Skip to content

Commit

Permalink
MRT begin_pass, new begin_default_pass, new shader uniform declaration
Browse files Browse the repository at this point in the history
  • Loading branch information
floooh committed Jul 26, 2017
1 parent b17ad1f commit 2b67a23
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 72 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.vscode/
#>fips
# this area is managed by fips, do not edit
.fips-*
*.pyc
#<fips
133 changes: 96 additions & 37 deletions _sokol_gfx.impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,19 +87,22 @@ void sg_init_image_desc(sg_image_desc* desc) {
static void _sg_init_shader_stage_desc(sg_shader_stage_desc* desc) {
SOKOL_ASSERT(desc);
desc->source = 0;
desc->num_ubs = 0;
desc->num_images = 0;
for (int ub_index = 0; ub_index < SG_MAX_SHADERSTAGE_UBS; ub_index++) {
sg_shader_uniform_block_desc* ub_desc = &desc->ub[ub_index];
ub_desc->size = 0;
ub_desc->num_uniforms = 0;
for (int u_index = 0; u_index < SG_MAX_UNIFORMS; u_index++) {
sg_shader_uniform_desc* u_desc = &ub_desc->u[u_index];
u_desc->name = 0;
u_desc->offset = 0;
u_desc->type = SG_UNIFORMTYPE_INVALID;
u_desc->count = 1;
u_desc->array_count = 1;
}
}
for (int img_index = 0; img_index < SG_MAX_SHADERSTAGE_IMAGES; img_index++) {
sg_shader_image_desc* img_desc = &desc->images[img_index];
sg_shader_image_desc* img_desc = &desc->image[img_index];
img_desc->name = 0;
img_desc->type = SG_IMAGETYPE_INVALID;
}
Expand All @@ -112,22 +115,32 @@ void sg_init_shader_desc(sg_shader_desc* desc) {
_sg_init_shader_stage_desc(&desc->fs);
}

void sg_init_uniform_block(sg_shader_uniform_block_desc* desc, int ub_size) {
void sg_init_uniform_block(sg_shader_desc* desc, sg_shader_stage stage, int ub_size) {
SOKOL_ASSERT(desc);
SOKOL_ASSERT((stage == SG_SHADERSTAGE_VS) || (stage == SG_SHADERSTAGE_FS));
SOKOL_ASSERT(ub_size > 0);
desc->size = ub_size;
sg_shader_stage_desc* s = (stage == SG_SHADERSTAGE_VS) ? &desc->vs : &desc->fs;
SOKOL_ASSERT(s->num_ubs < SG_MAX_SHADERSTAGE_UBS);
SOKOL_ASSERT(s->ub[s->num_ubs].size == 0);
s->ub[s->num_ubs++].size = ub_size;
}

void sg_init_named_uniform(sg_shader_uniform_desc* desc, const char* name, int ub_offset, sg_uniform_type type, int array_count) {
void sg_init_named_uniform(sg_shader_desc* desc, sg_shader_stage stage, const char* name, int ub_offset, sg_uniform_type type, int array_count) {
SOKOL_ASSERT(desc);
SOKOL_ASSERT((stage == SG_SHADERSTAGE_VS) || (stage == SG_SHADERSTAGE_FS));
SOKOL_ASSERT(name);
SOKOL_ASSERT(ub_offset >= 0);
SOKOL_ASSERT(type != SG_UNIFORMTYPE_INVALID);
SOKOL_ASSERT(array_count >= 1);
desc->name = name;
desc->offset = ub_offset;
desc->type = type;
desc->count = array_count;
sg_shader_stage_desc* s = (stage == SG_SHADERSTAGE_VS) ? &desc->vs : &desc->fs;
SOKOL_ASSERT(s->num_ubs >= 1);
sg_shader_uniform_block_desc* ub = &(s->ub[s->num_ubs-1]);
SOKOL_ASSERT(ub->num_uniforms < SG_MAX_UNIFORMS);
sg_shader_uniform_desc* u_desc = &(ub->u[ub->num_uniforms++]);
u_desc->name = name;
u_desc->offset = ub_offset;
u_desc->type = type;
u_desc->array_count = array_count;
}

static void _sg_init_vertex_layout_desc(sg_vertex_layout_desc* layout) {
Expand Down Expand Up @@ -751,34 +764,22 @@ static void _sg_validate_shader_desc(const sg_shader_desc* desc) {
SOKOL_ASSERT(desc->fs.source);
#endif
#ifdef SOKOL_DEBUG
bool ub_range_valid = true;
for (int i = 0; i < SG_NUM_SHADER_STAGES; i++) {
const sg_shader_stage_desc* stage_desc = (i == 0)? &desc->vs : &desc->fs;
for (int ub_index = 0; ub_index < SG_MAX_SHADERSTAGE_UBS; ub_index++) {
SOKOL_ASSERT((stage_desc->num_ubs >= 0) && (stage_desc->num_ubs <= SG_MAX_SHADERSTAGE_UBS));
for (int ub_index = 0; ub_index < stage_desc->num_ubs; ub_index++) {
const sg_shader_uniform_block_desc* ub_desc = &stage_desc->ub[ub_index];
if (ub_desc->size > 0) {
SOKOL_ASSERT(ub_range_valid);
bool u_range_valid = true;
for (int u_index = 0; u_index < SG_MAX_UNIFORMS; u_index++) {
const sg_shader_uniform_desc* u_desc = &ub_desc->u[u_index];
if (u_desc->type != SG_UNIFORMTYPE_INVALID) {
SOKOL_ASSERT(u_range_valid);
#ifdef SOKOL_USE_GLES2
SOKOL_ASSERT(u_desc->name);
#endif
SOKOL_ASSERT(u_desc->count >= 1);
SOKOL_ASSERT(u_desc->offset >= 0);
SOKOL_ASSERT((u_desc->offset + _sg_uniform_size(u_desc->type, u_desc->count)) <= ub_desc->size);
}
else {
/* uniforms must use consecutive slots */
u_range_valid = false;
}
}
}
else {
/* uniform blocks must use consecutive slots */
ub_range_valid = false;
SOKOL_ASSERT(ub_desc->size > 0);
SOKOL_ASSERT((ub_desc->num_uniforms > 0) && (ub_desc->num_uniforms <= SG_MAX_UNIFORMS));
for (int u_index = 0; u_index < ub_desc->num_uniforms; u_index++) {
const sg_shader_uniform_desc* u_desc = &ub_desc->u[u_index];
SOKOL_ASSERT(u_desc->type != SG_UNIFORMTYPE_INVALID);
#ifdef SOKOL_USE_GLES2
SOKOL_ASSERT(u_desc->name);
#endif
SOKOL_ASSERT(u_desc->array_count >= 1);
SOKOL_ASSERT(u_desc->offset >= 0);
SOKOL_ASSERT((u_desc->offset + _sg_uniform_size(u_desc->type, u_desc->array_count)) <= ub_desc->size);
}
}
}
Expand Down Expand Up @@ -808,6 +809,54 @@ static void _sg_validate_draw_state(const sg_draw_state* ds) {
SOKOL_ASSERT(ds->vertex_buffers[0]);
}

static void _sg_validate_begin_pass(const _sg_pass* pass, const sg_pass_action* pass_action) {
SOKOL_ASSERT(pass && pass_action);
/* must have at least one color attachment */
SOKOL_ASSERT(pass->color_atts[0].image);
/* check color attachments */
#if defined(SOKOL_DEBUG)
const _sg_image* img = pass->color_atts[0].image;
bool img_continuous = true;
for (int i = 0; i < SG_MAX_COLOR_ATTACHMENTS; i++) {
const _sg_attachment* att = &pass->color_atts[i];
if (att->image) {
SOKOL_ASSERT(img_continuous);
/* pass valid? */
SOKOL_ASSERT(att->image->slot.state == SG_RESOURCESTATE_VALID);
/* pass still exists? */
SOKOL_ASSERT(att->image->slot.id == att->image_id);
/* all images must be render target */
SOKOL_ASSERT(att->image->render_target);
/* all images must be immutable */
SOKOL_ASSERT(att->image->usage == SG_USAGE_IMMUTABLE);
/* all images must have same size */
SOKOL_ASSERT(att->image->width == img->width);
SOKOL_ASSERT(att->image->height == img->height);
/* all images must have same pixel format */
SOKOL_ASSERT(att->image->color_format == img->color_format);
/* must be a valid color render target pixel format */
SOKOL_ASSERT(_sg_is_valid_rendertarget_color_format(att->image->color_format));
/* all images must have same sample count */
SOKOL_ASSERT(att->image->sample_count == img->sample_count);
}
else {
img_continuous = false;
}
}
/* check depth-stencil attachment */
const _sg_attachment* ds_att = &pass->ds_att;
if (ds_att->image) {
SOKOL_ASSERT(ds_att->image->slot.state == SG_RESOURCESTATE_VALID);
SOKOL_ASSERT(ds_att->image->slot.id == ds_att->image_id);
SOKOL_ASSERT(ds_att->image->render_target);
SOKOL_ASSERT(ds_att->image->usage == SG_USAGE_IMMUTABLE);
SOKOL_ASSERT(ds_att->image->width == img->width);
SOKOL_ASSERT(ds_att->image->height == img->height);
SOKOL_ASSERT(_sg_is_valid_rendertarget_depth_format(ds_att->image->depth_format));
}
#endif /* SOKOL_DEBUG */
}

static bool _sg_validate_draw(_sg_pipeline* pip,
_sg_buffer** vbs, int num_vbs, const _sg_buffer* ib,
_sg_image** vs_imgs, int num_vs_imgs,
Expand Down Expand Up @@ -1045,11 +1094,21 @@ void sg_destroy_pass(sg_id pass_id) {
}
}

void sg_begin_pass(sg_id pass_id, const sg_pass_action* pass_action, int width, int height) {
void sg_begin_default_pass(const sg_pass_action* pass_action, int width, int height) {
SOKOL_ASSERT(_sg && pass_action);
SOKOL_ASSERT(pass_action->_init_guard == _SG_INIT_GUARD);
_sg_begin_pass(&_sg->backend, 0, pass_action, width, height);
}

void sg_begin_pass(sg_id pass_id, const sg_pass_action* pass_action) {
SOKOL_ASSERT(_sg && pass_action);
SOKOL_ASSERT(pass_action->_init_guard == _SG_INIT_GUARD);
_sg_pass* pass = _sg_lookup_pass(&_sg->pools, pass_id); // can be 0
_sg_begin_pass(&_sg->backend, pass, pass_action, width, height);
_sg_pass* pass = _sg_lookup_pass(&_sg->pools, pass_id);
SOKOL_ASSERT(pass && pass->slot.state == SG_RESOURCESTATE_VALID);
_sg_validate_begin_pass(pass, pass_action);
const int w = pass->color_atts[0].image->width;
const int h = pass->color_atts[0].image->height;
_sg_begin_pass(&_sg->backend, pass, pass_action, w, h);
}

void sg_apply_draw_state(const sg_draw_state* ds) {
Expand Down
107 changes: 77 additions & 30 deletions _sokol_gfx_gl.impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,8 @@ typedef struct {
uint32_t frame_index;
GLenum cur_primitive_type;
GLenum cur_index_type;
int cur_pass_width;
int cur_pass_height;
_sg_pipeline* cur_pipeline;
sg_id cur_pipeline_id;
_sg_state_cache cache;
Expand All @@ -676,6 +678,8 @@ static void _sg_setup_backend(_sg_backend* state) {
state->frame_index = 1;
state->cur_primitive_type = GL_TRIANGLES;
state->cur_index_type = 0;
state->cur_pass_width = 0;
state->cur_pass_height = 0;
state->cur_pipeline = 0;
state->cur_pipeline_id = SG_INVALID_ID;
state->valid = true;
Expand Down Expand Up @@ -1046,23 +1050,19 @@ static void _sg_create_shader(_sg_backend* state, _sg_shader* shd, const sg_shad
const sg_shader_stage_desc* stage_desc = (stage_index == SG_SHADERSTAGE_VS)? &desc->vs : &desc->fs;
_sg_shader_stage* stage = &shd->stage[stage_index];
SOKOL_ASSERT(stage->num_uniform_blocks == 0);
for (int ub_index = 0; ub_index < SG_MAX_SHADERSTAGE_UBS; ub_index++) {
stage->num_uniform_blocks = stage_desc->num_ubs;
for (int ub_index = 0; ub_index < stage_desc->num_ubs; ub_index++) {
const sg_shader_uniform_block_desc* ub_desc = &stage_desc->ub[ub_index];
if (ub_desc->size == 0) {
break;
}
_sg_uniform_block* ub = &stage->uniform_blocks[stage->num_uniform_blocks++];
_sg_uniform_block* ub = &stage->uniform_blocks[ub_index];
ub->size = ub_desc->size;
SOKOL_ASSERT(ub->num_uniforms == 0);
for (int u_index = 0; u_index < SG_MAX_UNIFORMS; u_index++) {
ub->num_uniforms = ub_desc->num_uniforms;
for (int u_index = 0; u_index < ub_desc->num_uniforms; u_index++) {
const sg_shader_uniform_desc* u_desc = &ub_desc->u[u_index];
if (u_desc->type == SG_UNIFORMTYPE_INVALID) {
break;
}
_sg_uniform* u = &ub->uniforms[ub->num_uniforms++];
_sg_uniform* u = &ub->uniforms[u_index];
u->type = u_desc->type;
u->offset = u_desc->offset;
u->count = u_desc->count;
u->count = u_desc->array_count;
if (u_desc->name) {
u->gl_loc = glGetUniformLocation(gl_prog, u_desc->name);
}
Expand Down Expand Up @@ -1287,9 +1287,32 @@ static void _sg_begin_pass(_sg_backend* state, _sg_pass* pass, const sg_pass_act
SOKOL_ASSERT(state);
SOKOL_ASSERT(action);
SOKOL_ASSERT(!state->in_pass);
_SG_GL_CHECK_ERROR();
state->in_pass = true;
state->cur_pass_width = w;
state->cur_pass_height = h;
if (pass) {

/* offscreen pass */
SOKOL_ASSERT(pass->gl_fb);
glBindFramebuffer(GL_FRAMEBUFFER, pass->gl_fb);
#if !defined(SOKOL_USE_GLES2)
GLenum att[SG_MAX_COLOR_ATTACHMENTS] = {
GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1,
GL_COLOR_ATTACHMENT2,
GL_COLOR_ATTACHMENT3
};
int num_attrs = 0;
for (int i = 0; i < SG_MAX_COLOR_ATTACHMENTS; i++) {
if (pass->color_atts[num_attrs].image) {
num_attrs++;
}
else {
break;
}
}
glDrawBuffers(num_attrs, att);
#endif
}
else {
/* default pass */
Expand All @@ -1313,26 +1336,50 @@ static void _sg_begin_pass(_sg_backend* state, _sg_pass* pass, const sg_pass_act
state->cache.ds.stencil_write_mask = 0xFF;
glStencilMask(0xFF);
}
/* FIXME: multiple-render-target! */
GLbitfield clear_mask = 0;
if (action->actions & SG_PASSACTION_CLEAR_COLOR0) {
clear_mask |= GL_COLOR_BUFFER_BIT;
const float* c = action->color[0];
glClearColor(c[0], c[1], c[2], c[3]);
}
if (action->actions & SG_PASSACTION_CLEAR_DEPTH_STENCIL) {
/* FIXME: hmm separate depth/stencil clear? */
clear_mask |= GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT;
#ifdef SOKOL_USE_GLCORE33
glClearDepth(action->depth);
#else
glClearDepthf(action->depth);
#endif
glClearStencil(action->stencil);
bool use_mrt_clear = (0 != pass);
#if defined(SOKOL_USE_GLES2)
use_mrt_clear = false;
#endif
if (!use_mrt_clear) {
GLbitfield clear_mask = 0;
if (action->actions & SG_PASSACTION_CLEAR_COLOR0) {
clear_mask |= GL_COLOR_BUFFER_BIT;
const float* c = action->color[0];
glClearColor(c[0], c[1], c[2], c[3]);
}
if (action->actions & SG_PASSACTION_CLEAR_DEPTH_STENCIL) {
/* FIXME: hmm separate depth/stencil clear? */
clear_mask |= GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT;
#ifdef SOKOL_USE_GLCORE33
glClearDepth(action->depth);
#else
glClearDepthf(action->depth);
#endif
glClearStencil(action->stencil);
}
if (0 != clear_mask) {
glClear(clear_mask);
}
}
if (0 != clear_mask) {
glClear(clear_mask);
#if !defined SOKOL_USE_GLES2
else {
SOKOL_ASSERT(pass);
for (int i = 0; i < SG_MAX_COLOR_ATTACHMENTS; i++) {
if (pass->color_atts[i].image) {
if (action->actions & (SG_PASSACTION_CLEAR_COLOR0<<i)) {
glClearBufferfv(GL_COLOR, i, action->color[i]);
}
}
else {
break;
}
}
if (pass->ds_att.image && (action->actions & SG_PASSACTION_CLEAR_DEPTH_STENCIL)) {
glClearBufferfi(GL_DEPTH_STENCIL, 0, action->depth, action->stencil);
}
}
#endif
_SG_GL_CHECK_ERROR();
}

static void _sg_end_pass(_sg_backend* state) {
Expand Down
Loading

0 comments on commit 2b67a23

Please sign in to comment.