radeonsi: Added Diag Handler to receive LLVM Error messages
authorDarren Powell <darren.powell@amd.com>
Mon, 31 Mar 2014 22:00:28 +0000 (18:00 -0400)
committerTom Stellard <thomas.stellard@amd.com>
Thu, 17 Apr 2014 23:37:58 +0000 (19:37 -0400)
Reviewed-by: Tom Stellard <thomas.stellard@amd.com>
src/gallium/drivers/radeon/radeon_llvm_emit.c
src/gallium/drivers/radeonsi/si_shader.c
src/gallium/drivers/radeonsi/si_state.c

index 7bcdc27..891781f 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <llvm-c/Target.h>
 #include <llvm-c/TargetMachine.h>
+#include <llvm-c/Core.h>
 
 #include <stdlib.h>
 #include <stdio.h>
@@ -79,6 +80,22 @@ static LLVMTargetRef get_r600_target() {
        return target;
 }
 
+#if HAVE_LLVM >= 0x0305
+
+static void radeonDiagnosticHandler(LLVMDiagnosticInfoRef di, void *context) {
+       unsigned int *diagnosticflag;
+       char *diaginfo_message;
+
+       diaginfo_message = LLVMGetDiagInfoDescription(di);
+       fprintf(stderr,"LLVM triggered Diagnostic Handler: %s\n", diaginfo_message);
+       LLVMDisposeMessage(diaginfo_message);
+
+       diagnosticflag = (unsigned int *)context;
+       *diagnosticflag = ((LLVMDSError == LLVMGetDiagInfoSeverity(di)) ? 1 : 0);
+}
+
+#endif
+
 /**
  * Compile an LLVM module to machine code.
  *
@@ -92,12 +109,15 @@ unsigned radeon_llvm_compile(LLVMModuleRef M, struct radeon_shader_binary *binar
        char cpu[CPU_STRING_LEN];
        char fs[FS_STRING_LEN];
        char *err;
+       LLVMContextRef llvm_ctx;
+       unsigned rval = 0;
        LLVMMemoryBufferRef out_buffer;
        unsigned buffer_size;
        const char *buffer_data;
        char triple[TRIPLE_STRING_LEN];
-       LLVMBool r;
+       LLVMBool mem_err;
 
+       /* initialise */
        init_r600_target();
 
        target = get_r600_target();
@@ -112,24 +132,42 @@ unsigned radeon_llvm_compile(LLVMModuleRef M, struct radeon_shader_binary *binar
                strncpy(fs, "+DumpCode", FS_STRING_LEN);
        }
        strncpy(triple, "r600--", TRIPLE_STRING_LEN);
+
+       /* Setup Diagnostic Handler*/
+       llvm_ctx = LLVMGetModuleContext(M);
+
+#if HAVE_LLVM >= 0x0305
+       LLVMContextSetDiagnosticHandler(llvm_ctx, radeonDiagnosticHandler, &rval);
+#endif
+       rval = 0;
+
+       /* Compile IR*/
        tm = LLVMCreateTargetMachine(target, triple, cpu, fs,
                                  LLVMCodeGenLevelDefault, LLVMRelocDefault,
                                                  LLVMCodeModelDefault);
-
-       r = LLVMTargetMachineEmitToMemoryBuffer(tm, M, LLVMObjectFile, &err,
+       mem_err = LLVMTargetMachineEmitToMemoryBuffer(tm, M, LLVMObjectFile, &err,
                                                                 &out_buffer);
-       if (r) {
-               fprintf(stderr, "%s", err);
+
+       /* Process Errors/Warnings */
+       if (mem_err) {
+               fprintf(stderr, "%s: %s", __FUNCTION__, err);
                FREE(err);
+               LLVMDisposeTargetMachine(tm);
                return 1;
        }
 
+       if (0 != rval) {
+               fprintf(stderr, "%s: Processing Diag Flag\n", __FUNCTION__);
+       }
+
+       /* Extract Shader Code*/
        buffer_size = LLVMGetBufferSize(out_buffer);
        buffer_data = LLVMGetBufferStart(out_buffer);
 
        radeon_elf_read(buffer_data, buffer_size, binary, dump);
 
+       /* Clean up */
        LLVMDisposeMemoryBuffer(out_buffer);
        LLVMDisposeTargetMachine(tm);
-       return 0;
+       return rval;
 }
index e4390ee..0d070d3 100644 (file)
@@ -2293,14 +2293,19 @@ static void preload_streamout_buffers(struct si_shader_context *si_shader_ctx)
 int si_compile_llvm(struct si_context *sctx, struct si_pipe_shader *shader,
                                                        LLVMModuleRef mod)
 {
+       unsigned r; /* llvm_compile result */
        unsigned i;
        uint32_t *ptr;
        struct radeon_shader_binary binary;
        bool dump = r600_can_dump_shader(&sctx->screen->b,
                        shader->selector ? shader->selector->tokens : NULL);
+       const char * gpu_family = r600_get_llvm_processor_name(sctx->screen->b.family);
+
+       /* Use LLVM to compile shader */
        memset(&binary, 0, sizeof(binary));
-       radeon_llvm_compile(mod, &binary,
-               r600_get_llvm_processor_name(sctx->screen->b.family), dump);
+       r = radeon_llvm_compile(mod, &binary, gpu_family, dump);
+
+       /* Output binary dump if rscreen->debug_flags are set */
        if (dump && ! binary.disassembled) {
                fprintf(stderr, "SI CODE:\n");
                for (i = 0; i < binary.code_size; i+=4 ) {
@@ -2313,6 +2318,7 @@ int si_compile_llvm(struct si_context *sctx, struct si_pipe_shader *shader,
        /* XXX: We may be able to emit some of these values directly rather than
         * extracting fields to be emitted later.
         */
+       /* Parse config data in compiled binary */
        for (i = 0; i < binary.config_size; i+= 8) {
                unsigned reg = util_le32_to_cpu(*(uint32_t*)(binary.config + i));
                unsigned value = util_le32_to_cpu(*(uint32_t*)(binary.config + i + 4));
@@ -2361,7 +2367,7 @@ int si_compile_llvm(struct si_context *sctx, struct si_pipe_shader *shader,
        free(binary.code);
        free(binary.config);
 
-       return 0;
+       return r;
 }
 
 /* Generate code for the hardware VS shader stage to go with a geometry shader */
index d81354e..ab9c4cc 100644 (file)
@@ -2208,9 +2208,11 @@ static void si_bind_ps_shader(struct pipe_context *ctx, void *state)
        struct si_context *sctx = (struct si_context *)ctx;
        struct si_pipe_shader_selector *sel = state;
 
+       /* skip if supplied shader is one already in use */
        if (sctx->ps_shader == sel)
                return;
 
+       /* use dummy shader if supplied shader is corrupt */
        if (!sel || !sel->current)
                sel = sctx->dummy_pixel_shader;