Skip to content

Commit b79e530

Browse files
authored
Basic support of MSAA for render targets (#1261)
This is the native counter part to BabylonJS/Babylon.js#14055.
1 parent 88d09c8 commit b79e530

File tree

5 files changed

+64
-4
lines changed

5 files changed

+64
-4
lines changed

Plugins/ExternalTexture/Source/ExternalTexture_Base.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,23 @@ namespace Babylon::Plugins
4444
return mipLevel == static_cast<uint16_t>(std::floor(std::log2(std::max(static_cast<float>(width), static_cast<float>(height))) + 1));
4545
}
4646

47+
static auto RenderTargetSamplesToBgfxMsaaFlag(uint32_t renderTargetSamples)
48+
{
49+
switch (renderTargetSamples)
50+
{
51+
case 2:
52+
return BGFX_TEXTURE_RT_MSAA_X2;
53+
case 4:
54+
return BGFX_TEXTURE_RT_MSAA_X4;
55+
case 8:
56+
return BGFX_TEXTURE_RT_MSAA_X8;
57+
case 16:
58+
return BGFX_TEXTURE_RT_MSAA_X16;
59+
}
60+
61+
return BGFX_TEXTURE_NONE;
62+
}
63+
4764
void UpdateHandles(uintptr_t ptr)
4865
{
4966
std::scoped_lock lock{m_mutex};

Plugins/ExternalTexture/Source/ExternalTexture_D3D11.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,11 @@ namespace Babylon::Plugins
189189
if ((desc.BindFlags & D3D11_BIND_RENDER_TARGET) != 0)
190190
{
191191
info.Flags |= BGFX_TEXTURE_RT;
192+
193+
if (desc.SampleDesc.Count > 1)
194+
{
195+
info.Flags |= BGFX_TEXTURE_MSAA_SAMPLE | RenderTargetSamplesToBgfxMsaaFlag(desc.SampleDesc.Count);
196+
}
192197
}
193198

194199
for (int i = 0; i < BX_COUNTOF(s_textureFormat); ++i)

Plugins/ExternalTexture/Source/ExternalTexture_D3D12.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,11 @@ namespace Babylon::Plugins
183183
if ((desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) != 0)
184184
{
185185
info.Flags |= BGFX_TEXTURE_RT;
186+
187+
if (desc.SampleDesc.Count > 1)
188+
{
189+
info.Flags |= BGFX_TEXTURE_MSAA_SAMPLE | RenderTargetSamplesToBgfxMsaaFlag(desc.SampleDesc.Count);
190+
}
186191
}
187192

188193
for (int i = 0; i < BX_COUNTOF(s_textureFormat); ++i)

Plugins/ExternalTexture/Source/ExternalTexture_Metal.mm

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ uintptr_t Ptr() const
136136
private:
137137
void GetInfo(Graphics::TextureT ptr, Info& info)
138138
{
139-
if (ptr.textureType != MTLTextureType2D)
139+
if (ptr.textureType != MTLTextureType2D && ptr.textureType != MTLTextureType2DMultisample)
140140
{
141141
throw std::runtime_error{"Unsupported texture type"};
142142
}
@@ -148,6 +148,11 @@ void GetInfo(Graphics::TextureT ptr, Info& info)
148148
if ((ptr.usage & MTLTextureUsageRenderTarget) != 0)
149149
{
150150
info.Flags |= BGFX_TEXTURE_RT;
151+
152+
if (ptr.sampleCount > 1)
153+
{
154+
info.Flags |= BGFX_TEXTURE_MSAA_SAMPLE | RenderTargetSamplesToBgfxMsaaFlag(ptr.sampleCount);
155+
}
151156
}
152157

153158
const auto pixelFormat = m_ptr.pixelFormat;

Plugins/NativeEngine/Source/NativeEngine.cpp

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,23 @@ namespace Babylon
289289
}
290290
}
291291

292+
auto RenderTargetSamplesToBgfxMsaaFlag(uint32_t renderTargetSamples)
293+
{
294+
switch (renderTargetSamples)
295+
{
296+
case 2:
297+
return BGFX_TEXTURE_RT_MSAA_X2;
298+
case 4:
299+
return BGFX_TEXTURE_RT_MSAA_X4;
300+
case 8:
301+
return BGFX_TEXTURE_RT_MSAA_X8;
302+
case 16:
303+
return BGFX_TEXTURE_RT_MSAA_X16;
304+
}
305+
306+
return BGFX_TEXTURE_NONE;
307+
}
308+
292309
using CommandFunctionPointerT = void (NativeEngine::*)(NativeDataStream::Reader&);
293310
}
294311

@@ -1085,11 +1102,17 @@ namespace Babylon
10851102
const bgfx::TextureFormat::Enum format = static_cast<bgfx::TextureFormat::Enum>(info[4].As<Napi::Number>().Uint32Value());
10861103
const bool renderTarget = info[5].As<Napi::Boolean>();
10871104
const bool srgb = info[6].As<Napi::Boolean>();
1105+
const uint32_t samples = info[7].IsUndefined() ? 1 : info[7].As<Napi::Number>().Uint32Value();
10881106

10891107
auto flags = BGFX_TEXTURE_NONE;
10901108
if (renderTarget)
10911109
{
10921110
flags |= BGFX_TEXTURE_RT;
1111+
1112+
if (samples > 1)
1113+
{
1114+
flags |= BGFX_TEXTURE_MSAA_SAMPLE | RenderTargetSamplesToBgfxMsaaFlag(samples);
1115+
}
10931116
}
10941117
if (srgb)
10951118
{
@@ -1517,6 +1540,7 @@ namespace Babylon
15171540
const uint16_t height = static_cast<uint16_t>(info[2].As<Napi::Number>().Uint32Value());
15181541
const bool generateStencilBuffer = info[3].As<Napi::Boolean>();
15191542
const bool generateDepth = info[4].As<Napi::Boolean>();
1543+
const uint32_t samples = info[5].IsUndefined() ? 1 : info[5].As<Napi::Number>().Uint32Value();
15201544

15211545
std::array<bgfx::Attachment, 2> attachments{};
15221546
uint8_t numAttachments = 0;
@@ -1534,18 +1558,22 @@ namespace Babylon
15341558
JsConsoleLogger::LogWarn(info.Env(), "Stencil without depth is not supported, assuming depth and stencil");
15351559
}
15361560

1561+
auto flags = BGFX_TEXTURE_RT_WRITE_ONLY | RenderTargetSamplesToBgfxMsaaFlag(samples);
15371562
const auto depthStencilFormat{generateStencilBuffer ? bgfx::TextureFormat::D24S8 : bgfx::TextureFormat::D32};
1538-
assert(bgfx::isTextureValid(0, false, 1, depthStencilFormat, BGFX_TEXTURE_RT));
1563+
assert(bgfx::isTextureValid(0, false, 1, depthStencilFormat, flags));
15391564

15401565
// bgfx doesn't add flag D3D11_RESOURCE_MISC_GENERATE_MIPS for depth textures (missing that flag will crash D3D with resolving)
15411566
// And not sure it makes sense to generate mipmaps from a depth buffer with exponential values.
15421567
// only allows mipmaps resolve step when mipmapping is asked and for the color texture, not the depth.
15431568
// https://github.com/bkaradzic/bgfx/blob/2c21f68998595fa388e25cb6527e82254d0e9bff/src/renderer_d3d11.cpp#L4525
1544-
attachments[numAttachments++].init(bgfx::createTexture2D(width, height, false, 1, depthStencilFormat, BGFX_TEXTURE_RT));
1569+
attachments[numAttachments++].init(bgfx::createTexture2D(width, height, false, 1, depthStencilFormat, flags));
15451570
}
15461571

15471572
bgfx::FrameBufferHandle frameBufferHandle = bgfx::createFrameBuffer(numAttachments, attachments.data(), true);
1548-
assert(bgfx::isValid(frameBufferHandle));
1573+
if (!bgfx::isValid(frameBufferHandle))
1574+
{
1575+
throw Napi::Error::New(info.Env(), "Failed to create frame buffer");
1576+
}
15491577

15501578
Graphics::FrameBuffer* frameBuffer = new Graphics::FrameBuffer(m_graphicsContext, frameBufferHandle, width, height, false, generateDepth, generateStencilBuffer);
15511579
return Napi::Pointer<Graphics::FrameBuffer>::Create(info.Env(), frameBuffer, Napi::NapiPointerDeleter(frameBuffer));

0 commit comments

Comments
 (0)