gallium: PIPE_COMPUTE_CAP_IR_TARGET - allow drivers to specify a processor v2

This target string now contains four values instead of three.  The old
processor field (which was really being interpreted as arch) has been split
into two fields: processor and arch.  This allows drivers to pass a
more a more detailed description of the hardware to compiler frontends.

v2:
  - Adapt to libclc changes

Reviewed-by: Francisco Jerez <currojerez@riseup.net>
This commit is contained in:
Tom Stellard
2013-03-07 10:51:25 -05:00
parent 1a868acbec
commit c5e5b3401c
10 changed files with 105 additions and 80 deletions

View File

@@ -236,10 +236,10 @@ PIPE_COMPUTE_CAP_*
Compute-specific capabilities. They can be queried using Compute-specific capabilities. They can be queried using
pipe_screen::get_compute_param. pipe_screen::get_compute_param.
* ``PIPE_COMPUTE_CAP_IR_TARGET``: A description of the target as a target * ``PIPE_COMPUTE_CAP_IR_TARGET``: A description of the target of the form
triple specification of the form ``processor-manufacturer-os`` that will ``processor-arch-manufacturer-os`` that will be passed on to the compiler.
be passed on to the compiler. This CAP is only relevant for drivers This CAP is only relevant for drivers that specify PIPE_SHADER_IR_LLVM for
that specify PIPE_SHADER_IR_LLVM for their preferred IR. their preferred IR.
Value type: null-terminated string. Value type: null-terminated string.
* ``PIPE_COMPUTE_CAP_GRID_DIMENSION``: Number of supported dimensions * ``PIPE_COMPUTE_CAP_GRID_DIMENSION``: Number of supported dimensions
for grid and block coordinates. Value type: ``uint64_t``. for grid and block coordinates. Value type: ``uint64_t``.

View File

@@ -550,69 +550,6 @@ LLVMModuleRef r600_tgsi_llvm(
return ctx->gallivm.module; return ctx->gallivm.module;
} }
const char * r600_llvm_gpu_string(enum radeon_family family)
{
const char * gpu_family;
switch (family) {
case CHIP_R600:
case CHIP_RV610:
case CHIP_RV630:
case CHIP_RV620:
case CHIP_RV635:
case CHIP_RV670:
case CHIP_RS780:
case CHIP_RS880:
gpu_family = "r600";
break;
case CHIP_RV710:
gpu_family = "rv710";
break;
case CHIP_RV730:
gpu_family = "rv730";
break;
case CHIP_RV740:
case CHIP_RV770:
gpu_family = "rv770";
break;
case CHIP_PALM:
case CHIP_CEDAR:
gpu_family = "cedar";
break;
case CHIP_SUMO:
case CHIP_SUMO2:
case CHIP_REDWOOD:
gpu_family = "redwood";
break;
case CHIP_JUNIPER:
gpu_family = "juniper";
break;
case CHIP_HEMLOCK:
case CHIP_CYPRESS:
gpu_family = "cypress";
break;
case CHIP_BARTS:
gpu_family = "barts";
break;
case CHIP_TURKS:
gpu_family = "turks";
break;
case CHIP_CAICOS:
gpu_family = "caicos";
break;
case CHIP_CAYMAN:
case CHIP_ARUBA:
gpu_family = "cayman";
break;
default:
gpu_family = "";
fprintf(stderr, "Chip not supported by r600 llvm "
"backend, please file a bug at " PACKAGE_BUGREPORT "\n");
break;
}
return gpu_family;
}
unsigned r600_llvm_compile( unsigned r600_llvm_compile(
LLVMModuleRef mod, LLVMModuleRef mod,
unsigned char ** inst_bytes, unsigned char ** inst_bytes,

View File

@@ -15,8 +15,6 @@ LLVMModuleRef r600_tgsi_llvm(
struct radeon_llvm_context * ctx, struct radeon_llvm_context * ctx,
const struct tgsi_token * tokens); const struct tgsi_token * tokens);
const char * r600_llvm_gpu_string(enum radeon_family family);
unsigned r600_llvm_compile( unsigned r600_llvm_compile(
LLVMModuleRef mod, LLVMModuleRef mod,
unsigned char ** inst_bytes, unsigned char ** inst_bytes,

View File

@@ -764,18 +764,84 @@ static int r600_get_video_param(struct pipe_screen *screen,
} }
} }
const char * r600_llvm_gpu_string(enum radeon_family family)
{
const char * gpu_family;
switch (family) {
case CHIP_R600:
case CHIP_RV610:
case CHIP_RV630:
case CHIP_RV620:
case CHIP_RV635:
case CHIP_RV670:
case CHIP_RS780:
case CHIP_RS880:
gpu_family = "r600";
break;
case CHIP_RV710:
gpu_family = "rv710";
break;
case CHIP_RV730:
gpu_family = "rv730";
break;
case CHIP_RV740:
case CHIP_RV770:
gpu_family = "rv770";
break;
case CHIP_PALM:
case CHIP_CEDAR:
gpu_family = "cedar";
break;
case CHIP_SUMO:
case CHIP_SUMO2:
case CHIP_REDWOOD:
gpu_family = "redwood";
break;
case CHIP_JUNIPER:
gpu_family = "juniper";
break;
case CHIP_HEMLOCK:
case CHIP_CYPRESS:
gpu_family = "cypress";
break;
case CHIP_BARTS:
gpu_family = "barts";
break;
case CHIP_TURKS:
gpu_family = "turks";
break;
case CHIP_CAICOS:
gpu_family = "caicos";
break;
case CHIP_CAYMAN:
case CHIP_ARUBA:
gpu_family = "cayman";
break;
default:
gpu_family = "";
fprintf(stderr, "Chip not supported by r600 llvm "
"backend, please file a bug at " PACKAGE_BUGREPORT "\n");
break;
}
return gpu_family;
}
static int r600_get_compute_param(struct pipe_screen *screen, static int r600_get_compute_param(struct pipe_screen *screen,
enum pipe_compute_cap param, enum pipe_compute_cap param,
void *ret) void *ret)
{ {
struct r600_screen *rscreen = (struct r600_screen *)screen;
//TODO: select these params by asic //TODO: select these params by asic
switch (param) { switch (param) {
case PIPE_COMPUTE_CAP_IR_TARGET: case PIPE_COMPUTE_CAP_IR_TARGET: {
const char *gpu = r600_llvm_gpu_string(rscreen->family);
if (ret) { if (ret) {
strcpy(ret, "r600--"); sprintf(ret, "%s-r600--", gpu);
} }
return 7 * sizeof(char); return (8 + strlen(gpu)) * sizeof(char);
}
case PIPE_COMPUTE_CAP_GRID_DIMENSION: case PIPE_COMPUTE_CAP_GRID_DIMENSION:
if (ret) { if (ret) {
uint64_t * grid_dimension = ret; uint64_t * grid_dimension = ret;

View File

@@ -746,6 +746,8 @@ boolean r600_rings_is_buffer_referenced(struct r600_context *ctx,
void *r600_buffer_mmap_sync_with_rings(struct r600_context *ctx, void *r600_buffer_mmap_sync_with_rings(struct r600_context *ctx,
struct r600_resource *resource, struct r600_resource *resource,
unsigned usage); unsigned usage);
const char * r600_llvm_gpu_string(enum radeon_family family);
/* r600_query.c */ /* r600_query.c */
void r600_init_query_functions(struct r600_context *rctx); void r600_init_query_functions(struct r600_context *rctx);

View File

@@ -1 +1 @@
@178505 @178928

View File

@@ -274,6 +274,17 @@ static const char* r600_get_vendor(struct pipe_screen* pscreen)
return "X.Org"; return "X.Org";
} }
const char *r600_get_llvm_processor_name(enum radeon_family family)
{
switch (family) {
case CHIP_TAHITI: return "tahiti";
case CHIP_PITCAIRN: return "pitcairn";
case CHIP_VERDE: return "verde";
case CHIP_OLAND: return "oland";
default: return "";
}
}
static const char *r600_get_family_name(enum radeon_family family) static const char *r600_get_family_name(enum radeon_family family)
{ {
switch(family) { switch(family) {

View File

@@ -218,6 +218,7 @@ void r600_upload_index_buffer(struct r600_context *rctx,
/* r600_pipe.c */ /* r600_pipe.c */
void radeonsi_flush(struct pipe_context *ctx, struct pipe_fence_handle **fence, void radeonsi_flush(struct pipe_context *ctx, struct pipe_fence_handle **fence,
unsigned flags); unsigned flags);
const char *r600_get_llvm_processor_name(enum radeon_family family);
/* r600_query.c */ /* r600_query.c */
void r600_init_query_functions(struct r600_context *rctx); void r600_init_query_functions(struct r600_context *rctx);

View File

@@ -1165,7 +1165,9 @@ int si_pipe_shader_create(
if (dump) { if (dump) {
LLVMDumpModule(mod); LLVMDumpModule(mod);
} }
radeon_llvm_compile(mod, &inst_bytes, &inst_byte_count, "SI", dump); radeon_llvm_compile(mod, &inst_bytes, &inst_byte_count,
r600_get_llvm_processor_name(rctx->screen->family)
, dump);
if (dump) { if (dump) {
fprintf(stderr, "SI CODE:\n"); fprintf(stderr, "SI CODE:\n");
for (i = 0; i < inst_byte_count; i+=4 ) { for (i = 0; i < inst_byte_count; i+=4 ) {

View File

@@ -110,7 +110,8 @@ namespace {
llvm::Module * llvm::Module *
compile(const std::string &source, const std::string &name, compile(const std::string &source, const std::string &name,
const std::string &triple, const std::string &opts) { const std::string &triple, const std::string &processor,
const std::string &opts) {
clang::CompilerInstance c; clang::CompilerInstance c;
clang::CompilerInvocation invocation; clang::CompilerInvocation invocation;
@@ -175,6 +176,7 @@ namespace {
c.getLangOpts().NoBuiltin = true; c.getLangOpts().NoBuiltin = true;
c.getTargetOpts().Triple = triple; c.getTargetOpts().Triple = triple;
c.getTargetOpts().CPU = processor;
#if HAVE_LLVM <= 0x0301 #if HAVE_LLVM <= 0x0301
c.getInvocation().setLangDefaults(clang::IK_OpenCL); c.getInvocation().setLangDefaults(clang::IK_OpenCL);
#else #else
@@ -215,12 +217,14 @@ namespace {
void void
link(llvm::Module *mod, const std::string &triple, link(llvm::Module *mod, const std::string &triple,
const std::string &processor,
const std::vector<llvm::Function *> &kernels) { const std::vector<llvm::Function *> &kernels) {
llvm::PassManager PM; llvm::PassManager PM;
llvm::PassManagerBuilder Builder; llvm::PassManagerBuilder Builder;
llvm::sys::Path libclc_path = llvm::sys::Path libclc_path =
llvm::sys::Path(LIBCLC_LIBEXECDIR + triple + ".bc"); llvm::sys::Path(LIBCLC_LIBEXECDIR + processor +
"-" + triple + ".bc");
// Link the kernel with libclc // Link the kernel with libclc
#if HAVE_LLVM < 0x0303 #if HAVE_LLVM < 0x0303
@@ -339,18 +343,22 @@ namespace {
module module
clover::compile_program_llvm(const compat::string &source, clover::compile_program_llvm(const compat::string &source,
enum pipe_shader_ir ir, enum pipe_shader_ir ir,
const compat::string &triple, const compat::string &target,
const compat::string &opts) { const compat::string &opts) {
std::vector<llvm::Function *> kernels; std::vector<llvm::Function *> kernels;
size_t processor_str_len = std::string(target.begin()).find_first_of("-");
std::string processor(target.begin(), 0, processor_str_len);
std::string triple(target.begin(), processor_str_len + 1,
target.size() - processor_str_len - 1);
// The input file name must have the .cl extension in order for the // The input file name must have the .cl extension in order for the
// CompilerInvocation class to recognize it as an OpenCL source file. // CompilerInvocation class to recognize it as an OpenCL source file.
llvm::Module *mod = compile(source, "input.cl", triple, opts); llvm::Module *mod = compile(source, "input.cl", triple, processor, opts);
find_kernels(mod, kernels); find_kernels(mod, kernels);
link(mod, triple, kernels); link(mod, triple, processor, kernels);
// Build the clover::module // Build the clover::module
switch (ir) { switch (ir) {