mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-09-05 21:35:49 +00:00
Add support for accessing arrays of resources
This commit is contained in:
@@ -2179,7 +2179,7 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray<ThreadState>
|
||||
|
||||
// at setup time we stored the texture type for easy access here
|
||||
DebugAPIWrapper::TextureType texType =
|
||||
(DebugAPIWrapper::TextureType)img.value.uv[TextureTypeVariableSlot];
|
||||
(DebugAPIWrapper::TextureType)img.value.u64v[TextureTypeVariableSlot];
|
||||
|
||||
ShaderVariable result;
|
||||
|
||||
|
||||
@@ -101,10 +101,11 @@ public:
|
||||
|
||||
// this could be cleaner if ShaderVariable wasn't a very public struct, but it's not worth it so
|
||||
// we just reserve value slots that we know won't be used in opaque variables
|
||||
static const uint32_t TextureTypeVariableSlot = 8;
|
||||
static const uint32_t BufferPointerByteOffsetVariableSlot = 8;
|
||||
static const uint32_t BufferPointerTypeIdVariableSlot = 9;
|
||||
static const uint32_t SSBOVariableSlot = 10;
|
||||
static const uint32_t ArrayVariableSlot = 8;
|
||||
static const uint32_t TextureTypeVariableSlot = 9;
|
||||
static const uint32_t BufferPointerByteOffsetVariableSlot = 9;
|
||||
static const uint32_t BufferPointerTypeIdVariableSlot = 10;
|
||||
static const uint32_t SSBOVariableSlot = 11;
|
||||
|
||||
typedef ShaderVariable (*ExtInstImpl)(ThreadState &, uint32_t, const rdcarray<Id> &);
|
||||
|
||||
|
||||
@@ -406,7 +406,8 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader
|
||||
|
||||
for(const rdcstr &e : extensions)
|
||||
{
|
||||
if(e == "SPV_GOOGLE_decorate_string" || e == "SPV_GOOGLE_hlsl_functionality1")
|
||||
if(e == "SPV_GOOGLE_decorate_string" || e == "SPV_GOOGLE_hlsl_functionality1" ||
|
||||
e == "SPV_EXT_descriptor_indexing")
|
||||
{
|
||||
// supported extensions
|
||||
}
|
||||
@@ -514,19 +515,22 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader
|
||||
// global variables should all be pointers into opaque storage
|
||||
RDCASSERT(type.type == DataType::PointerType);
|
||||
|
||||
const DataType &innertype = dataTypes[type.InnerType()];
|
||||
const DataType *innertype = &dataTypes[type.InnerType()];
|
||||
|
||||
if(sourceName == var.name)
|
||||
sourceName = GetHumanName(innertype.id);
|
||||
sourceName = GetHumanName(innertype->id);
|
||||
|
||||
bool isArray = false;
|
||||
if(innertype->type == DataType::ArrayType)
|
||||
{
|
||||
isArray = true;
|
||||
innertype = &dataTypes[innertype->InnerType()];
|
||||
}
|
||||
|
||||
const bool ssbo = (v.storage == StorageClass::StorageBuffer) ||
|
||||
(decorations[innertype.id].flags & Decorations::BufferBlock);
|
||||
(decorations[innertype->id].flags & Decorations::BufferBlock);
|
||||
|
||||
if(innertype.type == DataType::ArrayType)
|
||||
{
|
||||
RDCERR("uniform Arrays not supported yet");
|
||||
}
|
||||
else if(innertype.type == DataType::StructType)
|
||||
if(innertype->type == DataType::StructType)
|
||||
{
|
||||
// if we don't have a good human name, generate a better one using the interface information
|
||||
// we have
|
||||
@@ -566,11 +570,13 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader
|
||||
if(decorations[v.id].flags & Decorations::HasBinding)
|
||||
bind = decorations[v.id].binding;
|
||||
|
||||
// TODO handle arrays
|
||||
var.SetBinding((int32_t)set, (int32_t)bind, 0U);
|
||||
|
||||
var.value.u64v[SSBOVariableSlot] = 1;
|
||||
|
||||
if(isArray)
|
||||
var.value.u64v[ArrayVariableSlot] = 1;
|
||||
|
||||
sourceVar.type = VarType::ReadWriteResource;
|
||||
sourceVar.rows = 1;
|
||||
sourceVar.columns = 1;
|
||||
@@ -583,7 +589,10 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader
|
||||
else
|
||||
{
|
||||
uint32_t offset = 0;
|
||||
AllocateVariable(d, d, DebugVariableType::Constant, sourceName, 0, innertype, var);
|
||||
AllocateVariable(d, d, DebugVariableType::Constant, sourceName, 0, *innertype, var);
|
||||
|
||||
if(isArray)
|
||||
RDCERR("Uniform buffer arrays not supported yet");
|
||||
|
||||
sourceVar.type = VarType::ConstantBlock;
|
||||
sourceVar.rows = 0;
|
||||
@@ -598,7 +607,7 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Unhandled type of uniform: %u", innertype.type);
|
||||
RDCERR("Unhandled type of uniform: %u", innertype->type);
|
||||
}
|
||||
}
|
||||
else if(v.storage == StorageClass::UniformConstant)
|
||||
@@ -616,18 +625,18 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader
|
||||
// global variables should all be pointers into opaque storage
|
||||
RDCASSERT(type.type == DataType::PointerType);
|
||||
|
||||
const DataType &innertype = dataTypes[type.InnerType()];
|
||||
const DataType *innertype = &dataTypes[type.InnerType()];
|
||||
|
||||
// if we don't have a good human name, generate a better one using the interface information
|
||||
// we have
|
||||
if(sourceName == var.name)
|
||||
{
|
||||
rdcstr innerName;
|
||||
if(innertype.type == DataType::SamplerType)
|
||||
if(innertype->type == DataType::SamplerType)
|
||||
innerName = "sampler";
|
||||
else if(innertype.type == DataType::SampledImageType)
|
||||
else if(innertype->type == DataType::SampledImageType)
|
||||
innerName = "sampledImage";
|
||||
else if(innertype.type == DataType::ImageType)
|
||||
else if(innertype->type == DataType::ImageType)
|
||||
innerName = "image";
|
||||
sourceName = StringFormat::Fmt("_%s_set%u_bind%u", innerName.c_str(), decorations[v.id].set,
|
||||
decorations[v.id].binding);
|
||||
@@ -641,10 +650,15 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader
|
||||
if(decorations[v.id].flags & Decorations::HasBinding)
|
||||
bind = decorations[v.id].binding;
|
||||
|
||||
// TODO handle arrays
|
||||
var.SetBinding((int32_t)set, (int32_t)bind, 0U);
|
||||
|
||||
if(innertype.type == DataType::SamplerType)
|
||||
if(innertype->type == DataType::ArrayType)
|
||||
{
|
||||
var.value.u64v[ArrayVariableSlot] = 1;
|
||||
innertype = &dataTypes[innertype->InnerType()];
|
||||
}
|
||||
|
||||
if(innertype->type == DataType::SamplerType)
|
||||
{
|
||||
var.type = VarType::Sampler;
|
||||
debugType = DebugVariableType::Sampler;
|
||||
@@ -652,7 +666,7 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader
|
||||
global.samplers.push_back(var);
|
||||
samplerIDs.push_back(v.id);
|
||||
}
|
||||
else if(innertype.type == DataType::SampledImageType || innertype.type == DataType::ImageType)
|
||||
else if(innertype->type == DataType::SampledImageType || innertype->type == DataType::ImageType)
|
||||
{
|
||||
var.type = VarType::ReadOnlyResource;
|
||||
debugType = DebugVariableType::ReadOnlyResource;
|
||||
@@ -663,7 +677,7 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader
|
||||
|
||||
Id imgid = type.InnerType();
|
||||
|
||||
if(innertype.type == DataType::SampledImageType)
|
||||
if(innertype->type == DataType::SampledImageType)
|
||||
imgid = sampledImageTypes[imgid].baseId;
|
||||
|
||||
if(imageTypes[imgid].dim == Dim::Buffer)
|
||||
@@ -677,7 +691,7 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader
|
||||
texType |= DebugAPIWrapper::UInt_Texture;
|
||||
}
|
||||
|
||||
var.value.uv[TextureTypeVariableSlot] = texType;
|
||||
var.value.u64v[TextureTypeVariableSlot] = texType;
|
||||
|
||||
if(imageTypes[imgid].sampled == 2)
|
||||
{
|
||||
@@ -695,7 +709,7 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Unhandled type of uniform: %u", innertype.type);
|
||||
RDCERR("Unhandled type of uniform: %u", innertype->type);
|
||||
}
|
||||
|
||||
SourceVariableMapping sourceVar;
|
||||
@@ -998,6 +1012,15 @@ ShaderVariable Debugger::MakeCompositePointer(const ShaderVariable &base, Id id,
|
||||
if(base.type == VarType::GPUPointer)
|
||||
leaf = (const ShaderVariable *)(uintptr_t)base.value.u64v[0];
|
||||
|
||||
bool isArray = false;
|
||||
|
||||
if((leaf->type == VarType::ReadWriteResource || leaf->type == VarType::ReadOnlyResource ||
|
||||
leaf->type == VarType::Sampler) &&
|
||||
leaf->value.u64v[ArrayVariableSlot])
|
||||
{
|
||||
isArray = true;
|
||||
}
|
||||
|
||||
if(leaf->type == VarType::ReadWriteResource && leaf->value.u64v[SSBOVariableSlot])
|
||||
{
|
||||
ShaderVariable ret = MakePointerVariable(id, leaf);
|
||||
@@ -1011,6 +1034,14 @@ ShaderVariable Debugger::MakeCompositePointer(const ShaderVariable &base, Id id,
|
||||
|
||||
// first walk any aggregate types
|
||||
size_t i = 0;
|
||||
|
||||
// if it's an array, consume the array index first
|
||||
if(isArray)
|
||||
{
|
||||
ret.value.u64v[ArrayVariableSlot] = indices[i++];
|
||||
type = &dataTypes[type->InnerType()];
|
||||
}
|
||||
|
||||
while(i < indices.size() &&
|
||||
(type->type == DataType::ArrayType || type->type == DataType::StructType))
|
||||
{
|
||||
@@ -1105,6 +1136,8 @@ ShaderVariable Debugger::MakeCompositePointer(const ShaderVariable &base, Id id,
|
||||
|
||||
// first walk any struct member/array indices
|
||||
size_t i = 0;
|
||||
if(isArray)
|
||||
i++;
|
||||
while(i < indices.size() && !leaf->members.empty())
|
||||
{
|
||||
leaf = &leaf->members[indices[i++]];
|
||||
@@ -1124,7 +1157,12 @@ ShaderVariable Debugger::MakeCompositePointer(const ShaderVariable &base, Id id,
|
||||
scalar0 = indices[i];
|
||||
}
|
||||
|
||||
return MakePointerVariable(id, leaf, scalar0, scalar1);
|
||||
ShaderVariable ret = MakePointerVariable(id, leaf, scalar0, scalar1);
|
||||
|
||||
if(isArray)
|
||||
ret.value.u64v[ArrayVariableSlot] = indices[0];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ShaderVariable Debugger::GetPointerValue(const ShaderVariable &ptr) const
|
||||
@@ -1135,6 +1173,9 @@ ShaderVariable Debugger::GetPointerValue(const ShaderVariable &ptr) const
|
||||
const ShaderVariable *inner = (const ShaderVariable *)(uintptr_t)ptr.value.u64v[0];
|
||||
ShaderVariable ret = *inner;
|
||||
ret.name = ptr.name;
|
||||
// inherit any array index from the pointer
|
||||
BindpointIndex bind = ret.GetBinding();
|
||||
ret.SetBinding(bind.bindset, bind.bind, (uint32_t)ptr.value.u64v[ArrayVariableSlot]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1159,6 +1200,8 @@ ShaderVariable Debugger::ReadFromPointer(const ShaderVariable &ptr) const
|
||||
|
||||
BindpointIndex bind = inner->GetBinding();
|
||||
|
||||
bind.arrayIndex = (uint32_t)ptr.value.u64v[ArrayVariableSlot];
|
||||
|
||||
WalkVariable(dataTypes[typeId], byteOffset, ret, true, [this, bind](ShaderVariable &var,
|
||||
const DataType &type,
|
||||
uint64_t offset) {
|
||||
@@ -1217,6 +1260,14 @@ ShaderVariable Debugger::ReadFromPointer(const ShaderVariable &ptr) const
|
||||
ret = *inner;
|
||||
ret.name = ptr.name;
|
||||
|
||||
if(inner->type == VarType::ReadOnlyResource || inner->type == VarType::ReadWriteResource ||
|
||||
inner->type == VarType::Sampler)
|
||||
{
|
||||
BindpointIndex bind = ret.GetBinding();
|
||||
|
||||
ret.SetBinding(bind.bindset, bind.bind, (uint32_t)ptr.value.u64v[ArrayVariableSlot]);
|
||||
}
|
||||
|
||||
// we don't support pointers to scalars since our 'unit' of pointer is a ShaderVariable, so check
|
||||
// if we have scalar indices to apply:
|
||||
uint32_t scalar0 = ptr.value.uv[2];
|
||||
@@ -1290,7 +1341,8 @@ bool Debugger::IsOpaquePointer(const ShaderVariable &ptr) const
|
||||
return false;
|
||||
|
||||
ShaderVariable *inner = (ShaderVariable *)(uintptr_t)ptr.value.u64v[0];
|
||||
return inner->type == VarType::ReadOnlyResource || inner->type == VarType::ReadWriteResource;
|
||||
return inner->type == VarType::ReadOnlyResource || inner->type == VarType::Sampler ||
|
||||
inner->type == VarType::ReadWriteResource;
|
||||
}
|
||||
|
||||
bool Debugger::ArePointersAndEqual(const ShaderVariable &a, const ShaderVariable &b) const
|
||||
@@ -1317,6 +1369,8 @@ void Debugger::WriteThroughPointer(const ShaderVariable &ptr, const ShaderVariab
|
||||
|
||||
BindpointIndex bind = storage->GetBinding();
|
||||
|
||||
bind.arrayIndex = (uint32_t)ptr.value.u64v[ArrayVariableSlot];
|
||||
|
||||
WalkVariable(dataTypes[typeId], byteOffset, (ShaderVariable &)val, false,
|
||||
[this, bind](ShaderVariable &var, const DataType &type, uint64_t offset) {
|
||||
if(type.type == DataType::MatrixType)
|
||||
|
||||
@@ -101,11 +101,12 @@ void main()
|
||||
#version 460 core
|
||||
|
||||
#extension GL_EXT_samplerless_texture_functions : require
|
||||
#extension GL_EXT_nonuniform_qualifier : require
|
||||
|
||||
layout(set = 0, binding = 0, std140) uniform constsbuf
|
||||
{
|
||||
vec4 first;
|
||||
vec4 pad1;
|
||||
uint uniformIndex;
|
||||
vec4 second;
|
||||
vec4 pad2;
|
||||
vec4 third;
|
||||
@@ -152,6 +153,30 @@ layout(set = 0, binding = 9) uniform sampler shadowSampler;
|
||||
layout(set = 0, binding = 20) uniform sampler2DArray queryTest;
|
||||
layout(set = 0, binding = 21) uniform sampler2DMSArray queryTestMS;
|
||||
|
||||
layout(set = 1, binding = 1) uniform sampler pointSamplers[14];
|
||||
layout(set = 1, binding = 2) uniform sampler linearSamplers[14];
|
||||
|
||||
layout(set = 1, binding = 3) uniform texture2D sampledImages[14];
|
||||
|
||||
layout(set = 1, binding = 4) uniform sampler2D linearSampledImages[14];
|
||||
|
||||
layout(set = 1, binding = 5, std430) buffer storebufstype
|
||||
{
|
||||
vec4 x;
|
||||
dummy y;
|
||||
vec4 arr[];
|
||||
} storebufs[14];
|
||||
|
||||
layout(set = 1, binding = 6, rgba32f) uniform coherent image2D storeImages[14];
|
||||
|
||||
layout(set = 1, binding = 7) uniform samplerBuffer texBuffers[14];
|
||||
layout(set = 1, binding = 8, rgba32f) uniform coherent imageBuffer storeTexBuffers[14];
|
||||
|
||||
layout(set = 1, binding = 9) uniform sampler shadowSamplers[14];
|
||||
|
||||
layout(set = 1, binding = 20) uniform sampler2DArray queryTests[14];
|
||||
layout(set = 1, binding = 21) uniform sampler2DMSArray queryTestsMS[14];
|
||||
|
||||
layout(push_constant) uniform PushData {
|
||||
layout(offset = 16) ivec4 data;
|
||||
} push;
|
||||
@@ -355,7 +380,7 @@ void main()
|
||||
case 30:
|
||||
{
|
||||
Color = cbuf.first + cbuf.second + cbuf.third + cbuf.fourth +
|
||||
cbuf.pad1 + cbuf.pad2 + cbuf.pad3;
|
||||
cbuf.pad2 + cbuf.pad3;
|
||||
break;
|
||||
}
|
||||
case 31:
|
||||
@@ -1097,6 +1122,130 @@ void main()
|
||||
Color = imageLoad(storeImage, ivec2(zeroi+1,zeroi+3));
|
||||
break;
|
||||
}
|
||||
case 134:
|
||||
{
|
||||
ivec2 coord = ivec2(zeroi + 20, zeroi + 20);
|
||||
|
||||
Color = texelFetch(sampledImages[1], coord, 0);
|
||||
break;
|
||||
}
|
||||
case 135:
|
||||
{
|
||||
vec2 coord = vec2(zerof + 0.5, zerof + 0.145);
|
||||
|
||||
Color = textureLod(sampler2D(sampledImages[2], pointSamplers[3]), coord, 0.0);
|
||||
break;
|
||||
}
|
||||
case 136:
|
||||
{
|
||||
vec2 coord = vec2(zerof + 0.5, zerof + 0.145);
|
||||
|
||||
Color = textureLod(sampler2D(sampledImages[2], linearSamplers[3]), coord, 0.0);
|
||||
break;
|
||||
}
|
||||
case 137:
|
||||
{
|
||||
Color = texture(linearSampledImages[4], inpos.xy);
|
||||
break;
|
||||
}
|
||||
case 138:
|
||||
{
|
||||
ivec2 coord = ivec2(zeroi + 20, zeroi + 20);
|
||||
|
||||
Color = texelFetch(sampledImages[cbuf.uniformIndex+1], coord, 0);
|
||||
break;
|
||||
}
|
||||
case 139:
|
||||
{
|
||||
vec2 coord = vec2(zerof + 0.5, zerof + 0.145);
|
||||
|
||||
Color = textureLod(sampler2D(sampledImages[cbuf.uniformIndex+2], pointSamplers[cbuf.uniformIndex+3]), coord, 0.0);
|
||||
break;
|
||||
}
|
||||
case 140:
|
||||
{
|
||||
vec2 coord = vec2(zerof + 0.5, zerof + 0.145);
|
||||
|
||||
Color = textureLod(sampler2D(sampledImages[cbuf.uniformIndex+2], linearSamplers[cbuf.uniformIndex+3]), coord, 0.0);
|
||||
break;
|
||||
}
|
||||
case 141:
|
||||
{
|
||||
Color = texture(linearSampledImages[cbuf.uniformIndex+4], inpos.xy);
|
||||
break;
|
||||
}
|
||||
case 142:
|
||||
{
|
||||
ivec2 coord = ivec2(zeroi + 20, zeroi + 20);
|
||||
|
||||
Color = texelFetch(sampledImages[nonuniformEXT(zeroi)+9], coord, 0);
|
||||
break;
|
||||
}
|
||||
case 143:
|
||||
{
|
||||
vec2 coord = vec2(zerof + 0.5, zerof + 0.145);
|
||||
|
||||
Color = textureLod(sampler2D(sampledImages[nonuniformEXT(zeroi)+10], pointSamplers[nonuniformEXT(zeroi)+11]), coord, 0.0);
|
||||
break;
|
||||
}
|
||||
case 144:
|
||||
{
|
||||
vec2 coord = vec2(zerof + 0.5, zerof + 0.145);
|
||||
|
||||
Color = textureLod(sampler2D(sampledImages[nonuniformEXT(zeroi)+10], linearSamplers[nonuniformEXT(zeroi)+11]), coord, 0.0);
|
||||
break;
|
||||
}
|
||||
case 145:
|
||||
{
|
||||
Color = texture(linearSampledImages[nonuniformEXT(zeroi)+12], inpos.xy);
|
||||
break;
|
||||
}
|
||||
case 146:
|
||||
{
|
||||
Color = vec4(float(textureQueryLevels(queryTests[0])), float(textureSamples(queryTestsMS[0])), 0.0f, 1.0f);
|
||||
break;
|
||||
}
|
||||
case 147:
|
||||
{
|
||||
Color = vec4(float(textureQueryLevels(queryTests[zeroi+3])), float(textureSamples(queryTestsMS[zeroi+3])), 0.0f, 1.0f);
|
||||
break;
|
||||
}
|
||||
case 148:
|
||||
{
|
||||
Color = vec4(float(textureQueryLevels(queryTests[nonuniformEXT(zeroi)+5])), float(textureSamples(queryTestsMS[nonuniformEXT(zeroi)+5])), 0.0f, 1.0f);
|
||||
break;
|
||||
}
|
||||
case 149:
|
||||
{
|
||||
uint len = storebufs[zeroi+7].arr.length();
|
||||
Color = vec4(float(len), float(len), float(len), float(len));
|
||||
break;
|
||||
}
|
||||
case 150:
|
||||
{
|
||||
// test storage buffer write here, we'll read from it in GLSL test 2
|
||||
storebufs[zeroi+7].x = vec4(3.1f, 4.1f, 5.9f, 2.6f);
|
||||
storebufs[zeroi+7].y.val = uvec4(31, 41, 59, 26);
|
||||
storebufs[zeroi+7].arr[flatData.intval - flatData.test] = vec4(inpos, inposIncreased);
|
||||
|
||||
Color = storebufs[zeroi+7].x;
|
||||
break;
|
||||
}
|
||||
case 151:
|
||||
{
|
||||
imageStore(storeImages[zeroi+7], ivec2(zeroi+1,zeroi+3), vec4(3.1f, 4.1f, 5.9f, 2.6f));
|
||||
Color = imageLoad(storeImages[zeroi+7], ivec2(zeroi+1,zeroi+3));
|
||||
break;
|
||||
}
|
||||
case 152:
|
||||
{
|
||||
float x = texture(sampler2DShadow(sampledImages[zeroi+5], shadowSamplers[zeroi+8]), vec3(inpos, 0.1f));
|
||||
float y = texture(sampler2DShadow(sampledImages[zeroi+5], shadowSamplers[zeroi+8]), vec3(inpos, 0.3f));
|
||||
float z = texture(sampler2DShadow(sampledImages[zeroi+5], shadowSamplers[zeroi+8]), vec3(inpos, 0.7f));
|
||||
float w = texture(sampler2DShadow(sampledImages[zeroi+5], shadowSamplers[zeroi+8]), vec3(inpos, 0.9f));
|
||||
Color = vec4(x, y, z, w);
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
@@ -1197,6 +1346,7 @@ layout(location = 0) out vec4 Color;
|
||||
|
||||
void main()
|
||||
{
|
||||
float zerof = float(zeroi);
|
||||
Color = vec4(0,0,0,0);
|
||||
switch(test)
|
||||
{
|
||||
@@ -1296,6 +1446,29 @@ void main()
|
||||
Color = dFdxFine(val).xyxy;
|
||||
break;
|
||||
}
|
||||
case 15:
|
||||
{
|
||||
// test loading from the storage buffer (after a nice big barrier)
|
||||
Color = storebufs[zeroi+7].x;
|
||||
break;
|
||||
}
|
||||
case 16:
|
||||
{
|
||||
// test loading from the storage buffer (after a nice big barrier)
|
||||
Color = vec4(storebufs[zeroi+7].y.val);
|
||||
break;
|
||||
}
|
||||
case 17:
|
||||
{
|
||||
// test loading from the storage buffer (after a nice big barrier)
|
||||
Color = storebufs[zeroi+7].arr[intval - test];
|
||||
break;
|
||||
}
|
||||
case 18:
|
||||
{
|
||||
Color = imageLoad(storeImages[zeroi+7], ivec2(zeroi+1,zeroi+3));
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
@@ -2548,7 +2721,11 @@ OpMemberDecorate %cbuffer_struct 17 Offset 216 ; double doublePackSource
|
||||
|
||||
void Prepare(int argc, char **argv)
|
||||
{
|
||||
optDevExts.push_back(VK_KHR_SPIRV_1_4_EXTENSION_NAME);
|
||||
// require descriptor indexing
|
||||
devExts.push_back(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME);
|
||||
|
||||
// dependencies of VK_EXT_descriptor_indexing
|
||||
devExts.push_back(VK_KHR_MAINTENANCE3_EXTENSION_NAME);
|
||||
|
||||
// we require this to pixel shader debug anyway, so we might as well require it for all tests.
|
||||
features.fragmentStoresAndAtomics = VK_TRUE;
|
||||
@@ -2570,6 +2747,47 @@ OpMemberDecorate %cbuffer_struct 17 Offset 216 ; double doublePackSource
|
||||
// Disabled until we support these in debugging
|
||||
// if(supported.shaderFloat64)
|
||||
// features.shaderFloat64 = VK_TRUE;
|
||||
|
||||
static VkPhysicalDeviceDescriptorIndexingFeaturesEXT descIndexing = {
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT,
|
||||
};
|
||||
|
||||
getPhysFeatures2(&descIndexing);
|
||||
|
||||
// enable descriptor indexing on arrays of all types
|
||||
|
||||
if(!descIndexing.runtimeDescriptorArray)
|
||||
Avail = "Descriptor indexing feature 'runtimeDescriptorArray' not available";
|
||||
else if(!descIndexing.shaderUniformTexelBufferArrayDynamicIndexing)
|
||||
Avail =
|
||||
"Descriptor indexing feature 'shaderUniformTexelBufferArrayDynamicIndexing' not "
|
||||
"available";
|
||||
else if(!descIndexing.shaderStorageTexelBufferArrayDynamicIndexing)
|
||||
Avail =
|
||||
"Descriptor indexing feature 'shaderStorageTexelBufferArrayDynamicIndexing' not "
|
||||
"available";
|
||||
else if(!descIndexing.shaderUniformBufferArrayNonUniformIndexing)
|
||||
Avail =
|
||||
"Descriptor indexing feature 'shaderUniformBufferArrayNonUniformIndexing' not available";
|
||||
else if(!descIndexing.shaderSampledImageArrayNonUniformIndexing)
|
||||
Avail =
|
||||
"Descriptor indexing feature 'shaderSampledImageArrayNonUniformIndexing' not available";
|
||||
else if(!descIndexing.shaderStorageBufferArrayNonUniformIndexing)
|
||||
Avail =
|
||||
"Descriptor indexing feature 'shaderStorageBufferArrayNonUniformIndexing' not available";
|
||||
else if(!descIndexing.shaderStorageImageArrayNonUniformIndexing)
|
||||
Avail =
|
||||
"Descriptor indexing feature 'shaderStorageImageArrayNonUniformIndexing' not available";
|
||||
else if(!descIndexing.shaderUniformTexelBufferArrayNonUniformIndexing)
|
||||
Avail =
|
||||
"Descriptor indexing feature 'shaderUniformTexelBufferArrayNonUniformIndexing' not "
|
||||
"available";
|
||||
else if(!descIndexing.shaderStorageTexelBufferArrayNonUniformIndexing)
|
||||
Avail =
|
||||
"Descriptor indexing feature 'shaderStorageTexelBufferArrayNonUniformIndexing' not "
|
||||
"available";
|
||||
|
||||
devInfoNext = &descIndexing;
|
||||
}
|
||||
|
||||
int main()
|
||||
@@ -2607,8 +2825,29 @@ OpMemberDecorate %cbuffer_struct 17 Offset 216 ; double doublePackSource
|
||||
{21, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT},
|
||||
}));
|
||||
|
||||
// this set layout has arrays of each type. We'll uniformly, dynamic-uniformly, and
|
||||
// non-uniformly access each of these
|
||||
VkDescriptorSetLayout setlayout2 = createDescriptorSetLayout(vkh::DescriptorSetLayoutCreateInfo({
|
||||
{1, VK_DESCRIPTOR_TYPE_SAMPLER, 14, VK_SHADER_STAGE_FRAGMENT_BIT},
|
||||
{2, VK_DESCRIPTOR_TYPE_SAMPLER, 14, VK_SHADER_STAGE_FRAGMENT_BIT},
|
||||
{3, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 14, VK_SHADER_STAGE_FRAGMENT_BIT},
|
||||
{4, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 14, VK_SHADER_STAGE_FRAGMENT_BIT},
|
||||
{5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 14, VK_SHADER_STAGE_FRAGMENT_BIT},
|
||||
{6, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 14, VK_SHADER_STAGE_FRAGMENT_BIT},
|
||||
{7, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 14, VK_SHADER_STAGE_FRAGMENT_BIT},
|
||||
{8, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 14, VK_SHADER_STAGE_FRAGMENT_BIT},
|
||||
{9, VK_DESCRIPTOR_TYPE_SAMPLER, 14, VK_SHADER_STAGE_FRAGMENT_BIT},
|
||||
{20, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 14, VK_SHADER_STAGE_FRAGMENT_BIT},
|
||||
{21, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 14, VK_SHADER_STAGE_FRAGMENT_BIT},
|
||||
}));
|
||||
|
||||
VkPipelineLayout layout = createPipelineLayout(vkh::PipelineLayoutCreateInfo(
|
||||
{setlayout}, {vkh::PushConstantRange(VK_SHADER_STAGE_FRAGMENT_BIT, 16, sizeof(Vec4i))}));
|
||||
{
|
||||
setlayout, setlayout2,
|
||||
},
|
||||
{
|
||||
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(std::max(numGLSL1Tests, numGLSL2Tests), numASMTests), 256U);
|
||||
@@ -2793,6 +3032,7 @@ OpMemberDecorate %cbuffer_struct 17 Offset 216 ; double doublePackSource
|
||||
vkCreateSampler(device, &sampInfo, NULL, &shadowsampler);
|
||||
|
||||
VkDescriptorSet descset = allocateDescriptorSet(setlayout);
|
||||
VkDescriptorSet descset2 = allocateDescriptorSet(setlayout2);
|
||||
|
||||
Vec4f cbufferdata[16] = {};
|
||||
|
||||
@@ -2817,6 +3057,9 @@ OpMemberDecorate %cbuffer_struct 17 Offset 216 ; double doublePackSource
|
||||
// halfPackSource - we pick exact half values to avoid rounding problems
|
||||
cbufferdata[11] = Vec4f(98.125f, 76.375f, 54.5625f, 32.78125f);
|
||||
|
||||
uint32_t index = 4;
|
||||
memcpy(&cbufferdata[1], &index, sizeof(index));
|
||||
|
||||
Vec4u unpack = {};
|
||||
|
||||
// unormUnpackSource
|
||||
@@ -2914,6 +3157,47 @@ OpMemberDecorate %cbuffer_struct 17 Offset 216 ; double doublePackSource
|
||||
{vkh::DescriptorImageInfo(queryTestMSView, VK_IMAGE_LAYOUT_GENERAL, mipsampler)}),
|
||||
});
|
||||
|
||||
for(uint32_t i = 0; i < 14; i++)
|
||||
{
|
||||
vkh::updateDescriptorSets(
|
||||
device,
|
||||
{
|
||||
vkh::WriteDescriptorSet(descset2, 1, i, VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||
{vkh::DescriptorImageInfo(
|
||||
VK_NULL_HANDLE, VK_IMAGE_LAYOUT_UNDEFINED, pointsampler)}),
|
||||
vkh::WriteDescriptorSet(descset2, 2, i, VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||
{vkh::DescriptorImageInfo(
|
||||
VK_NULL_HANDLE, VK_IMAGE_LAYOUT_UNDEFINED, linearsampler)}),
|
||||
vkh::WriteDescriptorSet(
|
||||
descset2, 3, i, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
{vkh::DescriptorImageInfo(smileyview, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_NULL_HANDLE)}),
|
||||
vkh::WriteDescriptorSet(
|
||||
descset2, 4, i, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
{vkh::DescriptorImageInfo(smileyview, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
linearsampler)}),
|
||||
vkh::WriteDescriptorSet(descset2, 5, i, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
{vkh::DescriptorBufferInfo(store_buffer.buffer)}),
|
||||
vkh::WriteDescriptorSet(
|
||||
descset2, 6, i, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||
{vkh::DescriptorImageInfo(store_view, VK_IMAGE_LAYOUT_GENERAL, VK_NULL_HANDLE)}),
|
||||
vkh::WriteDescriptorSet(descset2, 7, i, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
|
||||
{bufview}),
|
||||
vkh::WriteDescriptorSet(descset2, 8, i, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
|
||||
{store_bufview}),
|
||||
vkh::WriteDescriptorSet(descset2, 9, i, VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||
{vkh::DescriptorImageInfo(
|
||||
VK_NULL_HANDLE, VK_IMAGE_LAYOUT_UNDEFINED, shadowsampler)}),
|
||||
|
||||
vkh::WriteDescriptorSet(
|
||||
descset2, 20, i, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
{vkh::DescriptorImageInfo(queryTestView, VK_IMAGE_LAYOUT_GENERAL, mipsampler)}),
|
||||
vkh::WriteDescriptorSet(
|
||||
descset2, 21, i, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
{vkh::DescriptorImageInfo(queryTestMSView, VK_IMAGE_LAYOUT_GENERAL, mipsampler)}),
|
||||
});
|
||||
}
|
||||
|
||||
while(Running())
|
||||
{
|
||||
VkCommandBuffer cmd = GetCommandBuffer();
|
||||
@@ -2978,7 +3262,8 @@ OpMemberDecorate %cbuffer_struct 17 Offset 216 ; double doublePackSource
|
||||
|
||||
Vec4i push = Vec4i(101, 103, 107, 109);
|
||||
|
||||
vkh::cmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, {descset}, {});
|
||||
vkh::cmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0,
|
||||
{descset, descset2}, {});
|
||||
vkCmdPushConstants(cmd, layout, VK_SHADER_STAGE_FRAGMENT_BIT, 16, sizeof(Vec4i), &push);
|
||||
|
||||
vkCmdBeginRenderPass(cmd, vkh::RenderPassBeginInfo(renderPass, framebuffer, s,
|
||||
|
||||
Reference in New Issue
Block a user