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 (23)
Showing
with 738 additions and 185 deletions
......@@ -196,6 +196,14 @@ enum vkd3d_shader_compile_option_fragment_coordinate_origin
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN),
};
/** Advertises feature availability. \since 1.11 */
enum vkd3d_shader_compile_option_feature_flags
{
VKD3D_SHADER_COMPILE_OPTION_FEATURE_INT64 = 0x00000001,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_FEATURE_FLAGS),
};
enum vkd3d_shader_compile_option_name
{
/**
......@@ -253,6 +261,16 @@ enum vkd3d_shader_compile_option_name
* \since 1.10
*/
VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN = 0x00000009,
/**
* This option specifies the shader features available in the target
* environment. These are not extensions, i.e. they are always supported
* by the driver, but may not be supported by the available hardware.
*
* \a value is a member of enum vkd3d_shader_compile_option_feature_flags.
*
* \since 1.11
*/
VKD3D_SHADER_COMPILE_OPTION_FEATURE = 0x0000000a,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_NAME),
};
......
......@@ -364,6 +364,7 @@ struct vkd3d_d3d_asm_compiler
struct vkd3d_string_buffer buffer;
struct vkd3d_shader_version shader_version;
struct vkd3d_d3d_asm_colours colours;
enum vsir_asm_dialect dialect;
};
static int VKD3D_PRINTF_FUNC(2, 3) shader_addline(struct vkd3d_string_buffer *buffer, const char *format, ...)
......@@ -606,7 +607,7 @@ static void shader_dump_resource_type(struct vkd3d_d3d_asm_compiler *compiler, e
vkd3d_string_buffer_printf(&compiler->buffer, "unknown");
}
static void shader_dump_data_type(struct vkd3d_d3d_asm_compiler *compiler, const enum vkd3d_data_type *type)
static void shader_dump_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum vkd3d_data_type type)
{
static const char *const data_type_names[] =
{
......@@ -623,19 +624,31 @@ static void shader_dump_data_type(struct vkd3d_d3d_asm_compiler *compiler, const
[VKD3D_DATA_DOUBLE ] = "double",
[VKD3D_DATA_CONTINUED] = "<continued>",
[VKD3D_DATA_UNUSED ] = "<unused>",
[VKD3D_DATA_UINT8 ] = "uint8",
[VKD3D_DATA_UINT64 ] = "uint64",
[VKD3D_DATA_BOOL ] = "bool",
};
const char *name;
if (type < ARRAY_SIZE(data_type_names))
name = data_type_names[type];
else
name = "<unknown>";
vkd3d_string_buffer_printf(&compiler->buffer, "%s", name);
}
static void shader_dump_resource_data_type(struct vkd3d_d3d_asm_compiler *compiler, const enum vkd3d_data_type *type)
{
int i;
vkd3d_string_buffer_printf(&compiler->buffer, "(");
for (i = 0; i < 4; i++)
{
if (type[i] < ARRAY_SIZE(data_type_names))
name = data_type_names[type[i]];
else
name = "unknown";
vkd3d_string_buffer_printf(&compiler->buffer, "%s%s", i == 0 ? "" : ",", name);
vkd3d_string_buffer_printf(&compiler->buffer, "%s", i == 0 ? "" : ",");
shader_dump_data_type(compiler, type[i]);
}
vkd3d_string_buffer_printf(&compiler->buffer, ")");
......@@ -682,7 +695,7 @@ static void shader_dump_decl_usage(struct vkd3d_d3d_asm_compiler *compiler,
if (semantic->resource.reg.reg.type == VKD3DSPR_UAV)
shader_dump_uav_flags(compiler, flags);
shader_addline(buffer, " ");
shader_dump_data_type(compiler, semantic->resource_data_type);
shader_dump_resource_data_type(compiler, semantic->resource_data_type);
}
else
{
......@@ -1265,6 +1278,32 @@ static void shader_print_non_uniform(struct vkd3d_d3d_asm_compiler *compiler, co
compiler->colours.modifier, compiler->colours.reset);
}
static void shader_dump_reg_type(struct vkd3d_d3d_asm_compiler *compiler,
const struct vkd3d_shader_register *reg)
{
static const char *dimensions[] =
{
[VSIR_DIMENSION_NONE] = "",
[VSIR_DIMENSION_SCALAR] = "s:",
[VSIR_DIMENSION_VEC4] = "v4:",
};
struct vkd3d_string_buffer *buffer = &compiler->buffer;
const char *dimension;
if (compiler->dialect != VSIR_ASM_VSIR)
return;
if (reg->dimension < ARRAY_SIZE(dimensions))
dimension = dimensions[reg->dimension];
else
dimension = "??";
shader_addline(buffer, " <%s", dimension);
shader_dump_data_type(compiler, reg->data_type);
shader_addline(buffer, ">");
}
static void shader_dump_dst_param(struct vkd3d_d3d_asm_compiler *compiler,
const struct vkd3d_shader_dst_param *param, bool is_declaration)
{
......@@ -1294,6 +1333,7 @@ static void shader_dump_dst_param(struct vkd3d_d3d_asm_compiler *compiler,
shader_print_precision(compiler, &param->reg);
shader_print_non_uniform(compiler, &param->reg);
shader_dump_reg_type(compiler, &param->reg);
}
static void shader_dump_src_param(struct vkd3d_d3d_asm_compiler *compiler,
......@@ -1367,6 +1407,7 @@ static void shader_dump_src_param(struct vkd3d_d3d_asm_compiler *compiler,
shader_print_precision(compiler, &param->reg);
shader_print_non_uniform(compiler, &param->reg);
shader_dump_reg_type(compiler, &param->reg);
}
static void shader_dump_ins_modifiers(struct vkd3d_d3d_asm_compiler *compiler,
......@@ -1577,6 +1618,12 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile
shader_addline(buffer, "p");
break;
case VKD3DSIH_ISHL:
case VKD3DSIH_ISHR:
case VKD3DSIH_USHR:
if (ins->flags & VKD3DSI_SHIFT_UNMASKED)
shader_addline(buffer, "_unmasked");
/* fall through */
default:
shader_dump_precise_flags(compiler, ins->flags);
break;
......@@ -1883,7 +1930,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
|| ins->resource_data_type[1] != VKD3D_DATA_FLOAT
|| ins->resource_data_type[2] != VKD3D_DATA_FLOAT
|| ins->resource_data_type[3] != VKD3D_DATA_FLOAT)
shader_dump_data_type(compiler, ins->resource_data_type);
shader_dump_resource_data_type(compiler, ins->resource_data_type);
for (i = 0; i < ins->dst_count; ++i)
{
......@@ -1906,10 +1953,13 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
enum vkd3d_result vkd3d_dxbc_binary_to_text(const struct vkd3d_shader_instruction_array *instructions,
const struct vkd3d_shader_version *shader_version, const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_code *out)
struct vkd3d_shader_code *out, enum vsir_asm_dialect dialect)
{
enum vkd3d_shader_compile_option_formatting_flags formatting;
struct vkd3d_d3d_asm_compiler compiler;
struct vkd3d_d3d_asm_compiler compiler =
{
.dialect = dialect,
};
enum vkd3d_result result = VKD3D_OK;
struct vkd3d_string_buffer *buffer;
unsigned int indent, i, j;
......@@ -2002,6 +2052,7 @@ enum vkd3d_result vkd3d_dxbc_binary_to_text(const struct vkd3d_shader_instructio
{
case VKD3DSIH_ELSE:
case VKD3DSIH_IF:
case VKD3DSIH_IFC:
case VKD3DSIH_LOOP:
case VKD3DSIH_SWITCH:
++indent;
......@@ -2034,7 +2085,7 @@ void vkd3d_shader_trace(const struct vkd3d_shader_instruction_array *instruction
const char *p, *q, *end;
struct vkd3d_shader_code code;
if (vkd3d_dxbc_binary_to_text(instructions, shader_version, NULL, &code) != VKD3D_OK)
if (vkd3d_dxbc_binary_to_text(instructions, shader_version, NULL, &code, VSIR_ASM_VSIR) != VKD3D_OK)
return;
end = (const char *)code.code + code.size;
......
......@@ -431,10 +431,6 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s
case TAG_OSG5:
if (e[i].sysval_semantic == VKD3D_SHADER_SV_NONE)
e[i].sysval_semantic = map_fragment_output_sysval(e[i].semantic_name);
/* Fall through. */
case TAG_PCSG:
case TAG_PSG1:
e[i].used_mask = e[i].mask & ~e[i].used_mask;
break;
}
......
......@@ -29,6 +29,9 @@ static const uint64_t MAX_ALIGNMENT_EXPONENT = 29;
static const uint64_t GLOBALVAR_FLAG_IS_CONSTANT = 1;
static const uint64_t GLOBALVAR_FLAG_EXPLICIT_TYPE = 2;
static const unsigned int GLOBALVAR_ADDRESS_SPACE_SHIFT = 2;
static const uint64_t ALLOCA_FLAG_IN_ALLOCA = 0x20;
static const uint64_t ALLOCA_FLAG_EXPLICIT_TYPE = 0x40;
static const uint64_t ALLOCA_ALIGNMENT_MASK = ALLOCA_FLAG_IN_ALLOCA - 1;
static const unsigned int SHADER_DESCRIPTOR_TYPE_COUNT = 4;
static const unsigned int dx_max_thread_group_size[3] = {1024, 1024, 64};
......@@ -2688,12 +2691,15 @@ static void sm6_parser_declare_icb(struct sm6_parser *sm6, const struct sm6_type
}
static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const struct sm6_type *elem_type,
unsigned int count, unsigned int alignment, unsigned int init, struct sm6_value *dst)
unsigned int count, unsigned int alignment, unsigned int init, struct vkd3d_shader_instruction *ins,
struct sm6_value *dst)
{
enum vkd3d_data_type data_type = vkd3d_data_type_from_sm6_type(elem_type);
struct vkd3d_shader_instruction *ins;
ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_INDEXABLE_TEMP);
if (ins)
vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_DCL_INDEXABLE_TEMP);
else
ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_INDEXABLE_TEMP);
ins->declaration.indexable_temp.register_idx = sm6->indexable_temp_count++;
ins->declaration.indexable_temp.register_size = count;
ins->declaration.indexable_temp.alignment = alignment;
......@@ -2826,7 +2832,7 @@ static bool sm6_parser_declare_global(struct sm6_parser *sm6, const struct dxil_
if (is_constant)
sm6_parser_declare_icb(sm6, scalar_type, count, alignment, init, dst);
else
sm6_parser_declare_indexable_temp(sm6, scalar_type, count, alignment, init, dst);
sm6_parser_declare_indexable_temp(sm6, scalar_type, count, alignment, init, NULL, dst);
}
else if (address_space == ADDRESS_SPACE_GROUPSHARED)
{
......@@ -2854,17 +2860,19 @@ static const struct vkd3d_shader_immediate_constant_buffer *resolve_forward_init
assert(index);
--index;
if (!(value = sm6_parser_get_value_safe(sm6, index)) || !sm6_value_is_icb(value))
if (!(value = sm6_parser_get_value_safe(sm6, index)) || (!sm6_value_is_icb(value) && !sm6_value_is_undef(value)))
{
WARN("Invalid initialiser index %zu.\n", index);
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
"Global variable initialiser value index %zu is invalid.", index);
return NULL;
}
else
else if (sm6_value_is_icb(value))
{
return value->u.icb;
}
/* In VSIR, initialisation with undefined values of objects is implied, not explicit. */
return NULL;
}
static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6)
......@@ -2987,45 +2995,6 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade
}
}
static void sm6_parser_emit_signature(struct sm6_parser *sm6, const struct shader_signature *s,
enum vkd3d_shader_opcode handler_idx, enum vkd3d_shader_opcode siv_handler_idx,
struct vkd3d_shader_dst_param *params)
{
struct vkd3d_shader_instruction *ins;
struct vkd3d_shader_dst_param *param;
const struct signature_element *e;
unsigned int i;
for (i = 0; i < s->element_count; ++i)
{
e = &s->elements[i];
/* Do not check e->used_mask because in some cases it is zero for used elements.
* TODO: scan ahead for used I/O elements. */
if (e->sysval_semantic != VKD3D_SHADER_SV_NONE && e->sysval_semantic != VKD3D_SHADER_SV_TARGET)
{
ins = sm6_parser_add_instruction(sm6, siv_handler_idx);
param = &ins->declaration.register_semantic.reg;
ins->declaration.register_semantic.sysval_semantic = vkd3d_siv_from_sysval(e->sysval_semantic);
}
else
{
ins = sm6_parser_add_instruction(sm6, handler_idx);
param = &ins->declaration.dst;
}
ins->flags = e->interpolation_mode;
*param = params[i];
if (e->register_count > 1)
{
param->reg.idx[0].rel_addr = NULL;
param->reg.idx[0].offset = e->register_count;
}
}
}
static void sm6_parser_init_output_signature(struct sm6_parser *sm6, const struct shader_signature *output_signature)
{
sm6_parser_init_signature(sm6, output_signature, VKD3DSPR_OUTPUT, sm6->output_params);
......@@ -3036,19 +3005,6 @@ static void sm6_parser_init_input_signature(struct sm6_parser *sm6, const struct
sm6_parser_init_signature(sm6, input_signature, VKD3DSPR_INPUT, sm6->input_params);
}
static void sm6_parser_emit_output_signature(struct sm6_parser *sm6, const struct shader_signature *output_signature)
{
sm6_parser_emit_signature(sm6, output_signature, VKD3DSIH_DCL_OUTPUT, VKD3DSIH_DCL_OUTPUT_SIV, sm6->output_params);
}
static void sm6_parser_emit_input_signature(struct sm6_parser *sm6, const struct shader_signature *input_signature)
{
sm6_parser_emit_signature(sm6, input_signature,
(sm6->p.shader_version.type == VKD3D_SHADER_TYPE_PIXEL) ? VKD3DSIH_DCL_INPUT_PS : VKD3DSIH_DCL_INPUT,
(sm6->p.shader_version.type == VKD3D_SHADER_TYPE_PIXEL) ? VKD3DSIH_DCL_INPUT_PS_SIV : VKD3DSIH_DCL_INPUT_SIV,
sm6->input_params);
}
static const struct sm6_value *sm6_parser_next_function_definition(struct sm6_parser *sm6)
{
size_t i, count = sm6->function_count;
......@@ -3071,6 +3027,81 @@ static struct sm6_block *sm6_block_create()
return block;
}
static void sm6_parser_emit_alloca(struct sm6_parser *sm6, const struct dxil_record *record,
struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
{
const struct sm6_type *type[2], *elem_type;
const struct sm6_value *size;
unsigned int i, alignment;
uint64_t packed_operands;
if (!dxil_record_validate_operand_count(record, 4, 4, sm6))
return;
for (i = 0; i < 2; ++i)
{
if (!(type[i] = sm6_parser_get_type(sm6, record->operands[i])))
return;
}
packed_operands = record->operands[3];
if (packed_operands & ALLOCA_FLAG_IN_ALLOCA)
WARN("Ignoring in_alloca flag.\n");
if (!(packed_operands & ALLOCA_FLAG_EXPLICIT_TYPE))
{
FIXME("Unhandled implicit type.\n");
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
"Implicit result type for ALLOCA instructions is not supported.");
return;
}
packed_operands &= ~(ALLOCA_FLAG_IN_ALLOCA | ALLOCA_FLAG_EXPLICIT_TYPE);
if (!sm6_type_is_array(type[0]) || !sm6_type_is_numeric(elem_type = type[0]->u.array.elem_type))
{
WARN("Type is not a numeric array.\n");
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
"Result type of an ALLOCA instruction is not a numeric array.");
return;
}
/* The second type operand is the type of the allocation size operand, in case it is a
* forward reference. We only support a constant size, so no forward ref support is needed. */
if (!sm6_type_is_integer(type[1]))
{
WARN("Size operand type is not scalar integer.\n");
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
"The type of the allocation size operand of an ALLOCA instruction is not scalar integer.");
return;
}
if (!(dst->type = sm6_type_get_pointer_to_type(type[0], ADDRESS_SPACE_DEFAULT, sm6)))
{
WARN("Failed to get pointer type for type class %u.\n", type[0]->class);
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE,
"Module does not define a pointer type for an ALLOCA instruction.");
return;
}
if (!(size = sm6_parser_get_value_safe(sm6, record->operands[2])))
return;
/* A size of 1 means one instance of type[0], i.e. one array. */
if (sm6_value_get_constant_uint(size) != 1)
{
FIXME("Allocation size is not 1.\n");
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
"ALLOCA instruction allocation sizes other than 1 are not supported.");
return;
}
if (!bitcode_parse_alignment(packed_operands & ALLOCA_ALIGNMENT_MASK, &alignment))
WARN("Invalid alignment %"PRIu64".\n", packed_operands);
packed_operands &= ~ALLOCA_ALIGNMENT_MASK;
if (packed_operands)
WARN("Ignoring flags %#"PRIx64".\n", packed_operands);
sm6_parser_declare_indexable_temp(sm6, elem_type, type[0]->u.array.count, alignment, 0, ins, dst);
}
static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_type *type_a,
const struct sm6_type *type_b, struct sm6_parser *sm6)
{
......@@ -3171,8 +3202,10 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco
unsigned int i = 0;
a = sm6_parser_get_value_by_ref(sm6, record, NULL, &i);
if (!a)
return;
b = sm6_parser_get_value_by_ref(sm6, record, a->type, &i);
if (!a || !b)
if (!b)
return;
if (!dxil_record_validate_operand_count(record, i + 1, i + 2, sm6))
......@@ -3246,6 +3279,12 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco
}
else
{
if (handler_idx == VKD3DSIH_ISHL || handler_idx == VKD3DSIH_ISHR || handler_idx == VKD3DSIH_USHR)
{
/* DXC emits AND instructions where necessary to mask shift counts. Shift binops
* do not imply masking the shift as the TPF equivalents do. */
ins->flags |= VKD3DSI_SHIFT_UNMASKED;
}
instruction_dst_param_init_ssa_scalar(ins, sm6);
}
}
......@@ -3963,8 +4002,10 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor
}
a = sm6_parser_get_value_by_ref(sm6, record, NULL, &i);
if (!a)
return;
b = sm6_parser_get_value_by_ref(sm6, record, a->type, &i);
if (!a || !b)
if (!b)
return;
if (!dxil_record_validate_operand_count(record, i + 1, i + 2, sm6))
......@@ -4253,6 +4294,57 @@ static void sm6_parser_emit_ret(struct sm6_parser *sm6, const struct dxil_record
ins->handler_idx = VKD3DSIH_NOP;
}
static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_record *record,
struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
{
struct vkd3d_shader_src_param *src_param;
struct vkd3d_shader_dst_param *dst_param;
const struct sm6_type *pointee_type;
const struct sm6_value *ptr, *src;
unsigned int i = 0, alignment;
uint64_t alignment_code;
if (!(ptr = sm6_parser_get_value_by_ref(sm6, record, NULL, &i))
|| !sm6_value_validate_is_register(ptr, sm6)
|| !sm6_value_validate_is_pointer(ptr, sm6))
{
return;
}
pointee_type = ptr->type->u.pointer.type;
if (!(src = sm6_parser_get_value_by_ref(sm6, record, pointee_type, &i)))
return;
if (!sm6_value_validate_is_numeric(src, sm6))
return;
if (pointee_type != src->type)
{
WARN("Type mismatch.\n");
vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH,
"Type mismatch in pointer store arguments.");
}
if (!dxil_record_validate_operand_count(record, i + 2, i + 2, sm6))
return;
alignment_code = record->operands[i++];
if (!bitcode_parse_alignment(alignment_code, &alignment))
WARN("Invalid alignment %"PRIu64".\n", alignment_code);
if (record->operands[i])
WARN("Ignoring volatile modifier.\n");
vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
src_param = instruction_src_params_alloc(ins, 1, sm6);
src_param_init_from_value(&src_param[0], src);
dst_param = instruction_dst_params_alloc(ins, 1, sm6);
dst_param_init(dst_param);
dst_param->reg = ptr->u.reg;
dst_param->reg.alignment = alignment;
}
static void sm6_parser_emit_vselect(struct sm6_parser *sm6, const struct dxil_record *record,
struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
{
......@@ -4630,6 +4722,9 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
record = block->records[i];
switch (record->code)
{
case FUNC_CODE_INST_ALLOCA:
sm6_parser_emit_alloca(sm6, record, ins, dst);
break;
case FUNC_CODE_INST_BINOP:
sm6_parser_emit_binop(sm6, record, ins, dst);
break;
......@@ -4656,6 +4751,9 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
is_terminator = true;
ret_found = true;
break;
case FUNC_CODE_INST_STORE:
sm6_parser_emit_store(sm6, record, ins, dst);
break;
case FUNC_CODE_INST_VSELECT:
sm6_parser_emit_vselect(sm6, record, ins, dst);
break;
......@@ -5040,7 +5138,7 @@ static const enum vkd3d_shader_sysval_semantic sysval_semantic_table[] =
{
[SEMANTIC_KIND_ARBITRARY] = VKD3D_SHADER_SV_NONE,
[SEMANTIC_KIND_POSITION] = VKD3D_SHADER_SV_POSITION,
[SEMANTIC_KIND_TARGET] = VKD3D_SHADER_SV_NONE,
[SEMANTIC_KIND_TARGET] = VKD3D_SHADER_SV_TARGET,
};
static enum vkd3d_shader_sysval_semantic sysval_semantic_from_dxil_semantic_kind(enum dxil_semantic_kind kind)
......@@ -6111,8 +6209,6 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t
"Out of memory emitting shader signature declarations.");
return VKD3D_ERROR_OUT_OF_MEMORY;
}
sm6_parser_emit_output_signature(sm6, output_signature);
sm6_parser_emit_input_signature(sm6, input_signature);
sm6->p.shader_desc.ssa_count = sm6->ssa_next_id;
......
This diff is collapsed.
......@@ -2544,6 +2544,16 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, const uint32_t
return true;
}
static void uninvert_used_masks(struct shader_signature *signature)
{
for (unsigned int i = 0; i < signature->element_count; ++i)
{
struct signature_element *e = &signature->elements[i];
e->used_mask = e->mask & ~e->used_mask;
}
}
static bool shader_sm4_parser_validate_signature(struct vkd3d_shader_sm4_parser *sm4,
const struct shader_signature *signature, unsigned int *masks, const char *name)
{
......@@ -2639,6 +2649,12 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi
return VKD3D_ERROR_INVALID_ARGUMENT;
}
/* DXBC stores used masks inverted for output signatures, for some reason.
* We return them un-inverted. */
uninvert_used_masks(&shader_desc->output_signature);
if (sm4->p.shader_version.type == VKD3D_SHADER_TYPE_HULL)
uninvert_used_masks(&shader_desc->patch_constant_signature);
if (!shader_sm4_parser_validate_signature(sm4, &shader_desc->input_signature,
sm4->input_register_masks, "Input")
|| !shader_sm4_parser_validate_signature(sm4, &shader_desc->output_signature,
......
......@@ -1546,7 +1546,7 @@ static int vkd3d_shader_parser_compile(struct vkd3d_shader_parser *parser,
switch (compile_info->target_type)
{
case VKD3D_SHADER_TARGET_D3D_ASM:
ret = vkd3d_dxbc_binary_to_text(&parser->instructions, &parser->shader_version, compile_info, out);
ret = vkd3d_dxbc_binary_to_text(&parser->instructions, &parser->shader_version, compile_info, out, VSIR_ASM_D3D);
break;
case VKD3D_SHADER_TARGET_GLSL:
......@@ -1623,7 +1623,7 @@ static int compile_d3d_bytecode(const struct vkd3d_shader_compile_info *compile_
if (compile_info->target_type == VKD3D_SHADER_TARGET_D3D_ASM)
{
ret = vkd3d_dxbc_binary_to_text(&parser->instructions, &parser->shader_version, compile_info, out);
ret = vkd3d_dxbc_binary_to_text(&parser->instructions, &parser->shader_version, compile_info, out, VSIR_ASM_D3D);
vkd3d_shader_parser_destroy(parser);
return ret;
}
......
......@@ -91,7 +91,7 @@ enum vkd3d_shader_error
VKD3D_SHADER_ERROR_SPV_INVALID_REGISTER_TYPE = 2001,
VKD3D_SHADER_ERROR_SPV_INVALID_DESCRIPTOR_BINDING = 2002,
VKD3D_SHADER_ERROR_SPV_DESCRIPTOR_IDX_UNSUPPORTED = 2003,
VKD3D_SHADER_ERROR_SPV_STENCIL_EXPORT_UNSUPPORTED = 2004,
VKD3D_SHADER_ERROR_SPV_UNSUPPORTED_FEATURE = 2004,
VKD3D_SHADER_ERROR_SPV_OUT_OF_MEMORY = 2005,
VKD3D_SHADER_ERROR_SPV_INVALID_TYPE = 2006,
VKD3D_SHADER_ERROR_SPV_INVALID_HANDLER = 2007,
......@@ -741,6 +741,7 @@ enum vkd3d_tessellator_domain
#define VKD3DSI_RESINFO_UINT 0x2
#define VKD3DSI_SAMPLE_INFO_UINT 0x1
#define VKD3DSI_SAMPLER_COMPARISON_MODE 0x1
#define VKD3DSI_SHIFT_UNMASKED 0x1
#define VKD3DSI_PRECISE_X 0x100
#define VKD3DSI_PRECISE_Y 0x200
......@@ -1314,9 +1315,15 @@ struct vkd3d_string_buffer_cache
size_t count, max_count, capacity;
};
enum vsir_asm_dialect
{
VSIR_ASM_VSIR,
VSIR_ASM_D3D,
};
enum vkd3d_result vkd3d_dxbc_binary_to_text(const struct vkd3d_shader_instruction_array *instructions,
const struct vkd3d_shader_version *shader_version, const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_code *out);
struct vkd3d_shader_code *out, enum vsir_asm_dialect dialect);
void vkd3d_string_buffer_cleanup(struct vkd3d_string_buffer *buffer);
struct vkd3d_string_buffer *vkd3d_string_buffer_get(struct vkd3d_string_buffer_cache *list);
void vkd3d_string_buffer_init(struct vkd3d_string_buffer *buffer);
......
......@@ -90,3 +90,53 @@ float4 main() : SV_TARGET
uniform 0 float4 1.0 0.0 0.0 0.0
draw quad
probe all rgba (1e99, 1e99, 1e99, 1e99)
[require]
shader model >= 5.0
float64
[pixel shader todo]
uniform double2 a;
float4 main() : SV_TARGET
{
double x = a.x;
double y = a.y;
return float4(x + y, x - y, x * y, x / y);
}
[test]
uniform 0 double2 7.5 -2.5
todo(sm<6) draw quad
probe all rgba (5.0, 10.0, -18.75, -3.0)
[pixel shader todo]
uniform double2 a;
float4 main() : SV_TARGET
{
double x = a.x;
double y = a.y;
return x * y;
}
[test]
uniform 0 double2 3.0e-300 2.5e300
todo(sm<6) draw quad
probe all rgba (7.5, 7.5, 7.5, 7.5)
% Note: DXC does not support modulo on doubles.
[pixel shader todo]
uniform double2 a;
float4 main() : SV_TARGET
{
double x = a.x;
double y = a.y;
return x / y;
}
[test]
uniform 0 double2 1.5e300 2.0e299
todo(sm<6) draw quad
probe all rgba (7.5, 7.5, 7.5, 7.5)
......@@ -119,3 +119,80 @@ uniform 0 float4 45.0 5.0 50.0 10.0
uniform 4 float4 3.0 8.0 2.0 5.0
draw quad
probe all rgba (9.0, 5.0, 1.0, 3.0)
[require]
shader model >= 6.0
int64
[pixel shader]
uniform int64_t2 a;
float4 main() : SV_TARGET
{
int64_t x = a.x;
int64_t y = a.y;
return float4(x + y, x - y, x * (y >> 4), x / y);
}
[test]
uniform 0 int64_t2 5000000000 16000000000
todo draw quad
probe all rgba (21.0e9, -11.0e9, 5.0e18, 0.0) 1
[pixel shader]
uniform int64_t2 a;
float4 main() : SV_TARGET
{
int64_t x = a.x;
int64_t y = a.y;
return float4(x % y, +x, -x, y / x);
}
[test]
uniform 0 int64_t2 5000000000 16000000000
todo draw quad
probe all rgba (5.0e9, 5.0e9, -5.0e9, 3.0)
[pixel shader]
uniform int64_t2 a;
float4 main() : SV_TARGET
{
int64_t x = a.x;
int64_t y = a.y;
return float4(x / y, -x / y, x / -y, -x / -y);
}
[test]
uniform 0 int64_t2 42000000000 5000000000
todo draw quad
probe all rgba (8.0, -8.0, -8.0, 8.0)
[pixel shader]
uniform int64_t2 a;
float4 main() : SV_TARGET
{
int64_t x = a.x;
int64_t y = a.y;
return float4(x % y, -x % y, x % -y, -x % -y);
}
[test]
uniform 0 int64_t2 42000000000 5000000000
todo draw quad
probe all rgba (2.0e9, -2.0e9, 2.0e9, -2.0e9)
[pixel shader]
uniform int64_t2 a;
float4 main() : SV_TARGET
{
return float4(abs(a), 0, 0);
}
[test]
uniform 0 int64_t2 5000000000 -7000000000
todo draw quad
probe all rgba (5.0, 7.0, 0.0, 10.0)
......@@ -160,3 +160,88 @@ float4 main() : SV_TARGET
[test]
draw quad
probe all rgba (0.0, 1.0, 1.0, 0.0)
[require]
shader model >= 6.0
int64
[pixel shader]
int64_t2 a;
int2 s;
float4 main() : sv_target
{
int64_t x = a.x;
int64_t y = a.y;
int z = s.x;
int w = s.y;
return float4(x >> y, x >> -y, x >> z, x >> w);
}
[test]
uniform 0 int64_t2 9223372036854775807 -1
uniform 4 int4 34 66 0 0
todo draw quad
probe all rgba (0.0, 4.611686018e18, 536870912.0, 2.305843009e18) 1
uniform 0 int64_t2 -1 -1
uniform 4 int4 34 66 0 0
todo draw quad
probe all rgba (-1.0, -1.0, -1.0, -1.0) 1
[pixel shader]
uint64_t2 a;
uint2 s;
float4 main() : sv_target
{
uint64_t x = a.x;
uint64_t y = a.y;
uint z = s.x;
uint w = s.y;
return float4(x >> y, x >> -y, x >> z, x >> w);
}
[test]
uniform 0 uint64_t2 0xffffffffffffffff 1
uniform 4 uint4 34 66 0 0
todo draw quad
probe all rgba (9.223372036e18, 1.0, 1073741823.0, 4.611686018e18) 1
[pixel shader]
uint64_t2 a;
uint2 s;
float4 main() : sv_target
{
uint64_t x = a.x;
uint64_t y = a.y;
uint z = s.x;
uint w = s.y;
return float4(x << y, x << -y, x << z, x << w);
}
[test]
uniform 0 uint64_t2 0x83 1
uniform 4 uint4 34 66 0 0
todo draw quad
probe all rgba (262.0, 9.223372036e18, 2250562863104.0, 524.0) 1
[pixel shader]
uint64_t2 a;
float4 main() : sv_target
{
uint64_t x = a.x;
uint64_t y = a.y;
return float4(x ^ y, x & y, x | y, ~x);
}
[test]
uniform 0 uint64_t2 0x300000000 0x500000000
todo draw quad
probe all rgba (25769803776.0, 4294967296.0, 30064771072.0, 1.844674404e19) 1
[require]
shader model >= 5.0
float64
[pixel shader todo]
uniform double2 d;
......@@ -20,6 +21,7 @@ probe all rgba (-4.5, 8.5, 2.0, 2.0)
[require]
shader model >= 6.0
int64
[pixel shader]
uniform uint64_t2 l;
......
......@@ -26,7 +26,7 @@ float4 main() : sv_target
uniform 0 float4 1.0 2.0 3.0 4.0
uniform 4 float4 5.0 6.0 7.0 8.0
uniform 8 float 2
todo(sm>=6) draw quad
draw quad
probe all rgba (10.0, 10.0, 10.0, 10.0)
......@@ -56,10 +56,10 @@ float4 main() : sv_target
[test]
uniform 0 float4 1.0 2.0 3.0 4.0
uniform 4 float 0
todo(sm>=6) draw quad
draw quad
probe all rgba (4.0, 4.0, 4.0, 4.0)
uniform 4 float 2
todo(sm>=6) draw quad
draw quad
probe all rgba (1.0, 1.0, 1.0, 1.0)
......@@ -99,5 +99,5 @@ float4 main() : sv_target
[test]
uniform 0 float4 1.0 2.0 3.0 4.0
uniform 4 float 1
todo(sm>=6) draw quad
draw quad
probe all rgba (2.0, 2.0, 2.0, 2.0)
......@@ -155,16 +155,16 @@ float4 main() : sv_target
[test]
uniform 0 int 0
uniform 1 int 0
todo(sm>=6) draw quad
todo(sm>=6) probe all rgba (100, 6, 7, 8)
draw quad
probe all rgba (100, 6, 7, 8)
uniform 0 int 2
uniform 1 int 2
todo(sm>=6) draw quad
todo(sm>=6) probe all rgba (5, 6, 100, 8)
draw quad
probe all rgba (5, 6, 100, 8)
uniform 0 int 1
uniform 1 int 3
todo(sm>=6) draw quad
todo(sm>=6) probe all rgba (5, 6, 7, 4)
draw quad
probe all rgba (5, 6, 7, 4)
[pixel shader]
......@@ -192,5 +192,82 @@ uniform 0 float4 1 2 3 4
uniform 4 float4 5 6 7 8
uniform 8 int 3
uniform 9 int 4
todo(sm>=6) draw quad
todo(sm>=6) probe all rgba (1126, 3344, 5566, 3788)
draw quad
probe all rgba (1126, 3344, 5566, 3788)
[pixel shader]
uint i, j;
float4 main() : sv_target
{
float mut1[4] = {1, 2, 3, 4};
/* dxc emits a pointer bitcast, which results in a VSIR MOV with mismatched data types. */
mut1[i] = asfloat(j);
return float4(mut1[0], mut1[1], mut1[2], mut1[3]);
}
[test]
uniform 0 uint 1
uniform 1 uint 0x40a00000
draw quad
probe all rgba (1, 5, 3, 4)
[pixel shader]
uniform float4 f[4];
uniform uint4 u;
uniform uint4 v;
float4 main() : sv_target
{
float temp[4];
temp[0] = f[u.x].x;
temp[1] = f[u.y].x;
temp[2] = f[u.z].x;
temp[3] = f[u.w].x;
return float4(temp[v.x], temp[v.y], temp[v.z], temp[v.w]);
}
% FXC is incapable of compiling this correctly, but results differ for SM1-3 vs SM4-5.
[require]
shader model < 4.0
[test]
uniform 0 float 1.0
uniform 4 float 2.0
uniform 8 float 3.0
uniform 12 float 4.0
uniform 16 uint4 3 1 0 2
uniform 20 uint4 0 3 1 2
draw quad
todo probe all rgba (1.0, 1.0, 1.0, 1.0)
[require]
shader model >= 4.0
shader model < 6.0
[test]
uniform 0 float 1.0
uniform 4 float 2.0
uniform 8 float 3.0
uniform 12 float 4.0
uniform 16 uint4 3 1 0 2
uniform 20 uint4 0 3 1 2
draw quad
todo probe all rgba (4.0, 4.0, 4.0, 4.0)
[require]
shader model >= 6.0
[test]
uniform 0 float 1.0
uniform 4 float 2.0
uniform 8 float 3.0
uniform 12 float 4.0
uniform 16 uint4 3 1 0 2
uniform 20 uint4 0 3 1 2
draw quad
probe all rgba (4.0, 3.0, 2.0, 1.0)
......@@ -191,6 +191,14 @@ static void parse_require_directive(struct shader_runner *runner, const char *li
runner->compile_options |= options[i].option;
}
}
else if (match_string(line, "float64", &line))
{
runner->require_float64 = true;
}
else if (match_string(line, "int64", &line))
{
runner->require_int64 = true;
}
else
{
fatal_error("Unknown require directive '%s'.\n", line);
......@@ -1311,6 +1319,8 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_o
state = STATE_REQUIRE;
runner->minimum_shader_model = minimum_shader_model;
runner->maximum_shader_model = maximum_shader_model;
runner->require_float64 = false;
runner->require_int64 = false;
runner->compile_options = 0;
skip_tests = false;
}
......
......@@ -122,6 +122,8 @@ struct shader_runner
char *fx_source;
enum shader_model minimum_shader_model;
enum shader_model maximum_shader_model;
bool require_float64;
bool require_int64;
bool last_render_failed;
......
......@@ -52,6 +52,9 @@ struct d3d12_shader_runner
ID3D12GraphicsCommandList *compute_list;
IDxcCompiler3 *dxc_compiler;
D3D12_FEATURE_DATA_D3D12_OPTIONS options;
D3D12_FEATURE_DATA_D3D12_OPTIONS1 options1;
};
static struct d3d12_shader_runner *d3d12_shader_runner(struct shader_runner *r)
......@@ -96,6 +99,19 @@ static ID3D10Blob *compile_shader(const struct d3d12_shader_runner *runner, cons
return blob;
}
static bool d3d12_runner_check_requirements(struct shader_runner *r)
{
struct d3d12_shader_runner *runner = d3d12_shader_runner(r);
if (runner->r.require_float64 && !runner->options.DoublePrecisionFloatShaderOps)
return false;
if (runner->r.require_int64 && !runner->options1.Int64ShaderOps)
return false;
return true;
}
#define MAX_RESOURCE_DESCRIPTORS (MAX_RESOURCES * 2)
static struct resource *d3d12_runner_create_resource(struct shader_runner *r, const struct resource_params *params)
......@@ -561,6 +577,7 @@ static void d3d12_runner_release_readback(struct shader_runner *r, struct resour
static const struct shader_runner_ops d3d12_runner_ops =
{
.check_requirements = d3d12_runner_check_requirements,
.create_resource = d3d12_runner_create_resource,
.destroy_resource = d3d12_runner_destroy_resource,
.dispatch = d3d12_runner_dispatch,
......@@ -602,6 +619,17 @@ void run_shader_tests_d3d12(void *dxc_compiler, enum shader_model minimum_shader
runner.compute_allocator, NULL, &IID_ID3D12GraphicsCommandList, (void **)&runner.compute_list);
ok(hr == S_OK, "Failed to create command list, hr %#x.\n", hr);
hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_D3D12_OPTIONS,
&runner.options, sizeof(runner.options));
ok(hr == S_OK, "Failed to check feature options support, hr %#x.\n", hr);
trace("DoublePrecisionFloatShaderOps: %u.\n", runner.options.DoublePrecisionFloatShaderOps);
hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_D3D12_OPTIONS1,
&runner.options1, sizeof(runner.options1));
ok(hr == S_OK, "Failed to check feature options1 support, hr %#x.\n", hr);
if (maximum_shader_model >= SHADER_MODEL_6_0)
trace("Int64ShaderOps: %u.\n", runner.options1.Int64ShaderOps);
run_shader_tests(&runner.r, &d3d12_runner_ops, dxc_compiler, minimum_shader_model, maximum_shader_model);
ID3D12GraphicsCommandList_Release(runner.compute_list);
......