|
@@ -16,10 +16,7 @@ class ImageResource::LoadingContext
|
|
|
{
|
|
{
|
|
|
public:
|
|
public:
|
|
|
ImageLoader m_loader{&ResourceMemoryPool::getSingleton()};
|
|
ImageLoader m_loader{&ResourceMemoryPool::getSingleton()};
|
|
|
- U32 m_faces = 0;
|
|
|
|
|
- U32 m_layerCount = 0;
|
|
|
|
|
- TextureType m_texType;
|
|
|
|
|
- TexturePtr m_tex;
|
|
|
|
|
|
|
+ ImageResourcePtr m_image;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
/// Image upload async task.
|
|
/// Image upload async task.
|
|
@@ -30,7 +27,12 @@ public:
|
|
|
|
|
|
|
|
Error operator()([[maybe_unused]] AsyncLoaderTaskContext& ctx) final
|
|
Error operator()([[maybe_unused]] AsyncLoaderTaskContext& ctx) final
|
|
|
{
|
|
{
|
|
|
- return ImageResource::load(m_ctx);
|
|
|
|
|
|
|
+ return m_ctx.m_image->loadAsync(m_ctx);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ static BaseMemoryPool& getMemoryPool()
|
|
|
|
|
+ {
|
|
|
|
|
+ return ResourceMemoryPool::getSingleton();
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -40,18 +42,18 @@ ImageResource::~ImageResource()
|
|
|
|
|
|
|
|
Error ImageResource::load(const ResourceFilename& filename, Bool async)
|
|
Error ImageResource::load(const ResourceFilename& filename, Bool async)
|
|
|
{
|
|
{
|
|
|
- TexUploadTask* task;
|
|
|
|
|
|
|
+ UniquePtr<TexUploadTask> task;
|
|
|
LoadingContext* ctx;
|
|
LoadingContext* ctx;
|
|
|
LoadingContext localCtx;
|
|
LoadingContext localCtx;
|
|
|
|
|
|
|
|
if(async)
|
|
if(async)
|
|
|
{
|
|
{
|
|
|
- task = AsyncLoader::getSingleton().newTask<TexUploadTask>();
|
|
|
|
|
|
|
+ task.reset(AsyncLoader::getSingleton().newTask<TexUploadTask>());
|
|
|
ctx = &task->m_ctx;
|
|
ctx = &task->m_ctx;
|
|
|
|
|
+ ctx->m_image.reset(this);
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
|
- task = nullptr;
|
|
|
|
|
ctx = &localCtx;
|
|
ctx = &localCtx;
|
|
|
}
|
|
}
|
|
|
ImageLoader& loader = ctx->m_loader;
|
|
ImageLoader& loader = ctx->m_loader;
|
|
@@ -196,48 +198,25 @@ Error ImageResource::load(const ResourceFilename& filename, Bool async)
|
|
|
// Create the texture
|
|
// Create the texture
|
|
|
m_tex = GrManager::getSingleton().newTexture(init);
|
|
m_tex = GrManager::getSingleton().newTexture(init);
|
|
|
|
|
|
|
|
- // Transition it. TODO remove this
|
|
|
|
|
- {
|
|
|
|
|
- const TextureView view(m_tex.get(), TextureSubresourceDesc::all());
|
|
|
|
|
-
|
|
|
|
|
- CommandBufferInitInfo cmdbinit;
|
|
|
|
|
- cmdbinit.m_flags = CommandBufferFlag::kGeneralWork | CommandBufferFlag::kSmallBatch;
|
|
|
|
|
- CommandBufferPtr cmdb = GrManager::getSingleton().newCommandBuffer(cmdbinit);
|
|
|
|
|
-
|
|
|
|
|
- const TextureBarrierInfo barrier = {view, TextureUsageBit::kNone, TextureUsageBit::kAllSrv};
|
|
|
|
|
- cmdb->setPipelineBarrier({&barrier, 1}, {}, {});
|
|
|
|
|
-
|
|
|
|
|
- FencePtr outFence;
|
|
|
|
|
- cmdb->endRecording();
|
|
|
|
|
- GrManager::getSingleton().submit(cmdb.get(), {}, &outFence);
|
|
|
|
|
- outFence->clientWait(60.0_sec);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Set the context
|
|
|
|
|
- ctx->m_faces = faces;
|
|
|
|
|
- ctx->m_layerCount = init.m_layerCount;
|
|
|
|
|
- ctx->m_texType = init.m_type;
|
|
|
|
|
- ctx->m_tex = m_tex;
|
|
|
|
|
-
|
|
|
|
|
// Upload the data
|
|
// Upload the data
|
|
|
if(async)
|
|
if(async)
|
|
|
{
|
|
{
|
|
|
- AsyncLoader::getSingleton().submitTask(task);
|
|
|
|
|
|
|
+ TexUploadTask* pTask;
|
|
|
|
|
+ task.moveAndReset(pTask);
|
|
|
|
|
+ AsyncLoader::getSingleton().submitTask(pTask, AsyncLoaderPriority::kMedium);
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
|
- ANKI_CHECK(load(*ctx));
|
|
|
|
|
|
|
+ ANKI_CHECK(loadAsync(*ctx));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- m_size = UVec3(init.m_width, init.m_height, init.m_depth);
|
|
|
|
|
- m_layerCount = init.m_layerCount;
|
|
|
|
|
-
|
|
|
|
|
return Error::kNone;
|
|
return Error::kNone;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-Error ImageResource::load(LoadingContext& ctx)
|
|
|
|
|
|
|
+Error ImageResource::loadAsync(LoadingContext& ctx) const
|
|
|
{
|
|
{
|
|
|
- const U32 copyCount = ctx.m_layerCount * ctx.m_faces * ctx.m_loader.getMipmapCount();
|
|
|
|
|
|
|
+ const U32 faceCount = textureTypeIsCube(m_tex->getTextureType()) ? 6 : 1;
|
|
|
|
|
+ const U32 copyCount = m_tex->getLayerCount() * faceCount * ctx.m_loader.getMipmapCount();
|
|
|
|
|
|
|
|
for(U32 b = 0; b < copyCount; b += kMaxCopiesBeforeFlush)
|
|
for(U32 b = 0; b < copyCount; b += kMaxCopiesBeforeFlush)
|
|
|
{
|
|
{
|
|
@@ -254,9 +233,9 @@ Error ImageResource::load(LoadingContext& ctx)
|
|
|
for(U32 i = begin; i < end; ++i)
|
|
for(U32 i = begin; i < end; ++i)
|
|
|
{
|
|
{
|
|
|
U32 mip, layer, face;
|
|
U32 mip, layer, face;
|
|
|
- unflatten3dArrayIndex(ctx.m_layerCount, ctx.m_faces, ctx.m_loader.getMipmapCount(), i, layer, face, mip);
|
|
|
|
|
|
|
+ unflatten3dArrayIndex(m_tex->getLayerCount(), faceCount, ctx.m_loader.getMipmapCount(), i, layer, face, mip);
|
|
|
|
|
|
|
|
- barriers[barrierCount++] = {TextureView(ctx.m_tex.get(), TextureSubresourceDesc::surface(mip, face, layer)), TextureUsageBit::kAllSrv,
|
|
|
|
|
|
|
+ barriers[barrierCount++] = {TextureView(m_tex.get(), TextureSubresourceDesc::surface(mip, face, layer)), TextureUsageBit::kAllSrv,
|
|
|
TextureUsageBit::kCopyDestination};
|
|
TextureUsageBit::kCopyDestination};
|
|
|
}
|
|
}
|
|
|
cmdb->setPipelineBarrier({&barriers[0], barrierCount}, {}, {});
|
|
cmdb->setPipelineBarrier({&barriers[0], barrierCount}, {}, {});
|
|
@@ -267,20 +246,19 @@ Error ImageResource::load(LoadingContext& ctx)
|
|
|
for(U32 i = begin; i < end; ++i)
|
|
for(U32 i = begin; i < end; ++i)
|
|
|
{
|
|
{
|
|
|
U32 mip, layer, face;
|
|
U32 mip, layer, face;
|
|
|
- unflatten3dArrayIndex(ctx.m_layerCount, ctx.m_faces, ctx.m_loader.getMipmapCount(), i, layer, face, mip);
|
|
|
|
|
|
|
+ unflatten3dArrayIndex(m_tex->getLayerCount(), faceCount, ctx.m_loader.getMipmapCount(), i, layer, face, mip);
|
|
|
|
|
|
|
|
PtrSize surfOrVolSize;
|
|
PtrSize surfOrVolSize;
|
|
|
const void* surfOrVolData;
|
|
const void* surfOrVolData;
|
|
|
PtrSize allocationSize;
|
|
PtrSize allocationSize;
|
|
|
|
|
|
|
|
- if(ctx.m_texType == TextureType::k3D)
|
|
|
|
|
|
|
+ if(m_tex->getTextureType() == TextureType::k3D)
|
|
|
{
|
|
{
|
|
|
const auto& vol = ctx.m_loader.getVolume(mip);
|
|
const auto& vol = ctx.m_loader.getVolume(mip);
|
|
|
surfOrVolSize = vol.m_data.getSize();
|
|
surfOrVolSize = vol.m_data.getSize();
|
|
|
surfOrVolData = &vol.m_data[0];
|
|
surfOrVolData = &vol.m_data[0];
|
|
|
|
|
|
|
|
- allocationSize = computeVolumeSize(ctx.m_tex->getWidth() >> mip, ctx.m_tex->getHeight() >> mip, ctx.m_tex->getDepth() >> mip,
|
|
|
|
|
- ctx.m_tex->getFormat());
|
|
|
|
|
|
|
+ allocationSize = computeVolumeSize(m_tex->getWidth() >> mip, m_tex->getHeight() >> mip, m_tex->getDepth() >> mip, m_tex->getFormat());
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
@@ -288,7 +266,7 @@ Error ImageResource::load(LoadingContext& ctx)
|
|
|
surfOrVolSize = surf.m_data.getSize();
|
|
surfOrVolSize = surf.m_data.getSize();
|
|
|
surfOrVolData = &surf.m_data[0];
|
|
surfOrVolData = &surf.m_data[0];
|
|
|
|
|
|
|
|
- allocationSize = computeSurfaceSize(ctx.m_tex->getWidth() >> mip, ctx.m_tex->getHeight() >> mip, ctx.m_tex->getFormat());
|
|
|
|
|
|
|
+ allocationSize = computeSurfaceSize(m_tex->getWidth() >> mip, m_tex->getHeight() >> mip, m_tex->getFormat());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
ANKI_ASSERT(allocationSize >= surfOrVolSize);
|
|
ANKI_ASSERT(allocationSize >= surfOrVolSize);
|
|
@@ -301,7 +279,7 @@ Error ImageResource::load(LoadingContext& ctx)
|
|
|
|
|
|
|
|
// Create temp tex view
|
|
// Create temp tex view
|
|
|
const TextureSubresourceDesc subresource = TextureSubresourceDesc::surface(mip, face, layer);
|
|
const TextureSubresourceDesc subresource = TextureSubresourceDesc::surface(mip, face, layer);
|
|
|
- cmdb->copyBufferToTexture(handle, TextureView(ctx.m_tex.get(), subresource));
|
|
|
|
|
|
|
+ cmdb->copyBufferToTexture(handle, TextureView(m_tex.get(), subresource));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Set the barriers of the batch
|
|
// Set the barriers of the batch
|
|
@@ -309,9 +287,9 @@ Error ImageResource::load(LoadingContext& ctx)
|
|
|
for(U32 i = begin; i < end; ++i)
|
|
for(U32 i = begin; i < end; ++i)
|
|
|
{
|
|
{
|
|
|
U32 mip, layer, face;
|
|
U32 mip, layer, face;
|
|
|
- unflatten3dArrayIndex(ctx.m_layerCount, ctx.m_faces, ctx.m_loader.getMipmapCount(), i, layer, face, mip);
|
|
|
|
|
|
|
+ unflatten3dArrayIndex(m_tex->getLayerCount(), faceCount, ctx.m_loader.getMipmapCount(), i, layer, face, mip);
|
|
|
|
|
|
|
|
- barriers[barrierCount++] = {TextureView(ctx.m_tex.get(), TextureSubresourceDesc::surface(mip, face, layer)),
|
|
|
|
|
|
|
+ barriers[barrierCount++] = {TextureView(m_tex.get(), TextureSubresourceDesc::surface(mip, face, layer)),
|
|
|
TextureUsageBit::kCopyDestination, TextureUsageBit::kSrvPixel | TextureUsageBit::kSrvGeometry};
|
|
TextureUsageBit::kCopyDestination, TextureUsageBit::kSrvPixel | TextureUsageBit::kSrvGeometry};
|
|
|
}
|
|
}
|
|
|
cmdb->setPipelineBarrier({&barriers[0], barrierCount}, {}, {});
|
|
cmdb->setPipelineBarrier({&barriers[0], barrierCount}, {}, {});
|
|
@@ -328,6 +306,7 @@ Error ImageResource::load(LoadingContext& ctx)
|
|
|
cmdb.reset(nullptr);
|
|
cmdb.reset(nullptr);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ m_loadedMipCount.store(m_tex->getMipmapCount());
|
|
|
return Error::kNone;
|
|
return Error::kNone;
|
|
|
}
|
|
}
|
|
|
|
|
|