tests/shader_runner_metal: Implement explicit descriptor mapping.

This commit is contained in:
Giovanni Mascellani
2025-11-07 00:02:11 +01:00
committed by Henri Verbeet
parent 653de0c076
commit 7022bb57fc
Notes: Henri Verbeet 2025-11-12 15:30:40 +01:00
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1811
2 changed files with 74 additions and 84 deletions

View File

@@ -87,12 +87,12 @@ probe (0, 0) f32(2.0, 2.0, 2.0, 2.0)
u[2:2], space 0, uav 3 u[2:2], space 0, uav 3
[test] [test]
draw quad todo(msl) draw quad
probe (0, 0) f32(3.0, 3.0, 3.0, 3.0) probe (0, 0) f32(3.0, 3.0, 3.0, 3.0)
[descriptors] [descriptors]
u[2:3], space 0, uav 1 u[2:3], space 0, uav 1
[test] [test]
draw quad todo(msl) draw quad
probe (0, 0) f32(1.0, 1.0, 1.0, 1.0) probe (0, 0) f32(1.0, 1.0, 1.0, 1.0)

View File

@@ -386,8 +386,8 @@ static bool compile_shader(struct metal_runner *runner, enum shader_type type, s
{ {
struct vkd3d_shader_interface_info interface_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO}; struct vkd3d_shader_interface_info interface_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO};
struct vkd3d_shader_compile_info info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO}; struct vkd3d_shader_compile_info info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO};
struct vkd3d_shader_resource_binding bindings[MAX_RESOURCES + MAX_SAMPLERS + 1 /* CBV */]; struct vkd3d_shader_resource_binding bindings[MAX_DESCRIPTORS + MAX_SAMPLERS + 1 /* CBV */];
struct vkd3d_shader_resource_binding *binding, *base_binding = NULL; struct vkd3d_shader_resource_binding *binding;
unsigned int i, binding_idx = 0; unsigned int i, binding_idx = 0;
char *messages; char *messages;
int ret; int ret;
@@ -424,53 +424,27 @@ static bool compile_shader(struct metal_runner *runner, enum shader_type type, s
binding->binding.set = 0; binding->binding.set = 0;
binding->binding.binding = binding_idx; binding->binding.binding = binding_idx;
binding->binding.count = 1; binding->binding.count = 1;
++interface_info.binding_count; ++interface_info.binding_count;
++binding_idx; ++binding_idx;
} }
for (i = 0; i < runner->r.resource_count; ++i) for (i = 0; i < runner->r.descriptor_count; ++i)
{ {
const struct metal_resource *resource = metal_resource(runner->r.resources[i]); const struct descriptor_mapping *descriptor = &runner->r.descriptors[i];
switch (resource->r.desc.type) binding = &bindings[interface_info.binding_count];
{ binding->type = descriptor->type;
case RESOURCE_TYPE_TEXTURE: binding->register_index = descriptor->register_idx;
case RESOURCE_TYPE_UAV: binding->register_space = descriptor->register_space;
binding = &bindings[interface_info.binding_count]; binding->shader_visibility = VKD3D_SHADER_VISIBILITY_ALL;
if (resource->r.desc.type == RESOURCE_TYPE_UAV) binding->flags = VKD3D_SHADER_BINDING_FLAG_BUFFER | VKD3D_SHADER_BINDING_FLAG_IMAGE;
binding->type = VKD3D_SHADER_DESCRIPTOR_TYPE_UAV; binding->binding.set = 0;
else binding->binding.binding = binding_idx;
binding->type = VKD3D_SHADER_DESCRIPTOR_TYPE_SRV; binding->binding.count = descriptor->count;
binding->register_space = 0;
binding->register_index = resource->r.desc.slot;
binding->shader_visibility = VKD3D_SHADER_VISIBILITY_ALL;
if (resource->r.desc.dimension == RESOURCE_DIMENSION_BUFFER)
binding->flags = VKD3D_SHADER_BINDING_FLAG_BUFFER;
else
binding->flags = VKD3D_SHADER_BINDING_FLAG_IMAGE;
binding->binding.set = 0;
binding->binding.binding = binding_idx;
binding->binding.count = 1;
if (base_binding && base_binding->type == binding->type && base_binding->flags == binding->flags ++interface_info.binding_count;
&& base_binding->register_index + base_binding->binding.count == resource->r.desc.slot) binding_idx += descriptor->count;
{
++base_binding->binding.count;
++binding_idx;
break;
}
base_binding = binding;
++interface_info.binding_count;
++binding_idx;
break;
case RESOURCE_TYPE_RENDER_TARGET:
case RESOURCE_TYPE_DEPTH_STENCIL:
case RESOURCE_TYPE_VERTEX_BUFFER:
break;
}
} }
for (i = 0; i < runner->r.sampler_count; ++i) for (i = 0; i < runner->r.sampler_count; ++i)
@@ -484,6 +458,7 @@ static bool compile_shader(struct metal_runner *runner, enum shader_type type, s
binding->binding.set = 0; binding->binding.set = 0;
binding->binding.binding = binding_idx; binding->binding.binding = binding_idx;
binding->binding.count = 1; binding->binding.count = 1;
++interface_info.binding_count; ++interface_info.binding_count;
++binding_idx; ++binding_idx;
} }
@@ -527,6 +502,34 @@ static id<MTLFunction> compile_stage(struct metal_runner *runner, enum shader_ty
return [function autorelease]; return [function autorelease];
} }
static struct metal_resource *find_resource(struct metal_runner *runner,
const struct descriptor_mapping *descriptor, unsigned int offset)
{
enum resource_type resource_type;
struct resource *resource;
switch (descriptor->type)
{
case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV:
resource_type = RESOURCE_TYPE_TEXTURE;
break;
case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV:
resource_type = RESOURCE_TYPE_UAV;
break;
default:
fatal_error("Unhandled descriptor type %#x.\n", descriptor->type);
}
resource = shader_runner_get_resource(&runner->r, resource_type, descriptor->target_idx + offset);
if (!resource)
return NULL;
return metal_resource(resource);
}
static bool encode_argument_buffer(struct metal_runner *runner, id<MTLCommandEncoder> command_encoder, static bool encode_argument_buffer(struct metal_runner *runner, id<MTLCommandEncoder> command_encoder,
void (*use_resource)(id<MTLCommandEncoder> encoder, id<MTLResource> resource, MTLResourceUsage usage), void (*use_resource)(id<MTLCommandEncoder> encoder, id<MTLResource> resource, MTLResourceUsage usage),
const id<MTLSamplerState> *samplers, id<MTLBuffer> *argument_buffer) const id<MTLSamplerState> *samplers, id<MTLBuffer> *argument_buffer)
@@ -535,7 +538,7 @@ static bool encode_argument_buffer(struct metal_runner *runner, id<MTLCommandEnc
id<MTLDevice> device = runner->device; id<MTLDevice> device = runner->device;
MTLArgumentDescriptor *arg_desc; MTLArgumentDescriptor *arg_desc;
id<MTLArgumentEncoder> encoder; id<MTLArgumentEncoder> encoder;
unsigned int i, index = 0; unsigned int i, j, index = 0;
argument_descriptors = [[[NSMutableArray alloc] init] autorelease]; argument_descriptors = [[[NSMutableArray alloc] init] autorelease];
@@ -548,34 +551,21 @@ static bool encode_argument_buffer(struct metal_runner *runner, id<MTLCommandEnc
[argument_descriptors addObject:arg_desc]; [argument_descriptors addObject:arg_desc];
} }
for (i = 0; i < runner->r.resource_count; ++i) for (i = 0; i < runner->r.descriptor_count; ++i)
{ {
struct metal_resource *resource = metal_resource(runner->r.resources[i]); const struct descriptor_mapping *descriptor = &runner->r.descriptors[i];
switch (resource->r.desc.type) for (j = 0; j < descriptor->count; ++j)
{ {
case RESOURCE_TYPE_TEXTURE: const struct metal_resource *resource = find_resource(runner, descriptor, j);
arg_desc = [MTLArgumentDescriptor argumentDescriptor];
arg_desc.dataType = MTLDataTypeTexture;
arg_desc.index = [argument_descriptors count];
arg_desc.access = MTLBindingAccessReadOnly;
arg_desc.textureType = [resource->texture textureType];
[argument_descriptors addObject:arg_desc];
break;
case RESOURCE_TYPE_UAV: arg_desc = [MTLArgumentDescriptor argumentDescriptor];
arg_desc = [MTLArgumentDescriptor argumentDescriptor]; arg_desc.dataType = MTLDataTypeTexture;
arg_desc.dataType = MTLDataTypeTexture; arg_desc.index = [argument_descriptors count];
arg_desc.index = [argument_descriptors count]; arg_desc.access = descriptor->type == VKD3D_SHADER_DESCRIPTOR_TYPE_SRV ?
arg_desc.access = MTLBindingAccessReadWrite; MTLBindingAccessReadOnly : MTLBindingAccessReadWrite;
arg_desc.textureType = [resource->texture textureType]; arg_desc.textureType = resource ? [resource->texture textureType] : MTLTextureType2D;
[argument_descriptors addObject:arg_desc]; [argument_descriptors addObject:arg_desc];
break;
case RESOURCE_TYPE_RENDER_TARGET:
case RESOURCE_TYPE_DEPTH_STENCIL:
case RESOURCE_TYPE_VERTEX_BUFFER:
break;
} }
} }
@@ -610,26 +600,25 @@ static bool encode_argument_buffer(struct metal_runner *runner, id<MTLCommandEnc
use_resource(command_encoder, cb, MTLResourceUsageRead); use_resource(command_encoder, cb, MTLResourceUsageRead);
} }
for (i = 0; i < runner->r.resource_count; ++i) for (i = 0; i < runner->r.descriptor_count; ++i)
{ {
struct metal_resource *resource = metal_resource(runner->r.resources[i]); const struct descriptor_mapping *descriptor = &runner->r.descriptors[i];
MTLResourceUsage usage;
switch (resource->r.desc.type) usage = descriptor->type == VKD3D_SHADER_DESCRIPTOR_TYPE_SRV ?
MTLResourceUsageRead : MTLResourceUsageRead | MTLResourceUsageWrite;
for (j = 0; j < descriptor->count; ++j)
{ {
case RESOURCE_TYPE_TEXTURE: const struct metal_resource *resource = find_resource(runner, descriptor, j);
[encoder setTexture:resource->texture atIndex:index++];
use_resource(command_encoder, resource->texture, MTLResourceUsageRead);
break;
case RESOURCE_TYPE_UAV: if (resource)
[encoder setTexture:resource->texture atIndex:index++]; {
use_resource(command_encoder, resource->texture, MTLResourceUsageRead | MTLResourceUsageWrite); [encoder setTexture:resource->texture atIndex:index];
break; use_resource(command_encoder, resource->texture, usage);
}
case RESOURCE_TYPE_RENDER_TARGET: ++index;
case RESOURCE_TYPE_DEPTH_STENCIL:
case RESOURCE_TYPE_VERTEX_BUFFER:
break;
} }
} }
@@ -1190,6 +1179,7 @@ static bool metal_runner_init(struct metal_runner *runner)
} }
runner->caps.runner = "Metal"; runner->caps.runner = "Metal";
runner->caps.shader_caps[SHADER_CAP_DESCRIPTORS] = true;
runner->caps.tags[SHADER_RUNNER_TAG_MSL].present = true; runner->caps.tags[SHADER_RUNNER_TAG_MSL].present = true;