23
23
#define _IRR_VT_PAGE_TABLE_BINDING 0
24
24
25
25
#define _IRR_VT_FLOAT_VIEWS_BINDING 1
26
- #define _IRR_VT_FLOAT_VIEWS_COUNT 3
26
+ #define _IRR_VT_FLOAT_VIEWS_COUNT %u
27
27
#define _IRR_VT_FLOAT_VIEWS
28
28
29
29
#define _IRR_VT_INT_VIEWS_BINDING 2
@@ -110,18 +110,25 @@ layout (push_constant) uniform Block {
110
110
111
111
using STextureData = asset::ICPUVirtualTexture::SMasterTextureData;
112
112
113
- constexpr uint32_t PGTAB_LAYERS = 64u ;
114
113
constexpr uint32_t PAGE_SZ_LOG2 = 7u ;
115
114
constexpr uint32_t TILES_PER_DIM_LOG2 = 4u ;
116
- constexpr uint32_t PHYS_ADDR_TEX_LAYERS = 20u ;
117
115
constexpr uint32_t PAGE_PADDING = 8u ;
118
116
constexpr uint32_t MAX_ALLOCATABLE_TEX_SZ_LOG2 = 12u ; // 4096
119
117
120
118
constexpr uint32_t VT_SET = 0u ;
121
119
constexpr uint32_t PGTAB_BINDING = 0u ;
122
120
constexpr uint32_t PHYSICAL_STORAGE_VIEWS_BINDING = 1u ;
123
121
124
- STextureData getTextureData (const asset::ICPUImage* _img, asset::ICPUVirtualTexture* _vt, asset::ISampler::E_TEXTURE_CLAMP _uwrap, asset::ISampler::E_TEXTURE_CLAMP _vwrap, asset::ISampler::E_TEXTURE_BORDER_COLOR _borderColor)
122
+ struct commit_t
123
+ {
124
+ STextureData addr;
125
+ core::smart_refctd_ptr<asset::ICPUImage> texture;
126
+ asset::ICPUImage::SSubresourceRange subresource;
127
+ asset::ICPUSampler::E_TEXTURE_CLAMP uwrap;
128
+ asset::ICPUSampler::E_TEXTURE_CLAMP vwrap;
129
+ asset::ICPUSampler::E_TEXTURE_BORDER_COLOR border;
130
+ };
131
+ STextureData getTextureData (core::vector<commit_t >& _out_commits, const asset::ICPUImage* _img, asset::ICPUVirtualTexture* _vt, asset::ISampler::E_TEXTURE_CLAMP _uwrap, asset::ISampler::E_TEXTURE_CLAMP _vwrap, asset::ISampler::E_TEXTURE_BORDER_COLOR _borderColor)
125
132
{
126
133
const auto & extent = _img->getCreationParameters ().extent ;
127
134
@@ -134,7 +141,10 @@ STextureData getTextureData(const asset::ICPUImage* _img, asset::ICPUVirtualText
134
141
subres.layerCount = 1u ;
135
142
136
143
auto addr = _vt->alloc (_img->getCreationParameters ().format , imgAndOrigSz.second , subres, _uwrap, _vwrap);
137
- _vt->commit (addr, imgAndOrigSz.first .get (), subres, _uwrap, _vwrap, _borderColor);
144
+ commit_t cm{ addr, std::move (imgAndOrigSz.first ), subres, _uwrap, _vwrap, _borderColor };
145
+
146
+ _out_commits.push_back (cm);
147
+
138
148
return addr;
139
149
}
140
150
@@ -181,7 +191,7 @@ core::smart_refctd_ptr<asset::ICPUSpecializedShader> createModifiedFragShader(co
181
191
std::string glsl (begin,end);
182
192
183
193
std::string prelude (strlen (SHADER_OVERRIDES)+500u ,' \0 ' );
184
- sprintf (prelude.data (), SHADER_OVERRIDES, _vt->getGLSLFunctionsIncludePath ().c_str ());
194
+ sprintf (prelude.data (), SHADER_OVERRIDES, _vt->getFloatViews (). size (), _vt-> getGLSLFunctionsIncludePath ().c_str ());
185
195
prelude.resize (strlen (prelude.c_str ()));
186
196
187
197
size_t firstNewlineAfterVersion = glsl.find (" \n " ,glsl.find (" #version " ));
@@ -267,74 +277,20 @@ int main()
267
277
auto * smgr = device->getSceneManager ();
268
278
auto * am = device->getAssetManager ();
269
279
270
- constexpr uint32_t VT_COUNT = 3u ;
271
-
272
- core::smart_refctd_ptr<asset::ICPUVirtualTexture> vt;
273
- {
274
- std::array<asset::ICPUVirtualTexture::ICPUVTResidentStorage::SCreationParams,VT_COUNT> storage;
275
- storage[0 ].formatClass = asset::EFC_8_BIT;
276
- storage[0 ].layerCount = PHYS_ADDR_TEX_LAYERS;
277
- storage[0 ].tilesPerDim_log2 = TILES_PER_DIM_LOG2;
278
- storage[0 ].formatCount = 1u ;
279
- asset::E_FORMAT fmt1[1 ]{ asset::EF_R8_UNORM };
280
- storage[0 ].formats = fmt1;
281
- storage[1 ].formatClass = asset::EFC_24_BIT;
282
- storage[1 ].layerCount = PHYS_ADDR_TEX_LAYERS;
283
- storage[1 ].tilesPerDim_log2 = TILES_PER_DIM_LOG2;
284
- storage[1 ].formatCount = 1u ;
285
- asset::E_FORMAT fmt2[1 ]{ asset::EF_R8G8B8_SRGB };
286
- storage[1 ].formats = fmt2;
287
- storage[2 ].formatClass = asset::EFC_32_BIT;
288
- storage[2 ].layerCount = PHYS_ADDR_TEX_LAYERS;
289
- storage[2 ].tilesPerDim_log2 = TILES_PER_DIM_LOG2;
290
- storage[2 ].formatCount = 1u ;
291
- asset::E_FORMAT fmt3[1 ]{ asset::EF_R8G8B8A8_SRGB };
292
- storage[2 ].formats = fmt3;
293
-
294
- vt = core::make_smart_refctd_ptr<asset::ICPUVirtualTexture>(storage.data (), storage.size (), PAGE_SZ_LOG2, PGTAB_LAYERS, PAGE_PADDING, MAX_ALLOCATABLE_TEX_SZ_LOG2);
295
- }
280
+ core::smart_refctd_ptr<asset::ICPUVirtualTexture> vt = core::make_smart_refctd_ptr<asset::ICPUVirtualTexture>([](asset::E_FORMAT_CLASS) -> uint32_t { return TILES_PER_DIM_LOG2; }, PAGE_SZ_LOG2, PAGE_PADDING, MAX_ALLOCATABLE_TEX_SZ_LOG2);
296
281
297
282
core::unordered_map<core::smart_refctd_ptr<asset::ICPUImage>, STextureData> VTtexDataMap;
298
283
core::unordered_map<core::smart_refctd_ptr<asset::ICPUSpecializedShader>, core::smart_refctd_ptr<asset::ICPUSpecializedShader>> modifiedShaders;
299
284
300
- core::smart_refctd_ptr<asset::ICPUDescriptorSetLayout> ds0layout;
301
- {
302
- auto sizes = vt->getDSlayoutBindings (nullptr , nullptr );
303
- auto bindings = core::make_refctd_dynamic_array<core::smart_refctd_dynamic_array<asset::ICPUDescriptorSetLayout::SBinding>>(sizes.first );
304
- auto samplers = core::make_refctd_dynamic_array< core::smart_refctd_dynamic_array<core::smart_refctd_ptr<asset::ICPUSampler>>>(sizes.second );
305
-
306
- vt->getDSlayoutBindings (bindings->data (), samplers->data (), PGTAB_BINDING, PHYSICAL_STORAGE_VIEWS_BINDING);
307
-
308
- ds0layout = core::make_smart_refctd_ptr<asset::ICPUDescriptorSetLayout>(bindings->data (), bindings->data ()+bindings->size ());
309
- }
310
- core::smart_refctd_ptr<asset::ICPUDescriptorSetLayout> ds2layout;
311
- {
312
- std::array<asset::ICPUDescriptorSetLayout::SBinding,1 > bnd;
313
- bnd[0 ].binding = 0u ;
314
- bnd[0 ].count = 1u ;
315
- bnd[0 ].samplers = nullptr ;
316
- bnd[0 ].stageFlags = asset::ISpecializedShader::ESS_FRAGMENT;
317
- bnd[0 ].type = asset::EDT_STORAGE_BUFFER;
318
- ds2layout = core::make_smart_refctd_ptr<asset::ICPUDescriptorSetLayout>(bnd.data (),bnd.data ()+bnd.size ());
319
- }
320
-
321
- core::smart_refctd_ptr<asset::ICPUPipelineLayout> pipelineLayout;
322
- {
323
- asset::SPushConstantRange pcrng;
324
- pcrng.offset = 0 ;
325
- pcrng.size = 128 ;
326
- pcrng.stageFlags = asset::ISpecializedShader::ESS_FRAGMENT;
327
-
328
- pipelineLayout = core::make_smart_refctd_ptr<asset::ICPUPipelineLayout>(&pcrng, &pcrng+1 , core::smart_refctd_ptr (ds0layout), nullptr , core::smart_refctd_ptr (ds2layout), nullptr );
329
- }
330
-
331
285
device->getFileSystem ()->addFileArchive (" ../../media/sponza.zip" );
332
286
333
287
asset::IAssetLoader::SAssetLoadParams lp;
334
288
auto meshes_bundle = am->getAsset (" sponza.obj" , lp);
335
289
assert (!meshes_bundle.isEmpty ());
336
290
auto mesh = meshes_bundle.getContents ().begin ()[0 ];
337
291
auto mesh_raw = static_cast <asset::ICPUMesh*>(mesh.get ());
292
+
293
+ core::vector<commit_t > vt_commits;
338
294
// modifying push constants and default fragment shader for VT
339
295
for (uint32_t i = 0u ; i < mesh_raw->getMeshBufferCount (); ++i)
340
296
{
@@ -365,13 +321,68 @@ int main()
365
321
texData = found->second ;
366
322
else {
367
323
const asset::E_FORMAT fmt = img->getCreationParameters ().format ;
368
- texData = getTextureData (img.get (), vt.get (), uwrap, vwrap, borderColor);
324
+ texData = getTextureData (vt_commits, img.get (), vt.get (), uwrap, vwrap, borderColor);
369
325
VTtexDataMap.insert ({img,texData});
370
326
}
371
327
372
328
static_assert (sizeof (texData)==sizeof (pushConsts.map_data [0 ]), " wrong reinterpret_cast" );
373
329
pushConsts.map_data [k] = reinterpret_cast <uint64_t *>(&texData)[0 ];
374
330
}
331
+
332
+ auto * pipeline = mb->getPipeline ();
333
+ auto * metadata = static_cast <asset::CMTLPipelineMetadata*>( pipeline->getMetadata () );
334
+
335
+ // copy texture presence flags
336
+ pushConsts.extra = metadata->getMaterialParams ().extra ;
337
+ pushConsts.ambient = metadata->getMaterialParams ().ambient ;
338
+ pushConsts.diffuse = metadata->getMaterialParams ().diffuse ;
339
+ pushConsts.emissive = metadata->getMaterialParams ().emissive ;
340
+ pushConsts.specular = metadata->getMaterialParams ().specular ;
341
+ pushConsts.IoR = metadata->getMaterialParams ().IoR ;
342
+ pushConsts.opacity = metadata->getMaterialParams ().opacity ;
343
+ pushConsts.shininess = metadata->getMaterialParams ().shininess ;
344
+ memcpy (mb->getPushConstantsDataPtr (), &pushConsts, sizeof (pushConsts));
345
+
346
+ // we dont want this DS to be converted into GPU DS, so set to nullptr
347
+ // dont worry about deletion of textures (invalidation of pointers), they're grabbed in VTtexDataMap
348
+ mb->setAttachedDescriptorSet (nullptr );
349
+ }
350
+
351
+ core::smart_refctd_ptr<asset::ICPUDescriptorSetLayout> ds0layout;
352
+ {
353
+ auto sizes = vt->getDSlayoutBindings (nullptr , nullptr );
354
+ auto bindings = core::make_refctd_dynamic_array<core::smart_refctd_dynamic_array<asset::ICPUDescriptorSetLayout::SBinding>>(sizes.first );
355
+ auto samplers = core::make_refctd_dynamic_array< core::smart_refctd_dynamic_array<core::smart_refctd_ptr<asset::ICPUSampler>>>(sizes.second );
356
+
357
+ vt->getDSlayoutBindings (bindings->data (), samplers->data (), PGTAB_BINDING, PHYSICAL_STORAGE_VIEWS_BINDING);
358
+
359
+ ds0layout = core::make_smart_refctd_ptr<asset::ICPUDescriptorSetLayout>(bindings->data (), bindings->data () + bindings->size ());
360
+ }
361
+ core::smart_refctd_ptr<asset::ICPUDescriptorSetLayout> ds2layout;
362
+ {
363
+ std::array<asset::ICPUDescriptorSetLayout::SBinding, 1 > bnd;
364
+ bnd[0 ].binding = 0u ;
365
+ bnd[0 ].count = 1u ;
366
+ bnd[0 ].samplers = nullptr ;
367
+ bnd[0 ].stageFlags = asset::ISpecializedShader::ESS_FRAGMENT;
368
+ bnd[0 ].type = asset::EDT_STORAGE_BUFFER;
369
+ ds2layout = core::make_smart_refctd_ptr<asset::ICPUDescriptorSetLayout>(bnd.data (), bnd.data () + bnd.size ());
370
+ }
371
+
372
+ core::smart_refctd_ptr<asset::ICPUPipelineLayout> pipelineLayout;
373
+ {
374
+ asset::SPushConstantRange pcrng;
375
+ pcrng.offset = 0 ;
376
+ pcrng.size = 128 ;
377
+ pcrng.stageFlags = asset::ISpecializedShader::ESS_FRAGMENT;
378
+
379
+ pipelineLayout = core::make_smart_refctd_ptr<asset::ICPUPipelineLayout>(&pcrng, &pcrng + 1 , core::smart_refctd_ptr (ds0layout), nullptr , core::smart_refctd_ptr (ds2layout), nullptr );
380
+ }
381
+
382
+ for (uint32_t i = 0u ; i < mesh_raw->getMeshBufferCount (); ++i)
383
+ {
384
+ auto * mb = mesh_raw->getMeshBuffer (i);
385
+
375
386
auto * pipeline = mb->getPipeline ();
376
387
auto newPipeline = core::smart_refctd_ptr_static_cast<asset::ICPURenderpassIndependentPipeline>(pipeline->clone (0u ));// shallow copy
377
388
// leave original ds1 layout since it's for UBO with matrices
@@ -385,31 +396,22 @@ int main()
385
396
if (found != modifiedShaders.end ())
386
397
newfs = found->second ;
387
398
else {
388
- newfs = createModifiedFragShader (fs,vt.get ());
389
- modifiedShaders.insert ({core::smart_refctd_ptr<asset::ICPUSpecializedShader>(fs),newfs});
399
+ newfs = createModifiedFragShader (fs, vt.get ());
400
+ modifiedShaders.insert ({ core::smart_refctd_ptr<asset::ICPUSpecializedShader>(fs),newfs });
390
401
}
391
402
newPipeline->setShaderAtIndex (asset::ICPURenderpassIndependentPipeline::ESSI_FRAGMENT_SHADER_IX, newfs.get ());
392
403
}
393
- auto * metadata = static_cast <asset::CMTLPipelineMetadata*>( pipeline->getMetadata () );
404
+ auto * metadata = static_cast <asset::CMTLPipelineMetadata*>(pipeline->getMetadata ());
394
405
am->setAssetMetadata (newPipeline.get (), core::smart_refctd_ptr<asset::IAssetMetadata>(metadata));
395
- // copy texture presence flags
396
- pushConsts.extra = metadata->getMaterialParams ().extra ;
397
- pushConsts.ambient = metadata->getMaterialParams ().ambient ;
398
- pushConsts.diffuse = metadata->getMaterialParams ().diffuse ;
399
- pushConsts.emissive = metadata->getMaterialParams ().emissive ;
400
- pushConsts.specular = metadata->getMaterialParams ().specular ;
401
- pushConsts.IoR = metadata->getMaterialParams ().IoR ;
402
- pushConsts.opacity = metadata->getMaterialParams ().opacity ;
403
- pushConsts.shininess = metadata->getMaterialParams ().shininess ;
404
- memcpy (mb->getPushConstantsDataPtr (), &pushConsts, sizeof (pushConsts));
405
-
406
- // we dont want this DS to be converted into GPU DS, so set to nullptr
407
- // dont worry about deletion of textures (invalidation of pointers), they're grabbed in VTtexDataMap
408
- mb->setAttachedDescriptorSet (nullptr );
409
406
410
407
// set new pipeline (with overriden FS and layout)
411
408
mb->setPipeline (std::move (newPipeline));
412
- // optionally adjust push constant ranges, but at worst it'll just be specified too much because MTL uses all 128 bytes
409
+ }
410
+
411
+ vt->shrink ();
412
+ for (const auto & cm : vt_commits)
413
+ {
414
+ vt->commit (cm.addr , cm.texture .get (), cm.subresource , cm.uwrap , cm.vwrap , cm.border );
413
415
}
414
416
415
417
auto gpuvt = core::make_smart_refctd_ptr<video::IGPUVirtualTexture>(driver, vt.get ());
0 commit comments