Mesa (amdgpu): Revert "radeon/llvm: drop support for LLVM < 3.6"

Marek Olšák mareko at kemper.freedesktop.org
Mon Jun 22 22:47:04 UTC 2015


Module: Mesa
Branch: amdgpu
Commit: 18949a1d60be6705d6c43f2de00159172270625b
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=18949a1d60be6705d6c43f2de00159172270625b

Author: Marek Olšák <marek.olsak at amd.com>
Date:   Tue Jun 16 15:35:00 2015 +0200

Revert "radeon/llvm: drop support for LLVM < 3.6"

This reverts commit df57c3d5504ba91a1de8cbaa04dc7399a02a58c6.

---

 src/gallium/drivers/r600/evergreen_compute.c       |   70 +++++++++++-
 .../drivers/r600/evergreen_compute_internal.h      |   19 ++++
 src/gallium/drivers/r600/r600_llvm.c               |  118 ++++++++++++++++++--
 src/gallium/drivers/r600/r600_pipe.c               |    4 +
 src/gallium/drivers/radeon/r600_pipe_common.c      |   20 +++-
 src/gallium/drivers/radeon/radeon_llvm_emit.c      |    6 +
 .../drivers/radeon/radeon_setup_tgsi_llvm.c        |    4 +
 src/gallium/drivers/radeonsi/si_compute.c          |   56 +++++++++-
 src/gallium/drivers/radeonsi/si_pipe.c             |   15 ++-
 src/gallium/drivers/radeonsi/si_shader.c           |   15 ++-
 10 files changed, 308 insertions(+), 19 deletions(-)

diff --git a/src/gallium/drivers/r600/evergreen_compute.c b/src/gallium/drivers/r600/evergreen_compute.c
index 81a841c..4c3c34c 100644
--- a/src/gallium/drivers/r600/evergreen_compute.c
+++ b/src/gallium/drivers/r600/evergreen_compute.c
@@ -208,6 +208,23 @@ void *evergreen_create_compute_state(
 	COMPUTE_DBG(ctx->screen, "*** evergreen_create_compute_state\n");
 	header = cso->prog;
 	code = cso->prog + sizeof(struct pipe_llvm_program_header);
+#if HAVE_LLVM < 0x0306
+        (void)use_kill;
+	(void)p;
+	shader->llvm_ctx = LLVMContextCreate();
+	shader->num_kernels = radeon_llvm_get_num_kernels(shader->llvm_ctx,
+				code, header->num_bytes);
+	shader->kernels = CALLOC(sizeof(struct r600_kernel),
+				shader->num_kernels);
+	{
+		unsigned i;
+		for (i = 0; i < shader->num_kernels; i++) {
+			struct r600_kernel *kernel = &shader->kernels[i];
+			kernel->llvm_module = radeon_llvm_get_kernel_module(
+				shader->llvm_ctx, i, code, header->num_bytes);
+		}
+	}
+#else
 	memset(&shader->binary, 0, sizeof(shader->binary));
 	radeon_elf_read(code, header->num_bytes, &shader->binary, true);
 	r600_create_shader(&shader->bc, &shader->binary, &use_kill);
@@ -218,6 +235,7 @@ void *evergreen_create_compute_state(
 	memcpy(p, shader->bc.bytecode, shader->bc.ndw * 4);
 	ctx->b.ws->buffer_unmap(shader->code_bo->cs_buf);
 #endif
+#endif
 
 	shader->ctx = (struct r600_context*)ctx;
 	shader->local_size = cso->req_local_mem;
@@ -335,7 +353,13 @@ static void evergreen_emit_direct_dispatch(
 	unsigned wave_divisor = (16 * num_pipes);
 	int group_size = 1;
 	int grid_size = 1;
-	unsigned lds_size = shader->local_size / 4 + shader->bc.nlds_dw;
+	unsigned lds_size = shader->local_size / 4 +
+#if HAVE_LLVM < 0x0306
+		shader->active_kernel->bc.nlds_dw;
+#else
+		shader->bc.nlds_dw;
+#endif
+
 
 	/* Calculate group_size/grid_size */
 	for (i = 0; i < 3; i++) {
@@ -513,10 +537,18 @@ void evergreen_emit_cs_shader(
 	struct r600_resource *code_bo;
 	unsigned ngpr, nstack;
 
+#if HAVE_LLVM < 0x0306
+	struct r600_kernel *kernel = &shader->kernels[state->kernel_index];
+	code_bo = kernel->code_bo;
+	va = kernel->code_bo->gpu_address;
+	ngpr = kernel->bc.ngpr;
+	nstack = kernel->bc.nstack;
+#else
 	code_bo = shader->code_bo;
 	va = shader->code_bo->gpu_address + state->pc;
 	ngpr = shader->bc.ngpr;
 	nstack = shader->bc.nstack;
+#endif
 
 	r600_write_compute_context_reg_seq(cs, R_0288D0_SQ_PGM_START_LS, 3);
 	radeon_emit(cs, va >> 8); /* R_0288D0_SQ_PGM_START_LS */
@@ -541,10 +573,46 @@ static void evergreen_launch_grid(
 	struct r600_pipe_compute *shader = ctx->cs_shader_state.shader;
 	boolean use_kill;
 
+#if HAVE_LLVM < 0x0306
+	struct r600_kernel *kernel = &shader->kernels[pc];
+	(void)use_kill;
+        if (!kernel->code_bo) {
+                void *p;
+                struct r600_bytecode *bc = &kernel->bc;
+                LLVMModuleRef mod = kernel->llvm_module;
+                boolean use_kill = false;
+                bool dump = (ctx->screen->b.debug_flags & DBG_CS) != 0;
+                unsigned use_sb = ctx->screen->b.debug_flags & DBG_SB_CS;
+                unsigned sb_disasm = use_sb ||
+                        (ctx->screen->b.debug_flags & DBG_SB_DISASM);
+
+                r600_bytecode_init(bc, ctx->b.chip_class, ctx->b.family,
+                           ctx->screen->has_compressed_msaa_texturing);
+                bc->type = TGSI_PROCESSOR_COMPUTE;
+                bc->isa = ctx->isa;
+                r600_llvm_compile(mod, ctx->b.family, bc, &use_kill, dump);
+
+                if (dump && !sb_disasm) {
+                        r600_bytecode_disasm(bc);
+                } else if ((dump && sb_disasm) || use_sb) {
+                        if (r600_sb_bytecode_process(ctx, bc, NULL, dump, use_sb))
+                                R600_ERR("r600_sb_bytecode_process failed!\n");
+                }
+
+                kernel->code_bo = r600_compute_buffer_alloc_vram(ctx->screen,
+                                                        kernel->bc.ndw * 4);
+                p = r600_buffer_map_sync_with_rings(&ctx->b, kernel->code_bo, PIPE_TRANSFER_WRITE);
+                memcpy(p, kernel->bc.bytecode, kernel->bc.ndw * 4);
+                ctx->b.ws->buffer_unmap(kernel->code_bo->cs_buf);
+        }
+	shader->active_kernel = kernel;
+	ctx->cs_shader_state.kernel_index = pc;
+#else
 	ctx->cs_shader_state.pc = pc;
 	/* Get the config information for this kernel. */
 	r600_shader_binary_read_config(&shader->binary, &shader->bc, pc, &use_kill);
 #endif
+#endif
 
 	COMPUTE_DBG(ctx->screen, "*** evergreen_launch_grid: pc = %u\n", pc);
 
diff --git a/src/gallium/drivers/r600/evergreen_compute_internal.h b/src/gallium/drivers/r600/evergreen_compute_internal.h
index c8998d0..95593dd 100644
--- a/src/gallium/drivers/r600/evergreen_compute_internal.h
+++ b/src/gallium/drivers/r600/evergreen_compute_internal.h
@@ -27,9 +27,28 @@
 
 #include "r600_asm.h"
 
+#if HAVE_LLVM < 0x0306
+
+struct r600_kernel {
+	unsigned count;
+#ifdef HAVE_OPENCL
+	LLVMModuleRef llvm_module;
+#endif
+	struct r600_resource *code_bo;
+	struct r600_bytecode bc;
+};
+
+#endif
+
 struct r600_pipe_compute {
 	struct r600_context *ctx;
 
+#if HAVE_LLVM < 0x0306
+	unsigned num_kernels;
+	struct r600_kernel *kernels;
+	struct r600_kernel *active_kernel;
+#endif
+
 	struct radeon_shader_binary binary;
 	struct r600_resource *code_bo;
 	struct r600_bytecode bc;
diff --git a/src/gallium/drivers/r600/r600_llvm.c b/src/gallium/drivers/r600/r600_llvm.c
index c606418..72e2dc4 100644
--- a/src/gallium/drivers/r600/r600_llvm.c
+++ b/src/gallium/drivers/r600/r600_llvm.c
@@ -77,11 +77,22 @@ static void llvm_load_system_value(
 	default: assert(!"unknown system value");
 	}
 
+#if HAVE_LLVM >= 0x0304
 	ctx->system_values[index] = LLVMBuildExtractElement(ctx->gallivm.builder,
 		LLVMGetParam(ctx->main_fn, 0), lp_build_const_int32(&(ctx->gallivm), chan),
 		"");
+#else
+	LLVMValueRef reg = lp_build_const_int32(
+			ctx->soa.bld_base.base.gallivm, chan);
+	ctx->system_values[index] = build_intrinsic(
+			ctx->soa.bld_base.base.gallivm->builder,
+			"llvm.R600.load.input",
+			ctx->soa.bld_base.base.elem_type, &reg, 1,
+			LLVMReadNoneAttribute);
+#endif
 }
 
+#if HAVE_LLVM >= 0x0304
 static LLVMValueRef
 llvm_load_input_vector(
 	struct radeon_llvm_context * ctx, unsigned location, unsigned ijregs,
@@ -120,7 +131,34 @@ llvm_load_input_vector(
 				VecType, Args, ArgCount, LLVMReadNoneAttribute);
 		}
 }
+#else
+static LLVMValueRef
+llvm_load_input_helper(
+	struct radeon_llvm_context * ctx,
+	unsigned idx, int interp, int ij_index)
+{
+	const struct lp_build_context * bb = &ctx->soa.bld_base.base;
+	LLVMValueRef arg[2];
+	int arg_count;
+	const char * intrinsic;
+
+	arg[0] = lp_build_const_int32(bb->gallivm, idx);
+
+	if (interp) {
+		intrinsic = "llvm.R600.interp.input";
+		arg[1] = lp_build_const_int32(bb->gallivm, ij_index);
+		arg_count = 2;
+	} else {
+		intrinsic = "llvm.R600.load.input";
+		arg_count = 1;
+	}
+
+	return build_intrinsic(bb->gallivm->builder, intrinsic,
+		bb->elem_type, &arg[0], arg_count, LLVMReadNoneAttribute);
+}
+#endif
 
+#if HAVE_LLVM >= 0x0304
 static LLVMValueRef
 llvm_face_select_helper(
 	struct radeon_llvm_context * ctx,
@@ -133,6 +171,21 @@ llvm_face_select_helper(
 	return LLVMBuildSelect(bb->gallivm->builder, is_front,
 		front_color, back_color, "");
 }
+#else
+static LLVMValueRef
+llvm_face_select_helper(
+	struct radeon_llvm_context * ctx,
+	unsigned face_loc, LLVMValueRef front_color, LLVMValueRef back_color)
+{
+	const struct lp_build_context * bb = &ctx->soa.bld_base.base;
+	LLVMValueRef face = llvm_load_input_helper(ctx, face_loc, 0, 0);
+	LLVMValueRef is_front = LLVMBuildFCmp(
+		bb->gallivm->builder, LLVMRealUGT, face,
+		lp_build_const_float(bb->gallivm, 0.0f),	"");
+	return LLVMBuildSelect(bb->gallivm->builder, is_front,
+		front_color, back_color, "");
+}
+#endif
 
 static void llvm_load_input(
 	struct radeon_llvm_context * ctx,
@@ -141,11 +194,18 @@ static void llvm_load_input(
 {
 	const struct r600_shader_io * input = &ctx->r600_inputs[input_index];
 	unsigned chan;
+#if HAVE_LLVM < 0x0304
+	unsigned interp = 0;
+	int ij_index;
+#endif
 	int two_side = (ctx->two_side && input->name == TGSI_SEMANTIC_COLOR);
 	LLVMValueRef v;
+#if HAVE_LLVM >= 0x0304
 	boolean require_interp_intrinsic = ctx->chip_class >= EVERGREEN &&
 		ctx->type == TGSI_PROCESSOR_FRAGMENT;
+#endif
 
+#if HAVE_LLVM >= 0x0304
 	if (require_interp_intrinsic && input->spi_sid) {
 		v = llvm_load_input_vector(ctx, input->lds_pos, input->ij_index,
 			(input->interpolate > 0));
@@ -172,16 +232,58 @@ static void llvm_load_input(
 		unsigned soa_index = radeon_llvm_reg_index_soa(input_index, chan);
 
 		ctx->inputs[soa_index] = LLVMBuildExtractElement(ctx->gallivm.builder, v,
-								 lp_build_const_int32(&(ctx->gallivm), chan), "");
+			lp_build_const_int32(&(ctx->gallivm), chan), "");
 
 		if (input->name == TGSI_SEMANTIC_POSITION &&
-		    ctx->type == TGSI_PROCESSOR_FRAGMENT && chan == 3) {
+				ctx->type == TGSI_PROCESSOR_FRAGMENT && chan == 3) {
+		/* RCP for fragcoord.w */
+		ctx->inputs[soa_index] = LLVMBuildFDiv(ctx->gallivm.builder,
+				lp_build_const_float(&(ctx->gallivm), 1.0f),
+				ctx->inputs[soa_index], "");
+	}
+}
+#else
+	if (ctx->chip_class >= EVERGREEN && ctx->type == TGSI_PROCESSOR_FRAGMENT &&
+			input->spi_sid) {
+		interp = 1;
+		ij_index = (input->interpolate > 0) ? input->ij_index : -1;
+	}
+
+	for (chan = 0; chan < 4; chan++) {
+		unsigned soa_index = radeon_llvm_reg_index_soa(input_index, chan);
+		int loc;
+
+		if (interp) {
+			loc = 4 * input->lds_pos + chan;
+		} else {
+			if (input->name == TGSI_SEMANTIC_FACE)
+				loc = 4 * ctx->face_gpr;
+			else
+				loc = 4 * input->gpr + chan;
+		}
+
+		v = llvm_load_input_helper(ctx, loc, interp, ij_index);
+
+		if (two_side) {
+			struct r600_shader_io * back_input =
+					&ctx->r600_inputs[input->back_color_input];
+			int back_loc = interp ? back_input->lds_pos : back_input->gpr;
+			LLVMValueRef v2;
+
+			back_loc = 4 * back_loc + chan;
+			v2 = llvm_load_input_helper(ctx, back_loc, interp, ij_index);
+			v = llvm_face_select_helper(ctx, 4 * ctx->face_gpr, v, v2);
+		} else if (input->name == TGSI_SEMANTIC_POSITION &&
+				ctx->type == TGSI_PROCESSOR_FRAGMENT && chan == 3) {
 			/* RCP for fragcoord.w */
-			ctx->inputs[soa_index] = LLVMBuildFDiv(ctx->gallivm.builder,
-							       lp_build_const_float(&(ctx->gallivm), 1.0f),
-							       ctx->inputs[soa_index], "");
+			v = LLVMBuildFDiv(ctx->gallivm.builder,
+					lp_build_const_float(&(ctx->gallivm), 1.0f),
+					v, "");
 		}
+
+		ctx->inputs[soa_index] = v;
 	}
+#endif
 }
 
 static void llvm_emit_prologue(struct lp_build_tgsi_context * bld_base)
@@ -661,17 +763,19 @@ LLVMModuleRef r600_tgsi_llvm(
 	struct tgsi_shader_info shader_info;
 	struct lp_build_tgsi_context * bld_base = &ctx->soa.bld_base;
 	radeon_llvm_context_init(ctx);
+#if HAVE_LLVM >= 0x0304
 	LLVMTypeRef Arguments[32];
 	unsigned ArgumentsCount = 0;
-
 	for (unsigned i = 0; i < ctx->inputs_count; i++)
 		Arguments[ArgumentsCount++] = LLVMVectorType(bld_base->base.elem_type, 4);
-
 	radeon_llvm_create_func(ctx, Arguments, ArgumentsCount);
 	for (unsigned i = 0; i < ctx->inputs_count; i++) {
 		LLVMValueRef P = LLVMGetParam(ctx->main_fn, i);
 		LLVMAddAttribute(P, LLVMInRegAttribute);
 	}
+#else
+	radeon_llvm_create_func(ctx, NULL, 0);
+#endif
 	tgsi_scan_shader(tokens, &shader_info);
 
 	bld_base->info = &shader_info;
diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
index bc13086..4216b4b 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -484,7 +484,11 @@ static int r600_get_shader_param(struct pipe_screen* pscreen, unsigned shader, e
 		return 16;
         case PIPE_SHADER_CAP_PREFERRED_IR:
 		if (shader == PIPE_SHADER_COMPUTE) {
+#if HAVE_LLVM < 0x0306
+			return PIPE_SHADER_IR_LLVM;
+#else
 			return PIPE_SHADER_IR_NATIVE;
+#endif
 		} else {
 			return PIPE_SHADER_IR_TGSI;
 		}
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c
index e6276d4..755d070 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.c
+++ b/src/gallium/drivers/radeon/r600_pipe_common.c
@@ -517,7 +517,11 @@ const char *r600_get_llvm_processor_name(enum radeon_family family)
 	case CHIP_KAVERI: return "kaveri";
 	case CHIP_HAWAII: return "hawaii";
 	case CHIP_MULLINS:
+#if HAVE_LLVM >= 0x0305
 		return "mullins";
+#else
+		return "kabini";
+#endif
 	case CHIP_TONGA: return "tonga";
 	case CHIP_ICELAND: return "iceland";
 	case CHIP_CARRIZO: return "carrizo";
@@ -536,12 +540,24 @@ static int r600_get_compute_param(struct pipe_screen *screen,
 	case PIPE_COMPUTE_CAP_IR_TARGET: {
 		const char *gpu;
 		const char *triple;
-		if (rscreen->family <= CHIP_ARUBA) {
+		if (rscreen->family <= CHIP_ARUBA || HAVE_LLVM < 0x0306) {
 			triple = "r600--";
 		} else {
 			triple = "amdgcn--";
 		}
-		gpu = r600_get_llvm_processor_name(rscreen->family);
+		switch(rscreen->family) {
+		/* Clang < 3.6 is missing Hainan in its list of
+		 * GPUs, so we need to use the name of a similar GPU.
+		 */
+#if HAVE_LLVM < 0x0306
+		case CHIP_HAINAN:
+			gpu = "oland";
+			break;
+#endif
+		default:
+			gpu = r600_get_llvm_processor_name(rscreen->family);
+			break;
+		}
 		if (ret) {
 			sprintf(ret, "%s-%s", gpu, triple);
 		}
diff --git a/src/gallium/drivers/radeon/radeon_llvm_emit.c b/src/gallium/drivers/radeon/radeon_llvm_emit.c
index 65afeec..624077c 100644
--- a/src/gallium/drivers/radeon/radeon_llvm_emit.c
+++ b/src/gallium/drivers/radeon/radeon_llvm_emit.c
@@ -112,6 +112,8 @@ LLVMTargetRef radeon_llvm_get_r600_target(const char *triple)
 	return target;
 }
 
+#if HAVE_LLVM >= 0x0305
+
 static void radeonDiagnosticHandler(LLVMDiagnosticInfoRef di, void *context)
 {
 	if (LLVMGetDiagInfoSeverity(di) == LLVMDSError) {
@@ -124,6 +126,8 @@ static void radeonDiagnosticHandler(LLVMDiagnosticInfoRef di, void *context)
 	}
 }
 
+#endif
+
 /**
  * Compile an LLVM module to machine code.
  *
@@ -167,7 +171,9 @@ unsigned radeon_llvm_compile(LLVMModuleRef M, struct radeon_shader_binary *binar
 	/* Setup Diagnostic Handler*/
 	llvm_ctx = LLVMGetModuleContext(M);
 
+#if HAVE_LLVM >= 0x0305
 	LLVMContextSetDiagnosticHandler(llvm_ctx, radeonDiagnosticHandler, &rval);
+#endif
 	rval = 0;
 
 	/* Compile IR*/
diff --git a/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c b/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
index c7ef929..c8c980d 100644
--- a/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
+++ b/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
@@ -1573,7 +1573,11 @@ void radeon_llvm_context_init(struct radeon_llvm_context * ctx)
 	bld_base->op_actions[TGSI_OPCODE_UCMP].emit = emit_ucmp;
 
 	bld_base->rsq_action.emit = build_tgsi_intrinsic_nomem;
+#if HAVE_LLVM >= 0x0305
 	bld_base->rsq_action.intr_name = "llvm.AMDGPU.rsq.clamped.f32";
+#else
+	bld_base->rsq_action.intr_name = "llvm.AMDGPU.rsq";
+#endif
 }
 
 void radeon_llvm_create_func(struct radeon_llvm_context * ctx,
diff --git a/src/gallium/drivers/radeonsi/si_compute.c b/src/gallium/drivers/radeonsi/si_compute.c
index ce37b9d..89bef2e 100644
--- a/src/gallium/drivers/radeonsi/si_compute.c
+++ b/src/gallium/drivers/radeonsi/si_compute.c
@@ -33,10 +33,14 @@
 #include "sid.h"
 
 #define MAX_GLOBAL_BUFFERS 20
+#if HAVE_LLVM < 0x0305
+#define NUM_USER_SGPRS 2
+#else
 /* XXX: Even though we don't pass the scratch buffer via user sgprs any more
  * LLVM still expects that we specify 4 USER_SGPRS so it can remain compatible
  * with older mesa. */
 #define NUM_USER_SGPRS 4
+#endif
 
 struct si_compute {
 	struct si_context *ctx;
@@ -49,6 +53,12 @@ struct si_compute {
 
 	struct r600_resource *input_buffer;
 	struct pipe_resource *global_buffers[MAX_GLOBAL_BUFFERS];
+
+#if HAVE_LLVM < 0x0306
+	unsigned num_kernels;
+	struct si_shader *kernels;
+	LLVMContextRef llvm_ctx;
+#endif
 };
 
 static void init_scratch_buffer(struct si_context *sctx, struct si_compute *program)
@@ -109,6 +119,24 @@ static void *si_create_compute_state(
 	program->private_size = cso->req_private_mem;
 	program->input_size = cso->req_input_mem;
 
+#if HAVE_LLVM < 0x0306
+	{
+		unsigned i;
+		program->llvm_ctx = LLVMContextCreate();
+	        program->num_kernels = radeon_llvm_get_num_kernels(program->llvm_ctx,
+					code, header->num_bytes);
+	        program->kernels = CALLOC(sizeof(struct si_shader),
+                                                        program->num_kernels);
+	        for (i = 0; i < program->num_kernels; i++) {
+		        LLVMModuleRef mod = radeon_llvm_get_kernel_module(program->llvm_ctx, i,
+                                                        code, header->num_bytes);
+			si_compile_llvm(sctx->screen, &program->kernels[i], sctx->tm,
+					mod);
+			LLVMDisposeModule(mod);
+		}
+	}
+#else
+
 	radeon_elf_read(code, header->num_bytes, &program->shader.binary, true);
 
 	/* init_scratch_buffer patches the shader code with the scratch address,
@@ -118,6 +146,7 @@ static void *si_create_compute_state(
 	init_scratch_buffer(sctx, program);
 	si_shader_binary_read(sctx->screen, &program->shader, &program->shader.binary);
 
+#endif
 	program->input_buffer =	si_resource_create_custom(sctx->b.b.screen,
 		PIPE_USAGE_IMMUTABLE, program->input_size);
 
@@ -218,6 +247,11 @@ static void si_launch_grid(
 	unsigned lds_blocks;
 	unsigned num_waves_for_scratch;
 
+#if HAVE_LLVM < 0x0306
+	shader = &program->kernels[pc];
+#endif
+
+
 	radeon_emit(cs, PKT3(PKT3_CONTEXT_CONTROL, 1, 0) | PKT3_SHADER_TYPE_S(1));
 	radeon_emit(cs, 0x80000000);
 	radeon_emit(cs, 0x80000000);
@@ -232,8 +266,10 @@ static void si_launch_grid(
 
 	pm4->compute_pkt = true;
 
+#if HAVE_LLVM >= 0x0306
 	/* Read the config information */
 	si_shader_binary_read_config(sctx->screen, shader, pc);
+#endif
 
 	/* Upload the kernel arguments */
 
@@ -322,8 +358,11 @@ static void si_launch_grid(
 						0x190 /* Default value */);
 	}
 
-	shader_va = shader->bo->gpu_address + pc;
+	shader_va = shader->bo->gpu_address;
 
+#if HAVE_LLVM >= 0x0306
+	shader_va += pc;
+#endif
 	si_pm4_add_bo(pm4, shader->bo, RADEON_USAGE_READ, RADEON_PRIO_SHADER_DATA);
 	si_pm4_set_reg(pm4, R_00B830_COMPUTE_PGM_LO, (shader_va >> 8) & 0xffffffff);
 	si_pm4_set_reg(pm4, R_00B834_COMPUTE_PGM_HI, shader_va >> 40);
@@ -427,10 +466,25 @@ static void si_delete_compute_state(struct pipe_context *ctx, void* state){
 		return;
 	}
 
+#if HAVE_LLVM < 0x0306
+	if (program->kernels) {
+		for (int i = 0; i < program->num_kernels; i++){
+			if (program->kernels[i].bo){
+				si_shader_destroy(ctx, &program->kernels[i]);
+			}
+		}
+		FREE(program->kernels);
+	}
+
+	if (program->llvm_ctx){
+		LLVMContextDispose(program->llvm_ctx);
+	}
+#else
 	FREE(program->shader.binary.config);
 	FREE(program->shader.binary.rodata);
 	FREE(program->shader.binary.global_symbol_offsets);
 	si_shader_destroy(ctx, &program->shader);
+#endif
 
 	pipe_resource_reference(
 		(struct pipe_resource **)&program->input_buffer, NULL);
diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c
index f3dd1b7..ed732dc 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.c
+++ b/src/gallium/drivers/radeonsi/si_pipe.c
@@ -71,7 +71,10 @@ static void si_destroy_context(struct pipe_context *context)
 
 	r600_common_context_cleanup(&sctx->b);
 
+#if HAVE_LLVM >= 0x0306
 	LLVMDisposeTargetMachine(sctx->tm);
+#endif
+
 	FREE(sctx);
 }
 
@@ -89,7 +92,9 @@ static struct pipe_context *si_create_context(struct pipe_screen *screen, void *
 	struct si_screen* sscreen = (struct si_screen *)screen;
 	struct radeon_winsys *ws = sscreen->b.ws;
 	LLVMTargetRef r600_target;
+#if HAVE_LLVM >= 0x0306
 	const char *triple = "amdgcn--";
+#endif
 	int shader, i;
 
 	if (sctx == NULL)
@@ -188,6 +193,7 @@ static struct pipe_context *si_create_context(struct pipe_screen *screen, void *
 	 */
 	sctx->scratch_waves = 32 * sscreen->b.info.max_compute_units;
 
+#if HAVE_LLVM >= 0x0306
 	/* Initialize LLVM TargetMachine */
 	r600_target = radeon_llvm_get_r600_target(triple);
 	sctx->tm = LLVMCreateTargetMachine(r600_target, triple,
@@ -198,6 +204,7 @@ static struct pipe_context *si_create_context(struct pipe_screen *screen, void *
 					   LLVMCodeGenLevelDefault,
 					   LLVMRelocDefault,
 					   LLVMCodeModelDefault);
+#endif
 
 	return &sctx->b.b;
 fail:
@@ -296,9 +303,9 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
 
 	case PIPE_CAP_TEXTURE_QUERY_LOD:
 	case PIPE_CAP_TEXTURE_GATHER_SM5:
-		return 1;
+		return HAVE_LLVM >= 0x0305;
 	case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
-		return 4;
+		return HAVE_LLVM >= 0x0305 ? 4 : 0;
 
 	/* Unsupported features. */
 	case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
@@ -396,7 +403,11 @@ static int si_get_shader_param(struct pipe_screen* pscreen, unsigned shader, enu
 	case PIPE_SHADER_COMPUTE:
 		switch (param) {
 		case PIPE_SHADER_CAP_PREFERRED_IR:
+#if HAVE_LLVM < 0x0306
+			return PIPE_SHADER_IR_LLVM;
+#else
 			return PIPE_SHADER_IR_NATIVE;
+#endif
 		case PIPE_SHADER_CAP_DOUBLES:
 			return HAVE_LLVM >= 0x0307;
 
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index 3f1f981..e8f4748 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -1571,7 +1571,7 @@ static void tex_fetch_args(
 	unsigned chan;
 	unsigned sampler_src = emit_data->inst->Instruction.NumSrcRegs - 1;
 	unsigned sampler_index = emit_data->inst->Src[sampler_src].Register.Index;
-	bool has_offset = inst->Texture.NumOffsets > 0;
+	bool has_offset = HAVE_LLVM >= 0x0305 ? inst->Texture.NumOffsets > 0 : false;
 
 	if (target == TGSI_TEXTURE_BUFFER) {
 		LLVMTypeRef i128 = LLVMIntTypeInContext(gallivm->context, 128);
@@ -1936,7 +1936,8 @@ static void build_tex_intrinsic(const struct lp_build_tgsi_action * action,
 	unsigned opcode = emit_data->inst->Instruction.Opcode;
 	unsigned target = emit_data->inst->Texture.Texture;
 	char intr_name[127];
-	bool has_offset = emit_data->inst->Texture.NumOffsets > 0;
+	bool has_offset = HAVE_LLVM >= 0x0305 ?
+				emit_data->inst->Texture.NumOffsets > 0 : false;
 
 	if (target == TGSI_TEXTURE_BUFFER) {
 		emit_data->output[emit_data->chan] = build_intrinsic(
@@ -2909,10 +2910,12 @@ int si_shader_create(struct si_screen *sscreen, LLVMTargetMachineRef tm,
 	bld_base->op_actions[TGSI_OPCODE_EMIT].emit = si_llvm_emit_vertex;
 	bld_base->op_actions[TGSI_OPCODE_ENDPRIM].emit = si_llvm_emit_primitive;
 
-	bld_base->op_actions[TGSI_OPCODE_MAX].emit = build_tgsi_intrinsic_nomem;
-	bld_base->op_actions[TGSI_OPCODE_MAX].intr_name = "llvm.maxnum.f32";
-	bld_base->op_actions[TGSI_OPCODE_MIN].emit = build_tgsi_intrinsic_nomem;
-	bld_base->op_actions[TGSI_OPCODE_MIN].intr_name = "llvm.minnum.f32";
+	if (HAVE_LLVM >= 0x0306) {
+		bld_base->op_actions[TGSI_OPCODE_MAX].emit = build_tgsi_intrinsic_nomem;
+		bld_base->op_actions[TGSI_OPCODE_MAX].intr_name = "llvm.maxnum.f32";
+		bld_base->op_actions[TGSI_OPCODE_MIN].emit = build_tgsi_intrinsic_nomem;
+		bld_base->op_actions[TGSI_OPCODE_MIN].intr_name = "llvm.minnum.f32";
+	}
 
 	si_shader_ctx.radeon_bld.load_system_value = declare_system_value;
 	si_shader_ctx.shader = shader;




More information about the mesa-commit mailing list