struct radv_shader_context {
struct ac_llvm_context ac;
const struct radv_nir_compiler_options *options;
- struct radv_shader_variant_info *shader_info;
+ struct radv_shader_info *shader_info;
+ const struct nir_shader *shader;
struct ac_shader_abi abi;
unsigned max_workgroup_size;
LLVMContextRef context;
LLVMValueRef main_function;
- LLVMValueRef descriptor_sets[RADV_UD_MAX_SETS];
+ LLVMValueRef descriptor_sets[MAX_SETS];
LLVMValueRef ring_offsets;
LLVMValueRef vertex_buffers;
LLVMValueRef hs_ring_tess_offchip;
LLVMValueRef hs_ring_tess_factor;
- LLVMValueRef persp_sample, persp_center, persp_centroid;
- LLVMValueRef linear_sample, linear_center, linear_centroid;
-
/* Streamout */
LLVMValueRef streamout_buffers;
LLVMValueRef streamout_write_idx;
gl_shader_stage stage;
LLVMValueRef inputs[RADEON_LLVM_MAX_INPUTS * 4];
- uint64_t float16_shaded_mask;
- uint64_t input_mask;
uint64_t output_mask;
bool is_gs_copy_shader;
LLVMValueRef gs_generated_prims[4];
LLVMValueRef gs_ngg_emit;
LLVMValueRef gs_ngg_scratch;
- unsigned gs_max_out_vertices;
- unsigned gs_output_prim;
-
- unsigned tes_primitive_mode;
- uint32_t tcs_patch_outputs_read;
- uint64_t tcs_outputs_read;
- uint32_t tcs_vertices_per_patch;
uint32_t tcs_num_inputs;
uint32_t tcs_num_patches;
uint32_t max_gsvs_emit_size;
return container_of(abi, ctx, abi);
}
-struct ac_build_if_state
-{
- struct radv_shader_context *ctx;
- LLVMValueRef condition;
- LLVMBasicBlockRef entry_block;
- LLVMBasicBlockRef true_block;
- LLVMBasicBlockRef false_block;
- LLVMBasicBlockRef merge_block;
-};
-
-static LLVMBasicBlockRef
-ac_build_insert_new_block(struct radv_shader_context *ctx, const char *name)
-{
- LLVMBasicBlockRef current_block;
- LLVMBasicBlockRef next_block;
- LLVMBasicBlockRef new_block;
-
- /* get current basic block */
- current_block = LLVMGetInsertBlock(ctx->ac.builder);
-
- /* chqeck if there's another block after this one */
- next_block = LLVMGetNextBasicBlock(current_block);
- if (next_block) {
- /* insert the new block before the next block */
- new_block = LLVMInsertBasicBlockInContext(ctx->context, next_block, name);
- }
- else {
- /* append new block after current block */
- LLVMValueRef function = LLVMGetBasicBlockParent(current_block);
- new_block = LLVMAppendBasicBlockInContext(ctx->context, function, name);
- }
- return new_block;
-}
-
-static void
-ac_nir_build_if(struct ac_build_if_state *ifthen,
- struct radv_shader_context *ctx,
- LLVMValueRef condition)
-{
- LLVMBasicBlockRef block = LLVMGetInsertBlock(ctx->ac.builder);
-
- memset(ifthen, 0, sizeof *ifthen);
- ifthen->ctx = ctx;
- ifthen->condition = condition;
- ifthen->entry_block = block;
-
- /* create endif/merge basic block for the phi functions */
- ifthen->merge_block = ac_build_insert_new_block(ctx, "endif-block");
-
- /* create/insert true_block before merge_block */
- ifthen->true_block =
- LLVMInsertBasicBlockInContext(ctx->context,
- ifthen->merge_block,
- "if-true-block");
-
- /* successive code goes into the true block */
- LLVMPositionBuilderAtEnd(ctx->ac.builder, ifthen->true_block);
-}
-
-/**
- * End a conditional.
- */
-static void
-ac_nir_build_endif(struct ac_build_if_state *ifthen)
-{
- LLVMBuilderRef builder = ifthen->ctx->ac.builder;
-
- /* Insert branch to the merge block from current block */
- LLVMBuildBr(builder, ifthen->merge_block);
-
- /*
- * Now patch in the various branch instructions.
- */
-
- /* Insert the conditional branch instruction at the end of entry_block */
- LLVMPositionBuilderAtEnd(builder, ifthen->entry_block);
- if (ifthen->false_block) {
- /* we have an else clause */
- LLVMBuildCondBr(builder, ifthen->condition,
- ifthen->true_block, ifthen->false_block);
- }
- else {
- /* no else clause */
- LLVMBuildCondBr(builder, ifthen->condition,
- ifthen->true_block, ifthen->merge_block);
- }
-
- /* Resume building code at end of the ifthen->merge_block */
- LLVMPositionBuilderAtEnd(builder, ifthen->merge_block);
-}
-
-
static LLVMValueRef get_rel_patch_id(struct radv_shader_context *ctx)
{
switch (ctx->stage) {
get_tcs_num_patches(struct radv_shader_context *ctx)
{
unsigned num_tcs_input_cp = ctx->options->key.tcs.input_vertices;
- unsigned num_tcs_output_cp = ctx->tcs_vertices_per_patch;
+ unsigned num_tcs_output_cp = ctx->shader->info.tess.tcs_vertices_out;
uint32_t input_vertex_size = ctx->tcs_num_inputs * 16;
uint32_t input_patch_size = ctx->options->key.tcs.input_vertices * input_vertex_size;
- uint32_t num_tcs_outputs = util_last_bit64(ctx->shader_info->info.tcs.outputs_written);
- uint32_t num_tcs_patch_outputs = util_last_bit64(ctx->shader_info->info.tcs.patch_outputs_written);
+ uint32_t num_tcs_outputs = util_last_bit64(ctx->shader_info->tcs.outputs_written);
+ uint32_t num_tcs_patch_outputs = util_last_bit64(ctx->shader_info->tcs.patch_outputs_written);
uint32_t output_vertex_size = num_tcs_outputs * 16;
- uint32_t pervertex_output_patch_size = ctx->tcs_vertices_per_patch * output_vertex_size;
+ uint32_t pervertex_output_patch_size = ctx->shader->info.tess.tcs_vertices_out * output_vertex_size;
uint32_t output_patch_size = pervertex_output_patch_size + num_tcs_patch_outputs * 16;
unsigned num_patches;
unsigned hardware_lds_size;
/* GFX6 bug workaround - limit LS-HS threadgroups to only one wave. */
if (ctx->options->chip_class == GFX6) {
- unsigned one_wave = 64 / MAX2(num_tcs_input_cp, num_tcs_output_cp);
+ unsigned one_wave = ctx->options->wave_size / MAX2(num_tcs_input_cp, num_tcs_output_cp);
num_patches = MIN2(num_patches, one_wave);
}
return num_patches;
unsigned num_patches;
unsigned lds_size;
- num_tcs_output_cp = ctx->tcs_vertices_per_patch;
- num_tcs_outputs = util_last_bit64(ctx->shader_info->info.tcs.outputs_written);
- num_tcs_patch_outputs = util_last_bit64(ctx->shader_info->info.tcs.patch_outputs_written);
+ num_tcs_output_cp = ctx->shader->info.tess.tcs_vertices_out;
+ num_tcs_outputs = util_last_bit64(ctx->shader_info->tcs.outputs_written);
+ num_tcs_patch_outputs = util_last_bit64(ctx->shader_info->tcs.patch_outputs_written);
input_vertex_size = ctx->tcs_num_inputs * 16;
output_vertex_size = num_tcs_outputs * 16;
static LLVMValueRef
get_tcs_out_patch_stride(struct radv_shader_context *ctx)
{
- uint32_t num_tcs_outputs = util_last_bit64(ctx->shader_info->info.tcs.outputs_written);
- uint32_t num_tcs_patch_outputs = util_last_bit64(ctx->shader_info->info.tcs.patch_outputs_written);
+ uint32_t num_tcs_outputs = util_last_bit64(ctx->shader_info->tcs.outputs_written);
+ uint32_t num_tcs_patch_outputs = util_last_bit64(ctx->shader_info->tcs.patch_outputs_written);
uint32_t output_vertex_size = num_tcs_outputs * 16;
- uint32_t pervertex_output_patch_size = ctx->tcs_vertices_per_patch * output_vertex_size;
+ uint32_t pervertex_output_patch_size = ctx->shader->info.tess.tcs_vertices_out * output_vertex_size;
uint32_t output_patch_size = pervertex_output_patch_size + num_tcs_patch_outputs * 16;
output_patch_size /= 4;
return LLVMConstInt(ctx->ac.i32, output_patch_size, false);
static LLVMValueRef
get_tcs_out_vertex_stride(struct radv_shader_context *ctx)
{
- uint32_t num_tcs_outputs = util_last_bit64(ctx->shader_info->info.tcs.outputs_written);
+ uint32_t num_tcs_outputs = util_last_bit64(ctx->shader_info->tcs.outputs_written);
uint32_t output_vertex_size = num_tcs_outputs * 16;
output_vertex_size /= 4;
return LLVMConstInt(ctx->ac.i32, output_vertex_size, false);
uint32_t input_patch_size = ctx->options->key.tcs.input_vertices * input_vertex_size;
uint32_t output_patch0_offset = input_patch_size;
- uint32_t num_tcs_outputs = util_last_bit64(ctx->shader_info->info.tcs.outputs_written);
+ uint32_t num_tcs_outputs = util_last_bit64(ctx->shader_info->tcs.outputs_written);
uint32_t output_vertex_size = num_tcs_outputs * 16;
- uint32_t pervertex_output_patch_size = ctx->tcs_vertices_per_patch * output_vertex_size;
+ uint32_t pervertex_output_patch_size = ctx->shader->info.tess.tcs_vertices_out * output_vertex_size;
unsigned num_patches = ctx->tcs_num_patches;
output_patch0_offset *= num_patches;
{
switch (stage) {
case MESA_SHADER_VERTEX:
- if (ctx->shader_info->info.needs_multiview_view_index ||
+ if (ctx->shader_info->needs_multiview_view_index ||
(!ctx->options->key.vs_common_out.as_es && !ctx->options->key.vs_common_out.as_ls && ctx->options->key.has_multiview_view_index))
return true;
break;
case MESA_SHADER_TESS_EVAL:
- if (ctx->shader_info->info.needs_multiview_view_index || (!ctx->options->key.vs_common_out.as_es && ctx->options->key.has_multiview_view_index))
+ if (ctx->shader_info->needs_multiview_view_index || (!ctx->options->key.vs_common_out.as_es && ctx->options->key.has_multiview_view_index))
return true;
break;
case MESA_SHADER_GEOMETRY:
case MESA_SHADER_TESS_CTRL:
- if (ctx->shader_info->info.needs_multiview_view_index)
+ if (ctx->shader_info->needs_multiview_view_index)
return true;
break;
default:
{
uint8_t count = 0;
- if (ctx->shader_info->info.vs.has_vertex_buffers)
+ if (ctx->shader_info->vs.has_vertex_buffers)
count++;
- count += ctx->shader_info->info.vs.needs_draw_id ? 3 : 2;
+ count += ctx->shader_info->vs.needs_draw_id ? 3 : 2;
return count;
}
uint8_t remaining_sgprs = user_sgpr_info->remaining_sgprs;
/* Only supported if shaders use push constants. */
- if (ctx->shader_info->info.min_push_constant_used == UINT8_MAX)
+ if (ctx->shader_info->min_push_constant_used == UINT8_MAX)
return;
/* Only supported if shaders don't have indirect push constants. */
- if (ctx->shader_info->info.has_indirect_push_constants)
+ if (ctx->shader_info->has_indirect_push_constants)
return;
/* Only supported for 32-bit push constants. */
- if (!ctx->shader_info->info.has_only_32bit_push_constants)
+ if (!ctx->shader_info->has_only_32bit_push_constants)
return;
uint8_t num_push_consts =
- (ctx->shader_info->info.max_push_constant_used -
- ctx->shader_info->info.min_push_constant_used) / 4;
+ (ctx->shader_info->max_push_constant_used -
+ ctx->shader_info->min_push_constant_used) / 4;
/* Check if the number of user SGPRs is large enough. */
if (num_push_consts < remaining_sgprs) {
- ctx->shader_info->info.num_inline_push_consts = num_push_consts;
+ ctx->shader_info->num_inline_push_consts = num_push_consts;
} else {
- ctx->shader_info->info.num_inline_push_consts = remaining_sgprs;
+ ctx->shader_info->num_inline_push_consts = remaining_sgprs;
}
/* Clamp to the maximum number of allowed inlined push constants. */
- if (ctx->shader_info->info.num_inline_push_consts > AC_MAX_INLINE_PUSH_CONSTS)
- ctx->shader_info->info.num_inline_push_consts = AC_MAX_INLINE_PUSH_CONSTS;
+ if (ctx->shader_info->num_inline_push_consts > AC_MAX_INLINE_PUSH_CONSTS)
+ ctx->shader_info->num_inline_push_consts = AC_MAX_INLINE_PUSH_CONSTS;
- if (ctx->shader_info->info.num_inline_push_consts == num_push_consts &&
- !ctx->shader_info->info.loads_dynamic_offsets) {
+ if (ctx->shader_info->num_inline_push_consts == num_push_consts &&
+ !ctx->shader_info->loads_dynamic_offsets) {
/* Disable the default push constants path if all constants are
* inlined and if shaders don't use dynamic descriptors.
*/
- ctx->shader_info->info.loads_push_constants = false;
+ ctx->shader_info->loads_push_constants = false;
}
- ctx->shader_info->info.base_inline_push_consts =
- ctx->shader_info->info.min_push_constant_used / 4;
+ ctx->shader_info->base_inline_push_consts =
+ ctx->shader_info->min_push_constant_used / 4;
}
static void allocate_user_sgprs(struct radv_shader_context *ctx,
user_sgpr_info->need_ring_offsets = true;
if (stage == MESA_SHADER_FRAGMENT &&
- ctx->shader_info->info.ps.needs_sample_positions)
+ ctx->shader_info->ps.needs_sample_positions)
user_sgpr_info->need_ring_offsets = true;
/* 2 user sgprs will nearly always be allocated for scratch/rings */
switch (stage) {
case MESA_SHADER_COMPUTE:
- if (ctx->shader_info->info.cs.uses_grid_size)
+ if (ctx->shader_info->cs.uses_grid_size)
user_sgpr_count += 3;
break;
case MESA_SHADER_FRAGMENT:
- user_sgpr_count += ctx->shader_info->info.ps.needs_sample_positions;
+ user_sgpr_count += ctx->shader_info->ps.needs_sample_positions;
break;
case MESA_SHADER_VERTEX:
if (!ctx->is_gs_copy_shader)
if (needs_view_index)
user_sgpr_count++;
- if (ctx->shader_info->info.loads_push_constants)
+ if (ctx->shader_info->loads_push_constants)
user_sgpr_count++;
if (ctx->streamout_buffers)
uint32_t available_sgprs = ctx->options->chip_class >= GFX9 && stage != MESA_SHADER_COMPUTE ? 32 : 16;
uint32_t remaining_sgprs = available_sgprs - user_sgpr_count;
uint32_t num_desc_set =
- util_bitcount(ctx->shader_info->info.desc_set_used_mask);
+ util_bitcount(ctx->shader_info->desc_set_used_mask);
if (remaining_sgprs < num_desc_set) {
user_sgpr_info->indirect_all_descriptor_sets = true;
/* 1 for each descriptor set */
if (!user_sgpr_info->indirect_all_descriptor_sets) {
- uint32_t mask = ctx->shader_info->info.desc_set_used_mask;
+ uint32_t mask = ctx->shader_info->desc_set_used_mask;
while (mask) {
int i = u_bit_scan(&mask);
desc_sets);
}
- if (ctx->shader_info->info.loads_push_constants) {
+ if (ctx->shader_info->loads_push_constants) {
/* 1 for push constants and dynamic descriptors */
add_arg(args, ARG_SGPR, type, &ctx->abi.push_constants);
}
- for (unsigned i = 0; i < ctx->shader_info->info.num_inline_push_consts; i++) {
+ for (unsigned i = 0; i < ctx->shader_info->num_inline_push_consts; i++) {
add_arg(args, ARG_SGPR, ctx->ac.i32,
&ctx->abi.inline_push_consts[i]);
}
- ctx->abi.num_inline_push_consts = ctx->shader_info->info.num_inline_push_consts;
- ctx->abi.base_inline_push_consts = ctx->shader_info->info.base_inline_push_consts;
+ ctx->abi.num_inline_push_consts = ctx->shader_info->num_inline_push_consts;
+ ctx->abi.base_inline_push_consts = ctx->shader_info->base_inline_push_consts;
- if (ctx->shader_info->info.so.num_outputs) {
+ if (ctx->shader_info->so.num_outputs) {
add_arg(args, ARG_SGPR,
ac_array_in_const32_addr_space(ctx->ac.v4i32),
&ctx->streamout_buffers);
if (!ctx->is_gs_copy_shader &&
(stage == MESA_SHADER_VERTEX ||
(has_previous_stage && previous_stage == MESA_SHADER_VERTEX))) {
- if (ctx->shader_info->info.vs.has_vertex_buffers) {
+ if (ctx->shader_info->vs.has_vertex_buffers) {
add_arg(args, ARG_SGPR,
ac_array_in_const32_addr_space(ctx->ac.v4i32),
&ctx->vertex_buffers);
}
add_arg(args, ARG_SGPR, ctx->ac.i32, &ctx->abi.base_vertex);
add_arg(args, ARG_SGPR, ctx->ac.i32, &ctx->abi.start_instance);
- if (ctx->shader_info->info.vs.needs_draw_id) {
+ if (ctx->shader_info->vs.needs_draw_id) {
add_arg(args, ARG_SGPR, ctx->ac.i32, &ctx->abi.draw_id);
}
}
}
} else {
if (ctx->ac.chip_class >= GFX10) {
- add_arg(args, ARG_VGPR, ctx->ac.i32, NULL); /* user vgpr */
- add_arg(args, ARG_VGPR, ctx->ac.i32, NULL); /* user vgpr */
- add_arg(args, ARG_VGPR, ctx->ac.i32, &ctx->abi.instance_id);
+ if (ctx->options->key.vs_common_out.as_ngg) {
+ add_arg(args, ARG_VGPR, ctx->ac.i32, NULL); /* user vgpr */
+ add_arg(args, ARG_VGPR, ctx->ac.i32, NULL); /* user vgpr */
+ add_arg(args, ARG_VGPR, ctx->ac.i32, &ctx->abi.instance_id);
+ } else {
+ add_arg(args, ARG_VGPR, ctx->ac.i32, NULL); /* unused */
+ add_arg(args, ARG_VGPR, ctx->ac.i32, &ctx->vs_prim_id);
+ add_arg(args, ARG_VGPR, ctx->ac.i32, &ctx->abi.instance_id);
+ }
} else {
add_arg(args, ARG_VGPR, ctx->ac.i32, &ctx->abi.instance_id);
add_arg(args, ARG_VGPR, ctx->ac.i32, &ctx->vs_prim_id);
{
int i;
- if (ctx->ac.chip_class >= GFX10)
- return;
-
/* Streamout SGPRs. */
- if (ctx->shader_info->info.so.num_outputs) {
+ if (ctx->shader_info->so.num_outputs) {
assert(stage == MESA_SHADER_VERTEX ||
stage == MESA_SHADER_TESS_EVAL);
/* A streamout buffer offset is loaded if the stride is non-zero. */
for (i = 0; i < 4; i++) {
- if (!ctx->shader_info->info.so.strides[i])
+ if (!ctx->shader_info->so.strides[i])
continue;
add_arg(args, ARG_SGPR, ctx->ac.i32, &ctx->streamout_offset[i]);
const struct user_sgpr_info *user_sgpr_info,
LLVMValueRef desc_sets, uint8_t *user_sgpr_idx)
{
- uint32_t mask = ctx->shader_info->info.desc_set_used_mask;
+ uint32_t mask = ctx->shader_info->desc_set_used_mask;
if (!user_sgpr_info->indirect_all_descriptor_sets) {
while (mask) {
ctx->shader_info->need_indirect_descriptor_sets = true;
}
- if (ctx->shader_info->info.loads_push_constants) {
+ if (ctx->shader_info->loads_push_constants) {
set_loc_shader_ptr(ctx, AC_UD_PUSH_CONSTANTS, user_sgpr_idx);
}
- if (ctx->shader_info->info.num_inline_push_consts) {
+ if (ctx->shader_info->num_inline_push_consts) {
set_loc_shader(ctx, AC_UD_INLINE_PUSH_CONSTANTS, user_sgpr_idx,
- ctx->shader_info->info.num_inline_push_consts);
+ ctx->shader_info->num_inline_push_consts);
}
if (ctx->streamout_buffers) {
if (!ctx->is_gs_copy_shader &&
(stage == MESA_SHADER_VERTEX ||
(has_previous_stage && previous_stage == MESA_SHADER_VERTEX))) {
- if (ctx->shader_info->info.vs.has_vertex_buffers) {
+ if (ctx->shader_info->vs.has_vertex_buffers) {
set_loc_shader_ptr(ctx, AC_UD_VS_VERTEX_BUFFERS,
user_sgpr_idx);
}
unsigned vs_num = 2;
- if (ctx->shader_info->info.vs.needs_draw_id)
+ if (ctx->shader_info->vs.needs_draw_id)
vs_num++;
set_loc_shader(ctx, AC_UD_VS_BASE_VERTEX_START_INSTANCE,
declare_global_input_sgprs(ctx, &user_sgpr_info, &args,
&desc_sets);
- if (ctx->shader_info->info.cs.uses_grid_size) {
+ if (ctx->shader_info->cs.uses_grid_size) {
add_arg(&args, ARG_SGPR, ctx->ac.v3i32,
&ctx->abi.num_work_groups);
}
for (int i = 0; i < 3; i++) {
ctx->abi.workgroup_ids[i] = NULL;
- if (ctx->shader_info->info.cs.uses_block_id[i]) {
+ if (ctx->shader_info->cs.uses_block_id[i]) {
add_arg(&args, ARG_SGPR, ctx->ac.i32,
&ctx->abi.workgroup_ids[i]);
}
}
- if (ctx->shader_info->info.cs.uses_local_invocation_idx)
+ if (ctx->shader_info->cs.uses_local_invocation_idx)
add_arg(&args, ARG_SGPR, ctx->ac.i32, &ctx->abi.tg_size);
add_arg(&args, ARG_VGPR, ctx->ac.v3i32,
&ctx->abi.local_invocation_ids);
&desc_sets);
add_arg(&args, ARG_SGPR, ctx->ac.i32, &ctx->abi.prim_mask);
- add_arg(&args, ARG_VGPR, ctx->ac.v2i32, &ctx->persp_sample);
- add_arg(&args, ARG_VGPR, ctx->ac.v2i32, &ctx->persp_center);
- add_arg(&args, ARG_VGPR, ctx->ac.v2i32, &ctx->persp_centroid);
+ add_arg(&args, ARG_VGPR, ctx->ac.v2i32, &ctx->abi.persp_sample);
+ add_arg(&args, ARG_VGPR, ctx->ac.v2i32, &ctx->abi.persp_center);
+ add_arg(&args, ARG_VGPR, ctx->ac.v2i32, &ctx->abi.persp_centroid);
add_arg(&args, ARG_VGPR, ctx->ac.v3i32, NULL); /* persp pull model */
- add_arg(&args, ARG_VGPR, ctx->ac.v2i32, &ctx->linear_sample);
- add_arg(&args, ARG_VGPR, ctx->ac.v2i32, &ctx->linear_center);
- add_arg(&args, ARG_VGPR, ctx->ac.v2i32, &ctx->linear_centroid);
+ add_arg(&args, ARG_VGPR, ctx->ac.v2i32, &ctx->abi.linear_sample);
+ add_arg(&args, ARG_VGPR, ctx->ac.v2i32, &ctx->abi.linear_center);
+ add_arg(&args, ARG_VGPR, ctx->ac.v2i32, &ctx->abi.linear_centroid);
add_arg(&args, ARG_VGPR, ctx->ac.f32, NULL); /* line stipple tex */
add_arg(&args, ARG_VGPR, ctx->ac.f32, &ctx->abi.frag_pos[0]);
add_arg(&args, ARG_VGPR, ctx->ac.f32, &ctx->abi.frag_pos[1]);
switch (stage) {
case MESA_SHADER_COMPUTE:
- if (ctx->shader_info->info.cs.uses_grid_size) {
+ if (ctx->shader_info->cs.uses_grid_size) {
set_loc_shader(ctx, AC_UD_CS_GRID_SIZE,
&user_sgpr_idx, 3);
}
uint32_t desc_type = S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) |
S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) |
S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) |
- S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W) |
- S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
- S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32);
+ S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W);
+
+ if (ctx->ac.chip_class >= GFX10) {
+ desc_type |= S_008F0C_FORMAT(V_008F0C_IMG_FORMAT_32_FLOAT) |
+ S_008F0C_OOB_SELECT(3) |
+ S_008F0C_RESOURCE_LEVEL(1);
+ } else {
+ desc_type |= S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
+ S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32);
+ }
LLVMValueRef desc_components[4] = {
LLVMBuildPtrToInt(ctx->ac.builder, desc_ptr, ctx->ac.intptr, ""),
uint32_t num_patches = ctx->tcs_num_patches;
uint32_t num_tcs_outputs;
if (ctx->stage == MESA_SHADER_TESS_CTRL)
- num_tcs_outputs = util_last_bit64(ctx->shader_info->info.tcs.outputs_written);
+ num_tcs_outputs = util_last_bit64(ctx->shader_info->tcs.outputs_written);
else
num_tcs_outputs = ctx->options->key.tes.tcs_num_outputs;
uint32_t output_vertex_size = num_tcs_outputs * 16;
- uint32_t pervertex_output_patch_size = ctx->tcs_vertices_per_patch * output_vertex_size;
+ uint32_t pervertex_output_patch_size = ctx->shader->info.tess.tcs_vertices_out * output_vertex_size;
return LLVMConstInt(ctx->ac.i32, pervertex_output_patch_size * num_patches, false);
}
{
LLVMValueRef param_stride;
if (vertex_index)
- param_stride = LLVMConstInt(ctx->ac.i32, ctx->tcs_vertices_per_patch * ctx->tcs_num_patches, false);
+ param_stride = LLVMConstInt(ctx->ac.i32, ctx->shader->info.tess.tcs_vertices_out * ctx->tcs_num_patches, false);
else
param_stride = LLVMConstInt(ctx->ac.i32, ctx->tcs_num_patches, false);
return param_stride;
LLVMValueRef base_addr;
LLVMValueRef param_stride, constant16;
LLVMValueRef rel_patch_id = get_rel_patch_id(ctx);
- LLVMValueRef vertices_per_patch = LLVMConstInt(ctx->ac.i32, ctx->tcs_vertices_per_patch, false);
+ LLVMValueRef vertices_per_patch = LLVMConstInt(ctx->ac.i32, ctx->shader->info.tess.tcs_vertices_out, false);
constant16 = LLVMConstInt(ctx->ac.i32, 16, false);
param_stride = calc_param_stride(ctx, vertex_index);
if (vertex_index) {
bool store_lds = true;
if (is_patch) {
- if (!(ctx->tcs_patch_outputs_read & (1U << (location - VARYING_SLOT_PATCH0))))
+ if (!(ctx->shader->info.patch_outputs_read & (1U << (location - VARYING_SLOT_PATCH0))))
store_lds = false;
} else {
- if (!(ctx->tcs_outputs_read & (1ULL << location)))
+ if (!(ctx->shader->info.outputs_read & (1ULL << location)))
store_lds = false;
}
ac_build_kill_if_false(&ctx->ac, visible);
}
-static LLVMValueRef lookup_interp_param(struct ac_shader_abi *abi,
- enum glsl_interp_mode interp, unsigned location)
-{
- struct radv_shader_context *ctx = radv_shader_context_from_abi(abi);
-
- switch (interp) {
- case INTERP_MODE_FLAT:
- default:
- return NULL;
- case INTERP_MODE_SMOOTH:
- case INTERP_MODE_NONE:
- if (location == INTERP_CENTER)
- return ctx->persp_center;
- else if (location == INTERP_CENTROID)
- return ctx->persp_centroid;
- else if (location == INTERP_SAMPLE)
- return ctx->persp_sample;
- break;
- case INTERP_MODE_NOPERSPECTIVE:
- if (location == INTERP_CENTER)
- return ctx->linear_center;
- else if (location == INTERP_CENTROID)
- return ctx->linear_centroid;
- else if (location == INTERP_SAMPLE)
- return ctx->linear_sample;
- break;
- }
- return NULL;
-}
-
static uint32_t
radv_get_sample_pos_offset(uint32_t num_samples)
{
struct radv_shader_context *ctx = radv_shader_context_from_abi(abi);
uint8_t log2_ps_iter_samples;
- if (ctx->shader_info->info.ps.force_persample) {
+ if (ctx->shader_info->ps.force_persample) {
log2_ps_iter_samples =
util_logbase2(ctx->options->key.fs.num_samples);
} else {
* effects other than emitting vertices.
*/
can_emit = LLVMBuildICmp(ctx->ac.builder, LLVMIntULT, gs_next_vertex,
- LLVMConstInt(ctx->ac.i32, ctx->gs_max_out_vertices, false), "");
+ LLVMConstInt(ctx->ac.i32, ctx->shader->info.gs.vertices_out, false), "");
ac_build_kill_if_false(&ctx->ac, can_emit);
for (unsigned i = 0; i < AC_LLVM_MAX_OUTPUTS; ++i) {
unsigned output_usage_mask =
- ctx->shader_info->info.gs.output_usage_mask[i];
+ ctx->shader_info->gs.output_usage_mask[i];
uint8_t output_stream =
- ctx->shader_info->info.gs.output_streams[i];
+ ctx->shader_info->gs.output_streams[i];
LLVMValueRef *out_ptr = &addrs[i * 4];
int length = util_last_bit(output_usage_mask);
out_ptr[j], "");
LLVMValueRef voffset =
LLVMConstInt(ctx->ac.i32, offset *
- ctx->gs_max_out_vertices, false);
+ ctx->shader->info.gs.vertices_out, false);
offset++;
ctx->ac.f32_0,
};
- if (ctx->tes_primitive_mode == GL_TRIANGLES)
+ if (ctx->shader->info.tess.primitive_mode == GL_TRIANGLES)
coord[2] = LLVMBuildFSub(ctx->ac.builder, ctx->ac.f32_1,
LLVMBuildFAdd(ctx->ac.builder, coord[0], coord[1], ""), "");
LLVMValueRef buffer_index;
unsigned attrib_count = glsl_count_attribute_slots(variable->type, true);
uint8_t input_usage_mask =
- ctx->shader_info->info.vs.input_usage_mask[variable->data.location];
+ ctx->shader_info->vs.input_usage_mask[variable->data.location];
unsigned num_input_channels = util_last_bit(input_usage_mask);
variable->data.driver_location = variable->data.location * 4;
if (uses_center && uses_centroid) {
LLVMValueRef sel = LLVMBuildICmp(ctx->ac.builder, LLVMIntSLT, ctx->abi.prim_mask, ctx->ac.i32_0, "");
- ctx->persp_centroid = LLVMBuildSelect(ctx->ac.builder, sel, ctx->persp_center, ctx->persp_centroid, "");
- ctx->linear_centroid = LLVMBuildSelect(ctx->ac.builder, sel, ctx->linear_center, ctx->linear_centroid, "");
+ ctx->abi.persp_centroid = LLVMBuildSelect(ctx->ac.builder, sel, ctx->abi.persp_center, ctx->abi.persp_centroid, "");
+ ctx->abi.linear_centroid = LLVMBuildSelect(ctx->ac.builder, sel, ctx->abi.linear_center, ctx->abi.linear_centroid, "");
}
}
}
mask_attribs = ((1ull << attrib_count) - 1) << idx;
- if (stage == MESA_SHADER_VERTEX ||
- stage == MESA_SHADER_TESS_EVAL ||
- stage == MESA_SHADER_GEOMETRY) {
- if (idx == VARYING_SLOT_CLIP_DIST0) {
- if (stage == MESA_SHADER_VERTEX) {
- ctx->shader_info->vs.outinfo.clip_dist_mask = (1 << shader->info.clip_distance_array_size) - 1;
- ctx->shader_info->vs.outinfo.cull_dist_mask = (1 << shader->info.cull_distance_array_size) - 1;
- ctx->shader_info->vs.outinfo.cull_dist_mask <<= shader->info.clip_distance_array_size;
- }
- if (stage == MESA_SHADER_TESS_EVAL) {
- ctx->shader_info->tes.outinfo.clip_dist_mask = (1 << shader->info.clip_distance_array_size) - 1;
- ctx->shader_info->tes.outinfo.cull_dist_mask = (1 << shader->info.cull_distance_array_size) - 1;
- ctx->shader_info->tes.outinfo.cull_dist_mask <<= shader->info.clip_distance_array_size;
- }
- if (stage == MESA_SHADER_GEOMETRY) {
- ctx->shader_info->vs.outinfo.clip_dist_mask = (1 << shader->info.clip_distance_array_size) - 1;
- ctx->shader_info->vs.outinfo.cull_dist_mask = (1 << shader->info.cull_distance_array_size) - 1;
- ctx->shader_info->vs.outinfo.cull_dist_mask <<= shader->info.clip_distance_array_size;
- }
- }
- }
ctx->output_mask |= mask_attribs;
}
static void
radv_emit_streamout(struct radv_shader_context *ctx, unsigned stream)
{
- struct ac_build_if_state if_ctx;
int i;
/* Get bits [22:16], i.e. (so_param >> 16) & 127; */
* out-of-bounds buffer access. The hw tells us via the SGPR
* (so_vtx_count) which threads are allowed to emit streamout data.
*/
- ac_nir_build_if(&if_ctx, ctx, can_emit);
+ ac_build_ifcc(&ctx->ac, can_emit, 6501);
{
/* The buffer offset is computed as follows:
* ByteOffset = streamout_offset[buffer_id]*4 +
LLVMValueRef buf_ptr = ctx->streamout_buffers;
for (i = 0; i < 4; i++) {
- uint16_t stride = ctx->shader_info->info.so.strides[i];
+ uint16_t stride = ctx->shader_info->so.strides[i];
if (!stride)
continue;
}
/* Write streamout data. */
- for (i = 0; i < ctx->shader_info->info.so.num_outputs; i++) {
+ for (i = 0; i < ctx->shader_info->so.num_outputs; i++) {
struct radv_shader_output_values shader_out = {};
struct radv_stream_output *output =
- &ctx->shader_info->info.so.outputs[i];
+ &ctx->shader_info->so.outputs[i];
if (stream != output->stream)
continue;
output, &shader_out);
}
}
- ac_nir_build_endif(&if_ctx);
+ ac_build_endif(&ctx->ac, 6501);
}
static void
sizeof(outinfo->vs_output_param_offset));
outinfo->pos_exports = 0;
- if (ctx->output_mask & (1ull << VARYING_SLOT_PSIZ)) {
- outinfo->writes_pointsize = true;
- }
-
- if (ctx->output_mask & (1ull << VARYING_SLOT_LAYER)) {
- outinfo->writes_layer = true;
- }
-
- if (ctx->output_mask & (1ull << VARYING_SLOT_VIEWPORT)) {
- outinfo->writes_viewport_index = true;
- }
-
- if (ctx->shader_info->info.so.num_outputs &&
+ if (ctx->shader_info->so.num_outputs &&
!ctx->is_gs_copy_shader) {
/* The GS copy shader emission already emits streamout. */
radv_emit_streamout(ctx, 0);
if (ctx->stage == MESA_SHADER_VERTEX &&
!ctx->is_gs_copy_shader) {
outputs[noutput].usage_mask =
- ctx->shader_info->info.vs.output_usage_mask[i];
+ ctx->shader_info->vs.output_usage_mask[i];
} else if (ctx->stage == MESA_SHADER_TESS_EVAL) {
outputs[noutput].usage_mask =
- ctx->shader_info->info.tes.output_usage_mask[i];
+ ctx->shader_info->tes.output_usage_mask[i];
} else {
assert(ctx->is_gs_copy_shader);
outputs[noutput].usage_mask =
- ctx->shader_info->info.gs.output_usage_mask[i];
+ ctx->shader_info->gs.output_usage_mask[i];
}
for (unsigned j = 0; j < 4; j++) {
/* Export PrimitiveID. */
if (export_prim_id) {
- outinfo->export_prim_id = true;
-
outputs[noutput].slot_name = VARYING_SLOT_PRIMITIVE_ID;
outputs[noutput].slot_index = 0;
outputs[noutput].usage_mask = 0x1;
LLVMValueRef wave_idx = ac_unpack_param(&ctx->ac, ctx->merged_wave_info, 24, 4);
vertex_idx = LLVMBuildOr(ctx->ac.builder, vertex_idx,
LLVMBuildMul(ctx->ac.builder, wave_idx,
- LLVMConstInt(ctx->ac.i32, 64, false), ""), "");
+ LLVMConstInt(ctx->ac.i32,
+ ctx->ac.wave_size, false), ""), "");
lds_base = LLVMBuildMul(ctx->ac.builder, vertex_idx,
LLVMConstInt(ctx->ac.i32, itemsize_dw, 0), "");
}
if (ctx->stage == MESA_SHADER_VERTEX) {
output_usage_mask =
- ctx->shader_info->info.vs.output_usage_mask[i];
+ ctx->shader_info->vs.output_usage_mask[i];
} else {
assert(ctx->stage == MESA_SHADER_TESS_EVAL);
output_usage_mask =
- ctx->shader_info->info.tes.output_usage_mask[i];
+ ctx->shader_info->tes.output_usage_mask[i];
}
param_index = shader_io_get_unique_index(i);
handle_ls_outputs_post(struct radv_shader_context *ctx)
{
LLVMValueRef vertex_id = ctx->rel_auto_id;
- uint32_t num_tcs_inputs = util_last_bit64(ctx->shader_info->info.vs.ls_outputs_written);
+ uint32_t num_tcs_inputs = util_last_bit64(ctx->shader_info->vs.ls_outputs_written);
LLVMValueRef vertex_dw_stride = LLVMConstInt(ctx->ac.i32, num_tcs_inputs * 4, false);
LLVMValueRef base_dw_addr = LLVMBuildMul(ctx->ac.builder, vertex_id,
vertex_dw_stride, "");
LLVMBuilderRef builder = ctx->ac.builder;
LLVMValueRef tmp;
tmp = LLVMBuildMul(builder, get_wave_id_in_tg(ctx),
- LLVMConstInt(ctx->ac.i32, 64, false), "");
+ LLVMConstInt(ctx->ac.i32, ctx->ac.wave_size, false), "");
return LLVMBuildAdd(builder, tmp, ac_get_thread_id(&ctx->ac), "");
}
LLVMValueRef storage = ngg_gs_get_vertex_storage(ctx);
/* gs_max_out_vertices = 2^(write_stride_2exp) * some odd number */
- unsigned write_stride_2exp = ffs(ctx->gs_max_out_vertices) - 1;
+ unsigned write_stride_2exp = ffs(ctx->shader->info.gs.vertices_out) - 1;
if (write_stride_2exp) {
LLVMValueRef row =
LLVMBuildLShr(builder, vertexidx,
LLVMBuilderRef builder = ctx->ac.builder;
LLVMValueRef tmp;
- tmp = LLVMConstInt(ctx->ac.i32, ctx->gs_max_out_vertices, false);
+ tmp = LLVMConstInt(ctx->ac.i32, ctx->shader->info.gs.vertices_out, false);
tmp = LLVMBuildMul(builder, tmp, gsthread, "");
const LLVMValueRef vertexidx = LLVMBuildAdd(builder, tmp, emitidx, "");
return ngg_gs_vertex_ptr(ctx, vertexidx);
handle_ngg_outputs_post(struct radv_shader_context *ctx)
{
LLVMBuilderRef builder = ctx->ac.builder;
- struct ac_build_if_state if_state;
unsigned num_vertices = 3;
LLVMValueRef tmp;
* TODO: culling depends on the primitive type, so can have some
* interaction here.
*/
- ac_nir_build_if(&if_state, ctx, is_gs_thread);
+ ac_build_ifcc(&ctx->ac, is_gs_thread, 6001);
{
struct ngg_prim prim = {};
build_export_prim(ctx, &prim);
}
- ac_nir_build_endif(&if_state);
+ ac_build_endif(&ctx->ac, 6001);
/* Export per-vertex data (positions and parameters). */
- ac_nir_build_if(&if_state, ctx, is_es_thread);
+ ac_build_ifcc(&ctx->ac, is_es_thread, 6002);
{
struct radv_vs_output_info *outinfo =
ctx->stage == MESA_SHADER_TESS_EVAL ? &ctx->shader_info->tes.outinfo : &ctx->shader_info->vs.outinfo;
radv_export_param(ctx, param_count, values, 0x1);
outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID] = param_count++;
- outinfo->export_prim_id = true;
outinfo->param_exports = param_count;
}
}
- ac_nir_build_endif(&if_state);
+ ac_build_endif(&ctx->ac, 6002);
}
static void gfx10_ngg_gs_emit_prologue(struct radv_shader_context *ctx)
unsigned num_components;
num_components =
- ctx->shader_info->info.gs.num_stream_output_components[stream];
+ ctx->shader_info->gs.num_stream_output_components[stream];
if (!num_components)
continue;
const LLVMValueRef vertexidx =
LLVMBuildLoad(builder, ctx->gs_next_vertex[stream], "");
tmp = LLVMBuildICmp(builder, LLVMIntUGE, vertexidx,
- LLVMConstInt(ctx->ac.i32, ctx->gs_max_out_vertices, false), "");
+ LLVMConstInt(ctx->ac.i32, ctx->shader->info.gs.vertices_out, false), "");
ac_build_ifcc(&ctx->ac, tmp, 5101);
ac_build_break(&ctx->ac);
ac_build_endif(&ctx->ac, 5101);
static void gfx10_ngg_gs_emit_epilogue_2(struct radv_shader_context *ctx)
{
- const unsigned verts_per_prim = si_conv_gl_prim_to_vertices(ctx->gs_output_prim);
+ const unsigned verts_per_prim = si_conv_gl_prim_to_vertices(ctx->shader->info.gs.output_primitive);
LLVMBuilderRef builder = ctx->ac.builder;
LLVMValueRef tmp, tmp2;
tmp = LLVMBuildZExt(builder, tmp, ctx->ac.i32, "");
const LLVMValueRef vertexptr = ngg_gs_vertex_ptr(ctx, tmp);
- if (ctx->output_mask & (1ull << VARYING_SLOT_PSIZ)) {
- outinfo->writes_pointsize = true;
- }
-
- if (ctx->output_mask & (1ull << VARYING_SLOT_LAYER)) {
- outinfo->writes_layer = true;
- }
-
- if (ctx->output_mask & (1ull << VARYING_SLOT_VIEWPORT)) {
- outinfo->writes_viewport_index = true;
- }
-
unsigned out_idx = 0;
gep_idx[1] = ctx->ac.i32_0;
for (unsigned i = 0; i < AC_LLVM_MAX_OUTPUTS; ++i) {
outputs[noutput].slot_name = i;
outputs[noutput].slot_index = i == VARYING_SLOT_CLIP_DIST1;
- outputs[noutput].usage_mask = ctx->shader_info->info.gs.output_usage_mask[i];
+ outputs[noutput].usage_mask = ctx->shader_info->gs.output_usage_mask[i];
int length = util_last_bit(outputs[noutput].usage_mask);
for (unsigned j = 0; j < length; j++, out_idx++) {
/* Export ViewIndex. */
if (export_view_index) {
- outinfo->writes_layer = true;
-
outputs[noutput].slot_name = VARYING_SLOT_LAYER;
outputs[noutput].slot_index = 0;
outputs[noutput].usage_mask = 0x1;
*/
const LLVMValueRef can_emit =
LLVMBuildICmp(builder, LLVMIntULT, vertexidx,
- LLVMConstInt(ctx->ac.i32, ctx->gs_max_out_vertices, false), "");
+ LLVMConstInt(ctx->ac.i32, ctx->shader->info.gs.vertices_out, false), "");
ac_build_kill_if_false(&ctx->ac, can_emit);
tmp = LLVMBuildAdd(builder, vertexidx, ctx->ac.i32_1, "");
unsigned out_idx = 0;
for (unsigned i = 0; i < AC_LLVM_MAX_OUTPUTS; ++i) {
unsigned output_usage_mask =
- ctx->shader_info->info.gs.output_usage_mask[i];
+ ctx->shader_info->gs.output_usage_mask[i];
uint8_t output_stream =
- ctx->shader_info->info.gs.output_streams[i];
+ ctx->shader_info->gs.output_streams[i];
LLVMValueRef *out_ptr = &addrs[i * 4];
int length = util_last_bit(output_usage_mask);
/* Determine and store whether this vertex completed a primitive. */
const LLVMValueRef curverts = LLVMBuildLoad(builder, ctx->gs_curprim_verts[stream], "");
- tmp = LLVMConstInt(ctx->ac.i32, si_conv_gl_prim_to_vertices(ctx->gs_output_prim) - 1, false);
+ tmp = LLVMConstInt(ctx->ac.i32, si_conv_gl_prim_to_vertices(ctx->shader->info.gs.output_primitive) - 1, false);
const LLVMValueRef iscompleteprim =
LLVMBuildICmp(builder, LLVMIntUGE, curverts, tmp, "");
write_tess_factors(struct radv_shader_context *ctx)
{
unsigned stride, outer_comps, inner_comps;
- struct ac_build_if_state if_ctx, inner_if_ctx;
LLVMValueRef invocation_id = ac_unpack_param(&ctx->ac, ctx->abi.tcs_rel_ids, 8, 5);
LLVMValueRef rel_patch_id = ac_unpack_param(&ctx->ac, ctx->abi.tcs_rel_ids, 0, 8);
unsigned tess_inner_index = 0, tess_outer_index;
return;
}
- ac_nir_build_if(&if_ctx, ctx,
+ ac_build_ifcc(&ctx->ac,
LLVMBuildICmp(ctx->ac.builder, LLVMIntEQ,
- invocation_id, ctx->ac.i32_0, ""));
+ invocation_id, ctx->ac.i32_0, ""), 6503);
lds_base = get_tcs_out_current_patch_data_offset(ctx);
unsigned tf_offset = 0;
if (ctx->options->chip_class <= GFX8) {
- ac_nir_build_if(&inner_if_ctx, ctx,
+ ac_build_ifcc(&ctx->ac,
LLVMBuildICmp(ctx->ac.builder, LLVMIntEQ,
- rel_patch_id, ctx->ac.i32_0, ""));
+ rel_patch_id, ctx->ac.i32_0, ""), 6504);
/* Store the dynamic HS control word. */
ac_build_buffer_store_dword(&ctx->ac, buffer,
0, ac_glc, false);
tf_offset += 4;
- ac_nir_build_endif(&inner_if_ctx);
+ ac_build_endif(&ctx->ac, 6504);
}
/* Store the tessellation factors. */
ctx->oc_lds, 0, ac_glc, false);
}
}
- ac_nir_build_endif(&if_ctx);
+
+ ac_build_endif(&ctx->ac, 6503);
}
static void
}
/* Process depth, stencil, samplemask. */
- if (ctx->shader_info->info.ps.writes_z) {
+ if (ctx->shader_info->ps.writes_z) {
depth = ac_to_float(&ctx->ac,
radv_load_output(ctx, FRAG_RESULT_DEPTH, 0));
}
- if (ctx->shader_info->info.ps.writes_stencil) {
+ if (ctx->shader_info->ps.writes_stencil) {
stencil = ac_to_float(&ctx->ac,
radv_load_output(ctx, FRAG_RESULT_STENCIL, 0));
}
- if (ctx->shader_info->info.ps.writes_sample_mask) {
+ if (ctx->shader_info->ps.writes_sample_mask) {
samplemask = ac_to_float(&ctx->ac,
radv_load_output(ctx, FRAG_RESULT_SAMPLE_MASK, 0));
}
* exported.
*/
if (index > 0 &&
- !ctx->shader_info->info.ps.writes_z &&
- !ctx->shader_info->info.ps.writes_stencil &&
- !ctx->shader_info->info.ps.writes_sample_mask) {
+ !ctx->shader_info->ps.writes_z &&
+ !ctx->shader_info->ps.writes_stencil &&
+ !ctx->shader_info->ps.writes_sample_mask) {
unsigned last = index - 1;
color_args[last].valid_mask = 1; /* whether the EXEC mask is valid */
*/
LLVMTypeRef v2i64 = LLVMVectorType(ctx->ac.i64, 2);
uint64_t stream_offset = 0;
- unsigned num_records = 64;
+ unsigned num_records = ctx->ac.wave_size;
LLVMValueRef base_ring;
base_ring =
LLVMValueRef ring, tmp;
num_components =
- ctx->shader_info->info.gs.num_stream_output_components[stream];
+ ctx->shader_info->gs.num_stream_output_components[stream];
if (!num_components)
continue;
- stride = 4 * num_components * ctx->gs_max_out_vertices;
+ stride = 4 * num_components * ctx->shader->info.gs.vertices_out;
/* Limit on the stride field for <= GFX7. */
assert(stride < (1 << 14));
ring = LLVMBuildInsertElement(ctx->ac.builder,
ring, tmp, ctx->ac.i32_0, "");
- stream_offset += stride * 64;
+ stream_offset += stride * ctx->ac.wave_size;
ring = LLVMBuildBitCast(ctx->ac.builder, ring,
ctx->ac.v4i32, "");
unsigned
radv_nir_get_max_workgroup_size(enum chip_class chip_class,
+ gl_shader_stage stage,
const struct nir_shader *nir)
{
- switch (nir->info.stage) {
- case MESA_SHADER_TESS_CTRL:
- return chip_class >= GFX7 ? 128 : 64;
- case MESA_SHADER_GEOMETRY:
- return chip_class >= GFX9 ? 128 : 64;
- case MESA_SHADER_COMPUTE:
- break;
- default:
- return 0;
- }
-
- unsigned max_workgroup_size = nir->info.cs.local_size[0] *
- nir->info.cs.local_size[1] *
- nir->info.cs.local_size[2];
- return max_workgroup_size;
+ const unsigned backup_sizes[] = {chip_class >= GFX9 ? 128 : 64, 1, 1};
+ return radv_get_max_workgroup_size(chip_class, stage, nir ? nir->info.cs.local_size : backup_sizes);
}
/* Fixup the HW not emitting the TCS regs if there are no HS threads. */
LLVMModuleRef ac_translate_nir_to_llvm(struct ac_llvm_compiler *ac_llvm,
struct nir_shader *const *shaders,
int shader_count,
- struct radv_shader_variant_info *shader_info,
+ struct radv_shader_info *shader_info,
const struct radv_nir_compiler_options *options)
{
struct radv_shader_context ctx = {0};
ctx.options = options;
ctx.shader_info = shader_info;
- ac_llvm_context_init(&ctx.ac, options->chip_class, options->family);
- ctx.context = ctx.ac.context;
- ctx.ac.module = ac_create_module(ac_llvm->tm, ctx.context);
-
enum ac_float_mode float_mode =
options->unsafe_math ? AC_FLOAT_MODE_UNSAFE_FP_MATH :
AC_FLOAT_MODE_DEFAULT;
- ctx.ac.builder = ac_create_builder(ctx.context, float_mode);
+ ac_llvm_context_init(&ctx.ac, ac_llvm, options->chip_class,
+ options->family, float_mode, options->wave_size, 64);
+ ctx.context = ctx.ac.context;
- radv_nir_shader_info_init(&shader_info->info);
+ radv_nir_shader_info_init(shader_info);
for(int i = 0; i < shader_count; ++i)
- radv_nir_shader_info_pass(shaders[i], options, &shader_info->info);
+ radv_nir_shader_info_pass(shaders[i], options, shader_info);
- for (i = 0; i < RADV_UD_MAX_SETS; i++)
+ for (i = 0; i < MAX_SETS; i++)
shader_info->user_sgprs_locs.descriptor_sets[i].sgpr_idx = -1;
for (i = 0; i < AC_UD_MAX_UD; i++)
shader_info->user_sgprs_locs.shader_data[i].sgpr_idx = -1;
for (int i = 0; i < shader_count; ++i) {
ctx.max_workgroup_size = MAX2(ctx.max_workgroup_size,
radv_nir_get_max_workgroup_size(ctx.options->chip_class,
- shaders[i]));
+ shaders[i]->info.stage,
+ shaders[i]));
}
if (ctx.ac.chip_class >= GFX10) {
ctx.abi.load_sampler_desc = radv_get_sampler_desc;
ctx.abi.load_resource = radv_load_resource;
ctx.abi.clamp_shadow_reference = false;
- ctx.abi.gfx9_stride_size_workaround = ctx.ac.chip_class == GFX9 && HAVE_LLVM < 0x800;
-
- /* Because the new raw/struct atomic intrinsics are buggy with LLVM 8,
- * we fallback to the old intrinsics for atomic buffer image operations
- * and thus we need to apply the indexing workaround...
- */
- ctx.abi.gfx9_stride_size_workaround_for_atomic = ctx.ac.chip_class == GFX9 && HAVE_LLVM < 0x900;
+ ctx.abi.robust_buffer_access = options->robust_buffer_access;
bool is_ngg = is_pre_gs_stage(shaders[0]->info.stage) && ctx.options->key.vs_common_out.as_ngg;
if (shader_count >= 2 || is_ngg)
ac_init_exec_full_mask(&ctx.ac);
- if ((ctx.ac.family == CHIP_VEGA10 ||
- ctx.ac.family == CHIP_RAVEN) &&
+ if (options->has_ls_vgpr_init_bug &&
shaders[shader_count - 1]->info.stage == MESA_SHADER_TESS_CTRL)
ac_nir_fixup_ls_hs_input_vgprs(&ctx);
for(int i = 0; i < shader_count; ++i) {
ctx.stage = shaders[i]->info.stage;
+ ctx.shader = shaders[i];
ctx.output_mask = 0;
if (shaders[i]->info.stage == MESA_SHADER_GEOMETRY) {
"ngg_emit");
}
- ctx.gs_max_out_vertices = shaders[i]->info.gs.vertices_out;
- ctx.gs_output_prim = shaders[i]->info.gs.output_primitive;
ctx.abi.load_inputs = load_gs_input;
ctx.abi.emit_primitive = visit_end_primitive;
} else if (shaders[i]->info.stage == MESA_SHADER_TESS_CTRL) {
- ctx.tcs_outputs_read = shaders[i]->info.outputs_read;
- ctx.tcs_patch_outputs_read = shaders[i]->info.patch_outputs_read;
ctx.abi.load_tess_varyings = load_tcs_varyings;
ctx.abi.load_patch_vertices_in = load_patch_vertices_in;
ctx.abi.store_tcs_outputs = store_tcs_output;
- ctx.tcs_vertices_per_patch = shaders[i]->info.tess.tcs_vertices_out;
if (shader_count == 1)
ctx.tcs_num_inputs = ctx.options->key.tcs.num_inputs;
else
- ctx.tcs_num_inputs = util_last_bit64(shader_info->info.vs.ls_outputs_written);
+ ctx.tcs_num_inputs = util_last_bit64(shader_info->vs.ls_outputs_written);
ctx.tcs_num_patches = get_tcs_num_patches(&ctx);
} else if (shaders[i]->info.stage == MESA_SHADER_TESS_EVAL) {
- ctx.tes_primitive_mode = shaders[i]->info.tess.primitive_mode;
ctx.abi.load_tess_varyings = load_tes_input;
ctx.abi.load_tess_coord = load_tess_coord;
ctx.abi.load_patch_vertices_in = load_patch_vertices_in;
- ctx.tcs_vertices_per_patch = shaders[i]->info.tess.tcs_vertices_out;
ctx.tcs_num_patches = ctx.options->key.tes.num_patches;
} else if (shaders[i]->info.stage == MESA_SHADER_VERTEX) {
ctx.abi.load_base_vertex = radv_load_base_vertex;
} else if (shaders[i]->info.stage == MESA_SHADER_FRAGMENT) {
- shader_info->fs.can_discard = shaders[i]->info.fs.uses_discard;
- ctx.abi.lookup_interp_param = lookup_interp_param;
ctx.abi.load_sample_position = load_sample_position;
ctx.abi.load_sample_mask_in = load_sample_mask_in;
ctx.abi.emit_kill = radv_emit_kill;
declare_esgs_ring(&ctx);
}
- if (i)
+ bool nested_barrier = false;
+
+ if (i) {
+ if (shaders[i]->info.stage == MESA_SHADER_GEOMETRY &&
+ ctx.options->key.vs_common_out.as_ngg) {
+ gfx10_ngg_gs_emit_prologue(&ctx);
+ nested_barrier = false;
+ } else {
+ nested_barrier = true;
+ }
+ }
+
+ if (nested_barrier) {
+ /* Execute a barrier before the second shader in
+ * a merged shader.
+ *
+ * Execute the barrier inside the conditional block,
+ * so that empty waves can jump directly to s_endpgm,
+ * which will also signal the barrier.
+ *
+ * This is possible in gfx9, because an empty wave
+ * for the second shader does not participate in
+ * the epilogue. With NGG, empty waves may still
+ * be required to export data (e.g. GS output vertices),
+ * so we cannot let them exit early.
+ *
+ * If the shader is TCS and the TCS epilog is present
+ * and contains a barrier, it will wait there and then
+ * reach s_endpgm.
+ */
ac_emit_barrier(&ctx.ac, ctx.stage);
+ }
nir_foreach_variable(variable, &shaders[i]->outputs)
scan_shader_output_decl(&ctx, variable, shaders[i], shaders[i]->info.stage);
LLVMBasicBlockRef merge_block;
if (shader_count >= 2 || is_ngg) {
-
- if (shaders[i]->info.stage == MESA_SHADER_GEOMETRY &&
- ctx.options->key.vs_common_out.as_ngg) {
- gfx10_ngg_gs_emit_prologue(&ctx);
- }
-
LLVMValueRef fn = LLVMGetBasicBlockParent(LLVMGetInsertBlock(ctx.ac.builder));
LLVMBasicBlockRef then_block = LLVMAppendBasicBlockInContext(ctx.ac.context, fn, "");
merge_block = LLVMAppendBasicBlockInContext(ctx.ac.context, fn, "");
static void ac_compile_llvm_module(struct ac_llvm_compiler *ac_llvm,
LLVMModuleRef llvm_module,
struct radv_shader_binary **rbinary,
- struct radv_shader_variant_info *shader_info,
gl_shader_stage stage,
const char *name,
const struct radv_nir_compiler_options *options)
free(elf_buffer);
}
-static void
-ac_fill_shader_info(struct radv_shader_variant_info *shader_info, struct nir_shader *nir, const struct radv_nir_compiler_options *options)
-{
- switch (nir->info.stage) {
- case MESA_SHADER_COMPUTE:
- for (int i = 0; i < 3; ++i)
- shader_info->cs.block_size[i] = nir->info.cs.local_size[i];
- break;
- case MESA_SHADER_FRAGMENT:
- shader_info->fs.early_fragment_test = nir->info.fs.early_fragment_tests;
- shader_info->fs.post_depth_coverage = nir->info.fs.post_depth_coverage;
- break;
- case MESA_SHADER_GEOMETRY:
- shader_info->gs.vertices_in = nir->info.gs.vertices_in;
- shader_info->gs.vertices_out = nir->info.gs.vertices_out;
- shader_info->gs.output_prim = nir->info.gs.output_primitive;
- shader_info->gs.invocations = nir->info.gs.invocations;
- break;
- case MESA_SHADER_TESS_EVAL:
- shader_info->tes.primitive_mode = nir->info.tess.primitive_mode;
- shader_info->tes.spacing = nir->info.tess.spacing;
- shader_info->tes.ccw = nir->info.tess.ccw;
- shader_info->tes.point_mode = nir->info.tess.point_mode;
- shader_info->tes.as_es = options->key.vs_common_out.as_es;
- shader_info->tes.export_prim_id = options->key.vs_common_out.export_prim_id;
- shader_info->is_ngg = options->key.vs_common_out.as_ngg;
- break;
- case MESA_SHADER_TESS_CTRL:
- shader_info->tcs.tcs_vertices_out = nir->info.tess.tcs_vertices_out;
- break;
- case MESA_SHADER_VERTEX:
- shader_info->vs.as_es = options->key.vs_common_out.as_es;
- shader_info->vs.as_ls = options->key.vs_common_out.as_ls;
- shader_info->vs.export_prim_id = options->key.vs_common_out.export_prim_id;
- shader_info->is_ngg = options->key.vs_common_out.as_ngg;
- break;
- default:
- break;
- }
-}
-
void
radv_compile_nir_shader(struct ac_llvm_compiler *ac_llvm,
struct radv_shader_binary **rbinary,
- struct radv_shader_variant_info *shader_info,
+ struct radv_shader_info *shader_info,
struct nir_shader *const *nir,
int nir_count,
const struct radv_nir_compiler_options *options)
llvm_module = ac_translate_nir_to_llvm(ac_llvm, nir, nir_count, shader_info,
options);
- ac_compile_llvm_module(ac_llvm, llvm_module, rbinary, shader_info,
+ ac_compile_llvm_module(ac_llvm, llvm_module, rbinary,
nir[nir_count - 1]->info.stage,
radv_get_shader_name(shader_info,
nir[nir_count - 1]->info.stage),
options);
- for (int i = 0; i < nir_count; ++i)
- ac_fill_shader_info(shader_info, nir[i], options);
-
/* Determine the ES type (VS or TES) for the GS on GFX9. */
if (options->chip_class >= GFX9) {
if (nir_count == 2 &&
shader_info->gs.es_type = nir[0]->info.stage;
}
}
+ shader_info->wave_size = options->wave_size;
}
static void
LLVMValueRef stream_id;
/* Fetch the vertex stream ID. */
- if (ctx->shader_info->info.so.num_outputs) {
+ if (ctx->shader_info->so.num_outputs) {
stream_id =
ac_unpack_param(&ctx->ac, ctx->streamout_config, 24, 2);
} else {
for (unsigned stream = 0; stream < 4; stream++) {
unsigned num_components =
- ctx->shader_info->info.gs.num_stream_output_components[stream];
+ ctx->shader_info->gs.num_stream_output_components[stream];
LLVMBasicBlockRef bb;
unsigned offset;
if (!num_components)
continue;
- if (stream > 0 && !ctx->shader_info->info.so.num_outputs)
+ if (stream > 0 && !ctx->shader_info->so.num_outputs)
continue;
bb = LLVMInsertBasicBlockInContext(ctx->ac.context, end_bb, "out");
offset = 0;
for (unsigned i = 0; i < AC_LLVM_MAX_OUTPUTS; ++i) {
unsigned output_usage_mask =
- ctx->shader_info->info.gs.output_usage_mask[i];
+ ctx->shader_info->gs.output_usage_mask[i];
unsigned output_stream =
- ctx->shader_info->info.gs.output_streams[i];
+ ctx->shader_info->gs.output_streams[i];
int length = util_last_bit(output_usage_mask);
if (!(ctx->output_mask & (1ull << i)) ||
soffset = LLVMConstInt(ctx->ac.i32,
offset *
- ctx->gs_max_out_vertices * 16 * 4, false);
+ ctx->shader->info.gs.vertices_out * 16 * 4, false);
offset++;
}
}
- if (ctx->shader_info->info.so.num_outputs)
+ if (ctx->shader_info->so.num_outputs)
radv_emit_streamout(ctx, stream);
if (stream == 0) {
radv_compile_gs_copy_shader(struct ac_llvm_compiler *ac_llvm,
struct nir_shader *geom_shader,
struct radv_shader_binary **rbinary,
- struct radv_shader_variant_info *shader_info,
+ struct radv_shader_info *shader_info,
const struct radv_nir_compiler_options *options)
{
struct radv_shader_context ctx = {0};
ctx.options = options;
ctx.shader_info = shader_info;
- ac_llvm_context_init(&ctx.ac, options->chip_class, options->family);
- ctx.context = ctx.ac.context;
- ctx.ac.module = ac_create_module(ac_llvm->tm, ctx.context);
-
- ctx.is_gs_copy_shader = true;
-
enum ac_float_mode float_mode =
options->unsafe_math ? AC_FLOAT_MODE_UNSAFE_FP_MATH :
AC_FLOAT_MODE_DEFAULT;
- ctx.ac.builder = ac_create_builder(ctx.context, float_mode);
+ ac_llvm_context_init(&ctx.ac, ac_llvm, options->chip_class,
+ options->family, float_mode, 64, 64);
+ ctx.context = ctx.ac.context;
+
+ ctx.is_gs_copy_shader = true;
ctx.stage = MESA_SHADER_VERTEX;
+ ctx.shader = geom_shader;
- radv_nir_shader_info_pass(geom_shader, options, &shader_info->info);
+ radv_nir_shader_info_pass(geom_shader, options, shader_info);
create_function(&ctx, MESA_SHADER_VERTEX, false, MESA_SHADER_VERTEX);
- ctx.gs_max_out_vertices = geom_shader->info.gs.vertices_out;
ac_setup_rings(&ctx);
nir_foreach_variable(variable, &geom_shader->outputs) {
ac_llvm_finalize_module(&ctx, ac_llvm->passmgr, options);
- ac_compile_llvm_module(ac_llvm, ctx.ac.module, rbinary, shader_info,
+ ac_compile_llvm_module(ac_llvm, ctx.ac.module, rbinary,
MESA_SHADER_VERTEX, "GS Copy Shader", options);
(*rbinary)->is_gs_copy_shader = true;