From 47b9866f8b86edbfa0614547cce8d698fa2f175b Mon Sep 17 00:00:00 2001 From: Sergii Liebodkin Date: Wed, 12 Jun 2024 06:39:37 +0300 Subject: [PATCH] wg_engine: cross-platform support it provide changes public API for webgpu canvas interface to provide nessessary handles to native window for different platforms: API Change: - Result target(void *instance, void *surface, uint32_t w, uint32_t h) noexcept; --- inc/thorvg.h | 2 +- src/renderer/tvgWgCanvas.cpp | 7 +-- src/renderer/wg_engine/tvgWgBindGroups.cpp | 54 ++++++++++++++++---- src/renderer/wg_engine/tvgWgBindGroups.h | 14 ++++- src/renderer/wg_engine/tvgWgCommon.cpp | 26 ++++++---- src/renderer/wg_engine/tvgWgCommon.h | 5 +- src/renderer/wg_engine/tvgWgPipelines.cpp | 17 +++--- src/renderer/wg_engine/tvgWgPipelines.h | 8 +-- src/renderer/wg_engine/tvgWgRenderTarget.cpp | 20 ++++---- src/renderer/wg_engine/tvgWgRenderTarget.h | 5 +- src/renderer/wg_engine/tvgWgRenderer.cpp | 41 +++++---------- src/renderer/wg_engine/tvgWgRenderer.h | 3 +- src/renderer/wg_engine/tvgWgShaderSrc.cpp | 20 ++++---- 13 files changed, 131 insertions(+), 91 deletions(-) diff --git a/inc/thorvg.h b/inc/thorvg.h index 42d64997..4e070623 100644 --- a/inc/thorvg.h +++ b/inc/thorvg.h @@ -1845,7 +1845,7 @@ public: * @note Experimental API * @see Canvas::viewport() */ - Result target(void* window, uint32_t w, uint32_t h) noexcept; + Result target(void* instance, void* surface, uint32_t w, uint32_t h) noexcept; /** * @brief Creates a new WgCanvas object. diff --git a/src/renderer/tvgWgCanvas.cpp b/src/renderer/tvgWgCanvas.cpp index 7db77f6d..f7da7c26 100644 --- a/src/renderer/tvgWgCanvas.cpp +++ b/src/renderer/tvgWgCanvas.cpp @@ -52,17 +52,18 @@ WgCanvas::~WgCanvas() delete pImpl; } -Result WgCanvas::target(void* window, uint32_t w, uint32_t h) noexcept +Result WgCanvas::target(void* instance, void* surface, uint32_t w, uint32_t h) noexcept { #ifdef THORVG_WG_RASTER_SUPPORT - if (!window) return Result::InvalidArguments; + if (!instance) return Result::InvalidArguments; + if (!surface) return Result::InvalidArguments; if ((w == 0) || (h == 0)) return Result::InvalidArguments; //We know renderer type, avoid dynamic_cast for performance. auto renderer = static_cast(Canvas::pImpl->renderer); if (!renderer) return Result::MemoryCorruption; - if (!renderer->target(window, w, h)) return Result::Unknown; + if (!renderer->target((WGPUInstance)instance, (WGPUSurface)surface, w, h)) return Result::Unknown; Canvas::pImpl->vport = {0, 0, (int32_t)w, (int32_t)h}; renderer->viewport(Canvas::pImpl->vport); diff --git a/src/renderer/wg_engine/tvgWgBindGroups.cpp b/src/renderer/wg_engine/tvgWgBindGroups.cpp index 3fbea8fc..f3efa815 100644 --- a/src/renderer/wg_engine/tvgWgBindGroups.cpp +++ b/src/renderer/wg_engine/tvgWgBindGroups.cpp @@ -33,7 +33,8 @@ WGPUBindGroupLayout WgBindGroupRadialGradient::layout = nullptr; WGPUBindGroupLayout WgBindGroupPicture::layout = nullptr; // composition and blending properties gropus WGPUBindGroupLayout WgBindGroupTexture::layout = nullptr; -WGPUBindGroupLayout WgBindGroupTextureStorage::layout = nullptr; +WGPUBindGroupLayout WgBindGroupTextureStorageRgba::layout = nullptr; +WGPUBindGroupLayout WgBindGroupTextureStorageBgra::layout = nullptr; WGPUBindGroupLayout WgBindGroupTextureSampled::layout = nullptr; WGPUBindGroupLayout WgBindGroupTexComposeBlend::layout = nullptr; WGPUBindGroupLayout WgBindGroupOpacity::layout = nullptr; @@ -315,11 +316,11 @@ void WgBindGroupTexture::release() } -WGPUBindGroupLayout WgBindGroupTextureStorage::getLayout(WGPUDevice device) +WGPUBindGroupLayout WgBindGroupTextureStorageRgba::getLayout(WGPUDevice device) { if (layout) return layout; const WGPUBindGroupLayoutEntry bindGroupLayoutEntries[] { - makeBindGroupLayoutEntryStorageTexture(0, WGPUStorageTextureAccess_ReadWrite) + makeBindGroupLayoutEntryStorage(0, WGPUStorageTextureAccess_ReadWrite, WGPUTextureFormat_RGBA8Unorm) }; layout = createBindGroupLayout(device, bindGroupLayoutEntries, 1); assert(layout); @@ -327,13 +328,13 @@ WGPUBindGroupLayout WgBindGroupTextureStorage::getLayout(WGPUDevice device) } -void WgBindGroupTextureStorage::releaseLayout() +void WgBindGroupTextureStorageRgba::releaseLayout() { releaseBindGroupLayout(layout); } -void WgBindGroupTextureStorage::initialize(WGPUDevice device, WGPUQueue queue, WGPUTextureView uTexture) +void WgBindGroupTextureStorageRgba::initialize(WGPUDevice device, WGPUQueue queue, WGPUTextureView uTexture) { release(); const WGPUBindGroupEntry bindGroupEntries[] { @@ -344,7 +345,42 @@ void WgBindGroupTextureStorage::initialize(WGPUDevice device, WGPUQueue queue, W } -void WgBindGroupTextureStorage::release() +void WgBindGroupTextureStorageRgba::release() +{ + releaseBindGroup(mBindGroup); +} + + +WGPUBindGroupLayout WgBindGroupTextureStorageBgra::getLayout(WGPUDevice device) +{ + if (layout) return layout; + const WGPUBindGroupLayoutEntry bindGroupLayoutEntries[] { + makeBindGroupLayoutEntryStorage(0, WGPUStorageTextureAccess_WriteOnly, WGPUTextureFormat_BGRA8Unorm) + }; + layout = createBindGroupLayout(device, bindGroupLayoutEntries, 1); + assert(layout); + return layout; +} + + +void WgBindGroupTextureStorageBgra::releaseLayout() +{ + releaseBindGroupLayout(layout); +} + + +void WgBindGroupTextureStorageBgra::initialize(WGPUDevice device, WGPUQueue queue, WGPUTextureView uTexture) +{ + release(); + const WGPUBindGroupEntry bindGroupEntries[] { + makeBindGroupEntryTextureView(0, uTexture) + }; + mBindGroup = createBindGroup(device, getLayout(device), bindGroupEntries, 1); + assert(mBindGroup); +} + + +void WgBindGroupTextureStorageBgra::release() { releaseBindGroup(mBindGroup); } @@ -391,9 +427,9 @@ WGPUBindGroupLayout WgBindGroupTexComposeBlend::getLayout(WGPUDevice device) { if (layout) return layout; const WGPUBindGroupLayoutEntry bindGroupLayoutEntries[] { - makeBindGroupLayoutEntryStorageTexture(0, WGPUStorageTextureAccess_ReadOnly), - makeBindGroupLayoutEntryStorageTexture(1, WGPUStorageTextureAccess_ReadOnly), - makeBindGroupLayoutEntryStorageTexture(2, WGPUStorageTextureAccess_ReadWrite) + makeBindGroupLayoutEntryStorage(0, WGPUStorageTextureAccess_ReadOnly, WGPUTextureFormat_RGBA8Unorm), + makeBindGroupLayoutEntryStorage(1, WGPUStorageTextureAccess_ReadOnly, WGPUTextureFormat_RGBA8Unorm), + makeBindGroupLayoutEntryStorage(2, WGPUStorageTextureAccess_ReadWrite, WGPUTextureFormat_RGBA8Unorm) }; layout = createBindGroupLayout(device, bindGroupLayoutEntries, 3); assert(layout); diff --git a/src/renderer/wg_engine/tvgWgBindGroups.h b/src/renderer/wg_engine/tvgWgBindGroups.h index 6f18eb78..2e01651b 100644 --- a/src/renderer/wg_engine/tvgWgBindGroups.h +++ b/src/renderer/wg_engine/tvgWgBindGroups.h @@ -119,7 +119,19 @@ struct WgBindGroupTexture : public WgBindGroup }; // @group(0 or 1) -struct WgBindGroupTextureStorage : public WgBindGroup +struct WgBindGroupTextureStorageRgba : public WgBindGroup +{ + static WGPUBindGroupLayout layout; + static WGPUBindGroupLayout getLayout(WGPUDevice device); + static void releaseLayout(); + + void initialize(WGPUDevice device, WGPUQueue queue, + WGPUTextureView uTexture); + void release(); +}; + +// @group(0 or 1) +struct WgBindGroupTextureStorageBgra : public WgBindGroup { static WGPUBindGroupLayout layout; static WGPUBindGroupLayout getLayout(WGPUDevice device); diff --git a/src/renderer/wg_engine/tvgWgCommon.cpp b/src/renderer/wg_engine/tvgWgCommon.cpp index 0152a89a..6278f37c 100644 --- a/src/renderer/wg_engine/tvgWgCommon.cpp +++ b/src/renderer/wg_engine/tvgWgCommon.cpp @@ -27,18 +27,19 @@ // context //***************************************************************************** -void WgContext::initialize() +void WgContext::initialize(WGPUInstance instance, WGPUSurface surface) { - // create instance - WGPUInstanceDescriptor instanceDesc{}; - instanceDesc.nextInChain = nullptr; - instance = wgpuCreateInstance(&instanceDesc); assert(instance); + assert(surface); + + // store global instance and surface + this->instance = instance; + this->surface = surface; // request adapter options WGPURequestAdapterOptions requestAdapterOptions{}; requestAdapterOptions.nextInChain = nullptr; - requestAdapterOptions.compatibleSurface = nullptr; + requestAdapterOptions.compatibleSurface = surface; requestAdapterOptions.powerPreference = WGPUPowerPreference_HighPerformance; requestAdapterOptions.forceFallbackAdapter = false; // on adapter request ended function @@ -113,6 +114,11 @@ void WgContext::release() wgpuAdapterRelease(adapter); adapter = nullptr; } + if (surface) { + wgpuSurfaceUnconfigure(surface); + wgpuSurfaceRelease(surface); + surface = nullptr; + } if (instance) { wgpuInstanceRelease(instance); instance = nullptr; @@ -170,7 +176,6 @@ WGPUTexture WgContext::createTexture2d(WGPUTextureUsageFlags usage, WGPUTextureF WGPUTexture WgContext::createTexture2dMS(WGPUTextureUsageFlags usage, WGPUTextureFormat format, uint32_t width, uint32_t height, uint32_t sc, char const * label) { - WGPUTextureDescriptor textureDesc{}; textureDesc.nextInChain = nullptr; textureDesc.label = label; @@ -326,7 +331,6 @@ void WgContext::releaseIndexBuffer(WGPUBuffer& buffer) releaseBuffer(buffer); } - //***************************************************************************** // bind group //***************************************************************************** @@ -425,7 +429,7 @@ WGPUBindGroupLayoutEntry WgBindGroup::makeBindGroupLayoutEntryTexture(uint32_t b } -WGPUBindGroupLayoutEntry WgBindGroup::makeBindGroupLayoutEntryStorageTexture(uint32_t binding, WGPUStorageTextureAccess access) +WGPUBindGroupLayoutEntry WgBindGroup::makeBindGroupLayoutEntryStorage(uint32_t binding, WGPUStorageTextureAccess access, WGPUTextureFormat format) { WGPUBindGroupLayoutEntry bindGroupLayoutEntry{}; bindGroupLayoutEntry.nextInChain = nullptr; @@ -433,7 +437,7 @@ WGPUBindGroupLayoutEntry WgBindGroup::makeBindGroupLayoutEntryStorageTexture(uin bindGroupLayoutEntry.visibility = WGPUShaderStage_Fragment | WGPUShaderStage_Compute; bindGroupLayoutEntry.storageTexture.nextInChain = nullptr; bindGroupLayoutEntry.storageTexture.access = access; - bindGroupLayoutEntry.storageTexture.format = WGPUTextureFormat_BGRA8Unorm; + bindGroupLayoutEntry.storageTexture.format = format; bindGroupLayoutEntry.storageTexture.viewDimension = WGPUTextureViewDimension_2D; return bindGroupLayoutEntry; } @@ -634,7 +638,7 @@ WGPUColorTargetState WgRenderPipeline::makeColorTargetState(const WGPUBlendState { WGPUColorTargetState colorTargetState{}; colorTargetState.nextInChain = nullptr; - colorTargetState.format = WGPUTextureFormat_BGRA8Unorm; + colorTargetState.format = WGPUTextureFormat_RGBA8Unorm; colorTargetState.blend = blendState; colorTargetState.writeMask = writeMask; return colorTargetState; diff --git a/src/renderer/wg_engine/tvgWgCommon.h b/src/renderer/wg_engine/tvgWgCommon.h index ac2b9079..65db5a50 100644 --- a/src/renderer/wg_engine/tvgWgCommon.h +++ b/src/renderer/wg_engine/tvgWgCommon.h @@ -44,6 +44,7 @@ struct WgPipelines; struct WgContext { WGPUInstance instance{}; + WGPUSurface surface{}; WGPUAdapter adapter{}; WGPUDevice device{}; WGPUQueue queue{}; @@ -58,7 +59,7 @@ struct WgContext { WgPipelines* pipelines{}; // external handle (do not release) - void initialize(); + void initialize(WGPUInstance instance, WGPUSurface surface); void release(); void executeCommandEncoder(WGPUCommandEncoder commandEncoder); @@ -95,7 +96,7 @@ struct WgBindGroup static WGPUBindGroupLayoutEntry makeBindGroupLayoutEntryBuffer(uint32_t binding); static WGPUBindGroupLayoutEntry makeBindGroupLayoutEntrySampler(uint32_t binding); static WGPUBindGroupLayoutEntry makeBindGroupLayoutEntryTexture(uint32_t binding); - static WGPUBindGroupLayoutEntry makeBindGroupLayoutEntryStorageTexture(uint32_t binding, WGPUStorageTextureAccess access); + static WGPUBindGroupLayoutEntry makeBindGroupLayoutEntryStorage(uint32_t binding, WGPUStorageTextureAccess access, WGPUTextureFormat format); static WGPUBuffer createBuffer(WGPUDevice device, WGPUQueue queue, const void *data, size_t size); static WGPUBindGroup createBindGroup(WGPUDevice device, WGPUBindGroupLayout layout, const WGPUBindGroupEntry* bindGroupEntries, uint32_t count); diff --git a/src/renderer/wg_engine/tvgWgPipelines.cpp b/src/renderer/wg_engine/tvgWgPipelines.cpp index 70e6fc68..b066b719 100644 --- a/src/renderer/wg_engine/tvgWgPipelines.cpp +++ b/src/renderer/wg_engine/tvgWgPipelines.cpp @@ -270,7 +270,7 @@ void WgPipelineClear::initialize(WGPUDevice device) { // bind groups and layouts WGPUBindGroupLayout bindGroupLayouts[] = { - WgBindGroupTextureStorage::getLayout(device) + WgBindGroupTextureStorageRgba::getLayout(device) }; // sheder source and labels @@ -289,8 +289,8 @@ void WgPipelineBlend::initialize(WGPUDevice device) { // bind groups and layouts WGPUBindGroupLayout bindGroupLayouts[] = { - WgBindGroupTextureStorage::getLayout(device), - WgBindGroupTextureStorage::getLayout(device), + WgBindGroupTextureStorageRgba::getLayout(device), + WgBindGroupTextureStorageRgba::getLayout(device), WgBindGroupBlendMethod::getLayout(device) }; @@ -310,8 +310,8 @@ void WgPipelineCompose::initialize(WGPUDevice device) { // bind groups and layouts WGPUBindGroupLayout bindGroupLayouts[] = { - WgBindGroupTextureStorage::getLayout(device), - WgBindGroupTextureStorage::getLayout(device), + WgBindGroupTextureStorageRgba::getLayout(device), + WgBindGroupTextureStorageRgba::getLayout(device), WgBindGroupCompositeMethod::getLayout(device), WgBindGroupOpacity::getLayout(device) }; @@ -354,8 +354,8 @@ void WgPipelineAntiAliasing::initialize(WGPUDevice device) { // bind groups and layouts WGPUBindGroupLayout bindGroupLayouts[] = { - WgBindGroupTextureStorage::getLayout(device), - WgBindGroupTextureStorage::getLayout(device) + WgBindGroupTextureStorageRgba::getLayout(device), + WgBindGroupTextureStorageBgra::getLayout(device) }; // sheder source and labels @@ -400,7 +400,8 @@ void WgPipelines::release() { WgBindGroupTexComposeBlend::layout = nullptr; WgBindGroupTextureSampled::releaseLayout(); - WgBindGroupTextureStorage::releaseLayout(); + WgBindGroupTextureStorageBgra::releaseLayout(); + WgBindGroupTextureStorageRgba::releaseLayout(); WgBindGroupTexture::releaseLayout(); WgBindGroupOpacity::releaseLayout(); WgBindGroupPicture::releaseLayout(); diff --git a/src/renderer/wg_engine/tvgWgPipelines.h b/src/renderer/wg_engine/tvgWgPipelines.h index 7a90d768..60e115cb 100644 --- a/src/renderer/wg_engine/tvgWgPipelines.h +++ b/src/renderer/wg_engine/tvgWgPipelines.h @@ -121,7 +121,7 @@ struct WgPipelineImage: public WgRenderPipeline struct WgPipelineClear: public WgComputePipeline { void initialize(WGPUDevice device) override; - void use(WGPUComputePassEncoder encoder, WgBindGroupTextureStorage& groupTexDst) + void use(WGPUComputePassEncoder encoder, WgBindGroupTextureStorageRgba& groupTexDst) { set(encoder); groupTexDst.set(encoder, 0); @@ -132,7 +132,7 @@ struct WgPipelineClear: public WgComputePipeline struct WgPipelineBlend: public WgComputePipeline { void initialize(WGPUDevice device) override; - void use(WGPUComputePassEncoder encoder, WgBindGroupTextureStorage& groupTexSrc, WgBindGroupTextureStorage& groupTexDst, WgBindGroupBlendMethod& blendMethod) + void use(WGPUComputePassEncoder encoder, WgBindGroupTextureStorageRgba& groupTexSrc, WgBindGroupTextureStorageRgba& groupTexDst, WgBindGroupBlendMethod& blendMethod) { set(encoder); groupTexSrc.set(encoder, 0); @@ -145,7 +145,7 @@ struct WgPipelineBlend: public WgComputePipeline struct WgPipelineCompose: public WgComputePipeline { void initialize(WGPUDevice device) override; - void use(WGPUComputePassEncoder encoder, WgBindGroupTextureStorage& groupTexSrc, WgBindGroupTextureStorage& groupTexMsk, WgBindGroupCompositeMethod& groupComposeMethod, WgBindGroupOpacity& groupOpacity) + void use(WGPUComputePassEncoder encoder, WgBindGroupTextureStorageRgba& groupTexSrc, WgBindGroupTextureStorageRgba& groupTexMsk, WgBindGroupCompositeMethod& groupComposeMethod, WgBindGroupOpacity& groupOpacity) { set(encoder); groupTexSrc.set(encoder, 0); @@ -173,7 +173,7 @@ struct WgPipelineComposeBlend: public WgComputePipeline struct WgPipelineAntiAliasing: public WgComputePipeline { void initialize(WGPUDevice device) override; - void use(WGPUComputePassEncoder encoder, WgBindGroupTextureStorage& groupTexSrc, WgBindGroupTextureStorage& groupTexDst) + void use(WGPUComputePassEncoder encoder, WgBindGroupTextureStorageRgba& groupTexSrc, WgBindGroupTextureStorageBgra& groupTexDst) { set(encoder); groupTexSrc.set(encoder, 0); diff --git a/src/renderer/wg_engine/tvgWgRenderTarget.cpp b/src/renderer/wg_engine/tvgWgRenderTarget.cpp index 13b651b8..e6124b9f 100644 --- a/src/renderer/wg_engine/tvgWgRenderTarget.cpp +++ b/src/renderer/wg_engine/tvgWgRenderTarget.cpp @@ -26,7 +26,7 @@ // render storage //***************************************************************************** - void WgRenderStorage::initialize(WgContext& context, uint32_t w, uint32_t h, uint32_t samples) + void WgRenderStorage::initialize(WgContext& context, uint32_t w, uint32_t h, uint32_t samples, WGPUTextureFormat format) { release(context); // store target storage size @@ -41,8 +41,7 @@ WGPUTextureUsage_TextureBinding | WGPUTextureUsage_StorageBinding | WGPUTextureUsage_RenderAttachment, - WGPUTextureFormat_BGRA8Unorm, - width, height, "The target texture color"); + format, width, height, "The target texture color"); texStencil = context.createTexture2d( WGPUTextureUsage_RenderAttachment, WGPUTextureFormat_Stencil8, @@ -54,7 +53,10 @@ assert(texViewColor); assert(texViewStencil); // initialize bind group for blitting - bindGroupTexStorage.initialize(context.device, context.queue, texViewColor); + if (format == WGPUTextureFormat_RGBA8Unorm) + bindGroupTexStorageRgba.initialize(context.device, context.queue, texViewColor); + if (format == WGPUTextureFormat_BGRA8Unorm) + bindGroupTexStorageBgra.initialize(context.device, context.queue, texViewColor); // initialize window binding groups WgShaderTypeMat4x4f viewMat(w, h); mBindGroupCanvas.initialize(context.device, context.queue, viewMat); @@ -66,7 +68,7 @@ void WgRenderStorage::release(WgContext& context) { mRenderPassEncoder = nullptr; mBindGroupCanvas.release(); - bindGroupTexStorage.release(); + bindGroupTexStorageRgba.release(); context.releaseTextureView(texViewStencil); context.releaseTextureView(texViewColor); context.releaseTexture(texStencil); @@ -187,7 +189,7 @@ void WgRenderStorage::clear(WGPUCommandEncoder commandEncoder) { assert(commandEncoder); WGPUComputePassEncoder computePassEncoder = beginComputePass(commandEncoder); - mPipelines->computeClear.use(computePassEncoder, bindGroupTexStorage); + mPipelines->computeClear.use(computePassEncoder, bindGroupTexStorageRgba); dispatchWorkgroups(computePassEncoder); endComputePass(computePassEncoder); } @@ -198,7 +200,7 @@ void WgRenderStorage::blend(WGPUCommandEncoder commandEncoder, WgRenderStorage* assert(commandEncoder); assert(targetSrc); WGPUComputePassEncoder computePassEncoder = beginComputePass(commandEncoder); - mPipelines->computeBlend.use(computePassEncoder, targetSrc->bindGroupTexStorage, bindGroupTexStorage, *blendMethod); + mPipelines->computeBlend.use(computePassEncoder, targetSrc->bindGroupTexStorageRgba, bindGroupTexStorageRgba, *blendMethod); dispatchWorkgroups(computePassEncoder); endComputePass(computePassEncoder); }; @@ -209,7 +211,7 @@ void WgRenderStorage::compose(WGPUCommandEncoder commandEncoder, WgRenderStorage assert(commandEncoder); assert(targetMsk); WGPUComputePassEncoder computePassEncoder = beginComputePass(commandEncoder); - mPipelines->computeCompose.use(computePassEncoder, bindGroupTexStorage, targetMsk->bindGroupTexStorage, *composeMethod, *opacity); + mPipelines->computeCompose.use(computePassEncoder, bindGroupTexStorageRgba, targetMsk->bindGroupTexStorageRgba, *composeMethod, *opacity); dispatchWorkgroups(computePassEncoder); endComputePass(computePassEncoder); }; @@ -242,7 +244,7 @@ void WgRenderStorage::antialias(WGPUCommandEncoder commandEncoder, WgRenderStora assert(commandEncoder); assert(targetSrc); WGPUComputePassEncoder computePassEncoder = beginComputePass(commandEncoder); - mPipelines->computeAntiAliasing.use(computePassEncoder, targetSrc->bindGroupTexStorage, bindGroupTexStorage); + mPipelines->computeAntiAliasing.use(computePassEncoder, targetSrc->bindGroupTexStorageRgba, bindGroupTexStorageBgra); dispatchWorkgroups(computePassEncoder); endComputePass(computePassEncoder); } diff --git a/src/renderer/wg_engine/tvgWgRenderTarget.h b/src/renderer/wg_engine/tvgWgRenderTarget.h index 60e101e4..be1ef110 100644 --- a/src/renderer/wg_engine/tvgWgRenderTarget.h +++ b/src/renderer/wg_engine/tvgWgRenderTarget.h @@ -36,13 +36,14 @@ public: WGPUTexture texStencil{}; WGPUTextureView texViewColor{}; WGPUTextureView texViewStencil{}; - WgBindGroupTextureStorage bindGroupTexStorage; + WgBindGroupTextureStorageRgba bindGroupTexStorageRgba; + WgBindGroupTextureStorageBgra bindGroupTexStorageBgra; uint32_t width{}; uint32_t height{}; uint32_t workgroupsCountX{}; uint32_t workgroupsCountY{}; public: - void initialize(WgContext& context, uint32_t w, uint32_t h, uint32_t samples = 1); + void initialize(WgContext& context, uint32_t w, uint32_t h, uint32_t samples = 1, WGPUTextureFormat format = WGPUTextureFormat_RGBA8Unorm); void release(WgContext& context); void beginRenderPass(WGPUCommandEncoder commandEncoder, bool clear); diff --git a/src/renderer/wg_engine/tvgWgRenderer.cpp b/src/renderer/wg_engine/tvgWgRenderer.cpp index 6e1a198e..68bb3f66 100644 --- a/src/renderer/wg_engine/tvgWgRenderer.cpp +++ b/src/renderer/wg_engine/tvgWgRenderer.cpp @@ -22,28 +22,22 @@ #include "tvgWgRenderer.h" -#ifdef _WIN32 -// TODO: cross-platform realization -#include -#endif - #define WG_SSAA_SAMPLES (2) WgRenderer::WgRenderer() { - initialize(); } WgRenderer::~WgRenderer() { release(); + mContext.release(); } void WgRenderer::initialize() { - mContext.initialize(); mPipelines.initialize(mContext); mOpacityPool.initialize(mContext); mBlendMethodPool.initialize(mContext); @@ -70,10 +64,7 @@ void WgRenderer::release() mRenderStorageRoot.release(mContext); mRenderStorageScreen.release(mContext); mRenderTarget.release(mContext); - wgpuSurfaceUnconfigure(mSurface); - wgpuSurfaceRelease(mSurface); mPipelines.release(); - mContext.release(); } @@ -274,7 +265,7 @@ bool WgRenderer::clear() bool WgRenderer::sync() { WGPUSurfaceTexture backBuffer{}; - wgpuSurfaceGetCurrentTexture(mSurface, &backBuffer); + wgpuSurfaceGetCurrentTexture(mContext.surface, &backBuffer); WGPUCommandEncoderDescriptor commandEncoderDesc{}; commandEncoderDesc.nextInChain = nullptr; @@ -296,7 +287,7 @@ bool WgRenderer::sync() mContext.executeCommandEncoder(commandEncoder); wgpuCommandEncoderRelease(commandEncoder); - wgpuSurfacePresent(mSurface); + wgpuSurfacePresent(mContext.surface); return true; } @@ -314,25 +305,16 @@ bool WgRenderer::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t // target for native window handle -bool WgRenderer::target(void* window, uint32_t w, uint32_t h) +bool WgRenderer::target(WGPUInstance instance, WGPUSurface surface, uint32_t w, uint32_t h) { // store target surface properties mTargetSurface.stride = w; mTargetSurface.w = w > 0 ? w : 1; mTargetSurface.h = h > 0 ? h : 1; - // surface descriptor from windows hwnd - WGPUSurfaceDescriptorFromWindowsHWND surfaceDescHwnd{}; - surfaceDescHwnd.chain.next = nullptr; - surfaceDescHwnd.chain.sType = WGPUSType_SurfaceDescriptorFromWindowsHWND; - surfaceDescHwnd.hinstance = GetModuleHandle(NULL); - surfaceDescHwnd.hwnd = (HWND)window; - WGPUSurfaceDescriptor surfaceDesc{}; - surfaceDesc.nextInChain = (const WGPUChainedStruct*)&surfaceDescHwnd; - surfaceDesc.label = "The surface"; - mSurface = wgpuInstanceCreateSurface(mContext.instance, &surfaceDesc); - assert(mSurface); + mContext.initialize(instance, surface); + // configure surface WGPUSurfaceConfiguration surfaceConfiguration{}; surfaceConfiguration.nextInChain = nullptr; surfaceConfiguration.device = mContext.device; @@ -341,14 +323,15 @@ bool WgRenderer::target(void* window, uint32_t w, uint32_t h) surfaceConfiguration.viewFormatCount = 0; surfaceConfiguration.viewFormats = nullptr; surfaceConfiguration.alphaMode = WGPUCompositeAlphaMode_Auto; - surfaceConfiguration.width = mTargetSurface.w; - surfaceConfiguration.height = mTargetSurface.h; - surfaceConfiguration.presentMode = WGPUPresentMode_Mailbox; - wgpuSurfaceConfigure(mSurface, &surfaceConfiguration); + surfaceConfiguration.width = w; + surfaceConfiguration.height = h; + surfaceConfiguration.presentMode = WGPUPresentMode_Immediate; + wgpuSurfaceConfigure(mContext.surface, &surfaceConfiguration); + initialize(); mRenderTarget.initialize(mContext, w, h, WG_SSAA_SAMPLES); mRenderStorageRoot.initialize(mContext, w, h, WG_SSAA_SAMPLES); - mRenderStorageScreen.initialize(mContext, w, h); + mRenderStorageScreen.initialize(mContext, w, h, 1, WGPUTextureFormat_BGRA8Unorm); return true; } diff --git a/src/renderer/wg_engine/tvgWgRenderer.h b/src/renderer/wg_engine/tvgWgRenderer.h index ea8168d9..296383e6 100644 --- a/src/renderer/wg_engine/tvgWgRenderer.h +++ b/src/renderer/wg_engine/tvgWgRenderer.h @@ -52,7 +52,7 @@ public: bool sync() override; bool target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h); - bool target(void* window, uint32_t w, uint32_t h); // temporary solution + bool target(WGPUInstance instance, WGPUSurface surface, uint32_t w, uint32_t h); Compositor* target(const RenderRegion& region, ColorSpace cs) override; bool beginComposite(Compositor* cmp, CompositeMethod method, uint8_t opacity) override; @@ -78,7 +78,6 @@ private: Array mRenderStorageStack; // native window handles - WGPUSurface mSurface{}; WgContext mContext; WgPipelines mPipelines; Surface mTargetSurface; diff --git a/src/renderer/wg_engine/tvgWgShaderSrc.cpp b/src/renderer/wg_engine/tvgWgShaderSrc.cpp index 8e9d8e7f..0410513d 100644 --- a/src/renderer/wg_engine/tvgWgShaderSrc.cpp +++ b/src/renderer/wg_engine/tvgWgShaderSrc.cpp @@ -365,7 +365,7 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4f { // pipeline shader modules clear const char* cShaderSource_PipelineComputeClear = R"( -@group(0) @binding(0) var imageDst : texture_storage_2d; +@group(0) @binding(0) var imageDst : texture_storage_2d; @compute @workgroup_size(8, 8) fn cs_main( @builtin(global_invocation_id) id: vec3u) { @@ -376,8 +376,8 @@ fn cs_main( @builtin(global_invocation_id) id: vec3u) { // pipeline shader modules blend const char* cShaderSource_PipelineComputeBlend = R"( -@group(0) @binding(0) var imageSrc : texture_storage_2d; -@group(1) @binding(0) var imageDst : texture_storage_2d; +@group(0) @binding(0) var imageSrc : texture_storage_2d; +@group(1) @binding(0) var imageDst : texture_storage_2d; @group(2) @binding(0) var blendMethod : u32; @compute @workgroup_size(8, 8) @@ -420,8 +420,8 @@ fn cs_main( @builtin(global_invocation_id) id: vec3u) { // pipeline shader modules compose const char* cShaderSource_PipelineComputeCompose = R"( -@group(0) @binding(0) var imageSrc : texture_storage_2d; -@group(1) @binding(0) var imageMsk : texture_storage_2d; +@group(0) @binding(0) var imageSrc : texture_storage_2d; +@group(1) @binding(0) var imageMsk : texture_storage_2d; @group(2) @binding(0) var composeMethod : u32; @group(3) @binding(0) var opacity : f32; @@ -455,9 +455,9 @@ fn cs_main( @builtin(global_invocation_id) id: vec3u) { // pipeline shader modules compose blend const char* cShaderSource_PipelineComputeComposeBlend = R"( -@group(0) @binding(0) var imageSrc : texture_storage_2d; -@group(0) @binding(1) var imageMsk : texture_storage_2d; -@group(0) @binding(2) var imageDst : texture_storage_2d; +@group(0) @binding(0) var imageSrc : texture_storage_2d; +@group(0) @binding(1) var imageMsk : texture_storage_2d; +@group(0) @binding(2) var imageDst : texture_storage_2d; @group(1) @binding(0) var composeMethod : u32; @group(2) @binding(0) var blendMethod : u32; @group(3) @binding(0) var opacity : f32; @@ -517,8 +517,8 @@ fn cs_main( @builtin(global_invocation_id) id: vec3u) { // pipeline shader modules anti-aliasing const char* cShaderSource_PipelineComputeAntiAlias = R"( -@group(0) @binding(0) var imageSrc : texture_storage_2d; -@group(1) @binding(0) var imageDst : texture_storage_2d; +@group(0) @binding(0) var imageSrc : texture_storage_2d; +@group(1) @binding(0) var imageDst : texture_storage_2d; @compute @workgroup_size(8, 8) fn cs_main( @builtin(global_invocation_id) id: vec3u) {