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