#include "radv_private.h"
#include "radv_shader.h"
+#include "radv_shader_helper.h"
#include "nir/nir.h"
#include <llvm-c/Core.h>
LLVMValueRef hs_ring_tess_offchip;
LLVMValueRef hs_ring_tess_factor;
- LLVMValueRef sample_pos_offset;
LLVMValueRef persp_sample, persp_center, persp_centroid;
LLVMValueRef linear_sample, linear_center, linear_centroid;
set_loc_desc(struct radv_shader_context *ctx, int idx, uint8_t *sgpr_idx,
uint32_t indirect_offset)
{
- struct radv_userdata_info *ud_info =
- &ctx->shader_info->user_sgprs_locs.descriptor_sets[idx];
+ struct radv_userdata_locations *locs =
+ &ctx->shader_info->user_sgprs_locs;
+ struct radv_userdata_info *ud_info = &locs->descriptor_sets[idx];
assert(ud_info);
set_loc(ud_info, sgpr_idx, HAVE_32BIT_POINTERS ? 1 : 2, indirect_offset);
+ if (indirect_offset == 0)
+ locs->descriptor_sets_enabled |= 1 << idx;
}
struct user_sgpr_info {
previous_stage, &user_sgpr_info,
&args, &desc_sets);
- if (ctx->shader_info->info.ps.needs_sample_positions)
- add_arg(&args, ARG_SGPR, ctx->ac.i32,
- &ctx->sample_pos_offset);
-
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);
set_loc_shader(ctx, AC_UD_VIEW_INDEX, &user_sgpr_idx, 1);
break;
case MESA_SHADER_FRAGMENT:
- if (ctx->shader_info->info.ps.needs_sample_positions) {
- set_loc_shader(ctx, AC_UD_PS_SAMPLE_POS_OFFSET,
- &user_sgpr_idx, 1);
- }
break;
default:
unreachable("Shader stage not implemented");
return NULL;
}
+static uint32_t
+radv_get_sample_pos_offset(uint32_t num_samples)
+{
+ uint32_t sample_pos_offset = 0;
+
+ switch (num_samples) {
+ case 2:
+ sample_pos_offset = 1;
+ break;
+ case 4:
+ sample_pos_offset = 3;
+ break;
+ case 8:
+ sample_pos_offset = 7;
+ break;
+ case 16:
+ sample_pos_offset = 15;
+ break;
+ default:
+ break;
+ }
+ return sample_pos_offset;
+}
+
static LLVMValueRef load_sample_position(struct ac_shader_abi *abi,
LLVMValueRef sample_id)
{
ptr = LLVMBuildBitCast(ctx->ac.builder, ptr,
ac_array_in_const_addr_space(ctx->ac.v2f32), "");
- sample_id = LLVMBuildAdd(ctx->ac.builder, sample_id, ctx->sample_pos_offset, "");
+ uint32_t sample_pos_offset =
+ radv_get_sample_pos_offset(ctx->options->key.fs.num_samples);
+
+ sample_id =
+ LLVMBuildAdd(ctx->ac.builder, sample_id,
+ LLVMConstInt(ctx->ac.i32, sample_pos_offset, false), "");
result = ac_build_load_invariant(&ctx->ac, ptr, sample_id);
return result;
static LLVMValueRef load_sample_mask_in(struct ac_shader_abi *abi)
{
struct radv_shader_context *ctx = radv_shader_context_from_abi(abi);
- uint8_t log2_ps_iter_samples = ctx->shader_info->info.ps.force_persample ?
- ctx->options->key.fs.log2_num_samples :
- ctx->options->key.fs.log2_ps_iter_samples;
+ uint8_t log2_ps_iter_samples;
+
+ if (ctx->shader_info->info.ps.force_persample) {
+ log2_ps_iter_samples =
+ util_logbase2(ctx->options->key.fs.num_samples);
+ } else {
+ log2_ps_iter_samples = ctx->options->key.fs.log2_ps_iter_samples;
+ }
/* The bit pattern matches that used by fixed function fragment
* processing. */
}
static void ac_llvm_finalize_module(struct radv_shader_context *ctx,
+ LLVMPassManagerRef passmgr,
const struct radv_nir_compiler_options *options)
{
- LLVMPassManagerRef passmgr;
- /* Create the pass manager */
- passmgr = LLVMCreateFunctionPassManagerForModule(
- ctx->ac.module);
-
- if (options->check_ir)
- LLVMAddVerifierPass(passmgr);
-
- /* This pass should eliminate all the load and store instructions */
- LLVMAddPromoteMemoryToRegisterPass(passmgr);
-
- /* Add some optimization passes */
- LLVMAddScalarReplAggregatesPass(passmgr);
- LLVMAddLICMPass(passmgr);
- LLVMAddAggressiveDCEPass(passmgr);
- LLVMAddCFGSimplificationPass(passmgr);
- /* This is recommended by the instruction combining pass. */
- LLVMAddEarlyCSEMemSSAPass(passmgr);
- LLVMAddInstructionCombiningPass(passmgr);
-
- /* Run the pass */
- LLVMInitializeFunctionPassManager(passmgr);
- LLVMRunFunctionPassManager(passmgr, ctx->main_function);
- LLVMFinalizeFunctionPassManager(passmgr);
-
+ LLVMRunPassManager(passmgr, ctx->ac.module);
LLVMDisposeBuilder(ctx->ac.builder);
- LLVMDisposePassManager(passmgr);
ac_llvm_context_dispose(&ctx->ac);
}
LLVMValueRef hs_empty = LLVMBuildICmp(ctx->ac.builder, LLVMIntEQ, count,
ctx->ac.i32_0, "");
ctx->abi.instance_id = LLVMBuildSelect(ctx->ac.builder, hs_empty, ctx->rel_auto_id, ctx->abi.instance_id, "");
- ctx->vs_prim_id = LLVMBuildSelect(ctx->ac.builder, hs_empty, ctx->abi.vertex_id, ctx->vs_prim_id, "");
ctx->rel_auto_id = LLVMBuildSelect(ctx->ac.builder, hs_empty, ctx->abi.tcs_rel_ids, ctx->rel_auto_id, "");
ctx->abi.vertex_id = LLVMBuildSelect(ctx->ac.builder, hs_empty, ctx->abi.tcs_patch_id, ctx->abi.vertex_id, "");
}
static
-LLVMModuleRef ac_translate_nir_to_llvm(LLVMTargetMachineRef tm,
+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,
unsigned i;
ctx.options = options;
ctx.shader_info = shader_info;
- ctx.context = LLVMContextCreate();
- ac_llvm_context_init(&ctx.ac, ctx.context, options->chip_class,
- options->family);
- ctx.ac.module = LLVMModuleCreateWithNameInContext("shader", ctx.context);
- LLVMSetTarget(ctx.ac.module, options->supports_spill ? "amdgcn-mesa-mesa3d" : "amdgcn--");
-
- LLVMTargetDataRef data_layout = LLVMCreateTargetDataLayout(tm);
- char *data_layout_str = LLVMCopyStringRepOfTargetData(data_layout);
- LLVMSetDataLayout(ctx.ac.module, data_layout_str);
- LLVMDisposeTargetData(data_layout);
- LLVMDisposeMessage(data_layout_str);
+ 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 :
if (options->dump_preoptir)
ac_dump_module(ctx.ac.module);
- ac_llvm_finalize_module(&ctx, options);
+ ac_llvm_finalize_module(&ctx, ac_llvm->passmgr, options);
if (shader_count == 1)
ac_nir_eliminate_const_vs_outputs(&ctx);
static unsigned ac_llvm_compile(LLVMModuleRef M,
struct ac_shader_binary *binary,
- LLVMTargetMachineRef tm)
+ struct ac_llvm_compiler *ac_llvm)
{
unsigned retval = 0;
- char *err;
LLVMContextRef llvm_ctx;
- LLVMMemoryBufferRef out_buffer;
- unsigned buffer_size;
- const char *buffer_data;
- LLVMBool mem_err;
/* Setup Diagnostic Handler*/
llvm_ctx = LLVMGetModuleContext(M);
&retval);
/* Compile IR*/
- mem_err = LLVMTargetMachineEmitToMemoryBuffer(tm, M, LLVMObjectFile,
- &err, &out_buffer);
-
- /* Process Errors/Warnings */
- if (mem_err) {
- fprintf(stderr, "%s: %s", __FUNCTION__, err);
- free(err);
+ if (!radv_compile_to_binary(ac_llvm, M, binary))
retval = 1;
- goto out;
- }
-
- /* Extract Shader Code*/
- buffer_size = LLVMGetBufferSize(out_buffer);
- buffer_data = LLVMGetBufferStart(out_buffer);
-
- ac_elf_read(buffer_data, buffer_size, binary);
-
- /* Clean up */
- LLVMDisposeMemoryBuffer(out_buffer);
-
-out:
return retval;
}
-static void ac_compile_llvm_module(LLVMTargetMachineRef tm,
+static void ac_compile_llvm_module(struct ac_llvm_compiler *ac_llvm,
LLVMModuleRef llvm_module,
struct ac_shader_binary *binary,
struct ac_shader_config *config,
LLVMDisposeMessage(llvm_ir);
}
- int v = ac_llvm_compile(llvm_module, binary, tm);
+ int v = ac_llvm_compile(llvm_module, binary, ac_llvm);
if (v) {
fprintf(stderr, "compile failed\n");
}
}
void
-radv_compile_nir_shader(LLVMTargetMachineRef tm,
+radv_compile_nir_shader(struct ac_llvm_compiler *ac_llvm,
struct ac_shader_binary *binary,
struct ac_shader_config *config,
struct radv_shader_variant_info *shader_info,
LLVMModuleRef llvm_module;
- llvm_module = ac_translate_nir_to_llvm(tm, nir, nir_count, shader_info,
+ llvm_module = ac_translate_nir_to_llvm(ac_llvm, nir, nir_count, shader_info,
options);
- ac_compile_llvm_module(tm, llvm_module, binary, config, shader_info,
+ ac_compile_llvm_module(ac_llvm, llvm_module, binary, config, shader_info,
nir[0]->info.stage, options);
for (int i = 0; i < nir_count; ++i)
}
void
-radv_compile_gs_copy_shader(LLVMTargetMachineRef tm,
+radv_compile_gs_copy_shader(struct ac_llvm_compiler *ac_llvm,
struct nir_shader *geom_shader,
struct ac_shader_binary *binary,
struct ac_shader_config *config,
const struct radv_nir_compiler_options *options)
{
struct radv_shader_context ctx = {0};
- ctx.context = LLVMContextCreate();
ctx.options = options;
ctx.shader_info = shader_info;
- ac_llvm_context_init(&ctx.ac, ctx.context, options->chip_class,
- options->family);
- ctx.ac.module = LLVMModuleCreateWithNameInContext("shader", ctx.context);
+ 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;
- LLVMSetTarget(ctx.ac.module, "amdgcn--");
enum ac_float_mode float_mode =
options->unsafe_math ? AC_FLOAT_MODE_UNSAFE_FP_MATH :
LLVMBuildRetVoid(ctx.ac.builder);
- ac_llvm_finalize_module(&ctx, options);
+ ac_llvm_finalize_module(&ctx, ac_llvm->passmgr, options);
- ac_compile_llvm_module(tm, ctx.ac.module, binary, config, shader_info,
+ ac_compile_llvm_module(ac_llvm, ctx.ac.module, binary, config, shader_info,
MESA_SHADER_VERTEX, options);
}