Skip to content

Commit b4079f3

Browse files
committed
feat: add descriptor binding logic
Signed-off-by: Michael Pollind <mpollind@gmail.com>
1 parent 4b283c0 commit b4079f3

File tree

7 files changed

+184
-48
lines changed

7 files changed

+184
-48
lines changed

Source/Metal/DescriptorMTL.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ struct DescriptorMTL {
5050
Result Create(const Texture3DViewDesc& textureViewDesc);
5151
Result Create(const SamplerDesc& samplerDesc);
5252

53-
5453
private:
5554

5655
DeviceMTL& m_Device;

Source/Metal/DescriptorPoolMTL.h

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,31 +15,29 @@ struct DescriptorPoolMTL {
1515
, m_AllocatedSets(device.GetStdAllocator()) {
1616
m_AllocatedSets.reserve(64);
1717
}
18-
//
19-
// inline operator VkDescriptorPool() const {
20-
// return m_Handle;
21-
// }
22-
//
18+
2319
inline DeviceMTL& GetDevice() const {
2420
return m_Device;
2521
}
2622

2723
~DescriptorPoolMTL();
28-
2924
Result Create(const DescriptorPoolDesc& descriptorPoolDesc);
3025

3126
//================================================================================================================
3227
// NRI
3328
//================================================================================================================
34-
29+
30+
// size_t GetNumberOfArugmentsAlloc();
3531
void SetDebugName(const char* name);
3632
void Reset();
3733
Result AllocateDescriptorSets(const PipelineLayout& pipelineLayout, uint32_t setIndex, DescriptorSet** descriptorSets, uint32_t instanceNum, uint32_t variableDescriptorNum);
3834

3935
private:
4036
DeviceMTL& m_Device;
37+
size_t m_ArgumentOffset = 0;
4138
Vector<DescriptorSetMTL*> m_AllocatedSets;
42-
//VkDescriptorPool m_Handle = VK_NULL_HANDLE;
39+
id<MTLBuffer> m_ArgumentBuffer;
40+
4341
uint32_t m_UsedSets = 0;
4442
bool m_OwnsNativeObjects = true;
4543
};

Source/Metal/DescriptorPoolMTL.mm

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11

22
#include "SharedMTL.h"
33
#include "DescriptorPoolMTL.h"
4+
#include "DescriptorSetMTL.h"
5+
#include "PipelineLayoutMTL.h"
46

57
using namespace nri;
68

@@ -10,9 +12,25 @@
1012
}
1113

1214
Result DescriptorPoolMTL::Create(const DescriptorPoolDesc& descriptorPoolDesc) {
13-
15+
size_t numArgs = descriptorPoolDesc.samplerMaxNum +
16+
descriptorPoolDesc.constantBufferMaxNum +
17+
descriptorPoolDesc.dynamicConstantBufferMaxNum +
18+
descriptorPoolDesc.textureMaxNum +
19+
descriptorPoolDesc.storageTextureMaxNum +
20+
descriptorPoolDesc.bufferMaxNum +
21+
descriptorPoolDesc.storageBufferMaxNum +
22+
descriptorPoolDesc.structuredBufferMaxNum +
23+
descriptorPoolDesc.accelerationStructureMaxNum;
24+
25+
m_ArgumentBuffer = [m_Device
26+
newBufferWithLength: numArgs * sizeof(uint32_t) options:MTLResourceStorageModeShared];
1427
}
1528

29+
30+
//size_t DescriptorPoolMTL::GetNumberOfArugmentsAlloc() {
31+
// return [m_ArgumentBuffer length] / sizeof(uint32_t);
32+
//}
33+
1634
//================================================================================================================
1735
// NRI
1836
//================================================================================================================
@@ -23,7 +41,32 @@
2341
void DescriptorPoolMTL::Reset() {
2442

2543
}
44+
2645
Result DescriptorPoolMTL::AllocateDescriptorSets(const PipelineLayout& pipelineLayout, uint32_t setIndex, DescriptorSet** descriptorSets, uint32_t instanceNum, uint32_t variableDescriptorNum) {
46+
PipelineLayoutMTL* pipelineLayoutMTL = (PipelineLayoutMTL*)&pipelineLayout;
47+
48+
uint32_t freeSetNum = (uint32_t)m_AllocatedSets.size() - m_UsedSets;
49+
if (freeSetNum < instanceNum) {
50+
uint32_t newSetNum = instanceNum - freeSetNum;
51+
uint32_t prevSetNum = (uint32_t)m_AllocatedSets.size();
52+
m_AllocatedSets.resize(prevSetNum + newSetNum);
53+
for (size_t i = 0; i < newSetNum; i++) {
54+
Construct(m_AllocatedSets[prevSetNum + i], 1, m_Device);
55+
}
56+
}
57+
58+
struct DescriptorSetLayout* setLayoutMTL = pipelineLayoutMTL->GetDescriptorSetLayout(setIndex);
59+
for(uint32_t i = 0; i < instanceNum; i++) {
60+
descriptorSets[i] = (DescriptorSet*)m_AllocatedSets[m_UsedSets++];
61+
((DescriptorSetMTL*)descriptorSets[i])->Create(
62+
m_ArgumentOffset,
63+
m_ArgumentBuffer,
64+
setLayoutMTL->m_ArgumentDescriptors,
65+
&setLayoutMTL->m_DescriptorSetDesc);
66+
m_ArgumentOffset += ((DescriptorSetMTL*)descriptorSets[i])->getDescriptorLength();
67+
}
68+
69+
2770
return Result::SUCCESS;
2871
}
2972

Source/Metal/DescriptorSetMTL.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,21 @@ struct DescriptorSetMTL {
1111
: m_Device(device) {
1212
}
1313

14-
14+
void Create(size_t argumentBufferOffset, id<MTLBuffer> argumentBuffer, NSArray<MTLArgumentDescriptor *>* argDesc, const struct DescriptorSetDesc* desc);
1515
void UpdateDescriptorRanges(uint32_t rangeOffset, uint32_t rangeNum, const DescriptorRangeUpdateDesc* rangeUpdateDescs);
16-
1716
inline id<MTLArgumentEncoder> GetArgumentHandle() {
1817
return m_ArgumentEncoder;
1918
}
19+
size_t getDescriptorLength();
2020

2121
private:
2222
DeviceMTL& m_Device;
23-
id<MTLArgumentEncoder> m_ArgumentEncoder;
24-
23+
id<MTLArgumentEncoder> m_ArgumentEncoder;
24+
id<MTLBuffer> m_ArgumentBuffer;
25+
size_t m_ArgumentBufferOffset;
26+
NSArray<MTLArgumentDescriptor *>* m_ArgumentDescriptor;
27+
const DescriptorSetDesc* m_Desc = nullptr;
2528
};
2629

27-
2830
} // namespace nri
2931

Source/Metal/DescriptorSetMTL.mm

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,45 @@
77
using namespace nri;
88

99

10+
void DescriptorSetMTL::Create(size_t argumentBufferOffset, id<MTLBuffer> argumentBuffer, NSArray<MTLArgumentDescriptor *>* argDesc, const struct DescriptorSetDesc* desc) {
11+
m_ArgumentDescriptor = argDesc;
12+
m_ArgumentBuffer = argumentBuffer;
13+
m_ArgumentBufferOffset = argumentBufferOffset;
14+
m_Desc = desc;
15+
m_ArgumentEncoder = [m_Device newArgumentEncoderWithArguments: argDesc];
16+
[m_ArgumentEncoder setArgumentBuffer:m_ArgumentBuffer offset:argumentBufferOffset];
17+
}
18+
19+
size_t DescriptorSetMTL::getDescriptorLength() {
20+
return [m_ArgumentEncoder encodedLength];
21+
}
22+
1023
void DescriptorSetMTL::UpdateDescriptorRanges(uint32_t rangeOffset, uint32_t rangeNum, const DescriptorRangeUpdateDesc* rangeUpdateDescs) {
1124

1225
for(size_t j = 0; j < rangeNum; j++) {
1326
const DescriptorRangeUpdateDesc& update = rangeUpdateDescs[j];
14-
15-
// uint32_t offset = update.baseDescriptor + descriptorOffset;
16-
1727
for(size_t descIdx = 0; descIdx < update.descriptorNum; descIdx++) {
28+
DescriptorMTL* descriptorImpl = (DescriptorMTL*)&update.descriptors[descIdx];
29+
const DescriptorRangeDesc& rangeDesc = m_Desc->ranges[rangeOffset + j];
1830

19-
DescriptorMTL& descriptorImpl = *(DescriptorMTL*)&update.descriptors[descIdx];
20-
switch(descriptorImpl.GetType()) {
31+
switch(descriptorImpl->GetType()) {
2132
case DescriptorTypeMTL::IMAGE_VIEW_1D:
22-
[m_ArgumentEncoder setTexture: descriptorImpl.GetTextureHandle() atIndex:0];
23-
// [m_ArgumentEncoder setTextures:<#(id<MTLTexture> _Nullable const * _Nonnull)#> withRange:<#(NSRange)#>]
24-
break;
2533
case DescriptorTypeMTL::IMAGE_VIEW_2D:
26-
[m_ArgumentEncoder setTexture: descriptorImpl.GetTextureHandle() atIndex:0];
34+
case DescriptorTypeMTL::IMAGE_VIEW_3D:
35+
[m_ArgumentEncoder setTexture: descriptorImpl->GetTextureHandle() atIndex: rangeDesc.baseRegisterIndex + descIdx];
2736
break;
28-
case DescriptorTypeMTL::BUFFER_VIEW:
29-
// [m_ArgumentEncoder setBuffer: offset:<#(NSUInteger)#> atIndex:<#(NSUInteger)#>]
37+
case DescriptorTypeMTL::SAMPLER:
38+
[m_ArgumentEncoder setSamplerState: descriptorImpl->GetSamplerStateHandler() atIndex:rangeDesc.baseRegisterIndex + descIdx]; // not sure if this is correct
39+
break;
40+
case DescriptorTypeMTL::BUFFER_VIEW: {
41+
BufferViewDesc* view = &descriptorImpl->BufferView();
42+
[m_ArgumentEncoder setBuffer: descriptorImpl->GetBufferHandle() offset: view->offset atIndex: rangeDesc.baseRegisterIndex + descIdx];
43+
break;
44+
}
45+
default:
3046
break;
3147
}
32-
33-
// update.descriptors[descIdx];
48+
3449
}
3550
}
3651
}

Source/Metal/PipelineLayoutMTL.h

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,57 @@ namespace nri {
66

77
struct DeviceMTL;
88

9+
10+
//
11+
//struct BindingInfo {
12+
// BindingInfo(StdAllocator<uint8_t>& allocator);
13+
//// Vector<PushConstantBindingDesc> pushConstantBindings;
14+
//// Vector<PushDescriptorBindingDesc> pushDescriptorBindings;
15+
//};
16+
17+
struct DescriptorSetLayout {
18+
DescriptorSetDesc m_DescriptorSetDesc;
19+
NSMutableArray<MTLArgumentDescriptor*>* m_ArgumentDescriptors;
20+
};
21+
922
struct PipelineLayoutMTL {
23+
1024
inline PipelineLayoutMTL (DeviceMTL& device)
11-
: m_Device(device) {
25+
: m_Device(device)
26+
, m_HasVariableDescriptorNum(device.GetStdAllocator())
27+
, m_DescriptorSetRangeDescs(device.GetStdAllocator())
28+
, m_DynamicConstantBufferDescs(device.GetStdAllocator())
29+
, m_DescriptorSets(device.GetStdAllocator())
30+
{
1231
}
1332

1433
~PipelineLayoutMTL();
15-
16-
Result Create(const PipelineLayoutDesc& pipelineLayoutDesc);
1734

18-
struct PipelineDescriptorSet {
19-
NSMutableArray<MTLArgumentDescriptor*>* m_ArgumentDescriptors;
20-
};
35+
inline DeviceMTL& GetDevice() const {
36+
return m_Device;
37+
}
38+
39+
inline struct DescriptorSetLayout* GetDescriptorSetLayout(uint32_t setIndex) {
40+
return &m_DescriptorSets[setIndex];
41+
}
42+
43+
// inline struct DescriptorSetDesc* GetDescriptorSetDesc(uint32_t setIndex) {
44+
// return &m_DescriptorSetDesc[setIndex];
45+
// }
46+
47+
Result Create(const PipelineLayoutDesc& pipelineLayoutDesc);
48+
2149

2250
private:
2351
DeviceMTL& m_Device;
2452

25-
std::vector<PipelineDescriptorSet> m_DescriptorSets;
53+
Vector<bool> m_HasVariableDescriptorNum;
54+
Vector<DescriptorRangeDesc> m_DescriptorSetRangeDescs;
55+
Vector<DynamicConstantBufferDesc> m_DynamicConstantBufferDescs;
56+
// Vector<DescriptorSetDesc> m_DescriptorSetDesc;
57+
Vector<DescriptorSetLayout> m_DescriptorSets;
58+
59+
// BindingInfo m_BindingInfo;
2660
};
2761

2862
}

Source/Metal/PipelineLayoutMTL.mm

Lines changed: 58 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,76 @@
44

55
using namespace nri;
66

7+
//
8+
//BindingInfo::BindingInfo(StdAllocator<uint8_t>& allocator)
9+
// : hasVariableDescriptorNum(allocator)
10+
// , descriptorSetRangeDescs(allocator)
11+
// , dynamicConstantBufferDescs(allocator)
12+
// , descriptorSetDescs(allocator) {
13+
//
14+
//}
15+
//
16+
717
PipelineLayoutMTL::~PipelineLayoutMTL() {
818

919
}
1020

1121
Result PipelineLayoutMTL::Create(const PipelineLayoutDesc& pipelineLayoutDesc) {
22+
23+
24+
size_t rangeNum = 0;
25+
size_t dynamicConstantBufferNum = 0;
26+
for (uint32_t i = 0; i < pipelineLayoutDesc.descriptorSetNum; i++) {
27+
rangeNum += pipelineLayoutDesc.descriptorSets[i].rangeNum;
28+
dynamicConstantBufferNum += pipelineLayoutDesc.descriptorSets[i].dynamicConstantBufferNum;
29+
}
30+
1231
m_DescriptorSets.resize(pipelineLayoutDesc.descriptorSetNum);
32+
m_HasVariableDescriptorNum.resize(pipelineLayoutDesc.descriptorSetNum);
33+
m_DescriptorSetRangeDescs.reserve(rangeNum);
34+
m_DynamicConstantBufferDescs.reserve(dynamicConstantBufferNum);
35+
1336
for (uint32_t i = 0; i < pipelineLayoutDesc.descriptorSetNum; i++) {
1437
const DescriptorSetDesc& descriptorSetDesc = pipelineLayoutDesc.descriptorSets[i];
1538

16-
NSMutableArray<MTLArgumentDescriptor*>* argumentDescriptors = [[NSMutableArray alloc] init];
17-
MTLArgumentDescriptor* argDescriptor = [MTLArgumentDescriptor argumentDescriptor];
39+
// Binding info
40+
m_HasVariableDescriptorNum[i] = false;
41+
m_DescriptorSets[i].m_DescriptorSetDesc = descriptorSetDesc;
42+
m_DescriptorSets[i].m_DescriptorSetDesc.ranges = m_DescriptorSetRangeDescs.data() +m_DescriptorSetRangeDescs.size();
43+
m_DescriptorSets[i].m_DescriptorSetDesc.dynamicConstantBuffers = m_DynamicConstantBufferDescs.data() + m_DynamicConstantBufferDescs.size();
44+
m_DescriptorSetRangeDescs.insert(m_DescriptorSetRangeDescs.end(), descriptorSetDesc.ranges, descriptorSetDesc.ranges + descriptorSetDesc.rangeNum);
45+
m_DynamicConstantBufferDescs.insert(m_DynamicConstantBufferDescs.end(), descriptorSetDesc.dynamicConstantBuffers, descriptorSetDesc.dynamicConstantBuffers + descriptorSetDesc.dynamicConstantBufferNum);
1846

47+
NSMutableArray<MTLArgumentDescriptor*>* argumentDescriptors = [[NSMutableArray alloc] init];
1948
for(size_t r = 0; r < descriptorSetDesc.rangeNum; r++) {
20-
49+
MTLArgumentDescriptor* argDescriptor = [MTLArgumentDescriptor argumentDescriptor];
50+
const DescriptorRangeDesc* range = &descriptorSetDesc.ranges[r];
51+
argDescriptor.arrayLength = range->descriptorNum;
52+
argDescriptor.access = MTLBindingAccessReadWrite;
53+
argDescriptor.index = range->baseRegisterIndex;
54+
switch(range->descriptorType) {
55+
case DescriptorType::TEXTURE:
56+
argDescriptor.dataType = MTLDataTypeTexture;
57+
argDescriptor.textureType = MTLTextureType2D; // descriptor type does not have this
58+
break;
59+
case DescriptorType::SAMPLER:
60+
argDescriptor.dataType = MTLDataTypeSampler;
61+
break;
62+
case DescriptorType::CONSTANT_BUFFER:
63+
case DescriptorType::STORAGE_TEXTURE:
64+
case DescriptorType::BUFFER:
65+
case DescriptorType::STORAGE_BUFFER:
66+
case DescriptorType::STRUCTURED_BUFFER:
67+
case DescriptorType::STORAGE_STRUCTURED_BUFFER:
68+
argDescriptor.dataType = MTLDataTypeStruct;
69+
break;
70+
case DescriptorType::ACCELERATION_STRUCTURE:
71+
argDescriptor.dataType = MTLDataTypePrimitiveAccelerationStructure;
72+
break;
73+
default:
74+
break;
75+
}
2176
}
22-
23-
24-
//argDescriptor.access = memberDescriptor.mAccessType;
25-
//argDescriptor.arrayLength = memberDescriptor.mArrayLength;
26-
//argDescriptor.constantBlockAlignment = memberDescriptor.mAlignment;
27-
//argDescriptor.dataType = memberDescriptor.mDataType;
28-
//argDescriptor.index = memberDescriptor.mArgumentIndex;
29-
//argDescriptor.textureType = memberDescriptor.mTextureType;
30-
31-
[argumentDescriptors addObject:argDescriptor];
3277
m_DescriptorSets[i].m_ArgumentDescriptors = argumentDescriptors;
3378

3479
}

0 commit comments

Comments
 (0)