<div dir="ltr">Hi Dave,<div><br></div><div>This seems to cause some breakage when both push constants and dynamic descriptors are used.</div><div><br></div><div>I've commented 2 fixes inline below needed to avoid a crash, but with those F1 2017 will still hang pretty quick before the main menu, not sure why so far. Mad Max is OK but that doesn't use dynamic descriptors, so I presume the problem is related to that.<br><div class="gmail_extra"><br><div class="gmail_quote">On 11 January 2018 at 03:03, Dave Airlie <span dir="ltr"><<a href="mailto:airlied@gmail.com" target="_blank">airlied@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Dave Airlie <<a href="mailto:airlied@redhat.com">airlied@redhat.com</a>><br>
<br>
Instead of putting the push constants into the upload buffer,<br>
if we have space in the sgprs we can upload the per-stage<br>
constants into the shaders directly.<br>
<br>
This saves a few reads from memory in the meta shaders,<br>
we should also be able to inline other objects like<br>
descriptors.<br>
<br>
Signed-off-by: Dave Airlie <<a href="mailto:airlied@redhat.com">airlied@redhat.com</a>><br>
---<br>
 src/amd/common/ac_nir_to_llvm.<wbr>c  | 93 ++++++++++++++++++++++++++++++<wbr>++++++----<br>
 src/amd/common/ac_nir_to_llvm.<wbr>h  |  4 ++<br>
 src/amd/common/ac_shader_info.<wbr>c  |  5 ++-<br>
 src/amd/common/ac_shader_info.<wbr>h  |  1 +<br>
 src/amd/vulkan/radv_cmd_<wbr>buffer.c | 74 ++++++++++++++++++++++++------<wbr>--<br>
 5 files changed, 150 insertions(+), 27 deletions(-)<br>
<br>
diff --git a/src/amd/common/ac_nir_to_<wbr>llvm.c b/src/amd/common/ac_nir_to_<wbr>llvm.c<br>
index c00220a9c3..818ce40168 100644<br>
--- a/src/amd/common/ac_nir_to_<wbr>llvm.c<br>
+++ b/src/amd/common/ac_nir_to_<wbr>llvm.c<br>
@@ -92,6 +92,7 @@ struct nir_to_llvm_context {<br>
        LLVMValueRef descriptor_sets[AC_UD_MAX_<wbr>SETS];<br>
        LLVMValueRef ring_offsets;<br>
        LLVMValueRef push_constants;<br>
+       LLVMValueRef inline_push_consts[AC_UD_MAX_<wbr>INLINE_PUSH_CONST];<br>
        LLVMValueRef view_index;<br>
        LLVMValueRef num_work_groups;<br>
        LLVMValueRef workgroup_ids[3];<br>
@@ -243,7 +244,7 @@ static void set_llvm_calling_convention(<wbr>LLVMValueRef func,<br>
        LLVMSetFunctionCallConv(func, calling_conv);<br>
 }<br>
<br>
-#define MAX_ARGS 23<br>
+#define MAX_ARGS 32<br>
 struct arg_info {<br>
        LLVMTypeRef types[MAX_ARGS];<br>
        LLVMValueRef *assign[MAX_ARGS];<br>
@@ -538,6 +539,8 @@ struct user_sgpr_info {<br>
        bool need_ring_offsets;<br>
        uint8_t sgpr_count;<br>
        bool indirect_all_descriptor_sets;<br>
+       uint8_t base_inline_push_consts;<br>
+       uint8_t num_inline_push_consts;<br>
 };<br>
<br>
 static void allocate_user_sgprs(struct nir_to_llvm_context *ctx,<br>
@@ -609,8 +612,45 @@ static void allocate_user_sgprs(struct nir_to_llvm_context *ctx,<br>
        } else {<br>
                user_sgpr_info->sgpr_count += util_bitcount(ctx->shader_<wbr>info->info.desc_set_used_mask) * 2;<br>
        }<br>
+<br>
+       if (ctx->shader_info->info.loads_<wbr>push_constants) {<br>
+               uint32_t remaining_sgprs = 16 - user_sgpr_info->sgpr_count;<br>
+               if (!ctx->shader_info->info.has_<wbr>indirect_push_constants &&<br>
+                   !ctx->shader_info->info.loads_<wbr>dynamic_offsets)<br>
+                       remaining_sgprs += 2;<br>
+<br>
+               if (ctx->options->layout->push_<wbr>constant_size) {<br>
+                       uint8_t num_32bit_push_consts = (ctx->shader_info->info.max_<wbr>push_constant_used -<br>
+                                                        ctx->shader_info->info.min_<wbr>push_constant_used) / 4;<br>
+                       user_sgpr_info->base_inline_<wbr>push_consts = ctx->shader_info->info.min_<wbr>push_constant_used / 4;<br>
+<br>
+                       if (num_32bit_push_consts < remaining_sgprs) {<br>
+                               user_sgpr_info->num_inline_<wbr>push_consts = num_32bit_push_consts;<br>
+                               if (!ctx->shader_info->info.has_<wbr>indirect_push_constants)<br>
+                                       ctx->shader_info->info.loads_<wbr>push_constants = false;<br>
+                       } else {<br>
+                               user_sgpr_info->num_inline_<wbr>push_consts = remaining_sgprs;<br>
+                       }<br>
+<br>
+                       if (user_sgpr_info->num_inline_<wbr>push_consts > AC_UD_MAX_INLINE_PUSH_CONST)<br>
+                               user_sgpr_info->num_inline_<wbr>push_consts = AC_UD_MAX_INLINE_PUSH_CONST;<br>
+               }<br>
+       }<br>
 }<br>
<br>
+static void<br>
+declare_inline_push_consts(<wbr>struct nir_to_llvm_context *ctx,<br>
+                          gl_shader_stage stage,<br>
+                          const struct user_sgpr_info *user_sgpr_info,<br>
+                          struct arg_info *args)<br>
+{<br>
+       ctx->shader_info->inline_push_<wbr>const_mask = (1 << user_sgpr_info->num_inline_<wbr>push_consts) - 1;<br>
+       ctx->shader_info->inline_push_<wbr>const_mask <<= user_sgpr_info->base_inline_<wbr>push_consts;<br>
+<br>
+       for (unsigned i = 0; i < user_sgpr_info->num_inline_<wbr>push_consts; i++)<br>
+               add_arg(args, ARG_SGPR, ctx->ac.i32, &ctx->inline_push_consts[i]);<br>
+<br>
+}<br>
 static void<br>
 declare_global_input_sgprs(<wbr>struct nir_to_llvm_context *ctx,<br>
                           gl_shader_stage stage,<br>
@@ -644,6 +684,9 @@ declare_global_input_sgprs(<wbr>struct nir_to_llvm_context *ctx,<br>
                /* 1 for push constants and dynamic descriptors */<br>
                add_array_arg(args, type, &ctx->push_constants);<br></blockquote><div><br></div><div>This is only done if loads_push_constants is true, but that is set to false if all push constants are inlined. Need to do it if loads_dynamic_offsets is true as well.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
        }<br>
+<br>
+       if (!((stage == MESA_SHADER_VERTEX) || (has_previous_stage && previous_stage == MESA_SHADER_VERTEX)))<br>
+               declare_inline_push_consts(<wbr>ctx, stage, user_sgpr_info, args);<br>
 }<br>
<br>
 static void<br>
@@ -651,6 +694,7 @@ declare_vs_specific_input_<wbr>sgprs(struct nir_to_llvm_context *ctx,<br>
                                gl_shader_stage stage,<br>
                                bool has_previous_stage,<br>
                                gl_shader_stage previous_stage,<br>
+                               const struct user_sgpr_info *user_sgpr_info,<br>
                                struct arg_info *args)<br>
 {<br>
        if (!ctx->is_gs_copy_shader &&<br>
@@ -660,6 +704,7 @@ declare_vs_specific_input_<wbr>sgprs(struct nir_to_llvm_context *ctx,<br>
                        add_arg(args, ARG_SGPR, const_array(ctx->ac.v4i32, 16),<br>
                                &ctx->vertex_buffers);<br>
                }<br>
+               declare_inline_push_consts(<wbr>ctx, stage, user_sgpr_info, args);<br>
                add_arg(args, ARG_SGPR, ctx->ac.i32, &ctx->abi.base_vertex);<br>
                add_arg(args, ARG_SGPR, ctx->ac.i32, &ctx->abi.start_instance);<br>
                if (ctx->shader_info->info.vs.<wbr>needs_draw_id) {<br>
@@ -693,6 +738,16 @@ declare_tes_input_vgprs(struct nir_to_llvm_context *ctx, struct arg_info *args)<br>
        add_arg(args, ARG_VGPR, ctx->ac.i32, &ctx->abi.tes_patch_id);<br>
 }<br>
<br>
+static void<br>
+set_inline_pushconst_locs(<wbr>struct nir_to_llvm_context *ctx,<br>
+                         const struct user_sgpr_info *user_sgpr_info,<br>
+                         uint8_t *user_sgpr_idx)<br>
+{<br>
+       ctx->shader_info->user_sgprs_<wbr>locs.push_const_base = user_sgpr_info->base_inline_<wbr>push_consts;<br>
+       for (unsigned i = 0; i < user_sgpr_info->num_inline_<wbr>push_consts; i++)<br>
+               set_loc(&ctx->shader_info-><wbr>user_sgprs_locs.inline_push_<wbr>consts[i], user_sgpr_idx, 1, 0);<br>
+}<br>
+<br>
 static void<br>
 set_global_input_locs(struct nir_to_llvm_context *ctx, gl_shader_stage stage,<br>
                      bool has_previous_stage, gl_shader_stage previous_stage,<br>
@@ -734,12 +789,17 @@ set_global_input_locs(struct nir_to_llvm_context *ctx, gl_shader_stage stage,<br>
        if (ctx->shader_info->info.loads_<wbr>push_constants) {<br>
                set_loc_shader(ctx, AC_UD_PUSH_CONSTANTS, user_sgpr_idx, 2);<br></blockquote><div><br></div><div>Same as above.</div><div><br></div><div>Thanks,</div><div>Alex</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
        }<br>
+<br>
+<br>
+       if (!((stage == MESA_SHADER_VERTEX) || (has_previous_stage && previous_stage == MESA_SHADER_VERTEX)))<br>
+               set_inline_pushconst_locs(ctx, user_sgpr_info, user_sgpr_idx);<br>
 }<br>
<br>
 static void<br>
 set_vs_specific_input_locs(<wbr>struct nir_to_llvm_context *ctx,<br>
                           gl_shader_stage stage, bool has_previous_stage,<br>
                           gl_shader_stage previous_stage,<br>
+                          const struct user_sgpr_info *user_sgpr_info,<br>
                           uint8_t *user_sgpr_idx)<br>
 {<br>
        if (!ctx->is_gs_copy_shader &&<br>
@@ -750,6 +810,7 @@ set_vs_specific_input_locs(<wbr>struct nir_to_llvm_context *ctx,<br>
                                       user_sgpr_idx, 2);<br>
                }<br>
<br>
+               set_inline_pushconst_locs(ctx, user_sgpr_info, user_sgpr_idx);<br>
                unsigned vs_num = 2;<br>
                if (ctx->shader_info->info.vs.<wbr>needs_draw_id)<br>
                        vs_num++;<br>
@@ -805,7 +866,7 @@ static void create_function(struct nir_to_llvm_context *ctx,<br>
                                           previous_stage, &user_sgpr_info,<br>
                                           &args, &desc_sets);<br>
                declare_vs_specific_input_<wbr>sgprs(ctx, stage, has_previous_stage,<br>
-                                               previous_stage, &args);<br>
+                                               previous_stage, &user_sgpr_info, &args);<br>
<br>
                if (ctx->shader_info->info.needs_<wbr>multiview_view_index || (!ctx->options->key.vs.as_es && !ctx->options->key.vs.as_ls && ctx->options->key.has_<wbr>multiview_view_index))<br>
                        add_arg(&args, ARG_SGPR, ctx->ac.i32, &ctx->view_index);<br>
@@ -838,7 +899,7 @@ static void create_function(struct nir_to_llvm_context *ctx,<br>
                                                   &desc_sets);<br>
                        declare_vs_specific_input_<wbr>sgprs(ctx, stage,<br>
                                                        has_previous_stage,<br>
-                                                       previous_stage, &args);<br>
+                                                       previous_stage, &user_sgpr_info, &args);<br>
<br>
                        add_arg(&args, ARG_SGPR, ctx->ac.i32,<br>
                                &ctx->ls_out_layout);<br>
@@ -934,7 +995,7 @@ static void create_function(struct nir_to_llvm_context *ctx,<br>
                        } else {<br>
                                declare_vs_specific_input_<wbr>sgprs(ctx, stage,<br>
                                                                has_previous_stage,<br>
-                                                               previous_stage,<br>
+                                                               previous_stage, &user_sgpr_info,<br>
                                                                &args);<br>
                        }<br>
<br>
@@ -1076,7 +1137,7 @@ static void create_function(struct nir_to_llvm_context *ctx,<br>
                break;<br>
        case MESA_SHADER_VERTEX:<br>
                set_vs_specific_input_locs(<wbr>ctx, stage, has_previous_stage,<br>
-                                          previous_stage, &user_sgpr_idx);<br>
+                                          previous_stage, &user_sgpr_info, &user_sgpr_idx);<br>
                if (ctx->view_index)<br>
                        set_loc_shader(ctx, AC_UD_VIEW_INDEX, &user_sgpr_idx, 1);<br>
                if (ctx->options->key.vs.as_ls) {<br>
@@ -1088,7 +1149,7 @@ static void create_function(struct nir_to_llvm_context *ctx,<br>
                break;<br>
        case MESA_SHADER_TESS_CTRL:<br>
                set_vs_specific_input_locs(<wbr>ctx, stage, has_previous_stage,<br>
-                                          previous_stage, &user_sgpr_idx);<br>
+                                          previous_stage, &user_sgpr_info, &user_sgpr_idx);<br>
                if (has_previous_stage)<br>
                        set_loc_shader(ctx, AC_UD_VS_LS_TCS_IN_LAYOUT,<br>
                                       &user_sgpr_idx, 1);<br>
@@ -1108,6 +1169,7 @@ static void create_function(struct nir_to_llvm_context *ctx,<br>
                                set_vs_specific_input_locs(<wbr>ctx, stage,<br>
                                                           has_previous_stage,<br>
                                                           previous_stage,<br>
+                                                          &user_sgpr_info,<br>
                                                           &user_sgpr_idx);<br>
                        else<br>
                                set_loc_shader(ctx, AC_UD_TES_OFFCHIP_LAYOUT,<br>
@@ -2357,9 +2419,24 @@ static LLVMValueRef visit_load_push_constant(<wbr>struct nir_to_llvm_context *ctx,<br>
                                              nir_intrinsic_instr *instr)<br>
 {<br>
        LLVMValueRef ptr, addr;<br>
+       LLVMValueRef src0 = get_src(ctx->nir, instr->src[0]);<br>
+       unsigned index = nir_intrinsic_base(instr);<br>
+<br>
+       if (LLVMIsConstant(src0)) {<br>
+               unsigned array_index = index;<br>
+               array_index += LLVMConstIntGetZExtValue(src0)<wbr>;<br>
+               array_index /= 4;<br>
+<br>
+               uint32_t bits = ((1 << instr->num_components) - 1) << array_index;<br>
+<br>
+               if ((bits & ctx->shader_info->inline_push_<wbr>const_mask) == bits) {<br>
+                       array_index -= ctx->shader_info->user_sgprs_<wbr>locs.push_const_base;<br>
+                       return ac_build_gather_values(&ctx-><wbr>ac, &ctx->inline_push_consts[<wbr>array_index], instr->num_components);<br>
+               }<br>
+       }<br>
<br>
-       addr = LLVMConstInt(ctx->ac.i32, nir_intrinsic_base(instr), 0);<br>
-       addr = LLVMBuildAdd(ctx->builder, addr, get_src(ctx->nir, instr->src[0]), "");<br>
+       addr = LLVMConstInt(ctx->ac.i32, index, 0);<br>
+       addr = LLVMBuildAdd(ctx->builder, addr, src0, "");<br>
<br>
        ptr = ac_build_gep0(&ctx->ac, ctx->push_constants, addr);<br>
        ptr = cast_ptr(ctx, ptr, get_def_type(ctx->nir, &instr->dest.ssa));<br>
diff --git a/src/amd/common/ac_nir_to_<wbr>llvm.h b/src/amd/common/ac_nir_to_<wbr>llvm.h<br>
index b3ad0a0985..9f9230d3e6 100644<br>
--- a/src/amd/common/ac_nir_to_<wbr>llvm.h<br>
+++ b/src/amd/common/ac_nir_to_<wbr>llvm.h<br>
@@ -127,10 +127,13 @@ enum ac_ud_index {<br>
<br>
 // Match MAX_SETS from radv_descriptor_set.h<br>
 #define AC_UD_MAX_SETS MAX_SETS<br>
+#define AC_UD_MAX_INLINE_PUSH_CONST 8<br>
<br>
 struct ac_userdata_locations {<br>
        struct ac_userdata_info descriptor_sets[AC_UD_MAX_<wbr>SETS];<br>
        struct ac_userdata_info shader_data[AC_UD_MAX_UD];<br>
+       struct ac_userdata_info inline_push_consts[AC_UD_MAX_<wbr>INLINE_PUSH_CONST];<br>
+       uint8_t push_const_base;<br>
 };<br>
<br>
 struct ac_vs_output_info {<br>
@@ -156,6 +159,7 @@ struct ac_shader_variant_info {<br>
        unsigned num_user_sgprs;<br>
        unsigned num_input_sgprs;<br>
        unsigned num_input_vgprs;<br>
+       uint32_t inline_push_const_mask;<br>
        bool need_indirect_descriptor_sets;<br>
        struct {<br>
                struct {<br>
diff --git a/src/amd/common/ac_shader_<wbr>info.c b/src/amd/common/ac_shader_<wbr>info.c<br>
index 18fa9e1c94..fbb46684ae 100644<br>
--- a/src/amd/common/ac_shader_<wbr>info.c<br>
+++ b/src/amd/common/ac_shader_<wbr>info.c<br>
@@ -179,9 +179,10 @@ ac_nir_shader_info_pass(struct nir_shader *nir,<br>
 {<br>
        struct nir_function *func = (struct nir_function *)exec_list_get_head(&nir-><wbr>functions);<br>
<br>
-<br>
-       if (options->layout->dynamic_<wbr>offset_count)<br>
+       if (options->layout->dynamic_<wbr>offset_count) {<br>
                info->loads_push_constants = true;<br>
+               info->loads_dynamic_offsets = true;<br>
+       }<br>
<br>
        nir_foreach_variable(variable, &nir->inputs)<br>
                gather_info_input_decl(nir, options, variable, info);<br>
diff --git a/src/amd/common/ac_shader_<wbr>info.h b/src/amd/common/ac_shader_<wbr>info.h<br>
index e35cde0ca9..e8ea33f2e3 100644<br>
--- a/src/amd/common/ac_shader_<wbr>info.h<br>
+++ b/src/amd/common/ac_shader_<wbr>info.h<br>
@@ -32,6 +32,7 @@ struct ac_shader_info {<br>
        uint8_t min_push_constant_used;<br>
        uint8_t max_push_constant_used;<br>
        bool has_indirect_push_constants;<br>
+       bool loads_dynamic_offsets;<br>
        bool loads_push_constants;<br>
        bool needs_multiview_view_index;<br>
        bool uses_invocation_id;<br>
diff --git a/src/amd/vulkan/radv_cmd_<wbr>buffer.c b/src/amd/vulkan/radv_cmd_<wbr>buffer.c<br>
index 60f19fb12b..17306eeaf8 100644<br>
--- a/src/amd/vulkan/radv_cmd_<wbr>buffer.c<br>
+++ b/src/amd/vulkan/radv_cmd_<wbr>buffer.c<br>
@@ -1807,6 +1807,27 @@ radv_flush_descriptors(struct radv_cmd_buffer *cmd_buffer,<br>
        assert(cmd_buffer->cs->cdw <= cdw_max);<br>
 }<br>
<br>
+static struct ac_userdata_info *<br>
+radv_lookup_push_const_sgpr(<wbr>struct radv_shader_variant *shader,<br>
+                           int idx)<br>
+{<br>
+       idx -= shader->info.user_sgprs_locs.<wbr>push_const_base;<br>
+       return &shader->info.user_sgprs_locs.<wbr>inline_push_consts[idx];<br>
+}<br>
+<br>
+static void<br>
+radv_emit_inline_pushconsts(<wbr>struct radv_cmd_buffer *cmd_buffer,<br>
+                           struct radv_shader_variant *shader,<br>
+                           unsigned base_reg,<br>
+                           int idx, int count, uint32_t *values)<br>
+{<br>
+       struct ac_userdata_info *loc = radv_lookup_push_const_sgpr(<wbr>shader, idx);<br>
+       assert (loc->sgpr_idx == -1);<br>
+       assert (!loc->indirect);<br>
+       radeon_set_sh_reg_seq(cmd_<wbr>buffer->cs, base_reg + loc->sgpr_idx * 4, count);<br>
+       radeon_emit_array(cmd_buffer-><wbr>cs, values, count);<br>
+}<br>
+<br>
 static void<br>
 radv_flush_constants(struct radv_cmd_buffer *cmd_buffer,<br>
                     struct radv_pipeline *pipeline,<br>
@@ -1816,36 +1837,55 @@ radv_flush_constants(struct radv_cmd_buffer *cmd_buffer,<br>
        unsigned offset;<br>
        void *ptr;<br>
        uint64_t va;<br>
+       bool need_push_constants = false;<br>
<br>
        stages &= cmd_buffer->push_constant_<wbr>stages;<br>
        if (!stages ||<br>
            (!layout->push_constant_size && !layout->dynamic_offset_count)<wbr>)<br>
                return;<br>
<br>
-       if (!radv_cmd_buffer_upload_<wbr>alloc(cmd_buffer, layout->push_constant_size +<br>
-                                         16 * layout->dynamic_offset_count,<br>
-                                         256, &offset, &ptr))<br>
-               return;<br>
+       radv_foreach_stage(stage, stages) {<br>
+               if (!pipeline->shaders[stage])<br>
+                       continue;<br>
+<br>
+               need_push_constants |= pipeline->shaders[stage]-><wbr>info.info.loads_push_<wbr>constants;<br>
+               need_push_constants |= pipeline->shaders[stage]-><wbr>info.info.loads_dynamic_<wbr>offsets;<br>
<br>
-       memcpy(ptr, cmd_buffer->push_constants, layout->push_constant_size);<br>
-       if (layout->dynamic_offset_count) {<br>
-               memcpy((char*)ptr + layout->push_constant_size, cmd_buffer->dynamic_buffers,<br>
-                      16 * layout->dynamic_offset_count);<br>
+               uint32_t mask = pipeline->shaders[stage]-><wbr>info.inline_push_const_mask;<br>
+               uint32_t base_reg = pipeline->user_data_0[stage];<br>
+               while (mask) {<br>
+                       int start, count;<br>
+                       u_bit_scan_consecutive_range(&<wbr>mask, &start, &count);<br>
+                       radv_emit_inline_pushconsts(<wbr>cmd_buffer, pipeline->shaders[stage], base_reg,<br>
+                                                   start, count, (uint32_t *)&cmd_buffer->push_constants[<wbr>start * 4]);<br>
+               }<br>
        }<br>
<br>
-       va = radv_buffer_get_va(cmd_buffer-<wbr>>upload.upload_bo);<br>
-       va += offset;<br>
+       if (need_push_constants) {<br>
+               if (!radv_cmd_buffer_upload_<wbr>alloc(cmd_buffer, layout->push_constant_size +<br>
+                                                 16 * layout->dynamic_offset_count,<br>
+                                                 256, &offset, &ptr))<br>
+                       return;<br>
<br>
-       MAYBE_UNUSED unsigned cdw_max = radeon_check_space(cmd_buffer-<wbr>>device->ws,<br>
-                                                          cmd_buffer->cs, MESA_SHADER_STAGES * 4);<br>
+               memcpy(ptr, cmd_buffer->push_constants, layout->push_constant_size);<br>
+               if (layout->dynamic_offset_count) {<br>
+                       memcpy((char*)ptr + layout->push_constant_size, cmd_buffer->dynamic_buffers,<br>
+                              16 * layout->dynamic_offset_count);<br>
+               }<br>
<br>
-       radv_foreach_stage(stage, stages) {<br>
-               if (pipeline->shaders[stage]) {<br>
-                       radv_emit_userdata_address(<wbr>cmd_buffer, pipeline, stage,<br>
-                                                  AC_UD_PUSH_CONSTANTS, va);<br>
+               va = radv_buffer_get_va(cmd_buffer-<wbr>>upload.upload_bo);<br>
+               va += offset;<br>
+<br>
+               MAYBE_UNUSED unsigned cdw_max = radeon_check_space(cmd_buffer-<wbr>>device->ws,<br>
+                                                                  cmd_buffer->cs, MESA_SHADER_STAGES * 4);<br>
+<br>
+               radv_foreach_stage(stage, stages) {<br>
+                       if (pipeline->shaders[stage]) {<br>
+                               radv_emit_userdata_address(<wbr>cmd_buffer, pipeline, stage,<br>
+                                                          AC_UD_PUSH_CONSTANTS, va);<br>
+                       }<br>
                }<br>
        }<br>
-<br>
        cmd_buffer->push_constant_<wbr>stages &= ~stages;<br>
        assert(cmd_buffer->cs->cdw <= cdw_max);<br>
 }<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.14.3<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div></div>