From 983978ee66cc15c010b2af6703aab866f3a41dcf Mon Sep 17 00:00:00 2001 From: Tillmann Karras Date: Sun, 1 Nov 2015 22:39:31 +0100 Subject: [PATCH] VideoCommon: flush vertex manager if components change --- .../VideoBackends/D3D/PixelShaderCache.cpp | 8 ++++---- .../Core/VideoBackends/D3D/PixelShaderCache.h | 2 +- .../Core/VideoBackends/D3D/VertexManager.cpp | 6 ++---- .../VideoBackends/D3D/VertexShaderCache.cpp | 8 ++++---- .../Core/VideoBackends/D3D/VertexShaderCache.h | 2 +- .../VideoBackends/OGL/ProgramShaderCache.cpp | 18 +++++++++--------- .../VideoBackends/OGL/ProgramShaderCache.h | 4 ++-- .../Core/VideoBackends/OGL/VertexManager.cpp | 6 +++--- Source/Core/VideoCommon/NativeVertexFormat.h | 3 --- Source/Core/VideoCommon/PixelShaderGen.cpp | 17 +++++++++-------- Source/Core/VideoCommon/PixelShaderGen.h | 6 +++--- .../Core/VideoCommon/VertexLoaderManager.cpp | 8 ++++++-- Source/Core/VideoCommon/VertexLoaderManager.h | 3 +++ Source/Core/VideoCommon/VertexShaderGen.cpp | 12 +++++++----- Source/Core/VideoCommon/VertexShaderGen.h | 4 ++-- 15 files changed, 56 insertions(+), 51 deletions(-) diff --git a/Source/Core/VideoBackends/D3D/PixelShaderCache.cpp b/Source/Core/VideoBackends/D3D/PixelShaderCache.cpp index a3dff04361..c361a25835 100644 --- a/Source/Core/VideoBackends/D3D/PixelShaderCache.cpp +++ b/Source/Core/VideoBackends/D3D/PixelShaderCache.cpp @@ -525,14 +525,14 @@ void PixelShaderCache::Shutdown() g_ps_disk_cache.Close(); } -bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) +bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode) { PixelShaderUid uid; - GetPixelShaderUid(uid, dstAlphaMode, API_D3D, components); + GetPixelShaderUid(uid, dstAlphaMode, API_D3D); if (g_ActiveConfig.bEnableShaderDebugging) { ShaderCode code; - GeneratePixelShaderCode(code, dstAlphaMode, API_D3D, components); + GeneratePixelShaderCode(code, dstAlphaMode, API_D3D); pixel_uid_checker.AddToIndexAndCheck(code, uid, "Pixel", "p"); } @@ -562,7 +562,7 @@ bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) // Need to compile a new shader ShaderCode code; - GeneratePixelShaderCode(code, dstAlphaMode, API_D3D, components); + GeneratePixelShaderCode(code, dstAlphaMode, API_D3D); D3DBlob* pbytecode; if (!D3D::CompilePixelShader(code.GetBuffer(), &pbytecode)) diff --git a/Source/Core/VideoBackends/D3D/PixelShaderCache.h b/Source/Core/VideoBackends/D3D/PixelShaderCache.h index 4639078b40..f63956a92f 100644 --- a/Source/Core/VideoBackends/D3D/PixelShaderCache.h +++ b/Source/Core/VideoBackends/D3D/PixelShaderCache.h @@ -20,7 +20,7 @@ public: static void Init(); static void Clear(); static void Shutdown(); - static bool SetShader(DSTALPHA_MODE dstAlphaMode, u32 components); // TODO: Should be renamed to LoadShader + static bool SetShader(DSTALPHA_MODE dstAlphaMode); // TODO: Should be renamed to LoadShader static bool InsertByteCode(const PixelShaderUid &uid, const void* bytecode, unsigned int bytecodelen); static ID3D11PixelShader* GetActiveShader() { return last_entry->shader; } diff --git a/Source/Core/VideoBackends/D3D/VertexManager.cpp b/Source/Core/VideoBackends/D3D/VertexManager.cpp index 1c1d81f157..1312933726 100644 --- a/Source/Core/VideoBackends/D3D/VertexManager.cpp +++ b/Source/Core/VideoBackends/D3D/VertexManager.cpp @@ -151,16 +151,14 @@ void VertexManager::Draw(u32 stride) void VertexManager::vFlush(bool useDstAlpha) { - u32 components = VertexLoaderManager::GetCurrentVertexFormat()->m_components; - if (!PixelShaderCache::SetShader( - useDstAlpha ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE, components)) + useDstAlpha ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE)) { GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); return; } - if (!VertexShaderCache::SetShader(components)) + if (!VertexShaderCache::SetShader()) { GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");}); return; diff --git a/Source/Core/VideoBackends/D3D/VertexShaderCache.cpp b/Source/Core/VideoBackends/D3D/VertexShaderCache.cpp index d6b5ec6ade..38445422b1 100644 --- a/Source/Core/VideoBackends/D3D/VertexShaderCache.cpp +++ b/Source/Core/VideoBackends/D3D/VertexShaderCache.cpp @@ -184,14 +184,14 @@ void VertexShaderCache::Shutdown() g_vs_disk_cache.Close(); } -bool VertexShaderCache::SetShader(u32 components) +bool VertexShaderCache::SetShader() { VertexShaderUid uid; - GetVertexShaderUid(uid, components, API_D3D); + GetVertexShaderUid(uid, API_D3D); if (g_ActiveConfig.bEnableShaderDebugging) { ShaderCode code; - GenerateVertexShaderCode(code, components, API_D3D); + GenerateVertexShaderCode(code, API_D3D); vertex_uid_checker.AddToIndexAndCheck(code, uid, "Vertex", "v"); } @@ -217,7 +217,7 @@ bool VertexShaderCache::SetShader(u32 components) } ShaderCode code; - GenerateVertexShaderCode(code, components, API_D3D); + GenerateVertexShaderCode(code, API_D3D); D3DBlob* pbytecode = nullptr; D3D::CompileVertexShader(code.GetBuffer(), &pbytecode); diff --git a/Source/Core/VideoBackends/D3D/VertexShaderCache.h b/Source/Core/VideoBackends/D3D/VertexShaderCache.h index dc977f0ebb..2d7afa2d20 100644 --- a/Source/Core/VideoBackends/D3D/VertexShaderCache.h +++ b/Source/Core/VideoBackends/D3D/VertexShaderCache.h @@ -19,7 +19,7 @@ public: static void Init(); static void Clear(); static void Shutdown(); - static bool SetShader(u32 components); // TODO: Should be renamed to LoadShader + static bool SetShader(); // TODO: Should be renamed to LoadShader static ID3D11VertexShader* GetActiveShader() { return last_entry->shader; } static D3DBlob* GetActiveShaderBytecode() { return last_entry->bytecode; } diff --git a/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp b/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp index aa91a92478..52baa54523 100644 --- a/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp +++ b/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp @@ -176,10 +176,10 @@ void ProgramShaderCache::UploadConstants() } } -SHADER* ProgramShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components, u32 primitive_type) +SHADER* ProgramShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 primitive_type) { SHADERUID uid; - GetShaderId(&uid, dstAlphaMode, components, primitive_type); + GetShaderId(&uid, dstAlphaMode, primitive_type); // Check if the shader is already set if (last_entry) @@ -214,8 +214,8 @@ SHADER* ProgramShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components ShaderCode vcode; ShaderCode pcode; ShaderCode gcode; - GenerateVertexShaderCode(vcode, components, API_OPENGL); - GeneratePixelShaderCode(pcode, dstAlphaMode, API_OPENGL, components); + GenerateVertexShaderCode(vcode, API_OPENGL); + GeneratePixelShaderCode(pcode, dstAlphaMode, API_OPENGL); if (g_ActiveConfig.backend_info.bSupportsGeometryShaders && !uid.guid.GetUidData()->IsPassthrough()) GenerateGeometryShaderCode(gcode, primitive_type, API_OPENGL); @@ -396,20 +396,20 @@ GLuint ProgramShaderCache::CompileSingleShader(GLuint type, const char* code) return result; } -void ProgramShaderCache::GetShaderId(SHADERUID* uid, DSTALPHA_MODE dstAlphaMode, u32 components, u32 primitive_type) +void ProgramShaderCache::GetShaderId(SHADERUID* uid, DSTALPHA_MODE dstAlphaMode, u32 primitive_type) { - GetPixelShaderUid(uid->puid, dstAlphaMode, API_OPENGL, components); - GetVertexShaderUid(uid->vuid, components, API_OPENGL); + GetPixelShaderUid(uid->puid, dstAlphaMode, API_OPENGL); + GetVertexShaderUid(uid->vuid, API_OPENGL); GetGeometryShaderUid(uid->guid, primitive_type, API_OPENGL); if (g_ActiveConfig.bEnableShaderDebugging) { ShaderCode pcode; - GeneratePixelShaderCode(pcode, dstAlphaMode, API_OPENGL, components); + GeneratePixelShaderCode(pcode, dstAlphaMode, API_OPENGL); pixel_uid_checker.AddToIndexAndCheck(pcode, uid->puid, "Pixel", "p"); ShaderCode vcode; - GenerateVertexShaderCode(vcode, components, API_OPENGL); + GenerateVertexShaderCode(vcode, API_OPENGL); vertex_uid_checker.AddToIndexAndCheck(vcode, uid->vuid, "Vertex", "v"); ShaderCode gcode; diff --git a/Source/Core/VideoBackends/OGL/ProgramShaderCache.h b/Source/Core/VideoBackends/OGL/ProgramShaderCache.h index ef1c926f73..32e84c07af 100644 --- a/Source/Core/VideoBackends/OGL/ProgramShaderCache.h +++ b/Source/Core/VideoBackends/OGL/ProgramShaderCache.h @@ -88,8 +88,8 @@ public: static PCacheEntry GetShaderProgram(); - static SHADER* SetShader(DSTALPHA_MODE dstAlphaMode, u32 components, u32 primitive_type); - static void GetShaderId(SHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 components, u32 primitive_type); + static SHADER* SetShader(DSTALPHA_MODE dstAlphaMode, u32 primitive_type); + static void GetShaderId(SHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 primitive_type); static bool CompileShader(SHADER &shader, const char* vcode, const char* pcode, const char* gcode = nullptr); static GLuint CompileSingleShader(GLuint type, const char *code); diff --git a/Source/Core/VideoBackends/OGL/VertexManager.cpp b/Source/Core/VideoBackends/OGL/VertexManager.cpp index e2ea5e8fe3..82f9763808 100644 --- a/Source/Core/VideoBackends/OGL/VertexManager.cpp +++ b/Source/Core/VideoBackends/OGL/VertexManager.cpp @@ -160,11 +160,11 @@ void VertexManager::vFlush(bool useDstAlpha) // the same pass as regular rendering. if (useDstAlpha && dualSourcePossible) { - ProgramShaderCache::SetShader(DSTALPHA_DUAL_SOURCE_BLEND, nativeVertexFmt->m_components, current_primitive_type); + ProgramShaderCache::SetShader(DSTALPHA_DUAL_SOURCE_BLEND, current_primitive_type); } else { - ProgramShaderCache::SetShader(DSTALPHA_NONE, nativeVertexFmt->m_components, current_primitive_type); + ProgramShaderCache::SetShader(DSTALPHA_NONE, current_primitive_type); } // upload global constants @@ -178,7 +178,7 @@ void VertexManager::vFlush(bool useDstAlpha) // run through vertex groups again to set alpha if (useDstAlpha && !dualSourcePossible) { - ProgramShaderCache::SetShader(DSTALPHA_ALPHA_PASS, nativeVertexFmt->m_components, current_primitive_type); + ProgramShaderCache::SetShader(DSTALPHA_ALPHA_PASS, current_primitive_type); // only update alpha glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); diff --git a/Source/Core/VideoCommon/NativeVertexFormat.h b/Source/Core/VideoCommon/NativeVertexFormat.h index df86b90946..0f48341deb 100644 --- a/Source/Core/VideoCommon/NativeVertexFormat.h +++ b/Source/Core/VideoCommon/NativeVertexFormat.h @@ -114,9 +114,6 @@ public: u32 GetVertexStride() const { return vtx_decl.stride; } const PortableVertexDeclaration& GetVertexDeclaration() const { return vtx_decl; } - // TODO: move this under private: - u32 m_components; // VB_HAS_X. Bitmask telling what vertex components are present. - protected: // Let subclasses construct. NativeVertexFormat() {} diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index 5d6ab5ea42..a7283bfd39 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -14,6 +14,7 @@ #include "VideoCommon/LightingShaderGen.h" #include "VideoCommon/NativeVertexFormat.h" #include "VideoCommon/PixelShaderGen.h" +#include "VideoCommon/VertexLoaderManager.h" #include "VideoCommon/VertexShaderGen.h" #include "VideoCommon/VideoConfig.h" #include "VideoCommon/XFMemory.h" // for texture projection mode @@ -165,8 +166,9 @@ template static inline void WriteAlphaTest(T& out, pixel_shader_uid_dat template static inline void WriteFog(T& out, pixel_shader_uid_data* uid_data); template -static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) +static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType) { + const u32 components = VertexLoaderManager::g_current_components; // Non-uid template parameters will write to the dummy data (=> gets optimized out) pixel_shader_uid_data dummy_data; pixel_shader_uid_data* uid_data = out.template GetUidData(); @@ -1168,18 +1170,17 @@ static inline void WriteFog(T& out, pixel_shader_uid_data* uid_data) out.Write("\tprev.rgb = (prev.rgb * (256 - ifog) + " I_FOGCOLOR".rgb * ifog) >> 8;\n"); } -void GetPixelShaderUid(PixelShaderUid& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) +void GetPixelShaderUid(PixelShaderUid& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType) { - GeneratePixelShader(object, dstAlphaMode, ApiType, components); + GeneratePixelShader(object, dstAlphaMode, ApiType); } -void GeneratePixelShaderCode(ShaderCode& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) +void GeneratePixelShaderCode(ShaderCode& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType) { - GeneratePixelShader(object, dstAlphaMode, ApiType, components); + GeneratePixelShader(object, dstAlphaMode, ApiType); } -void GetPixelShaderConstantProfile(PixelShaderConstantProfile& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) +void GetPixelShaderConstantProfile(PixelShaderConstantProfile& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType) { - GeneratePixelShader(object, dstAlphaMode, ApiType, components); + GeneratePixelShader(object, dstAlphaMode, ApiType); } - diff --git a/Source/Core/VideoCommon/PixelShaderGen.h b/Source/Core/VideoCommon/PixelShaderGen.h index 83516aeb75..638ff9b2bc 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.h +++ b/Source/Core/VideoCommon/PixelShaderGen.h @@ -116,6 +116,6 @@ struct pixel_shader_uid_data typedef ShaderUid PixelShaderUid; typedef ShaderConstantProfile PixelShaderConstantProfile; // TODO: Obsolete -void GeneratePixelShaderCode(ShaderCode& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components); -void GetPixelShaderUid(PixelShaderUid& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components); -void GetPixelShaderConstantProfile(PixelShaderConstantProfile& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components); +void GeneratePixelShaderCode(ShaderCode& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType); +void GetPixelShaderUid(PixelShaderUid& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType); +void GetPixelShaderConstantProfile(PixelShaderConstantProfile& object, DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType); diff --git a/Source/Core/VideoCommon/VertexLoaderManager.cpp b/Source/Core/VideoCommon/VertexLoaderManager.cpp index 4a61c6bc6e..bc4f136500 100644 --- a/Source/Core/VideoCommon/VertexLoaderManager.cpp +++ b/Source/Core/VideoCommon/VertexLoaderManager.cpp @@ -32,6 +32,7 @@ u32 position_matrix_index[3]; typedef std::unordered_map> NativeVertexFormatMap; static NativeVertexFormatMap s_native_vertex_map; static NativeVertexFormat* s_current_vtx_fmt; +u32 g_current_components; typedef std::unordered_map> VertexLoaderMap; static std::mutex s_vertex_loader_map_lock; @@ -153,7 +154,6 @@ static VertexLoaderBase* RefreshLoader(int vtx_attr_group, bool preprocess = fal { native.reset(g_vertex_manager->CreateNativeVertexFormat()); native->Initialize(format); - native->m_components = loader->m_native_components; } loader->m_native_vertex_format = native.get(); } @@ -185,9 +185,13 @@ int RunVertices(int vtx_attr_group, int primitive, int count, DataReader src, bo return size; // If the native vertex format changed, force a flush. - if (loader->m_native_vertex_format != s_current_vtx_fmt) + if (loader->m_native_vertex_format != s_current_vtx_fmt || + loader->m_native_components != g_current_components) + { VertexManager::Flush(); + } s_current_vtx_fmt = loader->m_native_vertex_format; + g_current_components = loader->m_native_components; // if cull mode is CULL_ALL, tell VertexManager to skip triangles and quads. // They still need to go through vertex loading, because we need to calculate a zfreeze refrence slope. diff --git a/Source/Core/VideoCommon/VertexLoaderManager.h b/Source/Core/VideoCommon/VertexLoaderManager.h index 92d7e6da8f..4a1c64fd1e 100644 --- a/Source/Core/VideoCommon/VertexLoaderManager.h +++ b/Source/Core/VideoCommon/VertexLoaderManager.h @@ -33,5 +33,8 @@ namespace VertexLoaderManager // These arrays are in reverse order. extern float position_cache[3][4]; extern u32 position_matrix_index[3]; + + // VB_HAS_X. Bitmask telling what vertex components are present. + extern u32 g_current_components; } diff --git a/Source/Core/VideoCommon/VertexShaderGen.cpp b/Source/Core/VideoCommon/VertexShaderGen.cpp index 7a23cf1080..f00a6d760c 100644 --- a/Source/Core/VideoCommon/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/VertexShaderGen.cpp @@ -9,14 +9,16 @@ #include "VideoCommon/DriverDetails.h" #include "VideoCommon/LightingShaderGen.h" #include "VideoCommon/NativeVertexFormat.h" +#include "VideoCommon/VertexLoaderManager.h" #include "VideoCommon/VertexShaderGen.h" #include "VideoCommon/VideoConfig.h" static char text[16768]; template -static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_type) +static inline void GenerateVertexShader(T& out, API_TYPE api_type) { + const u32 components = VertexLoaderManager::g_current_components; // Non-uid template parameters will write to the dummy data (=> gets optimized out) vertex_shader_uid_data dummy_data; vertex_shader_uid_data* uid_data = out.template GetUidData(); @@ -394,12 +396,12 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ } } -void GetVertexShaderUid(VertexShaderUid& object, u32 components, API_TYPE api_type) +void GetVertexShaderUid(VertexShaderUid& object, API_TYPE api_type) { - GenerateVertexShader(object, components, api_type); + GenerateVertexShader(object, api_type); } -void GenerateVertexShaderCode(ShaderCode& object, u32 components, API_TYPE api_type) +void GenerateVertexShaderCode(ShaderCode& object, API_TYPE api_type) { - GenerateVertexShader(object, components, api_type); + GenerateVertexShader(object, api_type); } diff --git a/Source/Core/VideoCommon/VertexShaderGen.h b/Source/Core/VideoCommon/VertexShaderGen.h index 540ad94a71..45cc9bbac3 100644 --- a/Source/Core/VideoCommon/VertexShaderGen.h +++ b/Source/Core/VideoCommon/VertexShaderGen.h @@ -60,5 +60,5 @@ struct vertex_shader_uid_data typedef ShaderUid VertexShaderUid; -void GetVertexShaderUid(VertexShaderUid& object, u32 components, API_TYPE api_type); -void GenerateVertexShaderCode(ShaderCode& object, u32 components, API_TYPE api_type); +void GetVertexShaderUid(VertexShaderUid& object, API_TYPE api_type); +void GenerateVertexShaderCode(ShaderCode& object, API_TYPE api_type);