diff --git a/GPU/Common/GPUStateUtils.cpp b/GPU/Common/GPUStateUtils.cpp index 5244e4f83a..2c17f94d24 100644 --- a/GPU/Common/GPUStateUtils.cpp +++ b/GPU/Common/GPUStateUtils.cpp @@ -33,7 +33,6 @@ #include "GPU/Common/GPUStateUtils.h" - bool CanUseHardwareTransform(int prim) { if (!g_Config.bHardwareTransform) return false; diff --git a/GPU/D3D11/DrawEngineD3D11.cpp b/GPU/D3D11/DrawEngineD3D11.cpp index 3042e6090d..5ea686ae9c 100644 --- a/GPU/D3D11/DrawEngineD3D11.cpp +++ b/GPU/D3D11/DrawEngineD3D11.cpp @@ -119,7 +119,8 @@ void DrawEngineD3D11::ClearTrackedVertexArrays() { void DrawEngineD3D11::ClearInputLayoutMap() { for (auto &decl : inputLayoutMap_) { - decl.second->Release(); + if (decl.second) + decl.second->Release(); } inputLayoutMap_.clear(); } diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index 78c3c59a83..25ae3906f8 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -467,6 +467,8 @@ void FramebufferManagerD3D11::BindPostShader(const PostShaderUniforms &uniforms) context_->Unmap(postConstants_, 0); context_->VSSetConstantBuffers(0, 1, &postConstants_); // Probably not necessary context_->PSSetConstantBuffers(0, 1, &postConstants_); + + gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); } void FramebufferManagerD3D11::RebindFramebuffer() { @@ -510,7 +512,7 @@ void FramebufferManagerD3D11::ReformatFramebufferFrom(VirtualFramebuffer *vfb, G } RebindFramebuffer(); - gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE); + gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_VERTEXSHADER_STATE); } static void CopyPixelDepthOnly(u32 *dstp, const u32 *srcp, size_t c) { @@ -713,7 +715,7 @@ void FramebufferManagerD3D11::SimpleBlit( context_->IASetVertexBuffers(0, 1, &quadBuffer_, &stride, &offset); context_->Draw(4, 0); - gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE); + gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_VERTEXSHADER_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 c38cf2ffdd..e0c344dba8 100644 --- a/GPU/D3D11/GPU_D3D11.cpp +++ b/GPU/D3D11/GPU_D3D11.cpp @@ -445,12 +445,18 @@ void GPU_D3D11::ExecuteOp(u32 op, u32 diff) { } void GPU_D3D11::Execute_VertexType(u32 op, u32 diff) { + if (diff) + gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); if (diff & (GE_VTYPE_TC_MASK | GE_VTYPE_THROUGH_MASK)) { gstate_c.Dirty(DIRTY_UVSCALEOFFSET); + if (diff & GE_VTYPE_THROUGH_MASK) + gstate_c.Dirty(DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE); } } void GPU_D3D11::Execute_VertexTypeSkinning(u32 op, u32 diff) { + if (diff) + gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); // Don't flush when weight count changes, unless morph is enabled. if ((diff & ~GE_VTYPE_WEIGHTCOUNT_MASK) || (op & GE_VTYPE_MORPHCOUNT_MASK) != 0) { // Restore and flush @@ -466,6 +472,8 @@ void GPU_D3D11::Execute_VertexTypeSkinning(u32 op, u32 diff) { gstate_c.deferredVertTypeDirty = 0; } } + if (diff & GE_VTYPE_THROUGH_MASK) + gstate_c.Dirty(DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE); } void GPU_D3D11::Execute_Prim(u32 op, u32 diff) { @@ -474,12 +482,11 @@ void GPU_D3D11::Execute_Prim(u32 op, u32 diff) { u32 data = op & 0xFFFFFF; u32 count = data & 0xFFFF; - // Upper bits are ignored. - GEPrimitiveType prim = static_cast((data >> 16) & 7); - if (count == 0) return; + // Upper bits are ignored. + GEPrimitiveType prim = static_cast((data >> 16) & 7); SetDrawType(DRAW_PRIM, prim); // Discard AA lines as we can't do anything that makes sense with these anyway. The SW plugin might, though. diff --git a/GPU/D3D11/ShaderManagerD3D11.cpp b/GPU/D3D11/ShaderManagerD3D11.cpp index bc7ed26d6c..5bf62a1dae 100644 --- a/GPU/D3D11/ShaderManagerD3D11.cpp +++ b/GPU/D3D11/ShaderManagerD3D11.cpp @@ -139,6 +139,7 @@ void ShaderManagerD3D11::DirtyLastShader() { lastVSID_.clear(); lastVShader_ = nullptr; lastFShader_ = nullptr; + gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); } uint64_t ShaderManagerD3D11::UpdateUniforms() { @@ -178,7 +179,13 @@ void ShaderManagerD3D11::BindUniforms() { void ShaderManagerD3D11::GetShaders(int prim, u32 vertType, D3D11VertexShader **vshader, D3D11FragmentShader **fshader, bool useHWTransform) { ShaderID VSID; ShaderID FSID; - ComputeVertexShaderID(&VSID, vertType, useHWTransform); + + if (gstate_c.IsDirty(DIRTY_VERTEXSHADER_STATE)) { + gstate_c.Clean(DIRTY_VERTEXSHADER_STATE); + ComputeVertexShaderID(&VSID, vertType, useHWTransform); + } else { + VSID = lastVSID_; + } ComputeFragmentShaderID(&FSID); // Just update uniforms if this is the same shader as last time. diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index 367f317684..a1bd219f3a 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -412,12 +412,18 @@ void GPU_DX9::ExecuteOp(u32 op, u32 diff) { } void GPU_DX9::Execute_VertexType(u32 op, u32 diff) { + if (diff) + gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); if (diff & (GE_VTYPE_TC_MASK | GE_VTYPE_THROUGH_MASK)) { gstate_c.Dirty(DIRTY_UVSCALEOFFSET); + if (diff & GE_VTYPE_THROUGH_MASK) + gstate_c.Dirty(DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE); } } void GPU_DX9::Execute_VertexTypeSkinning(u32 op, u32 diff) { + if (diff) + gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); // Don't flush when weight count changes, unless morph is enabled. if ((diff & ~GE_VTYPE_WEIGHTCOUNT_MASK) || (op & GE_VTYPE_MORPHCOUNT_MASK) != 0) { // Restore and flush @@ -433,6 +439,8 @@ void GPU_DX9::Execute_VertexTypeSkinning(u32 op, u32 diff) { gstate_c.deferredVertTypeDirty = 0; } } + if (diff & GE_VTYPE_THROUGH_MASK) + gstate_c.Dirty(DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE); } void GPU_DX9::Execute_Prim(u32 op, u32 diff) { @@ -441,12 +449,10 @@ void GPU_DX9::Execute_Prim(u32 op, u32 diff) { u32 data = op & 0xFFFFFF; u32 count = data & 0xFFFF; - // Upper bits are ignored. - GEPrimitiveType prim = static_cast((data >> 16) & 7); - if (count == 0) return; - + // Upper bits are ignored. + GEPrimitiveType prim = static_cast((data >> 16) & 7); SetDrawType(DRAW_PRIM, prim); // Discard AA lines as we can't do anything that makes sense with these anyway. The SW plugin might, though. diff --git a/GPU/Directx9/ShaderManagerDX9.cpp b/GPU/Directx9/ShaderManagerDX9.cpp index 8836067ef2..28ea89f7b2 100644 --- a/GPU/Directx9/ShaderManagerDX9.cpp +++ b/GPU/Directx9/ShaderManagerDX9.cpp @@ -555,7 +555,13 @@ VSShader *ShaderManagerDX9::ApplyShader(int prim, u32 vertType) { bool useHWTransform = CanUseHardwareTransform(prim); ShaderID VSID; - ComputeVertexShaderID(&VSID, vertType, useHWTransform); + if (gstate_c.IsDirty(DIRTY_VERTEXSHADER_STATE)) { + gstate_c.Clean(DIRTY_VERTEXSHADER_STATE); + ComputeVertexShaderID(&VSID, vertType, useHWTransform); + } else { + VSID = lastVSID_; + } + ShaderID FSID; ComputeFragmentShaderID(&FSID); diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index 6122c16c3d..ab784b0a14 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -627,12 +627,11 @@ void GPU_GLES::Execute_Prim(u32 op, u32 diff) { u32 data = op & 0xFFFFFF; u32 count = data & 0xFFFF; - // Upper bits are ignored. - GEPrimitiveType prim = static_cast((data >> 16) & 7); - if (count == 0) return; + // Upper bits are ignored. + GEPrimitiveType prim = static_cast((data >> 16) & 7); SetDrawType(DRAW_PRIM, prim); // Discard AA lines as we can't do anything that makes sense with these anyway. The SW plugin might, though. @@ -690,6 +689,8 @@ void GPU_GLES::Execute_Prim(u32 op, u32 diff) { } void GPU_GLES::Execute_VertexType(u32 op, u32 diff) { + if (diff) + gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); if (diff & (GE_VTYPE_TC_MASK | GE_VTYPE_THROUGH_MASK)) { gstate_c.Dirty(DIRTY_UVSCALEOFFSET); if (diff & GE_VTYPE_THROUGH_MASK) @@ -698,6 +699,8 @@ void GPU_GLES::Execute_VertexType(u32 op, u32 diff) { } void GPU_GLES::Execute_VertexTypeSkinning(u32 op, u32 diff) { + if (diff) + gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); // Don't flush when weight count changes, unless morph is enabled. if ((diff & ~GE_VTYPE_WEIGHTCOUNT_MASK) || (op & GE_VTYPE_MORPHCOUNT_MASK) != 0) { // Restore and flush diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index 48847ed8f5..bf5ffcf928 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -747,7 +747,7 @@ void LinkedShader::UpdateUniforms(u32 vertType, const ShaderID &vsid) { } ShaderManagerGLES::ShaderManagerGLES() - : lastShader_(nullptr), shaderSwitchDirty_(0), diskCacheDirty_(false) { + : lastShader_(nullptr), shaderSwitchDirtyUniforms_(0), diskCacheDirty_(false) { codeBuffer_ = new char[16384]; lastFSID_.set_invalid(); lastVSID_.set_invalid(); @@ -788,7 +788,7 @@ void ShaderManagerGLES::DirtyShader() { lastVSID_.set_invalid(); DirtyLastShader(); gstate_c.Dirty(DIRTY_ALL_UNIFORMS); - shaderSwitchDirty_ = 0; + shaderSwitchDirtyUniforms_ = 0; } void ShaderManagerGLES::DirtyLastShader() { // disables vertex arrays @@ -816,22 +816,25 @@ Shader *ShaderManagerGLES::ApplyVertexShader(int prim, u32 vertType, ShaderID *V if (dirty) { if (lastShader_) lastShader_->dirtyUniforms |= dirty; - shaderSwitchDirty_ |= dirty; + shaderSwitchDirtyUniforms_ |= dirty; gstate_c.CleanUniforms(); } bool useHWTransform = CanUseHardwareTransform(prim); - ComputeVertexShaderID(VSID, vertType, useHWTransform); + if (gstate_c.IsDirty(DIRTY_VERTEXSHADER_STATE)) { + gstate_c.Clean(DIRTY_VERTEXSHADER_STATE); + ComputeVertexShaderID(VSID, vertType, useHWTransform); + } else { + *VSID = lastVSID_; + } - // Just update uniforms if this is the same shader as last time. if (lastShader_ != 0 && *VSID == lastVSID_) { lastVShaderSame_ = true; return lastShader_->vs_; // Already all set. } else { lastVShaderSame_ = false; } - lastVSID_ = *VSID; VSCache::iterator vsIter = vsCache_.find(*VSID); @@ -890,7 +893,7 @@ LinkedShader *ShaderManagerGLES::ApplyFragmentShader(ShaderID VSID, Shader *vs, // Okay, we have both shaders. Let's see if there's a linked one. LinkedShader *ls = nullptr; - u64 switchDirty = shaderSwitchDirty_; + u64 switchDirty = shaderSwitchDirtyUniforms_; for (auto iter = linkedShaderCache_.begin(); iter != linkedShaderCache_.end(); ++iter) { // Deferred dirtying! Let's see if we can make this even more clever later. iter->ls->dirtyUniforms |= switchDirty; @@ -899,7 +902,7 @@ LinkedShader *ShaderManagerGLES::ApplyFragmentShader(ShaderID VSID, Shader *vs, ls = iter->ls; } } - shaderSwitchDirty_ = 0; + shaderSwitchDirtyUniforms_ = 0; if (ls == nullptr) { diff --git a/GPU/GLES/ShaderManagerGLES.h b/GPU/GLES/ShaderManagerGLES.h index eb0755c491..2b16b75e63 100644 --- a/GPU/GLES/ShaderManagerGLES.h +++ b/GPU/GLES/ShaderManagerGLES.h @@ -188,7 +188,7 @@ private: ShaderID lastVSID_; LinkedShader *lastShader_; - u64 shaderSwitchDirty_; + u64 shaderSwitchDirtyUniforms_; char *codeBuffer_; typedef std::map FSCache; diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index b11afcfd5a..a4e64810e4 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -56,12 +56,12 @@ const CommonCommandTableEntry commonCommandTable[] = { { GE_CMD_FOG2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_FOGCOEF }, // These affect the fragment shader so need flushing. - { GE_CMD_CLEARMODE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_BLEND_STATE | DIRTY_VIEWPORTSCISSOR_STATE }, - { GE_CMD_TEXTUREMAPENABLE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_FOGENABLE, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_CLEARMODE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_VERTEXSHADER_STATE }, + { GE_CMD_TEXTUREMAPENABLE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE }, + { GE_CMD_FOGENABLE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE }, { GE_CMD_TEXMODE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, - { GE_CMD_TEXSHADELS, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_SHADEMODE, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_TEXSHADELS, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE }, + { GE_CMD_SHADEMODE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE }, { GE_CMD_TEXFUNC, FLAG_FLUSHBEFOREONCHANGE }, { GE_CMD_COLORTEST, FLAG_FLUSHBEFOREONCHANGE }, { GE_CMD_ALPHATESTENABLE, FLAG_FLUSHBEFOREONCHANGE }, @@ -69,20 +69,20 @@ const CommonCommandTableEntry commonCommandTable[] = { { GE_CMD_COLORTESTMASK, FLAG_FLUSHBEFOREONCHANGE, DIRTY_ALPHACOLORMASK }, // These change the vertex shader so need flushing. - { GE_CMD_REVERSENORMAL, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LIGHTINGENABLE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LIGHTENABLE0, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LIGHTENABLE1, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LIGHTENABLE2, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LIGHTENABLE3, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LIGHTTYPE0, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LIGHTTYPE1, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LIGHTTYPE2, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_LIGHTTYPE3, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_MATERIALUPDATE, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_REVERSENORMAL, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE }, + { GE_CMD_LIGHTINGENABLE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE }, + { GE_CMD_LIGHTENABLE0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE }, + { GE_CMD_LIGHTENABLE1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE }, + { GE_CMD_LIGHTENABLE2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE }, + { GE_CMD_LIGHTENABLE3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE }, + { GE_CMD_LIGHTTYPE0, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE }, + { GE_CMD_LIGHTTYPE1, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE }, + { GE_CMD_LIGHTTYPE2, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE }, + { GE_CMD_LIGHTTYPE3, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE }, + { GE_CMD_MATERIALUPDATE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE }, // These change both shaders so need flushing. - { GE_CMD_LIGHTMODE, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_LIGHTMODE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE }, { GE_CMD_TEXFILTER, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, { GE_CMD_TEXWRAP, FLAG_FLUSHBEFOREONCHANGE, DIRTY_TEXTURE_PARAMS }, @@ -109,7 +109,7 @@ const CommonCommandTableEntry commonCommandTable[] = { { GE_CMD_LOGICOP, FLAG_FLUSHBEFOREONCHANGE, DIRTY_BLEND_STATE }, { GE_CMD_LOGICOPENABLE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_BLEND_STATE }, - { GE_CMD_TEXMAPMODE, FLAG_FLUSHBEFOREONCHANGE, 0 }, + { GE_CMD_TEXMAPMODE, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE }, { GE_CMD_TEXSCALEU, FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_TexScaleU }, { GE_CMD_TEXSCALEV, FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_TexScaleV }, { GE_CMD_TEXOFFSETU, FLAG_EXECUTEONCHANGE, 0, &GPUCommon::Execute_TexOffsetU }, @@ -161,7 +161,7 @@ const CommonCommandTableEntry commonCommandTable[] = { // Control spline/bezier patches. Don't really require flushing as such, but meh. { GE_CMD_PATCHDIVISION, FLAG_FLUSHBEFOREONCHANGE }, { GE_CMD_PATCHPRIMITIVE, FLAG_FLUSHBEFOREONCHANGE }, - { GE_CMD_PATCHFACING, FLAG_FLUSHBEFOREONCHANGE }, + { GE_CMD_PATCHFACING, FLAG_FLUSHBEFOREONCHANGE, DIRTY_VERTEXSHADER_STATE }, { GE_CMD_PATCHCULLENABLE, FLAG_FLUSHBEFOREONCHANGE }, // Can probably ignore this one as we don't support AA lines. diff --git a/GPU/GPUCommon.h b/GPU/GPUCommon.h index fb5d5db497..a739672d5f 100644 --- a/GPU/GPUCommon.h +++ b/GPU/GPUCommon.h @@ -229,13 +229,13 @@ public: protected: void SetDrawType(DrawType type, GEPrimitiveType prim) { if (type != lastDraw_) { - gstate_c.Dirty(DIRTY_UVSCALEOFFSET); + gstate_c.Dirty(DIRTY_UVSCALEOFFSET | DIRTY_VERTEXSHADER_STATE); lastDraw_ = type; } // Prim == RECTANGLES can cause CanUseHardwareTransform to flip, so we need to dirty. // Also, culling may be affected. if ((prim == GE_PRIM_RECTANGLES) != (lastPrim_ == GE_PRIM_RECTANGLES)) { - gstate_c.Dirty(DIRTY_RASTER_STATE); + gstate_c.Dirty(DIRTY_RASTER_STATE | DIRTY_VERTEXSHADER_STATE); lastPrim_ = prim; } } @@ -348,6 +348,7 @@ protected: bool interruptsEnabled_; bool resized_; DrawType lastDraw_; + GEPrimitiveType lastPrim_; private: diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 5c5711decb..9e11902afb 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -456,12 +456,11 @@ void GPU_Vulkan::Execute_Prim(u32 op, u32 diff) { u32 data = op & 0xFFFFFF; u32 count = data & 0xFFFF; - // Upper bits are ignored. - GEPrimitiveType prim = static_cast((data >> 16) & 7); - if (count == 0) return; + // Upper bits are ignored. + GEPrimitiveType prim = static_cast((data >> 16) & 7); SetDrawType(DRAW_PRIM, prim); // Discard AA lines as we can't do anything that makes sense with these anyway. The SW plugin might, though. @@ -522,8 +521,12 @@ void GPU_Vulkan::Execute_Prim(u32 op, u32 diff) { } void GPU_Vulkan::Execute_VertexType(u32 op, u32 diff) { + if (diff) + gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); if (diff & (GE_VTYPE_TC_MASK | GE_VTYPE_THROUGH_MASK)) { gstate_c.Dirty(DIRTY_UVSCALEOFFSET); + if (diff & GE_VTYPE_THROUGH_MASK) + gstate_c.Dirty(DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE); } } diff --git a/GPU/Vulkan/ShaderManagerVulkan.cpp b/GPU/Vulkan/ShaderManagerVulkan.cpp index ad83041dd3..c7823874db 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.cpp +++ b/GPU/Vulkan/ShaderManagerVulkan.cpp @@ -234,8 +234,14 @@ uint64_t ShaderManagerVulkan::UpdateUniforms() { void ShaderManagerVulkan::GetShaders(int prim, u32 vertType, VulkanVertexShader **vshader, VulkanFragmentShader **fshader, bool useHWTransform) { ShaderID VSID; + if (gstate_c.IsDirty(DIRTY_VERTEXSHADER_STATE)) { + gstate_c.Clean(DIRTY_VERTEXSHADER_STATE); + ComputeVertexShaderID(&VSID, vertType, useHWTransform); + } else { + VSID = lastVSID_; + } + ShaderID FSID; - ComputeVertexShaderID(&VSID, vertType, useHWTransform); ComputeFragmentShaderID(&FSID); // Just update uniforms if this is the same shader as last time.