Skip to content

Commit

Permalink
Adding an image load failure case to the shader debug zoo and impleme…
Browse files Browse the repository at this point in the history
…nting a fix
  • Loading branch information
Honeybunch committed Nov 15, 2024
1 parent d1663d9 commit 29efc74
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 20 deletions.
8 changes: 8 additions & 0 deletions renderdoc/driver/shaders/spirv/spirv_debug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2840,6 +2840,14 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray<ThreadState>
set0001(result);
}
}
else if(texType & DebugAPIWrapper::Buffer_Texture)
{
if(!debugger.GetAPIWrapper()->ReadTexelBuffer(img.GetBindIndex(), coord, result))
{
// sample failed. Pretend we got 0 columns back
set0001(result);
}
}
else
{
if(!debugger.GetAPIWrapper()->ReadTexel(img.GetBindIndex(), coord,
Expand Down
3 changes: 3 additions & 0 deletions renderdoc/driver/shaders/spirv/spirv_debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ class DebugAPIWrapper
virtual bool WriteTexel(ShaderBindIndex imageBind, const ShaderVariable &coord, uint32_t sample,
const ShaderVariable &value) = 0;

virtual bool ReadTexelBuffer(ShaderBindIndex bind, const ShaderVariable &coord,
ShaderVariable &output) = 0;

virtual void FillInputValue(ShaderVariable &var, ShaderBuiltin builtin, uint32_t location,
uint32_t component) = 0;

Expand Down
130 changes: 130 additions & 0 deletions renderdoc/driver/vulkan/vk_shaderdebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,91 @@ class VulkanAPIWrapper : public rdcspv::DebugAPIWrapper
return true;
}

virtual bool ReadTexelBuffer(ShaderBindIndex bind, const ShaderVariable &coord,
ShaderVariable &output) override
{
const TexelBufData &data = PopulateTexelBuffer(bind);

uint32_t index = uintComp(coord, 0);
uint64_t offset = index * data.texelSize;

if(offset + data.texelSize > data.bytes.size())
{
m_pDriver->AddDebugMessage(
MessageCategory::Execution, MessageSeverity::High, MessageSource::RuntimeWarning,
StringFormat::Fmt("Out of bounds access to buffer, index %u outside size of %u", index,
data.bytes.size() / data.texelSize));
return false;
}

CompType varComp = VarTypeCompType(output.type);

set0001(output);

ShaderVariable input;
input.columns = data.fmt.compCount;

if(data.fmt.compType == CompType::UInt)
{
RDCASSERT(varComp == CompType::UInt, varComp);

// set up input type for proper expansion below
if(data.fmt.compByteWidth == 1)
input.type = VarType::UByte;
else if(data.fmt.compByteWidth == 2)
input.type = VarType::UShort;
else if(data.fmt.compByteWidth == 4)
input.type = VarType::UInt;
else if(data.fmt.compByteWidth == 8)
input.type = VarType::ULong;

memcpy(input.value.u8v.data(), data.bytes.data() + offset, data.texelSize);

for(uint8_t c = 0; c < RDCMIN(output.columns, input.columns); c++)
setUintComp(output, c, uintComp(input, c));
}
else if(data.fmt.compType == CompType::SInt)
{
RDCASSERT(varComp == CompType::SInt, varComp);

// set up input type for proper expansion below
if(data.fmt.compByteWidth == 1)
input.type = VarType::SByte;
else if(data.fmt.compByteWidth == 2)
input.type = VarType::SShort;
else if(data.fmt.compByteWidth == 4)
input.type = VarType::SInt;
else if(data.fmt.compByteWidth == 8)
input.type = VarType::SLong;

memcpy(input.value.u8v.data(), data.bytes.data() + offset, data.texelSize);

for(uint8_t c = 0; c < RDCMIN(output.columns, input.columns); c++)
setIntComp(output, c, intComp(input, c));
}
else
{
RDCASSERT(varComp == CompType::Float, varComp);

// do the decode of whatever unorm/float/etc the format is
FloatVector v = DecodeFormattedComponents(data.fmt, data.bytes.data() + offset);

// set it into f32v
input.value.f32v[0] = v.x;
input.value.f32v[1] = v.y;
input.value.f32v[2] = v.z;
input.value.f32v[3] = v.w;

// read as floats
input.type = VarType::Float;

for(uint8_t c = 0; c < RDCMIN(output.columns, input.columns); c++)
setFloatComp(output, c, input.value.f32v[c]);
}

return true;
}

virtual void FillInputValue(ShaderVariable &var, ShaderBuiltin builtin, uint32_t location,
uint32_t component) override
{
Expand Down Expand Up @@ -1526,7 +1611,15 @@ class VulkanAPIWrapper : public rdcspv::DebugAPIWrapper
}
};

struct TexelBufData
{
uint32_t texelSize = 0;
ResourceFormat fmt;
bytebuf bytes;
};

std::map<ShaderBindIndex, ImageData> imageCache;
std::map<ShaderBindIndex, TexelBufData> texelBufCache;

const Descriptor &GetDescriptor(const rdcstr &access, ShaderBindIndex index, bool &valid)
{
Expand Down Expand Up @@ -1766,6 +1859,43 @@ class VulkanAPIWrapper : public rdcspv::DebugAPIWrapper
return data;
}

TexelBufData &PopulateTexelBuffer(ShaderBindIndex bind)
{
auto insertIt = texelBufCache.insert(std::make_pair(bind, TexelBufData()));
TexelBufData &data = insertIt.first->second;
if(insertIt.second)
{
bool valid = true;
const Descriptor &bufData = GetDescriptor("accessing texel buffer value", bind, valid);
if(valid)
{
// if the resources might be dirty from side-effects from the action, replay back to right
// before it.
if(m_ResourcesDirty)
{
VkMarkerRegion region("un-dirtying resources");
m_pDriver->ReplayLog(0, m_EventID, eReplay_WithoutDraw);
m_ResourcesDirty = false;
}

if(bufData.resource != ResourceId())
{
const VulkanCreationInfo::BufferView &viewProps =
m_Creation.m_BufferView[m_pDriver->GetResourceManager()->GetLiveID(bufData.view)];

data.fmt = MakeResourceFormat(viewProps.format);
data.texelSize = (uint32_t)GetByteSize(1, 1, 1, viewProps.format, 0);

m_pDriver->GetReplay()->GetBufferData(
m_pDriver->GetResourceManager()->GetLiveID(bufData.resource), bufData.byteOffset,
bufData.byteSize, data.bytes);
}
}
}

return data;
}

VkPipeline MakePipe(const ShaderConstParameters &params, uint32_t floatBitSize, bool depthTex,
bool uintTex, bool sintTex)
{
Expand Down
53 changes: 33 additions & 20 deletions util/test/demos/vk/vk_shader_debug_zoo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,21 +167,23 @@ layout(set = 0, binding = 16, rgba32f) uniform coherent image2D storeImage;
layout(set = 0, binding = 17) uniform samplerBuffer texBuffer;
layout(set = 0, binding = 18, rgba32f) uniform coherent imageBuffer storeTexBuffer;
layout(set = 0, binding = 19) uniform sampler shadowSampler;
layout(set = 0, binding = 19, rgba8ui) uniform coherent uimageBuffer storeTexBufferUint;
layout(set = 0, binding = 20) uniform samplerCube cubeSampler;
layout(set = 0, binding = 20) uniform sampler shadowSampler;
layout(set = 0, binding = 21, std430) buffer atomicbuftype
layout(set = 0, binding = 21) uniform samplerCube cubeSampler;
layout(set = 0, binding = 22, std430) buffer atomicbuftype
{
uvec4 data[];
} atomicbuf;
layout(set = 0, r32ui, binding = 22) uniform uimage2D atomicimg;
layout(set = 0, r32ui, binding = 23) uniform uimage2D atomicimg;
layout(set = 0, binding = 30) uniform sampler2DArray queryTest;
layout(set = 0, binding = 31) uniform sampler2DMSArray queryTestMS;
layout(set = 0, binding = 31) uniform sampler2DArray queryTest;
layout(set = 0, binding = 32) uniform sampler2DMSArray queryTestMS;
layout(set = 0, binding = 32) uniform texture2D depthImage;
layout(set = 0, binding = 33) uniform texture2D depthImage;
#if TEST_DESC_INDEXING
Expand Down Expand Up @@ -1576,6 +1578,11 @@ void main()
Color += vec4(1.0, 1.0, 1.0, 1.0);
break;
}
case 177:
{
Color = vec4(imageLoad(storeTexBufferUint, int(zeroi+2)).x, 1, 0, 1);
break;
}
default: break;
}
}
Expand Down Expand Up @@ -4111,13 +4118,14 @@ OpMemberDecorate %cbuffer_struct 17 Offset 216 ; double doublePackSource
{16, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
{17, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
{18, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
{19, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
{20, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
{21, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
{22, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
{30, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
{19, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
{20, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
{21, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
{22, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
{23, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
{31, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
{32, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
{32, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
{33, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
}));

std::vector<VkDescriptorSetLayout> setLayouts = {setlayout0};
Expand Down Expand Up @@ -4643,6 +4651,9 @@ OpMemberDecorate %cbuffer_struct 17 Offset 216 ; double doublePackSource
VkBufferView store_bufview = createBufferView(
vkh::BufferViewCreateInfo(store_texbuffer.buffer, VK_FORMAT_R32G32B32A32_SFLOAT));

VkBufferView store_bufview_uint =
createBufferView(vkh::BufferViewCreateInfo(store_texbuffer.buffer, VK_FORMAT_R8G8B8A8_UINT));

setName(pointsampler, "pointsampler");
setName(linearsampler, "linearsampler");
setName(mipsampler, "mipsampler");
Expand Down Expand Up @@ -4695,27 +4706,29 @@ OpMemberDecorate %cbuffer_struct 17 Offset 216 ; double doublePackSource
vkh::WriteDescriptorSet(descset0, 17, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, {bufview}),
vkh::WriteDescriptorSet(descset0, 18, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
{store_bufview}),
vkh::WriteDescriptorSet(descset0, 19, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
{store_bufview_uint}),
vkh::WriteDescriptorSet(
descset0, 19, VK_DESCRIPTOR_TYPE_SAMPLER,
descset0, 20, VK_DESCRIPTOR_TYPE_SAMPLER,
{vkh::DescriptorImageInfo(VK_NULL_HANDLE, VK_IMAGE_LAYOUT_UNDEFINED, shadowsampler)}),
vkh::WriteDescriptorSet(
descset0, 20, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
descset0, 21, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
{vkh::DescriptorImageInfo(randomcubeview, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
linearsampler)}),
vkh::WriteDescriptorSet(descset0, 21, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
vkh::WriteDescriptorSet(descset0, 22, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
{vkh::DescriptorBufferInfo(atomic_buffer.buffer)}),
vkh::WriteDescriptorSet(
descset0, 22, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
descset0, 23, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
{vkh::DescriptorImageInfo(atomic_view, VK_IMAGE_LAYOUT_GENERAL, VK_NULL_HANDLE)}),

vkh::WriteDescriptorSet(
descset0, 30, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
descset0, 31, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
{vkh::DescriptorImageInfo(queryTestView, VK_IMAGE_LAYOUT_GENERAL, mipsampler)}),
vkh::WriteDescriptorSet(
descset0, 31, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
descset0, 32, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
{vkh::DescriptorImageInfo(queryTestMSView, VK_IMAGE_LAYOUT_GENERAL, mipsampler)}),
vkh::WriteDescriptorSet(
descset0, 32, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
descset0, 33, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
{vkh::DescriptorImageInfo(shadowview, VK_IMAGE_LAYOUT_GENERAL, VK_NULL_HANDLE)}),
});

Expand Down

0 comments on commit 29efc74

Please sign in to comment.