diff --git a/renderdoc/driver/shaders/spirv/spirv_debug.cpp b/renderdoc/driver/shaders/spirv/spirv_debug.cpp index c79524536..338c70d72 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_debug.cpp @@ -2192,6 +2192,9 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray DebugAPIWrapper::TextureType texType = (DebugAPIWrapper::TextureType)img.value.u64v[TextureTypeVariableSlot]; + // should not be sampling or fetching from subpass textures + RDCASSERT((texType & DebugAPIWrapper::Subpass_Texture) == 0); + ShaderVariable result; result.type = resultType.scalar().Type(); @@ -2239,23 +2242,60 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray ShaderVariable result; result.type = resultType.scalar().Type(); - if(!debugger.GetAPIWrapper()->ReadTexel(img.GetBinding(), coord, - read.imageOperands.flags & ImageOperands::Sample - ? GetSrc(read.imageOperands.sample).value.uv[0] - : 0, - result)) - { - // sample failed. Pretend we got 0 columns back - result.value.uv[0] = 0; - result.value.uv[1] = 0; - result.value.uv[2] = 0; + DebugAPIWrapper::TextureType texType = + (DebugAPIWrapper::TextureType)img.value.u64v[TextureTypeVariableSlot]; - if(result.type == VarType::Float || result.type == VarType::Half) - result.value.fv[3] = 1.0f; - else if(result.type == VarType::Double) - result.value.dv[3] = 1.0; - else - result.value.uv[3] = 1; + if(texType & DebugAPIWrapper::Subpass_Texture) + { + // get current position + ShaderVariable curCoord; + debugger.GetAPIWrapper()->FillInputValue(curCoord, ShaderBuiltin::Position, 0, 0); + + // co-ords are relative to the current position + coord.value.uv[0] += curCoord.value.uv[0]; + coord.value.uv[1] += curCoord.value.uv[1]; + + // do it with samplegather as ImageFetch rather than a Read which caches the whole texture + // on the CPU for no reason (since we can't write to it) + + if(!debugger.GetAPIWrapper()->CalculateSampleGather( + *this, Op::ImageFetch, texType, img.GetBinding(), DebugAPIWrapper::invalidBind, + coord, ShaderVariable(), ShaderVariable(), ShaderVariable(), GatherChannel::Red, + ImageOperandsAndParamDatas(), result)) + { + // sample failed. Pretend we got 0 columns back + result.value.uv[0] = 0; + result.value.uv[1] = 0; + result.value.uv[2] = 0; + + if(result.type == VarType::Float || result.type == VarType::Half) + result.value.fv[3] = 1.0f; + else if(result.type == VarType::Double) + result.value.dv[3] = 1.0; + else + result.value.uv[3] = 1; + } + } + else + { + if(!debugger.GetAPIWrapper()->ReadTexel(img.GetBinding(), coord, + read.imageOperands.flags & ImageOperands::Sample + ? GetSrc(read.imageOperands.sample).value.uv[0] + : 0, + result)) + { + // sample failed. Pretend we got 0 columns back + result.value.uv[0] = 0; + result.value.uv[1] = 0; + result.value.uv[2] = 0; + + if(result.type == VarType::Float || result.type == VarType::Half) + result.value.fv[3] = 1.0f; + else if(result.type == VarType::Double) + result.value.dv[3] = 1.0; + else + result.value.uv[3] = 1; + } } result.rows = 1; diff --git a/renderdoc/driver/shaders/spirv/spirv_debug.h b/renderdoc/driver/shaders/spirv/spirv_debug.h index ae2354422..804a361f3 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug.h +++ b/renderdoc/driver/shaders/spirv/spirv_debug.h @@ -74,6 +74,7 @@ public: SInt_Texture = 0x02, Buffer_Texture = 0x10, + Subpass_Texture = 0x20, }; static const BindpointIndex invalidBind; diff --git a/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp b/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp index ac130a404..397e62ff4 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp @@ -214,6 +214,7 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader case Capability::SampleRateShading: case Capability::ImageRect: case Capability::SampledRect: + case Capability::InputAttachment: case Capability::MinLod: case Capability::Sampled1D: case Capability::Image1D: @@ -310,13 +311,6 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader case Capability::GroupNonUniformQuad: case Capability::SubgroupBallotKHR: case Capability::SubgroupVoteKHR: - { - supported = false; - break; - } - - // input attachments - case Capability::InputAttachment: // sparse operations case Capability::SparseResidency: @@ -325,6 +319,10 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader case Capability::FragmentShaderSampleInterlockEXT: case Capability::FragmentShaderShadingRateInterlockEXT: case Capability::FragmentShaderPixelInterlockEXT: + { + supported = false; + break; + } // no plans to support these - mostly Kernel/OpenCL related or vendor extensions case Capability::Addresses: @@ -832,6 +830,9 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader if(imageTypes[imgid].dim == Dim::Buffer) texType |= DebugAPIWrapper::Buffer_Texture; + if(imageTypes[imgid].dim == Dim::SubpassData) + texType |= DebugAPIWrapper::Subpass_Texture; + if(imageTypes[imgid].retType.type == Op::TypeInt) { if(imageTypes[imgid].retType.signedness) @@ -842,7 +843,7 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader var.value.u64v[TextureTypeVariableSlot] = texType; - if(imageTypes[imgid].sampled == 2) + if(imageTypes[imgid].sampled == 2 && imageTypes[imgid].dim != Dim::SubpassData) { var.type = VarType::ReadWriteResource; debugType = DebugVariableType::ReadWriteResource; diff --git a/renderdoc/driver/vulkan/vk_shaderdebug.cpp b/renderdoc/driver/vulkan/vk_shaderdebug.cpp index 02e886bff..d9fd54213 100644 --- a/renderdoc/driver/vulkan/vk_shaderdebug.cpp +++ b/renderdoc/driver/vulkan/vk_shaderdebug.cpp @@ -3473,6 +3473,7 @@ ShaderDebugTrace *VulkanReplay::DebugPixel(uint32_t eventId, uint32_t x, uint32_ std::map &builtins = apiWrapper->builtin_inputs; builtins[ShaderBuiltin::DeviceIndex] = ShaderVariable(rdcstr(), 0U, 0U, 0U, 0U); builtins[ShaderBuiltin::DrawIndex] = ShaderVariable(rdcstr(), draw->drawIndex, 0U, 0U, 0U); + builtins[ShaderBuiltin::Position] = ShaderVariable(rdcstr(), x, y, 0U, 0U); // If the pipe contains a geometry shader, then Primitive ID cannot be used in the pixel // shader without being emitted from the geometry shader. For now, check if this semantic