-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding an image load failure case to the shader debug zoo and implementing a fix #3484
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1705,35 +1705,73 @@ class VulkanAPIWrapper : public rdcspv::DebugAPIWrapper | |
|
||
if(imgData.view != ResourceId()) | ||
{ | ||
const VulkanCreationInfo::ImageView &viewProps = | ||
const VulkanCreationInfo::ImageView &imgViewProps = | ||
m_Creation.m_ImageView[m_pDriver->GetResourceManager()->GetLiveID(imgData.view)]; | ||
const VulkanCreationInfo::Image &imageProps = m_Creation.m_Image[viewProps.image]; | ||
const VulkanCreationInfo::BufferView &bufViewProps = | ||
m_Creation.m_BufferView[m_pDriver->GetResourceManager()->GetLiveID(imgData.view)]; | ||
|
||
uint32_t mip = viewProps.range.baseMipLevel; | ||
bool resourceIsImage = false; | ||
uint32_t mip = 0; | ||
uint32_t numSlices = 0; | ||
uint32_t numSamples = 0; | ||
|
||
data.width = RDCMAX(1U, imageProps.extent.width >> mip); | ||
data.height = RDCMAX(1U, imageProps.extent.height >> mip); | ||
if(imageProps.type == VK_IMAGE_TYPE_3D) | ||
if(imgViewProps.image != ResourceId()) | ||
{ | ||
data.depth = RDCMAX(1U, imageProps.extent.depth >> mip); | ||
resourceIsImage = true; | ||
const VulkanCreationInfo::Image &imageProps = m_Creation.m_Image[imgViewProps.image]; | ||
|
||
mip = imgViewProps.range.baseMipLevel; | ||
|
||
data.width = RDCMAX(1U, imageProps.extent.width >> mip); | ||
data.height = RDCMAX(1U, imageProps.extent.height >> mip); | ||
if(imageProps.type == VK_IMAGE_TYPE_3D) | ||
{ | ||
data.depth = RDCMAX(1U, imageProps.extent.depth >> mip); | ||
} | ||
else | ||
{ | ||
data.depth = imgViewProps.range.layerCount; | ||
if(data.depth == VK_REMAINING_ARRAY_LAYERS) | ||
data.depth = imageProps.arrayLayers - imgViewProps.range.baseArrayLayer; | ||
} | ||
|
||
ResourceFormat fmt = MakeResourceFormat(imageProps.format); | ||
|
||
data.fmt = MakeResourceFormat(imageProps.format); | ||
data.texelSize = (uint32_t)GetByteSize(1, 1, 1, imageProps.format, 0); | ||
data.rowPitch = (uint32_t)GetByteSize(data.width, 1, 1, imageProps.format, 0); | ||
data.slicePitch = GetByteSize(data.width, data.height, 1, imageProps.format, 0); | ||
data.samplePitch = GetByteSize(data.width, data.height, data.depth, imageProps.format, 0); | ||
|
||
numSlices = imageProps.type == VK_IMAGE_TYPE_3D ? 1 : data.depth; | ||
numSamples = (uint32_t)imageProps.samples; | ||
} | ||
else | ||
else if(bufViewProps.buffer != ResourceId()) | ||
{ | ||
data.depth = viewProps.range.layerCount; | ||
if(data.depth == VK_REMAINING_ARRAY_LAYERS) | ||
data.depth = imageProps.arrayLayers - viewProps.range.baseArrayLayer; | ||
} | ||
const VulkanCreationInfo::Buffer &bufferProps = m_Creation.m_Buffer[bufViewProps.buffer]; | ||
|
||
ResourceFormat fmt = MakeResourceFormat(bufViewProps.format); | ||
|
||
ResourceFormat fmt = MakeResourceFormat(imageProps.format); | ||
mip = 0; | ||
data.width = (uint32_t)(bufferProps.size / (fmt.compByteWidth * fmt.compCount)); | ||
data.height = 1; | ||
data.depth = 1; | ||
|
||
data.fmt = MakeResourceFormat(imageProps.format); | ||
data.texelSize = (uint32_t)GetByteSize(1, 1, 1, imageProps.format, 0); | ||
data.rowPitch = (uint32_t)GetByteSize(data.width, 1, 1, imageProps.format, 0); | ||
data.slicePitch = GetByteSize(data.width, data.height, 1, imageProps.format, 0); | ||
data.samplePitch = GetByteSize(data.width, data.height, data.depth, imageProps.format, 0); | ||
data.fmt = fmt; | ||
data.texelSize = (uint32_t)GetByteSize(1, 1, 1, bufViewProps.format, 0); | ||
data.rowPitch = (uint32_t)GetByteSize(data.width, 1, 1, bufViewProps.format, 0); | ||
data.slicePitch = GetByteSize(data.width, data.height, 1, bufViewProps.format, 0); | ||
data.samplePitch = | ||
GetByteSize(data.width, data.height, data.depth, bufViewProps.format, 0); | ||
|
||
const uint32_t numSlices = imageProps.type == VK_IMAGE_TYPE_3D ? 1 : data.depth; | ||
const uint32_t numSamples = (uint32_t)imageProps.samples; | ||
numSlices = 1; | ||
numSamples = data.width; | ||
} | ||
else | ||
{ | ||
// Should be unreachable. If we have a view to neither a valid image or buffer, something is wrong | ||
RDCASSERT(false); | ||
} | ||
|
||
data.bytes.reserve(size_t(data.samplePitch * numSamples)); | ||
|
||
|
@@ -1745,8 +1783,17 @@ class VulkanAPIWrapper : public rdcspv::DebugAPIWrapper | |
for(uint32_t slice = 0; slice < numSlices; slice++) | ||
{ | ||
bytebuf subBytes; | ||
m_pDriver->GetReplay()->GetTextureData( | ||
viewProps.image, Subresource(mip, slice, sample), params, subBytes); | ||
if(resourceIsImage) | ||
{ | ||
m_pDriver->GetReplay()->GetTextureData( | ||
imgViewProps.image, Subresource(mip, slice, sample), params, subBytes); | ||
} | ||
else | ||
{ | ||
const uint64_t length = data.samplePitch; | ||
const uint64_t offset = bufViewProps.offset + ((slice * numSamples) + sample); | ||
m_pDriver->GetReplay()->GetBufferData(bufViewProps.buffer, offset, length, subBytes); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is getting called multiple times when it could be a single call |
||
} | ||
|
||
// fast path, swap into output if there's only one slice and one sample (common case) | ||
if(numSlices == 1 && numSamples == 1) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -183,6 +183,8 @@ layout(set = 0, binding = 31) uniform sampler2DMSArray queryTestMS; | |
|
||
layout(set = 0, binding = 32) uniform texture2D depthImage; | ||
|
||
layout(set = 0, binding = 33, rgba8ui) uniform uimageBuffer texBufferUint; | ||
layout(set = 0, binding = 34, rgba8ui) uniform coherent uimageBuffer storeTexBufferUint; | ||
#if TEST_DESC_INDEXING | ||
|
||
layout(set = 1, binding = 1) uniform sampler pointSamplers[14]; | ||
|
@@ -1576,6 +1578,17 @@ void main() | |
Color += vec4(1.0, 1.0, 1.0, 1.0); | ||
break; | ||
} | ||
case 177: | ||
{ | ||
Color = vec4(imageLoad(texBufferUint, int(zeroi+2)).x, 1, 0, 1); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Minor comment : this test does pass without the code change purely because the value at the offset is 0 and 0 is also returned by the failure case. Locally this change makes this test fail, by reading a non-zero value
|
||
break; | ||
} | ||
case 178: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you for adding this test : it does fail before the code change and passes after the code change |
||
{ | ||
imageStore(storeTexBufferUint, int(zeroi+2), uvec4(3, 4, 5, 2)); | ||
Color = imageLoad(storeTexBufferUint, int(zeroi+2)); | ||
break; | ||
} | ||
default: break; | ||
} | ||
} | ||
|
@@ -4118,6 +4131,8 @@ OpMemberDecorate %cbuffer_struct 17 Offset 216 ; double doublePackSource | |
{30, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 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}, | ||
{33, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT}, | ||
{34, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT}, | ||
})); | ||
|
||
std::vector<VkDescriptorSetLayout> setLayouts = {setlayout0}; | ||
|
@@ -4643,6 +4658,11 @@ OpMemberDecorate %cbuffer_struct 17 Offset 216 ; double doublePackSource | |
VkBufferView store_bufview = createBufferView( | ||
vkh::BufferViewCreateInfo(store_texbuffer.buffer, VK_FORMAT_R32G32B32A32_SFLOAT)); | ||
|
||
VkBufferView bufview_uint = | ||
createBufferView(vkh::BufferViewCreateInfo(texbuffer.buffer, VK_FORMAT_R8G8B8A8_UINT)); | ||
VkBufferView store_bufview_uint = | ||
createBufferView(vkh::BufferViewCreateInfo(store_texbuffer.buffer, VK_FORMAT_R8G8B8A8_UINT)); | ||
|
||
setName(pointsampler, "pointsampler"); | ||
setName(linearsampler, "linearsampler"); | ||
setName(mipsampler, "mipsampler"); | ||
|
@@ -4717,6 +4737,10 @@ OpMemberDecorate %cbuffer_struct 17 Offset 216 ; double doublePackSource | |
vkh::WriteDescriptorSet( | ||
descset0, 32, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, | ||
{vkh::DescriptorImageInfo(shadowview, VK_IMAGE_LAYOUT_GENERAL, VK_NULL_HANDLE)}), | ||
vkh::WriteDescriptorSet(descset0, 33, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, | ||
{bufview_uint}), | ||
vkh::WriteDescriptorSet(descset0, 34, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, | ||
{store_bufview_uint}), | ||
}); | ||
|
||
if(descIndexing) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think more simplification can be done still and also the call to
GetBufferData()
should be a single call to read all the required buffer data at once. CurrentlyGetBufferData()
is getting called to read the entire buffer x the number of elements in the buffer (which is too much data)Purely as an example here is an idea of how things can be simplified further and the buffer data retrieved in a single call.