1
0
Fork 0
mirror of synced 2025-03-07 03:53:26 +01:00

vkd3d: Import upstream release 1.11.

This commit is contained in:
Alexandre Julliard 2024-03-06 12:45:06 +01:00
parent ec2e266c76
commit 5bb80251b1
33 changed files with 10516 additions and 2421 deletions

View file

@ -13,6 +13,7 @@ Derek Lesho
Ethan Lee
Evan Tang
Fabian Maurer
Florian Weimer
Francisco Casas
Francois Gouget
Giovanni Mascellani
@ -33,6 +34,7 @@ Rémi Bernon
Robin Kertels
Stefan Dösinger
Sven Hesse
Victor Chiletto
Vinson Lee
Zebediah Figura
Zhiyi Zhang

View file

@ -1,4 +1,4 @@
Copyright 2016-2023 the Vkd3d project authors (see the file AUTHORS for a
Copyright 2016-2024 the Vkd3d project authors (see the file AUTHORS for a
complete list)
Vkd3d is free software; you can redistribute it and/or modify it under

View file

@ -17,6 +17,7 @@ SOURCES = \
libs/vkd3d-shader/d3dbc.c \
libs/vkd3d-shader/dxbc.c \
libs/vkd3d-shader/dxil.c \
libs/vkd3d-shader/fx.c \
libs/vkd3d-shader/glsl.c \
libs/vkd3d-shader/hlsl.c \
libs/vkd3d-shader/hlsl.l \

View file

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

View file

@ -52,6 +52,7 @@
#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_FX10 VKD3D_MAKE_TAG('F', 'X', '1', '0')
#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')
@ -63,6 +64,7 @@
#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_SFI0 VKD3D_MAKE_TAG('S', 'F', 'I', '0')
#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')
@ -70,7 +72,7 @@
#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)
static inline uint64_t align(uint64_t addr, size_t alignment)
{
return (addr + (alignment - 1)) & ~(alignment - 1);
}
@ -80,7 +82,7 @@ static inline size_t align(size_t addr, size_t alignment)
# ifdef __MINGW_PRINTF_FORMAT
# define VKD3D_PRINTF_FUNC(fmt, args) __attribute__((format(__MINGW_PRINTF_FORMAT, fmt, args)))
# else
# define VKD3D_PRINTF_FUNC(fmt, args) /* __attribute__((format(printf, fmt, args))) */
# define VKD3D_PRINTF_FUNC(fmt, args) __attribute__((format(printf, fmt, args)))
# endif
# define VKD3D_UNUSED __attribute__((unused))
# define VKD3D_UNREACHABLE __builtin_unreachable()
@ -266,34 +268,42 @@ static inline int ascii_strcasecmp(const char *a, const char *b)
return c_a - c_b;
}
#ifndef _WIN32
# if HAVE_SYNC_ADD_AND_FETCH
static inline LONG InterlockedIncrement(LONG volatile *x)
{
return __sync_add_and_fetch(x, 1);
}
static inline LONG64 InterlockedIncrement64(LONG64 volatile *x)
{
return __sync_add_and_fetch(x, 1);
}
static inline LONG InterlockedAdd(LONG volatile *x, LONG val)
static inline uint64_t vkd3d_atomic_add_fetch_u64(uint64_t volatile *x, uint64_t val)
{
#if HAVE_SYNC_ADD_AND_FETCH
return __sync_add_and_fetch(x, val);
#elif defined(_WIN32)
return InterlockedAdd64((LONG64 *)x, val);
#else
# error "vkd3d_atomic_add_fetch_u64() not implemented for this platform"
#endif
}
# else
# error "InterlockedIncrement() not implemented for this platform"
# endif /* HAVE_SYNC_ADD_AND_FETCH */
# if HAVE_SYNC_SUB_AND_FETCH
static inline LONG InterlockedDecrement(LONG volatile *x)
static inline uint32_t vkd3d_atomic_add_fetch_u32(uint32_t volatile *x, uint32_t val)
{
return __sync_sub_and_fetch(x, 1);
#if HAVE_SYNC_ADD_AND_FETCH
return __sync_add_and_fetch(x, val);
#elif defined(_WIN32)
return InterlockedAdd((LONG *)x, val);
#else
# error "vkd3d_atomic_add_fetch_u32() not implemented for this platform"
#endif
}
# else
# error "InterlockedDecrement() not implemented for this platform"
# endif
#endif /* _WIN32 */
static inline uint64_t vkd3d_atomic_increment_u64(uint64_t volatile *x)
{
return vkd3d_atomic_add_fetch_u64(x, 1);
}
static inline uint32_t vkd3d_atomic_decrement_u32(uint32_t volatile *x)
{
return vkd3d_atomic_add_fetch_u32(x, ~0u);
}
static inline uint32_t vkd3d_atomic_increment_u32(uint32_t volatile *x)
{
return vkd3d_atomic_add_fetch_u32(x, 1);
}
static inline void vkd3d_parse_version(const char *version, int *major, int *minor)
{

View file

@ -89,6 +89,10 @@ const char *debugstr_w(const WCHAR *wstr, size_t wchar_size);
#define TRACE_ON() (vkd3d_dbg_get_level() == VKD3D_DBG_LEVEL_TRACE)
#endif
#ifndef WARN_ON
#define WARN_ON() (vkd3d_dbg_get_level() >= VKD3D_DBG_LEVEL_WARN)
#endif
#define FIXME_ONCE VKD3D_DBG_LOG_ONCE(FIXME, WARN)
#define VKD3D_DEBUG_ENV_NAME(name) const char *const vkd3d_dbg_env_name = name
@ -104,6 +108,29 @@ static inline const char *debugstr_guid(const GUID *guid)
guid->Data4[5], guid->Data4[6], guid->Data4[7]);
}
static inline const char *debugstr_hresult(HRESULT hr)
{
switch (hr)
{
#define TO_STR(u) case u: return #u;
TO_STR(S_OK)
TO_STR(S_FALSE)
TO_STR(E_NOTIMPL)
TO_STR(E_NOINTERFACE)
TO_STR(E_POINTER)
TO_STR(E_ABORT)
TO_STR(E_FAIL)
TO_STR(E_OUTOFMEMORY)
TO_STR(E_INVALIDARG)
TO_STR(DXGI_ERROR_NOT_FOUND)
TO_STR(DXGI_ERROR_MORE_DATA)
TO_STR(DXGI_ERROR_UNSUPPORTED)
#undef TO_STR
default:
return vkd3d_dbg_sprintf("%#x", (int)hr);
}
}
unsigned int vkd3d_env_var_as_uint(const char *name, unsigned int default_value);
struct vkd3d_debug_option

View file

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

View file

@ -52,6 +52,7 @@ enum vkd3d_shader_api_version
VKD3D_SHADER_API_VERSION_1_8,
VKD3D_SHADER_API_VERSION_1_9,
VKD3D_SHADER_API_VERSION_1_10,
VKD3D_SHADER_API_VERSION_1_11,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_API_VERSION),
};
@ -196,6 +197,21 @@ enum vkd3d_shader_compile_option_fragment_coordinate_origin
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN),
};
/** Advertises feature availability. \since 1.11 */
enum vkd3d_shader_compile_option_feature_flags
{
/** The SPIR-V target environment supports 64-bit integer types. This
* corresponds to the "shaderInt64" feature in the Vulkan API, and the
* "GL_ARB_gpu_shader_int64" extension in the OpenGL API. */
VKD3D_SHADER_COMPILE_OPTION_FEATURE_INT64 = 0x00000001,
/** The SPIR-V target environment supports 64-bit floating-point types.
* This corresponds to the "shaderFloat64" feature in the Vulkan API, and
* the "GL_ARB_gpu_shader_fp64" extension in the OpenGL API. */
VKD3D_SHADER_COMPILE_OPTION_FEATURE_FLOAT64 = 0x00000002,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_FEATURE_FLAGS),
};
enum vkd3d_shader_compile_option_name
{
/**
@ -253,6 +269,16 @@ enum vkd3d_shader_compile_option_name
* \since 1.10
*/
VKD3D_SHADER_COMPILE_OPTION_FRAGMENT_COORDINATE_ORIGIN = 0x00000009,
/**
* This option specifies the shader features available in the target
* environment. These are not extensions, i.e. they are always supported
* by the driver, but may not be supported by the available hardware.
*
* \a value is a member of enum vkd3d_shader_compile_option_feature_flags.
*
* \since 1.11
*/
VKD3D_SHADER_COMPILE_OPTION_FEATURE = 0x0000000a,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_NAME),
};
@ -767,6 +793,11 @@ enum vkd3d_shader_target_type
* An 'OpenGL Shading Language' shader. \since 1.3
*/
VKD3D_SHADER_TARGET_GLSL,
/**
* Binary format used by Direct3D 9/10.x/11 effects profiles.
* Output is a raw FX section without container. \since 1.11
*/
VKD3D_SHADER_TARGET_FX,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_TARGET_TYPE),
};
@ -853,6 +884,8 @@ enum vkd3d_shader_spirv_extension
VKD3D_SHADER_SPIRV_EXTENSION_EXT_DESCRIPTOR_INDEXING,
/** \since 1.3 */
VKD3D_SHADER_SPIRV_EXTENSION_EXT_STENCIL_EXPORT,
/** \since 1.11 */
VKD3D_SHADER_SPIRV_EXTENSION_EXT_VIEWPORT_INDEX_LAYER,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_SPIRV_EXTENSION),
};
@ -1252,6 +1285,8 @@ enum vkd3d_shader_descriptor_range_flags
VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE = 0x2,
VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE = 0x4,
VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DATA_STATIC = 0x8,
/** \since 1.11 */
VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS = 0x10000,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_DESCRIPTOR_RANGE_FLAGS),
};
@ -1551,6 +1586,8 @@ enum vkd3d_shader_component_type
VKD3D_SHADER_COMPONENT_BOOL = 0x4,
/** 64-bit IEEE floating-point. */
VKD3D_SHADER_COMPONENT_DOUBLE = 0x5,
/** 64-bit unsigned integer. \since 1.11 */
VKD3D_SHADER_COMPONENT_UINT64 = 0x6,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPONENT_TYPE),
};
@ -1747,10 +1784,10 @@ struct vkd3d_shader_dxbc_desc
* \endcode
*/
#define VKD3D_SHADER_SWIZZLE(x, y, z, w) \
vkd3d_shader_create_swizzle(VKD3D_SHADER_SWIZZLE_ ## x, \
VKD3D_SHADER_SWIZZLE_ ## y, \
VKD3D_SHADER_SWIZZLE_ ## z, \
VKD3D_SHADER_SWIZZLE_ ## w)
(VKD3D_SHADER_SWIZZLE_ ## x << VKD3D_SHADER_SWIZZLE_SHIFT(0) \
| VKD3D_SHADER_SWIZZLE_ ## y << VKD3D_SHADER_SWIZZLE_SHIFT(1) \
| VKD3D_SHADER_SWIZZLE_ ## z << VKD3D_SHADER_SWIZZLE_SHIFT(2) \
| VKD3D_SHADER_SWIZZLE_ ## w << VKD3D_SHADER_SWIZZLE_SHIFT(3))
/** The identity swizzle ".xyzw". */
#define VKD3D_SHADER_NO_SWIZZLE VKD3D_SHADER_SWIZZLE(X, Y, Z, W)
@ -1954,9 +1991,13 @@ VKD3D_SHADER_API const enum vkd3d_shader_target_type *vkd3d_shader_get_supported
* - VKD3D_SHADER_SOURCE_DXBC_TPF to VKD3D_SHADER_TARGET_SPIRV_TEXT
* (if vkd3d was compiled with SPIRV-Tools)
* - VKD3D_SHADER_SOURCE_DXBC_TPF to VKD3D_SHADER_TARGET_D3D_ASM
* - VKD3D_SHADER_SOURCE_D3D_BYTECODE to VKD3D_SHADER_TARGET_SPIRV_BINARY
* - VKD3D_SHADER_SOURCE_D3D_BYTECODE to VKD3D_SHADER_TARGET_SPIRV_TEXT
* (if vkd3d was compiled with SPIRV-Tools)
* - VKD3D_SHADER_SOURCE_D3D_BYTECODE to VKD3D_SHADER_TARGET_D3D_ASM
* - VKD3D_SHADER_SOURCE_HLSL to VKD3D_SHADER_TARGET_DXBC_TPF
* - VKD3D_SHADER_SOURCE_HLSL to VKD3D_SHADER_TARGET_D3D_BYTECODE
* - VKD3D_SHADER_SOURCE_HLSL to VKD3D_SHADER_TARGET_FX
*
* Supported transformations can also be detected at runtime with the functions
* vkd3d_shader_get_supported_source_types() and
@ -1964,14 +2005,17 @@ VKD3D_SHADER_API const enum vkd3d_shader_target_type *vkd3d_shader_get_supported
*
* Depending on the source and target types, this function may support the
* following chained structures:
* - vkd3d_shader_descriptor_offset_info
* - vkd3d_shader_hlsl_source_info
* - vkd3d_shader_interface_info
* - vkd3d_shader_varying_map_info
* - vkd3d_shader_preprocess_info
* - vkd3d_shader_scan_combined_resource_sampler_info
* - vkd3d_shader_scan_descriptor_info
* - vkd3d_shader_scan_signature_info
* - vkd3d_shader_spirv_domain_shader_target_info
* - vkd3d_shader_spirv_target_info
* - vkd3d_shader_transform_feedback_info
* - vkd3d_shader_varying_map_info
*
* \param compile_info A chained structure containing compilation parameters.
*

View file

@ -26,7 +26,7 @@
struct vkd3d_blob
{
ID3D10Blob ID3DBlob_iface;
LONG refcount;
unsigned int refcount;
void *buffer;
SIZE_T size;
@ -58,7 +58,7 @@ static HRESULT STDMETHODCALLTYPE vkd3d_blob_QueryInterface(ID3DBlob *iface, REFI
static ULONG STDMETHODCALLTYPE vkd3d_blob_AddRef(ID3DBlob *iface)
{
struct vkd3d_blob *blob = impl_from_ID3DBlob(iface);
ULONG refcount = InterlockedIncrement(&blob->refcount);
unsigned int refcount = vkd3d_atomic_increment_u32(&blob->refcount);
TRACE("%p increasing refcount to %u.\n", blob, refcount);
@ -68,7 +68,7 @@ static ULONG STDMETHODCALLTYPE vkd3d_blob_AddRef(ID3DBlob *iface)
static ULONG STDMETHODCALLTYPE vkd3d_blob_Release(ID3DBlob *iface)
{
struct vkd3d_blob *blob = impl_from_ID3DBlob(iface);
ULONG refcount = InterlockedDecrement(&blob->refcount);
unsigned int refcount = vkd3d_atomic_decrement_u32(&blob->refcount);
TRACE("%p decreasing refcount to %u.\n", blob, refcount);

View file

@ -126,10 +126,10 @@ void vkd3d_dbg_set_log_callback(PFN_vkd3d_log callback)
static char *get_buffer(void)
{
static char buffers[VKD3D_DEBUG_BUFFER_COUNT][VKD3D_DEBUG_BUFFER_SIZE];
static LONG buffer_index;
LONG current_index;
static unsigned int buffer_index;
unsigned int current_index;
current_index = InterlockedIncrement(&buffer_index) % ARRAY_SIZE(buffers);
current_index = vkd3d_atomic_increment_u32(&buffer_index) % ARRAY_SIZE(buffers);
return buffers[current_index];
}

View file

@ -30,8 +30,11 @@
static const char * const shader_opcode_names[] =
{
[VKD3DSIH_ABS ] = "abs",
[VKD3DSIH_ACOS ] = "acos",
[VKD3DSIH_ADD ] = "add",
[VKD3DSIH_AND ] = "and",
[VKD3DSIH_ASIN ] = "asin",
[VKD3DSIH_ATAN ] = "atan",
[VKD3DSIH_ATOMIC_AND ] = "atomic_and",
[VKD3DSIH_ATOMIC_CMP_STORE ] = "atomic_cmp_store",
[VKD3DSIH_ATOMIC_IADD ] = "atomic_iadd",
@ -44,6 +47,7 @@ static const char * const shader_opcode_names[] =
[VKD3DSIH_BEM ] = "bem",
[VKD3DSIH_BFI ] = "bfi",
[VKD3DSIH_BFREV ] = "bfrev",
[VKD3DSIH_BRANCH ] = "branch",
[VKD3DSIH_BREAK ] = "break",
[VKD3DSIH_BREAKC ] = "breakc",
[VKD3DSIH_BREAKP ] = "breakp",
@ -167,10 +171,13 @@ static const char * const shader_opcode_names[] =
[VKD3DSIH_GATHER4_S ] = "gather4_s",
[VKD3DSIH_GEO ] = "ge",
[VKD3DSIH_GEU ] = "ge_unord",
[VKD3DSIH_HCOS ] = "hcos",
[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_HSIN ] = "hsin",
[VKD3DSIH_HTAN ] = "htan",
[VKD3DSIH_IADD ] = "iadd",
[VKD3DSIH_IBFE ] = "ibfe",
[VKD3DSIH_IDIV ] = "idiv",
@ -197,8 +204,11 @@ static const char * const shader_opcode_names[] =
[VKD3DSIH_IMUL ] = "imul",
[VKD3DSIH_INE ] = "ine",
[VKD3DSIH_INEG ] = "ineg",
[VKD3DSIH_ISFINITE ] = "isfinite",
[VKD3DSIH_ISHL ] = "ishl",
[VKD3DSIH_ISHR ] = "ishr",
[VKD3DSIH_ISINF ] = "isinf",
[VKD3DSIH_ISNAN ] = "isnan",
[VKD3DSIH_ITOD ] = "itod",
[VKD3DSIH_ITOF ] = "itof",
[VKD3DSIH_ITOI ] = "itoi",
@ -241,6 +251,7 @@ static const char * const shader_opcode_names[] =
[VKD3DSIH_NRM ] = "nrm",
[VKD3DSIH_OR ] = "or",
[VKD3DSIH_PHASE ] = "phase",
[VKD3DSIH_PHI ] = "phi",
[VKD3DSIH_POW ] = "pow",
[VKD3DSIH_RCP ] = "rcp",
[VKD3DSIH_REP ] = "rep",
@ -278,7 +289,9 @@ static const char * const shader_opcode_names[] =
[VKD3DSIH_SUB ] = "sub",
[VKD3DSIH_SWAPC ] = "swapc",
[VKD3DSIH_SWITCH ] = "switch",
[VKD3DSIH_SWITCH_MONOLITHIC ] = "switch",
[VKD3DSIH_SYNC ] = "sync",
[VKD3DSIH_TAN ] = "tan",
[VKD3DSIH_TEX ] = "texld",
[VKD3DSIH_TEXBEM ] = "texbem",
[VKD3DSIH_TEXBEML ] = "texbeml",
@ -364,6 +377,8 @@ struct vkd3d_d3d_asm_compiler
struct vkd3d_string_buffer buffer;
struct vkd3d_shader_version shader_version;
struct vkd3d_d3d_asm_colours colours;
enum vsir_asm_dialect dialect;
const struct vkd3d_shader_instruction *current;
};
static int VKD3D_PRINTF_FUNC(2, 3) shader_addline(struct vkd3d_string_buffer *buffer, const char *format, ...)
@ -437,6 +452,11 @@ static void shader_dump_sync_flags(struct vkd3d_d3d_asm_compiler *compiler, uint
vkd3d_string_buffer_printf(&compiler->buffer, "_uglobal");
sync_flags &= ~VKD3DSSF_GLOBAL_UAV;
}
if (sync_flags & VKD3DSSF_THREAD_GROUP_UAV)
{
vkd3d_string_buffer_printf(&compiler->buffer, "_ugroup");
sync_flags &= ~VKD3DSSF_THREAD_GROUP_UAV;
}
if (sync_flags & VKD3DSSF_GROUP_SHARED_MEMORY)
{
vkd3d_string_buffer_printf(&compiler->buffer, "_g");
@ -606,7 +626,7 @@ static void shader_dump_resource_type(struct vkd3d_d3d_asm_compiler *compiler, e
vkd3d_string_buffer_printf(&compiler->buffer, "unknown");
}
static void shader_dump_data_type(struct vkd3d_d3d_asm_compiler *compiler, const enum vkd3d_data_type *type)
static void shader_dump_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum vkd3d_data_type type)
{
static const char *const data_type_names[] =
{
@ -623,19 +643,31 @@ static void shader_dump_data_type(struct vkd3d_d3d_asm_compiler *compiler, const
[VKD3D_DATA_DOUBLE ] = "double",
[VKD3D_DATA_CONTINUED] = "<continued>",
[VKD3D_DATA_UNUSED ] = "<unused>",
[VKD3D_DATA_UINT8 ] = "uint8",
[VKD3D_DATA_UINT64 ] = "uint64",
[VKD3D_DATA_BOOL ] = "bool",
};
const char *name;
if (type < ARRAY_SIZE(data_type_names))
name = data_type_names[type];
else
name = "<unknown>";
vkd3d_string_buffer_printf(&compiler->buffer, "%s", name);
}
static void shader_dump_resource_data_type(struct vkd3d_d3d_asm_compiler *compiler, const enum vkd3d_data_type *type)
{
int i;
vkd3d_string_buffer_printf(&compiler->buffer, "(");
for (i = 0; i < 4; i++)
{
if (type[i] < ARRAY_SIZE(data_type_names))
name = data_type_names[type[i]];
else
name = "unknown";
vkd3d_string_buffer_printf(&compiler->buffer, "%s%s", i == 0 ? "" : ",", name);
vkd3d_string_buffer_printf(&compiler->buffer, "%s", i == 0 ? "" : ",");
shader_dump_data_type(compiler, type[i]);
}
vkd3d_string_buffer_printf(&compiler->buffer, ")");
@ -682,7 +714,7 @@ static void shader_dump_decl_usage(struct vkd3d_d3d_asm_compiler *compiler,
if (semantic->resource.reg.reg.type == VKD3DSPR_UAV)
shader_dump_uav_flags(compiler, flags);
shader_addline(buffer, " ");
shader_dump_data_type(compiler, semantic->resource_data_type);
shader_dump_resource_data_type(compiler, semantic->resource_data_type);
}
else
{
@ -814,6 +846,13 @@ static void shader_print_uint_literal(struct vkd3d_d3d_asm_compiler *compiler,
prefix, compiler->colours.literal, i, compiler->colours.reset, suffix);
}
static void shader_print_uint64_literal(struct vkd3d_d3d_asm_compiler *compiler,
const char *prefix, uint64_t i, const char *suffix)
{
vkd3d_string_buffer_printf(&compiler->buffer, "%s%s%"PRIu64"%s%s",
prefix, compiler->colours.literal, i, compiler->colours.reset, suffix);
}
static void shader_print_hex_literal(struct vkd3d_d3d_asm_compiler *compiler,
const char *prefix, unsigned int i, const char *suffix)
{
@ -828,6 +867,27 @@ static void shader_print_bool_literal(struct vkd3d_d3d_asm_compiler *compiler,
compiler->colours.literal, b ? "true" : "false", compiler->colours.reset, suffix);
}
static void shader_print_untyped_literal(struct vkd3d_d3d_asm_compiler *compiler,
const char *prefix, uint32_t u, const char *suffix)
{
union
{
uint32_t u;
float f;
} value;
unsigned int exponent = (u >> 23) & 0xff;
value.u = u;
if (exponent != 0 && exponent != 0xff)
return shader_print_float_literal(compiler, prefix, value.f, suffix);
if (u <= 10000)
return shader_print_uint_literal(compiler, prefix, value.u, suffix);
return shader_print_hex_literal(compiler, prefix, value.u, suffix);
}
static void shader_print_subscript(struct vkd3d_d3d_asm_compiler *compiler,
unsigned int offset, const struct vkd3d_shader_src_param *rel_addr)
{
@ -1089,6 +1149,19 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
if (reg->type == VKD3DSPR_IMMCONST)
{
bool untyped = false;
switch (compiler->current->handler_idx)
{
case VKD3DSIH_MOV:
case VKD3DSIH_MOVC:
untyped = true;
break;
default:
break;
}
shader_addline(buffer, "%s(", compiler->colours.reset);
switch (reg->dimension)
{
@ -1096,15 +1169,18 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
switch (reg->data_type)
{
case VKD3D_DATA_FLOAT:
shader_print_float_literal(compiler, "", reg->u.immconst_float[0], "");
if (untyped)
shader_print_untyped_literal(compiler, "", reg->u.immconst_u32[0], "");
else
shader_print_float_literal(compiler, "", reg->u.immconst_f32[0], "");
break;
case VKD3D_DATA_INT:
shader_print_int_literal(compiler, "", reg->u.immconst_uint[0], "");
shader_print_int_literal(compiler, "", reg->u.immconst_u32[0], "");
break;
case VKD3D_DATA_RESOURCE:
case VKD3D_DATA_SAMPLER:
case VKD3D_DATA_UINT:
shader_print_uint_literal(compiler, "", reg->u.immconst_uint[0], "");
shader_print_uint_literal(compiler, "", reg->u.immconst_u32[0], "");
break;
default:
shader_addline(buffer, "<unhandled data type %#x>", reg->data_type);
@ -1116,24 +1192,34 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
switch (reg->data_type)
{
case VKD3D_DATA_FLOAT:
shader_print_float_literal(compiler, "", reg->u.immconst_float[0], "");
shader_print_float_literal(compiler, ", ", reg->u.immconst_float[1], "");
shader_print_float_literal(compiler, ", ", reg->u.immconst_float[2], "");
shader_print_float_literal(compiler, ", ", reg->u.immconst_float[3], "");
if (untyped)
{
shader_print_untyped_literal(compiler, "", reg->u.immconst_u32[0], "");
shader_print_untyped_literal(compiler, ", ", reg->u.immconst_u32[1], "");
shader_print_untyped_literal(compiler, ", ", reg->u.immconst_u32[2], "");
shader_print_untyped_literal(compiler, ", ", reg->u.immconst_u32[3], "");
}
else
{
shader_print_float_literal(compiler, "", reg->u.immconst_f32[0], "");
shader_print_float_literal(compiler, ", ", reg->u.immconst_f32[1], "");
shader_print_float_literal(compiler, ", ", reg->u.immconst_f32[2], "");
shader_print_float_literal(compiler, ", ", reg->u.immconst_f32[3], "");
}
break;
case VKD3D_DATA_INT:
shader_print_int_literal(compiler, "", reg->u.immconst_uint[0], "");
shader_print_int_literal(compiler, ", ", reg->u.immconst_uint[1], "");
shader_print_int_literal(compiler, ", ", reg->u.immconst_uint[2], "");
shader_print_int_literal(compiler, ", ", reg->u.immconst_uint[3], "");
shader_print_int_literal(compiler, "", reg->u.immconst_u32[0], "");
shader_print_int_literal(compiler, ", ", reg->u.immconst_u32[1], "");
shader_print_int_literal(compiler, ", ", reg->u.immconst_u32[2], "");
shader_print_int_literal(compiler, ", ", reg->u.immconst_u32[3], "");
break;
case VKD3D_DATA_RESOURCE:
case VKD3D_DATA_SAMPLER:
case VKD3D_DATA_UINT:
shader_print_uint_literal(compiler, "", reg->u.immconst_uint[0], "");
shader_print_uint_literal(compiler, ", ", reg->u.immconst_uint[1], "");
shader_print_uint_literal(compiler, ", ", reg->u.immconst_uint[2], "");
shader_print_uint_literal(compiler, ", ", reg->u.immconst_uint[3], "");
shader_print_uint_literal(compiler, "", reg->u.immconst_u32[0], "");
shader_print_uint_literal(compiler, ", ", reg->u.immconst_u32[1], "");
shader_print_uint_literal(compiler, ", ", reg->u.immconst_u32[2], "");
shader_print_uint_literal(compiler, ", ", reg->u.immconst_u32[3], "");
break;
default:
shader_addline(buffer, "<unhandled data type %#x>", reg->data_type);
@ -1155,9 +1241,15 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
{
if (reg->data_type == VKD3D_DATA_DOUBLE)
{
shader_print_double_literal(compiler, "", reg->u.immconst_double[0], "");
shader_print_double_literal(compiler, "", reg->u.immconst_f64[0], "");
if (reg->dimension == VSIR_DIMENSION_VEC4)
shader_print_double_literal(compiler, ", ", reg->u.immconst_double[1], "");
shader_print_double_literal(compiler, ", ", reg->u.immconst_f64[1], "");
}
else if (reg->data_type == VKD3D_DATA_UINT64)
{
shader_print_uint64_literal(compiler, "", reg->u.immconst_u64[0], "");
if (reg->dimension == VSIR_DIMENSION_VEC4)
shader_print_uint64_literal(compiler, "", reg->u.immconst_u64[1], "");
}
else
{
@ -1265,6 +1357,32 @@ static void shader_print_non_uniform(struct vkd3d_d3d_asm_compiler *compiler, co
compiler->colours.modifier, compiler->colours.reset);
}
static void shader_dump_reg_type(struct vkd3d_d3d_asm_compiler *compiler,
const struct vkd3d_shader_register *reg)
{
static const char *dimensions[] =
{
[VSIR_DIMENSION_NONE] = "",
[VSIR_DIMENSION_SCALAR] = "s:",
[VSIR_DIMENSION_VEC4] = "v4:",
};
struct vkd3d_string_buffer *buffer = &compiler->buffer;
const char *dimension;
if (compiler->dialect != VSIR_ASM_VSIR)
return;
if (reg->dimension < ARRAY_SIZE(dimensions))
dimension = dimensions[reg->dimension];
else
dimension = "??";
shader_addline(buffer, " <%s", dimension);
shader_dump_data_type(compiler, reg->data_type);
shader_addline(buffer, ">");
}
static void shader_dump_dst_param(struct vkd3d_d3d_asm_compiler *compiler,
const struct vkd3d_shader_dst_param *param, bool is_declaration)
{
@ -1277,8 +1395,8 @@ static void shader_dump_dst_param(struct vkd3d_d3d_asm_compiler *compiler,
{
static const char write_mask_chars[] = "xyzw";
if (param->reg.data_type == VKD3D_DATA_DOUBLE)
write_mask = vkd3d_write_mask_32_from_64(write_mask);
if (data_type_is_64_bit(param->reg.data_type))
write_mask = vsir_write_mask_32_from_64(write_mask);
shader_addline(buffer, ".%s", compiler->colours.write_mask);
if (write_mask & VKD3DSP_WRITEMASK_0)
@ -1294,6 +1412,7 @@ static void shader_dump_dst_param(struct vkd3d_d3d_asm_compiler *compiler,
shader_print_precision(compiler, &param->reg);
shader_print_non_uniform(compiler, &param->reg);
shader_dump_reg_type(compiler, &param->reg);
}
static void shader_dump_src_param(struct vkd3d_d3d_asm_compiler *compiler,
@ -1341,13 +1460,18 @@ 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.dimension == VSIR_DIMENSION_VEC4)
{
unsigned int swizzle_x = vkd3d_swizzle_get_component(swizzle, 0);
unsigned int swizzle_y = vkd3d_swizzle_get_component(swizzle, 1);
unsigned int swizzle_z = vkd3d_swizzle_get_component(swizzle, 2);
unsigned int swizzle_w = vkd3d_swizzle_get_component(swizzle, 3);
static const char swizzle_chars[] = "xyzw";
unsigned int swizzle_x, swizzle_y, swizzle_z, swizzle_w;
if (data_type_is_64_bit(param->reg.data_type))
swizzle = vsir_swizzle_32_from_64(swizzle);
swizzle_x = vsir_swizzle_get_component(swizzle, 0);
swizzle_y = vsir_swizzle_get_component(swizzle, 1);
swizzle_z = vsir_swizzle_get_component(swizzle, 2);
swizzle_w = vsir_swizzle_get_component(swizzle, 3);
if (swizzle_x == swizzle_y
&& swizzle_x == swizzle_z
&& swizzle_x == swizzle_w)
@ -1367,6 +1491,7 @@ static void shader_dump_src_param(struct vkd3d_d3d_asm_compiler *compiler,
shader_print_precision(compiler, &param->reg);
shader_print_non_uniform(compiler, &param->reg);
shader_dump_reg_type(compiler, &param->reg);
}
static void shader_dump_ins_modifiers(struct vkd3d_d3d_asm_compiler *compiler,
@ -1577,6 +1702,12 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile
shader_addline(buffer, "p");
break;
case VKD3DSIH_ISHL:
case VKD3DSIH_ISHR:
case VKD3DSIH_USHR:
if (ins->flags & VKD3DSI_SHIFT_UNMASKED)
shader_addline(buffer, "_unmasked");
/* fall through */
default:
shader_dump_precise_flags(compiler, ins->flags);
break;
@ -1631,6 +1762,8 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
struct vkd3d_string_buffer *buffer = &compiler->buffer;
unsigned int i;
compiler->current = ins;
if (ins->predicate)
{
vkd3d_string_buffer_printf(buffer, "(");
@ -1835,25 +1968,25 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
vkd3d_string_buffer_printf(buffer, " %sc%u%s", compiler->colours.reg,
shader_get_float_offset(ins->dst[0].reg.type, ins->dst[0].reg.idx[0].offset),
compiler->colours.reset);
shader_print_float_literal(compiler, " = ", ins->src[0].reg.u.immconst_float[0], "");
shader_print_float_literal(compiler, ", ", ins->src[0].reg.u.immconst_float[1], "");
shader_print_float_literal(compiler, ", ", ins->src[0].reg.u.immconst_float[2], "");
shader_print_float_literal(compiler, ", ", ins->src[0].reg.u.immconst_float[3], "");
shader_print_float_literal(compiler, " = ", ins->src[0].reg.u.immconst_f32[0], "");
shader_print_float_literal(compiler, ", ", ins->src[0].reg.u.immconst_f32[1], "");
shader_print_float_literal(compiler, ", ", ins->src[0].reg.u.immconst_f32[2], "");
shader_print_float_literal(compiler, ", ", ins->src[0].reg.u.immconst_f32[3], "");
break;
case VKD3DSIH_DEFI:
vkd3d_string_buffer_printf(buffer, " %si%u%s", compiler->colours.reg,
ins->dst[0].reg.idx[0].offset, compiler->colours.reset);
shader_print_int_literal(compiler, " = ", ins->src[0].reg.u.immconst_uint[0], "");
shader_print_int_literal(compiler, ", ", ins->src[0].reg.u.immconst_uint[1], "");
shader_print_int_literal(compiler, ", ", ins->src[0].reg.u.immconst_uint[2], "");
shader_print_int_literal(compiler, ", ", ins->src[0].reg.u.immconst_uint[3], "");
shader_print_int_literal(compiler, " = ", ins->src[0].reg.u.immconst_u32[0], "");
shader_print_int_literal(compiler, ", ", ins->src[0].reg.u.immconst_u32[1], "");
shader_print_int_literal(compiler, ", ", ins->src[0].reg.u.immconst_u32[2], "");
shader_print_int_literal(compiler, ", ", ins->src[0].reg.u.immconst_u32[3], "");
break;
case VKD3DSIH_DEFB:
vkd3d_string_buffer_printf(buffer, " %sb%u%s", compiler->colours.reg,
ins->dst[0].reg.idx[0].offset, compiler->colours.reset);
shader_print_bool_literal(compiler, " = ", ins->src[0].reg.u.immconst_uint[0], "");
shader_print_bool_literal(compiler, " = ", ins->src[0].reg.u.immconst_u32[0], "");
break;
default:
@ -1883,7 +2016,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
|| ins->resource_data_type[1] != VKD3D_DATA_FLOAT
|| ins->resource_data_type[2] != VKD3D_DATA_FLOAT
|| ins->resource_data_type[3] != VKD3D_DATA_FLOAT)
shader_dump_data_type(compiler, ins->resource_data_type);
shader_dump_resource_data_type(compiler, ins->resource_data_type);
for (i = 0; i < ins->dst_count; ++i)
{
@ -1904,12 +2037,16 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
shader_addline(buffer, "\n");
}
enum vkd3d_result vkd3d_dxbc_binary_to_text(const struct vkd3d_shader_instruction_array *instructions,
const struct vkd3d_shader_version *shader_version, const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_code *out)
enum vkd3d_result vkd3d_dxbc_binary_to_text(const struct vsir_program *program,
const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_code *out, enum vsir_asm_dialect dialect)
{
const struct vkd3d_shader_version *shader_version = &program->shader_version;
enum vkd3d_shader_compile_option_formatting_flags formatting;
struct vkd3d_d3d_asm_compiler compiler;
struct vkd3d_d3d_asm_compiler compiler =
{
.dialect = dialect,
};
enum vkd3d_result result = VKD3D_OK;
struct vkd3d_string_buffer *buffer;
unsigned int indent, i, j;
@ -1973,9 +2110,9 @@ enum vkd3d_result vkd3d_dxbc_binary_to_text(const struct vkd3d_shader_instructio
shader_version->minor, compiler.colours.reset);
indent = 0;
for (i = 0; i < instructions->count; ++i)
for (i = 0; i < program->instructions.count; ++i)
{
struct vkd3d_shader_instruction *ins = &instructions->elements[i];
struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
switch (ins->handler_idx)
{
@ -2002,6 +2139,7 @@ enum vkd3d_result vkd3d_dxbc_binary_to_text(const struct vkd3d_shader_instructio
{
case VKD3DSIH_ELSE:
case VKD3DSIH_IF:
case VKD3DSIH_IFC:
case VKD3DSIH_LOOP:
case VKD3DSIH_SWITCH:
++indent;
@ -2028,13 +2166,12 @@ enum vkd3d_result vkd3d_dxbc_binary_to_text(const struct vkd3d_shader_instructio
return result;
}
void vkd3d_shader_trace(const struct vkd3d_shader_instruction_array *instructions,
const struct vkd3d_shader_version *shader_version)
void vkd3d_shader_trace(const struct vsir_program *program)
{
const char *p, *q, *end;
struct vkd3d_shader_code code;
if (vkd3d_dxbc_binary_to_text(instructions, shader_version, NULL, &code) != VKD3D_OK)
if (vkd3d_dxbc_binary_to_text(program, NULL, &code, VSIR_ASM_VSIR) != VKD3D_OK)
return;
end = (const char *)code.code + code.size;

View file

@ -414,6 +414,7 @@ static bool has_relative_address(uint32_t param)
static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info(
const struct vkd3d_shader_sm1_parser *sm1, enum vkd3d_sm1_opcode opcode)
{
const struct vkd3d_shader_version *version = &sm1->p.program.shader_version;
const struct vkd3d_sm1_opcode_info *info;
unsigned int i = 0;
@ -424,8 +425,8 @@ static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info(
return NULL;
if (opcode == info->sm1_opcode
&& 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)
&& vkd3d_shader_ver_ge(version, info->min_version.major, info->min_version.minor)
&& (vkd3d_shader_ver_le(version, info->max_version.major, info->max_version.minor)
|| !info->max_version.major))
return info;
}
@ -444,7 +445,7 @@ static uint32_t swizzle_from_sm1(uint32_t swizzle)
shader_sm1_get_swizzle_component(swizzle, 3));
}
static void shader_sm1_parse_src_param(uint32_t param, const struct vkd3d_shader_src_param *rel_addr,
static void shader_sm1_parse_src_param(uint32_t param, struct vkd3d_shader_src_param *rel_addr,
struct vkd3d_shader_src_param *src)
{
enum vkd3d_shader_register_type reg_type = ((param & VKD3D_SM1_REGISTER_TYPE_MASK) >> VKD3D_SM1_REGISTER_TYPE_SHIFT)
@ -465,7 +466,7 @@ static void shader_sm1_parse_src_param(uint32_t param, const struct vkd3d_shader
src->modifiers = (param & VKD3D_SM1_SRC_MODIFIER_MASK) >> VKD3D_SM1_SRC_MODIFIER_SHIFT;
}
static void shader_sm1_parse_dst_param(uint32_t param, const struct vkd3d_shader_src_param *rel_addr,
static void shader_sm1_parse_dst_param(uint32_t param, struct vkd3d_shader_src_param *rel_addr,
struct vkd3d_shader_dst_param *dst)
{
enum vkd3d_shader_register_type reg_type = ((param & VKD3D_SM1_REGISTER_TYPE_MASK) >> VKD3D_SM1_REGISTER_TYPE_SHIFT)
@ -482,9 +483,23 @@ static void shader_sm1_parse_dst_param(uint32_t param, const struct vkd3d_shader
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;
switch (dst->reg.dimension)
{
case VSIR_DIMENSION_SCALAR:
dst->write_mask = VKD3DSP_WRITEMASK_0;
break;
case VSIR_DIMENSION_VEC4:
dst->write_mask = (param & VKD3D_SM1_WRITEMASK_MASK) >> VKD3D_SM1_WRITEMASK_SHIFT;
break;
default:
dst->write_mask = 0;
break;
}
}
static struct signature_element *find_signature_element(const struct shader_signature *signature,
@ -518,8 +533,6 @@ static struct signature_element *find_signature_element_by_register_index(
return NULL;
}
#define SM1_COLOR_REGISTER_OFFSET 8
static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool output,
const char *name, unsigned int index, enum vkd3d_shader_sysval_semantic sysval,
unsigned int register_index, bool is_dcl, unsigned int mask)
@ -555,7 +568,7 @@ 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;
if (sm1->p.shader_version.type == VKD3D_SHADER_TYPE_PIXEL && !output)
if (sm1->p.program.shader_version.type == VKD3D_SHADER_TYPE_PIXEL && !output)
element->interpolation_mode = VKD3DSIM_LINEAR;
return true;
@ -574,7 +587,7 @@ static void add_signature_mask(struct vkd3d_shader_sm1_parser *sm1, bool output,
if (!(element = find_signature_element_by_register_index(signature, register_index)))
{
vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_UNDECLARED_SEMANTIC,
vkd3d_shader_parser_warning(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_UNDECLARED_SEMANTIC,
"%s register %u was used without being declared.", output ? "Output" : "Input", register_index);
return;
}
@ -585,20 +598,20 @@ static void add_signature_mask(struct vkd3d_shader_sm1_parser *sm1, bool output,
static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser *sm1,
const struct vkd3d_shader_register *reg, bool is_dcl, unsigned int mask)
{
const struct vkd3d_shader_version *version = &sm1->p.program.shader_version;
unsigned int register_index = reg->idx[0].offset;
switch (reg->type)
{
case VKD3DSPR_TEMP:
if (sm1->p.shader_version.type == VKD3D_SHADER_TYPE_PIXEL
&& sm1->p.shader_version.major == 1 && !register_index)
if (version->type == VKD3D_SHADER_TYPE_PIXEL && version->major == 1 && !register_index)
return add_signature_element(sm1, true, "COLOR", 0, VKD3D_SHADER_SV_TARGET, 0, is_dcl, mask);
return true;
case VKD3DSPR_INPUT:
/* For vertex shaders or sm3 pixel shaders, we should have already
* had a DCL instruction. Otherwise, this is a colour input. */
if (sm1->p.shader_version.type == VKD3D_SHADER_TYPE_VERTEX || sm1->p.shader_version.major == 3)
if (version->type == VKD3D_SHADER_TYPE_VERTEX || version->major == 3)
{
add_signature_mask(sm1, false, register_index, mask);
return true;
@ -608,19 +621,19 @@ static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser *
case VKD3DSPR_TEXTURE:
/* For vertex shaders, this is ADDR. */
if (sm1->p.shader_version.type == VKD3D_SHADER_TYPE_VERTEX)
if (version->type == VKD3D_SHADER_TYPE_VERTEX)
return true;
return add_signature_element(sm1, false, "TEXCOORD", register_index,
VKD3D_SHADER_SV_NONE, register_index, is_dcl, mask);
case VKD3DSPR_OUTPUT:
if (sm1->p.shader_version.type == VKD3D_SHADER_TYPE_VERTEX)
if (version->type == VKD3D_SHADER_TYPE_VERTEX)
{
/* For sm < 2 vertex shaders, this is TEXCRDOUT.
*
* For sm3 vertex shaders, this is OUTPUT, but we already
* should have had a DCL instruction. */
if (sm1->p.shader_version.major == 3)
if (version->major == 3)
{
add_signature_mask(sm1, true, register_index, mask);
return true;
@ -647,15 +660,15 @@ static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser *
{
case 0:
return add_signature_element(sm1, true, "POSITION", 0,
VKD3D_SHADER_SV_POSITION, register_index, is_dcl, mask);
VKD3D_SHADER_SV_POSITION, SM1_RASTOUT_REGISTER_OFFSET + register_index, is_dcl, mask);
case 1:
return add_signature_element(sm1, true, "FOG", 0,
VKD3D_SHADER_SV_NONE, register_index, is_dcl, 0x1);
VKD3D_SHADER_SV_NONE, SM1_RASTOUT_REGISTER_OFFSET + register_index, is_dcl, 0x1);
case 2:
return add_signature_element(sm1, true, "PSIZE", 0,
VKD3D_SHADER_SV_NONE, register_index, is_dcl, 0x1);
VKD3D_SHADER_SV_NONE, SM1_RASTOUT_REGISTER_OFFSET + register_index, is_dcl, 0x1);
default:
vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_INDEX,
@ -688,6 +701,7 @@ static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser *
static bool add_signature_element_from_semantic(struct vkd3d_shader_sm1_parser *sm1,
const struct vkd3d_shader_semantic *semantic)
{
const struct vkd3d_shader_version *version = &sm1->p.program.shader_version;
const struct vkd3d_shader_register *reg = &semantic->resource.reg.reg;
enum vkd3d_shader_sysval_semantic sysval = VKD3D_SHADER_SV_NONE;
unsigned int mask = semantic->resource.reg.write_mask;
@ -719,13 +733,13 @@ static bool add_signature_element_from_semantic(struct vkd3d_shader_sm1_parser *
return add_signature_element_from_register(sm1, reg, true, mask);
/* sm2 pixel shaders use DCL but don't provide a semantic. */
if (sm1->p.shader_version.type == VKD3D_SHADER_TYPE_PIXEL && sm1->p.shader_version.major == 2)
if (version->type == VKD3D_SHADER_TYPE_PIXEL && version->major == 2)
return add_signature_element_from_register(sm1, reg, true, mask);
/* With the exception of vertex POSITION output, none of these are system
* values. Pixel POSITION input is not equivalent to SV_Position; the closer
* equivalent is VPOS, which is not declared as a semantic. */
if (sm1->p.shader_version.type == VKD3D_SHADER_TYPE_VERTEX
if (version->type == VKD3D_SHADER_TYPE_VERTEX
&& output && semantic->usage == VKD3D_DECL_USAGE_POSITION)
sysval = VKD3D_SHADER_SV_POSITION;
@ -751,13 +765,13 @@ static void record_constant_register(struct vkd3d_shader_sm1_parser *sm1,
static void shader_sm1_scan_register(struct vkd3d_shader_sm1_parser *sm1,
const struct vkd3d_shader_register *reg, unsigned int mask, bool from_def)
{
struct vkd3d_shader_desc *desc = &sm1->p.shader_desc;
struct vsir_program *program = &sm1->p.program;
uint32_t register_index = reg->idx[0].offset;
switch (reg->type)
{
case VKD3DSPR_TEMP:
desc->temp_count = max(desc->temp_count, register_index + 1);
program->temp_count = max(program->temp_count, register_index + 1);
break;
case VKD3DSPR_CONST:
@ -812,7 +826,7 @@ static void shader_sm1_read_param(struct vkd3d_shader_sm1_parser *sm1,
* VS >= 2.0 have relative addressing (with token)
* VS >= 1.0 < 2.0 have relative addressing (without token)
* The version check below should work in general. */
if (sm1->p.shader_version.major < 2)
if (sm1->p.program.shader_version.major < 2)
{
*addr_token = (1u << 31)
| ((VKD3DSPR_ADDR << VKD3D_SM1_REGISTER_TYPE_SHIFT2) & VKD3D_SM1_REGISTER_TYPE_MASK2)
@ -841,7 +855,7 @@ static void shader_sm1_skip_opcode(const struct vkd3d_shader_sm1_parser *sm1, co
/* Version 2.0+ shaders may contain address tokens, but fortunately they
* have a useful length mask - use it here. Version 1.x shaders contain no
* such tokens. */
if (sm1->p.shader_version.major >= 2)
if (sm1->p.program.shader_version.major >= 2)
{
length = (opcode_token & VKD3D_SM1_INSTRUCTION_LENGTH_MASK) >> VKD3D_SM1_INSTRUCTION_LENGTH_SHIFT;
*ptr += length;
@ -871,7 +885,7 @@ static void shader_sm1_destroy(struct vkd3d_shader_parser *parser)
{
struct vkd3d_shader_sm1_parser *sm1 = vkd3d_shader_sm1_parser(parser);
shader_instruction_array_destroy(&parser->instructions);
vsir_program_cleanup(&parser->program);
free_shader_desc(&sm1->p.shader_desc);
vkd3d_free(sm1);
}
@ -885,7 +899,7 @@ static void shader_sm1_read_src_param(struct vkd3d_shader_sm1_parser *sm1, const
shader_sm1_read_param(sm1, ptr, &token, &addr_token);
if (has_relative_address(token))
{
if (!(src_rel_addr = shader_parser_get_src_params(&sm1->p, 1)))
if (!(src_rel_addr = vsir_program_get_src_params(&sm1->p.program, 1)))
{
vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY,
"Out of memory.");
@ -906,7 +920,7 @@ static void shader_sm1_read_dst_param(struct vkd3d_shader_sm1_parser *sm1, const
shader_sm1_read_param(sm1, ptr, &token, &addr_token);
if (has_relative_address(token))
{
if (!(dst_rel_addr = shader_parser_get_src_params(&sm1->p, 1)))
if (!(dst_rel_addr = vsir_program_get_src_params(&sm1->p.program, 1)))
{
vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY,
"Out of memory.");
@ -987,7 +1001,7 @@ static void shader_sm1_read_immconst(struct vkd3d_shader_sm1_parser *sm1, const
src_param->reg.idx[2].rel_addr = NULL;
src_param->reg.idx_count = 0;
src_param->reg.dimension = dimension;
memcpy(src_param->reg.u.immconst_uint, *ptr, count * sizeof(uint32_t));
memcpy(src_param->reg.u.immconst_u32, *ptr, count * sizeof(uint32_t));
src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE;
src_param->modifiers = 0;
@ -1063,18 +1077,19 @@ static void shader_sm1_validate_instruction(struct vkd3d_shader_sm1_parser *sm1,
}
}
static unsigned int mask_from_swizzle(unsigned int swizzle)
static unsigned int mask_from_swizzle(uint32_t swizzle)
{
return (1u << vkd3d_swizzle_get_component(swizzle, 0))
| (1u << vkd3d_swizzle_get_component(swizzle, 1))
| (1u << vkd3d_swizzle_get_component(swizzle, 2))
| (1u << vkd3d_swizzle_get_component(swizzle, 3));
return (1u << vsir_swizzle_get_component(swizzle, 0))
| (1u << vsir_swizzle_get_component(swizzle, 1))
| (1u << vsir_swizzle_get_component(swizzle, 2))
| (1u << vsir_swizzle_get_component(swizzle, 3));
}
static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, struct vkd3d_shader_instruction *ins)
{
struct vkd3d_shader_src_param *src_params, *predicate;
const struct vkd3d_sm1_opcode_info *opcode_info;
struct vsir_program *program = &sm1->p.program;
struct vkd3d_shader_dst_param *dst_param;
const uint32_t **ptr = &sm1->ptr;
uint32_t opcode_token;
@ -1097,7 +1112,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str
vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_INVALID_OPCODE,
"Invalid opcode %#x (token 0x%08x, shader version %u.%u).",
opcode_token & VKD3D_SM1_OPCODE_MASK, opcode_token,
sm1->p.shader_version.major, sm1->p.shader_version.minor);
program->shader_version.major, program->shader_version.minor);
goto fail;
}
@ -1107,11 +1122,11 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str
ins->raw = false;
ins->structured = false;
predicated = !!(opcode_token & VKD3D_SM1_INSTRUCTION_PREDICATED);
ins->predicate = predicate = predicated ? shader_parser_get_src_params(&sm1->p, 1) : NULL;
ins->predicate = predicate = predicated ? vsir_program_get_src_params(program, 1) : NULL;
ins->dst_count = opcode_info->dst_count;
ins->dst = dst_param = shader_parser_get_dst_params(&sm1->p, ins->dst_count);
ins->dst = dst_param = vsir_program_get_dst_params(program, ins->dst_count);
ins->src_count = opcode_info->src_count;
ins->src = src_params = shader_parser_get_src_params(&sm1->p, ins->src_count);
ins->src = src_params = vsir_program_get_src_params(program, ins->src_count);
if ((!predicate && predicated) || (!src_params && ins->src_count) || (!dst_param && ins->dst_count))
{
vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, "Out of memory.");
@ -1322,7 +1337,7 @@ int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compi
return ret;
}
instructions = &sm1->p.instructions;
instructions = &sm1->p.program.instructions;
while (!shader_sm1_is_end(sm1))
{
if (!shader_instruction_array_reserve(instructions, instructions->count + 1))
@ -1348,18 +1363,21 @@ int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compi
sm1->p.shader_desc.flat_constant_count[i].external = get_external_constant_count(sm1, i);
if (!sm1->p.failed)
vsir_validate(&sm1->p);
ret = vsir_validate(&sm1->p);
if (sm1->p.failed)
if (sm1->p.failed && ret >= 0)
ret = VKD3D_ERROR_INVALID_SHADER;
if (ret < 0)
{
WARN("Failed to parse shader.\n");
shader_sm1_destroy(&sm1->p);
return VKD3D_ERROR_INVALID_SHADER;
return ret;
}
*parser = &sm1->p;
return VKD3D_OK;
return ret;
}
bool hlsl_sm1_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic,
@ -1374,7 +1392,7 @@ bool hlsl_sm1_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_sem
enum vkd3d_shader_type shader_type;
unsigned int major_version;
D3DSHADER_PARAM_REGISTER_TYPE type;
DWORD offset;
unsigned int offset;
}
register_table[] =
{
@ -1940,6 +1958,82 @@ static void write_sm1_unary_op(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe
write_sm1_instruction(ctx, buffer, &instr);
}
static void write_sm1_cast(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer,
const struct hlsl_ir_node *instr)
{
struct hlsl_ir_expr *expr = hlsl_ir_expr(instr);
const struct hlsl_ir_node *arg1 = expr->operands[0].node;
const struct hlsl_type *dst_type = expr->node.data_type;
const struct hlsl_type *src_type = arg1->data_type;
/* Narrowing casts were already lowered. */
assert(src_type->dimx == dst_type->dimx);
switch (dst_type->base_type)
{
case HLSL_TYPE_HALF:
case HLSL_TYPE_FLOAT:
switch (src_type->base_type)
{
case HLSL_TYPE_INT:
case HLSL_TYPE_UINT:
/* Integers are internally represented as floats, so no change is necessary.*/
case HLSL_TYPE_HALF:
case HLSL_TYPE_FLOAT:
write_sm1_unary_op(ctx, buffer, D3DSIO_MOV, &instr->reg, &arg1->reg, 0, 0);
break;
case HLSL_TYPE_BOOL:
hlsl_fixme(ctx, &instr->loc, "SM1 cast from bool to float.");
break;
case HLSL_TYPE_DOUBLE:
hlsl_fixme(ctx, &instr->loc, "SM1 cast from double to float.");
break;
default:
vkd3d_unreachable();
}
break;
case HLSL_TYPE_INT:
case HLSL_TYPE_UINT:
switch(src_type->base_type)
{
case HLSL_TYPE_HALF:
case HLSL_TYPE_FLOAT:
/* A compilation pass applies a FLOOR operation to casts to int, so no change is necessary. */
case HLSL_TYPE_INT:
case HLSL_TYPE_UINT:
write_sm1_unary_op(ctx, buffer, D3DSIO_MOV, &instr->reg, &arg1->reg, 0, 0);
break;
case HLSL_TYPE_BOOL:
hlsl_fixme(ctx, &instr->loc, "SM1 cast from bool to integer.");
break;
case HLSL_TYPE_DOUBLE:
hlsl_fixme(ctx, &instr->loc, "SM1 cast from double to integer.");
break;
default:
vkd3d_unreachable();
}
break;
case HLSL_TYPE_DOUBLE:
hlsl_fixme(ctx, &instr->loc, "SM1 cast to double.");
break;
case HLSL_TYPE_BOOL:
/* Casts to bool should have already been lowered. */
default:
hlsl_fixme(ctx, &expr->node.loc, "SM1 cast from %s to %s.\n",
debug_hlsl_type(ctx, src_type), debug_hlsl_type(ctx, dst_type));
break;
}
}
static void write_sm1_constant_defs(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer)
{
unsigned int i, x;
@ -2148,6 +2242,12 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b
assert(instr->reg.allocated);
if (expr->op == HLSL_OP1_CAST)
{
write_sm1_cast(ctx, buffer, instr);
return;
}
if (instr->data_type->base_type != HLSL_TYPE_FLOAT)
{
/* These need to be lowered. */
@ -2253,7 +2353,7 @@ static void write_sm1_jump(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b
{
struct hlsl_reg *reg = &jump->condition.node->reg;
struct sm1_instruction instr =
struct sm1_instruction sm1_instr =
{
.opcode = D3DSIO_TEXKILL,
@ -2263,7 +2363,7 @@ static void write_sm1_jump(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b
.has_dst = 1,
};
write_sm1_instruction(ctx, buffer, &instr);
write_sm1_instruction(ctx, buffer, &sm1_instr);
break;
}
@ -2328,8 +2428,6 @@ static void write_sm1_resource_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_
sm1_instr = (struct sm1_instruction)
{
.opcode = D3DSIO_TEX,
.dst.type = D3DSPR_TEMP,
.dst.reg = instr->reg.id,
.dst.writemask = instr->reg.writemask,
@ -2345,8 +2443,22 @@ 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;
switch (load->load_type)
{
case HLSL_RESOURCE_SAMPLE:
sm1_instr.opcode = D3DSIO_TEX;
break;
case HLSL_RESOURCE_SAMPLE_PROJ:
sm1_instr.opcode = D3DSIO_TEX;
sm1_instr.opcode |= VKD3DSI_TEXLD_PROJECT << VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT;
break;
default:
hlsl_fixme(ctx, &instr->loc, "Resource load type %u\n", load->load_type);
return;
}
assert(instr->reg.allocated);

View file

@ -130,13 +130,13 @@ static void skip_dword_unknown(const char **ptr, unsigned int count)
}
}
static const char *shader_get_string(const char *data, size_t data_size, DWORD offset)
static const char *shader_get_string(const char *data, size_t data_size, size_t offset)
{
size_t len, max_len;
if (offset >= data_size)
{
WARN("Invalid offset %#x (data size %#lx).\n", offset, (long)data_size);
WARN("Invalid offset %#zx (data size %#zx).\n", offset, data_size);
return NULL;
}
@ -230,7 +230,7 @@ static int parse_dxbc(const struct vkd3d_shader_code *dxbc, struct vkd3d_shader_
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))
if (chunk_offset >= data_size || !require_space(chunk_offset, 2, sizeof(uint32_t), data_size))
{
WARN("Invalid chunk offset %#x (data size %zu).\n", chunk_offset, data_size);
vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_OFFSET,
@ -399,7 +399,8 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s
for (i = 0; i < count; ++i)
{
uint32_t name_offset, mask;
size_t name_offset;
uint32_t mask;
e[i].sort_index = i;
@ -411,7 +412,7 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s
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);
WARN("Invalid name offset %#zx (data size %#zx).\n", name_offset, section->data.size);
vkd3d_free(e);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
@ -431,10 +432,6 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s
case TAG_OSG5:
if (e[i].sysval_semantic == VKD3D_SHADER_SV_NONE)
e[i].sysval_semantic = map_fragment_output_sysval(e[i].semantic_name);
/* Fall through. */
case TAG_PCSG:
case TAG_PSG1:
e[i].used_mask = e[i].mask & ~e[i].used_mask;
break;
}
@ -596,7 +593,7 @@ static int shader_parse_descriptor_ranges(struct root_signature_parser_context *
const char *ptr;
unsigned int i;
if (!require_space(offset, 5 * count, sizeof(DWORD), context->data_size))
if (!require_space(offset, 5 * count, sizeof(uint32_t), context->data_size))
{
WARN("Invalid data size %#x (offset %u, count %u).\n", context->data_size, offset, count);
return VKD3D_ERROR_INVALID_ARGUMENT;
@ -627,7 +624,8 @@ static void shader_validate_descriptor_range1(const struct vkd3d_shader_descript
| VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_VOLATILE
| VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE
| VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE
| VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DATA_STATIC);
| VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DATA_STATIC
| VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS);
if (unknown_flags)
FIXME("Unknown descriptor range flags %#x.\n", unknown_flags);
@ -674,7 +672,7 @@ static int shader_parse_descriptor_table(struct root_signature_parser_context *c
unsigned int count;
const char *ptr;
if (!require_space(offset, 2, sizeof(DWORD), context->data_size))
if (!require_space(offset, 2, sizeof(uint32_t), context->data_size))
{
WARN("Invalid data size %#x (offset %u).\n", context->data_size, offset);
return VKD3D_ERROR_INVALID_ARGUMENT;
@ -701,7 +699,7 @@ static int shader_parse_descriptor_table1(struct root_signature_parser_context *
unsigned int count;
const char *ptr;
if (!require_space(offset, 2, sizeof(DWORD), context->data_size))
if (!require_space(offset, 2, sizeof(uint32_t), context->data_size))
{
WARN("Invalid data size %#x (offset %u).\n", context->data_size, offset);
return VKD3D_ERROR_INVALID_ARGUMENT;
@ -726,7 +724,7 @@ static int shader_parse_root_constants(struct root_signature_parser_context *con
{
const char *ptr;
if (!require_space(offset, 3, sizeof(DWORD), context->data_size))
if (!require_space(offset, 3, sizeof(uint32_t), context->data_size))
{
WARN("Invalid data size %#x (offset %u).\n", context->data_size, offset);
return VKD3D_ERROR_INVALID_ARGUMENT;
@ -748,7 +746,7 @@ static int shader_parse_root_descriptor(struct root_signature_parser_context *co
{
const char *ptr;
if (!require_space(offset, 2, sizeof(DWORD), context->data_size))
if (!require_space(offset, 2, sizeof(uint32_t), context->data_size))
{
WARN("Invalid data size %#x (offset %u).\n", context->data_size, offset);
return VKD3D_ERROR_INVALID_ARGUMENT;
@ -780,7 +778,7 @@ static int shader_parse_root_descriptor1(struct root_signature_parser_context *c
{
const char *ptr;
if (!require_space(offset, 3, sizeof(DWORD), context->data_size))
if (!require_space(offset, 3, sizeof(uint32_t), context->data_size))
{
WARN("Invalid data size %#x (offset %u).\n", context->data_size, offset);
return VKD3D_ERROR_INVALID_ARGUMENT;
@ -806,7 +804,7 @@ static int shader_parse_root_parameters(struct root_signature_parser_context *co
unsigned int i;
int ret;
if (!require_space(offset, 3 * count, sizeof(DWORD), context->data_size))
if (!require_space(offset, 3 * count, sizeof(uint32_t), context->data_size))
{
WARN("Invalid data size %#x (offset %u, count %u).\n", context->data_size, offset, count);
return VKD3D_ERROR_INVALID_ARGUMENT;
@ -848,13 +846,13 @@ static int shader_parse_root_parameters(struct root_signature_parser_context *co
}
static int shader_parse_root_parameters1(struct root_signature_parser_context *context,
uint32_t offset, DWORD count, struct vkd3d_shader_root_parameter1 *parameters)
uint32_t offset, unsigned int count, struct vkd3d_shader_root_parameter1 *parameters)
{
const char *ptr;
unsigned int i;
int ret;
if (!require_space(offset, 3 * count, sizeof(DWORD), context->data_size))
if (!require_space(offset, 3 * count, sizeof(uint32_t), context->data_size))
{
WARN("Invalid data size %#x (offset %u, count %u).\n", context->data_size, offset, count);
return VKD3D_ERROR_INVALID_ARGUMENT;
@ -901,7 +899,7 @@ static int shader_parse_static_samplers(struct root_signature_parser_context *co
const char *ptr;
unsigned int i;
if (!require_space(offset, 13 * count, sizeof(DWORD), context->data_size))
if (!require_space(offset, 13 * count, sizeof(uint32_t), context->data_size))
{
WARN("Invalid data size %#x (offset %u, count %u).\n", context->data_size, offset, count);
return VKD3D_ERROR_INVALID_ARGUMENT;

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,966 @@
/*
* FX (Direct3D 9/10/11 effect) support
*
* Copyright 2023 Nikolay Sivov for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "hlsl.h"
static inline size_t put_u32_unaligned(struct vkd3d_bytecode_buffer *buffer, uint32_t value)
{
return bytecode_put_bytes_unaligned(buffer, &value, sizeof(value));
}
struct string_entry
{
struct rb_entry entry;
/* String points to original data, should not be freed. */
const char *string;
uint32_t offset;
};
struct type_entry
{
struct list entry;
const char *name;
uint32_t elements_count;
uint32_t offset;
};
static int string_storage_compare(const void *key, const struct rb_entry *entry)
{
struct string_entry *string_entry = RB_ENTRY_VALUE(entry, struct string_entry, entry);
const char *string = key;
return strcmp(string, string_entry->string);
}
static void string_storage_destroy(struct rb_entry *entry, void *context)
{
struct string_entry *string_entry = RB_ENTRY_VALUE(entry, struct string_entry, entry);
vkd3d_free(string_entry);
}
struct fx_write_context;
struct fx_write_context_ops
{
uint32_t (*write_string)(const char *string, struct fx_write_context *fx);
uint32_t (*write_type)(const struct hlsl_type *type, struct fx_write_context *fx);
void (*write_technique)(struct hlsl_ir_var *var, struct fx_write_context *fx);
void (*write_pass)(struct hlsl_ir_var *var, struct fx_write_context *fx);
};
struct fx_write_context
{
struct hlsl_ctx *ctx;
struct vkd3d_bytecode_buffer unstructured;
struct vkd3d_bytecode_buffer structured;
struct rb_tree strings;
struct list types;
unsigned int min_technique_version;
unsigned int max_technique_version;
uint32_t technique_count;
uint32_t group_count;
uint32_t buffer_count;
uint32_t numeric_variable_count;
uint32_t object_variable_count;
int status;
const struct fx_write_context_ops *ops;
};
static void set_status(struct fx_write_context *fx, int status)
{
if (fx->status < 0)
return;
if (status < 0)
fx->status = status;
}
static uint32_t write_string(const char *string, struct fx_write_context *fx)
{
return fx->ops->write_string(string, fx);
}
static void write_pass(struct hlsl_ir_var *var, struct fx_write_context *fx)
{
fx->ops->write_pass(var, fx);
}
static uint32_t write_type(const struct hlsl_type *type, struct fx_write_context *fx)
{
struct type_entry *type_entry;
unsigned int elements_count;
const char *name;
if (type->class == HLSL_CLASS_ARRAY)
{
name = hlsl_get_multiarray_element_type(type)->name;
elements_count = hlsl_get_multiarray_size(type);
}
else
{
name = type->name;
elements_count = 0;
}
LIST_FOR_EACH_ENTRY(type_entry, &fx->types, struct type_entry, entry)
{
if (strcmp(type_entry->name, name))
continue;
if (type_entry->elements_count != elements_count)
continue;
return type_entry->offset;
}
if (!(type_entry = hlsl_alloc(fx->ctx, sizeof(*type_entry))))
return 0;
type_entry->offset = fx->ops->write_type(type, fx);
type_entry->name = name;
type_entry->elements_count = elements_count;
list_add_tail(&fx->types, &type_entry->entry);
return type_entry->offset;
}
static void fx_write_context_init(struct hlsl_ctx *ctx, const struct fx_write_context_ops *ops,
struct fx_write_context *fx)
{
unsigned int version = ctx->profile->major_version;
memset(fx, 0, sizeof(*fx));
fx->ctx = ctx;
fx->ops = ops;
if (version == 2)
{
fx->min_technique_version = 9;
fx->max_technique_version = 9;
}
else if (version == 4)
{
fx->min_technique_version = 10;
fx->max_technique_version = 10;
}
else if (version == 5)
{
fx->min_technique_version = 10;
fx->max_technique_version = 11;
}
rb_init(&fx->strings, string_storage_compare);
list_init(&fx->types);
}
static int fx_write_context_cleanup(struct fx_write_context *fx)
{
struct type_entry *type, *next_type;
int status = fx->status;
rb_destroy(&fx->strings, string_storage_destroy, NULL);
LIST_FOR_EACH_ENTRY_SAFE(type, next_type, &fx->types, struct type_entry, entry)
{
list_remove(&type->entry);
vkd3d_free(type);
}
return status;
}
static bool technique_matches_version(const struct hlsl_ir_var *var, const struct fx_write_context *fx)
{
const struct hlsl_type *type = var->data_type;
if (type->base_type != HLSL_TYPE_TECHNIQUE)
return false;
return type->e.version >= fx->min_technique_version && type->e.version <= fx->max_technique_version;
}
static uint32_t write_fx_4_string(const char *string, struct fx_write_context *fx)
{
struct string_entry *string_entry;
struct rb_entry *entry;
/* NULLs are emitted as empty strings using the same 4 bytes at the start of the section. */
if (!string)
return 0;
if ((entry = rb_get(&fx->strings, string)))
{
string_entry = RB_ENTRY_VALUE(entry, struct string_entry, entry);
return string_entry->offset;
}
if (!(string_entry = hlsl_alloc(fx->ctx, sizeof(*string_entry))))
return 0;
string_entry->offset = bytecode_put_bytes_unaligned(&fx->unstructured, string, strlen(string) + 1);
string_entry->string = string;
rb_put(&fx->strings, string, &string_entry->entry);
return string_entry->offset;
}
static void write_fx_4_pass(struct hlsl_ir_var *var, struct fx_write_context *fx)
{
struct vkd3d_bytecode_buffer *buffer = &fx->structured;
uint32_t name_offset;
name_offset = write_string(var->name, fx);
put_u32(buffer, name_offset);
put_u32(buffer, 0); /* Assignment count. */
put_u32(buffer, 0); /* Annotation count. */
/* TODO: annotations */
/* TODO: assignments */
}
static void write_fx_2_pass(struct hlsl_ir_var *var, struct fx_write_context *fx)
{
struct vkd3d_bytecode_buffer *buffer = &fx->structured;
uint32_t name_offset;
name_offset = write_string(var->name, fx);
put_u32(buffer, name_offset);
put_u32(buffer, 0); /* Annotation count. */
put_u32(buffer, 0); /* Assignment count. */
/* TODO: annotations */
/* TODO: assignments */
}
static uint32_t get_fx_4_type_size(const struct hlsl_type *type)
{
uint32_t elements_count;
elements_count = hlsl_get_multiarray_size(type);
type = hlsl_get_multiarray_element_type(type);
return type->reg_size[HLSL_REGSET_NUMERIC] * sizeof(float) * elements_count;
}
static uint32_t get_fx_4_numeric_type_description(const struct hlsl_type *type, struct fx_write_context *fx)
{
static const unsigned int NUMERIC_BASE_TYPE_SHIFT = 3;
static const unsigned int NUMERIC_ROWS_SHIFT = 8;
static const unsigned int NUMERIC_COLUMNS_SHIFT = 11;
static const unsigned int NUMERIC_COLUMN_MAJOR_MASK = 0x4000;
static const uint32_t numeric_type_class[] =
{
[HLSL_CLASS_SCALAR] = 1,
[HLSL_CLASS_VECTOR] = 2,
[HLSL_CLASS_MATRIX] = 3,
};
static const uint32_t numeric_base_type[] =
{
[HLSL_TYPE_FLOAT] = 1,
[HLSL_TYPE_INT ] = 2,
[HLSL_TYPE_UINT ] = 3,
[HLSL_TYPE_BOOL ] = 4,
};
uint32_t value = 0;
switch (type->class)
{
case HLSL_CLASS_SCALAR:
case HLSL_CLASS_VECTOR:
case HLSL_CLASS_MATRIX:
value |= numeric_type_class[type->class];
break;
default:
FIXME("Unexpected type class %u.\n", type->class);
set_status(fx, VKD3D_ERROR_NOT_IMPLEMENTED);
return 0;
}
switch (type->base_type)
{
case HLSL_TYPE_FLOAT:
case HLSL_TYPE_INT:
case HLSL_TYPE_UINT:
case HLSL_TYPE_BOOL:
value |= (numeric_base_type[type->base_type] << NUMERIC_BASE_TYPE_SHIFT);
break;
default:
FIXME("Unexpected base type %u.\n", type->base_type);
set_status(fx, VKD3D_ERROR_NOT_IMPLEMENTED);
return 0;
}
value |= (type->dimy & 0x7) << NUMERIC_ROWS_SHIFT;
value |= (type->dimx & 0x7) << NUMERIC_COLUMNS_SHIFT;
if (type->modifiers & HLSL_MODIFIER_COLUMN_MAJOR)
value |= NUMERIC_COLUMN_MAJOR_MASK;
return value;
}
static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_context *fx)
{
struct vkd3d_bytecode_buffer *buffer = &fx->unstructured;
uint32_t name_offset, offset, size, stride, numeric_desc;
uint32_t elements_count = 0;
const char *name;
static const uint32_t variable_type[] =
{
[HLSL_CLASS_SCALAR] = 1,
[HLSL_CLASS_VECTOR] = 1,
[HLSL_CLASS_MATRIX] = 1,
[HLSL_CLASS_OBJECT] = 2,
[HLSL_CLASS_STRUCT] = 3,
};
static const char * const texture_type_names[] =
{
[HLSL_SAMPLER_DIM_GENERIC] = "texture",
[HLSL_SAMPLER_DIM_1D] = "Texture1D",
[HLSL_SAMPLER_DIM_1DARRAY] = "Texture1DArray",
[HLSL_SAMPLER_DIM_2D] = "Texture2D",
[HLSL_SAMPLER_DIM_2DARRAY] = "Texture2DArray",
[HLSL_SAMPLER_DIM_2DMS] = "Texture2DMS",
[HLSL_SAMPLER_DIM_2DMSARRAY] = "Texture2DMSArray",
[HLSL_SAMPLER_DIM_3D] = "Texture3D",
[HLSL_SAMPLER_DIM_CUBE] = "TextureCube",
[HLSL_SAMPLER_DIM_CUBEARRAY] = "TextureCubeArray",
};
static const char * const uav_type_names[] =
{
[HLSL_SAMPLER_DIM_1D] = "RWTexture1D",
[HLSL_SAMPLER_DIM_1DARRAY] = "RWTexture1DArray",
[HLSL_SAMPLER_DIM_2D] = "RWTexture2D",
[HLSL_SAMPLER_DIM_2DARRAY] = "RWTexture2DArray",
[HLSL_SAMPLER_DIM_3D] = "RWTexture3D",
[HLSL_SAMPLER_DIM_BUFFER] = "RWBuffer",
[HLSL_SAMPLER_DIM_STRUCTURED_BUFFER] = "RWStructuredBuffer",
};
/* Resolve arrays to element type and number of elements. */
if (type->class == HLSL_CLASS_ARRAY)
{
elements_count = hlsl_get_multiarray_size(type);
type = hlsl_get_multiarray_element_type(type);
}
if (type->base_type == HLSL_TYPE_TEXTURE)
name = texture_type_names[type->sampler_dim];
else if (type->base_type == HLSL_TYPE_UAV)
name = uav_type_names[type->sampler_dim];
else
name = type->name;
name_offset = write_string(name, fx);
offset = put_u32_unaligned(buffer, name_offset);
switch (type->class)
{
case HLSL_CLASS_SCALAR:
case HLSL_CLASS_VECTOR:
case HLSL_CLASS_MATRIX:
case HLSL_CLASS_OBJECT:
case HLSL_CLASS_STRUCT:
put_u32_unaligned(buffer, variable_type[type->class]);
break;
default:
FIXME("Writing type class %u is not implemented.\n", type->class);
set_status(fx, VKD3D_ERROR_NOT_IMPLEMENTED);
return 0;
}
size = stride = type->reg_size[HLSL_REGSET_NUMERIC] * sizeof(float);
if (elements_count)
size *= elements_count;
stride = align(stride, 4 * sizeof(float));
put_u32_unaligned(buffer, elements_count);
put_u32_unaligned(buffer, size); /* Total size. */
put_u32_unaligned(buffer, stride); /* Stride. */
put_u32_unaligned(buffer, size);
if (type->class == HLSL_CLASS_STRUCT)
{
size_t i;
put_u32_unaligned(buffer, type->e.record.field_count);
for (i = 0; i < type->e.record.field_count; ++i)
{
const struct hlsl_struct_field *field = &type->e.record.fields[i];
uint32_t semantic_offset, field_type_offset;
name_offset = write_string(field->name, fx);
semantic_offset = write_string(field->semantic.name, fx);
field_type_offset = write_type(field->type, fx);
put_u32_unaligned(buffer, name_offset);
put_u32_unaligned(buffer, semantic_offset);
put_u32_unaligned(buffer, field->reg_offset[HLSL_REGSET_NUMERIC]);
put_u32_unaligned(buffer, field_type_offset);
}
}
else if (type->class == HLSL_CLASS_OBJECT)
{
static const uint32_t object_type[] =
{
[HLSL_TYPE_RENDERTARGETVIEW] = 19,
[HLSL_TYPE_DEPTHSTENCILVIEW] = 20,
};
static const uint32_t texture_type[] =
{
[HLSL_SAMPLER_DIM_GENERIC] = 9,
[HLSL_SAMPLER_DIM_1D] = 10,
[HLSL_SAMPLER_DIM_1DARRAY] = 11,
[HLSL_SAMPLER_DIM_2D] = 12,
[HLSL_SAMPLER_DIM_2DARRAY] = 13,
[HLSL_SAMPLER_DIM_2DMS] = 14,
[HLSL_SAMPLER_DIM_2DMSARRAY] = 15,
[HLSL_SAMPLER_DIM_3D] = 16,
[HLSL_SAMPLER_DIM_CUBE] = 17,
[HLSL_SAMPLER_DIM_CUBEARRAY] = 23,
};
static const uint32_t uav_type[] =
{
[HLSL_SAMPLER_DIM_1D] = 31,
[HLSL_SAMPLER_DIM_1DARRAY] = 32,
[HLSL_SAMPLER_DIM_2D] = 33,
[HLSL_SAMPLER_DIM_2DARRAY] = 34,
[HLSL_SAMPLER_DIM_3D] = 35,
[HLSL_SAMPLER_DIM_BUFFER] = 36,
[HLSL_SAMPLER_DIM_STRUCTURED_BUFFER] = 40,
};
switch (type->base_type)
{
case HLSL_TYPE_DEPTHSTENCILVIEW:
case HLSL_TYPE_RENDERTARGETVIEW:
put_u32_unaligned(buffer, object_type[type->base_type]);
break;
case HLSL_TYPE_TEXTURE:
put_u32_unaligned(buffer, texture_type[type->sampler_dim]);
break;
case HLSL_TYPE_UAV:
put_u32_unaligned(buffer, uav_type[type->sampler_dim]);
break;
default:
FIXME("Object type %u is not supported.\n", type->base_type);
set_status(fx, VKD3D_ERROR_NOT_IMPLEMENTED);
return 0;
}
}
else /* Numeric type */
{
numeric_desc = get_fx_4_numeric_type_description(type, fx);
put_u32_unaligned(buffer, numeric_desc);
}
return offset;
}
static void write_fx_4_technique(struct hlsl_ir_var *var, struct fx_write_context *fx)
{
struct vkd3d_bytecode_buffer *buffer = &fx->structured;
uint32_t name_offset, count = 0;
struct hlsl_ir_var *pass;
uint32_t count_offset;
name_offset = write_string(var->name, fx);
put_u32(buffer, name_offset);
count_offset = put_u32(buffer, 0);
put_u32(buffer, 0); /* Annotation count. */
LIST_FOR_EACH_ENTRY(pass, &var->scope->vars, struct hlsl_ir_var, scope_entry)
{
write_pass(pass, fx);
++count;
}
set_u32(buffer, count_offset, count);
}
static void write_techniques(struct hlsl_scope *scope, struct fx_write_context *fx)
{
struct hlsl_ir_var *var;
LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry)
{
if (technique_matches_version(var, fx))
{
fx->ops->write_technique(var, fx);
++fx->technique_count;
}
}
set_status(fx, fx->unstructured.status);
set_status(fx, fx->structured.status);
}
static void write_group(struct hlsl_ir_var *var, struct fx_write_context *fx)
{
struct vkd3d_bytecode_buffer *buffer = &fx->structured;
uint32_t name_offset = write_string(var ? var->name : NULL, fx);
uint32_t count_offset, count;
put_u32(buffer, name_offset);
count_offset = put_u32(buffer, 0); /* Technique count */
put_u32(buffer, 0); /* Annotation count */
count = fx->technique_count;
write_techniques(var ? var->scope : fx->ctx->globals, fx);
set_u32(buffer, count_offset, fx->technique_count - count);
++fx->group_count;
}
static void write_groups(struct fx_write_context *fx)
{
struct hlsl_scope *scope = fx->ctx->globals;
bool needs_default_group = false;
struct hlsl_ir_var *var;
LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry)
{
if (technique_matches_version(var, fx))
{
needs_default_group = true;
break;
}
}
if (needs_default_group)
write_group(NULL, fx);
LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry)
{
const struct hlsl_type *type = var->data_type;
if (type->base_type == HLSL_TYPE_EFFECT_GROUP)
write_group(var, fx);
}
}
static uint32_t write_fx_2_string(const char *string, struct fx_write_context *fx)
{
struct vkd3d_bytecode_buffer *buffer = &fx->unstructured;
const char *s = string ? string : "";
uint32_t size, offset;
size = strlen(s) + 1;
offset = put_u32(buffer, size);
bytecode_put_bytes(buffer, s, size);
return offset;
}
static void write_fx_2_technique(struct hlsl_ir_var *var, struct fx_write_context *fx)
{
struct vkd3d_bytecode_buffer *buffer = &fx->structured;
uint32_t name_offset, count_offset, count = 0;
struct hlsl_ir_var *pass;
name_offset = write_string(var->name, fx);
put_u32(buffer, name_offset);
put_u32(buffer, 0); /* Annotation count. */
count_offset = put_u32(buffer, 0); /* Pass count. */
/* FIXME: annotations */
LIST_FOR_EACH_ENTRY(pass, &var->scope->vars, struct hlsl_ir_var, scope_entry)
{
write_pass(pass, fx);
++count;
}
set_u32(buffer, count_offset, count);
}
static const struct fx_write_context_ops fx_2_ops =
{
.write_string = write_fx_2_string,
.write_technique = write_fx_2_technique,
.write_pass = write_fx_2_pass,
};
static int hlsl_fx_2_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out)
{
struct vkd3d_bytecode_buffer buffer = { 0 };
struct vkd3d_bytecode_buffer *structured;
uint32_t offset, size, technique_count;
struct fx_write_context fx;
fx_write_context_init(ctx, &fx_2_ops, &fx);
structured = &fx.structured;
/* First entry is always zeroed and skipped. */
put_u32(&fx.unstructured, 0);
put_u32(&buffer, 0xfeff0901); /* Version. */
offset = put_u32(&buffer, 0);
put_u32(structured, 0); /* Parameter count */
technique_count = put_u32(structured, 0);
put_u32(structured, 0); /* Unknown */
put_u32(structured, 0); /* Object count */
/* TODO: parameters */
write_techniques(ctx->globals, &fx);
set_u32(structured, technique_count, fx.technique_count);
put_u32(structured, 0); /* String count */
put_u32(structured, 0); /* Resource count */
/* TODO: strings */
/* TODO: resources */
size = align(fx.unstructured.size, 4);
set_u32(&buffer, offset, size);
bytecode_put_bytes(&buffer, fx.unstructured.data, fx.unstructured.size);
bytecode_put_bytes(&buffer, fx.structured.data, fx.structured.size);
vkd3d_free(fx.unstructured.data);
vkd3d_free(fx.structured.data);
if (!fx.status)
{
out->code = buffer.data;
out->size = buffer.size;
}
if (fx.status < 0)
ctx->result = fx.status;
return fx_write_context_cleanup(&fx);
}
static const struct fx_write_context_ops fx_4_ops =
{
.write_string = write_fx_4_string,
.write_type = write_fx_4_type,
.write_technique = write_fx_4_technique,
.write_pass = write_fx_4_pass,
};
static void write_fx_4_numeric_variable(struct hlsl_ir_var *var, struct fx_write_context *fx)
{
struct vkd3d_bytecode_buffer *buffer = &fx->structured;
uint32_t semantic_offset, flags = 0;
uint32_t name_offset, type_offset;
enum fx_4_numeric_variable_flags
{
HAS_EXPLICIT_BIND_POINT = 0x4,
};
/* Explicit bind point. */
if (var->reg_reservation.reg_type)
flags |= HAS_EXPLICIT_BIND_POINT;
type_offset = write_type(var->data_type, fx);
name_offset = write_string(var->name, fx);
semantic_offset = write_string(var->semantic.name, fx);
put_u32(buffer, name_offset);
put_u32(buffer, type_offset);
semantic_offset = put_u32(buffer, semantic_offset); /* Semantic */
put_u32(buffer, var->buffer_offset); /* Offset in the constant buffer */
put_u32(buffer, 0); /* FIXME: default value offset */
put_u32(buffer, flags); /* Flags */
put_u32(buffer, 0); /* Annotations count */
/* FIXME: write annotations */
}
static void write_fx_4_object_variable(struct hlsl_ir_var *var, struct fx_write_context *fx)
{
struct vkd3d_bytecode_buffer *buffer = &fx->structured;
uint32_t semantic_offset, bind_point = ~0u;
uint32_t name_offset, type_offset;
if (var->reg_reservation.reg_type)
bind_point = var->reg_reservation.reg_index;
type_offset = write_type(var->data_type, fx);
name_offset = write_string(var->name, fx);
semantic_offset = write_string(var->semantic.name, fx);
put_u32(buffer, name_offset);
put_u32(buffer, type_offset);
semantic_offset = put_u32(buffer, semantic_offset); /* Semantic */
put_u32(buffer, bind_point); /* Explicit bind point */
put_u32(buffer, 0); /* Annotations count */
/* FIXME: write annotations */
}
static void write_fx_4_buffer(struct hlsl_buffer *b, struct fx_write_context *fx)
{
enum fx_4_buffer_flags
{
IS_TBUFFER = 0x1,
IS_SINGLE = 0x2,
};
struct vkd3d_bytecode_buffer *buffer = &fx->structured;
uint32_t count = 0, bind_point = ~0u, flags = 0, size;
uint32_t name_offset, size_offset;
struct hlsl_ctx *ctx = fx->ctx;
struct hlsl_ir_var *var;
uint32_t count_offset;
if (b->reservation.reg_type)
bind_point = b->reservation.reg_index;
if (b->type == HLSL_BUFFER_TEXTURE)
flags |= IS_TBUFFER;
/* FIXME: set 'single' flag for fx_5_0 */
name_offset = write_string(b->name, fx);
put_u32(buffer, name_offset); /* Name */
size_offset = put_u32(buffer, 0); /* Data size */
put_u32(buffer, flags); /* Flags */
count_offset = put_u32(buffer, 0);
put_u32(buffer, bind_point); /* Bind point */
put_u32(buffer, 0); /* Annotations count */
/* FIXME: write annotations */
count = 0;
size = 0;
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
{
if (var->buffer != b)
continue;
write_fx_4_numeric_variable(var, fx);
size += get_fx_4_type_size(var->data_type);
++count;
}
set_u32(buffer, count_offset, count);
set_u32(buffer, size_offset, align(size, 16));
fx->numeric_variable_count += count;
}
static void write_buffers(struct fx_write_context *fx)
{
struct hlsl_buffer *buffer;
struct hlsl_block block;
hlsl_block_init(&block);
hlsl_prepend_global_uniform_copy(fx->ctx, &block);
hlsl_block_init(&block);
hlsl_calculate_buffer_offsets(fx->ctx);
LIST_FOR_EACH_ENTRY(buffer, &fx->ctx->buffers, struct hlsl_buffer, entry)
{
if (!buffer->size)
continue;
write_fx_4_buffer(buffer, fx);
++fx->buffer_count;
}
}
static bool is_object_variable(const struct hlsl_ir_var *var)
{
const struct hlsl_type *type = hlsl_get_multiarray_element_type(var->data_type);
if (type->class != HLSL_CLASS_OBJECT)
return false;
switch (type->base_type)
{
case HLSL_TYPE_SAMPLER:
case HLSL_TYPE_TEXTURE:
case HLSL_TYPE_UAV:
case HLSL_TYPE_PIXELSHADER:
case HLSL_TYPE_VERTEXSHADER:
case HLSL_TYPE_RENDERTARGETVIEW:
return true;
default:
return false;
}
}
static void write_objects(struct fx_write_context *fx)
{
struct hlsl_ir_var *var;
uint32_t count = 0;
LIST_FOR_EACH_ENTRY(var, &fx->ctx->extern_vars, struct hlsl_ir_var, extern_entry)
{
if (!is_object_variable(var))
continue;
write_fx_4_object_variable(var, fx);
++count;
}
fx->object_variable_count += count;
}
static int hlsl_fx_4_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out)
{
struct vkd3d_bytecode_buffer buffer = { 0 };
struct fx_write_context fx;
uint32_t size_offset;
fx_write_context_init(ctx, &fx_4_ops, &fx);
put_u32(&fx.unstructured, 0); /* Empty string placeholder. */
write_buffers(&fx);
write_objects(&fx);
/* TODO: shared buffers */
/* TODO: shared objects */
write_techniques(ctx->globals, &fx);
put_u32(&buffer, ctx->profile->minor_version == 0 ? 0xfeff1001 : 0xfeff1011); /* Version. */
put_u32(&buffer, fx.buffer_count); /* Buffer count. */
put_u32(&buffer, fx.numeric_variable_count); /* Numeric variable count. */
put_u32(&buffer, fx.object_variable_count); /* Object variable count. */
put_u32(&buffer, 0); /* Pool buffer count. */
put_u32(&buffer, 0); /* Pool variable count. */
put_u32(&buffer, 0); /* Pool object count. */
put_u32(&buffer, fx.technique_count);
size_offset = put_u32(&buffer, 0); /* Unstructured size. */
put_u32(&buffer, 0); /* String count. */
put_u32(&buffer, 0); /* Texture object count. */
put_u32(&buffer, 0); /* Depth stencil state count. */
put_u32(&buffer, 0); /* Blend state count. */
put_u32(&buffer, 0); /* Rasterizer state count. */
put_u32(&buffer, 0); /* Sampler state count. */
put_u32(&buffer, 0); /* Rendertarget view count. */
put_u32(&buffer, 0); /* Depth stencil view count. */
put_u32(&buffer, 0); /* Shader count. */
put_u32(&buffer, 0); /* Inline shader count. */
set_u32(&buffer, size_offset, fx.unstructured.size);
bytecode_put_bytes(&buffer, fx.unstructured.data, fx.unstructured.size);
bytecode_put_bytes_unaligned(&buffer, fx.structured.data, fx.structured.size);
vkd3d_free(fx.unstructured.data);
vkd3d_free(fx.structured.data);
set_status(&fx, buffer.status);
if (!fx.status)
{
out->code = buffer.data;
out->size = buffer.size;
}
if (fx.status < 0)
ctx->result = fx.status;
return fx_write_context_cleanup(&fx);
}
static int hlsl_fx_5_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out)
{
struct vkd3d_bytecode_buffer buffer = { 0 };
struct fx_write_context fx;
uint32_t size_offset;
fx_write_context_init(ctx, &fx_4_ops, &fx);
put_u32(&fx.unstructured, 0); /* Empty string placeholder. */
write_buffers(&fx);
write_objects(&fx);
/* TODO: interface variables */
write_groups(&fx);
put_u32(&buffer, 0xfeff2001); /* Version. */
put_u32(&buffer, fx.buffer_count); /* Buffer count. */
put_u32(&buffer, fx.numeric_variable_count); /* Numeric variable count. */
put_u32(&buffer, fx.object_variable_count); /* Object variable count. */
put_u32(&buffer, 0); /* Pool buffer count. */
put_u32(&buffer, 0); /* Pool variable count. */
put_u32(&buffer, 0); /* Pool object count. */
put_u32(&buffer, fx.technique_count);
size_offset = put_u32(&buffer, 0); /* Unstructured size. */
put_u32(&buffer, 0); /* String count. */
put_u32(&buffer, 0); /* Texture object count. */
put_u32(&buffer, 0); /* Depth stencil state count. */
put_u32(&buffer, 0); /* Blend state count. */
put_u32(&buffer, 0); /* Rasterizer state count. */
put_u32(&buffer, 0); /* Sampler state count. */
put_u32(&buffer, 0); /* Rendertarget view count. */
put_u32(&buffer, 0); /* Depth stencil view count. */
put_u32(&buffer, 0); /* Shader count. */
put_u32(&buffer, 0); /* Inline shader count. */
put_u32(&buffer, fx.group_count); /* Group count. */
put_u32(&buffer, 0); /* UAV count. */
put_u32(&buffer, 0); /* Interface variables count. */
put_u32(&buffer, 0); /* Interface variable element count. */
put_u32(&buffer, 0); /* Class instance elements count. */
set_u32(&buffer, size_offset, fx.unstructured.size);
bytecode_put_bytes(&buffer, fx.unstructured.data, fx.unstructured.size);
bytecode_put_bytes_unaligned(&buffer, fx.structured.data, fx.structured.size);
vkd3d_free(fx.unstructured.data);
vkd3d_free(fx.structured.data);
set_status(&fx, buffer.status);
if (!fx.status)
{
out->code = buffer.data;
out->size = buffer.size;
}
if (fx.status < 0)
ctx->result = fx.status;
return fx_write_context_cleanup(&fx);
}
int hlsl_emit_effect_binary(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out)
{
if (ctx->profile->major_version == 2)
{
return hlsl_fx_2_write(ctx, out);
}
else if (ctx->profile->major_version == 4)
{
return hlsl_fx_4_write(ctx, out);
}
else if (ctx->profile->major_version == 5)
{
return hlsl_fx_5_write(ctx, out);
}
else
{
vkd3d_unreachable();
}
}

View file

@ -91,7 +91,7 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *generator
}
int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *generator,
struct vkd3d_shader_parser *parser, struct vkd3d_shader_code *out)
struct vsir_program *program, struct vkd3d_shader_code *out)
{
unsigned int i;
void *code;
@ -100,10 +100,10 @@ int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *generator,
vkd3d_string_buffer_printf(&generator->buffer, "void main()\n{\n");
generator->location.column = 0;
for (i = 0; i < parser->instructions.count; ++i)
for (i = 0; i < program->instructions.count; ++i)
{
generator->location.line = i + 1;
vkd3d_glsl_handle_instruction(generator, &parser->instructions.elements[i]);
vkd3d_glsl_handle_instruction(generator, &program->instructions.elements[i]);
}
if (generator->failed)

View file

@ -98,19 +98,22 @@ bool hlsl_add_var(struct hlsl_ctx *ctx, struct hlsl_ir_var *decl, bool local_var
struct hlsl_scope *scope = ctx->cur_scope;
struct hlsl_ir_var *var;
LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry)
if (decl->name)
{
if (!strcmp(decl->name, var->name))
return false;
}
if (local_var && scope->upper->upper == ctx->globals)
{
/* Check whether the variable redefines a function parameter. */
LIST_FOR_EACH_ENTRY(var, &scope->upper->vars, struct hlsl_ir_var, scope_entry)
LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry)
{
if (!strcmp(decl->name, var->name))
if (var->name && !strcmp(decl->name, var->name))
return false;
}
if (local_var && scope->upper->upper == ctx->globals)
{
/* Check whether the variable redefines a function parameter. */
LIST_FOR_EACH_ENTRY(var, &scope->upper->vars, struct hlsl_ir_var, scope_entry)
{
if (var->name && !strcmp(decl->name, var->name))
return false;
}
}
}
list_add_tail(&scope->vars, &decl->scope_entry);
@ -123,7 +126,7 @@ struct hlsl_ir_var *hlsl_get_var(struct hlsl_scope *scope, const char *name)
LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry)
{
if (!strcmp(name, var->name))
if (var->name && !strcmp(name, var->name))
return var;
}
if (!scope->upper)
@ -748,14 +751,15 @@ struct hlsl_type *hlsl_new_texture_type(struct hlsl_ctx *ctx, enum hlsl_sampler_
type->dimx = 4;
type->dimy = 1;
type->sampler_dim = dim;
type->e.resource_format = format;
type->e.resource.format = format;
type->sample_count = sample_count;
hlsl_type_calculate_reg_size(ctx, type);
list_add_tail(&ctx->types, &type->entry);
return type;
}
struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, struct hlsl_type *format)
struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim,
struct hlsl_type *format, bool rasteriser_ordered)
{
struct hlsl_type *type;
@ -766,7 +770,8 @@ struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim
type->dimx = format->dimx;
type->dimy = 1;
type->sampler_dim = dim;
type->e.resource_format = format;
type->e.resource.format = format;
type->e.resource.rasteriser_ordered = rasteriser_ordered;
hlsl_type_calculate_reg_size(ctx, type);
list_add_tail(&ctx->types, &type->entry);
return type;
@ -882,8 +887,11 @@ bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2
{
if (t1->sampler_dim != t2->sampler_dim)
return false;
if (t1->base_type == HLSL_TYPE_TEXTURE && t1->sampler_dim != HLSL_SAMPLER_DIM_GENERIC
&& !hlsl_types_are_equal(t1->e.resource_format, t2->e.resource_format))
if ((t1->base_type == HLSL_TYPE_TEXTURE || t1->base_type == HLSL_TYPE_UAV)
&& t1->sampler_dim != HLSL_SAMPLER_DIM_GENERIC
&& !hlsl_types_are_equal(t1->e.resource.format, t2->e.resource.format))
return false;
if (t1->base_type == HLSL_TYPE_UAV && t1->e.resource.rasteriser_ordered != t2->e.resource.rasteriser_ordered)
return false;
}
if ((t1->modifiers & HLSL_MODIFIER_ROW_MAJOR)
@ -915,12 +923,17 @@ bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2
if (t1->class == HLSL_CLASS_ARRAY)
return t1->e.array.elements_count == t2->e.array.elements_count
&& hlsl_types_are_equal(t1->e.array.type, t2->e.array.type);
if (t1->class == HLSL_CLASS_OBJECT)
{
if (t1->base_type == HLSL_TYPE_TECHNIQUE && t1->e.version != t2->e.version)
return false;
}
return true;
}
struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old,
unsigned int default_majority, unsigned int modifiers)
unsigned int default_majority, uint32_t modifiers)
{
struct hlsl_type *type;
@ -945,6 +958,8 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old,
type->modifiers |= default_majority;
type->sampler_dim = old->sampler_dim;
type->is_minimum_precision = old->is_minimum_precision;
type->sample_count = old->sample_count;
switch (old->class)
{
case HLSL_CLASS_ARRAY:
@ -993,6 +1008,16 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old,
break;
}
case HLSL_CLASS_OBJECT:
if (type->base_type == HLSL_TYPE_TECHNIQUE)
type->e.version = old->e.version;
if (old->base_type == HLSL_TYPE_TEXTURE || old->base_type == HLSL_TYPE_UAV)
{
type->e.resource.format = old->e.resource.format;
type->e.resource.rasteriser_ordered = old->e.resource.rasteriser_ordered;
}
break;
default:
break;
}
@ -1030,7 +1055,7 @@ struct hlsl_ir_node *hlsl_new_copy(struct hlsl_ctx *ctx, struct hlsl_ir_node *no
}
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 vkd3d_shader_location *loc, const struct hlsl_semantic *semantic, uint32_t modifiers,
const struct hlsl_reg_reservation *reg_reservation)
{
struct hlsl_ir_var *var;
@ -1505,7 +1530,7 @@ struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, const struct
return &store->node;
}
struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned int components,
struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned int components,
struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc)
{
struct hlsl_ir_swizzle *swizzle;
@ -1535,6 +1560,15 @@ bool hlsl_index_is_resource_access(struct hlsl_ir_index *index)
return index->val.node->data_type->class == HLSL_CLASS_OBJECT;
}
bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index)
{
if (hlsl_index_is_resource_access(index))
return true;
if (index->val.node->type == HLSL_IR_INDEX)
return hlsl_index_chain_has_resource_access(hlsl_ir_index(index->val.node));
return false;
}
struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *val,
struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc)
{
@ -1545,7 +1579,7 @@ struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *v
return NULL;
if (type->class == HLSL_CLASS_OBJECT)
type = type->e.resource_format;
type = type->e.resource.format;
else if (type->class == HLSL_CLASS_MATRIX)
type = hlsl_get_vector_type(ctx, type->base_type, type->dimx);
else
@ -2173,10 +2207,17 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru
return string;
}
assert(type->sampler_dim < ARRAY_SIZE(dimensions));
assert(type->e.resource_format->base_type < ARRAY_SIZE(base_types));
vkd3d_string_buffer_printf(string, "Texture%s", dimensions[type->sampler_dim]);
if ((inner_string = hlsl_type_to_string(ctx, type->e.resource_format)))
assert(type->e.resource.format->base_type < ARRAY_SIZE(base_types));
if (type->sampler_dim == HLSL_SAMPLER_DIM_BUFFER)
{
vkd3d_string_buffer_printf(string, "Buffer");
}
else
{
assert(type->sampler_dim < ARRAY_SIZE(dimensions));
vkd3d_string_buffer_printf(string, "Texture%s", dimensions[type->sampler_dim]);
}
if ((inner_string = hlsl_type_to_string(ctx, type->e.resource.format)))
{
vkd3d_string_buffer_printf(string, "<%s>", inner_string->buffer);
hlsl_release_string_buffer(ctx, inner_string);
@ -2190,7 +2231,7 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru
vkd3d_string_buffer_printf(string, "RWStructuredBuffer");
else
vkd3d_string_buffer_printf(string, "RWTexture%s", dimensions[type->sampler_dim]);
if ((inner_string = hlsl_type_to_string(ctx, type->e.resource_format)))
if ((inner_string = hlsl_type_to_string(ctx, type->e.resource.format)))
{
vkd3d_string_buffer_printf(string, "<%s>", inner_string->buffer);
hlsl_release_string_buffer(ctx, inner_string);
@ -2246,7 +2287,7 @@ const char *debug_hlsl_type(struct hlsl_ctx *ctx, const struct hlsl_type *type)
return ret;
}
struct vkd3d_string_buffer *hlsl_modifiers_to_string(struct hlsl_ctx *ctx, unsigned int modifiers)
struct vkd3d_string_buffer *hlsl_modifiers_to_string(struct hlsl_ctx *ctx, uint32_t modifiers)
{
struct vkd3d_string_buffer *string;
@ -2432,7 +2473,7 @@ const char *debug_hlsl_writemask(unsigned int writemask)
return vkd3d_dbg_sprintf(".%s", string);
}
const char *debug_hlsl_swizzle(unsigned int swizzle, unsigned int size)
const char *debug_hlsl_swizzle(uint32_t swizzle, unsigned int size)
{
static const char components[] = {'x', 'y', 'z', 'w'};
char string[5];
@ -2976,7 +3017,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.rel_offset);
hlsl_cleanup_deref(&store->resource);
hlsl_src_remove(&store->coords);
hlsl_src_remove(&store->value);
vkd3d_free(store);
@ -3147,9 +3188,10 @@ void hlsl_add_function(struct hlsl_ctx *ctx, char *name, struct hlsl_ir_function
rb_put(&ctx->functions, func->name, &func->entry);
}
unsigned int hlsl_map_swizzle(unsigned int swizzle, unsigned int writemask)
uint32_t hlsl_map_swizzle(uint32_t swizzle, unsigned int writemask)
{
unsigned int i, ret = 0;
uint32_t ret = 0;
unsigned int i;
/* Leave replicate swizzles alone; some instructions need them. */
if (swizzle == HLSL_SWIZZLE(X, X, X, X)
@ -3169,7 +3211,7 @@ unsigned int hlsl_map_swizzle(unsigned int swizzle, unsigned int writemask)
return ret;
}
unsigned int hlsl_swizzle_from_writemask(unsigned int writemask)
uint32_t hlsl_swizzle_from_writemask(unsigned int writemask)
{
static const unsigned int swizzles[16] =
{
@ -3210,9 +3252,10 @@ unsigned int hlsl_combine_writemasks(unsigned int first, unsigned int second)
return ret;
}
unsigned int hlsl_combine_swizzles(unsigned int first, unsigned int second, unsigned int dim)
uint32_t hlsl_combine_swizzles(uint32_t first, uint32_t second, unsigned int dim)
{
unsigned int ret = 0, i;
uint32_t ret = 0;
unsigned int i;
for (i = 0; i < dim; ++i)
{
unsigned int s = hlsl_swizzle_get_component(second, i);
@ -3338,7 +3381,7 @@ static void declare_predefined_types(struct hlsl_ctx *ctx)
static const struct
{
char name[13];
char name[20];
enum hlsl_type_class class;
enum hlsl_base_type base_type;
unsigned int dimx, dimy;
@ -3346,13 +3389,28 @@ static void declare_predefined_types(struct hlsl_ctx *ctx)
effect_types[] =
{
{"dword", HLSL_CLASS_SCALAR, HLSL_TYPE_UINT, 1, 1},
{"float", HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1},
{"vector", HLSL_CLASS_VECTOR, HLSL_TYPE_FLOAT, 4, 1},
{"matrix", HLSL_CLASS_MATRIX, HLSL_TYPE_FLOAT, 4, 4},
{"fxgroup", HLSL_CLASS_OBJECT, HLSL_TYPE_EFFECT_GROUP, 1, 1},
{"pass", HLSL_CLASS_OBJECT, HLSL_TYPE_PASS, 1, 1},
{"STRING", HLSL_CLASS_OBJECT, HLSL_TYPE_STRING, 1, 1},
{"TEXTURE", HLSL_CLASS_OBJECT, HLSL_TYPE_TEXTURE, 1, 1},
{"PIXELSHADER", HLSL_CLASS_OBJECT, HLSL_TYPE_PIXELSHADER, 1, 1},
{"VERTEXSHADER", HLSL_CLASS_OBJECT, HLSL_TYPE_VERTEXSHADER, 1, 1},
{"RenderTargetView",HLSL_CLASS_OBJECT, HLSL_TYPE_RENDERTARGETVIEW, 1, 1},
{"DepthStencilView",HLSL_CLASS_OBJECT, HLSL_TYPE_DEPTHSTENCILVIEW, 1, 1},
};
static const struct
{
const char *name;
unsigned int version;
}
technique_types[] =
{
{"technique", 9},
{"technique10", 10},
{"technique11", 11},
};
for (bt = 0; bt <= HLSL_TYPE_LAST_SCALAR; ++bt)
@ -3459,6 +3517,13 @@ static void declare_predefined_types(struct hlsl_ctx *ctx)
effect_types[i].base_type, effect_types[i].dimx, effect_types[i].dimy);
hlsl_scope_add_type(ctx->globals, type);
}
for (i = 0; i < ARRAY_SIZE(technique_types); ++i)
{
type = hlsl_new_type(ctx, technique_types[i].name, HLSL_CLASS_OBJECT, HLSL_TYPE_TECHNIQUE, 1, 1);
type->e.version = technique_types[i].version;
hlsl_scope_add_type(ctx->globals, type);
}
}
static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info,
@ -3594,7 +3659,13 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
return VKD3D_ERROR_NOT_IMPLEMENTED;
}
if (compile_info->target_type == VKD3D_SHADER_TARGET_D3D_BYTECODE && profile->major_version > 3)
if (compile_info->target_type != VKD3D_SHADER_TARGET_FX && profile->type == VKD3D_SHADER_TYPE_EFFECT)
{
vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE,
"The '%s' target profile is only compatible with the 'fx' target type.", profile->name);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
else 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,
"The '%s' target profile is incompatible with the 'd3dbc' target type.", profile->name);
@ -3606,6 +3677,12 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
"The '%s' target profile is incompatible with the 'dxbc-tpf' target type.", profile->name);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
else if (compile_info->target_type == VKD3D_SHADER_TARGET_FX && profile->type != VKD3D_SHADER_TYPE_EFFECT)
{
vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE,
"The '%s' target profile is incompatible with the 'fx' target type.", profile->name);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
if (!hlsl_ctx_init(&ctx, compile_info, profile, message_context))
return VKD3D_ERROR_OUT_OF_MEMORY;
@ -3630,6 +3707,14 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
return VKD3D_ERROR_NOT_IMPLEMENTED;
}
if (ctx.profile->type == VKD3D_SHADER_TYPE_EFFECT)
{
ret = hlsl_emit_effect_binary(&ctx, out);
hlsl_ctx_cleanup(&ctx);
return ret;
}
if ((func = hlsl_get_function(&ctx, entry_point)))
{
LIST_FOR_EACH_ENTRY(decl, &func->overloads, struct hlsl_ir_function_decl, entry)

View file

@ -65,7 +65,7 @@
#define HLSL_SWIZZLE_MASK (0x3u)
#define HLSL_SWIZZLE_SHIFT(idx) (2u * (idx))
static inline unsigned int hlsl_swizzle_get_component(unsigned int swizzle, unsigned int idx)
static inline unsigned int hlsl_swizzle_get_component(uint32_t swizzle, unsigned int idx)
{
return (swizzle >> HLSL_SWIZZLE_SHIFT(idx)) & HLSL_SWIZZLE_MASK;
}
@ -95,13 +95,18 @@ enum hlsl_base_type
HLSL_TYPE_UAV,
HLSL_TYPE_PIXELSHADER,
HLSL_TYPE_VERTEXSHADER,
HLSL_TYPE_PASS,
HLSL_TYPE_RENDERTARGETVIEW,
HLSL_TYPE_DEPTHSTENCILVIEW,
HLSL_TYPE_TECHNIQUE,
HLSL_TYPE_EFFECT_GROUP,
HLSL_TYPE_STRING,
HLSL_TYPE_VOID,
};
enum hlsl_sampler_dim
{
HLSL_SAMPLER_DIM_GENERIC,
HLSL_SAMPLER_DIM_GENERIC = 0,
HLSL_SAMPLER_DIM_COMPARISON,
HLSL_SAMPLER_DIM_1D,
HLSL_SAMPLER_DIM_2D,
@ -113,10 +118,10 @@ enum hlsl_sampler_dim
HLSL_SAMPLER_DIM_2DMS,
HLSL_SAMPLER_DIM_2DMSARRAY,
HLSL_SAMPLER_DIM_CUBEARRAY,
HLSL_SAMPLER_DIM_LAST_TEXTURE = HLSL_SAMPLER_DIM_CUBEARRAY,
HLSL_SAMPLER_DIM_BUFFER,
HLSL_SAMPLER_DIM_STRUCTURED_BUFFER,
HLSL_SAMPLER_DIM_MAX = HLSL_SAMPLER_DIM_STRUCTURED_BUFFER,
/* NOTE: Remember to update object_methods[] in hlsl.y if this enum is modified. */
};
enum hlsl_regset
@ -138,13 +143,16 @@ struct hlsl_type
struct rb_entry scope_entry;
enum hlsl_type_class class;
/* If type is <= HLSL_CLASS_LAST_NUMERIC, then base_type is <= HLSL_TYPE_LAST_SCALAR.
* If type is HLSL_CLASS_OBJECT, then base_type is > HLSL_TYPE_LAST_SCALAR.
/* If class is <= HLSL_CLASS_LAST_NUMERIC, then base_type is <= HLSL_TYPE_LAST_SCALAR.
* If class is HLSL_CLASS_OBJECT, then base_type is > HLSL_TYPE_LAST_SCALAR.
* If class is HLSL_CLASS_OBJECT and base_type is HLSL_TYPE_TECHNIQUE, additional version
* field is used to distinguish between technique types.
* Otherwise, base_type is not used. */
enum hlsl_base_type base_type;
/* If base_type is HLSL_TYPE_SAMPLER, then sampler_dim is <= HLSL_SAMPLER_DIM_LAST_SAMPLER.
* If base_type is HLSL_TYPE_TEXTURE, then sampler_dim is <= HLSL_SAMPLER_DIM_LAST_TEXTURE.
* If base_type is HLSL_TYPE_TEXTURE, then sampler_dim can be any value of the enum except
* HLSL_SAMPLER_DIM_GENERIC and HLSL_SAMPLER_DIM_COMPARISON.
* If base_type is HLSL_TYPE_UAV, then sampler_dim must be one of HLSL_SAMPLER_DIM_1D,
* HLSL_SAMPLER_DIM_2D, HLSL_SAMPLER_DIM_3D, HLSL_SAMPLER_DIM_1DARRAY, HLSL_SAMPLER_DIM_2DARRAY,
* HLSL_SAMPLER_DIM_BUFFER, or HLSL_SAMPLER_DIM_STRUCTURED_BUFFER.
@ -155,7 +163,7 @@ struct hlsl_type
/* Bitfield for storing type modifiers, subset of HLSL_TYPE_MODIFIERS_MASK.
* Modifiers that don't fall inside this mask are to be stored in the variable in
* hlsl_ir_var.modifiers, or in the struct field in hlsl_ir_field.modifiers. */
unsigned int modifiers;
uint32_t modifiers;
/* Size of the type values on each dimension. For non-numeric types, they are set for the
* convenience of the sm1/sm4 backends.
* If type is HLSL_CLASS_SCALAR, then both dimx = 1 and dimy = 1.
@ -188,9 +196,17 @@ struct hlsl_type
/* Array length, or HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT if it is not known yet at parse time. */
unsigned int elements_count;
} array;
/* Format of the data contained within the type if the base_type is HLSL_TYPE_TEXTURE or
* HLSL_TYPE_UAV. */
struct hlsl_type *resource_format;
/* Additional information if the base_type is HLSL_TYPE_TEXTURE or
* HLSL_TYPE_UAV. */
struct
{
/* Format of the data contained within the type. */
struct hlsl_type *format;
/* The type is a rasteriser-ordered view. */
bool rasteriser_ordered;
} resource;
/* Additional field to distinguish object types. Currently used only for technique types. */
unsigned int version;
} e;
/* Number of numeric register components used by one value of this type, for each regset.
@ -234,7 +250,7 @@ struct hlsl_struct_field
/* Bitfield for storing modifiers that are not in HLSL_TYPE_MODIFIERS_MASK (these are stored in
* type->modifiers instead) and that also are specific to the field and not the whole variable.
* In particular, interpolation modifiers. */
unsigned int storage_modifiers;
uint32_t storage_modifiers;
/* Offset of the field within the type it belongs to, in register components, for each regset. */
unsigned int reg_offset[HLSL_REGSET_LAST + 1];
@ -341,23 +357,23 @@ struct hlsl_attribute
struct hlsl_src args[];
};
#define HLSL_STORAGE_EXTERN 0x00000001
#define HLSL_STORAGE_NOINTERPOLATION 0x00000002
#define HLSL_MODIFIER_PRECISE 0x00000004
#define HLSL_STORAGE_SHARED 0x00000008
#define HLSL_STORAGE_GROUPSHARED 0x00000010
#define HLSL_STORAGE_STATIC 0x00000020
#define HLSL_STORAGE_UNIFORM 0x00000040
#define HLSL_MODIFIER_VOLATILE 0x00000080
#define HLSL_MODIFIER_CONST 0x00000100
#define HLSL_MODIFIER_ROW_MAJOR 0x00000200
#define HLSL_MODIFIER_COLUMN_MAJOR 0x00000400
#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_STORAGE_EXTERN 0x00000001
#define HLSL_STORAGE_NOINTERPOLATION 0x00000002
#define HLSL_MODIFIER_PRECISE 0x00000004
#define HLSL_STORAGE_SHARED 0x00000008
#define HLSL_STORAGE_GROUPSHARED 0x00000010
#define HLSL_STORAGE_STATIC 0x00000020
#define HLSL_STORAGE_UNIFORM 0x00000040
#define HLSL_MODIFIER_VOLATILE 0x00000080
#define HLSL_MODIFIER_CONST 0x00000100
#define HLSL_MODIFIER_ROW_MAJOR 0x00000200
#define HLSL_MODIFIER_COLUMN_MAJOR 0x00000400
#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 | \
@ -392,7 +408,7 @@ struct hlsl_ir_var
/* Buffer where the variable's value is stored, in case it is uniform. */
struct hlsl_buffer *buffer;
/* Bitfield for storage modifiers (type modifiers are stored in data_type->modifiers). */
unsigned int storage_modifiers;
uint32_t storage_modifiers;
/* Optional reservations of registers and/or offsets for variables within constant buffers. */
struct hlsl_reg_reservation reg_reservation;
@ -400,6 +416,10 @@ struct hlsl_ir_var
struct list scope_entry;
/* Item entry in hlsl_ctx.extern_vars, if the variable is extern. */
struct list extern_entry;
/* Scope that variable itself defines, used to provide a container for techniques and passes. */
struct hlsl_scope *scope;
/* Scope that contains annotations for this variable. */
struct hlsl_scope *annotations;
/* Indexes of the IR instructions where the variable is first written and last read (liveness
* range). The IR instructions are numerated starting from 2, because 0 means unused, and 1
@ -622,7 +642,7 @@ struct hlsl_ir_swizzle
{
struct hlsl_ir_node node;
struct hlsl_src val;
DWORD swizzle;
uint32_t swizzle;
};
struct hlsl_ir_index
@ -1135,6 +1155,11 @@ static inline unsigned int hlsl_sampler_dim_count(enum hlsl_sampler_dim dim)
}
}
static inline bool hlsl_var_has_buffer_offset_register_reservation(struct hlsl_ctx *ctx, const struct hlsl_ir_var *var)
{
return var->reg_reservation.reg_type == 'c' && var->buffer == ctx->globals_buffer;
}
char *hlsl_sprintf_alloc(struct hlsl_ctx *ctx, const char *fmt, ...) VKD3D_PRINTF_FUNC(2, 3);
const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op);
@ -1160,6 +1185,7 @@ void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl
int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func,
enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out);
int hlsl_emit_effect_binary(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out);
bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_node *chain);
bool hlsl_copy_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, const struct hlsl_deref *other);
@ -1239,6 +1265,7 @@ bool hlsl_new_store_component(struct hlsl_ctx *ctx, struct hlsl_block *block,
bool hlsl_index_is_noncontiguous(struct hlsl_ir_index *index);
bool hlsl_index_is_resource_access(struct hlsl_ir_index *index);
bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index);
struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *val,
struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc);
@ -1250,7 +1277,7 @@ struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, const struct
struct hlsl_ir_node *coords, struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc);
struct hlsl_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const char *name,
struct hlsl_struct_field *fields, size_t field_count);
struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned int components,
struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned int components,
struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc);
struct hlsl_ir_var *hlsl_new_synthetic_var(struct hlsl_ctx *ctx, const char *template,
struct hlsl_type *type, const struct vkd3d_shader_location *loc);
@ -1258,13 +1285,14 @@ struct hlsl_ir_var *hlsl_new_synthetic_var_named(struct hlsl_ctx *ctx, const cha
struct hlsl_type *type, const struct vkd3d_shader_location *loc, bool dummy_scope);
struct hlsl_type *hlsl_new_texture_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, struct hlsl_type *format,
unsigned int sample_count);
struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, struct hlsl_type *format);
struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim,
struct hlsl_type *format, bool rasteriser_ordered);
struct hlsl_ir_node *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned int n,
const struct vkd3d_shader_location *loc);
struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg,
const struct vkd3d_shader_location *loc);
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 vkd3d_shader_location *loc, const struct hlsl_semantic *semantic, uint32_t 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);
@ -1286,7 +1314,7 @@ void hlsl_pop_scope(struct hlsl_ctx *ctx);
bool hlsl_scope_add_type(struct hlsl_scope *scope, struct hlsl_type *type);
struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old,
unsigned int default_majority, unsigned int modifiers);
unsigned int default_majority, uint32_t modifiers);
unsigned int hlsl_type_component_count(const struct hlsl_type *type);
unsigned int hlsl_type_get_array_element_reg_size(const struct hlsl_type *type, enum hlsl_regset regset);
struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl_type *type,
@ -1301,13 +1329,16 @@ bool hlsl_type_is_resource(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);
void hlsl_calculate_buffer_offsets(struct hlsl_ctx *ctx);
void hlsl_prepend_global_uniform_copy(struct hlsl_ctx *ctx, struct hlsl_block *block);
const struct hlsl_type *hlsl_get_multiarray_element_type(const struct hlsl_type *type);
unsigned int hlsl_get_multiarray_size(const struct hlsl_type *type);
unsigned int hlsl_combine_swizzles(unsigned int first, unsigned int second, unsigned int dim);
uint32_t hlsl_combine_swizzles(uint32_t first, uint32_t second, unsigned int dim);
unsigned int hlsl_combine_writemasks(unsigned int first, unsigned int second);
unsigned int hlsl_map_swizzle(unsigned int swizzle, unsigned int writemask);
unsigned int hlsl_swizzle_from_writemask(unsigned int writemask);
uint32_t hlsl_map_swizzle(uint32_t swizzle, unsigned int writemask);
uint32_t 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);

View file

@ -89,6 +89,7 @@ else {return KW_ELSE; }
extern {return KW_EXTERN; }
false {return KW_FALSE; }
for {return KW_FOR; }
fxgroup {return KW_FXGROUP; }
GeometryShader {return KW_GEOMETRYSHADER; }
groupshared {return KW_GROUPSHARED; }
if {return KW_IF; }
@ -105,6 +106,13 @@ packoffset {return KW_PACKOFFSET; }
pass {return KW_PASS; }
PixelShader {return KW_PIXELSHADER; }
precise {return KW_PRECISE; }
RasterizerOrderedBuffer {return KW_RASTERIZERORDEREDBUFFER; }
RasterizerOrderedStructuredBuffer {return KW_RASTERIZERORDEREDSTRUCTUREDBUFFER; }
RasterizerOrderedTexture1D {return KW_RASTERIZERORDEREDTEXTURE1D; }
RasterizerOrderedTexture1DArray {return KW_RASTERIZERORDEREDTEXTURE1DARRAY; }
RasterizerOrderedTexture2D {return KW_RASTERIZERORDEREDTEXTURE2D; }
RasterizerOrderedTexture2DArray {return KW_RASTERIZERORDEREDTEXTURE2DARRAY; }
RasterizerOrderedTexture3D {return KW_RASTERIZERORDEREDTEXTURE3D; }
RasterizerState {return KW_RASTERIZERSTATE; }
register {return KW_REGISTER; }
RenderTargetView {return KW_RENDERTARGETVIEW; }

File diff suppressed because it is too large Load diff

View file

@ -32,6 +32,11 @@ static struct hlsl_ir_node *new_offset_from_path_index(struct hlsl_ctx *ctx, str
switch (type->class)
{
case HLSL_CLASS_VECTOR:
if (idx->type != HLSL_IR_CONSTANT)
{
hlsl_fixme(ctx, &idx->loc, "Non-constant vector addressing.");
break;
}
*offset_component += hlsl_ir_constant(idx)->value.u[0].u;
break;
@ -263,7 +268,7 @@ static bool types_are_semantic_equivalent(struct hlsl_ctx *ctx, const struct hls
}
static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir_var *var,
struct hlsl_type *type, unsigned int modifiers, struct hlsl_semantic *semantic,
struct hlsl_type *type, uint32_t modifiers, struct hlsl_semantic *semantic,
uint32_t index, bool output, const struct vkd3d_shader_location *loc)
{
struct hlsl_semantic new_semantic;
@ -331,7 +336,7 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir
}
static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_load *lhs,
unsigned int modifiers, struct hlsl_semantic *semantic, uint32_t semantic_index)
uint32_t modifiers, struct hlsl_semantic *semantic, uint32_t semantic_index)
{
struct hlsl_type *type = lhs->node.data_type, *vector_type_src, *vector_type_dst;
struct vkd3d_shader_location *loc = &lhs->node.loc;
@ -395,7 +400,7 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, s
}
static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_load *lhs,
unsigned int modifiers, struct hlsl_semantic *semantic, uint32_t semantic_index)
uint32_t modifiers, struct hlsl_semantic *semantic, uint32_t semantic_index)
{
struct vkd3d_shader_location *loc = &lhs->node.loc;
struct hlsl_type *type = lhs->node.data_type;
@ -411,7 +416,7 @@ static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block *
for (i = 0; i < hlsl_type_element_count(type); ++i)
{
unsigned int element_modifiers = modifiers;
uint32_t element_modifiers = modifiers;
if (type->class == HLSL_CLASS_ARRAY)
{
@ -473,7 +478,7 @@ static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct hlsl_block *bloc
}
static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_load *rhs,
unsigned int modifiers, struct hlsl_semantic *semantic, uint32_t semantic_index)
uint32_t modifiers, struct hlsl_semantic *semantic, uint32_t semantic_index)
{
struct hlsl_type *type = rhs->node.data_type, *vector_type;
struct vkd3d_shader_location *loc = &rhs->node.loc;
@ -529,7 +534,7 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, s
}
static void append_output_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_load *rhs,
unsigned int modifiers, struct hlsl_semantic *semantic, uint32_t semantic_index)
uint32_t modifiers, struct hlsl_semantic *semantic, uint32_t semantic_index)
{
struct vkd3d_shader_location *loc = &rhs->node.loc;
struct hlsl_type *type = rhs->node.data_type;
@ -1090,7 +1095,7 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
unsigned int dim_count = hlsl_sampler_dim_count(val->data_type->sampler_dim);
struct hlsl_ir_node *coords = index->idx.node;
struct hlsl_resource_load_params params = {0};
struct hlsl_ir_node *load;
struct hlsl_ir_node *resource_load;
assert(coords->data_type->class == HLSL_CLASS_VECTOR);
assert(coords->data_type->base_type == HLSL_TYPE_UINT);
@ -1102,11 +1107,11 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
params.type = HLSL_RESOURCE_LOAD;
params.resource = val;
params.coords = coords;
params.format = val->data_type->e.resource_format;
params.format = val->data_type->e.resource.format;
if (!(load = hlsl_new_resource_load(ctx, &params, &instr->loc)))
if (!(resource_load = hlsl_new_resource_load(ctx, &params, &instr->loc)))
return false;
hlsl_block_add_instr(block, load);
hlsl_block_add_instr(block, resource_load);
return true;
}
@ -1519,7 +1524,7 @@ static void copy_propagation_set_value(struct hlsl_ctx *ctx, struct copy_propaga
static bool copy_propagation_replace_with_single_instr(struct hlsl_ctx *ctx,
const struct copy_propagation_state *state, const struct hlsl_ir_load *load,
unsigned int swizzle, struct hlsl_ir_node *instr)
uint32_t swizzle, struct hlsl_ir_node *instr)
{
const unsigned int instr_component_count = hlsl_type_component_count(instr->data_type);
const struct hlsl_deref *deref = &load->src;
@ -1527,7 +1532,7 @@ static bool copy_propagation_replace_with_single_instr(struct hlsl_ctx *ctx,
struct hlsl_ir_node *new_instr = NULL;
unsigned int time = load->node.index;
unsigned int start, count, i;
unsigned int ret_swizzle = 0;
uint32_t ret_swizzle = 0;
if (!hlsl_component_index_range_from_deref(ctx, deref, &start, &count))
return false;
@ -1573,7 +1578,7 @@ static bool copy_propagation_replace_with_single_instr(struct hlsl_ctx *ctx,
static bool copy_propagation_replace_with_constant_vector(struct hlsl_ctx *ctx,
const struct copy_propagation_state *state, const struct hlsl_ir_load *load,
unsigned int swizzle, struct hlsl_ir_node *instr)
uint32_t swizzle, struct hlsl_ir_node *instr)
{
const unsigned int instr_component_count = hlsl_type_component_count(instr->data_type);
const struct hlsl_deref *deref = &load->src;
@ -2239,7 +2244,7 @@ static bool fold_swizzle_chains(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
if (next_instr->type == HLSL_IR_SWIZZLE)
{
struct hlsl_ir_node *new_swizzle;
unsigned int combined_swizzle;
uint32_t combined_swizzle;
combined_swizzle = hlsl_combine_swizzles(hlsl_ir_swizzle(next_instr)->swizzle,
swizzle->swizzle, instr->data_type->dimx);
@ -2301,7 +2306,6 @@ static bool normalize_switch_cases(struct hlsl_ctx *ctx, struct hlsl_ir_node *in
struct hlsl_ir_switch_case *c, *def = NULL;
bool missing_terminal_break = false;
struct hlsl_ir_node *node;
struct hlsl_ir_jump *jump;
struct hlsl_ir_switch *s;
if (instr->type != HLSL_IR_SWITCH)
@ -2320,10 +2324,7 @@ static bool normalize_switch_cases(struct hlsl_ctx *ctx, struct hlsl_ir_node *in
{
node = LIST_ENTRY(list_tail(&c->body.instrs), struct hlsl_ir_node, entry);
if (node->type == HLSL_IR_JUMP)
{
jump = hlsl_ir_jump(node);
terminal_break = jump->type == HLSL_IR_JUMP_BREAK;
}
terminal_break = (hlsl_ir_jump(node)->type == HLSL_IR_JUMP_BREAK);
}
missing_terminal_break |= !terminal_break;
@ -2482,6 +2483,38 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir
return false;
}
static bool validate_nonconstant_vector_store_derefs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *idx;
struct hlsl_deref *deref;
struct hlsl_type *type;
unsigned int i;
if (instr->type != HLSL_IR_STORE)
return false;
deref = &hlsl_ir_store(instr)->lhs;
assert(deref->var);
if (deref->path_len == 0)
return false;
type = deref->var->data_type;
for (i = 0; i < deref->path_len - 1; ++i)
type = hlsl_get_element_type_from_path_index(ctx, type, deref->path[i].node);
idx = deref->path[deref->path_len - 1].node;
if (type->class == HLSL_CLASS_VECTOR && idx->type != HLSL_IR_CONSTANT)
{
/* We should turn this into an hlsl_error after we implement unrolling, because if we get
* here after that, it means that the HLSL is invalid. */
hlsl_fixme(ctx, &instr->loc, "Non-constant vector addressing on store. Unrolling may be missing.");
}
return false;
}
/* Lower combined samples and sampler variables to synthesized separated textures and samplers.
* That is, translate SM1-style samples in the source to SM4-style samples in the bytecode. */
static bool lower_combined_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
@ -2614,6 +2647,39 @@ static bool sort_synthetic_separated_samplers_first(struct hlsl_ctx *ctx)
return false;
}
/* Append a FLOOR before a CAST to int or uint (which is written as a mere MOV). */
static bool lower_casts_to_int(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *arg, *floor, *cast2;
struct hlsl_ir_expr *expr;
if (instr->type != HLSL_IR_EXPR)
return false;
expr = hlsl_ir_expr(instr);
if (expr->op != HLSL_OP1_CAST)
return false;
arg = expr->operands[0].node;
if (instr->data_type->base_type != HLSL_TYPE_INT && instr->data_type->base_type != HLSL_TYPE_UINT)
return false;
if (arg->data_type->base_type != HLSL_TYPE_FLOAT && arg->data_type->base_type != HLSL_TYPE_HALF)
return false;
/* Check that the argument is not already a FLOOR */
if (arg->type == HLSL_IR_EXPR && hlsl_ir_expr(arg)->op == HLSL_OP1_FLOOR)
return false;
if (!(floor = hlsl_new_unary_expr(ctx, HLSL_OP1_FLOOR, arg, &instr->loc)))
return false;
hlsl_block_add_instr(block, floor);
if (!(cast2 = hlsl_new_cast(ctx, floor, instr->data_type, &instr->loc)))
return false;
hlsl_block_add_instr(block, cast2);
return true;
}
/* Lower DIV to RCP + MUL. */
static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
{
@ -2857,6 +2923,12 @@ static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru
first = expr->operands[1].node;
second = expr->operands[2].node;
if (cond->data_type->class > HLSL_CLASS_VECTOR || instr->data_type->class > HLSL_CLASS_VECTOR)
{
hlsl_fixme(ctx, &instr->loc, "Lower ternary of type other than scalar or vector.\n");
return false;
}
if (ctx->profile->major_version < 4 && ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL)
{
struct hlsl_ir_node *abs, *neg;
@ -3149,7 +3221,7 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru
for (i = 0; i < dimx; ++i)
{
unsigned int s = hlsl_swizzle_from_writemask(1 << i);
uint32_t s = hlsl_swizzle_from_writemask(1 << i);
if (!(comps[i] = hlsl_new_swizzle(ctx, s, 1, mult, &instr->loc)))
return false;
@ -4084,13 +4156,46 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
{
if (var->is_uniform && var->last_read)
unsigned int reg_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC];
if (!var->is_uniform || !var->last_read || reg_size == 0)
continue;
if (var->reg_reservation.reg_type == 'c')
{
unsigned int reg_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC];
unsigned int reg_idx = var->reg_reservation.reg_index;
unsigned int i;
if (reg_size == 0)
continue;
assert(reg_size % 4 == 0);
for (i = 0; i < reg_size / 4; ++i)
{
if (get_available_writemask(&allocator, 1, UINT_MAX, reg_idx + i) != VKD3DSP_WRITEMASK_ALL)
{
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
"Overlapping register() reservations on 'c%u'.", reg_idx + i);
}
record_allocation(ctx, &allocator, reg_idx + i, VKD3DSP_WRITEMASK_ALL, 1, UINT_MAX);
}
var->regs[HLSL_REGSET_NUMERIC].id = reg_idx;
var->regs[HLSL_REGSET_NUMERIC].allocation_size = reg_size / 4;
var->regs[HLSL_REGSET_NUMERIC].writemask = VKD3DSP_WRITEMASK_ALL;
var->regs[HLSL_REGSET_NUMERIC].allocated = true;
TRACE("Allocated reserved %s to %s.\n", var->name,
debug_register('c', var->regs[HLSL_REGSET_NUMERIC], var->data_type));
}
}
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
{
unsigned int reg_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC];
if (!var->is_uniform || !var->last_read || reg_size == 0)
continue;
if (!var->regs[HLSL_REGSET_NUMERIC].allocated)
{
var->regs[HLSL_REGSET_NUMERIC] = allocate_numeric_registers_for_type(ctx, &allocator,
1, UINT_MAX, var->data_type);
TRACE("Allocated %s to %s.\n", var->name,
@ -4230,45 +4335,52 @@ static const struct hlsl_buffer *get_reserved_buffer(struct hlsl_ctx *ctx, uint3
return NULL;
}
static void calculate_buffer_offset(struct hlsl_ctx *ctx, struct hlsl_ir_var *var)
static void hlsl_calculate_buffer_offset(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, bool register_reservation)
{
unsigned int var_reg_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC];
enum hlsl_type_class var_class = var->data_type->class;
struct hlsl_buffer *buffer = var->buffer;
if (var->reg_reservation.offset_type == 'c')
if (register_reservation)
{
if (var->reg_reservation.offset_index % 4)
{
if (var_class == HLSL_CLASS_MATRIX)
{
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
"packoffset() reservations with matrix types must be aligned with the beginning of a register.");
}
else if (var_class == HLSL_CLASS_ARRAY)
{
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
"packoffset() reservations with array types must be aligned with the beginning of a register.");
}
else if (var_class == HLSL_CLASS_STRUCT)
{
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
"packoffset() reservations with struct types must be aligned with the beginning of a register.");
}
else if (var_class == HLSL_CLASS_VECTOR)
{
unsigned int aligned_offset = hlsl_type_get_sm4_offset(var->data_type, var->reg_reservation.offset_index);
if (var->reg_reservation.offset_index != aligned_offset)
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
"packoffset() reservations with vector types cannot span multiple registers.");
}
}
var->buffer_offset = var->reg_reservation.offset_index;
var->buffer_offset = 4 * var->reg_reservation.reg_index;
}
else
{
var->buffer_offset = hlsl_type_get_sm4_offset(var->data_type, buffer->size);
if (var->reg_reservation.offset_type == 'c')
{
if (var->reg_reservation.offset_index % 4)
{
if (var_class == HLSL_CLASS_MATRIX)
{
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
"packoffset() reservations with matrix types must be aligned with the beginning of a register.");
}
else if (var_class == HLSL_CLASS_ARRAY)
{
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
"packoffset() reservations with array types must be aligned with the beginning of a register.");
}
else if (var_class == HLSL_CLASS_STRUCT)
{
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
"packoffset() reservations with struct types must be aligned with the beginning of a register.");
}
else if (var_class == HLSL_CLASS_VECTOR)
{
unsigned int aligned_offset = hlsl_type_get_sm4_offset(var->data_type, var->reg_reservation.offset_index);
if (var->reg_reservation.offset_index != aligned_offset)
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
"packoffset() reservations with vector types cannot span multiple registers.");
}
}
var->buffer_offset = var->reg_reservation.offset_index;
}
else
{
var->buffer_offset = hlsl_type_get_sm4_offset(var->data_type, buffer->size);
}
}
TRACE("Allocated buffer offset %u to %s.\n", var->buffer_offset, var->name);
@ -4337,6 +4449,29 @@ static void validate_buffer_offsets(struct hlsl_ctx *ctx)
}
}
void hlsl_calculate_buffer_offsets(struct hlsl_ctx *ctx)
{
struct hlsl_ir_var *var;
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
{
if (!var->is_uniform || hlsl_type_is_resource(var->data_type))
continue;
if (hlsl_var_has_buffer_offset_register_reservation(ctx, var))
hlsl_calculate_buffer_offset(ctx, var, true);
}
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
{
if (!var->is_uniform || hlsl_type_is_resource(var->data_type))
continue;
if (!hlsl_var_has_buffer_offset_register_reservation(ctx, var))
hlsl_calculate_buffer_offset(ctx, var, false);
}
}
static void allocate_buffers(struct hlsl_ctx *ctx)
{
struct hlsl_buffer *buffer;
@ -4345,15 +4480,14 @@ static void allocate_buffers(struct hlsl_ctx *ctx)
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
{
if (var->is_uniform && !hlsl_type_is_resource(var->data_type))
{
if (var->is_param)
var->buffer = ctx->params_buffer;
if (!var->is_uniform || hlsl_type_is_resource(var->data_type))
continue;
calculate_buffer_offset(ctx, var);
}
if (var->is_param)
var->buffer = ctx->params_buffer;
}
hlsl_calculate_buffer_offsets(ctx);
validate_buffer_offsets(ctx);
LIST_FOR_EACH_ENTRY(buffer, &ctx->buffers, struct hlsl_buffer, entry)
@ -4826,6 +4960,17 @@ static void remove_unreachable_code(struct hlsl_ctx *ctx, struct hlsl_block *bod
}
}
void hlsl_prepend_global_uniform_copy(struct hlsl_ctx *ctx, struct hlsl_block *body)
{
struct hlsl_ir_var *var;
LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry)
{
if (var->storage_modifiers & HLSL_STORAGE_UNIFORM)
prepend_uniform_copy(ctx, body, var);
}
}
int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func,
enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out)
{
@ -4854,11 +4999,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry
lower_ir(ctx, lower_matrix_swizzles, body);
lower_ir(ctx, lower_index_loads, body);
LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry)
{
if (var->storage_modifiers & HLSL_STORAGE_UNIFORM)
prepend_uniform_copy(ctx, body, var);
}
hlsl_prepend_global_uniform_copy(ctx, body);
for (i = 0; i < entry_func->parameters.count; ++i)
{
@ -4960,6 +5101,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry
lower_ir(ctx, lower_ternary, body);
if (profile->major_version < 4)
{
lower_ir(ctx, lower_casts_to_int, body);
lower_ir(ctx, lower_division, body);
lower_ir(ctx, lower_sqrt, body);
lower_ir(ctx, lower_dot, body);
@ -4973,6 +5115,8 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry
lower_ir(ctx, lower_abs, body);
}
lower_ir(ctx, validate_nonconstant_vector_store_derefs, body);
/* TODO: move forward, remove when no longer needed */
transform_derefs(ctx, replace_deref_path_with_offset, body);
while (hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, body, NULL));

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -164,6 +164,21 @@ STATIC_ASSERT(SM4_MAX_SRC_COUNT <= SPIRV_MAX_SRC_COUNT);
/* The shift that corresponds to the D3D_SIF_TEXTURE_COMPONENTS mask. */
#define VKD3D_SM4_SIF_TEXTURE_COMPONENTS_SHIFT 2
#define VKD3D_SM4_REQUIRES_DOUBLES 0x00000001
#define VKD3D_SM4_REQUIRES_EARLY_DEPTH_STENCIL 0x00000002
#define VKD3D_SM4_REQUIRES_UAVS_AT_EVERY_STAGE 0x00000004
#define VKD3D_SM4_REQUIRES_64_UAVS 0x00000008
#define VKD3D_SM4_REQUIRES_MINIMUM_PRECISION 0x00000010
#define VKD3D_SM4_REQUIRES_11_1_DOUBLE_EXTENSIONS 0x00000020
#define VKD3D_SM4_REQUIRES_11_1_SHADER_EXTENSIONS 0x00000040
#define VKD3D_SM4_REQUIRES_LEVEL_9_COMPARISON_FILTERING 0x00000080
#define VKD3D_SM4_REQUIRES_TILED_RESOURCES 0x00000100
#define VKD3D_SM4_REQUIRES_STENCIL_REF 0x00000200
#define VKD3D_SM4_REQUIRES_INNER_COVERAGE 0x00000400
#define VKD3D_SM4_REQUIRES_TYPED_UAV_LOAD_ADDITIONAL_FORMATS 0x00000800
#define VKD3D_SM4_REQUIRES_ROVS 0x00001000
#define VKD3D_SM4_REQUIRES_VIEWPORT_AND_RT_ARRAY_INDEX_FROM_ANY_SHADER_FEEDING_RASTERIZER 0x00002000
enum vkd3d_sm4_opcode
{
VKD3D_SM4_OP_ADD = 0x00,
@ -711,7 +726,7 @@ static struct vkd3d_shader_sm4_parser *vkd3d_shader_sm4_parser(struct vkd3d_shad
static bool shader_is_sm_5_1(const struct vkd3d_shader_sm4_parser *sm4)
{
const struct vkd3d_shader_version *version = &sm4->p.shader_version;
const struct vkd3d_shader_version *version = &sm4->p.program.shader_version;
return version->major >= 5 && version->minor >= 1;
}
@ -742,8 +757,7 @@ static bool shader_sm4_read_register_space(struct vkd3d_shader_sm4_parser *priv,
static void shader_sm4_read_conditional_op(struct vkd3d_shader_instruction *ins, uint32_t opcode,
uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv)
{
shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_UINT,
(struct vkd3d_shader_src_param *)&ins->src[0]);
shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_UINT, &ins->src[0]);
ins->flags = (opcode_token & VKD3D_SM4_CONDITIONAL_NZ) ?
VKD3D_SHADER_CONDITIONAL_OP_NZ : VKD3D_SHADER_CONDITIONAL_OP_Z;
}
@ -751,8 +765,7 @@ static void shader_sm4_read_conditional_op(struct vkd3d_shader_instruction *ins,
static void shader_sm4_read_case_condition(struct vkd3d_shader_instruction *ins, uint32_t opcode,
uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv)
{
shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_UINT,
(struct vkd3d_shader_src_param *)&ins->src[0]);
shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_UINT, &ins->src[0]);
if (ins->src[0].reg.type != VKD3DSPR_IMMCONST)
{
FIXME("Switch case value is not a 32-bit constant.\n");
@ -792,11 +805,13 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui
ins->handler_idx = VKD3DSIH_INVALID;
return;
}
icb->register_idx = 0;
icb->data_type = VKD3D_DATA_FLOAT;
icb->component_count = VKD3D_VEC4_SIZE;
icb->element_count = icb_size / VKD3D_VEC4_SIZE;
icb->is_null = false;
memcpy(icb->data, tokens, sizeof(*tokens) * icb_size);
shader_instruction_array_add_icb(&priv->p.instructions, icb);
shader_instruction_array_add_icb(&priv->p.program.instructions, icb);
ins->declaration.icb = icb;
}
@ -821,7 +836,7 @@ static void shader_sm4_read_dcl_resource(struct vkd3d_shader_instruction *ins, u
const uint32_t *end = &tokens[token_count];
enum vkd3d_sm4_data_type data_type;
enum vkd3d_data_type reg_data_type;
DWORD components;
uint32_t components;
unsigned int i;
resource_type = (opcode_token & VKD3D_SM4_RESOURCE_TYPE_MASK) >> VKD3D_SM4_RESOURCE_TYPE_SHIFT;
@ -918,10 +933,12 @@ static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins
uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv)
{
struct vkd3d_shader_index_range *index_range = &ins->declaration.index_range;
unsigned int i, register_idx, register_count, write_mask;
unsigned int i, register_idx, register_count;
const struct shader_signature *signature;
enum vkd3d_shader_register_type type;
struct sm4_index_range_array *ranges;
unsigned int *io_masks;
uint32_t write_mask;
shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_OPAQUE,
&index_range->dst);
@ -931,40 +948,38 @@ static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins
register_count = index_range->register_count;
write_mask = index_range->dst.write_mask;
if (vkd3d_write_mask_component_count(write_mask) != 1)
{
WARN("Unhandled write mask %#x.\n", write_mask);
vkd3d_shader_parser_warning(&priv->p, VKD3D_SHADER_WARNING_TPF_UNHANDLED_INDEX_RANGE_MASK,
"Index range mask %#x is not scalar.", write_mask);
}
switch ((type = index_range->dst.reg.type))
{
case VKD3DSPR_INPUT:
case VKD3DSPR_INCONTROLPOINT:
io_masks = priv->input_register_masks;
ranges = &priv->input_index_ranges;
signature = &priv->p.shader_desc.input_signature;
break;
case VKD3DSPR_OUTPUT:
if (sm4_parser_is_in_fork_or_join_phase(priv))
{
io_masks = priv->patch_constant_register_masks;
ranges = &priv->patch_constant_index_ranges;
signature = &priv->p.shader_desc.patch_constant_signature;
}
else
{
io_masks = priv->output_register_masks;
ranges = &priv->output_index_ranges;
signature = &priv->p.shader_desc.output_signature;
}
break;
case VKD3DSPR_COLOROUT:
case VKD3DSPR_OUTCONTROLPOINT:
io_masks = priv->output_register_masks;
ranges = &priv->output_index_ranges;
signature = &priv->p.shader_desc.output_signature;
break;
case VKD3DSPR_PATCHCONST:
io_masks = priv->patch_constant_register_masks;
ranges = &priv->patch_constant_index_ranges;
signature = &priv->p.shader_desc.patch_constant_signature;
break;
default:
@ -1002,6 +1017,18 @@ static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins
for (i = 0; i < register_count; ++i)
{
const struct signature_element *e = vsir_signature_find_element_for_reg(signature, register_idx + i, write_mask);
/* Index ranges should not contain non-arrayed sysvals. FXC tries to forbid this but it is buggy,
* and can emit a range containing a sysval if the sysval is not actually accessed. */
if (e && e->sysval_semantic && register_count > 1 && !vsir_sysval_semantic_is_tess_factor(e->sysval_semantic)
&& !vsir_sysval_semantic_is_clip_cull(e->sysval_semantic))
{
WARN("Sysval %u included in an index range declaration.\n", e->sysval_semantic);
vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_INDEX_RANGE_DCL,
"Index range base %u, count %u, mask %#x contains sysval %u.",
register_idx, register_count, write_mask, e->sysval_semantic);
return;
}
if ((io_masks[register_idx + i] & write_mask) != write_mask)
{
WARN("No matching declaration for index range base %u, count %u, mask %#x.\n",
@ -1039,7 +1066,7 @@ static void shader_sm4_read_dcl_input_primitive(struct vkd3d_shader_instruction
{
ins->declaration.primitive_type.type = VKD3D_PT_PATCH;
ins->declaration.primitive_type.patch_vertex_count = primitive_type - VKD3D_SM5_INPUT_PT_PATCH1 + 1;
priv->p.shader_desc.input_control_point_count = ins->declaration.primitive_type.patch_vertex_count;
priv->p.program.input_control_point_count = ins->declaration.primitive_type.patch_vertex_count;
}
else if (primitive_type >= ARRAY_SIZE(input_primitive_type_table))
{
@ -1048,7 +1075,7 @@ static void shader_sm4_read_dcl_input_primitive(struct vkd3d_shader_instruction
else
{
ins->declaration.primitive_type.type = input_primitive_type_table[primitive_type].vkd3d_type;
priv->p.shader_desc.input_control_point_count = input_primitive_type_table[primitive_type].control_point_count;
priv->p.program.input_control_point_count = input_primitive_type_table[primitive_type].control_point_count;
}
if (ins->declaration.primitive_type.type == VKD3D_PT_UNDEFINED)
@ -1060,7 +1087,7 @@ static void shader_sm4_read_declaration_count(struct vkd3d_shader_instruction *i
{
ins->declaration.count = *tokens;
if (opcode == VKD3D_SM4_OP_DCL_TEMPS)
priv->p.shader_desc.temp_count = max(priv->p.shader_desc.temp_count, *tokens);
priv->p.program.temp_count = max(priv->p.program.temp_count, *tokens);
}
static void shader_sm4_read_declaration_dst(struct vkd3d_shader_instruction *ins, uint32_t opcode,
@ -1116,6 +1143,7 @@ static void shader_sm4_read_dcl_indexable_temp(struct vkd3d_shader_instruction *
ins->declaration.indexable_temp.alignment = 0;
ins->declaration.indexable_temp.data_type = VKD3D_DATA_FLOAT;
ins->declaration.indexable_temp.component_count = *tokens;
ins->declaration.indexable_temp.has_function_scope = false;
}
static void shader_sm4_read_dcl_global_flags(struct vkd3d_shader_instruction *ins, uint32_t opcode,
@ -1127,9 +1155,8 @@ static void shader_sm4_read_dcl_global_flags(struct vkd3d_shader_instruction *in
static void shader_sm5_read_fcall(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token,
const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv)
{
struct vkd3d_shader_src_param *src_params = (struct vkd3d_shader_src_param *)ins->src;
src_params[0].reg.u.fp_body_idx = *tokens++;
shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_OPAQUE, &src_params[0]);
ins->src[0].reg.u.fp_body_idx = *tokens++;
shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_OPAQUE, &ins->src[0]);
}
static void shader_sm5_read_dcl_function_body(struct vkd3d_shader_instruction *ins, uint32_t opcode,
@ -1162,9 +1189,9 @@ static void shader_sm5_read_control_point_count(struct vkd3d_shader_instruction
>> VKD3D_SM5_CONTROL_POINT_COUNT_SHIFT;
if (opcode == VKD3D_SM5_OP_DCL_INPUT_CONTROL_POINT_COUNT)
priv->p.shader_desc.input_control_point_count = ins->declaration.count;
priv->p.program.input_control_point_count = ins->declaration.count;
else
priv->p.shader_desc.output_control_point_count = ins->declaration.count;
priv->p.program.output_control_point_count = ins->declaration.count;
}
static void shader_sm5_read_dcl_tessellator_domain(struct vkd3d_shader_instruction *ins, uint32_t opcode,
@ -1720,7 +1747,7 @@ static void shader_sm4_destroy(struct vkd3d_shader_parser *parser)
{
struct vkd3d_shader_sm4_parser *sm4 = vkd3d_shader_sm4_parser(parser);
shader_instruction_array_destroy(&parser->instructions);
vsir_program_cleanup(&parser->program);
free_shader_desc(&parser->shader_desc);
vkd3d_free(sm4);
}
@ -1730,7 +1757,7 @@ static bool shader_sm4_read_reg_idx(struct vkd3d_shader_sm4_parser *priv, const
{
if (addressing & VKD3D_SM4_ADDRESSING_RELATIVE)
{
struct vkd3d_shader_src_param *rel_addr = shader_parser_get_src_params(&priv->p, 1);
struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(&priv->p.program, 1);
if (!(reg_idx->rel_addr = rel_addr))
{
@ -1759,11 +1786,11 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui
const struct vkd3d_sm4_register_type_info *register_type_info;
enum vkd3d_shader_register_type vsir_register_type;
enum vkd3d_sm4_register_precision precision;
uint32_t token, order, extended, addressing;
enum vkd3d_sm4_register_type register_type;
enum vkd3d_sm4_extended_operand_type type;
enum vkd3d_sm4_register_modifier m;
enum vkd3d_sm4_dimension sm4_dimension;
uint32_t token, order, extended;
enum vkd3d_sm4_register_modifier m;
if (*ptr >= end)
{
@ -1861,7 +1888,7 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui
if (order >= 1)
{
DWORD addressing = (token & VKD3D_SM4_ADDRESSING_MASK0) >> VKD3D_SM4_ADDRESSING_SHIFT0;
addressing = (token & VKD3D_SM4_ADDRESSING_MASK0) >> VKD3D_SM4_ADDRESSING_SHIFT0;
if (!(shader_sm4_read_reg_idx(priv, ptr, end, addressing, &param->idx[0])))
{
ERR("Failed to read register index.\n");
@ -1871,7 +1898,7 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui
if (order >= 2)
{
DWORD addressing = (token & VKD3D_SM4_ADDRESSING_MASK1) >> VKD3D_SM4_ADDRESSING_SHIFT1;
addressing = (token & VKD3D_SM4_ADDRESSING_MASK1) >> VKD3D_SM4_ADDRESSING_SHIFT1;
if (!(shader_sm4_read_reg_idx(priv, ptr, end, addressing, &param->idx[1])))
{
ERR("Failed to read register index.\n");
@ -1881,7 +1908,7 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui
if (order >= 3)
{
DWORD addressing = (token & VKD3D_SM4_ADDRESSING_MASK2) >> VKD3D_SM4_ADDRESSING_SHIFT2;
addressing = (token & VKD3D_SM4_ADDRESSING_MASK2) >> VKD3D_SM4_ADDRESSING_SHIFT2;
if (!(shader_sm4_read_reg_idx(priv, ptr, end, addressing, &param->idx[2])))
{
ERR("Failed to read register index.\n");
@ -1900,19 +1927,19 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui
if (register_type == VKD3D_SM4_RT_IMMCONST || register_type == VKD3D_SM4_RT_IMMCONST64)
{
unsigned int dword_count;
unsigned int u32_count;
switch (param->dimension)
{
case VSIR_DIMENSION_SCALAR:
dword_count = 1 + (register_type == VKD3D_SM4_RT_IMMCONST64);
if (end - *ptr < dword_count)
u32_count = 1 + (register_type == VKD3D_SM4_RT_IMMCONST64);
if (end - *ptr < u32_count)
{
WARN("Invalid ptr %p, end %p.\n", *ptr, end);
return false;
}
memcpy(param->u.immconst_uint, *ptr, dword_count * sizeof(DWORD));
*ptr += dword_count;
memcpy(param->u.immconst_u32, *ptr, u32_count * sizeof(uint32_t));
*ptr += u32_count;
break;
case VSIR_DIMENSION_VEC4:
@ -1921,7 +1948,7 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui
WARN("Invalid ptr %p, end %p.\n", *ptr, end);
return false;
}
memcpy(param->u.immconst_uint, *ptr, VKD3D_VEC4_SIZE * sizeof(DWORD));
memcpy(param->u.immconst_u32, *ptr, VKD3D_VEC4_SIZE * sizeof(uint32_t));
*ptr += 4;
break;
@ -1930,6 +1957,15 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui
break;
}
}
else if (register_type == VKD3D_SM4_RT_IMMCONSTBUFFER)
{
if (param->idx_count != 1)
{
WARN("Unexpected idx count %u.\n", param->idx_count);
vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_INDEX_COUNT,
"Invalid index count %u for immediate const buffer register; expected count 1.", param->idx_count);
}
}
else if (!shader_is_sm_5_1(priv) && vsir_register_is_descriptor(param))
{
/* SM5.1 places a symbol identifier in idx[0] and moves
@ -1970,10 +2006,10 @@ static uint32_t swizzle_from_sm4(uint32_t s)
static uint32_t swizzle_to_sm4(uint32_t s)
{
uint32_t ret = 0;
ret |= ((vkd3d_swizzle_get_component(s, 0)) & 0x3);
ret |= ((vkd3d_swizzle_get_component(s, 1)) & 0x3) << 2;
ret |= ((vkd3d_swizzle_get_component(s, 2)) & 0x3) << 4;
ret |= ((vkd3d_swizzle_get_component(s, 3)) & 0x3) << 6;
ret |= ((vsir_swizzle_get_component(s, 0)) & 0x3);
ret |= ((vsir_swizzle_get_component(s, 1)) & 0x3) << 2;
ret |= ((vsir_swizzle_get_component(s, 2)) & 0x3) << 4;
ret |= ((vsir_swizzle_get_component(s, 3)) & 0x3) << 6;
return ret;
}
@ -1999,15 +2035,15 @@ static bool register_is_control_point_input(const struct vkd3d_shader_register *
{
return reg->type == VKD3DSPR_INCONTROLPOINT || reg->type == VKD3DSPR_OUTCONTROLPOINT
|| (reg->type == VKD3DSPR_INPUT && (priv->phase == VKD3DSIH_HS_CONTROL_POINT_PHASE
|| priv->p.shader_version.type == VKD3D_SHADER_TYPE_GEOMETRY));
|| priv->p.program.shader_version.type == VKD3D_SHADER_TYPE_GEOMETRY));
}
static unsigned int mask_from_swizzle(unsigned int swizzle)
static uint32_t mask_from_swizzle(uint32_t swizzle)
{
return (1u << vkd3d_swizzle_get_component(swizzle, 0))
| (1u << vkd3d_swizzle_get_component(swizzle, 1))
| (1u << vkd3d_swizzle_get_component(swizzle, 2))
| (1u << vkd3d_swizzle_get_component(swizzle, 3));
return (1u << vsir_swizzle_get_component(swizzle, 0))
| (1u << vsir_swizzle_get_component(swizzle, 1))
| (1u << vsir_swizzle_get_component(swizzle, 2))
| (1u << vsir_swizzle_get_component(swizzle, 3));
}
static bool shader_sm4_validate_input_output_register(struct vkd3d_shader_sm4_parser *priv,
@ -2066,7 +2102,7 @@ static bool shader_sm4_read_src_param(struct vkd3d_shader_sm4_parser *priv, cons
const uint32_t *end, enum vkd3d_data_type data_type, struct vkd3d_shader_src_param *src_param)
{
unsigned int dimension, mask;
DWORD token;
uint32_t token;
if (*ptr >= end)
{
@ -2140,6 +2176,9 @@ static bool shader_sm4_read_src_param(struct vkd3d_shader_sm4_parser *priv, cons
break;
}
if (data_type_is_64_bit(data_type))
src_param->swizzle = vsir_swizzle_64_from_32(src_param->swizzle);
if (register_is_input_output(&src_param->reg) && !shader_sm4_validate_input_output_register(priv,
&src_param->reg, mask_from_swizzle(src_param->swizzle)))
return false;
@ -2153,7 +2192,7 @@ static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, cons
enum vkd3d_sm4_swizzle_type swizzle_type;
enum vkd3d_shader_src_modifier modifier;
unsigned int dimension, swizzle;
DWORD token;
uint32_t token;
if (*ptr >= end)
{
@ -2219,7 +2258,7 @@ static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, cons
}
if (data_type == VKD3D_DATA_DOUBLE)
dst_param->write_mask = vkd3d_write_mask_64_from_32(dst_param->write_mask);
dst_param->write_mask = vsir_write_mask_64_from_32(dst_param->write_mask);
/* Some scalar registers are declared with no write mask in shader bytecode. */
if (!dst_param->write_mask && shader_sm4_is_scalar_register(&dst_param->reg))
dst_param->write_mask = VKD3DSP_WRITEMASK_0;
@ -2233,7 +2272,7 @@ static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, cons
return true;
}
static void shader_sm4_read_instruction_modifier(DWORD modifier, struct vkd3d_shader_instruction *ins)
static void shader_sm4_read_instruction_modifier(uint32_t modifier, struct vkd3d_shader_instruction *ins)
{
enum vkd3d_sm4_instruction_modifier modifier_type = modifier & VKD3D_SM4_MODIFIER_MASK;
@ -2241,7 +2280,7 @@ static void shader_sm4_read_instruction_modifier(DWORD modifier, struct vkd3d_sh
{
case VKD3D_SM4_MODIFIER_AOFFIMMI:
{
static const DWORD recognized_bits = VKD3D_SM4_INSTRUCTION_MODIFIER
static const uint32_t recognized_bits = VKD3D_SM4_INSTRUCTION_MODIFIER
| VKD3D_SM4_MODIFIER_MASK
| VKD3D_SM4_AOFFIMMI_U_MASK
| VKD3D_SM4_AOFFIMMI_V_MASK
@ -2269,7 +2308,7 @@ static void shader_sm4_read_instruction_modifier(DWORD modifier, struct vkd3d_sh
case VKD3D_SM5_MODIFIER_DATA_TYPE:
{
DWORD components = (modifier & VKD3D_SM5_MODIFIER_DATA_TYPE_MASK) >> VKD3D_SM5_MODIFIER_DATA_TYPE_SHIFT;
uint32_t components = (modifier & VKD3D_SM5_MODIFIER_DATA_TYPE_MASK) >> VKD3D_SM5_MODIFIER_DATA_TYPE_SHIFT;
unsigned int i;
for (i = 0; i < VKD3D_VEC4_SIZE; i++)
@ -2320,14 +2359,15 @@ static void shader_sm4_read_instruction_modifier(DWORD modifier, struct vkd3d_sh
static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, struct vkd3d_shader_instruction *ins)
{
const struct vkd3d_sm4_opcode_info *opcode_info;
struct vsir_program *program = &sm4->p.program;
uint32_t opcode_token, opcode, previous_token;
struct vkd3d_shader_dst_param *dst_params;
struct vkd3d_shader_src_param *src_params;
const uint32_t **ptr = &sm4->ptr;
unsigned int i, len;
size_t remaining;
const uint32_t *p;
DWORD precise;
uint32_t precise;
size_t remaining;
if (*ptr >= sm4->end)
{
@ -2378,7 +2418,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str
ins->predicate = NULL;
ins->dst_count = strnlen(opcode_info->dst_info, SM4_MAX_DST_COUNT);
ins->src_count = strnlen(opcode_info->src_info, SM4_MAX_SRC_COUNT);
ins->src = src_params = shader_parser_get_src_params(&sm4->p, ins->src_count);
ins->src = src_params = vsir_program_get_src_params(program, ins->src_count);
if (!src_params && ins->src_count)
{
ERR("Failed to allocate src parameters.\n");
@ -2420,7 +2460,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str
precise = (opcode_token & VKD3D_SM5_PRECISE_MASK) >> VKD3D_SM5_PRECISE_SHIFT;
ins->flags |= precise << VKD3DSI_PRECISE_SHIFT;
ins->dst = dst_params = shader_parser_get_dst_params(&sm4->p, ins->dst_count);
ins->dst = dst_params = vsir_program_get_dst_params(program, ins->dst_count);
if (!dst_params && ins->dst_count)
{
ERR("Failed to allocate dst parameters.\n");
@ -2533,6 +2573,16 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, const uint32_t
return true;
}
static void uninvert_used_masks(struct shader_signature *signature)
{
for (unsigned int i = 0; i < signature->element_count; ++i)
{
struct signature_element *e = &signature->elements[i];
e->used_mask = e->mask & ~e->used_mask;
}
}
static bool shader_sm4_parser_validate_signature(struct vkd3d_shader_sm4_parser *sm4,
const struct shader_signature *signature, unsigned int *masks, const char *name)
{
@ -2628,6 +2678,12 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi
return VKD3D_ERROR_INVALID_ARGUMENT;
}
/* DXBC stores used masks inverted for output signatures, for some reason.
* We return them un-inverted. */
uninvert_used_masks(&shader_desc->output_signature);
if (sm4->p.program.shader_version.type == VKD3D_SHADER_TYPE_HULL)
uninvert_used_masks(&shader_desc->patch_constant_signature);
if (!shader_sm4_parser_validate_signature(sm4, &shader_desc->input_signature,
sm4->input_register_masks, "Input")
|| !shader_sm4_parser_validate_signature(sm4, &shader_desc->output_signature,
@ -2639,7 +2695,7 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi
return VKD3D_ERROR_INVALID_SHADER;
}
instructions = &sm4->p.instructions;
instructions = &sm4->p.program.instructions;
while (sm4->ptr != sm4->end)
{
if (!shader_instruction_array_reserve(instructions, instructions->count + 1))
@ -2660,7 +2716,8 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi
}
++instructions->count;
}
if (sm4->p.shader_version.type == VKD3D_SHADER_TYPE_HULL && !sm4->has_control_point_phase && !sm4->p.failed)
if (sm4->p.program.shader_version.type == VKD3D_SHADER_TYPE_HULL
&& !sm4->has_control_point_phase && !sm4->p.failed)
shader_sm4_validate_default_phase_index_ranges(sm4);
if (!sm4->p.failed)
@ -2768,7 +2825,10 @@ bool hlsl_sm4_usage_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semant
{"position", false, VKD3D_SHADER_TYPE_PIXEL, D3D_NAME_POSITION},
{"sv_position", false, VKD3D_SHADER_TYPE_PIXEL, D3D_NAME_POSITION},
{"sv_primitiveid", false, VKD3D_SHADER_TYPE_PIXEL, D3D_NAME_PRIMITIVE_ID},
{"sv_isfrontface", false, VKD3D_SHADER_TYPE_PIXEL, D3D_NAME_IS_FRONT_FACE},
{"sv_rendertargetarrayindex", false, VKD3D_SHADER_TYPE_PIXEL, D3D_NAME_RENDER_TARGET_ARRAY_INDEX},
{"sv_viewportarrayindex", false, VKD3D_SHADER_TYPE_PIXEL, D3D_NAME_VIEWPORT_ARRAY_INDEX},
{"color", true, VKD3D_SHADER_TYPE_PIXEL, D3D_NAME_TARGET},
{"depth", true, VKD3D_SHADER_TYPE_PIXEL, D3D_NAME_DEPTH},
@ -2777,9 +2837,12 @@ bool hlsl_sm4_usage_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semant
{"sv_position", false, VKD3D_SHADER_TYPE_VERTEX, D3D_NAME_UNDEFINED},
{"sv_vertexid", false, VKD3D_SHADER_TYPE_VERTEX, D3D_NAME_VERTEX_ID},
{"sv_instanceid", false, VKD3D_SHADER_TYPE_VERTEX, D3D_NAME_INSTANCE_ID},
{"position", true, VKD3D_SHADER_TYPE_VERTEX, D3D_NAME_POSITION},
{"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, D3D_NAME_POSITION},
{"sv_rendertargetarrayindex", true, VKD3D_SHADER_TYPE_VERTEX, D3D_NAME_RENDER_TARGET_ARRAY_INDEX},
{"sv_viewportarrayindex", true, VKD3D_SHADER_TYPE_VERTEX, D3D_NAME_VIEWPORT_ARRAY_INDEX},
};
bool needs_compat_mapping = ascii_strncasecmp(semantic->name, "sv_", 3);
@ -3108,7 +3171,7 @@ static D3D_RESOURCE_RETURN_TYPE sm4_resource_format(const struct hlsl_type *type
if (type->class == HLSL_CLASS_ARRAY)
return sm4_resource_format(type->e.array.type);
switch (type->e.resource_format->base_type)
switch (type->e.resource.format->base_type)
{
case HLSL_TYPE_DOUBLE:
return D3D_RETURN_TYPE_DOUBLE;
@ -3398,7 +3461,7 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
}
else
{
unsigned int dimx = hlsl_type_get_component_type(ctx, resource->data_type, 0)->e.resource_format->dimx;
unsigned int dimx = hlsl_type_get_component_type(ctx, resource->data_type, 0)->e.resource.format->dimx;
put_u32(&buffer, sm4_resource_format(resource->data_type));
put_u32(&buffer, sm4_rdef_resource_dimension(resource->data_type));
@ -3842,7 +3905,7 @@ static void sm4_src_from_constant_value(struct vkd3d_shader_src_param *src,
if (width == 1)
{
src->reg.dimension = VSIR_DIMENSION_SCALAR;
src->reg.u.immconst_uint[0] = value->u[0].u;
src->reg.u.immconst_u32[0] = value->u[0].u;
}
else
{
@ -3852,9 +3915,9 @@ static void sm4_src_from_constant_value(struct vkd3d_shader_src_param *src,
for (i = 0; i < 4; ++i)
{
if ((map_writemask & (1u << i)) && (j < width))
src->reg.u.immconst_uint[i] = value->u[j++].u;
src->reg.u.immconst_u32[i] = value->u[j++].u;
else
src->reg.u.immconst_uint[i] = 0;
src->reg.u.immconst_u32[i] = 0;
}
}
}
@ -4049,12 +4112,12 @@ static void sm4_write_src_register(const struct tpf_writer *tpf, const struct vk
if (src->reg.type == VKD3DSPR_IMMCONST)
{
put_u32(buffer, src->reg.u.immconst_uint[0]);
put_u32(buffer, src->reg.u.immconst_u32[0]);
if (src->reg.dimension == VSIR_DIMENSION_VEC4)
{
put_u32(buffer, src->reg.u.immconst_uint[1]);
put_u32(buffer, src->reg.u.immconst_uint[2]);
put_u32(buffer, src->reg.u.immconst_uint[3]);
put_u32(buffer, src->reg.u.immconst_u32[1]);
put_u32(buffer, src->reg.u.immconst_u32[2]);
put_u32(buffer, src->reg.u.immconst_u32[3]);
}
}
}
@ -4205,12 +4268,15 @@ static void write_sm4_dcl_textures(const struct tpf_writer *tpf, const struct ex
{
case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER:
instr.opcode = VKD3D_SM5_OP_DCL_UAV_STRUCTURED;
instr.byte_stride = resource->data_type->e.resource_format->reg_size[HLSL_REGSET_NUMERIC] * 4;
instr.byte_stride = resource->data_type->e.resource.format->reg_size[HLSL_REGSET_NUMERIC] * 4;
break;
default:
instr.opcode = VKD3D_SM5_OP_DCL_UAV_TYPED;
break;
}
if (resource->data_type->e.resource.rasteriser_ordered)
instr.opcode |= VKD3DSUF_RASTERISER_ORDERED_VIEW << VKD3D_SM5_UAV_FLAGS_SHIFT;
}
else
{
@ -4426,7 +4492,7 @@ static void write_sm4_unary_op(const struct tpf_writer *tpf, enum vkd3d_sm4_opco
}
static void write_sm4_unary_op_with_two_destinations(const struct tpf_writer *tpf, enum vkd3d_sm4_opcode opcode,
const struct hlsl_ir_node *dst, unsigned dst_idx, const struct hlsl_ir_node *src)
const struct hlsl_ir_node *dst, unsigned int dst_idx, const struct hlsl_ir_node *src)
{
struct sm4_instruction instr;
@ -4435,7 +4501,6 @@ static void write_sm4_unary_op_with_two_destinations(const struct tpf_writer *tp
assert(dst_idx < ARRAY_SIZE(instr.dsts));
sm4_dst_from_node(&instr.dsts[dst_idx], dst);
assert(1 - dst_idx >= 0);
instr.dsts[1 - dst_idx].reg.type = VKD3DSPR_NULL;
instr.dsts[1 - dst_idx].reg.dimension = VSIR_DIMENSION_NONE;
instr.dsts[1 - dst_idx].reg.idx_count = 0;
@ -4485,7 +4550,7 @@ static void write_sm4_binary_op_dot(const struct tpf_writer *tpf, enum vkd3d_sm4
}
static void write_sm4_binary_op_with_two_destinations(const struct tpf_writer *tpf,
enum vkd3d_sm4_opcode opcode, const struct hlsl_ir_node *dst, unsigned dst_idx,
enum vkd3d_sm4_opcode opcode, const struct hlsl_ir_node *dst, unsigned int dst_idx,
const struct hlsl_ir_node *src1, const struct hlsl_ir_node *src2)
{
struct sm4_instruction instr;
@ -4495,7 +4560,6 @@ static void write_sm4_binary_op_with_two_destinations(const struct tpf_writer *t
assert(dst_idx < ARRAY_SIZE(instr.dsts));
sm4_dst_from_node(&instr.dsts[dst_idx], dst);
assert(1 - dst_idx >= 0);
instr.dsts[1 - dst_idx].reg.type = VKD3DSPR_NULL;
instr.dsts[1 - dst_idx].reg.dimension = VSIR_DIMENSION_NONE;
instr.dsts[1 - dst_idx].reg.idx_count = 0;
@ -4589,7 +4653,7 @@ static void write_sm4_ld(const struct tpf_writer *tpf, const struct hlsl_ir_node
memset(&instr.srcs[2], 0, sizeof(instr.srcs[2]));
reg->type = VKD3DSPR_IMMCONST;
reg->dimension = VSIR_DIMENSION_SCALAR;
reg->u.immconst_uint[0] = index->value.u[0].u;
reg->u.immconst_u32[0] = index->value.u[0].u;
}
else if (tpf->ctx->profile->major_version == 4 && tpf->ctx->profile->minor_version == 0)
{
@ -4714,6 +4778,13 @@ static void write_sm4_resinfo(const struct tpf_writer *tpf, const struct hlsl_ir
const struct hlsl_ir_node *dst = &load->node;
struct sm4_instruction instr;
if (resource->data_type->sampler_dim == HLSL_SAMPLER_DIM_BUFFER
|| resource->data_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER)
{
hlsl_fixme(tpf->ctx, &load->node.loc, "resinfo for buffers.");
return;
}
assert(dst->data_type->base_type == HLSL_TYPE_UINT || dst->data_type->base_type == HLSL_TYPE_FLOAT);
memset(&instr, 0, sizeof(instr));
@ -4750,7 +4821,7 @@ static void write_sm4_cast_from_bool(const struct tpf_writer *tpf, const struct
sm4_src_from_node(tpf, &instr.srcs[0], arg, instr.dsts[0].write_mask);
instr.srcs[1].reg.type = VKD3DSPR_IMMCONST;
instr.srcs[1].reg.dimension = VSIR_DIMENSION_SCALAR;
instr.srcs[1].reg.u.immconst_uint[0] = mask;
instr.srcs[1].reg.u.immconst_u32[0] = mask;
instr.src_count = 2;
write_sm4_instruction(tpf, &instr);
@ -5460,7 +5531,7 @@ static void write_sm4_loop(const struct tpf_writer *tpf, const struct hlsl_ir_lo
static void write_sm4_gather(const struct tpf_writer *tpf, const struct hlsl_ir_node *dst,
const struct hlsl_deref *resource, const struct hlsl_deref *sampler,
const struct hlsl_ir_node *coords, DWORD swizzle, const struct hlsl_ir_node *texel_offset)
const struct hlsl_ir_node *coords, uint32_t swizzle, const struct hlsl_ir_node *texel_offset)
{
struct vkd3d_shader_src_param *src;
struct sm4_instruction instr;
@ -5840,6 +5911,31 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx,
sm4_free_extern_resources(extern_resources, extern_resources_count);
}
static void write_sm4_sfi0(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
{
struct extern_resource *extern_resources;
unsigned int extern_resources_count;
uint64_t *flags;
flags = vkd3d_calloc(1, sizeof(*flags));
extern_resources = sm4_get_extern_resources(ctx, &extern_resources_count);
for (unsigned int i = 0; i < extern_resources_count; ++i)
{
if (extern_resources[i].data_type->e.resource.rasteriser_ordered)
*flags |= VKD3D_SM4_REQUIRES_ROVS;
}
sm4_free_extern_resources(extern_resources, extern_resources_count);
/* FIXME: We also emit code that should require UAVS_AT_EVERY_STAGE,
* STENCIL_REF, and TYPED_UAV_LOAD_ADDITIONAL_FORMATS. */
if (flags)
dxbc_writer_add_section(dxbc, TAG_SFI0, flags, sizeof(*flags));
else
vkd3d_free(flags);
}
int hlsl_sm4_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out)
{
struct dxbc_writer dxbc;
@ -5852,6 +5948,7 @@ int hlsl_sm4_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun
write_sm4_signature(ctx, &dxbc, true);
write_sm4_rdef(ctx, &dxbc);
write_sm4_shdr(ctx, entry_func, &dxbc);
write_sm4_sfi0(ctx, &dxbc);
if (!(ret = ctx->result))
ret = dxbc_writer_write(&dxbc, out);

View file

@ -69,7 +69,7 @@ void vkd3d_string_buffer_cleanup(struct vkd3d_string_buffer *buffer)
vkd3d_free(buffer->buffer);
}
static void vkd3d_string_buffer_clear(struct vkd3d_string_buffer *buffer)
void vkd3d_string_buffer_clear(struct vkd3d_string_buffer *buffer)
{
buffer->buffer[0] = '\0';
buffer->content_size = 0;
@ -305,6 +305,16 @@ void vkd3d_shader_vwarning(struct vkd3d_shader_message_context *context, const s
vkd3d_string_buffer_printf(&context->messages, "\n");
}
void vkd3d_shader_warning(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location,
enum vkd3d_shader_error error, const char *format, ...)
{
va_list args;
va_start(args, format);
vkd3d_shader_vwarning(context, location, error, format, args);
va_end(args);
}
void vkd3d_shader_verror(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location,
enum vkd3d_shader_error error, const char *format, va_list args)
{
@ -354,9 +364,9 @@ size_t bytecode_align(struct vkd3d_bytecode_buffer *buffer)
return aligned_size;
}
size_t bytecode_put_bytes(struct vkd3d_bytecode_buffer *buffer, const void *bytes, size_t size)
size_t bytecode_put_bytes_unaligned(struct vkd3d_bytecode_buffer *buffer, const void *bytes, size_t size)
{
size_t offset = bytecode_align(buffer);
size_t offset = buffer->size;
if (buffer->status)
return offset;
@ -371,24 +381,59 @@ size_t bytecode_put_bytes(struct vkd3d_bytecode_buffer *buffer, const void *byte
return offset;
}
void set_u32(struct vkd3d_bytecode_buffer *buffer, size_t offset, uint32_t value)
size_t bytecode_put_bytes(struct vkd3d_bytecode_buffer *buffer, const void *bytes, size_t size)
{
bytecode_align(buffer);
return bytecode_put_bytes_unaligned(buffer, bytes, size);
}
size_t bytecode_reserve_bytes(struct vkd3d_bytecode_buffer *buffer, size_t size)
{
size_t offset = bytecode_align(buffer);
if (buffer->status)
return offset;
if (!vkd3d_array_reserve((void **)&buffer->data, &buffer->capacity, offset + size, 1))
{
buffer->status = VKD3D_ERROR_OUT_OF_MEMORY;
return offset;
}
memset(buffer->data + offset, 0, size);
buffer->size = offset + size;
return offset;
}
static void bytecode_set_bytes(struct vkd3d_bytecode_buffer *buffer, size_t offset,
const void *value, size_t size)
{
if (buffer->status)
return;
assert(vkd3d_bound_range(offset, sizeof(value), buffer->size));
memcpy(buffer->data + offset, &value, sizeof(value));
assert(vkd3d_bound_range(offset, size, buffer->size));
memcpy(buffer->data + offset, value, size);
}
void set_u32(struct vkd3d_bytecode_buffer *buffer, size_t offset, uint32_t value)
{
bytecode_set_bytes(buffer, offset, &value, sizeof(value));
}
void set_string(struct vkd3d_bytecode_buffer *buffer, size_t offset, const char *string, size_t length)
{
bytecode_set_bytes(buffer, offset, string, length);
}
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;
static unsigned int shader_id = 0;
char filename[1024];
unsigned int id;
FILE *f;
id = InterlockedIncrement(&shader_id) - 1;
id = vkd3d_atomic_increment_u32(&shader_id) - 1;
if (profile)
snprintf(filename, ARRAY_SIZE(filename), "%s/vkd3d-shader-%u-%s.%s", path, id, profile, suffix);
@ -498,10 +543,9 @@ bool vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser,
parser->location.source_name = source_name;
parser->location.line = 1;
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);
return vsir_program_init(&parser->program, version, instruction_reserve);
}
void VKD3D_PRINTF_FUNC(3, 4) vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser,
@ -888,6 +932,21 @@ static void vkd3d_shader_scan_combined_sampler_declaration(
&semantic->resource.range, semantic->resource_type, VKD3D_SHADER_RESOURCE_DATA_FLOAT);
}
static const struct vkd3d_shader_descriptor_info1 *find_descriptor(
const struct vkd3d_shader_scan_descriptor_info1 *info,
enum vkd3d_shader_descriptor_type type, unsigned int register_id)
{
for (unsigned int i = 0; i < info->descriptor_count; ++i)
{
const struct vkd3d_shader_descriptor_info1 *d = &info->descriptors[i];
if (d->type == type && d->register_id == register_id)
return d;
}
return NULL;
}
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)
{
@ -913,7 +972,6 @@ static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_co
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;
@ -928,30 +986,13 @@ static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_co
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;
if ((d = find_descriptor(context->scan_descriptor_info,
VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource->idx[0].offset)))
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;
}
}
if (sampler && (d = find_descriptor(context->scan_descriptor_info,
VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, sampler->idx[0].offset)))
sampler_space = d->register_space;
}
for (i = 0; i < info->combined_sampler_count; ++i)
@ -979,7 +1020,7 @@ static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_co
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,
unsigned int sample_count, unsigned int structure_stride, bool raw)
unsigned int sample_count, unsigned int structure_stride, bool raw, uint32_t flags)
{
struct vkd3d_shader_descriptor_info1 *d;
enum vkd3d_shader_descriptor_type type;
@ -995,6 +1036,8 @@ static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_cont
d->structure_stride = structure_stride;
if (raw)
d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER;
if (type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV)
d->uav_flags = flags;
}
static void vkd3d_shader_scan_typed_resource_declaration(struct vkd3d_shader_scan_context *context,
@ -1053,7 +1096,7 @@ static void vkd3d_shader_scan_typed_resource_declaration(struct vkd3d_shader_sca
}
vkd3d_shader_scan_resource_declaration(context, &semantic->resource,
semantic->resource_type, resource_data_type, semantic->sample_count, 0, false);
semantic->resource_type, resource_data_type, semantic->sample_count, 0, false, instruction->flags);
}
static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *context,
@ -1074,6 +1117,9 @@ 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_type == VKD3D_SHADER_RESOURCE_NONE)
break;
if (instruction->declaration.semantic.resource.reg.reg.type == VKD3DSPR_COMBINED_SAMPLER)
{
vkd3d_shader_scan_combined_sampler_declaration(context, &instruction->declaration.semantic);
@ -1086,15 +1132,16 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
case VKD3DSIH_DCL_RESOURCE_RAW:
case VKD3DSIH_DCL_UAV_RAW:
vkd3d_shader_scan_resource_declaration(context, &instruction->declaration.raw_resource.resource,
VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0, 0, true);
VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0, 0, true, instruction->flags);
break;
case VKD3DSIH_DCL_RESOURCE_STRUCTURED:
case VKD3DSIH_DCL_UAV_STRUCTURED:
vkd3d_shader_scan_resource_declaration(context, &instruction->declaration.structured_resource.resource,
VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0,
instruction->declaration.structured_resource.byte_stride, false);
instruction->declaration.structured_resource.byte_stride, false, instruction->flags);
break;
case VKD3DSIH_IF:
case VKD3DSIH_IFC:
cf_info = vkd3d_shader_scan_push_cf_info(context);
cf_info->type = VKD3D_SHADER_BLOCK_IF;
cf_info->inside_block = true;
@ -1361,17 +1408,15 @@ static int scan_with_parser(const struct vkd3d_shader_compile_info *compile_info
descriptor_info1 = &local_descriptor_info1;
}
vkd3d_shader_scan_context_init(&context, &parser->shader_version, compile_info,
vkd3d_shader_scan_context_init(&context, &parser->program.shader_version, compile_info,
descriptor_info1, combined_sampler_info, message_context);
if (TRACE_ON())
{
vkd3d_shader_trace(&parser->instructions, &parser->shader_version);
}
vkd3d_shader_trace(&parser->program);
for (i = 0; i < parser->instructions.count; ++i)
for (i = 0; i < parser->program.instructions.count; ++i)
{
instruction = &parser->instructions.elements[i];
instruction = &parser->program.instructions.elements[i];
if ((ret = vkd3d_shader_scan_instruction(&context, instruction)) < 0)
break;
}
@ -1541,17 +1586,16 @@ static int vkd3d_shader_parser_compile(struct vkd3d_shader_parser *parser,
scan_info = *compile_info;
if ((ret = scan_with_parser(&scan_info, message_context, &scan_descriptor_info, parser)) < 0)
return ret;
switch (compile_info->target_type)
{
case VKD3D_SHADER_TARGET_D3D_ASM:
ret = vkd3d_dxbc_binary_to_text(&parser->instructions, &parser->shader_version, compile_info, out);
ret = vkd3d_dxbc_binary_to_text(&parser->program, compile_info, out, VSIR_ASM_D3D);
break;
case VKD3D_SHADER_TARGET_GLSL:
if (!(glsl_generator = vkd3d_glsl_generator_create(&parser->shader_version,
if ((ret = scan_with_parser(&scan_info, message_context, &scan_descriptor_info, parser)) < 0)
return ret;
if (!(glsl_generator = vkd3d_glsl_generator_create(&parser->program.shader_version,
message_context, &parser->location)))
{
ERR("Failed to create GLSL generator.\n");
@ -1559,21 +1603,24 @@ static int vkd3d_shader_parser_compile(struct vkd3d_shader_parser *parser,
return VKD3D_ERROR;
}
ret = vkd3d_glsl_generator_generate(glsl_generator, parser, out);
ret = vkd3d_glsl_generator_generate(glsl_generator, &parser->program, out);
vkd3d_glsl_generator_destroy(glsl_generator);
vkd3d_shader_free_scan_descriptor_info1(&scan_descriptor_info);
break;
case VKD3D_SHADER_TARGET_SPIRV_BINARY:
case VKD3D_SHADER_TARGET_SPIRV_TEXT:
if ((ret = scan_with_parser(&scan_info, message_context, &scan_descriptor_info, parser)) < 0)
return ret;
ret = spirv_compile(parser, &scan_descriptor_info, compile_info, out, message_context);
vkd3d_shader_free_scan_descriptor_info1(&scan_descriptor_info);
break;
default:
/* Validation should prevent us from reaching this. */
assert(0);
vkd3d_unreachable();
}
vkd3d_shader_free_scan_descriptor_info1(&scan_descriptor_info);
return ret;
}
@ -1622,14 +1669,10 @@ static int compile_d3d_bytecode(const struct vkd3d_shader_compile_info *compile_
return ret;
}
if (compile_info->target_type == VKD3D_SHADER_TARGET_D3D_ASM)
{
ret = vkd3d_dxbc_binary_to_text(&parser->instructions, &parser->shader_version, compile_info, out);
vkd3d_shader_parser_destroy(parser);
return ret;
}
ret = vkd3d_shader_parser_compile(parser, compile_info, out, message_context);
return VKD3D_ERROR;
vkd3d_shader_parser_destroy(parser);
return ret;
}
static int compile_dxbc_dxil(const struct vkd3d_shader_compile_info *compile_info,
@ -1903,10 +1946,15 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types(
{
VKD3D_SHADER_TARGET_D3D_BYTECODE,
VKD3D_SHADER_TARGET_DXBC_TPF,
VKD3D_SHADER_TARGET_FX,
};
static const enum vkd3d_shader_target_type d3dbc_types[] =
{
VKD3D_SHADER_TARGET_SPIRV_BINARY,
#ifdef HAVE_SPIRV_TOOLS
VKD3D_SHADER_TARGET_SPIRV_TEXT,
#endif
VKD3D_SHADER_TARGET_D3D_ASM,
};
@ -2004,9 +2052,12 @@ void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator,
if (count > allocator->count - allocator->index)
{
struct vkd3d_shader_param_node *next = shader_param_allocator_node_create(allocator);
struct vkd3d_shader_param_node *next;
if (!next)
/* Monolithic switch has no definite parameter count limit. */
allocator->count = max(allocator->count, count);
if (!(next = shader_param_allocator_node_create(allocator)))
return NULL;
if (allocator->current)
allocator->current->next = next;
@ -2043,6 +2094,23 @@ bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *ins
return true;
}
bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *instructions,
unsigned int idx, unsigned int count)
{
assert(idx <= instructions->count);
if (!shader_instruction_array_reserve(instructions, instructions->count + count))
return false;
memmove(&instructions->elements[idx + count], &instructions->elements[idx],
(instructions->count - idx) * sizeof(*instructions->elements));
memset(&instructions->elements[idx], 0, count * sizeof(*instructions->elements));
instructions->count += count;
return true;
}
bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions,
struct vkd3d_shader_immediate_constant_buffer *icb)
{

View file

@ -91,13 +91,15 @@ enum vkd3d_shader_error
VKD3D_SHADER_ERROR_SPV_INVALID_REGISTER_TYPE = 2001,
VKD3D_SHADER_ERROR_SPV_INVALID_DESCRIPTOR_BINDING = 2002,
VKD3D_SHADER_ERROR_SPV_DESCRIPTOR_IDX_UNSUPPORTED = 2003,
VKD3D_SHADER_ERROR_SPV_STENCIL_EXPORT_UNSUPPORTED = 2004,
VKD3D_SHADER_ERROR_SPV_UNSUPPORTED_FEATURE = 2004,
VKD3D_SHADER_ERROR_SPV_OUT_OF_MEMORY = 2005,
VKD3D_SHADER_ERROR_SPV_INVALID_TYPE = 2006,
VKD3D_SHADER_ERROR_SPV_INVALID_HANDLER = 2007,
VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED = 2008,
VKD3D_SHADER_ERROR_SPV_INVALID_SHADER = 2009,
VKD3D_SHADER_WARNING_SPV_INVALID_SWIZZLE = 2300,
VKD3D_SHADER_WARNING_SPV_INVALID_UAV_FLAGS = 2301,
VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY = 3000,
VKD3D_SHADER_ERROR_RS_INVALID_VERSION = 3001,
@ -196,6 +198,7 @@ enum vkd3d_shader_error
VKD3D_SHADER_WARNING_DXIL_ENTRY_POINT_MISMATCH = 8306,
VKD3D_SHADER_WARNING_DXIL_INVALID_MASK = 8307,
VKD3D_SHADER_WARNING_DXIL_INVALID_OPERATION = 8308,
VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT = 8309,
VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED = 9000,
VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER = 9001,
@ -213,7 +216,8 @@ enum vkd3d_shader_error
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_ERROR_VSIR_INVALID_CONTROL_FLOW = 9016,
VKD3D_SHADER_ERROR_VSIR_INVALID_SSA_USAGE = 9017,
VKD3D_SHADER_WARNING_VSIR_DYNAMIC_DESCRIPTOR_ARRAY = 9300,
};
@ -221,8 +225,11 @@ enum vkd3d_shader_error
enum vkd3d_shader_opcode
{
VKD3DSIH_ABS,
VKD3DSIH_ACOS,
VKD3DSIH_ADD,
VKD3DSIH_AND,
VKD3DSIH_ASIN,
VKD3DSIH_ATAN,
VKD3DSIH_ATOMIC_AND,
VKD3DSIH_ATOMIC_CMP_STORE,
VKD3DSIH_ATOMIC_IADD,
@ -235,6 +242,7 @@ enum vkd3d_shader_opcode
VKD3DSIH_BEM,
VKD3DSIH_BFI,
VKD3DSIH_BFREV,
VKD3DSIH_BRANCH,
VKD3DSIH_BREAK,
VKD3DSIH_BREAKC,
VKD3DSIH_BREAKP,
@ -358,10 +366,13 @@ enum vkd3d_shader_opcode
VKD3DSIH_GATHER4_S,
VKD3DSIH_GEO,
VKD3DSIH_GEU,
VKD3DSIH_HCOS,
VKD3DSIH_HS_CONTROL_POINT_PHASE,
VKD3DSIH_HS_DECLS,
VKD3DSIH_HS_FORK_PHASE,
VKD3DSIH_HS_JOIN_PHASE,
VKD3DSIH_HSIN,
VKD3DSIH_HTAN,
VKD3DSIH_IADD,
VKD3DSIH_IBFE,
VKD3DSIH_IDIV,
@ -388,8 +399,11 @@ enum vkd3d_shader_opcode
VKD3DSIH_IMUL,
VKD3DSIH_INE,
VKD3DSIH_INEG,
VKD3DSIH_ISFINITE,
VKD3DSIH_ISHL,
VKD3DSIH_ISHR,
VKD3DSIH_ISINF,
VKD3DSIH_ISNAN,
VKD3DSIH_ITOD,
VKD3DSIH_ITOF,
VKD3DSIH_ITOI,
@ -432,6 +446,7 @@ enum vkd3d_shader_opcode
VKD3DSIH_NRM,
VKD3DSIH_OR,
VKD3DSIH_PHASE,
VKD3DSIH_PHI,
VKD3DSIH_POW,
VKD3DSIH_RCP,
VKD3DSIH_REP,
@ -469,7 +484,9 @@ enum vkd3d_shader_opcode
VKD3DSIH_SUB,
VKD3DSIH_SWAPC,
VKD3DSIH_SWITCH,
VKD3DSIH_SWITCH_MONOLITHIC,
VKD3DSIH_SYNC,
VKD3DSIH_TAN,
VKD3DSIH_TEX,
VKD3DSIH_TEXBEM,
VKD3DSIH_TEXBEML,
@ -618,6 +635,11 @@ static inline bool data_type_is_bool(enum vkd3d_data_type data_type)
return data_type == VKD3D_DATA_BOOL;
}
static inline bool data_type_is_64_bit(enum vkd3d_data_type data_type)
{
return data_type == VKD3D_DATA_DOUBLE || data_type == VKD3D_DATA_UINT64;
}
enum vsir_dimension
{
VSIR_DIMENSION_NONE,
@ -716,6 +738,7 @@ enum vkd3d_shader_sync_flags
{
VKD3DSSF_THREAD_GROUP = 0x1,
VKD3DSSF_GROUP_SHARED_MEMORY = 0x2,
VKD3DSSF_THREAD_GROUP_UAV = 0x4,
VKD3DSSF_GLOBAL_UAV = 0x8,
};
@ -740,6 +763,7 @@ enum vkd3d_tessellator_domain
#define VKD3DSI_RESINFO_UINT 0x2
#define VKD3DSI_SAMPLE_INFO_UINT 0x1
#define VKD3DSI_SAMPLER_COMPARISON_MODE 0x1
#define VKD3DSI_SHIFT_UNMASKED 0x1
#define VKD3DSI_PRECISE_X 0x100
#define VKD3DSI_PRECISE_Y 0x200
@ -793,10 +817,12 @@ struct vkd3d_shader_version
struct vkd3d_shader_immediate_constant_buffer
{
unsigned int register_idx;
enum vkd3d_data_type data_type;
/* total count is element_count * component_count */
unsigned int element_count;
unsigned int component_count;
bool is_null;
uint32_t data[];
};
@ -807,12 +833,13 @@ struct vkd3d_shader_indexable_temp
unsigned int alignment;
enum vkd3d_data_type data_type;
unsigned int component_count;
bool has_function_scope;
const struct vkd3d_shader_immediate_constant_buffer *initialiser;
};
struct vkd3d_shader_register_index
{
const struct vkd3d_shader_src_param *rel_addr;
struct vkd3d_shader_src_param *rel_addr;
unsigned int offset;
/* address is known to fall within the object (for optimisation) */
bool is_in_bounds;
@ -831,10 +858,10 @@ struct vkd3d_shader_register
unsigned int alignment;
union
{
DWORD immconst_uint[VKD3D_VEC4_SIZE];
float immconst_float[VKD3D_VEC4_SIZE];
uint64_t immconst_uint64[VKD3D_DVEC2_SIZE];
double immconst_double[VKD3D_DVEC2_SIZE];
uint32_t immconst_u32[VKD3D_VEC4_SIZE];
float immconst_f32[VKD3D_VEC4_SIZE];
uint64_t immconst_u64[VKD3D_DVEC2_SIZE];
double immconst_f64[VKD3D_DVEC2_SIZE];
unsigned fp_body_idx;
} u;
};
@ -861,17 +888,23 @@ struct vkd3d_shader_dst_param
{
struct vkd3d_shader_register reg;
uint32_t write_mask;
DWORD modifiers;
DWORD shift;
uint32_t modifiers;
unsigned int shift;
};
struct vkd3d_shader_src_param
{
struct vkd3d_shader_register reg;
DWORD swizzle;
uint32_t swizzle;
enum vkd3d_shader_src_modifier modifiers;
};
void vsir_src_param_init(struct vkd3d_shader_src_param *param, enum vkd3d_shader_register_type reg_type,
enum vkd3d_data_type data_type, unsigned int idx_count);
void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader_register_type reg_type,
enum vkd3d_data_type data_type, unsigned int idx_count);
void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id);
struct vkd3d_shader_index_range
{
struct vkd3d_shader_dst_param dst;
@ -945,6 +978,9 @@ enum vkd3d_shader_input_sysval_semantic
VKD3D_SIV_LINE_DENSITY_TESS_FACTOR = 22,
};
#define SM1_COLOR_REGISTER_OFFSET 8
#define SM1_RASTOUT_REGISTER_OFFSET 10
#define SIGNATURE_TARGET_LOCATION_UNUSED (~0u)
struct signature_element
@ -998,17 +1034,10 @@ 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
@ -1110,11 +1139,11 @@ struct vkd3d_shader_instruction
{
struct vkd3d_shader_location location;
enum vkd3d_shader_opcode handler_idx;
DWORD flags;
uint32_t flags;
unsigned int dst_count;
unsigned int src_count;
const struct vkd3d_shader_dst_param *dst;
const struct vkd3d_shader_src_param *src;
struct vkd3d_shader_dst_param *dst;
struct vkd3d_shader_src_param *src;
struct vkd3d_shader_texel_offset texel_offset;
enum vkd3d_shader_resource_type resource_type;
unsigned int resource_stride;
@ -1171,6 +1200,32 @@ static inline bool register_is_constant(const struct vkd3d_shader_register *reg)
return (reg->type == VKD3DSPR_IMMCONST || reg->type == VKD3DSPR_IMMCONST64);
}
static inline bool register_is_undef(const struct vkd3d_shader_register *reg)
{
return reg->type == VKD3DSPR_UNDEF;
}
static inline bool register_is_constant_or_undef(const struct vkd3d_shader_register *reg)
{
return register_is_constant(reg) || register_is_undef(reg);
}
static inline bool register_is_scalar_constant_zero(const struct vkd3d_shader_register *reg)
{
return register_is_constant(reg) && reg->dimension == VSIR_DIMENSION_SCALAR
&& (data_type_is_64_bit(reg->data_type) ? !reg->u.immconst_u64[0] : !reg->u.immconst_u32[0]);
}
static inline bool vsir_register_is_label(const struct vkd3d_shader_register *reg)
{
return reg->type == VKD3DSPR_LABEL;
}
static inline bool register_is_ssa(const struct vkd3d_shader_register *reg)
{
return reg->type == VKD3DSPR_SSA;
}
struct vkd3d_shader_param_node
{
struct vkd3d_shader_param_node *next;
@ -1217,6 +1272,8 @@ struct vkd3d_shader_instruction_array
bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve);
bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve);
bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *instructions,
unsigned int idx, unsigned int count);
bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions,
struct vkd3d_shader_immediate_constant_buffer *icb);
bool shader_instruction_array_clone_instruction(struct vkd3d_shader_instruction_array *instructions,
@ -1228,6 +1285,36 @@ enum vkd3d_shader_config_flags
VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION = 0x00000001,
};
struct vsir_program
{
struct vkd3d_shader_version shader_version;
struct vkd3d_shader_instruction_array instructions;
unsigned int input_control_point_count, output_control_point_count;
unsigned int block_count;
unsigned int temp_count;
unsigned int ssa_count;
bool use_vocp;
const char **block_names;
size_t block_name_count;
};
bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_version *version, unsigned int reserve);
void vsir_program_cleanup(struct vsir_program *program);
static inline struct vkd3d_shader_dst_param *vsir_program_get_dst_params(
struct vsir_program *program, unsigned int count)
{
return shader_dst_param_allocator_get(&program->instructions.dst_params, count);
}
static inline struct vkd3d_shader_src_param *vsir_program_get_src_params(
struct vsir_program *program, unsigned int count)
{
return shader_src_param_allocator_get(&program->instructions.src_params, count);
}
struct vkd3d_shader_parser
{
struct vkd3d_shader_message_context *message_context;
@ -1235,9 +1322,8 @@ struct vkd3d_shader_parser
bool failed;
struct vkd3d_shader_desc shader_desc;
struct vkd3d_shader_version shader_version;
const struct vkd3d_shader_parser_ops *ops;
struct vkd3d_shader_instruction_array instructions;
struct vsir_program program;
uint64_t config_flags;
};
@ -1256,18 +1342,6 @@ bool vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser,
void vkd3d_shader_parser_warning(struct vkd3d_shader_parser *parser,
enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4);
static inline struct vkd3d_shader_dst_param *shader_parser_get_dst_params(
struct vkd3d_shader_parser *parser, unsigned int count)
{
return shader_dst_param_allocator_get(&parser->instructions.dst_params, count);
}
static inline struct vkd3d_shader_src_param *shader_parser_get_src_params(
struct vkd3d_shader_parser *parser, unsigned int count)
{
return shader_src_param_allocator_get(&parser->instructions.src_params, count);
}
static inline void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parser)
{
parser->ops->parser_destroy(parser);
@ -1286,6 +1360,7 @@ struct vkd3d_shader_descriptor_info1
unsigned int buffer_size;
unsigned int structure_stride;
unsigned int count;
uint32_t uav_flags;
};
struct vkd3d_shader_scan_descriptor_info1
@ -1294,8 +1369,7 @@ struct vkd3d_shader_scan_descriptor_info1
unsigned int descriptor_count;
};
void vkd3d_shader_trace(const struct vkd3d_shader_instruction_array *instructions,
const struct vkd3d_shader_version *shader_version);
void vkd3d_shader_trace(const struct vsir_program *program);
const char *shader_get_type_prefix(enum vkd3d_shader_type type);
@ -1311,14 +1385,21 @@ struct vkd3d_string_buffer_cache
size_t count, max_count, capacity;
};
enum vkd3d_result vkd3d_dxbc_binary_to_text(const struct vkd3d_shader_instruction_array *instructions,
const struct vkd3d_shader_version *shader_version, const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_code *out);
enum vsir_asm_dialect
{
VSIR_ASM_VSIR,
VSIR_ASM_D3D,
};
enum vkd3d_result vkd3d_dxbc_binary_to_text(const struct vsir_program *program,
const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_code *out, enum vsir_asm_dialect dialect);
void vkd3d_string_buffer_cleanup(struct vkd3d_string_buffer *buffer);
struct vkd3d_string_buffer *vkd3d_string_buffer_get(struct vkd3d_string_buffer_cache *list);
void vkd3d_string_buffer_init(struct vkd3d_string_buffer *buffer);
void vkd3d_string_buffer_cache_cleanup(struct vkd3d_string_buffer_cache *list);
void vkd3d_string_buffer_cache_init(struct vkd3d_string_buffer_cache *list);
void vkd3d_string_buffer_clear(struct vkd3d_string_buffer *buffer);
int vkd3d_string_buffer_print_f32(struct vkd3d_string_buffer *buffer, float f);
int vkd3d_string_buffer_print_f64(struct vkd3d_string_buffer *buffer, double d);
int vkd3d_string_buffer_printf(struct vkd3d_string_buffer *buffer, const char *format, ...) VKD3D_PRINTF_FUNC(2, 3);
@ -1338,7 +1419,10 @@ struct vkd3d_bytecode_buffer
/* Align to the next 4-byte offset, and return that offset. */
size_t bytecode_align(struct vkd3d_bytecode_buffer *buffer);
size_t bytecode_put_bytes(struct vkd3d_bytecode_buffer *buffer, const void *bytes, size_t size);
size_t bytecode_put_bytes_unaligned(struct vkd3d_bytecode_buffer *buffer, const void *bytes, size_t size);
size_t bytecode_reserve_bytes(struct vkd3d_bytecode_buffer *buffer, size_t size);
void set_u32(struct vkd3d_bytecode_buffer *buffer, size_t offset, uint32_t value);
void set_string(struct vkd3d_bytecode_buffer *buffer, size_t offset, const char *string, size_t length);
static inline size_t put_u32(struct vkd3d_bytecode_buffer *buffer, uint32_t value)
{
@ -1382,6 +1466,8 @@ void vkd3d_shader_verror(struct vkd3d_shader_message_context *context, const str
enum vkd3d_shader_error error, const char *format, va_list args);
void vkd3d_shader_vnote(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location,
enum vkd3d_shader_log_level level, const char *format, va_list args);
void vkd3d_shader_warning(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location,
enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(4, 5);
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);
@ -1409,7 +1495,7 @@ struct vkd3d_glsl_generator;
struct vkd3d_glsl_generator *vkd3d_glsl_generator_create(const struct vkd3d_shader_version *version,
struct vkd3d_shader_message_context *message_context, const struct vkd3d_shader_location *location);
int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *generator,
struct vkd3d_shader_parser *parser, struct vkd3d_shader_code *out);
struct vsir_program *program, struct vkd3d_shader_code *out);
void vkd3d_glsl_generator_destroy(struct vkd3d_glsl_generator *generator);
#define SPIRV_MAX_SRC_COUNT 6
@ -1427,7 +1513,7 @@ 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);
enum vkd3d_result 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)
@ -1444,6 +1530,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_UINT64:
return VKD3D_SHADER_COMPONENT_UINT64;
case VKD3D_DATA_BOOL:
return VKD3D_SHADER_COMPONENT_BOOL;
default:
@ -1505,7 +1593,7 @@ static inline enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval(enum
return vkd3d_siv_from_sysval_indexed(sysval, 0);
}
static inline unsigned int vkd3d_write_mask_get_component_idx(DWORD write_mask)
static inline unsigned int vsir_write_mask_get_component_idx(uint32_t write_mask)
{
unsigned int i;
@ -1520,7 +1608,7 @@ static inline unsigned int vkd3d_write_mask_get_component_idx(DWORD write_mask)
return 0;
}
static inline unsigned int vkd3d_write_mask_component_count(DWORD write_mask)
static inline unsigned int vsir_write_mask_component_count(uint32_t write_mask)
{
unsigned int count = vkd3d_popcount(write_mask & VKD3DSP_WRITEMASK_ALL);
assert(1 <= count && count <= VKD3D_VEC4_SIZE);
@ -1533,32 +1621,94 @@ static inline unsigned int vkd3d_write_mask_from_component_count(unsigned int co
return (VKD3DSP_WRITEMASK_0 << component_count) - 1;
}
static inline unsigned int vkd3d_write_mask_64_from_32(DWORD write_mask32)
static inline uint32_t vsir_write_mask_64_from_32(uint32_t write_mask32)
{
unsigned int write_mask64 = write_mask32 | (write_mask32 >> 1);
return (write_mask64 & VKD3DSP_WRITEMASK_0) | ((write_mask64 & VKD3DSP_WRITEMASK_2) >> 1);
switch (write_mask32)
{
case VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1:
return VKD3DSP_WRITEMASK_0;
case VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3:
return VKD3DSP_WRITEMASK_1;
case VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1 | VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3:
return VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1;
default:
ERR("Invalid 32 bit writemask when converting to 64 bit: %#x.\n", write_mask32);
return VKD3DSP_WRITEMASK_0;
}
}
static inline unsigned int vkd3d_write_mask_32_from_64(unsigned int write_mask64)
static inline uint32_t vsir_write_mask_32_from_64(uint32_t write_mask64)
{
unsigned int write_mask32 = (write_mask64 | (write_mask64 << 1))
& (VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_2);
return write_mask32 | (write_mask32 << 1);
switch (write_mask64)
{
case VKD3DSP_WRITEMASK_0:
return VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1;
case VKD3DSP_WRITEMASK_1:
return VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3;
case VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1:
return VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1 | VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3;
default:
ERR("Invalid 64 bit writemask: %#x.\n", write_mask64);
return VKD3DSP_WRITEMASK_0;
}
}
static inline unsigned int vkd3d_swizzle_get_component(DWORD swizzle,
unsigned int idx)
static inline uint32_t vsir_swizzle_64_from_32(uint32_t swizzle32)
{
switch (swizzle32)
{
case VKD3D_SHADER_SWIZZLE(X, Y, X, Y):
return VKD3D_SHADER_SWIZZLE(X, X, X, X);
case VKD3D_SHADER_SWIZZLE(X, Y, Z, W):
return VKD3D_SHADER_SWIZZLE(X, Y, X, X);
case VKD3D_SHADER_SWIZZLE(Z, W, X, Y):
return VKD3D_SHADER_SWIZZLE(Y, X, X, X);
case VKD3D_SHADER_SWIZZLE(Z, W, Z, W):
return VKD3D_SHADER_SWIZZLE(Y, Y, X, X);
default:
ERR("Invalid 32 bit swizzle when converting to 64 bit: %#x.\n", swizzle32);
return VKD3D_SHADER_SWIZZLE(X, X, X, X);
}
}
static inline uint32_t vsir_swizzle_32_from_64(uint32_t swizzle64)
{
switch (swizzle64)
{
case VKD3D_SHADER_SWIZZLE(X, X, X, X):
return VKD3D_SHADER_SWIZZLE(X, Y, X, Y);
case VKD3D_SHADER_SWIZZLE(X, Y, X, X):
return VKD3D_SHADER_SWIZZLE(X, Y, Z, W);
case VKD3D_SHADER_SWIZZLE(Y, X, X, X):
return VKD3D_SHADER_SWIZZLE(Z, W, X, Y);
case VKD3D_SHADER_SWIZZLE(Y, Y, X, X):
return VKD3D_SHADER_SWIZZLE(Z, W, Z, W);
default:
ERR("Invalid 64 bit swizzle: %#x.\n", swizzle64);
return VKD3D_SHADER_SWIZZLE(X, Y, X, Y);
}
}
static inline unsigned int vsir_swizzle_get_component(uint32_t swizzle, unsigned int idx)
{
return (swizzle >> VKD3D_SHADER_SWIZZLE_SHIFT(idx)) & VKD3D_SHADER_SWIZZLE_MASK;
}
static inline unsigned int vkd3d_swizzle_get_component64(DWORD swizzle,
unsigned int idx)
{
return ((swizzle >> VKD3D_SHADER_SWIZZLE_SHIFT(idx * 2)) & VKD3D_SHADER_SWIZZLE_MASK) / 2u;
}
static inline unsigned int vkd3d_compact_swizzle(unsigned int swizzle, unsigned int write_mask)
static inline unsigned int vkd3d_compact_swizzle(uint32_t swizzle, uint32_t write_mask)
{
unsigned int i, compacted_swizzle = 0;
@ -1567,7 +1717,7 @@ static inline unsigned int vkd3d_compact_swizzle(unsigned int swizzle, unsigned
if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
{
compacted_swizzle <<= VKD3D_SHADER_SWIZZLE_SHIFT(1);
compacted_swizzle |= vkd3d_swizzle_get_component(swizzle, i);
compacted_swizzle |= vsir_swizzle_get_component(swizzle, i);
}
}

View file

@ -313,7 +313,7 @@ static void vkd3d_wait_for_gpu_fence(struct vkd3d_fence_worker *worker,
TRACE("Signaling fence %p value %#"PRIx64".\n", waiting_fence->fence, waiting_fence->value);
if (FAILED(hr = d3d12_fence_signal(waiting_fence->fence, waiting_fence->value, waiting_fence->u.vk_fence, false)))
ERR("Failed to signal D3D12 fence, hr %#x.\n", hr);
ERR("Failed to signal d3d12 fence, hr %s.\n", debugstr_hresult(hr));
d3d12_fence_decref(waiting_fence->fence);
@ -926,7 +926,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_fence_QueryInterface(ID3D12Fence1 *iface,
static ULONG STDMETHODCALLTYPE d3d12_fence_AddRef(ID3D12Fence1 *iface)
{
struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface);
ULONG refcount = InterlockedIncrement(&fence->refcount);
unsigned int refcount = vkd3d_atomic_increment_u32(&fence->refcount);
TRACE("%p increasing refcount to %u.\n", fence, refcount);
@ -935,13 +935,13 @@ static ULONG STDMETHODCALLTYPE d3d12_fence_AddRef(ID3D12Fence1 *iface)
static void d3d12_fence_incref(struct d3d12_fence *fence)
{
InterlockedIncrement(&fence->internal_refcount);
vkd3d_atomic_increment_u32(&fence->internal_refcount);
}
static ULONG STDMETHODCALLTYPE d3d12_fence_Release(ID3D12Fence1 *iface)
{
struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface);
ULONG refcount = InterlockedDecrement(&fence->refcount);
unsigned int refcount = vkd3d_atomic_decrement_u32(&fence->refcount);
TRACE("%p decreasing refcount to %u.\n", fence, refcount);
@ -953,24 +953,24 @@ static ULONG STDMETHODCALLTYPE d3d12_fence_Release(ID3D12Fence1 *iface)
static void d3d12_fence_decref(struct d3d12_fence *fence)
{
ULONG internal_refcount = InterlockedDecrement(&fence->internal_refcount);
struct d3d12_device *device;
if (!internal_refcount)
{
struct d3d12_device *device = fence->device;
if (vkd3d_atomic_decrement_u32(&fence->internal_refcount))
return;
vkd3d_private_store_destroy(&fence->private_store);
device = fence->device;
d3d12_fence_destroy_vk_objects(fence);
vkd3d_private_store_destroy(&fence->private_store);
vkd3d_free(fence->events);
vkd3d_free(fence->semaphores);
vkd3d_mutex_destroy(&fence->mutex);
vkd3d_cond_destroy(&fence->null_event_cond);
vkd3d_free(fence);
d3d12_fence_destroy_vk_objects(fence);
d3d12_device_release(device);
}
vkd3d_free(fence->events);
vkd3d_free(fence->semaphores);
vkd3d_mutex_destroy(&fence->mutex);
vkd3d_cond_destroy(&fence->null_event_cond);
vkd3d_free(fence);
d3d12_device_release(device);
}
static HRESULT STDMETHODCALLTYPE d3d12_fence_GetPrivateData(ID3D12Fence1 *iface,
@ -1635,7 +1635,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_allocator_QueryInterface(ID3D12Co
static ULONG STDMETHODCALLTYPE d3d12_command_allocator_AddRef(ID3D12CommandAllocator *iface)
{
struct d3d12_command_allocator *allocator = impl_from_ID3D12CommandAllocator(iface);
ULONG refcount = InterlockedIncrement(&allocator->refcount);
unsigned int refcount = vkd3d_atomic_increment_u32(&allocator->refcount);
TRACE("%p increasing refcount to %u.\n", allocator, refcount);
@ -1645,7 +1645,7 @@ static ULONG STDMETHODCALLTYPE d3d12_command_allocator_AddRef(ID3D12CommandAlloc
static ULONG STDMETHODCALLTYPE d3d12_command_allocator_Release(ID3D12CommandAllocator *iface)
{
struct d3d12_command_allocator *allocator = impl_from_ID3D12CommandAllocator(iface);
ULONG refcount = InterlockedDecrement(&allocator->refcount);
unsigned int refcount = vkd3d_atomic_decrement_u32(&allocator->refcount);
TRACE("%p decreasing refcount to %u.\n", allocator, refcount);
@ -1921,12 +1921,12 @@ HRESULT d3d12_command_allocator_create(struct d3d12_device *device,
static void d3d12_command_signature_incref(struct d3d12_command_signature *signature)
{
vkd3d_atomic_increment(&signature->internal_refcount);
vkd3d_atomic_increment_u32(&signature->internal_refcount);
}
static void d3d12_command_signature_decref(struct d3d12_command_signature *signature)
{
unsigned int refcount = vkd3d_atomic_decrement(&signature->internal_refcount);
unsigned int refcount = vkd3d_atomic_decrement_u32(&signature->internal_refcount);
if (!refcount)
{
@ -2320,7 +2320,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12Graphic
static ULONG STDMETHODCALLTYPE d3d12_command_list_AddRef(ID3D12GraphicsCommandList5 *iface)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
ULONG refcount = InterlockedIncrement(&list->refcount);
unsigned int refcount = vkd3d_atomic_increment_u32(&list->refcount);
TRACE("%p increasing refcount to %u.\n", list, refcount);
@ -2335,7 +2335,7 @@ static void vkd3d_pipeline_bindings_cleanup(struct vkd3d_pipeline_bindings *bind
static ULONG STDMETHODCALLTYPE d3d12_command_list_Release(ID3D12GraphicsCommandList5 *iface)
{
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface);
ULONG refcount = InterlockedDecrement(&list->refcount);
unsigned int refcount = vkd3d_atomic_decrement_u32(&list->refcount);
TRACE("%p decreasing refcount to %u.\n", list, refcount);
@ -2644,6 +2644,8 @@ static bool d3d12_command_list_update_compute_pipeline(struct d3d12_command_list
{
const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs;
vkd3d_cond_signal(&list->device->worker_cond);
if (list->current_pipeline != VK_NULL_HANDLE)
return true;
@ -2665,6 +2667,8 @@ static bool d3d12_command_list_update_graphics_pipeline(struct d3d12_command_lis
VkRenderPass vk_render_pass;
VkPipeline vk_pipeline;
vkd3d_cond_signal(&list->device->worker_cond);
if (list->current_pipeline != VK_NULL_HANDLE)
return true;
@ -3266,7 +3270,8 @@ static void d3d12_command_list_bind_descriptor_heap(struct d3d12_command_list *l
{
VkDescriptorSet vk_descriptor_set = heap->vk_descriptor_sets[set].vk_set;
if (!vk_descriptor_set)
/* Null vk_set_layout means set 0 uses mutable descriptors, and this set is unused. */
if (!vk_descriptor_set || !list->device->vk_descriptor_heap_layouts[set].vk_set_layout)
continue;
VK_CALL(vkCmdBindDescriptorSets(list->vk_command_buffer, bindings->vk_bind_point, rs->vk_pipeline_layout,
@ -3503,7 +3508,7 @@ static void vk_image_subresource_layers_from_d3d12(VkImageSubresourceLayers *sub
}
static void vk_extent_3d_from_d3d12_miplevel(VkExtent3D *extent,
const D3D12_RESOURCE_DESC *resource_desc, unsigned int miplevel_idx)
const D3D12_RESOURCE_DESC1 *resource_desc, unsigned int miplevel_idx)
{
extent->width = d3d12_resource_desc_get_width(resource_desc, miplevel_idx);
extent->height = d3d12_resource_desc_get_height(resource_desc, miplevel_idx);
@ -3512,7 +3517,7 @@ static void vk_extent_3d_from_d3d12_miplevel(VkExtent3D *extent,
static void vk_buffer_image_copy_from_d3d12(VkBufferImageCopy *copy,
const D3D12_PLACED_SUBRESOURCE_FOOTPRINT *footprint, unsigned int sub_resource_idx,
const D3D12_RESOURCE_DESC *image_desc, const struct vkd3d_format *format,
const D3D12_RESOURCE_DESC1 *image_desc, const struct vkd3d_format *format,
const D3D12_BOX *src_box, unsigned int dst_x, unsigned int dst_y, unsigned int dst_z)
{
copy->bufferOffset = footprint->Offset;
@ -3553,7 +3558,7 @@ static void vk_buffer_image_copy_from_d3d12(VkBufferImageCopy *copy,
static void vk_image_buffer_copy_from_d3d12(VkBufferImageCopy *copy,
const D3D12_PLACED_SUBRESOURCE_FOOTPRINT *footprint, unsigned int sub_resource_idx,
const D3D12_RESOURCE_DESC *image_desc, const struct vkd3d_format *format,
const D3D12_RESOURCE_DESC1 *image_desc, const struct vkd3d_format *format,
const D3D12_BOX *src_box, unsigned int dst_x, unsigned int dst_y, unsigned int dst_z)
{
VkDeviceSize row_count = footprint->Footprint.Height / format->block_height;
@ -3583,7 +3588,7 @@ static void vk_image_buffer_copy_from_d3d12(VkBufferImageCopy *copy,
static void vk_image_copy_from_d3d12(VkImageCopy *image_copy,
unsigned int src_sub_resource_idx, unsigned int dst_sub_resource_idx,
const D3D12_RESOURCE_DESC *src_desc, const D3D12_RESOURCE_DESC *dst_desc,
const D3D12_RESOURCE_DESC1 *src_desc, const D3D12_RESOURCE_DESC1 *dst_desc,
const struct vkd3d_format *src_format, const struct vkd3d_format *dst_format,
const D3D12_BOX *src_box, unsigned int dst_x, unsigned int dst_y, unsigned int dst_z)
{
@ -3616,7 +3621,7 @@ static HRESULT d3d12_command_list_allocate_transfer_buffer(struct d3d12_command_
const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs;
struct d3d12_device *device = list->device;
D3D12_HEAP_PROPERTIES heap_properties;
D3D12_RESOURCE_DESC buffer_desc;
D3D12_RESOURCE_DESC1 buffer_desc;
HRESULT hr;
memset(&heap_properties, 0, sizeof(heap_properties));
@ -3666,8 +3671,8 @@ static void d3d12_command_list_copy_incompatible_texture_region(struct d3d12_com
unsigned int src_sub_resource_idx, const struct vkd3d_format *src_format, unsigned int layer_count)
{
const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs;
const D3D12_RESOURCE_DESC *dst_desc = &dst_resource->desc;
const D3D12_RESOURCE_DESC *src_desc = &src_resource->desc;
const D3D12_RESOURCE_DESC1 *dst_desc = &dst_resource->desc;
const D3D12_RESOURCE_DESC1 *src_desc = &src_resource->desc;
unsigned int dst_miplevel_idx, src_miplevel_idx;
struct vkd3d_buffer transfer_buffer;
VkBufferImageCopy buffer_image_copy;
@ -3701,7 +3706,7 @@ static void d3d12_command_list_copy_incompatible_texture_region(struct d3d12_com
buffer_image_copy.imageExtent.height * buffer_image_copy.imageExtent.depth * layer_count;
if (FAILED(hr = d3d12_command_list_allocate_transfer_buffer(list, buffer_size, &transfer_buffer)))
{
ERR("Failed to allocate transfer buffer, hr %#x.\n", hr);
ERR("Failed to allocate transfer buffer, hr %s.\n", debugstr_hresult(hr));
return;
}
@ -4494,8 +4499,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootDescriptorTable(I
{
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);
TRACE("iface %p, root_parameter_index %u, base_descriptor %s.\n",
iface, root_parameter_index, debug_gpu_handle(base_descriptor));
d3d12_command_list_set_descriptor_table(list, VKD3D_PIPELINE_BIND_POINT_COMPUTE,
root_parameter_index, base_descriptor);
@ -4506,8 +4511,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootDescriptorTable(
{
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);
TRACE("iface %p, root_parameter_index %u, base_descriptor %s.\n",
iface, root_parameter_index, debug_gpu_handle(base_descriptor));
d3d12_command_list_set_descriptor_table(list, VKD3D_PIPELINE_BIND_POINT_GRAPHICS,
root_parameter_index, base_descriptor);
@ -5127,8 +5132,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12Gra
struct VkAttachmentDescription attachment_desc;
struct VkAttachmentReference ds_reference;
TRACE("iface %p, dsv %#lx, flags %#x, depth %.8e, stencil 0x%02x, rect_count %u, rects %p.\n",
iface, dsv.ptr, flags, depth, stencil, rect_count, rects);
TRACE("iface %p, dsv %s, flags %#x, depth %.8e, stencil 0x%02x, rect_count %u, rects %p.\n",
iface, debug_cpu_handle(dsv), flags, depth, stencil, rect_count, rects);
d3d12_command_list_track_resource_usage(list, dsv_desc->resource);
@ -5175,8 +5180,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12Gra
struct VkAttachmentReference color_reference;
VkClearValue clear_value;
TRACE("iface %p, rtv %#lx, color %p, rect_count %u, rects %p.\n",
iface, rtv.ptr, color, rect_count, rects);
TRACE("iface %p, rtv %s, color %p, rect_count %u, rects %p.\n",
iface, debug_cpu_handle(rtv), color, rect_count, rects);
d3d12_command_list_track_resource_usage(list, rtv_desc->resource);
@ -5427,8 +5432,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID
struct d3d12_resource *resource_impl;
VkClearColorValue colour;
TRACE("iface %p, gpu_handle %#"PRIx64", cpu_handle %lx, resource %p, values %p, rect_count %u, rects %p.\n",
iface, gpu_handle.ptr, cpu_handle.ptr, resource, values, rect_count, rects);
TRACE("iface %p, gpu_handle %s, cpu_handle %s, resource %p, values %p, rect_count %u, rects %p.\n",
iface, debug_gpu_handle(gpu_handle), debug_cpu_handle(cpu_handle), resource, values, rect_count, rects);
resource_impl = unsafe_impl_from_ID3D12Resource(resource);
if (!(descriptor = d3d12_desc_from_cpu_handle(cpu_handle)->s.u.view))
@ -5491,8 +5496,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(I
VkClearColorValue colour;
struct vkd3d_view *view;
TRACE("iface %p, gpu_handle %#"PRIx64", cpu_handle %lx, resource %p, values %p, rect_count %u, rects %p.\n",
iface, gpu_handle.ptr, cpu_handle.ptr, resource, values, rect_count, rects);
TRACE("iface %p, gpu_handle %s, cpu_handle %s, resource %p, values %p, rect_count %u, rects %p.\n",
iface, debug_gpu_handle(gpu_handle), debug_cpu_handle(cpu_handle), resource, values, rect_count, rects);
resource_impl = unsafe_impl_from_ID3D12Resource(resource);
if (!(view = d3d12_desc_from_cpu_handle(cpu_handle)->s.u.view))
@ -5958,15 +5963,15 @@ static void STDMETHODCALLTYPE d3d12_command_list_EndRenderPass(ID3D12GraphicsCom
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);
FIXME("iface %p, meta_command %p, parameters_data %p, data_size_in_bytes %"PRIuPTR" stub!\n", iface,
meta_command, parameters_data, (uintptr_t)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);
FIXME("iface %p, meta_command %p, parameters_data %p, data_size_in_bytes %"PRIuPTR" stub!\n", iface,
meta_command, parameters_data, (uintptr_t)data_size_in_bytes);
}
static void STDMETHODCALLTYPE d3d12_command_list_BuildRaytracingAccelerationStructure(ID3D12GraphicsCommandList5 *iface,
@ -6225,7 +6230,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_QueryInterface(ID3D12Comman
static ULONG STDMETHODCALLTYPE d3d12_command_queue_AddRef(ID3D12CommandQueue *iface)
{
struct d3d12_command_queue *command_queue = impl_from_ID3D12CommandQueue(iface);
ULONG refcount = InterlockedIncrement(&command_queue->refcount);
unsigned int refcount = vkd3d_atomic_increment_u32(&command_queue->refcount);
TRACE("%p increasing refcount to %u.\n", command_queue, refcount);
@ -6267,7 +6272,7 @@ static void d3d12_command_queue_op_array_destroy(struct d3d12_command_queue_op_a
static ULONG STDMETHODCALLTYPE d3d12_command_queue_Release(ID3D12CommandQueue *iface)
{
struct d3d12_command_queue *command_queue = impl_from_ID3D12CommandQueue(iface);
ULONG refcount = InterlockedDecrement(&command_queue->refcount);
unsigned int refcount = vkd3d_atomic_decrement_u32(&command_queue->refcount);
TRACE("%p decreasing refcount to %u.\n", command_queue, refcount);
@ -6508,7 +6513,7 @@ static void STDMETHODCALLTYPE d3d12_command_queue_CopyTileMappings(ID3D12Command
if (!(op = d3d12_command_queue_op_array_require_space(&command_queue->op_queue)))
{
ERR("Failed to add op.\n");
return;
goto unlock_mutex;
}
op->opcode = VKD3D_CS_OP_COPY_MAPPINGS;
op->u.copy_mappings.dst_resource = dst_resource_impl;
@ -6520,6 +6525,7 @@ static void STDMETHODCALLTYPE d3d12_command_queue_CopyTileMappings(ID3D12Command
d3d12_command_queue_submit_locked(command_queue);
unlock_mutex:
vkd3d_mutex_unlock(&command_queue->op_mutex);
}
@ -6558,7 +6564,7 @@ static void d3d12_command_queue_submit_locked(struct d3d12_command_queue *queue)
if (queue->op_queue.count == 1 && !queue->is_flushing)
{
if (FAILED(hr = d3d12_command_queue_flush_ops_locked(queue, &flushed_any)))
ERR("Cannot flush queue, hr %#x.\n", hr);
ERR("Failed to flush queue, hr %s.\n", debugstr_hresult(hr));
}
}
@ -7436,7 +7442,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_signature_QueryInterface(ID3D12Co
static ULONG STDMETHODCALLTYPE d3d12_command_signature_AddRef(ID3D12CommandSignature *iface)
{
struct d3d12_command_signature *signature = impl_from_ID3D12CommandSignature(iface);
ULONG refcount = InterlockedIncrement(&signature->refcount);
unsigned int refcount = vkd3d_atomic_increment_u32(&signature->refcount);
TRACE("%p increasing refcount to %u.\n", signature, refcount);
@ -7446,7 +7452,7 @@ static ULONG STDMETHODCALLTYPE d3d12_command_signature_AddRef(ID3D12CommandSigna
static ULONG STDMETHODCALLTYPE d3d12_command_signature_Release(ID3D12CommandSignature *iface)
{
struct d3d12_command_signature *signature = impl_from_ID3D12CommandSignature(iface);
ULONG refcount = InterlockedDecrement(&signature->refcount);
unsigned int refcount = vkd3d_atomic_decrement_u32(&signature->refcount);
TRACE("%p decreasing refcount to %u.\n", signature, refcount);

File diff suppressed because it is too large Load diff

View file

@ -22,7 +22,7 @@
#define VKD3D_NULL_BUFFER_SIZE 16
#define VKD3D_NULL_VIEW_FORMAT DXGI_FORMAT_R8G8B8A8_UNORM
LONG64 object_global_serial_id;
uint64_t object_global_serial_id;
static inline bool is_cpu_accessible_heap(const D3D12_HEAP_PROPERTIES *properties)
{
@ -308,7 +308,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_heap_QueryInterface(ID3D12Heap *iface,
static ULONG STDMETHODCALLTYPE d3d12_heap_AddRef(ID3D12Heap *iface)
{
struct d3d12_heap *heap = impl_from_ID3D12Heap(iface);
ULONG refcount = InterlockedIncrement(&heap->refcount);
unsigned int refcount = vkd3d_atomic_increment_u32(&heap->refcount);
TRACE("%p increasing refcount to %u.\n", heap, refcount);
@ -345,7 +345,7 @@ static void d3d12_heap_destroy(struct d3d12_heap *heap)
static ULONG STDMETHODCALLTYPE d3d12_heap_Release(ID3D12Heap *iface)
{
struct d3d12_heap *heap = impl_from_ID3D12Heap(iface);
ULONG refcount = InterlockedDecrement(&heap->refcount);
unsigned int refcount = vkd3d_atomic_decrement_u32(&heap->refcount);
TRACE("%p decreasing refcount to %u.\n", heap, refcount);
@ -358,7 +358,7 @@ static ULONG STDMETHODCALLTYPE d3d12_heap_Release(ID3D12Heap *iface)
static void d3d12_heap_resource_destroyed(struct d3d12_heap *heap)
{
if (!InterlockedDecrement(&heap->resource_count) && (!heap->refcount || heap->is_private))
if (!vkd3d_atomic_decrement_u32(&heap->resource_count) && (!heap->refcount || heap->is_private))
d3d12_heap_destroy(heap);
}
@ -651,7 +651,7 @@ VkSampleCountFlagBits vk_samples_from_dxgi_sample_desc(const DXGI_SAMPLE_DESC *d
HRESULT vkd3d_create_buffer(struct d3d12_device *device,
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,
const D3D12_RESOURCE_DESC *desc, VkBuffer *vk_buffer)
const D3D12_RESOURCE_DESC1 *desc, VkBuffer *vk_buffer)
{
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
const bool sparse_resource = !heap_properties;
@ -731,7 +731,7 @@ HRESULT vkd3d_create_buffer(struct d3d12_device *device,
return hresult_from_vk_result(vr);
}
static unsigned int max_miplevel_count(const D3D12_RESOURCE_DESC *desc)
static unsigned int max_miplevel_count(const D3D12_RESOURCE_DESC1 *desc)
{
unsigned int size = max(desc->Width, desc->Height);
size = max(size, d3d12_resource_desc_get_depth(desc, 0));
@ -775,7 +775,7 @@ static bool vkd3d_is_linear_tiling_supported(const struct d3d12_device *device,
static HRESULT vkd3d_create_image(struct d3d12_device *device,
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,
const D3D12_RESOURCE_DESC *desc, struct d3d12_resource *resource, VkImage *vk_image)
const D3D12_RESOURCE_DESC1 *desc, struct d3d12_resource *resource, VkImage *vk_image)
{
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
const struct vkd3d_format_compatibility_list *compat_list;
@ -940,11 +940,11 @@ static HRESULT vkd3d_create_image(struct d3d12_device *device,
}
HRESULT vkd3d_get_image_allocation_info(struct d3d12_device *device,
const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_ALLOCATION_INFO *allocation_info)
const D3D12_RESOURCE_DESC1 *desc, struct vkd3d_resource_allocation_info *allocation_info)
{
static const D3D12_HEAP_PROPERTIES heap_properties = {D3D12_HEAP_TYPE_DEFAULT};
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
D3D12_RESOURCE_DESC validated_desc;
D3D12_RESOURCE_DESC1 validated_desc;
VkMemoryRequirements requirements;
VkImage vk_image;
bool tiled;
@ -968,8 +968,8 @@ HRESULT vkd3d_get_image_allocation_info(struct d3d12_device *device,
VK_CALL(vkGetImageMemoryRequirements(device->vk_device, vk_image, &requirements));
VK_CALL(vkDestroyImage(device->vk_device, vk_image, NULL));
allocation_info->SizeInBytes = requirements.size;
allocation_info->Alignment = requirements.alignment;
allocation_info->size_in_bytes = requirements.size;
allocation_info->alignment = requirements.alignment;
}
return hr;
@ -1003,7 +1003,7 @@ static void d3d12_resource_destroy(struct d3d12_resource *resource, struct d3d12
static ULONG d3d12_resource_incref(struct d3d12_resource *resource)
{
ULONG refcount = InterlockedIncrement(&resource->internal_refcount);
unsigned int refcount = vkd3d_atomic_increment_u32(&resource->internal_refcount);
TRACE("%p increasing refcount to %u.\n", resource, refcount);
@ -1012,7 +1012,7 @@ static ULONG d3d12_resource_incref(struct d3d12_resource *resource)
static ULONG d3d12_resource_decref(struct d3d12_resource *resource)
{
ULONG refcount = InterlockedDecrement(&resource->internal_refcount);
unsigned int refcount = vkd3d_atomic_decrement_u32(&resource->internal_refcount);
TRACE("%p decreasing refcount to %u.\n", resource, refcount);
@ -1069,7 +1069,7 @@ static void d3d12_resource_get_level_box(const struct d3d12_resource *resource,
}
static void compute_image_subresource_size_in_tiles(const VkExtent3D *tile_extent,
const struct D3D12_RESOURCE_DESC *desc, unsigned int miplevel_idx,
const struct D3D12_RESOURCE_DESC1 *desc, unsigned int miplevel_idx,
struct vkd3d_tiled_region_extent *size)
{
unsigned int width, height, depth;
@ -1258,12 +1258,13 @@ static bool d3d12_resource_init_tiles(struct d3d12_resource *resource, struct d3
}
/* ID3D12Resource */
static HRESULT STDMETHODCALLTYPE d3d12_resource_QueryInterface(ID3D12Resource1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_resource_QueryInterface(ID3D12Resource2 *iface,
REFIID riid, void **object)
{
TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
if (IsEqualGUID(riid, &IID_ID3D12Resource1)
if (IsEqualGUID(riid, &IID_ID3D12Resource2)
|| IsEqualGUID(riid, &IID_ID3D12Resource1)
|| IsEqualGUID(riid, &IID_ID3D12Resource)
|| IsEqualGUID(riid, &IID_ID3D12Pageable)
|| IsEqualGUID(riid, &IID_ID3D12DeviceChild)
@ -1281,10 +1282,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_QueryInterface(ID3D12Resource1 *
return E_NOINTERFACE;
}
static ULONG STDMETHODCALLTYPE d3d12_resource_AddRef(ID3D12Resource1 *iface)
static ULONG STDMETHODCALLTYPE d3d12_resource_AddRef(ID3D12Resource2 *iface)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
ULONG refcount = InterlockedIncrement(&resource->refcount);
struct d3d12_resource *resource = impl_from_ID3D12Resource2(iface);
unsigned int refcount = vkd3d_atomic_increment_u32(&resource->refcount);
TRACE("%p increasing refcount to %u.\n", resource, refcount);
@ -1299,10 +1300,10 @@ static ULONG STDMETHODCALLTYPE d3d12_resource_AddRef(ID3D12Resource1 *iface)
return refcount;
}
static ULONG STDMETHODCALLTYPE d3d12_resource_Release(ID3D12Resource1 *iface)
static ULONG STDMETHODCALLTYPE d3d12_resource_Release(ID3D12Resource2 *iface)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
ULONG refcount = InterlockedDecrement(&resource->refcount);
struct d3d12_resource *resource = impl_from_ID3D12Resource2(iface);
unsigned int refcount = vkd3d_atomic_decrement_u32(&resource->refcount);
TRACE("%p decreasing refcount to %u.\n", resource, refcount);
@ -1318,39 +1319,39 @@ static ULONG STDMETHODCALLTYPE d3d12_resource_Release(ID3D12Resource1 *iface)
return refcount;
}
static HRESULT STDMETHODCALLTYPE d3d12_resource_GetPrivateData(ID3D12Resource1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_resource_GetPrivateData(ID3D12Resource2 *iface,
REFGUID guid, UINT *data_size, void *data)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
struct d3d12_resource *resource = impl_from_ID3D12Resource2(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(ID3D12Resource1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_resource_SetPrivateData(ID3D12Resource2 *iface,
REFGUID guid, UINT data_size, const void *data)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
struct d3d12_resource *resource = impl_from_ID3D12Resource2(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(ID3D12Resource1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_resource_SetPrivateDataInterface(ID3D12Resource2 *iface,
REFGUID guid, const IUnknown *data)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
struct d3d12_resource *resource = impl_from_ID3D12Resource2(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(ID3D12Resource1 *iface, const WCHAR *name)
static HRESULT STDMETHODCALLTYPE d3d12_resource_SetName(ID3D12Resource2 *iface, const WCHAR *name)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
struct d3d12_resource *resource = impl_from_ID3D12Resource2(iface);
HRESULT hr;
TRACE("iface %p, name %s.\n", iface, debugstr_w(name, resource->device->wchar_size));
@ -1369,9 +1370,9 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_SetName(ID3D12Resource1 *iface,
VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, name);
}
static HRESULT STDMETHODCALLTYPE d3d12_resource_GetDevice(ID3D12Resource1 *iface, REFIID iid, void **device)
static HRESULT STDMETHODCALLTYPE d3d12_resource_GetDevice(ID3D12Resource2 *iface, REFIID iid, void **device)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
struct d3d12_resource *resource = impl_from_ID3D12Resource2(iface);
TRACE("iface %p, iid %s, device %p.\n", iface, debugstr_guid(iid), device);
@ -1422,10 +1423,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(ID3D12Resource1 *iface, UINT sub_resource,
static HRESULT STDMETHODCALLTYPE d3d12_resource_Map(ID3D12Resource2 *iface, UINT sub_resource,
const D3D12_RANGE *read_range, void **data)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
struct d3d12_resource *resource = impl_from_ID3D12Resource2(iface);
unsigned int sub_resource_count;
TRACE("iface %p, sub_resource %u, read_range %p, data %p.\n",
@ -1471,10 +1472,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_Map(ID3D12Resource1 *iface, UINT
return S_OK;
}
static void STDMETHODCALLTYPE d3d12_resource_Unmap(ID3D12Resource1 *iface, UINT sub_resource,
static void STDMETHODCALLTYPE d3d12_resource_Unmap(ID3D12Resource2 *iface, UINT sub_resource,
const D3D12_RANGE *written_range)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
struct d3d12_resource *resource = impl_from_ID3D12Resource2(iface);
unsigned int sub_resource_count;
TRACE("iface %p, sub_resource %u, written_range %p.\n",
@ -1493,31 +1494,31 @@ static void STDMETHODCALLTYPE d3d12_resource_Unmap(ID3D12Resource1 *iface, UINT
d3d12_resource_flush(resource, written_range->Begin, written_range->End - written_range->Begin);
}
static D3D12_RESOURCE_DESC * STDMETHODCALLTYPE d3d12_resource_GetDesc(ID3D12Resource1 *iface,
static D3D12_RESOURCE_DESC * STDMETHODCALLTYPE d3d12_resource_GetDesc(ID3D12Resource2 *iface,
D3D12_RESOURCE_DESC *resource_desc)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
struct d3d12_resource *resource = impl_from_ID3D12Resource2(iface);
TRACE("iface %p, resource_desc %p.\n", iface, resource_desc);
*resource_desc = resource->desc;
memcpy(resource_desc, &resource->desc, sizeof(*resource_desc));
return resource_desc;
}
static D3D12_GPU_VIRTUAL_ADDRESS STDMETHODCALLTYPE d3d12_resource_GetGPUVirtualAddress(ID3D12Resource1 *iface)
static D3D12_GPU_VIRTUAL_ADDRESS STDMETHODCALLTYPE d3d12_resource_GetGPUVirtualAddress(ID3D12Resource2 *iface)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
struct d3d12_resource *resource = impl_from_ID3D12Resource2(iface);
TRACE("iface %p.\n", iface);
return resource->gpu_address;
}
static HRESULT STDMETHODCALLTYPE d3d12_resource_WriteToSubresource(ID3D12Resource1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_resource_WriteToSubresource(ID3D12Resource2 *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_ID3D12Resource1(iface);
struct d3d12_resource *resource = impl_from_ID3D12Resource2(iface);
const struct vkd3d_vk_device_procs *vk_procs;
VkImageSubresource vk_sub_resource;
const struct vkd3d_format *format;
@ -1598,11 +1599,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_WriteToSubresource(ID3D12Resourc
return S_OK;
}
static HRESULT STDMETHODCALLTYPE d3d12_resource_ReadFromSubresource(ID3D12Resource1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_resource_ReadFromSubresource(ID3D12Resource2 *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_ID3D12Resource1(iface);
struct d3d12_resource *resource = impl_from_ID3D12Resource2(iface);
const struct vkd3d_vk_device_procs *vk_procs;
VkImageSubresource vk_sub_resource;
const struct vkd3d_format *format;
@ -1683,10 +1684,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_ReadFromSubresource(ID3D12Resour
return S_OK;
}
static HRESULT STDMETHODCALLTYPE d3d12_resource_GetHeapProperties(ID3D12Resource1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_resource_GetHeapProperties(ID3D12Resource2 *iface,
D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS *flags)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
struct d3d12_resource *resource = impl_from_ID3D12Resource2(iface);
struct d3d12_heap *heap;
TRACE("iface %p, heap_properties %p, flags %p.\n",
@ -1720,15 +1721,26 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_GetHeapProperties(ID3D12Resource
return S_OK;
}
static HRESULT STDMETHODCALLTYPE d3d12_resource_GetProtectedResourceSession(ID3D12Resource1 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_resource_GetProtectedResourceSession(ID3D12Resource2 *iface,
REFIID iid, void **session)
{
FIXME("iface %p, iid %s, session %p stub!\n", iface, debugstr_guid(iid), session);
return E_NOTIMPL;
return DXGI_ERROR_NOT_FOUND;
}
static const struct ID3D12Resource1Vtbl d3d12_resource_vtbl =
static D3D12_RESOURCE_DESC1 * STDMETHODCALLTYPE d3d12_resource_GetDesc1(ID3D12Resource2 *iface,
D3D12_RESOURCE_DESC1 *resource_desc)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource2(iface);
TRACE("iface %p, resource_desc %p.\n", iface, resource_desc);
*resource_desc = resource->desc;
return resource_desc;
}
static const struct ID3D12Resource2Vtbl d3d12_resource_vtbl =
{
/* IUnknown methods */
d3d12_resource_QueryInterface,
@ -1751,6 +1763,8 @@ static const struct ID3D12Resource1Vtbl d3d12_resource_vtbl =
d3d12_resource_GetHeapProperties,
/* ID3D12Resource1 methods */
d3d12_resource_GetProtectedResourceSession,
/* ID3D12Resource2 methods */
d3d12_resource_GetDesc1,
};
struct d3d12_resource *unsafe_impl_from_ID3D12Resource(ID3D12Resource *iface)
@ -1777,7 +1791,7 @@ static void d3d12_validate_resource_flags(D3D12_RESOURCE_FLAGS flags)
FIXME("Ignoring D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER.\n");
}
static bool d3d12_resource_validate_texture_format(const D3D12_RESOURCE_DESC *desc,
static bool d3d12_resource_validate_texture_format(const D3D12_RESOURCE_DESC1 *desc,
const struct vkd3d_format *format)
{
if (desc->Format == DXGI_FORMAT_UNKNOWN)
@ -1806,7 +1820,7 @@ static bool d3d12_resource_validate_texture_format(const D3D12_RESOURCE_DESC *de
return true;
}
static bool d3d12_resource_validate_texture_alignment(const D3D12_RESOURCE_DESC *desc,
static bool d3d12_resource_validate_texture_alignment(const D3D12_RESOURCE_DESC1 *desc,
const struct vkd3d_format *format)
{
uint64_t estimated_size;
@ -1841,7 +1855,7 @@ static bool d3d12_resource_validate_texture_alignment(const D3D12_RESOURCE_DESC
return true;
}
HRESULT d3d12_resource_validate_desc(const D3D12_RESOURCE_DESC *desc, struct d3d12_device *device)
HRESULT d3d12_resource_validate_desc(const D3D12_RESOURCE_DESC1 *desc, struct d3d12_device *device)
{
const struct vkd3d_format *format;
@ -1950,12 +1964,12 @@ static bool d3d12_resource_validate_heap_properties(const struct d3d12_resource
static HRESULT d3d12_resource_init(struct d3d12_resource *resource, 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_RESOURCE_DESC1 *desc, D3D12_RESOURCE_STATES initial_state,
const D3D12_CLEAR_VALUE *optimized_clear_value)
{
HRESULT hr;
resource->ID3D12Resource1_iface.lpVtbl = &d3d12_resource_vtbl;
resource->ID3D12Resource2_iface.lpVtbl = &d3d12_resource_vtbl;
resource->refcount = 1;
resource->internal_refcount = 1;
@ -2047,7 +2061,7 @@ static HRESULT d3d12_resource_init(struct d3d12_resource *resource, struct d3d12
static HRESULT d3d12_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_RESOURCE_DESC1 *desc, D3D12_RESOURCE_STATES initial_state,
const D3D12_CLEAR_VALUE *optimized_clear_value, struct d3d12_resource **resource)
{
struct d3d12_resource *object;
@ -2086,7 +2100,7 @@ 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_RESOURCE_DESC1 *desc, D3D12_RESOURCE_STATES initial_state,
const D3D12_CLEAR_VALUE *optimized_clear_value, ID3D12ProtectedResourceSession *protected_session,
struct d3d12_resource **resource)
{
@ -2108,7 +2122,7 @@ HRESULT d3d12_committed_resource_create(struct d3d12_device *device,
if (FAILED(hr = vkd3d_allocate_resource_memory(device, object, heap_properties, heap_flags)))
{
d3d12_resource_Release(&object->ID3D12Resource1_iface);
d3d12_resource_Release(&object->ID3D12Resource2_iface);
return hr;
}
@ -2174,7 +2188,7 @@ static HRESULT vkd3d_bind_heap_memory(struct d3d12_device *device,
{
resource->heap = heap;
resource->heap_offset = heap_offset;
InterlockedIncrement(&heap->resource_count);
vkd3d_atomic_increment_u32(&heap->resource_count);
}
else
{
@ -2189,7 +2203,7 @@ allocate_memory:
}
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_RESOURCE_DESC1 *desc, D3D12_RESOURCE_STATES initial_state,
const D3D12_CLEAR_VALUE *optimized_clear_value, struct d3d12_resource **resource)
{
struct d3d12_resource *object;
@ -2201,7 +2215,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->ID3D12Resource1_iface);
d3d12_resource_Release(&object->ID3D12Resource2_iface);
return hr;
}
@ -2213,7 +2227,7 @@ HRESULT d3d12_placed_resource_create(struct d3d12_device *device, struct d3d12_h
}
HRESULT d3d12_reserved_resource_create(struct d3d12_device *device,
const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state,
const D3D12_RESOURCE_DESC1 *desc, D3D12_RESOURCE_STATES initial_state,
const D3D12_CLEAR_VALUE *optimized_clear_value, struct d3d12_resource **resource)
{
struct d3d12_resource *object;
@ -2225,7 +2239,7 @@ HRESULT d3d12_reserved_resource_create(struct d3d12_device *device,
if (!d3d12_resource_init_tiles(object, device))
{
d3d12_resource_Release(&object->ID3D12Resource1_iface);
d3d12_resource_Release(&object->ID3D12Resource2_iface);
return E_OUTOFMEMORY;
}
@ -2239,7 +2253,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_ID3D12Device5((ID3D12Device5 *)device);
struct d3d12_device *d3d12_device = unsafe_impl_from_ID3D12Device7((ID3D12Device7 *)device);
struct d3d12_resource *object;
HRESULT hr;
@ -2260,11 +2274,11 @@ HRESULT vkd3d_create_image_resource(ID3D12Device *device,
memset(object, 0, sizeof(*object));
object->ID3D12Resource1_iface.lpVtbl = &d3d12_resource_vtbl;
object->ID3D12Resource2_iface.lpVtbl = &d3d12_resource_vtbl;
object->refcount = 1;
object->internal_refcount = 1;
object->desc = create_info->desc;
object->format = vkd3d_format_from_d3d12_resource_desc(d3d12_device, &create_info->desc, 0);
d3d12_resource_desc1_from_desc(&object->desc, &create_info->desc);
object->format = vkd3d_format_from_d3d12_resource_desc(d3d12_device, &object->desc, 0);
object->u.vk_image = create_info->vk_image;
object->flags = VKD3D_RESOURCE_EXTERNAL;
object->flags |= create_info->flags & VKD3D_RESOURCE_PUBLIC_FLAGS;
@ -2284,7 +2298,7 @@ HRESULT vkd3d_create_image_resource(ID3D12Device *device,
TRACE("Created resource %p.\n", object);
*resource = (ID3D12Resource *)&object->ID3D12Resource1_iface;
*resource = (ID3D12Resource *)&object->ID3D12Resource2_iface;
return S_OK;
}
@ -2314,14 +2328,14 @@ static void *vkd3d_desc_object_cache_get(struct vkd3d_desc_object_cache *cache)
STATIC_ASSERT(!(ARRAY_SIZE(cache->heads) & HEAD_INDEX_MASK));
i = (vkd3d_atomic_increment(&cache->next_index)) & HEAD_INDEX_MASK;
i = vkd3d_atomic_increment_u32(&cache->next_index) & HEAD_INDEX_MASK;
for (;;)
{
if (vkd3d_atomic_compare_exchange(&cache->heads[i].spinlock, 0, 1))
{
if ((u.object = cache->heads[i].head))
{
vkd3d_atomic_decrement(&cache->free_count);
vkd3d_atomic_decrement_u32(&cache->free_count);
cache->heads[i].head = u.header->next;
vkd3d_atomic_exchange(&cache->heads[i].spinlock, 0);
return u.object;
@ -2345,7 +2359,7 @@ static void vkd3d_desc_object_cache_push(struct vkd3d_desc_object_cache *cache,
/* Using the same index as above may result in a somewhat uneven distribution,
* but the main objective is to avoid costly spinlock contention. */
i = (vkd3d_atomic_increment(&cache->next_index)) & HEAD_INDEX_MASK;
i = vkd3d_atomic_increment_u32(&cache->next_index) & HEAD_INDEX_MASK;
for (;;)
{
if (vkd3d_atomic_compare_exchange(&cache->heads[i].spinlock, 0, 1))
@ -2357,7 +2371,7 @@ static void vkd3d_desc_object_cache_push(struct vkd3d_desc_object_cache *cache,
u.header->next = head;
cache->heads[i].head = u.object;
vkd3d_atomic_exchange(&cache->heads[i].spinlock, 0);
vkd3d_atomic_increment(&cache->free_count);
vkd3d_atomic_increment_u32(&cache->free_count);
}
#undef HEAD_INDEX_MASK
@ -2429,7 +2443,7 @@ void vkd3d_view_decref(void *view, struct d3d12_device *device)
{
union d3d12_desc_object u = {view};
if (vkd3d_atomic_decrement(&u.header->refcount))
if (vkd3d_atomic_decrement_u32(&u.header->refcount))
return;
if (u.header->magic != VKD3D_DESCRIPTOR_MAGIC_CBV)
@ -2470,12 +2484,14 @@ static void d3d12_desc_write_vk_heap_null_descriptor(struct d3d12_descriptor_hea
{
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
struct d3d12_descriptor_heap_vk_set *descriptor_set;
enum vkd3d_vk_descriptor_set_index set;
enum vkd3d_vk_descriptor_set_index set, end;
unsigned int i = writes->count;
end = device->vk_info.EXT_mutable_descriptor_type ? VKD3D_SET_INDEX_UNIFORM_BUFFER
: VKD3D_SET_INDEX_STORAGE_IMAGE;
/* Binding a shader with the wrong null descriptor type works in Windows.
* To support that here we must write one to all applicable Vulkan sets. */
for (set = VKD3D_SET_INDEX_UNIFORM_BUFFER; set <= VKD3D_SET_INDEX_STORAGE_IMAGE; ++set)
for (set = VKD3D_SET_INDEX_UNIFORM_BUFFER; set <= end; ++set)
{
descriptor_set = &descriptor_heap->vk_descriptor_sets[set];
writes->vk_descriptor_writes[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
@ -2632,20 +2648,18 @@ void d3d12_desc_flush_vk_heap_updates_locked(struct d3d12_descriptor_heap *descr
for (; i != UINT_MAX; i = next)
{
src = &descriptors[i];
next = (int)src->next >> 1;
next = vkd3d_atomic_exchange(&src->next, 0);
next = (int)next >> 1;
/* A race exists here between updating src->next and getting the current object. The best
* we can do is get the object last, which may result in a harmless rewrite later. */
u.object = d3d12_desc_get_object_ref(src, device);
if (!u.object)
{
vkd3d_atomic_exchange(&src->next, 0);
continue;
}
writes.held_refs[writes.held_ref_count++] = u.object;
d3d12_desc_write_vk_heap(descriptor_heap, i, &writes, u.object, device);
vkd3d_atomic_exchange(&src->next, 0);
}
/* Avoid thunk calls wherever possible. */
@ -3022,7 +3036,7 @@ static bool init_default_texture_view_desc(struct vkd3d_texture_view_desc *desc,
}
static void vkd3d_texture_view_desc_normalise(struct vkd3d_texture_view_desc *desc,
const D3D12_RESOURCE_DESC *resource_desc)
const D3D12_RESOURCE_DESC1 *resource_desc)
{
unsigned int max_layer_count;
@ -3446,6 +3460,7 @@ static void vkd3d_create_null_uav(struct d3d12_desc *descriptor,
vkd3d_desc.miplevel_count = 1;
vkd3d_desc.layer_idx = 0;
vkd3d_desc.layer_count = 1;
vkd3d_desc.vk_image_aspect = VK_IMAGE_ASPECT_COLOR_BIT;
vkd3d_desc.components.r = VK_COMPONENT_SWIZZLE_R;
vkd3d_desc.components.g = VK_COMPONENT_SWIZZLE_G;
vkd3d_desc.components.b = VK_COMPONENT_SWIZZLE_B;
@ -3663,11 +3678,27 @@ static VkSamplerAddressMode vk_address_mode_from_d3d12(const struct d3d12_device
}
}
static VkBorderColor vk_border_colour_from_d3d12(D3D12_STATIC_BORDER_COLOR colour)
{
switch (colour)
{
case D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK:
return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
case D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK:
return VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
case D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE:
return VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
default:
FIXME("Unhandled border colour %#x.\n", colour);
return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
}
}
static VkResult d3d12_create_sampler(struct d3d12_device *device, D3D12_FILTER filter,
D3D12_TEXTURE_ADDRESS_MODE address_u, D3D12_TEXTURE_ADDRESS_MODE address_v,
D3D12_TEXTURE_ADDRESS_MODE address_w, float mip_lod_bias, unsigned int max_anisotropy,
D3D12_COMPARISON_FUNC comparison_func, float min_lod, float max_lod,
VkSampler *vk_sampler)
D3D12_COMPARISON_FUNC comparison_func, D3D12_STATIC_BORDER_COLOR border_colour,
float min_lod, float max_lod, VkSampler *vk_sampler)
{
const struct vkd3d_vk_device_procs *vk_procs;
struct VkSamplerCreateInfo sampler_desc;
@ -3697,15 +3728,48 @@ static VkResult d3d12_create_sampler(struct d3d12_device *device, D3D12_FILTER f
sampler_desc.maxLod = max_lod;
sampler_desc.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
sampler_desc.unnormalizedCoordinates = VK_FALSE;
if (address_u == D3D12_TEXTURE_ADDRESS_MODE_BORDER || address_v == D3D12_TEXTURE_ADDRESS_MODE_BORDER
|| address_w == D3D12_TEXTURE_ADDRESS_MODE_BORDER)
sampler_desc.borderColor = vk_border_colour_from_d3d12(border_colour);
if ((vr = VK_CALL(vkCreateSampler(device->vk_device, &sampler_desc, NULL, vk_sampler))) < 0)
WARN("Failed to create Vulkan sampler, vr %d.\n", vr);
return vr;
}
static D3D12_STATIC_BORDER_COLOR d3d12_static_border_colour(const float *colour)
{
unsigned int i;
static const struct
{
float colour[4];
D3D12_STATIC_BORDER_COLOR static_colour;
}
colours[] =
{
{{0.0f, 0.0f, 0.0f, 0.0f}, D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK},
{{0.0f, 0.0f, 0.0f, 1.0f}, D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK},
{{1.0f, 1.0f, 1.0f, 1.0f}, D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE},
};
for (i = 0; i < ARRAY_SIZE(colours); ++i)
{
if (!memcmp(colour, colours[i].colour, sizeof(colours[i].colour)))
return colours[i].static_colour;
}
FIXME("Unhandled border colour {%.8e, %.8e, %.8e, %.8e}.\n", colour[0], colour[1], colour[2], colour[3]);
return D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK;
}
void d3d12_desc_create_sampler(struct d3d12_desc *sampler,
struct d3d12_device *device, const D3D12_SAMPLER_DESC *desc)
{
D3D12_STATIC_BORDER_COLOR static_colour = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK;
struct vkd3d_view *view;
if (!desc)
@ -3717,8 +3781,7 @@ void d3d12_desc_create_sampler(struct d3d12_desc *sampler,
if (desc->AddressU == D3D12_TEXTURE_ADDRESS_MODE_BORDER
|| desc->AddressV == D3D12_TEXTURE_ADDRESS_MODE_BORDER
|| desc->AddressW == D3D12_TEXTURE_ADDRESS_MODE_BORDER)
FIXME("Ignoring border color {%.8e, %.8e, %.8e, %.8e}.\n",
desc->BorderColor[0], desc->BorderColor[1], desc->BorderColor[2], desc->BorderColor[3]);
static_colour = d3d12_static_border_colour(desc->BorderColor);
if (!(view = vkd3d_view_create(VKD3D_DESCRIPTOR_MAGIC_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLER,
VKD3D_VIEW_TYPE_SAMPLER, device)))
@ -3726,9 +3789,9 @@ void d3d12_desc_create_sampler(struct d3d12_desc *sampler,
view->v.u.vk_sampler = VK_NULL_HANDLE;
view->v.format = NULL;
if (d3d12_create_sampler(device, desc->Filter, desc->AddressU,
desc->AddressV, desc->AddressW, desc->MipLODBias, desc->MaxAnisotropy,
desc->ComparisonFunc, desc->MinLOD, desc->MaxLOD, &view->v.u.vk_sampler) < 0)
if (d3d12_create_sampler(device, desc->Filter, desc->AddressU, desc->AddressV,
desc->AddressW, desc->MipLODBias, desc->MaxAnisotropy, desc->ComparisonFunc,
static_colour, desc->MinLOD, desc->MaxLOD, &view->v.u.vk_sampler) < 0)
{
vkd3d_view_decref(view, device);
return;
@ -3742,14 +3805,9 @@ HRESULT vkd3d_create_static_sampler(struct d3d12_device *device,
{
VkResult vr;
if (desc->AddressU == D3D12_TEXTURE_ADDRESS_MODE_BORDER
|| desc->AddressV == D3D12_TEXTURE_ADDRESS_MODE_BORDER
|| desc->AddressW == D3D12_TEXTURE_ADDRESS_MODE_BORDER)
FIXME("Ignoring border %#x.\n", desc->BorderColor);
vr = d3d12_create_sampler(device, desc->Filter, desc->AddressU,
desc->AddressV, desc->AddressW, desc->MipLODBias, desc->MaxAnisotropy,
desc->ComparisonFunc, desc->MinLOD, desc->MaxLOD, vk_sampler);
vr = d3d12_create_sampler(device, desc->Filter, desc->AddressU, desc->AddressV,
desc->AddressW, desc->MipLODBias, desc->MaxAnisotropy, desc->ComparisonFunc,
desc->BorderColor, desc->MinLOD, desc->MaxLOD, vk_sampler);
return hresult_from_vk_result(vr);
}
@ -3966,7 +4024,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_descriptor_heap_QueryInterface(ID3D12Desc
static ULONG STDMETHODCALLTYPE d3d12_descriptor_heap_AddRef(ID3D12DescriptorHeap *iface)
{
struct d3d12_descriptor_heap *heap = impl_from_ID3D12DescriptorHeap(iface);
ULONG refcount = InterlockedIncrement(&heap->refcount);
unsigned int refcount = vkd3d_atomic_increment_u32(&heap->refcount);
TRACE("%p increasing refcount to %u.\n", heap, refcount);
@ -3976,7 +4034,7 @@ static ULONG STDMETHODCALLTYPE d3d12_descriptor_heap_AddRef(ID3D12DescriptorHeap
static ULONG STDMETHODCALLTYPE d3d12_descriptor_heap_Release(ID3D12DescriptorHeap *iface)
{
struct d3d12_descriptor_heap *heap = impl_from_ID3D12DescriptorHeap(iface);
ULONG refcount = InterlockedDecrement(&heap->refcount);
unsigned int refcount = vkd3d_atomic_decrement_u32(&heap->refcount);
TRACE("%p decreasing refcount to %u.\n", heap, refcount);
@ -3997,6 +4055,9 @@ static ULONG STDMETHODCALLTYPE d3d12_descriptor_heap_Release(ID3D12DescriptorHea
{
struct d3d12_desc *descriptors = (struct d3d12_desc *)heap->descriptors;
if (heap->use_vk_heaps)
d3d12_device_remove_descriptor_heap(device, heap);
for (i = 0; i < heap->desc.NumDescriptors; ++i)
{
d3d12_desc_destroy(&descriptors[i], device);
@ -4175,9 +4236,11 @@ static HRESULT d3d12_descriptor_heap_create_descriptor_pool(struct d3d12_descrip
for (set = 0, pool_desc.poolSizeCount = 0; set < ARRAY_SIZE(device->vk_descriptor_heap_layouts); ++set)
{
if (device->vk_descriptor_heap_layouts[set].applicable_heap_type == desc->Type)
if (device->vk_descriptor_heap_layouts[set].applicable_heap_type == desc->Type
&& device->vk_descriptor_heap_layouts[set].vk_set_layout)
{
pool_sizes[pool_desc.poolSizeCount].type = device->vk_descriptor_heap_layouts[set].type;
pool_sizes[pool_desc.poolSizeCount].type = (device->vk_info.EXT_mutable_descriptor_type && !set)
? VK_DESCRIPTOR_TYPE_MUTABLE_EXT : device->vk_descriptor_heap_layouts[set].type;
pool_sizes[pool_desc.poolSizeCount++].descriptorCount = desc->NumDescriptors;
}
}
@ -4203,6 +4266,16 @@ static HRESULT d3d12_descriptor_heap_create_descriptor_set(struct d3d12_descript
VkDescriptorSetAllocateInfo set_desc;
VkResult vr;
if (!device->vk_descriptor_heap_layouts[set].vk_set_layout)
{
/* Set 0 uses mutable descriptors, and this set is unused. */
if (!descriptor_heap->vk_descriptor_sets[0].vk_set)
d3d12_descriptor_heap_create_descriptor_set(descriptor_heap, device, 0);
descriptor_set->vk_set = descriptor_heap->vk_descriptor_sets[0].vk_set;
descriptor_set->vk_type = device->vk_descriptor_heap_layouts[set].type;
return S_OK;
}
set_desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
set_desc.pNext = &set_size;
set_desc.descriptorPool = descriptor_heap->vk_descriptor_pool;
@ -4255,7 +4328,7 @@ static HRESULT d3d12_descriptor_heap_init(struct d3d12_descriptor_heap *descript
descriptor_heap->ID3D12DescriptorHeap_iface.lpVtbl = &d3d12_descriptor_heap_vtbl;
descriptor_heap->refcount = 1;
descriptor_heap->serial_id = InterlockedIncrement64(&object_global_serial_id);
descriptor_heap->serial_id = vkd3d_atomic_increment_u64(&object_global_serial_id);
descriptor_heap->desc = *desc;
@ -4320,6 +4393,12 @@ HRESULT d3d12_descriptor_heap_create(struct d3d12_device *device,
dst[i].next = 0;
}
object->dirty_list_head = UINT_MAX;
if (object->use_vk_heaps && FAILED(hr = d3d12_device_add_descriptor_heap(device, object)))
{
vkd3d_free(object);
return hr;
}
}
else
{
@ -4364,7 +4443,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_query_heap_QueryInterface(ID3D12QueryHeap
static ULONG STDMETHODCALLTYPE d3d12_query_heap_AddRef(ID3D12QueryHeap *iface)
{
struct d3d12_query_heap *heap = impl_from_ID3D12QueryHeap(iface);
ULONG refcount = InterlockedIncrement(&heap->refcount);
unsigned int refcount = vkd3d_atomic_increment_u32(&heap->refcount);
TRACE("%p increasing refcount to %u.\n", heap, refcount);
@ -4374,7 +4453,7 @@ static ULONG STDMETHODCALLTYPE d3d12_query_heap_AddRef(ID3D12QueryHeap *iface)
static ULONG STDMETHODCALLTYPE d3d12_query_heap_Release(ID3D12QueryHeap *iface)
{
struct d3d12_query_heap *heap = impl_from_ID3D12QueryHeap(iface);
ULONG refcount = InterlockedDecrement(&heap->refcount);
unsigned int refcount = vkd3d_atomic_decrement_u32(&heap->refcount);
TRACE("%p decreasing refcount to %u.\n", heap, refcount);
@ -4750,7 +4829,7 @@ HRESULT vkd3d_init_null_resources(struct vkd3d_null_resources *null_resources,
{
const bool use_sparse_resources = device->vk_info.sparse_properties.residencyNonResidentStrict;
D3D12_HEAP_PROPERTIES heap_properties;
D3D12_RESOURCE_DESC resource_desc;
D3D12_RESOURCE_DESC1 resource_desc;
HRESULT hr;
TRACE("Creating resources for NULL views.\n");
@ -4775,6 +4854,7 @@ HRESULT vkd3d_init_null_resources(struct vkd3d_null_resources *null_resources,
resource_desc.SampleDesc.Quality = 0;
resource_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
resource_desc.Flags = D3D12_RESOURCE_FLAG_NONE;
memset(&resource_desc.SamplerFeedbackMipRegion, 0, sizeof(resource_desc.SamplerFeedbackMipRegion));
if (FAILED(hr = vkd3d_create_buffer(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
&resource_desc, &null_resources->vk_buffer)))
@ -4858,7 +4938,7 @@ HRESULT vkd3d_init_null_resources(struct vkd3d_null_resources *null_resources,
return vkd3d_init_null_resources_data(null_resources, device);
fail:
ERR("Failed to initialize NULL resources, hr %#x.\n", hr);
ERR("Failed to initialise NULL resources, hr %s.\n", debugstr_hresult(hr));
vkd3d_destroy_null_resources(null_resources, device);
return hr;
}

View file

@ -52,7 +52,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_root_signature_QueryInterface(ID3D12RootS
static ULONG STDMETHODCALLTYPE d3d12_root_signature_AddRef(ID3D12RootSignature *iface)
{
struct d3d12_root_signature *root_signature = impl_from_ID3D12RootSignature(iface);
ULONG refcount = InterlockedIncrement(&root_signature->refcount);
unsigned int refcount = vkd3d_atomic_increment_u32(&root_signature->refcount);
TRACE("%p increasing refcount to %u.\n", root_signature, refcount);
@ -110,7 +110,7 @@ static void d3d12_root_signature_cleanup(struct d3d12_root_signature *root_signa
static ULONG STDMETHODCALLTYPE d3d12_root_signature_Release(ID3D12RootSignature *iface)
{
struct d3d12_root_signature *root_signature = impl_from_ID3D12RootSignature(iface);
ULONG refcount = InterlockedDecrement(&root_signature->refcount);
unsigned int refcount = vkd3d_atomic_decrement_u32(&root_signature->refcount);
TRACE("%p decreasing refcount to %u.\n", root_signature, refcount);
@ -515,7 +515,7 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat
assert(p->ShaderVisibility <= D3D12_SHADER_VISIBILITY_PIXEL);
push_constants[p->ShaderVisibility].stageFlags = use_vk_heaps ? VK_SHADER_STAGE_ALL
: stage_flags_from_visibility(p->ShaderVisibility);
push_constants[p->ShaderVisibility].size += p->u.Constants.Num32BitValues * sizeof(uint32_t);
push_constants[p->ShaderVisibility].size += align(p->u.Constants.Num32BitValues, 4) * sizeof(uint32_t);
}
if (push_constants[D3D12_SHADER_VISIBILITY_ALL].size)
{
@ -564,7 +564,7 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat
idx = push_constant_count == 1 ? 0 : p->ShaderVisibility;
offset = push_constants_offset[idx];
push_constants_offset[idx] += p->u.Constants.Num32BitValues * sizeof(uint32_t);
push_constants_offset[idx] += align(p->u.Constants.Num32BitValues, 4) * sizeof(uint32_t);
root_signature->parameters[i].parameter_type = p->ParameterType;
root_constant->stage_flags = push_constant_count == 1
@ -848,7 +848,20 @@ static void vkd3d_descriptor_heap_binding_from_descriptor_range(const struct d3d
const struct vkd3d_device_descriptor_limits *descriptor_limits = &root_signature->device->vk_info.descriptor_limits;
unsigned int descriptor_set_size;
switch (range->type)
if (root_signature->device->vk_info.EXT_mutable_descriptor_type)
{
if (range->type == VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER)
{
binding->set = VKD3D_SET_INDEX_SAMPLER;
descriptor_set_size = descriptor_limits->sampler_max_descriptors;
}
else
{
binding->set = 0;
descriptor_set_size = descriptor_limits->sampled_image_max_descriptors;
}
}
else switch (range->type)
{
case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV:
binding->set = is_buffer ? VKD3D_SET_INDEX_UNIFORM_TEXEL_BUFFER : VKD3D_SET_INDEX_SAMPLED_IMAGE;
@ -1368,8 +1381,14 @@ static unsigned int d3d12_root_signature_copy_descriptor_set_layouts(const struc
if (device->use_vk_heaps)
{
VkDescriptorSetLayout mutable_layout = device->vk_descriptor_heap_layouts[0].vk_set_layout;
for (set = 0; set < ARRAY_SIZE(device->vk_descriptor_heap_layouts); ++set)
vk_set_layouts[i++] = device->vk_descriptor_heap_layouts[set].vk_set_layout;
{
VkDescriptorSetLayout vk_set_layout = device->vk_descriptor_heap_layouts[set].vk_set_layout;
/* All layouts must be valid, so if null, just set it to the mutable one. */
vk_set_layouts[i++] = vk_set_layout ? vk_set_layout : mutable_layout;
}
}
return i;
@ -1691,7 +1710,7 @@ HRESULT vkd3d_render_pass_cache_find(struct vkd3d_render_pass_cache *cache,
HRESULT hr = S_OK;
unsigned int i;
vkd3d_mutex_lock(&device->mutex);
vkd3d_mutex_lock(&device->pipeline_cache_mutex);
for (i = 0; i < cache->render_pass_count; ++i)
{
@ -1708,7 +1727,7 @@ HRESULT vkd3d_render_pass_cache_find(struct vkd3d_render_pass_cache *cache,
if (!found)
hr = vkd3d_render_pass_cache_create_pass_locked(cache, device, key, vk_render_pass);
vkd3d_mutex_unlock(&device->mutex);
vkd3d_mutex_unlock(&device->pipeline_cache_mutex);
return hr;
}
@ -1965,7 +1984,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_pipeline_state_QueryInterface(ID3D12Pipel
static ULONG STDMETHODCALLTYPE d3d12_pipeline_state_AddRef(ID3D12PipelineState *iface)
{
struct d3d12_pipeline_state *state = impl_from_ID3D12PipelineState(iface);
ULONG refcount = InterlockedIncrement(&state->refcount);
unsigned int refcount = vkd3d_atomic_increment_u32(&state->refcount);
TRACE("%p increasing refcount to %u.\n", state, refcount);
@ -2008,7 +2027,7 @@ static void d3d12_pipeline_uav_counter_state_cleanup(struct d3d12_pipeline_uav_c
static ULONG STDMETHODCALLTYPE d3d12_pipeline_state_Release(ID3D12PipelineState *iface)
{
struct d3d12_pipeline_state *state = impl_from_ID3D12PipelineState(iface);
ULONG refcount = InterlockedDecrement(&state->refcount);
unsigned int refcount = vkd3d_atomic_decrement_u32(&state->refcount);
TRACE("%p decreasing refcount to %u.\n", state, refcount);
@ -2129,6 +2148,18 @@ static inline unsigned int typed_uav_compile_option(const struct d3d12_device *d
: VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV_READ_FORMAT_R32;
}
static unsigned int feature_flags_compile_option(const struct d3d12_device *device)
{
unsigned int flags = 0;
if (device->feature_options1.Int64ShaderOps)
flags |= VKD3D_SHADER_COMPILE_OPTION_FEATURE_INT64;
if (device->feature_options.DoublePrecisionFloatShaderOps)
flags |= VKD3D_SHADER_COMPILE_OPTION_FEATURE_FLOAT64;
return flags;
}
static HRESULT create_shader_stage(struct d3d12_device *device,
struct VkPipelineShaderStageCreateInfo *stage_desc, enum VkShaderStageFlagBits stage,
const D3D12_SHADER_BYTECODE *code, const struct vkd3d_shader_interface_info *shader_interface)
@ -2142,9 +2173,10 @@ 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_10},
{VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_11},
{VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV, typed_uav_compile_option(device)},
{VKD3D_SHADER_COMPILE_OPTION_WRITE_TESS_GEOM_POINT_SIZE, 0},
{VKD3D_SHADER_COMPILE_OPTION_FEATURE, feature_flags_compile_option(device)},
};
stage_desc->sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
@ -2196,7 +2228,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_10},
{VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_11},
{VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV, typed_uav_compile_option(device)},
};
@ -2240,7 +2272,7 @@ static HRESULT vkd3d_create_compute_pipeline(struct d3d12_device *device,
VK_CALL(vkDestroyShaderModule(device->vk_device, pipeline_info.stage.module, NULL));
if (vr < 0)
{
WARN("Failed to create Vulkan compute pipeline, hr %#x.\n", hr);
WARN("Failed to create Vulkan compute pipeline, hr %s.\n", debugstr_hresult(hr));
return hresult_from_vk_result(vr);
}
@ -2368,7 +2400,7 @@ static HRESULT d3d12_pipeline_state_find_and_init_uav_counters(struct d3d12_pipe
}
if (FAILED(hr = d3d12_pipeline_state_init_uav_counters(state, device, root_signature, &shader_info, stage_flags)))
WARN("Failed to create descriptor set layout for UAV counters, hr %#x.\n", hr);
WARN("Failed to create descriptor set layout for UAV counters, hr %s.\n", debugstr_hresult(hr));
vkd3d_shader_free_scan_descriptor_info(&shader_info);
@ -2442,7 +2474,7 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
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);
WARN("Failed to create Vulkan compute pipeline, hr %s.\n", debugstr_hresult(hr));
d3d12_pipeline_uav_counter_state_cleanup(&state->uav_counters, device);
return hr;
}
@ -3615,7 +3647,7 @@ static VkPipeline d3d12_pipeline_state_find_compiled_pipeline(const struct d3d12
*vk_render_pass = VK_NULL_HANDLE;
vkd3d_mutex_lock(&device->mutex);
vkd3d_mutex_lock(&device->pipeline_cache_mutex);
LIST_FOR_EACH_ENTRY(current, &graphics->compiled_pipelines, struct vkd3d_compiled_pipeline, entry)
{
@ -3627,7 +3659,7 @@ static VkPipeline d3d12_pipeline_state_find_compiled_pipeline(const struct d3d12
}
}
vkd3d_mutex_unlock(&device->mutex);
vkd3d_mutex_unlock(&device->pipeline_cache_mutex);
return vk_pipeline;
}
@ -3646,7 +3678,7 @@ static bool d3d12_pipeline_state_put_pipeline_to_cache(struct d3d12_pipeline_sta
compiled_pipeline->vk_pipeline = vk_pipeline;
compiled_pipeline->vk_render_pass = vk_render_pass;
vkd3d_mutex_lock(&device->mutex);
vkd3d_mutex_lock(&device->pipeline_cache_mutex);
LIST_FOR_EACH_ENTRY(current, &graphics->compiled_pipelines, struct vkd3d_compiled_pipeline, entry)
{
@ -3661,7 +3693,7 @@ static bool d3d12_pipeline_state_put_pipeline_to_cache(struct d3d12_pipeline_sta
if (compiled_pipeline)
list_add_tail(&graphics->compiled_pipelines, &compiled_pipeline->entry);
vkd3d_mutex_unlock(&device->mutex);
vkd3d_mutex_unlock(&device->pipeline_cache_mutex);
return compiled_pipeline;
}
@ -3855,7 +3887,7 @@ static int compile_hlsl_cs(const struct vkd3d_shader_code *hlsl, struct vkd3d_sh
static const struct vkd3d_shader_compile_option options[] =
{
{VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_10},
{VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_11},
};
info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO;
@ -3996,14 +4028,14 @@ HRESULT vkd3d_uav_clear_state_init(struct vkd3d_uav_clear_state *state, struct d
if (FAILED(hr = vkd3d_create_descriptor_set_layout(device, 0,
1, false, &set_binding, set_layouts[i].set_layout)))
{
ERR("Failed to create descriptor set layout %u, hr %#x.\n", i, hr);
ERR("Failed to create descriptor set layout %u, hr %s.\n", i, debugstr_hresult(hr));
goto fail;
}
if (FAILED(hr = vkd3d_create_pipeline_layout(device, 1, set_layouts[i].set_layout,
1, &push_constant_range, set_layouts[i].pipeline_layout)))
{
ERR("Failed to create pipeline layout %u, hr %#x.\n", i, hr);
ERR("Failed to create pipeline layout %u, hr %s.\n", i, debugstr_hresult(hr));
goto fail;
}
}
@ -4041,7 +4073,7 @@ HRESULT vkd3d_uav_clear_state_init(struct vkd3d_uav_clear_state *state, struct d
vkd3d_shader_free_shader_code(&dxbc);
if (FAILED(hr))
{
ERR("Failed to create compute pipeline %u, hr %#x.\n", i, hr);
ERR("Failed to create compute pipeline %u, hr %s.\n", i, debugstr_hresult(hr));
goto fail;
}
}

View file

@ -539,6 +539,7 @@ bool is_valid_feature_level(D3D_FEATURE_LEVEL feature_level)
{
static const D3D_FEATURE_LEVEL valid_feature_levels[] =
{
D3D_FEATURE_LEVEL_12_2,
D3D_FEATURE_LEVEL_12_1,
D3D_FEATURE_LEVEL_12_0,
D3D_FEATURE_LEVEL_11_1,
@ -548,6 +549,7 @@ bool is_valid_feature_level(D3D_FEATURE_LEVEL feature_level)
D3D_FEATURE_LEVEL_9_3,
D3D_FEATURE_LEVEL_9_2,
D3D_FEATURE_LEVEL_9_1,
D3D_FEATURE_LEVEL_1_0_CORE,
};
unsigned int i;
@ -630,6 +632,11 @@ HRESULT return_interface(void *iface, REFIID iface_iid,
return hr;
}
const char *debug_cpu_handle(D3D12_CPU_DESCRIPTOR_HANDLE handle)
{
return vkd3d_dbg_sprintf("{%#"PRIxPTR"}", (uintptr_t)handle.ptr);
}
const char *debug_d3d12_box(const D3D12_BOX *box)
{
if (!box)
@ -671,6 +678,11 @@ const char *debug_d3d12_shader_component_mapping(unsigned int mapping)
debug_d3d12_shader_component(D3D12_DECODE_SHADER_4_COMPONENT_MAPPING(3, mapping)));
}
const char *debug_gpu_handle(D3D12_GPU_DESCRIPTOR_HANDLE handle)
{
return vkd3d_dbg_sprintf("{%#"PRIx64"}", handle.ptr);
}
const char *debug_vk_extent_3d(VkExtent3D extent)
{
return vkd3d_dbg_sprintf("(%u, %u, %u)",
@ -681,7 +693,7 @@ const char *debug_vk_extent_3d(VkExtent3D extent)
const char *debug_vk_queue_flags(VkQueueFlags flags)
{
char buffer[120];
char buffer[159];
buffer[0] = '\0';
#define FLAG_TO_STR(f) if (flags & f) { strcat(buffer, " | "#f); flags &= ~f; }
@ -689,6 +701,10 @@ const char *debug_vk_queue_flags(VkQueueFlags flags)
FLAG_TO_STR(VK_QUEUE_COMPUTE_BIT)
FLAG_TO_STR(VK_QUEUE_TRANSFER_BIT)
FLAG_TO_STR(VK_QUEUE_SPARSE_BINDING_BIT)
FLAG_TO_STR(VK_QUEUE_PROTECTED_BIT)
#undef FLAG_TO_STR
#define FLAG_TO_STR(f, n) if (flags & f) { strcat(buffer, " | "#n); flags &= ~f; }
FLAG_TO_STR(0x20, VK_QUEUE_VIDEO_DECODE_BIT_KHR)
#undef FLAG_TO_STR
if (flags)
FIXME("Unrecognized flag(s) %#x.\n", flags);
@ -727,10 +743,8 @@ const char *debug_vk_memory_property_flags(VkMemoryPropertyFlags flags)
FLAG_TO_STR(VK_MEMORY_PROPERTY_HOST_CACHED_BIT)
FLAG_TO_STR(VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)
FLAG_TO_STR(VK_MEMORY_PROPERTY_PROTECTED_BIT)
#undef FLAG_TO_STR
#define FLAG_TO_STR(f, n) if (flags & f) { strcat(buffer, " | "#n); flags &= ~f; }
FLAG_TO_STR(0x40, VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD)
FLAG_TO_STR(0x80, VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD)
FLAG_TO_STR(VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD)
FLAG_TO_STR(VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD)
#undef FLAG_TO_STR
if (flags)
FIXME("Unrecognized flag(s) %#x.\n", flags);

View file

@ -60,7 +60,7 @@ HRESULT vkd3d_create_device(const struct vkd3d_device_create_info *create_info,
}
else if (FAILED(hr = vkd3d_create_instance(create_info->instance_create_info, &instance)))
{
WARN("Failed to create instance, hr %#x.\n", hr);
WARN("Failed to create instance, hr %s.\n", debugstr_hresult(hr));
return E_FAIL;
}
@ -71,18 +71,18 @@ HRESULT vkd3d_create_device(const struct vkd3d_device_create_info *create_info,
if (!device)
{
ID3D12Device_Release(&object->ID3D12Device5_iface);
ID3D12Device_Release(&object->ID3D12Device7_iface);
return S_FALSE;
}
return return_interface(&object->ID3D12Device5_iface, &IID_ID3D12Device, iid, device);
return return_interface(&object->ID3D12Device7_iface, &IID_ID3D12Device, iid, device);
}
/* ID3D12RootSignatureDeserializer */
struct d3d12_root_signature_deserializer
{
ID3D12RootSignatureDeserializer ID3D12RootSignatureDeserializer_iface;
LONG refcount;
unsigned int refcount;
union
{
@ -123,7 +123,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_root_signature_deserializer_QueryInterfac
static ULONG STDMETHODCALLTYPE d3d12_root_signature_deserializer_AddRef(ID3D12RootSignatureDeserializer *iface)
{
struct d3d12_root_signature_deserializer *deserializer = impl_from_ID3D12RootSignatureDeserializer(iface);
ULONG refcount = InterlockedIncrement(&deserializer->refcount);
unsigned int refcount = vkd3d_atomic_increment_u32(&deserializer->refcount);
TRACE("%p increasing refcount to %u.\n", deserializer, refcount);
@ -133,7 +133,7 @@ static ULONG STDMETHODCALLTYPE d3d12_root_signature_deserializer_AddRef(ID3D12Ro
static ULONG STDMETHODCALLTYPE d3d12_root_signature_deserializer_Release(ID3D12RootSignatureDeserializer *iface)
{
struct d3d12_root_signature_deserializer *deserializer = impl_from_ID3D12RootSignatureDeserializer(iface);
ULONG refcount = InterlockedDecrement(&deserializer->refcount);
unsigned int refcount = vkd3d_atomic_decrement_u32(&deserializer->refcount);
TRACE("%p decreasing refcount to %u.\n", deserializer, refcount);
@ -222,8 +222,8 @@ HRESULT vkd3d_create_root_signature_deserializer(const void *data, SIZE_T data_s
struct d3d12_root_signature_deserializer *object;
HRESULT hr;
TRACE("data %p, data_size %lu, iid %s, deserializer %p.\n",
data, data_size, debugstr_guid(iid), deserializer);
TRACE("data %p, data_size %"PRIuPTR", iid %s, deserializer %p.\n",
data, (uintptr_t)data_size, debugstr_guid(iid), deserializer);
if (!(object = vkd3d_malloc(sizeof(*object))))
return E_OUTOFMEMORY;
@ -242,7 +242,7 @@ HRESULT vkd3d_create_root_signature_deserializer(const void *data, SIZE_T data_s
struct d3d12_versioned_root_signature_deserializer
{
ID3D12VersionedRootSignatureDeserializer ID3D12VersionedRootSignatureDeserializer_iface;
LONG refcount;
unsigned int refcount;
union
{
@ -284,7 +284,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_versioned_root_signature_deserializer_Que
static ULONG STDMETHODCALLTYPE d3d12_versioned_root_signature_deserializer_AddRef(ID3D12VersionedRootSignatureDeserializer *iface)
{
struct d3d12_versioned_root_signature_deserializer *deserializer = impl_from_ID3D12VersionedRootSignatureDeserializer(iface);
ULONG refcount = InterlockedIncrement(&deserializer->refcount);
unsigned int refcount = vkd3d_atomic_increment_u32(&deserializer->refcount);
TRACE("%p increasing refcount to %u.\n", deserializer, refcount);
@ -294,7 +294,7 @@ static ULONG STDMETHODCALLTYPE d3d12_versioned_root_signature_deserializer_AddRe
static ULONG STDMETHODCALLTYPE d3d12_versioned_root_signature_deserializer_Release(ID3D12VersionedRootSignatureDeserializer *iface)
{
struct d3d12_versioned_root_signature_deserializer *deserializer = impl_from_ID3D12VersionedRootSignatureDeserializer(iface);
ULONG refcount = InterlockedDecrement(&deserializer->refcount);
unsigned int refcount = vkd3d_atomic_decrement_u32(&deserializer->refcount);
TRACE("%p decreasing refcount to %u.\n", deserializer, refcount);
@ -406,8 +406,8 @@ HRESULT vkd3d_create_versioned_root_signature_deserializer(const void *data, SIZ
struct vkd3d_shader_code dxbc = {data, data_size};
HRESULT hr;
TRACE("data %p, data_size %lu, iid %s, deserializer %p.\n",
data, data_size, debugstr_guid(iid), deserializer);
TRACE("data %p, data_size %"PRIuPTR", iid %s, deserializer %p.\n",
data, (uintptr_t)data_size, debugstr_guid(iid), deserializer);
if (!(object = vkd3d_malloc(sizeof(*object))))
return E_OUTOFMEMORY;
@ -456,7 +456,7 @@ HRESULT vkd3d_serialize_root_signature(const D3D12_ROOT_SIGNATURE_DESC *desc,
if (error_blob && messages)
{
if (FAILED(hr = vkd3d_blob_create(messages, strlen(messages), error_blob)))
ERR("Failed to create error blob, hr %#x.\n", hr);
ERR("Failed to create error blob, hr %s.\n", debugstr_hresult(hr));
}
return hresult_from_vkd3d_result(ret);
}
@ -464,7 +464,7 @@ HRESULT vkd3d_serialize_root_signature(const D3D12_ROOT_SIGNATURE_DESC *desc,
if (FAILED(hr = vkd3d_blob_create((void *)dxbc.code, dxbc.size, blob)))
{
WARN("Failed to create blob object, hr %#x.\n", hr);
WARN("Failed to create blob object, hr %s.\n", debugstr_hresult(hr));
vkd3d_shader_free_shader_code(&dxbc);
}
return hr;
@ -497,7 +497,7 @@ HRESULT vkd3d_serialize_versioned_root_signature(const D3D12_VERSIONED_ROOT_SIGN
if (error_blob && messages)
{
if (FAILED(hr = vkd3d_blob_create(messages, strlen(messages), error_blob)))
ERR("Failed to create error blob, hr %#x.\n", hr);
ERR("Failed to create error blob, hr %s.\n", debugstr_hresult(hr));
}
return hresult_from_vkd3d_result(ret);
}
@ -505,7 +505,7 @@ HRESULT vkd3d_serialize_versioned_root_signature(const D3D12_VERSIONED_ROOT_SIGN
if (FAILED(hr = vkd3d_blob_create((void *)dxbc.code, dxbc.size, blob)))
{
WARN("Failed to create blob object, hr %#x.\n", hr);
WARN("Failed to create blob object, hr %s.\n", debugstr_hresult(hr));
vkd3d_shader_free_shader_code(&dxbc);
}
return hr;

View file

@ -55,7 +55,7 @@
#define VKD3D_MAX_COMPATIBLE_FORMAT_COUNT 6u
#define VKD3D_MAX_QUEUE_FAMILY_COUNT 3u
#define VKD3D_MAX_SHADER_EXTENSIONS 3u
#define VKD3D_MAX_SHADER_EXTENSIONS 4u
#define VKD3D_MAX_SHADER_STAGES 5u
#define VKD3D_MAX_VK_SYNC_OBJECTS 4u
#define VKD3D_MAX_DEVICE_BLOCKED_QUEUES 16u
@ -67,7 +67,7 @@
* this number to prevent excessive pool memory use. */
#define VKD3D_MAX_VIRTUAL_HEAP_DESCRIPTORS_PER_TYPE (16 * 1024u)
extern LONG64 object_global_serial_id;
extern uint64_t object_global_serial_id;
struct d3d12_command_list;
struct d3d12_device;
@ -133,9 +133,11 @@ struct vkd3d_vulkan_info
bool EXT_debug_marker;
bool EXT_depth_clip_enable;
bool EXT_descriptor_indexing;
bool EXT_mutable_descriptor_type;
bool EXT_robustness2;
bool EXT_shader_demote_to_helper_invocation;
bool EXT_shader_stencil_export;
bool EXT_shader_viewport_index_layer;
bool EXT_texel_buffer_alignment;
bool EXT_transform_feedback;
bool EXT_vertex_attribute_divisor;
@ -190,7 +192,7 @@ struct vkd3d_instance
uint64_t host_ticks_per_second;
LONG refcount;
unsigned int refcount;
};
#ifdef _WIN32
@ -248,23 +250,13 @@ static inline void vkd3d_cond_broadcast(struct vkd3d_cond *cond)
static inline void vkd3d_cond_wait(struct vkd3d_cond *cond, struct vkd3d_mutex *lock)
{
if (!SleepConditionVariableCS(&cond->cond, &lock->lock, INFINITE))
ERR("Could not sleep on the condition variable, error %u.\n", GetLastError());
ERR("Could not sleep on the condition variable, error %lu.\n", GetLastError());
}
static inline void vkd3d_cond_destroy(struct vkd3d_cond *cond)
{
}
static inline unsigned int vkd3d_atomic_increment(unsigned int volatile *x)
{
return InterlockedIncrement((LONG volatile *)x);
}
static inline unsigned int vkd3d_atomic_decrement(unsigned int volatile *x)
{
return InterlockedDecrement((LONG volatile *)x);
}
static inline bool vkd3d_atomic_compare_exchange(unsigned int volatile *x, unsigned int cmp, unsigned int xchg)
{
return InterlockedCompareExchange((LONG volatile *)x, xchg, cmp) == cmp;
@ -387,24 +379,6 @@ static inline void vkd3d_cond_destroy(struct vkd3d_cond *cond)
ERR("Could not destroy the condition variable, error %d.\n", ret);
}
# if HAVE_SYNC_SUB_AND_FETCH
static inline unsigned int vkd3d_atomic_decrement(unsigned int volatile *x)
{
return __sync_sub_and_fetch(x, 1);
}
# else
# error "vkd3d_atomic_decrement() not implemented for this platform"
# endif /* HAVE_SYNC_SUB_AND_FETCH */
# if HAVE_SYNC_ADD_AND_FETCH
static inline unsigned int vkd3d_atomic_increment(unsigned int volatile *x)
{
return __sync_add_and_fetch(x, 1);
}
# else
# error "vkd3d_atomic_increment() not implemented for this platform"
# endif /* HAVE_SYNC_ADD_AND_FETCH */
# if HAVE_SYNC_BOOL_COMPARE_AND_SWAP
static inline bool vkd3d_atomic_compare_exchange(unsigned int volatile *x, unsigned int cmp, unsigned int xchg)
{
@ -491,13 +465,13 @@ struct vkd3d_fence_worker
struct vkd3d_gpu_va_allocation
{
D3D12_GPU_VIRTUAL_ADDRESS base;
size_t size;
uint64_t size;
void *ptr;
};
struct vkd3d_gpu_va_slab
{
size_t size;
uint64_t size;
void *ptr;
};
@ -515,7 +489,7 @@ struct vkd3d_gpu_va_allocator
};
D3D12_GPU_VIRTUAL_ADDRESS vkd3d_gpu_va_allocator_allocate(struct vkd3d_gpu_va_allocator *allocator,
size_t alignment, size_t size, void *ptr);
size_t alignment, uint64_t size, void *ptr);
void *vkd3d_gpu_va_allocator_dereference(struct vkd3d_gpu_va_allocator *allocator, D3D12_GPU_VIRTUAL_ADDRESS address);
void vkd3d_gpu_va_allocator_free(struct vkd3d_gpu_va_allocator *allocator, D3D12_GPU_VIRTUAL_ADDRESS address);
@ -619,8 +593,8 @@ struct vkd3d_signaled_semaphore
struct d3d12_fence
{
ID3D12Fence1 ID3D12Fence1_iface;
LONG internal_refcount;
LONG refcount;
unsigned int internal_refcount;
unsigned int refcount;
D3D12_FENCE_FLAGS flags;
@ -663,8 +637,8 @@ VkResult vkd3d_create_timeline_semaphore(const struct d3d12_device *device, uint
struct d3d12_heap
{
ID3D12Heap ID3D12Heap_iface;
LONG refcount;
LONG resource_count;
unsigned int refcount;
unsigned int resource_count;
bool is_private;
D3D12_HEAP_DESC desc;
@ -718,11 +692,11 @@ struct d3d12_resource_tile_info
/* ID3D12Resource */
struct d3d12_resource
{
ID3D12Resource1 ID3D12Resource1_iface;
LONG refcount;
LONG internal_refcount;
ID3D12Resource2 ID3D12Resource2_iface;
unsigned int refcount;
unsigned int internal_refcount;
D3D12_RESOURCE_DESC desc;
D3D12_RESOURCE_DESC1 desc;
const struct vkd3d_format *format;
D3D12_GPU_VIRTUAL_ADDRESS gpu_address;
@ -750,12 +724,12 @@ struct d3d12_resource
static inline struct d3d12_resource *impl_from_ID3D12Resource(ID3D12Resource *iface)
{
return CONTAINING_RECORD(iface, struct d3d12_resource, ID3D12Resource1_iface);
return CONTAINING_RECORD(iface, struct d3d12_resource, ID3D12Resource2_iface);
}
static inline struct d3d12_resource *impl_from_ID3D12Resource1(ID3D12Resource1 *iface)
static inline struct d3d12_resource *impl_from_ID3D12Resource2(ID3D12Resource2 *iface)
{
return CONTAINING_RECORD(iface, struct d3d12_resource, ID3D12Resource1_iface);
return CONTAINING_RECORD(iface, struct d3d12_resource, ID3D12Resource2_iface);
}
static inline bool d3d12_resource_is_buffer(const struct d3d12_resource *resource)
@ -768,8 +742,15 @@ static inline bool d3d12_resource_is_texture(const struct d3d12_resource *resour
return resource->desc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER;
}
struct vkd3d_resource_allocation_info
{
uint64_t offset;
uint64_t alignment;
uint64_t size_in_bytes;
};
bool d3d12_resource_is_cpu_accessible(const struct d3d12_resource *resource);
HRESULT d3d12_resource_validate_desc(const D3D12_RESOURCE_DESC *desc, struct d3d12_device *device);
HRESULT d3d12_resource_validate_desc(const D3D12_RESOURCE_DESC1 *desc, struct d3d12_device *device);
void d3d12_resource_get_tiling(struct d3d12_device *device, const struct d3d12_resource *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,
@ -777,25 +758,33 @@ 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_RESOURCE_DESC1 *desc, D3D12_RESOURCE_STATES initial_state,
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_RESOURCE_DESC1 *desc, D3D12_RESOURCE_STATES initial_state,
const D3D12_CLEAR_VALUE *optimized_clear_value, struct d3d12_resource **resource);
HRESULT d3d12_reserved_resource_create(struct d3d12_device *device,
const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state,
const D3D12_RESOURCE_DESC1 *desc, D3D12_RESOURCE_STATES initial_state,
const D3D12_CLEAR_VALUE *optimized_clear_value, struct d3d12_resource **resource);
struct d3d12_resource *unsafe_impl_from_ID3D12Resource(ID3D12Resource *iface);
static inline void d3d12_resource_desc1_from_desc(D3D12_RESOURCE_DESC1 *desc1, const D3D12_RESOURCE_DESC *desc)
{
memcpy(desc1, desc, sizeof(*desc));
desc1->SamplerFeedbackMipRegion.Width = 0;
desc1->SamplerFeedbackMipRegion.Height = 0;
desc1->SamplerFeedbackMipRegion.Depth = 0;
}
HRESULT vkd3d_allocate_buffer_memory(struct d3d12_device *device, VkBuffer vk_buffer,
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,
VkDeviceMemory *vk_memory, uint32_t *vk_memory_type, VkDeviceSize *vk_memory_size);
HRESULT vkd3d_create_buffer(struct d3d12_device *device,
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,
const D3D12_RESOURCE_DESC *desc, VkBuffer *vk_buffer);
const D3D12_RESOURCE_DESC1 *desc, VkBuffer *vk_buffer);
HRESULT vkd3d_get_image_allocation_info(struct d3d12_device *device,
const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_ALLOCATION_INFO *allocation_info);
const D3D12_RESOURCE_DESC1 *desc, struct vkd3d_resource_allocation_info *allocation_info);
enum vkd3d_view_type
{
@ -1044,7 +1033,7 @@ struct d3d12_descriptor_heap_vk_set
struct d3d12_descriptor_heap
{
ID3D12DescriptorHeap ID3D12DescriptorHeap_iface;
LONG refcount;
unsigned int refcount;
uint64_t serial_id;
D3D12_DESCRIPTOR_HEAP_DESC desc;
@ -1083,7 +1072,7 @@ HRESULT d3d12_descriptor_heap_create(struct d3d12_device *device,
struct d3d12_query_heap
{
ID3D12QueryHeap ID3D12QueryHeap_iface;
LONG refcount;
unsigned int refcount;
VkQueryPool vk_query_pool;
@ -1170,7 +1159,7 @@ struct d3d12_descriptor_set_layout
struct d3d12_root_signature
{
ID3D12RootSignature ID3D12RootSignature_iface;
LONG refcount;
unsigned int refcount;
VkPipelineLayout vk_pipeline_layout;
struct d3d12_descriptor_set_layout descriptor_set_layouts[VKD3D_MAX_DESCRIPTOR_SETS];
@ -1279,7 +1268,7 @@ struct d3d12_pipeline_uav_counter_state
struct d3d12_pipeline_state
{
ID3D12PipelineState ID3D12PipelineState_iface;
LONG refcount;
unsigned int refcount;
union
{
@ -1363,7 +1352,7 @@ struct vkd3d_buffer
struct d3d12_command_allocator
{
ID3D12CommandAllocator ID3D12CommandAllocator_iface;
LONG refcount;
unsigned int refcount;
D3D12_COMMAND_LIST_TYPE type;
VkQueueFlags vk_queue_flags;
@ -1464,7 +1453,7 @@ enum vkd3d_pipeline_bind_point
struct d3d12_command_list
{
ID3D12GraphicsCommandList5 ID3D12GraphicsCommandList5_iface;
LONG refcount;
unsigned int refcount;
D3D12_COMMAND_LIST_TYPE type;
VkQueueFlags vk_queue_flags;
@ -1620,7 +1609,7 @@ struct d3d12_command_queue_op_array
struct d3d12_command_queue
{
ID3D12CommandQueue ID3D12CommandQueue_iface;
LONG refcount;
unsigned int refcount;
D3D12_COMMAND_QUEUE_DESC desc;
@ -1655,7 +1644,7 @@ HRESULT d3d12_command_queue_create(struct d3d12_device *device,
struct d3d12_command_signature
{
ID3D12CommandSignature ID3D12CommandSignature_iface;
LONG refcount;
unsigned int refcount;
unsigned int internal_refcount;
D3D12_COMMAND_SIGNATURE_DESC desc;
@ -1746,8 +1735,8 @@ struct vkd3d_desc_object_cache
/* ID3D12Device */
struct d3d12_device
{
ID3D12Device5 ID3D12Device5_iface;
LONG refcount;
ID3D12Device7 ID3D12Device7_iface;
unsigned int refcount;
VkDevice vk_device;
VkPhysicalDevice vk_physical_device;
@ -1757,9 +1746,23 @@ struct d3d12_device
struct vkd3d_gpu_va_allocator gpu_va_allocator;
struct vkd3d_mutex mutex;
struct vkd3d_desc_object_cache view_desc_cache;
struct vkd3d_desc_object_cache cbuffer_desc_cache;
VkDescriptorPoolSize vk_pool_sizes[VKD3D_DESCRIPTOR_POOL_COUNT];
unsigned int vk_pool_count;
struct vkd3d_vk_descriptor_heap_layout vk_descriptor_heap_layouts[VKD3D_SET_INDEX_COUNT];
bool use_vk_heaps;
struct d3d12_descriptor_heap **heaps;
size_t heap_capacity;
size_t heap_count;
union vkd3d_thread_handle worker_thread;
struct vkd3d_mutex worker_mutex;
struct vkd3d_cond worker_cond;
bool worker_should_exit;
struct vkd3d_mutex pipeline_cache_mutex;
struct vkd3d_render_pass_cache render_pass_cache;
VkPipelineCache vk_pipeline_cache;
@ -1799,11 +1802,6 @@ struct d3d12_device
const struct vkd3d_format_compatibility_list *format_compatibility_lists;
struct vkd3d_null_resources null_resources;
struct vkd3d_uav_clear_state uav_clear_state;
VkDescriptorPoolSize vk_pool_sizes[VKD3D_DESCRIPTOR_POOL_COUNT];
unsigned int vk_pool_count;
struct vkd3d_vk_descriptor_heap_layout vk_descriptor_heap_layouts[VKD3D_SET_INDEX_COUNT];
bool use_vk_heaps;
};
HRESULT d3d12_device_create(struct vkd3d_instance *instance,
@ -1812,27 +1810,29 @@ 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_ID3D12Device5(ID3D12Device5 *iface);
struct d3d12_device *unsafe_impl_from_ID3D12Device7(ID3D12Device7 *iface);
HRESULT d3d12_device_add_descriptor_heap(struct d3d12_device *device, struct d3d12_descriptor_heap *heap);
void d3d12_device_remove_descriptor_heap(struct d3d12_device *device, struct d3d12_descriptor_heap *heap);
static inline HRESULT d3d12_device_query_interface(struct d3d12_device *device, REFIID iid, void **object)
{
return ID3D12Device5_QueryInterface(&device->ID3D12Device5_iface, iid, object);
return ID3D12Device7_QueryInterface(&device->ID3D12Device7_iface, iid, object);
}
static inline ULONG d3d12_device_add_ref(struct d3d12_device *device)
{
return ID3D12Device5_AddRef(&device->ID3D12Device5_iface);
return ID3D12Device7_AddRef(&device->ID3D12Device7_iface);
}
static inline ULONG d3d12_device_release(struct d3d12_device *device)
{
return ID3D12Device5_Release(&device->ID3D12Device5_iface);
return ID3D12Device7_Release(&device->ID3D12Device7_iface);
}
static inline unsigned int d3d12_device_get_descriptor_handle_increment_size(struct d3d12_device *device,
D3D12_DESCRIPTOR_HEAP_TYPE descriptor_type)
{
return ID3D12Device5_GetDescriptorHandleIncrementSize(&device->ID3D12Device5_iface, descriptor_type);
return ID3D12Device7_GetDescriptorHandleIncrementSize(&device->ID3D12Device7_iface, descriptor_type);
}
/* utils */
@ -1884,7 +1884,7 @@ HRESULT vkd3d_init_format_info(struct d3d12_device *device);
void vkd3d_cleanup_format_info(struct d3d12_device *device);
static inline const struct vkd3d_format *vkd3d_format_from_d3d12_resource_desc(
const struct d3d12_device *device, const D3D12_RESOURCE_DESC *desc, DXGI_FORMAT view_format)
const struct d3d12_device *device, const D3D12_RESOURCE_DESC1 *desc, DXGI_FORMAT view_format)
{
return vkd3d_get_format(device, view_format ? view_format : desc->Format,
desc->Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL);
@ -1895,31 +1895,31 @@ static inline bool d3d12_box_is_empty(const D3D12_BOX *box)
return box->right <= box->left || box->bottom <= box->top || box->back <= box->front;
}
static inline unsigned int d3d12_resource_desc_get_width(const D3D12_RESOURCE_DESC *desc,
static inline unsigned int d3d12_resource_desc_get_width(const D3D12_RESOURCE_DESC1 *desc,
unsigned int miplevel_idx)
{
return max(1, desc->Width >> miplevel_idx);
}
static inline unsigned int d3d12_resource_desc_get_height(const D3D12_RESOURCE_DESC *desc,
static inline unsigned int d3d12_resource_desc_get_height(const D3D12_RESOURCE_DESC1 *desc,
unsigned int miplevel_idx)
{
return max(1, desc->Height >> miplevel_idx);
}
static inline unsigned int d3d12_resource_desc_get_depth(const D3D12_RESOURCE_DESC *desc,
static inline unsigned int d3d12_resource_desc_get_depth(const D3D12_RESOURCE_DESC1 *desc,
unsigned int miplevel_idx)
{
unsigned int d = desc->Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D ? 1 : desc->DepthOrArraySize;
return max(1, d >> miplevel_idx);
}
static inline unsigned int d3d12_resource_desc_get_layer_count(const D3D12_RESOURCE_DESC *desc)
static inline unsigned int d3d12_resource_desc_get_layer_count(const D3D12_RESOURCE_DESC1 *desc)
{
return desc->Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D ? desc->DepthOrArraySize : 1;
}
static inline unsigned int d3d12_resource_desc_get_sub_resource_count(const D3D12_RESOURCE_DESC *desc)
static inline unsigned int d3d12_resource_desc_get_sub_resource_count(const D3D12_RESOURCE_DESC1 *desc)
{
return d3d12_resource_desc_get_layer_count(desc) * desc->MipLevels;
}
@ -1940,8 +1940,10 @@ bool is_write_resource_state(D3D12_RESOURCE_STATES state);
HRESULT return_interface(void *iface, REFIID iface_iid, REFIID requested_iid, void **object);
const char *debug_cpu_handle(D3D12_CPU_DESCRIPTOR_HANDLE handle);
const char *debug_d3d12_box(const D3D12_BOX *box);
const char *debug_d3d12_shader_component_mapping(unsigned int mapping);
const char *debug_gpu_handle(D3D12_GPU_DESCRIPTOR_HANDLE handle);
const char *debug_vk_extent_3d(VkExtent3D extent);
const char *debug_vk_memory_heap_flags(VkMemoryHeapFlags flags);
const char *debug_vk_memory_property_flags(VkMemoryPropertyFlags flags);