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:

committed by
Marge Bot

parent
bf69d89b5a
commit
0bac0b7f19
@@ -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;
|
||||
|
@@ -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++) {
|
||||
|
Reference in New Issue
Block a user