vkd3d: Import upstream release 1.10.

This commit is contained in:
Alexandre Julliard 2023-12-06 16:15:53 +01:00
parent 0fea0db866
commit 23111d625b
29 changed files with 9454 additions and 2805 deletions

View file

@ -1,3 +1,4 @@
Akihiro Sagawa
Alexandre Julliard
Alistair Leslie-Hughes
Andrew Eikum
@ -18,6 +19,7 @@ Giovanni Mascellani
Hans-Kristian Arntzen
Henri Verbeet
Isabella Bosia
Jacek Caban
Jactry Zeng
Jan Sikorski
Joshua Ashton
@ -25,6 +27,7 @@ Józef Kucia
Martin Storsjö
Matteo Bruni
Nikolay Sivov
Petrichor Park
Philip Rebohle
Rémi Bernon
Robin Kertels

View file

@ -2,7 +2,6 @@ EXTLIB = libvkd3d.a
EXTRAINCL = $(VKD3D_PE_CFLAGS) -I$(srcdir)/include/private -I$(srcdir)/libs/vkd3d -I$(srcdir)/libs/vkd3d-shader
EXTRADEFS = \
-DWINE_NO_NAMELESS_EXTENSION \
-DCONST_VTABLE \
-DLIBVKD3D_SOURCE \
-DLIBVKD3D_SHADER_SOURCE \
-DLIBVKD3D_UTILS_SOURCE

View file

@ -1,5 +1,5 @@
#define PACKAGE_NAME "vkd3d"
#define PACKAGE_STRING "vkd3d 1.9"
#define PACKAGE_VERSION "1.9"
#define PACKAGE_STRING "vkd3d 1.10"
#define PACKAGE_VERSION "1.10"
#define PATH_MAX 1024
#define SONAME_LIBVULKAN "vulkan-1.dll"

View file

@ -49,12 +49,33 @@
((uint32_t)(ch0) | ((uint32_t)(ch1) << 8) \
| ((uint32_t)(ch2) << 16) | ((uint32_t)(ch3) << 24))
#define TAG_AON9 VKD3D_MAKE_TAG('A', 'o', 'n', '9')
#define TAG_DXBC VKD3D_MAKE_TAG('D', 'X', 'B', 'C')
#define TAG_DXIL VKD3D_MAKE_TAG('D', 'X', 'I', 'L')
#define TAG_ISG1 VKD3D_MAKE_TAG('I', 'S', 'G', '1')
#define TAG_ISGN VKD3D_MAKE_TAG('I', 'S', 'G', 'N')
#define TAG_OSG1 VKD3D_MAKE_TAG('O', 'S', 'G', '1')
#define TAG_OSG5 VKD3D_MAKE_TAG('O', 'S', 'G', '5')
#define TAG_OSGN VKD3D_MAKE_TAG('O', 'S', 'G', 'N')
#define TAG_PCSG VKD3D_MAKE_TAG('P', 'C', 'S', 'G')
#define TAG_PSG1 VKD3D_MAKE_TAG('P', 'S', 'G', '1')
#define TAG_RD11 VKD3D_MAKE_TAG('R', 'D', '1', '1')
#define TAG_RDEF VKD3D_MAKE_TAG('R', 'D', 'E', 'F')
#define TAG_RTS0 VKD3D_MAKE_TAG('R', 'T', 'S', '0')
#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')
static inline size_t align(size_t addr, size_t alignment)
{
return (addr + (alignment - 1)) & ~(alignment - 1);
}
#ifdef __GNUC__
#if defined(__GNUC__) || defined(__clang__)
# define VKD3D_NORETURN __attribute__((noreturn))
# ifdef __MINGW_PRINTF_FORMAT
# define VKD3D_PRINTF_FUNC(fmt, args) __attribute__((format(__MINGW_PRINTF_FORMAT, fmt, args)))

View file

@ -78,6 +78,7 @@ enum vkd3d_api_version
VKD3D_API_VERSION_1_7,
VKD3D_API_VERSION_1_8,
VKD3D_API_VERSION_1_9,
VKD3D_API_VERSION_1_10,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_API_VERSION),
};

View file

@ -51,6 +51,7 @@ enum vkd3d_shader_api_version
VKD3D_SHADER_API_VERSION_1_7,
VKD3D_SHADER_API_VERSION_1_8,
VKD3D_SHADER_API_VERSION_1_9,
VKD3D_SHADER_API_VERSION_1_10,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_API_VERSION),
};
@ -96,6 +97,11 @@ enum vkd3d_shader_structure_type
* \since 1.9
*/
VKD3D_SHADER_STRUCTURE_TYPE_VARYING_MAP_INFO,
/**
* The structure is a vkd3d_shader_scan_combined_resource_sampler_info structure.
* \since 1.10
*/
VKD3D_SHADER_STRUCTURE_TYPE_SCAN_COMBINED_RESOURCE_SAMPLER_INFO,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE),
};
@ -154,6 +160,42 @@ 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),
};
/**
* Determines the origin of fragment coordinates.
*
* \since 1.10
*/
enum vkd3d_shader_compile_option_fragment_coordinate_origin
{
/** Fragment coordinates originate from the upper-left. This is the
* default; it's also the only value supported by Vulkan environments. */
VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN_UPPER_LEFT = 0x00000000,
/** Fragment coordinates originate from the lower-left. This matches the
* traditional behaviour of OpenGL environments. */
VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN_LOWER_LEFT = 0x00000001,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN),
};
enum vkd3d_shader_compile_option_name
{
/**
@ -193,6 +235,24 @@ 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,
/**
* This option specifies the origin of fragment coordinates for SPIR-V
* targets.
*
* \a value is a member of enum
* vkd3d_shader_compile_option_fragment_coordinate_origin.
*
* \since 1.10
*/
VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN = 0x00000009,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_NAME),
};
@ -1383,19 +1443,33 @@ struct vkd3d_shader_descriptor_info
*
* This structure extends vkd3d_shader_compile_info.
*
* When scanning a legacy Direct3D shader, vkd3d-shader enumerates each
* constant register set used by the shader as a single constant buffer
* descriptor, as follows:
* - The \ref vkd3d_shader_descriptor_info.type field is set to
* VKD3D_SHADER_DESCRIPTOR_TYPE_CBV.
* - The \ref vkd3d_shader_descriptor_info.register_space field is set to zero.
* - The \ref vkd3d_shader_descriptor_info.register_index field is set to a
* member of enum vkd3d_shader_d3dbc_constant_register denoting which set
* is used.
* - The \ref vkd3d_shader_descriptor_info.count field is set to one.
* When scanning a legacy Direct3D shader, vkd3d-shader enumerates descriptors
* as follows:
*
* In summary, there may be up to three such descriptors, one for each register
* set used by the shader: float, integer, and boolean.
* - Each constant register set used by the shader is scanned as a single
* constant buffer descriptor.
* There may therefore be up to three such descriptors, one for each register
* set used by the shader: float, integer, and boolean.
* The fields are set as follows:
* * The \ref vkd3d_shader_descriptor_info.type field is set to
* VKD3D_SHADER_DESCRIPTOR_TYPE_CBV.
* * The \ref vkd3d_shader_descriptor_info.register_space field is set to zero.
* * The \ref vkd3d_shader_descriptor_info.register_index field is set to a
* member of enum vkd3d_shader_d3dbc_constant_register denoting which set
* is used.
* * The \ref vkd3d_shader_descriptor_info.count field is set to one.
* - Each sampler used by the shader is scanned as two separate descriptors,
* one representing the texture, and one representing the sampler state.
* If desired, these may be mapped back into a single combined sampler using
* struct vkd3d_shader_combined_resource_sampler.
* The fields are set as follows:
* * The \ref vkd3d_shader_descriptor_info.type field is set to
* VKD3D_SHADER_DESCRIPTOR_TYPE_SRV and VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER
* respectively.
* * The \ref vkd3d_shader_descriptor_info.register_space field is set to zero.
* * The \ref vkd3d_shader_descriptor_info.register_index field is set to the
* binding index of the original sampler, for both descriptors.
* * The \ref vkd3d_shader_descriptor_info.count field is set to one.
*/
struct vkd3d_shader_scan_descriptor_info
{
@ -1412,6 +1486,53 @@ struct vkd3d_shader_scan_descriptor_info
unsigned int descriptor_count;
};
/**
* This structure describes a single resource-sampler pair. It is returned as
* part of struct vkd3d_shader_scan_combined_resource_sampler_info.
*
* \since 1.10
*/
struct vkd3d_shader_combined_resource_sampler_info
{
unsigned int resource_space;
unsigned int resource_index;
unsigned int sampler_space;
unsigned int sampler_index;
};
/**
* A chained structure describing the resource-sampler pairs used by a shader.
*
* This structure extends vkd3d_shader_compile_info.
*
* The information returned in this structure can be used to populate the
* \ref vkd3d_shader_interface_info.combined_samplers field. This is
* particularly useful when targeting environments without separate binding
* points for samplers and resources, like OpenGL.
*
* No resource-sampler pairs are returned for dynamic accesses to
* resource/sampler descriptor arrays, as can occur in Direct3D shader model
* 5.1 shaders.
*
* Members of this structure are allocated by vkd3d-shader and should be freed
* with vkd3d_shader_free_scan_combined_resource_sampler_info() when no longer
* needed.
*
* \since 1.10
*/
struct vkd3d_shader_scan_combined_resource_sampler_info
{
/** Must be set to VKD3D_SHADER_STRUCTURE_TYPE_SCAN_COMBINED_RESOURCE_SAMPLER_INFO. */
enum vkd3d_shader_structure_type type;
/** Optional pointer to a structure containing further parameters. */
const void *next;
/** Pointer to an array of resource-sampler pairs. */
struct vkd3d_shader_combined_resource_sampler_info *combined_samplers;
/** The number of resource-sampler pairs in \ref combined_samplers. */
unsigned int combined_sampler_count;
};
/**
* Data type of a shader varying, returned as part of struct
* vkd3d_shader_signature_element.
@ -2028,12 +2149,14 @@ VKD3D_SHADER_API int vkd3d_shader_convert_root_signature(struct vkd3d_shader_ver
*
* Currently this function supports the following code types:
* - VKD3D_SHADER_SOURCE_DXBC_TPF
* - VKD3D_SHADER_SOURCE_D3D_BYTECODE
*
* \param compile_info A chained structure containing scan parameters.
* \n
* The DXBC_TPF scanner supports the following chained structures:
* The scanner supports the following chained structures:
* - vkd3d_shader_scan_descriptor_info
* - vkd3d_shader_scan_signature_info
* - vkd3d_shader_scan_combined_resource_sampler_info
* \n
* Although the \a compile_info parameter is read-only, chained structures
* passed to this function need not be, and may serve as output parameters,
@ -2313,6 +2436,21 @@ VKD3D_SHADER_API void vkd3d_shader_build_varying_map(const struct vkd3d_shader_s
const struct vkd3d_shader_signature *input_signature,
unsigned int *count, struct vkd3d_shader_varying_map *varyings);
/**
* Free members of struct vkd3d_shader_scan_combined_resource_sampler_info
* allocated by vkd3d_shader_scan().
*
* This function may free members of
* vkd3d_shader_scan_combined_resource_sampler_info, but does not free the
* structure itself.
*
* \param info Combined resource-sampler information to free.
*
* \since 1.10
*/
VKD3D_SHADER_API void vkd3d_shader_free_scan_combined_resource_sampler_info(
struct vkd3d_shader_scan_combined_resource_sampler_info *info);
#endif /* VKD3D_SHADER_NO_PROTOTYPES */
/** Type of vkd3d_shader_get_version(). */
@ -2385,6 +2523,10 @@ typedef void (*PFN_vkd3d_shader_build_varying_map)(const struct vkd3d_shader_sig
/** Type of vkd3d_shader_free_scan_signature_info(). \since 1.9 */
typedef void (*PFN_vkd3d_shader_free_scan_signature_info)(struct vkd3d_shader_scan_signature_info *info);
/** Type of vkd3d_shader_free_scan_combined_resource_sampler_info(). \since 1.10 */
typedef void (*PFN_vkd3d_shader_free_scan_combined_resource_sampler_info)(
struct vkd3d_shader_scan_combined_resource_sampler_info *info);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View file

@ -17,6 +17,7 @@
*/
#define COBJMACROS
#define CONST_VTABLE
#include "vkd3d.h"
#include "vkd3d_blob.h"
#include "vkd3d_debug.h"

View file

@ -106,9 +106,9 @@ static const char * const shader_opcode_names[] =
[VKD3DSIH_DEFAULT ] = "default",
[VKD3DSIH_DEFB ] = "defb",
[VKD3DSIH_DEFI ] = "defi",
[VKD3DSIH_DEQ ] = "deq",
[VKD3DSIH_DEQO ] = "deq",
[VKD3DSIH_DFMA ] = "dfma",
[VKD3DSIH_DGE ] = "dge",
[VKD3DSIH_DGEO ] = "dge",
[VKD3DSIH_DISCARD ] = "discard",
[VKD3DSIH_DIV ] = "div",
[VKD3DSIH_DLT ] = "dlt",
@ -140,7 +140,8 @@ static const char * const shader_opcode_names[] =
[VKD3DSIH_ENDLOOP ] = "endloop",
[VKD3DSIH_ENDREP ] = "endrep",
[VKD3DSIH_ENDSWITCH ] = "endswitch",
[VKD3DSIH_EQ ] = "eq",
[VKD3DSIH_EQO ] = "eq",
[VKD3DSIH_EQU ] = "eq_unord",
[VKD3DSIH_EVAL_CENTROID ] = "eval_centroid",
[VKD3DSIH_EVAL_SAMPLE_INDEX ] = "eval_sample_index",
[VKD3DSIH_EXP ] = "exp",
@ -152,6 +153,7 @@ static const char * const shader_opcode_names[] =
[VKD3DSIH_FIRSTBIT_LO ] = "firstbit_lo",
[VKD3DSIH_FIRSTBIT_SHI ] = "firstbit_shi",
[VKD3DSIH_FRC ] = "frc",
[VKD3DSIH_FREM ] = "frem",
[VKD3DSIH_FTOD ] = "ftod",
[VKD3DSIH_FTOI ] = "ftoi",
[VKD3DSIH_FTOU ] = "ftou",
@ -163,13 +165,15 @@ static const char * const shader_opcode_names[] =
[VKD3DSIH_GATHER4_PO_C_S ] = "gather4_po_c_s",
[VKD3DSIH_GATHER4_PO_S ] = "gather4_po_s",
[VKD3DSIH_GATHER4_S ] = "gather4_s",
[VKD3DSIH_GE ] = "ge",
[VKD3DSIH_GEO ] = "ge",
[VKD3DSIH_GEU ] = "ge_unord",
[VKD3DSIH_HS_CONTROL_POINT_PHASE ] = "hs_control_point_phase",
[VKD3DSIH_HS_DECLS ] = "hs_decls",
[VKD3DSIH_HS_FORK_PHASE ] = "hs_fork_phase",
[VKD3DSIH_HS_JOIN_PHASE ] = "hs_join_phase",
[VKD3DSIH_IADD ] = "iadd",
[VKD3DSIH_IBFE ] = "ibfe",
[VKD3DSIH_IDIV ] = "idiv",
[VKD3DSIH_IEQ ] = "ieq",
[VKD3DSIH_IF ] = "if",
[VKD3DSIH_IFC ] = "ifc",
@ -197,6 +201,7 @@ static const char * const shader_opcode_names[] =
[VKD3DSIH_ISHR ] = "ishr",
[VKD3DSIH_ITOD ] = "itod",
[VKD3DSIH_ITOF ] = "itof",
[VKD3DSIH_ITOI ] = "itoi",
[VKD3DSIH_LABEL ] = "label",
[VKD3DSIH_LD ] = "ld",
[VKD3DSIH_LD2DMS ] = "ld2dms",
@ -214,7 +219,8 @@ static const char * const shader_opcode_names[] =
[VKD3DSIH_LOGP ] = "logp",
[VKD3DSIH_LOOP ] = "loop",
[VKD3DSIH_LRP ] = "lrp",
[VKD3DSIH_LT ] = "lt",
[VKD3DSIH_LTO ] = "lt",
[VKD3DSIH_LTU ] = "lt_unord",
[VKD3DSIH_M3x2 ] = "m3x2",
[VKD3DSIH_M3x3 ] = "m3x3",
[VKD3DSIH_M3x4 ] = "m3x4",
@ -228,7 +234,8 @@ static const char * const shader_opcode_names[] =
[VKD3DSIH_MOVC ] = "movc",
[VKD3DSIH_MSAD ] = "msad",
[VKD3DSIH_MUL ] = "mul",
[VKD3DSIH_NE ] = "ne",
[VKD3DSIH_NEO ] = "ne_ord",
[VKD3DSIH_NEU ] = "ne",
[VKD3DSIH_NOP ] = "nop",
[VKD3DSIH_NOT ] = "not",
[VKD3DSIH_NRM ] = "nrm",
@ -304,6 +311,7 @@ static const char * const shader_opcode_names[] =
[VKD3DSIH_USHR ] = "ushr",
[VKD3DSIH_UTOD ] = "utod",
[VKD3DSIH_UTOF ] = "utof",
[VKD3DSIH_UTOU ] = "utou",
[VKD3DSIH_XOR ] = "xor",
};
@ -358,11 +366,6 @@ struct vkd3d_d3d_asm_compiler
struct vkd3d_d3d_asm_colours colours;
};
static int shader_ver_ge(const struct vkd3d_shader_version *v, int major, int minor)
{
return v->major > major || (v->major == major && v->minor >= minor);
}
static int VKD3D_PRINTF_FUNC(2, 3) shader_addline(struct vkd3d_string_buffer *buffer, const char *format, ...)
{
va_list args;
@ -391,13 +394,14 @@ static unsigned int shader_get_float_offset(enum vkd3d_shader_register_type regi
}
}
static void shader_dump_global_flags(struct vkd3d_d3d_asm_compiler *compiler, uint32_t global_flags)
static void shader_dump_global_flags(struct vkd3d_d3d_asm_compiler *compiler,
enum vkd3d_shader_global_flags global_flags)
{
unsigned int i;
static const struct
{
unsigned int flag;
enum vkd3d_shader_global_flags flag;
const char *name;
}
global_flag_info[] =
@ -423,7 +427,7 @@ static void shader_dump_global_flags(struct vkd3d_d3d_asm_compiler *compiler, ui
}
if (global_flags)
vkd3d_string_buffer_printf(&compiler->buffer, "unknown_flags(%#x)", global_flags);
vkd3d_string_buffer_printf(&compiler->buffer, "unknown_flags(%#"PRIx64")", (uint64_t)global_flags);
}
static void shader_dump_sync_flags(struct vkd3d_d3d_asm_compiler *compiler, uint32_t sync_flags)
@ -477,6 +481,11 @@ static void shader_dump_uav_flags(struct vkd3d_d3d_asm_compiler *compiler, uint3
vkd3d_string_buffer_printf(&compiler->buffer, "_opc");
uav_flags &= ~VKD3DSUF_ORDER_PRESERVING_COUNTER;
}
if (uav_flags & VKD3DSUF_RASTERISER_ORDERED_VIEW)
{
vkd3d_string_buffer_printf(&compiler->buffer, "_rov");
uav_flags &= ~VKD3DSUF_RASTERISER_ORDERED_VIEW;
}
if (uav_flags)
vkd3d_string_buffer_printf(&compiler->buffer, "_unknown_flags(%#x)", uav_flags);
@ -637,7 +646,7 @@ static void shader_dump_decl_usage(struct vkd3d_d3d_asm_compiler *compiler,
{
struct vkd3d_string_buffer *buffer = &compiler->buffer;
if (semantic->resource.reg.reg.type == VKD3DSPR_SAMPLER)
if (semantic->resource.reg.reg.type == VKD3DSPR_COMBINED_SAMPLER)
{
switch (semantic->resource_type)
{
@ -678,7 +687,7 @@ static void shader_dump_decl_usage(struct vkd3d_d3d_asm_compiler *compiler,
else
{
/* Pixel shaders 3.0 don't have usage semantics. */
if (!shader_ver_ge(&compiler->shader_version, 3, 0)
if (!vkd3d_shader_ver_ge(&compiler->shader_version, 3, 0)
&& compiler->shader_version.type == VKD3D_SHADER_TYPE_PIXEL)
return;
else
@ -880,9 +889,7 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
break;
case VKD3DSPR_COLOROUT:
shader_addline(buffer, "o");
if (!shader_ver_ge(&compiler->shader_version, 4, 0))
shader_addline(buffer, "C");
shader_addline(buffer, "oC");
break;
case VKD3DSPR_DEPTHOUT:
@ -904,7 +911,7 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
case VKD3DSPR_TEXCRDOUT:
/* Vertex shaders >= 3.0 use general purpose output registers
* (VKD3DSPR_OUTPUT), which can include an address token. */
if (shader_ver_ge(&compiler->shader_version, 3, 0))
if (vkd3d_shader_ver_ge(&compiler->shader_version, 3, 0))
shader_addline(buffer, "o");
else
shader_addline(buffer, "oT");
@ -926,6 +933,7 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
shader_addline(buffer, "aL");
break;
case VKD3DSPR_COMBINED_SAMPLER:
case VKD3DSPR_SAMPLER:
shader_addline(buffer, "s");
is_descriptor = true;
@ -1066,6 +1074,14 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
shader_addline(buffer, "oStencilRef");
break;
case VKD3DSPR_UNDEF:
shader_addline(buffer, "undef");
break;
case VKD3DSPR_SSA:
shader_addline(buffer, "sr");
break;
default:
shader_addline(buffer, "<unhandled_rtype(%#x)>", reg->type);
break;
@ -1074,9 +1090,9 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
if (reg->type == VKD3DSPR_IMMCONST)
{
shader_addline(buffer, "%s(", compiler->colours.reset);
switch (reg->immconst_type)
switch (reg->dimension)
{
case VKD3D_IMMCONST_SCALAR:
case VSIR_DIMENSION_SCALAR:
switch (reg->data_type)
{
case VKD3D_DATA_FLOAT:
@ -1096,7 +1112,7 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
}
break;
case VKD3D_IMMCONST_VEC4:
case VSIR_DIMENSION_VEC4:
switch (reg->data_type)
{
case VKD3D_DATA_FLOAT:
@ -1126,7 +1142,7 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
break;
default:
shader_addline(buffer, "<unhandled immconst_type %#x>", reg->immconst_type);
shader_addline(buffer, "<unhandled immconst dimension %#x>", reg->dimension);
break;
}
shader_addline(buffer, ")");
@ -1134,13 +1150,13 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
else if (reg->type == VKD3DSPR_IMMCONST64)
{
shader_addline(buffer, "%s(", compiler->colours.reset);
/* A double2 vector is treated as a float4 vector in enum vkd3d_immconst_type. */
if (reg->immconst_type == VKD3D_IMMCONST_SCALAR || reg->immconst_type == VKD3D_IMMCONST_VEC4)
/* A double2 vector is treated as a float4 vector in enum vsir_dimension. */
if (reg->dimension == VSIR_DIMENSION_SCALAR || reg->dimension == VSIR_DIMENSION_VEC4)
{
if (reg->data_type == VKD3D_DATA_DOUBLE)
{
shader_print_double_literal(compiler, "", reg->u.immconst_double[0], "");
if (reg->immconst_type == VKD3D_IMMCONST_VEC4)
if (reg->dimension == VSIR_DIMENSION_VEC4)
shader_print_double_literal(compiler, ", ", reg->u.immconst_double[1], "");
}
else
@ -1150,17 +1166,18 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
}
else
{
shader_addline(buffer, "<unhandled immconst_type %#x>", reg->immconst_type);
shader_addline(buffer, "<unhandled immconst64 dimension %#x>", reg->dimension);
}
shader_addline(buffer, ")");
}
else if (reg->type != VKD3DSPR_RASTOUT
&& reg->type != VKD3DSPR_MISCTYPE
&& reg->type != VKD3DSPR_NULL)
&& reg->type != VKD3DSPR_NULL
&& reg->type != VKD3DSPR_DEPTHOUT)
{
if (offset != ~0u)
{
bool is_sm_5_1 = shader_ver_ge(&compiler->shader_version, 5, 1);
bool is_sm_5_1 = vkd3d_shader_ver_ge(&compiler->shader_version, 5, 1);
if (reg->idx[0].rel_addr || reg->type == VKD3DSPR_IMMCONSTBUFFER
|| reg->type == VKD3DSPR_INCONTROLPOINT || (reg->type == VKD3DSPR_INPUT
@ -1181,7 +1198,7 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
{
shader_print_subscript_range(compiler, reg->idx[1].offset, reg->idx[2].offset);
}
else
else if (reg->type != VKD3DSPR_SSA)
{
/* For descriptors in sm < 5.1 we move the reg->idx values up one slot
* to normalise with 5.1.
@ -1256,7 +1273,7 @@ static void shader_dump_dst_param(struct vkd3d_d3d_asm_compiler *compiler,
shader_dump_register(compiler, &param->reg, is_declaration);
if (write_mask)
if (write_mask && param->reg.dimension == VSIR_DIMENSION_VEC4)
{
static const char write_mask_chars[] = "xyzw";
@ -1322,7 +1339,7 @@ static void shader_dump_src_param(struct vkd3d_d3d_asm_compiler *compiler,
}
if (param->reg.type != VKD3DSPR_IMMCONST && param->reg.type != VKD3DSPR_IMMCONST64
&& param->reg.type != VKD3DSPR_SAMPLER)
&& param->reg.dimension == VSIR_DIMENSION_VEC4)
{
unsigned int swizzle_x = vkd3d_swizzle_get_component(swizzle, 0);
unsigned int swizzle_y = vkd3d_swizzle_get_component(swizzle, 1);
@ -1374,7 +1391,7 @@ static void shader_dump_ins_modifiers(struct vkd3d_d3d_asm_compiler *compiler,
if (mmask & VKD3DSPDM_PARTIALPRECISION) shader_addline(buffer, "_pp");
if (mmask & VKD3DSPDM_MSAMPCENTROID) shader_addline(buffer, "_centroid");
mmask &= ~(VKD3DSPDM_SATURATE | VKD3DSPDM_PARTIALPRECISION | VKD3DSPDM_MSAMPCENTROID);
mmask &= ~VKD3DSPDM_MASK;
if (mmask) FIXME("Unrecognised modifier %#x.\n", mmask);
}
@ -1556,7 +1573,7 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile
break;
case VKD3DSIH_TEX:
if (shader_ver_ge(&compiler->shader_version, 2, 0) && (ins->flags & VKD3DSI_TEXLD_PROJECT))
if (vkd3d_shader_ver_ge(&compiler->shader_version, 2, 0) && (ins->flags & VKD3DSI_TEXLD_PROJECT))
shader_addline(buffer, "p");
break;
@ -1568,7 +1585,7 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile
static void shader_dump_register_space(struct vkd3d_d3d_asm_compiler *compiler, unsigned int register_space)
{
if (shader_ver_ge(&compiler->shader_version, 5, 1))
if (vkd3d_shader_ver_ge(&compiler->shader_version, 5, 1))
shader_print_uint_literal(compiler, ", space=", register_space, "");
}
@ -1578,6 +1595,36 @@ static void shader_print_opcode(struct vkd3d_d3d_asm_compiler *compiler, enum vk
shader_opcode_names[opcode], compiler->colours.reset);
}
static void shader_dump_icb(struct vkd3d_d3d_asm_compiler *compiler,
const struct vkd3d_shader_immediate_constant_buffer *icb)
{
struct vkd3d_string_buffer *buffer = &compiler->buffer;
unsigned int i, j;
vkd3d_string_buffer_printf(buffer, " {\n");
if (icb->component_count == 1)
{
for (i = 0; i < icb->element_count; )
{
for (j = 0; i < icb->element_count && j < 4; ++i, ++j)
shader_print_hex_literal(compiler, !j ? " " : ", ", icb->data[i], "");
vkd3d_string_buffer_printf(buffer, "\n");
}
}
else
{
assert(icb->component_count == VKD3D_VEC4_SIZE);
for (i = 0; i < icb->element_count; ++i)
{
shader_print_hex_literal(compiler, " {", icb->data[4 * i + 0], "");
shader_print_hex_literal(compiler, ", ", icb->data[4 * i + 1], "");
shader_print_hex_literal(compiler, ", ", icb->data[4 * i + 2], "");
shader_print_hex_literal(compiler, ", ", icb->data[4 * i + 3], "},\n");
}
}
shader_addline(buffer, "}");
}
static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
const struct vkd3d_shader_instruction *ins)
{
@ -1612,8 +1659,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 (vkd3d_shader_ver_ge(&compiler->shader_version, 6, 0))
shader_print_subscript(compiler, ins->declaration.cb.size, NULL);
else if (vkd3d_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);
@ -1629,7 +1678,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
case VKD3DSIH_DCL_GLOBAL_FLAGS:
vkd3d_string_buffer_printf(buffer, " ");
shader_dump_global_flags(compiler, ins->flags);
shader_dump_global_flags(compiler, ins->declaration.global_flags);
break;
case VKD3DSIH_DCL_HS_MAX_TESSFACTOR:
@ -1637,15 +1686,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
break;
case VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER:
vkd3d_string_buffer_printf(buffer, " {\n");
for (i = 0; i < ins->declaration.icb->vec4_count; ++i)
{
shader_print_hex_literal(compiler, " {", ins->declaration.icb->data[4 * i + 0], "");
shader_print_hex_literal(compiler, ", ", ins->declaration.icb->data[4 * i + 1], "");
shader_print_hex_literal(compiler, ", ", ins->declaration.icb->data[4 * i + 2], "");
shader_print_hex_literal(compiler, ", ", ins->declaration.icb->data[4 * i + 3], "},\n");
}
shader_addline(buffer, "}");
shader_dump_icb(compiler, ins->declaration.icb);
break;
case VKD3DSIH_DCL_INDEX_RANGE:
@ -1659,6 +1700,10 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
ins->declaration.indexable_temp.register_idx, compiler->colours.reset);
shader_print_subscript(compiler, ins->declaration.indexable_temp.register_size, NULL);
shader_print_uint_literal(compiler, ", ", ins->declaration.indexable_temp.component_count, "");
if (ins->declaration.indexable_temp.alignment)
shader_print_uint_literal(compiler, ", align ", ins->declaration.indexable_temp.alignment, "");
if (ins->declaration.indexable_temp.initialiser)
shader_dump_icb(compiler, ins->declaration.indexable_temp.initialiser);
break;
case VKD3DSIH_DCL_INPUT_PS:

View file

@ -261,7 +261,7 @@ static const struct vkd3d_sm1_opcode_info vs_opcode_table[] =
{VKD3D_SM1_OP_M3x3, 1, 2, VKD3DSIH_M3x3},
{VKD3D_SM1_OP_M3x2, 1, 2, VKD3DSIH_M3x2},
/* Declarations */
{VKD3D_SM1_OP_DCL, 0, 2, VKD3DSIH_DCL},
{VKD3D_SM1_OP_DCL, 0, 0, VKD3DSIH_DCL},
/* Constant definitions */
{VKD3D_SM1_OP_DEF, 1, 1, VKD3DSIH_DEF},
{VKD3D_SM1_OP_DEFB, 1, 1, VKD3DSIH_DEFB},
@ -328,7 +328,7 @@ static const struct vkd3d_sm1_opcode_info ps_opcode_table[] =
{VKD3D_SM1_OP_M3x3, 1, 2, VKD3DSIH_M3x3},
{VKD3D_SM1_OP_M3x2, 1, 2, VKD3DSIH_M3x2},
/* Declarations */
{VKD3D_SM1_OP_DCL, 0, 2, VKD3DSIH_DCL},
{VKD3D_SM1_OP_DCL, 0, 0, VKD3DSIH_DCL},
/* Constant definitions */
{VKD3D_SM1_OP_DEF, 1, 1, VKD3DSIH_DEF},
{VKD3D_SM1_OP_DEFB, 1, 1, VKD3DSIH_DEFB},
@ -402,16 +402,6 @@ static uint32_t read_u32(const uint32_t **ptr)
return *(*ptr)++;
}
static bool shader_ver_ge(const struct vkd3d_shader_version *v, unsigned int major, unsigned int minor)
{
return v->major > major || (v->major == major && v->minor >= minor);
}
static bool shader_ver_le(const struct vkd3d_shader_version *v, unsigned int major, unsigned int minor)
{
return v->major < major || (v->major == major && v->minor <= minor);
}
static bool has_relative_address(uint32_t param)
{
enum vkd3d_sm1_address_mode_type address_mode;
@ -434,8 +424,8 @@ static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info(
return NULL;
if (opcode == info->sm1_opcode
&& shader_ver_ge(&sm1->p.shader_version, info->min_version.major, info->min_version.minor)
&& (shader_ver_le(&sm1->p.shader_version, info->max_version.major, info->max_version.minor)
&& vkd3d_shader_ver_ge(&sm1->p.shader_version, info->min_version.major, info->min_version.minor)
&& (vkd3d_shader_ver_le(&sm1->p.shader_version, info->max_version.major, info->max_version.minor)
|| !info->max_version.major))
return info;
}
@ -457,18 +447,20 @@ static uint32_t swizzle_from_sm1(uint32_t swizzle)
static void shader_sm1_parse_src_param(uint32_t param, const struct vkd3d_shader_src_param *rel_addr,
struct vkd3d_shader_src_param *src)
{
src->reg.type = ((param & VKD3D_SM1_REGISTER_TYPE_MASK) >> VKD3D_SM1_REGISTER_TYPE_SHIFT)
enum vkd3d_shader_register_type reg_type = ((param & VKD3D_SM1_REGISTER_TYPE_MASK) >> VKD3D_SM1_REGISTER_TYPE_SHIFT)
| ((param & VKD3D_SM1_REGISTER_TYPE_MASK2) >> VKD3D_SM1_REGISTER_TYPE_SHIFT2);
vsir_register_init(&src->reg, reg_type, VKD3D_DATA_FLOAT, 1);
src->reg.precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT;
src->reg.non_uniform = false;
src->reg.data_type = VKD3D_DATA_FLOAT;
src->reg.idx[0].offset = param & VKD3D_SM1_REGISTER_NUMBER_MASK;
src->reg.idx[0].rel_addr = rel_addr;
src->reg.idx[1].offset = ~0u;
src->reg.idx[1].rel_addr = NULL;
src->reg.idx[2].offset = ~0u;
src->reg.idx[2].rel_addr = NULL;
src->reg.idx_count = 1;
if (src->reg.type == VKD3DSPR_SAMPLER)
src->reg.dimension = VSIR_DIMENSION_NONE;
else if (src->reg.type == VKD3DSPR_DEPTHOUT)
src->reg.dimension = VSIR_DIMENSION_SCALAR;
else
src->reg.dimension = VSIR_DIMENSION_VEC4;
src->swizzle = swizzle_from_sm1((param & VKD3D_SM1_SWIZZLE_MASK) >> VKD3D_SM1_SWIZZLE_SHIFT);
src->modifiers = (param & VKD3D_SM1_SRC_MODIFIER_MASK) >> VKD3D_SM1_SRC_MODIFIER_SHIFT;
}
@ -476,18 +468,20 @@ static void shader_sm1_parse_src_param(uint32_t param, const struct vkd3d_shader
static void shader_sm1_parse_dst_param(uint32_t param, const struct vkd3d_shader_src_param *rel_addr,
struct vkd3d_shader_dst_param *dst)
{
dst->reg.type = ((param & VKD3D_SM1_REGISTER_TYPE_MASK) >> VKD3D_SM1_REGISTER_TYPE_SHIFT)
enum vkd3d_shader_register_type reg_type = ((param & VKD3D_SM1_REGISTER_TYPE_MASK) >> VKD3D_SM1_REGISTER_TYPE_SHIFT)
| ((param & VKD3D_SM1_REGISTER_TYPE_MASK2) >> VKD3D_SM1_REGISTER_TYPE_SHIFT2);
vsir_register_init(&dst->reg, reg_type, VKD3D_DATA_FLOAT, 1);
dst->reg.precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT;
dst->reg.non_uniform = false;
dst->reg.data_type = VKD3D_DATA_FLOAT;
dst->reg.idx[0].offset = param & VKD3D_SM1_REGISTER_NUMBER_MASK;
dst->reg.idx[0].rel_addr = rel_addr;
dst->reg.idx[1].offset = ~0u;
dst->reg.idx[1].rel_addr = NULL;
dst->reg.idx[2].offset = ~0u;
dst->reg.idx[2].rel_addr = NULL;
dst->reg.idx_count = 1;
if (dst->reg.type == VKD3DSPR_SAMPLER)
dst->reg.dimension = VSIR_DIMENSION_NONE;
else if (dst->reg.type == VKD3DSPR_DEPTHOUT)
dst->reg.dimension = VSIR_DIMENSION_SCALAR;
else
dst->reg.dimension = VSIR_DIMENSION_VEC4;
dst->write_mask = (param & VKD3D_SM1_WRITEMASK_MASK) >> VKD3D_SM1_WRITEMASK_SHIFT;
dst->modifiers = (param & VKD3D_SM1_DST_MODIFIER_MASK) >> VKD3D_SM1_DST_MODIFIER_SHIFT;
dst->shift = (param & VKD3D_SM1_DSTSHIFT_MASK) >> VKD3D_SM1_DSTSHIFT_SHIFT;
@ -551,9 +545,9 @@ static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool outp
return false;
element = &signature->elements[signature->element_count++];
memset(element, 0, sizeof(*element));
element->semantic_name = name;
element->semantic_index = index;
element->stream_index = 0;
element->sysval_semantic = sysval;
element->component_type = VKD3D_SHADER_COMPONENT_FLOAT;
element->register_index = register_index;
@ -561,7 +555,8 @@ static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool outp
element->register_count = 1;
element->mask = mask;
element->used_mask = is_dcl ? 0 : mask;
element->min_precision = VKD3D_SHADER_MINIMUM_PRECISION_NONE;
if (sm1->p.shader_version.type == VKD3D_SHADER_TYPE_PIXEL && !output)
element->interpolation_mode = VKD3DSIM_LINEAR;
return true;
}
@ -853,6 +848,22 @@ static void shader_sm1_skip_opcode(const struct vkd3d_shader_sm1_parser *sm1, co
return;
}
/* DCL instructions do not have sources or destinations, but they
* read two tokens to a semantic. See
* shader_sm1_read_semantic(). */
if (opcode_info->vkd3d_opcode == VKD3DSIH_DCL)
{
*ptr += 2;
}
/* Somewhat similarly, DEF and DEFI have a single source, but need to read
* four tokens for that source. See shader_sm1_read_immconst().
* Technically shader model 1 doesn't have integer registers or DEFI; we
* handle it here anyway because it's easy. */
else if (opcode_info->vkd3d_opcode == VKD3DSIH_DEF || opcode_info->vkd3d_opcode == VKD3DSIH_DEFI)
{
*ptr += 3;
}
*ptr += (opcode_info->dst_count + opcode_info->src_count);
}
@ -951,9 +962,9 @@ static void shader_sm1_read_semantic(struct vkd3d_shader_sm1_parser *sm1,
}
static void shader_sm1_read_immconst(struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr,
struct vkd3d_shader_src_param *src_param, enum vkd3d_immconst_type type, enum vkd3d_data_type data_type)
struct vkd3d_shader_src_param *src_param, enum vsir_dimension dimension, enum vkd3d_data_type data_type)
{
unsigned int count = type == VKD3D_IMMCONST_VEC4 ? 4 : 1;
unsigned int count = dimension == VSIR_DIMENSION_VEC4 ? 4 : 1;
if (*ptr >= sm1->end || sm1->end - *ptr < count)
{
@ -975,7 +986,7 @@ static void shader_sm1_read_immconst(struct vkd3d_shader_sm1_parser *sm1, const
src_param->reg.idx[2].offset = ~0u;
src_param->reg.idx[2].rel_addr = NULL;
src_param->reg.idx_count = 0;
src_param->reg.immconst_type = type;
src_param->reg.dimension = dimension;
memcpy(src_param->reg.u.immconst_uint, *ptr, count * sizeof(uint32_t));
src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE;
src_param->modifiers = 0;
@ -1090,7 +1101,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str
goto fail;
}
ins->handler_idx = opcode_info->vkd3d_opcode;
vsir_instruction_init(ins, &sm1->p.location, opcode_info->vkd3d_opcode);
ins->flags = (opcode_token & VKD3D_SM1_INSTRUCTION_FLAGS_MASK) >> VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT;
ins->coissue = opcode_token & VKD3D_SM1_COISSUE;
ins->raw = false;
@ -1132,19 +1143,19 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str
else if (ins->handler_idx == VKD3DSIH_DEF)
{
shader_sm1_read_dst_param(sm1, &p, dst_param);
shader_sm1_read_immconst(sm1, &p, &src_params[0], VKD3D_IMMCONST_VEC4, VKD3D_DATA_FLOAT);
shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_VEC4, VKD3D_DATA_FLOAT);
shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true);
}
else if (ins->handler_idx == VKD3DSIH_DEFB)
{
shader_sm1_read_dst_param(sm1, &p, dst_param);
shader_sm1_read_immconst(sm1, &p, &src_params[0], VKD3D_IMMCONST_SCALAR, VKD3D_DATA_UINT);
shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_SCALAR, VKD3D_DATA_UINT);
shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true);
}
else if (ins->handler_idx == VKD3DSIH_DEFI)
{
shader_sm1_read_dst_param(sm1, &p, dst_param);
shader_sm1_read_immconst(sm1, &p, &src_params[0], VKD3D_IMMCONST_VEC4, VKD3D_DATA_INT);
shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_VEC4, VKD3D_DATA_INT);
shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true);
}
else
@ -1250,7 +1261,7 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1,
return VKD3D_ERROR_INVALID_SHADER;
}
if (!shader_ver_le(&version, 3, 0))
if (!vkd3d_shader_ver_le(&version, 3, 0))
{
vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_D3DBC_INVALID_VERSION_TOKEN,
"Invalid shader version %u.%u (token 0x%08x).", version.major, version.minor, code[0]);
@ -1333,12 +1344,22 @@ int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compi
++instructions->count;
}
*parser = &sm1->p;
for (i = 0; i < ARRAY_SIZE(sm1->p.shader_desc.flat_constant_count); ++i)
sm1->p.shader_desc.flat_constant_count[i].external = get_external_constant_count(sm1, i);
return sm1->p.failed ? VKD3D_ERROR_INVALID_SHADER : VKD3D_OK;
if (!sm1->p.failed)
vsir_validate(&sm1->p);
if (sm1->p.failed)
{
WARN("Failed to parse shader.\n");
shader_sm1_destroy(&sm1->p);
return VKD3D_ERROR_INVALID_SHADER;
}
*parser = &sm1->p;
return VKD3D_OK;
}
bool hlsl_sm1_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic,
@ -1811,6 +1832,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)
@ -2177,6 +2229,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;
@ -2199,7 +2255,7 @@ static void write_sm1_jump(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b
struct sm1_instruction instr =
{
.opcode = VKD3D_SM1_OP_TEXKILL,
.opcode = D3DSIO_TEXKILL,
.dst.type = D3DSPR_TEMP,
.dst.reg = reg->id,
@ -2289,6 +2345,8 @@ static void write_sm1_resource_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_
.src_count = 2,
};
if (load->load_type == HLSL_RESOURCE_SAMPLE_PROJ)
sm1_instr.opcode |= VKD3DSI_TEXLD_PROJECT << VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT;
assert(instr->reg.allocated);

View file

@ -94,16 +94,24 @@ static bool require_space(size_t offset, size_t count, size_t size, size_t data_
return !count || (data_size - offset) / count >= size;
}
static void read_dword(const char **ptr, uint32_t *d)
static uint32_t read_u32(const char **ptr)
{
memcpy(d, *ptr, sizeof(*d));
*ptr += sizeof(*d);
unsigned int ret;
memcpy(&ret, *ptr, sizeof(ret));
*ptr += sizeof(ret);
return ret;
}
static void read_float(const char **ptr, float *f)
static float read_float(const char **ptr)
{
union
{
uint32_t i;
float f;
} u;
STATIC_ASSERT(sizeof(float) == sizeof(uint32_t));
read_dword(ptr, (uint32_t *)f);
u.i = read_u32(ptr);
return u.f;
}
static void skip_dword_unknown(const char **ptr, unsigned int count)
@ -117,7 +125,7 @@ static void skip_dword_unknown(const char **ptr, unsigned int count)
WARN("Skipping %u unknown DWORDs:\n", count);
for (i = 0; i < count; ++i)
{
read_dword(ptr, &d);
d = read_u32(ptr);
WARN("\t0x%08x\n", d);
}
}
@ -164,7 +172,7 @@ static int parse_dxbc(const struct vkd3d_shader_code *dxbc, struct vkd3d_shader_
return VKD3D_ERROR_INVALID_ARGUMENT;
}
read_dword(&ptr, &tag);
tag = read_u32(&ptr);
TRACE("tag: %#x.\n", tag);
if (tag != TAG_DXBC)
@ -174,10 +182,10 @@ static int parse_dxbc(const struct vkd3d_shader_code *dxbc, struct vkd3d_shader_
return VKD3D_ERROR_INVALID_ARGUMENT;
}
read_dword(&ptr, &checksum[0]);
read_dword(&ptr, &checksum[1]);
read_dword(&ptr, &checksum[2]);
read_dword(&ptr, &checksum[3]);
checksum[0] = read_u32(&ptr);
checksum[1] = read_u32(&ptr);
checksum[2] = read_u32(&ptr);
checksum[3] = read_u32(&ptr);
vkd3d_compute_dxbc_checksum(data, data_size, calculated_checksum);
if (memcmp(checksum, calculated_checksum, sizeof(checksum)))
{
@ -191,7 +199,7 @@ static int parse_dxbc(const struct vkd3d_shader_code *dxbc, struct vkd3d_shader_
return VKD3D_ERROR_INVALID_ARGUMENT;
}
read_dword(&ptr, &version);
version = read_u32(&ptr);
TRACE("version: %#x.\n", version);
if (version != 0x00000001)
{
@ -201,10 +209,10 @@ static int parse_dxbc(const struct vkd3d_shader_code *dxbc, struct vkd3d_shader_
return VKD3D_ERROR_INVALID_ARGUMENT;
}
read_dword(&ptr, &total_size);
total_size = read_u32(&ptr);
TRACE("total size: %#x\n", total_size);
read_dword(&ptr, &chunk_count);
chunk_count = read_u32(&ptr);
TRACE("chunk count: %#x\n", chunk_count);
if (!(sections = vkd3d_calloc(chunk_count, sizeof(*sections))))
@ -219,7 +227,7 @@ static int parse_dxbc(const struct vkd3d_shader_code *dxbc, struct vkd3d_shader_
const char *chunk_ptr;
uint32_t chunk_offset;
read_dword(&ptr, &chunk_offset);
chunk_offset = read_u32(&ptr);
TRACE("chunk %u at offset %#x\n", i, chunk_offset);
if (chunk_offset >= data_size || !require_space(chunk_offset, 2, sizeof(DWORD), data_size))
@ -233,8 +241,8 @@ static int parse_dxbc(const struct vkd3d_shader_code *dxbc, struct vkd3d_shader_
chunk_ptr = data + chunk_offset;
read_dword(&chunk_ptr, &chunk_tag);
read_dword(&chunk_ptr, &chunk_size);
chunk_tag = read_u32(&chunk_ptr);
chunk_size = read_u32(&chunk_ptr);
if (!require_space(chunk_ptr - data, 1, chunk_size, data_size))
{
@ -359,10 +367,10 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s
return VKD3D_ERROR_INVALID_ARGUMENT;
}
read_dword(&ptr, &count);
count = read_u32(&ptr);
TRACE("%u elements.\n", count);
read_dword(&ptr, &header_size);
header_size = read_u32(&ptr);
i = header_size / sizeof(uint32_t);
if (align(header_size, sizeof(uint32_t)) != header_size || i < 2
|| !require_space(2, i - 2, sizeof(uint32_t), section->data.size))
@ -396,24 +404,24 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s
e[i].sort_index = i;
if (has_stream_index)
read_dword(&ptr, &e[i].stream_index);
e[i].stream_index = read_u32(&ptr);
else
e[i].stream_index = 0;
read_dword(&ptr, &name_offset);
name_offset = read_u32(&ptr);
if (!(e[i].semantic_name = shader_get_string(data, section->data.size, name_offset)))
{
WARN("Invalid name offset %#x (data size %#zx).\n", name_offset, section->data.size);
vkd3d_free(e);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
read_dword(&ptr, &e[i].semantic_index);
read_dword(&ptr, &e[i].sysval_semantic);
read_dword(&ptr, &e[i].component_type);
read_dword(&ptr, &e[i].register_index);
e[i].semantic_index = read_u32(&ptr);
e[i].sysval_semantic = read_u32(&ptr);
e[i].component_type = read_u32(&ptr);
e[i].register_index = read_u32(&ptr);
e[i].target_location = e[i].register_index;
e[i].register_count = 1;
read_dword(&ptr, &mask);
mask = read_u32(&ptr);
e[i].mask = mask & 0xff;
e[i].used_mask = (mask >> 8) & 0xff;
switch (section->tag)
@ -431,10 +439,12 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s
}
if (has_min_precision)
read_dword(&ptr, &e[i].min_precision);
e[i].min_precision = read_u32(&ptr);
else
e[i].min_precision = VKD3D_SHADER_MINIMUM_PRECISION_NONE;
e[i].interpolation_mode = VKD3DSIM_NONE;
TRACE("Stream: %u, semantic: %s, semantic idx: %u, sysval_semantic %#x, "
"type %u, register idx: %u, use_mask %#x, input_mask %#x, precision %u.\n",
e[i].stream_index, debugstr_a(e[i].semantic_name), e[i].semantic_index, e[i].sysval_semantic,
@ -452,7 +462,7 @@ static int isgn_handler(const struct vkd3d_shader_dxbc_section_desc *section,
{
struct shader_signature *is = ctx;
if (section->tag != TAG_ISGN)
if (section->tag != TAG_ISGN && section->tag != TAG_ISG1)
return VKD3D_OK;
if (is->elements)
@ -595,11 +605,11 @@ static int shader_parse_descriptor_ranges(struct root_signature_parser_context *
for (i = 0; i < count; ++i)
{
read_dword(&ptr, &ranges[i].range_type);
read_dword(&ptr, &ranges[i].descriptor_count);
read_dword(&ptr, &ranges[i].base_shader_register);
read_dword(&ptr, &ranges[i].register_space);
read_dword(&ptr, &ranges[i].descriptor_table_offset);
ranges[i].range_type = read_u32(&ptr);
ranges[i].descriptor_count = read_u32(&ptr);
ranges[i].base_shader_register = read_u32(&ptr);
ranges[i].register_space = read_u32(&ptr);
ranges[i].descriptor_table_offset = read_u32(&ptr);
TRACE("Type %#x, descriptor count %u, base shader register %u, "
"register space %u, offset %u.\n",
@ -638,12 +648,12 @@ static int shader_parse_descriptor_ranges1(struct root_signature_parser_context
for (i = 0; i < count; ++i)
{
read_dword(&ptr, &ranges[i].range_type);
read_dword(&ptr, &ranges[i].descriptor_count);
read_dword(&ptr, &ranges[i].base_shader_register);
read_dword(&ptr, &ranges[i].register_space);
read_dword(&ptr, &ranges[i].flags);
read_dword(&ptr, &ranges[i].descriptor_table_offset);
ranges[i].range_type = read_u32(&ptr);
ranges[i].descriptor_count = read_u32(&ptr);
ranges[i].base_shader_register = read_u32(&ptr);
ranges[i].register_space = read_u32(&ptr);
ranges[i].flags = read_u32(&ptr);
ranges[i].descriptor_table_offset = read_u32(&ptr);
TRACE("Type %#x, descriptor count %u, base shader register %u, "
"register space %u, flags %#x, offset %u.\n",
@ -671,8 +681,8 @@ static int shader_parse_descriptor_table(struct root_signature_parser_context *c
}
ptr = &context->data[offset];
read_dword(&ptr, &count);
read_dword(&ptr, &offset);
count = read_u32(&ptr);
offset = read_u32(&ptr);
TRACE("Descriptor range count %u.\n", count);
@ -698,8 +708,8 @@ static int shader_parse_descriptor_table1(struct root_signature_parser_context *
}
ptr = &context->data[offset];
read_dword(&ptr, &count);
read_dword(&ptr, &offset);
count = read_u32(&ptr);
offset = read_u32(&ptr);
TRACE("Descriptor range count %u.\n", count);
@ -723,9 +733,9 @@ static int shader_parse_root_constants(struct root_signature_parser_context *con
}
ptr = &context->data[offset];
read_dword(&ptr, &constants->shader_register);
read_dword(&ptr, &constants->register_space);
read_dword(&ptr, &constants->value_count);
constants->shader_register = read_u32(&ptr);
constants->register_space = read_u32(&ptr);
constants->value_count = read_u32(&ptr);
TRACE("Shader register %u, register space %u, 32-bit value count %u.\n",
constants->shader_register, constants->register_space, constants->value_count);
@ -745,8 +755,8 @@ static int shader_parse_root_descriptor(struct root_signature_parser_context *co
}
ptr = &context->data[offset];
read_dword(&ptr, &descriptor->shader_register);
read_dword(&ptr, &descriptor->register_space);
descriptor->shader_register = read_u32(&ptr);
descriptor->register_space = read_u32(&ptr);
TRACE("Shader register %u, register space %u.\n",
descriptor->shader_register, descriptor->register_space);
@ -777,9 +787,9 @@ static int shader_parse_root_descriptor1(struct root_signature_parser_context *c
}
ptr = &context->data[offset];
read_dword(&ptr, &descriptor->shader_register);
read_dword(&ptr, &descriptor->register_space);
read_dword(&ptr, &descriptor->flags);
descriptor->shader_register = read_u32(&ptr);
descriptor->register_space = read_u32(&ptr);
descriptor->flags = read_u32(&ptr);
TRACE("Shader register %u, register space %u, flags %#x.\n",
descriptor->shader_register, descriptor->register_space, descriptor->flags);
@ -805,9 +815,9 @@ static int shader_parse_root_parameters(struct root_signature_parser_context *co
for (i = 0; i < count; ++i)
{
read_dword(&ptr, &parameters[i].parameter_type);
read_dword(&ptr, &parameters[i].shader_visibility);
read_dword(&ptr, &offset);
parameters[i].parameter_type = read_u32(&ptr);
parameters[i].shader_visibility = read_u32(&ptr);
offset = read_u32(&ptr);
TRACE("Type %#x, shader visibility %#x.\n",
parameters[i].parameter_type, parameters[i].shader_visibility);
@ -853,9 +863,9 @@ static int shader_parse_root_parameters1(struct root_signature_parser_context *c
for (i = 0; i < count; ++i)
{
read_dword(&ptr, &parameters[i].parameter_type);
read_dword(&ptr, &parameters[i].shader_visibility);
read_dword(&ptr, &offset);
parameters[i].parameter_type = read_u32(&ptr);
parameters[i].shader_visibility = read_u32(&ptr);
offset = read_u32(&ptr);
TRACE("Type %#x, shader visibility %#x.\n",
parameters[i].parameter_type, parameters[i].shader_visibility);
@ -900,19 +910,19 @@ static int shader_parse_static_samplers(struct root_signature_parser_context *co
for (i = 0; i < count; ++i)
{
read_dword(&ptr, &sampler_descs[i].filter);
read_dword(&ptr, &sampler_descs[i].address_u);
read_dword(&ptr, &sampler_descs[i].address_v);
read_dword(&ptr, &sampler_descs[i].address_w);
read_float(&ptr, &sampler_descs[i].mip_lod_bias);
read_dword(&ptr, &sampler_descs[i].max_anisotropy);
read_dword(&ptr, &sampler_descs[i].comparison_func);
read_dword(&ptr, &sampler_descs[i].border_colour);
read_float(&ptr, &sampler_descs[i].min_lod);
read_float(&ptr, &sampler_descs[i].max_lod);
read_dword(&ptr, &sampler_descs[i].shader_register);
read_dword(&ptr, &sampler_descs[i].register_space);
read_dword(&ptr, &sampler_descs[i].shader_visibility);
sampler_descs[i].filter = read_u32(&ptr);
sampler_descs[i].address_u = read_u32(&ptr);
sampler_descs[i].address_v = read_u32(&ptr);
sampler_descs[i].address_w = read_u32(&ptr);
sampler_descs[i].mip_lod_bias = read_float(&ptr);
sampler_descs[i].max_anisotropy = read_u32(&ptr);
sampler_descs[i].comparison_func = read_u32(&ptr);
sampler_descs[i].border_colour = read_u32(&ptr);
sampler_descs[i].min_lod = read_float(&ptr);
sampler_descs[i].max_lod = read_float(&ptr);
sampler_descs[i].shader_register = read_u32(&ptr);
sampler_descs[i].register_space = read_u32(&ptr);
sampler_descs[i].shader_visibility = read_u32(&ptr);
}
return VKD3D_OK;
@ -936,7 +946,7 @@ static int shader_parse_root_signature(const struct vkd3d_shader_code *data,
return VKD3D_ERROR_INVALID_ARGUMENT;
}
read_dword(&ptr, &version);
version = read_u32(&ptr);
TRACE("Version %#x.\n", version);
if (version != VKD3D_SHADER_ROOT_SIGNATURE_VERSION_1_0 && version != VKD3D_SHADER_ROOT_SIGNATURE_VERSION_1_1)
{
@ -945,8 +955,8 @@ static int shader_parse_root_signature(const struct vkd3d_shader_code *data,
}
desc->version = version;
read_dword(&ptr, &count);
read_dword(&ptr, &offset);
count = read_u32(&ptr);
offset = read_u32(&ptr);
TRACE("Parameter count %u, offset %u.\n", count, offset);
if (desc->version == VKD3D_SHADER_ROOT_SIGNATURE_VERSION_1_0)
@ -980,8 +990,8 @@ static int shader_parse_root_signature(const struct vkd3d_shader_code *data,
}
}
read_dword(&ptr, &count);
read_dword(&ptr, &offset);
count = read_u32(&ptr);
offset = read_u32(&ptr);
TRACE("Static sampler count %u, offset %u.\n", count, offset);
v_1_0->static_sampler_count = count;
@ -995,7 +1005,7 @@ static int shader_parse_root_signature(const struct vkd3d_shader_code *data,
return ret;
}
read_dword(&ptr, &v_1_0->flags);
v_1_0->flags = read_u32(&ptr);
TRACE("Flags %#x.\n", v_1_0->flags);
return VKD3D_OK;

File diff suppressed because it is too large Load diff

View file

@ -216,13 +216,15 @@ bool hlsl_type_is_resource(const struct hlsl_type *type)
return false;
}
enum hlsl_regset hlsl_type_get_regset(const struct hlsl_type *type)
/* Only intended to be used for derefs (after copies have been lowered to components or vectors) or
* resources, since for both their data types span across a single regset. */
static enum hlsl_regset type_get_regset(const struct hlsl_type *type)
{
if (type->class <= HLSL_CLASS_LAST_NUMERIC)
if (hlsl_is_numeric_type(type))
return HLSL_REGSET_NUMERIC;
if (type->class == HLSL_CLASS_ARRAY)
return hlsl_type_get_regset(type->e.array.type);
return type_get_regset(type->e.array.type);
if (type->class == HLSL_CLASS_OBJECT)
{
@ -245,6 +247,11 @@ enum hlsl_regset hlsl_type_get_regset(const struct hlsl_type *type)
vkd3d_unreachable();
}
enum hlsl_regset hlsl_deref_get_regset(struct hlsl_ctx *ctx, const struct hlsl_deref *deref)
{
return type_get_regset(hlsl_deref_get_type(ctx, deref));
}
unsigned int hlsl_type_get_sm4_offset(const struct hlsl_type *type, unsigned int offset)
{
/* Align to the next vec4 boundary if:
@ -324,7 +331,7 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type
{
if (hlsl_type_is_resource(type))
{
enum hlsl_regset regset = hlsl_type_get_regset(type);
enum hlsl_regset regset = type_get_regset(type);
type->reg_size[regset] = 1;
}
@ -452,11 +459,11 @@ struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl
}
unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_type *type,
enum hlsl_regset regset, unsigned int index)
unsigned int index, enum hlsl_regset *regset)
{
unsigned int offset[HLSL_REGSET_LAST + 1] = {0};
struct hlsl_type *next_type;
unsigned int offset = 0;
unsigned int idx;
unsigned int idx, r;
while (!type_is_single_component(type))
{
@ -468,19 +475,22 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty
case HLSL_CLASS_SCALAR:
case HLSL_CLASS_VECTOR:
case HLSL_CLASS_MATRIX:
if (regset == HLSL_REGSET_NUMERIC)
offset += idx;
offset[HLSL_REGSET_NUMERIC] += idx;
break;
case HLSL_CLASS_STRUCT:
offset += type->e.record.fields[idx].reg_offset[regset];
for (r = 0; r <= HLSL_REGSET_LAST; ++r)
offset[r] += type->e.record.fields[idx].reg_offset[r];
break;
case HLSL_CLASS_ARRAY:
if (regset == HLSL_REGSET_NUMERIC)
offset += idx * align(type->e.array.type->reg_size[regset], 4);
else
offset += idx * type->e.array.type->reg_size[regset];
for (r = 0; r <= HLSL_REGSET_LAST; ++r)
{
if (r == HLSL_REGSET_NUMERIC)
offset[r] += idx * align(type->e.array.type->reg_size[r], 4);
else
offset[r] += idx * type->e.array.type->reg_size[r];
}
break;
case HLSL_CLASS_OBJECT:
@ -493,7 +503,8 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty
type = next_type;
}
return offset;
*regset = type_get_regset(type);
return offset[*regset];
}
static bool init_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_var *var,
@ -501,7 +512,9 @@ static bool init_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hl
{
deref->var = var;
deref->path_len = path_len;
deref->offset.node = NULL;
deref->rel_offset.node = NULL;
deref->const_offset = 0;
deref->data_type = NULL;
if (path_len == 0)
{
@ -528,7 +541,8 @@ bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *d
deref->path = NULL;
deref->path_len = 0;
deref->offset.node = NULL;
deref->rel_offset.node = NULL;
deref->const_offset = 0;
assert(chain);
if (chain->type == HLSL_IR_INDEX)
@ -591,7 +605,7 @@ struct hlsl_type *hlsl_deref_get_type(struct hlsl_ctx *ctx, const struct hlsl_de
assert(deref);
if (deref->offset.node)
if (hlsl_deref_is_lowered(deref))
return deref->data_type;
type = deref->var->data_type;
@ -745,7 +759,7 @@ struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim
{
struct hlsl_type *type;
if (!(type = vkd3d_calloc(1, sizeof(*type))))
if (!(type = hlsl_alloc(ctx, sizeof(*type))))
return NULL;
type->class = HLSL_CLASS_OBJECT;
type->base_type = HLSL_TYPE_UAV;
@ -811,17 +825,15 @@ struct hlsl_ir_function *hlsl_get_function(struct hlsl_ctx *ctx, const char *nam
return NULL;
}
struct hlsl_ir_function_decl *hlsl_get_func_decl(struct hlsl_ctx *ctx, const char *name)
struct hlsl_ir_function_decl *hlsl_get_first_func_decl(struct hlsl_ctx *ctx, const char *name)
{
struct hlsl_ir_function_decl *decl;
struct hlsl_ir_function *func;
struct rb_entry *entry;
if ((entry = rb_get(&ctx->functions, name)))
{
func = RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry);
RB_FOR_EACH_ENTRY(decl, &func->overloads, struct hlsl_ir_function_decl, entry)
return decl;
return LIST_ENTRY(list_head(&func->overloads), struct hlsl_ir_function_decl, entry);
}
return NULL;
@ -1102,7 +1114,7 @@ bool hlsl_copy_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, const struc
if (!other)
return true;
assert(!other->offset.node);
assert(!hlsl_deref_is_lowered(other));
if (!init_deref(ctx, deref, other->var, other->path_len))
return false;
@ -1124,7 +1136,8 @@ void hlsl_cleanup_deref(struct hlsl_deref *deref)
deref->path = NULL;
deref->path_len = 0;
hlsl_src_remove(&deref->offset);
hlsl_src_remove(&deref->rel_offset);
deref->const_offset = 0;
}
/* Initializes a simple variable dereference, so that it can be passed to load/store functions. */
@ -1159,7 +1172,7 @@ struct hlsl_ir_node *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hls
unsigned int i;
assert(lhs);
assert(!lhs->offset.node);
assert(!hlsl_deref_is_lowered(lhs));
if (!(store = hlsl_alloc(ctx, sizeof(*store))))
return NULL;
@ -1325,6 +1338,40 @@ struct hlsl_ir_node *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *cond
return &iff->node;
}
struct hlsl_ir_switch_case *hlsl_new_switch_case(struct hlsl_ctx *ctx, unsigned int value,
bool is_default, struct hlsl_block *body, const struct vkd3d_shader_location *loc)
{
struct hlsl_ir_switch_case *c;
if (!(c = hlsl_alloc(ctx, sizeof(*c))))
return NULL;
c->value = value;
c->is_default = is_default;
hlsl_block_init(&c->body);
if (body)
hlsl_block_add_block(&c->body, body);
c->loc = *loc;
return c;
}
struct hlsl_ir_node *hlsl_new_switch(struct hlsl_ctx *ctx, struct hlsl_ir_node *selector,
struct list *cases, const struct vkd3d_shader_location *loc)
{
struct hlsl_ir_switch *s;
if (!(s = hlsl_alloc(ctx, sizeof(*s))))
return NULL;
init_node(&s->node, HLSL_IR_SWITCH, NULL, loc);
hlsl_src_from_node(&s->selector, selector);
list_init(&s->cases);
if (cases)
list_move_head(&s->cases, cases);
return &s->node;
}
struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl_deref *deref,
struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc)
{
@ -1332,7 +1379,7 @@ struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl
struct hlsl_type *type;
unsigned int i;
assert(!deref->offset.node);
assert(!hlsl_deref_is_lowered(deref));
type = hlsl_deref_get_type(ctx, deref);
if (idx)
@ -1568,7 +1615,7 @@ static bool clone_block(struct hlsl_ctx *ctx, struct hlsl_block *dst_block,
if (!list_empty(&src->uses))
{
if (!vkd3d_array_reserve((void **)&map->instrs, &map->capacity, map->count + 1, sizeof(*map->instrs)))
if (!hlsl_array_reserve(ctx, (void **)&map->instrs, &map->capacity, map->count + 1, sizeof(*map->instrs)))
{
hlsl_block_cleanup(dst_block);
return false;
@ -1605,7 +1652,7 @@ static bool clone_deref(struct hlsl_ctx *ctx, struct clone_instr_map *map,
{
unsigned int i;
assert(!src->offset.node);
assert(!hlsl_deref_is_lowered(src));
if (!init_deref(ctx, dst, src->var, src->path_len))
return false;
@ -1787,6 +1834,58 @@ static struct hlsl_ir_node *clone_index(struct hlsl_ctx *ctx, struct clone_instr
return dst;
}
void hlsl_free_ir_switch_case(struct hlsl_ir_switch_case *c)
{
hlsl_block_cleanup(&c->body);
list_remove(&c->entry);
vkd3d_free(c);
}
void hlsl_cleanup_ir_switch_cases(struct list *cases)
{
struct hlsl_ir_switch_case *c, *next;
LIST_FOR_EACH_ENTRY_SAFE(c, next, cases, struct hlsl_ir_switch_case, entry)
{
hlsl_free_ir_switch_case(c);
}
}
static struct hlsl_ir_node *clone_switch(struct hlsl_ctx *ctx,
struct clone_instr_map *map, struct hlsl_ir_switch *s)
{
struct hlsl_ir_switch_case *c, *d;
struct hlsl_ir_node *ret;
struct hlsl_block body;
struct list cases;
list_init(&cases);
LIST_FOR_EACH_ENTRY(c, &s->cases, struct hlsl_ir_switch_case, entry)
{
if (!(clone_block(ctx, &body, &c->body, map)))
{
hlsl_cleanup_ir_switch_cases(&cases);
return NULL;
}
d = hlsl_new_switch_case(ctx, c->value, c->is_default, &body, &c->loc);
hlsl_block_cleanup(&body);
if (!d)
{
hlsl_cleanup_ir_switch_cases(&cases);
return NULL;
}
list_add_tail(&cases, &d->entry);
}
ret = hlsl_new_switch(ctx, map_instr(map, s->selector.node), &cases, &s->node.loc);
hlsl_cleanup_ir_switch_cases(&cases);
return ret;
}
static struct hlsl_ir_node *clone_instr(struct hlsl_ctx *ctx,
struct clone_instr_map *map, const struct hlsl_ir_node *instr)
{
@ -1825,6 +1924,9 @@ static struct hlsl_ir_node *clone_instr(struct hlsl_ctx *ctx,
case HLSL_IR_STORE:
return clone_store(ctx, map, hlsl_ir_store(instr));
case HLSL_IR_SWITCH:
return clone_switch(ctx, map, hlsl_ir_switch(instr));
case HLSL_IR_SWIZZLE:
return clone_swizzle(ctx, map, hlsl_ir_swizzle(instr));
}
@ -1946,76 +2048,38 @@ void hlsl_pop_scope(struct hlsl_ctx *ctx)
ctx->cur_scope = prev_scope;
}
static int compare_param_hlsl_types(const struct hlsl_type *t1, const struct hlsl_type *t2)
static bool func_decl_matches(const struct hlsl_ir_function_decl *decl,
const struct hlsl_func_parameters *parameters)
{
int r;
if ((r = vkd3d_u32_compare(t1->class, t2->class)))
{
if (!((t1->class == HLSL_CLASS_SCALAR && t2->class == HLSL_CLASS_VECTOR)
|| (t1->class == HLSL_CLASS_VECTOR && t2->class == HLSL_CLASS_SCALAR)))
return r;
}
if ((r = vkd3d_u32_compare(t1->base_type, t2->base_type)))
return r;
if (t1->base_type == HLSL_TYPE_SAMPLER || t1->base_type == HLSL_TYPE_TEXTURE)
{
if ((r = vkd3d_u32_compare(t1->sampler_dim, t2->sampler_dim)))
return r;
if (t1->base_type == HLSL_TYPE_TEXTURE && t1->sampler_dim != HLSL_SAMPLER_DIM_GENERIC
&& (r = compare_param_hlsl_types(t1->e.resource_format, t2->e.resource_format)))
return r;
}
if ((r = vkd3d_u32_compare(t1->dimx, t2->dimx)))
return r;
if ((r = vkd3d_u32_compare(t1->dimy, t2->dimy)))
return r;
if (t1->class == HLSL_CLASS_STRUCT)
{
size_t i;
if (t1->e.record.field_count != t2->e.record.field_count)
return t1->e.record.field_count - t2->e.record.field_count;
for (i = 0; i < t1->e.record.field_count; ++i)
{
const struct hlsl_struct_field *field1 = &t1->e.record.fields[i];
const struct hlsl_struct_field *field2 = &t2->e.record.fields[i];
if ((r = compare_param_hlsl_types(field1->type, field2->type)))
return r;
if ((r = strcmp(field1->name, field2->name)))
return r;
}
return 0;
}
if (t1->class == HLSL_CLASS_ARRAY)
{
if ((r = vkd3d_u32_compare(t1->e.array.elements_count, t2->e.array.elements_count)))
return r;
return compare_param_hlsl_types(t1->e.array.type, t2->e.array.type);
}
return 0;
}
static int compare_function_decl_rb(const void *key, const struct rb_entry *entry)
{
const struct hlsl_ir_function_decl *decl = RB_ENTRY_VALUE(entry, const struct hlsl_ir_function_decl, entry);
const struct hlsl_func_parameters *parameters = key;
size_t i;
int r;
if ((r = vkd3d_u32_compare(parameters->count, decl->parameters.count)))
return r;
if (parameters->count != decl->parameters.count)
return false;
for (i = 0; i < parameters->count; ++i)
{
if ((r = compare_param_hlsl_types(parameters->vars[i]->data_type, decl->parameters.vars[i]->data_type)))
return r;
if (!hlsl_types_are_equal(parameters->vars[i]->data_type, decl->parameters.vars[i]->data_type))
return false;
}
return 0;
return true;
}
struct hlsl_ir_function_decl *hlsl_get_func_decl(struct hlsl_ctx *ctx, const char *name,
const struct hlsl_func_parameters *parameters)
{
struct hlsl_ir_function_decl *decl;
struct hlsl_ir_function *func;
if (!(func = hlsl_get_function(ctx, name)))
return NULL;
LIST_FOR_EACH_ENTRY(decl, &func->overloads, struct hlsl_ir_function_decl, entry)
{
if (func_decl_matches(decl, parameters))
return decl;
}
return NULL;
}
struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const struct hlsl_type *type)
@ -2191,8 +2255,14 @@ struct vkd3d_string_buffer *hlsl_modifiers_to_string(struct hlsl_ctx *ctx, unsig
if (modifiers & HLSL_STORAGE_EXTERN)
vkd3d_string_buffer_printf(string, "extern ");
if (modifiers & HLSL_STORAGE_LINEAR)
vkd3d_string_buffer_printf(string, "linear ");
if (modifiers & HLSL_STORAGE_NOINTERPOLATION)
vkd3d_string_buffer_printf(string, "nointerpolation ");
if (modifiers & HLSL_STORAGE_CENTROID)
vkd3d_string_buffer_printf(string, "centroid ");
if (modifiers & HLSL_STORAGE_NOPERSPECTIVE)
vkd3d_string_buffer_printf(string, "noperspective ");
if (modifiers & HLSL_MODIFIER_PRECISE)
vkd3d_string_buffer_printf(string, "precise ");
if (modifiers & HLSL_STORAGE_SHARED)
@ -2239,6 +2309,7 @@ const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type)
[HLSL_IR_RESOURCE_LOAD ] = "HLSL_IR_RESOURCE_LOAD",
[HLSL_IR_RESOURCE_STORE] = "HLSL_IR_RESOURCE_STORE",
[HLSL_IR_STORE ] = "HLSL_IR_STORE",
[HLSL_IR_SWITCH ] = "HLSL_IR_SWITCH",
[HLSL_IR_SWIZZLE ] = "HLSL_IR_SWIZZLE",
};
@ -2305,21 +2376,34 @@ static void dump_deref(struct vkd3d_string_buffer *buffer, const struct hlsl_der
if (deref->var)
{
vkd3d_string_buffer_printf(buffer, "%s", deref->var->name);
if (deref->path_len)
if (!hlsl_deref_is_lowered(deref))
{
vkd3d_string_buffer_printf(buffer, "[");
for (i = 0; i < deref->path_len; ++i)
if (deref->path_len)
{
vkd3d_string_buffer_printf(buffer, "[");
dump_src(buffer, &deref->path[i]);
for (i = 0; i < deref->path_len; ++i)
{
vkd3d_string_buffer_printf(buffer, "[");
dump_src(buffer, &deref->path[i]);
vkd3d_string_buffer_printf(buffer, "]");
}
vkd3d_string_buffer_printf(buffer, "]");
}
vkd3d_string_buffer_printf(buffer, "]");
}
else if (deref->offset.node)
else
{
bool show_rel, show_const;
show_rel = deref->rel_offset.node;
show_const = deref->const_offset != 0 || !show_rel;
vkd3d_string_buffer_printf(buffer, "[");
dump_src(buffer, &deref->offset);
if (show_rel)
dump_src(buffer, &deref->rel_offset);
if (show_rel && show_const)
vkd3d_string_buffer_printf(buffer, " + ");
if (show_const)
vkd3d_string_buffer_printf(buffer, "%uc", deref->const_offset);
vkd3d_string_buffer_printf(buffer, "]");
}
}
@ -2440,6 +2524,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",
@ -2449,6 +2534,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] = "!",
@ -2485,6 +2571,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",
@ -2540,6 +2627,10 @@ static void dump_ir_jump(struct vkd3d_string_buffer *buffer, const struct hlsl_i
case HLSL_IR_JUMP_RETURN:
vkd3d_string_buffer_printf(buffer, "return");
break;
case HLSL_IR_JUMP_UNRESOLVED_CONTINUE:
vkd3d_string_buffer_printf(buffer, "unresolved_continue");
break;
}
}
@ -2659,6 +2750,32 @@ static void dump_ir_index(struct vkd3d_string_buffer *buffer, const struct hlsl_
vkd3d_string_buffer_printf(buffer, "]");
}
static void dump_ir_switch(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, const struct hlsl_ir_switch *s)
{
struct hlsl_ir_switch_case *c;
vkd3d_string_buffer_printf(buffer, "switch (");
dump_src(buffer, &s->selector);
vkd3d_string_buffer_printf(buffer, ") {\n");
LIST_FOR_EACH_ENTRY(c, &s->cases, struct hlsl_ir_switch_case, entry)
{
if (c->is_default)
{
vkd3d_string_buffer_printf(buffer, " %10s default: {\n", "");
}
else
{
vkd3d_string_buffer_printf(buffer, " %10s case %u : {\n", "", c->value);
}
dump_block(ctx, buffer, &c->body);
vkd3d_string_buffer_printf(buffer, " %10s }\n", "");
}
vkd3d_string_buffer_printf(buffer, " %10s }", "");
}
static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, const struct hlsl_ir_node *instr)
{
if (instr->index)
@ -2714,6 +2831,10 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer,
dump_ir_store(buffer, hlsl_ir_store(instr));
break;
case HLSL_IR_SWITCH:
dump_ir_switch(ctx, buffer, hlsl_ir_switch(instr));
break;
case HLSL_IR_SWIZZLE:
dump_ir_swizzle(buffer, hlsl_ir_swizzle(instr));
break;
@ -2855,7 +2976,7 @@ static void free_ir_resource_load(struct hlsl_ir_resource_load *load)
static void free_ir_resource_store(struct hlsl_ir_resource_store *store)
{
hlsl_src_remove(&store->resource.offset);
hlsl_src_remove(&store->resource.rel_offset);
hlsl_src_remove(&store->coords);
hlsl_src_remove(&store->value);
vkd3d_free(store);
@ -2874,6 +2995,14 @@ static void free_ir_swizzle(struct hlsl_ir_swizzle *swizzle)
vkd3d_free(swizzle);
}
static void free_ir_switch(struct hlsl_ir_switch *s)
{
hlsl_src_remove(&s->selector);
hlsl_cleanup_ir_switch_cases(&s->cases);
vkd3d_free(s);
}
static void free_ir_index(struct hlsl_ir_index *index)
{
hlsl_src_remove(&index->val);
@ -2934,6 +3063,10 @@ void hlsl_free_instr(struct hlsl_ir_node *node)
case HLSL_IR_SWIZZLE:
free_ir_swizzle(hlsl_ir_swizzle(node));
break;
case HLSL_IR_SWITCH:
free_ir_switch(hlsl_ir_switch(node));
break;
}
}
@ -2967,14 +3100,12 @@ static void free_function_decl(struct hlsl_ir_function_decl *decl)
vkd3d_free(decl);
}
static void free_function_decl_rb(struct rb_entry *entry, void *context)
{
free_function_decl(RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry));
}
static void free_function(struct hlsl_ir_function *func)
{
rb_destroy(&func->overloads, free_function_decl_rb, NULL);
struct hlsl_ir_function_decl *decl, *next;
LIST_FOR_EACH_ENTRY_SAFE(decl, next, &func->overloads, struct hlsl_ir_function_decl, entry)
free_function_decl(decl);
vkd3d_free((void *)func->name);
vkd3d_free(func);
}
@ -3004,17 +3135,15 @@ void hlsl_add_function(struct hlsl_ctx *ctx, char *name, struct hlsl_ir_function
{
func = RB_ENTRY_VALUE(func_entry, struct hlsl_ir_function, entry);
decl->func = func;
if (rb_put(&func->overloads, &decl->parameters, &decl->entry) == -1)
ERR("Failed to insert function overload.\n");
list_add_tail(&func->overloads, &decl->entry);
vkd3d_free(name);
return;
}
func = hlsl_alloc(ctx, sizeof(*func));
func->name = name;
rb_init(&func->overloads, compare_function_decl_rb);
list_init(&func->overloads);
decl->func = func;
rb_put(&func->overloads, &decl->parameters, &decl->entry);
list_add_tail(&func->overloads, &decl->entry);
rb_put(&ctx->functions, func->name, &func->entry);
}
@ -3092,7 +3221,7 @@ unsigned int hlsl_combine_swizzles(unsigned int first, unsigned int second, unsi
return ret;
}
static const struct hlsl_profile_info *get_target_info(const char *target)
const struct hlsl_profile_info *hlsl_get_target_info(const char *target)
{
unsigned int i;
@ -3395,6 +3524,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;
@ -3455,14 +3588,12 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
}
entry_point = hlsl_source_info->entry_point ? hlsl_source_info->entry_point : "main";
if (!(profile = get_target_info(hlsl_source_info->profile)))
if (!(profile = hlsl_get_target_info(hlsl_source_info->profile)))
{
FIXME("Unknown compilation target %s.\n", debugstr_a(hlsl_source_info->profile));
return VKD3D_ERROR_NOT_IMPLEMENTED;
}
vkd3d_shader_dump_shader(compile_info->source_type, profile->type, &compile_info->source);
if (compile_info->target_type == VKD3D_SHADER_TARGET_D3D_BYTECODE && profile->major_version > 3)
{
vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE,
@ -3501,7 +3632,7 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
if ((func = hlsl_get_function(&ctx, entry_point)))
{
RB_FOR_EACH_ENTRY(decl, &func->overloads, struct hlsl_ir_function_decl, entry)
LIST_FOR_EACH_ENTRY(decl, &func->overloads, struct hlsl_ir_function_decl, entry)
{
if (!decl->has_body)
continue;
@ -3567,7 +3698,7 @@ struct hlsl_ir_function_decl *hlsl_compile_internal_function(struct hlsl_ctx *ct
hlsl_release_string_buffer(ctx, internal_name);
return NULL;
}
func = hlsl_get_func_decl(ctx, internal_name->buffer);
func = hlsl_get_first_func_decl(ctx, internal_name->buffer);
hlsl_release_string_buffer(ctx, internal_name);
return func;
}

View file

@ -25,9 +25,6 @@
#include "d3dcommon.h"
#include "d3dx9shader.h"
enum vkd3d_sm4_register_type;
enum vkd3d_sm4_swizzle_type;
/* The general IR structure is inspired by Mesa GLSL hir, even though the code
* ends up being quite different in practice. Anyway, here comes the relevant
* licensing information.
@ -284,6 +281,7 @@ enum hlsl_ir_node_type
HLSL_IR_RESOURCE_STORE,
HLSL_IR_STORE,
HLSL_IR_SWIZZLE,
HLSL_IR_SWITCH,
};
/* Common data for every type of IR instruction node. */
@ -357,11 +355,17 @@ struct hlsl_attribute
#define HLSL_STORAGE_IN 0x00000800
#define HLSL_STORAGE_OUT 0x00001000
#define HLSL_MODIFIER_INLINE 0x00002000
#define HLSL_STORAGE_CENTROID 0x00004000
#define HLSL_STORAGE_NOPERSPECTIVE 0x00008000
#define HLSL_STORAGE_LINEAR 0x00010000
#define HLSL_TYPE_MODIFIERS_MASK (HLSL_MODIFIER_PRECISE | HLSL_MODIFIER_VOLATILE | \
HLSL_MODIFIER_CONST | HLSL_MODIFIER_ROW_MAJOR | \
HLSL_MODIFIER_COLUMN_MAJOR)
#define HLSL_INTERPOLATION_MODIFIERS_MASK (HLSL_STORAGE_NOINTERPOLATION | HLSL_STORAGE_CENTROID | \
HLSL_STORAGE_NOPERSPECTIVE | HLSL_STORAGE_LINEAR)
#define HLSL_MODIFIERS_MAJORITY_MASK (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)
#define HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT 0
@ -369,7 +373,7 @@ struct hlsl_attribute
/* Reservation of a register and/or an offset for objects inside constant buffers, to be used as a
* starting point of their allocation. They are available through the register(·) and the
* packoffset(·) syntaxes, respectivelly.
* The costant buffer offset is measured register components. */
* The constant buffer offset is measured register components. */
struct hlsl_reg_reservation
{
char reg_type;
@ -422,6 +426,9 @@ struct hlsl_ir_var
* It may be less than the allocation size, e.g. for texture arrays. */
unsigned int bind_count[HLSL_REGSET_LAST_OBJECT + 1];
/* Whether the shader performs dereferences with non-constant offsets in the variable. */
bool indexable;
uint32_t is_input_semantic : 1;
uint32_t is_output_semantic : 1;
uint32_t is_uniform : 1;
@ -444,7 +451,7 @@ struct hlsl_ir_function
const char *name;
/* Tree containing function definitions, stored as hlsl_ir_function_decl structures, which would
* be more than one in case of function overloading. */
struct rb_tree overloads;
struct list overloads;
};
struct hlsl_ir_function_decl
@ -454,8 +461,8 @@ struct hlsl_ir_function_decl
struct hlsl_ir_var *return_var;
struct vkd3d_shader_location loc;
/* Item entry in hlsl_ir_function.overloads. The parameters' types are used as key. */
struct rb_entry entry;
/* Item entry in hlsl_ir_function.overloads. */
struct list entry;
/* Function to which this declaration corresponds. */
struct hlsl_ir_function *func;
@ -497,6 +504,22 @@ struct hlsl_ir_loop
unsigned int next_index; /* liveness index of the end of the loop */
};
struct hlsl_ir_switch_case
{
unsigned int value;
bool is_default;
struct hlsl_block body;
struct list entry;
struct vkd3d_shader_location loc;
};
struct hlsl_ir_switch
{
struct hlsl_ir_node node;
struct hlsl_src selector;
struct list cases;
};
enum hlsl_ir_expr_op
{
HLSL_OP0_VOID,
@ -504,6 +527,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,
@ -556,7 +580,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,
};
@ -577,6 +604,10 @@ enum hlsl_ir_jump_type
HLSL_IR_JUMP_DISCARD_NEG,
HLSL_IR_JUMP_DISCARD_NZ,
HLSL_IR_JUMP_RETURN,
/* UNRESOLVED_CONTINUE type is used by the parser when 'continue' statement is found,
it never reaches code generation, and is resolved to CONTINUE type once iteration
and loop exit logic was properly applied. */
HLSL_IR_JUMP_UNRESOLVED_CONTINUE,
};
struct hlsl_ir_jump
@ -615,17 +646,25 @@ struct hlsl_deref
unsigned int path_len;
struct hlsl_src *path;
/* Single instruction node of data type uint used to represent the register offset (in register
* components, within the pertaining regset), from the start of the variable, of the part
* referenced.
* The path is lowered to this single offset -- whose value may vary between SM1 and SM4 --
* before writing the bytecode.
/* Before writing the bytecode, deref paths are lowered into an offset (within the pertaining
* regset) from the start of the variable, to the part of the variable that is referenced.
* This offset is stored using two fields, one for a variable part and other for a constant
* part, which are added together:
* - rel_offset: An offset given by an instruction node, in whole registers.
* - const_offset: A constant number of register components.
* Since the type information cannot longer be retrieved from the offset alone, the type is
* stored in the data_type field. */
struct hlsl_src offset;
* stored in the data_type field, which remains NULL if the deref hasn't been lowered yet. */
struct hlsl_src rel_offset;
unsigned int const_offset;
struct hlsl_type *data_type;
};
/* Whether the path has been lowered to an offset or not. */
static inline bool hlsl_deref_is_lowered(const struct hlsl_deref *deref)
{
return !!deref->data_type;
}
struct hlsl_ir_load
{
struct hlsl_ir_node node;
@ -641,6 +680,7 @@ enum hlsl_resource_load_type
HLSL_RESOURCE_SAMPLE_LOD,
HLSL_RESOURCE_SAMPLE_LOD_BIAS,
HLSL_RESOURCE_SAMPLE_GRAD,
HLSL_RESOURCE_SAMPLE_PROJ,
HLSL_RESOURCE_GATHER_RED,
HLSL_RESOURCE_GATHER_GREEN,
HLSL_RESOURCE_GATHER_BLUE,
@ -702,6 +742,10 @@ struct hlsl_scope
struct rb_tree types;
/* Scope containing this scope. This value is NULL for the global scope. */
struct hlsl_scope *upper;
/* The scope was created for the loop statement. */
bool loop;
/* The scope was created for the switch statement. */
bool _switch;
};
struct hlsl_profile_info
@ -854,13 +898,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;
};
enum hlsl_error_level
{
HLSL_LEVEL_ERROR = 0,
HLSL_LEVEL_WARNING,
HLSL_LEVEL_NOTE,
bool semantic_compat_mapping;
};
struct hlsl_resource_load_params
@ -944,6 +983,12 @@ static inline struct hlsl_ir_index *hlsl_ir_index(const struct hlsl_ir_node *nod
return CONTAINING_RECORD(node, struct hlsl_ir_index, node);
}
static inline struct hlsl_ir_switch *hlsl_ir_switch(const struct hlsl_ir_node *node)
{
assert(node->type == HLSL_IR_SWITCH);
return CONTAINING_RECORD(node, struct hlsl_ir_switch, node);
}
static inline void hlsl_block_init(struct hlsl_block *block)
{
list_init(&block->instrs);
@ -1061,6 +1106,11 @@ static inline struct hlsl_type *hlsl_get_numeric_type(const struct hlsl_ctx *ctx
return hlsl_get_matrix_type(ctx, base_type, dimx, dimy);
}
static inline bool hlsl_is_numeric_type(const struct hlsl_type *type)
{
return type->class <= HLSL_CLASS_LAST_NUMERIC;
}
static inline unsigned int hlsl_sampler_dim_count(enum hlsl_sampler_dim dim)
{
switch (dim)
@ -1117,6 +1167,9 @@ bool hlsl_copy_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, const struc
void hlsl_cleanup_deref(struct hlsl_deref *deref);
void hlsl_cleanup_semantic(struct hlsl_semantic *semantic);
void hlsl_cleanup_ir_switch_cases(struct list *cases);
void hlsl_free_ir_switch_case(struct hlsl_ir_switch_case *c);
void hlsl_replace_node(struct hlsl_ir_node *old, struct hlsl_ir_node *new);
void hlsl_free_attribute(struct hlsl_attribute *attr);
@ -1126,7 +1179,10 @@ void hlsl_free_type(struct hlsl_type *type);
void hlsl_free_var(struct hlsl_ir_var *decl);
struct hlsl_ir_function *hlsl_get_function(struct hlsl_ctx *ctx, const char *name);
struct hlsl_ir_function_decl *hlsl_get_func_decl(struct hlsl_ctx *ctx, const char *name);
struct hlsl_ir_function_decl *hlsl_get_first_func_decl(struct hlsl_ctx *ctx, const char *name);
struct hlsl_ir_function_decl *hlsl_get_func_decl(struct hlsl_ctx *ctx, const char *name,
const struct hlsl_func_parameters *parameters);
const struct hlsl_profile_info *hlsl_get_target_info(const char *target);
struct hlsl_type *hlsl_get_type(struct hlsl_scope *scope, const char *name, bool recursive, bool case_insensitive);
struct hlsl_ir_var *hlsl_get_var(struct hlsl_scope *scope, const char *name);
@ -1210,6 +1266,10 @@ struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr
struct hlsl_ir_var *hlsl_new_var(struct hlsl_ctx *ctx, const char *name, struct hlsl_type *type,
const struct vkd3d_shader_location *loc, const struct hlsl_semantic *semantic, unsigned int modifiers,
const struct hlsl_reg_reservation *reg_reservation);
struct hlsl_ir_switch_case *hlsl_new_switch_case(struct hlsl_ctx *ctx, unsigned int value, bool is_default,
struct hlsl_block *body, const struct vkd3d_shader_location *loc);
struct hlsl_ir_node *hlsl_new_switch(struct hlsl_ctx *ctx, struct hlsl_ir_node *selector,
struct list *cases, const struct vkd3d_shader_location *loc);
void hlsl_error(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc,
enum vkd3d_shader_error error, const char *fmt, ...) VKD3D_PRINTF_FUNC(4, 5);
@ -1232,13 +1292,12 @@ unsigned int hlsl_type_get_array_element_reg_size(const struct hlsl_type *type,
struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl_type *type,
unsigned int index);
unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_type *type,
enum hlsl_regset regset, unsigned int index);
unsigned int index, enum hlsl_regset *regset);
bool hlsl_type_is_row_major(const struct hlsl_type *type);
unsigned int hlsl_type_minor_size(const struct hlsl_type *type);
unsigned int hlsl_type_major_size(const struct hlsl_type *type);
unsigned int hlsl_type_element_count(const struct hlsl_type *type);
bool hlsl_type_is_resource(const struct hlsl_type *type);
enum hlsl_regset hlsl_type_get_regset(const struct hlsl_type *type);
unsigned int hlsl_type_get_sm4_offset(const struct hlsl_type *type, unsigned int offset);
bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2);
@ -1251,6 +1310,7 @@ unsigned int hlsl_map_swizzle(unsigned int swizzle, unsigned int writemask);
unsigned int hlsl_swizzle_from_writemask(unsigned int writemask);
struct hlsl_type *hlsl_deref_get_type(struct hlsl_ctx *ctx, const struct hlsl_deref *deref);
enum hlsl_regset hlsl_deref_get_regset(struct hlsl_ctx *ctx, const struct hlsl_deref *deref);
bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref,
unsigned int *start, unsigned int *count);
bool hlsl_regset_index_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref,
@ -1273,7 +1333,7 @@ int hlsl_sm1_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun
bool hlsl_sm4_usage_from_semantic(struct hlsl_ctx *ctx,
const struct hlsl_semantic *semantic, bool output, D3D_NAME *usage);
bool hlsl_sm4_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic,
bool output, enum vkd3d_shader_register_type *type, enum vkd3d_sm4_swizzle_type *swizzle_type, bool *has_idx);
bool output, enum vkd3d_shader_register_type *type, bool *has_idx);
int hlsl_sm4_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out);
struct hlsl_ir_function_decl *hlsl_compile_internal_function(struct hlsl_ctx *ctx, const char *name, const char *hlsl);

View file

@ -46,14 +46,13 @@ static void update_location(struct hlsl_ctx *ctx, YYLTYPE *loc);
%x pp pp_line pp_pragma pp_ignore
RESERVED1 auto|case|catch|char|class|const_cast|default|delete|dynamic_cast|enum
RESERVED1 auto|catch|char|class|const_cast|delete|dynamic_cast|enum
RESERVED2 explicit|friend|goto|long|mutable|new|operator|private|protected|public
RESERVED3 reinterpret_cast|short|signed|sizeof|static_cast|template|this|throw|try
RESERVED4 typename|union|unsigned|using|virtual
WS [ \t]
NEWLINE (\n)|(\r\n)
DOUBLESLASHCOMMENT "//"[^\n]*
STRING \"[^\"]*\"
IDENTIFIER [A-Za-z_][A-Za-z0-9_]*
@ -73,12 +72,16 @@ ANY (.)
BlendState {return KW_BLENDSTATE; }
break {return KW_BREAK; }
Buffer {return KW_BUFFER; }
case {return KW_CASE; }
cbuffer {return KW_CBUFFER; }
centroid {return KW_CENTROID; }
column_major {return KW_COLUMN_MAJOR; }
compile {return KW_COMPILE; }
const {return KW_CONST; }
continue {return KW_CONTINUE; }
DepthStencilState {return KW_DEPTHSTENCILSTATE; }
DepthStencilView {return KW_DEPTHSTENCILVIEW; }
default {return KW_DEFAULT; }
discard {return KW_DISCARD; }
do {return KW_DO; }
double {return KW_DOUBLE; }
@ -92,31 +95,36 @@ if {return KW_IF; }
in {return KW_IN; }
inline {return KW_INLINE; }
inout {return KW_INOUT; }
linear {return KW_LINEAR; }
matrix {return KW_MATRIX; }
namespace {return KW_NAMESPACE; }
nointerpolation {return KW_NOINTERPOLATION; }
noperspective {return KW_NOPERSPECTIVE; }
out {return KW_OUT; }
packoffset {return KW_PACKOFFSET; }
pass {return KW_PASS; }
PixelShader {return KW_PIXELSHADER; }
precise {return KW_PRECISE; }
RasterizerState {return KW_RASTERIZERSTATE; }
register {return KW_REGISTER; }
RenderTargetView {return KW_RENDERTARGETVIEW; }
return {return KW_RETURN; }
register {return KW_REGISTER; }
row_major {return KW_ROW_MAJOR; }
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; }
sampler2D {return KW_SAMPLER2D; }
sampler3D {return KW_SAMPLER3D; }
samplerCUBE {return KW_SAMPLERCUBE; }
sampler_state {return KW_SAMPLER_STATE; }
SamplerComparisonState {return KW_SAMPLERCOMPARISONSTATE;}
samplerCUBE {return KW_SAMPLERCUBE; }
SamplerState {return KW_SAMPLER; }
sampler_state {return KW_SAMPLER_STATE; }
shared {return KW_SHARED; }
stateblock {return KW_STATEBLOCK; }
stateblock_state {return KW_STATEBLOCK_STATE; }
@ -125,21 +133,22 @@ string {return KW_STRING; }
struct {return KW_STRUCT; }
switch {return KW_SWITCH; }
tbuffer {return KW_TBUFFER; }
technique {return KW_TECHNIQUE; }
(?i:technique) {return KW_TECHNIQUE; }
technique10 {return KW_TECHNIQUE10; }
technique11 {return KW_TECHNIQUE11; }
texture {return KW_TEXTURE; }
texture1D {return KW_TEXTURE1D; }
Texture1D {return KW_TEXTURE1D; }
texture1D {return KW_TEXTURE1D; }
Texture1DArray {return KW_TEXTURE1DARRAY; }
texture2D {return KW_TEXTURE2D; }
Texture2D {return KW_TEXTURE2D; }
texture2D {return KW_TEXTURE2D; }
Texture2DArray {return KW_TEXTURE2DARRAY; }
Texture2DMS {return KW_TEXTURE2DMS; }
Texture2DMSArray {return KW_TEXTURE2DMSARRAY; }
texture3D {return KW_TEXTURE3D; }
Texture3D {return KW_TEXTURE3D; }
textureCUBE {return KW_TEXTURECUBE; }
texture3D {return KW_TEXTURE3D; }
TextureCube {return KW_TEXTURECUBE; }
textureCUBE {return KW_TEXTURECUBE; }
TextureCubeArray {return KW_TEXTURECUBEARRAY; }
true {return KW_TRUE; }
typedef {return KW_TYPEDEF; }
@ -159,7 +168,6 @@ while {return KW_WHILE; }
\<\<= {return OP_LEFTSHIFTASSIGN; }
\>\> {return OP_RIGHTSHIFT; }
\>\>= {return OP_RIGHTSHIFTASSIGN; }
\.\.\. {return OP_ELLIPSIS; }
\<= {return OP_LE; }
\>= {return OP_GE; }
!= {return OP_NE; }
@ -171,13 +179,6 @@ while {return KW_WHILE; }
&= {return OP_ANDASSIGN; }
\|= {return OP_ORASSIGN; }
^= {return OP_XORASSIGN; }
## {return OP_UNKNOWN1; }
#@ {return OP_UNKNOWN2; }
:: {return OP_UNKNOWN3; }
\-\> {return OP_UNKNOWN4; }
column_major {return KW_COLUMN_MAJOR; }
row_major {return KW_ROW_MAJOR; }
{IDENTIFIER} {
struct hlsl_ctx *ctx = yyget_extra(yyscanner);
@ -203,20 +204,30 @@ row_major {return KW_ROW_MAJOR; }
yylval->floatval = atof(yytext);
return C_FLOAT;
}
0x[0-9a-fA-F]+ {
0x[0-9a-fA-F]+[lL]? {
yylval->intval = vkd3d_parse_integer(yytext);
return C_INTEGER;
}
0[0-7]+ {
0[0-7]+[lL]? {
yylval->intval = vkd3d_parse_integer(yytext);
return C_INTEGER;
}
[0-9]+ {
[0-9]+[lL]? {
yylval->intval = vkd3d_parse_integer(yytext);
return C_INTEGER;
}
{DOUBLESLASHCOMMENT} {}
0x[0-9a-fA-F]+([uU]|[uU][lL]|[lL][uU]) {
yylval->intval = vkd3d_parse_integer(yytext);
return C_UNSIGNED;
}
0[0-7]+([uU]|[uU][lL]|[lL][uU]) {
yylval->intval = vkd3d_parse_integer(yytext);
return C_UNSIGNED;
}
[0-9]+([uU]|[uU][lL]|[lL][uU]) {
yylval->intval = vkd3d_parse_integer(yytext);
return C_UNSIGNED;
}
{WS}+ {}
{NEWLINE} {

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -63,6 +63,82 @@ static bool fold_abs(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
return true;
}
static uint32_t float_to_uint(float x)
{
if (isnan(x) || x <= 0)
return 0;
if (x >= 4294967296.0f)
return UINT32_MAX;
return x;
}
static int32_t float_to_int(float x)
{
if (isnan(x))
return 0;
if (x <= -2147483648.0f)
return INT32_MIN;
if (x >= 2147483648.0f)
return INT32_MAX;
return x;
}
static uint32_t double_to_uint(double x)
{
if (isnan(x) || x <= 0)
return 0;
if (x >= 4294967296.0)
return UINT32_MAX;
return x;
}
static int32_t double_to_int(double x)
{
if (isnan(x))
return 0;
if (x <= -2147483648.0)
return INT32_MIN;
if (x >= 2147483648.0)
return INT32_MAX;
return x;
}
static bool fold_bit_not(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_INT:
case HLSL_TYPE_UINT:
case HLSL_TYPE_BOOL:
dst->u[k].u = ~src->value.u[k].u;
break;
default:
vkd3d_unreachable();
}
}
return true;
}
static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
{
@ -86,15 +162,15 @@ static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
{
case HLSL_TYPE_FLOAT:
case HLSL_TYPE_HALF:
u = src->value.u[k].f;
i = src->value.u[k].f;
u = float_to_uint(src->value.u[k].f);
i = float_to_int(src->value.u[k].f);
f = src->value.u[k].f;
d = src->value.u[k].f;
break;
case HLSL_TYPE_DOUBLE:
u = src->value.u[k].d;
i = src->value.u[k].d;
u = double_to_uint(src->value.u[k].d);
i = double_to_int(src->value.u[k].d);
f = src->value.u[k].d;
d = src->value.u[k].d;
break;
@ -152,6 +228,111 @@ 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)
{
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 = exp2f(src->value.u[k].f);
break;
default:
FIXME("Fold 'exp2' for type %s.\n", debug_hlsl_type(ctx, dst_type));
return false;
}
}
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)
{
enum hlsl_base_type type = dst_type->base_type;
unsigned int k;
float i;
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 = modff(src->value.u[k].f, &i);
break;
default:
FIXME("Fold 'fract' for type %s.\n", debug_hlsl_type(ctx, dst_type));
return false;
}
}
return true;
}
static bool fold_log2(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc)
{
@ -231,6 +412,30 @@ static bool fold_neg(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
return true;
}
static bool fold_not(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_BOOL:
dst->u[k].u = ~src->value.u[k].u;
break;
default:
FIXME("Fold logic 'not' for type %s.\n", debug_hlsl_type(ctx, dst_type));
return false;
}
}
return true;
}
static bool fold_rcp(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc)
{
@ -276,6 +481,72 @@ static bool fold_rcp(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons
return true;
}
static bool fold_rsq(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc)
{
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:
if (ctx->profile->major_version >= 4)
{
if (src->value.u[k].f < 0.0f)
hlsl_warning(ctx, loc, VKD3D_SHADER_WARNING_HLSL_IMAGINARY_NUMERIC_RESULT,
"Imaginary square root result.");
else if (src->value.u[k].f == 0.0f)
hlsl_warning(ctx, loc, VKD3D_SHADER_WARNING_HLSL_IMAGINARY_NUMERIC_RESULT,
"Floating point division by zero.");
}
dst->u[k].f = 1.0f / sqrtf(src->value.u[k].f);
if (ctx->profile->major_version < 4 && !isfinite(dst->u[k].f))
{
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_NON_FINITE_RESULT,
"Infinities and NaNs are not allowed by the shader model.");
}
break;
default:
FIXME("Fold 'rsq' for type %s.\n", debug_hlsl_type(ctx, dst_type));
return false;
}
}
return true;
}
static bool fold_sat(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 = min(max(0.0f, src->value.u[k].f), 1.0f);
break;
default:
FIXME("Fold 'sat' for type %s.\n", debug_hlsl_type(ctx, dst_type));
return false;
}
}
return true;
}
static bool fold_sqrt(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc)
{
@ -679,6 +950,36 @@ static bool fold_less(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, con
return true;
}
static bool fold_lshift(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
{
unsigned int k;
assert(dst_type->base_type == src1->node.data_type->base_type);
assert(src2->node.data_type->base_type == HLSL_TYPE_INT);
for (k = 0; k < dst_type->dimx; ++k)
{
unsigned int shift = src2->value.u[k].u % 32;
switch (src1->node.data_type->base_type)
{
case HLSL_TYPE_INT:
dst->u[k].i = src1->value.u[k].i << shift;
break;
case HLSL_TYPE_UINT:
dst->u[k].u = src1->value.u[k].u << shift;
break;
default:
vkd3d_unreachable();
}
}
return true;
}
static bool fold_max(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
{
@ -869,6 +1170,70 @@ static bool fold_nequal(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, c
return true;
}
static bool fold_ternary(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2, const struct hlsl_ir_constant *src3)
{
unsigned int k;
assert(dst_type->base_type == src2->node.data_type->base_type);
assert(dst_type->base_type == src3->node.data_type->base_type);
for (k = 0; k < dst_type->dimx; ++k)
{
switch (src1->node.data_type->base_type)
{
case HLSL_TYPE_FLOAT:
case HLSL_TYPE_HALF:
dst->u[k] = src1->value.u[k].f != 0.0f ? src2->value.u[k] : src3->value.u[k];
break;
case HLSL_TYPE_DOUBLE:
dst->u[k] = src1->value.u[k].d != 0.0 ? src2->value.u[k] : src3->value.u[k];
break;
case HLSL_TYPE_INT:
case HLSL_TYPE_UINT:
case HLSL_TYPE_BOOL:
dst->u[k] = src1->value.u[k].u ? src2->value.u[k] : src3->value.u[k];
break;
default:
vkd3d_unreachable();
}
}
return true;
}
static bool fold_rshift(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type,
const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2)
{
unsigned int k;
assert(dst_type->base_type == src1->node.data_type->base_type);
assert(src2->node.data_type->base_type == HLSL_TYPE_INT);
for (k = 0; k < dst_type->dimx; ++k)
{
unsigned int shift = src2->value.u[k].u % 32;
switch (src1->node.data_type->base_type)
{
case HLSL_TYPE_INT:
dst->u[k].i = src1->value.u[k].i >> shift;
break;
case HLSL_TYPE_UINT:
dst->u[k].u = src1->value.u[k].u >> shift;
break;
default:
vkd3d_unreachable();
}
}
return true;
}
bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
{
struct hlsl_ir_constant *arg1, *arg2 = NULL, *arg3 = NULL;
@ -908,10 +1273,30 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
success = fold_abs(ctx, &res, instr->data_type, arg1);
break;
case HLSL_OP1_BIT_NOT:
success = fold_bit_not(ctx, &res, instr->data_type, arg1);
break;
case HLSL_OP1_CAST:
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;
case HLSL_OP1_LOG2:
success = fold_log2(ctx, &res, instr->data_type, arg1, &instr->loc);
break;
@ -920,10 +1305,22 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
success = fold_neg(ctx, &res, instr->data_type, arg1);
break;
case HLSL_OP1_LOGIC_NOT:
success = fold_not(ctx, &res, instr->data_type, arg1);
break;
case HLSL_OP1_RCP:
success = fold_rcp(ctx, &res, instr->data_type, arg1, &instr->loc);
break;
case HLSL_OP1_RSQ:
success = fold_rsq(ctx, &res, instr->data_type, arg1, &instr->loc);
break;
case HLSL_OP1_SAT:
success = fold_sat(ctx, &res, instr->data_type, arg1);
break;
case HLSL_OP1_SQRT:
success = fold_sqrt(ctx, &res, instr->data_type, arg1, &instr->loc);
break;
@ -966,6 +1363,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
success = fold_less(ctx, &res, instr->data_type, arg1, arg2);
break;
case HLSL_OP2_LSHIFT:
success = fold_lshift(ctx, &res, instr->data_type, arg1, arg2);
break;
case HLSL_OP2_MAX:
success = fold_max(ctx, &res, instr->data_type, arg1, arg2);
break;
@ -986,10 +1387,18 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
success = fold_nequal(ctx, &res, instr->data_type, arg1, arg2);
break;
case HLSL_OP2_RSHIFT:
success = fold_rshift(ctx, &res, instr->data_type, arg1, arg2);
break;
case HLSL_OP3_DP2ADD:
success = fold_dp2add(ctx, &res, instr->data_type, arg1, arg2, arg3);
break;
case HLSL_OP3_TERNARY:
success = fold_ternary(ctx, &res, instr->data_type, arg1, arg2, arg3);
break;
default:
FIXME("Fold \"%s\" expression.\n", debug_hlsl_expr_op(expr->op));
success = false;

View file

@ -31,11 +31,9 @@ static bool shader_instruction_is_dcl(const struct vkd3d_shader_instruction *ins
static void vkd3d_shader_instruction_make_nop(struct vkd3d_shader_instruction *ins)
{
ins->handler_idx = VKD3DSIH_NOP;
ins->dst_count = 0;
ins->src_count = 0;
ins->dst = NULL;
ins->src = NULL;
struct vkd3d_shader_location location = ins->location;
vsir_instruction_init(ins, &location, VKD3DSIH_NOP);
}
static void shader_register_eliminate_phase_addressing(struct vkd3d_shader_register *reg,
@ -64,17 +62,7 @@ static void shader_instruction_eliminate_phase_instance_id(struct vkd3d_shader_i
reg = (struct vkd3d_shader_register *)&ins->src[i].reg;
if (shader_register_is_phase_instance_id(reg))
{
reg->type = VKD3DSPR_IMMCONST;
reg->precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT;
reg->non_uniform = false;
reg->idx[0].offset = ~0u;
reg->idx[0].rel_addr = NULL;
reg->idx[1].offset = ~0u;
reg->idx[1].rel_addr = NULL;
reg->idx[2].offset = ~0u;
reg->idx[2].rel_addr = NULL;
reg->idx_count = 0;
reg->immconst_type = VKD3D_IMMCONST_SCALAR;
vsir_register_init(reg, VKD3DSPR_IMMCONST, reg->data_type, 0);
reg->u.immconst_uint[0] = instance_id;
continue;
}
@ -161,6 +149,7 @@ struct hull_flattener
unsigned int instance_count;
unsigned int phase_body_idx;
enum vkd3d_shader_opcode phase;
struct vkd3d_shader_location last_ret_location;
};
static bool flattener_is_in_fork_or_join_phase(const struct hull_flattener *flattener)
@ -218,10 +207,15 @@ static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normal
{
/* Leave only the first temp declaration and set it to the max count later. */
if (!normaliser->max_temp_count)
{
normaliser->max_temp_count = ins->declaration.count;
normaliser->temp_dcl_idx = index;
}
else
{
normaliser->max_temp_count = max(normaliser->max_temp_count, ins->declaration.count);
vkd3d_shader_instruction_make_nop(ins);
normaliser->max_temp_count = max(normaliser->max_temp_count, ins->declaration.count);
}
return;
}
@ -233,6 +227,7 @@ static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normal
if (ins->handler_idx == VKD3DSIH_RET)
{
normaliser->last_ret_location = ins->location;
vkd3d_shader_instruction_make_nop(ins);
if (locations->count >= ARRAY_SIZE(locations->locations))
{
@ -296,7 +291,7 @@ static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normali
return VKD3D_OK;
}
void shader_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type,
void vsir_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type,
enum vkd3d_data_type data_type, unsigned int idx_count)
{
reg->type = reg_type;
@ -305,17 +300,23 @@ void shader_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_r
reg->data_type = data_type;
reg->idx[0].offset = ~0u;
reg->idx[0].rel_addr = NULL;
reg->idx[0].is_in_bounds = false;
reg->idx[1].offset = ~0u;
reg->idx[1].rel_addr = NULL;
reg->idx[1].is_in_bounds = false;
reg->idx[2].offset = ~0u;
reg->idx[2].rel_addr = NULL;
reg->idx[2].is_in_bounds = false;
reg->idx_count = idx_count;
reg->immconst_type = VKD3D_IMMCONST_SCALAR;
reg->dimension = VSIR_DIMENSION_SCALAR;
reg->alignment = 0;
}
void shader_instruction_init(struct vkd3d_shader_instruction *ins, enum vkd3d_shader_opcode handler_idx)
void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location,
enum vkd3d_shader_opcode handler_idx)
{
memset(ins, 0, sizeof(*ins));
ins->location = *location;
ins->handler_idx = handler_idx;
}
@ -343,7 +344,7 @@ static enum vkd3d_result instruction_array_flatten_hull_shader_phases(struct vkd
if (!shader_instruction_array_reserve(&flattener.instructions, flattener.instructions.count + 1))
return VKD3D_ERROR_OUT_OF_MEMORY;
shader_instruction_init(&instructions->elements[instructions->count++], VKD3DSIH_RET);
vsir_instruction_init(&instructions->elements[instructions->count++], &flattener.last_ret_location, VKD3DSIH_RET);
}
*src_instructions = flattener.instructions;
@ -370,7 +371,7 @@ static struct vkd3d_shader_src_param *instruction_array_create_outpointid_param(
if (!(rel_addr = shader_src_param_allocator_get(&instructions->src_params, 1)))
return NULL;
shader_register_init(&rel_addr->reg, VKD3DSPR_OUTPOINTID, VKD3D_DATA_UINT, 0);
vsir_register_init(&rel_addr->reg, VKD3DSPR_OUTPOINTID, VKD3D_DATA_UINT, 0);
rel_addr->swizzle = 0;
rel_addr->modifiers = 0;
@ -400,11 +401,12 @@ static void shader_dst_param_io_init(struct vkd3d_shader_dst_param *param, const
param->write_mask = e->mask;
param->modifiers = 0;
param->shift = 0;
shader_register_init(&param->reg, reg_type, vkd3d_data_type_from_component_type(e->component_type), idx_count);
vsir_register_init(&param->reg, reg_type, vkd3d_data_type_from_component_type(e->component_type), idx_count);
}
static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_point_normaliser *normaliser,
const struct shader_signature *s, unsigned int input_control_point_count, unsigned int dst)
const struct shader_signature *s, unsigned int input_control_point_count, unsigned int dst,
const struct vkd3d_shader_location *location)
{
struct vkd3d_shader_instruction *ins;
struct vkd3d_shader_dst_param *param;
@ -422,7 +424,7 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p
normaliser->instructions.count += count;
ins = &normaliser->instructions.elements[dst];
shader_instruction_init(ins, VKD3DSIH_HS_CONTROL_POINT_PHASE);
vsir_instruction_init(ins, location, VKD3DSIH_HS_CONTROL_POINT_PHASE);
ins->flags = 1;
++ins;
@ -434,19 +436,20 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p
if (e->sysval_semantic != VKD3D_SHADER_SV_NONE)
{
shader_instruction_init(ins, VKD3DSIH_DCL_INPUT_SIV);
vsir_instruction_init(ins, location, VKD3DSIH_DCL_INPUT_SIV);
param = &ins->declaration.register_semantic.reg;
ins->declaration.register_semantic.sysval_semantic = vkd3d_siv_from_sysval(e->sysval_semantic);
}
else
{
shader_instruction_init(ins, VKD3DSIH_DCL_INPUT);
vsir_instruction_init(ins, location, VKD3DSIH_DCL_INPUT);
param = &ins->declaration.dst;
}
shader_dst_param_io_init(param, e, VKD3DSPR_INPUT, 2);
param->reg.idx[0].offset = input_control_point_count;
param->reg.idx[1].offset = i;
param->reg.idx[1].offset = e->register_index;
param->write_mask = e->mask;
++ins;
}
@ -511,7 +514,7 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i
case VKD3DSIH_HS_FORK_PHASE:
case VKD3DSIH_HS_JOIN_PHASE:
ret = control_point_normaliser_emit_hs_input(&normaliser, input_signature,
input_control_point_count, i);
input_control_point_count, i, &ins->location);
*src_instructions = normaliser.instructions;
return ret;
default:
@ -547,6 +550,8 @@ struct io_normaliser
uint8_t input_range_map[MAX_REG_OUTPUT][VKD3D_VEC4_SIZE];
uint8_t output_range_map[MAX_REG_OUTPUT][VKD3D_VEC4_SIZE];
uint8_t pc_range_map[MAX_REG_OUTPUT][VKD3D_VEC4_SIZE];
bool use_vocp;
};
static bool io_normaliser_is_in_fork_or_join_phase(const struct io_normaliser *normaliser)
@ -578,6 +583,12 @@ static unsigned int shader_signature_find_element_for_reg(const struct shader_si
vkd3d_unreachable();
}
struct signature_element *vsir_signature_find_element_for_reg(const struct shader_signature *signature,
unsigned int reg_idx, unsigned int write_mask)
{
return &signature->elements[shader_signature_find_element_for_reg(signature, reg_idx, write_mask)];
}
static unsigned int range_map_get_register_count(uint8_t range_map[][VKD3D_VEC4_SIZE],
unsigned int register_idx, unsigned int write_mask)
{
@ -766,8 +777,9 @@ static bool shader_signature_merge(struct shader_signature *s, uint8_t range_map
f = &elements[j];
/* Merge different components of the same register unless sysvals are different,
* or it will be relative-addressed. */
* interpolation modes are different, or it will be relative-addressed. */
if (f->register_index != e->register_index || f->sysval_semantic != e->sysval_semantic
|| f->interpolation_mode != e->interpolation_mode
|| range_map_get_register_count(range_map, f->register_index, f->mask) > 1)
break;
@ -816,12 +828,6 @@ static bool shader_signature_merge(struct shader_signature *s, uint8_t range_map
return true;
}
static bool sysval_semantic_is_tess_factor(enum vkd3d_shader_sysval_semantic sysval_semantic)
{
return sysval_semantic >= VKD3D_SHADER_SV_TESS_FACTOR_QUADEDGE
&& sysval_semantic <= VKD3D_SHADER_SV_TESS_FACTOR_LINEDEN;
}
static unsigned int shader_register_normalise_arrayed_addressing(struct vkd3d_shader_register *reg,
unsigned int id_idx, unsigned int register_index)
{
@ -870,11 +876,13 @@ static bool shader_dst_param_io_normalise(struct vkd3d_shader_dst_param *dst_par
else if (reg->type == VKD3DSPR_OUTPUT || dst_param->reg.type == VKD3DSPR_COLOROUT)
{
signature = normaliser->output_signature;
reg->type = VKD3DSPR_OUTPUT;
dcl_params = normaliser->output_dcl_params;
}
else if (dst_param->reg.type == VKD3DSPR_INCONTROLPOINT || dst_param->reg.type == VKD3DSPR_INPUT)
{
signature = normaliser->input_signature;
reg->type = VKD3DSPR_INPUT;
dcl_params = normaliser->input_dcl_params;
}
else
@ -922,7 +930,7 @@ static bool shader_dst_param_io_normalise(struct vkd3d_shader_dst_param *dst_par
id_idx = 1;
}
if ((e->register_count > 1 || sysval_semantic_is_tess_factor(e->sysval_semantic)))
if ((e->register_count > 1 || vsir_sysval_semantic_is_tess_factor(e->sysval_semantic)))
{
if (is_io_dcl)
{
@ -974,15 +982,13 @@ static void shader_src_param_io_normalise(struct vkd3d_shader_src_param *src_par
signature = normaliser->patch_constant_signature;
break;
case VKD3DSPR_INCONTROLPOINT:
if (normaliser->shader_type == VKD3D_SHADER_TYPE_HULL)
reg->type = VKD3DSPR_INPUT;
reg->type = VKD3DSPR_INPUT;
/* fall through */
case VKD3DSPR_INPUT:
signature = normaliser->input_signature;
break;
case VKD3DSPR_OUTCONTROLPOINT:
if (normaliser->shader_type == VKD3D_SHADER_TYPE_HULL)
reg->type = VKD3DSPR_OUTPUT;
reg->type = VKD3DSPR_OUTPUT;
/* fall through */
case VKD3DSPR_OUTPUT:
signature = normaliser->output_signature;
@ -997,7 +1003,7 @@ static void shader_src_param_io_normalise(struct vkd3d_shader_src_param *src_par
element_idx = shader_signature_find_element_for_reg(signature, reg_idx, write_mask);
e = &signature->elements[element_idx];
if ((e->register_count > 1 || sysval_semantic_is_tess_factor(e->sysval_semantic)))
if ((e->register_count > 1 || vsir_sysval_semantic_is_tess_factor(e->sysval_semantic)))
id_idx = shader_register_normalise_arrayed_addressing(reg, id_idx, e->register_index);
reg->idx[id_idx].offset = element_idx;
reg->idx_count = id_idx + 1;
@ -1014,7 +1020,6 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi
struct io_normaliser *normaliser)
{
struct vkd3d_shader_register *reg;
bool keep = true;
unsigned int i;
switch (ins->handler_idx)
@ -1023,6 +1028,10 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi
if (normaliser->shader_type == VKD3D_SHADER_TYPE_HULL)
{
reg = &ins->declaration.dst.reg;
if (reg->type == VKD3DSPR_OUTCONTROLPOINT)
normaliser->use_vocp = true;
/* We don't need to keep OUTCONTROLPOINT or PATCHCONST input declarations since their
* equivalents were declared earlier, but INCONTROLPOINT may be the first occurrence. */
if (reg->type == VKD3DSPR_OUTCONTROLPOINT || reg->type == VKD3DSPR_PATCHCONST)
@ -1033,15 +1042,16 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi
/* fall through */
case VKD3DSIH_DCL_INPUT_PS:
case VKD3DSIH_DCL_OUTPUT:
keep = shader_dst_param_io_normalise(&ins->declaration.dst, true, normaliser);
if (!shader_dst_param_io_normalise(&ins->declaration.dst, true, normaliser))
vkd3d_shader_instruction_make_nop(ins);
break;
case VKD3DSIH_DCL_INPUT_SGV:
case VKD3DSIH_DCL_INPUT_SIV:
case VKD3DSIH_DCL_INPUT_PS_SGV:
case VKD3DSIH_DCL_INPUT_PS_SIV:
case VKD3DSIH_DCL_OUTPUT_SIV:
keep = shader_dst_param_io_normalise(&ins->declaration.register_semantic.reg, true,
normaliser);
if (!shader_dst_param_io_normalise(&ins->declaration.register_semantic.reg, true, normaliser))
vkd3d_shader_instruction_make_nop(ins);
break;
case VKD3DSIH_HS_CONTROL_POINT_PHASE:
case VKD3DSIH_HS_FORK_PHASE:
@ -1060,29 +1070,24 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi
shader_src_param_io_normalise((struct vkd3d_shader_src_param *)&ins->src[i], normaliser);
break;
}
if (!keep)
shader_instruction_init(ins, VKD3DSIH_NOP);
}
static enum vkd3d_result instruction_array_normalise_io_registers(struct vkd3d_shader_instruction_array *instructions,
enum vkd3d_shader_type shader_type, struct shader_signature *input_signature,
struct shader_signature *output_signature, struct shader_signature *patch_constant_signature)
static enum vkd3d_result shader_normalise_io_registers(struct vkd3d_shader_parser *parser)
{
struct io_normaliser normaliser = {*instructions};
struct io_normaliser normaliser = {parser->instructions};
struct vkd3d_shader_instruction *ins;
bool has_control_point_phase;
unsigned int i, j;
normaliser.phase = VKD3DSIH_INVALID;
normaliser.shader_type = shader_type;
normaliser.input_signature = input_signature;
normaliser.output_signature = output_signature;
normaliser.patch_constant_signature = patch_constant_signature;
normaliser.shader_type = parser->shader_version.type;
normaliser.input_signature = &parser->shader_desc.input_signature;
normaliser.output_signature = &parser->shader_desc.output_signature;
normaliser.patch_constant_signature = &parser->shader_desc.patch_constant_signature;
for (i = 0, has_control_point_phase = false; i < instructions->count; ++i)
for (i = 0, has_control_point_phase = false; i < parser->instructions.count; ++i)
{
ins = &instructions->elements[i];
ins = &parser->instructions.elements[i];
switch (ins->handler_idx)
{
@ -1121,11 +1126,11 @@ static enum vkd3d_result instruction_array_normalise_io_registers(struct vkd3d_s
}
}
if (!shader_signature_merge(input_signature, normaliser.input_range_map, false)
|| !shader_signature_merge(output_signature, normaliser.output_range_map, false)
|| !shader_signature_merge(patch_constant_signature, normaliser.pc_range_map, true))
if (!shader_signature_merge(&parser->shader_desc.input_signature, normaliser.input_range_map, false)
|| !shader_signature_merge(&parser->shader_desc.output_signature, normaliser.output_range_map, false)
|| !shader_signature_merge(&parser->shader_desc.patch_constant_signature, normaliser.pc_range_map, true))
{
*instructions = normaliser.instructions;
parser->instructions = normaliser.instructions;
return VKD3D_ERROR_OUT_OF_MEMORY;
}
@ -1133,7 +1138,8 @@ static enum vkd3d_result instruction_array_normalise_io_registers(struct vkd3d_s
for (i = 0; i < normaliser.instructions.count; ++i)
shader_instruction_normalise_io_params(&normaliser.instructions.elements[i], &normaliser);
*instructions = normaliser.instructions;
parser->instructions = normaliser.instructions;
parser->shader_desc.use_vocp = normaliser.use_vocp;
return VKD3D_OK;
}
@ -1207,7 +1213,7 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par
{
param->reg.type = VKD3DSPR_IMMCONST;
param->reg.idx_count = 0;
param->reg.immconst_type = VKD3D_IMMCONST_VEC4;
param->reg.dimension = VSIR_DIMENSION_VEC4;
for (j = 0; j < 4; ++j)
param->reg.u.immconst_uint[j] = normaliser->defs[i].value[j];
return;
@ -1260,6 +1266,164 @@ static enum vkd3d_result instruction_array_normalise_flat_constants(struct vkd3d
return VKD3D_OK;
}
static void remove_dead_code(struct vkd3d_shader_parser *parser)
{
size_t i, depth = 0;
bool dead = false;
for (i = 0; i < parser->instructions.count; ++i)
{
struct vkd3d_shader_instruction *ins = &parser->instructions.elements[i];
switch (ins->handler_idx)
{
case VKD3DSIH_IF:
case VKD3DSIH_LOOP:
case VKD3DSIH_SWITCH:
if (dead)
{
vkd3d_shader_instruction_make_nop(ins);
++depth;
}
break;
case VKD3DSIH_ENDIF:
case VKD3DSIH_ENDLOOP:
case VKD3DSIH_ENDSWITCH:
case VKD3DSIH_ELSE:
if (dead)
{
if (depth > 0)
{
if (ins->handler_idx != VKD3DSIH_ELSE)
--depth;
vkd3d_shader_instruction_make_nop(ins);
}
else
{
dead = false;
}
}
break;
/* `depth' is counted with respect to where the dead code
* segment began. So it starts at zero and it signals the
* termination of the dead code segment when it would
* become negative. */
case VKD3DSIH_BREAK:
case VKD3DSIH_RET:
case VKD3DSIH_CONTINUE:
if (dead)
{
vkd3d_shader_instruction_make_nop(ins);
}
else
{
dead = true;
depth = 0;
}
break;
/* If `case' or `default' appears at zero depth, it means
* that they are a possible target for the corresponding
* switch, so the code is live again. */
case VKD3DSIH_CASE:
case VKD3DSIH_DEFAULT:
if (dead)
{
if (depth == 0)
dead = false;
else
vkd3d_shader_instruction_make_nop(ins);
}
break;
/* Phase instructions can only appear in hull shaders and
* outside of any block. When a phase returns, control is
* moved to the following phase, so they make code live
* again. */
case VKD3DSIH_HS_CONTROL_POINT_PHASE:
case VKD3DSIH_HS_FORK_PHASE:
case VKD3DSIH_HS_JOIN_PHASE:
dead = false;
break;
default:
if (dead)
vkd3d_shader_instruction_make_nop(ins);
break;
}
}
}
static enum vkd3d_result normalise_combined_samplers(struct vkd3d_shader_parser *parser)
{
unsigned int i;
for (i = 0; i < parser->instructions.count; ++i)
{
struct vkd3d_shader_instruction *ins = &parser->instructions.elements[i];
struct vkd3d_shader_src_param *srcs;
switch (ins->handler_idx)
{
case VKD3DSIH_TEX:
if (!(srcs = shader_src_param_allocator_get(&parser->instructions.src_params, 3)))
return VKD3D_ERROR_OUT_OF_MEMORY;
memset(srcs, 0, sizeof(*srcs) * 3);
ins->handler_idx = VKD3DSIH_SAMPLE;
srcs[0] = ins->src[0];
srcs[1].reg.type = VKD3DSPR_RESOURCE;
srcs[1].reg.idx[0] = ins->src[1].reg.idx[0];
srcs[1].reg.idx[1] = ins->src[1].reg.idx[0];
srcs[1].reg.idx_count = 2;
srcs[1].reg.data_type = VKD3D_DATA_RESOURCE;
srcs[1].swizzle = VKD3D_SHADER_NO_SWIZZLE;
srcs[2].reg.type = VKD3DSPR_SAMPLER;
srcs[2].reg.idx[0] = ins->src[1].reg.idx[0];
srcs[2].reg.idx[1] = ins->src[1].reg.idx[0];
srcs[2].reg.idx_count = 2;
srcs[2].reg.data_type = VKD3D_DATA_SAMPLER;
ins->src = srcs;
ins->src_count = 3;
break;
case VKD3DSIH_TEXBEM:
case VKD3DSIH_TEXBEML:
case VKD3DSIH_TEXCOORD:
case VKD3DSIH_TEXDEPTH:
case VKD3DSIH_TEXDP3:
case VKD3DSIH_TEXDP3TEX:
case VKD3DSIH_TEXLDD:
case VKD3DSIH_TEXLDL:
case VKD3DSIH_TEXM3x2PAD:
case VKD3DSIH_TEXM3x2TEX:
case VKD3DSIH_TEXM3x3DIFF:
case VKD3DSIH_TEXM3x3PAD:
case VKD3DSIH_TEXM3x3SPEC:
case VKD3DSIH_TEXM3x3TEX:
case VKD3DSIH_TEXM3x3VSPEC:
case VKD3DSIH_TEXREG2AR:
case VKD3DSIH_TEXREG2GB:
case VKD3DSIH_TEXREG2RGB:
vkd3d_shader_parser_error(parser, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED,
"Aborting due to not yet implemented feature: "
"Combined sampler instruction %#x.", ins->handler_idx);
return VKD3D_ERROR_NOT_IMPLEMENTED;
default:
break;
}
}
return VKD3D_OK;
}
enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser,
const struct vkd3d_shader_compile_info *compile_info)
{
@ -1280,15 +1444,366 @@ enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser,
&parser->shader_desc.input_signature);
}
if (result >= 0)
result = instruction_array_normalise_io_registers(instructions, parser->shader_version.type,
&parser->shader_desc.input_signature, &parser->shader_desc.output_signature,
&parser->shader_desc.patch_constant_signature);
result = shader_normalise_io_registers(parser);
if (result >= 0)
result = instruction_array_normalise_flat_constants(parser);
if (result >= 0)
remove_dead_code(parser);
if (result >= 0)
result = normalise_combined_samplers(parser);
if (result >= 0 && TRACE_ON())
vkd3d_shader_trace(instructions, &parser->shader_version);
if (result >= 0 && !parser->failed)
vsir_validate(parser);
if (result >= 0 && parser->failed)
result = VKD3D_ERROR_INVALID_SHADER;
return result;
}
struct validation_context
{
struct vkd3d_shader_parser *parser;
size_t instruction_idx;
bool dcl_temps_found;
unsigned int temp_count;
enum vkd3d_shader_opcode phase;
enum vkd3d_shader_opcode *blocks;
size_t depth;
size_t blocks_capacity;
};
static void VKD3D_PRINTF_FUNC(3, 4) validator_error(struct validation_context *ctx,
enum vkd3d_shader_error error, const char *format, ...)
{
struct vkd3d_string_buffer buf;
va_list args;
vkd3d_string_buffer_init(&buf);
va_start(args, format);
vkd3d_string_buffer_vprintf(&buf, format, args);
va_end(args);
vkd3d_shader_parser_error(ctx->parser, error, "instruction %zu: %s", ctx->instruction_idx + 1, buf.buffer);
ERR("VSIR validation error: instruction %zu: %s\n", ctx->instruction_idx + 1, buf.buffer);
vkd3d_string_buffer_cleanup(&buf);
}
static void vsir_validate_src_param(struct validation_context *ctx,
const struct vkd3d_shader_src_param *src);
static void vsir_validate_register(struct validation_context *ctx,
const struct vkd3d_shader_register *reg)
{
unsigned int i, temp_count = ctx->temp_count;
/* SM1-3 shaders do not include a DCL_TEMPS instruction. */
if (ctx->parser->shader_version.major <= 3)
temp_count = ctx->parser->shader_desc.temp_count;
if (reg->type >= VKD3DSPR_COUNT)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, "Invalid register type %#x.",
reg->type);
if (reg->precision >= VKD3D_SHADER_REGISTER_PRECISION_COUNT)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION, "Invalid register precision %#x.",
reg->precision);
if (reg->data_type >= VKD3D_DATA_COUNT)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, "Invalid register data type %#x.",
reg->data_type);
if (reg->dimension >= VSIR_DIMENSION_COUNT)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION, "Invalid register dimension %#x.",
reg->dimension);
if (reg->idx_count > ARRAY_SIZE(reg->idx))
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT, "Invalid register index count %u.",
reg->idx_count);
for (i = 0; i < min(reg->idx_count, ARRAY_SIZE(reg->idx)); ++i)
{
const struct vkd3d_shader_src_param *param = reg->idx[i].rel_addr;
if (reg->idx[i].rel_addr)
vsir_validate_src_param(ctx, param);
}
switch (reg->type)
{
case VKD3DSPR_TEMP:
if (reg->idx_count != 1)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT, "Invalid index count %u for a TEMP register.",
reg->idx_count);
if (reg->idx_count >= 1 && reg->idx[0].rel_addr)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX, "Non-NULL relative address for a TEMP register.");
if (reg->idx_count >= 1 && reg->idx[0].offset >= temp_count)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX, "TEMP register index %u exceeds the maximum count %u.",
reg->idx[0].offset, temp_count);
break;
case VKD3DSPR_NULL:
if (reg->idx_count != 0)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT, "Invalid index count %u for a NULL register.",
reg->idx_count);
break;
case VKD3DSPR_IMMCONST:
if (reg->idx_count != 0)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT, "Invalid index count %u for a IMMCONST register.",
reg->idx_count);
break;
case VKD3DSPR_IMMCONST64:
if (reg->idx_count != 0)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT, "Invalid index count %u for a IMMCONST64 register.",
reg->idx_count);
break;
default:
break;
}
}
static void vsir_validate_dst_param(struct validation_context *ctx,
const struct vkd3d_shader_dst_param *dst)
{
vsir_validate_register(ctx, &dst->reg);
if (dst->write_mask & ~VKD3DSP_WRITEMASK_ALL)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_WRITE_MASK, "Destination has invalid write mask %#x.",
dst->write_mask);
if (dst->modifiers & ~VKD3DSPDM_MASK)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, "Destination has invalid modifiers %#x.",
dst->modifiers);
switch (dst->shift)
{
case 0:
case 1:
case 2:
case 3:
case 13:
case 14:
case 15:
break;
default:
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SHIFT, "Destination has invalid shift %#x.",
dst->shift);
}
}
static void vsir_validate_src_param(struct validation_context *ctx,
const struct vkd3d_shader_src_param *src)
{
vsir_validate_register(ctx, &src->reg);
if (src->swizzle & ~0x03030303u)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SWIZZLE, "Source has invalid swizzle %#x.",
src->swizzle);
if (src->modifiers >= VKD3DSPSM_COUNT)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, "Source has invalid modifiers %#x.",
src->modifiers);
}
static void vsir_validate_dst_count(struct validation_context *ctx,
const struct vkd3d_shader_instruction *instruction, unsigned int count)
{
if (instruction->dst_count != count)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DEST_COUNT,
"Invalid destination count %u for an instruction of type %#x, expected %u.",
instruction->dst_count, instruction->handler_idx, count);
}
static void vsir_validate_src_count(struct validation_context *ctx,
const struct vkd3d_shader_instruction *instruction, unsigned int count)
{
if (instruction->src_count != count)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT,
"Invalid source count %u for an instruction of type %#x, expected %u.",
instruction->src_count, instruction->handler_idx, count);
}
static void vsir_validate_instruction(struct validation_context *ctx)
{
const struct vkd3d_shader_instruction *instruction = &ctx->parser->instructions.elements[ctx->instruction_idx];
size_t i;
ctx->parser->location = instruction->location;
for (i = 0; i < instruction->dst_count; ++i)
vsir_validate_dst_param(ctx, &instruction->dst[i]);
for (i = 0; i < instruction->src_count; ++i)
vsir_validate_src_param(ctx, &instruction->src[i]);
if (instruction->handler_idx >= VKD3DSIH_INVALID)
{
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER, "Invalid instruction handler %#x.",
instruction->handler_idx);
}
switch (instruction->handler_idx)
{
case VKD3DSIH_HS_DECLS:
case VKD3DSIH_HS_CONTROL_POINT_PHASE:
case VKD3DSIH_HS_FORK_PHASE:
case VKD3DSIH_HS_JOIN_PHASE:
vsir_validate_dst_count(ctx, instruction, 0);
vsir_validate_src_count(ctx, instruction, 0);
if (ctx->parser->shader_version.type != VKD3D_SHADER_TYPE_HULL)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER, "Phase instruction %#x is only valid in a hull shader.",
instruction->handler_idx);
if (ctx->depth != 0)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INSTRUCTION_NESTING, "Phase instruction %#x must appear to top level.",
instruction->handler_idx);
ctx->phase = instruction->handler_idx;
ctx->dcl_temps_found = false;
ctx->temp_count = 0;
return;
default:
break;
}
if (ctx->parser->shader_version.type == VKD3D_SHADER_TYPE_HULL &&
ctx->phase == VKD3DSIH_INVALID)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER, "Instruction %#x appear before any phase instruction in a hull shader.",
instruction->handler_idx);
switch (instruction->handler_idx)
{
case VKD3DSIH_DCL_TEMPS:
vsir_validate_dst_count(ctx, instruction, 0);
vsir_validate_src_count(ctx, instruction, 0);
if (ctx->dcl_temps_found)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_DUPLICATE_DCL_TEMPS, "Duplicate DCL_TEMPS instruction.");
if (instruction->declaration.count > ctx->parser->shader_desc.temp_count)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DCL_TEMPS, "Invalid DCL_TEMPS count %u, expected at most %u.",
instruction->declaration.count, ctx->parser->shader_desc.temp_count);
ctx->dcl_temps_found = true;
ctx->temp_count = instruction->declaration.count;
break;
case VKD3DSIH_IF:
vsir_validate_dst_count(ctx, instruction, 0);
vsir_validate_src_count(ctx, instruction, 1);
if (!vkd3d_array_reserve((void **)&ctx->blocks, &ctx->blocks_capacity, ctx->depth + 1, sizeof(*ctx->blocks)))
return;
ctx->blocks[ctx->depth++] = instruction->handler_idx;
break;
case VKD3DSIH_IFC:
vsir_validate_dst_count(ctx, instruction, 0);
vsir_validate_src_count(ctx, instruction, 2);
if (!vkd3d_array_reserve((void **)&ctx->blocks, &ctx->blocks_capacity, ctx->depth + 1, sizeof(*ctx->blocks)))
return;
ctx->blocks[ctx->depth++] = VKD3DSIH_IF;
break;
case VKD3DSIH_ELSE:
vsir_validate_dst_count(ctx, instruction, 0);
vsir_validate_src_count(ctx, instruction, 0);
if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VKD3DSIH_IF)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INSTRUCTION_NESTING, "ELSE instruction doesn't terminate IF block.");
else
ctx->blocks[ctx->depth - 1] = instruction->handler_idx;
break;
case VKD3DSIH_ENDIF:
vsir_validate_dst_count(ctx, instruction, 0);
vsir_validate_src_count(ctx, instruction, 0);
if (ctx->depth == 0 || (ctx->blocks[ctx->depth - 1] != VKD3DSIH_IF && ctx->blocks[ctx->depth - 1] != VKD3DSIH_ELSE))
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INSTRUCTION_NESTING, "ENDIF instruction doesn't terminate IF/ELSE block.");
else
--ctx->depth;
break;
case VKD3DSIH_LOOP:
vsir_validate_dst_count(ctx, instruction, 0);
vsir_validate_src_count(ctx, instruction, ctx->parser->shader_version.major <= 3 ? 2 : 0);
if (!vkd3d_array_reserve((void **)&ctx->blocks, &ctx->blocks_capacity, ctx->depth + 1, sizeof(*ctx->blocks)))
return;
ctx->blocks[ctx->depth++] = instruction->handler_idx;
break;
case VKD3DSIH_ENDLOOP:
vsir_validate_dst_count(ctx, instruction, 0);
vsir_validate_src_count(ctx, instruction, 0);
if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VKD3DSIH_LOOP)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INSTRUCTION_NESTING, "ENDLOOP instruction doesn't terminate LOOP block.");
else
--ctx->depth;
break;
case VKD3DSIH_REP:
vsir_validate_dst_count(ctx, instruction, 0);
vsir_validate_src_count(ctx, instruction, 1);
if (!vkd3d_array_reserve((void **)&ctx->blocks, &ctx->blocks_capacity, ctx->depth + 1, sizeof(*ctx->blocks)))
return;
ctx->blocks[ctx->depth++] = instruction->handler_idx;
break;
case VKD3DSIH_ENDREP:
vsir_validate_dst_count(ctx, instruction, 0);
vsir_validate_src_count(ctx, instruction, 0);
if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VKD3DSIH_REP)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INSTRUCTION_NESTING, "ENDREP instruction doesn't terminate REP block.");
else
--ctx->depth;
break;
case VKD3DSIH_SWITCH:
vsir_validate_dst_count(ctx, instruction, 0);
vsir_validate_src_count(ctx, instruction, 1);
if (!vkd3d_array_reserve((void **)&ctx->blocks, &ctx->blocks_capacity, ctx->depth + 1, sizeof(*ctx->blocks)))
return;
ctx->blocks[ctx->depth++] = instruction->handler_idx;
break;
case VKD3DSIH_ENDSWITCH:
vsir_validate_dst_count(ctx, instruction, 0);
vsir_validate_src_count(ctx, instruction, 0);
if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VKD3DSIH_SWITCH)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INSTRUCTION_NESTING, "ENDSWITCH instruction doesn't terminate SWITCH block.");
else
--ctx->depth;
break;
default:
break;
}
}
void vsir_validate(struct vkd3d_shader_parser *parser)
{
struct validation_context ctx =
{
.parser = parser,
.phase = VKD3DSIH_INVALID,
};
if (!(parser->config_flags & VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION))
return;
for (ctx.instruction_idx = 0; ctx.instruction_idx < parser->instructions.count; ++ctx.instruction_idx)
vsir_validate_instruction(&ctx);
if (ctx.depth != 0)
validator_error(&ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INSTRUCTION_NESTING, "%zu nested blocks were not closed.", ctx.depth);
free(ctx.blocks);
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -18,6 +18,7 @@
#include "vkd3d_shader_private.h"
#include "vkd3d_version.h"
#include "hlsl.h"
#include <stdio.h>
#include <math.h>
@ -379,7 +380,7 @@ void set_u32(struct vkd3d_bytecode_buffer *buffer, size_t offset, uint32_t value
memcpy(buffer->data + offset, &value, sizeof(value));
}
static void vkd3d_shader_dump_blob(const char *path, const char *prefix,
static void vkd3d_shader_dump_blob(const char *path, const char *profile,
const char *suffix, const void *data, size_t size)
{
static LONG shader_id = 0;
@ -389,7 +390,10 @@ static void vkd3d_shader_dump_blob(const char *path, const char *prefix,
id = InterlockedIncrement(&shader_id) - 1;
snprintf(filename, ARRAY_SIZE(filename), "%s/vkd3d-shader-%s-%u.%s", path, prefix, id, suffix);
if (profile)
snprintf(filename, ARRAY_SIZE(filename), "%s/vkd3d-shader-%u-%s.%s", path, id, profile, suffix);
else
snprintf(filename, ARRAY_SIZE(filename), "%s/vkd3d-shader-%u.%s", path, id, suffix);
if ((f = fopen(filename, "wb")))
{
if (fwrite(data, 1, size, f) != size)
@ -421,9 +425,12 @@ static const char *shader_get_source_type_suffix(enum vkd3d_shader_source_type t
}
}
void vkd3d_shader_dump_shader(enum vkd3d_shader_source_type source_type,
enum vkd3d_shader_type shader_type, const struct vkd3d_shader_code *shader)
void vkd3d_shader_dump_shader(const struct vkd3d_shader_compile_info *compile_info)
{
const struct vkd3d_shader_code *shader = &compile_info->source;
const struct vkd3d_shader_hlsl_source_info *hlsl_source_info;
const struct hlsl_profile_info *profile;
const char *profile_name = NULL;
static bool enabled = true;
const char *path;
@ -436,8 +443,19 @@ void vkd3d_shader_dump_shader(enum vkd3d_shader_source_type source_type,
return;
}
vkd3d_shader_dump_blob(path, shader_get_type_prefix(shader_type),
shader_get_source_type_suffix(source_type), shader->code, shader->size);
if (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL)
{
if (!(hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO)))
return;
if (!(profile = hlsl_get_target_info(hlsl_source_info->profile)))
return;
profile_name = profile->name;
}
vkd3d_shader_dump_blob(path, profile_name, shader_get_source_type_suffix(compile_info->source_type),
shader->code, shader->size);
}
static void init_scan_signature_info(const struct vkd3d_shader_compile_info *info)
@ -452,6 +470,25 @@ static void init_scan_signature_info(const struct vkd3d_shader_compile_info *inf
}
}
static const struct vkd3d_debug_option vkd3d_shader_config_options[] =
{
{"force_validation", VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION}, /* force validation of internal shader representations */
};
static uint64_t vkd3d_shader_init_config_flags(void)
{
uint64_t config_flags;
const char *config;
config = getenv("VKD3D_SHADER_CONFIG");
config_flags = vkd3d_parse_debug_options(config, vkd3d_shader_config_options, ARRAY_SIZE(vkd3d_shader_config_options));
if (config_flags)
TRACE("VKD3D_SHADER_CONFIG='%s'.\n", config);
return config_flags;
}
bool vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser,
struct vkd3d_shader_message_context *message_context, const char *source_name,
const struct vkd3d_shader_version *version, const struct vkd3d_shader_parser_ops *ops,
@ -463,6 +500,7 @@ bool vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser,
parser->location.column = 0;
parser->shader_version = *version;
parser->ops = ops;
parser->config_flags = vkd3d_shader_init_config_flags();
return shader_instruction_array_init(&parser->instructions, instruction_reserve);
}
@ -577,6 +615,8 @@ static bool vkd3d_shader_signature_from_shader_signature(struct vkd3d_shader_sig
struct vkd3d_shader_scan_context
{
const struct vkd3d_shader_version *version;
struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info;
size_t descriptors_size;
@ -598,21 +638,48 @@ struct vkd3d_shader_scan_context
size_t cf_info_count;
enum vkd3d_shader_api_version api_version;
struct vkd3d_shader_scan_combined_resource_sampler_info *combined_sampler_info;
size_t combined_samplers_size;
};
static VKD3D_PRINTF_FUNC(3, 4) void vkd3d_shader_scan_error(struct vkd3d_shader_scan_context *context,
enum vkd3d_shader_error error, const char *format, ...)
{
va_list args;
va_start(args, format);
vkd3d_shader_verror(context->message_context, &context->location, error, format, args);
va_end(args);
}
static void VKD3D_PRINTF_FUNC(3, 4) vkd3d_shader_scan_warning(struct vkd3d_shader_scan_context *context,
enum vkd3d_shader_error error, const char *format, ...)
{
va_list args;
va_start(args, format);
vkd3d_shader_vwarning(context->message_context, &context->location, error, format, args);
va_end(args);
}
static void vkd3d_shader_scan_context_init(struct vkd3d_shader_scan_context *context,
const struct vkd3d_shader_version *version,
const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info,
struct vkd3d_shader_scan_combined_resource_sampler_info *combined_sampler_info,
struct vkd3d_shader_message_context *message_context)
{
unsigned int i;
memset(context, 0, sizeof(*context));
context->version = version;
context->scan_descriptor_info = scan_descriptor_info;
context->message_context = message_context;
context->location.source_name = compile_info->source_name;
context->location.line = 2; /* Line 1 is the version token. */
context->api_version = VKD3D_SHADER_API_VERSION_1_2;
context->combined_sampler_info = combined_sampler_info;
for (i = 0; i < compile_info->option_count; ++i)
{
@ -762,6 +829,9 @@ static struct vkd3d_shader_descriptor_info1 *vkd3d_shader_scan_add_descriptor(st
struct vkd3d_shader_scan_descriptor_info1 *info = context->scan_descriptor_info;
struct vkd3d_shader_descriptor_info1 *d;
if (!info)
return NULL;
if (!vkd3d_array_reserve((void **)&info->descriptors, &context->descriptors_size,
info->descriptor_count + 1, sizeof(*info->descriptors)))
{
@ -789,13 +859,10 @@ static void vkd3d_shader_scan_constant_buffer_declaration(struct vkd3d_shader_sc
const struct vkd3d_shader_constant_buffer *cb = &instruction->declaration.cb;
struct vkd3d_shader_descriptor_info1 *d;
if (!context->scan_descriptor_info)
return;
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,
@ -804,9 +871,6 @@ static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_conte
const struct vkd3d_shader_sampler *sampler = &instruction->declaration.sampler;
struct vkd3d_shader_descriptor_info1 *d;
if (!context->scan_descriptor_info)
return;
if (!(d = vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER,
&sampler->src.reg, &sampler->range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_SHADER_RESOURCE_DATA_UINT)))
return;
@ -815,6 +879,103 @@ static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_conte
d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE;
}
static void vkd3d_shader_scan_combined_sampler_declaration(
struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_semantic *semantic)
{
vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, &semantic->resource.reg.reg,
&semantic->resource.range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_SHADER_RESOURCE_DATA_UINT);
vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, &semantic->resource.reg.reg,
&semantic->resource.range, semantic->resource_type, VKD3D_SHADER_RESOURCE_DATA_FLOAT);
}
static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_context *context,
const struct vkd3d_shader_register *resource, const struct vkd3d_shader_register *sampler)
{
struct vkd3d_shader_scan_combined_resource_sampler_info *info;
struct vkd3d_shader_combined_resource_sampler_info *s;
unsigned resource_space = 0, sampler_space = 0;
unsigned int resource_idx, sampler_idx, i;
if (!(info = context->combined_sampler_info))
return;
if (resource->type == VKD3DSPR_RESOURCE)
resource_idx = resource->idx[1].offset;
else
resource_idx = resource->idx[0].offset;
if (!sampler)
sampler_idx = VKD3D_SHADER_DUMMY_SAMPLER_INDEX;
else if (sampler->type == VKD3DSPR_SAMPLER)
sampler_idx = sampler->idx[1].offset;
else
sampler_idx = sampler->idx[0].offset;
if (vkd3d_shader_ver_ge(context->version, 5, 1))
{
const struct vkd3d_shader_scan_descriptor_info1 *info = context->scan_descriptor_info;
const struct vkd3d_shader_descriptor_info1 *d;
bool dynamic_resource, dynamic_sampler;
if ((dynamic_resource = resource->idx[1].rel_addr))
vkd3d_shader_scan_warning(context, VKD3D_SHADER_WARNING_VSIR_DYNAMIC_DESCRIPTOR_ARRAY,
"Resource descriptor array %u is being dynamically indexed, "
"not recording a combined resource-sampler pair.", resource->idx[0].offset);
if ((dynamic_sampler = sampler && sampler->idx[1].rel_addr))
vkd3d_shader_scan_warning(context, VKD3D_SHADER_WARNING_VSIR_DYNAMIC_DESCRIPTOR_ARRAY,
"Sampler descriptor array %u is being dynamically indexed, "
"not recording a combined resource-sampler pair.", sampler->idx[0].offset);
if (dynamic_resource || dynamic_sampler)
return;
for (i = 0; i < info->descriptor_count; ++i)
{
d = &info->descriptors[i];
if (d->type != VKD3D_SHADER_DESCRIPTOR_TYPE_SRV)
continue;
if (d->register_id != resource->idx[0].offset)
continue;
resource_space = d->register_space;
break;
}
if (sampler)
{
for (i = 0; i < info->descriptor_count; ++i)
{
d = &info->descriptors[i];
if (d->type != VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER)
continue;
if (d->register_id != sampler->idx[0].offset)
continue;
sampler_space = d->register_space;
break;
}
}
}
for (i = 0; i < info->combined_sampler_count; ++i)
{
s = &info->combined_samplers[i];
if (s->resource_space == resource_space && s->resource_index == resource_idx
&& s->sampler_space == sampler_space && s->sampler_index == sampler_idx)
return;
}
if (!vkd3d_array_reserve((void **)&info->combined_samplers, &context->combined_samplers_size,
info->combined_sampler_count + 1, sizeof(*info->combined_samplers)))
{
ERR("Failed to allocate combined sampler info.\n");
return;
}
s = &info->combined_samplers[info->combined_sampler_count++];
s->resource_space = resource_space;
s->resource_index = resource_idx;
s->sampler_space = sampler_space;
s->sampler_index = sampler_idx;
}
static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_context *context,
const struct vkd3d_shader_resource *resource, enum vkd3d_shader_resource_type resource_type,
enum vkd3d_shader_resource_data_type resource_data_type,
@ -823,9 +984,6 @@ static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_cont
struct vkd3d_shader_descriptor_info1 *d;
enum vkd3d_shader_descriptor_type type;
if (!context->scan_descriptor_info)
return;
if (resource->reg.reg.type == VKD3DSPR_UAV)
type = VKD3D_SHADER_DESCRIPTOR_TYPE_UAV;
else
@ -898,22 +1056,15 @@ static void vkd3d_shader_scan_typed_resource_declaration(struct vkd3d_shader_sca
semantic->resource_type, resource_data_type, semantic->sample_count, 0, false);
}
static void vkd3d_shader_scan_error(struct vkd3d_shader_scan_context *context,
enum vkd3d_shader_error error, const char *format, ...)
{
va_list args;
va_start(args, format);
vkd3d_shader_verror(context->message_context, &context->location, error, format, args);
va_end(args);
}
static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *context,
const struct vkd3d_shader_instruction *instruction)
{
const struct vkd3d_shader_register *sampler_reg;
struct vkd3d_shader_cf_info *cf_info;
unsigned int i;
context->location = instruction->location;
switch (instruction->handler_idx)
{
case VKD3DSIH_DCL_CONSTANT_BUFFER:
@ -923,6 +1074,12 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
vkd3d_shader_scan_sampler_declaration(context, instruction);
break;
case VKD3DSIH_DCL:
if (instruction->declaration.semantic.resource.reg.reg.type == VKD3DSPR_COMBINED_SAMPLER)
{
vkd3d_shader_scan_combined_sampler_declaration(context, &instruction->declaration.semantic);
break;
}
/* fall through */
case VKD3DSIH_DCL_UAV_TYPED:
vkd3d_shader_scan_typed_resource_declaration(context, instruction);
break;
@ -1053,6 +1210,58 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
if (context->cf_info_count)
context->cf_info[context->cf_info_count - 1].inside_block = false;
break;
case VKD3DSIH_TEX:
if (context->version->major == 1)
sampler_reg = &instruction->dst[0].reg;
else
sampler_reg = &instruction->src[1].reg;
vkd3d_shader_scan_combined_sampler_usage(context, sampler_reg, sampler_reg);
break;
case VKD3DSIH_TEXBEM:
case VKD3DSIH_TEXBEML:
case VKD3DSIH_TEXDP3TEX:
case VKD3DSIH_TEXM3x2TEX:
case VKD3DSIH_TEXM3x3SPEC:
case VKD3DSIH_TEXM3x3TEX:
case VKD3DSIH_TEXM3x3VSPEC:
case VKD3DSIH_TEXREG2AR:
case VKD3DSIH_TEXREG2GB:
case VKD3DSIH_TEXREG2RGB:
sampler_reg = &instruction->dst[0].reg;
vkd3d_shader_scan_combined_sampler_usage(context, sampler_reg, sampler_reg);
break;
case VKD3DSIH_GATHER4:
case VKD3DSIH_GATHER4_C:
case VKD3DSIH_SAMPLE:
case VKD3DSIH_SAMPLE_B:
case VKD3DSIH_SAMPLE_C:
case VKD3DSIH_SAMPLE_C_LZ:
case VKD3DSIH_SAMPLE_GRAD:
case VKD3DSIH_SAMPLE_LOD:
vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[1].reg, &instruction->src[2].reg);
break;
case VKD3DSIH_GATHER4_PO:
case VKD3DSIH_GATHER4_PO_C:
vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[2].reg, &instruction->src[3].reg);
break;
case VKD3DSIH_LD:
case VKD3DSIH_LD2DMS:
vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[1].reg, NULL);
break;
case VKD3DSIH_BUFINFO:
case VKD3DSIH_SAMPLE_INFO:
if (instruction->src[0].reg.type == VKD3DSPR_RESOURCE)
vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[0].reg, NULL);
break;
case VKD3DSIH_LD_RAW:
case VKD3DSIH_RESINFO:
if (instruction->src[1].reg.type == VKD3DSPR_RESOURCE)
vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[1].reg, NULL);
break;
case VKD3DSIH_LD_STRUCTURED:
if (instruction->src[2].reg.type == VKD3DSPR_RESOURCE)
vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[2].reg, NULL);
break;
default:
break;
}
@ -1083,7 +1292,6 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
}
}
++context->location.line;
return VKD3D_OK;
}
@ -1124,6 +1332,7 @@ static int scan_with_parser(const struct vkd3d_shader_compile_info *compile_info
struct vkd3d_shader_message_context *message_context,
struct vkd3d_shader_scan_descriptor_info1 *descriptor_info1, struct vkd3d_shader_parser *parser)
{
struct vkd3d_shader_scan_combined_resource_sampler_info *combined_sampler_info;
struct vkd3d_shader_scan_descriptor_info1 local_descriptor_info1 = {0};
struct vkd3d_shader_scan_descriptor_info *descriptor_info;
struct vkd3d_shader_scan_signature_info *signature_info;
@ -1144,7 +1353,16 @@ static int scan_with_parser(const struct vkd3d_shader_compile_info *compile_info
}
signature_info = vkd3d_find_struct(compile_info->next, SCAN_SIGNATURE_INFO);
vkd3d_shader_scan_context_init(&context, compile_info, descriptor_info1, message_context);
if ((combined_sampler_info = vkd3d_find_struct(compile_info->next, SCAN_COMBINED_RESOURCE_SAMPLER_INFO)))
{
combined_sampler_info->combined_samplers = NULL;
combined_sampler_info->combined_sampler_count = 0;
if (!descriptor_info1)
descriptor_info1 = &local_descriptor_info1;
}
vkd3d_shader_scan_context_init(&context, &parser->shader_version, compile_info,
descriptor_info1, combined_sampler_info, message_context);
if (TRACE_ON())
{
@ -1190,6 +1408,8 @@ static int scan_with_parser(const struct vkd3d_shader_compile_info *compile_info
if (ret < 0)
{
if (combined_sampler_info)
vkd3d_shader_free_scan_combined_resource_sampler_info(combined_sampler_info);
if (descriptor_info)
vkd3d_shader_free_scan_descriptor_info(descriptor_info);
if (descriptor_info1)
@ -1276,6 +1496,8 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char
vkd3d_shader_message_context_init(&message_context, compile_info->log_level);
vkd3d_shader_dump_shader(compile_info);
switch (compile_info->source_type)
{
case VKD3D_SHADER_SOURCE_DXBC_TPF:
@ -1317,8 +1539,6 @@ static int vkd3d_shader_parser_compile(struct vkd3d_shader_parser *parser,
struct vkd3d_shader_compile_info scan_info;
int ret;
vkd3d_shader_dump_shader(compile_info->source_type, parser->shader_version.type, &compile_info->source);
scan_info = *compile_info;
if ((ret = scan_with_parser(&scan_info, message_context, &scan_descriptor_info, parser)) < 0)
@ -1402,8 +1622,6 @@ static int compile_d3d_bytecode(const struct vkd3d_shader_compile_info *compile_
return ret;
}
vkd3d_shader_dump_shader(compile_info->source_type, parser->shader_version.type, &compile_info->source);
if (compile_info->target_type == VKD3D_SHADER_TARGET_D3D_ASM)
{
ret = vkd3d_dxbc_binary_to_text(&parser->instructions, &parser->shader_version, compile_info, out);
@ -1450,6 +1668,8 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
vkd3d_shader_message_context_init(&message_context, compile_info->log_level);
vkd3d_shader_dump_shader(compile_info);
switch (compile_info->source_type)
{
case VKD3D_SHADER_SOURCE_DXBC_TPF:
@ -1479,6 +1699,14 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
return ret;
}
void vkd3d_shader_free_scan_combined_resource_sampler_info(
struct vkd3d_shader_scan_combined_resource_sampler_info *info)
{
TRACE("info %p.\n", info);
vkd3d_free(info->combined_samplers);
}
void vkd3d_shader_free_scan_descriptor_info(struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info)
{
TRACE("scan_descriptor_info %p.\n", scan_descriptor_info);
@ -1751,7 +1979,7 @@ static struct vkd3d_shader_param_node *shader_param_allocator_node_create(
static void shader_param_allocator_init(struct vkd3d_shader_param_allocator *allocator,
unsigned int count, unsigned int stride)
{
allocator->count = max(count, 4);
allocator->count = max(count, MAX_REG_OUTPUT);
allocator->stride = stride;
allocator->head = NULL;
allocator->current = NULL;

View file

@ -92,6 +92,10 @@ enum vkd3d_shader_error
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_OUT_OF_MEMORY = 2005,
VKD3D_SHADER_ERROR_SPV_INVALID_TYPE = 2006,
VKD3D_SHADER_ERROR_SPV_INVALID_HANDLER = 2007,
VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED = 2008,
VKD3D_SHADER_WARNING_SPV_INVALID_SWIZZLE = 2300,
@ -141,6 +145,7 @@ enum vkd3d_shader_error
VKD3D_SHADER_ERROR_HLSL_RECURSIVE_CALL = 5025,
VKD3D_SHADER_ERROR_HLSL_INCONSISTENT_SAMPLER = 5026,
VKD3D_SHADER_ERROR_HLSL_NON_FINITE_RESULT = 5027,
VKD3D_SHADER_ERROR_HLSL_DUPLICATE_SWITCH_CASE = 5028,
VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300,
VKD3D_SHADER_WARNING_HLSL_DIVISION_BY_ZERO = 5301,
@ -174,15 +179,43 @@ enum vkd3d_shader_error
VKD3D_SHADER_ERROR_DXIL_INVALID_TYPE_ID = 8010,
VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE = 8011,
VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND = 8012,
VKD3D_SHADER_ERROR_DXIL_UNHANDLED_INTRINSIC = 8013,
VKD3D_SHADER_ERROR_DXIL_INVALID_METADATA = 8014,
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_ERROR_DXIL_INVALID_RESOURCE_HANDLE = 8019,
VKD3D_SHADER_WARNING_DXIL_UNKNOWN_MAGIC_NUMBER = 8300,
VKD3D_SHADER_WARNING_DXIL_UNKNOWN_SHADER_TYPE = 8301,
VKD3D_SHADER_WARNING_DXIL_INVALID_BLOCK_LENGTH = 8302,
VKD3D_SHADER_WARNING_DXIL_INVALID_MODULE_LENGTH = 8303,
VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS = 8304,
VKD3D_SHADER_WARNING_DXIL_UNHANDLED_INTRINSIC = 8305,
VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH = 8305,
VKD3D_SHADER_WARNING_DXIL_ENTRY_POINT_MISMATCH = 8306,
VKD3D_SHADER_WARNING_DXIL_INVALID_MASK = 8307,
VKD3D_SHADER_WARNING_DXIL_INVALID_OPERATION = 8308,
VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED = 9000,
VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER = 9001,
VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE = 9002,
VKD3D_SHADER_ERROR_VSIR_INVALID_WRITE_MASK = 9003,
VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS = 9004,
VKD3D_SHADER_ERROR_VSIR_INVALID_SHIFT = 9005,
VKD3D_SHADER_ERROR_VSIR_INVALID_SWIZZLE = 9006,
VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION = 9007,
VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE = 9008,
VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION = 9009,
VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT = 9010,
VKD3D_SHADER_ERROR_VSIR_INVALID_DEST_COUNT = 9011,
VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT = 9012,
VKD3D_SHADER_ERROR_VSIR_DUPLICATE_DCL_TEMPS = 9013,
VKD3D_SHADER_ERROR_VSIR_INVALID_DCL_TEMPS = 9014,
VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX = 9015,
VKD3D_SHADER_ERROR_VSIR_INVALID_INSTRUCTION_NESTING = 9016,
VKD3D_SHADER_WARNING_VSIR_DYNAMIC_DESCRIPTOR_ARRAY = 9300,
};
enum vkd3d_shader_opcode
@ -264,9 +297,9 @@ enum vkd3d_shader_opcode
VKD3DSIH_DEFAULT,
VKD3DSIH_DEFB,
VKD3DSIH_DEFI,
VKD3DSIH_DEQ,
VKD3DSIH_DEQO,
VKD3DSIH_DFMA,
VKD3DSIH_DGE,
VKD3DSIH_DGEO,
VKD3DSIH_DISCARD,
VKD3DSIH_DIV,
VKD3DSIH_DLT,
@ -298,7 +331,8 @@ enum vkd3d_shader_opcode
VKD3DSIH_ENDLOOP,
VKD3DSIH_ENDREP,
VKD3DSIH_ENDSWITCH,
VKD3DSIH_EQ,
VKD3DSIH_EQO,
VKD3DSIH_EQU,
VKD3DSIH_EVAL_CENTROID,
VKD3DSIH_EVAL_SAMPLE_INDEX,
VKD3DSIH_EXP,
@ -310,6 +344,7 @@ enum vkd3d_shader_opcode
VKD3DSIH_FIRSTBIT_LO,
VKD3DSIH_FIRSTBIT_SHI,
VKD3DSIH_FRC,
VKD3DSIH_FREM,
VKD3DSIH_FTOD,
VKD3DSIH_FTOI,
VKD3DSIH_FTOU,
@ -321,13 +356,15 @@ enum vkd3d_shader_opcode
VKD3DSIH_GATHER4_PO_C_S,
VKD3DSIH_GATHER4_PO_S,
VKD3DSIH_GATHER4_S,
VKD3DSIH_GE,
VKD3DSIH_GEO,
VKD3DSIH_GEU,
VKD3DSIH_HS_CONTROL_POINT_PHASE,
VKD3DSIH_HS_DECLS,
VKD3DSIH_HS_FORK_PHASE,
VKD3DSIH_HS_JOIN_PHASE,
VKD3DSIH_IADD,
VKD3DSIH_IBFE,
VKD3DSIH_IDIV,
VKD3DSIH_IEQ,
VKD3DSIH_IF,
VKD3DSIH_IFC,
@ -355,6 +392,7 @@ enum vkd3d_shader_opcode
VKD3DSIH_ISHR,
VKD3DSIH_ITOD,
VKD3DSIH_ITOF,
VKD3DSIH_ITOI,
VKD3DSIH_LABEL,
VKD3DSIH_LD,
VKD3DSIH_LD2DMS,
@ -372,7 +410,8 @@ enum vkd3d_shader_opcode
VKD3DSIH_LOGP,
VKD3DSIH_LOOP,
VKD3DSIH_LRP,
VKD3DSIH_LT,
VKD3DSIH_LTO,
VKD3DSIH_LTU,
VKD3DSIH_M3x2,
VKD3DSIH_M3x3,
VKD3DSIH_M3x4,
@ -386,7 +425,8 @@ enum vkd3d_shader_opcode
VKD3DSIH_MOVC,
VKD3DSIH_MSAD,
VKD3DSIH_MUL,
VKD3DSIH_NE,
VKD3DSIH_NEO,
VKD3DSIH_NEU,
VKD3DSIH_NOP,
VKD3DSIH_NOT,
VKD3DSIH_NRM,
@ -462,6 +502,7 @@ enum vkd3d_shader_opcode
VKD3DSIH_USHR,
VKD3DSIH_UTOD,
VKD3DSIH_UTOF,
VKD3DSIH_UTOU,
VKD3DSIH_XOR,
VKD3DSIH_INVALID,
@ -481,7 +522,7 @@ enum vkd3d_shader_register_type
VKD3DSPR_CONSTINT = 7,
VKD3DSPR_COLOROUT = 8,
VKD3DSPR_DEPTHOUT = 9,
VKD3DSPR_SAMPLER = 10,
VKD3DSPR_COMBINED_SAMPLER = 10,
VKD3DSPR_CONST2 = 11,
VKD3DSPR_CONST3 = 12,
VKD3DSPR_CONST4 = 13,
@ -497,6 +538,7 @@ enum vkd3d_shader_register_type
VKD3DSPR_IMMCONSTBUFFER,
VKD3DSPR_PRIMID,
VKD3DSPR_NULL,
VKD3DSPR_SAMPLER,
VKD3DSPR_RESOURCE,
VKD3DSPR_UAV,
VKD3DSPR_OUTPOINTID,
@ -523,6 +565,7 @@ enum vkd3d_shader_register_type
VKD3DSPR_RASTERIZER,
VKD3DSPR_OUTSTENCILREF,
VKD3DSPR_UNDEF,
VKD3DSPR_SSA,
VKD3DSPR_COUNT,
@ -537,6 +580,8 @@ enum vkd3d_shader_register_precision
VKD3D_SHADER_REGISTER_PRECISION_MIN_INT_16,
VKD3D_SHADER_REGISTER_PRECISION_MIN_UINT_16,
VKD3D_SHADER_REGISTER_PRECISION_COUNT,
VKD3D_SHADER_REGISTER_PRECISION_INVALID = ~0u,
};
@ -556,17 +601,30 @@ enum vkd3d_data_type
VKD3D_DATA_CONTINUED,
VKD3D_DATA_UNUSED,
VKD3D_DATA_UINT8,
VKD3D_DATA_UINT64,
VKD3D_DATA_BOOL,
VKD3D_DATA_COUNT,
};
static inline bool data_type_is_integer(enum vkd3d_data_type data_type)
{
return data_type == VKD3D_DATA_INT || data_type == VKD3D_DATA_UINT8 || data_type == VKD3D_DATA_UINT;
return data_type == VKD3D_DATA_INT || data_type == VKD3D_DATA_UINT8 || data_type == VKD3D_DATA_UINT
|| data_type == VKD3D_DATA_UINT64;
}
enum vkd3d_immconst_type
static inline bool data_type_is_bool(enum vkd3d_data_type data_type)
{
VKD3D_IMMCONST_SCALAR,
VKD3D_IMMCONST_VEC4,
return data_type == VKD3D_DATA_BOOL;
}
enum vsir_dimension
{
VSIR_DIMENSION_NONE,
VSIR_DIMENSION_SCALAR,
VSIR_DIMENSION_VEC4,
VSIR_DIMENSION_COUNT,
};
enum vkd3d_shader_src_modifier
@ -585,6 +643,7 @@ enum vkd3d_shader_src_modifier
VKD3DSPSM_ABS = 11,
VKD3DSPSM_ABSNEG = 12,
VKD3DSPSM_NOT = 13,
VKD3DSPSM_COUNT,
};
#define VKD3DSP_WRITEMASK_0 0x1u /* .x r */
@ -599,6 +658,7 @@ enum vkd3d_shader_dst_modifier
VKD3DSPDM_SATURATE = 1,
VKD3DSPDM_PARTIALPRECISION = 2,
VKD3DSPDM_MSAMPCENTROID = 4,
VKD3DSPDM_MASK = 7,
};
enum vkd3d_shader_interpolation_mode
@ -611,6 +671,8 @@ enum vkd3d_shader_interpolation_mode
VKD3DSIM_LINEAR_NOPERSPECTIVE_CENTROID = 5,
VKD3DSIM_LINEAR_SAMPLE = 6,
VKD3DSIM_LINEAR_NOPERSPECTIVE_SAMPLE = 7,
VKD3DSIM_COUNT = 8,
};
enum vkd3d_shader_global_flags
@ -622,6 +684,32 @@ enum vkd3d_shader_global_flags
VKD3DSGF_SKIP_OPTIMIZATION = 0x10,
VKD3DSGF_ENABLE_MINIMUM_PRECISION = 0x20,
VKD3DSGF_ENABLE_11_1_DOUBLE_EXTENSIONS = 0x40,
VKD3DSGF_ENABLE_SHADER_EXTENSIONS = 0x80, /* never emitted? */
VKD3DSGF_BIND_FOR_DURATION = 0x100,
VKD3DSGF_ENABLE_VP_AND_RT_ARRAY_INDEX = 0x200,
VKD3DSGF_ENABLE_INNER_COVERAGE = 0x400,
VKD3DSGF_ENABLE_STENCIL_REF = 0x800,
VKD3DSGF_ENABLE_TILED_RESOURCE_INTRINSICS = 0x1000,
VKD3DSGF_ENABLE_RELAXED_TYPED_UAV_FORMATS = 0x2000,
VKD3DSGF_ENABLE_LVL_9_COMPARISON_FILTERING = 0x4000,
VKD3DSGF_ENABLE_UP_TO_64_UAVS = 0x8000,
VKD3DSGF_ENABLE_UAVS_AT_EVERY_STAGE = 0x10000,
VKD3DSGF_ENABLE_CS4_RAW_STRUCTURED_BUFFERS = 0x20000,
VKD3DSGF_ENABLE_RASTERIZER_ORDERED_VIEWS = 0x40000,
VKD3DSGF_ENABLE_WAVE_INTRINSICS = 0x80000,
VKD3DSGF_ENABLE_INT64 = 0x100000,
VKD3DSGF_ENABLE_VIEWID = 0x200000,
VKD3DSGF_ENABLE_BARYCENTRICS = 0x400000,
VKD3DSGF_FORCE_NATIVE_LOW_PRECISION = 0x800000,
VKD3DSGF_ENABLE_SHADINGRATE = 0x1000000,
VKD3DSGF_ENABLE_RAYTRACING_TIER_1_1 = 0x2000000,
VKD3DSGF_ENABLE_SAMPLER_FEEDBACK = 0x4000000,
VKD3DSGF_ENABLE_ATOMIC_INT64_ON_TYPED_RESOURCE = 0x8000000,
VKD3DSGF_ENABLE_ATOMIC_INT64_ON_GROUP_SHARED = 0x10000000,
VKD3DSGF_ENABLE_DERIVATIVES_IN_MESH_AND_AMPLIFICATION_SHADERS = 0x20000000,
VKD3DSGF_ENABLE_RESOURCE_DESCRIPTOR_HEAP_INDEXING = 0x40000000,
VKD3DSGF_ENABLE_SAMPLER_DESCRIPTOR_HEAP_INDEXING = 0x80000000,
VKD3DSGF_ENABLE_ATOMIC_INT64_ON_DESCRIPTOR_HEAP_RESOURCE = 0x100000000ull,
};
enum vkd3d_shader_sync_flags
@ -633,7 +721,8 @@ enum vkd3d_shader_sync_flags
enum vkd3d_shader_uav_flags
{
VKD3DSUF_GLOBALLY_COHERENT = 0x2,
VKD3DSUF_GLOBALLY_COHERENT = 0x002,
VKD3DSUF_RASTERISER_ORDERED_VIEW = 0x004,
VKD3DSUF_ORDER_PRESERVING_COUNTER = 0x100,
};
@ -704,22 +793,29 @@ struct vkd3d_shader_version
struct vkd3d_shader_immediate_constant_buffer
{
unsigned int vec4_count;
enum vkd3d_data_type data_type;
/* total count is element_count * component_count */
unsigned int element_count;
unsigned int component_count;
uint32_t data[];
};
struct vkd3d_shader_indexable_temp
{
struct list entry;
unsigned int register_idx;
unsigned int register_size;
unsigned int alignment;
enum vkd3d_data_type data_type;
unsigned int component_count;
const struct vkd3d_shader_immediate_constant_buffer *initialiser;
};
struct vkd3d_shader_register_index
{
const struct vkd3d_shader_src_param *rel_addr;
unsigned int offset;
/* address is known to fall within the object (for optimisation) */
bool is_in_bounds;
};
struct vkd3d_shader_register
@ -730,7 +826,9 @@ struct vkd3d_shader_register
enum vkd3d_data_type data_type;
struct vkd3d_shader_register_index idx[3];
unsigned int idx_count;
enum vkd3d_immconst_type immconst_type;
enum vsir_dimension dimension;
/* known address alignment for optimisation, or zero */
unsigned int alignment;
union
{
DWORD immconst_uint[VKD3D_VEC4_SIZE];
@ -741,13 +839,28 @@ struct vkd3d_shader_register
} u;
};
void shader_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type,
void vsir_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type,
enum vkd3d_data_type data_type, unsigned int idx_count);
static inline bool vsir_register_is_descriptor(const struct vkd3d_shader_register *reg)
{
switch (reg->type)
{
case VKD3DSPR_SAMPLER:
case VKD3DSPR_RESOURCE:
case VKD3DSPR_CONSTBUFFER:
case VKD3DSPR_UAV:
return true;
default:
return false;
}
}
struct vkd3d_shader_dst_param
{
struct vkd3d_shader_register reg;
DWORD write_mask;
uint32_t write_mask;
DWORD modifiers;
DWORD shift;
};
@ -848,6 +961,7 @@ struct signature_element
unsigned int mask;
unsigned int used_mask;
enum vkd3d_shader_minimum_precision min_precision;
enum vkd3d_shader_interpolation_mode interpolation_mode;
/* Register index / location in the target shader.
* If SIGNATURE_TARGET_LOCATION_UNUSED, this element should not be written. */
unsigned int target_location;
@ -860,6 +974,19 @@ struct shader_signature
unsigned int element_count;
};
static inline bool vsir_sysval_semantic_is_tess_factor(enum vkd3d_shader_sysval_semantic sysval_semantic)
{
return sysval_semantic >= VKD3D_SHADER_SV_TESS_FACTOR_QUADEDGE
&& sysval_semantic <= VKD3D_SHADER_SV_TESS_FACTOR_LINEDEN;
}
static inline bool vsir_sysval_semantic_is_clip_cull(enum vkd3d_shader_sysval_semantic sysval_semantic)
{
return sysval_semantic == VKD3D_SHADER_SV_CLIP_DISTANCE || sysval_semantic == VKD3D_SHADER_SV_CULL_DISTANCE;
}
struct signature_element *vsir_signature_find_element_for_reg(const struct shader_signature *signature,
unsigned int reg_idx, unsigned int write_mask);
void shader_signature_cleanup(struct shader_signature *signature);
struct vkd3d_shader_desc
@ -871,12 +998,17 @@ struct vkd3d_shader_desc
struct shader_signature output_signature;
struct shader_signature patch_constant_signature;
unsigned int input_control_point_count, output_control_point_count;
uint32_t temp_count;
unsigned int ssa_count;
struct
{
uint32_t used, external;
} flat_constant_count[3];
bool use_vocp;
};
struct vkd3d_shader_register_semantic
@ -968,8 +1100,15 @@ struct vkd3d_shader_primitive_type
unsigned int patch_vertex_count;
};
struct vkd3d_shader_location
{
const char *source_name;
unsigned int line, column;
};
struct vkd3d_shader_instruction
{
struct vkd3d_shader_location location;
enum vkd3d_shader_opcode handler_idx;
DWORD flags;
unsigned int dst_count;
@ -984,6 +1123,7 @@ struct vkd3d_shader_instruction
const struct vkd3d_shader_src_param *predicate;
union
{
enum vkd3d_shader_global_flags global_flags;
struct vkd3d_shader_semantic semantic;
struct vkd3d_shader_register_semantic register_semantic;
struct vkd3d_shader_primitive_type primitive_type;
@ -1008,39 +1148,29 @@ struct vkd3d_shader_instruction
} declaration;
};
void shader_instruction_init(struct vkd3d_shader_instruction *ins, enum vkd3d_shader_opcode handler_idx);
static inline bool vkd3d_shader_ver_ge(const struct vkd3d_shader_version *v, unsigned int major, unsigned int minor)
{
return v->major > major || (v->major == major && v->minor >= minor);
}
static inline bool vkd3d_shader_ver_le(const struct vkd3d_shader_version *v, unsigned int major, unsigned int minor)
{
return v->major < major || (v->major == major && v->minor <= minor);
}
void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location,
enum vkd3d_shader_opcode handler_idx);
static inline bool vkd3d_shader_instruction_has_texel_offset(const struct vkd3d_shader_instruction *ins)
{
return ins->texel_offset.u || ins->texel_offset.v || ins->texel_offset.w;
}
static inline bool vkd3d_shader_register_is_input(const struct vkd3d_shader_register *reg)
{
return reg->type == VKD3DSPR_INPUT || reg->type == VKD3DSPR_INCONTROLPOINT || reg->type == VKD3DSPR_OUTCONTROLPOINT;
}
static inline bool vkd3d_shader_register_is_output(const struct vkd3d_shader_register *reg)
{
return reg->type == VKD3DSPR_OUTPUT || reg->type == VKD3DSPR_COLOROUT;
}
static inline bool vkd3d_shader_register_is_patch_constant(const struct vkd3d_shader_register *reg)
{
return reg->type == VKD3DSPR_PATCHCONST;
}
static inline bool register_is_constant(const struct vkd3d_shader_register *reg)
{
return (reg->type == VKD3DSPR_IMMCONST || reg->type == VKD3DSPR_IMMCONST64);
}
struct vkd3d_shader_location
{
const char *source_name;
unsigned int line, column;
};
struct vkd3d_shader_param_node
{
struct vkd3d_shader_param_node *next;
@ -1093,6 +1223,11 @@ bool shader_instruction_array_clone_instruction(struct vkd3d_shader_instruction_
unsigned int dst, unsigned int src);
void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *instructions);
enum vkd3d_shader_config_flags
{
VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION = 0x00000001,
};
struct vkd3d_shader_parser
{
struct vkd3d_shader_message_context *message_context;
@ -1103,6 +1238,8 @@ struct vkd3d_shader_parser
struct vkd3d_shader_version shader_version;
const struct vkd3d_shader_parser_ops *ops;
struct vkd3d_shader_instruction_array instructions;
uint64_t config_flags;
};
struct vkd3d_shader_parser_ops
@ -1248,8 +1385,7 @@ void vkd3d_shader_vnote(struct vkd3d_shader_message_context *context, const stru
void vkd3d_shader_vwarning(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location,
enum vkd3d_shader_error error, const char *format, va_list args);
void vkd3d_shader_dump_shader(enum vkd3d_shader_source_type source_type,
enum vkd3d_shader_type shader_type, const struct vkd3d_shader_code *shader);
void vkd3d_shader_dump_shader(const struct vkd3d_shader_compile_info *compile_info);
void vkd3d_shader_trace_text_(const char *text, size_t size, const char *function);
#define vkd3d_shader_trace_text(text, size) \
vkd3d_shader_trace_text_(text, size, __FUNCTION__)
@ -1291,6 +1427,8 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info,
int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context);
void vsir_validate(struct vkd3d_shader_parser *parser);
static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_type(
enum vkd3d_data_type data_type)
{
@ -1306,6 +1444,8 @@ static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_ty
return VKD3D_SHADER_COMPONENT_INT;
case VKD3D_DATA_DOUBLE:
return VKD3D_SHADER_COMPONENT_DOUBLE;
case VKD3D_DATA_BOOL:
return VKD3D_SHADER_COMPONENT_BOOL;
default:
FIXME("Unhandled data type %#x.\n", data_type);
/* fall-through */
@ -1458,23 +1598,6 @@ static inline void *vkd3d_find_struct_(const struct vkd3d_struct *chain,
#define VKD3D_DXBC_HEADER_SIZE (8 * sizeof(uint32_t))
#define VKD3D_DXBC_CHUNK_ALIGNMENT sizeof(uint32_t)
#define TAG_AON9 VKD3D_MAKE_TAG('A', 'o', 'n', '9')
#define TAG_DXBC VKD3D_MAKE_TAG('D', 'X', 'B', 'C')
#define TAG_DXIL VKD3D_MAKE_TAG('D', 'X', 'I', 'L')
#define TAG_ISG1 VKD3D_MAKE_TAG('I', 'S', 'G', '1')
#define TAG_ISGN VKD3D_MAKE_TAG('I', 'S', 'G', 'N')
#define TAG_OSG1 VKD3D_MAKE_TAG('O', 'S', 'G', '1')
#define TAG_OSG5 VKD3D_MAKE_TAG('O', 'S', 'G', '5')
#define TAG_OSGN VKD3D_MAKE_TAG('O', 'S', 'G', 'N')
#define TAG_PCSG VKD3D_MAKE_TAG('P', 'C', 'S', 'G')
#define TAG_PSG1 VKD3D_MAKE_TAG('P', 'S', 'G', '1')
#define TAG_RD11 VKD3D_MAKE_TAG('R', 'D', '1', '1')
#define TAG_RDEF VKD3D_MAKE_TAG('R', 'D', 'E', 'F')
#define TAG_RTS0 VKD3D_MAKE_TAG('R', 'T', 'S', '0')
#define TAG_SHDR VKD3D_MAKE_TAG('S', 'H', 'D', 'R')
#define TAG_SHEX VKD3D_MAKE_TAG('S', 'H', 'E', 'X')
#define TAG_TEXT VKD3D_MAKE_TAG('T', 'E', 'X', 'T')
#define DXBC_MAX_SECTION_COUNT 5
struct dxbc_writer

View file

@ -1942,9 +1942,9 @@ static void d3d12_command_signature_decref(struct d3d12_command_signature *signa
}
/* ID3D12CommandList */
static inline struct d3d12_command_list *impl_from_ID3D12GraphicsCommandList3(ID3D12GraphicsCommandList3 *iface)
static inline struct d3d12_command_list *impl_from_ID3D12GraphicsCommandList5(ID3D12GraphicsCommandList5 *iface)
{
return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandList3_iface);
return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandList5_iface);
}
static void d3d12_command_list_invalidate_current_framebuffer(struct d3d12_command_list *list)
@ -2290,12 +2290,14 @@ static void d3d12_command_list_track_resource_usage(struct d3d12_command_list *l
}
}
static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12GraphicsCommandList3 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12GraphicsCommandList5 *iface,
REFIID iid, void **object)
{
TRACE("iface %p, iid %s, object %p.\n", iface, debugstr_guid(iid), object);
if (IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList3)
if (IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList5)
|| IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList4)
|| IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList3)
|| IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList2)
|| IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList1)
|| IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList)
@ -2304,7 +2306,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12Graphic
|| IsEqualGUID(iid, &IID_ID3D12Object)
|| IsEqualGUID(iid, &IID_IUnknown))
{
ID3D12GraphicsCommandList3_AddRef(iface);
ID3D12GraphicsCommandList5_AddRef(iface);
*object = iface;
return S_OK;
}
@ -2315,9 +2317,9 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12Graphic
return E_NOINTERFACE;
}
static ULONG STDMETHODCALLTYPE d3d12_command_list_AddRef(ID3D12GraphicsCommandList3 *iface)
static ULONG STDMETHODCALLTYPE d3d12_command_list_AddRef(ID3D12GraphicsCommandList5 *iface)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
ULONG refcount = InterlockedIncrement(&list->refcount);
TRACE("%p increasing refcount to %u.\n", list, refcount);
@ -2330,9 +2332,9 @@ static void vkd3d_pipeline_bindings_cleanup(struct vkd3d_pipeline_bindings *bind
vkd3d_free(bindings->vk_uav_counter_views);
}
static ULONG STDMETHODCALLTYPE d3d12_command_list_Release(ID3D12GraphicsCommandList3 *iface)
static ULONG STDMETHODCALLTYPE d3d12_command_list_Release(ID3D12GraphicsCommandList5 *iface)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
ULONG refcount = InterlockedDecrement(&list->refcount);
TRACE("%p decreasing refcount to %u.\n", list, refcount);
@ -2358,66 +2360,66 @@ static ULONG STDMETHODCALLTYPE d3d12_command_list_Release(ID3D12GraphicsCommandL
return refcount;
}
static HRESULT STDMETHODCALLTYPE d3d12_command_list_GetPrivateData(ID3D12GraphicsCommandList3 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_command_list_GetPrivateData(ID3D12GraphicsCommandList5 *iface,
REFGUID guid, UINT *data_size, void *data)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
return vkd3d_get_private_data(&list->private_store, guid, data_size, data);
}
static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetPrivateData(ID3D12GraphicsCommandList3 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetPrivateData(ID3D12GraphicsCommandList5 *iface,
REFGUID guid, UINT data_size, const void *data)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
return vkd3d_set_private_data(&list->private_store, guid, data_size, data);
}
static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetPrivateDataInterface(ID3D12GraphicsCommandList3 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetPrivateDataInterface(ID3D12GraphicsCommandList5 *iface,
REFGUID guid, const IUnknown *data)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
return vkd3d_set_private_data_interface(&list->private_store, guid, data);
}
static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetName(ID3D12GraphicsCommandList3 *iface, const WCHAR *name)
static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetName(ID3D12GraphicsCommandList5 *iface, const WCHAR *name)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
TRACE("iface %p, name %s.\n", iface, debugstr_w(name, list->device->wchar_size));
return name ? S_OK : E_INVALIDARG;
}
static HRESULT STDMETHODCALLTYPE d3d12_command_list_GetDevice(ID3D12GraphicsCommandList3 *iface, REFIID iid, void **device)
static HRESULT STDMETHODCALLTYPE d3d12_command_list_GetDevice(ID3D12GraphicsCommandList5 *iface, REFIID iid, void **device)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
TRACE("iface %p, iid %s, device %p.\n", iface, debugstr_guid(iid), device);
return d3d12_device_query_interface(list->device, iid, device);
}
static D3D12_COMMAND_LIST_TYPE STDMETHODCALLTYPE d3d12_command_list_GetType(ID3D12GraphicsCommandList3 *iface)
static D3D12_COMMAND_LIST_TYPE STDMETHODCALLTYPE d3d12_command_list_GetType(ID3D12GraphicsCommandList5 *iface)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
TRACE("iface %p.\n", iface);
return list->type;
}
static HRESULT STDMETHODCALLTYPE d3d12_command_list_Close(ID3D12GraphicsCommandList3 *iface)
static HRESULT STDMETHODCALLTYPE d3d12_command_list_Close(ID3D12GraphicsCommandList5 *iface)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
const struct vkd3d_vk_device_procs *vk_procs;
VkResult vr;
@ -2461,7 +2463,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_Close(ID3D12GraphicsCommandL
static void d3d12_command_list_reset_state(struct d3d12_command_list *list,
ID3D12PipelineState *initial_pipeline_state)
{
ID3D12GraphicsCommandList3 *iface = &list->ID3D12GraphicsCommandList3_iface;
ID3D12GraphicsCommandList5 *iface = &list->ID3D12GraphicsCommandList5_iface;
memset(list->strides, 0, sizeof(list->strides));
list->primitive_topology = D3D_PRIMITIVE_TOPOLOGY_POINTLIST;
@ -2497,14 +2499,14 @@ static void d3d12_command_list_reset_state(struct d3d12_command_list *list,
list->descriptor_heap_count = 0;
ID3D12GraphicsCommandList3_SetPipelineState(iface, initial_pipeline_state);
ID3D12GraphicsCommandList5_SetPipelineState(iface, initial_pipeline_state);
}
static HRESULT STDMETHODCALLTYPE d3d12_command_list_Reset(ID3D12GraphicsCommandList3 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_command_list_Reset(ID3D12GraphicsCommandList5 *iface,
ID3D12CommandAllocator *allocator, ID3D12PipelineState *initial_pipeline_state)
{
struct d3d12_command_allocator *allocator_impl = unsafe_impl_from_ID3D12CommandAllocator(allocator);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
HRESULT hr;
TRACE("iface %p, allocator %p, initial_pipeline_state %p.\n",
@ -2531,10 +2533,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_Reset(ID3D12GraphicsCommandL
return hr;
}
static void STDMETHODCALLTYPE d3d12_command_list_ClearState(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_ClearState(ID3D12GraphicsCommandList5 *iface,
ID3D12PipelineState *pipeline_state)
{
FIXME("iface %p, pipline_state %p stub!\n", iface, pipeline_state);
FIXME("iface %p, pipeline_state %p stub!\n", iface, pipeline_state);
}
static bool d3d12_command_list_has_depth_stencil_view(struct d3d12_command_list *list)
@ -3390,11 +3392,11 @@ static void d3d12_command_list_check_index_buffer_strip_cut_value(struct d3d12_c
}
}
static void STDMETHODCALLTYPE d3d12_command_list_DrawInstanced(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_DrawInstanced(ID3D12GraphicsCommandList5 *iface,
UINT vertex_count_per_instance, UINT instance_count, UINT start_vertex_location,
UINT start_instance_location)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
const struct vkd3d_vk_device_procs *vk_procs;
TRACE("iface %p, vertex_count_per_instance %u, instance_count %u, "
@ -3414,11 +3416,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_DrawInstanced(ID3D12GraphicsCom
instance_count, start_vertex_location, start_instance_location));
}
static void STDMETHODCALLTYPE d3d12_command_list_DrawIndexedInstanced(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_DrawIndexedInstanced(ID3D12GraphicsCommandList5 *iface,
UINT index_count_per_instance, UINT instance_count, UINT start_vertex_location,
INT base_vertex_location, UINT start_instance_location)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
const struct vkd3d_vk_device_procs *vk_procs;
TRACE("iface %p, index_count_per_instance %u, instance_count %u, start_vertex_location %u, "
@ -3440,10 +3442,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_DrawIndexedInstanced(ID3D12Grap
instance_count, start_vertex_location, base_vertex_location, start_instance_location));
}
static void STDMETHODCALLTYPE d3d12_command_list_Dispatch(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_Dispatch(ID3D12GraphicsCommandList5 *iface,
UINT x, UINT y, UINT z)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
const struct vkd3d_vk_device_procs *vk_procs;
TRACE("iface %p, x %u, y %u, z %u.\n", iface, x, y, z);
@ -3459,10 +3461,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_Dispatch(ID3D12GraphicsCommandL
VK_CALL(vkCmdDispatch(list->vk_command_buffer, x, y, z));
}
static void STDMETHODCALLTYPE d3d12_command_list_CopyBufferRegion(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_CopyBufferRegion(ID3D12GraphicsCommandList5 *iface,
ID3D12Resource *dst, UINT64 dst_offset, ID3D12Resource *src, UINT64 src_offset, UINT64 byte_count)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
struct d3d12_resource *dst_resource, *src_resource;
const struct vkd3d_vk_device_procs *vk_procs;
VkBufferCopy buffer_copy;
@ -3744,11 +3746,11 @@ static bool validate_d3d12_box(const D3D12_BOX *box)
&& box->back > box->front;
}
static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12GraphicsCommandList5 *iface,
const D3D12_TEXTURE_COPY_LOCATION *dst, UINT dst_x, UINT dst_y, UINT dst_z,
const D3D12_TEXTURE_COPY_LOCATION *src, const D3D12_BOX *src_box)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
struct d3d12_resource *dst_resource, *src_resource;
const struct vkd3d_format *src_format, *dst_format;
const struct vkd3d_vk_device_procs *vk_procs;
@ -3869,10 +3871,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12Graphic
}
}
static void STDMETHODCALLTYPE d3d12_command_list_CopyResource(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_CopyResource(ID3D12GraphicsCommandList5 *iface,
ID3D12Resource *dst, ID3D12Resource *src)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
struct d3d12_resource *dst_resource, *src_resource;
const struct vkd3d_format *dst_format, *src_format;
const struct vkd3d_vk_device_procs *vk_procs;
@ -3939,7 +3941,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyResource(ID3D12GraphicsComm
}
}
static void STDMETHODCALLTYPE d3d12_command_list_CopyTiles(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_CopyTiles(ID3D12GraphicsCommandList5 *iface,
ID3D12Resource *tiled_resource, const D3D12_TILED_RESOURCE_COORDINATE *tile_region_start_coordinate,
const D3D12_TILE_REGION_SIZE *tile_region_size, ID3D12Resource *buffer, UINT64 buffer_offset,
D3D12_TILE_COPY_FLAGS flags)
@ -3950,11 +3952,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyTiles(ID3D12GraphicsCommand
buffer, buffer_offset, flags);
}
static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresource(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresource(ID3D12GraphicsCommandList5 *iface,
ID3D12Resource *dst, UINT dst_sub_resource_idx,
ID3D12Resource *src, UINT src_sub_resource_idx, DXGI_FORMAT format)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
const struct vkd3d_format *src_format, *dst_format, *vk_format;
struct d3d12_resource *dst_resource, *src_resource;
const struct vkd3d_vk_device_procs *vk_procs;
@ -4017,10 +4019,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresource(ID3D12Graphi
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &vk_image_resolve));
}
static void STDMETHODCALLTYPE d3d12_command_list_IASetPrimitiveTopology(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_IASetPrimitiveTopology(ID3D12GraphicsCommandList5 *iface,
D3D12_PRIMITIVE_TOPOLOGY topology)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
TRACE("iface %p, topology %#x.\n", iface, topology);
@ -4031,11 +4033,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetPrimitiveTopology(ID3D12Gr
d3d12_command_list_invalidate_current_pipeline(list);
}
static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCommandList5 *iface,
UINT viewport_count, const D3D12_VIEWPORT *viewports)
{
VkViewport vk_viewports[D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
const struct vkd3d_vk_device_procs *vk_procs;
unsigned int i;
@ -4069,10 +4071,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCo
VK_CALL(vkCmdSetViewport(list->vk_command_buffer, 0, viewport_count, vk_viewports));
}
static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12GraphicsCommandList5 *iface,
UINT rect_count, const D3D12_RECT *rects)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
VkRect2D vk_rects[D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
const struct vkd3d_vk_device_procs *vk_procs;
unsigned int i;
@ -4097,10 +4099,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12Graphic
VK_CALL(vkCmdSetScissor(list->vk_command_buffer, 0, rect_count, vk_rects));
}
static void STDMETHODCALLTYPE d3d12_command_list_OMSetBlendFactor(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_OMSetBlendFactor(ID3D12GraphicsCommandList5 *iface,
const FLOAT blend_factor[4])
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
const struct vkd3d_vk_device_procs *vk_procs;
TRACE("iface %p, blend_factor %p.\n", iface, blend_factor);
@ -4109,10 +4111,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetBlendFactor(ID3D12Graphics
VK_CALL(vkCmdSetBlendConstants(list->vk_command_buffer, blend_factor));
}
static void STDMETHODCALLTYPE d3d12_command_list_OMSetStencilRef(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_OMSetStencilRef(ID3D12GraphicsCommandList5 *iface,
UINT stencil_ref)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
const struct vkd3d_vk_device_procs *vk_procs;
TRACE("iface %p, stencil_ref %u.\n", iface, stencil_ref);
@ -4121,11 +4123,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetStencilRef(ID3D12GraphicsC
VK_CALL(vkCmdSetStencilReference(list->vk_command_buffer, VK_STENCIL_FRONT_AND_BACK, stencil_ref));
}
static void STDMETHODCALLTYPE d3d12_command_list_SetPipelineState(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_SetPipelineState(ID3D12GraphicsCommandList5 *iface,
ID3D12PipelineState *pipeline_state)
{
struct d3d12_pipeline_state *state = unsafe_impl_from_ID3D12PipelineState(pipeline_state);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
TRACE("iface %p, pipeline_state %p.\n", iface, pipeline_state);
@ -4176,10 +4178,10 @@ static unsigned int d3d12_find_ds_multiplanar_transition(const D3D12_RESOURCE_BA
return 0;
}
static void STDMETHODCALLTYPE d3d12_command_list_ResourceBarrier(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_ResourceBarrier(ID3D12GraphicsCommandList5 *iface,
UINT barrier_count, const D3D12_RESOURCE_BARRIER *barriers)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
bool have_aliasing_barriers = false, have_split_barriers = false;
const struct vkd3d_vk_device_procs *vk_procs;
const struct vkd3d_vulkan_info *vk_info;
@ -4402,13 +4404,13 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResourceBarrier(ID3D12GraphicsC
WARN("Issuing split barrier(s) on D3D12_RESOURCE_BARRIER_FLAG_END_ONLY.\n");
}
static void STDMETHODCALLTYPE d3d12_command_list_ExecuteBundle(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_ExecuteBundle(ID3D12GraphicsCommandList5 *iface,
ID3D12GraphicsCommandList *command_list)
{
FIXME("iface %p, command_list %p stub!\n", iface, command_list);
}
static void STDMETHODCALLTYPE d3d12_command_list_SetDescriptorHeaps(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_SetDescriptorHeaps(ID3D12GraphicsCommandList5 *iface,
UINT heap_count, ID3D12DescriptorHeap *const *heaps)
{
TRACE("iface %p, heap_count %u, heaps %p.\n", iface, heap_count, heaps);
@ -4434,10 +4436,10 @@ static void d3d12_command_list_set_root_signature(struct d3d12_command_list *lis
d3d12_command_list_invalidate_root_parameters(list, bind_point);
}
static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootSignature(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootSignature(ID3D12GraphicsCommandList5 *iface,
ID3D12RootSignature *root_signature)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
TRACE("iface %p, root_signature %p.\n", iface, root_signature);
@ -4445,10 +4447,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootSignature(ID3D12G
unsafe_impl_from_ID3D12RootSignature(root_signature));
}
static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootSignature(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootSignature(ID3D12GraphicsCommandList5 *iface,
ID3D12RootSignature *root_signature)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
TRACE("iface %p, root_signature %p.\n", iface, root_signature);
@ -4487,10 +4489,10 @@ static void d3d12_command_list_set_descriptor_table(struct d3d12_command_list *l
bindings->descriptor_table_active_mask |= (uint64_t)1 << index;
}
static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootDescriptorTable(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootDescriptorTable(ID3D12GraphicsCommandList5 *iface,
UINT root_parameter_index, D3D12_GPU_DESCRIPTOR_HANDLE base_descriptor)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
TRACE("iface %p, root_parameter_index %u, base_descriptor %#"PRIx64".\n",
iface, root_parameter_index, base_descriptor.ptr);
@ -4499,10 +4501,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootDescriptorTable(I
root_parameter_index, base_descriptor);
}
static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootDescriptorTable(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootDescriptorTable(ID3D12GraphicsCommandList5 *iface,
UINT root_parameter_index, D3D12_GPU_DESCRIPTOR_HANDLE base_descriptor)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
TRACE("iface %p, root_parameter_index %u, base_descriptor %#"PRIx64".\n",
iface, root_parameter_index, base_descriptor.ptr);
@ -4524,10 +4526,10 @@ static void d3d12_command_list_set_root_constants(struct d3d12_command_list *lis
c->stage_flags, c->offset + offset * sizeof(uint32_t), count * sizeof(uint32_t), data));
}
static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstant(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstant(ID3D12GraphicsCommandList5 *iface,
UINT root_parameter_index, UINT data, UINT dst_offset)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
TRACE("iface %p, root_parameter_index %u, data 0x%08x, dst_offset %u.\n",
iface, root_parameter_index, data, dst_offset);
@ -4536,10 +4538,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstant(ID3
root_parameter_index, dst_offset, 1, &data);
}
static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstant(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstant(ID3D12GraphicsCommandList5 *iface,
UINT root_parameter_index, UINT data, UINT dst_offset)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
TRACE("iface %p, root_parameter_index %u, data 0x%08x, dst_offset %u.\n",
iface, root_parameter_index, data, dst_offset);
@ -4548,10 +4550,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstant(ID
root_parameter_index, dst_offset, 1, &data);
}
static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstants(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstants(ID3D12GraphicsCommandList5 *iface,
UINT root_parameter_index, UINT constant_count, const void *data, UINT dst_offset)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
TRACE("iface %p, root_parameter_index %u, constant_count %u, data %p, dst_offset %u.\n",
iface, root_parameter_index, constant_count, data, dst_offset);
@ -4560,10 +4562,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstants(ID
root_parameter_index, dst_offset, constant_count, data);
}
static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstants(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstants(ID3D12GraphicsCommandList5 *iface,
UINT root_parameter_index, UINT constant_count, const void *data, UINT dst_offset)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
TRACE("iface %p, root_parameter_index %u, constant_count %u, data %p, dst_offset %u.\n",
iface, root_parameter_index, constant_count, data, dst_offset);
@ -4625,9 +4627,9 @@ static void d3d12_command_list_set_root_cbv(struct d3d12_command_list *list,
}
static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootConstantBufferView(
ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address)
ID3D12GraphicsCommandList5 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n",
iface, root_parameter_index, address);
@ -4636,9 +4638,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootConstantBufferVie
}
static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootConstantBufferView(
ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address)
ID3D12GraphicsCommandList5 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n",
iface, root_parameter_index, address);
@ -4697,9 +4699,9 @@ static void d3d12_command_list_set_root_descriptor(struct d3d12_command_list *li
}
static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootShaderResourceView(
ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address)
ID3D12GraphicsCommandList5 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n",
iface, root_parameter_index, address);
@ -4709,9 +4711,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootShaderResourceVie
}
static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootShaderResourceView(
ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address)
ID3D12GraphicsCommandList5 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n",
iface, root_parameter_index, address);
@ -4721,9 +4723,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootShaderResourceVi
}
static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootUnorderedAccessView(
ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address)
ID3D12GraphicsCommandList5 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n",
iface, root_parameter_index, address);
@ -4733,9 +4735,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootUnorderedAccessVi
}
static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootUnorderedAccessView(
ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address)
ID3D12GraphicsCommandList5 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n",
iface, root_parameter_index, address);
@ -4744,10 +4746,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootUnorderedAccessV
root_parameter_index, address);
}
static void STDMETHODCALLTYPE d3d12_command_list_IASetIndexBuffer(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_IASetIndexBuffer(ID3D12GraphicsCommandList5 *iface,
const D3D12_INDEX_BUFFER_VIEW *view)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
const struct vkd3d_vk_device_procs *vk_procs;
struct d3d12_resource *resource;
enum VkIndexType index_type;
@ -4787,10 +4789,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetIndexBuffer(ID3D12Graphics
view->BufferLocation - resource->gpu_address, index_type));
}
static void STDMETHODCALLTYPE d3d12_command_list_IASetVertexBuffers(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_IASetVertexBuffers(ID3D12GraphicsCommandList5 *iface,
UINT start_slot, UINT view_count, const D3D12_VERTEX_BUFFER_VIEW *views)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
const struct vkd3d_null_resources *null_resources;
struct vkd3d_gpu_va_allocator *gpu_va_allocator;
VkDeviceSize offsets[ARRAY_SIZE(list->strides)];
@ -4845,10 +4847,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetVertexBuffers(ID3D12Graphi
d3d12_command_list_invalidate_current_pipeline(list);
}
static void STDMETHODCALLTYPE d3d12_command_list_SOSetTargets(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_SOSetTargets(ID3D12GraphicsCommandList5 *iface,
UINT start_slot, UINT view_count, const D3D12_STREAM_OUTPUT_BUFFER_VIEW *views)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
VkDeviceSize offsets[ARRAY_SIZE(list->so_counter_buffers)];
VkDeviceSize sizes[ARRAY_SIZE(list->so_counter_buffers)];
VkBuffer buffers[ARRAY_SIZE(list->so_counter_buffers)];
@ -4910,11 +4912,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_SOSetTargets(ID3D12GraphicsComm
VK_CALL(vkCmdBindTransformFeedbackBuffersEXT(list->vk_command_buffer, first, count, buffers, offsets, sizes));
}
static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12GraphicsCommandList5 *iface,
UINT render_target_descriptor_count, const D3D12_CPU_DESCRIPTOR_HANDLE *render_target_descriptors,
BOOL single_descriptor_handle, const D3D12_CPU_DESCRIPTOR_HANDLE *depth_stencil_descriptor)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
const struct d3d12_rtv_desc *rtv_desc;
const struct d3d12_dsv_desc *dsv_desc;
VkFormat prev_dsv_format;
@ -5115,12 +5117,12 @@ static void d3d12_command_list_clear(struct d3d12_command_list *list,
}
}
static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12GraphicsCommandList5 *iface,
D3D12_CPU_DESCRIPTOR_HANDLE dsv, D3D12_CLEAR_FLAGS flags, float depth, UINT8 stencil,
UINT rect_count, const D3D12_RECT *rects)
{
const union VkClearValue clear_value = {.depthStencil = {depth, stencil}};
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
const struct d3d12_dsv_desc *dsv_desc = d3d12_dsv_desc_from_cpu_handle(dsv);
struct VkAttachmentDescription attachment_desc;
struct VkAttachmentReference ds_reference;
@ -5164,10 +5166,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12Gra
&clear_value, rect_count, rects);
}
static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12GraphicsCommandList5 *iface,
D3D12_CPU_DESCRIPTOR_HANDLE rtv, const FLOAT color[4], UINT rect_count, const D3D12_RECT *rects)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
const struct d3d12_rtv_desc *rtv_desc = d3d12_rtv_desc_from_cpu_handle(rtv);
struct VkAttachmentDescription attachment_desc;
struct VkAttachmentReference color_reference;
@ -5412,11 +5414,11 @@ static const struct vkd3d_format *vkd3d_fixup_clear_uav_uint_colour(struct d3d12
}
}
static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID3D12GraphicsCommandList5 *iface,
D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle, D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle, ID3D12Resource *resource,
const UINT values[4], UINT rect_count, const D3D12_RECT *rects)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
struct vkd3d_view *descriptor, *uint_view = NULL;
struct d3d12_device *device = list->device;
struct vkd3d_texture_view_desc view_desc;
@ -5461,6 +5463,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID
view_desc.miplevel_count = 1;
view_desc.layer_idx = view->info.texture.layer_idx;
view_desc.layer_count = view->info.texture.layer_count;
view_desc.vk_image_aspect = VK_IMAGE_ASPECT_COLOR_BIT;
view_desc.usage = VK_IMAGE_USAGE_STORAGE_BIT;
if (!vkd3d_create_texture_view(device, VKD3D_DESCRIPTOR_MAGIC_UAV, resource_impl->u.vk_image, &view_desc,
&uint_view))
@ -5478,11 +5482,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID
vkd3d_view_decref(uint_view, device);
}
static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(ID3D12GraphicsCommandList5 *iface,
D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle, D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle, ID3D12Resource *resource,
const float values[4], UINT rect_count, const D3D12_RECT *rects)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
struct d3d12_resource *resource_impl;
VkClearColorValue colour;
struct vkd3d_view *view;
@ -5498,16 +5502,16 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(I
d3d12_command_list_clear_uav(list, resource_impl, view, &colour, rect_count, rects);
}
static void STDMETHODCALLTYPE d3d12_command_list_DiscardResource(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_DiscardResource(ID3D12GraphicsCommandList5 *iface,
ID3D12Resource *resource, const D3D12_DISCARD_REGION *region)
{
FIXME_ONCE("iface %p, resource %p, region %p stub!\n", iface, resource, region);
}
static void STDMETHODCALLTYPE d3d12_command_list_BeginQuery(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_BeginQuery(ID3D12GraphicsCommandList5 *iface,
ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, UINT index)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
struct d3d12_query_heap *query_heap = unsafe_impl_from_ID3D12QueryHeap(heap);
const struct vkd3d_vk_device_procs *vk_procs;
VkQueryControlFlags flags = 0;
@ -5534,10 +5538,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_BeginQuery(ID3D12GraphicsComman
VK_CALL(vkCmdBeginQuery(list->vk_command_buffer, query_heap->vk_query_pool, index, flags));
}
static void STDMETHODCALLTYPE d3d12_command_list_EndQuery(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_EndQuery(ID3D12GraphicsCommandList5 *iface,
ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, UINT index)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
struct d3d12_query_heap *query_heap = unsafe_impl_from_ID3D12QueryHeap(heap);
const struct vkd3d_vk_device_procs *vk_procs;
@ -5579,12 +5583,12 @@ static size_t get_query_stride(D3D12_QUERY_TYPE type)
return sizeof(uint64_t);
}
static void STDMETHODCALLTYPE d3d12_command_list_ResolveQueryData(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_ResolveQueryData(ID3D12GraphicsCommandList5 *iface,
ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, UINT start_index, UINT query_count,
ID3D12Resource *dst_buffer, UINT64 aligned_dst_buffer_offset)
{
const struct d3d12_query_heap *query_heap = unsafe_impl_from_ID3D12QueryHeap(heap);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
struct d3d12_resource *buffer = unsafe_impl_from_ID3D12Resource(dst_buffer);
const struct vkd3d_vk_device_procs *vk_procs;
unsigned int i, first, count;
@ -5660,10 +5664,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveQueryData(ID3D12Graphics
}
}
static void STDMETHODCALLTYPE d3d12_command_list_SetPredication(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_SetPredication(ID3D12GraphicsCommandList5 *iface,
ID3D12Resource *buffer, UINT64 aligned_buffer_offset, D3D12_PREDICATION_OP operation)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
struct d3d12_resource *resource = unsafe_impl_from_ID3D12Resource(buffer);
const struct vkd3d_vulkan_info *vk_info = &list->device->vk_info;
const struct vkd3d_vk_device_procs *vk_procs;
@ -5732,19 +5736,19 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetPredication(ID3D12GraphicsCo
}
}
static void STDMETHODCALLTYPE d3d12_command_list_SetMarker(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_SetMarker(ID3D12GraphicsCommandList5 *iface,
UINT metadata, const void *data, UINT size)
{
FIXME("iface %p, metadata %#x, data %p, size %u stub!\n", iface, metadata, data, size);
}
static void STDMETHODCALLTYPE d3d12_command_list_BeginEvent(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_BeginEvent(ID3D12GraphicsCommandList5 *iface,
UINT metadata, const void *data, UINT size)
{
FIXME("iface %p, metadata %#x, data %p, size %u stub!\n", iface, metadata, data, size);
}
static void STDMETHODCALLTYPE d3d12_command_list_EndEvent(ID3D12GraphicsCommandList3 *iface)
static void STDMETHODCALLTYPE d3d12_command_list_EndEvent(ID3D12GraphicsCommandList5 *iface)
{
FIXME("iface %p stub!\n", iface);
}
@ -5753,14 +5757,14 @@ STATIC_ASSERT(sizeof(VkDispatchIndirectCommand) == sizeof(D3D12_DISPATCH_ARGUMEN
STATIC_ASSERT(sizeof(VkDrawIndexedIndirectCommand) == sizeof(D3D12_DRAW_INDEXED_ARGUMENTS));
STATIC_ASSERT(sizeof(VkDrawIndirectCommand) == sizeof(D3D12_DRAW_ARGUMENTS));
static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsCommandList5 *iface,
ID3D12CommandSignature *command_signature, UINT max_command_count, ID3D12Resource *arg_buffer,
UINT64 arg_buffer_offset, ID3D12Resource *count_buffer, UINT64 count_buffer_offset)
{
struct d3d12_command_signature *sig_impl = unsafe_impl_from_ID3D12CommandSignature(command_signature);
struct d3d12_resource *count_impl = unsafe_impl_from_ID3D12Resource(count_buffer);
struct d3d12_resource *arg_impl = unsafe_impl_from_ID3D12Resource(arg_buffer);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
const D3D12_COMMAND_SIGNATURE_DESC *signature_desc;
const struct vkd3d_vk_device_procs *vk_procs;
unsigned int i;
@ -5859,7 +5863,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsC
d3d12_command_signature_decref(sig_impl);
}
static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT(ID3D12GraphicsCommandList5 *iface,
ID3D12Resource *dst_buffer, UINT64 dst_offset,
ID3D12Resource *src_buffer, UINT64 src_offset,
UINT dependent_resource_count, ID3D12Resource * const *dependent_resources,
@ -5872,7 +5876,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT(ID3D12Grap
dependent_resource_count, dependent_resources, dependent_sub_resource_ranges);
}
static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT64(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT64(ID3D12GraphicsCommandList5 *iface,
ID3D12Resource *dst_buffer, UINT64 dst_offset,
ID3D12Resource *src_buffer, UINT64 src_offset,
UINT dependent_resource_count, ID3D12Resource * const *dependent_resources,
@ -5885,20 +5889,20 @@ static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT64(ID3D12Gr
dependent_resource_count, dependent_resources, dependent_sub_resource_ranges);
}
static void STDMETHODCALLTYPE d3d12_command_list_OMSetDepthBounds(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_OMSetDepthBounds(ID3D12GraphicsCommandList5 *iface,
FLOAT min, FLOAT max)
{
FIXME("iface %p, min %.8e, max %.8e stub!\n", iface, min, max);
}
static void STDMETHODCALLTYPE d3d12_command_list_SetSamplePositions(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_SetSamplePositions(ID3D12GraphicsCommandList5 *iface,
UINT sample_count, UINT pixel_count, D3D12_SAMPLE_POSITION *sample_positions)
{
FIXME("iface %p, sample_count %u, pixel_count %u, sample_positions %p stub!\n",
iface, sample_count, pixel_count, sample_positions);
}
static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresourceRegion(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresourceRegion(ID3D12GraphicsCommandList5 *iface,
ID3D12Resource *dst_resource, UINT dst_sub_resource_idx, UINT dst_x, UINT dst_y,
ID3D12Resource *src_resource, UINT src_sub_resource_idx,
D3D12_RECT *src_rect, DXGI_FORMAT format, D3D12_RESOLVE_MODE mode)
@ -5910,16 +5914,16 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresourceRegion(ID3D12
src_resource, src_sub_resource_idx, src_rect, format, mode);
}
static void STDMETHODCALLTYPE d3d12_command_list_SetViewInstanceMask(ID3D12GraphicsCommandList3 *iface, UINT mask)
static void STDMETHODCALLTYPE d3d12_command_list_SetViewInstanceMask(ID3D12GraphicsCommandList5 *iface, UINT mask)
{
FIXME("iface %p, mask %#x stub!\n", iface, mask);
}
static void STDMETHODCALLTYPE d3d12_command_list_WriteBufferImmediate(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_WriteBufferImmediate(ID3D12GraphicsCommandList5 *iface,
UINT count, const D3D12_WRITEBUFFERIMMEDIATE_PARAMETER *parameters,
const D3D12_WRITEBUFFERIMMEDIATE_MODE *modes)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
struct d3d12_resource *resource;
unsigned int i;
@ -5932,13 +5936,88 @@ static void STDMETHODCALLTYPE d3d12_command_list_WriteBufferImmediate(ID3D12Grap
}
}
static void STDMETHODCALLTYPE d3d12_command_list_SetProtectedResourceSession(ID3D12GraphicsCommandList3 *iface,
static void STDMETHODCALLTYPE d3d12_command_list_SetProtectedResourceSession(ID3D12GraphicsCommandList5 *iface,
ID3D12ProtectedResourceSession *protected_session)
{
FIXME("iface %p, protected_session %p stub!\n", iface, protected_session);
}
static const struct ID3D12GraphicsCommandList3Vtbl d3d12_command_list_vtbl =
static void STDMETHODCALLTYPE d3d12_command_list_BeginRenderPass(ID3D12GraphicsCommandList5 *iface,
UINT count, const D3D12_RENDER_PASS_RENDER_TARGET_DESC *render_targets,
const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC *depth_stencil, D3D12_RENDER_PASS_FLAGS flags)
{
FIXME("iface %p, count %u, render_targets %p, depth_stencil %p, flags %#x stub!\n", iface,
count, render_targets, depth_stencil, flags);
}
static void STDMETHODCALLTYPE d3d12_command_list_EndRenderPass(ID3D12GraphicsCommandList5 *iface)
{
FIXME("iface %p stub!\n", iface);
}
static void STDMETHODCALLTYPE d3d12_command_list_InitializeMetaCommand(ID3D12GraphicsCommandList5 *iface,
ID3D12MetaCommand *meta_command, const void *parameters_data, SIZE_T data_size_in_bytes)
{
FIXME("iface %p, meta_command %p, parameters_data %p, data_size_in_bytes %lu stub!\n", iface,
meta_command, parameters_data, data_size_in_bytes);
}
static void STDMETHODCALLTYPE d3d12_command_list_ExecuteMetaCommand(ID3D12GraphicsCommandList5 *iface,
ID3D12MetaCommand *meta_command, const void *parameters_data, SIZE_T data_size_in_bytes)
{
FIXME("iface %p, meta_command %p, parameters_data %p, data_size_in_bytes %lu stub!\n", iface,
meta_command, parameters_data, data_size_in_bytes);
}
static void STDMETHODCALLTYPE d3d12_command_list_BuildRaytracingAccelerationStructure(ID3D12GraphicsCommandList5 *iface,
const D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC *desc, UINT count,
const D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC *postbuild_info_descs)
{
FIXME("iface %p, desc %p, count %u, postbuild_info_descs %p stub!\n", iface, desc, count, postbuild_info_descs);
}
static void STDMETHODCALLTYPE d3d12_command_list_EmitRaytracingAccelerationStructurePostbuildInfo(ID3D12GraphicsCommandList5 *iface,
const D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC *desc,
UINT structures_count, const D3D12_GPU_VIRTUAL_ADDRESS *src_structure_data)
{
FIXME("iface %p, desc %p, structures_count %u, src_structure_data %p stub!\n",
iface, desc, structures_count, src_structure_data);
}
static void STDMETHODCALLTYPE d3d12_command_list_CopyRaytracingAccelerationStructure(ID3D12GraphicsCommandList5 *iface,
D3D12_GPU_VIRTUAL_ADDRESS dst_structure_data,
D3D12_GPU_VIRTUAL_ADDRESS src_structure_data,
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE mode)
{
FIXME("iface %p, dst_structure_data %#"PRIx64", src_structure_data %#"PRIx64", mode %u stub!\n",
iface, dst_structure_data, src_structure_data, mode);
}
static void STDMETHODCALLTYPE d3d12_command_list_SetPipelineState1(ID3D12GraphicsCommandList5 *iface,
ID3D12StateObject *state_object)
{
FIXME("iface %p, state_object %p stub!\n", iface, state_object);
}
static void STDMETHODCALLTYPE d3d12_command_list_DispatchRays(ID3D12GraphicsCommandList5 *iface,
const D3D12_DISPATCH_RAYS_DESC *desc)
{
FIXME("iface %p, desc %p stub!\n", iface, desc);
}
static void STDMETHODCALLTYPE d3d12_command_list_RSSetShadingRate(ID3D12GraphicsCommandList5 *iface,
D3D12_SHADING_RATE rate, const D3D12_SHADING_RATE_COMBINER *combiners)
{
FIXME("iface %p, rate %#x, combiners %p stub!\n", iface, rate, combiners);
}
static void STDMETHODCALLTYPE d3d12_command_list_RSSetShadingRateImage(ID3D12GraphicsCommandList5 *iface,
ID3D12Resource *rate_image)
{
FIXME("iface %p, rate_image %p stub!\n", iface, rate_image);
}
static const struct ID3D12GraphicsCommandList5Vtbl d3d12_command_list_vtbl =
{
/* IUnknown methods */
d3d12_command_list_QueryInterface,
@ -6016,6 +6095,19 @@ static const struct ID3D12GraphicsCommandList3Vtbl d3d12_command_list_vtbl =
d3d12_command_list_WriteBufferImmediate,
/* ID3D12GraphicsCommandList3 methods */
d3d12_command_list_SetProtectedResourceSession,
/* ID3D12GraphicsCommandList4 methods */
d3d12_command_list_BeginRenderPass,
d3d12_command_list_EndRenderPass,
d3d12_command_list_InitializeMetaCommand,
d3d12_command_list_ExecuteMetaCommand,
d3d12_command_list_BuildRaytracingAccelerationStructure,
d3d12_command_list_EmitRaytracingAccelerationStructurePostbuildInfo,
d3d12_command_list_CopyRaytracingAccelerationStructure,
d3d12_command_list_SetPipelineState1,
d3d12_command_list_DispatchRays,
/* ID3D12GraphicsCommandList5 methods */
d3d12_command_list_RSSetShadingRate,
d3d12_command_list_RSSetShadingRateImage,
};
static struct d3d12_command_list *unsafe_impl_from_ID3D12CommandList(ID3D12CommandList *iface)
@ -6023,7 +6115,7 @@ static struct d3d12_command_list *unsafe_impl_from_ID3D12CommandList(ID3D12Comma
if (!iface)
return NULL;
assert(iface->lpVtbl == (struct ID3D12CommandListVtbl *)&d3d12_command_list_vtbl);
return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandList3_iface);
return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandList5_iface);
}
static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, struct d3d12_device *device,
@ -6032,7 +6124,7 @@ static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, struct d
{
HRESULT hr;
list->ID3D12GraphicsCommandList3_iface.lpVtbl = &d3d12_command_list_vtbl;
list->ID3D12GraphicsCommandList5_iface.lpVtbl = &d3d12_command_list_vtbl;
list->refcount = 1;
list->type = type;
@ -6760,7 +6852,7 @@ fail:
static HRESULT d3d12_command_queue_wait_binary_semaphore_locked(struct d3d12_command_queue *command_queue,
struct d3d12_fence *fence, uint64_t value)
{
static const VkPipelineStageFlagBits wait_stage_mask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
static const VkPipelineStageFlags wait_stage_mask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
const struct vkd3d_vk_device_procs *vk_procs;
struct vkd3d_signaled_semaphore *semaphore;
uint64_t completed_value = 0;
@ -6856,7 +6948,7 @@ fail:
static HRESULT d3d12_command_queue_wait_locked(struct d3d12_command_queue *command_queue,
struct d3d12_fence *fence, uint64_t value)
{
static const VkPipelineStageFlagBits wait_stage_mask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
static const VkPipelineStageFlags wait_stage_mask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
VkTimelineSemaphoreSubmitInfoKHR timeline_submit_info;
const struct vkd3d_vk_device_procs *vk_procs;
struct vkd3d_queue *queue;

View file

@ -83,6 +83,7 @@ static const struct vkd3d_optional_extension_info optional_device_extensions[] =
VK_EXTENSION(KHR_DRAW_INDIRECT_COUNT, KHR_draw_indirect_count),
VK_EXTENSION(KHR_GET_MEMORY_REQUIREMENTS_2, KHR_get_memory_requirements2),
VK_EXTENSION(KHR_IMAGE_FORMAT_LIST, KHR_image_format_list),
VK_EXTENSION(KHR_MAINTENANCE2, KHR_maintenance2),
VK_EXTENSION(KHR_MAINTENANCE3, KHR_maintenance3),
VK_EXTENSION(KHR_PUSH_DESCRIPTOR, KHR_push_descriptor),
VK_EXTENSION(KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE, KHR_sampler_mirror_clamp_to_edge),
@ -1521,9 +1522,7 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
device->feature_options1.ExpandedComputeResourceStates = TRUE;
device->feature_options1.Int64ShaderOps = features->shaderInt64;
/* Depth bounds test is enabled in D3D12_DEPTH_STENCIL_DESC1, which is not
* supported. */
device->feature_options2.DepthBoundsTestSupported = FALSE;
device->feature_options2.DepthBoundsTestSupported = features->depthBounds;
/* d3d12_command_list_SetSamplePositions() is not implemented. */
device->feature_options2.ProgrammableSamplePositionsTier = D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_NOT_SUPPORTED;
@ -2456,17 +2455,21 @@ static void vkd3d_desc_object_cache_cleanup(struct vkd3d_desc_object_cache *cach
}
/* ID3D12Device */
static inline struct d3d12_device *impl_from_ID3D12Device1(ID3D12Device1 *iface)
static inline struct d3d12_device *impl_from_ID3D12Device5(ID3D12Device5 *iface)
{
return CONTAINING_RECORD(iface, struct d3d12_device, ID3D12Device1_iface);
return CONTAINING_RECORD(iface, struct d3d12_device, ID3D12Device5_iface);
}
static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(ID3D12Device1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(ID3D12Device5 *iface,
REFIID riid, void **object)
{
TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
if (IsEqualGUID(riid, &IID_ID3D12Device1)
if (IsEqualGUID(riid, &IID_ID3D12Device5)
|| IsEqualGUID(riid, &IID_ID3D12Device4)
|| IsEqualGUID(riid, &IID_ID3D12Device3)
|| IsEqualGUID(riid, &IID_ID3D12Device2)
|| IsEqualGUID(riid, &IID_ID3D12Device1)
|| IsEqualGUID(riid, &IID_ID3D12Device)
|| IsEqualGUID(riid, &IID_ID3D12Object)
|| IsEqualGUID(riid, &IID_IUnknown))
@ -2482,9 +2485,9 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(ID3D12Device1 *ifac
return E_NOINTERFACE;
}
static ULONG STDMETHODCALLTYPE d3d12_device_AddRef(ID3D12Device1 *iface)
static ULONG STDMETHODCALLTYPE d3d12_device_AddRef(ID3D12Device5 *iface)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
ULONG refcount = InterlockedIncrement(&device->refcount);
TRACE("%p increasing refcount to %u.\n", device, refcount);
@ -2492,9 +2495,9 @@ static ULONG STDMETHODCALLTYPE d3d12_device_AddRef(ID3D12Device1 *iface)
return refcount;
}
static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device1 *iface)
static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device5 *iface)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
ULONG refcount = InterlockedDecrement(&device->refcount);
TRACE("%p decreasing refcount to %u.\n", device, refcount);
@ -2528,10 +2531,10 @@ static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device1 *iface)
return refcount;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_GetPrivateData(ID3D12Device1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_device_GetPrivateData(ID3D12Device5 *iface,
REFGUID guid, UINT *data_size, void *data)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
TRACE("iface %p, guid %s, data_size %p, data %p.\n",
iface, debugstr_guid(guid), data_size, data);
@ -2539,10 +2542,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_GetPrivateData(ID3D12Device1 *ifac
return vkd3d_get_private_data(&device->private_store, guid, data_size, data);
}
static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateData(ID3D12Device1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateData(ID3D12Device5 *iface,
REFGUID guid, UINT data_size, const void *data)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
TRACE("iface %p, guid %s, data_size %u, data %p.\n",
iface, debugstr_guid(guid), data_size, data);
@ -2550,19 +2553,19 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateData(ID3D12Device1 *ifac
return vkd3d_set_private_data(&device->private_store, guid, data_size, data);
}
static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateDataInterface(ID3D12Device1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateDataInterface(ID3D12Device5 *iface,
REFGUID guid, const IUnknown *data)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
return vkd3d_set_private_data_interface(&device->private_store, guid, data);
}
static HRESULT STDMETHODCALLTYPE d3d12_device_SetName(ID3D12Device1 *iface, const WCHAR *name)
static HRESULT STDMETHODCALLTYPE d3d12_device_SetName(ID3D12Device5 *iface, const WCHAR *name)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
TRACE("iface %p, name %s.\n", iface, debugstr_w(name, device->wchar_size));
@ -2570,17 +2573,17 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetName(ID3D12Device1 *iface, cons
VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, name);
}
static UINT STDMETHODCALLTYPE d3d12_device_GetNodeCount(ID3D12Device1 *iface)
static UINT STDMETHODCALLTYPE d3d12_device_GetNodeCount(ID3D12Device5 *iface)
{
TRACE("iface %p.\n", iface);
return 1;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandQueue(ID3D12Device1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandQueue(ID3D12Device5 *iface,
const D3D12_COMMAND_QUEUE_DESC *desc, REFIID riid, void **command_queue)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
struct d3d12_command_queue *object;
HRESULT hr;
@ -2594,10 +2597,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandQueue(ID3D12Device1 *
riid, command_queue);
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandAllocator(ID3D12Device1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandAllocator(ID3D12Device5 *iface,
D3D12_COMMAND_LIST_TYPE type, REFIID riid, void **command_allocator)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
struct d3d12_command_allocator *object;
HRESULT hr;
@ -2611,10 +2614,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandAllocator(ID3D12Devic
riid, command_allocator);
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateGraphicsPipelineState(ID3D12Device1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateGraphicsPipelineState(ID3D12Device5 *iface,
const D3D12_GRAPHICS_PIPELINE_STATE_DESC *desc, REFIID riid, void **pipeline_state)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
struct d3d12_pipeline_state *object;
HRESULT hr;
@ -2628,10 +2631,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateGraphicsPipelineState(ID3D12
&IID_ID3D12PipelineState, riid, pipeline_state);
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateComputePipelineState(ID3D12Device1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateComputePipelineState(ID3D12Device5 *iface,
const D3D12_COMPUTE_PIPELINE_STATE_DESC *desc, REFIID riid, void **pipeline_state)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
struct d3d12_pipeline_state *object;
HRESULT hr;
@ -2645,11 +2648,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateComputePipelineState(ID3D12D
&IID_ID3D12PipelineState, riid, pipeline_state);
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList(ID3D12Device1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList(ID3D12Device5 *iface,
UINT node_mask, D3D12_COMMAND_LIST_TYPE type, ID3D12CommandAllocator *command_allocator,
ID3D12PipelineState *initial_pipeline_state, REFIID riid, void **command_list)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
struct d3d12_command_list *object;
HRESULT hr;
@ -2662,8 +2665,8 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList(ID3D12Device1 *i
initial_pipeline_state, &object)))
return hr;
return return_interface(&object->ID3D12GraphicsCommandList3_iface,
&IID_ID3D12GraphicsCommandList3, riid, command_list);
return return_interface(&object->ID3D12GraphicsCommandList5_iface,
&IID_ID3D12GraphicsCommandList5, riid, command_list);
}
/* Direct3D feature levels restrict which formats can be optionally supported. */
@ -2772,10 +2775,10 @@ bool d3d12_device_is_uma(struct d3d12_device *device, bool *coherent)
return true;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device5 *iface,
D3D12_FEATURE feature, void *feature_data, UINT feature_data_size)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
TRACE("iface %p, feature %#x, feature_data %p, feature_data_size %u.\n",
iface, feature, feature_data, feature_data_size);
@ -2925,7 +2928,14 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device1
if (image_features & VK_FORMAT_FEATURE_BLIT_SRC_BIT)
data->Support1 |= D3D12_FORMAT_SUPPORT1_MULTISAMPLE_RESOLVE;
if (image_features & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)
{
data->Support1 |= D3D12_FORMAT_SUPPORT1_TYPED_UNORDERED_ACCESS_VIEW;
if (device->vk_info.uav_read_without_format)
data->Support2 |= D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD;
/* We effectively require shaderStorageImageWriteWithoutFormat,
* so we can just report UAV_TYPED_STORE unconditionally. */
data->Support2 |= D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE;
}
if (image_features & VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT)
data->Support2 |= D3D12_FORMAT_SUPPORT2_UAV_ATOMIC_ADD
@ -3274,10 +3284,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device1
}
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateDescriptorHeap(ID3D12Device1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateDescriptorHeap(ID3D12Device5 *iface,
const D3D12_DESCRIPTOR_HEAP_DESC *desc, REFIID riid, void **descriptor_heap)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
struct d3d12_descriptor_heap *object;
HRESULT hr;
@ -3291,7 +3301,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateDescriptorHeap(ID3D12Device1
&IID_ID3D12DescriptorHeap, riid, descriptor_heap);
}
static UINT STDMETHODCALLTYPE d3d12_device_GetDescriptorHandleIncrementSize(ID3D12Device1 *iface,
static UINT STDMETHODCALLTYPE d3d12_device_GetDescriptorHandleIncrementSize(ID3D12Device5 *iface,
D3D12_DESCRIPTOR_HEAP_TYPE descriptor_heap_type)
{
TRACE("iface %p, descriptor_heap_type %#x.\n", iface, descriptor_heap_type);
@ -3314,11 +3324,11 @@ static UINT STDMETHODCALLTYPE d3d12_device_GetDescriptorHandleIncrementSize(ID3D
}
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateRootSignature(ID3D12Device1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateRootSignature(ID3D12Device5 *iface,
UINT node_mask, const void *bytecode, SIZE_T bytecode_length,
REFIID riid, void **root_signature)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
struct d3d12_root_signature *object;
HRESULT hr;
@ -3334,10 +3344,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateRootSignature(ID3D12Device1
&IID_ID3D12RootSignature, riid, root_signature);
}
static void STDMETHODCALLTYPE d3d12_device_CreateConstantBufferView(ID3D12Device1 *iface,
static void STDMETHODCALLTYPE d3d12_device_CreateConstantBufferView(ID3D12Device5 *iface,
const D3D12_CONSTANT_BUFFER_VIEW_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
struct d3d12_desc tmp = {0};
TRACE("iface %p, desc %p, descriptor %#lx.\n", iface, desc, descriptor.ptr);
@ -3346,11 +3356,11 @@ static void STDMETHODCALLTYPE d3d12_device_CreateConstantBufferView(ID3D12Device
d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device);
}
static void STDMETHODCALLTYPE d3d12_device_CreateShaderResourceView(ID3D12Device1 *iface,
static void STDMETHODCALLTYPE d3d12_device_CreateShaderResourceView(ID3D12Device5 *iface,
ID3D12Resource *resource, const D3D12_SHADER_RESOURCE_VIEW_DESC *desc,
D3D12_CPU_DESCRIPTOR_HANDLE descriptor)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
struct d3d12_desc tmp = {0};
TRACE("iface %p, resource %p, desc %p, descriptor %#lx.\n",
@ -3360,11 +3370,11 @@ static void STDMETHODCALLTYPE d3d12_device_CreateShaderResourceView(ID3D12Device
d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device);
}
static void STDMETHODCALLTYPE d3d12_device_CreateUnorderedAccessView(ID3D12Device1 *iface,
static void STDMETHODCALLTYPE d3d12_device_CreateUnorderedAccessView(ID3D12Device5 *iface,
ID3D12Resource *resource, ID3D12Resource *counter_resource,
const D3D12_UNORDERED_ACCESS_VIEW_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
struct d3d12_desc tmp = {0};
TRACE("iface %p, resource %p, counter_resource %p, desc %p, descriptor %#lx.\n",
@ -3375,7 +3385,7 @@ static void STDMETHODCALLTYPE d3d12_device_CreateUnorderedAccessView(ID3D12Devic
d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device);
}
static void STDMETHODCALLTYPE d3d12_device_CreateRenderTargetView(ID3D12Device1 *iface,
static void STDMETHODCALLTYPE d3d12_device_CreateRenderTargetView(ID3D12Device5 *iface,
ID3D12Resource *resource, const D3D12_RENDER_TARGET_VIEW_DESC *desc,
D3D12_CPU_DESCRIPTOR_HANDLE descriptor)
{
@ -3383,10 +3393,10 @@ static void STDMETHODCALLTYPE d3d12_device_CreateRenderTargetView(ID3D12Device1
iface, resource, desc, descriptor.ptr);
d3d12_rtv_desc_create_rtv(d3d12_rtv_desc_from_cpu_handle(descriptor),
impl_from_ID3D12Device1(iface), unsafe_impl_from_ID3D12Resource(resource), desc);
impl_from_ID3D12Device5(iface), unsafe_impl_from_ID3D12Resource(resource), desc);
}
static void STDMETHODCALLTYPE d3d12_device_CreateDepthStencilView(ID3D12Device1 *iface,
static void STDMETHODCALLTYPE d3d12_device_CreateDepthStencilView(ID3D12Device5 *iface,
ID3D12Resource *resource, const D3D12_DEPTH_STENCIL_VIEW_DESC *desc,
D3D12_CPU_DESCRIPTOR_HANDLE descriptor)
{
@ -3394,13 +3404,13 @@ static void STDMETHODCALLTYPE d3d12_device_CreateDepthStencilView(ID3D12Device1
iface, resource, desc, descriptor.ptr);
d3d12_dsv_desc_create_dsv(d3d12_dsv_desc_from_cpu_handle(descriptor),
impl_from_ID3D12Device1(iface), unsafe_impl_from_ID3D12Resource(resource), desc);
impl_from_ID3D12Device5(iface), unsafe_impl_from_ID3D12Resource(resource), desc);
}
static void STDMETHODCALLTYPE d3d12_device_CreateSampler(ID3D12Device1 *iface,
static void STDMETHODCALLTYPE d3d12_device_CreateSampler(ID3D12Device5 *iface,
const D3D12_SAMPLER_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
struct d3d12_desc tmp = {0};
TRACE("iface %p, desc %p, descriptor %#lx.\n", iface, desc, descriptor.ptr);
@ -3409,14 +3419,14 @@ static void STDMETHODCALLTYPE d3d12_device_CreateSampler(ID3D12Device1 *iface,
d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device);
}
static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device1 *iface,
static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device5 *iface,
UINT dst_descriptor_range_count, const D3D12_CPU_DESCRIPTOR_HANDLE *dst_descriptor_range_offsets,
const UINT *dst_descriptor_range_sizes,
UINT src_descriptor_range_count, const D3D12_CPU_DESCRIPTOR_HANDLE *src_descriptor_range_offsets,
const UINT *src_descriptor_range_sizes,
D3D12_DESCRIPTOR_HEAP_TYPE descriptor_heap_type)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
unsigned int dst_range_idx, dst_idx, src_range_idx, src_idx;
unsigned int dst_range_size, src_range_size;
struct d3d12_descriptor_heap *dst_heap;
@ -3472,7 +3482,7 @@ static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device1 *iface,
}
}
static void STDMETHODCALLTYPE d3d12_device_CopyDescriptorsSimple(ID3D12Device1 *iface,
static void STDMETHODCALLTYPE d3d12_device_CopyDescriptorsSimple(ID3D12Device5 *iface,
UINT descriptor_count, const D3D12_CPU_DESCRIPTOR_HANDLE dst_descriptor_range_offset,
const D3D12_CPU_DESCRIPTOR_HANDLE src_descriptor_range_offset,
D3D12_DESCRIPTOR_HEAP_TYPE descriptor_heap_type)
@ -3487,10 +3497,10 @@ static void STDMETHODCALLTYPE d3d12_device_CopyDescriptorsSimple(ID3D12Device1 *
}
static D3D12_RESOURCE_ALLOCATION_INFO * STDMETHODCALLTYPE d3d12_device_GetResourceAllocationInfo(
ID3D12Device1 *iface, D3D12_RESOURCE_ALLOCATION_INFO *info, UINT visible_mask,
ID3D12Device5 *iface, D3D12_RESOURCE_ALLOCATION_INFO *info, UINT visible_mask,
UINT count, const D3D12_RESOURCE_DESC *resource_descs)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
const D3D12_RESOURCE_DESC *desc;
uint64_t requested_alignment;
@ -3563,10 +3573,10 @@ invalid:
return info;
}
static D3D12_HEAP_PROPERTIES * STDMETHODCALLTYPE d3d12_device_GetCustomHeapProperties(ID3D12Device1 *iface,
static D3D12_HEAP_PROPERTIES * STDMETHODCALLTYPE d3d12_device_GetCustomHeapProperties(ID3D12Device5 *iface,
D3D12_HEAP_PROPERTIES *heap_properties, UINT node_mask, D3D12_HEAP_TYPE heap_type)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
bool coherent;
TRACE("iface %p, heap_properties %p, node_mask 0x%08x, heap_type %#x.\n",
@ -3606,12 +3616,12 @@ static D3D12_HEAP_PROPERTIES * STDMETHODCALLTYPE d3d12_device_GetCustomHeapPrope
return heap_properties;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource(ID3D12Device1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource(ID3D12Device5 *iface,
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,
const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state,
const D3D12_CLEAR_VALUE *optimized_clear_value, REFIID iid, void **resource)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
struct d3d12_resource *object;
HRESULT hr;
@ -3621,26 +3631,26 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource(ID3D12Devi
optimized_clear_value, debugstr_guid(iid), resource);
if (FAILED(hr = d3d12_committed_resource_create(device, heap_properties, heap_flags,
desc, initial_state, optimized_clear_value, &object)))
desc, initial_state, optimized_clear_value, NULL, &object)))
{
*resource = NULL;
return hr;
}
return return_interface(&object->ID3D12Resource_iface, &IID_ID3D12Resource, iid, resource);
return return_interface(&object->ID3D12Resource1_iface, &IID_ID3D12Resource1, iid, resource);
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap(ID3D12Device1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap(ID3D12Device5 *iface,
const D3D12_HEAP_DESC *desc, REFIID iid, void **heap)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
struct d3d12_heap *object;
HRESULT hr;
TRACE("iface %p, desc %p, iid %s, heap %p.\n",
iface, desc, debugstr_guid(iid), heap);
if (FAILED(hr = d3d12_heap_create(device, desc, NULL, &object)))
if (FAILED(hr = d3d12_heap_create(device, desc, NULL, NULL, &object)))
{
*heap = NULL;
return hr;
@ -3649,12 +3659,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap(ID3D12Device1 *iface,
return return_interface(&object->ID3D12Heap_iface, &IID_ID3D12Heap, iid, heap);
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePlacedResource(ID3D12Device1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePlacedResource(ID3D12Device5 *iface,
ID3D12Heap *heap, UINT64 heap_offset,
const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state,
const D3D12_CLEAR_VALUE *optimized_clear_value, REFIID iid, void **resource)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
struct d3d12_heap *heap_object;
struct d3d12_resource *object;
HRESULT hr;
@ -3670,14 +3680,14 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePlacedResource(ID3D12Device1
desc, initial_state, optimized_clear_value, &object)))
return hr;
return return_interface(&object->ID3D12Resource_iface, &IID_ID3D12Resource, iid, resource);
return return_interface(&object->ID3D12Resource1_iface, &IID_ID3D12Resource1, iid, resource);
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource(ID3D12Device1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource(ID3D12Device5 *iface,
const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state,
const D3D12_CLEAR_VALUE *optimized_clear_value, REFIID iid, void **resource)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
struct d3d12_resource *object;
HRESULT hr;
@ -3688,14 +3698,14 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource(ID3D12Devic
desc, initial_state, optimized_clear_value, &object)))
return hr;
return return_interface(&object->ID3D12Resource_iface, &IID_ID3D12Resource, iid, resource);
return return_interface(&object->ID3D12Resource1_iface, &IID_ID3D12Resource1, iid, resource);
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateSharedHandle(ID3D12Device1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateSharedHandle(ID3D12Device5 *iface,
ID3D12DeviceChild *object, const SECURITY_ATTRIBUTES *attributes, DWORD access,
const WCHAR *name, HANDLE *handle)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
FIXME("iface %p, object %p, attributes %p, access %#x, name %s, handle %p stub!\n",
iface, object, attributes, access, debugstr_w(name, device->wchar_size), handle);
@ -3703,7 +3713,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateSharedHandle(ID3D12Device1 *
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandle(ID3D12Device1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandle(ID3D12Device5 *iface,
HANDLE handle, REFIID riid, void **object)
{
FIXME("iface %p, handle %p, riid %s, object %p stub!\n",
@ -3712,10 +3722,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandle(ID3D12Device1 *if
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandleByName(ID3D12Device1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandleByName(ID3D12Device5 *iface,
const WCHAR *name, DWORD access, HANDLE *handle)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
FIXME("iface %p, name %s, access %#x, handle %p stub!\n",
iface, debugstr_w(name, device->wchar_size), access, handle);
@ -3723,7 +3733,25 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandleByName(ID3D12Devic
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_MakeResident(ID3D12Device1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_device_MakeResident(ID3D12Device5 *iface,
UINT object_count, ID3D12Pageable * const *objects)
{
ID3D12Fence *fence;
HRESULT hr;
TRACE("iface %p, object_count %u, objects %p.\n", iface, object_count, objects);
if (FAILED(hr = ID3D12Device5_CreateFence(iface, 0, 0, &IID_ID3D12Fence, (void **)&fence)))
return hr;
hr = ID3D12Device5_EnqueueMakeResident(iface, 0, object_count, objects, fence, 1);
if (SUCCEEDED(hr))
ID3D12Fence_SetEventOnCompletion(fence, 1, NULL);
ID3D12Fence_Release(fence);
return hr;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_Evict(ID3D12Device5 *iface,
UINT object_count, ID3D12Pageable * const *objects)
{
FIXME_ONCE("iface %p, object_count %u, objects %p stub!\n",
@ -3732,19 +3760,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_MakeResident(ID3D12Device1 *iface,
return S_OK;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_Evict(ID3D12Device1 *iface,
UINT object_count, ID3D12Pageable * const *objects)
{
FIXME_ONCE("iface %p, object_count %u, objects %p stub!\n",
iface, object_count, objects);
return S_OK;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateFence(ID3D12Device1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateFence(ID3D12Device5 *iface,
UINT64 initial_value, D3D12_FENCE_FLAGS flags, REFIID riid, void **fence)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
struct d3d12_fence *object;
HRESULT hr;
@ -3757,21 +3776,21 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateFence(ID3D12Device1 *iface,
return return_interface(&object->ID3D12Fence1_iface, &IID_ID3D12Fence1, riid, fence);
}
static HRESULT STDMETHODCALLTYPE d3d12_device_GetDeviceRemovedReason(ID3D12Device1 *iface)
static HRESULT STDMETHODCALLTYPE d3d12_device_GetDeviceRemovedReason(ID3D12Device5 *iface)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
TRACE("iface %p.\n", iface);
return device->removed_reason;
}
static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(ID3D12Device1 *iface,
static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(ID3D12Device5 *iface,
const D3D12_RESOURCE_DESC *desc, UINT first_sub_resource, UINT sub_resource_count,
UINT64 base_offset, D3D12_PLACED_SUBRESOURCE_FOOTPRINT *layouts,
UINT *row_counts, UINT64 *row_sizes, UINT64 *total_bytes)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
unsigned int i, sub_resource_idx, miplevel_idx, row_count, row_size, row_pitch;
unsigned int width, height, depth, plane_count, sub_resources_per_plane;
@ -3851,10 +3870,10 @@ static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(ID3D12Device1 *
*total_bytes = total;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateQueryHeap(ID3D12Device1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateQueryHeap(ID3D12Device5 *iface,
const D3D12_QUERY_HEAP_DESC *desc, REFIID iid, void **heap)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
struct d3d12_query_heap *object;
HRESULT hr;
@ -3867,18 +3886,18 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateQueryHeap(ID3D12Device1 *ifa
return return_interface(&object->ID3D12QueryHeap_iface, &IID_ID3D12QueryHeap, iid, heap);
}
static HRESULT STDMETHODCALLTYPE d3d12_device_SetStablePowerState(ID3D12Device1 *iface, BOOL enable)
static HRESULT STDMETHODCALLTYPE d3d12_device_SetStablePowerState(ID3D12Device5 *iface, BOOL enable)
{
FIXME("iface %p, enable %#x stub!\n", iface, enable);
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandSignature(ID3D12Device1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandSignature(ID3D12Device5 *iface,
const D3D12_COMMAND_SIGNATURE_DESC *desc, ID3D12RootSignature *root_signature,
REFIID iid, void **command_signature)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
struct d3d12_command_signature *object;
HRESULT hr;
@ -3892,14 +3911,14 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandSignature(ID3D12Devic
&IID_ID3D12CommandSignature, iid, command_signature);
}
static void STDMETHODCALLTYPE d3d12_device_GetResourceTiling(ID3D12Device1 *iface,
static void STDMETHODCALLTYPE d3d12_device_GetResourceTiling(ID3D12Device5 *iface,
ID3D12Resource *resource, UINT *total_tile_count,
D3D12_PACKED_MIP_INFO *packed_mip_info, D3D12_TILE_SHAPE *standard_tile_shape,
UINT *sub_resource_tiling_count, UINT first_sub_resource_tiling,
D3D12_SUBRESOURCE_TILING *sub_resource_tilings)
{
const struct d3d12_resource *resource_impl = impl_from_ID3D12Resource(resource);
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
TRACE("iface %p, resource %p, total_tile_count %p, packed_mip_info %p, "
"standard_title_shape %p, sub_resource_tiling_count %p, "
@ -3912,9 +3931,9 @@ static void STDMETHODCALLTYPE d3d12_device_GetResourceTiling(ID3D12Device1 *ifac
sub_resource_tiling_count, first_sub_resource_tiling, sub_resource_tilings);
}
static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device1 *iface, LUID *luid)
static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device5 *iface, LUID *luid)
{
struct d3d12_device *device = impl_from_ID3D12Device1(iface);
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
TRACE("iface %p, luid %p.\n", iface, luid);
@ -3923,7 +3942,7 @@ static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device1 *iface
return luid;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineLibrary(ID3D12Device1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineLibrary(ID3D12Device5 *iface,
const void *blob, SIZE_T blob_size, REFIID iid, void **lib)
{
FIXME("iface %p, blob %p, blob_size %lu, iid %s, lib %p stub!\n", iface, blob, blob_size, debugstr_guid(iid), lib);
@ -3931,7 +3950,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineLibrary(ID3D12Device
return DXGI_ERROR_UNSUPPORTED;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_SetEventOnMultipleFenceCompletion(ID3D12Device1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_device_SetEventOnMultipleFenceCompletion(ID3D12Device5 *iface,
ID3D12Fence *const *fences, const UINT64 *values, UINT fence_count,
D3D12_MULTIPLE_FENCE_WAIT_FLAGS flags, HANDLE event)
{
@ -3941,7 +3960,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetEventOnMultipleFenceCompletion(
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_SetResidencyPriority(ID3D12Device1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_device_SetResidencyPriority(ID3D12Device5 *iface,
UINT object_count, ID3D12Pageable *const *objects, const D3D12_RESIDENCY_PRIORITY *priorities)
{
FIXME_ONCE("iface %p, object_count %u, objects %p, priorities %p stub!\n", iface, object_count, objects, priorities);
@ -3949,7 +3968,205 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetResidencyPriority(ID3D12Device1
return S_OK;
}
static const struct ID3D12Device1Vtbl d3d12_device_vtbl =
static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineState(ID3D12Device5 *iface,
const D3D12_PIPELINE_STATE_STREAM_DESC *desc, REFIID iid, void **pipeline_state)
{
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
struct d3d12_pipeline_state *object;
HRESULT hr;
TRACE("iface %p, desc %p, iid %s, pipeline_state %p.\n", iface, desc, debugstr_guid(iid), pipeline_state);
if (FAILED(hr = d3d12_pipeline_state_create(device, desc, &object)))
return hr;
return return_interface(&object->ID3D12PipelineState_iface, &IID_ID3D12PipelineState, iid, pipeline_state);
}
static HRESULT STDMETHODCALLTYPE d3d12_device_OpenExistingHeapFromAddress(ID3D12Device5 *iface,
const void *address, REFIID iid, void **heap)
{
FIXME("iface %p, address %p, iid %s, heap %p stub!\n", iface, address, debugstr_guid(iid), heap);
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_OpenExistingHeapFromFileMapping(ID3D12Device5 *iface,
HANDLE file_mapping, REFIID iid, void **heap)
{
FIXME("iface %p, file_mapping %p, iid %s, heap %p stub!\n", iface, file_mapping, debugstr_guid(iid), heap);
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_EnqueueMakeResident(ID3D12Device5 *iface,
D3D12_RESIDENCY_FLAGS flags, UINT num_objects, ID3D12Pageable *const *objects,
ID3D12Fence *fence, UINT64 fence_value)
{
FIXME_ONCE("iface %p, flags %#x, num_objects %u, objects %p, fence %p, fence_value %#"PRIx64" stub!\n",
iface, flags, num_objects, objects, fence, fence_value);
ID3D12Fence_Signal(fence, fence_value);
return S_OK;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList1(ID3D12Device5 *iface,
UINT node_mask, D3D12_COMMAND_LIST_TYPE type, D3D12_COMMAND_LIST_FLAGS flags,
REFIID iid, void **command_list)
{
FIXME("iface %p, node_mask 0x%08x, type %#x, flags %#x, iid %s, command_list %p stub!\n",
iface, node_mask, type, flags, debugstr_guid(iid), command_list);
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateProtectedResourceSession(ID3D12Device5 *iface,
const D3D12_PROTECTED_RESOURCE_SESSION_DESC *desc, REFIID iid, void **session)
{
FIXME("iface %p, desc %p, iid %s, session %p stub!\n", iface, desc, debugstr_guid(iid), session);
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource1(ID3D12Device5 *iface,
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,
const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state,
const D3D12_CLEAR_VALUE *optimized_clear_value,
ID3D12ProtectedResourceSession *protected_session, REFIID iid, void **resource)
{
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
struct d3d12_resource *object;
HRESULT hr;
TRACE("iface %p, heap_properties %p, heap_flags %#x, desc %p, initial_state %#x, "
"optimized_clear_value %p, protected_session %p, iid %s, resource %p.\n",
iface, heap_properties, heap_flags, desc, initial_state,
optimized_clear_value, protected_session, debugstr_guid(iid), resource);
if (FAILED(hr = d3d12_committed_resource_create(device, heap_properties, heap_flags,
desc, initial_state, optimized_clear_value, protected_session, &object)))
{
*resource = NULL;
return hr;
}
return return_interface(&object->ID3D12Resource1_iface, &IID_ID3D12Resource1, iid, resource);
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap1(ID3D12Device5 *iface,
const D3D12_HEAP_DESC *desc, ID3D12ProtectedResourceSession *protected_session,
REFIID iid, void **heap)
{
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
struct d3d12_heap *object;
HRESULT hr;
TRACE("iface %p, desc %p, protected_session %p, iid %s, heap %p.\n",
iface, desc, protected_session, debugstr_guid(iid), heap);
if (FAILED(hr = d3d12_heap_create(device, desc, NULL, protected_session, &object)))
{
*heap = NULL;
return hr;
}
return return_interface(&object->ID3D12Heap_iface, &IID_ID3D12Heap, iid, heap);
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource1(ID3D12Device5 *iface,
const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state,
const D3D12_CLEAR_VALUE *optimized_clear_value,
ID3D12ProtectedResourceSession *protected_session, REFIID iid, void **resource)
{
FIXME("iface %p, desc %p, initial_state %#x, optimized_clear_value %p, "
"protected_session %p, iid %s, resource %p stub!\n",
iface, desc, initial_state, optimized_clear_value, protected_session,
debugstr_guid(iid), resource);
return E_NOTIMPL;
}
static D3D12_RESOURCE_ALLOCATION_INFO * STDMETHODCALLTYPE d3d12_device_GetResourceAllocationInfo1(
ID3D12Device5 *iface, D3D12_RESOURCE_ALLOCATION_INFO *info, UINT visible_mask,
UINT count, const D3D12_RESOURCE_DESC *resource_descs,
D3D12_RESOURCE_ALLOCATION_INFO1 *info1)
{
FIXME("iface %p, info %p, visible_mask 0x%08x, count %u, resource_descs %p, info1 %p stub!\n",
iface, info, visible_mask, count, resource_descs, info1);
return info;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateLifetimeTracker(ID3D12Device5 *iface,
ID3D12LifetimeOwner *owner, REFIID iid, void **tracker)
{
FIXME("iface %p, owner %p, iid %s, tracker %p stub!\n", iface, owner, debugstr_guid(iid), tracker);
return E_NOTIMPL;
}
static void STDMETHODCALLTYPE d3d12_device_RemoveDevice(ID3D12Device5 *iface)
{
FIXME("iface %p stub!\n", iface);
}
static HRESULT STDMETHODCALLTYPE d3d12_device_EnumerateMetaCommands(ID3D12Device5 *iface,
UINT *num_meta_commands, D3D12_META_COMMAND_DESC *command_desc)
{
FIXME("iface %p, num_meta_commands %p, command_desc %p stub!\n", iface,
num_meta_commands, command_desc);
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_EnumerateMetaCommandParameters(ID3D12Device5 *iface,
REFGUID command_id, D3D12_META_COMMAND_PARAMETER_STAGE stage,
UINT *size_in_bytes, UINT *parameter_count,
D3D12_META_COMMAND_PARAMETER_DESC *parameter_desc)
{
FIXME("iface %p, command_id %s, stage %u, size_in_bytes %p, "
"parameter_count %p, parameter_desc %p stub!\n", iface,
debugstr_guid(command_id), stage, size_in_bytes, parameter_count, parameter_desc);
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateMetaCommand(ID3D12Device5 *iface,
REFGUID command_id, UINT node_mask, const void *parameters_data,
SIZE_T data_size_in_bytes, REFIID iid, void **meta_command)
{
FIXME("iface %p, command_id %s, node_mask %#x, parameters_data %p, "
"data_size_in_bytes %lu, iid %s, meta_command %p stub!\n", iface,
debugstr_guid(command_id), node_mask, parameters_data,
data_size_in_bytes, debugstr_guid(iid), meta_command);
return E_NOTIMPL;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateStateObject(ID3D12Device5 *iface,
const D3D12_STATE_OBJECT_DESC *desc, REFIID iid, void **state_object)
{
FIXME("iface %p, desc %p, iid %s, state_object %p stub!\n", iface, desc, debugstr_guid(iid), state_object);
return E_NOTIMPL;
}
static void STDMETHODCALLTYPE d3d12_device_GetRaytracingAccelerationStructurePrebuildInfo(ID3D12Device5 *iface,
const D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS *desc,
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO *info)
{
FIXME("iface %p, desc %p, info %p stub!\n", iface, desc, info);
}
static D3D12_DRIVER_MATCHING_IDENTIFIER_STATUS STDMETHODCALLTYPE d3d12_device_CheckDriverMatchingIdentifier(ID3D12Device5 *iface,
D3D12_SERIALIZED_DATA_TYPE data_type, const D3D12_SERIALIZED_DATA_DRIVER_MATCHING_IDENTIFIER *identifier)
{
FIXME("iface %p, data_type %u, identifier %p stub!\n", iface, data_type, identifier);
return D3D12_DRIVER_MATCHING_IDENTIFIER_UNRECOGNIZED;
}
static const struct ID3D12Device5Vtbl d3d12_device_vtbl =
{
/* IUnknown methods */
d3d12_device_QueryInterface,
@ -4002,14 +4219,36 @@ static const struct ID3D12Device1Vtbl d3d12_device_vtbl =
d3d12_device_CreatePipelineLibrary,
d3d12_device_SetEventOnMultipleFenceCompletion,
d3d12_device_SetResidencyPriority,
/* ID3D12Device2 methods */
d3d12_device_CreatePipelineState,
/* ID3D12Device3 methods */
d3d12_device_OpenExistingHeapFromAddress,
d3d12_device_OpenExistingHeapFromFileMapping,
d3d12_device_EnqueueMakeResident,
/* ID3D12Device4 methods */
d3d12_device_CreateCommandList1,
d3d12_device_CreateProtectedResourceSession,
d3d12_device_CreateCommittedResource1,
d3d12_device_CreateHeap1,
d3d12_device_CreateReservedResource1,
d3d12_device_GetResourceAllocationInfo1,
/* ID3D12Device5 methods */
d3d12_device_CreateLifetimeTracker,
d3d12_device_RemoveDevice,
d3d12_device_EnumerateMetaCommands,
d3d12_device_EnumerateMetaCommandParameters,
d3d12_device_CreateMetaCommand,
d3d12_device_CreateStateObject,
d3d12_device_GetRaytracingAccelerationStructurePrebuildInfo,
d3d12_device_CheckDriverMatchingIdentifier,
};
struct d3d12_device *unsafe_impl_from_ID3D12Device1(ID3D12Device1 *iface)
struct d3d12_device *unsafe_impl_from_ID3D12Device5(ID3D12Device5 *iface)
{
if (!iface)
return NULL;
assert(iface->lpVtbl == &d3d12_device_vtbl);
return impl_from_ID3D12Device1(iface);
return impl_from_ID3D12Device5(iface);
}
static HRESULT d3d12_device_init(struct d3d12_device *device,
@ -4018,7 +4257,7 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
const struct vkd3d_vk_device_procs *vk_procs;
HRESULT hr;
device->ID3D12Device1_iface.lpVtbl = &d3d12_device_vtbl;
device->ID3D12Device5_iface.lpVtbl = &d3d12_device_vtbl;
device->refcount = 1;
vkd3d_instance_incref(device->vkd3d_instance = instance);
@ -4215,28 +4454,28 @@ HRESULT vkd3d_join_thread(struct vkd3d_instance *instance, union vkd3d_thread_ha
IUnknown *vkd3d_get_device_parent(ID3D12Device *device)
{
struct d3d12_device *d3d12_device = impl_from_ID3D12Device1((ID3D12Device1 *)device);
struct d3d12_device *d3d12_device = impl_from_ID3D12Device5((ID3D12Device5 *)device);
return d3d12_device->parent;
}
VkDevice vkd3d_get_vk_device(ID3D12Device *device)
{
struct d3d12_device *d3d12_device = impl_from_ID3D12Device1((ID3D12Device1 *)device);
struct d3d12_device *d3d12_device = impl_from_ID3D12Device5((ID3D12Device5 *)device);
return d3d12_device->vk_device;
}
VkPhysicalDevice vkd3d_get_vk_physical_device(ID3D12Device *device)
{
struct d3d12_device *d3d12_device = impl_from_ID3D12Device1((ID3D12Device1 *)device);
struct d3d12_device *d3d12_device = impl_from_ID3D12Device5((ID3D12Device5 *)device);
return d3d12_device->vk_physical_device;
}
struct vkd3d_instance *vkd3d_instance_from_device(ID3D12Device *device)
{
struct d3d12_device *d3d12_device = impl_from_ID3D12Device1((ID3D12Device1 *)device);
struct d3d12_device *d3d12_device = impl_from_ID3D12Device5((ID3D12Device5 *)device);
return d3d12_device->vkd3d_instance;
}

View file

@ -574,11 +574,15 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap,
}
HRESULT d3d12_heap_create(struct d3d12_device *device, const D3D12_HEAP_DESC *desc,
const struct d3d12_resource *resource, struct d3d12_heap **heap)
const struct d3d12_resource *resource, ID3D12ProtectedResourceSession *protected_session,
struct d3d12_heap **heap)
{
struct d3d12_heap *object;
HRESULT hr;
if (protected_session)
FIXME("Protected session is not supported.\n");
if (!(object = vkd3d_malloc(sizeof(*object))))
return E_OUTOFMEMORY;
@ -1254,12 +1258,13 @@ static bool d3d12_resource_init_tiles(struct d3d12_resource *resource, struct d3
}
/* ID3D12Resource */
static HRESULT STDMETHODCALLTYPE d3d12_resource_QueryInterface(ID3D12Resource *iface,
static HRESULT STDMETHODCALLTYPE d3d12_resource_QueryInterface(ID3D12Resource1 *iface,
REFIID riid, void **object)
{
TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
if (IsEqualGUID(riid, &IID_ID3D12Resource)
if (IsEqualGUID(riid, &IID_ID3D12Resource1)
|| IsEqualGUID(riid, &IID_ID3D12Resource)
|| IsEqualGUID(riid, &IID_ID3D12Pageable)
|| IsEqualGUID(riid, &IID_ID3D12DeviceChild)
|| IsEqualGUID(riid, &IID_ID3D12Object)
@ -1276,9 +1281,9 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_QueryInterface(ID3D12Resource *i
return E_NOINTERFACE;
}
static ULONG STDMETHODCALLTYPE d3d12_resource_AddRef(ID3D12Resource *iface)
static ULONG STDMETHODCALLTYPE d3d12_resource_AddRef(ID3D12Resource1 *iface)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource(iface);
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
ULONG refcount = InterlockedIncrement(&resource->refcount);
TRACE("%p increasing refcount to %u.\n", resource, refcount);
@ -1294,9 +1299,9 @@ static ULONG STDMETHODCALLTYPE d3d12_resource_AddRef(ID3D12Resource *iface)
return refcount;
}
static ULONG STDMETHODCALLTYPE d3d12_resource_Release(ID3D12Resource *iface)
static ULONG STDMETHODCALLTYPE d3d12_resource_Release(ID3D12Resource1 *iface)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource(iface);
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
ULONG refcount = InterlockedDecrement(&resource->refcount);
TRACE("%p decreasing refcount to %u.\n", resource, refcount);
@ -1313,39 +1318,39 @@ static ULONG STDMETHODCALLTYPE d3d12_resource_Release(ID3D12Resource *iface)
return refcount;
}
static HRESULT STDMETHODCALLTYPE d3d12_resource_GetPrivateData(ID3D12Resource *iface,
static HRESULT STDMETHODCALLTYPE d3d12_resource_GetPrivateData(ID3D12Resource1 *iface,
REFGUID guid, UINT *data_size, void *data)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource(iface);
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
return vkd3d_get_private_data(&resource->private_store, guid, data_size, data);
}
static HRESULT STDMETHODCALLTYPE d3d12_resource_SetPrivateData(ID3D12Resource *iface,
static HRESULT STDMETHODCALLTYPE d3d12_resource_SetPrivateData(ID3D12Resource1 *iface,
REFGUID guid, UINT data_size, const void *data)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource(iface);
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
return vkd3d_set_private_data(&resource->private_store, guid, data_size, data);
}
static HRESULT STDMETHODCALLTYPE d3d12_resource_SetPrivateDataInterface(ID3D12Resource *iface,
static HRESULT STDMETHODCALLTYPE d3d12_resource_SetPrivateDataInterface(ID3D12Resource1 *iface,
REFGUID guid, const IUnknown *data)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource(iface);
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
return vkd3d_set_private_data_interface(&resource->private_store, guid, data);
}
static HRESULT STDMETHODCALLTYPE d3d12_resource_SetName(ID3D12Resource *iface, const WCHAR *name)
static HRESULT STDMETHODCALLTYPE d3d12_resource_SetName(ID3D12Resource1 *iface, const WCHAR *name)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource(iface);
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
HRESULT hr;
TRACE("iface %p, name %s.\n", iface, debugstr_w(name, resource->device->wchar_size));
@ -1364,9 +1369,9 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_SetName(ID3D12Resource *iface, c
VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, name);
}
static HRESULT STDMETHODCALLTYPE d3d12_resource_GetDevice(ID3D12Resource *iface, REFIID iid, void **device)
static HRESULT STDMETHODCALLTYPE d3d12_resource_GetDevice(ID3D12Resource1 *iface, REFIID iid, void **device)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource(iface);
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
TRACE("iface %p, iid %s, device %p.\n", iface, debugstr_guid(iid), device);
@ -1417,10 +1422,10 @@ static void d3d12_resource_flush(struct d3d12_resource *resource, uint64_t offse
ERR("Failed to flush memory, vr %d.\n", vr);
}
static HRESULT STDMETHODCALLTYPE d3d12_resource_Map(ID3D12Resource *iface, UINT sub_resource,
static HRESULT STDMETHODCALLTYPE d3d12_resource_Map(ID3D12Resource1 *iface, UINT sub_resource,
const D3D12_RANGE *read_range, void **data)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource(iface);
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
unsigned int sub_resource_count;
TRACE("iface %p, sub_resource %u, read_range %p, data %p.\n",
@ -1466,10 +1471,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_Map(ID3D12Resource *iface, UINT
return S_OK;
}
static void STDMETHODCALLTYPE d3d12_resource_Unmap(ID3D12Resource *iface, UINT sub_resource,
static void STDMETHODCALLTYPE d3d12_resource_Unmap(ID3D12Resource1 *iface, UINT sub_resource,
const D3D12_RANGE *written_range)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource(iface);
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
unsigned int sub_resource_count;
TRACE("iface %p, sub_resource %u, written_range %p.\n",
@ -1488,10 +1493,10 @@ static void STDMETHODCALLTYPE d3d12_resource_Unmap(ID3D12Resource *iface, UINT s
d3d12_resource_flush(resource, written_range->Begin, written_range->End - written_range->Begin);
}
static D3D12_RESOURCE_DESC * STDMETHODCALLTYPE d3d12_resource_GetDesc(ID3D12Resource *iface,
static D3D12_RESOURCE_DESC * STDMETHODCALLTYPE d3d12_resource_GetDesc(ID3D12Resource1 *iface,
D3D12_RESOURCE_DESC *resource_desc)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource(iface);
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
TRACE("iface %p, resource_desc %p.\n", iface, resource_desc);
@ -1499,20 +1504,20 @@ static D3D12_RESOURCE_DESC * STDMETHODCALLTYPE d3d12_resource_GetDesc(ID3D12Reso
return resource_desc;
}
static D3D12_GPU_VIRTUAL_ADDRESS STDMETHODCALLTYPE d3d12_resource_GetGPUVirtualAddress(ID3D12Resource *iface)
static D3D12_GPU_VIRTUAL_ADDRESS STDMETHODCALLTYPE d3d12_resource_GetGPUVirtualAddress(ID3D12Resource1 *iface)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource(iface);
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
TRACE("iface %p.\n", iface);
return resource->gpu_address;
}
static HRESULT STDMETHODCALLTYPE d3d12_resource_WriteToSubresource(ID3D12Resource *iface,
static HRESULT STDMETHODCALLTYPE d3d12_resource_WriteToSubresource(ID3D12Resource1 *iface,
UINT dst_sub_resource, const D3D12_BOX *dst_box, const void *src_data,
UINT src_row_pitch, UINT src_slice_pitch)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource(iface);
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
const struct vkd3d_vk_device_procs *vk_procs;
VkImageSubresource vk_sub_resource;
const struct vkd3d_format *format;
@ -1593,11 +1598,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_WriteToSubresource(ID3D12Resourc
return S_OK;
}
static HRESULT STDMETHODCALLTYPE d3d12_resource_ReadFromSubresource(ID3D12Resource *iface,
static HRESULT STDMETHODCALLTYPE d3d12_resource_ReadFromSubresource(ID3D12Resource1 *iface,
void *dst_data, UINT dst_row_pitch, UINT dst_slice_pitch,
UINT src_sub_resource, const D3D12_BOX *src_box)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource(iface);
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
const struct vkd3d_vk_device_procs *vk_procs;
VkImageSubresource vk_sub_resource;
const struct vkd3d_format *format;
@ -1678,10 +1683,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_ReadFromSubresource(ID3D12Resour
return S_OK;
}
static HRESULT STDMETHODCALLTYPE d3d12_resource_GetHeapProperties(ID3D12Resource *iface,
static HRESULT STDMETHODCALLTYPE d3d12_resource_GetHeapProperties(ID3D12Resource1 *iface,
D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS *flags)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource(iface);
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
struct d3d12_heap *heap;
TRACE("iface %p, heap_properties %p, flags %p.\n",
@ -1715,7 +1720,15 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_GetHeapProperties(ID3D12Resource
return S_OK;
}
static const struct ID3D12ResourceVtbl d3d12_resource_vtbl =
static HRESULT STDMETHODCALLTYPE d3d12_resource_GetProtectedResourceSession(ID3D12Resource1 *iface,
REFIID iid, void **session)
{
FIXME("iface %p, iid %s, session %p stub!\n", iface, debugstr_guid(iid), session);
return E_NOTIMPL;
}
static const struct ID3D12Resource1Vtbl d3d12_resource_vtbl =
{
/* IUnknown methods */
d3d12_resource_QueryInterface,
@ -1736,13 +1749,15 @@ static const struct ID3D12ResourceVtbl d3d12_resource_vtbl =
d3d12_resource_WriteToSubresource,
d3d12_resource_ReadFromSubresource,
d3d12_resource_GetHeapProperties,
/* ID3D12Resource1 methods */
d3d12_resource_GetProtectedResourceSession,
};
struct d3d12_resource *unsafe_impl_from_ID3D12Resource(ID3D12Resource *iface)
{
if (!iface)
return NULL;
assert(iface->lpVtbl == &d3d12_resource_vtbl);
assert(iface->lpVtbl == (ID3D12ResourceVtbl *)&d3d12_resource_vtbl);
return impl_from_ID3D12Resource(iface);
}
@ -1940,7 +1955,7 @@ static HRESULT d3d12_resource_init(struct d3d12_resource *resource, struct d3d12
{
HRESULT hr;
resource->ID3D12Resource_iface.lpVtbl = &d3d12_resource_vtbl;
resource->ID3D12Resource1_iface.lpVtbl = &d3d12_resource_vtbl;
resource->refcount = 1;
resource->internal_refcount = 1;
@ -2064,7 +2079,7 @@ static HRESULT vkd3d_allocate_resource_memory(
heap_desc.Properties = *heap_properties;
heap_desc.Alignment = 0;
heap_desc.Flags = heap_flags;
if (SUCCEEDED(hr = d3d12_heap_create(device, &heap_desc, resource, &resource->heap)))
if (SUCCEEDED(hr = d3d12_heap_create(device, &heap_desc, resource, NULL, &resource->heap)))
resource->flags |= VKD3D_RESOURCE_DEDICATED_HEAP;
return hr;
}
@ -2072,7 +2087,8 @@ static HRESULT vkd3d_allocate_resource_memory(
HRESULT d3d12_committed_resource_create(struct d3d12_device *device,
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,
const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state,
const D3D12_CLEAR_VALUE *optimized_clear_value, struct d3d12_resource **resource)
const D3D12_CLEAR_VALUE *optimized_clear_value, ID3D12ProtectedResourceSession *protected_session,
struct d3d12_resource **resource)
{
struct d3d12_resource *object;
HRESULT hr;
@ -2083,13 +2099,16 @@ HRESULT d3d12_committed_resource_create(struct d3d12_device *device,
return E_INVALIDARG;
}
if (protected_session)
FIXME("Protected session is not supported.\n");
if (FAILED(hr = d3d12_resource_create(device, heap_properties, heap_flags,
desc, initial_state, optimized_clear_value, &object)))
return hr;
if (FAILED(hr = vkd3d_allocate_resource_memory(device, object, heap_properties, heap_flags)))
{
d3d12_resource_Release(&object->ID3D12Resource_iface);
d3d12_resource_Release(&object->ID3D12Resource1_iface);
return hr;
}
@ -2182,7 +2201,7 @@ HRESULT d3d12_placed_resource_create(struct d3d12_device *device, struct d3d12_h
if (FAILED(hr = vkd3d_bind_heap_memory(device, object, heap, heap_offset)))
{
d3d12_resource_Release(&object->ID3D12Resource_iface);
d3d12_resource_Release(&object->ID3D12Resource1_iface);
return hr;
}
@ -2206,7 +2225,7 @@ HRESULT d3d12_reserved_resource_create(struct d3d12_device *device,
if (!d3d12_resource_init_tiles(object, device))
{
d3d12_resource_Release(&object->ID3D12Resource_iface);
d3d12_resource_Release(&object->ID3D12Resource1_iface);
return E_OUTOFMEMORY;
}
@ -2220,7 +2239,7 @@ HRESULT d3d12_reserved_resource_create(struct d3d12_device *device,
HRESULT vkd3d_create_image_resource(ID3D12Device *device,
const struct vkd3d_image_resource_create_info *create_info, ID3D12Resource **resource)
{
struct d3d12_device *d3d12_device = unsafe_impl_from_ID3D12Device1((ID3D12Device1 *)device);
struct d3d12_device *d3d12_device = unsafe_impl_from_ID3D12Device5((ID3D12Device5 *)device);
struct d3d12_resource *object;
HRESULT hr;
@ -2241,7 +2260,7 @@ HRESULT vkd3d_create_image_resource(ID3D12Device *device,
memset(object, 0, sizeof(*object));
object->ID3D12Resource_iface.lpVtbl = &d3d12_resource_vtbl;
object->ID3D12Resource1_iface.lpVtbl = &d3d12_resource_vtbl;
object->refcount = 1;
object->internal_refcount = 1;
object->desc = create_info->desc;
@ -2265,7 +2284,7 @@ HRESULT vkd3d_create_image_resource(ID3D12Device *device,
TRACE("Created resource %p.\n", object);
*resource = &object->ID3D12Resource_iface;
*resource = (ID3D12Resource *)&object->ID3D12Resource1_iface;
return S_OK;
}
@ -2998,6 +3017,7 @@ static bool init_default_texture_view_desc(struct vkd3d_texture_view_desc *desc,
desc->components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
desc->components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
desc->allowed_swizzle = false;
desc->usage = 0;
return true;
}
@ -3039,6 +3059,7 @@ bool vkd3d_create_texture_view(struct d3d12_device *device, uint32_t magic, VkIm
{
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
const struct vkd3d_format *format = desc->format;
VkImageViewUsageCreateInfoKHR usage_desc;
struct VkImageViewCreateInfo view_desc;
VkImageView vk_view = VK_NULL_HANDLE;
struct vkd3d_view *object;
@ -3060,6 +3081,13 @@ bool vkd3d_create_texture_view(struct d3d12_device *device, uint32_t magic, VkIm
view_desc.subresourceRange.levelCount = desc->miplevel_count;
view_desc.subresourceRange.baseArrayLayer = desc->layer_idx;
view_desc.subresourceRange.layerCount = desc->layer_count;
if (device->vk_info.KHR_maintenance2)
{
usage_desc.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO;
usage_desc.pNext = NULL;
usage_desc.usage = desc->usage;
view_desc.pNext = &usage_desc;
}
if ((vr = VK_CALL(vkCreateImageView(device->vk_device, &view_desc, NULL, &vk_view))) < 0)
{
WARN("Failed to create Vulkan image view, vr %d.\n", vr);
@ -3196,6 +3224,7 @@ static void vkd3d_create_null_srv(struct d3d12_desc *descriptor,
vkd3d_desc.components.b = VK_COMPONENT_SWIZZLE_ZERO;
vkd3d_desc.components.a = VK_COMPONENT_SWIZZLE_ZERO;
vkd3d_desc.allowed_swizzle = true;
vkd3d_desc.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
vkd3d_create_texture_view(device, VKD3D_DESCRIPTOR_MAGIC_SRV, vk_image, &vkd3d_desc, &descriptor->s.u.view);
}
@ -3268,6 +3297,7 @@ void d3d12_desc_create_srv(struct d3d12_desc *descriptor,
vkd3d_desc.miplevel_count = VK_REMAINING_MIP_LEVELS;
vkd3d_desc.allowed_swizzle = true;
vkd3d_desc.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
if (desc)
{
@ -3421,6 +3451,7 @@ static void vkd3d_create_null_uav(struct d3d12_desc *descriptor,
vkd3d_desc.components.b = VK_COMPONENT_SWIZZLE_B;
vkd3d_desc.components.a = VK_COMPONENT_SWIZZLE_A;
vkd3d_desc.allowed_swizzle = false;
vkd3d_desc.usage = VK_IMAGE_USAGE_STORAGE_BIT;
vkd3d_create_texture_view(device, VKD3D_DESCRIPTOR_MAGIC_UAV, vk_image, &vkd3d_desc, &descriptor->s.u.view);
}
@ -3480,6 +3511,8 @@ static void vkd3d_create_texture_uav(struct d3d12_desc *descriptor,
if (!init_default_texture_view_desc(&vkd3d_desc, resource, desc ? desc->Format : 0))
return;
vkd3d_desc.usage = VK_IMAGE_USAGE_STORAGE_BIT;
if (vkd3d_format_is_compressed(vkd3d_desc.format))
{
WARN("UAVs cannot be created for compressed formats.\n");
@ -3747,6 +3780,8 @@ void d3d12_rtv_desc_create_rtv(struct d3d12_rtv_desc *rtv_desc, struct d3d12_dev
if (!init_default_texture_view_desc(&vkd3d_desc, resource, desc ? desc->Format : 0))
return;
vkd3d_desc.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
if (vkd3d_desc.format->vk_aspect_mask != VK_IMAGE_ASPECT_COLOR_BIT)
{
WARN("Trying to create RTV for depth/stencil format %#x.\n", vkd3d_desc.format->dxgi_format);
@ -3847,6 +3882,8 @@ void d3d12_dsv_desc_create_dsv(struct d3d12_dsv_desc *dsv_desc, struct d3d12_dev
if (!init_default_texture_view_desc(&vkd3d_desc, resource, desc ? desc->Format : 0))
return;
vkd3d_desc.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
if (!(vkd3d_desc.format->vk_aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)))
{
WARN("Trying to create DSV for format %#x.\n", vkd3d_desc.format->dxgi_format);

View file

@ -836,7 +836,7 @@ static unsigned int vk_heap_binding_count_from_descriptor_range(const struct d3d
else
{
/* Prefer an unsupported binding count vs a zero count, because shader compilation will fail
* to match a declaration to a zero binding, resulting in failure of pipline state creation. */
* to match a declaration to a zero binding, resulting in failure of pipeline state creation. */
return max_count + !max_count;
}
}
@ -1736,6 +1736,189 @@ void vkd3d_render_pass_cache_cleanup(struct vkd3d_render_pass_cache *cache,
cache->render_passes = NULL;
}
static void d3d12_init_pipeline_state_desc(struct d3d12_pipeline_state_desc *desc)
{
D3D12_DEPTH_STENCIL_DESC1 *ds_state = &desc->depth_stencil_state;
D3D12_RASTERIZER_DESC *rs_state = &desc->rasterizer_state;
D3D12_BLEND_DESC *blend_state = &desc->blend_state;
DXGI_SAMPLE_DESC *sample_desc = &desc->sample_desc;
memset(desc, 0, sizeof(*desc));
ds_state->DepthEnable = TRUE;
ds_state->DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
ds_state->DepthFunc = D3D12_COMPARISON_FUNC_LESS;
ds_state->StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK;
ds_state->StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK;
ds_state->FrontFace.StencilFunc = ds_state->BackFace.StencilFunc = D3D12_COMPARISON_FUNC_ALWAYS;
ds_state->FrontFace.StencilDepthFailOp = ds_state->BackFace.StencilDepthFailOp = D3D12_STENCIL_OP_KEEP;
ds_state->FrontFace.StencilPassOp = ds_state->BackFace.StencilPassOp = D3D12_STENCIL_OP_KEEP;
ds_state->FrontFace.StencilFailOp = ds_state->BackFace.StencilFailOp = D3D12_STENCIL_OP_KEEP;
rs_state->FillMode = D3D12_FILL_MODE_SOLID;
rs_state->CullMode = D3D12_CULL_MODE_BACK;
rs_state->DepthClipEnable = TRUE;
rs_state->ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
blend_state->RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
sample_desc->Count = 1;
sample_desc->Quality = 0;
desc->sample_mask = D3D12_DEFAULT_SAMPLE_MASK;
}
static void pipeline_state_desc_from_d3d12_graphics_desc(struct d3d12_pipeline_state_desc *desc,
const D3D12_GRAPHICS_PIPELINE_STATE_DESC *d3d12_desc)
{
memset(desc, 0, sizeof(*desc));
desc->root_signature = d3d12_desc->pRootSignature;
desc->vs = d3d12_desc->VS;
desc->ps = d3d12_desc->PS;
desc->ds = d3d12_desc->DS;
desc->hs = d3d12_desc->HS;
desc->gs = d3d12_desc->GS;
desc->stream_output = d3d12_desc->StreamOutput;
desc->blend_state = d3d12_desc->BlendState;
desc->sample_mask = d3d12_desc->SampleMask;
desc->rasterizer_state = d3d12_desc->RasterizerState;
memcpy(&desc->depth_stencil_state, &d3d12_desc->DepthStencilState, sizeof(d3d12_desc->DepthStencilState));
desc->input_layout = d3d12_desc->InputLayout;
desc->strip_cut_value = d3d12_desc->IBStripCutValue;
desc->primitive_topology_type = d3d12_desc->PrimitiveTopologyType;
desc->rtv_formats.NumRenderTargets = d3d12_desc->NumRenderTargets;
memcpy(desc->rtv_formats.RTFormats, d3d12_desc->RTVFormats, sizeof(desc->rtv_formats.RTFormats));
desc->dsv_format = d3d12_desc->DSVFormat;
desc->sample_desc = d3d12_desc->SampleDesc;
desc->node_mask = d3d12_desc->NodeMask;
desc->cached_pso = d3d12_desc->CachedPSO;
desc->flags = d3d12_desc->Flags;
}
static void pipeline_state_desc_from_d3d12_compute_desc(struct d3d12_pipeline_state_desc *desc,
const D3D12_COMPUTE_PIPELINE_STATE_DESC *d3d12_desc)
{
memset(desc, 0, sizeof(*desc));
desc->root_signature = d3d12_desc->pRootSignature;
desc->cs = d3d12_desc->CS;
desc->node_mask = d3d12_desc->NodeMask;
desc->cached_pso = d3d12_desc->CachedPSO;
desc->flags = d3d12_desc->Flags;
}
static HRESULT pipeline_state_desc_from_d3d12_stream_desc(struct d3d12_pipeline_state_desc *desc,
const D3D12_PIPELINE_STATE_STREAM_DESC *d3d12_desc, VkPipelineBindPoint *vk_bind_point)
{
D3D12_PIPELINE_STATE_SUBOBJECT_TYPE subobject_type;
uint64_t defined_subobjects = 0;
const uint8_t *stream_ptr;
uint64_t subobject_bit;
size_t start, size, i;
uint8_t *desc_bytes;
static const struct
{
size_t alignment;
size_t size;
size_t dst_offset;
}
subobject_info[] =
{
#define DCL_SUBOBJECT_INFO(type, field) {__alignof__(type), sizeof(type), offsetof(struct d3d12_pipeline_state_desc, field)}
[D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_ROOT_SIGNATURE] = DCL_SUBOBJECT_INFO(ID3D12RootSignature *, root_signature),
[D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VS] = DCL_SUBOBJECT_INFO(D3D12_SHADER_BYTECODE, vs),
[D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PS] = DCL_SUBOBJECT_INFO(D3D12_SHADER_BYTECODE, ps),
[D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DS] = DCL_SUBOBJECT_INFO(D3D12_SHADER_BYTECODE, ds),
[D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_HS] = DCL_SUBOBJECT_INFO(D3D12_SHADER_BYTECODE, hs),
[D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_GS] = DCL_SUBOBJECT_INFO(D3D12_SHADER_BYTECODE, gs),
[D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CS] = DCL_SUBOBJECT_INFO(D3D12_SHADER_BYTECODE, cs),
[D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_STREAM_OUTPUT] = DCL_SUBOBJECT_INFO(D3D12_STREAM_OUTPUT_DESC, stream_output),
[D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_BLEND] = DCL_SUBOBJECT_INFO(D3D12_BLEND_DESC, blend_state),
[D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_MASK] = DCL_SUBOBJECT_INFO(UINT, sample_mask),
[D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER] = DCL_SUBOBJECT_INFO(D3D12_RASTERIZER_DESC, rasterizer_state),
[D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL] = DCL_SUBOBJECT_INFO(D3D12_DEPTH_STENCIL_DESC, depth_stencil_state),
[D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_INPUT_LAYOUT] = DCL_SUBOBJECT_INFO(D3D12_INPUT_LAYOUT_DESC, input_layout),
[D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_IB_STRIP_CUT_VALUE] = DCL_SUBOBJECT_INFO(D3D12_INDEX_BUFFER_STRIP_CUT_VALUE, strip_cut_value),
[D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PRIMITIVE_TOPOLOGY] = DCL_SUBOBJECT_INFO(D3D12_PRIMITIVE_TOPOLOGY_TYPE, primitive_topology_type),
[D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RENDER_TARGET_FORMATS] = DCL_SUBOBJECT_INFO(struct D3D12_RT_FORMAT_ARRAY, rtv_formats),
[D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL_FORMAT] = DCL_SUBOBJECT_INFO(DXGI_FORMAT, dsv_format),
[D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_DESC] = DCL_SUBOBJECT_INFO(DXGI_SAMPLE_DESC, sample_desc),
[D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_NODE_MASK] = DCL_SUBOBJECT_INFO(UINT, node_mask),
[D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CACHED_PSO] = DCL_SUBOBJECT_INFO(D3D12_CACHED_PIPELINE_STATE, cached_pso),
[D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_FLAGS] = DCL_SUBOBJECT_INFO(D3D12_PIPELINE_STATE_FLAGS, flags),
[D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL1] = DCL_SUBOBJECT_INFO(D3D12_DEPTH_STENCIL_DESC1, depth_stencil_state),
[D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VIEW_INSTANCING] = DCL_SUBOBJECT_INFO(D3D12_VIEW_INSTANCING_DESC, view_instancing_desc),
#undef DCL_SUBOBJECT_INFO
};
STATIC_ASSERT(ARRAY_SIZE(subobject_info) <= sizeof(defined_subobjects) * CHAR_BIT);
/* Initialize defaults for undefined subobjects. */
d3d12_init_pipeline_state_desc(desc);
stream_ptr = d3d12_desc->pPipelineStateSubobjectStream;
desc_bytes = (uint8_t *)desc;
for (i = 0; i < d3d12_desc->SizeInBytes; )
{
if (!vkd3d_bound_range(0, sizeof(subobject_type), d3d12_desc->SizeInBytes - i))
{
WARN("Invalid pipeline state stream.\n");
return E_INVALIDARG;
}
subobject_type = *(const D3D12_PIPELINE_STATE_SUBOBJECT_TYPE *)&stream_ptr[i];
if (subobject_type >= ARRAY_SIZE(subobject_info))
{
FIXME("Unhandled pipeline subobject type %#x.\n", subobject_type);
return E_INVALIDARG;
}
subobject_bit = 1ull << subobject_type;
if (defined_subobjects & subobject_bit)
{
WARN("Duplicate pipeline subobject type %u.\n", subobject_type);
return E_INVALIDARG;
}
defined_subobjects |= subobject_bit;
start = align(sizeof(subobject_type), subobject_info[subobject_type].alignment);
size = subobject_info[subobject_type].size;
if (!vkd3d_bound_range(start, size, d3d12_desc->SizeInBytes - i))
{
WARN("Invalid pipeline state stream.\n");
return E_INVALIDARG;
}
memcpy(&desc_bytes[subobject_info[subobject_type].dst_offset], &stream_ptr[i + start], size);
/* Stream packets are aligned to the size of pointers. */
i += align(start + size, sizeof(void *));
}
/* Deduce pipeline type from specified shaders. */
if (desc->vs.BytecodeLength && desc->vs.pShaderBytecode)
{
*vk_bind_point = VK_PIPELINE_BIND_POINT_GRAPHICS;
}
else if (desc->cs.BytecodeLength && desc->cs.pShaderBytecode)
{
*vk_bind_point = VK_PIPELINE_BIND_POINT_COMPUTE;
}
else
{
WARN("Cannot deduce pipeline type from shader stages.\n");
return E_INVALIDARG;
}
if (desc->vs.BytecodeLength && desc->vs.pShaderBytecode
&& desc->cs.BytecodeLength && desc->cs.pShaderBytecode)
{
WARN("Invalid combination of shader stages VS and CS.\n");
return E_INVALIDARG;
}
return S_OK;
}
struct vkd3d_pipeline_key
{
D3D12_PRIMITIVE_TOPOLOGY topology;
@ -1959,7 +2142,7 @@ static HRESULT create_shader_stage(struct d3d12_device *device,
const struct vkd3d_shader_compile_option options[] =
{
{VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_9},
{VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_10},
{VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV, typed_uav_compile_option(device)},
{VKD3D_SHADER_COMPILE_OPTION_WRITE_TESS_GEOM_POINT_SIZE, 0},
};
@ -2013,7 +2196,7 @@ static int vkd3d_scan_dxbc(const struct d3d12_device *device, const D3D12_SHADER
const struct vkd3d_shader_compile_option options[] =
{
{VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_9},
{VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_10},
{VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV, typed_uav_compile_option(device)},
};
@ -2193,7 +2376,7 @@ static HRESULT d3d12_pipeline_state_find_and_init_uav_counters(struct d3d12_pipe
}
static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *state,
struct d3d12_device *device, const D3D12_COMPUTE_PIPELINE_STATE_DESC *desc)
struct d3d12_device *device, const struct d3d12_pipeline_state_desc *desc)
{
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
struct vkd3d_shader_interface_info shader_interface;
@ -2208,14 +2391,14 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
memset(&state->uav_counters, 0, sizeof(state->uav_counters));
if (!(root_signature = unsafe_impl_from_ID3D12RootSignature(desc->pRootSignature)))
if (!(root_signature = unsafe_impl_from_ID3D12RootSignature(desc->root_signature)))
{
WARN("Root signature is NULL.\n");
return E_INVALIDARG;
}
if (FAILED(hr = d3d12_pipeline_state_find_and_init_uav_counters(state, device, root_signature,
&desc->CS, VK_SHADER_STAGE_COMPUTE_BIT)))
&desc->cs, VK_SHADER_STAGE_COMPUTE_BIT)))
return hr;
memset(&target_info, 0, sizeof(target_info));
@ -2256,7 +2439,7 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
vk_pipeline_layout = state->uav_counters.vk_pipeline_layout
? state->uav_counters.vk_pipeline_layout : root_signature->vk_pipeline_layout;
if (FAILED(hr = vkd3d_create_compute_pipeline(device, &desc->CS, &shader_interface,
if (FAILED(hr = vkd3d_create_compute_pipeline(device, &desc->cs, &shader_interface,
vk_pipeline_layout, &state->u.compute.vk_pipeline)))
{
WARN("Failed to create Vulkan compute pipeline, hr %#x.\n", hr);
@ -2280,13 +2463,16 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
HRESULT d3d12_pipeline_state_create_compute(struct d3d12_device *device,
const D3D12_COMPUTE_PIPELINE_STATE_DESC *desc, struct d3d12_pipeline_state **state)
{
struct d3d12_pipeline_state_desc pipeline_desc;
struct d3d12_pipeline_state *object;
HRESULT hr;
pipeline_state_desc_from_d3d12_compute_desc(&pipeline_desc, desc);
if (!(object = vkd3d_malloc(sizeof(*object))))
return E_OUTOFMEMORY;
if (FAILED(hr = d3d12_pipeline_state_init_compute(object, device, desc)))
if (FAILED(hr = d3d12_pipeline_state_init_compute(object, device, &pipeline_desc)))
{
vkd3d_free(object);
return hr;
@ -2457,7 +2643,7 @@ static void vk_stencil_op_state_from_d3d12(struct VkStencilOpState *vk_desc,
}
static void ds_desc_from_d3d12(struct VkPipelineDepthStencilStateCreateInfo *vk_desc,
const D3D12_DEPTH_STENCIL_DESC *d3d12_desc)
const D3D12_DEPTH_STENCIL_DESC1 *d3d12_desc)
{
memset(vk_desc, 0, sizeof(*vk_desc));
vk_desc->sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
@ -2473,7 +2659,7 @@ static void ds_desc_from_d3d12(struct VkPipelineDepthStencilStateCreateInfo *vk_
vk_desc->depthWriteEnable = VK_FALSE;
vk_desc->depthCompareOp = VK_COMPARE_OP_NEVER;
}
vk_desc->depthBoundsTestEnable = VK_FALSE;
vk_desc->depthBoundsTestEnable = d3d12_desc->DepthBoundsTestEnable;
if ((vk_desc->stencilTestEnable = d3d12_desc->StencilEnable))
{
vk_stencil_op_state_from_d3d12(&vk_desc->front, &d3d12_desc->FrontFace,
@ -2738,12 +2924,12 @@ static VkLogicOp vk_logic_op_from_d3d12(D3D12_LOGIC_OP op)
}
static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *state,
struct d3d12_device *device, const D3D12_GRAPHICS_PIPELINE_STATE_DESC *desc)
struct d3d12_device *device, const struct d3d12_pipeline_state_desc *desc)
{
unsigned int ps_output_swizzle[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT];
struct d3d12_graphics_pipeline_state *graphics = &state->u.graphics;
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
const D3D12_STREAM_OUTPUT_DESC *so_desc = &desc->StreamOutput;
const D3D12_STREAM_OUTPUT_DESC *so_desc = &desc->stream_output;
VkVertexInputBindingDivisorDescriptionEXT *binding_divisor;
const struct vkd3d_vulkan_info *vk_info = &device->vk_info;
uint32_t instance_divisors[D3D12_VS_INPUT_REGISTER_COUNT];
@ -2787,11 +2973,11 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
}
shader_stages[] =
{
{VK_SHADER_STAGE_VERTEX_BIT, offsetof(D3D12_GRAPHICS_PIPELINE_STATE_DESC, VS)},
{VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, offsetof(D3D12_GRAPHICS_PIPELINE_STATE_DESC, HS)},
{VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, offsetof(D3D12_GRAPHICS_PIPELINE_STATE_DESC, DS)},
{VK_SHADER_STAGE_GEOMETRY_BIT, offsetof(D3D12_GRAPHICS_PIPELINE_STATE_DESC, GS)},
{VK_SHADER_STAGE_FRAGMENT_BIT, offsetof(D3D12_GRAPHICS_PIPELINE_STATE_DESC, PS)},
{VK_SHADER_STAGE_VERTEX_BIT, offsetof(struct d3d12_pipeline_state_desc, vs)},
{VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, offsetof(struct d3d12_pipeline_state_desc, hs)},
{VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, offsetof(struct d3d12_pipeline_state_desc, ds)},
{VK_SHADER_STAGE_GEOMETRY_BIT, offsetof(struct d3d12_pipeline_state_desc, gs)},
{VK_SHADER_STAGE_FRAGMENT_BIT, offsetof(struct d3d12_pipeline_state_desc, ps)},
};
state->ID3D12PipelineState_iface.lpVtbl = &d3d12_pipeline_state_vtbl;
@ -2802,26 +2988,26 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
memset(&input_signature, 0, sizeof(input_signature));
for (i = desc->NumRenderTargets; i < ARRAY_SIZE(desc->RTVFormats); ++i)
for (i = desc->rtv_formats.NumRenderTargets; i < ARRAY_SIZE(desc->rtv_formats.RTFormats); ++i)
{
if (desc->RTVFormats[i] != DXGI_FORMAT_UNKNOWN)
if (desc->rtv_formats.RTFormats[i] != DXGI_FORMAT_UNKNOWN)
{
WARN("Format must be set to DXGI_FORMAT_UNKNOWN for inactive render targets.\n");
return E_INVALIDARG;
}
}
if (!(root_signature = unsafe_impl_from_ID3D12RootSignature(desc->pRootSignature)))
if (!(root_signature = unsafe_impl_from_ID3D12RootSignature(desc->root_signature)))
{
WARN("Root signature is NULL.\n");
return E_INVALIDARG;
}
sample_count = vk_samples_from_dxgi_sample_desc(&desc->SampleDesc);
if (desc->SampleDesc.Count != 1 && desc->SampleDesc.Quality)
WARN("Ignoring sample quality %u.\n", desc->SampleDesc.Quality);
sample_count = vk_samples_from_dxgi_sample_desc(&desc->sample_desc);
if (desc->sample_desc.Count != 1 && desc->sample_desc.Quality)
WARN("Ignoring sample quality %u.\n", desc->sample_desc.Quality);
rt_count = desc->NumRenderTargets;
rt_count = desc->rtv_formats.NumRenderTargets;
if (rt_count > ARRAY_SIZE(graphics->blend_attachments))
{
FIXME("NumRenderTargets %zu > %zu, ignoring extra formats.\n",
@ -2829,40 +3015,40 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
rt_count = ARRAY_SIZE(graphics->blend_attachments);
}
graphics->om_logic_op_enable = desc->BlendState.RenderTarget[0].LogicOpEnable
graphics->om_logic_op_enable = desc->blend_state.RenderTarget[0].LogicOpEnable
&& device->feature_options.OutputMergerLogicOp;
graphics->om_logic_op = graphics->om_logic_op_enable
? vk_logic_op_from_d3d12(desc->BlendState.RenderTarget[0].LogicOp)
? vk_logic_op_from_d3d12(desc->blend_state.RenderTarget[0].LogicOp)
: VK_LOGIC_OP_COPY;
if (desc->BlendState.RenderTarget[0].LogicOpEnable && !graphics->om_logic_op_enable)
if (desc->blend_state.RenderTarget[0].LogicOpEnable && !graphics->om_logic_op_enable)
WARN("The device does not support output merger logic ops. Ignoring logic op %#x.\n",
desc->BlendState.RenderTarget[0].LogicOp);
desc->blend_state.RenderTarget[0].LogicOp);
graphics->null_attachment_mask = 0;
for (i = 0; i < rt_count; ++i)
{
const D3D12_RENDER_TARGET_BLEND_DESC *rt_desc;
if (desc->RTVFormats[i] == DXGI_FORMAT_UNKNOWN)
if (desc->rtv_formats.RTFormats[i] == DXGI_FORMAT_UNKNOWN)
{
graphics->null_attachment_mask |= 1u << i;
ps_output_swizzle[i] = VKD3D_SHADER_NO_SWIZZLE;
graphics->rtv_formats[i] = VK_FORMAT_UNDEFINED;
}
else if ((format = vkd3d_get_format(device, desc->RTVFormats[i], false)))
else if ((format = vkd3d_get_format(device, desc->rtv_formats.RTFormats[i], false)))
{
ps_output_swizzle[i] = vkd3d_get_rt_format_swizzle(format);
graphics->rtv_formats[i] = format->vk_format;
}
else
{
WARN("Invalid RTV format %#x.\n", desc->RTVFormats[i]);
WARN("Invalid RTV format %#x.\n", desc->rtv_formats.RTFormats[i]);
hr = E_INVALIDARG;
goto fail;
}
rt_desc = &desc->BlendState.RenderTarget[desc->BlendState.IndependentBlendEnable ? i : 0];
if (desc->BlendState.IndependentBlendEnable && rt_desc->LogicOpEnable)
rt_desc = &desc->blend_state.RenderTarget[desc->blend_state.IndependentBlendEnable ? i : 0];
if (desc->blend_state.IndependentBlendEnable && rt_desc->LogicOpEnable)
{
WARN("IndependentBlendEnable must be FALSE when logic operations are enabled.\n");
hr = E_INVALIDARG;
@ -2881,8 +3067,14 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
graphics->rtv_formats[i] = VK_FORMAT_UNDEFINED;
graphics->rt_count = rt_count;
ds_desc_from_d3d12(&graphics->ds_desc, &desc->DepthStencilState);
if (desc->DSVFormat == DXGI_FORMAT_UNKNOWN
ds_desc_from_d3d12(&graphics->ds_desc, &desc->depth_stencil_state);
if (graphics->ds_desc.depthBoundsTestEnable && !device->feature_options2.DepthBoundsTestSupported)
{
WARN("Depth bounds test not supported by device.\n");
hr = E_INVALIDARG;
goto fail;
}
if (desc->dsv_format == DXGI_FORMAT_UNKNOWN
&& graphics->ds_desc.depthTestEnable && !graphics->ds_desc.depthWriteEnable
&& graphics->ds_desc.depthCompareOp == VK_COMPARE_OP_ALWAYS && !graphics->ds_desc.stencilTestEnable)
{
@ -2891,15 +3083,16 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
}
graphics->dsv_format = VK_FORMAT_UNDEFINED;
if (graphics->ds_desc.depthTestEnable || graphics->ds_desc.stencilTestEnable)
if (graphics->ds_desc.depthTestEnable || graphics->ds_desc.stencilTestEnable
|| graphics->ds_desc.depthBoundsTestEnable)
{
if (desc->DSVFormat == DXGI_FORMAT_UNKNOWN)
if (desc->dsv_format == DXGI_FORMAT_UNKNOWN)
{
WARN("DSV format is DXGI_FORMAT_UNKNOWN.\n");
graphics->dsv_format = VK_FORMAT_UNDEFINED;
graphics->null_attachment_mask |= dsv_attachment_mask(graphics);
}
else if ((format = vkd3d_get_format(device, desc->DSVFormat, true)))
else if ((format = vkd3d_get_format(device, desc->dsv_format, true)))
{
if (!(format->vk_aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)))
FIXME("Format %#x is not depth/stencil format.\n", format->dxgi_format);
@ -2908,12 +3101,12 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
}
else
{
WARN("Invalid DSV format %#x.\n", desc->DSVFormat);
WARN("Invalid DSV format %#x.\n", desc->dsv_format);
hr = E_INVALIDARG;
goto fail;
}
if (!desc->PS.pShaderBytecode)
if (!desc->ps.pShaderBytecode)
{
if (FAILED(hr = create_shader_stage(device, &graphics->stages[graphics->stage_count],
VK_SHADER_STAGE_FRAGMENT_BIT, &default_ps, NULL)))
@ -2936,7 +3129,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
ps_target_info.extension_count = vk_info->shader_extension_count;
ps_target_info.parameters = ps_shader_parameters;
ps_target_info.parameter_count = ARRAY_SIZE(ps_shader_parameters);
ps_target_info.dual_source_blending = is_dual_source_blending(&desc->BlendState.RenderTarget[0]);
ps_target_info.dual_source_blending = is_dual_source_blending(&desc->blend_state.RenderTarget[0]);
ps_target_info.output_swizzles = ps_output_swizzle;
ps_target_info.output_swizzle_count = rt_count;
@ -2946,11 +3139,11 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
hr = E_INVALIDARG;
goto fail;
}
if (ps_target_info.dual_source_blending && desc->BlendState.IndependentBlendEnable)
if (ps_target_info.dual_source_blending && desc->blend_state.IndependentBlendEnable)
{
for (i = 1; i < ARRAY_SIZE(desc->BlendState.RenderTarget); ++i)
for (i = 1; i < ARRAY_SIZE(desc->blend_state.RenderTarget); ++i)
{
if (desc->BlendState.RenderTarget[i].BlendEnable)
if (desc->blend_state.RenderTarget[i].BlendEnable)
{
WARN("Blend enable cannot be set for render target %u when dual source blending is used.\n", i);
hr = E_INVALIDARG;
@ -2992,9 +3185,9 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
xfb_info.buffer_strides = so_desc->pBufferStrides;
xfb_info.buffer_stride_count = so_desc->NumStrides;
if (desc->GS.pShaderBytecode)
if (desc->gs.pShaderBytecode)
xfb_stage = VK_SHADER_STAGE_GEOMETRY_BIT;
else if (desc->DS.pShaderBytecode)
else if (desc->ds.pShaderBytecode)
xfb_stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
else
xfb_stage = VK_SHADER_STAGE_VERTEX_BIT;
@ -3046,7 +3239,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
if (desc->PrimitiveTopologyType != D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH)
if (desc->primitive_topology_type != D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH)
{
WARN("D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH must be used with tessellation shaders.\n");
hr = E_INVALIDARG;
@ -3088,7 +3281,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
++graphics->stage_count;
}
graphics->attribute_count = desc->InputLayout.NumElements;
graphics->attribute_count = desc->input_layout.NumElements;
if (graphics->attribute_count > ARRAY_SIZE(graphics->attributes))
{
FIXME("InputLayout.NumElements %zu > %zu, ignoring extra elements.\n",
@ -3104,13 +3297,13 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
goto fail;
}
if (FAILED(hr = compute_input_layout_offsets(device, &desc->InputLayout, aligned_offsets)))
if (FAILED(hr = compute_input_layout_offsets(device, &desc->input_layout, aligned_offsets)))
goto fail;
graphics->instance_divisor_count = 0;
for (i = 0, j = 0, mask = 0; i < graphics->attribute_count; ++i)
{
const D3D12_INPUT_ELEMENT_DESC *e = &desc->InputLayout.pInputElementDescs[i];
const D3D12_INPUT_ELEMENT_DESC *e = &desc->input_layout.pInputElementDescs[i];
const struct vkd3d_shader_signature_element *signature_element;
/* TODO: DXGI_FORMAT_UNKNOWN will succeed here, which may not match
@ -3194,30 +3387,30 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
graphics->attribute_count = j;
vkd3d_shader_free_shader_signature(&input_signature);
switch (desc->IBStripCutValue)
switch (desc->strip_cut_value)
{
case D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED:
case D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF:
case D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF:
graphics->index_buffer_strip_cut_value = desc->IBStripCutValue;
graphics->index_buffer_strip_cut_value = desc->strip_cut_value;
break;
default:
WARN("Invalid index buffer strip cut value %#x.\n", desc->IBStripCutValue);
WARN("Invalid index buffer strip cut value %#x.\n", desc->strip_cut_value);
hr = E_INVALIDARG;
goto fail;
}
is_dsv_format_unknown = graphics->null_attachment_mask & dsv_attachment_mask(graphics);
rs_desc_from_d3d12(&graphics->rs_desc, &desc->RasterizerState);
rs_desc_from_d3d12(&graphics->rs_desc, &desc->rasterizer_state);
have_attachment = graphics->rt_count || graphics->dsv_format || is_dsv_format_unknown;
if ((!have_attachment && !(desc->PS.pShaderBytecode && desc->PS.BytecodeLength))
if ((!have_attachment && !(desc->ps.pShaderBytecode && desc->ps.BytecodeLength))
|| (graphics->xfb_enabled && so_desc->RasterizedStream == D3D12_SO_NO_RASTERIZED_STREAM))
graphics->rs_desc.rasterizerDiscardEnable = VK_TRUE;
rs_stream_info_from_d3d12(&graphics->rs_stream_info, &graphics->rs_desc, so_desc, vk_info);
if (vk_info->EXT_depth_clip_enable)
rs_depth_clip_info_from_d3d12(&graphics->rs_depth_clip_info, &graphics->rs_desc, &desc->RasterizerState);
rs_depth_clip_info_from_d3d12(&graphics->rs_depth_clip_info, &graphics->rs_desc, &desc->rasterizer_state);
graphics->ms_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
graphics->ms_desc.pNext = NULL;
@ -3226,17 +3419,24 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
graphics->ms_desc.sampleShadingEnable = VK_FALSE;
graphics->ms_desc.minSampleShading = 0.0f;
graphics->ms_desc.pSampleMask = NULL;
if (desc->SampleMask != ~0u)
if (desc->sample_mask != ~0u)
{
assert(DIV_ROUND_UP(sample_count, 32) <= ARRAY_SIZE(graphics->sample_mask));
graphics->sample_mask[0] = desc->SampleMask;
graphics->sample_mask[0] = desc->sample_mask;
graphics->sample_mask[1] = 0xffffffffu;
graphics->ms_desc.pSampleMask = graphics->sample_mask;
}
graphics->ms_desc.alphaToCoverageEnable = desc->BlendState.AlphaToCoverageEnable;
graphics->ms_desc.alphaToCoverageEnable = desc->blend_state.AlphaToCoverageEnable;
graphics->ms_desc.alphaToOneEnable = VK_FALSE;
/* We defer creating the render pass for pipelines wth DSVFormat equal to
if (desc->view_instancing_desc.ViewInstanceCount)
{
FIXME("View instancing is not supported yet.\n");
hr = E_INVALIDARG;
goto fail;
}
/* We defer creating the render pass for pipelines with DSVFormat equal to
* DXGI_FORMAT_UNKNOWN. We take the actual DSV format from the bound DSV. */
if (is_dsv_format_unknown)
graphics->render_pass = VK_NULL_HANDLE;
@ -3271,13 +3471,16 @@ fail:
HRESULT d3d12_pipeline_state_create_graphics(struct d3d12_device *device,
const D3D12_GRAPHICS_PIPELINE_STATE_DESC *desc, struct d3d12_pipeline_state **state)
{
struct d3d12_pipeline_state_desc pipeline_desc;
struct d3d12_pipeline_state *object;
HRESULT hr;
pipeline_state_desc_from_d3d12_graphics_desc(&pipeline_desc, desc);
if (!(object = vkd3d_malloc(sizeof(*object))))
return E_OUTOFMEMORY;
if (FAILED(hr = d3d12_pipeline_state_init_graphics(object, device, desc)))
if (FAILED(hr = d3d12_pipeline_state_init_graphics(object, device, &pipeline_desc)))
{
vkd3d_free(object);
return hr;
@ -3290,6 +3493,46 @@ HRESULT d3d12_pipeline_state_create_graphics(struct d3d12_device *device,
return S_OK;
}
HRESULT d3d12_pipeline_state_create(struct d3d12_device *device,
const D3D12_PIPELINE_STATE_STREAM_DESC *desc, struct d3d12_pipeline_state **state)
{
struct d3d12_pipeline_state_desc pipeline_desc;
struct d3d12_pipeline_state *object;
VkPipelineBindPoint bind_point;
HRESULT hr;
if (FAILED(hr = pipeline_state_desc_from_d3d12_stream_desc(&pipeline_desc, desc, &bind_point)))
return hr;
if (!(object = vkd3d_calloc(1, sizeof(*object))))
return E_OUTOFMEMORY;
switch (bind_point)
{
case VK_PIPELINE_BIND_POINT_COMPUTE:
hr = d3d12_pipeline_state_init_compute(object, device, &pipeline_desc);
break;
case VK_PIPELINE_BIND_POINT_GRAPHICS:
hr = d3d12_pipeline_state_init_graphics(object, device, &pipeline_desc);
break;
default:
vkd3d_unreachable();
}
if (FAILED(hr))
{
vkd3d_free(object);
return hr;
}
TRACE("Created pipeline state %p.\n", object);
*state = object;
return S_OK;
}
static enum VkPrimitiveTopology vk_topology_from_d3d12_topology(D3D12_PRIMITIVE_TOPOLOGY topology)
{
switch (topology)
@ -3605,6 +3848,36 @@ VkPipeline d3d12_pipeline_state_get_or_create_pipeline(struct d3d12_pipeline_sta
return vk_pipeline;
}
static int compile_hlsl_cs(const struct vkd3d_shader_code *hlsl, struct vkd3d_shader_code *dxbc)
{
struct vkd3d_shader_hlsl_source_info hlsl_info;
struct vkd3d_shader_compile_info info;
static const struct vkd3d_shader_compile_option options[] =
{
{VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_10},
};
info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO;
info.next = &hlsl_info;
info.source = *hlsl;
info.source_type = VKD3D_SHADER_SOURCE_HLSL;
info.target_type = VKD3D_SHADER_TARGET_DXBC_TPF;
info.options = options;
info.option_count = ARRAY_SIZE(options);
info.log_level = VKD3D_SHADER_LOG_NONE;
info.source_name = NULL;
hlsl_info.type = VKD3D_SHADER_STRUCTURE_TYPE_HLSL_SOURCE_INFO;
hlsl_info.next = NULL;
hlsl_info.entry_point = "main";
hlsl_info.secondary_code.code = NULL;
hlsl_info.secondary_code.size = 0;
hlsl_info.profile = "cs_5_0";
return vkd3d_shader_compile(&info, dxbc, NULL);
}
static void vkd3d_uav_clear_pipelines_cleanup(struct vkd3d_uav_clear_pipelines *pipelines,
struct d3d12_device *device)
{
@ -3658,7 +3931,7 @@ HRESULT vkd3d_uav_clear_state_init(struct vkd3d_uav_clear_state *state, struct d
{
VkPipeline *pipeline;
VkPipelineLayout *pipeline_layout;
D3D12_SHADER_BYTECODE code;
struct vkd3d_shader_code code;
}
pipelines[] =
{
@ -3748,13 +4021,25 @@ HRESULT vkd3d_uav_clear_state_init(struct vkd3d_uav_clear_state *state, struct d
for (i = 0; i < ARRAY_SIZE(pipelines); ++i)
{
struct vkd3d_shader_code dxbc;
int ret;
if ((ret = compile_hlsl_cs(&pipelines[i].code, &dxbc)))
{
ERR("Failed to compile HLSL compute shader %u, ret %d.\n", i, ret);
hr = hresult_from_vk_result(ret);
goto fail;
}
if (pipelines[i].pipeline_layout == &state->vk_pipeline_layout_buffer)
binding.flags = VKD3D_SHADER_BINDING_FLAG_BUFFER;
else
binding.flags = VKD3D_SHADER_BINDING_FLAG_IMAGE;
if (FAILED(hr = vkd3d_create_compute_pipeline(device, &pipelines[i].code, &shader_interface,
*pipelines[i].pipeline_layout, pipelines[i].pipeline)))
hr = vkd3d_create_compute_pipeline(device, &(D3D12_SHADER_BYTECODE){dxbc.code, dxbc.size},
&shader_interface, *pipelines[i].pipeline_layout, pipelines[i].pipeline);
vkd3d_shader_free_shader_code(&dxbc);
if (FAILED(hr))
{
ERR("Failed to create compute pipeline %u, hr %#x.\n", i, hr);
goto fail;

View file

@ -71,11 +71,11 @@ HRESULT vkd3d_create_device(const struct vkd3d_device_create_info *create_info,
if (!device)
{
ID3D12Device_Release(&object->ID3D12Device1_iface);
ID3D12Device_Release(&object->ID3D12Device5_iface);
return S_FALSE;
}
return return_interface(&object->ID3D12Device1_iface, &IID_ID3D12Device, iid, device);
return return_interface(&object->ID3D12Device5_iface, &IID_ID3D12Device, iid, device);
}
/* ID3D12RootSignatureDeserializer */

View file

@ -22,6 +22,7 @@
#define COBJMACROS
#define NONAMELESSUNION
#define VK_NO_PROTOTYPES
#define CONST_VTABLE
#ifdef _WIN32
# define _WIN32_WINNT 0x0600 /* for condition variables */
@ -121,6 +122,7 @@ struct vkd3d_vulkan_info
bool KHR_draw_indirect_count;
bool KHR_get_memory_requirements2;
bool KHR_image_format_list;
bool KHR_maintenance2;
bool KHR_maintenance3;
bool KHR_push_descriptor;
bool KHR_sampler_mirror_clamp_to_edge;
@ -680,7 +682,7 @@ struct d3d12_heap
};
HRESULT d3d12_heap_create(struct d3d12_device *device, const D3D12_HEAP_DESC *desc,
const struct d3d12_resource *resource, struct d3d12_heap **heap);
const struct d3d12_resource *resource, ID3D12ProtectedResourceSession *protected_session, struct d3d12_heap **heap);
struct d3d12_heap *unsafe_impl_from_ID3D12Heap(ID3D12Heap *iface);
#define VKD3D_RESOURCE_PUBLIC_FLAGS \
@ -716,7 +718,7 @@ struct d3d12_resource_tile_info
/* ID3D12Resource */
struct d3d12_resource
{
ID3D12Resource ID3D12Resource_iface;
ID3D12Resource1 ID3D12Resource1_iface;
LONG refcount;
LONG internal_refcount;
@ -748,7 +750,12 @@ struct d3d12_resource
static inline struct d3d12_resource *impl_from_ID3D12Resource(ID3D12Resource *iface)
{
return CONTAINING_RECORD(iface, struct d3d12_resource, ID3D12Resource_iface);
return CONTAINING_RECORD(iface, struct d3d12_resource, ID3D12Resource1_iface);
}
static inline struct d3d12_resource *impl_from_ID3D12Resource1(ID3D12Resource1 *iface)
{
return CONTAINING_RECORD(iface, struct d3d12_resource, ID3D12Resource1_iface);
}
static inline bool d3d12_resource_is_buffer(const struct d3d12_resource *resource)
@ -771,7 +778,8 @@ void d3d12_resource_get_tiling(struct d3d12_device *device, const struct d3d12_r
HRESULT d3d12_committed_resource_create(struct d3d12_device *device,
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,
const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state,
const D3D12_CLEAR_VALUE *optimized_clear_value, struct d3d12_resource **resource);
const D3D12_CLEAR_VALUE *optimized_clear_value, ID3D12ProtectedResourceSession *protected_session,
struct d3d12_resource **resource);
HRESULT d3d12_placed_resource_create(struct d3d12_device *device, struct d3d12_heap *heap, uint64_t heap_offset,
const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state,
const D3D12_CLEAR_VALUE *optimized_clear_value, struct d3d12_resource **resource);
@ -835,6 +843,7 @@ struct vkd3d_texture_view_desc
VkImageAspectFlags vk_image_aspect;
VkComponentMapping components;
bool allowed_swizzle;
VkImageUsageFlags usage;
};
struct vkd3d_desc_header
@ -1090,7 +1099,7 @@ HRESULT d3d12_query_heap_create(struct d3d12_device *device,
struct d3d12_query_heap *unsafe_impl_from_ID3D12QueryHeap(ID3D12QueryHeap *iface);
/* A Vulkan query has to be issued at least one time before the result is
* available. In D3D12 it is legal to get query reults for not issued queries.
* available. In D3D12 it is legal to get query results for not issued queries.
*/
static inline bool d3d12_query_heap_is_result_available(const struct d3d12_query_heap *heap,
unsigned int query_index)
@ -1308,10 +1317,38 @@ static inline bool d3d12_pipeline_state_has_unknown_dsv_format(struct d3d12_pipe
return false;
}
struct d3d12_pipeline_state_desc
{
ID3D12RootSignature *root_signature;
D3D12_SHADER_BYTECODE vs;
D3D12_SHADER_BYTECODE ps;
D3D12_SHADER_BYTECODE ds;
D3D12_SHADER_BYTECODE hs;
D3D12_SHADER_BYTECODE gs;
D3D12_SHADER_BYTECODE cs;
D3D12_STREAM_OUTPUT_DESC stream_output;
D3D12_BLEND_DESC blend_state;
unsigned int sample_mask;
D3D12_RASTERIZER_DESC rasterizer_state;
D3D12_DEPTH_STENCIL_DESC1 depth_stencil_state;
D3D12_INPUT_LAYOUT_DESC input_layout;
D3D12_INDEX_BUFFER_STRIP_CUT_VALUE strip_cut_value;
D3D12_PRIMITIVE_TOPOLOGY_TYPE primitive_topology_type;
struct D3D12_RT_FORMAT_ARRAY rtv_formats;
DXGI_FORMAT dsv_format;
DXGI_SAMPLE_DESC sample_desc;
D3D12_VIEW_INSTANCING_DESC view_instancing_desc;
unsigned int node_mask;
D3D12_CACHED_PIPELINE_STATE cached_pso;
D3D12_PIPELINE_STATE_FLAGS flags;
};
HRESULT d3d12_pipeline_state_create_compute(struct d3d12_device *device,
const D3D12_COMPUTE_PIPELINE_STATE_DESC *desc, struct d3d12_pipeline_state **state);
HRESULT d3d12_pipeline_state_create_graphics(struct d3d12_device *device,
const D3D12_GRAPHICS_PIPELINE_STATE_DESC *desc, struct d3d12_pipeline_state **state);
HRESULT d3d12_pipeline_state_create(struct d3d12_device *device,
const D3D12_PIPELINE_STATE_STREAM_DESC *desc, struct d3d12_pipeline_state **state);
VkPipeline d3d12_pipeline_state_get_or_create_pipeline(struct d3d12_pipeline_state *state,
D3D12_PRIMITIVE_TOPOLOGY topology, const uint32_t *strides, VkFormat dsv_format, VkRenderPass *vk_render_pass);
struct d3d12_pipeline_state *unsafe_impl_from_ID3D12PipelineState(ID3D12PipelineState *iface);
@ -1426,7 +1463,7 @@ enum vkd3d_pipeline_bind_point
/* ID3D12CommandList */
struct d3d12_command_list
{
ID3D12GraphicsCommandList3 ID3D12GraphicsCommandList3_iface;
ID3D12GraphicsCommandList5 ID3D12GraphicsCommandList5_iface;
LONG refcount;
D3D12_COMMAND_LIST_TYPE type;
@ -1709,7 +1746,7 @@ struct vkd3d_desc_object_cache
/* ID3D12Device */
struct d3d12_device
{
ID3D12Device1 ID3D12Device1_iface;
ID3D12Device5 ID3D12Device5_iface;
LONG refcount;
VkDevice vk_device;
@ -1775,27 +1812,27 @@ struct vkd3d_queue *d3d12_device_get_vkd3d_queue(struct d3d12_device *device, D3
bool d3d12_device_is_uma(struct d3d12_device *device, bool *coherent);
void d3d12_device_mark_as_removed(struct d3d12_device *device, HRESULT reason,
const char *message, ...) VKD3D_PRINTF_FUNC(3, 4);
struct d3d12_device *unsafe_impl_from_ID3D12Device1(ID3D12Device1 *iface);
struct d3d12_device *unsafe_impl_from_ID3D12Device5(ID3D12Device5 *iface);
static inline HRESULT d3d12_device_query_interface(struct d3d12_device *device, REFIID iid, void **object)
{
return ID3D12Device1_QueryInterface(&device->ID3D12Device1_iface, iid, object);
return ID3D12Device5_QueryInterface(&device->ID3D12Device5_iface, iid, object);
}
static inline ULONG d3d12_device_add_ref(struct d3d12_device *device)
{
return ID3D12Device1_AddRef(&device->ID3D12Device1_iface);
return ID3D12Device5_AddRef(&device->ID3D12Device5_iface);
}
static inline ULONG d3d12_device_release(struct d3d12_device *device)
{
return ID3D12Device1_Release(&device->ID3D12Device1_iface);
return ID3D12Device5_Release(&device->ID3D12Device5_iface);
}
static inline unsigned int d3d12_device_get_descriptor_handle_increment_size(struct d3d12_device *device,
D3D12_DESCRIPTOR_HEAP_TYPE descriptor_type)
{
return ID3D12Device1_GetDescriptorHandleIncrementSize(&device->ID3D12Device1_iface, descriptor_type);
return ID3D12Device5_GetDescriptorHandleIncrementSize(&device->ID3D12Device5_iface, descriptor_type);
}
/* utils */

View file

@ -19,370 +19,208 @@
#ifndef __VKD3D_SHADERS_H
#define __VKD3D_SHADERS_H
static const uint32_t cs_uav_clear_buffer_float_code[] =
{
#if 0
RWBuffer<float4> dst;
static const char cs_uav_clear_buffer_float_code[] =
"RWBuffer<float4> dst;\n"
"\n"
"struct\n"
"{\n"
" float4 clear_value;\n"
" int2 dst_offset;\n"
" int2 dst_extent;\n"
"} u_info;\n"
"\n"
"[numthreads(128, 1, 1)]\n"
"void main(int3 thread_id : SV_DispatchThreadID)\n"
"{\n"
" if (thread_id.x < u_info.dst_extent.x)\n"
" dst[u_info.dst_offset.x + thread_id.x] = u_info.clear_value;\n"
"}\n";
struct
{
float4 clear_value;
int2 dst_offset;
int2 dst_extent;
} u_info;
static const char cs_uav_clear_buffer_uint_code[] =
"RWBuffer<uint4> dst;\n"
"\n"
"struct\n"
"{\n"
" uint4 clear_value;\n"
" int2 dst_offset;\n"
" int2 dst_extent;\n"
"} u_info;\n"
"\n"
"[numthreads(128, 1, 1)]\n"
"void main(int3 thread_id : SV_DispatchThreadID)\n"
"{\n"
" if (thread_id.x < u_info.dst_extent.x)\n"
" dst[u_info.dst_offset.x + thread_id.x] = u_info.clear_value;\n"
"}\n";
[numthreads(128, 1, 1)]
void main(int3 thread_id : SV_DispatchThreadID)
{
if (thread_id.x < u_info.dst_extent.x)
dst[u_info.dst_offset.x + thread_id.x] = u_info.clear_value;
}
#endif
0x43425844, 0xe114ba61, 0xff6a0d0b, 0x7b25c8f4, 0xfcf7cf22, 0x00000001, 0x0000010c, 0x00000003,
0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000b8, 0x00050050, 0x0000002e, 0x0100086a,
0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0400089c, 0x0011e000, 0x00000000, 0x00005555,
0x0200005f, 0x00020012, 0x02000068, 0x00000001, 0x0400009b, 0x00000080, 0x00000001, 0x00000001,
0x07000022, 0x00100012, 0x00000000, 0x0002000a, 0x0020802a, 0x00000000, 0x00000001, 0x0304001f,
0x0010000a, 0x00000000, 0x0700001e, 0x00100012, 0x00000000, 0x0002000a, 0x0020800a, 0x00000000,
0x00000001, 0x080000a4, 0x0011e0f2, 0x00000000, 0x00100006, 0x00000000, 0x00208e46, 0x00000000,
0x00000000, 0x01000015, 0x0100003e,
};
static const char cs_uav_clear_1d_array_float_code[] =
"RWTexture1DArray<float4> dst;\n"
"\n"
"struct\n"
"{\n"
" float4 clear_value;\n"
" int2 dst_offset;\n"
" int2 dst_extent;\n"
"} u_info;\n"
"\n"
"[numthreads(64, 1, 1)]\n"
"void main(int3 thread_id : SV_DispatchThreadID)\n"
"{\n"
" if (thread_id.x < u_info.dst_extent.x)\n"
" dst[int2(u_info.dst_offset.x + thread_id.x, thread_id.y)] = u_info.clear_value;\n"
"}\n";
static const uint32_t cs_uav_clear_buffer_uint_code[] =
{
#if 0
RWBuffer<uint4> dst;
static const char cs_uav_clear_1d_array_uint_code[] =
"RWTexture1DArray<uint4> dst;\n"
"\n"
"struct\n"
"{\n"
" uint4 clear_value;\n"
" int2 dst_offset;\n"
" int2 dst_extent;\n"
"} u_info;\n"
"\n"
"[numthreads(64, 1, 1)]\n"
"void main(int3 thread_id : SV_DispatchThreadID)\n"
"{\n"
" if (thread_id.x < u_info.dst_extent.x)\n"
" dst[int2(u_info.dst_offset.x + thread_id.x, thread_id.y)] = u_info.clear_value;\n"
"}\n";
struct
{
uint4 clear_value;
int2 dst_offset;
int2 dst_extent;
} u_info;
static const char cs_uav_clear_1d_float_code[] =
"RWTexture1D<float4> dst;\n"
"\n"
"struct\n"
"{\n"
" float4 clear_value;\n"
" int2 dst_offset;\n"
" int2 dst_extent;\n"
"} u_info;\n"
"\n"
"[numthreads(64, 1, 1)]\n"
"void main(int3 thread_id : SV_DispatchThreadID)\n"
"{\n"
" if (thread_id.x < u_info.dst_extent.x)\n"
" dst[u_info.dst_offset.x + thread_id.x] = u_info.clear_value;\n"
"}\n";
[numthreads(128, 1, 1)]
void main(int3 thread_id : SV_DispatchThreadID)
{
if (thread_id.x < u_info.dst_extent.x)
dst[u_info.dst_offset.x + thread_id.x] = u_info.clear_value;
}
#endif
0x43425844, 0x3afd0cfd, 0x5145c166, 0x5b9f76b8, 0xa73775cd, 0x00000001, 0x0000010c, 0x00000003,
0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000b8, 0x00050050, 0x0000002e, 0x0100086a,
0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0400089c, 0x0011e000, 0x00000000, 0x00004444,
0x0200005f, 0x00020012, 0x02000068, 0x00000001, 0x0400009b, 0x00000080, 0x00000001, 0x00000001,
0x07000022, 0x00100012, 0x00000000, 0x0002000a, 0x0020802a, 0x00000000, 0x00000001, 0x0304001f,
0x0010000a, 0x00000000, 0x0700001e, 0x00100012, 0x00000000, 0x0002000a, 0x0020800a, 0x00000000,
0x00000001, 0x080000a4, 0x0011e0f2, 0x00000000, 0x00100006, 0x00000000, 0x00208e46, 0x00000000,
0x00000000, 0x01000015, 0x0100003e,
};
static const char cs_uav_clear_1d_uint_code[] =
"RWTexture1D<uint4> dst;\n"
"\n"
"struct\n"
"{\n"
" uint4 clear_value;\n"
" int2 dst_offset;\n"
" int2 dst_extent;\n"
"} u_info;\n"
"\n"
"[numthreads(64, 1, 1)]\n"
"void main(int3 thread_id : SV_DispatchThreadID)\n"
"{\n"
" if (thread_id.x < u_info.dst_extent.x)\n"
" dst[u_info.dst_offset.x + thread_id.x] = u_info.clear_value;\n"
"}\n";
static const uint32_t cs_uav_clear_1d_array_float_code[] =
{
#if 0
RWTexture1DArray<float4> dst;
static const char cs_uav_clear_2d_array_float_code[] =
"RWTexture2DArray<float4> dst;\n"
"\n"
"struct\n"
"{\n"
" float4 clear_value;\n"
" int2 dst_offset;\n"
" int2 dst_extent;\n"
"} u_info;\n"
"\n"
"[numthreads(8, 8, 1)]\n"
"void main(int3 thread_id : SV_DispatchThreadID)\n"
"{\n"
" if (all(thread_id.xy < u_info.dst_extent.xy))\n"
" dst[int3(u_info.dst_offset.xy + thread_id.xy, thread_id.z)] = u_info.clear_value;\n"
"}\n";
struct
{
float4 clear_value;
int2 dst_offset;
int2 dst_extent;
} u_info;
static const char cs_uav_clear_2d_array_uint_code[] =
"RWTexture2DArray<uint4> dst;\n"
"\n"
"struct\n"
"{\n"
" uint4 clear_value;\n"
" int2 dst_offset;\n"
" int2 dst_extent;\n"
"} u_info;\n"
"\n"
"[numthreads(8, 8, 1)]\n"
"void main(int3 thread_id : SV_DispatchThreadID)\n"
"{\n"
" if (all(thread_id.xy < u_info.dst_extent.xy))\n"
" dst[int3(u_info.dst_offset.xy + thread_id.xy, thread_id.z)] = u_info.clear_value;\n"
"}\n";
[numthreads(64, 1, 1)]
void main(int3 thread_id : SV_DispatchThreadID)
{
if (thread_id.x < u_info.dst_extent.x)
dst[int2(u_info.dst_offset.x + thread_id.x, thread_id.y)] = u_info.clear_value;
}
#endif
0x43425844, 0x3d73bc2d, 0x2b635f3d, 0x6bf98e92, 0xbe0aa5d9, 0x00000001, 0x0000011c, 0x00000003,
0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000c8, 0x00050050, 0x00000032, 0x0100086a,
0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0400389c, 0x0011e000, 0x00000000, 0x00005555,
0x0200005f, 0x00020032, 0x02000068, 0x00000001, 0x0400009b, 0x00000040, 0x00000001, 0x00000001,
0x07000022, 0x00100012, 0x00000000, 0x0002000a, 0x0020802a, 0x00000000, 0x00000001, 0x0304001f,
0x0010000a, 0x00000000, 0x0700001e, 0x00100012, 0x00000000, 0x0002000a, 0x0020800a, 0x00000000,
0x00000001, 0x04000036, 0x001000e2, 0x00000000, 0x00020556, 0x080000a4, 0x0011e0f2, 0x00000000,
0x00100e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x01000015, 0x0100003e,
};
static const char cs_uav_clear_2d_float_code[] =
"RWTexture2D<float4> dst;\n"
"\n"
"struct\n"
"{\n"
" float4 clear_value;\n"
" int2 dst_offset;\n"
" int2 dst_extent;\n"
"} u_info;\n"
"\n"
"[numthreads(8, 8, 1)]\n"
"void main(int3 thread_id : SV_DispatchThreadID)\n"
"{\n"
" if (all(thread_id.xy < u_info.dst_extent.xy))\n"
" dst[u_info.dst_offset.xy + thread_id.xy] = u_info.clear_value;\n"
"}\n";
static const uint32_t cs_uav_clear_1d_array_uint_code[] =
{
#if 0
RWTexture1DArray<uint4> dst;
static const char cs_uav_clear_2d_uint_code[] =
"RWTexture2D<uint4> dst;\n"
"\n"
"struct\n"
"{\n"
" uint4 clear_value;\n"
" int2 dst_offset;\n"
" int2 dst_extent;\n"
"} u_info;\n"
"\n"
"[numthreads(8, 8, 1)]\n"
"void main(int3 thread_id : SV_DispatchThreadID)\n"
"{\n"
" if (all(thread_id.xy < u_info.dst_extent.xy))\n"
" dst[u_info.dst_offset.xy + thread_id.xy] = u_info.clear_value;\n"
"}\n";
struct
{
uint4 clear_value;
int2 dst_offset;
int2 dst_extent;
} u_info;
static const char cs_uav_clear_3d_float_code[] =
"RWTexture3D<float4> dst;\n"
"\n"
"struct\n"
"{\n"
" float4 clear_value;\n"
" int2 dst_offset;\n"
" int2 dst_extent;\n"
"} u_info;\n"
"\n"
"[numthreads(8, 8, 1)]\n"
"void main(int3 thread_id : SV_DispatchThreadID)\n"
"{\n"
" if (all(thread_id.xy < u_info.dst_extent.xy))\n"
" dst[int3(u_info.dst_offset.xy, 0) + thread_id.xyz] = u_info.clear_value;\n"
"}\n";
[numthreads(64, 1, 1)]
void main(int3 thread_id : SV_DispatchThreadID)
{
if (thread_id.x < u_info.dst_extent.x)
dst[int2(u_info.dst_offset.x + thread_id.x, thread_id.y)] = u_info.clear_value;
}
#endif
0x43425844, 0x2f0ca457, 0x72068b34, 0xd9dadc2b, 0xd3178c3e, 0x00000001, 0x0000011c, 0x00000003,
0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000c8, 0x00050050, 0x00000032, 0x0100086a,
0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0400389c, 0x0011e000, 0x00000000, 0x00004444,
0x0200005f, 0x00020032, 0x02000068, 0x00000001, 0x0400009b, 0x00000040, 0x00000001, 0x00000001,
0x07000022, 0x00100012, 0x00000000, 0x0002000a, 0x0020802a, 0x00000000, 0x00000001, 0x0304001f,
0x0010000a, 0x00000000, 0x0700001e, 0x00100012, 0x00000000, 0x0002000a, 0x0020800a, 0x00000000,
0x00000001, 0x04000036, 0x001000e2, 0x00000000, 0x00020556, 0x080000a4, 0x0011e0f2, 0x00000000,
0x00100e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x01000015, 0x0100003e,
};
static const uint32_t cs_uav_clear_1d_float_code[] =
{
#if 0
RWTexture1D<float4> dst;
struct
{
float4 clear_value;
int2 dst_offset;
int2 dst_extent;
} u_info;
[numthreads(64, 1, 1)]
void main(int3 thread_id : SV_DispatchThreadID)
{
if (thread_id.x < u_info.dst_extent.x)
dst[u_info.dst_offset.x + thread_id.x] = u_info.clear_value;
}
#endif
0x43425844, 0x05266503, 0x4b97006f, 0x01a5cc63, 0xe617d0a1, 0x00000001, 0x0000010c, 0x00000003,
0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000b8, 0x00050050, 0x0000002e, 0x0100086a,
0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0400109c, 0x0011e000, 0x00000000, 0x00005555,
0x0200005f, 0x00020012, 0x02000068, 0x00000001, 0x0400009b, 0x00000040, 0x00000001, 0x00000001,
0x07000022, 0x00100012, 0x00000000, 0x0002000a, 0x0020802a, 0x00000000, 0x00000001, 0x0304001f,
0x0010000a, 0x00000000, 0x0700001e, 0x00100012, 0x00000000, 0x0002000a, 0x0020800a, 0x00000000,
0x00000001, 0x080000a4, 0x0011e0f2, 0x00000000, 0x00100006, 0x00000000, 0x00208e46, 0x00000000,
0x00000000, 0x01000015, 0x0100003e,
};
static const uint32_t cs_uav_clear_1d_uint_code[] =
{
#if 0
RWTexture1D<uint4> dst;
struct
{
uint4 clear_value;
int2 dst_offset;
int2 dst_extent;
} u_info;
[numthreads(64, 1, 1)]
void main(int3 thread_id : SV_DispatchThreadID)
{
if (thread_id.x < u_info.dst_extent.x)
dst[u_info.dst_offset.x + thread_id.x] = u_info.clear_value;
}
#endif
0x43425844, 0x19d5c8f2, 0x3ca4ac24, 0x9e258499, 0xf0463fd6, 0x00000001, 0x0000010c, 0x00000003,
0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000b8, 0x00050050, 0x0000002e, 0x0100086a,
0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0400109c, 0x0011e000, 0x00000000, 0x00004444,
0x0200005f, 0x00020012, 0x02000068, 0x00000001, 0x0400009b, 0x00000040, 0x00000001, 0x00000001,
0x07000022, 0x00100012, 0x00000000, 0x0002000a, 0x0020802a, 0x00000000, 0x00000001, 0x0304001f,
0x0010000a, 0x00000000, 0x0700001e, 0x00100012, 0x00000000, 0x0002000a, 0x0020800a, 0x00000000,
0x00000001, 0x080000a4, 0x0011e0f2, 0x00000000, 0x00100006, 0x00000000, 0x00208e46, 0x00000000,
0x00000000, 0x01000015, 0x0100003e,
};
static const uint32_t cs_uav_clear_2d_array_float_code[] =
{
#if 0
RWTexture2DArray<float4> dst;
struct
{
float4 clear_value;
int2 dst_offset;
int2 dst_extent;
} u_info;
[numthreads(8, 8, 1)]
void main(int3 thread_id : SV_DispatchThreadID)
{
if (all(thread_id.xy < u_info.dst_extent.xy))
dst[int3(u_info.dst_offset.xy + thread_id.xy, thread_id.z)] = u_info.clear_value;
}
#endif
0x43425844, 0x924d2d2c, 0xb9166376, 0x99f83871, 0x8ef65025, 0x00000001, 0x00000138, 0x00000003,
0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000e4, 0x00050050, 0x00000039, 0x0100086a,
0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0400409c, 0x0011e000, 0x00000000, 0x00005555,
0x0200005f, 0x00020072, 0x02000068, 0x00000001, 0x0400009b, 0x00000008, 0x00000008, 0x00000001,
0x07000022, 0x00100032, 0x00000000, 0x00020046, 0x00208ae6, 0x00000000, 0x00000001, 0x07000001,
0x00100012, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0304001f, 0x0010000a,
0x00000000, 0x0700001e, 0x00100032, 0x00000000, 0x00020046, 0x00208046, 0x00000000, 0x00000001,
0x04000036, 0x001000c2, 0x00000000, 0x00020aa6, 0x080000a4, 0x0011e0f2, 0x00000000, 0x00100e46,
0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x01000015, 0x0100003e,
};
static const uint32_t cs_uav_clear_2d_array_uint_code[] =
{
#if 0
RWTexture2DArray<uint4> dst;
struct
{
uint4 clear_value;
int2 dst_offset;
int2 dst_extent;
} u_info;
[numthreads(8, 8, 1)]
void main(int3 thread_id : SV_DispatchThreadID)
{
if (all(thread_id.xy < u_info.dst_extent.xy))
dst[int3(u_info.dst_offset.xy + thread_id.xy, thread_id.z)] = u_info.clear_value;
}
#endif
0x43425844, 0xa92219d4, 0xa2c5e47d, 0x0d308500, 0xf32197b4, 0x00000001, 0x00000138, 0x00000003,
0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000e4, 0x00050050, 0x00000039, 0x0100086a,
0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0400409c, 0x0011e000, 0x00000000, 0x00004444,
0x0200005f, 0x00020072, 0x02000068, 0x00000001, 0x0400009b, 0x00000008, 0x00000008, 0x00000001,
0x07000022, 0x00100032, 0x00000000, 0x00020046, 0x00208ae6, 0x00000000, 0x00000001, 0x07000001,
0x00100012, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0304001f, 0x0010000a,
0x00000000, 0x0700001e, 0x00100032, 0x00000000, 0x00020046, 0x00208046, 0x00000000, 0x00000001,
0x04000036, 0x001000c2, 0x00000000, 0x00020aa6, 0x080000a4, 0x0011e0f2, 0x00000000, 0x00100e46,
0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x01000015, 0x0100003e,
};
static const uint32_t cs_uav_clear_2d_float_code[] =
{
#if 0
RWTexture2D<float4> dst;
struct
{
float4 clear_value;
int2 dst_offset;
int2 dst_extent;
} u_info;
[numthreads(8, 8, 1)]
void main(int3 thread_id : SV_DispatchThreadID)
{
if (all(thread_id.xy < u_info.dst_extent.xy))
dst[u_info.dst_offset.xy + thread_id.xy] = u_info.clear_value;
}
#endif
0x43425844, 0x6e735b3f, 0x7348c4fa, 0xb3634e42, 0x50e2d99b, 0x00000001, 0x00000128, 0x00000003,
0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000d4, 0x00050050, 0x00000035, 0x0100086a,
0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0400189c, 0x0011e000, 0x00000000, 0x00005555,
0x0200005f, 0x00020032, 0x02000068, 0x00000001, 0x0400009b, 0x00000008, 0x00000008, 0x00000001,
0x07000022, 0x00100032, 0x00000000, 0x00020046, 0x00208ae6, 0x00000000, 0x00000001, 0x07000001,
0x00100012, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0304001f, 0x0010000a,
0x00000000, 0x0700001e, 0x001000f2, 0x00000000, 0x00020546, 0x00208546, 0x00000000, 0x00000001,
0x080000a4, 0x0011e0f2, 0x00000000, 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000000,
0x01000015, 0x0100003e,
};
static const uint32_t cs_uav_clear_2d_uint_code[] =
{
#if 0
RWTexture2D<uint4> dst;
struct
{
uint4 clear_value;
int2 dst_offset;
int2 dst_extent;
} u_info;
[numthreads(8, 8, 1)]
void main(int3 thread_id : SV_DispatchThreadID)
{
if (all(thread_id.xy < u_info.dst_extent.xy))
dst[u_info.dst_offset.xy + thread_id.xy] = u_info.clear_value;
}
#endif
0x43425844, 0xf01db5dd, 0xc7dc5e55, 0xb017c1a8, 0x55abd52d, 0x00000001, 0x00000128, 0x00000003,
0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000d4, 0x00050050, 0x00000035, 0x0100086a,
0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0400189c, 0x0011e000, 0x00000000, 0x00004444,
0x0200005f, 0x00020032, 0x02000068, 0x00000001, 0x0400009b, 0x00000008, 0x00000008, 0x00000001,
0x07000022, 0x00100032, 0x00000000, 0x00020046, 0x00208ae6, 0x00000000, 0x00000001, 0x07000001,
0x00100012, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0304001f, 0x0010000a,
0x00000000, 0x0700001e, 0x001000f2, 0x00000000, 0x00020546, 0x00208546, 0x00000000, 0x00000001,
0x080000a4, 0x0011e0f2, 0x00000000, 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000000,
0x01000015, 0x0100003e,
};
static const uint32_t cs_uav_clear_3d_float_code[] =
{
#if 0
RWTexture3D<float4> dst;
struct
{
float4 clear_value;
int2 dst_offset;
int2 dst_extent;
} u_info;
[numthreads(8, 8, 1)]
void main(int3 thread_id : SV_DispatchThreadID)
{
if (all(thread_id.xy < u_info.dst_extent.xy))
dst[int3(u_info.dst_offset.xy, 0) + thread_id.xyz] = u_info.clear_value;
}
#endif
0x43425844, 0x5d8f36a0, 0x30fa86a5, 0xfec7f2ef, 0xdfd76cbb, 0x00000001, 0x00000138, 0x00000003,
0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000e4, 0x00050050, 0x00000039, 0x0100086a,
0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0400289c, 0x0011e000, 0x00000000, 0x00005555,
0x0200005f, 0x00020072, 0x02000068, 0x00000001, 0x0400009b, 0x00000008, 0x00000008, 0x00000001,
0x07000022, 0x00100032, 0x00000000, 0x00020046, 0x00208ae6, 0x00000000, 0x00000001, 0x07000001,
0x00100012, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0304001f, 0x0010000a,
0x00000000, 0x0700001e, 0x00100032, 0x00000000, 0x00020046, 0x00208046, 0x00000000, 0x00000001,
0x04000036, 0x001000c2, 0x00000000, 0x00020aa6, 0x080000a4, 0x0011e0f2, 0x00000000, 0x00100e46,
0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x01000015, 0x0100003e,
};
static const uint32_t cs_uav_clear_3d_uint_code[] =
{
#if 0
RWTexture3D<uint4> dst;
struct
{
uint4 clear_value;
int2 dst_offset;
int2 dst_extent;
} u_info;
[numthreads(8, 8, 1)]
void main(int3 thread_id : SV_DispatchThreadID)
{
if (all(thread_id.xy < u_info.dst_extent.xy))
dst[int3(u_info.dst_offset.xy, 0) + thread_id.xyz] = u_info.clear_value;
}
#endif
0x43425844, 0x5b9c95b1, 0xc9bde4e3, 0x9aaff806, 0x24a1d264, 0x00000001, 0x00000138, 0x00000003,
0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000e4, 0x00050050, 0x00000039, 0x0100086a,
0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0400289c, 0x0011e000, 0x00000000, 0x00004444,
0x0200005f, 0x00020072, 0x02000068, 0x00000001, 0x0400009b, 0x00000008, 0x00000008, 0x00000001,
0x07000022, 0x00100032, 0x00000000, 0x00020046, 0x00208ae6, 0x00000000, 0x00000001, 0x07000001,
0x00100012, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0304001f, 0x0010000a,
0x00000000, 0x0700001e, 0x00100032, 0x00000000, 0x00020046, 0x00208046, 0x00000000, 0x00000001,
0x04000036, 0x001000c2, 0x00000000, 0x00020aa6, 0x080000a4, 0x0011e0f2, 0x00000000, 0x00100e46,
0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x01000015, 0x0100003e,
};
static const char cs_uav_clear_3d_uint_code[] =
"RWTexture3D<uint4> dst;\n"
"\n"
"struct\n"
"{\n"
" uint4 clear_value;\n"
" int2 dst_offset;\n"
" int2 dst_extent;\n"
"} u_info;\n"
"\n"
"[numthreads(8, 8, 1)]\n"
"void main(int3 thread_id : SV_DispatchThreadID)\n"
"{\n"
" if (all(thread_id.xy < u_info.dst_extent.xy))\n"
" dst[int3(u_info.dst_offset.xy, 0) + thread_id.xyz] = u_info.clear_value;\n"
"}\n";
#endif /* __VKD3D_SHADERS_H */