[Fix] (P13 W8): the transport-less monolith sends set_context_values like the split build's does, and render-state padding is zeroed so equal states share one CSO.

This commit is contained in:
2026-10-06 22:17:16 -04:00
parent f7360fe210
commit db8484cbb9
2 changed files with 19 additions and 1 deletions
+6 -1
View File
@@ -3555,7 +3555,12 @@ namespace MobileGL::MG_Pipe {
? MG_Remote::Client::ContextValuesWireLive()
: MG_Config::RecordArmAliasesFrontend();
#else
constexpr Bool contextValuesWireLive = false;
// P13 W8: a library without a transport is ALWAYS monolith's record arm, so it takes the
// eight fields from the record exactly as the split build's monolith does. This branch
// used to answer a constant false - the pre-W5 pull shape - and left the shipped (FCL)
// build pulling them by residual fill while the split build's monolith carried them; the
// recorder goldens (MG_Test/Pipe/RecorderGoldenTest.cpp) found the two streams differ.
const Bool contextValuesWireLive = MG_Config::RecordArmAliasesFrontend();
#endif
// AND THE SEVENTH IS P5eFamilyIsLive (ID-106), which is the same sentence for the
// binding-point family and asks bit 13's OWN consumer bit rather than the resource
@@ -6,6 +6,9 @@
// SPDX-License-Identifier: LGPL-3.0-only
// End of Source File Header
#include <cstring>
#include <new>
#include <type_traits>
#include "RenderState.h"
#include <MG_State/GLState/FramebufferState/FramebufferObject.h>
#include "MG_Util/Debug/Log.h"
@@ -35,6 +38,16 @@ namespace MobileGL {
} // namespace
RenderState::RenderState() {
// ZERO PADDING FIRST. The parameters' pipeline and dynamic chunks are pushed as
// bytes and content-addressed byte for byte (CsoCache's hash and memcmp), so the
// padding between members must not carry whatever the allocator left there: two
// contexts with equal state would otherwise mint two render-state CSOs, and the
// recorder goldens (MG_Test/Pipe/RecorderGoldenTest.cpp) would not be repeatable.
// Re-constructing in place keeps every default member initializer; the type is
// trivially destructible, so the first construction needs no destructor call.
static_assert(std::is_trivially_destructible_v<RenderStateParameters>);
std::memset(static_cast<void*>(&m_parameters), 0, sizeof(m_parameters));
new (&m_parameters) RenderStateParameters();
// The color writemask defaults to all-true for every draw buffer.
for (auto& mask : m_parameters.ColorMasks) {
mask = BoolVec4(true, true, true, true);