On 13.11.2015 00:14, Glenn Kennard wrote:
Signed-off-by: Glenn Kennard <glenn.kenn...@gmail.com>
---
Maybe there is a better way to check if a thread is a helper invocation?

Is ctx->face_gpr guaranteed to be initialized when load_helper_invocation is called?

Aside, I'm not sure I understand correctly what this is supposed to do. The values you're querying are related to multi-sampling, but my understanding has always been that helper invocations can also happen without multi-sampling: you always want to process 2x2 quads of pixels at a time to be able to compute derivatives for texture sampling. When the boundary of primitive intersects such a quad, you get helper invocations outside the primitive.

Cheers,
Nicolai

  src/gallium/drivers/r600/r600_shader.c | 83 +++++++++++++++++++++++++++++-----
  1 file changed, 72 insertions(+), 11 deletions(-)

diff --git a/src/gallium/drivers/r600/r600_shader.c 
b/src/gallium/drivers/r600/r600_shader.c
index 560197c..a227d78 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -530,7 +530,8 @@ static int r600_spi_sid(struct r600_shader_io * io)
            name == TGSI_SEMANTIC_PSIZE ||
            name == TGSI_SEMANTIC_EDGEFLAG ||
            name == TGSI_SEMANTIC_FACE ||
-           name == TGSI_SEMANTIC_SAMPLEMASK)
+           name == TGSI_SEMANTIC_SAMPLEMASK ||
+           name == TGSI_SEMANTIC_HELPER_INVOCATION)
                index = 0;
        else {
                if (name == TGSI_SEMANTIC_GENERIC) {
@@ -734,7 +735,8 @@ static int tgsi_declaration(struct r600_shader_ctx *ctx)
        case TGSI_FILE_SYSTEM_VALUE:
                if (d->Semantic.Name == TGSI_SEMANTIC_SAMPLEMASK ||
                        d->Semantic.Name == TGSI_SEMANTIC_SAMPLEID ||
-                       d->Semantic.Name == TGSI_SEMANTIC_SAMPLEPOS) {
+                       d->Semantic.Name == TGSI_SEMANTIC_SAMPLEPOS ||
+                       d->Semantic.Name == TGSI_SEMANTIC_HELPER_INVOCATION) {
                        break; /* Already handled from 
allocate_system_value_inputs */
                } else if (d->Semantic.Name == TGSI_SEMANTIC_INSTANCEID) {
                        if (!ctx->native_integers) {
@@ -776,13 +778,14 @@ static int allocate_system_value_inputs(struct 
r600_shader_ctx *ctx, int gpr_off
        struct {
                boolean enabled;
                int *reg;
-               unsigned name, alternate_name;
+               unsigned associated_semantics[3];
        } inputs[2] = {
-               { false, &ctx->face_gpr, TGSI_SEMANTIC_SAMPLEMASK, ~0u }, /* 
lives in Front Face GPR.z */
-
-               { false, &ctx->fixed_pt_position_gpr, TGSI_SEMANTIC_SAMPLEID, 
TGSI_SEMANTIC_SAMPLEPOS } /* SAMPLEID is in Fixed Point Position GPR.w */
+               { false, &ctx->face_gpr, { TGSI_SEMANTIC_SAMPLEMASK /* lives in 
Front Face GPR.z */,
+                       TGSI_SEMANTIC_HELPER_INVOCATION, ~0u } },
+               { false, &ctx->fixed_pt_position_gpr, { TGSI_SEMANTIC_SAMPLEID  
/* in Fixed Point Position GPR.w */,
+                       TGSI_SEMANTIC_SAMPLEPOS, 
TGSI_SEMANTIC_HELPER_INVOCATION } }
        };
-       int i, k, num_regs = 0;
+       int i, k, l, num_regs = 0;

        if (tgsi_parse_init(&parse, ctx->tokens) != TGSI_PARSE_OK) {
                return 0;
@@ -818,9 +821,11 @@ static int allocate_system_value_inputs(struct 
r600_shader_ctx *ctx, int gpr_off
                        struct tgsi_full_declaration *d = 
&parse.FullToken.FullDeclaration;
                        if (d->Declaration.File == TGSI_FILE_SYSTEM_VALUE) {
                                for (k = 0; k < Elements(inputs); k++) {
-                                       if (d->Semantic.Name == inputs[k].name 
||
-                                               d->Semantic.Name == 
inputs[k].alternate_name) {
-                                               inputs[k].enabled = true;
+                                       for (l = 0; l < 3; l++) {
+                                               if (d->Semantic.Name == 
inputs[k].associated_semantics[l]) {
+                                                       inputs[k].enabled = 
true;
+                                                       break;
+                                               }
                                        }
                                }
                        }
@@ -832,7 +837,7 @@ static int allocate_system_value_inputs(struct 
r600_shader_ctx *ctx, int gpr_off
        for (i = 0; i < Elements(inputs); i++) {
                boolean enabled = inputs[i].enabled;
                int *reg = inputs[i].reg;
-               unsigned name = inputs[i].name;
+               unsigned name = inputs[i].associated_semantics[0];

                if (enabled) {
                        int gpr = gpr_offset + num_regs++;
@@ -985,6 +990,56 @@ static int load_sample_position(struct r600_shader_ctx 
*ctx, struct r600_shader_
        return t1;
  }

+static int load_helper_invocation(struct r600_shader_ctx *ctx,
+       int mask_gpr, int mask_chan, int id_gpr, int id_chan)
+{
+       // sample (mask >> sampleid) & 1
+       struct r600_bytecode_alu alu;
+       int r, t = r600_get_temp(ctx);
+
+       memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+       alu.op = ALU_OP2_LSHR_INT;
+       alu.src[0].sel = mask_gpr;
+       alu.src[0].chan = mask_chan;
+       alu.src[1].sel = id_gpr;
+       alu.src[1].chan = id_chan;
+       alu.dst.sel = t;
+       alu.dst.chan = 0;
+       alu.dst.write = 1;
+       alu.last = 1;
+       r = r600_bytecode_add_alu(ctx->bc, &alu);
+       if (r)
+               return r;
+
+       memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+       alu.op = ALU_OP2_AND_INT;
+       alu.src[0].sel = t;
+       alu.src[0].chan = 0;
+       alu.src[1].sel = V_SQ_ALU_SRC_1_INT;
+       alu.dst.sel = t;
+       alu.dst.chan = 0;
+       alu.dst.write = 1;
+       alu.last = 1;
+       r = r600_bytecode_add_alu(ctx->bc, &alu);
+       if (r)
+               return r;
+
+       memset(&alu, 0, sizeof(struct r600_bytecode_alu));
+       alu.op = ALU_OP2_SUB_INT;
+       alu.src[0].sel = t;
+       alu.src[0].chan = 0;
+       alu.src[1].sel = V_SQ_ALU_SRC_1_INT;
+       alu.dst.sel = t;
+       alu.dst.chan = 0;
+       alu.dst.write = 1;
+       alu.last = 1;
+       r = r600_bytecode_add_alu(ctx->bc, &alu);
+       if (r)
+               return r;
+
+       return t;
+}
+
  static void tgsi_src(struct r600_shader_ctx *ctx,
                     const struct tgsi_full_src_register *tgsi_src,
                     struct r600_shader_src *r600_src)
@@ -1048,6 +1103,12 @@ static void tgsi_src(struct r600_shader_ctx *ctx,
                        r600_src->swizzle[2] = 3;
                        r600_src->swizzle[3] = 3;
                        r600_src->sel = 1;
+               } else if 
(ctx->info.system_value_semantic_name[tgsi_src->Register.Index] == 
TGSI_SEMANTIC_HELPER_INVOCATION) {
+                       r600_src->swizzle[0] = 0;
+                       r600_src->swizzle[1] = 0;
+                       r600_src->swizzle[2] = 0;
+                       r600_src->swizzle[3] = 0;
+                       r600_src->sel = load_helper_invocation(ctx, ctx->face_gpr, 
2, ctx->fixed_pt_position_gpr, 3);
                }
        } else {
                if (tgsi_src->Register.Indirect)


_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to