Added ShaderDirectAccess helper struct and ShaderVariable set/get

ShaderDirectAccess is used to reference resources which are accessed directly from the Shader (not via a direct binding). Shader resource references using direct binding are stored in ShaderBindIndex.
This commit is contained in:
Jake Turner
2024-12-03 13:08:50 +00:00
parent 61a559a944
commit dbe18fc7fe
3 changed files with 125 additions and 0 deletions
+3
View File
@@ -166,3 +166,6 @@ Shader Variables
.. autoclass:: renderdoc.ShaderBindIndex
:members:
.. autoclass:: renderdoc.ShaderDirectAccess
:members:
+12
View File
@@ -651,6 +651,11 @@ struct DescriptorAccess
return CategoryForDescriptorType(type) == o.category && index == o.index &&
arrayElement == o.arrayElement;
}
bool operator==(const ShaderDirectAccess &o) const
{
return CategoryForDescriptorType(type) == o.category && descriptorStore == o.descriptorStore &&
byteOffset == o.byteOffset && byteSize == o.byteSize;
}
bool operator==(const DescriptorAccess &o) const
{
return stage == o.stage && type == o.type && index == o.index &&
@@ -740,6 +745,12 @@ inline ShaderBindIndex::ShaderBindIndex(const DescriptorAccess &access)
{
}
inline ShaderDirectAccess::ShaderDirectAccess(const DescriptorAccess &access)
: ShaderDirectAccess(CategoryForDescriptorType(access.type), access.descriptorStore,
access.byteOffset, access.byteSize)
{
}
DOCUMENT(R"(In many cases there may be a logical location or fixed binding point for a particular
descriptor which is not conveyed with a simple byte offset into a descriptor store.
This is particularly true for any descriptor stores that are not equivalent to a buffer of bytes
@@ -860,6 +871,7 @@ struct UsedDescriptor
bool operator==(const DescriptorAccess &o) const { return access == o; }
bool operator==(const ShaderBindIndex &o) const { return access == o; }
bool operator==(const ShaderDirectAccess &o) const { return access == o; }
bool operator==(const UsedDescriptor &o) const
{
return access == o.access && descriptor == o.descriptor && sampler == o.sampler;
+110
View File
@@ -128,6 +128,73 @@ identifies the particular array index being referred to.
DECLARE_REFLECTION_STRUCT(ShaderBindIndex);
DOCUMENT(R"(References a particular resource accessed via the shader using direct heap access (as opposed to a direct binding).
)");
struct ShaderDirectAccess
{
DOCUMENT("");
ShaderDirectAccess()
{
category = DescriptorCategory::Unknown;
descriptorStore = ResourceId();
byteOffset = 0;
byteSize = 0;
}
ShaderDirectAccess(const ShaderDirectAccess &) = default;
ShaderDirectAccess &operator=(const ShaderDirectAccess &) = default;
ShaderDirectAccess(DescriptorCategory category, ResourceId descriptorStore, uint32_t byteOffset,
uint32_t byteSize)
: category(category),
descriptorStore(descriptorStore),
byteOffset(byteOffset),
byteSize(byteSize)
{
}
ShaderDirectAccess(const DescriptorAccess &access);
bool operator<(const ShaderDirectAccess &o) const
{
if(category != o.category)
return category < o.category;
if(descriptorStore != o.descriptorStore)
return descriptorStore < o.descriptorStore;
if(byteOffset != o.byteOffset)
return byteOffset < o.byteOffset;
return byteSize < o.byteSize;
}
bool operator==(const ShaderDirectAccess &o) const
{
return category == o.category && descriptorStore == o.descriptorStore &&
byteOffset == o.byteOffset && byteSize == o.byteSize;
}
DOCUMENT(R"(The category of the resource being accessed.
:type: DescriptorCategory
)");
DescriptorCategory category;
DOCUMENT(R"(The backing storage of the descriptor.
:type: ResourceId
)");
ResourceId descriptorStore;
DOCUMENT(R"(The offset in bytes to the descriptor in the descriptor store.
:type: int
)");
uint32_t byteOffset = 0;
DOCUMENT(R"(The size in bytes of the descriptor.
:type: int
)");
uint32_t byteSize = 0;
};
DECLARE_REFLECTION_STRUCT(ShaderDirectAccess);
#if !defined(SWIG)
// similarly these need to be pre-declared for use in rdhalf
extern "C" RENDERDOC_API float RENDERDOC_CC RENDERDOC_HalfToFloat(uint16_t half);
@@ -417,6 +484,8 @@ an arrayed binding.
value.u32v[0] = (uint32_t)idx.category;
value.u32v[1] = idx.index;
value.u32v[2] = idx.arrayElement;
// This marks the variable as ShaderBindIndex and not ShaderDirectAccess
value.u32v[3] = 0;
}
DOCUMENT(R"(Utility function for getting a shader binding referenced by this variable.
@@ -432,6 +501,47 @@ an arrayed binding.
{
return ShaderBindIndex((DescriptorCategory)value.u32v[0], value.u32v[1], value.u32v[2]);
}
DOCUMENT(R"(Utility function for setting a resource which is accessed directly from a shader without using bindings.
The :class:`ShaderDirectAccess` uniquely refers to a resource descriptor.
:param ShaderDirectAccess access: The resource descriptor being referenced.
)");
inline void SetDirectAccess(const ShaderDirectAccess &access)
{
value.u32v[0] = (uint32_t)access.category;
value.u32v[1] = access.byteOffset;
value.u32v[2] = access.byteSize;
// This marks the variable as ShaderDirectAccess and not ShaderBindIndex
value.u32v[3] = 1;
static_assert(sizeof(access.descriptorStore) == sizeof(value.u64v[2]),
"ResourceId can't be packed");
memcpy(&value.u64v[2], &access.descriptorStore, sizeof(access.descriptorStore));
}
DOCUMENT(R"(Utility function for getting the resource which is accessed directly from a shader without using bindings.
.. note::
The return value is undefined if this variable is not a resource referenced directly by a shader.
:return: A :class:`ShaderDirectAccess` containing the resource reference.
:rtype: ShaderDirectAccess
)");
inline ShaderDirectAccess GetDirectAccess() const
{
ResourceId descriptorStore;
memcpy(&descriptorStore, &value.u64v[2], sizeof(descriptorStore));
return ShaderDirectAccess((DescriptorCategory)value.u64v[0], descriptorStore, value.u32v[1],
value.u32v[2]);
}
DOCUMENT(R"(Utility function to check if this variable stores a resource reference directly accessed by a shader.
:return: If the variable represents a :class:`ShaderDirectAccess`.
:rtype: bool
)");
inline bool IsDirectAccess() const { return (value.u32v[3] == 1); }
};
DECLARE_REFLECTION_STRUCT(ShaderVariable);