summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/broadcom/compiler/v3d_compiler.h5
-rw-r--r--src/broadcom/compiler/vir.c33
-rw-r--r--src/gallium/drivers/vc5/vc5_context.h7
-rw-r--r--src/gallium/drivers/vc5/vc5_program.c9
4 files changed, 54 insertions, 0 deletions
diff --git a/src/broadcom/compiler/v3d_compiler.h b/src/broadcom/compiler/v3d_compiler.h
index df81f0757e2..207e29733aa 100644
--- a/src/broadcom/compiler/v3d_compiler.h
+++ b/src/broadcom/compiler/v3d_compiler.h
@@ -336,6 +336,11 @@ struct v3d_fs_key {
uint8_t swap_color_rb;
/* Mask of which render targets need to be written as 32-bit floats */
uint8_t f32_color_rb;
+ /* Masks of which render targets need to be written as ints/uints.
+ * Used by gallium to work around lost information in TGSI.
+ */
+ uint8_t int_color_rb;
+ uint8_t uint_color_rb;
uint8_t alpha_test_func;
uint8_t logicop_func;
uint32_t point_sprite_mask;
diff --git a/src/broadcom/compiler/vir.c b/src/broadcom/compiler/vir.c
index 05f557fbcd0..ff9405e6c12 100644
--- a/src/broadcom/compiler/vir.c
+++ b/src/broadcom/compiler/vir.c
@@ -756,6 +756,36 @@ v3d_set_fs_prog_data_inputs(struct v3d_compile *c,
}
}
+static void
+v3d_fixup_fs_output_types(struct v3d_compile *c)
+{
+ nir_foreach_variable(var, &c->s->outputs) {
+ uint32_t mask = 0;
+
+ switch (var->data.location) {
+ case FRAG_RESULT_COLOR:
+ mask = ~0;
+ break;
+ case FRAG_RESULT_DATA0:
+ case FRAG_RESULT_DATA1:
+ case FRAG_RESULT_DATA2:
+ case FRAG_RESULT_DATA3:
+ mask = 1 << (var->data.location - FRAG_RESULT_DATA0);
+ break;
+ }
+
+ if (c->fs_key->int_color_rb & mask) {
+ var->type =
+ glsl_vector_type(GLSL_TYPE_INT,
+ glsl_get_components(var->type));
+ } else if (c->fs_key->uint_color_rb & mask) {
+ var->type =
+ glsl_vector_type(GLSL_TYPE_UINT,
+ glsl_get_components(var->type));
+ }
+ }
+}
+
uint64_t *v3d_compile_fs(const struct v3d_compiler *compiler,
struct v3d_fs_key *key,
struct v3d_fs_prog_data *prog_data,
@@ -768,6 +798,9 @@ uint64_t *v3d_compile_fs(const struct v3d_compiler *compiler,
c->fs_key = key;
+ if (key->int_color_rb || key->uint_color_rb)
+ v3d_fixup_fs_output_types(c);
+
v3d_lower_nir(c);
if (key->light_twoside)
diff --git a/src/gallium/drivers/vc5/vc5_context.h b/src/gallium/drivers/vc5/vc5_context.h
index 28b2e165a9d..1ab5a6b1532 100644
--- a/src/gallium/drivers/vc5/vc5_context.h
+++ b/src/gallium/drivers/vc5/vc5_context.h
@@ -132,6 +132,13 @@ struct vc5_uncompiled_shader {
struct v3d_varying_slot *tf_outputs;
uint16_t tf_specs[PIPE_MAX_SO_BUFFERS];
uint32_t num_tf_specs;
+
+ /**
+ * Flag for if the NIR in this shader originally came from TGSI. If
+ * so, we need to do some fixups at compile time, due to missing
+ * information in TGSI that exists in NIR.
+ */
+ bool was_tgsi;
};
struct vc5_compiled_shader {
diff --git a/src/gallium/drivers/vc5/vc5_program.c b/src/gallium/drivers/vc5/vc5_program.c
index ae3850a64b3..87c21abe8b1 100644
--- a/src/gallium/drivers/vc5/vc5_program.c
+++ b/src/gallium/drivers/vc5/vc5_program.c
@@ -170,6 +170,8 @@ vc5_shader_state_create(struct pipe_context *pctx,
fprintf(stderr, "\n");
}
s = tgsi_to_nir(cso->tokens, &v3d_nir_options);
+
+ so->was_tgsi = true;
}
NIR_PASS_V(s, nir_opt_global_to_local);
@@ -414,6 +416,13 @@ vc5_update_compiled_fs(struct vc5_context *vc5, uint8_t prim_mode)
desc->channel[0].size == 32) {
key->f32_color_rb |= 1 << i;
}
+
+ if (vc5->prog.bind_fs->was_tgsi) {
+ if (util_format_is_pure_uint(cbuf->format))
+ key->uint_color_rb |= 1 << i;
+ else if (util_format_is_pure_sint(cbuf->format))
+ key->int_color_rb |= 1 << i;
+ }
}
if (key->is_points) {