GPUBatch & GPUImmediate: Use GPUShader instead of using raw OGL handle
This commit is contained in:
parent
3eff2b44db
commit
19175f4757
|
@ -47,6 +47,7 @@
|
|||
|
||||
extern "C" {
|
||||
#include "GPU_immediate.h"
|
||||
#include "GPU_shader.h"
|
||||
}
|
||||
|
||||
using namespace OCIO_NAMESPACE;
|
||||
|
@ -94,18 +95,15 @@ struct OCIO_GLSLCurveMappingParameters {
|
|||
struct OCIO_GLSLShader {
|
||||
/** Cache IDs */
|
||||
std::string cacheId;
|
||||
/** TODO(fclem): Remove. IMM shader interface. */
|
||||
struct GPUShaderInterface *interface;
|
||||
/** OpenGL Shader objects handles. */
|
||||
GLuint frag;
|
||||
GLuint vert;
|
||||
GLuint program;
|
||||
|
||||
struct GPUShader *shader;
|
||||
/** Uniform locations. */
|
||||
GLint dither_loc;
|
||||
GLint overlay_loc;
|
||||
GLint overlay_tex_loc;
|
||||
GLint predivide_loc;
|
||||
GLint curve_mapping_loc;
|
||||
GLint ubo_bind;
|
||||
/** Error checking. */
|
||||
bool valid;
|
||||
};
|
||||
|
@ -152,56 +150,6 @@ static OCIO_GLSLDrawState *allocateOpenGLState(void)
|
|||
/** \name Shader
|
||||
* \{ */
|
||||
|
||||
static GLuint compileShaderText(GLenum shader_type, const char *text)
|
||||
{
|
||||
GLuint shader;
|
||||
GLint stat;
|
||||
|
||||
shader = glCreateShader(shader_type);
|
||||
glShaderSource(shader, 1, (const GLchar **)&text, NULL);
|
||||
glCompileShader(shader);
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &stat);
|
||||
|
||||
if (!stat) {
|
||||
GLchar log[1000];
|
||||
GLsizei len;
|
||||
glGetShaderInfoLog(shader, 1000, &len, log);
|
||||
fprintf(stderr, "Shader compile error:\n%s\n", log);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
static GLuint linkShaders(GLuint frag, GLuint vert)
|
||||
{
|
||||
if (!frag || !vert) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLuint program = glCreateProgram();
|
||||
|
||||
glAttachShader(program, frag);
|
||||
glAttachShader(program, vert);
|
||||
|
||||
glLinkProgram(program);
|
||||
|
||||
/* check link */
|
||||
{
|
||||
GLint stat;
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &stat);
|
||||
if (!stat) {
|
||||
GLchar log[1000];
|
||||
GLsizei len;
|
||||
glGetProgramInfoLog(program, 1000, &len, log);
|
||||
fprintf(stderr, "Shader link error:\n%s\n", log);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
static void updateGLSLShader(OCIO_GLSLShader *shader,
|
||||
ConstProcessorRcPtr *processor_scene_to_ui,
|
||||
ConstProcessorRcPtr *processpr_ui_to_display,
|
||||
|
@ -213,28 +161,14 @@ static void updateGLSLShader(OCIO_GLSLShader *shader,
|
|||
}
|
||||
|
||||
/* Delete any previous shader. */
|
||||
glDeleteProgram(shader->program);
|
||||
glDeleteShader(shader->frag);
|
||||
glDeleteShader(shader->vert);
|
||||
|
||||
if (shader->interface) {
|
||||
GPU_shaderinterface_discard(shader->interface);
|
||||
if (shader->shader) {
|
||||
GPU_shader_free(shader->shader);
|
||||
}
|
||||
|
||||
{
|
||||
/* Vertex shader */
|
||||
std::ostringstream osv;
|
||||
|
||||
osv << "#version 330\n";
|
||||
osv << datatoc_gpu_shader_display_transform_vertex_glsl;
|
||||
|
||||
shader->vert = compileShaderText(GL_VERTEX_SHADER, osv.str().c_str());
|
||||
}
|
||||
std::ostringstream os;
|
||||
{
|
||||
/* Fragment shader */
|
||||
std::ostringstream os;
|
||||
|
||||
os << "#version 330\n";
|
||||
/* Work around OpenColorIO not supporting latest GLSL yet. */
|
||||
os << "#define texture2D texture\n";
|
||||
os << "#define texture3D texture\n";
|
||||
|
@ -246,41 +180,36 @@ static void updateGLSLShader(OCIO_GLSLShader *shader,
|
|||
os << (*processpr_ui_to_display)->getGpuShaderText(*shader_desc) << "\n";
|
||||
|
||||
os << datatoc_gpu_shader_display_transform_glsl;
|
||||
|
||||
shader->frag = compileShaderText(GL_FRAGMENT_SHADER, os.str().c_str());
|
||||
}
|
||||
|
||||
/* shader_Program */
|
||||
if (shader->frag && shader->vert) {
|
||||
shader->program = linkShaders(shader->frag, shader->vert);
|
||||
}
|
||||
shader->shader = GPU_shader_create(datatoc_gpu_shader_display_transform_vertex_glsl,
|
||||
os.str().c_str(),
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
__func__);
|
||||
|
||||
if (shader->program) {
|
||||
shader->dither_loc = glGetUniformLocation(shader->program, "dither");
|
||||
shader->overlay_tex_loc = glGetUniformLocation(shader->program, "overlay_texture");
|
||||
shader->overlay_loc = glGetUniformLocation(shader->program, "overlay");
|
||||
shader->predivide_loc = glGetUniformLocation(shader->program, "predivide");
|
||||
shader->curve_mapping_loc = glGetUniformLocation(shader->program, "curve_mapping");
|
||||
if (shader->shader) {
|
||||
shader->dither_loc = GPU_shader_get_uniform(shader->shader, "dither");
|
||||
shader->overlay_tex_loc = GPU_shader_get_uniform(shader->shader, "overlay_texture");
|
||||
shader->overlay_loc = GPU_shader_get_uniform(shader->shader, "overlay");
|
||||
shader->predivide_loc = GPU_shader_get_uniform(shader->shader, "predivide");
|
||||
shader->curve_mapping_loc = GPU_shader_get_uniform(shader->shader, "curve_mapping");
|
||||
shader->ubo_bind = GPU_shader_get_uniform_block_binding(shader->shader,
|
||||
"OCIO_GLSLCurveMappingParameters");
|
||||
|
||||
glUseProgram(shader->program);
|
||||
|
||||
/* TODO(fclem) Remove this. Make caller always assume viewport space and
|
||||
* specify texco via vertex attribs. */
|
||||
shader->interface = GPU_shaderinterface_create(shader->program);
|
||||
|
||||
/* Set UBO binding location. */
|
||||
GLuint index = glGetUniformBlockIndex(shader->program, "OCIO_GLSLCurveMappingParameters");
|
||||
glUniformBlockBinding(shader->program, index, UBO_BIND_LOC);
|
||||
GPU_shader_bind(shader->shader);
|
||||
|
||||
/* Set texture bind point uniform once. This is saved by the shader. */
|
||||
glUniform1i(glGetUniformLocation(shader->program, "image_texture"), 0);
|
||||
glUniform1i(glGetUniformLocation(shader->program, "lut3d_texture"), 2);
|
||||
glUniform1i(glGetUniformLocation(shader->program, "lut3d_display_texture"), 3);
|
||||
glUniform1i(glGetUniformLocation(shader->program, "curve_mapping_texture"), 4);
|
||||
GPUShader *sh = shader->shader;
|
||||
GPU_shader_uniform_int(sh, GPU_shader_get_uniform(sh, "image_texture"), 0);
|
||||
GPU_shader_uniform_int(sh, GPU_shader_get_uniform(sh, "lut3d_texture"), 2);
|
||||
GPU_shader_uniform_int(sh, GPU_shader_get_uniform(sh, "lut3d_display_texture"), 3);
|
||||
GPU_shader_uniform_int(sh, GPU_shader_get_uniform(sh, "curve_mapping_texture"), 4);
|
||||
}
|
||||
|
||||
shader->cacheId = cache_id;
|
||||
shader->valid = (shader->program != 0);
|
||||
shader->valid = (shader->shader != NULL);
|
||||
}
|
||||
|
||||
static void ensureGLSLShader(OCIO_GLSLShader **shader_ptr,
|
||||
|
@ -302,12 +231,8 @@ static void ensureGLSLShader(OCIO_GLSLShader **shader_ptr,
|
|||
|
||||
static void freeGLSLShader(OCIO_GLSLShader *shader)
|
||||
{
|
||||
glDeleteProgram(shader->program);
|
||||
glDeleteShader(shader->frag);
|
||||
glDeleteShader(shader->vert);
|
||||
|
||||
if (shader->interface) {
|
||||
GPU_shaderinterface_discard(shader->interface);
|
||||
if (shader->shader) {
|
||||
GPU_shader_free(shader->shader);
|
||||
}
|
||||
|
||||
OBJECT_GUARDED_DELETE(shader, OCIO_GLSLShader);
|
||||
|
@ -674,10 +599,10 @@ bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r,
|
|||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
/* Bind UBO. */
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, 0, shader_curvemap->buffer);
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, shader->ubo_bind, shader_curvemap->buffer);
|
||||
|
||||
/* TODO(fclem) remove remains of IMM. */
|
||||
immBindProgram(shader->program, shader->interface);
|
||||
immBindShader(shader->shader);
|
||||
|
||||
/* Bind Shader and set uniforms. */
|
||||
// glUseProgram(shader->program);
|
||||
|
|
|
@ -670,8 +670,7 @@ BLI_INLINE void draw_geometry_bind(DRWShadingGroup *shgroup, GPUBatch *geom)
|
|||
|
||||
DST.batch = geom;
|
||||
|
||||
GPU_batch_program_set_no_use(
|
||||
geom, GPU_shader_get_program(shgroup->shader), GPU_shader_get_interface(shgroup->shader));
|
||||
GPU_batch_set_shader_no_bind(geom, shgroup->shader);
|
||||
|
||||
geom->program_in_use = true; /* XXX hacking #GPUBatch */
|
||||
|
||||
|
|
|
@ -184,8 +184,7 @@ void DRW_draw_cursor(void)
|
|||
|
||||
GPUBatch *cursor_batch = DRW_cache_cursor_get(is_aligned);
|
||||
GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_FLAT_COLOR);
|
||||
GPU_batch_program_set(
|
||||
cursor_batch, GPU_shader_get_program(shader), GPU_shader_get_interface(shader));
|
||||
GPU_batch_set_shader(cursor_batch, shader);
|
||||
|
||||
GPU_batch_draw(cursor_batch);
|
||||
|
||||
|
|
|
@ -1599,7 +1599,7 @@ static void sequencer_draw_display_buffer(const bContext *C,
|
|||
GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
/* Format needs to be created prior to any immBindProgram call.
|
||||
/* Format needs to be created prior to any immBindShader call.
|
||||
* Do it here because OCIO binds it's own shader. */
|
||||
eGPUTextureFormat format;
|
||||
eGPUDataFormat data;
|
||||
|
|
|
@ -127,9 +127,8 @@ int GPU_batch_vertbuf_add_ex(GPUBatch *, GPUVertBuf *, bool own_vbo);
|
|||
|
||||
#define GPU_batch_vertbuf_add(batch, verts) GPU_batch_vertbuf_add_ex(batch, verts, false)
|
||||
|
||||
void GPU_batch_program_set_no_use(GPUBatch *, uint32_t program, const GPUShaderInterface *);
|
||||
void GPU_batch_program_set(GPUBatch *, uint32_t program, const GPUShaderInterface *);
|
||||
void GPU_batch_program_set_shader(GPUBatch *, GPUShader *shader);
|
||||
void GPU_batch_set_shader(GPUBatch *batch, GPUShader *shader);
|
||||
void GPU_batch_set_shader_no_bind(GPUBatch *batch, GPUShader *shader);
|
||||
void GPU_batch_program_set_imm_shader(GPUBatch *batch);
|
||||
void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id);
|
||||
void GPU_batch_program_set_builtin_with_config(GPUBatch *batch,
|
||||
|
|
|
@ -42,7 +42,7 @@ extern "C" {
|
|||
GPUVertFormat *immVertexFormat(void);
|
||||
|
||||
/** Every immBegin must have a program bound first. */
|
||||
void immBindProgram(uint32_t program, const GPUShaderInterface *);
|
||||
void immBindShader(GPUShader *shader);
|
||||
/** Call after your last immEnd, or before binding another program. */
|
||||
void immUnbindProgram(void);
|
||||
|
||||
|
@ -134,7 +134,7 @@ void immUniformColor3ubvAlpha(const unsigned char rgb[3], unsigned char a);
|
|||
void immUniformColor4ubv(const unsigned char rgba[4]);
|
||||
|
||||
/**
|
||||
* Extend #immBindProgram to use Blender’s library of built-in shader programs.
|
||||
* Extend #immBindShader to use Blender’s library of built-in shader programs.
|
||||
* Use #immUnbindProgram() when done.
|
||||
*/
|
||||
void immBindBuiltinProgram(eGPUBuiltinShader shader_id);
|
||||
|
|
|
@ -87,8 +87,6 @@ void GPU_shader_transform_feedback_disable(GPUShader *shader);
|
|||
|
||||
int GPU_shader_get_program(GPUShader *shader);
|
||||
|
||||
void *GPU_shader_get_interface(GPUShader *shader);
|
||||
|
||||
void GPU_shader_set_srgb_uniform(const struct GPUShaderInterface *interface);
|
||||
|
||||
int GPU_shader_get_uniform(GPUShader *shader, const char *name);
|
||||
|
|
|
@ -371,22 +371,20 @@ static GLuint batch_vao_get(GPUBatch *batch)
|
|||
return new_vao;
|
||||
}
|
||||
|
||||
void GPU_batch_program_set_no_use(GPUBatch *batch,
|
||||
uint32_t program,
|
||||
const GPUShaderInterface *shaderface)
|
||||
void GPU_batch_set_shader_no_bind(GPUBatch *batch, GPUShader *shader)
|
||||
{
|
||||
#if TRUST_NO_ONE
|
||||
assert(glIsProgram(program));
|
||||
assert(glIsProgram(shader->program));
|
||||
assert(batch->program_in_use == 0);
|
||||
#endif
|
||||
batch->interface = shaderface;
|
||||
batch->program = program;
|
||||
batch->interface = shader->interface;
|
||||
batch->program = shader->program;
|
||||
batch->vao_id = batch_vao_get(batch);
|
||||
}
|
||||
|
||||
void GPU_batch_program_set(GPUBatch *batch, uint32_t program, const GPUShaderInterface *shaderface)
|
||||
void GPU_batch_set_shader(GPUBatch *batch, GPUShader *shader)
|
||||
{
|
||||
GPU_batch_program_set_no_use(batch, program, shaderface);
|
||||
GPU_batch_set_shader_no_bind(batch, shader);
|
||||
GPU_batch_program_use_begin(batch); /* hack! to make Batch_Uniform* simpler */
|
||||
}
|
||||
|
||||
|
@ -983,17 +981,12 @@ void GPU_draw_list_submit(GPUDrawList *list)
|
|||
/** \name Utilities
|
||||
* \{ */
|
||||
|
||||
void GPU_batch_program_set_shader(GPUBatch *batch, GPUShader *shader)
|
||||
{
|
||||
GPU_batch_program_set(batch, shader->program, shader->interface);
|
||||
}
|
||||
|
||||
void GPU_batch_program_set_builtin_with_config(GPUBatch *batch,
|
||||
eGPUBuiltinShader shader_id,
|
||||
eGPUShaderConfig sh_cfg)
|
||||
{
|
||||
GPUShader *shader = GPU_shader_get_builtin_shader_with_config(shader_id, sh_cfg);
|
||||
GPU_batch_program_set(batch, shader->program, shader->interface);
|
||||
GPU_batch_set_shader(batch, shader);
|
||||
}
|
||||
|
||||
void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id)
|
||||
|
@ -1006,10 +999,7 @@ void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id)
|
|||
* DO NOT DRAW WITH THE BATCH BEFORE CALLING immUnbindProgram. */
|
||||
void GPU_batch_program_set_imm_shader(GPUBatch *batch)
|
||||
{
|
||||
GLuint program;
|
||||
GPUShaderInterface *interface;
|
||||
immGetProgram(&program, &interface);
|
||||
GPU_batch_program_set(batch, program, interface);
|
||||
GPU_batch_set_shader(batch, immGetShader());
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -72,7 +72,7 @@ typedef struct {
|
|||
|
||||
GLuint vao_id;
|
||||
|
||||
GLuint bound_program;
|
||||
GPUShader *bound_program;
|
||||
const GPUShaderInterface *shader_interface;
|
||||
GPUAttrBinding attr_binding;
|
||||
uint16_t prev_enabled_attr_bits; /* <-- only affects this VAO, so we're ok */
|
||||
|
@ -143,48 +143,47 @@ GPUVertFormat *immVertexFormat(void)
|
|||
return &imm.vertex_format;
|
||||
}
|
||||
|
||||
void immBindProgram(GLuint program, const GPUShaderInterface *shaderface)
|
||||
void immBindShader(GPUShader *shader)
|
||||
{
|
||||
#if TRUST_NO_ONE
|
||||
assert(imm.bound_program == 0);
|
||||
assert(glIsProgram(program));
|
||||
assert(imm.bound_program == NULL);
|
||||
assert(glIsProgram(shader->program));
|
||||
#endif
|
||||
|
||||
imm.bound_program = program;
|
||||
imm.shader_interface = shaderface;
|
||||
imm.bound_program = shader;
|
||||
imm.shader_interface = shader->interface;
|
||||
|
||||
if (!imm.vertex_format.packed) {
|
||||
VertexFormat_pack(&imm.vertex_format);
|
||||
}
|
||||
|
||||
glUseProgram(program);
|
||||
get_attr_locations(&imm.vertex_format, &imm.attr_binding, shaderface);
|
||||
GPU_matrix_bind(shaderface);
|
||||
GPU_shader_set_srgb_uniform(shaderface);
|
||||
GPU_shader_bind(shader);
|
||||
get_attr_locations(&imm.vertex_format, &imm.attr_binding, imm.shader_interface);
|
||||
GPU_matrix_bind(imm.shader_interface);
|
||||
GPU_shader_set_srgb_uniform(imm.shader_interface);
|
||||
}
|
||||
|
||||
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
|
||||
{
|
||||
GPUShader *shader = GPU_shader_get_builtin_shader(shader_id);
|
||||
immBindProgram(shader->program, shader->interface);
|
||||
immBindShader(shader);
|
||||
}
|
||||
|
||||
void immUnbindProgram(void)
|
||||
{
|
||||
#if TRUST_NO_ONE
|
||||
assert(imm.bound_program != 0);
|
||||
assert(imm.bound_program != NULL);
|
||||
#endif
|
||||
#if PROGRAM_NO_OPTI
|
||||
glUseProgram(0);
|
||||
#endif
|
||||
imm.bound_program = 0;
|
||||
imm.bound_program = NULL;
|
||||
}
|
||||
|
||||
/* XXX do not use it. Special hack to use OCIO with batch API. */
|
||||
void immGetProgram(GLuint *program, GPUShaderInterface **shaderface)
|
||||
GPUShader *immGetShader(void)
|
||||
{
|
||||
*program = imm.bound_program;
|
||||
*shaderface = (GPUShaderInterface *)imm.shader_interface;
|
||||
return imm.bound_program;
|
||||
}
|
||||
|
||||
#if TRUST_NO_ONE
|
||||
|
@ -423,7 +422,7 @@ void immEnd(void)
|
|||
GPU_vertbuf_data_resize(imm.batch->verts[0], imm.vertex_len);
|
||||
/* TODO: resize only if vertex count is much smaller */
|
||||
}
|
||||
GPU_batch_program_set(imm.batch, imm.bound_program, imm.shader_interface);
|
||||
GPU_batch_set_shader(imm.batch, imm.bound_program);
|
||||
imm.batch->phase = GPU_BATCH_READY_TO_DRAW;
|
||||
imm.batch = NULL; /* don't free, batch belongs to caller */
|
||||
}
|
||||
|
|
|
@ -694,11 +694,6 @@ int GPU_shader_get_attribute(GPUShader *shader, const char *name)
|
|||
/** \name Getters
|
||||
* \{ */
|
||||
|
||||
void *GPU_shader_get_interface(GPUShader *shader)
|
||||
{
|
||||
return shader->interface;
|
||||
}
|
||||
|
||||
/* Clement : Temp */
|
||||
int GPU_shader_get_program(GPUShader *shader)
|
||||
{
|
||||
|
|
|
@ -48,7 +48,7 @@ struct GPUShader {
|
|||
};
|
||||
|
||||
/* XXX do not use it. Special hack to use OCIO with batch API. */
|
||||
void immGetProgram(GLuint *program, GPUShaderInterface **shaderface);
|
||||
GPUShader *immGetShader(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -184,8 +184,7 @@ static PyObject *bpygpu_Batch_program_set(BPyGPUBatch *self, BPyGPUShader *py_sh
|
|||
}
|
||||
|
||||
GPUShader *shader = py_shader->shader;
|
||||
GPU_batch_program_set(
|
||||
self->batch, GPU_shader_get_program(shader), GPU_shader_get_interface(shader));
|
||||
GPU_batch_set_shader(self->batch, shader);
|
||||
|
||||
#ifdef USE_GPU_PY_REFERENCES
|
||||
/* Remove existing user (if any), hold new user. */
|
||||
|
@ -229,9 +228,7 @@ static PyObject *bpygpu_Batch_draw(BPyGPUBatch *self, PyObject *args)
|
|||
}
|
||||
}
|
||||
else if (self->batch->program != GPU_shader_get_program(py_program->shader)) {
|
||||
GPU_batch_program_set(self->batch,
|
||||
GPU_shader_get_program(py_program->shader),
|
||||
GPU_shader_get_interface(py_program->shader));
|
||||
GPU_batch_set_shader(self->batch, py_program->shader);
|
||||
}
|
||||
|
||||
GPU_batch_draw(self->batch);
|
||||
|
|
Loading…
Reference in New Issue