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;
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;
float viewport_neg_val;
@ -1135,22 +1135,21 @@ static void bind_ubo_locs(struct vrend_linked_shader_program *sprog,
{
if (!has_feature(feat_ubo))
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);
sprog->ubo_locs[id] = calloc(sprog->ss[id]->sel->sinfo.num_ubos, sizeof(uint32_t));
for (int i = 0; i < sprog->ss[id]->sel->sinfo.num_ubos; i++) {
int ubo_idx = sprog->ss[id]->sel->sinfo.ubo_idx[i];
unsigned mask = sprog->ss[id]->sel->sinfo.ubo_used_mask;
while (mask) {
uint32_t ubo_idx = u_bit_scan(&mask);
char name[32];
if (sprog->ss[id]->sel->sinfo.ubo_indirect)
snprintf(name, 32, "%subo[%d]", prefix, ubo_idx - 1);
else
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,
@ -1492,7 +1491,6 @@ static void vrend_destroy_program(struct vrend_linked_shader_program *ent)
free(ent->samp_locs[i]);
free(ent->ssbo_locs[i]);
free(ent->img_locs[i]);
free(ent->ubo_locs[i]);
}
free(ent->attrib_locs);
free(ent);
@ -3647,7 +3645,6 @@ static void vrend_draw_bind_ubo_shader(struct vrend_context *ctx,
int shader_type, int *ubo_id)
{
uint32_t mask;
int shader_ubo_idx;
struct pipe_constant_buffer *cb;
struct vrend_resource *res;
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;
mask = ctx->sub->const_bufs_used_mask[shader_type];
mask = ctx->sub->const_bufs_used_mask[shader_type] & sinfo->ubo_used_mask;
while (mask) {
/* The const_bufs_used_mask stores the gallium uniform buffer indices */
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];
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,
cb->buffer_offset, cb->buffer_size);
/* 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)++;
}
}

@ -178,9 +178,8 @@ struct dump_ctx {
uint32_t req_local_mem;
bool integer_memory;
uint32_t num_ubo;
uint32_t ubo_base;
int ubo_idx[32];
uint32_t ubo_used_mask;
int ubo_sizes[32];
uint32_t num_address;
@ -1240,13 +1239,16 @@ iter_declaration(struct tgsi_iterate_context *iter,
break;
case TGSI_FILE_CONSTANT:
if (decl->Declaration.Dimension && decl->Dim.Index2D != 0) {
if (ctx->num_ubo >= ARRAY_SIZE(ctx->ubo_idx)) {
fprintf(stderr, "Number of uniforms exceeded, max is %lu\n", ARRAY_SIZE(ctx->ubo_idx));
if (decl->Dim.Index2D > 31) {
fprintf(stderr, "Number of uniforms exceeded, max is 32\n");
return false;
}
ctx->ubo_idx[ctx->num_ubo] = decl->Dim.Index2D;
ctx->ubo_sizes[ctx->num_ubo] = decl->Range.Last + 1;
ctx->num_ubo++;
if (ctx->ubo_used_mask & (1 << decl->Dim.Index2D)) {
fprintf(stderr, "UBO #%d is already defined\n", decl->Dim.Index2D);
return false;
}
ctx->ubo_used_mask |= (1 << decl->Dim.Index2D);
ctx->ubo_sizes[decl->Dim.Index2D] = decl->Range.Last + 1;
} else {
/* if we have a normal single const set then ubo base should be 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))
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");
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)
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);
if (ctx->info.dimension_indirect_files & (1 << TGSI_FILE_CONSTANT)) {
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 {
for (i = 0; i < ctx->num_ubo; i++) {
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]);
unsigned mask = ctx->ubo_used_mask;
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->images_used_mask = ctx.images_used_mask;
sinfo->num_consts = ctx.num_consts;
sinfo->num_ubos = ctx.num_ubo;
memcpy(sinfo->ubo_idx, ctx.ubo_idx, ctx.num_ubo * sizeof(*ctx.ubo_idx));
sinfo->ubo_used_mask = ctx.ubo_used_mask;
sinfo->ssbo_used_mask = ctx.ssbo_used_mask;

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

Loading…
Cancel
Save