CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/GPU/D3D11/StateMappingD3D11.cpp
Views: 1401
// Copyright (c) 2012- PPSSPP Project.12// This program is free software: you can redistribute it and/or modify3// it under the terms of the GNU General Public License as published by4// the Free Software Foundation, version 2.0 or later versions.56// This program is distributed in the hope that it will be useful,7// but WITHOUT ANY WARRANTY; without even the implied warranty of8// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the9// GNU General Public License 2.0 for more details.1011// A copy of the GPL 2.0 should have been included with the program.12// If not, see http://www.gnu.org/licenses/1314// Official git repository and contact information can be found at15// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.1617#include <d3d11.h>18#include <d3d11_1.h>1920#include <algorithm>2122#include "Common/Data/Convert/SmallDataConvert.h"2324#include "GPU/Math3D.h"25#include "GPU/GPUState.h"26#include "GPU/ge_constants.h"27#include "GPU/Common/GPUStateUtils.h"28#include "Core/System.h"29#include "Core/Config.h"3031#include "GPU/Common/FramebufferManagerCommon.h"32#include "GPU/D3D11/DrawEngineD3D11.h"33#include "GPU/D3D11/StateMappingD3D11.h"34#include "GPU/D3D11/FramebufferManagerD3D11.h"35#include "GPU/D3D11/TextureCacheD3D11.h"3637// These tables all fit into u8s.38static const D3D11_BLEND d3d11BlendFactorLookup[(size_t)BlendFactor::COUNT] = {39D3D11_BLEND_ZERO,40D3D11_BLEND_ONE,41D3D11_BLEND_SRC_COLOR,42D3D11_BLEND_INV_SRC_COLOR,43D3D11_BLEND_DEST_COLOR,44D3D11_BLEND_INV_DEST_COLOR,45D3D11_BLEND_SRC_ALPHA,46D3D11_BLEND_INV_SRC_ALPHA,47D3D11_BLEND_DEST_ALPHA,48D3D11_BLEND_INV_DEST_ALPHA,49D3D11_BLEND_BLEND_FACTOR,50D3D11_BLEND_INV_BLEND_FACTOR,51D3D11_BLEND_BLEND_FACTOR,52D3D11_BLEND_INV_BLEND_FACTOR,53D3D11_BLEND_SRC1_COLOR,54D3D11_BLEND_INV_SRC1_COLOR,55D3D11_BLEND_SRC1_ALPHA,56D3D11_BLEND_INV_SRC1_ALPHA,57};5859static const D3D11_BLEND_OP d3d11BlendEqLookup[(size_t)BlendEq::COUNT] = {60D3D11_BLEND_OP_ADD,61D3D11_BLEND_OP_SUBTRACT,62D3D11_BLEND_OP_REV_SUBTRACT,63D3D11_BLEND_OP_MIN,64D3D11_BLEND_OP_MAX,65};6667static const D3D11_CULL_MODE cullingMode[] = {68D3D11_CULL_BACK,69D3D11_CULL_FRONT,70};7172static const D3D11_COMPARISON_FUNC compareOps[] = {73D3D11_COMPARISON_NEVER,74D3D11_COMPARISON_ALWAYS,75D3D11_COMPARISON_EQUAL,76D3D11_COMPARISON_NOT_EQUAL,77D3D11_COMPARISON_LESS,78D3D11_COMPARISON_LESS_EQUAL,79D3D11_COMPARISON_GREATER,80D3D11_COMPARISON_GREATER_EQUAL,81};8283static const D3D11_STENCIL_OP stencilOps[] = {84D3D11_STENCIL_OP_KEEP,85D3D11_STENCIL_OP_ZERO,86D3D11_STENCIL_OP_REPLACE,87D3D11_STENCIL_OP_INVERT,88D3D11_STENCIL_OP_INCR_SAT,89D3D11_STENCIL_OP_DECR_SAT,90D3D11_STENCIL_OP_KEEP, // reserved91D3D11_STENCIL_OP_KEEP, // reserved92};9394static const D3D11_PRIMITIVE_TOPOLOGY primToD3D11[8] = {95D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, // Points are expanded to triangles.96D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, // Lines are expanded to triangles too.97D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, // Lines are expanded to triangles too.98D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST,99D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,100D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED, // D3D11 doesn't do triangle fans.101D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, // Rectangles are expanded to triangles.102};103104static const D3D11_LOGIC_OP logicOps[] = {105D3D11_LOGIC_OP_CLEAR,106D3D11_LOGIC_OP_AND,107D3D11_LOGIC_OP_AND_REVERSE,108D3D11_LOGIC_OP_COPY,109D3D11_LOGIC_OP_AND_INVERTED,110D3D11_LOGIC_OP_NOOP,111D3D11_LOGIC_OP_XOR,112D3D11_LOGIC_OP_OR,113D3D11_LOGIC_OP_NOR,114D3D11_LOGIC_OP_EQUIV,115D3D11_LOGIC_OP_INVERT,116D3D11_LOGIC_OP_OR_REVERSE,117D3D11_LOGIC_OP_COPY_INVERTED,118D3D11_LOGIC_OP_OR_INVERTED,119D3D11_LOGIC_OP_NAND,120D3D11_LOGIC_OP_SET,121};122123class FramebufferManagerD3D11;124class ShaderManagerD3D11;125126void DrawEngineD3D11::ApplyDrawState(int prim) {127dynState_.topology = primToD3D11[prim];128129if (!gstate_c.IsDirty(DIRTY_BLEND_STATE | DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE)) {130// nothing to do131return;132}133134bool useBufferedRendering = framebufferManager_->UseBufferedRendering();135// Blend136if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) {137if (gstate.isModeClear()) {138keys_.blend.value = 0; // full wipe139keys_.blend.blendEnable = false;140dynState_.useBlendColor = false;141// Color Test142bool alphaMask = gstate.isClearModeAlphaMask();143bool colorMask = gstate.isClearModeColorMask();144keys_.blend.colorWriteMask = (colorMask ? (1 | 2 | 4) : 0) | (alphaMask ? 8 : 0);145} else {146keys_.blend.value = 0;147148pipelineState_.Convert(draw_->GetShaderLanguageDesc().bitwiseOps);149GenericMaskState &maskState = pipelineState_.maskState;150GenericBlendState &blendState = pipelineState_.blendState;151// We ignore the logicState on D3D since there's no support, the emulation of it is blend-and-shader only.152153if (pipelineState_.FramebufferRead()) {154FBOTexState fboTexBindState = FBO_TEX_NONE;155ApplyFramebufferRead(&fboTexBindState);156// The shader takes over the responsibility for blending, so recompute.157ApplyStencilReplaceAndLogicOpIgnoreBlend(blendState.replaceAlphaWithStencil, blendState);158159if (fboTexBindState == FBO_TEX_COPY_BIND_TEX) {160framebufferManager_->BindFramebufferAsColorTexture(1, framebufferManager_->GetCurrentRenderVFB(), BINDFBCOLOR_MAY_COPY | BINDFBCOLOR_UNCACHED, 0);161// No sampler required, we do a plain Load in the pixel shader.162fboTexBound_ = true;163fboTexBindState = FBO_TEX_NONE;164165framebufferManager_->RebindFramebuffer("RebindFramebuffer - ApplyDrawState");166// Must dirty blend state here so we re-copy next time. Example: Lunar's spell effects.167dirtyRequiresRecheck_ |= DIRTY_BLEND_STATE;168gstate_c.Dirty(DIRTY_BLEND_STATE);169}170171dirtyRequiresRecheck_ |= DIRTY_FRAGMENTSHADER_STATE;172gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE);173} else {174if (fboTexBound_) {175fboTexBound_ = false;176dirtyRequiresRecheck_ |= DIRTY_FRAGMENTSHADER_STATE;177gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE);178}179}180181if (blendState.blendEnabled) {182keys_.blend.blendEnable = true;183keys_.blend.logicOpEnable = false;184keys_.blend.blendOpColor = d3d11BlendEqLookup[(size_t)blendState.eqColor];185keys_.blend.blendOpAlpha = d3d11BlendEqLookup[(size_t)blendState.eqAlpha];186keys_.blend.srcColor = d3d11BlendFactorLookup[(size_t)blendState.srcColor];187keys_.blend.srcAlpha = d3d11BlendFactorLookup[(size_t)blendState.srcAlpha];188keys_.blend.destColor = d3d11BlendFactorLookup[(size_t)blendState.dstColor];189keys_.blend.destAlpha = d3d11BlendFactorLookup[(size_t)blendState.dstAlpha];190if (blendState.dirtyShaderBlendFixValues) {191dirtyRequiresRecheck_ |= DIRTY_SHADERBLEND;192gstate_c.Dirty(DIRTY_SHADERBLEND);193}194dynState_.useBlendColor = blendState.useBlendColor;195if (blendState.useBlendColor) {196dynState_.blendColor = blendState.blendColor;197}198} else {199keys_.blend.blendEnable = false;200dynState_.useBlendColor = false;201}202203if (gstate_c.Use(GPU_USE_LOGIC_OP)) {204// Logic Ops205if (gstate.isLogicOpEnabled() && gstate.getLogicOp() != GE_LOGIC_COPY) {206keys_.blend.blendEnable = false; // Can't have both blend & logic op - although I think the PSP can!207keys_.blend.logicOpEnable = true;208keys_.blend.logicOp = logicOps[gstate.getLogicOp()];209} else {210keys_.blend.logicOpEnable = false;211}212}213214keys_.blend.colorWriteMask = maskState.channelMask;215}216}217218if (gstate_c.IsDirty(DIRTY_RASTER_STATE)) {219keys_.raster.value = 0;220bool wantCull = !gstate.isModeClear() && prim != GE_PRIM_RECTANGLES && prim > GE_PRIM_LINE_STRIP && gstate.isCullEnabled();221keys_.raster.cullMode = wantCull ? (gstate.getCullMode() ? D3D11_CULL_FRONT : D3D11_CULL_BACK) : D3D11_CULL_NONE;222223if (gstate.isModeClear() || gstate.isModeThrough()) {224// TODO: Might happen in clear mode if not through...225keys_.raster.depthClipEnable = 1;226} else {227if (gstate.getDepthRangeMin() == 0 || gstate.getDepthRangeMax() == 65535) {228// TODO: Still has a bug where we clamp to depth range if one is not the full range.229// But the alternate is not clamping in either direction...230keys_.raster.depthClipEnable = !gstate.isDepthClampEnabled() || !gstate_c.Use(GPU_USE_DEPTH_CLAMP);231} else {232// We just want to clip in this case, the clamp would be clipped anyway.233keys_.raster.depthClipEnable = 1;234}235}236}237238if (gstate_c.IsDirty(DIRTY_DEPTHSTENCIL_STATE)) {239GenericStencilFuncState stencilState;240ConvertStencilFuncState(stencilState);241242if (gstate.isModeClear()) {243keys_.depthStencil.value = 0;244keys_.depthStencil.depthTestEnable = true;245keys_.depthStencil.depthCompareOp = D3D11_COMPARISON_ALWAYS;246keys_.depthStencil.depthWriteEnable = gstate.isClearModeDepthMask();247248// Stencil Test249bool alphaMask = gstate.isClearModeAlphaMask();250if (alphaMask) {251keys_.depthStencil.stencilTestEnable = true;252keys_.depthStencil.stencilCompareFunc = D3D11_COMPARISON_ALWAYS;253keys_.depthStencil.stencilPassOp = D3D11_STENCIL_OP_REPLACE;254keys_.depthStencil.stencilFailOp = D3D11_STENCIL_OP_REPLACE;255keys_.depthStencil.stencilDepthFailOp = D3D11_STENCIL_OP_REPLACE;256dynState_.useStencil = true;257// In clear mode, the stencil value is set to the alpha value of the vertex.258// A normal clear will be 2 points, the second point has the color.259// We override this value in the pipeline from software transform for clear rectangles.260dynState_.stencilRef = 0xFF;261// But we still apply the stencil write mask.262keys_.depthStencil.stencilWriteMask = stencilState.writeMask;263} else {264keys_.depthStencil.stencilTestEnable = false;265dynState_.useStencil = false;266}267268} else {269keys_.depthStencil.value = 0;270// Depth Test271if (!IsDepthTestEffectivelyDisabled()) {272keys_.depthStencil.depthTestEnable = true;273keys_.depthStencil.depthCompareOp = compareOps[gstate.getDepthTestFunction()];274keys_.depthStencil.depthWriteEnable = gstate.isDepthWriteEnabled();275UpdateEverUsedEqualDepth(gstate.getDepthTestFunction());276} else {277keys_.depthStencil.depthTestEnable = false;278keys_.depthStencil.depthWriteEnable = false;279keys_.depthStencil.depthCompareOp = D3D11_COMPARISON_ALWAYS;280}281282// Stencil Test283if (stencilState.enabled) {284keys_.depthStencil.stencilTestEnable = true;285keys_.depthStencil.stencilCompareFunc = compareOps[stencilState.testFunc];286keys_.depthStencil.stencilPassOp = stencilOps[stencilState.zPass];287keys_.depthStencil.stencilFailOp = stencilOps[stencilState.sFail];288keys_.depthStencil.stencilDepthFailOp = stencilOps[stencilState.zFail];289keys_.depthStencil.stencilCompareMask = stencilState.testMask;290keys_.depthStencil.stencilWriteMask = stencilState.writeMask;291dynState_.useStencil = true;292dynState_.stencilRef = stencilState.testRef;293294// Nasty special case for Spongebob and similar where it tries to write zeros to alpha/stencil during295// depth-fail. We can't write to alpha then because the pixel is killed. However, we can invert the depth296// test and modify the alpha function...297if (SpongebobDepthInverseConditions(stencilState)) {298keys_.blend.blendEnable = true;299keys_.blend.blendOpAlpha = D3D11_BLEND_OP_ADD;300keys_.blend.blendOpColor = D3D11_BLEND_OP_ADD;301keys_.blend.srcColor = D3D11_BLEND_ZERO;302keys_.blend.destColor = D3D11_BLEND_ZERO;303keys_.blend.logicOpEnable = false;304keys_.blend.srcAlpha = D3D11_BLEND_ZERO;305keys_.blend.destAlpha = D3D11_BLEND_ZERO;306keys_.blend.colorWriteMask = D3D11_COLOR_WRITE_ENABLE_ALPHA;307308keys_.depthStencil.depthCompareOp = D3D11_COMPARISON_LESS; // Inverse of GREATER_EQUAL309keys_.depthStencil.stencilCompareFunc = D3D11_COMPARISON_ALWAYS;310// Invert311keys_.depthStencil.stencilPassOp = D3D11_STENCIL_OP_ZERO;312keys_.depthStencil.stencilFailOp = D3D11_STENCIL_OP_ZERO;313keys_.depthStencil.stencilDepthFailOp = D3D11_STENCIL_OP_KEEP;314315dirtyRequiresRecheck_ |= DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE;316gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE);317}318} else {319keys_.depthStencil.stencilTestEnable = false;320dynState_.useStencil = false;321}322}323}324325if (gstate_c.IsDirty(DIRTY_VIEWPORTSCISSOR_STATE)) {326ViewportAndScissor vpAndScissor;327ConvertViewportAndScissor(useBufferedRendering,328framebufferManager_->GetRenderWidth(), framebufferManager_->GetRenderHeight(),329framebufferManager_->GetTargetBufferWidth(), framebufferManager_->GetTargetBufferHeight(),330vpAndScissor);331UpdateCachedViewportState(vpAndScissor);332333float depthMin = vpAndScissor.depthRangeMin;334float depthMax = vpAndScissor.depthRangeMax;335336if (depthMin < 0.0f) depthMin = 0.0f;337if (depthMax > 1.0f) depthMax = 1.0f;338339Draw::Viewport &vp = dynState_.viewport;340vp.TopLeftX = vpAndScissor.viewportX;341vp.TopLeftY = vpAndScissor.viewportY;342vp.Width = vpAndScissor.viewportW;343vp.Height = vpAndScissor.viewportH;344vp.MinDepth = depthMin;345vp.MaxDepth = depthMax;346347D3D11_RECT &scissor = dynState_.scissor;348scissor.left = vpAndScissor.scissorX;349scissor.top = vpAndScissor.scissorY;350scissor.right = vpAndScissor.scissorX + std::max(0, vpAndScissor.scissorW);351scissor.bottom = vpAndScissor.scissorY + std::max(0, vpAndScissor.scissorH);352}353354// Actually create/set the state objects only after we're done mapping all the state.355// There might have been interactions between depth and blend above.356if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) {357if (!device1_) {358ID3D11BlendState *bs = nullptr;359if (!blendCache_.Get(keys_.blend.value, &bs) || !bs) {360D3D11_BLEND_DESC desc{};361D3D11_RENDER_TARGET_BLEND_DESC &rt = desc.RenderTarget[0];362rt.BlendEnable = keys_.blend.blendEnable;363rt.BlendOp = (D3D11_BLEND_OP)keys_.blend.blendOpColor;364rt.BlendOpAlpha = (D3D11_BLEND_OP)keys_.blend.blendOpAlpha;365rt.SrcBlend = (D3D11_BLEND)keys_.blend.srcColor;366rt.DestBlend = (D3D11_BLEND)keys_.blend.destColor;367rt.SrcBlendAlpha = (D3D11_BLEND)keys_.blend.srcAlpha;368rt.DestBlendAlpha = (D3D11_BLEND)keys_.blend.destAlpha;369rt.RenderTargetWriteMask = keys_.blend.colorWriteMask;370ASSERT_SUCCESS(device_->CreateBlendState(&desc, &bs));371blendCache_.Insert(keys_.blend.value, bs);372}373blendState_ = bs;374} else {375ID3D11BlendState1 *bs1 = nullptr;376if (!blendCache1_.Get(keys_.blend.value, &bs1) || !bs1) {377D3D11_BLEND_DESC1 desc1{};378D3D11_RENDER_TARGET_BLEND_DESC1 &rt = desc1.RenderTarget[0];379rt.BlendEnable = keys_.blend.blendEnable;380rt.BlendOp = (D3D11_BLEND_OP)keys_.blend.blendOpColor;381rt.BlendOpAlpha = (D3D11_BLEND_OP)keys_.blend.blendOpAlpha;382rt.SrcBlend = (D3D11_BLEND)keys_.blend.srcColor;383rt.DestBlend = (D3D11_BLEND)keys_.blend.destColor;384rt.SrcBlendAlpha = (D3D11_BLEND)keys_.blend.srcAlpha;385rt.DestBlendAlpha = (D3D11_BLEND)keys_.blend.destAlpha;386rt.RenderTargetWriteMask = keys_.blend.colorWriteMask;387rt.LogicOpEnable = keys_.blend.logicOpEnable;388rt.LogicOp = (D3D11_LOGIC_OP)keys_.blend.logicOp;389ASSERT_SUCCESS(device1_->CreateBlendState1(&desc1, &bs1));390blendCache1_.Insert(keys_.blend.value, bs1);391}392blendState1_ = bs1;393}394}395396if (gstate_c.IsDirty(DIRTY_RASTER_STATE)) {397ID3D11RasterizerState *rs;398if (!rasterCache_.Get(keys_.raster.value, &rs) || !rs) {399D3D11_RASTERIZER_DESC desc{};400desc.CullMode = (D3D11_CULL_MODE)(keys_.raster.cullMode);401desc.FillMode = D3D11_FILL_SOLID;402desc.ScissorEnable = TRUE;403desc.FrontCounterClockwise = TRUE;404desc.DepthClipEnable = keys_.raster.depthClipEnable;405ASSERT_SUCCESS(device_->CreateRasterizerState(&desc, &rs));406rasterCache_.Insert(keys_.raster.value, rs);407}408rasterState_ = rs;409}410411if (gstate_c.IsDirty(DIRTY_DEPTHSTENCIL_STATE)) {412ID3D11DepthStencilState *ds;413if (!depthStencilCache_.Get(keys_.depthStencil.value, &ds) || !ds) {414D3D11_DEPTH_STENCIL_DESC desc{};415desc.DepthEnable = keys_.depthStencil.depthTestEnable;416desc.DepthWriteMask = keys_.depthStencil.depthWriteEnable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;417desc.DepthFunc = (D3D11_COMPARISON_FUNC)keys_.depthStencil.depthCompareOp;418desc.StencilEnable = keys_.depthStencil.stencilTestEnable;419desc.StencilReadMask = keys_.depthStencil.stencilCompareMask;420desc.StencilWriteMask = keys_.depthStencil.stencilWriteMask;421desc.FrontFace.StencilFailOp = (D3D11_STENCIL_OP)keys_.depthStencil.stencilFailOp;422desc.FrontFace.StencilPassOp = (D3D11_STENCIL_OP)keys_.depthStencil.stencilPassOp;423desc.FrontFace.StencilDepthFailOp = (D3D11_STENCIL_OP)keys_.depthStencil.stencilDepthFailOp;424desc.FrontFace.StencilFunc = (D3D11_COMPARISON_FUNC)keys_.depthStencil.stencilCompareFunc;425desc.BackFace = desc.FrontFace;426ASSERT_SUCCESS(device_->CreateDepthStencilState(&desc, &ds));427depthStencilCache_.Insert(keys_.depthStencil.value, ds);428}429depthStencilState_ = ds;430}431432if (gstate_c.IsDirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS) && !gstate.isModeClear() && gstate.isTextureMapEnabled()) {433textureCache_->SetTexture();434gstate_c.Clean(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS);435} else if (gstate.getTextureAddress(0) == (gstate.getFrameBufRawAddress() | 0x04000000)) {436// This catches the case of clearing a texture.437gstate_c.Dirty(DIRTY_TEXTURE_IMAGE);438}439}440441void DrawEngineD3D11::ApplyDrawStateLate(bool applyStencilRef, uint8_t stencilRef) {442// we go through Draw here because it automatically handles screen rotation, as needed in UWP on mobiles.443if (gstate_c.IsDirty(DIRTY_VIEWPORTSCISSOR_STATE)) {444draw_->SetViewport(dynState_.viewport);445draw_->SetScissorRect(dynState_.scissor.left, dynState_.scissor.top, dynState_.scissor.right - dynState_.scissor.left, dynState_.scissor.bottom - dynState_.scissor.top);446}447if (gstate_c.IsDirty(DIRTY_RASTER_STATE)) {448context_->RSSetState(rasterState_);449}450if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) {451// Need to do this AFTER ApplyTexture because the process of depalettization can ruin the blend state.452float blendColor[4];453Uint8x4ToFloat4(blendColor, dynState_.blendColor);454if (device1_) {455context1_->OMSetBlendState(blendState1_, blendColor, 0xFFFFFFFF);456} else {457context_->OMSetBlendState(blendState_, blendColor, 0xFFFFFFFF);458}459}460if (gstate_c.IsDirty(DIRTY_DEPTHSTENCIL_STATE) || applyStencilRef) {461context_->OMSetDepthStencilState(depthStencilState_, applyStencilRef ? stencilRef : dynState_.stencilRef);462}463gstate_c.Clean(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_BLEND_STATE);464gstate_c.Dirty(dirtyRequiresRecheck_);465dirtyRequiresRecheck_ = 0;466}467468469