Add microprofile support (#11403) c83919a247

* Initial commit

* Update macros

* Add GPU Markers

* Fix builds without microprofile

* minor updates

* clang format

* Update profiler.cpp

* clang format

* Name Main Thread

* Update profiler_macros.h

* Fix end flip

* Update fiddle_context_gl.cpp

* clang format

* Update rive_build_config.lua

* Update rive_build_config.lua

* forked microprofile so I can use a tag

* Update render_context_d3d_impl.cpp

* clang

Co-authored-by: John White <aliasbinman@gmail.com>
This commit is contained in:
aliasbinman
2026-01-16 18:31:42 +00:00
parent 9617565e7c
commit decf2d683d
15 changed files with 305 additions and 126 deletions

View File

@@ -1 +1 @@
28e95e51e7823ed149fa5fc323ccc9751bca5356
c83919a2477577deac9afdc2f22b83b9093e4b93

View File

@@ -145,6 +145,13 @@ if _OPTIONS['with_optick'] then
RIVE_OPTICK_VERSION = '1.4.0.0'
end
newoption({ trigger = 'with_microprofile', description = 'use microprofile profiler' })
if _OPTIONS['with_microprofile'] then
defines({ 'RIVE_MICROPROFILE' })
RIVE_MICROPROFILE_URL = 'aliasbinman/microprofile'
RIVE_MICROPROFILE_VERSION = 'rivebuild'
end
location(RIVE_BUILD_OUT)
targetdir(RIVE_BUILD_OUT)
objdir(RIVE_BUILD_OUT .. '/obj')

11
dependencies/premake5_microprofile.lua vendored Normal file
View File

@@ -0,0 +1,11 @@
local dependency = require('dependency')
microprofile = dependency.github(RIVE_MICROPROFILE_URL, RIVE_MICROPROFILE_VERSION)
project('microprofile')
do
kind('StaticLib')
language('C++')
cppdialect('C++11')
files { microprofile .. "/src/embed.c" }
includedirs(microprofile)
end

View File

@@ -14,17 +14,65 @@
// Add to new threads
#if defined(RIVE_OPTICK) // Optick integration
#include "optick_core.h"
#include "optick.h"
#define RIVE_PROF_INIT()
#define RIVE_PROF_FRAME() OPTICK_FRAME("RiveFrame")
#define RIVE_PROF_SCOPE() OPTICK_EVENT()
#define RIVE_PROF_SCOPENAME(name) OPTICK_EVENT(name)
#define RIVE_PROF_GPUNAME(name)
#define RIVE_PROF_TAG(cat, tag) OPTICK_TAG(cat, tag)
#define RIVE_PROF_THREAD(name) OPTICK_THREAD(name)
#define RIVE_PROF_DRAW()
#define RIVE_PROF_TOGGLEDRAW()
#define RIVE_PROF_GPUSUBMIT(i)
#define RIVE_PROF_GPUFLIP()
#define RIVE_PROF_ENDFRAME()
#elif defined(RIVE_MICROPROFILE) // Microprofile integration
#include "microprofile.h"
#include "microprofiledraw.h"
#include "microprofileui.h"
#define MICROPROFILE_WEBSERVER 1
#define MICROPROFILE_GPU_TIMERS 1
#define RIVE_PROF_INIT() \
MicroProfileSetEnableAllGroups(true); \
MicroProfileSetForceEnable(true); \
MicroProfileWebServerStart(); \
MicroProfileOnThreadCreate("MainThread"); \
MicroProfileInit();
#define RIVE_PROF_FRAME()
#define RIVE_PROF_SCOPE() \
MICROPROFILE_SCOPEI(__FILE__, __FUNCTION__, 0xffffffff);
#define RIVE_PROF_SCOPENAME(name) \
MICROPROFILE_SCOPEI("group", name, 0xffffffff);
#define RIVE_PROF_GPUNAME(name) MICROPROFILE_SCOPEGPUI(name, 0xffffffff);
#define RIVE_PROF_TAG(cat, tag)
#define RIVE_PROF_THREAD(name)
#define RIVE_PROF_DRAW() MicroProfileDraw();
#define RIVE_PROF_TOGGLEDRAW() // MicroProfileToggleDisplayMode();
#define RIVE_PROF_GPUSUBMIT(i) MicroProfileGpuSubmit(i);
#define RIVE_PROF_GPUFLIP() // MicroProfileGpuFlip();
#define RIVE_PROF_ENDFRAME() MicroProfileFlip();
#else // No profiler selected - fallback to no-op
#define RIVE_PROF_INIT()
#define RIVE_PROF_FRAME()
#define RIVE_PROF_SCOPE()
#define RIVE_PROF_SCOPENAME(name)
#define RIVE_PROF_GPUNAME(name)
#define RIVE_PROF_TAG(cat, tag)
#define RIVE_PROF_THREAD(name)
#define RIVE_PROF_DRAW()
#define RIVE_PROF_TOGGLEDRAW()
#define RIVE_PROF_GPUSUBMIT(i)
#define RIVE_PROF_GPUFLIP()
#define RIVE_PROF_ENDFRAME()
#endif

View File

@@ -42,6 +42,11 @@ if _OPTIONS['with_optick'] then
dofile(path.join(dependencies, 'premake5_optick.lua'))
end
if _OPTIONS['with_microprofile'] then
dofile(path.join(dependencies, 'premake5_microprofile.lua'))
end
if _OPTIONS['with_rive_scripting'] then
local scripting = require(path.join(path.getabsolute('scripting/'), 'premake5'))
luau = scripting.luau
@@ -125,6 +130,10 @@ do
includedirs({ optick .. '/src' })
end
if _OPTIONS['with_microprofile'] then
includedirs({microprofile})
end
filter('system:macosx or system:ios')
do
files({ 'src/text/font_hb_apple.mm' })

View File

@@ -193,6 +193,8 @@ public:
if (!m_isHeadless)
m_swapchain->Present(0, 0);
RIVE_PROF_ENDFRAME()
m_renderTarget->setTargetTexture(nullptr);
}

View File

@@ -1,4 +1,5 @@
#include "fiddle_context.hpp"
#include "rive/profiler/profiler_macros.h"
#if !defined(_WIN32) || defined(RIVE_UNREAL)
@@ -160,6 +161,10 @@ public:
IID_PPV_ARGS(&m_copyCommandQueue)));
NAME_RAW_D3D12_OBJECT(m_copyCommandQueue);
#if defined(RIVE_MICROPROFILE)
MicroProfileGpuInitD3D12(m_device.Get(), m_commandQueue.Get());
#endif
for (auto i = 0; i < FrameCount; ++i)
{
VERIFY_OK(m_device->CreateCommandAllocator(
@@ -431,6 +436,9 @@ public:
VERIFY_OK(m_commandQueue->Signal(m_fence.Get(),
m_previousFrames[m_frameIndex]));
RIVE_PROF_GPUSUBMIT(0);
RIVE_PROF_ENDFRAME()
}
void flushPLSContext(RenderTarget* offscreenRenderTarget) final
@@ -447,7 +455,9 @@ public:
VERIFY_OK(m_copyCommandList->Reset(m_copyAllocators[m_frameIndex].Get(),
NULL));
#if defined(RIVE_MICROPROFILE)
MicroProfileGpuSetContext(m_commandList.Get());
#endif
RenderContextD3D12Impl::CommandLists cmdLists = {
m_copyCommandList.Get(),
m_commandList.Get()};
@@ -575,6 +585,8 @@ public:
if (!m_isHeadless)
m_swapChain->Present(0, 0);
RIVE_PROF_GPUFLIP();
}
private:

View File

@@ -13,6 +13,7 @@ std::unique_ptr<FiddleContext> FiddleContext::MakeGLPLS(FiddleContextOptions)
#include "rive/renderer/rive_renderer.hpp"
#include "rive/renderer/gl/render_context_gl_impl.hpp"
#include "rive/renderer/gl/render_target_gl.hpp"
#include "rive/profiler/profiler_macros.h"
#ifdef RIVE_WEBGL
#include <emscripten/emscripten.h>
@@ -169,6 +170,7 @@ public:
GL_NEAREST);
glDisable(GL_SCISSOR_TEST);
}
RIVE_PROF_ENDFRAME()
}
protected:

View File

@@ -341,7 +341,15 @@ static void key_callback(GLFWwindow* window,
clockwiseFill = !clockwiseFill;
break;
case GLFW_KEY_P:
paused = !paused;
if (!shift)
{
paused = !paused;
}
else
{
RIVE_PROF_TOGGLEDRAW();
}
break;
case GLFW_KEY_H:
if (!shift)
@@ -427,6 +435,8 @@ int main(int argc, const char** argv)
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
RIVE_PROF_INIT()
#ifdef DEBUG
options.enableVulkanCoreValidationLayers = true;
#endif

View File

@@ -94,6 +94,11 @@ if not _OPTIONS['with-webgpu'] then
externalincludedirs({ optick .. '/src'})
end
if _OPTIONS['with_microprofile'] then
links({'microprofile'})
externalincludedirs({ microprofile})
end
if rive_target_os == 'windows' then
externalincludedirs({
dx12_headers .. '/include/directx',

View File

@@ -183,6 +183,10 @@ if _OPTIONS['with_optick'] then
optick = dependency.github(RIVE_OPTICK_URL, RIVE_OPTICK_VERSION)
end
if _OPTIONS['with_microprofile'] then
microprofile = dependency.github(RIVE_MICROPROFILE_URL, RIVE_MICROPROFILE_VERSION)
end
project('rive_pls_renderer')
do
kind('StaticLib')
@@ -204,6 +208,10 @@ do
includedirs({optick .. '/src'})
end
if _OPTIONS['with_microprofile'] then
includedirs({ microprofile })
end
if _OPTIONS['with_vulkan'] then
externalincludedirs({
vulkan_headers .. '/include',

View File

@@ -7,6 +7,7 @@
#include "rive/renderer/d3d/d3d_constants.hpp"
#include "rive/renderer/texture.hpp"
#include "rive/profiler/profiler_macros.h"
#include <D3DCompiler.h>
@@ -408,6 +409,9 @@ std::unique_ptr<RenderContext> RenderContextD3DImpl::MakeContext(
ComPtr<ID3D11DeviceContext> gpuContext,
const D3DContextOptions& contextOptions)
{
#if defined(RIVE_MICROPROFILE)
MicroProfileGpuInitD3D11(gpu.Get());
#endif
D3DCapabilities d3dCapabilities;
D3D11_FEATURE_DATA_D3D11_OPTIONS2 d3d11Options2;
@@ -1544,6 +1548,8 @@ void RenderContextD3DImpl::flush(const FlushDescriptor& desc)
// Tessellate all curves into vertices in the tessellation texture.
if (desc.tessVertexSpanCount > 0)
{
RIVE_PROF_GPUNAME("Tessellate Curves");
ID3D11Buffer* tessSpanBuffer =
flush_buffer(m_gpuContext.Get(), tessSpanBufferRing());
UINT tessStride = sizeof(TessVertexSpan);
@@ -1626,6 +1632,8 @@ void RenderContextD3DImpl::flush(const FlushDescriptor& desc)
// Render the atlas if we have any offscreen feathers.
if ((desc.atlasFillBatchCount | desc.atlasStrokeBatchCount) != 0)
{
RIVE_PROF_GPUNAME("atlasRender");
float clearZero[4]{};
m_gpuContext->ClearRenderTargetView(m_atlasTextureRTV.Get(), clearZero);
@@ -1708,60 +1716,70 @@ void RenderContextD3DImpl::flush(const FlushDescriptor& desc)
}
// Setup and clear the PLS textures.
switch (desc.colorLoadAction)
{
case gpu::LoadAction::clear:
if (desc.fixedFunctionColorOutput)
{
float clearColor4f[4];
UnpackColorToRGBA32FPremul(desc.colorClearValue, clearColor4f);
m_gpuContext->ClearRenderTargetView(renderTarget->targetRTV(),
clearColor4f);
}
else if (m_d3dCapabilities.supportsTypedUAVLoadStore)
{
float clearColor4f[4];
UnpackColorToRGBA32FPremul(desc.colorClearValue, clearColor4f);
m_gpuContext->ClearUnorderedAccessViewFloat(
renderTarget->targetUAV(),
clearColor4f);
}
else
{
UINT clearColorui[4] = {
gpu::SwizzleRiveColorToRGBAPremul(desc.colorClearValue)};
m_gpuContext->ClearUnorderedAccessViewUint(
renderTarget->targetUAV(),
clearColorui);
}
break;
case gpu::LoadAction::preserveRenderTarget:
if (!desc.fixedFunctionColorOutput &&
!renderTarget->targetTextureSupportsUAV())
{
// We're rendering to an offscreen UAV and preserving the
// target. Copy the target texture over.
blit_sub_rect(m_gpuContext.Get(),
renderTarget->offscreenTexture(),
renderTarget->targetTexture(),
desc.renderTargetUpdateBounds);
}
break;
case gpu::LoadAction::dontCare:
break;
}
if (desc.combinedShaderFeatures & gpu::ShaderFeatures::ENABLE_CLIPPING)
{
constexpr static UINT kZero[4]{};
m_gpuContext->ClearUnorderedAccessViewUint(renderTarget->clipUAV(),
kZero);
}
{
UINT coverageClear[4]{desc.coverageClearValue};
m_gpuContext->ClearUnorderedAccessViewUint(renderTarget->coverageUAV(),
coverageClear);
RIVE_PROF_GPUNAME("clearPLSTextures");
switch (desc.colorLoadAction)
{
case gpu::LoadAction::clear:
if (desc.fixedFunctionColorOutput)
{
float clearColor4f[4];
UnpackColorToRGBA32FPremul(desc.colorClearValue,
clearColor4f);
m_gpuContext->ClearRenderTargetView(
renderTarget->targetRTV(),
clearColor4f);
}
else if (m_d3dCapabilities.supportsTypedUAVLoadStore)
{
float clearColor4f[4];
UnpackColorToRGBA32FPremul(desc.colorClearValue,
clearColor4f);
m_gpuContext->ClearUnorderedAccessViewFloat(
renderTarget->targetUAV(),
clearColor4f);
}
else
{
UINT clearColorui[4] = {gpu::SwizzleRiveColorToRGBAPremul(
desc.colorClearValue)};
m_gpuContext->ClearUnorderedAccessViewUint(
renderTarget->targetUAV(),
clearColorui);
}
break;
case gpu::LoadAction::preserveRenderTarget:
if (!desc.fixedFunctionColorOutput &&
!renderTarget->targetTextureSupportsUAV())
{
// We're rendering to an offscreen UAV and preserving the
// target. Copy the target texture over.
blit_sub_rect(m_gpuContext.Get(),
renderTarget->offscreenTexture(),
renderTarget->targetTexture(),
desc.renderTargetUpdateBounds);
}
break;
case gpu::LoadAction::dontCare:
break;
}
if (desc.combinedShaderFeatures & gpu::ShaderFeatures::ENABLE_CLIPPING)
{
constexpr static UINT kZero[4]{};
m_gpuContext->ClearUnorderedAccessViewUint(renderTarget->clipUAV(),
kZero);
}
{
UINT coverageClear[4]{desc.coverageClearValue};
m_gpuContext->ClearUnorderedAccessViewUint(
renderTarget->coverageUAV(),
coverageClear);
}
}
RIVE_PROF_GPUNAME("DrawList");
// Execute the DrawList.
ID3D11RenderTargetView* targetRTV =
desc.fixedFunctionColorOutput ? renderTarget->targetRTV() : NULL;
@@ -1892,6 +1910,7 @@ void RenderContextD3DImpl::flush(const FlushDescriptor& desc)
&drawUniforms,
0,
0);
RIVE_PROF_GPUNAME("Patches");
m_gpuContext->DrawIndexedInstanced(PatchIndexCount(drawType),
batch.elementCount,
PatchBaseIndex(drawType),
@@ -1906,11 +1925,16 @@ void RenderContextD3DImpl::flush(const FlushDescriptor& desc)
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
m_gpuContext->RSSetState(
m_backCulledRasterState[desc.wireframe].Get());
RIVE_PROF_GPUNAME(drawType == DrawType::atlasBlit
? "atlasBlit"
: "interiorTriangulation");
m_gpuContext->Draw(batch.elementCount, batch.baseElement);
break;
}
case DrawType::imageRect:
{
RIVE_PROF_GPUNAME("imageRect");
m_gpuContext->IASetPrimitiveTopology(
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
m_gpuContext->IASetIndexBuffer(m_imageRectIndexBuffer.Get(),
@@ -1932,6 +1956,7 @@ void RenderContextD3DImpl::flush(const FlushDescriptor& desc)
}
case DrawType::imageMesh:
{
RIVE_PROF_GPUNAME("imageMesh");
LITE_RTTI_CAST_OR_BREAK(vertexBuffer,
RenderBufferD3DImpl*,
batch.vertexBuffer);
@@ -1972,6 +1997,9 @@ void RenderContextD3DImpl::flush(const FlushDescriptor& desc)
break;
}
case DrawType::renderPassResolve:
{
RIVE_PROF_GPUNAME("renderPassResolve");
assert(desc.interlockMode == gpu::InterlockMode::atomics);
m_gpuContext->IASetPrimitiveTopology(
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
@@ -2010,7 +2038,8 @@ void RenderContextD3DImpl::flush(const FlushDescriptor& desc)
NULL);
}
m_gpuContext->Draw(4, 0);
break;
}
break;
case DrawType::msaaStrokes:
case DrawType::msaaMidpointFanBorrowedCoverage:
case DrawType::msaaMidpointFans:
@@ -2027,6 +2056,8 @@ void RenderContextD3DImpl::flush(const FlushDescriptor& desc)
if (desc.interlockMode == gpu::InterlockMode::rasterOrdering &&
!renderTarget->targetTextureSupportsUAV())
{
RIVE_PROF_GPUNAME("blit_sub_rect");
// We rendered to an offscreen UAV and did not resolve to the
// renderTarget. Copy back to the main target.
assert(!desc.fixedFunctionColorOutput);

View File

@@ -4,6 +4,8 @@
#include "rive/renderer/d3d12/render_context_d3d12_impl.hpp"
#include "rive/renderer/d3d/d3d_constants.hpp"
#include "rive/profiler/profiler_macros.h"
// needed for root sig and heap constants
#include "shaders/d3d/root.sig"
@@ -1108,6 +1110,8 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc)
if (desc.tessVertexSpanCount)
{
RIVE_PROF_GPUNAME("Tessellate Curves");
m_resourceManager->transition(cmdList,
m_tesselationTexture.get(),
D3D12_RESOURCE_STATE_RENDER_TARGET);
@@ -1190,6 +1194,7 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc)
if ((desc.atlasFillBatchCount | desc.atlasStrokeBatchCount) != 0)
{
RIVE_PROF_GPUNAME("atlasRender");
m_resourceManager->transition(cmdList,
m_atlasTexture.get(),
D3D12_RESOURCE_STATE_RENDER_TARGET);
@@ -1278,88 +1283,95 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc)
cmdList->RSSetScissorRects(1, &scissorRect);
// Setup and clear the PLS textures.
if (desc.fixedFunctionColorOutput)
{
m_resourceManager->transition(cmdList,
targetTexture,
D3D12_RESOURCE_STATE_RENDER_TARGET);
auto rtvHandle = m_rtvHeap->cpuHandleForIndex(TARGET_RTV_HEAP_OFFSET);
cmdList->OMSetRenderTargets(1, &rtvHandle, FALSE, nullptr);
if (desc.colorLoadAction == gpu::LoadAction::clear)
RIVE_PROF_GPUNAME("clearPLSTextures");
if (desc.fixedFunctionColorOutput)
{
float clearColor4f[4];
UnpackColorToRGBA32FPremul(desc.colorClearValue, clearColor4f);
cmdList->ClearRenderTargetView(rtvHandle, clearColor4f, 0, nullptr);
}
}
else // !desc.fixedFunctionColorOutput
{
if (renderTarget->targetTextureSupportsUAV())
{
m_resourceManager->transition(
cmdList,
targetTexture,
D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
}
m_resourceManager->transition(cmdList,
targetTexture,
D3D12_RESOURCE_STATE_RENDER_TARGET);
if (desc.colorLoadAction == gpu::LoadAction::clear)
{
auto tex = renderTarget->targetTextureSupportsUAV()
? renderTarget->targetTexture()->resource()
: renderTarget->offscreenTexture()->resource();
auto rtvHandle =
m_rtvHeap->cpuHandleForIndex(TARGET_RTV_HEAP_OFFSET);
cmdList->OMSetRenderTargets(1, &rtvHandle, FALSE, nullptr);
if (m_capabilities.supportsTypedUAVLoadStore)
if (desc.colorLoadAction == gpu::LoadAction::clear)
{
float clearColor4f[4];
UnpackColorToRGBA32FPremul(desc.colorClearValue, clearColor4f);
auto gpuHandle = m_srvUavCbvHeap->gpuHandleForIndex(
ATOMIC_COLOR_HEAP_OFFSET);
auto cpuHandle = m_cpuSrvUavCbvHeap->cpuHandleForIndex(
ATOMIC_COLOR_HEAP_OFFSET);
m_resourceManager->clearUAV(cmdList,
tex,
gpuHandle,
cpuHandle,
clearColor4f,
desc.interlockMode ==
InterlockMode::atomics);
}
else
{
UINT clearColorui[4] = {
gpu::SwizzleRiveColorToRGBAPremul(desc.colorClearValue)};
auto gpuHandle = m_srvUavCbvHeap->gpuHandleForIndex(
ATOMIC_COLOR_HEAP_OFFSET);
auto cpuHandle = m_cpuSrvUavCbvHeap->cpuHandleForIndex(
ATOMIC_COLOR_HEAP_OFFSET);
m_resourceManager->clearUAV(cmdList,
tex,
gpuHandle,
cpuHandle,
clearColorui,
desc.interlockMode ==
InterlockMode::atomics);
cmdList->ClearRenderTargetView(rtvHandle,
clearColor4f,
0,
nullptr);
}
}
if (desc.colorLoadAction == gpu::LoadAction::preserveRenderTarget &&
!renderTarget->targetTextureSupportsUAV())
else // !desc.fixedFunctionColorOutput
{
auto offscreenTex = renderTarget->offscreenTexture();
blitSubRect(cmdList,
offscreenTex,
renderTarget->targetTexture(),
desc.renderTargetUpdateBounds);
if (renderTarget->targetTextureSupportsUAV())
{
m_resourceManager->transition(
cmdList,
targetTexture,
D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
}
m_resourceManager->transition(
cmdList,
offscreenTex,
D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
if (desc.colorLoadAction == gpu::LoadAction::clear)
{
auto tex = renderTarget->targetTextureSupportsUAV()
? renderTarget->targetTexture()->resource()
: renderTarget->offscreenTexture()->resource();
if (m_capabilities.supportsTypedUAVLoadStore)
{
float clearColor4f[4];
UnpackColorToRGBA32FPremul(desc.colorClearValue,
clearColor4f);
auto gpuHandle = m_srvUavCbvHeap->gpuHandleForIndex(
ATOMIC_COLOR_HEAP_OFFSET);
auto cpuHandle = m_cpuSrvUavCbvHeap->cpuHandleForIndex(
ATOMIC_COLOR_HEAP_OFFSET);
m_resourceManager->clearUAV(cmdList,
tex,
gpuHandle,
cpuHandle,
clearColor4f,
desc.interlockMode ==
InterlockMode::atomics);
}
else
{
UINT clearColorui[4] = {gpu::SwizzleRiveColorToRGBAPremul(
desc.colorClearValue)};
auto gpuHandle = m_srvUavCbvHeap->gpuHandleForIndex(
ATOMIC_COLOR_HEAP_OFFSET);
auto cpuHandle = m_cpuSrvUavCbvHeap->cpuHandleForIndex(
ATOMIC_COLOR_HEAP_OFFSET);
m_resourceManager->clearUAV(cmdList,
tex,
gpuHandle,
cpuHandle,
clearColorui,
desc.interlockMode ==
InterlockMode::atomics);
}
}
if (desc.colorLoadAction == gpu::LoadAction::preserveRenderTarget &&
!renderTarget->targetTextureSupportsUAV())
{
auto offscreenTex = renderTarget->offscreenTexture();
blitSubRect(cmdList,
offscreenTex,
renderTarget->targetTexture(),
desc.renderTargetUpdateBounds);
m_resourceManager->transition(
cmdList,
offscreenTex,
D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
}
}
}
@@ -1412,6 +1424,7 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc)
m_heapDescriptorOffset += imageDescriptorOffset;
RIVE_PROF_GPUNAME("DrawList");
for (const DrawBatch& batch : *desc.drawList)
{
assert(batch.elementCount != 0);
@@ -1544,6 +1557,7 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc)
case DrawType::midpointFanCenterAAPatches:
case DrawType::outerCurvePatches:
{
RIVE_PROF_GPUNAME("Patches");
cmdList->IASetPrimitiveTopology(
D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
auto IBV = m_pathPatchIndexBuffer->indexBufferView();
@@ -1562,6 +1576,7 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc)
case DrawType::interiorTriangulation:
case DrawType::atlasBlit:
{
RIVE_PROF_GPUNAME("interiorTriangulation||atlasBlit");
cmdList->IASetPrimitiveTopology(
D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
cmdList->DrawInstanced(batch.elementCount,
@@ -1572,6 +1587,8 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc)
}
case DrawType::imageRect:
{
RIVE_PROF_GPUNAME("imageRect");
cmdList->IASetPrimitiveTopology(
D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
auto IBV = m_imageRectIndexBuffer->indexBufferView();
@@ -1592,6 +1609,8 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc)
}
case DrawType::imageMesh:
{
RIVE_PROF_GPUNAME("imageMesh");
LITE_RTTI_CAST_OR_BREAK(vertexBuffer,
RenderBufferD3D12Impl*,
batch.vertexBuffer);
@@ -1633,11 +1652,16 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc)
break;
}
case DrawType::renderPassResolve:
{
RIVE_PROF_GPUNAME("renderPassResolve");
assert(desc.interlockMode == gpu::InterlockMode::atomics);
cmdList->IASetPrimitiveTopology(
D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
cmdList->DrawInstanced(4, 1, 0, 0);
break;
}
case DrawType::msaaStrokes:
case DrawType::msaaMidpointFanBorrowedCoverage:
case DrawType::msaaMidpointFans:
@@ -1654,6 +1678,8 @@ void RenderContextD3D12Impl::flush(const FlushDescriptor& desc)
if (desc.interlockMode == gpu::InterlockMode::rasterOrdering &&
!renderTarget->targetTextureSupportsUAV())
{
RIVE_PROF_GPUNAME("blit_sub_rect");
// We rendered to an offscreen UAV and did not resolve to the
// renderTarget. Copy back to the main target.
assert(!desc.fixedFunctionColorOutput);

View File

@@ -0,0 +1,8 @@
#ifdef RIVE_MICROPROFILE
#define MICROPROFILE_IMPL
#if defined(RIVE_WINDOWS)
#define MICROPROFILE_GPU_TIMERS_D3D11 1
#define MICROPROFILE_GPU_TIMERS_D3D12 1
#endif
#include "microprofile.h"
#endif