diff --git a/libs/vkd3d-shader/msl.c b/libs/vkd3d-shader/msl.c index 26ffac9eb..9279b5ae5 100644 --- a/libs/vkd3d-shader/msl.c +++ b/libs/vkd3d-shader/msl.c @@ -387,6 +387,14 @@ static enum msl_data_type msl_print_register_name(struct vkd3d_string_buffer *bu msl_print_subscript(buffer, gen, reg->idx[1].rel_addr, reg->idx[1].offset); return MSL_DATA_UNION; + case VKD3DSPR_SAMPLEMASK: + if (gen->program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled sample coverage mask in shader type #%x.", + gen->program->shader_version.type); + vkd3d_string_buffer_printf(buffer, "o_mask"); + return MSL_DATA_FLOAT; + default: msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, "Internal compiler error: Unhandled register type %#x.", reg->type); @@ -1292,6 +1300,12 @@ static void msl_generate_output_struct_declarations(struct msl_generator *gen) vkd3d_string_buffer_printf(buffer, "float shader_out_depth [[depth(any)]];\n"); } + if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK)) + { + msl_print_indent(gen->buffer, 1); + vkd3d_string_buffer_printf(buffer, "uint shader_out_mask [[sample_mask]];\n"); + } + vkd3d_string_buffer_printf(buffer, "};\n\n"); } @@ -1387,6 +1401,9 @@ static void msl_generate_entrypoint_epilogue(struct msl_generator *gen) } vkd3d_string_buffer_printf(buffer, ";\n"); } + + if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK)) + vkd3d_string_buffer_printf(gen->buffer, " output.shader_out_mask = as_type(o_mask);\n"); } static void msl_generate_entrypoint(struct msl_generator *gen) @@ -1430,6 +1447,9 @@ static void msl_generate_entrypoint(struct msl_generator *gen) vkd3d_string_buffer_printf(gen->buffer, " vkd3d_vec4 %s_in[%u];\n", gen->prefix, 32); vkd3d_string_buffer_printf(gen->buffer, " vkd3d_vec4 %s_out[%u];\n", gen->prefix, 32); vkd3d_string_buffer_printf(gen->buffer, " vkd3d_%s_out output;\n", gen->prefix); + if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK)) + vkd3d_string_buffer_printf(gen->buffer, " float o_mask;\n"); + vkd3d_string_buffer_printf(gen->buffer, "\n"); msl_generate_entrypoint_prologue(gen); @@ -1438,9 +1458,11 @@ static void msl_generate_entrypoint(struct msl_generator *gen) vkd3d_string_buffer_printf(gen->buffer, ", vertex_id"); if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_DEPTHOUT)) vkd3d_string_buffer_printf(gen->buffer, ", output.shader_out_depth"); + if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK)) + vkd3d_string_buffer_printf(gen->buffer, ", o_mask"); if (gen->program->descriptors.descriptor_count) vkd3d_string_buffer_printf(gen->buffer, ", descriptors"); - vkd3d_string_buffer_printf(gen->buffer, ");\n"); + vkd3d_string_buffer_printf(gen->buffer, ");\n\n"); msl_generate_entrypoint_epilogue(gen); @@ -1502,6 +1524,8 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader vkd3d_string_buffer_printf(gen->buffer, ", uint vertex_id"); if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_DEPTHOUT)) vkd3d_string_buffer_printf(gen->buffer, ", thread float &o_depth"); + if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK)) + vkd3d_string_buffer_printf(gen->buffer, ", thread float &o_mask"); if (gen->program->descriptors.descriptor_count) vkd3d_string_buffer_printf(gen->buffer, ", constant descriptor *descriptors"); vkd3d_string_buffer_printf(gen->buffer, ")\n{\n"); diff --git a/tests/hlsl/coverage.shader_test b/tests/hlsl/coverage.shader_test index bcaf3aa85..f09476c42 100644 --- a/tests/hlsl/coverage.shader_test +++ b/tests/hlsl/coverage.shader_test @@ -14,11 +14,11 @@ float4 main(out uint sample_mask : SV_Coverage) : SV_Target [test] clear rtv 0 0.0 0.0 0.0 0.0 -todo(glsl | msl) draw quad +todo(glsl) draw quad probe (0, 0) rgba (0.5, 0.5, 0.5, 0.5) sample mask 0x0b clear rtv 0 0.0 0.0 0.0 0.0 -todo(glsl | msl) draw quad +todo(glsl) draw quad probe (0, 0) rgba (0.25, 0.25, 0.25, 0.25) diff --git a/tests/shader_runner_metal.m b/tests/shader_runner_metal.m index d06111318..256099cac 100644 --- a/tests/shader_runner_metal.m +++ b/tests/shader_runner_metal.m @@ -24,8 +24,13 @@ #define BOOL VKD3D_BOOLEAN #include "shader_runner.h" #include "vkd3d_d3dcommon.h" +#undef interface #undef BOOL +@interface MTLRenderPipelineDescriptor () +@property (nonatomic, readwrite) NSUInteger sampleMask; +@end + static const MTLResourceOptions DEFAULT_BUFFER_RESOURCE_OPTIONS = MTLResourceCPUCacheModeDefaultCache | MTLResourceHazardTrackingModeDefault; @@ -687,6 +692,7 @@ static bool metal_runner_draw(struct shader_runner *r, D3D_PRIMITIVE_TOPOLOGY to } } pipeline_desc.rasterSampleCount = runner->r.sample_count; + pipeline_desc.sampleMask = runner->r.sample_mask; viewport.width = fb_width; viewport.height = fb_height;