Better GLSL version handling. Now specify the latest version supported by the device.

Correct the version check for our own implementations of packUnorm4x8 etc.
This commit is contained in:
Henrik Rydgård 2020-11-16 23:26:37 +01:00
parent cf092eb534
commit 29b2f2c4ef
8 changed files with 44 additions and 47 deletions

View file

@ -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

View file

@ -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;
}
}
}

View file

@ -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";

View file

@ -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";

View file

@ -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 {

View file

@ -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");

View file

@ -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");

View file

@ -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");