mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08:00
vkd3d-shader/hlsl: Lower separated samplers for SM1.
The combined sampler is created as a SAMPLER instead of a TEXTURE because that fits all our current infrastructure. The only problem is that in the CTAB it must appear as a Texture, so the new field hlsl_type.is_combined_sampler is added. Co-authored-by: Elizabeth Figura <zfigura@codeweavers.com>
This commit is contained in:
parent
58d318719c
commit
3a6bf3be24
Notes:
Henri Verbeet
2024-12-10 15:58:19 +01:00
Approved-by: Elizabeth Figura (@zfigura) Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1303
@ -1570,9 +1570,14 @@ D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type)
|
||||
vkd3d_unreachable();
|
||||
}
|
||||
|
||||
D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type)
|
||||
D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type, bool is_combined_sampler)
|
||||
{
|
||||
switch (type->class)
|
||||
enum hlsl_type_class class = type->class;
|
||||
|
||||
if (is_combined_sampler)
|
||||
class = HLSL_CLASS_TEXTURE;
|
||||
|
||||
switch (class)
|
||||
{
|
||||
case HLSL_CLASS_SCALAR:
|
||||
case HLSL_CLASS_VECTOR:
|
||||
@ -1639,7 +1644,7 @@ D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type)
|
||||
break;
|
||||
|
||||
case HLSL_CLASS_ARRAY:
|
||||
return hlsl_sm1_base_type(type->e.array.type);
|
||||
return hlsl_sm1_base_type(type->e.array.type, is_combined_sampler);
|
||||
|
||||
case HLSL_CLASS_STRUCT:
|
||||
return D3DXPT_VOID;
|
||||
@ -1677,7 +1682,8 @@ D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type)
|
||||
vkd3d_unreachable();
|
||||
}
|
||||
|
||||
static void write_sm1_type(struct vkd3d_bytecode_buffer *buffer, struct hlsl_type *type, unsigned int ctab_start)
|
||||
static void write_sm1_type(struct vkd3d_bytecode_buffer *buffer,
|
||||
struct hlsl_type *type, bool is_combined_sampler, unsigned int ctab_start)
|
||||
{
|
||||
const struct hlsl_type *array_type = hlsl_get_multiarray_element_type(type);
|
||||
unsigned int array_size = hlsl_get_multiarray_size(type);
|
||||
@ -1697,7 +1703,7 @@ static void write_sm1_type(struct vkd3d_bytecode_buffer *buffer, struct hlsl_typ
|
||||
struct hlsl_struct_field *field = &array_type->e.record.fields[i];
|
||||
|
||||
field->name_bytecode_offset = put_string(buffer, field->name);
|
||||
write_sm1_type(buffer, field->type, ctab_start);
|
||||
write_sm1_type(buffer, field->type, false, ctab_start);
|
||||
}
|
||||
|
||||
fields_offset = bytecode_align(buffer) - ctab_start;
|
||||
@ -1711,7 +1717,8 @@ static void write_sm1_type(struct vkd3d_bytecode_buffer *buffer, struct hlsl_typ
|
||||
}
|
||||
}
|
||||
|
||||
type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(hlsl_sm1_class(type), hlsl_sm1_base_type(array_type)));
|
||||
type->bytecode_offset = put_u32(buffer,
|
||||
vkd3d_make_u32(hlsl_sm1_class(type), hlsl_sm1_base_type(array_type, is_combined_sampler)));
|
||||
put_u32(buffer, vkd3d_make_u32(type->dimy, type->dimx));
|
||||
put_u32(buffer, vkd3d_make_u32(array_size, field_count));
|
||||
put_u32(buffer, fields_offset);
|
||||
@ -1836,7 +1843,7 @@ void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buff
|
||||
name_offset = put_string(buffer, var->name);
|
||||
set_u32(buffer, var_offset, name_offset - ctab_start);
|
||||
|
||||
write_sm1_type(buffer, var->data_type, ctab_start);
|
||||
write_sm1_type(buffer, var->data_type, var->is_combined_sampler, ctab_start);
|
||||
set_u32(buffer, var_offset + 3 * sizeof(uint32_t), var->data_type->bytecode_offset - ctab_start);
|
||||
|
||||
if (var->default_values)
|
||||
|
@ -1021,8 +1021,8 @@ static uint32_t get_fx_2_type_class(const struct hlsl_type *type)
|
||||
return hlsl_sm1_class(type);
|
||||
}
|
||||
|
||||
static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *name, const struct hlsl_semantic *semantic,
|
||||
struct fx_write_context *fx)
|
||||
static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *name,
|
||||
const struct hlsl_semantic *semantic, bool is_combined_sampler, struct fx_write_context *fx)
|
||||
{
|
||||
struct vkd3d_bytecode_buffer *buffer = &fx->unstructured;
|
||||
uint32_t semantic_offset, offset, elements_count = 0, name_offset;
|
||||
@ -1038,7 +1038,7 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n
|
||||
name_offset = write_string(name, fx);
|
||||
semantic_offset = semantic->raw_name ? write_string(semantic->raw_name, fx) : 0;
|
||||
|
||||
offset = put_u32(buffer, hlsl_sm1_base_type(type));
|
||||
offset = put_u32(buffer, hlsl_sm1_base_type(type, is_combined_sampler));
|
||||
put_u32(buffer, get_fx_2_type_class(type));
|
||||
put_u32(buffer, name_offset);
|
||||
put_u32(buffer, semantic_offset);
|
||||
@ -1074,7 +1074,7 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n
|
||||
|
||||
/* Validated in check_invalid_object_fields(). */
|
||||
VKD3D_ASSERT(hlsl_is_numeric_type(field->type));
|
||||
write_fx_2_parameter(field->type, field->name, &field->semantic, fx);
|
||||
write_fx_2_parameter(field->type, field->name, &field->semantic, false, fx);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1335,7 +1335,7 @@ static void write_fx_2_parameters(struct fx_write_context *fx)
|
||||
if (!is_type_supported_fx_2(ctx, var->data_type, &var->loc))
|
||||
continue;
|
||||
|
||||
desc_offset = write_fx_2_parameter(var->data_type, var->name, &var->semantic, fx);
|
||||
desc_offset = write_fx_2_parameter(var->data_type, var->name, &var->semantic, var->is_combined_sampler, fx);
|
||||
value_offset = write_fx_2_initial_value(var, fx);
|
||||
|
||||
flags = 0;
|
||||
@ -1358,7 +1358,7 @@ static void write_fx_2_annotation(struct hlsl_ir_var *var, struct fx_write_conte
|
||||
struct vkd3d_bytecode_buffer *buffer = &fx->structured;
|
||||
uint32_t desc_offset, value_offset;
|
||||
|
||||
desc_offset = write_fx_2_parameter(var->data_type, var->name, &var->semantic, fx);
|
||||
desc_offset = write_fx_2_parameter(var->data_type, var->name, &var->semantic, var->is_combined_sampler, fx);
|
||||
value_offset = write_fx_2_initial_value(var, fx);
|
||||
|
||||
put_u32(buffer, desc_offset);
|
||||
|
@ -535,6 +535,10 @@ struct hlsl_ir_var
|
||||
* element of a struct, and thus needs to be aligned when packed in the signature. */
|
||||
bool force_align;
|
||||
|
||||
/* Whether this is a sampler that was created from the combination of a
|
||||
* sampler and a texture for SM<4 backwards compatibility. */
|
||||
bool is_combined_sampler;
|
||||
|
||||
uint32_t is_input_semantic : 1;
|
||||
uint32_t is_output_semantic : 1;
|
||||
uint32_t is_uniform : 1;
|
||||
@ -1643,7 +1647,7 @@ bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx,
|
||||
struct hlsl_block *block, void *context);
|
||||
|
||||
D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type);
|
||||
D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type);
|
||||
D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type, bool is_combined_sampler);
|
||||
|
||||
void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer);
|
||||
int d3dbc_compile(struct vsir_program *program, uint64_t config_flags,
|
||||
|
@ -2790,6 +2790,87 @@ static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_n
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Lower samples from separate texture and sampler variables to samples from
|
||||
* synthetized combined samplers. That is, translate SM4-style samples in the
|
||||
* source to SM1-style samples in the bytecode. */
|
||||
static bool lower_separate_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
|
||||
{
|
||||
struct hlsl_ir_var *var, *resource, *sampler;
|
||||
struct hlsl_ir_resource_load *load;
|
||||
struct vkd3d_string_buffer *name;
|
||||
struct hlsl_type *sampler_type;
|
||||
unsigned int sampler_dim;
|
||||
|
||||
if (instr->type != HLSL_IR_RESOURCE_LOAD)
|
||||
return false;
|
||||
load = hlsl_ir_resource_load(instr);
|
||||
|
||||
if (load->load_type != HLSL_RESOURCE_SAMPLE
|
||||
&& load->load_type != HLSL_RESOURCE_SAMPLE_LOD
|
||||
&& load->load_type != HLSL_RESOURCE_SAMPLE_LOD_BIAS)
|
||||
return false;
|
||||
|
||||
if (!load->sampler.var)
|
||||
return false;
|
||||
resource = load->resource.var;
|
||||
sampler = load->sampler.var;
|
||||
|
||||
VKD3D_ASSERT(hlsl_type_is_resource(resource->data_type));
|
||||
VKD3D_ASSERT(hlsl_type_is_resource(sampler->data_type));
|
||||
if (sampler->data_type->class == HLSL_CLASS_ARRAY)
|
||||
{
|
||||
/* Only supported by d3dcompiler if the sampler is the first component
|
||||
* of the sampler array. */
|
||||
hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NOT_IMPLEMENTED,
|
||||
"Lower separated samples with sampler arrays.");
|
||||
return false;
|
||||
}
|
||||
if (resource->data_type->class == HLSL_CLASS_ARRAY)
|
||||
{
|
||||
hlsl_fixme(ctx, &instr->loc, "Lower separated samples with resource arrays.");
|
||||
return false;
|
||||
}
|
||||
if (!resource->is_uniform)
|
||||
return false;
|
||||
if(!sampler->is_uniform)
|
||||
return false;
|
||||
|
||||
if (!(name = hlsl_get_string_buffer(ctx)))
|
||||
return false;
|
||||
vkd3d_string_buffer_printf(name, "%s+%s", sampler->name, resource->name);
|
||||
sampler_dim = hlsl_get_multiarray_element_type(resource->data_type)->sampler_dim;
|
||||
|
||||
TRACE("Lowering to combined sampler %s.\n", debugstr_a(name->buffer));
|
||||
|
||||
if (!(var = hlsl_get_var(ctx->globals, name->buffer)))
|
||||
{
|
||||
sampler_type = ctx->builtin_types.sampler[sampler_dim];
|
||||
|
||||
if (!(var = hlsl_new_synthetic_var_named(ctx, name->buffer, sampler_type, &instr->loc, false)))
|
||||
{
|
||||
hlsl_release_string_buffer(ctx, name);
|
||||
return false;
|
||||
}
|
||||
var->storage_modifiers |= HLSL_STORAGE_UNIFORM;
|
||||
var->is_combined_sampler = true;
|
||||
var->is_uniform = 1;
|
||||
|
||||
list_remove(&var->scope_entry);
|
||||
list_add_after(&sampler->scope_entry, &var->scope_entry);
|
||||
|
||||
list_add_after(&sampler->extern_entry, &var->extern_entry);
|
||||
}
|
||||
hlsl_release_string_buffer(ctx, name);
|
||||
|
||||
/* Only change the deref's var, keep the path. */
|
||||
load->resource.var = var;
|
||||
hlsl_cleanup_deref(&load->sampler);
|
||||
load->sampler.var = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Lower combined samples and sampler variables to synthesized separated textures and samplers.
|
||||
* That is, translate SM1-style samples in the source to SM4-style samples in the bytecode. */
|
||||
static bool lower_combined_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
|
||||
@ -2901,6 +2982,27 @@ static void insert_ensuring_decreasing_bind_count(struct list *list, struct hlsl
|
||||
list_add_tail(list, &to_add->extern_entry);
|
||||
}
|
||||
|
||||
static bool sort_synthetic_combined_samplers_first(struct hlsl_ctx *ctx)
|
||||
{
|
||||
struct list separated_resources;
|
||||
struct hlsl_ir_var *var, *next;
|
||||
|
||||
list_init(&separated_resources);
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(var, next, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
|
||||
{
|
||||
if (var->is_combined_sampler)
|
||||
{
|
||||
list_remove(&var->extern_entry);
|
||||
insert_ensuring_decreasing_bind_count(&separated_resources, var, HLSL_REGSET_SAMPLERS);
|
||||
}
|
||||
}
|
||||
|
||||
list_move_head(&ctx->extern_vars, &separated_resources);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool sort_synthetic_separated_samplers_first(struct hlsl_ctx *ctx)
|
||||
{
|
||||
struct list separated_resources;
|
||||
@ -10260,9 +10362,13 @@ static void process_entry_function(struct hlsl_ctx *ctx,
|
||||
lower_ir(ctx, lower_casts_to_bool, body);
|
||||
lower_ir(ctx, lower_int_dot, body);
|
||||
|
||||
if (hlsl_version_lt(ctx, 4, 0))
|
||||
hlsl_transform_ir(ctx, lower_separate_samples, body, NULL);
|
||||
|
||||
hlsl_transform_ir(ctx, validate_dereferences, body, NULL);
|
||||
hlsl_transform_ir(ctx, track_object_components_sampler_dim, body, NULL);
|
||||
if (profile->major_version >= 4)
|
||||
|
||||
if (hlsl_version_ge(ctx, 4, 0))
|
||||
hlsl_transform_ir(ctx, lower_combined_samples, body, NULL);
|
||||
|
||||
do
|
||||
@ -10270,7 +10376,10 @@ static void process_entry_function(struct hlsl_ctx *ctx,
|
||||
while (hlsl_transform_ir(ctx, dce, body, NULL));
|
||||
|
||||
hlsl_transform_ir(ctx, track_components_usage, body, NULL);
|
||||
sort_synthetic_separated_samplers_first(ctx);
|
||||
if (hlsl_version_lt(ctx, 4, 0))
|
||||
sort_synthetic_combined_samplers_first(ctx);
|
||||
else
|
||||
sort_synthetic_separated_samplers_first(ctx);
|
||||
|
||||
if (profile->major_version < 4)
|
||||
{
|
||||
|
@ -95,8 +95,8 @@ float4 main() : sv_target
|
||||
|
||||
[test]
|
||||
todo(msl) draw quad
|
||||
if(sm<4) todo probe (0, 0) rgba (1, 1, 1, 11)
|
||||
if(sm>=4) probe (0, 0) rgba (10, 10, 10, 11)
|
||||
if(sm<4) probe (0, 0) rgba(1, 1, 1, 11)
|
||||
if(sm>=4) probe (0, 0) rgba(10, 10, 10, 11)
|
||||
|
||||
|
||||
[pixel shader]
|
||||
@ -110,8 +110,8 @@ float4 main() : sv_target
|
||||
|
||||
[test]
|
||||
todo(msl) draw quad
|
||||
if(sm<4) todo probe (0, 0) rgba (1, 1, 1, 11)
|
||||
if(sm>=4) probe (0, 0) rgba (10, 10, 10, 11)
|
||||
if(sm<4) probe (0, 0) rgba(1, 1, 1, 11)
|
||||
if(sm>=4) probe (0, 0) rgba(10, 10, 10, 11)
|
||||
|
||||
|
||||
[pixel shader todo(sm<4)]
|
||||
@ -202,7 +202,7 @@ float4 main() : sv_target
|
||||
|
||||
[test]
|
||||
todo(msl) draw quad
|
||||
if(sm<4) todo probe (0, 0) rgba(453021, 453021, 453021, 111111)
|
||||
if(sm<4) probe (0, 0) rgba(453021, 453021, 453021, 111111)
|
||||
if(sm>=4) probe (0, 0) rgba(12333, 12333, 12333, 111111)
|
||||
|
||||
|
||||
|
@ -229,7 +229,7 @@ size (2d, 2, 2)
|
||||
filter linear linear linear
|
||||
address clamp clamp clamp
|
||||
|
||||
[pixel shader todo(sm<4)]
|
||||
[pixel shader]
|
||||
Texture2D tex;
|
||||
sampler sam;
|
||||
float a;
|
||||
@ -243,14 +243,14 @@ float4 main() : sv_target
|
||||
|
||||
[test]
|
||||
uniform 0 float -2
|
||||
todo(sm<4 | msl) draw quad
|
||||
todo(msl) draw quad
|
||||
probe (0, 0) rgba (0.0, 0.0, 0.0, 4.0)
|
||||
uniform 0 float 4
|
||||
todo(sm<4 | msl) draw quad
|
||||
todo(msl) draw quad
|
||||
probe (0, 0) rgba (1.0, 2.0, 3.0, 4.0)
|
||||
|
||||
|
||||
[pixel shader todo(sm<4)]
|
||||
[pixel shader]
|
||||
Texture2D tex;
|
||||
sampler sam;
|
||||
float a;
|
||||
@ -267,11 +267,11 @@ float4 main() : sv_target
|
||||
|
||||
[test]
|
||||
uniform 0 float 2
|
||||
todo(sm<4 | msl) draw quad
|
||||
todo(msl) draw quad
|
||||
probe (0, 0) rgba (0.0, 0.0, 0.0, 4.0)
|
||||
uniform 0 float 1
|
||||
todo(sm<4 | msl) draw quad
|
||||
todo(msl) draw quad
|
||||
probe (0, 0) rgba (1.0, 0.0, 0.0, 4.0)
|
||||
uniform 0 float 0
|
||||
todo(sm<4 | msl) draw quad
|
||||
todo(msl) draw quad
|
||||
probe (0, 0) rgba (1.0, 1.0, 0.0, 4.0)
|
||||
|
@ -18,7 +18,7 @@ void main(float4 pos : position, out float2 tex : texcoord, out float4 out_pos :
|
||||
out_pos = pos;
|
||||
}
|
||||
|
||||
[pixel shader todo(sm<4)]
|
||||
[pixel shader]
|
||||
sampler s;
|
||||
Texture2D t;
|
||||
uniform float bias;
|
||||
@ -32,16 +32,16 @@ float4 main(float2 coord : texcoord) : sv_target
|
||||
|
||||
[test]
|
||||
uniform 0 float4 6.5 0.0 0.0 0.0
|
||||
todo(sm<4 | msl) draw quad
|
||||
todo(msl) draw quad
|
||||
probe (0, 0) rgba (10.0, 0.0, 10.0, 0.0)
|
||||
|
||||
uniform 0 float4 7.5 0.0 0.0 0.0
|
||||
todo(sm<4 | msl) draw quad
|
||||
probe (0, 0) rgba (4.0, 0.0, 10.0, 0.0)
|
||||
todo(msl) draw quad
|
||||
todo(sm<4) probe (0, 0) rgba(4.0, 0.0, 10.0, 0.0)
|
||||
|
||||
uniform 0 float4 8.5 0.0 0.0 0.0
|
||||
todo(sm<4 | msl) draw quad
|
||||
probe (0, 0) rgba (0.0, 0.0, 10.0, 0.0)
|
||||
todo(msl) draw quad
|
||||
todo(sm<4) probe (0, 0) rgba(0.0, 0.0, 10.0, 0.0)
|
||||
|
||||
[require]
|
||||
shader model >= 3.0
|
||||
|
@ -7,7 +7,7 @@ size (2d, 2, 2)
|
||||
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
|
||||
0.0 0.0 0.0 0.0 1.0 0.0 1.0 0.0
|
||||
|
||||
[pixel shader todo(sm<4)]
|
||||
[pixel shader]
|
||||
sampler s;
|
||||
Texture2D t;
|
||||
|
||||
@ -17,10 +17,10 @@ float4 main() : sv_target
|
||||
}
|
||||
|
||||
[test]
|
||||
todo(sm<4 | msl) draw quad
|
||||
todo(msl) draw quad
|
||||
probe (0, 0) rgba (0.25, 0, 0.25, 0)
|
||||
|
||||
[pixel shader todo(sm<4)]
|
||||
[pixel shader]
|
||||
SamplerState s;
|
||||
Texture2D t;
|
||||
|
||||
@ -30,7 +30,7 @@ float4 main() : sv_target
|
||||
}
|
||||
|
||||
[test]
|
||||
todo(sm<4 | msl) draw quad
|
||||
todo(msl) draw quad
|
||||
probe (0, 0) rgba (0.25, 0, 0.25, 0)
|
||||
|
||||
[pixel shader fail]
|
||||
|
@ -136,7 +136,7 @@ float4 main(Texture2D tex2) : sv_target
|
||||
}
|
||||
|
||||
|
||||
[pixel shader todo(sm<4)]
|
||||
[pixel shader]
|
||||
Texture2D real_tex;
|
||||
static Texture2D tex = real_tex;
|
||||
sampler sam;
|
||||
@ -147,11 +147,11 @@ float4 main() : sv_target
|
||||
}
|
||||
|
||||
[test]
|
||||
todo(sm<4 | msl) draw quad
|
||||
todo(msl) draw quad
|
||||
probe (0, 0) rgba (1, 2, 3, 4)
|
||||
|
||||
|
||||
[pixel shader todo(sm<4)]
|
||||
[pixel shader]
|
||||
Texture2D real_tex;
|
||||
static Texture2D tex;
|
||||
sampler sam;
|
||||
@ -163,7 +163,7 @@ float4 main() : sv_target
|
||||
}
|
||||
|
||||
[test]
|
||||
todo(sm<4 | msl) draw quad
|
||||
todo(msl) draw quad
|
||||
probe (0, 0) rgba (1, 2, 3, 4)
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user