Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • wine/vkd3d
  • stefan/vkd3d
  • cmccarthy/vkd3d
  • giomasce/vkd3d
  • fcasas/vkd3d
  • jactry/vkd3d
  • ReDress/vkd3d
  • mstorsjo/vkd3d
  • huw/vkd3d
  • julliard/vkd3d
  • bshanks/vkd3d
  • zfigura/vkd3d
  • hverbeet/vkd3d
  • DarkShadow44/vkd3d
  • nsivov/vkd3d
  • dhary686/vkd3d
  • Mystral/vkd3d
  • maljaf/vkd3d
  • smcv/vkd3d
  • flibitijibibo/vkd3d
  • q4a/vkd3d
  • jsikorski/vkd3d
  • alesliehughes/vkd3d-alesliehughes
  • vitorhnn/vkd3d
  • agusev/vkd3d
  • etang-cw/vkd3d
  • petrathekat/vkd3d
  • simon.mr995/vkd3d
  • sgwaki/vkd3d
  • jacek/vkd3d
  • fweimer/vkd3d
  • Clara/vkd3d
  • disini/vkd3d
  • antenabr2/vkd3d
  • gilvbp/vkd3d
  • yshui/vkd3d
  • shaunren/vkd3d
  • jennetsaryyewa96/vkd3d
  • Jamesattay/vkd3d
  • zacemmneeto77/vkd3d
  • GermanAizek/vkd3d
  • opespinach/vkd3d
  • ruslanboyka201/vkd3d
  • navi/vkd3d
  • Feifan/vkd3d
  • yashmhmdly172/vkd3d
  • Sec32fun32/vkd3d
  • ritalat/vkd3d
  • ivyl/vkd3d
  • baikaishiuc/vkd3d
  • austin987/vkd3d
  • TornadoCookie/vkd3d
52 results
Show changes
Commits on Source (10)
......@@ -69,6 +69,7 @@ vkd3d_shader_tests = \
tests/hlsl/cast-to-int.shader_test \
tests/hlsl/cast-to-uint.shader_test \
tests/hlsl/cbuffer.shader_test \
tests/hlsl/ceil.shader_test \
tests/hlsl/clamp.shader_test \
tests/hlsl/clip.shader_test \
tests/hlsl/combined-samplers.shader_test \
......
......@@ -1824,6 +1824,37 @@ static void write_sm1_dp2add(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer
write_sm1_instruction(ctx, buffer, &instr);
}
static void write_sm1_ternary_op(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer,
D3DSHADER_INSTRUCTION_OPCODE_TYPE opcode, const struct hlsl_reg *dst, const struct hlsl_reg *src1,
const struct hlsl_reg *src2, const struct hlsl_reg *src3)
{
struct sm1_instruction instr =
{
.opcode = opcode,
.dst.type = D3DSPR_TEMP,
.dst.writemask = dst->writemask,
.dst.reg = dst->id,
.has_dst = 1,
.srcs[0].type = D3DSPR_TEMP,
.srcs[0].swizzle = hlsl_swizzle_from_writemask(src1->writemask),
.srcs[0].reg = src1->id,
.srcs[1].type = D3DSPR_TEMP,
.srcs[1].swizzle = hlsl_swizzle_from_writemask(src2->writemask),
.srcs[1].reg = src2->id,
.srcs[2].type = D3DSPR_TEMP,
.srcs[2].swizzle = hlsl_swizzle_from_writemask(src3->writemask),
.srcs[2].reg = src3->id,
.src_count = 3,
};
sm1_map_src_swizzle(&instr.srcs[0], instr.dst.writemask);
sm1_map_src_swizzle(&instr.srcs[1], instr.dst.writemask);
sm1_map_src_swizzle(&instr.srcs[2], instr.dst.writemask);
write_sm1_instruction(ctx, buffer, &instr);
}
static void write_sm1_binary_op(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer,
D3DSHADER_INSTRUCTION_OPCODE_TYPE opcode, const struct hlsl_reg *dst,
const struct hlsl_reg *src1, const struct hlsl_reg *src2)
......@@ -2190,6 +2221,10 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b
}
break;
case HLSL_OP3_CMP:
write_sm1_ternary_op(ctx, buffer, D3DSIO_CMP, &instr->reg, &arg1->reg, &arg2->reg, &arg3->reg);
break;
case HLSL_OP3_DP2ADD:
write_sm1_dp2add(ctx, buffer, &instr->reg, &arg1->reg, &arg2->reg, &arg3->reg);
break;
......
......@@ -2562,6 +2562,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op)
[HLSL_OP1_ABS] = "abs",
[HLSL_OP1_BIT_NOT] = "~",
[HLSL_OP1_CAST] = "cast",
[HLSL_OP1_CEIL] = "ceil",
[HLSL_OP1_COS] = "cos",
[HLSL_OP1_COS_REDUCED] = "cos_reduced",
[HLSL_OP1_DSX] = "dsx",
......@@ -2571,6 +2572,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op)
[HLSL_OP1_DSY_COARSE] = "dsy_coarse",
[HLSL_OP1_DSY_FINE] = "dsy_fine",
[HLSL_OP1_EXP2] = "exp2",
[HLSL_OP1_FLOOR] = "floor",
[HLSL_OP1_FRACT] = "fract",
[HLSL_OP1_LOG2] = "log2",
[HLSL_OP1_LOGIC_NOT] = "!",
......@@ -2607,6 +2609,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op)
[HLSL_OP2_NEQUAL] = "!=",
[HLSL_OP2_RSHIFT] = ">>",
[HLSL_OP3_CMP] = "cmp",
[HLSL_OP3_DP2ADD] = "dp2add",
[HLSL_OP3_MOVC] = "movc",
[HLSL_OP3_TERNARY] = "ternary",
......
......@@ -526,6 +526,7 @@ enum hlsl_ir_expr_op
HLSL_OP1_ABS,
HLSL_OP1_BIT_NOT,
HLSL_OP1_CAST,
HLSL_OP1_CEIL,
HLSL_OP1_COS,
HLSL_OP1_COS_REDUCED, /* Reduced range [-pi, pi] */
HLSL_OP1_DSX,
......@@ -578,7 +579,10 @@ enum hlsl_ir_expr_op
/* MOVC(a, b, c) returns c if a is bitwise zero and b otherwise.
* TERNARY(a, b, c) returns c if a == 0 and b otherwise.
* They differ for floating point numbers, because
* -0.0 == 0.0, but it is not bitwise zero. */
* -0.0 == 0.0, but it is not bitwise zero. CMP(a, b, c) returns b
if a >= 0, and c otherwise. It's used only for SM1-SM3 targets, while
SM4+ is using MOVC in such cases. */
HLSL_OP3_CMP,
HLSL_OP3_MOVC,
HLSL_OP3_TERNARY,
};
......
......@@ -2749,6 +2749,17 @@ static bool intrinsic_asuint(struct hlsl_ctx *ctx,
return add_expr(ctx, params->instrs, HLSL_OP1_REINTERPRET, operands, data_type, loc);
}
static bool intrinsic_ceil(struct hlsl_ctx *ctx,
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
{
struct hlsl_ir_node *arg;
if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
return false;
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_CEIL, arg, loc);
}
static bool intrinsic_clamp(struct hlsl_ctx *ctx,
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
{
......@@ -3547,7 +3558,7 @@ static bool intrinsic_tan(struct hlsl_ctx *ctx,
static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *params,
const struct vkd3d_shader_location *loc, const char *name, enum hlsl_sampler_dim dim)
{
struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_SAMPLE};
struct hlsl_resource_load_params load_params = { 0 };
const struct hlsl_type *sampler_type;
struct hlsl_ir_node *coords, *load;
......@@ -3576,10 +3587,41 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *
hlsl_release_string_buffer(ctx, string);
}
if (!(coords = add_implicit_conversion(ctx, params->instrs, params->args[1],
hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, hlsl_sampler_dim_count(dim)), loc)))
if (!strcmp(name, "tex2Dlod"))
{
return false;
struct hlsl_ir_node *lod, *c;
load_params.type = HLSL_RESOURCE_SAMPLE_LOD;
if (!(c = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, Y, Z, W), hlsl_sampler_dim_count(dim), params->args[1], loc)))
return false;
hlsl_block_add_instr(params->instrs, c);
if (!(coords = add_implicit_conversion(ctx, params->instrs, c, hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT,
hlsl_sampler_dim_count(dim)), loc)))
{
return false;
}
if (!(lod = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(W, W, W, W), 1, params->args[1], loc)))
return false;
hlsl_block_add_instr(params->instrs, lod);
if (!(load_params.lod = add_implicit_conversion(ctx, params->instrs, lod,
hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc)))
{
return false;
}
}
else
{
load_params.type = HLSL_RESOURCE_SAMPLE;
if (!(coords = add_implicit_conversion(ctx, params->instrs, params->args[1],
hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, hlsl_sampler_dim_count(dim)), loc)))
{
return false;
}
}
/* tex1D() functions never produce 1D resource declarations. For newer profiles half offset
......@@ -3638,6 +3680,12 @@ static bool intrinsic_tex2D(struct hlsl_ctx *ctx,
return intrinsic_tex(ctx, params, loc, "tex2D", HLSL_SAMPLER_DIM_2D);
}
static bool intrinsic_tex2Dlod(struct hlsl_ctx *ctx,
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
{
return intrinsic_tex(ctx, params, loc, "tex2Dlod", HLSL_SAMPLER_DIM_2D);
}
static bool intrinsic_tex3D(struct hlsl_ctx *ctx,
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
{
......@@ -3780,6 +3828,7 @@ intrinsic_functions[] =
{"any", 1, true, intrinsic_any},
{"asfloat", 1, true, intrinsic_asfloat},
{"asuint", -1, true, intrinsic_asuint},
{"ceil", 1, true, intrinsic_ceil},
{"clamp", 3, true, intrinsic_clamp},
{"clip", 1, true, intrinsic_clip},
{"cos", 1, true, intrinsic_cos},
......@@ -3822,6 +3871,7 @@ intrinsic_functions[] =
{"tan", 1, true, intrinsic_tan},
{"tex1D", -1, false, intrinsic_tex1D},
{"tex2D", -1, false, intrinsic_tex2D},
{"tex2Dlod", 2, false, intrinsic_tex2Dlod},
{"tex3D", -1, false, intrinsic_tex3D},
{"texCUBE", -1, false, intrinsic_texCUBE},
{"transpose", 1, true, intrinsic_transpose},
......
......@@ -2685,10 +2685,68 @@ static bool lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct
return true;
}
/* Lower CEIL to FRC */
static bool lower_ceil(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *arg, *neg, *sum, *frc;
struct hlsl_ir_expr *expr;
if (instr->type != HLSL_IR_EXPR)
return false;
expr = hlsl_ir_expr(instr);
arg = expr->operands[0].node;
if (expr->op != HLSL_OP1_CEIL)
return false;
if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg, &instr->loc)))
return false;
hlsl_block_add_instr(block, neg);
if (!(frc = hlsl_new_unary_expr(ctx, HLSL_OP1_FRACT, neg, &instr->loc)))
return false;
hlsl_block_add_instr(block, frc);
if (!(sum = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, frc, arg)))
return false;
hlsl_block_add_instr(block, sum);
return true;
}
/* Lower FLOOR to FRC */
static bool lower_floor(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *arg, *neg, *sum, *frc;
struct hlsl_ir_expr *expr;
if (instr->type != HLSL_IR_EXPR)
return false;
expr = hlsl_ir_expr(instr);
arg = expr->operands[0].node;
if (expr->op != HLSL_OP1_FLOOR)
return false;
if (!(frc = hlsl_new_unary_expr(ctx, HLSL_OP1_FRACT, arg, &instr->loc)))
return false;
hlsl_block_add_instr(block, frc);
if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, frc, &instr->loc)))
return false;
hlsl_block_add_instr(block, neg);
if (!(sum = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, neg, arg)))
return false;
hlsl_block_add_instr(block, sum);
return true;
}
/* Use 'movc' for the ternary operator. */
static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], *replacement;
struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = { 0 }, *replacement;
struct hlsl_ir_node *zero, *cond, *first, *second;
struct hlsl_constant_value zero_value = { 0 };
struct hlsl_ir_expr *expr;
......@@ -2705,28 +2763,54 @@ static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru
first = expr->operands[1].node;
second = expr->operands[2].node;
if (cond->data_type->base_type == HLSL_TYPE_FLOAT)
if (ctx->profile->major_version < 4 && ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL)
{
if (!(zero = hlsl_new_constant(ctx, cond->data_type, &zero_value, &instr->loc)))
struct hlsl_ir_node *abs, *neg;
if (!(abs = hlsl_new_unary_expr(ctx, HLSL_OP1_ABS, cond, &instr->loc)))
return false;
hlsl_block_add_instr(block, zero);
hlsl_block_add_instr(block, abs);
if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, abs, &instr->loc)))
return false;
hlsl_block_add_instr(block, neg);
operands[0] = neg;
operands[1] = second;
operands[2] = first;
if (!(replacement = hlsl_new_expr(ctx, HLSL_OP3_CMP, operands, first->data_type, &instr->loc)))
return false;
}
else if (ctx->profile->major_version < 4 && ctx->profile->type == VKD3D_SHADER_TYPE_VERTEX)
{
hlsl_fixme(ctx, &instr->loc, "Ternary operator is not implemented for %s profile.", ctx->profile->name);
return false;
}
else
{
if (cond->data_type->base_type == HLSL_TYPE_FLOAT)
{
if (!(zero = hlsl_new_constant(ctx, cond->data_type, &zero_value, &instr->loc)))
return false;
hlsl_block_add_instr(block, zero);
operands[0] = zero;
operands[1] = cond;
type = cond->data_type;
type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_BOOL, type->dimx, type->dimy);
if (!(cond = hlsl_new_expr(ctx, HLSL_OP2_NEQUAL, operands, type, &instr->loc)))
return false;
hlsl_block_add_instr(block, cond);
}
memset(operands, 0, sizeof(operands));
operands[0] = zero;
operands[1] = cond;
type = cond->data_type;
type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_BOOL, type->dimx, type->dimy);
if (!(cond = hlsl_new_expr(ctx, HLSL_OP2_NEQUAL, operands, type, &instr->loc)))
operands[0] = cond;
operands[1] = first;
operands[2] = second;
if (!(replacement = hlsl_new_expr(ctx, HLSL_OP3_MOVC, operands, first->data_type, &instr->loc)))
return false;
hlsl_block_add_instr(block, cond);
}
memset(operands, 0, sizeof(operands));
operands[0] = cond;
operands[1] = first;
operands[2] = second;
if (!(replacement = hlsl_new_expr(ctx, HLSL_OP3_MOVC, operands, first->data_type, &instr->loc)))
return false;
hlsl_block_add_instr(block, replacement);
return true;
}
......@@ -4818,14 +4902,15 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry
hlsl_transform_ir(ctx, track_object_components_usage, body, NULL);
sort_synthetic_separated_samplers_first(ctx);
if (profile->major_version >= 4)
lower_ir(ctx, lower_ternary, body);
lower_ir(ctx, lower_ternary, body);
if (profile->major_version < 4)
{
lower_ir(ctx, lower_division, body);
lower_ir(ctx, lower_sqrt, body);
lower_ir(ctx, lower_dot, body);
lower_ir(ctx, lower_round, body);
lower_ir(ctx, lower_ceil, body);
lower_ir(ctx, lower_floor, body);
}
if (profile->major_version < 2)
......
......@@ -228,6 +228,32 @@ static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
return true;
}
static bool fold_ceil(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
{
enum hlsl_base_type type = dst_type->base_type;
unsigned int k;
assert(type == src->node.data_type->base_type);
for (k = 0; k < dst_type->dimx; ++k)
{
switch (type)
{
case HLSL_TYPE_FLOAT:
case HLSL_TYPE_HALF:
dst->u[k].f = ceilf(src->value.u[k].f);
break;
default:
FIXME("Fold 'ceil' for type %s.\n", debug_hlsl_type(ctx, dst_type));
return false;
}
}
return true;
}
static bool fold_exp2(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
{
......@@ -254,6 +280,32 @@ static bool fold_exp2(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
return true;
}
static bool fold_floor(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
{
enum hlsl_base_type type = dst_type->base_type;
unsigned int k;
assert(type == src->node.data_type->base_type);
for (k = 0; k < dst_type->dimx; ++k)
{
switch (type)
{
case HLSL_TYPE_FLOAT:
case HLSL_TYPE_HALF:
dst->u[k].f = floorf(src->value.u[k].f);
break;
default:
FIXME("Fold 'floor' for type %s.\n", debug_hlsl_type(ctx, dst_type));
return false;
}
}
return true;
}
static bool fold_fract(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
{
......@@ -1229,10 +1281,18 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
success = fold_cast(ctx, &res, instr->data_type, arg1);
break;
case HLSL_OP1_CEIL:
success = fold_ceil(ctx, &res, instr->data_type, arg1);
break;
case HLSL_OP1_EXP2:
success = fold_exp2(ctx, &res, instr->data_type, arg1);
break;
case HLSL_OP1_FLOOR:
success = fold_floor(ctx, &res, instr->data_type, arg1);
break;
case HLSL_OP1_FRACT:
success = fold_fract(ctx, &res, instr->data_type, arg1);
break;
......
......@@ -4931,6 +4931,11 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex
write_sm4_cast(tpf, expr);
break;
case HLSL_OP1_CEIL:
assert(type_is_float(dst_type));
write_sm4_unary_op(tpf, VKD3D_SM4_OP_ROUND_PI, &expr->node, arg1, 0);
break;
case HLSL_OP1_COS:
assert(type_is_float(dst_type));
write_sm4_unary_op_with_two_destinations(tpf, VKD3D_SM4_OP_SINCOS, &expr->node, 1, arg1);
......
[pixel shader]
float4 main() : sv_target
{
return ceil(float4(-0.5, 6.5, 7.5, 3.4));
}
[test]
draw quad
probe all rgba (0.0, 7.0, 8.0, 4.0) 4
[pixel shader]
uniform float4 u;
float4 main() : sv_target
{
return ceil(u);
}
[test]
uniform 0 float4 -0.5 6.5 7.5 3.4
todo(sm>=6) draw quad
probe all rgba (0.0, 7.0, 8.0, 4.0) 4
[pixel shader]
uniform float4 u;
float4 main() : sv_target
{
float a = ceil(u.r);
int2 b = ceil(u.gb);
float4 res = float4(b, a, u.a);
return ceil(res);
}
[test]
uniform 0 float4 -0.5 6.5 7.5 3.4
todo(sm>=6) draw quad
probe all rgba (7.0, 8.0, 0.0, 4.0) 4
[require]
shader model >= 4.0
[pixel shader]
uniform int4 u;
float4 main() : sv_target
{
float a = ceil(u.r);
int2 b = ceil(u.gb);
float4 res = float4(b, a, u.a);
return ceil(res);
}
[test]
uniform 0 int4 -1 6 7 3
todo(sm>=6) draw quad
probe all rgba (6.0, 7.0, -1.0, 3.0) 4
[pixel shader]
float4 main() : sv_target
{
return floor(float4(-0.5, 6.5, 7.5, 3.4));
}
[test]
draw quad
probe all rgba (-1.0, 6.0, 7.0, 3.0) 4
[pixel shader]
uniform float4 u;
......
......@@ -34,3 +34,27 @@ probe all rgba (0.5, 0.0, 1.0, 0.0)
uniform 0 float4 1.0 0.0 0.0 0.0
todo(sm>=6) draw quad
probe all rgba (0.0, 0.0, 1.0, 0.0)
[require]
shader model >= 3.0
options: backcompat
[pixel shader fail(sm>=6)]
sampler s;
float level;
float4 main() : sv_target
{
return tex2Dlod(s, float4(0.5, 0.5, 0, level));
}
[test]
uniform 0 float4 0.0 0.0 0.0 0.0
draw quad
probe all rgba (1.0, 0.0, 1.0, 0.0)
uniform 0 float4 0.5 0.0 0.0 0.0
draw quad
probe all rgba (0.5, 0.0, 1.0, 0.0)
uniform 0 float4 1.0 0.0 0.0 0.0
draw quad
probe all rgba (0.0, 0.0, 1.0, 0.0)