Implement image dimension query opcodes

This commit is contained in:
baldurk
2020-04-16 18:41:59 +01:00
parent 9d5d9fa0bb
commit 7082f4eb44
4 changed files with 155 additions and 32 deletions
@@ -1824,6 +1824,10 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray<ThreadState>
SetDst(image.result, var);
break;
}
case Op::ImageQueryLevels:
case Op::ImageQuerySamples:
case Op::ImageQuerySize:
case Op::ImageQuerySizeLod:
case Op::ImageFetch:
case Op::ImageSampleExplicitLod:
case Op::ImageSampleImplicitLod:
@@ -1865,6 +1869,21 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray<ThreadState>
derivId = image.coordinate;
}
else if(opdata.op == Op::ImageQueryLevels || opdata.op == Op::ImageQuerySamples ||
opdata.op == Op::ImageQuerySize)
{
// these opcodes are all identical, they just query a property of the image
OpImageQueryLevels query(it);
img = GetSrc(query.image);
}
else if(opdata.op == Op::ImageQuerySizeLod)
{
OpImageQuerySizeLod query(it);
img = GetSrc(query.image);
operands.setLod(query.levelofDetail);
}
if(derivId != Id())
{
@@ -166,6 +166,7 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader
case Capability::ImageBuffer:
case Capability::ImageMSArray:
case Capability::StorageImageExtendedFormats:
case Capability::ImageQuery:
case Capability::DerivativeControl:
case Capability::TransformFeedback:
case Capability::GeometryStreams:
@@ -179,6 +180,7 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader
case Capability::MultiView:
case Capability::SampleMaskPostDepthCoverage:
case Capability::StencilExportEXT:
case Capability::ShaderClockKHR:
case Capability::ShaderViewportIndexLayerEXT:
case Capability::FragmentFullyCoveredEXT:
case Capability::FragmentDensityEXT:
@@ -196,6 +198,7 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader
case Capability::StorageTexelBufferArrayNonUniformIndexing:
case Capability::VulkanMemoryModel:
case Capability::VulkanMemoryModelDeviceScope:
case Capability::DemoteToHelperInvocationEXT:
{
supported = true;
break;
@@ -203,18 +206,12 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader
// we plan to support these but needs additional testing/proving
// image queries
case Capability::ImageQuery:
// image gather operations
case Capability::ImageGatherExtended:
// image storage
case Capability::StorageImageMultisample:
// demote to helper
case Capability::DemoteToHelperInvocationEXT:
// all these are related to non-32-bit types
case Capability::Float16Buffer:
case Capability::Float16:
@@ -252,9 +249,6 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader
case Capability::RoundingModeRTE:
case Capability::RoundingModeRTZ:
// shader clock
case Capability::ShaderClockKHR:
// group instructions
case Capability::Groups:
case Capability::GroupNonUniform:
+63 -19
View File
@@ -420,6 +420,69 @@ public:
return false;
}
switch(imageType)
{
case VK_IMAGE_TYPE_1D: params.dim = ShaderDebugBind::Tex1D; break;
case VK_IMAGE_TYPE_2D:
params.dim = ShaderDebugBind::Tex2D;
if(samples > 1)
params.dim = ShaderDebugBind::Tex2DMS;
break;
case VK_IMAGE_TYPE_3D: params.dim = ShaderDebugBind::Tex3D; break;
default:
{
RDCERR("Unsupported image type %s", ToStr(imageType).c_str());
return false;
}
}
if(buffer)
{
params.dim = ShaderDebugBind::Buffer;
coords = gradCoords = 1;
}
// handle query opcodes now
switch(opcode)
{
case rdcspv::Op::ImageQueryLevels:
{
output.value.u.x = viewProps.range.levelCount;
if(viewProps.range.levelCount == VK_REMAINING_MIP_LEVELS)
output.value.u.x = imageProps.mipLevels - viewProps.range.baseMipLevel;
return true;
}
case rdcspv::Op::ImageQuerySamples:
{
output.value.u.x = (uint32_t)imageProps.samples;
return true;
}
case rdcspv::Op::ImageQuerySize:
case rdcspv::Op::ImageQuerySizeLod:
{
uint32_t mip = viewProps.range.baseMipLevel;
if(opcode == rdcspv::Op::ImageQuerySizeLod)
mip += lane.GetSrc(operands.lod).value.u.x;
int i = 0;
output.value.uv[i++] = RDCMAX(1U, imageProps.extent.width >> mip);
if(coords >= 2)
output.value.uv[i++] = RDCMAX(1U, imageProps.extent.height >> mip);
if(viewProps.viewType == VK_IMAGE_VIEW_TYPE_3D)
output.value.uv[i++] = RDCMAX(1U, imageProps.extent.depth >> mip);
if(viewProps.viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY ||
viewProps.viewType == VK_IMAGE_VIEW_TYPE_2D_ARRAY)
output.value.uv[i++] = imageProps.arrayLayers;
else if(viewProps.viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
output.value.uv[i++] = imageProps.arrayLayers / 6;
return true;
}
default: break;
}
// create our own view (if we haven't already for this view) so we can promote to array
VkImageView sampleView = m_SampleViews[GetResID(view)];
if(sampleView == VK_NULL_HANDLE)
@@ -520,25 +583,6 @@ public:
params.operation = (uint32_t)opcode;
switch(imageType)
{
case VK_IMAGE_TYPE_1D: params.dim = ShaderDebugBind::Tex1D; break;
case VK_IMAGE_TYPE_2D:
params.dim = ShaderDebugBind::Tex2D;
if(samples > 1)
params.dim = ShaderDebugBind::Tex2DMS;
break;
case VK_IMAGE_TYPE_3D: params.dim = ShaderDebugBind::Tex3D; break;
default:
{
RDCERR("Unsupported image type %s", ToStr(imageType).c_str());
return false;
}
}
if(buffer)
params.dim = ShaderDebugBind::Buffer;
switch(opcode)
{
case rdcspv::Op::ImageFetch:
+70 -4
View File
@@ -134,6 +134,9 @@ 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(set = 0, binding = 20) uniform sampler2DArray queryTest;
layout(set = 0, binding = 21) uniform sampler2DMSArray queryTestMS;
layout(push_constant) uniform PushData {
layout(offset = 16) ivec4 data;
} push;
@@ -881,6 +884,31 @@ void main()
uintBitsToFloat(bitfieldInsert(a, af, 4, 5)), intBitsToFloat(bitfieldInsert(b, bf, 4, 5)));
break;
}
case 106:
{
Color = vec4(float(textureQueryLevels(queryTest)), float(textureSamples(queryTestMS)), 0.0f, 1.0f);
break;
}
case 107:
{
Color = vec4(vec3(textureSize(queryTest, 0)), 1.0f);
break;
}
case 108:
{
Color = vec4(vec3(textureSize(queryTest, 1)), 1.0f);
break;
}
case 109:
{
Color = vec4(vec3(textureSize(queryTestMS)), 1.0f);
break;
}
case 110:
{
Color = vec4(vec3(textureSize(queryTestMS)), 1.0f);
break;
}
default: break;
}
}
@@ -2033,6 +2061,8 @@ void main()
{6, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
{7, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
{8, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
{20, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
{21, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
}));
VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo(
@@ -2118,6 +2148,21 @@ void main()
Texture rgba8;
LoadXPM(SmileyTexture, rgba8);
AllocatedImage queryTest(this, vkh::ImageCreateInfo(183, 347, 0, VK_FORMAT_R8G8B8A8_UNORM,
VK_IMAGE_USAGE_SAMPLED_BIT, 4, 3),
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
VkImageView queryTestView = createImageView(vkh::ImageViewCreateInfo(
queryTest.image, VK_IMAGE_VIEW_TYPE_2D_ARRAY, VK_FORMAT_R8G8B8A8_UNORM));
AllocatedImage queryTestMS(
this, vkh::ImageCreateInfo(183, 347, 0, VK_FORMAT_R8G8B8A8_UNORM,
VK_IMAGE_USAGE_SAMPLED_BIT, 1, 5, VK_SAMPLE_COUNT_4_BIT),
VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_GPU_ONLY}));
VkImageView queryTestMSView = createImageView(vkh::ImageViewCreateInfo(
queryTestMS.image, VK_IMAGE_VIEW_TYPE_2D_ARRAY, VK_FORMAT_R8G8B8A8_UNORM));
AllocatedImage smiley(
this, vkh::ImageCreateInfo(rgba8.width, rgba8.height, 0, VK_FORMAT_R8G8B8A8_UNORM,
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT),
@@ -2137,10 +2182,15 @@ void main()
vkBeginCommandBuffer(cmd, vkh::CommandBufferBeginInfo());
vkh::cmdPipelineBarrier(
cmd, {
vkh::ImageMemoryBarrier(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, smiley.image),
});
cmd,
{
vkh::ImageMemoryBarrier(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, smiley.image),
vkh::ImageMemoryBarrier(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_GENERAL, queryTest.image),
vkh::ImageMemoryBarrier(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_GENERAL, queryTestMS.image),
});
VkBufferImageCopy copy = {};
copy.imageExtent = {rgba8.width, rgba8.height, 1};
@@ -2166,6 +2216,7 @@ void main()
VkSampler pointsampler = VK_NULL_HANDLE;
VkSampler linearsampler = VK_NULL_HANDLE;
VkSampler mipsampler = VK_NULL_HANDLE;
VkSamplerCreateInfo sampInfo = {VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO};
sampInfo.magFilter = VK_FILTER_NEAREST;
@@ -2178,6 +2229,10 @@ void main()
vkCreateSampler(device, &sampInfo, NULL, &linearsampler);
sampInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
vkCreateSampler(device, &sampInfo, NULL, &mipsampler);
VkDescriptorSet descset = allocateDescriptorSet(setlayout);
Vec4f cbufferdata[16] = {};
@@ -2225,6 +2280,9 @@ void main()
setName(pointsampler, "pointsampler");
setName(linearsampler, "linearsampler");
setName(mipsampler, "mipsampler");
setName(queryTest.image, "queryTest");
setName(queryTestMS.image, "queryTestMS");
setName(smiley.image, "smiley");
setName(texbuffer.buffer, "texbuffer");
setName(store_buffer.buffer, "store_buffer");
@@ -2258,6 +2316,13 @@ void main()
vkh::WriteDescriptorSet(descset, 7, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, {bufview}),
vkh::WriteDescriptorSet(descset, 8, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
{store_bufview}),
vkh::WriteDescriptorSet(
descset, 20, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
{vkh::DescriptorImageInfo(queryTestView, VK_IMAGE_LAYOUT_GENERAL, mipsampler)}),
vkh::WriteDescriptorSet(
descset, 21, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
{vkh::DescriptorImageInfo(queryTestMSView, VK_IMAGE_LAYOUT_GENERAL, mipsampler)}),
});
while(Running())
@@ -2382,6 +2447,7 @@ void main()
vkDestroySampler(device, pointsampler, NULL);
vkDestroySampler(device, linearsampler, NULL);
vkDestroySampler(device, mipsampler, NULL);
return 0;
}