diff --git a/src/lightmap/glsl_frag.h b/src/lightmap/glsl_frag.h index 4cac922..9c594de 100644 --- a/src/lightmap/glsl_frag.h +++ b/src/lightmap/glsl_frag.h @@ -46,8 +46,16 @@ layout(push_constant) uniform PushConstants { uint LightStart; uint LightEnd; - int surfaceIndex; - int pushPadding; + int SurfaceIndex; + int PushPadding1; + vec2 TileTL; + vec2 TileBR; + vec3 LightmapOrigin; + float PushPadding2; + vec3 LightmapStepX; + float PushPadding3; + vec3 LightmapStepY; + float PushPadding4; }; layout(location = 0) in vec3 worldpos; @@ -59,12 +67,13 @@ void main() vec3 origin = worldpos; vec3 normal; - if (surfaceIndex >= 0) + if (SurfaceIndex >= 0) { - normal = surfaces[surfaceIndex].Normal; + normal = surfaces[SurfaceIndex].Normal; origin += normal * 0.1; } + vec3 incoming = vec3(0.0); for (uint j = LightStart; j < LightEnd; j++) { LightInfo light = lights[j]; @@ -76,7 +85,7 @@ void main() float distAttenuation = max(1.0 - (dist / light.Radius), 0.0); float angleAttenuation = 1.0f; - if (surfaceIndex >= 0) + if (SurfaceIndex >= 0) { angleAttenuation = max(dot(normal, dir), 0.0); } @@ -98,13 +107,13 @@ void main() if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionNoneEXT) { - incoming.rgb += light.Color * (attenuation * light.Intensity) * incoming.w; + incoming.rgb += light.Color * (attenuation * light.Intensity); } } } } - fragcolor = vec4(0.0); + fragcolor = vec4(incoming, 1.0); } )glsl"; diff --git a/src/lightmap/glsl_vert.h b/src/lightmap/glsl_vert.h index d526320..bc1336d 100644 --- a/src/lightmap/glsl_vert.h +++ b/src/lightmap/glsl_vert.h @@ -2,20 +2,20 @@ static const char* glsl_vert = R"glsl( #version 460 -layout(set = 0, binding = 1) uniform Uniforms -{ - vec3 SunDir; - float Padding1; - vec3 SunColor; - float SunIntensity; -}; - layout(push_constant) uniform PushConstants { uint LightStart; uint LightEnd; - int surfaceIndex; - int pushPadding; + int SurfaceIndex; + int PushPadding1; + vec2 TileTL; + vec2 TileBR; + vec3 LightmapOrigin; + float PushPadding2; + vec3 LightmapStepX; + float PushPadding3; + vec3 LightmapStepY; + float PushPadding4; }; layout(location = 0) out vec3 worldpos; @@ -29,8 +29,9 @@ vec2 positions[4] = vec2[]( void main() { - worldpos = vec3(0.0); - gl_Position = vec4(positions[gl_VertexIndex] * 2.0 - 1.0, 0.0, 1.0); + vec2 tilepos = positions[gl_VertexIndex]; + worldpos = LightmapOrigin + LightmapStepX * tilepos.x + LightmapStepY * tilepos.y; + gl_Position = vec4(mix(TileTL, TileBR, tilepos) * 2.0 - 1.0, 0.0, 1.0); } )glsl"; diff --git a/src/lightmap/gpuraytracer2.cpp b/src/lightmap/gpuraytracer2.cpp index 8f96ca7..bdfe08a 100644 --- a/src/lightmap/gpuraytracer2.cpp +++ b/src/lightmap/gpuraytracer2.cpp @@ -42,7 +42,77 @@ void GPURaytracer2::Raytrace(LevelMesh* level) printf("Ray tracing in progress...\n"); + BeginCommands(); + std::vector surfaceImages; + + for (size_t i = 0; i < mesh->surfaces.size(); i++) + { + Surface* surface = mesh->surfaces[i].get(); + int sampleWidth = surface->lightmapDims[0]; + int sampleHeight = surface->lightmapDims[1]; + + LightmapImage img = CreateImage(sampleWidth, sampleHeight); + + RenderPassBegin() + .RenderPass(renderPass.get()) + .RenderArea(0, 0, sampleWidth, sampleHeight) + .Framebuffer(img.Framebuffer.get()) + .Execute(cmdbuffer.get()); + + PushConstants2 pc; + pc.LightStart = 0; + pc.LightEnd = mesh->map->ThingLights.Size(); + pc.SurfaceIndex = (int32_t)i; + pc.TileTL = vec2(0.0f); + pc.TileBR = vec2(1.0f); + pc.LightmapOrigin = surface->lightmapOrigin; + pc.LightmapStepX = surface->lightmapSteps[0] * (float)sampleWidth; + pc.LightmapStepY = surface->lightmapSteps[1] * (float)sampleHeight; + + VkViewport viewport = {}; + viewport.maxDepth = 1; + viewport.width = (float)sampleWidth; + viewport.height = (float)sampleHeight; + cmdbuffer->setViewport(0, 1, &viewport); + + cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.get()); + cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0, descriptorSet.get()); + cmdbuffer->pushConstants(pipelineLayout.get(), VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PushConstants2), &pc); + cmdbuffer->draw(4, 1, 0, 0); + + cmdbuffer->endRenderPass(); + + PipelineBarrier() + .AddImage(img.Image.get(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT) + .Execute(cmdbuffer.get(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); + + VkBufferImageCopy region = {}; + region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + region.imageSubresource.layerCount = 1; + region.imageExtent.width = sampleWidth; + region.imageExtent.height = sampleHeight; + region.imageExtent.depth = 1; + cmdbuffer->copyImageToBuffer(img.Image->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, img.Transfer->buffer, 1, ®ion); + + surfaceImages.push_back(std::move(img)); + } + + FinishCommands(); + + for (size_t i = 0; i < mesh->surfaces.size(); i++) + { + Surface* surface = mesh->surfaces[i].get(); + int sampleWidth = surface->lightmapDims[0]; + int sampleHeight = surface->lightmapDims[1]; + + vec4* pixels = (vec4*)surfaceImages[i].Transfer->Map(0, sampleWidth * sampleHeight * sizeof(vec4)); + for (int i = 0; i < sampleWidth * sampleHeight; i++) + { + surface->samples[i] = pixels[i].xyz(); + } + surfaceImages[i].Transfer->Unmap(); + } if (device->renderdoc) device->renderdoc->EndFrameCapture(0, 0); @@ -62,7 +132,6 @@ void GPURaytracer2::CreateVulkanObjects() CreateTopLevelAccelerationStructure(); CreateShaders(); CreatePipeline(); - CreateFrameBuffer(); CreateDescriptorSet(); PipelineBarrier() @@ -334,9 +403,10 @@ void GPURaytracer2::CreatePipeline() { descriptorSetLayout = DescriptorSetLayoutBuilder() .AddBinding(0, VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1, VK_SHADER_STAGE_FRAGMENT_BIT) - .AddBinding(1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT) + .AddBinding(1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT) .AddBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT) .AddBinding(3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT) + .AddBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT) .DebugName("descriptorSetLayout") .Create(device.get()); @@ -348,19 +418,19 @@ void GPURaytracer2::CreatePipeline() renderPass = RenderPassBuilder() .AddAttachment( - VK_FORMAT_R8G8B8A8_UNORM, + VK_FORMAT_R32G32B32A32_SFLOAT, VK_SAMPLE_COUNT_1_BIT, - VK_ATTACHMENT_LOAD_OP_LOAD, + VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_STORE, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) .AddSubpass() .AddSubpassColorAttachmentRef(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) .AddExternalSubpassDependency( VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT) + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT) .DebugName("renderpass") .Create(device.get()); @@ -370,35 +440,43 @@ void GPURaytracer2::CreatePipeline() .AddVertexShader(vertShader.get()) .AddFragmentShader(fragShader.get()) .Topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP) - .Viewport(0.0f, 0.0f, 320.0f, 200.0f) - .Scissor(0, 0, 320, 200) + .AddDynamicState(VK_DYNAMIC_STATE_VIEWPORT) + .Viewport(0.0f, 0.0f, 0.0f, 0.0f) + .Scissor(0, 0, 4096, 4096) .DebugName("pipeline") .Create(device.get()); } -void GPURaytracer2::CreateFrameBuffer() +LightmapImage GPURaytracer2::CreateImage(int width, int height) { - framebufferImage = ImageBuilder() + LightmapImage img; + + img.Image = ImageBuilder() .Usage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT) - .Format(VK_FORMAT_R8G8B8A8_UNORM) - .Size(320, 200) + .Format(VK_FORMAT_R32G32B32A32_SFLOAT) + .Size(width, height) + .DebugName("LightmapImage.Image") .Create(device.get()); - framebufferImageView = ImageViewBuilder() - .Image(framebufferImage.get(), VK_FORMAT_R8G8B8A8_UNORM) - .DebugName("framebufferImageView") + img.View = ImageViewBuilder() + .Image(img.Image.get(), VK_FORMAT_R32G32B32A32_SFLOAT) + .DebugName("LightmapImage.View") .Create(device.get()); - framebuffer = FramebufferBuilder() + img.Framebuffer = FramebufferBuilder() .RenderPass(renderPass.get()) - .Size(320, 200) - .AddAttachment(framebufferImageView.get()) - .DebugName("framebuffer") + .Size(width, height) + .AddAttachment(img.View.get()) + .DebugName("LightmapImage.Framebuffer") .Create(device.get()); - PipelineBarrier() - .AddImage(framebufferImage.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT) - .Execute(cmdbuffer.get(), 0, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); + img.Transfer = BufferBuilder() + .Size(width * height * sizeof(vec4)) + .Usage(VK_IMAGE_USAGE_TRANSFER_DST_BIT, VMA_MEMORY_USAGE_CPU_ONLY) + .DebugName("LightmapImage.Transfer") + .Create(device.get()); + + return img; } void GPURaytracer2::CreateDescriptorSet() @@ -420,7 +498,7 @@ void GPURaytracer2::CreateDescriptorSet() descriptorPool = DescriptorPoolBuilder() .AddPoolSize(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1) - .AddPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1) + .AddPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1) .AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 3) .MaxSets(1) .DebugName("descriptorPool") @@ -431,7 +509,7 @@ void GPURaytracer2::CreateDescriptorSet() WriteDescriptors() .AddAccelerationStructure(descriptorSet.get(), 0, tlAccelStruct.get()) - .AddBuffer(descriptorSet.get(), 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, uniformBuffer.get(), 0, sizeof(Uniforms2)) + .AddBuffer(descriptorSet.get(), 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, uniformBuffer.get(), 0, sizeof(Uniforms2)) .AddBuffer(descriptorSet.get(), 2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, surfaceIndexBuffer.get()) .AddBuffer(descriptorSet.get(), 3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, surfaceBuffer.get()) .AddBuffer(descriptorSet.get(), 4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, lightBuffer.get()) diff --git a/src/lightmap/gpuraytracer2.h b/src/lightmap/gpuraytracer2.h index 0708180..f15e565 100644 --- a/src/lightmap/gpuraytracer2.h +++ b/src/lightmap/gpuraytracer2.h @@ -18,8 +18,16 @@ struct PushConstants2 { uint32_t LightStart; uint32_t LightEnd; - int32_t surfaceIndex; - int32_t pushPadding; + int32_t SurfaceIndex; + int32_t PushPadding1; + vec2 TileTL; + vec2 TileBR; + vec3 LightmapOrigin; + float PushPadding2; + vec3 LightmapStepX; + float PushPadding3; + vec3 LightmapStepY; + float PushPadding4; }; struct SurfaceInfo2 @@ -47,6 +55,14 @@ struct LightInfo2 float Padding2; }; +struct LightmapImage +{ + std::unique_ptr Image; + std::unique_ptr View; + std::unique_ptr Framebuffer; + std::unique_ptr Transfer; +}; + class GPURaytracer2 { public: @@ -62,9 +78,10 @@ private: void CreateTopLevelAccelerationStructure(); void CreateShaders(); void CreatePipeline(); - void CreateFrameBuffer(); void CreateDescriptorSet(); + LightmapImage CreateImage(int width, int height); + void BeginCommands(); void FinishCommands(); @@ -108,10 +125,6 @@ private: std::unique_ptr pipeline; std::unique_ptr renderPass; - std::unique_ptr framebufferImage; - std::unique_ptr framebufferImageView; - std::unique_ptr framebuffer; - std::unique_ptr uniformBuffer; std::unique_ptr uniformTransferBuffer; diff --git a/src/lightmap/vulkanbuilders.cpp b/src/lightmap/vulkanbuilders.cpp index 31238fa..d42ad5e 100644 --- a/src/lightmap/vulkanbuilders.cpp +++ b/src/lightmap/vulkanbuilders.cpp @@ -192,7 +192,7 @@ std::unique_ptr ShaderBuilder::Create(const char *shadername, Vulk bool compileSuccess = shader.parse(&resources, 110, false, EShMsgVulkanRules); if (!compileSuccess) { - throw std::runtime_error(std::string("Shader compile failed: ") + shader.getInfoLog()); + throw std::runtime_error(std::string("Could not compile shader ") + shadername + ": " + shader.getInfoLog()); } glslang::TProgram program; @@ -200,7 +200,7 @@ std::unique_ptr ShaderBuilder::Create(const char *shadername, Vulk bool linkSuccess = program.link(EShMsgDefault); if (!linkSuccess) { - throw std::runtime_error(std::string("Shader link failed: ") + program.getInfoLog()); + throw std::runtime_error(std::string("Could not link shader ") + shadername + ": " + program.getInfoLog()); } glslang::TIntermediate *intermediate = program.getIntermediate(stage); diff --git a/src/lightmap/vulkandevice.cpp b/src/lightmap/vulkandevice.cpp index 5368a23..904ba2f 100644 --- a/src/lightmap/vulkandevice.cpp +++ b/src/lightmap/vulkandevice.cpp @@ -200,9 +200,13 @@ void VulkanDevice::createDevice() queueCreateInfos.push_back(queueCreateInfo); } + VkPhysicalDeviceRayQueryFeaturesKHR rayqueryFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR }; + rayqueryFeatures.rayQuery = true; + VkPhysicalDeviceRayTracingPipelineFeaturesKHR raytracingFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR }; raytracingFeatures.rayTracingPipeline = true; raytracingFeatures.rayTraversalPrimitiveCulling = true; + raytracingFeatures.pNext = &rayqueryFeatures; VkPhysicalDeviceAccelerationStructureFeaturesKHR deviceAccelFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR }; deviceAccelFeatures.accelerationStructure = true; diff --git a/src/lightmap/vulkandevice.h b/src/lightmap/vulkandevice.h index f7bfca3..2cba352 100644 --- a/src/lightmap/vulkandevice.h +++ b/src/lightmap/vulkandevice.h @@ -74,7 +74,7 @@ public: VkPhysicalDeviceFeatures enabledDeviceFeatures = {}; std::vector enabledDeviceExtensions = { //VK_KHR_SWAPCHAIN_EXTENSION_NAME, - //VK_KHR_RAY_QUERY_EXTENSION_NAME, + VK_KHR_RAY_QUERY_EXTENSION_NAME, VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME diff --git a/src/lightmap/vulkanobjects.h b/src/lightmap/vulkanobjects.h index 759d330..9dbe60d 100644 --- a/src/lightmap/vulkanobjects.h +++ b/src/lightmap/vulkanobjects.h @@ -7,6 +7,7 @@ class VulkanCommandPool; class VulkanDescriptorPool; +class VulkanCommandBuffer; class VulkanSemaphore { @@ -307,13 +308,15 @@ class RenderPassBegin public: RenderPassBegin(); - void setRenderPass(VulkanRenderPass *renderpass); - void setRenderArea(int x, int y, int width, int height); - void setFramebuffer(VulkanFramebuffer *framebuffer); - void addClearColor(float r, float g, float b, float a); - void addClearDepth(float value); - void addClearStencil(int value); - void addClearDepthStencil(float depthValue, int stencilValue); + RenderPassBegin& RenderPass(VulkanRenderPass *renderpass); + RenderPassBegin& RenderArea(int x, int y, int width, int height); + RenderPassBegin& Framebuffer(VulkanFramebuffer *framebuffer); + RenderPassBegin& AddClearColor(float r, float g, float b, float a); + RenderPassBegin& AddClearDepth(float value); + RenderPassBegin& AddClearStencil(int value); + RenderPassBegin& AddClearDepthStencil(float depthValue, int stencilValue); + + void Execute(VulkanCommandBuffer* cmdbuffer, VkSubpassContents contents = VK_SUBPASS_CONTENTS_INLINE); VkRenderPassBeginInfo renderPassInfo = {}; @@ -381,7 +384,6 @@ public: void copyQueryPoolResults(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags); void pushConstants(VulkanPipelineLayout *layout, VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void* pValues); void pushConstants(VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void* pValues); - void beginRenderPass(const RenderPassBegin &renderPassBegin, VkSubpassContents contents = VK_SUBPASS_CONTENTS_INLINE); void beginRenderPass(const VkRenderPassBeginInfo* pRenderPassBegin, VkSubpassContents contents); void nextSubpass(VkSubpassContents contents); void endRenderPass(); @@ -509,25 +511,28 @@ inline RenderPassBegin::RenderPassBegin() renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; } -inline void RenderPassBegin::setRenderPass(VulkanRenderPass *renderPass) +inline RenderPassBegin& RenderPassBegin::RenderPass(VulkanRenderPass *renderPass) { renderPassInfo.renderPass = renderPass->renderPass; + return *this; } -inline void RenderPassBegin::setRenderArea(int x, int y, int width, int height) +inline RenderPassBegin& RenderPassBegin::RenderArea(int x, int y, int width, int height) { renderPassInfo.renderArea.offset.x = x; renderPassInfo.renderArea.offset.y = y; renderPassInfo.renderArea.extent.width = width; renderPassInfo.renderArea.extent.height = height; + return *this; } -inline void RenderPassBegin::setFramebuffer(VulkanFramebuffer *framebuffer) +inline RenderPassBegin& RenderPassBegin::Framebuffer(VulkanFramebuffer *framebuffer) { renderPassInfo.framebuffer = framebuffer->framebuffer; + return *this; } -inline void RenderPassBegin::addClearColor(float r, float g, float b, float a) +inline RenderPassBegin& RenderPassBegin::AddClearColor(float r, float g, float b, float a) { VkClearValue clearValue = { }; clearValue.color = { r, g, b, a }; @@ -535,9 +540,10 @@ inline void RenderPassBegin::addClearColor(float r, float g, float b, float a) renderPassInfo.clearValueCount = (uint32_t)clearValues.size(); renderPassInfo.pClearValues = clearValues.data(); + return *this; } -inline void RenderPassBegin::addClearDepth(float value) +inline RenderPassBegin& RenderPassBegin::AddClearDepth(float value) { VkClearValue clearValue = { }; clearValue.depthStencil.depth = value; @@ -545,9 +551,10 @@ inline void RenderPassBegin::addClearDepth(float value) renderPassInfo.clearValueCount = (uint32_t)clearValues.size(); renderPassInfo.pClearValues = clearValues.data(); + return *this; } -inline void RenderPassBegin::addClearStencil(int value) +inline RenderPassBegin& RenderPassBegin::AddClearStencil(int value) { VkClearValue clearValue = { }; clearValue.depthStencil.stencil = value; @@ -555,9 +562,10 @@ inline void RenderPassBegin::addClearStencil(int value) renderPassInfo.clearValueCount = (uint32_t)clearValues.size(); renderPassInfo.pClearValues = clearValues.data(); + return *this; } -inline void RenderPassBegin::addClearDepthStencil(float depthValue, int stencilValue) +inline RenderPassBegin& RenderPassBegin::AddClearDepthStencil(float depthValue, int stencilValue) { VkClearValue clearValue = { }; clearValue.depthStencil.depth = depthValue; @@ -566,6 +574,12 @@ inline void RenderPassBegin::addClearDepthStencil(float depthValue, int stencilV renderPassInfo.clearValueCount = (uint32_t)clearValues.size(); renderPassInfo.pClearValues = clearValues.data(); + return *this; +} + +inline void RenderPassBegin::Execute(VulkanCommandBuffer* cmdbuffer, VkSubpassContents contents) +{ + cmdbuffer->beginRenderPass(&renderPassInfo, contents); } ///////////////////////////////////////////////////////////////////////////// @@ -896,11 +910,6 @@ inline void VulkanCommandBuffer::pushConstants(VkPipelineLayout layout, VkShader vkCmdPushConstants(buffer, layout, stageFlags, offset, size, pValues); } -inline void VulkanCommandBuffer::beginRenderPass(const RenderPassBegin &renderPassBegin, VkSubpassContents contents) -{ - beginRenderPass(&renderPassBegin.renderPassInfo, contents); -} - inline void VulkanCommandBuffer::beginRenderPass(const VkRenderPassBeginInfo* pRenderPassBegin, VkSubpassContents contents) { vkCmdBeginRenderPass(buffer, pRenderPassBegin, contents);