mirror of
https://github.com/MobileGL-Dev/MobileGlues.git
synced 2025-09-11 05:00:53 -04:00
[Feat] (Shader): Emulate atomicCounter advanced operations.
This commit is contained in:
parent
cea5d7ab81
commit
a2b4aa69f8
@ -19,6 +19,7 @@ GLuint bufSampelerLoc;
|
|||||||
std::string bufSampelerName;
|
std::string bufSampelerName;
|
||||||
|
|
||||||
extern std::unordered_map<GLuint, bool> program_map_is_sampler_buffer_emulated;
|
extern std::unordered_map<GLuint, bool> program_map_is_sampler_buffer_emulated;
|
||||||
|
extern std::unordered_map<GLuint, bool> program_map_is_atomic_counter_emulated;
|
||||||
|
|
||||||
unordered_map<GLuint, SamplerInfo> g_samplerCacheForSamplerBuffer;
|
unordered_map<GLuint, SamplerInfo> g_samplerCacheForSamplerBuffer;
|
||||||
|
|
||||||
@ -99,10 +100,6 @@ void prepareForDraw() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// solve the crash error for ANGLE, but it will make Derivative Main with Optifine not work!
|
|
||||||
|
|
||||||
//_Thread_local static bool unexpected_error = false;
|
|
||||||
|
|
||||||
void glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount) {
|
void glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount) {
|
||||||
LOG()
|
LOG()
|
||||||
LOG_D("glDrawElementsInstanced, mode: %d, count: %d, type: %d, indices: %p, primcount: %d",
|
LOG_D("glDrawElementsInstanced, mode: %d, count: %d, type: %d, indices: %p, primcount: %d",
|
||||||
@ -116,67 +113,73 @@ void glDrawElements(GLenum mode, GLsizei count, GLenum type, const void* indices
|
|||||||
LOG()
|
LOG()
|
||||||
LOG_D("glDrawElements, mode: %d, count: %d, type: %d, indices: %p", mode, count, type, indices)
|
LOG_D("glDrawElements, mode: %d, count: %d, type: %d, indices: %p", mode, count, type, indices)
|
||||||
prepareForDraw();
|
prepareForDraw();
|
||||||
//LOAD_GLES_FUNC(glGetError)
|
|
||||||
//GLenum pre_err = GLES.glGetError();
|
|
||||||
//if(pre_err != GL_NO_ERROR) {
|
|
||||||
// LOG_D("Skipping due to prior error: 0x%04X", pre_err)
|
|
||||||
// return;
|
|
||||||
//}
|
|
||||||
//if (!unexpected_error) {
|
|
||||||
// LOG_D("es_glDrawElements, mode: %d, count: %d, type: %d, indices: %p", mode, count, type, indices)
|
|
||||||
GLES.glDrawElements(mode, count, type, indices);
|
GLES.glDrawElements(mode, count, type, indices);
|
||||||
CHECK_GL_ERROR
|
CHECK_GL_ERROR
|
||||||
//} else {
|
|
||||||
// unexpected_error = false;
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void glBindImageTexture(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format) {
|
void glBindImageTexture(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format) {
|
||||||
|
|
||||||
LOG()
|
LOG()
|
||||||
LOG_D("glBindImageTexture, unit: %d, texture: %d, level: %d, layered: %d, layer: %d, access: %d, format: %d",
|
LOG_D("glBindImageTexture, unit: %d, texture: %d, level: %d, layered: %d, layer: %d, access: %d, format: %d",
|
||||||
unit, texture, level, layered, layer, access, format)
|
unit, texture, level, layered, layer, access, format)
|
||||||
//LOAD_GLES_FUNC(glGetError)
|
|
||||||
GLES.glBindImageTexture(unit, texture, level, layered, layer, access, format);
|
GLES.glBindImageTexture(unit, texture, level, layered, layer, access, format);
|
||||||
CHECK_GL_ERROR
|
CHECK_GL_ERROR
|
||||||
//GLenum err;
|
|
||||||
//while((err = GLES.glGetError()) != GL_NO_ERROR) {
|
|
||||||
// LOG_D("GL Error: 0x%04X", err)
|
|
||||||
// unexpected_error = true;
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void glUniform1i(GLint location, GLint v0) {
|
void glUniform1i(GLint location, GLint v0) {
|
||||||
LOG()
|
LOG()
|
||||||
LOG_D("glUniform1i, location: %d, v0: %d", location, v0)
|
LOG_D("glUniform1i, location: %d, v0: %d", location, v0)
|
||||||
//LOAD_GLES_FUNC(glGetError)
|
|
||||||
GLES.glUniform1i(location, v0);
|
GLES.glUniform1i(location, v0);
|
||||||
CHECK_GL_ERROR
|
CHECK_GL_ERROR
|
||||||
//GLenum err;
|
}
|
||||||
//while((err = GLES.glGetError()) != GL_NO_ERROR) {
|
|
||||||
// LOG_D("GL Error: 0x%04X", err)
|
void bindAllAtomicCounterAsSSBO() {
|
||||||
// unexpected_error = true;
|
GLint maxBindings = 0;
|
||||||
//}
|
GLES.glGetIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, &maxBindings);
|
||||||
|
if (maxBindings <= 0) {
|
||||||
|
LOG_W("No atomic counter buffer bindings available, maxBindings: %d", maxBindings);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<GLuint> buffers(maxBindings, 0);
|
||||||
|
|
||||||
|
for (GLint i = 0; i < maxBindings; ++i) {
|
||||||
|
GLES.glGetIntegeri_v(GL_ATOMIC_COUNTER_BUFFER_BINDING, i, reinterpret_cast<GLint*>(&buffers[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (GLint i = 0; i < maxBindings; ++i) {
|
||||||
|
GLuint buf = buffers[i];
|
||||||
|
if (buf != 0) {
|
||||||
|
GLES.glBindBufferBase(GL_SHADER_STORAGE_BUFFER, i, buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_D("Bound %d atomic counter buffers as SSBOs", maxBindings);
|
||||||
}
|
}
|
||||||
|
|
||||||
void glDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z) {
|
void glDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z) {
|
||||||
LOG()
|
LOG()
|
||||||
LOG_D("glDispatchCompute, num_groups_x: %d, num_groups_y: %d, num_groups_z: %d",
|
LOG_D("glDispatchCompute, num_groups_x: %d, num_groups_y: %d, num_groups_z: %d",
|
||||||
num_groups_x, num_groups_y, num_groups_z)
|
num_groups_x, num_groups_y, num_groups_z)
|
||||||
//LOAD_GLES_FUNC(glGetError)
|
if (program_map_is_atomic_counter_emulated[gl_state->current_program]) {
|
||||||
//GLenum pre_err = GLES.glGetError();
|
bindAllAtomicCounterAsSSBO();
|
||||||
//if(pre_err != GL_NO_ERROR) {
|
LOG_D("Atomic counters bound as SSBOs for program %d", gl_state->current_program);
|
||||||
// LOG_D("Skipping due to prior error: 0x%04X", pre_err)
|
}
|
||||||
// return;
|
else {
|
||||||
//}
|
LOG_D("No atomic counters bound as SSBOs for program %d", gl_state->current_program);
|
||||||
//if (!unexpected_error) {
|
}
|
||||||
// LOG_D("es_glDispatchCompute, num_groups_x: %d, num_groups_y: %d, num_groups_z: %d",
|
|
||||||
// num_groups_x, num_groups_y, num_groups_z)
|
|
||||||
GLES.glDispatchCompute(num_groups_x, num_groups_y, num_groups_z);
|
GLES.glDispatchCompute(num_groups_x, num_groups_y, num_groups_z);
|
||||||
CHECK_GL_ERROR
|
CHECK_GL_ERROR
|
||||||
//} else {
|
}
|
||||||
// unexpected_error = false;
|
|
||||||
//}
|
void glMemoryBarrier(GLbitfield barriers) {
|
||||||
|
LOG()
|
||||||
|
LOG_D("glMemoryBarrier, barriers: %d", barriers)
|
||||||
|
if (program_map_is_atomic_counter_emulated[gl_state->current_program]) {
|
||||||
|
barriers |= GL_ATOMIC_COUNTER_BARRIER_BIT;
|
||||||
|
barriers |= GL_SHADER_STORAGE_BARRIER_BIT;
|
||||||
|
}
|
||||||
|
GLES.glMemoryBarrier(barriers);
|
||||||
|
CHECK_GL_ERROR
|
||||||
}
|
}
|
||||||
|
|
||||||
void glDrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const void* indices, GLint basevertex) {
|
void glDrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const void* indices, GLint basevertex) {
|
||||||
|
@ -35,6 +35,7 @@ GLAPI GLAPIENTRY void glDrawElements(GLenum mode, GLsizei count, GLenum type, co
|
|||||||
|
|
||||||
GLAPI GLAPIENTRY void glBindImageTexture(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);
|
GLAPI GLAPIENTRY void glBindImageTexture(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);
|
||||||
GLAPI GLAPIENTRY void glDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);
|
GLAPI GLAPIENTRY void glDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);
|
||||||
|
GLAPI GLAPIENTRY void glMemoryBarrier(GLbitfield barriers);
|
||||||
GLAPI GLAPIENTRY void glUniform1i(GLint location, GLint v0);
|
GLAPI GLAPIENTRY void glUniform1i(GLint location, GLint v0);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -311,7 +311,7 @@ NATIVE_FUNCTION_HEAD(void, glValidateProgramPipeline, GLuint pipeline) NATIVE_FU
|
|||||||
NATIVE_FUNCTION_HEAD(void, glGetProgramPipelineInfoLog, GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog) NATIVE_FUNCTION_END_NO_RETURN(void, glGetProgramPipelineInfoLog, pipeline,bufSize,length,infoLog)
|
NATIVE_FUNCTION_HEAD(void, glGetProgramPipelineInfoLog, GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog) NATIVE_FUNCTION_END_NO_RETURN(void, glGetProgramPipelineInfoLog, pipeline,bufSize,length,infoLog)
|
||||||
//NATIVE_FUNCTION_HEAD(void, glBindImageTexture, GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format) NATIVE_FUNCTION_END_NO_RETURN(void, glBindImageTexture, unit,texture,level,layered,layer,access,format)
|
//NATIVE_FUNCTION_HEAD(void, glBindImageTexture, GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format) NATIVE_FUNCTION_END_NO_RETURN(void, glBindImageTexture, unit,texture,level,layered,layer,access,format)
|
||||||
NATIVE_FUNCTION_HEAD(void, glGetBooleani_v, GLenum target, GLuint index, GLboolean *data) NATIVE_FUNCTION_END_NO_RETURN(void, glGetBooleani_v, target,index,data)
|
NATIVE_FUNCTION_HEAD(void, glGetBooleani_v, GLenum target, GLuint index, GLboolean *data) NATIVE_FUNCTION_END_NO_RETURN(void, glGetBooleani_v, target,index,data)
|
||||||
NATIVE_FUNCTION_HEAD(void, glMemoryBarrier, GLbitfield barriers) NATIVE_FUNCTION_END_NO_RETURN(void, glMemoryBarrier, barriers)
|
//NATIVE_FUNCTION_HEAD(void, glMemoryBarrier, GLbitfield barriers) NATIVE_FUNCTION_END_NO_RETURN(void, glMemoryBarrier, barriers)
|
||||||
NATIVE_FUNCTION_HEAD(void, glMemoryBarrierByRegion, GLbitfield barriers) NATIVE_FUNCTION_END_NO_RETURN(void, glMemoryBarrierByRegion, barriers)
|
NATIVE_FUNCTION_HEAD(void, glMemoryBarrierByRegion, GLbitfield barriers) NATIVE_FUNCTION_END_NO_RETURN(void, glMemoryBarrierByRegion, barriers)
|
||||||
NATIVE_FUNCTION_HEAD(void, glTexStorage2DMultisample, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) NATIVE_FUNCTION_END_NO_RETURN(void, glTexStorage2DMultisample, target,samples,internalformat,width,height,fixedsamplelocations)
|
NATIVE_FUNCTION_HEAD(void, glTexStorage2DMultisample, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) NATIVE_FUNCTION_END_NO_RETURN(void, glTexStorage2DMultisample, target,samples,internalformat,width,height,fixedsamplelocations)
|
||||||
NATIVE_FUNCTION_HEAD(void, glGetMultisamplefv, GLenum pname, GLuint index, GLfloat *val) NATIVE_FUNCTION_END_NO_RETURN(void, glGetMultisamplefv, pname,index,val)
|
NATIVE_FUNCTION_HEAD(void, glGetMultisamplefv, GLenum pname, GLuint index, GLfloat *val) NATIVE_FUNCTION_END_NO_RETURN(void, glGetMultisamplefv, pname,index,val)
|
||||||
|
@ -16,7 +16,9 @@
|
|||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "../../version.h"
|
#include "../../version.h"
|
||||||
|
|
||||||
#define DEBUG 0
|
#define DEBUG 0
|
||||||
|
|
||||||
|
const char* atomicCounterEmulatedWatermark = "\n// Non-opaque atomic uniform converted to SSBO\n";
|
||||||
|
|
||||||
#if !defined(__APPLE__)
|
#if !defined(__APPLE__)
|
||||||
char* (*MesaConvertShader)(const char *src, unsigned int type, unsigned int glsl, unsigned int essl);
|
char* (*MesaConvertShader)(const char *src, unsigned int type, unsigned int glsl, unsigned int essl);
|
||||||
@ -335,33 +337,29 @@ std::string processOutColorLocations(const std::string& glslCode) {
|
|||||||
return std::regex_replace(glslCode, pattern, replacement);
|
return std::regex_replace(glslCode, pattern, replacement);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getCachedESSL(const char* glsl_code, uint essl_version) {
|
bool checkIfAtomicCounterBufferEmulated(const std::string& glslCode) {
|
||||||
std::string sha256_string(glsl_code);
|
return glslCode.find(atomicCounterEmulatedWatermark) != std::string::npos;
|
||||||
sha256_string += "\n//" + std::to_string(MAJOR) + "." + std::to_string(MINOR) + "." + std::to_string(REVISION) + "|" + std::to_string(essl_version);
|
|
||||||
const char* cachedESSL = Cache::get_instance().get(sha256_string.c_str());
|
|
||||||
if (cachedESSL) {
|
|
||||||
LOG_D("GLSL Hit Cache:\n%s\n-->\n%s", glsl_code, cachedESSL)
|
|
||||||
return cachedESSL;
|
|
||||||
} else return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GLSLtoGLSLES(const char* glsl_code, GLenum glsl_type, uint essl_version, uint glsl_version) {
|
std::string GLSLtoGLSLES(const char* glsl_code, GLenum glsl_type, uint essl_version, uint glsl_version, int& return_code) {
|
||||||
std::string sha256_string(glsl_code);
|
std::string sha256_string(glsl_code);
|
||||||
sha256_string += "\n//" + std::to_string(MAJOR) + "." + std::to_string(MINOR) + "." + std::to_string(REVISION) + "|" + std::to_string(essl_version);
|
sha256_string += "\n//" + std::to_string(MAJOR) + "." + std::to_string(MINOR) + "." + std::to_string(REVISION) + "|" + std::to_string(essl_version);
|
||||||
const char* cachedESSL = Cache::get_instance().get(sha256_string.c_str());
|
const char* cachedESSL = Cache::get_instance().get(sha256_string.c_str());
|
||||||
if (cachedESSL) {
|
if (cachedESSL) {
|
||||||
LOG_D("GLSL Hit Cache:\n%s\n-->\n%s", glsl_code, cachedESSL)
|
LOG_D("GLSL Hit Cache:\n%s\n-->\n%s", glsl_code, cachedESSL)
|
||||||
|
bool atomicCounterEmulated = checkIfAtomicCounterBufferEmulated(std::string(cachedESSL));
|
||||||
|
return_code = atomicCounterEmulated ? 1 : 0;
|
||||||
return (char*)cachedESSL;
|
return (char*)cachedESSL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int return_code = -1;
|
return_code = -1;
|
||||||
std::string converted = glsl_version<140? GLSLtoGLSLES_1(glsl_code, glsl_type, essl_version, return_code):GLSLtoGLSLES_2(glsl_code, glsl_type, essl_version, return_code);
|
std::string converted = glsl_version<140? GLSLtoGLSLES_1(glsl_code, glsl_type, essl_version, return_code):GLSLtoGLSLES_2(glsl_code, glsl_type, essl_version, return_code);
|
||||||
if (return_code == 0 && !converted.empty()) {
|
if (return_code >= 0 && !converted.empty()) {
|
||||||
converted = process_uniform_declarations(converted);
|
converted = process_uniform_declarations(converted);
|
||||||
Cache::get_instance().put(sha256_string.c_str(), converted.c_str());
|
Cache::get_instance().put(sha256_string.c_str(), converted.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return (return_code == 0) ? converted : glsl_code;
|
return (return_code >= 0) ? converted : glsl_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string replace_line_starting_with(const std::string& glslCode, const std::string& starting, const std::string& substitution = "") {
|
std::string replace_line_starting_with(const std::string& glslCode, const std::string& starting, const std::string& substitution = "") {
|
||||||
@ -487,6 +485,70 @@ static size_t find_insertion_point(const std::string& glsl) {
|
|||||||
return insertion_point;
|
return insertion_point;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool process_non_opaque_atomic_to_ssbo(std::string& source) {
|
||||||
|
if (source.find("atomicCounter") == std::string::npos) return false;
|
||||||
|
|
||||||
|
std::set<std::string> atomic_vars;
|
||||||
|
std::map<std::string, std::string> binding_map;
|
||||||
|
std::regex decl_rx(
|
||||||
|
R"(layout\s*\(\s*binding\s*=\s*(\d+)\s*(?:,\s*offset\s*=\s*(\d+)\s*)?\)\s*uniform\s+atomic_uint\s+(\w+)\s*;)",
|
||||||
|
std::regex::icase
|
||||||
|
);
|
||||||
|
|
||||||
|
std::smatch m;
|
||||||
|
auto it = source.cbegin();
|
||||||
|
while (std::regex_search(it, source.cend(), m, decl_rx)) {
|
||||||
|
size_t prefix = std::distance(source.cbegin(), it);
|
||||||
|
size_t match_pos = prefix + m.position(0);
|
||||||
|
size_t match_len = m.length(0);
|
||||||
|
|
||||||
|
std::string binding = m[1].str();
|
||||||
|
std::string var = m[3].str();
|
||||||
|
atomic_vars.insert(var);
|
||||||
|
binding_map[var] = binding;
|
||||||
|
|
||||||
|
std::string repl =
|
||||||
|
"layout(std430, binding=" + binding + ") buffer AtomicCounterSSBO_" + binding + " {\n"
|
||||||
|
" uint " + var + ";\n"
|
||||||
|
"};\n";
|
||||||
|
source.replace(match_pos, match_len, repl);
|
||||||
|
|
||||||
|
it = source.cbegin() + match_pos + repl.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (atomic_vars.empty()) return true;
|
||||||
|
|
||||||
|
for (auto& var : atomic_vars) {
|
||||||
|
source = std::regex_replace(source,
|
||||||
|
std::regex(R"(\batomicCounterIncrement\s*\(\s*)" + var + R"(\s*\))", std::regex::icase),
|
||||||
|
"atomicAdd(" + var + ", 1u)"
|
||||||
|
);
|
||||||
|
source = std::regex_replace(source,
|
||||||
|
std::regex(R"(\batomicCounterDecrement\s*\(\s*)" + var + R"(\s*\))", std::regex::icase),
|
||||||
|
"atomicAdd(" + var + ", uint(-1))"
|
||||||
|
);
|
||||||
|
source = std::regex_replace(source,
|
||||||
|
std::regex(R"(\batomicCounterAdd\s*\(\s*)" + var + R"(\s*,\s*([^)]+)\s*\))", std::regex::icase),
|
||||||
|
"atomicAdd(" + var + ", $1)"
|
||||||
|
);
|
||||||
|
source = std::regex_replace(source,
|
||||||
|
std::regex(R"(\batomicCounter\s*\(\s*)" + var + R"(\s*\))", std::regex::icase),
|
||||||
|
var
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::regex rx_barrier(R"(\batomicAdd\s*\([^;]*\);)");
|
||||||
|
source = std::regex_replace(source,
|
||||||
|
rx_barrier,
|
||||||
|
"$&\n memoryBarrierBuffer();"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
source += atomicCounterEmulatedWatermark;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void process_sampler_buffer(std::string& source) { // a simplized version, should be rewritten in the future
|
void process_sampler_buffer(std::string& source) { // a simplized version, should be rewritten in the future
|
||||||
if (source.find("isamplerBuffer") == std::string::npos) {
|
if (source.find("isamplerBuffer") == std::string::npos) {
|
||||||
return;
|
return;
|
||||||
@ -636,8 +698,7 @@ void inject_mg_macro_definition(std::string& glslCode) {
|
|||||||
glslCode.insert(insertionPos, macro_definitions);
|
glslCode.insert(insertionPos, macro_definitions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string preprocess_glsl(const std::string& glsl, GLenum shaderType, bool* atomicCounterEmulated) {
|
||||||
std::string preprocess_glsl(const std::string& glsl, GLenum shaderType) {
|
|
||||||
std::string ret = glsl;
|
std::string ret = glsl;
|
||||||
// Remove lines beginning with `#line`
|
// Remove lines beginning with `#line`
|
||||||
ret = replace_line_starting_with(ret, "#line");
|
ret = replace_line_starting_with(ret, "#line");
|
||||||
@ -666,6 +727,7 @@ std::string preprocess_glsl(const std::string& glsl, GLenum shaderType) {
|
|||||||
process_sampler_buffer(ret);
|
process_sampler_buffer(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*atomicCounterEmulated = process_non_opaque_atomic_to_ssbo(ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -783,7 +845,8 @@ std::string spirv_to_essl(std::vector<unsigned int> spirv, uint essl_version, in
|
|||||||
|
|
||||||
static bool glslang_inited = false;
|
static bool glslang_inited = false;
|
||||||
std::string GLSLtoGLSLES_2(const char *glsl_code, GLenum glsl_type, uint essl_version, int& return_code) {
|
std::string GLSLtoGLSLES_2(const char *glsl_code, GLenum glsl_type, uint essl_version, int& return_code) {
|
||||||
std::string correct_glsl_str = preprocess_glsl(glsl_code, glsl_type);
|
bool atomicCounterEmulated = false;
|
||||||
|
std::string correct_glsl_str = preprocess_glsl(glsl_code, glsl_type, &atomicCounterEmulated);
|
||||||
LOG_D("Firstly converted GLSL:\n%s", correct_glsl_str.c_str())
|
LOG_D("Firstly converted GLSL:\n%s", correct_glsl_str.c_str())
|
||||||
int glsl_version = get_or_add_glsl_version(correct_glsl_str);
|
int glsl_version = get_or_add_glsl_version(correct_glsl_str);
|
||||||
|
|
||||||
@ -814,8 +877,10 @@ std::string GLSLtoGLSLES_2(const char *glsl_code, GLenum glsl_type, uint essl_ve
|
|||||||
essl = forceSupporterOutput(essl);
|
essl = forceSupporterOutput(essl);
|
||||||
|
|
||||||
LOG_D("Originally GLSL to GLSL ES Complete: \n%s", essl.c_str())
|
LOG_D("Originally GLSL to GLSL ES Complete: \n%s", essl.c_str())
|
||||||
|
|
||||||
return_code = errc;
|
return_code = errc;
|
||||||
|
if (return_code == 0) {
|
||||||
|
return_code = atomicCounterEmulated ? 1 : 0;
|
||||||
|
}
|
||||||
return essl;
|
return essl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,8 +16,7 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::string getCachedESSL(const char* glsl_code, uint essl_version);
|
std::string GLSLtoGLSLES(const char* glsl_code, GLenum glsl_type, uint essl_version, uint glsl_version, int& return_code);
|
||||||
std::string GLSLtoGLSLES(const char *glsl_code, GLenum glsl_type, uint esversion, uint glsl_version);
|
|
||||||
std::string GLSLtoGLSLES_1(const char *glsl_code, GLenum glsl_type, uint esversion, int& return_code);
|
std::string GLSLtoGLSLES_1(const char *glsl_code, GLenum glsl_type, uint esversion, int& return_code);
|
||||||
std::string GLSLtoGLSLES_2(const char *glsl_code, GLenum glsl_type, uint essl_version, int& return_code);
|
std::string GLSLtoGLSLES_2(const char *glsl_code, GLenum glsl_type, uint essl_version, int& return_code);
|
||||||
int getGLSLVersion(const char* glsl_code);
|
int getGLSLVersion(const char* glsl_code);
|
||||||
|
@ -18,6 +18,9 @@
|
|||||||
extern std::unordered_map<GLuint, bool> shader_map_is_sampler_buffer_emulated;
|
extern std::unordered_map<GLuint, bool> shader_map_is_sampler_buffer_emulated;
|
||||||
std::unordered_map<GLuint, bool> program_map_is_sampler_buffer_emulated;
|
std::unordered_map<GLuint, bool> program_map_is_sampler_buffer_emulated;
|
||||||
|
|
||||||
|
extern std::unordered_map<GLuint, bool> shader_map_is_atomic_counter_emulated;
|
||||||
|
std::unordered_map<GLuint, bool> program_map_is_atomic_counter_emulated;
|
||||||
|
|
||||||
char* updateLayoutLocation(const char* esslSource, GLuint color, const char* name) {
|
char* updateLayoutLocation(const char* esslSource, GLuint color, const char* name) {
|
||||||
std::string shaderCode(esslSource);
|
std::string shaderCode(esslSource);
|
||||||
|
|
||||||
@ -142,6 +145,10 @@ void glAttachShader(GLuint program, GLuint shader) {
|
|||||||
LOG_D("glAttachShader(%u, %u)", program, shader)
|
LOG_D("glAttachShader(%u, %u)", program, shader)
|
||||||
if (hardware->emulate_texture_buffer && shader_map_is_sampler_buffer_emulated[shader])
|
if (hardware->emulate_texture_buffer && shader_map_is_sampler_buffer_emulated[shader])
|
||||||
program_map_is_sampler_buffer_emulated[program] = true;
|
program_map_is_sampler_buffer_emulated[program] = true;
|
||||||
|
if (shader_map_is_atomic_counter_emulated[shader]) {
|
||||||
|
program_map_is_atomic_counter_emulated[program] = true;
|
||||||
|
LOG_D("Shader %d is atomic counter emulated, setting program %d to atomic counter emulated", shader, program)
|
||||||
|
}
|
||||||
|
|
||||||
GLES.glAttachShader(program, shader);
|
GLES.glAttachShader(program, shader);
|
||||||
CHECK_GL_ERROR
|
CHECK_GL_ERROR
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
struct shader_t shaderInfo;
|
struct shader_t shaderInfo;
|
||||||
|
|
||||||
std::unordered_map<GLuint, bool> shader_map_is_sampler_buffer_emulated;
|
std::unordered_map<GLuint, bool> shader_map_is_sampler_buffer_emulated;
|
||||||
|
std::unordered_map<GLuint, bool> shader_map_is_atomic_counter_emulated;
|
||||||
|
|
||||||
bool can_run_essl3(unsigned int esversion, const char *glsl) {
|
bool can_run_essl3(unsigned int esversion, const char *glsl) {
|
||||||
if (strncmp(glsl, "#version 100", 12) == 0) {
|
if (strncmp(glsl, "#version 100", 12) == 0) {
|
||||||
@ -83,9 +84,13 @@ void glShaderSource(GLuint shader, GLsizei count, const GLchar *const* string, c
|
|||||||
LOG_D("%s", glsl_src.c_str())
|
LOG_D("%s", glsl_src.c_str())
|
||||||
GLint shaderType;
|
GLint shaderType;
|
||||||
GLES.glGetShaderiv(shader, GL_SHADER_TYPE, &shaderType);
|
GLES.glGetShaderiv(shader, GL_SHADER_TYPE, &shaderType);
|
||||||
essl_src = getCachedESSL(glsl_src.c_str(), hardware->es_version);
|
int return_code = 0;
|
||||||
if (essl_src.empty())
|
essl_src = GLSLtoGLSLES(glsl_src.c_str(), shaderType, hardware->es_version, glsl_version, return_code);
|
||||||
essl_src = GLSLtoGLSLES(glsl_src.c_str(), shaderType, hardware->es_version, glsl_version);
|
if (return_code == 1) { //atomicCounterEmulated
|
||||||
|
shader_map_is_atomic_counter_emulated[shader] = true;
|
||||||
|
LOG_D("[INFO] [Shader] Atomic counter emulated in shader %d", shader)
|
||||||
|
}
|
||||||
|
|
||||||
if (essl_src.empty()) {
|
if (essl_src.empty()) {
|
||||||
LOG_E("Failed to convert shader %d.", shader)
|
LOG_E("Failed to convert shader %d.", shader)
|
||||||
return;
|
return;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user