summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2015-12-21 15:51:18 +1000
committerDave Airlie <airlied@redhat.com>2016-02-19 11:17:27 +1000
commit5ad3a61657294094e0abc35adba4339627622bd1 (patch)
treee97fd835e6ad817072a069a62a7cea45e9886bb9
parentbd09a39fc9471b3db36f36424b4064e434a9fe89 (diff)
handle sampler rrays
-rw-r--r--src/vrend_renderer.c6
-rw-r--r--src/vrend_shader.c139
-rw-r--r--src/vrend_shader.h13
3 files changed, 138 insertions, 20 deletions
diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c
index f21cf59..9ccbf52 100644
--- a/src/vrend_renderer.c
+++ b/src/vrend_renderer.c
@@ -924,7 +924,11 @@ static struct vrend_linked_shader_program *add_shader_program(struct vrend_conte
index = 0;
while(mask) {
i = u_bit_scan(&mask);
- snprintf(name, 10, "%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, 14, "%ssamp%d[%d]", prefix, arr_idx, i - sprog->ss[id]->sel->sinfo.sampler_arrays[arr_idx].first);
+ } else
+ snprintf(name, 10, "%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, 14, "%sshadmask%d", prefix, i);
diff --git a/src/vrend_shader.c b/src/vrend_shader.c
index 63e6861..f3e6331 100644
--- a/src/vrend_shader.c
+++ b/src/vrend_shader.c
@@ -96,8 +96,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;
@@ -237,6 +242,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 )
@@ -573,6 +618,19 @@ iter_declaration(struct tgsi_iterate_context *iter,
ctx->samplers_used |= (1 << decl->Range.Last);
break;
case TGSI_FILE_SAMPLER_VIEW:
+ 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) {
@@ -1566,7 +1624,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) {
struct immed *imd = &ctx->imm[(src->Register.Index)];
@@ -2247,6 +2315,15 @@ static const char *get_interp_string(int interpolate, bool flatshade)
}
}
+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;
@@ -2254,6 +2331,8 @@ static char *emit_ios(struct dump_ctx *ctx, char *glsl_hdr)
char postfix[8];
const char *prefix = "";
bool fcolor_emitted[2], bcolor_emitted[2];
+ int nsamp;
+ const char *sname = tgsi_proc_to_prefix(ctx->prog_type);
ctx->num_interps = 0;
if (ctx->key->color_two_side) {
@@ -2443,27 +2522,42 @@ static char *emit_ios(struct dump_ctx *ctx, char *glsl_hdr)
STRCAT_WITH_RET(glsl_hdr, buf);
}
}
- for (i = 0; i < 32; i++) {
- int is_shad = 0;
- const char *stc;
- 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;
- 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;
+ stc = vrend_shader_samplertypeconv(ctx->samplers[i].tgsi_sampler_type, &is_shad);
- sname = tgsi_proc_to_prefix(ctx->prog_type);
- snprintf(buf, 255, "uniform sampler%s %ssamp%d;\n", stc, sname, i);
- STRCAT_WITH_RET(glsl_hdr, buf);
- if (is_shad) {
- snprintf(buf, 255, "uniform vec4 %sshadmask%d;\n", sname, i);
- STRCAT_WITH_RET(glsl_hdr, buf);
- snprintf(buf, 255, "uniform vec4 %sshadadd%d;\n", sname, i);
+ if (stc) {
+
+ snprintf(buf, 255, "uniform sampler%s %ssamp%d;\n", stc, sname, i);
STRCAT_WITH_RET(glsl_hdr, buf);
- ctx->shadow_samp_mask |= (1 << i);
+ if (is_shad) {
+ snprintf(buf, 255, "uniform vec4 %sshadmask%d;\n", sname, i);
+ STRCAT_WITH_RET(glsl_hdr, buf);
+ snprintf(buf, 255, "uniform vec4 %sshadadd%d;\n", sname, i);
+ STRCAT_WITH_RET(glsl_hdr, buf);
+ ctx->shadow_samp_mask |= (1 << i);
+ }
}
}
}
@@ -2543,7 +2637,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)
@@ -2560,6 +2656,9 @@ char *vrend_convert_shader(struct vrend_shader_cfg *cfg,
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;
@@ -2610,6 +2709,8 @@ char *vrend_convert_shader(struct vrend_shader_cfg *cfg,
sinfo->glsl_ver = ctx.glsl_ver_required;
sinfo->gs_out_prim = ctx.gs_out_prim;
sinfo->so_names = ctx.so_names;
+ sinfo->sampler_arrays = ctx.sampler_arrays;
+ sinfo->num_sampler_arrays = ctx.num_sampler_arrays;
return glsl_final;
fail:
free(ctx.glsl_main);
diff --git a/src/vrend_shader.h b/src/vrend_shader.h
index 6614f37..5f42d23 100644
--- a/src/vrend_shader.h
+++ b/src/vrend_shader.h
@@ -34,6 +34,14 @@ struct vrend_interp_info {
int interpolate;
};
+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;
@@ -47,6 +55,9 @@ struct vrend_shader_info {
uint32_t shadow_samp_mask;
int gs_out_prim;
+ struct vrend_sampler_array *sampler_arrays;
+ int num_sampler_arrays;
+
struct pipe_stream_output_info so_info;
struct vrend_interp_info *interpinfo;
@@ -83,4 +94,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