arb_gpu_shader5: add support for indirect ubo/samplers

Tested-by: Gurchetan Singh <gurchetansingh@chromium.org>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
macos/master
Dave Airlie 7 years ago
parent 881152e93d
commit 54c2308029
  1. 15
      src/vrend_renderer.c
  2. 189
      src/vrend_shader.c
  3. 15
      src/vrend_shader.h

@ -627,6 +627,7 @@ static void vrend_destroy_shader_selector(struct vrend_shader_selector *sel)
free(sel->tmp_buf);
free(sel->sinfo.so_names);
free(sel->sinfo.interpinfo);
free(sel->sinfo.sampler_arrays);
free(sel->tokens);
free(sel);
}
@ -871,7 +872,7 @@ static struct vrend_linked_shader_program *add_shader_program(struct vrend_conte
struct vrend_shader *gs)
{
struct vrend_linked_shader_program *sprog = CALLOC_STRUCT(vrend_linked_shader_program);
char name[32];
char name[64];
int i;
GLuint prog_id;
GLint lret;
@ -994,7 +995,11 @@ static struct vrend_linked_shader_program *add_shader_program(struct vrend_conte
index = 0;
while(mask) {
i = u_bit_scan(&mask);
snprintf(name, 32, "%ssamp%d", prefix, i);
if (sprog->ss[id]->sel->sinfo.num_sampler_arrays) {
int arr_idx = shader_lookup_sampler_array(&sprog->ss[id]->sel->sinfo, i);
snprintf(name, 32, "%ssamp%d[%d]", prefix, arr_idx, i - sprog->ss[id]->sel->sinfo.sampler_arrays[arr_idx].first);
} else
snprintf(name, 32, "%ssamp%d", prefix, i);
sprog->samp_locs[id][index] = glGetUniformLocation(prog_id, name);
if (sprog->ss[id]->sel->sinfo.shadow_samp_mask & (1 << i)) {
snprintf(name, 32, "%sshadmask%d", prefix, i);
@ -1048,7 +1053,11 @@ static struct vrend_linked_shader_program *add_shader_program(struct vrend_conte
sprog->ubo_locs[id] = calloc(sprog->ss[id]->sel->sinfo.num_ubos, sizeof(uint32_t));
for (i = 0; i < sprog->ss[id]->sel->sinfo.num_ubos; i++) {
int ubo_idx = sprog->ss[id]->sel->sinfo.ubo_idx[i];
snprintf(name, 32, "%subo%d", prefix, ubo_idx);
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(prog_id, name);
}
} else

@ -102,8 +102,13 @@ struct dump_ctx {
struct vrend_shader_sampler samplers[32];
uint32_t samplers_used;
int num_consts;
bool sviews_used;
struct vrend_sampler_array *sampler_arrays;
int num_sampler_arrays;
int last_sampler_array_idx;
int num_consts;
int num_imm;
struct immed imm[MAX_IMMEDIATE];
unsigned fragcoord_input;
@ -249,6 +254,46 @@ static struct vrend_temp_range *find_temp_range(struct dump_ctx *ctx, int index)
return NULL;
}
static int add_sampler_array(struct dump_ctx *ctx, int first, int last, int sview_type, int sview_rtype)
{
int idx = ctx->num_sampler_arrays;
ctx->num_sampler_arrays++;
ctx->sampler_arrays = realloc(ctx->sampler_arrays, sizeof(struct vrend_sampler_array) * ctx->num_sampler_arrays);
if (!ctx->sampler_arrays)
return -1;
ctx->sampler_arrays[idx].first = first;
ctx->sampler_arrays[idx].last = last;
ctx->sampler_arrays[idx].idx = idx;
ctx->sampler_arrays[idx].sview_type = sview_type;
ctx->sampler_arrays[idx].sview_rtype = sview_rtype;
return idx;
}
int lookup_sampler_array(struct dump_ctx *ctx, int index)
{
int i;
for (i = 0; i < ctx->num_sampler_arrays; i++) {
if (index >= ctx->sampler_arrays[i].first &&
index <= ctx->sampler_arrays[i].last) {
return ctx->sampler_arrays[i].idx;
}
}
return -1;
}
int shader_lookup_sampler_array(struct vrend_shader_info *sinfo, int index)
{
int i;
for (i = 0; i < sinfo->num_sampler_arrays; i++) {
if (index >= sinfo->sampler_arrays[i].first &&
index <= sinfo->sampler_arrays[i].last) {
return sinfo->sampler_arrays[i].idx;
}
}
return -1;
}
static boolean
iter_declaration(struct tgsi_iterate_context *iter,
struct tgsi_full_declaration *decl )
@ -662,6 +707,19 @@ iter_declaration(struct tgsi_iterate_context *iter,
return FALSE;
}
ctx->samplers[decl->Range.First].tgsi_sampler_return = decl->SamplerView.ReturnTypeX;
if (ctx->info.indirect_files & (1 << TGSI_FILE_SAMPLER)) {
if (ctx->last_sampler_array_idx != -1) {
if (ctx->sampler_arrays[ctx->last_sampler_array_idx].sview_type == decl->SamplerView.Resource &&
ctx->sampler_arrays[ctx->last_sampler_array_idx].sview_rtype == decl->SamplerView.ReturnTypeX) {
ctx->sampler_arrays[ctx->last_sampler_array_idx].last = decl->Range.Last + 1;
} else {
ctx->last_sampler_array_idx = add_sampler_array(ctx, decl->Range.First, decl->Range.Last + 1, decl->SamplerView.Resource, decl->SamplerView.ReturnTypeX);
}
} else {
ctx->last_sampler_array_idx = add_sampler_array(ctx, decl->Range.First, decl->Range.Last + 1, decl->SamplerView.Resource, decl->SamplerView.ReturnTypeX);
}
} else
ctx->sviews_used = true;
break;
case TGSI_FILE_CONSTANT:
if (decl->Declaration.Dimension) {
@ -681,7 +739,7 @@ iter_declaration(struct tgsi_iterate_context *iter,
}
break;
case TGSI_FILE_ADDRESS:
ctx->num_address = 1;
ctx->num_address = decl->Range.Last + 1;
break;
case TGSI_FILE_SYSTEM_VALUE:
i = ctx->num_system_values++;
@ -1770,10 +1828,14 @@ iter_instruction(struct tgsi_iterate_context *iter,
if (!range)
return FALSE;
if (dst->Register.Indirect) {
snprintf(dsts[i], 255, "temp%d[addr0 + %d]%s", range->first, dst->Register.Index - range->first, writemask);
assert(dst->Indirect.File == TGSI_FILE_ADDRESS);
snprintf(dsts[i], 255, "temp%d[addr%d + %d]%s", range->first, dst->Indirect.Index, dst->Register.Index - range->first, writemask);
} else
snprintf(dsts[i], 255, "temp%d[%d]%s", range->first, dst->Register.Index - range->first, writemask);
}
else if (dst->Register.File == TGSI_FILE_ADDRESS) {
snprintf(dsts[i], 255, "addr%d", dst->Register.Index);
}
}
for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
@ -1793,8 +1855,13 @@ iter_instruction(struct tgsi_iterate_context *iter,
if (isabsolute)
strcpy(&prefix[pre_idx++], "abs(");
if (src->Register.Dimension)
sprintf(arrayname, "[%d]", src->Dimension.Index);
if (src->Register.Dimension) {
if (src->Dimension.Indirect) {
assert(src->DimIndirect.File == TGSI_FILE_ADDRESS);
sprintf(arrayname, "[addr%d]", src->DimIndirect.Index);
} else
sprintf(arrayname, "[%d]", src->Dimension.Index);
}
if (src->Register.SwizzleX != TGSI_SWIZZLE_X ||
src->Register.SwizzleY != TGSI_SWIZZLE_Y ||
@ -1857,7 +1924,8 @@ iter_instruction(struct tgsi_iterate_context *iter,
}
if (src->Register.Indirect) {
snprintf(srcs[i], 255, "%s%c%stemp%d[addr0 + %d]%s%c", stypeprefix, stprefix ? '(' : ' ', prefix, range->first, src->Register.Index - range->first, swizzle, stprefix ? ')' : ' ');
assert(src->Indirect.File == TGSI_FILE_ADDRESS);
snprintf(srcs[i], 255, "%s%c%stemp%d[addr%d + %d]%s%c", stypeprefix, stprefix ? '(' : ' ', prefix, range->first, src->Indirect.Index, src->Register.Index - range->first, swizzle, stprefix ? ')' : ' ');
} else
snprintf(srcs[i], 255, "%s%c%stemp%d[%d]%s%c", stypeprefix, stprefix ? '(' : ' ', prefix, range->first, src->Register.Index - range->first, swizzle, stprefix ? ')' : ' ');
} else if (src->Register.File == TGSI_FILE_CONSTANT) {
@ -1865,10 +1933,27 @@ iter_instruction(struct tgsi_iterate_context *iter,
int dim = 0;
if (src->Register.Dimension) {
dim = src->Dimension.Index;
if (src->Register.Indirect) {
snprintf(srcs[i], 255, "%s(%s%subo%dcontents[addr0 + %d]%s)", stypeprefix, prefix, cname, dim, src->Register.Index, swizzle);
} else
snprintf(srcs[i], 255, "%s(%s%subo%dcontents[%d]%s)", stypeprefix, prefix, cname, dim, src->Register.Index, swizzle);
if (src->Dimension.Indirect) {
assert(src->DimIndirect.File == TGSI_FILE_ADDRESS);
ctx->uses_gpu_shader5 = true;
if (src->Register.Indirect) {
assert(src->Indirect.File == TGSI_FILE_ADDRESS);
snprintf(srcs[i], 255, "%s(%s%suboarr[addr%d].ubocontents[addr%d + %d]%s)", stypeprefix, prefix, cname, src->DimIndirect.Index, src->Indirect.Index, src->Register.Index, swizzle);
} else
snprintf(srcs[i], 255, "%s(%s%suboarr[addr%d].ubocontents[%d]%s)", stypeprefix, prefix, cname, src->DimIndirect.Index, src->Register.Index, swizzle);
} else {
if (ctx->info.dimension_indirect_files & (1 << TGSI_FILE_CONSTANT)) {
if (src->Register.Indirect) {
snprintf(srcs[i], 255, "%s(%s%suboarr[%d].ubocontents[addr%d + %d]%s)", stypeprefix, prefix, cname, dim, src->Indirect.Index, src->Register.Index, swizzle);
} else
snprintf(srcs[i], 255, "%s(%s%suboarr[%d].ubocontents[%d]%s)", stypeprefix, prefix, cname, dim, src->Register.Index, swizzle);
} else {
if (src->Register.Indirect) {
snprintf(srcs[i], 255, "%s(%s%subo%dcontents[addr0 + %d]%s)", stypeprefix, prefix, cname, dim, src->Register.Index, swizzle);
} else
snprintf(srcs[i], 255, "%s(%s%subo%dcontents[%d]%s)", stypeprefix, prefix, cname, dim, src->Register.Index, swizzle);
}
}
} else {
const char *csp;
ctx->has_ints = true;
@ -1888,7 +1973,17 @@ iter_instruction(struct tgsi_iterate_context *iter,
}
} else if (src->Register.File == TGSI_FILE_SAMPLER) {
const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
snprintf(srcs[i], 255, "%ssamp%d%s", cname, src->Register.Index, swizzle);
if (ctx->info.indirect_files & (1 << TGSI_FILE_SAMPLER)) {
int arr_idx = lookup_sampler_array(ctx, src->Register.Index);
if (src->Register.Indirect) {
snprintf(srcs[i], 255, "%ssamp%d[addr%d+%d]%s", cname, arr_idx, src->Indirect.Index, src->Register.Index - ctx->sampler_arrays[arr_idx].first, swizzle);
} else {
snprintf(srcs[i], 255, "%ssamp%d[%d]%s", cname, arr_idx, src->Register.Index - ctx->sampler_arrays[arr_idx].first, swizzle);
}
} else {
snprintf(srcs[i], 255, "%ssamp%d%s", cname, src->Register.Index, swizzle);
}
sreg_index = src->Register.Index;
} else if (src->Register.File == TGSI_FILE_IMMEDIATE) {
if (src->Register.Index >= ARRAY_SIZE(ctx->imm)) {
@ -2325,11 +2420,11 @@ iter_instruction(struct tgsi_iterate_context *iter,
EMIT_BUF_WITH_RET(ctx, "return;\n");
break;
case TGSI_OPCODE_ARL:
snprintf(buf, 255, "addr0 = int(floor(%s)%s);\n", srcs[0], writemask);
snprintf(buf, 255, "%s = int(floor(%s)%s);\n", dsts[0], srcs[0], writemask);
EMIT_BUF_WITH_RET(ctx, buf);
break;
case TGSI_OPCODE_UARL:
snprintf(buf, 255, "addr0 = int(%s);\n", srcs[0]);
snprintf(buf, 255, "%s = int(%s);\n", dsts[0], srcs[0]);
EMIT_BUF_WITH_RET(ctx, buf);
break;
case TGSI_OPCODE_XPD:
@ -2597,6 +2692,15 @@ static const char *get_aux_string(struct vrend_shader_cfg *cfg, bool centroid)
return centroid ? "centroid " : "";
}
static const char get_return_type_prefix(enum tgsi_return_type type)
{
if (type == TGSI_RETURN_TYPE_SINT)
return 'i';
if (type == TGSI_RETURN_TYPE_UINT)
return 'u';
return ' ';
}
static char *emit_ios(struct dump_ctx *ctx, char *glsl_hdr)
{
int i;
@ -2855,27 +2959,49 @@ static char *emit_ios(struct dump_ctx *ctx, char *glsl_hdr)
}
}
if (ctx->num_ubo) {
for (i = 0; i < ctx->num_ubo; i++) {
const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
snprintf(buf, 255, "uniform %subo%d { vec4 %subo%dcontents[%d]; };\n", cname, ctx->ubo_idx[i], cname, ctx->ubo_idx[i], ctx->ubo_sizes[i]);
const char *cname = tgsi_proc_to_prefix(ctx->prog_type);
if (ctx->info.dimension_indirect_files & (1 << TGSI_FILE_CONSTANT)) {
ctx->glsl_ver_required = 150;
snprintf(buf, 255, "uniform %subo { vec4 ubocontents[%d]; } %suboarr[%d];\n", cname, ctx->ubo_sizes[0], cname, ctx->num_ubo);
STRCAT_WITH_RET(glsl_hdr, buf);
} else {
for (i = 0; i < ctx->num_ubo; i++) {
snprintf(buf, 255, "uniform %subo%d { vec4 %subo%dcontents[%d]; };\n", cname, ctx->ubo_idx[i], cname, ctx->ubo_idx[i], ctx->ubo_sizes[i]);
STRCAT_WITH_RET(glsl_hdr, buf);
}
}
}
for (i = 0; i < 32; i++) {
int is_shad = 0;
const char *stc;
char ptc;
if ((ctx->samplers_used & (1 << i)) == 0)
continue;
if (ctx->info.indirect_files & (1 << TGSI_FILE_SAMPLER)) {
for (i = 0; i < ctx->num_sampler_arrays; i++) {
int is_shad = 0;
const char *stc;
stc = vrend_shader_samplertypeconv(ctx->sampler_arrays[i].sview_type, &is_shad);
if (!stc)
continue;
snprintf(buf, 255, "uniform %csampler%s %ssamp%d[%d];\n",
get_return_type_prefix(ctx->sampler_arrays[i].sview_rtype),
stc, sname, ctx->sampler_arrays[i].idx,
ctx->sampler_arrays[i].last - ctx->sampler_arrays[i].first);
STRCAT_WITH_RET(glsl_hdr, buf);
}
} else {
nsamp = util_last_bit(ctx->samplers_used);
for (i = 0; i < nsamp; i++) {
int is_shad = 0;
const char *stc;
char ptc;
ptc = vrend_shader_samplerreturnconv(ctx->samplers[i].tgsi_sampler_return);
stc = vrend_shader_samplertypeconv(ctx->samplers[i].tgsi_sampler_type, &is_shad);
if ((ctx->samplers_used & (1 << i)) == 0)
continue;
if (stc) {
const char *sname;
const char *precision;
ptc = vrend_shader_samplerreturnconv(ctx->samplers[i].tgsi_sampler_return);
stc = vrend_shader_samplertypeconv(ctx->samplers[i].tgsi_sampler_type, &is_shad);
sname = tgsi_proc_to_prefix(ctx->prog_type);
if (ctx->cfg->use_gles) {
@ -2979,7 +3105,9 @@ char *vrend_convert_shader(struct vrend_shader_cfg *cfg,
ctx.key = key;
ctx.cfg = cfg;
ctx.prog_type = -1;
ctx.num_sampler_arrays = 0;
ctx.sampler_arrays = NULL;
ctx.last_sampler_array_idx = -1;
tgsi_scan_shader(tokens, &ctx.info);
/* if we are in core profile mode we should use GLSL 1.40 */
if (cfg->use_core_profile && cfg->glsl_version >= 140)
@ -2993,6 +3121,12 @@ char *vrend_convert_shader(struct vrend_shader_cfg *cfg,
} else
ctx.so_names = NULL;
if (ctx.info.dimension_indirect_files & (1 << TGSI_FILE_CONSTANT))
ctx.glsl_ver_required = 150;
if (ctx.info.indirect_files & (1 << TGSI_FILE_SAMPLER))
ctx.uses_gpu_shader5 = true;
ctx.glsl_main = malloc(4096);
if (!ctx.glsl_main)
goto fail;
@ -3040,6 +3174,7 @@ char *vrend_convert_shader(struct vrend_shader_cfg *cfg,
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_indirect = ctx.info.dimension_indirect_files & (1 << TGSI_FILE_CONSTANT);
sinfo->num_inputs = ctx.num_inputs;
sinfo->num_interps = ctx.num_interps;
sinfo->num_outputs = ctx.num_outputs;
@ -3048,6 +3183,8 @@ char *vrend_convert_shader(struct vrend_shader_cfg *cfg,
sinfo->gs_out_prim = ctx.gs_out_prim;
sinfo->so_names = ctx.so_names;
sinfo->attrib_input_mask = ctx.attrib_input_mask;
sinfo->sampler_arrays = ctx.sampler_arrays;
sinfo->num_sampler_arrays = ctx.num_sampler_arrays;
return glsl_final;
fail:
free(ctx.glsl_main);

@ -35,6 +35,14 @@ struct vrend_interp_info {
bool centroid;
};
struct vrend_sampler_array {
int first;
int last;
int idx;
int sview_type;
int sview_rtype;
};
struct vrend_shader_info {
uint32_t samplers_used_mask;
int num_consts;
@ -43,6 +51,7 @@ struct vrend_shader_info {
int num_outputs;
int num_ubos;
int ubo_idx[32];
bool ubo_indirect;
int num_ucp;
int glsl_ver;
bool has_pervertex_out;
@ -51,6 +60,10 @@ struct vrend_shader_info {
uint32_t shadow_samp_mask;
int gs_out_prim;
uint32_t attrib_input_mask;
struct vrend_sampler_array *sampler_arrays;
int num_sampler_arrays;
struct pipe_stream_output_info so_info;
struct vrend_interp_info *interpinfo;
@ -92,4 +105,6 @@ char *vrend_convert_shader(struct vrend_shader_cfg *cfg,
struct vrend_shader_key *key,
struct vrend_shader_info *sinfo);
const char *vrend_shader_samplertypeconv(int sampler_type, int *is_shad);
int shader_lookup_sampler_array(struct vrend_shader_info *sinfo, int index);
#endif

Loading…
Cancel
Save