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 (11)
Showing
with 592 additions and 12 deletions
......@@ -65,6 +65,7 @@
#define TAG_SDBG VKD3D_MAKE_TAG('S', 'D', 'B', 'G')
#define TAG_SHDR VKD3D_MAKE_TAG('S', 'H', 'D', 'R')
#define TAG_SHEX VKD3D_MAKE_TAG('S', 'H', 'E', 'X')
#define TAG_STAT VKD3D_MAKE_TAG('S', 'T', 'A', 'T')
#define TAG_TEXT VKD3D_MAKE_TAG('T', 'E', 'X', 'T')
#define TAG_XNAP VKD3D_MAKE_TAG('X', 'N', 'A', 'P')
#define TAG_XNAS VKD3D_MAKE_TAG('X', 'N', 'A', 'S')
......
......@@ -79,6 +79,16 @@ typedef enum D3D_BLOB_PART
D3D_BLOB_TEST_COMPILE_REPORT
} D3D_BLOB_PART;
typedef enum D3DCOMPILER_STRIP_FLAGS
{
D3DCOMPILER_STRIP_REFLECTION_DATA = 0x00000001,
D3DCOMPILER_STRIP_DEBUG_INFO = 0x00000002,
D3DCOMPILER_STRIP_TEST_BLOBS = 0x00000004,
D3DCOMPILER_STRIP_PRIVATE_DATA = 0x00000008,
D3DCOMPILER_STRIP_ROOT_SIGNATURE = 0x00000010,
D3DCOMPILER_STRIP_FORCE_DWORD = 0x7fffffff,
} D3DCOMPILER_STRIP_FLAGS;
HRESULT WINAPI D3DCompile(const void *data, SIZE_T data_size, const char *filename,
const D3D_SHADER_MACRO *macros, ID3DInclude *include, const char *entrypoint,
const char *profile, UINT flags, UINT effect_flags, ID3DBlob **shader, ID3DBlob **error_messages);
......@@ -95,6 +105,7 @@ HRESULT WINAPI D3DGetInputSignatureBlob(const void *data, SIZE_T data_size, ID3D
HRESULT WINAPI D3DGetOutputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob);
HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, const char *filename, const D3D_SHADER_MACRO *macros,
ID3DInclude *include, ID3DBlob **shader, ID3DBlob **error_messages);
HRESULT WINAPI D3DStripShader(const void *data, SIZE_T data_size, UINT flags, ID3DBlob **blob);
#endif /* __D3DCOMPILER_H__ */
#endif /* __VKD3D_D3DCOMPILER_H */
......@@ -154,6 +154,25 @@ enum vkd3d_shader_compile_option_pack_matrix_order
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ORDER),
};
/** Individual options to enable various backward compatibility features. \since 1.10 */
enum vkd3d_shader_compile_option_backward_compatibility
{
/**
* Causes compiler to convert SM1-3 semantics to corresponding System Value semantics,
* when compiling HLSL sources for SM4+ targets.
*
* This option does the following conversions:
*
* - POSITION to SV_Position for vertex shader outputs, pixel shader inputs,
* and geometry shader inputs and outputs;
* - COLORN to SV_TargetN for pixel shader outputs;
* - DEPTH to SV_Depth for pixel shader outputs.
*/
VKD3D_SHADER_COMPILE_OPTION_BACKCOMPAT_MAP_SEMANTIC_NAMES = 0x00000001,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_BACKWARD_COMPATIBILITY),
};
enum vkd3d_shader_compile_option_name
{
/**
......@@ -193,6 +212,14 @@ enum vkd3d_shader_compile_option_name
* \since 1.9
*/
VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ORDER = 0x00000007,
/**
* This option is used to enable various backward compatibility features.
*
* \a value is a mask of values from enum vkd3d_shader_compile_option_backward_compatibility.
*
* \since 1.10
*/
VKD3D_SHADER_COMPILE_OPTION_BACKWARD_COMPATIBILITY = 0x00000008,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_NAME),
};
......
......@@ -115,6 +115,8 @@ VKD3D_UTILS_API HRESULT WINAPI D3DGetInputAndOutputSignatureBlob(const void *dat
VKD3D_UTILS_API HRESULT WINAPI D3DGetInputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob);
/** \since 1.10 */
VKD3D_UTILS_API HRESULT WINAPI D3DGetOutputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob);
/** \since 1.10 */
VKD3D_UTILS_API HRESULT WINAPI D3DStripShader(const void *data, SIZE_T data_size, UINT flags, ID3DBlob **blob);
#ifdef __cplusplus
}
......
......@@ -1626,8 +1626,10 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
case VKD3DSIH_DCL_CONSTANT_BUFFER:
vkd3d_string_buffer_printf(buffer, " ");
shader_dump_register(compiler, &ins->declaration.cb.src.reg, true);
if (shader_ver_ge(&compiler->shader_version, 5, 1))
if (shader_ver_ge(&compiler->shader_version, 6, 0))
shader_print_subscript(compiler, ins->declaration.cb.size, NULL);
else if (shader_ver_ge(&compiler->shader_version, 5, 1))
shader_print_subscript(compiler, ins->declaration.cb.size / VKD3D_VEC4_SIZE / sizeof(float), NULL);
shader_addline(buffer, ", %s",
ins->flags & VKD3DSI_INDEXED_DYNAMIC ? "dynamicIndexed" : "immediateIndexed");
shader_dump_register_space(compiler, ins->declaration.cb.range.space);
......
......@@ -25,6 +25,7 @@
#define BITCODE_MAGIC VKD3D_MAKE_TAG('B', 'C', 0xc0, 0xde)
#define DXIL_OP_MAX_OPERANDS 17
static const unsigned int SHADER_DESCRIPTOR_TYPE_COUNT = 4;
static const unsigned int dx_max_thread_group_size[3] = {1024, 1024, 64};
......@@ -2820,6 +2821,11 @@ static bool sm6_metadata_value_is_node(const struct sm6_metadata_value *m)
return m && m->type == VKD3D_METADATA_NODE;
}
static bool sm6_metadata_value_is_value(const struct sm6_metadata_value *m)
{
return m && m->type == VKD3D_METADATA_VALUE;
}
static bool sm6_metadata_value_is_string(const struct sm6_metadata_value *m)
{
return m && m->type == VKD3D_METADATA_STRING;
......@@ -3374,6 +3380,203 @@ static const struct sm6_metadata_value *sm6_parser_find_named_metadata(struct sm
return NULL;
}
static bool sm6_parser_resources_load_register_range(struct sm6_parser *sm6,
const struct sm6_metadata_node *node, struct vkd3d_shader_register_range *range)
{
unsigned int size;
if (!sm6_metadata_value_is_value(node->operands[1]))
{
WARN("Resource data type is not a value.\n");
return false;
}
if (!sm6_type_is_pointer(node->operands[1]->value_type))
{
WARN("Resource type is not a pointer.\n");
vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH,
"Resource metadata value type is not a pointer.");
}
if (!sm6_metadata_get_uint_value(sm6, node->operands[3], &range->space))
{
WARN("Failed to load register space.\n");
return false;
}
if (!sm6_metadata_get_uint_value(sm6, node->operands[4], &range->first))
{
WARN("Failed to load register first.\n");
return false;
}
if (!sm6_metadata_get_uint_value(sm6, node->operands[5], &size))
{
WARN("Failed to load register range size.\n");
return false;
}
if (!size || (size != UINT_MAX && !vkd3d_bound_range(range->first, size, UINT_MAX)))
{
WARN("Invalid register range, first %u, size %u.\n", range->first, size);
return false;
}
range->last = (size == UINT_MAX) ? UINT_MAX : range->first + size - 1;
return true;
}
static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6,
const struct sm6_metadata_node *node, const struct vkd3d_shader_register_range *range,
unsigned int register_id, struct vkd3d_shader_instruction *ins)
{
struct vkd3d_shader_register *reg;
unsigned int buffer_size;
if (node->operand_count < 7)
{
WARN("Invalid operand count %u.\n", node->operand_count);
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT,
"Invalid operand count %u for a CBV descriptor.", node->operand_count);
return VKD3D_ERROR_INVALID_SHADER;
}
if (node->operand_count > 7 && node->operands[7])
{
WARN("Ignoring %u extra operands.\n", node->operand_count - 7);
vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS,
"Ignoring %u extra operands for a CBV descriptor.", node->operand_count - 7);
}
if (!sm6_metadata_get_uint_value(sm6, node->operands[6], &buffer_size))
{
WARN("Failed to load buffer size.\n");
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES,
"Constant buffer size metadata value is not an integer.");
return VKD3D_ERROR_INVALID_SHADER;
}
vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_DCL_CONSTANT_BUFFER);
ins->resource_type = VKD3D_SHADER_RESOURCE_BUFFER;
ins->declaration.cb.size = buffer_size;
ins->declaration.cb.src.swizzle = VKD3D_SHADER_NO_SWIZZLE;
ins->declaration.cb.src.modifiers = VKD3DSPSM_NONE;
reg = &ins->declaration.cb.src.reg;
vsir_register_init(reg, VKD3DSPR_CONSTBUFFER, VKD3D_DATA_FLOAT, 3);
reg->idx[0].offset = register_id;
reg->idx[1].offset = range->first;
reg->idx[2].offset = range->last;
ins->declaration.cb.range = *range;
return VKD3D_OK;
}
static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6,
enum vkd3d_shader_descriptor_type type, const struct sm6_metadata_node *descriptor_node)
{
struct vkd3d_shader_register_range range;
struct vkd3d_shader_instruction *ins;
const struct sm6_metadata_node *node;
const struct sm6_metadata_value *m;
unsigned int i, register_id;
enum vkd3d_result ret;
for (i = 0; i < descriptor_node->operand_count; ++i)
{
m = descriptor_node->operands[i];
if (!sm6_metadata_value_is_node(m))
{
WARN("Resource descriptor is not a node.\n");
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES,
"Resource descriptor is not a metadata node.");
return VKD3D_ERROR_INVALID_SHADER;
}
node = m->u.node;
if (node->operand_count < 6)
{
WARN("Invalid operand count %u.\n", node->operand_count);
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT,
"Invalid operand count %u for a descriptor.", node->operand_count);
return VKD3D_ERROR_INVALID_SHADER;
}
if (!sm6_metadata_get_uint_value(sm6, node->operands[0], &register_id))
{
WARN("Failed to load resource id.\n");
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES,
"Resource id metadata value is not an integer.");
return VKD3D_ERROR_INVALID_SHADER;
}
if (!sm6_parser_resources_load_register_range(sm6, node, &range))
{
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES,
"Resource register range is invalid.");
return VKD3D_ERROR_INVALID_SHADER;
}
if (!(ins = sm6_parser_require_space(sm6, 1)))
{
ERR("Failed to allocate instruction.\n");
return VKD3D_ERROR_OUT_OF_MEMORY;
}
switch (type)
{
case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV:
if ((ret = sm6_parser_resources_load_cbv(sm6, node, &range, register_id, ins)) < 0)
return ret;
break;
default:
FIXME("Unsupported descriptor type %u.\n", type);
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES,
"Resource descriptor type %u is unsupported.", type);
return VKD3D_ERROR_INVALID_SHADER;
}
++sm6->p.instructions.count;
}
return VKD3D_OK;
}
static enum vkd3d_result sm6_parser_resources_init(struct sm6_parser *sm6)
{
const struct sm6_metadata_value *m = sm6_parser_find_named_metadata(sm6, "dx.resources");
enum vkd3d_shader_descriptor_type type;
const struct sm6_metadata_node *node;
enum vkd3d_result ret;
if (!m)
return VKD3D_OK;
node = m->u.node;
if (node->operand_count != SHADER_DESCRIPTOR_TYPE_COUNT)
{
WARN("Unexpected descriptor type count %u.\n", node->operand_count);
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES,
"Descriptor type count %u is invalid.", node->operand_count);
return VKD3D_ERROR_INVALID_SHADER;
}
for (type = 0; type < SHADER_DESCRIPTOR_TYPE_COUNT; ++type)
{
if (!(m = node->operands[type]))
continue;
if (!sm6_metadata_value_is_node(m))
{
WARN("Resource list is not a node.\n");
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES,
"Resource list is not a metadata node.");
return VKD3D_ERROR_INVALID_SHADER;
}
if ((ret = sm6_parser_descriptor_type_init(sm6, type, m->u.node)) < 0)
return ret;
}
return VKD3D_OK;
}
static void signature_element_read_additional_element_values(struct signature_element *e,
const struct sm6_metadata_node *node, struct sm6_parser *sm6)
{
......@@ -4176,6 +4379,9 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t
if ((ret = sm6_parser_entry_point_init(sm6)) < 0)
return ret;
if ((ret = sm6_parser_resources_init(sm6)) < 0)
return ret;
if ((ret = sm6_parser_module_init(sm6, &sm6->root_block, 0)) < 0)
{
if (ret == VKD3D_ERROR_OUT_OF_MEMORY)
......
......@@ -3421,6 +3421,10 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil
else if (option->value == VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_COLUMN_MAJOR)
ctx->matrix_majority = HLSL_MODIFIER_COLUMN_MAJOR;
}
else if (option->name == VKD3D_SHADER_COMPILE_OPTION_BACKWARD_COMPATIBILITY)
{
ctx->semantic_compat_mapping = option->value & VKD3D_SHADER_COMPILE_OPTION_BACKCOMPAT_MAP_SEMANTIC_NAMES;
}
}
return true;
......
......@@ -862,6 +862,8 @@ struct hlsl_ctx
uint32_t in_state_block : 1;
/* Whether the numthreads() attribute has been provided in the entry-point function. */
uint32_t found_numthreads : 1;
bool semantic_compat_mapping;
};
struct hlsl_resource_load_params
......
......@@ -109,7 +109,9 @@ register {return KW_REGISTER; }
RWBuffer {return KW_RWBUFFER; }
RWStructuredBuffer {return KW_RWSTRUCTUREDBUFFER; }
RWTexture1D {return KW_RWTEXTURE1D; }
RWTexture1DArray {return KW_RWTEXTURE1DARRAY; }
RWTexture2D {return KW_RWTEXTURE2D; }
RWTexture2DArray {return KW_RWTEXTURE2DARRAY; }
RWTexture3D {return KW_RWTEXTURE3D; }
sampler {return KW_SAMPLER; }
sampler1D {return KW_SAMPLER1D; }
......
......@@ -4722,7 +4722,9 @@ static struct hlsl_scope *get_loop_scope(struct hlsl_scope *scope)
%token KW_RWBUFFER
%token KW_RWSTRUCTUREDBUFFER
%token KW_RWTEXTURE1D
%token KW_RWTEXTURE1DARRAY
%token KW_RWTEXTURE2D
%token KW_RWTEXTURE2DARRAY
%token KW_RWTEXTURE3D
%token KW_SAMPLER
%token KW_SAMPLER1D
......@@ -5547,10 +5549,18 @@ uav_type:
{
$$ = HLSL_SAMPLER_DIM_1D;
}
| KW_RWTEXTURE1DARRAY
{
$$ = HLSL_SAMPLER_DIM_1DARRAY;
}
| KW_RWTEXTURE2D
{
$$ = HLSL_SAMPLER_DIM_2D;
}
| KW_RWTEXTURE2DARRAY
{
$$ = HLSL_SAMPLER_DIM_2DARRAY;
}
| KW_RWTEXTURE3D
{
$$ = HLSL_SAMPLER_DIM_3D;
......@@ -5697,7 +5707,9 @@ type_no_void:
{
case HLSL_SAMPLER_DIM_BUFFER:
case HLSL_SAMPLER_DIM_1D:
case HLSL_SAMPLER_DIM_1DARRAY:
case HLSL_SAMPLER_DIM_2D:
case HLSL_SAMPLER_DIM_2DARRAY:
case HLSL_SAMPLER_DIM_3D:
if ($3->class == HLSL_CLASS_ARRAY)
{
......
......@@ -5639,7 +5639,8 @@ static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler,
reg.idx[1].offset = range->first;
reg.idx[2].offset = range->last;
size = size_in_bytes / (VKD3D_VEC4_SIZE * sizeof(uint32_t));
size = align(size_in_bytes, VKD3D_VEC4_SIZE * sizeof(uint32_t));
size /= VKD3D_VEC4_SIZE * sizeof(uint32_t);
if ((push_cb = spirv_compiler_find_push_constant_buffer(compiler, range)))
{
......
......@@ -884,6 +884,8 @@ static void shader_sm4_read_dcl_constant_buffer(struct vkd3d_shader_instruction
ins->declaration.cb.size = *tokens++;
shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.cb.range.space);
}
ins->declaration.cb.size *= VKD3D_VEC4_SIZE * sizeof(float);
}
static void shader_sm4_read_dcl_sampler(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token,
......@@ -2762,20 +2764,21 @@ bool hlsl_sm4_usage_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semant
{"position", true, VKD3D_SHADER_TYPE_VERTEX, D3D_NAME_POSITION},
{"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, D3D_NAME_POSITION},
};
bool needs_compat_mapping = ascii_strncasecmp(semantic->name, "sv_", 3);
for (i = 0; i < ARRAY_SIZE(semantics); ++i)
{
if (!ascii_strcasecmp(semantic->name, semantics[i].name)
&& output == semantics[i].output
&& ctx->profile->type == semantics[i].shader_type
&& !ascii_strncasecmp(semantic->name, "sv_", 3))
&& (ctx->semantic_compat_mapping == needs_compat_mapping || !needs_compat_mapping)
&& ctx->profile->type == semantics[i].shader_type)
{
*usage = semantics[i].usage;
return true;
}
}
if (!ascii_strncasecmp(semantic->name, "sv_", 3))
if (!needs_compat_mapping)
return false;
*usage = D3D_NAME_UNDEFINED;
......
......@@ -817,7 +817,7 @@ static void vkd3d_shader_scan_constant_buffer_declaration(struct vkd3d_shader_sc
if (!(d = vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV,
&cb->src.reg, &cb->range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT)))
return;
d->buffer_size = cb->size * 16;
d->buffer_size = cb->size;
}
static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_context *context,
......
......@@ -180,6 +180,7 @@ enum vkd3d_shader_error
VKD3D_SHADER_ERROR_DXIL_INVALID_ENTRY_POINT = 8015,
VKD3D_SHADER_ERROR_DXIL_INVALID_SIGNATURE = 8016,
VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES = 8017,
VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES = 8018,
VKD3D_SHADER_WARNING_DXIL_UNKNOWN_MAGIC_NUMBER = 8300,
VKD3D_SHADER_WARNING_DXIL_UNKNOWN_SHADER_TYPE = 8301,
......
......@@ -17,6 +17,7 @@ global:
D3DGetInputSignatureBlob;
D3DGetOutputSignatureBlob;
D3DPreprocess;
D3DStripShader;
vkd3d_create_event;
vkd3d_destroy_event;
vkd3d_signal_event;
......
......@@ -187,7 +187,7 @@ HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filen
{
struct vkd3d_shader_preprocess_info preprocess_info;
struct vkd3d_shader_hlsl_source_info hlsl_info;
struct vkd3d_shader_compile_option options[3];
struct vkd3d_shader_compile_option options[4];
struct vkd3d_shader_compile_info compile_info;
struct vkd3d_shader_compile_option *option;
struct vkd3d_shader_code byte_code;
......@@ -302,6 +302,13 @@ HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filen
option->value |= VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_COLUMN_MAJOR;
}
if (flags & D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY)
{
option = &options[compile_info.option_count++];
option->name = VKD3D_SHADER_COMPILE_OPTION_BACKWARD_COMPATIBILITY;
option->value = VKD3D_SHADER_COMPILE_OPTION_BACKCOMPAT_MAP_SEMANTIC_NAMES;
}
ret = vkd3d_shader_compile(&compile_info, &byte_code, &messages);
if (messages && messages_blob)
......@@ -787,6 +794,100 @@ HRESULT WINAPI D3DGetOutputSignatureBlob(const void *data, SIZE_T data_size, ID3
return get_blob_part(data, data_size, D3D_BLOB_OUTPUT_SIGNATURE_BLOB, 0, blob);
}
static bool check_blob_strip(uint32_t tag, uint32_t flags)
{
bool add = true;
switch (tag)
{
case TAG_RDEF:
case TAG_STAT:
if (flags & D3DCOMPILER_STRIP_REFLECTION_DATA)
add = false;
break;
case TAG_SDBG:
if (flags & D3DCOMPILER_STRIP_DEBUG_INFO)
add = false;
break;
default:
break;
}
TRACE("%s tag %s.\n", add ? "Add" : "Skip", debugstr_an((const char *)&tag, 4));
return add;
}
HRESULT WINAPI D3DStripShader(const void *data, SIZE_T data_size, UINT flags, ID3DBlob **blob)
{
const struct vkd3d_shader_code src_dxbc = {.code = data, .size = data_size};
struct vkd3d_shader_dxbc_section_desc *sections;
struct vkd3d_shader_dxbc_desc src_dxbc_desc;
struct vkd3d_shader_code dst_dxbc;
unsigned int section_count, i;
HRESULT hr;
int ret;
TRACE("data %p, data_size %lu, flags %#x, blob %p.\n", data, data_size, flags, blob);
if (!blob)
{
WARN("Invalid 'blob' pointer specified.\n");
return E_FAIL;
}
if (!data || !data_size)
{
WARN("Invalid arguments: data %p, data_size %lu.\n", data, data_size);
return D3DERR_INVALIDCALL;
}
if ((ret = vkd3d_shader_parse_dxbc(&src_dxbc, 0, &src_dxbc_desc, NULL)) < 0)
{
WARN("Failed to parse source data, ret %d.\n", ret);
return D3DERR_INVALIDCALL;
}
if (!(sections = vkd3d_calloc(src_dxbc_desc.section_count, sizeof(*sections))))
{
ERR("Failed to allocate sections memory.\n");
vkd3d_shader_free_dxbc(&src_dxbc_desc);
return E_OUTOFMEMORY;
}
if (flags & ~(D3DCOMPILER_STRIP_REFLECTION_DATA | D3DCOMPILER_STRIP_DEBUG_INFO))
FIXME("Unhandled flags %#x.\n", flags);
for (i = 0, section_count = 0; i < src_dxbc_desc.section_count; ++i)
{
const struct vkd3d_shader_dxbc_section_desc *src_section = &src_dxbc_desc.sections[i];
if (check_blob_strip(src_section->tag, flags))
sections[section_count++] = *src_section;
}
if ((ret = vkd3d_shader_serialize_dxbc(section_count, sections, &dst_dxbc, NULL) < 0))
{
WARN("Failed to serialise DXBC, ret %d.\n", ret);
hr = hresult_from_vkd3d_result(ret);
goto done;
}
if (FAILED(hr = D3DCreateBlob(dst_dxbc.size, blob)))
WARN("Failed to create blob, hr %#x.\n", hr);
else
memcpy(ID3D10Blob_GetBufferPointer(*blob), dst_dxbc.code, dst_dxbc.size);
vkd3d_shader_free_shader_code(&dst_dxbc);
done:
vkd3d_free(sections);
vkd3d_shader_free_dxbc(&src_dxbc_desc);
return hr;
}
void vkd3d_utils_set_log_callback(PFN_vkd3d_log callback)
{
vkd3d_set_log_callback(callback);
......
......@@ -35,8 +35,6 @@
#include <term.h>
#endif
#define MAX_COMPILE_OPTIONS 5
enum
{
OPTION_HELP = CHAR_MAX + 1,
......@@ -47,6 +45,7 @@ enum
OPTION_PRINT_SOURCE_TYPES,
OPTION_PRINT_TARGET_TYPES,
OPTION_PROFILE,
OPTION_SEMANTIC_COMPAT_MAP,
OPTION_STRIP_DEBUG,
OPTION_VERSION,
OPTION_TEXT_FORMATTING,
......@@ -186,6 +185,8 @@ static void print_usage(const char *program_name)
" --matrix-storage-order=<order>\n"
" Specify default matrix storage order. Valid values are\n"
" 'column' (default) and 'row'.\n"
" --semantic-compat-map Enable semantic mapping compatibility mode to use SM4+ system values\n"
" instead of SM1-3 style semantic names when compiling from HLSL sources.\n"
" -e, --entry=<name> Use <name> as the entry point (default is \"main\").\n"
" -E Preprocess the source code instead of compiling it.\n"
" -o, --output=<file> Write the output to <file>. If <file> is '-' or no\n"
......@@ -230,7 +231,7 @@ struct options
uint32_t formatting;
bool explicit_colour;
struct vkd3d_shader_compile_option compile_options[MAX_COMPILE_OPTIONS];
struct vkd3d_shader_compile_option *compile_options;
unsigned int compile_option_count;
};
......@@ -239,6 +240,7 @@ static void add_compile_option(struct options *options,
{
struct vkd3d_shader_compile_option *o;
unsigned int i;
size_t size;
for (i = 0; i < options->compile_option_count; ++i)
{
......@@ -251,9 +253,10 @@ static void add_compile_option(struct options *options,
}
}
if (options->compile_option_count >= ARRAY_SIZE(options->compile_options))
size = (options->compile_option_count + 1) * sizeof(*o);
if (!(options->compile_options = realloc(options->compile_options, size)))
{
fprintf(stderr, "Ignoring option.\n");
fprintf(stderr, "Out of memory.\n");
return;
}
......@@ -439,6 +442,7 @@ static bool parse_command_line(int argc, char **argv, struct options *options)
{
enum vkd3d_shader_compile_option_pack_matrix_order pack_matrix_order;
enum vkd3d_shader_compile_option_buffer_uav buffer_uav;
unsigned int compat_options = 0;
int option;
static struct option long_options[] =
......@@ -454,6 +458,7 @@ static bool parse_command_line(int argc, char **argv, struct options *options)
{"profile", required_argument, NULL, OPTION_PROFILE},
{"strip-debug", no_argument, NULL, OPTION_STRIP_DEBUG},
{"version", no_argument, NULL, OPTION_VERSION},
{"semantic-compat-map", no_argument, NULL, OPTION_SEMANTIC_COMPAT_MAP},
{NULL, 0, NULL, 0},
};
......@@ -533,6 +538,10 @@ static bool parse_command_line(int argc, char **argv, struct options *options)
options->print_target_types = true;
break;
case OPTION_SEMANTIC_COMPAT_MAP:
compat_options |= VKD3D_SHADER_COMPILE_OPTION_BACKCOMPAT_MAP_SEMANTIC_NAMES;
break;
case OPTION_STRIP_DEBUG:
add_compile_option(options, VKD3D_SHADER_COMPILE_OPTION_STRIP_DEBUG, 1);
break;
......@@ -555,6 +564,9 @@ static bool parse_command_line(int argc, char **argv, struct options *options)
}
}
if (compat_options)
add_compile_option(options, VKD3D_SHADER_COMPILE_OPTION_BACKWARD_COMPATIBILITY, compat_options);
if (optind < argc)
options->filename = argv[argc - 1];
......
......@@ -180,6 +180,24 @@ float4 main() : sv_target1
return 0;
}
% RWTexture1DArray types
[pixel shader fail(sm>=6)]
struct s
{
float3 a;
};
RWTexture1DArray<float4> u : register(u2);
RWTexture1DArray<float> u1;
RWTexture1DArray<float2x2> u2;
RWTexture1DArray<struct s> u3;
float4 main() : sv_target1
{
u[int2(0, 0)] = float4(11.1, 12.2, 13.3, 14.4);
return 0;
}
% RWTexture2D types
[pixel shader fail(sm>=6)]
struct s
......@@ -198,6 +216,24 @@ float4 main() : sv_target1
return 0;
}
% RWTexture2DArray types
[pixel shader fail(sm>=6)]
struct s
{
float3 a;
};
RWTexture2DArray<float4> u : register(u2);
RWTexture2DArray<float> u1;
RWTexture2DArray<float2x2> u2;
RWTexture2DArray<struct s> u3;
float4 main() : sv_target1
{
u[int3(0, 0, 0)] = float4(11.1, 12.2, 13.3, 14.4);
return 0;
}
% RWTexture3D types
[pixel shader fail(sm>=6)]
struct s
......@@ -275,6 +311,14 @@ float4 main() : sv_target1
return 0;
}
[pixel shader fail]
RWTexture1DArray<Texture2D> u;
float4 main() : sv_target1
{
return 0;
}
[pixel shader fail]
RWTexture2D<Texture2D> u;
......@@ -283,6 +327,14 @@ float4 main() : sv_target1
return 0;
}
[pixel shader fail]
RWTexture2DArray<Texture2D> u;
float4 main() : sv_target1
{
return 0;
}
[pixel shader fail]
RWTexture3D<Texture2D> u;
......@@ -310,6 +362,19 @@ struct s
Texture2D t;
};
RWTexture1DArray<struct s> u;
float4 main() : sv_target1
{
return 0;
}
[pixel shader fail]
struct s
{
Texture2D t;
};
RWTexture2D<struct s> u;
float4 main() : sv_target1
......@@ -323,6 +388,19 @@ struct s
Texture2D t;
};
RWTexture2DArray<struct s> u;
float4 main() : sv_target1
{
return 0;
}
[pixel shader fail]
struct s
{
Texture2D t;
};
RWTexture3D<struct s> u;
float4 main() : sv_target1
......
......@@ -1095,6 +1095,80 @@ static void test_get_blob_part(void)
refcount = ID3D10Blob_Release(blob);
ok(!refcount, "Got refcount %u.\n", refcount);
/* D3DStripShader() corner cases. */
hr = D3DStripShader(test_blob_part, test_blob_part[6], 0xffffffff, &blob);
ok(hr == S_OK, "Got hr %#x.\n", hr);
refcount = ID3D10Blob_Release(blob);
ok(!refcount, "Got refcount %u.\n", refcount);
hr = D3DStripShader(test_blob_part, test_blob_part[6], 0, &blob);
ok(hr == S_OK, "Got hr %#x.\n", hr);
refcount = ID3D10Blob_Release(blob);
ok(!refcount, "Got refcount %u.\n", refcount);
hr = D3DStripShader(NULL, test_blob_part[6], 0, &blob);
ok(hr == D3DERR_INVALIDCALL, "Got hr %#x.\n", hr);
hr = D3DStripShader(test_blob_part, 7 * sizeof(DWORD), 0, &blob);
ok(hr == D3DERR_INVALIDCALL, "Got hr %#x.\n", hr);
hr = D3DStripShader(test_blob_part, 8 * sizeof(DWORD), 0, &blob);
ok(hr == D3DERR_INVALIDCALL, "Got hr %#x.\n", hr);
hr = D3DStripShader(test_blob_part, test_blob_part[6], 0, NULL);
ok(hr == E_FAIL, "Got hr %#x.\n", hr);
hr = D3DStripShader(NULL, test_blob_part[6], 0, NULL);
ok(hr == E_FAIL, "Got hr %#x.\n", hr);
hr = D3DStripShader(test_blob_part, 0, 0, NULL);
ok(hr == E_FAIL, "Got hr %#x.\n", hr);
/* D3DCOMPILER_STRIP_DEBUG_INFO */
hr = D3DStripShader(test_blob_part, test_blob_part[6], D3DCOMPILER_STRIP_DEBUG_INFO, &blob);
ok(hr == S_OK, "Got hr %#x.\n", hr);
size = ID3D10Blob_GetBufferSize(blob);
ok(size == 736, "Got size %u.\n", size);
u32 = ID3D10Blob_GetBufferPointer(blob);
ok(u32[0] == TAG_DXBC, "Got u32[0] 0x%08x, expected 0x%08x.\n", u32[0], TAG_DXBC);
ok(u32[16] == TAG_XNAS, "Got u32[16] 0x%08x, expected 0x%08x.\n", u32[16], TAG_XNAS);
ok(u32[35] == TAG_XNAP, "Got u32[35] 0x%08x, expected 0x%08x.\n", u32[35], TAG_XNAP);
ok(u32[54] == TAG_AON9, "Got u32[54] 0x%08x, expected 0x%08x.\n", u32[54], TAG_AON9);
ok(u32[79] == TAG_SHDR, "Got u32[79] 0x%08x, expected 0x%08x.\n", u32[79], TAG_SHDR);
ok(u32[96] == TAG_STAT, "Got u32[96] 0x%08x, expected 0x%08x.\n", u32[96], TAG_STAT);
ok(u32[127] == TAG_RDEF, "Got u32[127] 0x%08x, expected 0x%08x.\n", u32[127], TAG_RDEF);
ok(u32[149] == TAG_ISGN, "Got u32[149] 0x%08x, expected 0x%08x.\n", u32[149], TAG_ISGN);
ok(u32[171] == TAG_OSGN, "Got u32[171] 0x%08x, expected 0x%08x.\n", u32[171], TAG_OSGN);
hr = D3DGetBlobPart(u32, size, D3D_BLOB_DEBUG_INFO, 0, &blob2);
ok(hr == E_FAIL, "Got hr %#x.\n", hr);
refcount = ID3D10Blob_Release(blob);
ok(!refcount, "Got refcount %u.\n", refcount);
/* D3DCOMPILER_STRIP_REFLECTION_DATA */
hr = D3DStripShader(test_blob_part, test_blob_part[6], D3DCOMPILER_STRIP_REFLECTION_DATA, &blob);
ok(hr == S_OK, "Got hr %#x.\n", hr);
size = ID3D10Blob_GetBufferSize(blob);
ok(size == 516, "Got size %u.\n", size);
u32 = ID3D10Blob_GetBufferPointer(blob);
ok(u32[0] == TAG_DXBC, "Got u32[0] 0x%08x, expected 0x%08x.\n", u32[0], TAG_DXBC);
ok(u32[14] == TAG_XNAS, "Got u32[14] 0x%08x, expected 0x%08x.\n", u32[14], TAG_XNAS);
ok(u32[33] == TAG_XNAP, "Got u32[33] 0x%08x, expected 0x%08x.\n", u32[33], TAG_XNAP);
ok(u32[52] == TAG_AON9, "Got u32[52] 0x%08x, expected 0x%08x.\n", u32[52], TAG_AON9);
ok(u32[77] == TAG_SHDR, "Got u32[77] 0x%08x, expected 0x%08x.\n", u32[77], TAG_SHDR);
ok(u32[94] == TAG_ISGN, "Got u32[94] 0x%08x, expected 0x%08x.\n", u32[94], TAG_ISGN);
ok(u32[116] == TAG_OSGN, "Got u32[116] 0x%08x, expected 0x%08x.\n", u32[116], TAG_OSGN);
refcount = ID3D10Blob_Release(blob);
ok(!refcount, "Got refcount %u.\n", refcount);
/* D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB */
hr = D3DGetBlobPart(test_blob_part2, test_blob_part2[6], D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB, 0, &blob);
ok(hr == S_OK, "Got hr %#x.\n", hr);
......@@ -1200,6 +1274,46 @@ static void test_get_blob_part(void)
/* D3D_BLOB_XNA_SHADER */
hr = D3DGetBlobPart(test_blob_part2, test_blob_part2[6], D3D_BLOB_XNA_SHADER, 0, &blob);
ok(hr == E_FAIL, "Got hr %#x.\n", hr);
/* D3DCOMPILER_STRIP_DEBUG_INFO */
hr = D3DStripShader(test_blob_part2, test_blob_part2[6], D3DCOMPILER_STRIP_DEBUG_INFO, &blob);
ok(hr == S_OK, "Got hr %#x.\n", hr);
size = ID3D10Blob_GetBufferSize(blob);
ok(size == 952, "Got size %u.\n", size);
u32 = ID3D10Blob_GetBufferPointer(blob);
ok(u32[0] == TAG_DXBC, "Got u32[0] 0x%08x, expected 0x%08x.\n", u32[0], TAG_DXBC);
ok(u32[14] == TAG_RDEF, "Got u32[14] 0x%08x, expected 0x%08x.\n", u32[14], TAG_RDEF);
ok(u32[44] == TAG_ISGN, "Got u32[44] 0x%08x, expected 0x%08x.\n", u32[44], TAG_ISGN);
ok(u32[57] == TAG_OSGN, "Got u32[57] 0x%08x, expected 0x%08x.\n", u32[57], TAG_OSGN);
ok(u32[70] == TAG_PCSG, "Got u32[70] 0x%08x, expected 0x%08x.\n", u32[70], TAG_PCSG);
ok(u32[119] == TAG_SHEX, "Got u32[119] 0x%08x, expected 0x%08x.\n", u32[119], TAG_SHEX);
ok(u32[199] == TAG_STAT, "Got u32[199] 0x%08x, expected 0x%08x.\n", u32[199], TAG_STAT);
hr = D3DGetBlobPart(u32, size, D3D_BLOB_DEBUG_INFO, 0, &blob2);
ok(hr == E_FAIL, "Got hr %#x.\n", hr);
refcount = ID3D10Blob_Release(blob);
ok(!refcount, "Got refcount %u.\n", refcount);
/* D3DCOMPILER_STRIP_REFLECTION_DATA */
hr = D3DStripShader(test_blob_part2, test_blob_part2[6], D3DCOMPILER_STRIP_REFLECTION_DATA, &blob);
ok(hr == S_OK, "Got hr %#x.\n", hr);
size = ID3D10Blob_GetBufferSize(blob);
ok(size == 4735, "Got size %u.\n", size);
u32 = ID3D10Blob_GetBufferPointer(blob);
ok(u32[0] == TAG_DXBC, "Got u32[0] 0x%08x, expected 0x%08x.\n", u32[0], TAG_DXBC);
ok(u32[13] == TAG_ISGN, "Got u32[13] 0x%08x, expected 0x%08x.\n", u32[13], TAG_ISGN);
ok(u32[26] == TAG_OSGN, "Got u32[26] 0x%08x, expected 0x%08x.\n", u32[26], TAG_OSGN);
ok(u32[39] == TAG_PCSG, "Got u32[39] 0x%08x, expected 0x%08x.\n", u32[39], TAG_PCSG);
ok(u32[88] == TAG_SHEX, "Got u32[88] 0x%08x, expected 0x%08x.\n", u32[88], TAG_SHEX);
ok(u32[168] == TAG_SDBG, "Got u32[168] 0x%08x, expected 0x%08x.\n", u32[168], TAG_SDBG);
refcount = ID3D10Blob_Release(blob);
ok(!refcount, "Got refcount %u.\n", refcount);
}
START_TEST(hlsl_d3d12)
......