move pipelines and texture modes to deferred commands
This commit is contained in:
parent
139394c6de
commit
768daf1f54
@ -118,7 +118,6 @@ typedef struct {
|
|||||||
|
|
||||||
bool textured, texture_repeat;
|
bool textured, texture_repeat;
|
||||||
TextureKey texture;
|
TextureKey texture;
|
||||||
TextureMode texture_mode;
|
|
||||||
|
|
||||||
GLuint element_buffer;
|
GLuint element_buffer;
|
||||||
GLsizei element_count;
|
GLsizei element_count;
|
||||||
@ -134,19 +133,6 @@ typedef struct {
|
|||||||
} DeferredCommandClear;
|
} DeferredCommandClear;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
enum DeferredCommandType {
|
|
||||||
DEFERRED_COMMAND_TYPE_DRAW_ELEMENTS,
|
|
||||||
DEFERRED_COMMAND_TYPE_CLEAR,
|
|
||||||
} type;
|
|
||||||
|
|
||||||
union {
|
|
||||||
DeferredCommandDrawElements draw_elements;
|
|
||||||
DeferredCommandClear clear;
|
|
||||||
};
|
|
||||||
} DeferredCommand;
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PIPELINE_NO,
|
PIPELINE_NO,
|
||||||
PIPELINE_SPACE,
|
PIPELINE_SPACE,
|
||||||
@ -154,6 +140,33 @@ typedef enum {
|
|||||||
} Pipeline;
|
} Pipeline;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Pipeline pipeline;
|
||||||
|
} DeferredCommandUsePipeline;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
TextureMode mode;
|
||||||
|
} DeferredCommandUseTextureMode;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
enum DeferredCommandType {
|
||||||
|
DEFERRED_COMMAND_TYPE_DRAW_ELEMENTS,
|
||||||
|
DEFERRED_COMMAND_TYPE_CLEAR,
|
||||||
|
DEFERRED_COMMAND_TYPE_USE_PIPIELINE,
|
||||||
|
DEFERRED_COMMAND_TYPE_USE_TEXTURE_MODE,
|
||||||
|
} type;
|
||||||
|
|
||||||
|
union {
|
||||||
|
DeferredCommandDrawElements draw_elements;
|
||||||
|
DeferredCommandClear clear;
|
||||||
|
DeferredCommandUsePipeline use_pipeline;
|
||||||
|
DeferredCommandUseTextureMode use_texture_mode;
|
||||||
|
};
|
||||||
|
} DeferredCommand;
|
||||||
|
|
||||||
|
|
||||||
static Pipeline pipeline_last_used = PIPELINE_NO;
|
static Pipeline pipeline_last_used = PIPELINE_NO;
|
||||||
|
|
||||||
|
|
||||||
@ -165,13 +178,15 @@ static Pipeline pipeline_last_used = PIPELINE_NO;
|
|||||||
static size_t scratch_va_front_used, scratch_va_back_used;
|
static size_t scratch_va_front_used, scratch_va_back_used;
|
||||||
static GLuint *front_scratch_vertex_arrays, *back_scratch_vertex_arrays;
|
static GLuint *front_scratch_vertex_arrays, *back_scratch_vertex_arrays;
|
||||||
static GLuint **current_scratch_vertex_array = &front_scratch_vertex_arrays;
|
static GLuint **current_scratch_vertex_array = &front_scratch_vertex_arrays;
|
||||||
|
|
||||||
static void restart_scratch_vertex_arrays(void) {
|
static void restart_scratch_vertex_arrays(void) {
|
||||||
scratch_va_front_used = 0;
|
scratch_va_front_used = 0;
|
||||||
scratch_va_back_used = 0;
|
scratch_va_back_used = 0;
|
||||||
|
|
||||||
if (ctx.render_double_buffered)
|
if (ctx.render_double_buffered) {
|
||||||
current_scratch_vertex_array = current_scratch_vertex_array == &front_scratch_vertex_arrays ?
|
current_scratch_vertex_array = current_scratch_vertex_array == &front_scratch_vertex_arrays ?
|
||||||
&back_scratch_vertex_arrays : &front_scratch_vertex_arrays;
|
&back_scratch_vertex_arrays : &front_scratch_vertex_arrays;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -186,14 +201,17 @@ GLuint get_scratch_vertex_array(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
(*used)++;
|
(*used)++;
|
||||||
return (*current_scratch_vertex_array)[arrlenu(*current_scratch_vertex_array) - 1];
|
return (*current_scratch_vertex_array)[*used - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static DeferredCommand *deferred_commands;
|
static void finally_use_2d_pipeline(void);
|
||||||
static void issue_deferred_draw_commands(void) {
|
static void finally_use_space_pipeline(void);
|
||||||
use_2d_pipeline();
|
static void finally_use_texture_mode(TextureMode mode);
|
||||||
|
|
||||||
|
static DeferredCommand *deferred_commands;
|
||||||
|
|
||||||
|
static void issue_deferred_draw_commands(void) {
|
||||||
for (size_t i = 0; i < arrlenu(deferred_commands); ++i) {
|
for (size_t i = 0; i < arrlenu(deferred_commands); ++i) {
|
||||||
switch (deferred_commands[i].type) {
|
switch (deferred_commands[i].type) {
|
||||||
case DEFERRED_COMMAND_TYPE_CLEAR: {
|
case DEFERRED_COMMAND_TYPE_CLEAR: {
|
||||||
@ -230,8 +248,6 @@ static void issue_deferred_draw_commands(void) {
|
|||||||
command.vertices.stride,
|
command.vertices.stride,
|
||||||
(void *)command.vertices.offset);
|
(void *)command.vertices.offset);
|
||||||
|
|
||||||
use_texture_mode(command.texture_mode);
|
|
||||||
|
|
||||||
if (command.texcoords.arity != 0) {
|
if (command.texcoords.arity != 0) {
|
||||||
SDL_assert(command.texcoords.buffer == command.vertices.buffer);
|
SDL_assert(command.texcoords.buffer == command.vertices.buffer);
|
||||||
|
|
||||||
@ -293,6 +309,27 @@ static void issue_deferred_draw_commands(void) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case DEFERRED_COMMAND_TYPE_USE_PIPIELINE: {
|
||||||
|
switch (deferred_commands[i].use_pipeline.pipeline) {
|
||||||
|
case PIPELINE_2D:
|
||||||
|
finally_use_2d_pipeline();
|
||||||
|
break;
|
||||||
|
case PIPELINE_SPACE:
|
||||||
|
finally_use_space_pipeline();
|
||||||
|
break;
|
||||||
|
case PIPELINE_NO:
|
||||||
|
default:
|
||||||
|
SDL_assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case DEFERRED_COMMAND_TYPE_USE_TEXTURE_MODE: {
|
||||||
|
finally_use_texture_mode(deferred_commands[i].use_texture_mode.mode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
SDL_assert(false);
|
SDL_assert(false);
|
||||||
}
|
}
|
||||||
@ -318,7 +355,6 @@ void clear_draw_buffer(void) {
|
|||||||
|
|
||||||
|
|
||||||
void start_render_frame(void) {
|
void start_render_frame(void) {
|
||||||
restart_scratch_vertex_arrays();
|
|
||||||
clear_draw_buffer();
|
clear_draw_buffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,12 +364,14 @@ void end_render_frame(void) {
|
|||||||
issue_deferred_draw_commands();
|
issue_deferred_draw_commands();
|
||||||
SDL_GL_SwapWindow(ctx.window);
|
SDL_GL_SwapWindow(ctx.window);
|
||||||
arrsetlen(deferred_commands, 0);
|
arrsetlen(deferred_commands, 0);
|
||||||
|
restart_scratch_vertex_arrays();
|
||||||
} else {
|
} else {
|
||||||
/* instead of waiting for frame to finish for the swap, we continue */
|
/* instead of waiting for frame to finish for the swap, we continue */
|
||||||
/* while issuing new state for the next call, but deferring any fragment emitting calls for later */
|
/* while issuing new state for the next call, but deferring any fragment emitting calls for later */
|
||||||
/* actual swap will happen when next frame is fully finished, introducing a delay */
|
/* actual swap will happen when next frame is fully finished, introducing a delay */
|
||||||
SDL_GL_SwapWindow(ctx.window);
|
SDL_GL_SwapWindow(ctx.window);
|
||||||
issue_deferred_draw_commands();
|
issue_deferred_draw_commands();
|
||||||
|
restart_scratch_vertex_arrays();
|
||||||
glFlush();
|
glFlush();
|
||||||
arrsetlen(deferred_commands, 0);
|
arrsetlen(deferred_commands, 0);
|
||||||
}
|
}
|
||||||
@ -341,6 +379,16 @@ void end_render_frame(void) {
|
|||||||
|
|
||||||
|
|
||||||
void use_space_pipeline(void) {
|
void use_space_pipeline(void) {
|
||||||
|
DeferredCommand const command = {
|
||||||
|
.type = DEFERRED_COMMAND_TYPE_USE_PIPIELINE,
|
||||||
|
.use_pipeline = { PIPELINE_SPACE }
|
||||||
|
};
|
||||||
|
|
||||||
|
arrpush(deferred_commands, command);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void finally_use_space_pipeline(void) {
|
||||||
if (pipeline_last_used == PIPELINE_SPACE)
|
if (pipeline_last_used == PIPELINE_SPACE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -378,6 +426,16 @@ void use_space_pipeline(void) {
|
|||||||
|
|
||||||
|
|
||||||
void use_2d_pipeline(void) {
|
void use_2d_pipeline(void) {
|
||||||
|
DeferredCommand const command = {
|
||||||
|
.type = DEFERRED_COMMAND_TYPE_USE_PIPIELINE,
|
||||||
|
.use_pipeline = { PIPELINE_2D }
|
||||||
|
};
|
||||||
|
|
||||||
|
arrpush(deferred_commands, command);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void finally_use_2d_pipeline(void) {
|
||||||
if (pipeline_last_used == PIPELINE_SPACE) {
|
if (pipeline_last_used == PIPELINE_SPACE) {
|
||||||
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||||
glFlush();
|
glFlush();
|
||||||
@ -453,6 +511,16 @@ void render_circle(const CirclePrimitive *circle) {
|
|||||||
|
|
||||||
|
|
||||||
void use_texture_mode(TextureMode mode) {
|
void use_texture_mode(TextureMode mode) {
|
||||||
|
DeferredCommand const command = {
|
||||||
|
.type = DEFERRED_COMMAND_TYPE_USE_TEXTURE_MODE,
|
||||||
|
.use_texture_mode = { mode }
|
||||||
|
};
|
||||||
|
|
||||||
|
arrpush(deferred_commands, command);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void finally_use_texture_mode(TextureMode mode) {
|
||||||
static GLuint lists = 0;
|
static GLuint lists = 0;
|
||||||
if (!lists) {
|
if (!lists) {
|
||||||
lists = glGenLists(3);
|
lists = glGenLists(3);
|
||||||
@ -596,7 +664,7 @@ void finally_render_quads(const Primitive2D primitives[],
|
|||||||
command.element_count = 6 * (GLsizei)batch.size;
|
command.element_count = 6 * (GLsizei)batch.size;
|
||||||
command.range_end = 6 * (GLsizei)batch.size;
|
command.range_end = 6 * (GLsizei)batch.size;
|
||||||
|
|
||||||
command.texture_mode = batch.mode;
|
use_texture_mode(batch.mode);
|
||||||
|
|
||||||
DeferredCommand final_command = {
|
DeferredCommand final_command = {
|
||||||
.type = DEFERRED_COMMAND_TYPE_DRAW_ELEMENTS,
|
.type = DEFERRED_COMMAND_TYPE_DRAW_ELEMENTS,
|
||||||
|
Loading…
Reference in New Issue
Block a user