Module: vkd3d
Branch: master
Commit: 4b5c7e372196a303db6786f01f9c37589f86d2e8
URL: https://gitlab.winehq.org/wine/vkd3d/-/commit/4b5c7e372196a303db6786f01f9c3…
Author: Francisco Casas <fcasas(a)codeweavers.com>
Date: Fri Oct 20 18:38:12 2023 -0300
vkd3d-shader/d3dbc: Implement casts from ints to floats as a MOV.
For temporary registers, SM1-SM3 integer types are internally
represented as floating point, so, in order to perform a cast
from ints to floats we need a mere MOV.
For constant integer registers "iN" there is no operation for casting
from a floating point register to them. For address registers "aN", and
the loop counting register "aL", vertex shaders have the "mova" operation
but we haven't used these registers in any way yet.
We probably would want to introduce these as synthetic variables
allocated in a special register set. In that case we have to remember to
use MOVA instead of MOV in the store operations, but they shouldn't be src
or dst of CAST operations.
Regarding constant integer registers, in some shaders, constants are
expected to be received formatted as an integer, such as:
int m;
float4 main() : sv_target
{
float4 res = {0, 0, 0, 0};
for (int k = 0; k < m; ++k)
res += k;
return res;
}
which compiles as:
// Registers:
//
// Name Reg Size
// ------------ ----- ----
// m i0 1
//
ps_3_0
def c0, 0, 1, 0, 0
mov r0, c0.x
mov r1.x, c0.x
rep i0
add r0, r0, r1.x
add r1.x, r1.x, c0.y
endrep
mov oC0, r0
but this only happens if the integer constant is used directly in an
instruction that needs it, and as I said there is no instruction that
allows converting them to a float representation.
Notice how a more complex shader, that performs operations with this
integer variable "m":
int m;
float4 main() : sv_target
{
float4 res = {0, 0, 0, 0};
for (int k = 0; k < m * m; ++k)
res += k;
return res;
}
gives the following output:
// Registers:
//
// Name Reg Size
// ------------ ----- ----
// m c0 1
//
ps_3_0
def c1, 0, 0, 1, 0
defi i0, 255, 0, 0, 0
mul r0.x, c0.x, c0.x
mov r1, c1.y
mov r0.y, c1.y
rep i0
mov r0.z, r0.x
break_ge r0.y, r0.z
add r1, r0.y, r1
add r0.y, r0.y, c1.z
endrep
mov oC0, r1
Meaning that the uniform "m" is just stored as a floating point in
"c0", the constant integer register "i0" is just set to 255 (hoping
it is a high enough value) using "defi", and the "break_ge"
involving c0 is used to break from the loop.
We could potentially use this approach to implement loops from SM3
without expecting the variables being received as constant integer
registers.
According to the D3D documentation, for SM1-SM3 constant integer
registers are only used by the 'loop' and 'rep' instructions.
---
libs/vkd3d-shader/d3dbc.c | 82 +++++++++++++++++++++++++++++++++++++++++
tests/hlsl/distance.shader_test | 2 +-
tests/hlsl/half.shader_test | 4 +-
tests/hlsl/ldexp.shader_test | 4 +-
tests/hlsl/lerp.shader_test | 6 +--
5 files changed, 90 insertions(+), 8 deletions(-)
diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c
index 9ad9f735..27aec124 100644
--- a/libs/vkd3d-shader/d3dbc.c
+++ b/libs/vkd3d-shader/d3dbc.c
@@ -1958,6 +1958,84 @@ static void write_sm1_unary_op(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe
write_sm1_instruction(ctx, buffer, &instr);
}
+static void write_sm1_cast(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer,
+ const struct hlsl_ir_node *instr)
+{
+ struct hlsl_ir_expr *expr = hlsl_ir_expr(instr);
+ const struct hlsl_ir_node *arg1 = expr->operands[0].node;
+ const struct hlsl_type *dst_type = expr->node.data_type;
+ const struct hlsl_type *src_type = arg1->data_type;
+
+ /* Narrowing casts were already lowered. */
+ assert(src_type->dimx == dst_type->dimx);
+
+ switch (dst_type->base_type)
+ {
+ case HLSL_TYPE_HALF:
+ case HLSL_TYPE_FLOAT:
+ switch (src_type->base_type)
+ {
+ case HLSL_TYPE_INT:
+ case HLSL_TYPE_UINT:
+ /* Integers are internally represented as floats, so no change is necessary.*/
+ case HLSL_TYPE_HALF:
+ case HLSL_TYPE_FLOAT:
+ write_sm1_unary_op(ctx, buffer, D3DSIO_MOV, &instr->reg, &arg1->reg, 0, 0);
+ break;
+
+ case HLSL_TYPE_BOOL:
+ hlsl_fixme(ctx, &instr->loc, "SM1 cast from bool to float.");
+ break;
+
+ case HLSL_TYPE_DOUBLE:
+ hlsl_fixme(ctx, &instr->loc, "SM1 cast from double to float.");
+ break;
+
+ default:
+ vkd3d_unreachable();
+ }
+ break;
+
+ case HLSL_TYPE_INT:
+ case HLSL_TYPE_UINT:
+ switch(src_type->base_type)
+ {
+ case HLSL_TYPE_INT:
+ case HLSL_TYPE_UINT:
+ write_sm1_unary_op(ctx, buffer, D3DSIO_MOV, &instr->reg, &arg1->reg, 0, 0);
+ break;
+
+ case HLSL_TYPE_HALF:
+ case HLSL_TYPE_FLOAT:
+ hlsl_fixme(ctx, &instr->loc, "SM1 cast from float to integer.");
+ break;
+
+ case HLSL_TYPE_BOOL:
+ hlsl_fixme(ctx, &instr->loc, "SM1 cast from bool to integer.");
+ break;
+
+ case HLSL_TYPE_DOUBLE:
+ hlsl_fixme(ctx, &instr->loc, "SM1 cast from double to integer.");
+ break;
+
+ default:
+ vkd3d_unreachable();
+ }
+ break;
+
+ case HLSL_TYPE_DOUBLE:
+ hlsl_fixme(ctx, &instr->loc, "SM1 cast to double.");
+ break;
+
+ case HLSL_TYPE_BOOL:
+ /* Casts to bool should have already been lowered. */
+ default:
+ hlsl_fixme(ctx, &expr->node.loc, "SM1 cast from %s to %s.\n",
+ debug_hlsl_type(ctx, src_type), debug_hlsl_type(ctx, dst_type));
+ break;
+ }
+}
+
static void write_sm1_constant_defs(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer)
{
unsigned int i, x;
@@ -2179,6 +2257,10 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b
write_sm1_unary_op(ctx, buffer, D3DSIO_ABS, &instr->reg, &arg1->reg, 0, 0);
break;
+ case HLSL_OP1_CAST:
+ write_sm1_cast(ctx, buffer, instr);
+ break;
+
case HLSL_OP1_DSX:
write_sm1_unary_op(ctx, buffer, D3DSIO_DSX, &instr->reg, &arg1->reg, 0, 0);
break;
diff --git a/tests/hlsl/distance.shader_test b/tests/hlsl/distance.shader_test
index bf2423c7..3f544645 100644
--- a/tests/hlsl/distance.shader_test
+++ b/tests/hlsl/distance.shader_test
@@ -13,7 +13,7 @@ uniform 4 float4 2.0 -1.0 4.0 5.0
draw quad
probe all rgba (7.483983, 7.483983, 7.483983, 7.483983) 1
-[pixel shader todo(sm<4)]
+[pixel shader]
uniform int4 x;
uniform int4 y;
diff --git a/tests/hlsl/half.shader_test b/tests/hlsl/half.shader_test
index 8cf7a756..fe7074e4 100644
--- a/tests/hlsl/half.shader_test
+++ b/tests/hlsl/half.shader_test
@@ -9,7 +9,7 @@ float4 main() : sv_target
[require]
options: backcompat
-[pixel shader todo(sm<4)]
+[pixel shader]
uniform half h;
float4 main() : sv_target
@@ -19,5 +19,5 @@ float4 main() : sv_target
[test]
uniform 0 float 10.0
-todo(sm<4) draw quad
+draw quad
probe all rgba (10.0, 10.0, 10.0, 10.0)
diff --git a/tests/hlsl/ldexp.shader_test b/tests/hlsl/ldexp.shader_test
index 2d778e07..75492b66 100644
--- a/tests/hlsl/ldexp.shader_test
+++ b/tests/hlsl/ldexp.shader_test
@@ -14,7 +14,7 @@ draw quad
probe all rgba (2.0, 0.00292968750, 4096.0, 6.33825300e+030) 2
-[pixel shader todo(sm<4)]
+[pixel shader]
uniform int4 x;
uniform int4 y;
@@ -28,7 +28,7 @@ if(sm<4) uniform 0 float4 2 3 4 5
if(sm<4) uniform 4 float4 0 -10 10 100
if(sm>=4) uniform 0 int4 2 3 4 5
if(sm>=4) uniform 4 int4 0 -10 10 100
-todo(sm<4) draw quad
+draw quad
probe all rgba (2.0, 0.00292968750, 4096.0, 6.33825300e+030) 2
diff --git a/tests/hlsl/lerp.shader_test b/tests/hlsl/lerp.shader_test
index 901857df..ae6ef534 100644
--- a/tests/hlsl/lerp.shader_test
+++ b/tests/hlsl/lerp.shader_test
@@ -16,7 +16,7 @@ draw quad
probe all rgba (2.0, -10.0, -2.0, 76.25)
-[pixel shader todo(sm<4)]
+[pixel shader]
uniform int4 x;
uniform int4 y;
uniform int4 s;
@@ -33,8 +33,8 @@ if(sm<4) uniform 8 float4 0 1 -1 1000000
if(sm>=4) uniform 0 int4 2 3 4 0
if(sm>=4) uniform 4 int4 0 -10 10 1000000
if(sm>=4) uniform 8 int4 0 1 -1 1000000
-todo(sm<4) draw quad
-probe all rgba (2.0, -10.0, -2.0, 1e12)
+draw quad
+probe all rgba (2.0, -10.0, -2.0, 1e12) 4
[pixel shader]
Module: wine
Branch: master
Commit: f54acf3de01ab8e7870fd7e5482e156fd965138a
URL: https://gitlab.winehq.org/wine/wine/-/commit/f54acf3de01ab8e7870fd7e5482e15…
Author: Piotr Caban <piotr(a)codeweavers.com>
Date: Thu Feb 15 14:02:30 2024 +0100
wininet: Test INTERNET_OPTION_PER_CONNECTION_OPTION on process settings.
Setting invalid proxy server has some side effects.
---
dlls/wininet/tests/internet.c | 91 ++++++++++++++++---------------------------
1 file changed, 34 insertions(+), 57 deletions(-)