virglrenderer: use bitmask instead of arrays of indices

We already track samplers, images and ssbos using bitmasks, so this is a
bit more familiar to the rest of the code.

Also, this is going to enable some other nifty optimizations later on.

Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
Signed-off-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Signed-off-by: Jakob Bornecrantz <jakob@collabora.com>
macos/master
Erik Faye-Lund 6 years ago committed by Jakob Bornecrantz
parent 0aa272c21c
commit 5e89aea888
  1. 29
      src/vrend_renderer.c
  2. 33
      src/vrend_shader.c
  3. 3
      src/vrend_shader.h

@ -289,7 +289,7 @@ struct vrend_linked_shader_program {
GLuint *attrib_locs; GLuint *attrib_locs;
uint32_t shadow_samp_mask[PIPE_SHADER_TYPES]; uint32_t shadow_samp_mask[PIPE_SHADER_TYPES];
GLuint *ubo_locs[PIPE_SHADER_TYPES]; GLuint ubo_locs[PIPE_SHADER_TYPES][32];
GLuint vs_ws_adjust_loc; GLuint vs_ws_adjust_loc;
float viewport_neg_val; float viewport_neg_val;
@ -1135,22 +1135,21 @@ static void bind_ubo_locs(struct vrend_linked_shader_program *sprog,
{ {
if (!has_feature(feat_ubo)) if (!has_feature(feat_ubo))
return; return;
if (sprog->ss[id]->sel->sinfo.num_ubos) { if (sprog->ss[id]->sel->sinfo.ubo_used_mask) {
const char *prefix = pipe_shader_to_prefix(id); const char *prefix = pipe_shader_to_prefix(id);
sprog->ubo_locs[id] = calloc(sprog->ss[id]->sel->sinfo.num_ubos, sizeof(uint32_t)); unsigned mask = sprog->ss[id]->sel->sinfo.ubo_used_mask;
for (int i = 0; i < sprog->ss[id]->sel->sinfo.num_ubos; i++) { while (mask) {
int ubo_idx = sprog->ss[id]->sel->sinfo.ubo_idx[i]; uint32_t ubo_idx = u_bit_scan(&mask);
char name[32]; char name[32];
if (sprog->ss[id]->sel->sinfo.ubo_indirect) if (sprog->ss[id]->sel->sinfo.ubo_indirect)
snprintf(name, 32, "%subo[%d]", prefix, ubo_idx - 1); snprintf(name, 32, "%subo[%d]", prefix, ubo_idx - 1);
else else
snprintf(name, 32, "%subo%d", prefix, ubo_idx); snprintf(name, 32, "%subo%d", prefix, ubo_idx);
sprog->ubo_locs[id][i] = glGetUniformBlockIndex(sprog->id, name); sprog->ubo_locs[id][ubo_idx] = glGetUniformBlockIndex(sprog->id, name);
}
} }
} else
sprog->ubo_locs[id] = NULL;
} }
static void bind_ssbo_locs(struct vrend_linked_shader_program *sprog, static void bind_ssbo_locs(struct vrend_linked_shader_program *sprog,
@ -1492,7 +1491,6 @@ static void vrend_destroy_program(struct vrend_linked_shader_program *ent)
free(ent->samp_locs[i]); free(ent->samp_locs[i]);
free(ent->ssbo_locs[i]); free(ent->ssbo_locs[i]);
free(ent->img_locs[i]); free(ent->img_locs[i]);
free(ent->ubo_locs[i]);
} }
free(ent->attrib_locs); free(ent->attrib_locs);
free(ent); free(ent);
@ -3647,7 +3645,6 @@ static void vrend_draw_bind_ubo_shader(struct vrend_context *ctx,
int shader_type, int *ubo_id) int shader_type, int *ubo_id)
{ {
uint32_t mask; uint32_t mask;
int shader_ubo_idx;
struct pipe_constant_buffer *cb; struct pipe_constant_buffer *cb;
struct vrend_resource *res; struct vrend_resource *res;
struct vrend_shader_info* sinfo; struct vrend_shader_info* sinfo;
@ -3663,7 +3660,7 @@ static void vrend_draw_bind_ubo_shader(struct vrend_context *ctx,
sinfo = &ctx->sub->prog->ss[shader_type]->sel->sinfo; sinfo = &ctx->sub->prog->ss[shader_type]->sel->sinfo;
mask = ctx->sub->const_bufs_used_mask[shader_type]; mask = ctx->sub->const_bufs_used_mask[shader_type] & sinfo->ubo_used_mask;
while (mask) { while (mask) {
/* The const_bufs_used_mask stores the gallium uniform buffer indices */ /* The const_bufs_used_mask stores the gallium uniform buffer indices */
int i = u_bit_scan(&mask); int i = u_bit_scan(&mask);
@ -3672,18 +3669,10 @@ static void vrend_draw_bind_ubo_shader(struct vrend_context *ctx,
cb = &ctx->sub->cbs[shader_type][i]; cb = &ctx->sub->cbs[shader_type][i];
res = (struct vrend_resource *)cb->buffer; res = (struct vrend_resource *)cb->buffer;
/* Find the index of the uniform buffer in the array of shader ubo data */
for (shader_ubo_idx = 0; shader_ubo_idx < sinfo->num_ubos; shader_ubo_idx++) {
if (sinfo->ubo_idx[shader_ubo_idx] == i)
break;
}
if (shader_ubo_idx == sinfo->num_ubos)
continue;
glBindBufferRange(GL_UNIFORM_BUFFER, *ubo_id, res->id, glBindBufferRange(GL_UNIFORM_BUFFER, *ubo_id, res->id,
cb->buffer_offset, cb->buffer_size); cb->buffer_offset, cb->buffer_size);
/* The ubo_locs array is indexed using the shader ubo index */ /* The ubo_locs array is indexed using the shader ubo index */
glUniformBlockBinding(ctx->sub->prog->id, ctx->sub->prog->ubo_locs[shader_type][shader_ubo_idx], *ubo_id); glUniformBlockBinding(ctx->sub->prog->id, ctx->sub->prog->ubo_locs[shader_type][i], *ubo_id);
(*ubo_id)++; (*ubo_id)++;
} }
} }

@ -178,9 +178,8 @@ struct dump_ctx {
uint32_t req_local_mem; uint32_t req_local_mem;
bool integer_memory; bool integer_memory;
uint32_t num_ubo;
uint32_t ubo_base; uint32_t ubo_base;
int ubo_idx[32]; uint32_t ubo_used_mask;
int ubo_sizes[32]; int ubo_sizes[32];
uint32_t num_address; uint32_t num_address;
@ -1240,13 +1239,16 @@ iter_declaration(struct tgsi_iterate_context *iter,
break; break;
case TGSI_FILE_CONSTANT: case TGSI_FILE_CONSTANT:
if (decl->Declaration.Dimension && decl->Dim.Index2D != 0) { if (decl->Declaration.Dimension && decl->Dim.Index2D != 0) {
if (ctx->num_ubo >= ARRAY_SIZE(ctx->ubo_idx)) { if (decl->Dim.Index2D > 31) {
fprintf(stderr, "Number of uniforms exceeded, max is %lu\n", ARRAY_SIZE(ctx->ubo_idx)); fprintf(stderr, "Number of uniforms exceeded, max is 32\n");
return false; return false;
} }
ctx->ubo_idx[ctx->num_ubo] = decl->Dim.Index2D; if (ctx->ubo_used_mask & (1 << decl->Dim.Index2D)) {
ctx->ubo_sizes[ctx->num_ubo] = decl->Range.Last + 1; fprintf(stderr, "UBO #%d is already defined\n", decl->Dim.Index2D);
ctx->num_ubo++; return false;
}
ctx->ubo_used_mask |= (1 << decl->Dim.Index2D);
ctx->ubo_sizes[decl->Dim.Index2D] = decl->Range.Last + 1;
} else { } else {
/* if we have a normal single const set then ubo base should be 1 */ /* if we have a normal single const set then ubo base should be 1 */
ctx->ubo_base = 1; ctx->ubo_base = 1;
@ -3927,7 +3929,7 @@ static void emit_header(struct dump_ctx *ctx)
if (ctx->prog_type == TGSI_PROCESSOR_FRAGMENT && fs_emit_layout(ctx)) if (ctx->prog_type == TGSI_PROCESSOR_FRAGMENT && fs_emit_layout(ctx))
emit_ext(ctx, "ARB_fragment_coord_conventions", "require"); emit_ext(ctx, "ARB_fragment_coord_conventions", "require");
if (ctx->num_ubo) if (ctx->ubo_used_mask)
emit_ext(ctx, "ARB_uniform_buffer_object", "require"); emit_ext(ctx, "ARB_uniform_buffer_object", "require");
if (ctx->num_cull_dist_prop || ctx->key->prev_stage_num_cull_out) if (ctx->num_cull_dist_prop || ctx->key->prev_stage_num_cull_out)
@ -4601,15 +4603,19 @@ static void emit_ios(struct dump_ctx *ctx)
if (ctx->color_in_mask & 2) if (ctx->color_in_mask & 2)
emit_hdr(ctx, "vec4 realcolor1;\n"); emit_hdr(ctx, "vec4 realcolor1;\n");
} }
if (ctx->num_ubo) { if (ctx->ubo_used_mask) {
const char *cname = tgsi_proc_to_prefix(ctx->prog_type); const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
if (ctx->info.dimension_indirect_files & (1 << TGSI_FILE_CONSTANT)) { if (ctx->info.dimension_indirect_files & (1 << TGSI_FILE_CONSTANT)) {
require_glsl_ver(ctx, 150); require_glsl_ver(ctx, 150);
emit_hdrf(ctx, "uniform %subo { vec4 ubocontents[%d]; } %suboarr[%d];\n", cname, ctx->ubo_sizes[0], cname, ctx->num_ubo); int first = ffs(ctx->ubo_used_mask) - 1;
unsigned num_ubo = util_bitcount(ctx->ubo_used_mask);
emit_hdrf(ctx, "uniform %subo { vec4 ubocontents[%d]; } %suboarr[%d];\n", cname, ctx->ubo_sizes[first], cname, num_ubo);
} else { } else {
for (i = 0; i < ctx->num_ubo; i++) { unsigned mask = ctx->ubo_used_mask;
emit_hdrf(ctx, "uniform %subo%d { vec4 %subo%dcontents[%d]; };\n", cname, ctx->ubo_idx[i], cname, ctx->ubo_idx[i], ctx->ubo_sizes[i]); while (mask) {
uint32_t i = u_bit_scan(&mask);
emit_hdrf(ctx, "uniform %subo%d { vec4 %subo%dcontents[%d]; };\n", cname, i, cname, i, ctx->ubo_sizes[i]);
} }
} }
} }
@ -4847,8 +4853,7 @@ char *vrend_convert_shader(struct vrend_context *rctx,
sinfo->samplers_used_mask = ctx.samplers_used; sinfo->samplers_used_mask = ctx.samplers_used;
sinfo->images_used_mask = ctx.images_used_mask; sinfo->images_used_mask = ctx.images_used_mask;
sinfo->num_consts = ctx.num_consts; sinfo->num_consts = ctx.num_consts;
sinfo->num_ubos = ctx.num_ubo; sinfo->ubo_used_mask = ctx.ubo_used_mask;
memcpy(sinfo->ubo_idx, ctx.ubo_idx, ctx.num_ubo * sizeof(*ctx.ubo_idx));
sinfo->ssbo_used_mask = ctx.ssbo_used_mask; sinfo->ssbo_used_mask = ctx.ssbo_used_mask;

@ -44,13 +44,12 @@ struct vrend_array {
struct vrend_shader_info { struct vrend_shader_info {
uint32_t samplers_used_mask; uint32_t samplers_used_mask;
uint32_t images_used_mask; uint32_t images_used_mask;
uint32_t ubo_used_mask;
uint32_t ssbo_used_mask; uint32_t ssbo_used_mask;
int num_consts; int num_consts;
int num_inputs; int num_inputs;
int num_interps; int num_interps;
int num_outputs; int num_outputs;
int num_ubos;
int ubo_idx[32];
bool ubo_indirect; bool ubo_indirect;
uint8_t num_indirect_generic_outputs; uint8_t num_indirect_generic_outputs;
uint8_t num_indirect_patch_outputs; uint8_t num_indirect_patch_outputs;

Loading…
Cancel
Save