diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c index 589b800f..44b1714b 100644 --- a/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d-shader/d3dbc.c @@ -110,13 +110,6 @@ enum vkd3d_sm1_misc_register VKD3D_SM1_MISC_FACE = 0x1, }; -enum vkd3d_sm1_rastout_register -{ - VKD3D_SM1_RASTOUT_POSITION = 0x0, - VKD3D_SM1_RASTOUT_FOG = 0x1, - VKD3D_SM1_RASTOUT_POINT_SIZE = 0x2, -}; - enum vkd3d_sm1_opcode { VKD3D_SM1_OP_NOP = 0x00, @@ -957,6 +950,9 @@ static void shader_sm1_read_dst_param(struct vkd3d_shader_sm1_parser *sm1, const shader_sm1_parse_src_param(addr_token, NULL, dst_rel_addr); } shader_sm1_parse_dst_param(token, dst_rel_addr, dst_param); + + if (dst_param->reg.type == VKD3DSPR_RASTOUT && dst_param->reg.idx[0].offset == VSIR_RASTOUT_POINT_SIZE) + sm1->p.program->has_point_size = true; } static void shader_sm1_read_semantic(struct vkd3d_shader_sm1_parser *sm1, @@ -1434,17 +1430,17 @@ bool hlsl_sm1_register_from_semantic(const struct vkd3d_shader_version *version, {"vpos", false, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_MISCTYPE, VKD3D_SM1_MISC_POSITION}, {"color", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_ATTROUT}, - {"fog", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VKD3D_SM1_RASTOUT_FOG}, - {"position", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VKD3D_SM1_RASTOUT_POSITION}, - {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VKD3D_SM1_RASTOUT_POINT_SIZE}, - {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VKD3D_SM1_RASTOUT_POSITION}, + {"fog", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VSIR_RASTOUT_FOG}, + {"position", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, + {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POINT_SIZE}, + {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, {"texcoord", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_TEXCRDOUT}, {"color", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_ATTROUT}, - {"fog", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VKD3D_SM1_RASTOUT_FOG}, - {"position", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VKD3D_SM1_RASTOUT_POSITION}, - {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VKD3D_SM1_RASTOUT_POINT_SIZE}, - {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VKD3D_SM1_RASTOUT_POSITION}, + {"fog", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VSIR_RASTOUT_FOG}, + {"position", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, + {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POINT_SIZE}, + {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, {"texcoord", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_TEXCRDOUT}, }; diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index b5035b3c..293dbf68 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -1648,6 +1648,9 @@ static bool shader_dst_param_io_normalise(struct vkd3d_shader_dst_param *dst_par break; case VKD3DSPR_RASTOUT: + /* Leave point size as a system value for the backends to consume. */ + if (reg->idx[0].offset == VSIR_RASTOUT_POINT_SIZE) + return true; reg_idx = SM1_RASTOUT_REGISTER_OFFSET + reg->idx[0].offset; signature = normaliser->output_signature; reg->type = VKD3DSPR_OUTPUT; diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index a2771b62..57311407 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -4863,6 +4863,10 @@ static const struct vkd3d_spirv_builtin vkd3d_pixel_shader_position_builtin = { VKD3D_SHADER_COMPONENT_FLOAT, 4, SpvBuiltInFragCoord, frag_coord_fixup, }; +static const struct vkd3d_spirv_builtin vkd3d_output_point_size_builtin = +{ + VKD3D_SHADER_COMPONENT_FLOAT, 1, SpvBuiltInPointSize, +}; static const struct { enum vkd3d_shader_register_type reg_type; @@ -5452,7 +5456,11 @@ static void spirv_compiler_emit_output_register(struct spirv_compiler *compiler, VKD3D_ASSERT(!reg->idx_count || !reg->idx[0].rel_addr); VKD3D_ASSERT(reg->idx_count < 2); - if (!(builtin = get_spirv_builtin_for_register(reg->type))) + if (reg->type == VKD3DSPR_RASTOUT && reg->idx[0].offset == VSIR_RASTOUT_POINT_SIZE) + { + builtin = &vkd3d_output_point_size_builtin; + } + else if (!(builtin = get_spirv_builtin_for_register(reg->type))) { FIXME("Unhandled register %#x.\n", reg->type); return; @@ -6749,7 +6757,8 @@ static void spirv_compiler_emit_dcl_input_primitive(struct spirv_compiler *compi static void spirv_compiler_emit_point_size(struct spirv_compiler *compiler) { - static const struct vkd3d_spirv_builtin point_size = {VKD3D_SHADER_COMPONENT_FLOAT, 1, SpvBuiltInPointSize}; + if (compiler->program->has_point_size) + return; /* Set the point size. Point sprites are not supported in d3d10+, but * point primitives can still be used with e.g. stream output. Vulkan @@ -6763,7 +6772,8 @@ static void spirv_compiler_emit_point_size(struct spirv_compiler *compiler) || compiler->write_tess_geom_point_size) { vkd3d_spirv_build_op_store(&compiler->spirv_builder, - spirv_compiler_emit_builtin_variable(compiler, &point_size, SpvStorageClassOutput, 0), + spirv_compiler_emit_builtin_variable(compiler, + &vkd3d_output_point_size_builtin, SpvStorageClassOutput, 0), spirv_compiler_get_constant_float(compiler, 1.0f), SpvMemoryAccessMaskNone); } } @@ -10577,6 +10587,15 @@ static void spirv_compiler_emit_io_declarations(struct spirv_compiler *compiler) else spirv_compiler_emit_input(compiler, VKD3DSPR_PATCHCONST, i); } + + if (compiler->program->has_point_size) + { + struct vkd3d_shader_dst_param dst; + + vsir_dst_param_init(&dst, VKD3DSPR_RASTOUT, VKD3D_DATA_FLOAT, 1); + dst.reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE; + spirv_compiler_emit_output_register(compiler, &dst); + } } static void spirv_compiler_emit_descriptor_declarations(struct spirv_compiler *compiler) diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index b7397dfe..7c5f6686 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -650,6 +650,13 @@ enum vkd3d_shader_register_type VKD3DSPR_INVALID = ~0u, }; +enum vsir_rastout_register +{ + VSIR_RASTOUT_POSITION = 0x0, + VSIR_RASTOUT_FOG = 0x1, + VSIR_RASTOUT_POINT_SIZE = 0x2, +}; + enum vkd3d_shader_register_precision { VKD3D_SHADER_REGISTER_PRECISION_DEFAULT, @@ -1402,6 +1409,7 @@ struct vsir_program unsigned int temp_count; unsigned int ssa_count; bool use_vocp; + bool has_point_size; enum vsir_control_flow_type cf_type; const char **block_names; diff --git a/tests/hlsl/shader-point-size.shader_test b/tests/hlsl/shader-point-size.shader_test index 1e7a3395..cab511aa 100644 --- a/tests/hlsl/shader-point-size.shader_test +++ b/tests/hlsl/shader-point-size.shader_test @@ -24,11 +24,11 @@ float4 main() : color draw point list 2 probe (149, 240) rgba (0, 0, 0, 0) -todo probe (151, 240) rgba (0, 1, 0, 1) -todo probe (169, 240) rgba (0, 1, 0, 1) +probe (151, 240) rgba (0, 1, 0, 1) +probe (169, 240) rgba (0, 1, 0, 1) probe (171, 240) rgba (0, 0, 0, 0) probe (459, 240) rgba (0, 0, 0, 0) -todo probe (461, 240) rgba (0, 1, 0, 1) -todo probe (499, 240) rgba (0, 1, 0, 1) +probe (461, 240) rgba (0, 1, 0, 1) +probe (499, 240) rgba (0, 1, 0, 1) probe (501, 240) rgba (0, 0, 0, 0)