Skip to content

Commit aa64558

Browse files
committed
Serialization of graphics pipeline parameter structs
To be independent of bitfields (order, byte-straddling, values of unused bits etc)
1 parent 0e99ad7 commit aa64558

File tree

2 files changed

+106
-13
lines changed

2 files changed

+106
-13
lines changed

include/irr/asset/IRenderpassIndependentPipeline.h

Lines changed: 96 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,29 @@ struct SVertexInputAttribParams
5050
uint32_t binding : 4;
5151
uint32_t format : 8;//asset::E_FORMAT
5252
uint32_t relativeOffset : 13;//assuming max=2048
53+
54+
constexpr static size_t serializedSize() { return sizeof(uint32_t); }
55+
56+
void serialize(void* mem) const
57+
{
58+
auto* dst = reinterpret_cast<uint32_t*>(mem);
59+
*dst = core::bitfieldInsert(*dst, binding, 0, 4);
60+
*dst = core::bitfieldInsert(*dst, format, 4, 8);
61+
*dst = core::bitfieldInsert(*dst, relativeOffset, 12, 13);
62+
}
5363
} PACK_STRUCT;
5464
static_assert(sizeof(SVertexInputAttribParams)==(4u), "Unexpected size!");
5565
struct SVertexInputBindingParams
5666
{
5767
uint32_t stride = 0u;
5868
E_VERTEX_INPUT_RATE inputRate = EVIR_PER_VERTEX;
69+
70+
constexpr static size_t serializedSize() { return sizeof(SVertexInputBindingParams); }
71+
72+
void serialize(void* mem) const
73+
{
74+
memcpy(mem, this, serializedSize());
75+
}
5976
} PACK_STRUCT;
6077
static_assert(sizeof(SVertexInputBindingParams)==5u, "Unexpected size!");
6178
struct SVertexInputParams
@@ -72,6 +89,21 @@ struct SVertexInputParams
7289

7390
static_assert(sizeof(enabledAttribFlags)*8 >= MAX_VERTEX_ATTRIB_COUNT, "Insufficient flag bits for number of supported attributes");
7491
static_assert(sizeof(enabledBindingFlags)*8 >= MAX_ATTR_BUF_BINDING_COUNT, "Insufficient flag bits for number of supported bindings");
92+
93+
constexpr static size_t serializedSize() { return 2u*sizeof(uint16_t) + MAX_VERTEX_ATTRIB_COUNT*SVertexInputAttribParams::serializedSize() + MAX_ATTR_BUF_BINDING_COUNT*SVertexInputBindingParams::serializedSize(); }
94+
95+
void serialize(void* mem) const
96+
{
97+
auto* flags = reinterpret_cast<uint16_t*>(mem);
98+
flags[0] = enabledAttribFlags;
99+
flags[1] = enabledBindingFlags;
100+
auto* dst = reinterpret_cast<uint8_t*>(flags + 2);
101+
for (uint32_t i = 0u; i < MAX_VERTEX_ATTRIB_COUNT; ++i)
102+
attributes[i].serialize(dst + i*attributes[i].serializedSize());
103+
dst += MAX_VERTEX_ATTRIB_COUNT * SVertexInputAttribParams::serializedSize();
104+
for (uint32_t i = 0u; i < MAX_VERTEX_ATTRIB_COUNT; ++i)
105+
bindings[i].serialize(dst + i*bindings[i].serializedSize());
106+
}
75107
} PACK_STRUCT;
76108
static_assert(sizeof(SVertexInputParams) == (2u * 2u + SVertexInputParams::MAX_VERTEX_ATTRIB_COUNT * sizeof(SVertexInputAttribParams) + SVertexInputParams::MAX_ATTR_BUF_BINDING_COUNT * sizeof(SVertexInputBindingParams)), "Unexpected size!");
77109

@@ -80,6 +112,13 @@ struct SPrimitiveAssemblyParams
80112
E_PRIMITIVE_TOPOLOGY primitiveType = EPT_TRIANGLE_LIST;
81113
uint8_t primitiveRestartEnable = false;
82114
uint16_t tessPatchVertCount = 3u;
115+
116+
constexpr static size_t serializedSize() { return sizeof(SPrimitiveAssemblyParams); }
117+
118+
void serialize(void* mem) const
119+
{
120+
memcpy(mem, this, sizeof(*this));
121+
}
83122
} PACK_STRUCT;
84123
static_assert(sizeof(SPrimitiveAssemblyParams)==4u, "Unexpected size!");
85124

@@ -174,6 +213,29 @@ struct SRasterizationParams
174213
uint16_t depthBoundsTestEnable : 1;
175214
uint16_t stencilTestEnable : 1;
176215
} PACK_STRUCT;
216+
217+
constexpr static size_t serializedSize() { return offsetof(SRasterizationParams, backStencilOps) + sizeof(SStencilOpParams) + sizeof(uint16_t); }
218+
219+
void serialize(void* _mem) const
220+
{
221+
memcpy(_mem, this, sizeof(*this));
222+
auto* bf_dst = reinterpret_cast<uint8_t*>(_mem);
223+
bf_dst += offsetof(SRasterizationParams, backStencilOps) + sizeof(SStencilOpParams);
224+
uint16_t bf = 0;
225+
bf = core::bitfieldInsert(bf, depthClampEnable, 0, 1);
226+
bf = core::bitfieldInsert(bf, rasterizerDiscard, 1, 1);
227+
bf = core::bitfieldInsert(bf, frontFaceIsCCW, 2, 1);
228+
bf = core::bitfieldInsert(bf, depthBiasEnable, 3, 1);
229+
bf = core::bitfieldInsert(bf, sampleShadingEnable, 4, 1);
230+
bf = core::bitfieldInsert(bf, alphaToCoverageEnable, 5, 1);
231+
bf = core::bitfieldInsert(bf, alphaToOneEnable, 6, 1);
232+
bf = core::bitfieldInsert(bf, depthTestEnable, 7, 1);
233+
bf = core::bitfieldInsert(bf, depthWriteEnable, 8, 1);
234+
bf = core::bitfieldInsert(bf, depthBoundsTestEnable, 9, 1);
235+
bf = core::bitfieldInsert(bf, stencilTestEnable, 10, 1);
236+
237+
reinterpret_cast<uint16_t*>(bf_dst)[0] = bf;
238+
}
177239
} PACK_STRUCT;
178240
static_assert(sizeof(SRasterizationParams)==4u*sizeof(uint8_t) + 3u*sizeof(uint32_t) + 3u*sizeof(float) + 2u*sizeof(SStencilOpParams) + sizeof(uint16_t), "Unexpected size!");
179241

@@ -275,7 +337,6 @@ enum E_BLEND_OP : uint8_t
275337
EBO_BLUE_EXT
276338
};
277339

278-
#include "irr/irrunpack.h"
279340

280341
struct SColorAttachmentBlendParams
281342
{
@@ -306,7 +367,26 @@ struct SColorAttachmentBlendParams
306367
uint8_t alphaBlendOp : 2;
307368
//RGBA, LSB is R, MSB is A
308369
uint8_t colorWriteMask : 4;
309-
};
370+
371+
constexpr static size_t serializedSize() { return 5ull; }
372+
373+
void serialize(void* _mem) const
374+
{
375+
auto* bf_dst = reinterpret_cast<uint8_t*>(_mem);
376+
uint64_t bf = 0;
377+
bf = core::bitfieldInsert<uint64_t>(bf, attachmentEnabled, 0, 1);
378+
bf = core::bitfieldInsert<uint64_t>(bf, blendEnable, 1, 1);
379+
bf = core::bitfieldInsert<uint64_t>(bf, srcColorFactor, 2, 5);
380+
bf = core::bitfieldInsert<uint64_t>(bf, dstColorFactor, 7, 5);
381+
bf = core::bitfieldInsert<uint64_t>(bf, colorBlendOp, 12, 6);
382+
bf = core::bitfieldInsert<uint64_t>(bf, srcAlphaFactor, 18, 5);
383+
bf = core::bitfieldInsert<uint64_t>(bf, dstAlphaFactor, 23, 5);
384+
bf = core::bitfieldInsert<uint64_t>(bf, alphaBlendOp, 28, 2);
385+
bf = core::bitfieldInsert<uint64_t>(bf, colorWriteMask, 30, 4);
386+
387+
memcpy(bf_dst, &bf, serializedSize());
388+
}
389+
} PACK_STRUCT;
310390
static_assert(sizeof(SColorAttachmentBlendParams)==6u, "Unexpected size of SColorAttachmentBlendParams (should be 6)");
311391

312392
struct SBlendParams
@@ -317,9 +397,22 @@ struct SBlendParams
317397
uint8_t logicOpEnable : 1;
318398
uint8_t logicOp : 4;
319399
SColorAttachmentBlendParams blendParams[MAX_COLOR_ATTACHMENT_COUNT];
320-
};
400+
401+
constexpr static size_t serializedSize() { return 1u + MAX_COLOR_ATTACHMENT_COUNT * SColorAttachmentBlendParams::serializedSize(); }
402+
403+
void serialize(void* _mem) const
404+
{
405+
auto* bf_dst = reinterpret_cast<uint8_t*>(_mem);
406+
*bf_dst = core::bitfieldInsert(*bf_dst, logicOpEnable, 0, 1);
407+
*bf_dst = core::bitfieldInsert(*bf_dst, logicOp, 1, 4);
408+
++bf_dst;
409+
for (uint32_t i = 0u; i < MAX_COLOR_ATTACHMENT_COUNT; ++i)
410+
blendParams[i].serialize(bf_dst + i*SColorAttachmentBlendParams::serializedSize());
411+
}
412+
} PACK_STRUCT;
321413
static_assert(sizeof(SBlendParams)==(1u + sizeof(SColorAttachmentBlendParams)*SBlendParams::MAX_COLOR_ATTACHMENT_COUNT), "Unexpected size!");
322414

415+
#include "irr/irrunpack.h"
323416

324417
//TODO put into legacy namespace later
325418
/*

include/irr/video/IGPUObjectFromAssetConverter.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -222,21 +222,21 @@ struct IGPUObjectFromAssetConverter::Hash<asset::ICPURenderpassIndependentPipeli
222222
inline std::size_t operator()(asset::ICPURenderpassIndependentPipeline* _ppln) const
223223
{
224224
constexpr size_t bytesToHash =
225-
sizeof(asset::SVertexInputParams)+
226-
sizeof(asset::SBlendParams)+
227-
sizeof(asset::SRasterizationParams)+
228-
sizeof(asset::SPrimitiveAssemblyParams)+
225+
asset::SVertexInputParams::serializedSize()+
226+
asset::SBlendParams::serializedSize()+
227+
asset::SRasterizationParams::serializedSize()+
228+
asset::SPrimitiveAssemblyParams::serializedSize()+
229229
sizeof(void*)*asset::ICPURenderpassIndependentPipeline::SHADER_STAGE_COUNT+//shaders
230230
sizeof(void*);//layout
231231
uint8_t mem[bytesToHash]{};
232232
uint32_t offset = 0u;
233-
memcpy(mem+offset,&_ppln->getVertexInputParams(),sizeof(asset::SVertexInputParams));
234-
offset += sizeof(asset::SVertexInputParams);
235-
memcpy(mem+offset,&_ppln->getBlendParams(),sizeof(asset::SBlendParams));
236-
offset += sizeof(asset::SBlendParams);
237-
memcpy(mem+offset,&_ppln->getRasterizationParams(),sizeof(asset::SRasterizationParams));
233+
_ppln->getVertexInputParams().serialize(mem+offset);
234+
offset += asset::SVertexInputParams::serializedSize();
235+
_ppln->getBlendParams().serialize(mem+offset);
236+
offset += asset::SBlendParams::serializedSize();
237+
_ppln->getRasterizationParams().serialize(mem+offset);
238238
offset += sizeof(asset::SRasterizationParams);
239-
memcpy(mem+offset,&_ppln->getPrimitiveAssemblyParams(),sizeof(asset::SPrimitiveAssemblyParams));
239+
_ppln->getPrimitiveAssemblyParams().serialize(mem+offset);
240240
offset += sizeof(asset::SPrimitiveAssemblyParams);
241241
const asset::ICPUSpecializedShader** shaders = reinterpret_cast<const asset::ICPUSpecializedShader**>(mem+offset);
242242
for (uint32_t i = 0u; i < asset::ICPURenderpassIndependentPipeline::SHADER_STAGE_COUNT; ++i)

0 commit comments

Comments
 (0)