diff --git a/Common/GPU/D3D9/D3D9StateCache.cpp b/Common/GPU/D3D9/D3D9StateCache.cpp index ed0bbdeff4..a799713c95 100644 --- a/Common/GPU/D3D9/D3D9StateCache.cpp +++ b/Common/GPU/D3D9/D3D9StateCache.cpp @@ -5,7 +5,6 @@ namespace DX9 { DirectXState dxstate; -GLExtensions gl_extensions; LPDIRECT3DDEVICE9 pD3Ddevice = nullptr; LPDIRECT3DDEVICE9EX pD3DdeviceEx = nullptr; @@ -64,14 +63,6 @@ void DirectXState::Restore() { texAddressV.restore(); count++; } -void CheckGLExtensions() { - static bool done = false; - if (done) - return; - done = true; - memset(&gl_extensions, 0, sizeof(gl_extensions)); -} - } // namespace DX9 #endif // _MSC_VER diff --git a/Common/GPU/OpenGL/GLFeatures.cpp b/Common/GPU/OpenGL/GLFeatures.cpp index 9cff5bbad1..bb355d3013 100644 --- a/Common/GPU/OpenGL/GLFeatures.cpp +++ b/Common/GPU/OpenGL/GLFeatures.cpp @@ -77,19 +77,28 @@ bool GLExtensions::VersionGEThan(int major, int minor, int sub) { } int GLExtensions::GLSLVersion() { - // Used for shader translation and core contexts (Apple drives fail without an exact match.) - if (gl_extensions.VersionGEThan(3, 3)) { - return gl_extensions.ver[0] * 100 + gl_extensions.ver[1] * 10; - } else if (gl_extensions.VersionGEThan(3, 2)) { - return 150; - } else if (gl_extensions.VersionGEThan(3, 1)) { - return 140; - } else if (gl_extensions.VersionGEThan(3, 0)) { - return 130; - } else if (gl_extensions.VersionGEThan(2, 1)) { - return 120; + if (gl_extensions.IsGLES) { + if (gl_extensions.GLES3) { + // GLSL version matches ES version. + return gl_extensions.ver[0] * 100 + gl_extensions.ver[1] * 10; + } else { + return 100; + } } else { - return 110; + // Used for shader translation and core contexts (Apple drives fail without an exact match.) + if (gl_extensions.VersionGEThan(3, 3)) { + return gl_extensions.ver[0] * 100 + gl_extensions.ver[1] * 10; + } else if (gl_extensions.VersionGEThan(3, 2)) { + return 150; + } else if (gl_extensions.VersionGEThan(3, 1)) { + return 140; + } else if (gl_extensions.VersionGEThan(3, 0)) { + return 130; + } else if (gl_extensions.VersionGEThan(2, 1)) { + return 120; + } else { + return 110; + } } } diff --git a/Common/GPU/OpenGL/thin3d_gl.cpp b/Common/GPU/OpenGL/thin3d_gl.cpp index 6695ae7728..05b27923c2 100644 --- a/Common/GPU/OpenGL/thin3d_gl.cpp +++ b/Common/GPU/OpenGL/thin3d_gl.cpp @@ -134,25 +134,6 @@ static const unsigned short primToGL[] = { GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, -#if !defined(USING_GLES2) // TODO: Remove when we have better headers - GL_PATCHES, - GL_LINES_ADJACENCY, - GL_LINE_STRIP_ADJACENCY, - GL_TRIANGLES_ADJACENCY, - GL_TRIANGLE_STRIP_ADJACENCY, -#elif !defined(IOS) - GL_POINTS, - GL_POINTS, - GL_POINTS, - GL_POINTS, - GL_POINTS, -#else - GL_POINTS, - GL_POINTS, - GL_POINTS, - GL_POINTS, - GL_POINTS, -#endif }; class OpenGLBuffer; @@ -607,12 +588,15 @@ OpenGLContext::OpenGLContext() { shaderLanguageDesc_.Init(GLSL_1xx); + shaderLanguageDesc_.glslVersionNumber = gl_extensions.GLSLVersion(); + + snprintf(shaderLanguageDesc_.driverInfo, sizeof(shaderLanguageDesc_.driverInfo), + "%s - GLSL %d", gl_extensions.model, gl_extensions.GLSLVersion()); // Detect shader language features. if (gl_extensions.IsGLES) { shaderLanguageDesc_.gles = true; if (gl_extensions.GLES3) { shaderLanguageDesc_.shaderLanguage = ShaderLanguage::GLSL_3xx; - shaderLanguageDesc_.glslVersionNumber = 300; // GLSL ES 3.0 shaderLanguageDesc_.fragColor0 = "fragColor0"; shaderLanguageDesc_.texture = "texture"; shaderLanguageDesc_.glslES30 = true; @@ -623,7 +607,6 @@ OpenGLContext::OpenGLContext() { shaderLanguageDesc_.attribute = "in"; } else { shaderLanguageDesc_.shaderLanguage = ShaderLanguage::GLSL_1xx; - shaderLanguageDesc_.glslVersionNumber = 100; // GLSL ES 1.0 if (gl_extensions.EXT_gpu_shader4) { shaderLanguageDesc_.bitwiseOps = true; shaderLanguageDesc_.texelFetch = "texelFetch2D"; @@ -637,7 +620,6 @@ OpenGLContext::OpenGLContext() { if (gl_extensions.IsCoreContext) { if (gl_extensions.VersionGEThan(3, 3, 0)) { shaderLanguageDesc_.shaderLanguage = ShaderLanguage::GLSL_3xx; - shaderLanguageDesc_.glslVersionNumber = 330; shaderLanguageDesc_.fragColor0 = "fragColor0"; shaderLanguageDesc_.texture = "texture"; shaderLanguageDesc_.glslES30 = true; @@ -649,14 +631,12 @@ OpenGLContext::OpenGLContext() { } else if (gl_extensions.VersionGEThan(3, 0, 0)) { // Hm, I think this is wrong. This should be outside "if (gl_extensions.IsCoreContext)". shaderLanguageDesc_.shaderLanguage = ShaderLanguage::GLSL_1xx; - shaderLanguageDesc_.glslVersionNumber = 130; shaderLanguageDesc_.fragColor0 = "fragColor0"; shaderLanguageDesc_.bitwiseOps = true; shaderLanguageDesc_.texelFetch = "texelFetch"; } else { // This too... shaderLanguageDesc_.shaderLanguage = ShaderLanguage::GLSL_1xx; - shaderLanguageDesc_.glslVersionNumber = 110; if (gl_extensions.EXT_gpu_shader4) { shaderLanguageDesc_.bitwiseOps = true; shaderLanguageDesc_.texelFetch = "texelFetch2D"; diff --git a/Common/GPU/Shader.cpp b/Common/GPU/Shader.cpp index 35fd9fa035..bd62aaf2ed 100644 --- a/Common/GPU/Shader.cpp +++ b/Common/GPU/Shader.cpp @@ -15,6 +15,7 @@ void ShaderLanguageDesc::Init(ShaderLanguage lang) { switch (lang) { case GLSL_1xx: // Just used in the shader test, and as a basis for the others in DetectShaderLanguage. + // The real OpenGL initialization happens in thin3d_gl.cpp. glslVersionNumber = 110; attribute = "attribute"; varying_vs = "varying"; diff --git a/Common/GPU/Shader.h b/Common/GPU/Shader.h index 8a863f3c7f..20bf482239 100644 --- a/Common/GPU/Shader.h +++ b/Common/GPU/Shader.h @@ -50,6 +50,7 @@ struct ShaderLanguageDesc { bool bitwiseOps = false; bool forceMatrix4x4 = false; bool coefsFromBuffers = false; + char driverInfo[128]; // Really only GL uses this. }; enum class UniformType : int8_t { diff --git a/Common/GPU/ShaderWriter.cpp b/Common/GPU/ShaderWriter.cpp index d5bc375921..4db6bd8577 100644 --- a/Common/GPU/ShaderWriter.cpp +++ b/Common/GPU/ShaderWriter.cpp @@ -107,6 +107,8 @@ void ShaderWriter::Preamble(const char **gl_extensions, size_t num_gl_extensions for (size_t i = 0; i < num_gl_extensions; i++) { F("%s\n", gl_extensions[i]); } + // Print some system info - useful to gather information directly from screenshots. + F("// %s\n", lang_.driverInfo); switch (stage_) { case ShaderStage::Fragment: C("#define DISCARD discard\n"); diff --git a/Common/GPU/Vulkan/VulkanRenderManager.cpp b/Common/GPU/Vulkan/VulkanRenderManager.cpp index f7f15e58f1..e8b3849e00 100644 --- a/Common/GPU/Vulkan/VulkanRenderManager.cpp +++ b/Common/GPU/Vulkan/VulkanRenderManager.cpp @@ -434,7 +434,6 @@ void VulkanRenderManager::BeginFrame(bool enableProfiling) { int curFrame = vulkan_->GetCurFrame(); FrameData &frameData = frameData_[curFrame]; - frameData.profilingEnabled_ = enableProfiling; // Make sure the very last command buffer from the frame before the previous has been fully executed. if (useThread_) { @@ -447,9 +446,12 @@ void VulkanRenderManager::BeginFrame(bool enableProfiling) { } VLOG("PUSH: Fencing %d", curFrame); + vkWaitForFences(device, 1, &frameData.fence, true, UINT64_MAX); vkResetFences(device, 1, &frameData.fence); + // Can't set this until after the fence. + frameData.profilingEnabled_ = enableProfiling; frameData.readbackFenceUsed = false; uint64_t queryResults[MAX_TIMESTAMP_QUERIES]; @@ -502,6 +504,7 @@ void VulkanRenderManager::BeginFrame(bool enableProfiling) { if (frameData.profilingEnabled_) { // For various reasons, we need to always use an init cmd buffer in this case to perform the vkCmdResetQueryPool, // unless we want to limit ourselves to only measure the main cmd buffer. + // Later versions of Vulkan have support for clearing queries on the CPU timeline, but we don't want to rely on that. // Reserve the first two queries for initCmd. frameData.profile.timestampDescriptions.push_back("initCmd Begin"); frameData.profile.timestampDescriptions.push_back("initCmd"); diff --git a/GPU/Common/FragmentShaderGenerator.cpp b/GPU/Common/FragmentShaderGenerator.cpp index 4118696bb1..3fe4764029 100644 --- a/GPU/Common/FragmentShaderGenerator.cpp +++ b/GPU/Common/FragmentShaderGenerator.cpp @@ -409,11 +409,21 @@ bool GenerateFragmentShader(const FShaderID &id, char *buffer, const ShaderLangu WRITE(p, "%s vec4 fragColor0;\n", qualifierColor0); } } + } + bool hasPackUnorm4x8 = false; + if (compat.shaderLanguage == GLSL_VULKAN) { + hasPackUnorm4x8 = true; + } else if (ShaderLanguageIsOpenGL(compat.shaderLanguage)) { + if (compat.gles) { + hasPackUnorm4x8 = compat.glslVersionNumber >= 310; + } else { + hasPackUnorm4x8 = compat.glslVersionNumber >= 400; + } } // Provide implementations of packUnorm4x8 and unpackUnorm4x8 if not available. - if (colorWriteMask && (compat.shaderLanguage == HLSL_D3D11 || (compat.shaderLanguage == GLSL_3xx && (!compat.gles && compat.glslVersionNumber < 400)))) { + if (colorWriteMask && !hasPackUnorm4x8) { WRITE(p, "uint packUnorm4x8(vec4 v) {\n"); WRITE(p, " v = clamp(v, 0.0, 1.0);\n"); WRITE(p, " uvec4 u = uvec4(255.0 * v);\n");