From ca7c1bbba9ea5b5a625643bb3cbd56f55bb1ca69 Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 15 Apr 2020 11:14:17 +0100 Subject: [PATCH] Support push constants the same as constant buffer data --- renderdoc/driver/shaders/spirv/spirv_common.h | 3 ++ .../shaders/spirv/spirv_debug_setup.cpp | 22 ++++++++--- .../driver/shaders/spirv/spirv_reflect.h | 3 -- renderdoc/driver/vulkan/vk_shaderdebug.cpp | 37 +++++++++++++++---- util/test/demos/vk/vk_shader_debug_zoo.cpp | 15 ++++++-- 5 files changed, 60 insertions(+), 20 deletions(-) diff --git a/renderdoc/driver/shaders/spirv/spirv_common.h b/renderdoc/driver/shaders/spirv/spirv_common.h index f9af0ba6d..9ec0dfa49 100644 --- a/renderdoc/driver/shaders/spirv/spirv_common.h +++ b/renderdoc/driver/shaders/spirv/spirv_common.h @@ -220,6 +220,9 @@ public: }; // namespace rdcspv +static const uint32_t SpecializationConstantBindSet = 1234567; +static const uint32_t PushConstantBindSet = 1234568; + struct SpecConstant { SpecConstant() = default; diff --git a/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp b/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp index b32e29e49..d8a8dc62a 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp @@ -328,8 +328,8 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader } } - // pick up uniform globals, which could be cbuffers - else if(v.storage == StorageClass::Uniform && + // pick up uniform globals, which could be cbuffers, and push constants + else if((v.storage == StorageClass::Uniform || v.storage == StorageClass::PushConstant) && (decorations[v.id].flags & Decorations::BufferBlock) == 0) { ShaderVariable var; @@ -354,13 +354,23 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader // we have if(sourceName == var.name) { - sourceName = StringFormat::Fmt("_cbuffer_set%u_bind%u", decorations[v.id].set, - decorations[v.id].binding); + if(v.storage == StorageClass::PushConstant) + sourceName = "_pushconsts"; + else + sourceName = StringFormat::Fmt("_cbuffer_set%u_bind%u", decorations[v.id].set, + decorations[v.id].binding); + } + + Decorations d = decorations[v.id]; + + if(v.storage == StorageClass::PushConstant) + { + d.set = PushConstantBindSet; + d.flags = Decorations::Flags(d.flags | Decorations::HasDescriptorSet); } uint32_t offset = 0; - AllocateVariable(decorations[v.id], decorations[v.id], DebugVariableType::Constant, - sourceName, 0, innertype, var); + AllocateVariable(d, d, DebugVariableType::Constant, sourceName, 0, innertype, var); global.constantBlocks.push_back(var); cbufferIDs.push_back(v.id); diff --git a/renderdoc/driver/shaders/spirv/spirv_reflect.h b/renderdoc/driver/shaders/spirv/spirv_reflect.h index 910fa6228..77efeea59 100644 --- a/renderdoc/driver/shaders/spirv/spirv_reflect.h +++ b/renderdoc/driver/shaders/spirv/spirv_reflect.h @@ -133,9 +133,6 @@ private: }; // namespace rdcspv -static const uint32_t SpecializationConstantBindSet = 1234567; -static const uint32_t PushConstantBindSet = 1234568; - void FillSpecConstantVariables(ResourceId shader, const rdcarray &invars, rdcarray &outvars, const rdcarray &specInfo); diff --git a/renderdoc/driver/vulkan/vk_shaderdebug.cpp b/renderdoc/driver/vulkan/vk_shaderdebug.cpp index e84e6261d..50aacdca7 100644 --- a/renderdoc/driver/vulkan/vk_shaderdebug.cpp +++ b/renderdoc/driver/vulkan/vk_shaderdebug.cpp @@ -128,6 +128,18 @@ public: m_Creation.m_Pipeline[compute ? state.compute.pipeline : state.graphics.pipeline]; const VulkanCreationInfo::PipelineLayout &pipeLayout = m_Creation.m_PipelineLayout[pipe.layout]; + for(const VkPushConstantRange &range : pipeLayout.pushRanges) + { + if(range.stageFlags & stage) + { + pushData.resize(RDCMAX((uint32_t)pushData.size(), range.offset + range.size)); + + RDCASSERT(range.offset + range.size < sizeof(state.pushconsts)); + + memcpy(pushData.data() + range.offset, state.pushconsts + range.offset, range.size); + } + } + m_DescSets.resize(RDCMIN(descSets.size(), pipeLayout.descSetLayouts.size())); for(size_t set = 0; set < m_DescSets.size(); set++) { @@ -247,15 +259,22 @@ public: bytebuf &data = insertIt.first->second; if(insertIt.second) { - // TODO handle arrays here - BindpointIndex index(set, bind, 0); + if(set == PushConstantBindSet) + { + data = pushData; + } + else + { + // TODO handle arrays here + BindpointIndex index(set, bind, 0); - bool valid = true; - const VkDescriptorBufferInfo &bufData = - GetDescriptor("reading constant buffer value", index, valid); - if(valid) - m_pDriver->GetDebugManager()->GetBufferData(GetResID(bufData.buffer), bufData.offset, - bufData.range, data); + bool valid = true; + const VkDescriptorBufferInfo &bufData = + GetDescriptor("reading constant buffer value", index, valid); + if(valid) + m_pDriver->GetDebugManager()->GetBufferData(GetResID(bufData.buffer), bufData.offset, + bufData.range, data); + } } if(offset + byteSize <= data.size()) @@ -722,6 +741,8 @@ private: typedef rdcpair SamplerBiasKey; std::map m_BiasSamplers; + bytebuf pushData; + std::map, bytebuf> cbufferCache; template const T &GetDescriptor(const rdcstr &access, BindpointIndex index, bool &valid) diff --git a/util/test/demos/vk/vk_shader_debug_zoo.cpp b/util/test/demos/vk/vk_shader_debug_zoo.cpp index 378e99700..2c5d81f4a 100644 --- a/util/test/demos/vk/vk_shader_debug_zoo.cpp +++ b/util/test/demos/vk/vk_shader_debug_zoo.cpp @@ -134,6 +134,10 @@ layout(set = 0, binding = 5, std430) buffer storebuftype //layout(set = 0, binding = 7, rgba32f) uniform coherent samplerBuffer texBuffer; //layout(set = 0, binding = 8, rgba32f) uniform coherent imageBuffer storeTexBuffer; +layout(push_constant) uniform PushData { + layout(offset = 16) ivec4 data; +} push; + #define inout_type in )EOSHADER" + v2f + R"EOSHADER( @@ -499,6 +503,11 @@ void main() Color = vec4(isnan(posinf) ? 1.0f : 0.0f, isnan(neginf) ? 1.0f : 0.0f, isnan(nan) ? 1.0f : 0.0f, 1.0f); break; } + case 56: + { + Color = vec4(push.data); + break; + } default: break; } } @@ -1481,7 +1490,7 @@ void main() })); VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo( - {setlayout}, {vkh::PushConstantRange(VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(Vec4i))})); + {setlayout}, {vkh::PushConstantRange(VK_SHADER_STAGE_FRAGMENT_BIT, 16, sizeof(Vec4i))})); // calculate number of tests, wrapping each row at 256 uint32_t texWidth = AlignUp(std::max(numGLSLTests, numASMTests), 256U); @@ -1763,7 +1772,7 @@ void main() Vec4i push = Vec4i(101, 103, 107, 109); vkh::cmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, {descset}, {}); - vkCmdPushConstants(cmd, layout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(Vec4i), &push); + vkCmdPushConstants(cmd, layout, VK_SHADER_STAGE_FRAGMENT_BIT, 16, sizeof(Vec4i), &push); vkCmdBeginRenderPass(cmd, vkh::RenderPassBeginInfo(renderPass, framebuffer, s, {vkh::ClearValue(0.0f, 0.0f, 0.0f, 0.0f)}), @@ -1788,7 +1797,7 @@ void main() vkCmdSetViewport(cmd, 0, 1, &v); vkh::cmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, {descset}, {}); - vkCmdPushConstants(cmd, layout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(Vec4i), &push); + vkCmdPushConstants(cmd, layout, VK_SHADER_STAGE_FRAGMENT_BIT, 16, sizeof(Vec4i), &push); vkCmdBeginRenderPass(cmd, vkh::RenderPassBeginInfo(renderPass, framebuffer, s, {vkh::ClearValue(0.0f, 0.0f, 0.0f, 0.0f)}),