diff --git a/intern/gawain/gawain/attrib_binding.h b/intern/gawain/gawain/attrib_binding.h index f1378bff8cc..0642492882a 100644 --- a/intern/gawain/gawain/attrib_binding.h +++ b/intern/gawain/gawain/attrib_binding.h @@ -12,6 +12,7 @@ #pragma once #include "vertex_format.h" +#include "shader_interface.h" typedef struct { uint64_t loc_bits; // store 4 bits for each of the 16 attribs @@ -20,5 +21,5 @@ typedef struct { void AttribBinding_clear(AttribBinding*); -void get_attrib_locations(const VertexFormat*, AttribBinding*, GLuint program); +void get_attrib_locations(const VertexFormat*, AttribBinding*, const ShaderInterface*); unsigned read_attrib_location(const AttribBinding*, unsigned a_idx); diff --git a/intern/gawain/gawain/shader_interface.h b/intern/gawain/gawain/shader_interface.h index effa4aca90f..32b5098ad80 100644 --- a/intern/gawain/gawain/shader_interface.h +++ b/intern/gawain/gawain/shader_interface.h @@ -48,3 +48,4 @@ void ShaderInterface_discard(ShaderInterface*); const ShaderInput* ShaderInterface_uniform(const ShaderInterface*, const char* name); const ShaderInput* ShaderInterface_builtin_uniform(const ShaderInterface*, BuiltinUniform); +const ShaderInput* ShaderInterface_attrib(const ShaderInterface*, const char* name); diff --git a/intern/gawain/src/attrib_binding.c b/intern/gawain/src/attrib_binding.c index c510de497d8..b174bc04f06 100644 --- a/intern/gawain/src/attrib_binding.c +++ b/intern/gawain/src/attrib_binding.c @@ -46,24 +46,20 @@ static void write_attrib_location(AttribBinding* binding, unsigned a_idx, unsign binding->enabled_bits |= 1 << a_idx; } -void get_attrib_locations(const VertexFormat* format, AttribBinding* binding, GLuint program) +void get_attrib_locations(const VertexFormat* format, AttribBinding* binding, const ShaderInterface* shaderface) { -#if TRUST_NO_ONE - assert(glIsProgram(program)); -#endif - AttribBinding_clear(binding); for (unsigned a_idx = 0; a_idx < format->attrib_ct; ++a_idx) { const Attrib* a = format->attribs + a_idx; - GLint loc = glGetAttribLocation(program, a->name); + const ShaderInput* input = ShaderInterface_attrib(shaderface, a->name); #if TRUST_NO_ONE - assert(loc != -1); + assert(input != NULL); // TODO: make this a recoverable runtime error? indicates mismatch between vertex format and program #endif - write_attrib_location(binding, a_idx, loc); + write_attrib_location(binding, a_idx, input->location); } } diff --git a/intern/gawain/src/batch.c b/intern/gawain/src/batch.c index d4465c7809a..c2aa0f07773 100644 --- a/intern/gawain/src/batch.c +++ b/intern/gawain/src/batch.c @@ -127,23 +127,23 @@ static void Batch_update_program_bindings(Batch* batch) const GLvoid* pointer = (const GLubyte*)0 + a->offset; - const GLint loc = glGetAttribLocation(batch->program, a->name); + const ShaderInput* input = ShaderInterface_attrib(batch->interface, a->name); - if (loc == -1) continue; + if (input == NULL) continue; - glEnableVertexAttribArray(loc); + glEnableVertexAttribArray(input->location); switch (a->fetch_mode) { case KEEP_FLOAT: case CONVERT_INT_TO_FLOAT: - glVertexAttribPointer(loc, a->comp_ct, a->gl_comp_type, GL_FALSE, stride, pointer); + glVertexAttribPointer(input->location, a->comp_ct, a->gl_comp_type, GL_FALSE, stride, pointer); break; case NORMALIZE_INT_TO_FLOAT: - glVertexAttribPointer(loc, a->comp_ct, a->gl_comp_type, GL_TRUE, stride, pointer); + glVertexAttribPointer(input->location, a->comp_ct, a->gl_comp_type, GL_TRUE, stride, pointer); break; case KEEP_INT: - glVertexAttribIPointer(loc, a->comp_ct, a->gl_comp_type, stride, pointer); + glVertexAttribIPointer(input->location, a->comp_ct, a->gl_comp_type, stride, pointer); } } } diff --git a/intern/gawain/src/immediate.c b/intern/gawain/src/immediate.c index 3ec4c8ac79e..95414021091 100644 --- a/intern/gawain/src/immediate.c +++ b/intern/gawain/src/immediate.c @@ -133,7 +133,7 @@ void immBindProgram(GLuint program, const ShaderInterface* shaderface) VertexFormat_pack(&imm.vertex_format); glUseProgram(program); - get_attrib_locations(&imm.vertex_format, &imm.attrib_binding, program); + get_attrib_locations(&imm.vertex_format, &imm.attrib_binding, shaderface); gpuBindMatrices(shaderface); } diff --git a/intern/gawain/src/shader_interface.c b/intern/gawain/src/shader_interface.c index d1f6031c480..5e55ceed992 100644 --- a/intern/gawain/src/shader_interface.c +++ b/intern/gawain/src/shader_interface.c @@ -181,3 +181,21 @@ const ShaderInput* ShaderInterface_builtin_uniform(const ShaderInterface* shader // TODO: look up by enum, not name (fix setup_builtin_uniform first) return ShaderInterface_uniform(shaderface, BuiltinUniform_name(builtin)); } + +const ShaderInput* ShaderInterface_attrib(const ShaderInterface* shaderface, const char* name) + { + // attribs are stored after uniforms + const uint32_t input_ct = shaderface->uniform_ct + shaderface->attrib_ct; + for (uint32_t i = shaderface->uniform_ct; i < input_ct; ++i) + { + const ShaderInput* attrib = shaderface->inputs + i; + +#if SUPPORT_LEGACY_GLSL + if (attrib->name == NULL) continue; +#endif + + if (strcmp(attrib->name, name) == 0) + return attrib; + } + return NULL; // not found + } diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index 2a0e434537f..a3668eb156b 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -632,8 +632,8 @@ void GPU_shader_uniform_texture(GPUShader *UNUSED(shader), int location, GPUText int GPU_shader_get_attribute(GPUShader *shader, const char *name) { BLI_assert(shader && shader->program); - - return glGetAttribLocation(shader->program, name); + const ShaderInput *attrib = ShaderInterface_attrib(shader->interface, name); + return attrib ? attrib->location : -1; } GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)