radv: remove the radv_finishme() when compiling shaders
[mesa.git] / src / amd / vulkan / radv_nir_to_llvm.c
index e2d241e495ce6555467ece4c4600ecd72e92424a..b4af0f294150338b68b198bd3e55f9b580a13ab6 100644 (file)
@@ -124,6 +124,98 @@ radv_shader_context_from_abi(struct ac_shader_abi *abi)
        return container_of(abi, ctx, abi);
 }
 
+struct ac_build_if_state
+{
+       struct radv_shader_context *ctx;
+       LLVMValueRef condition;
+       LLVMBasicBlockRef entry_block;
+       LLVMBasicBlockRef true_block;
+       LLVMBasicBlockRef false_block;
+       LLVMBasicBlockRef merge_block;
+};
+
+static LLVMBasicBlockRef
+ac_build_insert_new_block(struct radv_shader_context *ctx, const char *name)
+{
+       LLVMBasicBlockRef current_block;
+       LLVMBasicBlockRef next_block;
+       LLVMBasicBlockRef new_block;
+
+       /* get current basic block */
+       current_block = LLVMGetInsertBlock(ctx->ac.builder);
+
+       /* chqeck if there's another block after this one */
+       next_block = LLVMGetNextBasicBlock(current_block);
+       if (next_block) {
+               /* insert the new block before the next block */
+               new_block = LLVMInsertBasicBlockInContext(ctx->context, next_block, name);
+       }
+       else {
+               /* append new block after current block */
+               LLVMValueRef function = LLVMGetBasicBlockParent(current_block);
+               new_block = LLVMAppendBasicBlockInContext(ctx->context, function, name);
+       }
+       return new_block;
+}
+
+static void
+ac_nir_build_if(struct ac_build_if_state *ifthen,
+               struct radv_shader_context *ctx,
+               LLVMValueRef condition)
+{
+       LLVMBasicBlockRef block = LLVMGetInsertBlock(ctx->ac.builder);
+
+       memset(ifthen, 0, sizeof *ifthen);
+       ifthen->ctx = ctx;
+       ifthen->condition = condition;
+       ifthen->entry_block = block;
+
+       /* create endif/merge basic block for the phi functions */
+       ifthen->merge_block = ac_build_insert_new_block(ctx, "endif-block");
+
+       /* create/insert true_block before merge_block */
+       ifthen->true_block =
+               LLVMInsertBasicBlockInContext(ctx->context,
+                                             ifthen->merge_block,
+                                             "if-true-block");
+
+       /* successive code goes into the true block */
+       LLVMPositionBuilderAtEnd(ctx->ac.builder, ifthen->true_block);
+}
+
+/**
+ * End a conditional.
+ */
+static void
+ac_nir_build_endif(struct ac_build_if_state *ifthen)
+{
+       LLVMBuilderRef builder = ifthen->ctx->ac.builder;
+
+       /* Insert branch to the merge block from current block */
+       LLVMBuildBr(builder, ifthen->merge_block);
+
+       /*
+        * Now patch in the various branch instructions.
+        */
+
+       /* Insert the conditional branch instruction at the end of entry_block */
+       LLVMPositionBuilderAtEnd(builder, ifthen->entry_block);
+       if (ifthen->false_block) {
+               /* we have an else clause */
+               LLVMBuildCondBr(builder, ifthen->condition,
+                               ifthen->true_block, ifthen->false_block);
+       }
+       else {
+               /* no else clause */
+               LLVMBuildCondBr(builder, ifthen->condition,
+                               ifthen->true_block, ifthen->merge_block);
+       }
+
+       /* Resume building code at end of the ifthen->merge_block */
+       LLVMPositionBuilderAtEnd(builder, ifthen->merge_block);
+}
+
+
 static LLVMValueRef get_rel_patch_id(struct radv_shader_context *ctx)
 {
        switch (ctx->stage) {
@@ -1773,6 +1865,47 @@ static LLVMValueRef radv_get_sampler_desc(struct ac_shader_abi *abi,
        return ac_build_load_to_sgpr(&ctx->ac, list, index);
 }
 
+/* For 2_10_10_10 formats the alpha is handled as unsigned by pre-vega HW.
+ * so we may need to fix it up. */
+static LLVMValueRef
+adjust_vertex_fetch_alpha(struct radv_shader_context *ctx,
+                          unsigned adjustment,
+                          LLVMValueRef alpha)
+{
+       if (adjustment == RADV_ALPHA_ADJUST_NONE)
+               return alpha;
+
+       LLVMValueRef c30 = LLVMConstInt(ctx->ac.i32, 30, 0);
+
+       if (adjustment == RADV_ALPHA_ADJUST_SSCALED)
+               alpha = LLVMBuildFPToUI(ctx->ac.builder, alpha, ctx->ac.i32, "");
+       else
+               alpha = ac_to_integer(&ctx->ac, alpha);
+
+       /* For the integer-like cases, do a natural sign extension.
+        *
+        * For the SNORM case, the values are 0.0, 0.333, 0.666, 1.0
+        * and happen to contain 0, 1, 2, 3 as the two LSBs of the
+        * exponent.
+        */
+       alpha = LLVMBuildShl(ctx->ac.builder, alpha,
+                            adjustment == RADV_ALPHA_ADJUST_SNORM ?
+                            LLVMConstInt(ctx->ac.i32, 7, 0) : c30, "");
+       alpha = LLVMBuildAShr(ctx->ac.builder, alpha, c30, "");
+
+       /* Convert back to the right type. */
+       if (adjustment == RADV_ALPHA_ADJUST_SNORM) {
+               LLVMValueRef clamp;
+               LLVMValueRef neg_one = LLVMConstReal(ctx->ac.f32, -1.0);
+               alpha = LLVMBuildSIToFP(ctx->ac.builder, alpha, ctx->ac.f32, "");
+               clamp = LLVMBuildFCmp(ctx->ac.builder, LLVMRealULT, alpha, neg_one, "");
+               alpha = LLVMBuildSelect(ctx->ac.builder, clamp, neg_one, alpha, "");
+       } else if (adjustment == RADV_ALPHA_ADJUST_SSCALED) {
+               alpha = LLVMBuildSIToFP(ctx->ac.builder, alpha, ctx->ac.f32, "");
+       }
+
+       return alpha;
+}
 
 static void
 handle_vs_input_decl(struct radv_shader_context *ctx,
@@ -1783,18 +1916,19 @@ handle_vs_input_decl(struct radv_shader_context *ctx,
        LLVMValueRef t_list;
        LLVMValueRef input;
        LLVMValueRef buffer_index;
-       int index = variable->data.location - VERT_ATTRIB_GENERIC0;
-       int idx = variable->data.location;
        unsigned attrib_count = glsl_count_attribute_slots(variable->type, true);
        uint8_t input_usage_mask =
                ctx->shader_info->info.vs.input_usage_mask[variable->data.location];
        unsigned num_channels = util_last_bit(input_usage_mask);
 
-       variable->data.driver_location = idx * 4;
+       variable->data.driver_location = variable->data.location * 4;
 
-       for (unsigned i = 0; i < attrib_count; ++i, ++idx) {
-               if (ctx->options->key.vs.instance_rate_inputs & (1u << (index + i))) {
-                       uint32_t divisor = ctx->options->key.vs.instance_rate_divisors[index + i];
+       for (unsigned i = 0; i < attrib_count; ++i) {
+               LLVMValueRef output[4];
+               unsigned attrib_index = variable->data.location + i - VERT_ATTRIB_GENERIC0;
+
+               if (ctx->options->key.vs.instance_rate_inputs & (1u << attrib_index)) {
+                       uint32_t divisor = ctx->options->key.vs.instance_rate_divisors[attrib_index];
 
                        if (divisor) {
                                buffer_index = LLVMBuildAdd(ctx->ac.builder, ctx->abi.instance_id,
@@ -1818,7 +1952,7 @@ handle_vs_input_decl(struct radv_shader_context *ctx,
                } else
                        buffer_index = LLVMBuildAdd(ctx->ac.builder, ctx->abi.vertex_id,
                                                    ctx->abi.base_vertex, "");
-               t_offset = LLVMConstInt(ctx->ac.i32, index + i, false);
+               t_offset = LLVMConstInt(ctx->ac.i32, attrib_index, false);
 
                t_list = ac_build_load_to_sgpr(&ctx->ac, t_list_ptr, t_offset);
 
@@ -1831,9 +1965,15 @@ handle_vs_input_decl(struct radv_shader_context *ctx,
 
                for (unsigned chan = 0; chan < 4; chan++) {
                        LLVMValueRef llvm_chan = LLVMConstInt(ctx->ac.i32, chan, false);
-                       ctx->inputs[ac_llvm_reg_index_soa(idx, chan)] =
-                               ac_to_integer(&ctx->ac, LLVMBuildExtractElement(ctx->ac.builder,
-                                                       input, llvm_chan, ""));
+                       output[chan] = LLVMBuildExtractElement(ctx->ac.builder, input, llvm_chan, "");
+               }
+
+               unsigned alpha_adjust = (ctx->options->key.vs.alpha_adjust >> (attrib_index * 2)) & 3;
+               output[3] = adjust_vertex_fetch_alpha(ctx, alpha_adjust, output[3]);
+
+               for (unsigned chan = 0; chan < 4; chan++) {
+                       ctx->inputs[ac_llvm_reg_index_soa(variable->data.location + i, chan)] =
+                               ac_to_integer(&ctx->ac, output[chan]);
                }
        }
 }
@@ -2353,10 +2493,9 @@ handle_vs_outputs_post(struct radv_shader_context *ctx,
                        output_usage_mask =
                                ctx->shader_info->info.tes.output_usage_mask[i];
                } else {
-                       /* Enable all channels for the GS copy shader because
-                        * we don't know the output usage mask currently.
-                        */
-                       output_usage_mask = 0xf;
+                       assert(ctx->is_gs_copy_shader);
+                       output_usage_mask =
+                               ctx->shader_info->info.gs.output_usage_mask[i];
                }
 
                radv_export_param(ctx, param_count, values, output_usage_mask);
@@ -2502,97 +2641,6 @@ handle_ls_outputs_post(struct radv_shader_context *ctx)
        }
 }
 
-struct ac_build_if_state
-{
-       struct radv_shader_context *ctx;
-       LLVMValueRef condition;
-       LLVMBasicBlockRef entry_block;
-       LLVMBasicBlockRef true_block;
-       LLVMBasicBlockRef false_block;
-       LLVMBasicBlockRef merge_block;
-};
-
-static LLVMBasicBlockRef
-ac_build_insert_new_block(struct radv_shader_context *ctx, const char *name)
-{
-       LLVMBasicBlockRef current_block;
-       LLVMBasicBlockRef next_block;
-       LLVMBasicBlockRef new_block;
-
-       /* get current basic block */
-       current_block = LLVMGetInsertBlock(ctx->ac.builder);
-
-       /* check if there's another block after this one */
-       next_block = LLVMGetNextBasicBlock(current_block);
-       if (next_block) {
-               /* insert the new block before the next block */
-               new_block = LLVMInsertBasicBlockInContext(ctx->context, next_block, name);
-       }
-       else {
-               /* append new block after current block */
-               LLVMValueRef function = LLVMGetBasicBlockParent(current_block);
-               new_block = LLVMAppendBasicBlockInContext(ctx->context, function, name);
-       }
-       return new_block;
-}
-
-static void
-ac_nir_build_if(struct ac_build_if_state *ifthen,
-               struct radv_shader_context *ctx,
-               LLVMValueRef condition)
-{
-       LLVMBasicBlockRef block = LLVMGetInsertBlock(ctx->ac.builder);
-
-       memset(ifthen, 0, sizeof *ifthen);
-       ifthen->ctx = ctx;
-       ifthen->condition = condition;
-       ifthen->entry_block = block;
-
-       /* create endif/merge basic block for the phi functions */
-       ifthen->merge_block = ac_build_insert_new_block(ctx, "endif-block");
-
-       /* create/insert true_block before merge_block */
-       ifthen->true_block =
-               LLVMInsertBasicBlockInContext(ctx->context,
-                                             ifthen->merge_block,
-                                             "if-true-block");
-
-       /* successive code goes into the true block */
-       LLVMPositionBuilderAtEnd(ctx->ac.builder, ifthen->true_block);
-}
-
-/**
- * End a conditional.
- */
-static void
-ac_nir_build_endif(struct ac_build_if_state *ifthen)
-{
-       LLVMBuilderRef builder = ifthen->ctx->ac.builder;
-
-       /* Insert branch to the merge block from current block */
-       LLVMBuildBr(builder, ifthen->merge_block);
-
-       /*
-        * Now patch in the various branch instructions.
-        */
-
-       /* Insert the conditional branch instruction at the end of entry_block */
-       LLVMPositionBuilderAtEnd(builder, ifthen->entry_block);
-       if (ifthen->false_block) {
-               /* we have an else clause */
-               LLVMBuildCondBr(builder, ifthen->condition,
-                               ifthen->true_block, ifthen->false_block);
-       }
-       else {
-               /* no else clause */
-               LLVMBuildCondBr(builder, ifthen->condition,
-                               ifthen->true_block, ifthen->merge_block);
-       }
-
-       /* Resume building code at end of the ifthen->merge_block */
-       LLVMPositionBuilderAtEnd(builder, ifthen->merge_block);
-}
-
 static void
 write_tess_factors(struct radv_shader_context *ctx)
 {
@@ -3500,6 +3548,8 @@ radv_compile_gs_copy_shader(LLVMTargetMachineRef tm,
        ctx.ac.builder = ac_create_builder(ctx.context, float_mode);
        ctx.stage = MESA_SHADER_VERTEX;
 
+       radv_nir_shader_info_pass(geom_shader, options, &shader_info->info);
+
        create_function(&ctx, MESA_SHADER_VERTEX, false, MESA_SHADER_VERTEX);
 
        ctx.gs_max_out_vertices = geom_shader->info.gs.vertices_out;