diff --git a/renderdoc/data/spv/histogram.comp b/renderdoc/data/spv/histogram.comp index fc205a5fc..2381a53f7 100644 --- a/renderdoc/data/spv/histogram.comp +++ b/renderdoc/data/spv/histogram.comp @@ -27,8 +27,6 @@ layout(binding=0, std140) writeonly buffer minmaxresultdest uint result[HGRAM_NUM_BUCKETS]; } dest; -layout (binding = 3) uniform sampler2D tex; - layout (local_size_x = HGRAM_TILES_PER_BLOCK, local_size_y = HGRAM_TILES_PER_BLOCK) in; void main() @@ -36,6 +34,8 @@ void main() uvec3 tid = gl_LocalInvocationID; uvec3 gid = gl_WorkGroupID; + int texType = SHADER_RESTYPE; + uvec3 texDim = uvec3(histogram_minmax.HistogramTextureResolution); uint blocksX = uint(ceil(float(texDim.x)/float(HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK))); @@ -50,8 +50,99 @@ void main() { uint bucketIdx = HGRAM_NUM_BUCKETS+1; +#if UINT_TEX { - vec4 data = textureLod(tex, vec2(x, y) / histogram_minmax.HistogramTextureResolution.xy, float(histogram_minmax.HistogramMip)); + uvec4 data = SampleTextureUInt4(texType, vec2(x, y), + histogram_minmax.HistogramSlice, + histogram_minmax.HistogramMip, + histogram_minmax.HistogramSample, + histogram_minmax.HistogramTextureResolution); + + float divisor = 0.0f; + uint sum = 0; + if((histogram_minmax.HistogramChannels & 0x1u) > 0) + { + sum += data.x; + divisor += 1.0f; + } + if((histogram_minmax.HistogramChannels & 0x2u) > 0) + { + sum += data.y; + divisor += 1.0f; + } + if((histogram_minmax.HistogramChannels & 0x4u) > 0) + { + sum += data.z; + divisor += 1.0f; + } + if((histogram_minmax.HistogramChannels & 0x8u) > 0) + { + sum += data.w; + divisor += 1.0f; + } + + if(divisor > 0.0f) + { + float val = float(sum)/divisor; + + float normalisedVal = (val - histogram_minmax.HistogramMin)/(histogram_minmax.HistogramMax - histogram_minmax.HistogramMin); + + if(normalisedVal < 0.0f) + normalisedVal = 2.0f; + + bucketIdx = uint(floor(normalisedVal*HGRAM_NUM_BUCKETS)); + } + } +#elif SINT_TEX + { + ivec4 data = SampleTextureSInt4(texType, vec2(x, y), + histogram_minmax.HistogramSlice, + histogram_minmax.HistogramMip, + histogram_minmax.HistogramSample, + histogram_minmax.HistogramTextureResolution); + + float divisor = 0.0f; + int sum = 0; + if((histogram_minmax.HistogramChannels & 0x1u) > 0) + { + sum += data.x; + divisor += 1.0f; + } + if((histogram_minmax.HistogramChannels & 0x2u) > 0) + { + sum += data.y; + divisor += 1.0f; + } + if((histogram_minmax.HistogramChannels & 0x4u) > 0) + { + sum += data.z; + divisor += 1.0f; + } + if((histogram_minmax.HistogramChannels & 0x8u) > 0) + { + sum += data.w; + divisor += 1.0f; + } + + if(divisor > 0.0f) + { + float val = float(sum)/divisor; + + float normalisedVal = (val - histogram_minmax.HistogramMin)/(histogram_minmax.HistogramMax - histogram_minmax.HistogramMin); + + if(normalisedVal < 0.0f) + normalisedVal = 2.0f; + + bucketIdx = uint(floor(normalisedVal*HGRAM_NUM_BUCKETS)); + } + } +#else + { + vec4 data = SampleTextureFloat4(texType, vec2(x, y), + histogram_minmax.HistogramSlice, + histogram_minmax.HistogramMip, + histogram_minmax.HistogramSample, + histogram_minmax.HistogramTextureResolution); float divisor = 0.0f; float sum = 0.0f; @@ -88,6 +179,7 @@ void main() bucketIdx = uint(floor(normalisedVal*HGRAM_NUM_BUCKETS)); } } +#endif if(bucketIdx >= 0 && bucketIdx < HGRAM_NUM_BUCKETS) atomicAdd(dest.result[bucketIdx], 1U); diff --git a/renderdoc/data/spv/minmaxresult.comp b/renderdoc/data/spv/minmaxresult.comp index feb59dd2a..ef9be247c 100644 --- a/renderdoc/data/spv/minmaxresult.comp +++ b/renderdoc/data/spv/minmaxresult.comp @@ -24,12 +24,24 @@ layout(binding=0, std140) writeonly buffer minmaxresultdest { +#if UINT_TEX + uvec4 result[2]; +#elif SINT_TEX + ivec4 result[2]; +#else vec4 result[2]; +#endif } dest; layout(binding=1, std140) readonly buffer minmaxtilesrc { +#if UINT_TEX + uvec4 tiles[]; +#elif SINT_TEX + ivec4 tiles[]; +#else vec4 tiles[]; +#endif } src; layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in; @@ -41,8 +53,16 @@ void main() uint blocksX = uint(ceil(float(texDim.x)/float(HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK))); uint blocksY = uint(ceil(float(texDim.y)/float(HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK))); +#if UINT_TEX + uvec4 minvalU = src.tiles[0]; + uvec4 maxvalU = src.tiles[1]; +#elif SINT_TEX + ivec4 minvalI = src.tiles[0]; + ivec4 maxvalI = src.tiles[1]; +#else vec4 minvalF = src.tiles[0]; vec4 maxvalF = src.tiles[1]; +#endif // i is the tile we're looking at for(uint i=1; i < blocksX*blocksY*HGRAM_TILES_PER_BLOCK*HGRAM_TILES_PER_BLOCK; i++) @@ -58,12 +78,28 @@ void main() if(blockXY.x*(HGRAM_TILES_PER_BLOCK*HGRAM_TILES_PER_BLOCK) + tileXY.x*HGRAM_PIXELS_PER_TILE < texDim.x && blockXY.y*(HGRAM_TILES_PER_BLOCK*HGRAM_TILES_PER_BLOCK) + tileXY.y*HGRAM_PIXELS_PER_TILE < texDim.y) { +#if UINT_TEX + minvalU = min(minvalU, src.tiles[i*2 + 0]); + maxvalU = max(maxvalU, src.tiles[i*2 + 1]); +#elif SINT_TEX + minvalI = min(minvalI, src.tiles[i*2 + 0]); + maxvalI = max(maxvalI, src.tiles[i*2 + 1]); +#else minvalF = min(minvalF, src.tiles[i*2 + 0]); maxvalF = max(maxvalF, src.tiles[i*2 + 1]); +#endif } } +#if UINT_TEX + dest.result[0] = minvalU; + dest.result[1] = maxvalU; +#elif SINT_TEX + dest.result[0] = minvalI; + dest.result[1] = maxvalI; +#else dest.result[0] = minvalF; dest.result[1] = maxvalF; +#endif } diff --git a/renderdoc/data/spv/minmaxtile.comp b/renderdoc/data/spv/minmaxtile.comp index ff1a50c0b..1d51acb8d 100644 --- a/renderdoc/data/spv/minmaxtile.comp +++ b/renderdoc/data/spv/minmaxtile.comp @@ -24,11 +24,15 @@ layout(binding=0, std140) writeonly buffer minmaxtiledest { +#if UINT_TEX + uvec4 tiles[]; +#elif SINT_TEX + ivec4 tiles[]; +#else vec4 tiles[]; +#endif } dest; -layout (binding = 3) uniform sampler2D tex; - layout (local_size_x = HGRAM_TILES_PER_BLOCK, local_size_y = HGRAM_TILES_PER_BLOCK) in; void main() @@ -36,6 +40,8 @@ void main() uvec3 tid = gl_LocalInvocationID; uvec3 gid = gl_WorkGroupID; + int texType = SHADER_RESTYPE; + uvec3 texDim = uvec3(histogram_minmax.HistogramTextureResolution); uint blocksX = uint(ceil(float(texDim.x)/float(HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK))); @@ -46,15 +52,20 @@ void main() int i=0; +#if UINT_TEX { - vec4 minval = vec4(0,0,0,0); - vec4 maxval = vec4(0,0,0,0); + uvec4 minval = uvec4(0,0,0,0); + uvec4 maxval = uvec4(0,0,0,0); for(uint y=topleft.y; y < min(texDim.y, topleft.y + HGRAM_PIXELS_PER_TILE); y++) { for(uint x=topleft.x; x < min(texDim.x, topleft.x + HGRAM_PIXELS_PER_TILE); x++) { - vec4 data = textureLod(tex, vec2(x, y) / histogram_minmax.HistogramTextureResolution.xy, float(histogram_minmax.HistogramMip)); + uvec4 data = SampleTextureUInt4(texType, vec2(x, y), + histogram_minmax.HistogramSlice, + histogram_minmax.HistogramMip, + histogram_minmax.HistogramSample, + histogram_minmax.HistogramTextureResolution); if(i == 0) { @@ -73,5 +84,70 @@ void main() dest.tiles[outIdx*2+0] = minval; dest.tiles[outIdx*2+1] = maxval; } +#elif SINT_TEX + { + ivec4 minval = ivec4(0,0,0,0); + ivec4 maxval = ivec4(0,0,0,0); + + for(uint y=topleft.y; y < min(texDim.y, topleft.y + HGRAM_PIXELS_PER_TILE); y++) + { + for(uint x=topleft.x; x < min(texDim.x, topleft.x + HGRAM_PIXELS_PER_TILE); x++) + { + ivec4 data = SampleTextureSInt4(texType, vec2(x, y), + histogram_minmax.HistogramSlice, + histogram_minmax.HistogramMip, + histogram_minmax.HistogramSample, + histogram_minmax.HistogramTextureResolution); + + if(i == 0) + { + minval = maxval = data; + } + else + { + minval = min(minval, data); + maxval = max(maxval, data); + } + + i++; + } + } + + dest.tiles[outIdx*2+0] = minval; + dest.tiles[outIdx*2+1] = maxval; + } +#else + { + vec4 minval = vec4(0,0,0,0); + vec4 maxval = vec4(0,0,0,0); + + for(uint y=topleft.y; y < min(texDim.y, topleft.y + HGRAM_PIXELS_PER_TILE); y++) + { + for(uint x=topleft.x; x < min(texDim.x, topleft.x + HGRAM_PIXELS_PER_TILE); x++) + { + vec4 data = SampleTextureFloat4(texType, vec2(x, y), + histogram_minmax.HistogramSlice, + histogram_minmax.HistogramMip, + histogram_minmax.HistogramSample, + histogram_minmax.HistogramTextureResolution); + + if(i == 0) + { + minval = maxval = data; + } + else + { + minval = min(minval, data); + maxval = max(maxval, data); + } + + i++; + } + } + + dest.tiles[outIdx*2+0] = minval; + dest.tiles[outIdx*2+1] = maxval; + } +#endif } diff --git a/renderdoc/driver/vulkan/vk_debug.cpp b/renderdoc/driver/vulkan/vk_debug.cpp index f279b5b33..2f16bd310 100644 --- a/renderdoc/driver/vulkan/vk_debug.cpp +++ b/renderdoc/driver/vulkan/vk_debug.cpp @@ -297,9 +297,9 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev) m_HistogramDescSetLayout = VK_NULL_HANDLE; m_HistogramPipeLayout = VK_NULL_HANDLE; RDCEraseEl(m_HistogramDescSet); - m_MinMaxResultPipe = VK_NULL_HANDLE; - m_MinMaxTilePipe = VK_NULL_HANDLE; - m_HistogramPipe = VK_NULL_HANDLE; + RDCEraseEl(m_MinMaxResultPipe); + RDCEraseEl(m_MinMaxTilePipe); + RDCEraseEl(m_HistogramPipe); m_OutlineDescSetLayout = VK_NULL_HANDLE; m_OutlinePipeLayout = VK_NULL_HANDLE; @@ -467,7 +467,21 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev) { 0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, NULL, }, { 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, NULL, }, { 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, NULL, }, - { 3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, } + { 6, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, + { 7, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, + { 8, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, + { 9, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, + { 10, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, + { 11, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, + { 12, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, + { 13, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, + { 14, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, + { 15, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, + { 16, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, + { 17, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, + { 18, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, + { 19, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, + { 20, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, NULL, }, }; VkDescriptorSetLayoutCreateInfo descsetLayoutInfo = { @@ -712,6 +726,10 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev) for(size_t i=0; i < ARRAY_COUNT(module); i++) { + // these modules will be compiled later + if(i == HISTOGRAMCS || i == MINMAXTILECS || i == MINMAXRESULTCS) + continue; + sources[0] = "#version 430 core\n"; sources[2] = ""; sources[3] = shaderSources[i]; @@ -972,27 +990,96 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev) Unwrap(m_HistogramPipeLayout), VK_NULL_HANDLE, 0, // base pipeline VkPipeline }; + + sources.resize(5); + sources[0] = "#version 430 core\n"; + sources[1] = GetEmbeddedResource(spv_debuguniforms_h); + sources[2] = GetEmbeddedResource(spv_texsample_h); + + for(size_t t=eTexType_1D; t < eTexType_Max; t++) + { + for(size_t f=0; f < 3; f++) + { + VkShaderModule minmaxtile; + VkShaderModule minmaxresult; + VkShaderModule histogram; + string err; + vector *blob; + VkShaderModuleCreateInfo modinfo = { + VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, NULL, 0, + 0, NULL, + }; - compPipeInfo.stage.module = Unwrap(module[MINMAXTILECS]); - - vkr = vt->CreateComputePipelines(Unwrap(dev), VK_NULL_HANDLE, 1, &compPipeInfo, NULL, &m_MinMaxTilePipe); - RDCASSERT(vkr == VK_SUCCESS); - - GetResourceManager()->WrapResource(Unwrap(dev), m_MinMaxTilePipe); - - compPipeInfo.stage.module = Unwrap(module[MINMAXRESULTCS]); - - vkr = vt->CreateComputePipelines(Unwrap(dev), VK_NULL_HANDLE, 1, &compPipeInfo, NULL, &m_MinMaxResultPipe); - RDCASSERT(vkr == VK_SUCCESS); - - GetResourceManager()->WrapResource(Unwrap(dev), m_MinMaxResultPipe); - - compPipeInfo.stage.module = Unwrap(module[HISTOGRAMCS]); - - vkr = vt->CreateComputePipelines(Unwrap(dev), VK_NULL_HANDLE, 1, &compPipeInfo, NULL, &m_HistogramPipe); - RDCASSERT(vkr == VK_SUCCESS); - - GetResourceManager()->WrapResource(Unwrap(dev), m_HistogramPipe); + sources[3] = string("#define SHADER_RESTYPE ") + ToStr::Get(t) + "\n"; + sources[3] += string("#define UINT_TEX ") + (f == 1 ? "1" : "0") + "\n"; + sources[3] += string("#define SINT_TEX ") + (f == 2 ? "1" : "0") + "\n"; + + sources[4] = shaderSources[HISTOGRAMCS]; + + err = GetSPIRVBlob(eSPIRVCompute, sources, &blob); + RDCASSERT(err.empty() && blob); + + modinfo.codeSize = blob->size()*sizeof(uint32_t); + modinfo.pCode = &(*blob)[0]; + + vkr = vt->CreateShaderModule(Unwrap(dev), &modinfo, NULL, &histogram); + RDCASSERT(vkr == VK_SUCCESS); + + sources[4] = shaderSources[MINMAXTILECS]; + + err = GetSPIRVBlob(eSPIRVCompute, sources, &blob); + RDCASSERT(err.empty() && blob); + + modinfo.codeSize = blob->size()*sizeof(uint32_t); + modinfo.pCode = &(*blob)[0]; + + vkr = vt->CreateShaderModule(Unwrap(dev), &modinfo, NULL, &minmaxtile); + RDCASSERT(vkr == VK_SUCCESS); + + if(t == 1) + { + sources[4] = shaderSources[MINMAXRESULTCS]; + + err = GetSPIRVBlob(eSPIRVCompute, sources, &blob); + RDCASSERT(err.empty() && blob); + + modinfo.codeSize = blob->size()*sizeof(uint32_t); + modinfo.pCode = &(*blob)[0]; + + vkr = vt->CreateShaderModule(Unwrap(dev), &modinfo, NULL, &minmaxresult); + RDCASSERT(vkr == VK_SUCCESS); + } + + compPipeInfo.stage.module = minmaxtile; + + vkr = vt->CreateComputePipelines(Unwrap(dev), VK_NULL_HANDLE, 1, &compPipeInfo, NULL, &m_MinMaxTilePipe[t][f]); + RDCASSERT(vkr == VK_SUCCESS); + + GetResourceManager()->WrapResource(Unwrap(dev), m_MinMaxTilePipe[t][f]); + + compPipeInfo.stage.module = histogram; + + vkr = vt->CreateComputePipelines(Unwrap(dev), VK_NULL_HANDLE, 1, &compPipeInfo, NULL, &m_HistogramPipe[t][f]); + RDCASSERT(vkr == VK_SUCCESS); + + GetResourceManager()->WrapResource(Unwrap(dev), m_HistogramPipe[t][f]); + + compPipeInfo.stage.module = minmaxresult; + + if(t == 1) + { + vkr = vt->CreateComputePipelines(Unwrap(dev), VK_NULL_HANDLE, 1, &compPipeInfo, NULL, &m_MinMaxResultPipe[f]); + RDCASSERT(vkr == VK_SUCCESS); + + GetResourceManager()->WrapResource(Unwrap(dev), m_MinMaxResultPipe[f]); + } + + vt->DestroyShaderModule(Unwrap(dev), histogram, NULL); + vt->DestroyShaderModule(Unwrap(dev), minmaxtile, NULL); + if(t == 1) + vt->DestroyShaderModule(Unwrap(dev), minmaxresult, NULL); + } + } vt->DestroyRenderPass(Unwrap(dev), RGBA16RP, NULL); vt->DestroyRenderPass(Unwrap(dev), RGBA32RP, NULL); @@ -1017,6 +1104,11 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev) { m_MeshModules[2] = module[i]; } + else if(i == HISTOGRAMCS || i == MINMAXTILECS || i == MINMAXRESULTCS) + { + // not compiled normally + continue; + } else { vt->DestroyShaderModule(Unwrap(dev), Unwrap(module[i]), NULL); @@ -1680,22 +1772,28 @@ VulkanDebugManager::~VulkanDebugManager() GetResourceManager()->ReleaseWrappedResource(m_HistogramPipeLayout); } - if(m_MinMaxResultPipe != VK_NULL_HANDLE) + for(size_t t=1; t < eTexType_Max; t++) { - vt->DestroyPipeline(Unwrap(dev), Unwrap(m_MinMaxResultPipe), NULL); - GetResourceManager()->ReleaseWrappedResource(m_MinMaxResultPipe); - } + for(size_t f=0; f < 3; f++) + { + if(m_MinMaxTilePipe[t][f] != VK_NULL_HANDLE) + { + vt->DestroyPipeline(Unwrap(dev), Unwrap(m_MinMaxTilePipe[t][f]), NULL); + GetResourceManager()->ReleaseWrappedResource(m_MinMaxTilePipe[t][f]); + } - if(m_MinMaxTilePipe != VK_NULL_HANDLE) - { - vt->DestroyPipeline(Unwrap(dev), Unwrap(m_MinMaxTilePipe), NULL); - GetResourceManager()->ReleaseWrappedResource(m_MinMaxTilePipe); - } + if(m_HistogramPipe[t][f] != VK_NULL_HANDLE) + { + vt->DestroyPipeline(Unwrap(dev), Unwrap(m_HistogramPipe[t][f]), NULL); + GetResourceManager()->ReleaseWrappedResource(m_HistogramPipe[t][f]); + } - if(m_HistogramPipe != VK_NULL_HANDLE) - { - vt->DestroyPipeline(Unwrap(dev), Unwrap(m_HistogramPipe), NULL); - GetResourceManager()->ReleaseWrappedResource(m_HistogramPipe); + if(t == 1 && m_MinMaxResultPipe[f] != VK_NULL_HANDLE) + { + vt->DestroyPipeline(Unwrap(dev), Unwrap(m_MinMaxResultPipe[f]), NULL); + GetResourceManager()->ReleaseWrappedResource(m_MinMaxResultPipe[f]); + } + } } m_ReadbackWindow.Destroy(vt, dev); diff --git a/renderdoc/driver/vulkan/vk_debug.h b/renderdoc/driver/vulkan/vk_debug.h index b76a76924..03f34ff27 100644 --- a/renderdoc/driver/vulkan/vk_debug.h +++ b/renderdoc/driver/vulkan/vk_debug.h @@ -214,6 +214,15 @@ class VulkanDebugManager GPUBuffer m_MeshUBO, m_MeshBBoxVB, m_MeshAxisFrustumVB; VkShaderModule m_MeshModules[3]; + enum TextureType + { + eTexType_1D = 1, // implicitly an array + eTexType_2D, // implicitly an array + eTexType_3D, + eTexType_2DMS, + eTexType_Max + }; + GPUBuffer m_MinMaxTileResult; // tile result buffer GPUBuffer m_MinMaxResult, m_MinMaxReadback; // Vec4f[2] final result buffer GPUBuffer m_HistogramBuf, m_HistogramReadback; // uint32_t * num buckets buffer @@ -221,9 +230,9 @@ class VulkanDebugManager VkPipelineLayout m_HistogramPipeLayout; VkDescriptorSet m_HistogramDescSet[2]; GPUBuffer m_HistogramUBO; - VkPipeline m_MinMaxResultPipe; - VkPipeline m_MinMaxTilePipe; - VkPipeline m_HistogramPipe; + VkPipeline m_HistogramPipe[eTexType_Max][3]; // float, uint, sint + VkPipeline m_MinMaxTilePipe[eTexType_Max][3]; // float, uint, sint + VkPipeline m_MinMaxResultPipe[3]; // float, uint, sint VkDescriptorSetLayout m_OutlineDescSetLayout; VkPipelineLayout m_OutlinePipeLayout; diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index dd9602f3a..0a1312e86 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -1241,6 +1241,11 @@ void VulkanReplay::CreateTexImageView(VkImageAspectFlags aspectFlags, VkImage li { aspectFlags, 0, RDCMAX(1U, (uint32_t)iminfo.mipLevels), 0, RDCMAX(1U, (uint32_t)iminfo.arrayLayers), }, }; + if(iminfo.type == VK_IMAGE_TYPE_1D) + viewInfo.viewType = VK_IMAGE_VIEW_TYPE_1D; + if(iminfo.type == VK_IMAGE_TYPE_3D) + viewInfo.viewType = VK_IMAGE_VIEW_TYPE_3D; + if(aspectFlags == VK_IMAGE_ASPECT_DEPTH_BIT) { viewInfo.components.r = VK_COMPONENT_SWIZZLE_R; @@ -3457,9 +3462,42 @@ bool VulkanReplay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, RDCASSERT(liveImView != VK_NULL_HANDLE); VkDescriptorImageInfo imdesc = {0}; - imdesc.imageLayout = VK_IMAGE_LAYOUT_GENERAL; + imdesc.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; imdesc.imageView = Unwrap(liveImView); imdesc.sampler = Unwrap(GetDebugManager()->m_PointSampler); + + int descSetBinding = 0; + uint32_t intTypeIndex = 0; + + if(IsUIntFormat(iminfo.format)) + { + descSetBinding = 10; + intTypeIndex = 1; + } + else if(IsSIntFormat(iminfo.format)) + { + descSetBinding = 15; + intTypeIndex = 2; + } + else + { + descSetBinding = 5; + } + + int textype = 0; + + if(iminfo.type == VK_IMAGE_TYPE_1D) + textype = RESTYPE_TEX1D; + if(iminfo.type == VK_IMAGE_TYPE_3D) + textype = RESTYPE_TEX3D; + if(iminfo.type == VK_IMAGE_TYPE_2D) + { + textype = RESTYPE_TEX2D; + if(iminfo.samples != VK_SAMPLE_COUNT_1_BIT) + textype = RESTYPE_TEX2DMS; + } + + descSetBinding += textype; VkDescriptorBufferInfo bufdescs[3]; RDCEraseEl(bufdescs); @@ -3491,7 +3529,7 @@ bool VulkanReplay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(GetDebugManager()->m_HistogramDescSet[0]), - 3, 0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + descSetBinding, 0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imdesc, NULL, NULL }, @@ -3569,7 +3607,7 @@ bool VulkanReplay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, int blocksX = (int)ceil(iminfo.extent.width/float(HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK)); int blocksY = (int)ceil(iminfo.extent.height/float(HGRAM_PIXELS_PER_TILE*HGRAM_TILES_PER_BLOCK)); - vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(GetDebugManager()->m_MinMaxTilePipe)); + vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(GetDebugManager()->m_MinMaxTilePipe[textype][intTypeIndex])); vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(GetDebugManager()->m_HistogramPipeLayout), 0, 1, UnwrapPtr(GetDebugManager()->m_HistogramDescSet[0]), 0, NULL); @@ -3595,7 +3633,7 @@ bool VulkanReplay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, // ensure shader writes complete before coalescing the tiles DoPipelineBarrier(cmd, 1, &tilebarrier); - vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(GetDebugManager()->m_MinMaxResultPipe)); + vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(GetDebugManager()->m_MinMaxResultPipe[intTypeIndex])); vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(GetDebugManager()->m_HistogramPipeLayout), 0, 1, UnwrapPtr(GetDebugManager()->m_HistogramDescSet[1]), 0, NULL); @@ -3663,6 +3701,39 @@ bool VulkanReplay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t m aspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT; CreateTexImageView(aspectFlags, liveIm, iminfo); + + int descSetBinding = 0; + uint32_t intTypeIndex = 0; + + if(IsUIntFormat(iminfo.format)) + { + descSetBinding = 10; + intTypeIndex = 1; + } + else if(IsSIntFormat(iminfo.format)) + { + descSetBinding = 15; + intTypeIndex = 2; + } + else + { + descSetBinding = 5; + } + + int textype = 0; + + if(iminfo.type == VK_IMAGE_TYPE_1D) + textype = RESTYPE_TEX1D; + if(iminfo.type == VK_IMAGE_TYPE_3D) + textype = RESTYPE_TEX3D; + if(iminfo.type == VK_IMAGE_TYPE_2D) + { + textype = RESTYPE_TEX2D; + if(iminfo.samples != VK_SAMPLE_COUNT_1_BIT) + textype = RESTYPE_TEX2DMS; + } + + descSetBinding += textype; VkImageView liveImView = (aspectFlags == VK_IMAGE_ASPECT_STENCIL_BIT ? iminfo.stencilView : iminfo.view); @@ -3702,7 +3773,7 @@ bool VulkanReplay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t m { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, NULL, Unwrap(GetDebugManager()->m_HistogramDescSet[0]), - 3, 0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + descSetBinding, 0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imdesc, NULL, NULL }, }; @@ -3770,7 +3841,7 @@ bool VulkanReplay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t m vt->CmdFillBuffer(Unwrap(cmd), Unwrap(GetDebugManager()->m_HistogramBuf.buf), 0, GetDebugManager()->m_HistogramBuf.totalsize, 0); - vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(GetDebugManager()->m_HistogramPipe)); + vt->CmdBindPipeline(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(GetDebugManager()->m_HistogramPipe[textype][intTypeIndex])); vt->CmdBindDescriptorSets(Unwrap(cmd), VK_PIPELINE_BIND_POINT_COMPUTE, Unwrap(GetDebugManager()->m_HistogramPipeLayout), 0, 1, UnwrapPtr(GetDebugManager()->m_HistogramDescSet[0]), 0, NULL);