vkd3d-shader/hlsl: Implement the GetRenderTargetSampleCount() intrinsic.

This commit is contained in:
Elizabeth Figura 2024-06-10 17:06:54 -05:00 committed by Henri Verbeet
parent a5a75d45d3
commit 71a3d55e8c
Notes: Henri Verbeet 2024-07-11 00:41:24 +02:00
Approved-by: Giovanni Mascellani (@giomasce)
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/924
5 changed files with 46 additions and 2 deletions

View File

@ -2793,6 +2793,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op)
static const char *const op_names[] =
{
[HLSL_OP0_VOID] = "void",
[HLSL_OP0_RASTERIZER_SAMPLE_COUNT] = "GetRenderTargetSampleCount",
[HLSL_OP1_ABS] = "abs",
[HLSL_OP1_BIT_NOT] = "~",

View File

@ -638,6 +638,7 @@ struct hlsl_ir_switch
enum hlsl_ir_expr_op
{
HLSL_OP0_VOID,
HLSL_OP0_RASTERIZER_SAMPLE_COUNT,
HLSL_OP1_ABS,
HLSL_OP1_BIT_NOT,

View File

@ -4688,6 +4688,20 @@ static bool intrinsic_d3dcolor_to_ubyte4(struct hlsl_ctx *ctx,
return true;
}
static bool intrinsic_GetRenderTargetSampleCount(struct hlsl_ctx *ctx,
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
{
struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0};
struct hlsl_ir_node *expr;
if (!(expr = hlsl_new_expr(ctx, HLSL_OP0_RASTERIZER_SAMPLE_COUNT,
operands, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc)))
return false;
hlsl_block_add_instr(params->instrs, expr);
return true;
}
static const struct intrinsic_function
{
const char *name;
@ -4700,6 +4714,7 @@ intrinsic_functions[] =
{
/* Note: these entries should be kept in alphabetical order. */
{"D3DCOLORtoUBYTE4", 1, true, intrinsic_d3dcolor_to_ubyte4},
{"GetRenderTargetSampleCount", 0, true, intrinsic_GetRenderTargetSampleCount},
{"abs", 1, true, intrinsic_abs},
{"acos", 1, true, intrinsic_acos},
{"all", 1, true, intrinsic_all},

View File

@ -5042,6 +5042,25 @@ static void write_sm4_store_uav_typed(const struct tpf_writer *tpf, const struct
write_sm4_instruction(tpf, &instr);
}
static void write_sm4_rasterizer_sample_count(const struct tpf_writer *tpf, const struct hlsl_ir_node *dst)
{
struct sm4_instruction instr;
memset(&instr, 0, sizeof(instr));
instr.opcode = VKD3D_SM4_OP_SAMPLE_INFO;
instr.extra_bits |= VKD3DSI_SAMPLE_INFO_UINT << VKD3D_SM4_INSTRUCTION_FLAGS_SHIFT;
sm4_dst_from_node(&instr.dsts[0], dst);
instr.dst_count = 1;
instr.srcs[0].reg.type = VKD3DSPR_RASTERIZER;
instr.srcs[0].reg.dimension = VSIR_DIMENSION_VEC4;
instr.srcs[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
instr.src_count = 1;
write_sm4_instruction(tpf, &instr);
}
static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_expr *expr)
{
const struct hlsl_ir_node *arg1 = expr->operands[0].node;
@ -5057,6 +5076,14 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex
switch (expr->op)
{
case HLSL_OP0_RASTERIZER_SAMPLE_COUNT:
if (tpf->ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL && hlsl_version_ge(tpf->ctx, 4, 1))
write_sm4_rasterizer_sample_count(tpf, &expr->node);
else
hlsl_error(tpf->ctx, &expr->node.loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE,
"GetRenderTargetSampleCount() can only be used from a pixel shader using version 4.1 or higher.");
break;
case HLSL_OP1_ABS:
switch (dst_type->e.numeric.type)
{

View File

@ -6,14 +6,14 @@ shader model >= 4.1
format r32g32b32a32 float
size (2dms, 4, 640, 480)
[pixel shader todo]
[pixel shader]
float4 main() : sv_target
{
return float4(GetRenderTargetSampleCount(), 0, 0, 0);
}
[test]
todo(sm<6) draw quad
todo(glsl) draw quad
probe (0, 0) rgba (4.0, 0.0, 0.0, 0.0)