diff --git a/libs/vkd3d-shader/glsl.c b/libs/vkd3d-shader/glsl.c index 828a94d7..4b54de0a 100644 --- a/libs/vkd3d-shader/glsl.c +++ b/libs/vkd3d-shader/glsl.c @@ -2468,6 +2468,7 @@ int glsl_compile(struct vsir_program *program, uint64_t config_flags, return ret; VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6); + VKD3D_ASSERT(program->has_descriptor_info); vkd3d_glsl_generator_init(&generator, program, compile_info, combined_sampler_info, message_context); diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index 460b4355..3e7acfbe 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -7782,6 +7782,33 @@ static void vsir_validate_label_register(struct validation_context *ctx, reg->idx[0].offset, ctx->program->block_count); } +static void vsir_validate_descriptor_indices(struct validation_context *ctx, + const struct vkd3d_shader_register *reg, enum vkd3d_shader_descriptor_type type, const char *name) +{ + const struct vkd3d_shader_descriptor_info1 *descriptor; + + if (reg->idx[0].rel_addr) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX, + "Non-NULL indirect address for the ID of a register of type \"%s\".", name); + + if (!ctx->program->has_descriptor_info) + return; + + if (!(descriptor = vkd3d_shader_find_descriptor(&ctx->program->descriptors, type, reg->idx[0].offset))) + { + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX, + "No matching descriptor found for register %s%u.", name, reg->idx[0].offset); + return; + } + + if (!reg->idx[1].rel_addr && (reg->idx[1].offset < descriptor->register_index + || reg->idx[1].offset - descriptor->register_index >= descriptor->count)) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX, + "Register index %u doesn't belong to the range [%u, %u] for register %s%u.", + reg->idx[1].offset, descriptor->register_index, + descriptor->register_index + descriptor->count - 1, name, reg->idx[0].offset); +} + static void vsir_validate_constbuffer_register(struct validation_context *ctx, const struct vkd3d_shader_register *reg) { @@ -7855,9 +7882,7 @@ static void vsir_validate_resource_register(struct validation_context *ctx, return; } - if (reg->idx[0].rel_addr) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX, - "Non-NULL relative address for the descriptor index of a RESOURCE register."); + vsir_validate_descriptor_indices(ctx, reg, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, "t"); } static void vsir_validate_uav_register(struct validation_context *ctx, diff --git a/libs/vkd3d-shader/msl.c b/libs/vkd3d-shader/msl.c index 756b4329..a5d952cd 100644 --- a/libs/vkd3d-shader/msl.c +++ b/libs/vkd3d-shader/msl.c @@ -1310,6 +1310,7 @@ int msl_compile(struct vsir_program *program, uint64_t config_flags, return ret; VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6); + VKD3D_ASSERT(program->has_descriptor_info); if ((ret = msl_generator_init(&generator, program, compile_info, message_context)) < 0) return ret; diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index aca20f4f..a146ff9a 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -11361,6 +11361,7 @@ int spirv_compile(struct vsir_program *program, uint64_t config_flags, return ret; VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6); + VKD3D_ASSERT(program->has_descriptor_info); if (!(spirv_compiler = spirv_compiler_create(program, compile_info, message_context, config_flags))) diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index 84f0498f..8ed48038 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -1127,7 +1127,7 @@ static void vkd3d_shader_scan_combined_sampler_declaration( &semantic->resource.range, semantic->resource_type, VKD3D_SHADER_RESOURCE_DATA_FLOAT); } -static const struct vkd3d_shader_descriptor_info1 *find_descriptor( +const struct vkd3d_shader_descriptor_info1 *vkd3d_shader_find_descriptor( const struct vkd3d_shader_scan_descriptor_info1 *info, enum vkd3d_shader_descriptor_type type, unsigned int register_id) { @@ -1181,11 +1181,11 @@ static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_co if (dynamic_resource || dynamic_sampler) return; - if ((d = find_descriptor(context->scan_descriptor_info, + if ((d = vkd3d_shader_find_descriptor(context->scan_descriptor_info, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource->idx[0].offset))) resource_space = d->register_space; - if (sampler && (d = find_descriptor(context->scan_descriptor_info, + if (sampler && (d = vkd3d_shader_find_descriptor(context->scan_descriptor_info, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, sampler->idx[0].offset))) sampler_space = d->register_space; } @@ -1606,6 +1606,9 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh vkd3d_shader_scan_context_init(&context, &program->shader_version, compile_info, add_descriptor_info ? &program->descriptors : NULL, combined_sampler_info, message_context); + if (add_descriptor_info) + program->has_descriptor_info = true; + if (TRACE_ON()) vsir_program_trace(program); diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 7fcee37c..168c40bd 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -1444,6 +1444,9 @@ struct vkd3d_shader_scan_descriptor_info1 unsigned int descriptor_count; }; +const struct vkd3d_shader_descriptor_info1 *vkd3d_shader_find_descriptor( + const struct vkd3d_shader_scan_descriptor_info1 *info, + enum vkd3d_shader_descriptor_type type, unsigned int register_id); void vkd3d_shader_free_scan_descriptor_info1(struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info); struct vsir_program @@ -1456,6 +1459,7 @@ struct vsir_program struct shader_signature patch_constant_signature; struct vkd3d_shader_scan_descriptor_info1 descriptors; + bool has_descriptor_info; unsigned int parameter_count; const struct vkd3d_shader_parameter1 *parameters;