-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathBindingGroupLayout.hpp
More file actions
132 lines (108 loc) · 4.11 KB
/
BindingGroupLayout.hpp
File metadata and controls
132 lines (108 loc) · 4.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#pragma once
#include "gapi/ForwardDeclarations.hpp"
#include "gapi/Resource.hpp"
#include "gapi/Shader.hpp"
#include "gapi/Limits.hpp"
#include "common/hashing/Hash.hpp"
#include <EASTL/fixed_vector.h>
#include <EASTL/span.h>
#include <EASTL/vector_map.h>
namespace RR::GAPI
{
enum class BindingType : uint8_t
{
ConstantBuffer,
TextureSRV,
TextureUAV,
BufferSRV,
BufferUAV,
Sampler
};
struct BindingLayoutElement
{
BindingType type;
uint32_t binding;
uint32_t count;
ShaderStageMask stageMask;
// Populated for TextureSRV and TextureUAV
GpuResourceDimension dimension;
GpuResourceFormat format; // TextureUAV only
TextureSampleType sampleType; // TextureSRV only
};
struct BindingGroupLayoutDesc
{
eastl::span<const BindingLayoutElement> elements;
};
// Reflection: a single uniform field within a CBV
struct FieldDesc
{
Common::HashType nameHash;
uint16_t offset; // byte offset in uniform buffer
uint16_t size; // byte size of field
};
// Reflection: a single resource slot (SRV, UAV, sampler)
struct ResourceSlotDesc
{
Common::HashType nameHash;
uint16_t binding; // binding index in bind group
uint16_t slotIndex; // dense index in EffectContext::resources[]
BindingType type;
};
struct BindingGroupReflectionDesc
{
uint32_t bindingSpace = 0;
eastl::span<const FieldDesc> fields;
eastl::span<const ResourceSlotDesc> resources;
uint32_t uniformBufferSize = 0;
uint32_t uniformCbvSlot = ~0u;
};
class IBindingGroupLayout
{
public:
virtual ~IBindingGroupLayout() = default;
};
class BindingGroupLayout final : public Resource<IBindingGroupLayout, true>
{
public:
static constexpr uint32_t INVALID_SLOT = ~0u;
BindingGroupLayout(const std::string& name)
: Resource(Type::BindingGroupLayout, name)
{
}
// Populate reflection metadata (call after GPU init).
void InitReflection(const BindingGroupReflectionDesc& desc);
uint32_t GetBindingSpace() const { return bindingSpace; }
uint32_t GetUniformBufferSize() const { return uniformBufferSize; }
uint32_t GetUniformCbvSlot() const { return uniformCbvSlot; }
uint32_t GetFieldCount() const { return static_cast<uint32_t>(fields.size()); }
const FieldDesc& GetField(uint32_t index) const
{
ASSERT(index < fields.size());
return fields[index];
}
uint32_t GetResourceSlotCount() const { return static_cast<uint32_t>(resourceSlots.size()); }
const ResourceSlotDesc& GetResourceSlot(uint32_t index) const
{
ASSERT(index < resourceSlots.size());
return resourceSlots[index];
}
// O(log n) lookup by precomputed name hash. Cache the index for hot paths.
uint32_t FindFieldIndex(Common::HashType nameHash) const;
uint32_t FindResourceSlotIndex(Common::HashType nameHash) const;
private:
using HashToIndex = eastl::pair<Common::HashType, uint32_t>;
template <size_t N, bool Overflow = true>
using Lookup = eastl::vector_map<
Common::HashType, uint32_t,
eastl::less<Common::HashType>,
EASTLAllocatorType,
eastl::fixed_vector<HashToIndex, N, Overflow>>;
uint32_t bindingSpace = 0;
uint32_t uniformBufferSize = 0;
uint32_t uniformCbvSlot = INVALID_SLOT;
eastl::fixed_vector<FieldDesc, 16, true> fields;
eastl::fixed_vector<ResourceSlotDesc, MAX_BINDINGS_PER_GROUP, false> resourceSlots;
Lookup<16> fieldMap; // nameHash -> field index
Lookup<MAX_BINDINGS_PER_GROUP, false> resourceMap; // nameHash -> slot index
};
}