Updated code generation so that for vertex shader output position is written at last...
[mesa.git] / src / libre-soc / vulkan / libresoc_llvm.c
index 06a62424300eef00c4c9c69a06151e5be7e1daba..14f4de0dbd54072c44b4115992cb1a52508cd97b 100644 (file)
@@ -1904,6 +1904,32 @@ static void visit_store_var(struct libresoc_nir_tran_ctx *ctx, nir_intrinsic_ins
 
    switch (deref->mode) {
    case nir_var_shader_out:
+       if (ctx->stage == MESA_SHADER_VERTEX && var->data.location == VARYING_SLOT_POS) {
+
+           LLVMValueRef vertexCache = LLVMGetParam(ctx->main_function, 2); 
+           LLVMValueRef idx[3];
+
+           idx[0] = LLVMConstInt(ctx->lc.i32, 0, false);
+           idx[1] = LLVMConstInt(ctx->lc.i32, 0, false);
+           LLVMValueRef outPos = LLVMConstInBoundsGEP(vertexCache,
+                   idx,
+                   2);
+           LLVMBuildStore(ctx->lc.builder, src, outPos);
+           break;
+       }
+       if (ctx->stage == MESA_SHADER_FRAGMENT && var->data.location == FRAG_RESULT_DATA0) {
+
+           LLVMValueRef outColor = LLVMGetParam(ctx->main_function, 4); 
+           // LLVMValueRef idx[3];
+
+           // idx[0] = LLVMConstInt(ctx->lc.i32, 0, false);
+           // idx[1] = LLVMConstInt(ctx->lc.i32, 0, false);
+           // LLVMValueRef outPos = LLVMConstInBoundsGEP(vertexCache,
+           //         idx,
+           //         2);
+           LLVMBuildStore(ctx->lc.builder, src, outColor);
+           break;
+       }
       /* TODO: remove this after RADV switches to lowered IO */
       // if (ctx->stage == MESA_SHADER_TESS_CTRL) {
       //    LLVMValueRef vertex_index = NULL;
@@ -2070,8 +2096,9 @@ static void visit_intrinsic(struct libresoc_nir_tran_ctx *ctx, nir_intrinsic_ins
       // result = ctx->abi->load_local_group_size(ctx->abi);
       break;
    case nir_intrinsic_load_vertex_id:
-      result = LLVMBuildAdd(ctx->lc.builder, LLVMGetParam(ctx->main_function, ctx->args.vertex_id.arg_index),
-                             LLVMGetParam(ctx->main_function, ctx->args.base_vertex.arg_index), "");
+      result = LLVMGetParam(ctx->main_function, 1); 
+      // result = LLVMBuildAdd(ctx->lc.builder, LLVMGetParam(ctx->main_function, ctx->args.vertex_id.arg_index),
+      //                        LLVMGetParam(ctx->main_function, ctx->args.base_vertex.arg_index), "");
       break;
    case nir_intrinsic_load_vertex_id_zero_base: {
       // result = ctx->abi->vertex_id;
@@ -2686,10 +2713,39 @@ LLVMModuleRef libresoc_nir_translate(struct libresoc_llvm *llvm_ref, struct nir_
       arg_types[i] = arg_llvm_type(ctx.args.args[i].type, ctx.args.args[i].size, &ctx.lc);
    }
 
-   //TODO: this is zero argument function and returns void
-   LLVMTypeRef main_function_type = LLVMFunctionType(ret_type, arg_types, ctx.args.arg_count, 0);
-
-   LLVMValueRef main_function = LLVMAddFunction(mod, "main_function", main_function_type);
+    LLVMTypeRef main_function_type;
+    if(nir->info.stage == MESA_SHADER_VERTEX) {
+        LLVMTypeRef arg_types[32];
+        LLVMTypeRef floatType = LLVMFloatTypeInContext(llvm_ref->lc.context);
+        LLVMTypeRef float4 = LLVMVectorType(floatType, 4);
+        LLVMTypeRef f4arrayType = LLVMArrayType(float4, 10);
+        arg_types[0] = float4;
+        arg_types[1] = f4arrayType;
+        LLVMTypeRef vertexCacheType = LLVMStructTypeInContext(llvm_ref->lc.context, arg_types, 2, false);
+        LLVMTypeRef gpuStatePtrType = LLVMPointerType(LLVMStructCreateNamed(llvm_ref->lc.context, "GPUState"), 0);
+        arg_types[0] = gpuStatePtrType;
+        arg_types[1] = LLVMIntTypeInContext(llvm_ref->lc.context, 32);
+        arg_types[2] = LLVMPointerType(vertexCacheType, 0);
+        main_function_type = LLVMFunctionType(ret_type, arg_types, 3, 0);
+    } else {
+
+        LLVMTypeRef floatType = LLVMFloatTypeInContext(llvm_ref->lc.context);
+        LLVMTypeRef float4 = LLVMVectorType(floatType, 4);
+        LLVMTypeRef f4arrayType = LLVMArrayType(float4, 10);
+        arg_types[0] = float4;
+        arg_types[1] = f4arrayType;
+        LLVMTypeRef vertexCacheType = LLVMStructTypeInContext(llvm_ref->lc.context, arg_types, 2, false);
+        arg_types[3] = LLVMPointerType(vertexCacheType, 0);
+        LLVMTypeRef gpuStatePtrType = LLVMPointerType(LLVMStructCreateNamed(llvm_ref->lc.context, "GPUState"), 0);
+        arg_types[0] = gpuStatePtrType;
+        arg_types[1] = LLVMFloatTypeInContext(llvm_ref->lc.context);
+        arg_types[2] = LLVMPointerType(float4, 0);
+        arg_types[4] = LLVMPointerType(float4, 0);
+        main_function_type = LLVMFunctionType(ret_type, arg_types, 3, 0);
+        //TODO: this is zero argument function and returns void
+        main_function_type = LLVMFunctionType(ret_type, arg_types, 5, 0);
+    }
+   LLVMValueRef main_function = LLVMAddFunction(mod, gl_shader_stage_name(nir->info.stage), main_function_type);
    LLVMBasicBlockRef main_function_body =
       LLVMAppendBasicBlockInContext(ctx.lc.context, main_function, "main_body");
    LLVMPositionBuilderAtEnd(ctx.lc.builder, main_function_body);
@@ -2732,52 +2788,60 @@ LLVMModuleRef libresoc_nir_translate(struct libresoc_llvm *llvm_ref, struct nir_
                                       0, NULL,
                                      NULL);
     if (disasm) {
-LLVMOrcTargetAddress MainAddr;
-LLVMOrcGetSymbolAddress(llvm_ref->orc_ref, &MainAddr ,"main_function");
-   const uint8_t *bytes = (const uint8_t *)MainAddr; 
-   char outline[1024];
-uint64_t pc;
-   pc = 0;
-uint64_t extent = 200;
-   while (pc < extent) {
-      size_t Size;
-
-      /*
-       * Print address.  We use addresses relative to the start of the function,
-       * so that between runs.
-       */
-
-
-      Size = LLVMDisasmInstruction(disasm, (uint8_t *)bytes + pc, extent - pc, 0, outline,
-                                   sizeof outline);
-
-      /*
-       * Print the instruction.
-       */
-      printf("\t%s \n", outline);
-
-
-      /*
-       * Stop disassembling on return statements, if there is no record of a
-       * jump to a successive address.
-       *
-       * XXX: This currently assumes x86
-       */
-
-      if (Size == 1 && bytes[pc] == 0xc3) {
-         break;
-      }
+        LLVMOrcTargetAddress MainAddr;
+        LLVMOrcGetSymbolAddress(llvm_ref->orc_ref, &MainAddr ,gl_shader_stage_name(nir->info.stage));
+        // if(nir->info.stage == MESA_SHADER_VERTEX)
+        // {
+        //     pipeline->vs = (VertexShader)MainAddr;
+        // }
+        // else if(nir->info.stage == MESA_SHADER_FRAGMENT)
+        // {
+        //     pipeline->fs = (FragmentShader)MainAddr;
+        // }
+        const uint8_t *bytes = (const uint8_t *)MainAddr; 
+        char outline[1024];
+        uint64_t pc;
+        pc = 0;
+        uint64_t extent = 200;
+        while (pc < extent) {
+            size_t Size;
+
+            /*
+             * Print address.  We use addresses relative to the start of the function,
+             * so that between runs.
+             */
+
+
+            Size = LLVMDisasmInstruction(disasm, (uint8_t *)bytes + pc, extent - pc, 0, outline,
+                    sizeof outline);
+
+            /*
+             * Print the instruction.
+             */
+            printf("\t%s \n", outline);
+
+
+            /*
+             * Stop disassembling on return statements, if there is no record of a
+             * jump to a successive address.
+             *
+             * XXX: This currently assumes x86
+             */
+
+            if (Size == 1 && bytes[pc] == 0xc3) {
+                break;
+            }
 
-      /*
-       * Advance.
-       */
+            /*
+             * Advance.
+             */
 
-      pc += Size;
+            pc += Size;
 
-      if (pc >= extent) {
-         break;
-      }
-   }    
+            if (pc >= extent) {
+                break;
+            }
+        }    
     }
     return mod;
     // LLVMModuleRef mod = LLVMModuleCreateWithName("libresoc_mod");
@@ -2800,3 +2864,9 @@ uint64_t extent = 200;
     //         orc_sym_resolver,
     //         (void *)(llvm_ref->orc_ref));
 }
+
+Shader GetFuncPointer(struct libresoc_llvm *llvm_ref, const char *name) {
+    LLVMOrcTargetAddress MainAddr;
+    LLVMOrcGetSymbolAddress(llvm_ref->orc_ref, &MainAddr , name);
+    return (Shader)MainAddr;
+}