Skip to content

Commit ff707a5

Browse files
committed
New virtual attribute
1 parent 628449c commit ff707a5

File tree

4 files changed

+195
-121
lines changed

4 files changed

+195
-121
lines changed

examples_tests/41.VisibilityBuffer/main.cpp

Lines changed: 98 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ constexpr const char* SHADER_OVERRIDES =
2121
R"(
2222
#define _NBL_VERT_INPUTS_DEFINED_
2323
24-
//#define nbl_glsl_VirtualAttribute_t uint
24+
#define nbl_glsl_VirtualAttribute_t uint
2525
2626
vec4 nbl_glsl_decodeRGB10A2_UNORM(in uint x)
2727
{
@@ -39,28 +39,18 @@ vec4 nbl_glsl_decodeRGB10A2_SNORM(in uint x)
3939
}
4040
4141
//pos
42-
layout(set = 0, binding = 0) uniform samplerBuffer MeshPackedData_R32G32B32_SFLOAT;
42+
layout(set = 0, binding = 0) uniform samplerBuffer MeshPackedDataFloat[2];
4343
4444
//uv
45-
layout(set = 0, binding = 1) uniform samplerBuffer MeshPackedData_R32G32_SFLOAT;
45+
layout(set = 0, binding = 1) uniform isamplerBuffer MeshPackedDataInt[1];
4646
4747
//normal
48-
layout(set = 0, binding = 2) uniform usamplerBuffer MeshPackedData_A2B10G10R10_SNORM_PACK32;
48+
layout(set = 0, binding = 2) uniform usamplerBuffer MeshPackedDataUint[1];
4949
50-
layout(set = 0, binding = 3) readonly buffer VertexDataOffsetTable
50+
layout(set = 0, binding = 3) readonly buffer VirtualAttributes
5151
{
52-
int dataOffsetTable[];
53-
} vertexPosition;
54-
55-
layout(set = 0, binding = 4) readonly buffer VertexUVOffsetTable
56-
{
57-
int dataOffsetTable[];
58-
} vertexUV;
59-
60-
layout(set = 0, binding = 5) readonly buffer VertexNormalOffsetTable
61-
{
62-
int dataOffsetTable[];
63-
} vertexNormal;
52+
nbl_glsl_VirtualAttribute_t vAttr[][3];
53+
} virtualAttribTable;
6454
6555
#define _NBL_BASIC_VTX_ATTRIB_FETCH_FUCTIONS_DEFINED_
6656
#define _NBL_POS_FETCH_FUNCTION_DEFINED
@@ -73,31 +63,40 @@ layout(set = 0, binding = 5) readonly buffer VertexNormalOffsetTable
7363
//vec3 nbl_glsl_readAttrib(uint offset)
7464
//..
7565
76-
vec3 nbl_glsl_fetchVtxPos()
66+
struct VirtualAttribute
7767
{
78-
int vtxPosOffset = int(gl_VertexIndex) + vertexPosition.dataOffsetTable[gl_DrawID];
79-
return texelFetch(MeshPackedData_R32G32B32_SFLOAT, vtxPosOffset).xyz;
80-
}
68+
uint binding;
69+
int offset;
70+
};
8171
82-
vec2 nbl_glsl_fetchVtxUV()
72+
VirtualAttribute unpackVirtualAttribute(in nbl_glsl_VirtualAttribute_t vaPacked)
8373
{
84-
int vtxUVOffset = int(gl_VertexIndex) + vertexUV.dataOffsetTable[gl_DrawID];
85-
return texelFetch(MeshPackedData_R32G32_SFLOAT, vtxUVOffset).xy;
74+
VirtualAttribute result;
75+
result.binding = bitfieldExtract(vaPacked, 0, 4);
76+
result.offset = int(bitfieldExtract(vaPacked, 4, 28));
77+
78+
return result;
8679
}
8780
88-
vec3 nbl_glsl_fetchVtxNormal()
81+
vec3 nbl_glsl_fetchVtxPos(in uint vtxID)
8982
{
90-
int vtxNormOffset = int(gl_VertexIndex) + vertexNormal.dataOffsetTable[gl_DrawID];
91-
return normalize(nbl_glsl_decodeRGB10A2_SNORM(texelFetch(MeshPackedData_A2B10G10R10_SNORM_PACK32, vtxNormOffset).x).xyz);
83+
VirtualAttribute va = unpackVirtualAttribute(virtualAttribTable.vAttr[gl_DrawID][0]);
84+
return texelFetch(MeshPackedDataFloat[va.binding], va.offset + int(vtxID)).xyz;
9285
}
9386
94-
)";
87+
vec2 nbl_glsl_fetchVtxUV(in uint vtxID)
88+
{
89+
VirtualAttribute va = unpackVirtualAttribute(virtualAttribTable.vAttr[gl_DrawID][1]);
90+
return texelFetch(MeshPackedDataFloat[va.binding], va.offset + int(vtxID)).xy;
91+
}
9592
96-
struct DataOffsetTable
93+
vec3 nbl_glsl_fetchVtxNormal(in uint vtxID)
9794
{
98-
uint32_t binding;
99-
asset::SBufferBinding<IGPUBuffer> offsetBuffer;
100-
};
95+
VirtualAttribute va = unpackVirtualAttribute(virtualAttribTable.vAttr[gl_DrawID][2]);
96+
return nbl_glsl_decodeRGB10A2_SNORM(texelFetch(MeshPackedDataUint[va.binding], va.offset + int(vtxID)).x).xyz;
97+
}
98+
99+
)";
101100

102101
core::smart_refctd_ptr<asset::ICPUSpecializedShader> createModifiedVertexShader(const asset::ICPUSpecializedShader* _fs)
103102
{
@@ -136,8 +135,7 @@ struct DrawIndexedIndirectInput
136135
size_t countOffset = 0u;
137136
};
138137

139-
140-
void packMeshBuffers(video::IVideoDriver* driver, core::vector<ICPUMeshBuffer*>& meshBuffers, DrawIndexedIndirectInput& output, std::array<DataOffsetTable, 3>& offsetTable)
138+
void packMeshBuffers(video::IVideoDriver* driver, core::vector<ICPUMeshBuffer*>& meshBuffers, DrawIndexedIndirectInput& output, core::smart_refctd_ptr<IGPUBuffer>& virtualAttribTableOut)
141139
{
142140
using MeshPacker = CCPUMeshPackerV2<DrawElementsIndirectCommand_t>;
143141

@@ -155,63 +153,65 @@ void packMeshBuffers(video::IVideoDriver* driver, core::vector<ICPUMeshBuffer*>&
155153

156154
bool allocSuccessfull = mp.alloc(allocData.data(), meshBuffers.begin(), meshBuffers.end());
157155
if (!allocSuccessfull)
156+
{
158157
std::cout << "Alloc failed \n";
158+
_NBL_DEBUG_BREAK_IF(true);
159+
}
160+
159161

160162
mp.instantiateDataStorage();
161163
MeshPacker::PackerDataStore packerDataStore = mp.getPackerDataStore();
162164

163165
core::vector<IMeshPackerBase::PackedMeshBufferData> pmbd(meshBuffers.size());
164-
165-
const uint32_t offsetTableSz = mp.calcDataTableNeededSize(meshBuffers.begin(), meshBuffers.end());
166+
167+
const uint32_t offsetTableSz = meshBuffers.size() * 3u;
166168
core::vector<MeshPacker::CombinedDataOffsetTable> cdot(offsetTableSz);
167169

168-
mp.commit(pmbd.data(), cdot.data(), allocData.data(), meshBuffers.begin(), meshBuffers.end());
170+
bool commitSuccessfull = mp.commit(pmbd.data(), cdot.data(), allocData.data(), meshBuffers.begin(), meshBuffers.end());
171+
if (!commitSuccessfull)
172+
{
173+
std::cout << "Commit failed \n";
174+
_NBL_DEBUG_BREAK_IF(true);
175+
}
169176

170177
output.vtxBuffer = { 0ull, driver->createFilledDeviceLocalGPUBufferOnDedMem(packerDataStore.vertexBuffer->getSize(), packerDataStore.vertexBuffer->getPointer()) };
171178
output.idxBuff = driver->createFilledDeviceLocalGPUBufferOnDedMem(packerDataStore.indexBuffer->getSize(), packerDataStore.indexBuffer->getPointer());
172179
output.indirectDrawBuff = driver->createFilledDeviceLocalGPUBufferOnDedMem(packerDataStore.MDIDataBuffer->getSize(), packerDataStore.MDIDataBuffer->getPointer());
173180

174-
output.maxCount = offsetTableSz;
181+
output.maxCount = meshBuffers.size(); //TODO
175182
output.stride = sizeof(DrawElementsIndirectCommand_t);
176183

177-
auto glsl = mp.generateGLSLBufferDefinitions(0u);
184+
//auto glsl = mp.generateGLSLBufferDefinitions(0u);
185+
186+
//setOffsetTables
187+
188+
core::vector<MeshPacker::VirtualAttribute> offsetTableLocal;
189+
offsetTableLocal.reserve(meshBuffers.size() * 3u);
190+
for (uint32_t i = 0u; i < meshBuffers.size(); i++)
191+
{
192+
MeshPacker::CombinedDataOffsetTable& virtualAttribTable = cdot[i];
193+
194+
offsetTableLocal.push_back(virtualAttribTable.attribInfo[0]);
195+
offsetTableLocal.push_back(virtualAttribTable.attribInfo[2]);
196+
offsetTableLocal.push_back(virtualAttribTable.attribInfo[3]);
197+
}
178198

179-
/*DrawElementsIndirectCommand_t* mdiPtr = static_cast<DrawElementsIndirectCommand_t*>(packerDataStore.MDIDataBuffer->getPointer());
199+
/*DrawElementsIndirectCommand_t* mdiPtr = static_cast<DrawElementsIndirectCommand_t*>(packerDataStore.MDIDataBuffer->getPointer()) + 99u;
180200
uint16_t* idxBuffPtr = static_cast<uint16_t*>(packerDataStore.indexBuffer->getPointer());
181201
float* vtxBuffPtr = static_cast<float*>(packerDataStore.vertexBuffer->getPointer());
182202
183-
for (uint32_t i = 0u; i < 1188; i++)
203+
for (uint32_t i = 0u; i < 264; i++)
184204
{
185-
float* firstCoord = vtxBuffPtr + (*(idxBuffPtr + i) * 3u);
205+
float* firstCoord = vtxBuffPtr + ((*(idxBuffPtr + i) + cdot[99].attribInfo[0].offset) * 3u);
186206
std::cout << "vtx: " << i << " idx: " << *(idxBuffPtr + i) << " ";
187207
std::cout << *firstCoord << ' ' << *(firstCoord + 1u) << ' ' << *(firstCoord + 2u) << std::endl;
188208
}*/
189209

190-
//setOffsetTables
191-
192-
core::vector<uint32_t> offsetTableLocal(offsetTableSz);
193-
194-
for (uint32_t i = 0u; i < offsetTableLocal.size(); i++)
195-
offsetTableLocal[i] = cdot[i].attribOffset[0];
196-
197-
offsetTable[0].offsetBuffer.offset = 0u;
198-
offsetTable[0].offsetBuffer.buffer = driver->createFilledDeviceLocalGPUBufferOnDedMem(sizeof(uint32_t) * offsetTableLocal.size(), static_cast<void*>(offsetTableLocal.data()));
199-
200-
for (uint32_t i = 0u; i < offsetTableLocal.size(); i++)
201-
offsetTableLocal[i] = cdot[i].attribOffset[1];
202-
203-
offsetTable[1].offsetBuffer.offset = 0u;
204-
offsetTable[1].offsetBuffer.buffer = driver->createFilledDeviceLocalGPUBufferOnDedMem(sizeof(uint32_t) * offsetTableLocal.size(), static_cast<void*>(offsetTableLocal.data()));
205-
206-
for (uint32_t i = 0u; i < offsetTableLocal.size(); i++)
207-
offsetTableLocal[i] = cdot[i].attribOffset[2];
208-
209-
offsetTable[2].offsetBuffer.offset = 0u;
210-
offsetTable[2].offsetBuffer.buffer = driver->createFilledDeviceLocalGPUBufferOnDedMem(sizeof(uint32_t) * offsetTableLocal.size(), static_cast<void*>(offsetTableLocal.data()));
210+
virtualAttribTableOut = driver->createFilledDeviceLocalGPUBufferOnDedMem(offsetTableLocal.size(), offsetTableLocal.data());
211211
}
212212

213213
void setPipeline(IVideoDriver* driver, ICPUSpecializedShader* vs, ICPUSpecializedShader* fs,
214-
core::smart_refctd_ptr<IGPUBuffer>& vtxBuffer, core::smart_refctd_ptr<IGPUBuffer>& outputUBO, std::array<DataOffsetTable, 3>& dataOffsetBuffers,
214+
core::smart_refctd_ptr<IGPUBuffer>& vtxBuffer, core::smart_refctd_ptr<IGPUBuffer>& outputUBO, core::smart_refctd_ptr<IGPUBuffer>& virtualAttribBuffer,
215215
core::smart_refctd_ptr<IGPUDescriptorSet>& outputGPUDescriptorSet0,
216216
core::smart_refctd_ptr<IGPUDescriptorSet>& outputGPUDescriptorSet1,
217217
core::smart_refctd_ptr<IGPURenderpassIndependentPipeline>& outputGpuPipeline)
@@ -222,16 +222,19 @@ void setPipeline(IVideoDriver* driver, ICPUSpecializedShader* vs, ICPUSpecialize
222222
core::smart_refctd_ptr<IGPUDescriptorSetLayout> ds0Layout;
223223
core::smart_refctd_ptr<IGPUDescriptorSetLayout> ds1Layout;
224224
{
225-
IGPUDescriptorSetLayout::SBinding b[6];
226-
b[0].binding = 0u; b[1].binding = 1u; b[2].binding = 2u; b[3].binding = 3u; b[4].binding = 4u; b[5].binding = 5u;
225+
IGPUDescriptorSetLayout::SBinding b[4];
226+
b[0].binding = 0u; b[1].binding = 1u; b[2].binding = 2u; b[3].binding = 3u;
227227
b[0].type = b[1].type = b[2].type = EDT_UNIFORM_TEXEL_BUFFER;
228-
b[3].type = b[4].type = b[5].type = EDT_STORAGE_BUFFER;
229-
b[0].stageFlags = b[1].stageFlags = b[2].stageFlags = b[3].stageFlags = b[4].stageFlags = b[5].stageFlags = ISpecializedShader::ESS_VERTEX;
230-
b[0].count = b[1].count = b[2].count = b[3].count = b[4].count = b[5].count = 1u;
231-
ds0Layout = driver->createGPUDescriptorSetLayout(b, b + 6u);
228+
b[3].type = EDT_STORAGE_BUFFER;
229+
b[0].stageFlags = b[1].stageFlags = b[2].stageFlags = b[3].stageFlags = ISpecializedShader::ESS_VERTEX;
230+
b[0].count = 2u;
231+
b[1].count = 1u;
232+
b[2].count = 1u;
233+
b[3].count = 1u;
234+
ds0Layout = driver->createGPUDescriptorSetLayout(b, b + 4u);
232235

233236
IGPUDescriptorSetLayout::SBinding b2;
234-
b2.binding = 0;
237+
b2.binding = 0u;
235238
b2.type = EDT_UNIFORM_BUFFER;
236239
b2.stageFlags = ISpecializedShader::ESS_VERTEX;
237240
b2.count = 1u;
@@ -244,48 +247,46 @@ void setPipeline(IVideoDriver* driver, ICPUSpecializedShader* vs, ICPUSpecialize
244247
outputGPUDescriptorSet0 = driver->createGPUDescriptorSet(std::move(ds0Layout));
245248
outputGPUDescriptorSet1 = driver->createGPUDescriptorSet(std::move(ds1Layout));
246249
{
247-
IGPUDescriptorSet::SWriteDescriptorSet w[6];
248-
w[0].arrayElement = w[1].arrayElement = w[2].arrayElement = w[3].arrayElement = w[4].arrayElement = w[5].arrayElement = 0u;
249-
w[0].count = w[1].count = w[2].count = w[3].count = w[4].count = w[5].count = 1u;
250-
w[0].binding = 0u; w[1].binding = 1u; w[2].binding = 2u; w[3].binding = 3u; w[4].binding = 4u; w[5].binding = 4u;
251-
w[0].descriptorType = w[1].descriptorType = w[2].descriptorType = EDT_UNIFORM_TEXEL_BUFFER;
252-
w[3].descriptorType = w[4].descriptorType = w[5].descriptorType = EDT_STORAGE_BUFFER;
250+
IGPUDescriptorSet::SWriteDescriptorSet w[5];
251+
w[0].arrayElement = 0u;
252+
w[1].arrayElement = 1u;
253+
w[2].arrayElement = 0u;
254+
w[3].arrayElement = 0u;
255+
w[4].arrayElement = 0u;
256+
w[0].count = w[1].count = w[2].count = w[3].count = w[4].count = 1u;
257+
w[0].binding = 0u; w[1].binding = 0u; w[2].binding = 1u; w[3].binding = 2u; w[4].binding = 3u;
258+
w[0].descriptorType = w[1].descriptorType = w[2].descriptorType = w[3].descriptorType = EDT_UNIFORM_TEXEL_BUFFER;
259+
w[4].descriptorType = EDT_STORAGE_BUFFER;
253260
w[0].dstSet = w[1].dstSet = w[2].dstSet = w[3].dstSet = w[4].dstSet = w[5].dstSet = outputGPUDescriptorSet0.get();
254261

255-
IGPUDescriptorSet::SDescriptorInfo info[6];
262+
IGPUDescriptorSet::SDescriptorInfo info[5];
256263

257264
info[0].buffer.offset = 0u;
258265
info[0].buffer.size = vtxBuffer->getSize();
259266
info[0].desc = driver->createGPUBufferView(vtxBuffer.get(), EF_R32G32B32_SFLOAT);
260267
info[1].buffer.offset = 0u;
261268
info[1].buffer.size = vtxBuffer->getSize();
262-
info[1].desc = driver->createGPUBufferView(vtxBuffer.get(), EF_R32G32_SFLOAT);
269+
info[1].desc = driver->createGPUBufferView(vtxBuffer.get(), EF_R32G32B32_SFLOAT);
263270
info[2].buffer.offset = 0u;
264271
info[2].buffer.size = vtxBuffer->getSize();
265-
info[2].desc = driver->createGPUBufferView(vtxBuffer.get(), EF_R32_UINT);
272+
info[2].desc = driver->createGPUBufferView(vtxBuffer.get(), EF_R32G32_SFLOAT);
273+
info[3].buffer.offset = 0u;
274+
info[3].buffer.size = vtxBuffer->getSize();
275+
info[3].desc = driver->createGPUBufferView(vtxBuffer.get(), EF_R32_UINT);
266276

267277
//sampler buffers
268278
w[0].info = &info[0];
269279
w[1].info = &info[1];
270280
w[2].info = &info[2];
271-
272-
//offset tables
273-
info[3].buffer.offset = dataOffsetBuffers[0].offsetBuffer.offset;
274-
info[3].buffer.size = dataOffsetBuffers[0].offsetBuffer.buffer->getSize();
275-
info[3].desc = core::smart_refctd_ptr(dataOffsetBuffers[0].offsetBuffer.buffer);
276281
w[3].info = &info[3];
277282

278-
info[4].buffer.offset = dataOffsetBuffers[1].offsetBuffer.offset;
279-
info[4].buffer.size = dataOffsetBuffers[1].offsetBuffer.buffer->getSize();
280-
info[4].desc = core::smart_refctd_ptr(dataOffsetBuffers[1].offsetBuffer.buffer);
283+
//offset tables
284+
info[4].buffer.offset = 0u;
285+
info[4].buffer.size = virtualAttribBuffer->getSize();
286+
info[4].desc = core::smart_refctd_ptr(virtualAttribBuffer);
281287
w[4].info = &info[4];
282288

283-
info[5].buffer.offset = dataOffsetBuffers[2].offsetBuffer.offset;
284-
info[5].buffer.size = dataOffsetBuffers[2].offsetBuffer.buffer->getSize();
285-
info[5].desc = core::smart_refctd_ptr(dataOffsetBuffers[2].offsetBuffer.buffer);
286-
w[5].info = &info[5];
287-
288-
driver->updateDescriptorSets(6u, w, 0u, nullptr);
289+
driver->updateDescriptorSets(5u, w, 0u, nullptr);
289290

290291
IGPUDescriptorSet::SWriteDescriptorSet w2;
291292
w2.arrayElement = 0u;
@@ -381,11 +382,11 @@ int main()
381382
auto* vtxShader = pipeline->getShaderAtIndex(asset::ICPURenderpassIndependentPipeline::ESSI_VERTEX_SHADER_IX);
382383
core::smart_refctd_ptr<ICPUSpecializedShader> vs = createModifiedVertexShader(vtxShader);
383384
ICPUSpecializedShader* fs = IAsset::castDown<ICPUSpecializedShader>(am->getAsset("../shader.frag", lp).getContents().begin()->get());
384-
std::array<DataOffsetTable, 3> offsetTable;
385+
core::smart_refctd_ptr<IGPUBuffer> virtualAttribTable;
385386

386-
packMeshBuffers(driver, meshBuffers, mdiCallParams, offsetTable);
387+
packMeshBuffers(driver, meshBuffers, mdiCallParams, virtualAttribTable);
387388

388-
setPipeline(driver, vs.get(), fs, mdiCallParams.vtxBuffer.buffer, ubo, offsetTable, ds0, ds1, gpuPipeline);
389+
setPipeline(driver, vs.get(), fs, mdiCallParams.vtxBuffer.buffer, ubo, virtualAttribTable, ds0, ds1, gpuPipeline);
389390
}
390391

391392
//! we want to move around the scene and view it from different angles

include/nbl/asset/CCPUMeshPackerV2.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,21 @@ bool CCPUMeshPackerV2<MDIStructType>::commit(IMeshPackerBase::PackedMeshBufferDa
8282
if (ramb.attribAllocParams[location].offset == INVALID_ADDRESS)
8383
return false;
8484

85+
const E_FORMAT attribFormat = static_cast<E_FORMAT>(mbVtxInputParams.attributes[location].format);
8586
//should I cashe it?
86-
const uint32_t attribSize = asset::getTexelOrBlockBytesize(static_cast<E_FORMAT>(mbVtxInputParams.attributes[location].format));
87+
const uint32_t attribSize = asset::getTexelOrBlockBytesize(attribFormat);
8788
const uint32_t currBatchOffset = verticesAddedCnt * attribSize;
8889

8990
uint8_t* dstAttrPtr = static_cast<uint8_t*>(m_packerDataStore.vertexBuffer->getPointer()) + ramb.attribAllocParams[location].offset + currBatchOffset;
9091
deinterleaveAndCopyAttribute(*it, location, usedVertices, dstAttrPtr);
9192

92-
cdotOut->attribOffset[location] = ramb.attribAllocParams[location].offset / attribSize + verticesAddedCnt;
93+
auto vtxFormatInfo = virtualAttribConfig.map.find(attribFormat);
94+
95+
if (vtxFormatInfo == virtualAttribConfig.map.end())
96+
return false;
97+
98+
cdotOut->attribInfo[location].arrayElement = vtxFormatInfo->second.second;
99+
cdotOut->attribInfo[location].offset = ramb.attribAllocParams[location].offset / attribSize + verticesAddedCnt;
93100
}
94101

95102
verticesAddedCnt += usedVertices.size();

0 commit comments

Comments
 (0)