mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-12-15 08:03:30 -08:00
vkd3d-shader: Introduce an interface to specify sm1 shadow samplers.
This commit is contained in:
committed by
Henri Verbeet
parent
539a5be370
commit
0bb8272f26
Notes:
Henri Verbeet
2025-10-13 19:31:51 +02:00
Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1769
@@ -2350,6 +2350,26 @@ struct vkd3d_shader_d3dbc_source_info
|
|||||||
* This field is ignored for shader models 2 and higher.
|
* This field is ignored for shader models 2 and higher.
|
||||||
*/
|
*/
|
||||||
enum vkd3d_shader_resource_type texture_dimensions[6];
|
enum vkd3d_shader_resource_type texture_dimensions[6];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A mask indicating which samplers should be shadow (i.e. comparison-mode)
|
||||||
|
* samplers. When legacy Direct3D shaders are used with the Direct3D 8 and 9
|
||||||
|
* APIs, this is implied by the format of the sampled resource; e.g. a
|
||||||
|
* D3DFMT_D24S8 texture implies shadow sampling, while a D3DFMT_A8R8G8B8
|
||||||
|
* or D3DFMT_INTZ texture does not.
|
||||||
|
* This information is necessary when converting to other formats
|
||||||
|
* (e.g. SPIR-V, GLSL) which specify this in the shader.
|
||||||
|
*
|
||||||
|
* For example, if bit 1 is set (so the value is 0x2), this indicates that
|
||||||
|
* the sampler at bind point 1 (and no others) should be a shadow sampler.
|
||||||
|
*
|
||||||
|
* Bits in this mask corresponding to textures not used by the shader will
|
||||||
|
* be ignored.
|
||||||
|
*
|
||||||
|
* If this structure is not specified, no samplers will be considered to
|
||||||
|
* be shadow samplers.
|
||||||
|
*/
|
||||||
|
uint32_t shadow_samplers;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -946,17 +946,21 @@ static void d3dbc_add_combined_sampler_descriptor(struct vkd3d_shader_sm1_parser
|
|||||||
unsigned int sampler_idx, enum vkd3d_shader_resource_type resource_type)
|
unsigned int sampler_idx, enum vkd3d_shader_resource_type resource_type)
|
||||||
{
|
{
|
||||||
struct vkd3d_shader_register_range range = {.first = sampler_idx, .last = sampler_idx};
|
struct vkd3d_shader_register_range range = {.first = sampler_idx, .last = sampler_idx};
|
||||||
|
const struct vkd3d_shader_d3dbc_source_info *source_info = d3dbc->d3dbc_source_info;
|
||||||
struct vsir_program *program = d3dbc->program;
|
struct vsir_program *program = d3dbc->program;
|
||||||
|
struct vkd3d_shader_descriptor_info1 *d;
|
||||||
|
|
||||||
if (!vsir_program_add_descriptor(program, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV,
|
if (!vsir_program_add_descriptor(program, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV,
|
||||||
sampler_idx, &range, resource_type, VSIR_DATA_F32))
|
sampler_idx, &range, resource_type, VSIR_DATA_F32))
|
||||||
vkd3d_shader_parser_error(&d3dbc->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY,
|
vkd3d_shader_parser_error(&d3dbc->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY,
|
||||||
"Failed to create SRV descriptor for combined sampler %u.", sampler_idx);
|
"Failed to create SRV descriptor for combined sampler %u.", sampler_idx);
|
||||||
|
|
||||||
if (!vsir_program_add_descriptor(program, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER,
|
if (!(d = vsir_program_add_descriptor(program, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER,
|
||||||
sampler_idx, &range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED))
|
sampler_idx, &range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED)))
|
||||||
vkd3d_shader_parser_error(&d3dbc->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY,
|
vkd3d_shader_parser_error(&d3dbc->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY,
|
||||||
"Failed to create sampler descriptor for combined sampler %u.", sampler_idx);
|
"Failed to create sampler descriptor for combined sampler %u.", sampler_idx);
|
||||||
|
else if (source_info && source_info->shadow_samplers & (1u << sampler_idx))
|
||||||
|
d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read a parameter token from the input stream, and possibly a relative
|
/* Read a parameter token from the input stream, and possibly a relative
|
||||||
|
|||||||
@@ -1680,6 +1680,7 @@ static enum vkd3d_result vsir_program_lower_texcrd(struct vsir_program *program,
|
|||||||
static enum vkd3d_result vsir_program_lower_texld_sm1(struct vsir_program *program,
|
static enum vkd3d_result vsir_program_lower_texld_sm1(struct vsir_program *program,
|
||||||
struct vkd3d_shader_instruction *ins, struct vkd3d_shader_message_context *message_context)
|
struct vkd3d_shader_instruction *ins, struct vkd3d_shader_message_context *message_context)
|
||||||
{
|
{
|
||||||
|
const struct vkd3d_shader_descriptor_info1 *sampler;
|
||||||
unsigned int idx = ins->src[0].reg.idx[0].offset;
|
unsigned int idx = ins->src[0].reg.idx[0].offset;
|
||||||
struct vkd3d_shader_src_param *srcs;
|
struct vkd3d_shader_src_param *srcs;
|
||||||
|
|
||||||
@@ -1692,7 +1693,7 @@ static enum vkd3d_result vsir_program_lower_texld_sm1(struct vsir_program *progr
|
|||||||
return VKD3D_ERROR_NOT_IMPLEMENTED;
|
return VKD3D_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(srcs = vsir_program_get_src_params(program, 3)))
|
if (!(srcs = vsir_program_get_src_params(program, 4)))
|
||||||
return VKD3D_ERROR_OUT_OF_MEMORY;
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
/* Note we run before I/O normalization. */
|
/* Note we run before I/O normalization. */
|
||||||
@@ -1700,9 +1701,26 @@ static enum vkd3d_result vsir_program_lower_texld_sm1(struct vsir_program *progr
|
|||||||
vsir_src_param_init_resource(&srcs[1], idx, idx);
|
vsir_src_param_init_resource(&srcs[1], idx, idx);
|
||||||
vsir_src_param_init_sampler(&srcs[2], idx, idx);
|
vsir_src_param_init_sampler(&srcs[2], idx, idx);
|
||||||
|
|
||||||
ins->opcode = VSIR_OP_SAMPLE;
|
sampler = vkd3d_shader_find_descriptor(&program->descriptors, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, idx);
|
||||||
ins->src = srcs;
|
if (sampler->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE)
|
||||||
ins->src_count = 3;
|
{
|
||||||
|
enum vkd3d_shader_swizzle_component ref = vsir_swizzle_get_component(srcs[0].swizzle, 2);
|
||||||
|
|
||||||
|
ins->opcode = VSIR_OP_SAMPLE_C;
|
||||||
|
ins->src = srcs;
|
||||||
|
ins->src_count = 4;
|
||||||
|
|
||||||
|
srcs[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
|
||||||
|
|
||||||
|
srcs[3] = srcs[0];
|
||||||
|
srcs[3].swizzle = vkd3d_shader_create_swizzle(ref, ref, ref, ref);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ins->opcode = VSIR_OP_SAMPLE;
|
||||||
|
ins->src = srcs;
|
||||||
|
ins->src_count = 3;
|
||||||
|
}
|
||||||
|
|
||||||
return VKD3D_OK;
|
return VKD3D_OK;
|
||||||
}
|
}
|
||||||
@@ -1762,6 +1780,7 @@ static enum vkd3d_result vsir_program_lower_texldp(struct vsir_program *program,
|
|||||||
static enum vkd3d_result vsir_program_lower_texld(struct vsir_program *program,
|
static enum vkd3d_result vsir_program_lower_texld(struct vsir_program *program,
|
||||||
struct vkd3d_shader_instruction *tex, struct vkd3d_shader_message_context *message_context)
|
struct vkd3d_shader_instruction *tex, struct vkd3d_shader_message_context *message_context)
|
||||||
{
|
{
|
||||||
|
const struct vkd3d_shader_descriptor_info1 *sampler;
|
||||||
unsigned int idx = tex->src[1].reg.idx[0].offset;
|
unsigned int idx = tex->src[1].reg.idx[0].offset;
|
||||||
struct vkd3d_shader_src_param *srcs;
|
struct vkd3d_shader_src_param *srcs;
|
||||||
|
|
||||||
@@ -1775,7 +1794,21 @@ static enum vkd3d_result vsir_program_lower_texld(struct vsir_program *program,
|
|||||||
vsir_src_param_init_resource(&srcs[1], idx, idx);
|
vsir_src_param_init_resource(&srcs[1], idx, idx);
|
||||||
vsir_src_param_init_sampler(&srcs[2], idx, idx);
|
vsir_src_param_init_sampler(&srcs[2], idx, idx);
|
||||||
|
|
||||||
if (!tex->flags)
|
sampler = vkd3d_shader_find_descriptor(&program->descriptors, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, idx);
|
||||||
|
if (sampler->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE)
|
||||||
|
{
|
||||||
|
enum vkd3d_shader_swizzle_component ref = vsir_swizzle_get_component(srcs[0].swizzle, 2);
|
||||||
|
|
||||||
|
tex->opcode = VSIR_OP_SAMPLE_C;
|
||||||
|
tex->src = srcs;
|
||||||
|
tex->src_count = 4;
|
||||||
|
|
||||||
|
srcs[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
|
||||||
|
|
||||||
|
srcs[3] = srcs[0];
|
||||||
|
srcs[3].swizzle = vkd3d_shader_create_swizzle(ref, ref, ref, ref);
|
||||||
|
}
|
||||||
|
else if (!tex->flags)
|
||||||
{
|
{
|
||||||
tex->opcode = VSIR_OP_SAMPLE;
|
tex->opcode = VSIR_OP_SAMPLE;
|
||||||
tex->src = srcs;
|
tex->src = srcs;
|
||||||
@@ -1857,6 +1890,7 @@ static enum vkd3d_result vsir_program_lower_texldl(struct vsir_program *program,
|
|||||||
|
|
||||||
static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, struct vkd3d_shader_instruction *ins)
|
static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, struct vkd3d_shader_instruction *ins)
|
||||||
{
|
{
|
||||||
|
const struct vkd3d_shader_descriptor_info1 *sampler;
|
||||||
unsigned int idx = ins->dst[0].reg.idx[0].offset;
|
unsigned int idx = ins->dst[0].reg.idx[0].offset;
|
||||||
struct vkd3d_shader_src_param *srcs;
|
struct vkd3d_shader_src_param *srcs;
|
||||||
|
|
||||||
@@ -1866,7 +1900,7 @@ static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, st
|
|||||||
/* We run before I/O normalization. */
|
/* We run before I/O normalization. */
|
||||||
VKD3D_ASSERT(program->normalisation_level < VSIR_NORMALISED_SM6);
|
VKD3D_ASSERT(program->normalisation_level < VSIR_NORMALISED_SM6);
|
||||||
|
|
||||||
if (!(srcs = vsir_program_get_src_params(program, 3)))
|
if (!(srcs = vsir_program_get_src_params(program, 4)))
|
||||||
return VKD3D_ERROR_OUT_OF_MEMORY;
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
vsir_src_param_init(&srcs[0], VKD3DSPR_TEXTURE, VSIR_DATA_F32, 1);
|
vsir_src_param_init(&srcs[0], VKD3DSPR_TEXTURE, VSIR_DATA_F32, 1);
|
||||||
@@ -1877,9 +1911,24 @@ static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, st
|
|||||||
vsir_src_param_init_resource(&srcs[1], idx, idx);
|
vsir_src_param_init_resource(&srcs[1], idx, idx);
|
||||||
vsir_src_param_init_sampler(&srcs[2], idx, idx);
|
vsir_src_param_init_sampler(&srcs[2], idx, idx);
|
||||||
|
|
||||||
ins->opcode = VSIR_OP_SAMPLE;
|
sampler = vkd3d_shader_find_descriptor(&program->descriptors, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, idx);
|
||||||
ins->src = srcs;
|
if (sampler->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE)
|
||||||
ins->src_count = 3;
|
{
|
||||||
|
ins->opcode = VSIR_OP_SAMPLE_C;
|
||||||
|
ins->src = srcs;
|
||||||
|
ins->src_count = 4;
|
||||||
|
|
||||||
|
srcs[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
|
||||||
|
|
||||||
|
srcs[3] = srcs[0];
|
||||||
|
srcs[3].swizzle = VKD3D_SHADER_SWIZZLE(Z, Z, Z, Z);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ins->opcode = VSIR_OP_SAMPLE;
|
||||||
|
ins->src = srcs;
|
||||||
|
ins->src_count = 3;
|
||||||
|
}
|
||||||
|
|
||||||
return VKD3D_OK;
|
return VKD3D_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user