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;
This commit is contained in:
Sergii Liebodkin 2024-06-12 06:39:37 +03:00 committed by Hermet Park
parent c35b731f0f
commit 47b9866f8b
13 changed files with 131 additions and 91 deletions

View file

@ -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.

View file

@ -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<WgRenderer*>(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);

View file

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

View file

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

View file

@ -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;

View file

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

View file

@ -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();

View file

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

View file

@ -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);
}

View file

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

View file

@ -22,28 +22,22 @@
#include "tvgWgRenderer.h"
#ifdef _WIN32
// TODO: cross-platform realization
#include <windows.h>
#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;
}

View file

@ -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<WgRenderStorage*> mRenderStorageStack;
// native window handles
WGPUSurface mSurface{};
WgContext mContext;
WgPipelines mPipelines;
Surface mTargetSurface;

View file

@ -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<bgra8unorm, read_write>;
@group(0) @binding(0) var imageDst : texture_storage_2d<rgba8unorm, read_write>;
@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<bgra8unorm, read_write>;
@group(1) @binding(0) var imageDst : texture_storage_2d<bgra8unorm, read_write>;
@group(0) @binding(0) var imageSrc : texture_storage_2d<rgba8unorm, read_write>;
@group(1) @binding(0) var imageDst : texture_storage_2d<rgba8unorm, read_write>;
@group(2) @binding(0) var<uniform> 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<bgra8unorm, read_write>;
@group(1) @binding(0) var imageMsk : texture_storage_2d<bgra8unorm, read_write>;
@group(0) @binding(0) var imageSrc : texture_storage_2d<rgba8unorm, read_write>;
@group(1) @binding(0) var imageMsk : texture_storage_2d<rgba8unorm, read_write>;
@group(2) @binding(0) var<uniform> composeMethod : u32;
@group(3) @binding(0) var<uniform> 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<bgra8unorm, read>;
@group(0) @binding(1) var imageMsk : texture_storage_2d<bgra8unorm, read>;
@group(0) @binding(2) var imageDst : texture_storage_2d<bgra8unorm, read_write>;
@group(0) @binding(0) var imageSrc : texture_storage_2d<rgba8unorm, read>;
@group(0) @binding(1) var imageMsk : texture_storage_2d<rgba8unorm, read>;
@group(0) @binding(2) var imageDst : texture_storage_2d<rgba8unorm, read_write>;
@group(1) @binding(0) var<uniform> composeMethod : u32;
@group(2) @binding(0) var<uniform> blendMethod : u32;
@group(3) @binding(0) var<uniform> 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<bgra8unorm, read_write>;
@group(1) @binding(0) var imageDst : texture_storage_2d<bgra8unorm, read_write>;
@group(0) @binding(0) var imageSrc : texture_storage_2d<rgba8unorm, read_write>;
@group(1) @binding(0) var imageDst : texture_storage_2d<bgra8unorm, write>;
@compute @workgroup_size(8, 8)
fn cs_main( @builtin(global_invocation_id) id: vec3u) {