mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 13:30:02 +00:00
OpenGL: Share the shader version detection.
Use a version integer instead of a string
This commit is contained in:
parent
c45515866b
commit
9e245d6835
@ -140,7 +140,8 @@ enum DoLightComputation {
|
||||
};
|
||||
|
||||
struct GLSLShaderCompat {
|
||||
const char *versionString;
|
||||
int glslVersionNumber;
|
||||
bool gles;
|
||||
const char *varying_fs;
|
||||
const char *varying_vs;
|
||||
const char *attribute;
|
||||
@ -150,7 +151,6 @@ struct GLSLShaderCompat {
|
||||
const char *texelFetch;
|
||||
const char *lastFragData;
|
||||
const char *framebufferFetchExtension;
|
||||
bool gles;
|
||||
bool glslES30;
|
||||
bool bitwiseOps;
|
||||
};
|
||||
|
@ -33,89 +33,9 @@
|
||||
|
||||
#define WRITE p+=sprintf
|
||||
|
||||
// #define DEBUG_SHADER
|
||||
|
||||
// Missing: Z depth range
|
||||
bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, uint64_t *uniformMask, std::string *errorString) {
|
||||
bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, const GLSLShaderCompat &compat, uint64_t *uniformMask, std::string *errorString) {
|
||||
*uniformMask = 0;
|
||||
|
||||
GLSLShaderCompat compat{};
|
||||
compat.varying_vs = "varying";
|
||||
compat.varying_fs = "varying";
|
||||
compat.fragColor0 = "gl_FragColor";
|
||||
compat.fragColor1 = "fragColor1";
|
||||
compat.texture = "texture2D";
|
||||
compat.texelFetch = nullptr;
|
||||
compat.bitwiseOps = false;
|
||||
compat.lastFragData = nullptr;
|
||||
compat.gles = gl_extensions.IsGLES;
|
||||
|
||||
if (compat.gles) {
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_GLSL_ES_300)) {
|
||||
compat.versionString = "#version 300 es"; // GLSL ES 3.0
|
||||
compat.fragColor0 = "fragColor0";
|
||||
compat.texture = "texture";
|
||||
compat.glslES30 = true;
|
||||
compat.bitwiseOps = true;
|
||||
compat.texelFetch = "texelFetch";
|
||||
} else {
|
||||
compat.versionString = "#version 100"; // GLSL ES 1.0
|
||||
if (gl_extensions.EXT_gpu_shader4) {
|
||||
compat.bitwiseOps = true;
|
||||
compat.texelFetch = "texelFetch2D";
|
||||
}
|
||||
if (gl_extensions.EXT_blend_func_extended) {
|
||||
// Oldy moldy GLES, so use the fixed output name.
|
||||
compat.fragColor1 = "gl_SecondaryFragColorEXT";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!gl_extensions.ForceGL2 || gl_extensions.IsCoreContext) {
|
||||
if (gl_extensions.VersionGEThan(3, 3, 0)) {
|
||||
compat.versionString = "#version 330";
|
||||
compat.fragColor0 = "fragColor0";
|
||||
compat.texture = "texture";
|
||||
compat.glslES30 = true;
|
||||
compat.bitwiseOps = true;
|
||||
compat.texelFetch = "texelFetch";
|
||||
} else if (gl_extensions.VersionGEThan(3, 0, 0)) {
|
||||
compat.versionString = "#version 130";
|
||||
compat.fragColor0 = "fragColor0";
|
||||
compat.bitwiseOps = true;
|
||||
compat.texelFetch = "texelFetch";
|
||||
} else {
|
||||
compat.versionString = "#version 110";
|
||||
if (gl_extensions.EXT_gpu_shader4) {
|
||||
compat.bitwiseOps = true;
|
||||
compat.texelFetch = "texelFetch2D";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH)) {
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_GLSL_ES_300) && gl_extensions.EXT_shader_framebuffer_fetch) {
|
||||
compat.framebufferFetchExtension = "#extension GL_EXT_shader_framebuffer_fetch : require";
|
||||
compat.lastFragData = "fragColor0";
|
||||
} else if (gl_extensions.EXT_shader_framebuffer_fetch) {
|
||||
compat.framebufferFetchExtension = "#extension GL_EXT_shader_framebuffer_fetch : require";
|
||||
compat.lastFragData = "gl_LastFragData[0]";
|
||||
} else if (gl_extensions.NV_shader_framebuffer_fetch) {
|
||||
// GL_NV_shader_framebuffer_fetch is available on mobile platform and ES 2.0 only but not on desktop.
|
||||
compat.framebufferFetchExtension = "#extension GL_NV_shader_framebuffer_fetch : require";
|
||||
compat.lastFragData = "gl_LastFragData[0]";
|
||||
} else if (gl_extensions.ARM_shader_framebuffer_fetch) {
|
||||
compat.framebufferFetchExtension = "#extension GL_ARM_shader_framebuffer_fetch : require";
|
||||
compat.lastFragData = "gl_LastFragColorARM";
|
||||
}
|
||||
}
|
||||
|
||||
if (compat.glslES30 || gl_extensions.IsCoreContext) {
|
||||
compat.varying_vs = "out";
|
||||
compat.varying_fs = "in";
|
||||
compat.attribute = "in";
|
||||
}
|
||||
|
||||
bool highpFog = false;
|
||||
bool highpTexcoord = false;
|
||||
if (compat.gles) {
|
||||
@ -129,8 +49,7 @@ bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, uint64_t *uni
|
||||
|
||||
char *p = buffer;
|
||||
|
||||
// Here the writing starts!
|
||||
WRITE(p, "%s\n", compat.versionString);
|
||||
WRITE(p, "#version %d%s\n", compat.glslVersionNumber, compat.gles ? " es" : "");
|
||||
|
||||
if (stencilToAlpha == REPLACE_ALPHA_DUALSOURCE && gl_extensions.EXT_blend_func_extended) {
|
||||
WRITE(p, "#extension GL_EXT_blend_func_extended : require\n");
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GPU/Common/ShaderCommon.h"
|
||||
|
||||
struct FShaderID;
|
||||
|
||||
bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, uint64_t *uniformMask, std::string *errorString);
|
||||
bool GenerateFragmentShaderGLSL(const FShaderID &id, char *buffer, const GLSLShaderCompat &compat, uint64_t *uniformMask, std::string *errorString);
|
||||
|
@ -576,12 +576,93 @@ ShaderManagerGLES::ShaderManagerGLES(Draw::DrawContext *draw)
|
||||
codeBuffer_ = new char[16384];
|
||||
lastFSID_.set_invalid();
|
||||
lastVSID_.set_invalid();
|
||||
DetectShaderLanguage();
|
||||
}
|
||||
|
||||
ShaderManagerGLES::~ShaderManagerGLES() {
|
||||
delete [] codeBuffer_;
|
||||
}
|
||||
|
||||
void ShaderManagerGLES::DetectShaderLanguage() {
|
||||
GLSLShaderCompat &compat = compat_;
|
||||
compat.attribute = "attribute";
|
||||
compat.varying_vs = "varying";
|
||||
compat.varying_fs = "varying";
|
||||
compat.fragColor0 = "gl_FragColor";
|
||||
compat.fragColor1 = "fragColor1";
|
||||
compat.texture = "texture2D";
|
||||
compat.texelFetch = nullptr;
|
||||
compat.bitwiseOps = false;
|
||||
compat.lastFragData = nullptr;
|
||||
compat.gles = gl_extensions.IsGLES;
|
||||
|
||||
if (compat.gles) {
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_GLSL_ES_300)) {
|
||||
compat.glslVersionNumber = 300; // GLSL ES 3.0
|
||||
compat.fragColor0 = "fragColor0";
|
||||
compat.texture = "texture";
|
||||
compat.glslES30 = true;
|
||||
compat.bitwiseOps = true;
|
||||
compat.texelFetch = "texelFetch";
|
||||
} else {
|
||||
compat.glslVersionNumber = 100; // GLSL ES 1.0
|
||||
if (gl_extensions.EXT_gpu_shader4) {
|
||||
compat.bitwiseOps = true;
|
||||
compat.texelFetch = "texelFetch2D";
|
||||
}
|
||||
if (gl_extensions.EXT_blend_func_extended) {
|
||||
// Oldy moldy GLES, so use the fixed output name.
|
||||
compat.fragColor1 = "gl_SecondaryFragColorEXT";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!gl_extensions.ForceGL2 || gl_extensions.IsCoreContext) {
|
||||
if (gl_extensions.VersionGEThan(3, 3, 0)) {
|
||||
compat.glslVersionNumber = 330;
|
||||
compat.fragColor0 = "fragColor0";
|
||||
compat.texture = "texture";
|
||||
compat.glslES30 = true;
|
||||
compat.bitwiseOps = true;
|
||||
compat.texelFetch = "texelFetch";
|
||||
} else if (gl_extensions.VersionGEThan(3, 0, 0)) {
|
||||
compat.glslVersionNumber = 130;
|
||||
compat.fragColor0 = "fragColor0";
|
||||
compat.bitwiseOps = true;
|
||||
compat.texelFetch = "texelFetch";
|
||||
} else {
|
||||
compat.glslVersionNumber = 110;
|
||||
if (gl_extensions.EXT_gpu_shader4) {
|
||||
compat.bitwiseOps = true;
|
||||
compat.texelFetch = "texelFetch2D";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_ANY_FRAMEBUFFER_FETCH)) {
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_GLSL_ES_300) && gl_extensions.EXT_shader_framebuffer_fetch) {
|
||||
compat.framebufferFetchExtension = "#extension GL_EXT_shader_framebuffer_fetch : require";
|
||||
compat.lastFragData = "fragColor0";
|
||||
} else if (gl_extensions.EXT_shader_framebuffer_fetch) {
|
||||
compat.framebufferFetchExtension = "#extension GL_EXT_shader_framebuffer_fetch : require";
|
||||
compat.lastFragData = "gl_LastFragData[0]";
|
||||
} else if (gl_extensions.NV_shader_framebuffer_fetch) {
|
||||
// GL_NV_shader_framebuffer_fetch is available on mobile platform and ES 2.0 only but not on desktop.
|
||||
compat.framebufferFetchExtension = "#extension GL_NV_shader_framebuffer_fetch : require";
|
||||
compat.lastFragData = "gl_LastFragData[0]";
|
||||
} else if (gl_extensions.ARM_shader_framebuffer_fetch) {
|
||||
compat.framebufferFetchExtension = "#extension GL_ARM_shader_framebuffer_fetch : require";
|
||||
compat.lastFragData = "gl_LastFragColorARM";
|
||||
}
|
||||
}
|
||||
|
||||
if (compat.glslES30 || gl_extensions.IsCoreContext) {
|
||||
compat.varying_vs = "out";
|
||||
compat.varying_fs = "in";
|
||||
compat.attribute = "in";
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderManagerGLES::Clear() {
|
||||
DirtyLastShader();
|
||||
for (auto iter = linkedShaderCache_.begin(); iter != linkedShaderCache_.end(); ++iter) {
|
||||
@ -630,7 +711,7 @@ void ShaderManagerGLES::DirtyLastShader() {
|
||||
Shader *ShaderManagerGLES::CompileFragmentShader(FShaderID FSID) {
|
||||
uint64_t uniformMask;
|
||||
std::string errorString;
|
||||
if (!GenerateFragmentShaderGLSL(FSID, codeBuffer_, &uniformMask, &errorString)) {
|
||||
if (!GenerateFragmentShaderGLSL(FSID, codeBuffer_, compat_, &uniformMask, &errorString)) {
|
||||
ERROR_LOG(G3D, "Shader gen error: %s", errorString.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
@ -643,7 +724,7 @@ Shader *ShaderManagerGLES::CompileVertexShader(VShaderID VSID) {
|
||||
uint32_t attrMask;
|
||||
uint64_t uniformMask;
|
||||
std::string errorString;
|
||||
if (!GenerateVertexShaderGLSL(VSID, codeBuffer_, &attrMask, &uniformMask, &errorString)) {
|
||||
if (!GenerateVertexShaderGLSL(VSID, codeBuffer_, compat_, &attrMask, &uniformMask, &errorString)) {
|
||||
ERROR_LOG(G3D, "Shader gen error: %s", errorString.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -183,6 +183,7 @@ private:
|
||||
void Clear();
|
||||
Shader *CompileFragmentShader(FShaderID id);
|
||||
Shader *CompileVertexShader(VShaderID id);
|
||||
void DetectShaderLanguage();
|
||||
|
||||
struct LinkedShaderCacheEntry {
|
||||
LinkedShaderCacheEntry(Shader *vs_, Shader *fs_, LinkedShader *ls_)
|
||||
@ -195,6 +196,7 @@ private:
|
||||
typedef std::vector<LinkedShaderCacheEntry> LinkedShaderCache;
|
||||
|
||||
GLRenderManager *render_;
|
||||
GLSLShaderCompat compat_{};
|
||||
LinkedShaderCache linkedShaderCache_;
|
||||
|
||||
bool lastVShaderSame_;
|
||||
|
@ -87,59 +87,12 @@ static const char * const boneWeightInDecl[9] = {
|
||||
// TODO: Skip all this if we can actually get a 16-bit depth buffer along with stencil, which
|
||||
// is a bit of a rare configuration, although quite common on mobile.
|
||||
|
||||
bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, uint32_t *attrMask, uint64_t *uniformMask, std::string *errorString) {
|
||||
bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, const GLSLShaderCompat &compat, uint32_t *attrMask, uint64_t *uniformMask, std::string *errorString) {
|
||||
*attrMask = 0;
|
||||
*uniformMask = 0;
|
||||
|
||||
// In GLSL ES 3.0, you use "out" variables instead.
|
||||
GLSLShaderCompat compat{};
|
||||
compat.glslES30 = false;
|
||||
compat.varying_vs = "varying";
|
||||
compat.varying_fs = "varying";
|
||||
compat.attribute = "attribute";
|
||||
compat.texelFetch = nullptr;
|
||||
compat.gles = gl_extensions.IsGLES;
|
||||
|
||||
if (compat.gles) {
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_GLSL_ES_300)) {
|
||||
compat.versionString = "#version 300 es"; // GLSL ES 3.0
|
||||
compat.glslES30 = true;
|
||||
compat.texelFetch = "texelFetch";
|
||||
} else {
|
||||
compat.versionString = "#version 100"; // GLSL ES 1.0
|
||||
if (gl_extensions.EXT_gpu_shader4) {
|
||||
compat.texelFetch = "texelFetch2D";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!gl_extensions.ForceGL2 || gl_extensions.IsCoreContext) {
|
||||
if (gl_extensions.VersionGEThan(3, 3, 0)) {
|
||||
compat.glslES30 = true;
|
||||
compat.versionString = "#version 330";
|
||||
compat.texelFetch = "texelFetch";
|
||||
} else if (gl_extensions.VersionGEThan(3, 0, 0)) {
|
||||
compat.versionString = "#version 130";
|
||||
if (gl_extensions.EXT_gpu_shader4) {
|
||||
compat.texelFetch = "texelFetch";
|
||||
}
|
||||
} else {
|
||||
compat.versionString = "#version 110";
|
||||
if (gl_extensions.EXT_gpu_shader4) {
|
||||
compat.texelFetch = "texelFetch2D";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (compat.glslES30 || gl_extensions.IsCoreContext) {
|
||||
compat.attribute = "in";
|
||||
compat.varying_vs = "out";
|
||||
compat.varying_fs = "in";
|
||||
}
|
||||
|
||||
char *p = buffer;
|
||||
// Here the writing starts!
|
||||
WRITE(p, "%s\n", compat.versionString);
|
||||
WRITE(p, "#version %d%s\n", compat.glslVersionNumber, compat.gles ? " es" : "");
|
||||
|
||||
bool highpFog = false;
|
||||
bool highpTexcoord = false;
|
||||
|
@ -21,4 +21,4 @@
|
||||
|
||||
struct VShaderID;
|
||||
|
||||
bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, uint32_t *attrMask, uint64_t *uniformMask, std::string *errorString);
|
||||
bool GenerateVertexShaderGLSL(const VShaderID &id, char *buffer, const GLSLShaderCompat &compat, uint32_t *attrMask, uint64_t *uniformMask, std::string *errorString);
|
||||
|
Loading…
Reference in New Issue
Block a user