vkd3d: Import upstream release 1.13.

This commit is contained in:
Alexandre Julliard 2024-08-29 21:17:45 +02:00
parent 566f0348cc
commit c83e0af9fd
Notes: Alexandre Julliard 2024-09-02 22:56:28 +02:00
Approved-by: Alexandre Julliard (@julliard)
Approved-by: Matteo Bruni (@Mystral)
Merge-Request: https://gitlab.winehq.org/wine/wine/merge_requests/6409
39 changed files with 7077 additions and 2237 deletions

View file

@ -9907,7 +9907,6 @@ static void test_effect_compiler(void)
hr = ID3D10Effect_GetDesc(effect, &desc);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
ok(desc.Techniques == 1, "Unexpected technique count %u.\n", desc.Techniques);
todo_wine
ok(desc.ConstantBuffers == 1, "Unexpected buffer count %u.\n", desc.ConstantBuffers);
cb = effect->lpVtbl->GetConstantBufferByIndex(effect, 0);
@ -9928,7 +9927,6 @@ static void test_effect_compiler(void)
hr = ID3D10Effect_GetDesc(effect, &desc);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
ok(desc.Techniques == 1, "Unexpected technique count %u.\n", desc.Techniques);
todo_wine
ok(desc.ConstantBuffers == 3, "Unexpected buffer count %u.\n", desc.ConstantBuffers);
cb = effect->lpVtbl->GetConstantBufferByIndex(effect, 0);

View file

@ -1066,7 +1066,6 @@ static void test_compile_effect(void)
hr = D3D10CompileEffectFromMemory(default_bs_source, strlen(default_bs_source),
NULL, NULL, NULL, 0, 0, &blob, NULL);
todo_wine
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
if (SUCCEEDED(hr))
ID3D10Blob_Release(blob);

View file

@ -702,7 +702,6 @@ static void test_trig(void)
return;
device = test_context.device;
todo_wine
ps_code = compile_shader(ps_source, "ps_2_0", 0);
if (ps_code)
{
@ -714,7 +713,6 @@ static void test_trig(void)
float expect_x = (sinf(i * 2 * M_PI / 32) + 1.0f) / 2.0f;
float expect_y = (cosf(i * 2 * M_PI / 32) + 1.0f) / 2.0f;
v = get_readback_vec4(&rb, i * 640 / 32, 0);
todo_wine
ok(compare_vec4(v, expect_x, expect_y, 0.0f, 0.0f, 4096),
"Test %u: Got {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
i, v->x, v->y, v->z, v->w, expect_x, expect_y, 0.0f, 0.0f);
@ -1087,7 +1085,7 @@ static void test_global_initializer(void)
if (!init_test_context(&test_context))
return;
todo_wine ps_code = compile_shader(ps_source, "ps_2_0", 0);
ps_code = compile_shader(ps_source, "ps_2_0", 0);
if (ps_code)
{
hr = pD3DXGetShaderConstantTable(ID3D10Blob_GetBufferPointer(ps_code), &constants);
@ -1098,7 +1096,7 @@ static void test_global_initializer(void)
draw_quad(test_context.device, ps_code);
v = get_color_vec4(test_context.device, 0, 0);
todo_wine ok(compare_vec4(&v, 0.8f, 0.2f, 0.0f, 0.0f, 4096),
ok(compare_vec4(&v, 0.8f, 0.2f, 0.0f, 0.0f, 4096),
"Got unexpected value {%.8e, %.8e, %.8e, %.8e}.\n", v.x, v.y, v.z, v.w);
ID3D10Blob_Release(ps_code);
@ -1680,12 +1678,12 @@ static void test_include(void)
winetest_push_context("Test %u", i);
hr = tests[i](filename_a, &include.ID3DInclude_iface, &blob, &errors);
todo_wine_if (i != 0)
todo_wine_if (i == 1)
{
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
ok(!!blob, "Got unexpected blob.\n");
}
todo_wine_if (i != 0)
todo_wine_if (i == 1)
ok(!errors, "Got unexpected errors.\n");
if (blob)
{
@ -1706,7 +1704,7 @@ static void test_include(void)
* instead of using the immediate parent, as it would be the case for
* standard C preprocessor includes. */
hr = tests[i](filename_a, D3D_COMPILE_STANDARD_FILE_INCLUDE, &blob, &errors);
todo_wine_if (i != 0)
todo_wine_if (i == 1)
{
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
ok(!!blob, "Got unexpected blob.\n");
@ -1727,7 +1725,7 @@ static void test_include(void)
hr = D3DCompileFromFile(L"nonexistent", NULL, NULL, "main", "vs_2_0", 0, 0, &blob, &errors);
ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Got unexpected hr %#lx.\n", hr);
ok(!blob, "Got unexpected blob.\n");
todo_wine ok(!errors, "Got unexpected errors.\n");
ok(!errors, "Got unexpected errors.\n");
hr = D3DCompileFromFile(filename, NULL, NULL, "main", "ps_2_0", 0, 0, &blob, &errors);
ok(hr == E_FAIL, "Got unexpected hr %#lx.\n", hr);
@ -1738,9 +1736,9 @@ static void test_include(void)
errors = NULL;
hr = D3DCompileFromFile(filename, NULL, &include.ID3DInclude_iface, "main", "ps_2_0", 0, 0, &blob, &errors);
todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
todo_wine ok(!!blob, "Got unexpected blob.\n");
todo_wine ok(!errors, "Got unexpected errors.\n");
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
ok(!!blob, "Got unexpected blob.\n");
ok(!errors, "Got unexpected errors.\n");
if (blob)
{
ID3D10Blob_Release(blob);
@ -1751,9 +1749,9 @@ static void test_include(void)
* instead of using the immediate parent, as it would be the case for
* standard C preprocessor includes. */
hr = D3DCompileFromFile(filename, NULL, D3D_COMPILE_STANDARD_FILE_INCLUDE, "main", "ps_2_0", 0, 0, &blob, &errors);
todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
todo_wine ok(!!blob, "Got unexpected blob.\n");
todo_wine ok(!errors, "Got unexpected errors.\n");
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
ok(!!blob, "Got unexpected blob.\n");
ok(!errors, "Got unexpected errors.\n");
if (blob)
{
ID3D10Blob_Release(blob);
@ -1780,7 +1778,7 @@ static void test_include(void)
winetest_push_context("Test %u", i);
hr = tests[i](NULL, D3D_COMPILE_STANDARD_FILE_INCLUDE, &blob, &errors);
todo_wine_if (i != 0)
todo_wine_if (i == 1)
{
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
ok(!!blob, "Got unexpected blob.\n");
@ -1796,9 +1794,9 @@ static void test_include(void)
}
hr = D3DCompileFromFile(L"source.ps", NULL, D3D_COMPILE_STANDARD_FILE_INCLUDE, "main", "ps_2_0", 0, 0, &blob, &errors);
todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
todo_wine ok(!!blob, "Got unexpected blob.\n");
todo_wine ok(!errors, "Got unexpected errors.\n");
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
ok(!!blob, "Got unexpected blob.\n");
ok(!errors, "Got unexpected errors.\n");
if (blob)
{
ID3D10Blob_Release(blob);

View file

@ -575,9 +575,9 @@ static void test_D3DX11CompileFromFile(void)
hr = D3DX11CompileFromFileW(filename, NULL, &include.ID3DInclude_iface,
"main", "ps_2_0", 0, 0, NULL, &blob, &errors, &result);
todo_wine ok(hr == S_OK && hr == result, "Got unexpected hr %#lx, result %#lx.\n", hr, result);
todo_wine ok(!!blob, "Got unexpected blob.\n");
todo_wine ok(!errors, "Got unexpected errors.\n");
ok(hr == S_OK && hr == result, "Got unexpected hr %#lx, result %#lx.\n", hr, result);
ok(!!blob, "Got unexpected blob.\n");
ok(!errors, "Got unexpected errors.\n");
if (errors)
{
ID3D10Blob_Release(errors);
@ -593,9 +593,9 @@ static void test_D3DX11CompileFromFile(void)
* instead of using the immediate parent, as it would be the case for
* standard C preprocessor includes. */
hr = D3DX11CompileFromFileW(filename, NULL, NULL, "main", "ps_2_0", 0, 0, NULL, &blob, &errors, &result);
todo_wine ok(hr == S_OK && hr == result, "Got unexpected hr %#lx, result %#lx.\n", hr, result);
todo_wine ok(!!blob, "Got unexpected blob.\n");
todo_wine ok(!errors, "Got unexpected errors.\n");
ok(hr == S_OK && hr == result, "Got unexpected hr %#lx, result %#lx.\n", hr, result);
ok(!!blob, "Got unexpected blob.\n");
ok(!errors, "Got unexpected errors.\n");
if (errors)
{
ID3D10Blob_Release(errors);
@ -610,9 +610,9 @@ static void test_D3DX11CompileFromFile(void)
len = WideCharToMultiByte(CP_ACP, 0, filename, -1, NULL, 0, NULL, NULL);
WideCharToMultiByte(CP_ACP, 0, filename, -1, filename_a, len, NULL, NULL);
hr = D3DX11CompileFromFileA(filename_a, NULL, NULL, "main", "ps_2_0", 0, 0, NULL, &blob, &errors, &result);
todo_wine ok(hr == S_OK && hr == result, "Got unexpected hr %#lx, result %#lx.\n", hr, result);
todo_wine ok(!!blob, "Got unexpected blob.\n");
todo_wine ok(!errors, "Got unexpected errors.\n");
ok(hr == S_OK && hr == result, "Got unexpected hr %#lx, result %#lx.\n", hr, result);
ok(!!blob, "Got unexpected blob.\n");
ok(!errors, "Got unexpected errors.\n");
if (errors)
{
ID3D10Blob_Release(errors);
@ -628,9 +628,9 @@ static void test_D3DX11CompileFromFile(void)
SetCurrentDirectoryW(temp_dir);
hr = D3DX11CompileFromFileW(L"source.ps", NULL, NULL, "main", "ps_2_0", 0, 0, NULL, &blob, &errors, &result);
todo_wine ok(hr == S_OK && hr == result, "Got unexpected hr %#lx, result %#lx.\n", hr, result);
todo_wine ok(!!blob, "Got unexpected blob.\n");
todo_wine ok(!errors, "Got unexpected errors.\n");
ok(hr == S_OK && hr == result, "Got unexpected hr %#lx, result %#lx.\n", hr, result);
ok(!!blob, "Got unexpected blob.\n");
ok(!errors, "Got unexpected errors.\n");
if (errors)
{
ID3D10Blob_Release(errors);

View file

@ -3,6 +3,7 @@ Alexandre Julliard
Alistair Leslie-Hughes
Andrew Eikum
Andrey Gusev
Anna (navi) Figueiredo Gomes
Atharva Nimbalkar
Biswapriyo Nath
Brendan Shanks
@ -33,8 +34,10 @@ Petrichor Park
Philip Rebohle
Rémi Bernon
Robin Kertels
Shaun Ren
Stefan Dösinger
Sven Hesse
Victor Chiletto
Vinson Lee
Yuxuan Shui
Zhiyi Zhang

View file

@ -46,12 +46,22 @@
#define STATIC_ASSERT(e) extern void __VKD3D_STATIC_ASSERT__(int [(e) ? 1 : -1])
#define VKD3D_ASSERT(cond) \
do { \
if (!(cond)) \
ERR("Failed assertion: %s\n", #cond); \
} while (0)
#define MEMBER_SIZE(t, m) sizeof(((t *)0)->m)
#define VKD3D_MAKE_TAG(ch0, ch1, ch2, ch3) \
((uint32_t)(ch0) | ((uint32_t)(ch1) << 8) \
| ((uint32_t)(ch2) << 16) | ((uint32_t)(ch3) << 24))
#define VKD3D_EXPAND(x) x
#define VKD3D_STRINGIFY(x) #x
#define VKD3D_EXPAND_AND_STRINGIFY(x) VKD3D_EXPAND(VKD3D_STRINGIFY(x))
#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')
@ -98,17 +108,11 @@ static inline uint64_t align(uint64_t addr, size_t alignment)
# define VKD3D_UNREACHABLE (void)0
#endif /* __GNUC__ */
VKD3D_NORETURN static inline void vkd3d_unreachable_(const char *filename, unsigned int line)
{
fprintf(stderr, "%s:%u: Aborting, reached unreachable code.\n", filename, line);
abort();
}
#ifdef NDEBUG
#define vkd3d_unreachable() VKD3D_UNREACHABLE
#else
#define vkd3d_unreachable() vkd3d_unreachable_(__FILE__, __LINE__)
#endif
#define vkd3d_unreachable() \
do { \
ERR("%s:%u: Unreachable code reached.\n", __FILE__, __LINE__); \
VKD3D_UNREACHABLE; \
} while (0)
#ifdef VKD3D_NO_TRACE_MESSAGES
#define TRACE(args...) do { } while (0)
@ -118,11 +122,19 @@ VKD3D_NORETURN static inline void vkd3d_unreachable_(const char *filename, unsig
#ifdef VKD3D_NO_DEBUG_MESSAGES
#define WARN(args...) do { } while (0)
#define FIXME(args...) do { } while (0)
#define WARN_ON() (false)
#define FIXME_ONCE(args...) do { } while (0)
#endif
#ifdef VKD3D_NO_ERROR_MESSAGES
#define ERR(args...) do { } while (0)
#define MESSAGE(args...) do { } while (0)
#endif
enum vkd3d_dbg_level
{
VKD3D_DBG_LEVEL_NONE,
VKD3D_DBG_LEVEL_MESSAGE,
VKD3D_DBG_LEVEL_ERR,
VKD3D_DBG_LEVEL_FIXME,
VKD3D_DBG_LEVEL_WARN,
@ -143,7 +155,7 @@ const char *debugstr_w(const WCHAR *wstr, size_t wchar_size);
#define VKD3D_DBG_LOG(level) \
do { \
const enum vkd3d_dbg_level vkd3d_dbg_level = VKD3D_DBG_LEVEL_##level; \
VKD3D_DBG_PRINTF
VKD3D_DBG_PRINTF_##level
#define VKD3D_DBG_LOG_ONCE(first_time_level, level) \
do { \
@ -151,24 +163,50 @@ const char *debugstr_w(const WCHAR *wstr, size_t wchar_size);
const enum vkd3d_dbg_level vkd3d_dbg_level = vkd3d_dbg_next_time \
? VKD3D_DBG_LEVEL_##level : VKD3D_DBG_LEVEL_##first_time_level; \
vkd3d_dbg_next_time = true; \
VKD3D_DBG_PRINTF
VKD3D_DBG_PRINTF_##level
#define VKD3D_DBG_PRINTF(...) \
vkd3d_dbg_printf(vkd3d_dbg_level, __FUNCTION__, __VA_ARGS__); } while (0)
#define VKD3D_DBG_PRINTF_TRACE(...) VKD3D_DBG_PRINTF(__VA_ARGS__)
#define VKD3D_DBG_PRINTF_WARN(...) VKD3D_DBG_PRINTF(__VA_ARGS__)
#define VKD3D_DBG_PRINTF_FIXME(...) VKD3D_DBG_PRINTF(__VA_ARGS__)
#define VKD3D_DBG_PRINTF_MESSAGE(...) VKD3D_DBG_PRINTF(__VA_ARGS__)
#ifdef VKD3D_ABORT_ON_ERR
#define VKD3D_DBG_PRINTF_ERR(...) \
vkd3d_dbg_printf(vkd3d_dbg_level, __FUNCTION__, __VA_ARGS__); \
abort(); \
} while (0)
#else
#define VKD3D_DBG_PRINTF_ERR(...) VKD3D_DBG_PRINTF(__VA_ARGS__)
#endif
/* Used by vkd3d_unreachable(). */
#ifdef VKD3D_CROSSTEST
#undef ERR
#define ERR(...) do { fprintf(stderr, __VA_ARGS__); abort(); } while (0)
#endif
#ifndef TRACE
#define TRACE VKD3D_DBG_LOG(TRACE)
#define TRACE VKD3D_DBG_LOG(TRACE)
#endif
#ifndef WARN
#define WARN VKD3D_DBG_LOG(WARN)
#define WARN VKD3D_DBG_LOG(WARN)
#endif
#ifndef FIXME
#define FIXME VKD3D_DBG_LOG(FIXME)
#define FIXME VKD3D_DBG_LOG(FIXME)
#endif
#define ERR VKD3D_DBG_LOG(ERR)
#ifndef ERR
#define ERR VKD3D_DBG_LOG(ERR)
#endif
#ifndef MESSAGE
#define MESSAGE VKD3D_DBG_LOG(MESSAGE)
#endif
#ifndef TRACE_ON
#define TRACE_ON() (vkd3d_dbg_get_level() == VKD3D_DBG_LEVEL_TRACE)
@ -178,7 +216,9 @@ const char *debugstr_w(const WCHAR *wstr, size_t wchar_size);
#define WARN_ON() (vkd3d_dbg_get_level() >= VKD3D_DBG_LEVEL_WARN)
#endif
#ifndef FIXME_ONCE
#define FIXME_ONCE VKD3D_DBG_LOG_ONCE(FIXME, WARN)
#endif
#define VKD3D_DEBUG_ENV_NAME(name) const char *const vkd3d_dbg_env_name = name

View file

@ -19,7 +19,6 @@
#ifndef __VKD3D_MEMORY_H
#define __VKD3D_MEMORY_H
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
@ -44,7 +43,7 @@ static inline void *vkd3d_realloc(void *ptr, size_t size)
static inline void *vkd3d_calloc(size_t count, size_t size)
{
void *ptr;
assert(count <= ~(size_t)0 / size);
VKD3D_ASSERT(!size || count <= ~(size_t)0 / size);
if (!(ptr = calloc(count, size)))
ERR("Out of memory.\n");
return ptr;

View file

@ -97,6 +97,7 @@ enum vkd3d_api_version
VKD3D_API_VERSION_1_10,
VKD3D_API_VERSION_1_11,
VKD3D_API_VERSION_1_12,
VKD3D_API_VERSION_1_13,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_API_VERSION),
};

View file

@ -55,6 +55,7 @@ enum vkd3d_shader_api_version
VKD3D_SHADER_API_VERSION_1_10,
VKD3D_SHADER_API_VERSION_1_11,
VKD3D_SHADER_API_VERSION_1_12,
VKD3D_SHADER_API_VERSION_1_13,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_API_VERSION),
};
@ -105,6 +106,11 @@ enum vkd3d_shader_structure_type
* \since 1.10
*/
VKD3D_SHADER_STRUCTURE_TYPE_SCAN_COMBINED_RESOURCE_SAMPLER_INFO,
/**
* The structure is a vkd3d_shader_parameter_info structure.
* \since 1.13
*/
VKD3D_SHADER_STRUCTURE_TYPE_PARAMETER_INFO,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE),
};
@ -453,44 +459,216 @@ enum vkd3d_shader_binding_flag
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_BINDING_FLAG),
};
/**
* The manner in which a parameter value is provided to the shader, used in
* struct vkd3d_shader_parameter and struct vkd3d_shader_parameter1.
*/
enum vkd3d_shader_parameter_type
{
VKD3D_SHADER_PARAMETER_TYPE_UNKNOWN,
/** The parameter value is embedded directly in the shader. */
VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT,
/**
* The parameter value is provided to the shader via a specialization
* constant. This value is only supported for the SPIR-V target type.
*/
VKD3D_SHADER_PARAMETER_TYPE_SPECIALIZATION_CONSTANT,
/**
* The parameter value is provided to the shader as part of a uniform
* buffer.
*
* \since 1.13
*/
VKD3D_SHADER_PARAMETER_TYPE_BUFFER,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_PARAMETER_TYPE),
};
/**
* The format of data provided to the shader, used in
* struct vkd3d_shader_parameter and struct vkd3d_shader_parameter1.
*/
enum vkd3d_shader_parameter_data_type
{
VKD3D_SHADER_PARAMETER_DATA_TYPE_UNKNOWN,
/** The parameter is provided as a 32-bit unsigned integer. */
VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32,
/** The parameter is provided as a 32-bit float. \since 1.13 */
VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_PARAMETER_DATA_TYPE),
};
/**
* Names a specific shader parameter, used in
* struct vkd3d_shader_parameter and struct vkd3d_shader_parameter1.
*/
enum vkd3d_shader_parameter_name
{
VKD3D_SHADER_PARAMETER_NAME_UNKNOWN,
/**
* The sample count of the framebuffer, as returned by the HLSL function
* GetRenderTargetSampleCount() or the GLSL builtin gl_NumSamples.
*
* This parameter should be specified when compiling to SPIR-V, which
* provides no builtin ability to query this information from the shader.
*
* The default value is 1.
*
* The data type for this parameter must be
* VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32.
*/
VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT,
/**
* Alpha test comparison function. When this parameter is provided, if the
* alpha component of the pixel shader colour output at location 0 fails the
* test, as defined by this function and the reference value provided by
* VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF, the fragment will be
* discarded.
*
* This parameter, along with VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF,
* can be used to implement fixed function alpha test, as present in
* Direct3D versions up to 9, if the target environment does not support
* alpha test as part of its own fixed-function API (as Vulkan and core
* OpenGL).
*
* The default value is VKD3D_SHADER_COMPARISON_FUNC_ALWAYS.
*
* The data type for this parameter must be
* VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32. The value specified must be
* a member of enum vkd3d_shader_comparison_func.
*
* Only VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT is supported in this
* version of vkd3d-shader.
*
* \since 1.13
*/
VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_FUNC,
/**
* Alpha test reference value.
* See VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_FUNC for documentation of
* alpha test.
*
* The default value is zero.
*
* \since 1.13
*/
VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF,
/**
* Whether to use flat interpolation for fragment shader colour inputs.
* If the value is nonzero, inputs whose semantic usage is COLOR will use
* flat interpolation instead of linear.
* This parameter is ignored if the shader model is 4 or greater, since only
* shader model 3 and below do not specify the interpolation mode in the
* shader bytecode.
*
* This parameter can be used to implement fixed function shade mode, as
* present in Direct3D versions up to 9, if the target environment does not
* support shade mode as part of its own fixed-function API (as Vulkan and
* core OpenGL).
*
* The data type for this parameter must be
* VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32.
*
* The default value is zero, i.e. use linear interpolation.
*
* Only VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT is supported in this
* version of vkd3d-shader.
*
* \since 1.13
*/
VKD3D_SHADER_PARAMETER_NAME_FLAT_INTERPOLATION,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_PARAMETER_NAME),
};
/**
* The value of an immediate constant parameter, used in
* struct vkd3d_shader_parameter.
*/
struct vkd3d_shader_parameter_immediate_constant
{
union
{
/**
* The value if the parameter's data type is
* VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32.
*/
uint32_t u32;
/**
* The value if the parameter's data type is
* VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32.
*
* \since 1.13
*/
float f32;
} u;
};
/**
* The value of an immediate constant parameter, used in
* struct vkd3d_shader_parameter1.
*
* \since 1.13
*/
struct vkd3d_shader_parameter_immediate_constant1
{
union
{
/**
* The value if the parameter's data type is
* VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32.
*/
uint32_t u32;
/**
* The value if the parameter's data type is
* VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32.
*/
float f32;
void *_pointer_pad;
uint32_t _pad[4];
} u;
};
/**
* The linkage of a specialization constant parameter, used in
* struct vkd3d_shader_parameter and struct vkd3d_shader_parameter1.
*/
struct vkd3d_shader_parameter_specialization_constant
{
/** The ID of the specialization constant. */
uint32_t id;
};
/**
* The linkage of a parameter specified through a uniform buffer, used in
* struct vkd3d_shader_parameter1.
*/
struct vkd3d_shader_parameter_buffer
{
/**
* The set of the uniform buffer descriptor. If the target environment does
* not support descriptor sets, this value must be set to 0.
*/
unsigned int set;
/** The binding index of the uniform buffer descriptor. */
unsigned int binding;
/** The byte offset of the parameter within the buffer. */
uint32_t offset;
};
/**
* An individual shader parameter.
*
* This structure is an earlier version of struct vkd3d_shader_parameter1
* which supports fewer parameter types;
* refer to that structure for usage information.
*
* Only the following types may be used with this structure:
*
* - VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT
* - VKD3D_SHADER_PARAMETER_TYPE_SPECIALIZATION_CONSTANT
*/
struct vkd3d_shader_parameter
{
enum vkd3d_shader_parameter_name name;
@ -503,6 +681,56 @@ struct vkd3d_shader_parameter
} u;
};
/**
* An individual shader parameter.
*
* This structure is used in struct vkd3d_shader_parameter_info; see there for
* explanation of shader parameters.
*
* For example, to specify the rasterizer sample count to the shader via an
* unsigned integer specialization constant with ID 3,
* set the following members:
*
* - \a name = VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT
* - \a type = VKD3D_SHADER_PARAMETER_TYPE_SPECIALIZATION_CONSTANT
* - \a data_type = VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32
* - \a u.specialization_constant.id = 3
*
* This structure is an extended version of struct vkd3d_shader_parameter.
*/
struct vkd3d_shader_parameter1
{
/** The builtin parameter to be mapped. */
enum vkd3d_shader_parameter_name name;
/** How the parameter will be provided to the shader. */
enum vkd3d_shader_parameter_type type;
/**
* The data type of the supplied parameter, which determines how it is to
* be interpreted.
*/
enum vkd3d_shader_parameter_data_type data_type;
union
{
/**
* Additional information if \a type is
* VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT.
*/
struct vkd3d_shader_parameter_immediate_constant1 immediate_constant;
/**
* Additional information if \a type is
* VKD3D_SHADER_PARAMETER_TYPE_SPECIALIZATION_CONSTANT.
*/
struct vkd3d_shader_parameter_specialization_constant specialization_constant;
/**
* Additional information if \a type is
* VKD3D_SHADER_PARAMETER_TYPE_BUFFER.
*/
struct vkd3d_shader_parameter_buffer buffer;
void *_pointer_pad;
uint32_t _pad[4];
} u;
};
/**
* Symbolic register indices for mapping uniform constant register sets in
* legacy Direct3D bytecode to constant buffer views in the target environment.
@ -1674,7 +1902,7 @@ enum vkd3d_shader_sysval_semantic
VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX = 0x05,
/** Vertex ID; SV_VertexID in Direct3D. */
VKD3D_SHADER_SV_VERTEX_ID = 0x06,
/** Primtive ID; SV_PrimitiveID in Direct3D. */
/** Primitive ID; SV_PrimitiveID in Direct3D. */
VKD3D_SHADER_SV_PRIMITIVE_ID = 0x07,
/** Instance ID; SV_InstanceID in Direct3D. */
VKD3D_SHADER_SV_INSTANCE_ID = 0x08,
@ -1994,6 +2222,44 @@ struct vkd3d_shader_varying_map_info
unsigned int varying_count;
};
/**
* Interface information regarding a builtin shader parameter.
*
* Like compile options specified with struct vkd3d_shader_compile_option,
* parameters are used to specify certain values which are not part of the
* source shader bytecode but which need to be specified in the shader bytecode
* in the target format.
* Unlike struct vkd3d_shader_compile_option, however, this structure allows
* parameters to be specified in a variety of different ways, as described by
* enum vkd3d_shader_parameter_type.
*
* This structure is an extended version of struct vkd3d_shader_parameter as
* used in struct vkd3d_shader_spirv_target_info, which allows more parameter
* types to be used, and also allows specifying parameters when compiling
* shaders to target types other than SPIR-V. If this structure is chained
* along with vkd3d_shader_spirv_target_info, any parameters specified in the
* latter structure are ignored.
*
* This structure is passed to vkd3d_shader_compile() and extends
* vkd3d_shader_compile_info.
*
* This structure contains only input parameters.
*
* \since 1.13
*/
struct vkd3d_shader_parameter_info
{
/** Must be set to VKD3D_SHADER_STRUCTURE_TYPE_PARAMETER_INFO. */
enum vkd3d_shader_structure_type type;
/** Optional pointer to a structure containing further parameters. */
const void *next;
/** Pointer to an array of dynamic parameters for this shader instance. */
const struct vkd3d_shader_parameter1 *parameters;
/** Size, in elements, of \ref parameters. */
unsigned int parameter_count;
};
#ifdef LIBVKD3D_SHADER_SOURCE
# define VKD3D_SHADER_API VKD3D_EXPORT
#else
@ -2077,6 +2343,7 @@ VKD3D_SHADER_API const enum vkd3d_shader_target_type *vkd3d_shader_get_supported
* - vkd3d_shader_descriptor_offset_info
* - vkd3d_shader_hlsl_source_info
* - vkd3d_shader_interface_info
* - vkd3d_shader_parameter_info
* - vkd3d_shader_preprocess_info
* - vkd3d_shader_scan_combined_resource_sampler_info
* - vkd3d_shader_scan_descriptor_info

View file

@ -22,7 +22,6 @@
#include "vkd3d_common.h"
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <inttypes.h>
@ -45,11 +44,12 @@ extern const char *const vkd3d_dbg_env_name;
static const char *const debug_level_names[] =
{
[VKD3D_DBG_LEVEL_NONE ] = "none",
[VKD3D_DBG_LEVEL_ERR ] = "err",
[VKD3D_DBG_LEVEL_FIXME] = "fixme",
[VKD3D_DBG_LEVEL_WARN ] = "warn",
[VKD3D_DBG_LEVEL_TRACE] = "trace",
[VKD3D_DBG_LEVEL_NONE ] = "none",
[VKD3D_DBG_LEVEL_MESSAGE] = "message",
[VKD3D_DBG_LEVEL_ERR ] = "err",
[VKD3D_DBG_LEVEL_FIXME] = "fixme",
[VKD3D_DBG_LEVEL_WARN ] = "warn",
[VKD3D_DBG_LEVEL_TRACE] = "trace",
};
enum vkd3d_dbg_level vkd3d_dbg_get_level(void)
@ -104,8 +104,6 @@ void vkd3d_dbg_printf(enum vkd3d_dbg_level level, const char *function, const ch
if (vkd3d_dbg_get_level() < level)
return;
assert(level < ARRAY_SIZE(debug_level_names));
#ifdef _WIN32
vkd3d_dbg_output("vkd3d:%04lx:%s:%s ", GetCurrentThreadId(), debug_level_names[level], function);
#elif HAVE_GETTID

View file

@ -288,7 +288,7 @@ void vkd3d_compute_dxbc_checksum(const void *dxbc, size_t size, uint32_t checksu
const uint8_t *ptr = dxbc;
struct md5_ctx ctx;
assert(size > DXBC_CHECKSUM_SKIP_BYTE_COUNT);
VKD3D_ASSERT(size > DXBC_CHECKSUM_SKIP_BYTE_COUNT);
ptr += DXBC_CHECKSUM_SKIP_BYTE_COUNT;
size -= DXBC_CHECKSUM_SKIP_BYTE_COUNT;

View file

@ -254,6 +254,10 @@ static const char * const shader_opcode_names[] =
[VKD3DSIH_PHASE ] = "phase",
[VKD3DSIH_PHI ] = "phi",
[VKD3DSIH_POW ] = "pow",
[VKD3DSIH_QUAD_READ_ACROSS_D ] = "quad_read_across_d",
[VKD3DSIH_QUAD_READ_ACROSS_X ] = "quad_read_across_x",
[VKD3DSIH_QUAD_READ_ACROSS_Y ] = "quad_read_across_y",
[VKD3DSIH_QUAD_READ_LANE_AT ] = "quad_read_lane_at",
[VKD3DSIH_RCP ] = "rcp",
[VKD3DSIH_REP ] = "rep",
[VKD3DSIH_RESINFO ] = "resinfo",
@ -1199,7 +1203,7 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const
{
bool untyped = false;
switch (compiler->current->handler_idx)
switch (compiler->current->opcode)
{
case VKD3DSIH_MOV:
case VKD3DSIH_MOVC:
@ -1755,7 +1759,7 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile
{
struct vkd3d_string_buffer *buffer = &compiler->buffer;
switch (ins->handler_idx)
switch (ins->opcode)
{
case VKD3DSIH_BREAKP:
case VKD3DSIH_CONTINUEP:
@ -1853,8 +1857,13 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile
break;
case VKD3DSIH_TEX:
if (vkd3d_shader_ver_ge(&compiler->shader_version, 2, 0) && (ins->flags & VKD3DSI_TEXLD_PROJECT))
vkd3d_string_buffer_printf(buffer, "p");
if (vkd3d_shader_ver_ge(&compiler->shader_version, 2, 0))
{
if (ins->flags & VKD3DSI_TEXLD_PROJECT)
vkd3d_string_buffer_printf(buffer, "p");
else if (ins->flags & VKD3DSI_TEXLD_BIAS)
vkd3d_string_buffer_printf(buffer, "b");
}
break;
case VKD3DSIH_WAVE_OP_ADD:
@ -1910,7 +1919,7 @@ static void shader_dump_icb(struct vkd3d_d3d_asm_compiler *compiler,
}
else
{
assert(icb->component_count == VKD3D_VEC4_SIZE);
VKD3D_ASSERT(icb->component_count == VKD3D_VEC4_SIZE);
for (i = 0; i < icb->element_count; ++i)
{
shader_print_hex_literal(compiler, " {", icb->data[4 * i + 0], "");
@ -1937,9 +1946,9 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
if (ins->coissue)
vkd3d_string_buffer_printf(buffer, "+");
shader_print_opcode(compiler, ins->handler_idx);
shader_print_opcode(compiler, ins->opcode);
switch (ins->handler_idx)
switch (ins->opcode)
{
case VKD3DSIH_DCL:
case VKD3DSIH_DCL_UAV_TYPED:
@ -2242,7 +2251,7 @@ static const char *get_semantic_register_name(enum vkd3d_shader_sysval_semantic
case VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL: return "oDepthGE";
case VKD3D_SHADER_SV_DEPTH_LESS_EQUAL: return "oDepthLE";
/* SV_Coverage has name vCoverage when used as an input,
* but it doens't appear in the signature in that case. */
* but it doesn't appear in the signature in that case. */
case VKD3D_SHADER_SV_COVERAGE: return "oMask";
case VKD3D_SHADER_SV_STENCIL_REF: return "oStencilRef";
default: return "??";
@ -2430,7 +2439,7 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program,
{
struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
switch (ins->handler_idx)
switch (ins->opcode)
{
case VKD3DSIH_ELSE:
case VKD3DSIH_ENDIF:
@ -2459,7 +2468,7 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program,
shader_dump_instruction(&compiler, ins);
switch (ins->handler_idx)
switch (ins->opcode)
{
case VKD3DSIH_ELSE:
case VKD3DSIH_IF:

File diff suppressed because it is too large Load diff

View file

@ -29,7 +29,7 @@ void dxbc_writer_add_section(struct dxbc_writer *dxbc, uint32_t tag, const void
{
struct vkd3d_shader_dxbc_section_desc *section;
assert(dxbc->section_count < ARRAY_SIZE(dxbc->sections));
VKD3D_ASSERT(dxbc->section_count < ARRAY_SIZE(dxbc->sections));
section = &dxbc->sections[dxbc->section_count++];
section->tag = tag;
@ -983,7 +983,7 @@ static int shader_parse_root_signature(const struct vkd3d_shader_code *data,
{
struct vkd3d_shader_root_signature_desc1 *v_1_1 = &desc->u.v_1_1;
assert(version == VKD3D_SHADER_ROOT_SIGNATURE_VERSION_1_1);
VKD3D_ASSERT(version == VKD3D_SHADER_ROOT_SIGNATURE_VERSION_1_1);
v_1_1->parameter_count = count;
if (v_1_1->parameter_count)
@ -1777,7 +1777,7 @@ int vkd3d_shader_convert_root_signature(struct vkd3d_shader_versioned_root_signa
}
else
{
assert(version == VKD3D_SHADER_ROOT_SIGNATURE_VERSION_1_1);
VKD3D_ASSERT(version == VKD3D_SHADER_ROOT_SIGNATURE_VERSION_1_1);
ret = convert_root_signature_to_v1_1(dst, src);
}

View file

@ -458,6 +458,8 @@ enum dx_intrinsic_opcode
DX_WAVE_ACTIVE_OP = 119,
DX_WAVE_ACTIVE_BIT = 120,
DX_WAVE_PREFIX_OP = 121,
DX_QUAD_READ_LANE_AT = 122,
DX_QUAD_OP = 123,
DX_LEGACY_F32TOF16 = 130,
DX_LEGACY_F16TOF32 = 131,
DX_WAVE_ALL_BIT_COUNT = 135,
@ -576,6 +578,13 @@ enum dxil_wave_op_kind
WAVE_OP_MAX = 3,
};
enum dxil_quad_op_kind
{
QUAD_READ_ACROSS_X = 0,
QUAD_READ_ACROSS_Y = 1,
QUAD_READ_ACROSS_D = 2,
};
struct sm6_pointer_info
{
const struct sm6_type *type;
@ -932,7 +941,7 @@ static uint32_t sm6_parser_read_bits(struct sm6_parser *sm6, unsigned int length
if (!length)
return 0;
assert(length < 32);
VKD3D_ASSERT(length < 32);
if (sm6_parser_is_end(sm6))
{
@ -940,7 +949,7 @@ static uint32_t sm6_parser_read_bits(struct sm6_parser *sm6, unsigned int length
return 0;
}
assert(sm6->bitpos < 32);
VKD3D_ASSERT(sm6->bitpos < 32);
bits = *sm6->ptr >> sm6->bitpos;
l = 32 - sm6->bitpos;
if (l <= length)
@ -1199,7 +1208,7 @@ static enum vkd3d_result sm6_parser_add_global_abbrev(struct sm6_parser *sm6)
struct dxil_global_abbrev *global_abbrev;
enum vkd3d_result ret;
assert(block->id == BLOCKINFO_BLOCK);
VKD3D_ASSERT(block->id == BLOCKINFO_BLOCK);
if (!vkd3d_array_reserve((void **)&sm6->abbrevs, &sm6->abbrev_capacity, sm6->abbrev_count + 1, sizeof(*sm6->abbrevs))
|| !(global_abbrev = vkd3d_malloc(sizeof(*global_abbrev) + count * sizeof(global_abbrev->abbrev.operands[0]))))
@ -1468,7 +1477,7 @@ static enum vkd3d_result dxil_block_init(struct dxil_block *block, const struct
if (sm6->abbrevs[i]->block_id == block->id)
block->abbrevs[abbrev_count++] = &sm6->abbrevs[i]->abbrev;
assert(abbrev_count == block->abbrev_count);
VKD3D_ASSERT(abbrev_count == block->abbrev_count);
}
if ((ret = dxil_block_read(block, sm6)) < 0)
@ -1546,7 +1555,7 @@ static char *dxil_record_to_string(const struct dxil_record *record, unsigned in
unsigned int i;
char *str;
assert(offset <= record->operand_count);
VKD3D_ASSERT(offset <= record->operand_count);
if (!(str = vkd3d_calloc(record->operand_count - offset + 1, 1)))
{
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
@ -1834,7 +1843,7 @@ static enum vkd3d_result sm6_parser_type_table_init(struct sm6_parser *sm6)
++sm6->type_count;
}
assert(sm6->type_count == type_count);
VKD3D_ASSERT(sm6->type_count == type_count);
if (struct_name)
{
@ -2207,13 +2216,13 @@ static inline bool sm6_value_is_function_dcl(const struct sm6_value *value)
static inline bool sm6_value_is_dx_intrinsic_dcl(const struct sm6_value *fn)
{
assert(sm6_value_is_function_dcl(fn));
VKD3D_ASSERT(sm6_value_is_function_dcl(fn));
return fn->u.function.is_prototype && !strncmp(fn->u.function.name, "dx.op.", 6);
}
static inline struct sm6_value *sm6_parser_get_current_value(const struct sm6_parser *sm6)
{
assert(sm6->value_count < sm6->value_capacity);
VKD3D_ASSERT(sm6->value_count < sm6->value_capacity);
return &sm6->values[sm6->value_count];
}
@ -3395,7 +3404,7 @@ static struct vkd3d_shader_instruction *sm6_parser_add_instruction(struct sm6_pa
enum vkd3d_shader_opcode handler_idx)
{
struct vkd3d_shader_instruction *ins = sm6_parser_require_space(sm6, 1);
assert(ins);
VKD3D_ASSERT(ins);
vsir_instruction_init(ins, &sm6->p.location, handler_idx);
++sm6->p.program->instructions.count;
return ins;
@ -3642,7 +3651,7 @@ static const struct vkd3d_shader_immediate_constant_buffer *resolve_forward_init
{
const struct sm6_value *value;
assert(index);
VKD3D_ASSERT(index);
--index;
if (!(value = sm6_parser_get_value_safe(sm6, index)) || (!sm6_value_is_icb(value) && !sm6_value_is_undef(value)))
{
@ -3755,21 +3764,21 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6)
for (i = 0; i < sm6->p.program->instructions.count; ++i)
{
ins = &sm6->p.program->instructions.elements[i];
if (ins->handler_idx == VKD3DSIH_DCL_INDEXABLE_TEMP && ins->declaration.indexable_temp.initialiser)
if (ins->opcode == VKD3DSIH_DCL_INDEXABLE_TEMP && ins->declaration.indexable_temp.initialiser)
{
ins->declaration.indexable_temp.initialiser = resolve_forward_initialiser(
(uintptr_t)ins->declaration.indexable_temp.initialiser, sm6);
}
else if (ins->handler_idx == VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER)
else if (ins->opcode == VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER)
{
ins->declaration.icb = resolve_forward_initialiser((uintptr_t)ins->declaration.icb, sm6);
}
else if (ins->handler_idx == VKD3DSIH_DCL_TGSM_RAW)
else if (ins->opcode == VKD3DSIH_DCL_TGSM_RAW)
{
ins->declaration.tgsm_raw.zero_init = resolve_forward_zero_initialiser(ins->flags, sm6);
ins->flags = 0;
}
else if (ins->handler_idx == VKD3DSIH_DCL_TGSM_STRUCTURED)
else if (ins->opcode == VKD3DSIH_DCL_TGSM_STRUCTURED)
{
ins->declaration.tgsm_structured.zero_init = resolve_forward_zero_initialiser(ins->flags, sm6);
ins->flags = 0;
@ -3886,7 +3895,7 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade
if (e->register_count > 1 || (is_patch_constant && vsir_sysval_semantic_is_tess_factor(e->sysval_semantic)))
param->reg.idx[count++].offset = 0;
assert(count < ARRAY_SIZE(param->reg.idx));
VKD3D_ASSERT(count < ARRAY_SIZE(param->reg.idx));
param->reg.idx[count++].offset = i;
param->reg.idx_count = count;
}
@ -4289,7 +4298,7 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco
if (!(flags & FP_ALLOW_UNSAFE_ALGEBRA))
ins->flags |= VKD3DSI_PRECISE_X;
flags &= ~FP_ALLOW_UNSAFE_ALGEBRA;
/* SPIR-V FPFastMathMode is only available in the Kernel executon model. */
/* SPIR-V FPFastMathMode is only available in the Kernel execution model. */
silence_warning = !(flags & ~(FP_NO_NAN | FP_NO_INF | FP_NO_SIGNED_ZEROS | FP_ALLOW_RECIPROCAL));
break;
case VKD3DSIH_IADD:
@ -4402,7 +4411,7 @@ static void sm6_parser_emit_br(struct sm6_parser *sm6, const struct dxil_record
code_block->terminator.false_block = sm6_function_get_block(function, record->operands[1], sm6);
}
ins->handler_idx = VKD3DSIH_NOP;
ins->opcode = VKD3DSIH_NOP;
}
static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, const struct vkd3d_shader_register **operand_regs,
@ -4619,6 +4628,8 @@ static enum vkd3d_shader_opcode map_dx_binary_op(enum dx_intrinsic_opcode op, co
return VKD3DSIH_IMAX;
case DX_IMIN:
return VKD3DSIH_IMIN;
case DX_QUAD_READ_LANE_AT:
return VKD3DSIH_QUAD_READ_LANE_AT;
case DX_UMAX:
return VKD3DSIH_UMAX;
case DX_UMIN:
@ -4855,10 +4866,10 @@ static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intr
return;
src_param_init_vector_from_reg(src_param, &buffer->u.handle.reg);
register_index_address_init(&src_param->reg.idx[2], operands[1], sm6);
assert(src_param->reg.idx_count == 3);
VKD3D_ASSERT(src_param->reg.idx_count == 3);
type = sm6_type_get_scalar_type(dst->type, 0);
assert(type);
VKD3D_ASSERT(type);
src_param->reg.data_type = vkd3d_data_type_from_sm6_type(type);
if (data_type_is_64_bit(src_param->reg.data_type))
src_param->swizzle = vsir_swizzle_64_from_32(src_param->swizzle);
@ -4962,7 +4973,7 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int
reg->non_uniform = !!sm6_value_get_constant_uint(operands[3]);
/* NOP is used to flag no instruction emitted. */
ins->handler_idx = VKD3DSIH_NOP;
ins->opcode = VKD3DSIH_NOP;
}
static void sm6_parser_emit_dx_stream(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
@ -5200,7 +5211,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in
instruction_dst_param_init_temp_vector(ins++, sm6);
state->temp_idx = 1;
/* DXIL does not have an instrinsic for sample info, and resinfo is expected to return
/* DXIL does not have an intrinsic for sample info, and resinfo is expected to return
* the sample count in .w for MS textures. The result is always a struct of 4 x uint32. */
vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SAMPLE_INFO);
ins->flags = VKD3DSI_SAMPLE_INFO_UINT;
@ -5331,7 +5342,7 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin
if (!is_patch_constant && !operands[3]->is_undefined)
{
assert(src_param->reg.idx_count > count);
VKD3D_ASSERT(src_param->reg.idx_count > count);
register_index_address_init(&src_param->reg.idx[count], operands[3], sm6);
}
@ -5370,6 +5381,47 @@ static void sm6_parser_emit_dx_primitive_id(struct sm6_parser *sm6, enum dx_intr
sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_PRIMID, VKD3D_DATA_UINT);
}
static enum vkd3d_shader_opcode dx_map_quad_op(enum dxil_quad_op_kind op)
{
switch (op)
{
case QUAD_READ_ACROSS_X:
return VKD3DSIH_QUAD_READ_ACROSS_X;
case QUAD_READ_ACROSS_Y:
return VKD3DSIH_QUAD_READ_ACROSS_Y;
case QUAD_READ_ACROSS_D:
return VKD3DSIH_QUAD_READ_ACROSS_D;
default:
return VKD3DSIH_INVALID;
}
}
static void sm6_parser_emit_dx_quad_op(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
const struct sm6_value **operands, struct function_emission_state *state)
{
struct vkd3d_shader_instruction *ins = state->ins;
struct vkd3d_shader_src_param *src_param;
enum vkd3d_shader_opcode opcode;
enum dxil_quad_op_kind quad_op;
quad_op = sm6_value_get_constant_uint(operands[1]);
if ((opcode = dx_map_quad_op(quad_op)) == VKD3DSIH_INVALID)
{
FIXME("Unhandled quad op kind %u.\n", quad_op);
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_UNHANDLED_INTRINSIC,
"Quad op kind %u is unhandled.", quad_op);
return;
}
vsir_instruction_init(ins, &sm6->p.location, opcode);
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
return;
src_param_init_from_value(src_param, operands[0]);
instruction_dst_param_init_ssa_scalar(ins, sm6);
}
static void sm6_parser_emit_dx_raw_buffer_load(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
const struct sm6_value **operands, struct function_emission_state *state)
{
@ -6229,6 +6281,8 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] =
[DX_MAKE_DOUBLE ] = {"d", "ii", sm6_parser_emit_dx_make_double},
[DX_OUTPUT_CONTROL_POINT_ID ] = {"i", "", sm6_parser_emit_dx_output_control_point_id},
[DX_PRIMITIVE_ID ] = {"i", "", sm6_parser_emit_dx_primitive_id},
[DX_QUAD_OP ] = {"n", "Rc", sm6_parser_emit_dx_quad_op},
[DX_QUAD_READ_LANE_AT ] = {"n", "Ri", sm6_parser_emit_dx_binary},
[DX_RAW_BUFFER_LOAD ] = {"o", "Hii8i", sm6_parser_emit_dx_raw_buffer_load},
[DX_RAW_BUFFER_STORE ] = {"v", "Hiioooocc", sm6_parser_emit_dx_raw_buffer_store},
[DX_ROUND_NE ] = {"g", "R", sm6_parser_emit_dx_unary},
@ -6346,7 +6400,7 @@ static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_
info = &sm6_dx_op_table[op];
assert(info->ret_type[0]);
VKD3D_ASSERT(info->ret_type[0]);
if (!sm6_parser_validate_operand_type(sm6, dst, info->ret_type[0], NULL, true))
{
WARN("Failed to validate return type for dx intrinsic id %u, '%s'.\n", op, name);
@ -6381,7 +6435,7 @@ static void sm6_parser_emit_unhandled(struct sm6_parser *sm6, struct vkd3d_shade
{
const struct sm6_type *type;
ins->handler_idx = VKD3DSIH_NOP;
ins->opcode = VKD3DSIH_NOP;
if (!dst->type)
return;
@ -6551,7 +6605,7 @@ static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_
else if (to->u.width > from->u.width)
{
op = (code == CAST_ZEXT) ? VKD3DSIH_UTOU : VKD3DSIH_ITOI;
assert(from->u.width == 1 || to->u.width == 64);
VKD3D_ASSERT(from->u.width == 1 || to->u.width == 64);
is_valid = from_int && to_int;
}
break;
@ -6628,7 +6682,7 @@ static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_recor
{
*dst = *value;
dst->type = type;
ins->handler_idx = VKD3DSIH_NOP;
ins->opcode = VKD3DSIH_NOP;
return;
}
@ -6739,7 +6793,7 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor
* do not otherwise occur, so deleting these avoids the need for backend support. */
if (sm6_type_is_bool(type_a) && code == ICMP_NE && sm6_value_is_constant_zero(b))
{
ins->handler_idx = VKD3DSIH_NOP;
ins->opcode = VKD3DSIH_NOP;
*dst = *a;
return;
}
@ -7039,7 +7093,7 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record
reg->idx_count = 2;
dst->structure_stride = src->structure_stride;
ins->handler_idx = VKD3DSIH_NOP;
ins->opcode = VKD3DSIH_NOP;
}
static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_record *record,
@ -7087,7 +7141,7 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor
if (ptr->structure_stride)
{
assert(ptr->u.reg.type == VKD3DSPR_GROUPSHAREDMEM);
VKD3D_ASSERT(ptr->u.reg.type == VKD3DSPR_GROUPSHAREDMEM);
vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_LD_STRUCTURED);
if (!(src_params = instruction_src_params_alloc(ins, 3, sm6)))
@ -7189,7 +7243,7 @@ static void sm6_parser_emit_phi(struct sm6_parser *sm6, const struct dxil_record
incoming[j].block = sm6_function_get_block(function, record->operands[i + 1], sm6);
}
ins->handler_idx = VKD3DSIH_NOP;
ins->opcode = VKD3DSIH_NOP;
qsort(incoming, phi->incoming_count, sizeof(*incoming), phi_incoming_compare);
@ -7224,7 +7278,7 @@ static void sm6_parser_emit_ret(struct sm6_parser *sm6, const struct dxil_record
code_block->terminator.type = TERMINATOR_RET;
ins->handler_idx = VKD3DSIH_NOP;
ins->opcode = VKD3DSIH_NOP;
}
static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_record *record,
@ -7270,7 +7324,7 @@ static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_reco
if (ptr->structure_stride)
{
assert(ptr->u.reg.type == VKD3DSPR_GROUPSHAREDMEM);
VKD3D_ASSERT(ptr->u.reg.type == VKD3DSPR_GROUPSHAREDMEM);
vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_STORE_STRUCTURED);
if (!(src_params = instruction_src_params_alloc(ins, 3, sm6)))
@ -7326,7 +7380,7 @@ static void sm6_parser_emit_switch(struct sm6_parser *sm6, const struct dxil_rec
if (!(src = sm6_parser_get_value_by_ref(sm6, record, type, &i))
|| !sm6_value_validate_is_register(src, sm6))
return;
assert(i == 2);
VKD3D_ASSERT(i == 2);
if (src->type != type)
{
@ -7384,7 +7438,7 @@ static void sm6_parser_emit_switch(struct sm6_parser *sm6, const struct dxil_rec
terminator->cases[i / 2u].value = sm6_value_get_constant_uint64(src);
}
ins->handler_idx = VKD3DSIH_NOP;
ins->opcode = VKD3DSIH_NOP;
}
static void sm6_parser_emit_vselect(struct sm6_parser *sm6, const struct dxil_record *record,
@ -7636,7 +7690,7 @@ static void metadata_attachment_record_apply(const struct dxil_record *record, e
"Ignoring a nested metadata attachment.");
}
assert(record->operand_count & 1);
VKD3D_ASSERT(record->operand_count & 1);
for (i = 1; i < record->operand_count; i += 2)
{
if (!(m = sm6_parser_find_metadata_kind(sm6, record->operands[i])))
@ -7843,7 +7897,7 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
}
ins = &code_block->instructions[code_block->instruction_count];
ins->handler_idx = VKD3DSIH_INVALID;
ins->opcode = VKD3DSIH_INVALID;
dst = sm6_parser_get_current_value(sm6);
fwd_type = dst->type;
@ -7922,7 +7976,6 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
if (sm6->p.failed)
return VKD3D_ERROR;
assert(ins->handler_idx != VKD3DSIH_INVALID);
if (record->attachment)
metadata_attachment_record_apply(record->attachment, record->code, ins, dst, sm6);
@ -7933,9 +7986,7 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
code_block = (block_idx < function->block_count) ? function->blocks[block_idx] : NULL;
}
if (code_block)
code_block->instruction_count += ins->handler_idx != VKD3DSIH_NOP;
else
assert(ins->handler_idx == VKD3DSIH_NOP);
code_block->instruction_count += ins->opcode != VKD3DSIH_NOP;
if (dst->type && fwd_type && dst->type != fwd_type)
{
@ -8002,7 +8053,7 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_
switch_case = &block->terminator.cases[i];
if (!(case_block = switch_case->block))
{
assert(sm6->p.failed);
VKD3D_ASSERT(sm6->p.failed);
continue;
}
if (switch_case->is_default)
@ -8071,7 +8122,7 @@ static void sm6_block_emit_phi(const struct sm6_block *block, struct sm6_parser
if (incoming_block)
vsir_src_param_init_label(&src_params[index + 1], incoming_block->id);
else
assert(sm6->p.failed);
VKD3D_ASSERT(sm6->p.failed);
}
dst_param_init(dst_param);
@ -8735,7 +8786,7 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc
if (!m)
{
ins->handler_idx = is_uav ? VKD3DSIH_DCL_UAV_RAW : VKD3DSIH_DCL_RESOURCE_RAW;
ins->opcode = is_uav ? VKD3DSIH_DCL_UAV_RAW : VKD3DSIH_DCL_RESOURCE_RAW;
ins->declaration.raw_resource.resource.reg.write_mask = 0;
return &ins->declaration.raw_resource.resource;
}
@ -8760,7 +8811,7 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc
"A typed resource has no data type.");
}
ins->handler_idx = is_uav ? VKD3DSIH_DCL_UAV_TYPED : VKD3DSIH_DCL;
ins->opcode = is_uav ? VKD3DSIH_DCL_UAV_TYPED : VKD3DSIH_DCL;
for (i = 0; i < VKD3D_VEC4_SIZE; ++i)
ins->declaration.semantic.resource_data_type[i] = resource_values.data_type;
ins->declaration.semantic.resource_type = resource_type;
@ -8770,14 +8821,14 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc
}
else if (kind == RESOURCE_KIND_RAWBUFFER)
{
ins->handler_idx = is_uav ? VKD3DSIH_DCL_UAV_RAW : VKD3DSIH_DCL_RESOURCE_RAW;
ins->opcode = is_uav ? VKD3DSIH_DCL_UAV_RAW : VKD3DSIH_DCL_RESOURCE_RAW;
ins->declaration.raw_resource.resource.reg.write_mask = 0;
return &ins->declaration.raw_resource.resource;
}
else if (kind == RESOURCE_KIND_STRUCTUREDBUFFER)
{
ins->handler_idx = is_uav ? VKD3DSIH_DCL_UAV_STRUCTURED : VKD3DSIH_DCL_RESOURCE_STRUCTURED;
ins->opcode = is_uav ? VKD3DSIH_DCL_UAV_STRUCTURED : VKD3DSIH_DCL_RESOURCE_STRUCTURED;
ins->declaration.structured_resource.byte_stride = resource_values.byte_stride;
ins->declaration.structured_resource.resource.reg.write_mask = 0;
@ -8858,7 +8909,7 @@ static enum vkd3d_result sm6_parser_resources_load_srv(struct sm6_parser *sm6,
d->kind = kind;
d->reg_type = VKD3DSPR_RESOURCE;
d->reg_data_type = (ins->resource_type == VKD3D_SHADER_RESOURCE_BUFFER) ? VKD3D_DATA_UINT : VKD3D_DATA_RESOURCE;
d->resource_data_type = (ins->handler_idx == VKD3DSIH_DCL)
d->resource_data_type = (ins->opcode == VKD3DSIH_DCL)
? ins->declaration.semantic.resource_data_type[0] : VKD3D_DATA_UNUSED;
init_resource_declaration(resource, VKD3DSPR_RESOURCE, d->reg_data_type, d->id, &d->range);
@ -8932,7 +8983,7 @@ static enum vkd3d_result sm6_parser_resources_load_uav(struct sm6_parser *sm6,
d->kind = values[0];
d->reg_type = VKD3DSPR_UAV;
d->reg_data_type = (ins->resource_type == VKD3D_SHADER_RESOURCE_BUFFER) ? VKD3D_DATA_UINT : VKD3D_DATA_UAV;
d->resource_data_type = (ins->handler_idx == VKD3DSIH_DCL_UAV_TYPED)
d->resource_data_type = (ins->opcode == VKD3DSIH_DCL_UAV_TYPED)
? ins->declaration.semantic.resource_data_type[0] : VKD3D_DATA_UNUSED;
init_resource_declaration(resource, VKD3DSPR_UAV, d->reg_data_type, d->id, &d->range);
@ -10155,12 +10206,13 @@ static struct sm6_function *sm6_parser_get_function(const struct sm6_parser *sm6
return NULL;
}
static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_program *program, const char *source_name,
static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_program *program,
const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_message_context *message_context, struct dxbc_shader_desc *dxbc_desc)
{
size_t count, length, function_count, expected_function_count, byte_code_size = dxbc_desc->byte_code_size;
const struct vkd3d_shader_location location = {.source_name = compile_info->source_name};
struct shader_signature *patch_constant_signature, *output_signature, *input_signature;
const struct vkd3d_shader_location location = {.source_name = source_name};
uint32_t version_token, dxil_version, token_count, magic;
const uint32_t *byte_code = dxbc_desc->byte_code;
unsigned int chunk_offset, chunk_size;
@ -10251,9 +10303,9 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro
/* Estimate instruction count to avoid reallocation in most shaders. */
count = max(token_count, 400) - 400;
if (!vsir_program_init(program, &version, (count + (count >> 2)) / 2u + 10))
if (!vsir_program_init(program, compile_info, &version, (count + (count >> 2)) / 2u + 10))
return VKD3D_ERROR_OUT_OF_MEMORY;
vkd3d_shader_parser_init(&sm6->p, program, message_context, source_name);
vkd3d_shader_parser_init(&sm6->p, program, message_context, compile_info->source_name);
sm6->ptr = &sm6->start[1];
sm6->bitpos = 2;
@ -10489,7 +10541,7 @@ int dxil_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t co
uint32_t *byte_code = NULL;
int ret;
ERR("Creating a DXIL parser. This is unsupported; you get to keep all the pieces if it breaks.\n");
MESSAGE("Creating a DXIL parser. This is unsupported; you get to keep all the pieces if it breaks.\n");
dxbc_desc.is_dxil = true;
if ((ret = shader_extract_from_dxbc(&compile_info->source, message_context, compile_info->source_name,
@ -10514,7 +10566,7 @@ int dxil_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t co
dxbc_desc.byte_code = byte_code;
}
ret = sm6_parser_init(&sm6, program, compile_info->source_name, message_context, &dxbc_desc);
ret = sm6_parser_init(&sm6, program, compile_info, message_context, &dxbc_desc);
free_dxbc_shader_desc(&dxbc_desc);
vkd3d_free(byte_code);

File diff suppressed because it is too large Load diff

View file

@ -18,10 +18,23 @@
#include "vkd3d_shader_private.h"
struct glsl_src
{
struct vkd3d_string_buffer *str;
};
struct glsl_dst
{
const struct vkd3d_shader_dst_param *vsir;
struct vkd3d_string_buffer *register_name;
struct vkd3d_string_buffer *mask;
};
struct vkd3d_glsl_generator
{
struct vsir_program *program;
struct vkd3d_string_buffer buffer;
struct vkd3d_string_buffer_cache string_buffers;
struct vkd3d_string_buffer *buffer;
struct vkd3d_shader_location location;
struct vkd3d_shader_message_context *message_context;
unsigned int indent;
@ -45,18 +58,149 @@ static void shader_glsl_print_indent(struct vkd3d_string_buffer *buffer, unsigne
vkd3d_string_buffer_printf(buffer, "%*s", 4 * indent, "");
}
static void shader_glsl_unhandled(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins)
static void shader_glsl_print_register_name(struct vkd3d_string_buffer *buffer,
struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_register *reg)
{
shader_glsl_print_indent(&gen->buffer, gen->indent);
vkd3d_string_buffer_printf(&gen->buffer, "/* <unhandled instruction %#x> */\n", ins->handler_idx);
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
"Internal compiler error: Unhandled instruction %#x.", ins->handler_idx);
switch (reg->type)
{
case VKD3DSPR_TEMP:
vkd3d_string_buffer_printf(buffer, "r[%u]", reg->idx[0].offset);
break;
default:
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
"Internal compiler error: Unhandled register type %#x.", reg->type);
vkd3d_string_buffer_printf(buffer, "<unrecognised register %#x>", reg->type);
break;
}
}
static void shader_glsl_ret(struct vkd3d_glsl_generator *generator,
const struct vkd3d_shader_instruction *ins)
static void shader_glsl_print_swizzle(struct vkd3d_string_buffer *buffer, uint32_t swizzle, uint32_t mask)
{
const struct vkd3d_shader_version *version = &generator->program->shader_version;
const char swizzle_chars[] = "xyzw";
unsigned int i;
vkd3d_string_buffer_printf(buffer, ".");
for (i = 0; i < VKD3D_VEC4_SIZE; ++i)
{
if (mask & (VKD3DSP_WRITEMASK_0 << i))
vkd3d_string_buffer_printf(buffer, "%c", swizzle_chars[vsir_swizzle_get_component(swizzle, i)]);
}
}
static void shader_glsl_print_write_mask(struct vkd3d_string_buffer *buffer, uint32_t write_mask)
{
vkd3d_string_buffer_printf(buffer, ".");
if (write_mask & VKD3DSP_WRITEMASK_0)
vkd3d_string_buffer_printf(buffer, "x");
if (write_mask & VKD3DSP_WRITEMASK_1)
vkd3d_string_buffer_printf(buffer, "y");
if (write_mask & VKD3DSP_WRITEMASK_2)
vkd3d_string_buffer_printf(buffer, "z");
if (write_mask & VKD3DSP_WRITEMASK_3)
vkd3d_string_buffer_printf(buffer, "w");
}
static void glsl_src_cleanup(struct glsl_src *src, struct vkd3d_string_buffer_cache *cache)
{
vkd3d_string_buffer_release(cache, src->str);
}
static void glsl_src_init(struct glsl_src *glsl_src, struct vkd3d_glsl_generator *gen,
const struct vkd3d_shader_src_param *vsir_src, uint32_t mask)
{
const struct vkd3d_shader_register *reg = &vsir_src->reg;
glsl_src->str = vkd3d_string_buffer_get(&gen->string_buffers);
if (reg->non_uniform)
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
"Internal compiler error: Unhandled 'non-uniform' modifier.");
if (vsir_src->modifiers)
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
"Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers);
shader_glsl_print_register_name(glsl_src->str, gen, reg);
if (reg->dimension == VSIR_DIMENSION_VEC4)
shader_glsl_print_swizzle(glsl_src->str, vsir_src->swizzle, mask);
}
static void glsl_dst_cleanup(struct glsl_dst *dst, struct vkd3d_string_buffer_cache *cache)
{
vkd3d_string_buffer_release(cache, dst->mask);
vkd3d_string_buffer_release(cache, dst->register_name);
}
static uint32_t glsl_dst_init(struct glsl_dst *glsl_dst, struct vkd3d_glsl_generator *gen,
const struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_dst_param *vsir_dst)
{
uint32_t write_mask = vsir_dst->write_mask;
if (ins->flags & VKD3DSI_PRECISE_XYZW)
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
"Internal compiler error: Unhandled 'precise' modifier.");
if (vsir_dst->reg.non_uniform)
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
"Internal compiler error: Unhandled 'non-uniform' modifier.");
glsl_dst->vsir = vsir_dst;
glsl_dst->register_name = vkd3d_string_buffer_get(&gen->string_buffers);
glsl_dst->mask = vkd3d_string_buffer_get(&gen->string_buffers);
shader_glsl_print_register_name(glsl_dst->register_name, gen, &vsir_dst->reg);
shader_glsl_print_write_mask(glsl_dst->mask, write_mask);
return write_mask;
}
static void VKD3D_PRINTF_FUNC(3, 4) shader_glsl_print_assignment(
struct vkd3d_glsl_generator *gen, struct glsl_dst *dst, const char *format, ...)
{
va_list args;
if (dst->vsir->shift)
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
"Internal compiler error: Unhandled destination shift %#x.", dst->vsir->shift);
if (dst->vsir->modifiers)
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
"Internal compiler error: Unhandled destination modifier(s) %#x.", dst->vsir->modifiers);
shader_glsl_print_indent(gen->buffer, gen->indent);
vkd3d_string_buffer_printf(gen->buffer, "%s%s = ", dst->register_name->buffer, dst->mask->buffer);
va_start(args, format);
vkd3d_string_buffer_vprintf(gen->buffer, format, args);
va_end(args);
vkd3d_string_buffer_printf(gen->buffer, ";\n");
}
static void shader_glsl_unhandled(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins)
{
shader_glsl_print_indent(gen->buffer, gen->indent);
vkd3d_string_buffer_printf(gen->buffer, "/* <unhandled instruction %#x> */\n", ins->opcode);
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
"Internal compiler error: Unhandled instruction %#x.", ins->opcode);
}
static void shader_glsl_mov(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins)
{
struct glsl_src src;
struct glsl_dst dst;
uint32_t mask;
mask = glsl_dst_init(&dst, gen, ins, &ins->dst[0]);
glsl_src_init(&src, gen, &ins->src[0], mask);
shader_glsl_print_assignment(gen, &dst, "%s", src.str->buffer);
glsl_src_cleanup(&src, &gen->string_buffers);
glsl_dst_cleanup(&dst, &gen->string_buffers);
}
static void shader_glsl_ret(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins)
{
const struct vkd3d_shader_version *version = &gen->program->shader_version;
/*
* TODO: Implement in_subroutine
@ -64,45 +208,59 @@ static void shader_glsl_ret(struct vkd3d_glsl_generator *generator,
*/
if (version->major >= 4)
{
shader_glsl_print_indent(&generator->buffer, generator->indent);
vkd3d_string_buffer_printf(&generator->buffer, "return;\n");
shader_glsl_print_indent(gen->buffer, gen->indent);
vkd3d_string_buffer_printf(gen->buffer, "return;\n");
}
}
static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *generator,
const struct vkd3d_shader_instruction *instruction)
static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen,
const struct vkd3d_shader_instruction *ins)
{
generator->location = instruction->location;
gen->location = ins->location;
switch (instruction->handler_idx)
switch (ins->opcode)
{
case VKD3DSIH_DCL_INPUT:
case VKD3DSIH_DCL_OUTPUT:
case VKD3DSIH_DCL_OUTPUT_SIV:
case VKD3DSIH_NOP:
break;
case VKD3DSIH_MOV:
shader_glsl_mov(gen, ins);
break;
case VKD3DSIH_RET:
shader_glsl_ret(generator, instruction);
shader_glsl_ret(gen, ins);
break;
default:
shader_glsl_unhandled(generator, instruction);
shader_glsl_unhandled(gen, ins);
break;
}
}
static void shader_glsl_generate_declarations(struct vkd3d_glsl_generator *gen)
{
const struct vsir_program *program = gen->program;
struct vkd3d_string_buffer *buffer = gen->buffer;
if (program->temp_count)
vkd3d_string_buffer_printf(buffer, "vec4 r[%u];\n\n", program->temp_count);
}
static int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *gen, struct vkd3d_shader_code *out)
{
const struct vkd3d_shader_instruction_array *instructions = &gen->program->instructions;
struct vkd3d_string_buffer *buffer = &gen->buffer;
struct vkd3d_string_buffer *buffer = gen->buffer;
unsigned int i;
void *code;
ERR("Generating a GLSL shader. This is unsupported; you get to keep all the pieces if it breaks.\n");
MESSAGE("Generating a GLSL shader. This is unsupported; you get to keep all the pieces if it breaks.\n");
vkd3d_string_buffer_printf(buffer, "#version 440\n\n");
vkd3d_string_buffer_printf(buffer, "/* Generated by %s. */\n\n", vkd3d_shader_get_version(NULL, NULL));
shader_glsl_generate_declarations(gen);
vkd3d_string_buffer_printf(buffer, "void main()\n{\n");
++gen->indent;
@ -132,7 +290,8 @@ static int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *gen, struc
static void vkd3d_glsl_generator_cleanup(struct vkd3d_glsl_generator *gen)
{
vkd3d_string_buffer_cleanup(&gen->buffer);
vkd3d_string_buffer_release(&gen->string_buffers, gen->buffer);
vkd3d_string_buffer_cache_cleanup(&gen->string_buffers);
}
static void vkd3d_glsl_generator_init(struct vkd3d_glsl_generator *gen,
@ -140,7 +299,8 @@ static void vkd3d_glsl_generator_init(struct vkd3d_glsl_generator *gen,
{
memset(gen, 0, sizeof(*gen));
gen->program = program;
vkd3d_string_buffer_init(&gen->buffer);
vkd3d_string_buffer_cache_init(&gen->string_buffers);
gen->buffer = vkd3d_string_buffer_get(&gen->string_buffers);
gen->message_context = message_context;
}

View file

@ -134,7 +134,7 @@ struct hlsl_ir_var *hlsl_get_var(struct hlsl_scope *scope, const char *name)
return hlsl_get_var(scope->upper, name);
}
static void free_state_block_entry(struct hlsl_state_block_entry *entry)
void hlsl_free_state_block_entry(struct hlsl_state_block_entry *entry)
{
unsigned int i;
@ -151,9 +151,9 @@ void hlsl_free_state_block(struct hlsl_state_block *state_block)
{
unsigned int k;
assert(state_block);
VKD3D_ASSERT(state_block);
for (k = 0; k < state_block->count; ++k)
free_state_block_entry(state_block->entries[k]);
hlsl_free_state_block_entry(state_block->entries[k]);
vkd3d_free(state_block->entries);
vkd3d_free(state_block);
}
@ -167,6 +167,15 @@ void hlsl_free_var(struct hlsl_ir_var *decl)
for (k = 0; k <= HLSL_REGSET_LAST_OBJECT; ++k)
vkd3d_free((void *)decl->objects_usage[k]);
if (decl->default_values)
{
unsigned int component_count = hlsl_type_component_count(decl->data_type);
for (k = 0; k < component_count; ++k)
vkd3d_free((void *)decl->default_values[k].string);
vkd3d_free(decl->default_values);
}
for (i = 0; i < decl->state_block_count; ++i)
hlsl_free_state_block(decl->state_blocks[i]);
vkd3d_free(decl->state_blocks);
@ -367,15 +376,24 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type
type->reg_size[HLSL_REGSET_UAVS] = 1;
break;
case HLSL_CLASS_DEPTH_STENCIL_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_EFFECT_GROUP:
case HLSL_CLASS_PASS:
case HLSL_CLASS_PIXEL_SHADER:
case HLSL_CLASS_RASTERIZER_STATE:
case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_STRING:
case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_VERTEX_SHADER:
case HLSL_CLASS_VOID:
case HLSL_CLASS_CONSTANT_BUFFER:
case HLSL_CLASS_COMPUTE_SHADER:
case HLSL_CLASS_DOMAIN_SHADER:
case HLSL_CLASS_HULL_SHADER:
case HLSL_CLASS_GEOMETRY_SHADER:
case HLSL_CLASS_BLEND_STATE:
case HLSL_CLASS_NULL:
break;
}
}
@ -435,21 +453,30 @@ static bool type_is_single_component(const struct hlsl_type *type)
{
switch (type->class)
{
case HLSL_CLASS_DEPTH_STENCIL_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_PIXEL_SHADER:
case HLSL_CLASS_SCALAR:
case HLSL_CLASS_SAMPLER:
case HLSL_CLASS_STRING:
case HLSL_CLASS_RASTERIZER_STATE:
case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_TEXTURE:
case HLSL_CLASS_UAV:
case HLSL_CLASS_VERTEX_SHADER:
case HLSL_CLASS_COMPUTE_SHADER:
case HLSL_CLASS_DOMAIN_SHADER:
case HLSL_CLASS_HULL_SHADER:
case HLSL_CLASS_GEOMETRY_SHADER:
case HLSL_CLASS_BLEND_STATE:
case HLSL_CLASS_NULL:
return true;
case HLSL_CLASS_VECTOR:
case HLSL_CLASS_MATRIX:
case HLSL_CLASS_STRUCT:
case HLSL_CLASS_ARRAY:
case HLSL_CLASS_CONSTANT_BUFFER:
return false;
case HLSL_CLASS_EFFECT_GROUP:
@ -474,13 +501,13 @@ static unsigned int traverse_path_from_component_index(struct hlsl_ctx *ctx,
struct hlsl_type *type = *type_ptr;
unsigned int index = *index_ptr;
assert(!type_is_single_component(type));
assert(index < hlsl_type_component_count(type));
VKD3D_ASSERT(!type_is_single_component(type));
VKD3D_ASSERT(index < hlsl_type_component_count(type));
switch (type->class)
{
case HLSL_CLASS_VECTOR:
assert(index < type->dimx);
VKD3D_ASSERT(index < type->dimx);
*type_ptr = hlsl_get_scalar_type(ctx, type->e.numeric.type);
*index_ptr = 0;
return index;
@ -490,7 +517,7 @@ static unsigned int traverse_path_from_component_index(struct hlsl_ctx *ctx,
unsigned int y = index / type->dimx, x = index % type->dimx;
bool row_major = hlsl_type_is_row_major(type);
assert(index < type->dimx * type->dimy);
VKD3D_ASSERT(index < type->dimx * type->dimy);
*type_ptr = hlsl_get_vector_type(ctx, type->e.numeric.type, row_major ? type->dimx : type->dimy);
*index_ptr = row_major ? x : y;
return row_major ? y : x;
@ -504,7 +531,7 @@ static unsigned int traverse_path_from_component_index(struct hlsl_ctx *ctx,
*type_ptr = type->e.array.type;
*index_ptr = index % elem_comp_count;
array_index = index / elem_comp_count;
assert(array_index < type->e.array.elements_count);
VKD3D_ASSERT(array_index < type->e.array.elements_count);
return array_index;
}
@ -528,6 +555,12 @@ static unsigned int traverse_path_from_component_index(struct hlsl_ctx *ctx,
vkd3d_unreachable();
}
case HLSL_CLASS_CONSTANT_BUFFER:
{
*type_ptr = type->e.resource.format;
return traverse_path_from_component_index(ctx, type_ptr, index_ptr);
}
default:
vkd3d_unreachable();
}
@ -556,12 +589,14 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty
switch (type->class)
{
case HLSL_CLASS_SCALAR:
case HLSL_CLASS_VECTOR:
case HLSL_CLASS_MATRIX:
offset[HLSL_REGSET_NUMERIC] += idx;
break;
case HLSL_CLASS_MATRIX:
offset[HLSL_REGSET_NUMERIC] += 4 * idx;
break;
case HLSL_CLASS_STRUCT:
for (r = 0; r <= HLSL_REGSET_LAST; ++r)
offset[r] += type->e.record.fields[idx].reg_offset[r];
@ -577,21 +612,31 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty
}
break;
case HLSL_CLASS_DEPTH_STENCIL_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_PIXEL_SHADER:
case HLSL_CLASS_RASTERIZER_STATE:
case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_SAMPLER:
case HLSL_CLASS_STRING:
case HLSL_CLASS_TEXTURE:
case HLSL_CLASS_UAV:
case HLSL_CLASS_VERTEX_SHADER:
assert(idx == 0);
case HLSL_CLASS_COMPUTE_SHADER:
case HLSL_CLASS_DOMAIN_SHADER:
case HLSL_CLASS_HULL_SHADER:
case HLSL_CLASS_GEOMETRY_SHADER:
case HLSL_CLASS_BLEND_STATE:
VKD3D_ASSERT(idx == 0);
break;
case HLSL_CLASS_EFFECT_GROUP:
case HLSL_CLASS_PASS:
case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_VOID:
case HLSL_CLASS_SCALAR:
case HLSL_CLASS_CONSTANT_BUFFER:
case HLSL_CLASS_NULL:
vkd3d_unreachable();
}
type = next_type;
@ -638,9 +683,9 @@ bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *d
deref->rel_offset.node = NULL;
deref->const_offset = 0;
assert(chain);
VKD3D_ASSERT(chain);
if (chain->type == HLSL_IR_INDEX)
assert(!hlsl_index_is_noncontiguous(hlsl_ir_index(chain)));
VKD3D_ASSERT(!hlsl_index_is_noncontiguous(hlsl_ir_index(chain)));
/* Find the length of the index chain */
chain_len = 0;
@ -687,7 +732,7 @@ bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *d
chain_len++;
ptr = index->val.node;
}
assert(deref->path_len == load->src.path_len + chain_len);
VKD3D_ASSERT(deref->path_len == load->src.path_len + chain_len);
return true;
}
@ -697,7 +742,7 @@ struct hlsl_type *hlsl_deref_get_type(struct hlsl_ctx *ctx, const struct hlsl_de
struct hlsl_type *type;
unsigned int i;
assert(deref);
VKD3D_ASSERT(deref);
if (hlsl_deref_is_lowered(deref))
return deref->data_type;
@ -752,7 +797,7 @@ static bool init_deref_from_component_index(struct hlsl_ctx *ctx, struct hlsl_bl
hlsl_src_from_node(&deref->path[deref_path_len++], c);
}
assert(deref_path_len == deref->path_len);
VKD3D_ASSERT(deref_path_len == deref->path_len);
return true;
}
@ -760,7 +805,7 @@ static bool init_deref_from_component_index(struct hlsl_ctx *ctx, struct hlsl_bl
struct hlsl_type *hlsl_get_element_type_from_path_index(struct hlsl_ctx *ctx, const struct hlsl_type *type,
struct hlsl_ir_node *idx)
{
assert(idx);
VKD3D_ASSERT(idx);
switch (type->class)
{
@ -780,7 +825,7 @@ struct hlsl_type *hlsl_get_element_type_from_path_index(struct hlsl_ctx *ctx, co
{
struct hlsl_ir_constant *c = hlsl_ir_constant(idx);
assert(c->value.u[0].u < type->e.record.field_count);
VKD3D_ASSERT(c->value.u[0].u < type->e.record.field_count);
return type->e.record.fields[c->value.u[0].u].type;
}
@ -865,6 +910,20 @@ struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim
return type;
}
struct hlsl_type *hlsl_new_cb_type(struct hlsl_ctx *ctx, struct hlsl_type *format)
{
struct hlsl_type *type;
if (!(type = hlsl_alloc(ctx, sizeof(*type))))
return NULL;
type->class = HLSL_CLASS_CONSTANT_BUFFER;
type->dimy = 1;
type->e.resource.format = format;
hlsl_type_calculate_reg_size(ctx, type);
list_add_tail(&ctx->types, &type->entry);
return type;
}
static const char * get_case_insensitive_typename(const char *name)
{
static const char *const names[] =
@ -876,6 +935,7 @@ static const char * get_case_insensitive_typename(const char *name)
"texture",
"vector",
"vertexshader",
"string",
};
unsigned int i;
@ -956,14 +1016,25 @@ unsigned int hlsl_type_component_count(const struct hlsl_type *type)
case HLSL_CLASS_ARRAY:
return hlsl_type_component_count(type->e.array.type) * type->e.array.elements_count;
case HLSL_CLASS_CONSTANT_BUFFER:
return hlsl_type_component_count(type->e.resource.format);
case HLSL_CLASS_DEPTH_STENCIL_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_PIXEL_SHADER:
case HLSL_CLASS_RASTERIZER_STATE:
case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_SAMPLER:
case HLSL_CLASS_STRING:
case HLSL_CLASS_TEXTURE:
case HLSL_CLASS_UAV:
case HLSL_CLASS_VERTEX_SHADER:
case HLSL_CLASS_COMPUTE_SHADER:
case HLSL_CLASS_DOMAIN_SHADER:
case HLSL_CLASS_HULL_SHADER:
case HLSL_CLASS_GEOMETRY_SHADER:
case HLSL_CLASS_BLEND_STATE:
case HLSL_CLASS_NULL:
return 1;
case HLSL_CLASS_EFFECT_GROUP:
@ -1038,14 +1109,25 @@ bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2
case HLSL_CLASS_TECHNIQUE:
return t1->e.version == t2->e.version;
case HLSL_CLASS_CONSTANT_BUFFER:
return hlsl_types_are_equal(t1->e.resource.format, t2->e.resource.format);
case HLSL_CLASS_DEPTH_STENCIL_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_EFFECT_GROUP:
case HLSL_CLASS_PASS:
case HLSL_CLASS_PIXEL_SHADER:
case HLSL_CLASS_RASTERIZER_STATE:
case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_STRING:
case HLSL_CLASS_VERTEX_SHADER:
case HLSL_CLASS_VOID:
case HLSL_CLASS_COMPUTE_SHADER:
case HLSL_CLASS_DOMAIN_SHADER:
case HLSL_CLASS_HULL_SHADER:
case HLSL_CLASS_GEOMETRY_SHADER:
case HLSL_CLASS_BLEND_STATE:
case HLSL_CLASS_NULL:
return true;
}
@ -1247,6 +1329,7 @@ struct hlsl_ir_var *hlsl_new_synthetic_var_named(struct hlsl_ctx *ctx, const cha
list_add_tail(&ctx->dummy_scope->vars, &var->scope_entry);
else
list_add_tail(&ctx->globals->vars, &var->scope_entry);
var->is_synthetic = true;
}
return var;
}
@ -1265,7 +1348,7 @@ bool hlsl_copy_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, const struc
if (!other)
return true;
assert(!hlsl_deref_is_lowered(other));
VKD3D_ASSERT(!hlsl_deref_is_lowered(other));
if (!init_deref(ctx, deref, other->var, other->path_len))
return false;
@ -1322,8 +1405,8 @@ struct hlsl_ir_node *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hls
struct hlsl_ir_store *store;
unsigned int i;
assert(lhs);
assert(!hlsl_deref_is_lowered(lhs));
VKD3D_ASSERT(lhs);
VKD3D_ASSERT(!hlsl_deref_is_lowered(lhs));
if (!(store = hlsl_alloc(ctx, sizeof(*store))))
return NULL;
@ -1394,7 +1477,7 @@ struct hlsl_ir_node *hlsl_new_constant(struct hlsl_ctx *ctx, struct hlsl_type *t
{
struct hlsl_ir_constant *c;
assert(type->class <= HLSL_CLASS_VECTOR);
VKD3D_ASSERT(type->class <= HLSL_CLASS_VECTOR || type->class == HLSL_CLASS_NULL);
if (!(c = hlsl_alloc(ctx, sizeof(*c))))
return NULL;
@ -1439,6 +1522,30 @@ struct hlsl_ir_node *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned int n
return hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), &value, loc);
}
struct hlsl_ir_node *hlsl_new_string_constant(struct hlsl_ctx *ctx, const char *str,
const struct vkd3d_shader_location *loc)
{
struct hlsl_ir_string_constant *s;
if (!(s = hlsl_alloc(ctx, sizeof(*s))))
return NULL;
init_node(&s->node, HLSL_IR_STRING_CONSTANT, ctx->builtin_types.string, loc);
if (!(s->string = hlsl_strdup(ctx, str)))
{
hlsl_free_instr(&s->node);
return NULL;
}
return &s->node;
}
struct hlsl_ir_node *hlsl_new_null_constant(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc)
{
struct hlsl_constant_value value = { 0 };
return hlsl_new_constant(ctx, ctx->builtin_types.null, &value, loc);
}
struct hlsl_ir_node *hlsl_new_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op,
struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS],
struct hlsl_type *data_type, const struct vkd3d_shader_location *loc)
@ -1468,7 +1575,7 @@ struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_exp
{
struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {arg1, arg2};
assert(hlsl_types_are_equal(arg1->data_type, arg2->data_type));
VKD3D_ASSERT(hlsl_types_are_equal(arg1->data_type, arg2->data_type));
return hlsl_new_expr(ctx, op, operands, arg1->data_type, &arg1->loc);
}
@ -1477,8 +1584,8 @@ struct hlsl_ir_node *hlsl_new_ternary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_ex
{
struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {arg1, arg2, arg3};
assert(hlsl_types_are_equal(arg1->data_type, arg2->data_type));
assert(hlsl_types_are_equal(arg1->data_type, arg3->data_type));
VKD3D_ASSERT(hlsl_types_are_equal(arg1->data_type, arg2->data_type));
VKD3D_ASSERT(hlsl_types_are_equal(arg1->data_type, arg3->data_type));
return hlsl_new_expr(ctx, op, operands, arg1->data_type, &arg1->loc);
}
@ -1540,7 +1647,7 @@ struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl
struct hlsl_type *type;
unsigned int i;
assert(!hlsl_deref_is_lowered(deref));
VKD3D_ASSERT(!hlsl_deref_is_lowered(deref));
type = hlsl_deref_get_type(ctx, deref);
if (idx)
@ -1569,7 +1676,7 @@ struct hlsl_ir_load *hlsl_new_load_parent(struct hlsl_ctx *ctx, const struct hls
/* This deref can only exists temporarily because it is not the real owner of its members. */
struct hlsl_deref tmp_deref;
assert(deref->path_len >= 1);
VKD3D_ASSERT(deref->path_len >= 1);
tmp_deref = *deref;
tmp_deref.path_len = deref->path_len - 1;
@ -1674,7 +1781,7 @@ struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned
if (!(swizzle = hlsl_alloc(ctx, sizeof(*swizzle))))
return NULL;
assert(hlsl_is_numeric_type(val->data_type));
VKD3D_ASSERT(hlsl_is_numeric_type(val->data_type));
if (components == 1)
type = hlsl_get_scalar_type(ctx, val->data_type->e.numeric.type);
else
@ -1765,7 +1872,8 @@ struct hlsl_ir_node *hlsl_new_jump(struct hlsl_ctx *ctx, enum hlsl_ir_jump_type
}
struct hlsl_ir_node *hlsl_new_loop(struct hlsl_ctx *ctx,
struct hlsl_block *block, const struct vkd3d_shader_location *loc)
struct hlsl_block *block, enum hlsl_ir_loop_unroll_type unroll_type,
unsigned int unroll_limit, const struct vkd3d_shader_location *loc)
{
struct hlsl_ir_loop *loop;
@ -1774,6 +1882,9 @@ struct hlsl_ir_node *hlsl_new_loop(struct hlsl_ctx *ctx,
init_node(&loop->node, HLSL_IR_LOOP, NULL, loc);
hlsl_block_init(&loop->body);
hlsl_block_add_block(&loop->body, block);
loop->unroll_type = unroll_type;
loop->unroll_limit = unroll_limit;
return &loop->node;
}
@ -1836,9 +1947,7 @@ static struct hlsl_ir_node *map_instr(const struct clone_instr_map *map, struct
return map->instrs[i].dst;
}
/* The block passed to hlsl_clone_block() should have been free of external
* references. */
vkd3d_unreachable();
return src;
}
static bool clone_deref(struct hlsl_ctx *ctx, struct clone_instr_map *map,
@ -1846,7 +1955,7 @@ static bool clone_deref(struct hlsl_ctx *ctx, struct clone_instr_map *map,
{
unsigned int i;
assert(!hlsl_deref_is_lowered(src));
VKD3D_ASSERT(!hlsl_deref_is_lowered(src));
if (!init_deref(ctx, dst, src->var, src->path_len))
return false;
@ -1935,7 +2044,7 @@ static struct hlsl_ir_node *clone_loop(struct hlsl_ctx *ctx, struct clone_instr_
if (!clone_block(ctx, &body, &src->body, map))
return NULL;
if (!(dst = hlsl_new_loop(ctx, &body, &src->node.loc)))
if (!(dst = hlsl_new_loop(ctx, &body, src->unroll_type, src->unroll_limit, &src->node.loc)))
{
hlsl_block_cleanup(&body);
return NULL;
@ -1992,6 +2101,11 @@ static struct hlsl_ir_node *clone_resource_store(struct hlsl_ctx *ctx,
return &dst->node;
}
static struct hlsl_ir_node *clone_string_constant(struct hlsl_ctx *ctx, struct hlsl_ir_string_constant *src)
{
return hlsl_new_string_constant(ctx, src->string, &src->node.loc);
}
static struct hlsl_ir_node *clone_store(struct hlsl_ctx *ctx, struct clone_instr_map *map, struct hlsl_ir_store *src)
{
struct hlsl_ir_store *dst;
@ -2034,6 +2148,43 @@ static struct hlsl_ir_node *clone_stateblock_constant(struct hlsl_ctx *ctx,
return hlsl_new_stateblock_constant(ctx, constant->name, &constant->node.loc);
}
struct hlsl_state_block_entry *clone_stateblock_entry(struct hlsl_ctx *ctx,
struct hlsl_state_block_entry *src, const char *name, bool lhs_has_index,
unsigned int lhs_index, unsigned int arg_index)
{
struct hlsl_state_block_entry *entry;
struct clone_instr_map map = { 0 };
if (!(entry = hlsl_alloc(ctx, sizeof(*entry))))
return NULL;
entry->name = hlsl_strdup(ctx, name);
entry->lhs_has_index = lhs_has_index;
entry->lhs_index = lhs_index;
if (!(entry->instrs = hlsl_alloc(ctx, sizeof(*entry->instrs))))
{
hlsl_free_state_block_entry(entry);
return NULL;
}
entry->args_count = 1;
if (!(entry->args = hlsl_alloc(ctx, sizeof(*entry->args) * entry->args_count)))
{
hlsl_free_state_block_entry(entry);
return NULL;
}
hlsl_block_init(entry->instrs);
if (!clone_block(ctx, entry->instrs, src->instrs, &map))
{
hlsl_free_state_block_entry(entry);
return NULL;
}
clone_src(&map, entry->args, &src->args[arg_index]);
vkd3d_free(map.instrs);
return entry;
}
void hlsl_free_ir_switch_case(struct hlsl_ir_switch_case *c)
{
hlsl_block_cleanup(&c->body);
@ -2121,6 +2272,9 @@ static struct hlsl_ir_node *clone_instr(struct hlsl_ctx *ctx,
case HLSL_IR_RESOURCE_STORE:
return clone_resource_store(ctx, map, hlsl_ir_resource_store(instr));
case HLSL_IR_STRING_CONSTANT:
return clone_string_constant(ctx, hlsl_ir_string_constant(instr));
case HLSL_IR_STORE:
return clone_store(ctx, map, hlsl_ir_store(instr));
@ -2249,7 +2403,7 @@ void hlsl_pop_scope(struct hlsl_ctx *ctx)
{
struct hlsl_scope *prev_scope = ctx->cur_scope->upper;
assert(prev_scope);
VKD3D_ASSERT(prev_scope);
TRACE("Popping current scope.\n");
ctx->cur_scope = prev_scope;
}
@ -2327,17 +2481,17 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru
switch (type->class)
{
case HLSL_CLASS_SCALAR:
assert(type->e.numeric.type < ARRAY_SIZE(base_types));
VKD3D_ASSERT(type->e.numeric.type < ARRAY_SIZE(base_types));
vkd3d_string_buffer_printf(string, "%s", base_types[type->e.numeric.type]);
return string;
case HLSL_CLASS_VECTOR:
assert(type->e.numeric.type < ARRAY_SIZE(base_types));
VKD3D_ASSERT(type->e.numeric.type < ARRAY_SIZE(base_types));
vkd3d_string_buffer_printf(string, "%s%u", base_types[type->e.numeric.type], type->dimx);
return string;
case HLSL_CLASS_MATRIX:
assert(type->e.numeric.type < ARRAY_SIZE(base_types));
VKD3D_ASSERT(type->e.numeric.type < ARRAY_SIZE(base_types));
vkd3d_string_buffer_printf(string, "%s%ux%u", base_types[type->e.numeric.type], type->dimy, type->dimx);
return string;
@ -2375,15 +2529,15 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru
return string;
}
assert(hlsl_is_numeric_type(type->e.resource.format));
assert(type->e.resource.format->e.numeric.type < ARRAY_SIZE(base_types));
VKD3D_ASSERT(hlsl_is_numeric_type(type->e.resource.format));
VKD3D_ASSERT(type->e.resource.format->e.numeric.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_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)))
@ -2407,16 +2561,33 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru
}
return string;
case HLSL_CLASS_CONSTANT_BUFFER:
vkd3d_string_buffer_printf(string, "ConstantBuffer");
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);
}
return string;
case HLSL_CLASS_DEPTH_STENCIL_STATE:
case HLSL_CLASS_DEPTH_STENCIL_VIEW:
case HLSL_CLASS_EFFECT_GROUP:
case HLSL_CLASS_PASS:
case HLSL_CLASS_PIXEL_SHADER:
case HLSL_CLASS_RASTERIZER_STATE:
case HLSL_CLASS_RENDER_TARGET_VIEW:
case HLSL_CLASS_SAMPLER:
case HLSL_CLASS_STRING:
case HLSL_CLASS_TECHNIQUE:
case HLSL_CLASS_VERTEX_SHADER:
case HLSL_CLASS_VOID:
case HLSL_CLASS_COMPUTE_SHADER:
case HLSL_CLASS_DOMAIN_SHADER:
case HLSL_CLASS_HULL_SHADER:
case HLSL_CLASS_GEOMETRY_SHADER:
case HLSL_CLASS_BLEND_STATE:
case HLSL_CLASS_NULL:
break;
}
@ -2513,19 +2684,21 @@ const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type)
{
static const char * const names[] =
{
[HLSL_IR_CALL ] = "HLSL_IR_CALL",
[HLSL_IR_CONSTANT ] = "HLSL_IR_CONSTANT",
[HLSL_IR_EXPR ] = "HLSL_IR_EXPR",
[HLSL_IR_IF ] = "HLSL_IR_IF",
[HLSL_IR_INDEX ] = "HLSL_IR_INDEX",
[HLSL_IR_LOAD ] = "HLSL_IR_LOAD",
[HLSL_IR_LOOP ] = "HLSL_IR_LOOP",
[HLSL_IR_JUMP ] = "HLSL_IR_JUMP",
[HLSL_IR_RESOURCE_LOAD ] = "HLSL_IR_RESOURCE_LOAD",
[HLSL_IR_RESOURCE_STORE] = "HLSL_IR_RESOURCE_STORE",
[HLSL_IR_STORE ] = "HLSL_IR_STORE",
[HLSL_IR_SWITCH ] = "HLSL_IR_SWITCH",
[HLSL_IR_SWIZZLE ] = "HLSL_IR_SWIZZLE",
[HLSL_IR_CALL ] = "HLSL_IR_CALL",
[HLSL_IR_CONSTANT ] = "HLSL_IR_CONSTANT",
[HLSL_IR_EXPR ] = "HLSL_IR_EXPR",
[HLSL_IR_IF ] = "HLSL_IR_IF",
[HLSL_IR_INDEX ] = "HLSL_IR_INDEX",
[HLSL_IR_LOAD ] = "HLSL_IR_LOAD",
[HLSL_IR_LOOP ] = "HLSL_IR_LOOP",
[HLSL_IR_JUMP ] = "HLSL_IR_JUMP",
[HLSL_IR_RESOURCE_LOAD ] = "HLSL_IR_RESOURCE_LOAD",
[HLSL_IR_RESOURCE_STORE ] = "HLSL_IR_RESOURCE_STORE",
[HLSL_IR_STRING_CONSTANT] = "HLSL_IR_STRING_CONSTANT",
[HLSL_IR_STORE ] = "HLSL_IR_STORE",
[HLSL_IR_SWITCH ] = "HLSL_IR_SWITCH",
[HLSL_IR_SWIZZLE ] = "HLSL_IR_SWIZZLE",
[HLSL_IR_STATEBLOCK_CONSTANT] = "HLSL_IR_STATEBLOCK_CONSTANT",
};
if (type >= ARRAY_SIZE(names))
@ -2544,7 +2717,7 @@ const char *hlsl_jump_type_to_string(enum hlsl_ir_jump_type type)
[HLSL_IR_JUMP_RETURN] = "HLSL_IR_JUMP_RETURN",
};
assert(type < ARRAY_SIZE(names));
VKD3D_ASSERT(type < ARRAY_SIZE(names));
return names[type];
}
@ -2634,7 +2807,7 @@ const char *debug_hlsl_writemask(unsigned int writemask)
char string[5];
unsigned int i = 0, pos = 0;
assert(!(writemask & ~VKD3DSP_WRITEMASK_ALL));
VKD3D_ASSERT(!(writemask & ~VKD3DSP_WRITEMASK_ALL));
while (writemask)
{
@ -2653,7 +2826,7 @@ const char *debug_hlsl_swizzle(uint32_t swizzle, unsigned int size)
char string[5];
unsigned int i;
assert(size <= ARRAY_SIZE(components));
VKD3D_ASSERT(size <= ARRAY_SIZE(components));
for (i = 0; i < size; ++i)
string[i] = components[hlsl_swizzle_get_component(swizzle, i)];
string[size] = 0;
@ -2735,6 +2908,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op)
static const char *const op_names[] =
{
[HLSL_OP0_VOID] = "void",
[HLSL_OP0_RASTERIZER_SAMPLE_COUNT] = "GetRenderTargetSampleCount",
[HLSL_OP1_ABS] = "abs",
[HLSL_OP1_BIT_NOT] = "~",
@ -2749,6 +2923,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op)
[HLSL_OP1_DSY_COARSE] = "dsy_coarse",
[HLSL_OP1_DSY_FINE] = "dsy_fine",
[HLSL_OP1_EXP2] = "exp2",
[HLSL_OP1_F16TOF32] = "f16tof32",
[HLSL_OP1_FLOOR] = "floor",
[HLSL_OP1_FRACT] = "fract",
[HLSL_OP1_LOG2] = "log2",
@ -2790,6 +2965,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op)
[HLSL_OP3_CMP] = "cmp",
[HLSL_OP3_DP2ADD] = "dp2add",
[HLSL_OP3_TERNARY] = "ternary",
[HLSL_OP3_MAD] = "mad",
};
return op_names[op];
@ -2875,7 +3051,7 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru
[HLSL_RESOURCE_RESINFO] = "resinfo",
};
assert(load->load_type < ARRAY_SIZE(type_names));
VKD3D_ASSERT(load->load_type < ARRAY_SIZE(type_names));
vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[load->load_type]);
dump_deref(buffer, &load->resource);
vkd3d_string_buffer_printf(buffer, ", sampler = ");
@ -2929,6 +3105,11 @@ static void dump_ir_resource_store(struct vkd3d_string_buffer *buffer, const str
vkd3d_string_buffer_printf(buffer, ")");
}
static void dump_ir_string(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_string_constant *string)
{
vkd3d_string_buffer_printf(buffer, "\"%s\"", debugstr_a(string->string));
}
static void dump_ir_store(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_store *store)
{
vkd3d_string_buffer_printf(buffer, "= (");
@ -3048,6 +3229,10 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer,
dump_ir_resource_store(buffer, hlsl_ir_resource_store(instr));
break;
case HLSL_IR_STRING_CONSTANT:
dump_ir_string(buffer, hlsl_ir_string_constant(instr));
break;
case HLSL_IR_STORE:
dump_ir_store(buffer, hlsl_ir_store(instr));
break;
@ -3086,12 +3271,45 @@ void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl
vkd3d_string_buffer_cleanup(&buffer);
}
void hlsl_dump_var_default_values(const struct hlsl_ir_var *var)
{
unsigned int k, component_count = hlsl_type_component_count(var->data_type);
struct vkd3d_string_buffer buffer;
vkd3d_string_buffer_init(&buffer);
if (!var->default_values)
{
vkd3d_string_buffer_printf(&buffer, "var \"%s\" has no default values.\n", var->name);
vkd3d_string_buffer_trace(&buffer);
vkd3d_string_buffer_cleanup(&buffer);
return;
}
vkd3d_string_buffer_printf(&buffer, "var \"%s\" default values:", var->name);
for (k = 0; k < component_count; ++k)
{
bool is_string = var->default_values[k].string;
if (k % 4 == 0 || is_string)
vkd3d_string_buffer_printf(&buffer, "\n ");
if (is_string)
vkd3d_string_buffer_printf(&buffer, " %s", debugstr_a(var->default_values[k].string));
else
vkd3d_string_buffer_printf(&buffer, " 0x%08x", var->default_values[k].number.u);
}
vkd3d_string_buffer_printf(&buffer, "\n");
vkd3d_string_buffer_trace(&buffer);
vkd3d_string_buffer_cleanup(&buffer);
}
void hlsl_replace_node(struct hlsl_ir_node *old, struct hlsl_ir_node *new)
{
struct hlsl_src *src, *next;
assert(old->data_type->dimx == new->data_type->dimx);
assert(old->data_type->dimy == new->data_type->dimy);
VKD3D_ASSERT(old->data_type->dimx == new->data_type->dimx);
VKD3D_ASSERT(old->data_type->dimy == new->data_type->dimy);
LIST_FOR_EACH_ENTRY_SAFE(src, next, &old->uses, struct hlsl_src, entry)
{
@ -3199,6 +3417,12 @@ static void free_ir_resource_load(struct hlsl_ir_resource_load *load)
vkd3d_free(load);
}
static void free_ir_string_constant(struct hlsl_ir_string_constant *string)
{
vkd3d_free(string->string);
vkd3d_free(string);
}
static void free_ir_resource_store(struct hlsl_ir_resource_store *store)
{
hlsl_cleanup_deref(&store->resource);
@ -3243,7 +3467,7 @@ static void free_ir_stateblock_constant(struct hlsl_ir_stateblock_constant *cons
void hlsl_free_instr(struct hlsl_ir_node *node)
{
assert(list_empty(&node->uses));
VKD3D_ASSERT(list_empty(&node->uses));
switch (node->type)
{
@ -3283,6 +3507,10 @@ void hlsl_free_instr(struct hlsl_ir_node *node)
free_ir_resource_load(hlsl_ir_resource_load(node));
break;
case HLSL_IR_STRING_CONSTANT:
free_ir_string_constant(hlsl_ir_string_constant(node));
break;
case HLSL_IR_RESOURCE_STORE:
free_ir_resource_store(hlsl_ir_resource_store(node));
break;
@ -3319,9 +3547,25 @@ void hlsl_free_attribute(struct hlsl_attribute *attr)
void hlsl_cleanup_semantic(struct hlsl_semantic *semantic)
{
vkd3d_free((void *)semantic->name);
vkd3d_free((void *)semantic->raw_name);
memset(semantic, 0, sizeof(*semantic));
}
bool hlsl_clone_semantic(struct hlsl_ctx *ctx, struct hlsl_semantic *dst, const struct hlsl_semantic *src)
{
*dst = *src;
dst->name = dst->raw_name = NULL;
if (src->name && !(dst->name = hlsl_strdup(ctx, src->name)))
return false;
if (src->raw_name && !(dst->raw_name = hlsl_strdup(ctx, src->raw_name)))
{
hlsl_cleanup_semantic(dst);
return false;
}
return true;
}
static void free_function_decl(struct hlsl_ir_function_decl *decl)
{
unsigned int i;
@ -3711,14 +3955,23 @@ static void declare_predefined_types(struct hlsl_ctx *ctx)
}
ctx->builtin_types.Void = hlsl_new_simple_type(ctx, "void", HLSL_CLASS_VOID);
ctx->builtin_types.null = hlsl_new_type(ctx, "NULL", HLSL_CLASS_NULL, HLSL_TYPE_UINT, 1, 1);
ctx->builtin_types.string = hlsl_new_simple_type(ctx, "string", HLSL_CLASS_STRING);
hlsl_scope_add_type(ctx->globals, ctx->builtin_types.string);
hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "DepthStencilView", HLSL_CLASS_DEPTH_STENCIL_VIEW));
hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "DepthStencilState", HLSL_CLASS_DEPTH_STENCIL_STATE));
hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "fxgroup", HLSL_CLASS_EFFECT_GROUP));
hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "pass", HLSL_CLASS_PASS));
hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "pixelshader", HLSL_CLASS_PIXEL_SHADER));
hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "RasterizerState", HLSL_CLASS_RASTERIZER_STATE));
hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "RenderTargetView", HLSL_CLASS_RENDER_TARGET_VIEW));
hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "STRING", HLSL_CLASS_STRING));
hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "texture", HLSL_CLASS_TEXTURE));
hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "vertexshader", HLSL_CLASS_VERTEX_SHADER));
hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "ComputeShader", HLSL_CLASS_COMPUTE_SHADER));
hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "DomainShader", HLSL_CLASS_DOMAIN_SHADER));
hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "HullShader", HLSL_CLASS_HULL_SHADER));
hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "GeometryShader", HLSL_CLASS_GEOMETRY_SHADER));
hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "BlendState", HLSL_CLASS_BLEND_STATE));
for (i = 0; i < ARRAY_SIZE(effect_types); ++i)
{
@ -4049,6 +4302,7 @@ struct hlsl_ir_function_decl *hlsl_compile_internal_function(struct hlsl_ctx *ct
/* Save and restore everything that matters.
* Note that saving the scope stack is hard, and shouldn't be necessary. */
hlsl_push_scope(ctx);
ctx->scanner = NULL;
ctx->internal_func_name = internal_name->buffer;
ctx->cur_function = NULL;
@ -4056,6 +4310,7 @@ struct hlsl_ir_function_decl *hlsl_compile_internal_function(struct hlsl_ctx *ct
ctx->scanner = saved_scanner;
ctx->internal_func_name = saved_internal_func_name;
ctx->cur_function = saved_cur_function;
hlsl_pop_scope(ctx);
if (ret)
{
ERR("Failed to compile intrinsic, error %u.\n", ret);

View file

@ -78,10 +78,12 @@ enum hlsl_type_class
HLSL_CLASS_LAST_NUMERIC = HLSL_CLASS_MATRIX,
HLSL_CLASS_STRUCT,
HLSL_CLASS_ARRAY,
HLSL_CLASS_DEPTH_STENCIL_STATE,
HLSL_CLASS_DEPTH_STENCIL_VIEW,
HLSL_CLASS_EFFECT_GROUP,
HLSL_CLASS_PASS,
HLSL_CLASS_PIXEL_SHADER,
HLSL_CLASS_RASTERIZER_STATE,
HLSL_CLASS_RENDER_TARGET_VIEW,
HLSL_CLASS_SAMPLER,
HLSL_CLASS_STRING,
@ -89,7 +91,14 @@ enum hlsl_type_class
HLSL_CLASS_TEXTURE,
HLSL_CLASS_UAV,
HLSL_CLASS_VERTEX_SHADER,
HLSL_CLASS_COMPUTE_SHADER,
HLSL_CLASS_DOMAIN_SHADER,
HLSL_CLASS_HULL_SHADER,
HLSL_CLASS_GEOMETRY_SHADER,
HLSL_CLASS_CONSTANT_BUFFER,
HLSL_CLASS_BLEND_STATE,
HLSL_CLASS_VOID,
HLSL_CLASS_NULL,
};
enum hlsl_base_type
@ -222,6 +231,8 @@ struct hlsl_semantic
const char *name;
uint32_t index;
/* Name exactly as it appears in the sources. */
const char *raw_name;
/* If the variable or field that stores this hlsl_semantic has already reported that it is missing. */
bool reported_missing;
/* In case the variable or field that stores this semantic has already reported to use a
@ -259,8 +270,20 @@ struct hlsl_struct_field
* struct. */
struct hlsl_reg
{
/* Index of the first register allocated. */
/* Register number of the first register allocated. */
uint32_t id;
/* For descriptors (buffer, texture, sampler, UAV) this is the base binding
* index of the descriptor.
* For 5.1 and above descriptors have space and may be arrayed, in which
* case the array shares a single register ID but has a range of register
* indices, and "id" and "index" are as a rule not equal.
* For versions below 5.1, the register number for descriptors is the same
* as its external binding index, so only "index" is used, and "id" is
* ignored.
* For numeric registers "index" is not used. */
uint32_t index;
/* Register space of a descriptor. Not used for numeric registers. */
uint32_t space;
/* Number of registers to be allocated.
* Unlike the variable's type's regsize, it is not expressed in register components, but rather
* in whole registers, and may depend on which components are used within the shader. */
@ -289,6 +312,7 @@ enum hlsl_ir_node_type
HLSL_IR_JUMP,
HLSL_IR_RESOURCE_LOAD,
HLSL_IR_RESOURCE_STORE,
HLSL_IR_STRING_CONSTANT,
HLSL_IR_STORE,
HLSL_IR_SWIZZLE,
HLSL_IR_SWITCH,
@ -371,6 +395,7 @@ struct hlsl_attribute
#define HLSL_STORAGE_LINEAR 0x00010000
#define HLSL_MODIFIER_SINGLE 0x00020000
#define HLSL_MODIFIER_EXPORT 0x00040000
#define HLSL_STORAGE_ANNOTATION 0x00080000
#define HLSL_TYPE_MODIFIERS_MASK (HLSL_MODIFIER_PRECISE | HLSL_MODIFIER_VOLATILE | \
HLSL_MODIFIER_CONST | HLSL_MODIFIER_ROW_MAJOR | \
@ -385,7 +410,7 @@ struct hlsl_attribute
/* Reservation of a register and/or an offset for objects inside constant buffers, to be used as a
* starting point of their allocation. They are available through the register(·) and the
* packoffset(·) syntaxes, respectivelly.
* packoffset(·) syntaxes, respectively.
* The constant buffer offset is measured register components. */
struct hlsl_reg_reservation
{
@ -396,6 +421,14 @@ struct hlsl_reg_reservation
unsigned int offset_index;
};
union hlsl_constant_value_component
{
uint32_t u;
int32_t i;
float f;
double d;
};
struct hlsl_ir_var
{
struct hlsl_type *data_type;
@ -418,6 +451,17 @@ struct hlsl_ir_var
/* Scope that contains annotations for this variable. */
struct hlsl_scope *annotations;
/* Array of default values the variable was initialized with, one for each component.
* Only for variables that need it, such as uniforms and variables inside constant buffers.
* This pointer is NULL for others. */
struct hlsl_default_value
{
/* Default value, in case the component is a string, otherwise it is NULL. */
const char *string;
/* Default value, in case the component is a numeric value. */
union hlsl_constant_value_component number;
} *default_values;
/* A dynamic array containing the state block on the variable's declaration, if any.
* An array variable may contain multiple state blocks.
* A technique pass will always contain one.
@ -460,6 +504,8 @@ struct hlsl_ir_var
uint32_t is_uniform : 1;
uint32_t is_param : 1;
uint32_t is_separated_resource : 1;
uint32_t is_synthetic : 1;
uint32_t has_explicit_bind_point : 1;
};
/* This struct is used to represent assignments in state block entries:
@ -470,22 +516,31 @@ struct hlsl_ir_var
* name[lhs_index] = args[0]
* - or -
* name[lhs_index] = {args[0], args[1], ...};
*
* This struct also represents function call syntax:
* name(args[0], args[1], ...)
*/
struct hlsl_state_block_entry
{
/* For assignments, the name in the lhs. */
/* Whether this entry is a function call. */
bool is_function_call;
/* For assignments, the name in the lhs.
* For functions, the name of the function. */
char *name;
/* Resolved format-specific property identifier. */
unsigned int name_id;
/* Whether the lhs in the assignment is indexed and, in that case, its index. */
/* For assignments, whether the lhs of an assignment is indexed and, in
* that case, its index. */
bool lhs_has_index;
unsigned int lhs_index;
/* Instructions present in the rhs. */
/* Instructions present in the rhs or the function arguments. */
struct hlsl_block *instrs;
/* For assignments, arguments of the rhs initializer. */
/* For assignments, arguments of the rhs initializer.
* For function calls, the arguments themselves. */
struct hlsl_src *args;
unsigned int args_count;
};
@ -556,12 +611,21 @@ struct hlsl_ir_if
struct hlsl_block else_block;
};
enum hlsl_ir_loop_unroll_type
{
HLSL_IR_LOOP_UNROLL,
HLSL_IR_LOOP_FORCE_UNROLL,
HLSL_IR_LOOP_FORCE_LOOP
};
struct hlsl_ir_loop
{
struct hlsl_ir_node node;
/* loop condition is stored in the body (as "if (!condition) break;") */
struct hlsl_block body;
unsigned int next_index; /* liveness index of the end of the loop */
unsigned int unroll_limit;
enum hlsl_ir_loop_unroll_type unroll_type;
};
struct hlsl_ir_switch_case
@ -583,13 +647,14 @@ struct hlsl_ir_switch
enum hlsl_ir_expr_op
{
HLSL_OP0_VOID,
HLSL_OP0_RASTERIZER_SAMPLE_COUNT,
HLSL_OP1_ABS,
HLSL_OP1_BIT_NOT,
HLSL_OP1_CAST,
HLSL_OP1_CEIL,
HLSL_OP1_COS,
HLSL_OP1_COS_REDUCED, /* Reduced range [-pi, pi] */
HLSL_OP1_COS_REDUCED, /* Reduced range [-pi, pi], writes to .x */
HLSL_OP1_DSX,
HLSL_OP1_DSX_COARSE,
HLSL_OP1_DSX_FINE,
@ -597,6 +662,7 @@ enum hlsl_ir_expr_op
HLSL_OP1_DSY_COARSE,
HLSL_OP1_DSY_FINE,
HLSL_OP1_EXP2,
HLSL_OP1_F16TOF32,
HLSL_OP1_FLOOR,
HLSL_OP1_FRACT,
HLSL_OP1_LOG2,
@ -610,7 +676,7 @@ enum hlsl_ir_expr_op
HLSL_OP1_SAT,
HLSL_OP1_SIGN,
HLSL_OP1_SIN,
HLSL_OP1_SIN_REDUCED, /* Reduced range [-pi, pi] */
HLSL_OP1_SIN_REDUCED, /* Reduced range [-pi, pi], writes to .y */
HLSL_OP1_SQRT,
HLSL_OP1_TRUNC,
@ -643,6 +709,7 @@ enum hlsl_ir_expr_op
* CMP(a, b, c) returns 'b' if 'a' >= 0, and 'c' otherwise. It's used only for SM1-SM3 targets. */
HLSL_OP3_CMP,
HLSL_OP3_TERNARY,
HLSL_OP3_MAD,
};
#define HLSL_MAX_OPERANDS 3
@ -775,18 +842,18 @@ struct hlsl_ir_constant
struct hlsl_ir_node node;
struct hlsl_constant_value
{
union hlsl_constant_value_component
{
uint32_t u;
int32_t i;
float f;
double d;
} u[4];
union hlsl_constant_value_component u[4];
} value;
/* Constant register of type 'c' where the constant value is stored for SM1. */
struct hlsl_reg reg;
};
struct hlsl_ir_string_constant
{
struct hlsl_ir_node node;
char *string;
};
/* Stateblock constants are undeclared values found on state blocks or technique passes descriptions,
* that do not concern regular pixel, vertex, or compute shaders, except for parsing. */
struct hlsl_ir_stateblock_constant
@ -811,6 +878,8 @@ struct hlsl_scope
bool loop;
/* The scope was created for the switch statement. */
bool _switch;
/* The scope contains annotation variables. */
bool annotations;
};
struct hlsl_profile_info
@ -931,7 +1000,9 @@ struct hlsl_ctx
/* matrix[HLSL_TYPE_FLOAT][1][3] is a float4x2, i.e. dimx = 2, dimy = 4 */
struct hlsl_type *matrix[HLSL_TYPE_LAST_SCALAR + 1][4][4];
struct hlsl_type *sampler[HLSL_SAMPLER_DIM_LAST_SAMPLER + 1];
struct hlsl_type *string;
struct hlsl_type *Void;
struct hlsl_type *null;
} builtin_types;
/* List of the instruction nodes for initializing static variables. */
@ -948,6 +1019,8 @@ struct hlsl_ctx
} *regs;
size_t count, size;
} constant_defs;
/* 'c' registers where the constants expected by SM2 sincos are stored. */
struct hlsl_reg d3dsincosconst1, d3dsincosconst2;
/* Number of temp. registers required for the shader to run, i.e. the largest temp register
* index that will be used in the output bytecode (+1). */
uint32_t temp_count;
@ -994,85 +1067,91 @@ struct hlsl_resource_load_params
static inline struct hlsl_ir_call *hlsl_ir_call(const struct hlsl_ir_node *node)
{
assert(node->type == HLSL_IR_CALL);
VKD3D_ASSERT(node->type == HLSL_IR_CALL);
return CONTAINING_RECORD(node, struct hlsl_ir_call, node);
}
static inline struct hlsl_ir_constant *hlsl_ir_constant(const struct hlsl_ir_node *node)
{
assert(node->type == HLSL_IR_CONSTANT);
VKD3D_ASSERT(node->type == HLSL_IR_CONSTANT);
return CONTAINING_RECORD(node, struct hlsl_ir_constant, node);
}
static inline struct hlsl_ir_string_constant *hlsl_ir_string_constant(const struct hlsl_ir_node *node)
{
VKD3D_ASSERT(node->type == HLSL_IR_STRING_CONSTANT);
return CONTAINING_RECORD(node, struct hlsl_ir_string_constant, node);
}
static inline struct hlsl_ir_expr *hlsl_ir_expr(const struct hlsl_ir_node *node)
{
assert(node->type == HLSL_IR_EXPR);
VKD3D_ASSERT(node->type == HLSL_IR_EXPR);
return CONTAINING_RECORD(node, struct hlsl_ir_expr, node);
}
static inline struct hlsl_ir_if *hlsl_ir_if(const struct hlsl_ir_node *node)
{
assert(node->type == HLSL_IR_IF);
VKD3D_ASSERT(node->type == HLSL_IR_IF);
return CONTAINING_RECORD(node, struct hlsl_ir_if, node);
}
static inline struct hlsl_ir_jump *hlsl_ir_jump(const struct hlsl_ir_node *node)
{
assert(node->type == HLSL_IR_JUMP);
VKD3D_ASSERT(node->type == HLSL_IR_JUMP);
return CONTAINING_RECORD(node, struct hlsl_ir_jump, node);
}
static inline struct hlsl_ir_load *hlsl_ir_load(const struct hlsl_ir_node *node)
{
assert(node->type == HLSL_IR_LOAD);
VKD3D_ASSERT(node->type == HLSL_IR_LOAD);
return CONTAINING_RECORD(node, struct hlsl_ir_load, node);
}
static inline struct hlsl_ir_loop *hlsl_ir_loop(const struct hlsl_ir_node *node)
{
assert(node->type == HLSL_IR_LOOP);
VKD3D_ASSERT(node->type == HLSL_IR_LOOP);
return CONTAINING_RECORD(node, struct hlsl_ir_loop, node);
}
static inline struct hlsl_ir_resource_load *hlsl_ir_resource_load(const struct hlsl_ir_node *node)
{
assert(node->type == HLSL_IR_RESOURCE_LOAD);
VKD3D_ASSERT(node->type == HLSL_IR_RESOURCE_LOAD);
return CONTAINING_RECORD(node, struct hlsl_ir_resource_load, node);
}
static inline struct hlsl_ir_resource_store *hlsl_ir_resource_store(const struct hlsl_ir_node *node)
{
assert(node->type == HLSL_IR_RESOURCE_STORE);
VKD3D_ASSERT(node->type == HLSL_IR_RESOURCE_STORE);
return CONTAINING_RECORD(node, struct hlsl_ir_resource_store, node);
}
static inline struct hlsl_ir_store *hlsl_ir_store(const struct hlsl_ir_node *node)
{
assert(node->type == HLSL_IR_STORE);
VKD3D_ASSERT(node->type == HLSL_IR_STORE);
return CONTAINING_RECORD(node, struct hlsl_ir_store, node);
}
static inline struct hlsl_ir_swizzle *hlsl_ir_swizzle(const struct hlsl_ir_node *node)
{
assert(node->type == HLSL_IR_SWIZZLE);
VKD3D_ASSERT(node->type == HLSL_IR_SWIZZLE);
return CONTAINING_RECORD(node, struct hlsl_ir_swizzle, node);
}
static inline struct hlsl_ir_index *hlsl_ir_index(const struct hlsl_ir_node *node)
{
assert(node->type == HLSL_IR_INDEX);
VKD3D_ASSERT(node->type == HLSL_IR_INDEX);
return CONTAINING_RECORD(node, struct hlsl_ir_index, node);
}
static inline struct hlsl_ir_switch *hlsl_ir_switch(const struct hlsl_ir_node *node)
{
assert(node->type == HLSL_IR_SWITCH);
VKD3D_ASSERT(node->type == HLSL_IR_SWITCH);
return CONTAINING_RECORD(node, struct hlsl_ir_switch, node);
}
static inline struct hlsl_ir_stateblock_constant *hlsl_ir_stateblock_constant(const struct hlsl_ir_node *node)
{
assert(node->type == HLSL_IR_STATEBLOCK_CONSTANT);
VKD3D_ASSERT(node->type == HLSL_IR_STATEBLOCK_CONSTANT);
return CONTAINING_RECORD(node, struct hlsl_ir_stateblock_constant, node);
}
@ -1249,6 +1328,13 @@ void hlsl_block_cleanup(struct hlsl_block *block);
bool hlsl_clone_block(struct hlsl_ctx *ctx, struct hlsl_block *dst_block, const struct hlsl_block *src_block);
void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *func);
void hlsl_dump_var_default_values(const struct hlsl_ir_var *var);
bool hlsl_validate_state_block_entry(struct hlsl_ctx *ctx, struct hlsl_state_block_entry *entry,
const struct vkd3d_shader_location *loc);
struct hlsl_state_block_entry *clone_stateblock_entry(struct hlsl_ctx *ctx,
struct hlsl_state_block_entry *src, const char *name, bool lhs_has_index,
unsigned int lhs_index, unsigned int arg_index);
void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body);
int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func,
@ -1259,7 +1345,9 @@ bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *d
bool hlsl_copy_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, const struct hlsl_deref *other);
void hlsl_cleanup_deref(struct hlsl_deref *deref);
void hlsl_cleanup_semantic(struct hlsl_semantic *semantic);
bool hlsl_clone_semantic(struct hlsl_ctx *ctx, struct hlsl_semantic *dst, const struct hlsl_semantic *src);
void hlsl_cleanup_ir_switch_cases(struct list *cases);
void hlsl_free_ir_switch_case(struct hlsl_ir_switch_case *c);
@ -1270,6 +1358,7 @@ void hlsl_free_attribute(struct hlsl_attribute *attr);
void hlsl_free_instr(struct hlsl_ir_node *node);
void hlsl_free_instr_list(struct list *list);
void hlsl_free_state_block(struct hlsl_state_block *state_block);
void hlsl_free_state_block_entry(struct hlsl_state_block_entry *state_block_entry);
void hlsl_free_type(struct hlsl_type *type);
void hlsl_free_var(struct hlsl_ir_var *decl);
@ -1342,7 +1431,7 @@ 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);
struct hlsl_ir_node *hlsl_new_loop(struct hlsl_ctx *ctx,
struct hlsl_block *block, const struct vkd3d_shader_location *loc);
struct hlsl_block *block, enum hlsl_ir_loop_unroll_type unroll_type, unsigned int unroll_limit, const struct vkd3d_shader_location *loc);
struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx,
const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc);
struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, const struct hlsl_deref *resource,
@ -1353,6 +1442,8 @@ struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned
struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc);
struct hlsl_ir_node *hlsl_new_stateblock_constant(struct hlsl_ctx *ctx, const char *name,
struct vkd3d_shader_location *loc);
struct hlsl_ir_node *hlsl_new_string_constant(struct hlsl_ctx *ctx, const char *str,
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);
struct hlsl_ir_var *hlsl_new_synthetic_var_named(struct hlsl_ctx *ctx, const char *name,
@ -1361,8 +1452,10 @@ struct hlsl_type *hlsl_new_texture_type(struct hlsl_ctx *ctx, enum hlsl_sampler_
unsigned int sample_count);
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 *hlsl_new_cb_type(struct hlsl_ctx *ctx, struct hlsl_type *format);
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_null_constant(struct hlsl_ctx *ctx, 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,
@ -1432,10 +1525,16 @@ bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx,
D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type);
D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type);
bool hlsl_sm1_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic,
bool output, D3DSHADER_PARAM_REGISTER_TYPE *type, unsigned int *reg);
bool hlsl_sm1_usage_from_semantic(const struct hlsl_semantic *semantic, D3DDECLUSAGE *usage, uint32_t *usage_idx);
int hlsl_sm1_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out);
bool hlsl_sm1_register_from_semantic(const struct vkd3d_shader_version *version, const char *semantic_name,
unsigned int semantic_index, bool output, enum vkd3d_shader_register_type *type, unsigned int *reg);
bool hlsl_sm1_usage_from_semantic(const char *semantic_name,
uint32_t semantic_index, D3DDECLUSAGE *usage, uint32_t *usage_idx);
void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer);
int d3dbc_compile(struct vsir_program *program, uint64_t config_flags,
const struct vkd3d_shader_compile_info *compile_info, const struct vkd3d_shader_code *ctab,
struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context,
struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func);
bool hlsl_sm4_usage_from_semantic(struct hlsl_ctx *ctx,
const struct hlsl_semantic *semantic, bool output, D3D_NAME *usage);

View file

@ -29,6 +29,8 @@
static void update_location(struct hlsl_ctx *ctx, YYLTYPE *loc);
static void apply_escape_sequences(char *str);
#define YY_USER_ACTION update_location(yyget_extra(yyscanner), yyget_lloc(yyscanner));
%}
@ -49,11 +51,11 @@ static void update_location(struct hlsl_ctx *ctx, YYLTYPE *loc);
RESERVED1 auto|catch|char|class|const_cast|delete|dynamic_cast|enum
RESERVED2 explicit|friend|goto|long|mutable|new|operator|private|protected|public
RESERVED3 reinterpret_cast|short|signed|sizeof|static_cast|template|this|throw|try
RESERVED4 typename|union|unsigned|using|virtual
RESERVED4 typename|union|using|virtual
WS [ \t]
NEWLINE (\n)|(\r\n)
STRING \"[^\"]*\"
STRING \"([^\"\\]|\\.)*\"
IDENTIFIER [A-Za-z_][A-Za-z0-9_]*
ANY (.)
@ -105,6 +107,7 @@ matrix {return KW_MATRIX; }
namespace {return KW_NAMESPACE; }
nointerpolation {return KW_NOINTERPOLATION; }
noperspective {return KW_NOPERSPECTIVE; }
NULL {return KW_NULL; }
out {return KW_OUT; }
packoffset {return KW_PACKOFFSET; }
pass {return KW_PASS; }
@ -142,6 +145,7 @@ stateblock {return KW_STATEBLOCK; }
stateblock_state {return KW_STATEBLOCK_STATE; }
static {return KW_STATIC; }
string {return KW_STRING; }
String {return KW_STRING; }
struct {return KW_STRUCT; }
switch {return KW_SWITCH; }
tbuffer {return KW_TBUFFER; }
@ -164,6 +168,7 @@ textureCUBE {return KW_TEXTURECUBE; }
TextureCubeArray {return KW_TEXTURECUBEARRAY; }
true {return KW_TRUE; }
typedef {return KW_TYPEDEF; }
unsigned {return KW_UNSIGNED; }
uniform {return KW_UNIFORM; }
vector {return KW_VECTOR; }
VertexShader {return KW_VERTEXSHADER; }
@ -197,7 +202,9 @@ while {return KW_WHILE; }
struct hlsl_ctx *ctx = yyget_extra(yyscanner);
yylval->name = hlsl_strdup(ctx, yytext);
if (hlsl_get_var(ctx->cur_scope, yytext) || hlsl_get_function(ctx, yytext))
if (hlsl_version_ge(ctx, 5, 1) && !strcmp(yytext, "ConstantBuffer"))
return KW_CONSTANTBUFFER;
else if (hlsl_get_var(ctx->cur_scope, yytext) || hlsl_get_function(ctx, yytext))
return VAR_IDENTIFIER;
else if (hlsl_get_type(ctx->cur_scope, yytext, true, true))
return TYPE_IDENTIFIER;
@ -205,6 +212,16 @@ while {return KW_WHILE; }
return NEW_IDENTIFIER;
}
{STRING} {
struct hlsl_ctx *ctx = yyget_extra(yyscanner);
char *string = hlsl_strdup(ctx, yytext + 1);
string[strlen(string) - 1] = 0;
apply_escape_sequences(string);
yylval->name = string;
return STRING;
}
[0-9]*\.[0-9]+([eE][+-]?[0-9]+)?[h|H|f|F]? {
yylval->floatval = atof(yytext);
return C_FLOAT;
@ -289,6 +306,7 @@ while {return KW_WHILE; }
BEGIN(pp_ignore);
string[strlen(string) - 1] = 0;
apply_escape_sequences(string);
yylval->name = string;
return STRING;
}
@ -338,3 +356,115 @@ int hlsl_lexer_compile(struct hlsl_ctx *ctx, const struct vkd3d_shader_code *hls
yylex_destroy(ctx->scanner);
return ret;
}
static void apply_escape_sequences(char *str)
{
unsigned int i = 0, k = 0, r;
while (str[i])
{
unsigned char v = 0;
if (str[i] != '\\')
{
str[k++] = str[i];
++i;
continue;
}
++i;
VKD3D_ASSERT(str[i]);
if ('0' <= str[i] && str[i] <= '7')
{
/* octal, up to 3 digits. */
for (r = 0; r < 3; ++r)
{
char c = str[i];
if ('0' <= c && c <= '7')
{
v = v << 3;
v += c - '0';
++i;
}
else
break;
}
str[k++] = v;
continue;
}
if (str[i] == 'x')
{
bool number = false;
/* hexadecimal */
++i;
while (1)
{
char c = str[i];
if ('0' <= c && c <= '9')
{
v = v << 4;
v += c - '0';
number = true;
++i;
}
else if ('a' <= c && c <= 'f')
{
v = v << 4;
v += c - 'a' + 10;
number = true;
++i;
}
else if ('A' <= c && c <= 'F')
{
v = v << 4;
v += c - 'A' + 10;
number = true;
++i;
}
else
break;
}
if (number)
str[k++] = v;
else
str[k++] = 'x';
continue;
}
switch (str[i])
{
case 'a':
str[k++] = '\a';
break;
case 'b':
str[k++] = '\b';
break;
case 'f':
str[k++] = '\f';
break;
case 'n':
str[k++] = '\n';
break;
case 'r':
str[k++] = '\r';
break;
case 't':
str[k++] = '\t';
break;
case 'v':
str[k++] = '\v';
break;
default:
str[k++] = str[i];
break;
}
++i;
}
str[k++] = '\0';
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -28,7 +28,7 @@ static bool fold_abs(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
enum hlsl_base_type type = dst_type->e.numeric.type;
unsigned int k;
assert(type == src->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src->node.data_type->e.numeric.type);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -119,7 +119,7 @@ static bool fold_bit_not(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
enum hlsl_base_type type = dst_type->e.numeric.type;
unsigned int k;
assert(type == src->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src->node.data_type->e.numeric.type);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -234,7 +234,7 @@ static bool fold_ceil(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
enum hlsl_base_type type = dst_type->e.numeric.type;
unsigned int k;
assert(type == src->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src->node.data_type->e.numeric.type);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -260,7 +260,7 @@ static bool fold_exp2(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
enum hlsl_base_type type = dst_type->e.numeric.type;
unsigned int k;
assert(type == src->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src->node.data_type->e.numeric.type);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -286,7 +286,7 @@ static bool fold_floor(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
enum hlsl_base_type type = dst_type->e.numeric.type;
unsigned int k;
assert(type == src->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src->node.data_type->e.numeric.type);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -313,7 +313,7 @@ static bool fold_fract(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
unsigned int k;
float i;
assert(type == src->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src->node.data_type->e.numeric.type);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -339,7 +339,7 @@ static bool fold_log2(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, con
enum hlsl_base_type type = dst_type->e.numeric.type;
unsigned int k;
assert(type == src->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src->node.data_type->e.numeric.type);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -384,7 +384,7 @@ static bool fold_neg(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
enum hlsl_base_type type = dst_type->e.numeric.type;
unsigned int k;
assert(type == src->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src->node.data_type->e.numeric.type);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -418,7 +418,7 @@ static bool fold_not(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
enum hlsl_base_type type = dst_type->e.numeric.type;
unsigned int k;
assert(type == src->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src->node.data_type->e.numeric.type);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -442,7 +442,7 @@ static bool fold_rcp(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons
enum hlsl_base_type type = dst_type->e.numeric.type;
unsigned int k;
assert(type == src->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src->node.data_type->e.numeric.type);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -487,7 +487,7 @@ static bool fold_rsq(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons
enum hlsl_base_type type = dst_type->e.numeric.type;
unsigned int k;
assert(type == src->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src->node.data_type->e.numeric.type);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -527,7 +527,7 @@ static bool fold_sat(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons
enum hlsl_base_type type = dst_type->e.numeric.type;
unsigned int k;
assert(type == src->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src->node.data_type->e.numeric.type);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -553,7 +553,7 @@ static bool fold_sqrt(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, con
enum hlsl_base_type type = dst_type->e.numeric.type;
unsigned int k;
assert(type == src->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src->node.data_type->e.numeric.type);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -598,8 +598,8 @@ static bool fold_add(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons
enum hlsl_base_type type = dst_type->e.numeric.type;
unsigned int k;
assert(type == src1->node.data_type->e.numeric.type);
assert(type == src2->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src1->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src2->node.data_type->e.numeric.type);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -635,8 +635,8 @@ static bool fold_and(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons
enum hlsl_base_type type = dst_type->e.numeric.type;
unsigned int k;
assert(type == src1->node.data_type->e.numeric.type);
assert(type == src2->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src1->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src2->node.data_type->e.numeric.type);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -662,8 +662,8 @@ static bool fold_or(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const
enum hlsl_base_type type = dst_type->e.numeric.type;
unsigned int k;
assert(type == src1->node.data_type->e.numeric.type);
assert(type == src2->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src1->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src2->node.data_type->e.numeric.type);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -689,8 +689,8 @@ static bool fold_bit_xor(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
enum hlsl_base_type type = dst_type->e.numeric.type;
unsigned int k;
assert(type == src1->node.data_type->e.numeric.type);
assert(type == src2->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src1->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src2->node.data_type->e.numeric.type);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -715,9 +715,9 @@ static bool fold_dot(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons
enum hlsl_base_type type = dst_type->e.numeric.type;
unsigned int k;
assert(type == src1->node.data_type->e.numeric.type);
assert(type == src2->node.data_type->e.numeric.type);
assert(src1->node.data_type->dimx == src2->node.data_type->dimx);
VKD3D_ASSERT(type == src1->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src2->node.data_type->e.numeric.type);
VKD3D_ASSERT(src1->node.data_type->dimx == src2->node.data_type->dimx);
dst->u[0].f = 0.0f;
for (k = 0; k < src1->node.data_type->dimx; ++k)
@ -743,11 +743,11 @@ static bool fold_dp2add(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, c
enum hlsl_base_type type = dst_type->e.numeric.type;
unsigned int k;
assert(type == src1->node.data_type->e.numeric.type);
assert(type == src2->node.data_type->e.numeric.type);
assert(type == src3->node.data_type->e.numeric.type);
assert(src1->node.data_type->dimx == src2->node.data_type->dimx);
assert(src3->node.data_type->dimx == 1);
VKD3D_ASSERT(type == src1->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src2->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src3->node.data_type->e.numeric.type);
VKD3D_ASSERT(src1->node.data_type->dimx == src2->node.data_type->dimx);
VKD3D_ASSERT(src3->node.data_type->dimx == 1);
dst->u[0].f = src3->value.u[0].f;
for (k = 0; k < src1->node.data_type->dimx; ++k)
@ -774,8 +774,8 @@ static bool fold_div(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons
enum hlsl_base_type type = dst_type->e.numeric.type;
unsigned int k;
assert(type == src1->node.data_type->e.numeric.type);
assert(type == src2->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src1->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src2->node.data_type->e.numeric.type);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -841,8 +841,8 @@ static bool fold_equal(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, co
{
unsigned int k;
assert(dst_type->e.numeric.type == HLSL_TYPE_BOOL);
assert(src1->node.data_type->e.numeric.type == src2->node.data_type->e.numeric.type);
VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL);
VKD3D_ASSERT(src1->node.data_type->e.numeric.type == src2->node.data_type->e.numeric.type);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -877,8 +877,8 @@ static bool fold_gequal(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, c
{
unsigned int k;
assert(dst_type->e.numeric.type == HLSL_TYPE_BOOL);
assert(src1->node.data_type->e.numeric.type == src2->node.data_type->e.numeric.type);
VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL);
VKD3D_ASSERT(src1->node.data_type->e.numeric.type == src2->node.data_type->e.numeric.type);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -916,8 +916,8 @@ static bool fold_less(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, con
{
unsigned int k;
assert(dst_type->e.numeric.type == HLSL_TYPE_BOOL);
assert(src1->node.data_type->e.numeric.type == src2->node.data_type->e.numeric.type);
VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL);
VKD3D_ASSERT(src1->node.data_type->e.numeric.type == src2->node.data_type->e.numeric.type);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -955,8 +955,8 @@ static bool fold_lshift(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, c
{
unsigned int k;
assert(dst_type->e.numeric.type == src1->node.data_type->e.numeric.type);
assert(src2->node.data_type->e.numeric.type == HLSL_TYPE_INT);
VKD3D_ASSERT(dst_type->e.numeric.type == src1->node.data_type->e.numeric.type);
VKD3D_ASSERT(src2->node.data_type->e.numeric.type == HLSL_TYPE_INT);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -986,8 +986,8 @@ static bool fold_max(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons
enum hlsl_base_type type = dst_type->e.numeric.type;
unsigned int k;
assert(type == src1->node.data_type->e.numeric.type);
assert(type == src2->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src1->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src2->node.data_type->e.numeric.type);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -1024,8 +1024,8 @@ static bool fold_min(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons
enum hlsl_base_type type = dst_type->e.numeric.type;
unsigned int k;
assert(type == src1->node.data_type->e.numeric.type);
assert(type == src2->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src1->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src2->node.data_type->e.numeric.type);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -1063,8 +1063,8 @@ static bool fold_mod(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons
enum hlsl_base_type type = dst_type->e.numeric.type;
unsigned int k;
assert(type == src1->node.data_type->e.numeric.type);
assert(type == src2->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src1->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src2->node.data_type->e.numeric.type);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -1105,8 +1105,8 @@ static bool fold_mul(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons
enum hlsl_base_type type = dst_type->e.numeric.type;
unsigned int k;
assert(type == src1->node.data_type->e.numeric.type);
assert(type == src2->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src1->node.data_type->e.numeric.type);
VKD3D_ASSERT(type == src2->node.data_type->e.numeric.type);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -1139,8 +1139,8 @@ static bool fold_nequal(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, c
{
unsigned int k;
assert(dst_type->e.numeric.type == HLSL_TYPE_BOOL);
assert(src1->node.data_type->e.numeric.type == src2->node.data_type->e.numeric.type);
VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL);
VKD3D_ASSERT(src1->node.data_type->e.numeric.type == src2->node.data_type->e.numeric.type);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -1175,9 +1175,9 @@ static bool fold_ternary(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
{
unsigned int k;
assert(dst_type->e.numeric.type == src2->node.data_type->e.numeric.type);
assert(dst_type->e.numeric.type == src3->node.data_type->e.numeric.type);
assert(src1->node.data_type->e.numeric.type == HLSL_TYPE_BOOL);
VKD3D_ASSERT(dst_type->e.numeric.type == src2->node.data_type->e.numeric.type);
VKD3D_ASSERT(dst_type->e.numeric.type == src3->node.data_type->e.numeric.type);
VKD3D_ASSERT(src1->node.data_type->e.numeric.type == HLSL_TYPE_BOOL);
for (k = 0; k < dst_type->dimx; ++k)
dst->u[k] = src1->value.u[k].u ? src2->value.u[k] : src3->value.u[k];
@ -1190,8 +1190,8 @@ static bool fold_rshift(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, c
{
unsigned int k;
assert(dst_type->e.numeric.type == src1->node.data_type->e.numeric.type);
assert(src2->node.data_type->e.numeric.type == HLSL_TYPE_INT);
VKD3D_ASSERT(dst_type->e.numeric.type == src1->node.data_type->e.numeric.type);
VKD3D_ASSERT(src2->node.data_type->e.numeric.type == HLSL_TYPE_INT);
for (k = 0; k < dst_type->dimx; ++k)
{
@ -1239,7 +1239,7 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
{
if (expr->operands[i].node->type != HLSL_IR_CONSTANT)
return false;
assert(expr->operands[i].node->data_type->class <= HLSL_CLASS_VECTOR);
VKD3D_ASSERT(expr->operands[i].node->data_type->class <= HLSL_CLASS_VECTOR);
}
}
arg1 = hlsl_ir_constant(expr->operands[0].node);

File diff suppressed because it is too large Load diff

View file

@ -141,7 +141,7 @@ void preproc_warning(struct preproc_ctx *ctx, const struct vkd3d_shader_location
static inline struct preproc_file *preproc_get_top_file(struct preproc_ctx *ctx)
{
assert(ctx->file_count);
VKD3D_ASSERT(ctx->file_count);
return &ctx->file_stack[ctx->file_count - 1];
}

View file

@ -408,7 +408,7 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
}
ctx->last_was_eof = false;
assert(ctx->file_count);
VKD3D_ASSERT(ctx->file_count);
if (!(token = preproc_lexer_lex(lval, lloc, scanner)))
{
ctx->last_was_eof = true;
@ -646,7 +646,7 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
{
struct preproc_text *current_arg = NULL;
assert(func_state->macro->arg_count);
VKD3D_ASSERT(func_state->macro->arg_count);
if (func_state->arg_count < func_state->macro->arg_count)
current_arg = &func_state->macro->arg_values[func_state->arg_count];

View file

@ -119,7 +119,7 @@ bool preproc_add_macro(struct preproc_ctx *ctx, const struct vkd3d_shader_locati
macro->body.text = *body;
macro->body.location = *body_loc;
ret = rb_put(&ctx->macros, name, &macro->entry);
assert(!ret);
VKD3D_ASSERT(!ret);
return true;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -60,7 +60,7 @@ void vkd3d_string_buffer_init(struct vkd3d_string_buffer *buffer)
buffer->buffer_size = 16;
buffer->content_size = 0;
buffer->buffer = vkd3d_malloc(buffer->buffer_size);
assert(buffer->buffer);
VKD3D_ASSERT(buffer->buffer);
memset(buffer->buffer, 0, buffer->buffer_size);
}
@ -228,7 +228,7 @@ void vkd3d_string_buffer_release(struct vkd3d_string_buffer_cache *cache, struct
{
if (!buffer)
return;
assert(cache->count + 1 <= cache->max_count);
VKD3D_ASSERT(cache->count + 1 <= cache->max_count);
cache->buffers[cache->count++] = buffer;
}
@ -429,7 +429,7 @@ static void bytecode_set_bytes(struct vkd3d_bytecode_buffer *buffer, size_t offs
if (buffer->status)
return;
assert(vkd3d_bound_range(offset, size, buffer->size));
VKD3D_ASSERT(vkd3d_bound_range(offset, size, buffer->size));
memcpy(buffer->data + offset, value, size);
}
@ -642,7 +642,7 @@ static bool vkd3d_shader_signature_from_shader_signature(struct vkd3d_shader_sig
signature->element_count = src->element_count;
if (!src->elements)
{
assert(!signature->element_count);
VKD3D_ASSERT(!signature->element_count);
signature->elements = NULL;
return true;
}
@ -787,7 +787,7 @@ static struct vkd3d_shader_cf_info *vkd3d_shader_scan_push_cf_info(struct vkd3d_
static void vkd3d_shader_scan_pop_cf_info(struct vkd3d_shader_scan_context *context)
{
assert(context->cf_info_count);
VKD3D_ASSERT(context->cf_info_count);
--context->cf_info_count;
}
@ -847,12 +847,13 @@ static void vkd3d_shader_scan_add_uav_flag(const struct vkd3d_shader_scan_contex
static bool vkd3d_shader_instruction_is_uav_read(const struct vkd3d_shader_instruction *instruction)
{
enum vkd3d_shader_opcode handler_idx = instruction->handler_idx;
return (VKD3DSIH_ATOMIC_AND <= handler_idx && handler_idx <= VKD3DSIH_ATOMIC_XOR)
|| (VKD3DSIH_IMM_ATOMIC_ALLOC <= handler_idx && handler_idx <= VKD3DSIH_IMM_ATOMIC_XOR)
|| handler_idx == VKD3DSIH_LD_UAV_TYPED
|| (handler_idx == VKD3DSIH_LD_RAW && instruction->src[1].reg.type == VKD3DSPR_UAV)
|| (handler_idx == VKD3DSIH_LD_STRUCTURED && instruction->src[2].reg.type == VKD3DSPR_UAV);
enum vkd3d_shader_opcode opcode = instruction->opcode;
return (VKD3DSIH_ATOMIC_AND <= opcode && opcode <= VKD3DSIH_ATOMIC_XOR)
|| (VKD3DSIH_IMM_ATOMIC_ALLOC <= opcode && opcode <= VKD3DSIH_IMM_ATOMIC_XOR)
|| opcode == VKD3DSIH_LD_UAV_TYPED
|| (opcode == VKD3DSIH_LD_RAW && instruction->src[1].reg.type == VKD3DSPR_UAV)
|| (opcode == VKD3DSIH_LD_STRUCTURED && instruction->src[2].reg.type == VKD3DSPR_UAV);
}
static void vkd3d_shader_scan_record_uav_read(struct vkd3d_shader_scan_context *context,
@ -863,9 +864,9 @@ static void vkd3d_shader_scan_record_uav_read(struct vkd3d_shader_scan_context *
static bool vkd3d_shader_instruction_is_uav_counter(const struct vkd3d_shader_instruction *instruction)
{
enum vkd3d_shader_opcode handler_idx = instruction->handler_idx;
return handler_idx == VKD3DSIH_IMM_ATOMIC_ALLOC
|| handler_idx == VKD3DSIH_IMM_ATOMIC_CONSUME;
enum vkd3d_shader_opcode opcode = instruction->opcode;
return opcode == VKD3DSIH_IMM_ATOMIC_ALLOC || opcode == VKD3DSIH_IMM_ATOMIC_CONSUME;
}
static void vkd3d_shader_scan_record_uav_counter(struct vkd3d_shader_scan_context *context,
@ -876,9 +877,10 @@ static void vkd3d_shader_scan_record_uav_counter(struct vkd3d_shader_scan_contex
static bool vkd3d_shader_instruction_is_uav_atomic_op(const struct vkd3d_shader_instruction *instruction)
{
enum vkd3d_shader_opcode handler_idx = instruction->handler_idx;
return (VKD3DSIH_ATOMIC_AND <= handler_idx && handler_idx <= VKD3DSIH_ATOMIC_XOR)
|| (VKD3DSIH_IMM_ATOMIC_ALLOC <= handler_idx && handler_idx <= VKD3DSIH_IMM_ATOMIC_XOR);
enum vkd3d_shader_opcode opcode = instruction->opcode;
return (VKD3DSIH_ATOMIC_AND <= opcode && opcode <= VKD3DSIH_ATOMIC_XOR)
|| (VKD3DSIH_IMM_ATOMIC_ALLOC <= opcode && opcode <= VKD3DSIH_IMM_ATOMIC_XOR);
}
static void vkd3d_shader_scan_record_uav_atomic_op(struct vkd3d_shader_scan_context *context,
@ -1130,7 +1132,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
context->location = instruction->location;
switch (instruction->handler_idx)
switch (instruction->opcode)
{
case VKD3DSIH_DCL_CONSTANT_BUFFER:
vkd3d_shader_scan_constant_buffer_declaration(context, instruction);
@ -2063,7 +2065,7 @@ bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *ins
bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *instructions,
unsigned int idx, unsigned int count)
{
assert(idx <= instructions->count);
VKD3D_ASSERT(idx <= instructions->count);
if (!shader_instruction_array_reserve(instructions, instructions->count + count))
return false;

View file

@ -51,7 +51,6 @@
#include "vkd3d_shader.h"
#include "wine/list.h"
#include <assert.h>
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
@ -151,6 +150,8 @@ enum vkd3d_shader_error
VKD3D_SHADER_ERROR_HLSL_DUPLICATE_SWITCH_CASE = 5028,
VKD3D_SHADER_ERROR_HLSL_MISSING_TECHNIQUE = 5029,
VKD3D_SHADER_ERROR_HLSL_UNKNOWN_MODIFIER = 5030,
VKD3D_SHADER_ERROR_HLSL_INVALID_STATE_BLOCK_ENTRY = 5031,
VKD3D_SHADER_ERROR_HLSL_FAILED_FORCED_UNROLL = 5032,
VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300,
VKD3D_SHADER_WARNING_HLSL_DIVISION_BY_ZERO = 5301,
@ -455,6 +456,10 @@ enum vkd3d_shader_opcode
VKD3DSIH_PHASE,
VKD3DSIH_PHI,
VKD3DSIH_POW,
VKD3DSIH_QUAD_READ_ACROSS_D,
VKD3DSIH_QUAD_READ_ACROSS_X,
VKD3DSIH_QUAD_READ_ACROSS_Y,
VKD3DSIH_QUAD_READ_LANE_AT,
VKD3DSIH_RCP,
VKD3DSIH_REP,
VKD3DSIH_RESINFO,
@ -613,6 +618,7 @@ enum vkd3d_shader_register_type
VKD3DSPR_SSA,
VKD3DSPR_WAVELANECOUNT,
VKD3DSPR_WAVELANEINDEX,
VKD3DSPR_PARAMETER,
VKD3DSPR_COUNT,
@ -805,6 +811,7 @@ enum vkd3d_tessellator_domain
#define VKD3DSI_NONE 0x0
#define VKD3DSI_TEXLD_PROJECT 0x1
#define VKD3DSI_TEXLD_BIAS 0x2
#define VKD3DSI_INDEXED_DYNAMIC 0x4
#define VKD3DSI_RESINFO_RCP_FLOAT 0x1
#define VKD3DSI_RESINFO_UINT 0x2
@ -1189,7 +1196,7 @@ struct vkd3d_shader_location
struct vkd3d_shader_instruction
{
struct vkd3d_shader_location location;
enum vkd3d_shader_opcode handler_idx;
enum vkd3d_shader_opcode opcode;
uint32_t flags;
unsigned int dst_count;
unsigned int src_count;
@ -1238,8 +1245,8 @@ static inline bool vkd3d_shader_ver_le(const struct vkd3d_shader_version *v, uns
return v->major < major || (v->major == major && v->minor <= minor);
}
void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location,
enum vkd3d_shader_opcode handler_idx);
void vsir_instruction_init(struct vkd3d_shader_instruction *ins,
const struct vkd3d_shader_location *location, enum vkd3d_shader_opcode opcode);
static inline bool vkd3d_shader_instruction_has_texel_offset(const struct vkd3d_shader_instruction *ins)
{
@ -1303,14 +1310,14 @@ void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator,
static inline struct vkd3d_shader_src_param *shader_src_param_allocator_get(
struct vkd3d_shader_param_allocator *allocator, unsigned int count)
{
assert(allocator->stride == sizeof(struct vkd3d_shader_src_param));
VKD3D_ASSERT(allocator->stride == sizeof(struct vkd3d_shader_src_param));
return shader_param_allocator_get(allocator, count);
}
static inline struct vkd3d_shader_dst_param *shader_dst_param_allocator_get(
struct vkd3d_shader_param_allocator *allocator, unsigned int count)
{
assert(allocator->stride == sizeof(struct vkd3d_shader_dst_param));
VKD3D_ASSERT(allocator->stride == sizeof(struct vkd3d_shader_dst_param));
return shader_param_allocator_get(allocator, count);
}
@ -1355,6 +1362,10 @@ struct vsir_program
struct shader_signature output_signature;
struct shader_signature patch_constant_signature;
unsigned int parameter_count;
const struct vkd3d_shader_parameter1 *parameters;
bool free_parameters;
unsigned int input_control_point_count, output_control_point_count;
unsigned int flat_constant_count[3];
unsigned int block_count;
@ -1370,7 +1381,10 @@ void vsir_program_cleanup(struct vsir_program *program);
int vsir_program_compile(struct vsir_program *program, uint64_t config_flags,
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out,
struct vkd3d_shader_message_context *message_context);
bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_version *version, unsigned int reserve);
const struct vkd3d_shader_parameter1 *vsir_program_get_parameter(
const struct vsir_program *program, enum vkd3d_shader_parameter_name name);
bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info,
const struct vkd3d_shader_version *version, unsigned int reserve);
enum vkd3d_result vsir_program_normalise(struct vsir_program *program, uint64_t config_flags,
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context);
enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t config_flags,
@ -1663,7 +1677,7 @@ static inline unsigned int vsir_write_mask_get_component_idx(uint32_t write_mask
{
unsigned int i;
assert(write_mask);
VKD3D_ASSERT(write_mask);
for (i = 0; i < VKD3D_VEC4_SIZE; ++i)
{
if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
@ -1677,13 +1691,13 @@ static inline unsigned int vsir_write_mask_get_component_idx(uint32_t 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);
VKD3D_ASSERT(1 <= count && count <= VKD3D_VEC4_SIZE);
return count;
}
static inline unsigned int vkd3d_write_mask_from_component_count(unsigned int component_count)
{
assert(component_count <= VKD3D_VEC4_SIZE);
VKD3D_ASSERT(component_count <= VKD3D_VEC4_SIZE);
return (VKD3DSP_WRITEMASK_0 << component_count) - 1;
}

View file

@ -69,7 +69,14 @@ static int vkd3d_shader_cache_compare_key(const void *key, const struct rb_entry
static void vkd3d_shader_cache_add_entry(struct vkd3d_shader_cache *cache,
struct shader_cache_entry *e)
{
rb_put(&cache->tree, &e->h.hash, &e->entry);
const struct shader_cache_key k =
{
.hash = e->h.hash,
.key_size = e->h.key_size,
.key = e->payload
};
rb_put(&cache->tree, &k, &e->entry);
}
int vkd3d_shader_open_cache(struct vkd3d_shader_cache **cache)

File diff suppressed because it is too large Load diff

View file

@ -76,6 +76,14 @@ static const char * const required_device_extensions[] =
VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME,
};
/* In general we don't want to enable Vulkan beta extensions, but make an
* exception for VK_KHR_portability_subset because we draw no real feature from
* it, but it's still useful to be able to develop for MoltenVK without being
* spammed with validation errors. */
#ifndef VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME
#define VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME "VK_KHR_portability_subset"
#endif
static const struct vkd3d_optional_extension_info optional_device_extensions[] =
{
/* KHR extensions */
@ -85,6 +93,7 @@ static const struct vkd3d_optional_extension_info optional_device_extensions[] =
VK_EXTENSION(KHR_IMAGE_FORMAT_LIST, KHR_image_format_list),
VK_EXTENSION(KHR_MAINTENANCE2, KHR_maintenance2),
VK_EXTENSION(KHR_MAINTENANCE3, KHR_maintenance3),
VK_EXTENSION(KHR_PORTABILITY_SUBSET, KHR_portability_subset),
VK_EXTENSION(KHR_PUSH_DESCRIPTOR, KHR_push_descriptor),
VK_EXTENSION(KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE, KHR_sampler_mirror_clamp_to_edge),
VK_EXTENSION(KHR_TIMELINE_SEMAPHORE, KHR_timeline_semaphore),
@ -92,7 +101,7 @@ static const struct vkd3d_optional_extension_info optional_device_extensions[] =
VK_EXTENSION(EXT_4444_FORMATS, EXT_4444_formats),
VK_EXTENSION(EXT_CALIBRATED_TIMESTAMPS, EXT_calibrated_timestamps),
VK_EXTENSION(EXT_CONDITIONAL_RENDERING, EXT_conditional_rendering),
VK_EXTENSION(EXT_DEBUG_MARKER, EXT_debug_marker),
VK_DEBUG_EXTENSION(EXT_DEBUG_MARKER, EXT_debug_marker),
VK_EXTENSION(EXT_DEPTH_CLIP_ENABLE, EXT_depth_clip_enable),
VK_EXTENSION(EXT_DESCRIPTOR_INDEXING, EXT_descriptor_indexing),
VK_EXTENSION(EXT_FRAGMENT_SHADER_INTERLOCK, EXT_fragment_shader_interlock),
@ -299,7 +308,7 @@ static unsigned int vkd3d_check_extensions(const VkExtensionProperties *extensio
for (i = 0; i < required_extension_count; ++i)
{
if (!has_extension(extensions, count, required_extensions[i]))
ERR("Required %s extension %s is not supported.\n",
WARN("Required %s extension %s is not supported.\n",
extension_type, debugstr_a(required_extensions[i]));
++extension_count;
}
@ -327,12 +336,12 @@ static unsigned int vkd3d_check_extensions(const VkExtensionProperties *extensio
for (i = 0; i < user_extension_count; ++i)
{
if (!has_extension(extensions, count, user_extensions[i]))
ERR("Required user %s extension %s is not supported.\n",
WARN("Required user %s extension %s is not supported.\n",
extension_type, debugstr_a(user_extensions[i]));
++extension_count;
}
assert(!optional_user_extension_count || user_extension_supported);
VKD3D_ASSERT(!optional_user_extension_count || user_extension_supported);
for (i = 0; i < optional_user_extension_count; ++i)
{
if (has_extension(extensions, count, optional_user_extensions[i]))
@ -394,7 +403,7 @@ static unsigned int vkd3d_enable_extensions(const char *extensions[],
{
extension_count = vkd3d_append_extension(extensions, extension_count, user_extensions[i]);
}
assert(!optional_user_extension_count || user_extension_supported);
VKD3D_ASSERT(!optional_user_extension_count || user_extension_supported);
for (i = 0; i < optional_user_extension_count; ++i)
{
if (!user_extension_supported[i])
@ -575,7 +584,7 @@ static HRESULT vkd3d_instance_init(struct vkd3d_instance *instance,
if (!create_info->pfn_signal_event)
{
ERR("Invalid signal event function pointer.\n");
WARN("Invalid signal event function pointer.\n");
return E_INVALIDARG;
}
if (!create_info->pfn_create_thread != !create_info->pfn_join_thread)
@ -585,7 +594,7 @@ static HRESULT vkd3d_instance_init(struct vkd3d_instance *instance,
}
if (create_info->wchar_size != 2 && create_info->wchar_size != 4)
{
ERR("Unexpected WCHAR size %zu.\n", create_info->wchar_size);
WARN("Unexpected WCHAR size %zu.\n", create_info->wchar_size);
return E_INVALIDARG;
}
@ -822,115 +831,91 @@ struct vkd3d_physical_device_info
VkPhysicalDeviceFeatures2 features2;
};
static void vkd3d_chain_physical_device_info_structures(struct vkd3d_physical_device_info *info,
struct d3d12_device *device)
{
struct vkd3d_vulkan_info *vulkan_info = &device->vk_info;
info->features2.pNext = NULL;
if (vulkan_info->EXT_conditional_rendering)
vk_prepend_struct(&info->features2, &info->conditional_rendering_features);
if (vulkan_info->EXT_depth_clip_enable)
vk_prepend_struct(&info->features2, &info->depth_clip_features);
if (vulkan_info->EXT_descriptor_indexing)
vk_prepend_struct(&info->features2, &info->descriptor_indexing_features);
if (vulkan_info->EXT_fragment_shader_interlock)
vk_prepend_struct(&info->features2, &info->fragment_shader_interlock_features);
if (vulkan_info->EXT_robustness2)
vk_prepend_struct(&info->features2, &info->robustness2_features);
if (vulkan_info->EXT_shader_demote_to_helper_invocation)
vk_prepend_struct(&info->features2, &info->demote_features);
if (vulkan_info->EXT_texel_buffer_alignment)
vk_prepend_struct(&info->features2, &info->texel_buffer_alignment_features);
if (vulkan_info->EXT_transform_feedback)
vk_prepend_struct(&info->features2, &info->xfb_features);
if (vulkan_info->EXT_vertex_attribute_divisor)
vk_prepend_struct(&info->features2, &info->vertex_divisor_features);
if (vulkan_info->KHR_timeline_semaphore)
vk_prepend_struct(&info->features2, &info->timeline_semaphore_features);
if (vulkan_info->EXT_mutable_descriptor_type)
vk_prepend_struct(&info->features2, &info->mutable_features);
if (vulkan_info->EXT_4444_formats)
vk_prepend_struct(&info->features2, &info->formats4444_features);
info->properties2.pNext = NULL;
if (vulkan_info->KHR_maintenance3)
vk_prepend_struct(&info->properties2, &info->maintenance3_properties);
if (vulkan_info->EXT_descriptor_indexing)
vk_prepend_struct(&info->properties2, &info->descriptor_indexing_properties);
if (vulkan_info->EXT_texel_buffer_alignment)
vk_prepend_struct(&info->properties2, &info->texel_buffer_alignment_properties);
if (vulkan_info->EXT_transform_feedback)
vk_prepend_struct(&info->properties2, &info->xfb_properties);
if (vulkan_info->EXT_vertex_attribute_divisor)
vk_prepend_struct(&info->properties2, &info->vertex_divisor_properties);
if (d3d12_device_environment_is_vulkan_min_1_1(device))
vk_prepend_struct(&info->properties2, &info->subgroup_properties);
}
static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *info, struct d3d12_device *device)
{
const struct vkd3d_vk_instance_procs *vk_procs = &device->vkd3d_instance->vk_procs;
VkPhysicalDeviceConditionalRenderingFeaturesEXT *conditional_rendering_features;
VkPhysicalDeviceDescriptorIndexingPropertiesEXT *descriptor_indexing_properties;
VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *vertex_divisor_properties;
VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT *buffer_alignment_properties;
VkPhysicalDeviceDescriptorIndexingFeaturesEXT *descriptor_indexing_features;
VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT *fragment_shader_interlock_features;
VkPhysicalDeviceRobustness2FeaturesEXT *robustness2_features;
VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *vertex_divisor_features;
VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT *buffer_alignment_features;
VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT *demote_features;
VkPhysicalDeviceTimelineSemaphoreFeaturesKHR *timeline_semaphore_features;
VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT *mutable_features;
VkPhysicalDeviceDepthClipEnableFeaturesEXT *depth_clip_features;
VkPhysicalDeviceMaintenance3Properties *maintenance3_properties;
VkPhysicalDeviceTransformFeedbackPropertiesEXT *xfb_properties;
VkPhysicalDevice physical_device = device->vk_physical_device;
VkPhysicalDevice4444FormatsFeaturesEXT *formats4444_features;
VkPhysicalDeviceTransformFeedbackFeaturesEXT *xfb_features;
struct vkd3d_vulkan_info *vulkan_info = &device->vk_info;
VkPhysicalDeviceSubgroupProperties *subgroup_properties;
memset(info, 0, sizeof(*info));
conditional_rendering_features = &info->conditional_rendering_features;
depth_clip_features = &info->depth_clip_features;
descriptor_indexing_features = &info->descriptor_indexing_features;
fragment_shader_interlock_features = &info->fragment_shader_interlock_features;
robustness2_features = &info->robustness2_features;
descriptor_indexing_properties = &info->descriptor_indexing_properties;
maintenance3_properties = &info->maintenance3_properties;
demote_features = &info->demote_features;
buffer_alignment_features = &info->texel_buffer_alignment_features;
buffer_alignment_properties = &info->texel_buffer_alignment_properties;
vertex_divisor_features = &info->vertex_divisor_features;
vertex_divisor_properties = &info->vertex_divisor_properties;
timeline_semaphore_features = &info->timeline_semaphore_features;
mutable_features = &info->mutable_features;
formats4444_features = &info->formats4444_features;
xfb_features = &info->xfb_features;
xfb_properties = &info->xfb_properties;
subgroup_properties = &info->subgroup_properties;
info->features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
info->conditional_rendering_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT;
info->depth_clip_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT;
info->descriptor_indexing_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT;
info->fragment_shader_interlock_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT;
info->robustness2_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT;
info->demote_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT;
info->texel_buffer_alignment_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT;
info->xfb_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT;
info->vertex_divisor_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT;
info->timeline_semaphore_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR;
info->mutable_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT;
info->formats4444_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT;
conditional_rendering_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT;
if (vulkan_info->EXT_conditional_rendering)
vk_prepend_struct(&info->features2, conditional_rendering_features);
depth_clip_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT;
if (vulkan_info->EXT_depth_clip_enable)
vk_prepend_struct(&info->features2, depth_clip_features);
descriptor_indexing_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT;
if (vulkan_info->EXT_descriptor_indexing)
vk_prepend_struct(&info->features2, descriptor_indexing_features);
fragment_shader_interlock_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT;
if (vulkan_info->EXT_fragment_shader_interlock)
vk_prepend_struct(&info->features2, fragment_shader_interlock_features);
robustness2_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT;
if (vulkan_info->EXT_robustness2)
vk_prepend_struct(&info->features2, robustness2_features);
demote_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT;
if (vulkan_info->EXT_shader_demote_to_helper_invocation)
vk_prepend_struct(&info->features2, demote_features);
buffer_alignment_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT;
if (vulkan_info->EXT_texel_buffer_alignment)
vk_prepend_struct(&info->features2, buffer_alignment_features);
xfb_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT;
if (vulkan_info->EXT_transform_feedback)
vk_prepend_struct(&info->features2, xfb_features);
vertex_divisor_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT;
if (vulkan_info->EXT_vertex_attribute_divisor)
vk_prepend_struct(&info->features2, vertex_divisor_features);
timeline_semaphore_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR;
if (vulkan_info->KHR_timeline_semaphore)
vk_prepend_struct(&info->features2, timeline_semaphore_features);
mutable_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT;
if (vulkan_info->EXT_mutable_descriptor_type)
vk_prepend_struct(&info->features2, mutable_features);
formats4444_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT;
if (vulkan_info->EXT_4444_formats)
vk_prepend_struct(&info->features2, formats4444_features);
info->properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
info->maintenance3_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES;
info->descriptor_indexing_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT;
info->texel_buffer_alignment_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT;
info->xfb_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT;
info->vertex_divisor_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT;
info->subgroup_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
vkd3d_chain_physical_device_info_structures(info, device);
if (vulkan_info->KHR_get_physical_device_properties2)
VK_CALL(vkGetPhysicalDeviceFeatures2KHR(physical_device, &info->features2));
else
VK_CALL(vkGetPhysicalDeviceFeatures(physical_device, &info->features2.features));
info->properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
maintenance3_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES;
if (vulkan_info->KHR_maintenance3)
vk_prepend_struct(&info->properties2, maintenance3_properties);
descriptor_indexing_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT;
if (vulkan_info->EXT_descriptor_indexing)
vk_prepend_struct(&info->properties2, descriptor_indexing_properties);
buffer_alignment_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT;
if (vulkan_info->EXT_texel_buffer_alignment)
vk_prepend_struct(&info->properties2, buffer_alignment_properties);
xfb_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT;
if (vulkan_info->EXT_transform_feedback)
vk_prepend_struct(&info->properties2, xfb_properties);
vertex_divisor_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT;
if (vulkan_info->EXT_vertex_attribute_divisor)
vk_prepend_struct(&info->properties2, vertex_divisor_properties);
subgroup_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
if (d3d12_device_environment_is_vulkan_min_1_1(device))
vk_prepend_struct(&info->properties2, subgroup_properties);
if (vulkan_info->KHR_get_physical_device_properties2)
VK_CALL(vkGetPhysicalDeviceProperties2KHR(physical_device, &info->properties2));
else
@ -1522,7 +1507,7 @@ static bool d3d12_device_supports_typed_uav_load_additional_formats(const struct
for (i = 0; i < ARRAY_SIZE(additional_formats); ++i)
{
format = vkd3d_get_format(device, additional_formats[i], false);
assert(format);
VKD3D_ASSERT(format);
VK_CALL(vkGetPhysicalDeviceFormatProperties(device->vk_physical_device, format->vk_format, &properties));
if (!((properties.linearTilingFeatures | properties.optimalTilingFeatures) & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
@ -1634,6 +1619,8 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
vulkan_info->device_limits = physical_device_info->properties2.properties.limits;
vulkan_info->sparse_properties = physical_device_info->properties2.properties.sparseProperties;
vulkan_info->geometry_shaders = physical_device_info->features2.features.geometryShader;
vulkan_info->tessellation_shaders = physical_device_info->features2.features.tessellationShader;
vulkan_info->sparse_binding = features->sparseBinding;
vulkan_info->sparse_residency_3d = features->sparseResidencyImage3D;
vulkan_info->rasterization_stream = physical_device_info->xfb_properties.transformFeedbackRasterizationStreamSelect;
@ -1829,6 +1816,8 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
vkd3d_device_descriptor_limits_init(&vulkan_info->descriptor_limits,
&physical_device_info->properties2.properties.limits);
vkd3d_chain_physical_device_info_structures(physical_device_info, device);
return S_OK;
}
@ -2166,7 +2155,7 @@ static HRESULT vkd3d_create_vk_device(struct d3d12_device *device,
vkd3d_free(extensions);
if (vr < 0)
{
ERR("Failed to create Vulkan device, vr %d.\n", vr);
WARN("Failed to create Vulkan device, vr %d.\n", vr);
return hresult_from_vk_result(vr);
}
@ -2552,11 +2541,13 @@ static void device_init_descriptor_pool_sizes(struct d3d12_device *device)
VKD3D_MAX_UAV_CLEAR_DESCRIPTORS_PER_TYPE);
pool_sizes[1].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
pool_sizes[1].descriptorCount = pool_sizes[0].descriptorCount;
device->vk_pool_count = 2;
pool_sizes[2].type = VK_DESCRIPTOR_TYPE_SAMPLER;
pool_sizes[2].descriptorCount = min(limits->sampler_max_descriptors, D3D12_MAX_LIVE_STATIC_SAMPLERS);
device->vk_pool_count = 3;
return;
}
assert(ARRAY_SIZE(device->vk_pool_sizes) >= 6);
VKD3D_ASSERT(ARRAY_SIZE(device->vk_pool_sizes) >= 6);
pool_sizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
pool_sizes[0].descriptorCount = min(limits->uniform_buffer_max_descriptors,
VKD3D_MAX_VIRTUAL_HEAP_DESCRIPTORS_PER_TYPE);
@ -3128,8 +3119,8 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList(ID3D12Device9 *i
initial_pipeline_state, &object)))
return hr;
return return_interface(&object->ID3D12GraphicsCommandList5_iface,
&IID_ID3D12GraphicsCommandList5, riid, command_list);
return return_interface(&object->ID3D12GraphicsCommandList6_iface,
&IID_ID3D12GraphicsCommandList6, riid, command_list);
}
/* Direct3D feature levels restrict which formats can be optionally supported. */
@ -3806,7 +3797,8 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device9
return E_INVALIDARG;
}
data->UnalignedBlockTexturesSupported = FALSE;
/* Vulkan does not restrict block texture alignment. */
data->UnalignedBlockTexturesSupported = TRUE;
TRACE("Unaligned block texture support %#x.\n", data->UnalignedBlockTexturesSupported);
return S_OK;
@ -5262,7 +5254,7 @@ struct d3d12_device *unsafe_impl_from_ID3D12Device9(ID3D12Device9 *iface)
{
if (!iface)
return NULL;
assert(iface->lpVtbl == &d3d12_device_vtbl);
VKD3D_ASSERT(iface->lpVtbl == &d3d12_device_vtbl);
return impl_from_ID3D12Device9(iface);
}

View file

@ -312,7 +312,7 @@ static ULONG STDMETHODCALLTYPE d3d12_heap_AddRef(ID3D12Heap *iface)
TRACE("%p increasing refcount to %u.\n", heap, refcount);
assert(!heap->is_private);
VKD3D_ASSERT(!heap->is_private);
return refcount;
}
@ -443,7 +443,7 @@ struct d3d12_heap *unsafe_impl_from_ID3D12Heap(ID3D12Heap *iface)
{
if (!iface)
return NULL;
assert(iface->lpVtbl == &d3d12_heap_vtbl);
VKD3D_ASSERT(iface->lpVtbl == &d3d12_heap_vtbl);
return impl_from_ID3D12Heap(iface);
}
@ -950,8 +950,8 @@ HRESULT vkd3d_get_image_allocation_info(struct d3d12_device *device,
bool tiled;
HRESULT hr;
assert(desc->Dimension != D3D12_RESOURCE_DIMENSION_BUFFER);
assert(d3d12_resource_validate_desc(desc, device) == S_OK);
VKD3D_ASSERT(desc->Dimension != D3D12_RESOURCE_DIMENSION_BUFFER);
VKD3D_ASSERT(d3d12_resource_validate_desc(desc, device) == S_OK);
if (!desc->MipLevels)
{
@ -1044,7 +1044,7 @@ static bool d3d12_resource_validate_box(const struct d3d12_resource *resource,
depth = d3d12_resource_desc_get_depth(&resource->desc, mip_level);
vkd3d_format = resource->format;
assert(vkd3d_format);
VKD3D_ASSERT(vkd3d_format);
width_mask = vkd3d_format->block_width - 1;
height_mask = vkd3d_format->block_height - 1;
@ -1162,7 +1162,7 @@ static bool d3d12_resource_init_tiles(struct d3d12_resource *resource, struct d3
if (d3d12_resource_is_buffer(resource))
{
assert(subresource_count == 1);
VKD3D_ASSERT(subresource_count == 1);
VK_CALL(vkGetBufferMemoryRequirements(device->vk_device, resource->u.vk_buffer, &requirements));
if (requirements.alignment > D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES)
@ -1381,7 +1381,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_GetDevice(ID3D12Resource2 *iface
static void *d3d12_resource_get_map_ptr(struct d3d12_resource *resource)
{
assert(resource->heap->map_ptr);
VKD3D_ASSERT(resource->heap->map_ptr);
return (uint8_t *)resource->heap->map_ptr + resource->heap_offset;
}
@ -1771,7 +1771,7 @@ struct d3d12_resource *unsafe_impl_from_ID3D12Resource(ID3D12Resource *iface)
{
if (!iface)
return NULL;
assert(iface->lpVtbl == (ID3D12ResourceVtbl *)&d3d12_resource_vtbl);
VKD3D_ASSERT(iface->lpVtbl == (ID3D12ResourceVtbl *)&d3d12_resource_vtbl);
return impl_from_ID3D12Resource(iface);
}
@ -1809,14 +1809,6 @@ static bool d3d12_resource_validate_texture_format(const D3D12_RESOURCE_DESC1 *d
return false;
}
if (align(desc->Width, format->block_width) != desc->Width
|| align(desc->Height, format->block_height) != desc->Height)
{
WARN("Invalid size %"PRIu64"x%u for block compressed format %#x.\n",
desc->Width, desc->Height, desc->Format);
return false;
}
return true;
}
@ -2173,7 +2165,7 @@ static HRESULT vkd3d_bind_heap_memory(struct d3d12_device *device,
if (heap_offset > heap->desc.SizeInBytes || requirements.size > heap->desc.SizeInBytes - heap_offset)
{
ERR("Heap too small for the resource (offset %"PRIu64", resource size %"PRIu64", heap size %"PRIu64".\n",
WARN("Heap too small for the resource (offset %"PRIu64", resource size %"PRIu64", heap size %"PRIu64".\n",
heap_offset, requirements.size, heap->desc.SizeInBytes);
return E_INVALIDARG;
}
@ -2192,7 +2184,7 @@ static HRESULT vkd3d_bind_heap_memory(struct d3d12_device *device,
goto allocate_memory;
}
/* Syncronisation is not required for binding, but vkMapMemory() may be called
/* Synchronisation is not required for binding, but vkMapMemory() may be called
* from another thread and it requires exclusive access. */
vkd3d_mutex_lock(&heap->mutex);
@ -2414,7 +2406,7 @@ static struct vkd3d_view *vkd3d_view_create(uint32_t magic, VkDescriptorType vk_
{
struct vkd3d_view *view;
assert(magic);
VKD3D_ASSERT(magic);
if (!(view = vkd3d_desc_object_cache_get(&device->view_desc_cache)))
{
@ -2544,7 +2536,7 @@ static void d3d12_desc_write_vk_heap_null_descriptor(struct d3d12_descriptor_hea
writes->vk_descriptor_writes[i].pTexelBufferView = &writes->null_vk_buffer_view;
break;
default:
assert(false);
VKD3D_ASSERT(false);
break;
}
if (++i < ARRAY_SIZE(writes->vk_descriptor_writes) - 1)
@ -2733,7 +2725,7 @@ void d3d12_desc_copy(struct d3d12_desc *dst, const struct d3d12_desc *src, struc
{
struct d3d12_desc tmp;
assert(dst != src);
VKD3D_ASSERT(dst != src);
tmp.s.u.object = d3d12_desc_get_object_ref(src, device);
descriptor_heap_write_atomic(dst_heap, dst, &tmp, device);
@ -2756,7 +2748,7 @@ static VkDeviceSize vkd3d_get_required_texel_buffer_alignment(const struct d3d12
if (properties->storageTexelBufferOffsetSingleTexelAlignment
&& properties->uniformTexelBufferOffsetSingleTexelAlignment)
{
assert(!vkd3d_format_is_compressed(format));
VKD3D_ASSERT(!vkd3d_format_is_compressed(format));
return min(format->byte_count, alignment);
}
@ -2856,7 +2848,7 @@ static bool vkd3d_create_buffer_view_for_resource(struct d3d12_device *device,
return false;
}
assert(d3d12_resource_is_buffer(resource));
VKD3D_ASSERT(d3d12_resource_is_buffer(resource));
return vkd3d_create_buffer_view(device, magic, resource->u.vk_buffer,
format, offset * element_size, size * element_size, view);
@ -2987,7 +2979,7 @@ static VkComponentSwizzle swizzle_vk_component(const VkComponentMapping *compone
break;
}
assert(component != VK_COMPONENT_SWIZZLE_IDENTITY);
VKD3D_ASSERT(component != VK_COMPONENT_SWIZZLE_IDENTITY);
return component;
}
@ -3519,8 +3511,8 @@ static void vkd3d_create_buffer_uav(struct d3d12_desc *descriptor, struct d3d12_
{
const struct vkd3d_format *format;
assert(d3d12_resource_is_buffer(counter_resource));
assert(desc->u.Buffer.StructureByteStride);
VKD3D_ASSERT(d3d12_resource_is_buffer(counter_resource));
VKD3D_ASSERT(desc->u.Buffer.StructureByteStride);
format = vkd3d_get_format(device, DXGI_FORMAT_R32_UINT, false);
if (!vkd3d_create_vk_buffer_view(device, counter_resource->u.vk_buffer, format,
@ -3640,7 +3632,7 @@ bool vkd3d_create_raw_buffer_view(struct d3d12_device *device,
}
resource = vkd3d_gpu_va_allocator_dereference(&device->gpu_va_allocator, gpu_address);
assert(d3d12_resource_is_buffer(resource));
VKD3D_ASSERT(d3d12_resource_is_buffer(resource));
return vkd3d_create_vk_buffer_view(device, resource->u.vk_buffer, format,
gpu_address - resource->gpu_address, VK_WHOLE_SIZE, vk_buffer_view);
}
@ -3912,7 +3904,7 @@ void d3d12_rtv_desc_create_rtv(struct d3d12_rtv_desc *rtv_desc, struct d3d12_dev
vkd3d_desc.layer_count = resource->desc.DepthOrArraySize;
}
assert(d3d12_resource_is_texture(resource));
VKD3D_ASSERT(d3d12_resource_is_texture(resource));
if (!vkd3d_create_texture_view(device, VKD3D_DESCRIPTOR_MAGIC_RTV, resource->u.vk_image, &vkd3d_desc, &view))
return;
@ -3998,7 +3990,7 @@ void d3d12_dsv_desc_create_dsv(struct d3d12_dsv_desc *dsv_desc, struct d3d12_dev
}
}
assert(d3d12_resource_is_texture(resource));
VKD3D_ASSERT(d3d12_resource_is_texture(resource));
if (!vkd3d_create_texture_view(device, VKD3D_DESCRIPTOR_MAGIC_DSV, resource->u.vk_image, &vkd3d_desc, &view))
return;
@ -4357,7 +4349,11 @@ static HRESULT d3d12_descriptor_heap_init(struct d3d12_descriptor_heap *descript
return hr;
descriptor_heap->use_vk_heaps = device->use_vk_heaps && (desc->Flags & D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE);
d3d12_descriptor_heap_vk_descriptor_sets_init(descriptor_heap, device, desc);
if (FAILED(hr = d3d12_descriptor_heap_vk_descriptor_sets_init(descriptor_heap, device, desc)))
{
vkd3d_private_store_destroy(&descriptor_heap->private_store);
return hr;
}
vkd3d_mutex_init(&descriptor_heap->vk_sets_mutex);
d3d12_device_add_ref(descriptor_heap->device = device);
@ -4563,7 +4559,7 @@ struct d3d12_query_heap *unsafe_impl_from_ID3D12QueryHeap(ID3D12QueryHeap *iface
{
if (!iface)
return NULL;
assert(iface->lpVtbl == &d3d12_query_heap_vtbl);
VKD3D_ASSERT(iface->lpVtbl == &d3d12_query_heap_vtbl);
return impl_from_ID3D12QueryHeap(iface);
}

View file

@ -194,7 +194,7 @@ struct d3d12_root_signature *unsafe_impl_from_ID3D12RootSignature(ID3D12RootSign
{
if (!iface)
return NULL;
assert(iface->lpVtbl == &d3d12_root_signature_vtbl);
VKD3D_ASSERT(iface->lpVtbl == &d3d12_root_signature_vtbl);
return impl_from_ID3D12RootSignature(iface);
}
@ -345,15 +345,93 @@ struct d3d12_root_signature_info
unsigned int sampler_unbounded_range_count;
size_t cost;
struct d3d12_root_signature_info_range
{
enum vkd3d_shader_descriptor_type type;
unsigned int space;
unsigned int base_idx;
unsigned int count;
D3D12_SHADER_VISIBILITY visibility;
} *ranges;
size_t range_count, range_capacity;
};
static HRESULT d3d12_root_signature_info_add_range(struct d3d12_root_signature_info *info,
enum vkd3d_shader_descriptor_type type, D3D12_SHADER_VISIBILITY visibility,
unsigned int space, unsigned int base_idx, unsigned int count)
{
struct d3d12_root_signature_info_range *range;
if (!vkd3d_array_reserve((void **)&info->ranges, &info->range_capacity, info->range_count + 1,
sizeof(*info->ranges)))
return E_OUTOFMEMORY;
range = &info->ranges[info->range_count++];
range->type = type;
range->space = space;
range->base_idx = base_idx;
range->count = count;
range->visibility = visibility;
return S_OK;
}
static int d3d12_root_signature_info_range_compare(const void *a, const void *b)
{
const struct d3d12_root_signature_info_range *range_a = a, *range_b = b;
int ret;
if ((ret = vkd3d_u32_compare(range_a->type, range_b->type)))
return ret;
if ((ret = vkd3d_u32_compare(range_a->space, range_b->space)))
return ret;
return vkd3d_u32_compare(range_a->base_idx, range_b->base_idx);
}
static HRESULT d3d12_root_signature_info_range_validate(const struct d3d12_root_signature_info_range *ranges,
unsigned int count, D3D12_SHADER_VISIBILITY visibility)
{
const struct d3d12_root_signature_info_range *range, *next;
unsigned int i = 0, j;
while (i < count)
{
range = &ranges[i];
for (j = i + 1; j < count; ++j)
{
next = &ranges[j];
if (range->visibility != D3D12_SHADER_VISIBILITY_ALL
&& next->visibility != D3D12_SHADER_VISIBILITY_ALL
&& range->visibility != next->visibility)
continue;
if (range->type == next->type && range->space == next->space
&& range->base_idx + range->count > next->base_idx)
return E_INVALIDARG;
break;
}
i = j;
}
return S_OK;
}
static HRESULT d3d12_root_signature_info_count_descriptors(struct d3d12_root_signature_info *info,
const D3D12_ROOT_DESCRIPTOR_TABLE *table, bool use_array)
const D3D12_ROOT_PARAMETER *param, bool use_array)
{
bool cbv_unbounded_range = false, srv_unbounded_range = false, uav_unbounded_range = false;
const D3D12_ROOT_DESCRIPTOR_TABLE *table = &param->u.DescriptorTable;
bool sampler_unbounded_range = false;
bool unbounded = false;
unsigned int i, count;
HRESULT hr;
for (i = 0; i < table->NumDescriptorRanges; ++i)
{
@ -381,6 +459,12 @@ static HRESULT d3d12_root_signature_info_count_descriptors(struct d3d12_root_sig
}
count = range->NumDescriptors;
if (FAILED(hr = d3d12_root_signature_info_add_range(info,
vkd3d_descriptor_type_from_d3d12_range_type(range->RangeType),
param->ShaderVisibility, range->RegisterSpace, range->BaseShaderRegister, count)))
return hr;
if (range->NumDescriptors == UINT_MAX)
{
unbounded = true;
@ -453,8 +537,8 @@ static HRESULT d3d12_root_signature_info_from_desc(struct d3d12_root_signature_i
{
case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE:
if (FAILED(hr = d3d12_root_signature_info_count_descriptors(info,
&p->u.DescriptorTable, use_array)))
return hr;
p, use_array)))
goto done;
++info->cost;
break;
@ -463,35 +547,80 @@ static HRESULT d3d12_root_signature_info_from_desc(struct d3d12_root_signature_i
++info->cbv_count;
++info->binding_count;
info->cost += 2;
if (FAILED(hr = d3d12_root_signature_info_add_range(info,
VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, p->ShaderVisibility,
p->u.Descriptor.RegisterSpace, p->u.Descriptor.ShaderRegister, 1)))
goto done;
break;
case D3D12_ROOT_PARAMETER_TYPE_SRV:
++info->root_descriptor_count;
++info->srv_count;
++info->binding_count;
info->cost += 2;
if (FAILED(hr = d3d12_root_signature_info_add_range(info,
VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, p->ShaderVisibility,
p->u.Descriptor.RegisterSpace, p->u.Descriptor.ShaderRegister, 1)))
goto done;
break;
case D3D12_ROOT_PARAMETER_TYPE_UAV:
++info->root_descriptor_count;
++info->uav_count;
++info->binding_count;
info->cost += 2;
if (FAILED(hr = d3d12_root_signature_info_add_range(info,
VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, p->ShaderVisibility,
p->u.Descriptor.RegisterSpace, p->u.Descriptor.ShaderRegister, 1)))
goto done;
break;
case D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS:
++info->root_constant_count;
info->cost += p->u.Constants.Num32BitValues;
if (FAILED(hr = d3d12_root_signature_info_add_range(info,
VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, p->ShaderVisibility,
p->u.Constants.RegisterSpace, p->u.Constants.ShaderRegister, 1)))
goto done;
break;
default:
FIXME("Unhandled type %#x for parameter %u.\n", p->ParameterType, i);
return E_NOTIMPL;
hr = E_NOTIMPL;
goto done;
}
}
info->binding_count += desc->NumStaticSamplers;
info->sampler_count += desc->NumStaticSamplers;
return S_OK;
for (i = 0; i < desc->NumStaticSamplers; ++i)
{
const D3D12_STATIC_SAMPLER_DESC *s = &desc->pStaticSamplers[i];
if (FAILED(hr = d3d12_root_signature_info_add_range(info,
VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, s->ShaderVisibility,
s->RegisterSpace, s->ShaderRegister, 1)))
goto done;
}
qsort(info->ranges, info->range_count, sizeof(*info->ranges),
d3d12_root_signature_info_range_compare);
for (i = D3D12_SHADER_VISIBILITY_VERTEX; i <= D3D12_SHADER_VISIBILITY_MESH; ++i)
{
if (FAILED(hr = d3d12_root_signature_info_range_validate(info->ranges, info->range_count, i)))
goto done;
}
hr = S_OK;
done:
vkd3d_free(info->ranges);
info->ranges = NULL;
info->range_count = 0;
info->range_capacity = 0;
return hr;
}
static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signature *root_signature,
@ -509,14 +638,18 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat
for (i = 0; i < desc->NumParameters; ++i)
{
const D3D12_ROOT_PARAMETER *p = &desc->pParameters[i];
D3D12_SHADER_VISIBILITY visibility;
if (p->ParameterType != D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS)
continue;
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 += align(p->u.Constants.Num32BitValues, 4) * sizeof(uint32_t);
visibility = use_vk_heaps ? D3D12_SHADER_VISIBILITY_ALL : p->ShaderVisibility;
VKD3D_ASSERT(visibility <= D3D12_SHADER_VISIBILITY_PIXEL);
push_constants[visibility].stageFlags = stage_flags_from_visibility(visibility);
push_constants[visibility].size += align(p->u.Constants.Num32BitValues, 4) * sizeof(uint32_t);
}
if (push_constants[D3D12_SHADER_VISIBILITY_ALL].size)
{
/* When D3D12_SHADER_VISIBILITY_ALL is used we use a single push
@ -645,7 +778,7 @@ static HRESULT d3d12_root_signature_append_descriptor_set_layout(struct d3d12_ro
return S_OK;
}
static void d3d12_root_signature_append_vk_binding(struct d3d12_root_signature *root_signature,
static HRESULT d3d12_root_signature_append_vk_binding(struct d3d12_root_signature *root_signature,
enum vkd3d_shader_descriptor_type descriptor_type, unsigned int register_space, unsigned int register_idx,
bool buffer_descriptor, enum vkd3d_shader_visibility shader_visibility,
unsigned int descriptor_count, struct vkd3d_descriptor_set_context *context)
@ -670,33 +803,38 @@ static void d3d12_root_signature_append_vk_binding(struct d3d12_root_signature *
}
if (context->unbounded_offset != UINT_MAX)
d3d12_root_signature_append_descriptor_set_layout(root_signature, context, 0);
return d3d12_root_signature_append_descriptor_set_layout(root_signature, context, 0);
return S_OK;
}
static uint32_t d3d12_root_signature_assign_vk_bindings(struct d3d12_root_signature *root_signature,
static HRESULT d3d12_root_signature_assign_vk_bindings(struct d3d12_root_signature *root_signature,
enum vkd3d_shader_descriptor_type descriptor_type, unsigned int register_space, unsigned int base_register_idx,
unsigned int binding_count, bool is_buffer_descriptor, bool duplicate_descriptors,
enum vkd3d_shader_visibility shader_visibility, struct vkd3d_descriptor_set_context *context)
enum vkd3d_shader_visibility shader_visibility, struct vkd3d_descriptor_set_context *context,
uint32_t *first_binding)
{
uint32_t first_binding;
unsigned int i;
HRESULT hr;
is_buffer_descriptor |= descriptor_type == VKD3D_SHADER_DESCRIPTOR_TYPE_CBV;
duplicate_descriptors = (descriptor_type == VKD3D_SHADER_DESCRIPTOR_TYPE_SRV
|| descriptor_type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV)
&& duplicate_descriptors;
first_binding = context->descriptor_binding;
*first_binding = context->descriptor_binding;
for (i = 0; i < binding_count; ++i)
{
if (duplicate_descriptors)
d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, register_space,
base_register_idx + i, true, shader_visibility, 1, context);
if (duplicate_descriptors
&& FAILED(hr = d3d12_root_signature_append_vk_binding(root_signature, descriptor_type,
register_space, base_register_idx + i, true, shader_visibility, 1, context)))
return hr;
d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, register_space,
base_register_idx + i, is_buffer_descriptor, shader_visibility, 1, context);
if (FAILED(hr = d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, register_space,
base_register_idx + i, is_buffer_descriptor, shader_visibility, 1, context)))
return hr;
}
return first_binding;
return S_OK;
}
static uint32_t vkd3d_descriptor_magic_from_d3d12(D3D12_DESCRIPTOR_RANGE_TYPE type)
@ -764,6 +902,7 @@ static HRESULT d3d12_root_signature_init_descriptor_array_binding(struct d3d12_r
enum vkd3d_shader_visibility shader_visibility = vkd3d_shader_visibility_from_d3d12(visibility);
bool is_buffer = range->type == VKD3D_SHADER_DESCRIPTOR_TYPE_CBV;
enum vkd3d_shader_descriptor_type descriptor_type = range->type;
HRESULT hr;
if (range->descriptor_count == UINT_MAX)
context->unbounded_offset = range->offset;
@ -775,8 +914,9 @@ static HRESULT d3d12_root_signature_init_descriptor_array_binding(struct d3d12_r
return E_NOTIMPL;
++context->current_binding;
d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, range->register_space,
range->base_register_idx, true, shader_visibility, range->vk_binding_count, context);
if (FAILED(hr = d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, range->register_space,
range->base_register_idx, true, shader_visibility, range->vk_binding_count, context)))
return hr;
}
if (!vk_binding_from_d3d12_descriptor_range(context->current_binding,
@ -784,8 +924,9 @@ static HRESULT d3d12_root_signature_init_descriptor_array_binding(struct d3d12_r
return E_NOTIMPL;
++context->current_binding;
d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, range->register_space,
range->base_register_idx, is_buffer, shader_visibility, range->vk_binding_count, context);
if (FAILED(hr = d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, range->register_space,
range->base_register_idx, is_buffer, shader_visibility, range->vk_binding_count, context)))
return hr;
context->unbounded_offset = UINT_MAX;
@ -955,20 +1096,6 @@ static void d3d12_root_signature_map_descriptor_unbounded_binding(struct d3d12_r
descriptor_offset, is_buffer, shader_visibility, context);
}
static int compare_register_range(const void *a, const void *b)
{
const struct d3d12_root_descriptor_table_range *range_a = a, *range_b = b;
int ret;
if ((ret = vkd3d_u32_compare(range_a->type, range_b->type)))
return ret;
if ((ret = vkd3d_u32_compare(range_a->register_space, range_b->register_space)))
return ret;
return vkd3d_u32_compare(range_a->base_register_idx, range_b->base_register_idx);
}
static int compare_descriptor_range(const void *a, const void *b)
{
const struct d3d12_root_descriptor_table_range *range_a = a, *range_b = b;
@ -983,25 +1110,6 @@ static int compare_descriptor_range(const void *a, const void *b)
return (range_a->descriptor_count == UINT_MAX) - (range_b->descriptor_count == UINT_MAX);
}
static HRESULT validate_descriptor_register_ranges(const struct d3d12_root_descriptor_table_range *ranges,
unsigned int count)
{
const struct d3d12_root_descriptor_table_range *range, *prev;
unsigned int i;
for (i = 1; i < count; ++i)
{
range = &ranges[i];
prev = &ranges[i - 1];
if (range->type == prev->type && range->register_space == prev->register_space
&& range->base_register_idx - prev->base_register_idx < prev->descriptor_count)
return E_INVALIDARG;
}
return S_OK;
}
static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_root_signature *root_signature,
const D3D12_ROOT_SIGNATURE_DESC *desc, const struct d3d12_root_signature_info *info,
struct vkd3d_descriptor_set_context *context)
@ -1062,10 +1170,6 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo
offset += range->NumDescriptors;
}
qsort(table->ranges, range_count, sizeof(*table->ranges), compare_register_range);
if (FAILED(hr = validate_descriptor_register_ranges(table->ranges, range_count)))
return hr;
qsort(table->ranges, range_count, sizeof(*table->ranges), compare_descriptor_range);
for (j = 0; j < range_count; ++j)
@ -1130,9 +1234,10 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo
cur_binding = context->current_binding;
vk_binding = d3d12_root_signature_assign_vk_bindings(root_signature,
if (FAILED(hr = d3d12_root_signature_assign_vk_bindings(root_signature,
range->type, range->register_space, range->base_register_idx, range->descriptor_count, false, true,
shader_visibility, context);
shader_visibility, context, &vk_binding)))
return hr;
/* Unroll descriptor range. */
for (k = 0; k < range->descriptor_count; ++k)
@ -1175,6 +1280,7 @@ static HRESULT d3d12_root_signature_init_root_descriptors(struct d3d12_root_sign
{
VkDescriptorSetLayoutBinding *cur_binding = context->current_binding;
unsigned int i;
HRESULT hr;
root_signature->push_descriptor_mask = 0;
@ -1188,10 +1294,11 @@ static HRESULT d3d12_root_signature_init_root_descriptors(struct d3d12_root_sign
root_signature->push_descriptor_mask |= 1u << i;
cur_binding->binding = d3d12_root_signature_assign_vk_bindings(root_signature,
if (FAILED(hr = d3d12_root_signature_assign_vk_bindings(root_signature,
vkd3d_descriptor_type_from_d3d12_root_parameter_type(p->ParameterType),
p->u.Descriptor.RegisterSpace, p->u.Descriptor.ShaderRegister, 1, true, false,
vkd3d_shader_visibility_from_d3d12(p->ShaderVisibility), context);
vkd3d_shader_visibility_from_d3d12(p->ShaderVisibility), context, &cur_binding->binding)))
return hr;
cur_binding->descriptorType = vk_descriptor_type_from_d3d12_root_parameter(p->ParameterType);
cur_binding->descriptorCount = 1;
cur_binding->stageFlags = stage_flags_from_visibility(p->ShaderVisibility);
@ -1215,7 +1322,7 @@ static HRESULT d3d12_root_signature_init_static_samplers(struct d3d12_root_signa
unsigned int i;
HRESULT hr;
assert(root_signature->static_sampler_count == desc->NumStaticSamplers);
VKD3D_ASSERT(root_signature->static_sampler_count == desc->NumStaticSamplers);
for (i = 0; i < desc->NumStaticSamplers; ++i)
{
const D3D12_STATIC_SAMPLER_DESC *s = &desc->pStaticSamplers[i];
@ -1223,9 +1330,10 @@ static HRESULT d3d12_root_signature_init_static_samplers(struct d3d12_root_signa
if (FAILED(hr = vkd3d_create_static_sampler(device, s, &root_signature->static_samplers[i])))
return hr;
cur_binding->binding = d3d12_root_signature_assign_vk_bindings(root_signature,
if (FAILED(hr = d3d12_root_signature_assign_vk_bindings(root_signature,
VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, s->RegisterSpace, s->ShaderRegister, 1, false, false,
vkd3d_shader_visibility_from_d3d12(s->ShaderVisibility), context);
vkd3d_shader_visibility_from_d3d12(s->ShaderVisibility), context, &cur_binding->binding)))
return hr;
cur_binding->descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
cur_binding->descriptorCount = 1;
cur_binding->stageFlags = stage_flags_from_visibility(s->ShaderVisibility);
@ -1600,7 +1708,7 @@ static HRESULT vkd3d_render_pass_cache_create_pass_locked(struct vkd3d_render_pa
have_depth_stencil = key->depth_enable || key->stencil_enable;
rt_count = have_depth_stencil ? key->attachment_count - 1 : key->attachment_count;
assert(rt_count <= D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT);
VKD3D_ASSERT(rt_count <= D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT);
for (index = 0, attachment_index = 0; index < rt_count; ++index)
{
@ -2140,7 +2248,7 @@ struct d3d12_pipeline_state *unsafe_impl_from_ID3D12PipelineState(ID3D12Pipeline
{
if (!iface)
return NULL;
assert(iface->lpVtbl == &d3d12_pipeline_state_vtbl);
VKD3D_ASSERT(iface->lpVtbl == &d3d12_pipeline_state_vtbl);
return impl_from_ID3D12PipelineState(iface);
}
@ -2178,7 +2286,7 @@ static HRESULT create_shader_stage(struct d3d12_device *device,
const struct vkd3d_shader_compile_option options[] =
{
{VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_12},
{VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_13},
{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)},
@ -2233,7 +2341,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_12},
{VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_13},
{VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV, typed_uav_compile_option(device)},
};
@ -2296,7 +2404,7 @@ static HRESULT d3d12_pipeline_state_init_uav_counters(struct d3d12_pipeline_stat
unsigned int i, j;
HRESULT hr;
assert(vkd3d_popcount(stage_flags) == 1);
VKD3D_ASSERT(vkd3d_popcount(stage_flags) == 1);
for (i = 0; i < shader_info->descriptor_count; ++i)
{
@ -2911,7 +3019,7 @@ static HRESULT d3d12_graphics_pipeline_state_create_render_pass(
if (dsv_format)
{
assert(graphics->ds_desc.front.writeMask == graphics->ds_desc.back.writeMask);
VKD3D_ASSERT(graphics->ds_desc.front.writeMask == graphics->ds_desc.back.writeMask);
key.depth_enable = graphics->ds_desc.depthTestEnable;
key.stencil_enable = graphics->ds_desc.stencilTestEnable;
key.depth_stencil_write = graphics->ds_desc.depthWriteEnable
@ -2928,7 +3036,7 @@ static HRESULT d3d12_graphics_pipeline_state_create_render_pass(
if (key.attachment_count != ARRAY_SIZE(key.vk_formats))
key.vk_formats[ARRAY_SIZE(key.vk_formats) - 1] = VK_FORMAT_UNDEFINED;
for (i = key.attachment_count; i < ARRAY_SIZE(key.vk_formats); ++i)
assert(key.vk_formats[i] == VK_FORMAT_UNDEFINED);
VKD3D_ASSERT(key.vk_formats[i] == VK_FORMAT_UNDEFINED);
key.padding = 0;
key.sample_count = graphics->ms_desc.rasterizationSamples;
@ -3476,7 +3584,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
graphics->ms_desc.pSampleMask = NULL;
if (desc->sample_mask != ~0u)
{
assert(DIV_ROUND_UP(sample_count, 32) <= ARRAY_SIZE(graphics->sample_mask));
VKD3D_ASSERT(DIV_ROUND_UP(sample_count, 32) <= ARRAY_SIZE(graphics->sample_mask));
graphics->sample_mask[0] = desc->sample_mask;
graphics->sample_mask[1] = 0xffffffffu;
graphics->ms_desc.pSampleMask = graphics->sample_mask;
@ -3769,7 +3877,7 @@ VkPipeline d3d12_pipeline_state_get_or_create_pipeline(struct d3d12_pipeline_sta
.pDynamicStates = dynamic_states,
};
assert(d3d12_pipeline_state_is_graphics(state));
VKD3D_ASSERT(d3d12_pipeline_state_is_graphics(state));
memset(&pipeline_key, 0, sizeof(pipeline_key));
pipeline_key.topology = topology;
@ -3911,7 +4019,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_12},
{VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_13},
};
info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO;

View file

@ -331,7 +331,7 @@ static HRESULT vkd3d_init_format_compatibility_lists(struct d3d12_device *device
if (j >= current_list->format_count)
{
assert(current_list->format_count < VKD3D_MAX_COMPATIBLE_FORMAT_COUNT);
VKD3D_ASSERT(current_list->format_count < VKD3D_MAX_COMPATIBLE_FORMAT_COUNT);
current_list->vk_formats[current_list->format_count++] = vk_format;
}
}
@ -427,7 +427,7 @@ static const struct vkd3d_format *vkd3d_get_depth_stencil_format(const struct d3
const struct vkd3d_format *formats;
unsigned int i;
assert(device);
VKD3D_ASSERT(device);
formats = device->depth_stencil_formats;
for (i = 0; i < ARRAY_SIZE(vkd3d_depth_stencil_formats); ++i)

View file

@ -38,12 +38,12 @@ HRESULT vkd3d_create_device(const struct vkd3d_device_create_info *create_info,
}
if (!create_info->instance && !create_info->instance_create_info)
{
ERR("Instance or instance create info is required.\n");
WARN("Instance or instance create info is required.\n");
return E_INVALIDARG;
}
if (create_info->instance && create_info->instance_create_info)
{
ERR("Instance and instance create info are mutually exclusive parameters.\n");
WARN("Instance and instance create info are mutually exclusive parameters.\n");
return E_INVALIDARG;
}
@ -153,7 +153,7 @@ static const D3D12_ROOT_SIGNATURE_DESC * STDMETHODCALLTYPE d3d12_root_signature_
TRACE("iface %p.\n", iface);
assert(deserializer->desc.d3d12.Version == D3D_ROOT_SIGNATURE_VERSION_1_0);
VKD3D_ASSERT(deserializer->desc.d3d12.Version == D3D_ROOT_SIGNATURE_VERSION_1_0);
return &deserializer->desc.d3d12.u.Desc_1_0;
}
@ -354,7 +354,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_versioned_root_signature_deserializer_Get
}
}
assert(deserializer->other_desc.d3d12.Version == version);
VKD3D_ASSERT(deserializer->other_desc.d3d12.Version == version);
*desc = &deserializer->other_desc.d3d12;
return S_OK;
}

View file

@ -37,7 +37,6 @@
#include "vkd3d.h"
#include "vkd3d_shader.h"
#include <assert.h>
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
@ -123,6 +122,7 @@ struct vkd3d_vulkan_info
bool KHR_image_format_list;
bool KHR_maintenance2;
bool KHR_maintenance3;
bool KHR_portability_subset;
bool KHR_push_descriptor;
bool KHR_sampler_mirror_clamp_to_edge;
bool KHR_timeline_semaphore;
@ -145,6 +145,8 @@ struct vkd3d_vulkan_info
bool rasterization_stream;
bool transform_feedback_queries;
bool geometry_shaders;
bool tessellation_shaders;
bool uav_read_without_format;
@ -676,7 +678,7 @@ static inline void *d3d12_desc_get_object_ref(const volatile struct d3d12_desc *
void *view;
/* Some games, e.g. Shadow of the Tomb Raider, GRID 2019, and Horizon Zero Dawn, write descriptors
* from multiple threads without syncronisation. This is apparently valid in Windows. */
* from multiple threads without synchronisation. This is apparently valid in Windows. */
for (;;)
{
do
@ -784,8 +786,8 @@ extern const enum vkd3d_vk_descriptor_set_index vk_descriptor_set_index_table[];
static inline enum vkd3d_vk_descriptor_set_index vkd3d_vk_descriptor_set_index_from_vk_descriptor_type(
VkDescriptorType type)
{
assert(type <= VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
assert(vk_descriptor_set_index_table[type] < VKD3D_SET_INDEX_COUNT);
VKD3D_ASSERT(type <= VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
VKD3D_ASSERT(vk_descriptor_set_index_table[type] < VKD3D_SET_INDEX_COUNT);
return vk_descriptor_set_index_table[type];
}
@ -1229,7 +1231,7 @@ enum vkd3d_pipeline_bind_point
/* ID3D12CommandList */
struct d3d12_command_list
{
ID3D12GraphicsCommandList5 ID3D12GraphicsCommandList5_iface;
ID3D12GraphicsCommandList6 ID3D12GraphicsCommandList6_iface;
unsigned int refcount;
D3D12_COMMAND_LIST_TYPE type;
@ -1753,7 +1755,6 @@ static inline void vk_prepend_struct(void *header, void *structure)
{
VkBaseOutStructure *vk_header = header, *vk_structure = structure;
assert(!vk_structure->pNext);
vk_structure->pNext = vk_header->pNext;
vk_header->pNext = vk_structure;
}
@ -1766,7 +1767,7 @@ static inline void vkd3d_prepend_struct(void *header, void *structure)
const void *next;
} *vkd3d_header = header, *vkd3d_structure = structure;
assert(!vkd3d_structure->next);
VKD3D_ASSERT(!vkd3d_structure->next);
vkd3d_structure->next = vkd3d_header->next;
vkd3d_header->next = vkd3d_structure;
}