renderer,gl33: expose new magic uniforms; see render_context.glslh
Also optimize access to all magic uniforms slightly.
This commit is contained in:
parent
bc6f41244d
commit
a5d0deec0f
5 changed files with 144 additions and 20 deletions
|
@ -9,4 +9,19 @@ UNIFORM(513) mat4 r_projectionMatrix;
|
|||
UNIFORM(514) mat4 r_textureMatrix;
|
||||
UNIFORM(515) vec4 r_color;
|
||||
|
||||
// Active viewport, i.e. the region we're rendering into.
|
||||
// xy = offset, zw = width and height.
|
||||
// Units are real pixels.
|
||||
UNIFORM(516) vec4 r_viewport;
|
||||
|
||||
// Size(s) of output buffer(s) we're rendering into, in real pixels.
|
||||
// A size of 0,0 means the buffer is not attached.
|
||||
//
|
||||
// Note that r_colorOutputSizes is not a direct mapping to framebuffer attachments;
|
||||
// it is affected by the output -> attachment mapping (see r_framebuffer_set_output_attachments).
|
||||
// This means that r_colorOutputSizes[N] always corresponds to fragment shader output #N, which
|
||||
// is probably what you'd expect.
|
||||
UNIFORM(517) vec2 r_colorOutputSizes[4]; // NOTE: should match FRAMEBUFFER_MAX_OUTPUTS in renderer/api.h
|
||||
UNIFORM(521) vec2 r_depthOutputSize;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -547,7 +547,7 @@ void _r_uniform_ptr_float_array(Uniform *uniform, uint offset, uint count, float
|
|||
void _r_uniform_float_array(const char *uniform, uint offset, uint count, float elements[count]) attr_nonnull(1, 4);
|
||||
#define r_uniform_float_array(uniform, ...) _R_UNIFORM_GENERIC(float_array, uniform, __VA_ARGS__)
|
||||
|
||||
void _r_uniform_ptr_vec2(Uniform *uniform, float x, float y) attr_nonnull(1);
|
||||
void _r_uniform_ptr_vec2(Uniform *uniform, float x, float y);
|
||||
void _r_uniform_vec2(const char *uniform, float x, float y) attr_nonnull(1);
|
||||
#define r_uniform_vec2(uniform, ...) _R_UNIFORM_GENERIC(vec2, uniform, __VA_ARGS__)
|
||||
|
||||
|
|
|
@ -383,17 +383,93 @@ static void gl33_sync_viewport(void) {
|
|||
}
|
||||
}
|
||||
|
||||
static IntExtent gl33_get_default_framebuffer_size(void) {
|
||||
IntExtent s;
|
||||
// TODO: cache this at window creation time and refresh on resize events?
|
||||
SDL_GL_GetDrawableSize(R.window, &s.w, &s.h);
|
||||
return s;
|
||||
}
|
||||
|
||||
static void gl33_get_output_size(Framebuffer *fb, FramebufferAttachment a, vec2_noalign out) {
|
||||
if(a == FRAMEBUFFER_ATTACH_NONE) {
|
||||
out[0] = 0;
|
||||
out[1] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
FramebufferAttachmentQueryResult q = gl33_framebuffer_query_attachment(fb, a);
|
||||
|
||||
if(q.texture == NULL) {
|
||||
out[0] = 0;
|
||||
out[1] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
uint w, h;
|
||||
gl33_texture_get_size(q.texture, q.miplevel, &w, &h);
|
||||
out[0] = w;
|
||||
out[1] = h;
|
||||
}
|
||||
|
||||
static void gl33_sync_magic_uniforms(void) {
|
||||
ShaderProgram *shader = NOT_NULL(R.progs.active);
|
||||
Framebuffer *fb = R.framebuffer.active;
|
||||
Uniform **u = shader->magic_uniforms;
|
||||
|
||||
r_uniform_mat4(u[UMAGIC_MATRIX_MV], *_r_matrices.modelview.head);
|
||||
r_uniform_mat4(u[UMAGIC_MATRIX_PROJ], *_r_matrices.projection.head);
|
||||
r_uniform_mat4(u[UMAGIC_MATRIX_TEX], *_r_matrices.texture.head);
|
||||
r_uniform_vec4_rgba(u[UMAGIC_COLOR], &R.color);
|
||||
r_uniform_vec4_vec(u[UMAGIC_VIEWPORT], &R.viewport.active.x);
|
||||
|
||||
int num_color_out;
|
||||
|
||||
if(u[UMAGIC_COLOR_OUT_SIZES]) {
|
||||
num_color_out = iclamp(u[UMAGIC_COLOR_OUT_SIZES]->array_size, 0, FRAMEBUFFER_MAX_OUTPUTS);
|
||||
} else {
|
||||
num_color_out = 0;
|
||||
}
|
||||
|
||||
if(fb) {
|
||||
if(num_color_out > 0) {
|
||||
vec2_noalign out[num_color_out];
|
||||
|
||||
for(int i = 0; i < num_color_out; ++i) {
|
||||
gl33_get_output_size(fb, fb->output_mapping[i], out[i]);
|
||||
}
|
||||
|
||||
r_uniform_vec2_array(u[UMAGIC_COLOR_OUT_SIZES], 0, num_color_out, out);
|
||||
}
|
||||
|
||||
if(u[UMAGIC_DEPTH_OUT_SIZE]) {
|
||||
vec2_noalign out;
|
||||
gl33_get_output_size(fb, FRAMEBUFFER_ATTACH_DEPTH, out);
|
||||
r_uniform_vec2_vec(u[UMAGIC_DEPTH_OUT_SIZE], out);
|
||||
}
|
||||
} else { // default framebuffer
|
||||
// TODO: Maybe figure out whether we have the depth buffer?
|
||||
// We don't request one for the default framebuffer, so pretend it's not there.
|
||||
r_uniform_vec2(u[UMAGIC_DEPTH_OUT_SIZE], 0, 0);
|
||||
|
||||
if(num_color_out > 0) {
|
||||
IntExtent fb_size = gl33_get_default_framebuffer_size();
|
||||
vec2 out[num_color_out];
|
||||
out[0][0] = fb_size.w;
|
||||
out[0][1] = fb_size.h;
|
||||
memset(out + 1, 0, sizeof(out) - sizeof(out[0]));
|
||||
r_uniform_vec2_array(u[UMAGIC_COLOR_OUT_SIZES], 0, num_color_out, out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gl33_sync_state(void) {
|
||||
gl33_sync_capabilities();
|
||||
gl33_sync_framebuffer();
|
||||
gl33_sync_shader();
|
||||
r_uniform_mat4("r_modelViewMatrix", *_r_matrices.modelview.head);
|
||||
r_uniform_mat4("r_projectionMatrix", *_r_matrices.projection.head);
|
||||
r_uniform_mat4("r_textureMatrix", *_r_matrices.texture.head);
|
||||
r_uniform_vec4_rgba("r_color", &R.color);
|
||||
gl33_sync_viewport();
|
||||
gl33_sync_magic_uniforms();
|
||||
gl33_sync_uniforms(R.progs.active);
|
||||
gl33_sync_texunits(true);
|
||||
gl33_sync_framebuffer();
|
||||
gl33_sync_viewport();
|
||||
gl33_sync_vao();
|
||||
gl33_sync_blend_mode();
|
||||
|
||||
|
@ -1057,8 +1133,7 @@ static IntExtent gl33_framebuffer_get_size(Framebuffer *fb) {
|
|||
IntExtent fb_size;
|
||||
|
||||
if(fb == NULL) {
|
||||
// TODO: cache this at window creation time and refresh on resize events?
|
||||
SDL_GL_GetDrawableSize(R.window, &fb_size.w, &fb_size.h);
|
||||
fb_size = gl33_get_default_framebuffer_size();
|
||||
} else {
|
||||
fb_size = gl33_framebuffer_get_effective_size(fb);
|
||||
}
|
||||
|
|
|
@ -151,18 +151,22 @@ static struct {
|
|||
[UNIFORM_MAT4] = { uset_mat4, uget_mat4 },
|
||||
};
|
||||
|
||||
typedef struct MagicalUniform {
|
||||
typedef struct MagicUniformSpec {
|
||||
const char *name;
|
||||
const char *typename;
|
||||
UniformType type;
|
||||
} MagicalUniform;
|
||||
} MagicUniformSpec;
|
||||
|
||||
static MagicalUniform magical_unfiroms[] = {
|
||||
{ "r_modelViewMatrix", "mat4", UNIFORM_MAT4 },
|
||||
{ "r_projectionMatrix", "mat4", UNIFORM_MAT4 },
|
||||
{ "r_textureMatrix", "mat4", UNIFORM_MAT4 },
|
||||
{ "r_color", "vec4", UNIFORM_VEC4 },
|
||||
static MagicUniformSpec magic_unfiroms[] = {
|
||||
[UMAGIC_MATRIX_MV] = { "r_modelViewMatrix", "mat4", UNIFORM_MAT4 },
|
||||
[UMAGIC_MATRIX_PROJ] = { "r_projectionMatrix", "mat4", UNIFORM_MAT4 },
|
||||
[UMAGIC_MATRIX_TEX] = { "r_textureMatrix", "mat4", UNIFORM_MAT4 },
|
||||
[UMAGIC_COLOR] = { "r_color", "vec4", UNIFORM_VEC4 },
|
||||
[UMAGIC_VIEWPORT] = { "r_viewport", "vec4", UNIFORM_VEC4 },
|
||||
[UMAGIC_COLOR_OUT_SIZES] = { "r_colorOutputSizes[0]", "vec2", UNIFORM_VEC2 },
|
||||
[UMAGIC_DEPTH_OUT_SIZE] = { "r_depthOutputSize", "vec2", UNIFORM_VEC2 },
|
||||
};
|
||||
static_assert_nomsg(ARRAY_SIZE(magic_unfiroms) == NUM_MAGIC_UNIFORMS);
|
||||
|
||||
static void gl33_update_uniform(Uniform *uniform, uint offset, uint count, const void *data) {
|
||||
// these are validated properly in gl33_uniform
|
||||
|
@ -325,13 +329,22 @@ static bool cache_uniforms(ShaderProgram *prog) {
|
|||
continue;
|
||||
}
|
||||
|
||||
for(int j = 0; j < sizeof(magical_unfiroms)/sizeof(MagicalUniform); ++j) {
|
||||
MagicalUniform *m = magical_unfiroms + j;
|
||||
MagicUniformIndex magic_index = UMAGIC_INVALID;
|
||||
|
||||
if(!strcmp(name, m->name) && uni.type != m->type) {
|
||||
log_error("Magical uniform '%s' must be of type '%s'", name, m->typename);
|
||||
for(int j = 0; j < ARRAY_SIZE(magic_unfiroms); ++j) {
|
||||
MagicUniformSpec *m = magic_unfiroms + j;
|
||||
|
||||
if(strcmp(name, m->name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(uni.type != m->type) {
|
||||
log_error("Magic uniform '%s' must be of type '%s'", name, m->typename);
|
||||
return false;
|
||||
}
|
||||
|
||||
magic_index = j;
|
||||
break;
|
||||
}
|
||||
|
||||
const UniformTypeInfo *typeinfo = r_uniform_type_info(uni.type);
|
||||
|
@ -385,6 +398,12 @@ static bool cache_uniforms(ShaderProgram *prog) {
|
|||
}
|
||||
}
|
||||
|
||||
if(magic_index != UMAGIC_INVALID) {
|
||||
assume((uint)magic_index < ARRAY_SIZE(prog->magic_uniforms));
|
||||
assert(prog->magic_uniforms[magic_index] == NULL);
|
||||
prog->magic_uniforms[magic_index] = new_uni;
|
||||
}
|
||||
|
||||
ht_set(&prog->uniforms, name, new_uni);
|
||||
log_debug("%s = %i [array elements: %i; size: %zi bytes]", name, loc, uni.array_size, uni.array_size * uni.elem_size);
|
||||
}
|
||||
|
|
|
@ -17,9 +17,24 @@
|
|||
#include "opengl.h"
|
||||
#include "resource/shader_program.h"
|
||||
|
||||
typedef enum MagicUniformIndex {
|
||||
UMAGIC_INVALID = -1,
|
||||
|
||||
UMAGIC_MATRIX_MV,
|
||||
UMAGIC_MATRIX_PROJ,
|
||||
UMAGIC_MATRIX_TEX,
|
||||
UMAGIC_COLOR,
|
||||
UMAGIC_VIEWPORT,
|
||||
UMAGIC_COLOR_OUT_SIZES,
|
||||
UMAGIC_DEPTH_OUT_SIZE,
|
||||
|
||||
NUM_MAGIC_UNIFORMS,
|
||||
} MagicUniformIndex;
|
||||
|
||||
struct ShaderProgram {
|
||||
GLuint gl_handle;
|
||||
ht_str2ptr_t uniforms;
|
||||
Uniform *magic_uniforms[NUM_MAGIC_UNIFORMS];
|
||||
char debug_label[R_DEBUG_LABEL_SIZE];
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue