vkd3d-shader/hlsl: Reinterpret minimum precision types as their regular counterparts.

Reinterpret min16float, min10float, min16int, min12int, and min16uint
as their regular counterparts: float, float, int, int, uint,
respectively.

A proper implementation would require adding minimum precision
indicators to all the dxbc-tpf instructions that use these types.
Consider the output of fxc 10.1 with the following shader:

    uniform int i;

    float4 main() : sv_target
    {
        min16float4 a = {0, 1, 2, i};
        min16int2 b = {4, i};
        min10float3 c = {6.4, 7, i};
        min12int d = 9.4;
        min16uint4x2 e = {14.4, 15, 16, 17, 18, 19, 20, i};

        return mul(e, b) + a + c.xyzx + d;
    }

However, if the graphics driver doesn't have minimum precision support,
it ignores the minimum precision indicators and runs at 32-bit
precision, which is equivalent as working with regular types.
This commit is contained in:
Francisco Casas
2022-12-07 18:06:06 -03:00
committed by Alexandre Julliard
parent 4ce6a17053
commit 404a2d6a3d
Notes: Alexandre Julliard 2023-01-25 22:43:55 +01:00
Approved-by: Giovanni Mascellani (@giomasce)
Approved-by: Zebediah Figura (@zfigura)
Approved-by: Henri Verbeet (@hverbeet)
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/58
4 changed files with 85 additions and 7 deletions

View File

@@ -680,6 +680,7 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old,
if (!(type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK))
type->modifiers |= default_majority;
type->sampler_dim = old->sampler_dim;
type->is_minimum_precision = old->is_minimum_precision;
switch (old->type)
{
case HLSL_CLASS_ARRAY:
@@ -2392,7 +2393,7 @@ static int compare_function_rb(const void *key, const struct rb_entry *entry)
static void declare_predefined_types(struct hlsl_ctx *ctx)
{
unsigned int x, y, bt, i;
unsigned int x, y, bt, i, v;
struct hlsl_type *type;
static const char * const names[] =
@@ -2404,7 +2405,11 @@ static void declare_predefined_types(struct hlsl_ctx *ctx)
"uint",
"bool",
};
char name[10];
char name[15];
static const char *const variants_float[] = {"min10float", "min16float"};
static const char *const variants_int[] = {"min12int", "min16int"};
static const char *const variants_uint[] = {"min16uint"};
static const char *const sampler_names[] =
{
@@ -2464,6 +2469,63 @@ static void declare_predefined_types(struct hlsl_ctx *ctx)
}
}
for (bt = 0; bt <= HLSL_TYPE_LAST_SCALAR; ++bt)
{
unsigned int n_variants = 0;
const char *const *variants;
switch (bt)
{
case HLSL_TYPE_FLOAT:
variants = variants_float;
n_variants = ARRAY_SIZE(variants_float);
break;
case HLSL_TYPE_INT:
variants = variants_int;
n_variants = ARRAY_SIZE(variants_int);
break;
case HLSL_TYPE_UINT:
variants = variants_uint;
n_variants = ARRAY_SIZE(variants_uint);
break;
default:
break;
}
for (v = 0; v < n_variants; ++v)
{
for (y = 1; y <= 4; ++y)
{
for (x = 1; x <= 4; ++x)
{
sprintf(name, "%s%ux%u", variants[v], y, x);
type = hlsl_new_type(ctx, name, HLSL_CLASS_MATRIX, bt, x, y);
type->is_minimum_precision = 1;
hlsl_scope_add_type(ctx->globals, type);
if (y == 1)
{
sprintf(name, "%s%u", variants[v], x);
type = hlsl_new_type(ctx, name, HLSL_CLASS_VECTOR, bt, x, y);
type->is_minimum_precision = 1;
hlsl_scope_add_type(ctx->globals, type);
if (x == 1)
{
sprintf(name, "%s", variants[v]);
type = hlsl_new_type(ctx, name, HLSL_CLASS_SCALAR, bt, x, y);
type->is_minimum_precision = 1;
hlsl_scope_add_type(ctx->globals, type);
}
}
}
}
}
}
for (bt = 0; bt <= HLSL_SAMPLER_DIM_LAST_SAMPLER; ++bt)
{
type = hlsl_new_type(ctx, sampler_names[bt], HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1);