radv/llvm: implement fragment shading rate

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7837>
This commit is contained in:
Samuel Pitoiset
2020-11-26 17:37:38 +01:00
committed by Marge Bot
parent bf69d89b5a
commit 0bac0b7f19
2 changed files with 67 additions and 1 deletions

View File

@@ -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;

View File

@@ -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++) {