Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorMike Erwin <significant.bit@gmail.com>2017-04-13 01:55:32 +0300
committerMike Erwin <significant.bit@gmail.com>2017-04-13 08:07:51 +0300
commitb02786ae6be71d3b7581b672b7896005f68c8b63 (patch)
tree15e094e9d7f9b3d442f07f76e3dd048ba8a1ecd4 /intern
parent6bfb9b7b5f164b303433d729d1cbe38f1ba44366 (diff)
Gawain: use ShaderInterface to manage uniforms
This eliminates tons of glGetUniformLocation calls from the drawing loop. Vast majority of code can keep making the same function calls. They're just faster now! - Batch_Uniform* - immUniform* - gpuBindMatrices - and others
Diffstat (limited to 'intern')
-rw-r--r--intern/gawain/gawain/batch.h4
-rw-r--r--intern/gawain/gawain/immediate.h3
-rw-r--r--intern/gawain/src/batch.c79
-rw-r--r--intern/gawain/src/immediate.c120
-rw-r--r--intern/opencolorio/ocio_impl_glsl.cc48
5 files changed, 91 insertions, 163 deletions
diff --git a/intern/gawain/gawain/batch.h b/intern/gawain/gawain/batch.h
index 2802dad3db3..9915b0b57f4 100644
--- a/intern/gawain/gawain/batch.h
+++ b/intern/gawain/gawain/batch.h
@@ -13,6 +13,7 @@
#include "vertex_buffer.h"
#include "element.h"
+#include "shader_interface.h"
typedef enum {
READY_TO_FORMAT,
@@ -38,6 +39,7 @@ typedef struct Batch {
// state
GLuint program;
+ const ShaderInterface* interface;
} Batch;
Batch* Batch_create(PrimitiveType, VertexBuffer*, ElementList*);
@@ -48,7 +50,7 @@ void Batch_discard_all(Batch*); // including verts & elem
int Batch_add_VertexBuffer(Batch*, VertexBuffer*);
-void Batch_set_program(Batch*, GLuint program);
+void Batch_set_program(Batch*, GLuint program, const ShaderInterface*);
// Entire batch draws with one shader program, but can be redrawn later with another program.
// Vertex shader's inputs must be compatible with the batch's vertex format.
diff --git a/intern/gawain/gawain/immediate.h b/intern/gawain/gawain/immediate.h
index 62754306abe..b08be688cf4 100644
--- a/intern/gawain/gawain/immediate.h
+++ b/intern/gawain/gawain/immediate.h
@@ -13,13 +13,14 @@
#include "vertex_format.h"
#include "primitive.h"
+#include "shader_interface.h"
#define IMM_BATCH_COMBO 1
VertexFormat* immVertexFormat(void); // returns a cleared vertex format, ready for add_attrib
-void immBindProgram(GLuint program); // every immBegin must have a program bound first
+void immBindProgram(GLuint program, const ShaderInterface*); // every immBegin must have a program bound first
void immUnbindProgram(void); // call after your last immEnd, or before binding another program
void immBegin(PrimitiveType, unsigned vertex_ct); // must supply exactly vertex_ct vertices
diff --git a/intern/gawain/src/batch.c b/intern/gawain/src/batch.c
index 7e904cbd487..5de6335e0bb 100644
--- a/intern/gawain/src/batch.c
+++ b/intern/gawain/src/batch.c
@@ -88,13 +88,14 @@ int Batch_add_VertexBuffer(Batch* batch, VertexBuffer* verts)
return -1;
}
-void Batch_set_program(Batch* batch, GLuint program)
+void Batch_set_program(Batch* batch, GLuint program, const ShaderInterface* shaderface)
{
#if TRUST_NO_ONE
assert(glIsProgram(program));
#endif
batch->program = program;
+ batch->interface = shaderface;
batch->program_dirty = true;
Batch_use_program(batch); // hack! to make Batch_Uniform* simpler
@@ -172,92 +173,58 @@ void Batch_done_using_program(Batch* batch)
}
}
-void Batch_Uniform1i(Batch* batch, const char* name, int value)
- {
- int loc = glGetUniformLocation(batch->program, name);
-
#if TRUST_NO_ONE
- assert(loc != -1);
+ #define GET_UNIFORM const ShaderInput* uniform = ShaderInterface_uniform(batch->interface, name); assert(uniform);
+#else
+ #define GET_UNIFORM const ShaderInput* uniform = ShaderInterface_uniform(batch->interface, name);
#endif
- glUniform1i(loc, value);
+void Batch_Uniform1i(Batch* batch, const char* name, int value)
+ {
+ GET_UNIFORM
+ glUniform1i(uniform->location, value);
}
void Batch_Uniform1b(Batch* batch, const char* name, bool value)
{
- int loc = glGetUniformLocation(batch->program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform1i(loc, value ? GL_TRUE : GL_FALSE);
+ GET_UNIFORM
+ glUniform1i(uniform->location, value ? GL_TRUE : GL_FALSE);
}
void Batch_Uniform2f(Batch* batch, const char* name, float x, float y)
{
- int loc = glGetUniformLocation(batch->program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform2f(loc, x, y);
+ GET_UNIFORM
+ glUniform2f(uniform->location, x, y);
}
void Batch_Uniform3f(Batch* batch, const char* name, float x, float y, float z)
{
- int loc = glGetUniformLocation(batch->program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform3f(loc, x, y, z);
+ GET_UNIFORM
+ glUniform3f(uniform->location, x, y, z);
}
void Batch_Uniform4f(Batch* batch, const char* name, float x, float y, float z, float w)
{
- int loc = glGetUniformLocation(batch->program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform4f(loc, x, y, z, w);
+ GET_UNIFORM
+ glUniform4f(uniform->location, x, y, z, w);
}
void Batch_Uniform1f(Batch* batch, const char* name, float x)
{
- int loc = glGetUniformLocation(batch->program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform1f(loc, x);
+ GET_UNIFORM
+ glUniform1f(uniform->location, x);
}
void Batch_Uniform3fv(Batch* batch, const char* name, const float data[3])
{
- int loc = glGetUniformLocation(batch->program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform3fv(loc, 1, data);
+ GET_UNIFORM
+ glUniform3fv(uniform->location, 1, data);
}
void Batch_Uniform4fv(Batch* batch, const char* name, const float data[4])
{
- int loc = glGetUniformLocation(batch->program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform4fv(loc, 1, data);
+ GET_UNIFORM
+ glUniform4fv(uniform->location, 1, data);
}
static void Batch_prime(Batch* batch)
diff --git a/intern/gawain/src/immediate.c b/intern/gawain/src/immediate.c
index 2fd2d2480a7..f384887a2ad 100644
--- a/intern/gawain/src/immediate.c
+++ b/intern/gawain/src/immediate.c
@@ -15,7 +15,7 @@
#include <string.h>
// necessary functions from matrix API
-extern void gpuBindMatrices(GLuint program);
+extern void gpuBindMatrices(const ShaderInterface*);
extern bool gpuMatricesDirty(void);
typedef struct {
@@ -44,6 +44,7 @@ typedef struct {
GLuint vao_id;
GLuint bound_program;
+ const ShaderInterface* shader_interface;
AttribBinding attrib_binding;
uint16_t prev_enabled_attrib_bits; // <-- only affects this VAO, so we're ok
} Immediate;
@@ -117,21 +118,22 @@ VertexFormat* immVertexFormat(void)
return &imm.vertex_format;
}
-void immBindProgram(GLuint program)
+void immBindProgram(GLuint program, const ShaderInterface* shaderface)
{
#if TRUST_NO_ONE
assert(imm.bound_program == 0);
assert(glIsProgram(program));
#endif
+ imm.bound_program = program;
+ imm.shader_interface = shaderface;
+
if (!imm.vertex_format.packed)
VertexFormat_pack(&imm.vertex_format);
glUseProgram(program);
get_attrib_locations(&imm.vertex_format, &imm.attrib_binding, program);
- imm.bound_program = program;
-
- gpuBindMatrices(program);
+ gpuBindMatrices(shaderface);
}
void immUnbindProgram(void)
@@ -267,7 +269,7 @@ Batch* immBeginBatch(PrimitiveType prim_type, unsigned vertex_ct)
imm.batch = Batch_create(prim_type, verts, NULL);
imm.batch->phase = BUILDING;
- Batch_set_program(imm.batch, imm.bound_program);
+ Batch_set_program(imm.batch, imm.bound_program, imm.shader_interface);
return imm.batch;
}
@@ -336,7 +338,7 @@ static void immDrawSetup(void)
}
if (gpuMatricesDirty())
- gpuBindMatrices(imm.bound_program);
+ gpuBindMatrices(imm.shader_interface);
}
void immEnd(void)
@@ -716,126 +718,76 @@ void immVertex2iv(unsigned attrib_id, const int data[2])
// --- generic uniform functions ---
-void immUniform1f(const char* name, float x)
- {
- int loc = glGetUniformLocation(imm.bound_program, name);
-
#if TRUST_NO_ONE
- assert(loc != -1);
+ #define GET_UNIFORM const ShaderInput* uniform = ShaderInterface_uniform(imm.shader_interface, name); assert(uniform);
+#else
+ #define GET_UNIFORM const ShaderInput* uniform = ShaderInterface_uniform(imm.shader_interface, name);
#endif
- glUniform1f(loc, x);
+void immUniform1f(const char* name, float x)
+ {
+ GET_UNIFORM
+ glUniform1f(uniform->location, x);
}
void immUniform2f(const char* name, float x, float y)
{
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform2f(loc, x, y);
+ GET_UNIFORM
+ glUniform2f(uniform->location, x, y);
}
void immUniform2fv(const char* name, const float data[2])
{
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform2fv(loc, 1, data);
+ GET_UNIFORM
+ glUniform2fv(uniform->location, 1, data);
}
void immUniform3f(const char* name, float x, float y, float z)
{
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform3f(loc, x, y, z);
+ GET_UNIFORM
+ glUniform3f(uniform->location, x, y, z);
}
void immUniform3fv(const char* name, const float data[3])
{
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform3fv(loc, 1, data);
+ GET_UNIFORM
+ glUniform3fv(uniform->location, 1, data);
}
void immUniformArray3fv(const char* name, const float *data, int count)
{
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
- assert(count > 0);
-#endif
-
- glUniform3fv(loc, count, data);
+ GET_UNIFORM
+ glUniform3fv(uniform->location, count, data);
}
void immUniform4f(const char* name, float x, float y, float z, float w)
{
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform4f(loc, x, y, z, w);
+ GET_UNIFORM
+ glUniform4f(uniform->location, x, y, z, w);
}
void immUniform4fv(const char* name, const float data[4])
{
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform4fv(loc, 1, data);
+ GET_UNIFORM
+ glUniform4fv(uniform->location, 1, data);
}
void immUniformMatrix4fv(const char* name, const float data[4][4])
{
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniformMatrix4fv(loc, 1, GL_FALSE, (float *)data);
+ GET_UNIFORM
+ glUniformMatrix4fv(uniform->location, 1, GL_FALSE, (float *)data);
}
void immUniform1i(const char* name, int x)
{
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform1i(loc, x);
+ GET_UNIFORM
+ glUniform1i(uniform->location, x);
}
void immUniform4iv(const char* name, const int data[4])
{
- int loc = glGetUniformLocation(imm.bound_program, name);
-
-#if TRUST_NO_ONE
- assert(loc != -1);
-#endif
-
- glUniform4iv(loc, 1, data);
+ GET_UNIFORM
+ glUniform4iv(uniform->location, 1, data);
}
// --- convenience functions for setting "uniform vec4 color" ---
diff --git a/intern/opencolorio/ocio_impl_glsl.cc b/intern/opencolorio/ocio_impl_glsl.cc
index 819dd6632b3..5d1d170c2cb 100644
--- a/intern/opencolorio/ocio_impl_glsl.cc
+++ b/intern/opencolorio/ocio_impl_glsl.cc
@@ -95,6 +95,7 @@ typedef struct OCIO_GLSLDrawState {
GLuint ocio_shader;
GLuint vert_shader;
GLuint program;
+ ShaderInterface *shader_interface;
/* Previous OpenGL state. */
GLint last_texture, last_texture_unit;
@@ -411,10 +412,12 @@ bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRc
glActiveTexture(GL_TEXTURE0);
- immBindProgram(state->program);
+ state->shader_interface = ShaderInterface_create(state->program);
- glUniform1i(glGetUniformLocation(state->program, "image_texture"), 0);
- glUniform1i(glGetUniformLocation(state->program, "lut3d_texture"), 1);
+ immBindProgram(state->program, state->shader_interface);
+
+ immUniform1i("image_texture", 0);
+ immUniform1i("lut3d_texture", 1);
if (state->texture_size_used) {
/* we use textureSize() if possible for best performance, if not
@@ -424,30 +427,30 @@ bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRc
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
- glUniform1f(glGetUniformLocation(state->program, "image_texture_width"), (float)width);
- glUniform1f(glGetUniformLocation(state->program, "image_texture_height"), (float)height);
+ immUniform1f("image_texture_width", (float)width);
+ immUniform1f("image_texture_height", (float)height);
}
if (use_dither) {
- glUniform1f(glGetUniformLocation(state->program, "dither"), dither);
+ immUniform1f("dither", dither);
}
if (use_curve_mapping) {
- glUniform1i(glGetUniformLocation(state->program, "curve_mapping_texture"), 2);
- glUniform1i(glGetUniformLocation(state->program, "curve_mapping_lut_size"), curve_mapping_settings->lut_size);
- glUniform4iv(glGetUniformLocation(state->program, "use_curve_mapping_extend_extrapolate"), 1, curve_mapping_settings->use_extend_extrapolate);
- glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_mintable"), 1, curve_mapping_settings->mintable);
- glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_range"), 1, curve_mapping_settings->range);
- glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_ext_in_x"), 1, curve_mapping_settings->ext_in_x);
- glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_ext_in_y"), 1, curve_mapping_settings->ext_in_y);
- glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_ext_out_x"), 1, curve_mapping_settings->ext_out_x);
- glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_ext_out_y"), 1, curve_mapping_settings->ext_out_y);
- glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_first_x"), 1, curve_mapping_settings->first_x);
- glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_first_y"), 1, curve_mapping_settings->first_y);
- glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_last_x"), 1, curve_mapping_settings->last_x);
- glUniform4fv(glGetUniformLocation(state->program, "curve_mapping_last_y"), 1, curve_mapping_settings->last_y);
- glUniform3fv(glGetUniformLocation(state->program, "curve_mapping_black"), 1, curve_mapping_settings->black);
- glUniform3fv(glGetUniformLocation(state->program, "curve_mapping_bwmul"), 1, curve_mapping_settings->bwmul);
+ immUniform1i("curve_mapping_texture", 2);
+ immUniform1i("curve_mapping_lut_size", curve_mapping_settings->lut_size);
+ immUniform4iv("use_curve_mapping_extend_extrapolate", curve_mapping_settings->use_extend_extrapolate);
+ immUniform4fv("curve_mapping_mintable", curve_mapping_settings->mintable);
+ immUniform4fv("curve_mapping_range", curve_mapping_settings->range);
+ immUniform4fv("curve_mapping_ext_in_x", curve_mapping_settings->ext_in_x);
+ immUniform4fv("curve_mapping_ext_in_y", curve_mapping_settings->ext_in_y);
+ immUniform4fv("curve_mapping_ext_out_x", curve_mapping_settings->ext_out_x);
+ immUniform4fv("curve_mapping_ext_out_y", curve_mapping_settings->ext_out_y);
+ immUniform4fv("curve_mapping_first_x", curve_mapping_settings->first_x);
+ immUniform4fv("curve_mapping_first_y", curve_mapping_settings->first_y);
+ immUniform4fv("curve_mapping_last_x", curve_mapping_settings->last_x);
+ immUniform4fv("curve_mapping_last_y", curve_mapping_settings->last_y);
+ immUniform3fv("curve_mapping_black", curve_mapping_settings->black);
+ immUniform3fv("curve_mapping_bwmul", curve_mapping_settings->bwmul);
}
return true;
@@ -480,6 +483,9 @@ void OCIOImpl::freeGLState(struct OCIO_GLSLDrawState *state)
if (state->program)
glDeleteProgram(state->program);
+ if (state->shader_interface)
+ ShaderInterface_discard(state->shader_interface);
+
if (state->ocio_shader)
glDeleteShader(state->ocio_shader);