diff --git a/bindings/bf/bgfx.bf b/bindings/bf/bgfx.bf
index 8e9c725c8..e8eb860c2 100644
--- a/bindings/bf/bgfx.bf
+++ b/bindings/bf/bgfx.bf
@@ -4423,7 +4423,8 @@ public static class bgfx
///
/// Set view clear flags with different clear color for each
/// frame buffer texture. `bgfx::setPaletteColor` must be used to set up a
- /// clear color palette.
+ /// clear color palette. Frame buffer attachment with palette index set to
+ /// `UINT8_MAX` is not cleared.
///
///
/// View id.
diff --git a/bindings/c3/bgfx.c3 b/bindings/c3/bgfx.c3
index 00fe21ba2..f1ce29729 100644
--- a/bindings/c3/bgfx.c3
+++ b/bindings/c3/bgfx.c3
@@ -3230,7 +3230,8 @@ extern fn void set_view_clear(ushort _id, ushort _flags, uint _rgba, float _dept
// Set view clear flags with different clear color for each
// frame buffer texture. `bgfx::setPaletteColor` must be used to set up a
-// clear color palette.
+// clear color palette. Frame buffer attachment with palette index set to
+// `UINT8_MAX` is not cleared.
// _id : `View id.`
// _flags : `Clear flags. Use `BGFX_CLEAR_NONE` to remove any clear operation. See: `BGFX_CLEAR_*`.`
// _depth : `Depth clear value.`
diff --git a/bindings/cs/bgfx.cs b/bindings/cs/bgfx.cs
index 4773f01fc..d0e3b751d 100644
--- a/bindings/cs/bgfx.cs
+++ b/bindings/cs/bgfx.cs
@@ -4370,7 +4370,8 @@ public static partial class bgfx
///
/// Set view clear flags with different clear color for each
/// frame buffer texture. `bgfx::setPaletteColor` must be used to set up a
- /// clear color palette.
+ /// clear color palette. Frame buffer attachment with palette index set to
+ /// `UINT8_MAX` is not cleared.
///
///
/// View id.
diff --git a/bindings/d/package.d b/bindings/d/package.d
index 5d3d4eb43..328493016 100644
--- a/bindings/d/package.d
+++ b/bindings/d/package.d
@@ -3764,7 +3764,8 @@ mixin(joinFnBinds((){
/**
* Set view clear flags with different clear color for each
* frame buffer texture. `bgfx::setPaletteColor` must be used to set up a
- * clear color palette.
+ * clear color palette. Frame buffer attachment with palette index set to
+ * `UINT8_MAX` is not cleared.
Params:
id = View id.
flags = Clear flags. Use `BGFX_CLEAR_NONE` to remove any clear
diff --git a/bindings/py/bgfx.pyi b/bindings/py/bgfx.pyi
index 662348e28..bcb7bbb60 100644
--- a/bindings/py/bgfx.pyi
+++ b/bindings/py/bgfx.pyi
@@ -2613,7 +2613,8 @@ def bgfx_set_view_clear(_id: int, _flags: int, _rgba: int, _depth: float, _stenc
# Set view clear flags with different clear color for each
# frame buffer texture. `bgfx::setPaletteColor` must be used to set up a
-# clear color palette.
+# clear color palette. Frame buffer attachment with palette index set to
+# `UINT8_MAX` is not cleared.
def bgfx_set_view_clear_mrt(
_id: int,
_flags: int,
diff --git a/bindings/zig/bgfx.zig b/bindings/zig/bgfx.zig
index d95d2fcff..0f1df0bfd 100644
--- a/bindings/zig/bgfx.zig
+++ b/bindings/zig/bgfx.zig
@@ -3627,7 +3627,8 @@ extern fn bgfx_set_view_clear(_id: ViewId, _flags: u16, _rgba: u32, _depth: f32,
/// Set view clear flags with different clear color for each
/// frame buffer texture. `bgfx::setPaletteColor` must be used to set up a
-/// clear color palette.
+/// clear color palette. Frame buffer attachment with palette index set to
+/// `UINT8_MAX` is not cleared.
/// View id.
/// Clear flags. Use `BGFX_CLEAR_NONE` to remove any clear operation. See: `BGFX_CLEAR_*`.
/// Depth clear value.
diff --git a/include/bgfx/bgfx.h b/include/bgfx/bgfx.h
index 59ad1bfe8..dd12739b8 100644
--- a/include/bgfx/bgfx.h
+++ b/include/bgfx/bgfx.h
@@ -4202,7 +4202,8 @@ namespace bgfx
/// Set view clear flags with different clear color for each
/// frame buffer texture. `bgfx::setPaletteColor` must be used to set up a
- /// clear color palette.
+ /// clear color palette. Frame buffer attachment with palette index set to
+ /// `UINT8_MAX` is not cleared.
///
/// @param[in] _id View id.
/// @param[in] _flags Clear flags. Use `BGFX_CLEAR_NONE` to remove any clear
diff --git a/include/bgfx/c99/bgfx.h b/include/bgfx/c99/bgfx.h
index ba01a3bd9..be7f818d9 100644
--- a/include/bgfx/c99/bgfx.h
+++ b/include/bgfx/c99/bgfx.h
@@ -2928,7 +2928,8 @@ BGFX_C_API void bgfx_set_view_clear(bgfx_view_id_t _id, uint16_t _flags, uint32_
/**
* Set view clear flags with different clear color for each
* frame buffer texture. `bgfx::setPaletteColor` must be used to set up a
- * clear color palette.
+ * clear color palette. Frame buffer attachment with palette index set to
+ * `UINT8_MAX` is not cleared.
*
* @param[in] _id View id.
* @param[in] _flags Clear flags. Use `BGFX_CLEAR_NONE` to remove any clear
diff --git a/scripts/bgfx.idl b/scripts/bgfx.idl
index 1e4d5d531..6ed1a4f62 100644
--- a/scripts/bgfx.idl
+++ b/scripts/bgfx.idl
@@ -2557,7 +2557,8 @@ func.setViewClear { section = "Views" }
--- Set view clear flags with different clear color for each
--- frame buffer texture. `bgfx::setPaletteColor` must be used to set up a
---- clear color palette.
+--- clear color palette. Frame buffer attachment with palette index set to
+--- `UINT8_MAX` is not cleared.
func.setViewClear { cname = "set_view_clear_mrt", section = "Views" }
"void"
.id "ViewId" --- View id.
diff --git a/src/bgfx.cpp b/src/bgfx.cpp
index 1545fc8c5..b90f36151 100644
--- a/src/bgfx.cpp
+++ b/src/bgfx.cpp
@@ -6209,6 +6209,7 @@ namespace bgfx
, storageSize
, _mem->size
);
+ BX_UNUSED(storageSize);
}
uint32_t size = sizeof(uint32_t)+sizeof(TextureCreate);
@@ -6281,6 +6282,7 @@ namespace bgfx
, storageSize
, _mem->size
);
+ BX_UNUSED(storageSize);
}
uint32_t size = sizeof(uint32_t)+sizeof(TextureCreate);
@@ -6332,6 +6334,7 @@ namespace bgfx
, storageSize
, _mem->size
);
+ BX_UNUSED(storageSize);
}
uint32_t size = sizeof(uint32_t)+sizeof(TextureCreate);
@@ -6701,6 +6704,24 @@ namespace bgfx
void setViewClear(ViewId _id, uint16_t _flags, float _depth, uint8_t _stencil, uint8_t _0, uint8_t _1, uint8_t _2, uint8_t _3, uint8_t _4, uint8_t _5, uint8_t _6, uint8_t _7)
{
BX_ASSERT(checkView(_id), "Invalid view id: %d", _id);
+
+ if (BX_ENABLED(BGFX_CONFIG_DEBUG) )
+ {
+ const uint8_t index[] = { _0, _1, _2, _3, _4, _5, _6, _7 };
+
+ for (uint32_t ii = 0; ii < BX_COUNTOF(index); ++ii)
+ {
+ BX_ASSERT(UINT8_MAX == index[ii] || index[ii] < BGFX_CONFIG_MAX_COLOR_PALETTE
+ , "setViewClear: Invalid palette index %d for frame buffer attachment %d (must be less than BGFX_CONFIG_MAX_COLOR_PALETTE (%d), or UINT8_MAX to leave the attachment unchanged)."
+ , index[ii]
+ , ii
+ , BGFX_CONFIG_MAX_COLOR_PALETTE
+ );
+ }
+
+ BX_UNUSED(index);
+ }
+
s_ctx->setViewClear(_id, _flags, _depth, _stencil, _0, _1, _2, _3, _4, _5, _6, _7);
}
diff --git a/src/bgfx_p.h b/src/bgfx_p.h
index 2656d34bf..e00913827 100644
--- a/src/bgfx_p.h
+++ b/src/bgfx_p.h
@@ -549,6 +549,23 @@ namespace bgfx
m_stencil = _stencil;
}
+ uint8_t getColorSkipMask(uint32_t _num) const
+ {
+ if (0 == (m_flags & BGFX_CLEAR_COLOR_USE_PALETTE) )
+ {
+ return 0;
+ }
+
+ uint8_t mask = 0;
+
+ for (uint32_t ii = 0, num = bx::min(_num, BX_COUNTOF(m_index) ); ii < num; ++ii)
+ {
+ mask |= UINT8_MAX == m_index[ii] ? 1<CreateBlendState(&desc, &bs) );
m_blendStateCache.add(hash, bs);
@@ -3854,10 +3868,6 @@ namespace bgfx { namespace d3d11
: 0
;
- setBlendState(state);
- setDepthStencilState(state, stencil);
- setRasterizerState(state);
-
uint32_t numMrt = 1;
FrameBufferHandle fbh = m_fbh;
if (isValid(fbh) )
@@ -3866,6 +3876,10 @@ namespace bgfx { namespace d3d11
numMrt = bx::max(1, fb.m_num);
}
+ setBlendState(state, 0, UINT32_MAX, uint8_t(~_clear.getColorSkipMask(numMrt) ) );
+ setDepthStencilState(state, stencil);
+ setRasterizerState(state);
+
ProgramD3D11& program = m_program[_clearQuad.m_program[numMrt-1].idx];
m_currentProgram = &program;
diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp
index 61de705df..ee3079b9c 100644
--- a/src/renderer_d3d12.cpp
+++ b/src/renderer_d3d12.cpp
@@ -2128,7 +2128,7 @@ namespace bgfx { namespace d3d12
void shutdown()
{
- m_cmd.finish();
+ finishAll(true);
m_batch.destroy();
DX_RELEASE(m_zeroInitBuffer, 0);
diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp
index f4567435c..5773eeb79 100644
--- a/src/renderer_gl.cpp
+++ b/src/renderer_gl.cpp
@@ -4876,8 +4876,13 @@ namespace bgfx { namespace gl
GLint intClear[4] = {};
+ const bool clearColor = true
+ && 0 != (BGFX_CLEAR_COLOR & _clear.m_flags)
+ && 0 == _clear.getColorSkipMask(1)
+ ;
+
GLuint flags = 0;
- if (BGFX_CLEAR_COLOR & _clear.m_flags)
+ if (clearColor)
{
if (BGFX_CLEAR_COLOR_USE_PALETTE & _clear.m_flags)
{
@@ -4941,7 +4946,7 @@ namespace bgfx { namespace gl
GL_CHECK(glStencilMask(0xff) );
}
- const bool clearColorInt = intColor && 0 != (BGFX_CLEAR_COLOR & _clear.m_flags);
+ const bool clearColorInt = intColor && clearColor;
if (0 != flags
|| clearColorInt)
@@ -5081,10 +5086,36 @@ namespace bgfx { namespace gl
commit(*program.m_constantBuffer);
+ const uint8_t skipMask = _clear.getColorSkipMask(numMrt);
+ GLenum buffers[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
+
+ if (0 != skipMask)
+ {
+ for (uint32_t ii = 0; ii < numMrt; ++ii)
+ {
+ buffers[ii] = 0 != (skipMask & (1<m_rps);
@@ -2971,6 +2973,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
, ProgramHandle _program
, uint8_t _numInstanceData
, uint32_t _sampleMask = UINT32_MAX
+ , uint8_t _mrtMask = UINT8_MAX
)
{
_state &= (0
@@ -2994,7 +2997,8 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
&& m_lastPsoState.m_fbh == _fbh.idx
&& m_lastPsoState.m_numStreams == _numStreams
&& m_lastPsoState.m_numInstanceData == _numInstanceData
- && m_lastPsoState.m_sampleMask == _sampleMask)
+ && m_lastPsoState.m_sampleMask == _sampleMask
+ && m_lastPsoState.m_mrtMask == _mrtMask)
{
bool match = true;
for (uint8_t ii = 0; ii < _numStreams && match; ++ii)
@@ -3015,6 +3019,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
m_lastPsoState.m_numStreams = _numStreams;
m_lastPsoState.m_numInstanceData = _numInstanceData;
m_lastPsoState.m_sampleMask = _sampleMask;
+ m_lastPsoState.m_mrtMask = _mrtMask;
for (uint8_t ii = 0; ii < _numStreams; ++ii)
{
m_lastPsoState.m_layouts[ii] = _layouts[ii];
@@ -3028,6 +3033,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
murmur.add(rgba);
murmur.add(_numInstanceData);
murmur.add(_sampleMask);
+ murmur.add(_mrtMask);
if (!isValid(_fbh) )
{
@@ -3193,6 +3199,17 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
}
}
+ if (UINT8_MAX != _mrtMask)
+ {
+ for (uint32_t ii = 0; ii < frameBufferAttachment; ++ii)
+ {
+ if (0 == (_mrtMask & (1<colorAttachments()->object(ii)->setWriteMask(MTL::ColorWriteMaskNone);
+ }
+ }
+ }
+
pd->setVertexFunction(program.m_vsh->m_function);
pd->setFragmentFunction(program.m_fsh != NULL
? program.m_fsh->getFunction(_sampleMask)
@@ -3688,6 +3705,7 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
uint16_t m_fbh;
uint8_t m_numStreams;
uint8_t m_numInstanceData;
+ uint8_t m_mrtMask;
};
PipelineState m_lastPsoState;
@@ -6289,13 +6307,16 @@ static_assert(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames
if (clearWithRenderPass)
{
+ const uint8_t colorSkipMask = clr.getColorSkipMask(g_caps.limits.maxFBAttachments);
+
for (uint32_t ii = 0; ii < g_caps.limits.maxFBAttachments; ++ii)
{
MTL::RenderPassColorAttachmentDescriptor* desc = renderPassDescriptor->colorAttachments()->object(ii);
if (desc->texture() != NULL)
{
- if (0 != (BGFX_CLEAR_COLOR & clr.m_flags) )
+ if (0 != (BGFX_CLEAR_COLOR & clr.m_flags)
+ && 0 == (colorSkipMask & (1<m_view[view].m_clear.m_flags);
+ const Clear& clr = _render->m_view[view].m_clear;
+
+ const bool partialColorClear = true
+ && 0 != (clr.m_flags & BGFX_CLEAR_COLOR)
+ && 0 != clr.getColorSkipMask(NULL == fb.m_nwh ? fb.m_num : 1)
+ ;
+
+ VkRenderPass renderPass = fb.getRenderPass(partialColorClear
+ ? clr.m_flags & ~BGFX_CLEAR_COLOR
+ : clr.m_flags
+ );
viewState.m_rect = _render->m_view[view].m_rect;
const Rect& rect = _render->m_view[view].m_rect;
@@ -10671,8 +10685,6 @@ VK_DESTROY
VkClearValue clearValues[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS + 1];
uint32_t mrt = 0;
- const Clear& clr = _render->m_view[view].m_clear;
-
for (uint32_t ii = 0; ii < numMrt; ++ii)
{
if (BGFX_CLEAR_COLOR & clr.m_flags)
@@ -10738,10 +10750,16 @@ VK_DESTROY
vkCmdBeginRenderPass(m_commandBuffer, &rpbi, VK_SUBPASS_CONTENTS_INLINE);
beginRenderPass = true;
+
+ if (partialColorClear)
+ {
+ Clear colorClr = clr;
+ colorClr.m_flags &= ~(BGFX_CLEAR_DEPTH|BGFX_CLEAR_STENCIL);
+ clearQuad(renderArea, colorClr, _render->m_colorPalette);
+ }
}
else
{
- const Clear& clr = _render->m_view[view].m_clear;
if (BGFX_CLEAR_NONE != clr.m_flags)
{
Rect clearRect;
diff --git a/src/renderer_webgpu.cpp b/src/renderer_webgpu.cpp
index 046a4b5cb..cc1b76f95 100644
--- a/src/renderer_webgpu.cpp
+++ b/src/renderer_webgpu.cpp
@@ -2567,6 +2567,12 @@ WGPU_IMPORT
, true
, renderBind
, true
+ , false
+ , 0
+ , 0.0f
+ , 0.0f
+ , UINT32_MAX
+ , uint8_t(~_clear.getColorSkipMask(numMrt) )
);
const ProgramWGPU& program = m_program[_clearQuad.m_program[numMrt-1].idx];
@@ -3206,6 +3212,7 @@ WGPU_IMPORT
, float _slopeScale = 0.0f
, float _biasClamp = 0.0f
, uint32_t _sampleMask = UINT32_MAX
+ , uint8_t _mrtMask = UINT8_MAX
)
{
const ProgramWGPU& program = m_program[_program.idx];
@@ -3310,6 +3317,7 @@ WGPU_IMPORT
murmur.add(_slopeScale);
murmur.add(_biasClamp);
murmur.add(_sampleMask);
+ murmur.add(_mrtMask);
const uint32_t hash = murmur.end();
RenderPipeline* renderPipeline = m_renderPipelineCache.find(hash);
@@ -3458,7 +3466,7 @@ WGPU_IMPORT
const bool hasFragmentShader = NULL != program.m_fsh;
const bool bgra8Storage = hasBgra8Storage(entries, entryCount);
- const uint32_t targetCount = hasFragmentShader ? setColorTargetState(blendState, colorTragetState, fb, _state, _rgba) : 0;
+ const uint32_t targetCount = hasFragmentShader ? setColorTargetState(blendState, colorTragetState, fb, _state, _rgba, _mrtMask) : 0;
if (NULL != depthStencilTextureView)
{
@@ -3707,7 +3715,7 @@ WGPU_IMPORT
}
}
- uint32_t setColorTargetState(WGPUBlendState* _outBlendState, WGPUColorTargetState* _outColorTargetState, const FrameBufferWGPU& _fb, uint64_t _state, uint32_t _rgba = 0)
+ uint32_t setColorTargetState(WGPUBlendState* _outBlendState, WGPUColorTargetState* _outColorTargetState, const FrameBufferWGPU& _fb, uint64_t _state, uint32_t _rgba = 0, uint8_t _mrtMask = UINT8_MAX)
{
if (0 == _fb.m_numColorAttachments
&& !_fb.isSwapChain() )
@@ -3807,7 +3815,10 @@ WGPU_IMPORT
.nextInChain = NULL,
.format = format,
.blend = blend,
- .writeMask = writeMask,
+ .writeMask = 0 != (_mrtMask & (1<