From 340ef142c3794bf0a8137daa957cfb82843d69b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D1=80=D0=B0=D0=BD=D0=B8=D0=BC=D0=B8=D1=80=20=D0=9A?= =?UTF-8?q?=D0=B0=D1=80=D0=B0=D1=9F=D0=B8=D1=9B?= Date: Tue, 1 Sep 2026 16:22:18 -0700 Subject: [PATCH] Enable primitive restart for strip topologies. --- src/renderer_d3d12.cpp | 15 +++++++++++++++ src/renderer_gl.cpp | 18 ++++++++++++++++++ src/renderer_gl.h | 4 ++++ src/renderer_vk.cpp | 8 +++++++- src/renderer_webgpu.cpp | 1 + 5 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index 55e046832..c19185ec1 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -3775,6 +3775,7 @@ namespace bgfx { namespace d3d12 , const VertexLayout** _layouts , ProgramHandle _program , uint8_t _numInstanceData + , bool _index32 = false ) { ProgramD3D12& program = m_program[_program.idx]; @@ -3856,6 +3857,7 @@ namespace bgfx { namespace d3d12 murmur.begin(); murmur.add(_state); murmur.add(rgba); + murmur.add(_index32); murmur.add(_stencil); murmur.add(program.m_vsh->m_hash); murmur.add(program.m_vsh->m_attrMask, sizeof(program.m_vsh->m_attrMask) ); @@ -3971,6 +3973,18 @@ namespace bgfx { namespace d3d12 uint8_t primIndex = uint8_t( (_state&BGFX_STATE_PT_MASK) >> BGFX_STATE_PT_SHIFT); desc.PrimitiveTopologyType = s_primInfo[primIndex].m_topologyType; + const uint64_t pt = _state & BGFX_STATE_PT_MASK; + desc.IBStripCutValue = (false + || BGFX_STATE_PT_TRISTRIP == pt + || BGFX_STATE_PT_LINESTRIP == pt + ) + ? (_index32 + ? D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF + : D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF + ) + : D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED + ; + if (isValid(m_fbh) ) { const FrameBufferD3D12& frameBuffer = m_frameBuffers[m_fbh.idx]; @@ -9397,6 +9411,7 @@ namespace bgfx { namespace d3d12 , layouts , key.m_program , uint8_t(draw.m_instanceDataStride/16) + , isValid(draw.m_indexBuffer) && !draw.isIndex16() ); if (currentBindIdx != bindIdx diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index 2e9e30009..397a6c23a 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -8194,6 +8194,11 @@ namespace bgfx { namespace gl } PrimInfo prim = s_primInfo[primIndex]; + const bool primitiveRestartSupported = false + || BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES >= 30) + || s_extension[Extension::ARB_ES3_compatibility].m_supported + ; + GL_CHECK(glPolygonMode(GL_FRONT_AND_BACK , _render->m_debug&BGFX_DEBUG_WIREFRAME ? GL_LINE @@ -8867,6 +8872,19 @@ namespace bgfx { namespace gl const uint64_t pt = newFlags&BGFX_STATE_PT_MASK; primIndex = uint8_t(pt>>BGFX_STATE_PT_SHIFT); prim = s_primInfo[primIndex]; + + if (primitiveRestartSupported) + { + if (BGFX_STATE_PT_TRISTRIP == pt + || BGFX_STATE_PT_LINESTRIP == pt) + { + GL_CHECK(glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX) ); + } + else + { + GL_CHECK(glDisable(GL_PRIMITIVE_RESTART_FIXED_INDEX) ); + } + } } bool programChanged = false; diff --git a/src/renderer_gl.h b/src/renderer_gl.h index 13872c39e..5b5361191 100644 --- a/src/renderer_gl.h +++ b/src/renderer_gl.h @@ -1181,6 +1181,10 @@ typedef double GLdouble; # define GL_LINE_SMOOTH 0x0B20 #endif // GL_LINE_SMOOTH +#ifndef GL_PRIMITIVE_RESTART_FIXED_INDEX +# define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 +#endif // GL_PRIMITIVE_RESTART_FIXED_INDEX + #ifndef GL_TEXTURE_LOD_BIAS # define GL_TEXTURE_LOD_BIAS 0x8501 #endif // GL_TEXTURE_LOD_BIAS diff --git a/src/renderer_vk.cpp b/src/renderer_vk.cpp index d8f9f0458..99e2da28c 100644 --- a/src/renderer_vk.cpp +++ b/src/renderer_vk.cpp @@ -4153,7 +4153,13 @@ VK_IMPORT_DEVICE inputAssemblyState.pNext = NULL; inputAssemblyState.flags = 0; inputAssemblyState.topology = s_primInfo[(_state&BGFX_STATE_PT_MASK) >> BGFX_STATE_PT_SHIFT].m_topology; - inputAssemblyState.primitiveRestartEnable = VK_FALSE; + inputAssemblyState.primitiveRestartEnable = (false + || VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP == inputAssemblyState.topology + || VK_PRIMITIVE_TOPOLOGY_LINE_STRIP == inputAssemblyState.topology + ) + ? VK_TRUE + : VK_FALSE + ; VkPipelineRasterizationStateCreateInfo rasterizationState; setRasterizerState(rasterizationState, _state, m_wireframe); diff --git a/src/renderer_webgpu.cpp b/src/renderer_webgpu.cpp index 695556569..441f3d6ab 100644 --- a/src/renderer_webgpu.cpp +++ b/src/renderer_webgpu.cpp @@ -3195,6 +3195,7 @@ WGPU_IMPORT murmur.add(layout.m_attributes, sizeof(layout.m_attributes) ); murmur.add(_msaaCount); murmur.add(_numInstanceData); + murmur.add(_isIndex16); murmur.add(_useDepthAttachment); addAttachmentState(murmur, fb); const uint32_t hash = murmur.end();