wg_engine: animation optimizations (part 1)

[issues 1479: update](#1479)

gpu vertex buffer reallocations optimization
This commit is contained in:
Sergii Liebodkin 2024-02-14 15:08:28 +02:00 committed by Hermet Park
parent 11ddfdb193
commit 21b1ef6f5f
3 changed files with 60 additions and 44 deletions

View file

@ -158,7 +158,7 @@ WGPUTexture WgContext::createTexture2d(WGPUTextureUsageFlags usage, WGPUTextureF
} }
WGPUTextureView WgContext::createTextureView2d(WGPUTexture texture, WGPU_NULLABLE char const * label) WGPUTextureView WgContext::createTextureView2d(WGPUTexture texture, char const * label)
{ {
WGPUTextureViewDescriptor textureViewDescColor{}; WGPUTextureViewDescriptor textureViewDescColor{};
textureViewDescColor.nextInChain = nullptr; textureViewDescColor.nextInChain = nullptr;
@ -174,6 +174,18 @@ WGPUTextureView WgContext::createTextureView2d(WGPUTexture texture, WGPU_NULLABL
}; };
WGPUBuffer WgContext::createBuffer(WGPUBufferUsageFlags usage, uint64_t size,char const * label)
{
WGPUBufferDescriptor bufferDesc{};
bufferDesc.nextInChain = nullptr;
bufferDesc.label = label;
bufferDesc.usage = usage;
bufferDesc.size = size;
bufferDesc.mappedAtCreation = false;
return wgpuDeviceCreateBuffer(device, &bufferDesc);
}
void WgContext::releaseSampler(WGPUSampler& sampler) void WgContext::releaseSampler(WGPUSampler& sampler)
{ {
if (sampler) { if (sampler) {
@ -182,6 +194,7 @@ void WgContext::releaseSampler(WGPUSampler& sampler)
} }
} }
void WgContext::releaseTexture(WGPUTexture& texture) void WgContext::releaseTexture(WGPUTexture& texture)
{ {
if (texture) { if (texture) {
@ -195,9 +208,21 @@ void WgContext::releaseTexture(WGPUTexture& texture)
void WgContext::releaseTextureView(WGPUTextureView& textureView) void WgContext::releaseTextureView(WGPUTextureView& textureView)
{ {
if (textureView) wgpuTextureViewRelease(textureView); if (textureView) {
wgpuTextureViewRelease(textureView);
textureView = nullptr; textureView = nullptr;
} }
}
void WgContext::releaseBuffer(WGPUBuffer& buffer)
{
if (buffer) {
wgpuBufferDestroy(buffer);
wgpuBufferRelease(buffer);
buffer = nullptr;
}
}
//***************************************************************************** //*****************************************************************************

View file

@ -52,10 +52,13 @@ struct WgContext {
WGPUSampler createSampler(WGPUFilterMode minFilter, WGPUMipmapFilterMode mipmapFilter); WGPUSampler createSampler(WGPUFilterMode minFilter, WGPUMipmapFilterMode mipmapFilter);
WGPUTexture createTexture2d(WGPUTextureUsageFlags usage, WGPUTextureFormat format, uint32_t width, uint32_t height, char const * label); WGPUTexture createTexture2d(WGPUTextureUsageFlags usage, WGPUTextureFormat format, uint32_t width, uint32_t height, char const * label);
WGPUTextureView createTextureView2d(WGPUTexture texture, WGPU_NULLABLE char const * label); WGPUTextureView createTextureView2d(WGPUTexture texture, char const * label);
WGPUBuffer createBuffer(WGPUBufferUsageFlags usage, uint64_t size,char const * label);
void releaseSampler(WGPUSampler& sampler); void releaseSampler(WGPUSampler& sampler);
void releaseTexture(WGPUTexture& texture); void releaseTexture(WGPUTexture& texture);
void releaseTextureView(WGPUTextureView& textureView); void releaseTextureView(WGPUTextureView& textureView);
void releaseBuffer(WGPUBuffer& buffer);
}; };
struct WgBindGroup struct WgBindGroup

View file

@ -48,43 +48,45 @@ void WgMeshData::drawImage(WGPURenderPassEncoder renderPassEncoder)
void WgMeshData::update(WgContext& context, WgGeometryData* geometryData){ void WgMeshData::update(WgContext& context, WgGeometryData* geometryData){
release(context);
assert(geometryData); assert(geometryData);
// buffer position data create and write // buffer position data create and write
if(geometryData->positions.count > 0) { if(geometryData->positions.count > 0) {
vertexCount = geometryData->positions.count; vertexCount = geometryData->positions.count;
WGPUBufferDescriptor bufferDesc{}; if (bufferPosition && (wgpuBufferGetSize(bufferPosition) < sizeof(float) * vertexCount * 2))
bufferDesc.nextInChain = nullptr; context.releaseBuffer(bufferPosition);
bufferDesc.label = "Buffer position geometry data"; if (!bufferPosition) {
bufferDesc.usage = WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex; bufferPosition = context.createBuffer(
bufferDesc.size = sizeof(float) * vertexCount * 2; // x, y WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex,
bufferDesc.mappedAtCreation = false; sizeof(float) * vertexCount * 2,
bufferPosition = wgpuDeviceCreateBuffer(context.device, &bufferDesc); "Buffer position geometry data");
}
assert(bufferPosition); assert(bufferPosition);
wgpuQueueWriteBuffer(context.queue, bufferPosition, 0, &geometryData->positions[0], vertexCount * sizeof(float) * 2); wgpuQueueWriteBuffer(context.queue, bufferPosition, 0, &geometryData->positions[0], vertexCount * sizeof(float) * 2);
} }
// buffer vertex data create and write // buffer vertex data create and write
if(geometryData->texCoords.count > 0) { if(geometryData->texCoords.count > 0) {
WGPUBufferDescriptor bufferDesc{}; if (bufferTexCoord && (wgpuBufferGetSize(bufferTexCoord) < sizeof(float) * vertexCount * 2))
bufferDesc.nextInChain = nullptr; context.releaseBuffer(bufferTexCoord);
bufferDesc.label = "Buffer tex coords geometry data"; if (!bufferTexCoord) {
bufferDesc.usage = WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex; bufferTexCoord = context.createBuffer(
bufferDesc.size = sizeof(float) * vertexCount * 2; // u, v WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex,
bufferDesc.mappedAtCreation = false; sizeof(float) * vertexCount * 2,
bufferTexCoord = wgpuDeviceCreateBuffer(context.device, &bufferDesc); "Buffer tex coords geometry data");
assert(bufferPosition); }
assert(bufferTexCoord);
wgpuQueueWriteBuffer(context.queue, bufferTexCoord, 0, &geometryData->texCoords[0], vertexCount * sizeof(float) * 2); wgpuQueueWriteBuffer(context.queue, bufferTexCoord, 0, &geometryData->texCoords[0], vertexCount * sizeof(float) * 2);
} }
// buffer index data create and write // buffer index data create and write
if(geometryData->indexes.count > 0) { if(geometryData->indexes.count > 0) {
indexCount = geometryData->indexes.count; indexCount = geometryData->indexes.count;
WGPUBufferDescriptor bufferDesc{}; if (bufferIndex && (wgpuBufferGetSize(bufferIndex) < sizeof(uint32_t) * indexCount))
bufferDesc.nextInChain = nullptr; context.releaseBuffer(bufferIndex);
bufferDesc.label = "Buffer index geometry data"; if (!bufferIndex) {
bufferDesc.usage = WGPUBufferUsage_CopyDst | WGPUBufferUsage_Index; bufferIndex = context.createBuffer(
bufferDesc.size = sizeof(uint32_t) * indexCount; WGPUBufferUsage_CopyDst | WGPUBufferUsage_Index,
bufferDesc.mappedAtCreation = false; sizeof(uint32_t) * indexCount,
bufferIndex = wgpuDeviceCreateBuffer(context.device, &bufferDesc); "Buffer index geometry data");
}
assert(bufferIndex); assert(bufferIndex);
wgpuQueueWriteBuffer(context.queue, bufferIndex, 0, &geometryData->indexes[0], indexCount * sizeof(uint32_t)); wgpuQueueWriteBuffer(context.queue, bufferIndex, 0, &geometryData->indexes[0], indexCount * sizeof(uint32_t));
} }
@ -93,23 +95,9 @@ void WgMeshData::update(WgContext& context, WgGeometryData* geometryData){
void WgMeshData::release(WgContext& context) void WgMeshData::release(WgContext& context)
{ {
if (bufferIndex) { context.releaseBuffer(bufferIndex);
wgpuBufferDestroy(bufferIndex); context.releaseBuffer(bufferTexCoord);
wgpuBufferRelease(bufferIndex); context.releaseBuffer(bufferPosition);
bufferIndex = nullptr;
indexCount = 0;
}
if (bufferTexCoord) {
wgpuBufferDestroy(bufferTexCoord);
wgpuBufferRelease(bufferTexCoord);
bufferTexCoord = nullptr;
}
if (bufferPosition) {
wgpuBufferDestroy(bufferPosition);
wgpuBufferRelease(bufferPosition);
bufferPosition = nullptr;
bufferPosition = 0;
}
}; };
//*********************************************************************** //***********************************************************************