mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-05 09:30:44 +00:00
Use StorageBuffer storage class when editing 1.3+ SPIR-V modules
This commit is contained in:
@@ -65,6 +65,11 @@ void Editor::Prepare()
|
||||
if(m_SPIRV.empty())
|
||||
return;
|
||||
|
||||
// In 1.3 and after we can (and should - it's gone in 1.4+) use the real SSBO storage class
|
||||
// instead of Uniform + BufferBlock
|
||||
if(m_MajorVersion > 1 || m_MinorVersion >= 3)
|
||||
m_StorageBufferClass = rdcspv::StorageClass::StorageBuffer;
|
||||
|
||||
// find any empty sections and insert a nop into the stream there. We need to fixup later section
|
||||
// offsets by hand as addWords doesn't handle empty sections properly (it thinks we're inserting
|
||||
// into the later section by offset since the offsets overlap). That's why we're adding these
|
||||
@@ -138,19 +143,38 @@ Id Editor::MakeId()
|
||||
return Id::fromWord(ret);
|
||||
}
|
||||
|
||||
void Editor::SetName(Id id, const char *name)
|
||||
void Editor::DecorateStorageBufferStruct(Id id)
|
||||
{
|
||||
size_t sz = strlen(name);
|
||||
rdcarray<uint32_t> uintName((sz / 4) + 1);
|
||||
memcpy(&uintName[0], name, sz);
|
||||
// set bufferblock if needed
|
||||
if(m_StorageBufferClass == rdcspv::StorageClass::Uniform)
|
||||
AddDecoration(rdcspv::OpDecorate(id, rdcspv::Decoration::BufferBlock));
|
||||
}
|
||||
|
||||
uintName.insert(0, id.value());
|
||||
|
||||
Operation op(Op::Name, uintName);
|
||||
void Editor::SetName(Id id, const rdcstr &name)
|
||||
{
|
||||
Operation op = OpName(id, name);
|
||||
|
||||
Iter it;
|
||||
|
||||
// OpName must be before OpModuleProcessed.
|
||||
// OpName/OpMemberName must be before OpModuleProcessed.
|
||||
for(it = Begin(Section::Debug); it < End(Section::Debug); ++it)
|
||||
{
|
||||
if(it.opcode() == Op::ModuleProcessed)
|
||||
break;
|
||||
}
|
||||
|
||||
op.insertInto(m_SPIRV, it.offs());
|
||||
RegisterOp(Iter(m_SPIRV, it.offs()));
|
||||
addWords(it.offs(), op.size());
|
||||
}
|
||||
|
||||
void Editor::SetMemberName(Id id, uint32_t member, const rdcstr &name)
|
||||
{
|
||||
Operation op = OpMemberName(id, member, name);
|
||||
|
||||
Iter it;
|
||||
|
||||
// OpName/OpMemberName must be before OpModuleProcessed.
|
||||
for(it = Begin(Section::Debug); it < End(Section::Debug); ++it)
|
||||
{
|
||||
if(it.opcode() == Op::ModuleProcessed)
|
||||
|
||||
@@ -84,7 +84,10 @@ public:
|
||||
iter.nopRemove();
|
||||
}
|
||||
|
||||
void SetName(Id id, const char *name);
|
||||
StorageClass StorageBufferClass() { return m_StorageBufferClass; }
|
||||
void DecorateStorageBufferStruct(Id id);
|
||||
void SetName(Id id, const rdcstr &name);
|
||||
void SetMemberName(Id id, uint32_t member, const rdcstr &name);
|
||||
void AddDecoration(const Operation &op);
|
||||
void AddCapability(Capability cap);
|
||||
void AddExtension(const rdcstr &extension);
|
||||
@@ -205,6 +208,8 @@ private:
|
||||
std::map<SampledImage, Id> sampledImageTypeToId;
|
||||
std::map<FunctionType, Id> functionTypeToId;
|
||||
|
||||
StorageClass m_StorageBufferClass = rdcspv::StorageClass::Uniform;
|
||||
|
||||
template <typename SPIRVType>
|
||||
std::map<SPIRVType, Id> &GetTable();
|
||||
|
||||
|
||||
@@ -118,9 +118,8 @@ void AnnotateShader(const SPIRVPatchData &patchData, const char *entryName,
|
||||
{
|
||||
rdcspv::Id id = varLookup[var.id] = editor.AddConstantImmediate<uint64_t>(it->second.offset);
|
||||
|
||||
editor.SetName(
|
||||
id, StringFormat::Fmt("__feedbackOffset_set%u_bind%u", it->first.set, it->first.binding)
|
||||
.c_str());
|
||||
editor.SetName(id, StringFormat::Fmt("__feedbackOffset_set%u_bind%u", it->first.set,
|
||||
it->first.binding));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -130,8 +129,7 @@ void AnnotateShader(const SPIRVPatchData &patchData, const char *entryName,
|
||||
rdcspv::Id id = varLookup[var.id] = editor.AddConstantImmediate<uint32_t>(uint32_t(index));
|
||||
|
||||
editor.SetName(
|
||||
id, StringFormat::Fmt("__feedbackIndex_set%u_bind%u", it->first.set, it->first.binding)
|
||||
.c_str());
|
||||
id, StringFormat::Fmt("__feedbackIndex_set%u_bind%u", it->first.set, it->first.binding));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -166,10 +164,11 @@ void AnnotateShader(const SPIRVPatchData &patchData, const char *entryName,
|
||||
}
|
||||
else
|
||||
{
|
||||
// the pointers are uniform pointers
|
||||
rdcspv::Id bufptrtype =
|
||||
editor.DeclareType(rdcspv::Pointer(uint32StructID, rdcspv::StorageClass::Uniform));
|
||||
uint32ptrtype = editor.DeclareType(rdcspv::Pointer(uint32ID, rdcspv::StorageClass::Uniform));
|
||||
rdcspv::StorageClass ssboClass = editor.StorageBufferClass();
|
||||
|
||||
// the pointers are SSBO pointers
|
||||
rdcspv::Id bufptrtype = editor.DeclareType(rdcspv::Pointer(uint32StructID, ssboClass));
|
||||
uint32ptrtype = editor.DeclareType(rdcspv::Pointer(uint32ID, ssboClass));
|
||||
|
||||
// patch all bindings up by 1
|
||||
for(rdcspv::Iter it = editor.Begin(rdcspv::Section::Annotations),
|
||||
@@ -197,7 +196,7 @@ void AnnotateShader(const SPIRVPatchData &patchData, const char *entryName,
|
||||
|
||||
// add our SSBO variable, at set 0 binding 0
|
||||
ssboVar = editor.MakeId();
|
||||
editor.AddVariable(rdcspv::OpVariable(bufptrtype, ssboVar, rdcspv::StorageClass::Uniform));
|
||||
editor.AddVariable(rdcspv::OpVariable(bufptrtype, ssboVar, ssboClass));
|
||||
editor.AddDecoration(
|
||||
rdcspv::OpDecorate(ssboVar, rdcspv::DecorationParam<rdcspv::Decoration::DescriptorSet>(0)));
|
||||
editor.AddDecoration(
|
||||
@@ -205,8 +204,7 @@ void AnnotateShader(const SPIRVPatchData &patchData, const char *entryName,
|
||||
|
||||
editor.SetName(ssboVar, "__rd_feedbackBuffer");
|
||||
|
||||
// struct is bufferblock decorated
|
||||
editor.AddDecoration(rdcspv::OpDecorate(uint32StructID, rdcspv::Decoration::BufferBlock));
|
||||
editor.DecorateStorageBufferStruct(uint32StructID);
|
||||
}
|
||||
|
||||
rdcspv::Id rtarrayOffset = editor.AddConstantImmediate<uint32_t>(0U);
|
||||
|
||||
@@ -113,7 +113,7 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
|
||||
// gvec4 type for this input, used as result type when fetching from tbuffer
|
||||
rdcspv::Id vec4ID;
|
||||
// Uniform Pointer ID for this output. Used only for output data, to write to output SSBO
|
||||
rdcspv::Id uniformPtrID;
|
||||
rdcspv::Id ssboPtrID;
|
||||
// Output Pointer ID for this attribute.
|
||||
// For inputs, used to 'write' to the global at the start.
|
||||
// For outputs, used to 'read' from the global at the end.
|
||||
@@ -421,7 +421,7 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
|
||||
{
|
||||
editor.Remove(it);
|
||||
if(typeReplacements.find(name.target) == typeReplacements.end())
|
||||
editor.SetName(name.target, ("emulated_" + name.name).c_str());
|
||||
editor.SetName(name.target, "emulated_" + name.name);
|
||||
}
|
||||
|
||||
// remove any OpName for the old entry points
|
||||
@@ -434,6 +434,8 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
|
||||
}
|
||||
}
|
||||
|
||||
rdcspv::StorageClass ssboStorageClass = editor.StorageBufferClass();
|
||||
|
||||
// declare necessary variables per-output, types and constants. We do this last so that we don't
|
||||
// add a private pointer that we later try and deduplicate when collapsing output/input pointers
|
||||
// to private
|
||||
@@ -470,13 +472,12 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
|
||||
io.basetypeID = editor.DeclareType(scalarType);
|
||||
}
|
||||
|
||||
io.uniformPtrID =
|
||||
editor.DeclareType(rdcspv::Pointer(io.basetypeID, rdcspv::StorageClass::Uniform));
|
||||
io.ssboPtrID = editor.DeclareType(rdcspv::Pointer(io.basetypeID, ssboStorageClass));
|
||||
io.privatePtrID =
|
||||
editor.DeclareType(rdcspv::Pointer(io.basetypeID, rdcspv::StorageClass::Private));
|
||||
|
||||
RDCASSERT(io.basetypeID && io.vec4ID && io.constID && io.privatePtrID && io.uniformPtrID,
|
||||
io.basetypeID, io.vec4ID, io.constID, io.privatePtrID, io.uniformPtrID);
|
||||
RDCASSERT(io.basetypeID && io.vec4ID && io.constID && io.privatePtrID && io.ssboPtrID,
|
||||
io.basetypeID, io.vec4ID, io.constID, io.privatePtrID, io.ssboPtrID);
|
||||
}
|
||||
|
||||
// repeat for inputs
|
||||
@@ -548,7 +549,7 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
|
||||
for(tbufferType tb : {tbuffer_float, tbuffer_sint, tbuffer_uint})
|
||||
{
|
||||
rdcspv::Scalar scalarType = rdcspv::scalar<float>();
|
||||
const char *name = "float_vbuffers";
|
||||
rdcstr name = "float_vbuffers";
|
||||
|
||||
if(tb == tbuffer_sint)
|
||||
{
|
||||
@@ -650,12 +651,12 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
|
||||
|
||||
// meshOutput *
|
||||
rdcspv::Id outputStructPtrID =
|
||||
editor.DeclareType(rdcspv::Pointer(outputStructID, rdcspv::StorageClass::Uniform));
|
||||
editor.DeclareType(rdcspv::Pointer(outputStructID, ssboStorageClass));
|
||||
editor.SetName(outputStructPtrID, "meshOutput_ptr");
|
||||
|
||||
// meshOutput *outputData;
|
||||
outBufferVarID = editor.AddVariable(
|
||||
rdcspv::OpVariable(outputStructPtrID, editor.MakeId(), rdcspv::StorageClass::Uniform));
|
||||
outBufferVarID =
|
||||
editor.AddVariable(rdcspv::OpVariable(outputStructPtrID, editor.MakeId(), ssboStorageClass));
|
||||
editor.SetName(outBufferVarID, "outputData");
|
||||
|
||||
uint32_t memberOffset = 0;
|
||||
@@ -701,8 +702,7 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
|
||||
editor.AddDecoration(rdcspv::OpDecorate(
|
||||
runtimeArrayID, rdcspv::DecorationParam<rdcspv::Decoration::ArrayStride>(bufStride)));
|
||||
|
||||
// set object type
|
||||
editor.AddDecoration(rdcspv::OpDecorate(outputStructID, rdcspv::Decoration::BufferBlock));
|
||||
editor.DecorateStorageBufferStruct(outputStructID);
|
||||
|
||||
// set binding
|
||||
editor.AddDecoration(rdcspv::OpDecorate(
|
||||
@@ -1066,7 +1066,7 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
|
||||
|
||||
char swizzle[] = "xyzw";
|
||||
|
||||
editor.SetName(packed, StringFormat::Fmt("packed_%c", swizzle[c]).c_str());
|
||||
editor.SetName(packed, StringFormat::Fmt("packed_%c", swizzle[c]));
|
||||
|
||||
// double comp = PackDouble2x32(packed);
|
||||
comps[c] = editor.MakeId();
|
||||
@@ -1194,7 +1194,7 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV
|
||||
// access chain the destination
|
||||
// type *writePtr = outBuffer.verts[arraySlot].outputN
|
||||
rdcspv::Id writePtr = editor.MakeId();
|
||||
ops.push_back(rdcspv::OpAccessChain(outs[o].uniformPtrID, writePtr, outBufferVarID,
|
||||
ops.push_back(rdcspv::OpAccessChain(outs[o].ssboPtrID, writePtr, outBufferVarID,
|
||||
{zero, arraySlotID, outs[o].constID}));
|
||||
|
||||
// *writePtr = loaded;
|
||||
|
||||
Reference in New Issue
Block a user