diff --git a/GPU/Common/FramebufferCommon.cpp b/GPU/Common/FramebufferCommon.cpp index 289dfda525..e64c2b7751 100644 --- a/GPU/Common/FramebufferCommon.cpp +++ b/GPU/Common/FramebufferCommon.cpp @@ -779,6 +779,8 @@ void FramebufferManagerCommon::DrawFramebufferToOutput(const u8 *srcPixels, GEBu SetViewport2D(0, 0, pixelWidth_, pixelHeight_); DrawActiveTexture(x, y, w, h, (float)pixelWidth_, (float)pixelHeight_, u0, v0, u1, v1, uvRotation, flags); } + + gstate_c.Dirty(DIRTY_BLEND_STATE); } void FramebufferManagerCommon::DownloadFramebufferOnSwitch(VirtualFramebuffer *vfb) { diff --git a/GPU/Common/ShaderCommon.h b/GPU/Common/ShaderCommon.h index cb1e1edd7e..d7d02f5a13 100644 --- a/GPU/Common/ShaderCommon.h +++ b/GPU/Common/ShaderCommon.h @@ -100,6 +100,14 @@ enum : uint64_t { DIRTY_TEXTURE_IMAGE = 1ULL << 41, DIRTY_TEXTURE_PARAMS = 1ULL << 42, + // Render State + DIRTY_BLEND_STATE = 1ULL << 43, + DIRTY_DEPTHSTENCIL_STATE = 1ULL << 44, + DIRTY_RASTER_STATE = 1ULL << 45, + DIRTY_VIEWPORTSCISSOR_STATE = 1ULL << 46, + DIRTY_VERTEXSHADER_STATE = 1ULL << 47, + DIRTY_FRAGMENTSHADER_STATE = 1ULL << 48, + DIRTY_ALL = 0xFFFFFFFFFFFFFFFF }; diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index f17f2830c5..c4d449f9ef 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -211,6 +211,7 @@ void FramebufferManagerD3D11::DisableState() { context_->OMSetBlendState(stockD3D11.blendStateDisabledWithColorMask[0xF], nullptr, 0xFFFFFFFF); context_->RSSetState(stockD3D11.rasterStateNoCull); context_->OMSetDepthStencilState(stockD3D11.depthStencilDisabled, 0xFF); + gstate_c.Dirty(DIRTY_BLEND_STATE); } void FramebufferManagerD3D11::CompilePostShader() { @@ -432,6 +433,7 @@ void FramebufferManagerD3D11::DrawActiveTexture(float x, float y, float w, float UINT offset = 0; context_->IASetVertexBuffers(0, 1, &quadBuffer_, &stride, &offset); context_->Draw(4, 0); + gstate_c.Dirty(DIRTY_BLEND_STATE); } void FramebufferManagerD3D11::Bind2DShader() { @@ -508,6 +510,7 @@ void FramebufferManagerD3D11::ReformatFramebufferFrom(VirtualFramebuffer *vfb, G } RebindFramebuffer(); + gstate_c.Dirty(DIRTY_BLEND_STATE); } static void CopyPixelDepthOnly(u32 *dstp, const u32 *srcp, size_t c) { @@ -709,6 +712,8 @@ void FramebufferManagerD3D11::SimpleBlit( UINT offset = 0; context_->IASetVertexBuffers(0, 1, &quadBuffer_, &stride, &offset); context_->Draw(4, 0); + + gstate_c.Dirty(DIRTY_BLEND_STATE); } void FramebufferManagerD3D11::BlitFramebuffer(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h, int bpp) { diff --git a/GPU/D3D11/GPU_D3D11.cpp b/GPU/D3D11/GPU_D3D11.cpp index 14904495f2..630825b713 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -77,7 +77,7 @@ static const D3D11CommandTableEntry commandTable[] = { // Changes that dirty the current texture. { GE_CMD_TEXSIZE0, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, 0, &GPU_D3D11::Execute_TexSize0 }, - { GE_CMD_STENCILTEST, FLAG_FLUSHBEFOREONCHANGE, DIRTY_STENCILREPLACEVALUE | DIRTY_FOGCOEF }, // These are combined in D3D11 + { GE_CMD_STENCILTEST, FLAG_FLUSHBEFOREONCHANGE, DIRTY_STENCILREPLACEVALUE | DIRTY_FOGCOEF | DIRTY_BLEND_STATE }, // These are combined in D3D11 // Changing the vertex type requires us to flush. { GE_CMD_VERTEXTYPE, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPU_D3D11::Execute_VertexType }, diff --git a/GPU/D3D11/StateMappingD3D11.cpp b/GPU/D3D11/StateMappingD3D11.cpp index dae663ca3c..a75ac4687c 100644 --- a/GPU/D3D11/StateMappingD3D11.cpp +++ b/GPU/D3D11/StateMappingD3D11.cpp @@ -135,7 +135,8 @@ void DrawEngineD3D11::ApplyDrawState(int prim) { bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; // Blend - { + if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) { + gstate_c.Clean(DIRTY_BLEND_STATE); gstate_c.SetAllowShaderBlend(!g_Config.bDisableSlowFramebufEffects); if (gstate.isModeClear()) { keys_.blend.value = 0; // full wipe diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index 4e1da0aff3..79eb6ecacc 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -61,7 +61,7 @@ static const D3D9CommandTableEntry commandTable[] = { // Changes that dirty the current texture. { GE_CMD_TEXSIZE0, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, 0, &GPU_DX9::Execute_TexSize0 }, - { GE_CMD_STENCILTEST, FLAG_FLUSHBEFOREONCHANGE, DIRTY_STENCILREPLACEVALUE }, + { GE_CMD_STENCILTEST, FLAG_FLUSHBEFOREONCHANGE, DIRTY_STENCILREPLACEVALUE | DIRTY_BLEND_STATE }, // Changing the vertex type requires us to flush. { GE_CMD_VERTEXTYPE, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPU_DX9::Execute_VertexType }, diff --git a/GPU/Directx9/StateMappingDX9.cpp b/GPU/Directx9/StateMappingDX9.cpp index 9e3abf2a7c..d621f3d70a 100644 --- a/GPU/Directx9/StateMappingDX9.cpp +++ b/GPU/Directx9/StateMappingDX9.cpp @@ -115,7 +115,8 @@ void DrawEngineDX9::ApplyDrawState(int prim) { bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; - { + if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) { + gstate_c.Clean(DIRTY_BLEND_STATE); // Unfortunately, this isn't implemented yet. gstate_c.SetAllowShaderBlend(false); if (gstate.isModeClear()) { diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index a22b4f0972..f72eadb595 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -65,7 +65,7 @@ static const GLESCommandTableEntry commandTable[] = { // Changes that dirty the current texture. { GE_CMD_TEXSIZE0, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, DIRTY_UVSCALEOFFSET, &GPU_GLES::Execute_TexSize0 }, - { GE_CMD_STENCILTEST, FLAG_FLUSHBEFOREONCHANGE, DIRTY_STENCILREPLACEVALUE }, + { GE_CMD_STENCILTEST, FLAG_FLUSHBEFOREONCHANGE, DIRTY_STENCILREPLACEVALUE | DIRTY_BLEND_STATE }, // Changing the vertex type requires us to flush. { GE_CMD_VERTEXTYPE, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPU_GLES::Execute_VertexType }, diff --git a/GPU/GLES/StateMappingGLES.cpp b/GPU/GLES/StateMappingGLES.cpp index 1437eea535..07de891722 100644 --- a/GPU/GLES/StateMappingGLES.cpp +++ b/GPU/GLES/StateMappingGLES.cpp @@ -158,7 +158,8 @@ void DrawEngineGLES::ApplyDrawState(int prim) { bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; - { + if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) { + gstate_c.Clean(DIRTY_BLEND_STATE); gstate_c.SetAllowShaderBlend(!g_Config.bDisableSlowFramebufEffects); if (gstate.isModeClear()) { @@ -256,7 +257,7 @@ void DrawEngineGLES::ApplyDrawState(int prim) { // Dither if (gstate.isDitherEnabled()) { glstate.dither.enable(); - glstate.dither.set(GL_TRUE); + glstate.dither.set(true); } else { glstate.dither.disable(); } diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index 7940cfbc17..2a058c9372 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -47,7 +47,7 @@ const CommonCommandTableEntry commonCommandTable[] = { // Changes that dirty the framebuffer { GE_CMD_FRAMEBUFPTR, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, { GE_CMD_FRAMEBUFWIDTH, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, - { GE_CMD_FRAMEBUFPIXFORMAT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS }, + { GE_CMD_FRAMEBUFPIXFORMAT, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FRAMEBUF | DIRTY_TEXTURE_PARAMS | DIRTY_BLEND_STATE }, { GE_CMD_ZBUFPTR, FLAG_FLUSHBEFOREONCHANGE }, { GE_CMD_ZBUFWIDTH, FLAG_FLUSHBEFOREONCHANGE }, @@ -56,7 +56,7 @@ const CommonCommandTableEntry commonCommandTable[] = { { GE_CMD_FOG2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FOGCOEF }, // These affect the fragment shader so need flushing. - { GE_CMD_CLEARMODE, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_CLEARMODE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_BLEND_STATE}, { GE_CMD_TEXTUREMAPENABLE, FLAG_FLUSHBEFOREONCHANGE }, { GE_CMD_FOGENABLE, FLAG_FLUSHBEFOREONCHANGE }, { GE_CMD_TEXMODE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, @@ -97,17 +97,19 @@ const CommonCommandTableEntry commonCommandTable[] = { { GE_CMD_CULL, FLAG_FLUSHBEFOREONCHANGE }, { GE_CMD_CULLFACEENABLE, FLAG_FLUSHBEFOREONCHANGE }, { GE_CMD_DITHERENABLE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_STENCILOP, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_STENCILTESTENABLE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_ALPHABLENDENABLE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_BLENDMODE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_BLENDFIXEDA, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_BLENDFIXEDB, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_MASKRGB, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_MASKALPHA, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_STENCILOP, FLAG_FLUSHBEFOREONCHANGE, DIRTY_BLEND_STATE }, + { GE_CMD_STENCILTESTENABLE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_BLEND_STATE }, + { GE_CMD_ALPHABLENDENABLE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_BLEND_STATE }, + { GE_CMD_BLENDMODE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_BLEND_STATE }, + { GE_CMD_BLENDFIXEDA, FLAG_FLUSHBEFOREONCHANGE, DIRTY_BLEND_STATE }, + { GE_CMD_BLENDFIXEDB, FLAG_FLUSHBEFOREONCHANGE, DIRTY_BLEND_STATE }, + { GE_CMD_MASKRGB, FLAG_FLUSHBEFOREONCHANGE, DIRTY_BLEND_STATE }, + { GE_CMD_MASKALPHA, FLAG_FLUSHBEFOREONCHANGE, DIRTY_BLEND_STATE }, { GE_CMD_ZTEST, FLAG_FLUSHBEFOREONCHANGE }, { GE_CMD_ZTESTENABLE, FLAG_FLUSHBEFOREONCHANGE }, { GE_CMD_ZWRITEDISABLE, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_LOGICOP, FLAG_FLUSHBEFOREONCHANGE, DIRTY_BLEND_STATE }, + { GE_CMD_LOGICOPENABLE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_BLEND_STATE }, { GE_CMD_TEXMAPMODE, FLAG_FLUSHBEFOREONCHANGE, 0 }, { GE_CMD_TEXSCALEU, FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_TexScaleU }, @@ -164,10 +166,6 @@ const CommonCommandTableEntry commonCommandTable[] = { { GE_CMD_PATCHFACING, FLAG_FLUSHBEFOREONCHANGE }, { GE_CMD_PATCHCULLENABLE, FLAG_FLUSHBEFOREONCHANGE }, - // These can't be emulated in D3D (except a few special cases) - { GE_CMD_LOGICOP, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LOGICOPENABLE, FLAG_FLUSHBEFOREONCHANGE }, - // Can probably ignore this one as we don't support AA lines. { GE_CMD_ANTIALIASENABLE, FLAG_FLUSHBEFOREONCHANGE }, diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 694f9c1a8f..5633e7fadd 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -61,7 +61,7 @@ static const VulkanCommandTableEntry commandTable[] = { // Changes that dirty the current texture. { GE_CMD_TEXSIZE0, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTE, 0, &GPU_Vulkan::Execute_TexSize0 }, - { GE_CMD_STENCILTEST, FLAG_FLUSHBEFOREONCHANGE, DIRTY_STENCILREPLACEVALUE }, + { GE_CMD_STENCILTEST, FLAG_FLUSHBEFOREONCHANGE, DIRTY_STENCILREPLACEVALUE | DIRTY_BLEND_STATE }, // Changing the vertex type requires us to flush. { GE_CMD_VERTEXTYPE, FLAG_FLUSHBEFOREONCHANGE | FLAG_EXECUTEONCHANGE, 0, &GPU_Vulkan::Execute_VertexType }, diff --git a/GPU/Vulkan/StateMappingVulkan.cpp b/GPU/Vulkan/StateMappingVulkan.cpp index 74ab0cf03e..8f7cce222d 100644 --- a/GPU/Vulkan/StateMappingVulkan.cpp +++ b/GPU/Vulkan/StateMappingVulkan.cpp @@ -131,7 +131,8 @@ void ResetShaderBlending() { void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManager, ShaderManagerVulkan *shaderManager, int prim, VulkanPipelineRasterStateKey &key, VulkanDynamicState &dynState) { bool useBufferedRendering = g_Config.iRenderingMode != FB_NON_BUFFERED_MODE; - { + if (gstate_c.IsDirty(DIRTY_BLEND_STATE)) { + gstate_c.Clean(DIRTY_BLEND_STATE); // Unfortunately, this isn't implemented yet. gstate_c.SetAllowShaderBlend(false); if (gstate.isModeClear()) {