Skip to content

Commit b7dbba8

Browse files
Merge pull request #554 from Crisspl/mitsuba
Material Compiler Merge necessary for Simple Raytracer
2 parents 05b893b + 8bc1b66 commit b7dbba8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+4878
-3301
lines changed

examples_tests/18.MitsubaLoader/main.cpp

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ layout(set = 2, binding = 1) uniform sampler2D envMap;
3535
layout(set = 2, binding = 2) uniform usamplerBuffer sampleSequence;
3636
layout(set = 2, binding = 3) uniform usampler2D scramblebuf;
3737
38-
vec2 rand2d(in uint _sample, inout irr_glsl_xoroshiro64star_state_t scramble_state)
38+
vec3 rand3d(in uint _sample, inout irr_glsl_xoroshiro64star_state_t scramble_state)
3939
{
40-
uvec2 seqVal = texelFetch(sampleSequence,int(_sample)).xy;
41-
seqVal ^= uvec2(irr_glsl_xoroshiro64star(scramble_state),irr_glsl_xoroshiro64star(scramble_state));
42-
return vec2(seqVal)*uintBitsToFloat(0x2f800004u);
40+
uvec3 seqVal = texelFetch(sampleSequence,int(_sample)).xyz;
41+
seqVal ^= uvec3(irr_glsl_xoroshiro64star(scramble_state),irr_glsl_xoroshiro64star(scramble_state),irr_glsl_xoroshiro64star(scramble_state));
42+
return vec3(seqVal)*uintBitsToFloat(0x2f800004u);
4343
}
4444
4545
vec2 SampleSphericalMap(in vec3 v)
@@ -50,7 +50,7 @@ vec2 SampleSphericalMap(in vec3 v)
5050
return uv;
5151
}
5252
53-
vec3 irr_computeLighting(inout irr_glsl_IsotropicViewSurfaceInteraction out_interaction, in mat2 dUV)
53+
vec3 irr_computeLighting(inout irr_glsl_IsotropicViewSurfaceInteraction out_interaction, in mat2 dUV, in MC_precomputed_t precomp)
5454
{
5555
irr_glsl_xoroshiro64star_state_t scramble_start_state = textureLod(scramblebuf,gl_FragCoord.xy/VIEWPORT_SZ,0).rg;
5656
@@ -59,32 +59,30 @@ vec3 irr_computeLighting(inout irr_glsl_IsotropicViewSurfaceInteraction out_inte
5959
vec3 color = vec3(0.0);
6060
6161
#ifdef USE_ENVMAP
62-
instr_stream_t gcs = getGenChoiceStream();
62+
instr_stream_t gcs = getGenChoiceStream(precomp);
63+
instr_stream_t rnps = getRemAndPdfStream(precomp);
6364
for (int i = 0; i < SAMPLE_COUNT; ++i)
6465
{
6566
irr_glsl_xoroshiro64star_state_t scramble_state = scramble_start_state;
6667
67-
instr_stream_t gcs = getGenChoiceStream();
68-
instr_stream_t rnps = getRemAndPdfStream();
69-
70-
vec2 rand = rand2d(i,scramble_state);//TODO has to be 3d
68+
vec3 rand = rand3d(i,scramble_state);
7169
float pdf;
72-
runGenerateAndRemainderStream(gcs, rnps, rand, pdf);
70+
irr_glsl_LightSample s;
71+
vec3 rem = runGenerateAndRemainderStream(precomp, gcs, rnps, rand, pdf, s);
7372
74-
vec2 uv = SampleSphericalMap(L);
73+
vec2 uv = SampleSphericalMap(s.L);
7574
color += rem*textureLod(envMap, uv, 0.0).xyz;
7675
}
7776
color /= float(SAMPLE_COUNT);
7877
#endif
7978
80-
irr_glsl_BSDFIsotropicParams params;
8179
for (int i = 0; i < LIGHT_COUNT; ++i)
8280
{
8381
SLight l = lights[i];
8482
vec3 L = l.position-WorldPos;
85-
params.L = L;
83+
//params.L = L;
8684
const float intensityScale = LIGHT_INTENSITY_SCALE;//ehh might want to render to hdr fbo and do tonemapping
87-
color += irr_bsdf_cos_eval(params, out_interaction, dUV)*l.intensity*intensityScale / dot(L,L);
85+
color += irr_bsdf_cos_eval(precomp, normalize(L), out_interaction, dUV)*l.intensity*intensityScale / dot(L,L);
8886
}
8987
9088
return color+emissive;
@@ -344,7 +342,7 @@ int main()
344342
meshmetas.push_back(static_cast<const ext::MitsubaLoader::IMeshMetadata*>(cpumesh->getMetadata()));
345343
const auto& instances = meshmetas.back()->getInstances();
346344

347-
auto computeAreaAndAvgPos = [](asset::ICPUMeshBuffer* mb, const core::matrix3x4SIMD& tform, core::vectorSIMDf& _outAvgPos) {
345+
auto computeAreaAndAvgPos = [](const asset::ICPUMeshBuffer* mb, const core::matrix3x4SIMD& tform, core::vectorSIMDf& _outAvgPos) {
348346
uint32_t triCount = 0u;
349347
asset::IMeshManipulator::getPolyCount(triCount, mb);
350348
assert(triCount>0u);
@@ -440,18 +438,8 @@ int main()
440438
}
441439
}
442440

443-
auto gpuVT = core::make_smart_refctd_ptr<video::IGPUVirtualTexture>(driver, globalMeta->VT.get());
441+
//auto gpuVT = core::make_smart_refctd_ptr<video::IGPUVirtualTexture>(driver, globalMeta->VT.get());
444442
auto gpuds0 = driver->getGPUObjectsFromAssets(&cpuds0.get(), &cpuds0.get()+1)->front();
445-
{
446-
auto count = gpuVT->getDescriptorSetWrites(nullptr, nullptr, nullptr);
447-
448-
auto writes = core::make_refctd_dynamic_array<core::smart_refctd_dynamic_array<video::IGPUDescriptorSet::SWriteDescriptorSet>>(count.first);
449-
auto info = core::make_refctd_dynamic_array<core::smart_refctd_dynamic_array<video::IGPUDescriptorSet::SDescriptorInfo>>(count.second);
450-
451-
gpuVT->getDescriptorSetWrites(writes->data(), info->data(), gpuds0.get());
452-
453-
driver->updateDescriptorSets(writes->size(), writes->data(), 0u, nullptr);
454-
}
455443

456444
auto gpuds1layout = driver->getGPUObjectsFromAssets(&ds1layout, &ds1layout+1)->front();
457445

@@ -477,18 +465,20 @@ int main()
477465
smart_refctd_ptr<video::IGPUBufferView> gpuSequenceBufferView;
478466
{
479467
constexpr uint32_t MaxSamples = ENVMAP_SAMPLE_COUNT;
468+
constexpr uint32_t Channels = 3u;
480469

481-
auto sampleSequence = core::make_smart_refctd_ptr<asset::ICPUBuffer>(sizeof(uint32_t) * MaxSamples*2u);
470+
auto sampleSequence = core::make_smart_refctd_ptr<asset::ICPUBuffer>(sizeof(uint32_t) * MaxSamples*Channels);
482471

483-
core::OwenSampler sampler(1u, 0xdeadbeefu);
472+
core::OwenSampler sampler(Channels, 0xdeadbeefu);
484473

485474
auto out = reinterpret_cast<uint32_t*>(sampleSequence->getPointer());
486-
for (uint32_t i = 0; i < MaxSamples*2u; i++)
475+
for (uint32_t c = 0; c < Channels; ++c)
476+
for (uint32_t i = 0; i < MaxSamples; i++)
487477
{
488-
out[i] = sampler.sample(i&1u, i>>1);
478+
out[Channels*i + c] = sampler.sample(c, i);
489479
}
490480
auto gpuSequenceBuffer = driver->createFilledDeviceLocalGPUBufferOnDedMem(sampleSequence->getSize(), sampleSequence->getPointer());
491-
gpuSequenceBufferView = driver->createGPUBufferView(gpuSequenceBuffer.get(), asset::EF_R32G32_UINT);
481+
gpuSequenceBufferView = driver->createGPUBufferView(gpuSequenceBuffer.get(), asset::EF_R32G32B32_UINT);
492482
}
493483

494484
smart_refctd_ptr<video::IGPUImageView> gpuScrambleImageView;

examples_tests/20.Megatexture/main.cpp

Lines changed: 84 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ R"(
2323
#define _IRR_VT_PAGE_TABLE_BINDING 0
2424
2525
#define _IRR_VT_FLOAT_VIEWS_BINDING 1
26-
#define _IRR_VT_FLOAT_VIEWS_COUNT 3
26+
#define _IRR_VT_FLOAT_VIEWS_COUNT %u
2727
#define _IRR_VT_FLOAT_VIEWS
2828
2929
#define _IRR_VT_INT_VIEWS_BINDING 2
@@ -110,18 +110,25 @@ layout (push_constant) uniform Block {
110110

111111
using STextureData = asset::ICPUVirtualTexture::SMasterTextureData;
112112

113-
constexpr uint32_t PGTAB_LAYERS = 64u;
114113
constexpr uint32_t PAGE_SZ_LOG2 = 7u;
115114
constexpr uint32_t TILES_PER_DIM_LOG2 = 4u;
116-
constexpr uint32_t PHYS_ADDR_TEX_LAYERS = 20u;
117115
constexpr uint32_t PAGE_PADDING = 8u;
118116
constexpr uint32_t MAX_ALLOCATABLE_TEX_SZ_LOG2 = 12u; //4096
119117

120118
constexpr uint32_t VT_SET = 0u;
121119
constexpr uint32_t PGTAB_BINDING = 0u;
122120
constexpr uint32_t PHYSICAL_STORAGE_VIEWS_BINDING = 1u;
123121

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)
125132
{
126133
const auto& extent = _img->getCreationParameters().extent;
127134

@@ -134,7 +141,10 @@ STextureData getTextureData(const asset::ICPUImage* _img, asset::ICPUVirtualText
134141
subres.layerCount = 1u;
135142

136143
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+
138148
return addr;
139149
}
140150

@@ -181,7 +191,7 @@ core::smart_refctd_ptr<asset::ICPUSpecializedShader> createModifiedFragShader(co
181191
std::string glsl(begin,end);
182192

183193
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());
185195
prelude.resize(strlen(prelude.c_str()));
186196

187197
size_t firstNewlineAfterVersion = glsl.find("\n",glsl.find("#version "));
@@ -267,74 +277,20 @@ int main()
267277
auto* smgr = device->getSceneManager();
268278
auto* am = device->getAssetManager();
269279

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);
296281

297282
core::unordered_map<core::smart_refctd_ptr<asset::ICPUImage>, STextureData> VTtexDataMap;
298283
core::unordered_map<core::smart_refctd_ptr<asset::ICPUSpecializedShader>, core::smart_refctd_ptr<asset::ICPUSpecializedShader>> modifiedShaders;
299284

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-
331285
device->getFileSystem()->addFileArchive("../../media/sponza.zip");
332286

333287
asset::IAssetLoader::SAssetLoadParams lp;
334288
auto meshes_bundle = am->getAsset("sponza.obj", lp);
335289
assert(!meshes_bundle.isEmpty());
336290
auto mesh = meshes_bundle.getContents().begin()[0];
337291
auto mesh_raw = static_cast<asset::ICPUMesh*>(mesh.get());
292+
293+
core::vector<commit_t> vt_commits;
338294
//modifying push constants and default fragment shader for VT
339295
for (uint32_t i = 0u; i < mesh_raw->getMeshBufferCount(); ++i)
340296
{
@@ -365,13 +321,68 @@ int main()
365321
texData = found->second;
366322
else {
367323
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);
369325
VTtexDataMap.insert({img,texData});
370326
}
371327

372328
static_assert(sizeof(texData)==sizeof(pushConsts.map_data[0]), "wrong reinterpret_cast");
373329
pushConsts.map_data[k] = reinterpret_cast<uint64_t*>(&texData)[0];
374330
}
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+
375386
auto* pipeline = mb->getPipeline();
376387
auto newPipeline = core::smart_refctd_ptr_static_cast<asset::ICPURenderpassIndependentPipeline>(pipeline->clone(0u));//shallow copy
377388
//leave original ds1 layout since it's for UBO with matrices
@@ -385,31 +396,22 @@ int main()
385396
if (found != modifiedShaders.end())
386397
newfs = found->second;
387398
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 });
390401
}
391402
newPipeline->setShaderAtIndex(asset::ICPURenderpassIndependentPipeline::ESSI_FRAGMENT_SHADER_IX, newfs.get());
392403
}
393-
auto* metadata = static_cast<asset::CMTLPipelineMetadata*>( pipeline->getMetadata() );
404+
auto* metadata = static_cast<asset::CMTLPipelineMetadata*>(pipeline->getMetadata());
394405
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);
409406

410407
//set new pipeline (with overriden FS and layout)
411408
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);
413415
}
414416

415417
auto gpuvt = core::make_smart_refctd_ptr<video::IGPUVirtualTexture>(driver, vt.get());

0 commit comments

Comments
 (0)