mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-14 07:08:32 +09:00
[Feat, Fix, Test] (MG_State, MG_Impl, MG_Backend, MG_Test): give ARB_viewport_array real 16-element indexed state instead of eight stubs and a viewport-0 echo
This commit is contained in:
@@ -1600,7 +1600,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
!g_hasSyncedRenderState || std::memcmp(currentBytes + kBlendSpanEnd, syncedBytes + kBlendSpanEnd,
|
||||
sizeof(RenderStateParameters) - kBlendSpanEnd) != 0;
|
||||
|
||||
IntVec4 backendViewport = parameters.Viewport;
|
||||
IntVec4 backendViewport = MG_State::pGLContext->GetViewport();
|
||||
if (backendViewport.z() <= 0 || backendViewport.w() <= 0) {
|
||||
Int surfaceWidth = 0;
|
||||
Int surfaceHeight = 0;
|
||||
@@ -1633,11 +1633,26 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
SYNC_CAPABILITY(SampleMask, GL_SAMPLE_MASK);
|
||||
SYNC_CAPABILITY(PolygonOffsetFill, GL_POLYGON_OFFSET_FILL);
|
||||
SYNC_CAPABILITY(RasterizerDiscard, GL_RASTERIZER_DISCARD);
|
||||
SYNC_CAPABILITY(ScissorTest, GL_SCISSOR_TEST);
|
||||
SYNC_CAPABILITY(StencilTest, GL_STENCIL_TEST);
|
||||
SYNC_CAPABILITY(CullFace, GL_CULL_FACE);
|
||||
|
||||
#undef SYNC_CAPABILITY
|
||||
|
||||
// GL_SCISSOR_TEST is per-viewport enable state (ARB_viewport_array), so it is a
|
||||
// 16-bit mask and not a "<Name>Enabled" bool the macro above could key off. ES
|
||||
// has exactly one scissor rectangle and one scissor enable, so only bit 0 - the
|
||||
// index every ES draw rasterizes against - can be forwarded; a program that
|
||||
// enables the test for viewport 3 alone gets viewport 0's answer here. That is
|
||||
// the same limitation as the unemulated gl_ViewportIndex on this backend and is
|
||||
// why the multi-viewport half of KHR-GL43.viewport_array stays red on Espryt.
|
||||
{
|
||||
const Bool scissorTest = (parameters.ScissorTestEnabledMask & 1u) != 0;
|
||||
const Bool syncedScissorTest =
|
||||
(g_syncedRenderStateParameters.ScissorTestEnabledMask & 1u) != 0;
|
||||
if (forceFullPush || scissorTest != syncedScissorTest) {
|
||||
scissorTest ? g_GLESFuncs.glEnable(GL_SCISSOR_TEST) : g_GLESFuncs.glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tailSpanDirty && g_GLESCapabilities.SupportsClipDistance) {
|
||||
@@ -1864,8 +1879,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
if (forceFullPush || parameters.DepthMask != g_syncedRenderStateParameters.DepthMask) {
|
||||
g_GLESFuncs.glDepthMask(parameters.DepthMask ? GL_TRUE : GL_FALSE);
|
||||
}
|
||||
if (forceFullPush || parameters.DepthRange != g_syncedRenderStateParameters.DepthRange) {
|
||||
g_GLESFuncs.glDepthRangef(parameters.DepthRange.x(), parameters.DepthRange.y());
|
||||
if (forceFullPush || parameters.DepthRanges[0] != g_syncedRenderStateParameters.DepthRanges[0]) {
|
||||
g_GLESFuncs.glDepthRangef(parameters.DepthRanges[0].x(), parameters.DepthRanges[0].y());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2003,7 +2018,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// everything drawn with GL_SCISSOR_TEST enabled before the app's first glScissor
|
||||
// is clipped away - Minecraft 26.2 keeps only its unscissored sky and hand and
|
||||
// loses the terrain and the whole GUI.
|
||||
IntVec4 backendScissorBox = parameters.ScissorBox;
|
||||
IntVec4 backendScissorBox = parameters.ScissorBoxes[0];
|
||||
if (backendScissorBox.z() <= 0 || backendScissorBox.w() <= 0) {
|
||||
Int surfaceWidth = 0;
|
||||
Int surfaceHeight = 0;
|
||||
@@ -4762,7 +4777,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// restores the app state on exit, tracked via the render-state shadow.
|
||||
class ScopedScissorDisable {
|
||||
public:
|
||||
ScopedScissorDisable() : m_wasEnabled(RenderStateImpl::g_syncedRenderStateParameters.ScissorTestEnabled) {
|
||||
ScopedScissorDisable()
|
||||
: m_wasEnabled((RenderStateImpl::g_syncedRenderStateParameters.ScissorTestEnabledMask & 1u) != 0) {
|
||||
if (m_wasEnabled) g_GLESFuncs.glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
~ScopedScissorDisable() {
|
||||
|
||||
@@ -335,19 +335,19 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
// Complete input inventory of ApplyDynamicDrawStateTail, one line per reader
|
||||
// (each accessor it replaces is a verified plain field read of the same
|
||||
// RenderStateParameters field - RenderState.cpp):
|
||||
// ApplyGLViewportState : Viewport, DepthRange, + extent/isDefaultFbo/preTransform
|
||||
// ApplyGLViewportState : Viewports[0], DepthRanges[0], + extent/isDefaultFbo/preTransform
|
||||
// ApplyBlendConstants : BlendColor
|
||||
// ApplyPolygonOffsetState : PolygonOffsetUnits, PolygonOffsetFactor
|
||||
// ApplyLineWidthState : LineWidth (see the caveat below)
|
||||
// ApplyStencilState : StencilStates[0..1].{ValueMask, WriteMask, Ref}
|
||||
// scissor rect : ScissorTestEnabled, ScissorBox,
|
||||
// scissor rect : ScissorTestEnabledMask bit 0, ScissorBoxes[0],
|
||||
// + extent/isDefaultFbo/preTransform
|
||||
// Caveat, unchanged from the version-only gate: ApplyLineWidthState also clamps
|
||||
// to the ACTIVE BACKEND OBJECT's aliased line-width range. Those are device
|
||||
// limits queried once at backend init and constant for the renderer's lifetime,
|
||||
// so they are not part of the key (the version gate never covered them either).
|
||||
struct DynamicTailKey {
|
||||
Int viewport[4] = {0, 0, 0, 0};
|
||||
Float viewport[4] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
Float depthRange[2] = {0.0f, 0.0f};
|
||||
Float blendColor[4] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
Float polygonOffsetFactor = 0.0f;
|
||||
@@ -5342,12 +5342,14 @@ void main() {
|
||||
DynamicStateShadow::DynamicTailKey key;
|
||||
{
|
||||
const RenderStateParameters& p = MG_State::pGLContext->GetRenderStateParameters();
|
||||
key.viewport[0] = p.Viewport.x();
|
||||
key.viewport[1] = p.Viewport.y();
|
||||
key.viewport[2] = p.Viewport.z();
|
||||
key.viewport[3] = p.Viewport.w();
|
||||
key.depthRange[0] = p.DepthRange.x();
|
||||
key.depthRange[1] = p.DepthRange.y();
|
||||
// Viewport 0 and its depth range: ApplyGLViewportState reads exactly those two
|
||||
// (per-index state for indices > 0 is keyed separately, see multiViewportKey below).
|
||||
key.viewport[0] = p.Viewports[0].x();
|
||||
key.viewport[1] = p.Viewports[0].y();
|
||||
key.viewport[2] = p.Viewports[0].z();
|
||||
key.viewport[3] = p.Viewports[0].w();
|
||||
key.depthRange[0] = p.DepthRanges[0].x();
|
||||
key.depthRange[1] = p.DepthRanges[0].y();
|
||||
key.blendColor[0] = p.BlendColor.x();
|
||||
key.blendColor[1] = p.BlendColor.y();
|
||||
key.blendColor[2] = p.BlendColor.z();
|
||||
@@ -5362,11 +5364,11 @@ void main() {
|
||||
key.stencilWriteMask[face] = p.StencilStates[face].WriteMask;
|
||||
key.stencilRef[face] = p.StencilStates[face].Ref;
|
||||
}
|
||||
key.scissorEnabled = p.ScissorTestEnabled;
|
||||
key.scissorBox[0] = p.ScissorBox.x();
|
||||
key.scissorBox[1] = p.ScissorBox.y();
|
||||
key.scissorBox[2] = p.ScissorBox.z();
|
||||
key.scissorBox[3] = p.ScissorBox.w();
|
||||
key.scissorEnabled = (p.ScissorTestEnabledMask & 1u) != 0;
|
||||
key.scissorBox[0] = p.ScissorBoxes[0].x();
|
||||
key.scissorBox[1] = p.ScissorBoxes[0].y();
|
||||
key.scissorBox[2] = p.ScissorBoxes[0].z();
|
||||
key.scissorBox[3] = p.ScissorBoxes[0].w();
|
||||
key.extentX = extent.x();
|
||||
key.extentY = extent.y();
|
||||
key.preTransform = static_cast<Uint32>(preTransform);
|
||||
|
||||
Reference in New Issue
Block a user