Mesa (master): radv/llvm: implement fragment shading rate

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Dec 14 16:41:52 UTC 2020


Module: Mesa
Branch: master
Commit: 0bac0b7f19bb74fe8e99edec87331cb6c7a9e64e
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=0bac0b7f19bb74fe8e99edec87331cb6c7a9e64e

Author: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Date:   Thu Nov 26 17:37:38 2020 +0100

radv/llvm: implement fragment shading rate

Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7837>

---

 src/amd/llvm/ac_nir_to_llvm.c     | 27 ++++++++++++++++++++++++++
 src/amd/vulkan/radv_nir_to_llvm.c | 41 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 67 insertions(+), 1 deletion(-)

diff --git a/src/amd/llvm/ac_nir_to_llvm.c b/src/amd/llvm/ac_nir_to_llvm.c
index 8551b908f85..64eb62a4a59 100644
--- a/src/amd/llvm/ac_nir_to_llvm.c
+++ b/src/amd/llvm/ac_nir_to_llvm.c
@@ -3304,6 +3304,30 @@ static LLVMValueRef visit_load(struct ac_nir_context *ctx, nir_intrinsic_instr *
    return LLVMBuildBitCast(ctx->ac.builder, result, dest_type, "");
 }
 
+static LLVMValueRef
+emit_load_frag_shading_rate(struct ac_nir_context *ctx)
+{
+   LLVMValueRef x_rate, y_rate, cond;
+
+   /* VRS Rate X = Ancillary[2:3]
+    * VRS Rate Y = Ancillary[4:5]
+    */
+   x_rate = ac_unpack_param(&ctx->ac, ac_get_arg(&ctx->ac, ctx->args->ancillary), 2, 2);
+   y_rate = ac_unpack_param(&ctx->ac, ac_get_arg(&ctx->ac, ctx->args->ancillary), 4, 2);
+
+   /* xRate = xRate == 0x1 ? Horizontal2Pixels : None. */
+   cond = LLVMBuildICmp(ctx->ac.builder, LLVMIntEQ, x_rate, ctx->ac.i32_1, "");
+   x_rate = LLVMBuildSelect(ctx->ac.builder, cond,
+                            LLVMConstInt(ctx->ac.i32, 4, false), ctx->ac.i32_0, "");
+
+   /* yRate = yRate == 0x1 ? Vertical2Pixels : None. */
+   cond = LLVMBuildICmp(ctx->ac.builder, LLVMIntEQ, y_rate, ctx->ac.i32_1, "");
+   y_rate = LLVMBuildSelect(ctx->ac.builder, cond,
+                            LLVMConstInt(ctx->ac.i32, 1, false), ctx->ac.i32_0, "");
+
+   return LLVMBuildOr(ctx->ac.builder, x_rate, y_rate, "");
+}
+
 static void visit_intrinsic(struct ac_nir_context *ctx, nir_intrinsic_instr *instr)
 {
    LLVMValueRef result = NULL;
@@ -3405,6 +3429,9 @@ static void visit_intrinsic(struct ac_nir_context *ctx, nir_intrinsic_instr *ins
       result = ac_to_integer(&ctx->ac, ac_build_gather_values(&ctx->ac, values, 4));
       break;
    }
+   case nir_intrinsic_load_frag_shading_rate:
+      result = emit_load_frag_shading_rate(ctx);
+      break;
    case nir_intrinsic_load_layer_id:
       result = ctx->abi->inputs[ac_llvm_reg_index_soa(VARYING_SLOT_LAYER, 0)];
       break;
diff --git a/src/amd/vulkan/radv_nir_to_llvm.c b/src/amd/vulkan/radv_nir_to_llvm.c
index f52953f6b04..129cf9dec66 100644
--- a/src/amd/vulkan/radv_nir_to_llvm.c
+++ b/src/amd/vulkan/radv_nir_to_llvm.c
@@ -1747,6 +1747,7 @@ radv_llvm_export_vs(struct radv_shader_context *ctx,
 		    bool export_clip_dists)
 {
 	LLVMValueRef psize_value = NULL, layer_value = NULL, viewport_value = NULL;
+	LLVMValueRef primitive_shading_rate = NULL;
 	struct ac_export_args pos_args[4] = {0};
 	unsigned pos_idx, index;
 	int i;
@@ -1767,6 +1768,9 @@ radv_llvm_export_vs(struct radv_shader_context *ctx,
 		case VARYING_SLOT_VIEWPORT:
 			viewport_value = outputs[i].values[0];
 			break;
+		case VARYING_SLOT_PRIMITIVE_SHADING_RATE:
+			primitive_shading_rate = outputs[i].values[0];
+			break;
 		case VARYING_SLOT_CLIP_DIST0:
 		case VARYING_SLOT_CLIP_DIST1:
 			index = 2 + outputs[i].slot_index;
@@ -1794,8 +1798,11 @@ radv_llvm_export_vs(struct radv_shader_context *ctx,
 
 	if (outinfo->writes_pointsize ||
 	    outinfo->writes_layer ||
-	    outinfo->writes_viewport_index) {
+	    outinfo->writes_layer ||
+	    outinfo->writes_viewport_index ||
+	    outinfo->writes_primitive_shading_rate) {
 		pos_args[1].enabled_channels = ((outinfo->writes_pointsize == true ? 1 : 0) |
+						(outinfo->writes_primitive_shading_rate == true ? 2 : 0) |
 						(outinfo->writes_layer == true ? 4 : 0));
 		pos_args[1].valid_mask = 0;
 		pos_args[1].done = 0;
@@ -1830,6 +1837,38 @@ radv_llvm_export_vs(struct radv_shader_context *ctx,
 				pos_args[1].enabled_channels |= 1 << 3;
 			}
 		}
+
+		if (outinfo->writes_primitive_shading_rate) {
+			LLVMValueRef v = ac_to_integer(&ctx->ac, primitive_shading_rate);
+			LLVMValueRef cond;
+
+			/* xRate = (shadingRate & (Horizontal2Pixels | Horizontal4Pixels)) ? 0x1 : 0x0; */
+			LLVMValueRef x_rate =
+				LLVMBuildAnd(ctx->ac.builder, v,
+					     LLVMConstInt(ctx->ac.i32, 4 | 8, false), "");
+			cond = LLVMBuildICmp(ctx->ac.builder, LLVMIntNE, x_rate, ctx->ac.i32_0, "");
+			x_rate = LLVMBuildSelect(ctx->ac.builder, cond,
+						 ctx->ac.i32_1, ctx->ac.i32_0, "");
+
+			/* yRate = (shadingRate & (Vertical2Pixels | Vertical4Pixels)) ? 0x1 : 0x0; */
+			LLVMValueRef y_rate =
+				LLVMBuildAnd(ctx->ac.builder, v,
+					     LLVMConstInt(ctx->ac.i32, 1 | 2, false), "");
+			cond = LLVMBuildICmp(ctx->ac.builder, LLVMIntNE, y_rate, ctx->ac.i32_0, "");
+			y_rate = LLVMBuildSelect(ctx->ac.builder, cond,
+						 ctx->ac.i32_1, ctx->ac.i32_0, "");
+
+			/* Bits [2:3] = VRS rate X
+			 * Bits [4:5] = VRS rate Y
+			 * HW shading rate = (xRate << 2) | (yRate << 4)
+			 */
+			v = LLVMBuildOr(ctx->ac.builder,
+					LLVMBuildShl(ctx->ac.builder, x_rate,
+						      LLVMConstInt(ctx->ac.i32, 2, false), ""),
+					LLVMBuildShl(ctx->ac.builder, y_rate,
+						      LLVMConstInt(ctx->ac.i32, 4, false), ""), "");
+			pos_args[1].out[1] = ac_to_float(&ctx->ac, v);
+		}
 	}
 
 	for (i = 0; i < 4; i++) {



More information about the mesa-commit mailing list