Add a structure and query for reporting descriptor accesses

This commit is contained in:
baldurk
2024-04-10 15:33:36 +01:00
parent c1d07f6bc3
commit 227842a295
25 changed files with 244 additions and 5 deletions
+103
View File
@@ -25,6 +25,7 @@
#pragma once
#include "apidefs.h"
#include "data_types.h"
#include "rdcarray.h"
#include "shader_types.h"
#include "stringise.h"
@@ -746,6 +747,108 @@ this sampler.
DECLARE_REFLECTION_STRUCT(SamplerDescriptor);
DOCUMENT(R"(The details of a single accessed descriptor as fetched by a shader and which descriptor
in the descriptor store was fetched.
This may be a somewhat conservative access, reported as possible but not actually executed on the
GPU itself.
.. data:: NoShaderBinding
No shader binding corresponds to this descriptor access, it happened directly without going
through any kind of binding.
)");
struct DescriptorAccess
{
DOCUMENT("");
DescriptorAccess() = default;
DescriptorAccess(const DescriptorAccess &) = default;
DescriptorAccess &operator=(const DescriptorAccess &) = default;
bool operator==(const DescriptorAccess &o) const
{
return stage == o.stage && type == o.type && index == o.index &&
arrayElement == o.arrayElement && descriptorStore == o.descriptorStore &&
byteOffset == o.byteOffset && byteSize == o.byteSize;
}
bool operator<(const DescriptorAccess &o) const
{
if(stage != o.stage)
return stage < o.stage;
if(type != o.type)
return type < o.type;
if(index != o.index)
return index < o.index;
if(arrayElement != o.arrayElement)
return arrayElement < o.arrayElement;
if(descriptorStore != o.descriptorStore)
return descriptorStore < o.descriptorStore;
if(byteOffset != o.byteOffset)
return byteOffset < o.byteOffset;
if(byteSize != o.byteSize)
return byteSize < o.byteSize;
return false;
}
DOCUMENT(R"(The shader stage that this descriptor access came from.
:type: ShaderStage
)");
ShaderStage stage = ShaderStage::Count;
DOCUMENT(R"(The type of the descriptor being accessed.
:type: DescriptorType
)");
DescriptorType type = DescriptorType::Unknown;
DOCUMENT(R"(The index within the shader's reflection list corresponding to :data:`type` of the
accessing resource.
If this value is set to :data:`NoShaderBinding` then the shader synthesised a direct access into
descriptor storage without passing through a declared binding.
:type: int
)");
uint16_t index = 0;
static const uint16_t NoShaderBinding = 0xFFFF;
DOCUMENT(R"(For an arrayed resource declared in a shader, the array element used.
:type: int
)");
uint32_t arrayElement = 0;
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;
DOCUMENT(R"(For informational purposes, some descriptors that are declared in the shader
interface but are provably unused may still be reported as descriptor accesses. This flag will be
set to ``True`` to indicate that the descriptor was definitely not used.
This flag only states that a descriptor is definitely unused on all paths. If set to ``False`` this
does not necessarily guarantee that the descriptor was accessed on the GPU during execution.
:type: bool
)");
bool staticallyUnused = false;
};
DECLARE_REFLECTION_STRUCT(DescriptorAccess);
DOCUMENT("Information about a single constant buffer binding.");
struct BoundCBuffer
{
+7
View File
@@ -27,6 +27,7 @@
#include <functional>
#include "apidefs.h"
#include "common_pipestate.h"
#include "data_types.h"
#include "rdcarray.h"
#include "replay_enums.h"
@@ -638,6 +639,12 @@ struct DescriptorRange
DescriptorRange(const DescriptorRange &) = default;
DescriptorRange &operator=(const DescriptorRange &) = default;
DescriptorRange(const DescriptorAccess &access)
{
offset = access.byteOffset;
descriptorSize = access.byteSize;
}
DOCUMENT("The offset in the descriptor storage where the descriptor range starts.");
uint32_t offset = 0;
DOCUMENT("The size of each descriptor in the range.");
+7
View File
@@ -588,6 +588,13 @@ Multiple ranges within the store can be queried at once, and are returned in a c
virtual rdcarray<SamplerDescriptor> GetSamplerDescriptors(
ResourceId descriptorStore, const rdcarray<DescriptorRange> &ranges) = 0;
DOCUMENT(R"(Retrieve the descriptor accesses that happened at the current event.
:return: The descriptor accesses.
:rtype: List[DescriptorAccess]
)");
virtual rdcarray<DescriptorAccess> GetDescriptorAccess() = 0;
DOCUMENT(R"(Retrieve the list of possible disassembly targets for :meth:`DisassembleShader`. The
values are implementation dependent but will always include a default target first which is the
native disassembly of the shader. Further options may be available for additional diassembly views
+33 -1
View File
@@ -907,6 +907,38 @@ enum class DescriptorType : uint8_t
DECLARE_REFLECTION_ENUM(DescriptorType);
DOCUMENT("Checks if a descriptor type corresponds to a constant buffer in shader reflection.");
constexpr bool IsConstantBufferDescriptor(DescriptorType type)
{
return type == DescriptorType::ConstantBuffer;
}
DOCUMENT(R"(Checks if a descriptor type corresponds to a sampler in shader reflection. Only dedicated
sampler types are sampler descriptors, combined image/samplers are reported only as read only
resources.
)");
constexpr bool IsSamplerDescriptor(DescriptorType type)
{
return type == DescriptorType::Sampler;
}
DOCUMENT(R"(Checks if a descriptor type corresponds to a read only resource in shader reflection.
Combined image/samplers are reported as read only resources.
)");
constexpr bool IsReadOnlyDescriptor(DescriptorType type)
{
return type == DescriptorType::ImageSampler || type == DescriptorType::Image ||
type == DescriptorType::TypedBuffer;
}
DOCUMENT(R"(Checks if a descriptor type corresponds to a read write resource in shader reflection.
)");
constexpr bool IsReadWriteDescriptor(DescriptorType type)
{
return type == DescriptorType::ReadWriteBuffer || type == DescriptorType::ReadWriteImage ||
type == DescriptorType::ReadWriteTypedBuffer;
}
DOCUMENT3(R"(Annotates a particular built-in input or output from a shader with a special meaning to
the hardware or API.
@@ -2472,7 +2504,7 @@ DOCUMENT(R"(The stage in a pipeline where a shader runs
The mesh shader.
)");
enum class ShaderStage : uint32_t
enum class ShaderStage : uint8_t
{
Vertex = 0,
First = Vertex,