radv: handle layer export from vs->fs properly
authorDave Airlie <airlied@redhat.com>
Mon, 30 Jan 2017 19:56:49 +0000 (05:56 +1000)
committerDave Airlie <airlied@redhat.com>
Mon, 30 Jan 2017 23:30:49 +0000 (09:30 +1000)
Fixes:
dEQP-VK.geometry.layered.1d_array.fragment_layer

Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Signed-off-by: Dave Airlie <airlied@redhat.com>
src/amd/common/ac_nir_to_llvm.c
src/amd/common/ac_nir_to_llvm.h
src/amd/vulkan/radv_cmd_buffer.c

index 15ea727755a432796989956cfcc07f547e58c7d1..cdcc154fc028d90c168ccd7619a4e87f312e6d8e 100644 (file)
@@ -4114,7 +4114,7 @@ handle_fs_inputs_pre(struct nir_to_llvm_context *ctx,
                        continue;
 
                if (i >= VARYING_SLOT_VAR0 || i == VARYING_SLOT_PNTC ||
-                   i == VARYING_SLOT_PRIMITIVE_ID) {
+                   i == VARYING_SLOT_PRIMITIVE_ID || i == VARYING_SLOT_LAYER) {
                        interp_param = *inputs;
                        interp_fs_input(ctx, index, interp_param, ctx->prim_mask,
                                        inputs);
@@ -4134,6 +4134,8 @@ handle_fs_inputs_pre(struct nir_to_llvm_context *ctx,
                ctx->shader_info->fs.has_pcoord = true;
        if (ctx->input_mask & (1 << VARYING_SLOT_PRIMITIVE_ID))
                ctx->shader_info->fs.prim_id_input = true;
+       if (ctx->input_mask & (1 << VARYING_SLOT_LAYER))
+               ctx->shader_info->fs.layer_input = true;
        ctx->shader_info->fs.input_mask = ctx->input_mask >> VARYING_SLOT_VAR0;
 }
 
@@ -4422,6 +4424,7 @@ handle_vs_outputs_post(struct nir_to_llvm_context *ctx)
                                                       (1ull << VARYING_SLOT_CULL_DIST1));
 
        ctx->shader_info->vs.prim_id_output = 0xffffffff;
+       ctx->shader_info->vs.layer_output = 0xffffffff;
        if (clip_mask) {
                LLVMValueRef slots[8];
                unsigned j;
@@ -4478,7 +4481,9 @@ handle_vs_outputs_post(struct nir_to_llvm_context *ctx)
                } else if (i == VARYING_SLOT_LAYER) {
                        ctx->shader_info->vs.writes_layer = true;
                        layer_value = values[0];
-                       continue;
+                       ctx->shader_info->vs.layer_output = param_count;
+                       target = V_008DFC_SQ_EXP_PARAM + param_count;
+                       param_count++;
                } else if (i == VARYING_SLOT_VIEWPORT) {
                        ctx->shader_info->vs.writes_viewport_index = true;
                        viewport_index_value = values[0];
index 4a6572d5d7c1d53ca6c173f8646df14bc68d28b8..c2662e2fe9caa4b528173d3462bdb226d4d10146 100644 (file)
@@ -107,6 +107,7 @@ struct ac_shader_variant_info {
                        uint8_t cull_dist_mask;
                        uint32_t esgs_itemsize;
                        uint32_t prim_id_output;
+                       uint32_t layer_output;
                } vs;
                struct {
                        unsigned num_interp;
@@ -121,6 +122,7 @@ struct ac_shader_variant_info {
                        bool writes_memory;
                        bool force_persample;
                        bool prim_id_input;
+                       bool layer_input;
                } fs;
                struct {
                        unsigned block_size[3];
index ad28c93a51296f49c65f017ecd3a6b512d26191c..091d970ee0ba6e65deaeec9a7ec72ba93235bfe9 100644 (file)
@@ -718,6 +718,16 @@ radv_emit_fragment_shader(struct radv_cmd_buffer *cmd_buffer,
                ++ps_offset;
        }
 
+       if (ps->info.fs.layer_input && (vs->info.vs.layer_output != 0xffffffff)) {
+               unsigned vs_offset, flat_shade;
+               unsigned val;
+               vs_offset = vs->info.vs.layer_output;
+               flat_shade = true;
+               val = S_028644_OFFSET(vs_offset) | S_028644_FLAT_SHADE(flat_shade);
+               radeon_set_context_reg(cmd_buffer->cs, R_028644_SPI_PS_INPUT_CNTL_0 + 4 * ps_offset, val);
+               ++ps_offset;
+       }
+
        for (unsigned i = 0; i < 32 && (1u << i) <= ps->info.fs.input_mask; ++i) {
                unsigned vs_offset, flat_shade;
                unsigned val;
@@ -738,6 +748,10 @@ radv_emit_fragment_shader(struct radv_cmd_buffer *cmd_buffer,
                        if (vs_offset >= vs->info.vs.prim_id_output)
                                vs_offset++;
                }
+               if (vs->info.vs.layer_output != 0xffffffff) {
+                       if (vs_offset >= vs->info.vs.layer_output)
+                         vs_offset++;
+               }
                flat_shade = !!(ps->info.fs.flat_shaded_mask & (1u << ps_offset));
 
                val = S_028644_OFFSET(vs_offset) | S_028644_FLAT_SHADE(flat_shade);