From acde46de573e94436fe85ddaa6a58b52cc3a54f2 Mon Sep 17 00:00:00 2001 From: Remi Palandri Date: Fri, 29 Apr 2022 11:55:33 -0700 Subject: [PATCH] move ms/compute shader system to single descriptorset --- renderdoc/data/glsl/vk_buffer2ms.comp | 20 +- renderdoc/data/glsl/vk_depthms2buffer.comp | 16 +- renderdoc/data/glsl/vk_ms2buffer.comp | 20 +- renderdoc/driver/vulkan/vk_debug.cpp | 15 +- renderdoc/driver/vulkan/vk_debug.h | 3 +- .../driver/vulkan/vk_msaa_buffer_conv.cpp | 243 ++++++++---------- 6 files changed, 142 insertions(+), 175 deletions(-) diff --git a/renderdoc/data/glsl/vk_buffer2ms.comp b/renderdoc/data/glsl/vk_buffer2ms.comp index 74153c807..7afeb269a 100644 --- a/renderdoc/data/glsl/vk_buffer2ms.comp +++ b/renderdoc/data/glsl/vk_buffer2ms.comp @@ -40,6 +40,7 @@ layout(push_constant) uniform multisamplePush int sampleOffset; int byteSize; int maxInvocationID; + int dispatchOffset; } mscopy; @@ -48,6 +49,7 @@ mscopy; #define sampleOffset (mscopy.sampleOffset) #define byteSize (mscopy.byteSize) #define maxInvocationID (mscopy.maxInvocationID) +#define dispatchOffset (mscopy.dispatchOffset) void main() { @@ -64,7 +66,7 @@ void main() uvec4 data; if(byteSize == 1) { - data.x = srcData[idx]; + data.x = srcData[dispatchOffset + idx]; int pxIdx = int(idx * 4); int x0 = (pxIdx + 0) % texWidth; int y0 = (pxIdx + 0) / texWidth; @@ -82,7 +84,7 @@ void main() } else if(byteSize == 2) { - data.x = srcData[idx]; + data.x = srcData[dispatchOffset + idx]; int pxIdx = int(idx * 2); int x0 = (pxIdx + 0) % texWidth; int y0 = (pxIdx + 0) / texWidth; @@ -96,25 +98,25 @@ void main() { int x0 = int(idx) % texWidth; int y0 = int(idx) / texWidth; - data.x = srcData[idx]; + data.x = srcData[dispatchOffset + idx]; imageStore(dstMS, ivec3(x0, y0, slice), sampleIdx, data); } else if(byteSize == 8) { int x0 = int(idx) % texWidth; int y0 = int(idx) / texWidth; - data.x = srcData[idx * 2]; - data.y = srcData[idx * 2 + 1]; + data.x = srcData[dispatchOffset + (idx * 2)]; + data.y = srcData[dispatchOffset + (idx * 2 + 1)]; imageStore(dstMS, ivec3(x0, y0, slice), sampleIdx, data); } else if(byteSize == 16) { int x0 = int(idx) % texWidth; int y0 = int(idx) / texWidth; - data.x = srcData[idx * 4]; - data.y = srcData[idx * 4 + 1]; - data.z = srcData[idx * 4 + 2]; - data.w = srcData[idx * 4 + 3]; + data.x = srcData[dispatchOffset + (idx * 4)]; + data.y = srcData[dispatchOffset + (idx * 4 + 1)]; + data.z = srcData[dispatchOffset + (idx * 4 + 2)]; + data.w = srcData[dispatchOffset + (idx * 4 + 3)]; imageStore(dstMS, ivec3(x0, y0, slice), sampleIdx, data); } } diff --git a/renderdoc/data/glsl/vk_depthms2buffer.comp b/renderdoc/data/glsl/vk_depthms2buffer.comp index d4e101646..f6d6a3165 100644 --- a/renderdoc/data/glsl/vk_depthms2buffer.comp +++ b/renderdoc/data/glsl/vk_depthms2buffer.comp @@ -48,6 +48,7 @@ layout(push_constant) uniform multisamplePush int baseSample; int format; int maxInvocationID; + int dispatchOffset; } mscopy; @@ -56,6 +57,7 @@ mscopy; #define baseSample (mscopy.baseSample) #define format (mscopy.format) #define maxInvocationID (mscopy.maxInvocationID) +#define dispatchOffset (mscopy.dispatchOffset) void main() { @@ -82,35 +84,35 @@ void main() vec2 depth = vec2(texelFetch(srcDepthMS, ivec3(x0, y0, slice), sampleIdx).x, texelFetch(srcDepthMS, ivec3(x1, y1, slice), sampleIdx).x); - result[idx] = (floatToD16(depth.x) << 0) | (floatToD16(depth.y) << 16); + result[dispatchOffset + idx] = (floatToD16(depth.x) << 0) | (floatToD16(depth.y) << 16); } else if(format == SHADER_D16_UNORM_S8_UINT) { float depth = texelFetch(srcDepthMS, coord, sampleIdx).x; uint stencil = texelFetch(srcStencilMS, coord, sampleIdx).x; - result[idx] = (floatToD16(depth) << 0) | (stencil << 16); + result[dispatchOffset + idx] = (floatToD16(depth) << 0) | (stencil << 16); } else if(format == SHADER_X8_D24_UNORM_PACK32) { float depth = texelFetch(srcDepthMS, coord, sampleIdx).x; - result[idx] = (floatToD24(depth) << 0); + result[dispatchOffset + idx] = (floatToD24(depth) << 0); } else if(format == SHADER_D24_UNORM_S8_UINT) { float depth = texelFetch(srcDepthMS, coord, sampleIdx).x; uint stencil = texelFetch(srcStencilMS, coord, sampleIdx).x; - result[idx] = (floatToD24(depth) << 0) | (stencil << 24); + result[dispatchOffset + idx] = (floatToD24(depth) << 0) | (stencil << 24); } else if(format == SHADER_D32_SFLOAT) { float depth = texelFetch(srcDepthMS, coord, sampleIdx).x; - result[idx] = floatBitsToUint(depth); + result[dispatchOffset + idx] = floatBitsToUint(depth); } else if(format == SHADER_D32_SFLOAT_S8_UINT) { float depth = texelFetch(srcDepthMS, coord, sampleIdx).x; uint stencil = texelFetch(srcStencilMS, coord, sampleIdx).x; - result[idx * 2 + 0] = floatBitsToUint(depth); - result[idx * 2 + 1] = stencil; + result[dispatchOffset + (idx * 2 + 0)] = floatBitsToUint(depth); + result[dispatchOffset + (idx * 2 + 1)] = stencil; } } diff --git a/renderdoc/data/glsl/vk_ms2buffer.comp b/renderdoc/data/glsl/vk_ms2buffer.comp index 291f884d9..4f3d46589 100644 --- a/renderdoc/data/glsl/vk_ms2buffer.comp +++ b/renderdoc/data/glsl/vk_ms2buffer.comp @@ -42,6 +42,7 @@ layout(push_constant) uniform multisamplePush int baseSample; int byteSize; int maxInvocationID; + int dispatchOffset; } mscopy; @@ -50,6 +51,7 @@ mscopy; #define baseSample (mscopy.baseSample) #define byteSize (mscopy.byteSize) #define maxInvocationID (mscopy.maxInvocationID) +#define dispatchOffset (mscopy.dispatchOffset) void main() { @@ -78,7 +80,7 @@ void main() texelFetch(srcMS, ivec3(x1, y1, slice), sampleIdx).x, texelFetch(srcMS, ivec3(x2, y2, slice), sampleIdx).x, texelFetch(srcMS, ivec3(x3, y3, slice), sampleIdx).x); - result[idx] = (data.x << 0 | data.y << 8 | data.z << 16 | data.w << 24); + result[dispatchOffset + idx] = (data.x << 0 | data.y << 8 | data.z << 16 | data.w << 24); } else if(byteSize == 2) { @@ -90,31 +92,31 @@ void main() uvec2 data = uvec2(texelFetch(srcMS, ivec3(x0, y0, slice), sampleIdx).x, texelFetch(srcMS, ivec3(x1, y1, slice), sampleIdx).x); - result[idx] = (data.x << 0 | data.y << 16); + result[dispatchOffset + idx] = (data.x << 0 | data.y << 16); } else if(byteSize == 4) { int x0 = int(idx) % textureWidth; int y0 = int(idx) / textureWidth; uint data = texelFetch(srcMS, ivec3(x0, y0, slice), sampleIdx).x; - result[idx] = data; + result[dispatchOffset + idx] = data; } else if(byteSize == 8) { int x0 = int(idx) % textureWidth; int y0 = int(idx) / textureWidth; uvec2 data = texelFetch(srcMS, ivec3(x0, y0, slice), sampleIdx).xy; - result[idx * 2] = data.x; - result[idx * 2 + 1] = data.y; + result[dispatchOffset + (idx * 2)] = data.x; + result[dispatchOffset + (idx * 2 + 1)] = data.y; } else if(byteSize == 16) { int x0 = int(idx) % textureWidth; int y0 = int(idx) / textureWidth; uvec4 data = texelFetch(srcMS, ivec3(x0, y0, slice), sampleIdx); - result[idx * 4] = data.x; - result[idx * 4 + 1] = data.y; - result[idx * 4 + 2] = data.z; - result[idx * 4 + 3] = data.w; + result[dispatchOffset + (idx * 4)] = data.x; + result[dispatchOffset + (idx * 4 + 1)] = data.y; + result[dispatchOffset + (idx * 4 + 2)] = data.z; + result[dispatchOffset + (idx * 4 + 3)] = data.w; } } diff --git a/renderdoc/driver/vulkan/vk_debug.cpp b/renderdoc/driver/vulkan/vk_debug.cpp index 24548ef97..daf3b7dde 100644 --- a/renderdoc/driver/vulkan/vk_debug.cpp +++ b/renderdoc/driver/vulkan/vk_debug.cpp @@ -374,16 +374,16 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver) ////////////////////////////////////////////////////////////////// // Color MS <-> Buffer copy (via compute) VkDescriptorPoolSize bufferPoolTypes[] = { - {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 2 * ARRAY_COUNT(m_BufferMSDescSet)}, - {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1 * ARRAY_COUNT(m_BufferMSDescSet)}, - {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1 * ARRAY_COUNT(m_BufferMSDescSet)}, + {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 2}, + {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1}, + {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1}, }; VkDescriptorPoolCreateInfo bufferPoolInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, NULL, 0, - ARRAY_COUNT(m_BufferMSDescSet), + 1, ARRAY_COUNT(bufferPoolTypes), &bufferPoolTypes[0], }; @@ -418,11 +418,8 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver) rm->SetInternalResource(GetResID(m_DepthMS2BufferPipe)); rm->SetInternalResource(GetResID(m_Buffer2MSPipe)); - for(size_t i = 0; i < ARRAY_COUNT(m_BufferMSDescSet); i++) - { - CREATE_OBJECT(m_BufferMSDescSet[i], m_BufferMSDescriptorPool, m_BufferMSDescSetLayout); - rm->SetInternalResource(GetResID(m_BufferMSDescSet[i])); - } + CREATE_OBJECT(m_BufferMSDescSet, m_BufferMSDescriptorPool, m_BufferMSDescSetLayout); + rm->SetInternalResource(GetResID(m_BufferMSDescSet)); ////////////////////////////////////////////////////////////////// // Depth MS to Buffer copy (via compute) diff --git a/renderdoc/driver/vulkan/vk_debug.h b/renderdoc/driver/vulkan/vk_debug.h index b1742898a..30b12c15c 100644 --- a/renderdoc/driver/vulkan/vk_debug.h +++ b/renderdoc/driver/vulkan/vk_debug.h @@ -128,8 +128,7 @@ private: VkDescriptorPool m_BufferMSDescriptorPool; VkDescriptorSetLayout m_BufferMSDescSetLayout = VK_NULL_HANDLE; VkPipelineLayout m_BufferMSPipeLayout = VK_NULL_HANDLE; - // 8 descriptor sets allows for 4x MSAA with 2 array slices, common for VR targets - VkDescriptorSet m_BufferMSDescSet[8] = {}; + VkDescriptorSet m_BufferMSDescSet = VK_NULL_HANDLE; VkPipeline m_Buffer2MSPipe = VK_NULL_HANDLE; VkPipeline m_MS2BufferPipe = VK_NULL_HANDLE; VkPipeline m_DepthMS2BufferPipe = VK_NULL_HANDLE; diff --git a/renderdoc/driver/vulkan/vk_msaa_buffer_conv.cpp b/renderdoc/driver/vulkan/vk_msaa_buffer_conv.cpp index f50f854ee..4bacc340c 100644 --- a/renderdoc/driver/vulkan/vk_msaa_buffer_conv.cpp +++ b/renderdoc/driver/vulkan/vk_msaa_buffer_conv.cpp @@ -92,9 +92,17 @@ void VulkanDebugManager::CopyTex2DMSToBuffer(VkBuffer destBuffer, VkImage srcMS, VkCommandBuffer cmd = VK_NULL_HANDLE; VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; + cmd = m_pDriver->GetNextCmd(); + + if(cmd == VK_NULL_HANDLE) + return; + + ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + + ObjDisp(cmd)->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(m_MS2BufferPipe)); const uint32_t dispatchBufferSize = GetByteSize(extent.width, extent.height, extent.depth, fmt, 0); - const uint32_t descriptorBatchSize = ARRAY_COUNT(m_BufferMSDescSet); + uint32_t dispatchOffset = 0; VkDescriptorImageInfo srcdesc = {0}; srcdesc.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; @@ -104,36 +112,25 @@ void VulkanDebugManager::CopyTex2DMSToBuffer(VkBuffer destBuffer, VkImage srcMS, VkDescriptorBufferInfo destdesc = {0}; destdesc.buffer = destBuffer; destdesc.offset = 0; - destdesc.range = dispatchBufferSize; + destdesc.range = VK_WHOLE_SIZE; - uint32_t currentBatch = 0; + VkWriteDescriptorSet writeSet[] = { + {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_BufferMSDescSet), 0, 0, 1, + VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &srcdesc, NULL, NULL}, + {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_BufferMSDescSet), 2, 0, 1, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, NULL, &destdesc, NULL}, + }; + + ObjDisp(dev)->UpdateDescriptorSets(Unwrap(dev), ARRAY_COUNT(writeSet), writeSet, 0, NULL); + + ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, + Unwrap(m_BufferMSPipeLayout), 0, 1, + UnwrapPtr(m_BufferMSDescSet), 0, NULL); for(uint32_t currentSlice = baseSlice; currentSlice < numSlices + baseSlice; currentSlice++) { for(uint32_t currentSample = baseSample; currentSample < numSamples + baseSample; currentSample++) { - // if we don't have a current cmd buffer, start a new one - if(cmd == VK_NULL_HANDLE) - { - cmd = m_pDriver->GetNextCmd(); - - if(cmd == VK_NULL_HANDLE) - return; - - ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - - ObjDisp(cmd)->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, - Unwrap(m_MS2BufferPipe)); - } - - const uint32_t batchIndex = currentBatch % descriptorBatchSize; - VkWriteDescriptorSet writeSet[] = { - {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_BufferMSDescSet[batchIndex]), 0, - 0, 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &srcdesc, NULL, NULL}, - {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_BufferMSDescSet[batchIndex]), 2, - 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, NULL, &destdesc, NULL}, - }; - // if the byte size is less than 4, we need to multisample. const uint32_t msDivider = bs < 4 ? (4 / bs) : 1; const uint32_t workGroupDivider = MS_DISPATCH_LOCAL_SIZE * msDivider; @@ -142,14 +139,9 @@ void VulkanDebugManager::CopyTex2DMSToBuffer(VkBuffer destBuffer, VkImage srcMS, const uint32_t maxInvoc = AlignUp(extent.width * extent.height, msDivider) / msDivider; Vec4u params[2] = { - {extent.width, currentSlice, currentSample, bs}, {maxInvoc, 0, 0, 0}, + {extent.width, currentSlice, currentSample, bs}, {maxInvoc, dispatchOffset, 0, 0}, }; - ObjDisp(dev)->UpdateDescriptorSets(Unwrap(dev), ARRAY_COUNT(writeSet), writeSet, 0, NULL); - - ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, - Unwrap(m_BufferMSPipeLayout), 0, 1, - UnwrapPtr(m_BufferMSDescSet[batchIndex]), 0, NULL); ObjDisp(cmd)->CmdPushConstants(Unwrap(cmd), Unwrap(m_BufferMSPipeLayout), VK_SHADER_STAGE_ALL, 0, sizeof(Vec4u) * 2, ¶ms); @@ -157,23 +149,18 @@ void VulkanDebugManager::CopyTex2DMSToBuffer(VkBuffer destBuffer, VkImage srcMS, // being a multiple of our multisample size ObjDisp(cmd)->CmdDispatch(Unwrap(cmd), numWorkGroup, 1, 1); - destdesc.offset += dispatchBufferSize; - currentBatch++; - - // if we're about to end a batch, or we're done entirely, submit and flush - if(batchIndex == descriptorBatchSize - 1 || currentBatch == numSamples * numSlices) - { - ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); - - cmd = VK_NULL_HANDLE; - - // submit cmds and wait for idle so we can readback - m_pDriver->SubmitCmds(); - m_pDriver->FlushQ(); - } + dispatchOffset += dispatchBufferSize / 4; } } + ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); + + cmd = VK_NULL_HANDLE; + + // submit cmds and wait for idle so we can readback + m_pDriver->SubmitCmds(); + m_pDriver->FlushQ(); + RDCASSERT(cmd == VK_NULL_HANDLE); ObjDisp(dev)->DestroyImageView(Unwrap(dev), srcView, NULL); @@ -245,6 +232,16 @@ void VulkanDebugManager::CopyDepthTex2DMSToBuffer(VkBuffer destBuffer, VkImage s VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; + cmd = m_pDriver->GetNextCmd(); + + if(cmd == VK_NULL_HANDLE) + return; + + ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + + ObjDisp(cmd)->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, + Unwrap(m_DepthMS2BufferPipe)); + VkDescriptorImageInfo srcdesc[2]; srcdesc[0].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; srcdesc[0].imageView = srcDepthView; @@ -269,43 +266,32 @@ void VulkanDebugManager::CopyDepthTex2DMSToBuffer(VkBuffer destBuffer, VkImage s } const uint32_t dispatchBufferSize = GetByteSize(extent.width, extent.height, extent.depth, fmt, 0); - const uint32_t descriptorBatchSize = ARRAY_COUNT(m_BufferMSDescSet); + uint32_t dispatchOffset = 0; VkDescriptorBufferInfo destdesc = {0}; destdesc.buffer = destBuffer; destdesc.offset = 0; - destdesc.range = dispatchBufferSize; + destdesc.range = VK_WHOLE_SIZE; - uint32_t currentBatch = 0; + VkWriteDescriptorSet writeSet[] = { + {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_BufferMSDescSet), 0, 0, 1, + VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &srcdesc[0], NULL, NULL}, + {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_BufferMSDescSet), 1, 0, 1, + VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &srcdesc[1], NULL, NULL}, + {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_BufferMSDescSet), 2, 0, 1, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, NULL, &destdesc, NULL}, + }; + + ObjDisp(dev)->UpdateDescriptorSets(Unwrap(dev), ARRAY_COUNT(writeSet), writeSet, 0, NULL); + + ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, + Unwrap(m_BufferMSPipeLayout), 0, 1, + UnwrapPtr(m_BufferMSDescSet), 0, NULL); for(uint32_t currentSlice = baseSlice; currentSlice < numSlices + baseSlice; currentSlice++) { for(uint32_t currentSample = baseSample; currentSample < numSamples + baseSample; currentSample++) { - // if we don't have a current cmd buffer, start a new one - if(cmd == VK_NULL_HANDLE) - { - cmd = m_pDriver->GetNextCmd(); - - if(cmd == VK_NULL_HANDLE) - return; - - ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - - ObjDisp(cmd)->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, - Unwrap(m_DepthMS2BufferPipe)); - } - const uint32_t batchIndex = currentBatch % descriptorBatchSize; - - VkWriteDescriptorSet writeSet[] = { - {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_BufferMSDescSet[batchIndex]), 0, - 0, 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &srcdesc[0], NULL, NULL}, - {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_BufferMSDescSet[batchIndex]), 1, - 0, 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &srcdesc[1], NULL, NULL}, - {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_BufferMSDescSet[batchIndex]), 2, - 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, NULL, &destdesc, NULL}, - }; - // for D16 textures, we need to multisample. const uint32_t msDivider = fmt == VK_FORMAT_D16_UNORM ? 2 : 1; const uint32_t workGroupDivider = MS_DISPATCH_LOCAL_SIZE * msDivider; @@ -314,36 +300,26 @@ void VulkanDebugManager::CopyDepthTex2DMSToBuffer(VkBuffer destBuffer, VkImage s const uint32_t maxInvoc = AlignUp(extent.width * extent.height, msDivider) / msDivider; Vec4u params[2] = { - {extent.width, currentSlice, currentSample, fmtIndex}, {maxInvoc, 0, 0, 0}, + {extent.width, currentSlice, currentSample, fmtIndex}, {maxInvoc, dispatchOffset, 0, 0}, }; - ObjDisp(dev)->UpdateDescriptorSets(Unwrap(dev), ARRAY_COUNT(writeSet), writeSet, 0, NULL); - - ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, - Unwrap(m_BufferMSPipeLayout), 0, 1, - UnwrapPtr(m_BufferMSDescSet[batchIndex]), 0, NULL); ObjDisp(cmd)->CmdPushConstants(Unwrap(cmd), Unwrap(m_BufferMSPipeLayout), VK_SHADER_STAGE_ALL, 0, sizeof(Vec4u) * 2, ¶ms); ObjDisp(cmd)->CmdDispatch(Unwrap(cmd), numWorkGroup, 1, 1); - destdesc.offset += dispatchBufferSize; - currentBatch++; - - // if we're about to end a batch, or we're done entirely, submit and flush - if(batchIndex == descriptorBatchSize - 1 || currentBatch == numSamples * numSlices) - { - ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); - - cmd = VK_NULL_HANDLE; - - // submit cmds and wait for idle so we can readback - m_pDriver->SubmitCmds(); - m_pDriver->FlushQ(); - } + dispatchOffset += dispatchBufferSize / 4; } } + ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); + + cmd = VK_NULL_HANDLE; + + // submit cmds and wait for idle so we can readback + m_pDriver->SubmitCmds(); + m_pDriver->FlushQ(); + RDCASSERT(cmd == VK_NULL_HANDLE); ObjDisp(dev)->DestroyImageView(Unwrap(dev), srcDepthView, NULL); @@ -416,45 +392,45 @@ void VulkanDebugManager::CopyBufferToTex2DMS(VkImage destMS, VkBuffer srcBuffer, VkCommandBufferBeginInfo beginInfo = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, NULL, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT}; + cmd = m_pDriver->GetNextCmd(); + + if(cmd == VK_NULL_HANDLE) + return; + + ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); + + ObjDisp(cmd)->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(m_Buffer2MSPipe)); + const uint32_t dispatchBufferSize = GetByteSize(extent.width, extent.height, extent.depth, fmt, 0); - const uint32_t descriptorBatchSize = ARRAY_COUNT(m_BufferMSDescSet); + uint32_t dispatchOffset = 0; VkDescriptorBufferInfo srcdesc = {0}; srcdesc.buffer = srcBuffer; srcdesc.offset = 0; - srcdesc.range = dispatchBufferSize; + srcdesc.range = VK_WHOLE_SIZE; VkDescriptorImageInfo destdesc = {0}; destdesc.imageLayout = VK_IMAGE_LAYOUT_GENERAL; destdesc.imageView = destView; destdesc.sampler = VK_NULL_HANDLE; + VkWriteDescriptorSet writeSet[] = { + {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_BufferMSDescSet), 2, 0, 1, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, NULL, &srcdesc, NULL}, + {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_BufferMSDescSet), 3, 0, 1, + VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &destdesc, NULL, NULL}, + }; + + ObjDisp(dev)->UpdateDescriptorSets(Unwrap(dev), ARRAY_COUNT(writeSet), writeSet, 0, NULL); + + ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, + Unwrap(m_BufferMSPipeLayout), 0, 1, + UnwrapPtr(m_BufferMSDescSet), 0, NULL); + for(uint32_t currentSlice = 0; currentSlice < numSlices; currentSlice++) { for(uint32_t currentSample = 0; currentSample < numSamples; currentSample++) { - // if we don't have a current cmd buffer, start a new one - if(cmd == VK_NULL_HANDLE) - { - cmd = m_pDriver->GetNextCmd(); - - if(cmd == VK_NULL_HANDLE) - return; - - ObjDisp(cmd)->BeginCommandBuffer(Unwrap(cmd), &beginInfo); - - ObjDisp(cmd)->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, - Unwrap(m_Buffer2MSPipe)); - } - - const uint32_t batchIndex = (currentSlice * numSamples + currentSample) % descriptorBatchSize; - VkWriteDescriptorSet writeSet[] = { - {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_BufferMSDescSet[batchIndex]), 2, - 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, NULL, &srcdesc, NULL}, - {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_BufferMSDescSet[batchIndex]), 3, - 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &destdesc, NULL, NULL}, - }; - // if the byte size is less than 4, we need to multisample. const uint32_t msDivider = bs < 4 ? (4 / bs) : 1; const uint32_t workGroupDivider = MS_DISPATCH_LOCAL_SIZE * msDivider; @@ -462,14 +438,8 @@ void VulkanDebugManager::CopyBufferToTex2DMS(VkImage destMS, VkBuffer srcBuffer, AlignUp(extent.width * extent.height, workGroupDivider) / workGroupDivider; const uint32_t maxInvoc = AlignUp(extent.width * extent.height, msDivider) / msDivider; - ObjDisp(dev)->UpdateDescriptorSets(Unwrap(dev), ARRAY_COUNT(writeSet), writeSet, 0, NULL); - - ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, - Unwrap(m_BufferMSPipeLayout), 0, 1, - UnwrapPtr(m_BufferMSDescSet[batchIndex]), 0, NULL); - Vec4u params[2] = { - {extent.width, currentSlice, currentSample, bs}, {maxInvoc, 0, 0, 0}, + {extent.width, currentSlice, currentSample, bs}, {maxInvoc, dispatchOffset, 0, 0}, }; ObjDisp(cmd)->CmdPushConstants(Unwrap(cmd), Unwrap(m_BufferMSPipeLayout), VK_SHADER_STAGE_ALL, @@ -477,23 +447,18 @@ void VulkanDebugManager::CopyBufferToTex2DMS(VkImage destMS, VkBuffer srcBuffer, ObjDisp(cmd)->CmdDispatch(Unwrap(cmd), numWorkGroup, 1, 1); - srcdesc.offset += dispatchBufferSize; - - // if we're about to end a batch, or we're done entirely, submit and flush - if(batchIndex == descriptorBatchSize - 1 || - (currentSlice == numSlices - 1 && currentSample == numSamples - 1)) - { - ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); - - cmd = VK_NULL_HANDLE; - - // submit cmds and wait for idle so we can readback - m_pDriver->SubmitCmds(); - m_pDriver->FlushQ(); - } + dispatchOffset += dispatchBufferSize / 4; } } + ObjDisp(cmd)->EndCommandBuffer(Unwrap(cmd)); + + cmd = VK_NULL_HANDLE; + + // submit cmds and wait for idle so we can readback + m_pDriver->SubmitCmds(); + m_pDriver->FlushQ(); + RDCASSERT(cmd == VK_NULL_HANDLE); ObjDisp(dev)->DestroyImageView(Unwrap(dev), destView, NULL); @@ -591,7 +556,7 @@ void VulkanDebugManager::CopyDepthBufferToTex2DMS(VkImage destMS, VkBuffer srcBu } VkWriteDescriptorSet writeSet[] = { - {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_BufferMSDescSet[0]), 2, 0, 1, + {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(m_BufferMSDescSet), 2, 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, NULL, &srcdesc, NULL}, }; @@ -691,7 +656,7 @@ void VulkanDebugManager::CopyDepthBufferToTex2DMS(VkImage destMS, VkBuffer srcBu ObjDisp(cmd)->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_GRAPHICS, Unwrap(m_BufferMSPipeLayout), 0, 1, - UnwrapPtr(m_BufferMSDescSet[0]), 0, NULL); + UnwrapPtr(m_BufferMSDescSet), 0, NULL); VkViewport viewport = {0.0f, 0.0f, (float)extent.width, (float)extent.height, 0.0f, 1.0f}; ObjDisp(cmd)->CmdSetViewport(Unwrap(cmd), 0, 1, &viewport);