mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-04 09:00:44 +00:00
Flatten user spec constants when debugging shaders. Closes #3803
This commit is contained in:
@@ -1094,6 +1094,63 @@ rdcpair<Id, Id> Editor::AddBufferVariable(rdcarray<Id> &addedGlobals, Id varType
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Editor::FlattenSpecConstants(const rdcarray<SpecConstant> &userSpec)
|
||||
{
|
||||
// patch all bindings up trivially to account for the extra reservation
|
||||
for(Iter it = Begin(Section::Annotations), end = End(Section::Annotations); it < end; ++it)
|
||||
{
|
||||
if(it.opcode() == Op::Decorate)
|
||||
{
|
||||
OpDecorate dec(it);
|
||||
if(dec.decoration == Decoration::SpecId)
|
||||
{
|
||||
for(const SpecConstant &s : userSpec)
|
||||
{
|
||||
if(s.specID == dec.decoration.specId)
|
||||
{
|
||||
Iter target = GetID(dec.target);
|
||||
|
||||
if(target.opcode() == Op::SpecConstantTrue || target.opcode() == Op::SpecConstantFalse)
|
||||
{
|
||||
RDCCOMPILE_ASSERT(
|
||||
OpConstantTrue::FixedWordSize == OpSpecConstantTrue::FixedWordSize &&
|
||||
OpConstantTrue::FixedWordSize == OpSpecConstantFalse::FixedWordSize &&
|
||||
OpConstantTrue::FixedWordSize == OpConstantFalse::FixedWordSize,
|
||||
"OpConstantTrue and False should be interchangeable and equal to Spec versions");
|
||||
|
||||
OpSpecConstantTrue orig(target);
|
||||
|
||||
if(s.value != 0)
|
||||
target = OpConstantTrue(orig.resultType, orig.result);
|
||||
else
|
||||
target = OpConstantFalse(orig.resultType, orig.result);
|
||||
}
|
||||
else if(target.opcode() == Op::SpecConstant)
|
||||
{
|
||||
rdcarray<uint32_t> data;
|
||||
data.assign(target.words() + 1, target.size() - 1);
|
||||
|
||||
// first two IDs are type and result
|
||||
size_t constSize = data.byteSize() - 2 * sizeof(Id);
|
||||
|
||||
RDCASSERTEQUAL(s.dataSize, constSize);
|
||||
|
||||
memcpy(&data[2], &s.value, RDCMIN(s.dataSize, constSize));
|
||||
|
||||
target = Operation(Op::Constant, data);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// remove the spec id whether we found one or not. If we didn't find one, the default should be used
|
||||
it.nopRemove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define TYPETABLE(StructType, variable) \
|
||||
template <> \
|
||||
std::map<StructType, Id> &Editor::GetTable<StructType>() \
|
||||
|
||||
@@ -140,6 +140,8 @@ public:
|
||||
Id AddConstant(const Operation &op);
|
||||
void AddFunction(const OperationList &ops);
|
||||
|
||||
void FlattenSpecConstants(const rdcarray<SpecConstant> &userSpec);
|
||||
|
||||
Iter GetID(Id id);
|
||||
// the entry point has 'two' opcodes, the entrypoint declaration and the function.
|
||||
// This returns the first, GetID returns the second.
|
||||
|
||||
@@ -3767,7 +3767,7 @@ static rdcspv::Id AddQuadSwizzleHelper(rdcspv::Editor &editor, uint32_t count)
|
||||
return func;
|
||||
}
|
||||
|
||||
static void CreateInputFetcher(rdcarray<uint32_t> &spv,
|
||||
static void CreateInputFetcher(rdcarray<uint32_t> &spv, const rdcarray<SpecConstant> &userSpec,
|
||||
VulkanCreationInfo::ShaderModuleReflection &shadRefl,
|
||||
BufferStorageMode storageMode, bool usePrimitiveID, bool useSampleID,
|
||||
bool useViewIndex, SubgroupCapability subgroupCapability,
|
||||
@@ -3815,6 +3815,8 @@ static void CreateInputFetcher(rdcarray<uint32_t> &spv,
|
||||
editor.Prepare();
|
||||
editor.SetBufferStorageMode(storageMode);
|
||||
|
||||
editor.FlattenSpecConstants(userSpec);
|
||||
|
||||
// remove any OpSource
|
||||
{
|
||||
// remove any OpName that refers to deleted IDs - functions or results
|
||||
@@ -5471,7 +5473,7 @@ ShaderDebugTrace *VulkanReplay::DebugVertex(uint32_t eventId, uint32_t vertid, u
|
||||
|
||||
VkSpecializationInfo patchedSpecInfo = MakeSpecInfo(specData, specMaps);
|
||||
|
||||
auto patchCallback = [this, &shadRefl, &patchedSpecInfo, useViewIndex, subgroupCapability,
|
||||
auto patchCallback = [this, &spec, &shadRefl, &patchedSpecInfo, useViewIndex, subgroupCapability,
|
||||
maxSubgroupSize](const AddedDescriptorData &patchedBufferdata,
|
||||
VkShaderStageFlagBits stage, const char *entryName,
|
||||
const rdcarray<uint32_t> &origSpirv,
|
||||
@@ -5485,14 +5487,13 @@ ShaderDebugTrace *VulkanReplay::DebugVertex(uint32_t eventId, uint32_t vertid, u
|
||||
if(!Vulkan_Debug_PSDebugDumpDirPath().empty())
|
||||
FileIO::WriteAll(Vulkan_Debug_PSDebugDumpDirPath() + "/debug_vsinput_before.spv", modSpirv);
|
||||
|
||||
CreateInputFetcher(modSpirv, shadRefl, m_StorageMode, false, false, useViewIndex,
|
||||
CreateInputFetcher(modSpirv, spec, shadRefl, m_StorageMode, false, false, useViewIndex,
|
||||
subgroupCapability, maxSubgroupSize);
|
||||
|
||||
if(!Vulkan_Debug_PSDebugDumpDirPath().empty())
|
||||
FileIO::WriteAll(Vulkan_Debug_PSDebugDumpDirPath() + "/debug_vsinput_after.spv", modSpirv);
|
||||
|
||||
// overwrite user's specialisation info, assuming that the old specialisation info is not
|
||||
// relevant for codegen (the only thing it would be used for)
|
||||
// overwrite user's specialisation info. We flattened the user's spec constants when patching the SPIR-V above.
|
||||
specInfo = &patchedSpecInfo;
|
||||
|
||||
return true;
|
||||
@@ -6039,7 +6040,7 @@ ShaderDebugTrace *VulkanReplay::DebugPixel(uint32_t eventId, uint32_t x, uint32_
|
||||
|
||||
VkSpecializationInfo patchedSpecInfo = MakeSpecInfo(specData, specMaps);
|
||||
|
||||
auto patchCallback = [this, &shadRefl, &patchedSpecInfo, usePrimitiveID, useSampleID,
|
||||
auto patchCallback = [this, &spec, &shadRefl, &patchedSpecInfo, usePrimitiveID, useSampleID,
|
||||
useViewIndex, subgroupCapability, maxSubgroupSize](
|
||||
const AddedDescriptorData &patchedBufferdata, VkShaderStageFlagBits stage,
|
||||
const char *entryName, const rdcarray<uint32_t> &origSpirv,
|
||||
@@ -6052,14 +6053,13 @@ ShaderDebugTrace *VulkanReplay::DebugPixel(uint32_t eventId, uint32_t x, uint32_
|
||||
if(!Vulkan_Debug_PSDebugDumpDirPath().empty())
|
||||
FileIO::WriteAll(Vulkan_Debug_PSDebugDumpDirPath() + "/debug_psinput_before.spv", modSpirv);
|
||||
|
||||
CreateInputFetcher(modSpirv, shadRefl, m_StorageMode, usePrimitiveID, useSampleID, useViewIndex,
|
||||
subgroupCapability, maxSubgroupSize);
|
||||
CreateInputFetcher(modSpirv, spec, shadRefl, m_StorageMode, usePrimitiveID, useSampleID,
|
||||
useViewIndex, subgroupCapability, maxSubgroupSize);
|
||||
|
||||
if(!Vulkan_Debug_PSDebugDumpDirPath().empty())
|
||||
FileIO::WriteAll(Vulkan_Debug_PSDebugDumpDirPath() + "/debug_psinput_after.spv", modSpirv);
|
||||
|
||||
// overwrite user's specialisation info, assuming that the old specialisation info is not
|
||||
// relevant for codegen (the only thing it would be used for)
|
||||
// overwrite user's specialisation info. We flattened the user's spec constants when patching the SPIR-V above.
|
||||
specInfo = &patchedSpecInfo;
|
||||
|
||||
return true;
|
||||
@@ -6575,7 +6575,7 @@ ShaderDebugTrace *VulkanReplay::DebugComputeCommon(ShaderStage stage, uint32_t e
|
||||
|
||||
VkSpecializationInfo patchedSpecInfo = MakeSpecInfo(specData, specMaps);
|
||||
|
||||
auto patchCallback = [this, stageBit, &shadRefl, &patchedSpecInfo, subgroupCapability,
|
||||
auto patchCallback = [this, stageBit, &spec, &shadRefl, &patchedSpecInfo, subgroupCapability,
|
||||
maxSubgroupSize](const AddedDescriptorData &patchedBufferdata,
|
||||
VkShaderStageFlagBits stage, const char *entryName,
|
||||
const rdcarray<uint32_t> &origSpirv,
|
||||
@@ -6597,14 +6597,13 @@ ShaderDebugTrace *VulkanReplay::DebugComputeCommon(ShaderStage stage, uint32_t e
|
||||
if(!Vulkan_Debug_PSDebugDumpDirPath().empty())
|
||||
FileIO::WriteAll(Vulkan_Debug_PSDebugDumpDirPath() + "/before_" + filename[idx], modSpirv);
|
||||
|
||||
CreateInputFetcher(modSpirv, shadRefl, m_StorageMode, false, false, false, subgroupCapability,
|
||||
maxSubgroupSize);
|
||||
CreateInputFetcher(modSpirv, spec, shadRefl, m_StorageMode, false, false, false,
|
||||
subgroupCapability, maxSubgroupSize);
|
||||
|
||||
if(!Vulkan_Debug_PSDebugDumpDirPath().empty())
|
||||
FileIO::WriteAll(Vulkan_Debug_PSDebugDumpDirPath() + "/after_" + filename[idx], modSpirv);
|
||||
|
||||
// overwrite user's specialisation info, assuming that the old specialisation info is not
|
||||
// relevant for codegen (the only thing it would be used for)
|
||||
// overwrite user's specialisation info. We flattened the user's spec constants when patching the SPIR-V above.
|
||||
specInfo = &patchedSpecInfo;
|
||||
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user