mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 04:08:32 +09:00
- ROADMAP P0.5 / ARCHITECTURE.md value-header manifest: MGPipeTypes.h embedded RenderStateParameters and PixelStoreParameters through RenderState.h, which drags FramebufferObject.h and the whole texture/renderbuffer/sampler chain into MG_Pipe; purity gate A (no MG_State/MG_Impl/MG_Backend/MG_Remote in the closure) could not be armed for anything in MG_Pipe while that include existed. - MGPipeValueTypes.h is a verbatim cut, comments included: the eleven RenderState.h enums (all of them - a split would be the maintenance trap), PixelStoreParameters, PerBufferBlendState, StencilFaceState, RenderStateParameters (member order untouched: DirectGLES' offsetof spans and PipeSpanTable.inc name the members), the six SamplerObject.h enums and SamplerParameters (BorderColorForm stays Uint8, it sets the tail padding), and VertexAttribute / VertexBufferBindingPoint / VertexAttributeVersion, which keep namespace MobileGL::MG_State::GLState with a forward-declared BufferObject so no mangled name changes. - MAX_DRAW_BUFFERS becomes inline constexpr kMGMaxDrawBuffers in namespace MobileGL and FramebufferObject::MAX_DRAW_BUFFERS is defined from it, so the eighty existing spellings keep working and the two cannot drift. No other constant is added. - The four MG_State headers become forwarders (include the value header, keep their class definitions); RenderState.cpp gains a direct FramebufferObject.h include because it spells FramebufferObject::MAX_DRAW_BUFFERS and only ever got that header transitively. No other TU lost a transitive include: the full build (Release, clang, tests + integration tests) passed without touching anything under MG_Backend, MG_Impl or MG_Util. - DynamicBackendParameters does NOT move (SizeT members and TextureTarget-taking member functions make that a type change, not a move); MGPipeTypes.h keeps its BackendObject.h include and the debt comment now says so, which is why gate A asserts MGPipeValueTypes.h rather than MGPipeTypes.h. - New trip wires in the header: trivially-copyable + exact sizeof for PixelStoreParameters/PerBufferBlendState/StencilFaceState (28), SamplerParameters (100), VertexAttributeVersion (6), RenderStateParameters (1168, standard layout, BlendStates before LogicOp, BlendStates sized by kMGMaxDrawBuffers). Their runtime twins ValueTypeLayoutsArePinned and the carrier check ResidualBlockIsExactlyItsTwoValueStructsPlusPatchTail (Pack at 1168, CapabilityBits at 1200) are added to PipeCatalogueTest without a new include. - gen_pipe.py's "field lists of their own in P0.5" comment now says P1 (the comparator needs std::array<struct> support first); PipeVerify.inc regenerated. - Verified: ctest -L unit 1460/1460 and -L integration-gpu green; ctest -N names a superset of feat/disaggregated@6672778b (two added, none lost); one definition per moved type; the -H closure of the new header contains no MG_State/MG_Backend/ MG_Impl/MG_Remote header and the header compiles alone; nm --defined-only -S against the base libMobileGL.so: 0 added / 0 removed / 0 resized, .text byte-identical, the only differing bytes are the build-id and two stamp strings.
181 lines
10 KiB
C++
181 lines
10 KiB
C++
// MobileGL - MobileGL/MG_State/GLState/RenderState/RenderState.h
|
|
// Copyright (c) 2025-2026 MobileGL-Dev
|
|
// Licensed under the GNU Lesser General Public License v3.0:
|
|
// https://www.gnu.org/licenses/gpl-3.0.txt
|
|
// https://www.gnu.org/licenses/lgpl-3.0.txt
|
|
// SPDX-License-Identifier: LGPL-3.0-only
|
|
// End of Source File Header
|
|
|
|
#pragma once
|
|
#include <Includes.h>
|
|
#include <MG_Pipe/MGPipeValueTypes.h>
|
|
|
|
namespace MobileGL {
|
|
namespace MG_State {
|
|
namespace GLState {
|
|
class RenderState {
|
|
public:
|
|
RenderState();
|
|
|
|
Uint GetVersion() const;
|
|
// Version of the pipeline-relevant subset only - see m_pipelineStateVersion.
|
|
Uint GetPipelineStateVersion() const;
|
|
const RenderStateParameters& GetAllParameters() const;
|
|
|
|
// Rasterization
|
|
// ARB_viewport_array defines glViewport as ViewportIndexedf on EVERY index, so the
|
|
// classic setter broadcasts; GetViewport answers for index 0 (rounded to the
|
|
// integers glGetIntegerv(GL_VIEWPORT) and both backends want) and is BY VALUE for
|
|
// that reason. The indexed pair is the verbatim float state.
|
|
void SetViewport(IntVec4 viewport); // x, y, width, height
|
|
IntVec4 GetViewport() const; // x, y, width, height, viewport 0, rounded
|
|
void SetViewportIndexed(Uint index, FloatVec4 viewport);
|
|
const FloatVec4& GetViewportIndexed(Uint index) const;
|
|
void SetLineWidth(Float width);
|
|
Float GetLineWidth() const;
|
|
void SetPointSize(Float size);
|
|
Float GetPointSize() const;
|
|
void SetPatchVertices(Uint vertices);
|
|
Uint GetPatchVertices() const;
|
|
void SetPatchDefaultOuterLevel(const FloatVec4& levels);
|
|
const FloatVec4& GetPatchDefaultOuterLevel() const;
|
|
void SetPatchDefaultInnerLevel(const FloatVec2& levels);
|
|
const FloatVec2& GetPatchDefaultInnerLevel() const;
|
|
void SetPolygonOffset(Float factor, Float units);
|
|
// glPolygonOffsetClamp. Writes the same factor/units as glPolygonOffset plus the
|
|
// clamp, because that is what the entry point does - glPolygonOffset is the
|
|
// clamp = 0 case of it (GL 4.6 core 14.6.5).
|
|
void SetPolygonOffsetClamped(Float factor, Float units, Float clamp);
|
|
Float GetPolygonOffsetFactor() const;
|
|
Float GetPolygonOffsetUnits() const;
|
|
Float GetPolygonOffsetClamp() const;
|
|
void SetClipControl(GLenum origin, GLenum depth);
|
|
GLenum GetClipOrigin() const;
|
|
GLenum GetClipDepthMode() const;
|
|
// Hints. target must be one of the 4 GL 3.3 core hint targets (validated by the caller).
|
|
void SetHint(GLenum target, GLenum mode);
|
|
GLenum GetHint(GLenum target) const;
|
|
void SetPointFadeThresholdSize(Float size);
|
|
Float GetPointFadeThresholdSize() const;
|
|
void SetPointSpriteCoordOrigin(GLenum origin);
|
|
GLenum GetPointSpriteCoordOrigin() const;
|
|
// Color clamping (glClampColor). Core profile has only GL_CLAMP_READ_COLOR.
|
|
void SetClampReadColor(GLenum clamp);
|
|
GLenum GetClampReadColor() const;
|
|
// Polygon mode (glPolygonMode). Core sets both faces together; the query reports both.
|
|
void SetPolygonMode(GLenum front, GLenum back);
|
|
GLenum GetPolygonModeFront() const;
|
|
GLenum GetPolygonModeBack() const;
|
|
void SetPrimitiveRestartIndex(Uint32 index);
|
|
Uint32 GetPrimitiveRestartIndex() const;
|
|
|
|
// Capabilities
|
|
void SetCapability(CapabilityInput cap, Bool enabled);
|
|
Bool IsCapabilityEnabled(CapabilityInput cap) const;
|
|
void SetCapabilityIndexed(CapabilityInput cap, Uint index, Bool enabled);
|
|
Bool IsCapabilityEnabledIndexed(CapabilityInput cap, Uint index) const;
|
|
|
|
// Blending
|
|
void SetBlendFunc(BlendFactor srcRGB, BlendFactor dstRGB, BlendFactor srcAlpha, BlendFactor dstAlpha);
|
|
void GetBlendFunc(BlendFactor& srcRGB, BlendFactor& dstRGB, BlendFactor& srcAlpha,
|
|
BlendFactor& dstAlpha) const;
|
|
void SetBlendFuncIndexed(Uint index, BlendFactor srcRGB, BlendFactor dstRGB, BlendFactor srcAlpha,
|
|
BlendFactor dstAlpha);
|
|
void GetBlendFuncIndexed(Uint index, BlendFactor& srcRGB, BlendFactor& dstRGB, BlendFactor& srcAlpha,
|
|
BlendFactor& dstAlpha) const;
|
|
void SetBlendEquation(BlendEquation color, BlendEquation alpha);
|
|
void GetBlendEquation(BlendEquation& color, BlendEquation& alpha) const;
|
|
void SetBlendEquationIndexed(Uint index, BlendEquation color, BlendEquation alpha);
|
|
void GetBlendEquationIndexed(Uint index, BlendEquation& color, BlendEquation& alpha) const;
|
|
void SetLogicOp(LogicOperation logicOp);
|
|
LogicOperation GetLogicOp() const;
|
|
|
|
// Depth
|
|
void SetDepthFunc(DepthTestFunc func);
|
|
DepthTestFunc GetDepthFunc() const;
|
|
void SetDepthMask(Bool flag);
|
|
Bool GetDepthMask() const;
|
|
void SetStencilFunc(StencilFace face, DepthTestFunc func, Int ref, Uint32 mask);
|
|
void SetStencilMask(StencilFace face, Uint32 mask);
|
|
void SetStencilOp(StencilFace face, StencilOperation fail, StencilOperation depthFail,
|
|
StencilOperation depthPass);
|
|
const StencilFaceState& GetStencilState(StencilFace face) const;
|
|
|
|
// Color Mask. SetColorMask broadcasts to every draw buffer and GetColorMask returns
|
|
// draw buffer 0; the indexed forms address a single draw buffer (glColorMaski). The
|
|
// caller is responsible for validating index against MAX_DRAW_BUFFERS.
|
|
void SetColorMask(BoolVec4 mask);
|
|
BoolVec4 GetColorMask() const;
|
|
void SetColorMaskIndexed(Uint index, BoolVec4 mask);
|
|
BoolVec4 GetColorMaskIndexed(Uint index) const;
|
|
|
|
// Clear State
|
|
void SetClearColor(FloatVec4 color);
|
|
const FloatVec4& GetClearColor() const;
|
|
void SetClearDepth(Float depth);
|
|
Float GetClearDepth() const;
|
|
void SetClearStencil(Int stencil);
|
|
Uint32 GetClearStencil() const;
|
|
void SetBlendColor(FloatVec4 color);
|
|
const FloatVec4& GetBlendColor() const;
|
|
// glDepthRange(f) writes every viewport's range (ARB_viewport_array); the indexed
|
|
// pair is glDepthRangeIndexed / glDepthRangeArrayv. GetDepthRange answers index 0.
|
|
void SetDepthRange(FloatVec2 range);
|
|
const FloatVec2& GetDepthRange() const;
|
|
void SetDepthRangeIndexed(Uint index, FloatVec2 range);
|
|
const FloatVec2& GetDepthRangeIndexed(Uint index) const;
|
|
void SetSampleCoverage(Float value, Bool invert);
|
|
Float GetSampleCoverageValue() const;
|
|
Bool GetSampleCoverageInvert() const;
|
|
void SetSampleMaskValue(Uint32 mask);
|
|
Uint32 GetSampleMaskValue() const;
|
|
// glMinSampleShading. `value` is stored as given; the entry point clamps.
|
|
void SetMinSampleShadingValue(Float value);
|
|
Float GetMinSampleShadingValue() const;
|
|
|
|
// Pixel Store
|
|
void SetPixelStoreParam(PixelStoreParam param, Int value);
|
|
Int GetPixelStoreParam(PixelStoreParam param) const;
|
|
PixelStoreParameters GetPixelStoreParameters(Bool isUnpack) const;
|
|
|
|
// Cull Face
|
|
void SetCullFaceMode(CullFaceMode mode);
|
|
CullFaceMode GetCullFaceMode() const;
|
|
void SetFrontFaceMode(FrontFaceMode mode);
|
|
FrontFaceMode GetFrontFaceMode() const;
|
|
void SetProvokingVertexMode(ProvokingVertexMode mode);
|
|
ProvokingVertexMode GetProvokingVertexMode() const;
|
|
|
|
// Scissor. glScissor writes every rectangle (ARB_viewport_array); GetScissorBox
|
|
// answers for index 0.
|
|
void SetScissorBox(IntVec4 box); // x, y, width, height
|
|
const IntVec4& GetScissorBox() const; // x, y, width, height
|
|
void SetScissorBoxIndexed(Uint index, IntVec4 box);
|
|
const IntVec4& GetScissorBoxIndexed(Uint index) const;
|
|
|
|
private:
|
|
// Bump both: any state change invalidates the draw snapshot, and this one also
|
|
// changes the VkPipeline (or its DirectGLES equivalent).
|
|
void BumpVersions() {
|
|
++m_version;
|
|
++m_pipelineStateVersion;
|
|
}
|
|
|
|
Uint16 m_version = 0;
|
|
// Only the subset of render state that a backend bakes INTO a pipeline object.
|
|
// Viewport, scissor, depth range, blend colour, line width, polygon offset, stencil
|
|
// write mask, the clear values, hints and the point-size family are all either
|
|
// dynamic pipeline state or not pipeline state at all, so changing one of them must
|
|
// not evict a cached pipeline. Keeping one counter for both made a glViewport call
|
|
// knock the next draw off the pipeline memo AND the draw fast path.
|
|
Uint16 m_pipelineStateVersion = 0;
|
|
RenderStateParameters m_parameters;
|
|
|
|
// Pixel Store
|
|
PixelStoreParameters m_pixelStorePackParameters;
|
|
PixelStoreParameters m_pixelStoreUnpackParameters;
|
|
};
|
|
} // namespace GLState
|
|
} // namespace MG_State
|
|
} // namespace MobileGL
|