diff --git a/defold-rive/src/comp_rive.cpp b/defold-rive/src/comp_rive.cpp index 35df9e67..58bd1423 100644 --- a/defold-rive/src/comp_rive.cpp +++ b/defold-rive/src/comp_rive.cpp @@ -1296,9 +1296,18 @@ namespace dmRive rivectx->m_RenderContext = *(dmRender::HRenderContext*)ctx->m_Contexts.Get(dmHashString64("render")); rivectx->m_MaxInstanceCount = dmConfigFile::GetInt(ctx->m_Config, "rive.max_instance_count", 128); - g_RenderBeginParams.m_DoFinalBlit = true; + g_RenderBeginParams.m_DoFinalBlit = dmConfigFile::GetInt(ctx->m_Config, "rive.render_to_texture", 1); g_RenderBeginParams.m_BackbufferSamples = dmConfigFile::GetInt(ctx->m_Config, "display.samples", 0); + if (g_RenderBeginParams.m_DoFinalBlit) + { + dmLogWarning("Render to texture enabled"); + } + else + { + dmLogWarning("Render to framebuffer enabled"); + } + g_OriginalWindowWidth = dmGraphics::GetWidth(rivectx->m_GraphicsContext); g_OriginalWindowHeight = dmGraphics::GetHeight(rivectx->m_GraphicsContext); g_DisplayFactor = dmGraphics::GetDisplayScaleFactor(rivectx->m_GraphicsContext); diff --git a/defold-rive/src/private/renderer_context_metal.mm b/defold-rive/src/private/renderer_context_metal.mm index 7767b522..5704131a 100644 --- a/defold-rive/src/private/renderer_context_metal.mm +++ b/defold-rive/src/private/renderer_context_metal.mm @@ -24,6 +24,7 @@ metalOptions.disableFramebufferReads = true; m_RenderContext = rive::gpu::RenderContextMetalImpl::MakeContext(m_GPU, metalOptions); + m_TargetTexture = 0; } rive::Factory* Factory() override @@ -57,24 +58,29 @@ void Flush() override void OnSizeChanged(uint32_t width, uint32_t height, uint32_t sample_count, bool do_final_blit) override { @autoreleasepool { - // For now we can only output the result if we blit it to the backbuffer via an extra DC - assert(do_final_blit); - auto renderContextImpl = m_RenderContext->static_impl_cast(); m_RenderTarget = renderContextImpl->makeRenderTarget(MTLPixelFormatBGRA8Unorm, width, height); - dmGraphics::TextureParams tp = {}; - tp.m_Width = width; - tp.m_Height = height; - tp.m_Depth = 1; - tp.m_Format = dmGraphics::TEXTURE_FORMAT_BGRA8U; - - dmGraphics::SetTexture(m_BackingTexture, tp); - - void* opaque_backing_texture = dmGraphics::VulkanTextureToMetal(m_GraphicsContext, m_BackingTexture); - assert(opaque_backing_texture); - id mtl_texture = (__bridge id) opaque_backing_texture; - m_RenderTarget->setTargetTexture(mtl_texture); + if (do_final_blit) + { + if (m_BackingTexture) + { + dmGraphics::DeleteTexture(m_BackingTexture); + } + + dmGraphics::TextureParams tp = {}; + tp.m_Width = width; + tp.m_Height = height; + tp.m_Depth = 1; + tp.m_Format = dmGraphics::TEXTURE_FORMAT_BGRA8U; + + dmGraphics::SetTexture(m_BackingTexture, tp); + + void* opaque_backing_texture = dmGraphics::VulkanTextureToMetal(m_GraphicsContext, m_BackingTexture); + assert(opaque_backing_texture); + id mtl_texture = (__bridge id) opaque_backing_texture; + m_RenderTarget->setTargetTexture(mtl_texture); + } } } @@ -93,7 +99,14 @@ void SetGraphicsContext(dmGraphics::HContext graphics_context) override void SetRenderTargetTexture(dmGraphics::HTexture texture) override { - m_TargetTexture = texture; + @autoreleasepool { + m_TargetTexture = texture; + + void* opaque_backing_texture = dmGraphics::VulkanTextureToMetal(m_GraphicsContext, m_TargetTexture); + assert(opaque_backing_texture); + id mtl_texture = (__bridge id) opaque_backing_texture; + m_RenderTarget->setTargetTexture(mtl_texture); + } } dmGraphics::HTexture GetBackingTexture() override diff --git a/defold-rive/src/private/renderer_context_webgpu.cpp b/defold-rive/src/private/renderer_context_webgpu.cpp index 12deafc6..ed3983d2 100644 --- a/defold-rive/src/private/renderer_context_webgpu.cpp +++ b/defold-rive/src/private/renderer_context_webgpu.cpp @@ -34,11 +34,12 @@ namespace dmRive dmGraphics::HContext graphics_context = dmGraphics::GetInstalledContext(); assert(graphics_context); - WGPUDevice webgpu_device = dmGraphics::WebGPUGetDevice(graphics_context); - WGPUQueue webgpu_queue = dmGraphics::WebGPUGetQueue(graphics_context); - // Part of Defold 1.10.4!!! - WGPUAdapter webgpu_adapter = dmGraphics::WebGPUGetAdapter(graphics_context); + WGPUDevice webgpu_device = dmGraphics::WebGPUGetDevice(graphics_context); + WGPUQueue webgpu_queue = dmGraphics::WebGPUGetQueue(graphics_context); + WGPUAdapter webgpu_adapter = dmGraphics::WebGPUGetAdapter(graphics_context); + m_RenderToTexture = true; // render to texture is the default + m_TargetTexture = 0; m_BackingTexture = 0; m_Adapter = wgpu::Adapter::Acquire(webgpu_adapter); m_Device = wgpu::Device::Acquire(webgpu_device); @@ -66,56 +67,95 @@ namespace dmRive void BeginFrame(const rive::gpu::RenderContext::FrameDescriptor& frameDescriptor) override { - m_RenderContext->beginFrame(frameDescriptor); - - /* - s_renderContext->beginFrame({ - .renderTargetWidth = s_renderTarget->width(), - .renderTargetHeight = s_renderTarget->height(), - .loadAction = static_cast(loadAction), - .clearColor = clearColor, - }); - */ + // Using operator= (in case it gets implemented) + rive::gpu::RenderContext::FrameDescriptor copy = frameDescriptor; + + // rendering to a render target + if (!m_RenderToTexture) + { + copy.loadAction = rive::gpu::LoadAction::preserveRenderTarget; + } + + m_RenderContext->beginFrame(copy); } void Flush() override { - m_RenderContext->flush({.renderTarget = m_RenderTarget.get()}); + WGPUCommandEncoder wgpu_encoder; + + if (!m_RenderToTexture) + { + wgpu_encoder = dmGraphics::WebGPUGetActiveCommandEncoder(m_GraphicsContext); + dmGraphics::WebGPURenderPassEnd(m_GraphicsContext); + } + else + { + wgpu_encoder = wgpuDeviceCreateCommandEncoder(m_Device.Get(), 0); + } + + m_RenderContext->flush({ + .renderTarget = m_RenderTarget.get(), + .externalCommandBuffer = (void*)(uintptr_t)wgpu_encoder + }); + + if (!m_RenderToTexture) + { + dmGraphics::WebGPURenderPassBegin(m_GraphicsContext); + } + else + { + const WGPUCommandBuffer buffer = wgpuCommandEncoderFinish(wgpu_encoder, NULL); + wgpuQueueSubmit(m_Queue.Get(), 1, &buffer); + wgpuCommandBufferRelease(buffer); + wgpuCommandEncoderRelease(wgpu_encoder); + } } void OnSizeChanged(uint32_t width, uint32_t height, uint32_t sample_count, bool do_final_blit) override { - dmLogInfo("Before creating RT"); auto renderContextImpl = m_RenderContext->static_impl_cast(); m_RenderTarget = renderContextImpl->makeRenderTarget(wgpu::TextureFormat::RGBA8Unorm, width, height); - dmLogInfo("After creating RT"); if (m_BackingTexture) { dmGraphics::DeleteTexture(m_BackingTexture); } - dmGraphics::TextureCreationParams default_texture_creation_params; - default_texture_creation_params.m_Width = width; - default_texture_creation_params.m_Height = height; - default_texture_creation_params.m_Depth = 1; - default_texture_creation_params.m_UsageHintBits = dmGraphics::TEXTURE_USAGE_FLAG_SAMPLE | dmGraphics::TEXTURE_USAGE_FLAG_COLOR | dmGraphics::TEXTURE_USAGE_FLAG_INPUT; - default_texture_creation_params.m_OriginalWidth = default_texture_creation_params.m_Width; - default_texture_creation_params.m_OriginalHeight = default_texture_creation_params.m_Height; + if (do_final_blit) + { + dmGraphics::TextureCreationParams default_texture_creation_params; + default_texture_creation_params.m_Width = width; + default_texture_creation_params.m_Height = height; + default_texture_creation_params.m_Depth = 1; + default_texture_creation_params.m_UsageHintBits = dmGraphics::TEXTURE_USAGE_FLAG_SAMPLE | dmGraphics::TEXTURE_USAGE_FLAG_COLOR | dmGraphics::TEXTURE_USAGE_FLAG_INPUT; + default_texture_creation_params.m_OriginalWidth = default_texture_creation_params.m_Width; + default_texture_creation_params.m_OriginalHeight = default_texture_creation_params.m_Height; + + m_BackingTexture = dmGraphics::NewTexture(m_GraphicsContext, default_texture_creation_params); + + dmGraphics::TextureParams tp = {}; + tp.m_Width = width; + tp.m_Height = height; + //tp.m_Format = dmGraphics::TEXTURE_FORMAT_BGRA8U; + tp.m_Format = dmGraphics::TEXTURE_FORMAT_RGBA; - m_BackingTexture = dmGraphics::NewTexture(m_GraphicsContext, default_texture_creation_params); + dmGraphics::SetTexture(m_BackingTexture, tp); - dmGraphics::TextureParams tp = {}; - tp.m_Width = width; - tp.m_Height = height; - //tp.m_Format = dmGraphics::TEXTURE_FORMAT_BGRA8U; - tp.m_Format = dmGraphics::TEXTURE_FORMAT_RGBA; + WGPUTextureView webgpu_texture_view = dmGraphics::WebGPUGetTextureView(m_GraphicsContext, m_BackingTexture); + m_BackingTextureView = wgpu::TextureView::Acquire(webgpu_texture_view); + m_RenderTarget->setTargetTextureView(m_BackingTextureView); - dmGraphics::SetTexture(m_BackingTexture, tp); + m_RenderToTexture = true; + } + else + { + dmGraphics::HTexture frame_buffer = dmGraphics::WebGPUGetActiveSwapChainTexture(m_GraphicsContext); + WGPUTextureView webgpu_texture_view = dmGraphics::WebGPUGetTextureView(m_GraphicsContext, frame_buffer); + m_BackingTextureView = wgpu::TextureView::Acquire(webgpu_texture_view); + m_RenderTarget->setTargetTextureView(m_BackingTextureView); - WGPUTextureView webgpu_texture_view = dmGraphics::WebGPUGetTextureView(m_GraphicsContext, m_BackingTexture); - m_BackingTextureView = wgpu::TextureView::Acquire(webgpu_texture_view); - m_RenderTarget->setTargetTextureView(m_BackingTextureView); + m_RenderToTexture = false; + } } void SetGraphicsContext(dmGraphics::HContext graphics_context) override @@ -158,6 +198,8 @@ namespace dmRive wgpu::Device m_Device; wgpu::Queue m_Queue; wgpu::TextureView m_BackingTextureView; + + bool m_RenderToTexture; }; IDefoldRiveRenderer* MakeDefoldRiveRendererWebGPU() diff --git a/defold-rive/src/private/renderer_private.cpp b/defold-rive/src/private/renderer_private.cpp index b9b611a3..c12e3c1e 100644 --- a/defold-rive/src/private/renderer_private.cpp +++ b/defold-rive/src/private/renderer_private.cpp @@ -184,9 +184,12 @@ namespace dmRive int samples = (int) params.m_DoFinalBlit ? 0 : params.m_BackbufferSamples; #if defined(DM_PLATFORM_MACOS) || defined(DM_PLATFORM_IOS) - dmGraphics::HTexture swap_chain_texture = dmGraphics::VulkanGetActiveSwapChainTexture(renderer->m_GraphicsContext); - renderer->m_RenderContext->SetRenderTargetTexture(swap_chain_texture); - samples = 0; + if (!params.m_DoFinalBlit) + { + dmGraphics::HTexture swap_chain_texture = dmGraphics::VulkanGetActiveSwapChainTexture(renderer->m_GraphicsContext); + renderer->m_RenderContext->SetRenderTargetTexture(swap_chain_texture); + samples = 0; + } #endif renderer->m_RenderContext->BeginFrame({ diff --git a/game.project b/game.project index c2d9a699..1fc6d570 100644 --- a/game.project +++ b/game.project @@ -9,7 +9,7 @@ shared_state = 1 width = 960 height = 540 high_dpi = 1 -samples = 4 +samples = 0 [android] input_method = HiddenInputField @@ -41,3 +41,7 @@ clear_color_green = 0.25 clear_color_blue = 0.25 clear_color_alpha = 1.0 + +[rive] +render_to_texture = 0 + diff --git a/wagyu-old.appmanifest b/wagyu-old.appmanifest index 290f017d..b88bdccd 100644 --- a/wagyu-old.appmanifest +++ b/wagyu-old.appmanifest @@ -8,4 +8,4 @@ platforms: flags: ["-std=c++17", "-fno-rtti"] linkFlags: ['-lexports.js', '-lrive_renderer_wagyu_gl'] externalJsPorts: ["ext/wagyu-port/old/webgpu-port.py:wagyu=true"] - emscriptenLinkFlags: [ASYNCIFY=1, ASYNCIFY_IGNORE_INDIRECT=1, 'ASYNCIFY_ADD=["main","dmEngineCreate(*)","requestDeviceCallback(*)","WebGPUConfigure(*)","instanceRequestAdapterCallback(*)"]' ] + emscriptenLinkFlags: [WASM_BIGINT=1, ASYNCIFY=1, ASYNCIFY_IGNORE_INDIRECT=1, 'ASYNCIFY_ADD=["main","dmEngineCreate(*)","requestDeviceCallback(*)","WebGPUConfigure(*)","instanceRequestAdapterCallback(*)"]' ] diff --git a/wagyu.appmanifest b/wagyu.appmanifest index 08ff1504..7b60905b 100644 --- a/wagyu.appmanifest +++ b/wagyu.appmanifest @@ -8,3 +8,4 @@ platforms: flags: ["-std=c++17", "-fno-rtti"] linkFlags: ['-lexports.js', '-lrive_renderer_wagyu'] externalJsPorts: ["ext/wagyu-port/new/webgpu-port.py:wagyu=true"] + emscriptenLinkFlags: [WASM_BIGINT=1]