static bool gl_glsl_set_coords(void *handle_data, void *shader_data, const struct video_coords *coords) { /* Avoid hitting malloc on every single regular quad draw. */ GLfloat short_buffer[4 * (2 + 2 + 4 + 2)]; GLfloat *buffer; struct glsl_attrib attribs[4]; size_t attribs_size = 0, size = 0; struct glsl_attrib *attr = NULL; const struct shader_uniforms *uni = NULL; glsl_shader_data_t *glsl = (glsl_shader_data_t*)shader_data; if (!glsl || !glsl->shader->modern || !coords) goto fallback; buffer = short_buffer; if (coords->vertices > 4) buffer = (GLfloat*)calloc(coords->vertices * (2 + 2 + 4 + 2), sizeof(*buffer)); if (!buffer) goto fallback; attr = attribs; uni = &glsl->uniforms[glsl->active_idx]; if (uni->tex_coord >= 0) gl_glsl_set_coord_array(attr, uni->tex_coord, coords->tex_coord, coords, size, 2); if (uni->vertex_coord >= 0) gl_glsl_set_coord_array(attr, uni->vertex_coord, coords->vertex, coords, size, 2); if (uni->color >= 0) gl_glsl_set_coord_array(attr, uni->color, coords->color, coords, size, 4); if (uni->lut_tex_coord >= 0) gl_glsl_set_coord_array(attr, uni->lut_tex_coord, coords->lut_tex_coord, coords, size, 2); if (size) gl_glsl_set_attribs(glsl, glsl->vbo[glsl->active_idx].vbo_primary, &glsl->vbo[glsl->active_idx].buffer_primary, &glsl->vbo[glsl->active_idx].size_primary, buffer, size, attribs, attribs_size); if (buffer != short_buffer) free(buffer); return true; fallback: if (coords) gl_ff_vertex(coords); return false; }
static bool gl_glsl_set_coords(void *handle_data, void *shader_data, const struct video_coords *coords) { GLfloat short_buffer[4 * (2 + 2 + 4 + 2)]; struct glsl_attrib attribs[4]; size_t attribs_size = 0; size_t size = 0; GLfloat *buffer = short_buffer; glsl_shader_data_t *glsl = (glsl_shader_data_t*)shader_data; const struct shader_uniforms *uni = glsl ? &glsl->uniforms[glsl->active_idx] : NULL; if (!glsl || !glsl->shader->modern || !coords) { if (coords) return false; return true; } if (coords->vertices > 4) { /* Avoid hitting malloc on every single regular quad draw. */ size_t elems = 0; elems += (uni->color >= 0) * 4; elems += (uni->tex_coord >= 0) * 2; elems += (uni->vertex_coord >= 0) * 2; elems += (uni->lut_tex_coord >= 0) * 2; elems *= coords->vertices * sizeof(GLfloat); buffer = (GLfloat*)malloc(elems); } if (!buffer) return false; if (uni->tex_coord >= 0) { gl_glsl_set_coord_array(attribs, uni->tex_coord, coords->tex_coord, coords, size, 2); attribs_size++; } if (uni->vertex_coord >= 0) { gl_glsl_set_coord_array(attribs, uni->vertex_coord, coords->vertex, coords, size, 2); attribs_size++; } if (uni->color >= 0) { gl_glsl_set_coord_array(attribs, uni->color, coords->color, coords, size, 4); attribs_size++; } if (uni->lut_tex_coord >= 0) { gl_glsl_set_coord_array(attribs, uni->lut_tex_coord, coords->lut_tex_coord, coords, size, 2); attribs_size++; } if (size) gl_glsl_set_attribs(glsl, glsl->vbo[glsl->active_idx].vbo_primary, &glsl->vbo[glsl->active_idx].buffer_primary, &glsl->vbo[glsl->active_idx].size_primary, buffer, size, attribs, attribs_size); if (buffer != short_buffer) free(buffer); return true; }
static void gl_glsl_set_params(void *data, void *shader_data, unsigned width, unsigned height, unsigned tex_width, unsigned tex_height, unsigned out_width, unsigned out_height, unsigned frame_count, const void *_info, const void *_prev_info, const void *_feedback_info, const void *_fbo_info, unsigned fbo_info_cnt) { unsigned i; GLfloat buffer[512]; struct glsl_attrib attribs[32]; float input_size[2], output_size[2], texture_size[2]; unsigned texunit = 1; const struct shader_uniforms *uni = NULL; size_t size = 0; size_t attribs_size = 0; const struct video_tex_info *info = (const struct video_tex_info*)_info; const struct video_tex_info *prev_info = (const struct video_tex_info*)_prev_info; const struct video_tex_info *feedback_info = (const struct video_tex_info*)_feedback_info; const struct video_tex_info *fbo_info = (const struct video_tex_info*)_fbo_info; struct glsl_attrib *attr = (struct glsl_attrib*)attribs; glsl_shader_data_t *glsl = (glsl_shader_data_t*)shader_data; if (!glsl) return; uni = (const struct shader_uniforms*)&glsl->uniforms[glsl->active_idx]; if (glsl->prg[glsl->active_idx].id == 0) return; input_size [0] = (float)width; input_size [1] = (float)height; output_size[0] = (float)out_width; output_size[1] = (float)out_height; texture_size[0] = (float)tex_width; texture_size[1] = (float)tex_height; if (uni->input_size >= 0) glUniform2fv(uni->input_size, 1, input_size); if (uni->output_size >= 0) glUniform2fv(uni->output_size, 1, output_size); if (uni->texture_size >= 0) glUniform2fv(uni->texture_size, 1, texture_size); if (uni->frame_count >= 0 && glsl->active_idx) { unsigned modulo = glsl->shader->pass[glsl->active_idx - 1].frame_count_mod; if (modulo) frame_count %= modulo; glUniform1i(uni->frame_count, frame_count); } if (uni->frame_direction >= 0) glUniform1i(uni->frame_direction, state_manager_frame_is_reversed() ? -1 : 1); /* Set lookup textures. */ for (i = 0; i < glsl->shader->luts; i++) { if (uni->lut_texture[i] < 0) continue; /* Have to rebind as HW render could override this. */ glActiveTexture(GL_TEXTURE0 + texunit); glBindTexture(GL_TEXTURE_2D, glsl->lut_textures[i]); glUniform1i(uni->lut_texture[i], texunit); texunit++; } if (glsl->active_idx) { /* Set original texture. */ if (uni->orig.texture >= 0) { /* Bind original texture. */ glActiveTexture(GL_TEXTURE0 + texunit); glUniform1i(uni->orig.texture, texunit); glBindTexture(GL_TEXTURE_2D, info->tex); texunit++; } if (uni->orig.texture_size >= 0) glUniform2fv(uni->orig.texture_size, 1, info->tex_size); if (uni->orig.input_size >= 0) glUniform2fv(uni->orig.input_size, 1, info->input_size); /* Pass texture coordinates. */ if (uni->orig.tex_coord >= 0) { attr->loc = uni->orig.tex_coord; attr->size = 2; attr->offset = (GLsizei)(size * sizeof(GLfloat)); attribs_size++; attr++; buffer[size ] = info->coord[0]; buffer[size + 1] = info->coord[1]; buffer[size + 2] = info->coord[2]; buffer[size + 3] = info->coord[3]; buffer[size + 4] = info->coord[4]; buffer[size + 5] = info->coord[5]; buffer[size + 6] = info->coord[6]; buffer[size + 7] = info->coord[7]; size += 8; } /* Set feedback texture. */ if (uni->feedback.texture >= 0) { /* Bind original texture. */ glActiveTexture(GL_TEXTURE0 + texunit); glUniform1i(uni->feedback.texture, texunit); glBindTexture(GL_TEXTURE_2D, feedback_info->tex); texunit++; } if (uni->feedback.texture_size >= 0) glUniform2fv(uni->feedback.texture_size, 1, feedback_info->tex_size); if (uni->feedback.input_size >= 0) glUniform2fv(uni->feedback.input_size, 1, feedback_info->input_size); /* Pass texture coordinates. */ if (uni->feedback.tex_coord >= 0) { attr->loc = uni->feedback.tex_coord; attr->size = 2; attr->offset = (GLsizei)(size * sizeof(GLfloat)); attribs_size++; attr++; buffer[size ] = feedback_info->coord[0]; buffer[size + 1] = feedback_info->coord[1]; buffer[size + 2] = feedback_info->coord[2]; buffer[size + 3] = feedback_info->coord[3]; buffer[size + 4] = feedback_info->coord[4]; buffer[size + 5] = feedback_info->coord[5]; buffer[size + 6] = feedback_info->coord[6]; buffer[size + 7] = feedback_info->coord[7]; size += 8; } /* Bind FBO textures. */ for (i = 0; i < fbo_info_cnt; i++) { if (uni->pass[i].texture) { glActiveTexture(GL_TEXTURE0 + texunit); glBindTexture(GL_TEXTURE_2D, fbo_info[i].tex); glUniform1i(uni->pass[i].texture, texunit); texunit++; } if (uni->pass[i].texture_size >= 0) glUniform2fv(uni->pass[i].texture_size, 1, fbo_info[i].tex_size); if (uni->pass[i].input_size >= 0) glUniform2fv(uni->pass[i].input_size, 1, fbo_info[i].input_size); if (uni->pass[i].tex_coord >= 0) { attr->loc = uni->pass[i].tex_coord; attr->size = 2; attr->offset = (GLsizei)(size * sizeof(GLfloat)); attribs_size++; attr++; buffer[size ] = fbo_info[i].coord[0]; buffer[size + 1] = fbo_info[i].coord[1]; buffer[size + 2] = fbo_info[i].coord[2]; buffer[size + 3] = fbo_info[i].coord[3]; buffer[size + 4] = fbo_info[i].coord[4]; buffer[size + 5] = fbo_info[i].coord[5]; buffer[size + 6] = fbo_info[i].coord[6]; buffer[size + 7] = fbo_info[i].coord[7]; size += 8; } } } /* Set previous textures. Only bind if they're actually used. */ for (i = 0; i < PREV_TEXTURES; i++) { if (uni->prev[i].texture >= 0) { glActiveTexture(GL_TEXTURE0 + texunit); glBindTexture(GL_TEXTURE_2D, prev_info[i].tex); glUniform1i(uni->prev[i].texture, texunit); texunit++; } if (uni->prev[i].texture_size >= 0) glUniform2fv(uni->prev[i].texture_size, 1, prev_info[i].tex_size); if (uni->prev[i].input_size >= 0) glUniform2fv(uni->prev[i].input_size, 1, prev_info[i].input_size); /* Pass texture coordinates. */ if (uni->prev[i].tex_coord >= 0) { attr->loc = uni->prev[i].tex_coord; attr->size = 2; attr->offset = (GLsizei)(size * sizeof(GLfloat)); attribs_size++; attr++; buffer[size ] = prev_info[i].coord[0]; buffer[size + 1] = prev_info[i].coord[1]; buffer[size + 2] = prev_info[i].coord[2]; buffer[size + 3] = prev_info[i].coord[3]; buffer[size + 4] = prev_info[i].coord[4]; buffer[size + 5] = prev_info[i].coord[5]; buffer[size + 6] = prev_info[i].coord[6]; buffer[size + 7] = prev_info[i].coord[7]; size += 8; } } if (size) gl_glsl_set_attribs(glsl, glsl->vbo[glsl->active_idx].vbo_secondary, &glsl->vbo[glsl->active_idx].buffer_secondary, &glsl->vbo[glsl->active_idx].size_secondary, buffer, size, attribs, attribs_size); glActiveTexture(GL_TEXTURE0); /* #pragma parameters. */ for (i = 0; i < glsl->shader->num_parameters; i++) { int location = glGetUniformLocation( glsl->prg[glsl->active_idx].id, glsl->shader->parameters[i].id); glUniform1f(location, glsl->shader->parameters[i].current); } /* Set state parameters. */ if (glsl->state_tracker) { static struct state_tracker_uniform state_info[GFX_MAX_VARIABLES]; static unsigned cnt = 0; if (glsl->active_idx == 1) cnt = state_tracker_get_uniform(glsl->state_tracker, state_info, GFX_MAX_VARIABLES, frame_count); for (i = 0; i < cnt; i++) { int location = glGetUniformLocation( glsl->prg[glsl->active_idx].id, state_info[i].id); glUniform1f(location, state_info[i].value); } } }
static void gl_glsl_set_params(void *data, unsigned width, unsigned height, unsigned tex_width, unsigned tex_height, unsigned out_width, unsigned out_height, unsigned frame_count, const struct gl_tex_info *info, const struct gl_tex_info *prev_info, const struct gl_tex_info *fbo_info, unsigned fbo_info_cnt) { (void)data; // We enforce a certain layout for our various texture types in the texunits. // - Regular frame (Texture) (always bound). // - LUT textures (always bound). // - Original texture (always bound if meaningful). // - FBO textures (always bound if available). // - Previous textures. if (!glsl_enable || (gl_program[active_index] == 0)) return; GLfloat buffer[128]; unsigned i; size_t size = 0; struct glsl_attrib attribs[32]; size_t attribs_size = 0; struct glsl_attrib *attr = attribs; const struct shader_uniforms *uni = &gl_uniforms[active_index]; float input_size[2] = {(float)width, (float)height}; float output_size[2] = {(float)out_width, (float)out_height}; float texture_size[2] = {(float)tex_width, (float)tex_height}; if (uni->input_size >= 0) glUniform2fv(uni->input_size, 1, input_size); if (uni->output_size >= 0) glUniform2fv(uni->output_size, 1, output_size); if (uni->texture_size >= 0) glUniform2fv(uni->texture_size, 1, texture_size); if (uni->frame_count >= 0 && active_index) { unsigned modulo = glsl_shader->pass[active_index - 1].frame_count_mod; if (modulo) frame_count %= modulo; glUniform1i(uni->frame_count, frame_count); } if (uni->frame_direction >= 0) glUniform1i(uni->frame_direction, g_extern.frame_is_reverse ? -1 : 1); for (i = 0; i < glsl_shader->luts; i++) { if (uni->lut_texture[i] >= 0) { // Have to rebind as HW render could override this. glActiveTexture(GL_TEXTURE0 + i + 1); glBindTexture(GL_TEXTURE_2D, gl_teximage[i]); glUniform1i(uni->lut_texture[i], i + 1); } } unsigned texunit = glsl_shader->luts + 1; // Set original texture unless we're in first pass (pointless). if (active_index > 1) { if (uni->orig.texture >= 0) { // Bind original texture. glActiveTexture(GL_TEXTURE0 + texunit); glUniform1i(uni->orig.texture, texunit); glBindTexture(GL_TEXTURE_2D, info->tex); } texunit++; if (uni->orig.texture_size >= 0) glUniform2fv(uni->orig.texture_size, 1, info->tex_size); if (uni->orig.input_size >= 0) glUniform2fv(uni->orig.input_size, 1, info->input_size); // Pass texture coordinates. if (uni->orig.tex_coord >= 0) { attr->loc = uni->orig.tex_coord; attr->size = 2; attr->offset = size * sizeof(GLfloat); attribs_size++; attr++; memcpy(buffer + size, info->coord, 8 * sizeof(GLfloat)); size += 8; } // Bind new texture in the chain. if (fbo_info_cnt > 0) { glActiveTexture(GL_TEXTURE0 + texunit + fbo_info_cnt - 1); glBindTexture(GL_TEXTURE_2D, fbo_info[fbo_info_cnt - 1].tex); } // Bind FBO textures. for (i = 0; i < fbo_info_cnt; i++) { if (uni->pass[i].texture) glUniform1i(uni->pass[i].texture, texunit); texunit++; if (uni->pass[i].texture_size >= 0) glUniform2fv(uni->pass[i].texture_size, 1, fbo_info[i].tex_size); if (uni->pass[i].input_size >= 0) glUniform2fv(uni->pass[i].input_size, 1, fbo_info[i].input_size); if (uni->pass[i].tex_coord >= 0) { attr->loc = uni->pass[i].tex_coord; attr->size = 2; attr->offset = size * sizeof(GLfloat); attribs_size++; attr++; memcpy(buffer + size, fbo_info[i].coord, 8 * sizeof(GLfloat)); size += 8; } } } else { // First pass, so unbind everything to avoid collitions. // Unbind ORIG. glActiveTexture(GL_TEXTURE0 + texunit); glBindTexture(GL_TEXTURE_2D, 0); GLuint base_tex = texunit + 1; // Unbind any lurking FBO passes. // Rendering to a texture that is bound to a texture unit // sounds very shaky ... ;) for (i = 0; i < glsl_shader->passes; i++) { glActiveTexture(GL_TEXTURE0 + base_tex + i); glBindTexture(GL_TEXTURE_2D, 0); } } // Set previous textures. Only bind if they're actually used. for (i = 0; i < PREV_TEXTURES; i++) { if (uni->prev[i].texture >= 0) { glActiveTexture(GL_TEXTURE0 + texunit); glBindTexture(GL_TEXTURE_2D, prev_info[i].tex); glUniform1i(uni->prev[i].texture, texunit++); } texunit++; if (uni->prev[i].texture_size >= 0) glUniform2fv(uni->prev[i].texture_size, 1, prev_info[i].tex_size); if (uni->prev[i].input_size >= 0) glUniform2fv(uni->prev[i].input_size, 1, prev_info[i].input_size); // Pass texture coordinates. if (uni->prev[i].tex_coord >= 0) { attr->loc = uni->prev[i].tex_coord; attr->size = 2; attr->offset = size * sizeof(GLfloat); attribs_size++; attr++; memcpy(buffer + size, prev_info[i].coord, 8 * sizeof(GLfloat)); size += 8; } } if (size) { gl_glsl_set_attribs(glsl_vbo[active_index].vbo_secondary, glsl_vbo[active_index].buffer_secondary, &glsl_vbo[active_index].size_secondary, buffer, size, attribs, attribs_size); } glActiveTexture(GL_TEXTURE0); if (gl_state_tracker) { static struct state_tracker_uniform info[GFX_MAX_VARIABLES]; static unsigned cnt = 0; if (active_index == 1) cnt = state_get_uniform(gl_state_tracker, info, GFX_MAX_VARIABLES, frame_count); for (i = 0; i < cnt; i++) { int location = glGetUniformLocation(gl_program[active_index], info[i].id); glUniform1f(location, info[i].value); } } }
static bool gl_glsl_set_coords(const struct gl_coords *coords) { if (!glsl_enable || !glsl_shader->modern) return false; GLfloat buffer[128]; size_t size = 0; struct glsl_attrib attribs[4]; size_t attribs_size = 0; struct glsl_attrib *attr = attribs; const struct shader_uniforms *uni = &gl_uniforms[active_index]; if (uni->tex_coord >= 0) { attr->loc = uni->tex_coord; attr->size = 2; attr->offset = size * sizeof(GLfloat); attribs_size++; attr++; memcpy(buffer + size, coords->tex_coord, 8 * sizeof(GLfloat)); size += 8; } if (uni->vertex_coord >= 0) { attr->loc = uni->vertex_coord; attr->size = 2; attr->offset = size * sizeof(GLfloat); attribs_size++; attr++; memcpy(buffer + size, coords->vertex, 8 * sizeof(GLfloat)); size += 8; } if (uni->color >= 0) { attr->loc = uni->color; attr->size = 4; attr->offset = size * sizeof(GLfloat); attribs_size++; attr++; memcpy(buffer + size, coords->color, 16 * sizeof(GLfloat)); size += 16; } if (uni->lut_tex_coord >= 0) { attr->loc = uni->lut_tex_coord; attr->size = 2; attr->offset = size * sizeof(GLfloat); attribs_size++; attr++; memcpy(buffer + size, coords->lut_tex_coord, 8 * sizeof(GLfloat)); size += 8; } if (size) { gl_glsl_set_attribs(glsl_vbo[active_index].vbo_primary, glsl_vbo[active_index].buffer_primary, &glsl_vbo[active_index].size_primary, buffer, size, attribs, attribs_size); } return true; }
static bool gl_glsl_set_coords(const void *data) { /* Avoid hitting malloc on every single regular quad draw. */ GLfloat short_buffer[4 * (2 + 2 + 4 + 2)]; GLfloat *buffer; struct glsl_attrib attribs[4]; size_t attribs_size = 0, size = 0; struct glsl_attrib *attr = NULL; const struct shader_uniforms *uni = NULL; const struct gfx_coords *coords = (const struct gfx_coords*)data; driver_t *driver = driver_get_ptr(); glsl_shader_data_t *glsl = (glsl_shader_data_t*)driver->video_shader_data; if (!glsl || !glsl->shader->modern || !coords) { gl_ff_vertex(coords); return false; } buffer = short_buffer; if (coords->vertices > 4) buffer = (GLfloat*)calloc(coords->vertices * (2 + 2 + 4 + 2), sizeof(*buffer)); if (!buffer) { gl_ff_vertex(coords); return false; } attr = attribs; uni = &glsl->gl_uniforms[glsl->glsl_active_index]; if (uni->tex_coord >= 0) { attr->loc = uni->tex_coord; attr->size = 2; attr->offset = size * sizeof(GLfloat); attribs_size++; attr++; memcpy(buffer + size, coords->tex_coord, 2 * coords->vertices * sizeof(GLfloat)); size += 2 * coords->vertices; } if (uni->vertex_coord >= 0) { attr->loc = uni->vertex_coord; attr->size = 2; attr->offset = size * sizeof(GLfloat); attribs_size++; attr++; memcpy(buffer + size, coords->vertex, 2 * coords->vertices * sizeof(GLfloat)); size += 2 * coords->vertices; } if (uni->color >= 0) { attr->loc = uni->color; attr->size = 4; attr->offset = size * sizeof(GLfloat); attribs_size++; attr++; memcpy(buffer + size, coords->color, 4 * coords->vertices * sizeof(GLfloat)); size += 4 * coords->vertices; } if (uni->lut_tex_coord >= 0) { attr->loc = uni->lut_tex_coord; attr->size = 2; attr->offset = size * sizeof(GLfloat); attribs_size++; attr++; memcpy(buffer + size, coords->lut_tex_coord, 2 * coords->vertices * sizeof(GLfloat)); size += 2 * coords->vertices; } if (size) { gl_glsl_set_attribs(glsl, glsl->glsl_vbo[glsl->glsl_active_index].vbo_primary, &glsl->glsl_vbo[glsl->glsl_active_index].buffer_primary, &glsl->glsl_vbo[glsl->glsl_active_index].size_primary, buffer, size, attribs, attribs_size); } if (buffer != short_buffer) free(buffer); return true; }
static void gl_glsl_set_params(void *data, void *shader_data, unsigned width, unsigned height, unsigned tex_width, unsigned tex_height, unsigned out_width, unsigned out_height, unsigned frame_count, const void *_info, const void *_prev_info, const void *_feedback_info, const void *_fbo_info, unsigned fbo_info_cnt) { unsigned i; struct uniform_info uniform_params[10] = {{0}}; GLfloat buffer[512]; struct glsl_attrib attribs[32]; float input_size[2], output_size[2], texture_size[2]; unsigned uniform_count = 0; unsigned texunit = 1; const struct shader_uniforms *uni = NULL; size_t size = 0, attribs_size = 0; const struct gfx_tex_info *info = (const struct gfx_tex_info*)_info; const struct gfx_tex_info *prev_info = (const struct gfx_tex_info*)_prev_info; const struct gfx_tex_info *feedback_info = (const struct gfx_tex_info*)_feedback_info; const struct gfx_tex_info *fbo_info = (const struct gfx_tex_info*)_fbo_info; struct glsl_attrib *attr = (struct glsl_attrib*)attribs; glsl_shader_data_t *glsl = (glsl_shader_data_t*)shader_data; if (!glsl) return; uni = (const struct shader_uniforms*)&glsl->uniforms[glsl->active_idx]; if (glsl->prg[glsl->active_idx].id == 0) return; input_size [0] = (float)width; input_size [1] = (float)height; output_size[0] = (float)out_width; output_size[1] = (float)out_height; texture_size[0] = (float)tex_width; texture_size[1] = (float)tex_height; uniform_params[0].enabled = false; uniform_params[0].location = uni->input_size; uniform_params[0].type = UNIFORM_2FV; uniform_params[0].result.floatv = input_size; if (uni->input_size >= 0) uniform_params[0].enabled = true; uniform_params[1].enabled = false; uniform_params[1].location = uni->output_size; uniform_params[1].type = UNIFORM_2FV; uniform_params[1].result.floatv = output_size; if (uni->output_size >= 0) uniform_params[1].enabled = true; uniform_params[2].enabled = false; uniform_params[2].location = uni->texture_size; uniform_params[2].type = UNIFORM_2FV; uniform_params[2].result.floatv = texture_size; if (uni->texture_size >= 0) uniform_params[2].enabled = true; uniform_count += 3; if (uni->frame_count >= 0 && glsl->active_idx) { unsigned modulo = glsl->shader->pass[glsl->active_idx - 1].frame_count_mod; if (modulo) frame_count %= modulo; uniform_params[uniform_count].enabled = true; uniform_params[uniform_count].location = uni->frame_count; uniform_params[uniform_count].type = UNIFORM_1I; uniform_params[uniform_count].result.integer.v0 = frame_count; uniform_count++; } uniform_params[uniform_count].enabled = true; uniform_params[uniform_count].location = uni->frame_direction; uniform_params[uniform_count].type = UNIFORM_1I; uniform_params[uniform_count].result.integer.v0 = state_manager_frame_is_reversed() ? -1 : 1; uniform_count++; for (i = 0; i < uniform_count; i++) gl_glsl_set_uniform_parameter(glsl, &uniform_params[i], NULL); /* Set lookup textures. */ for (i = 0; i < glsl->shader->luts; i++) { struct uniform_info lut_uniform = {0}; if (uni->lut_texture[i] < 0) continue; /* Have to rebind as HW render could override this. */ glActiveTexture(GL_TEXTURE0 + texunit); glBindTexture(GL_TEXTURE_2D, glsl->lut_textures[i]); lut_uniform.enabled = true; lut_uniform.location = uni->lut_texture[i]; lut_uniform.type = UNIFORM_1I; lut_uniform.result.integer.v0 = texunit; gl_glsl_set_uniform_parameter(glsl, &lut_uniform, NULL); texunit++; } if (glsl->active_idx) { unsigned j; struct uniform_info orig_uniforms[2] = {{0}}; struct uniform_info feedback_uniforms[2] = {{0}}; /* Set original texture. */ if (uni->orig.texture >= 0) { struct uniform_info orig_tex_uniform = {0}; /* Bind original texture. */ glActiveTexture(GL_TEXTURE0 + texunit); orig_tex_uniform.enabled = true; orig_tex_uniform.location = uni->orig.texture; orig_tex_uniform.type = UNIFORM_1I; orig_tex_uniform.result.integer.v0 = texunit; gl_glsl_set_uniform_parameter(glsl, &orig_tex_uniform, NULL); glBindTexture(GL_TEXTURE_2D, info->tex); texunit++; } orig_uniforms[0].enabled = false; orig_uniforms[0].location = uni->orig.texture_size; orig_uniforms[0].type = UNIFORM_2FV; orig_uniforms[0].result.floatv = (float*)info->tex_size; if (uni->orig.texture_size >= 0) orig_uniforms[0].enabled = true; orig_uniforms[1].enabled = false; orig_uniforms[1].location = uni->orig.input_size; orig_uniforms[1].type = UNIFORM_2FV; orig_uniforms[1].result.floatv = (float*)info->input_size; if (uni->orig.input_size >= 0) orig_uniforms[1].enabled = true; for (j = 0; j < 2; j++) gl_glsl_set_uniform_parameter(glsl, &orig_uniforms[j], NULL); /* Pass texture coordinates. */ if (uni->orig.tex_coord >= 0) { attr->loc = uni->orig.tex_coord; attr->size = 2; attr->offset = size * sizeof(GLfloat); attribs_size++; attr++; memcpy(buffer + size, info->coord, 8 * sizeof(GLfloat)); size += 8; } /* Set feedback texture. */ if (uni->feedback.texture >= 0) { struct uniform_info feedback_texture_param = {0}; /* Bind original texture. */ glActiveTexture(GL_TEXTURE0 + texunit); feedback_texture_param.enabled = true; feedback_texture_param.location = uni->pass[i].texture; feedback_texture_param.type = UNIFORM_1I; feedback_texture_param.result.integer.v0 = texunit; gl_glsl_set_uniform_parameter(glsl, &feedback_texture_param, NULL); glBindTexture(GL_TEXTURE_2D, feedback_info->tex); texunit++; } feedback_uniforms[0].enabled = false; feedback_uniforms[0].location = uni->feedback.texture_size; feedback_uniforms[0].type = UNIFORM_2FV; feedback_uniforms[0].result.floatv = (float*)feedback_info->tex_size; if (uni->feedback.texture_size >= 0) feedback_uniforms[0].enabled = true; feedback_uniforms[1].enabled = false; feedback_uniforms[1].location = uni->feedback.input_size; feedback_uniforms[1].type = UNIFORM_2FV; feedback_uniforms[1].result.floatv = (float*)feedback_info->input_size; if (uni->feedback.input_size >= 0) feedback_uniforms[1].enabled = true; for (j = 0; j < 2; j++) gl_glsl_set_uniform_parameter(glsl, &feedback_uniforms[j], NULL); /* Pass texture coordinates. */ if (uni->feedback.tex_coord >= 0) { attr->loc = uni->feedback.tex_coord; attr->size = 2; attr->offset = size * sizeof(GLfloat); attribs_size++; attr++; memcpy(buffer + size, feedback_info->coord, 8 * sizeof(GLfloat)); size += 8; } /* Bind FBO textures. */ for (i = 0; i < fbo_info_cnt; i++) { unsigned j; struct uniform_info fbo_tex_params[3] = {{0}}; if (uni->pass[i].texture) { glActiveTexture(GL_TEXTURE0 + texunit); glBindTexture(GL_TEXTURE_2D, fbo_info[i].tex); fbo_tex_params[0].enabled = true; fbo_tex_params[0].location = uni->pass[i].texture; fbo_tex_params[0].type = UNIFORM_1I; fbo_tex_params[0].result.integer.v0 = texunit; texunit++; } fbo_tex_params[1].enabled = false; fbo_tex_params[1].location = uni->pass[i].texture_size; fbo_tex_params[1].type = UNIFORM_2FV; fbo_tex_params[1].result.floatv = (float*)fbo_info[i].tex_size; if (uni->pass[i].texture_size >= 0) fbo_tex_params[1].enabled = true; fbo_tex_params[2].enabled = false; fbo_tex_params[2].location = uni->pass[i].input_size; fbo_tex_params[2].type = UNIFORM_2FV; fbo_tex_params[2].result.floatv = (float*)fbo_info[i].input_size; if (uni->pass[i].input_size >= 0) fbo_tex_params[2].enabled = true; for (j = 0; j < 3; j++) gl_glsl_set_uniform_parameter(glsl, &fbo_tex_params[j], NULL); if (uni->pass[i].tex_coord >= 0) { attr->loc = uni->pass[i].tex_coord; attr->size = 2; attr->offset = size * sizeof(GLfloat); attribs_size++; attr++; memcpy(buffer + size, fbo_info[i].coord, 8 * sizeof(GLfloat)); size += 8; } } } /* Set previous textures. Only bind if they're actually used. */ for (i = 0; i < PREV_TEXTURES; i++) { unsigned j; struct uniform_info prev_tex_params[3] = {{0}}; if (uni->prev[i].texture >= 0) { glActiveTexture(GL_TEXTURE0 + texunit); glBindTexture(GL_TEXTURE_2D, prev_info[i].tex); prev_tex_params[0].enabled = true; prev_tex_params[0].location = uni->prev[i].texture; prev_tex_params[0].type = UNIFORM_1I; prev_tex_params[0].result.integer.v0 = texunit; texunit++; } prev_tex_params[1].enabled = false; prev_tex_params[1].location = uni->prev[i].texture_size; prev_tex_params[1].type = UNIFORM_2FV; prev_tex_params[1].result.floatv = (float*)prev_info[i].tex_size; if (uni->prev[i].texture_size >= 0) prev_tex_params[1].enabled = true; prev_tex_params[2].enabled = false; prev_tex_params[2].location = uni->prev[i].input_size; prev_tex_params[2].type = UNIFORM_2FV; prev_tex_params[2].result.floatv = (float*)prev_info[i].input_size; if (uni->prev[i].input_size >= 0) prev_tex_params[2].enabled = true; for (j = 0; j < 3; j++) gl_glsl_set_uniform_parameter(glsl, &prev_tex_params[j], NULL); /* Pass texture coordinates. */ if (uni->prev[i].tex_coord >= 0) { attr->loc = uni->prev[i].tex_coord; attr->size = 2; attr->offset = size * sizeof(GLfloat); attribs_size++; attr++; memcpy(buffer + size, prev_info[i].coord, 8 * sizeof(GLfloat)); size += 8; } } if (size) gl_glsl_set_attribs(glsl, glsl->vbo[glsl->active_idx].vbo_secondary, &glsl->vbo[glsl->active_idx].buffer_secondary, &glsl->vbo[glsl->active_idx].size_secondary, buffer, size, attribs, attribs_size); glActiveTexture(GL_TEXTURE0); /* #pragma parameters. */ for (i = 0; i < glsl->shader->num_parameters; i++) { struct uniform_info pragma_param = {0}; pragma_param.lookup.enable = true; pragma_param.lookup.idx = glsl->active_idx; pragma_param.lookup.ident = glsl->shader->parameters[i].id; pragma_param.lookup.type = SHADER_PROGRAM_COMBINED; pragma_param.enabled = true; pragma_param.type = UNIFORM_1F; pragma_param.result.f.v0 = glsl->shader->parameters[i].current; gl_glsl_set_uniform_parameter(glsl, &pragma_param, NULL); } /* Set state parameters. */ if (glsl->state_tracker) { static struct state_tracker_uniform state_info[GFX_MAX_VARIABLES]; static unsigned cnt = 0; if (glsl->active_idx == 1) cnt = state_tracker_get_uniform(glsl->state_tracker, state_info, GFX_MAX_VARIABLES, frame_count); for (i = 0; i < cnt; i++) { struct uniform_info state_param = {0}; state_param.lookup.enable = true; state_param.lookup.idx = glsl->active_idx; state_param.lookup.ident = state_info[i].id; state_param.lookup.type = SHADER_PROGRAM_COMBINED; state_param.enabled = true; state_param.type = UNIFORM_1F; state_param.result.f.v0 = state_info[i].value; gl_glsl_set_uniform_parameter(glsl, &state_param, NULL); } } }
static void gl_glsl_set_params(void *data, unsigned width, unsigned height, unsigned tex_width, unsigned tex_height, unsigned out_width, unsigned out_height, unsigned frame_count, const void *_info, const void *_prev_info, const void *_fbo_info, unsigned fbo_info_cnt) { GLfloat buffer[512]; struct glsl_attrib attribs[32]; float input_size[2], output_size[2], texture_size[2]; unsigned i, texunit = 1; const struct shader_uniforms *uni = NULL; size_t size = 0, attribs_size = 0; const struct gl_tex_info *info = (const struct gl_tex_info*)_info; const struct gl_tex_info *prev_info = (const struct gl_tex_info*)_prev_info; const struct gl_tex_info *fbo_info = (const struct gl_tex_info*)_fbo_info; struct glsl_attrib *attr = (struct glsl_attrib*)attribs; driver_t *driver = driver_get_ptr(); global_t *global = global_get_ptr(); glsl_shader_data_t *glsl = (glsl_shader_data_t*)driver->video_shader_data; if (!glsl) return; uni = (const struct shader_uniforms*)&glsl->gl_uniforms[glsl->glsl_active_index]; (void)data; if (glsl->gl_program[glsl->glsl_active_index] == 0) return; input_size [0] = (float)width; input_size [1] = (float)height; output_size[0] = (float)out_width; output_size[1] = (float)out_height; texture_size[0] = (float)tex_width; texture_size[1] = (float)tex_height; if (uni->input_size >= 0) glUniform2fv(uni->input_size, 1, input_size); if (uni->output_size >= 0) glUniform2fv(uni->output_size, 1, output_size); if (uni->texture_size >= 0) glUniform2fv(uni->texture_size, 1, texture_size); if (uni->frame_count >= 0 && glsl->glsl_active_index) { unsigned modulo = glsl->glsl_shader->pass[glsl->glsl_active_index - 1].frame_count_mod; if (modulo) frame_count %= modulo; glUniform1i(uni->frame_count, frame_count); } if (uni->frame_direction >= 0) glUniform1i(uni->frame_direction, global->rewind.frame_is_reverse ? -1 : 1); for (i = 0; i < glsl->glsl_shader->luts; i++) { if (uni->lut_texture[i] < 0) continue; /* Have to rebind as HW render could override this. */ glActiveTexture(GL_TEXTURE0 + texunit); glBindTexture(GL_TEXTURE_2D, glsl->gl_teximage[i]); glUniform1i(uni->lut_texture[i], texunit); texunit++; } /* Set original texture. */ if (glsl->glsl_active_index) { if (uni->orig.texture >= 0) { /* Bind original texture. */ glActiveTexture(GL_TEXTURE0 + texunit); glUniform1i(uni->orig.texture, texunit); glBindTexture(GL_TEXTURE_2D, info->tex); texunit++; } if (uni->orig.texture_size >= 0) glUniform2fv(uni->orig.texture_size, 1, info->tex_size); if (uni->orig.input_size >= 0) glUniform2fv(uni->orig.input_size, 1, info->input_size); /* Pass texture coordinates. */ if (uni->orig.tex_coord >= 0) { attr->loc = uni->orig.tex_coord; attr->size = 2; attr->offset = size * sizeof(GLfloat); attribs_size++; attr++; memcpy(buffer + size, info->coord, 8 * sizeof(GLfloat)); size += 8; } /* Bind FBO textures. */ for (i = 0; i < fbo_info_cnt; i++) { if (uni->pass[i].texture) { glActiveTexture(GL_TEXTURE0 + texunit); glBindTexture(GL_TEXTURE_2D, fbo_info[i].tex); glUniform1i(uni->pass[i].texture, texunit); texunit++; } if (uni->pass[i].texture_size >= 0) glUniform2fv(uni->pass[i].texture_size, 1, fbo_info[i].tex_size); if (uni->pass[i].input_size >= 0) glUniform2fv(uni->pass[i].input_size, 1, fbo_info[i].input_size); if (uni->pass[i].tex_coord >= 0) { attr->loc = uni->pass[i].tex_coord; attr->size = 2; attr->offset = size * sizeof(GLfloat); attribs_size++; attr++; memcpy(buffer + size, fbo_info[i].coord, 8 * sizeof(GLfloat)); size += 8; } } } /* Set previous textures. Only bind if they're actually used. */ for (i = 0; i < PREV_TEXTURES; i++) { if (uni->prev[i].texture >= 0) { glActiveTexture(GL_TEXTURE0 + texunit); glBindTexture(GL_TEXTURE_2D, prev_info[i].tex); glUniform1i(uni->prev[i].texture, texunit); texunit++; } if (uni->prev[i].texture_size >= 0) glUniform2fv(uni->prev[i].texture_size, 1, prev_info[i].tex_size); if (uni->prev[i].input_size >= 0) glUniform2fv(uni->prev[i].input_size, 1, prev_info[i].input_size); /* Pass texture coordinates. */ if (uni->prev[i].tex_coord >= 0) { attr->loc = uni->prev[i].tex_coord; attr->size = 2; attr->offset = size * sizeof(GLfloat); attribs_size++; attr++; memcpy(buffer + size, prev_info[i].coord, 8 * sizeof(GLfloat)); size += 8; } } if (size) { gl_glsl_set_attribs(glsl, glsl->glsl_vbo[glsl->glsl_active_index].vbo_secondary, &glsl->glsl_vbo[glsl->glsl_active_index].buffer_secondary, &glsl->glsl_vbo[glsl->glsl_active_index].size_secondary, buffer, size, attribs, attribs_size); } glActiveTexture(GL_TEXTURE0); /* #pragma parameters. */ for (i = 0; i < glsl->glsl_shader->num_parameters; i++) { int location = glGetUniformLocation( glsl->gl_program[glsl->glsl_active_index], glsl->glsl_shader->parameters[i].id); glUniform1f(location, glsl->glsl_shader->parameters[i].current); } /* Set state parameters. */ if (glsl->gl_state_tracker) { static struct state_tracker_uniform state_info[GFX_MAX_VARIABLES]; static unsigned cnt = 0; if (glsl->glsl_active_index == 1) cnt = state_tracker_get_uniform(glsl->gl_state_tracker, state_info, GFX_MAX_VARIABLES, frame_count); for (i = 0; i < cnt; i++) { int location = glGetUniformLocation( glsl->gl_program[glsl->glsl_active_index], state_info[i].id); glUniform1f(location, state_info[i].value); } } }