radv: emit framebuffer state from primary if secondary doesn't inherit it
[mesa.git] / src / amd / vulkan / radv_shader_info.c
index 24b7b4510dd7c6b4c9388b89f257fc6a761abdbc..e771ad79878255158f37a903e19f4015ff4005ee 100644 (file)
@@ -59,9 +59,7 @@ get_deref_offset(nir_deref_instr *instr,
 
        if (var->data.compact) {
                assert(instr->deref_type == nir_deref_type_array);
-               nir_const_value *v = nir_src_as_const_value(instr->arr.index);
-               assert(v);
-               *const_out = v->u32[0];
+               *const_out = nir_src_as_uint(instr->arr.index);
                return;
        }
 
@@ -80,9 +78,8 @@ get_deref_offset(nir_deref_instr *instr,
                        }
                } else if(path.path[idx_lvl]->deref_type == nir_deref_type_array) {
                        unsigned size = glsl_count_attribute_slots(path.path[idx_lvl]->type, false);
-                       nir_const_value *v = nir_src_as_const_value(path.path[idx_lvl]->arr.index);
-                       if (v)
-                               const_offset += v->u32[0] * size;
+                       if (nir_src_is_const(path.path[idx_lvl]->arr.index))
+                               const_offset += nir_src_as_uint(path.path[idx_lvl]->arr.index) * size;
                } else
                        unreachable("Uhandled deref type in get_deref_instr_offset");
        }
@@ -115,6 +112,15 @@ gather_intrinsic_load_deref_info(const nir_shader *nir,
        }
 }
 
+static uint32_t
+widen_writemask(uint32_t wrmask)
+{
+       uint32_t new_wrmask = 0;
+       for(unsigned i = 0; i < 4; i++)
+               new_wrmask |= (wrmask & (1 << i) ? 0x3 : 0x0) << (i * 2);
+       return new_wrmask;
+}
+
 static void
 set_output_usage_mask(const nir_shader *nir, const nir_intrinsic_instr *instr,
                      uint8_t *output_usage_mask)
@@ -122,25 +128,27 @@ set_output_usage_mask(const nir_shader *nir, const nir_intrinsic_instr *instr,
        nir_deref_instr *deref_instr =
                nir_instr_as_deref(instr->src[0].ssa->parent_instr);
        nir_variable *var = nir_deref_instr_get_variable(deref_instr);
-       unsigned attrib_count = glsl_count_attribute_slots(var->type, false);
+       unsigned attrib_count = glsl_count_attribute_slots(deref_instr->type, false);
        unsigned idx = var->data.location;
        unsigned comp = var->data.location_frac;
        unsigned const_offset = 0;
 
        get_deref_offset(deref_instr, &const_offset);
 
-       if (idx == VARYING_SLOT_CLIP_DIST0) {
-               /* Special case for clip/cull distances because there are
-                * combined into a single array that contains both.
-                */
-               output_usage_mask[idx] |= 1 << const_offset;
+       if (var->data.compact) {
+               assert(!glsl_type_is_64bit(deref_instr->type));
+               const_offset += comp;
+               output_usage_mask[idx + const_offset / 4] |= 1 << (const_offset % 4);
                return;
        }
 
-       for (unsigned i = 0; i < attrib_count; i++) {
+       uint32_t wrmask = nir_intrinsic_write_mask(instr);
+       if (glsl_type_is_64bit(deref_instr->type))
+               wrmask = widen_writemask(wrmask);
+
+       for (unsigned i = 0; i < attrib_count; i++)
                output_usage_mask[idx + i + const_offset] |=
-                       instr->const_index[0] << comp;
-       }
+                       ((wrmask >> (i * 4)) & 0xf) << comp;
 }
 
 static void
@@ -174,13 +182,9 @@ gather_intrinsic_store_deref_info(const nir_shader *nir,
                                type = glsl_get_array_element(var->type);
 
                        unsigned slots =
-                               var->data.compact ? DIV_ROUND_UP(glsl_get_length(type), 4)
+                               var->data.compact ? DIV_ROUND_UP(var->data.location_frac + glsl_get_length(type), 4)
                                                  : glsl_count_attribute_slots(type, false);
 
-                       if (idx == VARYING_SLOT_CLIP_DIST0)
-                               slots = (nir->info.clip_distance_array_size +
-                                        nir->info.cull_distance_array_size > 4) ? 2 : 1;
-
                        mark_tess_output(info, var->data.patch, param, slots);
                        break;
                }
@@ -195,13 +199,12 @@ gather_push_constant_info(const nir_shader *nir,
                          const nir_intrinsic_instr *instr,
                          struct radv_shader_info *info)
 {
-       nir_const_value *cval = nir_src_as_const_value(instr->src[0]);
        int base = nir_intrinsic_base(instr);
 
-       if (!cval) {
+       if (!nir_src_is_const(instr->src[0])) {
                info->has_indirect_push_constants = true;
        } else {
-               uint32_t min = base + cval->u32[0];
+               uint32_t min = base + nir_src_as_uint(instr->src[0]);
                uint32_t max = min + instr->num_components * 4;
 
                info->max_push_constant_used =
@@ -400,7 +403,8 @@ gather_info_input_decl_ps(const nir_shader *nir, const nir_variable *var,
                info->ps.layer_input = true;
                break;
        case VARYING_SLOT_CLIP_DIST0:
-               info->ps.num_input_clips_culls = attrib_count;
+       case VARYING_SLOT_CLIP_DIST1:
+               info->ps.num_input_clips_culls += attrib_count;
                break;
        default:
                break;
@@ -435,8 +439,8 @@ gather_info_output_decl_ls(const nir_shader *nir, const nir_variable *var,
        int idx = var->data.location;
        unsigned param = shader_io_get_unique_index(idx);
        int num_slots = glsl_count_attribute_slots(var->type, false);
-       if (idx == VARYING_SLOT_CLIP_DIST0)
-               num_slots = (nir->info.clip_distance_array_size + nir->info.cull_distance_array_size > 4) ? 2 : 1;
+       if (var->data.compact)
+               num_slots = DIV_ROUND_UP(var->data.location_frac + glsl_get_length(var->type), 4);
        mark_ls_output(info, param, num_slots);
 }
 
@@ -524,7 +528,7 @@ gather_xfb_info(const nir_shader *nir, struct radv_shader_info *info)
        }
 
        for (unsigned i = 0; i < NIR_MAX_XFB_BUFFERS; i++) {
-               so->strides[i] = xfb->strides[i] / 4;
+               so->strides[i] = xfb->buffers[i].stride / 4;
        }
 
        ralloc_free(xfb);