mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Reorganize depth-stencil
This commit is contained in:
parent
d581a96d79
commit
cffb1d7014
4 changed files with 369 additions and 363 deletions
|
@ -148,8 +148,7 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
|
|||
bool alphaMask = gstate.isClearModeAlphaMask();
|
||||
bool colorMask = gstate.isClearModeColorMask();
|
||||
keys_.blend.colorWriteMask = (colorMask ? (1 | 2 | 4) : 0) | (alphaMask ? 8 : 0);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Set blend - unless we need to do it in the shader.
|
||||
GenericBlendState blendState;
|
||||
ConvertBlendState(blendState, gstate_c.allowShaderBlend);
|
||||
|
@ -158,14 +157,12 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
|
|||
if (ApplyShaderBlending()) {
|
||||
// We may still want to do something about stencil -> alpha.
|
||||
ApplyStencilReplaceAndLogicOp(blendState.replaceAlphaWithStencil, blendState);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Until next time, force it off.
|
||||
ResetShaderBlending();
|
||||
gstate_c.allowShaderBlend = false;
|
||||
}
|
||||
}
|
||||
else if (blendState.resetShaderBlending) {
|
||||
} else if (blendState.resetShaderBlending) {
|
||||
ResetShaderBlending();
|
||||
}
|
||||
|
||||
|
@ -185,8 +182,7 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
|
|||
if (blendState.useBlendColor) {
|
||||
dynState_.blendColor = blendState.blendColor;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
keys_.blend.blendEnable = false;
|
||||
dynState_.useBlendColor = false;
|
||||
}
|
||||
|
@ -197,8 +193,7 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
|
|||
keys_.blend.blendEnable = false; // Can't have both blend & logic op - although I think the PSP can!
|
||||
keys_.blend.logicOpEnable = true;
|
||||
keys_.blend.logicOp = logicOps[gstate.getLogicOp()];
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
keys_.blend.logicOpEnable = false;
|
||||
}
|
||||
}
|
||||
|
@ -240,120 +235,120 @@ void DrawEngineD3D11::ApplyDrawState(int prim) {
|
|||
|
||||
dynState_.useStencil = false;
|
||||
|
||||
// Set ColorMask/Stencil/Depth
|
||||
if (gstate.isModeClear()) {
|
||||
keys_.raster.cullMode = D3D11_CULL_NONE;
|
||||
{
|
||||
// Set ColorMask/Stencil/Depth
|
||||
if (gstate.isModeClear()) {
|
||||
keys_.raster.cullMode = D3D11_CULL_NONE;
|
||||
|
||||
keys_.depthStencil.depthTestEnable = true;
|
||||
keys_.depthStencil.depthCompareOp = D3D11_COMPARISON_ALWAYS;
|
||||
keys_.depthStencil.depthWriteEnable = gstate.isClearModeDepthMask();
|
||||
if (gstate.isClearModeDepthMask()) {
|
||||
framebufferManager_->SetDepthUpdated();
|
||||
}
|
||||
|
||||
// Stencil Test
|
||||
bool alphaMask = gstate.isClearModeAlphaMask();
|
||||
if (alphaMask) {
|
||||
keys_.depthStencil.stencilTestEnable = true;
|
||||
keys_.depthStencil.stencilCompareFunc = D3D11_COMPARISON_ALWAYS;
|
||||
keys_.depthStencil.stencilPassOp = D3D11_STENCIL_OP_REPLACE;
|
||||
keys_.depthStencil.stencilFailOp = D3D11_STENCIL_OP_REPLACE;
|
||||
keys_.depthStencil.stencilDepthFailOp = D3D11_STENCIL_OP_REPLACE;
|
||||
dynState_.useStencil = true;
|
||||
// In clear mode, the stencil value is set to the alpha value of the vertex.
|
||||
// A normal clear will be 2 points, the second point has the color.
|
||||
// We override this value in the pipeline from software transform for clear rectangles.
|
||||
dynState_.stencilRef = 0xFF;
|
||||
keys_.depthStencil.stencilWriteMask = 0xFF;
|
||||
}
|
||||
else {
|
||||
keys_.depthStencil.stencilTestEnable = false;
|
||||
dynState_.useStencil = false;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
// Set cull
|
||||
bool wantCull = !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES && gstate.isCullEnabled();
|
||||
keys_.raster.cullMode = wantCull ? (gstate.getCullMode() ? D3D11_CULL_FRONT : D3D11_CULL_BACK) : D3D11_CULL_NONE;
|
||||
|
||||
// Depth Test
|
||||
if (gstate.isDepthTestEnabled()) {
|
||||
keys_.depthStencil.depthTestEnable = true;
|
||||
keys_.depthStencil.depthCompareOp = compareOps[gstate.getDepthTestFunction()];
|
||||
keys_.depthStencil.depthWriteEnable = gstate.isDepthWriteEnabled();
|
||||
if (gstate.isDepthWriteEnabled()) {
|
||||
keys_.depthStencil.depthCompareOp = D3D11_COMPARISON_ALWAYS;
|
||||
keys_.depthStencil.depthWriteEnable = gstate.isClearModeDepthMask();
|
||||
if (gstate.isClearModeDepthMask()) {
|
||||
framebufferManager_->SetDepthUpdated();
|
||||
}
|
||||
}
|
||||
else {
|
||||
keys_.depthStencil.depthTestEnable = false;
|
||||
keys_.depthStencil.depthWriteEnable = false;
|
||||
keys_.depthStencil.depthCompareOp = D3D11_COMPARISON_ALWAYS;
|
||||
}
|
||||
|
||||
GenericStencilFuncState stencilState;
|
||||
ConvertStencilFuncState(stencilState);
|
||||
// Stencil Test
|
||||
bool alphaMask = gstate.isClearModeAlphaMask();
|
||||
if (alphaMask) {
|
||||
keys_.depthStencil.stencilTestEnable = true;
|
||||
keys_.depthStencil.stencilCompareFunc = D3D11_COMPARISON_ALWAYS;
|
||||
keys_.depthStencil.stencilPassOp = D3D11_STENCIL_OP_REPLACE;
|
||||
keys_.depthStencil.stencilFailOp = D3D11_STENCIL_OP_REPLACE;
|
||||
keys_.depthStencil.stencilDepthFailOp = D3D11_STENCIL_OP_REPLACE;
|
||||
dynState_.useStencil = true;
|
||||
// In clear mode, the stencil value is set to the alpha value of the vertex.
|
||||
// A normal clear will be 2 points, the second point has the color.
|
||||
// We override this value in the pipeline from software transform for clear rectangles.
|
||||
dynState_.stencilRef = 0xFF;
|
||||
keys_.depthStencil.stencilWriteMask = 0xFF;
|
||||
} else {
|
||||
keys_.depthStencil.stencilTestEnable = false;
|
||||
dynState_.useStencil = false;
|
||||
}
|
||||
|
||||
// Stencil Test
|
||||
if (stencilState.enabled) {
|
||||
keys_.depthStencil.stencilTestEnable = true;
|
||||
keys_.depthStencil.stencilCompareFunc = compareOps[stencilState.testFunc];
|
||||
keys_.depthStencil.stencilPassOp = stencilOps[stencilState.zPass];
|
||||
keys_.depthStencil.stencilFailOp = stencilOps[stencilState.sFail];
|
||||
keys_.depthStencil.stencilDepthFailOp = stencilOps[stencilState.zFail];
|
||||
keys_.depthStencil.stencilCompareMask = stencilState.testMask;
|
||||
keys_.depthStencil.stencilWriteMask = stencilState.writeMask;
|
||||
dynState_.useStencil = true;
|
||||
dynState_.stencilRef = stencilState.testRef;
|
||||
} else {
|
||||
keys_.depthStencil.stencilTestEnable = false;
|
||||
dynState_.useStencil = false;
|
||||
// Set cull
|
||||
bool wantCull = !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES && gstate.isCullEnabled();
|
||||
keys_.raster.cullMode = wantCull ? (gstate.getCullMode() ? D3D11_CULL_FRONT : D3D11_CULL_BACK) : D3D11_CULL_NONE;
|
||||
|
||||
// Depth Test
|
||||
if (gstate.isDepthTestEnabled()) {
|
||||
keys_.depthStencil.depthTestEnable = true;
|
||||
keys_.depthStencil.depthCompareOp = compareOps[gstate.getDepthTestFunction()];
|
||||
keys_.depthStencil.depthWriteEnable = gstate.isDepthWriteEnabled();
|
||||
if (gstate.isDepthWriteEnabled()) {
|
||||
framebufferManager_->SetDepthUpdated();
|
||||
}
|
||||
} else {
|
||||
keys_.depthStencil.depthTestEnable = false;
|
||||
keys_.depthStencil.depthWriteEnable = false;
|
||||
keys_.depthStencil.depthCompareOp = D3D11_COMPARISON_ALWAYS;
|
||||
}
|
||||
|
||||
GenericStencilFuncState stencilState;
|
||||
ConvertStencilFuncState(stencilState);
|
||||
|
||||
// Stencil Test
|
||||
if (stencilState.enabled) {
|
||||
keys_.depthStencil.stencilTestEnable = true;
|
||||
keys_.depthStencil.stencilCompareFunc = compareOps[stencilState.testFunc];
|
||||
keys_.depthStencil.stencilPassOp = stencilOps[stencilState.zPass];
|
||||
keys_.depthStencil.stencilFailOp = stencilOps[stencilState.sFail];
|
||||
keys_.depthStencil.stencilDepthFailOp = stencilOps[stencilState.zFail];
|
||||
keys_.depthStencil.stencilCompareMask = stencilState.testMask;
|
||||
keys_.depthStencil.stencilWriteMask = stencilState.writeMask;
|
||||
dynState_.useStencil = true;
|
||||
dynState_.stencilRef = stencilState.testRef;
|
||||
} else {
|
||||
keys_.depthStencil.stencilTestEnable = false;
|
||||
dynState_.useStencil = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
ViewportAndScissor vpAndScissor;
|
||||
ConvertViewportAndScissor(useBufferedRendering,
|
||||
framebufferManager_->GetRenderWidth(), framebufferManager_->GetRenderHeight(),
|
||||
framebufferManager_->GetTargetBufferWidth(), framebufferManager_->GetTargetBufferHeight(),
|
||||
vpAndScissor);
|
||||
|
||||
float depthMin = vpAndScissor.depthRangeMin;
|
||||
float depthMax = vpAndScissor.depthRangeMax;
|
||||
|
||||
if (depthMin < 0.0f) depthMin = 0.0f;
|
||||
if (depthMax > 1.0f) depthMax = 1.0f;
|
||||
if (vpAndScissor.dirtyDepth) {
|
||||
gstate_c.Dirty(DIRTY_DEPTHRANGE);
|
||||
}
|
||||
|
||||
Draw::Viewport &vp = dynState_.viewport;
|
||||
vp.TopLeftX = vpAndScissor.viewportX;
|
||||
vp.TopLeftY = vpAndScissor.viewportY;
|
||||
vp.Width = vpAndScissor.viewportW;
|
||||
vp.Height = vpAndScissor.viewportH;
|
||||
vp.MinDepth = depthMin;
|
||||
vp.MaxDepth = depthMax;
|
||||
if (vpAndScissor.dirtyProj) {
|
||||
gstate_c.Dirty(DIRTY_PROJMATRIX);
|
||||
}
|
||||
|
||||
D3D11_RECT &scissor = dynState_.scissor;
|
||||
if (vpAndScissor.scissorEnable) {
|
||||
scissor.left = vpAndScissor.scissorX;
|
||||
scissor.top = vpAndScissor.scissorY;
|
||||
scissor.right = vpAndScissor.scissorX + std::max(0, vpAndScissor.scissorW);
|
||||
scissor.bottom = vpAndScissor.scissorY + std::max(0, vpAndScissor.scissorH);
|
||||
} else {
|
||||
scissor.left = 0;
|
||||
scissor.top = 0;
|
||||
scissor.right = framebufferManager_->GetRenderWidth();
|
||||
scissor.bottom = framebufferManager_->GetRenderHeight();
|
||||
}
|
||||
}
|
||||
|
||||
dynState_.topology = primToD3D11[prim];
|
||||
|
||||
ViewportAndScissor vpAndScissor;
|
||||
ConvertViewportAndScissor(useBufferedRendering,
|
||||
framebufferManager_->GetRenderWidth(), framebufferManager_->GetRenderHeight(),
|
||||
framebufferManager_->GetTargetBufferWidth(), framebufferManager_->GetTargetBufferHeight(),
|
||||
vpAndScissor);
|
||||
|
||||
float depthMin = vpAndScissor.depthRangeMin;
|
||||
float depthMax = vpAndScissor.depthRangeMax;
|
||||
|
||||
if (depthMin < 0.0f) depthMin = 0.0f;
|
||||
if (depthMax > 1.0f) depthMax = 1.0f;
|
||||
if (vpAndScissor.dirtyDepth) {
|
||||
gstate_c.Dirty(DIRTY_DEPTHRANGE);
|
||||
}
|
||||
|
||||
Draw::Viewport &vp = dynState_.viewport;
|
||||
vp.TopLeftX = vpAndScissor.viewportX;
|
||||
vp.TopLeftY = vpAndScissor.viewportY;
|
||||
vp.Width = vpAndScissor.viewportW;
|
||||
vp.Height = vpAndScissor.viewportH;
|
||||
vp.MinDepth = depthMin;
|
||||
vp.MaxDepth = depthMax;
|
||||
if (vpAndScissor.dirtyProj) {
|
||||
gstate_c.Dirty(DIRTY_PROJMATRIX);
|
||||
}
|
||||
|
||||
D3D11_RECT &scissor = dynState_.scissor;
|
||||
if (vpAndScissor.scissorEnable) {
|
||||
scissor.left = vpAndScissor.scissorX;
|
||||
scissor.top = vpAndScissor.scissorY;
|
||||
scissor.right = vpAndScissor.scissorX + std::max(0, vpAndScissor.scissorW);
|
||||
scissor.bottom = vpAndScissor.scissorY + std::max(0, vpAndScissor.scissorH);
|
||||
}
|
||||
else {
|
||||
scissor.left = 0;
|
||||
scissor.top = 0;
|
||||
scissor.right = framebufferManager_->GetRenderWidth();
|
||||
scissor.bottom = framebufferManager_->GetRenderHeight();
|
||||
}
|
||||
|
||||
if (gstate_c.IsDirty(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS) && !gstate.isModeClear() && gstate.isTextureMapEnabled()) {
|
||||
textureCache_->SetTexture();
|
||||
gstate_c.Clean(DIRTY_TEXTURE_IMAGE | DIRTY_TEXTURE_PARAMS);
|
||||
|
|
|
@ -205,83 +205,87 @@ void DrawEngineDX9::ApplyDrawState(int prim) {
|
|||
dxstate.dither.disable();
|
||||
}
|
||||
|
||||
// Set ColorMask/Stencil/Depth
|
||||
if (gstate.isModeClear()) {
|
||||
// Set Cull
|
||||
dxstate.cullMode.set(false, false);
|
||||
|
||||
// Depth Test
|
||||
dxstate.depthTest.enable();
|
||||
dxstate.depthFunc.set(D3DCMP_ALWAYS);
|
||||
dxstate.depthWrite.set(gstate.isClearModeDepthMask());
|
||||
if (gstate.isClearModeDepthMask() || alwaysDepthWrite) {
|
||||
framebufferManager_->SetDepthUpdated();
|
||||
}
|
||||
{
|
||||
// Set Stencil/Depth
|
||||
if (gstate.isModeClear()) {
|
||||
// Set Cull
|
||||
dxstate.cullMode.set(false, false);
|
||||
|
||||
// Stencil Test
|
||||
bool alphaMask = gstate.isClearModeAlphaMask();
|
||||
if (alphaMask && enableStencilTest) {
|
||||
dxstate.stencilTest.enable();
|
||||
dxstate.stencilOp.set(D3DSTENCILOP_REPLACE, D3DSTENCILOP_REPLACE, D3DSTENCILOP_REPLACE);
|
||||
dxstate.stencilFunc.set(D3DCMP_ALWAYS, 255, 0xFF);
|
||||
dxstate.stencilMask.set(0xFF);
|
||||
} else {
|
||||
dxstate.stencilTest.disable();
|
||||
}
|
||||
|
||||
} else {
|
||||
// Set cull
|
||||
bool wantCull = !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES && gstate.isCullEnabled();
|
||||
dxstate.cullMode.set(wantCull, gstate.getCullMode());
|
||||
|
||||
// Depth Test
|
||||
if (gstate.isDepthTestEnabled()) {
|
||||
// Depth Test
|
||||
dxstate.depthTest.enable();
|
||||
dxstate.depthFunc.set(ztests[gstate.getDepthTestFunction()]);
|
||||
dxstate.depthWrite.set(gstate.isDepthWriteEnabled());
|
||||
if (gstate.isDepthWriteEnabled()) {
|
||||
dxstate.depthFunc.set(D3DCMP_ALWAYS);
|
||||
dxstate.depthWrite.set(gstate.isClearModeDepthMask());
|
||||
if (gstate.isClearModeDepthMask() || alwaysDepthWrite) {
|
||||
framebufferManager_->SetDepthUpdated();
|
||||
}
|
||||
} else {
|
||||
dxstate.depthTest.disable();
|
||||
}
|
||||
|
||||
GenericStencilFuncState stencilState;
|
||||
ConvertStencilFuncState(stencilState);
|
||||
// Stencil Test
|
||||
bool alphaMask = gstate.isClearModeAlphaMask();
|
||||
if (alphaMask && enableStencilTest) {
|
||||
dxstate.stencilTest.enable();
|
||||
dxstate.stencilOp.set(D3DSTENCILOP_REPLACE, D3DSTENCILOP_REPLACE, D3DSTENCILOP_REPLACE);
|
||||
dxstate.stencilFunc.set(D3DCMP_ALWAYS, 255, 0xFF);
|
||||
dxstate.stencilMask.set(0xFF);
|
||||
} else {
|
||||
dxstate.stencilTest.disable();
|
||||
}
|
||||
|
||||
// Stencil Test
|
||||
if (stencilState.enabled) {
|
||||
dxstate.stencilTest.enable();
|
||||
dxstate.stencilFunc.set(ztests[stencilState.testFunc], stencilState.testRef, stencilState.testMask);
|
||||
dxstate.stencilOp.set(stencilOps[stencilState.sFail], stencilOps[stencilState.zFail], stencilOps[stencilState.zPass]);
|
||||
dxstate.stencilMask.set(stencilState.writeMask);
|
||||
} else {
|
||||
dxstate.stencilTest.disable();
|
||||
// Set cull
|
||||
bool wantCull = !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES && gstate.isCullEnabled();
|
||||
dxstate.cullMode.set(wantCull, gstate.getCullMode());
|
||||
|
||||
// Depth Test
|
||||
if (gstate.isDepthTestEnabled()) {
|
||||
dxstate.depthTest.enable();
|
||||
dxstate.depthFunc.set(ztests[gstate.getDepthTestFunction()]);
|
||||
dxstate.depthWrite.set(gstate.isDepthWriteEnabled());
|
||||
if (gstate.isDepthWriteEnabled()) {
|
||||
framebufferManager_->SetDepthUpdated();
|
||||
}
|
||||
} else {
|
||||
dxstate.depthTest.disable();
|
||||
}
|
||||
|
||||
GenericStencilFuncState stencilState;
|
||||
ConvertStencilFuncState(stencilState);
|
||||
|
||||
// Stencil Test
|
||||
if (stencilState.enabled) {
|
||||
dxstate.stencilTest.enable();
|
||||
dxstate.stencilFunc.set(ztests[stencilState.testFunc], stencilState.testRef, stencilState.testMask);
|
||||
dxstate.stencilOp.set(stencilOps[stencilState.sFail], stencilOps[stencilState.zFail], stencilOps[stencilState.zPass]);
|
||||
dxstate.stencilMask.set(stencilState.writeMask);
|
||||
} else {
|
||||
dxstate.stencilTest.disable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ViewportAndScissor vpAndScissor;
|
||||
ConvertViewportAndScissor(useBufferedRendering,
|
||||
framebufferManager_->GetRenderWidth(), framebufferManager_->GetRenderHeight(),
|
||||
framebufferManager_->GetTargetBufferWidth(), framebufferManager_->GetTargetBufferHeight(),
|
||||
vpAndScissor);
|
||||
{
|
||||
ViewportAndScissor vpAndScissor;
|
||||
ConvertViewportAndScissor(useBufferedRendering,
|
||||
framebufferManager_->GetRenderWidth(), framebufferManager_->GetRenderHeight(),
|
||||
framebufferManager_->GetTargetBufferWidth(), framebufferManager_->GetTargetBufferHeight(),
|
||||
vpAndScissor);
|
||||
|
||||
if (vpAndScissor.scissorEnable) {
|
||||
dxstate.scissorTest.enable();
|
||||
dxstate.scissorRect.set(vpAndScissor.scissorX, vpAndScissor.scissorY, vpAndScissor.scissorX + vpAndScissor.scissorW, vpAndScissor.scissorY + vpAndScissor.scissorH);
|
||||
} else {
|
||||
dxstate.scissorTest.disable();
|
||||
}
|
||||
if (vpAndScissor.scissorEnable) {
|
||||
dxstate.scissorTest.enable();
|
||||
dxstate.scissorRect.set(vpAndScissor.scissorX, vpAndScissor.scissorY, vpAndScissor.scissorX + vpAndScissor.scissorW, vpAndScissor.scissorY + vpAndScissor.scissorH);
|
||||
} else {
|
||||
dxstate.scissorTest.disable();
|
||||
}
|
||||
|
||||
float depthMin = vpAndScissor.depthRangeMin;
|
||||
float depthMax = vpAndScissor.depthRangeMax;
|
||||
float depthMin = vpAndScissor.depthRangeMin;
|
||||
float depthMax = vpAndScissor.depthRangeMax;
|
||||
|
||||
dxstate.viewport.set(vpAndScissor.viewportX, vpAndScissor.viewportY, vpAndScissor.viewportW, vpAndScissor.viewportH, depthMin, depthMax);
|
||||
if (vpAndScissor.dirtyProj) {
|
||||
gstate_c.Dirty(DIRTY_PROJMATRIX);
|
||||
}
|
||||
if (vpAndScissor.dirtyDepth) {
|
||||
gstate_c.Dirty(DIRTY_DEPTHRANGE);
|
||||
dxstate.viewport.set(vpAndScissor.viewportX, vpAndScissor.viewportY, vpAndScissor.viewportW, vpAndScissor.viewportH, depthMin, depthMax);
|
||||
if (vpAndScissor.dirtyProj) {
|
||||
gstate_c.Dirty(DIRTY_PROJMATRIX);
|
||||
}
|
||||
if (vpAndScissor.dirtyDepth) {
|
||||
gstate_c.Dirty(DIRTY_DEPTHRANGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -167,6 +167,12 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
|
|||
bool colorMask = gstate.isClearModeColorMask();
|
||||
bool alphaMask = gstate.isClearModeAlphaMask();
|
||||
glstate.colorMask.set(colorMask, colorMask, colorMask, alphaMask);
|
||||
#ifndef USING_GLES2
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_LOGIC_OP)) {
|
||||
// Logic Ops
|
||||
glstate.colorLogicOp.disable();
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
// Do the large chunks of state conversion. We might be able to hide these two behind a dirty-flag each,
|
||||
// to avoid recomputing heavy stuff unnecessarily every draw call.
|
||||
|
@ -230,12 +236,22 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
|
|||
#endif
|
||||
|
||||
glstate.colorMask.set(rmask, gmask, bmask, amask);
|
||||
|
||||
#ifndef USING_GLES2
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_LOGIC_OP)) {
|
||||
// TODO: Make this dynamic
|
||||
// Logic Ops
|
||||
if (gstate.isLogicOpEnabled() && gstate.getLogicOp() != GE_LOGIC_COPY) {
|
||||
glstate.colorLogicOp.enable();
|
||||
glstate.logicOp.set(logicOps[gstate.getLogicOp()]);
|
||||
} else {
|
||||
glstate.colorLogicOp.disable();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
bool alwaysDepthWrite = g_Config.bAlwaysDepthWrite;
|
||||
bool enableStencilTest = !g_Config.bDisableStencilTest;
|
||||
|
||||
// Dither
|
||||
if (gstate.isDitherEnabled()) {
|
||||
glstate.dither.enable();
|
||||
|
@ -245,49 +261,9 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
|
|||
}
|
||||
|
||||
if (gstate.isModeClear()) {
|
||||
#ifndef USING_GLES2
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_LOGIC_OP)) {
|
||||
// Logic Ops
|
||||
glstate.colorLogicOp.disable();
|
||||
}
|
||||
#endif
|
||||
// Culling
|
||||
glstate.cullFace.disable();
|
||||
|
||||
// Depth Test
|
||||
glstate.depthTest.enable();
|
||||
glstate.depthFunc.set(GL_ALWAYS);
|
||||
glstate.depthWrite.set(gstate.isClearModeDepthMask() || alwaysDepthWrite ? GL_TRUE : GL_FALSE);
|
||||
if (gstate.isClearModeDepthMask() || alwaysDepthWrite) {
|
||||
framebufferManager_->SetDepthUpdated();
|
||||
}
|
||||
|
||||
// Stencil Test
|
||||
if (gstate.isClearModeAlphaMask() && enableStencilTest) {
|
||||
glstate.stencilTest.enable();
|
||||
glstate.stencilOp.set(GL_REPLACE, GL_REPLACE, GL_REPLACE);
|
||||
// TODO: In clear mode, the stencil value is set to the alpha value of the vertex.
|
||||
// A normal clear will be 2 points, the second point has the color.
|
||||
// We should set "ref" to that value instead of 0.
|
||||
// In case of clear rectangles, we set it again once we know what the color is.
|
||||
glstate.stencilFunc.set(GL_ALWAYS, 255, 0xFF);
|
||||
glstate.stencilMask.set(0xFF);
|
||||
} else {
|
||||
glstate.stencilTest.disable();
|
||||
}
|
||||
} else {
|
||||
#ifndef USING_GLES2
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_LOGIC_OP)) {
|
||||
// TODO: Make this dynamic
|
||||
// Logic Ops
|
||||
if (gstate.isLogicOpEnabled() && gstate.getLogicOp() != GE_LOGIC_COPY) {
|
||||
glstate.colorLogicOp.enable();
|
||||
glstate.logicOp.set(logicOps[gstate.getLogicOp()]);
|
||||
} else {
|
||||
glstate.colorLogicOp.disable();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// Set cull
|
||||
bool cullEnabled = !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES && gstate.isCullEnabled();
|
||||
if (cullEnabled) {
|
||||
|
@ -296,60 +272,90 @@ void DrawEngineGLES::ApplyDrawState(int prim) {
|
|||
} else {
|
||||
glstate.cullFace.disable();
|
||||
}
|
||||
}
|
||||
|
||||
// Depth Test
|
||||
if (gstate.isDepthTestEnabled()) {
|
||||
{
|
||||
bool alwaysDepthWrite = g_Config.bAlwaysDepthWrite;
|
||||
bool enableStencilTest = !g_Config.bDisableStencilTest;
|
||||
if (gstate.isModeClear()) {
|
||||
// Depth Test
|
||||
glstate.depthTest.enable();
|
||||
glstate.depthFunc.set(compareOps[gstate.getDepthTestFunction()]);
|
||||
glstate.depthWrite.set(gstate.isDepthWriteEnabled() || alwaysDepthWrite ? GL_TRUE : GL_FALSE);
|
||||
if (gstate.isDepthWriteEnabled() || alwaysDepthWrite) {
|
||||
glstate.depthFunc.set(GL_ALWAYS);
|
||||
glstate.depthWrite.set(gstate.isClearModeDepthMask() || alwaysDepthWrite ? GL_TRUE : GL_FALSE);
|
||||
if (gstate.isClearModeDepthMask() || alwaysDepthWrite) {
|
||||
framebufferManager_->SetDepthUpdated();
|
||||
}
|
||||
} else {
|
||||
glstate.depthTest.disable();
|
||||
}
|
||||
|
||||
GenericStencilFuncState stencilState;
|
||||
ConvertStencilFuncState(stencilState);
|
||||
|
||||
// Stencil Test
|
||||
if (stencilState.enabled) {
|
||||
glstate.stencilTest.enable();
|
||||
glstate.stencilFunc.set(compareOps[stencilState.testFunc], stencilState.testRef, stencilState.testMask);
|
||||
glstate.stencilOp.set(stencilOps[stencilState.sFail], stencilOps[stencilState.zFail], stencilOps[stencilState.zPass]);
|
||||
glstate.stencilMask.set(stencilState.writeMask);
|
||||
// Stencil Test
|
||||
if (gstate.isClearModeAlphaMask() && enableStencilTest) {
|
||||
glstate.stencilTest.enable();
|
||||
glstate.stencilOp.set(GL_REPLACE, GL_REPLACE, GL_REPLACE);
|
||||
// TODO: In clear mode, the stencil value is set to the alpha value of the vertex.
|
||||
// A normal clear will be 2 points, the second point has the color.
|
||||
// We should set "ref" to that value instead of 0.
|
||||
// In case of clear rectangles, we set it again once we know what the color is.
|
||||
glstate.stencilFunc.set(GL_ALWAYS, 255, 0xFF);
|
||||
glstate.stencilMask.set(0xFF);
|
||||
} else {
|
||||
glstate.stencilTest.disable();
|
||||
}
|
||||
} else {
|
||||
glstate.stencilTest.disable();
|
||||
// Depth Test
|
||||
if (gstate.isDepthTestEnabled()) {
|
||||
glstate.depthTest.enable();
|
||||
glstate.depthFunc.set(compareOps[gstate.getDepthTestFunction()]);
|
||||
glstate.depthWrite.set(gstate.isDepthWriteEnabled() || alwaysDepthWrite ? GL_TRUE : GL_FALSE);
|
||||
if (gstate.isDepthWriteEnabled() || alwaysDepthWrite) {
|
||||
framebufferManager_->SetDepthUpdated();
|
||||
}
|
||||
} else {
|
||||
glstate.depthTest.disable();
|
||||
}
|
||||
|
||||
GenericStencilFuncState stencilState;
|
||||
ConvertStencilFuncState(stencilState);
|
||||
|
||||
// Stencil Test
|
||||
if (stencilState.enabled) {
|
||||
glstate.stencilTest.enable();
|
||||
glstate.stencilFunc.set(compareOps[stencilState.testFunc], stencilState.testRef, stencilState.testMask);
|
||||
glstate.stencilOp.set(stencilOps[stencilState.sFail], stencilOps[stencilState.zFail], stencilOps[stencilState.zPass]);
|
||||
glstate.stencilMask.set(stencilState.writeMask);
|
||||
} else {
|
||||
glstate.stencilTest.disable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ViewportAndScissor vpAndScissor;
|
||||
ConvertViewportAndScissor(useBufferedRendering,
|
||||
framebufferManager_->GetRenderWidth(), framebufferManager_->GetRenderHeight(),
|
||||
framebufferManager_->GetTargetBufferWidth(), framebufferManager_->GetTargetBufferHeight(),
|
||||
vpAndScissor);
|
||||
{
|
||||
ViewportAndScissor vpAndScissor;
|
||||
ConvertViewportAndScissor(useBufferedRendering,
|
||||
framebufferManager_->GetRenderWidth(), framebufferManager_->GetRenderHeight(),
|
||||
framebufferManager_->GetTargetBufferWidth(), framebufferManager_->GetTargetBufferHeight(),
|
||||
vpAndScissor);
|
||||
|
||||
if (vpAndScissor.scissorEnable) {
|
||||
glstate.scissorTest.enable();
|
||||
if (!useBufferedRendering) {
|
||||
vpAndScissor.scissorY = PSP_CoreParameter().pixelHeight - vpAndScissor.scissorH - vpAndScissor.scissorY;
|
||||
}
|
||||
glstate.scissorRect.set(vpAndScissor.scissorX, vpAndScissor.scissorY, vpAndScissor.scissorW, vpAndScissor.scissorH);
|
||||
} else {
|
||||
glstate.scissorTest.disable();
|
||||
}
|
||||
|
||||
if (vpAndScissor.scissorEnable) {
|
||||
glstate.scissorTest.enable();
|
||||
if (!useBufferedRendering) {
|
||||
vpAndScissor.scissorY = PSP_CoreParameter().pixelHeight - vpAndScissor.scissorH - vpAndScissor.scissorY;
|
||||
vpAndScissor.viewportY = PSP_CoreParameter().pixelHeight - vpAndScissor.viewportH - vpAndScissor.viewportY;
|
||||
}
|
||||
glstate.scissorRect.set(vpAndScissor.scissorX, vpAndScissor.scissorY, vpAndScissor.scissorW, vpAndScissor.scissorH);
|
||||
} else {
|
||||
glstate.scissorTest.disable();
|
||||
}
|
||||
glstate.viewport.set(vpAndScissor.viewportX, vpAndScissor.viewportY, vpAndScissor.viewportW, vpAndScissor.viewportH);
|
||||
glstate.depthRange.set(vpAndScissor.depthRangeMin, vpAndScissor.depthRangeMax);
|
||||
|
||||
if (!useBufferedRendering) {
|
||||
vpAndScissor.viewportY = PSP_CoreParameter().pixelHeight - vpAndScissor.viewportH - vpAndScissor.viewportY;
|
||||
}
|
||||
glstate.viewport.set(vpAndScissor.viewportX, vpAndScissor.viewportY, vpAndScissor.viewportW, vpAndScissor.viewportH);
|
||||
glstate.depthRange.set(vpAndScissor.depthRangeMin, vpAndScissor.depthRangeMax);
|
||||
|
||||
if (vpAndScissor.dirtyProj) {
|
||||
gstate_c.Dirty(DIRTY_PROJMATRIX);
|
||||
}
|
||||
if (vpAndScissor.dirtyDepth) {
|
||||
gstate_c.Dirty(DIRTY_DEPTHRANGE);
|
||||
if (vpAndScissor.dirtyProj) {
|
||||
gstate_c.Dirty(DIRTY_PROJMATRIX);
|
||||
}
|
||||
if (vpAndScissor.dirtyDepth) {
|
||||
gstate_c.Dirty(DIRTY_DEPTHRANGE);
|
||||
}
|
||||
}
|
||||
CHECK_GL_ERROR_IF_DEBUG();
|
||||
}
|
||||
|
|
|
@ -220,117 +220,118 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag
|
|||
}
|
||||
}
|
||||
|
||||
dynState.useStencil = false;
|
||||
{
|
||||
// Set Stencil/Depth
|
||||
if (gstate.isModeClear()) {
|
||||
key.cullMode = VK_CULL_MODE_NONE;
|
||||
|
||||
// Set Stencil/Depth
|
||||
if (gstate.isModeClear()) {
|
||||
key.cullMode = VK_CULL_MODE_NONE;
|
||||
|
||||
key.depthTestEnable = true;
|
||||
key.depthCompareOp = VK_COMPARE_OP_ALWAYS;
|
||||
key.depthWriteEnable = gstate.isClearModeDepthMask();
|
||||
if (gstate.isClearModeDepthMask()) {
|
||||
fbManager.SetDepthUpdated();
|
||||
}
|
||||
|
||||
// Stencil Test
|
||||
bool alphaMask = gstate.isClearModeAlphaMask();
|
||||
if (alphaMask) {
|
||||
key.stencilTestEnable = true;
|
||||
key.stencilCompareOp = VK_COMPARE_OP_ALWAYS;
|
||||
key.stencilPassOp = VK_STENCIL_OP_REPLACE;
|
||||
key.stencilFailOp = VK_STENCIL_OP_REPLACE;
|
||||
key.stencilDepthFailOp = VK_STENCIL_OP_REPLACE;
|
||||
dynState.useStencil = true;
|
||||
// In clear mode, the stencil value is set to the alpha value of the vertex.
|
||||
// A normal clear will be 2 points, the second point has the color.
|
||||
// We override this value in the pipeline from software transform for clear rectangles.
|
||||
dynState.stencilRef = 0xFF;
|
||||
dynState.stencilWriteMask = 0xFF;
|
||||
} else {
|
||||
key.stencilTestEnable = false;
|
||||
dynState.useStencil = false;
|
||||
}
|
||||
} else {
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_LOGIC_OP)) {
|
||||
// Logic Ops
|
||||
if (gstate.isLogicOpEnabled() && gstate.getLogicOp() != GE_LOGIC_COPY) {
|
||||
key.logicOpEnable = true;
|
||||
key.logicOp = logicOps[gstate.getLogicOp()];
|
||||
} else {
|
||||
key.logicOpEnable = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Set cull
|
||||
bool wantCull = !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES && gstate.isCullEnabled();
|
||||
key.cullMode = wantCull ? (gstate.getCullMode() ? VK_CULL_MODE_FRONT_BIT : VK_CULL_MODE_BACK_BIT) : VK_CULL_MODE_NONE;
|
||||
|
||||
// Depth Test
|
||||
if (gstate.isDepthTestEnabled()) {
|
||||
key.depthTestEnable = true;
|
||||
key.depthCompareOp = compareOps[gstate.getDepthTestFunction()];
|
||||
key.depthWriteEnable = gstate.isDepthWriteEnabled();
|
||||
if (gstate.isDepthWriteEnabled()) {
|
||||
key.depthCompareOp = VK_COMPARE_OP_ALWAYS;
|
||||
key.depthWriteEnable = gstate.isClearModeDepthMask();
|
||||
if (gstate.isClearModeDepthMask()) {
|
||||
fbManager.SetDepthUpdated();
|
||||
}
|
||||
} else {
|
||||
key.depthTestEnable = false;
|
||||
key.depthWriteEnable = false;
|
||||
key.depthCompareOp = VK_COMPARE_OP_ALWAYS;
|
||||
}
|
||||
|
||||
GenericStencilFuncState stencilState;
|
||||
ConvertStencilFuncState(stencilState);
|
||||
|
||||
// Stencil Test
|
||||
if (stencilState.enabled) {
|
||||
key.stencilTestEnable = true;
|
||||
key.stencilCompareOp = compareOps[stencilState.testFunc];
|
||||
key.stencilPassOp = stencilOps[stencilState.zPass];
|
||||
key.stencilFailOp = stencilOps[stencilState.sFail];
|
||||
key.stencilDepthFailOp = stencilOps[stencilState.zFail];
|
||||
dynState.useStencil = true;
|
||||
dynState.stencilRef = stencilState.testRef;
|
||||
dynState.stencilCompareMask = stencilState.testMask;
|
||||
dynState.stencilWriteMask = stencilState.writeMask;
|
||||
// Stencil Test
|
||||
bool alphaMask = gstate.isClearModeAlphaMask();
|
||||
if (alphaMask) {
|
||||
key.stencilTestEnable = true;
|
||||
key.stencilCompareOp = VK_COMPARE_OP_ALWAYS;
|
||||
key.stencilPassOp = VK_STENCIL_OP_REPLACE;
|
||||
key.stencilFailOp = VK_STENCIL_OP_REPLACE;
|
||||
key.stencilDepthFailOp = VK_STENCIL_OP_REPLACE;
|
||||
dynState.useStencil = true;
|
||||
// In clear mode, the stencil value is set to the alpha value of the vertex.
|
||||
// A normal clear will be 2 points, the second point has the color.
|
||||
// We override this value in the pipeline from software transform for clear rectangles.
|
||||
dynState.stencilRef = 0xFF;
|
||||
dynState.stencilWriteMask = 0xFF;
|
||||
} else {
|
||||
key.stencilTestEnable = false;
|
||||
dynState.useStencil = false;
|
||||
}
|
||||
} else {
|
||||
key.stencilTestEnable = false;
|
||||
dynState.useStencil = false;
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_LOGIC_OP)) {
|
||||
// Logic Ops
|
||||
if (gstate.isLogicOpEnabled() && gstate.getLogicOp() != GE_LOGIC_COPY) {
|
||||
key.logicOpEnable = true;
|
||||
key.logicOp = logicOps[gstate.getLogicOp()];
|
||||
} else {
|
||||
key.logicOpEnable = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Set cull
|
||||
bool wantCull = !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES && gstate.isCullEnabled();
|
||||
key.cullMode = wantCull ? (gstate.getCullMode() ? VK_CULL_MODE_FRONT_BIT : VK_CULL_MODE_BACK_BIT) : VK_CULL_MODE_NONE;
|
||||
|
||||
// Depth Test
|
||||
if (gstate.isDepthTestEnabled()) {
|
||||
key.depthTestEnable = true;
|
||||
key.depthCompareOp = compareOps[gstate.getDepthTestFunction()];
|
||||
key.depthWriteEnable = gstate.isDepthWriteEnabled();
|
||||
if (gstate.isDepthWriteEnabled()) {
|
||||
fbManager.SetDepthUpdated();
|
||||
}
|
||||
} else {
|
||||
key.depthTestEnable = false;
|
||||
key.depthWriteEnable = false;
|
||||
key.depthCompareOp = VK_COMPARE_OP_ALWAYS;
|
||||
}
|
||||
|
||||
GenericStencilFuncState stencilState;
|
||||
ConvertStencilFuncState(stencilState);
|
||||
|
||||
// Stencil Test
|
||||
if (stencilState.enabled) {
|
||||
key.stencilTestEnable = true;
|
||||
key.stencilCompareOp = compareOps[stencilState.testFunc];
|
||||
key.stencilPassOp = stencilOps[stencilState.zPass];
|
||||
key.stencilFailOp = stencilOps[stencilState.sFail];
|
||||
key.stencilDepthFailOp = stencilOps[stencilState.zFail];
|
||||
dynState.useStencil = true;
|
||||
dynState.stencilRef = stencilState.testRef;
|
||||
dynState.stencilCompareMask = stencilState.testMask;
|
||||
dynState.stencilWriteMask = stencilState.writeMask;
|
||||
} else {
|
||||
key.stencilTestEnable = false;
|
||||
dynState.useStencil = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
ViewportAndScissor vpAndScissor;
|
||||
ConvertViewportAndScissor(useBufferedRendering,
|
||||
fbManager.GetRenderWidth(), fbManager.GetRenderHeight(),
|
||||
fbManager.GetTargetBufferWidth(), fbManager.GetTargetBufferHeight(),
|
||||
vpAndScissor);
|
||||
|
||||
VkViewport &vp = dynState.viewport;
|
||||
vp.x = vpAndScissor.viewportX;
|
||||
vp.y = vpAndScissor.viewportY;
|
||||
vp.width = vpAndScissor.viewportW;
|
||||
vp.height = vpAndScissor.viewportH;
|
||||
vp.minDepth = vpAndScissor.depthRangeMin;
|
||||
vp.maxDepth = vpAndScissor.depthRangeMax;
|
||||
if (vpAndScissor.dirtyProj) {
|
||||
gstate_c.Dirty(DIRTY_PROJMATRIX);
|
||||
}
|
||||
|
||||
VkRect2D &scissor = dynState.scissor;
|
||||
scissor.offset.x = vpAndScissor.scissorX;
|
||||
scissor.offset.y = vpAndScissor.scissorY;
|
||||
scissor.extent.width = vpAndScissor.scissorW;
|
||||
scissor.extent.height = vpAndScissor.scissorH;
|
||||
|
||||
float depthMin = vpAndScissor.depthRangeMin;
|
||||
float depthMax = vpAndScissor.depthRangeMax;
|
||||
|
||||
if (depthMin < 0.0f) depthMin = 0.0f;
|
||||
if (depthMax > 1.0f) depthMax = 1.0f;
|
||||
if (vpAndScissor.dirtyDepth) {
|
||||
gstate_c.Dirty(DIRTY_DEPTHRANGE);
|
||||
}
|
||||
}
|
||||
key.topology = primToVulkan[prim];
|
||||
|
||||
ViewportAndScissor vpAndScissor;
|
||||
ConvertViewportAndScissor(useBufferedRendering,
|
||||
fbManager.GetRenderWidth(), fbManager.GetRenderHeight(),
|
||||
fbManager.GetTargetBufferWidth(), fbManager.GetTargetBufferHeight(),
|
||||
vpAndScissor);
|
||||
|
||||
VkViewport &vp = dynState.viewport;
|
||||
vp.x = vpAndScissor.viewportX;
|
||||
vp.y = vpAndScissor.viewportY;
|
||||
vp.width = vpAndScissor.viewportW;
|
||||
vp.height = vpAndScissor.viewportH;
|
||||
vp.minDepth = vpAndScissor.depthRangeMin;
|
||||
vp.maxDepth = vpAndScissor.depthRangeMax;
|
||||
if (vpAndScissor.dirtyProj) {
|
||||
gstate_c.Dirty(DIRTY_PROJMATRIX);
|
||||
}
|
||||
|
||||
VkRect2D &scissor = dynState.scissor;
|
||||
scissor.offset.x = vpAndScissor.scissorX;
|
||||
scissor.offset.y = vpAndScissor.scissorY;
|
||||
scissor.extent.width = vpAndScissor.scissorW;
|
||||
scissor.extent.height = vpAndScissor.scissorH;
|
||||
|
||||
float depthMin = vpAndScissor.depthRangeMin;
|
||||
float depthMax = vpAndScissor.depthRangeMax;
|
||||
|
||||
if (depthMin < 0.0f) depthMin = 0.0f;
|
||||
if (depthMax > 1.0f) depthMax = 1.0f;
|
||||
if (vpAndScissor.dirtyDepth) {
|
||||
gstate_c.Dirty(DIRTY_DEPTHRANGE);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue