diff --git a/libs/vkd3d-shader/msl.c b/libs/vkd3d-shader/msl.c index 08519787b..3a04e5c88 100644 --- a/libs/vkd3d-shader/msl.c +++ b/libs/vkd3d-shader/msl.c @@ -55,7 +55,7 @@ struct msl_generator struct msl_resource_type_info { - size_t read_coord_size; + size_t coord_size; bool array; const char *type_suffix; }; @@ -84,11 +84,11 @@ static const struct msl_resource_type_info *msl_get_resource_type_info(enum vkd3 [VKD3D_SHADER_RESOURCE_TEXTURE_2D] = {2, 0, "2d"}, [VKD3D_SHADER_RESOURCE_TEXTURE_2DMS] = {2, 0, "2d_ms"}, [VKD3D_SHADER_RESOURCE_TEXTURE_3D] = {3, 0, "3d"}, - [VKD3D_SHADER_RESOURCE_TEXTURE_CUBE] = {2, 0, "cube"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_CUBE] = {3, 0, "cube"}, [VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY] = {1, 1, "1d_array"}, [VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY] = {2, 1, "2d_array"}, [VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY] = {2, 1, "2d_ms_array"}, - [VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY] = {2, 1, "cube_array"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY] = {3, 1, "cube_array"}, }; if (!t || t >= ARRAY_SIZE(info)) @@ -228,6 +228,35 @@ static const struct vkd3d_shader_descriptor_binding *msl_get_cbv_binding(const s return NULL; } +static const struct vkd3d_shader_descriptor_binding *msl_get_sampler_binding(const struct msl_generator *gen, + unsigned int register_space, unsigned int register_idx) +{ + const struct vkd3d_shader_interface_info *interface_info = gen->interface_info; + const struct vkd3d_shader_resource_binding *binding; + unsigned int i; + + if (!interface_info) + return NULL; + + for (i = 0; i < interface_info->binding_count; ++i) + { + binding = &interface_info->bindings[i]; + + if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER) + continue; + if (binding->register_space != register_space) + continue; + if (binding->register_index != register_idx) + continue; + if (!msl_check_shader_visibility(gen, binding->shader_visibility)) + continue; + + return &binding->binding; + } + + return NULL; +} + static const struct vkd3d_shader_descriptor_binding *msl_get_srv_binding(const struct msl_generator *gen, unsigned int register_space, unsigned int register_idx, enum vkd3d_shader_resource_type resource_type) { @@ -267,10 +296,15 @@ static void msl_print_cbv_name(struct vkd3d_string_buffer *buffer, unsigned int vkd3d_string_buffer_printf(buffer, "descriptors[%u].buf()", binding); } +static void msl_print_sampler_name(struct vkd3d_string_buffer *buffer, unsigned int binding) +{ + vkd3d_string_buffer_printf(buffer, "descriptors[%u].as()", binding); +} + static void msl_print_srv_name(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, unsigned int binding, const struct msl_resource_type_info *resource_type_info, enum vkd3d_data_type resource_data_type) { - vkd3d_string_buffer_printf(buffer, "descriptors[%u].textype_suffix); msl_print_resource_datatype(gen, buffer, resource_data_type); vkd3d_string_buffer_printf(buffer, ">>()"); @@ -877,7 +911,7 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct "Internal compiler error: Unhandled resource type %#x.", resource_type); resource_type_info = msl_get_resource_type_info(VKD3D_SHADER_RESOURCE_TEXTURE_2D); } - coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->read_coord_size); + coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->coord_size); if ((binding = msl_get_srv_binding(gen, resource_space, resource_idx, resource_type))) { @@ -920,6 +954,123 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct msl_dst_cleanup(&dst, &gen->string_buffers); } +static void msl_sample(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) +{ + const struct msl_resource_type_info *resource_type_info; + unsigned int resource_id, resource_idx, resource_space; + const struct vkd3d_shader_descriptor_binding *binding; + unsigned int sampler_id, sampler_idx, sampler_space; + const struct vkd3d_shader_descriptor_info1 *d; + enum vkd3d_shader_resource_type resource_type; + unsigned int srv_binding, sampler_binding; + struct vkd3d_string_buffer *sample; + enum vkd3d_data_type data_type; + uint32_t coord_mask; + struct msl_dst dst; + + if (vkd3d_shader_instruction_has_texel_offset(ins)) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled texel sample offset."); + + if (ins->src[1].reg.idx[0].rel_addr || ins->src[1].reg.idx[1].rel_addr + || ins->src[2].reg.idx[0].rel_addr || ins->src[2].reg.idx[1].rel_addr) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, + "Descriptor indexing is not supported."); + + resource_id = ins->src[1].reg.idx[0].offset; + resource_idx = ins->src[1].reg.idx[1].offset; + if ((d = vkd3d_shader_find_descriptor(&gen->program->descriptors, + VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource_id))) + { + resource_space = d->register_space; + resource_type = d->resource_type; + data_type = d->resource_data_type; + } + else + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Undeclared resource descriptor %u.", resource_id); + resource_space = 0; + resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; + data_type = VKD3D_DATA_FLOAT; + } + + if (resource_type == VKD3D_SHADER_RESOURCE_BUFFER + || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS + || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, + "Sampling resource type %#x is not supported.", resource_type); + + if (!(resource_type_info = msl_get_resource_type_info(resource_type))) + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled resource type %#x.", resource_type); + resource_type_info = msl_get_resource_type_info(VKD3D_SHADER_RESOURCE_TEXTURE_2D); + } + coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->coord_size); + + if ((binding = msl_get_srv_binding(gen, resource_space, resource_idx, resource_type))) + { + srv_binding = binding->binding; + } + else + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, + "No descriptor binding specified for SRV %u (index %u, space %u).", + resource_id, resource_idx, resource_space); + srv_binding = 0; + } + + sampler_id = ins->src[2].reg.idx[0].offset; + sampler_idx = ins->src[2].reg.idx[1].offset; + if ((d = vkd3d_shader_find_descriptor(&gen->program->descriptors, + VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, sampler_id))) + { + sampler_space = d->register_space; + } + else + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Undeclared sampler descriptor %u.", sampler_id); + sampler_space = 0; + } + + if ((binding = msl_get_sampler_binding(gen, sampler_space, sampler_idx))) + { + sampler_binding = binding->binding; + } + else + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, + "No descriptor binding specified for sampler %u (index %u, space %u).", + sampler_id, sampler_idx, sampler_space); + sampler_binding = 0; + } + + msl_dst_init(&dst, gen, ins, &ins->dst[0]); + sample = vkd3d_string_buffer_get(&gen->string_buffers); + + vkd3d_string_buffer_printf(sample, "as_type("); + msl_print_srv_name(sample, gen, srv_binding, resource_type_info, data_type); + vkd3d_string_buffer_printf(sample, ".sample("); + msl_print_sampler_name(sample, sampler_binding); + vkd3d_string_buffer_printf(sample, ", "); + msl_print_src_with_type(sample, gen, &ins->src[0], coord_mask, ins->src[0].reg.data_type); + if (resource_type_info->array) + { + vkd3d_string_buffer_printf(sample, ", uint("); + msl_print_src_with_type(sample, gen, &ins->src[0], coord_mask + 1, ins->src[0].reg.data_type); + vkd3d_string_buffer_printf(sample, ")"); + } + vkd3d_string_buffer_printf(sample, "))"); + msl_print_swizzle(sample, ins->src[1].swizzle, ins->dst[0].write_mask); + + msl_print_assignment(gen, &dst, "%s", sample->buffer); + + vkd3d_string_buffer_release(&gen->string_buffers, sample); + msl_dst_cleanup(&dst, &gen->string_buffers); +} + static void msl_unary_op(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins, const char *op) { struct msl_src src; @@ -1086,6 +1237,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d case VKD3DSIH_FTOU: msl_cast(gen, ins, "uint"); break; + case VKD3DSIH_SAMPLE: + msl_sample(gen, ins); + break; case VKD3DSIH_GEO: case VKD3DSIH_IGE: msl_relop(gen, ins, ">="); @@ -1631,7 +1785,7 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader " const device void *ptr;\n" "\n" " template\n" - " constant T &tex() constant\n" + " constant T &as() constant\n" " {\n" " return reinterpret_cast(this->ptr);\n" " }\n" diff --git a/tests/hlsl/cbuffer.shader_test b/tests/hlsl/cbuffer.shader_test index 92521003d..d649f3475 100644 --- a/tests/hlsl/cbuffer.shader_test +++ b/tests/hlsl/cbuffer.shader_test @@ -569,7 +569,7 @@ float4 main() : sv_target uniform 0 float4 1.0 0.0 0.0 0.0 uniform 4 float4 0.0 2.0 0.0 0.0 uniform 8 float4 0.0 0.0 3.0 0.0 -todo(msl) draw quad +draw quad probe (0, 0) rgba (1.0, 2.0, 0.0, 4.0) diff --git a/tests/hlsl/combined-samplers.shader_test b/tests/hlsl/combined-samplers.shader_test index 184e90186..0f2350d1a 100644 --- a/tests/hlsl/combined-samplers.shader_test +++ b/tests/hlsl/combined-samplers.shader_test @@ -62,7 +62,7 @@ float4 main() : sv_target } [test] -todo(msl) draw quad +draw quad probe (0, 0) rgba (0, 0, 0, 1) @@ -78,7 +78,7 @@ float4 main() : sv_target [test] uniform 0 float4 0.5 0.0 0.0 0.0 -todo(msl) draw quad +draw quad probe (0, 0) rgba (0.5, 0.5, 0.5, 1.5) @@ -94,7 +94,7 @@ float4 main() : sv_target } [test] -todo(msl) draw quad +draw quad if(sm<4) probe (0, 0) rgba(1, 1, 1, 11) if(sm>=4) probe (0, 0) rgba(10, 10, 10, 11) @@ -109,7 +109,7 @@ float4 main() : sv_target } [test] -todo(msl) draw quad +draw quad if(sm<4) probe (0, 0) rgba(1, 1, 1, 11) if(sm>=4) probe (0, 0) rgba(10, 10, 10, 11) @@ -124,7 +124,7 @@ float4 main() : sv_target } [test] -todo(msl) draw quad +draw quad probe (0, 0) rgba (21, 21, 21, 11) @@ -140,7 +140,7 @@ float4 main() : sv_target } [test] -todo(msl) draw quad +draw quad if(sm<4) probe (0, 0) rgba (102, 102, 102, 111) if(sm>=4) probe (0, 0) rgba (12, 12, 12, 111) @@ -156,7 +156,7 @@ float4 main() : sv_target } [test] -todo(msl) draw quad +draw quad probe (0, 0) rgba (104, 104, 104, 111) @@ -180,7 +180,7 @@ float4 main() : sv_target } [test] -todo(msl) draw quad +draw quad probe (0, 0) rgba (1, 1, 1, 11) @@ -201,7 +201,7 @@ float4 main() : sv_target } [test] -todo(msl) draw quad +draw quad if(sm<4) probe (0, 0) rgba(453021, 453021, 453021, 111111) if(sm>=4) probe (0, 0) rgba(12333, 12333, 12333, 111111) @@ -221,7 +221,7 @@ float4 main() : sv_target } [test] -todo(msl) draw quad +draw quad if(sm<4) probe (0, 0) rgba(4351, 4351, 4351, 1111) if(sm>=4) probe (0, 0) rgba(3125, 3125, 3125, 1111) diff --git a/tests/hlsl/conditional.shader_test b/tests/hlsl/conditional.shader_test index 039c74ab3..38dafa017 100644 --- a/tests/hlsl/conditional.shader_test +++ b/tests/hlsl/conditional.shader_test @@ -243,10 +243,10 @@ float4 main() : sv_target [test] uniform 0 float -2 -todo(msl) draw quad +draw quad probe (0, 0) rgba (0.0, 0.0, 0.0, 4.0) uniform 0 float 4 -todo(msl) draw quad +draw quad probe (0, 0) rgba (1.0, 2.0, 3.0, 4.0) @@ -267,13 +267,13 @@ float4 main() : sv_target [test] uniform 0 float 2 -todo(msl) draw quad +draw quad probe (0, 0) rgba (0.0, 0.0, 0.0, 4.0) uniform 0 float 1 -todo(msl) draw quad +draw quad probe (0, 0) rgba (1.0, 0.0, 0.0, 4.0) uniform 0 float 0 -todo(msl) draw quad +draw quad probe (0, 0) rgba (1.0, 1.0, 0.0, 4.0) % Test 16-bit phi instructions. diff --git a/tests/hlsl/object-references.shader_test b/tests/hlsl/object-references.shader_test index d09deed3d..5158cecd9 100644 --- a/tests/hlsl/object-references.shader_test +++ b/tests/hlsl/object-references.shader_test @@ -46,7 +46,7 @@ float4 main() : sv_target } [test] -todo(msl) draw quad +draw quad probe (0, 0) rgba (77.77, 77.77, 77.77, 77.77) diff --git a/tests/hlsl/register-reservations-numeric.shader_test b/tests/hlsl/register-reservations-numeric.shader_test index 3fb5d9eba..4303bb6c1 100644 --- a/tests/hlsl/register-reservations-numeric.shader_test +++ b/tests/hlsl/register-reservations-numeric.shader_test @@ -544,7 +544,7 @@ float4 main() : sv_target } [test] -todo(msl) draw quad +draw quad if(sm<6) probe (0, 0) rgba(2.0, 2.0, 2.0, 2.0) if(sm>=6) probe (0, 0) rgba(0.5, 0.5, 0.5, 0.5) diff --git a/tests/hlsl/sampler.shader_test b/tests/hlsl/sampler.shader_test index f2829fb0b..7e5db1153 100644 --- a/tests/hlsl/sampler.shader_test +++ b/tests/hlsl/sampler.shader_test @@ -17,7 +17,7 @@ float4 main() : sv_target } [test] -todo(msl) draw quad +draw quad probe (0, 0) rgba (0.25, 0, 0.25, 0) [pixel shader] @@ -30,7 +30,7 @@ float4 main() : sv_target } [test] -todo(msl) draw quad +draw quad probe (0, 0) rgba (0.25, 0, 0.25, 0) [pixel shader fail] @@ -86,16 +86,16 @@ float4 main() : sv_target [test] uniform 0 float4 50.0 50.0 42.0 100 -todo(msl) draw quad +draw quad probe (0, 0) rgba(1.0, 1.0, 0, 1.0) uniform 0 float4 0.075 0.025 -42.0 0.1 -todo(msl) draw quad +draw quad probe (0, 0) rgba(1.75, 0.25, 0, 1.0) uniform 0 float4 0.5 1.5 0.0 2.0 -todo(msl) draw quad +draw quad probe (0, 0) rgba(0.25, 1.75, 0, 1.0) uniform 0 float4 1.0 1.0 0.0 0.0 -todo(msl) draw quad +draw quad probe (0, 0) rgba(2.0, 2.0, 0, 1.0) [sampler 0] @@ -160,7 +160,7 @@ float4 main() : sv_target } [test] -todo(msl) draw quad +draw quad if(sm<4) probe (0, 0) rgba(243, 243, 243, 111) if(sm>=4) probe (0, 0) rgba(234, 234, 234, 111) @@ -182,7 +182,7 @@ float4 main() : sv_target } [test] -todo(msl) draw quad +draw quad probe (0, 0) rgba(655.0, 0, -655.0, 0) 4096 [require] diff --git a/tests/hlsl/static-initializer.shader_test b/tests/hlsl/static-initializer.shader_test index c1cef48cd..62e2929ce 100644 --- a/tests/hlsl/static-initializer.shader_test +++ b/tests/hlsl/static-initializer.shader_test @@ -173,7 +173,7 @@ float4 main() : sv_target } [test] -todo(msl) draw quad +draw quad probe (0, 0) rgba (1, 2, 3, 4) @@ -189,7 +189,7 @@ float4 main() : sv_target } [test] -todo(msl) draw quad +draw quad probe (0, 0) rgba (1, 2, 3, 4) diff --git a/tests/hlsl/texture-ordering.shader_test b/tests/hlsl/texture-ordering.shader_test index ae8dbbcd4..6486bdb17 100644 --- a/tests/hlsl/texture-ordering.shader_test +++ b/tests/hlsl/texture-ordering.shader_test @@ -136,7 +136,7 @@ float4 main() : sv_target } [test] -todo(msl) draw quad +draw quad probe (0, 0) rgba (450, 139, 876, 333) @@ -189,7 +189,7 @@ float4 main() : sv_target } [test] -todo(msl) draw quad +draw quad probe (0, 0) rgba (450, 138, 796, 333) @@ -242,7 +242,7 @@ float4 main() : sv_target } [test] -todo(msl) draw quad +draw quad probe (0, 0) rgba (478, 913, 256, 333) @@ -275,7 +275,7 @@ float4 main() : sv_target } [test] -todo(msl) draw quad +draw quad probe (0, 0) rgba (215, 215, 215, 111) @@ -305,5 +305,5 @@ float4 main() : sv_target } [test] -todo(msl) draw quad +draw quad probe (0, 0) rgba (5, 4, 2, 0) diff --git a/tests/shader_runner_metal.m b/tests/shader_runner_metal.m index fb5d01490..65126f861 100644 --- a/tests/shader_runner_metal.m +++ b/tests/shader_runner_metal.m @@ -121,6 +121,26 @@ static MTLPrimitiveType get_metal_primitive_type(D3D_PRIMITIVE_TOPOLOGY topology } } +static MTLSamplerAddressMode get_metal_address_mode(D3D12_TEXTURE_ADDRESS_MODE mode) +{ + switch (mode) + { + case D3D12_TEXTURE_ADDRESS_MODE_WRAP: + return MTLSamplerAddressModeRepeat; + case D3D12_TEXTURE_ADDRESS_MODE_MIRROR: + return MTLSamplerAddressModeMirrorRepeat; + case D3D12_TEXTURE_ADDRESS_MODE_CLAMP: + return MTLSamplerAddressModeClampToEdge; + case D3D12_TEXTURE_ADDRESS_MODE_BORDER: + return MTLSamplerAddressModeClampToBorderColor; + case D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE: + return MTLSamplerAddressModeMirrorClampToEdge; + + default: + fatal_error("Unhandled address mode %#x.\n", mode); + } +} + static MTLCompareFunction get_metal_compare_function(D3D12_COMPARISON_FUNC func) { switch (func) @@ -410,6 +430,20 @@ static bool compile_shader(struct metal_runner *runner, enum shader_type type, s } } + for (i = 0; i < runner->r.sampler_count; ++i) + { + binding = &bindings[interface_info.binding_count]; + binding->type = VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER; + binding->register_space = 0; + binding->register_index = runner->r.samplers[i].slot; + binding->shader_visibility = VKD3D_SHADER_VISIBILITY_ALL; + binding->flags = 0; + binding->binding.set = 0; + binding->binding.binding = interface_info.binding_count; + binding->binding.count = 1; + ++interface_info.binding_count; + } + interface_info.bindings = bindings; interface_info.next = &runner->signatures[type]; runner->signatures[type].type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_SIGNATURE_INFO; @@ -446,7 +480,7 @@ static id compile_stage(struct metal_runner *runner, enum shader_ty } static bool encode_argument_buffer(struct metal_runner *runner, - id command_encoder) + id command_encoder, id *samplers) { NSMutableArray *argument_descriptors; id device = runner->device; @@ -489,6 +523,15 @@ static bool encode_argument_buffer(struct metal_runner *runner, } } + for (i = 0; i < runner->r.sampler_count; ++i) + { + arg_desc = [MTLArgumentDescriptor argumentDescriptor]; + arg_desc.dataType = MTLDataTypeSampler; + arg_desc.index = [argument_descriptors count]; + arg_desc.access = MTLBindingAccessReadOnly; + [argument_descriptors addObject:arg_desc]; + } + if (![argument_descriptors count]) return true; @@ -536,6 +579,11 @@ static bool encode_argument_buffer(struct metal_runner *runner, } } + for (i = 0; i < runner->r.sampler_count; ++i) + { + [encoder setSamplerState:samplers[i] atIndex:index++]; + } + [argument_buffer didModifyRange:NSMakeRange(0, encoder.encodedLength)]; [command_encoder setVertexBuffer:argument_buffer offset:0 atIndex:0]; @@ -597,6 +645,7 @@ static bool metal_runner_draw(struct shader_runner *r, D3D_PRIMITIVE_TOPOLOGY to unsigned int fb_width, fb_height, vb_idx, i, j; struct metal_runner *runner = metal_runner(r); MTLRenderPipelineDescriptor *pipeline_desc; + id samplers[MAX_SAMPLERS]; MTLVertexBufferLayoutDescriptor *binding; id ds_state = nil; id device = runner->device; @@ -605,9 +654,11 @@ static bool metal_runner_draw(struct shader_runner *r, D3D_PRIMITIVE_TOPOLOGY to id command_buffer; MTLDepthStencilDescriptor *ds_desc; MTLRenderPassDescriptor *pass_desc; + MTLSamplerDescriptor *sampler_desc; MTLVertexDescriptor *vertex_desc; struct metal_resource *resource; id pso; + const struct sampler *sampler; bool ret = false; NSError *err; @@ -635,6 +686,25 @@ static bool metal_runner_draw(struct shader_runner *r, D3D_PRIMITIVE_TOPOLOGY to goto done; } + sampler_desc = [[MTLSamplerDescriptor new] autorelease]; + for (i = 0; i < runner->r.sampler_count; ++i) + { + sampler = &runner->r.samplers[i]; + sampler_desc.sAddressMode = get_metal_address_mode(sampler->u_address); + sampler_desc.tAddressMode = get_metal_address_mode(sampler->v_address); + sampler_desc.rAddressMode = get_metal_address_mode(sampler->w_address); + sampler_desc.magFilter = (sampler->filter & 0x4) + ? MTLSamplerMinMagFilterLinear : MTLSamplerMinMagFilterNearest; + sampler_desc.minFilter = (sampler->filter & 0x1) + ? MTLSamplerMinMagFilterLinear : MTLSamplerMinMagFilterNearest; + sampler_desc.mipFilter = (sampler->filter & 0x10) + ? MTLSamplerMipFilterLinear : MTLSamplerMipFilterNearest; + sampler_desc.compareFunction = sampler->func + ? get_metal_compare_function(sampler->func) : MTLCompareFunctionNever; + sampler_desc.supportArgumentBuffers = true; + samplers[i] = [[device newSamplerStateWithDescriptor:sampler_desc] autorelease]; + } + fb_width = ~0u; fb_height = ~0u; /* [[buffer(0)]] is used for the descriptor argument buffer. */ @@ -705,7 +775,7 @@ static bool metal_runner_draw(struct shader_runner *r, D3D_PRIMITIVE_TOPOLOGY to command_buffer = [runner->queue commandBuffer]; encoder = [command_buffer renderCommandEncoderWithDescriptor:pass_desc]; - if (!encode_argument_buffer(runner, encoder)) + if (!encode_argument_buffer(runner, encoder, samplers)) { [encoder endEncoding]; ret = false;