From ec94204a28cc392363f3bc3fd7a5914977bb3a4d Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 18 Sep 2023 02:42:12 +0200 Subject: [PATCH] Move vertex transform to the GPU --- .../vulkan/accelstructs/vk_lightmap.cpp | 107 ++++++------------ .../vulkan/accelstructs/vk_lightmap.h | 15 ++- wadsrc/static/shaders/lightmap/frag_blur.glsl | 2 +- .../{frag.glsl => frag_raytrace.glsl} | 10 ++ .../static/shaders/lightmap/frag_resolve.glsl | 2 +- wadsrc/static/shaders/lightmap/vert.glsl | 23 ---- .../shaders/lightmap/vert_raytrace.glsl | 38 +++++++ .../shaders/lightmap/vert_screenquad.glsl | 20 ++++ 8 files changed, 116 insertions(+), 101 deletions(-) rename wadsrc/static/shaders/lightmap/{frag.glsl => frag_raytrace.glsl} (98%) delete mode 100644 wadsrc/static/shaders/lightmap/vert.glsl create mode 100644 wadsrc/static/shaders/lightmap/vert_raytrace.glsl create mode 100644 wadsrc/static/shaders/lightmap/vert_screenquad.glsl diff --git a/src/common/rendering/vulkan/accelstructs/vk_lightmap.cpp b/src/common/rendering/vulkan/accelstructs/vk_lightmap.cpp index 441f46d84b..cfb740ec07 100644 --- a/src/common/rendering/vulkan/accelstructs/vk_lightmap.cpp +++ b/src/common/rendering/vulkan/accelstructs/vk_lightmap.cpp @@ -205,10 +205,17 @@ void VkLightmap::RenderBakeImage() LightmapPushConstants pc; pc.LightStart = firstLight; pc.LightEnd = firstLight + lightCount; + pc.TileX = selectedSurface.X; + pc.TileY = selectedSurface.Y; pc.SurfaceIndex = mesh->GetSurfaceIndex(targetSurface); pc.LightmapOrigin = targetSurface->worldOrigin - targetSurface->worldStepX - targetSurface->worldStepY; pc.LightmapStepX = targetSurface->worldStepX * viewport.width; pc.LightmapStepY = targetSurface->worldStepY * viewport.height; + pc.TileWidth = targetSurface->texWidth; + pc.TileHeight = targetSurface->texHeight; + pc.WorldToLocal = targetSurface->translateWorldToLocal; + pc.ProjLocalToU = targetSurface->projLocalToU; + pc.ProjLocalToV = targetSurface->projLocalToV; fb->GetCommands()->GetTransferCommands()->pushConstants(raytrace.pipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(LightmapPushConstants), &pc); SceneVertex* vertex = &vertices.Vertices[firstVertex]; @@ -217,15 +224,15 @@ void VkLightmap::RenderBakeImage() { for (int idx = 0; idx < vertexCount; idx++) { - (vertex++)->Position = ToUV(mesh->MeshVertices[surface->startVertIndex + idx], targetSurface); + (vertex++)->Position = mesh->MeshVertices[surface->startVertIndex + idx]; } } else { - (vertex++)->Position = ToUV(mesh->MeshVertices[surface->startVertIndex + 0], targetSurface); - (vertex++)->Position = ToUV(mesh->MeshVertices[surface->startVertIndex + 2], targetSurface); - (vertex++)->Position = ToUV(mesh->MeshVertices[surface->startVertIndex + 3], targetSurface); - (vertex++)->Position = ToUV(mesh->MeshVertices[surface->startVertIndex + 1], targetSurface); + (vertex++)->Position = mesh->MeshVertices[surface->startVertIndex + 0]; + (vertex++)->Position = mesh->MeshVertices[surface->startVertIndex + 2]; + (vertex++)->Position = mesh->MeshVertices[surface->startVertIndex + 3]; + (vertex++)->Position = mesh->MeshVertices[surface->startVertIndex + 1]; } fb->GetCommands()->GetTransferCommands()->draw(vertexCount, 1, firstVertex, 0); @@ -290,24 +297,7 @@ void VkLightmap::ResolveBakeImage() viewport.height = (float)bakeImage.maxY; cmdbuffer->setViewport(0, 1, &viewport); - LightmapPushConstants pc; - pc.LightStart = 0; - pc.LightEnd = 0; - pc.SurfaceIndex = 0; - pc.LightmapOrigin = FVector3(0.0f, 0.0f, 0.0f); - pc.LightmapStepX = FVector3(0.0f, 0.0f, 0.0f); - pc.LightmapStepY = FVector3(0.0f, 0.0f, 0.0f); - cmdbuffer->pushConstants(resolve.pipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(LightmapPushConstants), &pc); - - int firstVertex = vertices.Pos; - int vertexCount = 4; - vertices.Pos += vertexCount; - SceneVertex* vertex = &vertices.Vertices[firstVertex]; - vertex[0].Position = FVector2(0.0f, 0.0f); - vertex[1].Position = FVector2(1.0f, 0.0f); - vertex[2].Position = FVector2(1.0f, 1.0f); - vertex[3].Position = FVector2(0.0f, 1.0f); - cmdbuffer->draw(vertexCount, 1, firstVertex, 0); + cmdbuffer->draw(3, 1, 0, 0); cmdbuffer->endRenderPass(); } @@ -339,24 +329,7 @@ void VkLightmap::BlurBakeImage() viewport.height = (float)bakeImage.maxY; cmdbuffer->setViewport(0, 1, &viewport); - LightmapPushConstants pc; - pc.LightStart = 0; - pc.LightEnd = 0; - pc.SurfaceIndex = 0; - pc.LightmapOrigin = FVector3(0.0f, 0.0f, 0.0f); - pc.LightmapStepX = FVector3(0.0f, 0.0f, 0.0f); - pc.LightmapStepY = FVector3(0.0f, 0.0f, 0.0f); - cmdbuffer->pushConstants(blur.pipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(LightmapPushConstants), &pc); - - int firstVertex = vertices.Pos; - int vertexCount = 4; - vertices.Pos += vertexCount; - SceneVertex* vertex = &vertices.Vertices[firstVertex]; - vertex[0].Position = FVector2(0.0f, 0.0f); - vertex[1].Position = FVector2(1.0f, 0.0f); - vertex[2].Position = FVector2(1.0f, 1.0f); - vertex[3].Position = FVector2(0.0f, 1.0f); - cmdbuffer->draw(vertexCount, 1, firstVertex, 0); + cmdbuffer->draw(3, 1, 0, 0); cmdbuffer->endRenderPass(); } @@ -384,24 +357,7 @@ void VkLightmap::BlurBakeImage() viewport.height = (float)bakeImage.maxY; cmdbuffer->setViewport(0, 1, &viewport); - LightmapPushConstants pc; - pc.LightStart = 0; - pc.LightEnd = 0; - pc.SurfaceIndex = 0; - pc.LightmapOrigin = FVector3(0.0f, 0.0f, 0.0f); - pc.LightmapStepX = FVector3(0.0f, 0.0f, 0.0f); - pc.LightmapStepY = FVector3(0.0f, 0.0f, 0.0f); - cmdbuffer->pushConstants(blur.pipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(LightmapPushConstants), &pc); - - int firstVertex = vertices.Pos; - int vertexCount = 4; - vertices.Pos += vertexCount; - SceneVertex* vertex = &vertices.Vertices[firstVertex]; - vertex[0].Position = FVector2(0.0f, 0.0f); - vertex[1].Position = FVector2(1.0f, 0.0f); - vertex[2].Position = FVector2(1.0f, 1.0f); - vertex[3].Position = FVector2(0.0f, 1.0f); - cmdbuffer->draw(vertexCount, 1, firstVertex, 0); + cmdbuffer->draw(3, 1, 0, 0); cmdbuffer->endRenderPass(); } @@ -480,17 +436,24 @@ void VkLightmap::CreateShaders() traceprefix += "#define USE_RAYQUERY\r\n"; } - shaders.vert = ShaderBuilder() + shaders.vertRaytrace = ShaderBuilder() .Type(ShaderType::Vertex) .AddSource("VersionBlock", prefix) - .AddSource("vert.glsl", LoadPrivateShaderLump("shaders/lightmap/vert.glsl").GetChars()) - .DebugName("VkLightmap.Vert") - .Create("VkLightmap.Vert", fb->GetDevice()); + .AddSource("vert_raytrace.glsl", LoadPrivateShaderLump("shaders/lightmap/vert_raytrace.glsl").GetChars()) + .DebugName("VkLightmap.VertRaytrace") + .Create("VkLightmap.VertRaytrace", fb->GetDevice()); + + shaders.vertScreenquad = ShaderBuilder() + .Type(ShaderType::Vertex) + .AddSource("VersionBlock", prefix) + .AddSource("vert_screenquad.glsl", LoadPrivateShaderLump("shaders/lightmap/vert_screenquad.glsl").GetChars()) + .DebugName("VkLightmap.VertScreenquad") + .Create("VkLightmap.VertScreenquad", fb->GetDevice()); shaders.fragRaytrace = ShaderBuilder() .Type(ShaderType::Fragment) .AddSource("VersionBlock", traceprefix) - .AddSource("frag.glsl", LoadPrivateShaderLump("shaders/lightmap/frag.glsl").GetChars()) + .AddSource("frag.glsl", LoadPrivateShaderLump("shaders/lightmap/frag_raytrace.glsl").GetChars()) .DebugName("VkLightmap.FragRaytrace") .Create("VkLightmap.FragRaytrace", fb->GetDevice()); @@ -579,10 +542,10 @@ void VkLightmap::CreateRaytracePipeline() raytrace.pipeline = GraphicsPipelineBuilder() .Layout(raytrace.pipelineLayout.get()) .RenderPass(raytrace.renderPass.get()) - .AddVertexShader(shaders.vert.get()) + .AddVertexShader(shaders.vertRaytrace.get()) .AddFragmentShader(shaders.fragRaytrace.get()) .AddVertexBufferBinding(0, sizeof(SceneVertex)) - .AddVertexAttribute(0, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(SceneVertex, Position)) + .AddVertexAttribute(0, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(SceneVertex, Position)) .Topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN) .AddDynamicState(VK_DYNAMIC_STATE_VIEWPORT) .RasterizationSamples(VK_SAMPLE_COUNT_4_BIT) @@ -683,11 +646,9 @@ void VkLightmap::CreateResolvePipeline() resolve.pipeline = GraphicsPipelineBuilder() .Layout(resolve.pipelineLayout.get()) .RenderPass(resolve.renderPass.get()) - .AddVertexShader(shaders.vert.get()) + .AddVertexShader(shaders.vertScreenquad.get()) .AddFragmentShader(shaders.fragResolve.get()) - .AddVertexBufferBinding(0, sizeof(SceneVertex)) - .AddVertexAttribute(0, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(SceneVertex, Position)) - .Topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN) + .Topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST) .AddDynamicState(VK_DYNAMIC_STATE_VIEWPORT) .Viewport(0.0f, 0.0f, 0.0f, 0.0f) .Scissor(0, 0, 4096, 4096) @@ -741,11 +702,9 @@ void VkLightmap::CreateBlurPipeline() blur.pipeline[i] = GraphicsPipelineBuilder() .Layout(blur.pipelineLayout.get()) .RenderPass(blur.renderPass.get()) - .AddVertexShader(shaders.vert.get()) + .AddVertexShader(shaders.vertScreenquad.get()) .AddFragmentShader(shaders.fragBlur[i].get()) - .AddVertexBufferBinding(0, sizeof(SceneVertex)) - .AddVertexAttribute(0, 0, VK_FORMAT_R32G32_SFLOAT, offsetof(SceneVertex, Position)) - .Topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN) + .Topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST) .AddDynamicState(VK_DYNAMIC_STATE_VIEWPORT) .Viewport(0.0f, 0.0f, 0.0f, 0.0f) .Scissor(0, 0, 4096, 4096) diff --git a/src/common/rendering/vulkan/accelstructs/vk_lightmap.h b/src/common/rendering/vulkan/accelstructs/vk_lightmap.h index 37220a081b..72af9df191 100644 --- a/src/common/rendering/vulkan/accelstructs/vk_lightmap.h +++ b/src/common/rendering/vulkan/accelstructs/vk_lightmap.h @@ -29,6 +29,16 @@ struct LightmapPushConstants float PushPadding3; FVector3 LightmapStepY; float PushPadding4; + FVector3 WorldToLocal; + float PushPadding5; + FVector3 ProjLocalToU; + float PushPadding6; + FVector3 ProjLocalToV; + float PushPadding7; + int32_t TileX; + int32_t TileY; + int32_t TileWidth; + int32_t TileHeight; }; struct LightmapBakeImage @@ -63,7 +73,7 @@ struct LightmapBakeImage struct SceneVertex { - FVector2 Position; + FVector3 Position; }; struct LightInfo @@ -161,7 +171,8 @@ private: struct { - std::unique_ptr vert; + std::unique_ptr vertRaytrace; + std::unique_ptr vertScreenquad; std::unique_ptr fragRaytrace; std::unique_ptr fragResolve; std::unique_ptr fragBlur[2]; diff --git a/wadsrc/static/shaders/lightmap/frag_blur.glsl b/wadsrc/static/shaders/lightmap/frag_blur.glsl index b515610816..26c96bf825 100644 --- a/wadsrc/static/shaders/lightmap/frag_blur.glsl +++ b/wadsrc/static/shaders/lightmap/frag_blur.glsl @@ -1,7 +1,7 @@ layout(set = 0, binding = 0) uniform sampler2D tex; -layout(location = 0) in vec3 worldpos; +layout(location = 0) in vec2 TexCoord; layout(location = 0) out vec4 fragcolor; vec4 centerFragColor; diff --git a/wadsrc/static/shaders/lightmap/frag.glsl b/wadsrc/static/shaders/lightmap/frag_raytrace.glsl similarity index 98% rename from wadsrc/static/shaders/lightmap/frag.glsl rename to wadsrc/static/shaders/lightmap/frag_raytrace.glsl index 056781db6f..ae061f22a1 100644 --- a/wadsrc/static/shaders/lightmap/frag.glsl +++ b/wadsrc/static/shaders/lightmap/frag_raytrace.glsl @@ -80,6 +80,16 @@ layout(push_constant) uniform PushConstants float PushPadding3; vec3 LightmapStepY; float PushPadding4; + vec3 WorldToLocal; + float PushPadding5; + vec3 ProjLocalToU; + float PushPadding6; + vec3 ProjLocalToV; + float PushPadding7; + int TileX; + int TileY; + int TileWidth; + int TileHeight; }; layout(location = 0) centroid in vec3 worldpos; diff --git a/wadsrc/static/shaders/lightmap/frag_resolve.glsl b/wadsrc/static/shaders/lightmap/frag_resolve.glsl index f7f2707220..886778ed23 100644 --- a/wadsrc/static/shaders/lightmap/frag_resolve.glsl +++ b/wadsrc/static/shaders/lightmap/frag_resolve.glsl @@ -1,7 +1,7 @@ layout(set = 0, binding = 0) uniform sampler2DMS tex; -layout(location = 0) in vec3 worldpos; +layout(location = 0) in vec2 TexCoord; layout(location = 0) out vec4 fragcolor; vec4 samplePixel(ivec2 pos, int count) diff --git a/wadsrc/static/shaders/lightmap/vert.glsl b/wadsrc/static/shaders/lightmap/vert.glsl deleted file mode 100644 index c70c239b6e..0000000000 --- a/wadsrc/static/shaders/lightmap/vert.glsl +++ /dev/null @@ -1,23 +0,0 @@ - -layout(push_constant) uniform PushConstants -{ - uint LightStart; - uint LightEnd; - int SurfaceIndex; - int PushPadding1; - vec3 LightmapOrigin; - float PushPadding2; - vec3 LightmapStepX; - float PushPadding3; - vec3 LightmapStepY; - float PushPadding4; -}; - -layout(location = 0) in vec2 aPosition; -layout(location = 0) out vec3 worldpos; - -void main() -{ - worldpos = LightmapOrigin + LightmapStepX * aPosition.x + LightmapStepY * aPosition.y; - gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0); -} diff --git a/wadsrc/static/shaders/lightmap/vert_raytrace.glsl b/wadsrc/static/shaders/lightmap/vert_raytrace.glsl new file mode 100644 index 0000000000..2388b5cdb4 --- /dev/null +++ b/wadsrc/static/shaders/lightmap/vert_raytrace.glsl @@ -0,0 +1,38 @@ + +layout(push_constant) uniform PushConstants +{ + uint LightStart; + uint LightEnd; + int SurfaceIndex; + int PushPadding1; + vec3 LightmapOrigin; + float PushPadding2; + vec3 LightmapStepX; + float PushPadding3; + vec3 LightmapStepY; + float PushPadding4; + vec3 WorldToLocal; + float PushPadding5; + vec3 ProjLocalToU; + float PushPadding6; + vec3 ProjLocalToV; + float PushPadding7; + int TileX; + int TileY; + int TileWidth; + int TileHeight; +}; + +layout(location = 0) in vec3 aPosition; +layout(location = 0) out vec3 worldpos; + +void main() +{ + vec3 localPos = aPosition - WorldToLocal; + float u = (1.0f + dot(localPos, ProjLocalToU)) / float(TileWidth + 2); + float v = (1.0f + dot(localPos, ProjLocalToV)) / float(TileHeight + 2); + + worldpos = LightmapOrigin + LightmapStepX * u + LightmapStepY * v; + gl_Position = vec4(vec2(u, v) * 2.0 - 1.0, 0.0, 1.0); +} + \ No newline at end of file diff --git a/wadsrc/static/shaders/lightmap/vert_screenquad.glsl b/wadsrc/static/shaders/lightmap/vert_screenquad.glsl new file mode 100644 index 0000000000..ce33270f1b --- /dev/null +++ b/wadsrc/static/shaders/lightmap/vert_screenquad.glsl @@ -0,0 +1,20 @@ + +layout(location = 0) out vec2 TexCoord; + +vec2 positions[3] = vec2[]( + vec2(-1.0, -1.0), + vec2( 3.0, -1.0), + vec2(-1.0, 3.0) +); + +vec2 uvs[3] = vec2[]( + vec2(0.0, 0.0), + vec2(2.0, 0.0), + vec2(0.0, 2.0) +); + +void main() +{ + gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0); + TexCoord = uvs[gl_VertexIndex]; +}