diff --git a/dll/directx/wine/d3d12/d3d12_main.c b/dll/directx/wine/d3d12/d3d12_main.c index 74f0c0930bb7e..2dddfe60efe27 100644 --- a/dll/directx/wine/d3d12/d3d12_main.c +++ b/dll/directx/wine/d3d12/d3d12_main.c @@ -17,36 +17,25 @@ * */ -#include "config.h" -#include "wine/port.h" - #define COBJMACROS -#define VK_NO_PROTOTYPES #define VKD3D_NO_VULKAN_H #define VKD3D_NO_WIN32_TYPES -#ifndef USE_WIN32_VULKAN -#define USE_WIN32_VULKAN -#endif - -#include "wine/debug.h" -#include "wine/heap.h" -#include "wine/vulkan.h" -#include "wine/vulkan_driver.h" +#include "windef.h" #include "dxgi1_6.h" #include "d3d12.h" +#include "wine/vulkan.h" #include #include "initguid.h" #include "wine/wined3d.h" #include "wine/winedxgi.h" +#include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(d3d12); WINE_DECLARE_DEBUG_CHANNEL(winediag); -#ifdef USE_WIN32_VULKAN - static HMODULE vulkan_module; /* FIXME: We should unload vulkan-1.dll. */ @@ -68,25 +57,6 @@ static PFN_vkGetInstanceProcAddr load_vulkan(void) return NULL; } -#else - -static PFN_vkGetInstanceProcAddr load_vulkan(void) -{ - const struct vulkan_funcs *vk_funcs; - HDC hdc; - - hdc = GetDC(0); - vk_funcs = __wine_get_vulkan_driver(hdc, WINE_VULKAN_DRIVER_VERSION); - ReleaseDC(0, hdc); - - if (vk_funcs) - return (PFN_vkGetInstanceProcAddr)vk_funcs->p_vkGetInstanceProcAddr; - - return NULL; -} - -#endif /* USE_WIN32_VULKAN */ - HRESULT WINAPI D3D12GetDebugInterface(REFIID iid, void **debug) { TRACE("iid %s, debug %p.\n", debugstr_guid(iid), debug); @@ -109,52 +79,6 @@ static HRESULT d3d12_signal_event(HANDLE event) return SetEvent(event) ? S_OK : E_FAIL; } -struct d3d12_thread_data -{ - PFN_vkd3d_thread main_pfn; - void *data; -}; - -static DWORD WINAPI d3d12_thread_main(void *data) -{ - struct d3d12_thread_data *thread_data = data; - - thread_data->main_pfn(thread_data->data); - heap_free(thread_data); - return 0; -} - -static void *d3d12_create_thread(PFN_vkd3d_thread main_pfn, void *data) -{ - struct d3d12_thread_data *thread_data; - HANDLE thread; - - if (!(thread_data = heap_alloc(sizeof(*thread_data)))) - { - ERR("Failed to allocate thread data.\n"); - return NULL; - } - - thread_data->main_pfn = main_pfn; - thread_data->data = data; - - if (!(thread = CreateThread(NULL, 0, d3d12_thread_main, thread_data, 0, NULL))) - heap_free(thread_data); - - return thread; -} - -static HRESULT d3d12_join_thread(void *handle) -{ - HANDLE thread = handle; - DWORD ret; - - if ((ret = WaitForSingleObject(thread, INFINITE)) != WAIT_OBJECT_0) - ERR("Failed to wait for thread, ret %#x.\n", ret); - CloseHandle(thread); - return ret == WAIT_OBJECT_0 ? S_OK : E_FAIL; -} - static HRESULT d3d12_get_adapter(IWineDXGIAdapter **wine_adapter, IUnknown *adapter) { IDXGIAdapter *dxgi_adapter = NULL; @@ -165,13 +89,13 @@ static HRESULT d3d12_get_adapter(IWineDXGIAdapter **wine_adapter, IUnknown *adap { if (FAILED(hr = CreateDXGIFactory2(0, &IID_IDXGIFactory4, (void **)&factory))) { - WARN("Failed to create DXGI factory, hr %#x.\n", hr); + WARN("Failed to create DXGI factory, hr %#lx.\n", hr); goto done; } if (FAILED(hr = IDXGIFactory4_EnumAdapters(factory, 0, &dxgi_adapter))) { - WARN("Failed to enumerate primary adapter, hr %#x.\n", hr); + WARN("Failed to enumerate primary adapter, hr %#lx.\n", hr); goto done; } @@ -179,7 +103,7 @@ static HRESULT d3d12_get_adapter(IWineDXGIAdapter **wine_adapter, IUnknown *adap } if (FAILED(hr = IUnknown_QueryInterface(adapter, &IID_IWineDXGIAdapter, (void **)wine_adapter))) - WARN("Invalid adapter %p, hr %#x.\n", adapter, hr); + WARN("Invalid adapter %p, hr %#lx.\n", adapter, hr); done: if (dxgi_adapter) @@ -205,7 +129,7 @@ static BOOL check_vk_instance_extension(VkInstance vk_instance, if (pfn_vkEnumerateInstanceExtensionProperties(NULL, &count, NULL) < 0) return FALSE; - if (!(properties = heap_calloc(count, sizeof(*properties)))) + if (!(properties = calloc(count, sizeof(*properties)))) return FALSE; if (pfn_vkEnumerateInstanceExtensionProperties(NULL, &count, properties) >= 0) @@ -220,7 +144,7 @@ static BOOL check_vk_instance_extension(VkInstance vk_instance, } } - heap_free(properties); + free(properties); return ret; } @@ -259,13 +183,15 @@ static VkPhysicalDevice d3d12_get_vk_physical_device(struct vkd3d_instance *inst return VK_NULL_HANDLE; } - if (!(vk_physical_devices = heap_calloc(count, sizeof(*vk_physical_devices)))) + if (!(vk_physical_devices = calloc(count, sizeof(*vk_physical_devices)))) return VK_NULL_HANDLE; if ((vr = pfn_vkEnumeratePhysicalDevices(vk_instance, &count, vk_physical_devices)) < 0) goto done; - if (!IsEqualGUID(&adapter_info->driver_uuid, &GUID_NULL) && pfn_vkGetPhysicalDeviceProperties2) + if (!IsEqualGUID(&adapter_info->driver_uuid, &GUID_NULL) && pfn_vkGetPhysicalDeviceProperties2 + && check_vk_instance_extension(vk_instance, pfn_vkGetInstanceProcAddr, + VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME)) { TRACE("Matching adapters by UUIDs.\n"); @@ -308,7 +234,7 @@ static VkPhysicalDevice d3d12_get_vk_physical_device(struct vkd3d_instance *inst FIXME("Could not find Vulkan physical device for DXGI adapter.\n"); done: - heap_free(vk_physical_devices); + free(vk_physical_devices); return vk_physical_device; } @@ -331,12 +257,18 @@ HRESULT WINAPI D3D12CreateDevice(IUnknown *adapter, D3D_FEATURE_LEVEL minimum_fe }; static const char * const optional_instance_extensions[] = { + VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, }; static const char * const device_extensions[] = { VK_KHR_SWAPCHAIN_EXTENSION_NAME, }; + static const struct vkd3d_application_info application_info = + { + .type = VKD3D_STRUCTURE_TYPE_APPLICATION_INFO, + .api_version = VKD3D_API_VERSION_1_2, + }; TRACE("adapter %p, minimum_feature_level %#x, iid %s, device %p.\n", adapter, minimum_feature_level, debugstr_guid(iid), device); @@ -352,20 +284,20 @@ HRESULT WINAPI D3D12CreateDevice(IUnknown *adapter, D3D_FEATURE_LEVEL minimum_fe if (FAILED(hr = IWineDXGIAdapter_get_adapter_info(wine_adapter, &adapter_info))) { - WARN("Failed to get adapter info, hr %#x.\n", hr); + WARN("Failed to get adapter info, hr %#lx.\n", hr); goto done; } optional_extensions_info.type = VKD3D_STRUCTURE_TYPE_OPTIONAL_INSTANCE_EXTENSIONS_INFO; - optional_extensions_info.next = NULL; + optional_extensions_info.next = &application_info; optional_extensions_info.extensions = optional_instance_extensions; optional_extensions_info.extension_count = ARRAY_SIZE(optional_instance_extensions); instance_create_info.type = VKD3D_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; instance_create_info.next = &optional_extensions_info; instance_create_info.pfn_signal_event = d3d12_signal_event; - instance_create_info.pfn_create_thread = d3d12_create_thread; - instance_create_info.pfn_join_thread = d3d12_join_thread; + instance_create_info.pfn_create_thread = NULL; + instance_create_info.pfn_join_thread = NULL; instance_create_info.wchar_size = sizeof(WCHAR); instance_create_info.pfn_vkGetInstanceProcAddr = pfn_vkGetInstanceProcAddr; instance_create_info.instance_extensions = instance_extensions; @@ -373,7 +305,7 @@ HRESULT WINAPI D3D12CreateDevice(IUnknown *adapter, D3D_FEATURE_LEVEL minimum_fe if (FAILED(hr = vkd3d_create_instance(&instance_create_info, &instance))) { - WARN("Failed to create vkd3d instance, hr %#x.\n", hr); + WARN("Failed to create vkd3d instance, hr %#lx.\n", hr); goto done; } @@ -400,12 +332,21 @@ HRESULT WINAPI D3D12CreateDevice(IUnknown *adapter, D3D_FEATURE_LEVEL minimum_fe HRESULT WINAPI D3D12CreateRootSignatureDeserializer(const void *data, SIZE_T data_size, REFIID iid, void **deserializer) { - TRACE("data %p, data_size %lu, iid %s, deserializer %p.\n", + TRACE("data %p, data_size %Iu, iid %s, deserializer %p.\n", data, data_size, debugstr_guid(iid), deserializer); return vkd3d_create_root_signature_deserializer(data, data_size, iid, deserializer); } +HRESULT WINAPI D3D12CreateVersionedRootSignatureDeserializer(const void *data, SIZE_T data_size, + REFIID iid, void **deserializer) +{ + TRACE("data %p, data_size %Iu, iid %s, deserializer %p.\n", + data, data_size, debugstr_guid(iid), deserializer); + + return vkd3d_create_versioned_root_signature_deserializer(data, data_size, iid, deserializer); +} + HRESULT WINAPI D3D12SerializeRootSignature(const D3D12_ROOT_SIGNATURE_DESC *root_signature_desc, D3D_ROOT_SIGNATURE_VERSION version, ID3DBlob **blob, ID3DBlob **error_blob) { @@ -420,9 +361,5 @@ HRESULT WINAPI D3D12SerializeVersionedRootSignature(const D3D12_VERSIONED_ROOT_S { TRACE("desc %p, blob %p, error_blob %p.\n", desc, blob, error_blob); - if (desc->Version == D3D_ROOT_SIGNATURE_VERSION_1_0) - return vkd3d_serialize_root_signature(&desc->Desc_1_0, desc->Version, blob, error_blob); - - FIXME("Unsupported version %#x.\n", desc->Version); - return E_NOTIMPL; + return vkd3d_serialize_versioned_root_signature(desc, blob, error_blob); } diff --git a/dll/directx/wine/d3d12/vkd3d/CMakeLists.txt b/dll/directx/wine/d3d12/vkd3d/CMakeLists.txt deleted file mode 100644 index 9000d64439fe7..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -include_directories("include/") -include_directories(${CMAKE_CURRENT_BINARY_DIR}/include/) -add_subdirectory(include) -add_subdirectory(vkd3d) -add_subdirectory(vkd3d-common) -add_subdirectory(vkd3d-shader) -#add_subdirectory(vkd3d-utils) diff --git a/dll/directx/wine/d3d12/vkd3d/include/.gitignore b/dll/directx/wine/d3d12/vkd3d/include/.gitignore deleted file mode 100644 index 37b101d465b2c..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/include/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -config.h -config.h.in -private/vkd3d_version.h -stamp-h1 -vkd3d_d3d12.h -vkd3d_d3d12sdklayers.h -vkd3d_d3dcommon.h -vkd3d_d3dx9shader.h -vkd3d_dxgi.h -vkd3d_dxgi1_2.h -vkd3d_dxgi1_3.h -vkd3d_dxgi1_4.h -vkd3d_dxgibase.h -vkd3d_dxgiformat.h -vkd3d_dxgitype.h diff --git a/dll/directx/wine/d3d12/vkd3d/include/CMakeLists.txt b/dll/directx/wine/d3d12/vkd3d/include/CMakeLists.txt deleted file mode 100644 index 5903e88dd3942..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/include/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -list(APPEND VKD3DIDL - vkd3d_d3d12.idl - vkd3d_d3d12sdklayers.idl - vkd3d_d3dcommon.idl - vkd3d_dxgi.idl - vkd3d_d3dx9shader.idl - vkd3d_dxgi1_2.idl - vkd3d_dxgi1_3.idl - vkd3d_dxgi1_4.idl - vkd3d_dxgibase.idl - vkd3d_dxgiformat.idl - vkd3d_dxgitype.idl - vkd3d_unknown.idl) - -add_idl_headers(vkd3d_idl_headers ${VKD3DIDL}) \ No newline at end of file diff --git a/dll/directx/wine/d3d12/vkd3d/include/private/list.h b/dll/directx/wine/d3d12/vkd3d/include/private/list.h deleted file mode 100644 index b4d681fe0f31a..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/include/private/list.h +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Linked lists support - * - * Copyright (C) 2002 Alexandre Julliard - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef __WINE_SERVER_LIST_H -#define __WINE_SERVER_LIST_H - -#include - -struct list -{ - struct list *next; - struct list *prev; -}; - -/* Define a list like so: - * - * struct gadget - * { - * struct list entry; <-- doesn't have to be the first item in the struct - * int a, b; - * }; - * - * static struct list global_gadgets = LIST_INIT( global_gadgets ); - * - * or - * - * struct some_global_thing - * { - * struct list gadgets; - * }; - * - * list_init( &some_global_thing->gadgets ); - * - * Manipulate it like this: - * - * list_add_head( &global_gadgets, &new_gadget->entry ); - * list_remove( &new_gadget->entry ); - * list_add_after( &some_random_gadget->entry, &new_gadget->entry ); - * - * And to iterate over it: - * - * struct gadget *gadget; - * LIST_FOR_EACH_ENTRY( gadget, &global_gadgets, struct gadget, entry ) - * { - * ... - * } - * - */ - -/* add an element after the specified one */ -static inline void list_add_after( struct list *elem, struct list *to_add ) -{ - to_add->next = elem->next; - to_add->prev = elem; - elem->next->prev = to_add; - elem->next = to_add; -} - -/* add an element before the specified one */ -static inline void list_add_before( struct list *elem, struct list *to_add ) -{ - to_add->next = elem; - to_add->prev = elem->prev; - elem->prev->next = to_add; - elem->prev = to_add; -} - -/* add element at the head of the list */ -static inline void list_add_head( struct list *list, struct list *elem ) -{ - list_add_after( list, elem ); -} - -/* add element at the tail of the list */ -static inline void list_add_tail( struct list *list, struct list *elem ) -{ - list_add_before( list, elem ); -} - -/* remove an element from its list */ -static inline void list_remove( struct list *elem ) -{ - elem->next->prev = elem->prev; - elem->prev->next = elem->next; -} - -/* get the next element */ -static inline struct list *list_next( const struct list *list, const struct list *elem ) -{ - struct list *ret = elem->next; - if (elem->next == list) ret = NULL; - return ret; -} - -/* get the previous element */ -static inline struct list *list_prev( const struct list *list, const struct list *elem ) -{ - struct list *ret = elem->prev; - if (elem->prev == list) ret = NULL; - return ret; -} - -/* get the first element */ -static inline struct list *list_head( const struct list *list ) -{ - return list_next( list, list ); -} - -/* get the last element */ -static inline struct list *list_tail( const struct list *list ) -{ - return list_prev( list, list ); -} - -/* check if a list is empty */ -static inline int list_empty( const struct list *list ) -{ - return list->next == list; -} - -/* initialize a list */ -static inline void list_init( struct list *list ) -{ - list->next = list->prev = list; -} - -/* count the elements of a list */ -static inline unsigned int list_count( const struct list *list ) -{ - unsigned count = 0; - const struct list *ptr; - for (ptr = list->next; ptr != list; ptr = ptr->next) count++; - return count; -} - -/* move all elements from src to the tail of dst */ -static inline void list_move_tail( struct list *dst, struct list *src ) -{ - if (list_empty(src)) return; - - dst->prev->next = src->next; - src->next->prev = dst->prev; - dst->prev = src->prev; - src->prev->next = dst; - list_init(src); -} - -/* move all elements from src to the head of dst */ -static inline void list_move_head( struct list *dst, struct list *src ) -{ - if (list_empty(src)) return; - - dst->next->prev = src->prev; - src->prev->next = dst->next; - dst->next = src->next; - src->next->prev = dst; - list_init(src); -} - -/* iterate through the list */ -#define LIST_FOR_EACH(cursor,list) \ - for ((cursor) = (list)->next; (cursor) != (list); (cursor) = (cursor)->next) - -/* iterate through the list, with safety against removal */ -#define LIST_FOR_EACH_SAFE(cursor, cursor2, list) \ - for ((cursor) = (list)->next, (cursor2) = (cursor)->next; \ - (cursor) != (list); \ - (cursor) = (cursor2), (cursor2) = (cursor)->next) - -/* iterate through the list using a list entry */ -#define LIST_FOR_EACH_ENTRY(elem, list, type, field) \ - for ((elem) = LIST_ENTRY((list)->next, type, field); \ - &(elem)->field != (list); \ - (elem) = LIST_ENTRY((elem)->field.next, type, field)) - -/* iterate through the list using a list entry, with safety against removal */ -#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field) \ - for ((cursor) = LIST_ENTRY((list)->next, type, field), \ - (cursor2) = LIST_ENTRY((cursor)->field.next, type, field); \ - &(cursor)->field != (list); \ - (cursor) = (cursor2), \ - (cursor2) = LIST_ENTRY((cursor)->field.next, type, field)) - -/* iterate through the list in reverse order */ -#define LIST_FOR_EACH_REV(cursor,list) \ - for ((cursor) = (list)->prev; (cursor) != (list); (cursor) = (cursor)->prev) - -/* iterate through the list in reverse order, with safety against removal */ -#define LIST_FOR_EACH_SAFE_REV(cursor, cursor2, list) \ - for ((cursor) = (list)->prev, (cursor2) = (cursor)->prev; \ - (cursor) != (list); \ - (cursor) = (cursor2), (cursor2) = (cursor)->prev) - -/* iterate through the list in reverse order using a list entry */ -#define LIST_FOR_EACH_ENTRY_REV(elem, list, type, field) \ - for ((elem) = LIST_ENTRY((list)->prev, type, field); \ - &(elem)->field != (list); \ - (elem) = LIST_ENTRY((elem)->field.prev, type, field)) - -/* iterate through the list in reverse order using a list entry, with safety against removal */ -#define LIST_FOR_EACH_ENTRY_SAFE_REV(cursor, cursor2, list, type, field) \ - for ((cursor) = LIST_ENTRY((list)->prev, type, field), \ - (cursor2) = LIST_ENTRY((cursor)->field.prev, type, field); \ - &(cursor)->field != (list); \ - (cursor) = (cursor2), \ - (cursor2) = LIST_ENTRY((cursor)->field.prev, type, field)) - -/* macros for statically initialized lists */ -#undef LIST_INIT -#define LIST_INIT(list) { &(list), &(list) } - -/* get pointer to object containing list element */ -#undef LIST_ENTRY -#define LIST_ENTRY(elem, type, field) \ - ((type *)((char *)(elem) - offsetof(type, field))) - -#endif /* __WINE_SERVER_LIST_H */ diff --git a/dll/directx/wine/d3d12/vkd3d/include/private/vkd3d_shader.h b/dll/directx/wine/d3d12/vkd3d/include/private/vkd3d_shader.h deleted file mode 100644 index 61789d63e2467..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/include/private/vkd3d_shader.h +++ /dev/null @@ -1,418 +0,0 @@ -/* - * Copyright 2017 Józef Kucia for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef __VKD3D_SHADER_H -#define __VKD3D_SHADER_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#define VKD3D_FORCE_32_BIT_ENUM(name) name##_FORCE_32BIT = 0x7fffffff - -enum vkd3d_result -{ - VKD3D_OK = 0, - VKD3D_ERROR = -1, /* unspecified failure */ - VKD3D_ERROR_OUT_OF_MEMORY = -2, - VKD3D_ERROR_INVALID_ARGUMENT = -3, - VKD3D_ERROR_NOT_IMPLEMENTED = -4, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_RESULT), -}; - -enum vkd3d_shader_compiler_option -{ - VKD3D_SHADER_STRIP_DEBUG = 0x00000001, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILER_OPTION), -}; - -enum vkd3d_shader_visibility -{ - VKD3D_SHADER_VISIBILITY_ALL = 0, - VKD3D_SHADER_VISIBILITY_VERTEX = 1, - VKD3D_SHADER_VISIBILITY_HULL = 2, - VKD3D_SHADER_VISIBILITY_DOMAIN = 3, - VKD3D_SHADER_VISIBILITY_GEOMETRY = 4, - VKD3D_SHADER_VISIBILITY_PIXEL = 5, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_VISIBILITY), -}; - -struct vkd3d_shader_code -{ - const void *code; - size_t size; -}; - -enum vkd3d_shader_descriptor_type -{ - VKD3D_SHADER_DESCRIPTOR_TYPE_UNKNOWN, - VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, /* cb# */ - VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, /* t# */ - VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, /* u# */ - VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, /* s# */ - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_DESCRIPTOR_TYPE), -}; - -struct vkd3d_shader_descriptor_binding -{ - uint32_t set; - uint32_t binding; -}; - -struct vkd3d_shader_resource_binding -{ - enum vkd3d_shader_descriptor_type type; - unsigned int register_index; - enum vkd3d_shader_visibility shader_visibility; - bool is_buffer; - - struct vkd3d_shader_descriptor_binding binding; -}; - -struct vkd3d_shader_uav_counter_binding -{ - unsigned int register_index; /* u# */ - - struct vkd3d_shader_descriptor_binding binding; -}; - -struct vkd3d_shader_push_constant_buffer -{ - unsigned int register_index; - enum vkd3d_shader_visibility shader_visibility; - - unsigned int offset; /* in bytes */ - unsigned int size; /* in bytes */ -}; - -struct vkd3d_shader_interface -{ - const struct vkd3d_shader_resource_binding *bindings; - unsigned int binding_count; - - const struct vkd3d_shader_push_constant_buffer *push_constant_buffers; - unsigned int push_constant_buffer_count; - - /* A sampler used by OpImageFetches generated for SM4 ld instructions. - * - * In Vulkan OpImageFetch must be used with a sampled image. - */ - struct vkd3d_shader_descriptor_binding dummy_sampler; - - const struct vkd3d_shader_uav_counter_binding *uav_counters; - unsigned int uav_counter_count; -}; - -struct vkd3d_shader_compile_arguments -{ - unsigned int *output_swizzles; - unsigned int output_swizzle_count; -}; - -int vkd3d_shader_compile_dxbc(const struct vkd3d_shader_code *dxbc, - struct vkd3d_shader_code *spirv, uint32_t compiler_options, - const struct vkd3d_shader_interface *shader_interface, - const struct vkd3d_shader_compile_arguments *compile_args); -void vkd3d_shader_free_shader_code(struct vkd3d_shader_code *code); - -enum vkd3d_filter -{ - VKD3D_FILTER_MIN_MAG_MIP_POINT = 0x0, - VKD3D_FILTER_MIN_MAG_POINT_MIP_LINEAR = 0x1, - VKD3D_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x4, - VKD3D_FILTER_MIN_POINT_MAG_MIP_LINEAR = 0x5, - VKD3D_FILTER_MIN_LINEAR_MAG_MIP_POINT = 0x10, - VKD3D_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x11, - VKD3D_FILTER_MIN_MAG_LINEAR_MIP_POINT = 0x14, - VKD3D_FILTER_MIN_MAG_MIP_LINEAR = 0x15, - VKD3D_FILTER_ANISOTROPIC = 0x55, - VKD3D_FILTER_COMPARISON_MIN_MAG_MIP_POINT = 0x80, - VKD3D_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR = 0x81, - VKD3D_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x84, - VKD3D_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR = 0x85, - VKD3D_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT = 0x90, - VKD3D_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x91, - VKD3D_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT = 0x94, - VKD3D_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR = 0x95, - VKD3D_FILTER_COMPARISON_ANISOTROPIC = 0xd5, - VKD3D_FILTER_MINIMUM_MIN_MAG_MIP_POINT = 0x100, - VKD3D_FILTER_MINIMUM_MIN_MAG_POINT_MIP_LINEAR = 0x101, - VKD3D_FILTER_MINIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x104, - VKD3D_FILTER_MINIMUM_MIN_POINT_MAG_MIP_LINEAR = 0x105, - VKD3D_FILTER_MINIMUM_MIN_LINEAR_MAG_MIP_POINT = 0x110, - VKD3D_FILTER_MINIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x111, - VKD3D_FILTER_MINIMUM_MIN_MAG_LINEAR_MIP_POINT = 0x114, - VKD3D_FILTER_MINIMUM_MIN_MAG_MIP_LINEAR = 0x115, - VKD3D_FILTER_MINIMUM_ANISOTROPIC = 0x155, - VKD3D_FILTER_MAXIMUM_MIN_MAG_MIP_POINT = 0x180, - VKD3D_FILTER_MAXIMUM_MIN_MAG_POINT_MIP_LINEAR = 0x181, - VKD3D_FILTER_MAXIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x184, - VKD3D_FILTER_MAXIMUM_MIN_POINT_MAG_MIP_LINEAR = 0x185, - VKD3D_FILTER_MAXIMUM_MIN_LINEAR_MAG_MIP_POINT = 0x190, - VKD3D_FILTER_MAXIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x191, - VKD3D_FILTER_MAXIMUM_MIN_MAG_LINEAR_MIP_POINT = 0x194, - VKD3D_FILTER_MAXIMUM_MIN_MAG_MIP_LINEAR = 0x195, - VKD3D_FILTER_MAXIMUM_ANISOTROPIC = 0x1d5, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_FILTER), -}; - -enum vkd3d_texture_address_mode -{ - VKD3D_TEXTURE_ADDRESS_MODE_WRAP = 1, - VKD3D_TEXTURE_ADDRESS_MODE_MIRROR = 2, - VKD3D_TEXTURE_ADDRESS_MODE_CLAMP = 3, - VKD3D_TEXTURE_ADDRESS_MODE_BORDER = 4, - VKD3D_TEXTURE_ADDRESS_MODE_MIRROR_ONCE = 5, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_TEXTURE_ADDRESS_MODE), -}; - -enum vkd3d_comparison_func -{ - VKD3D_COMPARISON_FUNC_NEVER = 1, - VKD3D_COMPARISON_FUNC_LESS = 2, - VKD3D_COMPARISON_FUNC_EQUAL = 3, - VKD3D_COMPARISON_FUNC_LESS_EQUAL = 4, - VKD3D_COMPARISON_FUNC_GREATER = 5, - VKD3D_COMPARISON_FUNC_NOT_EQUAL = 6, - VKD3D_COMPARISON_FUNC_GREATER_EQUAL = 7, - VKD3D_COMPARISON_FUNC_ALWAYS = 8, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_COMPARISON_FUNC), -}; - -enum vkd3d_static_border_color -{ - VKD3D_STATIC_BORDER_COLOR_TRANSPARENT_BLACK = 0, - VKD3D_STATIC_BORDER_COLOR_OPAQUE_BLACK = 1, - VKD3D_STATIC_BORDER_COLOR_OPAQUE_WHITE = 2, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_STATIC_BORDER_COLOR), -}; - -struct vkd3d_static_sampler_desc -{ - enum vkd3d_filter filter; - enum vkd3d_texture_address_mode address_u; - enum vkd3d_texture_address_mode address_v; - enum vkd3d_texture_address_mode address_w; - float mip_lod_bias; - unsigned int max_anisotropy; - enum vkd3d_comparison_func comparison_func; - enum vkd3d_static_border_color border_color; - float min_lod; - float max_lod; - unsigned int shader_register; - unsigned int register_space; - enum vkd3d_shader_visibility shader_visibility; -}; - -enum vkd3d_descriptor_range_type -{ - VKD3D_DESCRIPTOR_RANGE_TYPE_SRV = 0, - VKD3D_DESCRIPTOR_RANGE_TYPE_UAV = 1, - VKD3D_DESCRIPTOR_RANGE_TYPE_CBV = 2, - VKD3D_DESCRIPTOR_RANGE_TYPE_SAMPLER = 3, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_DESCRIPTOR_RANGE_TYPE), -}; - -struct vkd3d_descriptor_range -{ - enum vkd3d_descriptor_range_type range_type; - unsigned int descriptor_count; - unsigned int base_shader_register; - unsigned int register_space; - unsigned int descriptor_table_offset; -}; - -struct vkd3d_root_descriptor_table -{ - unsigned int descriptor_range_count; - const struct vkd3d_descriptor_range *descriptor_ranges; -}; - -struct vkd3d_root_constants -{ - unsigned int shader_register; - unsigned int register_space; - unsigned int value_count; -}; - -struct vkd3d_root_descriptor -{ - unsigned int shader_register; - unsigned int register_space; -}; - -enum vkd3d_root_parameter_type -{ - VKD3D_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE = 0, - VKD3D_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS = 1, - VKD3D_ROOT_PARAMETER_TYPE_CBV = 2, - VKD3D_ROOT_PARAMETER_TYPE_SRV = 3, - VKD3D_ROOT_PARAMETER_TYPE_UAV = 4, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_ROOT_PARAMETER_TYPE), -}; - -struct vkd3d_root_parameter -{ - enum vkd3d_root_parameter_type parameter_type; - union - { - struct vkd3d_root_descriptor_table descriptor_table; - struct vkd3d_root_constants constants; - struct vkd3d_root_descriptor descriptor; - } u; - enum vkd3d_shader_visibility shader_visibility; -}; - -enum vkd3d_root_signature_flags -{ - VKD3D_ROOT_SIGNATURE_FLAG_NONE = 0x0, - VKD3D_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT = 0x1, - VKD3D_ROOT_SIGNATURE_FLAG_DENY_VERTEX_SHADER_ROOT_ACCESS = 0x2, - VKD3D_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS = 0x4, - VKD3D_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS = 0x8, - VKD3D_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS = 0x10, - VKD3D_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS = 0x20, - VKD3D_ROOT_SIGNATURE_FLAG_ALLOW_STREAM_OUTPUT = 0x40, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_ROOT_SIGNATURE_FLAGS), -}; - -struct vkd3d_root_signature_desc -{ - unsigned int parameter_count; - const struct vkd3d_root_parameter *parameters; - unsigned int static_sampler_count; - const struct vkd3d_static_sampler_desc *static_samplers; - enum vkd3d_root_signature_flags flags; -}; - -int vkd3d_shader_parse_root_signature(const struct vkd3d_shader_code *dxbc, - struct vkd3d_root_signature_desc *root_signature); -void vkd3d_shader_free_root_signature(struct vkd3d_root_signature_desc *root_signature); - -enum vkd3d_root_signature_version -{ - VKD3D_ROOT_SIGNATURE_VERSION_1_0 = 0x1, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_ROOT_SIGNATURE_VERSION), -}; - -int vkd3d_shader_serialize_root_signature(const struct vkd3d_root_signature_desc *root_signature, - enum vkd3d_root_signature_version version, struct vkd3d_shader_code *dxbc); - -#define VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS 8 - -struct vkd3d_shader_scan_info -{ - unsigned int uav_read_mask : VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS; - unsigned int uav_counter_mask : VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS; -}; - -int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc, - struct vkd3d_shader_scan_info *scan_info); - -enum vkd3d_component_type -{ - VKD3D_TYPE_VOID = 0, - VKD3D_TYPE_UINT = 1, - VKD3D_TYPE_INT = 2, - VKD3D_TYPE_FLOAT = 3, - VKD3D_TYPE_BOOL, - VKD3D_TYPE_COUNT, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_COMPONENT_TYPE), -}; - -enum vkd3d_sysval_semantic -{ - VKD3D_SV_POSITION = 1, - VKD3D_SV_CLIP_DISTANCE = 2, - VKD3D_SV_CULL_DISTANCE = 3, - VKD3D_SV_RENDER_TARGET_ARRAY_INDEX = 4, - VKD3D_SV_VIEWPORT_ARRAY_INDEX = 5, - VKD3D_SV_VERTEX_ID = 6, - VKD3D_SV_PRIMITIVE_ID = 7, - VKD3D_SV_INSTANCE_ID = 8, - VKD3D_SV_IS_FRONT_FACE = 9, - VKD3D_SV_SAMPLE_INDEX = 10, - VKD3D_SV_TESS_FACTOR_QUADEDGE = 11, - VKD3D_SV_TESS_FACTOR_QUADINT = 12, - VKD3D_SV_TESS_FACTOR_TRIEDGE = 13, - VKD3D_SV_TESS_FACTOR_TRIINT = 14, - VKD3D_SV_TESS_FACTOR_LINEDET = 15, - VKD3D_SV_TESS_FACTOR_LINEDEN = 16, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SYSVAL_SEMANTIC), -}; - -struct vkd3d_shader_signature_element -{ - const char *semantic_name; - unsigned int semantic_index; - unsigned int stream_index; - enum vkd3d_sysval_semantic sysval_semantic; - enum vkd3d_component_type component_type; - unsigned int register_index; - unsigned int mask; -}; - -struct vkd3d_shader_signature -{ - struct vkd3d_shader_signature_element *elements; - unsigned int element_count; -}; - -int vkd3d_shader_parse_input_signature(const struct vkd3d_shader_code *dxbc, - struct vkd3d_shader_signature *signature); -struct vkd3d_shader_signature_element *vkd3d_shader_find_signature_element( - const struct vkd3d_shader_signature *signature, const char *semantic_name, - unsigned int semantic_index, unsigned int stream_index); -void vkd3d_shader_free_shader_signature(struct vkd3d_shader_signature *signature); - -/* swizzle bits fields: wwzzyyxx */ -#define VKD3D_SWIZZLE_X (0u) -#define VKD3D_SWIZZLE_Y (1u) -#define VKD3D_SWIZZLE_Z (2u) -#define VKD3D_SWIZZLE_W (3u) -#define VKD3D_SWIZZLE_MASK (0x3u) -#define VKD3D_SWIZZLE_SHIFT(idx) (2u * (idx)) -#define VKD3D_SWIZZLE(x, y, z, w) (((x & VKD3D_SWIZZLE_MASK) << VKD3D_SWIZZLE_SHIFT(0)) \ - | ((y & VKD3D_SWIZZLE_MASK) << VKD3D_SWIZZLE_SHIFT(1)) \ - | ((z & VKD3D_SWIZZLE_MASK) << VKD3D_SWIZZLE_SHIFT(2)) \ - | ((w & VKD3D_SWIZZLE_MASK) << VKD3D_SWIZZLE_SHIFT(3))) -#define VKD3D_NO_SWIZZLE \ - VKD3D_SWIZZLE(VKD3D_SWIZZLE_X, VKD3D_SWIZZLE_Y, VKD3D_SWIZZLE_Z, VKD3D_SWIZZLE_W) - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __VKD3D_SHADER_H */ diff --git a/dll/directx/wine/d3d12/vkd3d/include/private/vkd3d_test.h b/dll/directx/wine/d3d12/vkd3d/include/private/vkd3d_test.h deleted file mode 100644 index 0cc7fe4f38073..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/include/private/vkd3d_test.h +++ /dev/null @@ -1,417 +0,0 @@ -/* - * Copyright 2016 Józef Kucia for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef __VKD3D_TEST_H -#define __VKD3D_TEST_H - -#include "vkd3d_common.h" -#include -#include -#include -#include -#include -#include -#include - -extern const char *vkd3d_test_name; -extern const char *vkd3d_test_platform; - -static void vkd3d_test_start_todo(bool is_todo); -static int vkd3d_test_loop_todo(void); -static void vkd3d_test_end_todo(void); - -#define START_TEST(name) \ - const char *vkd3d_test_name = #name; \ - static void vkd3d_test_main(int argc, char **argv) - -/* - * Use assert_that() for conditions that should always be true. - * todo_if() and bug_if() do not influence assert_that(). - */ -#define assert_that assert_that_(__LINE__) - -#define ok ok_(__LINE__) - -#define skip skip_(__LINE__) - -#define trace trace_(__LINE__) - -#define assert_that_(line) \ - do { \ - unsigned int vkd3d_line = line; \ - VKD3D_TEST_ASSERT_THAT - -#define VKD3D_TEST_ASSERT_THAT(...) \ - vkd3d_test_assert_that(vkd3d_line, __VA_ARGS__); } while (0) - -#define ok_(line) \ - do { \ - unsigned int vkd3d_line = line; \ - VKD3D_TEST_OK - -#define VKD3D_TEST_OK(...) \ - vkd3d_test_ok(vkd3d_line, __VA_ARGS__); } while (0) - -#define todo_(line) \ - do { \ - unsigned int vkd3d_line = line; \ - VKD3D_TEST_TODO - -#define VKD3D_TEST_TODO(...) \ - vkd3d_test_todo(vkd3d_line, __VA_ARGS__); } while (0) - -#define skip_(line) \ - do { \ - unsigned int vkd3d_line = line; \ - VKD3D_TEST_SKIP - -#define VKD3D_TEST_SKIP(...) \ - vkd3d_test_skip(vkd3d_line, __VA_ARGS__); } while (0) - -#define trace_(line) \ - do { \ - unsigned int vkd3d_line = line; \ - VKD3D_TEST_TRACE - -#define VKD3D_TEST_TRACE(...) \ - vkd3d_test_trace(vkd3d_line, __VA_ARGS__); } while (0) - -#define todo_if(is_todo) \ - for (vkd3d_test_start_todo(is_todo); vkd3d_test_loop_todo(); vkd3d_test_end_todo()) - -#define bug_if(is_bug) \ - for (vkd3d_test_start_bug(is_bug); vkd3d_test_loop_bug(); vkd3d_test_end_bug()) - -#define todo todo_if(true) - -struct vkd3d_test_state -{ - LONG success_count; - LONG failure_count; - LONG skip_count; - LONG todo_count; - LONG todo_success_count; - LONG bug_count; - - unsigned int debug_level; - - unsigned int todo_level; - bool todo_do_loop; - - unsigned int bug_level; - bool bug_do_loop; - bool bug_enabled; - - const char *test_name_filter; - char context[1024]; -}; -extern struct vkd3d_test_state vkd3d_test_state; - -static bool -vkd3d_test_platform_is_windows(void) -{ - return !strcmp(vkd3d_test_platform, "windows"); -} - -static inline bool -broken(bool condition) -{ - return condition && vkd3d_test_platform_is_windows(); -} - -static void -vkd3d_test_check_assert_that(unsigned int line, bool result, const char *fmt, va_list args) -{ - if (result) - { - InterlockedIncrement(&vkd3d_test_state.success_count); - if (vkd3d_test_state.debug_level > 1) - printf("%s:%d%s: Test succeeded.\n", vkd3d_test_name, line, vkd3d_test_state.context); - } - else - { - InterlockedIncrement(&vkd3d_test_state.failure_count); - printf("%s:%d%s: Test failed: ", vkd3d_test_name, line, vkd3d_test_state.context); - vprintf(fmt, args); - } -} - -static void VKD3D_PRINTF_FUNC(3, 4) VKD3D_UNUSED -vkd3d_test_assert_that(unsigned int line, bool result, const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - vkd3d_test_check_assert_that(line, result, fmt, args); - va_end(args); -} - -static void -vkd3d_test_check_ok(unsigned int line, bool result, const char *fmt, va_list args) -{ - bool is_todo = vkd3d_test_state.todo_level && !vkd3d_test_platform_is_windows(); - bool is_bug = vkd3d_test_state.bug_level && !vkd3d_test_platform_is_windows(); - - if (is_bug && vkd3d_test_state.bug_enabled) - { - InterlockedIncrement(&vkd3d_test_state.bug_count); - if (is_todo) - result = !result; - if (result) - printf("%s:%d%s: Fixed bug: ", vkd3d_test_name, line, vkd3d_test_state.context); - else - printf("%s:%d%s: Bug: ", vkd3d_test_name, line, vkd3d_test_state.context); - vprintf(fmt, args); - } - else if (is_todo) - { - if (result) - { - InterlockedIncrement(&vkd3d_test_state.todo_success_count); - printf("%s:%d%s: Todo succeeded: ", vkd3d_test_name, line, vkd3d_test_state.context); - } - else - { - InterlockedIncrement(&vkd3d_test_state.todo_count); - printf("%s:%d%s: Todo: ", vkd3d_test_name, line, vkd3d_test_state.context); - } - vprintf(fmt, args); - } - else - { - vkd3d_test_check_assert_that(line, result, fmt, args); - } -} - -static void VKD3D_PRINTF_FUNC(3, 4) VKD3D_UNUSED -vkd3d_test_ok(unsigned int line, bool result, const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - vkd3d_test_check_ok(line, result, fmt, args); - va_end(args); -} - -static void VKD3D_PRINTF_FUNC(2, 3) VKD3D_UNUSED -vkd3d_test_skip(unsigned int line, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - printf("%s:%d%s: Test skipped: ", vkd3d_test_name, line, vkd3d_test_state.context); - vprintf(fmt, args); - va_end(args); - InterlockedIncrement(&vkd3d_test_state.skip_count); -} - -static void VKD3D_PRINTF_FUNC(2, 3) VKD3D_UNUSED -vkd3d_test_trace(unsigned int line, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - printf("%s:%d%s: ", vkd3d_test_name, line, vkd3d_test_state.context); - vprintf(fmt, args); - va_end(args); -} - -static void VKD3D_PRINTF_FUNC(1, 2) VKD3D_UNUSED -vkd3d_test_debug(const char *fmt, ...) -{ - char buffer[512]; - va_list args; - int size; - - size = snprintf(buffer, sizeof(buffer), "%s: ", vkd3d_test_name); - if (0 < size && size < sizeof(buffer)) - { - va_start(args, fmt); - vsnprintf(buffer + size, sizeof(buffer) - size, fmt, args); - va_end(args); - } - buffer[sizeof(buffer) - 1] = '\0'; - -#ifdef _WIN32 - OutputDebugStringA(buffer); -#endif - - if (vkd3d_test_state.debug_level > 0) - printf("%s\n", buffer); -} - -#ifndef VKD3D_TEST_NO_DEFS -const char *vkd3d_test_platform = "other"; -struct vkd3d_test_state vkd3d_test_state; - -static void vkd3d_test_main(int argc, char **argv); - -int main(int argc, char **argv) -{ - const char *test_filter = getenv("VKD3D_TEST_FILTER"); - const char *debug_level = getenv("VKD3D_TEST_DEBUG"); - char *test_platform = getenv("VKD3D_TEST_PLATFORM"); - const char *bug = getenv("VKD3D_TEST_BUG"); - - memset(&vkd3d_test_state, 0, sizeof(vkd3d_test_state)); - vkd3d_test_state.debug_level = debug_level ? atoi(debug_level) : 0; - vkd3d_test_state.bug_enabled = bug ? atoi(bug) : true; - vkd3d_test_state.test_name_filter = test_filter; - - if (test_platform) - { - test_platform = strdup(test_platform); - vkd3d_test_platform = test_platform; - } - - if (vkd3d_test_state.debug_level > 1) - printf("Test platform: '%s'.\n", vkd3d_test_platform); - - vkd3d_test_main(argc, argv); - - printf("%s: %lu tests executed (%lu failures, %lu skipped, %lu todo, %lu bugs).\n", - vkd3d_test_name, - (unsigned long)(vkd3d_test_state.success_count - + vkd3d_test_state.failure_count + vkd3d_test_state.todo_count - + vkd3d_test_state.todo_success_count), - (unsigned long)(vkd3d_test_state.failure_count - + vkd3d_test_state.todo_success_count), - (unsigned long)vkd3d_test_state.skip_count, - (unsigned long)vkd3d_test_state.todo_count, - (unsigned long)vkd3d_test_state.bug_count); - - if (test_platform) - free(test_platform); - - return vkd3d_test_state.failure_count || vkd3d_test_state.todo_success_count; -} - -#ifdef _WIN32 -static char *vkd3d_test_strdupWtoA(WCHAR *str) -{ - char *out; - int len; - - if (!(len = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL))) - return NULL; - if (!(out = malloc(len))) - return NULL; - WideCharToMultiByte(CP_ACP, 0, str, -1, out, len, NULL, NULL); - - return out; -} - -static bool running_under_wine(void) -{ - HMODULE module = GetModuleHandleA("ntdll.dll"); - return module && GetProcAddress(module, "wine_server_call"); -} - -int wmain(int argc, WCHAR **wargv) -{ - char **argv; - int i, ret; - - argv = malloc(argc * sizeof(*argv)); - assert(argv); - for (i = 0; i < argc; ++i) - { - if (!(argv[i] = vkd3d_test_strdupWtoA(wargv[i]))) - break; - } - assert(i == argc); - - vkd3d_test_platform = running_under_wine() ? "wine" : "windows"; - - ret = main(argc, argv); - - for (i = 0; i < argc; ++i) - free(argv[i]); - free(argv); - - return ret; -} -#endif /* _WIN32 */ -#endif /* VKD3D_TEST_NO_DEFS */ - -typedef void (*vkd3d_test_pfn)(void); - -static inline void vkd3d_run_test(const char *name, vkd3d_test_pfn test_pfn) -{ - if (vkd3d_test_state.test_name_filter && !strstr(name, vkd3d_test_state.test_name_filter)) - return; - - vkd3d_test_debug("%s", name); - test_pfn(); -} - -static inline void vkd3d_test_start_todo(bool is_todo) -{ - vkd3d_test_state.todo_level = (vkd3d_test_state.todo_level << 1) | is_todo; - vkd3d_test_state.todo_do_loop = true; -} - -static inline int vkd3d_test_loop_todo(void) -{ - bool do_loop = vkd3d_test_state.todo_do_loop; - vkd3d_test_state.todo_do_loop = false; - return do_loop; -} - -static inline void vkd3d_test_end_todo(void) -{ - vkd3d_test_state.todo_level >>= 1; -} - -static inline void vkd3d_test_start_bug(bool is_bug) -{ - vkd3d_test_state.bug_level = (vkd3d_test_state.bug_level << 1) | is_bug; - vkd3d_test_state.bug_do_loop = true; -} - -static inline int vkd3d_test_loop_bug(void) -{ - bool do_loop = vkd3d_test_state.bug_do_loop; - vkd3d_test_state.bug_do_loop = false; - return do_loop; -} - -static inline void vkd3d_test_end_bug(void) -{ - vkd3d_test_state.bug_level >>= 1; -} - -static inline void vkd3d_test_set_context(const char *fmt, ...) -{ - va_list args; - - if (!fmt) - { - vkd3d_test_state.context[0] = '\0'; - return; - } - - vkd3d_test_state.context[0] = ':'; - va_start(args, fmt); - vsnprintf(&vkd3d_test_state.context[1], sizeof(vkd3d_test_state.context) - 1, fmt, args); - va_end(args); - vkd3d_test_state.context[sizeof(vkd3d_test_state.context) - 1] = '\0'; -} - -#define run_test(test_pfn) \ - vkd3d_run_test(#test_pfn, test_pfn) - -#endif /* __VKD3D_TEST_H */ diff --git a/dll/directx/wine/d3d12/vkd3d/include/private/wine_rbtree.h b/dll/directx/wine/d3d12/vkd3d/include/private/wine_rbtree.h deleted file mode 100644 index b5d38bca54c9e..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/include/private/wine_rbtree.h +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Red-black search tree support - * - * Copyright 2009 Henri Verbeet - * Copyright 2009 Andrew Riedi - * Copyright 2016 Jacek Caban for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef __WINE_WINE_RBTREE_H -#define __WINE_WINE_RBTREE_H - -#define RB_ENTRY_VALUE(element, type, field) \ - ((type *)((char *)(element) - offsetof(type, field))) - -struct rb_entry -{ - struct rb_entry *parent; - struct rb_entry *left; - struct rb_entry *right; - unsigned int flags; -}; - -typedef int (*rb_compare_func)(const void *key, const struct rb_entry *entry); - -struct rb_tree -{ - rb_compare_func compare; - struct rb_entry *root; -}; - -typedef void (rb_traverse_func)(struct rb_entry *entry, void *context); - -#define RB_FLAG_RED 0x1 - -static inline int rb_is_red(struct rb_entry *entry) -{ - return entry && (entry->flags & RB_FLAG_RED); -} - -static inline void rb_rotate_left(struct rb_tree *tree, struct rb_entry *e) -{ - struct rb_entry *right = e->right; - - if (!e->parent) - tree->root = right; - else if (e->parent->left == e) - e->parent->left = right; - else - e->parent->right = right; - - e->right = right->left; - if (e->right) e->right->parent = e; - right->left = e; - right->parent = e->parent; - e->parent = right; -} - -static inline void rb_rotate_right(struct rb_tree *tree, struct rb_entry *e) -{ - struct rb_entry *left = e->left; - - if (!e->parent) - tree->root = left; - else if (e->parent->left == e) - e->parent->left = left; - else - e->parent->right = left; - - e->left = left->right; - if (e->left) e->left->parent = e; - left->right = e; - left->parent = e->parent; - e->parent = left; -} - -static inline void rb_flip_color(struct rb_entry *entry) -{ - entry->flags ^= RB_FLAG_RED; - entry->left->flags ^= RB_FLAG_RED; - entry->right->flags ^= RB_FLAG_RED; -} - -static inline struct rb_entry *rb_head(struct rb_entry *iter) -{ - if (!iter) return NULL; - while (iter->left) iter = iter->left; - return iter; -} - -static inline struct rb_entry *rb_next(struct rb_entry *iter) -{ - if (iter->right) return rb_head(iter->right); - while (iter->parent && iter->parent->right == iter) iter = iter->parent; - return iter->parent; -} - -static inline struct rb_entry *rb_postorder_head(struct rb_entry *iter) -{ - if (!iter) return NULL; - - for (;;) { - while (iter->left) iter = iter->left; - if (!iter->right) return iter; - iter = iter->right; - } -} - -static inline struct rb_entry *rb_postorder_next(struct rb_entry *iter) -{ - if (!iter->parent) return NULL; - if (iter == iter->parent->right || !iter->parent->right) return iter->parent; - return rb_postorder_head(iter->parent->right); -} - -/* iterate through the tree */ -#define RB_FOR_EACH(cursor, tree) \ - for ((cursor) = rb_head((tree)->root); (cursor); (cursor) = rb_next(cursor)) - -/* iterate through the tree using a tree entry */ -#define RB_FOR_EACH_ENTRY(elem, tree, type, field) \ - for ((elem) = RB_ENTRY_VALUE(rb_head((tree)->root), type, field); \ - (elem) != RB_ENTRY_VALUE(0, type, field); \ - (elem) = RB_ENTRY_VALUE(rb_next(&elem->field), type, field)) - -/* iterate through the tree using using postorder, making it safe to free the entry */ -#define RB_FOR_EACH_DESTRUCTOR(cursor, cursor2, tree) \ - for ((cursor) = rb_postorder_head((tree)->root); \ - (cursor) && (((cursor2) = rb_postorder_next(cursor)) || 1); \ - (cursor) = (cursor2)) - -/* iterate through the tree using a tree entry and postorder, making it safe to free the entry */ -#define RB_FOR_EACH_ENTRY_DESTRUCTOR(elem, elem2, tree, type, field) \ - for ((elem) = RB_ENTRY_VALUE(rb_postorder_head((tree)->root), type, field); \ - (elem) != WINE_RB_ENTRY_VALUE(0, type, field) \ - && (((elem2) = RB_ENTRY_VALUE(rb_postorder_next(&(elem)->field), type, field)) || 1); \ - (elem) = (elem2)) - - -static inline void rb_postorder(struct rb_tree *tree, rb_traverse_func *callback, void *context) -{ - struct rb_entry *iter, *next; - RB_FOR_EACH_DESTRUCTOR(iter, next, tree) callback(iter, context); -} - -static inline void rb_init(struct rb_tree *tree, rb_compare_func compare) -{ - tree->compare = compare; - tree->root = NULL; -} - -static inline void rb_for_each_entry(struct rb_tree *tree, rb_traverse_func *callback, void *context) -{ - struct rb_entry *iter; - RB_FOR_EACH(iter, tree) callback(iter, context); -} - -static inline void rb_clear(struct rb_tree *tree, rb_traverse_func *callback, void *context) -{ - /* Note that we use postorder here because the callback will likely free the entry. */ - if (callback) rb_postorder(tree, callback, context); - tree->root = NULL; -} - -static inline void rb_destroy(struct rb_tree *tree, rb_traverse_func *callback, void *context) -{ - rb_clear(tree, callback, context); -} - -static inline struct rb_entry *rb_get(const struct rb_tree *tree, const void *key) -{ - struct rb_entry *entry = tree->root; - while (entry) - { - int c = tree->compare(key, entry); - if (!c) return entry; - entry = c < 0 ? entry->left : entry->right; - } - return NULL; -} - -static inline int rb_put(struct rb_tree *tree, const void *key, struct rb_entry *entry) -{ - struct rb_entry **iter = &tree->root, *parent = tree->root; - - while (*iter) - { - int c; - - parent = *iter; - c = tree->compare(key, parent); - if (!c) return -1; - else if (c < 0) iter = &parent->left; - else iter = &parent->right; - } - - entry->flags = RB_FLAG_RED; - entry->parent = parent; - entry->left = NULL; - entry->right = NULL; - *iter = entry; - - while (rb_is_red(entry->parent)) - { - if (entry->parent == entry->parent->parent->left) - { - if (rb_is_red(entry->parent->parent->right)) - { - rb_flip_color(entry->parent->parent); - entry = entry->parent->parent; - } - else - { - if (entry == entry->parent->right) - { - entry = entry->parent; - rb_rotate_left(tree, entry); - } - entry->parent->flags &= ~RB_FLAG_RED; - entry->parent->parent->flags |= RB_FLAG_RED; - rb_rotate_right(tree, entry->parent->parent); - } - } - else - { - if (rb_is_red(entry->parent->parent->left)) - { - rb_flip_color(entry->parent->parent); - entry = entry->parent->parent; - } - else - { - if (entry == entry->parent->left) - { - entry = entry->parent; - rb_rotate_right(tree, entry); - } - entry->parent->flags &= ~RB_FLAG_RED; - entry->parent->parent->flags |= RB_FLAG_RED; - rb_rotate_left(tree, entry->parent->parent); - } - } - } - - tree->root->flags &= ~RB_FLAG_RED; - - return 0; -} - -static inline void rb_remove(struct rb_tree *tree, struct rb_entry *entry) -{ - struct rb_entry *iter, *child, *parent, *w; - int need_fixup; - - if (entry->right && entry->left) - for(iter = entry->right; iter->left; iter = iter->left); - else - iter = entry; - - child = iter->left ? iter->left : iter->right; - - if (!iter->parent) - tree->root = child; - else if (iter == iter->parent->left) - iter->parent->left = child; - else - iter->parent->right = child; - - if (child) child->parent = iter->parent; - parent = iter->parent; - - need_fixup = !rb_is_red(iter); - - if (entry != iter) - { - *iter = *entry; - if (!iter->parent) - tree->root = iter; - else if (entry == iter->parent->left) - iter->parent->left = iter; - else - iter->parent->right = iter; - - if (iter->right) iter->right->parent = iter; - if (iter->left) iter->left->parent = iter; - if (parent == entry) parent = iter; - } - - if (need_fixup) - { - while (parent && !rb_is_red(child)) - { - if (child == parent->left) - { - w = parent->right; - if (rb_is_red(w)) - { - w->flags &= ~RB_FLAG_RED; - parent->flags |= RB_FLAG_RED; - rb_rotate_left(tree, parent); - w = parent->right; - } - if (rb_is_red(w->left) || rb_is_red(w->right)) - { - if (!rb_is_red(w->right)) - { - w->left->flags &= ~RB_FLAG_RED; - w->flags |= RB_FLAG_RED; - rb_rotate_right(tree, w); - w = parent->right; - } - w->flags = (w->flags & ~RB_FLAG_RED) | (parent->flags & RB_FLAG_RED); - parent->flags &= ~RB_FLAG_RED; - if (w->right) - w->right->flags &= ~RB_FLAG_RED; - rb_rotate_left(tree, parent); - child = NULL; - break; - } - } - else - { - w = parent->left; - if (rb_is_red(w)) - { - w->flags &= ~RB_FLAG_RED; - parent->flags |= RB_FLAG_RED; - rb_rotate_right(tree, parent); - w = parent->left; - } - if (rb_is_red(w->left) || rb_is_red(w->right)) - { - if (!rb_is_red(w->left)) - { - w->right->flags &= ~RB_FLAG_RED; - w->flags |= RB_FLAG_RED; - rb_rotate_left(tree, w); - w = parent->left; - } - w->flags = (w->flags & ~RB_FLAG_RED) | (parent->flags & RB_FLAG_RED); - parent->flags &= ~RB_FLAG_RED; - if (w->left) - w->left->flags &= ~RB_FLAG_RED; - rb_rotate_right(tree, parent); - child = NULL; - break; - } - } - w->flags |= RB_FLAG_RED; - child = parent; - parent = child->parent; - } - if (child) child->flags &= ~RB_FLAG_RED; - } - - if (tree->root) tree->root->flags &= ~RB_FLAG_RED; -} - -static inline void rb_remove_key(struct rb_tree *tree, const void *key) -{ - struct rb_entry *entry = rb_get(tree, key); - if (entry) rb_remove(tree, entry); -} - -#endif /* __WINE_WINE_RBTREE_H */ diff --git a/dll/directx/wine/d3d12/vkd3d/include/vkd3d.h b/dll/directx/wine/d3d12/vkd3d/include/vkd3d.h deleted file mode 100644 index fbb44ac16f559..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/include/vkd3d.h +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright 2016 Józef Kucia for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef __VKD3D_H -#define __VKD3D_H - -#include - -#ifndef VKD3D_NO_WIN32_TYPES -# include -# include -#endif /* VKD3D_NO_WIN32_TYPES */ - -#ifndef VKD3D_NO_VULKAN_H -# include -#endif /* VKD3D_NO_VULKAN_H */ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -enum vkd3d_structure_type -{ - /* 1.0 */ - VKD3D_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, - VKD3D_STRUCTURE_TYPE_DEVICE_CREATE_INFO, - VKD3D_STRUCTURE_TYPE_IMAGE_RESOURCE_CREATE_INFO, - - /* 1.1 */ - VKD3D_STRUCTURE_TYPE_OPTIONAL_INSTANCE_EXTENSIONS_INFO, - - /* 1.2 */ - VKD3D_STRUCTURE_TYPE_OPTIONAL_DEVICE_EXTENSIONS_INFO, - VKD3D_STRUCTURE_TYPE_APPLICATION_INFO, - - /* 1.3 */ - VKD3D_STRUCTURE_TYPE_HOST_TIME_DOMAIN_INFO, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_STRUCTURE_TYPE), -}; - -enum vkd3d_api_version -{ - VKD3D_API_VERSION_1_0, - VKD3D_API_VERSION_1_1, - VKD3D_API_VERSION_1_2, - VKD3D_API_VERSION_1_3, -}; - -typedef HRESULT (*PFN_vkd3d_signal_event)(HANDLE event); - -typedef void * (*PFN_vkd3d_thread)(void *data); - -typedef void * (*PFN_vkd3d_create_thread)(PFN_vkd3d_thread thread_main, void *data); -typedef HRESULT (*PFN_vkd3d_join_thread)(void *thread); - -struct vkd3d_instance; - -struct vkd3d_instance_create_info -{ - enum vkd3d_structure_type type; - const void *next; - - PFN_vkd3d_signal_event pfn_signal_event; - PFN_vkd3d_create_thread pfn_create_thread; - PFN_vkd3d_join_thread pfn_join_thread; - size_t wchar_size; - - /* If set to NULL, libvkd3d loads libvulkan. */ - PFN_vkGetInstanceProcAddr pfn_vkGetInstanceProcAddr; - - const char * const *instance_extensions; - uint32_t instance_extension_count; -}; - -/* Extends vkd3d_instance_create_info. Available since 1.1. */ -struct vkd3d_optional_instance_extensions_info -{ - enum vkd3d_structure_type type; - const void *next; - - const char * const *extensions; - uint32_t extension_count; -}; - -/* Extends vkd3d_instance_create_info. Available since 1.2. */ -struct vkd3d_application_info -{ - enum vkd3d_structure_type type; - const void *next; - - const char *application_name; - uint32_t application_version; - - const char *engine_name; /* "vkd3d" if NULL */ - uint32_t engine_version; /* vkd3d version if engine_name is NULL */ - - enum vkd3d_api_version api_version; -}; - -/* Extends vkd3d_instance_create_info. Available since 1.3. */ -struct vkd3d_host_time_domain_info -{ - enum vkd3d_structure_type type; - const void *next; - - uint64_t ticks_per_second; -}; - -struct vkd3d_device_create_info -{ - enum vkd3d_structure_type type; - const void *next; - - D3D_FEATURE_LEVEL minimum_feature_level; - - struct vkd3d_instance *instance; - const struct vkd3d_instance_create_info *instance_create_info; - - VkPhysicalDevice vk_physical_device; - - const char * const *device_extensions; - uint32_t device_extension_count; - - IUnknown *parent; - LUID adapter_luid; -}; - -/* Extends vkd3d_device_create_info. Available since 1.2. */ -struct vkd3d_optional_device_extensions_info -{ - enum vkd3d_structure_type type; - const void *next; - - const char * const *extensions; - uint32_t extension_count; -}; - -/* vkd3d_image_resource_create_info flags */ -#define VKD3D_RESOURCE_INITIAL_STATE_TRANSITION 0x00000001 -#define VKD3D_RESOURCE_PRESENT_STATE_TRANSITION 0x00000002 - -struct vkd3d_image_resource_create_info -{ - enum vkd3d_structure_type type; - const void *next; - - VkImage vk_image; - D3D12_RESOURCE_DESC desc; - unsigned int flags; - D3D12_RESOURCE_STATES present_state; -}; - -#ifdef LIBVKD3D_SOURCE -# define VKD3D_API VKD3D_EXPORT -#else -# define VKD3D_API VKD3D_IMPORT -#endif - -#ifndef VKD3D_NO_PROTOTYPES - -VKD3D_API HRESULT vkd3d_create_instance(const struct vkd3d_instance_create_info *create_info, - struct vkd3d_instance **instance); -VKD3D_API ULONG vkd3d_instance_decref(struct vkd3d_instance *instance); -VKD3D_API VkInstance vkd3d_instance_get_vk_instance(struct vkd3d_instance *instance); -VKD3D_API ULONG vkd3d_instance_incref(struct vkd3d_instance *instance); - -VKD3D_API HRESULT vkd3d_create_device(const struct vkd3d_device_create_info *create_info, - REFIID iid, void **device); -VKD3D_API IUnknown *vkd3d_get_device_parent(ID3D12Device *device); -VKD3D_API VkDevice vkd3d_get_vk_device(ID3D12Device *device); -VKD3D_API VkPhysicalDevice vkd3d_get_vk_physical_device(ID3D12Device *device); -VKD3D_API struct vkd3d_instance *vkd3d_instance_from_device(ID3D12Device *device); - -VKD3D_API uint32_t vkd3d_get_vk_queue_family_index(ID3D12CommandQueue *queue); -VKD3D_API VkQueue vkd3d_acquire_vk_queue(ID3D12CommandQueue *queue); -VKD3D_API void vkd3d_release_vk_queue(ID3D12CommandQueue *queue); - -VKD3D_API HRESULT vkd3d_create_image_resource(ID3D12Device *device, - const struct vkd3d_image_resource_create_info *create_info, ID3D12Resource **resource); -VKD3D_API ULONG vkd3d_resource_decref(ID3D12Resource *resource); -VKD3D_API ULONG vkd3d_resource_incref(ID3D12Resource *resource); - -VKD3D_API HRESULT vkd3d_serialize_root_signature(const D3D12_ROOT_SIGNATURE_DESC *desc, - D3D_ROOT_SIGNATURE_VERSION version, ID3DBlob **blob, ID3DBlob **error_blob); -VKD3D_API HRESULT vkd3d_create_root_signature_deserializer(const void *data, SIZE_T data_size, - REFIID iid, void **deserializer); - -VKD3D_API VkFormat vkd3d_get_vk_format(DXGI_FORMAT format); - -/* 1.1 */ -VKD3D_API DXGI_FORMAT vkd3d_get_dxgi_format(VkFormat format); - -/* 1.2 */ -VKD3D_API HRESULT vkd3d_serialize_versioned_root_signature(const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *desc, - ID3DBlob **blob, ID3DBlob **error_blob); -VKD3D_API HRESULT vkd3d_create_versioned_root_signature_deserializer(const void *data, SIZE_T data_size, - REFIID iid, void **deserializer); - -#endif /* VKD3D_NO_PROTOTYPES */ - -/* - * Function pointer typedefs for vkd3d functions. - */ -typedef HRESULT (*PFN_vkd3d_create_instance)(const struct vkd3d_instance_create_info *create_info, - struct vkd3d_instance **instance); -typedef ULONG (*PFN_vkd3d_instance_decref)(struct vkd3d_instance *instance); -typedef VkInstance (*PFN_vkd3d_instance_get_vk_instance)(struct vkd3d_instance *instance); -typedef ULONG (*PFN_vkd3d_instance_incref)(struct vkd3d_instance *instance); - -typedef HRESULT (*PFN_vkd3d_create_device)(const struct vkd3d_device_create_info *create_info, - REFIID iid, void **device); -typedef IUnknown * (*PFN_vkd3d_get_device_parent)(ID3D12Device *device); -typedef VkDevice (*PFN_vkd3d_get_vk_device)(ID3D12Device *device); -typedef VkPhysicalDevice (*PFN_vkd3d_get_vk_physical_device)(ID3D12Device *device); -typedef struct vkd3d_instance * (*PFN_vkd3d_instance_from_device)(ID3D12Device *device); - -typedef uint32_t (*PFN_vkd3d_get_vk_queue_family_index)(ID3D12CommandQueue *queue); -typedef VkQueue (*PFN_vkd3d_acquire_vk_queue)(ID3D12CommandQueue *queue); -typedef void (*PFN_vkd3d_release_vk_queue)(ID3D12CommandQueue *queue); - -typedef HRESULT (*PFN_vkd3d_create_image_resource)(ID3D12Device *device, - const struct vkd3d_image_resource_create_info *create_info, ID3D12Resource **resource); -typedef ULONG (*PFN_vkd3d_resource_decref)(ID3D12Resource *resource); -typedef ULONG (*PFN_vkd3d_resource_incref)(ID3D12Resource *resource); - -typedef HRESULT (*PFN_vkd3d_serialize_root_signature)(const D3D12_ROOT_SIGNATURE_DESC *desc, - D3D_ROOT_SIGNATURE_VERSION version, ID3DBlob **blob, ID3DBlob **error_blob); -typedef HRESULT (*PFN_vkd3d_create_root_signature_deserializer)(const void *data, SIZE_T data_size, - REFIID iid, void **deserializer); - -typedef VkFormat (*PFN_vkd3d_get_vk_format)(DXGI_FORMAT format); - -/* 1.1 */ -typedef DXGI_FORMAT (*PFN_vkd3d_get_dxgi_format)(VkFormat format); - -/* 1.2 */ -typedef HRESULT (*PFN_vkd3d_serialize_versioned_root_signature)(const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *desc, - ID3DBlob **blob, ID3DBlob **error_blob); -typedef HRESULT (*PFN_vkd3d_create_versioned_root_signature_deserializer)(const void *data, SIZE_T data_size, - REFIID iid, void **deserializer); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __VKD3D_H */ diff --git a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_d3d12.idl b/dll/directx/wine/d3d12/vkd3d/include/vkd3d_d3d12.idl deleted file mode 100644 index 2d0800b98bbe7..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_d3d12.idl +++ /dev/null @@ -1,2592 +0,0 @@ -/* - * Copyright 2016 Józef Kucia for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -import "vkd3d_windows.h"; - -import "vkd3d_dxgibase.idl"; - -import "vkd3d_d3dcommon.idl"; - -cpp_quote("#ifndef _D3D12_CONSTANTS") -cpp_quote("#define _D3D12_CONSTANTS") - -const UINT D3D12_CS_TGSM_REGISTER_COUNT = 8192; -const UINT D3D12_MAX_ROOT_COST = 64; -const UINT D3D12_VIEWPORT_BOUNDS_MAX = 32767; -const UINT D3D12_VIEWPORT_BOUNDS_MIN = -32768; - -const UINT D3D12_COMMONSHADER_CONSTANT_BUFFER_REGISTER_COUNT = 15; - -const UINT D3D12_APPEND_ALIGNED_ELEMENT = 0xffffffff; -cpp_quote("#define D3D12_DEFAULT_BLEND_FACTOR_ALPHA (1.0f)") -cpp_quote("#define D3D12_DEFAULT_BLEND_FACTOR_BLUE (1.0f)") -cpp_quote("#define D3D12_DEFAULT_BLEND_FACTOR_GREEN (1.0f)") -cpp_quote("#define D3D12_DEFAULT_BLEND_FACTOR_RED (1.0f)") -const UINT D3D12_DEFAULT_DEPTH_BIAS = 0; -cpp_quote("#define D3D12_DEFAULT_DEPTH_BIAS_CLAMP (0.0f)") -cpp_quote("#define D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS (0.0f)") -const UINT D3D12_DEFAULT_STENCIL_READ_MASK = 0xff; -const UINT D3D12_DEFAULT_STENCIL_WRITE_MASK = 0xff; -const UINT D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND = 0xffffffff; -cpp_quote("#define D3D12_FLOAT32_MAX (3.402823466e+38f)") -const UINT D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT = 32; -const UINT D3D12_UAV_SLOT_COUNT = 64; -const UINT D3D12_REQ_CONSTANT_BUFFER_ELEMENT_COUNT = 4096; -const UINT D3D12_REQ_IMMEDIATE_CONSTANT_BUFFER_ELEMENT_COUNT = 4096; -const UINT D3D12_REQ_MIP_LEVELS = 15; -const UINT D3D12_REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION = 2048; -const UINT D3D12_REQ_TEXTURE1D_U_DIMENSION = 16384; -const UINT D3D12_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION = 2048; -const UINT D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION = 16384; -const UINT D3D12_REQ_TEXTURE3D_U_V_OR_W_DIMENSION = 2048; -const UINT D3D12_REQ_TEXTURECUBE_DIMENSION = 16384; -const UINT D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES = 0xffffffff; -const UINT D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT = 8; -const UINT D3D12_SO_BUFFER_MAX_STRIDE_IN_BYTES = 2048; -const UINT D3D12_SO_BUFFER_SLOT_COUNT = 4; -const UINT D3D12_SO_DDI_REGISTER_INDEX_DENOTING_GAP = 0xffffffff; -const UINT D3D12_SO_NO_RASTERIZED_STREAM = 0xffffffff; -const UINT D3D12_SO_OUTPUT_COMPONENT_COUNT = 128; -const UINT D3D12_SO_STREAM_COUNT = 4; -const UINT D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT = 256; -const UINT D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT = 4194304; -const UINT D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT = 65536; -const UINT D3D12_RAW_UAV_SRV_BYTE_ALIGNMENT = 16; -const UINT D3D12_SMALL_MSAA_RESOURCE_PLACEMENT_ALIGNMENT = 65536; -const UINT D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT = 4096; -const UINT D3D12_STANDARD_MAXIMUM_ELEMENT_ALIGNMENT_BYTE_MULTIPLE = 4; -const UINT D3D12_TEXTURE_DATA_PITCH_ALIGNMENT = 256; -const UINT D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT = 512; -const UINT D3D12_UAV_COUNTER_PLACEMENT_ALIGNMENT = 4096; -const UINT D3D12_VS_INPUT_REGISTER_COUNT = 32; -const UINT D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE = 16; - -cpp_quote("#endif") - -const UINT D3D12_SHADER_COMPONENT_MAPPING_MASK = 0x7; -const UINT D3D12_SHADER_COMPONENT_MAPPING_SHIFT = 3; -const UINT D3D12_SHADER_COMPONENT_MAPPING_ALWAYS_SET_BIT_AVOIDING_ZEROMEM_MISTAKES - = 1 << (D3D12_SHADER_COMPONENT_MAPPING_SHIFT * 4); - -typedef enum D3D12_SHADER_MIN_PRECISION_SUPPORT -{ - D3D12_SHADER_MIN_PRECISION_SUPPORT_NONE = 0x0, - D3D12_SHADER_MIN_PRECISION_SUPPORT_10_BIT = 0x1, - D3D12_SHADER_MIN_PRECISION_SUPPORT_16_BIT = 0x2, -} D3D12_SHADER_MIN_PRECISION_SUPPORT; -cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_SHADER_MIN_PRECISION_SUPPORT);") - -typedef enum D3D12_TILED_RESOURCES_TIER -{ - D3D12_TILED_RESOURCES_TIER_NOT_SUPPORTED = 0, - D3D12_TILED_RESOURCES_TIER_1 = 1, - D3D12_TILED_RESOURCES_TIER_2 = 2, - D3D12_TILED_RESOURCES_TIER_3 = 3, -} D3D12_TILED_RESOURCES_TIER; - -typedef enum D3D12_RESOURCE_BINDING_TIER -{ - D3D12_RESOURCE_BINDING_TIER_1 = 1, - D3D12_RESOURCE_BINDING_TIER_2 = 2, - D3D12_RESOURCE_BINDING_TIER_3 = 3, -} D3D12_RESOURCE_BINDING_TIER; - -typedef enum D3D12_CONSERVATIVE_RASTERIZATION_TIER -{ - D3D12_CONSERVATIVE_RASTERIZATION_TIER_NOT_SUPPORTED = 0, - D3D12_CONSERVATIVE_RASTERIZATION_TIER_1 = 1, - D3D12_CONSERVATIVE_RASTERIZATION_TIER_2 = 2, - D3D12_CONSERVATIVE_RASTERIZATION_TIER_3 = 3, -} D3D12_CONSERVATIVE_RASTERIZATION_TIER; - -typedef enum D3D12_CROSS_NODE_SHARING_TIER -{ - D3D12_CROSS_NODE_SHARING_TIER_NOT_SUPPORTED = 0, - D3D12_CROSS_NODE_SHARING_TIER_1_EMULATED = 1, - D3D12_CROSS_NODE_SHARING_TIER_1 = 2, - D3D12_CROSS_NODE_SHARING_TIER_2 = 3, -} D3D12_CROSS_NODE_SHARING_TIER; - -typedef enum D3D12_RESOURCE_HEAP_TIER -{ - D3D12_RESOURCE_HEAP_TIER_1 = 1, - D3D12_RESOURCE_HEAP_TIER_2 = 2, -} D3D12_RESOURCE_HEAP_TIER; - -typedef enum D3D12_FORMAT_SUPPORT1 -{ - D3D12_FORMAT_SUPPORT1_NONE = 0x00000000, - D3D12_FORMAT_SUPPORT1_BUFFER = 0x00000001, - D3D12_FORMAT_SUPPORT1_IA_VERTEX_BUFFER = 0x00000002, - D3D12_FORMAT_SUPPORT1_IA_INDEX_BUFFER = 0x00000004, - D3D12_FORMAT_SUPPORT1_SO_BUFFER = 0x00000008, - D3D12_FORMAT_SUPPORT1_TEXTURE1D = 0x00000010, - D3D12_FORMAT_SUPPORT1_TEXTURE2D = 0x00000020, - D3D12_FORMAT_SUPPORT1_TEXTURE3D = 0x00000040, - D3D12_FORMAT_SUPPORT1_TEXTURECUBE = 0x00000080, - D3D12_FORMAT_SUPPORT1_SHADER_LOAD = 0x00000100, - D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE = 0x00000200, - D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE_COMPARISON = 0x00000400, - D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE_MONO_TEXT = 0x00000800, - D3D12_FORMAT_SUPPORT1_MIP = 0x00001000, - D3D12_FORMAT_SUPPORT1_RENDER_TARGET = 0x00004000, - D3D12_FORMAT_SUPPORT1_BLENDABLE = 0x00008000, - D3D12_FORMAT_SUPPORT1_DEPTH_STENCIL = 0x00010000, - D3D12_FORMAT_SUPPORT1_MULTISAMPLE_RESOLVE = 0x00040000, - D3D12_FORMAT_SUPPORT1_DISPLAY = 0x00080000, - D3D12_FORMAT_SUPPORT1_CAST_WITHIN_BIT_LAYOUT = 0x00100000, - D3D12_FORMAT_SUPPORT1_MULTISAMPLE_RENDERTARGET = 0x00200000, - D3D12_FORMAT_SUPPORT1_MULTISAMPLE_LOAD = 0x00400000, - D3D12_FORMAT_SUPPORT1_SHADER_GATHER = 0x00800000, - D3D12_FORMAT_SUPPORT1_BACK_BUFFER_CAST = 0x01000000, - D3D12_FORMAT_SUPPORT1_TYPED_UNORDERED_ACCESS_VIEW = 0x02000000, - D3D12_FORMAT_SUPPORT1_SHADER_GATHER_COMPARISON = 0x04000000, - D3D12_FORMAT_SUPPORT1_DECODER_OUTPUT = 0x08000000, - D3D12_FORMAT_SUPPORT1_VIDEO_PROCESSOR_OUTPUT = 0x10000000, - D3D12_FORMAT_SUPPORT1_VIDEO_PROCESSOR_INPUT = 0x20000000, - D3D12_FORMAT_SUPPORT1_VIDEO_ENCODER = 0x40000000, -} D3D12_FORMAT_SUPPORT1; -cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_FORMAT_SUPPORT1);") - -typedef enum D3D12_FORMAT_SUPPORT2 -{ - D3D12_FORMAT_SUPPORT2_NONE = 0x00000000, - D3D12_FORMAT_SUPPORT2_UAV_ATOMIC_ADD = 0x00000001, - D3D12_FORMAT_SUPPORT2_UAV_ATOMIC_BITWISE_OPS = 0x00000002, - D3D12_FORMAT_SUPPORT2_UAV_ATOMIC_COMPARE_STORE_OR_COMPARE_EXCHANGE = 0x00000004, - D3D12_FORMAT_SUPPORT2_UAV_ATOMIC_EXCHANGE = 0x00000008, - D3D12_FORMAT_SUPPORT2_UAV_ATOMIC_SIGNED_MIN_OR_MAX = 0x00000010, - D3D12_FORMAT_SUPPORT2_UAV_ATOMIC_UNSIGNED_MIN_OR_MAX = 0x00000020, - D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD = 0x00000040, - D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE = 0x00000080, - D3D12_FORMAT_SUPPORT2_OUTPUT_MERGER_LOGIC_OP = 0x00000100, - D3D12_FORMAT_SUPPORT2_TILED = 0x00000200, - D3D12_FORMAT_SUPPORT2_MULTIPLANE_OVERLAY = 0x00004000, -} D3D12_FORMAT_SUPPORT2; -cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_FORMAT_SUPPORT2);") - -typedef enum D3D12_WRITEBUFFERIMMEDIATE_MODE -{ - D3D12_WRITEBUFFERIMMEDIATE_MODE_DEFAULT = 0x0, - D3D12_WRITEBUFFERIMMEDIATE_MODE_MARKER_IN = 0x1, - D3D12_WRITEBUFFERIMMEDIATE_MODE_MARKER_OUT = 0x2, -} D3D12_WRITEBUFFERIMMEDIATE_MODE; - -typedef enum D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER -{ - D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_NOT_SUPPORTED = 0x0, - D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_1 = 0x1, - D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_2 = 0x2, -} D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER; - -typedef enum D3D12_SHADER_CACHE_SUPPORT_FLAGS -{ - D3D12_SHADER_CACHE_SUPPORT_NONE = 0x0, - D3D12_SHADER_CACHE_SUPPORT_SINGLE_PSO = 0x1, - D3D12_SHADER_CACHE_SUPPORT_LIBRARY = 0x2, - D3D12_SHADER_CACHE_SUPPORT_AUTOMATIC_INPROC_CACHE = 0x4, - D3D12_SHADER_CACHE_SUPPORT_AUTOMATIC_DISK_CACHE = 0x8, -} D3D12_SHADER_CACHE_SUPPORT_FLAGS; -cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_SHADER_CACHE_SUPPORT_FLAGS);") - -typedef enum D3D12_COMMAND_LIST_SUPPORT_FLAGS -{ - D3D12_COMMAND_LIST_SUPPORT_FLAG_NONE = 0x0, - D3D12_COMMAND_LIST_SUPPORT_FLAG_DIRECT = 0x1, - D3D12_COMMAND_LIST_SUPPORT_FLAG_BUNDLE = 0x2, - D3D12_COMMAND_LIST_SUPPORT_FLAG_COMPUTE = 0x4, - D3D12_COMMAND_LIST_SUPPORT_FLAG_COPY = 0x8, - D3D12_COMMAND_LIST_SUPPORT_FLAG_VIDEO_DECODE = 0x10, - D3D12_COMMAND_LIST_SUPPORT_FLAG_VIDEO_PROCESS = 0x20, - D3D12_COMMAND_LIST_SUPPORT_FLAG_VIDEO_ENCODE = 0x40, -} D3D12_COMMAND_LIST_SUPPORT_FLAGS; -cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_COMMAND_LIST_SUPPORT_FLAGS);") - -typedef enum D3D12_VIEW_INSTANCING_TIER -{ - D3D12_VIEW_INSTANCING_TIER_NOT_SUPPORTED = 0x0, - D3D12_VIEW_INSTANCING_TIER_1 = 0x1, - D3D12_VIEW_INSTANCING_TIER_2 = 0x2, - D3D12_VIEW_INSTANCING_TIER_3 = 0x3, -} D3D12_VIEW_INSTANCING_TIER; - -typedef enum D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER -{ - D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_0 = 0x0, - D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_1 = 0x1, -} D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER; - -typedef enum D3D12_HEAP_SERIALIZATION_TIER -{ - D3D12_HEAP_SERIALIZATION_TIER_0 = 0x0, - D3D12_HEAP_SERIALIZATION_TIER_10 = 0xa, -} D3D12_HEAP_SERIALIZATION_TIER; - -typedef enum D3D12_RENDER_PASS_TIER -{ - D3D12_RENDER_PASS_TIER_0 = 0x0, - D3D12_RENDER_PASS_TIER_1 = 0x1, - D3D12_RENDER_PASS_TIER_2 = 0x2, -} D3D12_RENDER_PASS_TIER; - -typedef enum D3D12_RAYTRACING_TIER -{ - D3D12_RAYTRACING_TIER_NOT_SUPPORTED = 0x0, - D3D12_RAYTRACING_TIER_1_0 = 0xa, -} D3D12_RAYTRACING_TIER; - -interface ID3D12Fence; -interface ID3D12RootSignature; -interface ID3D12Heap; -interface ID3D12DescriptorHeap; -interface ID3D12Resource; -interface ID3D12CommandAllocator; -interface ID3D12GraphicsCommandList; -interface ID3D12CommandQueue; -interface ID3D12PipelineState; -interface ID3D12Device; - -typedef RECT D3D12_RECT; - -typedef struct D3D12_BOX -{ - UINT left; - UINT top; - UINT front; - UINT right; - UINT bottom; - UINT back; -} D3D12_BOX; - -typedef struct D3D12_VIEWPORT -{ - FLOAT TopLeftX; - FLOAT TopLeftY; - FLOAT Width; - FLOAT Height; - FLOAT MinDepth; - FLOAT MaxDepth; -} D3D12_VIEWPORT; - -typedef struct D3D12_RANGE -{ - SIZE_T Begin; - SIZE_T End; -} D3D12_RANGE; - -typedef struct D3D12_RANGE_UINT64 -{ - UINT64 Begin; - UINT64 End; -} D3D12_RANGE_UINT64; - -typedef struct D3D12_SUBRESOURCE_RANGE_UINT64 -{ - UINT Subresource; - D3D12_RANGE_UINT64 Range; -} D3D12_SUBRESOURCE_RANGE_UINT64; - -typedef struct D3D12_RESOURCE_ALLOCATION_INFO -{ - UINT64 SizeInBytes; - UINT64 Alignment; -} D3D12_RESOURCE_ALLOCATION_INFO; - -typedef struct D3D12_DRAW_ARGUMENTS -{ - UINT VertexCountPerInstance; - UINT InstanceCount; - UINT StartVertexLocation; - UINT StartInstanceLocation; -} D3D12_DRAW_ARGUMENTS; - -typedef struct D3D12_DRAW_INDEXED_ARGUMENTS -{ - UINT IndexCountPerInstance; - UINT InstanceCount; - UINT StartIndexLocation; - INT BaseVertexLocation; - UINT StartInstanceLocation; -} D3D12_DRAW_INDEXED_ARGUMENTS; - -typedef struct D3D12_DISPATCH_ARGUMENTS -{ - UINT ThreadGroupCountX; - UINT ThreadGroupCountY; - UINT ThreadGroupCountZ; -} D3D12_DISPATCH_ARGUMENTS; - -typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS -{ - BOOL DoublePrecisionFloatShaderOps; - BOOL OutputMergerLogicOp; - D3D12_SHADER_MIN_PRECISION_SUPPORT MinPrecisionSupport; - D3D12_TILED_RESOURCES_TIER TiledResourcesTier; - D3D12_RESOURCE_BINDING_TIER ResourceBindingTier; - BOOL PSSpecifiedStencilRefSupported; - BOOL TypedUAVLoadAdditionalFormats; - BOOL ROVsSupported; - D3D12_CONSERVATIVE_RASTERIZATION_TIER ConservativeRasterizationTier; - UINT MaxGPUVirtualAddressBitsPerResource; - BOOL StandardSwizzle64KBSupported; - D3D12_CROSS_NODE_SHARING_TIER CrossNodeSharingTier; - BOOL CrossAdapterRowMajorTextureSupported; - BOOL VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation; - D3D12_RESOURCE_HEAP_TIER ResourceHeapTier; -} D3D12_FEATURE_DATA_D3D12_OPTIONS; - -typedef struct D3D12_FEATURE_DATA_FORMAT_SUPPORT -{ - DXGI_FORMAT Format; - D3D12_FORMAT_SUPPORT1 Support1; - D3D12_FORMAT_SUPPORT2 Support2; -} D3D12_FEATURE_DATA_FORMAT_SUPPORT; - -typedef enum D3D12_MULTISAMPLE_QUALITY_LEVEL_FLAGS -{ - D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_NONE = 0x00000000, - D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_TILED_RESOURCE = 0x00000001, -} D3D12_MULTISAMPLE_QUALITY_LEVEL_FLAGS; -cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_MULTISAMPLE_QUALITY_LEVEL_FLAGS);") - -typedef struct D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS -{ - DXGI_FORMAT Format; - UINT SampleCount; - D3D12_MULTISAMPLE_QUALITY_LEVEL_FLAGS Flags; - UINT NumQualityLevels; -} D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS; - -typedef enum D3D12_HEAP_TYPE -{ - D3D12_HEAP_TYPE_DEFAULT = 1, - D3D12_HEAP_TYPE_UPLOAD = 2, - D3D12_HEAP_TYPE_READBACK = 3, - D3D12_HEAP_TYPE_CUSTOM = 4, -} D3D12_HEAP_TYPE; - -typedef enum D3D12_CPU_PAGE_PROPERTY -{ - D3D12_CPU_PAGE_PROPERTY_UNKNOWN = 0, - D3D12_CPU_PAGE_PROPERTY_NOT_AVAILABLE = 1, - D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE = 2, - D3D12_CPU_PAGE_PROPERTY_WRITE_BACK = 3, -} D3D12_CPU_PAGE_PROPERTY; - -typedef enum D3D12_MEMORY_POOL -{ - D3D12_MEMORY_POOL_UNKNOWN = 0, - D3D12_MEMORY_POOL_L0 = 1, - D3D12_MEMORY_POOL_L1 = 2, -} D3D12_MEMORY_POOL; - -typedef struct D3D12_HEAP_PROPERTIES -{ - D3D12_HEAP_TYPE Type; - D3D12_CPU_PAGE_PROPERTY CPUPageProperty; - D3D12_MEMORY_POOL MemoryPoolPreference; - UINT CreationNodeMask; - UINT VisibleNodeMask; -} D3D12_HEAP_PROPERTIES; - -typedef enum D3D12_HEAP_FLAGS -{ - D3D12_HEAP_FLAG_NONE = 0x00, - D3D12_HEAP_FLAG_SHARED = 0x01, - D3D12_HEAP_FLAG_DENY_BUFFERS = 0x04, - D3D12_HEAP_FLAG_ALLOW_DISPLAY = 0x08, - D3D12_HEAP_FLAG_SHARED_CROSS_ADAPTER = 0x20, - D3D12_HEAP_FLAG_DENY_RT_DS_TEXTURES = 0x40, - D3D12_HEAP_FLAG_DENY_NON_RT_DS_TEXTURES = 0x80, - D3D12_HEAP_FLAG_ALLOW_ALL_BUFFERS_AND_TEXTURES = 0x00, - D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS = 0xc0, - D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES = 0x44, - D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES = 0x84, -} D3D12_HEAP_FLAGS; -cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_HEAP_FLAGS);") - -typedef struct D3D12_HEAP_DESC -{ - UINT64 SizeInBytes; - D3D12_HEAP_PROPERTIES Properties; - UINT64 Alignment; - D3D12_HEAP_FLAGS Flags; -} D3D12_HEAP_DESC; - -typedef struct D3D12_TILED_RESOURCE_COORDINATE -{ - UINT X; - UINT Y; - UINT Z; - UINT Subresource; -} D3D12_TILED_RESOURCE_COORDINATE; - -typedef struct D3D12_TILE_REGION_SIZE -{ - UINT NumTiles; - BOOL UseBox; - UINT Width; - UINT16 Height; - UINT16 Depth; -} D3D12_TILE_REGION_SIZE; - -typedef struct D3D12_SUBRESOURCE_TILING -{ - UINT WidthInTiles; - UINT16 HeightInTiles; - UINT16 DepthInTiles; - UINT StartTileIndexInOverallResource; -} D3D12_SUBRESOURCE_TILING; - -typedef struct D3D12_TILE_SHAPE -{ - UINT WidthInTexels; - UINT HeightInTexels; - UINT DepthInTexels; -} D3D12_TILE_SHAPE; - -typedef struct D3D12_SHADER_BYTECODE -{ - const void *pShaderBytecode; - SIZE_T BytecodeLength; -} D3D12_SHADER_BYTECODE; - -typedef struct D3D12_DEPTH_STENCIL_VALUE -{ - FLOAT Depth; - UINT8 Stencil; -} D3D12_DEPTH_STENCIL_VALUE; - -typedef struct D3D12_CLEAR_VALUE -{ - DXGI_FORMAT Format; - union - { - FLOAT Color[4]; - D3D12_DEPTH_STENCIL_VALUE DepthStencil; - }; -} D3D12_CLEAR_VALUE; - -typedef struct D3D12_PACKED_MIP_INFO -{ - UINT8 NumStandardMips; - UINT8 NumPackedMips; - UINT NumTilesForPackedMips; - UINT StartTileIndexInOverallResource; -} D3D12_PACKED_MIP_INFO; - -typedef enum D3D12_RESOURCE_STATES -{ - D3D12_RESOURCE_STATE_COMMON = 0, - D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER = 0x1, - D3D12_RESOURCE_STATE_INDEX_BUFFER = 0x2, - D3D12_RESOURCE_STATE_RENDER_TARGET = 0x4, - D3D12_RESOURCE_STATE_UNORDERED_ACCESS = 0x8, - D3D12_RESOURCE_STATE_DEPTH_WRITE = 0x10, - D3D12_RESOURCE_STATE_DEPTH_READ = 0x20, - D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE = 0x40, - D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE = 0x80, - D3D12_RESOURCE_STATE_STREAM_OUT = 0x100, - D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT = 0x200, - D3D12_RESOURCE_STATE_COPY_DEST = 0x400, - D3D12_RESOURCE_STATE_COPY_SOURCE = 0x800, - D3D12_RESOURCE_STATE_RESOLVE_DEST = 0x1000, - D3D12_RESOURCE_STATE_RESOLVE_SOURCE = 0x2000, - D3D12_RESOURCE_STATE_GENERIC_READ = 0x1 | 0x2 | 0x40 | 0x80 | 0x200 | 0x800, - D3D12_RESOURCE_STATE_PRESENT = 0x0, - D3D12_RESOURCE_STATE_PREDICATION = 0x200, - D3D12_RESOURCE_STATE_VIDEO_DECODE_READ = 0x10000, - D3D12_RESOURCE_STATE_VIDEO_DECODE_WRITE = 0x20000, - D3D12_RESOURCE_STATE_VIDEO_PROCESS_READ = 0x40000, - D3D12_RESOURCE_STATE_VIDEO_PROCESS_WRITE = 0x80000, - D3D12_RESOURCE_STATE_VIDEO_ENCODE_READ = 0x200000, - D3D12_RESOURCE_STATE_VIDEO_ENCODE_WRITE = 0x800000, -} D3D12_RESOURCE_STATES; -cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_RESOURCE_STATES);") - -typedef enum D3D12_RESOURCE_BARRIER_TYPE -{ - D3D12_RESOURCE_BARRIER_TYPE_TRANSITION = 0, - D3D12_RESOURCE_BARRIER_TYPE_ALIASING = 1, - D3D12_RESOURCE_BARRIER_TYPE_UAV = 2, -} D3D12_RESOURCE_BARRIER_TYPE; - -typedef enum D3D12_RESOURCE_BARRIER_FLAGS -{ - D3D12_RESOURCE_BARRIER_FLAG_NONE = 0x0, - D3D12_RESOURCE_BARRIER_FLAG_BEGIN_ONLY = 0x1, - D3D12_RESOURCE_BARRIER_FLAG_END_ONLY = 0x2, -} D3D12_RESOURCE_BARRIER_FLAGS; -cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_RESOURCE_BARRIER_FLAGS);") - -typedef struct D3D12_RESOURCE_TRANSITION_BARRIER -{ - ID3D12Resource *pResource; - UINT Subresource; - D3D12_RESOURCE_STATES StateBefore; - D3D12_RESOURCE_STATES StateAfter; -} D3D12_RESOURCE_TRANSITION_BARRIER; - -typedef struct D3D12_RESOURCE_ALIASING_BARRIER_ALIASING -{ - ID3D12Resource *pResourceBefore; - ID3D12Resource *pResourceAfter; -} D3D12_RESOURCE_ALIASING_BARRIER; - -typedef struct D3D12_RESOURCE_UAV_BARRIER -{ - ID3D12Resource *pResource; -} D3D12_RESOURCE_UAV_BARRIER; - -typedef struct D3D12_RESOURCE_BARRIER -{ - D3D12_RESOURCE_BARRIER_TYPE Type; - D3D12_RESOURCE_BARRIER_FLAGS Flags; - union - { - D3D12_RESOURCE_TRANSITION_BARRIER Transition; - D3D12_RESOURCE_ALIASING_BARRIER Aliasing; - D3D12_RESOURCE_UAV_BARRIER UAV; - }; -} D3D12_RESOURCE_BARRIER; - -typedef enum D3D12_RESOURCE_DIMENSION -{ - D3D12_RESOURCE_DIMENSION_UNKNOWN = 0, - D3D12_RESOURCE_DIMENSION_BUFFER = 1, - D3D12_RESOURCE_DIMENSION_TEXTURE1D = 2, - D3D12_RESOURCE_DIMENSION_TEXTURE2D = 3, - D3D12_RESOURCE_DIMENSION_TEXTURE3D = 4, -} D3D12_RESOURCE_DIMENSION; - -typedef enum D3D12_TEXTURE_LAYOUT -{ - D3D12_TEXTURE_LAYOUT_UNKNOWN = 0, - D3D12_TEXTURE_LAYOUT_ROW_MAJOR = 1, - D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE = 2, - D3D12_TEXTURE_LAYOUT_64KB_STANDARD_SWIZZLE = 3, -} D3D12_TEXTURE_LAYOUT; - -typedef enum D3D12_RESOURCE_FLAGS -{ - D3D12_RESOURCE_FLAG_NONE = 0x0, - D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET = 0x1, - D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL = 0x2, - D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS = 0x4, - D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE = 0x8, - D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER = 0x10, - D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS = 0x20, -} D3D12_RESOURCE_FLAGS; -cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_RESOURCE_FLAGS);") - -typedef struct D3D12_RESOURCE_DESC -{ - D3D12_RESOURCE_DIMENSION Dimension; - UINT64 Alignment; - UINT64 Width; - UINT Height; - UINT16 DepthOrArraySize; - UINT16 MipLevels; - DXGI_FORMAT Format; - DXGI_SAMPLE_DESC SampleDesc; - D3D12_TEXTURE_LAYOUT Layout; - D3D12_RESOURCE_FLAGS Flags; -} D3D12_RESOURCE_DESC; - -typedef enum D3D12_RESOLVE_MODE -{ - D3D12_RESOLVE_MODE_DECOMPRESS = 0, - D3D12_RESOLVE_MODE_MIN = 1, - D3D12_RESOLVE_MODE_MAX = 2, - D3D12_RESOLVE_MODE_AVERAGE = 3, -} D3D12_RESOLVE_MODE; - -typedef struct D3D12_SAMPLE_POSITION -{ - INT8 X; - INT8 Y; -} D3D12_SAMPLE_POSITION; - -typedef enum D3D12_TEXTURE_COPY_TYPE -{ - D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX = 0, - D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT = 1, -} D3D12_TEXTURE_COPY_TYPE; - -typedef struct D3D12_SUBRESOURCE_FOOTPRINT -{ - DXGI_FORMAT Format; - UINT Width; - UINT Height; - UINT Depth; - UINT RowPitch; -} D3D12_SUBRESOURCE_FOOTPRINT; - -typedef struct D3D12_PLACED_SUBRESOURCE_FOOTPRINT -{ - UINT64 Offset; - D3D12_SUBRESOURCE_FOOTPRINT Footprint; -} D3D12_PLACED_SUBRESOURCE_FOOTPRINT; - -typedef struct D3D12_TEXTURE_COPY_LOCATION -{ - ID3D12Resource *pResource; - D3D12_TEXTURE_COPY_TYPE Type; - union - { - D3D12_PLACED_SUBRESOURCE_FOOTPRINT PlacedFootprint; - UINT SubresourceIndex; - }; -} D3D12_TEXTURE_COPY_LOCATION; - -typedef enum D3D12_DESCRIPTOR_RANGE_TYPE -{ - D3D12_DESCRIPTOR_RANGE_TYPE_SRV = 0, - D3D12_DESCRIPTOR_RANGE_TYPE_UAV = 1, - D3D12_DESCRIPTOR_RANGE_TYPE_CBV = 2, - D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER = 3, -} D3D12_DESCRIPTOR_RANGE_TYPE; - -typedef struct D3D12_DESCRIPTOR_RANGE -{ - D3D12_DESCRIPTOR_RANGE_TYPE RangeType; - UINT NumDescriptors; - UINT BaseShaderRegister; - UINT RegisterSpace; - UINT OffsetInDescriptorsFromTableStart; -} D3D12_DESCRIPTOR_RANGE; - -typedef enum D3D12_DESCRIPTOR_RANGE_FLAGS -{ - D3D12_DESCRIPTOR_RANGE_FLAG_NONE = 0x0, - D3D12_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_VOLATILE = 0x1, - D3D12_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE = 0x2, - D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE = 0x4, - D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC = 0x8, -} D3D12_DESCRIPTOR_RANGE_FLAGS; -cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_DESCRIPTOR_RANGE_FLAGS);") - -typedef struct D3D12_DESCRIPTOR_RANGE1 -{ - D3D12_DESCRIPTOR_RANGE_TYPE RangeType; - UINT NumDescriptors; - UINT BaseShaderRegister; - UINT RegisterSpace; - D3D12_DESCRIPTOR_RANGE_FLAGS Flags; - UINT OffsetInDescriptorsFromTableStart; -} D3D12_DESCRIPTOR_RANGE1; - -typedef struct D3D12_ROOT_DESCRIPTOR_TABLE -{ - UINT NumDescriptorRanges; - const D3D12_DESCRIPTOR_RANGE *pDescriptorRanges; -} D3D12_ROOT_DESCRIPTOR_TABLE; - -typedef struct D3D12_ROOT_DESCRIPTOR_TABLE1 -{ - UINT NumDescriptorRanges; - const D3D12_DESCRIPTOR_RANGE1 *pDescriptorRanges; -} D3D12_ROOT_DESCRIPTOR_TABLE1; - -typedef struct D3D12_ROOT_CONSTANTS -{ - UINT ShaderRegister; - UINT RegisterSpace; - UINT Num32BitValues; -} D3D12_ROOT_CONSTANTS; - -typedef struct D3D12_ROOT_DESCRIPTOR -{ - UINT ShaderRegister; - UINT RegisterSpace; -} D3D12_ROOT_DESCRIPTOR; - -typedef enum D3D12_ROOT_DESCRIPTOR_FLAGS -{ - D3D12_ROOT_DESCRIPTOR_FLAG_NONE = 0x0, - D3D12_ROOT_DESCRIPTOR_FLAG_DATA_VOLATILE = 0x2, - D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE = 0x4, - D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC = 0x8, -} D3D12_ROOT_DESCRIPTOR_FLAGS; -cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_ROOT_DESCRIPTOR_FLAGS);") - -typedef struct D3D12_ROOT_DESCRIPTOR1 -{ - UINT ShaderRegister; - UINT RegisterSpace; - D3D12_ROOT_DESCRIPTOR_FLAGS Flags; -} D3D12_ROOT_DESCRIPTOR1; - -typedef enum D3D12_ROOT_PARAMETER_TYPE -{ - D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE = 0, - D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS = 1, - D3D12_ROOT_PARAMETER_TYPE_CBV = 2, - D3D12_ROOT_PARAMETER_TYPE_SRV = 3, - D3D12_ROOT_PARAMETER_TYPE_UAV = 4, -} D3D12_ROOT_PARAMETER_TYPE; - -typedef enum D3D12_SHADER_VISIBILITY -{ - D3D12_SHADER_VISIBILITY_ALL = 0, - D3D12_SHADER_VISIBILITY_VERTEX = 1, - D3D12_SHADER_VISIBILITY_HULL = 2, - D3D12_SHADER_VISIBILITY_DOMAIN = 3, - D3D12_SHADER_VISIBILITY_GEOMETRY = 4, - D3D12_SHADER_VISIBILITY_PIXEL = 5, -} D3D12_SHADER_VISIBILITY; - -typedef struct D3D12_ROOT_PARAMETER -{ - D3D12_ROOT_PARAMETER_TYPE ParameterType; - union - { - D3D12_ROOT_DESCRIPTOR_TABLE DescriptorTable; - D3D12_ROOT_CONSTANTS Constants; - D3D12_ROOT_DESCRIPTOR Descriptor; - }; - D3D12_SHADER_VISIBILITY ShaderVisibility; -} D3D12_ROOT_PARAMETER; - -typedef struct D3D12_ROOT_PARAMETER1 -{ - D3D12_ROOT_PARAMETER_TYPE ParameterType; - union - { - D3D12_ROOT_DESCRIPTOR_TABLE1 DescriptorTable; - D3D12_ROOT_CONSTANTS Constants; - D3D12_ROOT_DESCRIPTOR1 Descriptor; - }; - D3D12_SHADER_VISIBILITY ShaderVisibility; -} D3D12_ROOT_PARAMETER1; - -typedef enum D3D12_STATIC_BORDER_COLOR -{ - D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK = 0, - D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK = 1, - D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE = 2, -} D3D12_STATIC_BORDER_COLOR; - -typedef enum D3D12_FILTER -{ - D3D12_FILTER_MIN_MAG_MIP_POINT = 0x00, - D3D12_FILTER_MIN_MAG_POINT_MIP_LINEAR = 0x01, - D3D12_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x04, - D3D12_FILTER_MIN_POINT_MAG_MIP_LINEAR = 0x05, - D3D12_FILTER_MIN_LINEAR_MAG_MIP_POINT = 0x10, - D3D12_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x11, - D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT = 0x14, - D3D12_FILTER_MIN_MAG_MIP_LINEAR = 0x15, - D3D12_FILTER_ANISOTROPIC = 0x55, - D3D12_FILTER_COMPARISON_MIN_MAG_MIP_POINT = 0x80, - D3D12_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR = 0x81, - D3D12_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x84, - D3D12_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR = 0x85, - D3D12_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT = 0x90, - D3D12_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x91, - D3D12_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT = 0x94, - D3D12_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR = 0x95, - D3D12_FILTER_COMPARISON_ANISOTROPIC = 0xd5, - D3D12_FILTER_MINIMUM_MIN_MAG_MIP_POINT = 0x100, - D3D12_FILTER_MINIMUM_MIN_MAG_POINT_MIP_LINEAR = 0x101, - D3D12_FILTER_MINIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x104, - D3D12_FILTER_MINIMUM_MIN_POINT_MAG_MIP_LINEAR = 0x105, - D3D12_FILTER_MINIMUM_MIN_LINEAR_MAG_MIP_POINT = 0x110, - D3D12_FILTER_MINIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x111, - D3D12_FILTER_MINIMUM_MIN_MAG_LINEAR_MIP_POINT = 0x114, - D3D12_FILTER_MINIMUM_MIN_MAG_MIP_LINEAR = 0x115, - D3D12_FILTER_MINIMUM_ANISOTROPIC = 0x155, - D3D12_FILTER_MAXIMUM_MIN_MAG_MIP_POINT = 0x180, - D3D12_FILTER_MAXIMUM_MIN_MAG_POINT_MIP_LINEAR = 0x181, - D3D12_FILTER_MAXIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x184, - D3D12_FILTER_MAXIMUM_MIN_POINT_MAG_MIP_LINEAR = 0x185, - D3D12_FILTER_MAXIMUM_MIN_LINEAR_MAG_MIP_POINT = 0x190, - D3D12_FILTER_MAXIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x191, - D3D12_FILTER_MAXIMUM_MIN_MAG_LINEAR_MIP_POINT = 0x194, - D3D12_FILTER_MAXIMUM_MIN_MAG_MIP_LINEAR = 0x195, - D3D12_FILTER_MAXIMUM_ANISOTROPIC = 0x1d5, -} D3D12_FILTER; - -typedef enum D3D12_FILTER_TYPE -{ - D3D12_FILTER_TYPE_POINT = 0, - D3D12_FILTER_TYPE_LINEAR = 1, -} D3D12_FILTER_TYPE; - -const UINT D3D12_MIP_FILTER_SHIFT = 0; -const UINT D3D12_MAG_FILTER_SHIFT = 2; -const UINT D3D12_MIN_FILTER_SHIFT = 4; -const UINT D3D12_FILTER_TYPE_MASK = 0x3; - -const UINT D3D12_ANISOTROPIC_FILTERING_BIT = 0x40; - -typedef enum D3D12_FILTER_REDUCTION_TYPE -{ - D3D12_FILTER_REDUCTION_TYPE_STANDARD = 0, - D3D12_FILTER_REDUCTION_TYPE_COMPARISON = 1, - D3D12_FILTER_REDUCTION_TYPE_MINIMUM = 2, - D3D12_FILTER_REDUCTION_TYPE_MAXIMUM = 3, -} D3D12_FILTER_REDUCTION_TYPE; - -const UINT D3D12_FILTER_REDUCTION_TYPE_MASK = 0x3; -const UINT D3D12_FILTER_REDUCTION_TYPE_SHIFT = 7; - -cpp_quote("#define D3D12_DECODE_MAG_FILTER(filter) \\") -cpp_quote(" ((D3D12_FILTER_TYPE)(((filter) >> D3D12_MAG_FILTER_SHIFT) & D3D12_FILTER_TYPE_MASK))") - -cpp_quote("#define D3D12_DECODE_MIN_FILTER(filter) \\") -cpp_quote(" ((D3D12_FILTER_TYPE)(((filter) >> D3D12_MIN_FILTER_SHIFT) & D3D12_FILTER_TYPE_MASK))") - -cpp_quote("#define D3D12_DECODE_MIP_FILTER(filter) \\") -cpp_quote(" ((D3D12_FILTER_TYPE)(((filter) >> D3D12_MIP_FILTER_SHIFT) & D3D12_FILTER_TYPE_MASK))") - -cpp_quote("#define D3D12_DECODE_IS_ANISOTROPIC_FILTER(filter) \\") -cpp_quote(" (((filter) & D3D12_ANISOTROPIC_FILTERING_BIT) \\") -cpp_quote(" && (D3D12_DECODE_MIN_FILTER(filter) == D3D12_FILTER_TYPE_LINEAR) \\") -cpp_quote(" && (D3D12_DECODE_MAG_FILTER(filter) == D3D12_FILTER_TYPE_LINEAR) \\") -cpp_quote(" && (D3D12_DECODE_MIP_FILTER(filter) == D3D12_FILTER_TYPE_LINEAR))") - -cpp_quote("#define D3D12_DECODE_FILTER_REDUCTION(filter) \\") -cpp_quote(" ((D3D12_FILTER_REDUCTION_TYPE)(((filter) >> D3D12_FILTER_REDUCTION_TYPE_SHIFT) \\") -cpp_quote(" & D3D12_FILTER_REDUCTION_TYPE_MASK))") - -cpp_quote("#define D3D12_DECODE_IS_COMPARISON_FILTER(filter) \\") -cpp_quote(" (D3D12_DECODE_FILTER_REDUCTION(filter) == D3D12_FILTER_REDUCTION_TYPE_COMPARISON)") - -typedef enum D3D12_TEXTURE_ADDRESS_MODE -{ - D3D12_TEXTURE_ADDRESS_MODE_WRAP = 1, - D3D12_TEXTURE_ADDRESS_MODE_MIRROR = 2, - D3D12_TEXTURE_ADDRESS_MODE_CLAMP = 3, - D3D12_TEXTURE_ADDRESS_MODE_BORDER = 4, - D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE = 5, -} D3D12_TEXTURE_ADDRESS_MODE; - -typedef enum D3D12_COMPARISON_FUNC -{ - D3D12_COMPARISON_FUNC_NEVER = 1, - D3D12_COMPARISON_FUNC_LESS = 2, - D3D12_COMPARISON_FUNC_EQUAL = 3, - D3D12_COMPARISON_FUNC_LESS_EQUAL = 4, - D3D12_COMPARISON_FUNC_GREATER = 5, - D3D12_COMPARISON_FUNC_NOT_EQUAL = 6, - D3D12_COMPARISON_FUNC_GREATER_EQUAL = 7, - D3D12_COMPARISON_FUNC_ALWAYS = 8, -} D3D12_COMPARISON_FUNC; - -typedef struct D3D12_STATIC_SAMPLER_DESC -{ - D3D12_FILTER Filter; - D3D12_TEXTURE_ADDRESS_MODE AddressU; - D3D12_TEXTURE_ADDRESS_MODE AddressV; - D3D12_TEXTURE_ADDRESS_MODE AddressW; - FLOAT MipLODBias; - UINT MaxAnisotropy; - D3D12_COMPARISON_FUNC ComparisonFunc; - D3D12_STATIC_BORDER_COLOR BorderColor; - FLOAT MinLOD; - FLOAT MaxLOD; - UINT ShaderRegister; - UINT RegisterSpace; - D3D12_SHADER_VISIBILITY ShaderVisibility; -} D3D12_STATIC_SAMPLER_DESC; - -typedef enum D3D12_ROOT_SIGNATURE_FLAGS -{ - D3D12_ROOT_SIGNATURE_FLAG_NONE = 0x00, - D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT = 0x01, - D3D12_ROOT_SIGNATURE_FLAG_DENY_VERTEX_SHADER_ROOT_ACCESS = 0x02, - D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS = 0x04, - D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS = 0x08, - D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS = 0x10, - D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS = 0x20, - D3D12_ROOT_SIGNATURE_FLAG_ALLOW_STREAM_OUTPUT = 0x40, -} D3D12_ROOT_SIGNATURE_FLAGS; -cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_ROOT_SIGNATURE_FLAGS);") - -typedef struct D3D12_ROOT_SIGNATURE_DESC -{ - UINT NumParameters; - const D3D12_ROOT_PARAMETER *pParameters; - UINT NumStaticSamplers; - const D3D12_STATIC_SAMPLER_DESC *pStaticSamplers; - D3D12_ROOT_SIGNATURE_FLAGS Flags; -} D3D12_ROOT_SIGNATURE_DESC; - -typedef struct D3D12_ROOT_SIGNATURE_DESC1 -{ - UINT NumParameters; - const D3D12_ROOT_PARAMETER1 *pParameters; - UINT NumStaticSamplers; - const D3D12_STATIC_SAMPLER_DESC *pStaticSamplers; - D3D12_ROOT_SIGNATURE_FLAGS Flags; -} D3D12_ROOT_SIGNATURE_DESC1; - -typedef enum D3D_ROOT_SIGNATURE_VERSION -{ - D3D_ROOT_SIGNATURE_VERSION_1 = 0x1, - D3D_ROOT_SIGNATURE_VERSION_1_0 = 0x1, - D3D_ROOT_SIGNATURE_VERSION_1_1 = 0x2, -} D3D_ROOT_SIGNATURE_VERSION; - -typedef struct D3D12_VERSIONED_ROOT_SIGNATURE_DESC -{ - D3D_ROOT_SIGNATURE_VERSION Version; - union - { - D3D12_ROOT_SIGNATURE_DESC Desc_1_0; - D3D12_ROOT_SIGNATURE_DESC1 Desc_1_1; - }; -} D3D12_VERSIONED_ROOT_SIGNATURE_DESC; - -typedef enum D3D12_DESCRIPTOR_HEAP_TYPE -{ - D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, - D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, - D3D12_DESCRIPTOR_HEAP_TYPE_RTV, - D3D12_DESCRIPTOR_HEAP_TYPE_DSV, - D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES, -} D3D12_DESCRIPTOR_HEAP_TYPE; - -typedef enum D3D12_DESCRIPTOR_HEAP_FLAGS -{ - D3D12_DESCRIPTOR_HEAP_FLAG_NONE = 0x0, - D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE = 0x1, -} D3D12_DESCRIPTOR_HEAP_FLAGS; -cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_DESCRIPTOR_HEAP_FLAGS);") - -typedef struct D3D12_DESCRIPTOR_HEAP_DESC -{ - D3D12_DESCRIPTOR_HEAP_TYPE Type; - UINT NumDescriptors; - D3D12_DESCRIPTOR_HEAP_FLAGS Flags; - UINT NodeMask; -} D3D12_DESCRIPTOR_HEAP_DESC; - -typedef UINT64 D3D12_GPU_VIRTUAL_ADDRESS; - -typedef struct D3D12_CONSTANT_BUFFER_VIEW_DESC -{ - D3D12_GPU_VIRTUAL_ADDRESS BufferLocation; - UINT SizeInBytes; -} D3D12_CONSTANT_BUFFER_VIEW_DESC; - -typedef enum D3D12_SRV_DIMENSION -{ - D3D12_SRV_DIMENSION_UNKNOWN = 0, - D3D12_SRV_DIMENSION_BUFFER = 1, - D3D12_SRV_DIMENSION_TEXTURE1D = 2, - D3D12_SRV_DIMENSION_TEXTURE1DARRAY = 3, - D3D12_SRV_DIMENSION_TEXTURE2D = 4, - D3D12_SRV_DIMENSION_TEXTURE2DARRAY = 5, - D3D12_SRV_DIMENSION_TEXTURE2DMS = 6, - D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY = 7, - D3D12_SRV_DIMENSION_TEXTURE3D = 8, - D3D12_SRV_DIMENSION_TEXTURECUBE = 9, - D3D12_SRV_DIMENSION_TEXTURECUBEARRAY = 10, -} D3D12_SRV_DIMENSION; - -typedef enum D3D12_BUFFER_SRV_FLAGS -{ - D3D12_BUFFER_SRV_FLAG_NONE = 0x0, - D3D12_BUFFER_SRV_FLAG_RAW = 0x1, -} D3D12_BUFFER_SRV_FLAGS; -cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_BUFFER_SRV_FLAGS);") - -typedef enum D3D12_SHADER_COMPONENT_MAPPING -{ - D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0 = 0, - D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1 = 1, - D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_2 = 2, - D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_3 = 3, - D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0 = 4, - D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1 = 5, -} D3D12_SHADER_COMPONENT_MAPPING; - -cpp_quote("#define D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(x, y, z, w) \\") -cpp_quote(" (((x) & D3D12_SHADER_COMPONENT_MAPPING_MASK) \\") -cpp_quote(" | (((y) & D3D12_SHADER_COMPONENT_MAPPING_MASK) << D3D12_SHADER_COMPONENT_MAPPING_SHIFT) \\") -cpp_quote(" | (((z) & D3D12_SHADER_COMPONENT_MAPPING_MASK) << (D3D12_SHADER_COMPONENT_MAPPING_SHIFT * 2)) \\") -cpp_quote(" | (((w) & D3D12_SHADER_COMPONENT_MAPPING_MASK) << (D3D12_SHADER_COMPONENT_MAPPING_SHIFT * 3)) \\") -cpp_quote(" | D3D12_SHADER_COMPONENT_MAPPING_ALWAYS_SET_BIT_AVOIDING_ZEROMEM_MISTAKES)") -cpp_quote("#define D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(0, 1, 2, 3)") - -cpp_quote("#define D3D12_DECODE_SHADER_4_COMPONENT_MAPPING(i, mapping) \\") -cpp_quote(" ((D3D12_SHADER_COMPONENT_MAPPING)(mapping >> (i * D3D12_SHADER_COMPONENT_MAPPING_SHIFT) \\") -cpp_quote(" & D3D12_SHADER_COMPONENT_MAPPING_MASK))") - -typedef struct D3D12_BUFFER_SRV -{ - UINT64 FirstElement; - UINT NumElements; - UINT StructureByteStride; - D3D12_BUFFER_SRV_FLAGS Flags; -} D3D12_BUFFER_SRV; - -typedef struct D3D12_TEX1D_SRV -{ - UINT MostDetailedMip; - UINT MipLevels; - FLOAT ResourceMinLODClamp; -} D3D12_TEX1D_SRV; - -typedef struct D3D12_TEX1D_ARRAY_SRV -{ - UINT MostDetailedMip; - UINT MipLevels; - UINT FirstArraySlice; - UINT ArraySize; - FLOAT ResourceMinLODClamp; -} D3D12_TEX1D_ARRAY_SRV; - -typedef struct D3D12_TEX2D_SRV -{ - UINT MostDetailedMip; - UINT MipLevels; - UINT PlaneSlice; - FLOAT ResourceMinLODClamp; -} D3D12_TEX2D_SRV; - -typedef struct D3D12_TEX2D_ARRAY_SRV -{ - UINT MostDetailedMip; - UINT MipLevels; - UINT FirstArraySlice; - UINT ArraySize; - UINT PlaneSlice; - FLOAT ResourceMinLODClamp; -} D3D12_TEX2D_ARRAY_SRV; - -typedef struct D3D12_TEX2DMS_SRV -{ - UINT UnusedField_NothingToDefine; -} D3D12_TEX2DMS_SRV; - -typedef struct D3D12_TEX2DMS_ARRAY_SRV -{ - UINT FirstArraySlice; - UINT ArraySize; -} D3D12_TEX2DMS_ARRAY_SRV; - -typedef struct D3D12_TEX3D_SRV -{ - UINT MostDetailedMip; - UINT MipLevels; - FLOAT ResourceMinLODClamp; -} D3D12_TEX3D_SRV; - -typedef struct D3D12_TEXCUBE_SRV -{ - UINT MostDetailedMip; - UINT MipLevels; - FLOAT ResourceMinLODClamp; -} D3D12_TEXCUBE_SRV; - -typedef struct D3D12_TEXCUBE_ARRAY_SRV -{ - UINT MostDetailedMip; - UINT MipLevels; - UINT First2DArrayFace; - UINT NumCubes; - FLOAT ResourceMinLODClamp; -} D3D12_TEXCUBE_ARRAY_SRV; - -typedef struct D3D12_SHADER_RESOURCE_VIEW_DESC -{ - DXGI_FORMAT Format; - D3D12_SRV_DIMENSION ViewDimension; - UINT Shader4ComponentMapping; - union - { - D3D12_BUFFER_SRV Buffer; - D3D12_TEX1D_SRV Texture1D; - D3D12_TEX1D_ARRAY_SRV Texture1DArray; - D3D12_TEX2D_SRV Texture2D; - D3D12_TEX2D_ARRAY_SRV Texture2DArray; - D3D12_TEX2DMS_SRV Texture2DMS; - D3D12_TEX2DMS_ARRAY_SRV Texture2DMSArray; - D3D12_TEX3D_SRV Texture3D; - D3D12_TEXCUBE_SRV TextureCube; - D3D12_TEXCUBE_ARRAY_SRV TextureCubeArray; - }; -} D3D12_SHADER_RESOURCE_VIEW_DESC; - -typedef enum D3D12_UAV_DIMENSION -{ - D3D12_UAV_DIMENSION_UNKNOWN = 0, - D3D12_UAV_DIMENSION_BUFFER = 1, - D3D12_UAV_DIMENSION_TEXTURE1D = 2, - D3D12_UAV_DIMENSION_TEXTURE1DARRAY = 3, - D3D12_UAV_DIMENSION_TEXTURE2D = 4, - D3D12_UAV_DIMENSION_TEXTURE2DARRAY = 5, - D3D12_UAV_DIMENSION_TEXTURE3D = 8, -} D3D12_UAV_DIMENSION; - -typedef enum D3D12_BUFFER_UAV_FLAGS -{ - D3D12_BUFFER_UAV_FLAG_NONE = 0x0, - D3D12_BUFFER_UAV_FLAG_RAW = 0x1, -} D3D12_BUFFER_UAV_FLAGS; -cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_BUFFER_UAV_FLAGS);") - -typedef struct D3D12_BUFFER_UAV -{ - UINT64 FirstElement; - UINT NumElements; - UINT StructureByteStride; - UINT64 CounterOffsetInBytes; - D3D12_BUFFER_UAV_FLAGS Flags; -} D3D12_BUFFER_UAV; - -typedef struct D3D12_TEX1D_UAV -{ - UINT MipSlice; -} D3D12_TEX1D_UAV; - -typedef struct D3D12_TEX1D_ARRAY_UAV -{ - UINT MipSlice; - UINT FirstArraySlice; - UINT ArraySize; -} D3D12_TEX1D_ARRAY_UAV; - -typedef struct D3D12_TEX2D_UAV -{ - UINT MipSlice; - UINT PlaneSlice; -} D3D12_TEX2D_UAV; - -typedef struct D3D12_TEX2D_ARRAY_UAV -{ - UINT MipSlice; - UINT FirstArraySlice; - UINT ArraySize; - UINT PlaneSlice; -} D3D12_TEX2D_ARRAY_UAV; - -typedef struct D3D12_TEX3D_UAV -{ - UINT MipSlice; - UINT FirstWSlice; - UINT WSize; -} D3D12_TEX3D_UAV; - -typedef struct D3D12_UNORDERED_ACCESS_VIEW_DESC -{ - DXGI_FORMAT Format; - D3D12_UAV_DIMENSION ViewDimension; - union - { - D3D12_BUFFER_UAV Buffer; - D3D12_TEX1D_UAV Texture1D; - D3D12_TEX1D_ARRAY_UAV Texture1DArray; - D3D12_TEX2D_UAV Texture2D; - D3D12_TEX2D_ARRAY_UAV Texture2DArray; - D3D12_TEX3D_UAV Texture3D; - }; -} D3D12_UNORDERED_ACCESS_VIEW_DESC; - -typedef enum D3D12_RTV_DIMENSION -{ - D3D12_RTV_DIMENSION_UNKNOWN = 0, - D3D12_RTV_DIMENSION_BUFFER = 1, - D3D12_RTV_DIMENSION_TEXTURE1D = 2, - D3D12_RTV_DIMENSION_TEXTURE1DARRAY = 3, - D3D12_RTV_DIMENSION_TEXTURE2D = 4, - D3D12_RTV_DIMENSION_TEXTURE2DARRAY = 5, - D3D12_RTV_DIMENSION_TEXTURE2DMS = 6, - D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY = 7, - D3D12_RTV_DIMENSION_TEXTURE3D = 8, -} D3D12_RTV_DIMENSION; - -typedef struct D3D12_BUFFER_RTV -{ - UINT64 FirstElement; - UINT NumElements; -} D3D12_BUFFER_RTV; - -typedef struct D3D12_TEX1D_RTV -{ - UINT MipSlice; -} D3D12_TEX1D_RTV; - -typedef struct D3D12_TEX1D_ARRAY_RTV -{ - UINT MipSlice; - UINT FirstArraySlice; - UINT ArraySize; -} D3D12_TEX1D_ARRAY_RTV; - -typedef struct D3D12_TEX2D_RTV -{ - UINT MipSlice; - UINT PlaneSlice; -} D3D12_TEX2D_RTV; - -typedef struct D3D12_TEX2D_ARRAY_RTV -{ - UINT MipSlice; - UINT FirstArraySlice; - UINT ArraySize; - UINT PlaneSlice; -} D3D12_TEX2D_ARRAY_RTV; - -typedef struct D3D12_TEX2DMS_RTV -{ - UINT UnusedField_NothingToDefine; -} D3D12_TEX2DMS_RTV; - -typedef struct D3D12_TEX2DMS_ARRAY_RTV -{ - UINT FirstArraySlice; - UINT ArraySize; -} D3D12_TEX2DMS_ARRAY_RTV; - -typedef struct D3D12_TEX3D_RTV -{ - UINT MipSlice; - UINT FirstWSlice; - UINT WSize; -} D3D12_TEX3D_RTV; - -typedef struct D3D12_RENDER_TARGET_VIEW_DESC -{ - DXGI_FORMAT Format; - D3D12_RTV_DIMENSION ViewDimension; - union - { - D3D12_BUFFER_RTV Buffer; - D3D12_TEX1D_RTV Texture1D; - D3D12_TEX1D_ARRAY_RTV Texture1DArray; - D3D12_TEX2D_RTV Texture2D; - D3D12_TEX2D_ARRAY_RTV Texture2DArray; - D3D12_TEX2DMS_RTV Texture2DMS; - D3D12_TEX2DMS_ARRAY_RTV Texture2DMSArray; - D3D12_TEX3D_RTV Texture3D; - }; -} D3D12_RENDER_TARGET_VIEW_DESC; - -typedef enum D3D12_DSV_DIMENSION -{ - D3D12_DSV_DIMENSION_UNKNOWN = 0, - D3D12_DSV_DIMENSION_TEXTURE1D = 1, - D3D12_DSV_DIMENSION_TEXTURE1DARRAY = 2, - D3D12_DSV_DIMENSION_TEXTURE2D = 3, - D3D12_DSV_DIMENSION_TEXTURE2DARRAY = 4, - D3D12_DSV_DIMENSION_TEXTURE2DMS = 5, - D3D12_DSV_DIMENSION_TEXTURE2DMSARRAY = 6, -} D3D12_DSV_DIMENSION; - -typedef enum D3D12_DSV_FLAGS -{ - D3D12_DSV_FLAG_NONE = 0x0, - D3D12_DSV_FLAG_READ_ONLY_DEPTH = 0x1, - D3D12_DSV_FLAG_READ_ONLY_STENCIL = 0x2, -} D3D12_DSV_FLAGS; -cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_DSV_FLAGS);") - -typedef struct D3D12_TEX1D_DSV -{ - UINT MipSlice; -} D3D12_TEX1D_DSV; - -typedef struct D3D12_TEX1D_ARRAY_DSV -{ - UINT MipSlice; - UINT FirstArraySlice; - UINT ArraySize; -} D3D12_TEX1D_ARRAY_DSV; - -typedef struct D3D12_TEX2D_DSV -{ - UINT MipSlice; -} D3D12_TEX2D_DSV; - -typedef struct D3D12_TEX2D_ARRAY_DSV -{ - UINT MipSlice; - UINT FirstArraySlice; - UINT ArraySize; -} D3D12_TEX2D_ARRAY_DSV; - -typedef struct D3D12_TEX2DMS_DSV -{ - UINT UnusedField_NothingToDefine; -} D3D12_TEX2DMS_DSV; - -typedef struct D3D12_TEX2DMS_ARRAY_DSV -{ - UINT FirstArraySlice; - UINT ArraySize; -} D3D12_TEX2DMS_ARRAY_DSV; - -typedef struct D3D12_DEPTH_STENCIL_VIEW_DESC -{ - DXGI_FORMAT Format; - D3D12_DSV_DIMENSION ViewDimension; - D3D12_DSV_FLAGS Flags; - union - { - D3D12_TEX1D_DSV Texture1D; - D3D12_TEX1D_ARRAY_DSV Texture1DArray; - D3D12_TEX2D_DSV Texture2D; - D3D12_TEX2D_ARRAY_DSV Texture2DArray; - D3D12_TEX2DMS_DSV Texture2DMS; - D3D12_TEX2DMS_ARRAY_DSV Texture2DMSArray; - }; -} D3D12_DEPTH_STENCIL_VIEW_DESC; - -typedef struct D3D12_SAMPLER_DESC -{ - D3D12_FILTER Filter; - D3D12_TEXTURE_ADDRESS_MODE AddressU; - D3D12_TEXTURE_ADDRESS_MODE AddressV; - D3D12_TEXTURE_ADDRESS_MODE AddressW; - FLOAT MipLODBias; - UINT MaxAnisotropy; - D3D12_COMPARISON_FUNC ComparisonFunc; - FLOAT BorderColor[4]; - FLOAT MinLOD; - FLOAT MaxLOD; -} D3D12_SAMPLER_DESC; - -typedef struct D3D12_CPU_DESCRIPTOR_HANDLE -{ - SIZE_T ptr; -} D3D12_CPU_DESCRIPTOR_HANDLE; - -typedef struct D3D12_GPU_DESCRIPTOR_HANDLE -{ - UINT64 ptr; -} D3D12_GPU_DESCRIPTOR_HANDLE; - -typedef enum D3D12_STENCIL_OP -{ - D3D12_STENCIL_OP_KEEP = 1, - D3D12_STENCIL_OP_ZERO = 2, - D3D12_STENCIL_OP_REPLACE = 3, - D3D12_STENCIL_OP_INCR_SAT = 4, - D3D12_STENCIL_OP_DECR_SAT = 5, - D3D12_STENCIL_OP_INVERT = 6, - D3D12_STENCIL_OP_INCR = 7, - D3D12_STENCIL_OP_DECR = 8, -} D3D12_STENCIL_OP; - -typedef struct D3D12_DEPTH_STENCILOP_DESC -{ - D3D12_STENCIL_OP StencilFailOp; - D3D12_STENCIL_OP StencilDepthFailOp; - D3D12_STENCIL_OP StencilPassOp; - D3D12_COMPARISON_FUNC StencilFunc; -} D3D12_DEPTH_STENCILOP_DESC; - -typedef enum D3D12_DEPTH_WRITE_MASK -{ - D3D12_DEPTH_WRITE_MASK_ZERO = 0, - D3D12_DEPTH_WRITE_MASK_ALL = 1, -} D3D12_DEPTH_WRITE_MASK; - -typedef struct D3D12_DEPTH_STENCIL_DESC -{ - BOOL DepthEnable; - D3D12_DEPTH_WRITE_MASK DepthWriteMask; - D3D12_COMPARISON_FUNC DepthFunc; - BOOL StencilEnable; - UINT8 StencilReadMask; - UINT8 StencilWriteMask; - D3D12_DEPTH_STENCILOP_DESC FrontFace; - D3D12_DEPTH_STENCILOP_DESC BackFace; -} D3D12_DEPTH_STENCIL_DESC; - -typedef enum D3D12_BLEND -{ - D3D12_BLEND_ZERO = 1, - D3D12_BLEND_ONE = 2, - D3D12_BLEND_SRC_COLOR = 3, - D3D12_BLEND_INV_SRC_COLOR = 4, - D3D12_BLEND_SRC_ALPHA = 5, - D3D12_BLEND_INV_SRC_ALPHA = 6, - D3D12_BLEND_DEST_ALPHA = 7, - D3D12_BLEND_INV_DEST_ALPHA = 8, - D3D12_BLEND_DEST_COLOR = 9, - D3D12_BLEND_INV_DEST_COLOR = 10, - D3D12_BLEND_SRC_ALPHA_SAT = 11, - D3D12_BLEND_BLEND_FACTOR = 14, - D3D12_BLEND_INV_BLEND_FACTOR = 15, - D3D12_BLEND_SRC1_COLOR = 16, - D3D12_BLEND_INV_SRC1_COLOR = 17, - D3D12_BLEND_SRC1_ALPHA = 18, - D3D12_BLEND_INV_SRC1_ALPHA = 19, -} D3D12_BLEND; - -typedef enum D3D12_BLEND_OP -{ - D3D12_BLEND_OP_ADD = 1, - D3D12_BLEND_OP_SUBTRACT = 2, - D3D12_BLEND_OP_REV_SUBTRACT = 3, - D3D12_BLEND_OP_MIN = 4, - D3D12_BLEND_OP_MAX = 5, -} D3D12_BLEND_OP; - -typedef enum D3D12_LOGIC_OP -{ - D3D12_LOGIC_OP_CLEAR = 0x0, - D3D12_LOGIC_OP_SET = 0x1, - D3D12_LOGIC_OP_COPY = 0x2, - D3D12_LOGIC_OP_COPY_INVERTED = 0x3, - D3D12_LOGIC_OP_NOOP = 0x4, - D3D12_LOGIC_OP_INVERT = 0x5, - D3D12_LOGIC_OP_AND = 0x6, - D3D12_LOGIC_OP_NAND = 0x7, - D3D12_LOGIC_OP_OR = 0x8, - D3D12_LOGIC_OP_NOR = 0x9, - D3D12_LOGIC_OP_XOR = 0xa, - D3D12_LOGIC_OP_EQUIV = 0xb, - D3D12_LOGIC_OP_AND_REVERSE = 0xc, - D3D12_LOGIC_OP_AND_INVERTED = 0xd, - D3D12_LOGIC_OP_OR_REVERSE = 0xe, - D3D12_LOGIC_OP_OR_INVERTED = 0xf, -} D3D12_LOGIC_OP; - -typedef enum D3D12_COLOR_WRITE_ENABLE -{ - D3D12_COLOR_WRITE_ENABLE_RED = 0x1, - D3D12_COLOR_WRITE_ENABLE_GREEN = 0x2, - D3D12_COLOR_WRITE_ENABLE_BLUE = 0x4, - D3D12_COLOR_WRITE_ENABLE_ALPHA = 0x8, - D3D12_COLOR_WRITE_ENABLE_ALL = (D3D12_COLOR_WRITE_ENABLE_RED - | D3D12_COLOR_WRITE_ENABLE_GREEN | D3D12_COLOR_WRITE_ENABLE_BLUE - | D3D12_COLOR_WRITE_ENABLE_ALPHA), -} D3D12_COLOR_WRITE_ENABLE; - -typedef struct D3D12_RENDER_TARGET_BLEND_DESC -{ - BOOL BlendEnable; - BOOL LogicOpEnable; - D3D12_BLEND SrcBlend; - D3D12_BLEND DestBlend; - D3D12_BLEND_OP BlendOp; - D3D12_BLEND SrcBlendAlpha; - D3D12_BLEND DestBlendAlpha; - D3D12_BLEND_OP BlendOpAlpha; - D3D12_LOGIC_OP LogicOp; - UINT8 RenderTargetWriteMask; -} D3D12_RENDER_TARGET_BLEND_DESC; - -typedef struct D3D12_BLEND_DESC -{ - BOOL AlphaToCoverageEnable; - BOOL IndependentBlendEnable; - D3D12_RENDER_TARGET_BLEND_DESC RenderTarget[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT]; -} D3D12_BLEND_DESC; - -typedef enum D3D12_FILL_MODE -{ - D3D12_FILL_MODE_WIREFRAME = 2, - D3D12_FILL_MODE_SOLID = 3, -} D3D12_FILL_MODE; - -typedef enum D3D12_CULL_MODE -{ - D3D12_CULL_MODE_NONE = 1, - D3D12_CULL_MODE_FRONT = 2, - D3D12_CULL_MODE_BACK = 3, -} D3D12_CULL_MODE; - -typedef enum D3D12_CONSERVATIVE_RASTERIZATION_MODE -{ - D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF = 0, - D3D12_CONSERVATIVE_RASTERIZATION_MODE_ON = 1, -} D3D12_CONSERVATIVE_RASTERIZATION_MODE; - -typedef struct D3D12_RASTERIZER_DESC -{ - D3D12_FILL_MODE FillMode; - D3D12_CULL_MODE CullMode; - BOOL FrontCounterClockwise; - INT DepthBias; - FLOAT DepthBiasClamp; - FLOAT SlopeScaledDepthBias; - BOOL DepthClipEnable; - BOOL MultisampleEnable; - BOOL AntialiasedLineEnable; - UINT ForcedSampleCount; - D3D12_CONSERVATIVE_RASTERIZATION_MODE ConservativeRaster; -} D3D12_RASTERIZER_DESC; - -typedef struct D3D12_SO_DECLARATION_ENTRY -{ - UINT Stream; - const char *SemanticName; - UINT SemanticIndex; - BYTE StartComponent; - BYTE ComponentCount; - BYTE OutputSlot; -} D3D12_SO_DECLARATION_ENTRY; - -typedef struct D3D12_STREAM_OUTPUT_DESC -{ - const D3D12_SO_DECLARATION_ENTRY *pSODeclaration; - UINT NumEntries; - const UINT *pBufferStrides; - UINT NumStrides; - UINT RasterizedStream; -} D3D12_STREAM_OUTPUT_DESC; - -typedef enum D3D12_INPUT_CLASSIFICATION -{ - D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA = 0, - D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA = 1, -} D3D12_INPUT_CLASSIFICATION; - -typedef struct D3D12_INPUT_ELEMENT_DESC -{ - const char *SemanticName; - UINT SemanticIndex; - DXGI_FORMAT Format; - UINT InputSlot; - UINT AlignedByteOffset; - D3D12_INPUT_CLASSIFICATION InputSlotClass; - UINT InstanceDataStepRate; -} D3D12_INPUT_ELEMENT_DESC; - -typedef struct D3D12_INPUT_LAYOUT_DESC -{ - const D3D12_INPUT_ELEMENT_DESC *pInputElementDescs; - UINT NumElements; -} D3D12_INPUT_LAYOUT_DESC; - -typedef enum D3D12_INDEX_BUFFER_STRIP_CUT_VALUE -{ - D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED = 0, - D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF = 1, - D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF = 2, -} D3D12_INDEX_BUFFER_STRIP_CUT_VALUE; - -typedef D3D_PRIMITIVE_TOPOLOGY D3D12_PRIMITIVE_TOPOLOGY; - -typedef enum D3D12_PRIMITIVE_TOPOLOGY_TYPE -{ - D3D12_PRIMITIVE_TOPOLOGY_TYPE_UNDEFINED = 0, - D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT = 1, - D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE = 2, - D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE = 3, - D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH = 4, -} D3D12_PRIMITIVE_TOPOLOGY_TYPE; - -typedef struct D3D12_CACHED_PIPELINE_STATE -{ - const void *pCachedBlob; - SIZE_T CachedBlobSizeInBytes; -} D3D12_CACHED_PIPELINE_STATE; - -typedef enum D3D12_PIPELINE_STATE_FLAGS -{ - D3D12_PIPELINE_STATE_FLAG_NONE = 0x0, - D3D12_PIPELINE_STATE_FLAG_DEBUG = 0x1, -} D3D12_PIPELINE_STATE_FLAGS; -cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_PIPELINE_STATE_FLAGS);") - -typedef struct D3D12_GRAPHICS_PIPELINE_STATE_DESC -{ - ID3D12RootSignature *pRootSignature; - D3D12_SHADER_BYTECODE VS; - D3D12_SHADER_BYTECODE PS; - D3D12_SHADER_BYTECODE DS; - D3D12_SHADER_BYTECODE HS; - D3D12_SHADER_BYTECODE GS; - D3D12_STREAM_OUTPUT_DESC StreamOutput; - D3D12_BLEND_DESC BlendState; - UINT SampleMask; - D3D12_RASTERIZER_DESC RasterizerState; - D3D12_DEPTH_STENCIL_DESC DepthStencilState; - D3D12_INPUT_LAYOUT_DESC InputLayout; - D3D12_INDEX_BUFFER_STRIP_CUT_VALUE IBStripCutValue; - D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimitiveTopologyType; - UINT NumRenderTargets; - DXGI_FORMAT RTVFormats[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT]; - DXGI_FORMAT DSVFormat; - DXGI_SAMPLE_DESC SampleDesc; - UINT NodeMask; - D3D12_CACHED_PIPELINE_STATE CachedPSO; - D3D12_PIPELINE_STATE_FLAGS Flags; -} D3D12_GRAPHICS_PIPELINE_STATE_DESC; - -typedef struct D3D12_COMPUTE_PIPELINE_STATE_DESC -{ - ID3D12RootSignature *pRootSignature; - D3D12_SHADER_BYTECODE CS; - UINT NodeMask; - D3D12_CACHED_PIPELINE_STATE CachedPSO; - D3D12_PIPELINE_STATE_FLAGS Flags; -} D3D12_COMPUTE_PIPELINE_STATE_DESC; - -typedef enum D3D12_COMMAND_LIST_TYPE -{ - D3D12_COMMAND_LIST_TYPE_DIRECT = 0, - D3D12_COMMAND_LIST_TYPE_BUNDLE = 1, - D3D12_COMMAND_LIST_TYPE_COMPUTE = 2, - D3D12_COMMAND_LIST_TYPE_COPY = 3, -} D3D12_COMMAND_LIST_TYPE; - -typedef enum D3D12_COMMAND_QUEUE_PRIORITY -{ - D3D12_COMMAND_QUEUE_PRIORITY_NORMAL = 0, - D3D12_COMMAND_QUEUE_PRIORITY_HIGH = 100, - D3D12_COMMAND_QUEUE_PRIORITY_GLOBAL_REALTIME = 10000, -} D3D12_COMMAND_QUEUE_PRIORITY; - -typedef enum D3D12_COMMAND_QUEUE_FLAGS -{ - D3D12_COMMAND_QUEUE_FLAG_NONE = 0x0, - D3D12_COMMAND_QUEUE_FLAG_DISABLE_GPU_TIMEOUT = 0x1, -} D3D12_COMMAND_QUEUE_FLAGS; -cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_COMMAND_QUEUE_FLAGS);") - -typedef struct D3D12_COMMAND_QUEUE_DESC -{ - D3D12_COMMAND_LIST_TYPE Type; - INT Priority; - D3D12_COMMAND_QUEUE_FLAGS Flags; - UINT NodeMask; -} D3D12_COMMAND_QUEUE_DESC; - -typedef struct D3D12_FEATURE_DATA_ARCHITECTURE -{ - UINT NodeIndex; - BOOL TileBasedRenderer; - BOOL UMA; - BOOL CacheCoherentUMA; -} D3D12_FEATURE_DATA_ARCHITECTURE; - -typedef struct D3D12_FEATURE_DATA_FORMAT_INFO -{ - DXGI_FORMAT Format; - UINT8 PlaneCount; -} D3D12_FEATURE_DATA_FORMAT_INFO; - -typedef struct D3D12_FEATURE_DATA_FEATURE_LEVELS -{ - UINT NumFeatureLevels; - const D3D_FEATURE_LEVEL *pFeatureLevelsRequested; - D3D_FEATURE_LEVEL MaxSupportedFeatureLevel; -} D3D12_FEATURE_DATA_FEATURE_LEVELS; - -typedef struct D3D12_FEATURE_DATA_ROOT_SIGNATURE -{ - D3D_ROOT_SIGNATURE_VERSION HighestVersion; -} D3D12_FEATURE_DATA_ROOT_SIGNATURE; - -typedef struct D3D12_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT -{ - UINT MaxGPUVirtualAddressBitsPerResource; - UINT MaxGPUVirtualAddressBitsPerProcess; -} D3D12_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT; - -typedef enum D3D_SHADER_MODEL -{ - D3D_SHADER_MODEL_5_1 = 0x51, - D3D_SHADER_MODEL_6_0 = 0x60, -} D3D_SHADER_MODEL; - -typedef struct D3D12_FEATURE_DATA_SHADER_MODEL -{ - D3D_SHADER_MODEL HighestShaderModel; -} D3D12_FEATURE_DATA_SHADER_MODEL; - -typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS1 -{ - BOOL WaveOps; - UINT WaveLaneCountMin; - UINT WaveLaneCountMax; - UINT TotalLaneCount; - BOOL ExpandedComputeResourceStates; - BOOL Int64ShaderOps; -} D3D12_FEATURE_DATA_D3D12_OPTIONS1; - -typedef struct D3D12_FEATURE_DATA_ARCHITECTURE1 -{ - UINT NodeIndex; - BOOL TileBasedRenderer; - BOOL UMA; - BOOL CacheCoherentUMA; - BOOL IsolatedMMU; -} D3D12_FEATURE_DATA_ARCHITECTURE1; - -typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS2 -{ - BOOL DepthBoundsTestSupported; - D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER ProgrammableSamplePositionsTier; -} D3D12_FEATURE_DATA_D3D12_OPTIONS2; - -typedef struct D3D12_FEATURE_DATA_SHADER_CACHE -{ - D3D12_SHADER_CACHE_SUPPORT_FLAGS SupportFlags; -} D3D12_FEATURE_DATA_SHADER_CACHE; - -typedef struct D3D12_FEATURE_DATA_COMMAND_QUEUE_PRIORITY -{ - D3D12_COMMAND_LIST_TYPE CommandListType; - UINT Priority; - BOOL PriorityForTypeIsSupported; -} D3D12_FEATURE_DATA_COMMAND_QUEUE_PRIORITY; - -typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS3 -{ - BOOL CopyQueueTimestampQueriesSupported; - BOOL CastingFullyTypedFormatSupported; - D3D12_COMMAND_LIST_SUPPORT_FLAGS WriteBufferImmediateSupportFlags; - D3D12_VIEW_INSTANCING_TIER ViewInstancingTier; - BOOL BarycentricsSupported; -} D3D12_FEATURE_DATA_D3D12_OPTIONS3; - -typedef struct D3D12_FEATURE_DATA_EXISTING_HEAPS -{ - BOOL Supported; -} D3D12_FEATURE_DATA_EXISTING_HEAPS; - -typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS4 -{ - BOOL MSAA64KBAlignedTextureSupported; - D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER SharedResourceCompatibilityTier; - BOOL Native16BitShaderOpsSupported; -} D3D12_FEATURE_DATA_D3D12_OPTIONS4; - -typedef struct D3D12_FEATURE_DATA_SERIALIZATION -{ - UINT NodeIndex; - D3D12_HEAP_SERIALIZATION_TIER HeapSerializationTier; -} D3D12_FEATURE_DATA_SERIALIZATION; - -typedef struct D3D12_FEATURE_DATA_CROSS_NODE -{ - D3D12_CROSS_NODE_SHARING_TIER SharingTier; - BOOL AtomicShaderInstructions; -} D3D12_FEATURE_DATA_CROSS_NODE; - -typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS5 -{ - BOOL SRVOnlyTiledResourceTier3; - D3D12_RENDER_PASS_TIER RenderPassesTier; - D3D12_RAYTRACING_TIER RaytracingTier; -} D3D12_FEATURE_DATA_D3D12_OPTIONS5; - -typedef enum D3D12_FEATURE -{ - D3D12_FEATURE_D3D12_OPTIONS = 0, - D3D12_FEATURE_ARCHITECTURE = 1, - D3D12_FEATURE_FEATURE_LEVELS = 2, - D3D12_FEATURE_FORMAT_SUPPORT = 3, - D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS = 4, - D3D12_FEATURE_FORMAT_INFO = 5, - D3D12_FEATURE_GPU_VIRTUAL_ADDRESS_SUPPORT = 6, - D3D12_FEATURE_SHADER_MODEL = 7, - D3D12_FEATURE_D3D12_OPTIONS1 = 8, - D3D12_FEATURE_PROTECTED_RESOURCE_SESSION_SUPPORT = 10, - D3D12_FEATURE_ROOT_SIGNATURE = 12, - D3D12_FEATURE_ARCHITECTURE1 = 16, - D3D12_FEATURE_D3D12_OPTIONS2 = 18, - D3D12_FEATURE_SHADER_CACHE = 19, - D3D12_FEATURE_COMMAND_QUEUE_PRIORITY = 20, - D3D12_FEATURE_D3D12_OPTIONS3 = 21, - D3D12_FEATURE_EXISTING_HEAPS = 22, - D3D12_FEATURE_D3D12_OPTIONS4 = 23, - D3D12_FEATURE_SERIALIZATION = 24, - D3D12_FEATURE_CROSS_NODE = 25, - D3D12_FEATURE_D3D12_OPTIONS5 = 27, - D3D12_FEATURE_D3D12_OPTIONS6 = 30, - D3D12_FEATURE_QUERY_META_COMMAND = 31, - D3D12_FEATURE_D3D12_OPTIONS7 = 32, - D3D12_FEATURE_PROTECTED_RESOURCE_SESSION_TYPE_COUNT = 33, - D3D12_FEATURE_PROTECTED_RESOURCE_SESSION_TYPES = 34, -} D3D12_FEATURE; - -typedef struct D3D12_MEMCPY_DEST -{ - void *pData; - SIZE_T RowPitch; - SIZE_T SlicePitch; -} D3D12_MEMCPY_DEST; - -typedef struct D3D12_SUBRESOURCE_DATA -{ - const void *pData; - LONG_PTR RowPitch; - LONG_PTR SlicePitch; -} D3D12_SUBRESOURCE_DATA; - -typedef enum D3D12_MULTIPLE_FENCE_WAIT_FLAGS -{ - D3D12_MULTIPLE_FENCE_WAIT_FLAG_NONE = 0x0, - D3D12_MULTIPLE_FENCE_WAIT_FLAG_ANY = 0x1, - D3D12_MULTIPLE_FENCE_WAIT_FLAG_ALL = 0x0, -} D3D12_MULTIPLE_FENCE_WAIT_FLAGS; -cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_MULTIPLE_FENCE_WAIT_FLAGS);") - -typedef enum D3D12_RESIDENCY_PRIORITY -{ - D3D12_RESIDENCY_PRIORITY_MINIMUM = 0x28000000, - D3D12_RESIDENCY_PRIORITY_LOW = 0x50000000, - D3D12_RESIDENCY_PRIORITY_NORMAL = 0x78000000, - D3D12_RESIDENCY_PRIORITY_HIGH = 0xa0010000, - D3D12_RESIDENCY_PRIORITY_MAXIMUM = 0xc8000000, -} D3D12_RESIDENCY_PRIORITY; - -typedef struct D3D12_WRITEBUFFERIMMEDIATE_PARAMETER -{ - D3D12_GPU_VIRTUAL_ADDRESS Dest; - UINT32 Value; -} D3D12_WRITEBUFFERIMMEDIATE_PARAMETER; - -[ - uuid(c4fec28f-7966-4e95-9f94-f431cb56c3b8), - object, - local, - pointer_default(unique) -] -interface ID3D12Object : IUnknown -{ - HRESULT GetPrivateData(REFGUID guid, UINT *data_size, void *data); - HRESULT SetPrivateData(REFGUID guid, UINT data_size, const void *data); - HRESULT SetPrivateDataInterface(REFGUID guid, const IUnknown *data); - HRESULT SetName(const WCHAR *name); -} - -[ - uuid(905db94b-a00c-4140-9df5-2b64ca9ea357), - object, - local, - pointer_default(unique) -] -interface ID3D12DeviceChild : ID3D12Object -{ - HRESULT GetDevice(REFIID riid, void **device); -} - -[ - uuid(63ee58fb-1268-4835-86da-f008ce62f0d6), - object, - local, - pointer_default(unique) -] -interface ID3D12Pageable : ID3D12DeviceChild -{ -} - -[ - uuid(6b3b2502-6e51-45b3-90ee-9884265e8df3), - object, - local, - pointer_default(unique) -] -interface ID3D12Heap : ID3D12Pageable -{ - D3D12_HEAP_DESC GetDesc(); -} - -[ - uuid(696442be-a72e-4059-bc79-5b5c98040fad), - object, - local, - pointer_default(unique) -] -interface ID3D12Resource : ID3D12Pageable -{ - HRESULT Map(UINT sub_resource, const D3D12_RANGE *read_range, void **data); - void Unmap(UINT sub_resource, const D3D12_RANGE *written_range); - - D3D12_RESOURCE_DESC GetDesc(); - - D3D12_GPU_VIRTUAL_ADDRESS GetGPUVirtualAddress(); - - HRESULT WriteToSubresource(UINT dst_sub_resource, const D3D12_BOX *dst_box, - const void *src_data, UINT src_row_pitch, UINT src_slice_pitch); - HRESULT ReadFromSubresource(void *dst_data, UINT dst_row_pitch, UINT dst_slice_pitch, - UINT src_sub_resource, const D3D12_BOX *src_box); - - HRESULT GetHeapProperties(D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS *flags); -} - -[ - uuid(7116d91c-e7e4-47ce-b8c6-ec8168f437e5), - object, - local, - pointer_default(unique) -] -interface ID3D12CommandList : ID3D12DeviceChild -{ - D3D12_COMMAND_LIST_TYPE GetType(); -} - -typedef enum D3D12_TILE_COPY_FLAGS -{ - D3D12_TILE_COPY_FLAG_NONE = 0x0, - D3D12_TILE_COPY_FLAG_NO_HAZARD = 0x1, - D3D12_TILE_COPY_FLAG_LINEAR_BUFFER_TO_SWIZZLED_TILED_RESOURCE = 0x2, - D3D12_TILE_COPY_FLAG_SWIZZLED_TILED_RESOURCE_TO_LINEAR_BUFFER = 0x4, -} D3D12_TILE_COPY_FLAGS; -cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_TILE_COPY_FLAGS);") - -typedef struct D3D12_INDEX_BUFFER_VIEW -{ - D3D12_GPU_VIRTUAL_ADDRESS BufferLocation; - UINT SizeInBytes; - DXGI_FORMAT Format; -} D3D12_INDEX_BUFFER_VIEW; - -typedef struct D3D12_VERTEX_BUFFER_VIEW -{ - D3D12_GPU_VIRTUAL_ADDRESS BufferLocation; - UINT SizeInBytes; - UINT StrideInBytes; -} D3D12_VERTEX_BUFFER_VIEW; - -typedef struct D3D12_STREAM_OUTPUT_BUFFER_VIEW -{ - D3D12_GPU_VIRTUAL_ADDRESS BufferLocation; - UINT64 SizeInBytes; - D3D12_GPU_VIRTUAL_ADDRESS BufferFilledSizeLocation; -} D3D12_STREAM_OUTPUT_BUFFER_VIEW; - -typedef enum D3D12_CLEAR_FLAGS -{ - D3D12_CLEAR_FLAG_DEPTH = 0x1, - D3D12_CLEAR_FLAG_STENCIL = 0x2, -} D3D12_CLEAR_FLAGS; -cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_CLEAR_FLAGS);") - -typedef struct D3D12_DISCARD_REGION -{ - UINT NumRects; - const D3D12_RECT *pRects; - UINT FirstSubresource; - UINT NumSubresources; -} D3D12_DISCARD_REGION; - -typedef enum D3D12_QUERY_TYPE -{ - D3D12_QUERY_TYPE_OCCLUSION = 0, - D3D12_QUERY_TYPE_BINARY_OCCLUSION = 1, - D3D12_QUERY_TYPE_TIMESTAMP = 2, - D3D12_QUERY_TYPE_PIPELINE_STATISTICS = 3, - D3D12_QUERY_TYPE_SO_STATISTICS_STREAM0 = 4, - D3D12_QUERY_TYPE_SO_STATISTICS_STREAM1 = 5, - D3D12_QUERY_TYPE_SO_STATISTICS_STREAM2 = 6, - D3D12_QUERY_TYPE_SO_STATISTICS_STREAM3 = 7, -} D3D12_QUERY_TYPE; - -typedef struct D3D12_QUERY_DATA_PIPELINE_STATISTICS -{ - UINT64 IAVertices; - UINT64 IAPrimitives; - UINT64 VSInvocations; - UINT64 GSInvocations; - UINT64 GSPrimitives; - UINT64 CInvocations; - UINT64 CPrimitives; - UINT64 PSInvocations; - UINT64 HSInvocations; - UINT64 DSInvocations; - UINT64 CSInvocations; -} D3D12_QUERY_DATA_PIPELINE_STATISTICS; - -typedef struct D3D12_QUERY_DATA_SO_STATISTICS -{ - UINT64 NumPrimitivesWritten; - UINT64 PrimitivesStorageNeeded; -} D3D12_QUERY_DATA_SO_STATISTICS; - -typedef enum D3D12_PREDICATION_OP -{ - D3D12_PREDICATION_OP_EQUAL_ZERO = 0, - D3D12_PREDICATION_OP_NOT_EQUAL_ZERO = 1, -} D3D12_PREDICATION_OP; - -[ - uuid(8efb471d-616c-4f49-90f7-127bb763fa51), - object, - local, - pointer_default(unique) -] -interface ID3D12DescriptorHeap : ID3D12Pageable -{ - D3D12_DESCRIPTOR_HEAP_DESC GetDesc(); - - D3D12_CPU_DESCRIPTOR_HANDLE GetCPUDescriptorHandleForHeapStart(); - D3D12_GPU_DESCRIPTOR_HANDLE GetGPUDescriptorHandleForHeapStart(); -} - -[ - uuid(0d9658ae-ed45-469e-a61d-970ec583cab4), - object, - local, - pointer_default(unique) -] -interface ID3D12QueryHeap : ID3D12Pageable -{ -} - -[ - uuid(c36a797c-ec80-4f0a-8985-a7b2475082d1), - object, - local, - pointer_default(unique) -] -interface ID3D12CommandSignature : ID3D12Pageable -{ -} - -[ - uuid(5b160d0f-ac1b-4185-8ba8-b3ae42a5a455), - object, - local, - pointer_default(unique) -] -interface ID3D12GraphicsCommandList : ID3D12CommandList -{ - HRESULT Close(); - - HRESULT Reset(ID3D12CommandAllocator *allocator, ID3D12PipelineState *initial_state); - - void ClearState(ID3D12PipelineState *pipeline_state); - - void DrawInstanced(UINT vertex_count_per_instance, UINT instance_count, - UINT start_vertex_location, UINT start_instance_location); - void DrawIndexedInstanced(UINT index_count_per_instance, UINT instance_count, - UINT start_vertex_location, INT base_vertex_location, UINT start_instance_location); - - void Dispatch(UINT x, UINT u, UINT z); - - void CopyBufferRegion(ID3D12Resource *dst_buffer, UINT64 dst_offset, - ID3D12Resource *src_buffer, UINT64 src_offset, UINT64 byte_count); - void CopyTextureRegion(const D3D12_TEXTURE_COPY_LOCATION *dst, - UINT dst_x, UINT dst_y, UINT dst_z, - const D3D12_TEXTURE_COPY_LOCATION *src, const D3D12_BOX *src_box); - void CopyResource(ID3D12Resource *dst_resource, ID3D12Resource *src_resource); - - void CopyTiles(ID3D12Resource *tiled_resource, - const D3D12_TILED_RESOURCE_COORDINATE *tile_region_start_coordinate, - const D3D12_TILE_REGION_SIZE *tile_region_size, - ID3D12Resource *buffer, - UINT64 buffer_offset, - D3D12_TILE_COPY_FLAGS flags); - - void ResolveSubresource(ID3D12Resource *dst_resource, UINT dst_sub_resource, - ID3D12Resource *src_resource, UINT src_sub_resource, - DXGI_FORMAT format); - - void IASetPrimitiveTopology(D3D12_PRIMITIVE_TOPOLOGY primitive_topology); - - void RSSetViewports(UINT viewport_count, const D3D12_VIEWPORT *viewports); - void RSSetScissorRects(UINT rect_count, const D3D12_RECT *rects); - - void OMSetBlendFactor(const FLOAT blend_factor[4]); - void OMSetStencilRef(UINT stencil_ref); - - void SetPipelineState(ID3D12PipelineState *pipeline_state); - - void ResourceBarrier(UINT barrier_count, const D3D12_RESOURCE_BARRIER *barriers); - - void ExecuteBundle(ID3D12GraphicsCommandList *command_list); - - void SetDescriptorHeaps(UINT heap_count, ID3D12DescriptorHeap * const *heaps); - - void SetComputeRootSignature(ID3D12RootSignature *root_signature); - void SetGraphicsRootSignature(ID3D12RootSignature *root_signature); - - void SetComputeRootDescriptorTable(UINT root_parameter_index, D3D12_GPU_DESCRIPTOR_HANDLE base_descriptor); - void SetGraphicsRootDescriptorTable(UINT root_parameter_index, D3D12_GPU_DESCRIPTOR_HANDLE base_descriptor); - - void SetComputeRoot32BitConstant(UINT root_parameter_index, UINT data, UINT dst_offset); - void SetGraphicsRoot32BitConstant(UINT root_parameter_index, UINT data, UINT dst_offset); - - void SetComputeRoot32BitConstants(UINT root_parameter_index, UINT constant_count, const void *data, - UINT dst_offset); - void SetGraphicsRoot32BitConstants(UINT root_parameter_index, UINT constant_count, const void *data, - UINT dst_offset); - - void SetComputeRootConstantBufferView(UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address); - void SetGraphicsRootConstantBufferView(UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address); - - void SetComputeRootShaderResourceView(UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address); - void SetGraphicsRootShaderResourceView(UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address); - - void SetComputeRootUnorderedAccessView(UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address); - void SetGraphicsRootUnorderedAccessView(UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address); - - void IASetIndexBuffer(const D3D12_INDEX_BUFFER_VIEW *view); - void IASetVertexBuffers(UINT start_slot, UINT view_count, const D3D12_VERTEX_BUFFER_VIEW *views); - - void SOSetTargets(UINT start_slot, UINT view_count, const D3D12_STREAM_OUTPUT_BUFFER_VIEW *views); - - void OMSetRenderTargets(UINT render_target_descriptor_count, - const D3D12_CPU_DESCRIPTOR_HANDLE *render_target_descriptors, - BOOL single_descriptor_handle, - const D3D12_CPU_DESCRIPTOR_HANDLE *depth_stencil_descriptor); - - void ClearDepthStencilView(D3D12_CPU_DESCRIPTOR_HANDLE dsv, D3D12_CLEAR_FLAGS flags, - FLOAT depth, UINT8 stencil, UINT rect_count, const D3D12_RECT *rects); - void ClearRenderTargetView(D3D12_CPU_DESCRIPTOR_HANDLE rtv, const FLOAT color[4], - UINT rect_count, const D3D12_RECT *rects); - void ClearUnorderedAccessViewUint(D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle, - D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle, ID3D12Resource *resource, const UINT values[4], - UINT rect_count, const D3D12_RECT *rects); - void ClearUnorderedAccessViewFloat(D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle, - D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle, ID3D12Resource *resource, const float values[4], - UINT rect_count, const D3D12_RECT *rects); - - void DiscardResource(ID3D12Resource *resource, const D3D12_DISCARD_REGION *region); - - void BeginQuery(ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, UINT index); - void EndQuery(ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, UINT index); - void ResolveQueryData(ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, - UINT start_index, UINT query_count, - ID3D12Resource *dst_buffer, UINT64 aligned_dst_buffer_offset); - - void SetPredication(ID3D12Resource *buffer, UINT64 aligned_buffer_offset, - D3D12_PREDICATION_OP operation); - - void SetMarker(UINT metadata, const void *data, UINT size); - void BeginEvent(UINT metadata, const void *data, UINT size); - void EndEvent(); - - void ExecuteIndirect(ID3D12CommandSignature *command_signature, - UINT max_command_count, ID3D12Resource *arg_buffer, UINT64 arg_buffer_offset, - ID3D12Resource *count_buffer, UINT64 count_buffer_offset); -} - -[ - uuid(553103fb-1fe7-4557-bb38-946d7d0e7ca7), - object, - local, - pointer_default(unique) -] -interface ID3D12GraphicsCommandList1 : ID3D12GraphicsCommandList -{ - void AtomicCopyBufferUINT(ID3D12Resource *dst_buffer, UINT64 dst_offset, - ID3D12Resource *src_buffer, UINT64 src_offset, - UINT dependent_resource_count, ID3D12Resource * const *dependent_resources, - const D3D12_SUBRESOURCE_RANGE_UINT64 *dependent_sub_resource_ranges); - - void AtomicCopyBufferUINT64(ID3D12Resource *dst_buffer, UINT64 dst_offset, - ID3D12Resource *src_buffer, UINT64 src_offset, - UINT dependent_resource_count, ID3D12Resource * const *dependent_resources, - const D3D12_SUBRESOURCE_RANGE_UINT64 *dependent_sub_resource_ranges); - - void OMSetDepthBounds(FLOAT min, FLOAT max); - - void SetSamplePositions(UINT sample_count, UINT pixel_count, - D3D12_SAMPLE_POSITION *sample_positions); - - void ResolveSubresourceRegion(ID3D12Resource *dst_resource, - UINT dst_sub_resource_idx, UINT dst_x, UINT dst_y, - ID3D12Resource *src_resource, UINT src_sub_resource_idx, - D3D12_RECT *src_rect, DXGI_FORMAT format, D3D12_RESOLVE_MODE mode); - - void SetViewInstanceMask(UINT mask); -} - -[ - uuid(38c3e585-ff17-412c-9150-4fc6f9d72a28), - object, - local, - pointer_default(unique) -] -interface ID3D12GraphicsCommandList2 : ID3D12GraphicsCommandList1 -{ - void WriteBufferImmediate(UINT count, - const D3D12_WRITEBUFFERIMMEDIATE_PARAMETER *parameters, - const D3D12_WRITEBUFFERIMMEDIATE_MODE *modes); -} - -typedef enum D3D12_TILE_RANGE_FLAGS -{ - D3D12_TILE_RANGE_FLAG_NONE = 0x0, - D3D12_TILE_RANGE_FLAG_NULL = 0x1, - D3D12_TILE_RANGE_FLAG_SKIP = 0x2, - D3D12_TILE_RANGE_FLAG_REUSE_SINGLE_TILE = 0x4 -} D3D12_TILE_RANGE_FLAGS; - -typedef enum D3D12_TILE_MAPPING_FLAGS -{ - D3D12_TILE_MAPPING_FLAG_NONE = 0x0, - D3D12_TILE_MAPPING_FLAG_NO_HAZARD = 0x1, -} D3D12_TILE_MAPPING_FLAGS; -cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_TILE_MAPPING_FLAGS);") - -[ - uuid(0ec870a6-5d7e-4c22-8cfc-5baae07616ed), - object, - local, - pointer_default(unique) -] -interface ID3D12CommandQueue : ID3D12Pageable -{ - void UpdateTileMappings(ID3D12Resource *resource, UINT region_count, - const D3D12_TILED_RESOURCE_COORDINATE *region_start_coordinates, - const D3D12_TILE_REGION_SIZE *region_sizes, - UINT range_count, - const D3D12_TILE_RANGE_FLAGS *range_flags, - UINT *heap_range_offsets, - UINT *range_tile_counts, - D3D12_TILE_MAPPING_FLAGS flags); - - void CopyTileMappings(ID3D12Resource *dst_resource, - const D3D12_TILED_RESOURCE_COORDINATE *dst_region_start_coordinate, - ID3D12Resource *src_resource, - const D3D12_TILED_RESOURCE_COORDINATE *src_region_start_coordinate, - const D3D12_TILE_REGION_SIZE *region_size, - D3D12_TILE_MAPPING_FLAGS flags); - - void ExecuteCommandLists(UINT command_list_count, - ID3D12CommandList * const * command_lists); - - void SetMarker(UINT metadata, const void *data, UINT size); - void BeginEvent(UINT metadata, const void *data, UINT size); - void EndEvent(); - - HRESULT Signal(ID3D12Fence *fence, UINT64 value); - HRESULT Wait(ID3D12Fence *fence, UINT64 value); - - HRESULT GetTimestampFrequency(UINT64 *frequency); - HRESULT GetClockCalibration(UINT64 *gpu_timestamp, UINT64 *cpu_timestamp); - - D3D12_COMMAND_QUEUE_DESC GetDesc(); -} - -typedef enum D3D12_FENCE_FLAGS -{ - D3D12_FENCE_FLAG_NONE = 0x0, - D3D12_FENCE_FLAG_SHARED = 0x1, - D3D12_FENCE_FLAG_SHARED_CROSS_ADAPTER = 0x2, -} D3D12_FENCE_FLAGS; -cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_FENCE_FLAGS);") - -typedef enum D3D12_QUERY_HEAP_TYPE -{ - D3D12_QUERY_HEAP_TYPE_OCCLUSION = 0, - D3D12_QUERY_HEAP_TYPE_TIMESTAMP = 1, - D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS = 2, - D3D12_QUERY_HEAP_TYPE_SO_STATISTICS = 3, -} D3D12_QUERY_HEAP_TYPE; - -typedef struct D3D12_QUERY_HEAP_DESC -{ - D3D12_QUERY_HEAP_TYPE Type; - UINT Count; - UINT NodeMask; -} D3D12_QUERY_HEAP_DESC; - -typedef enum D3D12_INDIRECT_ARGUMENT_TYPE -{ - D3D12_INDIRECT_ARGUMENT_TYPE_DRAW, - D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED, - D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH, - D3D12_INDIRECT_ARGUMENT_TYPE_VERTEX_BUFFER_VIEW, - D3D12_INDIRECT_ARGUMENT_TYPE_INDEX_BUFFER_VIEW, - D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT, - D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT_BUFFER_VIEW, - D3D12_INDIRECT_ARGUMENT_TYPE_SHADER_RESOURCE_VIEW, - D3D12_INDIRECT_ARGUMENT_TYPE_UNORDERED_ACCESS_VIEW, -} D3D12_INDIRECT_ARGUMENT_TYPE; - -typedef struct D3D12_INDIRECT_ARGUMENT_DESC -{ - D3D12_INDIRECT_ARGUMENT_TYPE Type; - union - { - struct - { - UINT Slot; - } VertexBuffer; - struct - { - UINT RootParameterIndex; - UINT DestOffsetIn32BitValues; - UINT Num32BitValuesToSet; - } Constant; - struct - { - UINT RootParameterIndex; - } ConstantBufferView; - struct - { - UINT RootParameterIndex; - } ShaderResourceView; - struct - { - UINT RootParameterIndex; - } UnorderedAccessView; - }; -} D3D12_INDIRECT_ARGUMENT_DESC; - -typedef struct D3D12_COMMAND_SIGNATURE_DESC -{ - UINT ByteStride; - UINT NumArgumentDescs; - const D3D12_INDIRECT_ARGUMENT_DESC *pArgumentDescs; - UINT NodeMask; -} D3D12_COMMAND_SIGNATURE_DESC; - -[ - uuid(c54a6b66-72df-4ee8-8be5-a946a1429214), - object, - local, - pointer_default(unique) -] -interface ID3D12RootSignature : ID3D12DeviceChild -{ -} - -[ - uuid(765a30f3-f624-4c6f-a828-ace948622445), - object, - local, - pointer_default(unique) -] -interface ID3D12PipelineState : ID3D12Pageable -{ - HRESULT GetCachedBlob(ID3DBlob **blob); -} - -[ - uuid(0a753dcf-c4d8-4b91-adf6-be5a60d95a76), - object, - local, - pointer_default(unique) -] -interface ID3D12Fence : ID3D12Pageable -{ - UINT64 GetCompletedValue(); - HRESULT SetEventOnCompletion(UINT64 value, HANDLE event); - HRESULT Signal(UINT64 value); -} - -[ - uuid(6102dee4-af59-4b09-b999-b44d73f09b24), - object, - local, - pointer_default(unique) -] -interface ID3D12CommandAllocator : ID3D12Pageable -{ - HRESULT Reset(); -} - -[ - uuid(189819f1-1db6-4b57-be54-1821339b85f7), - object, - local, - pointer_default(unique) -] -interface ID3D12Device : ID3D12Object -{ - UINT GetNodeCount(); - - HRESULT CreateCommandQueue(const D3D12_COMMAND_QUEUE_DESC *desc, - REFIID riid, void **command_queue); - HRESULT CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE type, - REFIID riid, void **command_allocator); - HRESULT CreateGraphicsPipelineState(const D3D12_GRAPHICS_PIPELINE_STATE_DESC *desc, - REFIID riid, void **pipeline_state); - HRESULT CreateComputePipelineState(const D3D12_COMPUTE_PIPELINE_STATE_DESC *desc, - REFIID riid, void **pipeline_state); - HRESULT CreateCommandList(UINT node_mask, - D3D12_COMMAND_LIST_TYPE type, - ID3D12CommandAllocator *command_allocator, - ID3D12PipelineState *initial_pipeline_state, - REFIID riid, void **command_list); - - HRESULT CheckFeatureSupport(D3D12_FEATURE feature, - void *feature_data, UINT feature_data_size); - - HRESULT CreateDescriptorHeap(const D3D12_DESCRIPTOR_HEAP_DESC *desc, - REFIID riid, void **descriptor_heap); - UINT GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE descriptor_heap_type); - - HRESULT CreateRootSignature(UINT node_mask, - const void *bytecode, SIZE_T bytecode_length, - REFIID riid, void **root_signature); - - void CreateConstantBufferView(const D3D12_CONSTANT_BUFFER_VIEW_DESC *desc, - D3D12_CPU_DESCRIPTOR_HANDLE descriptor); - void CreateShaderResourceView(ID3D12Resource *resource, - const D3D12_SHADER_RESOURCE_VIEW_DESC *desc, - D3D12_CPU_DESCRIPTOR_HANDLE descriptor); - void CreateUnorderedAccessView(ID3D12Resource *resource, ID3D12Resource *counter_resource, - const D3D12_UNORDERED_ACCESS_VIEW_DESC *desc, - D3D12_CPU_DESCRIPTOR_HANDLE descriptor); - void CreateRenderTargetView(ID3D12Resource *resource, - const D3D12_RENDER_TARGET_VIEW_DESC *desc, - D3D12_CPU_DESCRIPTOR_HANDLE descriptor); - void CreateDepthStencilView(ID3D12Resource *resource, - const D3D12_DEPTH_STENCIL_VIEW_DESC *desc, - D3D12_CPU_DESCRIPTOR_HANDLE descriptor); - void CreateSampler(const D3D12_SAMPLER_DESC *desc, - D3D12_CPU_DESCRIPTOR_HANDLE descriptor); - - void CopyDescriptors(UINT dst_descriptor_range_count, - const D3D12_CPU_DESCRIPTOR_HANDLE *dst_descriptor_range_offsets, - const UINT *dst_descriptor_range_sizes, - UINT src_descriptor_range_count, - const D3D12_CPU_DESCRIPTOR_HANDLE *src_descriptor_range_offsets, - const UINT *src_descriptor_range_sizes, - D3D12_DESCRIPTOR_HEAP_TYPE descriptor_heap_type); - void CopyDescriptorsSimple(UINT descriptor_count, - const D3D12_CPU_DESCRIPTOR_HANDLE dst_descriptor_range_offset, - const D3D12_CPU_DESCRIPTOR_HANDLE src_descriptor_range_offset, - D3D12_DESCRIPTOR_HEAP_TYPE descriptor_heap_type); - - D3D12_RESOURCE_ALLOCATION_INFO GetResourceAllocationInfo(UINT visible_mask, - UINT reource_desc_count, const D3D12_RESOURCE_DESC *resource_descs); - - D3D12_HEAP_PROPERTIES GetCustomHeapProperties(UINT node_mask, - D3D12_HEAP_TYPE heap_type); - - HRESULT CreateCommittedResource(const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags, - const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state, - const D3D12_CLEAR_VALUE *optimized_clear_value, - REFIID riid, void **resource); - - HRESULT CreateHeap(const D3D12_HEAP_DESC *desc, REFIID riid, void **heap); - - HRESULT CreatePlacedResource(ID3D12Heap *heap, UINT64 heap_offset, - const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state, - const D3D12_CLEAR_VALUE *optimized_clear_value, - REFIID riid, void **resource); - HRESULT CreateReservedResource(const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state, - const D3D12_CLEAR_VALUE *optimized_clear_value, - REFIID riid, void **resource); - - HRESULT CreateSharedHandle(ID3D12DeviceChild *object, - const SECURITY_ATTRIBUTES *attributes, DWORD access, - const WCHAR *name, HANDLE *handle); - HRESULT OpenSharedHandle(HANDLE handle, - REFIID riid, void **object); - HRESULT OpenSharedHandleByName(const WCHAR *name, DWORD access, HANDLE *handle); - - HRESULT MakeResident(UINT object_count, ID3D12Pageable * const *objects); - HRESULT Evict(UINT object_count, ID3D12Pageable * const *objects); - - HRESULT CreateFence(UINT64 initial_value, D3D12_FENCE_FLAGS flags, REFIID riid, void **fence); - - HRESULT GetDeviceRemovedReason(); - - void GetCopyableFootprints(const D3D12_RESOURCE_DESC *desc, - UINT first_sub_resource, - UINT sub_resource_count, - UINT64 base_offset, - D3D12_PLACED_SUBRESOURCE_FOOTPRINT *layouts, - UINT *row_count, - UINT64 *row_size, - UINT64 *total_bytes); - - HRESULT CreateQueryHeap(const D3D12_QUERY_HEAP_DESC *desc, - REFIID riid, void **heap); - - HRESULT SetStablePowerState(BOOL enable); - - HRESULT CreateCommandSignature(const D3D12_COMMAND_SIGNATURE_DESC *desc, - ID3D12RootSignature *root_signature, - REFIID riid, void **command_signature); - - void GetResourceTiling(ID3D12Resource *resource, - UINT *total_tile_count, - D3D12_PACKED_MIP_INFO *packed_mip_info, - D3D12_TILE_SHAPE *standard_tile_shape, - UINT *sub_resource_tiling_count, - UINT first_sub_resource_tiling, - D3D12_SUBRESOURCE_TILING *sub_resource_tilings); - - LUID GetAdapterLuid(); -} - -[ - uuid(77acce80-638e-4e65-8895-c1f23386863e), - object, - local, - pointer_default(unique) -] -interface ID3D12Device1 : ID3D12Device -{ - HRESULT CreatePipelineLibrary(const void *blob, SIZE_T blob_size, REFIID iid, void **lib); - - HRESULT SetEventOnMultipleFenceCompletion(ID3D12Fence * const *fences, - const UINT64 *values, UINT fence_count, D3D12_MULTIPLE_FENCE_WAIT_FLAGS flags, HANDLE event); - - HRESULT SetResidencyPriority(UINT object_count, ID3D12Pageable * const *objects, - const D3D12_RESIDENCY_PRIORITY *priorities); -} - -[ - uuid(34ab647b-3cc8-46ac-841b-c0965645c046), - object, - local, - pointer_default(unique) -] -interface ID3D12RootSignatureDeserializer : IUnknown -{ - const D3D12_ROOT_SIGNATURE_DESC *GetRootSignatureDesc(); -} - -[ - uuid(7f91ce67-090c-4bb7-b78e-ed8ff2e31da0), - object, - local, - pointer_default(unique) -] -interface ID3D12VersionedRootSignatureDeserializer : IUnknown -{ - HRESULT GetRootSignatureDescAtVersion(D3D_ROOT_SIGNATURE_VERSION version, - const D3D12_VERSIONED_ROOT_SIGNATURE_DESC **desc); - - const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *GetUnconvertedRootSignatureDesc(); -}; - -[local] HRESULT __stdcall D3D12CreateRootSignatureDeserializer( - const void *data, SIZE_T data_size, REFIID iid, void **deserializer); - -typedef HRESULT (__stdcall *PFN_D3D12_CREATE_VERSIONED_ROOT_SIGNATURE_DESERIALIZER)( - const void *data, SIZE_T data_size, REFIID iid, void **deserializer); - -[local] HRESULT __stdcall D3D12CreateVersionedRootSignatureDeserializer( - const void *data, SIZE_T data_size, REFIID iid, void **deserializer); - -[local] HRESULT __stdcall D3D12SerializeRootSignature( - const D3D12_ROOT_SIGNATURE_DESC *root_signature_desc, - D3D_ROOT_SIGNATURE_VERSION version, ID3DBlob **blob, ID3DBlob **error_blob); - -typedef HRESULT (__stdcall *PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE)( - const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *desc, ID3DBlob **blob, ID3DBlob **error_blob); - -[local] HRESULT __stdcall D3D12SerializeVersionedRootSignature( - const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *root_signature_desc, - ID3DBlob **blob, ID3DBlob **error_blob); - -typedef HRESULT (__stdcall *PFN_D3D12_CREATE_DEVICE)(IUnknown *adapter, - D3D_FEATURE_LEVEL minimum_feature_level, REFIID iid, void **device); - -[local] HRESULT __stdcall D3D12CreateDevice(IUnknown *adapter, - D3D_FEATURE_LEVEL minimum_feature_level, REFIID iid, void **device); - -typedef HRESULT (__stdcall *PFN_D3D12_GET_DEBUG_INTERFACE)(REFIID iid, void **debug); - -[local] HRESULT __stdcall D3D12GetDebugInterface(REFIID iid, void **debug); - -[local] HRESULT __stdcall D3D12EnableExperimentalFeatures(UINT feature_count, - const IID *iids, void *configurations, UINT *configurations_sizes); diff --git a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_d3d12sdklayers.idl b/dll/directx/wine/d3d12/vkd3d/include/vkd3d_d3d12sdklayers.idl deleted file mode 100644 index 027eeaa268b95..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_d3d12sdklayers.idl +++ /dev/null @@ -1,995 +0,0 @@ -/* - * Copyright 2016-2019 Józef Kucia for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -import "vkd3d_d3d12.idl"; - -typedef enum D3D12_MESSAGE_CATEGORY -{ - D3D12_MESSAGE_CATEGORY_APPLICATION_DEFINED = 0x0, - D3D12_MESSAGE_CATEGORY_MISCELLANEOUS = 0x1, - D3D12_MESSAGE_CATEGORY_INITIALIZATION = 0x2, - D3D12_MESSAGE_CATEGORY_CLEANUP = 0x3, - D3D12_MESSAGE_CATEGORY_COMPILATION = 0x4, - D3D12_MESSAGE_CATEGORY_STATE_CREATION = 0x5, - D3D12_MESSAGE_CATEGORY_STATE_SETTING = 0x6, - D3D12_MESSAGE_CATEGORY_STATE_GETTING = 0x7, - D3D12_MESSAGE_CATEGORY_RESOURCE_MANIPULATION = 0x8, - D3D12_MESSAGE_CATEGORY_EXECUTION = 0x9, - D3D12_MESSAGE_CATEGORY_SHADER = 0xa, -} D3D12_MESSAGE_CATEGORY; - -typedef enum D3D12_MESSAGE_SEVERITY -{ - D3D12_MESSAGE_SEVERITY_CORRUPTION = 0x0, - D3D12_MESSAGE_SEVERITY_ERROR = 0x1, - D3D12_MESSAGE_SEVERITY_WARNING = 0x2, - D3D12_MESSAGE_SEVERITY_INFO = 0x3, - D3D12_MESSAGE_SEVERITY_MESSAGE = 0x4, -} D3D12_MESSAGE_SEVERITY; - -typedef enum D3D12_MESSAGE_ID -{ - D3D12_MESSAGE_ID_UNKNOWN = 0x0000, - D3D12_MESSAGE_ID_STRING_FROM_APPLICATION = 0x0001, - D3D12_MESSAGE_ID_CORRUPTED_THIS = 0x0002, - D3D12_MESSAGE_ID_CORRUPTED_PARAMETER1 = 0x0003, - D3D12_MESSAGE_ID_CORRUPTED_PARAMETER2 = 0x0004, - D3D12_MESSAGE_ID_CORRUPTED_PARAMETER3 = 0x0005, - D3D12_MESSAGE_ID_CORRUPTED_PARAMETER4 = 0x0006, - D3D12_MESSAGE_ID_CORRUPTED_PARAMETER5 = 0x0007, - D3D12_MESSAGE_ID_CORRUPTED_PARAMETER6 = 0x0008, - D3D12_MESSAGE_ID_CORRUPTED_PARAMETER7 = 0x0009, - D3D12_MESSAGE_ID_CORRUPTED_PARAMETER8 = 0x000a, - D3D12_MESSAGE_ID_CORRUPTED_PARAMETER9 = 0x000b, - D3D12_MESSAGE_ID_CORRUPTED_PARAMETER10 = 0x000c, - D3D12_MESSAGE_ID_CORRUPTED_PARAMETER11 = 0x000d, - D3D12_MESSAGE_ID_CORRUPTED_PARAMETER12 = 0x000e, - D3D12_MESSAGE_ID_CORRUPTED_PARAMETER13 = 0x000f, - D3D12_MESSAGE_ID_CORRUPTED_PARAMETER14 = 0x0010, - D3D12_MESSAGE_ID_CORRUPTED_PARAMETER15 = 0x0011, - D3D12_MESSAGE_ID_CORRUPTED_MULTITHREADING = 0x0012, - D3D12_MESSAGE_ID_MESSAGE_REPORTING_OUTOFMEMORY = 0x0013, - D3D12_MESSAGE_ID_GETPRIVATEDATA_MOREDATA = 0x0014, - D3D12_MESSAGE_ID_SETPRIVATEDATA_INVALIDFREEDATA = 0x0015, - D3D12_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS = 0x0018, - D3D12_MESSAGE_ID_SETPRIVATEDATA_OUTOFMEMORY = 0x0019, - D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_UNRECOGNIZEDFORMAT = 0x001a, - D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDDESC = 0x001b, - D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDFORMAT = 0x001c, - D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDVIDEOPLANESLICE = 0x001d, - D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDPLANESLICE = 0x001e, - D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDDIMENSIONS = 0x001f, - D3D12_MESSAGE_ID_CREATESHADERRESOURCEVIEW_INVALIDRESOURCE = 0x0020, - D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_UNRECOGNIZEDFORMAT = 0x0023, - D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_UNSUPPORTEDFORMAT = 0x0024, - D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDDESC = 0x0025, - D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDFORMAT = 0x0026, - D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDVIDEOPLANESLICE = 0x0027, - D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDPLANESLICE = 0x0028, - D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDDIMENSIONS = 0x0029, - D3D12_MESSAGE_ID_CREATERENDERTARGETVIEW_INVALIDRESOURCE = 0x002a, - D3D12_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_UNRECOGNIZEDFORMAT = 0x002d, - D3D12_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDDESC = 0x002e, - D3D12_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDFORMAT = 0x002f, - D3D12_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDDIMENSIONS = 0x0030, - D3D12_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDRESOURCE = 0x0031, - D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_OUTOFMEMORY = 0x0034, - D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_TOOMANYELEMENTS = 0x0035, - D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDFORMAT = 0x0036, - D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_INCOMPATIBLEFORMAT = 0x0037, - D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDSLOT = 0x0038, - D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDINPUTSLOTCLASS = 0x0039, - D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_STEPRATESLOTCLASSMISMATCH = 0x003a, - D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDSLOTCLASSCHANGE = 0x003b, - D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDSTEPRATECHANGE = 0x003c, - D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_INVALIDALIGNMENT = 0x003d, - D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_DUPLICATESEMANTIC = 0x003e, - D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_UNPARSEABLEINPUTSIGNATURE = 0x003f, - D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_NULLSEMANTIC = 0x0040, - D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_MISSINGELEMENT = 0x0041, - D3D12_MESSAGE_ID_CREATEVERTEXSHADER_OUTOFMEMORY = 0x0042, - D3D12_MESSAGE_ID_CREATEVERTEXSHADER_INVALIDSHADERBYTECODE = 0x0043, - D3D12_MESSAGE_ID_CREATEVERTEXSHADER_INVALIDSHADERTYPE = 0x0044, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADER_OUTOFMEMORY = 0x0045, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADER_INVALIDSHADERBYTECODE = 0x0046, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADER_INVALIDSHADERTYPE = 0x0047, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTOFMEMORY = 0x0048, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSHADERBYTECODE = 0x0049, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSHADERTYPE = 0x004a, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDNUMENTRIES = 0x004b, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTPUTSTREAMSTRIDEUNUSED = 0x004c, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_OUTPUTSLOT0EXPECTED = 0x004f, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDOUTPUTSLOT = 0x0050, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_ONLYONEELEMENTPERSLOT = 0x0051, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDCOMPONENTCOUNT = 0x0052, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSTARTCOMPONENTANDCOMPONENTCOUNT = 0x0053, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDGAPDEFINITION = 0x0054, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_REPEATEDOUTPUT = 0x0055, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDOUTPUTSTREAMSTRIDE = 0x0056, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MISSINGSEMANTIC = 0x0057, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MASKMISMATCH = 0x0058, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_CANTHAVEONLYGAPS = 0x0059, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_DECLTOOCOMPLEX = 0x005a, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_MISSINGOUTPUTSIGNATURE = 0x005b, - D3D12_MESSAGE_ID_CREATEPIXELSHADER_OUTOFMEMORY = 0x005c, - D3D12_MESSAGE_ID_CREATEPIXELSHADER_INVALIDSHADERBYTECODE = 0x005d, - D3D12_MESSAGE_ID_CREATEPIXELSHADER_INVALIDSHADERTYPE = 0x005e, - D3D12_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDFILLMODE = 0x005f, - D3D12_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDCULLMODE = 0x0060, - D3D12_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDDEPTHBIASCLAMP = 0x0061, - D3D12_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDSLOPESCALEDDEPTHBIAS = 0x0062, - D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDDEPTHWRITEMASK = 0x0064, - D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDDEPTHFUNC = 0x0065, - D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILFAILOP = 0x0066, - D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILZFAILOP = 0x0067, - D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILPASSOP = 0x0068, - D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDFRONTFACESTENCILFUNC = 0x0069, - D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILFAILOP = 0x006a, - D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILZFAILOP = 0x006b, - D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILPASSOP = 0x006c, - D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_INVALIDBACKFACESTENCILFUNC = 0x006d, - D3D12_MESSAGE_ID_CREATEBLENDSTATE_INVALIDSRCBLEND = 0x006f, - D3D12_MESSAGE_ID_CREATEBLENDSTATE_INVALIDDESTBLEND = 0x0070, - D3D12_MESSAGE_ID_CREATEBLENDSTATE_INVALIDBLENDOP = 0x0071, - D3D12_MESSAGE_ID_CREATEBLENDSTATE_INVALIDSRCBLENDALPHA = 0x0072, - D3D12_MESSAGE_ID_CREATEBLENDSTATE_INVALIDDESTBLENDALPHA = 0x0073, - D3D12_MESSAGE_ID_CREATEBLENDSTATE_INVALIDBLENDOPALPHA = 0x0074, - D3D12_MESSAGE_ID_CREATEBLENDSTATE_INVALIDRENDERTARGETWRITEMASK = 0x0075, - D3D12_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_INVALID = 0x0087, - D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_ROOT_SIGNATURE_NOT_SET = 0x00c8, - D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_ROOT_SIGNATURE_MISMATCH = 0x00c9, - D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_VERTEX_BUFFER_NOT_SET = 0x00ca, - D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_VERTEX_BUFFER_STRIDE_TOO_SMALL = 0x00d1, - D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_VERTEX_BUFFER_TOO_SMALL = 0x00d2, - D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_INDEX_BUFFER_NOT_SET = 0x00d3, - D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_INDEX_BUFFER_FORMAT_INVALID = 0x00d4, - D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_INDEX_BUFFER_TOO_SMALL = 0x00d5, - D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_INVALID_PRIMITIVETOPOLOGY = 0x00db, - D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_VERTEX_STRIDE_UNALIGNED = 0x00dd, - D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_INDEX_OFFSET_UNALIGNED = 0x00de, - D3D12_MESSAGE_ID_DEVICE_REMOVAL_PROCESS_AT_FAULT = 0x00e8, - D3D12_MESSAGE_ID_DEVICE_REMOVAL_PROCESS_POSSIBLY_AT_FAULT = 0x00e9, - D3D12_MESSAGE_ID_DEVICE_REMOVAL_PROCESS_NOT_AT_FAULT = 0x00ea, - D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_TRAILING_DIGIT_IN_SEMANTIC = 0x00ef, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_TRAILING_DIGIT_IN_SEMANTIC = 0x00f0, - D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_TYPE_MISMATCH = 0x00f5, - D3D12_MESSAGE_ID_CREATEINPUTLAYOUT_EMPTY_LAYOUT = 0x00fd, - D3D12_MESSAGE_ID_LIVE_OBJECT_SUMMARY = 0x00ff, - D3D12_MESSAGE_ID_LIVE_DEVICE = 0x0112, - D3D12_MESSAGE_ID_LIVE_SWAPCHAIN = 0x0113, - D3D12_MESSAGE_ID_CREATEDEPTHSTENCILVIEW_INVALIDFLAGS = 0x0114, - D3D12_MESSAGE_ID_CREATEVERTEXSHADER_INVALIDCLASSLINKAGE = 0x0115, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADER_INVALIDCLASSLINKAGE = 0x0116, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSTREAMTORASTERIZER = 0x0118, - D3D12_MESSAGE_ID_CREATEPIXELSHADER_INVALIDCLASSLINKAGE = 0x011b, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDSTREAM = 0x011c, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UNEXPECTEDENTRIES = 0x011d, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UNEXPECTEDSTRIDES = 0x011e, - D3D12_MESSAGE_ID_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_INVALIDNUMSTRIDES = 0x011f, - D3D12_MESSAGE_ID_CREATEHULLSHADER_OUTOFMEMORY = 0x0121, - D3D12_MESSAGE_ID_CREATEHULLSHADER_INVALIDSHADERBYTECODE = 0x0122, - D3D12_MESSAGE_ID_CREATEHULLSHADER_INVALIDSHADERTYPE = 0x0123, - D3D12_MESSAGE_ID_CREATEHULLSHADER_INVALIDCLASSLINKAGE = 0x0124, - D3D12_MESSAGE_ID_CREATEDOMAINSHADER_OUTOFMEMORY = 0x0126, - D3D12_MESSAGE_ID_CREATEDOMAINSHADER_INVALIDSHADERBYTECODE = 0x0127, - D3D12_MESSAGE_ID_CREATEDOMAINSHADER_INVALIDSHADERTYPE = 0x0128, - D3D12_MESSAGE_ID_CREATEDOMAINSHADER_INVALIDCLASSLINKAGE = 0x0129, - D3D12_MESSAGE_ID_RESOURCE_UNMAP_NOTMAPPED = 0x0136, - D3D12_MESSAGE_ID_DEVICE_CHECKFEATURESUPPORT_MISMATCHED_DATA_SIZE = 0x013e, - D3D12_MESSAGE_ID_CREATECOMPUTESHADER_OUTOFMEMORY = 0x0141, - D3D12_MESSAGE_ID_CREATECOMPUTESHADER_INVALIDSHADERBYTECODE = 0x0142, - D3D12_MESSAGE_ID_CREATECOMPUTESHADER_INVALIDCLASSLINKAGE = 0x0143, - D3D12_MESSAGE_ID_DEVICE_CREATEVERTEXSHADER_DOUBLEFLOATOPSNOTSUPPORTED = 0x014b, - D3D12_MESSAGE_ID_DEVICE_CREATEHULLSHADER_DOUBLEFLOATOPSNOTSUPPORTED = 0x014c, - D3D12_MESSAGE_ID_DEVICE_CREATEDOMAINSHADER_DOUBLEFLOATOPSNOTSUPPORTED = 0x014d, - D3D12_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADER_DOUBLEFLOATOPSNOTSUPPORTED = 0x014e, - D3D12_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_DOUBLEFLOATOPSNOTSUPPORTED = 0x014f, - D3D12_MESSAGE_ID_DEVICE_CREATEPIXELSHADER_DOUBLEFLOATOPSNOTSUPPORTED = 0x0150, - D3D12_MESSAGE_ID_DEVICE_CREATECOMPUTESHADER_DOUBLEFLOATOPSNOTSUPPORTED = 0x0151, - D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDRESOURCE = 0x0154, - D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDDESC = 0x0155, - D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDFORMAT = 0x0156, - D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDVIDEOPLANESLICE = 0x0157, - D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDPLANESLICE = 0x0158, - D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDDIMENSIONS = 0x0159, - D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_UNRECOGNIZEDFORMAT = 0x015a, - D3D12_MESSAGE_ID_CREATEUNORDEREDACCESSVIEW_INVALIDFLAGS = 0x0162, - D3D12_MESSAGE_ID_CREATERASTERIZERSTATE_INVALIDFORCEDSAMPLECOUNT = 0x0191, - D3D12_MESSAGE_ID_CREATEBLENDSTATE_INVALIDLOGICOPS = 0x0193, - D3D12_MESSAGE_ID_DEVICE_CREATEVERTEXSHADER_DOUBLEEXTENSIONSNOTSUPPORTED = 0x019a, - D3D12_MESSAGE_ID_DEVICE_CREATEHULLSHADER_DOUBLEEXTENSIONSNOTSUPPORTED = 0x019c, - D3D12_MESSAGE_ID_DEVICE_CREATEDOMAINSHADER_DOUBLEEXTENSIONSNOTSUPPORTED = 0x019e, - D3D12_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADER_DOUBLEEXTENSIONSNOTSUPPORTED = 0x01a0, - D3D12_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_DOUBLEEXTENSIONSNOTSUPPORTED = 0x01a2, - D3D12_MESSAGE_ID_DEVICE_CREATEPIXELSHADER_DOUBLEEXTENSIONSNOTSUPPORTED = 0x01a4, - D3D12_MESSAGE_ID_DEVICE_CREATECOMPUTESHADER_DOUBLEEXTENSIONSNOTSUPPORTED = 0x01a6, - D3D12_MESSAGE_ID_DEVICE_CREATEVERTEXSHADER_UAVSNOTSUPPORTED = 0x01a9, - D3D12_MESSAGE_ID_DEVICE_CREATEHULLSHADER_UAVSNOTSUPPORTED = 0x01aa, - D3D12_MESSAGE_ID_DEVICE_CREATEDOMAINSHADER_UAVSNOTSUPPORTED = 0x01ab, - D3D12_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADER_UAVSNOTSUPPORTED = 0x01ac, - D3D12_MESSAGE_ID_DEVICE_CREATEGEOMETRYSHADERWITHSTREAMOUTPUT_UAVSNOTSUPPORTED = 0x01ad, - D3D12_MESSAGE_ID_DEVICE_CREATEPIXELSHADER_UAVSNOTSUPPORTED = 0x01ae, - D3D12_MESSAGE_ID_DEVICE_CREATECOMPUTESHADER_UAVSNOTSUPPORTED = 0x01af, - D3D12_MESSAGE_ID_DEVICE_CLEARVIEW_INVALIDSOURCERECT = 0x01bf, - D3D12_MESSAGE_ID_DEVICE_CLEARVIEW_EMPTYRECT = 0x01c0, - D3D12_MESSAGE_ID_UPDATETILEMAPPINGS_INVALID_PARAMETER = 0x01ed, - D3D12_MESSAGE_ID_COPYTILEMAPPINGS_INVALID_PARAMETER = 0x01ee, - D3D12_MESSAGE_ID_CREATEDEVICE_INVALIDARGS = 0x01fa, - D3D12_MESSAGE_ID_CREATEDEVICE_WARNING = 0x01fb, - D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_TYPE = 0x0207, - D3D12_MESSAGE_ID_RESOURCE_BARRIER_NULL_POINTER = 0x0208, - D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_SUBRESOURCE = 0x0209, - D3D12_MESSAGE_ID_RESOURCE_BARRIER_RESERVED_BITS = 0x020a, - D3D12_MESSAGE_ID_RESOURCE_BARRIER_MISSING_BIND_FLAGS = 0x020b, - D3D12_MESSAGE_ID_RESOURCE_BARRIER_MISMATCHING_MISC_FLAGS = 0x020c, - D3D12_MESSAGE_ID_RESOURCE_BARRIER_MATCHING_STATES = 0x020d, - D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_COMBINATION = 0x020e, - D3D12_MESSAGE_ID_RESOURCE_BARRIER_BEFORE_AFTER_MISMATCH = 0x020f, - D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_RESOURCE = 0x0210, - D3D12_MESSAGE_ID_RESOURCE_BARRIER_SAMPLE_COUNT = 0x0211, - D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_FLAGS = 0x0212, - D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_COMBINED_FLAGS = 0x0213, - D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_FLAGS_FOR_FORMAT = 0x0214, - D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_SPLIT_BARRIER = 0x0215, - D3D12_MESSAGE_ID_RESOURCE_BARRIER_UNMATCHED_END = 0x0216, - D3D12_MESSAGE_ID_RESOURCE_BARRIER_UNMATCHED_BEGIN = 0x0217, - D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_FLAG = 0x0218, - D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_COMMAND_LIST_TYPE = 0x0219, - D3D12_MESSAGE_ID_INVALID_SUBRESOURCE_STATE = 0x021a, - D3D12_MESSAGE_ID_COMMAND_ALLOCATOR_CONTENTION = 0x021c, - D3D12_MESSAGE_ID_COMMAND_ALLOCATOR_RESET = 0x021d, - D3D12_MESSAGE_ID_COMMAND_ALLOCATOR_RESET_BUNDLE = 0x021e, - D3D12_MESSAGE_ID_COMMAND_ALLOCATOR_CANNOT_RESET = 0x021f, - D3D12_MESSAGE_ID_COMMAND_LIST_OPEN = 0x0220, - D3D12_MESSAGE_ID_INVALID_BUNDLE_API = 0x0222, - D3D12_MESSAGE_ID_COMMAND_LIST_CLOSED = 0x0223, - D3D12_MESSAGE_ID_WRONG_COMMAND_ALLOCATOR_TYPE = 0x0225, - D3D12_MESSAGE_ID_COMMAND_ALLOCATOR_SYNC = 0x0228, - D3D12_MESSAGE_ID_COMMAND_LIST_SYNC = 0x0229, - D3D12_MESSAGE_ID_SET_DESCRIPTOR_HEAP_INVALID = 0x022a, - D3D12_MESSAGE_ID_CREATE_COMMANDQUEUE = 0x022d, - D3D12_MESSAGE_ID_CREATE_COMMANDALLOCATOR = 0x022e, - D3D12_MESSAGE_ID_CREATE_PIPELINESTATE = 0x022f, - D3D12_MESSAGE_ID_CREATE_COMMANDLIST12 = 0x0230, - D3D12_MESSAGE_ID_CREATE_RESOURCE = 0x0232, - D3D12_MESSAGE_ID_CREATE_DESCRIPTORHEAP = 0x0233, - D3D12_MESSAGE_ID_CREATE_ROOTSIGNATURE = 0x0234, - D3D12_MESSAGE_ID_CREATE_LIBRARY = 0x0235, - D3D12_MESSAGE_ID_CREATE_HEAP = 0x0236, - D3D12_MESSAGE_ID_CREATE_MONITOREDFENCE = 0x0237, - D3D12_MESSAGE_ID_CREATE_QUERYHEAP = 0x0238, - D3D12_MESSAGE_ID_CREATE_COMMANDSIGNATURE = 0x0239, - D3D12_MESSAGE_ID_LIVE_COMMANDQUEUE = 0x023a, - D3D12_MESSAGE_ID_LIVE_COMMANDALLOCATOR = 0x023b, - D3D12_MESSAGE_ID_LIVE_PIPELINESTATE = 0x023c, - D3D12_MESSAGE_ID_LIVE_COMMANDLIST12 = 0x023d, - D3D12_MESSAGE_ID_LIVE_RESOURCE = 0x023f, - D3D12_MESSAGE_ID_LIVE_DESCRIPTORHEAP = 0x0240, - D3D12_MESSAGE_ID_LIVE_ROOTSIGNATURE = 0x0241, - D3D12_MESSAGE_ID_LIVE_LIBRARY = 0x0242, - D3D12_MESSAGE_ID_LIVE_HEAP = 0x0243, - D3D12_MESSAGE_ID_LIVE_MONITOREDFENCE = 0x0244, - D3D12_MESSAGE_ID_LIVE_QUERYHEAP = 0x0245, - D3D12_MESSAGE_ID_LIVE_COMMANDSIGNATURE = 0x0246, - D3D12_MESSAGE_ID_DESTROY_COMMANDQUEUE = 0x0247, - D3D12_MESSAGE_ID_DESTROY_COMMANDALLOCATOR = 0x0248, - D3D12_MESSAGE_ID_DESTROY_PIPELINESTATE = 0x0249, - D3D12_MESSAGE_ID_DESTROY_COMMANDLIST12 = 0x024a, - D3D12_MESSAGE_ID_DESTROY_RESOURCE = 0x024c, - D3D12_MESSAGE_ID_DESTROY_DESCRIPTORHEAP = 0x024d, - D3D12_MESSAGE_ID_DESTROY_ROOTSIGNATURE = 0x024e, - D3D12_MESSAGE_ID_DESTROY_LIBRARY = 0x024f, - D3D12_MESSAGE_ID_DESTROY_HEAP = 0x0250, - D3D12_MESSAGE_ID_DESTROY_MONITOREDFENCE = 0x0251, - D3D12_MESSAGE_ID_DESTROY_QUERYHEAP = 0x0252, - D3D12_MESSAGE_ID_DESTROY_COMMANDSIGNATURE = 0x0253, - D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDDIMENSIONS = 0x0255, - D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDMISCFLAGS = 0x0257, - D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDARG_RETURN = 0x025a, - D3D12_MESSAGE_ID_CREATERESOURCE_OUTOFMEMORY_RETURN = 0x025b, - D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDDESC = 0x025c, - D3D12_MESSAGE_ID_POSSIBLY_INVALID_SUBRESOURCE_STATE = 0x025f, - D3D12_MESSAGE_ID_INVALID_USE_OF_NON_RESIDENT_RESOURCE = 0x0260, - D3D12_MESSAGE_ID_POSSIBLE_INVALID_USE_OF_NON_RESIDENT_RESOURCE = 0x0261, - D3D12_MESSAGE_ID_BUNDLE_PIPELINE_STATE_MISMATCH = 0x0262, - D3D12_MESSAGE_ID_PRIMITIVE_TOPOLOGY_MISMATCH_PIPELINE_STATE = 0x0263, - D3D12_MESSAGE_ID_RENDER_TARGET_FORMAT_MISMATCH_PIPELINE_STATE = 0x0265, - D3D12_MESSAGE_ID_RENDER_TARGET_SAMPLE_DESC_MISMATCH_PIPELINE_STATE = 0x0266, - D3D12_MESSAGE_ID_DEPTH_STENCIL_FORMAT_MISMATCH_PIPELINE_STATE = 0x0267, - D3D12_MESSAGE_ID_DEPTH_STENCIL_SAMPLE_DESC_MISMATCH_PIPELINE_STATE = 0x0268, - D3D12_MESSAGE_ID_CREATESHADER_INVALIDBYTECODE = 0x026e, - D3D12_MESSAGE_ID_CREATEHEAP_NULLDESC = 0x026f, - D3D12_MESSAGE_ID_CREATEHEAP_INVALIDSIZE = 0x0270, - D3D12_MESSAGE_ID_CREATEHEAP_UNRECOGNIZEDHEAPTYPE = 0x0271, - D3D12_MESSAGE_ID_CREATEHEAP_UNRECOGNIZEDCPUPAGEPROPERTIES = 0x0272, - D3D12_MESSAGE_ID_CREATEHEAP_UNRECOGNIZEDMEMORYPOOL = 0x0273, - D3D12_MESSAGE_ID_CREATEHEAP_INVALIDPROPERTIES = 0x0274, - D3D12_MESSAGE_ID_CREATEHEAP_INVALIDALIGNMENT = 0x0275, - D3D12_MESSAGE_ID_CREATEHEAP_UNRECOGNIZEDMISCFLAGS = 0x0276, - D3D12_MESSAGE_ID_CREATEHEAP_INVALIDMISCFLAGS = 0x0277, - D3D12_MESSAGE_ID_CREATEHEAP_INVALIDARG_RETURN = 0x0278, - D3D12_MESSAGE_ID_CREATEHEAP_OUTOFMEMORY_RETURN = 0x0279, - D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_NULLHEAPPROPERTIES = 0x027a, - D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_UNRECOGNIZEDHEAPTYPE = 0x027b, - D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_UNRECOGNIZEDCPUPAGEPROPERTIES = 0x027c, - D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_UNRECOGNIZEDMEMORYPOOL = 0x027d, - D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_INVALIDHEAPPROPERTIES = 0x027e, - D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_UNRECOGNIZEDHEAPMISCFLAGS = 0x027f, - D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_INVALIDHEAPMISCFLAGS = 0x0280, - D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_INVALIDARG_RETURN = 0x0281, - D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_OUTOFMEMORY_RETURN = 0x0282, - D3D12_MESSAGE_ID_GETCUSTOMHEAPPROPERTIES_UNRECOGNIZEDHEAPTYPE = 0x0283, - D3D12_MESSAGE_ID_GETCUSTOMHEAPPROPERTIES_INVALIDHEAPTYPE = 0x0284, - D3D12_MESSAGE_ID_CREATE_DESCRIPTOR_HEAP_INVALID_DESC = 0x0285, - D3D12_MESSAGE_ID_INVALID_DESCRIPTOR_HANDLE = 0x0286, - D3D12_MESSAGE_ID_CREATERASTERIZERSTATE_INVALID_CONSERVATIVERASTERMODE = 0x0287, - D3D12_MESSAGE_ID_CREATE_CONSTANT_BUFFER_VIEW_INVALID_RESOURCE = 0x0289, - D3D12_MESSAGE_ID_CREATE_CONSTANT_BUFFER_VIEW_INVALID_DESC = 0x028a, - D3D12_MESSAGE_ID_CREATE_UNORDEREDACCESS_VIEW_INVALID_COUNTER_USAGE = 0x028c, - D3D12_MESSAGE_ID_COPY_DESCRIPTORS_INVALID_RANGES = 0x028d, - D3D12_MESSAGE_ID_COPY_DESCRIPTORS_WRITE_ONLY_DESCRIPTOR = 0x028e, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_RTV_FORMAT_NOT_UNKNOWN = 0x028f, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_INVALID_RENDER_TARGET_COUNT = 0x0290, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_VERTEX_SHADER_NOT_SET = 0x0291, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_INPUTLAYOUT_NOT_SET = 0x0292, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_HS_DS_SIGNATURE_MISMATCH = 0x0293, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_REGISTERINDEX = 0x0294, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_COMPONENTTYPE = 0x0295, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_REGISTERMASK = 0x0296, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_SYSTEMVALUE = 0x0297, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_NEVERWRITTEN_ALWAYSREADS = 0x0298, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_MINPRECISION = 0x0299, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_SHADER_LINKAGE_SEMANTICNAME_NOT_FOUND = 0x029a, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_HS_XOR_DS_MISMATCH = 0x029b, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_HULL_SHADER_INPUT_TOPOLOGY_MISMATCH = 0x029c, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_HS_DS_CONTROL_POINT_COUNT_MISMATCH = 0x029d, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_HS_DS_TESSELLATOR_DOMAIN_MISMATCH = 0x029e, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_INVALID_USE_OF_CENTER_MULTISAMPLE_PATTERN = 0x029f, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_INVALID_USE_OF_FORCED_SAMPLE_COUNT = 0x02a0, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_INVALID_PRIMITIVETOPOLOGY = 0x02a1, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_INVALID_SYSTEMVALUE = 0x02a2, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_OM_DUAL_SOURCE_BLENDING_CAN_ONLY_HAVE_RENDER_TARGET_0 = 0x02a3, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_OM_RENDER_TARGET_DOES_NOT_SUPPORT_BLENDING = 0x02a4, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_PS_OUTPUT_TYPE_MISMATCH = 0x02a5, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_OM_RENDER_TARGET_DOES_NOT_SUPPORT_LOGIC_OPS = 0x02a6, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_RENDERTARGETVIEW_NOT_SET = 0x02a7, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_DEPTHSTENCILVIEW_NOT_SET = 0x02a8, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_GS_INPUT_PRIMITIVE_MISMATCH = 0x02a9, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_POSITION_NOT_PRESENT = 0x02aa, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_MISSING_ROOT_SIGNATURE_FLAGS = 0x02ab, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_INVALID_INDEX_BUFFER_PROPERTIES = 0x02ac, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_INVALID_SAMPLE_DESC = 0x02ad, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_HS_ROOT_SIGNATURE_MISMATCH = 0x02ae, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_DS_ROOT_SIGNATURE_MISMATCH = 0x02af, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_VS_ROOT_SIGNATURE_MISMATCH = 0x02b0, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_GS_ROOT_SIGNATURE_MISMATCH = 0x02b1, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_PS_ROOT_SIGNATURE_MISMATCH = 0x02b2, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_MISSING_ROOT_SIGNATURE = 0x02b3, - D3D12_MESSAGE_ID_EXECUTE_BUNDLE_OPEN_BUNDLE = 0x02b4, - D3D12_MESSAGE_ID_EXECUTE_BUNDLE_DESCRIPTOR_HEAP_MISMATCH = 0x02b5, - D3D12_MESSAGE_ID_EXECUTE_BUNDLE_TYPE = 0x02b6, - D3D12_MESSAGE_ID_DRAW_EMPTY_SCISSOR_RECTANGLE = 0x02b7, - D3D12_MESSAGE_ID_CREATE_ROOT_SIGNATURE_BLOB_NOT_FOUND = 0x02b8, - D3D12_MESSAGE_ID_CREATE_ROOT_SIGNATURE_DESERIALIZE_FAILED = 0x02b9, - D3D12_MESSAGE_ID_CREATE_ROOT_SIGNATURE_INVALID_CONFIGURATION = 0x02ba, - D3D12_MESSAGE_ID_CREATE_ROOT_SIGNATURE_NOT_SUPPORTED_ON_DEVICE = 0x02bb, - D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_NULLRESOURCEPROPERTIES = 0x02bc, - D3D12_MESSAGE_ID_CREATERESOURCEANDHEAP_NULLHEAP = 0x02bd, - D3D12_MESSAGE_ID_GETRESOURCEALLOCATIONINFO_INVALIDRDESCS = 0x02be, - D3D12_MESSAGE_ID_MAKERESIDENT_NULLOBJECTARRAY = 0x02bf, - D3D12_MESSAGE_ID_EVICT_NULLOBJECTARRAY = 0x02c1, - D3D12_MESSAGE_ID_SET_DESCRIPTOR_TABLE_INVALID = 0x02c4, - D3D12_MESSAGE_ID_SET_ROOT_CONSTANT_INVALID = 0x02c5, - D3D12_MESSAGE_ID_SET_ROOT_CONSTANT_BUFFER_VIEW_INVALID = 0x02c6, - D3D12_MESSAGE_ID_SET_ROOT_SHADER_RESOURCE_VIEW_INVALID = 0x02c7, - D3D12_MESSAGE_ID_SET_ROOT_UNORDERED_ACCESS_VIEW_INVALID = 0x02c8, - D3D12_MESSAGE_ID_SET_VERTEX_BUFFERS_INVALID_DESC = 0x02c9, - D3D12_MESSAGE_ID_SET_INDEX_BUFFER_INVALID_DESC = 0x02cb, - D3D12_MESSAGE_ID_SET_STREAM_OUTPUT_BUFFERS_INVALID_DESC = 0x02cd, - D3D12_MESSAGE_ID_CREATERESOURCE_UNRECOGNIZEDDIMENSIONALITY = 0x02ce, - D3D12_MESSAGE_ID_CREATERESOURCE_UNRECOGNIZEDLAYOUT = 0x02cf, - D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDDIMENSIONALITY = 0x02d0, - D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDALIGNMENT = 0x02d1, - D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDMIPLEVELS = 0x02d2, - D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDSAMPLEDESC = 0x02d3, - D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDLAYOUT = 0x02d4, - D3D12_MESSAGE_ID_SET_INDEX_BUFFER_INVALID = 0x02d5, - D3D12_MESSAGE_ID_SET_VERTEX_BUFFERS_INVALID = 0x02d6, - D3D12_MESSAGE_ID_SET_STREAM_OUTPUT_BUFFERS_INVALID = 0x02d7, - D3D12_MESSAGE_ID_SET_RENDER_TARGETS_INVALID = 0x02d8, - D3D12_MESSAGE_ID_CREATEQUERY_HEAP_INVALID_PARAMETERS = 0x02d9, - D3D12_MESSAGE_ID_BEGIN_END_QUERY_INVALID_PARAMETERS = 0x02db, - D3D12_MESSAGE_ID_CLOSE_COMMAND_LIST_OPEN_QUERY = 0x02dc, - D3D12_MESSAGE_ID_RESOLVE_QUERY_DATA_INVALID_PARAMETERS = 0x02dd, - D3D12_MESSAGE_ID_SET_PREDICATION_INVALID_PARAMETERS = 0x02de, - D3D12_MESSAGE_ID_TIMESTAMPS_NOT_SUPPORTED = 0x02df, - D3D12_MESSAGE_ID_CREATERESOURCE_UNRECOGNIZEDFORMAT = 0x02e1, - D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDFORMAT = 0x02e2, - D3D12_MESSAGE_ID_GETCOPYABLEFOOTPRINTS_INVALIDSUBRESOURCERANGE = 0x02e3, - D3D12_MESSAGE_ID_GETCOPYABLEFOOTPRINTS_INVALIDBASEOFFSET = 0x02e4, - D3D12_MESSAGE_ID_GETCOPYABLELAYOUT_INVALIDSUBRESOURCERANGE = 0x02e3, - D3D12_MESSAGE_ID_GETCOPYABLELAYOUT_INVALIDBASEOFFSET = 0x02e4, - D3D12_MESSAGE_ID_RESOURCE_BARRIER_INVALID_HEAP = 0x02e5, - D3D12_MESSAGE_ID_CREATE_SAMPLER_INVALID = 0x02e6, - D3D12_MESSAGE_ID_CREATECOMMANDSIGNATURE_INVALID = 0x02e7, - D3D12_MESSAGE_ID_EXECUTE_INDIRECT_INVALID_PARAMETERS = 0x02e8, - D3D12_MESSAGE_ID_GETGPUVIRTUALADDRESS_INVALID_RESOURCE_DIMENSION = 0x02e9, - D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDCLEARVALUE = 0x032f, - D3D12_MESSAGE_ID_CREATERESOURCE_UNRECOGNIZEDCLEARVALUEFORMAT = 0x0330, - D3D12_MESSAGE_ID_CREATERESOURCE_INVALIDCLEARVALUEFORMAT = 0x0331, - D3D12_MESSAGE_ID_CREATERESOURCE_CLEARVALUEDENORMFLUSH = 0x0332, - D3D12_MESSAGE_ID_CLEARRENDERTARGETVIEW_MISMATCHINGCLEARVALUE = 0x0334, - D3D12_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_MISMATCHINGCLEARVALUE = 0x0335, - D3D12_MESSAGE_ID_MAP_INVALIDHEAP = 0x0336, - D3D12_MESSAGE_ID_UNMAP_INVALIDHEAP = 0x0337, - D3D12_MESSAGE_ID_MAP_INVALIDRESOURCE = 0x0338, - D3D12_MESSAGE_ID_UNMAP_INVALIDRESOURCE = 0x0339, - D3D12_MESSAGE_ID_MAP_INVALIDSUBRESOURCE = 0x033a, - D3D12_MESSAGE_ID_UNMAP_INVALIDSUBRESOURCE = 0x033b, - D3D12_MESSAGE_ID_MAP_INVALIDRANGE = 0x033c, - D3D12_MESSAGE_ID_UNMAP_INVALIDRANGE = 0x033d, - D3D12_MESSAGE_ID_MAP_INVALIDDATAPOINTER = 0x0340, - D3D12_MESSAGE_ID_MAP_INVALIDARG_RETURN = 0x0341, - D3D12_MESSAGE_ID_MAP_OUTOFMEMORY_RETURN = 0x0342, - D3D12_MESSAGE_ID_EXECUTECOMMANDLISTS_BUNDLENOTSUPPORTED = 0x0343, - D3D12_MESSAGE_ID_EXECUTECOMMANDLISTS_COMMANDLISTMISMATCH = 0x0344, - D3D12_MESSAGE_ID_EXECUTECOMMANDLISTS_OPENCOMMANDLIST = 0x0345, - D3D12_MESSAGE_ID_EXECUTECOMMANDLISTS_FAILEDCOMMANDLIST = 0x0346, - D3D12_MESSAGE_ID_COPYBUFFERREGION_NULLDST = 0x0347, - D3D12_MESSAGE_ID_COPYBUFFERREGION_INVALIDDSTRESOURCEDIMENSION = 0x0348, - D3D12_MESSAGE_ID_COPYBUFFERREGION_DSTRANGEOUTOFBOUNDS = 0x0349, - D3D12_MESSAGE_ID_COPYBUFFERREGION_NULLSRC = 0x034a, - D3D12_MESSAGE_ID_COPYBUFFERREGION_INVALIDSRCRESOURCEDIMENSION = 0x034b, - D3D12_MESSAGE_ID_COPYBUFFERREGION_SRCRANGEOUTOFBOUNDS = 0x034c, - D3D12_MESSAGE_ID_COPYBUFFERREGION_INVALIDCOPYFLAGS = 0x034d, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_NULLDST = 0x034e, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_UNRECOGNIZEDDSTTYPE = 0x034f, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTRESOURCEDIMENSION = 0x0350, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTRESOURCE = 0x0351, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTSUBRESOURCE = 0x0352, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTOFFSET = 0x0353, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_UNRECOGNIZEDDSTFORMAT = 0x0354, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTFORMAT = 0x0355, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTDIMENSIONS = 0x0356, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTROWPITCH = 0x0357, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTPLACEMENT = 0x0358, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTDSPLACEDFOOTPRINTFORMAT = 0x0359, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_DSTREGIONOUTOFBOUNDS = 0x035a, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_NULLSRC = 0x035b, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_UNRECOGNIZEDSRCTYPE = 0x035c, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCRESOURCEDIMENSION = 0x035d, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCRESOURCE = 0x035e, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCSUBRESOURCE = 0x035f, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCOFFSET = 0x0360, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_UNRECOGNIZEDSRCFORMAT = 0x0361, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCFORMAT = 0x0362, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCDIMENSIONS = 0x0363, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCROWPITCH = 0x0364, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCPLACEMENT = 0x0365, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCDSPLACEDFOOTPRINTFORMAT = 0x0366, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_SRCREGIONOUTOFBOUNDS = 0x0367, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDDSTCOORDINATES = 0x0368, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDSRCBOX = 0x0369, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_FORMATMISMATCH = 0x036a, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_EMPTYBOX = 0x036b, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_INVALIDCOPYFLAGS = 0x036c, - D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_INVALID_SUBRESOURCE_INDEX = 0x036d, - D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_INVALID_FORMAT = 0x036e, - D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_RESOURCE_MISMATCH = 0x036f, - D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_INVALID_SAMPLE_COUNT = 0x0370, - D3D12_MESSAGE_ID_CREATECOMPUTEPIPELINESTATE_INVALID_SHADER = 0x0371, - D3D12_MESSAGE_ID_CREATECOMPUTEPIPELINESTATE_CS_ROOT_SIGNATURE_MISMATCH = 0x0372, - D3D12_MESSAGE_ID_CREATECOMPUTEPIPELINESTATE_MISSING_ROOT_SIGNATURE = 0x0373, - D3D12_MESSAGE_ID_CREATEPIPELINESTATE_INVALIDCACHEDBLOB = 0x0374, - D3D12_MESSAGE_ID_CREATEPIPELINESTATE_CACHEDBLOBADAPTERMISMATCH = 0x0375, - D3D12_MESSAGE_ID_CREATEPIPELINESTATE_CACHEDBLOBDRIVERVERSIONMISMATCH = 0x0376, - D3D12_MESSAGE_ID_CREATEPIPELINESTATE_CACHEDBLOBDESCMISMATCH = 0x0377, - D3D12_MESSAGE_ID_CREATEPIPELINESTATE_CACHEDBLOBIGNORED = 0x0378, - D3D12_MESSAGE_ID_WRITETOSUBRESOURCE_INVALIDHEAP = 0x0379, - D3D12_MESSAGE_ID_WRITETOSUBRESOURCE_INVALIDRESOURCE = 0x037a, - D3D12_MESSAGE_ID_WRITETOSUBRESOURCE_INVALIDBOX = 0x037b, - D3D12_MESSAGE_ID_WRITETOSUBRESOURCE_INVALIDSUBRESOURCE = 0x037c, - D3D12_MESSAGE_ID_WRITETOSUBRESOURCE_EMPTYBOX = 0x037d, - D3D12_MESSAGE_ID_READFROMSUBRESOURCE_INVALIDHEAP = 0x037e, - D3D12_MESSAGE_ID_READFROMSUBRESOURCE_INVALIDRESOURCE = 0x037f, - D3D12_MESSAGE_ID_READFROMSUBRESOURCE_INVALIDBOX = 0x0380, - D3D12_MESSAGE_ID_READFROMSUBRESOURCE_INVALIDSUBRESOURCE = 0x0381, - D3D12_MESSAGE_ID_READFROMSUBRESOURCE_EMPTYBOX = 0x0382, - D3D12_MESSAGE_ID_TOO_MANY_NODES_SPECIFIED = 0x0383, - D3D12_MESSAGE_ID_INVALID_NODE_INDEX = 0x0384, - D3D12_MESSAGE_ID_GETHEAPPROPERTIES_INVALIDRESOURCE = 0x0385, - D3D12_MESSAGE_ID_NODE_MASK_MISMATCH = 0x0386, - D3D12_MESSAGE_ID_COMMAND_LIST_OUTOFMEMORY = 0x0387, - D3D12_MESSAGE_ID_COMMAND_LIST_MULTIPLE_SWAPCHAIN_BUFFER_REFERENCES = 0x0388, - D3D12_MESSAGE_ID_COMMAND_LIST_TOO_MANY_SWAPCHAIN_REFERENCES = 0x0389, - D3D12_MESSAGE_ID_COMMAND_QUEUE_TOO_MANY_SWAPCHAIN_REFERENCES = 0x038a, - D3D12_MESSAGE_ID_EXECUTECOMMANDLISTS_WRONGSWAPCHAINBUFFERREFERENCE = 0x038b, - D3D12_MESSAGE_ID_COMMAND_LIST_SETRENDERTARGETS_INVALIDNUMRENDERTARGETS = 0x038c, - D3D12_MESSAGE_ID_CREATE_QUEUE_INVALID_TYPE = 0x038d, - D3D12_MESSAGE_ID_CREATE_QUEUE_INVALID_FLAGS = 0x038e, - D3D12_MESSAGE_ID_CREATESHAREDRESOURCE_INVALIDFLAGS = 0x038f, - D3D12_MESSAGE_ID_CREATESHAREDRESOURCE_INVALIDFORMAT = 0x0390, - D3D12_MESSAGE_ID_CREATESHAREDHEAP_INVALIDFLAGS = 0x0391, - D3D12_MESSAGE_ID_REFLECTSHAREDPROPERTIES_UNRECOGNIZEDPROPERTIES = 0x0392, - D3D12_MESSAGE_ID_REFLECTSHAREDPROPERTIES_INVALIDSIZE = 0x0393, - D3D12_MESSAGE_ID_REFLECTSHAREDPROPERTIES_INVALIDOBJECT = 0x0394, - D3D12_MESSAGE_ID_KEYEDMUTEX_INVALIDOBJECT = 0x0395, - D3D12_MESSAGE_ID_KEYEDMUTEX_INVALIDKEY = 0x0396, - D3D12_MESSAGE_ID_KEYEDMUTEX_WRONGSTATE = 0x0397, - D3D12_MESSAGE_ID_CREATE_QUEUE_INVALID_PRIORITY = 0x0398, - D3D12_MESSAGE_ID_OBJECT_DELETED_WHILE_STILL_IN_USE = 0x0399, - D3D12_MESSAGE_ID_CREATEPIPELINESTATE_INVALID_FLAGS = 0x039a, - D3D12_MESSAGE_ID_HEAP_ADDRESS_RANGE_HAS_NO_RESOURCE = 0x039b, - D3D12_MESSAGE_ID_COMMAND_LIST_DRAW_RENDER_TARGET_DELETED = 0x039c, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_ALL_RENDER_TARGETS_HAVE_UNKNOWN_FORMAT = 0x039d, - D3D12_MESSAGE_ID_HEAP_ADDRESS_RANGE_INTERSECTS_MULTIPLE_BUFFERS = 0x039e, - D3D12_MESSAGE_ID_EXECUTECOMMANDLISTS_GPU_WRITTEN_READBACK_RESOURCE_MAPPED = 0x039f, - D3D12_MESSAGE_ID_UNMAP_RANGE_NOT_EMPTY = 0x03a1, - D3D12_MESSAGE_ID_MAP_INVALID_NULLRANGE = 0x03a2, - D3D12_MESSAGE_ID_UNMAP_INVALID_NULLRANGE = 0x03a3, - D3D12_MESSAGE_ID_NO_GRAPHICS_API_SUPPORT = 0x03a4, - D3D12_MESSAGE_ID_NO_COMPUTE_API_SUPPORT = 0x03a5, - D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_RESOURCE_FLAGS_NOT_SUPPORTED = 0x03a6, - D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_ROOT_ARGUMENT_UNINITIALIZED = 0x03a7, - D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_DESCRIPTOR_HEAP_INDEX_OUT_OF_BOUNDS = 0x03a8, - D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_DESCRIPTOR_TABLE_REGISTER_INDEX_OUT_OF_BOUNDS = 0x03a9, - D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_DESCRIPTOR_UNINITIALIZED = 0x03aa, - D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_DESCRIPTOR_TYPE_MISMATCH = 0x03ab, - D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_SRV_RESOURCE_DIMENSION_MISMATCH = 0x03ac, - D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_UAV_RESOURCE_DIMENSION_MISMATCH = 0x03ad, - D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_INCOMPATIBLE_RESOURCE_STATE = 0x03ae, - D3D12_MESSAGE_ID_COPYRESOURCE_NULLDST = 0x03af, - D3D12_MESSAGE_ID_COPYRESOURCE_INVALIDDSTRESOURCE = 0x03b0, - D3D12_MESSAGE_ID_COPYRESOURCE_NULLSRC = 0x03b1, - D3D12_MESSAGE_ID_COPYRESOURCE_INVALIDSRCRESOURCE = 0x03b2, - D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_NULLDST = 0x03b3, - D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_INVALIDDSTRESOURCE = 0x03b4, - D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_NULLSRC = 0x03b5, - D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_INVALIDSRCRESOURCE = 0x03b6, - D3D12_MESSAGE_ID_PIPELINE_STATE_TYPE_MISMATCH = 0x03b7, - D3D12_MESSAGE_ID_COMMAND_LIST_DISPATCH_ROOT_SIGNATURE_NOT_SET = 0x03b8, - D3D12_MESSAGE_ID_COMMAND_LIST_DISPATCH_ROOT_SIGNATURE_MISMATCH = 0x03b9, - D3D12_MESSAGE_ID_RESOURCE_BARRIER_ZERO_BARRIERS = 0x03ba, - D3D12_MESSAGE_ID_BEGIN_END_EVENT_MISMATCH = 0x03bb, - D3D12_MESSAGE_ID_RESOURCE_BARRIER_POSSIBLE_BEFORE_AFTER_MISMATCH = 0x03bc, - D3D12_MESSAGE_ID_RESOURCE_BARRIER_MISMATCHING_BEGIN_END = 0x03bd, - D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_INVALID_RESOURCE = 0x03be, - D3D12_MESSAGE_ID_USE_OF_ZERO_REFCOUNT_OBJECT = 0x03bf, - D3D12_MESSAGE_ID_OBJECT_EVICTED_WHILE_STILL_IN_USE = 0x03c0, - D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_ROOT_DESCRIPTOR_ACCESS_OUT_OF_BOUNDS = 0x03c1, - D3D12_MESSAGE_ID_CREATEPIPELINELIBRARY_INVALIDLIBRARYBLOB = 0x03c2, - D3D12_MESSAGE_ID_CREATEPIPELINELIBRARY_DRIVERVERSIONMISMATCH = 0x03c3, - D3D12_MESSAGE_ID_CREATEPIPELINELIBRARY_ADAPTERVERSIONMISMATCH = 0x03c4, - D3D12_MESSAGE_ID_CREATEPIPELINELIBRARY_UNSUPPORTED = 0x03c5, - D3D12_MESSAGE_ID_CREATE_PIPELINELIBRARY = 0x03c6, - D3D12_MESSAGE_ID_LIVE_PIPELINELIBRARY = 0x03c7, - D3D12_MESSAGE_ID_DESTROY_PIPELINELIBRARY = 0x03c8, - D3D12_MESSAGE_ID_STOREPIPELINE_NONAME = 0x03c9, - D3D12_MESSAGE_ID_STOREPIPELINE_DUPLICATENAME = 0x03ca, - D3D12_MESSAGE_ID_LOADPIPELINE_NAMENOTFOUND = 0x03cb, - D3D12_MESSAGE_ID_LOADPIPELINE_INVALIDDESC = 0x03cc, - D3D12_MESSAGE_ID_PIPELINELIBRARY_SERIALIZE_NOTENOUGHMEMORY = 0x03cd, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_PS_OUTPUT_RT_OUTPUT_MISMATCH = 0x03ce, - D3D12_MESSAGE_ID_SETEVENTONMULTIPLEFENCECOMPLETION_INVALIDFLAGS = 0x03cf, - D3D12_MESSAGE_ID_CREATE_QUEUE_VIDEO_NOT_SUPPORTED = 0x03d0, - D3D12_MESSAGE_ID_CREATE_COMMAND_ALLOCATOR_VIDEO_NOT_SUPPORTED = 0x03d1, - D3D12_MESSAGE_ID_CREATEQUERY_HEAP_VIDEO_DECODE_STATISTICS_NOT_SUPPORTED = 0x03d2, - D3D12_MESSAGE_ID_CREATE_VIDEODECODECOMMANDLIST = 0x03d3, - D3D12_MESSAGE_ID_CREATE_VIDEODECODER = 0x03d4, - D3D12_MESSAGE_ID_CREATE_VIDEODECODESTREAM = 0x03d5, - D3D12_MESSAGE_ID_LIVE_VIDEODECODECOMMANDLIST = 0x03d6, - D3D12_MESSAGE_ID_LIVE_VIDEODECODER = 0x03d7, - D3D12_MESSAGE_ID_LIVE_VIDEODECODESTREAM = 0x03d8, - D3D12_MESSAGE_ID_DESTROY_VIDEODECODECOMMANDLIST = 0x03d9, - D3D12_MESSAGE_ID_DESTROY_VIDEODECODER = 0x03da, - D3D12_MESSAGE_ID_DESTROY_VIDEODECODESTREAM = 0x03db, - D3D12_MESSAGE_ID_DECODE_FRAME_INVALID_PARAMETERS = 0x03dc, - D3D12_MESSAGE_ID_DEPRECATED_API = 0x03dd, - D3D12_MESSAGE_ID_RESOURCE_BARRIER_MISMATCHING_COMMAND_LIST_TYPE = 0x03de, - D3D12_MESSAGE_ID_COMMAND_LIST_DESCRIPTOR_TABLE_NOT_SET = 0x03df, - D3D12_MESSAGE_ID_COMMAND_LIST_ROOT_CONSTANT_BUFFER_VIEW_NOT_SET = 0x03e0, - D3D12_MESSAGE_ID_COMMAND_LIST_ROOT_SHADER_RESOURCE_VIEW_NOT_SET = 0x03e1, - D3D12_MESSAGE_ID_COMMAND_LIST_ROOT_UNORDERED_ACCESS_VIEW_NOT_SET = 0x03e2, - D3D12_MESSAGE_ID_DISCARD_INVALID_SUBRESOURCE_RANGE = 0x03e3, - D3D12_MESSAGE_ID_DISCARD_ONE_SUBRESOURCE_FOR_MIPS_WITH_RECTS = 0x03e4, - D3D12_MESSAGE_ID_DISCARD_NO_RECTS_FOR_NON_TEXTURE2D = 0x03e5, - D3D12_MESSAGE_ID_COPY_ON_SAME_SUBRESOURCE = 0x03e6, - D3D12_MESSAGE_ID_SETRESIDENCYPRIORITY_INVALID_PAGEABLE = 0x03e7, - D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_UNSUPPORTED = 0x03e8, - D3D12_MESSAGE_ID_STATIC_DESCRIPTOR_INVALID_DESCRIPTOR_CHANGE = 0x03e9, - D3D12_MESSAGE_ID_DATA_STATIC_DESCRIPTOR_INVALID_DATA_CHANGE = 0x03ea, - D3D12_MESSAGE_ID_DATA_STATIC_WHILE_SET_AT_EXECUTE_DESCRIPTOR_INVALID_DATA_CHANGE = 0x03eb, - D3D12_MESSAGE_ID_EXECUTE_BUNDLE_STATIC_DESCRIPTOR_DATA_STATIC_NOT_SET = 0x03ec, - D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_RESOURCE_ACCESS_OUT_OF_BOUNDS = 0x03ed, - D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_SAMPLER_MODE_MISMATCH = 0x03ee, - D3D12_MESSAGE_ID_CREATE_FENCE_INVALID_FLAGS = 0x03ef, - D3D12_MESSAGE_ID_RESOURCE_BARRIER_DUPLICATE_SUBRESOURCE_TRANSITIONS = 0x03f0, - D3D12_MESSAGE_ID_SETRESIDENCYPRIORITY_INVALID_PRIORITY = 0x03f1, - D3D12_MESSAGE_ID_CREATE_DESCRIPTOR_HEAP_LARGE_NUM_DESCRIPTORS = 0x03f5, - D3D12_MESSAGE_ID_BEGIN_EVENT = 0x03f6, - D3D12_MESSAGE_ID_END_EVENT = 0x03f7, - D3D12_MESSAGE_ID_CREATEDEVICE_DEBUG_LAYER_STARTUP_OPTIONS = 0x03f8, - D3D12_MESSAGE_ID_CREATEDEPTHSTENCILSTATE_DEPTHBOUNDSTEST_UNSUPPORTED = 0x03f9, - D3D12_MESSAGE_ID_CREATEPIPELINESTATE_DUPLICATE_SUBOBJECT = 0x03fa, - D3D12_MESSAGE_ID_CREATEPIPELINESTATE_UNKNOWN_SUBOBJECT = 0x03fb, - D3D12_MESSAGE_ID_CREATEPIPELINESTATE_ZERO_SIZE_STREAM = 0x03fc, - D3D12_MESSAGE_ID_CREATEPIPELINESTATE_INVALID_STREAM = 0x03fd, - D3D12_MESSAGE_ID_CREATEPIPELINESTATE_CANNOT_DEDUCE_TYPE = 0x03fe, - D3D12_MESSAGE_ID_COMMAND_LIST_STATIC_DESCRIPTOR_RESOURCE_DIMENSION_MISMATCH = 0x03ff, - D3D12_MESSAGE_ID_CREATE_COMMAND_QUEUE_INSUFFICIENT_PRIVILEGE_FOR_GLOBAL_REALTIME = 0x0400, - D3D12_MESSAGE_ID_CREATE_COMMAND_QUEUE_INSUFFICIENT_HARDWARE_SUPPORT_FOR_GLOBAL_REALTIME = 0x0401, - D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_INVALID_ARCHITECTURE = 0x0402, - D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_NULL_DST = 0x0403, - D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_INVALID_DST_RESOURCE_DIMENSION = 0x0404, - D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_DST_RANGE_OUT_OF_BOUNDS = 0x0405, - D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_NULL_SRC = 0x0406, - D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_INVALID_SRC_RESOURCE_DIMENSION = 0x0407, - D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_SRC_RANGE_OUT_OF_BOUNDS = 0x0408, - D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_INVALID_OFFSET_ALIGNMENT = 0x0409, - D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_NULL_DEPENDENT_RESOURCES = 0x040a, - D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_NULL_DEPENDENT_SUBRESOURCE_RANGES = 0x040b, - D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_INVALID_DEPENDENT_RESOURCE = 0x040c, - D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_INVALID_DEPENDENT_SUBRESOURCE_RANGE = 0x040d, - D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_DEPENDENT_SUBRESOURCE_OUT_OF_BOUNDS = 0x040e, - D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_DEPENDENT_RANGE_OUT_OF_BOUNDS = 0x040f, - D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_ZERO_DEPENDENCIES = 0x0410, - D3D12_MESSAGE_ID_DEVICE_CREATE_SHARED_HANDLE_INVALIDARG = 0x0411, - D3D12_MESSAGE_ID_DESCRIPTOR_HANDLE_WITH_INVALID_RESOURCE = 0x0412, - D3D12_MESSAGE_ID_SETDEPTHBOUNDS_INVALIDARGS = 0x0413, - D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_RESOURCE_STATE_IMPRECISE = 0x0414, - D3D12_MESSAGE_ID_COMMAND_LIST_PIPELINE_STATE_NOT_SET = 0x0415, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_SHADER_MODEL_MISMATCH = 0x0416, - D3D12_MESSAGE_ID_OBJECT_ACCESSED_WHILE_STILL_IN_USE = 0x0417, - D3D12_MESSAGE_ID_PROGRAMMABLE_MSAA_UNSUPPORTED = 0x0418, - D3D12_MESSAGE_ID_SETSAMPLEPOSITIONS_INVALIDARGS = 0x0419, - D3D12_MESSAGE_ID_RESOLVESUBRESOURCEREGION_INVALID_RECT = 0x041a, - D3D12_MESSAGE_ID_CREATE_VIDEODECODECOMMANDQUEUE = 0x041b, - D3D12_MESSAGE_ID_CREATE_VIDEOPROCESSCOMMANDLIST = 0x041c, - D3D12_MESSAGE_ID_CREATE_VIDEOPROCESSCOMMANDQUEUE = 0x041d, - D3D12_MESSAGE_ID_LIVE_VIDEODECODECOMMANDQUEUE = 0x041e, - D3D12_MESSAGE_ID_LIVE_VIDEOPROCESSCOMMANDLIST = 0x041f, - D3D12_MESSAGE_ID_LIVE_VIDEOPROCESSCOMMANDQUEUE = 0x0420, - D3D12_MESSAGE_ID_DESTROY_VIDEODECODECOMMANDQUEUE = 0x0421, - D3D12_MESSAGE_ID_DESTROY_VIDEOPROCESSCOMMANDLIST = 0x0422, - D3D12_MESSAGE_ID_DESTROY_VIDEOPROCESSCOMMANDQUEUE = 0x0423, - D3D12_MESSAGE_ID_CREATE_VIDEOPROCESSOR = 0x0424, - D3D12_MESSAGE_ID_CREATE_VIDEOPROCESSSTREAM = 0x0425, - D3D12_MESSAGE_ID_LIVE_VIDEOPROCESSOR = 0x0426, - D3D12_MESSAGE_ID_LIVE_VIDEOPROCESSSTREAM = 0x0427, - D3D12_MESSAGE_ID_DESTROY_VIDEOPROCESSOR = 0x0428, - D3D12_MESSAGE_ID_DESTROY_VIDEOPROCESSSTREAM = 0x0429, - D3D12_MESSAGE_ID_PROCESS_FRAME_INVALID_PARAMETERS = 0x042a, - D3D12_MESSAGE_ID_COPY_INVALIDLAYOUT = 0x042b, - D3D12_MESSAGE_ID_CREATE_CRYPTO_SESSION = 0x042c, - D3D12_MESSAGE_ID_CREATE_CRYPTO_SESSION_POLICY = 0x042d, - D3D12_MESSAGE_ID_CREATE_PROTECTED_RESOURCE_SESSION = 0x042e, - D3D12_MESSAGE_ID_LIVE_CRYPTO_SESSION = 0x042f, - D3D12_MESSAGE_ID_LIVE_CRYPTO_SESSION_POLICY = 0x0430, - D3D12_MESSAGE_ID_LIVE_PROTECTED_RESOURCE_SESSION = 0x0431, - D3D12_MESSAGE_ID_DESTROY_CRYPTO_SESSION = 0x0432, - D3D12_MESSAGE_ID_DESTROY_CRYPTO_SESSION_POLICY = 0x0433, - D3D12_MESSAGE_ID_DESTROY_PROTECTED_RESOURCE_SESSION = 0x0434, - D3D12_MESSAGE_ID_PROTECTED_RESOURCE_SESSION_UNSUPPORTED = 0x0435, - D3D12_MESSAGE_ID_FENCE_INVALIDOPERATION = 0x0436, - D3D12_MESSAGE_ID_CREATEQUERY_HEAP_COPY_QUEUE_TIMESTAMPS_NOT_SUPPORTED = 0x0437, - D3D12_MESSAGE_ID_SAMPLEPOSITIONS_MISMATCH_DEFERRED = 0x0438, - D3D12_MESSAGE_ID_SAMPLEPOSITIONS_MISMATCH_RECORDTIME_ASSUMEDFROMFIRSTUSE = 0x0439, - D3D12_MESSAGE_ID_SAMPLEPOSITIONS_MISMATCH_RECORDTIME_ASSUMEDFROMCLEAR = 0x043a, - D3D12_MESSAGE_ID_CREATE_VIDEODECODERHEAP = 0x043b, - D3D12_MESSAGE_ID_LIVE_VIDEODECODERHEAP = 0x043c, - D3D12_MESSAGE_ID_DESTROY_VIDEODECODERHEAP = 0x043d, - D3D12_MESSAGE_ID_OPENEXISTINGHEAP_INVALIDARG_RETURN = 0x043e, - D3D12_MESSAGE_ID_OPENEXISTINGHEAP_OUTOFMEMORY_RETURN = 0x043f, - D3D12_MESSAGE_ID_OPENEXISTINGHEAP_INVALIDADDRESS = 0x0440, - D3D12_MESSAGE_ID_OPENEXISTINGHEAP_INVALIDHANDLE = 0x0441, - D3D12_MESSAGE_ID_WRITEBUFFERIMMEDIATE_INVALID_DEST = 0x0442, - D3D12_MESSAGE_ID_WRITEBUFFERIMMEDIATE_INVALID_MODE = 0x0443, - D3D12_MESSAGE_ID_WRITEBUFFERIMMEDIATE_INVALID_ALIGNMENT = 0x0444, - D3D12_MESSAGE_ID_WRITEBUFFERIMMEDIATE_NOT_SUPPORTED = 0x0445, - D3D12_MESSAGE_ID_SETVIEWINSTANCEMASK_INVALIDARGS = 0x0446, - D3D12_MESSAGE_ID_VIEW_INSTANCING_UNSUPPORTED = 0x0447, - D3D12_MESSAGE_ID_VIEW_INSTANCING_INVALIDARGS = 0x0448, - D3D12_MESSAGE_ID_COPYTEXTUREREGION_MISMATCH_DECODE_REFERENCE_ONLY_FLAG = 0x0449, - D3D12_MESSAGE_ID_COPYRESOURCE_MISMATCH_DECODE_REFERENCE_ONLY_FLAG = 0x044a, - D3D12_MESSAGE_ID_CREATE_VIDEO_DECODE_HEAP_CAPS_FAILURE = 0x044b, - D3D12_MESSAGE_ID_CREATE_VIDEO_DECODE_HEAP_CAPS_UNSUPPORTED = 0x044c, - D3D12_MESSAGE_ID_VIDEO_DECODE_SUPPORT_INVALID_INPUT = 0x044d, - D3D12_MESSAGE_ID_CREATE_VIDEO_DECODER_UNSUPPORTED = 0x044e, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_METADATA_ERROR = 0x044f, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_VIEW_INSTANCING_VERTEX_SIZE_EXCEEDED = 0x0450, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_RUNTIME_INTERNAL_ERROR = 0x0451, - D3D12_MESSAGE_ID_NO_VIDEO_API_SUPPORT = 0x0452, - D3D12_MESSAGE_ID_VIDEO_PROCESS_SUPPORT_INVALID_INPUT = 0x0453, - D3D12_MESSAGE_ID_CREATE_VIDEO_PROCESSOR_CAPS_FAILURE = 0x0454, - D3D12_MESSAGE_ID_VIDEO_PROCESS_SUPPORT_UNSUPPORTED_FORMAT = 0x0455, - D3D12_MESSAGE_ID_VIDEO_DECODE_FRAME_INVALID_ARGUMENT = 0x0456, - D3D12_MESSAGE_ID_ENQUEUE_MAKE_RESIDENT_INVALID_FLAGS = 0x0457, - D3D12_MESSAGE_ID_OPENEXISTINGHEAP_UNSUPPORTED = 0x0458, - D3D12_MESSAGE_ID_VIDEO_PROCESS_FRAMES_INVALID_ARGUMENT = 0x0459, - D3D12_MESSAGE_ID_VIDEO_DECODE_SUPPORT_UNSUPPORTED = 0x045a, - D3D12_MESSAGE_ID_CREATE_COMMANDRECORDER = 0x045b, - D3D12_MESSAGE_ID_LIVE_COMMANDRECORDER = 0x045c, - D3D12_MESSAGE_ID_DESTROY_COMMANDRECORDER = 0x045d, - D3D12_MESSAGE_ID_CREATE_COMMAND_RECORDER_VIDEO_NOT_SUPPORTED = 0x045e, - D3D12_MESSAGE_ID_CREATE_COMMAND_RECORDER_INVALID_SUPPORT_FLAGS = 0x045f, - D3D12_MESSAGE_ID_CREATE_COMMAND_RECORDER_INVALID_FLAGS = 0x0460, - D3D12_MESSAGE_ID_CREATE_COMMAND_RECORDER_MORE_RECORDERS_THAN_LOGICAL_PROCESSORS = 0x0461, - D3D12_MESSAGE_ID_CREATE_COMMANDPOOL = 0x0462, - D3D12_MESSAGE_ID_LIVE_COMMANDPOOL = 0x0463, - D3D12_MESSAGE_ID_DESTROY_COMMANDPOOL = 0x0464, - D3D12_MESSAGE_ID_CREATE_COMMAND_POOL_INVALID_FLAGS = 0x0465, - D3D12_MESSAGE_ID_CREATE_COMMAND_LIST_VIDEO_NOT_SUPPORTED = 0x0466, - D3D12_MESSAGE_ID_COMMAND_RECORDER_SUPPORT_FLAGS_MISMATCH = 0x0467, - D3D12_MESSAGE_ID_COMMAND_RECORDER_CONTENTION = 0x0468, - D3D12_MESSAGE_ID_COMMAND_RECORDER_USAGE_WITH_CREATECOMMANDLIST_COMMAND_LIST = 0x0469, - D3D12_MESSAGE_ID_COMMAND_ALLOCATOR_USAGE_WITH_CREATECOMMANDLIST1_COMMAND_LIST = 0x046a, - D3D12_MESSAGE_ID_CANNOT_EXECUTE_EMPTY_COMMAND_LIST = 0x046b, - D3D12_MESSAGE_ID_CANNOT_RESET_COMMAND_POOL_WITH_OPEN_COMMAND_LISTS = 0x046c, - D3D12_MESSAGE_ID_CANNOT_USE_COMMAND_RECORDER_WITHOUT_CURRENT_TARGET = 0x046d, - D3D12_MESSAGE_ID_CANNOT_CHANGE_COMMAND_RECORDER_TARGET_WHILE_RECORDING = 0x046e, - D3D12_MESSAGE_ID_COMMAND_POOL_SYNC = 0x046f, - D3D12_MESSAGE_ID_EVICT_UNDERFLOW = 0x0470, - D3D12_MESSAGE_ID_CREATE_META_COMMAND = 0x0471, - D3D12_MESSAGE_ID_LIVE_META_COMMAND = 0x0472, - D3D12_MESSAGE_ID_DESTROY_META_COMMAND = 0x0473, - D3D12_MESSAGE_ID_COPYBUFFERREGION_INVALID_DST_RESOURCE = 0x0474, - D3D12_MESSAGE_ID_COPYBUFFERREGION_INVALID_SRC_RESOURCE = 0x0475, - D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_INVALID_DST_RESOURCE = 0x0476, - D3D12_MESSAGE_ID_ATOMICCOPYBUFFER_INVALID_SRC_RESOURCE = 0x0477, - D3D12_MESSAGE_ID_CREATEPLACEDRESOURCEONBUFFER_NULL_BUFFER = 0x0478, - D3D12_MESSAGE_ID_CREATEPLACEDRESOURCEONBUFFER_NULL_RESOURCE_DESC = 0x0479, - D3D12_MESSAGE_ID_CREATEPLACEDRESOURCEONBUFFER_UNSUPPORTED = 0x047a, - D3D12_MESSAGE_ID_CREATEPLACEDRESOURCEONBUFFER_INVALID_BUFFER_DIMENSION = 0x047b, - D3D12_MESSAGE_ID_CREATEPLACEDRESOURCEONBUFFER_INVALID_BUFFER_FLAGS = 0x047c, - D3D12_MESSAGE_ID_CREATEPLACEDRESOURCEONBUFFER_INVALID_BUFFER_OFFSET = 0x047d, - D3D12_MESSAGE_ID_CREATEPLACEDRESOURCEONBUFFER_INVALID_RESOURCE_DIMENSION = 0x047e, - D3D12_MESSAGE_ID_CREATEPLACEDRESOURCEONBUFFER_INVALID_RESOURCE_FLAGS = 0x047f, - D3D12_MESSAGE_ID_CREATEPLACEDRESOURCEONBUFFER_OUTOFMEMORY_RETURN = 0x0480, - D3D12_MESSAGE_ID_CANNOT_CREATE_GRAPHICS_AND_VIDEO_COMMAND_RECORDER = 0x0481, - D3D12_MESSAGE_ID_UPDATETILEMAPPINGS_POSSIBLY_MISMATCHING_PROPERTIES = 0x0482, - D3D12_MESSAGE_ID_CREATE_COMMAND_LIST_INVALID_COMMAND_LIST_TYPE = 0x0483, - D3D12_MESSAGE_ID_CLEARUNORDEREDACCESSVIEW_INCOMPATIBLE_WITH_STRUCTURED_BUFFERS = 0x0484, - D3D12_MESSAGE_ID_COMPUTE_ONLY_DEVICE_OPERATION_UNSUPPORTED = 0x0485, - D3D12_MESSAGE_ID_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INVALID = 0x0486, - D3D12_MESSAGE_ID_EMIT_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_INVALID = 0x0487, - D3D12_MESSAGE_ID_COPY_RAYTRACING_ACCELERATION_STRUCTURE_INVALID = 0x0488, - D3D12_MESSAGE_ID_DISPATCH_RAYS_INVALID = 0x0489, - D3D12_MESSAGE_ID_GET_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO_INVALID = 0x048a, - D3D12_MESSAGE_ID_CREATE_LIFETIMETRACKER = 0x048b, - D3D12_MESSAGE_ID_LIVE_LIFETIMETRACKER = 0x048c, - D3D12_MESSAGE_ID_DESTROY_LIFETIMETRACKER = 0x048d, - D3D12_MESSAGE_ID_DESTROYOWNEDOBJECT_OBJECTNOTOWNED = 0x048e, - D3D12_MESSAGE_ID_CREATE_TRACKEDWORKLOAD = 0x048f, - D3D12_MESSAGE_ID_LIVE_TRACKEDWORKLOAD = 0x0490, - D3D12_MESSAGE_ID_DESTROY_TRACKEDWORKLOAD = 0x0491, - D3D12_MESSAGE_ID_RENDER_PASS_ERROR = 0x0492, - D3D12_MESSAGE_ID_META_COMMAND_ID_INVALID = 0x0493, - D3D12_MESSAGE_ID_META_COMMAND_UNSUPPORTED_PARAMS = 0x0494, - D3D12_MESSAGE_ID_META_COMMAND_FAILED_ENUMERATION = 0x0495, - D3D12_MESSAGE_ID_META_COMMAND_PARAMETER_SIZE_MISMATCH = 0x0496, - D3D12_MESSAGE_ID_UNINITIALIZED_META_COMMAND = 0x0497, - D3D12_MESSAGE_ID_META_COMMAND_INVALID_GPU_VIRTUAL_ADDRESS = 0x0498, - D3D12_MESSAGE_ID_CREATE_VIDEOENCODECOMMANDLIST = 0x0499, - D3D12_MESSAGE_ID_LIVE_VIDEOENCODECOMMANDLIST = 0x049a, - D3D12_MESSAGE_ID_DESTROY_VIDEOENCODECOMMANDLIST = 0x049b, - D3D12_MESSAGE_ID_CREATE_VIDEOENCODECOMMANDQUEUE = 0x049c, - D3D12_MESSAGE_ID_LIVE_VIDEOENCODECOMMANDQUEUE = 0x049d, - D3D12_MESSAGE_ID_DESTROY_VIDEOENCODECOMMANDQUEUE = 0x049e, - D3D12_MESSAGE_ID_CREATE_VIDEOMOTIONESTIMATOR = 0x049f, - D3D12_MESSAGE_ID_LIVE_VIDEOMOTIONESTIMATOR = 0x04a0, - D3D12_MESSAGE_ID_DESTROY_VIDEOMOTIONESTIMATOR = 0x04a1, - D3D12_MESSAGE_ID_CREATE_VIDEOMOTIONVECTORHEAP = 0x04a2, - D3D12_MESSAGE_ID_LIVE_VIDEOMOTIONVECTORHEAP = 0x04a3, - D3D12_MESSAGE_ID_DESTROY_VIDEOMOTIONVECTORHEAP = 0x04a4, - D3D12_MESSAGE_ID_MULTIPLE_TRACKED_WORKLOADS = 0x04a5, - D3D12_MESSAGE_ID_MULTIPLE_TRACKED_WORKLOAD_PAIRS = 0x04a6, - D3D12_MESSAGE_ID_OUT_OF_ORDER_TRACKED_WORKLOAD_PAIR = 0x04a7, - D3D12_MESSAGE_ID_CANNOT_ADD_TRACKED_WORKLOAD = 0x04a8, - D3D12_MESSAGE_ID_INCOMPLETE_TRACKED_WORKLOAD_PAIR = 0x04a9, - D3D12_MESSAGE_ID_CREATE_STATE_OBJECT_ERROR = 0x04aa, - D3D12_MESSAGE_ID_GET_SHADER_IDENTIFIER_ERROR = 0x04ab, - D3D12_MESSAGE_ID_GET_SHADER_STACK_SIZE_ERROR = 0x04ac, - D3D12_MESSAGE_ID_GET_PIPELINE_STACK_SIZE_ERROR = 0x04ad, - D3D12_MESSAGE_ID_SET_PIPELINE_STACK_SIZE_ERROR = 0x04ae, - D3D12_MESSAGE_ID_GET_SHADER_IDENTIFIER_SIZE_INVALID = 0x04af, - D3D12_MESSAGE_ID_CHECK_DRIVER_MATCHING_IDENTIFIER_INVALID = 0x04b0, - D3D12_MESSAGE_ID_CHECK_DRIVER_MATCHING_IDENTIFIER_DRIVER_REPORTED_ISSUE = 0x04b1, - D3D12_MESSAGE_ID_RENDER_PASS_INVALID_RESOURCE_BARRIER = 0x04b2, - D3D12_MESSAGE_ID_RENDER_PASS_DISALLOWED_API_CALLED = 0x04b3, - D3D12_MESSAGE_ID_RENDER_PASS_CANNOT_NEST_RENDER_PASSES = 0x04b4, - D3D12_MESSAGE_ID_RENDER_PASS_CANNOT_END_WITHOUT_BEGIN = 0x04b5, - D3D12_MESSAGE_ID_RENDER_PASS_CANNOT_CLOSE_COMMAND_LIST = 0x04b6, - D3D12_MESSAGE_ID_RENDER_PASS_GPU_WORK_WHILE_SUSPENDED = 0x04b7, - D3D12_MESSAGE_ID_RENDER_PASS_MISMATCHING_SUSPEND_RESUME = 0x04b8, - D3D12_MESSAGE_ID_RENDER_PASS_NO_PRIOR_SUSPEND_WITHIN_EXECUTECOMMANDLISTS = 0x04b9, - D3D12_MESSAGE_ID_RENDER_PASS_NO_SUBSEQUENT_RESUME_WITHIN_EXECUTECOMMANDLISTS = 0x04ba, - D3D12_MESSAGE_ID_TRACKED_WORKLOAD_COMMAND_QUEUE_MISMATCH = 0x04bb, - D3D12_MESSAGE_ID_TRACKED_WORKLOAD_NOT_SUPPORTED = 0x04bc, - D3D12_MESSAGE_ID_RENDER_PASS_MISMATCHING_NO_ACCESS = 0x04bd, - D3D12_MESSAGE_ID_RENDER_PASS_UNSUPPORTED_RESOLVE = 0x04be, - D3D12_MESSAGE_ID_CLEARUNORDEREDACCESSVIEW_INVALID_RESOURCE_PTR = 0x04bf, - D3D12_MESSAGE_ID_WINDOWS7_FENCE_OUTOFORDER_SIGNAL = 0x04c0, - D3D12_MESSAGE_ID_WINDOWS7_FENCE_OUTOFORDER_WAIT = 0x04c1, - D3D12_MESSAGE_ID_VIDEO_CREATE_MOTION_ESTIMATOR_INVALID_ARGUMENT = 0x04c2, - D3D12_MESSAGE_ID_VIDEO_CREATE_MOTION_VECTOR_HEAP_INVALID_ARGUMENT = 0x04c3, - D3D12_MESSAGE_ID_ESTIMATE_MOTION_INVALID_ARGUMENT = 0x04c4, - D3D12_MESSAGE_ID_RESOLVE_MOTION_VECTOR_HEAP_INVALID_ARGUMENT = 0x04c5, - D3D12_MESSAGE_ID_GETGPUVIRTUALADDRESS_INVALID_HEAP_TYPE = 0x04c6, - D3D12_MESSAGE_ID_SET_BACKGROUND_PROCESSING_MODE_INVALID_ARGUMENT = 0x04c7, - D3D12_MESSAGE_ID_CREATE_COMMAND_LIST_INVALID_COMMAND_LIST_TYPE_FOR_FEATURE_LEVEL = 0x04c8, - D3D12_MESSAGE_ID_CREATE_VIDEOEXTENSIONCOMMAND = 0x04c9, - D3D12_MESSAGE_ID_LIVE_VIDEOEXTENSIONCOMMAND = 0x04ca, - D3D12_MESSAGE_ID_DESTROY_VIDEOEXTENSIONCOMMAND = 0x04cb, - D3D12_MESSAGE_ID_INVALID_VIDEO_EXTENSION_COMMAND_ID = 0x04cc, - D3D12_MESSAGE_ID_VIDEO_EXTENSION_COMMAND_INVALID_ARGUMENT = 0x04cd, - D3D12_MESSAGE_ID_CREATE_ROOT_SIGNATURE_NOT_UNIQUE_IN_DXIL_LIBRARY = 0x04ce, - D3D12_MESSAGE_ID_VARIABLE_SHADING_RATE_NOT_ALLOWED_WITH_TIR = 0x04cf, - D3D12_MESSAGE_ID_GEOMETRY_SHADER_OUTPUTTING_BOTH_VIEWPORT_ARRAY_INDEX_AND_SHADING_RATE_NOT_SUPPORTED_ON_DEVICE = 0x04d0, - D3D12_MESSAGE_ID_RSSETSHADING_RATE_INVALID_SHADING_RATE = 0x04d1, - D3D12_MESSAGE_ID_RSSETSHADING_RATE_SHADING_RATE_NOT_PERMITTED_BY_CAP = 0x04d2, - D3D12_MESSAGE_ID_RSSETSHADING_RATE_INVALID_COMBINER = 0x04d3, - D3D12_MESSAGE_ID_RSSETSHADINGRATEIMAGE_REQUIRES_TIER_2 = 0x04d4, - D3D12_MESSAGE_ID_RSSETSHADINGRATE_REQUIRES_TIER_1 = 0x04d5, - D3D12_MESSAGE_ID_SHADING_RATE_IMAGE_INCORRECT_FORMAT = 0x04d6, - D3D12_MESSAGE_ID_SHADING_RATE_IMAGE_INCORRECT_ARRAY_SIZE = 0x04d7, - D3D12_MESSAGE_ID_SHADING_RATE_IMAGE_INCORRECT_MIP_LEVEL = 0x04d8, - D3D12_MESSAGE_ID_SHADING_RATE_IMAGE_INCORRECT_SAMPLE_COUNT = 0x04d9, - D3D12_MESSAGE_ID_SHADING_RATE_IMAGE_INCORRECT_SAMPLE_QUALITY = 0x04da, - D3D12_MESSAGE_ID_NON_RETAIL_SHADER_MODEL_WONT_VALIDATE = 0x04db, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_AS_ROOT_SIGNATURE_MISMATCH = 0x04dc, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_MS_ROOT_SIGNATURE_MISMATCH = 0x04dd, - D3D12_MESSAGE_ID_ADD_TO_STATE_OBJECT_ERROR = 0x04de, - D3D12_MESSAGE_ID_CREATE_PROTECTED_RESOURCE_SESSION_INVALID_ARGUMENT = 0x04df, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_MS_PSO_DESC_MISMATCH = 0x04e0, - D3D12_MESSAGE_ID_CREATEPIPELINESTATE_MS_INCOMPLETE_TYPE = 0x04e1, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_AS_NOT_MS_MISMATCH = 0x04e2, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_MS_NOT_PS_MISMATCH = 0x04e3, - D3D12_MESSAGE_ID_NONZERO_SAMPLER_FEEDBACK_MIP_REGION_WITH_INCOMPATIBLE_FORMAT = 0x04e4, - D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_INPUTLAYOUT_SHADER_MISMATCH = 0x04e5, - D3D12_MESSAGE_ID_EMPTY_DISPATCH = 0x04e6, - D3D12_MESSAGE_ID_RESOURCE_FORMAT_REQUIRES_SAMPLER_FEEDBACK_CAPABILITY = 0x04e7, - D3D12_MESSAGE_ID_SAMPLER_FEEDBACK_MAP_INVALID_MIP_REGION = 0x04e8, - D3D12_MESSAGE_ID_SAMPLER_FEEDBACK_MAP_INVALID_DIMENSION = 0x04e9, - D3D12_MESSAGE_ID_SAMPLER_FEEDBACK_MAP_INVALID_SAMPLE_COUNT = 0x04ea, - D3D12_MESSAGE_ID_SAMPLER_FEEDBACK_MAP_INVALID_SAMPLE_QUALITY = 0x04eb, - D3D12_MESSAGE_ID_SAMPLER_FEEDBACK_MAP_INVALID_LAYOUT = 0x04ec, - D3D12_MESSAGE_ID_SAMPLER_FEEDBACK_MAP_REQUIRES_UNORDERED_ACCESS_FLAG = 0x04ed, - D3D12_MESSAGE_ID_SAMPLER_FEEDBACK_CREATE_UAV_NULL_ARGUMENTS = 0x04ee, - D3D12_MESSAGE_ID_SAMPLER_FEEDBACK_UAV_REQUIRES_SAMPLER_FEEDBACK_CAPABILITY = 0x04ef, - D3D12_MESSAGE_ID_SAMPLER_FEEDBACK_CREATE_UAV_REQUIRES_FEEDBACK_MAP_FORMAT = 0x04f0, - D3D12_MESSAGE_ID_CREATEMESHSHADER_INVALIDSHADERBYTECODE = 0x04f1, - D3D12_MESSAGE_ID_CREATEMESHSHADER_OUTOFMEMORY = 0x04f2, - D3D12_MESSAGE_ID_CREATEMESHSHADERWITHSTREAMOUTPUT_INVALIDSHADERTYPE = 0x04f3, - D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_SAMPLER_FEEDBACK_TRANSCODE_INVALID_FORMAT = 0x04f4, - D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_SAMPLER_FEEDBACK_INVALID_MIP_LEVEL_COUNT = 0x04f5, - D3D12_MESSAGE_ID_RESOLVESUBRESOURCE_SAMPLER_FEEDBACK_TRANSCODE_ARRAY_SIZE_MISMATCH = 0x04f6, - D3D12_MESSAGE_ID_SAMPLER_FEEDBACK_CREATE_UAV_MISMATCHING_TARGETED_RESOURCE = 0x04f7, - D3D12_MESSAGE_ID_CREATEMESHSHADER_OUTPUTEXCEEDSMAXSIZE = 0x04f8, - D3D12_MESSAGE_ID_CREATEMESHSHADER_GROUPSHAREDEXCEEDSMAXSIZE = 0x04f9, - D3D12_MESSAGE_ID_VERTEX_SHADER_OUTPUTTING_BOTH_VIEWPORT_ARRAY_INDEX_AND_SHADING_RATE_NOT_SUPPORTED_ON_DEVICE = 0x04fa, - D3D12_MESSAGE_ID_MESH_SHADER_OUTPUTTING_BOTH_VIEWPORT_ARRAY_INDEX_AND_SHADING_RATE_NOT_SUPPORTED_ON_DEVICE = 0x04fb, - D3D12_MESSAGE_ID_CREATEMESHSHADER_MISMATCHEDASMSPAYLOADSIZE = 0x04fc, - D3D12_MESSAGE_ID_CREATE_ROOT_SIGNATURE_UNBOUNDED_STATIC_DESCRIPTORS = 0x04fd, - D3D12_MESSAGE_ID_CREATEAMPLIFICATIONSHADER_INVALIDSHADERBYTECODE = 0x04fe, - D3D12_MESSAGE_ID_CREATEAMPLIFICATIONSHADER_OUTOFMEMORY = 0x04ff, - D3D12_MESSAGE_ID_D3D12_MESSAGES_END -} D3D12_MESSAGE_ID; - -typedef enum D3D12_GPU_BASED_VALIDATION_SHADER_PATCH_MODE -{ - D3D12_GPU_BASED_VALIDATION_SHADER_PATCH_MODE_NONE = 0x0, - D3D12_GPU_BASED_VALIDATION_SHADER_PATCH_MODE_STATE_TRACKING_ONLY = 0x1, - D3D12_GPU_BASED_VALIDATION_SHADER_PATCH_MODE_UNGUARDED_VALIDATION = 0x2, - D3D12_GPU_BASED_VALIDATION_SHADER_PATCH_MODE_GUARDED_VALIDATION = 0x3, - NUM_D3D12_GPU_BASED_VALIDATION_SHADER_PATCH_MODES = 0x4, -} D3D12_GPU_BASED_VALIDATION_SHADER_PATCH_MODE; - -typedef struct D3D12_MESSAGE -{ - D3D12_MESSAGE_CATEGORY Category; - D3D12_MESSAGE_SEVERITY Severity; - D3D12_MESSAGE_ID ID; - const char *pDescription; - SIZE_T DescriptionByteLength; -} D3D12_MESSAGE; - -typedef struct D3D12_INFO_QUEUE_FILTER_DESC -{ - UINT NumCategories; - D3D12_MESSAGE_CATEGORY *pCategoryList; - UINT NumSeverities; - D3D12_MESSAGE_SEVERITY *pSeverityList; - UINT NumIDs; - D3D12_MESSAGE_ID *pIDList; -} D3D12_INFO_QUEUE_FILTER_DESC; - -typedef struct D3D12_INFO_QUEUE_FILTER -{ - D3D12_INFO_QUEUE_FILTER_DESC AllowList; - D3D12_INFO_QUEUE_FILTER_DESC DenyList; -} D3D12_INFO_QUEUE_FILTER; - -[ - uuid(344488b7-6846-474b-b989-f027448245e0), - object, - local, - pointer_default(unique) -] -interface ID3D12Debug : IUnknown -{ - void EnableDebugLayer(); -} - -[ - uuid(affaa4ca-63fe-4d8e-b8ad-159000af4304), - object, - local, - pointer_default(unique) -] -interface ID3D12Debug1 : IUnknown -{ - void EnableDebugLayer(); - void SetEnableGPUBasedValidation(BOOL enable); - void SetEnableSynchronizedCommandQueueValidation(BOOL enable); -} - -[ - uuid(0742a90b-c387-483f-b946-30a7e4e61458), - object, - local, - pointer_default(unique) -] -interface ID3D12InfoQueue : IUnknown -{ - HRESULT SetMessageCountLimit([in] UINT64 limit); - void ClearStoredMessages(); - HRESULT GetMessage([in] UINT64 index, [out] D3D12_MESSAGE *message, [in, out] SIZE_T *length); - UINT64 GetNumMessagesAllowedByStorageFilter(); - UINT64 GetNumMessagesDeniedByStorageFilter(); - UINT64 GetNumStoredMessages(); - UINT64 GetNumStoredMessagesAllowedByRetrievalFilter(); - UINT64 GetNumMessagesDiscardedByMessageCountLimit(); - UINT64 GetMessageCountLimit(); - HRESULT AddStorageFilterEntries([in] D3D12_INFO_QUEUE_FILTER *filter); - HRESULT GetStorageFilter([out] D3D12_INFO_QUEUE_FILTER *filter, [in, out] SIZE_T *length); - void ClearStorageFilter(); - HRESULT PushEmptyStorageFilter(); - HRESULT PushCopyOfStorageFilter(); - HRESULT PushStorageFilter([in] D3D12_INFO_QUEUE_FILTER *filter); - void PopStorageFilter(); - UINT GetStorageFilterStackSize(); - HRESULT AddRetrievalFilterEntries([in] D3D12_INFO_QUEUE_FILTER *filter); - HRESULT GetRetrievalFilter([out] D3D12_INFO_QUEUE_FILTER *filter, [in, out] SIZE_T *length); - void ClearRetrievalFilter(); - HRESULT PushEmptyRetrievalFilter(); - HRESULT PushCopyOfRetrievalFilter(); - HRESULT PushRetrievalFilter([in] D3D12_INFO_QUEUE_FILTER *filter); - void PopRetrievalFilter(); - UINT GetRetrievalFilterStackSize(); - HRESULT AddMessage([in] D3D12_MESSAGE_CATEGORY category, [in] D3D12_MESSAGE_SEVERITY severity, - [in] D3D12_MESSAGE_ID id, [in] const char *description); - HRESULT AddApplicationMessage([in] D3D12_MESSAGE_SEVERITY severity, [in] const char *description); - HRESULT SetBreakOnCategory([in] D3D12_MESSAGE_CATEGORY category, [in] BOOL enable); - HRESULT SetBreakOnSeverity([in] D3D12_MESSAGE_SEVERITY severity, [in] BOOL enable); - HRESULT SetBreakOnID([in] D3D12_MESSAGE_ID id, [in] BOOL enable); - BOOL GetBreakOnCategory([in] D3D12_MESSAGE_CATEGORY category); - BOOL GetBreakOnSeverity([in] D3D12_MESSAGE_SEVERITY severity); - BOOL GetBreakOnID([in] D3D12_MESSAGE_ID id); - void SetMuteDebugOutput([in] BOOL mute); - BOOL GetMuteDebugOutput(); -} diff --git a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_d3d9types.h b/dll/directx/wine/d3d12/vkd3d/include/vkd3d_d3d9types.h deleted file mode 100644 index 75d0461409d0e..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_d3d9types.h +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright 2002-2003 Jason Edmeades - * Copyright 2002-2003 Raphael Junqueira - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef __VKD3D_D3D9TYPES_H -#define __VKD3D_D3D9TYPES_H -#ifndef _d3d9TYPES_H_ - -#ifndef MAKEFOURCC -#define MAKEFOURCC(ch0, ch1, ch2, ch3) \ - ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \ - ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 )) -#endif - -#define D3DSI_INSTLENGTH_SHIFT 24 - -#define D3DSP_DCL_USAGE_SHIFT 0 -#define D3DSP_DCL_USAGEINDEX_SHIFT 16 -#define D3DSP_DSTMOD_SHIFT 20 - -#define D3DSP_SRCMOD_SHIFT 24 - -#define D3DSP_REGTYPE_SHIFT 28 -#define D3DSP_REGTYPE_SHIFT2 8 -#define D3DSP_REGTYPE_MASK (0x7 << D3DSP_REGTYPE_SHIFT) -#define D3DSP_REGTYPE_MASK2 0x00001800 - -#define D3DSP_WRITEMASK_0 0x00010000 -#define D3DSP_WRITEMASK_1 0x00020000 -#define D3DSP_WRITEMASK_2 0x00040000 -#define D3DSP_WRITEMASK_3 0x00080000 -#define D3DSP_WRITEMASK_ALL 0x000f0000 - -#define D3DPS_VERSION(major, minor) (0xffff0000 | ((major) << 8) | (minor)) -#define D3DVS_VERSION(major, minor) (0xfffe0000 | ((major) << 8) | (minor)) - -typedef enum _D3DDECLUSAGE -{ - D3DDECLUSAGE_POSITION = 0x0, - D3DDECLUSAGE_BLENDWEIGHT = 0x1, - D3DDECLUSAGE_BLENDINDICES = 0x2, - D3DDECLUSAGE_NORMAL = 0x3, - D3DDECLUSAGE_PSIZE = 0x4, - D3DDECLUSAGE_TEXCOORD = 0x5, - D3DDECLUSAGE_TANGENT = 0x6, - D3DDECLUSAGE_BINORMAL = 0x7, - D3DDECLUSAGE_TESSFACTOR = 0x8, - D3DDECLUSAGE_POSITIONT = 0x9, - D3DDECLUSAGE_COLOR = 0xa, - D3DDECLUSAGE_FOG = 0xb, - D3DDECLUSAGE_DEPTH = 0xc, - D3DDECLUSAGE_SAMPLE = 0xd, -} D3DDECLUSAGE; - -typedef enum _D3DSHADER_INSTRUCTION_OPCODE_TYPE -{ - D3DSIO_NOP = 0x00, - D3DSIO_MOV = 0x01, - D3DSIO_ADD = 0x02, - D3DSIO_SUB = 0x03, - D3DSIO_MAD = 0x04, - D3DSIO_MUL = 0x05, - D3DSIO_RCP = 0x06, - D3DSIO_RSQ = 0x07, - D3DSIO_DP3 = 0x08, - D3DSIO_DP4 = 0x09, - D3DSIO_MIN = 0x0a, - D3DSIO_MAX = 0x0b, - D3DSIO_SLT = 0x0c, - D3DSIO_SGE = 0x0d, - D3DSIO_EXP = 0x0e, - D3DSIO_LOG = 0x0f, - D3DSIO_LIT = 0x10, - D3DSIO_DST = 0x11, - D3DSIO_LRP = 0x12, - D3DSIO_FRC = 0x13, - D3DSIO_M4x4 = 0x14, - D3DSIO_M4x3 = 0x15, - D3DSIO_M3x4 = 0x16, - D3DSIO_M3x3 = 0x17, - D3DSIO_M3x2 = 0x18, - D3DSIO_CALL = 0x19, - D3DSIO_CALLNZ = 0x1a, - D3DSIO_LOOP = 0x1b, - D3DSIO_RET = 0x1c, - D3DSIO_ENDLOOP = 0x1d, - D3DSIO_LABEL = 0x1e, - D3DSIO_DCL = 0x1f, - D3DSIO_POW = 0x20, - D3DSIO_CRS = 0x21, - D3DSIO_SGN = 0x22, - D3DSIO_ABS = 0x23, - D3DSIO_NRM = 0x24, - D3DSIO_SINCOS = 0x25, - D3DSIO_REP = 0x26, - D3DSIO_ENDREP = 0x27, - D3DSIO_IF = 0x28, - D3DSIO_IFC = 0x29, - D3DSIO_ELSE = 0x2a, - D3DSIO_ENDIF = 0x2b, - D3DSIO_BREAK = 0x2c, - D3DSIO_BREAKC = 0x2d, - D3DSIO_MOVA = 0x2e, - D3DSIO_DEFB = 0x2f, - D3DSIO_DEFI = 0x30, - - D3DSIO_TEXCOORD = 0x40, - D3DSIO_TEXKILL = 0x41, - D3DSIO_TEX = 0x42, - D3DSIO_TEXBEM = 0x43, - D3DSIO_TEXBEML = 0x44, - D3DSIO_TEXREG2AR = 0x45, - D3DSIO_TEXREG2GB = 0x46, - D3DSIO_TEXM3x2PAD = 0x47, - D3DSIO_TEXM3x2TEX = 0x48, - D3DSIO_TEXM3x3PAD = 0x49, - D3DSIO_TEXM3x3TEX = 0x4a, - D3DSIO_TEXM3x3DIFF = 0x4b, - D3DSIO_TEXM3x3SPEC = 0x4c, - D3DSIO_TEXM3x3VSPEC = 0x4d, - D3DSIO_EXPP = 0x4e, - D3DSIO_LOGP = 0x4f, - D3DSIO_CND = 0x50, - D3DSIO_DEF = 0x51, - D3DSIO_TEXREG2RGB = 0x52, - D3DSIO_TEXDP3TEX = 0x53, - D3DSIO_TEXM3x2DEPTH = 0x54, - D3DSIO_TEXDP3 = 0x55, - D3DSIO_TEXM3x3 = 0x56, - D3DSIO_TEXDEPTH = 0x57, - D3DSIO_CMP = 0x58, - D3DSIO_BEM = 0x59, - D3DSIO_DP2ADD = 0x5a, - D3DSIO_DSX = 0x5b, - D3DSIO_DSY = 0x5c, - D3DSIO_TEXLDD = 0x5d, - D3DSIO_SETP = 0x5e, - D3DSIO_TEXLDL = 0x5f, - D3DSIO_BREAKP = 0x60, - - D3DSIO_PHASE = 0xfffd, - D3DSIO_COMMENT = 0xfffe, - D3DSIO_END = 0xffff, - - D3DSIO_FORCE_DWORD = 0x7fffffff, -} D3DSHADER_INSTRUCTION_OPCODE_TYPE; - -typedef enum _D3DSHADER_PARAM_DSTMOD_TYPE -{ - D3DSPDM_NONE = 0 << D3DSP_DSTMOD_SHIFT, - D3DSPDM_SATURATE = 1 << D3DSP_DSTMOD_SHIFT, - D3DSPDM_PARTIALPRECISION = 2 << D3DSP_DSTMOD_SHIFT, - D3DSPDM_MSAMPCENTROID = 4 << D3DSP_DSTMOD_SHIFT, - - D3DSPDM_FORCE_DWORD = 0x7fffffff, -} D3DSHADER_PARAM_DSTMOD_TYPE; - -typedef enum _D3DSHADER_PARAM_REGISTER_TYPE -{ - D3DSPR_TEMP = 0x00, - D3DSPR_INPUT = 0x01, - D3DSPR_CONST = 0x02, - D3DSPR_ADDR = 0x03, - D3DSPR_TEXTURE = 0x03, - D3DSPR_RASTOUT = 0x04, - D3DSPR_ATTROUT = 0x05, - D3DSPR_TEXCRDOUT = 0x06, - D3DSPR_OUTPUT = 0x06, - D3DSPR_CONSTINT = 0x07, - D3DSPR_COLOROUT = 0x08, - D3DSPR_DEPTHOUT = 0x09, - D3DSPR_SAMPLER = 0x0a, - D3DSPR_CONST2 = 0x0b, - D3DSPR_CONST3 = 0x0c, - D3DSPR_CONST4 = 0x0d, - D3DSPR_CONSTBOOL = 0x0e, - D3DSPR_LOOP = 0x0f, - D3DSPR_TEMPFLOAT16 = 0x10, - D3DSPR_MISCTYPE = 0x11, - D3DSPR_LABEL = 0x12, - D3DSPR_PREDICATE = 0x13, - - D3DSPR_FORCE_DWORD = 0x7fffffff, -} D3DSHADER_PARAM_REGISTER_TYPE; - -typedef enum _D3DSHADER_PARAM_SRCMOD_TYPE -{ - D3DSPSM_NONE = 0x0 << D3DSP_SRCMOD_SHIFT, - D3DSPSM_NEG = 0x1 << D3DSP_SRCMOD_SHIFT, - D3DSPSM_BIAS = 0x2 << D3DSP_SRCMOD_SHIFT, - D3DSPSM_BIASNEG = 0x3 << D3DSP_SRCMOD_SHIFT, - D3DSPSM_SIGN = 0x4 << D3DSP_SRCMOD_SHIFT, - D3DSPSM_SIGNNEG = 0x5 << D3DSP_SRCMOD_SHIFT, - D3DSPSM_COMP = 0x6 << D3DSP_SRCMOD_SHIFT, - D3DSPSM_X2 = 0x7 << D3DSP_SRCMOD_SHIFT, - D3DSPSM_X2NEG = 0x8 << D3DSP_SRCMOD_SHIFT, - D3DSPSM_DZ = 0x9 << D3DSP_SRCMOD_SHIFT, - D3DSPSM_DW = 0xa << D3DSP_SRCMOD_SHIFT, - D3DSPSM_ABS = 0xb << D3DSP_SRCMOD_SHIFT, - D3DSPSM_ABSNEG = 0xc << D3DSP_SRCMOD_SHIFT, - D3DSPSM_NOT = 0xd << D3DSP_SRCMOD_SHIFT, - - D3DSPSM_FORCE_DWORD = 0x7fffffff, -} D3DSHADER_PARAM_SRCMOD_TYPE; - -typedef enum _D3DSHADER_MISCTYPE_OFFSETS -{ - D3DSMO_POSITION = 0x0, - D3DSMO_FACE = 0x1, -} D3DSHADER_MISCTYPE_OFFSETS; - -typedef enum _D3DVS_RASTOUT_OFFSETS -{ - D3DSRO_POSITION = 0x0, - D3DSRO_FOG = 0x1, - D3DSRO_POINT_SIZE = 0x2, - - D3DSRO_FORCE_DWORD = 0x7fffffff, -} D3DVS_RASTOUT_OFFSETS; - -#endif /* _d3d9TYPES_H_ */ -#endif /* __VKD3D_D3D9TYPES_H */ diff --git a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_d3dcommon.idl b/dll/directx/wine/d3d12/vkd3d/include/vkd3d_d3dcommon.idl deleted file mode 100644 index 0e0d4f7ba722e..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_d3dcommon.idl +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright 2010 Matteo Bruni for CodeWeavers - * Copyright 2016 Józef Kucia for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -import "vkd3d_windows.h"; - -#include "vkd3d_unknown.idl" - -typedef enum D3D_PRIMITIVE_TOPOLOGY -{ - D3D_PRIMITIVE_TOPOLOGY_UNDEFINED = 0, - D3D_PRIMITIVE_TOPOLOGY_POINTLIST = 1, - D3D_PRIMITIVE_TOPOLOGY_LINELIST = 2, - D3D_PRIMITIVE_TOPOLOGY_LINESTRIP = 3, - D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST = 4, - D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = 5, - D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ = 10, - D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ = 11, - D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ = 12, - D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ = 13, - D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST = 33, - D3D_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST, - D3D_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST, -} D3D_PRIMITIVE_TOPOLOGY; - -typedef enum D3D_FEATURE_LEVEL -{ - D3D_FEATURE_LEVEL_9_1 = 0x9100, - D3D_FEATURE_LEVEL_9_2 = 0x9200, - D3D_FEATURE_LEVEL_9_3 = 0x9300, - D3D_FEATURE_LEVEL_10_0 = 0xa000, - D3D_FEATURE_LEVEL_10_1 = 0xa100, - D3D_FEATURE_LEVEL_11_0 = 0xb000, - D3D_FEATURE_LEVEL_11_1 = 0xb100, - D3D_FEATURE_LEVEL_12_0 = 0xc000, - D3D_FEATURE_LEVEL_12_1 = 0xc100, -} D3D_FEATURE_LEVEL; - -typedef enum D3D_CBUFFER_TYPE -{ - D3D_CT_CBUFFER, - D3D_CT_TBUFFER, - D3D_CT_INTERFACE_POINTERS, - D3D_CT_RESOURCE_BIND_INFO, -} D3D_CBUFFER_TYPE; - -typedef enum D3D_NAME -{ - D3D_NAME_UNDEFINED, - D3D_NAME_POSITION, - D3D_NAME_CLIP_DISTANCE, - D3D_NAME_CULL_DISTANCE, - D3D_NAME_RENDER_TARGET_ARRAY_INDEX, - D3D_NAME_VIEWPORT_ARRAY_INDEX, - D3D_NAME_VERTEX_ID, - D3D_NAME_PRIMITIVE_ID, - D3D_NAME_INSTANCE_ID, - D3D_NAME_IS_FRONT_FACE, - D3D_NAME_SAMPLE_INDEX, - D3D_NAME_FINAL_QUAD_EDGE_TESSFACTOR, - D3D_NAME_FINAL_QUAD_INSIDE_TESSFACTOR, - D3D_NAME_FINAL_TRI_EDGE_TESSFACTOR, - D3D_NAME_FINAL_TRI_INSIDE_TESSFACTOR, - D3D_NAME_FINAL_LINE_DETAIL_TESSFACTOR, - D3D_NAME_FINAL_LINE_DENSITY_TESSFACTOR, - D3D_NAME_BARYCENTRICS = 23, - D3D_NAME_SHADINGRATE, - D3D_NAME_CULLPRIMITIVE, - D3D_NAME_TARGET = 64, - D3D_NAME_DEPTH, - D3D_NAME_COVERAGE, - D3D_NAME_DEPTH_GREATER_EQUAL, - D3D_NAME_DEPTH_LESS_EQUAL, -} D3D_NAME; - -typedef enum D3D_REGISTER_COMPONENT_TYPE -{ - D3D_REGISTER_COMPONENT_UNKNOWN, - D3D_REGISTER_COMPONENT_UINT32, - D3D_REGISTER_COMPONENT_SINT32, - D3D_REGISTER_COMPONENT_FLOAT32, -} D3D_REGISTER_COMPONENT_TYPE; - -typedef enum D3D_RESOURCE_RETURN_TYPE -{ - D3D_RETURN_TYPE_UNORM = 1, - D3D_RETURN_TYPE_SNORM, - D3D_RETURN_TYPE_SINT, - D3D_RETURN_TYPE_UINT, - D3D_RETURN_TYPE_FLOAT, - D3D_RETURN_TYPE_MIXED, - D3D_RETURN_TYPE_DOUBLE, - D3D_RETURN_TYPE_CONTINUED, -} D3D_RESOURCE_RETURN_TYPE; - -typedef enum _D3D_SHADER_INPUT_FLAGS -{ - D3D_SIF_USERPACKED = 0x01, - D3D_SIF_COMPARISON_SAMPLER = 0x02, - D3D_SIF_TEXTURE_COMPONENT_0 = 0x04, - D3D_SIF_TEXTURE_COMPONENT_1 = 0x08, - D3D_SIF_TEXTURE_COMPONENTS = 0x0c, - D3D_SIF_UNUSED = 0x10, - D3D_SIF_FORCE_DWORD = 0x7fffffff, -} D3D_SHADER_INPUT_FLAGS; - -typedef enum _D3D_SHADER_INPUT_TYPE -{ - D3D_SIT_CBUFFER, - D3D_SIT_TBUFFER, - D3D_SIT_TEXTURE, - D3D_SIT_SAMPLER, - D3D_SIT_UAV_RWTYPED, - D3D_SIT_STRUCTURED, - D3D_SIT_UAV_RWSTRUCTURED, - D3D_SIT_BYTEADDRESS, - D3D_SIT_UAV_RWBYTEADDRESS, - D3D_SIT_UAV_APPEND_STRUCTURED, - D3D_SIT_UAV_CONSUME_STRUCTURED, - D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER, -} D3D_SHADER_INPUT_TYPE; - -typedef enum D3D_SRV_DIMENSION -{ - D3D_SRV_DIMENSION_UNKNOWN, - D3D_SRV_DIMENSION_BUFFER, - D3D_SRV_DIMENSION_TEXTURE1D, - D3D_SRV_DIMENSION_TEXTURE1DARRAY, - D3D_SRV_DIMENSION_TEXTURE2D, - D3D_SRV_DIMENSION_TEXTURE2DARRAY, - D3D_SRV_DIMENSION_TEXTURE2DMS, - D3D_SRV_DIMENSION_TEXTURE2DMSARRAY, - D3D_SRV_DIMENSION_TEXTURE3D, - D3D_SRV_DIMENSION_TEXTURECUBE, - D3D_SRV_DIMENSION_TEXTURECUBEARRAY, - D3D_SRV_DIMENSION_BUFFEREX, -} D3D_SRV_DIMENSION; - -typedef enum _D3D_SHADER_VARIABLE_CLASS -{ - D3D_SVC_SCALAR, - D3D_SVC_VECTOR, - D3D_SVC_MATRIX_ROWS, - D3D_SVC_MATRIX_COLUMNS, - D3D_SVC_OBJECT, - D3D_SVC_STRUCT, - D3D_SVC_INTERFACE_CLASS, - D3D_SVC_INTERFACE_POINTER, - D3D_SVC_FORCE_DWORD = 0x7fffffff, -} D3D_SHADER_VARIABLE_CLASS; - -typedef enum _D3D_SHADER_VARIABLE_FLAGS -{ - D3D_SVF_USERPACKED = 0x01, - D3D_SVF_USED = 0x02, - D3D_SVF_INTERFACE_POINTER = 0x04, - D3D_SVF_INTERFACE_PARAMETER = 0x08, - D3D_SVF_FORCE_DWORD = 0x7fffffff, -} D3D_SHADER_VARIABLE_FLAGS; - -typedef enum _D3D_SHADER_VARIABLE_TYPE -{ - D3D_SVT_VOID, - D3D_SVT_BOOL, - D3D_SVT_INT, - D3D_SVT_FLOAT, - D3D_SVT_STRING, - D3D_SVT_TEXTURE, - D3D_SVT_TEXTURE1D, - D3D_SVT_TEXTURE2D, - D3D_SVT_TEXTURE3D, - D3D_SVT_TEXTURECUBE, - D3D_SVT_SAMPLER, - D3D_SVT_SAMPLER1D, - D3D_SVT_SAMPLER2D, - D3D_SVT_SAMPLER3D, - D3D_SVT_SAMPLERCUBE, - D3D_SVT_PIXELSHADER, - D3D_SVT_VERTEXSHADER, - D3D_SVT_PIXELFRAGMENT, - D3D_SVT_VERTEXFRAGMENT, - D3D_SVT_UINT, - D3D_SVT_UINT8, - D3D_SVT_GEOMETRYSHADER, - D3D_SVT_RASTERIZER, - D3D_SVT_DEPTHSTENCIL, - D3D_SVT_BLEND, - D3D_SVT_BUFFER, - D3D_SVT_CBUFFER, - D3D_SVT_TBUFFER, - D3D_SVT_TEXTURE1DARRAY, - D3D_SVT_TEXTURE2DARRAY, - D3D_SVT_RENDERTARGETVIEW, - D3D_SVT_DEPTHSTENCILVIEW, - D3D_SVT_TEXTURE2DMS, - D3D_SVT_TEXTURE2DMSARRAY, - D3D_SVT_TEXTURECUBEARRAY, - D3D_SVT_HULLSHADER, - D3D_SVT_DOMAINSHADER, - D3D_SVT_INTERFACE_POINTER, - D3D_SVT_COMPUTESHADER, - D3D_SVT_DOUBLE, - D3D_SVT_RWTEXTURE1D, - D3D_SVT_RWTEXTURE1DARRAY, - D3D_SVT_RWTEXTURE2D, - D3D_SVT_RWTEXTURE2DARRAY, - D3D_SVT_RWTEXTURE3D, - D3D_SVT_RWBUFFER, - D3D_SVT_BYTEADDRESS_BUFFER, - D3D_SVT_RWBYTEADDRESS_BUFFER, - D3D_SVT_STRUCTURED_BUFFER, - D3D_SVT_RWSTRUCTURED_BUFFER, - D3D_SVT_APPEND_STRUCTURED_BUFFER, - D3D_SVT_CONSUME_STRUCTURED_BUFFER, - D3D_SVT_MIN8FLOAT, - D3D_SVT_MIN10FLOAT, - D3D_SVT_MIN16FLOAT, - D3D_SVT_MIN12INT, - D3D_SVT_MIN16INT, - D3D_SVT_MIN16UINT, - D3D_SVT_FORCE_DWORD = 0x7fffffff, -} D3D_SHADER_VARIABLE_TYPE; - -[ - uuid(8ba5fb08-5195-40e2-ac58-0d989c3a0102), - object, - local, - pointer_default(unique) -] -interface ID3D10Blob : IUnknown -{ - void *GetBufferPointer(); - SIZE_T GetBufferSize(); -} - -typedef ID3D10Blob ID3DBlob; -cpp_quote("#define IID_ID3DBlob IID_ID3D10Blob") - -typedef enum _D3D_INCLUDE_TYPE -{ - D3D_INCLUDE_LOCAL = 0, - D3D_INCLUDE_SYSTEM, - D3D10_INCLUDE_LOCAL = D3D_INCLUDE_LOCAL, - D3D10_INCLUDE_SYSTEM = D3D_INCLUDE_SYSTEM, - D3D_INCLUDE_FORCE_DWORD = 0x7fffffff, -} D3D_INCLUDE_TYPE; - -[ - object, - local, -] -interface ID3DInclude -{ - HRESULT Open(D3D_INCLUDE_TYPE include_type, const char *filename, const void *parent_data, const void **data, - UINT *size); - HRESULT Close(const void *data); -} - -typedef struct _D3D_SHADER_MACRO -{ - const char *Name; - const char *Definition; -} D3D_SHADER_MACRO; diff --git a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_d3dcompiler.h b/dll/directx/wine/d3d12/vkd3d/include/vkd3d_d3dcompiler.h deleted file mode 100644 index c934835dc0a55..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_d3dcompiler.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2010 Matteo Bruni for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef __VKD3D_D3DCOMPILER_H -#define __VKD3D_D3DCOMPILER_H -#ifndef __D3DCOMPILER_H__ - -#define D3DCOMPILE_DEBUG 0x00000001 -#define D3DCOMPILE_SKIP_VALIDATION 0x00000002 -#define D3DCOMPILE_SKIP_OPTIMIZATION 0x00000004 -#define D3DCOMPILE_PACK_MATRIX_ROW_MAJOR 0x00000008 -#define D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR 0x00000010 -#define D3DCOMPILE_PARTIAL_PRECISION 0x00000020 -#define D3DCOMPILE_FORCE_VS_SOFTWARE_NO_OPT 0x00000040 -#define D3DCOMPILE_FORCE_PS_SOFTWARE_NO_OPT 0x00000080 -#define D3DCOMPILE_NO_PRESHADER 0x00000100 -#define D3DCOMPILE_AVOID_FLOW_CONTROL 0x00000200 -#define D3DCOMPILE_PREFER_FLOW_CONTROL 0x00000400 -#define D3DCOMPILE_ENABLE_STRICTNESS 0x00000800 -#define D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY 0x00001000 -#define D3DCOMPILE_IEEE_STRICTNESS 0x00002000 -#define D3DCOMPILE_OPTIMIZATION_LEVEL0 0x00004000 -#define D3DCOMPILE_OPTIMIZATION_LEVEL1 0x00000000 -#define D3DCOMPILE_OPTIMIZATION_LEVEL2 0x0000c000 -#define D3DCOMPILE_OPTIMIZATION_LEVEL3 0x00008000 -#define D3DCOMPILE_RESERVED16 0x00010000 -#define D3DCOMPILE_RESERVED17 0x00020000 -#define D3DCOMPILE_WARNINGS_ARE_ERRORS 0x00040000 -#define D3DCOMPILE_RESOURCES_MAY_ALIAS 0x00080000 -#define D3DCOMPILE_ENABLE_UNBOUNDED_DESCRIPTOR_TABLES 0x00100000 -#define D3DCOMPILE_ALL_RESOURCES_BOUND 0x00200000 -#define D3DCOMPILE_DEBUG_NAME_FOR_SOURCE 0x00400000 -#define D3DCOMPILE_DEBUG_NAME_FOR_BINARY 0x00800000 - -#define D3DCOMPILE_EFFECT_CHILD_EFFECT 0x00000001 -#define D3DCOMPILE_EFFECT_ALLOW_SLOW_OPS 0x00000002 - -#define D3DCOMPILE_FLAGS2_FORCE_ROOT_SIGNATURE_LATEST 0x00000000 -#define D3DCOMPILE_FLAGS2_FORCE_ROOT_SIGNATURE_1_0 0x00000010 -#define D3DCOMPILE_FLAGS2_FORCE_ROOT_SIGNATURE_1_1 0x00000020 - -#define D3DCOMPILE_SECDATA_MERGE_UAV_SLOTS 0x00000001 -#define D3DCOMPILE_SECDATA_PRESERVE_TEMPLATE_SLOTS 0x00000002 -#define D3DCOMPILE_SECDATA_REQUIRE_TEMPLATE_MATCH 0x00000004 - -HRESULT WINAPI D3DCompile(const void *data, SIZE_T data_size, const char *filename, - const D3D_SHADER_MACRO *macros, ID3DInclude *include, const char *entrypoint, - const char *profile, UINT flags, UINT effect_flags, ID3DBlob **shader, ID3DBlob **error_messages); -HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filename, - const D3D_SHADER_MACRO *macros, ID3DInclude *include, const char *entrypoint, - const char *profile, UINT flags, UINT effect_flags, UINT secondary_flags, - const void *secondary_data, SIZE_T secondary_data_size, ID3DBlob **shader, - ID3DBlob **error_messages); -HRESULT WINAPI D3DCreateBlob(SIZE_T size, ID3DBlob **blob); -HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, const char *filename, const D3D_SHADER_MACRO *macros, - ID3DInclude *include, ID3DBlob **shader, ID3DBlob **error_messages); - -#endif /* __D3DCOMPILER_H__ */ -#endif /* __VKD3D_D3DCOMPILER_H */ diff --git a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_d3dx9shader.idl b/dll/directx/wine/d3d12/vkd3d/include/vkd3d_d3dx9shader.idl deleted file mode 100644 index 4000ff298971a..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_d3dx9shader.idl +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2008 Luis Busquets - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -import "vkd3d_windows.h"; -import "vkd3d_d3d9types.h"; - -typedef enum _D3DXREGISTER_SET -{ - D3DXRS_BOOL, - D3DXRS_INT4, - D3DXRS_FLOAT4, - D3DXRS_SAMPLER, - D3DXRS_FORCE_DWORD = 0x7fffffff, -} D3DXREGISTER_SET; - -typedef enum D3DXPARAMETER_CLASS -{ - D3DXPC_SCALAR, - D3DXPC_VECTOR, - D3DXPC_MATRIX_ROWS, - D3DXPC_MATRIX_COLUMNS, - D3DXPC_OBJECT, - D3DXPC_STRUCT, - D3DXPC_FORCE_DWORD = 0x7fffffff, -} D3DXPARAMETER_CLASS; - -typedef enum D3DXPARAMETER_TYPE -{ - D3DXPT_VOID, - D3DXPT_BOOL, - D3DXPT_INT, - D3DXPT_FLOAT, - D3DXPT_STRING, - D3DXPT_TEXTURE, - D3DXPT_TEXTURE1D, - D3DXPT_TEXTURE2D, - D3DXPT_TEXTURE3D, - D3DXPT_TEXTURECUBE, - D3DXPT_SAMPLER, - D3DXPT_SAMPLER1D, - D3DXPT_SAMPLER2D, - D3DXPT_SAMPLER3D, - D3DXPT_SAMPLERCUBE, - D3DXPT_PIXELSHADER, - D3DXPT_VERTEXSHADER, - D3DXPT_PIXELFRAGMENT, - D3DXPT_VERTEXFRAGMENT, - D3DXPT_UNSUPPORTED, - D3DXPT_FORCE_DWORD = 0x7fffffff, -} D3DXPARAMETER_TYPE; - -typedef struct _D3DXSHADER_CONSTANTTABLE -{ - DWORD Size; - DWORD Creator; - DWORD Version; - DWORD Constants; - DWORD ConstantInfo; - DWORD Flags; - DWORD Target; -} D3DXSHADER_CONSTANTTABLE; diff --git a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_dxgi.idl b/dll/directx/wine/d3d12/vkd3d/include/vkd3d_dxgi.idl deleted file mode 100644 index 7e07a78dd3656..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_dxgi.idl +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright 2016 Józef Kucia for CodeWeavers - * Copyright 2016 Henri Verbeet for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -import "vkd3d_dxgitype.idl"; - -#include "vkd3d_unknown.idl" - -typedef enum DXGI_SWAP_EFFECT -{ - DXGI_SWAP_EFFECT_DISCARD = 0x0, - DXGI_SWAP_EFFECT_SEQUENTIAL = 0x1, - DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL = 0x3, - DXGI_SWAP_EFFECT_FLIP_DISCARD = 0x4, -} DXGI_SWAP_EFFECT; - -typedef enum DXGI_MODE_ROTATION -{ - DXGI_MODE_ROTATION_UNSPECIFIED = 0x0, - DXGI_MODE_ROTATION_IDENTITY = 0x1, - DXGI_MODE_ROTATION_ROTATE90 = 0x2, - DXGI_MODE_ROTATION_ROTATE180 = 0x3, - DXGI_MODE_ROTATION_ROTATE270 = 0x4, -} DXGI_MODE_ROTATION; - -interface IDXGIAdapter1; -interface IDXGIOutput; -typedef struct DXGI_SWAP_CHAIN_DESC DXGI_SWAP_CHAIN_DESC; -typedef struct DXGI_FRAME_STATISTICS DXGI_FRAME_STATISTICS; - -typedef UINT DXGI_USAGE; - -const DXGI_USAGE DXGI_USAGE_SHADER_INPUT = 0x00000010ul; -const DXGI_USAGE DXGI_USAGE_RENDER_TARGET_OUTPUT = 0x00000020ul; -const DXGI_USAGE DXGI_USAGE_BACK_BUFFER = 0x00000040ul; -const DXGI_USAGE DXGI_USAGE_SHARED = 0x00000080ul; -const DXGI_USAGE DXGI_USAGE_READ_ONLY = 0x00000100ul; -const DXGI_USAGE DXGI_USAGE_DISCARD_ON_PRESENT = 0x00000200ul; -const DXGI_USAGE DXGI_USAGE_UNORDERED_ACCESS = 0x00000400ul; - -typedef struct DXGI_ADAPTER_DESC -{ - WCHAR Description[128]; - UINT VendorId; - UINT DeviceId; - UINT SubSysId; - UINT Revision; - SIZE_T DedicatedVideoMemory; - SIZE_T DedicatedSystemMemory; - SIZE_T SharedSystemMemory; - LUID AdapterLuid; -} DXGI_ADAPTER_DESC; - -[ - local, - object, - uuid(aec22fb8-76f3-4639-9be0-28eb43a67a2e), - pointer_default(unique) -] -interface IDXGIObject : IUnknown -{ - HRESULT SetPrivateData(REFGUID name, UINT data_size, const void *data); - HRESULT GetPrivateDataInterface(REFGUID name, const IUnknown *unknown); - HRESULT GetPrivateData(REFGUID name, UINT *data_size, void *data); - HRESULT GetParent(REFIID riid, void **parent); -} - -[ - local, - object, - uuid(3d3e0379-f9de-4d58-bb6c-18d62992f1a6), - pointer_default(unique) -] -interface IDXGIDeviceSubObject : IDXGIObject -{ - HRESULT GetDevice(REFIID riid, void **device); -} - -[ - object, - local, - uuid(2411e7e1-12ac-4ccf-bd14-9798e8534dc0) -] -interface IDXGIAdapter : IDXGIObject -{ - HRESULT EnumOutputs(UINT output_idx, IDXGIOutput **output); - HRESULT GetDesc(DXGI_ADAPTER_DESC *desc); - HRESULT CheckInterfaceSupport(REFGUID guid, void *umd_version); -} - -[ - local, - object, - uuid(310d36a0-d2e7-4c0a-aa04-6a9d23b8886a), - pointer_default(unique) -] -interface IDXGISwapChain : IDXGIDeviceSubObject -{ - HRESULT Present(UINT sync_interval, UINT flags); - HRESULT GetBuffer(UINT buffer_idx, REFIID riid, void **surface); - HRESULT SetFullscreenState(BOOL fullscreen, IDXGIOutput *target); - HRESULT GetFullscreenState(BOOL *fullscreen, IDXGIOutput **target); - HRESULT GetDesc(DXGI_SWAP_CHAIN_DESC *desc); - HRESULT ResizeBuffers(UINT buffer_count, UINT width, UINT height, DXGI_FORMAT format, UINT flags); - HRESULT ResizeTarget(const DXGI_MODE_DESC *desc); - HRESULT GetContainingOutput(IDXGIOutput **output); - HRESULT GetFrameStatistics(DXGI_FRAME_STATISTICS *stats); - HRESULT GetLastPresentCount(UINT *last_present_count); -} - -[ - local, - object, - uuid(7b7166ec-21c7-44ae-b21a-c9ae321ae369), - pointer_default(unique) -] -interface IDXGIFactory : IDXGIObject -{ - HRESULT EnumAdapters(UINT adapter_idx, IDXGIAdapter **adapter); - HRESULT MakeWindowAssociation(HWND hwnd, UINT flags); - HRESULT GetWindowAssociation(HWND *hwnd); - HRESULT CreateSwapChain(IUnknown *device, DXGI_SWAP_CHAIN_DESC *desc, IDXGISwapChain **swapchain); - HRESULT CreateSoftwareAdapter(HMODULE hmodule, IDXGIAdapter **adapter); -} - -[ - local, - object, - uuid(770aae78-f26f-4dba-a829-253c83d1b387), - pointer_default(unique) -] -interface IDXGIFactory1 : IDXGIFactory -{ - HRESULT EnumAdapters1(UINT adapter_idx, IDXGIAdapter1 **adpter); - BOOL IsCurrent(); -} - -[local] HRESULT __stdcall CreateDXGIFactory(REFIID riid, void **factory); -[local] HRESULT __stdcall CreateDXGIFactory1(REFIID riid, void **factory); diff --git a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_dxgi1_2.idl b/dll/directx/wine/d3d12/vkd3d/include/vkd3d_dxgi1_2.idl deleted file mode 100644 index e7f951ac9172b..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_dxgi1_2.idl +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2016 Józef Kucia for CodeWeavers - * Copyright 2016 Henri Verbeet for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -import "vkd3d_dxgi.idl"; - -typedef enum DXGI_SCALING -{ - DXGI_SCALING_STRETCH = 0x0, - DXGI_SCALING_NONE = 0x1, - DXGI_SCALING_ASPECT_RATIO_STRETCH = 0x2, - DXGI_SCALING_FORCE_DWORD = 0xffffffff, -} DXGI_SCALING; - -typedef enum DXGI_ALPHA_MODE -{ - DXGI_ALPHA_MODE_UNSPECIFIED = 0x0, - DXGI_ALPHA_MODE_PREMULTIPLIED = 0x1, - DXGI_ALPHA_MODE_STRAIGHT = 0x2, - DXGI_ALPHA_MODE_IGNORE = 0x3, - DXGI_ALPHA_MODE_FORCE_DWORD = 0xffffffff, -} DXGI_ALPHA_MODE; - -typedef struct DXGI_SWAP_CHAIN_DESC1 -{ - UINT Width; - UINT Height; - DXGI_FORMAT Format; - BOOL Stereo; - DXGI_SAMPLE_DESC SampleDesc; - DXGI_USAGE BufferUsage; - UINT BufferCount; - DXGI_SCALING Scaling; - DXGI_SWAP_EFFECT SwapEffect; - DXGI_ALPHA_MODE AlphaMode; - UINT Flags; -} DXGI_SWAP_CHAIN_DESC1; - -typedef struct DXGI_SWAP_CHAIN_FULLSCREEN_DESC DXGI_SWAP_CHAIN_FULLSCREEN_DESC; -typedef struct DXGI_PRESENT_PARAMETERS DXGI_PRESENT_PARAMETERS; - -[ - local, - object, - uuid(790a45f7-0d42-4876-983a-0a55cfe6f4aa), - pointer_default(unique) -] -interface IDXGISwapChain1 : IDXGISwapChain -{ - HRESULT GetDesc1(DXGI_SWAP_CHAIN_DESC1 *desc); - HRESULT GetFullscreenDesc(DXGI_SWAP_CHAIN_FULLSCREEN_DESC *desc); - HRESULT GetHwnd(HWND *hwnd); - HRESULT GetCoreWindow(REFIID riid, void **object); - HRESULT Present1(UINT sync_interval, UINT flags, const DXGI_PRESENT_PARAMETERS *parameters); - BOOL IsTemporaryMonoSupported(); - HRESULT GetRestrictToOutput(IDXGIOutput **output); - HRESULT SetBackgroundColor(const DXGI_RGBA *color); - HRESULT GetBackgroundColor(DXGI_RGBA *color); - HRESULT SetRotation(DXGI_MODE_ROTATION rotation); - HRESULT GetRotation(DXGI_MODE_ROTATION *rotation); -} - -[ - local, - object, - uuid(50c83a1c-e072-4c48-87b0-3630fa36a6d0), - pointer_default(unique) -] -interface IDXGIFactory2 : IDXGIFactory1 -{ - BOOL IsWindowedStereoEnabled(); - HRESULT CreateSwapChainForHwnd(IUnknown *device, HWND window, const DXGI_SWAP_CHAIN_DESC1 *desc, - const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *fullscreen_desc, IDXGIOutput *output, IDXGISwapChain1 **swapchain); - HRESULT CreateSwapChainForCoreWindow(IUnknown *device, IUnknown *window, const DXGI_SWAP_CHAIN_DESC1 *desc, - IDXGIOutput *output, IDXGISwapChain1 **swapchain); - HRESULT GetSharedResourceAdapterLuid(HANDLE resource, LUID *luid); - HRESULT RegisterStereoStatusWindow(HWND window, UINT msg, DWORD *cookie); - HRESULT RegisterStereoStatusEvent(HANDLE event, DWORD *cookie); - void UnregisterStereoStatus(DWORD cookie); - HRESULT RegisterOcclusionStatusWindow(HWND window, UINT msg, DWORD *cookie); - HRESULT RegisterOcclusionStatusEvent(HANDLE event, DWORD *cookie); - void UnregisterOcclusionStatus(DWORD cookie); - HRESULT CreateSwapChainForComposition(IUnknown *device, const DXGI_SWAP_CHAIN_DESC1 *desc, - IDXGIOutput *output, IDXGISwapChain1 **swapchain); -} diff --git a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_dxgi1_3.idl b/dll/directx/wine/d3d12/vkd3d/include/vkd3d_dxgi1_3.idl deleted file mode 100644 index 88ac0a34f702f..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_dxgi1_3.idl +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2016 Józef Kucia for CodeWeavers - * Copyright 2016 Henri Verbeet for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -import "vkd3d_dxgi1_2.idl"; - -typedef struct DXGI_MATRIX_3X2_F DXGI_MATRIX_3X2_F; - -[ - local, - object, - uuid(a8be2ac4-199f-4946-b331-79599fb98de7), - pointer_default(unique) -] -interface IDXGISwapChain2 : IDXGISwapChain1 -{ - HRESULT SetSourceSize(UINT width, UINT height); - HRESULT GetSourceSize(UINT *width, UINT *height); - HRESULT SetMaximumFrameLatency(UINT latency); - HRESULT GetMaximumFrameLatency(UINT *latency); - HANDLE GetFrameLatencyWaitableObject(); - HRESULT SetMatrixTransform(const DXGI_MATRIX_3X2_F *matrix); - HRESULT GetMatrixTransform(DXGI_MATRIX_3X2_F *matrix); -} - -[ - local, - object, - uuid(25483823-cd46-4c7d-86ca-47aa95b837bd), - pointer_default(unique) -] -interface IDXGIFactory3 : IDXGIFactory2 -{ - UINT GetCreationFlags(); -} diff --git a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_dxgi1_4.idl b/dll/directx/wine/d3d12/vkd3d/include/vkd3d_dxgi1_4.idl deleted file mode 100644 index ccd2224c82def..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_dxgi1_4.idl +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2016 Józef Kucia for CodeWeavers - * Copyright 2016 Henri Verbeet for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -import "vkd3d_dxgi1_3.idl"; - -[ - local, - object, - uuid(94d99bdb-f1f8-4ab0-b236-7da0170edab1), - pointer_default(unique) -] -interface IDXGISwapChain3 : IDXGISwapChain2 -{ - UINT GetCurrentBackBufferIndex(); - HRESULT CheckColorSpaceSupport(DXGI_COLOR_SPACE_TYPE type, UINT *support); - HRESULT SetColorSpace1(DXGI_COLOR_SPACE_TYPE type); - HRESULT ResizeBuffers1(UINT buffer_count, UINT width, UINT height, DXGI_FORMAT format, - UINT flags, const UINT *node_mask, IUnknown *const *present_queue); -} - -[ - local, - object, - uuid(1bc6ea02-ef36-464f-bf0c-21ca39e5168a), - pointer_default(unique), -] -interface IDXGIFactory4 : IDXGIFactory3 -{ - HRESULT EnumAdapterByLuid(LUID luid, REFIID iid, void **adapter); - HRESULT EnumWarpAdapter(REFIID iid, void **adapter); -} diff --git a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_dxgibase.idl b/dll/directx/wine/d3d12/vkd3d/include/vkd3d_dxgibase.idl deleted file mode 100644 index 93f931e094442..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_dxgibase.idl +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2016 Józef Kucia for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -import "vkd3d_windows.h"; - -import "vkd3d_dxgiformat.idl"; - -cpp_quote("#ifndef DXGI_ERROR_INVALID_CALL") -cpp_quote("#define DXGI_ERROR_INVALID_CALL _HRESULT_TYPEDEF_(0x887a0001)") -cpp_quote("#endif") -cpp_quote("#ifndef DXGI_ERROR_DEVICE_REMOVED") -cpp_quote("#define DXGI_ERROR_DEVICE_REMOVED _HRESULT_TYPEDEF_(0x887a0005)") -cpp_quote("#endif") - -typedef struct DXGI_SAMPLE_DESC -{ - UINT Count; - UINT Quality; -} DXGI_SAMPLE_DESC; diff --git a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_dxgiformat.idl b/dll/directx/wine/d3d12/vkd3d/include/vkd3d_dxgiformat.idl deleted file mode 100644 index 63129bbefa14a..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_dxgiformat.idl +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2016 Józef Kucia for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -typedef enum DXGI_FORMAT -{ - DXGI_FORMAT_UNKNOWN = 0x00, - DXGI_FORMAT_R32G32B32A32_TYPELESS = 0x01, - DXGI_FORMAT_R32G32B32A32_FLOAT = 0x02, - DXGI_FORMAT_R32G32B32A32_UINT = 0x03, - DXGI_FORMAT_R32G32B32A32_SINT = 0x04, - DXGI_FORMAT_R32G32B32_TYPELESS = 0x05, - DXGI_FORMAT_R32G32B32_FLOAT = 0x06, - DXGI_FORMAT_R32G32B32_UINT = 0x07, - DXGI_FORMAT_R32G32B32_SINT = 0x08, - DXGI_FORMAT_R16G16B16A16_TYPELESS = 0x09, - DXGI_FORMAT_R16G16B16A16_FLOAT = 0x0a, - DXGI_FORMAT_R16G16B16A16_UNORM = 0x0b, - DXGI_FORMAT_R16G16B16A16_UINT = 0x0c, - DXGI_FORMAT_R16G16B16A16_SNORM = 0x0d, - DXGI_FORMAT_R16G16B16A16_SINT = 0x0e, - DXGI_FORMAT_R32G32_TYPELESS = 0x0f, - DXGI_FORMAT_R32G32_FLOAT = 0x10, - DXGI_FORMAT_R32G32_UINT = 0x11, - DXGI_FORMAT_R32G32_SINT = 0x12, - DXGI_FORMAT_R32G8X24_TYPELESS = 0x13, - DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 0x14, - DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 0x15, - DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 0x16, - DXGI_FORMAT_R10G10B10A2_TYPELESS = 0x17, - DXGI_FORMAT_R10G10B10A2_UNORM = 0x18, - DXGI_FORMAT_R10G10B10A2_UINT = 0x19, - DXGI_FORMAT_R11G11B10_FLOAT = 0x1a, - DXGI_FORMAT_R8G8B8A8_TYPELESS = 0x1b, - DXGI_FORMAT_R8G8B8A8_UNORM = 0x1c, - DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 0x1d, - DXGI_FORMAT_R8G8B8A8_UINT = 0x1e, - DXGI_FORMAT_R8G8B8A8_SNORM = 0x1f, - DXGI_FORMAT_R8G8B8A8_SINT = 0x20, - DXGI_FORMAT_R16G16_TYPELESS = 0x21, - DXGI_FORMAT_R16G16_FLOAT = 0x22, - DXGI_FORMAT_R16G16_UNORM = 0x23, - DXGI_FORMAT_R16G16_UINT = 0x24, - DXGI_FORMAT_R16G16_SNORM = 0x25, - DXGI_FORMAT_R16G16_SINT = 0x26, - DXGI_FORMAT_R32_TYPELESS = 0x27, - DXGI_FORMAT_D32_FLOAT = 0x28, - DXGI_FORMAT_R32_FLOAT = 0x29, - DXGI_FORMAT_R32_UINT = 0x2a, - DXGI_FORMAT_R32_SINT = 0x2b, - DXGI_FORMAT_R24G8_TYPELESS = 0x2c, - DXGI_FORMAT_D24_UNORM_S8_UINT = 0x2d, - DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 0x2e, - DXGI_FORMAT_X24_TYPELESS_G8_UINT = 0x2f, - DXGI_FORMAT_R8G8_TYPELESS = 0x30, - DXGI_FORMAT_R8G8_UNORM = 0x31, - DXGI_FORMAT_R8G8_UINT = 0x32, - DXGI_FORMAT_R8G8_SNORM = 0x33, - DXGI_FORMAT_R8G8_SINT = 0x34, - DXGI_FORMAT_R16_TYPELESS = 0x35, - DXGI_FORMAT_R16_FLOAT = 0x36, - DXGI_FORMAT_D16_UNORM = 0x37, - DXGI_FORMAT_R16_UNORM = 0x38, - DXGI_FORMAT_R16_UINT = 0x39, - DXGI_FORMAT_R16_SNORM = 0x3a, - DXGI_FORMAT_R16_SINT = 0x3b, - DXGI_FORMAT_R8_TYPELESS = 0x3c, - DXGI_FORMAT_R8_UNORM = 0x3d, - DXGI_FORMAT_R8_UINT = 0x3e, - DXGI_FORMAT_R8_SNORM = 0x3f, - DXGI_FORMAT_R8_SINT = 0x40, - DXGI_FORMAT_A8_UNORM = 0x41, - DXGI_FORMAT_R1_UNORM = 0x42, - DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 0x43, - DXGI_FORMAT_R8G8_B8G8_UNORM = 0x44, - DXGI_FORMAT_G8R8_G8B8_UNORM = 0x45, - DXGI_FORMAT_BC1_TYPELESS = 0x46, - DXGI_FORMAT_BC1_UNORM = 0x47, - DXGI_FORMAT_BC1_UNORM_SRGB = 0x48, - DXGI_FORMAT_BC2_TYPELESS = 0x49, - DXGI_FORMAT_BC2_UNORM = 0x4a, - DXGI_FORMAT_BC2_UNORM_SRGB = 0x4b, - DXGI_FORMAT_BC3_TYPELESS = 0x4c, - DXGI_FORMAT_BC3_UNORM = 0x4d, - DXGI_FORMAT_BC3_UNORM_SRGB = 0x4e, - DXGI_FORMAT_BC4_TYPELESS = 0x4f, - DXGI_FORMAT_BC4_UNORM = 0x50, - DXGI_FORMAT_BC4_SNORM = 0x51, - DXGI_FORMAT_BC5_TYPELESS = 0x52, - DXGI_FORMAT_BC5_UNORM = 0x53, - DXGI_FORMAT_BC5_SNORM = 0x54, - DXGI_FORMAT_B5G6R5_UNORM = 0x55, - DXGI_FORMAT_B5G5R5A1_UNORM = 0x56, - DXGI_FORMAT_B8G8R8A8_UNORM = 0x57, - DXGI_FORMAT_B8G8R8X8_UNORM = 0x58, - DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 0x59, - DXGI_FORMAT_B8G8R8A8_TYPELESS = 0x5a, - DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 0x5b, - DXGI_FORMAT_B8G8R8X8_TYPELESS = 0x5c, - DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 0x5d, - DXGI_FORMAT_BC6H_TYPELESS = 0x5e, - DXGI_FORMAT_BC6H_UF16 = 0x5f, - DXGI_FORMAT_BC6H_SF16 = 0x60, - DXGI_FORMAT_BC7_TYPELESS = 0x61, - DXGI_FORMAT_BC7_UNORM = 0x62, - DXGI_FORMAT_BC7_UNORM_SRGB = 0x63, - DXGI_FORMAT_AYUV = 0x64, - DXGI_FORMAT_Y410 = 0x65, - DXGI_FORMAT_Y416 = 0x66, - DXGI_FORMAT_NV12 = 0x67, - DXGI_FORMAT_P010 = 0x68, - DXGI_FORMAT_P016 = 0x69, - DXGI_FORMAT_420_OPAQUE = 0x6a, - DXGI_FORMAT_YUY2 = 0x6b, - DXGI_FORMAT_Y210 = 0x6c, - DXGI_FORMAT_Y216 = 0x6d, - DXGI_FORMAT_NV11 = 0x6e, - DXGI_FORMAT_AI44 = 0x6f, - DXGI_FORMAT_IA44 = 0x70, - DXGI_FORMAT_P8 = 0x71, - DXGI_FORMAT_A8P8 = 0x72, - DXGI_FORMAT_B4G4R4A4_UNORM = 0x73, - - DXGI_FORMAT_FORCE_UINT = 0xffffffff, -} DXGI_FORMAT; diff --git a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_dxgitype.idl b/dll/directx/wine/d3d12/vkd3d/include/vkd3d_dxgitype.idl deleted file mode 100644 index 74806c0ce41c2..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_dxgitype.idl +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2016 Józef Kucia for CodeWeavers - * Copyright 2016 Henri Verbeet for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -import "vkd3d_windows.h"; -import "vkd3d_dxgibase.idl"; - -typedef enum DXGI_COLOR_SPACE_TYPE -{ - DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709 = 0x0, - DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709 = 0x1, - DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P709 = 0x2, - DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P2020 = 0x3, - DXGI_COLOR_SPACE_RESERVED = 0x4, - DXGI_COLOR_SPACE_YCBCR_FULL_G22_NONE_P709_X601 = 0x5, - DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P601 = 0x6, - DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P601 = 0x7, - DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709 = 0x8, - DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P709 = 0x9, - DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P2020 = 0xa, - DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P2020 = 0xb, - DXGI_COLOR_SPACE_CUSTOM = 0xffffffff, -} DXGI_COLOR_SPACE_TYPE; - -typedef struct _D3DCOLORVALUE D3DCOLORVALUE, DXGI_RGBA; -typedef struct DXGI_MODE_DESC DXGI_MODE_DESC; diff --git a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_shader.h b/dll/directx/wine/d3d12/vkd3d/include/vkd3d_shader.h deleted file mode 100644 index 05d235f9de68c..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_shader.h +++ /dev/null @@ -1,1866 +0,0 @@ -/* - * Copyright 2017-2019 Józef Kucia for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef __VKD3D_SHADER_H -#define __VKD3D_SHADER_H - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/** - * \file vkd3d_shader.h - * - * \since 1.2 - * - * This file contains definitions for the vkd3d-shader library. - * - * The vkd3d-shader library provides multiple utilities related to the - * compilation, transformation, and reflection of GPU shaders. - */ - -/** \since 1.3 */ -enum vkd3d_shader_api_version -{ - VKD3D_SHADER_API_VERSION_1_0, - VKD3D_SHADER_API_VERSION_1_1, - VKD3D_SHADER_API_VERSION_1_2, - VKD3D_SHADER_API_VERSION_1_3, -}; - -/** The type of a chained structure. */ -enum vkd3d_shader_structure_type -{ - /** The structure is a vkd3d_shader_compile_info structure. */ - VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO, - /** The structure is a vkd3d_shader_interface_info structure. */ - VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO, - /** The structure is a vkd3d_shader_scan_descriptor_info structure. */ - VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO, - /** The structure is a vkd3d_shader_spirv_domain_shader_target_info structure. */ - VKD3D_SHADER_STRUCTURE_TYPE_SPIRV_DOMAIN_SHADER_TARGET_INFO, - /** The structure is a vkd3d_shader_spirv_target_info structure. */ - VKD3D_SHADER_STRUCTURE_TYPE_SPIRV_TARGET_INFO, - /** The structure is a vkd3d_shader_transform_feedback_info structure. */ - VKD3D_SHADER_STRUCTURE_TYPE_TRANSFORM_FEEDBACK_INFO, - - /** - * The structure is a vkd3d_shader_hlsl_source_info structure. - * \since 1.3 - */ - VKD3D_SHADER_STRUCTURE_TYPE_HLSL_SOURCE_INFO, - /** - * The structure is a vkd3d_shader_preprocess_info structure. - * \since 1.3 - */ - VKD3D_SHADER_STRUCTURE_TYPE_PREPROCESS_INFO, - /** - * The structure is a vkd3d_shader_descriptor_offset_info structure. - * \since 1.3 - */ - VKD3D_SHADER_STRUCTURE_TYPE_DESCRIPTOR_OFFSET_INFO, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE), -}; - -/** - * Determines how buffer UAVs are stored. - * - * This also affects UAV counters in Vulkan environments. In OpenGL - * environments, atomic counter buffers are always used for UAV counters. - */ -enum vkd3d_shader_compile_option_buffer_uav -{ - /** Use buffer textures for buffer UAVs. This is the default value. */ - VKD3D_SHADER_COMPILE_OPTION_BUFFER_UAV_STORAGE_TEXEL_BUFFER = 0x00000000, - /** Use storage buffers for buffer UAVs. */ - VKD3D_SHADER_COMPILE_OPTION_BUFFER_UAV_STORAGE_BUFFER = 0x00000001, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_BUFFER_UAV), -}; - -enum vkd3d_shader_compile_option_formatting_flags -{ - VKD3D_SHADER_COMPILE_OPTION_FORMATTING_NONE = 0x00000000, - VKD3D_SHADER_COMPILE_OPTION_FORMATTING_COLOUR = 0x00000001, - VKD3D_SHADER_COMPILE_OPTION_FORMATTING_INDENT = 0x00000002, - VKD3D_SHADER_COMPILE_OPTION_FORMATTING_OFFSETS = 0x00000004, - VKD3D_SHADER_COMPILE_OPTION_FORMATTING_HEADER = 0x00000008, - VKD3D_SHADER_COMPILE_OPTION_FORMATTING_RAW_IDS = 0x00000010, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_FORMATTING_FLAGS), -}; - -enum vkd3d_shader_compile_option_name -{ - /** - * If \a value is nonzero, do not include debug information in the - * compiled shader. The default value is zero. - * - * This option is supported by vkd3d_shader_compile(). However, not all - * compilers support generating debug information. - */ - VKD3D_SHADER_COMPILE_OPTION_STRIP_DEBUG = 0x00000001, - /** \a value is a member of enum vkd3d_shader_compile_option_buffer_uav. */ - VKD3D_SHADER_COMPILE_OPTION_BUFFER_UAV = 0x00000002, - /** \a value is a member of enum vkd3d_shader_compile_option_formatting_flags. */ - VKD3D_SHADER_COMPILE_OPTION_FORMATTING = 0x00000003, - /** \a value is a member of enum vkd3d_shader_api_version. \since 1.3 */ - VKD3D_SHADER_COMPILE_OPTION_API_VERSION = 0x00000004, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_NAME), -}; - -/** - * Various settings which may affect shader compilation or scanning, passed as - * part of struct vkd3d_shader_compile_info. For more details, see the - * documentation for individual options. - */ -struct vkd3d_shader_compile_option -{ - /** Name of the option. */ - enum vkd3d_shader_compile_option_name name; - /** - * A value associated with the option. The type and interpretation of the - * value depends on the option in question. - */ - unsigned int value; -}; - -/** Describes which shader stages a resource is visible to. */ -enum vkd3d_shader_visibility -{ - /** The resource is visible to all shader stages. */ - VKD3D_SHADER_VISIBILITY_ALL = 0, - /** The resource is visible only to the vertex shader. */ - VKD3D_SHADER_VISIBILITY_VERTEX = 1, - /** The resource is visible only to the hull shader. */ - VKD3D_SHADER_VISIBILITY_HULL = 2, - /** The resource is visible only to the domain shader. */ - VKD3D_SHADER_VISIBILITY_DOMAIN = 3, - /** The resource is visible only to the geometry shader. */ - VKD3D_SHADER_VISIBILITY_GEOMETRY = 4, - /** The resource is visible only to the pixel shader. */ - VKD3D_SHADER_VISIBILITY_PIXEL = 5, - - /** The resource is visible only to the compute shader. */ - VKD3D_SHADER_VISIBILITY_COMPUTE = 1000000000, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_VISIBILITY), -}; - -/** A generic structure containing a GPU shader, in text or byte-code format. */ -struct vkd3d_shader_code -{ - /** - * Pointer to the code. Note that textual formats are not null-terminated. - * Therefore \a size should not include a null terminator, when this - * structure is passed as input to a vkd3d-shader function, and the - * allocated string will not include a null terminator when this structure - * is used as output. - */ - const void *code; - /** Size of \a code, in bytes. */ - size_t size; -}; - -/** The type of a shader resource descriptor. */ -enum vkd3d_shader_descriptor_type -{ - /** - * The descriptor is a shader resource view. In Direct3D assembly, this is - * bound to a t# register. - */ - VKD3D_SHADER_DESCRIPTOR_TYPE_SRV = 0x0, - /** - * The descriptor is an unordered access view. In Direct3D assembly, this is - * bound to a u# register. - */ - VKD3D_SHADER_DESCRIPTOR_TYPE_UAV = 0x1, - /** - * The descriptor is a constant buffer view. In Direct3D assembly, this is - * bound to a cb# register. - */ - VKD3D_SHADER_DESCRIPTOR_TYPE_CBV = 0x2, - /** - * The descriptor is a sampler. In Direct3D assembly, this is bound to an s# - * register. - */ - VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER = 0x3, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_DESCRIPTOR_TYPE), -}; - -/** - * A common structure describing the bind point of a descriptor or descriptor - * array in the target environment. - */ -struct vkd3d_shader_descriptor_binding -{ - /** - * The set of the 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 descriptor. */ - unsigned int binding; - /** - * The size of this descriptor array. If an offset is specified for this - * binding by the vkd3d_shader_descriptor_offset_info structure, counting - * starts at that offset. - */ - unsigned int count; -}; - -enum vkd3d_shader_binding_flag -{ - VKD3D_SHADER_BINDING_FLAG_BUFFER = 0x00000001, - VKD3D_SHADER_BINDING_FLAG_IMAGE = 0x00000002, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_BINDING_FLAG), -}; - -enum vkd3d_shader_parameter_type -{ - VKD3D_SHADER_PARAMETER_TYPE_UNKNOWN, - VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT, - VKD3D_SHADER_PARAMETER_TYPE_SPECIALIZATION_CONSTANT, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_PARAMETER_TYPE), -}; - -enum vkd3d_shader_parameter_data_type -{ - VKD3D_SHADER_PARAMETER_DATA_TYPE_UNKNOWN, - VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_PARAMETER_DATA_TYPE), -}; - -enum vkd3d_shader_parameter_name -{ - VKD3D_SHADER_PARAMETER_NAME_UNKNOWN, - VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_PARAMETER_NAME), -}; - -struct vkd3d_shader_parameter_immediate_constant -{ - union - { - uint32_t u32; - } u; -}; - -struct vkd3d_shader_parameter_specialization_constant -{ - uint32_t id; -}; - -struct vkd3d_shader_parameter -{ - enum vkd3d_shader_parameter_name name; - enum vkd3d_shader_parameter_type type; - enum vkd3d_shader_parameter_data_type data_type; - union - { - struct vkd3d_shader_parameter_immediate_constant immediate_constant; - struct vkd3d_shader_parameter_specialization_constant specialization_constant; - } u; -}; - -/** - * Describes the mapping of a single resource or resource array to its binding - * point in the target environment. - * - * For example, to map a Direct3D SRV with register space 2, register "t3" to - * a Vulkan descriptor in set 4 and with binding 5, set the following members: - * - \a type = VKD3D_SHADER_DESCRIPTOR_TYPE_SRV - * - \a register_space = 2 - * - \a register_index = 3 - * - \a binding.set = 4 - * - \a binding.binding = 5 - * - \a binding.count = 1 - * - * This structure is used in struct vkd3d_shader_interface_info. - */ -struct vkd3d_shader_resource_binding -{ - /** The type of this descriptor. */ - enum vkd3d_shader_descriptor_type type; - /** - * Register space of the Direct3D resource. If the source format does not - * support multiple register spaces, this parameter must be set to 0. - */ - unsigned int register_space; - /** Register index of the DXBC resource. */ - unsigned int register_index; - /** Shader stage(s) to which the resource is visible. */ - enum vkd3d_shader_visibility shader_visibility; - /** A combination of zero or more elements of vkd3d_shader_binding_flag. */ - unsigned int flags; - - /** The binding in the target environment. */ - struct vkd3d_shader_descriptor_binding binding; -}; - -#define VKD3D_SHADER_DUMMY_SAMPLER_INDEX ~0u - -/** - * Describes the mapping of a Direct3D resource-sampler pair to a combined - * sampler (i.e. sampled image). - * - * This structure is used in struct vkd3d_shader_interface_info. - */ -struct vkd3d_shader_combined_resource_sampler -{ - /** - * Register space of the Direct3D resource. If the source format does not - * support multiple register spaces, this parameter must be set to 0. - */ - unsigned int resource_space; - /** Register index of the Direct3D resource. */ - unsigned int resource_index; - /** - * Register space of the Direct3D sampler. If the source format does not - * support multiple register spaces, this parameter must be set to 0. - */ - unsigned int sampler_space; - /** Register index of the Direct3D sampler. */ - unsigned int sampler_index; - /** Shader stage(s) to which the resource is visible. */ - enum vkd3d_shader_visibility shader_visibility; - /** A combination of zero or more elements of vkd3d_shader_binding_flag. */ - unsigned int flags; - - /** The binding in the target environment. */ - struct vkd3d_shader_descriptor_binding binding; -}; - -/** - * Describes the mapping of a single Direct3D UAV counter. - * - * This structure is used in struct vkd3d_shader_interface_info. - */ -struct vkd3d_shader_uav_counter_binding -{ - /** - * Register space of the Direct3D UAV descriptor. If the source format does - * not support multiple register spaces, this parameter must be set to 0. - */ - unsigned int register_space; - /** Register index of the Direct3D UAV descriptor. */ - unsigned int register_index; - /** Shader stage(s) to which the UAV counter is visible. */ - enum vkd3d_shader_visibility shader_visibility; - - /** The binding in the target environment. */ - struct vkd3d_shader_descriptor_binding binding; - unsigned int offset; -}; - -/** - * Describes the mapping of a Direct3D constant buffer to a range of push - * constants in the target environment. - * - * This structure is used in struct vkd3d_shader_interface_info. - */ -struct vkd3d_shader_push_constant_buffer -{ - /** - * Register space of the Direct3D resource. If the source format does not - * support multiple register spaces, this parameter must be set to 0. - */ - unsigned int register_space; - /** Register index of the Direct3D resource. */ - unsigned int register_index; - /** Shader stage(s) to which the resource is visible. */ - enum vkd3d_shader_visibility shader_visibility; - - /** Offset, in bytes, of the target push constants. */ - unsigned int offset; - /** Size, in bytes, of the target push constants. */ - unsigned int size; -}; - -/** - * A chained structure describing the interface between a compiled shader and - * the target environment. - * - * For example, when compiling Direct3D shader byte code to SPIR-V, this - * structure contains mappings from Direct3D descriptor registers to SPIR-V - * descriptor bindings. - * - * This structure is optional. If omitted, vkd3d_shader_compile() will use a - * default mapping, in which resources are mapped to sequential bindings in - * register set 0. - * - * This structure extends vkd3d_shader_compile_info. - * - * This structure contains only input parameters. - */ -struct vkd3d_shader_interface_info -{ - /** Must be set to VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO. */ - enum vkd3d_shader_structure_type type; - /** Optional pointer to a structure containing further parameters. */ - const void *next; - - /** Pointer to an array of bindings for shader resource descriptors. */ - const struct vkd3d_shader_resource_binding *bindings; - /** Size, in elements, of \ref bindings. */ - unsigned int binding_count; - - /** Pointer to an array of bindings for push constant buffers. */ - const struct vkd3d_shader_push_constant_buffer *push_constant_buffers; - /** Size, in elements, of \ref push_constant_buffers. */ - unsigned int push_constant_buffer_count; - - /** Pointer to an array of bindings for combined samplers. */ - const struct vkd3d_shader_combined_resource_sampler *combined_samplers; - /** Size, in elements, of \ref combined_samplers. */ - unsigned int combined_sampler_count; - - /** Pointer to an array of bindings for UAV counters. */ - const struct vkd3d_shader_uav_counter_binding *uav_counters; - /** Size, in elements, of \ref uav_counters. */ - unsigned int uav_counter_count; -}; - -struct vkd3d_shader_transform_feedback_element -{ - unsigned int stream_index; - const char *semantic_name; - unsigned int semantic_index; - uint8_t component_index; - uint8_t component_count; - uint8_t output_slot; -}; - -/* Extends vkd3d_shader_interface_info. */ -struct vkd3d_shader_transform_feedback_info -{ - enum vkd3d_shader_structure_type type; - const void *next; - - const struct vkd3d_shader_transform_feedback_element *elements; - unsigned int element_count; - const unsigned int *buffer_strides; - unsigned int buffer_stride_count; -}; - -struct vkd3d_shader_descriptor_offset -{ - unsigned int static_offset; - unsigned int dynamic_offset_index; -}; - -/** - * A chained structure containing descriptor offsets. - * - * This structure is optional. - * - * This structure extends vkd3d_shader_interface_info. - * - * This structure contains only input parameters. - * - * \since 1.3 - */ -struct vkd3d_shader_descriptor_offset_info -{ - /** Must be set to VKD3D_SHADER_STRUCTURE_TYPE_DESCRIPTOR_OFFSET_INFO. */ - enum vkd3d_shader_structure_type type; - /** Optional pointer to a structure containing further parameters. */ - const void *next; - - /** - * Byte offset within the push constants of an array of 32-bit - * descriptor array offsets. See the description of 'binding_offsets' - * below. - */ - unsigned int descriptor_table_offset; - /** Size, in elements, of the descriptor table push constant array. */ - unsigned int descriptor_table_count; - - /** - * Pointer to an array of struct vkd3d_shader_descriptor_offset objects. - * The 'static_offset' field contains an offset into the descriptor arrays - * referenced by the 'bindings' array in struct vkd3d_shader_interface_info. - * This allows mapping multiple shader resource arrays to a single binding - * point in the target environment. - * - * 'dynamic_offset_index' in struct vkd3d_shader_descriptor_offset allows - * offsets to be set at runtime. The 32-bit descriptor table push constant - * at this index will be added to 'static_offset' to calculate the final - * binding offset. - * - * If runtime offsets are not required, set all 'dynamic_offset_index' - * values to \c ~0u and 'descriptor_table_count' to zero. - * - * For example, to map Direct3D constant buffer registers 'cb0[0:3]' and - * 'cb1[6:7]' to descriptors 8-12 and 4-5 in the Vulkan descriptor array in - * descriptor set 3 and with binding 2, set the following values in the - * 'bindings' array in struct vkd3d_shader_interface_info: - * - * \code - * type = VKD3D_SHADER_DESCRIPTOR_TYPE_CBV - * register_space = 0 - * register_index = 0 - * binding.set = 3 - * binding.binding = 2 - * binding.count = 4 - * - * type = VKD3D_SHADER_DESCRIPTOR_TYPE_CBV - * register_space = 0 - * register_index = 6 - * binding.set = 3 - * binding.binding = 2 - * binding.count = 2 - * \endcode - * - * and then pass \c {8, \c 4} as static binding offsets here. - * - * This field may be NULL, in which case the corresponding offsets are - * specified to be 0. - */ - const struct vkd3d_shader_descriptor_offset *binding_offsets; - - /** - * Pointer to an array of offsets into the descriptor arrays referenced by - * the 'uav_counters' array in struct vkd3d_shader_interface_info. This - * works the same way as \ref binding_offsets above. - */ - const struct vkd3d_shader_descriptor_offset *uav_counter_offsets; -}; - -/** The format of a shader to be compiled or scanned. */ -enum vkd3d_shader_source_type -{ - /** - * The shader has no type or is to be ignored. This is not a valid value - * for vkd3d_shader_compile() or vkd3d_shader_scan(). - */ - VKD3D_SHADER_SOURCE_NONE, - /** - * A 'Tokenized Program Format' shader embedded in a DXBC container. This is - * the format used for Direct3D shader model 4 and 5 shaders. - */ - VKD3D_SHADER_SOURCE_DXBC_TPF, - /** High-Level Shader Language source code. \since 1.3 */ - VKD3D_SHADER_SOURCE_HLSL, - /** - * Legacy Direct3D byte-code. This is the format used for Direct3D shader - * model 1, 2, and 3 shaders. \since 1.3 - */ - VKD3D_SHADER_SOURCE_D3D_BYTECODE, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_SOURCE_TYPE), -}; - -/** The output format of a compiled shader. */ -enum vkd3d_shader_target_type -{ - /** - * The shader has no type or is to be ignored. This is not a valid value - * for vkd3d_shader_compile() or vkd3d_shader_scan(). - */ - VKD3D_SHADER_TARGET_NONE, - /** - * A SPIR-V shader in binary form. This is the format used for Vulkan - * shaders. - */ - VKD3D_SHADER_TARGET_SPIRV_BINARY, - VKD3D_SHADER_TARGET_SPIRV_TEXT, - /** - * Direct3D shader assembly. \since 1.3 - */ - VKD3D_SHADER_TARGET_D3D_ASM, - /** - * Legacy Direct3D byte-code. This is the format used for Direct3D shader - * model 1, 2, and 3 shaders. \since 1.3 - */ - VKD3D_SHADER_TARGET_D3D_BYTECODE, - /** - * A 'Tokenized Program Format' shader embedded in a DXBC container. This is - * the format used for Direct3D shader model 4 and 5 shaders. \since 1.3 - */ - VKD3D_SHADER_TARGET_DXBC_TPF, - /** - * An 'OpenGL Shading Language' shader. \since 1.3 - */ - VKD3D_SHADER_TARGET_GLSL, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_TARGET_TYPE), -}; - -/** - * Describes the minimum severity of compilation messages returned by - * vkd3d_shader_compile() and similar functions. - */ -enum vkd3d_shader_log_level -{ - /** No messages will be returned. */ - VKD3D_SHADER_LOG_NONE, - /** Only fatal errors which prevent successful compilation will be returned. */ - VKD3D_SHADER_LOG_ERROR, - /** Non-fatal warnings and fatal errors will be returned. */ - VKD3D_SHADER_LOG_WARNING, - /** - * All messages, including general informational messages, will be returned. - */ - VKD3D_SHADER_LOG_INFO, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_LOG_LEVEL), -}; - -/** - * A chained structure containing compilation parameters. - */ -struct vkd3d_shader_compile_info -{ - /** Must be set to VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO. */ - enum vkd3d_shader_structure_type type; - /** - * Optional pointer to a structure containing further parameters. For a list - * of valid structures, refer to the respective function documentation. If - * no further parameters are needed, this field should be set to NULL. - */ - const void *next; - - /** Input source code or byte code. */ - struct vkd3d_shader_code source; - - /** Format of the input code passed in \ref source. */ - enum vkd3d_shader_source_type source_type; - /** Desired output format. */ - enum vkd3d_shader_target_type target_type; - - /** - * Pointer to an array of compilation options. This field is ignored if - * \ref option_count is zero, but must be valid otherwise. - * - * If the same option is specified multiple times, only the last value is - * used. - * - * Options not relevant to or not supported by a particular shader compiler - * or scanner will be ignored. - */ - const struct vkd3d_shader_compile_option *options; - /** Size, in elements, of \ref options. */ - unsigned int option_count; - - /** Minimum severity of messages returned from the shader function. */ - enum vkd3d_shader_log_level log_level; - /** - * Name of the initial source file, which may be used in error messages or - * debug information. This parameter is optional and may be NULL. - */ - const char *source_name; -}; - -enum vkd3d_shader_spirv_environment -{ - VKD3D_SHADER_SPIRV_ENVIRONMENT_NONE, - VKD3D_SHADER_SPIRV_ENVIRONMENT_OPENGL_4_5, - VKD3D_SHADER_SPIRV_ENVIRONMENT_VULKAN_1_0, /* default target */ - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_SPIRV_ENVIRONMENT), -}; - -enum vkd3d_shader_spirv_extension -{ - VKD3D_SHADER_SPIRV_EXTENSION_NONE, - VKD3D_SHADER_SPIRV_EXTENSION_EXT_DEMOTE_TO_HELPER_INVOCATION, - /** \since 1.3 */ - VKD3D_SHADER_SPIRV_EXTENSION_EXT_DESCRIPTOR_INDEXING, - /** \since 1.3 */ - VKD3D_SHADER_SPIRV_EXTENSION_EXT_STENCIL_EXPORT, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_SPIRV_EXTENSION), -}; - -/* Extends vkd3d_shader_compile_info. */ -struct vkd3d_shader_spirv_target_info -{ - enum vkd3d_shader_structure_type type; - const void *next; - - const char *entry_point; /* "main" if NULL. */ - - enum vkd3d_shader_spirv_environment environment; - - const enum vkd3d_shader_spirv_extension *extensions; - unsigned int extension_count; - - const struct vkd3d_shader_parameter *parameters; - unsigned int parameter_count; - - bool dual_source_blending; - const unsigned int *output_swizzles; - unsigned int output_swizzle_count; -}; - -enum vkd3d_shader_tessellator_output_primitive -{ - VKD3D_SHADER_TESSELLATOR_OUTPUT_POINT = 0x1, - VKD3D_SHADER_TESSELLATOR_OUTPUT_LINE = 0x2, - VKD3D_SHADER_TESSELLATOR_OUTPUT_TRIANGLE_CW = 0x3, - VKD3D_SHADER_TESSELLATOR_OUTPUT_TRIANGLE_CCW = 0x4, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_TESSELLATOR_OUTPUT_PRIMITIVE), -}; - -enum vkd3d_shader_tessellator_partitioning -{ - VKD3D_SHADER_TESSELLATOR_PARTITIONING_INTEGER = 0x1, - VKD3D_SHADER_TESSELLATOR_PARTITIONING_POW2 = 0x2, - VKD3D_SHADER_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD = 0x3, - VKD3D_SHADER_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN = 0x4, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_TESSELLATOR_PARTITIONING), -}; - -/* Extends vkd3d_shader_spirv_target_info. */ -struct vkd3d_shader_spirv_domain_shader_target_info -{ - enum vkd3d_shader_structure_type type; - const void *next; - - enum vkd3d_shader_tessellator_output_primitive output_primitive; - enum vkd3d_shader_tessellator_partitioning partitioning; -}; - -/** - * A single preprocessor macro, passed as part of struct - * vkd3d_shader_preprocess_info. - */ -struct vkd3d_shader_macro -{ - /** - * Pointer to a null-terminated string containing the name of a macro. This - * macro must not be a parameterized (i.e. function-like) macro. If this - * field is not a valid macro identifier, this macro will be ignored. - */ - const char *name; - /** - * Optional pointer to a null-terminated string containing the expansion of - * the macro. This field may be set to NULL, in which case the macro has an - * empty expansion. - */ - const char *value; -}; - -/** - * Type of a callback function which will be used to open preprocessor includes. - * - * This callback function is passed as part of struct - * vkd3d_shader_preprocess_info. - * - * If this function fails, vkd3d-shader will emit a compilation error, and the - * \a pfn_close_include callback will not be called. - * - * \param filename Unquoted string used as an argument to the \#include - * directive. - * - * \param local Whether the \#include directive is requesting a local (i.e. - * double-quoted) or system (i.e. angle-bracketed) include. - * - * \param parent_data Unprocessed source code of the file in which this - * \#include directive is evaluated. This parameter may be NULL. - * - * \param context The user-defined pointer passed to struct - * vkd3d_shader_preprocess_info. - * - * \param out Output location for the full contents of the included file. The - * code need not be allocated using standard vkd3d functions, but must remain - * valid until the corresponding call to \a pfn_close_include. If this function - * fails, the contents of this parameter are ignored. - * - * \return A member of \ref vkd3d_result. - */ -typedef int (*PFN_vkd3d_shader_open_include)(const char *filename, bool local, - const char *parent_data, void *context, struct vkd3d_shader_code *out); -/** - * Type of a callback function which will be used to close preprocessor - * includes. - * - * This callback function is passed as part of struct - * vkd3d_shader_preprocess_info. - * - * \param code Contents of the included file, which were allocated by the - * \ref pfn_open_include callback. The user must free them. - * - * \param context The user-defined pointer passed to struct - * vkd3d_shader_preprocess_info. - */ -typedef void (*PFN_vkd3d_shader_close_include)(const struct vkd3d_shader_code *code, void *context); - -/** - * A chained structure containing preprocessing parameters. - * - * This structure is optional. - * - * This structure extends vkd3d_shader_compile_info. - * - * This structure contains only input parameters. - * - * \since 1.3 - */ -struct vkd3d_shader_preprocess_info -{ - /** Must be set to VKD3D_SHADER_STRUCTURE_TYPE_PREPROCESS_INFO. */ - enum vkd3d_shader_structure_type type; - /** Optional pointer to a structure containing further parameters. */ - const void *next; - - /** - * Pointer to an array of predefined macros. Each macro in this array will - * be expanded as if a corresponding #define statement were prepended to the - * source code. - * - * If the same macro is specified multiple times, only the last value is - * used. - */ - const struct vkd3d_shader_macro *macros; - /** Size, in elements, of \ref macros. */ - unsigned int macro_count; - - /** - * Optional pointer to a callback function, which will be called in order to - * evaluate \#include directives. The function receives parameters - * corresponding to the directive's arguments, and should return the - * complete text of the included file. - * - * If this field is set to NULL, or if this structure is omitted, - * vkd3d-shader will attempt to open included files using POSIX file APIs. - * - * If this field is set to NULL, the \ref pfn_close_include field must also - * be set to NULL. - */ - PFN_vkd3d_shader_open_include pfn_open_include; - /** - * Optional pointer to a callback function, which will be called whenever an - * included file is closed. This function will be called exactly once for - * each successful call to \ref pfn_open_include, and should be used to free - * any resources allocated thereby. - * - * If this field is set to NULL, the \ref pfn_open_include field must also - * be set to NULL. - */ - PFN_vkd3d_shader_close_include pfn_close_include; - /** - * User-defined pointer which will be passed unmodified to the - * \ref pfn_open_include and \ref pfn_close_include callbacks. - */ - void *include_context; -}; - -/** - * A chained structure containing HLSL compilation parameters. - * - * This structure is optional. - * - * This structure extends vkd3d_shader_compile_info. - * - * This structure contains only input parameters. - * - * \since 1.3 - */ -struct vkd3d_shader_hlsl_source_info -{ - /** Must be set to VKD3D_SHADER_STRUCTURE_TYPE_HLSL_SOURCE_INFO. */ - enum vkd3d_shader_structure_type type; - /** Optional pointer to a structure containing further parameters. */ - const void *next; - - /** - * Optional pointer to a null-terminated string containing the shader entry - * point. - * - * If this parameter is NULL, vkd3d-shader uses the entry point "main". - */ - const char *entry_point; - struct vkd3d_shader_code secondary_code; - /** - * Pointer to a null-terminated string containing the target shader - * profile. - */ - const char *profile; -}; - -/* root signature 1.0 */ -enum vkd3d_shader_filter -{ - VKD3D_SHADER_FILTER_MIN_MAG_MIP_POINT = 0x000, - VKD3D_SHADER_FILTER_MIN_MAG_POINT_MIP_LINEAR = 0x001, - VKD3D_SHADER_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x004, - VKD3D_SHADER_FILTER_MIN_POINT_MAG_MIP_LINEAR = 0x005, - VKD3D_SHADER_FILTER_MIN_LINEAR_MAG_MIP_POINT = 0x010, - VKD3D_SHADER_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x011, - VKD3D_SHADER_FILTER_MIN_MAG_LINEAR_MIP_POINT = 0x014, - VKD3D_SHADER_FILTER_MIN_MAG_MIP_LINEAR = 0x015, - VKD3D_SHADER_FILTER_ANISOTROPIC = 0x055, - VKD3D_SHADER_FILTER_COMPARISON_MIN_MAG_MIP_POINT = 0x080, - VKD3D_SHADER_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR = 0x081, - VKD3D_SHADER_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x084, - VKD3D_SHADER_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR = 0x085, - VKD3D_SHADER_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT = 0x090, - VKD3D_SHADER_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x091, - VKD3D_SHADER_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT = 0x094, - VKD3D_SHADER_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR = 0x095, - VKD3D_SHADER_FILTER_COMPARISON_ANISOTROPIC = 0x0d5, - VKD3D_SHADER_FILTER_MINIMUM_MIN_MAG_MIP_POINT = 0x100, - VKD3D_SHADER_FILTER_MINIMUM_MIN_MAG_POINT_MIP_LINEAR = 0x101, - VKD3D_SHADER_FILTER_MINIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x104, - VKD3D_SHADER_FILTER_MINIMUM_MIN_POINT_MAG_MIP_LINEAR = 0x105, - VKD3D_SHADER_FILTER_MINIMUM_MIN_LINEAR_MAG_MIP_POINT = 0x110, - VKD3D_SHADER_FILTER_MINIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x111, - VKD3D_SHADER_FILTER_MINIMUM_MIN_MAG_LINEAR_MIP_POINT = 0x114, - VKD3D_SHADER_FILTER_MINIMUM_MIN_MAG_MIP_LINEAR = 0x115, - VKD3D_SHADER_FILTER_MINIMUM_ANISOTROPIC = 0x155, - VKD3D_SHADER_FILTER_MAXIMUM_MIN_MAG_MIP_POINT = 0x180, - VKD3D_SHADER_FILTER_MAXIMUM_MIN_MAG_POINT_MIP_LINEAR = 0x181, - VKD3D_SHADER_FILTER_MAXIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x184, - VKD3D_SHADER_FILTER_MAXIMUM_MIN_POINT_MAG_MIP_LINEAR = 0x185, - VKD3D_SHADER_FILTER_MAXIMUM_MIN_LINEAR_MAG_MIP_POINT = 0x190, - VKD3D_SHADER_FILTER_MAXIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x191, - VKD3D_SHADER_FILTER_MAXIMUM_MIN_MAG_LINEAR_MIP_POINT = 0x194, - VKD3D_SHADER_FILTER_MAXIMUM_MIN_MAG_MIP_LINEAR = 0x195, - VKD3D_SHADER_FILTER_MAXIMUM_ANISOTROPIC = 0x1d5, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_FILTER), -}; - -enum vkd3d_shader_texture_address_mode -{ - VKD3D_SHADER_TEXTURE_ADDRESS_MODE_WRAP = 0x1, - VKD3D_SHADER_TEXTURE_ADDRESS_MODE_MIRROR = 0x2, - VKD3D_SHADER_TEXTURE_ADDRESS_MODE_CLAMP = 0x3, - VKD3D_SHADER_TEXTURE_ADDRESS_MODE_BORDER = 0x4, - VKD3D_SHADER_TEXTURE_ADDRESS_MODE_MIRROR_ONCE = 0x5, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_TEXTURE_ADDRESS_MODE), -}; - -enum vkd3d_shader_comparison_func -{ - VKD3D_SHADER_COMPARISON_FUNC_NEVER = 0x1, - VKD3D_SHADER_COMPARISON_FUNC_LESS = 0x2, - VKD3D_SHADER_COMPARISON_FUNC_EQUAL = 0x3, - VKD3D_SHADER_COMPARISON_FUNC_LESS_EQUAL = 0x4, - VKD3D_SHADER_COMPARISON_FUNC_GREATER = 0x5, - VKD3D_SHADER_COMPARISON_FUNC_NOT_EQUAL = 0x6, - VKD3D_SHADER_COMPARISON_FUNC_GREATER_EQUAL = 0x7, - VKD3D_SHADER_COMPARISON_FUNC_ALWAYS = 0x8, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPARISON_FUNC), -}; - -enum vkd3d_shader_static_border_colour -{ - VKD3D_SHADER_STATIC_BORDER_COLOUR_TRANSPARENT_BLACK = 0x0, - VKD3D_SHADER_STATIC_BORDER_COLOUR_OPAQUE_BLACK = 0x1, - VKD3D_SHADER_STATIC_BORDER_COLOUR_OPAQUE_WHITE = 0x2, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STATIC_BORDER_COLOUR), -}; - -struct vkd3d_shader_static_sampler_desc -{ - enum vkd3d_shader_filter filter; - enum vkd3d_shader_texture_address_mode address_u; - enum vkd3d_shader_texture_address_mode address_v; - enum vkd3d_shader_texture_address_mode address_w; - float mip_lod_bias; - unsigned int max_anisotropy; - enum vkd3d_shader_comparison_func comparison_func; - enum vkd3d_shader_static_border_colour border_colour; - float min_lod; - float max_lod; - unsigned int shader_register; - unsigned int register_space; - enum vkd3d_shader_visibility shader_visibility; -}; - -struct vkd3d_shader_descriptor_range -{ - enum vkd3d_shader_descriptor_type range_type; - unsigned int descriptor_count; - unsigned int base_shader_register; - unsigned int register_space; - unsigned int descriptor_table_offset; -}; - -struct vkd3d_shader_root_descriptor_table -{ - unsigned int descriptor_range_count; - const struct vkd3d_shader_descriptor_range *descriptor_ranges; -}; - -struct vkd3d_shader_root_constants -{ - unsigned int shader_register; - unsigned int register_space; - unsigned int value_count; -}; - -struct vkd3d_shader_root_descriptor -{ - unsigned int shader_register; - unsigned int register_space; -}; - -enum vkd3d_shader_root_parameter_type -{ - VKD3D_SHADER_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE = 0x0, - VKD3D_SHADER_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS = 0x1, - VKD3D_SHADER_ROOT_PARAMETER_TYPE_CBV = 0x2, - VKD3D_SHADER_ROOT_PARAMETER_TYPE_SRV = 0x3, - VKD3D_SHADER_ROOT_PARAMETER_TYPE_UAV = 0x4, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_ROOT_PARAMETER_TYPE), -}; - -struct vkd3d_shader_root_parameter -{ - enum vkd3d_shader_root_parameter_type parameter_type; - union - { - struct vkd3d_shader_root_descriptor_table descriptor_table; - struct vkd3d_shader_root_constants constants; - struct vkd3d_shader_root_descriptor descriptor; - } u; - enum vkd3d_shader_visibility shader_visibility; -}; - -enum vkd3d_shader_root_signature_flags -{ - VKD3D_SHADER_ROOT_SIGNATURE_FLAG_NONE = 0x00, - VKD3D_SHADER_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT = 0x01, - VKD3D_SHADER_ROOT_SIGNATURE_FLAG_DENY_VERTEX_SHADER_ROOT_ACCESS = 0x02, - VKD3D_SHADER_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS = 0x04, - VKD3D_SHADER_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS = 0x08, - VKD3D_SHADER_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS = 0x10, - VKD3D_SHADER_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS = 0x20, - VKD3D_SHADER_ROOT_SIGNATURE_FLAG_ALLOW_STREAM_OUTPUT = 0x40, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_ROOT_SIGNATURE_FLAGS), -}; - -struct vkd3d_shader_root_signature_desc -{ - unsigned int parameter_count; - const struct vkd3d_shader_root_parameter *parameters; - unsigned int static_sampler_count; - const struct vkd3d_shader_static_sampler_desc *static_samplers; - enum vkd3d_shader_root_signature_flags flags; -}; - -/* root signature 1.1 */ -enum vkd3d_shader_root_descriptor_flags -{ - VKD3D_SHADER_ROOT_DESCRIPTOR_FLAG_NONE = 0x0, - VKD3D_SHADER_ROOT_DESCRIPTOR_FLAG_DATA_VOLATILE = 0x2, - VKD3D_SHADER_ROOT_DESCRIPTOR_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE = 0x4, - VKD3D_SHADER_ROOT_DESCRIPTOR_FLAG_DATA_STATIC = 0x8, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_ROOT_DESCRIPTOR_FLAGS), -}; - -enum vkd3d_shader_descriptor_range_flags -{ - VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_NONE = 0x0, - VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_VOLATILE = 0x1, - VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE = 0x2, - VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE = 0x4, - VKD3D_SHADER_DESCRIPTOR_RANGE_FLAG_DATA_STATIC = 0x8, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_DESCRIPTOR_RANGE_FLAGS), -}; - -struct vkd3d_shader_descriptor_range1 -{ - enum vkd3d_shader_descriptor_type range_type; - unsigned int descriptor_count; - unsigned int base_shader_register; - unsigned int register_space; - enum vkd3d_shader_descriptor_range_flags flags; - unsigned int descriptor_table_offset; -}; - -struct vkd3d_shader_root_descriptor_table1 -{ - unsigned int descriptor_range_count; - const struct vkd3d_shader_descriptor_range1 *descriptor_ranges; -}; - -struct vkd3d_shader_root_descriptor1 -{ - unsigned int shader_register; - unsigned int register_space; - enum vkd3d_shader_root_descriptor_flags flags; -}; - -struct vkd3d_shader_root_parameter1 -{ - enum vkd3d_shader_root_parameter_type parameter_type; - union - { - struct vkd3d_shader_root_descriptor_table1 descriptor_table; - struct vkd3d_shader_root_constants constants; - struct vkd3d_shader_root_descriptor1 descriptor; - } u; - enum vkd3d_shader_visibility shader_visibility; -}; - -struct vkd3d_shader_root_signature_desc1 -{ - unsigned int parameter_count; - const struct vkd3d_shader_root_parameter1 *parameters; - unsigned int static_sampler_count; - const struct vkd3d_shader_static_sampler_desc *static_samplers; - enum vkd3d_shader_root_signature_flags flags; -}; - -enum vkd3d_shader_root_signature_version -{ - VKD3D_SHADER_ROOT_SIGNATURE_VERSION_1_0 = 0x1, - VKD3D_SHADER_ROOT_SIGNATURE_VERSION_1_1 = 0x2, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_ROOT_SIGNATURE_VERSION), -}; - -struct vkd3d_shader_versioned_root_signature_desc -{ - enum vkd3d_shader_root_signature_version version; - union - { - struct vkd3d_shader_root_signature_desc v_1_0; - struct vkd3d_shader_root_signature_desc1 v_1_1; - } u; -}; - -/** - * The type of a shader resource, returned as part of struct - * vkd3d_shader_descriptor_info. - */ -enum vkd3d_shader_resource_type -{ - /** - * The type is invalid or not applicable for this descriptor. This value is - * returned for samplers. - */ - VKD3D_SHADER_RESOURCE_NONE = 0x0, - /** Dimensionless buffer. */ - VKD3D_SHADER_RESOURCE_BUFFER = 0x1, - /** 1-dimensional texture. */ - VKD3D_SHADER_RESOURCE_TEXTURE_1D = 0x2, - /** 2-dimensional texture. */ - VKD3D_SHADER_RESOURCE_TEXTURE_2D = 0x3, - /** Multisampled 2-dimensional texture. */ - VKD3D_SHADER_RESOURCE_TEXTURE_2DMS = 0x4, - /** 3-dimensional texture. */ - VKD3D_SHADER_RESOURCE_TEXTURE_3D = 0x5, - /** Cubemap texture. */ - VKD3D_SHADER_RESOURCE_TEXTURE_CUBE = 0x6, - /** 1-dimensional array texture. */ - VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY = 0x7, - /** 2-dimensional array texture. */ - VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY = 0x8, - /** Multisampled 2-dimensional array texture. */ - VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY = 0x9, - /** Cubemap array texture. */ - VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY = 0xa, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_RESOURCE_TYPE), -}; - -/** - * The type of the data contained in a shader resource, returned as part of - * struct vkd3d_shader_descriptor_info. All formats are 32-bit. - */ -enum vkd3d_shader_resource_data_type -{ - /** Unsigned normalized integer. */ - VKD3D_SHADER_RESOURCE_DATA_UNORM = 0x1, - /** Signed normalized integer. */ - VKD3D_SHADER_RESOURCE_DATA_SNORM = 0x2, - /** Signed integer. */ - VKD3D_SHADER_RESOURCE_DATA_INT = 0x3, - /** Unsigned integer. */ - VKD3D_SHADER_RESOURCE_DATA_UINT = 0x4, - /** IEEE single-precision floating-point. */ - VKD3D_SHADER_RESOURCE_DATA_FLOAT = 0x5, - /** Undefined/type-less. \since 1.3 */ - VKD3D_SHADER_RESOURCE_DATA_MIXED = 0x6, - /** IEEE double-precision floating-point. \since 1.3 */ - VKD3D_SHADER_RESOURCE_DATA_DOUBLE = 0x7, - /** Continuation of the previous component. For example, 64-bit - * double-precision floating-point data may be returned as two 32-bit - * components, with the first component (containing the LSB) specified as - * VKD3D_SHADER_RESOURCE_DATA_DOUBLE, and the second component specified - * as VKD3D_SHADER_RESOURCE_DATA_CONTINUED. \since 1.3 */ - VKD3D_SHADER_RESOURCE_DATA_CONTINUED = 0x8, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_RESOURCE_DATA_TYPE), -}; - -/** - * Additional flags describing a shader descriptor, returned as part of struct - * vkd3d_shader_descriptor_info. - */ -enum vkd3d_shader_descriptor_info_flag -{ - /** - * The descriptor is a UAV resource, whose counter is read from or written - * to by the shader. - */ - VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_COUNTER = 0x00000001, - /** The descriptor is a UAV resource, which is read from by the shader. */ - VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ = 0x00000002, - /** The descriptor is a comparison sampler. */ - VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE = 0x00000004, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_DESCRIPTOR_INFO_FLAG), -}; - -/** - * Describes a single shader descriptor; returned as part of - * struct vkd3d_shader_scan_descriptor_info. - */ -struct vkd3d_shader_descriptor_info -{ - /** Type of the descriptor (for example, SRV, CBV, UAV, or sampler). */ - enum vkd3d_shader_descriptor_type type; - /** - * Register space of the resource, or 0 if the shader does not - * support multiple register spaces. - */ - unsigned int register_space; - /** Register index of the descriptor. */ - unsigned int register_index; - /** Resource type, if applicable, including its dimension. */ - enum vkd3d_shader_resource_type resource_type; - /** Data type contained in the resource (for example, float or integer). */ - enum vkd3d_shader_resource_data_type resource_data_type; - /** - * Bitwise combination of zero or more members of - * \ref vkd3d_shader_descriptor_info_flag. - */ - unsigned int flags; - /** - * Size of this descriptor array, or 1 if a single descriptor. - * For an unbounded array this value is ~0u. - */ - unsigned int count; -}; - -/** - * A chained structure enumerating the descriptors declared by a shader. - * - * This structure extends vkd3d_shader_compile_info. - */ -struct vkd3d_shader_scan_descriptor_info -{ - /** - * Input; must be set to VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO. - */ - enum vkd3d_shader_structure_type type; - /** Input; optional pointer to a structure containing further parameters. */ - const void *next; - - /** Output; returns a pointer to an array of descriptors. */ - struct vkd3d_shader_descriptor_info *descriptors; - /** Output; size, in elements, of \ref descriptors. */ - unsigned int descriptor_count; -}; - -/** - * Data type of a shader varying, returned as part of struct - * vkd3d_shader_signature_element. - */ -enum vkd3d_shader_component_type -{ - /** The varying has no type. */ - VKD3D_SHADER_COMPONENT_VOID = 0x0, - /** 32-bit unsigned integer. */ - VKD3D_SHADER_COMPONENT_UINT = 0x1, - /** 32-bit signed integer. */ - VKD3D_SHADER_COMPONENT_INT = 0x2, - /** 32-bit IEEE floating-point. */ - VKD3D_SHADER_COMPONENT_FLOAT = 0x3, - /** Boolean. */ - VKD3D_SHADER_COMPONENT_BOOL = 0x4, - /** 64-bit IEEE floating-point. */ - VKD3D_SHADER_COMPONENT_DOUBLE = 0x5, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPONENT_TYPE), -}; - -/** System value semantic, returned as part of struct vkd3d_shader_signature. */ -enum vkd3d_shader_sysval_semantic -{ - /** No system value. */ - VKD3D_SHADER_SV_NONE = 0x00, - /** Vertex position; SV_Position in Direct3D. */ - VKD3D_SHADER_SV_POSITION = 0x01, - /** Clip distance; SV_ClipDistance in Direct3D. */ - VKD3D_SHADER_SV_CLIP_DISTANCE = 0x02, - /** Cull distance; SV_CullDistance in Direct3D. */ - VKD3D_SHADER_SV_CULL_DISTANCE = 0x03, - /** Render target layer; SV_RenderTargetArrayIndex in Direct3D. */ - VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX = 0x04, - /** Viewport index; SV_ViewportArrayIndex in Direct3D. */ - 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. */ - VKD3D_SHADER_SV_PRIMITIVE_ID = 0x07, - /** Instance ID; SV_InstanceID in Direct3D. */ - VKD3D_SHADER_SV_INSTANCE_ID = 0x08, - /** Whether the triangle is front-facing; SV_IsFrontFace in Direct3D. */ - VKD3D_SHADER_SV_IS_FRONT_FACE = 0x09, - /** Sample index; SV_SampleIndex in Direct3D. */ - VKD3D_SHADER_SV_SAMPLE_INDEX = 0x0a, - VKD3D_SHADER_SV_TESS_FACTOR_QUADEDGE = 0x0b, - VKD3D_SHADER_SV_TESS_FACTOR_QUADINT = 0x0c, - VKD3D_SHADER_SV_TESS_FACTOR_TRIEDGE = 0x0d, - VKD3D_SHADER_SV_TESS_FACTOR_TRIINT = 0x0e, - VKD3D_SHADER_SV_TESS_FACTOR_LINEDET = 0x0f, - VKD3D_SHADER_SV_TESS_FACTOR_LINEDEN = 0x10, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_SYSVAL_SEMANTIC), -}; - -/** - * Minimum interpolation precision of a shader varying, returned as part of - * struct vkd3d_shader_signature_element. - */ -enum vkd3d_shader_minimum_precision -{ - VKD3D_SHADER_MINIMUM_PRECISION_NONE = 0, - /** 16-bit floating-point. */ - VKD3D_SHADER_MINIMUM_PRECISION_FLOAT_16 = 1, - /** 10-bit fixed point (2 integer and 8 fractional bits). */ - VKD3D_SHADER_MINIMUM_PRECISION_FIXED_8_2 = 2, - /** 16-bit signed integer. */ - VKD3D_SHADER_MINIMUM_PRECISION_INT_16 = 4, - /** 16-bit unsigned integer. */ - VKD3D_SHADER_MINIMUM_PRECISION_UINT_16 = 5, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_MINIMUM_PRECISION), -}; - -/** - * A single shader varying, returned as part of struct vkd3d_shader_signature. - */ -struct vkd3d_shader_signature_element -{ - /** Semantic name. */ - const char *semantic_name; - /** Semantic index, or 0 if the semantic is not indexed. */ - unsigned int semantic_index; - /** - * Stream index of a geometry shader output semantic. If the signature is - * not a geometry shader output signature, this field will be set to 0. - */ - unsigned int stream_index; - /** - * System value semantic. If the varying is not a system value, this field - * will be set to VKD3D_SHADER_SV_NONE. - */ - enum vkd3d_shader_sysval_semantic sysval_semantic; - /** Data type. */ - enum vkd3d_shader_component_type component_type; - /** Register index. */ - unsigned int register_index; - /** Mask of the register components allocated to this varying. */ - unsigned int mask; - /** - * Subset of \ref mask which the shader reads from or writes to. Unlike - * Direct3D shader bytecode, the mask for output and tessellation signatures - * is not inverted, i.e. bits set in this field denote components which are - * written to. - */ - unsigned int used_mask; - /** Minimum interpolation precision. */ - enum vkd3d_shader_minimum_precision min_precision; -}; - -/** - * Description of a shader input or output signature. This structure is - * populated by vkd3d_shader_parse_input_signature(). - * - * The helper function vkd3d_shader_find_signature_element() will look up a - * varying element by its semantic name, semantic index, and stream index. - */ -struct vkd3d_shader_signature -{ - /** Pointer to an array of varyings. */ - struct vkd3d_shader_signature_element *elements; - /** Size, in elements, of \ref elements. */ - unsigned int element_count; -}; - -/** Possible values for a single component of a vkd3d-shader swizzle. */ -enum vkd3d_shader_swizzle_component -{ - VKD3D_SHADER_SWIZZLE_X = 0x0, - VKD3D_SHADER_SWIZZLE_Y = 0x1, - VKD3D_SHADER_SWIZZLE_Z = 0x2, - VKD3D_SHADER_SWIZZLE_W = 0x3, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_SWIZZLE_COMPONENT), -}; - -/** - * A mask selecting one component from a vkd3d-shader swizzle. The component has - * type \ref vkd3d_shader_swizzle_component. - */ -#define VKD3D_SHADER_SWIZZLE_MASK (0xffu) -/** The offset, in bits, of the nth parameter of a vkd3d-shader swizzle. */ -#define VKD3D_SHADER_SWIZZLE_SHIFT(idx) (8u * (idx)) - -/** - * A helper macro which returns a vkd3d-shader swizzle with the given - * components. The components are specified as the suffixes to members of - * \ref vkd3d_shader_swizzle_component. For example, the swizzle ".xwyy" can be - * represented as: - * \code - * VKD3D_SHADER_SWIZZLE(X, W, Y, Y) - * \endcode - */ -#define VKD3D_SHADER_SWIZZLE(x, y, z, w) \ - vkd3d_shader_create_swizzle(VKD3D_SHADER_SWIZZLE_ ## x, \ - VKD3D_SHADER_SWIZZLE_ ## y, \ - VKD3D_SHADER_SWIZZLE_ ## z, \ - VKD3D_SHADER_SWIZZLE_ ## w) - -/** The identity swizzle ".xyzw". */ -#define VKD3D_SHADER_NO_SWIZZLE VKD3D_SHADER_SWIZZLE(X, Y, Z, W) - -/** Build a vkd3d-shader swizzle with the given components. */ -static inline uint32_t vkd3d_shader_create_swizzle(enum vkd3d_shader_swizzle_component x, - enum vkd3d_shader_swizzle_component y, enum vkd3d_shader_swizzle_component z, - enum vkd3d_shader_swizzle_component w) -{ - return ((x & VKD3D_SHADER_SWIZZLE_MASK) << VKD3D_SHADER_SWIZZLE_SHIFT(0)) - | ((y & VKD3D_SHADER_SWIZZLE_MASK) << VKD3D_SHADER_SWIZZLE_SHIFT(1)) - | ((z & VKD3D_SHADER_SWIZZLE_MASK) << VKD3D_SHADER_SWIZZLE_SHIFT(2)) - | ((w & VKD3D_SHADER_SWIZZLE_MASK) << VKD3D_SHADER_SWIZZLE_SHIFT(3)); -} - -#ifdef LIBVKD3D_SHADER_SOURCE -# define VKD3D_SHADER_API VKD3D_EXPORT -#else -# define VKD3D_SHADER_API VKD3D_IMPORT -#endif - -#ifndef VKD3D_SHADER_NO_PROTOTYPES - -/** - * Returns the current version of this library. - * - * \param major Output location for the major version of this library. - * - * \param minor Output location for the minor version of this library. - * - * \return A human-readable string describing the library name and version. This - * string is null-terminated and UTF-8 encoded. This may be a pointer to static - * data in libvkd3d-shader; it should not be freed. - */ -VKD3D_SHADER_API const char *vkd3d_shader_get_version(unsigned int *major, unsigned int *minor); -/** - * Returns the source types supported, with any target type, by - * vkd3d_shader_compile(). Future versions of the library may introduce - * additional source types; callers should ignore unrecognised source types. - * - * Use vkd3d_shader_get_supported_target_types() to determine which target types - * are supported for each source type. - * - * \param count Output location for the size, in elements, of the returned - * array. - * - * \return Pointer to an array of source types supported by this version of - * vkd3d-shader. This array may be a pointer to static data in libvkd3d-shader; - * it should not be freed. - */ -VKD3D_SHADER_API const enum vkd3d_shader_source_type *vkd3d_shader_get_supported_source_types(unsigned int *count); -/** - * Returns the target types supported, with the given source type, by - * vkd3d_shader_compile(). Future versions of the library may introduce - * additional target types; callers should ignore unrecognised target types. - * - * \param source_type Source type for which to enumerate supported target types. - * - * \param count Output location for the size, in elements, of the returned - * array. - * - * \return Pointer to an array of target types supported by this version of - * vkd3d-shader. This array may be a pointer to static data in libvkd3d-shader; - * it should not be freed. - */ -VKD3D_SHADER_API const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( - enum vkd3d_shader_source_type source_type, unsigned int *count); - -/** - * Transform a form of GPU shader source code or byte code into another form of - * source code or byte code. - * - * This version of vkd3d-shader supports the following transformations: - * - VKD3D_SHADER_SOURCE_DXBC_TPF to VKD3D_SHADER_TARGET_SPIRV_BINARY - * - * Supported transformations can also be detected at runtime with the functions - * vkd3d_shader_get_supported_source_types() and - * vkd3d_shader_get_supported_target_types(). - * - * Depending on the source and target types, this function may support the - * following chained structures: - * - vkd3d_shader_interface_info - * - vkd3d_shader_spirv_domain_shader_target_info - * - vkd3d_shader_spirv_target_info - * - vkd3d_shader_transform_feedback_info - * - * \param compile_info A chained structure containing compilation parameters. - * - * \param out A pointer to a vkd3d_shader_code structure in which the compiled - * code will be stored. - * \n - * The compiled shader is allocated by vkd3d-shader and should be freed with - * vkd3d_shader_free_shader_code() when no longer needed. - * - * \param messages Optional output location for error or informational messages - * produced by the compiler. - * \n - * This string is null-terminated and UTF-8 encoded. - * \n - * The messages are allocated by vkd3d-shader and should be freed with - * vkd3d_shader_free_messages() when no longer needed. - * \n - * The messages returned can be regulated with the \a log_level member of struct - * vkd3d_shader_compile_info. Regardless of the requested level, if this - * parameter is NULL, no compilation messages will be returned. - * \n - * If no compilation messages are produced by the compiler, this parameter may - * receive NULL instead of a valid string pointer. - * - * \return A member of \ref vkd3d_result. - */ -VKD3D_SHADER_API int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_code *out, char **messages); -/** - * Free shader messages allocated by another vkd3d-shader function, such as - * vkd3d_shader_compile(). - * - * \param messages Messages to free. This pointer is optional and may be NULL, - * in which case no action will be taken. - */ -VKD3D_SHADER_API void vkd3d_shader_free_messages(char *messages); -/** - * Free shader code allocated by another vkd3d-shader function, such as - * vkd3d_shader_compile(). - * - * This function frees the \ref vkd3d_shader_code.code member, but does not free - * the structure itself. - * - * \param code Code to free. - */ -VKD3D_SHADER_API void vkd3d_shader_free_shader_code(struct vkd3d_shader_code *code); - -/** - * Convert a byte code description of a shader root signature to a structural - * description which can be easily parsed by C code. - * - * This function corresponds to - * ID3D12VersionedRootSignatureDeserializer::GetUnconvertedRootSignatureDesc(). - * - * This function performs the reverse transformation of - * vkd3d_shader_serialize_root_signature(). - * - * This function parses a standalone root signature, and should not be confused - * with vkd3d_shader_parse_input_signature(). - * - * \param dxbc Compiled byte code, in DXBC format. - * - * \param root_signature Output location in which the decompiled root signature - * will be stored. - * \n - * Members of \a root_signature may be allocated by vkd3d-shader. The signature - * should be freed with vkd3d_shader_free_root_signature() when no longer - * needed. - * - * \param messages Optional output location for error or informational messages - * produced by the compiler. - * \n - * This parameter behaves identically to the \a messages parameter of - * vkd3d_shader_compile(). - * - * \return A member of \ref vkd3d_result. - */ -VKD3D_SHADER_API int vkd3d_shader_parse_root_signature(const struct vkd3d_shader_code *dxbc, - struct vkd3d_shader_versioned_root_signature_desc *root_signature, char **messages); -/** - * Free a structural representation of a shader root signature allocated by - * vkd3d_shader_convert_root_signature() or vkd3d_shader_parse_root_signature(). - * - * This function may free members of struct - * vkd3d_shader_versioned_root_signature_desc, but does not free the structure - * itself. - * - * \param root_signature Signature description to free. - */ -VKD3D_SHADER_API void vkd3d_shader_free_root_signature( - struct vkd3d_shader_versioned_root_signature_desc *root_signature); - -/** - * Convert a structural description of a shader root signature to a byte code - * format capable of being read by ID3D12Device::CreateRootSignature. The - * compiled signature is compatible with Microsoft D3D 12. - * - * This function corresponds to D3D12SerializeVersionedRootSignature(). - * - * \param root_signature Description of the root signature. - * - * \param dxbc A pointer to a vkd3d_shader_code structure in which the compiled - * code will be stored. - * \n - * The compiled signature is allocated by vkd3d-shader and should be freed with - * vkd3d_shader_free_shader_code() when no longer needed. - * - * \param messages Optional output location for error or informational messages - * produced by the compiler. - * \n - * This parameter behaves identically to the \a messages parameter of - * vkd3d_shader_compile(). - * - * \return A member of \ref vkd3d_result. - */ -VKD3D_SHADER_API int vkd3d_shader_serialize_root_signature( - const struct vkd3d_shader_versioned_root_signature_desc *root_signature, - struct vkd3d_shader_code *dxbc, char **messages); -/** - * Convert a structural representation of a root signature to a different - * version of structural representation. - * - * This function corresponds to - * ID3D12VersionedRootSignatureDeserializer::GetRootSignatureDescAtVersion(). - * - * \param dst A pointer to a vkd3d_shader_versioned_root_signature_desc - * structure in which the converted signature will be stored. - * \n - * Members of \a dst may be allocated by vkd3d-shader. The signature should be - * freed with vkd3d_shader_free_root_signature() when no longer needed. - * - * \param version The desired version to convert \a src to. This version must - * not be equal to \a src->version. - * - * \param src Input root signature description. - * - * \return A member of \ref vkd3d_result. - */ -VKD3D_SHADER_API int vkd3d_shader_convert_root_signature(struct vkd3d_shader_versioned_root_signature_desc *dst, - enum vkd3d_shader_root_signature_version version, const struct vkd3d_shader_versioned_root_signature_desc *src); - -/** - * Parse shader source code or byte code, returning various types of requested - * information. - * - * Currently this function supports the following code types: - * - VKD3D_SHADER_SOURCE_DXBC_TPF - * - * \param compile_info A chained structure containing scan parameters. - * \n - * The DXBC_TPF scanner supports the following chained structures: - * - vkd3d_shader_scan_descriptor_info - * \n - * Although the \a compile_info parameter is read-only, chained structures - * passed to this function need not be, and may serve as output parameters, - * depending on their structure type. - * - * \param messages Optional output location for error or informational messages - * produced by the compiler. - * \n - * This parameter behaves identically to the \a messages parameter of - * vkd3d_shader_compile(). - * - * \return A member of \ref vkd3d_result. - */ -VKD3D_SHADER_API int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char **messages); -/** - * Free members of struct vkd3d_shader_scan_descriptor_info() allocated by - * vkd3d_shader_scan(). - * - * This function may free members of vkd3d_shader_scan_descriptor_info, but - * does not free the structure itself. - * - * \param scan_descriptor_info Descriptor information to free. - */ -VKD3D_SHADER_API void vkd3d_shader_free_scan_descriptor_info( - struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info); - -/** - * Read the input signature of a compiled shader, returning a structural - * description which can be easily parsed by C code. - * - * This function parses a compiled shader. To parse a standalone root signature, - * use vkd3d_shader_parse_root_signature(). - * - * \param dxbc Compiled byte code, in DXBC format. - * - * \param signature Output location in which the parsed root signature will be - * stored. - * \n - * Members of \a signature may be allocated by vkd3d-shader. The signature - * should be freed with vkd3d_shader_free_shader_signature() when no longer - * needed. - * - * \param messages Optional output location for error or informational messages - * produced by the compiler. - * \n - * This parameter behaves identically to the \a messages parameter of - * vkd3d_shader_compile(). - * - * \return A member of \ref vkd3d_result. - */ -VKD3D_SHADER_API int vkd3d_shader_parse_input_signature(const struct vkd3d_shader_code *dxbc, - struct vkd3d_shader_signature *signature, char **messages); -/** - * Find a single element of a parsed input signature. - * - * \param signature The parsed input signature. This structure is normally - * populated by vkd3d_shader_parse_input_signature(). - * - * \param semantic_name Semantic name of the desired element. This function - * performs a case-insensitive comparison with respect to the ASCII plane. - * - * \param semantic_index Semantic index of the desired element. - * - * \param stream_index Geometry shader stream index of the desired element. If - * the signature is not a geometry shader output signature, this parameter must - * be set to 0. - * - * \return A description of the element matching the requested parameters, or - * NULL if no such element was found. If not NULL, the return value points into - * the \a signature parameter and should not be explicitly freed. - */ -VKD3D_SHADER_API struct vkd3d_shader_signature_element *vkd3d_shader_find_signature_element( - const struct vkd3d_shader_signature *signature, const char *semantic_name, - unsigned int semantic_index, unsigned int stream_index); -/** - * Free a structural representation of a shader input signature allocated by - * vkd3d_shader_parse_input_signature(). - * - * This function may free members of struct vkd3d_shader_signature, but does not - * free the structure itself. - * - * \param signature Signature description to free. - */ -VKD3D_SHADER_API void vkd3d_shader_free_shader_signature(struct vkd3d_shader_signature *signature); - -/* 1.3 */ - -/** - * Preprocess the given source code. - * - * This function supports the following chained structures: - * - vkd3d_shader_preprocess_info - * - * \param compile_info A chained structure containing compilation parameters. - * - * \param out A pointer to a vkd3d_shader_code structure in which the - * preprocessed code will be stored. - * \n - * The preprocessed shader is allocated by vkd3d-shader and should be freed with - * vkd3d_shader_free_shader_code() when no longer needed. - * - * \param messages Optional output location for error or informational messages - * produced by the compiler. - * \n - * This parameter behaves identically to the \a messages parameter of - * vkd3d_shader_compile(). - * - * \return A member of \ref vkd3d_result. - * - * \since 1.3 - */ -VKD3D_SHADER_API int vkd3d_shader_preprocess(const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_code *out, char **messages); - -#endif /* VKD3D_SHADER_NO_PROTOTYPES */ - -/** Type of vkd3d_shader_get_version(). */ -typedef const char *(*PFN_vkd3d_shader_get_version)(unsigned int *major, unsigned int *minor); -/** Type of vkd3d_shader_get_supported_source_types(). */ -typedef const enum vkd3d_shader_source_type *(*PFN_vkd3d_shader_get_supported_source_types)(unsigned int *count); -/** Type of vkd3d_shader_get_supported_target_types(). */ -typedef const enum vkd3d_shader_target_type *(*PFN_vkd3d_shader_get_supported_target_types)( - enum vkd3d_shader_source_type source_type, unsigned int *count); - -/** Type of vkd3d_shader_compile(). */ -typedef int (*PFN_vkd3d_shader_compile)(const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_code *out, char **messages); -/** Type of vkd3d_shader_free_messages(). */ -typedef void (*PFN_vkd3d_shader_free_messages)(char *messages); -/** Type of vkd3d_shader_free_shader_code(). */ -typedef void (*PFN_vkd3d_shader_free_shader_code)(struct vkd3d_shader_code *code); - -/** Type of vkd3d_shader_parse_root_signature(). */ -typedef int (*PFN_vkd3d_shader_parse_root_signature)(const struct vkd3d_shader_code *dxbc, - struct vkd3d_shader_versioned_root_signature_desc *root_signature, char **messages); -/** Type of vkd3d_shader_free_root_signature(). */ -typedef void (*PFN_vkd3d_shader_free_root_signature)(struct vkd3d_shader_versioned_root_signature_desc *root_signature); - -/** Type of vkd3d_shader_serialize_root_signature(). */ -typedef int (*PFN_vkd3d_shader_serialize_root_signature)( - const struct vkd3d_shader_versioned_root_signature_desc *root_signature, - struct vkd3d_shader_code *dxbc, char **messages); - -/** Type of vkd3d_shader_convert_root_signature(). */ -typedef int (*PFN_vkd3d_shader_convert_root_signature)(struct vkd3d_shader_versioned_root_signature_desc *dst, - enum vkd3d_shader_root_signature_version version, const struct vkd3d_shader_versioned_root_signature_desc *src); - -/** Type of vkd3d_shader_scan(). */ -typedef int (*PFN_vkd3d_shader_scan)(const struct vkd3d_shader_compile_info *compile_info, char **messages); -/** Type of vkd3d_shader_free_scan_descriptor_info(). */ -typedef void (*PFN_vkd3d_shader_free_scan_descriptor_info)( - struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info); - -/** Type of vkd3d_shader_parse_input_signature(). */ -typedef int (*PFN_vkd3d_shader_parse_input_signature)(const struct vkd3d_shader_code *dxbc, - struct vkd3d_shader_signature *signature, char **messages); -/** Type of vkd3d_shader_find_signature_element(). */ -typedef struct vkd3d_shader_signature_element * (*PFN_vkd3d_shader_find_signature_element)( - const struct vkd3d_shader_signature *signature, const char *semantic_name, - unsigned int semantic_index, unsigned int stream_index); -/** Type of vkd3d_shader_free_shader_signature(). */ -typedef void (*PFN_vkd3d_shader_free_shader_signature)(struct vkd3d_shader_signature *signature); - -/** Type of vkd3d_shader_preprocess(). \since 1.3 */ -typedef void (*PFN_vkd3d_shader_preprocess)(struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_code *out, char **messages); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __VKD3D_SHADER_H */ diff --git a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_types.h b/dll/directx/wine/d3d12/vkd3d/include/vkd3d_types.h deleted file mode 100644 index 7014f4c25d64e..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_types.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2016-2018 Józef Kucia for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef __VKD3D_TYPES_H -#define __VKD3D_TYPES_H - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/** - * \file vkd3d_types.h - * - * This file contains definitions for basic types used by vkd3d libraries. - */ - -#define VKD3D_FORCE_32_BIT_ENUM(name) name##_FORCE_32BIT = 0x7fffffff - -/** - * Result codes returned by some vkd3d functions. Error codes always have - * negative values; non-error codes never do. - */ -enum vkd3d_result -{ - /** Success. */ - VKD3D_OK = 0, - /** An unspecified failure occurred. */ - VKD3D_ERROR = -1, - /** There are not enough resources available to complete the operation. */ - VKD3D_ERROR_OUT_OF_MEMORY = -2, - /** One or more parameters passed to a vkd3d function were invalid. */ - VKD3D_ERROR_INVALID_ARGUMENT = -3, - /** A shader passed to a vkd3d function was invalid. */ - VKD3D_ERROR_INVALID_SHADER = -4, - /** The operation is not implemented in this version of vkd3d. */ - VKD3D_ERROR_NOT_IMPLEMENTED = -5, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_RESULT), -}; - -#ifdef _WIN32 -# define VKD3D_IMPORT __declspec(dllimport) -# define VKD3D_EXPORT __declspec(dllexport) -#elif defined(__GNUC__) -# define VKD3D_IMPORT -# define VKD3D_EXPORT __attribute__((visibility("default"))) -#else -# define VKD3D_IMPORT -# define VKD3D_EXPORT -#endif - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __VKD3D_TYPES_H */ diff --git a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_unknown.idl b/dll/directx/wine/d3d12/vkd3d/include/vkd3d_unknown.idl deleted file mode 100644 index 9a7198c82d13c..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_unknown.idl +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2016 Józef Kucia for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -cpp_quote("#ifndef __VKD3D_UNKNOWN_H") -cpp_quote("#define __VKD3D_UNKNOWN_H") - -/* For IDL only. */ -cpp_quote("#if 0") -typedef IID *REFIID; -typedef IID *REFGUID; -cpp_quote("#endif") - -cpp_quote("#if !defined(_WIN32)") -typedef void *HWND; -typedef void *HMODULE; - -typedef struct LUID -{ - DWORD LowPart; - LONG HighPart; -} LUID; - -typedef struct _RECT -{ - LONG left; - LONG top; - LONG right; - LONG bottom; -} RECT; -cpp_quote("#endif") - -[uuid(00000000-0000-0000-C000-000000000046), object, local, pointer_default(unique)] -interface IUnknown -{ - HRESULT QueryInterface(REFIID riid, void **object); - ULONG AddRef(); - ULONG Release(); -} - -cpp_quote("#endif /* __VKD3D_UNKNOWN_H */") diff --git a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_utils.h b/dll/directx/wine/d3d12/vkd3d/include/vkd3d_utils.h deleted file mode 100644 index dd4cf32d175cf..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_utils.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2016 Józef Kucia for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef __VKD3D_UTILS_H -#define __VKD3D_UTILS_H - -#include - -#ifndef VKD3D_UTILS_API_VERSION -#define VKD3D_UTILS_API_VERSION VKD3D_API_VERSION_1_0 -#endif - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#define VKD3D_WAIT_OBJECT_0 (0) -#define VKD3D_WAIT_TIMEOUT (1) -#define VKD3D_WAIT_FAILED (~0u) -#define VKD3D_INFINITE (~0u) -#if 0 -#ifdef LIBVKD3D_UTILS_SOURCE -# define VKD3D_UTILS_API VKD3D_EXPORT -#else -# define VKD3D_UTILS_API VKD3D_IMPORT -#endif - -/* 1.0 */ -VKD3D_UTILS_API HANDLE vkd3d_create_event(void); -VKD3D_UTILS_API HRESULT vkd3d_signal_event(HANDLE event); -VKD3D_UTILS_API unsigned int vkd3d_wait_event(HANDLE event, unsigned int milliseconds); -VKD3D_UTILS_API void vkd3d_destroy_event(HANDLE event); - -#define D3D12CreateDevice(a, b, c, d) D3D12CreateDeviceVKD3D(a, b, c, d, VKD3D_UTILS_API_VERSION) -VKD3D_UTILS_API HRESULT WINAPI D3D12CreateRootSignatureDeserializer( - const void *data, SIZE_T data_size, REFIID iid, void **deserializer); -VKD3D_UTILS_API HRESULT WINAPI D3D12GetDebugInterface(REFIID iid, void **debug); -VKD3D_UTILS_API HRESULT WINAPI D3D12SerializeRootSignature(const D3D12_ROOT_SIGNATURE_DESC *desc, - D3D_ROOT_SIGNATURE_VERSION version, ID3DBlob **blob, ID3DBlob **error_blob); - -/* 1.2 */ -VKD3D_UTILS_API HRESULT WINAPI D3D12CreateDeviceVKD3D(IUnknown *adapter, D3D_FEATURE_LEVEL feature_level, - REFIID iid, void **device, enum vkd3d_api_version api_version); -VKD3D_UTILS_API HRESULT WINAPI D3D12CreateVersionedRootSignatureDeserializer(const void *data, - SIZE_T data_size, REFIID iid, void **deserializer); -VKD3D_UTILS_API HRESULT WINAPI D3D12SerializeVersionedRootSignature(const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *desc, - ID3DBlob **blob, ID3DBlob **error_blob); - -/* 1.3 */ -VKD3D_UTILS_API HRESULT WINAPI D3DCompile(const void *data, SIZE_T data_size, const char *filename, - const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint, - const char *target, UINT flags, UINT effect_flags, ID3DBlob **shader, ID3DBlob **error_messages); -VKD3D_UTILS_API HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filename, - const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint, - const char *target, UINT flags, UINT effect_flags, UINT secondary_flags, - const void *secondary_data, SIZE_T secondary_data_size, ID3DBlob **shader, - ID3DBlob **error_messages); -VKD3D_UTILS_API HRESULT WINAPI D3DCreateBlob(SIZE_T data_size, ID3DBlob **blob); -VKD3D_UTILS_API HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, const char *filename, - const D3D_SHADER_MACRO *defines, ID3DInclude *include, - ID3DBlob **shader, ID3DBlob **error_messages); -#endif -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __VKD3D_UTILS_H */ diff --git a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_windows.h b/dll/directx/wine/d3d12/vkd3d/include/vkd3d_windows.h deleted file mode 100644 index 8398d403b10d0..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/include/vkd3d_windows.h +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright 2016 Józef Kucia for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef __VKD3D_WINDOWS_H -#define __VKD3D_WINDOWS_H -#ifndef _INC_WINDOWS - -/* Nameless unions */ -#ifndef __C89_NAMELESS -# ifdef NONAMELESSUNION -# define __C89_NAMELESS -# define __C89_NAMELESSUNIONNAME u -# else -# define __C89_NAMELESS -# define __C89_NAMELESSUNIONNAME -# endif /* NONAMELESSUNION */ -#endif /* __C89_NAMELESS */ - -#if !defined(_WIN32) || defined(__WIDL__) - -# if !defined(__WIDL__) -# if !defined(VKD3D_WIN32_WCHAR) -# include -# endif -# include -# endif - -# ifdef __GNUC__ -# define DECLSPEC_ALIGN(x) __attribute__((aligned(x))) -# endif - -/* HRESULT */ -typedef int HRESULT; -# define SUCCEEDED(hr) ((HRESULT)(hr) >= 0) -# define FAILED(hr) ((HRESULT)(hr) < 0) - -# define _HRESULT_TYPEDEF_(x) ((HRESULT)x) - -# define S_OK _HRESULT_TYPEDEF_(0) -# define S_FALSE _HRESULT_TYPEDEF_(1) - -# define E_NOTIMPL _HRESULT_TYPEDEF_(0x80004001) -# define E_NOINTERFACE _HRESULT_TYPEDEF_(0x80004002) -# define E_POINTER _HRESULT_TYPEDEF_(0x80004003) -# define E_ABORT _HRESULT_TYPEDEF_(0x80004004) -# define E_FAIL _HRESULT_TYPEDEF_(0x80004005) -# define E_OUTOFMEMORY _HRESULT_TYPEDEF_(0x8007000E) -# define E_INVALIDARG _HRESULT_TYPEDEF_(0x80070057) - -# define DXGI_ERROR_NOT_FOUND _HRESULT_TYPEDEF_(0x887a0002) -# define DXGI_ERROR_MORE_DATA _HRESULT_TYPEDEF_(0x887a0003) - -# define D3DERR_INVALIDCALL _HRESULT_TYPEDEF_(0x8876086c) - -/* Basic types */ -typedef unsigned char BYTE; -typedef unsigned int DWORD; -typedef int INT; -typedef unsigned int UINT; -typedef int LONG; -typedef unsigned int ULONG; -typedef float FLOAT; -typedef LONG BOOL; - -/* Assuming LP64 model */ -typedef char INT8; -typedef unsigned char UINT8; -typedef short INT16; -typedef unsigned short UINT16; -typedef int INT32; -typedef unsigned int UINT32; -# if defined(__WIDL__) -typedef __int64 INT64; -typedef unsigned __int64 UINT64; -# else -typedef int64_t DECLSPEC_ALIGN(8) INT64; -typedef uint64_t DECLSPEC_ALIGN(8) UINT64; -# endif -typedef long LONG_PTR; -typedef unsigned long ULONG_PTR; - -typedef ULONG_PTR SIZE_T; - -# ifdef VKD3D_WIN32_WCHAR -typedef unsigned short WCHAR; -# else -typedef wchar_t WCHAR; -# endif /* VKD3D_WIN32_WCHAR */ -typedef void *HANDLE; - -/* GUID */ -# ifdef __WIDL__ -typedef struct -{ - unsigned long Data1; - unsigned short Data2; - unsigned short Data3; - unsigned char Data4[8]; -} GUID; -# else -typedef struct _GUID -{ - unsigned int Data1; - unsigned short Data2; - unsigned short Data3; - unsigned char Data4[8]; -} GUID; -# endif - -typedef GUID IID; - -# ifdef INITGUID -# ifndef __cplusplus -# define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - const GUID name DECLSPEC_HIDDEN; \ - const GUID name = \ - { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 }} -# else -# define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - EXTERN_C const GUID name DECLSPEC_HIDDEN; \ - EXTERN_C const GUID name = \ - { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 }} -# endif -# else -# define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - EXTERN_C const GUID name DECLSPEC_HIDDEN; -# endif /* INITGUID */ - -/* __uuidof emulation */ -#if defined(__cplusplus) && !defined(_MSC_VER) - -extern "C++" -{ - template const GUID &__vkd3d_uuidof(); -} - -# define __CRT_UUID_DECL(type, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - extern "C++" \ - { \ - template<> inline const GUID &__vkd3d_uuidof() \ - { \ - static const IID __uuid_inst = {l, w1, w2, {b1, b2, b3, b4, b5, b6, b7, b8}}; \ - return __uuid_inst; \ - } \ - template<> inline const GUID &__vkd3d_uuidof() \ - { \ - return __vkd3d_uuidof(); \ - } \ - } - -# define __uuidof(type) __vkd3d_uuidof() -#else -# define __CRT_UUID_DECL(type, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) -#endif /* defined(__cplusplus) && !defined(_MSC_VER) */ - -typedef struct SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES; -#endif /* !defined(_WIN32) || defined(__WIDL__) */ - - -#ifndef _WIN32 -# include -# include -# include - -# define COM_NO_WINDOWS_H - -# define FORCEINLINE inline - -# define CONTAINING_RECORD(address, type, field) \ - ((type *)((char *)(address) - offsetof(type, field))) - -# ifdef __x86_64__ -# define __stdcall __attribute__((ms_abi)) -# else -# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2)) || defined(__APPLE__) -# define __stdcall __attribute__((__stdcall__)) __attribute__((__force_align_arg_pointer__)) -# else -# define __stdcall __attribute__((__stdcall__)) -# endif -# endif - -# define WINAPI __stdcall -# define STDMETHODCALLTYPE __stdcall - -# ifdef __GNUC__ -# define DECLSPEC_SELECTANY __attribute__((weak)) -# endif - -/* Macros for COM interfaces */ -# define interface struct -# define BEGIN_INTERFACE -# define END_INTERFACE -# define MIDL_INTERFACE(x) struct - -# ifdef __cplusplus -# define EXTERN_C extern "C" -# else -# define EXTERN_C extern -# endif - -# define CONST_VTBL const - -# define TRUE 1 -# define FALSE 0 - -# if defined(__cplusplus) && !defined(CINTERFACE) -# define REFIID const IID & -# define REFGUID const GUID & -# else -# define REFIID const IID * const -# define REFGUID const GUID * const -# endif - -#if defined(__cplusplus) && !defined(CINTERFACE) -# define IsEqualGUID(guid1, guid2) (!memcmp(&(guid1), &(guid2), sizeof(GUID))) -#else -# define IsEqualGUID(guid1, guid2) (!memcmp(guid1, guid2, sizeof(GUID))) -#endif - -#elif !defined(__WIDL__) - -# include - -#endif /* _WIN32 */ - - -/* Define DECLSPEC_HIDDEN */ -#ifndef DECLSPEC_HIDDEN -# if defined(__MINGW32__) -# define DECLSPEC_HIDDEN -# elif defined(__GNUC__) -# define DECLSPEC_HIDDEN __attribute__((visibility("hidden"))) -# else -# define DECLSPEC_HIDDEN -# endif -#endif /* DECLSPEC_HIDDEN */ - -/* Define min() & max() macros */ -#ifndef NOMINMAX -# ifndef min -# define min(a, b) (((a) <= (b)) ? (a) : (b)) -# endif - -# ifndef max -# define max(a, b) (((a) >= (b)) ? (a) : (b)) -# endif -#endif /* NOMINMAX */ - -#ifndef DEFINE_ENUM_FLAG_OPERATORS -#ifdef __cplusplus -# define DEFINE_ENUM_FLAG_OPERATORS(type) \ -extern "C++" \ -{ \ - inline type operator &(type x, type y) { return (type)((int)x & (int)y); } \ - inline type operator &=(type &x, type y) { return (type &)((int &)x &= (int)y); } \ - inline type operator ~(type x) { return (type)~(int)x; } \ - inline type operator |(type x, type y) { return (type)((int)x | (int)y); } \ - inline type operator |=(type &x, type y) { return (type &)((int &)x |= (int)y); } \ - inline type operator ^(type x, type y) { return (type)((int)x ^ (int)y); } \ - inline type operator ^=(type &x, type y) { return (type &)((int &)x ^= (int)y); } \ -} -#else -# define DEFINE_ENUM_FLAG_OPERATORS(type) -#endif -#endif /* DEFINE_ENUM_FLAG_OPERATORS */ - -#endif /* _INC_WINDOWS */ -#endif /* __VKD3D_WINDOWS_H */ diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-common/CMakeLists.txt b/dll/directx/wine/d3d12/vkd3d/vkd3d-common/CMakeLists.txt deleted file mode 100644 index 33250c01c2944..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-common/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -include_directories("../include") -include_directories("../include/private") -add_library(vkd3d-common blob.c - debug.c - error.c - memory.c - utf8.c) - -add_dependencies(vkd3d-common vkd3d_idl_headers psdk) diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/CMakeLists.txt b/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/CMakeLists.txt deleted file mode 100644 index 9ef5190fc8fc0..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ - -include_directories("../include") -include_directories("../include/private") - -FLEX_TARGET(preproc_scanner preproc.l ${CMAKE_CURRENT_BINARY_DIR}/preproc.yy.c) -BISON_TARGET(preproc_parser preproc.y ${CMAKE_CURRENT_BINARY_DIR}/preproc.tab.c COMPILE_FLAGS "-p asmshader_") -ADD_FLEX_BISON_DEPENDENCY(preproc_scanner preproc_parser) - -FLEX_TARGET(hlsl_scanner hlsl.l ${CMAKE_CURRENT_BINARY_DIR}/hlsl.yy.c) -BISON_TARGET(hlsl_parser hlsl.y ${CMAKE_CURRENT_BINARY_DIR}/hlsl.tab.c COMPILE_FLAGS "-p hlsl_") -ADD_FLEX_BISON_DEPENDENCY(hlsl_scanner hlsl_parser) - -list(APPEND MISC_ITEMS - ${FLEX_preproc_scanner_OUTPUTS} - ${BISON_preproc_parser_OUTPUTS} - ${FLEX_hlsl_scanner_OUTPUTS} - ${BISON_hlsl_parser_OUTPUTS}) - -add_library(vkd3d-shader checksum.c - d3dbc.c - dxbc.c - glsl.c - hlsl_codegen.c - hlsl_constant_ops.c - hlsl_sm1.c - hlsl_sm4.c - hlsl.c - spirv.c - trace.c - vkd3d_shader_main.c - ${MISC_ITEMS}) - - -add_dependencies(vkd3d-shader vkd3d_idl_headers psdk) diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/hlsl.y b/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/hlsl.y deleted file mode 100644 index 6c39e75a1431e..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/hlsl.y +++ /dev/null @@ -1,3857 +0,0 @@ -/* - * HLSL parser - * - * Copyright 2008 Stefan Dösinger - * Copyright 2012 Matteo Bruni for CodeWeavers - * Copyright 2019-2020 Zebediah Figura for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -%code requires -{ - -#include "hlsl.h" -#include - -#define HLSL_YYLTYPE struct vkd3d_shader_location - -struct parse_parameter -{ - struct hlsl_type *type; - const char *name; - struct hlsl_semantic semantic; - struct hlsl_reg_reservation reg_reservation; - unsigned int modifiers; -}; - -struct parse_colon_attribute -{ - struct hlsl_semantic semantic; - struct hlsl_reg_reservation reg_reservation; -}; - -struct parse_initializer -{ - struct hlsl_ir_node **args; - unsigned int args_count; - struct list *instrs; -}; - -struct parse_array_sizes -{ - uint32_t *sizes; /* innermost first */ - unsigned int count; -}; - -struct parse_variable_def -{ - struct list entry; - struct vkd3d_shader_location loc; - - char *name; - struct parse_array_sizes arrays; - struct hlsl_semantic semantic; - struct hlsl_reg_reservation reg_reservation; - struct parse_initializer initializer; -}; - -struct parse_function -{ - char *name; - struct hlsl_ir_function_decl *decl; -}; - -struct parse_if_body -{ - struct list *then_instrs; - struct list *else_instrs; -}; - -enum parse_assign_op -{ - ASSIGN_OP_ASSIGN, - ASSIGN_OP_ADD, - ASSIGN_OP_SUB, - ASSIGN_OP_MUL, - ASSIGN_OP_DIV, - ASSIGN_OP_MOD, - ASSIGN_OP_LSHIFT, - ASSIGN_OP_RSHIFT, - ASSIGN_OP_AND, - ASSIGN_OP_OR, - ASSIGN_OP_XOR, -}; - -} - -%code provides -{ - -int yylex(HLSL_YYSTYPE *yylval_param, HLSL_YYLTYPE *yylloc_param, void *yyscanner); - -} - -%code -{ - -#define YYLLOC_DEFAULT(cur, rhs, n) (cur) = YYRHSLOC(rhs, !!n) - -static void yyerror(YYLTYPE *loc, void *scanner, struct hlsl_ctx *ctx, const char *s) -{ - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "%s", s); -} - -static struct hlsl_ir_node *node_from_list(struct list *list) -{ - return LIST_ENTRY(list_tail(list), struct hlsl_ir_node, entry); -} - -static struct list *make_empty_list(struct hlsl_ctx *ctx) -{ - struct list *list; - - if ((list = hlsl_alloc(ctx, sizeof(*list)))) - list_init(list); - return list; -} - -static void destroy_instr_list(struct list *list) -{ - hlsl_free_instr_list(list); - vkd3d_free(list); -} - -static void check_invalid_matrix_modifiers(struct hlsl_ctx *ctx, DWORD modifiers, struct vkd3d_shader_location loc) -{ - if (modifiers & HLSL_MODIFIERS_MAJORITY_MASK) - hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, - "'row_major' and 'column_major' modifiers are only allowed for matrices."); -} - -static bool convertible_data_type(struct hlsl_type *type) -{ - return type->type != HLSL_CLASS_OBJECT; -} - -static bool compatible_data_types(struct hlsl_type *t1, struct hlsl_type *t2) -{ - if (!convertible_data_type(t1) || !convertible_data_type(t2)) - return false; - - if (t1->type <= HLSL_CLASS_LAST_NUMERIC) - { - /* Scalar vars can be cast to pretty much everything */ - if (t1->dimx == 1 && t1->dimy == 1) - return true; - - if (t1->type == HLSL_CLASS_VECTOR && t2->type == HLSL_CLASS_VECTOR) - return t1->dimx >= t2->dimx; - } - - /* The other way around is true too i.e. whatever to scalar */ - if (t2->type <= HLSL_CLASS_LAST_NUMERIC && t2->dimx == 1 && t2->dimy == 1) - return true; - - if (t1->type == HLSL_CLASS_ARRAY) - { - if (hlsl_types_are_equal(t1->e.array.type, t2)) - /* e.g. float4[3] to float4 is allowed */ - return true; - - if (t2->type == HLSL_CLASS_ARRAY || t2->type == HLSL_CLASS_STRUCT) - return hlsl_type_component_count(t1) >= hlsl_type_component_count(t2); - else - return hlsl_type_component_count(t1) == hlsl_type_component_count(t2); - } - - if (t1->type == HLSL_CLASS_STRUCT) - return hlsl_type_component_count(t1) >= hlsl_type_component_count(t2); - - if (t2->type == HLSL_CLASS_ARRAY || t2->type == HLSL_CLASS_STRUCT) - return hlsl_type_component_count(t1) == hlsl_type_component_count(t2); - - if (t1->type == HLSL_CLASS_MATRIX || t2->type == HLSL_CLASS_MATRIX) - { - if (t1->type == HLSL_CLASS_MATRIX && t2->type == HLSL_CLASS_MATRIX && t1->dimx >= t2->dimx && t1->dimy >= t2->dimy) - return true; - - /* Matrix-vector conversion is apparently allowed if they have the same components count */ - if ((t1->type == HLSL_CLASS_VECTOR || t2->type == HLSL_CLASS_VECTOR) - && hlsl_type_component_count(t1) == hlsl_type_component_count(t2)) - return true; - return false; - } - - if (hlsl_type_component_count(t1) >= hlsl_type_component_count(t2)) - return true; - return false; -} - -static bool implicit_compatible_data_types(struct hlsl_type *t1, struct hlsl_type *t2) -{ - if (!convertible_data_type(t1) || !convertible_data_type(t2)) - return false; - - if (t1->type <= HLSL_CLASS_LAST_NUMERIC) - { - /* Scalar vars can be converted to any other numeric data type */ - if (t1->dimx == 1 && t1->dimy == 1 && t2->type <= HLSL_CLASS_LAST_NUMERIC) - return true; - /* The other way around is true too */ - if (t2->dimx == 1 && t2->dimy == 1 && t2->type <= HLSL_CLASS_LAST_NUMERIC) - return true; - } - - if (t1->type == HLSL_CLASS_ARRAY && t2->type == HLSL_CLASS_ARRAY) - { - return hlsl_type_component_count(t1) == hlsl_type_component_count(t2); - } - - if ((t1->type == HLSL_CLASS_ARRAY && t2->type <= HLSL_CLASS_LAST_NUMERIC) - || (t1->type <= HLSL_CLASS_LAST_NUMERIC && t2->type == HLSL_CLASS_ARRAY)) - { - /* e.g. float4[3] to float4 is allowed */ - if (t1->type == HLSL_CLASS_ARRAY && hlsl_types_are_equal(t1->e.array.type, t2)) - return true; - if (hlsl_type_component_count(t1) == hlsl_type_component_count(t2)) - return true; - return false; - } - - if (t1->type <= HLSL_CLASS_VECTOR && t2->type <= HLSL_CLASS_VECTOR) - { - if (t1->dimx >= t2->dimx) - return true; - return false; - } - - if (t1->type == HLSL_CLASS_MATRIX || t2->type == HLSL_CLASS_MATRIX) - { - if (t1->type == HLSL_CLASS_MATRIX && t2->type == HLSL_CLASS_MATRIX) - return t1->dimx >= t2->dimx && t1->dimy >= t2->dimy; - - /* Matrix-vector conversion is apparently allowed if they have - * the same components count, or if the matrix is 1xN or Nx1 - * and we are reducing the component count */ - if (t1->type == HLSL_CLASS_VECTOR || t2->type == HLSL_CLASS_VECTOR) - { - if (hlsl_type_component_count(t1) == hlsl_type_component_count(t2)) - return true; - - if ((t1->type == HLSL_CLASS_VECTOR || t1->dimx == 1 || t1->dimy == 1) && - (t2->type == HLSL_CLASS_VECTOR || t2->dimx == 1 || t2->dimy == 1)) - return hlsl_type_component_count(t1) >= hlsl_type_component_count(t2); - } - - return false; - } - - if (t1->type == HLSL_CLASS_STRUCT && t2->type == HLSL_CLASS_STRUCT) - return hlsl_types_are_equal(t1, t2); - - return false; -} - -static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct list *instrs, - struct hlsl_ir_node *node, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc) -{ - struct hlsl_type *src_type = node->data_type; - struct hlsl_ir_expr *cast; - - if (hlsl_types_are_equal(src_type, dst_type)) - return node; - - if (!implicit_compatible_data_types(src_type, dst_type)) - { - struct vkd3d_string_buffer *src_string, *dst_string; - - src_string = hlsl_type_to_string(ctx, src_type); - dst_string = hlsl_type_to_string(ctx, dst_type); - if (src_string && dst_string) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Can't implicitly convert from %s to %s.", src_string->buffer, dst_string->buffer); - hlsl_release_string_buffer(ctx, src_string); - hlsl_release_string_buffer(ctx, dst_string); - return NULL; - } - - if (dst_type->dimx * dst_type->dimy < src_type->dimx * src_type->dimy) - hlsl_warning(ctx, loc, VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION, "Implicit truncation of %s type.", - src_type->type == HLSL_CLASS_VECTOR ? "vector" : "matrix"); - - if (!(cast = hlsl_new_cast(ctx, node, dst_type, loc))) - return NULL; - list_add_tail(instrs, &cast->node.entry); - return &cast->node; -} - -static DWORD add_modifiers(struct hlsl_ctx *ctx, DWORD modifiers, DWORD mod, const struct vkd3d_shader_location loc) -{ - if (modifiers & mod) - { - struct vkd3d_string_buffer *string; - - if ((string = hlsl_modifiers_to_string(ctx, mod))) - hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, - "Modifier '%s' was already specified.", string->buffer); - hlsl_release_string_buffer(ctx, string); - return modifiers; - } - if ((mod & HLSL_MODIFIERS_MAJORITY_MASK) && (modifiers & HLSL_MODIFIERS_MAJORITY_MASK)) - { - hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, - "'row_major' and 'column_major' modifiers are mutually exclusive."); - return modifiers; - } - return modifiers | mod; -} - -static bool append_conditional_break(struct hlsl_ctx *ctx, struct list *cond_list) -{ - struct hlsl_ir_node *condition, *not; - struct hlsl_ir_jump *jump; - struct hlsl_ir_if *iff; - - /* E.g. "for (i = 0; ; ++i)". */ - if (list_empty(cond_list)) - return true; - - condition = node_from_list(cond_list); - if (!(not = hlsl_new_unary_expr(ctx, HLSL_OP1_LOGIC_NOT, condition, condition->loc))) - return false; - list_add_tail(cond_list, ¬->entry); - - if (!(iff = hlsl_new_if(ctx, not, condition->loc))) - return false; - list_add_tail(cond_list, &iff->node.entry); - - if (!(jump = hlsl_new_jump(ctx, HLSL_IR_JUMP_BREAK, condition->loc))) - return false; - list_add_head(&iff->then_instrs.instrs, &jump->node.entry); - return true; -} - -enum loop_type -{ - LOOP_FOR, - LOOP_WHILE, - LOOP_DO_WHILE -}; - -static struct list *create_loop(struct hlsl_ctx *ctx, enum loop_type type, struct list *init, struct list *cond, - struct list *iter, struct list *body, struct vkd3d_shader_location loc) -{ - struct list *list = NULL; - struct hlsl_ir_loop *loop = NULL; - struct hlsl_ir_if *cond_jump = NULL; - - if (!(list = make_empty_list(ctx))) - goto oom; - - if (init) - list_move_head(list, init); - - if (!(loop = hlsl_new_loop(ctx, loc))) - goto oom; - list_add_tail(list, &loop->node.entry); - - if (!append_conditional_break(ctx, cond)) - goto oom; - - if (type != LOOP_DO_WHILE) - list_move_tail(&loop->body.instrs, cond); - - list_move_tail(&loop->body.instrs, body); - - if (iter) - list_move_tail(&loop->body.instrs, iter); - - if (type == LOOP_DO_WHILE) - list_move_tail(&loop->body.instrs, cond); - - vkd3d_free(init); - vkd3d_free(cond); - vkd3d_free(body); - return list; - -oom: - vkd3d_free(loop); - vkd3d_free(cond_jump); - vkd3d_free(list); - destroy_instr_list(init); - destroy_instr_list(cond); - destroy_instr_list(iter); - destroy_instr_list(body); - return NULL; -} - -static unsigned int initializer_size(const struct parse_initializer *initializer) -{ - unsigned int count = 0, i; - - for (i = 0; i < initializer->args_count; ++i) - { - count += hlsl_type_component_count(initializer->args[i]->data_type); - } - return count; -} - -static void free_parse_initializer(struct parse_initializer *initializer) -{ - destroy_instr_list(initializer->instrs); - vkd3d_free(initializer->args); -} - -static struct hlsl_ir_swizzle *get_swizzle(struct hlsl_ctx *ctx, struct hlsl_ir_node *value, const char *swizzle, - struct vkd3d_shader_location *loc) -{ - unsigned int len = strlen(swizzle), component = 0; - unsigned int i, set, swiz = 0; - bool valid; - - if (value->data_type->type == HLSL_CLASS_MATRIX) - { - /* Matrix swizzle */ - bool m_swizzle; - unsigned int inc, x, y; - - if (len < 3 || swizzle[0] != '_') - return NULL; - m_swizzle = swizzle[1] == 'm'; - inc = m_swizzle ? 4 : 3; - - if (len % inc || len > inc * 4) - return NULL; - - for (i = 0; i < len; i += inc) - { - if (swizzle[i] != '_') - return NULL; - if (m_swizzle) - { - if (swizzle[i + 1] != 'm') - return NULL; - y = swizzle[i + 2] - '0'; - x = swizzle[i + 3] - '0'; - } - else - { - y = swizzle[i + 1] - '1'; - x = swizzle[i + 2] - '1'; - } - - if (x >= value->data_type->dimx || y >= value->data_type->dimy) - return NULL; - swiz |= (y << 4 | x) << component * 8; - component++; - } - return hlsl_new_swizzle(ctx, swiz, component, value, loc); - } - - /* Vector swizzle */ - if (len > 4) - return NULL; - - for (set = 0; set < 2; ++set) - { - valid = true; - component = 0; - for (i = 0; i < len; ++i) - { - char c[2][4] = {{'x', 'y', 'z', 'w'}, {'r', 'g', 'b', 'a'}}; - unsigned int s = 0; - - for (s = 0; s < 4; ++s) - { - if (swizzle[i] == c[set][s]) - break; - } - if (s == 4) - { - valid = false; - break; - } - - if (s >= value->data_type->dimx) - return NULL; - swiz |= s << component * 2; - component++; - } - if (valid) - return hlsl_new_swizzle(ctx, swiz, component, value, loc); - } - - return NULL; -} - -static struct hlsl_ir_jump *add_return(struct hlsl_ctx *ctx, struct list *instrs, - struct hlsl_ir_node *return_value, struct vkd3d_shader_location loc) -{ - struct hlsl_type *return_type = ctx->cur_function->return_type; - struct hlsl_ir_jump *jump; - - if (return_value) - { - struct hlsl_ir_store *store; - - if (!(return_value = add_implicit_conversion(ctx, instrs, return_value, return_type, &loc))) - return NULL; - - if (!(store = hlsl_new_simple_store(ctx, ctx->cur_function->return_var, return_value))) - return NULL; - list_add_after(&return_value->entry, &store->node.entry); - } - else if (ctx->cur_function->return_var) - { - hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RETURN, "Non-void function must return a value."); - return NULL; - } - - if (!(jump = hlsl_new_jump(ctx, HLSL_IR_JUMP_RETURN, loc))) - return NULL; - list_add_tail(instrs, &jump->node.entry); - - return jump; -} - -static struct hlsl_ir_load *add_load(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_node, - struct hlsl_ir_node *offset, struct hlsl_type *data_type, const struct vkd3d_shader_location loc) -{ - struct hlsl_ir_node *add = NULL; - struct hlsl_ir_load *load; - struct hlsl_ir_var *var; - - if (var_node->type == HLSL_IR_LOAD) - { - const struct hlsl_deref *src = &hlsl_ir_load(var_node)->src; - - var = src->var; - if (src->offset.node) - { - if (!(add = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, src->offset.node, offset))) - return NULL; - list_add_tail(instrs, &add->entry); - offset = add; - } - } - else - { - struct hlsl_ir_store *store; - char name[27]; - - sprintf(name, "", var_node); - if (!(var = hlsl_new_synthetic_var(ctx, name, var_node->data_type, var_node->loc))) - return NULL; - - if (!(store = hlsl_new_simple_store(ctx, var, var_node))) - return NULL; - - list_add_tail(instrs, &store->node.entry); - } - - if (!(load = hlsl_new_load(ctx, var, offset, data_type, loc))) - return NULL; - list_add_tail(instrs, &load->node.entry); - return load; -} - -static struct hlsl_ir_load *add_record_load(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *record, - const struct hlsl_struct_field *field, const struct vkd3d_shader_location loc) -{ - struct hlsl_ir_constant *c; - - if (!(c = hlsl_new_uint_constant(ctx, field->reg_offset, loc))) - return NULL; - list_add_tail(instrs, &c->node.entry); - - return add_load(ctx, instrs, record, &c->node, field->type, loc); -} - -static struct hlsl_ir_load *add_array_load(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *array, - struct hlsl_ir_node *index, const struct vkd3d_shader_location loc) -{ - const struct hlsl_type *expr_type = array->data_type; - struct hlsl_type *data_type; - struct hlsl_ir_constant *c; - struct hlsl_ir_node *mul; - - if (expr_type->type == HLSL_CLASS_ARRAY) - { - data_type = expr_type->e.array.type; - } - else if (expr_type->type == HLSL_CLASS_MATRIX || expr_type->type == HLSL_CLASS_VECTOR) - { - /* This needs to be lowered now, while we still have type information. */ - FIXME("Index of matrix or vector type.\n"); - return NULL; - } - else - { - if (expr_type->type == HLSL_CLASS_SCALAR) - hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_INVALID_INDEX, "Scalar expressions cannot be array-indexed."); - else - hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_INVALID_INDEX, "Expression cannot be array-indexed."); - return NULL; - } - - if (!(c = hlsl_new_uint_constant(ctx, data_type->reg_size, loc))) - return NULL; - list_add_tail(instrs, &c->node.entry); - if (!(mul = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, index, &c->node))) - return NULL; - list_add_tail(instrs, &mul->entry); - index = mul; - - return add_load(ctx, instrs, array, index, data_type, loc); -} - -static struct hlsl_struct_field *get_struct_field(struct list *fields, const char *name) -{ - struct hlsl_struct_field *f; - - LIST_FOR_EACH_ENTRY(f, fields, struct hlsl_struct_field, entry) - { - if (!strcmp(f->name, name)) - return f; - } - return NULL; -} - -static struct hlsl_type *apply_type_modifiers(struct hlsl_ctx *ctx, struct hlsl_type *type, - unsigned int *modifiers, struct vkd3d_shader_location loc) -{ - unsigned int default_majority = 0; - struct hlsl_type *new_type; - - /* This function is only used for declarations (i.e. variables and struct - * fields), which should inherit the matrix majority. We only explicitly set - * the default majority for declarations—typedefs depend on this—but we - * want to always set it, so that an hlsl_type object is never used to - * represent two different majorities (and thus can be used to store its - * register size, etc.) */ - if (!(*modifiers & HLSL_MODIFIERS_MAJORITY_MASK) - && !(type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK) - && type->type == HLSL_CLASS_MATRIX) - { - if (ctx->matrix_majority == HLSL_COLUMN_MAJOR) - default_majority = HLSL_MODIFIER_COLUMN_MAJOR; - else - default_majority = HLSL_MODIFIER_ROW_MAJOR; - } - - if (!default_majority && !(*modifiers & HLSL_TYPE_MODIFIERS_MASK)) - return type; - - if (!(new_type = hlsl_type_clone(ctx, type, default_majority, *modifiers & HLSL_TYPE_MODIFIERS_MASK))) - return NULL; - - *modifiers &= ~HLSL_TYPE_MODIFIERS_MASK; - - if ((new_type->modifiers & HLSL_MODIFIER_ROW_MAJOR) && (new_type->modifiers & HLSL_MODIFIER_COLUMN_MAJOR)) - hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, - "'row_major' and 'column_major' modifiers are mutually exclusive."); - - return new_type; -} - -static struct list *gen_struct_fields(struct hlsl_ctx *ctx, struct hlsl_type *type, struct list *fields) -{ - struct parse_variable_def *v, *v_next; - struct hlsl_struct_field *field; - struct list *list; - - if (type->type == HLSL_CLASS_MATRIX) - assert(type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK); - - if (!(list = make_empty_list(ctx))) - return NULL; - LIST_FOR_EACH_ENTRY_SAFE(v, v_next, fields, struct parse_variable_def, entry) - { - unsigned int i; - - if (!(field = hlsl_alloc(ctx, sizeof(*field)))) - { - vkd3d_free(v); - return list; - } - - field->type = type; - for (i = 0; i < v->arrays.count; ++i) - field->type = hlsl_new_array_type(ctx, field->type, v->arrays.sizes[i]); - field->loc = v->loc; - field->name = v->name; - field->semantic = v->semantic; - if (v->initializer.args_count) - { - hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Illegal initializer on a struct field."); - free_parse_initializer(&v->initializer); - } - list_add_tail(list, &field->entry); - vkd3d_free(v); - } - vkd3d_free(fields); - return list; -} - -static bool add_typedef(struct hlsl_ctx *ctx, DWORD modifiers, struct hlsl_type *orig_type, struct list *list) -{ - struct parse_variable_def *v, *v_next; - struct hlsl_type *type; - unsigned int i; - bool ret; - - LIST_FOR_EACH_ENTRY_SAFE(v, v_next, list, struct parse_variable_def, entry) - { - if (!v->arrays.count) - { - if (!(type = hlsl_type_clone(ctx, orig_type, 0, modifiers))) - return false; - } - else - { - type = orig_type; - } - - for (i = 0; i < v->arrays.count; ++i) - { - if (!(type = hlsl_new_array_type(ctx, type, v->arrays.sizes[i]))) - return false; - } - - vkd3d_free((void *)type->name); - type->name = v->name; - - if (type->type != HLSL_CLASS_MATRIX) - check_invalid_matrix_modifiers(ctx, type->modifiers, v->loc); - - if ((type->modifiers & HLSL_MODIFIER_COLUMN_MAJOR) - && (type->modifiers & HLSL_MODIFIER_ROW_MAJOR)) - hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, - "'row_major' and 'column_major' modifiers are mutually exclusive."); - - ret = hlsl_scope_add_type(ctx->cur_scope, type); - if (!ret) - hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, - "Type '%s' is already defined.", v->name); - vkd3d_free(v); - } - vkd3d_free(list); - return true; -} - -static bool add_func_parameter(struct hlsl_ctx *ctx, struct list *list, - struct parse_parameter *param, const struct vkd3d_shader_location loc) -{ - struct hlsl_ir_var *var; - - if (param->type->type == HLSL_CLASS_MATRIX) - assert(param->type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK); - - if ((param->modifiers & HLSL_STORAGE_OUT) && (param->modifiers & HLSL_STORAGE_UNIFORM)) - hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, - "Parameter '%s' is declared as both \"out\" and \"uniform\".", param->name); - - if (!(var = hlsl_new_var(ctx, param->name, param->type, loc, ¶m->semantic, param->modifiers, ¶m->reg_reservation))) - return false; - var->is_param = 1; - - if (!hlsl_add_var(ctx, var, false)) - { - hlsl_free_var(var); - return false; - } - list_add_tail(list, &var->param_entry); - return true; -} - -static struct hlsl_reg_reservation parse_reg_reservation(const char *reg_string) -{ - struct hlsl_reg_reservation reservation = {0}; - - if (!sscanf(reg_string + 1, "%u", &reservation.index)) - { - FIXME("Unsupported register reservation syntax.\n"); - return reservation; - } - reservation.type = reg_string[0]; - return reservation; -} - -static const struct hlsl_ir_function_decl *get_func_decl(struct wine_rb_tree *funcs, char *name, struct list *params) -{ - struct hlsl_ir_function *func; - struct wine_rb_entry *entry; - - if ((entry = wine_rb_get(funcs, name))) - { - func = RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry); - - if ((entry = wine_rb_get(&func->overloads, params))) - return RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry); - } - return NULL; -} - -static struct list *make_list(struct hlsl_ctx *ctx, struct hlsl_ir_node *node) -{ - struct list *list; - - if (!(list = make_empty_list(ctx))) - { - hlsl_free_instr(node); - return NULL; - } - list_add_tail(list, &node->entry); - return list; -} - -static unsigned int evaluate_array_dimension(struct hlsl_ir_node *node) -{ - if (node->data_type->type != HLSL_CLASS_SCALAR) - return 0; - - switch (node->type) - { - case HLSL_IR_CONSTANT: - { - struct hlsl_ir_constant *constant = hlsl_ir_constant(node); - const union hlsl_constant_value *value = &constant->value[0]; - - switch (constant->node.data_type->base_type) - { - case HLSL_TYPE_UINT: - return value->u; - case HLSL_TYPE_INT: - return value->i; - case HLSL_TYPE_FLOAT: - case HLSL_TYPE_HALF: - return value->f; - case HLSL_TYPE_DOUBLE: - return value->d; - case HLSL_TYPE_BOOL: - return value->b; - default: - assert(0); - return 0; - } - } - - case HLSL_IR_EXPR: - case HLSL_IR_LOAD: - case HLSL_IR_RESOURCE_LOAD: - case HLSL_IR_SWIZZLE: - FIXME("Unhandled type %s.\n", hlsl_node_type_to_string(node->type)); - return 0; - - case HLSL_IR_IF: - case HLSL_IR_JUMP: - case HLSL_IR_LOOP: - case HLSL_IR_STORE: - WARN("Invalid node type %s.\n", hlsl_node_type_to_string(node->type)); - return 0; - } - - assert(0); - return 0; -} - -static bool expr_compatible_data_types(struct hlsl_type *t1, struct hlsl_type *t2) -{ - if (t1->base_type > HLSL_TYPE_LAST_SCALAR || t2->base_type > HLSL_TYPE_LAST_SCALAR) - return false; - - /* Scalar vars can be converted to pretty much everything */ - if ((t1->dimx == 1 && t1->dimy == 1) || (t2->dimx == 1 && t2->dimy == 1)) - return true; - - if (t1->type == HLSL_CLASS_VECTOR && t2->type == HLSL_CLASS_VECTOR) - return true; - - if (t1->type == HLSL_CLASS_MATRIX || t2->type == HLSL_CLASS_MATRIX) - { - /* Matrix-vector conversion is apparently allowed if either they have the same components - count or the matrix is nx1 or 1xn */ - if (t1->type == HLSL_CLASS_VECTOR || t2->type == HLSL_CLASS_VECTOR) - { - if (hlsl_type_component_count(t1) == hlsl_type_component_count(t2)) - return true; - - return (t1->type == HLSL_CLASS_MATRIX && (t1->dimx == 1 || t1->dimy == 1)) - || (t2->type == HLSL_CLASS_MATRIX && (t2->dimx == 1 || t2->dimy == 1)); - } - - /* Both matrices */ - if ((t1->dimx >= t2->dimx && t1->dimy >= t2->dimy) - || (t1->dimx <= t2->dimx && t1->dimy <= t2->dimy)) - return true; - } - - return false; -} - -static enum hlsl_base_type expr_common_base_type(enum hlsl_base_type t1, enum hlsl_base_type t2) -{ - if (t1 > HLSL_TYPE_LAST_SCALAR || t2 > HLSL_TYPE_LAST_SCALAR) { - FIXME("Unexpected base type.\n"); - return HLSL_TYPE_FLOAT; - } - if (t1 == t2) - return t1 == HLSL_TYPE_BOOL ? HLSL_TYPE_INT : t1; - if (t1 == HLSL_TYPE_DOUBLE || t2 == HLSL_TYPE_DOUBLE) - return HLSL_TYPE_DOUBLE; - if (t1 == HLSL_TYPE_FLOAT || t2 == HLSL_TYPE_FLOAT - || t1 == HLSL_TYPE_HALF || t2 == HLSL_TYPE_HALF) - return HLSL_TYPE_FLOAT; - if (t1 == HLSL_TYPE_UINT || t2 == HLSL_TYPE_UINT) - return HLSL_TYPE_UINT; - return HLSL_TYPE_INT; -} - -static bool expr_common_shape(struct hlsl_ctx *ctx, struct hlsl_type *t1, struct hlsl_type *t2, - const struct vkd3d_shader_location *loc, enum hlsl_type_class *type, unsigned int *dimx, unsigned int *dimy) -{ - if (t1->type > HLSL_CLASS_LAST_NUMERIC) - { - struct vkd3d_string_buffer *string; - - if ((string = hlsl_type_to_string(ctx, t1))) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Expression of type \"%s\" cannot be used in a numeric expression.", string->buffer); - hlsl_release_string_buffer(ctx, string); - return false; - } - - if (t2->type > HLSL_CLASS_LAST_NUMERIC) - { - struct vkd3d_string_buffer *string; - - if ((string = hlsl_type_to_string(ctx, t2))) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Expression of type \"%s\" cannot be used in a numeric expression.", string->buffer); - hlsl_release_string_buffer(ctx, string); - return false; - } - - if (!expr_compatible_data_types(t1, t2)) - { - struct vkd3d_string_buffer *t1_string = hlsl_type_to_string(ctx, t1); - struct vkd3d_string_buffer *t2_string = hlsl_type_to_string(ctx, t2); - - if (t1_string && t2_string) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Expression data types \"%s\" and \"%s\" are incompatible.", - t1_string->buffer, t2_string->buffer); - hlsl_release_string_buffer(ctx, t1_string); - hlsl_release_string_buffer(ctx, t2_string); - return false; - } - - if (t1->dimx == 1 && t1->dimy == 1) - { - *type = t2->type; - *dimx = t2->dimx; - *dimy = t2->dimy; - } - else if (t2->dimx == 1 && t2->dimy == 1) - { - *type = t1->type; - *dimx = t1->dimx; - *dimy = t1->dimy; - } - else if (t1->type == HLSL_CLASS_MATRIX && t2->type == HLSL_CLASS_MATRIX) - { - *type = HLSL_CLASS_MATRIX; - *dimx = min(t1->dimx, t2->dimx); - *dimy = min(t1->dimy, t2->dimy); - } - else - { - if (t1->dimx * t1->dimy <= t2->dimx * t2->dimy) - { - *type = t1->type; - *dimx = t1->dimx; - *dimy = t1->dimy; - } - else - { - *type = t2->type; - *dimx = t2->dimx; - *dimy = t2->dimy; - } - } - - return true; -} - -static struct hlsl_ir_expr *add_expr(struct hlsl_ctx *ctx, struct list *instrs, - enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], - struct hlsl_type *type, const struct vkd3d_shader_location *loc) -{ - struct hlsl_ir_expr *expr; - unsigned int i; - - if (!(expr = hlsl_alloc(ctx, sizeof(*expr)))) - return NULL; - init_node(&expr->node, HLSL_IR_EXPR, type, *loc); - expr->op = op; - for (i = 0; i < HLSL_MAX_OPERANDS; ++i) - hlsl_src_from_node(&expr->operands[i], operands[i]); - list_add_tail(instrs, &expr->node.entry); - - return expr; -} - -static void check_integer_type(struct hlsl_ctx *ctx, const struct hlsl_ir_node *instr) -{ - const struct hlsl_type *type = instr->data_type; - struct vkd3d_string_buffer *string; - - switch (type->base_type) - { - case HLSL_TYPE_BOOL: - case HLSL_TYPE_INT: - case HLSL_TYPE_UINT: - break; - - default: - if ((string = hlsl_type_to_string(ctx, type))) - hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Expression type '%s' is not integer.", string->buffer); - hlsl_release_string_buffer(ctx, string); - break; - } -} - -static struct hlsl_ir_expr *add_unary_arithmetic_expr(struct hlsl_ctx *ctx, struct list *instrs, - enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc) -{ - struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {arg}; - - return add_expr(ctx, instrs, op, args, arg->data_type, loc); -} - -static struct hlsl_ir_expr *add_unary_bitwise_expr(struct hlsl_ctx *ctx, struct list *instrs, - enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc) -{ - check_integer_type(ctx, arg); - - return add_unary_arithmetic_expr(ctx, instrs, op, arg, loc); -} - -static struct hlsl_ir_expr *add_unary_logical_expr(struct hlsl_ctx *ctx, struct list *instrs, - enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc) -{ - struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0}; - struct hlsl_type *bool_type; - - bool_type = hlsl_get_numeric_type(ctx, arg->data_type->type, HLSL_TYPE_BOOL, - arg->data_type->dimx, arg->data_type->dimy); - - if (!(args[0] = add_implicit_conversion(ctx, instrs, arg, bool_type, loc))) - return NULL; - - return add_expr(ctx, instrs, op, args, bool_type, loc); -} - -static struct hlsl_ir_expr *add_binary_arithmetic_expr(struct hlsl_ctx *ctx, struct list *instrs, - enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, - const struct vkd3d_shader_location *loc) -{ - struct hlsl_type *common_type; - enum hlsl_base_type base = expr_common_base_type(arg1->data_type->base_type, arg2->data_type->base_type); - enum hlsl_type_class type; - unsigned int dimx, dimy; - struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0}; - - if (!expr_common_shape(ctx, arg1->data_type, arg2->data_type, loc, &type, &dimx, &dimy)) - return NULL; - - common_type = hlsl_get_numeric_type(ctx, type, base, dimx, dimy); - - if (!(args[0] = add_implicit_conversion(ctx, instrs, arg1, common_type, loc))) - return NULL; - - if (!(args[1] = add_implicit_conversion(ctx, instrs, arg2, common_type, loc))) - return NULL; - - return add_expr(ctx, instrs, op, args, common_type, loc); -} - -static struct list *add_binary_arithmetic_expr_merge(struct hlsl_ctx *ctx, struct list *list1, struct list *list2, - enum hlsl_ir_expr_op op, struct vkd3d_shader_location loc) -{ - struct hlsl_ir_node *arg1 = node_from_list(list1), *arg2 = node_from_list(list2); - - list_move_tail(list1, list2); - vkd3d_free(list2); - add_binary_arithmetic_expr(ctx, list1, op, arg1, arg2, &loc); - return list1; -} - -static struct hlsl_ir_expr *add_binary_bitwise_expr(struct hlsl_ctx *ctx, struct list *instrs, - enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, - const struct vkd3d_shader_location *loc) -{ - check_integer_type(ctx, arg1); - check_integer_type(ctx, arg2); - - return add_binary_arithmetic_expr(ctx, instrs, op, arg1, arg2, loc); -} - -static struct list *add_binary_bitwise_expr_merge(struct hlsl_ctx *ctx, struct list *list1, struct list *list2, - enum hlsl_ir_expr_op op, const struct vkd3d_shader_location *loc) -{ - struct hlsl_ir_node *arg1 = node_from_list(list1), *arg2 = node_from_list(list2); - - list_move_tail(list1, list2); - vkd3d_free(list2); - add_binary_bitwise_expr(ctx, list1, op, arg1, arg2, loc); - - return list1; -} - -static struct hlsl_ir_expr *add_binary_comparison_expr(struct hlsl_ctx *ctx, struct list *instrs, - enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, - struct vkd3d_shader_location *loc) -{ - struct hlsl_type *common_type, *return_type; - enum hlsl_base_type base = expr_common_base_type(arg1->data_type->base_type, arg2->data_type->base_type); - enum hlsl_type_class type; - unsigned int dimx, dimy; - struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0}; - - if (!expr_common_shape(ctx, arg1->data_type, arg2->data_type, loc, &type, &dimx, &dimy)) - return NULL; - - common_type = hlsl_get_numeric_type(ctx, type, base, dimx, dimy); - return_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_BOOL, dimx, dimy); - - if (!(args[0] = add_implicit_conversion(ctx, instrs, arg1, common_type, loc))) - return NULL; - - if (!(args[1] = add_implicit_conversion(ctx, instrs, arg2, common_type, loc))) - return NULL; - - return add_expr(ctx, instrs, op, args, return_type, loc); -} - -static struct list *add_binary_comparison_expr_merge(struct hlsl_ctx *ctx, struct list *list1, struct list *list2, - enum hlsl_ir_expr_op op, struct vkd3d_shader_location loc) -{ - struct hlsl_ir_node *arg1 = node_from_list(list1), *arg2 = node_from_list(list2); - - list_move_tail(list1, list2); - vkd3d_free(list2); - add_binary_comparison_expr(ctx, list1, op, arg1, arg2, &loc); - return list1; -} - -static struct hlsl_ir_expr *add_binary_logical_expr(struct hlsl_ctx *ctx, struct list *instrs, - enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, - const struct vkd3d_shader_location *loc) -{ - struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0}; - struct hlsl_type *common_type; - enum hlsl_type_class type; - unsigned int dimx, dimy; - - if (!expr_common_shape(ctx, arg1->data_type, arg2->data_type, loc, &type, &dimx, &dimy)) - return NULL; - - common_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_BOOL, dimx, dimy); - - if (!(args[0] = add_implicit_conversion(ctx, instrs, arg1, common_type, loc))) - return NULL; - - if (!(args[1] = add_implicit_conversion(ctx, instrs, arg2, common_type, loc))) - return NULL; - - return add_expr(ctx, instrs, op, args, common_type, loc); -} - -static struct list *add_binary_logical_expr_merge(struct hlsl_ctx *ctx, struct list *list1, struct list *list2, - enum hlsl_ir_expr_op op, const struct vkd3d_shader_location *loc) -{ - struct hlsl_ir_node *arg1 = node_from_list(list1), *arg2 = node_from_list(list2); - - list_move_tail(list1, list2); - vkd3d_free(list2); - add_binary_logical_expr(ctx, list1, op, arg1, arg2, loc); - - return list1; -} - -static struct hlsl_ir_expr *add_binary_shift_expr(struct hlsl_ctx *ctx, struct list *instrs, - enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, - const struct vkd3d_shader_location *loc) -{ - enum hlsl_base_type base = arg1->data_type->base_type; - struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0}; - struct hlsl_type *return_type, *integer_type; - enum hlsl_type_class type; - unsigned int dimx, dimy; - - check_integer_type(ctx, arg1); - check_integer_type(ctx, arg2); - - if (base == HLSL_TYPE_BOOL) - base = HLSL_TYPE_INT; - - if (!expr_common_shape(ctx, arg1->data_type, arg2->data_type, loc, &type, &dimx, &dimy)) - return NULL; - - return_type = hlsl_get_numeric_type(ctx, type, base, dimx, dimy); - integer_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_INT, dimx, dimy); - - if (!(args[0] = add_implicit_conversion(ctx, instrs, arg1, return_type, loc))) - return NULL; - - if (!(args[1] = add_implicit_conversion(ctx, instrs, arg2, integer_type, loc))) - return NULL; - - return add_expr(ctx, instrs, op, args, return_type, loc); -} - -static struct list *add_binary_shift_expr_merge(struct hlsl_ctx *ctx, struct list *list1, struct list *list2, - enum hlsl_ir_expr_op op, const struct vkd3d_shader_location *loc) -{ - struct hlsl_ir_node *arg1 = node_from_list(list1), *arg2 = node_from_list(list2); - - list_move_tail(list1, list2); - vkd3d_free(list2); - add_binary_shift_expr(ctx, list1, op, arg1, arg2, loc); - - return list1; -} - -static enum hlsl_ir_expr_op op_from_assignment(enum parse_assign_op op) -{ - static const enum hlsl_ir_expr_op ops[] = - { - 0, - HLSL_OP2_ADD, - 0, - HLSL_OP2_MUL, - HLSL_OP2_DIV, - HLSL_OP2_MOD, - HLSL_OP2_LSHIFT, - HLSL_OP2_RSHIFT, - HLSL_OP2_BIT_AND, - HLSL_OP2_BIT_OR, - HLSL_OP2_BIT_XOR, - }; - - return ops[op]; -} - -static bool invert_swizzle(unsigned int *swizzle, unsigned int *writemask, unsigned int *ret_width) -{ - unsigned int i, j, bit = 0, inverted = 0, width, new_writemask = 0, new_swizzle = 0; - - /* Apply the writemask to the swizzle to get a new writemask and swizzle. */ - for (i = 0; i < 4; ++i) - { - if (*writemask & (1 << i)) - { - unsigned int s = (*swizzle >> (i * 2)) & 3; - new_swizzle |= s << (bit++ * 2); - if (new_writemask & (1 << s)) - return false; - new_writemask |= 1 << s; - } - } - width = bit; - - /* Invert the swizzle. */ - bit = 0; - for (i = 0; i < 4; ++i) - { - for (j = 0; j < width; ++j) - { - unsigned int s = (new_swizzle >> (j * 2)) & 3; - if (s == i) - inverted |= j << (bit++ * 2); - } - } - - *swizzle = inverted; - *writemask = new_writemask; - *ret_width = width; - return true; -} - -static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *lhs, - enum parse_assign_op assign_op, struct hlsl_ir_node *rhs) -{ - struct hlsl_type *lhs_type = lhs->data_type; - struct hlsl_ir_store *store; - struct hlsl_ir_expr *copy; - unsigned int writemask = 0; - - if (assign_op == ASSIGN_OP_SUB) - { - struct hlsl_ir_expr *expr; - - if (!(expr = add_unary_arithmetic_expr(ctx, instrs, HLSL_OP1_NEG, rhs, &rhs->loc))) - return NULL; - rhs = &expr->node; - assign_op = ASSIGN_OP_ADD; - } - if (assign_op != ASSIGN_OP_ASSIGN) - { - enum hlsl_ir_expr_op op = op_from_assignment(assign_op); - struct hlsl_ir_expr *expr; - - assert(op); - if (!(expr = add_binary_arithmetic_expr(ctx, instrs, op, lhs, rhs, &rhs->loc))) - return NULL; - rhs = &expr->node; - } - - if (lhs_type->type <= HLSL_CLASS_LAST_NUMERIC) - { - writemask = (1 << lhs_type->dimx) - 1; - - if (!(rhs = add_implicit_conversion(ctx, instrs, rhs, lhs_type, &rhs->loc))) - return NULL; - } - - if (!(store = hlsl_alloc(ctx, sizeof(*store)))) - return NULL; - - while (lhs->type != HLSL_IR_LOAD) - { - if (lhs->type == HLSL_IR_EXPR && hlsl_ir_expr(lhs)->op == HLSL_OP1_CAST) - { - hlsl_fixme(ctx, &lhs->loc, "Cast on the LHS."); - vkd3d_free(store); - return NULL; - } - else if (lhs->type == HLSL_IR_SWIZZLE) - { - struct hlsl_ir_swizzle *swizzle = hlsl_ir_swizzle(lhs), *new_swizzle; - unsigned int width, s = swizzle->swizzle; - - if (lhs->data_type->type == HLSL_CLASS_MATRIX) - hlsl_fixme(ctx, &lhs->loc, "Matrix assignment with a writemask."); - - if (!invert_swizzle(&s, &writemask, &width)) - { - hlsl_error(ctx, &lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_WRITEMASK, "Invalid writemask."); - vkd3d_free(store); - return NULL; - } - - if (!(new_swizzle = hlsl_new_swizzle(ctx, s, width, rhs, &swizzle->node.loc))) - { - vkd3d_free(store); - return NULL; - } - list_add_tail(instrs, &new_swizzle->node.entry); - - lhs = swizzle->val.node; - rhs = &new_swizzle->node; - } - else - { - hlsl_error(ctx, &lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_LVALUE, "Invalid lvalue."); - vkd3d_free(store); - return NULL; - } - } - - init_node(&store->node, HLSL_IR_STORE, NULL, lhs->loc); - store->writemask = writemask; - store->lhs.var = hlsl_ir_load(lhs)->src.var; - hlsl_src_from_node(&store->lhs.offset, hlsl_ir_load(lhs)->src.offset.node); - hlsl_src_from_node(&store->rhs, rhs); - list_add_tail(instrs, &store->node.entry); - - /* Don't use the instruction itself as a source, as this makes structure - * splitting easier. Instead copy it here. Since we retrieve sources from - * the last instruction in the list, we do need to copy. */ - if (!(copy = hlsl_new_copy(ctx, rhs))) - return NULL; - list_add_tail(instrs, ©->node.entry); - return ©->node; -} - -static bool add_increment(struct hlsl_ctx *ctx, struct list *instrs, bool decrement, bool post, - struct vkd3d_shader_location loc) -{ - struct hlsl_ir_node *lhs = node_from_list(instrs); - struct hlsl_ir_constant *one; - - if (lhs->data_type->modifiers & HLSL_MODIFIER_CONST) - hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_MODIFIES_CONST, - "Argument to %s%screment operator is const.", post ? "post" : "pre", decrement ? "de" : "in"); - - if (!(one = hlsl_new_int_constant(ctx, 1, loc))) - return false; - list_add_tail(instrs, &one->node.entry); - - if (!add_assignment(ctx, instrs, lhs, decrement ? ASSIGN_OP_SUB : ASSIGN_OP_ADD, &one->node)) - return false; - - if (post) - { - struct hlsl_ir_expr *copy; - - if (!(copy = hlsl_new_copy(ctx, lhs))) - return false; - list_add_tail(instrs, ©->node.entry); - - /* Post increment/decrement expressions are considered const. */ - if (!(copy->node.data_type = hlsl_type_clone(ctx, copy->node.data_type, 0, HLSL_MODIFIER_CONST))) - return false; - } - - return true; -} - -static void struct_var_initializer(struct hlsl_ctx *ctx, struct list *list, struct hlsl_ir_var *var, - struct parse_initializer *initializer) -{ - struct hlsl_type *type = var->data_type; - struct hlsl_struct_field *field; - unsigned int i = 0; - - if (initializer_size(initializer) != hlsl_type_component_count(type)) - { - hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, - "Expected %u components in initializer, but got %u.", - hlsl_type_component_count(type), initializer_size(initializer)); - free_parse_initializer(initializer); - return; - } - - list_move_tail(list, initializer->instrs); - vkd3d_free(initializer->instrs); - - LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry) - { - struct hlsl_ir_node *node = initializer->args[i]; - struct hlsl_ir_store *store; - struct hlsl_ir_constant *c; - - if (i++ >= initializer->args_count) - break; - - if (hlsl_type_component_count(field->type) == hlsl_type_component_count(node->data_type)) - { - if (!(c = hlsl_new_uint_constant(ctx, field->reg_offset, node->loc))) - break; - list_add_tail(list, &c->node.entry); - - if (!(store = hlsl_new_store(ctx, var, &c->node, node, 0, node->loc))) - break; - list_add_tail(list, &store->node.entry); - } - else - { - hlsl_fixme(ctx, &node->loc, "Implicit cast in structure initializer."); - } - } - - vkd3d_free(initializer->args); -} - -static void free_parse_variable_def(struct parse_variable_def *v) -{ - free_parse_initializer(&v->initializer); - vkd3d_free(v->arrays.sizes); - vkd3d_free(v->name); - vkd3d_free((void *)v->semantic.name); - vkd3d_free(v); -} - -static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_type, - DWORD modifiers, struct list *var_list) -{ - struct parse_variable_def *v, *v_next; - struct hlsl_ir_function_decl *func; - struct list *statements_list; - struct hlsl_ir_var *var; - struct hlsl_type *type; - bool local = true; - - if (basic_type->type == HLSL_CLASS_MATRIX) - assert(basic_type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK); - - if (!(statements_list = make_empty_list(ctx))) - { - LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry) - free_parse_variable_def(v); - vkd3d_free(var_list); - return NULL; - } - - if (!var_list) - return statements_list; - - LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry) - { - unsigned int i; - - type = basic_type; - for (i = 0; i < v->arrays.count; ++i) - type = hlsl_new_array_type(ctx, type, v->arrays.sizes[i]); - - if (type->type != HLSL_CLASS_MATRIX) - check_invalid_matrix_modifiers(ctx, modifiers, v->loc); - - if (!(var = hlsl_new_var(ctx, v->name, type, v->loc, &v->semantic, modifiers, &v->reg_reservation))) - { - free_parse_variable_def(v); - continue; - } - - var->buffer = ctx->cur_buffer; - - if (ctx->cur_scope == ctx->globals) - { - local = false; - - if ((modifiers & HLSL_STORAGE_UNIFORM) && (modifiers & HLSL_STORAGE_STATIC)) - hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, - "Variable '%s' is declared as both \"uniform\" and \"static\".", var->name); - - /* Mark it as uniform. We need to do this here since synthetic - * variables also get put in the global scope, but shouldn't be - * considered uniforms, and we have no way of telling otherwise. */ - if (!(modifiers & HLSL_STORAGE_STATIC)) - var->modifiers |= HLSL_STORAGE_UNIFORM; - - if ((func = hlsl_get_func_decl(ctx, var->name))) - { - hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, - "'%s' is already defined as a function.", var->name); - hlsl_note(ctx, &func->loc, VKD3D_SHADER_LOG_ERROR, - "'%s' was previously defined here.", var->name); - } - } - else - { - static const unsigned int invalid = HLSL_STORAGE_EXTERN | HLSL_STORAGE_SHARED - | HLSL_STORAGE_GROUPSHARED | HLSL_STORAGE_UNIFORM; - - if (modifiers & invalid) - { - struct vkd3d_string_buffer *string; - - if ((string = hlsl_modifiers_to_string(ctx, modifiers & invalid))) - hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, - "Modifiers '%s' are not allowed on local variables.", string->buffer); - hlsl_release_string_buffer(ctx, string); - } - if (var->semantic.name) - hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, - "Semantics are not allowed on local variables."); - } - - if ((type->modifiers & HLSL_MODIFIER_CONST) && !v->initializer.args_count - && !(modifiers & (HLSL_STORAGE_STATIC | HLSL_STORAGE_UNIFORM))) - { - hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_INITIALIZER, - "Const variable \"%s\" is missing an initializer.", var->name); - hlsl_free_var(var); - vkd3d_free(v); - continue; - } - - if (!hlsl_add_var(ctx, var, local)) - { - struct hlsl_ir_var *old = hlsl_get_var(ctx->cur_scope, var->name); - - hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, - "Variable \"%s\" was already declared in this scope.", var->name); - hlsl_note(ctx, &old->loc, VKD3D_SHADER_LOG_ERROR, "\"%s\" was previously declared here.", old->name); - hlsl_free_var(var); - vkd3d_free(v); - continue; - } - - if (v->initializer.args_count) - { - unsigned int size = initializer_size(&v->initializer); - struct hlsl_ir_load *load; - - if (type->type <= HLSL_CLASS_LAST_NUMERIC - && type->dimx * type->dimy != size && size != 1) - { - if (size < type->dimx * type->dimy) - { - hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, - "Expected %u components in numeric initializer, but got %u.", - type->dimx * type->dimy, size); - free_parse_initializer(&v->initializer); - vkd3d_free(v); - continue; - } - } - if ((type->type == HLSL_CLASS_STRUCT || type->type == HLSL_CLASS_ARRAY) - && hlsl_type_component_count(type) != size) - { - hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, - "Expected %u components in initializer, but got %u.", hlsl_type_component_count(type), size); - free_parse_initializer(&v->initializer); - vkd3d_free(v); - continue; - } - - if (type->type == HLSL_CLASS_STRUCT) - { - struct_var_initializer(ctx, statements_list, var, &v->initializer); - vkd3d_free(v); - continue; - } - if (type->type > HLSL_CLASS_LAST_NUMERIC) - { - FIXME("Initializers for non scalar/struct variables not supported yet.\n"); - free_parse_initializer(&v->initializer); - vkd3d_free(v); - continue; - } - if (v->arrays.count) - { - hlsl_fixme(ctx, &v->loc, "Array initializer."); - free_parse_initializer(&v->initializer); - vkd3d_free(v); - continue; - } - if (v->initializer.args_count > 1) - { - hlsl_fixme(ctx, &v->loc, "Complex initializer."); - free_parse_initializer(&v->initializer); - vkd3d_free(v); - continue; - } - - load = hlsl_new_var_load(ctx, var, var->loc); - list_add_tail(v->initializer.instrs, &load->node.entry); - add_assignment(ctx, v->initializer.instrs, &load->node, ASSIGN_OP_ASSIGN, v->initializer.args[0]); - vkd3d_free(v->initializer.args); - - if (modifiers & HLSL_STORAGE_STATIC) - list_move_tail(&ctx->static_initializers, v->initializer.instrs); - else - list_move_tail(statements_list, v->initializer.instrs); - vkd3d_free(v->initializer.instrs); - } - vkd3d_free(v); - } - vkd3d_free(var_list); - return statements_list; -} - -struct find_function_call_args -{ - const struct parse_initializer *params; - const struct hlsl_ir_function_decl *decl; -}; - -static void find_function_call_exact(struct wine_rb_entry *entry, void *context) -{ - const struct hlsl_ir_function_decl *decl = RB_ENTRY_VALUE(entry, const struct hlsl_ir_function_decl, entry); - struct find_function_call_args *args = context; - const struct hlsl_ir_var *param; - unsigned int i = 0; - - LIST_FOR_EACH_ENTRY(param, decl->parameters, struct hlsl_ir_var, param_entry) - { - if (i >= args->params->args_count - || !hlsl_types_are_equal(param->data_type, args->params->args[i++]->data_type)) - return; - } - if (i == args->params->args_count) - args->decl = decl; -} - -static const struct hlsl_ir_function_decl *find_function_call(struct hlsl_ctx *ctx, - const char *name, const struct parse_initializer *params) -{ - struct find_function_call_args args = {.params = params}; - struct hlsl_ir_function *func; - struct wine_rb_entry *entry; - - if (!(entry = wine_rb_get(&ctx->functions, name))) - return NULL; - func = RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry); - - wine_rb_for_each_entry(&func->overloads, find_function_call_exact, &args); - if (!args.decl) - FIXME("Search for compatible overloads.\n"); - return args.decl; -} - -static struct hlsl_ir_node *intrinsic_float_convert_arg(struct hlsl_ctx *ctx, - const struct parse_initializer *params, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc) -{ - struct hlsl_type *type = arg->data_type; - - if (type->base_type == HLSL_TYPE_FLOAT || type->base_type == HLSL_TYPE_HALF) - return arg; - - type = hlsl_get_numeric_type(ctx, type->type, HLSL_TYPE_FLOAT, type->dimx, type->dimy); - return add_implicit_conversion(ctx, params->instrs, arg, type, loc); -} - -static bool intrinsic_abs(struct hlsl_ctx *ctx, - const struct parse_initializer *params, const struct vkd3d_shader_location *loc) -{ - return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_ABS, params->args[0], loc); -} - -static bool intrinsic_clamp(struct hlsl_ctx *ctx, - const struct parse_initializer *params, const struct vkd3d_shader_location *loc) -{ - struct hlsl_ir_expr *max; - - if (!(max = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MAX, params->args[0], params->args[1], loc))) - return false; - - return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MIN, &max->node, params->args[2], loc); -} - -static bool intrinsic_cross(struct hlsl_ctx *ctx, - const struct parse_initializer *params, const struct vkd3d_shader_location *loc) -{ - struct hlsl_ir_swizzle *arg1_swzl1, *arg1_swzl2, *arg2_swzl1, *arg2_swzl2; - struct hlsl_ir_node *arg1 = params->args[0], *arg2 = params->args[1]; - struct hlsl_ir_node *arg1_cast, *arg2_cast, *mul1_neg; - struct hlsl_ir_expr *mul1, *mul2; - struct hlsl_type *cast_type; - enum hlsl_base_type base; - - if (arg1->data_type->base_type == HLSL_TYPE_HALF && arg2->data_type->base_type == HLSL_TYPE_HALF) - base = HLSL_TYPE_HALF; - else - base = HLSL_TYPE_FLOAT; - - cast_type = hlsl_get_vector_type(ctx, base, 3); - - if (!(arg1_cast = add_implicit_conversion(ctx, params->instrs, arg1, cast_type, loc))) - return false; - - if (!(arg2_cast = add_implicit_conversion(ctx, params->instrs, arg2, cast_type, loc))) - return false; - - if (!(arg1_swzl1 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Z, X, Y, Z), 3, arg1_cast, loc))) - return false; - list_add_tail(params->instrs, &arg1_swzl1->node.entry); - - if (!(arg2_swzl1 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Y, Z, X, Y), 3, arg2_cast, loc))) - return false; - list_add_tail(params->instrs, &arg2_swzl1->node.entry); - - if (!(mul1 = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, - &arg1_swzl1->node, &arg2_swzl1->node, loc))) - return false; - - if (!(mul1_neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, &mul1->node, *loc))) - return false; - list_add_tail(params->instrs, &mul1_neg->entry); - - if (!(arg1_swzl2 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Y, Z, X, Y), 3, arg1_cast, loc))) - return false; - list_add_tail(params->instrs, &arg1_swzl2->node.entry); - - if (!(arg2_swzl2 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Z, X, Y, Z), 3, arg2_cast, loc))) - return false; - list_add_tail(params->instrs, &arg2_swzl2->node.entry); - - if (!(mul2 = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, - &arg1_swzl2->node, &arg2_swzl2->node, loc))) - return false; - - return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, &mul2->node, mul1_neg, loc); -} - -static bool intrinsic_floor(struct hlsl_ctx *ctx, - const struct parse_initializer *params, const struct vkd3d_shader_location *loc) -{ - struct hlsl_ir_node *arg; - - if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; - - return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_FLOOR, arg, loc); -} - -static bool intrinsic_max(struct hlsl_ctx *ctx, - const struct parse_initializer *params, const struct vkd3d_shader_location *loc) -{ - return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MAX, params->args[0], params->args[1], loc); -} - -static bool intrinsic_min(struct hlsl_ctx *ctx, - const struct parse_initializer *params, const struct vkd3d_shader_location *loc) -{ - return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MIN, params->args[0], params->args[1], loc); -} - -static bool intrinsic_pow(struct hlsl_ctx *ctx, - const struct parse_initializer *params, const struct vkd3d_shader_location *loc) -{ - struct hlsl_ir_node *log, *exp; - struct hlsl_ir_expr *mul; - - if (!(log = hlsl_new_unary_expr(ctx, HLSL_OP1_LOG2, params->args[0], *loc))) - return false; - list_add_tail(params->instrs, &log->entry); - - if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, params->args[1], log, loc))) - return false; - - if (!(exp = hlsl_new_unary_expr(ctx, HLSL_OP1_EXP2, &mul->node, *loc))) - return false; - list_add_tail(params->instrs, &exp->entry); - return true; -} - -static bool intrinsic_round(struct hlsl_ctx *ctx, - const struct parse_initializer *params, const struct vkd3d_shader_location *loc) -{ - struct hlsl_ir_node *arg; - - if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; - - return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_ROUND, arg, loc); -} - -static bool intrinsic_saturate(struct hlsl_ctx *ctx, - const struct parse_initializer *params, const struct vkd3d_shader_location *loc) -{ - struct hlsl_ir_node *arg; - - if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; - - return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_SAT, arg, loc); -} - -static const struct intrinsic_function -{ - const char *name; - int param_count; - bool check_numeric; - bool (*handler)(struct hlsl_ctx *ctx, const struct parse_initializer *params, - const struct vkd3d_shader_location *loc); -} -intrinsic_functions[] = -{ - /* Note: these entries should be kept in alphabetical order. */ - {"abs", 1, true, intrinsic_abs}, - {"clamp", 3, true, intrinsic_clamp}, - {"cross", 2, true, intrinsic_cross}, - {"floor", 1, true, intrinsic_floor}, - {"max", 2, true, intrinsic_max}, - {"min", 2, true, intrinsic_min}, - {"pow", 2, true, intrinsic_pow}, - {"round", 1, true, intrinsic_round}, - {"saturate", 1, true, intrinsic_saturate}, -}; - -static int intrinsic_function_name_compare(const void *a, const void *b) -{ - const struct intrinsic_function *func = b; - - return strcmp(a, func->name); -} - -static struct list *add_call(struct hlsl_ctx *ctx, const char *name, - struct parse_initializer *params, struct vkd3d_shader_location loc) -{ - const struct hlsl_ir_function_decl *decl; - struct intrinsic_function *intrinsic; - - if ((decl = find_function_call(ctx, name, params))) - { - hlsl_fixme(ctx, &loc, "Call to user-defined function \"%s\".", name); - free_parse_initializer(params); - return NULL; - } - else if ((intrinsic = bsearch(name, intrinsic_functions, ARRAY_SIZE(intrinsic_functions), - sizeof(*intrinsic_functions), intrinsic_function_name_compare))) - { - if (intrinsic->param_count >= 0 && params->args_count != intrinsic->param_count) - { - hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, - "Wrong number of arguments to function '%s': expected %u, but got %u.\n", - name, intrinsic->param_count, params->args_count); - free_parse_initializer(params); - return NULL; - } - - if (intrinsic->check_numeric) - { - unsigned int i; - - for (i = 0; i < params->args_count; ++i) - { - if (params->args[i]->data_type->type > HLSL_CLASS_LAST_NUMERIC) - { - struct vkd3d_string_buffer *string; - - if ((string = hlsl_type_to_string(ctx, params->args[i]->data_type))) - hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Wrong type for argument %u of '%s': expected a numeric type, but got '%s'.\n", - i + 1, name, string->buffer); - hlsl_release_string_buffer(ctx, string); - free_parse_initializer(params); - return NULL; - } - } - } - - if (!intrinsic->handler(ctx, params, &loc)) - { - free_parse_initializer(params); - return NULL; - } - } - else - { - hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Function \"%s\" is not defined.", name); - free_parse_initializer(params); - return NULL; - } - vkd3d_free(params->args); - return params->instrs; -} - -static struct list *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type, - struct parse_initializer *params, struct vkd3d_shader_location loc) -{ - unsigned int i, writemask_offset = 0; - struct hlsl_ir_store *store; - static unsigned int counter; - struct hlsl_ir_load *load; - struct hlsl_ir_var *var; - char name[23]; - - if (type->type == HLSL_CLASS_MATRIX) - hlsl_fixme(ctx, &loc, "Matrix constructor."); - - sprintf(name, "", counter++); - if (!(var = hlsl_new_synthetic_var(ctx, name, type, loc))) - return NULL; - - for (i = 0; i < params->args_count; ++i) - { - struct hlsl_ir_node *arg = params->args[i]; - unsigned int width; - - if (arg->data_type->type == HLSL_CLASS_OBJECT) - { - struct vkd3d_string_buffer *string; - - if ((string = hlsl_type_to_string(ctx, arg->data_type))) - hlsl_error(ctx, &arg->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Invalid type %s for constructor argument.", string->buffer); - hlsl_release_string_buffer(ctx, string); - continue; - } - width = hlsl_type_component_count(arg->data_type); - - if (width > 4) - { - FIXME("Constructor argument with %u components.\n", width); - continue; - } - - if (!(arg = add_implicit_conversion(ctx, params->instrs, arg, - hlsl_get_vector_type(ctx, type->base_type, width), &arg->loc))) - continue; - - if (!(store = hlsl_new_store(ctx, var, NULL, arg, - ((1u << width) - 1) << writemask_offset, arg->loc))) - return NULL; - list_add_tail(params->instrs, &store->node.entry); - - writemask_offset += width; - } - - if (!(load = hlsl_new_var_load(ctx, var, loc))) - return NULL; - list_add_tail(params->instrs, &load->node.entry); - - vkd3d_free(params->args); - return params->instrs; -} - -static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, - const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) -{ - const struct hlsl_type *object_type = object->data_type; - struct hlsl_ir_load *object_load; - - if (object_type->type != HLSL_CLASS_OBJECT || object_type->base_type != HLSL_TYPE_TEXTURE - || object_type->sampler_dim == HLSL_SAMPLER_DIM_GENERIC) - { - struct vkd3d_string_buffer *string; - - if ((string = hlsl_type_to_string(ctx, object_type))) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Type '%s' does not have methods.", string->buffer); - hlsl_release_string_buffer(ctx, string); - return false; - } - - /* Only HLSL_IR_LOAD can return an object. */ - object_load = hlsl_ir_load(object); - - if (!strcmp(name, "Load") - && object_type->sampler_dim != HLSL_SAMPLER_DIM_CUBE - && object_type->sampler_dim != HLSL_SAMPLER_DIM_CUBEARRAY) - { - const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); - struct hlsl_ir_resource_load *load; - struct hlsl_ir_node *coords; - - if (object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS - || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY) - { - FIXME("'Load' method for multi-sample textures.\n"); - return false; - } - - if (params->args_count < 1 || params->args_count > 3) - { - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, - "Wrong number of arguments to method 'Load': expected 1, 2, or 3, but got %u.", params->args_count); - return false; - } - if (params->args_count >= 2) - hlsl_fixme(ctx, loc, "Offset parameter."); - if (params->args_count == 3) - hlsl_fixme(ctx, loc, "Tiled resource status argument."); - - /* +1 for the mipmap level */ - if (!(coords = add_implicit_conversion(ctx, instrs, params->args[0], - hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim + 1), loc))) - return false; - - if (!(load = hlsl_new_resource_load(ctx, object_type->e.resource_format, HLSL_RESOURCE_LOAD, - object_load->src.var, object_load->src.offset.node, NULL, NULL, coords, NULL, loc))) - return false; - list_add_tail(instrs, &load->node.entry); - return true; - } - else if (!strcmp(name, "Sample") - && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMS - && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) - { - const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); - const struct hlsl_type *sampler_type; - struct hlsl_ir_resource_load *load; - struct hlsl_ir_node *offset = NULL; - struct hlsl_ir_load *sampler_load; - struct hlsl_ir_node *coords; - - if (params->args_count != 2 && params->args_count != 3) - { - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, - "Wrong number of arguments to method 'Sample': expected 2 or 3, but got %u.", params->args_count); - return false; - } - - sampler_type = params->args[0]->data_type; - if (sampler_type->type != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER - || sampler_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC) - { - struct vkd3d_string_buffer *string; - - if ((string = hlsl_type_to_string(ctx, sampler_type))) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Wrong type for argument 0 of Sample(): expected 'sampler', but got '%s'.", string->buffer); - hlsl_release_string_buffer(ctx, string); - return false; - } - - /* Only HLSL_IR_LOAD can return an object. */ - sampler_load = hlsl_ir_load(params->args[0]); - - if (!(coords = add_implicit_conversion(ctx, instrs, params->args[1], - hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) - return false; - - if (params->args_count == 3) - { - if (!(offset = add_implicit_conversion(ctx, instrs, params->args[2], - hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim), loc))) - return false; - } - - if (!(load = hlsl_new_resource_load(ctx, object_type->e.resource_format, - HLSL_RESOURCE_SAMPLE, object_load->src.var, object_load->src.offset.node, - sampler_load->src.var, sampler_load->src.offset.node, coords, offset, loc))) - return false; - list_add_tail(instrs, &load->node.entry); - return true; - } - else if ((!strcmp(name, "Gather") || !strcmp(name, "GatherRed") || !strcmp(name, "GatherBlue") - || !strcmp(name, "GatherGreen") || !strcmp(name, "GatherAlpha")) - && (object_type->sampler_dim == HLSL_SAMPLER_DIM_2D - || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DARRAY - || object_type->sampler_dim == HLSL_SAMPLER_DIM_CUBE - || object_type->sampler_dim == HLSL_SAMPLER_DIM_CUBEARRAY)) - { - const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); - enum hlsl_resource_load_type load_type; - const struct hlsl_type *sampler_type; - struct hlsl_ir_resource_load *load; - struct hlsl_ir_node *offset = NULL; - struct hlsl_ir_load *sampler_load; - struct hlsl_type *result_type; - struct hlsl_ir_node *coords; - unsigned int read_channel; - - if (!strcmp(name, "GatherGreen")) - { - load_type = HLSL_RESOURCE_GATHER_GREEN; - read_channel = 1; - } - else if (!strcmp(name, "GatherBlue")) - { - load_type = HLSL_RESOURCE_GATHER_BLUE; - read_channel = 2; - } - else if (!strcmp(name, "GatherAlpha")) - { - load_type = HLSL_RESOURCE_GATHER_ALPHA; - read_channel = 3; - } - else - { - load_type = HLSL_RESOURCE_GATHER_RED; - read_channel = 0; - } - - if (!strcmp(name, "Gather")) - { - if (params->args_count != 2 && params->args_count != 3) - { - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, - "Wrong number of arguments to method 'Gather': expected 2 or 3, but got %u.", params->args_count); - return false; - } - } - else if (params->args_count < 2 || params->args_count == 5 || params->args_count > 7) - { - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, - "Wrong number of arguments to method '%s': expected 2, 3, 4, 6 or 7, but got %u.", - name, params->args_count); - return false; - } - - if (params->args_count == 4 || params->args_count == 7) - hlsl_fixme(ctx, loc, "Tiled resource status argument."); - - if (params->args_count == 6 || params->args_count == 7) - hlsl_fixme(ctx, loc, "Multiple Gather() offset parameters."); - - if (params->args_count == 3 || params->args_count == 4) - { - if (!(offset = add_implicit_conversion(ctx, instrs, params->args[2], - hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim), loc))) - return false; - } - - sampler_type = params->args[0]->data_type; - if (sampler_type->type != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER - || sampler_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC) - { - struct vkd3d_string_buffer *string; - - if ((string = hlsl_type_to_string(ctx, sampler_type))) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Wrong type for argument 1 of %s(): expected 'sampler', but got '%s'.", name, string->buffer); - hlsl_release_string_buffer(ctx, string); - return false; - } - - if (read_channel >= object_type->e.resource_format->dimx) - { - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Method %s() requires at least %u channels.", name, read_channel + 1); - return false; - } - - result_type = hlsl_get_vector_type(ctx, object_type->e.resource_format->base_type, 4); - - /* Only HLSL_IR_LOAD can return an object. */ - sampler_load = hlsl_ir_load(params->args[0]); - - if (!(coords = add_implicit_conversion(ctx, instrs, params->args[1], - hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) - return false; - - if (!(load = hlsl_new_resource_load(ctx, result_type, - load_type, object_load->src.var, object_load->src.offset.node, - sampler_load->src.var, sampler_load->src.offset.node, coords, offset, loc))) - return false; - list_add_tail(instrs, &load->node.entry); - return true; - } - else - { - struct vkd3d_string_buffer *string; - - if ((string = hlsl_type_to_string(ctx, object_type))) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, - "Method '%s' is not defined on type '%s'.", name, string->buffer); - hlsl_release_string_buffer(ctx, string); - return false; - } -} - -} - -%locations -%define parse.error verbose -%define api.prefix {hlsl_yy} -%define api.pure full -%expect 1 -%lex-param {yyscan_t scanner} -%parse-param {void *scanner} -%parse-param {struct hlsl_ctx *ctx} - -%union -{ - struct hlsl_type *type; - INT intval; - FLOAT floatval; - BOOL boolval; - char *name; - DWORD modifiers; - struct hlsl_ir_node *instr; - struct list *list; - struct parse_function function; - struct parse_parameter parameter; - struct parse_initializer initializer; - struct parse_array_sizes arrays; - struct parse_variable_def *variable_def; - struct parse_if_body if_body; - enum parse_assign_op assign_op; - struct hlsl_reg_reservation reg_reservation; - struct parse_colon_attribute colon_attribute; - struct hlsl_semantic semantic; - enum hlsl_buffer_type buffer_type; - enum hlsl_sampler_dim sampler_dim; -} - -%token KW_BLENDSTATE -%token KW_BREAK -%token KW_BUFFER -%token KW_CBUFFER -%token KW_COLUMN_MAJOR -%token KW_COMPILE -%token KW_CONST -%token KW_CONTINUE -%token KW_DEPTHSTENCILSTATE -%token KW_DEPTHSTENCILVIEW -%token KW_DISCARD -%token KW_DO -%token KW_DOUBLE -%token KW_ELSE -%token KW_EXTERN -%token KW_FALSE -%token KW_FOR -%token KW_GEOMETRYSHADER -%token KW_GROUPSHARED -%token KW_IF -%token KW_IN -%token KW_INLINE -%token KW_INOUT -%token KW_MATRIX -%token KW_NAMESPACE -%token KW_NOINTERPOLATION -%token KW_OUT -%token KW_PASS -%token KW_PIXELSHADER -%token KW_PRECISE -%token KW_RASTERIZERSTATE -%token KW_RENDERTARGETVIEW -%token KW_RETURN -%token KW_REGISTER -%token KW_ROW_MAJOR -%token KW_SAMPLER -%token KW_SAMPLER1D -%token KW_SAMPLER2D -%token KW_SAMPLER3D -%token KW_SAMPLERCUBE -%token KW_SAMPLER_STATE -%token KW_SAMPLERCOMPARISONSTATE -%token KW_SHARED -%token KW_STATEBLOCK -%token KW_STATEBLOCK_STATE -%token KW_STATIC -%token KW_STRING -%token KW_STRUCT -%token KW_SWITCH -%token KW_TBUFFER -%token KW_TECHNIQUE -%token KW_TECHNIQUE10 -%token KW_TEXTURE -%token KW_TEXTURE1D -%token KW_TEXTURE1DARRAY -%token KW_TEXTURE2D -%token KW_TEXTURE2DARRAY -%token KW_TEXTURE2DMS -%token KW_TEXTURE2DMSARRAY -%token KW_TEXTURE3D -%token KW_TEXTURECUBE -%token KW_TEXTURECUBEARRAY -%token KW_TRUE -%token KW_TYPEDEF -%token KW_UNIFORM -%token KW_VECTOR -%token KW_VERTEXSHADER -%token KW_VOID -%token KW_VOLATILE -%token KW_WHILE - -%token OP_INC -%token OP_DEC -%token OP_AND -%token OP_OR -%token OP_EQ -%token OP_LEFTSHIFT -%token OP_LEFTSHIFTASSIGN -%token OP_RIGHTSHIFT -%token OP_RIGHTSHIFTASSIGN -%token OP_ELLIPSIS -%token OP_LE -%token OP_GE -%token OP_NE -%token OP_ADDASSIGN -%token OP_SUBASSIGN -%token OP_MULASSIGN -%token OP_DIVASSIGN -%token OP_MODASSIGN -%token OP_ANDASSIGN -%token OP_ORASSIGN -%token OP_XORASSIGN -%token OP_UNKNOWN1 -%token OP_UNKNOWN2 -%token OP_UNKNOWN3 -%token OP_UNKNOWN4 - -%token C_FLOAT - -%token C_INTEGER -%token PRE_LINE - -%type add_expr -%type assignment_expr -%type bitand_expr -%type bitor_expr -%type bitxor_expr -%type compound_statement -%type conditional_expr -%type declaration -%type declaration_statement -%type equality_expr -%type expr -%type expr_statement -%type field -%type fields_list -%type initializer_expr -%type jump_statement -%type logicand_expr -%type logicor_expr -%type loop_statement -%type mul_expr -%type param_list -%type parameters -%type postfix_expr -%type primary_expr -%type relational_expr -%type selection_statement -%type shift_expr -%type statement -%type statement_list -%type struct_declaration -%type type_specs -%type unary_expr -%type variables_def -%type variables_def_optional - -%token VAR_IDENTIFIER -%token NEW_IDENTIFIER -%token STRING -%token TYPE_IDENTIFIER - -%type arrays - -%type assign_op - -%type boolean - -%type buffer_type - -%type colon_attribute - -%type func_declaration -%type func_prototype - -%type complex_initializer -%type func_arguments -%type initializer_expr_list - -%type if_body - -%type input_mod -%type input_mods -%type var_modifiers - -%type any_identifier -%type var_identifier - -%type parameter - -%type register_opt - -%type texture_type - -%type semantic - -%type field_type -%type named_struct_spec -%type unnamed_struct_spec -%type struct_spec -%type type -%type typedef_type - -%type type_spec -%type variable_decl -%type variable_def - -%% - -hlsl_prog: - %empty - | hlsl_prog func_declaration - { - const struct hlsl_ir_function_decl *decl; - - decl = get_func_decl(&ctx->functions, $2.name, $2.decl->parameters); - if (decl && !decl->func->intrinsic) - { - if (decl->has_body && $2.decl->has_body) - { - hlsl_error(ctx, &$2.decl->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, - "Function \"%s\" is already defined.", $2.name); - hlsl_note(ctx, &decl->loc, VKD3D_SHADER_LOG_ERROR, "\"%s\" was previously defined here.", $2.name); - YYABORT; - } - else if (!hlsl_types_are_equal(decl->return_type, $2.decl->return_type)) - { - hlsl_error(ctx, &$2.decl->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, - "Function \"%s\" was already declared with a different return type.", $2.name); - hlsl_note(ctx, &decl->loc, VKD3D_SHADER_LOG_ERROR, "\"%s\" was previously declared here.", $2.name); - YYABORT; - } - } - - hlsl_add_function(ctx, $2.name, $2.decl, false); - } - | hlsl_prog buffer_declaration buffer_body - | hlsl_prog declaration_statement - { - if (!list_empty($2)) - hlsl_fixme(ctx, &@2, "Uniform initializer."); - destroy_instr_list($2); - } - | hlsl_prog preproc_directive - | hlsl_prog ';' - -buffer_declaration: - buffer_type any_identifier colon_attribute - { - if ($3.semantic.name) - hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, "Semantics are not allowed on buffers."); - - if (!(ctx->cur_buffer = hlsl_new_buffer(ctx, $1, $2, &$3.reg_reservation, @2))) - YYABORT; - } - -buffer_body: - '{' declaration_statement_list '}' - { - ctx->cur_buffer = ctx->globals_buffer; - } - -buffer_type: - KW_CBUFFER - { - $$ = HLSL_BUFFER_CONSTANT; - } - | KW_TBUFFER - { - $$ = HLSL_BUFFER_TEXTURE; - } - -declaration_statement_list: - declaration_statement - | declaration_statement_list declaration_statement - -preproc_directive: - PRE_LINE STRING - { - const char **new_array = NULL; - - ctx->location.line = $1; - if (strcmp($2, ctx->location.source_name)) - new_array = hlsl_realloc(ctx, ctx->source_files, - sizeof(*ctx->source_files) * (ctx->source_files_count + 1)); - - if (new_array) - { - ctx->source_files = new_array; - ctx->source_files[ctx->source_files_count++] = $2; - ctx->location.source_name = $2; - } - else - { - vkd3d_free($2); - } - } - -struct_declaration: - var_modifiers struct_spec variables_def_optional ';' - { - struct hlsl_type *type; - unsigned int modifiers = $1; - - if (!$3) - { - if (!$2->name) - hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, - "Anonymous struct type must declare a variable."); - if (modifiers) - hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, - "Modifiers are not allowed on struct type declarations."); - } - - if (!(type = apply_type_modifiers(ctx, $2, &modifiers, @1))) - YYABORT; - $$ = declare_vars(ctx, type, modifiers, $3); - } - -struct_spec: - named_struct_spec - | unnamed_struct_spec - -named_struct_spec: - KW_STRUCT any_identifier '{' fields_list '}' - { - bool ret; - - $$ = hlsl_new_struct_type(ctx, $2, $4); - - if (hlsl_get_var(ctx->cur_scope, $2)) - { - hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_REDEFINED, "\"%s\" is already declared as a variable.", $2); - YYABORT; - } - - ret = hlsl_scope_add_type(ctx->cur_scope, $$); - if (!ret) - { - hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_REDEFINED, "Struct \"%s\" is already defined.", $2); - YYABORT; - } - } - -unnamed_struct_spec: - KW_STRUCT '{' fields_list '}' - { - $$ = hlsl_new_struct_type(ctx, NULL, $3); - } - -any_identifier: - VAR_IDENTIFIER - | TYPE_IDENTIFIER - | NEW_IDENTIFIER - -fields_list: - %empty - { - if (!($$ = make_empty_list(ctx))) - YYABORT; - } - | fields_list field - { - struct hlsl_struct_field *field, *next, *existing; - - $$ = $1; - LIST_FOR_EACH_ENTRY_SAFE(field, next, $2, struct hlsl_struct_field, entry) - { - if ((existing = get_struct_field($$, field->name))) - { - hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_REDEFINED, - "Field \"%s\" is already defined.", field->name); - hlsl_note(ctx, &existing->loc, VKD3D_SHADER_LOG_ERROR, - "'%s' was previously defined here.", field->name); - vkd3d_free(field); - } - else - { - list_add_tail($$, &field->entry); - } - } - vkd3d_free($2); - } - -field_type: - type - | unnamed_struct_spec - -field: - var_modifiers field_type variables_def ';' - { - struct hlsl_type *type; - unsigned int modifiers = $1; - - if (!(type = apply_type_modifiers(ctx, $2, &modifiers, @1))) - YYABORT; - if (modifiers) - { - struct vkd3d_string_buffer *string; - - if ((string = hlsl_modifiers_to_string(ctx, modifiers))) - hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, - "Modifiers '%s' are not allowed on struct fields.", string->buffer); - hlsl_release_string_buffer(ctx, string); - } - $$ = gen_struct_fields(ctx, type, $3); - } - -func_declaration: - func_prototype compound_statement - { - $$ = $1; - $$.decl->has_body = true; - list_move_tail(&$$.decl->body.instrs, $2); - vkd3d_free($2); - hlsl_pop_scope(ctx); - } - | func_prototype ';' - { - $$ = $1; - hlsl_pop_scope(ctx); - } - -func_prototype: - /* var_modifiers is necessary to avoid shift/reduce conflicts. */ - var_modifiers type var_identifier '(' parameters ')' colon_attribute - { - struct hlsl_ir_var *var; - - if ($1) - { - hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, - "Modifiers are not allowed on functions."); - YYABORT; - } - if ((var = hlsl_get_var(ctx->globals, $3))) - { - hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_REDEFINED, - "\"%s\" is already declared as a variable.", $3); - hlsl_note(ctx, &var->loc, VKD3D_SHADER_LOG_ERROR, - "\"%s\" was previously declared here.", $3); - YYABORT; - } - if (hlsl_types_are_equal($2, ctx->builtin_types.Void) && $7.semantic.name) - { - hlsl_error(ctx, &@7, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, - "Semantics are not allowed on void functions."); - } - - if ($7.reg_reservation.type) - FIXME("Unexpected register reservation for a function.\n"); - - if (!($$.decl = hlsl_new_func_decl(ctx, $2, $5, &$7.semantic, @3))) - YYABORT; - $$.name = $3; - ctx->cur_function = $$.decl; - } - -compound_statement: - '{' '}' - { - if (!($$ = make_empty_list(ctx))) - YYABORT; - } - | '{' scope_start statement_list '}' - { - hlsl_pop_scope(ctx); - $$ = $3; - } - -scope_start: - %empty - { - hlsl_push_scope(ctx); - } - -var_identifier: - VAR_IDENTIFIER - | NEW_IDENTIFIER - -colon_attribute: - %empty - { - $$.semantic.name = NULL; - $$.reg_reservation.type = 0; - } - | semantic - { - $$.semantic = $1; - $$.reg_reservation.type = 0; - } - | register_opt - { - $$.semantic.name = NULL; - $$.reg_reservation = $1; - } - -semantic: - ':' any_identifier - { - char *p; - - for (p = $2 + strlen($2); p > $2 && isdigit(p[-1]); --p) - ; - $$.name = $2; - $$.index = atoi(p); - *p = 0; - } - -/* FIXME: Writemasks */ -register_opt: - ':' KW_REGISTER '(' any_identifier ')' - { - $$ = parse_reg_reservation($4); - vkd3d_free($4); - } - | ':' KW_REGISTER '(' any_identifier ',' any_identifier ')' - { - FIXME("Ignoring shader target %s in a register reservation.\n", debugstr_a($4)); - vkd3d_free($4); - - $$ = parse_reg_reservation($6); - vkd3d_free($6); - } - -parameters: - scope_start - { - if (!($$ = make_empty_list(ctx))) - YYABORT; - } - | scope_start param_list - { - $$ = $2; - } - -param_list: - parameter - { - if (!($$ = make_empty_list(ctx))) - YYABORT; - if (!add_func_parameter(ctx, $$, &$1, @1)) - { - ERR("Error adding function parameter %s.\n", $1.name); - YYABORT; - } - } - | param_list ',' parameter - { - $$ = $1; - if (!add_func_parameter(ctx, $$, &$3, @3)) - { - hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_REDEFINED, - "Parameter \"%s\" is already declared.", $3.name); - YYABORT; - } - } - -parameter: - input_mods var_modifiers type any_identifier colon_attribute - { - struct hlsl_type *type; - unsigned int modifiers = $2; - - if (!(type = apply_type_modifiers(ctx, $3, &modifiers, @2))) - YYABORT; - - $$.modifiers = $1 ? $1 : HLSL_STORAGE_IN; - $$.modifiers |= modifiers; - $$.type = type; - $$.name = $4; - $$.semantic = $5.semantic; - $$.reg_reservation = $5.reg_reservation; - } - -input_mods: - %empty - { - $$ = 0; - } - | input_mods input_mod - { - if ($1 & $2) - { - struct vkd3d_string_buffer *string; - - if ((string = hlsl_modifiers_to_string(ctx, $2))) - hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, - "Modifier \"%s\" was already specified.", string->buffer); - hlsl_release_string_buffer(ctx, string); - YYABORT; - } - $$ = $1 | $2; - } - -input_mod: - KW_IN - { - $$ = HLSL_STORAGE_IN; - } - | KW_OUT - { - $$ = HLSL_STORAGE_OUT; - } - | KW_INOUT - { - $$ = HLSL_STORAGE_IN | HLSL_STORAGE_OUT; - } - -texture_type: - KW_TEXTURE1D - { - $$ = HLSL_SAMPLER_DIM_1D; - } - | KW_TEXTURE2D - { - $$ = HLSL_SAMPLER_DIM_2D; - } - | KW_TEXTURE3D - { - $$ = HLSL_SAMPLER_DIM_3D; - } - | KW_TEXTURECUBE - { - $$ = HLSL_SAMPLER_DIM_CUBE; - } - | KW_TEXTURE1DARRAY - { - $$ = HLSL_SAMPLER_DIM_1DARRAY; - } - | KW_TEXTURE2DARRAY - { - $$ = HLSL_SAMPLER_DIM_2DARRAY; - } - | KW_TEXTURECUBEARRAY - { - $$ = HLSL_SAMPLER_DIM_CUBEARRAY; - } - -type: - KW_VECTOR '<' type ',' C_INTEGER '>' - { - if ($3->type != HLSL_CLASS_SCALAR) - { - struct vkd3d_string_buffer *string; - - string = hlsl_type_to_string(ctx, $3); - if (string) - hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Vector base type %s is not scalar.", string->buffer); - hlsl_release_string_buffer(ctx, string); - YYABORT; - } - if ($5 < 1 || $5 > 4) - { - hlsl_error(ctx, &@5, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE, - "Vector size %d is not between 1 and 4.", $5); - YYABORT; - } - - $$ = hlsl_get_vector_type(ctx, $3->base_type, $5); - } - | KW_VECTOR - { - $$ = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4); - } - | KW_MATRIX '<' type ',' C_INTEGER ',' C_INTEGER '>' - { - if ($3->type != HLSL_CLASS_SCALAR) - { - struct vkd3d_string_buffer *string; - - string = hlsl_type_to_string(ctx, $3); - if (string) - hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Matrix base type %s is not scalar.", string->buffer); - hlsl_release_string_buffer(ctx, string); - YYABORT; - } - if ($5 < 1 || $5 > 4) - { - hlsl_error(ctx, &@5, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE, - "Matrix row count %d is not between 1 and 4.", $5); - YYABORT; - } - if ($7 < 1 || $7 > 4) - { - hlsl_error(ctx, &@7, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE, - "Matrix column count %d is not between 1 and 4.", $7); - YYABORT; - } - - $$ = hlsl_get_matrix_type(ctx, $3->base_type, $7, $5); - } - | KW_MATRIX - { - $$ = hlsl_get_matrix_type(ctx, HLSL_TYPE_FLOAT, 4, 4); - } - | KW_VOID - { - $$ = ctx->builtin_types.Void; - } - | KW_SAMPLER - { - $$ = ctx->builtin_types.sampler[HLSL_SAMPLER_DIM_GENERIC]; - } - | KW_SAMPLER1D - { - $$ = ctx->builtin_types.sampler[HLSL_SAMPLER_DIM_1D]; - } - | KW_SAMPLER2D - { - $$ = ctx->builtin_types.sampler[HLSL_SAMPLER_DIM_2D]; - } - | KW_SAMPLER3D - { - $$ = ctx->builtin_types.sampler[HLSL_SAMPLER_DIM_3D]; - } - | KW_SAMPLERCUBE - { - $$ = ctx->builtin_types.sampler[HLSL_SAMPLER_DIM_3D]; - } - | KW_TEXTURE - { - $$ = hlsl_new_texture_type(ctx, HLSL_SAMPLER_DIM_GENERIC, NULL); - } - | texture_type - { - $$ = hlsl_new_texture_type(ctx, $1, hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4)); - } - | texture_type '<' type '>' - { - if ($3->type > HLSL_CLASS_VECTOR) - { - struct vkd3d_string_buffer *string; - - string = hlsl_type_to_string(ctx, $3); - if (string) - hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Texture data type %s is not scalar or vector.\n", string->buffer); - hlsl_release_string_buffer(ctx, string); - } - $$ = hlsl_new_texture_type(ctx, $1, $3); - } - | TYPE_IDENTIFIER - { - $$ = hlsl_get_type(ctx->cur_scope, $1, true); - vkd3d_free($1); - } - | KW_STRUCT TYPE_IDENTIFIER - { - $$ = hlsl_get_type(ctx->cur_scope, $2, true); - if ($$->type != HLSL_CLASS_STRUCT) - hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_REDEFINED, "\"%s\" redefined as a structure.", $2); - vkd3d_free($2); - } - -declaration_statement: - declaration - | struct_declaration - | typedef - { - if (!($$ = make_empty_list(ctx))) - YYABORT; - } - -typedef_type: - type - | struct_spec - -typedef: - KW_TYPEDEF var_modifiers typedef_type type_specs ';' - { - if ($2 & ~HLSL_TYPE_MODIFIERS_MASK) - { - struct parse_variable_def *v, *v_next; - hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, - "Storage modifiers are not allowed on typedefs."); - LIST_FOR_EACH_ENTRY_SAFE(v, v_next, $4, struct parse_variable_def, entry) - vkd3d_free(v); - vkd3d_free($4); - YYABORT; - } - if (!add_typedef(ctx, $2, $3, $4)) - YYABORT; - } - -type_specs: - type_spec - { - if (!($$ = make_empty_list(ctx))) - YYABORT; - list_add_head($$, &$1->entry); - } - | type_specs ',' type_spec - { - $$ = $1; - list_add_tail($$, &$3->entry); - } - -type_spec: - any_identifier arrays - { - $$ = hlsl_alloc(ctx, sizeof(*$$)); - $$->loc = @1; - $$->name = $1; - $$->arrays = $2; - } - -declaration: - var_modifiers type variables_def ';' - { - struct hlsl_type *type; - unsigned int modifiers = $1; - - if (!(type = apply_type_modifiers(ctx, $2, &modifiers, @1))) - YYABORT; - $$ = declare_vars(ctx, type, modifiers, $3); - } - -variables_def_optional: - %empty - { - $$ = NULL; - } - | variables_def - -variables_def: - variable_def - { - if (!($$ = make_empty_list(ctx))) - YYABORT; - list_add_head($$, &$1->entry); - } - | variables_def ',' variable_def - { - $$ = $1; - list_add_tail($$, &$3->entry); - } - -variable_decl: - any_identifier arrays colon_attribute - { - $$ = hlsl_alloc(ctx, sizeof(*$$)); - $$->loc = @1; - $$->name = $1; - $$->arrays = $2; - $$->semantic = $3.semantic; - $$->reg_reservation = $3.reg_reservation; - } - -state: - any_identifier '=' expr ';' - { - vkd3d_free($1); - hlsl_free_instr_list($3); - } - -state_block_start: - %empty - { - ctx->in_state_block = 1; - } - -state_block: - %empty - | state_block state - -variable_def: - variable_decl - | variable_decl '=' complex_initializer - { - $$ = $1; - $$->initializer = $3; - } - | variable_decl '{' state_block_start state_block '}' - { - $$ = $1; - ctx->in_state_block = 0; - } - -arrays: - %empty - { - $$.sizes = NULL; - $$.count = 0; - } - | '[' expr ']' arrays - { - unsigned int size = evaluate_array_dimension(node_from_list($2)); - uint32_t *new_array; - - destroy_instr_list($2); - - $$ = $4; - - if (!size) - { - hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE, - "Array size is not a positive integer constant."); - vkd3d_free($$.sizes); - YYABORT; - } - - if (size > 65536) - { - hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE, - "Array size %u is not between 1 and 65536.", size); - vkd3d_free($$.sizes); - YYABORT; - } - - if (!(new_array = hlsl_realloc(ctx, $$.sizes, ($$.count + 1) * sizeof(*new_array)))) - { - vkd3d_free($$.sizes); - YYABORT; - } - $$.sizes = new_array; - $$.sizes[$$.count++] = size; - } - -var_modifiers: - %empty - { - $$ = 0; - } - | KW_EXTERN var_modifiers - { - $$ = add_modifiers(ctx, $2, HLSL_STORAGE_EXTERN, @1); - } - | KW_NOINTERPOLATION var_modifiers - { - $$ = add_modifiers(ctx, $2, HLSL_STORAGE_NOINTERPOLATION, @1); - } - | KW_PRECISE var_modifiers - { - $$ = add_modifiers(ctx, $2, HLSL_MODIFIER_PRECISE, @1); - } - | KW_SHARED var_modifiers - { - $$ = add_modifiers(ctx, $2, HLSL_STORAGE_SHARED, @1); - } - | KW_GROUPSHARED var_modifiers - { - $$ = add_modifiers(ctx, $2, HLSL_STORAGE_GROUPSHARED, @1); - } - | KW_STATIC var_modifiers - { - $$ = add_modifiers(ctx, $2, HLSL_STORAGE_STATIC, @1); - } - | KW_UNIFORM var_modifiers - { - $$ = add_modifiers(ctx, $2, HLSL_STORAGE_UNIFORM, @1); - } - | KW_VOLATILE var_modifiers - { - $$ = add_modifiers(ctx, $2, HLSL_STORAGE_VOLATILE, @1); - } - | KW_CONST var_modifiers - { - $$ = add_modifiers(ctx, $2, HLSL_MODIFIER_CONST, @1); - } - | KW_ROW_MAJOR var_modifiers - { - $$ = add_modifiers(ctx, $2, HLSL_MODIFIER_ROW_MAJOR, @1); - } - | KW_COLUMN_MAJOR var_modifiers - { - $$ = add_modifiers(ctx, $2, HLSL_MODIFIER_COLUMN_MAJOR, @1); - } - -complex_initializer: - initializer_expr - { - $$.args_count = 1; - if (!($$.args = hlsl_alloc(ctx, sizeof(*$$.args)))) - YYABORT; - $$.args[0] = node_from_list($1); - $$.instrs = $1; - } - | '{' initializer_expr_list '}' - { - $$ = $2; - } - | '{' initializer_expr_list ',' '}' - { - $$ = $2; - } - -initializer_expr: - assignment_expr - -initializer_expr_list: - initializer_expr - { - $$.args_count = 1; - if (!($$.args = hlsl_alloc(ctx, sizeof(*$$.args)))) - YYABORT; - $$.args[0] = node_from_list($1); - $$.instrs = $1; - } - | initializer_expr_list ',' initializer_expr - { - $$ = $1; - if (!($$.args = hlsl_realloc(ctx, $$.args, ($$.args_count + 1) * sizeof(*$$.args)))) - YYABORT; - $$.args[$$.args_count++] = node_from_list($3); - list_move_tail($$.instrs, $3); - vkd3d_free($3); - } - -boolean: - KW_TRUE - { - $$ = TRUE; - } - | KW_FALSE - { - $$ = FALSE; - } - -statement_list: - statement - | statement_list statement - { - $$ = $1; - list_move_tail($$, $2); - vkd3d_free($2); - } - -statement: - declaration_statement - | expr_statement - | compound_statement - | jump_statement - | selection_statement - | loop_statement - -jump_statement: - KW_RETURN expr ';' - { - if (!add_return(ctx, $2, node_from_list($2), @1)) - YYABORT; - $$ = $2; - } - | KW_RETURN ';' - { - if (!($$ = make_empty_list(ctx))) - YYABORT; - if (!add_return(ctx, $$, NULL, @1)) - YYABORT; - } - -selection_statement: - KW_IF '(' expr ')' if_body - { - struct hlsl_ir_node *condition = node_from_list($3); - struct hlsl_ir_if *instr; - - if (!(instr = hlsl_new_if(ctx, condition, @1))) - YYABORT; - list_move_tail(&instr->then_instrs.instrs, $5.then_instrs); - if ($5.else_instrs) - list_move_tail(&instr->else_instrs.instrs, $5.else_instrs); - vkd3d_free($5.then_instrs); - vkd3d_free($5.else_instrs); - if (condition->data_type->dimx > 1 || condition->data_type->dimy > 1) - { - struct vkd3d_string_buffer *string; - - if ((string = hlsl_type_to_string(ctx, condition->data_type))) - hlsl_error(ctx, &instr->node.loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "if condition type %s is not scalar.", string->buffer); - hlsl_release_string_buffer(ctx, string); - } - $$ = $3; - list_add_tail($$, &instr->node.entry); - } - -if_body: - statement - { - $$.then_instrs = $1; - $$.else_instrs = NULL; - } - | statement KW_ELSE statement - { - $$.then_instrs = $1; - $$.else_instrs = $3; - } - -loop_statement: - KW_WHILE '(' expr ')' statement - { - $$ = create_loop(ctx, LOOP_WHILE, NULL, $3, NULL, $5, @1); - } - | KW_DO statement KW_WHILE '(' expr ')' ';' - { - $$ = create_loop(ctx, LOOP_DO_WHILE, NULL, $5, NULL, $2, @1); - } - | KW_FOR '(' scope_start expr_statement expr_statement expr ')' statement - { - $$ = create_loop(ctx, LOOP_FOR, $4, $5, $6, $8, @1); - hlsl_pop_scope(ctx); - } - | KW_FOR '(' scope_start declaration expr_statement expr ')' statement - { - $$ = create_loop(ctx, LOOP_FOR, $4, $5, $6, $8, @1); - hlsl_pop_scope(ctx); - } - -expr_statement: - ';' - { - if (!($$ = make_empty_list(ctx))) - YYABORT; - } - | expr ';' - { - $$ = $1; - } - -func_arguments: - %empty - { - $$.args = NULL; - $$.args_count = 0; - if (!($$.instrs = make_empty_list(ctx))) - YYABORT; - } - | initializer_expr_list - -primary_expr: - C_FLOAT - { - struct hlsl_ir_constant *c; - - if (!(c = hlsl_alloc(ctx, sizeof(*c)))) - YYABORT; - init_node(&c->node, HLSL_IR_CONSTANT, hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), @1); - c->value[0].f = $1; - if (!($$ = make_list(ctx, &c->node))) - YYABORT; - } - | C_INTEGER - { - struct hlsl_ir_constant *c; - - if (!(c = hlsl_alloc(ctx, sizeof(*c)))) - YYABORT; - init_node(&c->node, HLSL_IR_CONSTANT, hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), @1); - c->value[0].i = $1; - if (!($$ = make_list(ctx, &c->node))) - YYABORT; - } - | boolean - { - struct hlsl_ir_constant *c; - - if (!(c = hlsl_alloc(ctx, sizeof(*c)))) - YYABORT; - init_node(&c->node, HLSL_IR_CONSTANT, hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL), @1); - c->value[0].b = $1; - if (!($$ = make_list(ctx, &c->node))) - YYABORT; - } - | VAR_IDENTIFIER - { - struct hlsl_ir_load *load; - struct hlsl_ir_var *var; - - if (!(var = hlsl_get_var(ctx->cur_scope, $1))) - { - hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Variable \"%s\" is not defined.", $1); - YYABORT; - } - if (!(load = hlsl_new_var_load(ctx, var, @1))) - YYABORT; - if (!($$ = make_list(ctx, &load->node))) - YYABORT; - } - | '(' expr ')' - { - $$ = $2; - } - | var_identifier '(' func_arguments ')' - { - if (!($$ = add_call(ctx, $1, &$3, @1))) - YYABORT; - } - | NEW_IDENTIFIER - { - if (ctx->in_state_block) - { - struct hlsl_ir_load *load; - struct hlsl_ir_var *var; - - if (!(var = hlsl_new_synthetic_var(ctx, "", - hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), @1))) - YYABORT; - if (!(load = hlsl_new_var_load(ctx, var, @1))) - YYABORT; - if (!($$ = make_list(ctx, &load->node))) - YYABORT; - } - else - { - hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Identifier \"%s\" is not declared.\n", $1); - YYABORT; - } - } - -postfix_expr: - primary_expr - | postfix_expr OP_INC - { - if (!add_increment(ctx, $1, false, true, @2)) - { - destroy_instr_list($1); - YYABORT; - } - $$ = $1; - } - | postfix_expr OP_DEC - { - if (!add_increment(ctx, $1, true, true, @2)) - { - destroy_instr_list($1); - YYABORT; - } - $$ = $1; - } - | postfix_expr '.' any_identifier - { - struct hlsl_ir_node *node = node_from_list($1); - - if (node->data_type->type == HLSL_CLASS_STRUCT) - { - struct hlsl_type *type = node->data_type; - struct hlsl_struct_field *field; - - if (!(field = get_struct_field(type->e.elements, $3))) - { - hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Field \"%s\" is not defined.", $3); - YYABORT; - } - - if (!add_record_load(ctx, $1, node, field, @2)) - YYABORT; - $$ = $1; - } - else if (node->data_type->type <= HLSL_CLASS_LAST_NUMERIC) - { - struct hlsl_ir_swizzle *swizzle; - - if (!(swizzle = get_swizzle(ctx, node, $3, &@3))) - { - hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Invalid swizzle \"%s\".", $3); - YYABORT; - } - list_add_tail($1, &swizzle->node.entry); - $$ = $1; - } - else - { - hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Invalid subscript \"%s\".", $3); - YYABORT; - } - } - | postfix_expr '[' expr ']' - { - struct hlsl_ir_node *array = node_from_list($1), *index = node_from_list($3); - struct hlsl_ir_expr *cast; - - list_move_tail($1, $3); - vkd3d_free($3); - - if (index->data_type->type != HLSL_CLASS_SCALAR) - { - hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Array index is not scalar."); - destroy_instr_list($1); - YYABORT; - } - - if (!(cast = hlsl_new_cast(ctx, index, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), &index->loc))) - { - destroy_instr_list($1); - YYABORT; - } - list_add_tail($1, &cast->node.entry); - - if (!add_array_load(ctx, $1, array, &cast->node, @2)) - { - destroy_instr_list($1); - YYABORT; - } - $$ = $1; - } - - /* var_modifiers is necessary to avoid shift/reduce conflicts. */ - | var_modifiers type '(' initializer_expr_list ')' - { - if ($1) - { - hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, - "Modifiers are not allowed on constructors."); - free_parse_initializer(&$4); - YYABORT; - } - if ($2->type > HLSL_CLASS_LAST_NUMERIC) - { - struct vkd3d_string_buffer *string; - - if ((string = hlsl_type_to_string(ctx, $2))) - hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Constructor data type %s is not numeric.", string->buffer); - hlsl_release_string_buffer(ctx, string); - free_parse_initializer(&$4); - YYABORT; - } - if ($2->dimx * $2->dimy != initializer_size(&$4)) - { - hlsl_error(ctx, &@4, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, - "Expected %u components in constructor, but got %u.", - $2->dimx * $2->dimy, initializer_size(&$4)); - free_parse_initializer(&$4); - YYABORT; - } - - if (!($$ = add_constructor(ctx, $2, &$4, @2))) - { - free_parse_initializer(&$4); - YYABORT; - } - } - | postfix_expr '.' any_identifier '(' func_arguments ')' - { - struct hlsl_ir_node *object = node_from_list($1); - - list_move_tail($1, $5.instrs); - vkd3d_free($5.instrs); - - if (!add_method_call(ctx, $1, object, $3, &$5, &@3)) - { - hlsl_free_instr_list($1); - vkd3d_free($5.args); - YYABORT; - } - vkd3d_free($5.args); - $$ = $1; - } - -unary_expr: - postfix_expr - | OP_INC unary_expr - { - if (!add_increment(ctx, $2, false, false, @1)) - { - destroy_instr_list($2); - YYABORT; - } - $$ = $2; - } - | OP_DEC unary_expr - { - if (!add_increment(ctx, $2, true, false, @1)) - { - destroy_instr_list($2); - YYABORT; - } - $$ = $2; - } - | '+' unary_expr - { - $$ = $2; - } - | '-' unary_expr - { - add_unary_arithmetic_expr(ctx, $2, HLSL_OP1_NEG, node_from_list($2), &@1); - $$ = $2; - } - | '~' unary_expr - { - add_unary_bitwise_expr(ctx, $2, HLSL_OP1_BIT_NOT, node_from_list($2), &@1); - $$ = $2; - } - | '!' unary_expr - { - add_unary_logical_expr(ctx, $2, HLSL_OP1_LOGIC_NOT, node_from_list($2), &@1); - $$ = $2; - } - /* var_modifiers is necessary to avoid shift/reduce conflicts. */ - | '(' var_modifiers type arrays ')' unary_expr - { - struct hlsl_type *src_type = node_from_list($6)->data_type; - struct hlsl_type *dst_type; - struct hlsl_ir_expr *cast; - unsigned int i; - - if ($2) - { - hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, - "Modifiers are not allowed on casts."); - YYABORT; - } - - dst_type = $3; - for (i = 0; i < $4.count; ++i) - dst_type = hlsl_new_array_type(ctx, dst_type, $4.sizes[i]); - - if (!compatible_data_types(src_type, dst_type)) - { - struct vkd3d_string_buffer *src_string, *dst_string; - - src_string = hlsl_type_to_string(ctx, src_type); - dst_string = hlsl_type_to_string(ctx, dst_type); - if (src_string && dst_string) - hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Can't cast from %s to %s.", - src_string->buffer, dst_string->buffer); - hlsl_release_string_buffer(ctx, src_string); - hlsl_release_string_buffer(ctx, dst_string); - YYABORT; - } - - if (!(cast = hlsl_new_cast(ctx, node_from_list($6), dst_type, &@3))) - { - hlsl_free_instr_list($6); - YYABORT; - } - list_add_tail($6, &cast->node.entry); - $$ = $6; - } - -mul_expr: - unary_expr - | mul_expr '*' unary_expr - { - $$ = add_binary_arithmetic_expr_merge(ctx, $1, $3, HLSL_OP2_MUL, @2); - } - | mul_expr '/' unary_expr - { - $$ = add_binary_arithmetic_expr_merge(ctx, $1, $3, HLSL_OP2_DIV, @2); - } - | mul_expr '%' unary_expr - { - $$ = add_binary_arithmetic_expr_merge(ctx, $1, $3, HLSL_OP2_MOD, @2); - } - -add_expr: - mul_expr - | add_expr '+' mul_expr - { - $$ = add_binary_arithmetic_expr_merge(ctx, $1, $3, HLSL_OP2_ADD, @2); - } - | add_expr '-' mul_expr - { - struct hlsl_ir_node *neg; - - if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, node_from_list($3), @2))) - YYABORT; - list_add_tail($3, &neg->entry); - $$ = add_binary_arithmetic_expr_merge(ctx, $1, $3, HLSL_OP2_ADD, @2); - } - -shift_expr: - add_expr - | shift_expr OP_LEFTSHIFT add_expr - { - $$ = add_binary_shift_expr_merge(ctx, $1, $3, HLSL_OP2_LSHIFT, &@2); - } - | shift_expr OP_RIGHTSHIFT add_expr - { - $$ = add_binary_shift_expr_merge(ctx, $1, $3, HLSL_OP2_RSHIFT, &@2); - } - -relational_expr: - shift_expr - | relational_expr '<' shift_expr - { - $$ = add_binary_comparison_expr_merge(ctx, $1, $3, HLSL_OP2_LESS, @2); - } - | relational_expr '>' shift_expr - { - $$ = add_binary_comparison_expr_merge(ctx, $3, $1, HLSL_OP2_LESS, @2); - } - | relational_expr OP_LE shift_expr - { - $$ = add_binary_comparison_expr_merge(ctx, $3, $1, HLSL_OP2_GEQUAL, @2); - } - | relational_expr OP_GE shift_expr - { - $$ = add_binary_comparison_expr_merge(ctx, $1, $3, HLSL_OP2_GEQUAL, @2); - } - -equality_expr: - relational_expr - | equality_expr OP_EQ relational_expr - { - $$ = add_binary_comparison_expr_merge(ctx, $1, $3, HLSL_OP2_EQUAL, @2); - } - | equality_expr OP_NE relational_expr - { - $$ = add_binary_comparison_expr_merge(ctx, $1, $3, HLSL_OP2_NEQUAL, @2); - } - -bitand_expr: - equality_expr - | bitand_expr '&' equality_expr - { - $$ = add_binary_bitwise_expr_merge(ctx, $1, $3, HLSL_OP2_BIT_AND, &@2); - } - -bitxor_expr: - bitand_expr - | bitxor_expr '^' bitand_expr - { - $$ = add_binary_bitwise_expr_merge(ctx, $1, $3, HLSL_OP2_BIT_XOR, &@2); - } - -bitor_expr: - bitxor_expr - | bitor_expr '|' bitxor_expr - { - $$ = add_binary_bitwise_expr_merge(ctx, $1, $3, HLSL_OP2_BIT_OR, &@2); - } - -logicand_expr: - bitor_expr - | logicand_expr OP_AND bitor_expr - { - $$ = add_binary_logical_expr_merge(ctx, $1, $3, HLSL_OP2_LOGIC_AND, &@2); - } - -logicor_expr: - logicand_expr - | logicor_expr OP_OR logicand_expr - { - $$ = add_binary_logical_expr_merge(ctx, $1, $3, HLSL_OP2_LOGIC_OR, &@2); - } - -conditional_expr: - logicor_expr - | logicor_expr '?' expr ':' assignment_expr - { - hlsl_fixme(ctx, &@$, "Ternary operator."); - } - -assignment_expr: - - conditional_expr - | unary_expr assign_op assignment_expr - { - struct hlsl_ir_node *lhs = node_from_list($1), *rhs = node_from_list($3); - - if (lhs->data_type->modifiers & HLSL_MODIFIER_CONST) - { - hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_MODIFIES_CONST, "Statement modifies a const expression."); - YYABORT; - } - list_move_tail($3, $1); - vkd3d_free($1); - if (!add_assignment(ctx, $3, lhs, $2, rhs)) - YYABORT; - $$ = $3; - } - -assign_op: - '=' - { - $$ = ASSIGN_OP_ASSIGN; - } - | OP_ADDASSIGN - { - $$ = ASSIGN_OP_ADD; - } - | OP_SUBASSIGN - { - $$ = ASSIGN_OP_SUB; - } - | OP_MULASSIGN - { - $$ = ASSIGN_OP_MUL; - } - | OP_DIVASSIGN - { - $$ = ASSIGN_OP_DIV; - } - | OP_MODASSIGN - { - $$ = ASSIGN_OP_MOD; - } - | OP_LEFTSHIFTASSIGN - { - $$ = ASSIGN_OP_LSHIFT; - } - | OP_RIGHTSHIFTASSIGN - { - $$ = ASSIGN_OP_RSHIFT; - } - | OP_ANDASSIGN - { - $$ = ASSIGN_OP_AND; - } - | OP_ORASSIGN - { - $$ = ASSIGN_OP_OR; - } - | OP_XORASSIGN - { - $$ = ASSIGN_OP_XOR; - } - -expr: - assignment_expr - | expr ',' assignment_expr - { - $$ = $1; - list_move_tail($$, $3); - vkd3d_free($3); - } diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/hlsl_codegen.c b/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/hlsl_codegen.c deleted file mode 100644 index 934ed33db5a25..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/hlsl_codegen.c +++ /dev/null @@ -1,1713 +0,0 @@ -/* - * HLSL optimization and code generation - * - * Copyright 2019-2020 Zebediah Figura for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "hlsl.h" -#include - -/* Split uniforms into two variables representing the constant and temp - * registers, and copy the former to the latter, so that writes to uniforms - * work. */ -static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *temp) -{ - struct vkd3d_string_buffer *name; - struct hlsl_ir_var *uniform; - struct hlsl_ir_store *store; - struct hlsl_ir_load *load; - - /* Use the synthetic name for the temp, rather than the uniform, so that we - * can write the uniform name into the shader reflection data. */ - - if (!(uniform = hlsl_new_var(ctx, temp->name, temp->data_type, temp->loc, NULL, 0, &temp->reg_reservation))) - return; - list_add_before(&temp->scope_entry, &uniform->scope_entry); - list_add_tail(&ctx->extern_vars, &uniform->extern_entry); - uniform->is_uniform = 1; - uniform->is_param = temp->is_param; - uniform->buffer = temp->buffer; - - if (!(name = hlsl_get_string_buffer(ctx))) - return; - vkd3d_string_buffer_printf(name, "", temp->name); - temp->name = hlsl_strdup(ctx, name->buffer); - hlsl_release_string_buffer(ctx, name); - - if (!(load = hlsl_new_var_load(ctx, uniform, temp->loc))) - return; - list_add_head(instrs, &load->node.entry); - - if (!(store = hlsl_new_simple_store(ctx, temp, &load->node))) - return; - list_add_after(&load->node.entry, &store->node.entry); -} - -static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var, - struct hlsl_type *type, unsigned int field_offset, const struct hlsl_semantic *semantic) -{ - struct vkd3d_string_buffer *name; - struct hlsl_semantic new_semantic; - struct hlsl_ir_constant *offset; - struct hlsl_ir_store *store; - struct hlsl_ir_load *load; - struct hlsl_ir_var *input; - - if (!(name = hlsl_get_string_buffer(ctx))) - return; - vkd3d_string_buffer_printf(name, "", semantic->name, semantic->index); - if (!(new_semantic.name = hlsl_strdup(ctx, semantic->name))) - { - hlsl_release_string_buffer(ctx, name); - return; - } - new_semantic.index = semantic->index; - if (!(input = hlsl_new_var(ctx, hlsl_strdup(ctx, name->buffer), type, var->loc, &new_semantic, 0, NULL))) - { - hlsl_release_string_buffer(ctx, name); - vkd3d_free((void *)new_semantic.name); - return; - } - hlsl_release_string_buffer(ctx, name); - input->is_input_semantic = 1; - input->is_param = var->is_param; - list_add_before(&var->scope_entry, &input->scope_entry); - list_add_tail(&ctx->extern_vars, &input->extern_entry); - - if (!(load = hlsl_new_var_load(ctx, input, var->loc))) - return; - list_add_head(instrs, &load->node.entry); - - if (!(offset = hlsl_new_uint_constant(ctx, field_offset, var->loc))) - return; - list_add_after(&load->node.entry, &offset->node.entry); - - if (!(store = hlsl_new_store(ctx, var, &offset->node, &load->node, 0, var->loc))) - return; - list_add_after(&offset->node.entry, &store->node.entry); -} - -static void prepend_input_struct_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var, - struct hlsl_type *type, unsigned int field_offset) -{ - struct hlsl_struct_field *field; - - LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry) - { - if (field->type->type == HLSL_CLASS_STRUCT) - prepend_input_struct_copy(ctx, instrs, var, field->type, field_offset + field->reg_offset); - else if (field->semantic.name) - prepend_input_copy(ctx, instrs, var, field->type, field_offset + field->reg_offset, &field->semantic); - else - hlsl_error(ctx, &field->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, - "Field '%s' is missing a semantic.", field->name); - } -} - -/* Split inputs into two variables representing the semantic and temp registers, - * and copy the former to the latter, so that writes to input variables work. */ -static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var) -{ - if (var->data_type->type == HLSL_CLASS_STRUCT) - prepend_input_struct_copy(ctx, instrs, var, var->data_type, 0); - else if (var->semantic.name) - prepend_input_copy(ctx, instrs, var, var->data_type, 0, &var->semantic); -} - -static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var, - struct hlsl_type *type, unsigned int field_offset, const struct hlsl_semantic *semantic) -{ - struct vkd3d_string_buffer *name; - struct hlsl_semantic new_semantic; - struct hlsl_ir_constant *offset; - struct hlsl_ir_store *store; - struct hlsl_ir_var *output; - struct hlsl_ir_load *load; - - if (!(name = hlsl_get_string_buffer(ctx))) - return; - vkd3d_string_buffer_printf(name, "", semantic->name, semantic->index); - if (!(new_semantic.name = hlsl_strdup(ctx, semantic->name))) - { - hlsl_release_string_buffer(ctx, name); - return; - } - new_semantic.index = semantic->index; - if (!(output = hlsl_new_var(ctx, hlsl_strdup(ctx, name->buffer), type, var->loc, &new_semantic, 0, NULL))) - { - vkd3d_free((void *)new_semantic.name); - hlsl_release_string_buffer(ctx, name); - return; - } - hlsl_release_string_buffer(ctx, name); - output->is_output_semantic = 1; - output->is_param = var->is_param; - list_add_before(&var->scope_entry, &output->scope_entry); - list_add_tail(&ctx->extern_vars, &output->extern_entry); - - if (!(offset = hlsl_new_uint_constant(ctx, field_offset, var->loc))) - return; - list_add_tail(instrs, &offset->node.entry); - - if (!(load = hlsl_new_load(ctx, var, &offset->node, type, var->loc))) - return; - list_add_after(&offset->node.entry, &load->node.entry); - - if (!(store = hlsl_new_store(ctx, output, NULL, &load->node, 0, var->loc))) - return; - list_add_after(&load->node.entry, &store->node.entry); -} - -static void append_output_struct_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var, - struct hlsl_type *type, unsigned int field_offset) -{ - struct hlsl_struct_field *field; - - LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry) - { - if (field->type->type == HLSL_CLASS_STRUCT) - append_output_struct_copy(ctx, instrs, var, field->type, field_offset + field->reg_offset); - else if (field->semantic.name) - append_output_copy(ctx, instrs, var, field->type, field_offset + field->reg_offset, &field->semantic); - else - hlsl_error(ctx, &field->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, - "Field '%s' is missing a semantic.", field->name); - } -} - -/* Split outputs into two variables representing the temp and semantic - * registers, and copy the former to the latter, so that reads from output - * variables work. */ -static void append_output_var_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var) -{ - if (var->data_type->type == HLSL_CLASS_STRUCT) - append_output_struct_copy(ctx, instrs, var, var->data_type, 0); - else if (var->semantic.name) - append_output_copy(ctx, instrs, var, var->data_type, 0, &var->semantic); -} - -static bool transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, struct hlsl_ir_node *, void *), - struct hlsl_block *block, void *context) -{ - struct hlsl_ir_node *instr, *next; - bool progress = false; - - LIST_FOR_EACH_ENTRY_SAFE(instr, next, &block->instrs, struct hlsl_ir_node, entry) - { - if (instr->type == HLSL_IR_IF) - { - struct hlsl_ir_if *iff = hlsl_ir_if(instr); - - progress |= transform_ir(ctx, func, &iff->then_instrs, context); - progress |= transform_ir(ctx, func, &iff->else_instrs, context); - } - else if (instr->type == HLSL_IR_LOOP) - progress |= transform_ir(ctx, func, &hlsl_ir_loop(instr)->body, context); - - progress |= func(ctx, instr, context); - } - - return progress; -} - -/* Lower casts from vec1 to vecN to swizzles. */ -static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -{ - const struct hlsl_type *src_type, *dst_type; - struct hlsl_type *dst_scalar_type; - struct hlsl_ir_expr *cast; - - if (instr->type != HLSL_IR_EXPR) - return false; - cast = hlsl_ir_expr(instr); - src_type = cast->operands[0].node->data_type; - dst_type = cast->node.data_type; - - if (cast->op == HLSL_OP1_CAST - && src_type->type <= HLSL_CLASS_VECTOR && dst_type->type <= HLSL_CLASS_VECTOR - && src_type->dimx == 1) - { - struct hlsl_ir_swizzle *swizzle; - struct hlsl_ir_expr *new_cast; - - dst_scalar_type = hlsl_get_scalar_type(ctx, dst_type->base_type); - /* We need to preserve the cast since it might be doing more than just - * turning the scalar into a vector. */ - if (!(new_cast = hlsl_new_cast(ctx, cast->operands[0].node, dst_scalar_type, &cast->node.loc))) - return false; - list_add_after(&cast->node.entry, &new_cast->node.entry); - if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X), dst_type->dimx, &new_cast->node, &cast->node.loc))) - return false; - list_add_after(&new_cast->node.entry, &swizzle->node.entry); - - hlsl_replace_node(&cast->node, &swizzle->node); - return true; - } - - return false; -} - -struct copy_propagation_value -{ - struct hlsl_ir_node *node; - unsigned int component; -}; - -struct copy_propagation_var_def -{ - struct wine_rb_entry entry; - struct hlsl_ir_var *var; - struct copy_propagation_value values[]; -}; - -struct copy_propagation_state -{ - struct wine_rb_tree var_defs; -}; - -static int copy_propagation_var_def_compare(const void *key, const struct wine_rb_entry *entry) -{ - struct copy_propagation_var_def *var_def = WINE_RB_ENTRY_VALUE(entry, struct copy_propagation_var_def, entry); - uintptr_t key_int = (uintptr_t)key, entry_int = (uintptr_t)var_def->var; - - return (key_int > entry_int) - (key_int < entry_int); -} - -static void copy_propagation_var_def_destroy(struct wine_rb_entry *entry, void *context) -{ - struct copy_propagation_var_def *var_def = WINE_RB_ENTRY_VALUE(entry, struct copy_propagation_var_def, entry); - - vkd3d_free(var_def); -} - -static struct copy_propagation_var_def *copy_propagation_get_var_def(const struct copy_propagation_state *state, - const struct hlsl_ir_var *var) -{ - struct wine_rb_entry *entry = wine_rb_get(&state->var_defs, var); - - if (entry) - return WINE_RB_ENTRY_VALUE(entry, struct copy_propagation_var_def, entry); - else - return NULL; -} - -static struct copy_propagation_var_def *copy_propagation_create_var_def(struct hlsl_ctx *ctx, - struct copy_propagation_state *state, struct hlsl_ir_var *var) -{ - struct wine_rb_entry *entry = wine_rb_get(&state->var_defs, var); - struct copy_propagation_var_def *var_def; - int res; - - if (entry) - return WINE_RB_ENTRY_VALUE(entry, struct copy_propagation_var_def, entry); - - if (!(var_def = hlsl_alloc(ctx, offsetof(struct copy_propagation_var_def, values[var->data_type->reg_size])))) - return NULL; - - var_def->var = var; - - res = wine_rb_put(&state->var_defs, var, &var_def->entry); - assert(!res); - - return var_def; -} - -static void copy_propagation_invalidate_whole_variable(struct copy_propagation_var_def *var_def) -{ - TRACE("Invalidate variable %s.\n", var_def->var->name); - memset(var_def->values, 0, sizeof(*var_def->values) * var_def->var->data_type->reg_size); -} - -static void copy_propagation_set_value(struct copy_propagation_var_def *var_def, unsigned int offset, - unsigned char writemask, struct hlsl_ir_node *node) -{ - unsigned int i, j = 0; - - for (i = 0; i < 4; ++i) - { - if (writemask & (1u << i)) - { - TRACE("Variable %s[%u] is written by instruction %p%s.\n", - var_def->var->name, offset + i, node, debug_hlsl_writemask(1u << i)); - var_def->values[offset + i].node = node; - var_def->values[offset + i].component = j++; - } - } -} - -static struct hlsl_ir_node *copy_propagation_compute_replacement(struct hlsl_ctx *ctx, - const struct copy_propagation_state *state, const struct hlsl_deref *deref, - unsigned int count, unsigned int *swizzle) -{ - const struct hlsl_ir_var *var = deref->var; - struct copy_propagation_var_def *var_def; - struct hlsl_ir_node *node = NULL; - unsigned int offset, i; - - if (!hlsl_offset_from_deref(ctx, deref, &offset)) - return NULL; - - if (!(var_def = copy_propagation_get_var_def(state, var))) - return NULL; - - assert(offset + count <= var_def->var->data_type->reg_size); - - *swizzle = 0; - - for (i = 0; i < count; ++i) - { - if (!node) - { - node = var_def->values[offset + i].node; - } - else if (node != var_def->values[offset + i].node) - { - TRACE("No single source for propagating load from %s[%u-%u].\n", var->name, offset, offset + count); - return NULL; - } - *swizzle |= var_def->values[offset + i].component << i * 2; - } - - TRACE("Load from %s[%u-%u] propagated as instruction %p%s.\n", - var->name, offset, offset + count, node, debug_hlsl_swizzle(*swizzle, count)); - return node; -} - -static bool copy_propagation_transform_load(struct hlsl_ctx *ctx, - struct hlsl_ir_load *load, struct copy_propagation_state *state) -{ - struct hlsl_ir_node *node = &load->node, *new_node; - struct hlsl_type *type = node->data_type; - struct hlsl_ir_swizzle *swizzle_node; - unsigned int dimx = 0; - unsigned int swizzle; - - switch (type->type) - { - case HLSL_CLASS_SCALAR: - case HLSL_CLASS_VECTOR: - dimx = type->dimx; - break; - - case HLSL_CLASS_OBJECT: - dimx = 1; - break; - - case HLSL_CLASS_MATRIX: - case HLSL_CLASS_ARRAY: - case HLSL_CLASS_STRUCT: - /* FIXME: Actually we shouldn't even get here, but we don't split - * matrices yet. */ - return false; - } - - if (!(new_node = copy_propagation_compute_replacement(ctx, state, &load->src, dimx, &swizzle))) - return false; - - if (type->type != HLSL_CLASS_OBJECT) - { - if (!(swizzle_node = hlsl_new_swizzle(ctx, swizzle, dimx, new_node, &node->loc))) - return false; - list_add_before(&node->entry, &swizzle_node->node.entry); - new_node = &swizzle_node->node; - } - hlsl_replace_node(node, new_node); - return true; -} - -static bool copy_propagation_transform_object_load(struct hlsl_ctx *ctx, - struct hlsl_deref *deref, struct copy_propagation_state *state) -{ - struct hlsl_ir_load *load; - struct hlsl_ir_node *node; - unsigned int swizzle; - - if (!(node = copy_propagation_compute_replacement(ctx, state, deref, 1, &swizzle))) - return false; - - /* Only HLSL_IR_LOAD can produce an object. */ - load = hlsl_ir_load(node); - deref->var = load->src.var; - hlsl_src_remove(&deref->offset); - hlsl_src_from_node(&deref->offset, load->src.offset.node); - return true; -} - -static bool copy_propagation_transform_resource_load(struct hlsl_ctx *ctx, - struct hlsl_ir_resource_load *load, struct copy_propagation_state *state) -{ - bool progress = false; - - progress |= copy_propagation_transform_object_load(ctx, &load->resource, state); - if (load->sampler.var) - progress |= copy_propagation_transform_object_load(ctx, &load->sampler, state); - return progress; -} - -static void copy_propagation_record_store(struct hlsl_ctx *ctx, struct hlsl_ir_store *store, - struct copy_propagation_state *state) -{ - struct copy_propagation_var_def *var_def; - struct hlsl_deref *lhs = &store->lhs; - struct hlsl_ir_var *var = lhs->var; - unsigned int offset; - - if (!(var_def = copy_propagation_create_var_def(ctx, state, var))) - return; - - if (hlsl_offset_from_deref(ctx, lhs, &offset)) - { - unsigned int writemask = store->writemask; - - if (store->rhs.node->data_type->type == HLSL_CLASS_OBJECT) - writemask = VKD3DSP_WRITEMASK_0; - copy_propagation_set_value(var_def, offset, writemask, store->rhs.node); - } - else - { - copy_propagation_invalidate_whole_variable(var_def); - } -} - -static bool copy_propagation_transform_block(struct hlsl_ctx *ctx, struct hlsl_block *block, - struct copy_propagation_state *state) -{ - struct hlsl_ir_node *instr, *next; - bool progress = false; - - LIST_FOR_EACH_ENTRY_SAFE(instr, next, &block->instrs, struct hlsl_ir_node, entry) - { - switch (instr->type) - { - case HLSL_IR_LOAD: - progress |= copy_propagation_transform_load(ctx, hlsl_ir_load(instr), state); - break; - - case HLSL_IR_RESOURCE_LOAD: - progress |= copy_propagation_transform_resource_load(ctx, hlsl_ir_resource_load(instr), state); - break; - - case HLSL_IR_STORE: - copy_propagation_record_store(ctx, hlsl_ir_store(instr), state); - break; - - case HLSL_IR_IF: - FIXME("Copy propagation doesn't support conditionals yet, leaving.\n"); - return progress; - - case HLSL_IR_LOOP: - FIXME("Copy propagation doesn't support loops yet, leaving.\n"); - return progress; - - default: - break; - } - } - - return progress; -} - -static bool copy_propagation_execute(struct hlsl_ctx *ctx, struct hlsl_block *block) -{ - struct copy_propagation_state state; - bool progress; - - wine_rb_init(&state.var_defs, copy_propagation_var_def_compare); - - progress = copy_propagation_transform_block(ctx, block, &state); - - wine_rb_destroy(&state.var_defs, copy_propagation_var_def_destroy, NULL); - - return progress; -} - -static bool is_vec1(const struct hlsl_type *type) -{ - return (type->type == HLSL_CLASS_SCALAR) || (type->type == HLSL_CLASS_VECTOR && type->dimx == 1); -} - -static bool fold_redundant_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -{ - if (instr->type == HLSL_IR_EXPR) - { - struct hlsl_ir_expr *expr = hlsl_ir_expr(instr); - const struct hlsl_type *src_type = expr->operands[0].node->data_type; - const struct hlsl_type *dst_type = expr->node.data_type; - - if (expr->op != HLSL_OP1_CAST) - return false; - - if (hlsl_types_are_equal(src_type, dst_type) - || (src_type->base_type == dst_type->base_type && is_vec1(src_type) && is_vec1(dst_type))) - { - hlsl_replace_node(&expr->node, expr->operands[0].node); - return true; - } - } - - return false; -} - -/* Helper for split_array_copies() and split_struct_copies(). Inserts new - * instructions right before "store". */ -static bool split_copy(struct hlsl_ctx *ctx, struct hlsl_ir_store *store, - const struct hlsl_ir_load *load, const unsigned int offset, struct hlsl_type *type) -{ - struct hlsl_ir_node *offset_instr, *add; - struct hlsl_ir_store *split_store; - struct hlsl_ir_load *split_load; - struct hlsl_ir_constant *c; - - if (!(c = hlsl_new_uint_constant(ctx, offset, store->node.loc))) - return false; - list_add_before(&store->node.entry, &c->node.entry); - - offset_instr = &c->node; - if (load->src.offset.node) - { - if (!(add = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, load->src.offset.node, &c->node))) - return false; - list_add_before(&store->node.entry, &add->entry); - offset_instr = add; - } - if (!(split_load = hlsl_new_load(ctx, load->src.var, offset_instr, type, store->node.loc))) - return false; - list_add_before(&store->node.entry, &split_load->node.entry); - - offset_instr = &c->node; - if (store->lhs.offset.node) - { - if (!(add = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, store->lhs.offset.node, &c->node))) - return false; - list_add_before(&store->node.entry, &add->entry); - offset_instr = add; - } - - if (!(split_store = hlsl_new_store(ctx, store->lhs.var, offset_instr, &split_load->node, 0, store->node.loc))) - return false; - list_add_before(&store->node.entry, &split_store->node.entry); - - return true; -} - -static bool split_array_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -{ - const struct hlsl_ir_node *rhs; - struct hlsl_type *element_type; - const struct hlsl_type *type; - unsigned int element_size, i; - struct hlsl_ir_store *store; - - if (instr->type != HLSL_IR_STORE) - return false; - - store = hlsl_ir_store(instr); - rhs = store->rhs.node; - type = rhs->data_type; - if (type->type != HLSL_CLASS_ARRAY) - return false; - element_type = type->e.array.type; - element_size = element_type->reg_size; - - for (i = 0; i < type->e.array.elements_count; ++i) - { - if (!split_copy(ctx, store, hlsl_ir_load(rhs), i * element_size, element_type)) - return false; - } - - /* Remove the store instruction, so that we can split structs which contain - * other structs. Although assignments produce a value, we don't allow - * HLSL_IR_STORE to be used as a source. */ - list_remove(&store->node.entry); - hlsl_free_instr(&store->node); - return true; -} - -static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -{ - const struct hlsl_struct_field *field; - const struct hlsl_ir_node *rhs; - const struct hlsl_type *type; - struct hlsl_ir_store *store; - - if (instr->type != HLSL_IR_STORE) - return false; - - store = hlsl_ir_store(instr); - rhs = store->rhs.node; - type = rhs->data_type; - if (type->type != HLSL_CLASS_STRUCT) - return false; - - LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry) - { - if (!split_copy(ctx, store, hlsl_ir_load(rhs), field->reg_offset, field->type)) - return false; - } - - /* Remove the store instruction, so that we can split structs which contain - * other structs. Although assignments produce a value, we don't allow - * HLSL_IR_STORE to be used as a source. */ - list_remove(&store->node.entry); - hlsl_free_instr(&store->node); - return true; -} - -static bool lower_narrowing_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -{ - const struct hlsl_type *src_type, *dst_type; - struct hlsl_type *dst_vector_type; - struct hlsl_ir_expr *cast; - - if (instr->type != HLSL_IR_EXPR) - return false; - cast = hlsl_ir_expr(instr); - src_type = cast->operands[0].node->data_type; - dst_type = cast->node.data_type; - - if (cast->op == HLSL_OP1_CAST - && src_type->type <= HLSL_CLASS_VECTOR && dst_type->type <= HLSL_CLASS_VECTOR - && dst_type->dimx < src_type->dimx) - { - struct hlsl_ir_swizzle *swizzle; - struct hlsl_ir_expr *new_cast; - - dst_vector_type = hlsl_get_vector_type(ctx, dst_type->base_type, src_type->dimx); - /* We need to preserve the cast since it might be doing more than just - * narrowing the vector. */ - if (!(new_cast = hlsl_new_cast(ctx, cast->operands[0].node, dst_vector_type, &cast->node.loc))) - return false; - list_add_after(&cast->node.entry, &new_cast->node.entry); - if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, Y, Z, W), dst_type->dimx, &new_cast->node, &cast->node.loc))) - return false; - list_add_after(&new_cast->node.entry, &swizzle->node.entry); - - hlsl_replace_node(&cast->node, &swizzle->node); - return true; - } - - return false; -} - -static bool remove_trivial_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -{ - struct hlsl_ir_swizzle *swizzle; - unsigned int i; - - if (instr->type != HLSL_IR_SWIZZLE) - return false; - swizzle = hlsl_ir_swizzle(instr); - - if (instr->data_type->dimx != swizzle->val.node->data_type->dimx) - return false; - - for (i = 0; i < instr->data_type->dimx; ++i) - if (((swizzle->swizzle >> (2 * i)) & 3) != i) - return false; - - hlsl_replace_node(instr, swizzle->val.node); - - return true; -} - -/* Lower DIV to RCP + MUL. */ -static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -{ - struct hlsl_ir_expr *expr; - struct hlsl_ir_node *rcp; - - if (instr->type != HLSL_IR_EXPR) - return false; - expr = hlsl_ir_expr(instr); - if (expr->op != HLSL_OP2_DIV) - return false; - - if (!(rcp = hlsl_new_unary_expr(ctx, HLSL_OP1_RCP, expr->operands[1].node, instr->loc))) - return false; - list_add_before(&expr->node.entry, &rcp->entry); - expr->op = HLSL_OP2_MUL; - hlsl_src_remove(&expr->operands[1]); - hlsl_src_from_node(&expr->operands[1], rcp); - return true; -} - -static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -{ - switch (instr->type) - { - case HLSL_IR_CONSTANT: - case HLSL_IR_EXPR: - case HLSL_IR_LOAD: - case HLSL_IR_RESOURCE_LOAD: - case HLSL_IR_SWIZZLE: - if (list_empty(&instr->uses)) - { - list_remove(&instr->entry); - hlsl_free_instr(instr); - return true; - } - break; - - case HLSL_IR_STORE: - { - struct hlsl_ir_store *store = hlsl_ir_store(instr); - struct hlsl_ir_var *var = store->lhs.var; - - if (var->last_read < instr->index) - { - list_remove(&instr->entry); - hlsl_free_instr(instr); - return true; - } - break; - } - - case HLSL_IR_IF: - case HLSL_IR_JUMP: - case HLSL_IR_LOOP: - break; - } - - return false; -} - -/* Allocate a unique, ordered index to each instruction, which will be used for - * computing liveness ranges. */ -static unsigned int index_instructions(struct hlsl_block *block, unsigned int index) -{ - struct hlsl_ir_node *instr; - - LIST_FOR_EACH_ENTRY(instr, &block->instrs, struct hlsl_ir_node, entry) - { - instr->index = index++; - - if (instr->type == HLSL_IR_IF) - { - struct hlsl_ir_if *iff = hlsl_ir_if(instr); - index = index_instructions(&iff->then_instrs, index); - index = index_instructions(&iff->else_instrs, index); - } - else if (instr->type == HLSL_IR_LOOP) - { - index = index_instructions(&hlsl_ir_loop(instr)->body, index); - hlsl_ir_loop(instr)->next_index = index; - } - } - - return index; -} - -static void dump_function_decl(struct wine_rb_entry *entry, void *context) -{ - struct hlsl_ir_function_decl *func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry); - struct hlsl_ctx *ctx = context; - - if (func->has_body) - hlsl_dump_function(ctx, func); -} - -static void dump_function(struct wine_rb_entry *entry, void *context) -{ - struct hlsl_ir_function *func = WINE_RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry); - struct hlsl_ctx *ctx = context; - - wine_rb_for_each_entry(&func->overloads, dump_function_decl, ctx); -} - -/* Compute the earliest and latest liveness for each variable. In the case that - * a variable is accessed inside of a loop, we promote its liveness to extend - * to at least the range of the entire loop. Note that we don't need to do this - * for anonymous nodes, since there's currently no way to use a node which was - * calculated in an earlier iteration of the loop. */ -static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop_first, unsigned int loop_last) -{ - struct hlsl_ir_node *instr; - struct hlsl_ir_var *var; - - LIST_FOR_EACH_ENTRY(instr, &block->instrs, struct hlsl_ir_node, entry) - { - const unsigned int var_last_read = loop_last ? max(instr->index, loop_last) : instr->index; - - switch (instr->type) - { - case HLSL_IR_STORE: - { - struct hlsl_ir_store *store = hlsl_ir_store(instr); - - var = store->lhs.var; - if (!var->first_write) - var->first_write = loop_first ? min(instr->index, loop_first) : instr->index; - store->rhs.node->last_read = instr->index; - if (store->lhs.offset.node) - store->lhs.offset.node->last_read = instr->index; - break; - } - case HLSL_IR_EXPR: - { - struct hlsl_ir_expr *expr = hlsl_ir_expr(instr); - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(expr->operands) && expr->operands[i].node; ++i) - expr->operands[i].node->last_read = instr->index; - break; - } - case HLSL_IR_IF: - { - struct hlsl_ir_if *iff = hlsl_ir_if(instr); - - compute_liveness_recurse(&iff->then_instrs, loop_first, loop_last); - compute_liveness_recurse(&iff->else_instrs, loop_first, loop_last); - iff->condition.node->last_read = instr->index; - break; - } - case HLSL_IR_LOAD: - { - struct hlsl_ir_load *load = hlsl_ir_load(instr); - - var = load->src.var; - var->last_read = max(var->last_read, var_last_read); - if (load->src.offset.node) - load->src.offset.node->last_read = instr->index; - break; - } - case HLSL_IR_LOOP: - { - struct hlsl_ir_loop *loop = hlsl_ir_loop(instr); - - compute_liveness_recurse(&loop->body, loop_first ? loop_first : instr->index, - loop_last ? loop_last : loop->next_index); - break; - } - case HLSL_IR_RESOURCE_LOAD: - { - struct hlsl_ir_resource_load *load = hlsl_ir_resource_load(instr); - - var = load->resource.var; - var->last_read = max(var->last_read, var_last_read); - if (load->resource.offset.node) - load->resource.offset.node->last_read = instr->index; - - if ((var = load->sampler.var)) - { - var->last_read = max(var->last_read, var_last_read); - if (load->sampler.offset.node) - load->sampler.offset.node->last_read = instr->index; - } - - load->coords.node->last_read = instr->index; - if (load->texel_offset.node) - load->texel_offset.node->last_read = instr->index; - break; - } - case HLSL_IR_SWIZZLE: - { - struct hlsl_ir_swizzle *swizzle = hlsl_ir_swizzle(instr); - - swizzle->val.node->last_read = instr->index; - break; - } - case HLSL_IR_CONSTANT: - case HLSL_IR_JUMP: - break; - } - } -} - -static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) -{ - struct hlsl_scope *scope; - struct hlsl_ir_var *var; - - /* Index 0 means unused; index 1 means function entry, so start at 2. */ - index_instructions(&entry_func->body, 2); - - LIST_FOR_EACH_ENTRY(scope, &ctx->scopes, struct hlsl_scope, entry) - { - LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry) - var->first_write = var->last_read = 0; - } - - LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) - { - if (var->is_uniform || var->is_input_semantic) - var->first_write = 1; - else if (var->is_output_semantic) - var->last_read = UINT_MAX; - } - - compute_liveness_recurse(&entry_func->body, 0, 0); -} - -struct liveness -{ - size_t size; - uint32_t reg_count; - struct - { - /* 0 if not live yet. */ - unsigned int last_read; - } *regs; -}; - -static unsigned int get_available_writemask(struct liveness *liveness, - unsigned int first_write, unsigned int component_idx, unsigned int component_count) -{ - unsigned int i, writemask = 0, count = 0; - - for (i = 0; i < 4; ++i) - { - if (liveness->regs[component_idx + i].last_read <= first_write) - { - writemask |= 1u << i; - if (++count == component_count) - return writemask; - } - } - - return 0; -} - -static bool resize_liveness(struct hlsl_ctx *ctx, struct liveness *liveness, size_t new_count) -{ - size_t old_capacity = liveness->size; - - if (!hlsl_array_reserve(ctx, (void **)&liveness->regs, &liveness->size, new_count, sizeof(*liveness->regs))) - return false; - - if (liveness->size > old_capacity) - memset(liveness->regs + old_capacity, 0, (liveness->size - old_capacity) * sizeof(*liveness->regs)); - return true; -} - -static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct liveness *liveness, - unsigned int first_write, unsigned int last_read, unsigned int component_count) -{ - unsigned int component_idx, writemask, i; - struct hlsl_reg ret = {0}; - - for (component_idx = 0; component_idx < liveness->size; component_idx += 4) - { - if ((writemask = get_available_writemask(liveness, first_write, component_idx, component_count))) - break; - } - if (component_idx == liveness->size) - { - if (!resize_liveness(ctx, liveness, component_idx + 4)) - return ret; - writemask = (1u << component_count) - 1; - } - for (i = 0; i < 4; ++i) - { - if (writemask & (1u << i)) - liveness->regs[component_idx + i].last_read = last_read; - } - ret.id = component_idx / 4; - ret.writemask = writemask; - ret.allocated = true; - liveness->reg_count = max(liveness->reg_count, ret.id + 1); - return ret; -} - -static bool is_range_available(struct liveness *liveness, unsigned int first_write, - unsigned int component_idx, unsigned int component_count) -{ - unsigned int i; - - for (i = 0; i < component_count; i += 4) - { - if (!get_available_writemask(liveness, first_write, component_idx + i, 4)) - return false; - } - return true; -} - -static struct hlsl_reg allocate_range(struct hlsl_ctx *ctx, struct liveness *liveness, - unsigned int first_write, unsigned int last_read, unsigned int component_count) -{ - unsigned int i, component_idx; - struct hlsl_reg ret = {0}; - - for (component_idx = 0; component_idx < liveness->size; component_idx += 4) - { - if (is_range_available(liveness, first_write, component_idx, - min(component_count, liveness->size - component_idx))) - break; - } - if (!resize_liveness(ctx, liveness, component_idx + component_count)) - return ret; - - for (i = 0; i < component_count; ++i) - liveness->regs[component_idx + i].last_read = last_read; - ret.id = component_idx / 4; - ret.allocated = true; - liveness->reg_count = max(liveness->reg_count, ret.id + align(component_count, 4)); - return ret; -} - -static const char *debug_register(char class, struct hlsl_reg reg, const struct hlsl_type *type) -{ - static const char writemask_offset[] = {'w','x','y','z'}; - - if (type->reg_size > 4) - { - if (type->reg_size & 3) - return vkd3d_dbg_sprintf("%c%u-%c%u.%c", class, reg.id, class, - reg.id + (type->reg_size / 4), writemask_offset[type->reg_size & 3]); - - return vkd3d_dbg_sprintf("%c%u-%c%u", class, reg.id, class, - reg.id + (type->reg_size / 4) - 1); - } - return vkd3d_dbg_sprintf("%c%u%s", class, reg.id, debug_hlsl_writemask(reg.writemask)); -} - -static void allocate_variable_temp_register(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, struct liveness *liveness) -{ - if (var->is_input_semantic || var->is_output_semantic || var->is_uniform) - return; - - if (!var->reg.allocated && var->last_read) - { - if (var->data_type->reg_size > 4) - var->reg = allocate_range(ctx, liveness, var->first_write, - var->last_read, var->data_type->reg_size); - else - var->reg = allocate_register(ctx, liveness, var->first_write, - var->last_read, var->data_type->dimx); - TRACE("Allocated %s to %s (liveness %u-%u).\n", var->name, - debug_register('r', var->reg, var->data_type), var->first_write, var->last_read); - } -} - -static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_block *block, struct liveness *liveness) -{ - struct hlsl_ir_node *instr; - - LIST_FOR_EACH_ENTRY(instr, &block->instrs, struct hlsl_ir_node, entry) - { - if (!instr->reg.allocated && instr->last_read) - { - if (instr->data_type->reg_size > 4) - instr->reg = allocate_range(ctx, liveness, instr->index, - instr->last_read, instr->data_type->reg_size); - else - instr->reg = allocate_register(ctx, liveness, instr->index, - instr->last_read, instr->data_type->dimx); - TRACE("Allocated anonymous expression @%u to %s (liveness %u-%u).\n", instr->index, - debug_register('r', instr->reg, instr->data_type), instr->index, instr->last_read); - } - - switch (instr->type) - { - case HLSL_IR_IF: - { - struct hlsl_ir_if *iff = hlsl_ir_if(instr); - allocate_temp_registers_recurse(ctx, &iff->then_instrs, liveness); - allocate_temp_registers_recurse(ctx, &iff->else_instrs, liveness); - break; - } - - case HLSL_IR_LOAD: - { - struct hlsl_ir_load *load = hlsl_ir_load(instr); - /* We need to at least allocate a variable for undefs. - * FIXME: We should probably find a way to remove them instead. */ - allocate_variable_temp_register(ctx, load->src.var, liveness); - break; - } - - case HLSL_IR_LOOP: - { - struct hlsl_ir_loop *loop = hlsl_ir_loop(instr); - allocate_temp_registers_recurse(ctx, &loop->body, liveness); - break; - } - - case HLSL_IR_STORE: - { - struct hlsl_ir_store *store = hlsl_ir_store(instr); - allocate_variable_temp_register(ctx, store->lhs.var, liveness); - break; - } - - default: - break; - } - } -} - -static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_block *block, struct liveness *liveness) -{ - struct hlsl_constant_defs *defs = &ctx->constant_defs; - struct hlsl_ir_node *instr; - - LIST_FOR_EACH_ENTRY(instr, &block->instrs, struct hlsl_ir_node, entry) - { - switch (instr->type) - { - case HLSL_IR_CONSTANT: - { - struct hlsl_ir_constant *constant = hlsl_ir_constant(instr); - const struct hlsl_type *type = instr->data_type; - unsigned int x, y, i, writemask, end_reg; - unsigned int reg_size = type->reg_size; - - if (reg_size > 4) - constant->reg = allocate_range(ctx, liveness, 1, UINT_MAX, reg_size); - else - constant->reg = allocate_register(ctx, liveness, 1, UINT_MAX, type->dimx); - TRACE("Allocated constant @%u to %s.\n", instr->index, debug_register('c', constant->reg, type)); - - if (!hlsl_array_reserve(ctx, (void **)&defs->values, &defs->size, - constant->reg.id + reg_size / 4, sizeof(*defs->values))) - return; - end_reg = constant->reg.id + reg_size / 4; - if (end_reg > defs->count) - { - memset(&defs->values[defs->count], 0, sizeof(*defs->values) * (end_reg - defs->count)); - defs->count = end_reg; - } - - assert(type->type <= HLSL_CLASS_LAST_NUMERIC); - - if (!(writemask = constant->reg.writemask)) - writemask = (1u << type->dimx) - 1; - - for (y = 0; y < type->dimy; ++y) - { - for (x = 0, i = 0; x < 4; ++x) - { - const union hlsl_constant_value *value; - float f; - - if (!(writemask & (1u << x))) - continue; - value = &constant->value[i++]; - - switch (type->base_type) - { - case HLSL_TYPE_BOOL: - f = value->b; - break; - - case HLSL_TYPE_FLOAT: - case HLSL_TYPE_HALF: - f = value->f; - break; - - case HLSL_TYPE_INT: - f = value->i; - break; - - case HLSL_TYPE_UINT: - f = value->u; - break; - - case HLSL_TYPE_DOUBLE: - FIXME("Double constant.\n"); - return; - - default: - assert(0); - return; - } - defs->values[constant->reg.id + y].f[x] = f; - } - } - - break; - } - - case HLSL_IR_IF: - { - struct hlsl_ir_if *iff = hlsl_ir_if(instr); - allocate_const_registers_recurse(ctx, &iff->then_instrs, liveness); - allocate_const_registers_recurse(ctx, &iff->else_instrs, liveness); - break; - } - - case HLSL_IR_LOOP: - { - struct hlsl_ir_loop *loop = hlsl_ir_loop(instr); - allocate_const_registers_recurse(ctx, &loop->body, liveness); - break; - } - - default: - break; - } - } -} - -static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) -{ - struct liveness liveness = {0}; - struct hlsl_ir_var *var; - - allocate_const_registers_recurse(ctx, &entry_func->body, &liveness); - - LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) - { - if (var->is_uniform && var->last_read) - { - if (var->data_type->reg_size > 4) - var->reg = allocate_range(ctx, &liveness, 1, UINT_MAX, var->data_type->reg_size); - else - { - var->reg = allocate_register(ctx, &liveness, 1, UINT_MAX, 4); - var->reg.writemask = (1u << var->data_type->dimx) - 1; - } - TRACE("Allocated %s to %s.\n", var->name, debug_register('c', var->reg, var->data_type)); - } - } -} - -/* Simple greedy temporary register allocation pass that just assigns a unique - * index to all (simultaneously live) variables or intermediate values. Agnostic - * as to how many registers are actually available for the current backend, and - * does not handle constants. */ -static void allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) -{ - struct liveness liveness = {0}; - allocate_temp_registers_recurse(ctx, &entry_func->body, &liveness); - ctx->temp_count = liveness.reg_count; - vkd3d_free(liveness.regs); -} - -static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, unsigned int *counter, bool output) -{ - static const char *shader_names[] = - { - [VKD3D_SHADER_TYPE_PIXEL] = "Pixel", - [VKD3D_SHADER_TYPE_VERTEX] = "Vertex", - [VKD3D_SHADER_TYPE_GEOMETRY] = "Geometry", - [VKD3D_SHADER_TYPE_HULL] = "Hull", - [VKD3D_SHADER_TYPE_DOMAIN] = "Domain", - [VKD3D_SHADER_TYPE_COMPUTE] = "Compute", - }; - - unsigned int type; - uint32_t reg; - bool builtin; - - assert(var->semantic.name); - - if (ctx->profile->major_version < 4) - { - D3DDECLUSAGE usage; - uint32_t usage_idx; - - if (!hlsl_sm1_usage_from_semantic(&var->semantic, &usage, &usage_idx)) - { - hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, - "Invalid semantic '%s'.", var->semantic.name); - return; - } - - if ((!output && !var->last_read) || (output && !var->first_write)) - return; - - builtin = hlsl_sm1_register_from_semantic(ctx, &var->semantic, output, &type, ®); - } - else - { - D3D_NAME usage; - bool has_idx; - - if (!hlsl_sm4_usage_from_semantic(ctx, &var->semantic, output, &usage)) - { - hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, - "Invalid semantic '%s'.", var->semantic.name); - return; - } - if ((builtin = hlsl_sm4_register_from_semantic(ctx, &var->semantic, output, &type, NULL, &has_idx))) - reg = has_idx ? var->semantic.index : 0; - } - - if (builtin) - { - TRACE("%s %s semantic %s[%u] matches predefined register %#x[%u].\n", shader_names[ctx->profile->type], - output ? "output" : "input", var->semantic.name, var->semantic.index, type, reg); - } - else - { - var->reg.allocated = true; - var->reg.id = (*counter)++; - var->reg.writemask = (1 << var->data_type->dimx) - 1; - TRACE("Allocated %s to %s.\n", var->name, debug_register(output ? 'o' : 'v', var->reg, var->data_type)); - } -} - -static void allocate_semantic_registers(struct hlsl_ctx *ctx) -{ - unsigned int input_counter = 0, output_counter = 0; - struct hlsl_ir_var *var; - - LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) - { - if (var->is_input_semantic) - allocate_semantic_register(ctx, var, &input_counter, false); - if (var->is_output_semantic) - allocate_semantic_register(ctx, var, &output_counter, true); - } -} - -static const struct hlsl_buffer *get_reserved_buffer(struct hlsl_ctx *ctx, uint32_t index) -{ - const struct hlsl_buffer *buffer; - - LIST_FOR_EACH_ENTRY(buffer, &ctx->buffers, const struct hlsl_buffer, entry) - { - if (buffer->used_size && buffer->reservation.type == 'b' && buffer->reservation.index == index) - return buffer; - } - return NULL; -} - -static void calculate_buffer_offset(struct hlsl_ir_var *var) -{ - struct hlsl_buffer *buffer = var->buffer; - - buffer->size = hlsl_type_get_sm4_offset(var->data_type, buffer->size); - - var->buffer_offset = buffer->size; - TRACE("Allocated buffer offset %u to %s.\n", var->buffer_offset, var->name); - buffer->size += var->data_type->reg_size; - if (var->last_read) - buffer->used_size = buffer->size; -} - -static void allocate_buffers(struct hlsl_ctx *ctx) -{ - struct hlsl_buffer *buffer; - struct hlsl_ir_var *var; - uint32_t index = 0; - - LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) - { - if (var->is_uniform && var->data_type->type != HLSL_CLASS_OBJECT) - { - if (var->is_param) - var->buffer = ctx->params_buffer; - - calculate_buffer_offset(var); - } - } - - LIST_FOR_EACH_ENTRY(buffer, &ctx->buffers, struct hlsl_buffer, entry) - { - if (!buffer->used_size) - continue; - - if (buffer->type == HLSL_BUFFER_CONSTANT) - { - if (buffer->reservation.type == 'b') - { - const struct hlsl_buffer *reserved_buffer = get_reserved_buffer(ctx, buffer->reservation.index); - - if (reserved_buffer && reserved_buffer != buffer) - { - hlsl_error(ctx, &buffer->loc, VKD3D_SHADER_ERROR_HLSL_OVERLAPPING_RESERVATIONS, - "Multiple buffers bound to cb%u.", buffer->reservation.index); - hlsl_note(ctx, &reserved_buffer->loc, VKD3D_SHADER_LOG_ERROR, - "Buffer %s is already bound to cb%u.", reserved_buffer->name, buffer->reservation.index); - } - - buffer->reg.id = buffer->reservation.index; - buffer->reg.allocated = true; - TRACE("Allocated reserved %s to cb%u.\n", buffer->name, index); - } - else if (!buffer->reservation.type) - { - while (get_reserved_buffer(ctx, index)) - ++index; - - buffer->reg.id = index; - buffer->reg.allocated = true; - TRACE("Allocated %s to cb%u.\n", buffer->name, index); - ++index; - } - else - { - hlsl_error(ctx, &buffer->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, - "Constant buffers must be allocated to register type 'b'."); - } - } - else - { - FIXME("Allocate registers for texture buffers.\n"); - } - } -} - -static const struct hlsl_ir_var *get_reserved_object(struct hlsl_ctx *ctx, char type, uint32_t index) -{ - const struct hlsl_ir_var *var; - - LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, const struct hlsl_ir_var, extern_entry) - { - if (var->last_read && var->reg_reservation.type == type && var->reg_reservation.index == index) - return var; - } - return NULL; -} - -static const struct object_type_info -{ - enum hlsl_base_type type; - char reg_name; -} -object_types[] = -{ - { HLSL_TYPE_SAMPLER, 's' }, - { HLSL_TYPE_TEXTURE, 't' }, -}; - -static const struct object_type_info *get_object_type_info(enum hlsl_base_type type) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(object_types); ++i) - if (type == object_types[i].type) - return &object_types[i]; - - WARN("No type info for object type %u.\n", type); - return NULL; -} - -static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_base_type type) -{ - const struct object_type_info *type_info = get_object_type_info(type); - struct hlsl_ir_var *var; - uint32_t index = 0; - - LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) - { - if (!var->last_read || var->data_type->type != HLSL_CLASS_OBJECT - || var->data_type->base_type != type) - continue; - - if (var->reg_reservation.type == type_info->reg_name) - { - const struct hlsl_ir_var *reserved_object = get_reserved_object(ctx, type_info->reg_name, - var->reg_reservation.index); - - if (reserved_object && reserved_object != var) - { - hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_OVERLAPPING_RESERVATIONS, - "Multiple objects bound to %c%u.", type_info->reg_name, - var->reg_reservation.index); - hlsl_note(ctx, &reserved_object->loc, VKD3D_SHADER_LOG_ERROR, - "Object '%s' is already bound to %c%u.", reserved_object->name, - type_info->reg_name, var->reg_reservation.index); - } - - var->reg.id = var->reg_reservation.index; - var->reg.allocated = true; - TRACE("Allocated reserved %s to %c%u.\n", var->name, type_info->reg_name, var->reg_reservation.index); - } - else if (!var->reg_reservation.type) - { - while (get_reserved_object(ctx, type_info->reg_name, index)) - ++index; - - var->reg.id = index; - var->reg.allocated = true; - TRACE("Allocated object to %c%u.\n", type_info->reg_name, index); - ++index; - } - else - { - struct vkd3d_string_buffer *type_string; - - type_string = hlsl_type_to_string(ctx, var->data_type); - hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, - "Object of type '%s' must be bound to register type '%c'.", - type_string->buffer, type_info->reg_name); - hlsl_release_string_buffer(ctx, type_string); - } - } -} - -static bool type_is_single_reg(const struct hlsl_type *type) -{ - return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_VECTOR; -} - -bool hlsl_offset_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, unsigned int *offset) -{ - struct hlsl_ir_node *offset_node = deref->offset.node; - - if (!offset_node) - { - *offset = 0; - return true; - } - - /* We should always have generated a cast to UINT. */ - assert(offset_node->data_type->type == HLSL_CLASS_SCALAR - && offset_node->data_type->base_type == HLSL_TYPE_UINT); - - if (offset_node->type != HLSL_IR_CONSTANT) - return false; - - *offset = hlsl_ir_constant(offset_node)->value[0].u; - - if (*offset >= deref->var->data_type->reg_size) - { - hlsl_error(ctx, &deref->offset.node->loc, VKD3D_SHADER_ERROR_HLSL_OFFSET_OUT_OF_BOUNDS, - "Dereference is out of bounds."); - return false; - } - - return true; -} - -unsigned int hlsl_offset_from_deref_safe(struct hlsl_ctx *ctx, const struct hlsl_deref *deref) -{ - unsigned int offset; - - if (hlsl_offset_from_deref(ctx, deref, &offset)) - return offset; - - hlsl_fixme(ctx, &deref->offset.node->loc, "Dereference with non-constant offset of type %s.", - hlsl_node_type_to_string(deref->offset.node->type)); - - return 0; -} - -struct hlsl_reg hlsl_reg_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, - const struct hlsl_type *type) -{ - const struct hlsl_ir_var *var = deref->var; - struct hlsl_reg ret = var->reg; - unsigned int offset = hlsl_offset_from_deref_safe(ctx, deref); - - ret.id += offset / 4; - - if (type_is_single_reg(var->data_type)) - { - assert(!offset); - ret.writemask = var->reg.writemask; - } - else - { - assert(type_is_single_reg(type)); - ret.writemask = ((1 << type->dimx) - 1) << (offset % 4); - } - return ret; -} - -int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, - enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out) -{ - struct hlsl_block *const body = &entry_func->body; - struct hlsl_ir_var *var; - bool progress; - - list_move_head(&body->instrs, &ctx->static_initializers); - - LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry) - { - if (var->modifiers & HLSL_STORAGE_UNIFORM) - prepend_uniform_copy(ctx, &body->instrs, var); - } - - LIST_FOR_EACH_ENTRY(var, entry_func->parameters, struct hlsl_ir_var, param_entry) - { - if (var->data_type->type == HLSL_CLASS_OBJECT || (var->modifiers & HLSL_STORAGE_UNIFORM)) - { - prepend_uniform_copy(ctx, &body->instrs, var); - } - else - { - if (var->data_type->type != HLSL_CLASS_STRUCT && !var->semantic.name) - hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, - "Parameter \"%s\" is missing a semantic.", var->name); - - if (var->modifiers & HLSL_STORAGE_IN) - prepend_input_var_copy(ctx, &body->instrs, var); - if (var->modifiers & HLSL_STORAGE_OUT) - append_output_var_copy(ctx, &body->instrs, var); - } - } - if (entry_func->return_var) - { - if (entry_func->return_var->data_type->type != HLSL_CLASS_STRUCT && !entry_func->return_var->semantic.name) - hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, - "Entry point \"%s\" is missing a return value semantic.", entry_func->func->name); - - append_output_var_copy(ctx, &body->instrs, entry_func->return_var); - } - - transform_ir(ctx, lower_broadcasts, body, NULL); - while (transform_ir(ctx, fold_redundant_casts, body, NULL)); - do - { - progress = transform_ir(ctx, split_array_copies, body, NULL); - progress |= transform_ir(ctx, split_struct_copies, body, NULL); - } - while (progress); - transform_ir(ctx, lower_narrowing_casts, body, NULL); - do - { - progress = transform_ir(ctx, hlsl_fold_constants, body, NULL); - progress |= copy_propagation_execute(ctx, body); - progress |= transform_ir(ctx, remove_trivial_swizzles, body, NULL); - } - while (progress); - - if (ctx->profile->major_version < 4) - transform_ir(ctx, lower_division, body, NULL); - - do - compute_liveness(ctx, entry_func); - while (transform_ir(ctx, dce, body, NULL)); - - compute_liveness(ctx, entry_func); - - if (TRACE_ON()) - wine_rb_for_each_entry(&ctx->functions, dump_function, ctx); - - allocate_temp_registers(ctx, entry_func); - if (ctx->profile->major_version < 4) - { - allocate_const_registers(ctx, entry_func); - } - else - { - allocate_buffers(ctx); - allocate_objects(ctx, HLSL_TYPE_TEXTURE); - } - allocate_semantic_registers(ctx); - allocate_objects(ctx, HLSL_TYPE_SAMPLER); - - if (ctx->result) - return ctx->result; - - switch (target_type) - { - case VKD3D_SHADER_TARGET_D3D_BYTECODE: - return hlsl_sm1_write(ctx, entry_func, out); - - case VKD3D_SHADER_TARGET_DXBC_TPF: - return hlsl_sm4_write(ctx, entry_func, out); - - default: - ERR("Unsupported shader target type %#x.\n", target_type); - return VKD3D_ERROR_INVALID_ARGUMENT; - } -} diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/hlsl_constant_ops.c b/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/hlsl_constant_ops.c deleted file mode 100644 index 51cee179e37cd..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/hlsl_constant_ops.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * HLSL constant value operations for constant folding - * - * Copyright 2022 Francisco Casas for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "hlsl.h" - -static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, struct hlsl_ir_constant *src) -{ - unsigned int k; - uint32_t u; - int32_t i; - double d; - float f; - bool b; - - if (dst->node.data_type->dimx != src->node.data_type->dimx - || dst->node.data_type->dimy != src->node.data_type->dimy) - { - FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, src->node.data_type), - debug_hlsl_type(ctx, dst->node.data_type)); - return false; - } - - for (k = 0; k < 4; ++k) - { - switch (src->node.data_type->base_type) - { - case HLSL_TYPE_FLOAT: - case HLSL_TYPE_HALF: - u = src->value[k].f; - i = src->value[k].f; - f = src->value[k].f; - d = src->value[k].f; - b = src->value[k].f; - break; - - case HLSL_TYPE_DOUBLE: - u = src->value[k].d; - i = src->value[k].d; - f = src->value[k].d; - d = src->value[k].d; - b = src->value[k].d; - break; - - case HLSL_TYPE_INT: - u = src->value[k].i; - i = src->value[k].i; - f = src->value[k].i; - d = src->value[k].i; - b = src->value[k].i; - break; - - case HLSL_TYPE_UINT: - u = src->value[k].u; - i = src->value[k].u; - f = src->value[k].u; - d = src->value[k].u; - b = src->value[k].u; - break; - - case HLSL_TYPE_BOOL: - u = src->value[k].b; - i = src->value[k].b; - f = src->value[k].b; - d = src->value[k].b; - b = src->value[k].b; - break; - - default: - FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, src->node.data_type), - debug_hlsl_type(ctx, dst->node.data_type)); - return false; - } - - switch (dst->node.data_type->base_type) - { - case HLSL_TYPE_FLOAT: - case HLSL_TYPE_HALF: - dst->value[k].f = f; - break; - - case HLSL_TYPE_DOUBLE: - dst->value[k].d = d; - break; - - case HLSL_TYPE_INT: - dst->value[k].i = i; - break; - - case HLSL_TYPE_UINT: - dst->value[k].u = u; - break; - - case HLSL_TYPE_BOOL: - dst->value[k].b = b; - break; - - default: - FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, src->node.data_type), - debug_hlsl_type(ctx, dst->node.data_type)); - return false; - } - } - return true; -} - -static bool fold_neg(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, struct hlsl_ir_constant *src) -{ - enum hlsl_base_type type = dst->node.data_type->base_type; - unsigned int k; - - assert(type == src->node.data_type->base_type); - - for (k = 0; k < 4; ++k) - { - switch (type) - { - case HLSL_TYPE_FLOAT: - case HLSL_TYPE_HALF: - dst->value[k].f = -src->value[k].f; - break; - - case HLSL_TYPE_DOUBLE: - dst->value[k].d = -src->value[k].d; - break; - - case HLSL_TYPE_INT: - case HLSL_TYPE_UINT: - dst->value[k].u = -src->value[k].u; - break; - - default: - FIXME("Fold negation for type %s.\n", debug_hlsl_type(ctx, dst->node.data_type)); - return false; - } - } - return true; -} - -static bool fold_add(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, struct hlsl_ir_constant *src1, - struct hlsl_ir_constant *src2) -{ - enum hlsl_base_type type = dst->node.data_type->base_type; - unsigned int k; - - assert(type == src1->node.data_type->base_type); - assert(type == src2->node.data_type->base_type); - - for (k = 0; k < 4; ++k) - { - switch (type) - { - case HLSL_TYPE_FLOAT: - case HLSL_TYPE_HALF: - dst->value[k].f = src1->value[k].f + src2->value[k].f; - break; - - case HLSL_TYPE_DOUBLE: - dst->value[k].d = src1->value[k].d + src2->value[k].d; - break; - - /* Handling HLSL_TYPE_INT through the unsigned field to avoid - * undefined behavior with signed integers in C. */ - case HLSL_TYPE_INT: - case HLSL_TYPE_UINT: - dst->value[k].u = src1->value[k].u + src2->value[k].u; - break; - - default: - FIXME("Fold addition for type %s.\n", debug_hlsl_type(ctx, dst->node.data_type)); - return false; - } - } - return true; -} - -static bool fold_mul(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, - struct hlsl_ir_constant *src1, struct hlsl_ir_constant *src2) -{ - enum hlsl_base_type type = dst->node.data_type->base_type; - - assert(type == src1->node.data_type->base_type); - assert(type == src2->node.data_type->base_type); - - for (int k = 0; k < 4; ++k) - { - switch (type) - { - case HLSL_TYPE_FLOAT: - case HLSL_TYPE_HALF: - dst->value[k].f = src1->value[k].f * src2->value[k].f; - break; - - case HLSL_TYPE_DOUBLE: - dst->value[k].d = src1->value[k].d * src2->value[k].d; - break; - - case HLSL_TYPE_INT: - case HLSL_TYPE_UINT: - dst->value[k].u = src1->value[k].u * src2->value[k].u; - break; - - default: - FIXME("Fold multiplication for type %s.\n", debug_hlsl_type(ctx, dst->node.data_type)); - return false; - } - } - return true; -} - -bool hlsl_fold_constants(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -{ - struct hlsl_ir_constant *arg1, *arg2 = NULL, *res; - struct hlsl_ir_expr *expr; - unsigned int i; - bool success; - - if (instr->type != HLSL_IR_EXPR) - return false; - expr = hlsl_ir_expr(instr); - - for (i = 0; i < ARRAY_SIZE(expr->operands); ++i) - { - if (expr->operands[i].node && expr->operands[i].node->type != HLSL_IR_CONSTANT) - return false; - } - arg1 = hlsl_ir_constant(expr->operands[0].node); - if (expr->operands[1].node) - arg2 = hlsl_ir_constant(expr->operands[1].node); - - if (!(res = hlsl_alloc(ctx, sizeof(*res)))) - return false; - init_node(&res->node, HLSL_IR_CONSTANT, instr->data_type, instr->loc); - - switch (expr->op) - { - case HLSL_OP1_CAST: - success = fold_cast(ctx, res, arg1); - break; - - case HLSL_OP1_NEG: - success = fold_neg(ctx, res, arg1); - break; - - case HLSL_OP2_ADD: - success = fold_add(ctx, res, arg1, arg2); - break; - - case HLSL_OP2_MUL: - success = fold_mul(ctx, res, arg1, arg2); - break; - - default: - FIXME("Fold \"%s\" expression.\n", debug_hlsl_expr_op(expr->op)); - success = false; - break; - } - - if (success) - { - list_add_before(&expr->node.entry, &res->node.entry); - hlsl_replace_node(&expr->node, &res->node); - } - else - { - vkd3d_free(res); - } - return success; -} diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/libvkd3d-shader.pc.in b/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/libvkd3d-shader.pc.in deleted file mode 100644 index b93e6ed9c6d69..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/libvkd3d-shader.pc.in +++ /dev/null @@ -1,10 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: vkd3d-shader -Description: The vkd3d Shader Translation Library -Version: @PACKAGE_VERSION@ -Cflags: -I${includedir}/vkd3d -Libs: -L${libdir} -lvkd3d-shader diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/spirv.h b/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/spirv.h deleted file mode 100644 index 098c03a0424e8..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/spirv.h +++ /dev/null @@ -1,992 +0,0 @@ -/* -** Copyright (c) 2014-2018 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and/or associated documentation files (the "Materials"), -** to deal in the Materials without restriction, including without limitation -** the rights to use, copy, modify, merge, publish, distribute, sublicense, -** and/or sell copies of the Materials, and to permit persons to whom the -** Materials are furnished to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in -** all copies or substantial portions of the Materials. -** -** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS -** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND -** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS -** IN THE MATERIALS. -*/ - -/* -** This header is automatically generated by the same tool that creates -** the Binary Section of the SPIR-V specification. -*/ - -/* -** Enumeration tokens for SPIR-V, in various styles: -** C, C++, C++11, JSON, Lua, Python -** -** - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL -** - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL -** - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL -** - Lua will use tables, e.g.: spv.SourceLanguage.GLSL -** - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] -** -** Some tokens act like mask values, which can be OR'd together, -** while others are mutually exclusive. The mask-like ones have -** "Mask" in their name, and a parallel enum that has the shift -** amount (1 << x) for each corresponding enumerant. -*/ - -#ifndef spirv_H -#define spirv_H - -typedef unsigned int SpvId; - -#define SPV_VERSION 0x10000 -#define SPV_REVISION 12 - -static const unsigned int SpvMagicNumber = 0x07230203; -static const unsigned int SpvVersion = 0x00010000; -static const unsigned int SpvRevision = 12; -static const unsigned int SpvOpCodeMask = 0xffff; -static const unsigned int SpvWordCountShift = 16; - -typedef enum SpvSourceLanguage_ { - SpvSourceLanguageUnknown = 0, - SpvSourceLanguageESSL = 1, - SpvSourceLanguageGLSL = 2, - SpvSourceLanguageOpenCL_C = 3, - SpvSourceLanguageOpenCL_CPP = 4, - SpvSourceLanguageHLSL = 5, - SpvSourceLanguageMax = 0x7fffffff, -} SpvSourceLanguage; - -typedef enum SpvExecutionModel_ { - SpvExecutionModelVertex = 0, - SpvExecutionModelTessellationControl = 1, - SpvExecutionModelTessellationEvaluation = 2, - SpvExecutionModelGeometry = 3, - SpvExecutionModelFragment = 4, - SpvExecutionModelGLCompute = 5, - SpvExecutionModelKernel = 6, - SpvExecutionModelMax = 0x7fffffff, -} SpvExecutionModel; - -typedef enum SpvAddressingModel_ { - SpvAddressingModelLogical = 0, - SpvAddressingModelPhysical32 = 1, - SpvAddressingModelPhysical64 = 2, - SpvAddressingModelMax = 0x7fffffff, -} SpvAddressingModel; - -typedef enum SpvMemoryModel_ { - SpvMemoryModelSimple = 0, - SpvMemoryModelGLSL450 = 1, - SpvMemoryModelOpenCL = 2, - SpvMemoryModelMax = 0x7fffffff, -} SpvMemoryModel; - -typedef enum SpvExecutionMode_ { - SpvExecutionModeInvocations = 0, - SpvExecutionModeSpacingEqual = 1, - SpvExecutionModeSpacingFractionalEven = 2, - SpvExecutionModeSpacingFractionalOdd = 3, - SpvExecutionModeVertexOrderCw = 4, - SpvExecutionModeVertexOrderCcw = 5, - SpvExecutionModePixelCenterInteger = 6, - SpvExecutionModeOriginUpperLeft = 7, - SpvExecutionModeOriginLowerLeft = 8, - SpvExecutionModeEarlyFragmentTests = 9, - SpvExecutionModePointMode = 10, - SpvExecutionModeXfb = 11, - SpvExecutionModeDepthReplacing = 12, - SpvExecutionModeDepthGreater = 14, - SpvExecutionModeDepthLess = 15, - SpvExecutionModeDepthUnchanged = 16, - SpvExecutionModeLocalSize = 17, - SpvExecutionModeLocalSizeHint = 18, - SpvExecutionModeInputPoints = 19, - SpvExecutionModeInputLines = 20, - SpvExecutionModeInputLinesAdjacency = 21, - SpvExecutionModeTriangles = 22, - SpvExecutionModeInputTrianglesAdjacency = 23, - SpvExecutionModeQuads = 24, - SpvExecutionModeIsolines = 25, - SpvExecutionModeOutputVertices = 26, - SpvExecutionModeOutputPoints = 27, - SpvExecutionModeOutputLineStrip = 28, - SpvExecutionModeOutputTriangleStrip = 29, - SpvExecutionModeVecTypeHint = 30, - SpvExecutionModeContractionOff = 31, - SpvExecutionModePostDepthCoverage = 4446, - SpvExecutionModeStencilRefReplacingEXT = 5027, - SpvExecutionModeMax = 0x7fffffff, -} SpvExecutionMode; - -typedef enum SpvStorageClass_ { - SpvStorageClassUniformConstant = 0, - SpvStorageClassInput = 1, - SpvStorageClassUniform = 2, - SpvStorageClassOutput = 3, - SpvStorageClassWorkgroup = 4, - SpvStorageClassCrossWorkgroup = 5, - SpvStorageClassPrivate = 6, - SpvStorageClassFunction = 7, - SpvStorageClassGeneric = 8, - SpvStorageClassPushConstant = 9, - SpvStorageClassAtomicCounter = 10, - SpvStorageClassImage = 11, - SpvStorageClassStorageBuffer = 12, - SpvStorageClassMax = 0x7fffffff, -} SpvStorageClass; - -typedef enum SpvDim_ { - SpvDim1D = 0, - SpvDim2D = 1, - SpvDim3D = 2, - SpvDimCube = 3, - SpvDimRect = 4, - SpvDimBuffer = 5, - SpvDimSubpassData = 6, - SpvDimMax = 0x7fffffff, -} SpvDim; - -typedef enum SpvSamplerAddressingMode_ { - SpvSamplerAddressingModeNone = 0, - SpvSamplerAddressingModeClampToEdge = 1, - SpvSamplerAddressingModeClamp = 2, - SpvSamplerAddressingModeRepeat = 3, - SpvSamplerAddressingModeRepeatMirrored = 4, - SpvSamplerAddressingModeMax = 0x7fffffff, -} SpvSamplerAddressingMode; - -typedef enum SpvSamplerFilterMode_ { - SpvSamplerFilterModeNearest = 0, - SpvSamplerFilterModeLinear = 1, - SpvSamplerFilterModeMax = 0x7fffffff, -} SpvSamplerFilterMode; - -typedef enum SpvImageFormat_ { - SpvImageFormatUnknown = 0, - SpvImageFormatRgba32f = 1, - SpvImageFormatRgba16f = 2, - SpvImageFormatR32f = 3, - SpvImageFormatRgba8 = 4, - SpvImageFormatRgba8Snorm = 5, - SpvImageFormatRg32f = 6, - SpvImageFormatRg16f = 7, - SpvImageFormatR11fG11fB10f = 8, - SpvImageFormatR16f = 9, - SpvImageFormatRgba16 = 10, - SpvImageFormatRgb10A2 = 11, - SpvImageFormatRg16 = 12, - SpvImageFormatRg8 = 13, - SpvImageFormatR16 = 14, - SpvImageFormatR8 = 15, - SpvImageFormatRgba16Snorm = 16, - SpvImageFormatRg16Snorm = 17, - SpvImageFormatRg8Snorm = 18, - SpvImageFormatR16Snorm = 19, - SpvImageFormatR8Snorm = 20, - SpvImageFormatRgba32i = 21, - SpvImageFormatRgba16i = 22, - SpvImageFormatRgba8i = 23, - SpvImageFormatR32i = 24, - SpvImageFormatRg32i = 25, - SpvImageFormatRg16i = 26, - SpvImageFormatRg8i = 27, - SpvImageFormatR16i = 28, - SpvImageFormatR8i = 29, - SpvImageFormatRgba32ui = 30, - SpvImageFormatRgba16ui = 31, - SpvImageFormatRgba8ui = 32, - SpvImageFormatR32ui = 33, - SpvImageFormatRgb10a2ui = 34, - SpvImageFormatRg32ui = 35, - SpvImageFormatRg16ui = 36, - SpvImageFormatRg8ui = 37, - SpvImageFormatR16ui = 38, - SpvImageFormatR8ui = 39, - SpvImageFormatMax = 0x7fffffff, -} SpvImageFormat; - -typedef enum SpvImageChannelOrder_ { - SpvImageChannelOrderR = 0, - SpvImageChannelOrderA = 1, - SpvImageChannelOrderRG = 2, - SpvImageChannelOrderRA = 3, - SpvImageChannelOrderRGB = 4, - SpvImageChannelOrderRGBA = 5, - SpvImageChannelOrderBGRA = 6, - SpvImageChannelOrderARGB = 7, - SpvImageChannelOrderIntensity = 8, - SpvImageChannelOrderLuminance = 9, - SpvImageChannelOrderRx = 10, - SpvImageChannelOrderRGx = 11, - SpvImageChannelOrderRGBx = 12, - SpvImageChannelOrderDepth = 13, - SpvImageChannelOrderDepthStencil = 14, - SpvImageChannelOrdersRGB = 15, - SpvImageChannelOrdersRGBx = 16, - SpvImageChannelOrdersRGBA = 17, - SpvImageChannelOrdersBGRA = 18, - SpvImageChannelOrderABGR = 19, - SpvImageChannelOrderMax = 0x7fffffff, -} SpvImageChannelOrder; - -typedef enum SpvImageChannelDataType_ { - SpvImageChannelDataTypeSnormInt8 = 0, - SpvImageChannelDataTypeSnormInt16 = 1, - SpvImageChannelDataTypeUnormInt8 = 2, - SpvImageChannelDataTypeUnormInt16 = 3, - SpvImageChannelDataTypeUnormShort565 = 4, - SpvImageChannelDataTypeUnormShort555 = 5, - SpvImageChannelDataTypeUnormInt101010 = 6, - SpvImageChannelDataTypeSignedInt8 = 7, - SpvImageChannelDataTypeSignedInt16 = 8, - SpvImageChannelDataTypeSignedInt32 = 9, - SpvImageChannelDataTypeUnsignedInt8 = 10, - SpvImageChannelDataTypeUnsignedInt16 = 11, - SpvImageChannelDataTypeUnsignedInt32 = 12, - SpvImageChannelDataTypeHalfFloat = 13, - SpvImageChannelDataTypeFloat = 14, - SpvImageChannelDataTypeUnormInt24 = 15, - SpvImageChannelDataTypeUnormInt101010_2 = 16, - SpvImageChannelDataTypeMax = 0x7fffffff, -} SpvImageChannelDataType; - -typedef enum SpvImageOperandsShift_ { - SpvImageOperandsBiasShift = 0, - SpvImageOperandsLodShift = 1, - SpvImageOperandsGradShift = 2, - SpvImageOperandsConstOffsetShift = 3, - SpvImageOperandsOffsetShift = 4, - SpvImageOperandsConstOffsetsShift = 5, - SpvImageOperandsSampleShift = 6, - SpvImageOperandsMinLodShift = 7, - SpvImageOperandsMax = 0x7fffffff, -} SpvImageOperandsShift; - -typedef enum SpvImageOperandsMask_ { - SpvImageOperandsMaskNone = 0, - SpvImageOperandsBiasMask = 0x00000001, - SpvImageOperandsLodMask = 0x00000002, - SpvImageOperandsGradMask = 0x00000004, - SpvImageOperandsConstOffsetMask = 0x00000008, - SpvImageOperandsOffsetMask = 0x00000010, - SpvImageOperandsConstOffsetsMask = 0x00000020, - SpvImageOperandsSampleMask = 0x00000040, - SpvImageOperandsMinLodMask = 0x00000080, -} SpvImageOperandsMask; - -typedef enum SpvFPFastMathModeShift_ { - SpvFPFastMathModeNotNaNShift = 0, - SpvFPFastMathModeNotInfShift = 1, - SpvFPFastMathModeNSZShift = 2, - SpvFPFastMathModeAllowRecipShift = 3, - SpvFPFastMathModeFastShift = 4, - SpvFPFastMathModeMax = 0x7fffffff, -} SpvFPFastMathModeShift; - -typedef enum SpvFPFastMathModeMask_ { - SpvFPFastMathModeMaskNone = 0, - SpvFPFastMathModeNotNaNMask = 0x00000001, - SpvFPFastMathModeNotInfMask = 0x00000002, - SpvFPFastMathModeNSZMask = 0x00000004, - SpvFPFastMathModeAllowRecipMask = 0x00000008, - SpvFPFastMathModeFastMask = 0x00000010, -} SpvFPFastMathModeMask; - -typedef enum SpvFPRoundingMode_ { - SpvFPRoundingModeRTE = 0, - SpvFPRoundingModeRTZ = 1, - SpvFPRoundingModeRTP = 2, - SpvFPRoundingModeRTN = 3, - SpvFPRoundingModeMax = 0x7fffffff, -} SpvFPRoundingMode; - -typedef enum SpvLinkageType_ { - SpvLinkageTypeExport = 0, - SpvLinkageTypeImport = 1, - SpvLinkageTypeMax = 0x7fffffff, -} SpvLinkageType; - -typedef enum SpvAccessQualifier_ { - SpvAccessQualifierReadOnly = 0, - SpvAccessQualifierWriteOnly = 1, - SpvAccessQualifierReadWrite = 2, - SpvAccessQualifierMax = 0x7fffffff, -} SpvAccessQualifier; - -typedef enum SpvFunctionParameterAttribute_ { - SpvFunctionParameterAttributeZext = 0, - SpvFunctionParameterAttributeSext = 1, - SpvFunctionParameterAttributeByVal = 2, - SpvFunctionParameterAttributeSret = 3, - SpvFunctionParameterAttributeNoAlias = 4, - SpvFunctionParameterAttributeNoCapture = 5, - SpvFunctionParameterAttributeNoWrite = 6, - SpvFunctionParameterAttributeNoReadWrite = 7, - SpvFunctionParameterAttributeMax = 0x7fffffff, -} SpvFunctionParameterAttribute; - -typedef enum SpvDecoration_ { - SpvDecorationRelaxedPrecision = 0, - SpvDecorationSpecId = 1, - SpvDecorationBlock = 2, - SpvDecorationBufferBlock = 3, - SpvDecorationRowMajor = 4, - SpvDecorationColMajor = 5, - SpvDecorationArrayStride = 6, - SpvDecorationMatrixStride = 7, - SpvDecorationGLSLShared = 8, - SpvDecorationGLSLPacked = 9, - SpvDecorationCPacked = 10, - SpvDecorationBuiltIn = 11, - SpvDecorationNoPerspective = 13, - SpvDecorationFlat = 14, - SpvDecorationPatch = 15, - SpvDecorationCentroid = 16, - SpvDecorationSample = 17, - SpvDecorationInvariant = 18, - SpvDecorationRestrict = 19, - SpvDecorationAliased = 20, - SpvDecorationVolatile = 21, - SpvDecorationConstant = 22, - SpvDecorationCoherent = 23, - SpvDecorationNonWritable = 24, - SpvDecorationNonReadable = 25, - SpvDecorationUniform = 26, - SpvDecorationSaturatedConversion = 28, - SpvDecorationStream = 29, - SpvDecorationLocation = 30, - SpvDecorationComponent = 31, - SpvDecorationIndex = 32, - SpvDecorationBinding = 33, - SpvDecorationDescriptorSet = 34, - SpvDecorationOffset = 35, - SpvDecorationXfbBuffer = 36, - SpvDecorationXfbStride = 37, - SpvDecorationFuncParamAttr = 38, - SpvDecorationFPRoundingMode = 39, - SpvDecorationFPFastMathMode = 40, - SpvDecorationLinkageAttributes = 41, - SpvDecorationNoContraction = 42, - SpvDecorationInputAttachmentIndex = 43, - SpvDecorationAlignment = 44, - SpvDecorationExplicitInterpAMD = 4999, - SpvDecorationOverrideCoverageNV = 5248, - SpvDecorationPassthroughNV = 5250, - SpvDecorationViewportRelativeNV = 5252, - SpvDecorationSecondaryViewportRelativeNV = 5256, - SpvDecorationHlslCounterBufferGOOGLE = 5634, - SpvDecorationHlslSemanticGOOGLE = 5635, - SpvDecorationMax = 0x7fffffff, -} SpvDecoration; - -typedef enum SpvBuiltIn_ { - SpvBuiltInPosition = 0, - SpvBuiltInPointSize = 1, - SpvBuiltInClipDistance = 3, - SpvBuiltInCullDistance = 4, - SpvBuiltInVertexId = 5, - SpvBuiltInInstanceId = 6, - SpvBuiltInPrimitiveId = 7, - SpvBuiltInInvocationId = 8, - SpvBuiltInLayer = 9, - SpvBuiltInViewportIndex = 10, - SpvBuiltInTessLevelOuter = 11, - SpvBuiltInTessLevelInner = 12, - SpvBuiltInTessCoord = 13, - SpvBuiltInPatchVertices = 14, - SpvBuiltInFragCoord = 15, - SpvBuiltInPointCoord = 16, - SpvBuiltInFrontFacing = 17, - SpvBuiltInSampleId = 18, - SpvBuiltInSamplePosition = 19, - SpvBuiltInSampleMask = 20, - SpvBuiltInFragDepth = 22, - SpvBuiltInHelperInvocation = 23, - SpvBuiltInNumWorkgroups = 24, - SpvBuiltInWorkgroupSize = 25, - SpvBuiltInWorkgroupId = 26, - SpvBuiltInLocalInvocationId = 27, - SpvBuiltInGlobalInvocationId = 28, - SpvBuiltInLocalInvocationIndex = 29, - SpvBuiltInWorkDim = 30, - SpvBuiltInGlobalSize = 31, - SpvBuiltInEnqueuedWorkgroupSize = 32, - SpvBuiltInGlobalOffset = 33, - SpvBuiltInGlobalLinearId = 34, - SpvBuiltInSubgroupSize = 36, - SpvBuiltInSubgroupMaxSize = 37, - SpvBuiltInNumSubgroups = 38, - SpvBuiltInNumEnqueuedSubgroups = 39, - SpvBuiltInSubgroupId = 40, - SpvBuiltInSubgroupLocalInvocationId = 41, - SpvBuiltInVertexIndex = 42, - SpvBuiltInInstanceIndex = 43, - SpvBuiltInSubgroupEqMaskKHR = 4416, - SpvBuiltInSubgroupGeMaskKHR = 4417, - SpvBuiltInSubgroupGtMaskKHR = 4418, - SpvBuiltInSubgroupLeMaskKHR = 4419, - SpvBuiltInSubgroupLtMaskKHR = 4420, - SpvBuiltInBaseVertex = 4424, - SpvBuiltInBaseInstance = 4425, - SpvBuiltInDrawIndex = 4426, - SpvBuiltInDeviceIndex = 4438, - SpvBuiltInViewIndex = 4440, - SpvBuiltInBaryCoordNoPerspAMD = 4992, - SpvBuiltInBaryCoordNoPerspCentroidAMD = 4993, - SpvBuiltInBaryCoordNoPerspSampleAMD = 4994, - SpvBuiltInBaryCoordSmoothAMD = 4995, - SpvBuiltInBaryCoordSmoothCentroidAMD = 4996, - SpvBuiltInBaryCoordSmoothSampleAMD = 4997, - SpvBuiltInBaryCoordPullModelAMD = 4998, - SpvBuiltInFragStencilRefEXT = 5014, - SpvBuiltInViewportMaskNV = 5253, - SpvBuiltInSecondaryPositionNV = 5257, - SpvBuiltInSecondaryViewportMaskNV = 5258, - SpvBuiltInPositionPerViewNV = 5261, - SpvBuiltInViewportMaskPerViewNV = 5262, - SpvBuiltInMax = 0x7fffffff, -} SpvBuiltIn; - -typedef enum SpvSelectionControlShift_ { - SpvSelectionControlFlattenShift = 0, - SpvSelectionControlDontFlattenShift = 1, - SpvSelectionControlMax = 0x7fffffff, -} SpvSelectionControlShift; - -typedef enum SpvSelectionControlMask_ { - SpvSelectionControlMaskNone = 0, - SpvSelectionControlFlattenMask = 0x00000001, - SpvSelectionControlDontFlattenMask = 0x00000002, -} SpvSelectionControlMask; - -typedef enum SpvLoopControlShift_ { - SpvLoopControlUnrollShift = 0, - SpvLoopControlDontUnrollShift = 1, - SpvLoopControlMax = 0x7fffffff, -} SpvLoopControlShift; - -typedef enum SpvLoopControlMask_ { - SpvLoopControlMaskNone = 0, - SpvLoopControlUnrollMask = 0x00000001, - SpvLoopControlDontUnrollMask = 0x00000002, -} SpvLoopControlMask; - -typedef enum SpvFunctionControlShift_ { - SpvFunctionControlInlineShift = 0, - SpvFunctionControlDontInlineShift = 1, - SpvFunctionControlPureShift = 2, - SpvFunctionControlConstShift = 3, - SpvFunctionControlMax = 0x7fffffff, -} SpvFunctionControlShift; - -typedef enum SpvFunctionControlMask_ { - SpvFunctionControlMaskNone = 0, - SpvFunctionControlInlineMask = 0x00000001, - SpvFunctionControlDontInlineMask = 0x00000002, - SpvFunctionControlPureMask = 0x00000004, - SpvFunctionControlConstMask = 0x00000008, -} SpvFunctionControlMask; - -typedef enum SpvMemorySemanticsShift_ { - SpvMemorySemanticsAcquireShift = 1, - SpvMemorySemanticsReleaseShift = 2, - SpvMemorySemanticsAcquireReleaseShift = 3, - SpvMemorySemanticsSequentiallyConsistentShift = 4, - SpvMemorySemanticsUniformMemoryShift = 6, - SpvMemorySemanticsSubgroupMemoryShift = 7, - SpvMemorySemanticsWorkgroupMemoryShift = 8, - SpvMemorySemanticsCrossWorkgroupMemoryShift = 9, - SpvMemorySemanticsAtomicCounterMemoryShift = 10, - SpvMemorySemanticsImageMemoryShift = 11, - SpvMemorySemanticsMax = 0x7fffffff, -} SpvMemorySemanticsShift; - -typedef enum SpvMemorySemanticsMask_ { - SpvMemorySemanticsMaskNone = 0, - SpvMemorySemanticsAcquireMask = 0x00000002, - SpvMemorySemanticsReleaseMask = 0x00000004, - SpvMemorySemanticsAcquireReleaseMask = 0x00000008, - SpvMemorySemanticsSequentiallyConsistentMask = 0x00000010, - SpvMemorySemanticsUniformMemoryMask = 0x00000040, - SpvMemorySemanticsSubgroupMemoryMask = 0x00000080, - SpvMemorySemanticsWorkgroupMemoryMask = 0x00000100, - SpvMemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, - SpvMemorySemanticsAtomicCounterMemoryMask = 0x00000400, - SpvMemorySemanticsImageMemoryMask = 0x00000800, -} SpvMemorySemanticsMask; - -typedef enum SpvMemoryAccessShift_ { - SpvMemoryAccessVolatileShift = 0, - SpvMemoryAccessAlignedShift = 1, - SpvMemoryAccessNontemporalShift = 2, - SpvMemoryAccessMax = 0x7fffffff, -} SpvMemoryAccessShift; - -typedef enum SpvMemoryAccessMask_ { - SpvMemoryAccessMaskNone = 0, - SpvMemoryAccessVolatileMask = 0x00000001, - SpvMemoryAccessAlignedMask = 0x00000002, - SpvMemoryAccessNontemporalMask = 0x00000004, -} SpvMemoryAccessMask; - -typedef enum SpvScope_ { - SpvScopeCrossDevice = 0, - SpvScopeDevice = 1, - SpvScopeWorkgroup = 2, - SpvScopeSubgroup = 3, - SpvScopeInvocation = 4, - SpvScopeMax = 0x7fffffff, -} SpvScope; - -typedef enum SpvGroupOperation_ { - SpvGroupOperationReduce = 0, - SpvGroupOperationInclusiveScan = 1, - SpvGroupOperationExclusiveScan = 2, - SpvGroupOperationMax = 0x7fffffff, -} SpvGroupOperation; - -typedef enum SpvKernelEnqueueFlags_ { - SpvKernelEnqueueFlagsNoWait = 0, - SpvKernelEnqueueFlagsWaitKernel = 1, - SpvKernelEnqueueFlagsWaitWorkGroup = 2, - SpvKernelEnqueueFlagsMax = 0x7fffffff, -} SpvKernelEnqueueFlags; - -typedef enum SpvKernelProfilingInfoShift_ { - SpvKernelProfilingInfoCmdExecTimeShift = 0, - SpvKernelProfilingInfoMax = 0x7fffffff, -} SpvKernelProfilingInfoShift; - -typedef enum SpvKernelProfilingInfoMask_ { - SpvKernelProfilingInfoMaskNone = 0, - SpvKernelProfilingInfoCmdExecTimeMask = 0x00000001, -} SpvKernelProfilingInfoMask; - -typedef enum SpvCapability_ { - SpvCapabilityMatrix = 0, - SpvCapabilityShader = 1, - SpvCapabilityGeometry = 2, - SpvCapabilityTessellation = 3, - SpvCapabilityAddresses = 4, - SpvCapabilityLinkage = 5, - SpvCapabilityKernel = 6, - SpvCapabilityVector16 = 7, - SpvCapabilityFloat16Buffer = 8, - SpvCapabilityFloat16 = 9, - SpvCapabilityFloat64 = 10, - SpvCapabilityInt64 = 11, - SpvCapabilityInt64Atomics = 12, - SpvCapabilityImageBasic = 13, - SpvCapabilityImageReadWrite = 14, - SpvCapabilityImageMipmap = 15, - SpvCapabilityPipes = 17, - SpvCapabilityGroups = 18, - SpvCapabilityDeviceEnqueue = 19, - SpvCapabilityLiteralSampler = 20, - SpvCapabilityAtomicStorage = 21, - SpvCapabilityInt16 = 22, - SpvCapabilityTessellationPointSize = 23, - SpvCapabilityGeometryPointSize = 24, - SpvCapabilityImageGatherExtended = 25, - SpvCapabilityStorageImageMultisample = 27, - SpvCapabilityUniformBufferArrayDynamicIndexing = 28, - SpvCapabilitySampledImageArrayDynamicIndexing = 29, - SpvCapabilityStorageBufferArrayDynamicIndexing = 30, - SpvCapabilityStorageImageArrayDynamicIndexing = 31, - SpvCapabilityClipDistance = 32, - SpvCapabilityCullDistance = 33, - SpvCapabilityImageCubeArray = 34, - SpvCapabilitySampleRateShading = 35, - SpvCapabilityImageRect = 36, - SpvCapabilitySampledRect = 37, - SpvCapabilityGenericPointer = 38, - SpvCapabilityInt8 = 39, - SpvCapabilityInputAttachment = 40, - SpvCapabilitySparseResidency = 41, - SpvCapabilityMinLod = 42, - SpvCapabilitySampled1D = 43, - SpvCapabilityImage1D = 44, - SpvCapabilitySampledCubeArray = 45, - SpvCapabilitySampledBuffer = 46, - SpvCapabilityImageBuffer = 47, - SpvCapabilityImageMSArray = 48, - SpvCapabilityStorageImageExtendedFormats = 49, - SpvCapabilityImageQuery = 50, - SpvCapabilityDerivativeControl = 51, - SpvCapabilityInterpolationFunction = 52, - SpvCapabilityTransformFeedback = 53, - SpvCapabilityGeometryStreams = 54, - SpvCapabilityStorageImageReadWithoutFormat = 55, - SpvCapabilityStorageImageWriteWithoutFormat = 56, - SpvCapabilityMultiViewport = 57, - SpvCapabilitySubgroupBallotKHR = 4423, - SpvCapabilityDrawParameters = 4427, - SpvCapabilitySubgroupVoteKHR = 4431, - SpvCapabilityStorageBuffer16BitAccess = 4433, - SpvCapabilityStorageUniformBufferBlock16 = 4433, - SpvCapabilityStorageUniform16 = 4434, - SpvCapabilityUniformAndStorageBuffer16BitAccess = 4434, - SpvCapabilityStoragePushConstant16 = 4435, - SpvCapabilityStorageInputOutput16 = 4436, - SpvCapabilityDeviceGroup = 4437, - SpvCapabilityMultiView = 4439, - SpvCapabilityVariablePointersStorageBuffer = 4441, - SpvCapabilityVariablePointers = 4442, - SpvCapabilityAtomicStorageOps = 4445, - SpvCapabilitySampleMaskPostDepthCoverage = 4447, - SpvCapabilityImageGatherBiasLodAMD = 5009, - SpvCapabilityFragmentMaskAMD = 5010, - SpvCapabilityStencilExportEXT = 5013, - SpvCapabilityImageReadWriteLodAMD = 5015, - SpvCapabilitySampleMaskOverrideCoverageNV = 5249, - SpvCapabilityGeometryShaderPassthroughNV = 5251, - SpvCapabilityShaderViewportIndexLayerEXT = 5254, - SpvCapabilityShaderViewportIndexLayerNV = 5254, - SpvCapabilityShaderViewportMaskNV = 5255, - SpvCapabilityShaderStereoViewNV = 5259, - SpvCapabilityPerViewAttributesNV = 5260, - SpvCapabilitySubgroupShuffleINTEL = 5568, - SpvCapabilitySubgroupBufferBlockIOINTEL = 5569, - SpvCapabilitySubgroupImageBlockIOINTEL = 5570, - SpvCapabilityMax = 0x7fffffff, -} SpvCapability; - -typedef enum SpvOp_ { - SpvOpNop = 0, - SpvOpUndef = 1, - SpvOpSourceContinued = 2, - SpvOpSource = 3, - SpvOpSourceExtension = 4, - SpvOpName = 5, - SpvOpMemberName = 6, - SpvOpString = 7, - SpvOpLine = 8, - SpvOpExtension = 10, - SpvOpExtInstImport = 11, - SpvOpExtInst = 12, - SpvOpMemoryModel = 14, - SpvOpEntryPoint = 15, - SpvOpExecutionMode = 16, - SpvOpCapability = 17, - SpvOpTypeVoid = 19, - SpvOpTypeBool = 20, - SpvOpTypeInt = 21, - SpvOpTypeFloat = 22, - SpvOpTypeVector = 23, - SpvOpTypeMatrix = 24, - SpvOpTypeImage = 25, - SpvOpTypeSampler = 26, - SpvOpTypeSampledImage = 27, - SpvOpTypeArray = 28, - SpvOpTypeRuntimeArray = 29, - SpvOpTypeStruct = 30, - SpvOpTypeOpaque = 31, - SpvOpTypePointer = 32, - SpvOpTypeFunction = 33, - SpvOpTypeEvent = 34, - SpvOpTypeDeviceEvent = 35, - SpvOpTypeReserveId = 36, - SpvOpTypeQueue = 37, - SpvOpTypePipe = 38, - SpvOpTypeForwardPointer = 39, - SpvOpConstantTrue = 41, - SpvOpConstantFalse = 42, - SpvOpConstant = 43, - SpvOpConstantComposite = 44, - SpvOpConstantSampler = 45, - SpvOpConstantNull = 46, - SpvOpSpecConstantTrue = 48, - SpvOpSpecConstantFalse = 49, - SpvOpSpecConstant = 50, - SpvOpSpecConstantComposite = 51, - SpvOpSpecConstantOp = 52, - SpvOpFunction = 54, - SpvOpFunctionParameter = 55, - SpvOpFunctionEnd = 56, - SpvOpFunctionCall = 57, - SpvOpVariable = 59, - SpvOpImageTexelPointer = 60, - SpvOpLoad = 61, - SpvOpStore = 62, - SpvOpCopyMemory = 63, - SpvOpCopyMemorySized = 64, - SpvOpAccessChain = 65, - SpvOpInBoundsAccessChain = 66, - SpvOpPtrAccessChain = 67, - SpvOpArrayLength = 68, - SpvOpGenericPtrMemSemantics = 69, - SpvOpInBoundsPtrAccessChain = 70, - SpvOpDecorate = 71, - SpvOpMemberDecorate = 72, - SpvOpDecorationGroup = 73, - SpvOpGroupDecorate = 74, - SpvOpGroupMemberDecorate = 75, - SpvOpVectorExtractDynamic = 77, - SpvOpVectorInsertDynamic = 78, - SpvOpVectorShuffle = 79, - SpvOpCompositeConstruct = 80, - SpvOpCompositeExtract = 81, - SpvOpCompositeInsert = 82, - SpvOpCopyObject = 83, - SpvOpTranspose = 84, - SpvOpSampledImage = 86, - SpvOpImageSampleImplicitLod = 87, - SpvOpImageSampleExplicitLod = 88, - SpvOpImageSampleDrefImplicitLod = 89, - SpvOpImageSampleDrefExplicitLod = 90, - SpvOpImageSampleProjImplicitLod = 91, - SpvOpImageSampleProjExplicitLod = 92, - SpvOpImageSampleProjDrefImplicitLod = 93, - SpvOpImageSampleProjDrefExplicitLod = 94, - SpvOpImageFetch = 95, - SpvOpImageGather = 96, - SpvOpImageDrefGather = 97, - SpvOpImageRead = 98, - SpvOpImageWrite = 99, - SpvOpImage = 100, - SpvOpImageQueryFormat = 101, - SpvOpImageQueryOrder = 102, - SpvOpImageQuerySizeLod = 103, - SpvOpImageQuerySize = 104, - SpvOpImageQueryLod = 105, - SpvOpImageQueryLevels = 106, - SpvOpImageQuerySamples = 107, - SpvOpConvertFToU = 109, - SpvOpConvertFToS = 110, - SpvOpConvertSToF = 111, - SpvOpConvertUToF = 112, - SpvOpUConvert = 113, - SpvOpSConvert = 114, - SpvOpFConvert = 115, - SpvOpQuantizeToF16 = 116, - SpvOpConvertPtrToU = 117, - SpvOpSatConvertSToU = 118, - SpvOpSatConvertUToS = 119, - SpvOpConvertUToPtr = 120, - SpvOpPtrCastToGeneric = 121, - SpvOpGenericCastToPtr = 122, - SpvOpGenericCastToPtrExplicit = 123, - SpvOpBitcast = 124, - SpvOpSNegate = 126, - SpvOpFNegate = 127, - SpvOpIAdd = 128, - SpvOpFAdd = 129, - SpvOpISub = 130, - SpvOpFSub = 131, - SpvOpIMul = 132, - SpvOpFMul = 133, - SpvOpUDiv = 134, - SpvOpSDiv = 135, - SpvOpFDiv = 136, - SpvOpUMod = 137, - SpvOpSRem = 138, - SpvOpSMod = 139, - SpvOpFRem = 140, - SpvOpFMod = 141, - SpvOpVectorTimesScalar = 142, - SpvOpMatrixTimesScalar = 143, - SpvOpVectorTimesMatrix = 144, - SpvOpMatrixTimesVector = 145, - SpvOpMatrixTimesMatrix = 146, - SpvOpOuterProduct = 147, - SpvOpDot = 148, - SpvOpIAddCarry = 149, - SpvOpISubBorrow = 150, - SpvOpUMulExtended = 151, - SpvOpSMulExtended = 152, - SpvOpAny = 154, - SpvOpAll = 155, - SpvOpIsNan = 156, - SpvOpIsInf = 157, - SpvOpIsFinite = 158, - SpvOpIsNormal = 159, - SpvOpSignBitSet = 160, - SpvOpLessOrGreater = 161, - SpvOpOrdered = 162, - SpvOpUnordered = 163, - SpvOpLogicalEqual = 164, - SpvOpLogicalNotEqual = 165, - SpvOpLogicalOr = 166, - SpvOpLogicalAnd = 167, - SpvOpLogicalNot = 168, - SpvOpSelect = 169, - SpvOpIEqual = 170, - SpvOpINotEqual = 171, - SpvOpUGreaterThan = 172, - SpvOpSGreaterThan = 173, - SpvOpUGreaterThanEqual = 174, - SpvOpSGreaterThanEqual = 175, - SpvOpULessThan = 176, - SpvOpSLessThan = 177, - SpvOpULessThanEqual = 178, - SpvOpSLessThanEqual = 179, - SpvOpFOrdEqual = 180, - SpvOpFUnordEqual = 181, - SpvOpFOrdNotEqual = 182, - SpvOpFUnordNotEqual = 183, - SpvOpFOrdLessThan = 184, - SpvOpFUnordLessThan = 185, - SpvOpFOrdGreaterThan = 186, - SpvOpFUnordGreaterThan = 187, - SpvOpFOrdLessThanEqual = 188, - SpvOpFUnordLessThanEqual = 189, - SpvOpFOrdGreaterThanEqual = 190, - SpvOpFUnordGreaterThanEqual = 191, - SpvOpShiftRightLogical = 194, - SpvOpShiftRightArithmetic = 195, - SpvOpShiftLeftLogical = 196, - SpvOpBitwiseOr = 197, - SpvOpBitwiseXor = 198, - SpvOpBitwiseAnd = 199, - SpvOpNot = 200, - SpvOpBitFieldInsert = 201, - SpvOpBitFieldSExtract = 202, - SpvOpBitFieldUExtract = 203, - SpvOpBitReverse = 204, - SpvOpBitCount = 205, - SpvOpDPdx = 207, - SpvOpDPdy = 208, - SpvOpFwidth = 209, - SpvOpDPdxFine = 210, - SpvOpDPdyFine = 211, - SpvOpFwidthFine = 212, - SpvOpDPdxCoarse = 213, - SpvOpDPdyCoarse = 214, - SpvOpFwidthCoarse = 215, - SpvOpEmitVertex = 218, - SpvOpEndPrimitive = 219, - SpvOpEmitStreamVertex = 220, - SpvOpEndStreamPrimitive = 221, - SpvOpControlBarrier = 224, - SpvOpMemoryBarrier = 225, - SpvOpAtomicLoad = 227, - SpvOpAtomicStore = 228, - SpvOpAtomicExchange = 229, - SpvOpAtomicCompareExchange = 230, - SpvOpAtomicCompareExchangeWeak = 231, - SpvOpAtomicIIncrement = 232, - SpvOpAtomicIDecrement = 233, - SpvOpAtomicIAdd = 234, - SpvOpAtomicISub = 235, - SpvOpAtomicSMin = 236, - SpvOpAtomicUMin = 237, - SpvOpAtomicSMax = 238, - SpvOpAtomicUMax = 239, - SpvOpAtomicAnd = 240, - SpvOpAtomicOr = 241, - SpvOpAtomicXor = 242, - SpvOpPhi = 245, - SpvOpLoopMerge = 246, - SpvOpSelectionMerge = 247, - SpvOpLabel = 248, - SpvOpBranch = 249, - SpvOpBranchConditional = 250, - SpvOpSwitch = 251, - SpvOpKill = 252, - SpvOpReturn = 253, - SpvOpReturnValue = 254, - SpvOpUnreachable = 255, - SpvOpLifetimeStart = 256, - SpvOpLifetimeStop = 257, - SpvOpGroupAsyncCopy = 259, - SpvOpGroupWaitEvents = 260, - SpvOpGroupAll = 261, - SpvOpGroupAny = 262, - SpvOpGroupBroadcast = 263, - SpvOpGroupIAdd = 264, - SpvOpGroupFAdd = 265, - SpvOpGroupFMin = 266, - SpvOpGroupUMin = 267, - SpvOpGroupSMin = 268, - SpvOpGroupFMax = 269, - SpvOpGroupUMax = 270, - SpvOpGroupSMax = 271, - SpvOpReadPipe = 274, - SpvOpWritePipe = 275, - SpvOpReservedReadPipe = 276, - SpvOpReservedWritePipe = 277, - SpvOpReserveReadPipePackets = 278, - SpvOpReserveWritePipePackets = 279, - SpvOpCommitReadPipe = 280, - SpvOpCommitWritePipe = 281, - SpvOpIsValidReserveId = 282, - SpvOpGetNumPipePackets = 283, - SpvOpGetMaxPipePackets = 284, - SpvOpGroupReserveReadPipePackets = 285, - SpvOpGroupReserveWritePipePackets = 286, - SpvOpGroupCommitReadPipe = 287, - SpvOpGroupCommitWritePipe = 288, - SpvOpEnqueueMarker = 291, - SpvOpEnqueueKernel = 292, - SpvOpGetKernelNDrangeSubGroupCount = 293, - SpvOpGetKernelNDrangeMaxSubGroupSize = 294, - SpvOpGetKernelWorkGroupSize = 295, - SpvOpGetKernelPreferredWorkGroupSizeMultiple = 296, - SpvOpRetainEvent = 297, - SpvOpReleaseEvent = 298, - SpvOpCreateUserEvent = 299, - SpvOpIsValidEvent = 300, - SpvOpSetUserEventStatus = 301, - SpvOpCaptureEventProfilingInfo = 302, - SpvOpGetDefaultQueue = 303, - SpvOpBuildNDRange = 304, - SpvOpImageSparseSampleImplicitLod = 305, - SpvOpImageSparseSampleExplicitLod = 306, - SpvOpImageSparseSampleDrefImplicitLod = 307, - SpvOpImageSparseSampleDrefExplicitLod = 308, - SpvOpImageSparseSampleProjImplicitLod = 309, - SpvOpImageSparseSampleProjExplicitLod = 310, - SpvOpImageSparseSampleProjDrefImplicitLod = 311, - SpvOpImageSparseSampleProjDrefExplicitLod = 312, - SpvOpImageSparseFetch = 313, - SpvOpImageSparseGather = 314, - SpvOpImageSparseDrefGather = 315, - SpvOpImageSparseTexelsResident = 316, - SpvOpNoLine = 317, - SpvOpAtomicFlagTestAndSet = 318, - SpvOpAtomicFlagClear = 319, - SpvOpImageSparseRead = 320, - SpvOpDecorateId = 332, - SpvOpSubgroupBallotKHR = 4421, - SpvOpSubgroupFirstInvocationKHR = 4422, - SpvOpSubgroupAllKHR = 4428, - SpvOpSubgroupAnyKHR = 4429, - SpvOpSubgroupAllEqualKHR = 4430, - SpvOpSubgroupReadInvocationKHR = 4432, - SpvOpGroupIAddNonUniformAMD = 5000, - SpvOpGroupFAddNonUniformAMD = 5001, - SpvOpGroupFMinNonUniformAMD = 5002, - SpvOpGroupUMinNonUniformAMD = 5003, - SpvOpGroupSMinNonUniformAMD = 5004, - SpvOpGroupFMaxNonUniformAMD = 5005, - SpvOpGroupUMaxNonUniformAMD = 5006, - SpvOpGroupSMaxNonUniformAMD = 5007, - SpvOpFragmentMaskFetchAMD = 5011, - SpvOpFragmentFetchAMD = 5012, - SpvOpSubgroupShuffleINTEL = 5571, - SpvOpSubgroupShuffleDownINTEL = 5572, - SpvOpSubgroupShuffleUpINTEL = 5573, - SpvOpSubgroupShuffleXorINTEL = 5574, - SpvOpSubgroupBlockReadINTEL = 5575, - SpvOpSubgroupBlockWriteINTEL = 5576, - SpvOpSubgroupImageBlockReadINTEL = 5577, - SpvOpSubgroupImageBlockWriteINTEL = 5578, - SpvOpDecorateStringGOOGLE = 5632, - SpvOpMemberDecorateStringGOOGLE = 5633, - SpvOpMax = 0x7fffffff, -} SpvOp; - -#endif // #ifndef spirv_H \ No newline at end of file diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/vkd3d_shader.map b/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/vkd3d_shader.map deleted file mode 100644 index 2e49fe248e0c4..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/vkd3d_shader.map +++ /dev/null @@ -1,22 +0,0 @@ -VKD3D_1_0 -{ -global: - vkd3d_shader_compile; - vkd3d_shader_convert_root_signature; - vkd3d_shader_find_signature_element; - vkd3d_shader_free_messages; - vkd3d_shader_free_root_signature; - vkd3d_shader_free_scan_descriptor_info; - vkd3d_shader_free_shader_code; - vkd3d_shader_free_shader_signature; - vkd3d_shader_get_supported_source_types; - vkd3d_shader_get_supported_target_types; - vkd3d_shader_get_version; - vkd3d_shader_parse_input_signature; - vkd3d_shader_parse_root_signature; - vkd3d_shader_preprocess; - vkd3d_shader_scan; - vkd3d_shader_serialize_root_signature; - -local: *; -}; diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-utils/CMakeLists.txt b/dll/directx/wine/d3d12/vkd3d/vkd3d-utils/CMakeLists.txt deleted file mode 100644 index 66765d5768435..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-utils/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ - -include_directories("../include") -include_directories("../include/private") -add_library(vkd3d-utils vkd3d_utils_main.c) - - -add_dependencies(vkd3d-utils vkd3d_idl_headers psdk) diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-utils/libvkd3d-utils.pc.in b/dll/directx/wine/d3d12/vkd3d/vkd3d-utils/libvkd3d-utils.pc.in deleted file mode 100644 index 31d2a89c3fcb7..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-utils/libvkd3d-utils.pc.in +++ /dev/null @@ -1,10 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: vkd3d-utils -Description: The vkd3d 3D Graphics Utility Library -Version: @PACKAGE_VERSION@ -Cflags: -I${includedir}/vkd3d -Libs: -L${libdir} -lvkd3d-utils diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-utils/vkd3d_utils.map b/dll/directx/wine/d3d12/vkd3d/vkd3d-utils/vkd3d_utils.map deleted file mode 100644 index 1e46cd8659f22..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-utils/vkd3d_utils.map +++ /dev/null @@ -1,21 +0,0 @@ -VKD3D_1_0 -{ -global: - D3D12CreateDevice; - D3D12CreateDeviceVKD3D; - D3D12CreateRootSignatureDeserializer; - D3D12CreateVersionedRootSignatureDeserializer; - D3D12GetDebugInterface; - D3D12SerializeRootSignature; - D3D12SerializeVersionedRootSignature; - D3DCompile; - D3DCompile2; - D3DCreateBlob; - D3DPreprocess; - vkd3d_create_event; - vkd3d_destroy_event; - vkd3d_signal_event; - vkd3d_wait_event; - -local: *; -}; diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-utils/vkd3d_utils_main.c b/dll/directx/wine/d3d12/vkd3d/vkd3d-utils/vkd3d_utils_main.c deleted file mode 100644 index 865a552318cbc..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-utils/vkd3d_utils_main.c +++ /dev/null @@ -1,541 +0,0 @@ -/* - * Copyright 2016 Józef Kucia for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "vkd3d_utils_private.h" -#undef D3D12CreateDevice -#if 0 -VKD3D_DEBUG_ENV_NAME("VKD3D_DEBUG"); - -HRESULT WINAPI D3D12GetDebugInterface(REFIID iid, void **debug) -{ - FIXME("iid %s, debug %p stub!\n", debugstr_guid(iid), debug); - - return E_NOTIMPL; -} - -HRESULT WINAPI D3D12CreateDeviceVKD3D(IUnknown *adapter, D3D_FEATURE_LEVEL minimum_feature_level, - REFIID iid, void **device, enum vkd3d_api_version api_version) -{ - struct vkd3d_optional_instance_extensions_info optional_extensions_info; - struct vkd3d_instance_create_info instance_create_info; - struct vkd3d_device_create_info device_create_info; - - static const char * const instance_extensions[] = - { - VK_KHR_SURFACE_EXTENSION_NAME, - }; - static const char * const optional_instance_extensions[] = - { - "VK_KHR_xcb_surface", - "VK_MVK_macos_surface", - }; - static const char * const device_extensions[] = - { - VK_KHR_SWAPCHAIN_EXTENSION_NAME, - }; - struct vkd3d_application_info application_info = - { - .type = VKD3D_STRUCTURE_TYPE_APPLICATION_INFO, - .api_version = api_version, - }; - - TRACE("adapter %p, minimum_feature_level %#x, iid %s, device %p, api_version %#x.\n", - adapter, minimum_feature_level, debugstr_guid(iid), device, api_version); - - if (adapter) - FIXME("Ignoring adapter %p.\n", adapter); - - memset(&optional_extensions_info, 0, sizeof(optional_extensions_info)); - optional_extensions_info.type = VKD3D_STRUCTURE_TYPE_OPTIONAL_INSTANCE_EXTENSIONS_INFO; - optional_extensions_info.next = &application_info; - optional_extensions_info.extensions = optional_instance_extensions; - optional_extensions_info.extension_count = ARRAY_SIZE(optional_instance_extensions); - - memset(&instance_create_info, 0, sizeof(instance_create_info)); - instance_create_info.type = VKD3D_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; - instance_create_info.next = &optional_extensions_info; - instance_create_info.pfn_signal_event = vkd3d_signal_event; - instance_create_info.wchar_size = sizeof(WCHAR); - instance_create_info.instance_extensions = instance_extensions; - instance_create_info.instance_extension_count = ARRAY_SIZE(instance_extensions); - - memset(&device_create_info, 0, sizeof(device_create_info)); - device_create_info.type = VKD3D_STRUCTURE_TYPE_DEVICE_CREATE_INFO; - device_create_info.next = NULL; - device_create_info.minimum_feature_level = minimum_feature_level; - device_create_info.instance_create_info = &instance_create_info; - device_create_info.device_extensions = device_extensions; - device_create_info.device_extension_count = ARRAY_SIZE(device_extensions); - - return vkd3d_create_device(&device_create_info, iid, device); -} - -HRESULT WINAPI D3D12CreateDevice(IUnknown *adapter, - D3D_FEATURE_LEVEL minimum_feature_level, REFIID iid, void **device) -{ - return D3D12CreateDeviceVKD3D(adapter, minimum_feature_level, iid, device, VKD3D_API_VERSION_1_0); -} - -HRESULT WINAPI D3D12CreateRootSignatureDeserializer(const void *data, SIZE_T data_size, - REFIID iid, void **deserializer) -{ - TRACE("data %p, data_size %lu, iid %s, deserializer %p.\n", - data, data_size, debugstr_guid(iid), deserializer); - - return vkd3d_create_root_signature_deserializer(data, data_size, iid, deserializer); -} - -HRESULT WINAPI D3D12CreateVersionedRootSignatureDeserializer(const void *data, SIZE_T data_size, - REFIID iid,void **deserializer) -{ - TRACE("data %p, data_size %lu, iid %s, deserializer %p.\n", - data, data_size, debugstr_guid(iid), deserializer); - - return vkd3d_create_versioned_root_signature_deserializer(data, data_size, iid, deserializer); -} - -HRESULT WINAPI D3D12SerializeRootSignature(const D3D12_ROOT_SIGNATURE_DESC *desc, - D3D_ROOT_SIGNATURE_VERSION version, ID3DBlob **blob, ID3DBlob **error_blob) -{ - TRACE("desc %p, version %#x, blob %p, error_blob %p.\n", desc, version, blob, error_blob); - - return vkd3d_serialize_root_signature(desc, version, blob, error_blob); -} - -HRESULT WINAPI D3D12SerializeVersionedRootSignature(const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *desc, - ID3DBlob **blob, ID3DBlob **error_blob) -{ - TRACE("desc %p, blob %p, error_blob %p.\n", desc, blob, error_blob); - - return vkd3d_serialize_versioned_root_signature(desc, blob, error_blob); -} - -static int open_include(const char *filename, bool local, const char *parent_data, void *context, - struct vkd3d_shader_code *code) -{ - ID3DInclude *iface = context; - unsigned int size = 0; - - if (!iface) - return VKD3D_ERROR; - - memset(code, 0, sizeof(*code)); - if (FAILED(ID3DInclude_Open(iface, local ? D3D_INCLUDE_LOCAL : D3D_INCLUDE_SYSTEM, - filename, parent_data, &code->code, &size))) - return VKD3D_ERROR; - - code->size = size; - return VKD3D_OK; -} - -static void close_include(const struct vkd3d_shader_code *code, void *context) -{ - ID3DInclude *iface = context; - - ID3DInclude_Close(iface, code->code); -} - -HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filename, - const D3D_SHADER_MACRO *macros, ID3DInclude *include, const char *entry_point, - const char *profile, UINT flags, UINT effect_flags, UINT secondary_flags, - const void *secondary_data, SIZE_T secondary_data_size, ID3DBlob **shader_blob, - ID3DBlob **messages_blob) -{ - struct vkd3d_shader_preprocess_info preprocess_info; - struct vkd3d_shader_hlsl_source_info hlsl_info; - struct vkd3d_shader_compile_option options[2]; - struct vkd3d_shader_compile_info compile_info; - struct vkd3d_shader_compile_option *option; - struct vkd3d_shader_code byte_code; - const D3D_SHADER_MACRO *macro; - size_t profile_len, i; - char *messages; - HRESULT hr; - int ret; - - static const char * const d3dbc_profiles[] = - { - "fx_2_", - - "ps.1.", - "ps.2.", - "ps.3.", - - "ps_1_", - "ps_2_", - "ps_3_", - - "vs.1.", - "vs.2.", - "vs.3.", - - "vs_1_", - "vs_2_", - "vs_3_", - - "tx_1_", - }; - - TRACE("data %p, data_size %lu, filename %s, macros %p, include %p, entry_point %s, " - "profile %s, flags %#x, effect_flags %#x, secondary_flags %#x, secondary_data %p, " - "secondary_data_size %lu, shader_blob %p, messages_blob %p.\n", - data, data_size, debugstr_a(filename), macros, include, debugstr_a(entry_point), - debugstr_a(profile), flags, effect_flags, secondary_flags, secondary_data, - secondary_data_size, shader_blob, messages_blob); - - if (flags & ~D3DCOMPILE_DEBUG) - FIXME("Ignoring flags %#x.\n", flags); - if (effect_flags) - FIXME("Ignoring effect flags %#x.\n", effect_flags); - if (secondary_flags) - FIXME("Ignoring secondary flags %#x.\n", secondary_flags); - - if (messages_blob) - *messages_blob = NULL; - - option = &options[0]; - option->name = VKD3D_SHADER_COMPILE_OPTION_API_VERSION; - option->value = VKD3D_SHADER_API_VERSION_1_3; - - compile_info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; - compile_info.next = &preprocess_info; - compile_info.source.code = data; - compile_info.source.size = data_size; - compile_info.source_type = VKD3D_SHADER_SOURCE_HLSL; - compile_info.target_type = VKD3D_SHADER_TARGET_DXBC_TPF; - compile_info.options = options; - compile_info.option_count = 1; - compile_info.log_level = VKD3D_SHADER_LOG_INFO; - compile_info.source_name = filename; - - profile_len = strlen(profile); - for (i = 0; i < ARRAY_SIZE(d3dbc_profiles); ++i) - { - size_t len = strlen(d3dbc_profiles[i]); - - if (len <= profile_len && !memcmp(profile, d3dbc_profiles[i], len)) - { - compile_info.target_type = VKD3D_SHADER_TARGET_D3D_BYTECODE; - break; - } - } - - preprocess_info.type = VKD3D_SHADER_STRUCTURE_TYPE_PREPROCESS_INFO; - preprocess_info.next = &hlsl_info; - preprocess_info.macros = (const struct vkd3d_shader_macro *)macros; - preprocess_info.macro_count = 0; - if (macros) - { - for (macro = macros; macro->Name; ++macro) - ++preprocess_info.macro_count; - } - preprocess_info.pfn_open_include = open_include; - preprocess_info.pfn_close_include = close_include; - preprocess_info.include_context = include; - - hlsl_info.type = VKD3D_SHADER_STRUCTURE_TYPE_HLSL_SOURCE_INFO; - hlsl_info.next = NULL; - hlsl_info.profile = profile; - hlsl_info.entry_point = entry_point; - hlsl_info.secondary_code.code = secondary_data; - hlsl_info.secondary_code.size = secondary_data_size; - - if (!(flags & D3DCOMPILE_DEBUG)) - { - option = &options[compile_info.option_count++]; - option->name = VKD3D_SHADER_COMPILE_OPTION_STRIP_DEBUG; - option->value = true; - } - - ret = vkd3d_shader_compile(&compile_info, &byte_code, &messages); - if (messages) - { - if (messages_blob) - { - if (FAILED(hr = vkd3d_blob_create(messages, strlen(messages), messages_blob))) - { - vkd3d_shader_free_shader_code(&byte_code); - return hr; - } - } - else - vkd3d_shader_free_messages(messages); - } - - if (!ret) - { - if (FAILED(hr = vkd3d_blob_create((void *)byte_code.code, byte_code.size, shader_blob))) - { - vkd3d_shader_free_shader_code(&byte_code); - return hr; - } - } - - return hresult_from_vkd3d_result(ret); -} - -HRESULT WINAPI D3DCompile(const void *data, SIZE_T data_size, const char *filename, - const D3D_SHADER_MACRO *macros, ID3DInclude *include, const char *entrypoint, - const char *profile, UINT flags, UINT effect_flags, ID3DBlob **shader, ID3DBlob **error_messages) -{ - TRACE("data %p, data_size %lu, filename %s, macros %p, include %p, entrypoint %s, " - "profile %s, flags %#x, effect_flags %#x, shader %p, error_messages %p.\n", - data, data_size, debugstr_a(filename), macros, include, debugstr_a(entrypoint), - debugstr_a(profile), flags, effect_flags, shader, error_messages); - - return D3DCompile2(data, data_size, filename, macros, include, entrypoint, profile, flags, - effect_flags, 0, NULL, 0, shader, error_messages); -} - -HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, const char *filename, - const D3D_SHADER_MACRO *macros, ID3DInclude *include, - ID3DBlob **preprocessed_blob, ID3DBlob **messages_blob) -{ - struct vkd3d_shader_preprocess_info preprocess_info; - struct vkd3d_shader_compile_info compile_info; - struct vkd3d_shader_code preprocessed_code; - const D3D_SHADER_MACRO *macro; - char *messages; - HRESULT hr; - int ret; - - static const struct vkd3d_shader_compile_option options[] = - { - {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_3}, - }; - - TRACE("data %p, size %lu, filename %s, macros %p, include %p, preprocessed_blob %p, messages_blob %p.\n", - data, size, debugstr_a(filename), macros, include, preprocessed_blob, messages_blob); - - if (messages_blob) - *messages_blob = NULL; - - compile_info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; - compile_info.next = &preprocess_info; - compile_info.source.code = data; - compile_info.source.size = size; - compile_info.source_type = VKD3D_SHADER_SOURCE_HLSL; - compile_info.target_type = VKD3D_SHADER_TARGET_NONE; - compile_info.options = options; - compile_info.option_count = ARRAY_SIZE(options); - compile_info.log_level = VKD3D_SHADER_LOG_INFO; - compile_info.source_name = filename; - - preprocess_info.type = VKD3D_SHADER_STRUCTURE_TYPE_PREPROCESS_INFO; - preprocess_info.next = NULL; - preprocess_info.macros = (const struct vkd3d_shader_macro *)macros; - preprocess_info.macro_count = 0; - if (macros) - { - for (macro = macros; macro->Name; ++macro) - ++preprocess_info.macro_count; - } - preprocess_info.pfn_open_include = open_include; - preprocess_info.pfn_close_include = close_include; - preprocess_info.include_context = include; - - ret = vkd3d_shader_preprocess(&compile_info, &preprocessed_code, &messages); - if (messages) - { - if (messages_blob) - { - if (FAILED(hr = vkd3d_blob_create(messages, strlen(messages), messages_blob))) - { - vkd3d_shader_free_shader_code(&preprocessed_code); - return hr; - } - } - else - vkd3d_shader_free_messages(messages); - } - - if (!ret) - { - if (FAILED(hr = vkd3d_blob_create((void *)preprocessed_code.code, preprocessed_code.size, preprocessed_blob))) - { - vkd3d_shader_free_shader_code(&preprocessed_code); - return hr; - } - } - - return hresult_from_vkd3d_result(ret); -} - -/* Events */ - -#ifdef _WIN32 - -HANDLE vkd3d_create_event(void) -{ - return CreateEventA(NULL, FALSE, FALSE, NULL); -} - -HRESULT vkd3d_signal_event(HANDLE event) -{ - SetEvent(event); - return S_OK; -} - -unsigned int vkd3d_wait_event(HANDLE event, unsigned int milliseconds) -{ - return WaitForSingleObject(event, milliseconds); -} - -void vkd3d_destroy_event(HANDLE event) -{ - CloseHandle(event); -} - -#else /* _WIN32 */ - -#include - -struct vkd3d_event -{ - pthread_mutex_t mutex; - pthread_cond_t cond; - BOOL is_signaled; -}; - -HANDLE vkd3d_create_event(void) -{ - struct vkd3d_event *event; - int rc; - - TRACE(".\n"); - - if (!(event = vkd3d_malloc(sizeof(*event)))) - return NULL; - - if ((rc = pthread_mutex_init(&event->mutex, NULL))) - { - ERR("Failed to initialize mutex, error %d.\n", rc); - vkd3d_free(event); - return NULL; - } - if ((rc = pthread_cond_init(&event->cond, NULL))) - { - ERR("Failed to initialize condition variable, error %d.\n", rc); - pthread_mutex_destroy(&event->mutex); - vkd3d_free(event); - return NULL; - } - - event->is_signaled = false; - - TRACE("Created event %p.\n", event); - - return event; -} - -unsigned int vkd3d_wait_event(HANDLE event, unsigned int milliseconds) -{ - struct vkd3d_event *impl = event; - int rc; - - TRACE("event %p, milliseconds %u.\n", event, milliseconds); - - if ((rc = pthread_mutex_lock(&impl->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return VKD3D_WAIT_FAILED; - } - - if (impl->is_signaled || !milliseconds) - { - bool is_signaled = impl->is_signaled; - impl->is_signaled = false; - pthread_mutex_unlock(&impl->mutex); - return is_signaled ? VKD3D_WAIT_OBJECT_0 : VKD3D_WAIT_TIMEOUT; - } - - if (milliseconds == VKD3D_INFINITE) - { - do - { - if ((rc = pthread_cond_wait(&impl->cond, &impl->mutex))) - { - ERR("Failed to wait on condition variable, error %d.\n", rc); - pthread_mutex_unlock(&impl->mutex); - return VKD3D_WAIT_FAILED; - } - } while (!impl->is_signaled); - - impl->is_signaled = false; - pthread_mutex_unlock(&impl->mutex); - return VKD3D_WAIT_OBJECT_0; - } - - pthread_mutex_unlock(&impl->mutex); - FIXME("Timed wait not implemented yet.\n"); - return VKD3D_WAIT_FAILED; -} - -HRESULT vkd3d_signal_event(HANDLE event) -{ - struct vkd3d_event *impl = event; - int rc; - - TRACE("event %p.\n", event); - - if ((rc = pthread_mutex_lock(&impl->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return E_FAIL; - } - impl->is_signaled = true; - pthread_cond_signal(&impl->cond); - pthread_mutex_unlock(&impl->mutex); - - return S_OK; -} - -void vkd3d_destroy_event(HANDLE event) -{ - struct vkd3d_event *impl = event; - int rc; - - TRACE("event %p.\n", event); - - if ((rc = pthread_mutex_destroy(&impl->mutex))) - ERR("Failed to destroy mutex, error %d.\n", rc); - if ((rc = pthread_cond_destroy(&impl->cond))) - ERR("Failed to destroy condition variable, error %d.\n", rc); - vkd3d_free(impl); -} - -#endif /* _WIN32 */ - -HRESULT WINAPI D3DCreateBlob(SIZE_T data_size, ID3DBlob **blob) -{ - HRESULT hr; - void *data; - - TRACE("data_size %lu, blob %p.\n", data_size, blob); - - if (!(data = vkd3d_calloc(data_size, 1))) - return E_OUTOFMEMORY; - - if (FAILED(hr = vkd3d_blob_create(data, data_size, blob))) - { - WARN("Failed to create blob object, hr %#x.\n", hr); - vkd3d_free(data); - } - return hr; -} -#endif \ No newline at end of file diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-utils/vkd3d_utils_private.h b/dll/directx/wine/d3d12/vkd3d/vkd3d-utils/vkd3d_utils_private.h deleted file mode 100644 index 1b8254b67b1a4..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-utils/vkd3d_utils_private.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2016 Józef Kucia for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef __VKD3D_UTILS_PRIVATE_H -#define __VKD3D_UTILS_PRIVATE_H - -#define COBJMACROS -#define NONAMELESSUNION -#define VK_NO_PROTOTYPES - -#include -#include -#include - -#include "vkd3d_blob.h" -#include "vkd3d_memory.h" -#include - -#endif /* __VKD3D_UTILS_PRIVATE_H */ diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d/CMakeLists.txt b/dll/directx/wine/d3d12/vkd3d/vkd3d/CMakeLists.txt deleted file mode 100644 index fcb5641fc591f..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ - -include_directories("../include") -include_directories("../include/private") -add_library(vkd3d command.c - device.c - resource.c - state.c - utils.c - vkd3d_main.c) - - -add_dependencies(vkd3d vkd3d_idl_headers psdk) diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d/vkd3d.map b/dll/directx/wine/d3d12/vkd3d/vkd3d/vkd3d.map deleted file mode 100644 index 6f1f376113e0c..0000000000000 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d/vkd3d.map +++ /dev/null @@ -1,27 +0,0 @@ -VKD3D_1_0 -{ -global: - vkd3d_acquire_vk_queue; - vkd3d_create_device; - vkd3d_create_image_resource; - vkd3d_create_instance; - vkd3d_create_root_signature_deserializer; - vkd3d_create_versioned_root_signature_deserializer; - vkd3d_get_device_parent; - vkd3d_get_dxgi_format; - vkd3d_get_vk_device; - vkd3d_get_vk_format; - vkd3d_get_vk_physical_device; - vkd3d_get_vk_queue_family_index; - vkd3d_instance_decref; - vkd3d_instance_from_device; - vkd3d_instance_get_vk_instance; - vkd3d_instance_incref; - vkd3d_release_vk_queue; - vkd3d_resource_decref; - vkd3d_resource_incref; - vkd3d_serialize_root_signature; - vkd3d_serialize_versioned_root_signature; - -local: *; -}; diff --git a/dll/directx/wine/d3d12core/Makefile.in b/dll/directx/wine/d3d12core/Makefile.in new file mode 100644 index 0000000000000..8778b66138b8f --- /dev/null +++ b/dll/directx/wine/d3d12core/Makefile.in @@ -0,0 +1 @@ +MODULE = d3d12core.dll diff --git a/dll/directx/wine/d3d12core/d3d12core.spec b/dll/directx/wine/d3d12core/d3d12core.spec new file mode 100644 index 0000000000000..c9c73bd4ee492 --- /dev/null +++ b/dll/directx/wine/d3d12core/d3d12core.spec @@ -0,0 +1,2 @@ +@ stub D3D12GetInterface +@ stub D3D12SDKVersion diff --git a/dll/directx/wine/d3d12/vkd3d/include/private/vkd3d_blob.h b/dll/directx/wine/vkd3d/include/private/vkd3d_blob.h similarity index 94% rename from dll/directx/wine/d3d12/vkd3d/include/private/vkd3d_blob.h rename to dll/directx/wine/vkd3d/include/private/vkd3d_blob.h index 0f48e876cbbae..0f133aa6fe7cb 100644 --- a/dll/directx/wine/d3d12/vkd3d/include/private/vkd3d_blob.h +++ b/dll/directx/wine/vkd3d/include/private/vkd3d_blob.h @@ -19,8 +19,8 @@ #ifndef __VKD3D_BLOB_H #define __VKD3D_BLOB_H -#include "vkd3d_windows.h" -#include "vkd3d_d3dcommon.h" +#include "windows.h" +#include "d3dcommon.h" HRESULT vkd3d_blob_create(void *buffer, SIZE_T size, ID3D10Blob **blob); diff --git a/dll/directx/wine/d3d12/vkd3d/include/private/vkd3d_common.h b/dll/directx/wine/vkd3d/include/private/vkd3d_common.h similarity index 74% rename from dll/directx/wine/d3d12/vkd3d/include/private/vkd3d_common.h rename to dll/directx/wine/vkd3d/include/private/vkd3d_common.h index ebf0521688cae..3cf0422596c1b 100644 --- a/dll/directx/wine/d3d12/vkd3d/include/private/vkd3d_common.h +++ b/dll/directx/wine/vkd3d/include/private/vkd3d_common.h @@ -20,13 +20,14 @@ #define __VKD3D_COMMON_H #include "config.h" -#include "vkd3d_windows.h" +#include "windows.h" #include "vkd3d_types.h" #include #include #include #include +#include #ifdef _MSC_VER #include @@ -53,19 +54,37 @@ static inline size_t align(size_t addr, size_t alignment) #ifdef __GNUC__ # define VKD3D_NORETURN __attribute__((noreturn)) -# define VKD3D_PRINTF_FUNC(fmt, args) __attribute__((format(printf, fmt, args))) +# ifdef __MINGW_PRINTF_FORMAT +# define VKD3D_PRINTF_FUNC(fmt, args) __attribute__((format(__MINGW_PRINTF_FORMAT, fmt, args))) +# else +# define VKD3D_PRINTF_FUNC(fmt, args) __attribute__((format(printf, fmt, args))) +# endif # define VKD3D_UNUSED __attribute__((unused)) +# define VKD3D_UNREACHABLE __builtin_unreachable() #else # define VKD3D_NORETURN # define VKD3D_PRINTF_FUNC(fmt, args) # define VKD3D_UNUSED +# 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 + static inline unsigned int vkd3d_popcount(unsigned int v) { #ifdef _MSC_VER return __popcnt(v); -#elif defined(HAVE_BUILTIN_POPCOUNT) +#elif defined(__MINGW32__) return __builtin_popcount(v); #else v -= (v >> 1) & 0x55555555; @@ -210,6 +229,10 @@ static inline LONG InterlockedIncrement(LONG volatile *x) { return __sync_add_and_fetch(x, 1); } +static inline LONG64 InterlockedIncrement64(LONG64 volatile *x) +{ + return __sync_add_and_fetch(x, 1); +} static inline LONG InterlockedAdd(LONG volatile *x, LONG val) { return __sync_add_and_fetch(x, val); @@ -242,4 +265,74 @@ static inline void vkd3d_parse_version(const char *version, int *major, int *min HRESULT hresult_from_vkd3d_result(int vkd3d_result); +#ifdef _WIN32 +static inline void *vkd3d_dlopen(const char *name) +{ + return LoadLibraryA(name); +} + +static inline void *vkd3d_dlsym(void *handle, const char *symbol) +{ + return GetProcAddress(handle, symbol); +} + +static inline int vkd3d_dlclose(void *handle) +{ + return FreeLibrary(handle); +} + +static inline const char *vkd3d_dlerror(void) +{ + unsigned int error = GetLastError(); + static char message[256]; + + if (FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, message, sizeof(message), NULL)) + return message; + sprintf(message, "Unknown error %u.\n", error); + return message; +} +#elif defined(HAVE_DLFCN_H) +#include + +static inline void *vkd3d_dlopen(const char *name) +{ + return dlopen(name, RTLD_NOW); +} + +static inline void *vkd3d_dlsym(void *handle, const char *symbol) +{ + return dlsym(handle, symbol); +} + +static inline int vkd3d_dlclose(void *handle) +{ + return dlclose(handle); +} + +static inline const char *vkd3d_dlerror(void) +{ + return dlerror(); +} +#else +static inline void *vkd3d_dlopen(const char *name) +{ + return NULL; +} + +static inline void *vkd3d_dlsym(void *handle, const char *symbol) +{ + return NULL; +} + +static inline int vkd3d_dlclose(void *handle) +{ + return 0; +} + +static inline const char *vkd3d_dlerror(void) +{ + return "Not implemented for this platform.\n"; +} +#endif + #endif /* __VKD3D_COMMON_H */ diff --git a/dll/directx/wine/d3d12/vkd3d/include/private/vkd3d_debug.h b/dll/directx/wine/vkd3d/include/private/vkd3d_debug.h similarity index 97% rename from dll/directx/wine/d3d12/vkd3d/include/private/vkd3d_debug.h rename to dll/directx/wine/vkd3d/include/private/vkd3d_debug.h index 8ab653aef2e99..4f6d43af12f25 100644 --- a/dll/directx/wine/d3d12/vkd3d/include/private/vkd3d_debug.h +++ b/dll/directx/wine/vkd3d/include/private/vkd3d_debug.h @@ -47,6 +47,7 @@ enum vkd3d_dbg_level enum vkd3d_dbg_level vkd3d_dbg_get_level(void); void vkd3d_dbg_printf(enum vkd3d_dbg_level level, const char *function, const char *fmt, ...) VKD3D_PRINTF_FUNC(3, 4); +void vkd3d_dbg_set_log_callback(PFN_vkd3d_log callback); const char *vkd3d_dbg_sprintf(const char *fmt, ...) VKD3D_PRINTF_FUNC(1, 2); const char *vkd3d_dbg_vsprintf(const char *fmt, va_list args); @@ -114,5 +115,6 @@ struct vkd3d_debug_option bool vkd3d_debug_list_has_member(const char *string, const char *member); uint64_t vkd3d_parse_debug_options(const char *string, const struct vkd3d_debug_option *options, unsigned int option_count); +void vkd3d_set_thread_name(const char *name); #endif /* __VKD3D_DEBUG_H */ diff --git a/dll/directx/wine/d3d12/vkd3d/include/private/vkd3d_memory.h b/dll/directx/wine/vkd3d/include/private/vkd3d_memory.h similarity index 100% rename from dll/directx/wine/d3d12/vkd3d/include/private/vkd3d_memory.h rename to dll/directx/wine/vkd3d/include/private/vkd3d_memory.h diff --git a/dll/directx/wine/d3d12/vkd3d/include/private/vkd3d_utf8.h b/dll/directx/wine/vkd3d/include/private/vkd3d_utf8.h similarity index 100% rename from dll/directx/wine/d3d12/vkd3d/include/private/vkd3d_utf8.h rename to dll/directx/wine/vkd3d/include/private/vkd3d_utf8.h diff --git a/dll/directx/wine/vkd3d/include/private/vkd3d_version.h b/dll/directx/wine/vkd3d/include/private/vkd3d_version.h new file mode 100644 index 0000000000000..0edc442802257 --- /dev/null +++ b/dll/directx/wine/vkd3d/include/private/vkd3d_version.h @@ -0,0 +1 @@ +#define VKD3D_VCS_ID " (Wine bundled)" diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/GLSL.std.450.h b/dll/directx/wine/vkd3d/include/vulkan/GLSL.std.450.h similarity index 99% rename from dll/directx/wine/d3d12/vkd3d/vkd3d-shader/GLSL.std.450.h rename to dll/directx/wine/vkd3d/include/vulkan/GLSL.std.450.h index 54cc00e9a8882..943fd8650f850 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/GLSL.std.450.h +++ b/dll/directx/wine/vkd3d/include/vulkan/GLSL.std.450.h @@ -13,7 +13,7 @@ ** ** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS ** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND -** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ** ** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/dll/directx/wine/vkd3d/include/vulkan/spirv.h b/dll/directx/wine/vkd3d/include/vulkan/spirv.h new file mode 100644 index 0000000000000..bc20ad7fea94d --- /dev/null +++ b/dll/directx/wine/vkd3d/include/vulkan/spirv.h @@ -0,0 +1,2510 @@ +/* +** Copyright (c) 2014-2020 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and/or associated documentation files (the "Materials"), +** to deal in the Materials without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Materials, and to permit persons to whom the +** Materials are furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Materials. +** +** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS +** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS +** IN THE MATERIALS. +*/ + +/* +** This header is automatically generated by the same tool that creates +** the Binary Section of the SPIR-V specification. +*/ + +/* +** Enumeration tokens for SPIR-V, in various styles: +** C, C++, C++11, JSON, Lua, Python, C#, D +** +** - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +** - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +** - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +** - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +** - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +** - C# will use enum classes in the Specification class located in the "Spv" namespace, +** e.g.: Spv.Specification.SourceLanguage.GLSL +** - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL +** +** Some tokens act like mask values, which can be OR'd together, +** while others are mutually exclusive. The mask-like ones have +** "Mask" in their name, and a parallel enum that has the shift +** amount (1 << x) for each corresponding enumerant. +*/ + +#ifndef spirv_H +#define spirv_H + +typedef unsigned int SpvId; + +#define SPV_VERSION 0x10600 +#define SPV_REVISION 1 + +static const unsigned int SpvMagicNumber = 0x07230203; +static const unsigned int SpvVersion = 0x00010600; +static const unsigned int SpvRevision = 1; +static const unsigned int SpvOpCodeMask = 0xffff; +static const unsigned int SpvWordCountShift = 16; + +typedef enum SpvSourceLanguage_ { + SpvSourceLanguageUnknown = 0, + SpvSourceLanguageESSL = 1, + SpvSourceLanguageGLSL = 2, + SpvSourceLanguageOpenCL_C = 3, + SpvSourceLanguageOpenCL_CPP = 4, + SpvSourceLanguageHLSL = 5, + SpvSourceLanguageCPP_for_OpenCL = 6, + SpvSourceLanguageMax = 0x7fffffff, +} SpvSourceLanguage; + +typedef enum SpvExecutionModel_ { + SpvExecutionModelVertex = 0, + SpvExecutionModelTessellationControl = 1, + SpvExecutionModelTessellationEvaluation = 2, + SpvExecutionModelGeometry = 3, + SpvExecutionModelFragment = 4, + SpvExecutionModelGLCompute = 5, + SpvExecutionModelKernel = 6, + SpvExecutionModelTaskNV = 5267, + SpvExecutionModelMeshNV = 5268, + SpvExecutionModelRayGenerationKHR = 5313, + SpvExecutionModelRayGenerationNV = 5313, + SpvExecutionModelIntersectionKHR = 5314, + SpvExecutionModelIntersectionNV = 5314, + SpvExecutionModelAnyHitKHR = 5315, + SpvExecutionModelAnyHitNV = 5315, + SpvExecutionModelClosestHitKHR = 5316, + SpvExecutionModelClosestHitNV = 5316, + SpvExecutionModelMissKHR = 5317, + SpvExecutionModelMissNV = 5317, + SpvExecutionModelCallableKHR = 5318, + SpvExecutionModelCallableNV = 5318, + SpvExecutionModelMax = 0x7fffffff, +} SpvExecutionModel; + +typedef enum SpvAddressingModel_ { + SpvAddressingModelLogical = 0, + SpvAddressingModelPhysical32 = 1, + SpvAddressingModelPhysical64 = 2, + SpvAddressingModelPhysicalStorageBuffer64 = 5348, + SpvAddressingModelPhysicalStorageBuffer64EXT = 5348, + SpvAddressingModelMax = 0x7fffffff, +} SpvAddressingModel; + +typedef enum SpvMemoryModel_ { + SpvMemoryModelSimple = 0, + SpvMemoryModelGLSL450 = 1, + SpvMemoryModelOpenCL = 2, + SpvMemoryModelVulkan = 3, + SpvMemoryModelVulkanKHR = 3, + SpvMemoryModelMax = 0x7fffffff, +} SpvMemoryModel; + +typedef enum SpvExecutionMode_ { + SpvExecutionModeInvocations = 0, + SpvExecutionModeSpacingEqual = 1, + SpvExecutionModeSpacingFractionalEven = 2, + SpvExecutionModeSpacingFractionalOdd = 3, + SpvExecutionModeVertexOrderCw = 4, + SpvExecutionModeVertexOrderCcw = 5, + SpvExecutionModePixelCenterInteger = 6, + SpvExecutionModeOriginUpperLeft = 7, + SpvExecutionModeOriginLowerLeft = 8, + SpvExecutionModeEarlyFragmentTests = 9, + SpvExecutionModePointMode = 10, + SpvExecutionModeXfb = 11, + SpvExecutionModeDepthReplacing = 12, + SpvExecutionModeDepthGreater = 14, + SpvExecutionModeDepthLess = 15, + SpvExecutionModeDepthUnchanged = 16, + SpvExecutionModeLocalSize = 17, + SpvExecutionModeLocalSizeHint = 18, + SpvExecutionModeInputPoints = 19, + SpvExecutionModeInputLines = 20, + SpvExecutionModeInputLinesAdjacency = 21, + SpvExecutionModeTriangles = 22, + SpvExecutionModeInputTrianglesAdjacency = 23, + SpvExecutionModeQuads = 24, + SpvExecutionModeIsolines = 25, + SpvExecutionModeOutputVertices = 26, + SpvExecutionModeOutputPoints = 27, + SpvExecutionModeOutputLineStrip = 28, + SpvExecutionModeOutputTriangleStrip = 29, + SpvExecutionModeVecTypeHint = 30, + SpvExecutionModeContractionOff = 31, + SpvExecutionModeInitializer = 33, + SpvExecutionModeFinalizer = 34, + SpvExecutionModeSubgroupSize = 35, + SpvExecutionModeSubgroupsPerWorkgroup = 36, + SpvExecutionModeSubgroupsPerWorkgroupId = 37, + SpvExecutionModeLocalSizeId = 38, + SpvExecutionModeLocalSizeHintId = 39, + SpvExecutionModeSubgroupUniformControlFlowKHR = 4421, + SpvExecutionModePostDepthCoverage = 4446, + SpvExecutionModeDenormPreserve = 4459, + SpvExecutionModeDenormFlushToZero = 4460, + SpvExecutionModeSignedZeroInfNanPreserve = 4461, + SpvExecutionModeRoundingModeRTE = 4462, + SpvExecutionModeRoundingModeRTZ = 4463, + SpvExecutionModeStencilRefReplacingEXT = 5027, + SpvExecutionModeOutputLinesNV = 5269, + SpvExecutionModeOutputPrimitivesNV = 5270, + SpvExecutionModeDerivativeGroupQuadsNV = 5289, + SpvExecutionModeDerivativeGroupLinearNV = 5290, + SpvExecutionModeOutputTrianglesNV = 5298, + SpvExecutionModePixelInterlockOrderedEXT = 5366, + SpvExecutionModePixelInterlockUnorderedEXT = 5367, + SpvExecutionModeSampleInterlockOrderedEXT = 5368, + SpvExecutionModeSampleInterlockUnorderedEXT = 5369, + SpvExecutionModeShadingRateInterlockOrderedEXT = 5370, + SpvExecutionModeShadingRateInterlockUnorderedEXT = 5371, + SpvExecutionModeSharedLocalMemorySizeINTEL = 5618, + SpvExecutionModeRoundingModeRTPINTEL = 5620, + SpvExecutionModeRoundingModeRTNINTEL = 5621, + SpvExecutionModeFloatingPointModeALTINTEL = 5622, + SpvExecutionModeFloatingPointModeIEEEINTEL = 5623, + SpvExecutionModeMaxWorkgroupSizeINTEL = 5893, + SpvExecutionModeMaxWorkDimINTEL = 5894, + SpvExecutionModeNoGlobalOffsetINTEL = 5895, + SpvExecutionModeNumSIMDWorkitemsINTEL = 5896, + SpvExecutionModeSchedulerTargetFmaxMhzINTEL = 5903, + SpvExecutionModeMax = 0x7fffffff, +} SpvExecutionMode; + +typedef enum SpvStorageClass_ { + SpvStorageClassUniformConstant = 0, + SpvStorageClassInput = 1, + SpvStorageClassUniform = 2, + SpvStorageClassOutput = 3, + SpvStorageClassWorkgroup = 4, + SpvStorageClassCrossWorkgroup = 5, + SpvStorageClassPrivate = 6, + SpvStorageClassFunction = 7, + SpvStorageClassGeneric = 8, + SpvStorageClassPushConstant = 9, + SpvStorageClassAtomicCounter = 10, + SpvStorageClassImage = 11, + SpvStorageClassStorageBuffer = 12, + SpvStorageClassCallableDataKHR = 5328, + SpvStorageClassCallableDataNV = 5328, + SpvStorageClassIncomingCallableDataKHR = 5329, + SpvStorageClassIncomingCallableDataNV = 5329, + SpvStorageClassRayPayloadKHR = 5338, + SpvStorageClassRayPayloadNV = 5338, + SpvStorageClassHitAttributeKHR = 5339, + SpvStorageClassHitAttributeNV = 5339, + SpvStorageClassIncomingRayPayloadKHR = 5342, + SpvStorageClassIncomingRayPayloadNV = 5342, + SpvStorageClassShaderRecordBufferKHR = 5343, + SpvStorageClassShaderRecordBufferNV = 5343, + SpvStorageClassPhysicalStorageBuffer = 5349, + SpvStorageClassPhysicalStorageBufferEXT = 5349, + SpvStorageClassCodeSectionINTEL = 5605, + SpvStorageClassDeviceOnlyINTEL = 5936, + SpvStorageClassHostOnlyINTEL = 5937, + SpvStorageClassMax = 0x7fffffff, +} SpvStorageClass; + +typedef enum SpvDim_ { + SpvDim1D = 0, + SpvDim2D = 1, + SpvDim3D = 2, + SpvDimCube = 3, + SpvDimRect = 4, + SpvDimBuffer = 5, + SpvDimSubpassData = 6, + SpvDimMax = 0x7fffffff, +} SpvDim; + +typedef enum SpvSamplerAddressingMode_ { + SpvSamplerAddressingModeNone = 0, + SpvSamplerAddressingModeClampToEdge = 1, + SpvSamplerAddressingModeClamp = 2, + SpvSamplerAddressingModeRepeat = 3, + SpvSamplerAddressingModeRepeatMirrored = 4, + SpvSamplerAddressingModeMax = 0x7fffffff, +} SpvSamplerAddressingMode; + +typedef enum SpvSamplerFilterMode_ { + SpvSamplerFilterModeNearest = 0, + SpvSamplerFilterModeLinear = 1, + SpvSamplerFilterModeMax = 0x7fffffff, +} SpvSamplerFilterMode; + +typedef enum SpvImageFormat_ { + SpvImageFormatUnknown = 0, + SpvImageFormatRgba32f = 1, + SpvImageFormatRgba16f = 2, + SpvImageFormatR32f = 3, + SpvImageFormatRgba8 = 4, + SpvImageFormatRgba8Snorm = 5, + SpvImageFormatRg32f = 6, + SpvImageFormatRg16f = 7, + SpvImageFormatR11fG11fB10f = 8, + SpvImageFormatR16f = 9, + SpvImageFormatRgba16 = 10, + SpvImageFormatRgb10A2 = 11, + SpvImageFormatRg16 = 12, + SpvImageFormatRg8 = 13, + SpvImageFormatR16 = 14, + SpvImageFormatR8 = 15, + SpvImageFormatRgba16Snorm = 16, + SpvImageFormatRg16Snorm = 17, + SpvImageFormatRg8Snorm = 18, + SpvImageFormatR16Snorm = 19, + SpvImageFormatR8Snorm = 20, + SpvImageFormatRgba32i = 21, + SpvImageFormatRgba16i = 22, + SpvImageFormatRgba8i = 23, + SpvImageFormatR32i = 24, + SpvImageFormatRg32i = 25, + SpvImageFormatRg16i = 26, + SpvImageFormatRg8i = 27, + SpvImageFormatR16i = 28, + SpvImageFormatR8i = 29, + SpvImageFormatRgba32ui = 30, + SpvImageFormatRgba16ui = 31, + SpvImageFormatRgba8ui = 32, + SpvImageFormatR32ui = 33, + SpvImageFormatRgb10a2ui = 34, + SpvImageFormatRg32ui = 35, + SpvImageFormatRg16ui = 36, + SpvImageFormatRg8ui = 37, + SpvImageFormatR16ui = 38, + SpvImageFormatR8ui = 39, + SpvImageFormatR64ui = 40, + SpvImageFormatR64i = 41, + SpvImageFormatMax = 0x7fffffff, +} SpvImageFormat; + +typedef enum SpvImageChannelOrder_ { + SpvImageChannelOrderR = 0, + SpvImageChannelOrderA = 1, + SpvImageChannelOrderRG = 2, + SpvImageChannelOrderRA = 3, + SpvImageChannelOrderRGB = 4, + SpvImageChannelOrderRGBA = 5, + SpvImageChannelOrderBGRA = 6, + SpvImageChannelOrderARGB = 7, + SpvImageChannelOrderIntensity = 8, + SpvImageChannelOrderLuminance = 9, + SpvImageChannelOrderRx = 10, + SpvImageChannelOrderRGx = 11, + SpvImageChannelOrderRGBx = 12, + SpvImageChannelOrderDepth = 13, + SpvImageChannelOrderDepthStencil = 14, + SpvImageChannelOrdersRGB = 15, + SpvImageChannelOrdersRGBx = 16, + SpvImageChannelOrdersRGBA = 17, + SpvImageChannelOrdersBGRA = 18, + SpvImageChannelOrderABGR = 19, + SpvImageChannelOrderMax = 0x7fffffff, +} SpvImageChannelOrder; + +typedef enum SpvImageChannelDataType_ { + SpvImageChannelDataTypeSnormInt8 = 0, + SpvImageChannelDataTypeSnormInt16 = 1, + SpvImageChannelDataTypeUnormInt8 = 2, + SpvImageChannelDataTypeUnormInt16 = 3, + SpvImageChannelDataTypeUnormShort565 = 4, + SpvImageChannelDataTypeUnormShort555 = 5, + SpvImageChannelDataTypeUnormInt101010 = 6, + SpvImageChannelDataTypeSignedInt8 = 7, + SpvImageChannelDataTypeSignedInt16 = 8, + SpvImageChannelDataTypeSignedInt32 = 9, + SpvImageChannelDataTypeUnsignedInt8 = 10, + SpvImageChannelDataTypeUnsignedInt16 = 11, + SpvImageChannelDataTypeUnsignedInt32 = 12, + SpvImageChannelDataTypeHalfFloat = 13, + SpvImageChannelDataTypeFloat = 14, + SpvImageChannelDataTypeUnormInt24 = 15, + SpvImageChannelDataTypeUnormInt101010_2 = 16, + SpvImageChannelDataTypeMax = 0x7fffffff, +} SpvImageChannelDataType; + +typedef enum SpvImageOperandsShift_ { + SpvImageOperandsBiasShift = 0, + SpvImageOperandsLodShift = 1, + SpvImageOperandsGradShift = 2, + SpvImageOperandsConstOffsetShift = 3, + SpvImageOperandsOffsetShift = 4, + SpvImageOperandsConstOffsetsShift = 5, + SpvImageOperandsSampleShift = 6, + SpvImageOperandsMinLodShift = 7, + SpvImageOperandsMakeTexelAvailableShift = 8, + SpvImageOperandsMakeTexelAvailableKHRShift = 8, + SpvImageOperandsMakeTexelVisibleShift = 9, + SpvImageOperandsMakeTexelVisibleKHRShift = 9, + SpvImageOperandsNonPrivateTexelShift = 10, + SpvImageOperandsNonPrivateTexelKHRShift = 10, + SpvImageOperandsVolatileTexelShift = 11, + SpvImageOperandsVolatileTexelKHRShift = 11, + SpvImageOperandsSignExtendShift = 12, + SpvImageOperandsZeroExtendShift = 13, + SpvImageOperandsNontemporalShift = 14, + SpvImageOperandsOffsetsShift = 16, + SpvImageOperandsMax = 0x7fffffff, +} SpvImageOperandsShift; + +typedef enum SpvImageOperandsMask_ { + SpvImageOperandsMaskNone = 0, + SpvImageOperandsBiasMask = 0x00000001, + SpvImageOperandsLodMask = 0x00000002, + SpvImageOperandsGradMask = 0x00000004, + SpvImageOperandsConstOffsetMask = 0x00000008, + SpvImageOperandsOffsetMask = 0x00000010, + SpvImageOperandsConstOffsetsMask = 0x00000020, + SpvImageOperandsSampleMask = 0x00000040, + SpvImageOperandsMinLodMask = 0x00000080, + SpvImageOperandsMakeTexelAvailableMask = 0x00000100, + SpvImageOperandsMakeTexelAvailableKHRMask = 0x00000100, + SpvImageOperandsMakeTexelVisibleMask = 0x00000200, + SpvImageOperandsMakeTexelVisibleKHRMask = 0x00000200, + SpvImageOperandsNonPrivateTexelMask = 0x00000400, + SpvImageOperandsNonPrivateTexelKHRMask = 0x00000400, + SpvImageOperandsVolatileTexelMask = 0x00000800, + SpvImageOperandsVolatileTexelKHRMask = 0x00000800, + SpvImageOperandsSignExtendMask = 0x00001000, + SpvImageOperandsZeroExtendMask = 0x00002000, + SpvImageOperandsNontemporalMask = 0x00004000, + SpvImageOperandsOffsetsMask = 0x00010000, +} SpvImageOperandsMask; + +typedef enum SpvFPFastMathModeShift_ { + SpvFPFastMathModeNotNaNShift = 0, + SpvFPFastMathModeNotInfShift = 1, + SpvFPFastMathModeNSZShift = 2, + SpvFPFastMathModeAllowRecipShift = 3, + SpvFPFastMathModeFastShift = 4, + SpvFPFastMathModeAllowContractFastINTELShift = 16, + SpvFPFastMathModeAllowReassocINTELShift = 17, + SpvFPFastMathModeMax = 0x7fffffff, +} SpvFPFastMathModeShift; + +typedef enum SpvFPFastMathModeMask_ { + SpvFPFastMathModeMaskNone = 0, + SpvFPFastMathModeNotNaNMask = 0x00000001, + SpvFPFastMathModeNotInfMask = 0x00000002, + SpvFPFastMathModeNSZMask = 0x00000004, + SpvFPFastMathModeAllowRecipMask = 0x00000008, + SpvFPFastMathModeFastMask = 0x00000010, + SpvFPFastMathModeAllowContractFastINTELMask = 0x00010000, + SpvFPFastMathModeAllowReassocINTELMask = 0x00020000, +} SpvFPFastMathModeMask; + +typedef enum SpvFPRoundingMode_ { + SpvFPRoundingModeRTE = 0, + SpvFPRoundingModeRTZ = 1, + SpvFPRoundingModeRTP = 2, + SpvFPRoundingModeRTN = 3, + SpvFPRoundingModeMax = 0x7fffffff, +} SpvFPRoundingMode; + +typedef enum SpvLinkageType_ { + SpvLinkageTypeExport = 0, + SpvLinkageTypeImport = 1, + SpvLinkageTypeLinkOnceODR = 2, + SpvLinkageTypeMax = 0x7fffffff, +} SpvLinkageType; + +typedef enum SpvAccessQualifier_ { + SpvAccessQualifierReadOnly = 0, + SpvAccessQualifierWriteOnly = 1, + SpvAccessQualifierReadWrite = 2, + SpvAccessQualifierMax = 0x7fffffff, +} SpvAccessQualifier; + +typedef enum SpvFunctionParameterAttribute_ { + SpvFunctionParameterAttributeZext = 0, + SpvFunctionParameterAttributeSext = 1, + SpvFunctionParameterAttributeByVal = 2, + SpvFunctionParameterAttributeSret = 3, + SpvFunctionParameterAttributeNoAlias = 4, + SpvFunctionParameterAttributeNoCapture = 5, + SpvFunctionParameterAttributeNoWrite = 6, + SpvFunctionParameterAttributeNoReadWrite = 7, + SpvFunctionParameterAttributeMax = 0x7fffffff, +} SpvFunctionParameterAttribute; + +typedef enum SpvDecoration_ { + SpvDecorationRelaxedPrecision = 0, + SpvDecorationSpecId = 1, + SpvDecorationBlock = 2, + SpvDecorationBufferBlock = 3, + SpvDecorationRowMajor = 4, + SpvDecorationColMajor = 5, + SpvDecorationArrayStride = 6, + SpvDecorationMatrixStride = 7, + SpvDecorationGLSLShared = 8, + SpvDecorationGLSLPacked = 9, + SpvDecorationCPacked = 10, + SpvDecorationBuiltIn = 11, + SpvDecorationNoPerspective = 13, + SpvDecorationFlat = 14, + SpvDecorationPatch = 15, + SpvDecorationCentroid = 16, + SpvDecorationSample = 17, + SpvDecorationInvariant = 18, + SpvDecorationRestrict = 19, + SpvDecorationAliased = 20, + SpvDecorationVolatile = 21, + SpvDecorationConstant = 22, + SpvDecorationCoherent = 23, + SpvDecorationNonWritable = 24, + SpvDecorationNonReadable = 25, + SpvDecorationUniform = 26, + SpvDecorationUniformId = 27, + SpvDecorationSaturatedConversion = 28, + SpvDecorationStream = 29, + SpvDecorationLocation = 30, + SpvDecorationComponent = 31, + SpvDecorationIndex = 32, + SpvDecorationBinding = 33, + SpvDecorationDescriptorSet = 34, + SpvDecorationOffset = 35, + SpvDecorationXfbBuffer = 36, + SpvDecorationXfbStride = 37, + SpvDecorationFuncParamAttr = 38, + SpvDecorationFPRoundingMode = 39, + SpvDecorationFPFastMathMode = 40, + SpvDecorationLinkageAttributes = 41, + SpvDecorationNoContraction = 42, + SpvDecorationInputAttachmentIndex = 43, + SpvDecorationAlignment = 44, + SpvDecorationMaxByteOffset = 45, + SpvDecorationAlignmentId = 46, + SpvDecorationMaxByteOffsetId = 47, + SpvDecorationNoSignedWrap = 4469, + SpvDecorationNoUnsignedWrap = 4470, + SpvDecorationExplicitInterpAMD = 4999, + SpvDecorationOverrideCoverageNV = 5248, + SpvDecorationPassthroughNV = 5250, + SpvDecorationViewportRelativeNV = 5252, + SpvDecorationSecondaryViewportRelativeNV = 5256, + SpvDecorationPerPrimitiveNV = 5271, + SpvDecorationPerViewNV = 5272, + SpvDecorationPerTaskNV = 5273, + SpvDecorationPerVertexKHR = 5285, + SpvDecorationPerVertexNV = 5285, + SpvDecorationNonUniform = 5300, + SpvDecorationNonUniformEXT = 5300, + SpvDecorationRestrictPointer = 5355, + SpvDecorationRestrictPointerEXT = 5355, + SpvDecorationAliasedPointer = 5356, + SpvDecorationAliasedPointerEXT = 5356, + SpvDecorationBindlessSamplerNV = 5398, + SpvDecorationBindlessImageNV = 5399, + SpvDecorationBoundSamplerNV = 5400, + SpvDecorationBoundImageNV = 5401, + SpvDecorationSIMTCallINTEL = 5599, + SpvDecorationReferencedIndirectlyINTEL = 5602, + SpvDecorationClobberINTEL = 5607, + SpvDecorationSideEffectsINTEL = 5608, + SpvDecorationVectorComputeVariableINTEL = 5624, + SpvDecorationFuncParamIOKindINTEL = 5625, + SpvDecorationVectorComputeFunctionINTEL = 5626, + SpvDecorationStackCallINTEL = 5627, + SpvDecorationGlobalVariableOffsetINTEL = 5628, + SpvDecorationCounterBuffer = 5634, + SpvDecorationHlslCounterBufferGOOGLE = 5634, + SpvDecorationHlslSemanticGOOGLE = 5635, + SpvDecorationUserSemantic = 5635, + SpvDecorationUserTypeGOOGLE = 5636, + SpvDecorationFunctionRoundingModeINTEL = 5822, + SpvDecorationFunctionDenormModeINTEL = 5823, + SpvDecorationRegisterINTEL = 5825, + SpvDecorationMemoryINTEL = 5826, + SpvDecorationNumbanksINTEL = 5827, + SpvDecorationBankwidthINTEL = 5828, + SpvDecorationMaxPrivateCopiesINTEL = 5829, + SpvDecorationSinglepumpINTEL = 5830, + SpvDecorationDoublepumpINTEL = 5831, + SpvDecorationMaxReplicatesINTEL = 5832, + SpvDecorationSimpleDualPortINTEL = 5833, + SpvDecorationMergeINTEL = 5834, + SpvDecorationBankBitsINTEL = 5835, + SpvDecorationForcePow2DepthINTEL = 5836, + SpvDecorationBurstCoalesceINTEL = 5899, + SpvDecorationCacheSizeINTEL = 5900, + SpvDecorationDontStaticallyCoalesceINTEL = 5901, + SpvDecorationPrefetchINTEL = 5902, + SpvDecorationStallEnableINTEL = 5905, + SpvDecorationFuseLoopsInFunctionINTEL = 5907, + SpvDecorationAliasScopeINTEL = 5914, + SpvDecorationNoAliasINTEL = 5915, + SpvDecorationBufferLocationINTEL = 5921, + SpvDecorationIOPipeStorageINTEL = 5944, + SpvDecorationFunctionFloatingPointModeINTEL = 6080, + SpvDecorationSingleElementVectorINTEL = 6085, + SpvDecorationVectorComputeCallableFunctionINTEL = 6087, + SpvDecorationMediaBlockIOINTEL = 6140, + SpvDecorationMax = 0x7fffffff, +} SpvDecoration; + +typedef enum SpvBuiltIn_ { + SpvBuiltInPosition = 0, + SpvBuiltInPointSize = 1, + SpvBuiltInClipDistance = 3, + SpvBuiltInCullDistance = 4, + SpvBuiltInVertexId = 5, + SpvBuiltInInstanceId = 6, + SpvBuiltInPrimitiveId = 7, + SpvBuiltInInvocationId = 8, + SpvBuiltInLayer = 9, + SpvBuiltInViewportIndex = 10, + SpvBuiltInTessLevelOuter = 11, + SpvBuiltInTessLevelInner = 12, + SpvBuiltInTessCoord = 13, + SpvBuiltInPatchVertices = 14, + SpvBuiltInFragCoord = 15, + SpvBuiltInPointCoord = 16, + SpvBuiltInFrontFacing = 17, + SpvBuiltInSampleId = 18, + SpvBuiltInSamplePosition = 19, + SpvBuiltInSampleMask = 20, + SpvBuiltInFragDepth = 22, + SpvBuiltInHelperInvocation = 23, + SpvBuiltInNumWorkgroups = 24, + SpvBuiltInWorkgroupSize = 25, + SpvBuiltInWorkgroupId = 26, + SpvBuiltInLocalInvocationId = 27, + SpvBuiltInGlobalInvocationId = 28, + SpvBuiltInLocalInvocationIndex = 29, + SpvBuiltInWorkDim = 30, + SpvBuiltInGlobalSize = 31, + SpvBuiltInEnqueuedWorkgroupSize = 32, + SpvBuiltInGlobalOffset = 33, + SpvBuiltInGlobalLinearId = 34, + SpvBuiltInSubgroupSize = 36, + SpvBuiltInSubgroupMaxSize = 37, + SpvBuiltInNumSubgroups = 38, + SpvBuiltInNumEnqueuedSubgroups = 39, + SpvBuiltInSubgroupId = 40, + SpvBuiltInSubgroupLocalInvocationId = 41, + SpvBuiltInVertexIndex = 42, + SpvBuiltInInstanceIndex = 43, + SpvBuiltInSubgroupEqMask = 4416, + SpvBuiltInSubgroupEqMaskKHR = 4416, + SpvBuiltInSubgroupGeMask = 4417, + SpvBuiltInSubgroupGeMaskKHR = 4417, + SpvBuiltInSubgroupGtMask = 4418, + SpvBuiltInSubgroupGtMaskKHR = 4418, + SpvBuiltInSubgroupLeMask = 4419, + SpvBuiltInSubgroupLeMaskKHR = 4419, + SpvBuiltInSubgroupLtMask = 4420, + SpvBuiltInSubgroupLtMaskKHR = 4420, + SpvBuiltInBaseVertex = 4424, + SpvBuiltInBaseInstance = 4425, + SpvBuiltInDrawIndex = 4426, + SpvBuiltInPrimitiveShadingRateKHR = 4432, + SpvBuiltInDeviceIndex = 4438, + SpvBuiltInViewIndex = 4440, + SpvBuiltInShadingRateKHR = 4444, + SpvBuiltInBaryCoordNoPerspAMD = 4992, + SpvBuiltInBaryCoordNoPerspCentroidAMD = 4993, + SpvBuiltInBaryCoordNoPerspSampleAMD = 4994, + SpvBuiltInBaryCoordSmoothAMD = 4995, + SpvBuiltInBaryCoordSmoothCentroidAMD = 4996, + SpvBuiltInBaryCoordSmoothSampleAMD = 4997, + SpvBuiltInBaryCoordPullModelAMD = 4998, + SpvBuiltInFragStencilRefEXT = 5014, + SpvBuiltInViewportMaskNV = 5253, + SpvBuiltInSecondaryPositionNV = 5257, + SpvBuiltInSecondaryViewportMaskNV = 5258, + SpvBuiltInPositionPerViewNV = 5261, + SpvBuiltInViewportMaskPerViewNV = 5262, + SpvBuiltInFullyCoveredEXT = 5264, + SpvBuiltInTaskCountNV = 5274, + SpvBuiltInPrimitiveCountNV = 5275, + SpvBuiltInPrimitiveIndicesNV = 5276, + SpvBuiltInClipDistancePerViewNV = 5277, + SpvBuiltInCullDistancePerViewNV = 5278, + SpvBuiltInLayerPerViewNV = 5279, + SpvBuiltInMeshViewCountNV = 5280, + SpvBuiltInMeshViewIndicesNV = 5281, + SpvBuiltInBaryCoordKHR = 5286, + SpvBuiltInBaryCoordNV = 5286, + SpvBuiltInBaryCoordNoPerspKHR = 5287, + SpvBuiltInBaryCoordNoPerspNV = 5287, + SpvBuiltInFragSizeEXT = 5292, + SpvBuiltInFragmentSizeNV = 5292, + SpvBuiltInFragInvocationCountEXT = 5293, + SpvBuiltInInvocationsPerPixelNV = 5293, + SpvBuiltInLaunchIdKHR = 5319, + SpvBuiltInLaunchIdNV = 5319, + SpvBuiltInLaunchSizeKHR = 5320, + SpvBuiltInLaunchSizeNV = 5320, + SpvBuiltInWorldRayOriginKHR = 5321, + SpvBuiltInWorldRayOriginNV = 5321, + SpvBuiltInWorldRayDirectionKHR = 5322, + SpvBuiltInWorldRayDirectionNV = 5322, + SpvBuiltInObjectRayOriginKHR = 5323, + SpvBuiltInObjectRayOriginNV = 5323, + SpvBuiltInObjectRayDirectionKHR = 5324, + SpvBuiltInObjectRayDirectionNV = 5324, + SpvBuiltInRayTminKHR = 5325, + SpvBuiltInRayTminNV = 5325, + SpvBuiltInRayTmaxKHR = 5326, + SpvBuiltInRayTmaxNV = 5326, + SpvBuiltInInstanceCustomIndexKHR = 5327, + SpvBuiltInInstanceCustomIndexNV = 5327, + SpvBuiltInObjectToWorldKHR = 5330, + SpvBuiltInObjectToWorldNV = 5330, + SpvBuiltInWorldToObjectKHR = 5331, + SpvBuiltInWorldToObjectNV = 5331, + SpvBuiltInHitTNV = 5332, + SpvBuiltInHitKindKHR = 5333, + SpvBuiltInHitKindNV = 5333, + SpvBuiltInCurrentRayTimeNV = 5334, + SpvBuiltInIncomingRayFlagsKHR = 5351, + SpvBuiltInIncomingRayFlagsNV = 5351, + SpvBuiltInRayGeometryIndexKHR = 5352, + SpvBuiltInWarpsPerSMNV = 5374, + SpvBuiltInSMCountNV = 5375, + SpvBuiltInWarpIDNV = 5376, + SpvBuiltInSMIDNV = 5377, + SpvBuiltInMax = 0x7fffffff, +} SpvBuiltIn; + +typedef enum SpvSelectionControlShift_ { + SpvSelectionControlFlattenShift = 0, + SpvSelectionControlDontFlattenShift = 1, + SpvSelectionControlMax = 0x7fffffff, +} SpvSelectionControlShift; + +typedef enum SpvSelectionControlMask_ { + SpvSelectionControlMaskNone = 0, + SpvSelectionControlFlattenMask = 0x00000001, + SpvSelectionControlDontFlattenMask = 0x00000002, +} SpvSelectionControlMask; + +typedef enum SpvLoopControlShift_ { + SpvLoopControlUnrollShift = 0, + SpvLoopControlDontUnrollShift = 1, + SpvLoopControlDependencyInfiniteShift = 2, + SpvLoopControlDependencyLengthShift = 3, + SpvLoopControlMinIterationsShift = 4, + SpvLoopControlMaxIterationsShift = 5, + SpvLoopControlIterationMultipleShift = 6, + SpvLoopControlPeelCountShift = 7, + SpvLoopControlPartialCountShift = 8, + SpvLoopControlInitiationIntervalINTELShift = 16, + SpvLoopControlMaxConcurrencyINTELShift = 17, + SpvLoopControlDependencyArrayINTELShift = 18, + SpvLoopControlPipelineEnableINTELShift = 19, + SpvLoopControlLoopCoalesceINTELShift = 20, + SpvLoopControlMaxInterleavingINTELShift = 21, + SpvLoopControlSpeculatedIterationsINTELShift = 22, + SpvLoopControlNoFusionINTELShift = 23, + SpvLoopControlMax = 0x7fffffff, +} SpvLoopControlShift; + +typedef enum SpvLoopControlMask_ { + SpvLoopControlMaskNone = 0, + SpvLoopControlUnrollMask = 0x00000001, + SpvLoopControlDontUnrollMask = 0x00000002, + SpvLoopControlDependencyInfiniteMask = 0x00000004, + SpvLoopControlDependencyLengthMask = 0x00000008, + SpvLoopControlMinIterationsMask = 0x00000010, + SpvLoopControlMaxIterationsMask = 0x00000020, + SpvLoopControlIterationMultipleMask = 0x00000040, + SpvLoopControlPeelCountMask = 0x00000080, + SpvLoopControlPartialCountMask = 0x00000100, + SpvLoopControlInitiationIntervalINTELMask = 0x00010000, + SpvLoopControlMaxConcurrencyINTELMask = 0x00020000, + SpvLoopControlDependencyArrayINTELMask = 0x00040000, + SpvLoopControlPipelineEnableINTELMask = 0x00080000, + SpvLoopControlLoopCoalesceINTELMask = 0x00100000, + SpvLoopControlMaxInterleavingINTELMask = 0x00200000, + SpvLoopControlSpeculatedIterationsINTELMask = 0x00400000, + SpvLoopControlNoFusionINTELMask = 0x00800000, +} SpvLoopControlMask; + +typedef enum SpvFunctionControlShift_ { + SpvFunctionControlInlineShift = 0, + SpvFunctionControlDontInlineShift = 1, + SpvFunctionControlPureShift = 2, + SpvFunctionControlConstShift = 3, + SpvFunctionControlOptNoneINTELShift = 16, + SpvFunctionControlMax = 0x7fffffff, +} SpvFunctionControlShift; + +typedef enum SpvFunctionControlMask_ { + SpvFunctionControlMaskNone = 0, + SpvFunctionControlInlineMask = 0x00000001, + SpvFunctionControlDontInlineMask = 0x00000002, + SpvFunctionControlPureMask = 0x00000004, + SpvFunctionControlConstMask = 0x00000008, + SpvFunctionControlOptNoneINTELMask = 0x00010000, +} SpvFunctionControlMask; + +typedef enum SpvMemorySemanticsShift_ { + SpvMemorySemanticsAcquireShift = 1, + SpvMemorySemanticsReleaseShift = 2, + SpvMemorySemanticsAcquireReleaseShift = 3, + SpvMemorySemanticsSequentiallyConsistentShift = 4, + SpvMemorySemanticsUniformMemoryShift = 6, + SpvMemorySemanticsSubgroupMemoryShift = 7, + SpvMemorySemanticsWorkgroupMemoryShift = 8, + SpvMemorySemanticsCrossWorkgroupMemoryShift = 9, + SpvMemorySemanticsAtomicCounterMemoryShift = 10, + SpvMemorySemanticsImageMemoryShift = 11, + SpvMemorySemanticsOutputMemoryShift = 12, + SpvMemorySemanticsOutputMemoryKHRShift = 12, + SpvMemorySemanticsMakeAvailableShift = 13, + SpvMemorySemanticsMakeAvailableKHRShift = 13, + SpvMemorySemanticsMakeVisibleShift = 14, + SpvMemorySemanticsMakeVisibleKHRShift = 14, + SpvMemorySemanticsVolatileShift = 15, + SpvMemorySemanticsMax = 0x7fffffff, +} SpvMemorySemanticsShift; + +typedef enum SpvMemorySemanticsMask_ { + SpvMemorySemanticsMaskNone = 0, + SpvMemorySemanticsAcquireMask = 0x00000002, + SpvMemorySemanticsReleaseMask = 0x00000004, + SpvMemorySemanticsAcquireReleaseMask = 0x00000008, + SpvMemorySemanticsSequentiallyConsistentMask = 0x00000010, + SpvMemorySemanticsUniformMemoryMask = 0x00000040, + SpvMemorySemanticsSubgroupMemoryMask = 0x00000080, + SpvMemorySemanticsWorkgroupMemoryMask = 0x00000100, + SpvMemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, + SpvMemorySemanticsAtomicCounterMemoryMask = 0x00000400, + SpvMemorySemanticsImageMemoryMask = 0x00000800, + SpvMemorySemanticsOutputMemoryMask = 0x00001000, + SpvMemorySemanticsOutputMemoryKHRMask = 0x00001000, + SpvMemorySemanticsMakeAvailableMask = 0x00002000, + SpvMemorySemanticsMakeAvailableKHRMask = 0x00002000, + SpvMemorySemanticsMakeVisibleMask = 0x00004000, + SpvMemorySemanticsMakeVisibleKHRMask = 0x00004000, + SpvMemorySemanticsVolatileMask = 0x00008000, +} SpvMemorySemanticsMask; + +typedef enum SpvMemoryAccessShift_ { + SpvMemoryAccessVolatileShift = 0, + SpvMemoryAccessAlignedShift = 1, + SpvMemoryAccessNontemporalShift = 2, + SpvMemoryAccessMakePointerAvailableShift = 3, + SpvMemoryAccessMakePointerAvailableKHRShift = 3, + SpvMemoryAccessMakePointerVisibleShift = 4, + SpvMemoryAccessMakePointerVisibleKHRShift = 4, + SpvMemoryAccessNonPrivatePointerShift = 5, + SpvMemoryAccessNonPrivatePointerKHRShift = 5, + SpvMemoryAccessAliasScopeINTELMaskShift = 16, + SpvMemoryAccessNoAliasINTELMaskShift = 17, + SpvMemoryAccessMax = 0x7fffffff, +} SpvMemoryAccessShift; + +typedef enum SpvMemoryAccessMask_ { + SpvMemoryAccessMaskNone = 0, + SpvMemoryAccessVolatileMask = 0x00000001, + SpvMemoryAccessAlignedMask = 0x00000002, + SpvMemoryAccessNontemporalMask = 0x00000004, + SpvMemoryAccessMakePointerAvailableMask = 0x00000008, + SpvMemoryAccessMakePointerAvailableKHRMask = 0x00000008, + SpvMemoryAccessMakePointerVisibleMask = 0x00000010, + SpvMemoryAccessMakePointerVisibleKHRMask = 0x00000010, + SpvMemoryAccessNonPrivatePointerMask = 0x00000020, + SpvMemoryAccessNonPrivatePointerKHRMask = 0x00000020, + SpvMemoryAccessAliasScopeINTELMaskMask = 0x00010000, + SpvMemoryAccessNoAliasINTELMaskMask = 0x00020000, +} SpvMemoryAccessMask; + +typedef enum SpvScope_ { + SpvScopeCrossDevice = 0, + SpvScopeDevice = 1, + SpvScopeWorkgroup = 2, + SpvScopeSubgroup = 3, + SpvScopeInvocation = 4, + SpvScopeQueueFamily = 5, + SpvScopeQueueFamilyKHR = 5, + SpvScopeShaderCallKHR = 6, + SpvScopeMax = 0x7fffffff, +} SpvScope; + +typedef enum SpvGroupOperation_ { + SpvGroupOperationReduce = 0, + SpvGroupOperationInclusiveScan = 1, + SpvGroupOperationExclusiveScan = 2, + SpvGroupOperationClusteredReduce = 3, + SpvGroupOperationPartitionedReduceNV = 6, + SpvGroupOperationPartitionedInclusiveScanNV = 7, + SpvGroupOperationPartitionedExclusiveScanNV = 8, + SpvGroupOperationMax = 0x7fffffff, +} SpvGroupOperation; + +typedef enum SpvKernelEnqueueFlags_ { + SpvKernelEnqueueFlagsNoWait = 0, + SpvKernelEnqueueFlagsWaitKernel = 1, + SpvKernelEnqueueFlagsWaitWorkGroup = 2, + SpvKernelEnqueueFlagsMax = 0x7fffffff, +} SpvKernelEnqueueFlags; + +typedef enum SpvKernelProfilingInfoShift_ { + SpvKernelProfilingInfoCmdExecTimeShift = 0, + SpvKernelProfilingInfoMax = 0x7fffffff, +} SpvKernelProfilingInfoShift; + +typedef enum SpvKernelProfilingInfoMask_ { + SpvKernelProfilingInfoMaskNone = 0, + SpvKernelProfilingInfoCmdExecTimeMask = 0x00000001, +} SpvKernelProfilingInfoMask; + +typedef enum SpvCapability_ { + SpvCapabilityMatrix = 0, + SpvCapabilityShader = 1, + SpvCapabilityGeometry = 2, + SpvCapabilityTessellation = 3, + SpvCapabilityAddresses = 4, + SpvCapabilityLinkage = 5, + SpvCapabilityKernel = 6, + SpvCapabilityVector16 = 7, + SpvCapabilityFloat16Buffer = 8, + SpvCapabilityFloat16 = 9, + SpvCapabilityFloat64 = 10, + SpvCapabilityInt64 = 11, + SpvCapabilityInt64Atomics = 12, + SpvCapabilityImageBasic = 13, + SpvCapabilityImageReadWrite = 14, + SpvCapabilityImageMipmap = 15, + SpvCapabilityPipes = 17, + SpvCapabilityGroups = 18, + SpvCapabilityDeviceEnqueue = 19, + SpvCapabilityLiteralSampler = 20, + SpvCapabilityAtomicStorage = 21, + SpvCapabilityInt16 = 22, + SpvCapabilityTessellationPointSize = 23, + SpvCapabilityGeometryPointSize = 24, + SpvCapabilityImageGatherExtended = 25, + SpvCapabilityStorageImageMultisample = 27, + SpvCapabilityUniformBufferArrayDynamicIndexing = 28, + SpvCapabilitySampledImageArrayDynamicIndexing = 29, + SpvCapabilityStorageBufferArrayDynamicIndexing = 30, + SpvCapabilityStorageImageArrayDynamicIndexing = 31, + SpvCapabilityClipDistance = 32, + SpvCapabilityCullDistance = 33, + SpvCapabilityImageCubeArray = 34, + SpvCapabilitySampleRateShading = 35, + SpvCapabilityImageRect = 36, + SpvCapabilitySampledRect = 37, + SpvCapabilityGenericPointer = 38, + SpvCapabilityInt8 = 39, + SpvCapabilityInputAttachment = 40, + SpvCapabilitySparseResidency = 41, + SpvCapabilityMinLod = 42, + SpvCapabilitySampled1D = 43, + SpvCapabilityImage1D = 44, + SpvCapabilitySampledCubeArray = 45, + SpvCapabilitySampledBuffer = 46, + SpvCapabilityImageBuffer = 47, + SpvCapabilityImageMSArray = 48, + SpvCapabilityStorageImageExtendedFormats = 49, + SpvCapabilityImageQuery = 50, + SpvCapabilityDerivativeControl = 51, + SpvCapabilityInterpolationFunction = 52, + SpvCapabilityTransformFeedback = 53, + SpvCapabilityGeometryStreams = 54, + SpvCapabilityStorageImageReadWithoutFormat = 55, + SpvCapabilityStorageImageWriteWithoutFormat = 56, + SpvCapabilityMultiViewport = 57, + SpvCapabilitySubgroupDispatch = 58, + SpvCapabilityNamedBarrier = 59, + SpvCapabilityPipeStorage = 60, + SpvCapabilityGroupNonUniform = 61, + SpvCapabilityGroupNonUniformVote = 62, + SpvCapabilityGroupNonUniformArithmetic = 63, + SpvCapabilityGroupNonUniformBallot = 64, + SpvCapabilityGroupNonUniformShuffle = 65, + SpvCapabilityGroupNonUniformShuffleRelative = 66, + SpvCapabilityGroupNonUniformClustered = 67, + SpvCapabilityGroupNonUniformQuad = 68, + SpvCapabilityShaderLayer = 69, + SpvCapabilityShaderViewportIndex = 70, + SpvCapabilityUniformDecoration = 71, + SpvCapabilityFragmentShadingRateKHR = 4422, + SpvCapabilitySubgroupBallotKHR = 4423, + SpvCapabilityDrawParameters = 4427, + SpvCapabilityWorkgroupMemoryExplicitLayoutKHR = 4428, + SpvCapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR = 4429, + SpvCapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR = 4430, + SpvCapabilitySubgroupVoteKHR = 4431, + SpvCapabilityStorageBuffer16BitAccess = 4433, + SpvCapabilityStorageUniformBufferBlock16 = 4433, + SpvCapabilityStorageUniform16 = 4434, + SpvCapabilityUniformAndStorageBuffer16BitAccess = 4434, + SpvCapabilityStoragePushConstant16 = 4435, + SpvCapabilityStorageInputOutput16 = 4436, + SpvCapabilityDeviceGroup = 4437, + SpvCapabilityMultiView = 4439, + SpvCapabilityVariablePointersStorageBuffer = 4441, + SpvCapabilityVariablePointers = 4442, + SpvCapabilityAtomicStorageOps = 4445, + SpvCapabilitySampleMaskPostDepthCoverage = 4447, + SpvCapabilityStorageBuffer8BitAccess = 4448, + SpvCapabilityUniformAndStorageBuffer8BitAccess = 4449, + SpvCapabilityStoragePushConstant8 = 4450, + SpvCapabilityDenormPreserve = 4464, + SpvCapabilityDenormFlushToZero = 4465, + SpvCapabilitySignedZeroInfNanPreserve = 4466, + SpvCapabilityRoundingModeRTE = 4467, + SpvCapabilityRoundingModeRTZ = 4468, + SpvCapabilityRayQueryProvisionalKHR = 4471, + SpvCapabilityRayQueryKHR = 4472, + SpvCapabilityRayTraversalPrimitiveCullingKHR = 4478, + SpvCapabilityRayTracingKHR = 4479, + SpvCapabilityFloat16ImageAMD = 5008, + SpvCapabilityImageGatherBiasLodAMD = 5009, + SpvCapabilityFragmentMaskAMD = 5010, + SpvCapabilityStencilExportEXT = 5013, + SpvCapabilityImageReadWriteLodAMD = 5015, + SpvCapabilityInt64ImageEXT = 5016, + SpvCapabilityShaderClockKHR = 5055, + SpvCapabilitySampleMaskOverrideCoverageNV = 5249, + SpvCapabilityGeometryShaderPassthroughNV = 5251, + SpvCapabilityShaderViewportIndexLayerEXT = 5254, + SpvCapabilityShaderViewportIndexLayerNV = 5254, + SpvCapabilityShaderViewportMaskNV = 5255, + SpvCapabilityShaderStereoViewNV = 5259, + SpvCapabilityPerViewAttributesNV = 5260, + SpvCapabilityFragmentFullyCoveredEXT = 5265, + SpvCapabilityMeshShadingNV = 5266, + SpvCapabilityImageFootprintNV = 5282, + SpvCapabilityFragmentBarycentricKHR = 5284, + SpvCapabilityFragmentBarycentricNV = 5284, + SpvCapabilityComputeDerivativeGroupQuadsNV = 5288, + SpvCapabilityFragmentDensityEXT = 5291, + SpvCapabilityShadingRateNV = 5291, + SpvCapabilityGroupNonUniformPartitionedNV = 5297, + SpvCapabilityShaderNonUniform = 5301, + SpvCapabilityShaderNonUniformEXT = 5301, + SpvCapabilityRuntimeDescriptorArray = 5302, + SpvCapabilityRuntimeDescriptorArrayEXT = 5302, + SpvCapabilityInputAttachmentArrayDynamicIndexing = 5303, + SpvCapabilityInputAttachmentArrayDynamicIndexingEXT = 5303, + SpvCapabilityUniformTexelBufferArrayDynamicIndexing = 5304, + SpvCapabilityUniformTexelBufferArrayDynamicIndexingEXT = 5304, + SpvCapabilityStorageTexelBufferArrayDynamicIndexing = 5305, + SpvCapabilityStorageTexelBufferArrayDynamicIndexingEXT = 5305, + SpvCapabilityUniformBufferArrayNonUniformIndexing = 5306, + SpvCapabilityUniformBufferArrayNonUniformIndexingEXT = 5306, + SpvCapabilitySampledImageArrayNonUniformIndexing = 5307, + SpvCapabilitySampledImageArrayNonUniformIndexingEXT = 5307, + SpvCapabilityStorageBufferArrayNonUniformIndexing = 5308, + SpvCapabilityStorageBufferArrayNonUniformIndexingEXT = 5308, + SpvCapabilityStorageImageArrayNonUniformIndexing = 5309, + SpvCapabilityStorageImageArrayNonUniformIndexingEXT = 5309, + SpvCapabilityInputAttachmentArrayNonUniformIndexing = 5310, + SpvCapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310, + SpvCapabilityUniformTexelBufferArrayNonUniformIndexing = 5311, + SpvCapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311, + SpvCapabilityStorageTexelBufferArrayNonUniformIndexing = 5312, + SpvCapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312, + SpvCapabilityRayTracingNV = 5340, + SpvCapabilityRayTracingMotionBlurNV = 5341, + SpvCapabilityVulkanMemoryModel = 5345, + SpvCapabilityVulkanMemoryModelKHR = 5345, + SpvCapabilityVulkanMemoryModelDeviceScope = 5346, + SpvCapabilityVulkanMemoryModelDeviceScopeKHR = 5346, + SpvCapabilityPhysicalStorageBufferAddresses = 5347, + SpvCapabilityPhysicalStorageBufferAddressesEXT = 5347, + SpvCapabilityComputeDerivativeGroupLinearNV = 5350, + SpvCapabilityRayTracingProvisionalKHR = 5353, + SpvCapabilityCooperativeMatrixNV = 5357, + SpvCapabilityFragmentShaderSampleInterlockEXT = 5363, + SpvCapabilityFragmentShaderShadingRateInterlockEXT = 5372, + SpvCapabilityShaderSMBuiltinsNV = 5373, + SpvCapabilityFragmentShaderPixelInterlockEXT = 5378, + SpvCapabilityDemoteToHelperInvocation = 5379, + SpvCapabilityDemoteToHelperInvocationEXT = 5379, + SpvCapabilityBindlessTextureNV = 5390, + SpvCapabilitySubgroupShuffleINTEL = 5568, + SpvCapabilitySubgroupBufferBlockIOINTEL = 5569, + SpvCapabilitySubgroupImageBlockIOINTEL = 5570, + SpvCapabilitySubgroupImageMediaBlockIOINTEL = 5579, + SpvCapabilityRoundToInfinityINTEL = 5582, + SpvCapabilityFloatingPointModeINTEL = 5583, + SpvCapabilityIntegerFunctions2INTEL = 5584, + SpvCapabilityFunctionPointersINTEL = 5603, + SpvCapabilityIndirectReferencesINTEL = 5604, + SpvCapabilityAsmINTEL = 5606, + SpvCapabilityAtomicFloat32MinMaxEXT = 5612, + SpvCapabilityAtomicFloat64MinMaxEXT = 5613, + SpvCapabilityAtomicFloat16MinMaxEXT = 5616, + SpvCapabilityVectorComputeINTEL = 5617, + SpvCapabilityVectorAnyINTEL = 5619, + SpvCapabilityExpectAssumeKHR = 5629, + SpvCapabilitySubgroupAvcMotionEstimationINTEL = 5696, + SpvCapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697, + SpvCapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698, + SpvCapabilityVariableLengthArrayINTEL = 5817, + SpvCapabilityFunctionFloatControlINTEL = 5821, + SpvCapabilityFPGAMemoryAttributesINTEL = 5824, + SpvCapabilityFPFastMathModeINTEL = 5837, + SpvCapabilityArbitraryPrecisionIntegersINTEL = 5844, + SpvCapabilityArbitraryPrecisionFloatingPointINTEL = 5845, + SpvCapabilityUnstructuredLoopControlsINTEL = 5886, + SpvCapabilityFPGALoopControlsINTEL = 5888, + SpvCapabilityKernelAttributesINTEL = 5892, + SpvCapabilityFPGAKernelAttributesINTEL = 5897, + SpvCapabilityFPGAMemoryAccessesINTEL = 5898, + SpvCapabilityFPGAClusterAttributesINTEL = 5904, + SpvCapabilityLoopFuseINTEL = 5906, + SpvCapabilityMemoryAccessAliasingINTEL = 5910, + SpvCapabilityFPGABufferLocationINTEL = 5920, + SpvCapabilityArbitraryPrecisionFixedPointINTEL = 5922, + SpvCapabilityUSMStorageClassesINTEL = 5935, + SpvCapabilityIOPipesINTEL = 5943, + SpvCapabilityBlockingPipesINTEL = 5945, + SpvCapabilityFPGARegINTEL = 5948, + SpvCapabilityDotProductInputAll = 6016, + SpvCapabilityDotProductInputAllKHR = 6016, + SpvCapabilityDotProductInput4x8Bit = 6017, + SpvCapabilityDotProductInput4x8BitKHR = 6017, + SpvCapabilityDotProductInput4x8BitPacked = 6018, + SpvCapabilityDotProductInput4x8BitPackedKHR = 6018, + SpvCapabilityDotProduct = 6019, + SpvCapabilityDotProductKHR = 6019, + SpvCapabilityBitInstructions = 6025, + SpvCapabilityAtomicFloat32AddEXT = 6033, + SpvCapabilityAtomicFloat64AddEXT = 6034, + SpvCapabilityLongConstantCompositeINTEL = 6089, + SpvCapabilityOptNoneINTEL = 6094, + SpvCapabilityAtomicFloat16AddEXT = 6095, + SpvCapabilityDebugInfoModuleINTEL = 6114, + SpvCapabilityMax = 0x7fffffff, +} SpvCapability; + +typedef enum SpvRayFlagsShift_ { + SpvRayFlagsOpaqueKHRShift = 0, + SpvRayFlagsNoOpaqueKHRShift = 1, + SpvRayFlagsTerminateOnFirstHitKHRShift = 2, + SpvRayFlagsSkipClosestHitShaderKHRShift = 3, + SpvRayFlagsCullBackFacingTrianglesKHRShift = 4, + SpvRayFlagsCullFrontFacingTrianglesKHRShift = 5, + SpvRayFlagsCullOpaqueKHRShift = 6, + SpvRayFlagsCullNoOpaqueKHRShift = 7, + SpvRayFlagsSkipTrianglesKHRShift = 8, + SpvRayFlagsSkipAABBsKHRShift = 9, + SpvRayFlagsMax = 0x7fffffff, +} SpvRayFlagsShift; + +typedef enum SpvRayFlagsMask_ { + SpvRayFlagsMaskNone = 0, + SpvRayFlagsOpaqueKHRMask = 0x00000001, + SpvRayFlagsNoOpaqueKHRMask = 0x00000002, + SpvRayFlagsTerminateOnFirstHitKHRMask = 0x00000004, + SpvRayFlagsSkipClosestHitShaderKHRMask = 0x00000008, + SpvRayFlagsCullBackFacingTrianglesKHRMask = 0x00000010, + SpvRayFlagsCullFrontFacingTrianglesKHRMask = 0x00000020, + SpvRayFlagsCullOpaqueKHRMask = 0x00000040, + SpvRayFlagsCullNoOpaqueKHRMask = 0x00000080, + SpvRayFlagsSkipTrianglesKHRMask = 0x00000100, + SpvRayFlagsSkipAABBsKHRMask = 0x00000200, +} SpvRayFlagsMask; + +typedef enum SpvRayQueryIntersection_ { + SpvRayQueryIntersectionRayQueryCandidateIntersectionKHR = 0, + SpvRayQueryIntersectionRayQueryCommittedIntersectionKHR = 1, + SpvRayQueryIntersectionMax = 0x7fffffff, +} SpvRayQueryIntersection; + +typedef enum SpvRayQueryCommittedIntersectionType_ { + SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionNoneKHR = 0, + SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionTriangleKHR = 1, + SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionGeneratedKHR = 2, + SpvRayQueryCommittedIntersectionTypeMax = 0x7fffffff, +} SpvRayQueryCommittedIntersectionType; + +typedef enum SpvRayQueryCandidateIntersectionType_ { + SpvRayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionTriangleKHR = 0, + SpvRayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionAABBKHR = 1, + SpvRayQueryCandidateIntersectionTypeMax = 0x7fffffff, +} SpvRayQueryCandidateIntersectionType; + +typedef enum SpvFragmentShadingRateShift_ { + SpvFragmentShadingRateVertical2PixelsShift = 0, + SpvFragmentShadingRateVertical4PixelsShift = 1, + SpvFragmentShadingRateHorizontal2PixelsShift = 2, + SpvFragmentShadingRateHorizontal4PixelsShift = 3, + SpvFragmentShadingRateMax = 0x7fffffff, +} SpvFragmentShadingRateShift; + +typedef enum SpvFragmentShadingRateMask_ { + SpvFragmentShadingRateMaskNone = 0, + SpvFragmentShadingRateVertical2PixelsMask = 0x00000001, + SpvFragmentShadingRateVertical4PixelsMask = 0x00000002, + SpvFragmentShadingRateHorizontal2PixelsMask = 0x00000004, + SpvFragmentShadingRateHorizontal4PixelsMask = 0x00000008, +} SpvFragmentShadingRateMask; + +typedef enum SpvFPDenormMode_ { + SpvFPDenormModePreserve = 0, + SpvFPDenormModeFlushToZero = 1, + SpvFPDenormModeMax = 0x7fffffff, +} SpvFPDenormMode; + +typedef enum SpvFPOperationMode_ { + SpvFPOperationModeIEEE = 0, + SpvFPOperationModeALT = 1, + SpvFPOperationModeMax = 0x7fffffff, +} SpvFPOperationMode; + +typedef enum SpvQuantizationModes_ { + SpvQuantizationModesTRN = 0, + SpvQuantizationModesTRN_ZERO = 1, + SpvQuantizationModesRND = 2, + SpvQuantizationModesRND_ZERO = 3, + SpvQuantizationModesRND_INF = 4, + SpvQuantizationModesRND_MIN_INF = 5, + SpvQuantizationModesRND_CONV = 6, + SpvQuantizationModesRND_CONV_ODD = 7, + SpvQuantizationModesMax = 0x7fffffff, +} SpvQuantizationModes; + +typedef enum SpvOverflowModes_ { + SpvOverflowModesWRAP = 0, + SpvOverflowModesSAT = 1, + SpvOverflowModesSAT_ZERO = 2, + SpvOverflowModesSAT_SYM = 3, + SpvOverflowModesMax = 0x7fffffff, +} SpvOverflowModes; + +typedef enum SpvPackedVectorFormat_ { + SpvPackedVectorFormatPackedVectorFormat4x8Bit = 0, + SpvPackedVectorFormatPackedVectorFormat4x8BitKHR = 0, + SpvPackedVectorFormatMax = 0x7fffffff, +} SpvPackedVectorFormat; + +typedef enum SpvOp_ { + SpvOpNop = 0, + SpvOpUndef = 1, + SpvOpSourceContinued = 2, + SpvOpSource = 3, + SpvOpSourceExtension = 4, + SpvOpName = 5, + SpvOpMemberName = 6, + SpvOpString = 7, + SpvOpLine = 8, + SpvOpExtension = 10, + SpvOpExtInstImport = 11, + SpvOpExtInst = 12, + SpvOpMemoryModel = 14, + SpvOpEntryPoint = 15, + SpvOpExecutionMode = 16, + SpvOpCapability = 17, + SpvOpTypeVoid = 19, + SpvOpTypeBool = 20, + SpvOpTypeInt = 21, + SpvOpTypeFloat = 22, + SpvOpTypeVector = 23, + SpvOpTypeMatrix = 24, + SpvOpTypeImage = 25, + SpvOpTypeSampler = 26, + SpvOpTypeSampledImage = 27, + SpvOpTypeArray = 28, + SpvOpTypeRuntimeArray = 29, + SpvOpTypeStruct = 30, + SpvOpTypeOpaque = 31, + SpvOpTypePointer = 32, + SpvOpTypeFunction = 33, + SpvOpTypeEvent = 34, + SpvOpTypeDeviceEvent = 35, + SpvOpTypeReserveId = 36, + SpvOpTypeQueue = 37, + SpvOpTypePipe = 38, + SpvOpTypeForwardPointer = 39, + SpvOpConstantTrue = 41, + SpvOpConstantFalse = 42, + SpvOpConstant = 43, + SpvOpConstantComposite = 44, + SpvOpConstantSampler = 45, + SpvOpConstantNull = 46, + SpvOpSpecConstantTrue = 48, + SpvOpSpecConstantFalse = 49, + SpvOpSpecConstant = 50, + SpvOpSpecConstantComposite = 51, + SpvOpSpecConstantOp = 52, + SpvOpFunction = 54, + SpvOpFunctionParameter = 55, + SpvOpFunctionEnd = 56, + SpvOpFunctionCall = 57, + SpvOpVariable = 59, + SpvOpImageTexelPointer = 60, + SpvOpLoad = 61, + SpvOpStore = 62, + SpvOpCopyMemory = 63, + SpvOpCopyMemorySized = 64, + SpvOpAccessChain = 65, + SpvOpInBoundsAccessChain = 66, + SpvOpPtrAccessChain = 67, + SpvOpArrayLength = 68, + SpvOpGenericPtrMemSemantics = 69, + SpvOpInBoundsPtrAccessChain = 70, + SpvOpDecorate = 71, + SpvOpMemberDecorate = 72, + SpvOpDecorationGroup = 73, + SpvOpGroupDecorate = 74, + SpvOpGroupMemberDecorate = 75, + SpvOpVectorExtractDynamic = 77, + SpvOpVectorInsertDynamic = 78, + SpvOpVectorShuffle = 79, + SpvOpCompositeConstruct = 80, + SpvOpCompositeExtract = 81, + SpvOpCompositeInsert = 82, + SpvOpCopyObject = 83, + SpvOpTranspose = 84, + SpvOpSampledImage = 86, + SpvOpImageSampleImplicitLod = 87, + SpvOpImageSampleExplicitLod = 88, + SpvOpImageSampleDrefImplicitLod = 89, + SpvOpImageSampleDrefExplicitLod = 90, + SpvOpImageSampleProjImplicitLod = 91, + SpvOpImageSampleProjExplicitLod = 92, + SpvOpImageSampleProjDrefImplicitLod = 93, + SpvOpImageSampleProjDrefExplicitLod = 94, + SpvOpImageFetch = 95, + SpvOpImageGather = 96, + SpvOpImageDrefGather = 97, + SpvOpImageRead = 98, + SpvOpImageWrite = 99, + SpvOpImage = 100, + SpvOpImageQueryFormat = 101, + SpvOpImageQueryOrder = 102, + SpvOpImageQuerySizeLod = 103, + SpvOpImageQuerySize = 104, + SpvOpImageQueryLod = 105, + SpvOpImageQueryLevels = 106, + SpvOpImageQuerySamples = 107, + SpvOpConvertFToU = 109, + SpvOpConvertFToS = 110, + SpvOpConvertSToF = 111, + SpvOpConvertUToF = 112, + SpvOpUConvert = 113, + SpvOpSConvert = 114, + SpvOpFConvert = 115, + SpvOpQuantizeToF16 = 116, + SpvOpConvertPtrToU = 117, + SpvOpSatConvertSToU = 118, + SpvOpSatConvertUToS = 119, + SpvOpConvertUToPtr = 120, + SpvOpPtrCastToGeneric = 121, + SpvOpGenericCastToPtr = 122, + SpvOpGenericCastToPtrExplicit = 123, + SpvOpBitcast = 124, + SpvOpSNegate = 126, + SpvOpFNegate = 127, + SpvOpIAdd = 128, + SpvOpFAdd = 129, + SpvOpISub = 130, + SpvOpFSub = 131, + SpvOpIMul = 132, + SpvOpFMul = 133, + SpvOpUDiv = 134, + SpvOpSDiv = 135, + SpvOpFDiv = 136, + SpvOpUMod = 137, + SpvOpSRem = 138, + SpvOpSMod = 139, + SpvOpFRem = 140, + SpvOpFMod = 141, + SpvOpVectorTimesScalar = 142, + SpvOpMatrixTimesScalar = 143, + SpvOpVectorTimesMatrix = 144, + SpvOpMatrixTimesVector = 145, + SpvOpMatrixTimesMatrix = 146, + SpvOpOuterProduct = 147, + SpvOpDot = 148, + SpvOpIAddCarry = 149, + SpvOpISubBorrow = 150, + SpvOpUMulExtended = 151, + SpvOpSMulExtended = 152, + SpvOpAny = 154, + SpvOpAll = 155, + SpvOpIsNan = 156, + SpvOpIsInf = 157, + SpvOpIsFinite = 158, + SpvOpIsNormal = 159, + SpvOpSignBitSet = 160, + SpvOpLessOrGreater = 161, + SpvOpOrdered = 162, + SpvOpUnordered = 163, + SpvOpLogicalEqual = 164, + SpvOpLogicalNotEqual = 165, + SpvOpLogicalOr = 166, + SpvOpLogicalAnd = 167, + SpvOpLogicalNot = 168, + SpvOpSelect = 169, + SpvOpIEqual = 170, + SpvOpINotEqual = 171, + SpvOpUGreaterThan = 172, + SpvOpSGreaterThan = 173, + SpvOpUGreaterThanEqual = 174, + SpvOpSGreaterThanEqual = 175, + SpvOpULessThan = 176, + SpvOpSLessThan = 177, + SpvOpULessThanEqual = 178, + SpvOpSLessThanEqual = 179, + SpvOpFOrdEqual = 180, + SpvOpFUnordEqual = 181, + SpvOpFOrdNotEqual = 182, + SpvOpFUnordNotEqual = 183, + SpvOpFOrdLessThan = 184, + SpvOpFUnordLessThan = 185, + SpvOpFOrdGreaterThan = 186, + SpvOpFUnordGreaterThan = 187, + SpvOpFOrdLessThanEqual = 188, + SpvOpFUnordLessThanEqual = 189, + SpvOpFOrdGreaterThanEqual = 190, + SpvOpFUnordGreaterThanEqual = 191, + SpvOpShiftRightLogical = 194, + SpvOpShiftRightArithmetic = 195, + SpvOpShiftLeftLogical = 196, + SpvOpBitwiseOr = 197, + SpvOpBitwiseXor = 198, + SpvOpBitwiseAnd = 199, + SpvOpNot = 200, + SpvOpBitFieldInsert = 201, + SpvOpBitFieldSExtract = 202, + SpvOpBitFieldUExtract = 203, + SpvOpBitReverse = 204, + SpvOpBitCount = 205, + SpvOpDPdx = 207, + SpvOpDPdy = 208, + SpvOpFwidth = 209, + SpvOpDPdxFine = 210, + SpvOpDPdyFine = 211, + SpvOpFwidthFine = 212, + SpvOpDPdxCoarse = 213, + SpvOpDPdyCoarse = 214, + SpvOpFwidthCoarse = 215, + SpvOpEmitVertex = 218, + SpvOpEndPrimitive = 219, + SpvOpEmitStreamVertex = 220, + SpvOpEndStreamPrimitive = 221, + SpvOpControlBarrier = 224, + SpvOpMemoryBarrier = 225, + SpvOpAtomicLoad = 227, + SpvOpAtomicStore = 228, + SpvOpAtomicExchange = 229, + SpvOpAtomicCompareExchange = 230, + SpvOpAtomicCompareExchangeWeak = 231, + SpvOpAtomicIIncrement = 232, + SpvOpAtomicIDecrement = 233, + SpvOpAtomicIAdd = 234, + SpvOpAtomicISub = 235, + SpvOpAtomicSMin = 236, + SpvOpAtomicUMin = 237, + SpvOpAtomicSMax = 238, + SpvOpAtomicUMax = 239, + SpvOpAtomicAnd = 240, + SpvOpAtomicOr = 241, + SpvOpAtomicXor = 242, + SpvOpPhi = 245, + SpvOpLoopMerge = 246, + SpvOpSelectionMerge = 247, + SpvOpLabel = 248, + SpvOpBranch = 249, + SpvOpBranchConditional = 250, + SpvOpSwitch = 251, + SpvOpKill = 252, + SpvOpReturn = 253, + SpvOpReturnValue = 254, + SpvOpUnreachable = 255, + SpvOpLifetimeStart = 256, + SpvOpLifetimeStop = 257, + SpvOpGroupAsyncCopy = 259, + SpvOpGroupWaitEvents = 260, + SpvOpGroupAll = 261, + SpvOpGroupAny = 262, + SpvOpGroupBroadcast = 263, + SpvOpGroupIAdd = 264, + SpvOpGroupFAdd = 265, + SpvOpGroupFMin = 266, + SpvOpGroupUMin = 267, + SpvOpGroupSMin = 268, + SpvOpGroupFMax = 269, + SpvOpGroupUMax = 270, + SpvOpGroupSMax = 271, + SpvOpReadPipe = 274, + SpvOpWritePipe = 275, + SpvOpReservedReadPipe = 276, + SpvOpReservedWritePipe = 277, + SpvOpReserveReadPipePackets = 278, + SpvOpReserveWritePipePackets = 279, + SpvOpCommitReadPipe = 280, + SpvOpCommitWritePipe = 281, + SpvOpIsValidReserveId = 282, + SpvOpGetNumPipePackets = 283, + SpvOpGetMaxPipePackets = 284, + SpvOpGroupReserveReadPipePackets = 285, + SpvOpGroupReserveWritePipePackets = 286, + SpvOpGroupCommitReadPipe = 287, + SpvOpGroupCommitWritePipe = 288, + SpvOpEnqueueMarker = 291, + SpvOpEnqueueKernel = 292, + SpvOpGetKernelNDrangeSubGroupCount = 293, + SpvOpGetKernelNDrangeMaxSubGroupSize = 294, + SpvOpGetKernelWorkGroupSize = 295, + SpvOpGetKernelPreferredWorkGroupSizeMultiple = 296, + SpvOpRetainEvent = 297, + SpvOpReleaseEvent = 298, + SpvOpCreateUserEvent = 299, + SpvOpIsValidEvent = 300, + SpvOpSetUserEventStatus = 301, + SpvOpCaptureEventProfilingInfo = 302, + SpvOpGetDefaultQueue = 303, + SpvOpBuildNDRange = 304, + SpvOpImageSparseSampleImplicitLod = 305, + SpvOpImageSparseSampleExplicitLod = 306, + SpvOpImageSparseSampleDrefImplicitLod = 307, + SpvOpImageSparseSampleDrefExplicitLod = 308, + SpvOpImageSparseSampleProjImplicitLod = 309, + SpvOpImageSparseSampleProjExplicitLod = 310, + SpvOpImageSparseSampleProjDrefImplicitLod = 311, + SpvOpImageSparseSampleProjDrefExplicitLod = 312, + SpvOpImageSparseFetch = 313, + SpvOpImageSparseGather = 314, + SpvOpImageSparseDrefGather = 315, + SpvOpImageSparseTexelsResident = 316, + SpvOpNoLine = 317, + SpvOpAtomicFlagTestAndSet = 318, + SpvOpAtomicFlagClear = 319, + SpvOpImageSparseRead = 320, + SpvOpSizeOf = 321, + SpvOpTypePipeStorage = 322, + SpvOpConstantPipeStorage = 323, + SpvOpCreatePipeFromPipeStorage = 324, + SpvOpGetKernelLocalSizeForSubgroupCount = 325, + SpvOpGetKernelMaxNumSubgroups = 326, + SpvOpTypeNamedBarrier = 327, + SpvOpNamedBarrierInitialize = 328, + SpvOpMemoryNamedBarrier = 329, + SpvOpModuleProcessed = 330, + SpvOpExecutionModeId = 331, + SpvOpDecorateId = 332, + SpvOpGroupNonUniformElect = 333, + SpvOpGroupNonUniformAll = 334, + SpvOpGroupNonUniformAny = 335, + SpvOpGroupNonUniformAllEqual = 336, + SpvOpGroupNonUniformBroadcast = 337, + SpvOpGroupNonUniformBroadcastFirst = 338, + SpvOpGroupNonUniformBallot = 339, + SpvOpGroupNonUniformInverseBallot = 340, + SpvOpGroupNonUniformBallotBitExtract = 341, + SpvOpGroupNonUniformBallotBitCount = 342, + SpvOpGroupNonUniformBallotFindLSB = 343, + SpvOpGroupNonUniformBallotFindMSB = 344, + SpvOpGroupNonUniformShuffle = 345, + SpvOpGroupNonUniformShuffleXor = 346, + SpvOpGroupNonUniformShuffleUp = 347, + SpvOpGroupNonUniformShuffleDown = 348, + SpvOpGroupNonUniformIAdd = 349, + SpvOpGroupNonUniformFAdd = 350, + SpvOpGroupNonUniformIMul = 351, + SpvOpGroupNonUniformFMul = 352, + SpvOpGroupNonUniformSMin = 353, + SpvOpGroupNonUniformUMin = 354, + SpvOpGroupNonUniformFMin = 355, + SpvOpGroupNonUniformSMax = 356, + SpvOpGroupNonUniformUMax = 357, + SpvOpGroupNonUniformFMax = 358, + SpvOpGroupNonUniformBitwiseAnd = 359, + SpvOpGroupNonUniformBitwiseOr = 360, + SpvOpGroupNonUniformBitwiseXor = 361, + SpvOpGroupNonUniformLogicalAnd = 362, + SpvOpGroupNonUniformLogicalOr = 363, + SpvOpGroupNonUniformLogicalXor = 364, + SpvOpGroupNonUniformQuadBroadcast = 365, + SpvOpGroupNonUniformQuadSwap = 366, + SpvOpCopyLogical = 400, + SpvOpPtrEqual = 401, + SpvOpPtrNotEqual = 402, + SpvOpPtrDiff = 403, + SpvOpTerminateInvocation = 4416, + SpvOpSubgroupBallotKHR = 4421, + SpvOpSubgroupFirstInvocationKHR = 4422, + SpvOpSubgroupAllKHR = 4428, + SpvOpSubgroupAnyKHR = 4429, + SpvOpSubgroupAllEqualKHR = 4430, + SpvOpSubgroupReadInvocationKHR = 4432, + SpvOpTraceRayKHR = 4445, + SpvOpExecuteCallableKHR = 4446, + SpvOpConvertUToAccelerationStructureKHR = 4447, + SpvOpIgnoreIntersectionKHR = 4448, + SpvOpTerminateRayKHR = 4449, + SpvOpSDot = 4450, + SpvOpSDotKHR = 4450, + SpvOpUDot = 4451, + SpvOpUDotKHR = 4451, + SpvOpSUDot = 4452, + SpvOpSUDotKHR = 4452, + SpvOpSDotAccSat = 4453, + SpvOpSDotAccSatKHR = 4453, + SpvOpUDotAccSat = 4454, + SpvOpUDotAccSatKHR = 4454, + SpvOpSUDotAccSat = 4455, + SpvOpSUDotAccSatKHR = 4455, + SpvOpTypeRayQueryKHR = 4472, + SpvOpRayQueryInitializeKHR = 4473, + SpvOpRayQueryTerminateKHR = 4474, + SpvOpRayQueryGenerateIntersectionKHR = 4475, + SpvOpRayQueryConfirmIntersectionKHR = 4476, + SpvOpRayQueryProceedKHR = 4477, + SpvOpRayQueryGetIntersectionTypeKHR = 4479, + SpvOpGroupIAddNonUniformAMD = 5000, + SpvOpGroupFAddNonUniformAMD = 5001, + SpvOpGroupFMinNonUniformAMD = 5002, + SpvOpGroupUMinNonUniformAMD = 5003, + SpvOpGroupSMinNonUniformAMD = 5004, + SpvOpGroupFMaxNonUniformAMD = 5005, + SpvOpGroupUMaxNonUniformAMD = 5006, + SpvOpGroupSMaxNonUniformAMD = 5007, + SpvOpFragmentMaskFetchAMD = 5011, + SpvOpFragmentFetchAMD = 5012, + SpvOpReadClockKHR = 5056, + SpvOpImageSampleFootprintNV = 5283, + SpvOpGroupNonUniformPartitionNV = 5296, + SpvOpWritePackedPrimitiveIndices4x8NV = 5299, + SpvOpReportIntersectionKHR = 5334, + SpvOpReportIntersectionNV = 5334, + SpvOpIgnoreIntersectionNV = 5335, + SpvOpTerminateRayNV = 5336, + SpvOpTraceNV = 5337, + SpvOpTraceMotionNV = 5338, + SpvOpTraceRayMotionNV = 5339, + SpvOpTypeAccelerationStructureKHR = 5341, + SpvOpTypeAccelerationStructureNV = 5341, + SpvOpExecuteCallableNV = 5344, + SpvOpTypeCooperativeMatrixNV = 5358, + SpvOpCooperativeMatrixLoadNV = 5359, + SpvOpCooperativeMatrixStoreNV = 5360, + SpvOpCooperativeMatrixMulAddNV = 5361, + SpvOpCooperativeMatrixLengthNV = 5362, + SpvOpBeginInvocationInterlockEXT = 5364, + SpvOpEndInvocationInterlockEXT = 5365, + SpvOpDemoteToHelperInvocation = 5380, + SpvOpDemoteToHelperInvocationEXT = 5380, + SpvOpIsHelperInvocationEXT = 5381, + SpvOpConvertUToImageNV = 5391, + SpvOpConvertUToSamplerNV = 5392, + SpvOpConvertImageToUNV = 5393, + SpvOpConvertSamplerToUNV = 5394, + SpvOpConvertUToSampledImageNV = 5395, + SpvOpConvertSampledImageToUNV = 5396, + SpvOpSamplerImageAddressingModeNV = 5397, + SpvOpSubgroupShuffleINTEL = 5571, + SpvOpSubgroupShuffleDownINTEL = 5572, + SpvOpSubgroupShuffleUpINTEL = 5573, + SpvOpSubgroupShuffleXorINTEL = 5574, + SpvOpSubgroupBlockReadINTEL = 5575, + SpvOpSubgroupBlockWriteINTEL = 5576, + SpvOpSubgroupImageBlockReadINTEL = 5577, + SpvOpSubgroupImageBlockWriteINTEL = 5578, + SpvOpSubgroupImageMediaBlockReadINTEL = 5580, + SpvOpSubgroupImageMediaBlockWriteINTEL = 5581, + SpvOpUCountLeadingZerosINTEL = 5585, + SpvOpUCountTrailingZerosINTEL = 5586, + SpvOpAbsISubINTEL = 5587, + SpvOpAbsUSubINTEL = 5588, + SpvOpIAddSatINTEL = 5589, + SpvOpUAddSatINTEL = 5590, + SpvOpIAverageINTEL = 5591, + SpvOpUAverageINTEL = 5592, + SpvOpIAverageRoundedINTEL = 5593, + SpvOpUAverageRoundedINTEL = 5594, + SpvOpISubSatINTEL = 5595, + SpvOpUSubSatINTEL = 5596, + SpvOpIMul32x16INTEL = 5597, + SpvOpUMul32x16INTEL = 5598, + SpvOpConstantFunctionPointerINTEL = 5600, + SpvOpFunctionPointerCallINTEL = 5601, + SpvOpAsmTargetINTEL = 5609, + SpvOpAsmINTEL = 5610, + SpvOpAsmCallINTEL = 5611, + SpvOpAtomicFMinEXT = 5614, + SpvOpAtomicFMaxEXT = 5615, + SpvOpAssumeTrueKHR = 5630, + SpvOpExpectKHR = 5631, + SpvOpDecorateString = 5632, + SpvOpDecorateStringGOOGLE = 5632, + SpvOpMemberDecorateString = 5633, + SpvOpMemberDecorateStringGOOGLE = 5633, + SpvOpVmeImageINTEL = 5699, + SpvOpTypeVmeImageINTEL = 5700, + SpvOpTypeAvcImePayloadINTEL = 5701, + SpvOpTypeAvcRefPayloadINTEL = 5702, + SpvOpTypeAvcSicPayloadINTEL = 5703, + SpvOpTypeAvcMcePayloadINTEL = 5704, + SpvOpTypeAvcMceResultINTEL = 5705, + SpvOpTypeAvcImeResultINTEL = 5706, + SpvOpTypeAvcImeResultSingleReferenceStreamoutINTEL = 5707, + SpvOpTypeAvcImeResultDualReferenceStreamoutINTEL = 5708, + SpvOpTypeAvcImeSingleReferenceStreaminINTEL = 5709, + SpvOpTypeAvcImeDualReferenceStreaminINTEL = 5710, + SpvOpTypeAvcRefResultINTEL = 5711, + SpvOpTypeAvcSicResultINTEL = 5712, + SpvOpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = 5713, + SpvOpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = 5714, + SpvOpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = 5715, + SpvOpSubgroupAvcMceSetInterShapePenaltyINTEL = 5716, + SpvOpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = 5717, + SpvOpSubgroupAvcMceSetInterDirectionPenaltyINTEL = 5718, + SpvOpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = 5719, + SpvOpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = 5720, + SpvOpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = 5721, + SpvOpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = 5722, + SpvOpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = 5723, + SpvOpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = 5724, + SpvOpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = 5725, + SpvOpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = 5726, + SpvOpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = 5727, + SpvOpSubgroupAvcMceSetAcOnlyHaarINTEL = 5728, + SpvOpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = 5729, + SpvOpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = 5730, + SpvOpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = 5731, + SpvOpSubgroupAvcMceConvertToImePayloadINTEL = 5732, + SpvOpSubgroupAvcMceConvertToImeResultINTEL = 5733, + SpvOpSubgroupAvcMceConvertToRefPayloadINTEL = 5734, + SpvOpSubgroupAvcMceConvertToRefResultINTEL = 5735, + SpvOpSubgroupAvcMceConvertToSicPayloadINTEL = 5736, + SpvOpSubgroupAvcMceConvertToSicResultINTEL = 5737, + SpvOpSubgroupAvcMceGetMotionVectorsINTEL = 5738, + SpvOpSubgroupAvcMceGetInterDistortionsINTEL = 5739, + SpvOpSubgroupAvcMceGetBestInterDistortionsINTEL = 5740, + SpvOpSubgroupAvcMceGetInterMajorShapeINTEL = 5741, + SpvOpSubgroupAvcMceGetInterMinorShapeINTEL = 5742, + SpvOpSubgroupAvcMceGetInterDirectionsINTEL = 5743, + SpvOpSubgroupAvcMceGetInterMotionVectorCountINTEL = 5744, + SpvOpSubgroupAvcMceGetInterReferenceIdsINTEL = 5745, + SpvOpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = 5746, + SpvOpSubgroupAvcImeInitializeINTEL = 5747, + SpvOpSubgroupAvcImeSetSingleReferenceINTEL = 5748, + SpvOpSubgroupAvcImeSetDualReferenceINTEL = 5749, + SpvOpSubgroupAvcImeRefWindowSizeINTEL = 5750, + SpvOpSubgroupAvcImeAdjustRefOffsetINTEL = 5751, + SpvOpSubgroupAvcImeConvertToMcePayloadINTEL = 5752, + SpvOpSubgroupAvcImeSetMaxMotionVectorCountINTEL = 5753, + SpvOpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = 5754, + SpvOpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = 5755, + SpvOpSubgroupAvcImeSetWeightedSadINTEL = 5756, + SpvOpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = 5757, + SpvOpSubgroupAvcImeEvaluateWithDualReferenceINTEL = 5758, + SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = 5759, + SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = 5760, + SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = 5761, + SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = 5762, + SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = 5763, + SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = 5764, + SpvOpSubgroupAvcImeConvertToMceResultINTEL = 5765, + SpvOpSubgroupAvcImeGetSingleReferenceStreaminINTEL = 5766, + SpvOpSubgroupAvcImeGetDualReferenceStreaminINTEL = 5767, + SpvOpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = 5768, + SpvOpSubgroupAvcImeStripDualReferenceStreamoutINTEL = 5769, + SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = 5770, + SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = 5771, + SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = 5772, + SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = 5773, + SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = 5774, + SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = 5775, + SpvOpSubgroupAvcImeGetBorderReachedINTEL = 5776, + SpvOpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = 5777, + SpvOpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = 5778, + SpvOpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = 5779, + SpvOpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = 5780, + SpvOpSubgroupAvcFmeInitializeINTEL = 5781, + SpvOpSubgroupAvcBmeInitializeINTEL = 5782, + SpvOpSubgroupAvcRefConvertToMcePayloadINTEL = 5783, + SpvOpSubgroupAvcRefSetBidirectionalMixDisableINTEL = 5784, + SpvOpSubgroupAvcRefSetBilinearFilterEnableINTEL = 5785, + SpvOpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = 5786, + SpvOpSubgroupAvcRefEvaluateWithDualReferenceINTEL = 5787, + SpvOpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = 5788, + SpvOpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = 5789, + SpvOpSubgroupAvcRefConvertToMceResultINTEL = 5790, + SpvOpSubgroupAvcSicInitializeINTEL = 5791, + SpvOpSubgroupAvcSicConfigureSkcINTEL = 5792, + SpvOpSubgroupAvcSicConfigureIpeLumaINTEL = 5793, + SpvOpSubgroupAvcSicConfigureIpeLumaChromaINTEL = 5794, + SpvOpSubgroupAvcSicGetMotionVectorMaskINTEL = 5795, + SpvOpSubgroupAvcSicConvertToMcePayloadINTEL = 5796, + SpvOpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = 5797, + SpvOpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = 5798, + SpvOpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = 5799, + SpvOpSubgroupAvcSicSetBilinearFilterEnableINTEL = 5800, + SpvOpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = 5801, + SpvOpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = 5802, + SpvOpSubgroupAvcSicEvaluateIpeINTEL = 5803, + SpvOpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = 5804, + SpvOpSubgroupAvcSicEvaluateWithDualReferenceINTEL = 5805, + SpvOpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = 5806, + SpvOpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = 5807, + SpvOpSubgroupAvcSicConvertToMceResultINTEL = 5808, + SpvOpSubgroupAvcSicGetIpeLumaShapeINTEL = 5809, + SpvOpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = 5810, + SpvOpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = 5811, + SpvOpSubgroupAvcSicGetPackedIpeLumaModesINTEL = 5812, + SpvOpSubgroupAvcSicGetIpeChromaModeINTEL = 5813, + SpvOpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, + SpvOpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, + SpvOpSubgroupAvcSicGetInterRawSadsINTEL = 5816, + SpvOpVariableLengthArrayINTEL = 5818, + SpvOpSaveMemoryINTEL = 5819, + SpvOpRestoreMemoryINTEL = 5820, + SpvOpArbitraryFloatSinCosPiINTEL = 5840, + SpvOpArbitraryFloatCastINTEL = 5841, + SpvOpArbitraryFloatCastFromIntINTEL = 5842, + SpvOpArbitraryFloatCastToIntINTEL = 5843, + SpvOpArbitraryFloatAddINTEL = 5846, + SpvOpArbitraryFloatSubINTEL = 5847, + SpvOpArbitraryFloatMulINTEL = 5848, + SpvOpArbitraryFloatDivINTEL = 5849, + SpvOpArbitraryFloatGTINTEL = 5850, + SpvOpArbitraryFloatGEINTEL = 5851, + SpvOpArbitraryFloatLTINTEL = 5852, + SpvOpArbitraryFloatLEINTEL = 5853, + SpvOpArbitraryFloatEQINTEL = 5854, + SpvOpArbitraryFloatRecipINTEL = 5855, + SpvOpArbitraryFloatRSqrtINTEL = 5856, + SpvOpArbitraryFloatCbrtINTEL = 5857, + SpvOpArbitraryFloatHypotINTEL = 5858, + SpvOpArbitraryFloatSqrtINTEL = 5859, + SpvOpArbitraryFloatLogINTEL = 5860, + SpvOpArbitraryFloatLog2INTEL = 5861, + SpvOpArbitraryFloatLog10INTEL = 5862, + SpvOpArbitraryFloatLog1pINTEL = 5863, + SpvOpArbitraryFloatExpINTEL = 5864, + SpvOpArbitraryFloatExp2INTEL = 5865, + SpvOpArbitraryFloatExp10INTEL = 5866, + SpvOpArbitraryFloatExpm1INTEL = 5867, + SpvOpArbitraryFloatSinINTEL = 5868, + SpvOpArbitraryFloatCosINTEL = 5869, + SpvOpArbitraryFloatSinCosINTEL = 5870, + SpvOpArbitraryFloatSinPiINTEL = 5871, + SpvOpArbitraryFloatCosPiINTEL = 5872, + SpvOpArbitraryFloatASinINTEL = 5873, + SpvOpArbitraryFloatASinPiINTEL = 5874, + SpvOpArbitraryFloatACosINTEL = 5875, + SpvOpArbitraryFloatACosPiINTEL = 5876, + SpvOpArbitraryFloatATanINTEL = 5877, + SpvOpArbitraryFloatATanPiINTEL = 5878, + SpvOpArbitraryFloatATan2INTEL = 5879, + SpvOpArbitraryFloatPowINTEL = 5880, + SpvOpArbitraryFloatPowRINTEL = 5881, + SpvOpArbitraryFloatPowNINTEL = 5882, + SpvOpLoopControlINTEL = 5887, + SpvOpAliasDomainDeclINTEL = 5911, + SpvOpAliasScopeDeclINTEL = 5912, + SpvOpAliasScopeListDeclINTEL = 5913, + SpvOpFixedSqrtINTEL = 5923, + SpvOpFixedRecipINTEL = 5924, + SpvOpFixedRsqrtINTEL = 5925, + SpvOpFixedSinINTEL = 5926, + SpvOpFixedCosINTEL = 5927, + SpvOpFixedSinCosINTEL = 5928, + SpvOpFixedSinPiINTEL = 5929, + SpvOpFixedCosPiINTEL = 5930, + SpvOpFixedSinCosPiINTEL = 5931, + SpvOpFixedLogINTEL = 5932, + SpvOpFixedExpINTEL = 5933, + SpvOpPtrCastToCrossWorkgroupINTEL = 5934, + SpvOpCrossWorkgroupCastToPtrINTEL = 5938, + SpvOpReadPipeBlockingINTEL = 5946, + SpvOpWritePipeBlockingINTEL = 5947, + SpvOpFPGARegINTEL = 5949, + SpvOpRayQueryGetRayTMinKHR = 6016, + SpvOpRayQueryGetRayFlagsKHR = 6017, + SpvOpRayQueryGetIntersectionTKHR = 6018, + SpvOpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019, + SpvOpRayQueryGetIntersectionInstanceIdKHR = 6020, + SpvOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021, + SpvOpRayQueryGetIntersectionGeometryIndexKHR = 6022, + SpvOpRayQueryGetIntersectionPrimitiveIndexKHR = 6023, + SpvOpRayQueryGetIntersectionBarycentricsKHR = 6024, + SpvOpRayQueryGetIntersectionFrontFaceKHR = 6025, + SpvOpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026, + SpvOpRayQueryGetIntersectionObjectRayDirectionKHR = 6027, + SpvOpRayQueryGetIntersectionObjectRayOriginKHR = 6028, + SpvOpRayQueryGetWorldRayDirectionKHR = 6029, + SpvOpRayQueryGetWorldRayOriginKHR = 6030, + SpvOpRayQueryGetIntersectionObjectToWorldKHR = 6031, + SpvOpRayQueryGetIntersectionWorldToObjectKHR = 6032, + SpvOpAtomicFAddEXT = 6035, + SpvOpTypeBufferSurfaceINTEL = 6086, + SpvOpTypeStructContinuedINTEL = 6090, + SpvOpConstantCompositeContinuedINTEL = 6091, + SpvOpSpecConstantCompositeContinuedINTEL = 6092, + SpvOpMax = 0x7fffffff, +} SpvOp; + +#ifdef SPV_ENABLE_UTILITY_CODE +inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultType) { + *hasResult = *hasResultType = false; + switch (opcode) { + default: /* unknown opcode */ break; + case SpvOpNop: *hasResult = false; *hasResultType = false; break; + case SpvOpUndef: *hasResult = true; *hasResultType = true; break; + case SpvOpSourceContinued: *hasResult = false; *hasResultType = false; break; + case SpvOpSource: *hasResult = false; *hasResultType = false; break; + case SpvOpSourceExtension: *hasResult = false; *hasResultType = false; break; + case SpvOpName: *hasResult = false; *hasResultType = false; break; + case SpvOpMemberName: *hasResult = false; *hasResultType = false; break; + case SpvOpString: *hasResult = true; *hasResultType = false; break; + case SpvOpLine: *hasResult = false; *hasResultType = false; break; + case SpvOpExtension: *hasResult = false; *hasResultType = false; break; + case SpvOpExtInstImport: *hasResult = true; *hasResultType = false; break; + case SpvOpExtInst: *hasResult = true; *hasResultType = true; break; + case SpvOpMemoryModel: *hasResult = false; *hasResultType = false; break; + case SpvOpEntryPoint: *hasResult = false; *hasResultType = false; break; + case SpvOpExecutionMode: *hasResult = false; *hasResultType = false; break; + case SpvOpCapability: *hasResult = false; *hasResultType = false; break; + case SpvOpTypeVoid: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeBool: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeInt: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeFloat: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeVector: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeMatrix: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeImage: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeSampler: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeSampledImage: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeArray: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeRuntimeArray: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeStruct: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeOpaque: *hasResult = true; *hasResultType = false; break; + case SpvOpTypePointer: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeFunction: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeEvent: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeDeviceEvent: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeReserveId: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeQueue: *hasResult = true; *hasResultType = false; break; + case SpvOpTypePipe: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeForwardPointer: *hasResult = false; *hasResultType = false; break; + case SpvOpConstantTrue: *hasResult = true; *hasResultType = true; break; + case SpvOpConstantFalse: *hasResult = true; *hasResultType = true; break; + case SpvOpConstant: *hasResult = true; *hasResultType = true; break; + case SpvOpConstantComposite: *hasResult = true; *hasResultType = true; break; + case SpvOpConstantSampler: *hasResult = true; *hasResultType = true; break; + case SpvOpConstantNull: *hasResult = true; *hasResultType = true; break; + case SpvOpSpecConstantTrue: *hasResult = true; *hasResultType = true; break; + case SpvOpSpecConstantFalse: *hasResult = true; *hasResultType = true; break; + case SpvOpSpecConstant: *hasResult = true; *hasResultType = true; break; + case SpvOpSpecConstantComposite: *hasResult = true; *hasResultType = true; break; + case SpvOpSpecConstantOp: *hasResult = true; *hasResultType = true; break; + case SpvOpFunction: *hasResult = true; *hasResultType = true; break; + case SpvOpFunctionParameter: *hasResult = true; *hasResultType = true; break; + case SpvOpFunctionEnd: *hasResult = false; *hasResultType = false; break; + case SpvOpFunctionCall: *hasResult = true; *hasResultType = true; break; + case SpvOpVariable: *hasResult = true; *hasResultType = true; break; + case SpvOpImageTexelPointer: *hasResult = true; *hasResultType = true; break; + case SpvOpLoad: *hasResult = true; *hasResultType = true; break; + case SpvOpStore: *hasResult = false; *hasResultType = false; break; + case SpvOpCopyMemory: *hasResult = false; *hasResultType = false; break; + case SpvOpCopyMemorySized: *hasResult = false; *hasResultType = false; break; + case SpvOpAccessChain: *hasResult = true; *hasResultType = true; break; + case SpvOpInBoundsAccessChain: *hasResult = true; *hasResultType = true; break; + case SpvOpPtrAccessChain: *hasResult = true; *hasResultType = true; break; + case SpvOpArrayLength: *hasResult = true; *hasResultType = true; break; + case SpvOpGenericPtrMemSemantics: *hasResult = true; *hasResultType = true; break; + case SpvOpInBoundsPtrAccessChain: *hasResult = true; *hasResultType = true; break; + case SpvOpDecorate: *hasResult = false; *hasResultType = false; break; + case SpvOpMemberDecorate: *hasResult = false; *hasResultType = false; break; + case SpvOpDecorationGroup: *hasResult = true; *hasResultType = false; break; + case SpvOpGroupDecorate: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupMemberDecorate: *hasResult = false; *hasResultType = false; break; + case SpvOpVectorExtractDynamic: *hasResult = true; *hasResultType = true; break; + case SpvOpVectorInsertDynamic: *hasResult = true; *hasResultType = true; break; + case SpvOpVectorShuffle: *hasResult = true; *hasResultType = true; break; + case SpvOpCompositeConstruct: *hasResult = true; *hasResultType = true; break; + case SpvOpCompositeExtract: *hasResult = true; *hasResultType = true; break; + case SpvOpCompositeInsert: *hasResult = true; *hasResultType = true; break; + case SpvOpCopyObject: *hasResult = true; *hasResultType = true; break; + case SpvOpTranspose: *hasResult = true; *hasResultType = true; break; + case SpvOpSampledImage: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageFetch: *hasResult = true; *hasResultType = true; break; + case SpvOpImageGather: *hasResult = true; *hasResultType = true; break; + case SpvOpImageDrefGather: *hasResult = true; *hasResultType = true; break; + case SpvOpImageRead: *hasResult = true; *hasResultType = true; break; + case SpvOpImageWrite: *hasResult = false; *hasResultType = false; break; + case SpvOpImage: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQueryFormat: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQueryOrder: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQuerySizeLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQuerySize: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQueryLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQueryLevels: *hasResult = true; *hasResultType = true; break; + case SpvOpImageQuerySamples: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertFToU: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertFToS: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertSToF: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertUToF: *hasResult = true; *hasResultType = true; break; + case SpvOpUConvert: *hasResult = true; *hasResultType = true; break; + case SpvOpSConvert: *hasResult = true; *hasResultType = true; break; + case SpvOpFConvert: *hasResult = true; *hasResultType = true; break; + case SpvOpQuantizeToF16: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertPtrToU: *hasResult = true; *hasResultType = true; break; + case SpvOpSatConvertSToU: *hasResult = true; *hasResultType = true; break; + case SpvOpSatConvertUToS: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertUToPtr: *hasResult = true; *hasResultType = true; break; + case SpvOpPtrCastToGeneric: *hasResult = true; *hasResultType = true; break; + case SpvOpGenericCastToPtr: *hasResult = true; *hasResultType = true; break; + case SpvOpGenericCastToPtrExplicit: *hasResult = true; *hasResultType = true; break; + case SpvOpBitcast: *hasResult = true; *hasResultType = true; break; + case SpvOpSNegate: *hasResult = true; *hasResultType = true; break; + case SpvOpFNegate: *hasResult = true; *hasResultType = true; break; + case SpvOpIAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpFAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpISub: *hasResult = true; *hasResultType = true; break; + case SpvOpFSub: *hasResult = true; *hasResultType = true; break; + case SpvOpIMul: *hasResult = true; *hasResultType = true; break; + case SpvOpFMul: *hasResult = true; *hasResultType = true; break; + case SpvOpUDiv: *hasResult = true; *hasResultType = true; break; + case SpvOpSDiv: *hasResult = true; *hasResultType = true; break; + case SpvOpFDiv: *hasResult = true; *hasResultType = true; break; + case SpvOpUMod: *hasResult = true; *hasResultType = true; break; + case SpvOpSRem: *hasResult = true; *hasResultType = true; break; + case SpvOpSMod: *hasResult = true; *hasResultType = true; break; + case SpvOpFRem: *hasResult = true; *hasResultType = true; break; + case SpvOpFMod: *hasResult = true; *hasResultType = true; break; + case SpvOpVectorTimesScalar: *hasResult = true; *hasResultType = true; break; + case SpvOpMatrixTimesScalar: *hasResult = true; *hasResultType = true; break; + case SpvOpVectorTimesMatrix: *hasResult = true; *hasResultType = true; break; + case SpvOpMatrixTimesVector: *hasResult = true; *hasResultType = true; break; + case SpvOpMatrixTimesMatrix: *hasResult = true; *hasResultType = true; break; + case SpvOpOuterProduct: *hasResult = true; *hasResultType = true; break; + case SpvOpDot: *hasResult = true; *hasResultType = true; break; + case SpvOpIAddCarry: *hasResult = true; *hasResultType = true; break; + case SpvOpISubBorrow: *hasResult = true; *hasResultType = true; break; + case SpvOpUMulExtended: *hasResult = true; *hasResultType = true; break; + case SpvOpSMulExtended: *hasResult = true; *hasResultType = true; break; + case SpvOpAny: *hasResult = true; *hasResultType = true; break; + case SpvOpAll: *hasResult = true; *hasResultType = true; break; + case SpvOpIsNan: *hasResult = true; *hasResultType = true; break; + case SpvOpIsInf: *hasResult = true; *hasResultType = true; break; + case SpvOpIsFinite: *hasResult = true; *hasResultType = true; break; + case SpvOpIsNormal: *hasResult = true; *hasResultType = true; break; + case SpvOpSignBitSet: *hasResult = true; *hasResultType = true; break; + case SpvOpLessOrGreater: *hasResult = true; *hasResultType = true; break; + case SpvOpOrdered: *hasResult = true; *hasResultType = true; break; + case SpvOpUnordered: *hasResult = true; *hasResultType = true; break; + case SpvOpLogicalEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpLogicalNotEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpLogicalOr: *hasResult = true; *hasResultType = true; break; + case SpvOpLogicalAnd: *hasResult = true; *hasResultType = true; break; + case SpvOpLogicalNot: *hasResult = true; *hasResultType = true; break; + case SpvOpSelect: *hasResult = true; *hasResultType = true; break; + case SpvOpIEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpINotEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpUGreaterThan: *hasResult = true; *hasResultType = true; break; + case SpvOpSGreaterThan: *hasResult = true; *hasResultType = true; break; + case SpvOpUGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpSGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpULessThan: *hasResult = true; *hasResultType = true; break; + case SpvOpSLessThan: *hasResult = true; *hasResultType = true; break; + case SpvOpULessThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpSLessThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFOrdEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFUnordEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFOrdNotEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFUnordNotEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFOrdLessThan: *hasResult = true; *hasResultType = true; break; + case SpvOpFUnordLessThan: *hasResult = true; *hasResultType = true; break; + case SpvOpFOrdGreaterThan: *hasResult = true; *hasResultType = true; break; + case SpvOpFUnordGreaterThan: *hasResult = true; *hasResultType = true; break; + case SpvOpFOrdLessThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFUnordLessThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFOrdGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpFUnordGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpShiftRightLogical: *hasResult = true; *hasResultType = true; break; + case SpvOpShiftRightArithmetic: *hasResult = true; *hasResultType = true; break; + case SpvOpShiftLeftLogical: *hasResult = true; *hasResultType = true; break; + case SpvOpBitwiseOr: *hasResult = true; *hasResultType = true; break; + case SpvOpBitwiseXor: *hasResult = true; *hasResultType = true; break; + case SpvOpBitwiseAnd: *hasResult = true; *hasResultType = true; break; + case SpvOpNot: *hasResult = true; *hasResultType = true; break; + case SpvOpBitFieldInsert: *hasResult = true; *hasResultType = true; break; + case SpvOpBitFieldSExtract: *hasResult = true; *hasResultType = true; break; + case SpvOpBitFieldUExtract: *hasResult = true; *hasResultType = true; break; + case SpvOpBitReverse: *hasResult = true; *hasResultType = true; break; + case SpvOpBitCount: *hasResult = true; *hasResultType = true; break; + case SpvOpDPdx: *hasResult = true; *hasResultType = true; break; + case SpvOpDPdy: *hasResult = true; *hasResultType = true; break; + case SpvOpFwidth: *hasResult = true; *hasResultType = true; break; + case SpvOpDPdxFine: *hasResult = true; *hasResultType = true; break; + case SpvOpDPdyFine: *hasResult = true; *hasResultType = true; break; + case SpvOpFwidthFine: *hasResult = true; *hasResultType = true; break; + case SpvOpDPdxCoarse: *hasResult = true; *hasResultType = true; break; + case SpvOpDPdyCoarse: *hasResult = true; *hasResultType = true; break; + case SpvOpFwidthCoarse: *hasResult = true; *hasResultType = true; break; + case SpvOpEmitVertex: *hasResult = false; *hasResultType = false; break; + case SpvOpEndPrimitive: *hasResult = false; *hasResultType = false; break; + case SpvOpEmitStreamVertex: *hasResult = false; *hasResultType = false; break; + case SpvOpEndStreamPrimitive: *hasResult = false; *hasResultType = false; break; + case SpvOpControlBarrier: *hasResult = false; *hasResultType = false; break; + case SpvOpMemoryBarrier: *hasResult = false; *hasResultType = false; break; + case SpvOpAtomicLoad: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicStore: *hasResult = false; *hasResultType = false; break; + case SpvOpAtomicExchange: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicCompareExchange: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicCompareExchangeWeak: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicIIncrement: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicIDecrement: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicIAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicISub: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicSMin: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicUMin: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicSMax: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicUMax: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicAnd: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicOr: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicXor: *hasResult = true; *hasResultType = true; break; + case SpvOpPhi: *hasResult = true; *hasResultType = true; break; + case SpvOpLoopMerge: *hasResult = false; *hasResultType = false; break; + case SpvOpSelectionMerge: *hasResult = false; *hasResultType = false; break; + case SpvOpLabel: *hasResult = true; *hasResultType = false; break; + case SpvOpBranch: *hasResult = false; *hasResultType = false; break; + case SpvOpBranchConditional: *hasResult = false; *hasResultType = false; break; + case SpvOpSwitch: *hasResult = false; *hasResultType = false; break; + case SpvOpKill: *hasResult = false; *hasResultType = false; break; + case SpvOpReturn: *hasResult = false; *hasResultType = false; break; + case SpvOpReturnValue: *hasResult = false; *hasResultType = false; break; + case SpvOpUnreachable: *hasResult = false; *hasResultType = false; break; + case SpvOpLifetimeStart: *hasResult = false; *hasResultType = false; break; + case SpvOpLifetimeStop: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupAsyncCopy: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupWaitEvents: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupAll: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupAny: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupBroadcast: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupIAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFMin: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupUMin: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupSMin: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFMax: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupUMax: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupSMax: *hasResult = true; *hasResultType = true; break; + case SpvOpReadPipe: *hasResult = true; *hasResultType = true; break; + case SpvOpWritePipe: *hasResult = true; *hasResultType = true; break; + case SpvOpReservedReadPipe: *hasResult = true; *hasResultType = true; break; + case SpvOpReservedWritePipe: *hasResult = true; *hasResultType = true; break; + case SpvOpReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; + case SpvOpReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; + case SpvOpCommitReadPipe: *hasResult = false; *hasResultType = false; break; + case SpvOpCommitWritePipe: *hasResult = false; *hasResultType = false; break; + case SpvOpIsValidReserveId: *hasResult = true; *hasResultType = true; break; + case SpvOpGetNumPipePackets: *hasResult = true; *hasResultType = true; break; + case SpvOpGetMaxPipePackets: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupCommitReadPipe: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupCommitWritePipe: *hasResult = false; *hasResultType = false; break; + case SpvOpEnqueueMarker: *hasResult = true; *hasResultType = true; break; + case SpvOpEnqueueKernel: *hasResult = true; *hasResultType = true; break; + case SpvOpGetKernelNDrangeSubGroupCount: *hasResult = true; *hasResultType = true; break; + case SpvOpGetKernelNDrangeMaxSubGroupSize: *hasResult = true; *hasResultType = true; break; + case SpvOpGetKernelWorkGroupSize: *hasResult = true; *hasResultType = true; break; + case SpvOpGetKernelPreferredWorkGroupSizeMultiple: *hasResult = true; *hasResultType = true; break; + case SpvOpRetainEvent: *hasResult = false; *hasResultType = false; break; + case SpvOpReleaseEvent: *hasResult = false; *hasResultType = false; break; + case SpvOpCreateUserEvent: *hasResult = true; *hasResultType = true; break; + case SpvOpIsValidEvent: *hasResult = true; *hasResultType = true; break; + case SpvOpSetUserEventStatus: *hasResult = false; *hasResultType = false; break; + case SpvOpCaptureEventProfilingInfo: *hasResult = false; *hasResultType = false; break; + case SpvOpGetDefaultQueue: *hasResult = true; *hasResultType = true; break; + case SpvOpBuildNDRange: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseFetch: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseGather: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseDrefGather: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSparseTexelsResident: *hasResult = true; *hasResultType = true; break; + case SpvOpNoLine: *hasResult = false; *hasResultType = false; break; + case SpvOpAtomicFlagTestAndSet: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicFlagClear: *hasResult = false; *hasResultType = false; break; + case SpvOpImageSparseRead: *hasResult = true; *hasResultType = true; break; + case SpvOpSizeOf: *hasResult = true; *hasResultType = true; break; + case SpvOpTypePipeStorage: *hasResult = true; *hasResultType = false; break; + case SpvOpConstantPipeStorage: *hasResult = true; *hasResultType = true; break; + case SpvOpCreatePipeFromPipeStorage: *hasResult = true; *hasResultType = true; break; + case SpvOpGetKernelLocalSizeForSubgroupCount: *hasResult = true; *hasResultType = true; break; + case SpvOpGetKernelMaxNumSubgroups: *hasResult = true; *hasResultType = true; break; + case SpvOpTypeNamedBarrier: *hasResult = true; *hasResultType = false; break; + case SpvOpNamedBarrierInitialize: *hasResult = true; *hasResultType = true; break; + case SpvOpMemoryNamedBarrier: *hasResult = false; *hasResultType = false; break; + case SpvOpModuleProcessed: *hasResult = false; *hasResultType = false; break; + case SpvOpExecutionModeId: *hasResult = false; *hasResultType = false; break; + case SpvOpDecorateId: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupNonUniformElect: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformAll: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformAny: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformAllEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBroadcast: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBroadcastFirst: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBallot: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformInverseBallot: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBallotBitExtract: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBallotBitCount: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBallotFindLSB: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBallotFindMSB: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformShuffle: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformShuffleXor: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformShuffleUp: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformShuffleDown: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformIAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformFAdd: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformIMul: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformFMul: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformSMin: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformUMin: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformFMin: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformSMax: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformUMax: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformFMax: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBitwiseAnd: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBitwiseOr: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformBitwiseXor: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformLogicalAnd: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformLogicalOr: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformLogicalXor: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformQuadBroadcast: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformQuadSwap: *hasResult = true; *hasResultType = true; break; + case SpvOpCopyLogical: *hasResult = true; *hasResultType = true; break; + case SpvOpPtrEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpPtrNotEqual: *hasResult = true; *hasResultType = true; break; + case SpvOpPtrDiff: *hasResult = true; *hasResultType = true; break; + case SpvOpTerminateInvocation: *hasResult = false; *hasResultType = false; break; + case SpvOpSubgroupBallotKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupFirstInvocationKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpTraceRayKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpIgnoreIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpTerminateRayKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpSDot: *hasResult = true; *hasResultType = true; break; + case SpvOpUDot: *hasResult = true; *hasResultType = true; break; + case SpvOpSUDot: *hasResult = true; *hasResultType = true; break; + case SpvOpSDotAccSat: *hasResult = true; *hasResultType = true; break; + case SpvOpUDotAccSat: *hasResult = true; *hasResultType = true; break; + case SpvOpSUDotAccSat: *hasResult = true; *hasResultType = true; break; + case SpvOpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break; + case SpvOpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpRayQueryGenerateIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpRayQueryConfirmIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpRayQueryProceedKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionTypeKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupUMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupSMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupUMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupSMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpFragmentMaskFetchAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break; + case SpvOpReadClockKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpImageSampleFootprintNV: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformPartitionNV: *hasResult = true; *hasResultType = true; break; + case SpvOpWritePackedPrimitiveIndices4x8NV: *hasResult = false; *hasResultType = false; break; + case SpvOpReportIntersectionNV: *hasResult = true; *hasResultType = true; break; + case SpvOpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break; + case SpvOpTerminateRayNV: *hasResult = false; *hasResultType = false; break; + case SpvOpTraceNV: *hasResult = false; *hasResultType = false; break; + case SpvOpTraceMotionNV: *hasResult = false; *hasResultType = false; break; + case SpvOpTraceRayMotionNV: *hasResult = false; *hasResultType = false; break; + case SpvOpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break; + case SpvOpExecuteCallableNV: *hasResult = false; *hasResultType = false; break; + case SpvOpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break; + case SpvOpCooperativeMatrixLoadNV: *hasResult = true; *hasResultType = true; break; + case SpvOpCooperativeMatrixStoreNV: *hasResult = false; *hasResultType = false; break; + case SpvOpCooperativeMatrixMulAddNV: *hasResult = true; *hasResultType = true; break; + case SpvOpCooperativeMatrixLengthNV: *hasResult = true; *hasResultType = true; break; + case SpvOpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; + case SpvOpEndInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; + case SpvOpDemoteToHelperInvocation: *hasResult = false; *hasResultType = false; break; + case SpvOpIsHelperInvocationEXT: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertUToImageNV: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertUToSamplerNV: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertImageToUNV: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertSamplerToUNV: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertUToSampledImageNV: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertSampledImageToUNV: *hasResult = true; *hasResultType = true; break; + case SpvOpSamplerImageAddressingModeNV: *hasResult = false; *hasResultType = false; break; + case SpvOpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupShuffleXorINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpSubgroupImageBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupImageBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpSubgroupImageMediaBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupImageMediaBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpUCountLeadingZerosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpUCountTrailingZerosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpAbsISubINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpAbsUSubINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpIAddSatINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpUAddSatINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpIAverageINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpUAverageINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpIAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpUAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpISubSatINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpUSubSatINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpConstantFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpAsmTargetINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpAsmINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpAsmCallINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicFMinEXT: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicFMaxEXT: *hasResult = true; *hasResultType = true; break; + case SpvOpAssumeTrueKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpExpectKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpDecorateString: *hasResult = false; *hasResultType = false; break; + case SpvOpMemberDecorateString: *hasResult = false; *hasResultType = false; break; + case SpvOpVmeImageINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpTypeVmeImageINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcImePayloadINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcRefPayloadINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcSicPayloadINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcMcePayloadINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcMceResultINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcImeResultINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcImeResultSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcImeResultDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcImeSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcImeDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcRefResultINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAvcSicResultINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetMotionVectorCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetAcOnlyHaarINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceConvertToImePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceConvertToImeResultINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceConvertToRefPayloadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceConvertToRefResultINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceConvertToSicPayloadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceConvertToSicResultINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetBestInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterMajorShapeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterMinorShapeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterDirectionsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeSetSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeSetDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeRefWindowSizeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeAdjustRefOffsetINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeSetMaxMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeSetUnidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeSetWeightedSadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeStripSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeStripDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetBorderReachedINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetTruncatedSearchIndicationINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcFmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcBmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefSetBidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcRefConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicConfigureSkcINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicConfigureIpeLumaINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicConfigureIpeLumaChromaINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetMotionVectorMaskINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicSetSkcForwardTransformEnableINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicEvaluateIpeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetIpeLumaShapeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetBestIpeLumaDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetBestIpeChromaDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetPackedIpeLumaModesINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetIpeChromaModeINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpVariableLengthArrayINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpRestoreMemoryINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpArbitraryFloatSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatCastINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatCastFromIntINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatCastToIntINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatAddINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatSubINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatMulINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatDivINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatGTINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatGEINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatLTINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatLEINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatEQINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatRecipINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatRSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatCbrtINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatHypotINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatLogINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatLog2INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatLog10INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatLog1pINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatExpINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatExp2INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatExp10INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatExpm1INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatSinINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatCosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatSinCosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatSinPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatASinINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatASinPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatACosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatACosPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatATanINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatATanPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatATan2INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatPowINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatPowRINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatPowNINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpLoopControlINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpAliasDomainDeclINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpAliasScopeDeclINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpAliasScopeListDeclINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpFixedSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedRecipINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedRsqrtINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedSinINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedCosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedSinCosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedSinPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedLogINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedExpINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpPtrCastToCrossWorkgroupINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFPGARegINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetRayTMinKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetRayFlagsKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionTKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionInstanceCustomIndexKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionInstanceIdKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionGeometryIndexKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionPrimitiveIndexKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionBarycentricsKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionFrontFaceKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionCandidateAABBOpaqueKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionObjectRayDirectionKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionObjectRayOriginKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetWorldRayDirectionKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetWorldRayOriginKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break; + case SpvOpTypeBufferSurfaceINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + } +} +#endif /* SPV_ENABLE_UTILITY_CODE */ + +#endif diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-common/blob.c b/dll/directx/wine/vkd3d/libs/vkd3d-common/blob.c similarity index 99% rename from dll/directx/wine/d3d12/vkd3d/vkd3d-common/blob.c rename to dll/directx/wine/vkd3d/libs/vkd3d-common/blob.c index c46abb558cbd5..30205088b1b19 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-common/blob.c +++ b/dll/directx/wine/vkd3d/libs/vkd3d-common/blob.c @@ -17,7 +17,6 @@ */ #define COBJMACROS -#define INITGUID #include "vkd3d.h" #include "vkd3d_blob.h" #include "vkd3d_debug.h" diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-common/debug.c b/dll/directx/wine/vkd3d/libs/vkd3d-common/debug.c similarity index 78% rename from dll/directx/wine/d3d12/vkd3d/vkd3d-common/debug.c rename to dll/directx/wine/vkd3d/libs/vkd3d-common/debug.c index 4868f3fbaa884..499334a35f162 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-common/debug.c +++ b/dll/directx/wine/vkd3d/libs/vkd3d-common/debug.c @@ -16,6 +16,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#ifdef _WIN32 +# define _WIN32_WINNT 0x0600 /* For InitOnceExecuteOnce(). */ +#endif + #include "vkd3d_debug.h" #include @@ -27,6 +31,11 @@ #include #include #include +#ifdef HAVE_PTHREAD_H +#include +#endif + +#include "vkd3d_memory.h" #define VKD3D_DEBUG_BUFFER_COUNT 64 #define VKD3D_DEBUG_BUFFER_SIZE 512 @@ -68,6 +77,25 @@ enum vkd3d_dbg_level vkd3d_dbg_get_level(void) return level; } +static PFN_vkd3d_log log_callback; + +static void vkd3d_dbg_voutput(const char *fmt, va_list args) +{ + if (log_callback) + log_callback(fmt, args); + else + vfprintf(stderr, fmt, args); +} + +static void vkd3d_dbg_output(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vkd3d_dbg_voutput(fmt, args); + va_end(args); +} + void vkd3d_dbg_printf(enum vkd3d_dbg_level level, const char *function, const char *fmt, ...) { va_list args; @@ -77,12 +105,17 @@ void vkd3d_dbg_printf(enum vkd3d_dbg_level level, const char *function, const ch assert(level < ARRAY_SIZE(debug_level_names)); - fprintf(stderr, "%s:%s: ", debug_level_names[level], function); + vkd3d_dbg_output("vkd3d:%s:%s ", debug_level_names[level], function); va_start(args, fmt); - vfprintf(stderr, fmt, args); + vkd3d_dbg_voutput(fmt, args); va_end(args); } +void vkd3d_dbg_set_log_callback(PFN_vkd3d_log callback) +{ + log_callback = callback; +} + static char *get_buffer(void) { static char buffers[VKD3D_DEBUG_BUFFER_COUNT][VKD3D_DEBUG_BUFFER_SIZE]; @@ -345,3 +378,49 @@ uint64_t vkd3d_parse_debug_options(const char *string, return flags; } + +#ifdef _WIN32 + +static HRESULT (WINAPI *pfn_SetThreadDescription)(HANDLE, const WCHAR *); +static BOOL WINAPI resolve_SetThreadDescription(INIT_ONCE *once, void *param, void **context) +{ + HMODULE kernelbase; + + if (!(kernelbase = LoadLibraryA("kernelbase.dll"))) + return TRUE; + + if (!(pfn_SetThreadDescription = (void *)GetProcAddress(kernelbase, "SetThreadDescription"))) + FreeLibrary(kernelbase); + + return TRUE; +} + +#endif + +void vkd3d_set_thread_name(const char *name) +{ +#ifdef _WIN32 + static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT; + WCHAR *wname; + int ret; + + InitOnceExecuteOnce(&init_once, resolve_SetThreadDescription, NULL, NULL); + if (!pfn_SetThreadDescription) + return; + + if ((ret = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0)) <= 0) + return; + + if (!(wname = vkd3d_malloc(ret * sizeof(*wname)))) + return; + + if ((ret = MultiByteToWideChar(CP_UTF8, 0, name, -1, wname, ret)) > 0) + pfn_SetThreadDescription(GetCurrentThread(), wname); + + vkd3d_free(wname); +#elif defined(HAVE_PTHREAD_SETNAME_NP_2) + pthread_setname_np(pthread_self(), name); +#elif defined(HAVE_PTHREAD_SETNAME_NP_1) + pthread_setname_np(name); +#endif +} diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-common/error.c b/dll/directx/wine/vkd3d/libs/vkd3d-common/error.c similarity index 96% rename from dll/directx/wine/d3d12/vkd3d/vkd3d-common/error.c rename to dll/directx/wine/vkd3d/libs/vkd3d-common/error.c index 81c1fd97a585f..3572669ac1c04 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-common/error.c +++ b/dll/directx/wine/vkd3d/libs/vkd3d-common/error.c @@ -26,7 +26,7 @@ HRESULT hresult_from_vkd3d_result(int vkd3d_result) case VKD3D_OK: return S_OK; case VKD3D_ERROR_INVALID_SHADER: - WARN("Invalid shader bytecode.\n"); + WARN("Invalid shader.\n"); /* fall-through */ case VKD3D_ERROR: return E_FAIL; diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-common/memory.c b/dll/directx/wine/vkd3d/libs/vkd3d-common/memory.c similarity index 100% rename from dll/directx/wine/d3d12/vkd3d/vkd3d-common/memory.c rename to dll/directx/wine/vkd3d/libs/vkd3d-common/memory.c diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-common/utf8.c b/dll/directx/wine/vkd3d/libs/vkd3d-common/utf8.c similarity index 100% rename from dll/directx/wine/d3d12/vkd3d/vkd3d-common/utf8.c rename to dll/directx/wine/vkd3d/libs/vkd3d-common/utf8.c diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/checksum.c b/dll/directx/wine/vkd3d/libs/vkd3d-shader/checksum.c similarity index 100% rename from dll/directx/wine/d3d12/vkd3d/vkd3d-shader/checksum.c rename to dll/directx/wine/vkd3d/libs/vkd3d-shader/checksum.c diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/d3dbc.c b/dll/directx/wine/vkd3d/libs/vkd3d-shader/d3dbc.c similarity index 91% rename from dll/directx/wine/d3d12/vkd3d/vkd3d-shader/d3dbc.c rename to dll/directx/wine/vkd3d/libs/vkd3d-shader/d3dbc.c index c5518752a2ba1..ed81137d225f0 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/d3dbc.c +++ b/dll/directx/wine/vkd3d/libs/vkd3d-shader/d3dbc.c @@ -210,13 +210,6 @@ struct vkd3d_shader_sm1_parser const uint32_t *start, *end; bool abort; - struct vkd3d_shader_src_param src_rel_addr[4]; - struct vkd3d_shader_src_param pred_rel_addr; - struct vkd3d_shader_src_param dst_rel_addr; - struct vkd3d_shader_src_param src_param[4]; - struct vkd3d_shader_src_param pred_param; - struct vkd3d_shader_dst_param dst_param; - struct vkd3d_shader_parser p; }; @@ -556,33 +549,50 @@ static void shader_sm1_destroy(struct vkd3d_shader_parser *parser) { struct vkd3d_shader_sm1_parser *sm1 = vkd3d_shader_sm1_parser(parser); + shader_instruction_array_destroy(&parser->instructions); free_shader_desc(&sm1->p.shader_desc); vkd3d_free(sm1); } static void shader_sm1_read_src_param(struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr, - struct vkd3d_shader_src_param *src_param, struct vkd3d_shader_src_param *src_rel_addr) + struct vkd3d_shader_src_param *src_param) { + struct vkd3d_shader_src_param *src_rel_addr = NULL; uint32_t token, addr_token; shader_sm1_read_param(sm1, ptr, &token, &addr_token); if (has_relative_address(token)) + { + if (!(src_rel_addr = shader_parser_get_src_params(&sm1->p, 1))) + { + vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, + "Out of memory."); + sm1->abort = true; + return; + } shader_sm1_parse_src_param(addr_token, NULL, src_rel_addr); - else - src_rel_addr = NULL; + } shader_sm1_parse_src_param(token, src_rel_addr, src_param); } static void shader_sm1_read_dst_param(struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr, - struct vkd3d_shader_dst_param *dst_param, struct vkd3d_shader_src_param *dst_rel_addr) + struct vkd3d_shader_dst_param *dst_param) { + struct vkd3d_shader_src_param *dst_rel_addr = NULL; uint32_t token, addr_token; shader_sm1_read_param(sm1, ptr, &token, &addr_token); if (has_relative_address(token)) + { + if (!(dst_rel_addr = shader_parser_get_src_params(&sm1->p, 1))) + { + vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, + "Out of memory."); + sm1->abort = true; + return; + } shader_sm1_parse_src_param(addr_token, NULL, dst_rel_addr); - else - dst_rel_addr = NULL; + } shader_sm1_parse_dst_param(token, dst_rel_addr, dst_param); } @@ -731,10 +741,13 @@ static void shader_sm1_validate_instruction(struct vkd3d_shader_sm1_parser *sm1, static void shader_sm1_read_instruction(struct vkd3d_shader_parser *parser, struct vkd3d_shader_instruction *ins) { struct vkd3d_shader_sm1_parser *sm1 = vkd3d_shader_sm1_parser(parser); + struct vkd3d_shader_src_param *src_params, *predicate; const struct vkd3d_sm1_opcode_info *opcode_info; + struct vkd3d_shader_dst_param *dst_param; const uint32_t **ptr = &parser->ptr; uint32_t opcode_token; const uint32_t *p; + bool predicated; unsigned int i; shader_sm1_read_comment(sm1); @@ -761,11 +774,18 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_parser *parser, stru ins->coissue = opcode_token & VKD3D_SM1_COISSUE; ins->raw = false; ins->structured = false; - ins->predicate = opcode_token & VKD3D_SM1_INSTRUCTION_PREDICATED ? &sm1->pred_param : NULL; + predicated = !!(opcode_token & VKD3D_SM1_INSTRUCTION_PREDICATED); + ins->predicate = predicate = predicated ? shader_parser_get_src_params(parser, 1) : NULL; ins->dst_count = opcode_info->dst_count; - ins->dst = &sm1->dst_param; + ins->dst = dst_param = shader_parser_get_dst_params(parser, ins->dst_count); ins->src_count = opcode_info->src_count; - ins->src = sm1->src_param; + ins->src = src_params = shader_parser_get_src_params(parser, ins->src_count); + if ((!predicate && predicated) || (!src_params && ins->src_count) || (!dst_param && ins->dst_count)) + { + vkd3d_shader_parser_error(parser, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, "Out of memory."); + goto fail; + } + ins->resource_type = VKD3D_SHADER_RESOURCE_NONE; ins->resource_stride = 0; ins->resource_data_type[0] = VKD3D_DATA_FLOAT; @@ -790,32 +810,32 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_parser *parser, stru } else if (ins->handler_idx == VKD3DSIH_DEF) { - shader_sm1_read_dst_param(sm1, &p, &sm1->dst_param, &sm1->dst_rel_addr); - shader_sm1_read_immconst(sm1, &p, &sm1->src_param[0], VKD3D_IMMCONST_VEC4, VKD3D_DATA_FLOAT); + shader_sm1_read_dst_param(sm1, &p, dst_param); + shader_sm1_read_immconst(sm1, &p, &src_params[0], VKD3D_IMMCONST_VEC4, VKD3D_DATA_FLOAT); } else if (ins->handler_idx == VKD3DSIH_DEFB) { - shader_sm1_read_dst_param(sm1, &p, &sm1->dst_param, &sm1->dst_rel_addr); - shader_sm1_read_immconst(sm1, &p, &sm1->src_param[0], VKD3D_IMMCONST_SCALAR, VKD3D_DATA_UINT); + shader_sm1_read_dst_param(sm1, &p, dst_param); + shader_sm1_read_immconst(sm1, &p, &src_params[0], VKD3D_IMMCONST_SCALAR, VKD3D_DATA_UINT); } else if (ins->handler_idx == VKD3DSIH_DEFI) { - shader_sm1_read_dst_param(sm1, &p, &sm1->dst_param, &sm1->dst_rel_addr); - shader_sm1_read_immconst(sm1, &p, &sm1->src_param[0], VKD3D_IMMCONST_VEC4, VKD3D_DATA_INT); + shader_sm1_read_dst_param(sm1, &p, dst_param); + shader_sm1_read_immconst(sm1, &p, &src_params[0], VKD3D_IMMCONST_VEC4, VKD3D_DATA_INT); } else { /* Destination token */ if (ins->dst_count) - shader_sm1_read_dst_param(sm1, &p, &sm1->dst_param, &sm1->dst_rel_addr); + shader_sm1_read_dst_param(sm1, &p, dst_param); /* Predication token */ if (ins->predicate) - shader_sm1_read_src_param(sm1, &p, &sm1->pred_param, &sm1->pred_rel_addr); + shader_sm1_read_src_param(sm1, &p, predicate); /* Other source tokens */ for (i = 0; i < ins->src_count; ++i) - shader_sm1_read_src_param(sm1, &p, &sm1->src_param[i], &sm1->src_rel_addr[i]); + shader_sm1_read_src_param(sm1, &p, &src_params[i]); } if (sm1->abort) @@ -851,20 +871,9 @@ static bool shader_sm1_is_end(struct vkd3d_shader_parser *parser) return false; } -static void shader_sm1_reset(struct vkd3d_shader_parser *parser) -{ - struct vkd3d_shader_sm1_parser *sm1 = vkd3d_shader_sm1_parser(parser); - - parser->ptr = sm1->start; - parser->failed = false; -} - const struct vkd3d_shader_parser_ops shader_sm1_parser_ops = { - .parser_reset = shader_sm1_reset, .parser_destroy = shader_sm1_destroy, - .parser_read_instruction = shader_sm1_read_instruction, - .parser_is_end = shader_sm1_is_end, }; static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1, @@ -922,7 +931,10 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1, sm1->start = &code[1]; sm1->end = &code[token_count]; - vkd3d_shader_parser_init(&sm1->p, message_context, compile_info->source_name, &version, &shader_sm1_parser_ops); + /* Estimate instruction count to avoid reallocation in most shaders. */ + if (!vkd3d_shader_parser_init(&sm1->p, message_context, compile_info->source_name, &version, &shader_sm1_parser_ops, + code_size != ~(size_t)0 ? token_count / 4u + 4 : 16)) + return VKD3D_ERROR_OUT_OF_MEMORY; shader_desc = &sm1->p.shader_desc; shader_desc->byte_code = code; shader_desc->byte_code_size = code_size; @@ -934,6 +946,8 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1, int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser) { + struct vkd3d_shader_instruction_array *instructions; + struct vkd3d_shader_instruction *ins; struct vkd3d_shader_sm1_parser *sm1; int ret; @@ -950,6 +964,28 @@ int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compi return ret; } + instructions = &sm1->p.instructions; + while (!shader_sm1_is_end(&sm1->p)) + { + if (!shader_instruction_array_reserve(instructions, instructions->count + 1)) + { + ERR("Failed to allocate instructions.\n"); + vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, "Out of memory."); + shader_sm1_destroy(&sm1->p); + return VKD3D_ERROR_OUT_OF_MEMORY; + } + ins = &instructions->elements[instructions->count]; + shader_sm1_read_instruction(&sm1->p, ins); + + if (ins->handler_idx == VKD3DSIH_INVALID) + { + WARN("Encountered unrecognized or invalid instruction.\n"); + shader_sm1_destroy(&sm1->p); + return VKD3D_ERROR_INVALID_SHADER; + } + ++instructions->count; + } + *parser = &sm1->p; return VKD3D_OK; diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/dxbc.c b/dll/directx/wine/vkd3d/libs/vkd3d-shader/dxbc.c similarity index 92% rename from dll/directx/wine/d3d12/vkd3d/vkd3d-shader/dxbc.c rename to dll/directx/wine/vkd3d/libs/vkd3d-shader/dxbc.c index 1ab71ca47142a..d99ea2e36b683 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/dxbc.c +++ b/dll/directx/wine/vkd3d/libs/vkd3d-shader/dxbc.c @@ -21,6 +21,11 @@ #include "vkd3d_shader_private.h" #include "sm4.h" +#define SM4_MAX_SRC_COUNT 6 +#define SM4_MAX_DST_COUNT 2 + +STATIC_ASSERT(SM4_MAX_SRC_COUNT <= SPIRV_MAX_SRC_COUNT); + void dxbc_writer_init(struct dxbc_writer *dxbc) { memset(dxbc, 0, sizeof(*dxbc)); @@ -28,22 +33,28 @@ void dxbc_writer_init(struct dxbc_writer *dxbc) void dxbc_writer_add_section(struct dxbc_writer *dxbc, uint32_t tag, const void *data, size_t size) { - struct dxbc_writer_section *section; + struct vkd3d_shader_dxbc_section_desc *section; assert(dxbc->section_count < ARRAY_SIZE(dxbc->sections)); section = &dxbc->sections[dxbc->section_count++]; section->tag = tag; - section->data = data; - section->size = size; + section->data.code = data; + section->data.size = size; } -int dxbc_writer_write(struct dxbc_writer *dxbc, struct vkd3d_shader_code *out) +int vkd3d_shader_serialize_dxbc(size_t section_count, const struct vkd3d_shader_dxbc_section_desc *sections, + struct vkd3d_shader_code *dxbc, char **messages) { size_t size_position, offsets_position, checksum_position, i; struct vkd3d_bytecode_buffer buffer = {0}; uint32_t checksum[4]; + TRACE("section_count %zu, sections %p, dxbc %p, messages %p.\n", section_count, sections, dxbc, messages); + + if (messages) + *messages = NULL; + put_u32(&buffer, TAG_DXBC); checksum_position = bytecode_get_size(&buffer); @@ -52,18 +63,18 @@ int dxbc_writer_write(struct dxbc_writer *dxbc, struct vkd3d_shader_code *out) put_u32(&buffer, 1); /* version */ size_position = put_u32(&buffer, 0); - put_u32(&buffer, dxbc->section_count); + put_u32(&buffer, section_count); offsets_position = bytecode_get_size(&buffer); - for (i = 0; i < dxbc->section_count; ++i) + for (i = 0; i < section_count; ++i) put_u32(&buffer, 0); - for (i = 0; i < dxbc->section_count; ++i) + for (i = 0; i < section_count; ++i) { set_u32(&buffer, offsets_position + i * sizeof(uint32_t), bytecode_get_size(&buffer)); - put_u32(&buffer, dxbc->sections[i].tag); - put_u32(&buffer, dxbc->sections[i].size); - bytecode_put_bytes(&buffer, dxbc->sections[i].data, dxbc->sections[i].size); + put_u32(&buffer, sections[i].tag); + put_u32(&buffer, sections[i].data.size); + bytecode_put_bytes(&buffer, sections[i].data.code, sections[i].data.size); } set_u32(&buffer, size_position, bytecode_get_size(&buffer)); @@ -73,12 +84,17 @@ int dxbc_writer_write(struct dxbc_writer *dxbc, struct vkd3d_shader_code *out) if (!buffer.status) { - out->code = buffer.data; - out->size = buffer.size; + dxbc->code = buffer.data; + dxbc->size = buffer.size; } return buffer.status; } +int dxbc_writer_write(struct dxbc_writer *dxbc, struct vkd3d_shader_code *out) +{ + return vkd3d_shader_serialize_dxbc(dxbc->section_count, dxbc->sections, out, NULL); +} + struct vkd3d_shader_src_param_entry { struct list entry; @@ -91,12 +107,6 @@ struct vkd3d_shader_sm4_parser unsigned int output_map[MAX_REG_OUTPUT]; - struct vkd3d_shader_src_param src_param[6]; - struct vkd3d_shader_dst_param dst_param[2]; - struct list src_free; - struct list src; - struct vkd3d_shader_immediate_constant_buffer icb; - struct vkd3d_shader_parser p; }; @@ -104,8 +114,8 @@ struct vkd3d_sm4_opcode_info { enum vkd3d_sm4_opcode opcode; enum vkd3d_shader_opcode handler_idx; - const char *dst_info; - const char *src_info; + char dst_info[SM4_MAX_DST_COUNT]; + char src_info[SM4_MAX_SRC_COUNT]; void (*read_opcode_func)(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv); }; @@ -201,7 +211,8 @@ static bool shader_sm4_read_register_space(struct vkd3d_shader_sm4_parser *priv, static void shader_sm4_read_conditional_op(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) { - shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_UINT, &priv->src_param[0]); + shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_UINT, + (struct vkd3d_shader_src_param *)&ins->src[0]); ins->flags = (opcode_token & VKD3D_SM4_CONDITIONAL_NZ) ? VKD3D_SHADER_CONDITIONAL_OP_NZ : VKD3D_SHADER_CONDITIONAL_OP_Z; } @@ -209,6 +220,7 @@ static void shader_sm4_read_conditional_op(struct vkd3d_shader_instruction *ins, static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) { + struct vkd3d_shader_immediate_constant_buffer *icb; enum vkd3d_sm4_shader_data_type type; unsigned int icb_size; @@ -222,16 +234,24 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui ++tokens; icb_size = token_count - 1; - if (icb_size % 4 || icb_size > MAX_IMMEDIATE_CONSTANT_BUFFER_SIZE) + if (icb_size % 4) { FIXME("Unexpected immediate constant buffer size %u.\n", icb_size); ins->handler_idx = VKD3DSIH_INVALID; return; } - priv->icb.vec4_count = icb_size / 4; - memcpy(priv->icb.data, tokens, sizeof(*tokens) * icb_size); - ins->declaration.icb = &priv->icb; + if (!(icb = vkd3d_malloc(offsetof(struct vkd3d_shader_immediate_constant_buffer, data[icb_size])))) + { + ERR("Failed to allocate immediate constant buffer, size %u.\n", icb_size); + vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_OUT_OF_MEMORY, "Out of memory."); + ins->handler_idx = VKD3DSIH_INVALID; + return; + } + icb->vec4_count = icb_size / 4; + memcpy(icb->data, tokens, sizeof(*tokens) * icb_size); + shader_instruction_array_add_icb(&priv->p.instructions, icb); + ins->declaration.icb = icb; } static void shader_sm4_set_descriptor_register_range(struct vkd3d_shader_sm4_parser *sm4, @@ -268,6 +288,13 @@ static void shader_sm4_read_dcl_resource(struct vkd3d_shader_instruction *ins, u { semantic->resource_type = resource_type_table[resource_type]; } + + if (semantic->resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS + || semantic->resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY) + { + semantic->sample_count = (opcode_token & VKD3D_SM4_RESOURCE_SAMPLE_COUNT_MASK) >> VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT; + } + reg_data_type = opcode == VKD3D_SM4_OP_DCL_RESOURCE ? VKD3D_DATA_RESOURCE : VKD3D_DATA_UAV; shader_sm4_read_dst_param(priv, &tokens, end, reg_data_type, &semantic->resource.reg); shader_sm4_set_descriptor_register_range(priv, &semantic->resource.reg.reg, &semantic->resource.range); @@ -433,8 +460,9 @@ static void shader_sm4_read_dcl_global_flags(struct vkd3d_shader_instruction *in static void shader_sm5_read_fcall(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) { - priv->src_param[0].reg.u.fp_body_idx = *tokens++; - shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_OPAQUE, &priv->src_param[0]); + struct vkd3d_shader_src_param *src_params = (struct vkd3d_shader_src_param *)ins->src; + src_params[0].reg.u.fp_body_idx = *tokens++; + shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_OPAQUE, &src_params[0]); } static void shader_sm5_read_dcl_function_body(struct vkd3d_shader_instruction *ins, uint32_t opcode, @@ -682,7 +710,7 @@ static const struct vkd3d_sm4_opcode_info opcode_table[] = {VKD3D_SM4_OP_USHR, VKD3DSIH_USHR, "u", "uu"}, {VKD3D_SM4_OP_UTOF, VKD3DSIH_UTOF, "f", "u"}, {VKD3D_SM4_OP_XOR, VKD3DSIH_XOR, "u", "uu"}, - {VKD3D_SM4_OP_DCL_RESOURCE, VKD3DSIH_DCL, "R", "", + {VKD3D_SM4_OP_DCL_RESOURCE, VKD3DSIH_DCL, "", "", shader_sm4_read_dcl_resource}, {VKD3D_SM4_OP_DCL_CONSTANT_BUFFER, VKD3DSIH_DCL_CONSTANT_BUFFER, "", "", shader_sm4_read_dcl_constant_buffer}, @@ -837,6 +865,7 @@ static const struct vkd3d_sm4_opcode_info opcode_table[] = {VKD3D_SM5_OP_DDIV, VKD3DSIH_DDIV, "d", "dd"}, {VKD3D_SM5_OP_DFMA, VKD3DSIH_DFMA, "d", "ddd"}, {VKD3D_SM5_OP_DRCP, VKD3DSIH_DRCP, "d", "d"}, + {VKD3D_SM5_OP_MSAD, VKD3DSIH_MSAD, "u", "uuu"}, {VKD3D_SM5_OP_DTOI, VKD3DSIH_DTOI, "i", "d"}, {VKD3D_SM5_OP_DTOU, VKD3DSIH_DTOU, "u", "d"}, {VKD3D_SM5_OP_ITOD, VKD3DSIH_ITOD, "d", "i"}, @@ -981,45 +1010,18 @@ static enum vkd3d_data_type map_data_type(char t) static void shader_sm4_destroy(struct vkd3d_shader_parser *parser) { struct vkd3d_shader_sm4_parser *sm4 = vkd3d_shader_sm4_parser(parser); - struct vkd3d_shader_src_param_entry *e1, *e2; - list_move_head(&sm4->src_free, &sm4->src); - LIST_FOR_EACH_ENTRY_SAFE(e1, e2, &sm4->src_free, struct vkd3d_shader_src_param_entry, entry) - { - vkd3d_free(e1); - } + shader_instruction_array_destroy(&parser->instructions); free_shader_desc(&parser->shader_desc); vkd3d_free(sm4); } -static struct vkd3d_shader_src_param *get_src_param(struct vkd3d_shader_sm4_parser *priv) -{ - struct vkd3d_shader_src_param_entry *e; - struct list *elem; - - if (!list_empty(&priv->src_free)) - { - elem = list_head(&priv->src_free); - list_remove(elem); - } - else - { - if (!(e = vkd3d_malloc(sizeof(*e)))) - return NULL; - elem = &e->entry; - } - - list_add_tail(&priv->src, elem); - e = LIST_ENTRY(elem, struct vkd3d_shader_src_param_entry, entry); - return &e->param; -} - static bool shader_sm4_read_reg_idx(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr, const uint32_t *end, uint32_t addressing, struct vkd3d_shader_register_index *reg_idx) { if (addressing & VKD3D_SM4_ADDRESSING_RELATIVE) { - struct vkd3d_shader_src_param *rel_addr = get_src_param(priv); + struct vkd3d_shader_src_param *rel_addr = shader_parser_get_src_params(&priv->p, 1); if (!(reg_idx->rel_addr = rel_addr)) { @@ -1462,14 +1464,14 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_parser *parser, stru struct vkd3d_shader_sm4_parser *sm4 = vkd3d_shader_sm4_parser(parser); const struct vkd3d_sm4_opcode_info *opcode_info; uint32_t opcode_token, opcode, previous_token; + struct vkd3d_shader_dst_param *dst_params; + struct vkd3d_shader_src_param *src_params; const uint32_t **ptr = &parser->ptr; unsigned int i, len; size_t remaining; const uint32_t *p; DWORD precise; - list_move_head(&sm4->src_free, &sm4->src); - if (*ptr >= sm4->end) { WARN("End of byte-code, failed to read opcode.\n"); @@ -1513,12 +1515,16 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_parser *parser, stru ins->raw = false; ins->structured = false; ins->predicate = NULL; - ins->dst_count = strlen(opcode_info->dst_info); - ins->dst = sm4->dst_param; - ins->src_count = strlen(opcode_info->src_info); - ins->src = sm4->src_param; - assert(ins->dst_count <= ARRAY_SIZE(sm4->dst_param)); - assert(ins->src_count <= ARRAY_SIZE(sm4->src_param)); + ins->dst_count = strnlen(opcode_info->dst_info, SM4_MAX_DST_COUNT); + ins->src_count = strnlen(opcode_info->src_info, SM4_MAX_SRC_COUNT); + ins->src = src_params = shader_parser_get_src_params(parser, ins->src_count); + if (!src_params && ins->src_count) + { + ERR("Failed to allocate src parameters.\n"); + vkd3d_shader_parser_error(parser, VKD3D_SHADER_ERROR_TPF_OUT_OF_MEMORY, "Out of memory."); + ins->handler_idx = VKD3DSIH_INVALID; + return; + } ins->resource_type = VKD3D_SHADER_RESOURCE_NONE; ins->resource_stride = 0; ins->resource_data_type[0] = VKD3D_DATA_FLOAT; @@ -1532,6 +1538,8 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_parser *parser, stru if (opcode_info->read_opcode_func) { + ins->dst = NULL; + ins->dst_count = 0; opcode_info->read_opcode_func(ins, opcode, opcode_token, p, len, sm4); } else @@ -1551,21 +1559,29 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_parser *parser, stru precise = (opcode_token & VKD3D_SM5_PRECISE_MASK) >> VKD3D_SM5_PRECISE_SHIFT; ins->flags |= precise << VKD3DSI_PRECISE_SHIFT; + ins->dst = dst_params = shader_parser_get_dst_params(parser, ins->dst_count); + if (!dst_params && ins->dst_count) + { + ERR("Failed to allocate dst parameters.\n"); + vkd3d_shader_parser_error(parser, VKD3D_SHADER_ERROR_TPF_OUT_OF_MEMORY, "Out of memory."); + ins->handler_idx = VKD3DSIH_INVALID; + return; + } for (i = 0; i < ins->dst_count; ++i) { if (!(shader_sm4_read_dst_param(sm4, &p, *ptr, map_data_type(opcode_info->dst_info[i]), - &sm4->dst_param[i]))) + &dst_params[i]))) { ins->handler_idx = VKD3DSIH_INVALID; return; } - sm4->dst_param[i].modifiers |= instruction_dst_modifier; + dst_params[i].modifiers |= instruction_dst_modifier; } for (i = 0; i < ins->src_count; ++i) { if (!(shader_sm4_read_src_param(sm4, &p, *ptr, map_data_type(opcode_info->src_info[i]), - &sm4->src_param[i]))) + &src_params[i]))) { ins->handler_idx = VKD3DSIH_INVALID; return; @@ -1588,20 +1604,9 @@ static bool shader_sm4_is_end(struct vkd3d_shader_parser *parser) return parser->ptr == sm4->end; } -static void shader_sm4_reset(struct vkd3d_shader_parser *parser) -{ - struct vkd3d_shader_sm4_parser *sm4 = vkd3d_shader_sm4_parser(parser); - - parser->ptr = sm4->start; - parser->failed = false; -} - static const struct vkd3d_shader_parser_ops shader_sm4_parser_ops = { - .parser_reset = shader_sm4_reset, .parser_destroy = shader_sm4_destroy, - .parser_read_instruction = shader_sm4_read_instruction, - .parser_is_end = shader_sm4_is_end, }; static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, const uint32_t *byte_code, @@ -1664,7 +1669,10 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, const uint32_t version.major = VKD3D_SM4_VERSION_MAJOR(version_token); version.minor = VKD3D_SM4_VERSION_MINOR(version_token); - vkd3d_shader_parser_init(&sm4->p, message_context, source_name, &version, &shader_sm4_parser_ops); + /* Estimate instruction count to avoid reallocation in most shaders. */ + if (!vkd3d_shader_parser_init(&sm4->p, message_context, source_name, &version, &shader_sm4_parser_ops, + token_count / 7u + 20)) + return false; sm4->p.ptr = sm4->start; memset(sm4->output_map, 0xff, sizeof(sm4->output_map)); @@ -1684,9 +1692,6 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, const uint32_t sm4->output_map[e->register_index] = e->semantic_index; } - list_init(&sm4->src_free); - list_init(&sm4->src); - return true; } @@ -1712,6 +1717,9 @@ static void skip_dword_unknown(const char **ptr, unsigned int count) unsigned int i; uint32_t d; + if (!count) + return; + WARN("Skipping %u unknown DWORDs:\n", count); for (i = 0; i < count; ++i) { @@ -1739,18 +1747,19 @@ static const char *shader_get_string(const char *data, size_t data_size, DWORD o return data + offset; } -static int parse_dxbc(const char *data, size_t data_size, - struct vkd3d_shader_message_context *message_context, const char *source_name, - int (*chunk_handler)(const char *data, DWORD data_size, DWORD tag, void *ctx), void *ctx) +static int parse_dxbc(const struct vkd3d_shader_code *dxbc, struct vkd3d_shader_message_context *message_context, + const char *source_name, struct vkd3d_shader_dxbc_desc *desc) { const struct vkd3d_shader_location location = {.source_name = source_name}; + struct vkd3d_shader_dxbc_section_desc *sections, *section; uint32_t checksum[4], calculated_checksum[4]; + const char *data = dxbc->code; + size_t data_size = dxbc->size; const char *ptr = data; - int ret = VKD3D_OK; uint32_t chunk_count; uint32_t total_size; - unsigned int i; uint32_t version; + unsigned int i; uint32_t tag; if (data_size < VKD3D_DXBC_HEADER_SIZE) @@ -1804,6 +1813,12 @@ static int parse_dxbc(const char *data, size_t data_size, read_dword(&ptr, &chunk_count); TRACE("chunk count: %#x\n", chunk_count); + if (!(sections = vkd3d_calloc(chunk_count, sizeof(*sections)))) + { + vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXBC_OUT_OF_MEMORY, "Out of memory."); + return VKD3D_ERROR_OUT_OF_MEMORY; + } + for (i = 0; i < chunk_count; ++i) { uint32_t chunk_tag, chunk_size; @@ -1818,6 +1833,7 @@ static int parse_dxbc(const char *data, size_t data_size, WARN("Invalid chunk offset %#x (data size %zu).\n", chunk_offset, data_size); vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_OFFSET, "DXBC chunk %u has invalid offset %#x (data size %#zx).", i, chunk_offset, data_size); + vkd3d_free(sections); return VKD3D_ERROR_INVALID_ARGUMENT; } @@ -1833,39 +1849,120 @@ static int parse_dxbc(const char *data, size_t data_size, vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_SIZE, "DXBC chunk %u has invalid size %#x (data size %#zx, chunk offset %#x).", i, chunk_offset, data_size, chunk_offset); + vkd3d_free(sections); return VKD3D_ERROR_INVALID_ARGUMENT; } - if ((ret = chunk_handler(chunk_ptr, chunk_size, chunk_tag, ctx)) < 0) + section = §ions[i]; + section->tag = chunk_tag; + section->data.code = chunk_ptr; + section->data.size = chunk_size; + } + + desc->tag = tag; + memcpy(desc->checksum, checksum, sizeof(checksum)); + desc->version = version; + desc->size = total_size; + desc->section_count = chunk_count; + desc->sections = sections; + + return VKD3D_OK; +} + +void vkd3d_shader_free_dxbc(struct vkd3d_shader_dxbc_desc *dxbc) +{ + TRACE("dxbc %p.\n", dxbc); + + vkd3d_free(dxbc->sections); +} + +static int for_each_dxbc_section(const struct vkd3d_shader_code *dxbc, + struct vkd3d_shader_message_context *message_context, const char *source_name, + int (*section_handler)(const struct vkd3d_shader_dxbc_section_desc *section, + struct vkd3d_shader_message_context *message_context, void *ctx), void *ctx) +{ + struct vkd3d_shader_dxbc_desc desc; + unsigned int i; + int ret; + + if ((ret = parse_dxbc(dxbc, message_context, source_name, &desc)) < 0) + return ret; + + for (i = 0; i < desc.section_count; ++i) + { + if ((ret = section_handler(&desc.sections[i], message_context, ctx)) < 0) break; } + vkd3d_shader_free_dxbc(&desc); + + return ret; +} + +int vkd3d_shader_parse_dxbc(const struct vkd3d_shader_code *dxbc, + uint32_t flags, struct vkd3d_shader_dxbc_desc *desc, char **messages) +{ + struct vkd3d_shader_message_context message_context; + int ret; + + TRACE("dxbc {%p, %zu}, flags %#x, desc %p, messages %p.\n", dxbc->code, dxbc->size, flags, desc, messages); + + if (messages) + *messages = NULL; + vkd3d_shader_message_context_init(&message_context, VKD3D_SHADER_LOG_INFO); + + ret = parse_dxbc(dxbc, &message_context, NULL, desc); + + vkd3d_shader_message_context_trace_messages(&message_context); + if (!vkd3d_shader_message_context_copy_messages(&message_context, messages) && ret >= 0) + { + vkd3d_shader_free_dxbc(desc); + ret = VKD3D_ERROR_OUT_OF_MEMORY; + } + vkd3d_shader_message_context_cleanup(&message_context); + + if (ret < 0) + memset(desc, 0, sizeof(*desc)); + return ret; } -static int shader_parse_signature(DWORD tag, const char *data, DWORD data_size, - struct vkd3d_shader_signature *s) +static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *section, + struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_signature *s) { bool has_stream_index, has_min_precision; struct vkd3d_shader_signature_element *e; + const char *data = section->data.code; + uint32_t count, header_size; const char *ptr = data; unsigned int i; - uint32_t count; - if (!require_space(0, 2, sizeof(DWORD), data_size)) + if (!require_space(0, 2, sizeof(uint32_t), section->data.size)) { - WARN("Invalid data size %#x.\n", data_size); + WARN("Invalid data size %#zx.\n", section->data.size); + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_SIGNATURE, + "Section size %zu is smaller than the minimum signature header size.\n", section->data.size); return VKD3D_ERROR_INVALID_ARGUMENT; } read_dword(&ptr, &count); TRACE("%u elements.\n", count); - skip_dword_unknown(&ptr, 1); /* It seems to always be 0x00000008. */ + read_dword(&ptr, &header_size); + i = header_size / sizeof(uint32_t); + if (align(header_size, sizeof(uint32_t)) != header_size || i < 2 + || !require_space(2, i - 2, sizeof(uint32_t), section->data.size)) + { + WARN("Invalid header size %#x.\n", header_size); + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_SIGNATURE, + "Signature header size %#x is invalid.\n", header_size); + return VKD3D_ERROR_INVALID_ARGUMENT; + } + skip_dword_unknown(&ptr, i - 2); - if (!require_space(ptr - data, count, 6 * sizeof(DWORD), data_size)) + if (!require_space(ptr - data, count, 6 * sizeof(uint32_t), section->data.size)) { - WARN("Invalid count %#x (data size %#x).\n", count, data_size); + WARN("Invalid count %#x (data size %#zx).\n", count, section->data.size); return VKD3D_ERROR_INVALID_ARGUMENT; } @@ -1875,8 +1972,8 @@ static int shader_parse_signature(DWORD tag, const char *data, DWORD data_size, return VKD3D_ERROR_OUT_OF_MEMORY; } - has_min_precision = tag == TAG_OSG1 || tag == TAG_PSG1 || tag == TAG_ISG1; - has_stream_index = tag == TAG_OSG5 || has_min_precision; + has_min_precision = section->tag == TAG_OSG1 || section->tag == TAG_PSG1 || section->tag == TAG_ISG1; + has_stream_index = section->tag == TAG_OSG5 || has_min_precision; for (i = 0; i < count; ++i) { @@ -1888,9 +1985,9 @@ static int shader_parse_signature(DWORD tag, const char *data, DWORD data_size, e[i].stream_index = 0; read_dword(&ptr, &name_offset); - if (!(e[i].semantic_name = shader_get_string(data, data_size, name_offset))) + if (!(e[i].semantic_name = shader_get_string(data, section->data.size, name_offset))) { - WARN("Invalid name offset %#x (data size %#x).\n", name_offset, data_size); + WARN("Invalid name offset %#x (data size %#zx).\n", name_offset, section->data.size); vkd3d_free(e); return VKD3D_ERROR_INVALID_ARGUMENT; } @@ -1901,7 +1998,7 @@ static int shader_parse_signature(DWORD tag, const char *data, DWORD data_size, read_dword(&ptr, &mask); e[i].mask = mask & 0xff; e[i].used_mask = (mask >> 8) & 0xff; - switch (tag) + switch (section->tag) { case TAG_OSGN: case TAG_OSG1: @@ -1929,11 +2026,12 @@ static int shader_parse_signature(DWORD tag, const char *data, DWORD data_size, return VKD3D_OK; } -static int isgn_handler(const char *data, DWORD data_size, DWORD tag, void *ctx) +static int isgn_handler(const struct vkd3d_shader_dxbc_section_desc *section, + struct vkd3d_shader_message_context *message_context, void *ctx) { struct vkd3d_shader_signature *is = ctx; - if (tag != TAG_ISGN) + if (section->tag != TAG_ISGN) return VKD3D_OK; if (is->elements) @@ -1941,27 +2039,28 @@ static int isgn_handler(const char *data, DWORD data_size, DWORD tag, void *ctx) FIXME("Multiple input signatures.\n"); vkd3d_shader_free_shader_signature(is); } - return shader_parse_signature(tag, data, data_size, is); + return shader_parse_signature(section, message_context, is); } -int shader_parse_input_signature(const void *dxbc, size_t dxbc_length, +int shader_parse_input_signature(const struct vkd3d_shader_code *dxbc, struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_signature *signature) { int ret; memset(signature, 0, sizeof(*signature)); - if ((ret = parse_dxbc(dxbc, dxbc_length, message_context, NULL, isgn_handler, signature)) < 0) + if ((ret = for_each_dxbc_section(dxbc, message_context, NULL, isgn_handler, signature)) < 0) ERR("Failed to parse input signature.\n"); return ret; } -static int shdr_handler(const char *data, DWORD data_size, DWORD tag, void *context) +static int shdr_handler(const struct vkd3d_shader_dxbc_section_desc *section, + struct vkd3d_shader_message_context *message_context, void *context) { struct vkd3d_shader_desc *desc = context; int ret; - switch (tag) + switch (section->tag) { case TAG_ISGN: case TAG_ISG1: @@ -1970,7 +2069,7 @@ static int shdr_handler(const char *data, DWORD data_size, DWORD tag, void *cont FIXME("Multiple input signatures.\n"); break; } - if ((ret = shader_parse_signature(tag, data, data_size, &desc->input_signature)) < 0) + if ((ret = shader_parse_signature(section, message_context, &desc->input_signature)) < 0) return ret; break; @@ -1982,7 +2081,7 @@ static int shdr_handler(const char *data, DWORD data_size, DWORD tag, void *cont FIXME("Multiple output signatures.\n"); break; } - if ((ret = shader_parse_signature(tag, data, data_size, &desc->output_signature)) < 0) + if ((ret = shader_parse_signature(section, message_context, &desc->output_signature)) < 0) return ret; break; @@ -1993,7 +2092,7 @@ static int shdr_handler(const char *data, DWORD data_size, DWORD tag, void *cont FIXME("Multiple patch constant signatures.\n"); break; } - if ((ret = shader_parse_signature(tag, data, data_size, &desc->patch_constant_signature)) < 0) + if ((ret = shader_parse_signature(section, message_context, &desc->patch_constant_signature)) < 0) return ret; break; @@ -2001,8 +2100,8 @@ static int shdr_handler(const char *data, DWORD data_size, DWORD tag, void *cont case TAG_SHEX: if (desc->byte_code) FIXME("Multiple shader code chunks.\n"); - desc->byte_code = (const uint32_t *)data; - desc->byte_code_size = data_size; + desc->byte_code = section->data.code; + desc->byte_code_size = section->data.size; break; case TAG_AON9: @@ -2014,7 +2113,7 @@ static int shdr_handler(const char *data, DWORD data_size, DWORD tag, void *cont break; default: - TRACE("Skipping chunk %#x.\n", tag); + TRACE("Skipping chunk %#x.\n", section->tag); break; } @@ -2028,7 +2127,7 @@ void free_shader_desc(struct vkd3d_shader_desc *desc) vkd3d_shader_free_shader_signature(&desc->patch_constant_signature); } -static int shader_extract_from_dxbc(const void *dxbc, size_t dxbc_length, +static int shader_extract_from_dxbc(const struct vkd3d_shader_code *dxbc, struct vkd3d_shader_message_context *message_context, const char *source_name, struct vkd3d_shader_desc *desc) { int ret; @@ -2039,7 +2138,7 @@ static int shader_extract_from_dxbc(const void *dxbc, size_t dxbc_length, memset(&desc->output_signature, 0, sizeof(desc->output_signature)); memset(&desc->patch_constant_signature, 0, sizeof(desc->patch_constant_signature)); - ret = parse_dxbc(dxbc, dxbc_length, message_context, source_name, shdr_handler, desc); + ret = for_each_dxbc_section(dxbc, message_context, source_name, shdr_handler, desc); if (!desc->byte_code) ret = VKD3D_ERROR_INVALID_ARGUMENT; @@ -2055,7 +2154,9 @@ static int shader_extract_from_dxbc(const void *dxbc, size_t dxbc_length, int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser) { + struct vkd3d_shader_instruction_array *instructions; struct vkd3d_shader_desc *shader_desc; + struct vkd3d_shader_instruction *ins; struct vkd3d_shader_sm4_parser *sm4; int ret; @@ -2066,7 +2167,7 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi } shader_desc = &sm4->p.shader_desc; - if ((ret = shader_extract_from_dxbc(compile_info->source.code, compile_info->source.size, + if ((ret = shader_extract_from_dxbc(&compile_info->source, message_context, compile_info->source_name, shader_desc)) < 0) { WARN("Failed to extract shader, vkd3d result %d.\n", ret); @@ -2083,6 +2184,28 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi return VKD3D_ERROR_INVALID_ARGUMENT; } + instructions = &sm4->p.instructions; + while (!shader_sm4_is_end(&sm4->p)) + { + if (!shader_instruction_array_reserve(instructions, instructions->count + 1)) + { + ERR("Failed to allocate instructions.\n"); + vkd3d_shader_parser_error(&sm4->p, VKD3D_SHADER_ERROR_TPF_OUT_OF_MEMORY, "Out of memory."); + shader_sm4_destroy(&sm4->p); + return VKD3D_ERROR_OUT_OF_MEMORY; + } + ins = &instructions->elements[instructions->count]; + shader_sm4_read_instruction(&sm4->p, ins); + + if (ins->handler_idx == VKD3DSIH_INVALID) + { + WARN("Encountered unrecognized or invalid instruction.\n"); + shader_sm4_destroy(&sm4->p); + return VKD3D_ERROR_OUT_OF_MEMORY; + } + ++instructions->count; + } + *parser = &sm4->p; return VKD3D_OK; @@ -2438,21 +2561,21 @@ static int shader_parse_static_samplers(struct root_signature_parser_context *co return VKD3D_OK; } -static int shader_parse_root_signature(const char *data, unsigned int data_size, +static int shader_parse_root_signature(const struct vkd3d_shader_code *data, struct vkd3d_shader_versioned_root_signature_desc *desc) { struct vkd3d_shader_root_signature_desc *v_1_0 = &desc->u.v_1_0; struct root_signature_parser_context context; unsigned int count, offset, version; - const char *ptr = data; + const char *ptr = data->code; int ret; - context.data = data; - context.data_size = data_size; + context.data = data->code; + context.data_size = data->size; - if (!require_space(0, 6, sizeof(DWORD), data_size)) + if (!require_space(0, 6, sizeof(uint32_t), data->size)) { - WARN("Invalid data size %#x.\n", data_size); + WARN("Invalid data size %#zx.\n", data->size); return VKD3D_ERROR_INVALID_ARGUMENT; } @@ -2521,14 +2644,15 @@ static int shader_parse_root_signature(const char *data, unsigned int data_size, return VKD3D_OK; } -static int rts0_handler(const char *data, DWORD data_size, DWORD tag, void *context) +static int rts0_handler(const struct vkd3d_shader_dxbc_section_desc *section, + struct vkd3d_shader_message_context *message_context, void *context) { struct vkd3d_shader_versioned_root_signature_desc *desc = context; - if (tag != TAG_RTS0) + if (section->tag != TAG_RTS0) return VKD3D_OK; - return shader_parse_root_signature(data, data_size, desc); + return shader_parse_root_signature(§ion->data, desc); } int vkd3d_shader_parse_root_signature(const struct vkd3d_shader_code *dxbc, @@ -2544,7 +2668,7 @@ int vkd3d_shader_parse_root_signature(const struct vkd3d_shader_code *dxbc, *messages = NULL; vkd3d_shader_message_context_init(&message_context, VKD3D_SHADER_LOG_INFO); - ret = parse_dxbc(dxbc->code, dxbc->size, &message_context, NULL, rts0_handler, root_signature); + ret = for_each_dxbc_section(dxbc, &message_context, NULL, rts0_handler, root_signature); vkd3d_shader_message_context_trace_messages(&message_context); if (!vkd3d_shader_message_context_copy_messages(&message_context, messages)) ret = VKD3D_ERROR_OUT_OF_MEMORY; diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/glsl.c b/dll/directx/wine/vkd3d/libs/vkd3d-shader/glsl.c similarity index 84% rename from dll/directx/wine/d3d12/vkd3d/vkd3d-shader/glsl.c rename to dll/directx/wine/vkd3d/libs/vkd3d-shader/glsl.c index 56fa7043a3fc4..f8d68b5a79827 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/glsl.c +++ b/dll/directx/wine/vkd3d/libs/vkd3d-shader/glsl.c @@ -22,7 +22,7 @@ struct vkd3d_glsl_generator { struct vkd3d_shader_version version; struct vkd3d_string_buffer buffer; - const struct vkd3d_shader_location *location; + struct vkd3d_shader_location location; struct vkd3d_shader_message_context *message_context; bool failed; }; @@ -38,7 +38,7 @@ struct vkd3d_glsl_generator *vkd3d_glsl_generator_create(const struct vkd3d_shad memset(generator, 0, sizeof(*generator)); generator->version = *version; vkd3d_string_buffer_init(&generator->buffer); - generator->location = location; + generator->location = *location; generator->message_context = message_context; return generator; } @@ -50,7 +50,7 @@ static void VKD3D_PRINTF_FUNC(3, 4) vkd3d_glsl_compiler_error( va_list args; va_start(args, fmt); - vkd3d_shader_verror(generator->message_context, generator->location, error, fmt, args); + vkd3d_shader_verror(generator->message_context, &generator->location, error, fmt, args); va_end(args); generator->failed = true; } @@ -93,28 +93,20 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *generator int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *generator, struct vkd3d_shader_parser *parser, struct vkd3d_shader_code *out) { + unsigned int i; void *code; - struct vkd3d_shader_instruction ins; vkd3d_string_buffer_printf(&generator->buffer, "#version 440\n\n"); vkd3d_string_buffer_printf(&generator->buffer, "void main()\n{\n"); - while (!vkd3d_shader_parser_is_end(parser)) + generator->location.column = 0; + for (i = 0; i < parser->instructions.count; ++i) { - vkd3d_shader_parser_read_instruction(parser, &ins); - - if (ins.handler_idx == VKD3DSIH_INVALID) - { - vkd3d_glsl_compiler_error(generator, - VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Encountered unrecognized or invalid instruction."); - break; - } - - vkd3d_glsl_handle_instruction(generator, &ins); + generator->location.line = i + 1; + vkd3d_glsl_handle_instruction(generator, &parser->instructions.elements[i]); } - if (parser->failed || generator->failed) + if (generator->failed) return VKD3D_ERROR_INVALID_SHADER; vkd3d_string_buffer_printf(&generator->buffer, "}\n"); diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/hlsl.c b/dll/directx/wine/vkd3d/libs/vkd3d-shader/hlsl.c similarity index 55% rename from dll/directx/wine/d3d12/vkd3d/vkd3d-shader/hlsl.c rename to dll/directx/wine/vkd3d/libs/vkd3d-shader/hlsl.c index c5052693a4892..64d6e87065be6 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/hlsl.c +++ b/dll/directx/wine/vkd3d/libs/vkd3d-shader/hlsl.c @@ -113,17 +113,50 @@ struct hlsl_ir_var *hlsl_get_var(struct hlsl_scope *scope, const char *name) void hlsl_free_var(struct hlsl_ir_var *decl) { vkd3d_free((void *)decl->name); - vkd3d_free((void *)decl->semantic.name); + hlsl_cleanup_semantic(&decl->semantic); vkd3d_free(decl); } -static bool hlsl_type_is_row_major(const struct hlsl_type *type) +bool hlsl_type_is_row_major(const struct hlsl_type *type) { /* Default to column-major if the majority isn't explicitly set, which can * happen for anonymous nodes. */ return !!(type->modifiers & HLSL_MODIFIER_ROW_MAJOR); } +unsigned int hlsl_type_minor_size(const struct hlsl_type *type) +{ + if (type->type != HLSL_CLASS_MATRIX || hlsl_type_is_row_major(type)) + return type->dimx; + else + return type->dimy; +} + +unsigned int hlsl_type_major_size(const struct hlsl_type *type) +{ + if (type->type != HLSL_CLASS_MATRIX || hlsl_type_is_row_major(type)) + return type->dimy; + else + return type->dimx; +} + +unsigned int hlsl_type_element_count(const struct hlsl_type *type) +{ + switch (type->type) + { + case HLSL_CLASS_VECTOR: + return type->dimx; + case HLSL_CLASS_MATRIX: + return hlsl_type_major_size(type); + case HLSL_CLASS_ARRAY: + return type->e.array.elements_count; + case HLSL_CLASS_STRUCT: + return type->e.record.field_count; + default: + return 0; + } +} + static unsigned int get_array_size(const struct hlsl_type *type) { if (type->type == HLSL_CLASS_ARRAY) @@ -131,6 +164,51 @@ static unsigned int get_array_size(const struct hlsl_type *type) return 1; } +bool hlsl_type_is_resource(const struct hlsl_type *type) +{ + if (type->type == HLSL_CLASS_OBJECT) + { + switch (type->base_type) + { + case HLSL_TYPE_TEXTURE: + case HLSL_TYPE_SAMPLER: + case HLSL_TYPE_UAV: + return true; + default: + return false; + } + } + return false; +} + +enum hlsl_regset hlsl_type_get_regset(const struct hlsl_type *type) +{ + if (type->type <= HLSL_CLASS_LAST_NUMERIC) + return HLSL_REGSET_NUMERIC; + + if (type->type == HLSL_CLASS_OBJECT) + { + switch (type->base_type) + { + case HLSL_TYPE_TEXTURE: + return HLSL_REGSET_TEXTURES; + + case HLSL_TYPE_SAMPLER: + return HLSL_REGSET_SAMPLERS; + + case HLSL_TYPE_UAV: + return HLSL_REGSET_UAVS; + + default: + vkd3d_unreachable(); + } + } + else if (type->type == HLSL_CLASS_ARRAY) + return hlsl_type_get_regset(type->e.array.type); + + vkd3d_unreachable(); +} + unsigned int hlsl_type_get_sm4_offset(const struct hlsl_type *type, unsigned int offset) { /* Align to the next vec4 boundary if: @@ -138,7 +216,7 @@ unsigned int hlsl_type_get_sm4_offset(const struct hlsl_type *type, unsigned int * (b) the type would cross a vec4 boundary; i.e. a vec3 and a * vec1 can be packed together, but not a vec3 and a vec2. */ - if (type->type > HLSL_CLASS_LAST_NUMERIC || (offset & 3) + type->reg_size > 4) + if (type->type > HLSL_CLASS_LAST_NUMERIC || (offset & 3) + type->reg_size[HLSL_REGSET_NUMERIC] > 4) return align(offset, 4); return offset; } @@ -146,49 +224,59 @@ unsigned int hlsl_type_get_sm4_offset(const struct hlsl_type *type, unsigned int static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type *type) { bool is_sm4 = (ctx->profile->major_version >= 4); + unsigned int k; + + for (k = 0; k <= HLSL_REGSET_LAST; ++k) + type->reg_size[k] = 0; switch (type->type) { case HLSL_CLASS_SCALAR: case HLSL_CLASS_VECTOR: - type->reg_size = is_sm4 ? type->dimx : 4; + type->reg_size[HLSL_REGSET_NUMERIC] = is_sm4 ? type->dimx : 4; break; case HLSL_CLASS_MATRIX: if (hlsl_type_is_row_major(type)) - type->reg_size = is_sm4 ? (4 * (type->dimy - 1) + type->dimx) : (4 * type->dimy); + type->reg_size[HLSL_REGSET_NUMERIC] = is_sm4 ? (4 * (type->dimy - 1) + type->dimx) : (4 * type->dimy); else - type->reg_size = is_sm4 ? (4 * (type->dimx - 1) + type->dimy) : (4 * type->dimx); + type->reg_size[HLSL_REGSET_NUMERIC] = is_sm4 ? (4 * (type->dimx - 1) + type->dimy) : (4 * type->dimx); break; case HLSL_CLASS_ARRAY: { - unsigned int element_size = type->e.array.type->reg_size; + if (type->e.array.elements_count == HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT) + break; + + for (k = 0; k <= HLSL_REGSET_LAST; ++k) + { + unsigned int element_size = type->e.array.type->reg_size[k]; + + if (is_sm4 && k == HLSL_REGSET_NUMERIC) + type->reg_size[k] = (type->e.array.elements_count - 1) * align(element_size, 4) + element_size; + else + type->reg_size[k] = type->e.array.elements_count * element_size; + } - assert(element_size); - if (is_sm4) - type->reg_size = (type->e.array.elements_count - 1) * align(element_size, 4) + element_size; - else - type->reg_size = type->e.array.elements_count * element_size; break; } case HLSL_CLASS_STRUCT: { - struct hlsl_struct_field *field; + unsigned int i; type->dimx = 0; - type->reg_size = 0; - - LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry) + for (i = 0; i < type->e.record.field_count; ++i) { - unsigned int field_size = field->type->reg_size; - - assert(field_size); + struct hlsl_struct_field *field = &type->e.record.fields[i]; - type->reg_size = hlsl_type_get_sm4_offset(field->type, type->reg_size); - field->reg_offset = type->reg_size; - type->reg_size += field_size; + for (k = 0; k <= HLSL_REGSET_LAST; ++k) + { + if (k == HLSL_REGSET_NUMERIC) + type->reg_size[k] = hlsl_type_get_sm4_offset(field->type, type->reg_size[k]); + field->reg_offset[k] = type->reg_size[k]; + type->reg_size[k] += field->type->reg_size[k]; + } type->dimx += field->type->dimx * field->type->dimy * get_array_size(field->type); } @@ -196,12 +284,27 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type } case HLSL_CLASS_OBJECT: - /* For convenience when performing copy propagation. */ - type->reg_size = 1; + { + if (hlsl_type_is_resource(type)) + { + enum hlsl_regset regset = hlsl_type_get_regset(type); + + type->reg_size[regset] = 1; + } break; + } } } +/* Returns the size of a type, considered as part of an array of that type, within a specific + * register set. As such it includes padding after the type, when applicable. */ +unsigned int hlsl_type_get_array_element_reg_size(const struct hlsl_type *type, enum hlsl_regset regset) +{ + if (regset == HLSL_REGSET_NUMERIC) + return align(type->reg_size[regset], 4); + return type->reg_size[regset]; +} + static struct hlsl_type *hlsl_new_type(struct hlsl_ctx *ctx, const char *name, enum hlsl_type_class type_class, enum hlsl_base_type base_type, unsigned dimx, unsigned dimy) { @@ -225,6 +328,210 @@ static struct hlsl_type *hlsl_new_type(struct hlsl_ctx *ctx, const char *name, e return type; } +static bool type_is_single_component(const struct hlsl_type *type) +{ + return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_OBJECT; +} + +/* Given a type and a component index, this function moves one step through the path required to + * reach that component within the type. + * It returns the first index of this path. + * It sets *type_ptr to the (outermost) type within the original type that contains the component. + * It sets *index_ptr to the index of the component within *type_ptr. + * So, this function can be called several times in sequence to obtain all the path's indexes until + * the component is finally reached. */ +static unsigned int traverse_path_from_component_index(struct hlsl_ctx *ctx, + struct hlsl_type **type_ptr, unsigned int *index_ptr) +{ + struct hlsl_type *type = *type_ptr; + unsigned int index = *index_ptr; + + assert(!type_is_single_component(type)); + assert(index < hlsl_type_component_count(type)); + + switch (type->type) + { + case HLSL_CLASS_VECTOR: + assert(index < type->dimx); + *type_ptr = hlsl_get_scalar_type(ctx, type->base_type); + *index_ptr = 0; + return index; + + case HLSL_CLASS_MATRIX: + { + 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); + *type_ptr = hlsl_get_vector_type(ctx, type->base_type, row_major ? type->dimx : type->dimy); + *index_ptr = row_major ? x : y; + return row_major ? y : x; + } + + case HLSL_CLASS_ARRAY: + { + unsigned int elem_comp_count = hlsl_type_component_count(type->e.array.type); + unsigned int array_index; + + *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); + return array_index; + } + + case HLSL_CLASS_STRUCT: + { + struct hlsl_struct_field *field; + unsigned int field_comp_count, i; + + for (i = 0; i < type->e.record.field_count; ++i) + { + field = &type->e.record.fields[i]; + field_comp_count = hlsl_type_component_count(field->type); + if (index < field_comp_count) + { + *type_ptr = field->type; + *index_ptr = index; + return i; + } + index -= field_comp_count; + } + vkd3d_unreachable(); + } + + default: + vkd3d_unreachable(); + } +} + +struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl_type *type, + unsigned int index) +{ + while (!type_is_single_component(type)) + traverse_path_from_component_index(ctx, &type, &index); + + return type; +} + +static bool init_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_var *var, + unsigned int path_len) +{ + deref->var = var; + deref->path_len = path_len; + deref->offset.node = NULL; + + if (path_len == 0) + { + deref->path = NULL; + return true; + } + + if (!(deref->path = hlsl_alloc(ctx, sizeof(*deref->path) * deref->path_len))) + { + deref->var = NULL; + deref->path_len = 0; + return false; + } + + return true; +} + +struct hlsl_type *hlsl_deref_get_type(struct hlsl_ctx *ctx, const struct hlsl_deref *deref) +{ + struct hlsl_type *type; + unsigned int i; + + assert(deref); + assert(!deref->offset.node); + + type = deref->var->data_type; + for (i = 0; i < deref->path_len; ++i) + type = hlsl_get_element_type_from_path_index(ctx, type, deref->path[i].node); + return type; +} + +/* Initializes a deref from another deref (prefix) and a component index. + * *block is initialized to contain the new constant node instructions used by the deref's path. */ +static bool init_deref_from_component_index(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_deref *deref, const struct hlsl_deref *prefix, unsigned int index, + const struct vkd3d_shader_location *loc) +{ + unsigned int path_len, path_index, deref_path_len, i; + struct hlsl_type *path_type; + struct hlsl_ir_constant *c; + + list_init(&block->instrs); + + path_len = 0; + path_type = hlsl_deref_get_type(ctx, prefix); + path_index = index; + while (!type_is_single_component(path_type)) + { + traverse_path_from_component_index(ctx, &path_type, &path_index); + ++path_len; + } + + if (!init_deref(ctx, deref, prefix->var, prefix->path_len + path_len)) + return false; + + deref_path_len = 0; + for (i = 0; i < prefix->path_len; ++i) + hlsl_src_from_node(&deref->path[deref_path_len++], prefix->path[i].node); + + path_type = hlsl_deref_get_type(ctx, prefix); + path_index = index; + while (!type_is_single_component(path_type)) + { + unsigned int next_index = traverse_path_from_component_index(ctx, &path_type, &path_index); + + if (!(c = hlsl_new_uint_constant(ctx, next_index, loc))) + { + hlsl_free_instr_list(&block->instrs); + return false; + } + list_add_tail(&block->instrs, &c->node.entry); + + hlsl_src_from_node(&deref->path[deref_path_len++], &c->node); + } + + assert(deref_path_len == deref->path_len); + + return true; +} + +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); + + switch (type->type) + { + case HLSL_CLASS_VECTOR: + return hlsl_get_scalar_type(ctx, type->base_type); + + case HLSL_CLASS_MATRIX: + if (hlsl_type_is_row_major(type)) + return hlsl_get_vector_type(ctx, type->base_type, type->dimx); + else + return hlsl_get_vector_type(ctx, type->base_type, type->dimy); + + case HLSL_CLASS_ARRAY: + return type->e.array.type; + + case HLSL_CLASS_STRUCT: + { + struct hlsl_ir_constant *c = hlsl_ir_constant(idx); + + assert(c->value[0].u < type->e.record.field_count); + return type->e.record.fields[c->value[0].u].type; + } + + default: + vkd3d_unreachable(); + } +} + struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *basic_type, unsigned int array_size) { struct hlsl_type *type; @@ -245,7 +552,8 @@ struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *ba return type; } -struct hlsl_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const char *name, struct list *fields) +struct hlsl_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const char *name, + struct hlsl_struct_field *fields, size_t field_count) { struct hlsl_type *type; @@ -255,7 +563,8 @@ struct hlsl_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const char *name, s type->base_type = HLSL_TYPE_VOID; type->name = name; type->dimy = 1; - type->e.elements = fields; + type->e.record.fields = fields; + type->e.record.field_count = field_count; hlsl_type_calculate_reg_size(ctx, type); list_add_tail(&ctx->types, &type->entry); @@ -263,7 +572,8 @@ struct hlsl_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const char *name, s return type; } -struct hlsl_type *hlsl_new_texture_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, struct hlsl_type *format) +struct hlsl_type *hlsl_new_texture_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, + struct hlsl_type *format, unsigned int sample_count) { struct hlsl_type *type; @@ -275,35 +585,87 @@ struct hlsl_type *hlsl_new_texture_type(struct hlsl_ctx *ctx, enum hlsl_sampler_ type->dimy = 1; type->sampler_dim = dim; type->e.resource_format = format; + type->sample_count = sample_count; + hlsl_type_calculate_reg_size(ctx, type); + list_add_tail(&ctx->types, &type->entry); + return type; +} + +struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, struct hlsl_type *format) +{ + struct hlsl_type *type; + + if (!(type = vkd3d_calloc(1, sizeof(*type)))) + return NULL; + type->type = HLSL_CLASS_OBJECT; + type->base_type = HLSL_TYPE_UAV; + type->dimx = format->dimx; + type->dimy = 1; + type->sampler_dim = dim; + type->e.resource_format = format; hlsl_type_calculate_reg_size(ctx, type); list_add_tail(&ctx->types, &type->entry); return type; } -struct hlsl_type *hlsl_get_type(struct hlsl_scope *scope, const char *name, bool recursive) +static const char * get_case_insensitive_typename(const char *name) +{ + static const char *const names[] = + { + "dword", + "float", + }; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(names); ++i) + { + if (!ascii_strcasecmp(names[i], name)) + return names[i]; + } + + return NULL; +} + +struct hlsl_type *hlsl_get_type(struct hlsl_scope *scope, const char *name, bool recursive, bool case_insensitive) { - struct wine_rb_entry *entry = wine_rb_get(&scope->types, name); + struct rb_entry *entry = rb_get(&scope->types, name); if (entry) return RB_ENTRY_VALUE(entry, struct hlsl_type, scope_entry); - if (recursive && scope->upper) - return hlsl_get_type(scope->upper, name, recursive); + if (scope->upper) + { + if (recursive) + return hlsl_get_type(scope->upper, name, recursive, case_insensitive); + } + else + { + if (case_insensitive && (name = get_case_insensitive_typename(name))) + { + if ((entry = rb_get(&scope->types, name))) + return RB_ENTRY_VALUE(entry, struct hlsl_type, scope_entry); + } + } + return NULL; } -bool hlsl_get_function(struct hlsl_ctx *ctx, const char *name) +struct hlsl_ir_function *hlsl_get_function(struct hlsl_ctx *ctx, const char *name) { - return wine_rb_get(&ctx->functions, name) != NULL; + struct rb_entry *entry; + + if ((entry = rb_get(&ctx->functions, name))) + return RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry); + return NULL; } struct hlsl_ir_function_decl *hlsl_get_func_decl(struct hlsl_ctx *ctx, const char *name) { struct hlsl_ir_function_decl *decl; struct hlsl_ir_function *func; - struct wine_rb_entry *entry; + struct rb_entry *entry; - if ((entry = wine_rb_get(&ctx->functions, name))) + if ((entry = rb_get(&ctx->functions, name))) { func = RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry); RB_FOR_EACH_ENTRY(decl, &func->overloads, struct hlsl_ir_function_decl, entry) @@ -313,30 +675,33 @@ struct hlsl_ir_function_decl *hlsl_get_func_decl(struct hlsl_ctx *ctx, const cha return NULL; } -unsigned int hlsl_type_component_count(struct hlsl_type *type) +unsigned int hlsl_type_component_count(const struct hlsl_type *type) { - struct hlsl_struct_field *field; - unsigned int count = 0; - - if (type->type <= HLSL_CLASS_LAST_NUMERIC) - { - return type->dimx * type->dimy; - } - if (type->type == HLSL_CLASS_ARRAY) - { - return hlsl_type_component_count(type->e.array.type) * type->e.array.elements_count; - } - if (type->type != HLSL_CLASS_STRUCT) + switch (type->type) { - ERR("Unexpected data type %#x.\n", type->type); - return 0; - } + case HLSL_CLASS_SCALAR: + case HLSL_CLASS_VECTOR: + case HLSL_CLASS_MATRIX: + return type->dimx * type->dimy; - LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry) - { - count += hlsl_type_component_count(field->type); + case HLSL_CLASS_STRUCT: + { + unsigned int count = 0, i; + + for (i = 0; i < type->e.record.field_count; ++i) + count += hlsl_type_component_count(type->e.record.fields[i].type); + return count; + } + + case HLSL_CLASS_ARRAY: + return hlsl_type_component_count(type->e.array.type) * type->e.array.elements_count; + + case HLSL_CLASS_OBJECT: + return 1; + + default: + vkd3d_unreachable(); } - return count; } bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2) @@ -348,7 +713,8 @@ bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2 return false; if (t1->base_type != t2->base_type) return false; - if (t1->base_type == HLSL_TYPE_SAMPLER || t1->base_type == HLSL_TYPE_TEXTURE) + if (t1->base_type == HLSL_TYPE_SAMPLER || t1->base_type == HLSL_TYPE_TEXTURE + || t1->base_type == HLSL_TYPE_UAV) { if (t1->sampler_dim != t2->sampler_dim) return false; @@ -365,24 +731,22 @@ bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2 return false; if (t1->type == HLSL_CLASS_STRUCT) { - struct list *t1cur, *t2cur; - struct hlsl_struct_field *t1field, *t2field; + size_t i; - t1cur = list_head(t1->e.elements); - t2cur = list_head(t2->e.elements); - while (t1cur && t2cur) + if (t1->e.record.field_count != t2->e.record.field_count) + return false; + + for (i = 0; i < t1->e.record.field_count; ++i) { - t1field = LIST_ENTRY(t1cur, struct hlsl_struct_field, entry); - t2field = LIST_ENTRY(t2cur, struct hlsl_struct_field, entry); - if (!hlsl_types_are_equal(t1field->type, t2field->type)) + const struct hlsl_struct_field *field1 = &t1->e.record.fields[i]; + const struct hlsl_struct_field *field2 = &t2->e.record.fields[i]; + + if (!hlsl_types_are_equal(field1->type, field2->type)) return false; - if (strcmp(t1field->name, t2field->name)) + + if (strcmp(field1->name, field2->name)) return false; - t1cur = list_next(t1->e.elements, t1cur); - t2cur = list_next(t2->e.elements, t2cur); } - if (t1cur != t2cur) - return false; } if (t1->type == HLSL_CLASS_ARRAY) return t1->e.array.elements_count == t2->e.array.elements_count @@ -394,7 +758,6 @@ bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2 struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, unsigned int default_majority, unsigned int modifiers) { - struct hlsl_struct_field *old_field, *field; struct hlsl_type *type; if (!(type = hlsl_alloc(ctx, sizeof(*type)))) @@ -417,46 +780,51 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, if (!(type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK)) type->modifiers |= default_majority; type->sampler_dim = old->sampler_dim; + type->is_minimum_precision = old->is_minimum_precision; switch (old->type) { case HLSL_CLASS_ARRAY: - type->e.array.type = hlsl_type_clone(ctx, old->e.array.type, default_majority, modifiers); + if (!(type->e.array.type = hlsl_type_clone(ctx, old->e.array.type, default_majority, modifiers))) + { + vkd3d_free((void *)type->name); + vkd3d_free(type); + return NULL; + } type->e.array.elements_count = old->e.array.elements_count; break; case HLSL_CLASS_STRUCT: { - if (!(type->e.elements = hlsl_alloc(ctx, sizeof(*type->e.elements)))) + size_t field_count = old->e.record.field_count, i; + + type->e.record.field_count = field_count; + + if (!(type->e.record.fields = hlsl_alloc(ctx, field_count * sizeof(*type->e.record.fields)))) { vkd3d_free((void *)type->name); vkd3d_free(type); return NULL; } - list_init(type->e.elements); - LIST_FOR_EACH_ENTRY(old_field, old->e.elements, struct hlsl_struct_field, entry) + + for (i = 0; i < field_count; ++i) { - if (!(field = hlsl_alloc(ctx, sizeof(*field)))) + const struct hlsl_struct_field *src_field = &old->e.record.fields[i]; + struct hlsl_struct_field *dst_field = &type->e.record.fields[i]; + + dst_field->loc = src_field->loc; + if (!(dst_field->type = hlsl_type_clone(ctx, src_field->type, default_majority, modifiers))) { - LIST_FOR_EACH_ENTRY_SAFE(field, old_field, type->e.elements, struct hlsl_struct_field, entry) - { - vkd3d_free((void *)field->semantic.name); - vkd3d_free((void *)field->name); - vkd3d_free(field); - } - vkd3d_free(type->e.elements); + vkd3d_free(type->e.record.fields); vkd3d_free((void *)type->name); vkd3d_free(type); return NULL; } - field->loc = old_field->loc; - field->type = hlsl_type_clone(ctx, old_field->type, default_majority, modifiers); - field->name = hlsl_strdup(ctx, old_field->name); - if (old_field->semantic.name) + dst_field->name = hlsl_strdup(ctx, src_field->name); + if (src_field->semantic.name) { - field->semantic.name = hlsl_strdup(ctx, old_field->semantic.name); - field->semantic.index = old_field->semantic.index; + dst_field->semantic.name = hlsl_strdup(ctx, src_field->semantic.name); + dst_field->semantic.index = src_field->semantic.index; } - list_add_tail(type->e.elements, &field->entry); } break; } @@ -473,10 +841,10 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, bool hlsl_scope_add_type(struct hlsl_scope *scope, struct hlsl_type *type) { - if (hlsl_get_type(scope, type->name, false)) + if (hlsl_get_type(scope, type->name, false, false)) return false; - wine_rb_put(&scope->types, type->name, &type->scope_entry); + rb_put(&scope->types, type->name, &type->scope_entry); return true; } @@ -511,19 +879,32 @@ struct hlsl_ir_var *hlsl_new_var(struct hlsl_ctx *ctx, const char *name, struct var->loc = loc; if (semantic) var->semantic = *semantic; - var->modifiers = modifiers; + var->storage_modifiers = modifiers; if (reg_reservation) var->reg_reservation = *reg_reservation; return var; } -struct hlsl_ir_var *hlsl_new_synthetic_var(struct hlsl_ctx *ctx, const char *name, struct hlsl_type *type, - 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 *var = hlsl_new_var(ctx, hlsl_strdup(ctx, name), type, loc, NULL, 0, NULL); + struct vkd3d_string_buffer *string; + struct hlsl_ir_var *var; + static LONG counter; + const char *name; + if (!(string = hlsl_get_string_buffer(ctx))) + return NULL; + vkd3d_string_buffer_printf(string, "<%s-%u>", template, InterlockedIncrement(&counter)); + if (!(name = hlsl_strdup(ctx, string->buffer))) + { + hlsl_release_string_buffer(ctx, string); + return NULL; + } + var = hlsl_new_var(ctx, name, type, *loc, NULL, 0, NULL); + hlsl_release_string_buffer(ctx, string); if (var) - list_add_tail(&ctx->globals->vars, &var->scope_entry); + list_add_tail(&ctx->dummy_scope->vars, &var->scope_entry); return var; } @@ -532,198 +913,719 @@ static bool type_is_single_reg(const struct hlsl_type *type) return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_VECTOR; } -struct hlsl_ir_store *hlsl_new_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, struct hlsl_ir_node *offset, - struct hlsl_ir_node *rhs, unsigned int writemask, struct vkd3d_shader_location loc) +bool hlsl_copy_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, const struct hlsl_deref *other) { - struct hlsl_ir_store *store; + unsigned int i; - if (!writemask && type_is_single_reg(rhs->data_type)) - writemask = (1 << rhs->data_type->dimx) - 1; + memset(deref, 0, sizeof(*deref)); + + if (!other) + return true; + + assert(!other->offset.node); + + if (!init_deref(ctx, deref, other->var, other->path_len)) + return false; + + for (i = 0; i < deref->path_len; ++i) + hlsl_src_from_node(&deref->path[i], other->path[i].node); + + return true; +} + +void hlsl_cleanup_deref(struct hlsl_deref *deref) +{ + unsigned int i; + + for (i = 0; i < deref->path_len; ++i) + hlsl_src_remove(&deref->path[i]); + vkd3d_free(deref->path); + + deref->path = NULL; + deref->path_len = 0; + + hlsl_src_remove(&deref->offset); +} + +/* Initializes a simple variable dereference, so that it can be passed to load/store functions. */ +void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_var *var) +{ + memset(deref, 0, sizeof(*deref)); + deref->var = var; +} + +static void init_node(struct hlsl_ir_node *node, enum hlsl_ir_node_type type, + struct hlsl_type *data_type, const struct vkd3d_shader_location *loc) +{ + memset(node, 0, sizeof(*node)); + node->type = type; + node->data_type = data_type; + node->loc = *loc; + list_init(&node->uses); +} + +struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs) +{ + struct hlsl_deref lhs_deref; + + hlsl_init_simple_deref_from_var(&lhs_deref, lhs); + return hlsl_new_store_index(ctx, &lhs_deref, NULL, rhs, 0, &rhs->loc); +} + +struct hlsl_ir_store *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hlsl_deref *lhs, + struct hlsl_ir_node *idx, struct hlsl_ir_node *rhs, unsigned int writemask, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_store *store; + unsigned int i; + + assert(lhs); + assert(!lhs->offset.node); if (!(store = hlsl_alloc(ctx, sizeof(*store)))) return NULL; - init_node(&store->node, HLSL_IR_STORE, NULL, loc); - store->lhs.var = var; - hlsl_src_from_node(&store->lhs.offset, offset); + + if (!init_deref(ctx, &store->lhs, lhs->var, lhs->path_len + !!idx)) + { + vkd3d_free(store); + return NULL; + } + for (i = 0; i < lhs->path_len; ++i) + hlsl_src_from_node(&store->lhs.path[i], lhs->path[i].node); + if (idx) + hlsl_src_from_node(&store->lhs.path[lhs->path_len], idx); + hlsl_src_from_node(&store->rhs, rhs); + + if (!writemask && type_is_single_reg(rhs->data_type)) + writemask = (1 << rhs->data_type->dimx) - 1; store->writemask = writemask; + + return store; +} + +struct hlsl_ir_store *hlsl_new_store_component(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_deref *lhs, unsigned int comp, struct hlsl_ir_node *rhs) +{ + struct hlsl_block comp_path_block; + struct hlsl_ir_store *store; + + list_init(&block->instrs); + + if (!(store = hlsl_alloc(ctx, sizeof(*store)))) + return NULL; + init_node(&store->node, HLSL_IR_STORE, NULL, &rhs->loc); + + if (!init_deref_from_component_index(ctx, &comp_path_block, &store->lhs, lhs, comp, &rhs->loc)) + { + vkd3d_free(store); + return NULL; + } + list_move_tail(&block->instrs, &comp_path_block.instrs); + hlsl_src_from_node(&store->rhs, rhs); + + if (type_is_single_reg(rhs->data_type)) + store->writemask = (1 << rhs->data_type->dimx) - 1; + + list_add_tail(&block->instrs, &store->node.entry); + return store; } -struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs) +struct hlsl_ir_node *hlsl_new_call(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *decl, + const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_call *call; + + if (!(call = hlsl_alloc(ctx, sizeof(*call)))) + return NULL; + + init_node(&call->node, HLSL_IR_CALL, NULL, loc); + call->decl = decl; + return &call->node; +} + +struct hlsl_ir_constant *hlsl_new_constant(struct hlsl_ctx *ctx, struct hlsl_type *type, + const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_constant *c; + + assert(type->type <= HLSL_CLASS_VECTOR); + + if (!(c = hlsl_alloc(ctx, sizeof(*c)))) + return NULL; + + init_node(&c->node, HLSL_IR_CONSTANT, type, loc); + + return c; +} + +struct hlsl_ir_constant *hlsl_new_bool_constant(struct hlsl_ctx *ctx, bool b, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_constant *c; + + if ((c = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL), loc))) + c->value[0].u = b ? ~0u : 0; + + return c; +} + +struct hlsl_ir_constant *hlsl_new_float_constant(struct hlsl_ctx *ctx, float f, + const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_constant *c; + + if ((c = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc))) + c->value[0].f = f; + + return c; +} + +struct hlsl_ir_constant *hlsl_new_int_constant(struct hlsl_ctx *ctx, int n, + const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_constant *c; + + c = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), loc); + + if (c) + c->value[0].i = n; + + return c; +} + +struct hlsl_ir_constant *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned int n, + const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_constant *c; + + c = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc); + + if (c) + c->value[0].u = n; + + return c; +} + +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) +{ + struct hlsl_ir_expr *expr; + unsigned int i; + + if (!(expr = hlsl_alloc(ctx, sizeof(*expr)))) + return NULL; + init_node(&expr->node, HLSL_IR_EXPR, data_type, loc); + expr->op = op; + for (i = 0; i < HLSL_MAX_OPERANDS; ++i) + hlsl_src_from_node(&expr->operands[i], operands[i]); + return &expr->node; +} + +struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, + struct hlsl_ir_node *arg, struct vkd3d_shader_location loc) +{ + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {arg}; + + return hlsl_new_expr(ctx, op, operands, arg->data_type, &loc); +} + +struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, + struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2) +{ + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {arg1, arg2}; + + assert(hlsl_types_are_equal(arg1->data_type, arg2->data_type)); + return hlsl_new_expr(ctx, op, operands, arg1->data_type, &arg1->loc); +} + +struct hlsl_ir_if *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *condition, struct vkd3d_shader_location loc) +{ + struct hlsl_ir_if *iff; + + if (!(iff = hlsl_alloc(ctx, sizeof(*iff)))) + return NULL; + init_node(&iff->node, HLSL_IR_IF, NULL, &loc); + hlsl_src_from_node(&iff->condition, condition); + list_init(&iff->then_instrs.instrs); + list_init(&iff->else_instrs.instrs); + return iff; +} + +struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, + struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_load *load; + struct hlsl_type *type; + unsigned int i; + + assert(!deref->offset.node); + + type = hlsl_deref_get_type(ctx, deref); + if (idx) + type = hlsl_get_element_type_from_path_index(ctx, type, idx); + + if (!(load = hlsl_alloc(ctx, sizeof(*load)))) + return NULL; + init_node(&load->node, HLSL_IR_LOAD, type, loc); + + if (!init_deref(ctx, &load->src, deref->var, deref->path_len + !!idx)) + { + vkd3d_free(load); + return NULL; + } + for (i = 0; i < deref->path_len; ++i) + hlsl_src_from_node(&load->src.path[i], deref->path[i].node); + if (idx) + hlsl_src_from_node(&load->src.path[deref->path_len], idx); + + return load; +} + +struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, + struct vkd3d_shader_location loc) +{ + struct hlsl_deref var_deref; + + hlsl_init_simple_deref_from_var(&var_deref, var); + return hlsl_new_load_index(ctx, &var_deref, NULL, &loc); +} + +struct hlsl_ir_load *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_deref *deref, unsigned int comp, const struct vkd3d_shader_location *loc) +{ + struct hlsl_type *type, *comp_type; + struct hlsl_block comp_path_block; + struct hlsl_ir_load *load; + + list_init(&block->instrs); + + if (!(load = hlsl_alloc(ctx, sizeof(*load)))) + return NULL; + + type = hlsl_deref_get_type(ctx, deref); + comp_type = hlsl_type_get_component_type(ctx, type, comp); + init_node(&load->node, HLSL_IR_LOAD, comp_type, loc); + + if (!init_deref_from_component_index(ctx, &comp_path_block, &load->src, deref, comp, loc)) + { + vkd3d_free(load); + return NULL; + } + list_move_tail(&block->instrs, &comp_path_block.instrs); + + list_add_tail(&block->instrs, &load->node.entry); + + return load; +} + +struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, + const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_resource_load *load; + + if (!(load = hlsl_alloc(ctx, sizeof(*load)))) + return NULL; + init_node(&load->node, HLSL_IR_RESOURCE_LOAD, params->format, loc); + load->load_type = params->type; + if (!hlsl_copy_deref(ctx, &load->resource, ¶ms->resource)) + { + vkd3d_free(load); + return NULL; + } + if (!hlsl_copy_deref(ctx, &load->sampler, ¶ms->sampler)) + { + hlsl_cleanup_deref(&load->resource); + vkd3d_free(load); + return NULL; + } + hlsl_src_from_node(&load->coords, params->coords); + hlsl_src_from_node(&load->texel_offset, params->texel_offset); + hlsl_src_from_node(&load->lod, params->lod); + return load; +} + +struct hlsl_ir_resource_store *hlsl_new_resource_store(struct hlsl_ctx *ctx, const struct hlsl_deref *resource, + struct hlsl_ir_node *coords, struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_resource_store *store; + + if (!(store = hlsl_alloc(ctx, sizeof(*store)))) + return NULL; + init_node(&store->node, HLSL_IR_RESOURCE_STORE, NULL, loc); + hlsl_copy_deref(ctx, &store->resource, resource); + hlsl_src_from_node(&store->coords, coords); + hlsl_src_from_node(&store->value, value); + return store; +} + +struct hlsl_ir_swizzle *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned int components, + struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_swizzle *swizzle; + struct hlsl_type *type; + + if (!(swizzle = hlsl_alloc(ctx, sizeof(*swizzle)))) + return NULL; + if (components == 1) + type = hlsl_get_scalar_type(ctx, val->data_type->base_type); + else + type = hlsl_get_vector_type(ctx, val->data_type->base_type, components); + init_node(&swizzle->node, HLSL_IR_SWIZZLE, type, loc); + hlsl_src_from_node(&swizzle->val, val); + swizzle->swizzle = s; + return swizzle; +} + +struct hlsl_ir_jump *hlsl_new_jump(struct hlsl_ctx *ctx, enum hlsl_ir_jump_type type, struct vkd3d_shader_location loc) +{ + struct hlsl_ir_jump *jump; + + if (!(jump = hlsl_alloc(ctx, sizeof(*jump)))) + return NULL; + init_node(&jump->node, HLSL_IR_JUMP, NULL, &loc); + jump->type = type; + return jump; +} + +struct hlsl_ir_loop *hlsl_new_loop(struct hlsl_ctx *ctx, struct vkd3d_shader_location loc) +{ + struct hlsl_ir_loop *loop; + + if (!(loop = hlsl_alloc(ctx, sizeof(*loop)))) + return NULL; + init_node(&loop->node, HLSL_IR_LOOP, NULL, &loc); + list_init(&loop->body.instrs); + return loop; +} + +struct clone_instr_map +{ + struct + { + const struct hlsl_ir_node *src; + struct hlsl_ir_node *dst; + } *instrs; + size_t count, capacity; +}; + +static struct hlsl_ir_node *clone_instr(struct hlsl_ctx *ctx, + struct clone_instr_map *map, const struct hlsl_ir_node *instr); + +static bool clone_block(struct hlsl_ctx *ctx, struct hlsl_block *dst_block, + const struct hlsl_block *src_block, struct clone_instr_map *map) +{ + const struct hlsl_ir_node *src; + struct hlsl_ir_node *dst; + + LIST_FOR_EACH_ENTRY(src, &src_block->instrs, struct hlsl_ir_node, entry) + { + if (!(dst = clone_instr(ctx, map, src))) + { + hlsl_free_instr_list(&dst_block->instrs); + return false; + } + list_add_tail(&dst_block->instrs, &dst->entry); + + if (!list_empty(&src->uses)) + { + if (!vkd3d_array_reserve((void **)&map->instrs, &map->capacity, map->count + 1, sizeof(*map->instrs))) + { + hlsl_free_instr_list(&dst_block->instrs); + return false; + } + + map->instrs[map->count].dst = dst; + map->instrs[map->count].src = src; + ++map->count; + } + } + return true; +} + +static struct hlsl_ir_node *map_instr(const struct clone_instr_map *map, struct hlsl_ir_node *src) +{ + size_t i; + + if (!src) + return NULL; + + for (i = 0; i < map->count; ++i) + { + if (map->instrs[i].src == src) + return map->instrs[i].dst; + } + + /* The block passed to hlsl_clone_block() should have been free of external + * references. */ + vkd3d_unreachable(); +} + +static bool clone_deref(struct hlsl_ctx *ctx, struct clone_instr_map *map, + struct hlsl_deref *dst, const struct hlsl_deref *src) +{ + unsigned int i; + + assert(!src->offset.node); + + if (!init_deref(ctx, dst, src->var, src->path_len)) + return false; + + for (i = 0; i < src->path_len; ++i) + hlsl_src_from_node(&dst->path[i], map_instr(map, src->path[i].node)); + + return true; +} + +static void clone_src(struct clone_instr_map *map, struct hlsl_src *dst, const struct hlsl_src *src) +{ + hlsl_src_from_node(dst, map_instr(map, src->node)); +} + +static struct hlsl_ir_node *clone_call(struct hlsl_ctx *ctx, struct hlsl_ir_call *src) { - return hlsl_new_store(ctx, lhs, NULL, rhs, 0, rhs->loc); + return hlsl_new_call(ctx, src->decl, &src->node.loc); } -struct hlsl_ir_constant *hlsl_new_int_constant(struct hlsl_ctx *ctx, int n, - const struct vkd3d_shader_location loc) +static struct hlsl_ir_node *clone_constant(struct hlsl_ctx *ctx, struct hlsl_ir_constant *src) { - struct hlsl_ir_constant *c; + struct hlsl_ir_constant *dst; - if (!(c = hlsl_alloc(ctx, sizeof(*c)))) + if (!(dst = hlsl_new_constant(ctx, src->node.data_type, &src->node.loc))) return NULL; - init_node(&c->node, HLSL_IR_CONSTANT, hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), loc); - c->value[0].i = n; - return c; + memcpy(dst->value, src->value, sizeof(src->value)); + return &dst->node; } -struct hlsl_ir_constant *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned int n, - const struct vkd3d_shader_location loc) +static struct hlsl_ir_node *clone_expr(struct hlsl_ctx *ctx, struct clone_instr_map *map, struct hlsl_ir_expr *src) { - struct hlsl_ir_constant *c; + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS]; + unsigned int i; - if (!(c = hlsl_alloc(ctx, sizeof(*c)))) + for (i = 0; i < ARRAY_SIZE(operands); ++i) + operands[i] = map_instr(map, src->operands[i].node); + + return hlsl_new_expr(ctx, src->op, operands, src->node.data_type, &src->node.loc); +} + +static struct hlsl_ir_node *clone_if(struct hlsl_ctx *ctx, struct clone_instr_map *map, struct hlsl_ir_if *src) +{ + struct hlsl_ir_if *dst; + + if (!(dst = hlsl_new_if(ctx, map_instr(map, src->condition.node), src->node.loc))) return NULL; - init_node(&c->node, HLSL_IR_CONSTANT, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc); - c->value[0].u = n; - return c; + + if (!clone_block(ctx, &dst->then_instrs, &src->then_instrs, map) + || !clone_block(ctx, &dst->else_instrs, &src->else_instrs, map)) + { + hlsl_free_instr(&dst->node); + return NULL; + } + return &dst->node; } -struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, - struct hlsl_ir_node *arg, struct vkd3d_shader_location loc) +static struct hlsl_ir_node *clone_jump(struct hlsl_ctx *ctx, struct hlsl_ir_jump *src) { - struct hlsl_ir_expr *expr; + struct hlsl_ir_jump *dst; - if (!(expr = hlsl_alloc(ctx, sizeof(*expr)))) + if (!(dst = hlsl_new_jump(ctx, src->type, src->node.loc))) return NULL; - init_node(&expr->node, HLSL_IR_EXPR, arg->data_type, loc); - expr->op = op; - hlsl_src_from_node(&expr->operands[0], arg); - return &expr->node; + return &dst->node; } -struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, - struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2) +static struct hlsl_ir_node *clone_load(struct hlsl_ctx *ctx, struct clone_instr_map *map, struct hlsl_ir_load *src) { - struct hlsl_ir_expr *expr; + struct hlsl_ir_load *dst; - assert(hlsl_types_are_equal(arg1->data_type, arg2->data_type)); + if (!(dst = hlsl_alloc(ctx, sizeof(*dst)))) + return NULL; + init_node(&dst->node, HLSL_IR_LOAD, src->node.data_type, &src->node.loc); - if (!(expr = hlsl_alloc(ctx, sizeof(*expr)))) + if (!clone_deref(ctx, map, &dst->src, &src->src)) + { + vkd3d_free(dst); return NULL; - init_node(&expr->node, HLSL_IR_EXPR, arg1->data_type, arg1->loc); - expr->op = op; - hlsl_src_from_node(&expr->operands[0], arg1); - hlsl_src_from_node(&expr->operands[1], arg2); - return &expr->node; + } + return &dst->node; } -struct hlsl_ir_if *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *condition, struct vkd3d_shader_location loc) +static struct hlsl_ir_node *clone_loop(struct hlsl_ctx *ctx, struct clone_instr_map *map, struct hlsl_ir_loop *src) { - struct hlsl_ir_if *iff; + struct hlsl_ir_loop *dst; - if (!(iff = hlsl_alloc(ctx, sizeof(*iff)))) + if (!(dst = hlsl_new_loop(ctx, src->node.loc))) return NULL; - init_node(&iff->node, HLSL_IR_IF, NULL, loc); - hlsl_src_from_node(&iff->condition, condition); - list_init(&iff->then_instrs.instrs); - list_init(&iff->else_instrs.instrs); - return iff; + if (!clone_block(ctx, &dst->body, &src->body, map)) + { + hlsl_free_instr(&dst->node); + return NULL; + } + return &dst->node; } -struct hlsl_ir_load *hlsl_new_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, struct hlsl_ir_node *offset, - struct hlsl_type *type, const struct vkd3d_shader_location loc) +static struct hlsl_ir_node *clone_resource_load(struct hlsl_ctx *ctx, + struct clone_instr_map *map, struct hlsl_ir_resource_load *src) { - struct hlsl_ir_load *load; + struct hlsl_ir_resource_load *dst; - if (!(load = hlsl_alloc(ctx, sizeof(*load)))) + if (!(dst = hlsl_alloc(ctx, sizeof(*dst)))) return NULL; - init_node(&load->node, HLSL_IR_LOAD, type, loc); - load->src.var = var; - hlsl_src_from_node(&load->src.offset, offset); - return load; + init_node(&dst->node, HLSL_IR_RESOURCE_LOAD, src->node.data_type, &src->node.loc); + dst->load_type = src->load_type; + if (!clone_deref(ctx, map, &dst->resource, &src->resource)) + { + vkd3d_free(dst); + return NULL; + } + if (!clone_deref(ctx, map, &dst->sampler, &src->sampler)) + { + hlsl_cleanup_deref(&dst->resource); + vkd3d_free(dst); + return NULL; + } + clone_src(map, &dst->coords, &src->coords); + clone_src(map, &dst->lod, &src->lod); + clone_src(map, &dst->texel_offset, &src->texel_offset); + return &dst->node; } -struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, - const struct vkd3d_shader_location loc) +static struct hlsl_ir_node *clone_resource_store(struct hlsl_ctx *ctx, + struct clone_instr_map *map, struct hlsl_ir_resource_store *src) { - return hlsl_new_load(ctx, var, NULL, var->data_type, loc); + struct hlsl_ir_resource_store *dst; + + if (!(dst = hlsl_alloc(ctx, sizeof(*dst)))) + return NULL; + init_node(&dst->node, HLSL_IR_RESOURCE_STORE, NULL, &src->node.loc); + if (!clone_deref(ctx, map, &dst->resource, &src->resource)) + { + vkd3d_free(dst); + return NULL; + } + clone_src(map, &dst->coords, &src->coords); + clone_src(map, &dst->value, &src->value); + return &dst->node; } -struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, struct hlsl_type *data_type, - enum hlsl_resource_load_type type, struct hlsl_ir_var *resource, struct hlsl_ir_node *resource_offset, - struct hlsl_ir_var *sampler, struct hlsl_ir_node *sampler_offset, struct hlsl_ir_node *coords, - struct hlsl_ir_node *texel_offset, const struct vkd3d_shader_location *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_resource_load *load; + struct hlsl_ir_store *dst; - if (!(load = hlsl_alloc(ctx, sizeof(*load)))) + if (!(dst = hlsl_alloc(ctx, sizeof(*dst)))) return NULL; - init_node(&load->node, HLSL_IR_RESOURCE_LOAD, data_type, *loc); - load->load_type = type; - load->resource.var = resource; - hlsl_src_from_node(&load->resource.offset, resource_offset); - load->sampler.var = sampler; - hlsl_src_from_node(&load->sampler.offset, sampler_offset); - hlsl_src_from_node(&load->coords, coords); - hlsl_src_from_node(&load->texel_offset, texel_offset); - return load; + init_node(&dst->node, HLSL_IR_STORE, NULL, &src->node.loc); + + if (!clone_deref(ctx, map, &dst->lhs, &src->lhs)) + { + vkd3d_free(dst); + return NULL; + } + clone_src(map, &dst->rhs, &src->rhs); + dst->writemask = src->writemask; + return &dst->node; } -struct hlsl_ir_swizzle *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned int components, - struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc) +static struct hlsl_ir_node *clone_swizzle(struct hlsl_ctx *ctx, + struct clone_instr_map *map, struct hlsl_ir_swizzle *src) { - struct hlsl_ir_swizzle *swizzle; + struct hlsl_ir_swizzle *dst; - if (!(swizzle = hlsl_alloc(ctx, sizeof(*swizzle)))) + if (!(dst = hlsl_new_swizzle(ctx, src->swizzle, src->node.data_type->dimx, + map_instr(map, src->val.node), &src->node.loc))) return NULL; - init_node(&swizzle->node, HLSL_IR_SWIZZLE, - hlsl_get_vector_type(ctx, val->data_type->base_type, components), *loc); - hlsl_src_from_node(&swizzle->val, val); - swizzle->swizzle = s; - return swizzle; + return &dst->node; } -struct hlsl_ir_jump *hlsl_new_jump(struct hlsl_ctx *ctx, enum hlsl_ir_jump_type type, struct vkd3d_shader_location loc) +static struct hlsl_ir_node *clone_instr(struct hlsl_ctx *ctx, + struct clone_instr_map *map, const struct hlsl_ir_node *instr) { - struct hlsl_ir_jump *jump; + switch (instr->type) + { + case HLSL_IR_CALL: + return clone_call(ctx, hlsl_ir_call(instr)); - if (!(jump = hlsl_alloc(ctx, sizeof(*jump)))) - return NULL; - init_node(&jump->node, HLSL_IR_JUMP, NULL, loc); - jump->type = type; - return jump; + case HLSL_IR_CONSTANT: + return clone_constant(ctx, hlsl_ir_constant(instr)); + + case HLSL_IR_EXPR: + return clone_expr(ctx, map, hlsl_ir_expr(instr)); + + case HLSL_IR_IF: + return clone_if(ctx, map, hlsl_ir_if(instr)); + + case HLSL_IR_JUMP: + return clone_jump(ctx, hlsl_ir_jump(instr)); + + case HLSL_IR_LOAD: + return clone_load(ctx, map, hlsl_ir_load(instr)); + + case HLSL_IR_LOOP: + return clone_loop(ctx, map, hlsl_ir_loop(instr)); + + case HLSL_IR_RESOURCE_LOAD: + return clone_resource_load(ctx, map, hlsl_ir_resource_load(instr)); + + case HLSL_IR_RESOURCE_STORE: + return clone_resource_store(ctx, map, hlsl_ir_resource_store(instr)); + + case HLSL_IR_STORE: + return clone_store(ctx, map, hlsl_ir_store(instr)); + + case HLSL_IR_SWIZZLE: + return clone_swizzle(ctx, map, hlsl_ir_swizzle(instr)); + } + + vkd3d_unreachable(); } -struct hlsl_ir_loop *hlsl_new_loop(struct hlsl_ctx *ctx, struct vkd3d_shader_location loc) +bool hlsl_clone_block(struct hlsl_ctx *ctx, struct hlsl_block *dst_block, const struct hlsl_block *src_block) { - struct hlsl_ir_loop *loop; + struct clone_instr_map map = {0}; + bool ret; - if (!(loop = hlsl_alloc(ctx, sizeof(*loop)))) - return NULL; - init_node(&loop->node, HLSL_IR_LOOP, NULL, loc); - list_init(&loop->body.instrs); - return loop; + ret = clone_block(ctx, dst_block, src_block, &map); + vkd3d_free(map.instrs); + return ret; } -struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, struct hlsl_type *return_type, - struct list *parameters, const struct hlsl_semantic *semantic, struct vkd3d_shader_location loc) +struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, + struct hlsl_type *return_type, const struct hlsl_func_parameters *parameters, + const struct hlsl_semantic *semantic, const struct vkd3d_shader_location *loc) { struct hlsl_ir_function_decl *decl; + struct hlsl_ir_constant *constant; + struct hlsl_ir_store *store; if (!(decl = hlsl_alloc(ctx, sizeof(*decl)))) return NULL; list_init(&decl->body.instrs); decl->return_type = return_type; - decl->parameters = parameters; - decl->loc = loc; + decl->parameters = *parameters; + decl->loc = *loc; if (!hlsl_types_are_equal(return_type, ctx->builtin_types.Void)) { - struct hlsl_ir_var *return_var; - char name[28]; - - sprintf(name, "", decl); - if (!(return_var = hlsl_new_var(ctx, hlsl_strdup(ctx, name), return_type, loc, semantic, 0, NULL))) + if (!(decl->return_var = hlsl_new_synthetic_var(ctx, "retval", return_type, loc))) { vkd3d_free(decl); return NULL; } - list_add_tail(&ctx->globals->vars, &return_var->scope_entry); - decl->return_var = return_var; + decl->return_var->semantic = *semantic; } + if (!(decl->early_return_var = hlsl_new_synthetic_var(ctx, "early_return", + hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL), loc))) + return decl; + + if (!(constant = hlsl_new_bool_constant(ctx, false, loc))) + return decl; + list_add_tail(&decl->body.instrs, &constant->node.entry); + + if (!(store = hlsl_new_simple_store(ctx, decl->early_return_var, &constant->node))) + return decl; + list_add_tail(&decl->body.instrs, &store->node.entry); + return decl; } @@ -743,7 +1645,7 @@ struct hlsl_buffer *hlsl_new_buffer(struct hlsl_ctx *ctx, enum hlsl_buffer_type return buffer; } -static int compare_hlsl_types_rb(const void *key, const struct wine_rb_entry *entry) +static int compare_hlsl_types_rb(const void *key, const struct rb_entry *entry) { const struct hlsl_type *type = RB_ENTRY_VALUE(entry, const struct hlsl_type, scope_entry); const char *name = key; @@ -759,18 +1661,28 @@ static int compare_hlsl_types_rb(const void *key, const struct wine_rb_entry *en return strcmp(name, type->name); } +static struct hlsl_scope *hlsl_new_scope(struct hlsl_ctx *ctx, struct hlsl_scope *upper) +{ + struct hlsl_scope *scope; + + if (!(scope = hlsl_alloc(ctx, sizeof(*scope)))) + return NULL; + list_init(&scope->vars); + rb_init(&scope->types, compare_hlsl_types_rb); + scope->upper = upper; + list_add_tail(&ctx->scopes, &scope->entry); + return scope; +} + void hlsl_push_scope(struct hlsl_ctx *ctx) { struct hlsl_scope *new_scope; - if (!(new_scope = hlsl_alloc(ctx, sizeof(*new_scope)))) + if (!(new_scope = hlsl_new_scope(ctx, ctx->cur_scope))) return; + TRACE("Pushing a new scope.\n"); - list_init(&new_scope->vars); - wine_rb_init(&new_scope->types, compare_hlsl_types_rb); - new_scope->upper = ctx->cur_scope; ctx->cur_scope = new_scope; - list_add_tail(&ctx->scopes, &new_scope->entry); } void hlsl_pop_scope(struct hlsl_ctx *ctx) @@ -808,24 +1720,22 @@ static int compare_param_hlsl_types(const struct hlsl_type *t1, const struct hls return r; if (t1->type == HLSL_CLASS_STRUCT) { - struct list *t1cur, *t2cur; - struct hlsl_struct_field *t1field, *t2field; + size_t i; - t1cur = list_head(t1->e.elements); - t2cur = list_head(t2->e.elements); - while (t1cur && t2cur) + if (t1->e.record.field_count != t2->e.record.field_count) + return t1->e.record.field_count - t2->e.record.field_count; + + for (i = 0; i < t1->e.record.field_count; ++i) { - t1field = LIST_ENTRY(t1cur, struct hlsl_struct_field, entry); - t2field = LIST_ENTRY(t2cur, struct hlsl_struct_field, entry); - if ((r = compare_param_hlsl_types(t1field->type, t2field->type))) + const struct hlsl_struct_field *field1 = &t1->e.record.fields[i]; + const struct hlsl_struct_field *field2 = &t2->e.record.fields[i]; + + if ((r = compare_param_hlsl_types(field1->type, field2->type))) return r; - if ((r = strcmp(t1field->name, t2field->name))) + + if ((r = strcmp(field1->name, field2->name))) return r; - t1cur = list_next(t1->e.elements, t1cur); - t2cur = list_next(t2->e.elements, t2cur); } - if (t1cur != t2cur) - return t1cur ? 1 : -1; return 0; } if (t1->type == HLSL_CLASS_ARRAY) @@ -838,29 +1748,20 @@ static int compare_param_hlsl_types(const struct hlsl_type *t1, const struct hls return 0; } -static int compare_function_decl_rb(const void *key, const struct wine_rb_entry *entry) +static int compare_function_decl_rb(const void *key, const struct rb_entry *entry) { - const struct list *params = key; const struct hlsl_ir_function_decl *decl = RB_ENTRY_VALUE(entry, const struct hlsl_ir_function_decl, entry); - int decl_params_count = decl->parameters ? list_count(decl->parameters) : 0; - int params_count = params ? list_count(params) : 0; - struct list *p1cur, *p2cur; + const struct hlsl_func_parameters *parameters = key; + size_t i; int r; - if ((r = vkd3d_u32_compare(params_count, decl_params_count))) + if ((r = vkd3d_u32_compare(parameters->count, decl->parameters.count))) return r; - p1cur = params ? list_head(params) : NULL; - p2cur = decl->parameters ? list_head(decl->parameters) : NULL; - while (p1cur && p2cur) + for (i = 0; i < parameters->count; ++i) { - struct hlsl_ir_var *p1, *p2; - p1 = LIST_ENTRY(p1cur, struct hlsl_ir_var, param_entry); - p2 = LIST_ENTRY(p2cur, struct hlsl_ir_var, param_entry); - if ((r = compare_param_hlsl_types(p1->data_type, p2->data_type))) + if ((r = compare_param_hlsl_types(parameters->vars[i]->data_type, decl->parameters.vars[i]->data_type))) return r; - p1cur = list_next(params, p1cur); - p2cur = list_next(decl->parameters, p2cur); } return 0; } @@ -920,7 +1821,12 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru } for (t = type; t->type == HLSL_CLASS_ARRAY; t = t->e.array.type) - vkd3d_string_buffer_printf(string, "[%u]", t->e.array.elements_count); + { + if (t->e.array.elements_count == HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT) + vkd3d_string_buffer_printf(string, "[]"); + else + vkd3d_string_buffer_printf(string, "[%u]", t->e.array.elements_count); + } return string; } @@ -958,6 +1864,11 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru base_types[type->e.resource_format->base_type], type->e.resource_format->dimx); return string; + case HLSL_TYPE_UAV: + vkd3d_string_buffer_printf(string, "RWTexture%s<%s%u>", dimensions[type->sampler_dim], + base_types[type->e.resource_format->base_type], type->e.resource_format->dimx); + return string; + default: vkd3d_string_buffer_printf(string, ""); return string; @@ -1003,7 +1914,7 @@ struct vkd3d_string_buffer *hlsl_modifiers_to_string(struct hlsl_ctx *ctx, unsig vkd3d_string_buffer_printf(string, "static "); if (modifiers & HLSL_STORAGE_UNIFORM) vkd3d_string_buffer_printf(string, "uniform "); - if (modifiers & HLSL_STORAGE_VOLATILE) + if (modifiers & HLSL_MODIFIER_VOLATILE) vkd3d_string_buffer_printf(string, "volatile "); if (modifiers & HLSL_MODIFIER_CONST) vkd3d_string_buffer_printf(string, "const "); @@ -1028,6 +1939,7 @@ const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type) { static const char * const names[] = { + "HLSL_IR_CALL", "HLSL_IR_CONSTANT", "HLSL_IR_EXPR", "HLSL_IR_IF", @@ -1035,6 +1947,7 @@ const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type) "HLSL_IR_LOOP", "HLSL_IR_JUMP", "HLSL_IR_RESOURCE_LOAD", + "HLSL_IR_RESOURCE_STORE", "HLSL_IR_STORE", "HLSL_IR_SWIZZLE", }; @@ -1044,6 +1957,20 @@ const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type) return names[type]; } +const char *hlsl_jump_type_to_string(enum hlsl_ir_jump_type type) +{ + static const char * const names[] = + { + "HLSL_IR_JUMP_BREAK", + "HLSL_IR_JUMP_CONTINUE", + "HLSL_IR_JUMP_DISCARD", + "HLSL_IR_JUMP_RETURN", + }; + + assert(type < ARRAY_SIZE(names)); + return names[type]; +} + static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, const struct hlsl_ir_node *instr); static void dump_instr_list(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, const struct list *list) @@ -1067,11 +1994,11 @@ static void dump_src(struct vkd3d_string_buffer *buffer, const struct hlsl_src * static void dump_ir_var(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, const struct hlsl_ir_var *var) { - if (var->modifiers) + if (var->storage_modifiers) { struct vkd3d_string_buffer *string; - if ((string = hlsl_modifiers_to_string(ctx, var->modifiers))) + if ((string = hlsl_modifiers_to_string(ctx, var->storage_modifiers))) vkd3d_string_buffer_printf(buffer, "%s ", string->buffer); hlsl_release_string_buffer(ctx, string); } @@ -1082,10 +2009,23 @@ static void dump_ir_var(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer static void dump_deref(struct vkd3d_string_buffer *buffer, const struct hlsl_deref *deref) { + unsigned int i; + if (deref->var) { vkd3d_string_buffer_printf(buffer, "%s", deref->var->name); - if (deref->offset.node) + if (deref->path_len) + { + vkd3d_string_buffer_printf(buffer, "["); + for (i = 0; i < deref->path_len; ++i) + { + vkd3d_string_buffer_printf(buffer, "["); + dump_src(buffer, &deref->path[i]); + vkd3d_string_buffer_printf(buffer, "]"); + } + vkd3d_string_buffer_printf(buffer, "]"); + } + else if (deref->offset.node) { vkd3d_string_buffer_printf(buffer, "["); dump_src(buffer, &deref->offset); @@ -1125,11 +2065,39 @@ const char *debug_hlsl_swizzle(unsigned int swizzle, unsigned int size) assert(size <= ARRAY_SIZE(components)); for (i = 0; i < size; ++i) - string[i] = components[(swizzle >> i * 2) & 3]; + string[i] = components[hlsl_swizzle_get_component(swizzle, i)]; string[size] = 0; return vkd3d_dbg_sprintf(".%s", string); } +static void dump_ir_call(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, const struct hlsl_ir_call *call) +{ + const struct hlsl_ir_function_decl *decl = call->decl; + struct vkd3d_string_buffer *string; + size_t i; + + if (!(string = hlsl_type_to_string(ctx, decl->return_type))) + return; + + vkd3d_string_buffer_printf(buffer, "call %s %s(", string->buffer, decl->func->name); + hlsl_release_string_buffer(ctx, string); + + for (i = 0; i < decl->parameters.count; ++i) + { + const struct hlsl_ir_var *param = decl->parameters.vars[i]; + + if (!(string = hlsl_type_to_string(ctx, param->data_type))) + return; + + if (i) + vkd3d_string_buffer_printf(buffer, ", "); + vkd3d_string_buffer_printf(buffer, "%s", string->buffer); + + hlsl_release_string_buffer(ctx, string); + } + vkd3d_string_buffer_printf(buffer, ")"); +} + static void dump_ir_constant(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_constant *constant) { struct hlsl_type *type = constant->node.data_type; @@ -1144,7 +2112,7 @@ static void dump_ir_constant(struct vkd3d_string_buffer *buffer, const struct hl switch (type->base_type) { case HLSL_TYPE_BOOL: - vkd3d_string_buffer_printf(buffer, "%s ", value->b ? "true" : "false"); + vkd3d_string_buffer_printf(buffer, "%s ", value->u ? "true" : "false"); break; case HLSL_TYPE_DOUBLE: @@ -1152,6 +2120,7 @@ static void dump_ir_constant(struct vkd3d_string_buffer *buffer, const struct hl break; case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: vkd3d_string_buffer_printf(buffer, "%.8e ", value->f); break; @@ -1164,7 +2133,7 @@ static void dump_ir_constant(struct vkd3d_string_buffer *buffer, const struct hl break; default: - assert(0); + vkd3d_unreachable(); } } if (type->dimx != 1) @@ -1175,6 +2144,8 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) { static const char *const op_names[] = { + [HLSL_OP0_VOID] = "void", + [HLSL_OP1_ABS] = "abs", [HLSL_OP1_BIT_NOT] = "~", [HLSL_OP1_CAST] = "cast", @@ -1189,6 +2160,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) [HLSL_OP1_NEG] = "-", [HLSL_OP1_NRM] = "nrm", [HLSL_OP1_RCP] = "rcp", + [HLSL_OP1_REINTERPRET] = "reinterpret", [HLSL_OP1_ROUND] = "round", [HLSL_OP1_RSQ] = "rsq", [HLSL_OP1_SAT] = "sat", @@ -1217,6 +2189,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) [HLSL_OP2_NEQUAL] = "!=", [HLSL_OP2_RSHIFT] = ">>", + [HLSL_OP3_DP2ADD] = "dp2add", [HLSL_OP3_LERP] = "lerp", }; @@ -1282,6 +2255,7 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru { [HLSL_RESOURCE_LOAD] = "load_resource", [HLSL_RESOURCE_SAMPLE] = "sample", + [HLSL_RESOURCE_SAMPLE_LOD] = "sample_lod", [HLSL_RESOURCE_GATHER_RED] = "gather_red", [HLSL_RESOURCE_GATHER_GREEN] = "gather_green", [HLSL_RESOURCE_GATHER_BLUE] = "gather_blue", @@ -1300,6 +2274,22 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru vkd3d_string_buffer_printf(buffer, ", offset = "); dump_src(buffer, &load->texel_offset); } + if (load->lod.node) + { + vkd3d_string_buffer_printf(buffer, ", lod = "); + dump_src(buffer, &load->lod); + } + vkd3d_string_buffer_printf(buffer, ")"); +} + +static void dump_ir_resource_store(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_resource_store *store) +{ + vkd3d_string_buffer_printf(buffer, "store_resource(resource = "); + dump_deref(buffer, &store->resource); + vkd3d_string_buffer_printf(buffer, ", coords = "); + dump_src(buffer, &store->coords); + vkd3d_string_buffer_printf(buffer, ", value = "); + dump_src(buffer, &store->value); vkd3d_string_buffer_printf(buffer, ")"); } @@ -1342,6 +2332,10 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, switch (instr->type) { + case HLSL_IR_CALL: + dump_ir_call(ctx, buffer, hlsl_ir_call(instr)); + break; + case HLSL_IR_CONSTANT: dump_ir_constant(buffer, hlsl_ir_constant(instr)); break; @@ -1370,6 +2364,10 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, dump_ir_resource_load(buffer, hlsl_ir_resource_load(instr)); break; + case HLSL_IR_RESOURCE_STORE: + dump_ir_resource_store(buffer, hlsl_ir_resource_store(instr)); + break; + case HLSL_IR_STORE: dump_ir_store(buffer, hlsl_ir_store(instr)); break; @@ -1383,14 +2381,14 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *func) { struct vkd3d_string_buffer buffer; - struct hlsl_ir_var *param; + size_t i; vkd3d_string_buffer_init(&buffer); vkd3d_string_buffer_printf(&buffer, "Dumping function %s.\n", func->func->name); vkd3d_string_buffer_printf(&buffer, "Function parameters:\n"); - LIST_FOR_EACH_ENTRY(param, func->parameters, struct hlsl_ir_var, param_entry) + for (i = 0; i < func->parameters.count; ++i) { - dump_ir_var(ctx, &buffer, param); + dump_ir_var(ctx, &buffer, func->parameters.vars[i]); vkd3d_string_buffer_printf(&buffer, "\n"); } if (func->has_body) @@ -1404,6 +2402,9 @@ 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); + LIST_FOR_EACH_ENTRY_SAFE(src, next, &old->uses, struct hlsl_src, entry) { hlsl_src_remove(src); @@ -1416,17 +2417,20 @@ void hlsl_replace_node(struct hlsl_ir_node *old, struct hlsl_ir_node *new) void hlsl_free_type(struct hlsl_type *type) { - struct hlsl_struct_field *field, *next_field; + struct hlsl_struct_field *field; + size_t i; vkd3d_free((void *)type->name); if (type->type == HLSL_CLASS_STRUCT) { - LIST_FOR_EACH_ENTRY_SAFE(field, next_field, type->e.elements, struct hlsl_struct_field, entry) + for (i = 0; i < type->e.record.field_count; ++i) { + field = &type->e.record.fields[i]; + vkd3d_free((void *)field->name); - vkd3d_free((void *)field->semantic.name); - vkd3d_free(field); + hlsl_cleanup_semantic(&field->semantic); } + vkd3d_free((void *)type->e.record.fields); } vkd3d_free(type); } @@ -1443,6 +2447,11 @@ void hlsl_free_instr_list(struct list *list) hlsl_free_instr(node); } +static void free_ir_call(struct hlsl_ir_call *call) +{ + vkd3d_free(call); +} + static void free_ir_constant(struct hlsl_ir_constant *constant) { vkd3d_free(constant); @@ -1472,7 +2481,7 @@ static void free_ir_jump(struct hlsl_ir_jump *jump) static void free_ir_load(struct hlsl_ir_load *load) { - hlsl_src_remove(&load->src.offset); + hlsl_cleanup_deref(&load->src); vkd3d_free(load); } @@ -1484,17 +2493,26 @@ static void free_ir_loop(struct hlsl_ir_loop *loop) static void free_ir_resource_load(struct hlsl_ir_resource_load *load) { + hlsl_cleanup_deref(&load->sampler); + hlsl_cleanup_deref(&load->resource); hlsl_src_remove(&load->coords); - hlsl_src_remove(&load->sampler.offset); - hlsl_src_remove(&load->resource.offset); + hlsl_src_remove(&load->lod); hlsl_src_remove(&load->texel_offset); vkd3d_free(load); } +static void free_ir_resource_store(struct hlsl_ir_resource_store *store) +{ + hlsl_src_remove(&store->resource.offset); + hlsl_src_remove(&store->coords); + hlsl_src_remove(&store->value); + vkd3d_free(store); +} + static void free_ir_store(struct hlsl_ir_store *store) { hlsl_src_remove(&store->rhs); - hlsl_src_remove(&store->lhs.offset); + hlsl_cleanup_deref(&store->lhs); vkd3d_free(store); } @@ -1510,6 +2528,10 @@ void hlsl_free_instr(struct hlsl_ir_node *node) switch (node->type) { + case HLSL_IR_CALL: + free_ir_call(hlsl_ir_call(node)); + break; + case HLSL_IR_CONSTANT: free_ir_constant(hlsl_ir_constant(node)); break; @@ -1538,6 +2560,10 @@ void hlsl_free_instr(struct hlsl_ir_node *node) free_ir_resource_load(hlsl_ir_resource_load(node)); break; + case HLSL_IR_RESOURCE_STORE: + free_ir_resource_store(hlsl_ir_resource_store(node)); + break; + case HLSL_IR_STORE: free_ir_store(hlsl_ir_store(node)); break; @@ -1548,76 +2574,75 @@ void hlsl_free_instr(struct hlsl_ir_node *node) } } +void hlsl_free_attribute(struct hlsl_attribute *attr) +{ + unsigned int i; + + for (i = 0; i < attr->args_count; ++i) + hlsl_src_remove(&attr->args[i]); + hlsl_free_instr_list(&attr->instrs); + vkd3d_free((void *)attr->name); + vkd3d_free(attr); +} + +void hlsl_cleanup_semantic(struct hlsl_semantic *semantic) +{ + vkd3d_free((void *)semantic->name); + memset(semantic, 0, sizeof(*semantic)); +} + static void free_function_decl(struct hlsl_ir_function_decl *decl) { - vkd3d_free(decl->parameters); + unsigned int i; + + for (i = 0; i < decl->attr_count; ++i) + hlsl_free_attribute((void *)decl->attrs[i]); + vkd3d_free((void *)decl->attrs); + + vkd3d_free(decl->parameters.vars); hlsl_free_instr_list(&decl->body.instrs); vkd3d_free(decl); } -static void free_function_decl_rb(struct wine_rb_entry *entry, void *context) +static void free_function_decl_rb(struct rb_entry *entry, void *context) { free_function_decl(RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry)); } static void free_function(struct hlsl_ir_function *func) { - wine_rb_destroy(&func->overloads, free_function_decl_rb, NULL); + rb_destroy(&func->overloads, free_function_decl_rb, NULL); vkd3d_free((void *)func->name); vkd3d_free(func); } -static void free_function_rb(struct wine_rb_entry *entry, void *context) +static void free_function_rb(struct rb_entry *entry, void *context) { free_function(RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry)); } -void hlsl_add_function(struct hlsl_ctx *ctx, char *name, struct hlsl_ir_function_decl *decl, bool intrinsic) +void hlsl_add_function(struct hlsl_ctx *ctx, char *name, struct hlsl_ir_function_decl *decl) { struct hlsl_ir_function *func; - struct wine_rb_entry *func_entry, *old_entry; + struct rb_entry *func_entry; - func_entry = wine_rb_get(&ctx->functions, name); + func_entry = rb_get(&ctx->functions, name); if (func_entry) { func = RB_ENTRY_VALUE(func_entry, struct hlsl_ir_function, entry); - if (intrinsic != func->intrinsic) - { - if (intrinsic) - { - ERR("Redeclaring a user defined function as an intrinsic.\n"); - return; - } - func->intrinsic = intrinsic; - wine_rb_destroy(&func->overloads, free_function_decl_rb, NULL); - wine_rb_init(&func->overloads, compare_function_decl_rb); - } decl->func = func; - if ((old_entry = wine_rb_get(&func->overloads, decl->parameters))) - { - struct hlsl_ir_function_decl *old_decl = - RB_ENTRY_VALUE(old_entry, struct hlsl_ir_function_decl, entry); - if (!decl->has_body) - { - free_function_decl(decl); - vkd3d_free(name); - return; - } - wine_rb_remove(&func->overloads, old_entry); - free_function_decl(old_decl); - } - wine_rb_put(&func->overloads, decl->parameters, &decl->entry); + if (rb_put(&func->overloads, &decl->parameters, &decl->entry) == -1) + ERR("Failed to insert function overload.\n"); vkd3d_free(name); return; } func = hlsl_alloc(ctx, sizeof(*func)); func->name = name; - wine_rb_init(&func->overloads, compare_function_decl_rb); + rb_init(&func->overloads, compare_function_decl_rb); decl->func = func; - wine_rb_put(&func->overloads, decl->parameters, &decl->entry); - func->intrinsic = intrinsic; - wine_rb_put(&ctx->functions, func->name, &func->entry); + rb_put(&func->overloads, &decl->parameters, &decl->entry); + rb_put(&ctx->functions, func->name, &func->entry); } unsigned int hlsl_map_swizzle(unsigned int swizzle, unsigned int writemask) @@ -1688,8 +2713,8 @@ unsigned int hlsl_combine_swizzles(unsigned int first, unsigned int second, unsi unsigned int ret = 0, i; for (i = 0; i < dim; ++i) { - unsigned int s = (second >> (i * 2)) & 3; - ret |= ((first >> (s * 2)) & 3) << (i * 2); + unsigned int s = hlsl_swizzle_get_component(second, i); + ret |= hlsl_swizzle_get_component(first, s) << HLSL_SWIZZLE_SHIFT(i); } return ret; } @@ -1771,7 +2796,7 @@ static const struct hlsl_profile_info *get_target_info(const char *target) return NULL; } -static int compare_function_rb(const void *key, const struct wine_rb_entry *entry) +static int compare_function_rb(const void *key, const struct rb_entry *entry) { const char *name = key; const struct hlsl_ir_function *func = RB_ENTRY_VALUE(entry, const struct hlsl_ir_function,entry); @@ -1781,7 +2806,7 @@ static int compare_function_rb(const void *key, const struct wine_rb_entry *entr static void declare_predefined_types(struct hlsl_ctx *ctx) { - unsigned int x, y, bt, i; + unsigned int x, y, bt, i, v; struct hlsl_type *type; static const char * const names[] = @@ -1793,7 +2818,11 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) "uint", "bool", }; - char name[10]; + char name[15]; + + static const char *const variants_float[] = {"min10float", "min16float"}; + static const char *const variants_int[] = {"min12int", "min16int"}; + static const char *const variants_uint[] = {"min16uint"}; static const char *const sampler_names[] = { @@ -1813,8 +2842,8 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) } effect_types[] = { - {"DWORD", HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1}, - {"FLOAT", HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1}, + {"dword", HLSL_CLASS_SCALAR, HLSL_TYPE_UINT, 1, 1}, + {"float", HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1}, {"VECTOR", HLSL_CLASS_VECTOR, HLSL_TYPE_FLOAT, 4, 1}, {"MATRIX", HLSL_CLASS_MATRIX, HLSL_TYPE_FLOAT, 4, 4}, {"STRING", HLSL_CLASS_OBJECT, HLSL_TYPE_STRING, 1, 1}, @@ -1853,6 +2882,63 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) } } + for (bt = 0; bt <= HLSL_TYPE_LAST_SCALAR; ++bt) + { + unsigned int n_variants = 0; + const char *const *variants; + + switch (bt) + { + case HLSL_TYPE_FLOAT: + variants = variants_float; + n_variants = ARRAY_SIZE(variants_float); + break; + + case HLSL_TYPE_INT: + variants = variants_int; + n_variants = ARRAY_SIZE(variants_int); + break; + + case HLSL_TYPE_UINT: + variants = variants_uint; + n_variants = ARRAY_SIZE(variants_uint); + break; + + default: + break; + } + + for (v = 0; v < n_variants; ++v) + { + for (y = 1; y <= 4; ++y) + { + for (x = 1; x <= 4; ++x) + { + sprintf(name, "%s%ux%u", variants[v], y, x); + type = hlsl_new_type(ctx, name, HLSL_CLASS_MATRIX, bt, x, y); + type->is_minimum_precision = 1; + hlsl_scope_add_type(ctx->globals, type); + + if (y == 1) + { + sprintf(name, "%s%u", variants[v], x); + type = hlsl_new_type(ctx, name, HLSL_CLASS_VECTOR, bt, x, y); + type->is_minimum_precision = 1; + hlsl_scope_add_type(ctx->globals, type); + + if (x == 1) + { + sprintf(name, "%s", variants[v]); + type = hlsl_new_type(ctx, name, HLSL_CLASS_SCALAR, bt, x, y); + type->is_minimum_precision = 1; + hlsl_scope_add_type(ctx->globals, type); + } + } + } + } + } + } + for (bt = 0; bt <= HLSL_SAMPLER_DIM_LAST_SAMPLER; ++bt) { type = hlsl_new_type(ctx, sampler_names[bt], HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1); @@ -1891,16 +2977,21 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const char *source_name, ctx->location.line = ctx->location.column = 1; vkd3d_string_buffer_cache_init(&ctx->string_buffers); - ctx->matrix_majority = HLSL_COLUMN_MAJOR; - list_init(&ctx->scopes); + + if (!(ctx->dummy_scope = hlsl_new_scope(ctx, NULL))) + { + vkd3d_free((void *)ctx->source_files[0]); + vkd3d_free(ctx->source_files); + return false; + } hlsl_push_scope(ctx); ctx->globals = ctx->cur_scope; list_init(&ctx->types); declare_predefined_types(ctx); - wine_rb_init(&ctx->functions, compare_function_rb); + rb_init(&ctx->functions, compare_function_rb); list_init(&ctx->static_initializers); list_init(&ctx->extern_vars); @@ -1931,13 +3022,13 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx) vkd3d_free(ctx->source_files); vkd3d_string_buffer_cache_cleanup(&ctx->string_buffers); - wine_rb_destroy(&ctx->functions, free_function_rb, NULL); + rb_destroy(&ctx->functions, free_function_rb, NULL); LIST_FOR_EACH_ENTRY_SAFE(scope, next_scope, &ctx->scopes, struct hlsl_scope, entry) { LIST_FOR_EACH_ENTRY_SAFE(var, next_var, &scope->vars, struct hlsl_ir_var, scope_entry) hlsl_free_var(var); - wine_rb_destroy(&scope->types, NULL, NULL); + rb_destroy(&scope->types, NULL, NULL); vkd3d_free(scope); } @@ -1955,8 +3046,9 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) { const struct vkd3d_shader_hlsl_source_info *hlsl_source_info; - struct hlsl_ir_function_decl *entry_func; + struct hlsl_ir_function_decl *decl, *entry_func = NULL; const struct hlsl_profile_info *profile; + struct hlsl_ir_function *func; const char *entry_point; struct hlsl_ctx ctx; int ret; @@ -2012,7 +3104,23 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d return VKD3D_ERROR_NOT_IMPLEMENTED; } - if (!(entry_func = hlsl_get_func_decl(&ctx, entry_point))) + if ((func = hlsl_get_function(&ctx, entry_point))) + { + RB_FOR_EACH_ENTRY(decl, &func->overloads, struct hlsl_ir_function_decl, entry) + { + if (!decl->has_body) + continue; + if (entry_func) + { + /* Depending on d3dcompiler version, either the first or last is + * selected. */ + hlsl_fixme(&ctx, &decl->loc, "Multiple valid entry point definitions."); + } + entry_func = decl; + } + } + + if (!entry_func) { const struct vkd3d_shader_location loc = {.source_name = compile_info->source_name}; diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/hlsl.h b/dll/directx/wine/vkd3d/libs/vkd3d-shader/hlsl.h similarity index 51% rename from dll/directx/wine/d3d12/vkd3d/vkd3d-shader/hlsl.h rename to dll/directx/wine/vkd3d/libs/vkd3d-shader/hlsl.h index 9aacd4829d8b1..ccbf22a580146 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/hlsl.h +++ b/dll/directx/wine/vkd3d/libs/vkd3d-shader/hlsl.h @@ -21,9 +21,9 @@ #define __VKD3D_SHADER_HLSL_H #include "vkd3d_shader_private.h" -#include "rbtree.h" -#include "vkd3d_d3dcommon.h" -#include "vkd3d_d3dx9shader.h" +#include "wine/rbtree.h" +#include "d3dcommon.h" +#include "d3dx9shader.h" #include "sm4.h" /* The general IR structure is inspired by Mesa GLSL hir, even though the code @@ -63,6 +63,14 @@ | ((HLSL_SWIZZLE_ ## z) << 4) \ | ((HLSL_SWIZZLE_ ## w) << 6)) +#define HLSL_SWIZZLE_MASK (0x3u) +#define HLSL_SWIZZLE_SHIFT(idx) (2u * (idx)) + +static inline unsigned int hlsl_swizzle_get_component(unsigned int swizzle, unsigned int idx) +{ + return (swizzle >> HLSL_SWIZZLE_SHIFT(idx)) & HLSL_SWIZZLE_MASK; +} + enum hlsl_type_class { HLSL_CLASS_SCALAR, @@ -85,6 +93,7 @@ enum hlsl_base_type HLSL_TYPE_LAST_SCALAR = HLSL_TYPE_BOOL, HLSL_TYPE_SAMPLER, HLSL_TYPE_TEXTURE, + HLSL_TYPE_UAV, HLSL_TYPE_PIXELSHADER, HLSL_TYPE_VERTEXSHADER, HLSL_TYPE_STRING, @@ -107,65 +116,141 @@ enum hlsl_sampler_dim HLSL_SAMPLER_DIM_MAX = HLSL_SAMPLER_DIM_CUBEARRAY, }; -enum hlsl_matrix_majority +enum hlsl_regset { - HLSL_COLUMN_MAJOR, - HLSL_ROW_MAJOR + HLSL_REGSET_SAMPLERS, + HLSL_REGSET_TEXTURES, + HLSL_REGSET_UAVS, + HLSL_REGSET_LAST_OBJECT = HLSL_REGSET_UAVS, + HLSL_REGSET_NUMERIC, + HLSL_REGSET_LAST = HLSL_REGSET_NUMERIC, }; +/* An HLSL source-level data type, including anonymous structs and typedefs. */ struct hlsl_type { + /* Item entry in hlsl_ctx->types. */ struct list entry; - struct wine_rb_entry scope_entry; + /* Item entry in hlsl_scope->types. hlsl_type->name is used as key (if not NULL). */ + struct rb_entry scope_entry; + enum hlsl_type_class type; + /* If type is <= HLSL_CLASS_LAST_NUMERIC, then base_type is <= HLSL_TYPE_LAST_SCALAR. + * If type is HLSL_CLASS_OBJECT, then base_type is > HLSL_TYPE_LAST_SCALAR. + * Otherwise, base_type is not used. */ enum hlsl_base_type base_type; + + /* If base_type is HLSL_TYPE_SAMPLER, then sampler_dim is <= HLSL_SAMPLER_DIM_LAST_SAMPLER. + * If base_type is HLSL_TYPE_TEXTURE, then sampler_dim can have any value of the enum. + * If base_type is HLSL_TYPE_UAV, them sampler_dim must be one of HLSL_SAMPLER_DIM_1D, + * HLSL_SAMPLER_DIM_2D, HLSL_SAMPLER_DIM_3D, HLSL_SAMPLER_DIM_1DARRAY, or HLSL_SAMPLER_DIM_2DARRAY. + * Otherwise, sampler_dim is not used */ enum hlsl_sampler_dim sampler_dim; + /* Name, in case the type is a named struct or a typedef. */ const char *name; + /* Bitfield for storing type modifiers, subset of HLSL_TYPE_MODIFIERS_MASK. + * Modifiers that don't fall inside this mask are to be stored in the variable in + * hlsl_ir_var.modifiers, or in the struct field in hlsl_ir_field.modifiers. */ unsigned int modifiers; + /* Size of the type values on each dimension. For non-numeric types, they are set for the + * convenience of the sm1/sm4 backends. + * If type is HLSL_CLASS_SCALAR, then both dimx = 1 and dimy = 1. + * If type is HLSL_CLASS_VECTOR, then dimx is the size of the vector, and dimy = 1. + * If type is HLSL_CLASS_MATRIX, then dimx is the number of columns, and dimy the number of rows. + * If type is HLSL_CLASS_ARRAY, then dimx and dimy have the same value as in the type of the array elements. + * If type is HLSL_CLASS_STRUCT, then dimx is the sum of (dimx * dimy) of every component, and dimy = 1. + * If type is HLSL_CLASS_OBJECT, dimx and dimy depend on the base_type: + * If base_type is HLSL_TYPE_SAMPLER, then both dimx = 1 and dimy = 1. + * If base_type is HLSL_TYPE_TEXTURE, then dimx = 4 and dimy = 1. + * If base_type is HLSL_TYPE_UAV, then dimx is the dimx of e.resource_format, and dimy = 1. + * Otherwise both dimx = 1 and dimy = 1. */ unsigned int dimx; unsigned int dimy; + /* Sample count for HLSL_SAMPLER_DIM_2DMS or HLSL_SAMPLER_DIM_2DMSARRAY. */ + unsigned int sample_count; + union { - struct list *elements; + /* Additional information if type is HLSL_CLASS_STRUCT. */ + struct + { + struct hlsl_struct_field *fields; + size_t field_count; + } record; + /* Additional information if type is HLSL_CLASS_ARRAY. */ struct { struct hlsl_type *type; + /* Array length, or HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT if it is not known yet at parse time. */ unsigned int elements_count; } array; + /* Format of the data contained within the type if the base_type is HLSL_TYPE_TEXTURE or + * HLSL_TYPE_UAV. */ struct hlsl_type *resource_format; } e; - unsigned int reg_size; + /* Number of numeric register components used by one value of this type, for each regset. + * For HLSL_REGSET_NUMERIC, 4 components make 1 register, while for other regsets 1 component makes + * 1 register. + * If type is HLSL_CLASS_STRUCT or HLSL_CLASS_ARRAY, the reg_size of their elements and padding + * (which varies according to the backend) is also included. */ + unsigned int reg_size[HLSL_REGSET_LAST + 1]; + /* Offset where the type's description starts in the output bytecode, in bytes. */ size_t bytecode_offset; + + uint32_t is_minimum_precision : 1; }; +/* In HLSL, a semantic is a string linked to a variable (or a field) to be recognized across + * different shader stages in the graphics pipeline. */ struct hlsl_semantic { const char *name; uint32_t index; }; +/* A field within a struct type declaration, used in hlsl_type.e.fields. */ struct hlsl_struct_field { - struct list entry; struct vkd3d_shader_location loc; struct hlsl_type *type; const char *name; struct hlsl_semantic semantic; - unsigned int reg_offset; + /* Bitfield for storing modifiers that are not in HLSL_TYPE_MODIFIERS_MASK (these are stored in + * type->modifiers instead) and that also are specific to the field and not the whole variable. + * In particular, interpolation modifiers. */ + unsigned int storage_modifiers; + /* Offset of the field within the type it belongs to, in register components, for each regset. */ + unsigned int reg_offset[HLSL_REGSET_LAST + 1]; + + /* Offset where the field name starts in the output bytecode, in bytes. */ size_t name_bytecode_offset; }; +/* Information of the register allocated for an instruction node or variable. + * These values are initialized at the end of hlsl_emit_bytecode(), after the compilation passes, + * just before writing the bytecode. + * For numeric registers, a writemask can be provided to indicate the reservation of only some of the + * 4 components. + * The type of register (register class) is implied from its use, so it is not stored in this + * struct. */ struct hlsl_reg { uint32_t id; unsigned int writemask; + /* Whether the register has been allocated. */ bool allocated; }; +/* Types of instruction nodes for the IR. + * Each type of instruction node is associated to a struct with the same name in lower case. + * e.g. for HLSL_IR_CONSTANT there exists struct hlsl_ir_constant. + * Each one of these structs start with a struct hlsl_ir_node field, so pointers to values of these + * types can be casted seamlessly to (struct hlsl_ir_node *) and vice-versa. */ enum hlsl_ir_node_type { + HLSL_IR_CALL, HLSL_IR_CONSTANT, HLSL_IR_EXPR, HLSL_IR_IF, @@ -173,16 +258,27 @@ enum hlsl_ir_node_type HLSL_IR_LOOP, HLSL_IR_JUMP, HLSL_IR_RESOURCE_LOAD, + HLSL_IR_RESOURCE_STORE, HLSL_IR_STORE, HLSL_IR_SWIZZLE, }; +/* Common data for every type of IR instruction node. */ struct hlsl_ir_node { + /* Item entry for storing the instruction in a list of instructions. */ struct list entry; + + /* Type of node, which means that a pointer to this struct hlsl_ir_node can be casted to a + * pointer to the struct with the same name. */ enum hlsl_ir_node_type type; + /* HLSL data type of the node, when used by other nodes as a source (through an hlsl_src). + * HLSL_IR_CONSTANT, HLSL_IR_EXPR, HLSL_IR_LOAD, HLSL_IR_RESOURCE_LOAD, and HLSL_IR_SWIZZLE + * have a data type and can be used through an hlsl_src; other types of node don't. */ struct hlsl_type *data_type; + /* List containing all the struct hlsl_src·s that point to this node; linked by the + * hlsl_src.entry fields. */ struct list uses; struct vkd3d_shader_location loc; @@ -192,20 +288,38 @@ struct hlsl_ir_node * true even for loops, since currently we can't have a reference to a * value generated in an earlier iteration of the loop. */ unsigned int index, last_read; + /* Temp. register allocated to store the result of this instruction (if any). */ struct hlsl_reg reg; }; struct hlsl_block { + /* List containing instruction nodes; linked by the hlsl_ir_node.entry fields. */ struct list instrs; }; +/* A reference to an instruction node (struct hlsl_ir_node), usable as a field in other structs. + * struct hlsl_src is more powerful than a mere pointer to an hlsl_ir_node because it also + * contains a linked list item entry, which is used by the referenced instruction node to keep + * track of all the hlsl_src·s that reference it. + * This allows replacing any hlsl_ir_node with any other in all the places it is used, or checking + * that a node has no uses before it is removed. */ struct hlsl_src { struct hlsl_ir_node *node; + /* Item entry for node->uses. */ struct list entry; }; +struct hlsl_attribute +{ + const char *name; + struct list instrs; + struct vkd3d_shader_location loc; + unsigned int args_count; + struct hlsl_src args[]; +}; + #define HLSL_STORAGE_EXTERN 0x00000001 #define HLSL_STORAGE_NOINTERPOLATION 0x00000002 #define HLSL_MODIFIER_PRECISE 0x00000004 @@ -213,19 +327,23 @@ struct hlsl_src #define HLSL_STORAGE_GROUPSHARED 0x00000010 #define HLSL_STORAGE_STATIC 0x00000020 #define HLSL_STORAGE_UNIFORM 0x00000040 -#define HLSL_STORAGE_VOLATILE 0x00000080 +#define HLSL_MODIFIER_VOLATILE 0x00000080 #define HLSL_MODIFIER_CONST 0x00000100 #define HLSL_MODIFIER_ROW_MAJOR 0x00000200 #define HLSL_MODIFIER_COLUMN_MAJOR 0x00000400 #define HLSL_STORAGE_IN 0x00000800 #define HLSL_STORAGE_OUT 0x00001000 -#define HLSL_TYPE_MODIFIERS_MASK (HLSL_MODIFIER_PRECISE | HLSL_STORAGE_VOLATILE | \ +#define HLSL_TYPE_MODIFIERS_MASK (HLSL_MODIFIER_PRECISE | HLSL_MODIFIER_VOLATILE | \ HLSL_MODIFIER_CONST | HLSL_MODIFIER_ROW_MAJOR | \ HLSL_MODIFIER_COLUMN_MAJOR) #define HLSL_MODIFIERS_MAJORITY_MASK (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR) +#define HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT 0 + +/* Reservation of a specific register to a variable, field, or buffer, written in the HLSL source + * using the register(·) syntax */ struct hlsl_reg_reservation { char type; @@ -238,14 +356,33 @@ struct hlsl_ir_var struct vkd3d_shader_location loc; const char *name; struct hlsl_semantic semantic; + /* Buffer where the variable's value is stored, in case it is uniform. */ struct hlsl_buffer *buffer; - unsigned int modifiers; + /* Bitfield for storage modifiers (type modifiers are stored in data_type->modifiers). */ + unsigned int storage_modifiers; + /* Optional register to be used as a starting point for the variable allocation, specified + * by the user via the register(·) syntax. */ struct hlsl_reg_reservation reg_reservation; - struct list scope_entry, param_entry, extern_entry; + /* Item entry in hlsl_scope.vars. Specifically hlsl_ctx.globals.vars if the variable is global. */ + struct list scope_entry; + /* Item entry in hlsl_ctx.extern_vars, if the variable is extern. */ + struct list extern_entry; + + /* Indexes of the IR instructions where the variable is first written and last read (liveness + * range). The IR instructions are numerated starting from 2, because 0 means unused, and 1 + * means function entry. */ unsigned int first_write, last_read; + /* Offset where the variable's value is stored within its buffer in numeric register components. + * This in case the variable is uniform. */ unsigned int buffer_offset; - struct hlsl_reg reg; + /* Register to which the variable is allocated during its lifetime, for each register set. + * In case that the variable spans multiple registers in one regset, this is set to the + * start of the register range. + * Builtin semantics don't use the field. + * In SM4, uniforms don't use the field because they are located using the buffer's hlsl_reg + * and the buffer_offset instead. */ + struct hlsl_reg regs[HLSL_REGSET_LAST + 1]; uint32_t is_input_semantic : 1; uint32_t is_output_semantic : 1; @@ -253,24 +390,56 @@ struct hlsl_ir_var uint32_t is_param : 1; }; +/* Sized array of variables representing a function's parameters. */ +struct hlsl_func_parameters +{ + struct hlsl_ir_var **vars; + size_t count, capacity; +}; + struct hlsl_ir_function { - struct wine_rb_entry entry; + /* Item entry in hlsl_ctx.functions */ + struct rb_entry entry; + const char *name; - struct wine_rb_tree overloads; - bool intrinsic; + /* Tree containing function definitions, stored as hlsl_ir_function_decl structures, which would + * be more than one in case of function overloading. */ + struct rb_tree overloads; }; struct hlsl_ir_function_decl { struct hlsl_type *return_type; + /* Synthetic variable used to store the return value of the function. */ struct hlsl_ir_var *return_var; + struct vkd3d_shader_location loc; - struct wine_rb_entry entry; + /* Item entry in hlsl_ir_function.overloads. The parameters' types are used as key. */ + struct rb_entry entry; + + /* Function to which this declaration corresponds. */ struct hlsl_ir_function *func; - struct list *parameters; + + struct hlsl_func_parameters parameters; + struct hlsl_block body; bool has_body; + /* Array of attributes (like numthreads) specified just before the function declaration. + * Not to be confused with the function parameters! */ + unsigned int attr_count; + const struct hlsl_attribute *const *attrs; + + /* Synthetic boolean variable marking whether a return statement has been + * executed. Needed to deal with return statements in non-uniform control + * flow, since some backends can't handle them. */ + struct hlsl_ir_var *early_return_var; +}; + +struct hlsl_ir_call +{ + struct hlsl_ir_node node; + struct hlsl_ir_function_decl *decl; }; struct hlsl_ir_if @@ -291,6 +460,8 @@ struct hlsl_ir_loop enum hlsl_ir_expr_op { + HLSL_OP0_VOID, + HLSL_OP1_ABS, HLSL_OP1_BIT_NOT, HLSL_OP1_CAST, @@ -306,6 +477,7 @@ enum hlsl_ir_expr_op HLSL_OP1_NEG, HLSL_OP1_NRM, HLSL_OP1_RCP, + HLSL_OP1_REINTERPRET, HLSL_OP1_ROUND, HLSL_OP1_RSQ, HLSL_OP1_SAT, @@ -334,6 +506,7 @@ enum hlsl_ir_expr_op HLSL_OP2_NEQUAL, HLSL_OP2_RSHIFT, + HLSL_OP3_DP2ADD, HLSL_OP3_LERP, }; @@ -367,10 +540,28 @@ struct hlsl_ir_swizzle DWORD swizzle; }; +/* Reference to a variable, or a part of it (e.g. a vector within a matrix within a struct). */ struct hlsl_deref { struct hlsl_ir_var *var; + + /* An array of references to instruction nodes, of data type uint, that are used to reach the + * desired part of the variable. + * If path_len is 0, then this is a reference to the whole variable. + * The value of each instruction node in the path corresponds to the index of the element/field + * that has to be selected on each nesting level to reach this part. + * The path shall not contain additional values once a type that cannot be subdivided + * (a.k.a. "component") is reached. */ + unsigned int path_len; + struct hlsl_src *path; + + /* Single instruction node of data type uint used to represent the register offset (in register + * components, within the pertaining regset), from the start of the variable, of the part + * referenced. + * The path is lowered to this single offset -- whose value may vary between SM1 and SM4 -- + * before writing the bytecode. */ struct hlsl_src offset; + enum hlsl_regset offset_regset; }; struct hlsl_ir_load @@ -383,6 +574,7 @@ enum hlsl_resource_load_type { HLSL_RESOURCE_LOAD, HLSL_RESOURCE_SAMPLE, + HLSL_RESOURCE_SAMPLE_LOD, HLSL_RESOURCE_GATHER_RED, HLSL_RESOURCE_GATHER_GREEN, HLSL_RESOURCE_GATHER_BLUE, @@ -394,8 +586,14 @@ struct hlsl_ir_resource_load struct hlsl_ir_node node; enum hlsl_resource_load_type load_type; struct hlsl_deref resource, sampler; - struct hlsl_src coords; - struct hlsl_src texel_offset; + struct hlsl_src coords, lod, texel_offset; +}; + +struct hlsl_ir_resource_store +{ + struct hlsl_ir_node node; + struct hlsl_deref resource; + struct hlsl_src coords, value; }; struct hlsl_ir_store @@ -415,16 +613,22 @@ struct hlsl_ir_constant int32_t i; float f; double d; - bool b; } value[4]; + /* Constant register of type 'c' where the constant value is stored for SM1. */ struct hlsl_reg reg; }; struct hlsl_scope { + /* Item entry for hlsl_ctx.scopes. */ struct list entry; + + /* List containing the variables declared in this scope; linked by hlsl_ir_var->scope_entry. */ struct list vars; - struct wine_rb_tree types; + /* Tree map containing the types declared in this scope, using hlsl_tree.name as key. + * The types are attached through the hlsl_type.scope_entry fields. */ + struct rb_tree types; + /* Scope containing this scope. This value is NULL for the global scope. */ struct hlsl_scope *upper; }; @@ -450,15 +654,25 @@ enum hlsl_buffer_type HLSL_BUFFER_TEXTURE, }; +/* In SM4, uniform variables are organized in different buffers. Besides buffers defined in the + * source code, there is also the implicit $Globals buffer and the implicit $Params buffer, + * to which uniform globals and parameters belong by default. */ struct hlsl_buffer { struct vkd3d_shader_location loc; enum hlsl_buffer_type type; const char *name; + /* Register reserved for this buffer, if any. + * If provided, it should be of type 'b' if type is HLSL_BUFFER_CONSTANT and 't' if type is + * HLSL_BUFFER_TEXTURE. */ struct hlsl_reg_reservation reservation; + /* Item entry for hlsl_ctx.buffers */ struct list entry; + /* The size of the buffer (in register components), and the size of the buffer as determined + * by its last variable that's actually used. */ unsigned size, used_size; + /* Register of type 'b' on which the buffer is allocated. */ struct hlsl_reg reg; }; @@ -468,46 +682,91 @@ struct hlsl_ctx const char **source_files; unsigned int source_files_count; + /* Current location being read in the HLSL source, updated while parsing. */ struct vkd3d_shader_location location; + /* Stores the logging messages and logging configuration. */ struct vkd3d_shader_message_context *message_context; + /* Cache for temporary string allocations. */ struct vkd3d_string_buffer_cache string_buffers; + /* A value from enum vkd3d_result with the current success/failure result of the whole + * compilation. + * It is initialized to VKD3D_OK and set to an error code in case a call to hlsl_fixme() or + * hlsl_error() is triggered, or in case of a memory allocation error. + * The value of this field is checked between compilation stages to stop execution in case of + * failure. */ int result; + /* Pointer to an opaque data structure managed by FLEX (during lexing), that encapsulates the + * current state of the scanner. This pointer is required by all FLEX API functions when the + * scanner is declared as reentrant, which is the case. */ void *scanner; + /* Pointer to the current scope; changes as the parser reads the code. */ struct hlsl_scope *cur_scope; + /* Scope of global variables. */ struct hlsl_scope *globals; + /* Dummy scope for variables which should never be looked up by name. */ + struct hlsl_scope *dummy_scope; + /* List of all the scopes in the program; linked by the hlsl_scope.entry fields. */ struct list scopes; + /* List of all the extern variables; linked by the hlsl_ir_var.extern_entry fields. + * This exists as a convenience because it is often necessary to iterate all extern variables + * and these can be declared in global scope, as function parameters, or as the function + * return value. */ struct list extern_vars; + /* List containing both the built-in HLSL buffers ($Globals and $Params) and the ones declared + * in the shader; linked by the hlsl_buffer.entry fields. */ struct list buffers; + /* Current buffer (changes as the parser reads the code), $Globals buffer, and $Params buffer, + * respectively. */ struct hlsl_buffer *cur_buffer, *globals_buffer, *params_buffer; + /* List containing all created hlsl_types, except builtin_types; linked by the hlsl_type.entry + * fields. */ struct list types; - struct wine_rb_tree functions; + /* Tree map for the declared functions, using hlsl_ir_function.name as key. + * The functions are attached through the hlsl_ir_function.entry fields. */ + struct rb_tree functions; + /* Pointer to the current function; changes as the parser reads the code. */ const struct hlsl_ir_function_decl *cur_function; - enum hlsl_matrix_majority matrix_majority; + /* Default matrix majority for matrix types. Can be set by a pragma within the HLSL source. */ + unsigned int matrix_majority; + /* Basic data types stored for convenience. */ struct { struct hlsl_type *scalar[HLSL_TYPE_LAST_SCALAR + 1]; struct hlsl_type *vector[HLSL_TYPE_LAST_SCALAR + 1][4]; - /* matrix[float][2][4] is a float4x2, i.e. dimx = 2, dimy = 4 */ + /* 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 *Void; } builtin_types; + /* List of the instruction nodes for initializing static variables; linked by the + * hlsl_ir_node.entry fields. */ struct list static_initializers; + /* Dynamic array of constant values that appear in the shader, associated to the 'c' registers. + * Only used for SM1 profiles. */ struct hlsl_constant_defs { struct hlsl_vec4 *values; size_t count, size; } constant_defs; + /* 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; + /* Number of threads to be executed (on the X, Y, and Z dimensions) in a single thread group in + * compute shader profiles. It is set using the numthreads() attribute in the entry point. */ + uint32_t thread_count[3]; + + /* Whether the parser is inside a state block (effects' metadata) inside a variable declaration. */ uint32_t in_state_block : 1; + /* Whether the numthreads() attribute has been provided in the entry-point function. */ + uint32_t found_numthreads : 1; }; enum hlsl_error_level @@ -517,6 +776,20 @@ enum hlsl_error_level HLSL_LEVEL_NOTE, }; +struct hlsl_resource_load_params +{ + struct hlsl_type *format; + enum hlsl_resource_load_type type; + struct hlsl_deref resource, sampler; + struct hlsl_ir_node *coords, *lod, *texel_offset; +}; + +static inline struct hlsl_ir_call *hlsl_ir_call(const struct hlsl_ir_node *node) +{ + 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); @@ -559,6 +832,12 @@ static inline struct hlsl_ir_resource_load *hlsl_ir_resource_load(const struct h 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); + 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); @@ -571,16 +850,6 @@ static inline struct hlsl_ir_swizzle *hlsl_ir_swizzle(const struct hlsl_ir_node return CONTAINING_RECORD(node, struct hlsl_ir_swizzle, node); } -static inline void init_node(struct hlsl_ir_node *node, enum hlsl_ir_node_type type, - struct hlsl_type *data_type, struct vkd3d_shader_location loc) -{ - memset(node, 0, sizeof(*node)); - node->type = type; - node->data_type = data_type; - node->loc = loc; - list_init(&node->uses); -} - static inline void hlsl_src_from_node(struct hlsl_src *src, struct hlsl_ir_node *node) { src->node = node; @@ -692,8 +961,7 @@ static inline unsigned int hlsl_sampler_dim_count(enum hlsl_sampler_dim dim) case HLSL_SAMPLER_DIM_CUBEARRAY: return 4; default: - assert(0); - return 0; + vkd3d_unreachable(); } } @@ -706,65 +974,103 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru struct vkd3d_string_buffer *hlsl_modifiers_to_string(struct hlsl_ctx *ctx, unsigned int modifiers); const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type); -void hlsl_add_function(struct hlsl_ctx *ctx, char *name, struct hlsl_ir_function_decl *decl, bool intrinsic); +struct hlsl_ir_load *hlsl_add_conditional(struct hlsl_ctx *ctx, struct list *instrs, + struct hlsl_ir_node *condition, struct hlsl_ir_node *if_true, struct hlsl_ir_node *if_false); +void hlsl_add_function(struct hlsl_ctx *ctx, char *name, struct hlsl_ir_function_decl *decl); bool hlsl_add_var(struct hlsl_ctx *ctx, struct hlsl_ir_var *decl, bool local_var); +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); int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out); +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); + void hlsl_replace_node(struct hlsl_ir_node *old, struct hlsl_ir_node *new); +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_type(struct hlsl_type *type); void hlsl_free_var(struct hlsl_ir_var *decl); -bool hlsl_get_function(struct hlsl_ctx *ctx, const char *name); +struct hlsl_ir_function *hlsl_get_function(struct hlsl_ctx *ctx, const char *name); struct hlsl_ir_function_decl *hlsl_get_func_decl(struct hlsl_ctx *ctx, const char *name); -struct hlsl_type *hlsl_get_type(struct hlsl_scope *scope, const char *name, bool recursive); +struct hlsl_type *hlsl_get_type(struct hlsl_scope *scope, const char *name, bool recursive, bool case_insensitive); struct hlsl_ir_var *hlsl_get_var(struct hlsl_scope *scope, const char *name); +struct hlsl_type *hlsl_get_element_type_from_path_index(struct hlsl_ctx *ctx, const struct hlsl_type *type, + struct hlsl_ir_node *idx); + +const char *hlsl_jump_type_to_string(enum hlsl_ir_jump_type type); + struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *basic_type, unsigned int array_size); struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2); +struct hlsl_ir_constant *hlsl_new_bool_constant(struct hlsl_ctx *ctx, bool b, const struct vkd3d_shader_location *loc); struct hlsl_buffer *hlsl_new_buffer(struct hlsl_ctx *ctx, enum hlsl_buffer_type type, const char *name, const struct hlsl_reg_reservation *reservation, struct vkd3d_shader_location loc); +struct hlsl_ir_node *hlsl_new_call(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *decl, + const struct vkd3d_shader_location *loc); struct hlsl_ir_expr *hlsl_new_cast(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_type *type, const struct vkd3d_shader_location *loc); +struct hlsl_ir_constant *hlsl_new_constant(struct hlsl_ctx *ctx, struct hlsl_type *type, + const struct vkd3d_shader_location *loc); struct hlsl_ir_expr *hlsl_new_copy(struct hlsl_ctx *ctx, struct hlsl_ir_node *node); -struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, struct hlsl_type *return_type, - struct list *parameters, const struct hlsl_semantic *semantic, struct vkd3d_shader_location 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); +struct hlsl_ir_constant *hlsl_new_float_constant(struct hlsl_ctx *ctx, + float f, const struct vkd3d_shader_location *loc); +struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, + struct hlsl_type *return_type, const struct hlsl_func_parameters *parameters, + const struct hlsl_semantic *semantic, const struct vkd3d_shader_location *loc); struct hlsl_ir_if *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *condition, struct vkd3d_shader_location loc); struct hlsl_ir_constant *hlsl_new_int_constant(struct hlsl_ctx *ctx, int n, - const struct vkd3d_shader_location loc); + const struct vkd3d_shader_location *loc); struct hlsl_ir_jump *hlsl_new_jump(struct hlsl_ctx *ctx, enum hlsl_ir_jump_type type, struct vkd3d_shader_location loc); -struct hlsl_ir_load *hlsl_new_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, struct hlsl_ir_node *offset, - struct hlsl_type *type, struct vkd3d_shader_location loc); -struct hlsl_ir_loop *hlsl_new_loop(struct hlsl_ctx *ctx, struct vkd3d_shader_location loc); -struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, struct hlsl_type *data_type, - enum hlsl_resource_load_type type, struct hlsl_ir_var *resource, struct hlsl_ir_node *resource_offset, - struct hlsl_ir_var *sampler, struct hlsl_ir_node *sampler_offset, struct hlsl_ir_node *coords, - struct hlsl_ir_node *texel_offset, const struct vkd3d_shader_location *loc); + +void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_var *var); + +struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, + struct vkd3d_shader_location loc); +struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, + struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc); +struct hlsl_ir_load *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_deref *deref, unsigned int comp, const struct vkd3d_shader_location *loc); + struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs); -struct hlsl_ir_store *hlsl_new_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, struct hlsl_ir_node *offset, - struct hlsl_ir_node *rhs, unsigned int writemask, struct vkd3d_shader_location loc); -struct hlsl_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const char *name, struct list *fields); +struct hlsl_ir_store *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hlsl_deref *lhs, + struct hlsl_ir_node *idx, struct hlsl_ir_node *rhs, unsigned int writemask, const struct vkd3d_shader_location *loc); +struct hlsl_ir_store *hlsl_new_store_component(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_deref *lhs, unsigned int comp, struct hlsl_ir_node *rhs); + +struct hlsl_ir_loop *hlsl_new_loop(struct hlsl_ctx *ctx, struct vkd3d_shader_location loc); +struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, + const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc); +struct hlsl_ir_resource_store *hlsl_new_resource_store(struct hlsl_ctx *ctx, const struct hlsl_deref *resource, + struct hlsl_ir_node *coords, struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc); +struct hlsl_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const char *name, + struct hlsl_struct_field *fields, size_t field_count); struct hlsl_ir_swizzle *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned int components, struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc); -struct hlsl_ir_var *hlsl_new_synthetic_var(struct hlsl_ctx *ctx, const char *name, struct hlsl_type *type, - const struct vkd3d_shader_location loc); -struct hlsl_type *hlsl_new_texture_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, struct hlsl_type *format); +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_type *hlsl_new_texture_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, struct hlsl_type *format, + unsigned int sample_count); +struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, struct hlsl_type *format); struct hlsl_ir_constant *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned int n, - const struct vkd3d_shader_location loc); + 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, struct vkd3d_shader_location loc); struct hlsl_ir_var *hlsl_new_var(struct hlsl_ctx *ctx, const char *name, struct hlsl_type *type, const struct vkd3d_shader_location loc, const struct hlsl_semantic *semantic, unsigned int modifiers, const struct hlsl_reg_reservation *reg_reservation); -struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, - const struct vkd3d_shader_location loc); void hlsl_error(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc, enum vkd3d_shader_error error, const char *fmt, ...) VKD3D_PRINTF_FUNC(4, 5); @@ -782,7 +1088,16 @@ bool hlsl_scope_add_type(struct hlsl_scope *scope, struct hlsl_type *type); struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, unsigned int default_majority, unsigned int modifiers); -unsigned int hlsl_type_component_count(struct hlsl_type *type); +unsigned int hlsl_type_component_count(const struct hlsl_type *type); +unsigned int hlsl_type_get_array_element_reg_size(const struct hlsl_type *type, enum hlsl_regset regset); +struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl_type *type, + unsigned int index); +bool hlsl_type_is_row_major(const struct hlsl_type *type); +unsigned int hlsl_type_minor_size(const struct hlsl_type *type); +unsigned int hlsl_type_major_size(const struct hlsl_type *type); +unsigned int hlsl_type_element_count(const struct hlsl_type *type); +bool hlsl_type_is_resource(const struct hlsl_type *type); +enum hlsl_regset hlsl_type_get_regset(const struct hlsl_type *type); unsigned int hlsl_type_get_sm4_offset(const struct hlsl_type *type, unsigned int offset); bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2); @@ -791,12 +1106,15 @@ unsigned int hlsl_combine_writemasks(unsigned int first, unsigned int second); unsigned int hlsl_map_swizzle(unsigned int swizzle, unsigned int writemask); unsigned int hlsl_swizzle_from_writemask(unsigned int writemask); +struct hlsl_type *hlsl_deref_get_type(struct hlsl_ctx *ctx, const struct hlsl_deref *deref); +bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, + unsigned int *start, unsigned int *count); bool hlsl_offset_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, unsigned int *offset); unsigned int hlsl_offset_from_deref_safe(struct hlsl_ctx *ctx, const struct hlsl_deref *deref); -struct hlsl_reg hlsl_reg_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, - const struct hlsl_type *type); +struct hlsl_reg hlsl_reg_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref); -bool hlsl_fold_constants(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context); +bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context); +bool hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context); 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); diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/hlsl.l b/dll/directx/wine/vkd3d/libs/vkd3d-shader/hlsl.l similarity index 95% rename from dll/directx/wine/d3d12/vkd3d/vkd3d-shader/hlsl.l rename to dll/directx/wine/vkd3d/libs/vkd3d-shader/hlsl.l index 267c8c3048383..adff1da04d828 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/hlsl.l +++ b/dll/directx/wine/vkd3d/libs/vkd3d-shader/hlsl.l @@ -102,6 +102,9 @@ RasterizerState {return KW_RASTERIZERSTATE; } RenderTargetView {return KW_RENDERTARGETVIEW; } return {return KW_RETURN; } register {return KW_REGISTER; } +RWTexture1D {return KW_RWTEXTURE1D; } +RWTexture2D {return KW_RWTEXTURE2D; } +RWTexture3D {return KW_RWTEXTURE3D; } sampler {return KW_SAMPLER; } sampler1D {return KW_SAMPLER1D; } sampler2D {return KW_SAMPLER2D; } @@ -178,7 +181,7 @@ row_major {return KW_ROW_MAJOR; } yylval->name = hlsl_strdup(ctx, yytext); 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)) + else if (hlsl_get_type(ctx->cur_scope, yytext, true, true)) return TYPE_IDENTIFIER; else return NEW_IDENTIFIER; @@ -197,15 +200,15 @@ row_major {return KW_ROW_MAJOR; } return C_FLOAT; } 0x[0-9a-fA-F]+ { - sscanf(yytext, "0x%x", &yylval->intval); + yylval->intval = vkd3d_parse_integer(yytext); return C_INTEGER; } 0[0-7]+ { - sscanf(yytext, "0%o", &yylval->intval); + yylval->intval = vkd3d_parse_integer(yytext); return C_INTEGER; } [0-9]+ { - yylval->intval = (atoi(yytext)); + yylval->intval = vkd3d_parse_integer(yytext); return C_INTEGER; } @@ -230,14 +233,14 @@ row_major {return KW_ROW_MAJOR; } struct hlsl_ctx *ctx = yyget_extra(yyscanner); TRACE("#pragma setting row_major mode.\n"); - ctx->matrix_majority = HLSL_ROW_MAJOR; + ctx->matrix_majority = HLSL_MODIFIER_ROW_MAJOR; BEGIN(pp_ignore); } pack_matrix{WS}*\({WS}*column_major{WS}*\) { struct hlsl_ctx *ctx = yyget_extra(yyscanner); TRACE("#pragma setting column_major mode.\n"); - ctx->matrix_majority = HLSL_COLUMN_MAJOR; + ctx->matrix_majority = HLSL_MODIFIER_COLUMN_MAJOR; BEGIN(pp_ignore); } {NEWLINE} { diff --git a/dll/directx/wine/vkd3d/libs/vkd3d-shader/hlsl.y b/dll/directx/wine/vkd3d/libs/vkd3d-shader/hlsl.y new file mode 100644 index 0000000000000..fd1eaf6ec9576 --- /dev/null +++ b/dll/directx/wine/vkd3d/libs/vkd3d-shader/hlsl.y @@ -0,0 +1,5730 @@ +/* + * HLSL parser + * + * Copyright 2008 Stefan Dösinger + * Copyright 2012 Matteo Bruni for CodeWeavers + * Copyright 2019-2020 Zebediah Figura for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +%code requires +{ + +#include "hlsl.h" +#include + +#define HLSL_YYLTYPE struct vkd3d_shader_location + +struct parse_fields +{ + struct hlsl_struct_field *fields; + size_t count, capacity; +}; + +struct parse_parameter +{ + struct hlsl_type *type; + const char *name; + struct hlsl_semantic semantic; + struct hlsl_reg_reservation reg_reservation; + unsigned int modifiers; +}; + +struct parse_colon_attribute +{ + struct hlsl_semantic semantic; + struct hlsl_reg_reservation reg_reservation; +}; + +struct parse_initializer +{ + struct hlsl_ir_node **args; + unsigned int args_count; + struct list *instrs; + bool braces; +}; + +struct parse_array_sizes +{ + uint32_t *sizes; /* innermost first */ + unsigned int count; +}; + +struct parse_variable_def +{ + struct list entry; + struct vkd3d_shader_location loc; + + char *name; + struct parse_array_sizes arrays; + struct hlsl_semantic semantic; + struct hlsl_reg_reservation reg_reservation; + struct parse_initializer initializer; +}; + +struct parse_function +{ + struct hlsl_ir_function_decl *decl; + struct hlsl_func_parameters parameters; + struct hlsl_semantic return_semantic; + bool first; +}; + +struct parse_if_body +{ + struct list *then_instrs; + struct list *else_instrs; +}; + +enum parse_assign_op +{ + ASSIGN_OP_ASSIGN, + ASSIGN_OP_ADD, + ASSIGN_OP_SUB, + ASSIGN_OP_MUL, + ASSIGN_OP_DIV, + ASSIGN_OP_MOD, + ASSIGN_OP_LSHIFT, + ASSIGN_OP_RSHIFT, + ASSIGN_OP_AND, + ASSIGN_OP_OR, + ASSIGN_OP_XOR, +}; + +struct parse_attribute_list +{ + unsigned int count; + const struct hlsl_attribute **attrs; +}; + +} + +%code provides +{ + +int yylex(HLSL_YYSTYPE *yylval_param, HLSL_YYLTYPE *yylloc_param, void *yyscanner); + +} + +%code +{ + +#define YYLLOC_DEFAULT(cur, rhs, n) (cur) = YYRHSLOC(rhs, !!n) + +static void yyerror(YYLTYPE *loc, void *scanner, struct hlsl_ctx *ctx, const char *s) +{ + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "%s", s); +} + +static struct hlsl_ir_node *node_from_list(struct list *list) +{ + return LIST_ENTRY(list_tail(list), struct hlsl_ir_node, entry); +} + +static struct list *make_empty_list(struct hlsl_ctx *ctx) +{ + struct list *list; + + if ((list = hlsl_alloc(ctx, sizeof(*list)))) + list_init(list); + return list; +} + +static void destroy_instr_list(struct list *list) +{ + hlsl_free_instr_list(list); + vkd3d_free(list); +} + +static bool hlsl_types_are_componentwise_compatible(struct hlsl_ctx *ctx, struct hlsl_type *src, + struct hlsl_type *dst) +{ + unsigned int k, count = hlsl_type_component_count(dst); + + if (count > hlsl_type_component_count(src)) + return false; + + for (k = 0; k < count; ++k) + { + struct hlsl_type *src_comp_type, *dst_comp_type; + + src_comp_type = hlsl_type_get_component_type(ctx, src, k); + dst_comp_type = hlsl_type_get_component_type(ctx, dst, k); + + if ((src_comp_type->type != HLSL_CLASS_SCALAR || dst_comp_type->type != HLSL_CLASS_SCALAR) + && !hlsl_types_are_equal(src_comp_type, dst_comp_type)) + return false; + } + return true; +} + +static bool hlsl_types_are_componentwise_equal(struct hlsl_ctx *ctx, struct hlsl_type *src, + struct hlsl_type *dst) +{ + unsigned int k, count = hlsl_type_component_count(src); + + if (count != hlsl_type_component_count(dst)) + return false; + + for (k = 0; k < count; ++k) + { + struct hlsl_type *src_comp_type, *dst_comp_type; + + src_comp_type = hlsl_type_get_component_type(ctx, src, k); + dst_comp_type = hlsl_type_get_component_type(ctx, dst, k); + + if (!hlsl_types_are_equal(src_comp_type, dst_comp_type)) + return false; + } + return true; +} + +static bool type_contains_only_numerics(struct hlsl_type *type) +{ + unsigned int i; + + if (type->type == HLSL_CLASS_ARRAY) + return type_contains_only_numerics(type->e.array.type); + if (type->type == HLSL_CLASS_STRUCT) + { + for (i = 0; i < type->e.record.field_count; ++i) + { + if (!type_contains_only_numerics(type->e.record.fields[i].type)) + return false; + } + return true; + } + return type->type <= HLSL_CLASS_LAST_NUMERIC; +} + +static bool explicit_compatible_data_types(struct hlsl_ctx *ctx, struct hlsl_type *src, struct hlsl_type *dst) +{ + if (src->type <= HLSL_CLASS_LAST_NUMERIC && src->dimx == 1 && src->dimy == 1 && type_contains_only_numerics(dst)) + return true; + + if (src->type == HLSL_CLASS_MATRIX && dst->type == HLSL_CLASS_MATRIX + && src->dimx >= dst->dimx && src->dimy >= dst->dimy) + return true; + + if ((src->type == HLSL_CLASS_MATRIX && src->dimx > 1 && src->dimy > 1) + && hlsl_type_component_count(src) != hlsl_type_component_count(dst)) + return false; + + if ((dst->type == HLSL_CLASS_MATRIX && dst->dimy > 1) + && hlsl_type_component_count(src) != hlsl_type_component_count(dst)) + return false; + + return hlsl_types_are_componentwise_compatible(ctx, src, dst); +} + +static bool implicit_compatible_data_types(struct hlsl_ctx *ctx, struct hlsl_type *src, struct hlsl_type *dst) +{ + if ((src->type <= HLSL_CLASS_LAST_NUMERIC) != (dst->type <= HLSL_CLASS_LAST_NUMERIC)) + return false; + + if (src->type <= HLSL_CLASS_LAST_NUMERIC) + { + /* Scalar vars can be converted to any other numeric data type */ + if (src->dimx == 1 && src->dimy == 1) + return true; + /* The other way around is true too */ + if (dst->dimx == 1 && dst->dimy == 1) + return true; + + if (src->type == HLSL_CLASS_MATRIX || dst->type == HLSL_CLASS_MATRIX) + { + if (src->type == HLSL_CLASS_MATRIX && dst->type == HLSL_CLASS_MATRIX) + return src->dimx >= dst->dimx && src->dimy >= dst->dimy; + + /* Matrix-vector conversion is apparently allowed if they have + * the same components count, or if the matrix is 1xN or Nx1 + * and we are reducing the component count */ + if (src->type == HLSL_CLASS_VECTOR || dst->type == HLSL_CLASS_VECTOR) + { + if (hlsl_type_component_count(src) == hlsl_type_component_count(dst)) + return true; + + if ((src->type == HLSL_CLASS_VECTOR || src->dimx == 1 || src->dimy == 1) && + (dst->type == HLSL_CLASS_VECTOR || dst->dimx == 1 || dst->dimy == 1)) + return hlsl_type_component_count(src) >= hlsl_type_component_count(dst); + } + + return false; + } + else + { + return src->dimx >= dst->dimx; + } + } + + return hlsl_types_are_componentwise_equal(ctx, src, dst); +} + +static struct hlsl_ir_load *add_load_component(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_instr, + unsigned int comp, const struct vkd3d_shader_location *loc); + +static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs, + struct hlsl_ir_node *node, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc) +{ + struct hlsl_type *src_type = node->data_type; + struct hlsl_ir_expr *cast; + + if (hlsl_types_are_equal(src_type, dst_type)) + return node; + + if (src_type->type > HLSL_CLASS_VECTOR || dst_type->type > HLSL_CLASS_VECTOR) + { + unsigned int src_comp_count = hlsl_type_component_count(src_type); + unsigned int dst_comp_count = hlsl_type_component_count(dst_type); + struct hlsl_deref var_deref; + bool broadcast, matrix_cast; + struct hlsl_ir_load *load; + struct hlsl_ir_var *var; + unsigned int dst_idx; + + broadcast = src_type->type <= HLSL_CLASS_LAST_NUMERIC && src_type->dimx == 1 && src_type->dimy == 1; + matrix_cast = !broadcast && dst_comp_count != src_comp_count + && src_type->type == HLSL_CLASS_MATRIX && dst_type->type == HLSL_CLASS_MATRIX; + assert(src_comp_count >= dst_comp_count || broadcast); + if (matrix_cast) + { + assert(dst_type->dimx <= src_type->dimx); + assert(dst_type->dimy <= src_type->dimy); + } + + if (!(var = hlsl_new_synthetic_var(ctx, "cast", dst_type, loc))) + return NULL; + hlsl_init_simple_deref_from_var(&var_deref, var); + + for (dst_idx = 0; dst_idx < dst_comp_count; ++dst_idx) + { + struct hlsl_type *dst_comp_type; + struct hlsl_ir_store *store; + struct hlsl_block block; + unsigned int src_idx; + + if (broadcast) + { + src_idx = 0; + } + else if (matrix_cast) + { + unsigned int x = dst_idx % dst_type->dimx, y = dst_idx / dst_type->dimx; + + src_idx = y * src_type->dimx + x; + } + else + { + src_idx = dst_idx; + } + + dst_comp_type = hlsl_type_get_component_type(ctx, dst_type, dst_idx); + + if (!(load = add_load_component(ctx, instrs, node, src_idx, loc))) + return NULL; + + if (!(cast = hlsl_new_cast(ctx, &load->node, dst_comp_type, loc))) + return NULL; + list_add_tail(instrs, &cast->node.entry); + + if (!(store = hlsl_new_store_component(ctx, &block, &var_deref, dst_idx, &cast->node))) + return NULL; + list_move_tail(instrs, &block.instrs); + } + + if (!(load = hlsl_new_var_load(ctx, var, *loc))) + return NULL; + list_add_tail(instrs, &load->node.entry); + + return &load->node; + } + else + { + if (!(cast = hlsl_new_cast(ctx, node, dst_type, loc))) + return NULL; + list_add_tail(instrs, &cast->node.entry); + return &cast->node; + } +} + +static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct list *instrs, + struct hlsl_ir_node *node, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc) +{ + struct hlsl_type *src_type = node->data_type; + + if (hlsl_types_are_equal(src_type, dst_type)) + return node; + + if (!implicit_compatible_data_types(ctx, src_type, dst_type)) + { + struct vkd3d_string_buffer *src_string, *dst_string; + + src_string = hlsl_type_to_string(ctx, src_type); + dst_string = hlsl_type_to_string(ctx, dst_type); + if (src_string && dst_string) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Can't implicitly convert from %s to %s.", src_string->buffer, dst_string->buffer); + hlsl_release_string_buffer(ctx, src_string); + hlsl_release_string_buffer(ctx, dst_string); + return NULL; + } + + if (dst_type->dimx * dst_type->dimy < src_type->dimx * src_type->dimy) + hlsl_warning(ctx, loc, VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION, "Implicit truncation of %s type.", + src_type->type == HLSL_CLASS_VECTOR ? "vector" : "matrix"); + + return add_cast(ctx, instrs, node, dst_type, loc); +} + +static DWORD add_modifiers(struct hlsl_ctx *ctx, DWORD modifiers, DWORD mod, const struct vkd3d_shader_location loc) +{ + if (modifiers & mod) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_modifiers_to_string(ctx, mod))) + hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Modifier '%s' was already specified.", string->buffer); + hlsl_release_string_buffer(ctx, string); + return modifiers; + } + return modifiers | mod; +} + +static bool append_conditional_break(struct hlsl_ctx *ctx, struct list *cond_list) +{ + struct hlsl_ir_node *condition, *not; + struct hlsl_ir_jump *jump; + struct hlsl_ir_if *iff; + + /* E.g. "for (i = 0; ; ++i)". */ + if (list_empty(cond_list)) + return true; + + condition = node_from_list(cond_list); + if (!(not = hlsl_new_unary_expr(ctx, HLSL_OP1_LOGIC_NOT, condition, condition->loc))) + return false; + list_add_tail(cond_list, ¬->entry); + + if (!(iff = hlsl_new_if(ctx, not, condition->loc))) + return false; + list_add_tail(cond_list, &iff->node.entry); + + if (!(jump = hlsl_new_jump(ctx, HLSL_IR_JUMP_BREAK, condition->loc))) + return false; + list_add_head(&iff->then_instrs.instrs, &jump->node.entry); + return true; +} + +enum loop_type +{ + LOOP_FOR, + LOOP_WHILE, + LOOP_DO_WHILE +}; + +static struct list *create_loop(struct hlsl_ctx *ctx, enum loop_type type, struct list *init, struct list *cond, + struct list *iter, struct list *body, struct vkd3d_shader_location loc) +{ + struct list *list = NULL; + struct hlsl_ir_loop *loop = NULL; + struct hlsl_ir_if *cond_jump = NULL; + + if (!(list = make_empty_list(ctx))) + goto oom; + + if (init) + list_move_head(list, init); + + if (!(loop = hlsl_new_loop(ctx, loc))) + goto oom; + list_add_tail(list, &loop->node.entry); + + if (!append_conditional_break(ctx, cond)) + goto oom; + + if (type != LOOP_DO_WHILE) + list_move_tail(&loop->body.instrs, cond); + + list_move_tail(&loop->body.instrs, body); + + if (iter) + list_move_tail(&loop->body.instrs, iter); + + if (type == LOOP_DO_WHILE) + list_move_tail(&loop->body.instrs, cond); + + vkd3d_free(init); + vkd3d_free(cond); + vkd3d_free(body); + return list; + +oom: + vkd3d_free(loop); + vkd3d_free(cond_jump); + vkd3d_free(list); + destroy_instr_list(init); + destroy_instr_list(cond); + destroy_instr_list(iter); + destroy_instr_list(body); + return NULL; +} + +static unsigned int initializer_size(const struct parse_initializer *initializer) +{ + unsigned int count = 0, i; + + for (i = 0; i < initializer->args_count; ++i) + { + count += hlsl_type_component_count(initializer->args[i]->data_type); + } + return count; +} + +static void free_parse_initializer(struct parse_initializer *initializer) +{ + destroy_instr_list(initializer->instrs); + vkd3d_free(initializer->args); +} + +static struct hlsl_ir_swizzle *get_swizzle(struct hlsl_ctx *ctx, struct hlsl_ir_node *value, const char *swizzle, + struct vkd3d_shader_location *loc) +{ + unsigned int len = strlen(swizzle), component = 0; + unsigned int i, set, swiz = 0; + bool valid; + + if (value->data_type->type == HLSL_CLASS_MATRIX) + { + /* Matrix swizzle */ + bool m_swizzle; + unsigned int inc, x, y; + + if (len < 3 || swizzle[0] != '_') + return NULL; + m_swizzle = swizzle[1] == 'm'; + inc = m_swizzle ? 4 : 3; + + if (len % inc || len > inc * 4) + return NULL; + + for (i = 0; i < len; i += inc) + { + if (swizzle[i] != '_') + return NULL; + if (m_swizzle) + { + if (swizzle[i + 1] != 'm') + return NULL; + y = swizzle[i + 2] - '0'; + x = swizzle[i + 3] - '0'; + } + else + { + y = swizzle[i + 1] - '1'; + x = swizzle[i + 2] - '1'; + } + + if (x >= value->data_type->dimx || y >= value->data_type->dimy) + return NULL; + swiz |= (y << 4 | x) << component * 8; + component++; + } + return hlsl_new_swizzle(ctx, swiz, component, value, loc); + } + + /* Vector swizzle */ + if (len > 4) + return NULL; + + for (set = 0; set < 2; ++set) + { + valid = true; + component = 0; + for (i = 0; i < len; ++i) + { + char c[2][4] = {{'x', 'y', 'z', 'w'}, {'r', 'g', 'b', 'a'}}; + unsigned int s = 0; + + for (s = 0; s < 4; ++s) + { + if (swizzle[i] == c[set][s]) + break; + } + if (s == 4) + { + valid = false; + break; + } + + if (s >= value->data_type->dimx) + return NULL; + swiz |= s << component * 2; + component++; + } + if (valid) + return hlsl_new_swizzle(ctx, swiz, component, value, loc); + } + + return NULL; +} + +static struct hlsl_ir_jump *add_return(struct hlsl_ctx *ctx, struct list *instrs, + struct hlsl_ir_node *return_value, struct vkd3d_shader_location loc) +{ + struct hlsl_type *return_type = ctx->cur_function->return_type; + struct hlsl_ir_jump *jump; + + if (ctx->cur_function->return_var) + { + if (return_value) + { + struct hlsl_ir_store *store; + + if (!(return_value = add_implicit_conversion(ctx, instrs, return_value, return_type, &loc))) + return NULL; + + if (!(store = hlsl_new_simple_store(ctx, ctx->cur_function->return_var, return_value))) + return NULL; + list_add_after(&return_value->entry, &store->node.entry); + } + else + { + hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RETURN, "Non-void functions must return a value."); + return NULL; + } + } + else + { + if (return_value) + hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RETURN, "Void functions cannot return a value."); + } + + if (!(jump = hlsl_new_jump(ctx, HLSL_IR_JUMP_RETURN, loc))) + return NULL; + list_add_tail(instrs, &jump->node.entry); + + return jump; +} + +static struct hlsl_ir_load *add_load_index(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_instr, + struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc) +{ + const struct hlsl_deref *src; + struct hlsl_ir_load *load; + + if (var_instr->type == HLSL_IR_LOAD) + { + src = &hlsl_ir_load(var_instr)->src; + } + else + { + struct hlsl_ir_store *store; + struct hlsl_ir_var *var; + + if (!(var = hlsl_new_synthetic_var(ctx, "deref", var_instr->data_type, &var_instr->loc))) + return NULL; + + if (!(store = hlsl_new_simple_store(ctx, var, var_instr))) + return NULL; + list_add_tail(instrs, &store->node.entry); + + src = &store->lhs; + } + + if (!(load = hlsl_new_load_index(ctx, src, idx, loc))) + return NULL; + list_add_tail(instrs, &load->node.entry); + + return load; +} + +static struct hlsl_ir_load *add_load_component(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_instr, + unsigned int comp, const struct vkd3d_shader_location *loc) +{ + const struct hlsl_deref *src; + struct hlsl_ir_load *load; + struct hlsl_block block; + + if (var_instr->type == HLSL_IR_LOAD) + { + src = &hlsl_ir_load(var_instr)->src; + } + else + { + struct hlsl_ir_store *store; + struct hlsl_ir_var *var; + + if (!(var = hlsl_new_synthetic_var(ctx, "deref", var_instr->data_type, &var_instr->loc))) + return NULL; + + if (!(store = hlsl_new_simple_store(ctx, var, var_instr))) + return NULL; + list_add_tail(instrs, &store->node.entry); + + src = &store->lhs; + } + + if (!(load = hlsl_new_load_component(ctx, &block, src, comp, loc))) + return NULL; + list_move_tail(instrs, &block.instrs); + + return load; +} + +static bool add_record_load(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *record, + unsigned int idx, const struct vkd3d_shader_location loc) +{ + struct hlsl_ir_constant *c; + + assert(idx < record->data_type->e.record.field_count); + + if (!(c = hlsl_new_uint_constant(ctx, idx, &loc))) + return false; + list_add_tail(instrs, &c->node.entry); + + return !!add_load_index(ctx, instrs, record, &c->node, &loc); +} + +static struct hlsl_ir_node *add_binary_arithmetic_expr(struct hlsl_ctx *ctx, struct list *instrs, + enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, + const struct vkd3d_shader_location *loc); + +static bool add_matrix_index(struct hlsl_ctx *ctx, struct list *instrs, + struct hlsl_ir_node *matrix, struct hlsl_ir_node *index, const struct vkd3d_shader_location *loc) +{ + struct hlsl_type *mat_type = matrix->data_type, *ret_type; + struct hlsl_deref var_deref; + struct hlsl_ir_load *load; + struct hlsl_ir_var *var; + unsigned int i; + + if (hlsl_type_is_row_major(mat_type)) + return add_load_index(ctx, instrs, matrix, index, loc); + + ret_type = hlsl_get_vector_type(ctx, mat_type->base_type, mat_type->dimx); + + if (!(var = hlsl_new_synthetic_var(ctx, "index", ret_type, loc))) + return false; + hlsl_init_simple_deref_from_var(&var_deref, var); + + for (i = 0; i < mat_type->dimx; ++i) + { + struct hlsl_ir_load *column, *value; + struct hlsl_ir_store *store; + struct hlsl_ir_constant *c; + struct hlsl_block block; + + if (!(c = hlsl_new_uint_constant(ctx, i, loc))) + return false; + list_add_tail(instrs, &c->node.entry); + + if (!(column = add_load_index(ctx, instrs, matrix, &c->node, loc))) + return false; + + if (!(value = add_load_index(ctx, instrs, &column->node, index, loc))) + return false; + + if (!(store = hlsl_new_store_component(ctx, &block, &var_deref, i, &value->node))) + return false; + list_move_tail(instrs, &block.instrs); + } + + if (!(load = hlsl_new_var_load(ctx, var, *loc))) + return false; + list_add_tail(instrs, &load->node.entry); + + return true; +} + +static struct hlsl_ir_node *add_zero_mipmap_level(struct hlsl_ctx *ctx, struct list *instrs, + struct hlsl_ir_node *index, unsigned int dim_count, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_load *coords_load; + struct hlsl_deref coords_deref; + struct hlsl_ir_constant *zero; + struct hlsl_ir_store *store; + struct hlsl_ir_var *coords; + + if (!(coords = hlsl_new_synthetic_var(ctx, "coords", + hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, dim_count + 1), loc))) + return NULL; + + hlsl_init_simple_deref_from_var(&coords_deref, coords); + if (!(store = hlsl_new_store_index(ctx, &coords_deref, NULL, index, (1u << dim_count) - 1, loc))) + return NULL; + list_add_tail(instrs, &store->node.entry); + + if (!(zero = hlsl_new_uint_constant(ctx, 0, loc))) + return NULL; + list_add_tail(instrs, &zero->node.entry); + + if (!(store = hlsl_new_store_index(ctx, &coords_deref, NULL, &zero->node, 1u << dim_count, loc))) + return NULL; + list_add_tail(instrs, &store->node.entry); + + if (!(coords_load = hlsl_new_var_load(ctx, coords, *loc))) + return NULL; + list_add_tail(instrs, &coords_load->node.entry); + + return &coords_load->node; +} + +static bool add_array_load(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *array, + struct hlsl_ir_node *index, const struct vkd3d_shader_location *loc) +{ + const struct hlsl_type *expr_type = array->data_type, *index_type = index->data_type; + struct hlsl_ir_expr *cast; + + if (expr_type->type == HLSL_CLASS_OBJECT + && (expr_type->base_type == HLSL_TYPE_TEXTURE || expr_type->base_type == HLSL_TYPE_UAV) + && expr_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC) + { + struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_LOAD}; + unsigned int dim_count = hlsl_sampler_dim_count(expr_type->sampler_dim); + /* Only HLSL_IR_LOAD can return an object. */ + struct hlsl_ir_load *object_load = hlsl_ir_load(array); + struct hlsl_ir_resource_load *resource_load; + + if (index_type->type > HLSL_CLASS_VECTOR || index_type->dimx != dim_count) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, expr_type))) + hlsl_error(ctx, &index->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Array index of type '%s' must be of type 'uint%u'.", string->buffer, dim_count); + hlsl_release_string_buffer(ctx, string); + return false; + } + + if (!(index = add_implicit_conversion(ctx, instrs, index, + hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, dim_count), &index->loc))) + return false; + + if (!(index = add_zero_mipmap_level(ctx, instrs, index, dim_count, loc))) + return false; + + load_params.format = expr_type->e.resource_format; + load_params.resource = object_load->src; + load_params.coords = index; + + if (!(resource_load = hlsl_new_resource_load(ctx, &load_params, loc))) + return false; + list_add_tail(instrs, &resource_load->node.entry); + return true; + } + + if (index_type->type != HLSL_CLASS_SCALAR) + { + hlsl_error(ctx, &index->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Array index is not scalar."); + return false; + } + + if (!(cast = hlsl_new_cast(ctx, index, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), &index->loc))) + return false; + list_add_tail(instrs, &cast->node.entry); + index = &cast->node; + + if (expr_type->type == HLSL_CLASS_MATRIX) + return add_matrix_index(ctx, instrs, array, index, loc); + + if (expr_type->type != HLSL_CLASS_ARRAY && expr_type->type != HLSL_CLASS_VECTOR) + { + if (expr_type->type == HLSL_CLASS_SCALAR) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_INDEX, "Scalar expressions cannot be array-indexed."); + else + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_INDEX, "Expression cannot be array-indexed."); + return false; + } + + if (!add_load_index(ctx, instrs, array, index, loc)) + return false; + + return true; +} + +static const struct hlsl_struct_field *get_struct_field(const struct hlsl_struct_field *fields, + size_t count, const char *name) +{ + size_t i; + + for (i = 0; i < count; ++i) + { + if (!strcmp(fields[i].name, name)) + return &fields[i]; + } + return NULL; +} + +static struct hlsl_type *apply_type_modifiers(struct hlsl_ctx *ctx, struct hlsl_type *type, + unsigned int *modifiers, bool force_majority, const struct vkd3d_shader_location *loc) +{ + unsigned int default_majority = 0; + struct hlsl_type *new_type; + + if (!(*modifiers & HLSL_MODIFIERS_MAJORITY_MASK) + && !(type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK) + && type->type == HLSL_CLASS_MATRIX) + { + if (!(default_majority = ctx->matrix_majority) && force_majority) + default_majority = HLSL_MODIFIER_COLUMN_MAJOR; + } + else if (type->type != HLSL_CLASS_MATRIX && (*modifiers & HLSL_MODIFIERS_MAJORITY_MASK)) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "'row_major' and 'column_major' modifiers are only allowed for matrices."); + } + + if (!default_majority && !(*modifiers & HLSL_TYPE_MODIFIERS_MASK)) + return type; + + if (!(new_type = hlsl_type_clone(ctx, type, default_majority, *modifiers & HLSL_TYPE_MODIFIERS_MASK))) + return NULL; + + *modifiers &= ~HLSL_TYPE_MODIFIERS_MASK; + + if ((new_type->modifiers & HLSL_MODIFIER_ROW_MAJOR) && (new_type->modifiers & HLSL_MODIFIER_COLUMN_MAJOR)) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "'row_major' and 'column_major' modifiers are mutually exclusive."); + + return new_type; +} + +static void free_parse_variable_def(struct parse_variable_def *v) +{ + free_parse_initializer(&v->initializer); + vkd3d_free(v->arrays.sizes); + vkd3d_free(v->name); + hlsl_cleanup_semantic(&v->semantic); + vkd3d_free(v); +} + +static bool shader_is_sm_5_1(const struct hlsl_ctx *ctx) +{ + return ctx->profile->major_version == 5 && ctx->profile->minor_version >= 1; +} + +static bool gen_struct_fields(struct hlsl_ctx *ctx, struct parse_fields *fields, + struct hlsl_type *type, unsigned int modifiers, struct list *defs) +{ + struct parse_variable_def *v, *v_next; + size_t i = 0; + + if (type->type == HLSL_CLASS_MATRIX) + assert(type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK); + + memset(fields, 0, sizeof(*fields)); + fields->count = list_count(defs); + if (!hlsl_array_reserve(ctx, (void **)&fields->fields, &fields->capacity, fields->count, sizeof(*fields->fields))) + return false; + + LIST_FOR_EACH_ENTRY_SAFE(v, v_next, defs, struct parse_variable_def, entry) + { + struct hlsl_struct_field *field = &fields->fields[i++]; + bool unbounded_res_array = false; + unsigned int k; + + field->type = type; + + if (shader_is_sm_5_1(ctx) && type->type == HLSL_CLASS_OBJECT) + { + for (k = 0; k < v->arrays.count; ++k) + unbounded_res_array |= (v->arrays.sizes[k] == HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT); + } + + if (unbounded_res_array) + { + if (v->arrays.count == 1) + { + hlsl_fixme(ctx, &v->loc, "Unbounded resource arrays as struct fields."); + free_parse_variable_def(v); + vkd3d_free(field); + continue; + } + else + { + hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Unbounded resource arrays cannot be multi-dimensional."); + } + } + else + { + for (k = 0; k < v->arrays.count; ++k) + { + if (v->arrays.sizes[k] == HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT) + { + hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Implicit size arrays not allowed in struct fields."); + } + + field->type = hlsl_new_array_type(ctx, field->type, v->arrays.sizes[k]); + } + } + vkd3d_free(v->arrays.sizes); + field->loc = v->loc; + field->name = v->name; + field->semantic = v->semantic; + field->storage_modifiers = modifiers; + if (v->initializer.args_count) + { + hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Illegal initializer on a struct field."); + free_parse_initializer(&v->initializer); + } + vkd3d_free(v); + } + vkd3d_free(defs); + return true; +} + +static bool add_typedef(struct hlsl_ctx *ctx, struct hlsl_type *const orig_type, struct list *list) +{ + struct parse_variable_def *v, *v_next; + struct hlsl_type *type; + unsigned int i; + bool ret; + + LIST_FOR_EACH_ENTRY_SAFE(v, v_next, list, struct parse_variable_def, entry) + { + if (!v->arrays.count) + { + if (!(type = hlsl_type_clone(ctx, orig_type, 0, 0))) + { + free_parse_variable_def(v); + continue; + } + } + else + { + unsigned int var_modifiers = 0; + + if (!(type = apply_type_modifiers(ctx, orig_type, &var_modifiers, true, &v->loc))) + { + free_parse_variable_def(v); + continue; + } + } + + ret = true; + for (i = 0; i < v->arrays.count; ++i) + { + if (v->arrays.sizes[i] == HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT) + { + hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Implicit size arrays not allowed in typedefs."); + } + + if (!(type = hlsl_new_array_type(ctx, type, v->arrays.sizes[i]))) + { + free_parse_variable_def(v); + ret = false; + break; + } + } + if (!ret) + continue; + vkd3d_free(v->arrays.sizes); + + vkd3d_free((void *)type->name); + type->name = v->name; + + ret = hlsl_scope_add_type(ctx->cur_scope, type); + if (!ret) + hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, + "Type '%s' is already defined.", v->name); + free_parse_initializer(&v->initializer); + vkd3d_free(v); + } + vkd3d_free(list); + return true; +} + +static bool add_func_parameter(struct hlsl_ctx *ctx, struct hlsl_func_parameters *parameters, + struct parse_parameter *param, const struct vkd3d_shader_location loc) +{ + struct hlsl_ir_var *var; + + if (param->type->type == HLSL_CLASS_MATRIX) + assert(param->type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK); + + if ((param->modifiers & HLSL_STORAGE_OUT) && (param->modifiers & HLSL_STORAGE_UNIFORM)) + hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Parameter '%s' is declared as both \"out\" and \"uniform\".", param->name); + + if (!(var = hlsl_new_var(ctx, param->name, param->type, loc, ¶m->semantic, param->modifiers, ¶m->reg_reservation))) + return false; + var->is_param = 1; + + if (!hlsl_add_var(ctx, var, false)) + { + hlsl_free_var(var); + return false; + } + + if (!hlsl_array_reserve(ctx, (void **)¶meters->vars, ¶meters->capacity, + parameters->count + 1, sizeof(*parameters->vars))) + return false; + parameters->vars[parameters->count++] = var; + return true; +} + +static struct hlsl_reg_reservation parse_reg_reservation(const char *reg_string) +{ + struct hlsl_reg_reservation reservation = {0}; + + if (!sscanf(reg_string + 1, "%u", &reservation.index)) + { + FIXME("Unsupported register reservation syntax.\n"); + return reservation; + } + reservation.type = reg_string[0]; + return reservation; +} + +static struct hlsl_ir_function_decl *get_func_decl(struct rb_tree *funcs, + const char *name, const struct hlsl_func_parameters *parameters) +{ + struct hlsl_ir_function *func; + struct rb_entry *entry; + + if ((entry = rb_get(funcs, name))) + { + func = RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry); + + if ((entry = rb_get(&func->overloads, parameters))) + return RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry); + } + return NULL; +} + +static struct list *make_list(struct hlsl_ctx *ctx, struct hlsl_ir_node *node) +{ + struct list *list; + + if (!(list = make_empty_list(ctx))) + { + hlsl_free_instr(node); + return NULL; + } + list_add_tail(list, &node->entry); + return list; +} + +static unsigned int evaluate_static_expression(struct hlsl_ir_node *node) +{ + if (node->data_type->type != HLSL_CLASS_SCALAR) + return 0; + + switch (node->type) + { + case HLSL_IR_CONSTANT: + { + struct hlsl_ir_constant *constant = hlsl_ir_constant(node); + const union hlsl_constant_value *value = &constant->value[0]; + + switch (constant->node.data_type->base_type) + { + case HLSL_TYPE_UINT: + return value->u; + case HLSL_TYPE_INT: + return value->i; + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + return value->f; + case HLSL_TYPE_DOUBLE: + return value->d; + case HLSL_TYPE_BOOL: + return !!value->u; + default: + vkd3d_unreachable(); + } + } + + case HLSL_IR_EXPR: + case HLSL_IR_LOAD: + case HLSL_IR_RESOURCE_LOAD: + case HLSL_IR_SWIZZLE: + FIXME("Unhandled type %s.\n", hlsl_node_type_to_string(node->type)); + return 0; + + case HLSL_IR_CALL: + case HLSL_IR_IF: + case HLSL_IR_JUMP: + case HLSL_IR_LOOP: + case HLSL_IR_RESOURCE_STORE: + case HLSL_IR_STORE: + vkd3d_unreachable(); + } + + vkd3d_unreachable(); +} + +static bool expr_compatible_data_types(struct hlsl_type *t1, struct hlsl_type *t2) +{ + if (t1->base_type > HLSL_TYPE_LAST_SCALAR || t2->base_type > HLSL_TYPE_LAST_SCALAR) + return false; + + /* Scalar vars can be converted to pretty much everything */ + if ((t1->dimx == 1 && t1->dimy == 1) || (t2->dimx == 1 && t2->dimy == 1)) + return true; + + if (t1->type == HLSL_CLASS_VECTOR && t2->type == HLSL_CLASS_VECTOR) + return true; + + if (t1->type == HLSL_CLASS_MATRIX || t2->type == HLSL_CLASS_MATRIX) + { + /* Matrix-vector conversion is apparently allowed if either they have the same components + count or the matrix is nx1 or 1xn */ + if (t1->type == HLSL_CLASS_VECTOR || t2->type == HLSL_CLASS_VECTOR) + { + if (hlsl_type_component_count(t1) == hlsl_type_component_count(t2)) + return true; + + return (t1->type == HLSL_CLASS_MATRIX && (t1->dimx == 1 || t1->dimy == 1)) + || (t2->type == HLSL_CLASS_MATRIX && (t2->dimx == 1 || t2->dimy == 1)); + } + + /* Both matrices */ + if ((t1->dimx >= t2->dimx && t1->dimy >= t2->dimy) + || (t1->dimx <= t2->dimx && t1->dimy <= t2->dimy)) + return true; + } + + return false; +} + +static enum hlsl_base_type expr_common_base_type(enum hlsl_base_type t1, enum hlsl_base_type t2) +{ + if (t1 > HLSL_TYPE_LAST_SCALAR || t2 > HLSL_TYPE_LAST_SCALAR) { + FIXME("Unexpected base type.\n"); + return HLSL_TYPE_FLOAT; + } + if (t1 == t2) + return t1 == HLSL_TYPE_BOOL ? HLSL_TYPE_INT : t1; + if (t1 == HLSL_TYPE_DOUBLE || t2 == HLSL_TYPE_DOUBLE) + return HLSL_TYPE_DOUBLE; + if (t1 == HLSL_TYPE_FLOAT || t2 == HLSL_TYPE_FLOAT + || t1 == HLSL_TYPE_HALF || t2 == HLSL_TYPE_HALF) + return HLSL_TYPE_FLOAT; + if (t1 == HLSL_TYPE_UINT || t2 == HLSL_TYPE_UINT) + return HLSL_TYPE_UINT; + return HLSL_TYPE_INT; +} + +static bool expr_common_shape(struct hlsl_ctx *ctx, struct hlsl_type *t1, struct hlsl_type *t2, + const struct vkd3d_shader_location *loc, enum hlsl_type_class *type, unsigned int *dimx, unsigned int *dimy) +{ + if (t1->type > HLSL_CLASS_LAST_NUMERIC) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, t1))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Expression of type \"%s\" cannot be used in a numeric expression.", string->buffer); + hlsl_release_string_buffer(ctx, string); + return false; + } + + if (t2->type > HLSL_CLASS_LAST_NUMERIC) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, t2))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Expression of type \"%s\" cannot be used in a numeric expression.", string->buffer); + hlsl_release_string_buffer(ctx, string); + return false; + } + + if (!expr_compatible_data_types(t1, t2)) + { + struct vkd3d_string_buffer *t1_string = hlsl_type_to_string(ctx, t1); + struct vkd3d_string_buffer *t2_string = hlsl_type_to_string(ctx, t2); + + if (t1_string && t2_string) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Expression data types \"%s\" and \"%s\" are incompatible.", + t1_string->buffer, t2_string->buffer); + hlsl_release_string_buffer(ctx, t1_string); + hlsl_release_string_buffer(ctx, t2_string); + return false; + } + + if (t1->dimx == 1 && t1->dimy == 1) + { + *type = t2->type; + *dimx = t2->dimx; + *dimy = t2->dimy; + } + else if (t2->dimx == 1 && t2->dimy == 1) + { + *type = t1->type; + *dimx = t1->dimx; + *dimy = t1->dimy; + } + else if (t1->type == HLSL_CLASS_MATRIX && t2->type == HLSL_CLASS_MATRIX) + { + *type = HLSL_CLASS_MATRIX; + *dimx = min(t1->dimx, t2->dimx); + *dimy = min(t1->dimy, t2->dimy); + } + else + { + if (t1->dimx * t1->dimy <= t2->dimx * t2->dimy) + { + *type = t1->type; + *dimx = t1->dimx; + *dimy = t1->dimy; + } + else + { + *type = t2->type; + *dimx = t2->dimx; + *dimy = t2->dimy; + } + } + + return true; +} + +static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, + enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], + struct hlsl_type *type, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *expr; + unsigned int i; + + if (type->type == HLSL_CLASS_MATRIX) + { + struct hlsl_type *vector_type; + struct hlsl_deref var_deref; + struct hlsl_ir_load *load; + struct hlsl_ir_var *var; + + vector_type = hlsl_get_vector_type(ctx, type->base_type, hlsl_type_minor_size(type)); + + if (!(var = hlsl_new_synthetic_var(ctx, "split_op", type, loc))) + return NULL; + hlsl_init_simple_deref_from_var(&var_deref, var); + + for (i = 0; i < hlsl_type_major_size(type); ++i) + { + struct hlsl_ir_node *value, *vector_operands[HLSL_MAX_OPERANDS] = { NULL }; + struct hlsl_ir_store *store; + struct hlsl_ir_constant *c; + unsigned int j; + + if (!(c = hlsl_new_uint_constant(ctx, i, loc))) + return NULL; + list_add_tail(instrs, &c->node.entry); + + for (j = 0; j < HLSL_MAX_OPERANDS; j++) + { + if (operands[j]) + { + struct hlsl_ir_load *load; + + if (!(load = add_load_index(ctx, instrs, operands[j], &c->node, loc))) + return NULL; + vector_operands[j] = &load->node; + } + } + + if (!(value = add_expr(ctx, instrs, op, vector_operands, vector_type, loc))) + return NULL; + + if (!(store = hlsl_new_store_index(ctx, &var_deref, &c->node, value, 0, loc))) + return NULL; + list_add_tail(instrs, &store->node.entry); + } + + if (!(load = hlsl_new_var_load(ctx, var, *loc))) + return NULL; + list_add_tail(instrs, &load->node.entry); + + return &load->node; + } + + if (!(expr = hlsl_new_expr(ctx, op, operands, type, loc))) + return NULL; + list_add_tail(instrs, &expr->entry); + + return expr; +} + +static void check_integer_type(struct hlsl_ctx *ctx, const struct hlsl_ir_node *instr) +{ + const struct hlsl_type *type = instr->data_type; + struct vkd3d_string_buffer *string; + + switch (type->base_type) + { + case HLSL_TYPE_BOOL: + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + break; + + default: + if ((string = hlsl_type_to_string(ctx, type))) + hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Expression type '%s' is not integer.", string->buffer); + hlsl_release_string_buffer(ctx, string); + break; + } +} + +static struct hlsl_ir_node *add_unary_arithmetic_expr(struct hlsl_ctx *ctx, struct list *instrs, + enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {arg}; + + return add_expr(ctx, instrs, op, args, arg->data_type, loc); +} + +static struct hlsl_ir_node *add_unary_bitwise_expr(struct hlsl_ctx *ctx, struct list *instrs, + enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc) +{ + check_integer_type(ctx, arg); + + return add_unary_arithmetic_expr(ctx, instrs, op, arg, loc); +} + +static struct hlsl_ir_node *add_unary_logical_expr(struct hlsl_ctx *ctx, struct list *instrs, + enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0}; + struct hlsl_type *bool_type; + + bool_type = hlsl_get_numeric_type(ctx, arg->data_type->type, HLSL_TYPE_BOOL, + arg->data_type->dimx, arg->data_type->dimy); + + if (!(args[0] = add_implicit_conversion(ctx, instrs, arg, bool_type, loc))) + return NULL; + + return add_expr(ctx, instrs, op, args, bool_type, loc); +} + +static struct hlsl_ir_node *add_binary_arithmetic_expr(struct hlsl_ctx *ctx, struct list *instrs, + enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, + const struct vkd3d_shader_location *loc) +{ + struct hlsl_type *common_type; + enum hlsl_base_type base = expr_common_base_type(arg1->data_type->base_type, arg2->data_type->base_type); + enum hlsl_type_class type; + unsigned int dimx, dimy; + struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0}; + + if (!expr_common_shape(ctx, arg1->data_type, arg2->data_type, loc, &type, &dimx, &dimy)) + return NULL; + + common_type = hlsl_get_numeric_type(ctx, type, base, dimx, dimy); + + if (!(args[0] = add_implicit_conversion(ctx, instrs, arg1, common_type, loc))) + return NULL; + + if (!(args[1] = add_implicit_conversion(ctx, instrs, arg2, common_type, loc))) + return NULL; + + return add_expr(ctx, instrs, op, args, common_type, loc); +} + +static struct list *add_binary_arithmetic_expr_merge(struct hlsl_ctx *ctx, struct list *list1, struct list *list2, + enum hlsl_ir_expr_op op, struct vkd3d_shader_location loc) +{ + struct hlsl_ir_node *arg1 = node_from_list(list1), *arg2 = node_from_list(list2); + + list_move_tail(list1, list2); + vkd3d_free(list2); + add_binary_arithmetic_expr(ctx, list1, op, arg1, arg2, &loc); + return list1; +} + +static struct hlsl_ir_node *add_binary_bitwise_expr(struct hlsl_ctx *ctx, struct list *instrs, + enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, + const struct vkd3d_shader_location *loc) +{ + check_integer_type(ctx, arg1); + check_integer_type(ctx, arg2); + + return add_binary_arithmetic_expr(ctx, instrs, op, arg1, arg2, loc); +} + +static struct list *add_binary_bitwise_expr_merge(struct hlsl_ctx *ctx, struct list *list1, struct list *list2, + enum hlsl_ir_expr_op op, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *arg1 = node_from_list(list1), *arg2 = node_from_list(list2); + + list_move_tail(list1, list2); + vkd3d_free(list2); + add_binary_bitwise_expr(ctx, list1, op, arg1, arg2, loc); + + return list1; +} + +static struct hlsl_ir_node *add_binary_comparison_expr(struct hlsl_ctx *ctx, struct list *instrs, + enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, + const struct vkd3d_shader_location *loc) +{ + struct hlsl_type *common_type, *return_type; + enum hlsl_base_type base = expr_common_base_type(arg1->data_type->base_type, arg2->data_type->base_type); + enum hlsl_type_class type; + unsigned int dimx, dimy; + struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0}; + + if (!expr_common_shape(ctx, arg1->data_type, arg2->data_type, loc, &type, &dimx, &dimy)) + return NULL; + + common_type = hlsl_get_numeric_type(ctx, type, base, dimx, dimy); + return_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_BOOL, dimx, dimy); + + if (!(args[0] = add_implicit_conversion(ctx, instrs, arg1, common_type, loc))) + return NULL; + + if (!(args[1] = add_implicit_conversion(ctx, instrs, arg2, common_type, loc))) + return NULL; + + return add_expr(ctx, instrs, op, args, return_type, loc); +} + +static struct list *add_binary_comparison_expr_merge(struct hlsl_ctx *ctx, struct list *list1, struct list *list2, + enum hlsl_ir_expr_op op, const struct vkd3d_shader_location loc) +{ + struct hlsl_ir_node *arg1 = node_from_list(list1), *arg2 = node_from_list(list2); + + list_move_tail(list1, list2); + vkd3d_free(list2); + add_binary_comparison_expr(ctx, list1, op, arg1, arg2, &loc); + return list1; +} + +static struct hlsl_ir_node *add_binary_logical_expr(struct hlsl_ctx *ctx, struct list *instrs, + enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, + const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0}; + struct hlsl_type *common_type; + enum hlsl_type_class type; + unsigned int dimx, dimy; + + if (!expr_common_shape(ctx, arg1->data_type, arg2->data_type, loc, &type, &dimx, &dimy)) + return NULL; + + common_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_BOOL, dimx, dimy); + + if (!(args[0] = add_implicit_conversion(ctx, instrs, arg1, common_type, loc))) + return NULL; + + if (!(args[1] = add_implicit_conversion(ctx, instrs, arg2, common_type, loc))) + return NULL; + + return add_expr(ctx, instrs, op, args, common_type, loc); +} + +static struct list *add_binary_logical_expr_merge(struct hlsl_ctx *ctx, struct list *list1, struct list *list2, + enum hlsl_ir_expr_op op, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *arg1 = node_from_list(list1), *arg2 = node_from_list(list2); + + list_move_tail(list1, list2); + vkd3d_free(list2); + add_binary_logical_expr(ctx, list1, op, arg1, arg2, loc); + + return list1; +} + +static struct hlsl_ir_node *add_binary_shift_expr(struct hlsl_ctx *ctx, struct list *instrs, + enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, + const struct vkd3d_shader_location *loc) +{ + enum hlsl_base_type base = arg1->data_type->base_type; + struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0}; + struct hlsl_type *return_type, *integer_type; + enum hlsl_type_class type; + unsigned int dimx, dimy; + + check_integer_type(ctx, arg1); + check_integer_type(ctx, arg2); + + if (base == HLSL_TYPE_BOOL) + base = HLSL_TYPE_INT; + + if (!expr_common_shape(ctx, arg1->data_type, arg2->data_type, loc, &type, &dimx, &dimy)) + return NULL; + + return_type = hlsl_get_numeric_type(ctx, type, base, dimx, dimy); + integer_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_INT, dimx, dimy); + + if (!(args[0] = add_implicit_conversion(ctx, instrs, arg1, return_type, loc))) + return NULL; + + if (!(args[1] = add_implicit_conversion(ctx, instrs, arg2, integer_type, loc))) + return NULL; + + return add_expr(ctx, instrs, op, args, return_type, loc); +} + +static struct list *add_binary_shift_expr_merge(struct hlsl_ctx *ctx, struct list *list1, struct list *list2, + enum hlsl_ir_expr_op op, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *arg1 = node_from_list(list1), *arg2 = node_from_list(list2); + + list_move_tail(list1, list2); + vkd3d_free(list2); + add_binary_shift_expr(ctx, list1, op, arg1, arg2, loc); + + return list1; +} + +static struct hlsl_ir_node *add_binary_dot_expr(struct hlsl_ctx *ctx, struct list *instrs, + struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, const struct vkd3d_shader_location *loc) +{ + enum hlsl_base_type base = expr_common_base_type(arg1->data_type->base_type, arg2->data_type->base_type); + struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0}; + struct hlsl_type *common_type, *ret_type; + enum hlsl_ir_expr_op op; + unsigned dim; + + if (arg1->data_type->type == HLSL_CLASS_MATRIX) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, arg1->data_type))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Invalid type %s.\n", string->buffer); + hlsl_release_string_buffer(ctx, string); + return NULL; + } + + if (arg2->data_type->type == HLSL_CLASS_MATRIX) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, arg2->data_type))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Invalid type %s.\n", string->buffer); + hlsl_release_string_buffer(ctx, string); + return NULL; + } + + if (arg1->data_type->type == HLSL_CLASS_SCALAR) + dim = arg2->data_type->dimx; + else if (arg2->data_type->type == HLSL_CLASS_SCALAR) + dim = arg1->data_type->dimx; + else + dim = min(arg1->data_type->dimx, arg2->data_type->dimx); + + if (dim == 1) + op = HLSL_OP2_MUL; + else + op = HLSL_OP2_DOT; + + common_type = hlsl_get_vector_type(ctx, base, dim); + ret_type = hlsl_get_scalar_type(ctx, base); + + if (!(args[0] = add_implicit_conversion(ctx, instrs, arg1, common_type, loc))) + return NULL; + + if (!(args[1] = add_implicit_conversion(ctx, instrs, arg2, common_type, loc))) + return NULL; + + return add_expr(ctx, instrs, op, args, ret_type, loc); +} + +static enum hlsl_ir_expr_op op_from_assignment(enum parse_assign_op op) +{ + static const enum hlsl_ir_expr_op ops[] = + { + 0, + HLSL_OP2_ADD, + 0, + HLSL_OP2_MUL, + HLSL_OP2_DIV, + HLSL_OP2_MOD, + HLSL_OP2_LSHIFT, + HLSL_OP2_RSHIFT, + HLSL_OP2_BIT_AND, + HLSL_OP2_BIT_OR, + HLSL_OP2_BIT_XOR, + }; + + return ops[op]; +} + +static bool invert_swizzle(unsigned int *swizzle, unsigned int *writemask, unsigned int *ret_width) +{ + unsigned int i, j, bit = 0, inverted = 0, width, new_writemask = 0, new_swizzle = 0; + + /* Apply the writemask to the swizzle to get a new writemask and swizzle. */ + for (i = 0; i < 4; ++i) + { + if (*writemask & (1 << i)) + { + unsigned int s = (*swizzle >> (i * 2)) & 3; + new_swizzle |= s << (bit++ * 2); + if (new_writemask & (1 << s)) + return false; + new_writemask |= 1 << s; + } + } + width = bit; + + /* Invert the swizzle. */ + bit = 0; + for (i = 0; i < 4; ++i) + { + for (j = 0; j < width; ++j) + { + unsigned int s = (new_swizzle >> (j * 2)) & 3; + if (s == i) + inverted |= j << (bit++ * 2); + } + } + + *swizzle = inverted; + *writemask = new_writemask; + *ret_width = width; + return true; +} + +static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *lhs, + enum parse_assign_op assign_op, struct hlsl_ir_node *rhs) +{ + struct hlsl_type *lhs_type = lhs->data_type; + struct hlsl_ir_expr *copy; + unsigned int writemask = 0; + + if (assign_op == ASSIGN_OP_SUB) + { + if (!(rhs = add_unary_arithmetic_expr(ctx, instrs, HLSL_OP1_NEG, rhs, &rhs->loc))) + return NULL; + assign_op = ASSIGN_OP_ADD; + } + if (assign_op != ASSIGN_OP_ASSIGN) + { + enum hlsl_ir_expr_op op = op_from_assignment(assign_op); + + assert(op); + if (!(rhs = add_binary_arithmetic_expr(ctx, instrs, op, lhs, rhs, &rhs->loc))) + return NULL; + } + + if (lhs_type->type <= HLSL_CLASS_LAST_NUMERIC) + writemask = (1 << lhs_type->dimx) - 1; + + if (!(rhs = add_implicit_conversion(ctx, instrs, rhs, lhs_type, &rhs->loc))) + return NULL; + + while (lhs->type != HLSL_IR_LOAD && lhs->type != HLSL_IR_RESOURCE_LOAD) + { + if (lhs->type == HLSL_IR_EXPR && hlsl_ir_expr(lhs)->op == HLSL_OP1_CAST) + { + hlsl_fixme(ctx, &lhs->loc, "Cast on the LHS."); + return NULL; + } + else if (lhs->type == HLSL_IR_SWIZZLE) + { + struct hlsl_ir_swizzle *swizzle = hlsl_ir_swizzle(lhs), *new_swizzle; + unsigned int width, s = swizzle->swizzle; + + if (lhs->data_type->type == HLSL_CLASS_MATRIX) + hlsl_fixme(ctx, &lhs->loc, "Matrix assignment with a writemask."); + + if (!invert_swizzle(&s, &writemask, &width)) + { + hlsl_error(ctx, &lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_WRITEMASK, "Invalid writemask."); + return NULL; + } + + if (!(new_swizzle = hlsl_new_swizzle(ctx, s, width, rhs, &swizzle->node.loc))) + { + return NULL; + } + list_add_tail(instrs, &new_swizzle->node.entry); + + lhs = swizzle->val.node; + rhs = &new_swizzle->node; + } + else + { + hlsl_error(ctx, &lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_LVALUE, "Invalid lvalue."); + return NULL; + } + } + + if (lhs->type == HLSL_IR_RESOURCE_LOAD) + { + struct hlsl_ir_resource_load *load = hlsl_ir_resource_load(lhs); + struct hlsl_ir_resource_store *store; + struct hlsl_type *resource_type; + struct hlsl_ir_swizzle *coords; + unsigned int dim_count; + + /* Such an lvalue was produced by an index expression. */ + assert(load->load_type == HLSL_RESOURCE_LOAD); + resource_type = hlsl_deref_get_type(ctx, &load->resource); + assert(resource_type->type == HLSL_CLASS_OBJECT); + assert(resource_type->base_type == HLSL_TYPE_TEXTURE || resource_type->base_type == HLSL_TYPE_UAV); + + if (resource_type->base_type != HLSL_TYPE_UAV) + hlsl_error(ctx, &lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Read-only resources cannot be stored to."); + + dim_count = hlsl_sampler_dim_count(resource_type->sampler_dim); + + if (writemask != ((1u << resource_type->e.resource_format->dimx) - 1)) + hlsl_error(ctx, &lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_WRITEMASK, + "Resource store expressions must write to all components."); + + /* Remove the (implicit) mipmap level from the load expression. */ + assert(load->coords.node->data_type->type == HLSL_CLASS_VECTOR); + assert(load->coords.node->data_type->base_type == HLSL_TYPE_UINT); + assert(load->coords.node->data_type->dimx == dim_count + 1); + if (!(coords = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, Y, Z, W), dim_count, load->coords.node, &lhs->loc))) + return NULL; + list_add_tail(instrs, &coords->node.entry); + + if (!(store = hlsl_new_resource_store(ctx, &load->resource, &coords->node, rhs, &lhs->loc))) + return NULL; + list_add_tail(instrs, &store->node.entry); + } + else + { + struct hlsl_ir_store *store; + + if (!(store = hlsl_new_store_index(ctx, &hlsl_ir_load(lhs)->src, NULL, rhs, writemask, &rhs->loc))) + return NULL; + list_add_tail(instrs, &store->node.entry); + } + + /* Don't use the instruction itself as a source, as this makes structure + * splitting easier. Instead copy it here. Since we retrieve sources from + * the last instruction in the list, we do need to copy. */ + if (!(copy = hlsl_new_copy(ctx, rhs))) + return NULL; + list_add_tail(instrs, ©->node.entry); + return ©->node; +} + +static bool add_increment(struct hlsl_ctx *ctx, struct list *instrs, bool decrement, bool post, + struct vkd3d_shader_location loc) +{ + struct hlsl_ir_node *lhs = node_from_list(instrs); + struct hlsl_ir_constant *one; + + if (lhs->data_type->modifiers & HLSL_MODIFIER_CONST) + hlsl_error(ctx, &loc, VKD3D_SHADER_ERROR_HLSL_MODIFIES_CONST, + "Argument to %s%screment operator is const.", post ? "post" : "pre", decrement ? "de" : "in"); + + if (!(one = hlsl_new_int_constant(ctx, 1, &loc))) + return false; + list_add_tail(instrs, &one->node.entry); + + if (!add_assignment(ctx, instrs, lhs, decrement ? ASSIGN_OP_SUB : ASSIGN_OP_ADD, &one->node)) + return false; + + if (post) + { + struct hlsl_ir_expr *copy; + + if (!(copy = hlsl_new_copy(ctx, lhs))) + return false; + list_add_tail(instrs, ©->node.entry); + + /* Post increment/decrement expressions are considered const. */ + if (!(copy->node.data_type = hlsl_type_clone(ctx, copy->node.data_type, 0, HLSL_MODIFIER_CONST))) + return false; + } + + return true; +} + +static void initialize_var_components(struct hlsl_ctx *ctx, struct list *instrs, + struct hlsl_ir_var *dst, unsigned int *store_index, struct hlsl_ir_node *src) +{ + unsigned int src_comp_count = hlsl_type_component_count(src->data_type); + struct hlsl_deref dst_deref; + unsigned int k; + + hlsl_init_simple_deref_from_var(&dst_deref, dst); + + for (k = 0; k < src_comp_count; ++k) + { + struct hlsl_type *dst_comp_type; + struct hlsl_ir_store *store; + struct hlsl_ir_load *load; + struct hlsl_ir_node *conv; + struct hlsl_block block; + + if (!(load = add_load_component(ctx, instrs, src, k, &src->loc))) + return; + + dst_comp_type = hlsl_type_get_component_type(ctx, dst->data_type, *store_index); + + if (!(conv = add_implicit_conversion(ctx, instrs, &load->node, dst_comp_type, &src->loc))) + return; + + if (!(store = hlsl_new_store_component(ctx, &block, &dst_deref, *store_index, conv))) + return; + list_move_tail(instrs, &block.instrs); + + ++*store_index; + } +} + +static bool type_has_object_components(struct hlsl_type *type, bool must_be_in_struct) +{ + if (type->type == HLSL_CLASS_OBJECT) + return !must_be_in_struct; + if (type->type == HLSL_CLASS_ARRAY) + return type_has_object_components(type->e.array.type, must_be_in_struct); + + if (type->type == HLSL_CLASS_STRUCT) + { + unsigned int i; + + for (i = 0; i < type->e.record.field_count; ++i) + { + if (type_has_object_components(type->e.record.fields[i].type, false)) + return true; + } + } + return false; +} + +static bool type_has_numeric_components(struct hlsl_type *type) +{ + if (type->type <= HLSL_CLASS_LAST_NUMERIC) + return true; + if (type->type == HLSL_CLASS_ARRAY) + return type_has_numeric_components(type->e.array.type); + + if (type->type == HLSL_CLASS_STRUCT) + { + unsigned int i; + + for (i = 0; i < type->e.record.field_count; ++i) + { + if (type_has_numeric_components(type->e.record.fields[i].type)) + return true; + } + } + return false; +} + +static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_type, + unsigned int modifiers, const struct vkd3d_shader_location *modifiers_loc, struct list *var_list) +{ + struct parse_variable_def *v, *v_next; + struct hlsl_ir_function_decl *func; + unsigned int invalid_modifiers; + struct list *statements_list; + struct hlsl_ir_var *var; + struct hlsl_type *type; + bool local = true; + + if (basic_type->type == HLSL_CLASS_MATRIX) + assert(basic_type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK); + + if (!(statements_list = make_empty_list(ctx))) + { + LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry) + free_parse_variable_def(v); + vkd3d_free(var_list); + return NULL; + } + + if (!var_list) + return statements_list; + + invalid_modifiers = modifiers & (HLSL_STORAGE_IN | HLSL_STORAGE_OUT); + if (invalid_modifiers) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_modifiers_to_string(ctx, invalid_modifiers))) + hlsl_error(ctx, modifiers_loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Modifiers '%s' are not allowed on non-parameter variables.", string->buffer); + hlsl_release_string_buffer(ctx, string); + } + + LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry) + { + bool unbounded_res_array = false; + unsigned int i; + + type = basic_type; + + if (shader_is_sm_5_1(ctx) && type->type == HLSL_CLASS_OBJECT) + { + for (i = 0; i < v->arrays.count; ++i) + unbounded_res_array |= (v->arrays.sizes[i] == HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT); + } + + if (unbounded_res_array) + { + if (v->arrays.count == 1) + { + hlsl_fixme(ctx, &v->loc, "Unbounded resource arrays."); + free_parse_variable_def(v); + continue; + } + else + { + hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Unbounded resource arrays cannot be multi-dimensional."); + } + } + else + { + for (i = 0; i < v->arrays.count; ++i) + { + if (v->arrays.sizes[i] == HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT) + { + unsigned int size = initializer_size(&v->initializer); + unsigned int elem_components = hlsl_type_component_count(type); + + if (i < v->arrays.count - 1) + { + hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Only innermost array size can be implicit."); + free_parse_initializer(&v->initializer); + v->initializer.args_count = 0; + } + else if (elem_components == 0) + { + hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Cannot declare an implicit size array of a size 0 type."); + free_parse_initializer(&v->initializer); + v->initializer.args_count = 0; + } + else if (size == 0) + { + hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Implicit size arrays need to be initialized."); + free_parse_initializer(&v->initializer); + v->initializer.args_count = 0; + + } + else if (size % elem_components != 0) + { + hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Cannot initialize implicit size array with %u components, expected a multiple of %u.", + size, elem_components); + free_parse_initializer(&v->initializer); + v->initializer.args_count = 0; + } + else + { + v->arrays.sizes[i] = size / elem_components; + } + } + type = hlsl_new_array_type(ctx, type, v->arrays.sizes[i]); + } + } + vkd3d_free(v->arrays.sizes); + + if (!(var = hlsl_new_var(ctx, v->name, type, v->loc, &v->semantic, modifiers, &v->reg_reservation))) + { + free_parse_variable_def(v); + continue; + } + + var->buffer = ctx->cur_buffer; + + if (ctx->cur_scope == ctx->globals) + { + local = false; + + if ((modifiers & HLSL_STORAGE_UNIFORM) && (modifiers & HLSL_STORAGE_STATIC)) + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Variable '%s' is declared as both \"uniform\" and \"static\".", var->name); + + /* Mark it as uniform. We need to do this here since synthetic + * variables also get put in the global scope, but shouldn't be + * considered uniforms, and we have no way of telling otherwise. */ + if (!(modifiers & HLSL_STORAGE_STATIC)) + var->storage_modifiers |= HLSL_STORAGE_UNIFORM; + + if (ctx->profile->major_version < 5 && (var->storage_modifiers & HLSL_STORAGE_UNIFORM) && + type_has_object_components(var->data_type, true)) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Target profile doesn't support objects as struct members in uniform variables.\n"); + } + + if ((func = hlsl_get_func_decl(ctx, var->name))) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, + "'%s' is already defined as a function.", var->name); + hlsl_note(ctx, &func->loc, VKD3D_SHADER_LOG_ERROR, + "'%s' was previously defined here.", var->name); + } + } + else + { + static const unsigned int invalid = HLSL_STORAGE_EXTERN | HLSL_STORAGE_SHARED + | HLSL_STORAGE_GROUPSHARED | HLSL_STORAGE_UNIFORM; + + if (modifiers & invalid) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_modifiers_to_string(ctx, modifiers & invalid))) + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Modifiers '%s' are not allowed on local variables.", string->buffer); + hlsl_release_string_buffer(ctx, string); + } + if (var->semantic.name) + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, + "Semantics are not allowed on local variables."); + } + + if ((var->storage_modifiers & HLSL_STORAGE_STATIC) && type_has_numeric_components(var->data_type) + && type_has_object_components(var->data_type, false)) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Static variables cannot have both numeric and resource components."); + } + + if ((type->modifiers & HLSL_MODIFIER_CONST) && !v->initializer.args_count + && !(modifiers & (HLSL_STORAGE_STATIC | HLSL_STORAGE_UNIFORM))) + { + hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_INITIALIZER, + "Const variable \"%s\" is missing an initializer.", var->name); + hlsl_free_var(var); + free_parse_initializer(&v->initializer); + vkd3d_free(v); + continue; + } + + if (!hlsl_add_var(ctx, var, local)) + { + struct hlsl_ir_var *old = hlsl_get_var(ctx->cur_scope, var->name); + + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, + "Variable \"%s\" was already declared in this scope.", var->name); + hlsl_note(ctx, &old->loc, VKD3D_SHADER_LOG_ERROR, "\"%s\" was previously declared here.", old->name); + hlsl_free_var(var); + free_parse_initializer(&v->initializer); + vkd3d_free(v); + continue; + } + + if (v->initializer.args_count) + { + if (v->initializer.braces) + { + unsigned int size = initializer_size(&v->initializer); + unsigned int store_index = 0; + unsigned int k; + + if (hlsl_type_component_count(type) != size) + { + hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Expected %u components in initializer, but got %u.", + hlsl_type_component_count(type), size); + free_parse_initializer(&v->initializer); + vkd3d_free(v); + continue; + } + + for (k = 0; k < v->initializer.args_count; ++k) + { + initialize_var_components(ctx, v->initializer.instrs, var, + &store_index, v->initializer.args[k]); + } + } + else + { + struct hlsl_ir_load *load = hlsl_new_var_load(ctx, var, var->loc); + + assert(v->initializer.args_count == 1); + list_add_tail(v->initializer.instrs, &load->node.entry); + add_assignment(ctx, v->initializer.instrs, &load->node, ASSIGN_OP_ASSIGN, v->initializer.args[0]); + } + + if (modifiers & HLSL_STORAGE_STATIC) + list_move_tail(&ctx->static_initializers, v->initializer.instrs); + else + list_move_tail(statements_list, v->initializer.instrs); + vkd3d_free(v->initializer.args); + vkd3d_free(v->initializer.instrs); + } + else if (var->storage_modifiers & HLSL_STORAGE_STATIC) + { + struct hlsl_ir_constant *zero; + struct hlsl_ir_store *store; + struct hlsl_ir_node *cast; + + /* Initialize statics to zero by default. */ + + if (type_has_object_components(var->data_type, false)) + { + vkd3d_free(v); + continue; + } + + if (!(zero = hlsl_new_uint_constant(ctx, 0, &var->loc))) + { + vkd3d_free(v); + continue; + } + list_add_tail(&ctx->static_initializers, &zero->node.entry); + + if (!(cast = add_cast(ctx, &ctx->static_initializers, &zero->node, var->data_type, &var->loc))) + { + vkd3d_free(v); + continue; + } + + if (!(store = hlsl_new_simple_store(ctx, var, cast))) + { + vkd3d_free(v); + continue; + } + list_add_tail(&ctx->static_initializers, &store->node.entry); + } + vkd3d_free(v); + } + vkd3d_free(var_list); + return statements_list; +} + +struct find_function_call_args +{ + struct hlsl_ctx *ctx; + const struct parse_initializer *params; + struct hlsl_ir_function_decl *decl; + unsigned int compatible_overloads_count; +}; + +static void find_function_call_exact(struct rb_entry *entry, void *context) +{ + struct hlsl_ir_function_decl *decl = RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry); + struct find_function_call_args *args = context; + unsigned int i; + + if (decl->parameters.count != args->params->args_count) + return; + + for (i = 0; i < decl->parameters.count; ++i) + { + if (!hlsl_types_are_equal(decl->parameters.vars[i]->data_type, args->params->args[i]->data_type)) + return; + } + args->decl = decl; +} + +static void find_function_call_compatible(struct rb_entry *entry, void *context) +{ + struct hlsl_ir_function_decl *decl = RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry); + struct find_function_call_args *args = context; + unsigned int i; + + if (decl->parameters.count != args->params->args_count) + return; + + for (i = 0; i < decl->parameters.count; ++i) + { + if (!implicit_compatible_data_types(args->ctx, args->params->args[i]->data_type, + decl->parameters.vars[i]->data_type)) + return; + } + + args->compatible_overloads_count++; + args->decl = decl; +} + +static struct hlsl_ir_function_decl *find_function_call(struct hlsl_ctx *ctx, + const char *name, const struct parse_initializer *params, + const struct vkd3d_shader_location *loc) +{ + struct find_function_call_args args = {.ctx = ctx, .params = params}; + struct hlsl_ir_function *func; + struct rb_entry *entry; + + if (!(entry = rb_get(&ctx->functions, name))) + return NULL; + func = RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry); + + rb_for_each_entry(&func->overloads, find_function_call_exact, &args); + if (!args.decl) + { + rb_for_each_entry(&func->overloads, find_function_call_compatible, &args); + if (args.compatible_overloads_count > 1) + { + hlsl_fixme(ctx, loc, "Prioritize between multiple compatible function overloads."); + } + } + return args.decl; +} + +static struct hlsl_ir_node *intrinsic_float_convert_arg(struct hlsl_ctx *ctx, + const struct parse_initializer *params, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc) +{ + struct hlsl_type *type = arg->data_type; + + if (type->base_type == HLSL_TYPE_FLOAT || type->base_type == HLSL_TYPE_HALF) + return arg; + + type = hlsl_get_numeric_type(ctx, type->type, HLSL_TYPE_FLOAT, type->dimx, type->dimy); + return add_implicit_conversion(ctx, params->instrs, arg, type, loc); +} + +static bool convert_args(struct hlsl_ctx *ctx, const struct parse_initializer *params, + struct hlsl_type *type, const struct vkd3d_shader_location *loc) +{ + unsigned int i; + + for (i = 0; i < params->args_count; ++i) + { + struct hlsl_ir_node *new_arg; + + if (!(new_arg = add_implicit_conversion(ctx, params->instrs, params->args[i], type, loc))) + return false; + params->args[i] = new_arg; + } + + return true; +} + +static struct hlsl_type *elementwise_intrinsic_get_common_type(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + enum hlsl_base_type base = params->args[0]->data_type->base_type; + bool vectors = false, matrices = false; + unsigned int dimx = 4, dimy = 4; + struct hlsl_type *common_type; + unsigned int i; + + for (i = 0; i < params->args_count; ++i) + { + struct hlsl_type *arg_type = params->args[i]->data_type; + + base = expr_common_base_type(base, arg_type->base_type); + + if (arg_type->type == HLSL_CLASS_VECTOR) + { + vectors = true; + dimx = min(dimx, arg_type->dimx); + } + else if (arg_type->type == HLSL_CLASS_MATRIX) + { + matrices = true; + dimx = min(dimx, arg_type->dimx); + dimy = min(dimy, arg_type->dimy); + } + } + + if (matrices && vectors) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Cannot use both matrices and vectors in an elementwise intrinsic."); + return NULL; + } + else if (matrices) + { + common_type = hlsl_get_matrix_type(ctx, base, dimx, dimy); + } + else if (vectors) + { + common_type = hlsl_get_vector_type(ctx, base, dimx); + } + else + { + common_type = hlsl_get_scalar_type(ctx, base); + } + + return common_type; +} + +static bool elementwise_intrinsic_convert_args(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_type *common_type; + + if (!(common_type = elementwise_intrinsic_get_common_type(ctx, params, loc))) + return false; + + return convert_args(ctx, params, common_type, loc); +} + +static bool elementwise_intrinsic_float_convert_args(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_type *type; + + if (!(type = elementwise_intrinsic_get_common_type(ctx, params, loc))) + return false; + + type = hlsl_get_numeric_type(ctx, type->type, HLSL_TYPE_FLOAT, type->dimx, type->dimy); + + return convert_args(ctx, params, type, loc); +} + +static bool intrinsic_abs(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_ABS, params->args[0], loc); +} + +static bool intrinsic_all(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *arg = params->args[0], *mul; + struct hlsl_ir_constant *one, *zero; + struct hlsl_ir_load *load; + unsigned int i, count; + + if (!(one = hlsl_new_float_constant(ctx, 1.0f, loc))) + return false; + list_add_tail(params->instrs, &one->node.entry); + + if (!(zero = hlsl_new_float_constant(ctx, 0.0f, loc))) + return false; + list_add_tail(params->instrs, &zero->node.entry); + + mul = &one->node; + + count = hlsl_type_component_count(arg->data_type); + for (i = 0; i < count; ++i) + { + if (!(load = add_load_component(ctx, params->instrs, arg, i, loc))) + return false; + + if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, &load->node, mul, loc))) + return false; + } + + return !!add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_NEQUAL, mul, &zero->node, loc); +} + +/* Find the type corresponding to the given source type, with the same + * dimensions but a different base type. */ +static struct hlsl_type *convert_numeric_type(const struct hlsl_ctx *ctx, + const struct hlsl_type *type, enum hlsl_base_type base_type) +{ + return hlsl_get_numeric_type(ctx, type->type, base_type, type->dimx, type->dimy); +} + +static bool intrinsic_asuint(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; + struct hlsl_type *data_type; + + if (params->args_count != 1 && params->args_count != 3) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Wrong number of arguments to function 'asuint': expected 1 or 3, but got %u.", params->args_count); + return false; + } + + if (params->args_count == 3) + { + hlsl_fixme(ctx, loc, "Double-to-integer conversion."); + return false; + } + + data_type = params->args[0]->data_type; + if (data_type->base_type == HLSL_TYPE_BOOL || data_type->base_type == HLSL_TYPE_DOUBLE) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, data_type))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Wrong type for argument 0 of asuint(): expected 'int', 'uint', 'float', or 'half', but got '%s'.", + string->buffer); + hlsl_release_string_buffer(ctx, string); + } + data_type = convert_numeric_type(ctx, data_type, HLSL_TYPE_UINT); + + operands[0] = params->args[0]; + return add_expr(ctx, params->instrs, HLSL_OP1_REINTERPRET, operands, data_type, loc); +} + +static bool intrinsic_clamp(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *max; + + if (!elementwise_intrinsic_convert_args(ctx, params, loc)) + return false; + + if (!(max = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MAX, params->args[0], params->args[1], loc))) + return false; + + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MIN, max, params->args[2], loc); +} + +static bool intrinsic_cos(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *arg; + + if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) + return false; + + return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_COS, arg, loc); +} + +static bool intrinsic_cross(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_swizzle *arg1_swzl1, *arg1_swzl2, *arg2_swzl1, *arg2_swzl2; + struct hlsl_ir_node *arg1 = params->args[0], *arg2 = params->args[1]; + struct hlsl_ir_node *arg1_cast, *arg2_cast, *mul1_neg, *mul1, *mul2; + struct hlsl_type *cast_type; + enum hlsl_base_type base; + + if (arg1->data_type->base_type == HLSL_TYPE_HALF && arg2->data_type->base_type == HLSL_TYPE_HALF) + base = HLSL_TYPE_HALF; + else + base = HLSL_TYPE_FLOAT; + + cast_type = hlsl_get_vector_type(ctx, base, 3); + + if (!(arg1_cast = add_implicit_conversion(ctx, params->instrs, arg1, cast_type, loc))) + return false; + + if (!(arg2_cast = add_implicit_conversion(ctx, params->instrs, arg2, cast_type, loc))) + return false; + + if (!(arg1_swzl1 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Z, X, Y, Z), 3, arg1_cast, loc))) + return false; + list_add_tail(params->instrs, &arg1_swzl1->node.entry); + + if (!(arg2_swzl1 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Y, Z, X, Y), 3, arg2_cast, loc))) + return false; + list_add_tail(params->instrs, &arg2_swzl1->node.entry); + + if (!(mul1 = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, + &arg1_swzl1->node, &arg2_swzl1->node, loc))) + return false; + + if (!(mul1_neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, mul1, *loc))) + return false; + list_add_tail(params->instrs, &mul1_neg->entry); + + if (!(arg1_swzl2 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Y, Z, X, Y), 3, arg1_cast, loc))) + return false; + list_add_tail(params->instrs, &arg1_swzl2->node.entry); + + if (!(arg2_swzl2 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Z, X, Y, Z), 3, arg2_cast, loc))) + return false; + list_add_tail(params->instrs, &arg2_swzl2->node.entry); + + if (!(mul2 = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, + &arg1_swzl2->node, &arg2_swzl2->node, loc))) + return false; + + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, mul2, mul1_neg, loc); +} + +static bool intrinsic_distance(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *arg1, *arg2, *neg, *add, *dot; + + if (!(arg1 = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) + return false; + + if (!(arg2 = intrinsic_float_convert_arg(ctx, params, params->args[1], loc))) + return false; + + if (!(neg = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_NEG, arg2, loc))) + return false; + + if (!(add = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, arg1, neg, loc))) + return false; + + if (!(dot = add_binary_dot_expr(ctx, params->instrs, add, add, loc))) + return false; + + return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_SQRT, dot, loc); +} + +static bool intrinsic_dot(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + return !!add_binary_dot_expr(ctx, params->instrs, params->args[0], params->args[1], loc); +} + +static bool intrinsic_exp(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_constant *coeff; + struct hlsl_ir_node *arg, *mul; + + if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) + return false; + + /* 1/ln(2) */ + if (!(coeff = hlsl_new_float_constant(ctx, 1.442695f, loc))) + return false; + list_add_tail(params->instrs, &coeff->node.entry); + + if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, &coeff->node, params->args[0], loc))) + return false; + + return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_EXP2, mul, loc); +} + +static bool intrinsic_exp2(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *arg; + + if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) + return false; + + return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_EXP2, arg, loc); +} + +static bool intrinsic_floor(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *arg; + + if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) + return false; + + return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_FLOOR, arg, loc); +} + +static bool intrinsic_frac(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *arg; + + if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) + return false; + + return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_FRACT, arg, loc); +} + +static bool intrinsic_ldexp(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *arg; + + if (!elementwise_intrinsic_float_convert_args(ctx, params, loc)) + return false; + + if (!(arg = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_EXP2, params->args[1], loc))) + return false; + + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, params->args[0], arg, loc); +} + +static bool intrinsic_length(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_type *type = params->args[0]->data_type; + struct hlsl_ir_node *arg, *dot; + + if (type->type == HLSL_CLASS_MATRIX) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, type))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Invalid type %s.", string->buffer); + hlsl_release_string_buffer(ctx, string); + } + + if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) + return false; + + if (!(dot = add_binary_dot_expr(ctx, params->instrs, arg, arg, loc))) + return false; + + return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_SQRT, dot, loc); +} + +static bool intrinsic_lerp(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *neg, *add, *mul; + + if (!elementwise_intrinsic_float_convert_args(ctx, params, loc)) + return false; + + if (!(neg = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_NEG, params->args[0], loc))) + return false; + + if (!(add = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, params->args[1], neg, loc))) + return false; + + if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, params->args[2], add, loc))) + return false; + + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, params->args[0], mul, loc); +} + +static struct hlsl_ir_node * add_pow_expr(struct hlsl_ctx *ctx, + struct list *instrs, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, + const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *log, *mul; + + if (!(log = add_unary_arithmetic_expr(ctx, instrs, HLSL_OP1_LOG2, arg1, loc))) + return NULL; + + if (!(mul = add_binary_arithmetic_expr(ctx, instrs, HLSL_OP2_MUL, arg2, log, loc))) + return NULL; + + return add_unary_arithmetic_expr(ctx, instrs, HLSL_OP1_EXP2, mul, loc); +} + +static bool intrinsic_lit(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *n_l_neg, *n_h_neg, *specular_or, *specular_pow; + struct hlsl_ir_constant *init, *zero; + struct hlsl_ir_node *n_l, *n_h, *m; + struct hlsl_ir_node *diffuse; + struct hlsl_ir_store *store; + struct hlsl_deref var_deref; + struct hlsl_type *ret_type; + struct hlsl_ir_load *load; + struct hlsl_ir_var *var; + struct hlsl_block block; + + if (params->args[0]->data_type->type != HLSL_CLASS_SCALAR + || params->args[1]->data_type->type != HLSL_CLASS_SCALAR + || params->args[2]->data_type->type != HLSL_CLASS_SCALAR) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Invalid argument type."); + return false; + } + + if (!(n_l = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) + return false; + + if (!(n_h = intrinsic_float_convert_arg(ctx, params, params->args[1], loc))) + return false; + + if (!(m = intrinsic_float_convert_arg(ctx, params, params->args[2], loc))) + return false; + + ret_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4); + + if (!(var = hlsl_new_synthetic_var(ctx, "lit", ret_type, loc))) + return false; + hlsl_init_simple_deref_from_var(&var_deref, var); + + if (!(init = hlsl_new_constant(ctx, ret_type, loc))) + return false; + init->value[0].f = 1.0f; + init->value[1].f = 0.0f; + init->value[2].f = 0.0f; + init->value[3].f = 1.0f; + list_add_tail(params->instrs, &init->node.entry); + + if (!(store = hlsl_new_simple_store(ctx, var, &init->node))) + return false; + list_add_tail(params->instrs, &store->node.entry); + + if (!(zero = hlsl_new_float_constant(ctx, 0.0f, loc))) + return false; + list_add_tail(params->instrs, &zero->node.entry); + + /* Diffuse component. */ + if (!(diffuse = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MAX, n_l, &zero->node, loc))) + return false; + + if (!(store = hlsl_new_store_component(ctx, &block, &var_deref, 1, diffuse))) + return false; + list_move_tail(params->instrs, &block.instrs); + + /* Specular component. */ + if (!(n_h_neg = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, + n_h, &zero->node, loc))) + return false; + + if (!(n_l_neg = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, + n_l, &zero->node, loc))) + return false; + + if (!(specular_or = add_binary_logical_expr(ctx, params->instrs, HLSL_OP2_LOGIC_OR, n_l_neg, n_h_neg, loc))) + return false; + + if (!(specular_pow = add_pow_expr(ctx, params->instrs, n_h, m, loc))) + return false; + + if (!(load = hlsl_add_conditional(ctx, params->instrs, specular_or, &zero->node, specular_pow))) + return false; + + if (!(store = hlsl_new_store_component(ctx, &block, &var_deref, 2, &load->node))) + return false; + list_move_tail(params->instrs, &block.instrs); + + if (!(load = hlsl_new_var_load(ctx, var, *loc))) + return false; + list_add_tail(params->instrs, &load->node.entry); + + return true; +} + +static bool intrinsic_max(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + if (!elementwise_intrinsic_convert_args(ctx, params, loc)) + return false; + + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MAX, params->args[0], params->args[1], loc); +} + +static bool intrinsic_min(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + if (!elementwise_intrinsic_convert_args(ctx, params, loc)) + return false; + + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MIN, params->args[0], params->args[1], loc); +} + +static bool intrinsic_mul(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *arg1 = params->args[0], *arg2 = params->args[1], *cast1, *cast2; + enum hlsl_base_type base = expr_common_base_type(arg1->data_type->base_type, arg2->data_type->base_type); + struct hlsl_type *cast_type1 = arg1->data_type, *cast_type2 = arg2->data_type, *matrix_type, *ret_type; + unsigned int i, j, k, vect_count = 0; + struct hlsl_deref var_deref; + struct hlsl_ir_load *load; + struct hlsl_ir_var *var; + + if (arg1->data_type->type == HLSL_CLASS_SCALAR || arg2->data_type->type == HLSL_CLASS_SCALAR) + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg1, arg2, loc); + + if (arg1->data_type->type == HLSL_CLASS_VECTOR) + { + vect_count++; + cast_type1 = hlsl_get_matrix_type(ctx, base, arg1->data_type->dimx, 1); + } + if (arg2->data_type->type == HLSL_CLASS_VECTOR) + { + vect_count++; + cast_type2 = hlsl_get_matrix_type(ctx, base, 1, arg2->data_type->dimx); + } + + matrix_type = hlsl_get_matrix_type(ctx, base, cast_type2->dimx, cast_type1->dimy); + + if (vect_count == 0) + { + ret_type = matrix_type; + } + else if (vect_count == 1) + { + assert(matrix_type->dimx == 1 || matrix_type->dimy == 1); + ret_type = hlsl_get_vector_type(ctx, base, matrix_type->dimx * matrix_type->dimy); + } + else + { + assert(matrix_type->dimx == 1 && matrix_type->dimy == 1); + ret_type = hlsl_get_scalar_type(ctx, base); + } + + if (!(cast1 = add_implicit_conversion(ctx, params->instrs, arg1, cast_type1, loc))) + return false; + + if (!(cast2 = add_implicit_conversion(ctx, params->instrs, arg2, cast_type2, loc))) + return false; + + if (!(var = hlsl_new_synthetic_var(ctx, "mul", matrix_type, loc))) + return false; + hlsl_init_simple_deref_from_var(&var_deref, var); + + for (i = 0; i < matrix_type->dimx; ++i) + { + for (j = 0; j < matrix_type->dimy; ++j) + { + struct hlsl_ir_node *instr = NULL; + struct hlsl_ir_store *store; + struct hlsl_block block; + + for (k = 0; k < cast_type1->dimx && k < cast_type2->dimy; ++k) + { + struct hlsl_ir_load *value1, *value2; + struct hlsl_ir_node *mul; + + if (!(value1 = add_load_component(ctx, params->instrs, cast1, j * cast1->data_type->dimx + k, loc))) + return false; + + if (!(value2 = add_load_component(ctx, params->instrs, cast2, k * cast2->data_type->dimx + i, loc))) + return false; + + if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, &value1->node, &value2->node, loc))) + return false; + + if (instr) + { + if (!(instr = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, instr, mul, loc))) + return false; + } + else + { + instr = mul; + } + } + + if (!(store = hlsl_new_store_component(ctx, &block, &var_deref, j * matrix_type->dimx + i, instr))) + return false; + list_move_tail(params->instrs, &block.instrs); + } + } + + if (!(load = hlsl_new_var_load(ctx, var, *loc))) + return false; + list_add_tail(params->instrs, &load->node.entry); + + return !!add_implicit_conversion(ctx, params->instrs, &load->node, ret_type, loc); +} + +static bool intrinsic_normalize(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_type *type = params->args[0]->data_type; + struct hlsl_ir_node *dot, *rsq, *arg; + + if (type->type == HLSL_CLASS_MATRIX) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, type))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Invalid type %s.", string->buffer); + hlsl_release_string_buffer(ctx, string); + } + + if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) + return false; + + if (!(dot = add_binary_dot_expr(ctx, params->instrs, arg, arg, loc))) + return false; + + if (!(rsq = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_RSQ, dot, loc))) + return false; + + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, rsq, arg, loc); +} + +static bool intrinsic_pow(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + if (!elementwise_intrinsic_float_convert_args(ctx, params, loc)) + return false; + + return !!add_pow_expr(ctx, params->instrs, params->args[0], params->args[1], loc); +} + +static bool intrinsic_reflect(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *i = params->args[0], *n = params->args[1]; + struct hlsl_ir_node *dot, *mul_n, *two_dot, *neg; + + if (!(dot = add_binary_dot_expr(ctx, params->instrs, i, n, loc))) + return false; + + if (!(two_dot = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, dot, dot, loc))) + return false; + + if (!(mul_n = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, n, two_dot, loc))) + return false; + + if (!(neg = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_NEG, mul_n, loc))) + return false; + + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, i, neg, loc); +} + +static bool intrinsic_round(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *arg; + + if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) + return false; + + return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_ROUND, arg, loc); +} + +static bool intrinsic_rsqrt(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *arg; + + if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) + return false; + + return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_RSQ, arg, loc); +} + +static bool intrinsic_saturate(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *arg; + + if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) + return false; + + return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_SAT, arg, loc); +} + +static bool intrinsic_sin(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *arg; + + if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) + return false; + + return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_SIN, arg, loc); +} + +/* smoothstep(a, b, x) = p^2 (3 - 2p), where p = saturate((x - a)/(b - a)) */ +static bool intrinsic_smoothstep(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *min_arg, *max_arg, *x_arg, *p, *p_num, *p_denom, *res; + struct hlsl_ir_constant *one, *minus_two, *three; + + if (!elementwise_intrinsic_float_convert_args(ctx, params, loc)) + return false; + + min_arg = params->args[0]; + max_arg = params->args[1]; + x_arg = params->args[2]; + + if (!(min_arg = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_NEG, min_arg, loc))) + return false; + + if (!(p_num = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, x_arg, min_arg, loc))) + return false; + + if (!(p_denom = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, max_arg, min_arg, loc))) + return false; + + if (!(one = hlsl_new_float_constant(ctx, 1.0, loc))) + return false; + list_add_tail(params->instrs, &one->node.entry); + + if (!(p_denom = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_DIV, &one->node, p_denom, loc))) + return false; + + if (!(p = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, p_num, p_denom, loc))) + return false; + + if (!(p = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_SAT, p, loc))) + return false; + + if (!(minus_two = hlsl_new_float_constant(ctx, -2.0, loc))) + return false; + list_add_tail(params->instrs, &minus_two->node.entry); + + if (!(three = hlsl_new_float_constant(ctx, 3.0, loc))) + return false; + list_add_tail(params->instrs, &three->node.entry); + + if (!(res = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, &minus_two->node, p, loc))) + return false; + + if (!(res = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, &three->node, res, loc))) + return false; + + if (!(p = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, p, p, loc))) + return false; + + if (!(res = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, p, res, loc))) + return false; + + return true; +} + +static bool intrinsic_sqrt(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *arg; + + if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) + return false; + + return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_SQRT, arg, loc); +} + +static bool intrinsic_step(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *ge; + struct hlsl_type *type; + + if (!elementwise_intrinsic_float_convert_args(ctx, params, loc)) + return false; + + if (!(ge = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_GEQUAL, + params->args[1], params->args[0], loc))) + return false; + + type = ge->data_type; + type = hlsl_get_numeric_type(ctx, type->type, HLSL_TYPE_FLOAT, type->dimx, type->dimy); + return !!add_implicit_conversion(ctx, params->instrs, ge, type, loc); +} + +static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *params, + const struct vkd3d_shader_location *loc, const char *name, enum hlsl_sampler_dim dim) +{ + struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_SAMPLE}; + const struct hlsl_type *sampler_type; + struct hlsl_ir_resource_load *load; + struct hlsl_ir_load *sampler_load; + struct hlsl_ir_node *coords; + + if (params->args_count != 2 && params->args_count != 4) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Wrong number of arguments to function '%s': expected 2 or 4, but got %u.", name, params->args_count); + return false; + } + + if (params->args_count == 4) + { + hlsl_fixme(ctx, loc, "Samples with gradients are not implemented.\n"); + } + + sampler_type = params->args[0]->data_type; + if (sampler_type->type != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER + || (sampler_type->sampler_dim != dim && sampler_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC)) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, sampler_type))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Wrong type for argument 1 of '%s': expected 'sampler' or '%s', but got '%s'.", + name, ctx->builtin_types.sampler[dim]->name, string->buffer); + hlsl_release_string_buffer(ctx, string); + } + else + { + /* Only HLSL_IR_LOAD can return an object. */ + sampler_load = hlsl_ir_load(params->args[0]); + + load_params.resource = sampler_load->src; + } + + if (!(coords = add_implicit_conversion(ctx, params->instrs, params->args[1], + hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, hlsl_sampler_dim_count(dim)), loc))) + coords = params->args[1]; + + load_params.coords = coords; + load_params.format = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4); + + if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) + return false; + list_add_tail(params->instrs, &load->node.entry); + return true; +} + +static bool intrinsic_tex2D(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + return intrinsic_tex(ctx, params, loc, "tex2D", HLSL_SAMPLER_DIM_2D); +} + +static bool intrinsic_tex3D(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + return intrinsic_tex(ctx, params, loc, "tex3D", HLSL_SAMPLER_DIM_3D); +} + +static bool intrinsic_transpose(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *arg = params->args[0]; + struct hlsl_type *arg_type = arg->data_type; + struct hlsl_deref var_deref; + struct hlsl_type *mat_type; + struct hlsl_ir_load *load; + struct hlsl_ir_var *var; + unsigned int i, j; + + if (arg_type->type != HLSL_CLASS_SCALAR && arg_type->type != HLSL_CLASS_MATRIX) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, arg_type))) + hlsl_error(ctx, &arg->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Wrong type for argument 1 of transpose(): expected a matrix or scalar type, but got '%s'.\n", + string->buffer); + hlsl_release_string_buffer(ctx, string); + return false; + } + + if (arg_type->type == HLSL_CLASS_SCALAR) + { + list_add_tail(params->instrs, &arg->entry); + return true; + } + + mat_type = hlsl_get_matrix_type(ctx, arg_type->base_type, arg_type->dimy, arg_type->dimx); + + if (!(var = hlsl_new_synthetic_var(ctx, "transpose", mat_type, loc))) + return false; + hlsl_init_simple_deref_from_var(&var_deref, var); + + for (i = 0; i < arg_type->dimx; ++i) + { + for (j = 0; j < arg_type->dimy; ++j) + { + struct hlsl_ir_store *store; + struct hlsl_block block; + + if (!(load = add_load_component(ctx, params->instrs, arg, j * arg->data_type->dimx + i, loc))) + return false; + + if (!(store = hlsl_new_store_component(ctx, &block, &var_deref, i * var->data_type->dimx + j, &load->node))) + return false; + list_move_tail(params->instrs, &block.instrs); + } + } + + if (!(load = hlsl_new_var_load(ctx, var, *loc))) + return false; + list_add_tail(params->instrs, &load->node.entry); + + return true; +} + +static const struct intrinsic_function +{ + const char *name; + int param_count; + bool check_numeric; + bool (*handler)(struct hlsl_ctx *ctx, const struct parse_initializer *params, + const struct vkd3d_shader_location *loc); +} +intrinsic_functions[] = +{ + /* Note: these entries should be kept in alphabetical order. */ + {"abs", 1, true, intrinsic_abs}, + {"all", 1, true, intrinsic_all}, + {"asuint", -1, true, intrinsic_asuint}, + {"clamp", 3, true, intrinsic_clamp}, + {"cos", 1, true, intrinsic_cos}, + {"cross", 2, true, intrinsic_cross}, + {"distance", 2, true, intrinsic_distance}, + {"dot", 2, true, intrinsic_dot}, + {"exp", 1, true, intrinsic_exp}, + {"exp2", 1, true, intrinsic_exp2}, + {"floor", 1, true, intrinsic_floor}, + {"frac", 1, true, intrinsic_frac}, + {"ldexp", 2, true, intrinsic_ldexp}, + {"length", 1, true, intrinsic_length}, + {"lerp", 3, true, intrinsic_lerp}, + {"lit", 3, true, intrinsic_lit}, + {"max", 2, true, intrinsic_max}, + {"min", 2, true, intrinsic_min}, + {"mul", 2, true, intrinsic_mul}, + {"normalize", 1, true, intrinsic_normalize}, + {"pow", 2, true, intrinsic_pow}, + {"reflect", 2, true, intrinsic_reflect}, + {"round", 1, true, intrinsic_round}, + {"rsqrt", 1, true, intrinsic_rsqrt}, + {"saturate", 1, true, intrinsic_saturate}, + {"sin", 1, true, intrinsic_sin}, + {"smoothstep", 3, true, intrinsic_smoothstep}, + {"sqrt", 1, true, intrinsic_sqrt}, + {"step", 2, true, intrinsic_step}, + {"tex2D", -1, false, intrinsic_tex2D}, + {"tex3D", -1, false, intrinsic_tex3D}, + {"transpose", 1, true, intrinsic_transpose}, +}; + +static int intrinsic_function_name_compare(const void *a, const void *b) +{ + const struct intrinsic_function *func = b; + + return strcmp(a, func->name); +} + +static struct list *add_call(struct hlsl_ctx *ctx, const char *name, + struct parse_initializer *args, const struct vkd3d_shader_location *loc) +{ + struct intrinsic_function *intrinsic; + struct hlsl_ir_function_decl *decl; + + if ((decl = find_function_call(ctx, name, args, loc))) + { + struct hlsl_ir_node *call; + unsigned int i; + + assert(args->args_count == decl->parameters.count); + + for (i = 0; i < decl->parameters.count; ++i) + { + struct hlsl_ir_var *param = decl->parameters.vars[i]; + struct hlsl_ir_node *arg = args->args[i]; + + if (!hlsl_types_are_equal(arg->data_type, param->data_type)) + { + struct hlsl_ir_node *cast; + + if (!(cast = add_cast(ctx, args->instrs, arg, param->data_type, &arg->loc))) + goto fail; + args->args[i] = cast; + arg = cast; + } + + if (param->storage_modifiers & HLSL_STORAGE_IN) + { + struct hlsl_ir_store *store; + + if (!(store = hlsl_new_simple_store(ctx, param, arg))) + goto fail; + list_add_tail(args->instrs, &store->node.entry); + } + } + + if (!(call = hlsl_new_call(ctx, decl, loc))) + goto fail; + list_add_tail(args->instrs, &call->entry); + + for (i = 0; i < decl->parameters.count; ++i) + { + struct hlsl_ir_var *param = decl->parameters.vars[i]; + struct hlsl_ir_node *arg = args->args[i]; + + if (param->storage_modifiers & HLSL_STORAGE_OUT) + { + struct hlsl_ir_load *load; + + if (arg->data_type->modifiers & HLSL_MODIFIER_CONST) + hlsl_error(ctx, &arg->loc, VKD3D_SHADER_ERROR_HLSL_MODIFIES_CONST, + "Output argument to \"%s\" is const.", decl->func->name); + + if (!(load = hlsl_new_var_load(ctx, param, arg->loc))) + goto fail; + list_add_tail(args->instrs, &load->node.entry); + + if (!add_assignment(ctx, args->instrs, arg, ASSIGN_OP_ASSIGN, &load->node)) + goto fail; + } + } + + if (decl->return_var) + { + struct hlsl_ir_load *load; + + if (!(load = hlsl_new_var_load(ctx, decl->return_var, *loc))) + goto fail; + list_add_tail(args->instrs, &load->node.entry); + } + else + { + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; + struct hlsl_ir_node *expr; + + if (!(expr = hlsl_new_expr(ctx, HLSL_OP0_VOID, operands, ctx->builtin_types.Void, loc))) + goto fail; + list_add_tail(args->instrs, &expr->entry); + } + } + else if ((intrinsic = bsearch(name, intrinsic_functions, ARRAY_SIZE(intrinsic_functions), + sizeof(*intrinsic_functions), intrinsic_function_name_compare))) + { + if (intrinsic->param_count >= 0 && args->args_count != intrinsic->param_count) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Wrong number of arguments to function '%s': expected %u, but got %u.", + name, intrinsic->param_count, args->args_count); + goto fail; + } + + if (intrinsic->check_numeric) + { + unsigned int i; + + for (i = 0; i < args->args_count; ++i) + { + if (args->args[i]->data_type->type > HLSL_CLASS_LAST_NUMERIC) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, args->args[i]->data_type))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Wrong type for argument %u of '%s': expected a numeric type, but got '%s'.", + i + 1, name, string->buffer); + hlsl_release_string_buffer(ctx, string); + goto fail; + } + } + } + + if (!intrinsic->handler(ctx, args, loc)) + goto fail; + } + else if (rb_get(&ctx->functions, name)) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "No compatible %u parameter declaration for \"%s\" found.", + args->args_count, name); + goto fail; + } + else + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Function \"%s\" is not defined.", name); + goto fail; + } + vkd3d_free(args->args); + return args->instrs; + +fail: + free_parse_initializer(args); + return NULL; +} + +static struct list *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type, + struct parse_initializer *params, struct vkd3d_shader_location loc) +{ + struct hlsl_ir_load *load; + struct hlsl_ir_var *var; + unsigned int i, idx = 0; + + if (!(var = hlsl_new_synthetic_var(ctx, "constructor", type, &loc))) + return NULL; + + for (i = 0; i < params->args_count; ++i) + { + struct hlsl_ir_node *arg = params->args[i]; + + if (arg->data_type->type == HLSL_CLASS_OBJECT) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, arg->data_type))) + hlsl_error(ctx, &arg->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Invalid type %s for constructor argument.", string->buffer); + hlsl_release_string_buffer(ctx, string); + continue; + } + + initialize_var_components(ctx, params->instrs, var, &idx, arg); + } + + if (!(load = hlsl_new_var_load(ctx, var, loc))) + return NULL; + list_add_tail(params->instrs, &load->node.entry); + + vkd3d_free(params->args); + return params->instrs; +} + +static unsigned int hlsl_offset_dim_count(enum hlsl_sampler_dim dim) +{ + switch (dim) + { + case HLSL_SAMPLER_DIM_1D: + case HLSL_SAMPLER_DIM_1DARRAY: + return 1; + case HLSL_SAMPLER_DIM_2D: + case HLSL_SAMPLER_DIM_2DMS: + case HLSL_SAMPLER_DIM_2DARRAY: + case HLSL_SAMPLER_DIM_2DMSARRAY: + return 2; + case HLSL_SAMPLER_DIM_3D: + return 3; + case HLSL_SAMPLER_DIM_CUBE: + case HLSL_SAMPLER_DIM_CUBEARRAY: + /* Offset parameters not supported for these types. */ + return 0; + default: + vkd3d_unreachable(); + } +} + +static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object, + const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + const struct hlsl_type *object_type = object->data_type; + struct hlsl_ir_load *object_load; + + if (object_type->type != HLSL_CLASS_OBJECT || object_type->base_type != HLSL_TYPE_TEXTURE + || object_type->sampler_dim == HLSL_SAMPLER_DIM_GENERIC) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, object_type))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Type '%s' does not have methods.", string->buffer); + hlsl_release_string_buffer(ctx, string); + return false; + } + + /* Only HLSL_IR_LOAD can return an object. */ + object_load = hlsl_ir_load(object); + + if (!strcmp(name, "Load") + && object_type->sampler_dim != HLSL_SAMPLER_DIM_CUBE + && object_type->sampler_dim != HLSL_SAMPLER_DIM_CUBEARRAY) + { + const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); + const unsigned int offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); + struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_LOAD}; + struct hlsl_ir_resource_load *load; + bool multisampled; + + multisampled = object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS + || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY; + + if (params->args_count < 1 + multisampled || params->args_count > 3 + multisampled) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Wrong number of arguments to method 'Load': expected between %u and %u, but got %u.", + 1 + multisampled, 3 + multisampled, params->args_count); + return false; + } + if (multisampled) + { + hlsl_fixme(ctx, loc, "Load() sampling index parameter."); + } + + assert(offset_dim); + if (params->args_count > 1 + multisampled) + { + if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[1 + multisampled], + hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) + return false; + } + if (params->args_count > 2 + multisampled) + { + hlsl_fixme(ctx, loc, "Tiled resource status argument."); + } + + /* +1 for the mipmap level */ + if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[0], + hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim + 1), loc))) + return false; + + load_params.format = object_type->e.resource_format; + load_params.resource = object_load->src; + + if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) + return false; + list_add_tail(instrs, &load->node.entry); + return true; + } + else if (!strcmp(name, "Sample") + && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMS + && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) + { + const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); + const unsigned int offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); + struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_SAMPLE}; + const struct hlsl_type *sampler_type; + struct hlsl_ir_resource_load *load; + struct hlsl_ir_load *sampler_load; + + if (params->args_count < 2 || params->args_count > 4 + !!offset_dim) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Wrong number of arguments to method 'Sample': expected from 2 to %u, but got %u.", + 4 + !!offset_dim, params->args_count); + return false; + } + + sampler_type = params->args[0]->data_type; + if (sampler_type->type != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER + || sampler_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, sampler_type))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Wrong type for argument 0 of Sample(): expected 'sampler', but got '%s'.", string->buffer); + hlsl_release_string_buffer(ctx, string); + return false; + } + + /* Only HLSL_IR_LOAD can return an object. */ + sampler_load = hlsl_ir_load(params->args[0]); + + if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], + hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) + return false; + + if (offset_dim && params->args_count > 2) + { + if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[2], + hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) + return false; + } + + if (params->args_count > 2 + !!offset_dim) + hlsl_fixme(ctx, loc, "Sample() clamp parameter."); + if (params->args_count > 3 + !!offset_dim) + hlsl_fixme(ctx, loc, "Tiled resource status argument."); + + load_params.format = object_type->e.resource_format; + load_params.resource = object_load->src; + load_params.sampler = sampler_load->src; + + if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) + return false; + list_add_tail(instrs, &load->node.entry); + + return true; + } + else if ((!strcmp(name, "Gather") || !strcmp(name, "GatherRed") || !strcmp(name, "GatherBlue") + || !strcmp(name, "GatherGreen") || !strcmp(name, "GatherAlpha")) + && (object_type->sampler_dim == HLSL_SAMPLER_DIM_2D + || object_type->sampler_dim == HLSL_SAMPLER_DIM_2DARRAY + || object_type->sampler_dim == HLSL_SAMPLER_DIM_CUBE + || object_type->sampler_dim == HLSL_SAMPLER_DIM_CUBEARRAY)) + { + const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); + const unsigned int offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); + struct hlsl_resource_load_params load_params = {0}; + const struct hlsl_type *sampler_type; + struct hlsl_ir_resource_load *load; + struct hlsl_ir_load *sampler_load; + unsigned int read_channel; + + if (!strcmp(name, "GatherGreen")) + { + load_params.type = HLSL_RESOURCE_GATHER_GREEN; + read_channel = 1; + } + else if (!strcmp(name, "GatherBlue")) + { + load_params.type = HLSL_RESOURCE_GATHER_BLUE; + read_channel = 2; + } + else if (!strcmp(name, "GatherAlpha")) + { + load_params.type = HLSL_RESOURCE_GATHER_ALPHA; + read_channel = 3; + } + else + { + load_params.type = HLSL_RESOURCE_GATHER_RED; + read_channel = 0; + } + + if (!strcmp(name, "Gather") || !offset_dim) + { + if (params->args_count < 2 || params->args_count > 3 + !!offset_dim) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Wrong number of arguments to method '%s': expected from 2 to %u, but got %u.", + name, 3 + !!offset_dim, params->args_count); + return false; + } + } + else if (params->args_count < 2 || params->args_count == 5 || params->args_count > 7) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Wrong number of arguments to method '%s': expected 2, 3, 4, 6 or 7, but got %u.", + name, params->args_count); + return false; + } + + if (params->args_count == 3 + !!offset_dim || params->args_count == 7) + hlsl_fixme(ctx, loc, "Tiled resource status argument."); + + if (params->args_count == 6 || params->args_count == 7) + { + hlsl_fixme(ctx, loc, "Multiple %s() offset parameters.", name); + } + else if (offset_dim && params->args_count > 2) + { + if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[2], + hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) + return false; + } + + sampler_type = params->args[0]->data_type; + if (sampler_type->type != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER + || sampler_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, sampler_type))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Wrong type for argument 1 of %s(): expected 'sampler', but got '%s'.", name, string->buffer); + hlsl_release_string_buffer(ctx, string); + return false; + } + + if (read_channel >= object_type->e.resource_format->dimx) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Method %s() requires at least %u channels.", name, read_channel + 1); + return false; + } + + /* Only HLSL_IR_LOAD can return an object. */ + sampler_load = hlsl_ir_load(params->args[0]); + + if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], + hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) + return false; + + load_params.format = hlsl_get_vector_type(ctx, object_type->e.resource_format->base_type, 4); + load_params.resource = object_load->src; + load_params.sampler = sampler_load->src; + + if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) + return false; + list_add_tail(instrs, &load->node.entry); + return true; + } + else if (!strcmp(name, "SampleLevel") + && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMS + && object_type->sampler_dim != HLSL_SAMPLER_DIM_2DMSARRAY) + { + struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_SAMPLE_LOD}; + const unsigned int sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); + const unsigned int offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); + const struct hlsl_type *sampler_type; + struct hlsl_ir_resource_load *load; + struct hlsl_ir_load *sampler_load; + + if (params->args_count < 3 || params->args_count > 4 + !!offset_dim) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Wrong number of arguments to method 'SampleLevel': expected from 3 to %u, but got %u.", + 4 + !!offset_dim, params->args_count); + return false; + } + + sampler_type = params->args[0]->data_type; + if (sampler_type->type != HLSL_CLASS_OBJECT || sampler_type->base_type != HLSL_TYPE_SAMPLER + || sampler_type->sampler_dim != HLSL_SAMPLER_DIM_GENERIC) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, sampler_type))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Wrong type for argument 0 of SampleLevel(): expected 'sampler', but got '%s'.", string->buffer); + hlsl_release_string_buffer(ctx, string); + return false; + } + + /* Only HLSL_IR_LOAD can return an object. */ + sampler_load = hlsl_ir_load(params->args[0]); + + if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], + hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) + load_params.coords = params->args[1]; + + if (!(load_params.lod = add_implicit_conversion(ctx, instrs, params->args[2], + hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc))) + load_params.lod = params->args[2]; + + if (offset_dim && params->args_count > 3) + { + if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[3], + hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) + return false; + } + + if (params->args_count > 3 + !!offset_dim) + hlsl_fixme(ctx, loc, "Tiled resource status argument."); + + load_params.format = object_type->e.resource_format; + load_params.resource = object_load->src; + load_params.sampler = sampler_load->src; + + if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) + return false; + list_add_tail(instrs, &load->node.entry); + return true; + } + else + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, object_type))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, + "Method '%s' is not defined on type '%s'.", name, string->buffer); + hlsl_release_string_buffer(ctx, string); + return false; + } +} + +static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type *format, + const struct vkd3d_shader_location *loc) +{ + if (format->type > HLSL_CLASS_VECTOR) + { + struct vkd3d_string_buffer *string; + + string = hlsl_type_to_string(ctx, format); + if (string) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Texture data type %s is not scalar or vector.", string->buffer); + hlsl_release_string_buffer(ctx, string); + } +} + +} + +%locations +%define parse.error verbose +%define api.prefix {hlsl_yy} +%define api.pure full +%expect 1 +%lex-param {yyscan_t scanner} +%parse-param {void *scanner} +%parse-param {struct hlsl_ctx *ctx} + +%union +{ + struct hlsl_type *type; + INT intval; + FLOAT floatval; + bool boolval; + char *name; + DWORD modifiers; + struct hlsl_ir_node *instr; + struct list *list; + struct parse_fields fields; + struct parse_function function; + struct parse_parameter parameter; + struct hlsl_func_parameters parameters; + struct parse_initializer initializer; + struct parse_array_sizes arrays; + struct parse_variable_def *variable_def; + struct parse_if_body if_body; + enum parse_assign_op assign_op; + struct hlsl_reg_reservation reg_reservation; + struct parse_colon_attribute colon_attribute; + struct hlsl_semantic semantic; + enum hlsl_buffer_type buffer_type; + enum hlsl_sampler_dim sampler_dim; + struct hlsl_attribute *attr; + struct parse_attribute_list attr_list; +} + +%token KW_BLENDSTATE +%token KW_BREAK +%token KW_BUFFER +%token KW_CBUFFER +%token KW_COLUMN_MAJOR +%token KW_COMPILE +%token KW_CONST +%token KW_CONTINUE +%token KW_DEPTHSTENCILSTATE +%token KW_DEPTHSTENCILVIEW +%token KW_DISCARD +%token KW_DO +%token KW_DOUBLE +%token KW_ELSE +%token KW_EXTERN +%token KW_FALSE +%token KW_FOR +%token KW_GEOMETRYSHADER +%token KW_GROUPSHARED +%token KW_IF +%token KW_IN +%token KW_INLINE +%token KW_INOUT +%token KW_MATRIX +%token KW_NAMESPACE +%token KW_NOINTERPOLATION +%token KW_OUT +%token KW_PASS +%token KW_PIXELSHADER +%token KW_PRECISE +%token KW_RASTERIZERSTATE +%token KW_RENDERTARGETVIEW +%token KW_RETURN +%token KW_REGISTER +%token KW_ROW_MAJOR +%token KW_RWTEXTURE1D +%token KW_RWTEXTURE2D +%token KW_RWTEXTURE3D +%token KW_SAMPLER +%token KW_SAMPLER1D +%token KW_SAMPLER2D +%token KW_SAMPLER3D +%token KW_SAMPLERCUBE +%token KW_SAMPLER_STATE +%token KW_SAMPLERCOMPARISONSTATE +%token KW_SHARED +%token KW_STATEBLOCK +%token KW_STATEBLOCK_STATE +%token KW_STATIC +%token KW_STRING +%token KW_STRUCT +%token KW_SWITCH +%token KW_TBUFFER +%token KW_TECHNIQUE +%token KW_TECHNIQUE10 +%token KW_TEXTURE +%token KW_TEXTURE1D +%token KW_TEXTURE1DARRAY +%token KW_TEXTURE2D +%token KW_TEXTURE2DARRAY +%token KW_TEXTURE2DMS +%token KW_TEXTURE2DMSARRAY +%token KW_TEXTURE3D +%token KW_TEXTURECUBE +%token KW_TEXTURECUBEARRAY +%token KW_TRUE +%token KW_TYPEDEF +%token KW_UNIFORM +%token KW_VECTOR +%token KW_VERTEXSHADER +%token KW_VOID +%token KW_VOLATILE +%token KW_WHILE + +%token OP_INC +%token OP_DEC +%token OP_AND +%token OP_OR +%token OP_EQ +%token OP_LEFTSHIFT +%token OP_LEFTSHIFTASSIGN +%token OP_RIGHTSHIFT +%token OP_RIGHTSHIFTASSIGN +%token OP_ELLIPSIS +%token OP_LE +%token OP_GE +%token OP_NE +%token OP_ADDASSIGN +%token OP_SUBASSIGN +%token OP_MULASSIGN +%token OP_DIVASSIGN +%token OP_MODASSIGN +%token OP_ANDASSIGN +%token OP_ORASSIGN +%token OP_XORASSIGN +%token OP_UNKNOWN1 +%token OP_UNKNOWN2 +%token OP_UNKNOWN3 +%token OP_UNKNOWN4 + +%token C_FLOAT + +%token C_INTEGER +%token PRE_LINE + +%type add_expr +%type assignment_expr +%type bitand_expr +%type bitor_expr +%type bitxor_expr +%type compound_statement +%type conditional_expr +%type declaration +%type declaration_statement +%type equality_expr +%type expr +%type expr_optional +%type expr_statement +%type initializer_expr +%type jump_statement +%type logicand_expr +%type logicor_expr +%type loop_statement +%type mul_expr +%type postfix_expr +%type primary_expr +%type relational_expr +%type selection_statement +%type shift_expr +%type statement +%type statement_list +%type struct_declaration +%type type_specs +%type unary_expr +%type variables_def +%type variables_def_optional + +%token VAR_IDENTIFIER +%token NEW_IDENTIFIER +%token STRING +%token TYPE_IDENTIFIER + +%type arrays + +%type assign_op + +%type attribute + +%type attribute_list + +%type boolean + +%type buffer_type + +%type colon_attribute + +%type field +%type fields_list + +%type func_prototype +%type func_prototype_no_attrs + +%type complex_initializer +%type complex_initializer_list +%type func_arguments +%type initializer_expr_list + +%type if_body + +%type var_modifiers + +%type any_identifier +%type var_identifier + +%type parameter + +%type param_list +%type parameters + +%type register_opt + +%type texture_type texture_ms_type uav_type + +%type semantic + +%type field_type +%type named_struct_spec +%type unnamed_struct_spec +%type struct_spec +%type type +%type type_no_void +%type typedef_type + +%type type_spec +%type variable_decl +%type variable_def + +%% + +hlsl_prog: + %empty + | hlsl_prog func_declaration + | hlsl_prog buffer_declaration buffer_body + | hlsl_prog declaration_statement + { + if (!list_empty($2)) + hlsl_fixme(ctx, &@2, "Uniform initializer."); + destroy_instr_list($2); + } + | hlsl_prog preproc_directive + | hlsl_prog ';' + +buffer_declaration: + buffer_type any_identifier colon_attribute + { + if ($3.semantic.name) + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, "Semantics are not allowed on buffers."); + + if (!(ctx->cur_buffer = hlsl_new_buffer(ctx, $1, $2, &$3.reg_reservation, @2))) + YYABORT; + } + +buffer_body: + '{' declaration_statement_list '}' + { + ctx->cur_buffer = ctx->globals_buffer; + } + +buffer_type: + KW_CBUFFER + { + $$ = HLSL_BUFFER_CONSTANT; + } + | KW_TBUFFER + { + $$ = HLSL_BUFFER_TEXTURE; + } + +declaration_statement_list: + %empty + | declaration_statement_list declaration_statement + +preproc_directive: + PRE_LINE STRING + { + const char **new_array = NULL; + + ctx->location.line = $1; + if (strcmp($2, ctx->location.source_name)) + new_array = hlsl_realloc(ctx, ctx->source_files, + sizeof(*ctx->source_files) * (ctx->source_files_count + 1)); + + if (new_array) + { + ctx->source_files = new_array; + ctx->source_files[ctx->source_files_count++] = $2; + ctx->location.source_name = $2; + } + else + { + vkd3d_free($2); + } + } + +struct_declaration: + var_modifiers struct_spec variables_def_optional ';' + { + struct hlsl_type *type; + unsigned int modifiers = $1; + + if (!$3) + { + if (!$2->name) + hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, + "Anonymous struct type must declare a variable."); + if (modifiers) + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Modifiers are not allowed on struct type declarations."); + } + + if (!(type = apply_type_modifiers(ctx, $2, &modifiers, true, &@1))) + YYABORT; + $$ = declare_vars(ctx, type, modifiers, &@1, $3); + } + +struct_spec: + named_struct_spec + | unnamed_struct_spec + +named_struct_spec: + KW_STRUCT any_identifier '{' fields_list '}' + { + bool ret; + + $$ = hlsl_new_struct_type(ctx, $2, $4.fields, $4.count); + + if (hlsl_get_var(ctx->cur_scope, $2)) + { + hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_REDEFINED, "\"%s\" is already declared as a variable.", $2); + YYABORT; + } + + ret = hlsl_scope_add_type(ctx->cur_scope, $$); + if (!ret) + { + hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_REDEFINED, "Struct \"%s\" is already defined.", $2); + YYABORT; + } + } + +unnamed_struct_spec: + KW_STRUCT '{' fields_list '}' + { + $$ = hlsl_new_struct_type(ctx, NULL, $3.fields, $3.count); + } + +any_identifier: + VAR_IDENTIFIER + | TYPE_IDENTIFIER + | NEW_IDENTIFIER + +fields_list: + %empty + { + $$.fields = NULL; + $$.count = 0; + $$.capacity = 0; + } + | fields_list field + { + size_t i; + + for (i = 0; i < $2.count; ++i) + { + const struct hlsl_struct_field *field = &$2.fields[i]; + const struct hlsl_struct_field *existing; + + if ((existing = get_struct_field($1.fields, $1.count, field->name))) + { + hlsl_error(ctx, &field->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, + "Field \"%s\" is already defined.", field->name); + hlsl_note(ctx, &existing->loc, VKD3D_SHADER_LOG_ERROR, + "'%s' was previously defined here.", field->name); + } + } + + if (!hlsl_array_reserve(ctx, (void **)&$1.fields, &$1.capacity, $1.count + $2.count, sizeof(*$1.fields))) + YYABORT; + memcpy($1.fields + $1.count, $2.fields, $2.count * sizeof(*$2.fields)); + $1.count += $2.count; + vkd3d_free($2.fields); + + $$ = $1; + } + +field_type: + type + | unnamed_struct_spec + +field: + var_modifiers field_type variables_def ';' + { + struct hlsl_type *type; + unsigned int modifiers = $1; + + if (!(type = apply_type_modifiers(ctx, $2, &modifiers, true, &@1))) + YYABORT; + if (modifiers & ~HLSL_STORAGE_NOINTERPOLATION) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_modifiers_to_string(ctx, modifiers))) + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Modifiers '%s' are not allowed on struct fields.", string->buffer); + hlsl_release_string_buffer(ctx, string); + } + if (!gen_struct_fields(ctx, &$$, type, modifiers, $3)) + YYABORT; + } + +attribute: + '[' any_identifier ']' + { + if (!($$ = hlsl_alloc(ctx, offsetof(struct hlsl_attribute, args[0])))) + { + vkd3d_free($2); + YYABORT; + } + $$->name = $2; + list_init(&$$->instrs); + $$->loc = @$; + $$->args_count = 0; + } + | '[' any_identifier '(' initializer_expr_list ')' ']' + { + unsigned int i; + + if (!($$ = hlsl_alloc(ctx, offsetof(struct hlsl_attribute, args[$4.args_count])))) + { + vkd3d_free($2); + free_parse_initializer(&$4); + YYABORT; + } + $$->name = $2; + list_init(&$$->instrs); + list_move_tail(&$$->instrs, $4.instrs); + vkd3d_free($4.instrs); + $$->loc = @$; + $$->args_count = $4.args_count; + for (i = 0; i < $4.args_count; ++i) + hlsl_src_from_node(&$$->args[i], $4.args[i]); + } + +attribute_list: + attribute + { + $$.count = 1; + if (!($$.attrs = hlsl_alloc(ctx, sizeof(*$$.attrs)))) + { + hlsl_free_attribute($1); + YYABORT; + } + $$.attrs[0] = $1; + } + | attribute_list attribute + { + const struct hlsl_attribute **new_array; + + $$ = $1; + if (!(new_array = vkd3d_realloc($$.attrs, ($$.count + 1) * sizeof(*$$.attrs)))) + { + unsigned int i; + + for (i = 0; i < $$.count; ++i) + hlsl_free_attribute((void *)$$.attrs[i]); + vkd3d_free($$.attrs); + YYABORT; + } + $$.attrs = new_array; + $$.attrs[$$.count++] = $2; + } + +func_declaration: + func_prototype compound_statement + { + struct hlsl_ir_function_decl *decl = $1.decl; + + if (decl->has_body) + { + hlsl_error(ctx, &decl->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, + "Function \"%s\" is already defined.", decl->func->name); + hlsl_note(ctx, &decl->loc, VKD3D_SHADER_LOG_ERROR, + "\"%s\" was previously defined here.", decl->func->name); + hlsl_free_instr_list($2); + } + else + { + size_t i; + + decl->has_body = true; + list_move_tail(&decl->body.instrs, $2); + vkd3d_free($2); + + /* Semantics are taken from whichever definition has a body. + * We can't just replace the hlsl_ir_var pointers, though: if + * the function was already declared but not defined, the + * callers would have used the old declaration's parameters to + * transfer arguments. */ + + if (!$1.first) + { + assert(decl->parameters.count == $1.parameters.count); + + for (i = 0; i < $1.parameters.count; ++i) + { + struct hlsl_ir_var *dst = decl->parameters.vars[i]; + struct hlsl_ir_var *src = $1.parameters.vars[i]; + + hlsl_cleanup_semantic(&dst->semantic); + dst->semantic = src->semantic; + memset(&src->semantic, 0, sizeof(src->semantic)); + } + + if (decl->return_var) + { + hlsl_cleanup_semantic(&decl->return_var->semantic); + decl->return_var->semantic = $1.return_semantic; + memset(&$1.return_semantic, 0, sizeof($1.return_semantic)); + } + } + } + hlsl_pop_scope(ctx); + + if (!$1.first) + { + vkd3d_free($1.parameters.vars); + hlsl_cleanup_semantic(&$1.return_semantic); + } + } + | func_prototype ';' + { + hlsl_pop_scope(ctx); + } + +func_prototype_no_attrs: + /* var_modifiers is necessary to avoid shift/reduce conflicts. */ + var_modifiers type var_identifier '(' parameters ')' colon_attribute + { + unsigned int modifiers = $1; + struct hlsl_ir_var *var; + struct hlsl_type *type; + + if (modifiers & ~HLSL_MODIFIERS_MAJORITY_MASK) + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Only majority modifiers are allowed on functions."); + if (!(type = apply_type_modifiers(ctx, $2, &modifiers, true, &@1))) + YYABORT; + if ((var = hlsl_get_var(ctx->globals, $3))) + { + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_REDEFINED, + "\"%s\" is already declared as a variable.", $3); + hlsl_note(ctx, &var->loc, VKD3D_SHADER_LOG_ERROR, + "\"%s\" was previously declared here.", $3); + } + if (hlsl_types_are_equal(type, ctx->builtin_types.Void) && $7.semantic.name) + { + hlsl_error(ctx, &@7, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, + "Semantics are not allowed on void functions."); + } + + if ($7.reg_reservation.type) + FIXME("Unexpected register reservation for a function.\n"); + + if (($$.decl = get_func_decl(&ctx->functions, $3, &$5))) + { + const struct hlsl_func_parameters *params = &$$.decl->parameters; + size_t i; + + if (!hlsl_types_are_equal($2, $$.decl->return_type)) + { + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_REDEFINED, + "\"%s\" was already declared with a different return type.", $3); + hlsl_note(ctx, &$$.decl->loc, VKD3D_SHADER_LOG_ERROR, "\"%s\" was previously declared here.", $3); + } + + vkd3d_free($3); + + /* We implement function invocation by copying to input + * parameters, emitting a HLSL_IR_CALL instruction, then copying + * from output parameters. As a result, we need to use the same + * parameter variables for every invocation of this function, + * which means we use the parameters created by the first + * declaration. If we're not the first declaration, the + * parameter variables that just got created will end up being + * mostly ignored—in particular, they won't be used in actual + * IR. + * + * There is a hitch: if this is the actual definition, the + * function body will look up parameter variables by name. We + * must return the original parameters, and not the ones we just + * created, but we're in the wrong scope, and the parameters + * might not even have the same names. + * + * Therefore we need to shuffle the parameters we just created + * into a dummy scope where they'll never be looked up, and + * rename the original parameters so they have the expected + * names. We actually do this for every prototype: we don't know + * whether this is the function definition yet, but it doesn't + * really matter. The variables can only be used in the + * actual definition, and don't do anything in a declaration. + * + * This is complex, and it seems tempting to avoid this logic by + * putting arguments into the HLSL_IR_CALL instruction, letting + * the canonical variables be the ones attached to the function + * definition, and resolving the copies when inlining. The + * problem with this is output parameters. We would have to use + * a lot of parsing logic on already lowered IR, which is + * brittle and ugly. + */ + + assert($5.count == params->count); + for (i = 0; i < params->count; ++i) + { + struct hlsl_ir_var *orig_param = params->vars[i]; + struct hlsl_ir_var *new_param = $5.vars[i]; + char *new_name; + + list_remove(&orig_param->scope_entry); + list_add_tail(&ctx->cur_scope->vars, &orig_param->scope_entry); + + list_remove(&new_param->scope_entry); + list_add_tail(&ctx->dummy_scope->vars, &new_param->scope_entry); + + if (!(new_name = hlsl_strdup(ctx, new_param->name))) + YYABORT; + vkd3d_free((void *)orig_param->name); + orig_param->name = new_name; + } + + $$.first = false; + $$.parameters = $5; + $$.return_semantic = $7.semantic; + } + else + { + if (!($$.decl = hlsl_new_func_decl(ctx, type, &$5, &$7.semantic, &@3))) + YYABORT; + + hlsl_add_function(ctx, $3, $$.decl); + + $$.first = true; + } + + ctx->cur_function = $$.decl; + } + +func_prototype: + func_prototype_no_attrs + | attribute_list func_prototype_no_attrs + { + if ($2.first) + { + $2.decl->attr_count = $1.count; + $2.decl->attrs = $1.attrs; + } + else + { + free($1.attrs); + } + $$ = $2; + } + +compound_statement: + '{' '}' + { + if (!($$ = make_empty_list(ctx))) + YYABORT; + } + | '{' scope_start statement_list '}' + { + hlsl_pop_scope(ctx); + $$ = $3; + } + +scope_start: + %empty + { + hlsl_push_scope(ctx); + } + +var_identifier: + VAR_IDENTIFIER + | NEW_IDENTIFIER + +colon_attribute: + %empty + { + $$.semantic.name = NULL; + $$.reg_reservation.type = 0; + } + | semantic + { + $$.semantic = $1; + $$.reg_reservation.type = 0; + } + | register_opt + { + $$.semantic.name = NULL; + $$.reg_reservation = $1; + } + +semantic: + ':' any_identifier + { + char *p; + + for (p = $2 + strlen($2); p > $2 && isdigit(p[-1]); --p) + ; + $$.name = $2; + $$.index = atoi(p); + *p = 0; + } + +/* FIXME: Writemasks */ +register_opt: + ':' KW_REGISTER '(' any_identifier ')' + { + $$ = parse_reg_reservation($4); + vkd3d_free($4); + } + | ':' KW_REGISTER '(' any_identifier ',' any_identifier ')' + { + FIXME("Ignoring shader target %s in a register reservation.\n", debugstr_a($4)); + vkd3d_free($4); + + $$ = parse_reg_reservation($6); + vkd3d_free($6); + } + +parameters: + scope_start + { + memset(&$$, 0, sizeof($$)); + } + | scope_start KW_VOID + { + memset(&$$, 0, sizeof($$)); + } + | scope_start param_list + { + $$ = $2; + } + +param_list: + parameter + { + memset(&$$, 0, sizeof($$)); + if (!add_func_parameter(ctx, &$$, &$1, @1)) + { + ERR("Error adding function parameter %s.\n", $1.name); + YYABORT; + } + } + | param_list ',' parameter + { + $$ = $1; + if (!add_func_parameter(ctx, &$$, &$3, @3)) + { + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_REDEFINED, + "Parameter \"%s\" is already declared.", $3.name); + YYABORT; + } + } + +parameter: + var_modifiers type_no_void any_identifier arrays colon_attribute + { + unsigned int modifiers = $1; + struct hlsl_type *type; + unsigned int i; + + if (!(type = apply_type_modifiers(ctx, $2, &modifiers, true, &@1))) + YYABORT; + + $$.modifiers = modifiers; + if (!($$.modifiers & (HLSL_STORAGE_IN | HLSL_STORAGE_OUT))) + $$.modifiers |= HLSL_STORAGE_IN; + + for (i = 0; i < $4.count; ++i) + { + if ($4.sizes[i] == HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT) + { + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Implicit size arrays not allowed in function parameters."); + } + type = hlsl_new_array_type(ctx, type, $4.sizes[i]); + } + $$.type = type; + + $$.name = $3; + $$.semantic = $5.semantic; + $$.reg_reservation = $5.reg_reservation; + } + +texture_type: + KW_TEXTURE1D + { + $$ = HLSL_SAMPLER_DIM_1D; + } + | KW_TEXTURE2D + { + $$ = HLSL_SAMPLER_DIM_2D; + } + | KW_TEXTURE3D + { + $$ = HLSL_SAMPLER_DIM_3D; + } + | KW_TEXTURECUBE + { + $$ = HLSL_SAMPLER_DIM_CUBE; + } + | KW_TEXTURE1DARRAY + { + $$ = HLSL_SAMPLER_DIM_1DARRAY; + } + | KW_TEXTURE2DARRAY + { + $$ = HLSL_SAMPLER_DIM_2DARRAY; + } + | KW_TEXTURECUBEARRAY + { + $$ = HLSL_SAMPLER_DIM_CUBEARRAY; + } + +texture_ms_type: + KW_TEXTURE2DMS + { + $$ = HLSL_SAMPLER_DIM_2DMS; + } + | KW_TEXTURE2DMSARRAY + { + $$ = HLSL_SAMPLER_DIM_2DMSARRAY; + } + +uav_type: + KW_RWTEXTURE1D + { + $$ = HLSL_SAMPLER_DIM_1D; + } + | KW_RWTEXTURE2D + { + $$ = HLSL_SAMPLER_DIM_2D; + } + | KW_RWTEXTURE3D + { + $$ = HLSL_SAMPLER_DIM_3D; + } + +type_no_void: + KW_VECTOR '<' type ',' C_INTEGER '>' + { + if ($3->type != HLSL_CLASS_SCALAR) + { + struct vkd3d_string_buffer *string; + + string = hlsl_type_to_string(ctx, $3); + if (string) + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Vector base type %s is not scalar.", string->buffer); + hlsl_release_string_buffer(ctx, string); + YYABORT; + } + if ($5 < 1 || $5 > 4) + { + hlsl_error(ctx, &@5, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE, + "Vector size %d is not between 1 and 4.", $5); + YYABORT; + } + + $$ = hlsl_type_clone(ctx, hlsl_get_vector_type(ctx, $3->base_type, $5), 0, 0); + $$->is_minimum_precision = $3->is_minimum_precision; + } + | KW_VECTOR + { + $$ = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4); + } + | KW_MATRIX '<' type ',' C_INTEGER ',' C_INTEGER '>' + { + if ($3->type != HLSL_CLASS_SCALAR) + { + struct vkd3d_string_buffer *string; + + string = hlsl_type_to_string(ctx, $3); + if (string) + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Matrix base type %s is not scalar.", string->buffer); + hlsl_release_string_buffer(ctx, string); + YYABORT; + } + if ($5 < 1 || $5 > 4) + { + hlsl_error(ctx, &@5, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE, + "Matrix row count %d is not between 1 and 4.", $5); + YYABORT; + } + if ($7 < 1 || $7 > 4) + { + hlsl_error(ctx, &@7, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE, + "Matrix column count %d is not between 1 and 4.", $7); + YYABORT; + } + + $$ = hlsl_type_clone(ctx, hlsl_get_matrix_type(ctx, $3->base_type, $7, $5), 0, 0); + $$->is_minimum_precision = $3->is_minimum_precision; + } + | KW_MATRIX + { + $$ = hlsl_get_matrix_type(ctx, HLSL_TYPE_FLOAT, 4, 4); + } + | KW_SAMPLER + { + $$ = ctx->builtin_types.sampler[HLSL_SAMPLER_DIM_GENERIC]; + } + | KW_SAMPLER1D + { + $$ = ctx->builtin_types.sampler[HLSL_SAMPLER_DIM_1D]; + } + | KW_SAMPLER2D + { + $$ = ctx->builtin_types.sampler[HLSL_SAMPLER_DIM_2D]; + } + | KW_SAMPLER3D + { + $$ = ctx->builtin_types.sampler[HLSL_SAMPLER_DIM_3D]; + } + | KW_SAMPLERCUBE + { + $$ = ctx->builtin_types.sampler[HLSL_SAMPLER_DIM_3D]; + } + | KW_TEXTURE + { + $$ = hlsl_new_texture_type(ctx, HLSL_SAMPLER_DIM_GENERIC, NULL, 0); + } + | texture_type + { + $$ = hlsl_new_texture_type(ctx, $1, hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4), 0); + } + | texture_type '<' type '>' + { + validate_texture_format_type(ctx, $3, &@3); + $$ = hlsl_new_texture_type(ctx, $1, $3, 0); + } + | texture_ms_type '<' type '>' + { + validate_texture_format_type(ctx, $3, &@3); + + /* TODO: unspecified sample count is not allowed for all targets */ + $$ = hlsl_new_texture_type(ctx, $1, $3, 0); + } + | texture_ms_type '<' type ',' shift_expr '>' + { + unsigned int sample_count = evaluate_static_expression(node_from_list($5)); + destroy_instr_list($5); + + $$ = hlsl_new_texture_type(ctx, $1, $3, sample_count); + } + | uav_type '<' type '>' + { + if ($3->type > HLSL_CLASS_VECTOR) + { + struct vkd3d_string_buffer *string; + + string = hlsl_type_to_string(ctx, $3); + if (string) + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "UAV data type %s is not scalar or vector.", string->buffer); + hlsl_release_string_buffer(ctx, string); + } + $$ = hlsl_new_uav_type(ctx, $1, $3); + } + | TYPE_IDENTIFIER + { + $$ = hlsl_get_type(ctx->cur_scope, $1, true, true); + if ($$->is_minimum_precision) + { + if (ctx->profile->major_version < 4) + { + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Target profile doesn't support minimum-precision types."); + } + else + { + FIXME("Reinterpreting type %s.\n", $$->name); + } + } + vkd3d_free($1); + } + | KW_STRUCT TYPE_IDENTIFIER + { + $$ = hlsl_get_type(ctx->cur_scope, $2, true, true); + if ($$->type != HLSL_CLASS_STRUCT) + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_REDEFINED, "\"%s\" redefined as a structure.", $2); + vkd3d_free($2); + } + +type: + type_no_void + | KW_VOID + { + $$ = ctx->builtin_types.Void; + } + +declaration_statement: + declaration + | struct_declaration + | typedef + { + if (!($$ = make_empty_list(ctx))) + YYABORT; + } + +typedef_type: + type + | struct_spec + +typedef: + KW_TYPEDEF var_modifiers typedef_type type_specs ';' + { + struct parse_variable_def *v, *v_next; + unsigned int modifiers = $2; + struct hlsl_type *type; + + if (!(type = apply_type_modifiers(ctx, $3, &modifiers, false, &@2))) + { + LIST_FOR_EACH_ENTRY_SAFE(v, v_next, $4, struct parse_variable_def, entry) + free_parse_variable_def(v); + vkd3d_free($4); + YYABORT; + } + + if (modifiers) + { + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Storage modifiers are not allowed on typedefs."); + LIST_FOR_EACH_ENTRY_SAFE(v, v_next, $4, struct parse_variable_def, entry) + vkd3d_free(v); + vkd3d_free($4); + YYABORT; + } + if (!add_typedef(ctx, type, $4)) + YYABORT; + } + +type_specs: + type_spec + { + if (!($$ = make_empty_list(ctx))) + YYABORT; + list_add_head($$, &$1->entry); + } + | type_specs ',' type_spec + { + $$ = $1; + list_add_tail($$, &$3->entry); + } + +type_spec: + any_identifier arrays + { + $$ = hlsl_alloc(ctx, sizeof(*$$)); + $$->loc = @1; + $$->name = $1; + $$->arrays = $2; + } + +declaration: + var_modifiers type variables_def ';' + { + struct hlsl_type *type; + unsigned int modifiers = $1; + + if (!(type = apply_type_modifiers(ctx, $2, &modifiers, true, &@1))) + YYABORT; + $$ = declare_vars(ctx, type, modifiers, &@1, $3); + } + +variables_def_optional: + %empty + { + $$ = NULL; + } + | variables_def + +variables_def: + variable_def + { + if (!($$ = make_empty_list(ctx))) + YYABORT; + list_add_head($$, &$1->entry); + } + | variables_def ',' variable_def + { + $$ = $1; + list_add_tail($$, &$3->entry); + } + +variable_decl: + any_identifier arrays colon_attribute + { + $$ = hlsl_alloc(ctx, sizeof(*$$)); + $$->loc = @1; + $$->name = $1; + $$->arrays = $2; + $$->semantic = $3.semantic; + $$->reg_reservation = $3.reg_reservation; + } + +state: + any_identifier '=' expr ';' + { + vkd3d_free($1); + hlsl_free_instr_list($3); + } + +state_block_start: + %empty + { + ctx->in_state_block = 1; + } + +state_block: + %empty + | state_block state + +variable_def: + variable_decl + | variable_decl '=' complex_initializer + { + $$ = $1; + $$->initializer = $3; + } + | variable_decl '{' state_block_start state_block '}' + { + $$ = $1; + ctx->in_state_block = 0; + } + +arrays: + %empty + { + $$.sizes = NULL; + $$.count = 0; + } + | '[' expr ']' arrays + { + unsigned int size = evaluate_static_expression(node_from_list($2)); + uint32_t *new_array; + + destroy_instr_list($2); + + $$ = $4; + + if (!size) + { + hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE, + "Array size is not a positive integer constant."); + vkd3d_free($$.sizes); + YYABORT; + } + + if (size > 65536) + { + hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE, + "Array size %u is not between 1 and 65536.", size); + vkd3d_free($$.sizes); + YYABORT; + } + + if (!(new_array = hlsl_realloc(ctx, $$.sizes, ($$.count + 1) * sizeof(*new_array)))) + { + vkd3d_free($$.sizes); + YYABORT; + } + $$.sizes = new_array; + $$.sizes[$$.count++] = size; + } + | '[' ']' arrays + { + uint32_t *new_array; + + $$ = $3; + + if (!(new_array = hlsl_realloc(ctx, $$.sizes, ($$.count + 1) * sizeof(*new_array)))) + { + vkd3d_free($$.sizes); + YYABORT; + } + + $$.sizes = new_array; + $$.sizes[$$.count++] = HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT; + } + +var_modifiers: + %empty + { + $$ = 0; + } + | KW_EXTERN var_modifiers + { + $$ = add_modifiers(ctx, $2, HLSL_STORAGE_EXTERN, @1); + } + | KW_NOINTERPOLATION var_modifiers + { + $$ = add_modifiers(ctx, $2, HLSL_STORAGE_NOINTERPOLATION, @1); + } + | KW_PRECISE var_modifiers + { + $$ = add_modifiers(ctx, $2, HLSL_MODIFIER_PRECISE, @1); + } + | KW_SHARED var_modifiers + { + $$ = add_modifiers(ctx, $2, HLSL_STORAGE_SHARED, @1); + } + | KW_GROUPSHARED var_modifiers + { + $$ = add_modifiers(ctx, $2, HLSL_STORAGE_GROUPSHARED, @1); + } + | KW_STATIC var_modifiers + { + $$ = add_modifiers(ctx, $2, HLSL_STORAGE_STATIC, @1); + } + | KW_UNIFORM var_modifiers + { + $$ = add_modifiers(ctx, $2, HLSL_STORAGE_UNIFORM, @1); + } + | KW_VOLATILE var_modifiers + { + $$ = add_modifiers(ctx, $2, HLSL_MODIFIER_VOLATILE, @1); + } + | KW_CONST var_modifiers + { + $$ = add_modifiers(ctx, $2, HLSL_MODIFIER_CONST, @1); + } + | KW_ROW_MAJOR var_modifiers + { + $$ = add_modifiers(ctx, $2, HLSL_MODIFIER_ROW_MAJOR, @1); + } + | KW_COLUMN_MAJOR var_modifiers + { + $$ = add_modifiers(ctx, $2, HLSL_MODIFIER_COLUMN_MAJOR, @1); + } + | KW_IN var_modifiers + { + $$ = add_modifiers(ctx, $2, HLSL_STORAGE_IN, @1); + } + | KW_OUT var_modifiers + { + $$ = add_modifiers(ctx, $2, HLSL_STORAGE_OUT, @1); + } + | KW_INOUT var_modifiers + { + $$ = add_modifiers(ctx, $2, HLSL_STORAGE_IN | HLSL_STORAGE_OUT, @1); + } + + +complex_initializer: + initializer_expr + { + $$.args_count = 1; + if (!($$.args = hlsl_alloc(ctx, sizeof(*$$.args)))) + { + destroy_instr_list($1); + YYABORT; + } + $$.args[0] = node_from_list($1); + $$.instrs = $1; + $$.braces = false; + } + | '{' complex_initializer_list '}' + { + $$ = $2; + $$.braces = true; + } + | '{' complex_initializer_list ',' '}' + { + $$ = $2; + $$.braces = true; + } + +complex_initializer_list: + complex_initializer + | complex_initializer_list ',' complex_initializer + { + struct hlsl_ir_node **new_args; + unsigned int i; + + $$ = $1; + if (!(new_args = hlsl_realloc(ctx, $$.args, ($$.args_count + $3.args_count) * sizeof(*$$.args)))) + { + free_parse_initializer(&$$); + free_parse_initializer(&$3); + YYABORT; + } + $$.args = new_args; + for (i = 0; i < $3.args_count; ++i) + $$.args[$$.args_count++] = $3.args[i]; + list_move_tail($$.instrs, $3.instrs); + free_parse_initializer(&$3); + } + +initializer_expr: + assignment_expr + +initializer_expr_list: + initializer_expr + { + $$.args_count = 1; + if (!($$.args = hlsl_alloc(ctx, sizeof(*$$.args)))) + { + destroy_instr_list($1); + YYABORT; + } + $$.args[0] = node_from_list($1); + $$.instrs = $1; + $$.braces = false; + } + | initializer_expr_list ',' initializer_expr + { + struct hlsl_ir_node **new_args; + + $$ = $1; + if (!(new_args = hlsl_realloc(ctx, $$.args, ($$.args_count + 1) * sizeof(*$$.args)))) + { + free_parse_initializer(&$$); + destroy_instr_list($3); + YYABORT; + } + $$.args = new_args; + $$.args[$$.args_count++] = node_from_list($3); + list_move_tail($$.instrs, $3); + vkd3d_free($3); + } + +boolean: + KW_TRUE + { + $$ = true; + } + | KW_FALSE + { + $$ = false; + } + +statement_list: + statement + | statement_list statement + { + $$ = $1; + list_move_tail($$, $2); + vkd3d_free($2); + } + +statement: + declaration_statement + | expr_statement + | compound_statement + | jump_statement + | selection_statement + | loop_statement + +jump_statement: + KW_RETURN expr ';' + { + if (!add_return(ctx, $2, node_from_list($2), @1)) + YYABORT; + $$ = $2; + } + | KW_RETURN ';' + { + if (!($$ = make_empty_list(ctx))) + YYABORT; + if (!add_return(ctx, $$, NULL, @1)) + YYABORT; + } + +selection_statement: + KW_IF '(' expr ')' if_body + { + struct hlsl_ir_node *condition = node_from_list($3); + struct hlsl_ir_if *instr; + + if (!(instr = hlsl_new_if(ctx, condition, @1))) + YYABORT; + list_move_tail(&instr->then_instrs.instrs, $5.then_instrs); + if ($5.else_instrs) + list_move_tail(&instr->else_instrs.instrs, $5.else_instrs); + vkd3d_free($5.then_instrs); + vkd3d_free($5.else_instrs); + if (condition->data_type->dimx > 1 || condition->data_type->dimy > 1) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, condition->data_type))) + hlsl_error(ctx, &instr->node.loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "if condition type %s is not scalar.", string->buffer); + hlsl_release_string_buffer(ctx, string); + } + $$ = $3; + list_add_tail($$, &instr->node.entry); + } + +if_body: + statement + { + $$.then_instrs = $1; + $$.else_instrs = NULL; + } + | statement KW_ELSE statement + { + $$.then_instrs = $1; + $$.else_instrs = $3; + } + +loop_statement: + KW_WHILE '(' expr ')' statement + { + $$ = create_loop(ctx, LOOP_WHILE, NULL, $3, NULL, $5, @1); + } + | KW_DO statement KW_WHILE '(' expr ')' ';' + { + $$ = create_loop(ctx, LOOP_DO_WHILE, NULL, $5, NULL, $2, @1); + } + | KW_FOR '(' scope_start expr_statement expr_statement expr_optional ')' statement + { + $$ = create_loop(ctx, LOOP_FOR, $4, $5, $6, $8, @1); + hlsl_pop_scope(ctx); + } + | KW_FOR '(' scope_start declaration expr_statement expr_optional ')' statement + { + $$ = create_loop(ctx, LOOP_FOR, $4, $5, $6, $8, @1); + hlsl_pop_scope(ctx); + } + +expr_optional: + %empty + { + if (!($$ = make_empty_list(ctx))) + YYABORT; + } + | expr + +expr_statement: + expr_optional ';' + { + $$ = $1; + } + +func_arguments: + %empty + { + $$.args = NULL; + $$.args_count = 0; + if (!($$.instrs = make_empty_list(ctx))) + YYABORT; + $$.braces = false; + } + | initializer_expr_list + +primary_expr: + C_FLOAT + { + struct hlsl_ir_constant *c; + + if (!(c = hlsl_new_float_constant(ctx, $1, &@1))) + YYABORT; + if (!($$ = make_list(ctx, &c->node))) + YYABORT; + } + | C_INTEGER + { + struct hlsl_ir_constant *c; + + if (!(c = hlsl_new_int_constant(ctx, $1, &@1))) + YYABORT; + if (!($$ = make_list(ctx, &c->node))) + YYABORT; + } + | boolean + { + struct hlsl_ir_constant *c; + + if (!(c = hlsl_new_bool_constant(ctx, $1, &@1))) + YYABORT; + if (!($$ = make_list(ctx, &c->node))) + { + hlsl_free_instr(&c->node); + YYABORT; + } + } + | VAR_IDENTIFIER + { + struct hlsl_ir_load *load; + struct hlsl_ir_var *var; + + if (!(var = hlsl_get_var(ctx->cur_scope, $1))) + { + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Variable \"%s\" is not defined.", $1); + YYABORT; + } + if (!(load = hlsl_new_var_load(ctx, var, @1))) + YYABORT; + if (!($$ = make_list(ctx, &load->node))) + YYABORT; + } + | '(' expr ')' + { + $$ = $2; + } + | var_identifier '(' func_arguments ')' + { + if (!($$ = add_call(ctx, $1, &$3, &@1))) + { + vkd3d_free($1); + YYABORT; + } + vkd3d_free($1); + } + | NEW_IDENTIFIER + { + if (ctx->in_state_block) + { + struct hlsl_ir_load *load; + struct hlsl_ir_var *var; + + if (!(var = hlsl_new_synthetic_var(ctx, "state_block_expr", + hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), &@1))) + YYABORT; + if (!(load = hlsl_new_var_load(ctx, var, @1))) + YYABORT; + if (!($$ = make_list(ctx, &load->node))) + YYABORT; + } + else + { + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Identifier \"%s\" is not declared.", $1); + YYABORT; + } + } + +postfix_expr: + primary_expr + | postfix_expr OP_INC + { + if (!add_increment(ctx, $1, false, true, @2)) + { + destroy_instr_list($1); + YYABORT; + } + $$ = $1; + } + | postfix_expr OP_DEC + { + if (!add_increment(ctx, $1, true, true, @2)) + { + destroy_instr_list($1); + YYABORT; + } + $$ = $1; + } + | postfix_expr '.' any_identifier + { + struct hlsl_ir_node *node = node_from_list($1); + + if (node->data_type->type == HLSL_CLASS_STRUCT) + { + struct hlsl_type *type = node->data_type; + const struct hlsl_struct_field *field; + unsigned int field_idx = 0; + + if (!(field = get_struct_field(type->e.record.fields, type->e.record.field_count, $3))) + { + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Field \"%s\" is not defined.", $3); + YYABORT; + } + + field_idx = field - type->e.record.fields; + if (!add_record_load(ctx, $1, node, field_idx, @2)) + YYABORT; + $$ = $1; + } + else if (node->data_type->type <= HLSL_CLASS_LAST_NUMERIC) + { + struct hlsl_ir_swizzle *swizzle; + + if (!(swizzle = get_swizzle(ctx, node, $3, &@3))) + { + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Invalid swizzle \"%s\".", $3); + YYABORT; + } + list_add_tail($1, &swizzle->node.entry); + $$ = $1; + } + else + { + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Invalid subscript \"%s\".", $3); + YYABORT; + } + } + | postfix_expr '[' expr ']' + { + struct hlsl_ir_node *array = node_from_list($1), *index = node_from_list($3); + + list_move_tail($1, $3); + vkd3d_free($3); + + if (!add_array_load(ctx, $1, array, index, &@2)) + { + destroy_instr_list($1); + YYABORT; + } + $$ = $1; + } + + /* var_modifiers is necessary to avoid shift/reduce conflicts. */ + | var_modifiers type '(' initializer_expr_list ')' + { + if ($1) + { + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Modifiers are not allowed on constructors."); + free_parse_initializer(&$4); + YYABORT; + } + if ($2->type > HLSL_CLASS_LAST_NUMERIC) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, $2))) + hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Constructor data type %s is not numeric.", string->buffer); + hlsl_release_string_buffer(ctx, string); + free_parse_initializer(&$4); + YYABORT; + } + if ($2->dimx * $2->dimy != initializer_size(&$4)) + { + hlsl_error(ctx, &@4, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Expected %u components in constructor, but got %u.", + $2->dimx * $2->dimy, initializer_size(&$4)); + free_parse_initializer(&$4); + YYABORT; + } + + if (!($$ = add_constructor(ctx, $2, &$4, @2))) + { + free_parse_initializer(&$4); + YYABORT; + } + } + | postfix_expr '.' any_identifier '(' func_arguments ')' + { + struct hlsl_ir_node *object = node_from_list($1); + + list_move_tail($1, $5.instrs); + vkd3d_free($5.instrs); + + if (!add_method_call(ctx, $1, object, $3, &$5, &@3)) + { + hlsl_free_instr_list($1); + vkd3d_free($5.args); + YYABORT; + } + vkd3d_free($5.args); + $$ = $1; + } + +unary_expr: + postfix_expr + | OP_INC unary_expr + { + if (!add_increment(ctx, $2, false, false, @1)) + { + destroy_instr_list($2); + YYABORT; + } + $$ = $2; + } + | OP_DEC unary_expr + { + if (!add_increment(ctx, $2, true, false, @1)) + { + destroy_instr_list($2); + YYABORT; + } + $$ = $2; + } + | '+' unary_expr + { + $$ = $2; + } + | '-' unary_expr + { + add_unary_arithmetic_expr(ctx, $2, HLSL_OP1_NEG, node_from_list($2), &@1); + $$ = $2; + } + | '~' unary_expr + { + add_unary_bitwise_expr(ctx, $2, HLSL_OP1_BIT_NOT, node_from_list($2), &@1); + $$ = $2; + } + | '!' unary_expr + { + add_unary_logical_expr(ctx, $2, HLSL_OP1_LOGIC_NOT, node_from_list($2), &@1); + $$ = $2; + } + /* var_modifiers is necessary to avoid shift/reduce conflicts. */ + | '(' var_modifiers type arrays ')' unary_expr + { + struct hlsl_type *src_type = node_from_list($6)->data_type; + struct hlsl_type *dst_type; + unsigned int i; + + if ($2) + { + hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Modifiers are not allowed on casts."); + YYABORT; + } + + dst_type = $3; + for (i = 0; i < $4.count; ++i) + { + if ($4.sizes[i] == HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT) + { + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Implicit size arrays not allowed in casts."); + } + dst_type = hlsl_new_array_type(ctx, dst_type, $4.sizes[i]); + } + + if (!explicit_compatible_data_types(ctx, src_type, dst_type)) + { + struct vkd3d_string_buffer *src_string, *dst_string; + + src_string = hlsl_type_to_string(ctx, src_type); + dst_string = hlsl_type_to_string(ctx, dst_type); + if (src_string && dst_string) + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Can't cast from %s to %s.", + src_string->buffer, dst_string->buffer); + hlsl_release_string_buffer(ctx, src_string); + hlsl_release_string_buffer(ctx, dst_string); + YYABORT; + } + + if (!add_cast(ctx, $6, node_from_list($6), dst_type, &@3)) + { + hlsl_free_instr_list($6); + YYABORT; + } + $$ = $6; + } + +mul_expr: + unary_expr + | mul_expr '*' unary_expr + { + $$ = add_binary_arithmetic_expr_merge(ctx, $1, $3, HLSL_OP2_MUL, @2); + } + | mul_expr '/' unary_expr + { + $$ = add_binary_arithmetic_expr_merge(ctx, $1, $3, HLSL_OP2_DIV, @2); + } + | mul_expr '%' unary_expr + { + $$ = add_binary_arithmetic_expr_merge(ctx, $1, $3, HLSL_OP2_MOD, @2); + } + +add_expr: + mul_expr + | add_expr '+' mul_expr + { + $$ = add_binary_arithmetic_expr_merge(ctx, $1, $3, HLSL_OP2_ADD, @2); + } + | add_expr '-' mul_expr + { + struct hlsl_ir_node *neg; + + if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, node_from_list($3), @2))) + YYABORT; + list_add_tail($3, &neg->entry); + $$ = add_binary_arithmetic_expr_merge(ctx, $1, $3, HLSL_OP2_ADD, @2); + } + +shift_expr: + add_expr + | shift_expr OP_LEFTSHIFT add_expr + { + $$ = add_binary_shift_expr_merge(ctx, $1, $3, HLSL_OP2_LSHIFT, &@2); + } + | shift_expr OP_RIGHTSHIFT add_expr + { + $$ = add_binary_shift_expr_merge(ctx, $1, $3, HLSL_OP2_RSHIFT, &@2); + } + +relational_expr: + shift_expr + | relational_expr '<' shift_expr + { + $$ = add_binary_comparison_expr_merge(ctx, $1, $3, HLSL_OP2_LESS, @2); + } + | relational_expr '>' shift_expr + { + $$ = add_binary_comparison_expr_merge(ctx, $3, $1, HLSL_OP2_LESS, @2); + } + | relational_expr OP_LE shift_expr + { + $$ = add_binary_comparison_expr_merge(ctx, $3, $1, HLSL_OP2_GEQUAL, @2); + } + | relational_expr OP_GE shift_expr + { + $$ = add_binary_comparison_expr_merge(ctx, $1, $3, HLSL_OP2_GEQUAL, @2); + } + +equality_expr: + relational_expr + | equality_expr OP_EQ relational_expr + { + $$ = add_binary_comparison_expr_merge(ctx, $1, $3, HLSL_OP2_EQUAL, @2); + } + | equality_expr OP_NE relational_expr + { + $$ = add_binary_comparison_expr_merge(ctx, $1, $3, HLSL_OP2_NEQUAL, @2); + } + +bitand_expr: + equality_expr + | bitand_expr '&' equality_expr + { + $$ = add_binary_bitwise_expr_merge(ctx, $1, $3, HLSL_OP2_BIT_AND, &@2); + } + +bitxor_expr: + bitand_expr + | bitxor_expr '^' bitand_expr + { + $$ = add_binary_bitwise_expr_merge(ctx, $1, $3, HLSL_OP2_BIT_XOR, &@2); + } + +bitor_expr: + bitxor_expr + | bitor_expr '|' bitxor_expr + { + $$ = add_binary_bitwise_expr_merge(ctx, $1, $3, HLSL_OP2_BIT_OR, &@2); + } + +logicand_expr: + bitor_expr + | logicand_expr OP_AND bitor_expr + { + $$ = add_binary_logical_expr_merge(ctx, $1, $3, HLSL_OP2_LOGIC_AND, &@2); + } + +logicor_expr: + logicand_expr + | logicor_expr OP_OR logicand_expr + { + $$ = add_binary_logical_expr_merge(ctx, $1, $3, HLSL_OP2_LOGIC_OR, &@2); + } + +conditional_expr: + logicor_expr + | logicor_expr '?' expr ':' assignment_expr + { + hlsl_fixme(ctx, &@$, "Ternary operator."); + } + +assignment_expr: + + conditional_expr + | unary_expr assign_op assignment_expr + { + struct hlsl_ir_node *lhs = node_from_list($1), *rhs = node_from_list($3); + + if (lhs->data_type->modifiers & HLSL_MODIFIER_CONST) + { + hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_MODIFIES_CONST, "Statement modifies a const expression."); + YYABORT; + } + list_move_tail($3, $1); + vkd3d_free($1); + if (!add_assignment(ctx, $3, lhs, $2, rhs)) + YYABORT; + $$ = $3; + } + +assign_op: + '=' + { + $$ = ASSIGN_OP_ASSIGN; + } + | OP_ADDASSIGN + { + $$ = ASSIGN_OP_ADD; + } + | OP_SUBASSIGN + { + $$ = ASSIGN_OP_SUB; + } + | OP_MULASSIGN + { + $$ = ASSIGN_OP_MUL; + } + | OP_DIVASSIGN + { + $$ = ASSIGN_OP_DIV; + } + | OP_MODASSIGN + { + $$ = ASSIGN_OP_MOD; + } + | OP_LEFTSHIFTASSIGN + { + $$ = ASSIGN_OP_LSHIFT; + } + | OP_RIGHTSHIFTASSIGN + { + $$ = ASSIGN_OP_RSHIFT; + } + | OP_ANDASSIGN + { + $$ = ASSIGN_OP_AND; + } + | OP_ORASSIGN + { + $$ = ASSIGN_OP_OR; + } + | OP_XORASSIGN + { + $$ = ASSIGN_OP_XOR; + } + +expr: + assignment_expr + | expr ',' assignment_expr + { + $$ = $1; + list_move_tail($$, $3); + vkd3d_free($3); + } diff --git a/dll/directx/wine/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/dll/directx/wine/vkd3d/libs/vkd3d-shader/hlsl_codegen.c new file mode 100644 index 0000000000000..ab59875738c6c --- /dev/null +++ b/dll/directx/wine/vkd3d/libs/vkd3d-shader/hlsl_codegen.c @@ -0,0 +1,3360 @@ +/* + * HLSL optimization and code generation + * + * Copyright 2019-2020 Zebediah Figura for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "hlsl.h" +#include + +/* TODO: remove when no longer needed, only used for new_offset_instr_from_deref() */ +static struct hlsl_ir_node *new_offset_from_path_index(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_type *type, struct hlsl_ir_node *offset, struct hlsl_ir_node *idx, + enum hlsl_regset regset, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *idx_offset = NULL; + struct hlsl_ir_constant *c; + + list_init(&block->instrs); + + switch (type->type) + { + case HLSL_CLASS_VECTOR: + idx_offset = idx; + break; + + case HLSL_CLASS_MATRIX: + { + if (!(c = hlsl_new_uint_constant(ctx, 4, loc))) + return NULL; + list_add_tail(&block->instrs, &c->node.entry); + + if (!(idx_offset = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, &c->node, idx))) + return NULL; + list_add_tail(&block->instrs, &idx_offset->entry); + + break; + } + + case HLSL_CLASS_ARRAY: + { + unsigned int size = hlsl_type_get_array_element_reg_size(type->e.array.type, regset); + + if (!(c = hlsl_new_uint_constant(ctx, size, loc))) + return NULL; + list_add_tail(&block->instrs, &c->node.entry); + + if (!(idx_offset = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, &c->node, idx))) + return NULL; + list_add_tail(&block->instrs, &idx_offset->entry); + + break; + } + + case HLSL_CLASS_STRUCT: + { + unsigned int field_idx = hlsl_ir_constant(idx)->value[0].u; + struct hlsl_struct_field *field = &type->e.record.fields[field_idx]; + + if (!(c = hlsl_new_uint_constant(ctx, field->reg_offset[regset], loc))) + return NULL; + list_add_tail(&block->instrs, &c->node.entry); + + idx_offset = &c->node; + + break; + } + + default: + vkd3d_unreachable(); + } + + if (offset) + { + if (!(idx_offset = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, offset, idx_offset))) + return NULL; + list_add_tail(&block->instrs, &idx_offset->entry); + } + + return idx_offset; +} + +/* TODO: remove when no longer needed, only used for replace_deref_path_with_offset() */ +static struct hlsl_ir_node *new_offset_instr_from_deref(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_deref *deref, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *offset = NULL; + struct hlsl_type *type; + unsigned int i; + + list_init(&block->instrs); + + assert(deref->var); + type = deref->var->data_type; + + for (i = 0; i < deref->path_len; ++i) + { + struct hlsl_block idx_block; + + if (!(offset = new_offset_from_path_index(ctx, &idx_block, type, offset, deref->path[i].node, + deref->offset_regset, loc))) + return NULL; + + list_move_tail(&block->instrs, &idx_block.instrs); + + type = hlsl_get_element_type_from_path_index(ctx, type, deref->path[i].node); + } + + return offset; +} + +/* TODO: remove when no longer needed, only used for transform_deref_paths_into_offsets() */ +static void replace_deref_path_with_offset(struct hlsl_ctx *ctx, struct hlsl_deref *deref, + struct hlsl_ir_node *instr) +{ + const struct hlsl_type *type; + struct hlsl_ir_node *offset; + struct hlsl_block block; + + if (!deref->var) + return; + + /* register offsets shouldn't be used before this point is reached. */ + assert(!deref->offset.node); + + type = hlsl_deref_get_type(ctx, deref); + + /* Instructions that directly refer to structs or arrays (instead of single-register components) + * are removed later by dce. So it is not a problem to just cleanup their derefs. */ + if (type->type == HLSL_CLASS_STRUCT || type->type == HLSL_CLASS_ARRAY) + { + hlsl_cleanup_deref(deref); + return; + } + + deref->offset_regset = hlsl_type_get_regset(type); + + if (!(offset = new_offset_instr_from_deref(ctx, &block, deref, &instr->loc))) + return; + list_move_before(&instr->entry, &block.instrs); + + hlsl_cleanup_deref(deref); + hlsl_src_from_node(&deref->offset, offset); +} + +/* TODO: remove when no longer needed. */ +static bool transform_deref_paths_into_offsets(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + switch(instr->type) + { + case HLSL_IR_LOAD: + replace_deref_path_with_offset(ctx, &hlsl_ir_load(instr)->src, instr); + return true; + + case HLSL_IR_STORE: + replace_deref_path_with_offset(ctx, &hlsl_ir_store(instr)->lhs, instr); + return true; + + case HLSL_IR_RESOURCE_LOAD: + replace_deref_path_with_offset(ctx, &hlsl_ir_resource_load(instr)->resource, instr); + replace_deref_path_with_offset(ctx, &hlsl_ir_resource_load(instr)->sampler, instr); + return true; + + case HLSL_IR_RESOURCE_STORE: + replace_deref_path_with_offset(ctx, &hlsl_ir_resource_store(instr)->resource, instr); + return true; + + default: + return false; + } + return false; +} + +/* Split uniforms into two variables representing the constant and temp + * registers, and copy the former to the latter, so that writes to uniforms + * work. */ +static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *temp) +{ + struct vkd3d_string_buffer *name; + struct hlsl_ir_var *uniform; + struct hlsl_ir_store *store; + struct hlsl_ir_load *load; + + /* Use the synthetic name for the temp, rather than the uniform, so that we + * can write the uniform name into the shader reflection data. */ + + if (!(uniform = hlsl_new_var(ctx, temp->name, temp->data_type, + temp->loc, NULL, temp->storage_modifiers, &temp->reg_reservation))) + return; + list_add_before(&temp->scope_entry, &uniform->scope_entry); + list_add_tail(&ctx->extern_vars, &uniform->extern_entry); + uniform->is_uniform = 1; + uniform->is_param = temp->is_param; + uniform->buffer = temp->buffer; + + if (!(name = hlsl_get_string_buffer(ctx))) + return; + vkd3d_string_buffer_printf(name, "", temp->name); + temp->name = hlsl_strdup(ctx, name->buffer); + hlsl_release_string_buffer(ctx, name); + + if (!(load = hlsl_new_var_load(ctx, uniform, temp->loc))) + return; + list_add_head(instrs, &load->node.entry); + + if (!(store = hlsl_new_simple_store(ctx, temp, &load->node))) + return; + list_add_after(&load->node.entry, &store->node.entry); +} + +static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, + struct hlsl_type *type, unsigned int modifiers, const struct hlsl_semantic *semantic, bool output) +{ + struct hlsl_semantic new_semantic; + struct vkd3d_string_buffer *name; + struct hlsl_ir_var *ext_var; + + if (!(name = hlsl_get_string_buffer(ctx))) + return NULL; + vkd3d_string_buffer_printf(name, "<%s-%s%u>", output ? "output" : "input", semantic->name, semantic->index); + if (!(new_semantic.name = hlsl_strdup(ctx, semantic->name))) + { + hlsl_release_string_buffer(ctx, name); + return NULL; + } + new_semantic.index = semantic->index; + if (!(ext_var = hlsl_new_var(ctx, hlsl_strdup(ctx, name->buffer), + type, var->loc, &new_semantic, modifiers, NULL))) + { + hlsl_release_string_buffer(ctx, name); + hlsl_cleanup_semantic(&new_semantic); + return NULL; + } + hlsl_release_string_buffer(ctx, name); + if (output) + ext_var->is_output_semantic = 1; + else + ext_var->is_input_semantic = 1; + ext_var->is_param = var->is_param; + list_add_before(&var->scope_entry, &ext_var->scope_entry); + list_add_tail(&ctx->extern_vars, &ext_var->extern_entry); + + return ext_var; +} + +static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_load *lhs, + unsigned int modifiers, const struct hlsl_semantic *semantic) +{ + struct hlsl_type *type = lhs->node.data_type, *vector_type; + struct hlsl_ir_var *var = lhs->src.var; + unsigned int i; + + vector_type = hlsl_get_vector_type(ctx, type->base_type, hlsl_type_minor_size(type)); + + for (i = 0; i < hlsl_type_major_size(type); ++i) + { + struct hlsl_semantic semantic_copy = *semantic; + struct hlsl_ir_store *store; + struct hlsl_ir_constant *c; + struct hlsl_ir_var *input; + struct hlsl_ir_load *load; + + semantic_copy.index = semantic->index + i; + + if (!(input = add_semantic_var(ctx, var, vector_type, modifiers, &semantic_copy, false))) + return; + + if (!(load = hlsl_new_var_load(ctx, input, var->loc))) + return; + list_add_after(&lhs->node.entry, &load->node.entry); + + if (type->type == HLSL_CLASS_MATRIX) + { + if (!(c = hlsl_new_uint_constant(ctx, i, &var->loc))) + return; + list_add_after(&load->node.entry, &c->node.entry); + + if (!(store = hlsl_new_store_index(ctx, &lhs->src, &c->node, &load->node, 0, &var->loc))) + return; + list_add_after(&c->node.entry, &store->node.entry); + } + else + { + assert(i == 0); + + if (!(store = hlsl_new_store_index(ctx, &lhs->src, NULL, &load->node, 0, &var->loc))) + return; + list_add_after(&load->node.entry, &store->node.entry); + } + } +} + +static void prepend_input_struct_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_load *lhs) +{ + struct hlsl_type *type = lhs->node.data_type; + struct hlsl_ir_var *var = lhs->src.var; + size_t i; + + for (i = 0; i < type->e.record.field_count; ++i) + { + const struct hlsl_struct_field *field = &type->e.record.fields[i]; + struct hlsl_ir_load *field_load; + struct hlsl_ir_constant *c; + + if (!(c = hlsl_new_uint_constant(ctx, i, &var->loc))) + return; + list_add_after(&lhs->node.entry, &c->node.entry); + + /* This redundant load is expected to be deleted later by DCE. */ + if (!(field_load = hlsl_new_load_index(ctx, &lhs->src, &c->node, &var->loc))) + return; + list_add_after(&c->node.entry, &field_load->node.entry); + + if (field->type->type == HLSL_CLASS_STRUCT) + prepend_input_struct_copy(ctx, instrs, field_load); + else if (field->semantic.name) + prepend_input_copy(ctx, instrs, field_load, field->storage_modifiers, &field->semantic); + else + hlsl_error(ctx, &field->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, + "Field '%s' is missing a semantic.", field->name); + } +} + +/* Split inputs into two variables representing the semantic and temp registers, + * and copy the former to the latter, so that writes to input variables work. */ +static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var) +{ + struct hlsl_ir_load *load; + + /* This redundant load is expected to be deleted later by DCE. */ + if (!(load = hlsl_new_var_load(ctx, var, var->loc))) + return; + list_add_head(instrs, &load->node.entry); + + if (var->data_type->type == HLSL_CLASS_STRUCT) + prepend_input_struct_copy(ctx, instrs, load); + else if (var->semantic.name) + prepend_input_copy(ctx, instrs, load, var->storage_modifiers, &var->semantic); +} + +static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_load *rhs, + unsigned int modifiers, const struct hlsl_semantic *semantic) +{ + struct hlsl_type *type = rhs->node.data_type, *vector_type; + struct hlsl_ir_var *var = rhs->src.var; + unsigned int i; + + vector_type = hlsl_get_vector_type(ctx, type->base_type, hlsl_type_minor_size(type)); + + for (i = 0; i < hlsl_type_major_size(type); ++i) + { + struct hlsl_semantic semantic_copy = *semantic; + struct hlsl_ir_store *store; + struct hlsl_ir_constant *c; + struct hlsl_ir_var *output; + struct hlsl_ir_load *load; + + semantic_copy.index = semantic->index + i; + + if (!(output = add_semantic_var(ctx, var, vector_type, modifiers, &semantic_copy, true))) + return; + + if (type->type == HLSL_CLASS_MATRIX) + { + if (!(c = hlsl_new_uint_constant(ctx, i, &var->loc))) + return; + list_add_tail(instrs, &c->node.entry); + + if (!(load = hlsl_new_load_index(ctx, &rhs->src, &c->node, &var->loc))) + return; + list_add_tail(instrs, &load->node.entry); + } + else + { + assert(i == 0); + + if (!(load = hlsl_new_load_index(ctx, &rhs->src, NULL, &var->loc))) + return; + list_add_tail(instrs, &load->node.entry); + } + + if (!(store = hlsl_new_simple_store(ctx, output, &load->node))) + return; + list_add_tail(instrs, &store->node.entry); + } +} + +static void append_output_struct_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_load *rhs) +{ + struct hlsl_type *type = rhs->node.data_type; + struct hlsl_ir_var *var = rhs->src.var; + size_t i; + + for (i = 0; i < type->e.record.field_count; ++i) + { + const struct hlsl_struct_field *field = &type->e.record.fields[i]; + struct hlsl_ir_load *field_load; + struct hlsl_ir_constant *c; + + if (!(c = hlsl_new_uint_constant(ctx, i, &var->loc))) + return; + list_add_tail(instrs, &c->node.entry); + + /* This redundant load is expected to be deleted later by DCE. */ + if (!(field_load = hlsl_new_load_index(ctx, &rhs->src, &c->node, &var->loc))) + return; + list_add_tail(instrs, &field_load->node.entry); + + if (field->type->type == HLSL_CLASS_STRUCT) + append_output_struct_copy(ctx, instrs, field_load); + else if (field->semantic.name) + append_output_copy(ctx, instrs, field_load, field->storage_modifiers, &field->semantic); + else + hlsl_error(ctx, &field->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, + "Field '%s' is missing a semantic.", field->name); + } +} + +/* Split outputs into two variables representing the temp and semantic + * registers, and copy the former to the latter, so that reads from output + * variables work. */ +static void append_output_var_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var) +{ + struct hlsl_ir_load *load; + + /* This redundant load is expected to be deleted later by DCE. */ + if (!(load = hlsl_new_var_load(ctx, var, var->loc))) + return; + list_add_tail(instrs, &load->node.entry); + + if (var->data_type->type == HLSL_CLASS_STRUCT) + append_output_struct_copy(ctx, instrs, load); + else if (var->semantic.name) + append_output_copy(ctx, instrs, load, var->storage_modifiers, &var->semantic); +} + +static bool transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, struct hlsl_ir_node *, void *), + struct hlsl_block *block, void *context) +{ + struct hlsl_ir_node *instr, *next; + bool progress = false; + + LIST_FOR_EACH_ENTRY_SAFE(instr, next, &block->instrs, struct hlsl_ir_node, entry) + { + if (instr->type == HLSL_IR_IF) + { + struct hlsl_ir_if *iff = hlsl_ir_if(instr); + + progress |= transform_ir(ctx, func, &iff->then_instrs, context); + progress |= transform_ir(ctx, func, &iff->else_instrs, context); + } + else if (instr->type == HLSL_IR_LOOP) + progress |= transform_ir(ctx, func, &hlsl_ir_loop(instr)->body, context); + + progress |= func(ctx, instr, context); + } + + return progress; +} + +struct recursive_call_ctx +{ + const struct hlsl_ir_function_decl **backtrace; + size_t count, capacity; +}; + +static bool find_recursive_calls(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct recursive_call_ctx *call_ctx = context; + struct hlsl_ir_function_decl *decl; + const struct hlsl_ir_call *call; + size_t i; + + if (instr->type != HLSL_IR_CALL) + return false; + call = hlsl_ir_call(instr); + decl = call->decl; + + for (i = 0; i < call_ctx->count; ++i) + { + if (call_ctx->backtrace[i] == decl) + { + hlsl_error(ctx, &call->node.loc, VKD3D_SHADER_ERROR_HLSL_RECURSIVE_CALL, + "Recursive call to \"%s\".", decl->func->name); + /* Native returns E_NOTIMPL instead of E_FAIL here. */ + ctx->result = VKD3D_ERROR_NOT_IMPLEMENTED; + return false; + } + } + + if (!hlsl_array_reserve(ctx, (void **)&call_ctx->backtrace, &call_ctx->capacity, + call_ctx->count + 1, sizeof(*call_ctx->backtrace))) + return false; + call_ctx->backtrace[call_ctx->count++] = decl; + + transform_ir(ctx, find_recursive_calls, &decl->body, call_ctx); + + --call_ctx->count; + + return false; +} + +static void insert_early_return_break(struct hlsl_ctx *ctx, + struct hlsl_ir_function_decl *func, struct hlsl_ir_node *cf_instr) +{ + struct hlsl_ir_jump *jump; + struct hlsl_ir_load *load; + struct hlsl_ir_if *iff; + + if (!(load = hlsl_new_var_load(ctx, func->early_return_var, cf_instr->loc))) + return; + list_add_after(&cf_instr->entry, &load->node.entry); + + if (!(iff = hlsl_new_if(ctx, &load->node, cf_instr->loc))) + return; + list_add_after(&load->node.entry, &iff->node.entry); + + if (!(jump = hlsl_new_jump(ctx, HLSL_IR_JUMP_BREAK, cf_instr->loc))) + return; + list_add_tail(&iff->then_instrs.instrs, &jump->node.entry); +} + +/* Remove HLSL_IR_JUMP_RETURN calls by altering subsequent control flow. */ +static bool lower_return(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, + struct hlsl_block *block, bool in_loop) +{ + struct hlsl_ir_node *return_instr = NULL, *cf_instr = NULL; + struct hlsl_ir_node *instr, *next; + bool has_early_return = false; + + /* SM1 has no function calls. SM4 does, but native d3dcompiler inlines + * everything anyway. We are safest following suit. + * + * The basic idea is to keep track of whether the function has executed an + * early return in a synthesized boolean variable (func->early_return_var) + * and guard all code after the return on that variable being false. In the + * case of loops we also replace the return with a break. + * + * The following algorithm loops over instructions in a block, recursing + * into inferior CF blocks, until it hits one of the following two things: + * + * - A return statement. In this case, we remove everything after the return + * statement in this block. We have to stop and do this in a separate + * loop, because instructions must be deleted in reverse order (due to + * def-use chains.) + * + * If we're inside of a loop CF block, we can instead just turn the + * return into a break, which offers the right semantics—except that it + * won't break out of nested loops. + * + * - A CF block which contains a return statement. After calling + * lower_return() on the CF block body, we stop, pull out everything after + * the CF instruction, shove it into an if block, and then lower that if + * block. + * + * (We could return a "did we make progress" boolean like transform_ir() + * and run this pass multiple times, but we already know the only block + * that still needs to be addressed, so there's not much point.) + * + * If we're inside of a loop CF block, we again do things differently. We + * already turned any returns into breaks. If the block we just processed + * was conditional, then "break" did our work for us. If it was a loop, + * we need to propagate that break to the outer loop. + * + * We return true if there was an early return anywhere in the block we just + * processed (including CF contained inside that block). + */ + + LIST_FOR_EACH_ENTRY_SAFE(instr, next, &block->instrs, struct hlsl_ir_node, entry) + { + if (instr->type == HLSL_IR_CALL) + { + struct hlsl_ir_call *call = hlsl_ir_call(instr); + + lower_return(ctx, call->decl, &call->decl->body, false); + } + else if (instr->type == HLSL_IR_IF) + { + struct hlsl_ir_if *iff = hlsl_ir_if(instr); + + has_early_return |= lower_return(ctx, func, &iff->then_instrs, in_loop); + has_early_return |= lower_return(ctx, func, &iff->else_instrs, in_loop); + + if (has_early_return) + { + /* If we're in a loop, we don't need to do anything here. We + * turned the return into a break, and that will already skip + * anything that comes after this "if" block. */ + if (!in_loop) + { + cf_instr = instr; + break; + } + } + } + else if (instr->type == HLSL_IR_LOOP) + { + has_early_return |= lower_return(ctx, func, &hlsl_ir_loop(instr)->body, true); + + if (has_early_return) + { + if (in_loop) + { + /* "instr" is a nested loop. "return" breaks out of all + * loops, so break out of this one too now. */ + insert_early_return_break(ctx, func, instr); + } + else + { + cf_instr = instr; + break; + } + } + } + else if (instr->type == HLSL_IR_JUMP) + { + struct hlsl_ir_jump *jump = hlsl_ir_jump(instr); + struct hlsl_ir_constant *constant; + struct hlsl_ir_store *store; + + if (jump->type == HLSL_IR_JUMP_RETURN) + { + if (!(constant = hlsl_new_bool_constant(ctx, true, &jump->node.loc))) + return false; + list_add_before(&jump->node.entry, &constant->node.entry); + + if (!(store = hlsl_new_simple_store(ctx, func->early_return_var, &constant->node))) + return false; + list_add_after(&constant->node.entry, &store->node.entry); + + has_early_return = true; + if (in_loop) + { + jump->type = HLSL_IR_JUMP_BREAK; + } + else + { + return_instr = instr; + break; + } + } + } + } + + if (return_instr) + { + /* If we're in a loop, we should have used "break" instead. */ + assert(!in_loop); + + /* Iterate in reverse, to avoid use-after-free when unlinking sources from + * the "uses" list. */ + LIST_FOR_EACH_ENTRY_SAFE_REV(instr, next, &block->instrs, struct hlsl_ir_node, entry) + { + list_remove(&instr->entry); + hlsl_free_instr(instr); + + /* Yes, we just freed it, but we're comparing pointers. */ + if (instr == return_instr) + break; + } + } + else if (cf_instr) + { + struct list *tail = list_tail(&block->instrs); + struct hlsl_ir_load *load; + struct hlsl_ir_node *not; + struct hlsl_ir_if *iff; + + /* If we're in a loop, we should have used "break" instead. */ + assert(!in_loop); + + if (tail == &cf_instr->entry) + return has_early_return; + + if (!(load = hlsl_new_var_load(ctx, func->early_return_var, cf_instr->loc))) + return false; + list_add_tail(&block->instrs, &load->node.entry); + + if (!(not = hlsl_new_unary_expr(ctx, HLSL_OP1_LOGIC_NOT, &load->node, cf_instr->loc))) + return false; + list_add_tail(&block->instrs, ¬->entry); + + if (!(iff = hlsl_new_if(ctx, not, cf_instr->loc))) + return false; + list_add_tail(&block->instrs, &iff->node.entry); + + list_move_slice_tail(&iff->then_instrs.instrs, list_next(&block->instrs, &cf_instr->entry), tail); + + lower_return(ctx, func, &iff->then_instrs, in_loop); + } + + return has_early_return; +} + +/* Remove HLSL_IR_CALL instructions by inlining them. */ +static bool lower_calls(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + const struct hlsl_ir_function_decl *decl; + struct hlsl_ir_call *call; + struct hlsl_block block; + + if (instr->type != HLSL_IR_CALL) + return false; + call = hlsl_ir_call(instr); + decl = call->decl; + + if (!decl->has_body) + hlsl_error(ctx, &call->node.loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, + "Function \"%s\" is not defined.", decl->func->name); + + list_init(&block.instrs); + if (!hlsl_clone_block(ctx, &block, &decl->body)) + return false; + list_move_before(&call->node.entry, &block.instrs); + + list_remove(&call->node.entry); + hlsl_free_instr(&call->node); + return true; +} + +/* Lower casts from vec1 to vecN to swizzles. */ +static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + const struct hlsl_type *src_type, *dst_type; + struct hlsl_type *dst_scalar_type; + struct hlsl_ir_expr *cast; + + if (instr->type != HLSL_IR_EXPR) + return false; + cast = hlsl_ir_expr(instr); + if (cast->op != HLSL_OP1_CAST) + return false; + src_type = cast->operands[0].node->data_type; + dst_type = cast->node.data_type; + + if (src_type->type <= HLSL_CLASS_VECTOR && dst_type->type <= HLSL_CLASS_VECTOR && src_type->dimx == 1) + { + struct hlsl_ir_node *replacement; + struct hlsl_ir_swizzle *swizzle; + struct hlsl_ir_expr *new_cast; + + dst_scalar_type = hlsl_get_scalar_type(ctx, dst_type->base_type); + /* We need to preserve the cast since it might be doing more than just + * turning the scalar into a vector. */ + if (!(new_cast = hlsl_new_cast(ctx, cast->operands[0].node, dst_scalar_type, &cast->node.loc))) + return false; + list_add_after(&cast->node.entry, &new_cast->node.entry); + replacement = &new_cast->node; + + if (dst_type->dimx != 1) + { + if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X), dst_type->dimx, replacement, &cast->node.loc))) + return false; + list_add_after(&new_cast->node.entry, &swizzle->node.entry); + replacement = &swizzle->node; + } + + hlsl_replace_node(&cast->node, replacement); + return true; + } + + return false; +} + +/* + * Copy propagation. The basic idea is to recognize instruction sequences of the + * form: + * + * 2: + * 3: v = @2 + * 4: load(v) + * + * and replace the load (@4) with the original instruction (@2). + * This works for multiple components, even if they're written using separate + * store instructions, as long as the rhs is the same in every case. This basic + * detection is implemented by copy_propagation_replace_with_single_instr(). + * + * In some cases, the load itself might not have a single source, but a + * subsequent swizzle might; hence we also try to replace swizzles of loads. + * + * We use the same infrastructure to implement a more specialized + * transformation. We recognize sequences of the form: + * + * 2: 123 + * 3: var.x = @2 + * 4: 345 + * 5: var.y = @4 + * 6: load(var.xy) + * + * where the load (@6) originates from different sources but that are constant, + * and transform it into a single constant vector. This latter pass is done + * by copy_propagation_replace_with_constant_vector(). + * + * This is a specialized form of vectorization, and begs the question: why does + * the load need to be involved? Can we just vectorize the stores into a single + * instruction, and then use "normal" copy-prop to convert that into a single + * vector? + * + * In general, the answer is yes, but there is a special case which necessitates + * the use of this transformation: non-uniform control flow. Copy-prop can act + * across some control flow, and in cases like the following: + * + * 2: 123 + * 3: var.x = @2 + * 4: if (...) + * 5: 456 + * 6: var.y = @5 + * 7: load(var.xy) + * + * we can copy-prop the load (@7) into a constant vector {123, 456}, but we + * cannot easily vectorize the stores @3 and @6. + */ + +enum copy_propagation_value_state +{ + VALUE_STATE_NOT_WRITTEN = 0, + VALUE_STATE_STATICALLY_WRITTEN, + VALUE_STATE_DYNAMICALLY_WRITTEN, +}; + +struct copy_propagation_value +{ + enum copy_propagation_value_state state; + struct hlsl_ir_node *node; + unsigned int component; +}; + +struct copy_propagation_var_def +{ + struct rb_entry entry; + struct hlsl_ir_var *var; + struct copy_propagation_value values[]; +}; + +struct copy_propagation_state +{ + struct rb_tree var_defs; + struct copy_propagation_state *parent; +}; + +static int copy_propagation_var_def_compare(const void *key, const struct rb_entry *entry) +{ + struct copy_propagation_var_def *var_def = RB_ENTRY_VALUE(entry, struct copy_propagation_var_def, entry); + uintptr_t key_int = (uintptr_t)key, entry_int = (uintptr_t)var_def->var; + + return (key_int > entry_int) - (key_int < entry_int); +} + +static void copy_propagation_var_def_destroy(struct rb_entry *entry, void *context) +{ + struct copy_propagation_var_def *var_def = RB_ENTRY_VALUE(entry, struct copy_propagation_var_def, entry); + + vkd3d_free(var_def); +} + +static struct copy_propagation_value *copy_propagation_get_value(const struct copy_propagation_state *state, + const struct hlsl_ir_var *var, unsigned int component) +{ + for (; state; state = state->parent) + { + struct rb_entry *entry = rb_get(&state->var_defs, var); + if (entry) + { + struct copy_propagation_var_def *var_def = RB_ENTRY_VALUE(entry, struct copy_propagation_var_def, entry); + unsigned int component_count = hlsl_type_component_count(var->data_type); + enum copy_propagation_value_state state; + + assert(component < component_count); + state = var_def->values[component].state; + + switch (state) + { + case VALUE_STATE_STATICALLY_WRITTEN: + return &var_def->values[component]; + case VALUE_STATE_DYNAMICALLY_WRITTEN: + return NULL; + case VALUE_STATE_NOT_WRITTEN: + break; + } + } + } + + return NULL; +} + +static struct copy_propagation_var_def *copy_propagation_create_var_def(struct hlsl_ctx *ctx, + struct copy_propagation_state *state, struct hlsl_ir_var *var) +{ + struct rb_entry *entry = rb_get(&state->var_defs, var); + struct copy_propagation_var_def *var_def; + unsigned int component_count = hlsl_type_component_count(var->data_type); + int res; + + if (entry) + return RB_ENTRY_VALUE(entry, struct copy_propagation_var_def, entry); + + if (!(var_def = hlsl_alloc(ctx, offsetof(struct copy_propagation_var_def, values[component_count])))) + return NULL; + + var_def->var = var; + + res = rb_put(&state->var_defs, var, &var_def->entry); + assert(!res); + + return var_def; +} + +static void copy_propagation_invalidate_variable(struct copy_propagation_var_def *var_def, + unsigned int comp, unsigned char writemask) +{ + unsigned i; + + TRACE("Invalidate variable %s[%u]%s.\n", var_def->var->name, comp, debug_hlsl_writemask(writemask)); + + for (i = 0; i < 4; ++i) + { + if (writemask & (1u << i)) + var_def->values[comp + i].state = VALUE_STATE_DYNAMICALLY_WRITTEN; + } +} + +static void copy_propagation_invalidate_variable_from_deref_recurse(struct hlsl_ctx *ctx, + struct copy_propagation_var_def *var_def, const struct hlsl_deref *deref, + struct hlsl_type *type, unsigned int depth, unsigned int comp_start, unsigned char writemask) +{ + unsigned int i, subtype_comp_count; + struct hlsl_ir_node *path_node; + struct hlsl_type *subtype; + + if (depth == deref->path_len) + { + copy_propagation_invalidate_variable(var_def, comp_start, writemask); + return; + } + + path_node = deref->path[depth].node; + subtype = hlsl_get_element_type_from_path_index(ctx, type, path_node); + + if (type->type == HLSL_CLASS_STRUCT) + { + unsigned int idx = hlsl_ir_constant(path_node)->value[0].u; + + for (i = 0; i < idx; ++i) + comp_start += hlsl_type_component_count(type->e.record.fields[i].type); + + copy_propagation_invalidate_variable_from_deref_recurse(ctx, var_def, deref, subtype, + depth + 1, comp_start, writemask); + } + else + { + subtype_comp_count = hlsl_type_component_count(subtype); + + if (path_node->type == HLSL_IR_CONSTANT) + { + copy_propagation_invalidate_variable_from_deref_recurse(ctx, var_def, deref, subtype, + depth + 1, hlsl_ir_constant(path_node)->value[0].u * subtype_comp_count, writemask); + } + else + { + for (i = 0; i < hlsl_type_element_count(type); ++i) + { + copy_propagation_invalidate_variable_from_deref_recurse(ctx, var_def, deref, subtype, + depth + 1, i * subtype_comp_count, writemask); + } + } + } +} + +static void copy_propagation_invalidate_variable_from_deref(struct hlsl_ctx *ctx, + struct copy_propagation_var_def *var_def, const struct hlsl_deref *deref, unsigned char writemask) +{ + copy_propagation_invalidate_variable_from_deref_recurse(ctx, var_def, deref, deref->var->data_type, + 0, 0, writemask); +} + +static void copy_propagation_set_value(struct copy_propagation_var_def *var_def, unsigned int comp, + unsigned char writemask, struct hlsl_ir_node *instr) +{ + unsigned int i, j = 0; + + for (i = 0; i < 4; ++i) + { + if (writemask & (1u << i)) + { + TRACE("Variable %s[%u] is written by instruction %p%s.\n", + var_def->var->name, comp + i, instr, debug_hlsl_writemask(1u << i)); + var_def->values[comp + i].state = VALUE_STATE_STATICALLY_WRITTEN; + var_def->values[comp + i].node = instr; + var_def->values[comp + i].component = j++; + } + } +} + +static bool copy_propagation_replace_with_single_instr(struct hlsl_ctx *ctx, + const struct copy_propagation_state *state, const struct hlsl_deref *deref, + unsigned int swizzle, struct hlsl_ir_node *instr) +{ + const unsigned int instr_component_count = hlsl_type_component_count(instr->data_type); + const struct hlsl_ir_var *var = deref->var; + struct hlsl_ir_node *new_instr = NULL; + unsigned int start, count, i; + unsigned int ret_swizzle = 0; + + if (!hlsl_component_index_range_from_deref(ctx, deref, &start, &count)) + return false; + + for (i = 0; i < instr_component_count; ++i) + { + struct copy_propagation_value *value; + + if (!(value = copy_propagation_get_value(state, var, start + hlsl_swizzle_get_component(swizzle, i)))) + return false; + + if (!new_instr) + { + new_instr = value->node; + } + else if (new_instr != value->node) + { + TRACE("No single source for propagating load from %s[%u-%u]%s\n", + var->name, start, start + count, debug_hlsl_swizzle(swizzle, instr_component_count)); + return false; + } + ret_swizzle |= value->component << HLSL_SWIZZLE_SHIFT(i); + } + + TRACE("Load from %s[%u-%u]%s propagated as instruction %p%s.\n", + var->name, start, start + count, debug_hlsl_swizzle(swizzle, instr_component_count), + new_instr, debug_hlsl_swizzle(ret_swizzle, instr_component_count)); + + if (instr->data_type->type != HLSL_CLASS_OBJECT) + { + struct hlsl_ir_swizzle *swizzle_node; + + if (!(swizzle_node = hlsl_new_swizzle(ctx, ret_swizzle, instr_component_count, new_instr, &instr->loc))) + return false; + list_add_before(&instr->entry, &swizzle_node->node.entry); + new_instr = &swizzle_node->node; + } + + hlsl_replace_node(instr, new_instr); + return true; +} + +static bool copy_propagation_replace_with_constant_vector(struct hlsl_ctx *ctx, + const struct copy_propagation_state *state, const struct hlsl_deref *deref, + unsigned int swizzle, struct hlsl_ir_node *instr) +{ + const unsigned int instr_component_count = hlsl_type_component_count(instr->data_type); + const struct hlsl_ir_var *var = deref->var; + union hlsl_constant_value values[4] = {0}; + struct hlsl_ir_constant *cons; + unsigned int start, count, i; + + if (!hlsl_component_index_range_from_deref(ctx, deref, &start, &count)) + return false; + + for (i = 0; i < instr_component_count; ++i) + { + struct copy_propagation_value *value; + + if (!(value = copy_propagation_get_value(state, var, start + hlsl_swizzle_get_component(swizzle, i))) + || value->node->type != HLSL_IR_CONSTANT) + return false; + + values[i] = hlsl_ir_constant(value->node)->value[value->component]; + } + + if (!(cons = hlsl_new_constant(ctx, instr->data_type, &instr->loc))) + return false; + cons->value[0] = values[0]; + cons->value[1] = values[1]; + cons->value[2] = values[2]; + cons->value[3] = values[3]; + list_add_before(&instr->entry, &cons->node.entry); + + TRACE("Load from %s[%u-%u]%s turned into a constant %p.\n", + var->name, start, start + count, debug_hlsl_swizzle(swizzle, instr_component_count), cons); + + hlsl_replace_node(instr, &cons->node); + return true; +} + +static bool copy_propagation_transform_load(struct hlsl_ctx *ctx, + struct hlsl_ir_load *load, struct copy_propagation_state *state) +{ + struct hlsl_type *type = load->node.data_type; + + switch (type->type) + { + case HLSL_CLASS_SCALAR: + case HLSL_CLASS_VECTOR: + case HLSL_CLASS_OBJECT: + break; + + case HLSL_CLASS_MATRIX: + case HLSL_CLASS_ARRAY: + case HLSL_CLASS_STRUCT: + /* FIXME: Actually we shouldn't even get here, but we don't split + * matrices yet. */ + return false; + } + + if (copy_propagation_replace_with_constant_vector(ctx, state, &load->src, HLSL_SWIZZLE(X, Y, Z, W), &load->node)) + return true; + + if (copy_propagation_replace_with_single_instr(ctx, state, &load->src, HLSL_SWIZZLE(X, Y, Z, W), &load->node)) + return true; + + return false; +} + +static bool copy_propagation_transform_swizzle(struct hlsl_ctx *ctx, + struct hlsl_ir_swizzle *swizzle, struct copy_propagation_state *state) +{ + struct hlsl_ir_load *load; + + if (swizzle->val.node->type != HLSL_IR_LOAD) + return false; + load = hlsl_ir_load(swizzle->val.node); + + if (copy_propagation_replace_with_constant_vector(ctx, state, &load->src, swizzle->swizzle, &swizzle->node)) + return true; + + if (copy_propagation_replace_with_single_instr(ctx, state, &load->src, swizzle->swizzle, &swizzle->node)) + return true; + + return false; +} + +static bool copy_propagation_transform_object_load(struct hlsl_ctx *ctx, + struct hlsl_deref *deref, struct copy_propagation_state *state) +{ + struct copy_propagation_value *value; + struct hlsl_ir_load *load; + unsigned int start, count; + + if (!hlsl_component_index_range_from_deref(ctx, deref, &start, &count)) + return false; + assert(count == 1); + + if (!(value = copy_propagation_get_value(state, deref->var, start))) + return false; + assert(value->component == 0); + + /* Only HLSL_IR_LOAD can produce an object. */ + load = hlsl_ir_load(value->node); + + /* As we are replacing the instruction's deref (with the one in the hlsl_ir_load) and not the + * instruction itself, we won't be able to rely on the value retrieved by + * copy_propagation_get_value() for the new deref in subsequent iterations of copy propagation. + * This is because another value may be written to that deref between the hlsl_ir_load and + * this instruction. + * + * For this reason, we only replace the new deref when it corresponds to a uniform variable, + * which cannot be written to. + * + * In a valid shader, all object references must resolve statically to a single uniform object. + * If this is the case, we can expect copy propagation on regular store/loads and the other + * compilation passes to replace all hlsl_ir_loads with loads to uniform objects, so this + * implementation is complete, even with this restriction. + */ + if (!load->src.var->is_uniform) + { + TRACE("Ignoring load from non-uniform object variable %s\n", load->src.var->name); + return false; + } + + hlsl_cleanup_deref(deref); + hlsl_copy_deref(ctx, deref, &load->src); + + return true; +} + +static bool copy_propagation_transform_resource_load(struct hlsl_ctx *ctx, + struct hlsl_ir_resource_load *load, struct copy_propagation_state *state) +{ + bool progress = false; + + progress |= copy_propagation_transform_object_load(ctx, &load->resource, state); + if (load->sampler.var) + progress |= copy_propagation_transform_object_load(ctx, &load->sampler, state); + return progress; +} + +static bool copy_propagation_transform_resource_store(struct hlsl_ctx *ctx, + struct hlsl_ir_resource_store *store, struct copy_propagation_state *state) +{ + bool progress = false; + + progress |= copy_propagation_transform_object_load(ctx, &store->resource, state); + return progress; +} + +static void copy_propagation_record_store(struct hlsl_ctx *ctx, struct hlsl_ir_store *store, + struct copy_propagation_state *state) +{ + struct copy_propagation_var_def *var_def; + struct hlsl_deref *lhs = &store->lhs; + struct hlsl_ir_var *var = lhs->var; + unsigned int start, count; + + if (!(var_def = copy_propagation_create_var_def(ctx, state, var))) + return; + + if (hlsl_component_index_range_from_deref(ctx, lhs, &start, &count)) + { + unsigned int writemask = store->writemask; + + if (store->rhs.node->data_type->type == HLSL_CLASS_OBJECT) + writemask = VKD3DSP_WRITEMASK_0; + copy_propagation_set_value(var_def, start, writemask, store->rhs.node); + } + else + { + copy_propagation_invalidate_variable_from_deref(ctx, var_def, lhs, store->writemask); + } +} + +static void copy_propagation_state_init(struct hlsl_ctx *ctx, struct copy_propagation_state *state, + struct copy_propagation_state *parent) +{ + rb_init(&state->var_defs, copy_propagation_var_def_compare); + state->parent = parent; +} + +static void copy_propagation_state_destroy(struct copy_propagation_state *state) +{ + rb_destroy(&state->var_defs, copy_propagation_var_def_destroy, NULL); +} + +static void copy_propagation_invalidate_from_block(struct hlsl_ctx *ctx, struct copy_propagation_state *state, + struct hlsl_block *block) +{ + struct hlsl_ir_node *instr; + + LIST_FOR_EACH_ENTRY(instr, &block->instrs, struct hlsl_ir_node, entry) + { + switch (instr->type) + { + case HLSL_IR_STORE: + { + struct hlsl_ir_store *store = hlsl_ir_store(instr); + struct copy_propagation_var_def *var_def; + struct hlsl_deref *lhs = &store->lhs; + struct hlsl_ir_var *var = lhs->var; + + if (!(var_def = copy_propagation_create_var_def(ctx, state, var))) + continue; + + copy_propagation_invalidate_variable_from_deref(ctx, var_def, lhs, store->writemask); + + break; + } + + case HLSL_IR_IF: + { + struct hlsl_ir_if *iff = hlsl_ir_if(instr); + + copy_propagation_invalidate_from_block(ctx, state, &iff->then_instrs); + copy_propagation_invalidate_from_block(ctx, state, &iff->else_instrs); + + break; + } + + case HLSL_IR_LOOP: + { + struct hlsl_ir_loop *loop = hlsl_ir_loop(instr); + + copy_propagation_invalidate_from_block(ctx, state, &loop->body); + + break; + } + + default: + break; + } + } +} + +static bool copy_propagation_transform_block(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct copy_propagation_state *state); + +static bool copy_propagation_process_if(struct hlsl_ctx *ctx, struct hlsl_ir_if *iff, + struct copy_propagation_state *state) +{ + struct copy_propagation_state inner_state; + bool progress = false; + + copy_propagation_state_init(ctx, &inner_state, state); + progress |= copy_propagation_transform_block(ctx, &iff->then_instrs, &inner_state); + copy_propagation_state_destroy(&inner_state); + + copy_propagation_state_init(ctx, &inner_state, state); + progress |= copy_propagation_transform_block(ctx, &iff->else_instrs, &inner_state); + copy_propagation_state_destroy(&inner_state); + + /* Ideally we'd invalidate the outer state looking at what was + * touched in the two inner states, but this doesn't work for + * loops (because we need to know what is invalidated in advance), + * so we need copy_propagation_invalidate_from_block() anyway. */ + copy_propagation_invalidate_from_block(ctx, state, &iff->then_instrs); + copy_propagation_invalidate_from_block(ctx, state, &iff->else_instrs); + + return progress; +} + +static bool copy_propagation_process_loop(struct hlsl_ctx *ctx, struct hlsl_ir_loop *loop, + struct copy_propagation_state *state) +{ + struct copy_propagation_state inner_state; + bool progress = false; + + copy_propagation_invalidate_from_block(ctx, state, &loop->body); + + copy_propagation_state_init(ctx, &inner_state, state); + progress |= copy_propagation_transform_block(ctx, &loop->body, &inner_state); + copy_propagation_state_destroy(&inner_state); + + return progress; +} + +static bool copy_propagation_transform_block(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct copy_propagation_state *state) +{ + struct hlsl_ir_node *instr, *next; + bool progress = false; + + LIST_FOR_EACH_ENTRY_SAFE(instr, next, &block->instrs, struct hlsl_ir_node, entry) + { + switch (instr->type) + { + case HLSL_IR_LOAD: + progress |= copy_propagation_transform_load(ctx, hlsl_ir_load(instr), state); + break; + + case HLSL_IR_RESOURCE_LOAD: + progress |= copy_propagation_transform_resource_load(ctx, hlsl_ir_resource_load(instr), state); + break; + + case HLSL_IR_RESOURCE_STORE: + progress |= copy_propagation_transform_resource_store(ctx, hlsl_ir_resource_store(instr), state); + break; + + case HLSL_IR_STORE: + copy_propagation_record_store(ctx, hlsl_ir_store(instr), state); + break; + + case HLSL_IR_SWIZZLE: + progress |= copy_propagation_transform_swizzle(ctx, hlsl_ir_swizzle(instr), state); + break; + + case HLSL_IR_IF: + progress |= copy_propagation_process_if(ctx, hlsl_ir_if(instr), state); + break; + + case HLSL_IR_LOOP: + progress |= copy_propagation_process_loop(ctx, hlsl_ir_loop(instr), state); + break; + + default: + break; + } + } + + return progress; +} + +static bool copy_propagation_execute(struct hlsl_ctx *ctx, struct hlsl_block *block) +{ + struct copy_propagation_state state; + bool progress; + + copy_propagation_state_init(ctx, &state, NULL); + + progress = copy_propagation_transform_block(ctx, block, &state); + + copy_propagation_state_destroy(&state); + + return progress; +} + +static void note_non_static_deref_expressions(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, + const char *usage) +{ + unsigned int i; + + for (i = 0; i < deref->path_len; ++i) + { + struct hlsl_ir_node *path_node = deref->path[i].node; + + assert(path_node); + if (path_node->type != HLSL_IR_CONSTANT) + hlsl_note(ctx, &path_node->loc, VKD3D_SHADER_LOG_ERROR, + "Expression for %s within \"%s\" cannot be resolved statically.", + usage, deref->var->name); + } +} + +static bool validate_static_object_references(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + void *context) +{ + unsigned int start, count; + + if (instr->type == HLSL_IR_RESOURCE_LOAD) + { + struct hlsl_ir_resource_load *load = hlsl_ir_resource_load(instr); + + if (!(load->resource.var->storage_modifiers & HLSL_STORAGE_UNIFORM)) + { + hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF, + "Loaded resource must have a single uniform source."); + } + else if (!hlsl_component_index_range_from_deref(ctx, &load->resource, &start, &count)) + { + hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF, + "Loaded resource from \"%s\" must be determinable at compile time.", + load->resource.var->name); + note_non_static_deref_expressions(ctx, &load->resource, "loaded resource"); + } + + if (load->sampler.var) + { + if (!(load->sampler.var->storage_modifiers & HLSL_STORAGE_UNIFORM)) + { + hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF, + "Resource load sampler must have a single uniform source."); + } + else if (!hlsl_component_index_range_from_deref(ctx, &load->sampler, &start, &count)) + { + hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF, + "Resource load sampler from \"%s\" must be determinable at compile time.", + load->sampler.var->name); + note_non_static_deref_expressions(ctx, &load->sampler, "resource load sampler"); + } + } + } + else if (instr->type == HLSL_IR_RESOURCE_STORE) + { + struct hlsl_ir_resource_store *store = hlsl_ir_resource_store(instr); + + if (!(store->resource.var->storage_modifiers & HLSL_STORAGE_UNIFORM)) + { + hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF, + "Accessed resource must have a single uniform source."); + } + else if (!hlsl_component_index_range_from_deref(ctx, &store->resource, &start, &count)) + { + hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF, + "Accessed resource from \"%s\" must be determinable at compile time.", + store->resource.var->name); + note_non_static_deref_expressions(ctx, &store->resource, "accessed resource"); + } + } + + return false; +} + +static bool is_vec1(const struct hlsl_type *type) +{ + return (type->type == HLSL_CLASS_SCALAR) || (type->type == HLSL_CLASS_VECTOR && type->dimx == 1); +} + +static bool fold_redundant_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + if (instr->type == HLSL_IR_EXPR) + { + struct hlsl_ir_expr *expr = hlsl_ir_expr(instr); + const struct hlsl_type *dst_type = expr->node.data_type; + const struct hlsl_type *src_type; + + if (expr->op != HLSL_OP1_CAST) + return false; + + src_type = expr->operands[0].node->data_type; + + if (hlsl_types_are_equal(src_type, dst_type) + || (src_type->base_type == dst_type->base_type && is_vec1(src_type) && is_vec1(dst_type))) + { + hlsl_replace_node(&expr->node, expr->operands[0].node); + return true; + } + } + + return false; +} + +/* Copy an element of a complex variable. Helper for + * split_array_copies(), split_struct_copies() and + * split_matrix_copies(). Inserts new instructions right before + * "store". */ +static bool split_copy(struct hlsl_ctx *ctx, struct hlsl_ir_store *store, + const struct hlsl_ir_load *load, const unsigned int idx, struct hlsl_type *type) +{ + struct hlsl_ir_store *split_store; + struct hlsl_ir_load *split_load; + struct hlsl_ir_constant *c; + + if (!(c = hlsl_new_uint_constant(ctx, idx, &store->node.loc))) + return false; + list_add_before(&store->node.entry, &c->node.entry); + + if (!(split_load = hlsl_new_load_index(ctx, &load->src, &c->node, &store->node.loc))) + return false; + list_add_before(&store->node.entry, &split_load->node.entry); + + if (!(split_store = hlsl_new_store_index(ctx, &store->lhs, &c->node, &split_load->node, 0, &store->node.loc))) + return false; + list_add_before(&store->node.entry, &split_store->node.entry); + + return true; +} + +static bool split_array_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + const struct hlsl_ir_node *rhs; + struct hlsl_type *element_type; + const struct hlsl_type *type; + struct hlsl_ir_store *store; + unsigned int i; + + if (instr->type != HLSL_IR_STORE) + return false; + + store = hlsl_ir_store(instr); + rhs = store->rhs.node; + type = rhs->data_type; + if (type->type != HLSL_CLASS_ARRAY) + return false; + element_type = type->e.array.type; + + if (rhs->type != HLSL_IR_LOAD) + { + hlsl_fixme(ctx, &instr->loc, "Array store rhs is not HLSL_IR_LOAD. Broadcast may be missing."); + return false; + } + + for (i = 0; i < type->e.array.elements_count; ++i) + { + if (!split_copy(ctx, store, hlsl_ir_load(rhs), i, element_type)) + return false; + } + + /* Remove the store instruction, so that we can split structs which contain + * other structs. Although assignments produce a value, we don't allow + * HLSL_IR_STORE to be used as a source. */ + list_remove(&store->node.entry); + hlsl_free_instr(&store->node); + return true; +} + +static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + const struct hlsl_ir_node *rhs; + const struct hlsl_type *type; + struct hlsl_ir_store *store; + size_t i; + + if (instr->type != HLSL_IR_STORE) + return false; + + store = hlsl_ir_store(instr); + rhs = store->rhs.node; + type = rhs->data_type; + if (type->type != HLSL_CLASS_STRUCT) + return false; + + if (rhs->type != HLSL_IR_LOAD) + { + hlsl_fixme(ctx, &instr->loc, "Struct store rhs is not HLSL_IR_LOAD. Broadcast may be missing."); + return false; + } + + for (i = 0; i < type->e.record.field_count; ++i) + { + const struct hlsl_struct_field *field = &type->e.record.fields[i]; + + if (!split_copy(ctx, store, hlsl_ir_load(rhs), i, field->type)) + return false; + } + + /* Remove the store instruction, so that we can split structs which contain + * other structs. Although assignments produce a value, we don't allow + * HLSL_IR_STORE to be used as a source. */ + list_remove(&store->node.entry); + hlsl_free_instr(&store->node); + return true; +} + +static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + const struct hlsl_ir_node *rhs; + struct hlsl_type *element_type; + const struct hlsl_type *type; + unsigned int i; + struct hlsl_ir_store *store; + + if (instr->type != HLSL_IR_STORE) + return false; + + store = hlsl_ir_store(instr); + rhs = store->rhs.node; + type = rhs->data_type; + if (type->type != HLSL_CLASS_MATRIX) + return false; + element_type = hlsl_get_vector_type(ctx, type->base_type, hlsl_type_minor_size(type)); + + if (rhs->type != HLSL_IR_LOAD) + { + hlsl_fixme(ctx, &instr->loc, "Copying from unsupported node type.\n"); + return false; + } + + for (i = 0; i < hlsl_type_major_size(type); ++i) + { + if (!split_copy(ctx, store, hlsl_ir_load(rhs), i, element_type)) + return false; + } + + list_remove(&store->node.entry); + hlsl_free_instr(&store->node); + return true; +} + +static bool lower_narrowing_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + const struct hlsl_type *src_type, *dst_type; + struct hlsl_type *dst_vector_type; + struct hlsl_ir_expr *cast; + + if (instr->type != HLSL_IR_EXPR) + return false; + cast = hlsl_ir_expr(instr); + if (cast->op != HLSL_OP1_CAST) + return false; + src_type = cast->operands[0].node->data_type; + dst_type = cast->node.data_type; + + if (src_type->type <= HLSL_CLASS_VECTOR && dst_type->type <= HLSL_CLASS_VECTOR && dst_type->dimx < src_type->dimx) + { + struct hlsl_ir_swizzle *swizzle; + struct hlsl_ir_expr *new_cast; + + dst_vector_type = hlsl_get_vector_type(ctx, dst_type->base_type, src_type->dimx); + /* We need to preserve the cast since it might be doing more than just + * narrowing the vector. */ + if (!(new_cast = hlsl_new_cast(ctx, cast->operands[0].node, dst_vector_type, &cast->node.loc))) + return false; + list_add_after(&cast->node.entry, &new_cast->node.entry); + if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, Y, Z, W), dst_type->dimx, &new_cast->node, &cast->node.loc))) + return false; + list_add_after(&new_cast->node.entry, &swizzle->node.entry); + + hlsl_replace_node(&cast->node, &swizzle->node); + return true; + } + + return false; +} + +static bool fold_swizzle_chains(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_ir_swizzle *swizzle; + struct hlsl_ir_node *next_instr; + + if (instr->type != HLSL_IR_SWIZZLE) + return false; + swizzle = hlsl_ir_swizzle(instr); + + next_instr = swizzle->val.node; + + if (next_instr->type == HLSL_IR_SWIZZLE) + { + struct hlsl_ir_swizzle *new_swizzle; + struct hlsl_ir_node *new_instr; + unsigned int combined_swizzle; + + combined_swizzle = hlsl_combine_swizzles(hlsl_ir_swizzle(next_instr)->swizzle, + swizzle->swizzle, instr->data_type->dimx); + next_instr = hlsl_ir_swizzle(next_instr)->val.node; + + if (!(new_swizzle = hlsl_new_swizzle(ctx, combined_swizzle, instr->data_type->dimx, next_instr, &instr->loc))) + return false; + + new_instr = &new_swizzle->node; + list_add_before(&instr->entry, &new_instr->entry); + hlsl_replace_node(instr, new_instr); + return true; + } + + return false; +} + +static bool remove_trivial_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_ir_swizzle *swizzle; + unsigned int i; + + if (instr->type != HLSL_IR_SWIZZLE) + return false; + swizzle = hlsl_ir_swizzle(instr); + + if (instr->data_type->dimx != swizzle->val.node->data_type->dimx) + return false; + + for (i = 0; i < instr->data_type->dimx; ++i) + if (hlsl_swizzle_get_component(swizzle->swizzle, i) != i) + return false; + + hlsl_replace_node(instr, swizzle->val.node); + + return true; +} + +/* Lower DIV to RCP + MUL. */ +static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_ir_expr *expr; + struct hlsl_ir_node *rcp; + + if (instr->type != HLSL_IR_EXPR) + return false; + expr = hlsl_ir_expr(instr); + if (expr->op != HLSL_OP2_DIV) + return false; + + if (!(rcp = hlsl_new_unary_expr(ctx, HLSL_OP1_RCP, expr->operands[1].node, instr->loc))) + return false; + list_add_before(&expr->node.entry, &rcp->entry); + expr->op = HLSL_OP2_MUL; + hlsl_src_remove(&expr->operands[1]); + hlsl_src_from_node(&expr->operands[1], rcp); + return true; +} + +/* Lower SQRT to RSQ + RCP. */ +static bool lower_sqrt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_ir_expr *expr; + struct hlsl_ir_node *rsq; + + if (instr->type != HLSL_IR_EXPR) + return false; + expr = hlsl_ir_expr(instr); + if (expr->op != HLSL_OP1_SQRT) + return false; + + if (!(rsq = hlsl_new_unary_expr(ctx, HLSL_OP1_RSQ, expr->operands[0].node, instr->loc))) + return false; + list_add_before(&expr->node.entry, &rsq->entry); + expr->op = HLSL_OP1_RCP; + hlsl_src_remove(&expr->operands[0]); + hlsl_src_from_node(&expr->operands[0], rsq); + return true; +} + +/* Lower DP2 to MUL + ADD */ +static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_ir_node *arg1, *arg2, *mul, *replacement; + struct hlsl_ir_swizzle *add_x, *add_y; + struct hlsl_ir_constant *zero; + struct hlsl_ir_expr *expr; + + if (instr->type != HLSL_IR_EXPR) + return false; + expr = hlsl_ir_expr(instr); + arg1 = expr->operands[0].node; + arg2 = expr->operands[1].node; + if (expr->op != HLSL_OP2_DOT) + return false; + if (arg1->data_type->dimx != 2) + return false; + + if (ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL) + { + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = { 0 }; + + if (!(zero = hlsl_new_float_constant(ctx, 0.0f, &expr->node.loc))) + return false; + list_add_before(&instr->entry, &zero->node.entry); + + operands[0] = arg1; + operands[1] = arg2; + operands[2] = &zero->node; + + if (!(replacement = hlsl_new_expr(ctx, HLSL_OP3_DP2ADD, operands, instr->data_type, &expr->node.loc))) + return false; + } + else + { + if (!(mul = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, expr->operands[0].node, expr->operands[1].node))) + return false; + list_add_before(&instr->entry, &mul->entry); + + if (!(add_x = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X), instr->data_type->dimx, mul, &expr->node.loc))) + return false; + list_add_before(&instr->entry, &add_x->node.entry); + + if (!(add_y = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Y, Y, Y, Y), instr->data_type->dimx, mul, &expr->node.loc))) + return false; + list_add_before(&instr->entry, &add_y->node.entry); + + if (!(replacement = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, &add_x->node, &add_y->node))) + return false; + } + list_add_before(&instr->entry, &replacement->entry); + + hlsl_replace_node(instr, replacement); + return true; +} + +/* Lower ABS to MAX */ +static bool lower_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_ir_node *arg, *neg, *replacement; + struct hlsl_ir_expr *expr; + + if (instr->type != HLSL_IR_EXPR) + return false; + expr = hlsl_ir_expr(instr); + arg = expr->operands[0].node; + if (expr->op != HLSL_OP1_ABS) + return false; + + if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg, instr->loc))) + return false; + list_add_before(&instr->entry, &neg->entry); + + if (!(replacement = hlsl_new_binary_expr(ctx, HLSL_OP2_MAX, neg, arg))) + return false; + list_add_before(&instr->entry, &replacement->entry); + + hlsl_replace_node(instr, replacement); + return true; +} + +static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_type *type = instr->data_type, *arg_type; + struct hlsl_ir_constant *zero; + struct hlsl_ir_expr *expr; + + if (instr->type != HLSL_IR_EXPR) + return false; + expr = hlsl_ir_expr(instr); + if (expr->op != HLSL_OP1_CAST) + return false; + arg_type = expr->operands[0].node->data_type; + if (type->type > HLSL_CLASS_VECTOR || arg_type->type > HLSL_CLASS_VECTOR) + return false; + if (type->base_type != HLSL_TYPE_BOOL) + return false; + + /* Narrowing casts should have already been lowered. */ + assert(type->dimx == arg_type->dimx); + + zero = hlsl_new_constant(ctx, arg_type, &instr->loc); + if (!zero) + return false; + list_add_before(&instr->entry, &zero->node.entry); + + expr->op = HLSL_OP2_NEQUAL; + hlsl_src_from_node(&expr->operands[1], &zero->node); + + return true; +} + +struct hlsl_ir_load *hlsl_add_conditional(struct hlsl_ctx *ctx, struct list *instrs, + struct hlsl_ir_node *condition, struct hlsl_ir_node *if_true, struct hlsl_ir_node *if_false) +{ + struct hlsl_ir_store *store; + struct hlsl_ir_load *load; + struct hlsl_ir_var *var; + struct hlsl_ir_if *iff; + + assert(hlsl_types_are_equal(if_true->data_type, if_false->data_type)); + + if (!(var = hlsl_new_synthetic_var(ctx, "conditional", if_true->data_type, &condition->loc))) + return NULL; + + if (!(iff = hlsl_new_if(ctx, condition, condition->loc))) + return NULL; + list_add_tail(instrs, &iff->node.entry); + + if (!(store = hlsl_new_simple_store(ctx, var, if_true))) + return NULL; + list_add_tail(&iff->then_instrs.instrs, &store->node.entry); + + if (!(store = hlsl_new_simple_store(ctx, var, if_false))) + return NULL; + list_add_tail(&iff->else_instrs.instrs, &store->node.entry); + + if (!(load = hlsl_new_var_load(ctx, var, condition->loc))) + return NULL; + list_add_tail(instrs, &load->node.entry); + + return load; +} + +static bool lower_int_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_ir_node *arg1, *arg2, *xor, *and, *abs1, *abs2, *div, *neg; + struct hlsl_type *type = instr->data_type, *utype; + struct hlsl_ir_expr *cast1, *cast2, *cast3; + struct hlsl_ir_constant *high_bit; + struct hlsl_ir_expr *expr; + struct hlsl_ir_load *cond; + unsigned int i; + + if (instr->type != HLSL_IR_EXPR) + return false; + expr = hlsl_ir_expr(instr); + arg1 = expr->operands[0].node; + arg2 = expr->operands[1].node; + if (expr->op != HLSL_OP2_DIV) + return false; + if (type->type != HLSL_CLASS_SCALAR && type->type != HLSL_CLASS_VECTOR) + return false; + if (type->base_type != HLSL_TYPE_INT) + return false; + utype = hlsl_get_numeric_type(ctx, type->type, HLSL_TYPE_UINT, type->dimx, type->dimy); + + if (!(xor = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_XOR, arg1, arg2))) + return false; + list_add_before(&instr->entry, &xor->entry); + + if (!(high_bit = hlsl_new_constant(ctx, type, &instr->loc))) + return false; + for (i = 0; i < type->dimx; ++i) + high_bit->value[i].u = 0x80000000; + list_add_before(&instr->entry, &high_bit->node.entry); + + if (!(and = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_AND, xor, &high_bit->node))) + return false; + list_add_before(&instr->entry, &and->entry); + + if (!(abs1 = hlsl_new_unary_expr(ctx, HLSL_OP1_ABS, arg1, instr->loc))) + return false; + list_add_before(&instr->entry, &abs1->entry); + + if (!(cast1 = hlsl_new_cast(ctx, abs1, utype, &instr->loc))) + return false; + list_add_before(&instr->entry, &cast1->node.entry); + + if (!(abs2 = hlsl_new_unary_expr(ctx, HLSL_OP1_ABS, arg2, instr->loc))) + return false; + list_add_before(&instr->entry, &abs2->entry); + + if (!(cast2 = hlsl_new_cast(ctx, abs2, utype, &instr->loc))) + return false; + list_add_before(&instr->entry, &cast2->node.entry); + + if (!(div = hlsl_new_binary_expr(ctx, HLSL_OP2_DIV, &cast1->node, &cast2->node))) + return false; + list_add_before(&instr->entry, &div->entry); + + if (!(cast3 = hlsl_new_cast(ctx, div, type, &instr->loc))) + return false; + list_add_before(&instr->entry, &cast3->node.entry); + + if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, &cast3->node, instr->loc))) + return false; + list_add_before(&instr->entry, &neg->entry); + + if (!(cond = hlsl_add_conditional(ctx, &instr->entry, and, neg, &cast3->node))) + return false; + hlsl_replace_node(instr, &cond->node); + + return true; +} + +static bool lower_int_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_ir_node *arg1, *arg2, *and, *abs1, *abs2, *div, *neg; + struct hlsl_type *type = instr->data_type, *utype; + struct hlsl_ir_expr *cast1, *cast2, *cast3; + struct hlsl_ir_constant *high_bit; + struct hlsl_ir_expr *expr; + struct hlsl_ir_load *cond; + unsigned int i; + + if (instr->type != HLSL_IR_EXPR) + return false; + expr = hlsl_ir_expr(instr); + arg1 = expr->operands[0].node; + arg2 = expr->operands[1].node; + if (expr->op != HLSL_OP2_MOD) + return false; + if (type->type != HLSL_CLASS_SCALAR && type->type != HLSL_CLASS_VECTOR) + return false; + if (type->base_type != HLSL_TYPE_INT) + return false; + utype = hlsl_get_numeric_type(ctx, type->type, HLSL_TYPE_UINT, type->dimx, type->dimy); + + if (!(high_bit = hlsl_new_constant(ctx, type, &instr->loc))) + return false; + for (i = 0; i < type->dimx; ++i) + high_bit->value[i].u = 0x80000000; + list_add_before(&instr->entry, &high_bit->node.entry); + + if (!(and = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_AND, arg1, &high_bit->node))) + return false; + list_add_before(&instr->entry, &and->entry); + + if (!(abs1 = hlsl_new_unary_expr(ctx, HLSL_OP1_ABS, arg1, instr->loc))) + return false; + list_add_before(&instr->entry, &abs1->entry); + + if (!(cast1 = hlsl_new_cast(ctx, abs1, utype, &instr->loc))) + return false; + list_add_before(&instr->entry, &cast1->node.entry); + + if (!(abs2 = hlsl_new_unary_expr(ctx, HLSL_OP1_ABS, arg2, instr->loc))) + return false; + list_add_before(&instr->entry, &abs2->entry); + + if (!(cast2 = hlsl_new_cast(ctx, abs2, utype, &instr->loc))) + return false; + list_add_before(&instr->entry, &cast2->node.entry); + + if (!(div = hlsl_new_binary_expr(ctx, HLSL_OP2_MOD, &cast1->node, &cast2->node))) + return false; + list_add_before(&instr->entry, &div->entry); + + if (!(cast3 = hlsl_new_cast(ctx, div, type, &instr->loc))) + return false; + list_add_before(&instr->entry, &cast3->node.entry); + + if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, &cast3->node, instr->loc))) + return false; + list_add_before(&instr->entry, &neg->entry); + + if (!(cond = hlsl_add_conditional(ctx, &instr->entry, and, neg, &cast3->node))) + return false; + hlsl_replace_node(instr, &cond->node); + + return true; +} + +static bool lower_int_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_type *type = instr->data_type; + struct hlsl_ir_node *arg, *neg; + struct hlsl_ir_expr *expr; + + if (instr->type != HLSL_IR_EXPR) + return false; + expr = hlsl_ir_expr(instr); + + if (expr->op != HLSL_OP1_ABS) + return false; + if (type->type != HLSL_CLASS_SCALAR && type->type != HLSL_CLASS_VECTOR) + return false; + if (type->base_type != HLSL_TYPE_INT) + return false; + + arg = expr->operands[0].node; + + if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg, instr->loc))) + return false; + list_add_before(&instr->entry, &neg->entry); + + expr->op = HLSL_OP2_MAX; + hlsl_src_from_node(&expr->operands[1], neg); + + return true; +} + +static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_ir_node *arg1, *arg2, *mul1, *neg1, *ge, *neg2, *div, *mul2, *frc; + struct hlsl_type *type = instr->data_type, *btype; + struct hlsl_ir_constant *one; + struct hlsl_ir_load *cond; + struct hlsl_ir_expr *expr; + unsigned int i; + + if (instr->type != HLSL_IR_EXPR) + return false; + expr = hlsl_ir_expr(instr); + arg1 = expr->operands[0].node; + arg2 = expr->operands[1].node; + if (expr->op != HLSL_OP2_MOD) + return false; + if (type->type != HLSL_CLASS_SCALAR && type->type != HLSL_CLASS_VECTOR) + return false; + if (type->base_type != HLSL_TYPE_FLOAT) + return false; + btype = hlsl_get_numeric_type(ctx, type->type, HLSL_TYPE_BOOL, type->dimx, type->dimy); + + if (!(mul1 = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, arg2, arg1))) + return false; + list_add_before(&instr->entry, &mul1->entry); + + if (!(neg1 = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, mul1, instr->loc))) + return false; + list_add_before(&instr->entry, &neg1->entry); + + if (!(ge = hlsl_new_binary_expr(ctx, HLSL_OP2_GEQUAL, mul1, neg1))) + return false; + ge->data_type = btype; + list_add_before(&instr->entry, &ge->entry); + + if (!(neg2 = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg2, instr->loc))) + return false; + list_add_before(&instr->entry, &neg2->entry); + + if (!(cond = hlsl_add_conditional(ctx, &instr->entry, ge, arg2, neg2))) + return false; + + if (!(one = hlsl_new_constant(ctx, type, &instr->loc))) + return false; + for (i = 0; i < type->dimx; ++i) + one->value[i].f = 1.0f; + list_add_before(&instr->entry, &one->node.entry); + + if (!(div = hlsl_new_binary_expr(ctx, HLSL_OP2_DIV, &one->node, &cond->node))) + return false; + list_add_before(&instr->entry, &div->entry); + + if (!(mul2 = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, div, arg1))) + return false; + list_add_before(&instr->entry, &mul2->entry); + + if (!(frc = hlsl_new_unary_expr(ctx, HLSL_OP1_FRACT, mul2, instr->loc))) + return false; + list_add_before(&instr->entry, &frc->entry); + + expr->op = HLSL_OP2_MUL; + hlsl_src_remove(&expr->operands[0]); + hlsl_src_remove(&expr->operands[1]); + hlsl_src_from_node(&expr->operands[0], frc); + hlsl_src_from_node(&expr->operands[1], &cond->node); + + return true; +} + +static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + switch (instr->type) + { + case HLSL_IR_CONSTANT: + case HLSL_IR_EXPR: + case HLSL_IR_LOAD: + case HLSL_IR_RESOURCE_LOAD: + case HLSL_IR_SWIZZLE: + if (list_empty(&instr->uses)) + { + list_remove(&instr->entry); + hlsl_free_instr(instr); + return true; + } + break; + + case HLSL_IR_STORE: + { + struct hlsl_ir_store *store = hlsl_ir_store(instr); + struct hlsl_ir_var *var = store->lhs.var; + + if (var->last_read < instr->index) + { + list_remove(&instr->entry); + hlsl_free_instr(instr); + return true; + } + break; + } + + case HLSL_IR_CALL: + case HLSL_IR_IF: + case HLSL_IR_JUMP: + case HLSL_IR_LOOP: + case HLSL_IR_RESOURCE_STORE: + break; + } + + return false; +} + +/* Allocate a unique, ordered index to each instruction, which will be used for + * computing liveness ranges. */ +static unsigned int index_instructions(struct hlsl_block *block, unsigned int index) +{ + struct hlsl_ir_node *instr; + + LIST_FOR_EACH_ENTRY(instr, &block->instrs, struct hlsl_ir_node, entry) + { + instr->index = index++; + + if (instr->type == HLSL_IR_IF) + { + struct hlsl_ir_if *iff = hlsl_ir_if(instr); + index = index_instructions(&iff->then_instrs, index); + index = index_instructions(&iff->else_instrs, index); + } + else if (instr->type == HLSL_IR_LOOP) + { + index = index_instructions(&hlsl_ir_loop(instr)->body, index); + hlsl_ir_loop(instr)->next_index = index; + } + } + + return index; +} + +static void dump_function_decl(struct rb_entry *entry, void *context) +{ + struct hlsl_ir_function_decl *func = RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry); + struct hlsl_ctx *ctx = context; + + if (func->has_body) + hlsl_dump_function(ctx, func); +} + +static void dump_function(struct rb_entry *entry, void *context) +{ + struct hlsl_ir_function *func = RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry); + struct hlsl_ctx *ctx = context; + + rb_for_each_entry(&func->overloads, dump_function_decl, ctx); +} + +static char get_regset_name(enum hlsl_regset regset) +{ + switch (regset) + { + case HLSL_REGSET_SAMPLERS: + return 's'; + case HLSL_REGSET_TEXTURES: + return 't'; + case HLSL_REGSET_UAVS: + return 'u'; + case HLSL_REGSET_NUMERIC: + vkd3d_unreachable(); + } + vkd3d_unreachable(); +} + +static void allocate_register_reservations(struct hlsl_ctx *ctx) +{ + struct hlsl_ir_var *var; + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + enum hlsl_regset regset; + + if (!hlsl_type_is_resource(var->data_type)) + continue; + regset = hlsl_type_get_regset(var->data_type); + + if (var->reg_reservation.type) + { + if (var->reg_reservation.type != get_regset_name(regset)) + { + struct vkd3d_string_buffer *type_string; + + type_string = hlsl_type_to_string(ctx, var->data_type); + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, + "Object of type '%s' must be bound to register type '%c'.", + type_string->buffer, get_regset_name(regset)); + hlsl_release_string_buffer(ctx, type_string); + } + else + { + var->regs[regset].allocated = true; + var->regs[regset].id = var->reg_reservation.index; + TRACE("Allocated reserved %s to %c%u.\n", var->name, var->reg_reservation.type, var->reg_reservation.index); + } + } + } +} + +/* Compute the earliest and latest liveness for each variable. In the case that + * a variable is accessed inside of a loop, we promote its liveness to extend + * to at least the range of the entire loop. Note that we don't need to do this + * for anonymous nodes, since there's currently no way to use a node which was + * calculated in an earlier iteration of the loop. */ +static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop_first, unsigned int loop_last) +{ + struct hlsl_ir_node *instr; + struct hlsl_ir_var *var; + + LIST_FOR_EACH_ENTRY(instr, &block->instrs, struct hlsl_ir_node, entry) + { + const unsigned int var_last_read = loop_last ? max(instr->index, loop_last) : instr->index; + + switch (instr->type) + { + case HLSL_IR_CALL: + /* We should have inlined all calls before computing liveness. */ + vkd3d_unreachable(); + + case HLSL_IR_STORE: + { + struct hlsl_ir_store *store = hlsl_ir_store(instr); + + var = store->lhs.var; + if (!var->first_write) + var->first_write = loop_first ? min(instr->index, loop_first) : instr->index; + store->rhs.node->last_read = instr->index; + if (store->lhs.offset.node) + store->lhs.offset.node->last_read = instr->index; + break; + } + case HLSL_IR_EXPR: + { + struct hlsl_ir_expr *expr = hlsl_ir_expr(instr); + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(expr->operands) && expr->operands[i].node; ++i) + expr->operands[i].node->last_read = instr->index; + break; + } + case HLSL_IR_IF: + { + struct hlsl_ir_if *iff = hlsl_ir_if(instr); + + compute_liveness_recurse(&iff->then_instrs, loop_first, loop_last); + compute_liveness_recurse(&iff->else_instrs, loop_first, loop_last); + iff->condition.node->last_read = instr->index; + break; + } + case HLSL_IR_LOAD: + { + struct hlsl_ir_load *load = hlsl_ir_load(instr); + + var = load->src.var; + var->last_read = max(var->last_read, var_last_read); + if (load->src.offset.node) + load->src.offset.node->last_read = instr->index; + break; + } + case HLSL_IR_LOOP: + { + struct hlsl_ir_loop *loop = hlsl_ir_loop(instr); + + compute_liveness_recurse(&loop->body, loop_first ? loop_first : instr->index, + loop_last ? loop_last : loop->next_index); + break; + } + case HLSL_IR_RESOURCE_LOAD: + { + struct hlsl_ir_resource_load *load = hlsl_ir_resource_load(instr); + + var = load->resource.var; + var->last_read = max(var->last_read, var_last_read); + if (load->resource.offset.node) + load->resource.offset.node->last_read = instr->index; + + if ((var = load->sampler.var)) + { + var->last_read = max(var->last_read, var_last_read); + if (load->sampler.offset.node) + load->sampler.offset.node->last_read = instr->index; + } + + load->coords.node->last_read = instr->index; + if (load->texel_offset.node) + load->texel_offset.node->last_read = instr->index; + if (load->lod.node) + load->lod.node->last_read = instr->index; + break; + } + case HLSL_IR_RESOURCE_STORE: + { + struct hlsl_ir_resource_store *store = hlsl_ir_resource_store(instr); + + var = store->resource.var; + var->last_read = max(var->last_read, var_last_read); + if (store->resource.offset.node) + store->resource.offset.node->last_read = instr->index; + store->coords.node->last_read = instr->index; + store->value.node->last_read = instr->index; + break; + } + case HLSL_IR_SWIZZLE: + { + struct hlsl_ir_swizzle *swizzle = hlsl_ir_swizzle(instr); + + swizzle->val.node->last_read = instr->index; + break; + } + case HLSL_IR_CONSTANT: + case HLSL_IR_JUMP: + break; + } + } +} + +static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) +{ + struct hlsl_scope *scope; + struct hlsl_ir_var *var; + + /* Index 0 means unused; index 1 means function entry, so start at 2. */ + index_instructions(&entry_func->body, 2); + + LIST_FOR_EACH_ENTRY(scope, &ctx->scopes, struct hlsl_scope, entry) + { + LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry) + var->first_write = var->last_read = 0; + } + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + if (var->is_uniform || var->is_input_semantic) + var->first_write = 1; + else if (var->is_output_semantic) + var->last_read = UINT_MAX; + } + + compute_liveness_recurse(&entry_func->body, 0, 0); +} + +struct liveness +{ + size_t size; + uint32_t reg_count; + struct + { + /* 0 if not live yet. */ + unsigned int last_read; + } *regs; +}; + +static unsigned int get_available_writemask(struct liveness *liveness, + unsigned int first_write, unsigned int component_idx, unsigned int reg_size) +{ + unsigned int i, writemask = 0, count = 0; + + for (i = 0; i < 4; ++i) + { + if (liveness->regs[component_idx + i].last_read <= first_write) + { + writemask |= 1u << i; + if (++count == reg_size) + return writemask; + } + } + + return 0; +} + +static bool resize_liveness(struct hlsl_ctx *ctx, struct liveness *liveness, size_t new_count) +{ + size_t old_capacity = liveness->size; + + if (!hlsl_array_reserve(ctx, (void **)&liveness->regs, &liveness->size, new_count, sizeof(*liveness->regs))) + return false; + + if (liveness->size > old_capacity) + memset(liveness->regs + old_capacity, 0, (liveness->size - old_capacity) * sizeof(*liveness->regs)); + return true; +} + +/* reg_size is the number of register components to be reserved, while component_count is the number + * of components for the register's writemask. In SM1, floats and vectors allocate the whole + * register, even if they don't use it completely. */ +static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct liveness *liveness, + unsigned int first_write, unsigned int last_read, unsigned int reg_size, + unsigned int component_count) +{ + unsigned int component_idx, writemask, i; + struct hlsl_reg ret = {0}; + + assert(component_count <= reg_size); + + for (component_idx = 0; component_idx < liveness->size; component_idx += 4) + { + if ((writemask = get_available_writemask(liveness, first_write, component_idx, reg_size))) + break; + } + if (component_idx == liveness->size) + { + if (!resize_liveness(ctx, liveness, component_idx + 4)) + return ret; + writemask = (1u << reg_size) - 1; + } + for (i = 0; i < 4; ++i) + { + if (writemask & (1u << i)) + liveness->regs[component_idx + i].last_read = last_read; + } + ret.id = component_idx / 4; + ret.writemask = hlsl_combine_writemasks(writemask, (1u << component_count) - 1); + ret.allocated = true; + liveness->reg_count = max(liveness->reg_count, ret.id + 1); + return ret; +} + +static bool is_range_available(struct liveness *liveness, unsigned int first_write, + unsigned int component_idx, unsigned int reg_size) +{ + unsigned int i; + + for (i = 0; i < reg_size; i += 4) + { + if (!get_available_writemask(liveness, first_write, component_idx + i, 4)) + return false; + } + return true; +} + +static struct hlsl_reg allocate_range(struct hlsl_ctx *ctx, struct liveness *liveness, + unsigned int first_write, unsigned int last_read, unsigned int reg_size) +{ + unsigned int i, component_idx; + struct hlsl_reg ret = {0}; + + for (component_idx = 0; component_idx < liveness->size; component_idx += 4) + { + if (is_range_available(liveness, first_write, component_idx, + min(reg_size, liveness->size - component_idx))) + break; + } + if (!resize_liveness(ctx, liveness, component_idx + reg_size)) + return ret; + + for (i = 0; i < reg_size; ++i) + liveness->regs[component_idx + i].last_read = last_read; + ret.id = component_idx / 4; + ret.allocated = true; + liveness->reg_count = max(liveness->reg_count, ret.id + align(reg_size, 4)); + return ret; +} + +static struct hlsl_reg allocate_numeric_registers_for_type(struct hlsl_ctx *ctx, struct liveness *liveness, + unsigned int first_write, unsigned int last_read, const struct hlsl_type *type) +{ + unsigned int reg_size = type->reg_size[HLSL_REGSET_NUMERIC]; + + if (type->type <= HLSL_CLASS_VECTOR) + return allocate_register(ctx, liveness, first_write, last_read, reg_size, type->dimx); + else + return allocate_range(ctx, liveness, first_write, last_read, reg_size); +} + +static const char *debug_register(char class, struct hlsl_reg reg, const struct hlsl_type *type) +{ + static const char writemask_offset[] = {'w','x','y','z'}; + unsigned int reg_size = type->reg_size[HLSL_REGSET_NUMERIC]; + + if (reg_size > 4) + { + if (reg_size & 3) + return vkd3d_dbg_sprintf("%c%u-%c%u.%c", class, reg.id, class, reg.id + (reg_size / 4), + writemask_offset[reg_size & 3]); + + return vkd3d_dbg_sprintf("%c%u-%c%u", class, reg.id, class, reg.id + (reg_size / 4) - 1); + } + return vkd3d_dbg_sprintf("%c%u%s", class, reg.id, debug_hlsl_writemask(reg.writemask)); +} + +static void allocate_variable_temp_register(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, struct liveness *liveness) +{ + if (var->is_input_semantic || var->is_output_semantic || var->is_uniform) + return; + + if (!var->regs[HLSL_REGSET_NUMERIC].allocated && var->last_read) + { + var->regs[HLSL_REGSET_NUMERIC] = allocate_numeric_registers_for_type(ctx, liveness, + var->first_write, var->last_read, var->data_type); + + TRACE("Allocated %s to %s (liveness %u-%u).\n", var->name, debug_register('r', + var->regs[HLSL_REGSET_NUMERIC], var->data_type), var->first_write, var->last_read); + } +} + +static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_block *block, struct liveness *liveness) +{ + struct hlsl_ir_node *instr; + + LIST_FOR_EACH_ENTRY(instr, &block->instrs, struct hlsl_ir_node, entry) + { + if (!instr->reg.allocated && instr->last_read) + { + instr->reg = allocate_numeric_registers_for_type(ctx, liveness, instr->index, instr->last_read, + instr->data_type); + TRACE("Allocated anonymous expression @%u to %s (liveness %u-%u).\n", instr->index, + debug_register('r', instr->reg, instr->data_type), instr->index, instr->last_read); + } + + switch (instr->type) + { + case HLSL_IR_IF: + { + struct hlsl_ir_if *iff = hlsl_ir_if(instr); + allocate_temp_registers_recurse(ctx, &iff->then_instrs, liveness); + allocate_temp_registers_recurse(ctx, &iff->else_instrs, liveness); + break; + } + + case HLSL_IR_LOAD: + { + struct hlsl_ir_load *load = hlsl_ir_load(instr); + /* We need to at least allocate a variable for undefs. + * FIXME: We should probably find a way to remove them instead. */ + allocate_variable_temp_register(ctx, load->src.var, liveness); + break; + } + + case HLSL_IR_LOOP: + { + struct hlsl_ir_loop *loop = hlsl_ir_loop(instr); + allocate_temp_registers_recurse(ctx, &loop->body, liveness); + break; + } + + case HLSL_IR_STORE: + { + struct hlsl_ir_store *store = hlsl_ir_store(instr); + allocate_variable_temp_register(ctx, store->lhs.var, liveness); + break; + } + + default: + break; + } + } +} + +static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_block *block, struct liveness *liveness) +{ + struct hlsl_constant_defs *defs = &ctx->constant_defs; + struct hlsl_ir_node *instr; + + LIST_FOR_EACH_ENTRY(instr, &block->instrs, struct hlsl_ir_node, entry) + { + switch (instr->type) + { + case HLSL_IR_CONSTANT: + { + struct hlsl_ir_constant *constant = hlsl_ir_constant(instr); + const struct hlsl_type *type = instr->data_type; + unsigned int x, y, i, writemask, end_reg; + unsigned int reg_size = type->reg_size[HLSL_REGSET_NUMERIC]; + + constant->reg = allocate_numeric_registers_for_type(ctx, liveness, 1, UINT_MAX, type); + TRACE("Allocated constant @%u to %s.\n", instr->index, debug_register('c', constant->reg, type)); + + if (!hlsl_array_reserve(ctx, (void **)&defs->values, &defs->size, + constant->reg.id + reg_size / 4, sizeof(*defs->values))) + return; + end_reg = constant->reg.id + reg_size / 4; + if (end_reg > defs->count) + { + memset(&defs->values[defs->count], 0, sizeof(*defs->values) * (end_reg - defs->count)); + defs->count = end_reg; + } + + assert(type->type <= HLSL_CLASS_LAST_NUMERIC); + + if (!(writemask = constant->reg.writemask)) + writemask = (1u << type->dimx) - 1; + + for (y = 0; y < type->dimy; ++y) + { + for (x = 0, i = 0; x < 4; ++x) + { + const union hlsl_constant_value *value; + float f; + + if (!(writemask & (1u << x))) + continue; + value = &constant->value[i++]; + + switch (type->base_type) + { + case HLSL_TYPE_BOOL: + f = !!value->u; + break; + + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + f = value->f; + break; + + case HLSL_TYPE_INT: + f = value->i; + break; + + case HLSL_TYPE_UINT: + f = value->u; + break; + + case HLSL_TYPE_DOUBLE: + FIXME("Double constant.\n"); + return; + + default: + vkd3d_unreachable(); + } + defs->values[constant->reg.id + y].f[x] = f; + } + } + + break; + } + + case HLSL_IR_IF: + { + struct hlsl_ir_if *iff = hlsl_ir_if(instr); + allocate_const_registers_recurse(ctx, &iff->then_instrs, liveness); + allocate_const_registers_recurse(ctx, &iff->else_instrs, liveness); + break; + } + + case HLSL_IR_LOOP: + { + struct hlsl_ir_loop *loop = hlsl_ir_loop(instr); + allocate_const_registers_recurse(ctx, &loop->body, liveness); + break; + } + + default: + break; + } + } +} + +static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) +{ + struct liveness liveness = {0}; + struct hlsl_ir_var *var; + + allocate_const_registers_recurse(ctx, &entry_func->body, &liveness); + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + if (var->is_uniform && var->last_read) + { + unsigned int reg_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC]; + + if (reg_size == 0) + continue; + + var->regs[HLSL_REGSET_NUMERIC] = allocate_numeric_registers_for_type(ctx, &liveness, + 1, UINT_MAX, var->data_type); + TRACE("Allocated %s to %s.\n", var->name, + debug_register('c', var->regs[HLSL_REGSET_NUMERIC], var->data_type)); + } + } +} + +/* Simple greedy temporary register allocation pass that just assigns a unique + * index to all (simultaneously live) variables or intermediate values. Agnostic + * as to how many registers are actually available for the current backend, and + * does not handle constants. */ +static void allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) +{ + struct liveness liveness = {0}; + allocate_temp_registers_recurse(ctx, &entry_func->body, &liveness); + ctx->temp_count = liveness.reg_count; + vkd3d_free(liveness.regs); +} + +static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, unsigned int *counter, bool output) +{ + static const char *shader_names[] = + { + [VKD3D_SHADER_TYPE_PIXEL] = "Pixel", + [VKD3D_SHADER_TYPE_VERTEX] = "Vertex", + [VKD3D_SHADER_TYPE_GEOMETRY] = "Geometry", + [VKD3D_SHADER_TYPE_HULL] = "Hull", + [VKD3D_SHADER_TYPE_DOMAIN] = "Domain", + [VKD3D_SHADER_TYPE_COMPUTE] = "Compute", + }; + + unsigned int type; + uint32_t reg; + bool builtin; + + assert(var->semantic.name); + + if (ctx->profile->major_version < 4) + { + D3DDECLUSAGE usage; + uint32_t usage_idx; + + if (!hlsl_sm1_usage_from_semantic(&var->semantic, &usage, &usage_idx)) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, + "Invalid semantic '%s'.", var->semantic.name); + return; + } + + if ((!output && !var->last_read) || (output && !var->first_write)) + return; + + builtin = hlsl_sm1_register_from_semantic(ctx, &var->semantic, output, &type, ®); + } + else + { + D3D_NAME usage; + bool has_idx; + + if (!hlsl_sm4_usage_from_semantic(ctx, &var->semantic, output, &usage)) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, + "Invalid semantic '%s'.", var->semantic.name); + return; + } + if ((builtin = hlsl_sm4_register_from_semantic(ctx, &var->semantic, output, &type, NULL, &has_idx))) + reg = has_idx ? var->semantic.index : 0; + } + + if (builtin) + { + TRACE("%s %s semantic %s[%u] matches predefined register %#x[%u].\n", shader_names[ctx->profile->type], + output ? "output" : "input", var->semantic.name, var->semantic.index, type, reg); + } + else + { + var->regs[HLSL_REGSET_NUMERIC].allocated = true; + var->regs[HLSL_REGSET_NUMERIC].id = (*counter)++; + var->regs[HLSL_REGSET_NUMERIC].writemask = (1 << var->data_type->dimx) - 1; + TRACE("Allocated %s to %s.\n", var->name, debug_register(output ? 'o' : 'v', + var->regs[HLSL_REGSET_NUMERIC], var->data_type)); + } +} + +static void allocate_semantic_registers(struct hlsl_ctx *ctx) +{ + unsigned int input_counter = 0, output_counter = 0; + struct hlsl_ir_var *var; + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + if (var->is_input_semantic) + allocate_semantic_register(ctx, var, &input_counter, false); + if (var->is_output_semantic) + allocate_semantic_register(ctx, var, &output_counter, true); + } +} + +static const struct hlsl_buffer *get_reserved_buffer(struct hlsl_ctx *ctx, uint32_t index) +{ + const struct hlsl_buffer *buffer; + + LIST_FOR_EACH_ENTRY(buffer, &ctx->buffers, const struct hlsl_buffer, entry) + { + if (buffer->used_size && buffer->reservation.type == 'b' && buffer->reservation.index == index) + return buffer; + } + return NULL; +} + +static void calculate_buffer_offset(struct hlsl_ir_var *var) +{ + struct hlsl_buffer *buffer = var->buffer; + + buffer->size = hlsl_type_get_sm4_offset(var->data_type, buffer->size); + + var->buffer_offset = buffer->size; + TRACE("Allocated buffer offset %u to %s.\n", var->buffer_offset, var->name); + buffer->size += var->data_type->reg_size[HLSL_REGSET_NUMERIC]; + if (var->last_read) + buffer->used_size = buffer->size; +} + +static void allocate_buffers(struct hlsl_ctx *ctx) +{ + struct hlsl_buffer *buffer; + struct hlsl_ir_var *var; + uint32_t index = 0; + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + if (var->is_uniform && var->data_type->type != HLSL_CLASS_OBJECT) + { + if (var->is_param) + var->buffer = ctx->params_buffer; + + calculate_buffer_offset(var); + } + } + + LIST_FOR_EACH_ENTRY(buffer, &ctx->buffers, struct hlsl_buffer, entry) + { + if (!buffer->used_size) + continue; + + if (buffer->type == HLSL_BUFFER_CONSTANT) + { + if (buffer->reservation.type == 'b') + { + const struct hlsl_buffer *reserved_buffer = get_reserved_buffer(ctx, buffer->reservation.index); + + if (reserved_buffer && reserved_buffer != buffer) + { + hlsl_error(ctx, &buffer->loc, VKD3D_SHADER_ERROR_HLSL_OVERLAPPING_RESERVATIONS, + "Multiple buffers bound to cb%u.", buffer->reservation.index); + hlsl_note(ctx, &reserved_buffer->loc, VKD3D_SHADER_LOG_ERROR, + "Buffer %s is already bound to cb%u.", reserved_buffer->name, buffer->reservation.index); + } + + buffer->reg.id = buffer->reservation.index; + buffer->reg.allocated = true; + TRACE("Allocated reserved %s to cb%u.\n", buffer->name, index); + } + else if (!buffer->reservation.type) + { + while (get_reserved_buffer(ctx, index)) + ++index; + + buffer->reg.id = index; + buffer->reg.allocated = true; + TRACE("Allocated %s to cb%u.\n", buffer->name, index); + ++index; + } + else + { + hlsl_error(ctx, &buffer->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, + "Constant buffers must be allocated to register type 'b'."); + } + } + else + { + FIXME("Allocate registers for texture buffers.\n"); + } + } +} + +static const struct hlsl_ir_var *get_allocated_object(struct hlsl_ctx *ctx, enum hlsl_regset regset, + uint32_t index) +{ + const struct hlsl_ir_var *var; + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, const struct hlsl_ir_var, extern_entry) + { + if (!var->regs[regset].allocated) + continue; + + if (index == var->regs[regset].id) + return var; + } + return NULL; +} + +static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_regset regset) +{ + char regset_name = get_regset_name(regset); + struct hlsl_ir_var *var; + uint32_t min_index = 0; + uint32_t index; + + if (regset == HLSL_REGSET_UAVS) + { + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + if (var->semantic.name && (!ascii_strcasecmp(var->semantic.name, "color") + || !ascii_strcasecmp(var->semantic.name, "sv_target"))) + min_index = max(min_index, var->semantic.index + 1); + } + } + + index = min_index; + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + if (!var->last_read || !var->data_type->reg_size[regset]) + continue; + + if (var->regs[regset].allocated) + { + const struct hlsl_ir_var *reserved_object; + unsigned int index = var->regs[regset].id; + + reserved_object = get_allocated_object(ctx, regset, index); + + if (var->regs[regset].id < min_index) + { + assert(regset == HLSL_REGSET_UAVS); + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_OVERLAPPING_RESERVATIONS, + "UAV index (%u) must be higher than the maximum render target index (%u).", + var->regs[regset].id, min_index - 1); + } + else if (reserved_object && reserved_object != var) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_OVERLAPPING_RESERVATIONS, + "Multiple objects bound to %c%u.", regset_name, index); + hlsl_note(ctx, &reserved_object->loc, VKD3D_SHADER_LOG_ERROR, + "Object '%s' is already bound to %c%u.", reserved_object->name, + regset_name, index); + } + + var->regs[regset].id = var->reg_reservation.index; + var->regs[regset].allocated = true; + TRACE("Allocated reserved %s to %c%u.\n", var->name, regset_name, var->regs[regset].id); + } + else + { + while (get_allocated_object(ctx, regset, index)) + ++index; + + var->regs[regset].id = index; + var->regs[regset].allocated = true; + TRACE("Allocated object to %c%u.\n", regset_name, index); + ++index; + } + } +} + +bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, + unsigned int *start, unsigned int *count) +{ + struct hlsl_type *type = deref->var->data_type; + unsigned int i, k; + + *start = 0; + *count = 0; + + for (i = 0; i < deref->path_len; ++i) + { + struct hlsl_ir_node *path_node = deref->path[i].node; + unsigned int idx = 0; + + assert(path_node); + if (path_node->type != HLSL_IR_CONSTANT) + return false; + + /* We should always have generated a cast to UINT. */ + assert(path_node->data_type->type == HLSL_CLASS_SCALAR + && path_node->data_type->base_type == HLSL_TYPE_UINT); + + idx = hlsl_ir_constant(path_node)->value[0].u; + + switch (type->type) + { + case HLSL_CLASS_VECTOR: + if (idx >= type->dimx) + { + hlsl_error(ctx, &path_node->loc, VKD3D_SHADER_ERROR_HLSL_OFFSET_OUT_OF_BOUNDS, + "Vector index is out of bounds. %u/%u", idx, type->dimx); + return false; + } + *start += idx; + break; + + case HLSL_CLASS_MATRIX: + if (idx >= hlsl_type_major_size(type)) + { + hlsl_error(ctx, &path_node->loc, VKD3D_SHADER_ERROR_HLSL_OFFSET_OUT_OF_BOUNDS, + "Matrix index is out of bounds. %u/%u", idx, hlsl_type_major_size(type)); + return false; + } + if (hlsl_type_is_row_major(type)) + *start += idx * type->dimx; + else + *start += idx * type->dimy; + break; + + case HLSL_CLASS_ARRAY: + if (idx >= type->e.array.elements_count) + { + hlsl_error(ctx, &path_node->loc, VKD3D_SHADER_ERROR_HLSL_OFFSET_OUT_OF_BOUNDS, + "Array index is out of bounds. %u/%u", idx, type->e.array.elements_count); + return false; + } + *start += idx * hlsl_type_component_count(type->e.array.type); + break; + + case HLSL_CLASS_STRUCT: + for (k = 0; k < idx; ++k) + *start += hlsl_type_component_count(type->e.record.fields[k].type); + break; + + default: + vkd3d_unreachable(); + } + + type = hlsl_get_element_type_from_path_index(ctx, type, path_node); + } + + *count = hlsl_type_component_count(type); + return true; +} + +bool hlsl_offset_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, unsigned int *offset) +{ + struct hlsl_ir_node *offset_node = deref->offset.node; + unsigned int size; + + if (!offset_node) + { + *offset = 0; + return true; + } + + /* We should always have generated a cast to UINT. */ + assert(offset_node->data_type->type == HLSL_CLASS_SCALAR + && offset_node->data_type->base_type == HLSL_TYPE_UINT); + + if (offset_node->type != HLSL_IR_CONSTANT) + return false; + + *offset = hlsl_ir_constant(offset_node)->value[0].u; + + size = deref->var->data_type->reg_size[deref->offset_regset]; + if (*offset >= size) + { + hlsl_error(ctx, &deref->offset.node->loc, VKD3D_SHADER_ERROR_HLSL_OFFSET_OUT_OF_BOUNDS, + "Dereference is out of bounds. %u/%u", *offset, size); + return false; + } + + return true; +} + +unsigned int hlsl_offset_from_deref_safe(struct hlsl_ctx *ctx, const struct hlsl_deref *deref) +{ + unsigned int offset; + + if (hlsl_offset_from_deref(ctx, deref, &offset)) + return offset; + + hlsl_fixme(ctx, &deref->offset.node->loc, "Dereference with non-constant offset of type %s.", + hlsl_node_type_to_string(deref->offset.node->type)); + + return 0; +} + +struct hlsl_reg hlsl_reg_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref) +{ + const struct hlsl_ir_var *var = deref->var; + struct hlsl_reg ret = var->regs[HLSL_REGSET_NUMERIC]; + unsigned int offset = hlsl_offset_from_deref_safe(ctx, deref); + + assert(deref->offset_regset == HLSL_REGSET_NUMERIC); + + ret.id += offset / 4; + + ret.writemask = 0xf & (0xf << (offset % 4)); + if (var->regs[HLSL_REGSET_NUMERIC].writemask) + ret.writemask = hlsl_combine_writemasks(var->regs[HLSL_REGSET_NUMERIC].writemask, ret.writemask); + + return ret; +} + +static void parse_numthreads_attribute(struct hlsl_ctx *ctx, const struct hlsl_attribute *attr) +{ + unsigned int i; + + ctx->found_numthreads = 1; + + if (attr->args_count != 3) + { + hlsl_error(ctx, &attr->loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Expected 3 parameters for [numthreads] attribute, but got %u.", attr->args_count); + return; + } + + for (i = 0; i < attr->args_count; ++i) + { + const struct hlsl_ir_node *instr = attr->args[i].node; + const struct hlsl_type *type = instr->data_type; + const struct hlsl_ir_constant *constant; + + if (type->type != HLSL_CLASS_SCALAR + || (type->base_type != HLSL_TYPE_INT && type->base_type != HLSL_TYPE_UINT)) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, type))) + hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Wrong type for argument %u of [numthreads]: expected int or uint, but got %s.", + i, string->buffer); + hlsl_release_string_buffer(ctx, string); + break; + } + + if (instr->type != HLSL_IR_CONSTANT) + { + hlsl_fixme(ctx, &instr->loc, "Non-constant expression in [numthreads] initializer."); + break; + } + constant = hlsl_ir_constant(instr); + + if ((type->base_type == HLSL_TYPE_INT && constant->value[0].i <= 0) + || (type->base_type == HLSL_TYPE_UINT && !constant->value[0].u)) + hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_THREAD_COUNT, + "Thread count must be a positive integer."); + + ctx->thread_count[i] = constant->value[0].u; + } +} + +int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, + enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out) +{ + const struct hlsl_profile_info *profile = ctx->profile; + struct hlsl_block *const body = &entry_func->body; + struct recursive_call_ctx recursive_call_ctx; + struct hlsl_ir_var *var; + unsigned int i; + bool progress; + + list_move_head(&body->instrs, &ctx->static_initializers); + + memset(&recursive_call_ctx, 0, sizeof(recursive_call_ctx)); + transform_ir(ctx, find_recursive_calls, body, &recursive_call_ctx); + vkd3d_free(recursive_call_ctx.backtrace); + + /* Avoid going into an infinite loop when processing call instructions. + * lower_return() recurses into inferior calls. */ + if (ctx->result) + return ctx->result; + + lower_return(ctx, entry_func, body, false); + + while (transform_ir(ctx, lower_calls, body, NULL)); + + LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry) + { + if (var->storage_modifiers & HLSL_STORAGE_UNIFORM) + prepend_uniform_copy(ctx, &body->instrs, var); + } + + for (i = 0; i < entry_func->parameters.count; ++i) + { + var = entry_func->parameters.vars[i]; + + if (var->data_type->type == HLSL_CLASS_OBJECT || (var->storage_modifiers & HLSL_STORAGE_UNIFORM)) + { + prepend_uniform_copy(ctx, &body->instrs, var); + } + else + { + if (var->data_type->type != HLSL_CLASS_STRUCT && !var->semantic.name) + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, + "Parameter \"%s\" is missing a semantic.", var->name); + + if (var->storage_modifiers & HLSL_STORAGE_IN) + prepend_input_var_copy(ctx, &body->instrs, var); + if (var->storage_modifiers & HLSL_STORAGE_OUT) + append_output_var_copy(ctx, &body->instrs, var); + } + } + if (entry_func->return_var) + { + if (entry_func->return_var->data_type->type != HLSL_CLASS_STRUCT && !entry_func->return_var->semantic.name) + hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, + "Entry point \"%s\" is missing a return value semantic.", entry_func->func->name); + + append_output_var_copy(ctx, &body->instrs, entry_func->return_var); + } + + for (i = 0; i < entry_func->attr_count; ++i) + { + const struct hlsl_attribute *attr = entry_func->attrs[i]; + + if (!strcmp(attr->name, "numthreads") && profile->type == VKD3D_SHADER_TYPE_COMPUTE) + parse_numthreads_attribute(ctx, attr); + else + hlsl_warning(ctx, &entry_func->attrs[i]->loc, VKD3D_SHADER_WARNING_HLSL_UNKNOWN_ATTRIBUTE, + "Ignoring unknown attribute \"%s\".", entry_func->attrs[i]->name); + } + + if (profile->type == VKD3D_SHADER_TYPE_COMPUTE && !ctx->found_numthreads) + hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_ATTRIBUTE, + "Entry point \"%s\" is missing a [numthreads] attribute.", entry_func->func->name); + + transform_ir(ctx, lower_broadcasts, body, NULL); + while (transform_ir(ctx, fold_redundant_casts, body, NULL)); + do + { + progress = transform_ir(ctx, split_array_copies, body, NULL); + progress |= transform_ir(ctx, split_struct_copies, body, NULL); + } + while (progress); + transform_ir(ctx, split_matrix_copies, body, NULL); + + transform_ir(ctx, lower_narrowing_casts, body, NULL); + transform_ir(ctx, lower_casts_to_bool, body, NULL); + transform_ir(ctx, lower_int_division, body, NULL); + transform_ir(ctx, lower_int_modulus, body, NULL); + transform_ir(ctx, lower_int_abs, body, NULL); + transform_ir(ctx, lower_float_modulus, body, NULL); + do + { + progress = transform_ir(ctx, hlsl_fold_constant_exprs, body, NULL); + progress |= transform_ir(ctx, hlsl_fold_constant_swizzles, body, NULL); + progress |= copy_propagation_execute(ctx, body); + progress |= transform_ir(ctx, fold_swizzle_chains, body, NULL); + progress |= transform_ir(ctx, remove_trivial_swizzles, body, NULL); + } + while (progress); + + if (profile->major_version < 4) + { + transform_ir(ctx, lower_division, body, NULL); + transform_ir(ctx, lower_sqrt, body, NULL); + transform_ir(ctx, lower_dot, body, NULL); + } + + if (profile->major_version < 2) + { + transform_ir(ctx, lower_abs, body, NULL); + } + + transform_ir(ctx, validate_static_object_references, body, NULL); + + /* TODO: move forward, remove when no longer needed */ + transform_ir(ctx, transform_deref_paths_into_offsets, body, NULL); + while (transform_ir(ctx, hlsl_fold_constant_exprs, body, NULL)); + + do + compute_liveness(ctx, entry_func); + while (transform_ir(ctx, dce, body, NULL)); + + compute_liveness(ctx, entry_func); + + if (TRACE_ON()) + rb_for_each_entry(&ctx->functions, dump_function, ctx); + + allocate_register_reservations(ctx); + allocate_temp_registers(ctx, entry_func); + if (profile->major_version < 4) + { + allocate_const_registers(ctx, entry_func); + } + else + { + allocate_buffers(ctx); + allocate_objects(ctx, HLSL_REGSET_TEXTURES); + allocate_objects(ctx, HLSL_REGSET_UAVS); + } + allocate_semantic_registers(ctx); + allocate_objects(ctx, HLSL_REGSET_SAMPLERS); + + if (ctx->result) + return ctx->result; + + switch (target_type) + { + case VKD3D_SHADER_TARGET_D3D_BYTECODE: + return hlsl_sm1_write(ctx, entry_func, out); + + case VKD3D_SHADER_TARGET_DXBC_TPF: + return hlsl_sm4_write(ctx, entry_func, out); + + default: + ERR("Unsupported shader target type %#x.\n", target_type); + return VKD3D_ERROR_INVALID_ARGUMENT; + } +} diff --git a/dll/directx/wine/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c b/dll/directx/wine/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c new file mode 100644 index 0000000000000..3210bbd571211 --- /dev/null +++ b/dll/directx/wine/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c @@ -0,0 +1,624 @@ +/* + * HLSL constant value operations for constant folding + * + * Copyright 2022 Francisco Casas for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#include "hlsl.h" + +static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, struct hlsl_ir_constant *src) +{ + unsigned int k; + uint32_t u; + int32_t i; + double d; + float f; + + if (dst->node.data_type->dimx != src->node.data_type->dimx + || dst->node.data_type->dimy != src->node.data_type->dimy) + { + FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, src->node.data_type), + debug_hlsl_type(ctx, dst->node.data_type)); + return false; + } + + for (k = 0; k < 4; ++k) + { + switch (src->node.data_type->base_type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + u = src->value[k].f; + i = src->value[k].f; + f = src->value[k].f; + d = src->value[k].f; + break; + + case HLSL_TYPE_DOUBLE: + u = src->value[k].d; + i = src->value[k].d; + f = src->value[k].d; + d = src->value[k].d; + break; + + case HLSL_TYPE_INT: + u = src->value[k].i; + i = src->value[k].i; + f = src->value[k].i; + d = src->value[k].i; + break; + + case HLSL_TYPE_UINT: + u = src->value[k].u; + i = src->value[k].u; + f = src->value[k].u; + d = src->value[k].u; + break; + + case HLSL_TYPE_BOOL: + u = !!src->value[k].u; + i = !!src->value[k].u; + f = !!src->value[k].u; + d = !!src->value[k].u; + break; + + default: + vkd3d_unreachable(); + } + + switch (dst->node.data_type->base_type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + dst->value[k].f = f; + break; + + case HLSL_TYPE_DOUBLE: + dst->value[k].d = d; + break; + + case HLSL_TYPE_INT: + dst->value[k].i = i; + break; + + case HLSL_TYPE_UINT: + dst->value[k].u = u; + break; + + case HLSL_TYPE_BOOL: + /* Casts to bool should have already been lowered. */ + default: + vkd3d_unreachable(); + } + } + return true; +} + +static bool fold_neg(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, struct hlsl_ir_constant *src) +{ + enum hlsl_base_type type = dst->node.data_type->base_type; + unsigned int k; + + assert(type == src->node.data_type->base_type); + + for (k = 0; k < 4; ++k) + { + switch (type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + dst->value[k].f = -src->value[k].f; + break; + + case HLSL_TYPE_DOUBLE: + dst->value[k].d = -src->value[k].d; + break; + + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + dst->value[k].u = -src->value[k].u; + break; + + default: + FIXME("Fold negation for type %s.\n", debug_hlsl_type(ctx, dst->node.data_type)); + return false; + } + } + return true; +} + +static bool fold_add(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, struct hlsl_ir_constant *src1, + struct hlsl_ir_constant *src2) +{ + enum hlsl_base_type type = dst->node.data_type->base_type; + unsigned int k; + + assert(type == src1->node.data_type->base_type); + assert(type == src2->node.data_type->base_type); + + for (k = 0; k < 4; ++k) + { + switch (type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + dst->value[k].f = src1->value[k].f + src2->value[k].f; + break; + + case HLSL_TYPE_DOUBLE: + dst->value[k].d = src1->value[k].d + src2->value[k].d; + break; + + /* Handling HLSL_TYPE_INT through the unsigned field to avoid + * undefined behavior with signed integers in C. */ + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + dst->value[k].u = src1->value[k].u + src2->value[k].u; + break; + + default: + FIXME("Fold addition for type %s.\n", debug_hlsl_type(ctx, dst->node.data_type)); + return false; + } + } + return true; +} + +static bool fold_mul(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, + struct hlsl_ir_constant *src1, struct hlsl_ir_constant *src2) +{ + enum hlsl_base_type type = dst->node.data_type->base_type; + unsigned int k; + + assert(type == src1->node.data_type->base_type); + assert(type == src2->node.data_type->base_type); + + for (k = 0; k < 4; ++k) + { + switch (type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + dst->value[k].f = src1->value[k].f * src2->value[k].f; + break; + + case HLSL_TYPE_DOUBLE: + dst->value[k].d = src1->value[k].d * src2->value[k].d; + break; + + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + dst->value[k].u = src1->value[k].u * src2->value[k].u; + break; + + default: + FIXME("Fold multiplication for type %s.\n", debug_hlsl_type(ctx, dst->node.data_type)); + return false; + } + } + return true; +} + +static bool fold_nequal(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, + struct hlsl_ir_constant *src1, struct hlsl_ir_constant *src2) +{ + unsigned int k; + + assert(dst->node.data_type->base_type == HLSL_TYPE_BOOL); + assert(src1->node.data_type->base_type == src2->node.data_type->base_type); + + for (k = 0; k < 4; ++k) + { + switch (src1->node.data_type->base_type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + dst->value[k].u = src1->value[k].f != src2->value[k].f; + break; + + case HLSL_TYPE_DOUBLE: + dst->value[k].u = src1->value[k].d != src2->value[k].d; + break; + + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + case HLSL_TYPE_BOOL: + dst->value[k].u = src1->value[k].u != src2->value[k].u; + break; + + default: + vkd3d_unreachable(); + } + + dst->value[k].u *= ~0u; + } + return true; +} + +static bool fold_div(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, + struct hlsl_ir_constant *src1, struct hlsl_ir_constant *src2) +{ + enum hlsl_base_type type = dst->node.data_type->base_type; + unsigned int k; + + assert(type == src1->node.data_type->base_type); + assert(type == src2->node.data_type->base_type); + + for (k = 0; k < dst->node.data_type->dimx; ++k) + { + switch (type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + if (ctx->profile->major_version >= 4 && src2->value[k].f == 0) + { + hlsl_warning(ctx, &dst->node.loc, VKD3D_SHADER_WARNING_HLSL_DIVISION_BY_ZERO, + "Floating point division by zero."); + } + dst->value[k].f = src1->value[k].f / src2->value[k].f; + if (ctx->profile->major_version < 4 && !isfinite(dst->value[k].f)) + { + hlsl_error(ctx, &dst->node.loc, VKD3D_SHADER_ERROR_HLSL_DIVISION_BY_ZERO, + "Infinities and NaNs are not allowed by the shader model."); + } + break; + + case HLSL_TYPE_DOUBLE: + if (src2->value[k].d == 0) + { + hlsl_warning(ctx, &dst->node.loc, VKD3D_SHADER_WARNING_HLSL_DIVISION_BY_ZERO, + "Floating point division by zero."); + } + dst->value[k].d = src1->value[k].d / src2->value[k].d; + break; + + case HLSL_TYPE_INT: + if (src2->value[k].i == 0) + { + hlsl_error(ctx, &dst->node.loc, VKD3D_SHADER_ERROR_HLSL_DIVISION_BY_ZERO, + "Division by zero."); + return false; + } + if (src1->value[k].i == INT_MIN && src2->value[k].i == -1) + dst->value[k].i = INT_MIN; + else + dst->value[k].i = src1->value[k].i / src2->value[k].i; + break; + + case HLSL_TYPE_UINT: + if (src2->value[k].u == 0) + { + hlsl_error(ctx, &dst->node.loc, VKD3D_SHADER_ERROR_HLSL_DIVISION_BY_ZERO, + "Division by zero."); + return false; + } + dst->value[k].u = src1->value[k].u / src2->value[k].u; + break; + + default: + FIXME("Fold division for type %s.\n", debug_hlsl_type(ctx, dst->node.data_type)); + return false; + } + } + return true; +} + +static bool fold_mod(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, + struct hlsl_ir_constant *src1, struct hlsl_ir_constant *src2) +{ + enum hlsl_base_type type = dst->node.data_type->base_type; + unsigned int k; + + assert(type == src1->node.data_type->base_type); + assert(type == src2->node.data_type->base_type); + + for (k = 0; k < dst->node.data_type->dimx; ++k) + { + switch (type) + { + case HLSL_TYPE_INT: + if (src2->value[k].i == 0) + { + hlsl_error(ctx, &dst->node.loc, VKD3D_SHADER_ERROR_HLSL_DIVISION_BY_ZERO, + "Division by zero."); + return false; + } + if (src1->value[k].i == INT_MIN && src2->value[k].i == -1) + dst->value[k].i = 0; + else + dst->value[k].i = src1->value[k].i % src2->value[k].i; + break; + + case HLSL_TYPE_UINT: + if (src2->value[k].u == 0) + { + hlsl_error(ctx, &dst->node.loc, VKD3D_SHADER_ERROR_HLSL_DIVISION_BY_ZERO, + "Division by zero."); + return false; + } + dst->value[k].u = src1->value[k].u % src2->value[k].u; + break; + + default: + FIXME("Fold modulus for type %s.\n", debug_hlsl_type(ctx, dst->node.data_type)); + return false; + } + } + return true; +} + +static bool fold_max(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, + struct hlsl_ir_constant *src1, struct hlsl_ir_constant *src2) +{ + enum hlsl_base_type type = dst->node.data_type->base_type; + unsigned int k; + + assert(type == src1->node.data_type->base_type); + assert(type == src2->node.data_type->base_type); + + for (k = 0; k < dst->node.data_type->dimx; ++k) + { + switch (type) + { + case HLSL_TYPE_INT: + dst->value[k].i = max(src1->value[k].i, src2->value[k].i); + break; + + case HLSL_TYPE_UINT: + dst->value[k].u = max(src1->value[k].u, src2->value[k].u); + break; + + default: + FIXME("Fold max for type %s.\n", debug_hlsl_type(ctx, dst->node.data_type)); + return false; + } + } + return true; +} + +static bool fold_min(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, + struct hlsl_ir_constant *src1, struct hlsl_ir_constant *src2) +{ + enum hlsl_base_type type = dst->node.data_type->base_type; + unsigned int k; + + assert(type == src1->node.data_type->base_type); + assert(type == src2->node.data_type->base_type); + + for (k = 0; k < dst->node.data_type->dimx; ++k) + { + switch (type) + { + case HLSL_TYPE_INT: + dst->value[k].i = min(src1->value[k].i, src2->value[k].i); + break; + + case HLSL_TYPE_UINT: + dst->value[k].u = min(src1->value[k].u, src2->value[k].u); + break; + + default: + FIXME("Fold min for type %s.\n", debug_hlsl_type(ctx, dst->node.data_type)); + return false; + } + } + return true; +} + +static bool fold_bit_xor(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, + struct hlsl_ir_constant *src1, struct hlsl_ir_constant *src2) +{ + enum hlsl_base_type type = dst->node.data_type->base_type; + unsigned int k; + + assert(type == src1->node.data_type->base_type); + assert(type == src2->node.data_type->base_type); + + for (k = 0; k < dst->node.data_type->dimx; ++k) + { + switch (type) + { + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + dst->value[k].u = src1->value[k].u ^ src2->value[k].u; + break; + + default: + FIXME("Fold bit xor for type %s.\n", debug_hlsl_type(ctx, dst->node.data_type)); + return false; + } + } + return true; +} + +static bool fold_bit_and(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, + struct hlsl_ir_constant *src1, struct hlsl_ir_constant *src2) +{ + enum hlsl_base_type type = dst->node.data_type->base_type; + unsigned int k; + + assert(type == src1->node.data_type->base_type); + assert(type == src2->node.data_type->base_type); + + for (k = 0; k < dst->node.data_type->dimx; ++k) + { + switch (type) + { + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + dst->value[k].u = src1->value[k].u & src2->value[k].u; + break; + + default: + FIXME("Fold bit and for type %s.\n", debug_hlsl_type(ctx, dst->node.data_type)); + return false; + } + } + return true; +} + +static bool fold_bit_or(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, + struct hlsl_ir_constant *src1, struct hlsl_ir_constant *src2) +{ + enum hlsl_base_type type = dst->node.data_type->base_type; + unsigned int k; + + assert(type == src1->node.data_type->base_type); + assert(type == src2->node.data_type->base_type); + + for (k = 0; k < dst->node.data_type->dimx; ++k) + { + switch (type) + { + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + dst->value[k].u = src1->value[k].u | src2->value[k].u; + break; + + default: + FIXME("Fold bit or for type %s.\n", debug_hlsl_type(ctx, dst->node.data_type)); + return false; + } + } + return true; +} + +bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_ir_constant *arg1, *arg2 = NULL, *res; + struct hlsl_ir_expr *expr; + unsigned int i; + bool success; + + if (instr->type != HLSL_IR_EXPR) + return false; + expr = hlsl_ir_expr(instr); + if (!expr->operands[0].node) + return false; + + if (instr->data_type->type > HLSL_CLASS_VECTOR) + return false; + + for (i = 0; i < ARRAY_SIZE(expr->operands); ++i) + { + if (expr->operands[i].node) + { + if (expr->operands[i].node->type != HLSL_IR_CONSTANT) + return false; + assert(expr->operands[i].node->data_type->type <= HLSL_CLASS_VECTOR); + } + } + arg1 = hlsl_ir_constant(expr->operands[0].node); + if (expr->operands[1].node) + arg2 = hlsl_ir_constant(expr->operands[1].node); + + if (!(res = hlsl_new_constant(ctx, instr->data_type, &instr->loc))) + return false; + + switch (expr->op) + { + case HLSL_OP1_CAST: + success = fold_cast(ctx, res, arg1); + break; + + case HLSL_OP1_NEG: + success = fold_neg(ctx, res, arg1); + break; + + case HLSL_OP2_ADD: + success = fold_add(ctx, res, arg1, arg2); + break; + + case HLSL_OP2_MUL: + success = fold_mul(ctx, res, arg1, arg2); + break; + + case HLSL_OP2_NEQUAL: + success = fold_nequal(ctx, res, arg1, arg2); + break; + + case HLSL_OP2_DIV: + success = fold_div(ctx, res, arg1, arg2); + break; + + case HLSL_OP2_MOD: + success = fold_mod(ctx, res, arg1, arg2); + break; + + case HLSL_OP2_MAX: + success = fold_max(ctx, res, arg1, arg2); + break; + + case HLSL_OP2_MIN: + success = fold_min(ctx, res, arg1, arg2); + break; + + case HLSL_OP2_BIT_XOR: + success = fold_bit_xor(ctx, res, arg1, arg2); + break; + + case HLSL_OP2_BIT_AND: + success = fold_bit_and(ctx, res, arg1, arg2); + break; + + case HLSL_OP2_BIT_OR: + success = fold_bit_or(ctx, res, arg1, arg2); + break; + + default: + FIXME("Fold \"%s\" expression.\n", debug_hlsl_expr_op(expr->op)); + success = false; + break; + } + + if (success) + { + list_add_before(&expr->node.entry, &res->node.entry); + hlsl_replace_node(&expr->node, &res->node); + } + else + { + vkd3d_free(res); + } + return success; +} + +bool hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_ir_constant *value, *res; + struct hlsl_ir_swizzle *swizzle; + unsigned int i; + + if (instr->type != HLSL_IR_SWIZZLE) + return false; + swizzle = hlsl_ir_swizzle(instr); + if (swizzle->val.node->type != HLSL_IR_CONSTANT) + return false; + value = hlsl_ir_constant(swizzle->val.node); + + if (!(res = hlsl_new_constant(ctx, instr->data_type, &instr->loc))) + return false; + + for (i = 0; i < swizzle->node.data_type->dimx; ++i) + res->value[i] = value->value[hlsl_swizzle_get_component(swizzle->swizzle, i)]; + + list_add_before(&swizzle->node.entry, &res->node.entry); + hlsl_replace_node(&swizzle->node, &res->node); + return true; +} diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/hlsl_sm1.c b/dll/directx/wine/vkd3d/libs/vkd3d-shader/hlsl_sm1.c similarity index 81% rename from dll/directx/wine/d3d12/vkd3d/vkd3d-shader/hlsl_sm1.c rename to dll/directx/wine/vkd3d/libs/vkd3d-shader/hlsl_sm1.c index 90ec6058c4a16..4a62d804ed643 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/hlsl_sm1.c +++ b/dll/directx/wine/vkd3d/libs/vkd3d-shader/hlsl_sm1.c @@ -159,8 +159,7 @@ static D3DXPARAMETER_CLASS sm1_class(const struct hlsl_type *type) return D3DXPC_VECTOR; default: ERR("Invalid class %#x.\n", type->type); - assert(0); - return 0; + vkd3d_unreachable(); } } @@ -193,6 +192,7 @@ static D3DXPARAMETER_TYPE sm1_base_type(const struct hlsl_type *type) return D3DXPT_SAMPLER; default: ERR("Invalid dimension %#x.\n", type->sampler_dim); + vkd3d_unreachable(); } break; case HLSL_TYPE_STRING: @@ -212,6 +212,7 @@ static D3DXPARAMETER_TYPE sm1_base_type(const struct hlsl_type *type) return D3DXPT_TEXTURE; default: ERR("Invalid dimension %#x.\n", type->sampler_dim); + vkd3d_unreachable(); } break; case HLSL_TYPE_VERTEXSHADER: @@ -219,10 +220,8 @@ static D3DXPARAMETER_TYPE sm1_base_type(const struct hlsl_type *type) case HLSL_TYPE_VOID: return D3DXPT_VOID; default: - assert(0); + vkd3d_unreachable(); } - assert(0); - return 0; } static const struct hlsl_type *get_array_type(const struct hlsl_type *type) @@ -243,32 +242,37 @@ static void write_sm1_type(struct vkd3d_bytecode_buffer *buffer, struct hlsl_typ { const struct hlsl_type *array_type = get_array_type(type); unsigned int array_size = get_array_size(type); - struct hlsl_struct_field *field; unsigned int field_count = 0; size_t fields_offset = 0; + size_t i; if (type->bytecode_offset) return; if (array_type->type == HLSL_CLASS_STRUCT) { - LIST_FOR_EACH_ENTRY(field, array_type->e.elements, struct hlsl_struct_field, entry) + field_count = array_type->e.record.field_count; + + for (i = 0; i < field_count; ++i) { + struct hlsl_struct_field *field = &array_type->e.record.fields[i]; + field->name_bytecode_offset = put_string(buffer, field->name); write_sm1_type(buffer, field->type, ctab_start); } fields_offset = bytecode_get_size(buffer) - ctab_start; - LIST_FOR_EACH_ENTRY(field, array_type->e.elements, struct hlsl_struct_field, entry) + for (i = 0; i < field_count; ++i) { + struct hlsl_struct_field *field = &array_type->e.record.fields[i]; + put_u32(buffer, field->name_bytecode_offset - ctab_start); put_u32(buffer, field->type->bytecode_offset - ctab_start); - ++field_count; } } - type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(sm1_class(type), sm1_base_type(type))); + type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(sm1_class(type), sm1_base_type(array_type))); put_u32(buffer, vkd3d_make_u32(type->dimy, type->dimx)); put_u32(buffer, vkd3d_make_u32(array_size, field_count)); put_u32(buffer, fields_offset); @@ -311,7 +315,9 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { - if (!var->semantic.name && var->reg.allocated) + enum hlsl_regset regset = hlsl_type_get_regset(var->data_type); + + if (!var->semantic.name && var->regs[regset].allocated) { ++uniform_count; @@ -349,20 +355,24 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { - if (!var->semantic.name && var->reg.allocated) + enum hlsl_regset regset = hlsl_type_get_regset(var->data_type); + + if (!var->semantic.name && var->regs[regset].allocated) { put_u32(buffer, 0); /* name */ if (var->data_type->type == HLSL_CLASS_OBJECT && (var->data_type->base_type == HLSL_TYPE_SAMPLER || var->data_type->base_type == HLSL_TYPE_TEXTURE)) { - put_u32(buffer, vkd3d_make_u32(D3DXRS_SAMPLER, var->reg.id)); + assert(regset == HLSL_REGSET_SAMPLERS); + put_u32(buffer, vkd3d_make_u32(D3DXRS_SAMPLER, var->regs[regset].id)); put_u32(buffer, 1); } else { - put_u32(buffer, vkd3d_make_u32(D3DXRS_FLOAT4, var->reg.id)); - put_u32(buffer, var->data_type->reg_size / 4); + assert(regset == HLSL_REGSET_NUMERIC); + put_u32(buffer, vkd3d_make_u32(D3DXRS_FLOAT4, var->regs[regset].id)); + put_u32(buffer, var->data_type->reg_size[regset] / 4); } put_u32(buffer, 0); /* type */ put_u32(buffer, 0); /* FIXME: default value */ @@ -373,7 +383,9 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { - if (!var->semantic.name && var->reg.allocated) + enum hlsl_regset regset = hlsl_type_get_regset(var->data_type); + + if (!var->semantic.name && var->regs[regset].allocated) { size_t var_offset = vars_start + (uniform_count * 5 * sizeof(uint32_t)); size_t name_offset; @@ -418,7 +430,7 @@ struct sm1_instruction D3DSHADER_PARAM_SRCMOD_TYPE mod; unsigned int swizzle; uint32_t reg; - } srcs[2]; + } srcs[3]; unsigned int src_count; unsigned int has_dst; @@ -431,11 +443,9 @@ static void write_sm1_dst_register(struct vkd3d_bytecode_buffer *buffer, const s } static void write_sm1_src_register(struct vkd3d_bytecode_buffer *buffer, - const struct sm1_src_register *reg, unsigned int dst_writemask) + const struct sm1_src_register *reg) { - unsigned int swizzle = hlsl_map_swizzle(reg->swizzle, dst_writemask); - - put_u32(buffer, (1u << 31) | sm1_encode_register_type(reg->type) | reg->mod | (swizzle << 16) | reg->reg); + put_u32(buffer, (1u << 31) | sm1_encode_register_type(reg->type) | reg->mod | (reg->swizzle << 16) | reg->reg); } static void write_sm1_instruction(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, @@ -452,14 +462,74 @@ static void write_sm1_instruction(struct hlsl_ctx *ctx, struct vkd3d_bytecode_bu write_sm1_dst_register(buffer, &instr->dst); for (i = 0; i < instr->src_count; ++i) - write_sm1_src_register(buffer, &instr->srcs[i], instr->dst.writemask); + write_sm1_src_register(buffer, &instr->srcs[i]); }; +static void sm1_map_src_swizzle(struct sm1_src_register *src, unsigned int map_writemask) +{ + src->swizzle = hlsl_map_swizzle(src->swizzle, map_writemask); +} + +static void write_sm1_dp2add(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, + const struct hlsl_reg *dst, const struct hlsl_reg *src1, const struct hlsl_reg *src2, + const struct hlsl_reg *src3) +{ + struct sm1_instruction instr = + { + .opcode = D3DSIO_DP2ADD, + + .dst.type = D3DSPR_TEMP, + .dst.writemask = dst->writemask, + .dst.reg = dst->id, + .has_dst = 1, + + .srcs[0].type = D3DSPR_TEMP, + .srcs[0].swizzle = hlsl_swizzle_from_writemask(src1->writemask), + .srcs[0].reg = src1->id, + .srcs[1].type = D3DSPR_TEMP, + .srcs[1].swizzle = hlsl_swizzle_from_writemask(src2->writemask), + .srcs[1].reg = src2->id, + .srcs[2].type = D3DSPR_TEMP, + .srcs[2].swizzle = hlsl_swizzle_from_writemask(src3->writemask), + .srcs[2].reg = src3->id, + .src_count = 3, + }; + + write_sm1_instruction(ctx, buffer, &instr); +} + static void write_sm1_binary_op(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, D3DSHADER_INSTRUCTION_OPCODE_TYPE opcode, const struct hlsl_reg *dst, const struct hlsl_reg *src1, const struct hlsl_reg *src2) { - const struct sm1_instruction instr = + struct sm1_instruction instr = + { + .opcode = opcode, + + .dst.type = D3DSPR_TEMP, + .dst.writemask = dst->writemask, + .dst.reg = dst->id, + .has_dst = 1, + + .srcs[0].type = D3DSPR_TEMP, + .srcs[0].swizzle = hlsl_swizzle_from_writemask(src1->writemask), + .srcs[0].reg = src1->id, + .srcs[1].type = D3DSPR_TEMP, + .srcs[1].swizzle = hlsl_swizzle_from_writemask(src2->writemask), + .srcs[1].reg = src2->id, + .src_count = 2, + }; + + sm1_map_src_swizzle(&instr.srcs[0], instr.dst.writemask); + sm1_map_src_swizzle(&instr.srcs[1], instr.dst.writemask); + write_sm1_instruction(ctx, buffer, &instr); +} + +static void write_sm1_binary_op_dot(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, + D3DSHADER_INSTRUCTION_OPCODE_TYPE opcode, const struct hlsl_reg *dst, + const struct hlsl_reg *src1, const struct hlsl_reg *src2) +{ + struct sm1_instruction instr = { .opcode = opcode, @@ -476,18 +546,20 @@ static void write_sm1_binary_op(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buff .srcs[1].reg = src2->id, .src_count = 2, }; + write_sm1_instruction(ctx, buffer, &instr); } static void write_sm1_unary_op(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, D3DSHADER_INSTRUCTION_OPCODE_TYPE opcode, const struct hlsl_reg *dst, - const struct hlsl_reg *src, D3DSHADER_PARAM_SRCMOD_TYPE src_mod) + const struct hlsl_reg *src, D3DSHADER_PARAM_SRCMOD_TYPE src_mod, D3DSHADER_PARAM_DSTMOD_TYPE dst_mod) { - const struct sm1_instruction instr = + struct sm1_instruction instr = { .opcode = opcode, .dst.type = D3DSPR_TEMP, + .dst.mod = dst_mod, .dst.writemask = dst->writemask, .dst.reg = dst->id, .has_dst = 1, @@ -498,6 +570,8 @@ static void write_sm1_unary_op(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe .srcs[0].mod = src_mod, .src_count = 1, }; + + sm1_map_src_swizzle(&instr.srcs[0], instr.dst.writemask); write_sm1_instruction(ctx, buffer, &instr); } @@ -543,7 +617,7 @@ static void write_sm1_semantic_dcl(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b ret = hlsl_sm1_usage_from_semantic(&var->semantic, &usage, &usage_idx); assert(ret); reg.type = output ? D3DSPR_OUTPUT : D3DSPR_INPUT; - reg.reg = var->reg.id; + reg.reg = var->regs[HLSL_REGSET_NUMERIC].id; } token = D3DSIO_DCL; @@ -602,15 +676,33 @@ static void write_sm1_constant(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe assert(instr->reg.allocated); assert(constant->reg.allocated); + sm1_map_src_swizzle(&sm1_instr.srcs[0], sm1_instr.dst.writemask); write_sm1_instruction(ctx, buffer, &sm1_instr); } +static void write_sm1_per_component_unary_op(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, + const struct hlsl_ir_node *instr, D3DSHADER_INSTRUCTION_OPCODE_TYPE opcode) +{ + struct hlsl_ir_expr *expr = hlsl_ir_expr(instr); + struct hlsl_ir_node *arg1 = expr->operands[0].node; + unsigned int i; + + for (i = 0; i < instr->data_type->dimx; ++i) + { + struct hlsl_reg src = arg1->reg, dst = instr->reg; + + src.writemask = hlsl_combine_writemasks(src.writemask, 1u << i); + dst.writemask = hlsl_combine_writemasks(dst.writemask, 1u << i); + write_sm1_unary_op(ctx, buffer, opcode, &dst, &src, 0, 0); + } +} + static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_node *instr) { struct hlsl_ir_expr *expr = hlsl_ir_expr(instr); struct hlsl_ir_node *arg1 = expr->operands[0].node; struct hlsl_ir_node *arg2 = expr->operands[1].node; - unsigned int i; + struct hlsl_ir_node *arg3 = expr->operands[2].node; assert(instr->reg.allocated); @@ -623,19 +715,28 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b switch (expr->op) { + case HLSL_OP1_ABS: + write_sm1_unary_op(ctx, buffer, D3DSIO_ABS, &instr->reg, &arg1->reg, 0, 0); + break; + + case HLSL_OP1_EXP2: + write_sm1_per_component_unary_op(ctx, buffer, instr, D3DSIO_EXP); + break; + case HLSL_OP1_NEG: - write_sm1_unary_op(ctx, buffer, D3DSIO_MOV, &instr->reg, &arg1->reg, D3DSPSM_NEG); + write_sm1_unary_op(ctx, buffer, D3DSIO_MOV, &instr->reg, &arg1->reg, D3DSPSM_NEG, 0); + break; + + case HLSL_OP1_SAT: + write_sm1_unary_op(ctx, buffer, D3DSIO_MOV, &instr->reg, &arg1->reg, 0, D3DSPDM_SATURATE); break; case HLSL_OP1_RCP: - for (i = 0; i < instr->data_type->dimx; ++i) - { - struct hlsl_reg src = arg1->reg, dst = instr->reg; + write_sm1_per_component_unary_op(ctx, buffer, instr, D3DSIO_RCP); + break; - src.writemask = hlsl_combine_writemasks(src.writemask, 1u << i); - dst.writemask = hlsl_combine_writemasks(dst.writemask, 1u << i); - write_sm1_unary_op(ctx, buffer, D3DSIO_RCP, &dst, &src, 0); - } + case HLSL_OP1_RSQ: + write_sm1_per_component_unary_op(ctx, buffer, instr, D3DSIO_RSQ); break; case HLSL_OP2_ADD: @@ -654,6 +755,30 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b write_sm1_binary_op(ctx, buffer, D3DSIO_MUL, &instr->reg, &arg1->reg, &arg2->reg); break; + case HLSL_OP1_FRACT: + write_sm1_unary_op(ctx, buffer, D3DSIO_FRC, &instr->reg, &arg1->reg, D3DSPSM_NONE, 0); + break; + + case HLSL_OP2_DOT: + switch (arg1->data_type->dimx) + { + case 4: + write_sm1_binary_op_dot(ctx, buffer, D3DSIO_DP4, &instr->reg, &arg1->reg, &arg2->reg); + break; + + case 3: + write_sm1_binary_op_dot(ctx, buffer, D3DSIO_DP3, &instr->reg, &arg1->reg, &arg2->reg); + break; + + default: + vkd3d_unreachable(); + } + break; + + case HLSL_OP3_DP2ADD: + write_sm1_dp2add(ctx, buffer, &instr->reg, &arg1->reg, &arg2->reg, &arg3->reg); + break; + default: hlsl_fixme(ctx, &instr->loc, "SM1 \"%s\" expression.", debug_hlsl_expr_op(expr->op)); break; @@ -663,7 +788,7 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b static void write_sm1_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_node *instr) { const struct hlsl_ir_load *load = hlsl_ir_load(instr); - const struct hlsl_reg reg = hlsl_reg_from_deref(ctx, &load->src, instr->data_type); + const struct hlsl_reg reg = hlsl_reg_from_deref(ctx, &load->src); struct sm1_instruction sm1_instr = { .opcode = D3DSIO_MOV, @@ -699,6 +824,7 @@ static void write_sm1_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b sm1_instr.srcs[0].swizzle = hlsl_swizzle_from_writemask((1 << load->src.var->data_type->dimx) - 1); } + sm1_map_src_swizzle(&sm1_instr.srcs[0], sm1_instr.dst.writemask); write_sm1_instruction(ctx, buffer, &sm1_instr); } @@ -707,7 +833,7 @@ static void write_sm1_store(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer * { const struct hlsl_ir_store *store = hlsl_ir_store(instr); const struct hlsl_ir_node *rhs = store->rhs.node; - const struct hlsl_reg reg = hlsl_reg_from_deref(ctx, &store->lhs, rhs->data_type); + const struct hlsl_reg reg = hlsl_reg_from_deref(ctx, &store->lhs); struct sm1_instruction sm1_instr = { .opcode = D3DSIO_MOV, @@ -744,6 +870,7 @@ static void write_sm1_store(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer * else assert(reg.allocated); + sm1_map_src_swizzle(&sm1_instr.srcs[0], sm1_instr.dst.writemask); write_sm1_instruction(ctx, buffer, &sm1_instr); } @@ -770,6 +897,7 @@ static void write_sm1_swizzle(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer assert(instr->reg.allocated); assert(val->reg.allocated); + sm1_map_src_swizzle(&sm1_instr.srcs[0], sm1_instr.dst.writemask); write_sm1_instruction(ctx, buffer, &sm1_instr); } @@ -790,7 +918,7 @@ static void write_sm1_instructions(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b } else if (instr->data_type->type == HLSL_CLASS_OBJECT) { - hlsl_fixme(ctx, &instr->loc, "Object copy.\n"); + hlsl_fixme(ctx, &instr->loc, "Object copy."); break; } @@ -799,6 +927,9 @@ static void write_sm1_instructions(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b switch (instr->type) { + case HLSL_IR_CALL: + vkd3d_unreachable(); + case HLSL_IR_CONSTANT: write_sm1_constant(ctx, buffer, instr); break; @@ -820,7 +951,7 @@ static void write_sm1_instructions(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b break; default: - FIXME("Unhandled instruction type %s.\n", hlsl_node_type_to_string(instr->type)); + hlsl_fixme(ctx, &instr->loc, "Instruction type %s.", hlsl_node_type_to_string(instr->type)); } } } diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/hlsl_sm4.c b/dll/directx/wine/vkd3d/libs/vkd3d-shader/hlsl_sm4.c similarity index 65% rename from dll/directx/wine/d3d12/vkd3d/vkd3d-shader/hlsl_sm4.c rename to dll/directx/wine/vkd3d/libs/vkd3d-shader/hlsl_sm4.c index 6996bb2d55f80..553a75818e75a 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/hlsl_sm4.c +++ b/dll/directx/wine/vkd3d/libs/vkd3d-shader/hlsl_sm4.c @@ -20,11 +20,25 @@ #include "hlsl.h" #include -#include "vkd3d_d3dcommon.h" +#include "d3dcommon.h" #include "sm4.h" static void write_sm4_block(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_block *block); +static bool type_is_integer(const struct hlsl_type *type) +{ + switch (type->base_type) + { + case HLSL_TYPE_BOOL: + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + return true; + + default: + return false; + } +} + bool hlsl_sm4_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic, bool output, enum vkd3d_sm4_register_type *type, enum vkd3d_sm4_swizzle_type *swizzle_type, bool *has_idx) { @@ -35,21 +49,25 @@ bool hlsl_sm4_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_sem const char *semantic; bool output; enum vkd3d_shader_type shader_type; - enum vkd3d_sm4_register_type type; enum vkd3d_sm4_swizzle_type swizzle_type; + enum vkd3d_sm4_register_type type; bool has_idx; } register_table[] = { - {"sv_primitiveid", false, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SM4_RT_PRIMID, VKD3D_SM4_SWIZZLE_NONE, false}, + {"sv_dispatchthreadid", false, VKD3D_SHADER_TYPE_COMPUTE, VKD3D_SM4_SWIZZLE_VEC4, VKD3D_SM5_RT_THREAD_ID, false}, + {"sv_groupid", false, VKD3D_SHADER_TYPE_COMPUTE, VKD3D_SM4_SWIZZLE_VEC4, VKD3D_SM5_RT_THREAD_GROUP_ID, false}, + {"sv_groupthreadid", false, VKD3D_SHADER_TYPE_COMPUTE, VKD3D_SM4_SWIZZLE_VEC4, VKD3D_SM5_RT_LOCAL_THREAD_ID, false}, + + {"sv_primitiveid", false, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SM4_SWIZZLE_NONE, VKD3D_SM4_RT_PRIMID, false}, /* Put sv_target in this table, instead of letting it fall through to * default varying allocation, so that the register index matches the * usage index. */ - {"color", true, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SM4_RT_OUTPUT, VKD3D_SM4_SWIZZLE_VEC4, true}, - {"depth", true, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SM4_RT_DEPTHOUT, VKD3D_SM4_SWIZZLE_VEC4, false}, - {"sv_depth", true, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SM4_RT_DEPTHOUT, VKD3D_SM4_SWIZZLE_VEC4, false}, - {"sv_target", true, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SM4_RT_OUTPUT, VKD3D_SM4_SWIZZLE_VEC4, true}, + {"color", true, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SM4_SWIZZLE_VEC4, VKD3D_SM4_RT_OUTPUT, true}, + {"depth", true, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SM4_SWIZZLE_VEC4, VKD3D_SM4_RT_DEPTHOUT, false}, + {"sv_depth", true, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SM4_SWIZZLE_VEC4, VKD3D_SM4_RT_DEPTHOUT, false}, + {"sv_target", true, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SM4_SWIZZLE_VEC4, VKD3D_SM4_RT_OUTPUT, true}, }; for (i = 0; i < ARRAY_SIZE(register_table); ++i) @@ -83,6 +101,10 @@ bool hlsl_sm4_usage_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semant } semantics[] = { + {"sv_dispatchthreadid", false, VKD3D_SHADER_TYPE_COMPUTE, ~0u}, + {"sv_groupid", false, VKD3D_SHADER_TYPE_COMPUTE, ~0u}, + {"sv_groupthreadid", false, VKD3D_SHADER_TYPE_COMPUTE, ~0u}, + {"position", false, VKD3D_SHADER_TYPE_GEOMETRY, D3D_NAME_POSITION}, {"sv_position", false, VKD3D_SHADER_TYPE_GEOMETRY, D3D_NAME_POSITION}, {"sv_primitiveid", false, VKD3D_SHADER_TYPE_GEOMETRY, D3D_NAME_PRIMITIVE_ID}, @@ -100,6 +122,7 @@ bool hlsl_sm4_usage_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semant {"sv_depth", true, VKD3D_SHADER_TYPE_PIXEL, D3D_NAME_DEPTH}, {"sv_position", false, VKD3D_SHADER_TYPE_VERTEX, D3D_NAME_UNDEFINED}, + {"sv_vertexid", false, VKD3D_SHADER_TYPE_VERTEX, D3D_NAME_VERTEX_ID}, {"position", true, VKD3D_SHADER_TYPE_VERTEX, D3D_NAME_POSITION}, {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, D3D_NAME_POSITION}, @@ -149,6 +172,8 @@ static void write_sm4_signature(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc, ret = hlsl_sm4_usage_from_semantic(ctx, &var->semantic, output, &usage); assert(ret); + if (usage == ~0u) + continue; usage_idx = var->semantic.index; if (hlsl_sm4_register_from_semantic(ctx, &var->semantic, output, &type, NULL, &has_idx)) @@ -157,9 +182,9 @@ static void write_sm4_signature(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc, } else { - assert(var->reg.allocated); + assert(var->regs[HLSL_REGSET_NUMERIC].allocated); type = VKD3D_SM4_RT_INPUT; - reg_idx = var->reg.id; + reg_idx = var->regs[HLSL_REGSET_NUMERIC].id; } use_mask = width; /* FIXME: accurately report use mask */ @@ -211,6 +236,8 @@ static void write_sm4_signature(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc, continue; hlsl_sm4_usage_from_semantic(ctx, &var->semantic, output, &usage); + if (usage == ~0u) + continue; if (usage == D3D_NAME_TARGET && !ascii_strcasecmp(semantic, "color")) string_offset = put_string(&buffer, "SV_Target"); @@ -264,8 +291,7 @@ static D3D_SHADER_VARIABLE_CLASS sm4_class(const struct hlsl_type *type) return D3D_SVC_VECTOR; default: ERR("Invalid class %#x.\n", type->type); - assert(0); - return 0; + vkd3d_unreachable(); } } @@ -275,6 +301,8 @@ static D3D_SHADER_VARIABLE_TYPE sm4_base_type(const struct hlsl_type *type) { case HLSL_TYPE_BOOL: return D3D_SVT_BOOL; + case HLSL_TYPE_DOUBLE: + return D3D_SVT_DOUBLE; case HLSL_TYPE_FLOAT: case HLSL_TYPE_HALF: return D3D_SVT_FLOAT; @@ -296,7 +324,7 @@ static D3D_SHADER_VARIABLE_TYPE sm4_base_type(const struct hlsl_type *type) case HLSL_SAMPLER_DIM_GENERIC: return D3D_SVT_SAMPLER; default: - assert(0); + vkd3d_unreachable(); } break; case HLSL_TYPE_STRING: @@ -315,7 +343,7 @@ static D3D_SHADER_VARIABLE_TYPE sm4_base_type(const struct hlsl_type *type) case HLSL_SAMPLER_DIM_GENERIC: return D3D_SVT_TEXTURE; default: - assert(0); + vkd3d_unreachable(); } break; case HLSL_TYPE_UINT: @@ -325,10 +353,8 @@ static D3D_SHADER_VARIABLE_TYPE sm4_base_type(const struct hlsl_type *type) case HLSL_TYPE_VOID: return D3D_SVT_VOID; default: - assert(0); + vkd3d_unreachable(); } - assert(0); - return 0; } static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, struct hlsl_type *type) @@ -338,7 +364,7 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b const struct hlsl_profile_info *profile = ctx->profile; unsigned int field_count = 0, array_size = 0; size_t fields_offset = 0, name_offset = 0; - struct hlsl_struct_field *field; + size_t i; if (type->bytecode_offset) return; @@ -351,20 +377,25 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b if (array_type->type == HLSL_CLASS_STRUCT) { - LIST_FOR_EACH_ENTRY(field, array_type->e.elements, struct hlsl_struct_field, entry) + field_count = array_type->e.record.field_count; + + for (i = 0; i < field_count; ++i) { + struct hlsl_struct_field *field = &array_type->e.record.fields[i]; + field->name_bytecode_offset = put_string(buffer, field->name); write_sm4_type(ctx, buffer, field->type); } fields_offset = bytecode_get_size(buffer); - LIST_FOR_EACH_ENTRY(field, array_type->e.elements, struct hlsl_struct_field, entry) + for (i = 0; i < field_count; ++i) { + struct hlsl_struct_field *field = &array_type->e.record.fields[i]; + put_u32(buffer, field->name_bytecode_offset); put_u32(buffer, field->type->bytecode_offset); - put_u32(buffer, field->reg_offset); - ++field_count; + put_u32(buffer, field->reg_offset[HLSL_REGSET_NUMERIC]); } } @@ -391,9 +422,10 @@ static D3D_SHADER_INPUT_TYPE sm4_resource_type(const struct hlsl_type *type) return D3D_SIT_SAMPLER; case HLSL_TYPE_TEXTURE: return D3D_SIT_TEXTURE; + case HLSL_TYPE_UAV: + return D3D_SIT_UAV_RWTYPED; default: - assert(0); - return 0; + vkd3d_unreachable(); } } @@ -417,8 +449,7 @@ static D3D_RESOURCE_RETURN_TYPE sm4_resource_format(const struct hlsl_type *type return D3D_RETURN_TYPE_UINT; default: - assert(0); - return 0; + vkd3d_unreachable(); } } @@ -445,57 +476,64 @@ static D3D_SRV_DIMENSION sm4_rdef_resource_dimension(const struct hlsl_type *typ case HLSL_SAMPLER_DIM_CUBEARRAY: return D3D_SRV_DIMENSION_TEXTURECUBEARRAY; default: - assert(0); - return D3D_SRV_DIMENSION_UNKNOWN; + vkd3d_unreachable(); } } -static int sm4_compare_externs(const struct hlsl_ir_var *a, const struct hlsl_ir_var *b) +static int sm4_compare_extern_resources(const void *a, const void *b) { - if (a->data_type->base_type != b->data_type->base_type) - return a->data_type->base_type - b->data_type->base_type; - if (a->reg.allocated && b->reg.allocated) - return a->reg.id - b->reg.id; - return strcmp(a->name, b->name); + const struct hlsl_ir_var *aa = *(const struct hlsl_ir_var **)a; + const struct hlsl_ir_var *bb = *(const struct hlsl_ir_var **)b; + enum hlsl_regset aa_regset, bb_regset; + + aa_regset = hlsl_type_get_regset(aa->data_type); + bb_regset = hlsl_type_get_regset(bb->data_type); + + if (aa_regset != bb_regset) + return aa_regset - bb_regset; + + return aa->regs[aa_regset].id - bb->regs[bb_regset].id; } -static void sm4_sort_extern(struct list *sorted, struct hlsl_ir_var *to_sort) +static const struct hlsl_ir_var **sm4_get_extern_resources(struct hlsl_ctx *ctx, unsigned int *count) { - struct hlsl_ir_var *var; + const struct hlsl_ir_var **extern_resources = NULL; + const struct hlsl_ir_var *var; + enum hlsl_regset regset; + size_t capacity = 0; - list_remove(&to_sort->extern_entry); + *count = 0; - LIST_FOR_EACH_ENTRY(var, sorted, struct hlsl_ir_var, extern_entry) + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { - if (sm4_compare_externs(to_sort, var) < 0) + if (!hlsl_type_is_resource(var->data_type)) + continue; + regset = hlsl_type_get_regset(var->data_type); + if (!var->regs[regset].allocated) + continue; + + if (!(hlsl_array_reserve(ctx, (void **)&extern_resources, &capacity, *count + 1, + sizeof(*extern_resources)))) { - list_add_before(&var->extern_entry, &to_sort->extern_entry); - return; + *count = 0; + return NULL; } - } - - list_add_tail(sorted, &to_sort->extern_entry); -} - -static void sm4_sort_externs(struct hlsl_ctx *ctx) -{ - struct list sorted = LIST_INIT(sorted); - struct hlsl_ir_var *var, *next; - LIST_FOR_EACH_ENTRY_SAFE(var, next, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) - { - if (var->data_type->type == HLSL_CLASS_OBJECT) - sm4_sort_extern(&sorted, var); + extern_resources[*count] = var; + ++*count; } - list_move_tail(&ctx->extern_vars, &sorted); + + qsort(extern_resources, *count, sizeof(*extern_resources), sm4_compare_extern_resources); + return extern_resources; } static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) { + unsigned int cbuffer_count = 0, resource_count = 0, extern_resources_count, i, j; size_t cbuffers_offset, resources_offset, creator_offset, string_offset; size_t cbuffer_position, resource_position, creator_position; - unsigned int cbuffer_count = 0, resource_count = 0, i, j; const struct hlsl_profile_info *profile = ctx->profile; + const struct hlsl_ir_var **extern_resources; struct vkd3d_bytecode_buffer buffer = {0}; const struct hlsl_buffer *cbuffer; const struct hlsl_ir_var *var; @@ -510,14 +548,9 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) 0x4353, /* COMPUTE */ }; - sm4_sort_externs(ctx); - - LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) - { - if (var->reg.allocated && var->data_type->type == HLSL_CLASS_OBJECT) - ++resource_count; - } + extern_resources = sm4_get_extern_resources(ctx, &extern_resources_count); + resource_count += extern_resources_count; LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) { if (cbuffer->reg.allocated) @@ -553,19 +586,20 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) resources_offset = bytecode_get_size(&buffer); set_u32(&buffer, resource_position, resources_offset); - LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + for (i = 0; i < extern_resources_count; ++i) { + enum hlsl_regset regset; uint32_t flags = 0; - if (!var->reg.allocated || var->data_type->type != HLSL_CLASS_OBJECT) - continue; + var = extern_resources[i]; + regset = hlsl_type_get_regset(var->data_type); if (var->reg_reservation.type) flags |= D3D_SIF_USERPACKED; put_u32(&buffer, 0); /* name */ put_u32(&buffer, sm4_resource_type(var->data_type)); - if (var->data_type->base_type == HLSL_TYPE_SAMPLER) + if (regset == HLSL_REGSET_SAMPLERS) { put_u32(&buffer, 0); put_u32(&buffer, 0); @@ -578,7 +612,7 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) put_u32(&buffer, ~0u); /* FIXME: multisample count */ flags |= (var->data_type->e.resource_format->dimx - 1) << VKD3D_SM4_SIF_TEXTURE_COMPONENTS_SHIFT; } - put_u32(&buffer, var->reg.id); + put_u32(&buffer, var->regs[regset].id); put_u32(&buffer, 1); /* bind count */ put_u32(&buffer, flags); } @@ -603,12 +637,9 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) put_u32(&buffer, flags); /* flags */ } - i = 0; - - LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + for (i = 0; i < extern_resources_count; ++i) { - if (!var->reg.allocated || var->data_type->type != HLSL_CLASS_OBJECT) - continue; + var = extern_resources[i]; string_offset = put_string(&buffer, var->name); set_u32(&buffer, resources_offset + i++ * 8 * sizeof(uint32_t), string_offset); @@ -623,8 +654,6 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) set_u32(&buffer, resources_offset + i++ * 8 * sizeof(uint32_t), string_offset); } - assert(i == resource_count); - /* Buffers. */ cbuffers_offset = bytecode_get_size(&buffer); @@ -681,7 +710,7 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) put_u32(&buffer, 0); /* name */ put_u32(&buffer, var->buffer_offset * sizeof(float)); - put_u32(&buffer, var->data_type->reg_size * sizeof(float)); + put_u32(&buffer, var->data_type->reg_size[HLSL_REGSET_NUMERIC] * sizeof(float)); put_u32(&buffer, flags); put_u32(&buffer, 0); /* type */ put_u32(&buffer, 0); /* FIXME: default value */ @@ -717,6 +746,8 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) set_u32(&buffer, creator_position, creator_offset); dxbc_writer_add_section(dxbc, TAG_RDEF, buffer.data, buffer.size); + + vkd3d_free(extern_resources); } static enum vkd3d_sm4_resource_type sm4_resource_dimension(const struct hlsl_type *type) @@ -742,8 +773,7 @@ static enum vkd3d_sm4_resource_type sm4_resource_dimension(const struct hlsl_typ case HLSL_SAMPLER_DIM_CUBEARRAY: return VKD3D_SM4_RESOURCE_TEXTURE_CUBEARRAY; default: - assert(0); - return 0; + vkd3d_unreachable(); } } @@ -778,8 +808,7 @@ static uint32_t sm4_encode_instruction_modifier(const struct sm4_instruction_mod break; default: - assert(0); - break; + vkd3d_unreachable(); } return word; @@ -817,7 +846,7 @@ struct sm4_instruction } srcs[4]; unsigned int src_count; - uint32_t idx[2]; + uint32_t idx[3]; unsigned int idx_count; }; @@ -835,7 +864,17 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r reg->dim = VKD3D_SM4_DIMENSION_VEC4; if (swizzle_type) *swizzle_type = VKD3D_SM4_SWIZZLE_VEC4; - reg->idx[0] = var->reg.id; + reg->idx[0] = var->regs[HLSL_REGSET_TEXTURES].id; + reg->idx_count = 1; + *writemask = VKD3DSP_WRITEMASK_ALL; + } + else if (data_type->type == HLSL_CLASS_OBJECT && data_type->base_type == HLSL_TYPE_UAV) + { + reg->type = VKD3D_SM5_RT_UAV; + reg->dim = VKD3D_SM4_DIMENSION_VEC4; + if (swizzle_type) + *swizzle_type = VKD3D_SM4_SWIZZLE_VEC4; + reg->idx[0] = var->regs[HLSL_REGSET_UAVS].id; reg->idx_count = 1; *writemask = VKD3DSP_WRITEMASK_ALL; } @@ -845,7 +884,7 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r reg->dim = VKD3D_SM4_DIMENSION_NONE; if (swizzle_type) *swizzle_type = VKD3D_SM4_SWIZZLE_NONE; - reg->idx[0] = var->reg.id; + reg->idx[0] = var->regs[HLSL_REGSET_SAMPLERS].id; reg->idx_count = 1; *writemask = VKD3DSP_WRITEMASK_ALL; } @@ -870,18 +909,20 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r if (hlsl_sm4_register_from_semantic(ctx, &var->semantic, false, ®->type, swizzle_type, &has_idx)) { + unsigned int offset = hlsl_offset_from_deref_safe(ctx, deref); + if (has_idx) { - reg->idx[0] = var->semantic.index; + reg->idx[0] = var->semantic.index + offset / 4; reg->idx_count = 1; } reg->dim = VKD3D_SM4_DIMENSION_VEC4; - *writemask = (1u << data_type->dimx) - 1; + *writemask = ((1u << data_type->dimx) - 1) << (offset % 4); } else { - struct hlsl_reg hlsl_reg = hlsl_reg_from_deref(ctx, deref, data_type); + struct hlsl_reg hlsl_reg = hlsl_reg_from_deref(ctx, deref); assert(hlsl_reg.allocated); reg->type = VKD3D_SM4_RT_INPUT; @@ -899,9 +940,11 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r if (hlsl_sm4_register_from_semantic(ctx, &var->semantic, true, ®->type, swizzle_type, &has_idx)) { + unsigned int offset = hlsl_offset_from_deref_safe(ctx, deref); + if (has_idx) { - reg->idx[0] = var->semantic.index; + reg->idx[0] = var->semantic.index + offset / 4; reg->idx_count = 1; } @@ -909,11 +952,11 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r reg->dim = VKD3D_SM4_DIMENSION_SCALAR; else reg->dim = VKD3D_SM4_DIMENSION_VEC4; - *writemask = (1u << data_type->dimx) - 1; + *writemask = ((1u << data_type->dimx) - 1) << (offset % 4); } else { - struct hlsl_reg hlsl_reg = hlsl_reg_from_deref(ctx, deref, data_type); + struct hlsl_reg hlsl_reg = hlsl_reg_from_deref(ctx, deref); assert(hlsl_reg.allocated); reg->type = VKD3D_SM4_RT_OUTPUT; @@ -925,7 +968,7 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r } else { - struct hlsl_reg hlsl_reg = hlsl_reg_from_deref(ctx, deref, data_type); + struct hlsl_reg hlsl_reg = hlsl_reg_from_deref(ctx, deref); assert(hlsl_reg.allocated); reg->type = VKD3D_SM4_RT_TEMP; @@ -1111,7 +1154,7 @@ static void write_sm4_dcl_sampler(struct vkd3d_bytecode_buffer *buffer, const st .opcode = VKD3D_SM4_OP_DCL_SAMPLER, .dsts[0].reg.type = VKD3D_SM4_RT_SAMPLER, - .dsts[0].reg.idx = {var->reg.id}, + .dsts[0].reg.idx = {var->regs[HLSL_REGSET_SAMPLERS].id}, .dsts[0].reg.idx_count = 1, .dst_count = 1, }; @@ -1120,19 +1163,27 @@ static void write_sm4_dcl_sampler(struct vkd3d_bytecode_buffer *buffer, const st static void write_sm4_dcl_texture(struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_var *var) { - const struct sm4_instruction instr = + bool uav = (var->data_type->base_type == HLSL_TYPE_UAV); + struct sm4_instruction instr = { - .opcode = VKD3D_SM4_OP_DCL_RESOURCE + .opcode = (uav ? VKD3D_SM5_OP_DCL_UAV_TYPED : VKD3D_SM4_OP_DCL_RESOURCE) | (sm4_resource_dimension(var->data_type) << VKD3D_SM4_RESOURCE_TYPE_SHIFT), - .dsts[0].reg.type = VKD3D_SM4_RT_RESOURCE, - .dsts[0].reg.idx = {var->reg.id}, + .dsts[0].reg.type = uav ? VKD3D_SM5_RT_UAV : VKD3D_SM4_RT_RESOURCE, + .dsts[0].reg.idx = {uav ? var->regs[HLSL_REGSET_UAVS].id : var->regs[HLSL_REGSET_TEXTURES].id}, .dsts[0].reg.idx_count = 1, .dst_count = 1, .idx[0] = sm4_resource_format(var->data_type) * 0x1111, .idx_count = 1, }; + + if (var->data_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS + || var->data_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY) + { + instr.opcode |= var->data_type->sample_count << VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT; + } + write_sm4_instruction(buffer, &instr); } @@ -1165,15 +1216,17 @@ static void write_sm4_dcl_semantic(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b else { instr.dsts[0].reg.type = output ? VKD3D_SM4_RT_OUTPUT : VKD3D_SM4_RT_INPUT; - instr.dsts[0].reg.idx[0] = var->reg.id; + instr.dsts[0].reg.idx[0] = var->regs[HLSL_REGSET_NUMERIC].id; instr.dsts[0].reg.idx_count = 1; - instr.dsts[0].writemask = var->reg.writemask; + instr.dsts[0].writemask = var->regs[HLSL_REGSET_NUMERIC].writemask; } if (instr.dsts[0].reg.type == VKD3D_SM4_RT_DEPTHOUT) instr.dsts[0].reg.dim = VKD3D_SM4_DIMENSION_SCALAR; hlsl_sm4_usage_from_semantic(ctx, &var->semantic, output, &usage); + if (usage == ~0u) + usage = D3D_NAME_UNDEFINED; if (var->is_input_semantic) { @@ -1198,7 +1251,14 @@ static void write_sm4_dcl_semantic(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b } if (profile->type == VKD3D_SHADER_TYPE_PIXEL) - instr.opcode |= VKD3DSIM_LINEAR << VKD3D_SM4_INTERPOLATION_MODE_SHIFT; + { + enum vkd3d_shader_interpolation_mode mode = VKD3DSIM_LINEAR; + + if ((var->storage_modifiers & HLSL_STORAGE_NOINTERPOLATION) || type_is_integer(var->data_type)) + mode = VKD3DSIM_CONSTANT; + + instr.opcode |= mode << VKD3D_SM4_INTERPOLATION_MODE_SHIFT; + } } else { @@ -1240,6 +1300,19 @@ static void write_sm4_dcl_temps(struct vkd3d_bytecode_buffer *buffer, uint32_t t write_sm4_instruction(buffer, &instr); } +static void write_sm4_dcl_thread_group(struct vkd3d_bytecode_buffer *buffer, const uint32_t thread_count[3]) +{ + struct sm4_instruction instr = + { + .opcode = VKD3D_SM5_OP_DCL_THREAD_GROUP, + + .idx = {thread_count[0], thread_count[1], thread_count[2]}, + .idx_count = 3, + }; + + write_sm4_instruction(buffer, &instr); +} + static void write_sm4_ret(struct vkd3d_bytecode_buffer *buffer) { struct sm4_instruction instr = @@ -1268,6 +1341,29 @@ static void write_sm4_unary_op(struct vkd3d_bytecode_buffer *buffer, enum vkd3d_ write_sm4_instruction(buffer, &instr); } +static void write_sm4_unary_op_with_two_destinations(struct vkd3d_bytecode_buffer *buffer, + enum vkd3d_sm4_opcode opcode, const struct hlsl_ir_node *dst, unsigned dst_idx, + const struct hlsl_ir_node *src) +{ + struct sm4_instruction instr; + + memset(&instr, 0, sizeof(instr)); + instr.opcode = opcode; + + assert(dst_idx < ARRAY_SIZE(instr.dsts)); + sm4_dst_from_node(&instr.dsts[dst_idx], dst); + assert(1 - dst_idx >= 0); + instr.dsts[1 - dst_idx].reg.type = VKD3D_SM4_RT_NULL; + instr.dsts[1 - dst_idx].reg.dim = VKD3D_SM4_DIMENSION_NONE; + instr.dsts[1 - dst_idx].reg.idx_count = 0; + instr.dst_count = 2; + + sm4_src_from_node(&instr.srcs[0], src, instr.dsts[dst_idx].writemask); + instr.src_count = 1; + + write_sm4_instruction(buffer, &instr); +} + static void write_sm4_binary_op(struct vkd3d_bytecode_buffer *buffer, enum vkd3d_sm4_opcode opcode, const struct hlsl_ir_node *dst, const struct hlsl_ir_node *src1, const struct hlsl_ir_node *src2) { @@ -1286,6 +1382,25 @@ static void write_sm4_binary_op(struct vkd3d_bytecode_buffer *buffer, enum vkd3d write_sm4_instruction(buffer, &instr); } +/* dp# instructions don't map the swizzle. */ +static void write_sm4_binary_op_dot(struct vkd3d_bytecode_buffer *buffer, enum vkd3d_sm4_opcode opcode, + const struct hlsl_ir_node *dst, const struct hlsl_ir_node *src1, const struct hlsl_ir_node *src2) +{ + struct sm4_instruction instr; + + memset(&instr, 0, sizeof(instr)); + instr.opcode = opcode; + + sm4_dst_from_node(&instr.dsts[0], dst); + instr.dst_count = 1; + + sm4_src_from_node(&instr.srcs[0], src1, VKD3DSP_WRITEMASK_ALL); + sm4_src_from_node(&instr.srcs[1], src2, VKD3DSP_WRITEMASK_ALL); + instr.src_count = 2; + + write_sm4_instruction(buffer, &instr); +} + static void write_sm4_binary_op_with_two_destinations(struct vkd3d_bytecode_buffer *buffer, enum vkd3d_sm4_opcode opcode, const struct hlsl_ir_node *dst, unsigned dst_idx, const struct hlsl_ir_node *src1, const struct hlsl_ir_node *src2) @@ -1348,26 +1463,41 @@ static void write_sm4_constant(struct hlsl_ctx *ctx, static void write_sm4_ld(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_type *resource_type, const struct hlsl_ir_node *dst, - const struct hlsl_deref *resource, const struct hlsl_ir_node *coords) + const struct hlsl_deref *resource, const struct hlsl_ir_node *coords, + const struct hlsl_ir_node *texel_offset) { + bool uav = (resource_type->base_type == HLSL_TYPE_UAV); struct sm4_instruction instr; unsigned int dim_count; memset(&instr, 0, sizeof(instr)); - instr.opcode = VKD3D_SM4_OP_LD; + instr.opcode = uav ? VKD3D_SM5_OP_LD_UAV_TYPED : VKD3D_SM4_OP_LD; + + if (texel_offset) + { + if (!encode_texel_offset_as_aoffimmi(&instr, texel_offset)) + { + hlsl_error(ctx, &texel_offset->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TEXEL_OFFSET, + "Offset must resolve to integer literal in the range -8 to 7."); + return; + } + } sm4_dst_from_node(&instr.dsts[0], dst); instr.dst_count = 1; sm4_src_from_node(&instr.srcs[0], coords, VKD3DSP_WRITEMASK_ALL); - /* Mipmap level is in the last component in the IR, but needs to be in the W - * component in the instruction. */ - dim_count = hlsl_sampler_dim_count(resource_type->sampler_dim); - if (dim_count == 1) - instr.srcs[0].swizzle = hlsl_combine_swizzles(instr.srcs[0].swizzle, HLSL_SWIZZLE(X, X, X, Y), 4); - if (dim_count == 2) - instr.srcs[0].swizzle = hlsl_combine_swizzles(instr.srcs[0].swizzle, HLSL_SWIZZLE(X, Y, X, Z), 4); + if (!uav) + { + /* Mipmap level is in the last component in the IR, but needs to be in the W + * component in the instruction. */ + dim_count = hlsl_sampler_dim_count(resource_type->sampler_dim); + if (dim_count == 1) + instr.srcs[0].swizzle = hlsl_combine_swizzles(instr.srcs[0].swizzle, HLSL_SWIZZLE(X, X, X, Y), 4); + if (dim_count == 2) + instr.srcs[0].swizzle = hlsl_combine_swizzles(instr.srcs[0].swizzle, HLSL_SWIZZLE(X, Y, X, Z), 4); + } sm4_src_from_deref(ctx, &instr.srcs[1], resource, resource_type, instr.dsts[0].writemask); @@ -1391,7 +1521,7 @@ static void write_sm4_sample(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer if (!encode_texel_offset_as_aoffimmi(&instr, texel_offset)) { hlsl_error(ctx, &texel_offset->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TEXEL_OFFSET, - "Offset must resolve to integer literal in the range -8 to 7.\n"); + "Offset must resolve to integer literal in the range -8 to 7."); return; } } @@ -1407,350 +1537,564 @@ static void write_sm4_sample(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer write_sm4_instruction(buffer, &instr); } -static void write_sm4_expr(struct hlsl_ctx *ctx, +static bool type_is_float(const struct hlsl_type *type) +{ + return type->base_type == HLSL_TYPE_FLOAT || type->base_type == HLSL_TYPE_HALF; +} + +static void write_sm4_cast_from_bool(struct hlsl_ctx *ctx, + struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_expr *expr, + const struct hlsl_ir_node *arg, uint32_t mask) +{ + struct sm4_instruction instr; + + memset(&instr, 0, sizeof(instr)); + instr.opcode = VKD3D_SM4_OP_AND; + + sm4_dst_from_node(&instr.dsts[0], &expr->node); + instr.dst_count = 1; + + sm4_src_from_node(&instr.srcs[0], arg, instr.dsts[0].writemask); + instr.srcs[1].swizzle_type = VKD3D_SM4_SWIZZLE_NONE; + instr.srcs[1].reg.type = VKD3D_SM4_RT_IMMCONST; + instr.srcs[1].reg.dim = VKD3D_SM4_DIMENSION_SCALAR; + instr.srcs[1].reg.immconst_uint[0] = mask; + instr.src_count = 2; + + write_sm4_instruction(buffer, &instr); +} + +static void write_sm4_cast(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_expr *expr) { + static const union + { + uint32_t u; + float f; + } one = { .f = 1.0 }; const struct hlsl_ir_node *arg1 = expr->operands[0].node; - const struct hlsl_ir_node *arg2 = expr->operands[1].node; + const struct hlsl_type *dst_type = expr->node.data_type; + const struct hlsl_type *src_type = arg1->data_type; - assert(expr->node.reg.allocated); + /* Narrowing casts were already lowered. */ + assert(src_type->dimx == dst_type->dimx); - switch (expr->node.data_type->base_type) + switch (dst_type->base_type) { case HLSL_TYPE_FLOAT: - { - switch (expr->op) + switch (src_type->base_type) { - case HLSL_OP1_ABS: - write_sm4_unary_op(buffer, VKD3D_SM4_OP_MOV, &expr->node, arg1, VKD3D_SM4_REGISTER_MODIFIER_ABS); + case HLSL_TYPE_HALF: + case HLSL_TYPE_FLOAT: + write_sm4_unary_op(buffer, VKD3D_SM4_OP_MOV, &expr->node, arg1, 0); break; - case HLSL_OP1_CAST: - { - const struct hlsl_type *src_type = arg1->data_type; - - /* Narrowing casts were already lowered. */ - assert(src_type->dimx == expr->node.data_type->dimx); + case HLSL_TYPE_INT: + write_sm4_unary_op(buffer, VKD3D_SM4_OP_ITOF, &expr->node, arg1, 0); + break; - switch (src_type->base_type) - { - case HLSL_TYPE_HALF: - case HLSL_TYPE_FLOAT: - write_sm4_unary_op(buffer, VKD3D_SM4_OP_MOV, &expr->node, arg1, 0); - break; + case HLSL_TYPE_UINT: + write_sm4_unary_op(buffer, VKD3D_SM4_OP_UTOF, &expr->node, arg1, 0); + break; - case HLSL_TYPE_INT: - write_sm4_unary_op(buffer, VKD3D_SM4_OP_ITOF, &expr->node, arg1, 0); - break; + case HLSL_TYPE_BOOL: + write_sm4_cast_from_bool(ctx, buffer, expr, arg1, one.u); + break; - case HLSL_TYPE_UINT: - write_sm4_unary_op(buffer, VKD3D_SM4_OP_UTOF, &expr->node, arg1, 0); - break; + case HLSL_TYPE_DOUBLE: + hlsl_fixme(ctx, &expr->node.loc, "SM4 cast from double to float."); + break; - case HLSL_TYPE_BOOL: - hlsl_fixme(ctx, &expr->node.loc, "Casts from bool to float are not implemented.\n"); - break; + default: + vkd3d_unreachable(); + } + break; - case HLSL_TYPE_DOUBLE: - hlsl_fixme(ctx, &expr->node.loc, "Casts from double to float are not implemented.\n"); - break; + case HLSL_TYPE_INT: + switch (src_type->base_type) + { + case HLSL_TYPE_HALF: + case HLSL_TYPE_FLOAT: + write_sm4_unary_op(buffer, VKD3D_SM4_OP_FTOI, &expr->node, arg1, 0); + break; - default: - break; - } + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + write_sm4_unary_op(buffer, VKD3D_SM4_OP_MOV, &expr->node, arg1, 0); break; - } - case HLSL_OP1_EXP2: - write_sm4_unary_op(buffer, VKD3D_SM4_OP_EXP, &expr->node, arg1, 0); + case HLSL_TYPE_BOOL: + write_sm4_cast_from_bool(ctx, buffer, expr, arg1, 1); break; - case HLSL_OP1_FLOOR: - write_sm4_unary_op(buffer, VKD3D_SM4_OP_ROUND_NI, &expr->node, arg1, 0); + case HLSL_TYPE_DOUBLE: + hlsl_fixme(ctx, &expr->node.loc, "SM4 cast from double to int."); break; - case HLSL_OP1_LOG2: - write_sm4_unary_op(buffer, VKD3D_SM4_OP_LOG, &expr->node, arg1, 0); + default: + vkd3d_unreachable(); + } + break; + + case HLSL_TYPE_UINT: + switch (src_type->base_type) + { + case HLSL_TYPE_HALF: + case HLSL_TYPE_FLOAT: + write_sm4_unary_op(buffer, VKD3D_SM4_OP_FTOU, &expr->node, arg1, 0); break; - case HLSL_OP1_NEG: - write_sm4_unary_op(buffer, VKD3D_SM4_OP_MOV, &expr->node, arg1, VKD3D_SM4_REGISTER_MODIFIER_NEGATE); + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + write_sm4_unary_op(buffer, VKD3D_SM4_OP_MOV, &expr->node, arg1, 0); break; - case HLSL_OP1_ROUND: - write_sm4_unary_op(buffer, VKD3D_SM4_OP_ROUND_NE, &expr->node, arg1, 0); + case HLSL_TYPE_BOOL: + write_sm4_cast_from_bool(ctx, buffer, expr, arg1, 1); break; - case HLSL_OP1_SAT: - write_sm4_unary_op(buffer, VKD3D_SM4_OP_MOV - | (VKD3D_SM4_INSTRUCTION_FLAG_SATURATE << VKD3D_SM4_INSTRUCTION_FLAGS_SHIFT), - &expr->node, arg1, 0); + case HLSL_TYPE_DOUBLE: + hlsl_fixme(ctx, &expr->node.loc, "SM4 cast from double to uint."); break; - case HLSL_OP2_ADD: - write_sm4_binary_op(buffer, VKD3D_SM4_OP_ADD, &expr->node, arg1, arg2); + default: + vkd3d_unreachable(); + } + break; + + case HLSL_TYPE_HALF: + hlsl_fixme(ctx, &expr->node.loc, "SM4 cast to half."); + break; + + case HLSL_TYPE_DOUBLE: + hlsl_fixme(ctx, &expr->node.loc, "SM4 cast to double."); + break; + + case HLSL_TYPE_BOOL: + /* Casts to bool should have already been lowered. */ + default: + vkd3d_unreachable(); + } +} + +static void write_sm4_store_uav_typed(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, + const struct hlsl_deref *dst, const struct hlsl_ir_node *coords, const struct hlsl_ir_node *value) +{ + struct sm4_instruction instr; + + memset(&instr, 0, sizeof(instr)); + instr.opcode = VKD3D_SM5_OP_STORE_UAV_TYPED; + + sm4_register_from_deref(ctx, &instr.dsts[0].reg, &instr.dsts[0].writemask, NULL, dst, dst->var->data_type); + instr.dst_count = 1; + + sm4_src_from_node(&instr.srcs[0], coords, VKD3DSP_WRITEMASK_ALL); + sm4_src_from_node(&instr.srcs[1], value, VKD3DSP_WRITEMASK_ALL); + instr.src_count = 2; + + write_sm4_instruction(buffer, &instr); +} + +static void write_sm4_expr(struct hlsl_ctx *ctx, + struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_expr *expr) +{ + const struct hlsl_ir_node *arg1 = expr->operands[0].node; + const struct hlsl_ir_node *arg2 = expr->operands[1].node; + const struct hlsl_type *dst_type = expr->node.data_type; + struct vkd3d_string_buffer *dst_type_string; + + assert(expr->node.reg.allocated); + + if (!(dst_type_string = hlsl_type_to_string(ctx, dst_type))) + return; + + switch (expr->op) + { + case HLSL_OP1_ABS: + switch (dst_type->base_type) + { + case HLSL_TYPE_FLOAT: + write_sm4_unary_op(buffer, VKD3D_SM4_OP_MOV, &expr->node, arg1, VKD3D_SM4_REGISTER_MODIFIER_ABS); break; - case HLSL_OP2_DIV: - write_sm4_binary_op(buffer, VKD3D_SM4_OP_DIV, &expr->node, arg1, arg2); + default: + hlsl_fixme(ctx, &expr->node.loc, "SM4 %s absolute value expression.", dst_type_string->buffer); + } + break; + + case HLSL_OP1_BIT_NOT: + assert(type_is_integer(dst_type)); + write_sm4_unary_op(buffer, VKD3D_SM4_OP_NOT, &expr->node, arg1, 0); + break; + + case HLSL_OP1_CAST: + write_sm4_cast(ctx, buffer, expr); + break; + + case HLSL_OP1_COS: + assert(type_is_float(dst_type)); + write_sm4_unary_op_with_two_destinations(buffer, VKD3D_SM4_OP_SINCOS, &expr->node, 1, arg1); + break; + + case HLSL_OP1_EXP2: + assert(type_is_float(dst_type)); + write_sm4_unary_op(buffer, VKD3D_SM4_OP_EXP, &expr->node, arg1, 0); + break; + + case HLSL_OP1_FLOOR: + assert(type_is_float(dst_type)); + write_sm4_unary_op(buffer, VKD3D_SM4_OP_ROUND_NI, &expr->node, arg1, 0); + break; + + case HLSL_OP1_FRACT: + assert(type_is_float(dst_type)); + write_sm4_unary_op(buffer, VKD3D_SM4_OP_FRC, &expr->node, arg1, 0); + break; + + case HLSL_OP1_LOG2: + assert(type_is_float(dst_type)); + write_sm4_unary_op(buffer, VKD3D_SM4_OP_LOG, &expr->node, arg1, 0); + break; + + case HLSL_OP1_LOGIC_NOT: + assert(dst_type->base_type == HLSL_TYPE_BOOL); + write_sm4_unary_op(buffer, VKD3D_SM4_OP_NOT, &expr->node, arg1, 0); + break; + + case HLSL_OP1_NEG: + switch (dst_type->base_type) + { + case HLSL_TYPE_FLOAT: + write_sm4_unary_op(buffer, VKD3D_SM4_OP_MOV, &expr->node, arg1, VKD3D_SM4_REGISTER_MODIFIER_NEGATE); break; - case HLSL_OP2_MAX: - write_sm4_binary_op(buffer, VKD3D_SM4_OP_MAX, &expr->node, arg1, arg2); + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + write_sm4_unary_op(buffer, VKD3D_SM4_OP_INEG, &expr->node, arg1, 0); break; - case HLSL_OP2_MIN: - write_sm4_binary_op(buffer, VKD3D_SM4_OP_MIN, &expr->node, arg1, arg2); + default: + hlsl_fixme(ctx, &expr->node.loc, "SM4 %s negation expression.", dst_type_string->buffer); + } + break; + + case HLSL_OP1_REINTERPRET: + write_sm4_unary_op(buffer, VKD3D_SM4_OP_MOV, &expr->node, arg1, 0); + break; + + case HLSL_OP1_ROUND: + assert(type_is_float(dst_type)); + write_sm4_unary_op(buffer, VKD3D_SM4_OP_ROUND_NE, &expr->node, arg1, 0); + break; + + case HLSL_OP1_RSQ: + assert(type_is_float(dst_type)); + write_sm4_unary_op(buffer, VKD3D_SM4_OP_RSQ, &expr->node, arg1, 0); + break; + + case HLSL_OP1_SAT: + assert(type_is_float(dst_type)); + write_sm4_unary_op(buffer, VKD3D_SM4_OP_MOV + | (VKD3D_SM4_INSTRUCTION_FLAG_SATURATE << VKD3D_SM4_INSTRUCTION_FLAGS_SHIFT), + &expr->node, arg1, 0); + break; + + case HLSL_OP1_SIN: + assert(type_is_float(dst_type)); + write_sm4_unary_op_with_two_destinations(buffer, VKD3D_SM4_OP_SINCOS, &expr->node, 0, arg1); + break; + + case HLSL_OP1_SQRT: + assert(type_is_float(dst_type)); + write_sm4_unary_op(buffer, VKD3D_SM4_OP_SQRT, &expr->node, arg1, 0); + break; + + case HLSL_OP2_ADD: + switch (dst_type->base_type) + { + case HLSL_TYPE_FLOAT: + write_sm4_binary_op(buffer, VKD3D_SM4_OP_ADD, &expr->node, arg1, arg2); break; - case HLSL_OP2_MUL: - write_sm4_binary_op(buffer, VKD3D_SM4_OP_MUL, &expr->node, arg1, arg2); + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + write_sm4_binary_op(buffer, VKD3D_SM4_OP_IADD, &expr->node, arg1, arg2); break; default: - hlsl_fixme(ctx, &expr->node.loc, "SM4 float \"%s\" expression.", debug_hlsl_expr_op(expr->op)); - break; + hlsl_fixme(ctx, &expr->node.loc, "SM4 %s addition expression.", dst_type_string->buffer); } break; - } - case HLSL_TYPE_INT: - { - switch (expr->op) + case HLSL_OP2_BIT_AND: + assert(type_is_integer(dst_type)); + write_sm4_binary_op(buffer, VKD3D_SM4_OP_AND, &expr->node, arg1, arg2); + break; + + case HLSL_OP2_BIT_OR: + assert(type_is_integer(dst_type)); + write_sm4_binary_op(buffer, VKD3D_SM4_OP_OR, &expr->node, arg1, arg2); + break; + + case HLSL_OP2_BIT_XOR: + assert(type_is_integer(dst_type)); + write_sm4_binary_op(buffer, VKD3D_SM4_OP_XOR, &expr->node, arg1, arg2); + break; + + case HLSL_OP2_DIV: + switch (dst_type->base_type) { - case HLSL_OP1_CAST: - { - const struct hlsl_type *src_type = arg1->data_type; + case HLSL_TYPE_FLOAT: + write_sm4_binary_op(buffer, VKD3D_SM4_OP_DIV, &expr->node, arg1, arg2); + break; - /* Narrowing casts were already lowered. */ - assert(src_type->dimx == expr->node.data_type->dimx); + case HLSL_TYPE_UINT: + write_sm4_binary_op_with_two_destinations(buffer, VKD3D_SM4_OP_UDIV, &expr->node, 0, arg1, arg2); + break; - switch (src_type->base_type) - { - case HLSL_TYPE_HALF: - case HLSL_TYPE_FLOAT: - write_sm4_unary_op(buffer, VKD3D_SM4_OP_FTOI, &expr->node, arg1, 0); - break; + default: + hlsl_fixme(ctx, &expr->node.loc, "SM4 %s division expression.", dst_type_string->buffer); + } + break; - case HLSL_TYPE_INT: - case HLSL_TYPE_UINT: - write_sm4_unary_op(buffer, VKD3D_SM4_OP_MOV, &expr->node, arg1, 0); + case HLSL_OP2_DOT: + switch (dst_type->base_type) + { + case HLSL_TYPE_FLOAT: + switch (arg1->data_type->dimx) + { + case 4: + write_sm4_binary_op_dot(buffer, VKD3D_SM4_OP_DP4, &expr->node, arg1, arg2); break; - case HLSL_TYPE_BOOL: - hlsl_fixme(ctx, &expr->node.loc, "SM4 cast from bool to int."); + case 3: + write_sm4_binary_op_dot(buffer, VKD3D_SM4_OP_DP3, &expr->node, arg1, arg2); break; - case HLSL_TYPE_DOUBLE: - hlsl_fixme(ctx, &expr->node.loc, "SM4 cast from double to int."); + case 2: + write_sm4_binary_op_dot(buffer, VKD3D_SM4_OP_DP2, &expr->node, arg1, arg2); break; + case 1: default: - break; + vkd3d_unreachable(); } break; - } - case HLSL_OP1_NEG: - write_sm4_unary_op(buffer, VKD3D_SM4_OP_INEG, &expr->node, arg1, 0); - break; + default: + hlsl_fixme(ctx, &expr->node.loc, "SM4 %s dot expression.", dst_type_string->buffer); + } + break; - case HLSL_OP2_MAX: - write_sm4_binary_op(buffer, VKD3D_SM4_OP_IMAX, &expr->node, arg1, arg2); + case HLSL_OP2_EQUAL: + { + const struct hlsl_type *src_type = arg1->data_type; + + assert(dst_type->base_type == HLSL_TYPE_BOOL); + + switch (src_type->base_type) + { + case HLSL_TYPE_FLOAT: + write_sm4_binary_op(buffer, VKD3D_SM4_OP_EQ, &expr->node, arg1, arg2); break; - case HLSL_OP2_MIN: - write_sm4_binary_op(buffer, VKD3D_SM4_OP_IMIN, &expr->node, arg1, arg2); + case HLSL_TYPE_BOOL: + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + write_sm4_binary_op(buffer, VKD3D_SM4_OP_IEQ, &expr->node, arg1, arg2); break; default: - hlsl_fixme(ctx, &expr->node.loc, "SM4 int \"%s\" expression.", debug_hlsl_expr_op(expr->op)); + hlsl_fixme(ctx, &expr->node.loc, "SM4 equality between \"%s\" operands.", + debug_hlsl_type(ctx, src_type)); break; } break; } - case HLSL_TYPE_UINT: + case HLSL_OP2_GEQUAL: { - switch (expr->op) - { - case HLSL_OP1_CAST: - { - const struct hlsl_type *src_type = arg1->data_type; + const struct hlsl_type *src_type = arg1->data_type; - /* Narrowing casts were already lowered. */ - assert(src_type->dimx == expr->node.data_type->dimx); + assert(dst_type->base_type == HLSL_TYPE_BOOL); - switch (src_type->base_type) - { - case HLSL_TYPE_HALF: - case HLSL_TYPE_FLOAT: - write_sm4_unary_op(buffer, VKD3D_SM4_OP_FTOU, &expr->node, arg1, 0); - break; - - case HLSL_TYPE_INT: - case HLSL_TYPE_UINT: - write_sm4_unary_op(buffer, VKD3D_SM4_OP_MOV, &expr->node, arg1, 0); - break; + switch (src_type->base_type) + { + case HLSL_TYPE_FLOAT: + write_sm4_binary_op(buffer, VKD3D_SM4_OP_GE, &expr->node, arg1, arg2); + break; - case HLSL_TYPE_BOOL: - hlsl_fixme(ctx, &expr->node.loc, "SM4 cast from bool to uint.\n"); - break; + case HLSL_TYPE_INT: + write_sm4_binary_op(buffer, VKD3D_SM4_OP_IGE, &expr->node, arg1, arg2); + break; - case HLSL_TYPE_DOUBLE: - hlsl_fixme(ctx, &expr->node.loc, "SM4 cast from double to uint.\n"); - break; + case HLSL_TYPE_BOOL: + case HLSL_TYPE_UINT: + write_sm4_binary_op(buffer, VKD3D_SM4_OP_UGE, &expr->node, arg1, arg2); + break; - default: - break; - } + default: + hlsl_fixme(ctx, &expr->node.loc, "SM4 greater-than-or-equal between \"%s\" operands.", + debug_hlsl_type(ctx, src_type)); break; - } + } + break; + } - case HLSL_OP2_MAX: - write_sm4_binary_op(buffer, VKD3D_SM4_OP_UMAX, &expr->node, arg1, arg2); + case HLSL_OP2_LESS: + { + const struct hlsl_type *src_type = arg1->data_type; + + assert(dst_type->base_type == HLSL_TYPE_BOOL); + + switch (src_type->base_type) + { + case HLSL_TYPE_FLOAT: + write_sm4_binary_op(buffer, VKD3D_SM4_OP_LT, &expr->node, arg1, arg2); break; - case HLSL_OP2_MIN: - write_sm4_binary_op(buffer, VKD3D_SM4_OP_UMIN, &expr->node, arg1, arg2); + case HLSL_TYPE_INT: + write_sm4_binary_op(buffer, VKD3D_SM4_OP_ILT, &expr->node, arg1, arg2); break; - case HLSL_OP2_MUL: - /* Using IMUL instead of UMUL because we're taking the low - * bits, and the native compiler generates IMUL. */ - write_sm4_binary_op_with_two_destinations(buffer, VKD3D_SM4_OP_IMUL, &expr->node, 1, arg1, arg2); + case HLSL_TYPE_BOOL: + case HLSL_TYPE_UINT: + write_sm4_binary_op(buffer, VKD3D_SM4_OP_ULT, &expr->node, arg1, arg2); break; default: - hlsl_fixme(ctx, &expr->node.loc, "SM4 uint \"%s\" expression.\n", debug_hlsl_expr_op(expr->op)); + hlsl_fixme(ctx, &expr->node.loc, "SM4 less-than between \"%s\" operands.", + debug_hlsl_type(ctx, src_type)); break; } break; } - case HLSL_TYPE_BOOL: - { - switch (expr->op) - { - case HLSL_OP2_EQUAL: - { - const struct hlsl_type *src_type = arg1->data_type; + case HLSL_OP2_LOGIC_AND: + assert(dst_type->base_type == HLSL_TYPE_BOOL); + write_sm4_binary_op(buffer, VKD3D_SM4_OP_AND, &expr->node, arg1, arg2); + break; - switch (src_type->base_type) - { - case HLSL_TYPE_FLOAT: - write_sm4_binary_op(buffer, VKD3D_SM4_OP_EQ, &expr->node, arg1, arg2); - break; + case HLSL_OP2_LOGIC_OR: + assert(dst_type->base_type == HLSL_TYPE_BOOL); + write_sm4_binary_op(buffer, VKD3D_SM4_OP_OR, &expr->node, arg1, arg2); + break; - case HLSL_TYPE_BOOL: - case HLSL_TYPE_INT: - case HLSL_TYPE_UINT: - write_sm4_binary_op(buffer, VKD3D_SM4_OP_IEQ, &expr->node, arg1, arg2); - break; + case HLSL_OP2_LSHIFT: + assert(type_is_integer(dst_type)); + assert(dst_type->base_type != HLSL_TYPE_BOOL); + write_sm4_binary_op(buffer, VKD3D_SM4_OP_ISHL, &expr->node, arg1, arg2); + break; - default: - hlsl_fixme(ctx, &expr->node.loc, "SM4 equality between \"%s\" operands.", - debug_hlsl_type(ctx, src_type)); - break; - } + case HLSL_OP2_MAX: + switch (dst_type->base_type) + { + case HLSL_TYPE_FLOAT: + write_sm4_binary_op(buffer, VKD3D_SM4_OP_MAX, &expr->node, arg1, arg2); break; - } - case HLSL_OP2_NEQUAL: - { - const struct hlsl_type *src_type = arg1->data_type; + case HLSL_TYPE_INT: + write_sm4_binary_op(buffer, VKD3D_SM4_OP_IMAX, &expr->node, arg1, arg2); + break; - switch (src_type->base_type) - { - case HLSL_TYPE_FLOAT: - write_sm4_binary_op(buffer, VKD3D_SM4_OP_NE, &expr->node, arg1, arg2); - break; + case HLSL_TYPE_UINT: + write_sm4_binary_op(buffer, VKD3D_SM4_OP_UMAX, &expr->node, arg1, arg2); + break; - case HLSL_TYPE_BOOL: - case HLSL_TYPE_INT: - case HLSL_TYPE_UINT: - write_sm4_binary_op(buffer, VKD3D_SM4_OP_INE, &expr->node, arg1, arg2); - break; + default: + hlsl_fixme(ctx, &expr->node.loc, "SM4 %s maximum expression.", dst_type_string->buffer); + } + break; - default: - hlsl_fixme(ctx, &expr->node.loc, "SM4 inequality between \"%s\" operands.", - debug_hlsl_type(ctx, src_type)); - break; - } + case HLSL_OP2_MIN: + switch (dst_type->base_type) + { + case HLSL_TYPE_FLOAT: + write_sm4_binary_op(buffer, VKD3D_SM4_OP_MIN, &expr->node, arg1, arg2); break; - } - case HLSL_OP2_LESS: - { - const struct hlsl_type *src_type = arg1->data_type; + case HLSL_TYPE_INT: + write_sm4_binary_op(buffer, VKD3D_SM4_OP_IMIN, &expr->node, arg1, arg2); + break; - switch (src_type->base_type) - { - case HLSL_TYPE_FLOAT: - write_sm4_binary_op(buffer, VKD3D_SM4_OP_LT, &expr->node, arg1, arg2); - break; + case HLSL_TYPE_UINT: + write_sm4_binary_op(buffer, VKD3D_SM4_OP_UMIN, &expr->node, arg1, arg2); + break; - case HLSL_TYPE_INT: - write_sm4_binary_op(buffer, VKD3D_SM4_OP_ILT, &expr->node, arg1, arg2); - break; + default: + hlsl_fixme(ctx, &expr->node.loc, "SM4 %s minimum expression.", dst_type_string->buffer); + } + break; - case HLSL_TYPE_BOOL: - case HLSL_TYPE_UINT: - write_sm4_binary_op(buffer, VKD3D_SM4_OP_ULT, &expr->node, arg1, arg2); - break; + case HLSL_OP2_MOD: + switch (dst_type->base_type) + { + case HLSL_TYPE_UINT: + write_sm4_binary_op_with_two_destinations(buffer, VKD3D_SM4_OP_UDIV, &expr->node, 1, arg1, arg2); + break; - default: - hlsl_fixme(ctx, &expr->node.loc, "SM4 less-than between \"%s\" operands.", - debug_hlsl_type(ctx, src_type)); - break; - } + default: + hlsl_fixme(ctx, &expr->node.loc, "SM4 %s modulus expression.", dst_type_string->buffer); + } + break; + + case HLSL_OP2_MUL: + switch (dst_type->base_type) + { + case HLSL_TYPE_FLOAT: + write_sm4_binary_op(buffer, VKD3D_SM4_OP_MUL, &expr->node, arg1, arg2); break; - } - case HLSL_OP2_GEQUAL: - { - const struct hlsl_type *src_type = arg1->data_type; + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + /* Using IMUL instead of UMUL because we're taking the low + * bits, and the native compiler generates IMUL. */ + write_sm4_binary_op_with_two_destinations(buffer, VKD3D_SM4_OP_IMUL, &expr->node, 1, arg1, arg2); + break; - switch (src_type->base_type) - { - case HLSL_TYPE_FLOAT: - write_sm4_binary_op(buffer, VKD3D_SM4_OP_GE, &expr->node, arg1, arg2); - break; + default: + hlsl_fixme(ctx, &expr->node.loc, "SM4 %s multiplication expression.", dst_type_string->buffer); + } + break; - case HLSL_TYPE_INT: - write_sm4_binary_op(buffer, VKD3D_SM4_OP_IGE, &expr->node, arg1, arg2); - break; + case HLSL_OP2_NEQUAL: + { + const struct hlsl_type *src_type = arg1->data_type; - case HLSL_TYPE_BOOL: - case HLSL_TYPE_UINT: - write_sm4_binary_op(buffer, VKD3D_SM4_OP_UGE, &expr->node, arg1, arg2); - break; + assert(dst_type->base_type == HLSL_TYPE_BOOL); - default: - hlsl_fixme(ctx, &expr->node.loc, "SM4 greater-than-or-equal between \"%s\" operands.", - debug_hlsl_type(ctx, src_type)); - break; - } + switch (src_type->base_type) + { + case HLSL_TYPE_FLOAT: + write_sm4_binary_op(buffer, VKD3D_SM4_OP_NE, &expr->node, arg1, arg2); + break; + + case HLSL_TYPE_BOOL: + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + write_sm4_binary_op(buffer, VKD3D_SM4_OP_INE, &expr->node, arg1, arg2); break; - } default: - hlsl_fixme(ctx, &expr->node.loc, "SM4 bool \"%s\" expression.", debug_hlsl_expr_op(expr->op)); + hlsl_fixme(ctx, &expr->node.loc, "SM4 inequality between \"%s\" operands.", + debug_hlsl_type(ctx, src_type)); break; } break; } - default: - { - struct vkd3d_string_buffer *string; - - if ((string = hlsl_type_to_string(ctx, expr->node.data_type))) - hlsl_fixme(ctx, &expr->node.loc, "SM4 %s expression.", string->buffer); - hlsl_release_string_buffer(ctx, string); + case HLSL_OP2_RSHIFT: + assert(type_is_integer(dst_type)); + assert(dst_type->base_type != HLSL_TYPE_BOOL); + write_sm4_binary_op(buffer, dst_type->base_type == HLSL_TYPE_INT ? VKD3D_SM4_OP_ISHR : VKD3D_SM4_OP_USHR, + &expr->node, arg1, arg2); break; - } + + default: + hlsl_fixme(ctx, &expr->node.loc, "SM4 %s expression.", debug_hlsl_expr_op(expr->op)); } + + hlsl_release_string_buffer(ctx, dst_type_string); } static void write_sm4_if(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_if *iff) @@ -1778,6 +2122,29 @@ static void write_sm4_if(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf } instr.opcode = VKD3D_SM4_OP_ENDIF; + instr.src_count = 0; + write_sm4_instruction(buffer, &instr); +} + +static void write_sm4_jump(struct hlsl_ctx *ctx, + struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_jump *jump) +{ + struct sm4_instruction instr = {0}; + + switch (jump->type) + { + case HLSL_IR_JUMP_BREAK: + instr.opcode = VKD3D_SM4_OP_BREAK; + break; + + case HLSL_IR_JUMP_RETURN: + vkd3d_unreachable(); + + default: + hlsl_fixme(ctx, &jump->node.loc, "Jump type %s.\n", hlsl_jump_type_to_string(jump->type)); + return; + } + write_sm4_instruction(buffer, &instr); } @@ -1831,11 +2198,19 @@ static void write_sm4_gather(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer sm4_src_from_node(&instr.srcs[instr.src_count++], coords, VKD3DSP_WRITEMASK_ALL); - /* FIXME: Use an aoffimmi modifier if possible. */ if (texel_offset) { - instr.opcode = VKD3D_SM5_OP_GATHER4_PO; - sm4_src_from_node(&instr.srcs[instr.src_count++], texel_offset, VKD3DSP_WRITEMASK_ALL); + if (!encode_texel_offset_as_aoffimmi(&instr, texel_offset)) + { + if (ctx->profile->major_version < 5) + { + hlsl_error(ctx, &texel_offset->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TEXEL_OFFSET, + "Offset must resolve to integer literal in the range -8 to 7 for profiles < 5."); + return; + } + instr.opcode = VKD3D_SM5_OP_GATHER4_PO; + sm4_src_from_node(&instr.srcs[instr.src_count++], texel_offset, VKD3DSP_WRITEMASK_ALL); + } } sm4_src_from_deref(ctx, &instr.srcs[instr.src_count++], resource, resource_type, instr.dsts[0].writemask); @@ -1856,11 +2231,23 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx, const struct hlsl_ir_node *texel_offset = load->texel_offset.node; const struct hlsl_ir_node *coords = load->coords.node; + if (resource_type->type != HLSL_CLASS_OBJECT) + { + assert(resource_type->type == HLSL_CLASS_ARRAY || resource_type->type == HLSL_CLASS_STRUCT); + hlsl_fixme(ctx, &load->node.loc, "Resource being a component of another variable."); + return; + } + if (load->sampler.var) { const struct hlsl_type *sampler_type = load->sampler.var->data_type; - assert(sampler_type->type == HLSL_CLASS_OBJECT); + if (sampler_type->type != HLSL_CLASS_OBJECT) + { + assert(sampler_type->type == HLSL_CLASS_ARRAY || sampler_type->type == HLSL_CLASS_STRUCT); + hlsl_fixme(ctx, &load->node.loc, "Sampler being a component of another variable."); + return; + } assert(sampler_type->base_type == HLSL_TYPE_SAMPLER); assert(sampler_type->sampler_dim == HLSL_SAMPLER_DIM_GENERIC); @@ -1880,12 +2267,16 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx, switch (load->load_type) { case HLSL_RESOURCE_LOAD: - write_sm4_ld(ctx, buffer, resource_type, &load->node, &load->resource, coords); + write_sm4_ld(ctx, buffer, resource_type, &load->node, &load->resource, + coords, texel_offset); break; case HLSL_RESOURCE_SAMPLE: if (!load->sampler.var) + { hlsl_fixme(ctx, &load->node.loc, "SM4 combined sample expression."); + return; + } write_sm4_sample(ctx, buffer, resource_type, &load->node, &load->resource, &load->sampler, coords, texel_offset); break; @@ -1909,9 +2300,34 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx, write_sm4_gather(ctx, buffer, resource_type, &load->node, &load->resource, &load->sampler, coords, HLSL_SWIZZLE(W, W, W, W), texel_offset); break; + + case HLSL_RESOURCE_SAMPLE_LOD: + hlsl_fixme(ctx, &load->node.loc, "SM4 sample-LOD expression."); + break; } } +static void write_sm4_resource_store(struct hlsl_ctx *ctx, + struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_resource_store *store) +{ + const struct hlsl_type *resource_type = store->resource.var->data_type; + + if (resource_type->type != HLSL_CLASS_OBJECT) + { + assert(resource_type->type == HLSL_CLASS_ARRAY || resource_type->type == HLSL_CLASS_STRUCT); + hlsl_fixme(ctx, &store->node.loc, "Resource being a component of another variable."); + return; + } + + if (!store->resource.var->is_uniform) + { + hlsl_fixme(ctx, &store->node.loc, "Store to non-uniform resource variable."); + return; + } + + write_sm4_store_uav_typed(ctx, buffer, &store->resource, store->coords.node, store->value.node); +} + static void write_sm4_store(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_store *store) { @@ -1919,12 +2335,6 @@ static void write_sm4_store(struct hlsl_ctx *ctx, struct sm4_instruction instr; unsigned int writemask; - if (store->lhs.var->data_type->type == HLSL_CLASS_MATRIX) - { - hlsl_fixme(ctx, &store->node.loc, "Store to a matrix variable.\n"); - return; - } - memset(&instr, 0, sizeof(instr)); instr.opcode = VKD3D_SM4_OP_MOV; @@ -1969,12 +2379,12 @@ static void write_sm4_block(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer * { if (instr->data_type->type == HLSL_CLASS_MATRIX) { - FIXME("Matrix operations need to be lowered.\n"); + hlsl_fixme(ctx, &instr->loc, "Matrix operations need to be lowered."); break; } else if (instr->data_type->type == HLSL_CLASS_OBJECT) { - hlsl_fixme(ctx, &instr->loc, "Object copy.\n"); + hlsl_fixme(ctx, &instr->loc, "Object copy."); break; } @@ -1983,6 +2393,9 @@ static void write_sm4_block(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer * switch (instr->type) { + case HLSL_IR_CALL: + vkd3d_unreachable(); + case HLSL_IR_CONSTANT: write_sm4_constant(ctx, buffer, hlsl_ir_constant(instr)); break; @@ -1995,6 +2408,10 @@ static void write_sm4_block(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer * write_sm4_if(ctx, buffer, hlsl_ir_if(instr)); break; + case HLSL_IR_JUMP: + write_sm4_jump(ctx, buffer, hlsl_ir_jump(instr)); + break; + case HLSL_IR_LOAD: write_sm4_load(ctx, buffer, hlsl_ir_load(instr)); break; @@ -2003,6 +2420,10 @@ static void write_sm4_block(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer * write_sm4_resource_load(ctx, buffer, hlsl_ir_resource_load(instr)); break; + case HLSL_IR_RESOURCE_STORE: + write_sm4_resource_store(ctx, buffer, hlsl_ir_resource_store(instr)); + break; + case HLSL_IR_LOOP: write_sm4_loop(ctx, buffer, hlsl_ir_loop(instr)); break; @@ -2016,7 +2437,7 @@ static void write_sm4_block(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer * break; default: - FIXME("Unhandled instruction type %s.\n", hlsl_node_type_to_string(instr->type)); + hlsl_fixme(ctx, &instr->loc, "Instruction type %s.", hlsl_node_type_to_string(instr->type)); } } } @@ -2025,7 +2446,9 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *entry_func, struct dxbc_writer *dxbc) { const struct hlsl_profile_info *profile = ctx->profile; + const struct hlsl_ir_var **extern_resources; struct vkd3d_bytecode_buffer buffer = {0}; + unsigned int extern_resources_count, i; const struct hlsl_buffer *cbuffer; const struct hlsl_ir_var *var; size_t token_count_position; @@ -2043,6 +2466,8 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx, VKD3D_SM4_LIB, }; + extern_resources = sm4_get_extern_resources(ctx, &extern_resources_count); + put_u32(&buffer, vkd3d_make_u32((profile->major_version << 4) | profile->minor_version, shader_types[profile->type])); token_count_position = put_u32(&buffer, 0); @@ -2052,14 +2477,13 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx, write_sm4_dcl_constant_buffer(&buffer, cbuffer); } - LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, const struct hlsl_ir_var, extern_entry) + for (i = 0; i < extern_resources_count; ++i) { - if (!var->reg.allocated || var->data_type->type != HLSL_CLASS_OBJECT) - continue; + var = extern_resources[i]; if (var->data_type->base_type == HLSL_TYPE_SAMPLER) write_sm4_dcl_sampler(&buffer, var); - else if (var->data_type->base_type == HLSL_TYPE_TEXTURE) + else if (var->data_type->base_type == HLSL_TYPE_TEXTURE || var->data_type->base_type == HLSL_TYPE_UAV) write_sm4_dcl_texture(&buffer, var); } @@ -2069,6 +2493,9 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx, write_sm4_dcl_semantic(ctx, &buffer, var); } + if (profile->type == VKD3D_SHADER_TYPE_COMPUTE) + write_sm4_dcl_thread_group(&buffer, ctx->thread_count); + if (ctx->temp_count) write_sm4_dcl_temps(&buffer, ctx->temp_count); @@ -2079,6 +2506,8 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx, set_u32(&buffer, token_count_position, bytecode_get_size(&buffer) / sizeof(uint32_t)); dxbc_writer_add_section(dxbc, TAG_SHDR, buffer.data, buffer.size); + + vkd3d_free(extern_resources); } int hlsl_sm4_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out) @@ -2097,6 +2526,6 @@ int hlsl_sm4_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun if (!(ret = ctx->result)) ret = dxbc_writer_write(&dxbc, out); for (i = 0; i < dxbc.section_count; ++i) - vkd3d_free((void *)dxbc.sections[i].data); + vkd3d_shader_free_shader_code(&dxbc.sections[i].data); return ret; } diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/preproc.h b/dll/directx/wine/vkd3d/libs/vkd3d-shader/preproc.h similarity index 98% rename from dll/directx/wine/d3d12/vkd3d/vkd3d-shader/preproc.h rename to dll/directx/wine/vkd3d/libs/vkd3d-shader/preproc.h index 78a4a7e41395c..4860cf5f90e5e 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/preproc.h +++ b/dll/directx/wine/vkd3d/libs/vkd3d-shader/preproc.h @@ -67,7 +67,7 @@ struct preproc_expansion struct preproc_macro { - struct wine_rb_entry entry; + struct rb_entry entry; char *name; char **arg_names; @@ -91,7 +91,7 @@ struct preproc_ctx struct preproc_expansion *expansion_stack; size_t expansion_count, expansion_stack_size; - struct wine_rb_tree macros; + struct rb_tree macros; /* It's possible to parse as many as two function-like macros at once: one * in the main text, and another inside of #if directives. E.g. diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/preproc.l b/dll/directx/wine/vkd3d/libs/vkd3d-shader/preproc.l similarity index 98% rename from dll/directx/wine/d3d12/vkd3d/vkd3d-shader/preproc.l rename to dll/directx/wine/vkd3d/libs/vkd3d-shader/preproc.l index bed80f045a040..bb5a6b61de132 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/preproc.l +++ b/dll/directx/wine/vkd3d/libs/vkd3d-shader/preproc.l @@ -20,6 +20,7 @@ %{ +#include "preproc.h" #include "preproc.tab.h" #undef ERROR /* defined in wingdi.h */ @@ -578,7 +579,10 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner) if (ctx->current_directive) return return_token(token, lval, text); - vkd3d_string_buffer_printf(&ctx->buffer, "%s ", text); + if (isspace(text[0])) + vkd3d_string_buffer_printf(&ctx->buffer, "%s", text); + else + vkd3d_string_buffer_printf(&ctx->buffer, "%s ", text); break; } @@ -706,7 +710,7 @@ bool preproc_push_include(struct preproc_ctx *ctx, char *filename, const struct return true; } -static int preproc_macro_compare(const void *key, const struct wine_rb_entry *entry) +static int preproc_macro_compare(const void *key, const struct rb_entry *entry) { const struct preproc_macro *macro = RB_ENTRY_VALUE(entry, struct preproc_macro, entry); const char *name = key; @@ -714,7 +718,7 @@ static int preproc_macro_compare(const void *key, const struct wine_rb_entry *en return strcmp(name, macro->name); } -static void preproc_macro_wine_rb_free(struct wine_rb_entry *entry, void *ctx) +static void preproc_macro_rb_free(struct rb_entry *entry, void *ctx) { preproc_free_macro(RB_ENTRY_VALUE(entry, struct preproc_macro, entry)); } @@ -729,7 +733,7 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info, unsigned int i; vkd3d_string_buffer_init(&ctx.buffer); - wine_rb_init(&ctx.macros, preproc_macro_compare); + rb_init(&ctx.macros, preproc_macro_compare); if (!(ctx.preprocess_info = vkd3d_find_struct(compile_info->next, PREPROCESS_INFO))) ctx.preprocess_info = &default_preprocess_info; ctx.message_context = message_context; @@ -791,7 +795,7 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info, preproc_pop_buffer(&ctx); yylex_destroy(ctx.scanner); - wine_rb_destroy(&ctx.macros, preproc_macro_wine_rb_free, NULL); + rb_destroy(&ctx.macros, preproc_macro_rb_free, NULL); vkd3d_free(ctx.file_stack); vkd3d_free(ctx.expansion_stack); @@ -815,7 +819,7 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info, return VKD3D_OK; fail: - wine_rb_destroy(&ctx.macros, preproc_macro_wine_rb_free, NULL); + rb_destroy(&ctx.macros, preproc_macro_rb_free, NULL); vkd3d_free(source_name); vkd3d_string_buffer_cleanup(&ctx.buffer); return VKD3D_ERROR_OUT_OF_MEMORY; diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/preproc.y b/dll/directx/wine/vkd3d/libs/vkd3d-shader/preproc.y similarity index 95% rename from dll/directx/wine/d3d12/vkd3d/vkd3d-shader/preproc.y rename to dll/directx/wine/vkd3d/libs/vkd3d-shader/preproc.y index fd69e9193afa0..009c35ffb970f 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/preproc.y +++ b/dll/directx/wine/vkd3d/libs/vkd3d-shader/preproc.y @@ -80,9 +80,9 @@ static void yyerror(const YYLTYPE *loc, void *scanner, struct preproc_ctx *ctx, struct preproc_macro *preproc_find_macro(struct preproc_ctx *ctx, const char *name) { - struct wine_rb_entry *entry; + struct rb_entry *entry; - if ((entry = wine_rb_get(&ctx->macros, name))) + if ((entry = rb_get(&ctx->macros, name))) return RB_ENTRY_VALUE(entry, struct preproc_macro, entry); return NULL; } @@ -97,7 +97,7 @@ bool preproc_add_macro(struct preproc_ctx *ctx, const struct vkd3d_shader_locati if ((macro = preproc_find_macro(ctx, name))) { preproc_warning(ctx, loc, VKD3D_SHADER_WARNING_PP_ALREADY_DEFINED, "Redefinition of %s.", name); - wine_rb_remove(&ctx->macros, ¯o->entry); + rb_remove(&ctx->macros, ¯o->entry); preproc_free_macro(macro); } @@ -118,7 +118,7 @@ bool preproc_add_macro(struct preproc_ctx *ctx, const struct vkd3d_shader_locati vkd3d_string_buffer_init(¯o->arg_values[i].text); macro->body.text = *body; macro->body.location = *body_loc; - ret = wine_rb_put(&ctx->macros, name, ¯o->entry); + ret = rb_put(&ctx->macros, name, ¯o->entry); assert(!ret); return true; } @@ -165,38 +165,6 @@ static bool preproc_push_if(struct preproc_ctx *ctx, bool condition) return true; } -static int char_to_int(char c) -{ - if ('0' <= c && c <= '9') - return c - '0'; - if ('A' <= c && c <= 'F') - return c - 'A' + 10; - if ('a' <= c && c <= 'f') - return c - 'a' + 10; - return -1; -} - -static uint32_t preproc_parse_integer(const char *s) -{ - uint32_t base = 10, ret = 0; - int digit; - - if (*s == '0') - { - base = 8; - ++s; - if (*s == 'x' || *s == 'X') - { - base = 16; - ++s; - } - } - - while ((digit = char_to_int(*s++)) >= 0) - ret = ret * base + (uint32_t)digit; - return ret; -} - static int default_open_include(const char *filename, bool local, const char *parent_data, void *context, struct vkd3d_shader_code *out) { @@ -557,7 +525,7 @@ directive if ((macro = preproc_find_macro(ctx, $2))) { TRACE("Removing macro definition %s.\n", debugstr_a($2)); - wine_rb_remove(&ctx->macros, ¯o->entry); + rb_remove(&ctx->macros, ¯o->entry); preproc_free_macro(macro); } vkd3d_free($2); @@ -691,7 +659,7 @@ directive primary_expr : T_INTEGER { - $$ = preproc_parse_integer($1); + $$ = vkd3d_parse_integer($1); vkd3d_free($1); } | T_IDENTIFIER diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/sm4.h b/dll/directx/wine/vkd3d/libs/vkd3d-shader/sm4.h similarity index 99% rename from dll/directx/wine/d3d12/vkd3d/vkd3d-shader/sm4.h rename to dll/directx/wine/vkd3d/libs/vkd3d-shader/sm4.h index 62bb4d12b8a4d..5ec4ee17e272c 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/sm4.h +++ b/dll/directx/wine/vkd3d/libs/vkd3d-shader/sm4.h @@ -56,6 +56,9 @@ #define VKD3D_SM4_RESOURCE_TYPE_SHIFT 11 #define VKD3D_SM4_RESOURCE_TYPE_MASK (0xfu << VKD3D_SM4_RESOURCE_TYPE_SHIFT) +#define VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT 16 +#define VKD3D_SM4_RESOURCE_SAMPLE_COUNT_MASK (0xfu << VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT) + #define VKD3D_SM4_PRIMITIVE_TYPE_SHIFT 11 #define VKD3D_SM4_PRIMITIVE_TYPE_MASK (0x3fu << VKD3D_SM4_PRIMITIVE_TYPE_SHIFT) @@ -350,6 +353,7 @@ enum vkd3d_sm4_opcode VKD3D_SM5_OP_DDIV = 0xd2, VKD3D_SM5_OP_DFMA = 0xd3, VKD3D_SM5_OP_DRCP = 0xd4, + VKD3D_SM5_OP_MSAD = 0xd5, VKD3D_SM5_OP_DTOI = 0xd6, VKD3D_SM5_OP_DTOU = 0xd7, VKD3D_SM5_OP_ITOD = 0xd8, diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/spirv.c b/dll/directx/wine/vkd3d/libs/vkd3d-shader/spirv.c similarity index 81% rename from dll/directx/wine/d3d12/vkd3d/vkd3d-shader/spirv.c rename to dll/directx/wine/vkd3d/libs/vkd3d-shader/spirv.c index c9ab8a56c9399..53e1373593733 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/spirv.c +++ b/dll/directx/wine/vkd3d/libs/vkd3d-shader/spirv.c @@ -1,6 +1,6 @@ /* * Copyright 2017 Józef Kucia for CodeWeavers - * Copyright 2021 Conor McCarthy for Codeweavers + * Copyright 2021 Conor McCarthy for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,12 +26,12 @@ #ifdef HAVE_SPIRV_UNIFIED1_SPIRV_H # include "spirv/unified1/spirv.h" #else -# include "spirv.h" +# include "vulkan/spirv.h" #endif /* HAVE_SPIRV_UNIFIED1_SPIRV_H */ #ifdef HAVE_SPIRV_UNIFIED1_GLSL_STD_450_H # include "spirv/unified1/GLSL.std.450.h" #else -# include "GLSL.std.450.h" +# include "vulkan/GLSL.std.450.h" #endif /* HAVE_SPIRV_UNIFIED1_GLSL_STD_450_H */ #ifdef HAVE_SPIRV_TOOLS @@ -206,7 +206,7 @@ static enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval(enum vkd3d_ #define VKD3D_SPIRV_VERSION 0x00010000 #define VKD3D_SPIRV_GENERATOR_ID 18 -#define VKD3D_SPIRV_GENERATOR_VERSION 3 +#define VKD3D_SPIRV_GENERATOR_VERSION 7 #define VKD3D_SPIRV_GENERATOR_MAGIC vkd3d_make_u32(VKD3D_SPIRV_GENERATOR_VERSION, VKD3D_SPIRV_GENERATOR_ID) struct vkd3d_spirv_stream @@ -335,7 +335,7 @@ struct vkd3d_spirv_builder uint32_t current_id; uint32_t main_function_id; - struct wine_rb_tree declarations; + struct rb_tree declarations; uint32_t type_sampler_id; uint32_t type_bool_id; uint32_t type_void_id; @@ -497,7 +497,7 @@ static uint32_t vkd3d_spirv_build_once(struct vkd3d_spirv_builder *builder, struct vkd3d_spirv_declaration { - struct wine_rb_entry entry; + struct rb_entry entry; SpvOp op; unsigned int parameter_count; @@ -505,10 +505,10 @@ struct vkd3d_spirv_declaration uint32_t id; }; -static int vkd3d_spirv_declaration_compare(const void *key, const struct wine_rb_entry *e) +static int vkd3d_spirv_declaration_compare(const void *key, const struct rb_entry *e) { const struct vkd3d_spirv_declaration *a = key; - const struct vkd3d_spirv_declaration *b = WINE_RB_ENTRY_VALUE(e, const struct vkd3d_spirv_declaration, entry); + const struct vkd3d_spirv_declaration *b = RB_ENTRY_VALUE(e, const struct vkd3d_spirv_declaration, entry); int ret; if ((ret = vkd3d_u32_compare(a->op, b->op))) @@ -519,9 +519,9 @@ static int vkd3d_spirv_declaration_compare(const void *key, const struct wine_rb return memcmp(&a->parameters, &b->parameters, a->parameter_count * sizeof(*a->parameters)); } -static void vkd3d_spirv_declaration_free(struct wine_rb_entry *entry, void *context) +static void vkd3d_spirv_declaration_free(struct rb_entry *entry, void *context) { - struct vkd3d_spirv_declaration *d = WINE_RB_ENTRY_VALUE(entry, struct vkd3d_spirv_declaration, entry); + struct vkd3d_spirv_declaration *d = RB_ENTRY_VALUE(entry, struct vkd3d_spirv_declaration, entry); vkd3d_free(d); } @@ -536,7 +536,7 @@ static void vkd3d_spirv_insert_declaration(struct vkd3d_spirv_builder *builder, if (!(d = vkd3d_malloc(sizeof(*d)))) return; memcpy(d, declaration, sizeof(*d)); - if (wine_rb_put(&builder->declarations, d, &d->entry) == -1) + if (rb_put(&builder->declarations, d, &d->entry) == -1) { ERR("Failed to insert declaration entry.\n"); vkd3d_free(d); @@ -547,14 +547,14 @@ static uint32_t vkd3d_spirv_build_once1(struct vkd3d_spirv_builder *builder, SpvOp op, uint32_t operand0, vkd3d_spirv_build1_pfn build_pfn) { struct vkd3d_spirv_declaration declaration; - struct wine_rb_entry *entry; + struct rb_entry *entry; declaration.op = op; declaration.parameter_count = 1; declaration.parameters[0] = operand0; - if ((entry = wine_rb_get(&builder->declarations, &declaration))) - return WINE_RB_ENTRY_VALUE(entry, struct vkd3d_spirv_declaration, entry)->id; + if ((entry = rb_get(&builder->declarations, &declaration))) + return RB_ENTRY_VALUE(entry, struct vkd3d_spirv_declaration, entry)->id; declaration.id = build_pfn(builder, operand0); vkd3d_spirv_insert_declaration(builder, &declaration); @@ -567,7 +567,7 @@ static uint32_t vkd3d_spirv_build_once1v(struct vkd3d_spirv_builder *builder, { struct vkd3d_spirv_declaration declaration; unsigned int i, param_idx = 0; - struct wine_rb_entry *entry; + struct rb_entry *entry; if (operand_count >= ARRAY_SIZE(declaration.parameters)) { @@ -581,8 +581,8 @@ static uint32_t vkd3d_spirv_build_once1v(struct vkd3d_spirv_builder *builder, declaration.parameters[param_idx++] = operands[i]; declaration.parameter_count = param_idx; - if ((entry = wine_rb_get(&builder->declarations, &declaration))) - return WINE_RB_ENTRY_VALUE(entry, struct vkd3d_spirv_declaration, entry)->id; + if ((entry = rb_get(&builder->declarations, &declaration))) + return RB_ENTRY_VALUE(entry, struct vkd3d_spirv_declaration, entry)->id; declaration.id = build_pfn(builder, operand0, operands, operand_count); vkd3d_spirv_insert_declaration(builder, &declaration); @@ -593,15 +593,15 @@ static uint32_t vkd3d_spirv_build_once2(struct vkd3d_spirv_builder *builder, SpvOp op, uint32_t operand0, uint32_t operand1, vkd3d_spirv_build2_pfn build_pfn) { struct vkd3d_spirv_declaration declaration; - struct wine_rb_entry *entry; + struct rb_entry *entry; declaration.op = op; declaration.parameter_count = 2; declaration.parameters[0] = operand0; declaration.parameters[1] = operand1; - if ((entry = wine_rb_get(&builder->declarations, &declaration))) - return WINE_RB_ENTRY_VALUE(entry, struct vkd3d_spirv_declaration, entry)->id; + if ((entry = rb_get(&builder->declarations, &declaration))) + return RB_ENTRY_VALUE(entry, struct vkd3d_spirv_declaration, entry)->id; declaration.id = build_pfn(builder, operand0, operand1); vkd3d_spirv_insert_declaration(builder, &declaration); @@ -612,14 +612,14 @@ static uint32_t vkd3d_spirv_build_once7(struct vkd3d_spirv_builder *builder, SpvOp op, const uint32_t *operands, vkd3d_spirv_build7_pfn build_pfn) { struct vkd3d_spirv_declaration declaration; - struct wine_rb_entry *entry; + struct rb_entry *entry; declaration.op = op; declaration.parameter_count = 7; memcpy(&declaration.parameters, operands, declaration.parameter_count * sizeof(*operands)); - if ((entry = wine_rb_get(&builder->declarations, &declaration))) - return WINE_RB_ENTRY_VALUE(entry, struct vkd3d_spirv_declaration, entry)->id; + if ((entry = rb_get(&builder->declarations, &declaration))) + return RB_ENTRY_VALUE(entry, struct vkd3d_spirv_declaration, entry)->id; declaration.id = build_pfn(builder, operands[0], operands[1], operands[2], operands[3], operands[4], operands[5], operands[6]); @@ -1066,8 +1066,8 @@ static uint32_t vkd3d_spirv_get_op_type_sampler(struct vkd3d_spirv_builder *buil /* Access qualifiers are not supported. */ static uint32_t vkd3d_spirv_build_op_type_image(struct vkd3d_spirv_builder *builder, - uint32_t sampled_type_id, SpvDim dim, uint32_t depth, uint32_t arrayed, - uint32_t ms, uint32_t sampled, SpvImageFormat format) + uint32_t sampled_type_id, uint32_t dim, uint32_t depth, uint32_t arrayed, + uint32_t ms, uint32_t sampled, uint32_t format) { uint32_t operands[] = {sampled_type_id, dim, depth, arrayed, ms, sampled, format}; return vkd3d_spirv_build_op_rv(builder, &builder->global_stream, @@ -1764,10 +1764,10 @@ static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder, const builder->current_id = 1; - wine_rb_init(&builder->declarations, vkd3d_spirv_declaration_compare); + rb_init(&builder->declarations, vkd3d_spirv_declaration_compare); builder->main_function_id = vkd3d_spirv_alloc_id(builder); - vkd3d_spirv_build_op_name(builder, builder->main_function_id, entry_point); + vkd3d_spirv_build_op_name(builder, builder->main_function_id, "%s", entry_point); } static void vkd3d_spirv_builder_begin_main_function(struct vkd3d_spirv_builder *builder) @@ -1795,7 +1795,7 @@ static void vkd3d_spirv_builder_free(struct vkd3d_spirv_builder *builder) vkd3d_free(builder->capabilities); - wine_rb_destroy(&builder->declarations, vkd3d_spirv_declaration_free, NULL); + rb_destroy(&builder->declarations, vkd3d_spirv_declaration_free, NULL); vkd3d_free(builder->iface); } @@ -2007,7 +2007,7 @@ struct vkd3d_symbol_descriptor_array_data struct vkd3d_symbol { - struct wine_rb_entry entry; + struct rb_entry entry; enum { @@ -2040,10 +2040,10 @@ struct vkd3d_symbol } info; }; -static int vkd3d_symbol_compare(const void *key, const struct wine_rb_entry *entry) +static int vkd3d_symbol_compare(const void *key, const struct rb_entry *entry) { const struct vkd3d_symbol *a = key; - const struct vkd3d_symbol *b = WINE_RB_ENTRY_VALUE(entry, const struct vkd3d_symbol, entry); + const struct vkd3d_symbol *b = RB_ENTRY_VALUE(entry, const struct vkd3d_symbol, entry); int ret; if ((ret = vkd3d_u32_compare(a->type, b->type))) @@ -2051,9 +2051,9 @@ static int vkd3d_symbol_compare(const void *key, const struct wine_rb_entry *ent return memcmp(&a->key, &b->key, sizeof(a->key)); } -static void vkd3d_symbol_free(struct wine_rb_entry *entry, void *context) +static void vkd3d_symbol_free(struct rb_entry *entry, void *context) { - struct vkd3d_symbol *s = WINE_RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); + struct vkd3d_symbol *s = RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); vkd3d_free(s); } @@ -2218,18 +2218,19 @@ struct vkd3d_hull_shader_variables uint32_t patch_constants_id; }; -struct vkd3d_dxbc_compiler +struct spirv_compiler { struct vkd3d_spirv_builder spirv_builder; struct vkd3d_shader_message_context *message_context; - const struct vkd3d_shader_location *location; + struct vkd3d_shader_location location; bool failed; bool strip_debug; bool ssbo_uavs; + bool uav_read_without_format; - struct wine_rb_tree symbol_table; + struct rb_tree symbol_table; uint32_t temp_id; unsigned int temp_count; struct vkd3d_hull_shader_variables hs; @@ -2284,6 +2285,7 @@ struct vkd3d_dxbc_compiler struct vkd3d_shader_spec_constant *spec_constants; size_t spec_constants_size; enum vkd3d_shader_compile_option_formatting_flags formatting; + bool write_tess_geom_point_size; struct vkd3d_string_buffer_cache string_buffers; }; @@ -2293,16 +2295,16 @@ static bool is_control_point_phase(const struct vkd3d_shader_phase *phase) return phase && phase->type == VKD3DSIH_HS_CONTROL_POINT_PHASE; } -static void vkd3d_dxbc_compiler_emit_initial_declarations(struct vkd3d_dxbc_compiler *compiler); +static void spirv_compiler_emit_initial_declarations(struct spirv_compiler *compiler); -static const char *vkd3d_dxbc_compiler_get_entry_point_name(const struct vkd3d_dxbc_compiler *compiler) +static const char *spirv_compiler_get_entry_point_name(const struct spirv_compiler *compiler) { const struct vkd3d_shader_spirv_target_info *info = compiler->spirv_target_info; return info && info->entry_point ? info->entry_point : "main"; } -struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader_version *shader_version, +struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_version *shader_version, const struct vkd3d_shader_desc *shader_desc, const struct vkd3d_shader_compile_info *compile_info, const struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info, struct vkd3d_shader_message_context *message_context, const struct vkd3d_shader_location *location) @@ -2312,7 +2314,7 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader const struct vkd3d_shader_interface_info *shader_interface; const struct vkd3d_shader_descriptor_offset_info *offset_info; const struct vkd3d_shader_spirv_target_info *target_info; - struct vkd3d_dxbc_compiler *compiler; + struct spirv_compiler *compiler; unsigned int max_element_count; unsigned int i; @@ -2321,7 +2323,7 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader memset(compiler, 0, sizeof(*compiler)); compiler->message_context = message_context; - compiler->location = location; + compiler->location = *location; if ((target_info = vkd3d_find_struct(compile_info->next, SPIRV_TARGET_INFO))) { @@ -2346,10 +2348,11 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader return NULL; } - vkd3d_spirv_builder_init(&compiler->spirv_builder, vkd3d_dxbc_compiler_get_entry_point_name(compiler)); + vkd3d_spirv_builder_init(&compiler->spirv_builder, spirv_compiler_get_entry_point_name(compiler)); compiler->formatting = VKD3D_SHADER_COMPILE_OPTION_FORMATTING_INDENT | VKD3D_SHADER_COMPILE_OPTION_FORMATTING_HEADER; + compiler->write_tess_geom_point_size = true; for (i = 0; i < compile_info->option_count; ++i) { @@ -2376,11 +2379,26 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader default: WARN("Ignoring unrecognised option %#x with value %#x.\n", option->name, option->value); + + case VKD3D_SHADER_COMPILE_OPTION_API_VERSION: + break; + + case VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV: + if (option->value == VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV_READ_FORMAT_R32) + compiler->uav_read_without_format = false; + else if (option->value == VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV_READ_FORMAT_UNKNOWN) + compiler->uav_read_without_format = true; + else + WARN("Ignoring unrecognised value %#x for option %#x.\n", option->value, option->name); + break; + + case VKD3D_SHADER_COMPILE_OPTION_WRITE_TESS_GEOM_POINT_SIZE: + compiler->write_tess_geom_point_size = option->value; break; } } - wine_rb_init(&compiler->symbol_table, vkd3d_symbol_compare); + rb_init(&compiler->symbol_table, vkd3d_symbol_compare); compiler->shader_type = shader_version->type; @@ -2398,7 +2416,7 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader if (!(compiler->push_constants = vkd3d_calloc(shader_interface->push_constant_buffer_count, sizeof(*compiler->push_constants)))) { - vkd3d_dxbc_compiler_destroy(compiler); + spirv_compiler_destroy(compiler); return NULL; } for (i = 0; i < shader_interface->push_constant_buffer_count; ++i) @@ -2411,7 +2429,7 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader if (compiler->offset_info.descriptor_table_count && !(compiler->descriptor_offset_ids = vkd3d_calloc( compiler->offset_info.descriptor_table_count, sizeof(*compiler->descriptor_offset_ids)))) { - vkd3d_dxbc_compiler_destroy(compiler); + spirv_compiler_destroy(compiler); return NULL; } } @@ -2421,31 +2439,31 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader vkd3d_string_buffer_cache_init(&compiler->string_buffers); - vkd3d_dxbc_compiler_emit_initial_declarations(compiler); + spirv_compiler_emit_initial_declarations(compiler); return compiler; } -static bool vkd3d_dxbc_compiler_use_storage_buffer(const struct vkd3d_dxbc_compiler *compiler, +static bool spirv_compiler_use_storage_buffer(const struct spirv_compiler *compiler, const struct vkd3d_symbol_resource_data *resource) { return compiler->ssbo_uavs && resource->resource_type_info->resource_type == VKD3D_SHADER_RESOURCE_BUFFER; } -static enum vkd3d_shader_spirv_environment vkd3d_dxbc_compiler_get_target_environment( - const struct vkd3d_dxbc_compiler *compiler) +static enum vkd3d_shader_spirv_environment spirv_compiler_get_target_environment( + const struct spirv_compiler *compiler) { const struct vkd3d_shader_spirv_target_info *info = compiler->spirv_target_info; return info ? info->environment : VKD3D_SHADER_SPIRV_ENVIRONMENT_VULKAN_1_0; } -static bool vkd3d_dxbc_compiler_is_opengl_target(const struct vkd3d_dxbc_compiler *compiler) +static bool spirv_compiler_is_opengl_target(const struct spirv_compiler *compiler) { - return vkd3d_dxbc_compiler_get_target_environment(compiler) == VKD3D_SHADER_SPIRV_ENVIRONMENT_OPENGL_4_5; + return spirv_compiler_get_target_environment(compiler) == VKD3D_SHADER_SPIRV_ENVIRONMENT_OPENGL_4_5; } -static bool vkd3d_dxbc_compiler_is_target_extension_supported(const struct vkd3d_dxbc_compiler *compiler, +static bool spirv_compiler_is_target_extension_supported(const struct spirv_compiler *compiler, enum vkd3d_shader_spirv_extension extension) { const struct vkd3d_shader_spirv_target_info *info = compiler->spirv_target_info; @@ -2460,7 +2478,7 @@ static bool vkd3d_dxbc_compiler_is_target_extension_supported(const struct vkd3d return false; } -static bool vkd3d_dxbc_compiler_check_shader_visibility(const struct vkd3d_dxbc_compiler *compiler, +static bool spirv_compiler_check_shader_visibility(const struct spirv_compiler *compiler, enum vkd3d_shader_visibility visibility) { switch (visibility) @@ -2485,8 +2503,8 @@ static bool vkd3d_dxbc_compiler_check_shader_visibility(const struct vkd3d_dxbc_ } } -static struct vkd3d_push_constant_buffer_binding *vkd3d_dxbc_compiler_find_push_constant_buffer( - const struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_constant_buffer *cb) +static struct vkd3d_push_constant_buffer_binding *spirv_compiler_find_push_constant_buffer( + const struct spirv_compiler *compiler, const struct vkd3d_shader_constant_buffer *cb) { unsigned int register_space = cb->range.space; unsigned int reg_idx = cb->range.first; @@ -2499,7 +2517,7 @@ static struct vkd3d_push_constant_buffer_binding *vkd3d_dxbc_compiler_find_push_ { struct vkd3d_push_constant_buffer_binding *current = &compiler->push_constants[i]; - if (!vkd3d_dxbc_compiler_check_shader_visibility(compiler, current->pc.shader_visibility)) + if (!spirv_compiler_check_shader_visibility(compiler, current->pc.shader_visibility)) continue; if (current->pc.register_space == register_space && current->pc.register_index == reg_idx) @@ -2509,7 +2527,7 @@ static struct vkd3d_push_constant_buffer_binding *vkd3d_dxbc_compiler_find_push_ return NULL; } -static bool vkd3d_dxbc_compiler_has_combined_sampler(const struct vkd3d_dxbc_compiler *compiler, +static bool spirv_compiler_has_combined_sampler(const struct spirv_compiler *compiler, const struct vkd3d_shader_resource *resource, const struct vkd3d_shader_sampler *sampler) { const struct vkd3d_shader_interface_info *shader_interface = &compiler->shader_interface; @@ -2529,7 +2547,7 @@ static bool vkd3d_dxbc_compiler_has_combined_sampler(const struct vkd3d_dxbc_com { combined_sampler = &shader_interface->combined_samplers[i]; - if (!vkd3d_dxbc_compiler_check_shader_visibility(compiler, combined_sampler->shader_visibility)) + if (!spirv_compiler_check_shader_visibility(compiler, combined_sampler->shader_visibility)) continue; if ((!resource || (combined_sampler->resource_space == resource->range.space @@ -2542,18 +2560,18 @@ static bool vkd3d_dxbc_compiler_has_combined_sampler(const struct vkd3d_dxbc_com return false; } -static void VKD3D_PRINTF_FUNC(3, 4) vkd3d_dxbc_compiler_error(struct vkd3d_dxbc_compiler *compiler, +static void VKD3D_PRINTF_FUNC(3, 4) spirv_compiler_error(struct spirv_compiler *compiler, enum vkd3d_shader_error error, const char *format, ...) { va_list args; va_start(args, format); - vkd3d_shader_verror(compiler->message_context, compiler->location, error, format, args); + vkd3d_shader_verror(compiler->message_context, &compiler->location, error, format, args); va_end(args); compiler->failed = true; } -static struct vkd3d_string_buffer *vkd3d_shader_register_range_string(struct vkd3d_dxbc_compiler *compiler, +static struct vkd3d_string_buffer *vkd3d_shader_register_range_string(struct spirv_compiler *compiler, const struct vkd3d_shader_register_range *range) { struct vkd3d_string_buffer *buffer = vkd3d_string_buffer_get(&compiler->string_buffers); @@ -2569,8 +2587,8 @@ static struct vkd3d_string_buffer *vkd3d_shader_register_range_string(struct vkd return buffer; } -static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor_binding( - struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_register *reg, +static struct vkd3d_shader_descriptor_binding spirv_compiler_get_descriptor_binding( + struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, const struct vkd3d_shader_register_range *range, enum vkd3d_shader_resource_type resource_type, bool is_uav_counter, struct vkd3d_descriptor_binding_address *binding_address) { @@ -2593,7 +2611,7 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor else { FIXME("Unhandled register type %#x.\n", reg->type); - vkd3d_dxbc_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_REGISTER_TYPE, + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_REGISTER_TYPE, "Encountered invalid/unhandled register type %#x.", reg->type); goto done; } @@ -2609,7 +2627,7 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor { const struct vkd3d_shader_uav_counter_binding *current = &shader_interface->uav_counters[i]; - if (!vkd3d_dxbc_compiler_check_shader_visibility(compiler, current->shader_visibility)) + if (!spirv_compiler_check_shader_visibility(compiler, current->shader_visibility)) continue; if (current->register_space != range->space || current->register_index > range->first @@ -2619,7 +2637,7 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor if (current->offset) { FIXME("Atomic counter offsets are not supported yet.\n"); - vkd3d_dxbc_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_DESCRIPTOR_BINDING, + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_DESCRIPTOR_BINDING, "Descriptor binding for UAV counter %u, space %u has unsupported ‘offset’ %u.", range->first, range->space, current->offset); } @@ -2632,7 +2650,7 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor if (shader_interface->uav_counter_count) { FIXME("Could not find descriptor binding for UAV counter %u, space %u.\n", range->first, range->space); - vkd3d_dxbc_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_DESCRIPTOR_BINDING_NOT_FOUND, + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_DESCRIPTOR_BINDING_NOT_FOUND, "Could not find descriptor binding for UAV counter %u, space %u.", range->first, range->space); } } @@ -2646,7 +2664,7 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor if (!(current->flags & resource_type_flag)) continue; - if (!vkd3d_dxbc_compiler_check_shader_visibility(compiler, current->shader_visibility)) + if (!spirv_compiler_check_shader_visibility(compiler, current->shader_visibility)) continue; if (current->type != descriptor_type || current->register_space != range->space @@ -2665,7 +2683,7 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor const char *range_str = buffer ? buffer->buffer : ""; FIXME("Could not find descriptor binding for type %#x, space %u, registers %s, shader type %#x.\n", descriptor_type, range->space, range_str, compiler->shader_type); - vkd3d_dxbc_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_DESCRIPTOR_BINDING_NOT_FOUND, + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_DESCRIPTOR_BINDING_NOT_FOUND, "Could not find descriptor binding for type %#x, space %u, registers %s, shader type %#x.", descriptor_type, range->space, range_str, compiler->shader_type); vkd3d_string_buffer_release(&compiler->string_buffers, buffer); @@ -2681,7 +2699,7 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor return binding; } -static void vkd3d_dxbc_compiler_emit_descriptor_binding(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_descriptor_binding(struct spirv_compiler *compiler, uint32_t variable_id, const struct vkd3d_shader_descriptor_binding *binding) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -2690,7 +2708,7 @@ static void vkd3d_dxbc_compiler_emit_descriptor_binding(struct vkd3d_dxbc_compil vkd3d_spirv_build_op_decorate1(builder, variable_id, SpvDecorationBinding, binding->binding); } -static void vkd3d_dxbc_compiler_decorate_nonuniform(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_decorate_nonuniform(struct spirv_compiler *compiler, uint32_t expression_id) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -2699,13 +2717,13 @@ static void vkd3d_dxbc_compiler_decorate_nonuniform(struct vkd3d_dxbc_compiler * vkd3d_spirv_build_op_decorate(builder, expression_id, SpvDecorationNonUniformEXT, NULL, 0); } -static const struct vkd3d_symbol *vkd3d_dxbc_compiler_put_symbol(struct vkd3d_dxbc_compiler *compiler, +static const struct vkd3d_symbol *spirv_compiler_put_symbol(struct spirv_compiler *compiler, const struct vkd3d_symbol *symbol) { struct vkd3d_symbol *s; s = vkd3d_symbol_dup(symbol); - if (wine_rb_put(&compiler->symbol_table, s, &s->entry) == -1) + if (rb_put(&compiler->symbol_table, s, &s->entry) == -1) { ERR("Failed to insert symbol entry (%s).\n", debug_vkd3d_symbol(symbol)); vkd3d_free(s); @@ -2714,7 +2732,7 @@ static const struct vkd3d_symbol *vkd3d_dxbc_compiler_put_symbol(struct vkd3d_dx return s; } -static uint32_t vkd3d_dxbc_compiler_get_constant(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_get_constant(struct spirv_compiler *compiler, enum vkd3d_shader_component_type component_type, unsigned int component_count, const uint32_t *values) { uint32_t type_id, scalar_type_id, component_ids[VKD3D_VEC4_SIZE]; @@ -2748,7 +2766,7 @@ static uint32_t vkd3d_dxbc_compiler_get_constant(struct vkd3d_dxbc_compiler *com } } -static uint32_t vkd3d_dxbc_compiler_get_constant64(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_get_constant64(struct spirv_compiler *compiler, enum vkd3d_shader_component_type component_type, unsigned int component_count, const uint64_t *values) { uint32_t type_id, scalar_type_id, component_ids[VKD3D_DVEC2_SIZE]; @@ -2777,48 +2795,48 @@ static uint32_t vkd3d_dxbc_compiler_get_constant64(struct vkd3d_dxbc_compiler *c } } -static uint32_t vkd3d_dxbc_compiler_get_constant_uint(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_get_constant_uint(struct spirv_compiler *compiler, uint32_t value) { - return vkd3d_dxbc_compiler_get_constant(compiler, VKD3D_SHADER_COMPONENT_UINT, 1, &value); + return spirv_compiler_get_constant(compiler, VKD3D_SHADER_COMPONENT_UINT, 1, &value); } -static uint32_t vkd3d_dxbc_compiler_get_constant_float(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_get_constant_float(struct spirv_compiler *compiler, float value) { - return vkd3d_dxbc_compiler_get_constant(compiler, VKD3D_SHADER_COMPONENT_FLOAT, 1, (uint32_t *)&value); + return spirv_compiler_get_constant(compiler, VKD3D_SHADER_COMPONENT_FLOAT, 1, (uint32_t *)&value); } -static uint32_t vkd3d_dxbc_compiler_get_constant_vector(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_get_constant_vector(struct spirv_compiler *compiler, enum vkd3d_shader_component_type component_type, unsigned int component_count, uint32_t value) { const uint32_t values[] = {value, value, value, value}; - return vkd3d_dxbc_compiler_get_constant(compiler, component_type, component_count, values); + return spirv_compiler_get_constant(compiler, component_type, component_count, values); } -static uint32_t vkd3d_dxbc_compiler_get_constant_uint_vector(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_get_constant_uint_vector(struct spirv_compiler *compiler, uint32_t value, unsigned int component_count) { - return vkd3d_dxbc_compiler_get_constant_vector(compiler, VKD3D_SHADER_COMPONENT_UINT, component_count, value); + return spirv_compiler_get_constant_vector(compiler, VKD3D_SHADER_COMPONENT_UINT, component_count, value); } -static uint32_t vkd3d_dxbc_compiler_get_constant_float_vector(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_get_constant_float_vector(struct spirv_compiler *compiler, float value, unsigned int component_count) { const float values[] = {value, value, value, value}; - return vkd3d_dxbc_compiler_get_constant(compiler, VKD3D_SHADER_COMPONENT_FLOAT, + return spirv_compiler_get_constant(compiler, VKD3D_SHADER_COMPONENT_FLOAT, component_count, (const uint32_t *)values); } -static uint32_t vkd3d_dxbc_compiler_get_constant_double_vector(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_get_constant_double_vector(struct spirv_compiler *compiler, double value, unsigned int component_count) { const double values[] = {value, value}; - return vkd3d_dxbc_compiler_get_constant64(compiler, VKD3D_SHADER_COMPONENT_DOUBLE, + return spirv_compiler_get_constant64(compiler, VKD3D_SHADER_COMPONENT_DOUBLE, component_count, (const uint64_t *)values); } -static uint32_t vkd3d_dxbc_compiler_get_type_id_for_reg(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_get_type_id_for_reg(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, DWORD write_mask) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -2828,13 +2846,13 @@ static uint32_t vkd3d_dxbc_compiler_get_type_id_for_reg(struct vkd3d_dxbc_compil vkd3d_write_mask_component_count(write_mask)); } -static uint32_t vkd3d_dxbc_compiler_get_type_id_for_dst(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_get_type_id_for_dst(struct spirv_compiler *compiler, const struct vkd3d_shader_dst_param *dst) { - return vkd3d_dxbc_compiler_get_type_id_for_reg(compiler, &dst->reg, dst->write_mask); + return spirv_compiler_get_type_id_for_reg(compiler, &dst->reg, dst->write_mask); } -static bool vkd3d_dxbc_compiler_get_register_name(char *buffer, unsigned int buffer_size, +static bool spirv_compiler_get_register_name(char *buffer, unsigned int buffer_size, const struct vkd3d_shader_register *reg) { unsigned int idx; @@ -2925,15 +2943,15 @@ static bool vkd3d_dxbc_compiler_get_register_name(char *buffer, unsigned int buf } /* TODO: UAV counters: vkd3d_spirv_build_op_name(builder, counter_var_id, "u%u_counter", reg->idx[0].offset); */ -static void vkd3d_dxbc_compiler_emit_register_debug_name(struct vkd3d_spirv_builder *builder, +static void spirv_compiler_emit_register_debug_name(struct vkd3d_spirv_builder *builder, uint32_t id, const struct vkd3d_shader_register *reg) { char debug_name[256]; - if (vkd3d_dxbc_compiler_get_register_name(debug_name, ARRAY_SIZE(debug_name), reg)) + if (spirv_compiler_get_register_name(debug_name, ARRAY_SIZE(debug_name), reg)) vkd3d_spirv_build_op_name(builder, id, "%s", debug_name); } -static uint32_t vkd3d_dxbc_compiler_emit_variable(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_variable(struct spirv_compiler *compiler, struct vkd3d_spirv_stream *stream, SpvStorageClass storage_class, enum vkd3d_shader_component_type component_type, unsigned int component_count) { @@ -2945,7 +2963,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_variable(struct vkd3d_dxbc_compiler *co return vkd3d_spirv_build_op_variable(builder, stream, ptr_type_id, storage_class, 0); } -static uint32_t vkd3d_dxbc_compiler_emit_array_variable(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_array_variable(struct spirv_compiler *compiler, struct vkd3d_spirv_stream *stream, SpvStorageClass storage_class, enum vkd3d_shader_component_type component_type, unsigned int component_count, unsigned int array_length) { @@ -2953,18 +2971,18 @@ static uint32_t vkd3d_dxbc_compiler_emit_array_variable(struct vkd3d_dxbc_compil uint32_t type_id, length_id, ptr_type_id; if (!array_length) - return vkd3d_dxbc_compiler_emit_variable(compiler, + return spirv_compiler_emit_variable(compiler, stream, storage_class, component_type, component_count); type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); - length_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, array_length); + length_id = spirv_compiler_get_constant_uint(compiler, array_length); type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, type_id); return vkd3d_spirv_build_op_variable(builder, stream, ptr_type_id, storage_class, 0); } -static const struct vkd3d_shader_parameter *vkd3d_dxbc_compiler_get_shader_parameter( - struct vkd3d_dxbc_compiler *compiler, enum vkd3d_shader_parameter_name name) +static const struct vkd3d_shader_parameter *spirv_compiler_get_shader_parameter( + struct spirv_compiler *compiler, enum vkd3d_shader_parameter_name name) { const struct vkd3d_shader_spirv_target_info *info = compiler->spirv_target_info; unsigned int i; @@ -3003,7 +3021,7 @@ static const struct vkd3d_spec_constant_info *get_spec_constant_info(enum vkd3d_ return NULL; } -static uint32_t vkd3d_dxbc_compiler_alloc_spec_constant_id(struct vkd3d_dxbc_compiler *compiler) +static uint32_t spirv_compiler_alloc_spec_constant_id(struct spirv_compiler *compiler) { if (!compiler->current_spec_constant_id) { @@ -3024,7 +3042,7 @@ static uint32_t vkd3d_dxbc_compiler_alloc_spec_constant_id(struct vkd3d_dxbc_com return compiler->current_spec_constant_id++; } -static uint32_t vkd3d_dxbc_compiler_emit_spec_constant(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_spec_constant(struct spirv_compiler *compiler, enum vkd3d_shader_parameter_name name, uint32_t spec_id) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -3052,7 +3070,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_spec_constant(struct vkd3d_dxbc_compile return id; } -static uint32_t vkd3d_dxbc_compiler_get_spec_constant(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_get_spec_constant(struct spirv_compiler *compiler, enum vkd3d_shader_parameter_name name, uint32_t spec_id) { unsigned int i; @@ -3063,33 +3081,33 @@ static uint32_t vkd3d_dxbc_compiler_get_spec_constant(struct vkd3d_dxbc_compiler return compiler->spec_constants[i].id; } - return vkd3d_dxbc_compiler_emit_spec_constant(compiler, name, spec_id); + return spirv_compiler_emit_spec_constant(compiler, name, spec_id); } -static uint32_t vkd3d_dxbc_compiler_emit_uint_shader_parameter(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_uint_shader_parameter(struct spirv_compiler *compiler, enum vkd3d_shader_parameter_name name) { const struct vkd3d_shader_parameter *parameter; - if (!(parameter = vkd3d_dxbc_compiler_get_shader_parameter(compiler, name))) + if (!(parameter = spirv_compiler_get_shader_parameter(compiler, name))) { WARN("Unresolved shader parameter %#x.\n", name); goto default_parameter; } if (parameter->type == VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) - return vkd3d_dxbc_compiler_get_constant_uint(compiler, parameter->u.immediate_constant.u.u32); + return spirv_compiler_get_constant_uint(compiler, parameter->u.immediate_constant.u.u32); if (parameter->type == VKD3D_SHADER_PARAMETER_TYPE_SPECIALIZATION_CONSTANT) - return vkd3d_dxbc_compiler_get_spec_constant(compiler, name, parameter->u.specialization_constant.id); + return spirv_compiler_get_spec_constant(compiler, name, parameter->u.specialization_constant.id); FIXME("Unhandled parameter type %#x.\n", parameter->type); default_parameter: - return vkd3d_dxbc_compiler_get_spec_constant(compiler, - name, vkd3d_dxbc_compiler_alloc_spec_constant_id(compiler)); + return spirv_compiler_get_spec_constant(compiler, + name, spirv_compiler_alloc_spec_constant_id(compiler)); } -static uint32_t vkd3d_dxbc_compiler_emit_construct_vector(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_construct_vector(struct spirv_compiler *compiler, enum vkd3d_shader_component_type component_type, unsigned int component_count, uint32_t val_id, unsigned int val_component_idx, unsigned int val_component_count) { @@ -3118,24 +3136,24 @@ static uint32_t vkd3d_dxbc_compiler_emit_construct_vector(struct vkd3d_dxbc_comp return result_id; } -static uint32_t vkd3d_dxbc_compiler_emit_load_src(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_load_src(struct spirv_compiler *compiler, const struct vkd3d_shader_src_param *src, DWORD write_mask); -static uint32_t vkd3d_dxbc_compiler_emit_register_addressing(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_register_addressing(struct spirv_compiler *compiler, const struct vkd3d_shader_register_index *reg_index) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id, addr_id; if (!reg_index->rel_addr) - return vkd3d_dxbc_compiler_get_constant_uint(compiler, reg_index->offset); + return spirv_compiler_get_constant_uint(compiler, reg_index->offset); - addr_id = vkd3d_dxbc_compiler_emit_load_src(compiler, reg_index->rel_addr, VKD3DSP_WRITEMASK_0); + addr_id = spirv_compiler_emit_load_src(compiler, reg_index->rel_addr, VKD3DSP_WRITEMASK_0); if (reg_index->offset) { type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); addr_id = vkd3d_spirv_build_op_iadd(builder, type_id, - addr_id, vkd3d_dxbc_compiler_get_constant_uint(compiler, reg_index->offset)); + addr_id, spirv_compiler_get_constant_uint(compiler, reg_index->offset)); } return addr_id; } @@ -3154,11 +3172,11 @@ struct vkd3d_shader_register_info bool is_dynamically_indexed; }; -static bool vkd3d_dxbc_compiler_get_register_info(const struct vkd3d_dxbc_compiler *compiler, +static bool spirv_compiler_get_register_info(const struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, struct vkd3d_shader_register_info *register_info) { struct vkd3d_symbol reg_symbol, *symbol; - struct wine_rb_entry *entry; + struct rb_entry *entry; assert(reg->type != VKD3DSPR_IMMCONST && reg->type != VKD3DSPR_IMMCONST64); @@ -3179,14 +3197,14 @@ static bool vkd3d_dxbc_compiler_get_register_info(const struct vkd3d_dxbc_compil } vkd3d_symbol_make_register(®_symbol, reg); - if (!(entry = wine_rb_get(&compiler->symbol_table, ®_symbol))) + if (!(entry = rb_get(&compiler->symbol_table, ®_symbol))) { FIXME("Unrecognized register (%s).\n", debug_vkd3d_symbol(®_symbol)); memset(register_info, 0, sizeof(*register_info)); return false; } - symbol = WINE_RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); + symbol = RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); register_info->id = symbol->id; register_info->descriptor_array = symbol->descriptor_array; register_info->storage_class = symbol->info.reg.storage_class; @@ -3216,12 +3234,12 @@ static bool register_is_descriptor(const struct vkd3d_shader_register *reg) } } -static bool vkd3d_dxbc_compiler_enable_descriptor_indexing(struct vkd3d_dxbc_compiler *compiler, +static bool spirv_compiler_enable_descriptor_indexing(struct spirv_compiler *compiler, enum vkd3d_shader_register_type reg_type, enum vkd3d_shader_resource_type resource_type) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - if (!vkd3d_dxbc_compiler_is_target_extension_supported(compiler, + if (!spirv_compiler_is_target_extension_supported(compiler, VKD3D_SHADER_SPIRV_EXTENSION_EXT_DESCRIPTOR_INDEXING)) return false; @@ -3253,7 +3271,7 @@ static bool vkd3d_dxbc_compiler_enable_descriptor_indexing(struct vkd3d_dxbc_com return true; } -static uint32_t vkd3d_dxbc_compiler_get_descriptor_index(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_get_descriptor_index(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, const struct vkd3d_symbol *array_symbol, unsigned int binding_base_idx, enum vkd3d_shader_resource_type resource_type) { @@ -3264,17 +3282,17 @@ static uint32_t vkd3d_dxbc_compiler_get_descriptor_index(struct vkd3d_dxbc_compi if ((push_constant_index = array_key->push_constant_index) != ~0u || index.rel_addr) { - if (!vkd3d_dxbc_compiler_enable_descriptor_indexing(compiler, reg->type, resource_type)) + if (!spirv_compiler_enable_descriptor_indexing(compiler, reg->type, resource_type)) { FIXME("The target environment does not support descriptor indexing.\n"); - vkd3d_dxbc_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_DESCRIPTOR_IDX_UNSUPPORTED, + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_DESCRIPTOR_IDX_UNSUPPORTED, "Cannot dynamically index a descriptor array of type %#x, id %u. " "The target environment does not support descriptor indexing.", reg->type, reg->idx[0].offset); } } index.offset -= binding_base_idx; - index_id = vkd3d_dxbc_compiler_emit_register_addressing(compiler, &index); + index_id = spirv_compiler_emit_register_addressing(compiler, &index); if (push_constant_index != ~0u) { @@ -3285,7 +3303,7 @@ static uint32_t vkd3d_dxbc_compiler_get_descriptor_index(struct vkd3d_dxbc_compi if (!(offset_id = compiler->descriptor_offset_ids[push_constant_index])) { index_ids[0] = compiler->descriptor_offsets_member_id; - index_ids[1] = vkd3d_dxbc_compiler_get_constant_uint(compiler, push_constant_index); + index_ids[1] = spirv_compiler_get_constant_uint(compiler, push_constant_index); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPushConstant, type_id); ptr_id = vkd3d_spirv_build_op_in_bounds_access_chain(builder, ptr_type_id, compiler->push_constants_var_id, index_ids, 2); @@ -3299,7 +3317,7 @@ static uint32_t vkd3d_dxbc_compiler_get_descriptor_index(struct vkd3d_dxbc_compi return index_id; } -static void vkd3d_dxbc_compiler_emit_dereference_register(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_dereference_register(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, struct vkd3d_shader_register_info *register_info) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -3311,18 +3329,18 @@ static void vkd3d_dxbc_compiler_emit_dereference_register(struct vkd3d_dxbc_comp { assert(!reg->idx[0].rel_addr); if (register_info->descriptor_array) - indexes[index_count++] = vkd3d_dxbc_compiler_get_descriptor_index(compiler, reg, + indexes[index_count++] = spirv_compiler_get_descriptor_index(compiler, reg, register_info->descriptor_array, register_info->binding_base_idx, VKD3D_SHADER_RESOURCE_BUFFER); - indexes[index_count++] = vkd3d_dxbc_compiler_get_constant_uint(compiler, register_info->member_idx); - indexes[index_count++] = vkd3d_dxbc_compiler_emit_register_addressing(compiler, ®->idx[2]); + indexes[index_count++] = spirv_compiler_get_constant_uint(compiler, register_info->member_idx); + indexes[index_count++] = spirv_compiler_emit_register_addressing(compiler, ®->idx[2]); } else if (reg->type == VKD3DSPR_IMMCONSTBUFFER) { - indexes[index_count++] = vkd3d_dxbc_compiler_emit_register_addressing(compiler, ®->idx[0]); + indexes[index_count++] = spirv_compiler_emit_register_addressing(compiler, ®->idx[0]); } else if (reg->type == VKD3DSPR_IDXTEMP) { - indexes[index_count++] = vkd3d_dxbc_compiler_emit_register_addressing(compiler, ®->idx[1]); + indexes[index_count++] = spirv_compiler_emit_register_addressing(compiler, ®->idx[1]); } else if (register_info->is_aggregate) { @@ -3330,9 +3348,9 @@ static void vkd3d_dxbc_compiler_emit_dereference_register(struct vkd3d_dxbc_comp { /* Indices for these are swapped compared to the generated SPIR-V. */ if (reg->idx[1].offset != ~0u) - indexes[index_count++] = vkd3d_dxbc_compiler_emit_register_addressing(compiler, ®->idx[1]); + indexes[index_count++] = spirv_compiler_emit_register_addressing(compiler, ®->idx[1]); if (reg->idx[0].offset != ~0u) - indexes[index_count++] = vkd3d_dxbc_compiler_emit_register_addressing(compiler, ®->idx[0]); + indexes[index_count++] = spirv_compiler_emit_register_addressing(compiler, ®->idx[0]); } else { @@ -3350,7 +3368,7 @@ static void vkd3d_dxbc_compiler_emit_dereference_register(struct vkd3d_dxbc_comp else { reg_idx.offset = register_info->member_idx; - indexes[index_count++] = vkd3d_dxbc_compiler_emit_register_addressing(compiler, ®_idx); + indexes[index_count++] = spirv_compiler_emit_register_addressing(compiler, ®_idx); } } } @@ -3361,7 +3379,7 @@ static void vkd3d_dxbc_compiler_emit_dereference_register(struct vkd3d_dxbc_comp /* Handle arrayed registers, e.g. v[3][0]. */ if (reg->idx[1].offset != ~0u && !register_is_descriptor(reg)) - indexes[index_count++] = vkd3d_dxbc_compiler_emit_register_addressing(compiler, ®->idx[0]); + indexes[index_count++] = spirv_compiler_emit_register_addressing(compiler, ®->idx[0]); } if (index_count) @@ -3372,23 +3390,23 @@ static void vkd3d_dxbc_compiler_emit_dereference_register(struct vkd3d_dxbc_comp register_info->id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, register_info->id, indexes, index_count); if (reg->non_uniform) - vkd3d_dxbc_compiler_decorate_nonuniform(compiler, register_info->id); + spirv_compiler_decorate_nonuniform(compiler, register_info->id); } } -static uint32_t vkd3d_dxbc_compiler_get_register_id(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_get_register_id(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; struct vkd3d_shader_register_info register_info; - if (vkd3d_dxbc_compiler_get_register_info(compiler, reg, ®ister_info)) + if (spirv_compiler_get_register_info(compiler, reg, ®ister_info)) { - vkd3d_dxbc_compiler_emit_dereference_register(compiler, reg, ®ister_info); + spirv_compiler_emit_dereference_register(compiler, reg, ®ister_info); return register_info.id; } - return vkd3d_dxbc_compiler_emit_variable(compiler, &builder->global_stream, + return spirv_compiler_emit_variable(compiler, &builder->global_stream, SpvStorageClassPrivate, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); } @@ -3398,7 +3416,7 @@ static bool vkd3d_swizzle_is_equal(unsigned int dst_write_mask, return vkd3d_compact_swizzle(VKD3D_SHADER_NO_SWIZZLE, dst_write_mask) == vkd3d_compact_swizzle(swizzle, write_mask); } -static uint32_t vkd3d_dxbc_compiler_emit_swizzle(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler, uint32_t val_id, unsigned int val_write_mask, enum vkd3d_shader_component_type component_type, unsigned int swizzle, unsigned int write_mask) { @@ -3445,7 +3463,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_swizzle(struct vkd3d_dxbc_compiler *com type_id, val_id, val_id, components, component_count); } -static uint32_t vkd3d_dxbc_compiler_emit_vector_shuffle(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compiler, uint32_t vector1_id, uint32_t vector2_id, unsigned int swizzle, unsigned int write_mask, enum vkd3d_shader_component_type component_type, unsigned int component_count) { @@ -3469,7 +3487,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_vector_shuffle(struct vkd3d_dxbc_compil type_id, vector1_id, vector2_id, components, component_count); } -static uint32_t vkd3d_dxbc_compiler_emit_load_constant(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask) { unsigned int component_count = vkd3d_write_mask_component_count(write_mask); @@ -3492,11 +3510,11 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_constant(struct vkd3d_dxbc_compile } } - return vkd3d_dxbc_compiler_get_constant(compiler, + return spirv_compiler_get_constant(compiler, vkd3d_component_type_from_data_type(reg->data_type), component_count, values); } -static uint32_t vkd3d_dxbc_compiler_emit_load_constant64(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_load_constant64(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask) { unsigned int component_count = vkd3d_write_mask_component_count(write_mask); @@ -3519,11 +3537,11 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_constant64(struct vkd3d_dxbc_compi } } - return vkd3d_dxbc_compiler_get_constant64(compiler, + return spirv_compiler_get_constant64(compiler, vkd3d_component_type_from_data_type(reg->data_type), component_count, values); } -static uint32_t vkd3d_dxbc_compiler_emit_load_scalar(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask, const struct vkd3d_shader_register_info *reg_info) { @@ -3556,7 +3574,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_scalar(struct vkd3d_dxbc_compiler if (reg_component_count != 1) { ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, reg_info->storage_class, type_id); - index = vkd3d_dxbc_compiler_get_constant_uint(compiler, component_idx); + index = spirv_compiler_get_constant_uint(compiler, component_idx); reg_id = vkd3d_spirv_build_op_in_bounds_access_chain1(builder, ptr_type_id, reg_id, index); } @@ -3571,7 +3589,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_scalar(struct vkd3d_dxbc_compiler return val_id; } -static uint32_t vkd3d_dxbc_compiler_emit_load_reg(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -3582,19 +3600,19 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_reg(struct vkd3d_dxbc_compiler *co uint32_t type_id, val_id; if (reg->type == VKD3DSPR_IMMCONST) - return vkd3d_dxbc_compiler_emit_load_constant(compiler, reg, swizzle, write_mask); + return spirv_compiler_emit_load_constant(compiler, reg, swizzle, write_mask); else if (reg->type == VKD3DSPR_IMMCONST64) - return vkd3d_dxbc_compiler_emit_load_constant64(compiler, reg, swizzle, write_mask); + return spirv_compiler_emit_load_constant64(compiler, reg, swizzle, write_mask); component_count = vkd3d_write_mask_component_count(write_mask); component_type = vkd3d_component_type_from_data_type(reg->data_type); - if (!vkd3d_dxbc_compiler_get_register_info(compiler, reg, ®_info)) + if (!spirv_compiler_get_register_info(compiler, reg, ®_info)) { type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); return vkd3d_spirv_build_op_undef(builder, &builder->global_stream, type_id); } assert(reg_info.component_type != VKD3D_SHADER_COMPONENT_DOUBLE); - vkd3d_dxbc_compiler_emit_dereference_register(compiler, reg, ®_info); + spirv_compiler_emit_dereference_register(compiler, reg, ®_info); write_mask32 = (reg->data_type == VKD3D_DATA_DOUBLE) ? vkd3d_write_mask_32_from_64(write_mask) : write_mask; @@ -3605,7 +3623,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_reg(struct vkd3d_dxbc_compiler *co } else if (vkd3d_write_mask_component_count(write_mask32) == 1) { - return vkd3d_dxbc_compiler_emit_load_scalar(compiler, reg, swizzle, write_mask, ®_info); + return spirv_compiler_emit_load_scalar(compiler, reg, swizzle, write_mask, ®_info); } else { @@ -3614,7 +3632,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_reg(struct vkd3d_dxbc_compiler *co val_id = vkd3d_spirv_build_op_load(builder, type_id, reg_info.id, SpvMemoryAccessMaskNone); } - val_id = vkd3d_dxbc_compiler_emit_swizzle(compiler, + val_id = spirv_compiler_emit_swizzle(compiler, val_id, reg_info.write_mask, reg_info.component_type, swizzle, write_mask32); if (component_type != reg_info.component_type) @@ -3626,7 +3644,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_reg(struct vkd3d_dxbc_compiler *co return val_id; } -static void vkd3d_dxbc_compiler_emit_execution_mode(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_execution_mode(struct spirv_compiler *compiler, SpvExecutionMode mode, const uint32_t *literals, unsigned int literal_count) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -3635,19 +3653,19 @@ static void vkd3d_dxbc_compiler_emit_execution_mode(struct vkd3d_dxbc_compiler * builder->main_function_id, mode, literals, literal_count); } -static void vkd3d_dxbc_compiler_emit_execution_mode1(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_execution_mode1(struct spirv_compiler *compiler, SpvExecutionMode mode, const uint32_t literal) { - vkd3d_dxbc_compiler_emit_execution_mode(compiler, mode, &literal, 1); + spirv_compiler_emit_execution_mode(compiler, mode, &literal, 1); } -static uint32_t vkd3d_dxbc_compiler_emit_abs(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_abs(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, DWORD write_mask, uint32_t val_id) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id; - type_id = vkd3d_dxbc_compiler_get_type_id_for_reg(compiler, reg, write_mask); + type_id = spirv_compiler_get_type_id_for_reg(compiler, reg, write_mask); if (reg->data_type == VKD3D_DATA_FLOAT || reg->data_type == VKD3D_DATA_DOUBLE) return vkd3d_spirv_build_op_glsl_std450_fabs(builder, type_id, val_id); @@ -3655,13 +3673,13 @@ static uint32_t vkd3d_dxbc_compiler_emit_abs(struct vkd3d_dxbc_compiler *compile return val_id; } -static uint32_t vkd3d_dxbc_compiler_emit_neg(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_neg(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, DWORD write_mask, uint32_t val_id) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id; - type_id = vkd3d_dxbc_compiler_get_type_id_for_reg(compiler, reg, write_mask); + type_id = spirv_compiler_get_type_id_for_reg(compiler, reg, write_mask); if (reg->data_type == VKD3D_DATA_FLOAT || reg->data_type == VKD3D_DATA_DOUBLE) return vkd3d_spirv_build_op_fnegate(builder, type_id, val_id); else if (reg->data_type == VKD3D_DATA_INT) @@ -3671,7 +3689,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_neg(struct vkd3d_dxbc_compiler *compile return val_id; } -static uint32_t vkd3d_dxbc_compiler_emit_src_modifier(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_src_modifier(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, DWORD write_mask, enum vkd3d_shader_src_modifier modifier, uint32_t val_id) { @@ -3680,12 +3698,12 @@ static uint32_t vkd3d_dxbc_compiler_emit_src_modifier(struct vkd3d_dxbc_compiler case VKD3DSPSM_NONE: break; case VKD3DSPSM_NEG: - return vkd3d_dxbc_compiler_emit_neg(compiler, reg, write_mask, val_id); + return spirv_compiler_emit_neg(compiler, reg, write_mask, val_id); case VKD3DSPSM_ABS: - return vkd3d_dxbc_compiler_emit_abs(compiler, reg, write_mask, val_id); + return spirv_compiler_emit_abs(compiler, reg, write_mask, val_id); case VKD3DSPSM_ABSNEG: - val_id = vkd3d_dxbc_compiler_emit_abs(compiler, reg, write_mask, val_id); - return vkd3d_dxbc_compiler_emit_neg(compiler, reg, write_mask, val_id); + val_id = spirv_compiler_emit_abs(compiler, reg, write_mask, val_id); + return spirv_compiler_emit_neg(compiler, reg, write_mask, val_id); default: FIXME("Unhandled src modifier %#x.\n", modifier); break; @@ -3694,25 +3712,25 @@ static uint32_t vkd3d_dxbc_compiler_emit_src_modifier(struct vkd3d_dxbc_compiler return val_id; } -static uint32_t vkd3d_dxbc_compiler_emit_load_src(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_load_src(struct spirv_compiler *compiler, const struct vkd3d_shader_src_param *src, DWORD write_mask) { uint32_t val_id; - val_id = vkd3d_dxbc_compiler_emit_load_reg(compiler, &src->reg, src->swizzle, write_mask); - return vkd3d_dxbc_compiler_emit_src_modifier(compiler, &src->reg, write_mask, src->modifiers, val_id); + val_id = spirv_compiler_emit_load_reg(compiler, &src->reg, src->swizzle, write_mask); + return spirv_compiler_emit_src_modifier(compiler, &src->reg, write_mask, src->modifiers, val_id); } -static uint32_t vkd3d_dxbc_compiler_emit_load_src_with_type(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_load_src_with_type(struct spirv_compiler *compiler, const struct vkd3d_shader_src_param *src, DWORD write_mask, enum vkd3d_shader_component_type component_type) { struct vkd3d_shader_src_param src_param = *src; src_param.reg.data_type = vkd3d_data_type_from_component_type(component_type); - return vkd3d_dxbc_compiler_emit_load_src(compiler, &src_param, write_mask); + return spirv_compiler_emit_load_src(compiler, &src_param, write_mask); } -static void vkd3d_dxbc_compiler_emit_store_scalar(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_store_scalar(struct spirv_compiler *compiler, uint32_t dst_id, unsigned int dst_write_mask, enum vkd3d_shader_component_type component_type, SpvStorageClass storage_class, unsigned int write_mask, uint32_t val_id) { @@ -3726,14 +3744,14 @@ static void vkd3d_dxbc_compiler_emit_store_scalar(struct vkd3d_dxbc_compiler *co ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, type_id); component_idx = vkd3d_write_mask_get_component_idx(write_mask); component_idx -= vkd3d_write_mask_get_component_idx(dst_write_mask); - index = vkd3d_dxbc_compiler_get_constant_uint(compiler, component_idx); + index = spirv_compiler_get_constant_uint(compiler, component_idx); dst_id = vkd3d_spirv_build_op_in_bounds_access_chain1(builder, ptr_type_id, dst_id, index); } vkd3d_spirv_build_op_store(builder, dst_id, val_id, SpvMemoryAccessMaskNone); } -static void vkd3d_dxbc_compiler_emit_store(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_store(struct spirv_compiler *compiler, uint32_t dst_id, unsigned int dst_write_mask, enum vkd3d_shader_component_type component_type, SpvStorageClass storage_class, unsigned int write_mask, uint32_t val_id) { @@ -3759,7 +3777,7 @@ static void vkd3d_dxbc_compiler_emit_store(struct vkd3d_dxbc_compiler *compiler, if (component_count == 1) { - return vkd3d_dxbc_compiler_emit_store_scalar(compiler, + return spirv_compiler_emit_store_scalar(compiler, dst_id, dst_write_mask, component_type, storage_class, write_mask, val_id); } @@ -3788,7 +3806,7 @@ static void vkd3d_dxbc_compiler_emit_store(struct vkd3d_dxbc_compiler *compiler, vkd3d_spirv_build_op_store(builder, dst_id, val_id, SpvMemoryAccessMaskNone); } -static void vkd3d_dxbc_compiler_emit_store_reg(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, unsigned int write_mask, uint32_t val_id) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -3799,9 +3817,9 @@ static void vkd3d_dxbc_compiler_emit_store_reg(struct vkd3d_dxbc_compiler *compi assert(reg->type != VKD3DSPR_IMMCONST && reg->type != VKD3DSPR_IMMCONST64); - if (!vkd3d_dxbc_compiler_get_register_info(compiler, reg, ®_info)) + if (!spirv_compiler_get_register_info(compiler, reg, ®_info)) return; - vkd3d_dxbc_compiler_emit_dereference_register(compiler, reg, ®_info); + spirv_compiler_emit_dereference_register(compiler, reg, ®_info); component_type = vkd3d_component_type_from_data_type(reg->data_type); if (component_type != reg_info.component_type) @@ -3814,11 +3832,11 @@ static void vkd3d_dxbc_compiler_emit_store_reg(struct vkd3d_dxbc_compiler *compi component_type = reg_info.component_type; } - vkd3d_dxbc_compiler_emit_store(compiler, + spirv_compiler_emit_store(compiler, reg_info.id, reg_info.write_mask, component_type, reg_info.storage_class, src_write_mask, val_id); } -static uint32_t vkd3d_dxbc_compiler_emit_sat(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_sat(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, DWORD write_mask, uint32_t val_id) { unsigned int component_count = vkd3d_write_mask_component_count(write_mask); @@ -3827,16 +3845,16 @@ static uint32_t vkd3d_dxbc_compiler_emit_sat(struct vkd3d_dxbc_compiler *compile if (reg->data_type == VKD3D_DATA_DOUBLE) { - zero_id = vkd3d_dxbc_compiler_get_constant_double_vector(compiler, 0.0, component_count); - one_id = vkd3d_dxbc_compiler_get_constant_double_vector(compiler, 1.0, component_count); + zero_id = spirv_compiler_get_constant_double_vector(compiler, 0.0, component_count); + one_id = spirv_compiler_get_constant_double_vector(compiler, 1.0, component_count); } else { - zero_id = vkd3d_dxbc_compiler_get_constant_float_vector(compiler, 0.0f, component_count); - one_id = vkd3d_dxbc_compiler_get_constant_float_vector(compiler, 1.0f, component_count); + zero_id = spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count); + one_id = spirv_compiler_get_constant_float_vector(compiler, 1.0f, component_count); } - type_id = vkd3d_dxbc_compiler_get_type_id_for_reg(compiler, reg, write_mask); + type_id = spirv_compiler_get_type_id_for_reg(compiler, reg, write_mask); if (reg->data_type == VKD3D_DATA_FLOAT || reg->data_type == VKD3D_DATA_DOUBLE) return vkd3d_spirv_build_op_glsl_std450_nclamp(builder, type_id, val_id, zero_id, one_id); @@ -3844,31 +3862,31 @@ static uint32_t vkd3d_dxbc_compiler_emit_sat(struct vkd3d_dxbc_compiler *compile return val_id; } -static void vkd3d_dxbc_compiler_emit_store_dst(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_store_dst(struct spirv_compiler *compiler, const struct vkd3d_shader_dst_param *dst, uint32_t val_id) { assert(!(dst->modifiers & ~VKD3DSPDM_SATURATE)); if (dst->modifiers & VKD3DSPDM_SATURATE) - val_id = vkd3d_dxbc_compiler_emit_sat(compiler, &dst->reg, dst->write_mask, val_id); + val_id = spirv_compiler_emit_sat(compiler, &dst->reg, dst->write_mask, val_id); - vkd3d_dxbc_compiler_emit_store_reg(compiler, &dst->reg, dst->write_mask, val_id); + spirv_compiler_emit_store_reg(compiler, &dst->reg, dst->write_mask, val_id); } -static void vkd3d_dxbc_compiler_emit_store_dst_swizzled(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_store_dst_swizzled(struct spirv_compiler *compiler, const struct vkd3d_shader_dst_param *dst, uint32_t val_id, enum vkd3d_shader_component_type component_type, DWORD swizzle) { struct vkd3d_shader_dst_param typed_dst = *dst; - val_id = vkd3d_dxbc_compiler_emit_swizzle(compiler, + val_id = spirv_compiler_emit_swizzle(compiler, val_id, VKD3DSP_WRITEMASK_ALL, component_type, swizzle, dst->write_mask); /* XXX: The register data type could be fixed by the shader parser. For SM5 * shaders the data types are stored in instructions modifiers. */ typed_dst.reg.data_type = vkd3d_data_type_from_component_type(component_type); - vkd3d_dxbc_compiler_emit_store_dst(compiler, &typed_dst, val_id); + spirv_compiler_emit_store_dst(compiler, &typed_dst, val_id); } -static void vkd3d_dxbc_compiler_emit_store_dst_components(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_store_dst_components(struct spirv_compiler *compiler, const struct vkd3d_shader_dst_param *dst, enum vkd3d_shader_component_type component_type, uint32_t *component_ids) { @@ -3886,10 +3904,10 @@ static void vkd3d_dxbc_compiler_emit_store_dst_components(struct vkd3d_dxbc_comp { val_id = *component_ids; } - vkd3d_dxbc_compiler_emit_store_dst(compiler, dst, val_id); + spirv_compiler_emit_store_dst(compiler, dst, val_id); } -static void vkd3d_dxbc_compiler_emit_store_dst_scalar(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_store_dst_scalar(struct spirv_compiler *compiler, const struct vkd3d_shader_dst_param *dst, uint32_t val_id, enum vkd3d_shader_component_type component_type, DWORD swizzle) { @@ -3905,10 +3923,10 @@ static void vkd3d_dxbc_compiler_emit_store_dst_scalar(struct vkd3d_dxbc_compiler component_ids[i] = val_id; } - vkd3d_dxbc_compiler_emit_store_dst_components(compiler, dst, component_type, component_ids); + spirv_compiler_emit_store_dst_components(compiler, dst, component_type, component_ids); } -static void vkd3d_dxbc_compiler_decorate_builtin(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_decorate_builtin(struct spirv_compiler *compiler, uint32_t target_id, SpvBuiltIn builtin) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -3920,7 +3938,7 @@ static void vkd3d_dxbc_compiler_decorate_builtin(struct vkd3d_dxbc_compiler *com vkd3d_spirv_enable_capability(builder, SpvCapabilityGeometry); break; case SpvBuiltInFragDepth: - vkd3d_dxbc_compiler_emit_execution_mode(compiler, SpvExecutionModeDepthReplacing, NULL, 0); + spirv_compiler_emit_execution_mode(compiler, SpvExecutionModeDepthReplacing, NULL, 0); break; case SpvBuiltInLayer: vkd3d_spirv_enable_capability(builder, SpvCapabilityGeometry); @@ -3944,7 +3962,7 @@ static void vkd3d_dxbc_compiler_decorate_builtin(struct vkd3d_dxbc_compiler *com vkd3d_spirv_build_op_decorate1(builder, target_id, SpvDecorationBuiltIn, builtin); } -static void vkd3d_dxbc_compiler_emit_interpolation_decorations(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_interpolation_decorations(struct spirv_compiler *compiler, uint32_t id, enum vkd3d_shader_interpolation_mode mode) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -3974,7 +3992,7 @@ static void vkd3d_dxbc_compiler_emit_interpolation_decorations(struct vkd3d_dxbc } } -static uint32_t vkd3d_dxbc_compiler_emit_int_to_bool(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, enum vkd3d_shader_conditional_op condition, unsigned int component_count, uint32_t val_id) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -3986,25 +4004,25 @@ static uint32_t vkd3d_dxbc_compiler_emit_int_to_bool(struct vkd3d_dxbc_compiler type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); op = condition & VKD3D_SHADER_CONDITIONAL_OP_Z ? SpvOpIEqual : SpvOpINotEqual; return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, val_id, - vkd3d_dxbc_compiler_get_constant_uint_vector(compiler, 0, component_count)); + spirv_compiler_get_constant_uint_vector(compiler, 0, component_count)); } -static uint32_t vkd3d_dxbc_compiler_emit_bool_to_int(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_bool_to_int(struct spirv_compiler *compiler, unsigned int component_count, uint32_t val_id) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id, true_id, false_id; - true_id = vkd3d_dxbc_compiler_get_constant_uint_vector(compiler, 0xffffffff, component_count); - false_id = vkd3d_dxbc_compiler_get_constant_uint_vector(compiler, 0, component_count); + true_id = spirv_compiler_get_constant_uint_vector(compiler, 0xffffffff, component_count); + false_id = spirv_compiler_get_constant_uint_vector(compiler, 0, component_count); type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, component_count); return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); } -typedef uint32_t (*vkd3d_spirv_builtin_fixup_pfn)(struct vkd3d_dxbc_compiler *compiler, +typedef uint32_t (*vkd3d_spirv_builtin_fixup_pfn)(struct spirv_compiler *compiler, uint32_t val_id); -static uint32_t vkd3d_dxbc_compiler_emit_draw_parameter_fixup(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_draw_parameter_fixup(struct spirv_compiler *compiler, uint32_t index_id, SpvBuiltIn base) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -4012,10 +4030,10 @@ static uint32_t vkd3d_dxbc_compiler_emit_draw_parameter_fixup(struct vkd3d_dxbc_ vkd3d_spirv_enable_capability(builder, SpvCapabilityDrawParameters); - base_var_id = vkd3d_dxbc_compiler_emit_variable(compiler, &builder->global_stream, + base_var_id = spirv_compiler_emit_variable(compiler, &builder->global_stream, SpvStorageClassInput, VKD3D_SHADER_COMPONENT_INT, 1); vkd3d_spirv_add_iface_variable(builder, base_var_id); - vkd3d_dxbc_compiler_decorate_builtin(compiler, base_var_id, base); + spirv_compiler_decorate_builtin(compiler, base_var_id, base); type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_INT, 1); base_id = vkd3d_spirv_build_op_load(builder, @@ -4025,29 +4043,29 @@ static uint32_t vkd3d_dxbc_compiler_emit_draw_parameter_fixup(struct vkd3d_dxbc_ } /* Substitute "VertexIndex - BaseVertex" for SV_VertexID. */ -static uint32_t sv_vertex_id_fixup(struct vkd3d_dxbc_compiler *compiler, +static uint32_t sv_vertex_id_fixup(struct spirv_compiler *compiler, uint32_t vertex_index_id) { - return vkd3d_dxbc_compiler_emit_draw_parameter_fixup(compiler, + return spirv_compiler_emit_draw_parameter_fixup(compiler, vertex_index_id, SpvBuiltInBaseVertex); } /* Substitute "InstanceIndex - BaseInstance" for SV_InstanceID. */ -static uint32_t sv_instance_id_fixup(struct vkd3d_dxbc_compiler *compiler, +static uint32_t sv_instance_id_fixup(struct spirv_compiler *compiler, uint32_t instance_index_id) { - return vkd3d_dxbc_compiler_emit_draw_parameter_fixup(compiler, + return spirv_compiler_emit_draw_parameter_fixup(compiler, instance_index_id, SpvBuiltInBaseInstance); } -static uint32_t sv_front_face_fixup(struct vkd3d_dxbc_compiler *compiler, +static uint32_t sv_front_face_fixup(struct spirv_compiler *compiler, uint32_t front_facing_id) { - return vkd3d_dxbc_compiler_emit_bool_to_int(compiler, 1, front_facing_id); + return spirv_compiler_emit_bool_to_int(compiler, 1, front_facing_id); } /* frag_coord.w = 1.0f / frag_coord.w */ -static uint32_t frag_coord_fixup(struct vkd3d_dxbc_compiler *compiler, +static uint32_t frag_coord_fixup(struct spirv_compiler *compiler, uint32_t frag_coord_id) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -4056,7 +4074,7 @@ static uint32_t frag_coord_fixup(struct vkd3d_dxbc_compiler *compiler, type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 1); w_id = vkd3d_spirv_build_op_composite_extract1(builder, type_id, frag_coord_id, 3); w_id = vkd3d_spirv_build_op_fdiv(builder, type_id, - vkd3d_dxbc_compiler_get_constant_float(compiler, 1.0f), w_id); + spirv_compiler_get_constant_float(compiler, 1.0f), w_id); type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); return vkd3d_spirv_build_op_composite_insert1(builder, type_id, w_id, frag_coord_id, 3); } @@ -4152,28 +4170,28 @@ vkd3d_register_builtins[] = {VKD3DSPR_OUTSTENCILREF, {VKD3D_SHADER_COMPONENT_UINT, 1, SpvBuiltInFragStencilRefEXT}}, }; -static void vkd3d_dxbc_compiler_emit_register_execution_mode(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_register_execution_mode(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg) { switch (reg->type) { case VKD3DSPR_DEPTHOUTGE: - vkd3d_dxbc_compiler_emit_execution_mode(compiler, SpvExecutionModeDepthGreater, NULL, 0); + spirv_compiler_emit_execution_mode(compiler, SpvExecutionModeDepthGreater, NULL, 0); break; case VKD3DSPR_DEPTHOUTLE: - vkd3d_dxbc_compiler_emit_execution_mode(compiler, SpvExecutionModeDepthLess, NULL, 0); + spirv_compiler_emit_execution_mode(compiler, SpvExecutionModeDepthLess, NULL, 0); break; case VKD3DSPR_OUTSTENCILREF: - if (!vkd3d_dxbc_compiler_is_target_extension_supported(compiler, + if (!spirv_compiler_is_target_extension_supported(compiler, VKD3D_SHADER_SPIRV_EXTENSION_EXT_STENCIL_EXPORT)) { FIXME("The target environment does not support stencil export.\n"); - vkd3d_dxbc_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_STENCIL_EXPORT_UNSUPPORTED, + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_STENCIL_EXPORT_UNSUPPORTED, "Cannot export stencil reference value for register id %u. " "The target environment does not support stencil export.", reg->idx[0].offset); } vkd3d_spirv_enable_capability(&compiler->spirv_builder, SpvCapabilityStencilExportEXT); - vkd3d_dxbc_compiler_emit_execution_mode(compiler, SpvExecutionModeStencilRefReplacingEXT, NULL, 0); + spirv_compiler_emit_execution_mode(compiler, SpvExecutionModeStencilRefReplacingEXT, NULL, 0); break; default: return; @@ -4181,7 +4199,7 @@ static void vkd3d_dxbc_compiler_emit_register_execution_mode(struct vkd3d_dxbc_c } static const struct vkd3d_spirv_builtin *get_spirv_builtin_for_sysval( - const struct vkd3d_dxbc_compiler *compiler, enum vkd3d_shader_input_sysval_semantic sysval) + const struct spirv_compiler *compiler, enum vkd3d_shader_input_sysval_semantic sysval) { enum vkd3d_shader_spirv_environment environment; unsigned int i; @@ -4193,7 +4211,7 @@ static const struct vkd3d_spirv_builtin *get_spirv_builtin_for_sysval( if (sysval == VKD3D_SIV_POSITION && compiler->shader_type == VKD3D_SHADER_TYPE_PIXEL) return &vkd3d_pixel_shader_position_builtin; - environment = vkd3d_dxbc_compiler_get_target_environment(compiler); + environment = spirv_compiler_get_target_environment(compiler); for (i = 0; i < ARRAY_SIZE(vkd3d_system_value_builtins); ++i) { if (vkd3d_system_value_builtins[i].sysval == sysval @@ -4221,7 +4239,7 @@ static const struct vkd3d_spirv_builtin *get_spirv_builtin_for_register( return NULL; } -static const struct vkd3d_spirv_builtin *vkd3d_get_spirv_builtin(const struct vkd3d_dxbc_compiler *compiler, +static const struct vkd3d_spirv_builtin *vkd3d_get_spirv_builtin(const struct spirv_compiler *compiler, enum vkd3d_shader_register_type reg_type, enum vkd3d_shader_input_sysval_semantic sysval) { const struct vkd3d_spirv_builtin *builtin; @@ -4260,7 +4278,7 @@ static const struct vkd3d_shader_signature_element *vkd3d_find_signature_element return NULL; } -static uint32_t vkd3d_dxbc_compiler_get_invocation_id(struct vkd3d_dxbc_compiler *compiler) +static uint32_t spirv_compiler_get_invocation_id(struct spirv_compiler *compiler) { struct vkd3d_shader_register r; @@ -4270,20 +4288,20 @@ static uint32_t vkd3d_dxbc_compiler_get_invocation_id(struct vkd3d_dxbc_compiler r.type = VKD3DSPR_OUTPOINTID; r.idx[0].offset = ~0u; r.idx[1].offset = ~0u; - return vkd3d_dxbc_compiler_get_register_id(compiler, &r); + return spirv_compiler_get_register_id(compiler, &r); } -static uint32_t vkd3d_dxbc_compiler_emit_load_invocation_id(struct vkd3d_dxbc_compiler *compiler) +static uint32_t spirv_compiler_emit_load_invocation_id(struct spirv_compiler *compiler) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id, id; - id = vkd3d_dxbc_compiler_get_invocation_id(compiler); + id = spirv_compiler_get_invocation_id(compiler); type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_INT, 1); return vkd3d_spirv_build_op_load(builder, type_id, id, SpvMemoryAccessMaskNone); } -static void vkd3d_dxbc_compiler_emit_shader_phase_name(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_shader_phase_name(struct spirv_compiler *compiler, uint32_t id, const struct vkd3d_shader_phase *phase, const char *suffix) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -4310,7 +4328,7 @@ static void vkd3d_dxbc_compiler_emit_shader_phase_name(struct vkd3d_dxbc_compile vkd3d_spirv_build_op_name(builder, id, "%s%u%s", name, phase->idx, suffix); } -static void vkd3d_dxbc_compiler_begin_shader_phase(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_begin_shader_phase(struct spirv_compiler *compiler, struct vkd3d_shader_phase *phase) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -4341,11 +4359,11 @@ static void vkd3d_dxbc_compiler_begin_shader_phase(struct vkd3d_dxbc_compiler *c vkd3d_spirv_build_op_label(builder, vkd3d_spirv_alloc_id(builder)); phase->function_location = vkd3d_spirv_stream_current_location(&builder->function_stream); - vkd3d_dxbc_compiler_emit_shader_phase_name(compiler, phase->function_id, phase, NULL); + spirv_compiler_emit_shader_phase_name(compiler, phase->function_id, phase, NULL); } -static const struct vkd3d_shader_phase *vkd3d_dxbc_compiler_get_current_shader_phase( - struct vkd3d_dxbc_compiler *compiler) +static const struct vkd3d_shader_phase *spirv_compiler_get_current_shader_phase( + struct spirv_compiler *compiler) { struct vkd3d_shader_phase *phase; @@ -4354,11 +4372,11 @@ static const struct vkd3d_shader_phase *vkd3d_dxbc_compiler_get_current_shader_p phase = &compiler->shader_phases[compiler->shader_phase_count - 1]; if (!phase->function_id) - vkd3d_dxbc_compiler_begin_shader_phase(compiler, phase); + spirv_compiler_begin_shader_phase(compiler, phase); return phase; } -static void vkd3d_dxbc_compiler_decorate_xfb_output(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_decorate_xfb_output(struct spirv_compiler *compiler, uint32_t id, unsigned int component_count, const struct vkd3d_shader_signature_element *signature_element) { const struct vkd3d_shader_transform_feedback_info *xfb_info = compiler->xfb_info; @@ -4418,7 +4436,7 @@ static void vkd3d_dxbc_compiler_decorate_xfb_output(struct vkd3d_dxbc_compiler * vkd3d_spirv_build_op_decorate1(builder, id, SpvDecorationOffset, offset); } -static uint32_t vkd3d_dxbc_compiler_emit_builtin_variable(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_builtin_variable(struct spirv_compiler *compiler, const struct vkd3d_spirv_builtin *builtin, SpvStorageClass storage_class, unsigned int array_size) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -4426,11 +4444,11 @@ static uint32_t vkd3d_dxbc_compiler_emit_builtin_variable(struct vkd3d_dxbc_comp array_size = max(array_size, builtin->spirv_array_size); - id = vkd3d_dxbc_compiler_emit_array_variable(compiler, + id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream, storage_class, builtin->component_type, builtin->component_count, array_size); vkd3d_spirv_add_iface_variable(builder, id); - vkd3d_dxbc_compiler_decorate_builtin(compiler, id, builtin->spirv_builtin); + spirv_compiler_decorate_builtin(compiler, id, builtin->spirv_builtin); if (compiler->shader_type == VKD3D_SHADER_TYPE_PIXEL && storage_class == SpvStorageClassInput && builtin->component_type != VKD3D_SHADER_COMPONENT_FLOAT @@ -4490,7 +4508,7 @@ static bool needs_private_io_variable(const struct vkd3d_shader_signature *signa return false; } -static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, const struct vkd3d_shader_dst_param *dst, enum vkd3d_shader_input_sysval_semantic sysval, enum vkd3d_shader_interpolation_mode interpolation_mode) { @@ -4507,7 +4525,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi struct vkd3d_symbol reg_symbol; struct vkd3d_symbol tmp_symbol; SpvStorageClass storage_class; - struct wine_rb_entry *entry = NULL; + struct rb_entry *entry = NULL; bool use_private_var = false; unsigned int write_mask; unsigned int array_size; @@ -4569,9 +4587,9 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi vkd3d_symbol_make_register(®_symbol, reg); - if ((entry = wine_rb_get(&compiler->symbol_table, ®_symbol))) + if ((entry = rb_get(&compiler->symbol_table, ®_symbol))) { - symbol = WINE_RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); + symbol = RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); input_id = symbol->id; } else if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL @@ -4589,7 +4607,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi * * We handle "vicp" and "vpc" here by creating aliases to the shader's * global inputs and outputs. We handle "vocp" in - * vkd3d_dxbc_compiler_leave_shader_phase(). */ + * spirv_compiler_leave_shader_phase(). */ tmp_symbol = reg_symbol; if (reg->type == VKD3DSPR_PATCHCONST) @@ -4597,12 +4615,12 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi else tmp_symbol.key.reg.type = VKD3DSPR_INPUT; - if ((entry = wine_rb_get(&compiler->symbol_table, &tmp_symbol))) + if ((entry = rb_get(&compiler->symbol_table, &tmp_symbol))) { - symbol = WINE_RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); + symbol = RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); tmp_symbol = *symbol; tmp_symbol.key.reg.type = reg->type; - vkd3d_dxbc_compiler_put_symbol(compiler, &tmp_symbol); + spirv_compiler_put_symbol(compiler, &tmp_symbol); input_id = symbol->id; } @@ -4619,7 +4637,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi { if (builtin) { - input_id = vkd3d_dxbc_compiler_emit_builtin_variable(compiler, builtin, storage_class, array_size); + input_id = spirv_compiler_emit_builtin_variable(compiler, builtin, storage_class, array_size); if (reg->type == VKD3DSPR_PATCHCONST) vkd3d_spirv_build_op_decorate(builder, input_id, SpvDecorationPatch, NULL, 0); } @@ -4627,7 +4645,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi { unsigned int location = reg_idx; - input_id = vkd3d_dxbc_compiler_emit_array_variable(compiler, &builder->global_stream, + input_id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream, storage_class, component_type, input_component_count, array_size); vkd3d_spirv_add_iface_variable(builder, input_id); if (reg->type == VKD3DSPR_PATCHCONST) @@ -4639,7 +4657,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi if (component_idx) vkd3d_spirv_build_op_decorate1(builder, input_id, SpvDecorationComponent, component_idx); - vkd3d_dxbc_compiler_emit_interpolation_decorations(compiler, input_id, interpolation_mode); + spirv_compiler_emit_interpolation_decorations(compiler, input_id, interpolation_mode); } } @@ -4649,7 +4667,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi if (use_private_var) { storage_class = SpvStorageClassPrivate; - var_id = vkd3d_dxbc_compiler_emit_array_variable(compiler, &builder->global_stream, + var_id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream, storage_class, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE, array_size); } @@ -4657,9 +4675,9 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi use_private_var ? VKD3D_SHADER_COMPONENT_FLOAT : component_type, use_private_var ? VKD3DSP_WRITEMASK_ALL : write_mask); reg_symbol.info.reg.dcl_mask |= write_mask; - vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol); + spirv_compiler_put_symbol(compiler, ®_symbol); - vkd3d_dxbc_compiler_emit_register_debug_name(builder, var_id, reg); + spirv_compiler_emit_register_debug_name(builder, var_id, reg); } else { @@ -4678,7 +4696,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi if (array_size) { ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassInput, type_id); - index = vkd3d_dxbc_compiler_get_constant_uint(compiler, i); + index = spirv_compiler_get_constant_uint(compiler, i); val_id = vkd3d_spirv_build_op_in_bounds_access_chain1(builder, ptr_type_id, input_id, index); dst_reg.idx[0].offset = i; } @@ -4688,7 +4706,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi * so we'll need to index into the SPIR-V builtin when loading * it. This happens when reading TessLevel in domain shaders. */ ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassInput, type_id); - index = vkd3d_dxbc_compiler_get_constant_uint(compiler, builtin->member_idx); + index = spirv_compiler_get_constant_uint(compiler, builtin->member_idx); val_id = vkd3d_spirv_build_op_in_bounds_access_chain1(builder, ptr_type_id, input_id, index); dst_reg.idx[0].offset = reg_idx + i; } @@ -4703,25 +4721,25 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi val_id = vkd3d_spirv_build_op_bitcast(builder, float_type_id, val_id); } - val_id = vkd3d_dxbc_compiler_emit_swizzle(compiler, val_id, + val_id = spirv_compiler_emit_swizzle(compiler, val_id, vkd3d_write_mask_from_component_count(input_component_count), VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_SHADER_NO_SWIZZLE, dst->write_mask >> component_idx); - vkd3d_dxbc_compiler_emit_store_reg(compiler, &dst_reg, dst->write_mask, val_id); + spirv_compiler_emit_store_reg(compiler, &dst_reg, dst->write_mask, val_id); } } return input_id; } -static void vkd3d_dxbc_compiler_emit_input_register(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_input_register(struct spirv_compiler *compiler, const struct vkd3d_shader_dst_param *dst) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; const struct vkd3d_shader_register *reg = &dst->reg; const struct vkd3d_spirv_builtin *builtin; struct vkd3d_symbol reg_symbol; - struct wine_rb_entry *entry; + struct rb_entry *entry; uint32_t write_mask; uint32_t input_id; @@ -4737,21 +4755,21 @@ static void vkd3d_dxbc_compiler_emit_input_register(struct vkd3d_dxbc_compiler * /* vPrim may be declared in multiple hull shader phases. */ vkd3d_symbol_make_register(®_symbol, reg); - if ((entry = wine_rb_get(&compiler->symbol_table, ®_symbol))) + if ((entry = rb_get(&compiler->symbol_table, ®_symbol))) return; - input_id = vkd3d_dxbc_compiler_emit_builtin_variable(compiler, builtin, SpvStorageClassInput, 0); + input_id = spirv_compiler_emit_builtin_variable(compiler, builtin, SpvStorageClassInput, 0); write_mask = vkd3d_write_mask_from_component_count(builtin->component_count); vkd3d_symbol_set_register_info(®_symbol, input_id, SpvStorageClassInput, builtin->component_type, write_mask); reg_symbol.info.reg.dcl_mask = write_mask; reg_symbol.info.reg.is_aggregate = builtin->spirv_array_size; - vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol); - vkd3d_dxbc_compiler_emit_register_debug_name(builder, input_id, reg); + spirv_compiler_put_symbol(compiler, ®_symbol); + spirv_compiler_emit_register_debug_name(builder, input_id, reg); } -static void vkd3d_dxbc_compiler_emit_shader_phase_input(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_shader_phase_input(struct spirv_compiler *compiler, const struct vkd3d_shader_phase *phase, const struct vkd3d_shader_dst_param *dst) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -4764,17 +4782,17 @@ static void vkd3d_dxbc_compiler_emit_shader_phase_input(struct vkd3d_dxbc_compil case VKD3DSPR_INPUT: case VKD3DSPR_INCONTROLPOINT: case VKD3DSPR_PATCHCONST: - vkd3d_dxbc_compiler_emit_input(compiler, dst, VKD3D_SIV_NONE, VKD3DSIM_NONE); + spirv_compiler_emit_input(compiler, dst, VKD3D_SIV_NONE, VKD3DSIM_NONE); return; case VKD3DSPR_PRIMID: - vkd3d_dxbc_compiler_emit_input_register(compiler, dst); + spirv_compiler_emit_input_register(compiler, dst); return; case VKD3DSPR_FORKINSTID: case VKD3DSPR_JOININSTID: val_id = phase->instance_id; break; - case VKD3DSPR_OUTPOINTID: /* Emitted in vkd3d_dxbc_compiler_emit_initial_declarations(). */ - case VKD3DSPR_OUTCONTROLPOINT: /* See vkd3d_dxbc_compiler_leave_shader_phase(). */ + case VKD3DSPR_OUTPOINTID: /* Emitted in spirv_compiler_emit_initial_declarations(). */ + case VKD3DSPR_OUTCONTROLPOINT: /* See spirv_compiler_leave_shader_phase(). */ return; default: FIXME("Unhandled shader phase input register %#x.\n", reg->type); @@ -4785,12 +4803,12 @@ static void vkd3d_dxbc_compiler_emit_shader_phase_input(struct vkd3d_dxbc_compil vkd3d_symbol_set_register_info(®_symbol, val_id, SpvStorageClassMax /* Intermediate value */, VKD3D_SHADER_COMPONENT_UINT, VKD3DSP_WRITEMASK_0); - vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol); - vkd3d_dxbc_compiler_emit_register_debug_name(builder, val_id, reg); + spirv_compiler_put_symbol(compiler, ®_symbol); + spirv_compiler_emit_register_debug_name(builder, val_id, reg); } -static unsigned int vkd3d_dxbc_compiler_get_output_variable_index( - struct vkd3d_dxbc_compiler *compiler, unsigned int register_idx) +static unsigned int spirv_compiler_get_output_variable_index( + struct spirv_compiler *compiler, unsigned int register_idx) { if (register_idx == ~0u) /* oDepth */ return ARRAY_SIZE(compiler->private_output_variable) - 1; @@ -4798,7 +4816,7 @@ static unsigned int vkd3d_dxbc_compiler_get_output_variable_index( return register_idx; } -static unsigned int get_shader_output_swizzle(const struct vkd3d_dxbc_compiler *compiler, +static unsigned int get_shader_output_swizzle(const struct spirv_compiler *compiler, unsigned int register_idx) { const struct vkd3d_shader_spirv_target_info *info; @@ -4810,7 +4828,7 @@ static unsigned int get_shader_output_swizzle(const struct vkd3d_dxbc_compiler * return info->output_swizzles[register_idx]; } -static bool is_dual_source_blending(const struct vkd3d_dxbc_compiler *compiler) +static bool is_dual_source_blending(const struct spirv_compiler *compiler) { const struct vkd3d_shader_spirv_target_info *info = compiler->spirv_target_info; @@ -4829,7 +4847,7 @@ static void calculate_clip_or_cull_distance_mask(const struct vkd3d_shader_signa *mask |= (e->mask & VKD3DSP_WRITEMASK_ALL) << (VKD3D_VEC4_SIZE * e->semantic_index); } -static uint32_t calculate_sysval_array_mask(struct vkd3d_dxbc_compiler *compiler, +static uint32_t calculate_sysval_array_mask(struct spirv_compiler *compiler, const struct vkd3d_shader_signature *signature, enum vkd3d_shader_input_sysval_semantic sysval) { const struct vkd3d_shader_signature_element *e; @@ -4858,7 +4876,7 @@ static uint32_t calculate_sysval_array_mask(struct vkd3d_dxbc_compiler *compiler } /* Emits arrayed SPIR-V built-in variables. */ -static void vkd3d_dxbc_compiler_emit_shader_signature_outputs(struct vkd3d_dxbc_compiler *compiler) +static void spirv_compiler_emit_shader_signature_outputs(struct spirv_compiler *compiler) { const struct vkd3d_shader_signature *output_signature = compiler->output_signature; uint32_t clip_distance_mask = 0, clip_distance_id = 0; @@ -4889,7 +4907,7 @@ static void vkd3d_dxbc_compiler_emit_shader_signature_outputs(struct vkd3d_dxbc_ { count = vkd3d_popcount(clip_distance_mask); builtin = get_spirv_builtin_for_sysval(compiler, VKD3D_SIV_CLIP_DISTANCE); - clip_distance_id = vkd3d_dxbc_compiler_emit_builtin_variable(compiler, + clip_distance_id = spirv_compiler_emit_builtin_variable(compiler, builtin, SpvStorageClassOutput, count); } @@ -4897,7 +4915,7 @@ static void vkd3d_dxbc_compiler_emit_shader_signature_outputs(struct vkd3d_dxbc_ { count = vkd3d_popcount(cull_distance_mask); builtin = get_spirv_builtin_for_sysval(compiler, VKD3D_SIV_CULL_DISTANCE); - cull_distance_id = vkd3d_dxbc_compiler_emit_builtin_variable(compiler, + cull_distance_id = spirv_compiler_emit_builtin_variable(compiler, builtin, SpvStorageClassOutput, count); } @@ -4925,7 +4943,7 @@ static void vkd3d_dxbc_compiler_emit_shader_signature_outputs(struct vkd3d_dxbc_ } } -static void vkd3d_dxbc_compiler_emit_output_register(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_output_register(struct spirv_compiler *compiler, const struct vkd3d_shader_dst_param *dst) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -4945,7 +4963,7 @@ static void vkd3d_dxbc_compiler_emit_output_register(struct vkd3d_dxbc_compiler return; } - output_id = vkd3d_dxbc_compiler_emit_builtin_variable(compiler, builtin, SpvStorageClassOutput, 0); + output_id = spirv_compiler_emit_builtin_variable(compiler, builtin, SpvStorageClassOutput, 0); vkd3d_symbol_make_register(®_symbol, reg); write_mask = vkd3d_write_mask_from_component_count(builtin->component_count); @@ -4953,12 +4971,12 @@ static void vkd3d_dxbc_compiler_emit_output_register(struct vkd3d_dxbc_compiler SpvStorageClassOutput, builtin->component_type, write_mask); reg_symbol.info.reg.dcl_mask = write_mask; reg_symbol.info.reg.is_aggregate = builtin->spirv_array_size; - vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol); - vkd3d_dxbc_compiler_emit_register_execution_mode(compiler, reg); - vkd3d_dxbc_compiler_emit_register_debug_name(builder, output_id, reg); + spirv_compiler_put_symbol(compiler, ®_symbol); + spirv_compiler_emit_register_execution_mode(compiler, reg); + spirv_compiler_emit_register_debug_name(builder, output_id, reg); } -static uint32_t vkd3d_dxbc_compiler_emit_shader_phase_builtin_variable(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_shader_phase_builtin_variable(struct spirv_compiler *compiler, const struct vkd3d_shader_phase *phase, const struct vkd3d_spirv_builtin *builtin) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -4974,7 +4992,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_shader_phase_builtin_variable(struct vk if (variable_id && *variable_id) return *variable_id; - id = vkd3d_dxbc_compiler_emit_builtin_variable(compiler, builtin, SpvStorageClassOutput, 0); + id = spirv_compiler_emit_builtin_variable(compiler, builtin, SpvStorageClassOutput, 0); if (phase->type == VKD3DSIH_HS_FORK_PHASE || phase->type == VKD3DSIH_HS_JOIN_PHASE) vkd3d_spirv_build_op_decorate(builder, id, SpvDecorationPatch, NULL, 0); @@ -4983,7 +5001,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_shader_phase_builtin_variable(struct vk return id; } -static void vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_output(struct spirv_compiler *compiler, const struct vkd3d_shader_dst_param *dst, enum vkd3d_shader_input_sysval_semantic sysval) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -4998,14 +5016,14 @@ static void vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *compiler bool use_private_variable = false; struct vkd3d_symbol reg_symbol; SpvStorageClass storage_class; - struct wine_rb_entry *entry = NULL; + struct rb_entry *entry = NULL; unsigned int signature_idx; unsigned int write_mask; unsigned int array_size; bool is_patch_constant; uint32_t id, var_id; - phase = vkd3d_dxbc_compiler_get_current_shader_phase(compiler); + phase = spirv_compiler_get_current_shader_phase(compiler); is_patch_constant = phase && (phase->type == VKD3DSIH_HS_FORK_PHASE || phase->type == VKD3DSIH_HS_JOIN_PHASE); shader_signature = is_patch_constant ? compiler->patch_constant_signature : compiler->output_signature; @@ -5049,9 +5067,9 @@ static void vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *compiler vkd3d_symbol_make_register(®_symbol, reg); - if ((entry = wine_rb_get(&compiler->symbol_table, ®_symbol))) + if ((entry = rb_get(&compiler->symbol_table, ®_symbol))) { - symbol = WINE_RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); + symbol = RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); id = symbol->id; } @@ -5066,15 +5084,15 @@ static void vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *compiler else if (builtin) { if (phase) - id = vkd3d_dxbc_compiler_emit_shader_phase_builtin_variable(compiler, phase, builtin); + id = spirv_compiler_emit_shader_phase_builtin_variable(compiler, phase, builtin); else - id = vkd3d_dxbc_compiler_emit_builtin_variable(compiler, builtin, storage_class, array_size); + id = spirv_compiler_emit_builtin_variable(compiler, builtin, storage_class, array_size); if (builtin->spirv_array_size) compiler->output_info[signature_idx].array_element_mask = calculate_sysval_array_mask(compiler, shader_signature, sysval); - vkd3d_dxbc_compiler_emit_register_execution_mode(compiler, &dst->reg); + spirv_compiler_emit_register_execution_mode(compiler, &dst->reg); } else { @@ -5083,7 +5101,7 @@ static void vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *compiler if (is_patch_constant) location += compiler->output_signature->element_count; - id = vkd3d_dxbc_compiler_emit_array_variable(compiler, &builder->global_stream, + id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream, storage_class, component_type, output_component_count, array_size); vkd3d_spirv_add_iface_variable(builder, id); @@ -5104,7 +5122,7 @@ static void vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *compiler if (is_patch_constant) vkd3d_spirv_build_op_decorate(builder, id, SpvDecorationPatch, NULL, 0); - vkd3d_dxbc_compiler_decorate_xfb_output(compiler, id, output_component_count, signature_element); + spirv_compiler_decorate_xfb_output(compiler, id, output_component_count, signature_element); compiler->output_info[signature_idx].id = id; compiler->output_info[signature_idx].component_type = component_type; @@ -5118,7 +5136,7 @@ static void vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *compiler if (is_patch_constant) var_id = compiler->hs.patch_constants_id; else if (use_private_variable) - var_id = vkd3d_dxbc_compiler_emit_variable(compiler, &builder->global_stream, + var_id = spirv_compiler_emit_variable(compiler, &builder->global_stream, storage_class, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); vkd3d_symbol_set_register_info(®_symbol, var_id, storage_class, @@ -5127,7 +5145,7 @@ static void vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *compiler reg_symbol.info.reg.is_aggregate = use_private_variable ? is_patch_constant : array_size; if (!use_private_variable && is_control_point_phase(phase)) { - reg_symbol.info.reg.member_idx = vkd3d_dxbc_compiler_get_invocation_id(compiler); + reg_symbol.info.reg.member_idx = spirv_compiler_get_invocation_id(compiler); reg_symbol.info.reg.is_dynamically_indexed = true; } else if (is_patch_constant) @@ -5136,10 +5154,10 @@ static void vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *compiler } reg_symbol.info.reg.dcl_mask = write_mask; - vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol); + spirv_compiler_put_symbol(compiler, ®_symbol); if (!is_patch_constant) - vkd3d_dxbc_compiler_emit_register_debug_name(builder, var_id, reg); + spirv_compiler_emit_register_debug_name(builder, var_id, reg); } else { @@ -5149,18 +5167,18 @@ static void vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *compiler if (use_private_variable) { - unsigned int idx = vkd3d_dxbc_compiler_get_output_variable_index(compiler, reg->idx[0].offset); + unsigned int idx = spirv_compiler_get_output_variable_index(compiler, reg->idx[0].offset); compiler->private_output_variable[idx] = var_id; compiler->private_output_variable_write_mask[idx] |= dst->write_mask; if (is_patch_constant) - compiler->private_output_variable_array_idx[idx] = vkd3d_dxbc_compiler_get_constant_uint( + compiler->private_output_variable_array_idx[idx] = spirv_compiler_get_constant_uint( compiler, reg->idx[0].offset); if (!compiler->epilogue_function_id) compiler->epilogue_function_id = vkd3d_spirv_alloc_id(builder); } } -static uint32_t vkd3d_dxbc_compiler_get_output_array_index(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_get_output_array_index(struct spirv_compiler *compiler, const struct vkd3d_shader_signature_element *e) { enum vkd3d_shader_input_sysval_semantic sysval; @@ -5179,7 +5197,7 @@ static uint32_t vkd3d_dxbc_compiler_get_output_array_index(struct vkd3d_dxbc_com } } -static void vkd3d_dxbc_compiler_emit_store_shader_output(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compiler, const struct vkd3d_shader_signature *signature, const struct vkd3d_shader_signature_element *output, const struct vkd3d_shader_output_info *output_info, uint32_t output_index_id, uint32_t val_id, unsigned int write_mask) @@ -5223,15 +5241,15 @@ static void vkd3d_dxbc_compiler_emit_store_shader_output(struct vkd3d_dxbc_compi { /* Set values to 0 for not initialized shader output components. */ write_mask |= uninit_mask; - zero_id = vkd3d_dxbc_compiler_get_constant_vector(compiler, + zero_id = spirv_compiler_get_constant_vector(compiler, output_info->component_type, VKD3D_VEC4_SIZE, 0); - val_id = vkd3d_dxbc_compiler_emit_vector_shuffle(compiler, + val_id = spirv_compiler_emit_vector_shuffle(compiler, zero_id, val_id, swizzle, uninit_mask, output_info->component_type, vkd3d_write_mask_component_count(write_mask)); } else { - val_id = vkd3d_dxbc_compiler_emit_swizzle(compiler, + val_id = spirv_compiler_emit_swizzle(compiler, val_id, VKD3DSP_WRITEMASK_ALL, output_info->component_type, swizzle, write_mask); } @@ -5246,7 +5264,7 @@ static void vkd3d_dxbc_compiler_emit_store_shader_output(struct vkd3d_dxbc_compi if (!output_info->array_element_mask) { - vkd3d_dxbc_compiler_emit_store(compiler, + spirv_compiler_emit_store(compiler, output_id, dst_write_mask, output_info->component_type, SpvStorageClassOutput, write_mask, val_id); return; } @@ -5254,7 +5272,7 @@ static void vkd3d_dxbc_compiler_emit_store_shader_output(struct vkd3d_dxbc_compi type_id = vkd3d_spirv_get_type_id(builder, output_info->component_type, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassOutput, type_id); mask = output_info->array_element_mask; - array_idx = vkd3d_dxbc_compiler_get_output_array_index(compiler, output); + array_idx = spirv_compiler_get_output_array_index(compiler, output); mask &= (1u << (array_idx * VKD3D_VEC4_SIZE)) - 1; for (i = 0, index = vkd3d_popcount(mask); i < VKD3D_VEC4_SIZE; ++i) { @@ -5262,16 +5280,16 @@ static void vkd3d_dxbc_compiler_emit_store_shader_output(struct vkd3d_dxbc_compi continue; chain_id = vkd3d_spirv_build_op_access_chain1(builder, - ptr_type_id, output_id, vkd3d_dxbc_compiler_get_constant_uint(compiler, index)); - object_id = vkd3d_dxbc_compiler_emit_swizzle(compiler, val_id, write_mask, + ptr_type_id, output_id, spirv_compiler_get_constant_uint(compiler, index)); + object_id = spirv_compiler_emit_swizzle(compiler, val_id, write_mask, output_info->component_type, VKD3D_SHADER_NO_SWIZZLE, VKD3DSP_WRITEMASK_0 << i); - vkd3d_dxbc_compiler_emit_store(compiler, chain_id, VKD3DSP_WRITEMASK_0, + spirv_compiler_emit_store(compiler, chain_id, VKD3DSP_WRITEMASK_0, output_info->component_type, SpvStorageClassOutput, VKD3DSP_WRITEMASK_0 << i, object_id); ++index; } } -static void vkd3d_dxbc_compiler_emit_shader_epilogue_function(struct vkd3d_dxbc_compiler *compiler) +static void spirv_compiler_emit_shader_epilogue_function(struct spirv_compiler *compiler) { uint32_t param_type_id[MAX_REG_OUTPUT + 1], param_id[MAX_REG_OUTPUT + 1] = {0}; uint32_t void_id, type_id, ptr_type_id, function_type_id, function_id; @@ -5288,7 +5306,7 @@ static void vkd3d_dxbc_compiler_emit_shader_epilogue_function(struct vkd3d_dxbc_ STATIC_ASSERT(ARRAY_SIZE(compiler->private_output_variable) == ARRAY_SIZE(compiler->private_output_variable_array_idx)); STATIC_ASSERT(ARRAY_SIZE(compiler->private_output_variable) == ARRAY_SIZE(compiler->private_output_variable_write_mask)); - phase = vkd3d_dxbc_compiler_get_current_shader_phase(compiler); + phase = spirv_compiler_get_current_shader_phase(compiler); is_patch_constant = phase && (phase->type == VKD3DSIH_HS_FORK_PHASE || phase->type == VKD3DSIH_HS_JOIN_PHASE); signature = is_patch_constant ? compiler->patch_constant_signature : compiler->output_signature; @@ -5323,19 +5341,19 @@ static void vkd3d_dxbc_compiler_emit_shader_epilogue_function(struct vkd3d_dxbc_ } if (is_control_point_phase(phase)) - output_index_id = vkd3d_dxbc_compiler_emit_load_invocation_id(compiler); + output_index_id = spirv_compiler_emit_load_invocation_id(compiler); for (i = 0; i < signature->element_count; ++i) { if (!compiler->output_info[i].id) continue; - variable_idx = vkd3d_dxbc_compiler_get_output_variable_index(compiler, + variable_idx = spirv_compiler_get_output_variable_index(compiler, signature->elements[i].register_index); if (!param_id[variable_idx]) continue; - vkd3d_dxbc_compiler_emit_store_shader_output(compiler, signature, + spirv_compiler_emit_store_shader_output(compiler, signature, &signature->elements[i], &compiler->output_info[i], output_index_id, param_id[variable_idx], compiler->private_output_variable_write_mask[variable_idx]); } @@ -5349,7 +5367,7 @@ static void vkd3d_dxbc_compiler_emit_shader_epilogue_function(struct vkd3d_dxbc_ compiler->epilogue_function_id = 0; } -static void vkd3d_dxbc_compiler_emit_hull_shader_builtins(struct vkd3d_dxbc_compiler *compiler) +static void spirv_compiler_emit_hull_shader_builtins(struct spirv_compiler *compiler) { struct vkd3d_shader_dst_param dst; @@ -5358,10 +5376,10 @@ static void vkd3d_dxbc_compiler_emit_hull_shader_builtins(struct vkd3d_dxbc_comp dst.reg.idx[0].offset = ~0u; dst.reg.idx[1].offset = ~0u; dst.write_mask = VKD3DSP_WRITEMASK_0; - vkd3d_dxbc_compiler_emit_input_register(compiler, &dst); + spirv_compiler_emit_input_register(compiler, &dst); } -static void vkd3d_dxbc_compiler_emit_hull_shader_patch_constants(struct vkd3d_dxbc_compiler *compiler) +static void spirv_compiler_emit_hull_shader_patch_constants(struct spirv_compiler *compiler) { const struct vkd3d_shader_signature *signature = compiler->patch_constant_signature; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -5374,12 +5392,12 @@ static void vkd3d_dxbc_compiler_emit_hull_shader_patch_constants(struct vkd3d_dx if (!register_count) return; - compiler->hs.patch_constants_id = vkd3d_dxbc_compiler_emit_array_variable(compiler, &builder->global_stream, + compiler->hs.patch_constants_id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream, SpvStorageClassPrivate, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE, register_count); vkd3d_spirv_build_op_name(builder, compiler->hs.patch_constants_id, "opc"); } -static void vkd3d_dxbc_compiler_emit_initial_declarations(struct vkd3d_dxbc_compiler *compiler) +static void spirv_compiler_emit_initial_declarations(struct spirv_compiler *compiler) { const struct vkd3d_shader_transform_feedback_info *xfb_info = compiler->xfb_info; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -5391,8 +5409,8 @@ static void vkd3d_dxbc_compiler_emit_initial_declarations(struct vkd3d_dxbc_comp break; case VKD3D_SHADER_TYPE_HULL: vkd3d_spirv_set_execution_model(builder, SpvExecutionModelTessellationControl); - vkd3d_dxbc_compiler_emit_hull_shader_builtins(compiler); - vkd3d_dxbc_compiler_emit_hull_shader_patch_constants(compiler); + spirv_compiler_emit_hull_shader_builtins(compiler); + spirv_compiler_emit_hull_shader_patch_constants(compiler); break; case VKD3D_SHADER_TYPE_DOMAIN: vkd3d_spirv_set_execution_model(builder, SpvExecutionModelTessellationEvaluation); @@ -5403,7 +5421,7 @@ static void vkd3d_dxbc_compiler_emit_initial_declarations(struct vkd3d_dxbc_comp break; case VKD3D_SHADER_TYPE_PIXEL: vkd3d_spirv_set_execution_model(builder, SpvExecutionModelFragment); - vkd3d_dxbc_compiler_emit_execution_mode(compiler, SpvExecutionModeOriginUpperLeft, NULL, 0); + spirv_compiler_emit_execution_mode(compiler, SpvExecutionModeOriginUpperLeft, NULL, 0); break; case VKD3D_SHADER_TYPE_COMPUTE: vkd3d_spirv_set_execution_model(builder, SpvExecutionModelGLCompute); @@ -5415,36 +5433,36 @@ static void vkd3d_dxbc_compiler_emit_initial_declarations(struct vkd3d_dxbc_comp if (xfb_info && xfb_info->element_count) { vkd3d_spirv_enable_capability(builder, SpvCapabilityTransformFeedback); - vkd3d_dxbc_compiler_emit_execution_mode(compiler, SpvExecutionModeXfb, NULL, 0); + spirv_compiler_emit_execution_mode(compiler, SpvExecutionModeXfb, NULL, 0); } if (compiler->shader_type != VKD3D_SHADER_TYPE_HULL) { vkd3d_spirv_builder_begin_main_function(builder); - vkd3d_dxbc_compiler_emit_shader_signature_outputs(compiler); + spirv_compiler_emit_shader_signature_outputs(compiler); } } -static size_t vkd3d_dxbc_compiler_get_current_function_location(struct vkd3d_dxbc_compiler *compiler) +static size_t spirv_compiler_get_current_function_location(struct spirv_compiler *compiler) { const struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; const struct vkd3d_shader_phase *phase; - if ((phase = vkd3d_dxbc_compiler_get_current_shader_phase(compiler))) + if ((phase = spirv_compiler_get_current_shader_phase(compiler))) return phase->function_location; return builder->main_function_location; } -static void vkd3d_dxbc_compiler_emit_dcl_global_flags(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_dcl_global_flags(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { unsigned int flags = instruction->flags; if (flags & VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL) { - vkd3d_dxbc_compiler_emit_execution_mode(compiler, SpvExecutionModeEarlyFragmentTests, NULL, 0); + spirv_compiler_emit_execution_mode(compiler, SpvExecutionModeEarlyFragmentTests, NULL, 0); flags &= ~VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL; } @@ -5460,7 +5478,7 @@ static void vkd3d_dxbc_compiler_emit_dcl_global_flags(struct vkd3d_dxbc_compiler WARN("Unhandled global flags %#x.\n", flags); } -static void vkd3d_dxbc_compiler_emit_dcl_temps(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_dcl_temps(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -5468,14 +5486,14 @@ static void vkd3d_dxbc_compiler_emit_dcl_temps(struct vkd3d_dxbc_compiler *compi unsigned int i; uint32_t id; - function_location = vkd3d_dxbc_compiler_get_current_function_location(compiler); + function_location = spirv_compiler_get_current_function_location(compiler); vkd3d_spirv_begin_function_stream_insertion(builder, function_location); assert(!compiler->temp_count); compiler->temp_count = instruction->declaration.count; for (i = 0; i < compiler->temp_count; ++i) { - id = vkd3d_dxbc_compiler_emit_variable(compiler, &builder->function_stream, + id = spirv_compiler_emit_variable(compiler, &builder->function_stream, SpvStorageClassFunction, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); if (!i) compiler->temp_id = id; @@ -5487,7 +5505,7 @@ static void vkd3d_dxbc_compiler_emit_dcl_temps(struct vkd3d_dxbc_compiler *compi vkd3d_spirv_end_function_stream_insertion(builder); } -static void vkd3d_dxbc_compiler_emit_dcl_indexable_temp(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_dcl_indexable_temp(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { const struct vkd3d_shader_indexable_temp *temp = &instruction->declaration.indexable_temp; @@ -5505,23 +5523,23 @@ static void vkd3d_dxbc_compiler_emit_dcl_indexable_temp(struct vkd3d_dxbc_compil reg.idx[0].offset = temp->register_idx; reg.idx[1].offset = ~0u; - function_location = vkd3d_dxbc_compiler_get_current_function_location(compiler); + function_location = spirv_compiler_get_current_function_location(compiler); vkd3d_spirv_begin_function_stream_insertion(builder, function_location); - id = vkd3d_dxbc_compiler_emit_array_variable(compiler, &builder->function_stream, + id = spirv_compiler_emit_array_variable(compiler, &builder->function_stream, SpvStorageClassFunction, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE, temp->register_size); - vkd3d_dxbc_compiler_emit_register_debug_name(builder, id, ®); + spirv_compiler_emit_register_debug_name(builder, id, ®); vkd3d_spirv_end_function_stream_insertion(builder); vkd3d_symbol_make_register(®_symbol, ®); vkd3d_symbol_set_register_info(®_symbol, id, SpvStorageClassFunction, VKD3D_SHADER_COMPONENT_FLOAT, VKD3DSP_WRITEMASK_ALL); - vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol); + spirv_compiler_put_symbol(compiler, ®_symbol); } -static void vkd3d_dxbc_compiler_emit_push_constant_buffers(struct vkd3d_dxbc_compiler *compiler) +static void spirv_compiler_emit_push_constant_buffers(struct spirv_compiler *compiler) { unsigned int i, j, count, reg_idx, descriptor_offsets_member_idx = 0; const SpvStorageClass storage_class = SpvStorageClassPushConstant; @@ -5552,7 +5570,7 @@ static void vkd3d_dxbc_compiler_emit_push_constant_buffers(struct vkd3d_dxbc_com if (!cb->reg.type) continue; - length_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, cb->size); + length_id = spirv_compiler_get_constant_uint(compiler, cb->size); member_ids[j] = vkd3d_spirv_build_op_type_array(builder, vec4_id, length_id); vkd3d_spirv_build_op_decorate1(builder, member_ids[j], SpvDecorationArrayStride, 16); @@ -5562,11 +5580,11 @@ static void vkd3d_dxbc_compiler_emit_push_constant_buffers(struct vkd3d_dxbc_com if (compiler->offset_info.descriptor_table_count) { uint32_t type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - length_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, compiler->offset_info.descriptor_table_count); + length_id = spirv_compiler_get_constant_uint(compiler, compiler->offset_info.descriptor_table_count); member_ids[j] = vkd3d_spirv_build_op_type_array(builder, type_id, length_id); vkd3d_spirv_build_op_decorate1(builder, member_ids[j], SpvDecorationArrayStride, 4); descriptor_offsets_member_idx = j; - compiler->descriptor_offsets_member_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, j); + compiler->descriptor_offsets_member_id = spirv_compiler_get_constant_uint(compiler, j); assert(j == count - 1); } @@ -5595,7 +5613,7 @@ static void vkd3d_dxbc_compiler_emit_push_constant_buffers(struct vkd3d_dxbc_com vkd3d_symbol_set_register_info(®_symbol, var_id, storage_class, VKD3D_SHADER_COMPONENT_FLOAT, VKD3DSP_WRITEMASK_ALL); reg_symbol.info.reg.member_idx = j; - vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol); + spirv_compiler_put_symbol(compiler, ®_symbol); ++j; } @@ -5612,7 +5630,7 @@ struct vkd3d_descriptor_variable_info unsigned int binding_base_idx; }; -static uint32_t vkd3d_dxbc_compiler_build_descriptor_variable(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_build_descriptor_variable(struct spirv_compiler *compiler, SpvStorageClass storage_class, uint32_t type_id, const struct vkd3d_shader_register *reg, const struct vkd3d_shader_register_range *range, enum vkd3d_shader_resource_type resource_type, bool is_uav_counter, struct vkd3d_descriptor_variable_info *var_info) @@ -5622,9 +5640,9 @@ static uint32_t vkd3d_dxbc_compiler_build_descriptor_variable(struct vkd3d_dxbc_ struct vkd3d_shader_descriptor_binding binding; uint32_t array_type_id, ptr_type_id, var_id; struct vkd3d_symbol symbol; - struct wine_rb_entry *entry; + struct rb_entry *entry; - binding = vkd3d_dxbc_compiler_get_descriptor_binding(compiler, reg, range, + binding = spirv_compiler_get_descriptor_binding(compiler, reg, range, resource_type, is_uav_counter, &binding_address); var_info->binding_base_idx = binding_address.binding_base_idx; @@ -5635,8 +5653,8 @@ static uint32_t vkd3d_dxbc_compiler_build_descriptor_variable(struct vkd3d_dxbc_ var_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream, ptr_type_id, storage_class, 0); - vkd3d_dxbc_compiler_emit_descriptor_binding(compiler, var_id, &binding); - vkd3d_dxbc_compiler_emit_register_debug_name(builder, var_id, reg); + spirv_compiler_emit_descriptor_binding(compiler, var_id, &binding); + spirv_compiler_emit_register_debug_name(builder, var_id, reg); var_info->array_symbol = NULL; return var_id; @@ -5654,27 +5672,27 @@ static uint32_t vkd3d_dxbc_compiler_build_descriptor_variable(struct vkd3d_dxbc_ symbol.key.descriptor_array.set = binding.set; symbol.key.descriptor_array.binding = binding.binding; symbol.key.descriptor_array.push_constant_index = binding_address.push_constant_index; - if ((entry = wine_rb_get(&compiler->symbol_table, &symbol))) + if ((entry = rb_get(&compiler->symbol_table, &symbol))) { - var_info->array_symbol = WINE_RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); + var_info->array_symbol = RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); return var_info->array_symbol->id; } var_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream, ptr_type_id, storage_class, 0); - vkd3d_dxbc_compiler_emit_descriptor_binding(compiler, var_id, &binding); - vkd3d_dxbc_compiler_emit_register_debug_name(builder, var_id, reg); + spirv_compiler_emit_descriptor_binding(compiler, var_id, &binding); + spirv_compiler_emit_register_debug_name(builder, var_id, reg); symbol.id = var_id; symbol.descriptor_array = NULL; symbol.info.descriptor_array.storage_class = storage_class; symbol.info.descriptor_array.contained_type_id = type_id; - var_info->array_symbol = vkd3d_dxbc_compiler_put_symbol(compiler, &symbol); + var_info->array_symbol = spirv_compiler_put_symbol(compiler, &symbol); return var_id; } -static void vkd3d_dxbc_compiler_emit_dcl_constant_buffer(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_dcl_constant_buffer(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { const struct vkd3d_shader_constant_buffer *cb = &instruction->declaration.cb; @@ -5688,10 +5706,10 @@ static void vkd3d_dxbc_compiler_emit_dcl_constant_buffer(struct vkd3d_dxbc_compi assert(!(instruction->flags & ~VKD3DSI_INDEXED_DYNAMIC)); - if ((push_cb = vkd3d_dxbc_compiler_find_push_constant_buffer(compiler, cb))) + if ((push_cb = spirv_compiler_find_push_constant_buffer(compiler, cb))) { /* Push constant buffers are handled in - * vkd3d_dxbc_compiler_emit_push_constant_buffers(). + * spirv_compiler_emit_push_constant_buffers(). */ unsigned int cb_size_in_bytes = cb->size * VKD3D_VEC4_SIZE * sizeof(uint32_t); push_cb->reg = *reg; @@ -5705,7 +5723,7 @@ static void vkd3d_dxbc_compiler_emit_dcl_constant_buffer(struct vkd3d_dxbc_compi } vec4_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); - length_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, cb->size); + length_id = spirv_compiler_get_constant_uint(compiler, cb->size); array_type_id = vkd3d_spirv_build_op_type_array(builder, vec4_id, length_id); vkd3d_spirv_build_op_decorate1(builder, array_type_id, SpvDecorationArrayStride, 16); @@ -5714,7 +5732,7 @@ static void vkd3d_dxbc_compiler_emit_dcl_constant_buffer(struct vkd3d_dxbc_compi vkd3d_spirv_build_op_member_decorate1(builder, struct_id, 0, SpvDecorationOffset, 0); vkd3d_spirv_build_op_name(builder, struct_id, "cb%u_struct", cb->size); - var_id = vkd3d_dxbc_compiler_build_descriptor_variable(compiler, storage_class, struct_id, + var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, struct_id, reg, &cb->range, VKD3D_SHADER_RESOURCE_BUFFER, false, &var_info); vkd3d_symbol_make_register(®_symbol, reg); @@ -5722,10 +5740,10 @@ static void vkd3d_dxbc_compiler_emit_dcl_constant_buffer(struct vkd3d_dxbc_compi VKD3D_SHADER_COMPONENT_FLOAT, VKD3DSP_WRITEMASK_ALL); reg_symbol.descriptor_array = var_info.array_symbol; reg_symbol.info.reg.binding_base_idx = var_info.binding_base_idx; - vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol); + spirv_compiler_put_symbol(compiler, ®_symbol); } -static void vkd3d_dxbc_compiler_emit_dcl_immediate_constant_buffer(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_dcl_immediate_constant_buffer(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { const struct vkd3d_shader_immediate_constant_buffer *icb = instruction->declaration.icb; @@ -5738,10 +5756,10 @@ static void vkd3d_dxbc_compiler_emit_dcl_immediate_constant_buffer(struct vkd3d_ if (!(elements = vkd3d_calloc(icb->vec4_count, sizeof(*elements)))) return; for (i = 0; i < icb->vec4_count; ++i) - elements[i] = vkd3d_dxbc_compiler_get_constant(compiler, + elements[i] = spirv_compiler_get_constant(compiler, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE, &icb->data[4 * i]); type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); - length_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, icb->vec4_count); + length_id = spirv_compiler_get_constant_uint(compiler, icb->vec4_count); type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id); const_id = vkd3d_spirv_build_op_constant_composite(builder, type_id, elements, icb->vec4_count); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPrivate, type_id); @@ -5755,10 +5773,10 @@ static void vkd3d_dxbc_compiler_emit_dcl_immediate_constant_buffer(struct vkd3d_ vkd3d_symbol_make_register(®_symbol, ®); vkd3d_symbol_set_register_info(®_symbol, icb_id, SpvStorageClassPrivate, VKD3D_SHADER_COMPONENT_FLOAT, VKD3DSP_WRITEMASK_ALL); - vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol); + spirv_compiler_put_symbol(compiler, ®_symbol); } -static void vkd3d_dxbc_compiler_emit_dcl_sampler(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_dcl_sampler(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { const struct vkd3d_shader_sampler *sampler = &instruction->declaration.sampler; @@ -5771,13 +5789,13 @@ static void vkd3d_dxbc_compiler_emit_dcl_sampler(struct vkd3d_dxbc_compiler *com vkd3d_symbol_make_sampler(®_symbol, reg); reg_symbol.info.sampler.range = sampler->range; - vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol); + spirv_compiler_put_symbol(compiler, ®_symbol); - if (vkd3d_dxbc_compiler_has_combined_sampler(compiler, NULL, sampler)) + if (spirv_compiler_has_combined_sampler(compiler, NULL, sampler)) return; type_id = vkd3d_spirv_get_op_type_sampler(builder); - var_id = vkd3d_dxbc_compiler_build_descriptor_variable(compiler, storage_class, type_id, reg, + var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, type_id, reg, &sampler->range, VKD3D_SHADER_RESOURCE_NONE, false, &var_info); vkd3d_symbol_make_register(®_symbol, reg); @@ -5785,11 +5803,11 @@ static void vkd3d_dxbc_compiler_emit_dcl_sampler(struct vkd3d_dxbc_compiler *com VKD3D_SHADER_COMPONENT_FLOAT, VKD3DSP_WRITEMASK_ALL); reg_symbol.descriptor_array = var_info.array_symbol; reg_symbol.info.reg.binding_base_idx = var_info.binding_base_idx; - vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol); + spirv_compiler_put_symbol(compiler, ®_symbol); } -static const struct vkd3d_spirv_resource_type *vkd3d_dxbc_compiler_enable_resource_type( - struct vkd3d_dxbc_compiler *compiler, enum vkd3d_shader_resource_type resource_type, bool is_uav) +static const struct vkd3d_spirv_resource_type *spirv_compiler_enable_resource_type( + struct spirv_compiler *compiler, enum vkd3d_shader_resource_type resource_type, bool is_uav) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; const struct vkd3d_spirv_resource_type *resource_type_info; @@ -5825,8 +5843,8 @@ static SpvImageFormat image_format_for_image_read(enum vkd3d_shader_component_ty } } -static const struct vkd3d_shader_descriptor_info *vkd3d_dxbc_compiler_get_descriptor_info( - struct vkd3d_dxbc_compiler *compiler, enum vkd3d_shader_descriptor_type type, +static const struct vkd3d_shader_descriptor_info *spirv_compiler_get_descriptor_info( + struct spirv_compiler *compiler, enum vkd3d_shader_descriptor_type type, const struct vkd3d_shader_register_range *range) { const struct vkd3d_shader_scan_descriptor_info *descriptor_info = compiler->scan_descriptor_info; @@ -5845,23 +5863,28 @@ static const struct vkd3d_shader_descriptor_info *vkd3d_dxbc_compiler_get_descri return NULL; } -static uint32_t vkd3d_dxbc_compiler_get_image_type_id(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_get_image_type_id(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, const struct vkd3d_shader_register_range *range, const struct vkd3d_spirv_resource_type *resource_type_info, enum vkd3d_shader_component_type data_type, bool raw_structured, uint32_t depth) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; const struct vkd3d_shader_descriptor_info *d; + bool uav_read, uav_atomics; uint32_t sampled_type_id; SpvImageFormat format; format = SpvImageFormatUnknown; if (reg->type == VKD3DSPR_UAV) { - d = vkd3d_dxbc_compiler_get_descriptor_info(compiler, + d = spirv_compiler_get_descriptor_info(compiler, VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, range); - if (raw_structured || (d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ)) + uav_read = !!(d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ); + uav_atomics = !!(d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_ATOMICS); + if (raw_structured || uav_atomics || (uav_read && !compiler->uav_read_without_format)) format = image_format_for_image_read(data_type); + else if (uav_read) + vkd3d_spirv_enable_capability(builder, SpvCapabilityStorageImageReadWithoutFormat); } sampled_type_id = vkd3d_spirv_get_type_id(builder, data_type, 1); @@ -5870,7 +5893,7 @@ static uint32_t vkd3d_dxbc_compiler_get_image_type_id(struct vkd3d_dxbc_compiler reg->type == VKD3DSPR_UAV ? 2 : 1, format); } -static void vkd3d_dxbc_compiler_emit_combined_sampler_declarations(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_combined_sampler_declarations(struct spirv_compiler *compiler, const struct vkd3d_shader_register *resource, const struct vkd3d_shader_register_range *resource_range, enum vkd3d_shader_resource_type resource_type, enum vkd3d_shader_component_type sampled_type, unsigned int structure_stride, bool raw, const struct vkd3d_spirv_resource_type *resource_type_info) @@ -5901,13 +5924,13 @@ static void vkd3d_dxbc_compiler_emit_combined_sampler_declarations(struct vkd3d_ if (!(current->flags & resource_type_flag)) continue; - if (!vkd3d_dxbc_compiler_check_shader_visibility(compiler, current->shader_visibility)) + if (!spirv_compiler_check_shader_visibility(compiler, current->shader_visibility)) continue; if (current->binding.count != 1) { FIXME("Descriptor arrays are not supported.\n"); - vkd3d_dxbc_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_DESCRIPTOR_BINDING, + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_DESCRIPTOR_BINDING, "Combined descriptor binding for resource %u, space %u, " "and sampler %u, space %u has unsupported ‘count’ %u.", resource_range->first, resource_range->space, current->sampler_index, @@ -5917,12 +5940,12 @@ static void vkd3d_dxbc_compiler_emit_combined_sampler_declarations(struct vkd3d_ sampler_range.space = current->sampler_space; sampler_range.first = current->sampler_index; sampler_range.last = current->sampler_index; - d = vkd3d_dxbc_compiler_get_descriptor_info(compiler, + d = spirv_compiler_get_descriptor_info(compiler, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, &sampler_range); depth = current->sampler_index != VKD3D_SHADER_DUMMY_SAMPLER_INDEX && (d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE); - image_type_id = vkd3d_dxbc_compiler_get_image_type_id(compiler, resource, resource_range, + image_type_id = spirv_compiler_get_image_type_id(compiler, resource, resource_range, resource_type_info, sampled_type, structure_stride || raw, depth); type_id = vkd3d_spirv_get_op_type_sampled_image(builder, image_type_id); @@ -5930,7 +5953,7 @@ static void vkd3d_dxbc_compiler_emit_combined_sampler_declarations(struct vkd3d_ var_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream, ptr_type_id, storage_class, 0); - vkd3d_dxbc_compiler_emit_descriptor_binding(compiler, var_id, ¤t->binding); + spirv_compiler_emit_descriptor_binding(compiler, var_id, ¤t->binding); if (current->sampler_index == VKD3D_SHADER_DUMMY_SAMPLER_INDEX) vkd3d_spirv_build_op_name(builder, var_id, "t%u_%u_dummy_sampler", resource_range->space, @@ -5952,15 +5975,15 @@ static void vkd3d_dxbc_compiler_emit_combined_sampler_declarations(struct vkd3d_ symbol.info.resource.uav_counter_id = 0; symbol.info.resource.uav_counter_array = NULL; symbol.info.resource.uav_counter_base_idx = 0; - vkd3d_dxbc_compiler_put_symbol(compiler, &symbol); + spirv_compiler_put_symbol(compiler, &symbol); } } -static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *compiler, const struct vkd3d_shader_resource *resource, enum vkd3d_shader_resource_type resource_type, enum vkd3d_data_type resource_data_type, unsigned int structure_stride, bool raw) { - struct vkd3d_descriptor_variable_info var_info, counter_var_info; + struct vkd3d_descriptor_variable_info var_info, counter_var_info = {0}; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; SpvStorageClass storage_class = SpvStorageClassUniformConstant; uint32_t counter_type_id, type_id, var_id, counter_var_id = 0; @@ -5971,7 +5994,7 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp bool is_uav; is_uav = reg->type == VKD3DSPR_UAV; - if (!(resource_type_info = vkd3d_dxbc_compiler_enable_resource_type(compiler, + if (!(resource_type_info = spirv_compiler_enable_resource_type(compiler, resource_type, is_uav))) { FIXME("Unrecognized resource type.\n"); @@ -5980,9 +6003,9 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp sampled_type = vkd3d_component_type_from_data_type(resource_data_type); - if (vkd3d_dxbc_compiler_has_combined_sampler(compiler, resource, NULL)) + if (spirv_compiler_has_combined_sampler(compiler, resource, NULL)) { - vkd3d_dxbc_compiler_emit_combined_sampler_declarations(compiler, reg, &resource->range, + spirv_compiler_emit_combined_sampler_declarations(compiler, reg, &resource->range, resource_type, sampled_type, structure_stride, raw, resource_type_info); return; } @@ -6005,18 +6028,18 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp } else { - type_id = vkd3d_dxbc_compiler_get_image_type_id(compiler, reg, &resource->range, + type_id = spirv_compiler_get_image_type_id(compiler, reg, &resource->range, resource_type_info, sampled_type, structure_stride || raw, 0); } - var_id = vkd3d_dxbc_compiler_build_descriptor_variable(compiler, storage_class, type_id, reg, + var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, type_id, reg, &resource->range, resource_type, false, &var_info); if (is_uav) { const struct vkd3d_shader_descriptor_info *d; - d = vkd3d_dxbc_compiler_get_descriptor_info(compiler, + d = spirv_compiler_get_descriptor_info(compiler, VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, &resource->range); if (!(d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ)) @@ -6027,7 +6050,7 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp assert(structure_stride); /* counters are valid only for structured buffers */ counter_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - if (vkd3d_dxbc_compiler_is_opengl_target(compiler)) + if (spirv_compiler_is_opengl_target(compiler)) { vkd3d_spirv_enable_capability(builder, SpvCapabilityAtomicStorage); storage_class = SpvStorageClassAtomicCounter; @@ -6037,7 +6060,7 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp { uint32_t length_id, array_type_id, struct_id; - length_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, 1); + length_id = spirv_compiler_get_constant_uint(compiler, 1); array_type_id = vkd3d_spirv_build_op_type_array(builder, counter_type_id, length_id); vkd3d_spirv_build_op_decorate1(builder, array_type_id, SpvDecorationArrayStride, 4); @@ -6049,7 +6072,7 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp type_id = struct_id; } - counter_var_id = vkd3d_dxbc_compiler_build_descriptor_variable(compiler, storage_class, type_id, reg, + counter_var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, type_id, reg, &resource->range, resource_type, true, &counter_var_info); } } @@ -6067,10 +6090,10 @@ static void vkd3d_dxbc_compiler_emit_resource_declaration(struct vkd3d_dxbc_comp resource_symbol.info.resource.uav_counter_id = counter_var_id; resource_symbol.info.resource.uav_counter_array = counter_var_info.array_symbol; resource_symbol.info.resource.uav_counter_base_idx = counter_var_info.binding_base_idx; - vkd3d_dxbc_compiler_put_symbol(compiler, &resource_symbol); + spirv_compiler_put_symbol(compiler, &resource_symbol); } -static void vkd3d_dxbc_compiler_emit_dcl_resource(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_dcl_resource(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { const struct vkd3d_shader_semantic *semantic = &instruction->declaration.semantic; @@ -6081,11 +6104,11 @@ static void vkd3d_dxbc_compiler_emit_dcl_resource(struct vkd3d_dxbc_compiler *co if (flags) FIXME("Unhandled UAV flags %#x.\n", flags); - vkd3d_dxbc_compiler_emit_resource_declaration(compiler, &semantic->resource, + spirv_compiler_emit_resource_declaration(compiler, &semantic->resource, semantic->resource_type, semantic->resource_data_type[0], 0, false); } -static void vkd3d_dxbc_compiler_emit_dcl_resource_raw(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_dcl_resource_raw(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { const struct vkd3d_shader_raw_resource *resource = &instruction->declaration.raw_resource; @@ -6096,11 +6119,11 @@ static void vkd3d_dxbc_compiler_emit_dcl_resource_raw(struct vkd3d_dxbc_compiler if (flags) FIXME("Unhandled UAV flags %#x.\n", flags); - vkd3d_dxbc_compiler_emit_resource_declaration(compiler, &resource->resource, + spirv_compiler_emit_resource_declaration(compiler, &resource->resource, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT, 0, true); } -static void vkd3d_dxbc_compiler_emit_dcl_resource_structured(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_dcl_resource_structured(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { const struct vkd3d_shader_structured_resource *resource = &instruction->declaration.structured_resource; @@ -6112,11 +6135,11 @@ static void vkd3d_dxbc_compiler_emit_dcl_resource_structured(struct vkd3d_dxbc_c if (flags) FIXME("Unhandled UAV flags %#x.\n", flags); - vkd3d_dxbc_compiler_emit_resource_declaration(compiler, &resource->resource, + spirv_compiler_emit_resource_declaration(compiler, &resource->resource, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT, stride / 4, false); } -static void vkd3d_dxbc_compiler_emit_workgroup_memory(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_workgroup_memory(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, unsigned int size, unsigned int structure_stride) { uint32_t type_id, array_type_id, length_id, pointer_type_id, var_id; @@ -6125,89 +6148,89 @@ static void vkd3d_dxbc_compiler_emit_workgroup_memory(struct vkd3d_dxbc_compiler struct vkd3d_symbol reg_symbol; type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - length_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, size); + length_id = spirv_compiler_get_constant_uint(compiler, size); array_type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id); pointer_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, array_type_id); var_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream, pointer_type_id, storage_class, 0); - vkd3d_dxbc_compiler_emit_register_debug_name(builder, var_id, reg); + spirv_compiler_emit_register_debug_name(builder, var_id, reg); vkd3d_symbol_make_register(®_symbol, reg); vkd3d_symbol_set_register_info(®_symbol, var_id, storage_class, VKD3D_SHADER_COMPONENT_UINT, VKD3DSP_WRITEMASK_0); reg_symbol.info.reg.structure_stride = structure_stride; - vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol); + spirv_compiler_put_symbol(compiler, ®_symbol); } -static void vkd3d_dxbc_compiler_emit_dcl_tgsm_raw(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_dcl_tgsm_raw(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { const struct vkd3d_shader_tgsm_raw *tgsm_raw = &instruction->declaration.tgsm_raw; - vkd3d_dxbc_compiler_emit_workgroup_memory(compiler, &tgsm_raw->reg.reg, + spirv_compiler_emit_workgroup_memory(compiler, &tgsm_raw->reg.reg, tgsm_raw->byte_count / 4, 0); } -static void vkd3d_dxbc_compiler_emit_dcl_tgsm_structured(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_dcl_tgsm_structured(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { const struct vkd3d_shader_tgsm_structured *tgsm_structured = &instruction->declaration.tgsm_structured; unsigned int stride = tgsm_structured->byte_stride / 4; - vkd3d_dxbc_compiler_emit_workgroup_memory(compiler, &tgsm_structured->reg.reg, + spirv_compiler_emit_workgroup_memory(compiler, &tgsm_structured->reg.reg, tgsm_structured->structure_count * stride, stride); } -static void vkd3d_dxbc_compiler_emit_dcl_input(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_dcl_input(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { const struct vkd3d_shader_dst_param *dst = &instruction->declaration.dst; const struct vkd3d_shader_phase *phase; - if ((phase = vkd3d_dxbc_compiler_get_current_shader_phase(compiler))) - vkd3d_dxbc_compiler_emit_shader_phase_input(compiler, phase, dst); + if ((phase = spirv_compiler_get_current_shader_phase(compiler))) + spirv_compiler_emit_shader_phase_input(compiler, phase, dst); else if (vkd3d_shader_register_is_input(&dst->reg) || dst->reg.type == VKD3DSPR_PATCHCONST) - vkd3d_dxbc_compiler_emit_input(compiler, dst, VKD3D_SIV_NONE, VKD3DSIM_NONE); + spirv_compiler_emit_input(compiler, dst, VKD3D_SIV_NONE, VKD3DSIM_NONE); else - vkd3d_dxbc_compiler_emit_input_register(compiler, dst); + spirv_compiler_emit_input_register(compiler, dst); if (dst->reg.type == VKD3DSPR_OUTCONTROLPOINT) compiler->use_vocp = true; } -static void vkd3d_dxbc_compiler_emit_dcl_input_ps(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_dcl_input_ps(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { - vkd3d_dxbc_compiler_emit_input(compiler, &instruction->declaration.dst, VKD3D_SIV_NONE, instruction->flags); + spirv_compiler_emit_input(compiler, &instruction->declaration.dst, VKD3D_SIV_NONE, instruction->flags); } -static void vkd3d_dxbc_compiler_emit_dcl_input_ps_sysval(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_dcl_input_ps_sysval(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { const struct vkd3d_shader_register_semantic *semantic = &instruction->declaration.register_semantic; - vkd3d_dxbc_compiler_emit_input(compiler, &semantic->reg, semantic->sysval_semantic, instruction->flags); + spirv_compiler_emit_input(compiler, &semantic->reg, semantic->sysval_semantic, instruction->flags); } -static void vkd3d_dxbc_compiler_emit_dcl_input_sysval(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_dcl_input_sysval(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { - vkd3d_dxbc_compiler_emit_input(compiler, &instruction->declaration.register_semantic.reg, + spirv_compiler_emit_input(compiler, &instruction->declaration.register_semantic.reg, instruction->declaration.register_semantic.sysval_semantic, VKD3DSIM_NONE); } -static void vkd3d_dxbc_compiler_emit_dcl_output(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_dcl_output(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { const struct vkd3d_shader_dst_param *dst = &instruction->declaration.dst; if (vkd3d_shader_register_is_output(&dst->reg)) - vkd3d_dxbc_compiler_emit_output(compiler, dst, VKD3D_SIV_NONE); + spirv_compiler_emit_output(compiler, dst, VKD3D_SIV_NONE); else - vkd3d_dxbc_compiler_emit_output_register(compiler, dst); + spirv_compiler_emit_output_register(compiler, dst); } -static void vkd3d_dxbc_compiler_emit_dcl_output_siv(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_dcl_output_siv(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { enum vkd3d_shader_input_sysval_semantic sysval; @@ -6216,10 +6239,10 @@ static void vkd3d_dxbc_compiler_emit_dcl_output_siv(struct vkd3d_dxbc_compiler * dst = &instruction->declaration.register_semantic.reg; sysval = instruction->declaration.register_semantic.sysval_semantic; - vkd3d_dxbc_compiler_emit_output(compiler, dst, sysval); + spirv_compiler_emit_output(compiler, dst, sysval); } -static bool vkd3d_dxbc_compiler_check_index_range(struct vkd3d_dxbc_compiler *compiler, +static bool spirv_compiler_check_index_range(struct spirv_compiler *compiler, const struct vkd3d_shader_index_range *range) { const struct vkd3d_shader_register *reg = &range->dst.reg; @@ -6231,7 +6254,7 @@ static bool vkd3d_dxbc_compiler_check_index_range(struct vkd3d_dxbc_compiler *co current_reg = *reg; vkd3d_symbol_make_register(®_symbol, ¤t_reg); - if (!vkd3d_dxbc_compiler_get_register_info(compiler, ¤t_reg, ®_info)) + if (!spirv_compiler_get_register_info(compiler, ¤t_reg, ®_info)) { ERR("Failed to get register info.\n"); return false; @@ -6268,16 +6291,16 @@ static bool vkd3d_dxbc_compiler_check_index_range(struct vkd3d_dxbc_compiler *co return true; } -static void vkd3d_dxbc_compiler_emit_dcl_index_range(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_dcl_index_range(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { const struct vkd3d_shader_index_range *range = &instruction->declaration.index_range; - if (!vkd3d_dxbc_compiler_check_index_range(compiler, range)) + if (!spirv_compiler_check_index_range(compiler, range)) FIXME("Ignoring dcl_index_range %#x %u.\n", range->dst.reg.type, range->register_count); } -static void vkd3d_dxbc_compiler_emit_dcl_stream(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_dcl_stream(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { unsigned int stream_idx = instruction->src[0].reg.idx[0].offset; @@ -6286,14 +6309,14 @@ static void vkd3d_dxbc_compiler_emit_dcl_stream(struct vkd3d_dxbc_compiler *comp FIXME("Multiple streams are not supported yet.\n"); } -static void vkd3d_dxbc_compiler_emit_output_vertex_count(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_output_vertex_count(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { - vkd3d_dxbc_compiler_emit_execution_mode1(compiler, + spirv_compiler_emit_execution_mode1(compiler, SpvExecutionModeOutputVertices, instruction->declaration.count); } -static void vkd3d_dxbc_compiler_emit_dcl_input_primitive(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_dcl_input_primitive(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { enum vkd3d_primitive_type primitive_type = instruction->declaration.primitive_type.type; @@ -6321,23 +6344,31 @@ static void vkd3d_dxbc_compiler_emit_dcl_input_primitive(struct vkd3d_dxbc_compi return; } - vkd3d_dxbc_compiler_emit_execution_mode(compiler, mode, NULL, 0); + spirv_compiler_emit_execution_mode(compiler, mode, NULL, 0); } -static void vkd3d_dxbc_compiler_emit_point_size(struct vkd3d_dxbc_compiler *compiler) +static void spirv_compiler_emit_point_size(struct spirv_compiler *compiler) { static const struct vkd3d_spirv_builtin point_size = {VKD3D_SHADER_COMPONENT_FLOAT, 1, SpvBuiltInPointSize}; /* Set the point size. Point sprites are not supported in d3d10+, but * point primitives can still be used with e.g. stream output. Vulkan * requires the point size to always be explicitly defined when outputting - * points. */ - vkd3d_spirv_build_op_store(&compiler->spirv_builder, - vkd3d_dxbc_compiler_emit_builtin_variable(compiler, &point_size, SpvStorageClassOutput, 0), - vkd3d_dxbc_compiler_get_constant_float(compiler, 1.0f), SpvMemoryAccessMaskNone); + * points. + * + * If shaderTessellationAndGeometryPointSize is disabled, we must not write + * PointSize for tessellation and geometry shaders. In that case the point + * size defaults to 1.0. */ + if (spirv_compiler_is_opengl_target(compiler) || compiler->shader_type == VKD3D_SHADER_TYPE_VERTEX + || compiler->write_tess_geom_point_size) + { + vkd3d_spirv_build_op_store(&compiler->spirv_builder, + spirv_compiler_emit_builtin_variable(compiler, &point_size, SpvStorageClassOutput, 0), + spirv_compiler_get_constant_float(compiler, 1.0f), SpvMemoryAccessMaskNone); + } } -static void vkd3d_dxbc_compiler_emit_dcl_output_topology(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_dcl_output_topology(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { enum vkd3d_primitive_type primitive_type = instruction->declaration.primitive_type.type; @@ -6347,7 +6378,7 @@ static void vkd3d_dxbc_compiler_emit_dcl_output_topology(struct vkd3d_dxbc_compi { case VKD3D_PT_POINTLIST: mode = SpvExecutionModeOutputPoints; - vkd3d_dxbc_compiler_emit_point_size(compiler); + spirv_compiler_emit_point_size(compiler); break; case VKD3D_PT_LINESTRIP: mode = SpvExecutionModeOutputLineStrip; @@ -6360,22 +6391,22 @@ static void vkd3d_dxbc_compiler_emit_dcl_output_topology(struct vkd3d_dxbc_compi return; } - vkd3d_dxbc_compiler_emit_execution_mode(compiler, mode, NULL, 0); + spirv_compiler_emit_execution_mode(compiler, mode, NULL, 0); } -static void vkd3d_dxbc_compiler_emit_dcl_gs_instances(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_dcl_gs_instances(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { compiler->spirv_builder.invocation_count = instruction->declaration.count; } -static void vkd3d_dxbc_compiler_emit_dcl_tessellator_domain(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_dcl_tessellator_domain(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { enum vkd3d_tessellator_domain domain = instruction->declaration.tessellator_domain; SpvExecutionMode mode; - if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL && vkd3d_dxbc_compiler_is_opengl_target(compiler)) + if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL && spirv_compiler_is_opengl_target(compiler)) return; switch (domain) @@ -6394,15 +6425,15 @@ static void vkd3d_dxbc_compiler_emit_dcl_tessellator_domain(struct vkd3d_dxbc_co return; } - vkd3d_dxbc_compiler_emit_execution_mode(compiler, mode, NULL, 0); + spirv_compiler_emit_execution_mode(compiler, mode, NULL, 0); } -static void vkd3d_dxbc_compiler_emit_tessellator_output_primitive(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_tessellator_output_primitive(struct spirv_compiler *compiler, enum vkd3d_shader_tessellator_output_primitive primitive) { SpvExecutionMode mode; - if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL && vkd3d_dxbc_compiler_is_opengl_target(compiler)) + if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL && spirv_compiler_is_opengl_target(compiler)) return; switch (primitive) @@ -6423,15 +6454,15 @@ static void vkd3d_dxbc_compiler_emit_tessellator_output_primitive(struct vkd3d_d return; } - vkd3d_dxbc_compiler_emit_execution_mode(compiler, mode, NULL, 0); + spirv_compiler_emit_execution_mode(compiler, mode, NULL, 0); } -static void vkd3d_dxbc_compiler_emit_tessellator_partitioning(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_tessellator_partitioning(struct spirv_compiler *compiler, enum vkd3d_shader_tessellator_partitioning partitioning) { SpvExecutionMode mode; - if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL && vkd3d_dxbc_compiler_is_opengl_target(compiler)) + if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL && spirv_compiler_is_opengl_target(compiler)) return; switch (partitioning) @@ -6451,27 +6482,27 @@ static void vkd3d_dxbc_compiler_emit_tessellator_partitioning(struct vkd3d_dxbc_ return; } - vkd3d_dxbc_compiler_emit_execution_mode(compiler, mode, NULL, 0); + spirv_compiler_emit_execution_mode(compiler, mode, NULL, 0); } -static void vkd3d_dxbc_compiler_emit_dcl_thread_group(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_dcl_thread_group(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { const struct vkd3d_shader_thread_group_size *group_size = &instruction->declaration.thread_group_size; const uint32_t local_size[] = {group_size->x, group_size->y, group_size->z}; - vkd3d_dxbc_compiler_emit_execution_mode(compiler, + spirv_compiler_emit_execution_mode(compiler, SpvExecutionModeLocalSize, local_size, ARRAY_SIZE(local_size)); } -static void vkd3d_dxbc_compiler_leave_shader_phase(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_leave_shader_phase(struct spirv_compiler *compiler, const struct vkd3d_shader_phase *phase) { const struct vkd3d_shader_signature *signature = compiler->output_signature; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; struct vkd3d_symbol reg_symbol, *symbol; struct vkd3d_shader_register reg; - struct wine_rb_entry *entry; + struct rb_entry *entry; unsigned int i; vkd3d_spirv_build_op_function_end(builder); @@ -6488,8 +6519,8 @@ static void vkd3d_dxbc_compiler_leave_shader_phase(struct vkd3d_dxbc_compiler *c { if (compiler->epilogue_function_id) { - vkd3d_dxbc_compiler_emit_shader_phase_name(compiler, compiler->epilogue_function_id, phase, "_epilogue"); - vkd3d_dxbc_compiler_emit_shader_epilogue_function(compiler); + spirv_compiler_emit_shader_phase_name(compiler, compiler->epilogue_function_id, phase, "_epilogue"); + spirv_compiler_emit_shader_epilogue_function(compiler); } memset(®, 0, sizeof(reg)); @@ -6509,11 +6540,11 @@ static void vkd3d_dxbc_compiler_leave_shader_phase(struct vkd3d_dxbc_compiler *c reg.type = VKD3DSPR_OUTPUT; reg.idx[0].offset = e->register_index; vkd3d_symbol_make_register(®_symbol, ®); - if ((entry = wine_rb_get(&compiler->symbol_table, ®_symbol))) + if ((entry = rb_get(&compiler->symbol_table, ®_symbol))) { - wine_rb_remove(&compiler->symbol_table, entry); + rb_remove(&compiler->symbol_table, entry); - symbol = WINE_RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); + symbol = RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); reg.type = VKD3DSPR_OUTCONTROLPOINT; reg.idx[1].offset = reg.idx[0].offset; @@ -6521,7 +6552,7 @@ static void vkd3d_dxbc_compiler_leave_shader_phase(struct vkd3d_dxbc_compiler *c vkd3d_symbol_make_register(symbol, ®); symbol->info.reg.is_aggregate = false; - if (wine_rb_put(&compiler->symbol_table, symbol, entry) == -1) + if (rb_put(&compiler->symbol_table, symbol, entry) == -1) { ERR("Failed to insert vocp symbol entry (%s).\n", debug_vkd3d_symbol(symbol)); vkd3d_symbol_free(entry, NULL); @@ -6537,22 +6568,22 @@ static void vkd3d_dxbc_compiler_leave_shader_phase(struct vkd3d_dxbc_compiler *c reg.idx[0].offset = ~0u; reg.idx[1].offset = ~0u; vkd3d_symbol_make_register(®_symbol, ®); - if ((entry = wine_rb_get(&compiler->symbol_table, ®_symbol))) + if ((entry = rb_get(&compiler->symbol_table, ®_symbol))) { - wine_rb_remove(&compiler->symbol_table, entry); + rb_remove(&compiler->symbol_table, entry); vkd3d_symbol_free(entry, NULL); } } } -static void vkd3d_dxbc_compiler_enter_shader_phase(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_enter_shader_phase(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { const struct vkd3d_shader_phase *previous_phase; struct vkd3d_shader_phase *phase; - if ((previous_phase = vkd3d_dxbc_compiler_get_current_shader_phase(compiler))) - vkd3d_dxbc_compiler_leave_shader_phase(compiler, previous_phase); + if ((previous_phase = spirv_compiler_get_current_shader_phase(compiler))) + spirv_compiler_leave_shader_phase(compiler, previous_phase); if (!vkd3d_array_reserve((void **)&compiler->shader_phases, &compiler->shader_phases_size, compiler->shader_phase_count + 1, sizeof(*compiler->shader_phases))) @@ -6569,7 +6600,7 @@ static void vkd3d_dxbc_compiler_enter_shader_phase(struct vkd3d_dxbc_compiler *c ++compiler->shader_phase_count; } -static int vkd3d_dxbc_compiler_emit_shader_phase_instance_count(struct vkd3d_dxbc_compiler *compiler, +static int spirv_compiler_emit_shader_phase_instance_count(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_shader_phase *phase = &compiler->shader_phases[compiler->shader_phase_count - 1]; @@ -6584,13 +6615,13 @@ static int vkd3d_dxbc_compiler_emit_shader_phase_instance_count(struct vkd3d_dxb phase->instance_count = instruction->declaration.count; - vkd3d_dxbc_compiler_begin_shader_phase(compiler, phase); + spirv_compiler_begin_shader_phase(compiler, phase); return VKD3D_OK; } -static const struct vkd3d_shader_phase *vkd3d_dxbc_compiler_get_control_point_phase( - struct vkd3d_dxbc_compiler *compiler) +static const struct vkd3d_shader_phase *spirv_compiler_get_control_point_phase( + struct spirv_compiler *compiler) { const struct vkd3d_shader_phase *phase; @@ -6604,7 +6635,7 @@ static const struct vkd3d_shader_phase *vkd3d_dxbc_compiler_get_control_point_ph return NULL; } -static void vkd3d_dxbc_compiler_emit_default_control_point_phase(struct vkd3d_dxbc_compiler *compiler) +static void spirv_compiler_emit_default_control_point_phase(struct spirv_compiler *compiler) { const struct vkd3d_shader_signature *output_signature = compiler->output_signature; const struct vkd3d_shader_signature *input_signature = compiler->input_signature; @@ -6618,7 +6649,7 @@ static void vkd3d_dxbc_compiler_emit_default_control_point_phase(struct vkd3d_dx uint32_t invocation_id; unsigned int i; - invocation_id = vkd3d_dxbc_compiler_emit_load_invocation_id(compiler); + invocation_id = spirv_compiler_emit_load_invocation_id(compiler); memset(&invocation, 0, sizeof(invocation)); invocation.reg.type = VKD3DSPR_OUTPOINTID; @@ -6633,7 +6664,7 @@ static void vkd3d_dxbc_compiler_emit_default_control_point_phase(struct vkd3d_dx input_reg.data_type = VKD3D_DATA_FLOAT; input_reg.idx[0].rel_addr = &invocation; input_reg.idx[2].offset = ~0u; - input_id = vkd3d_dxbc_compiler_get_register_id(compiler, &input_reg); + input_id = spirv_compiler_get_register_id(compiler, &input_reg); assert(input_signature->element_count == output_signature->element_count); for (i = 0; i < output_signature->element_count; ++i) @@ -6645,13 +6676,13 @@ static void vkd3d_dxbc_compiler_emit_default_control_point_phase(struct vkd3d_dx assert(input->component_type == output->component_type); input_reg.idx[1].offset = input->register_index; - input_id = vkd3d_dxbc_compiler_get_register_id(compiler, &input_reg); + input_id = spirv_compiler_get_register_id(compiler, &input_reg); type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 4); src_id = vkd3d_spirv_build_op_load(builder, type_id, input_id, SpvMemoryAccessMaskNone); component_type = output->component_type; component_count = vkd3d_write_mask_component_count(output->mask); - output_id = vkd3d_dxbc_compiler_emit_array_variable(compiler, &builder->global_stream, + output_id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream, SpvStorageClassOutput, component_type, component_count, compiler->output_control_point_count); vkd3d_spirv_add_iface_variable(builder, output_id); vkd3d_spirv_build_op_decorate1(builder, output_id, SpvDecorationLocation, output->register_index); @@ -6661,23 +6692,23 @@ static void vkd3d_dxbc_compiler_emit_default_control_point_phase(struct vkd3d_dx output_ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassOutput, type_id); dst_id = vkd3d_spirv_build_op_access_chain1(builder, output_ptr_type_id, output_id, invocation_id); - vkd3d_dxbc_compiler_emit_store(compiler, dst_id, output->mask, + spirv_compiler_emit_store(compiler, dst_id, output->mask, component_type, SpvStorageClassOutput, VKD3DSP_WRITEMASK_ALL, src_id); } } -static void vkd3d_dxbc_compiler_emit_barrier(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_barrier(struct spirv_compiler *compiler, SpvScope execution_scope, SpvScope memory_scope, SpvMemorySemanticsMask semantics) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t execution_id, memory_id, semantics_id; - memory_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, memory_scope); - semantics_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, semantics); + memory_id = spirv_compiler_get_constant_uint(compiler, memory_scope); + semantics_id = spirv_compiler_get_constant_uint(compiler, semantics); if (execution_scope != SpvScopeMax) { - execution_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, execution_scope); + execution_id = spirv_compiler_get_constant_uint(compiler, execution_scope); vkd3d_spirv_build_op_control_barrier(builder, execution_id, memory_id, semantics_id); } else @@ -6686,13 +6717,13 @@ static void vkd3d_dxbc_compiler_emit_barrier(struct vkd3d_dxbc_compiler *compile } } -static void vkd3d_dxbc_compiler_emit_hull_shader_barrier(struct vkd3d_dxbc_compiler *compiler) +static void spirv_compiler_emit_hull_shader_barrier(struct spirv_compiler *compiler) { - vkd3d_dxbc_compiler_emit_barrier(compiler, + spirv_compiler_emit_barrier(compiler, SpvScopeWorkgroup, SpvScopeInvocation, SpvMemorySemanticsMaskNone); } -static void vkd3d_dxbc_compiler_emit_hull_shader_input_initialisation(struct vkd3d_dxbc_compiler *compiler) +static void spirv_compiler_emit_hull_shader_input_initialisation(struct spirv_compiler *compiler) { uint32_t type_id, length_id, register_index_id, src_array_id, dst_array_id, vicp_id, tmp_id; const struct vkd3d_shader_signature *signature = compiler->input_signature; @@ -6704,7 +6735,7 @@ static void vkd3d_dxbc_compiler_emit_hull_shader_input_initialisation(struct vkd struct vkd3d_symbol *symbol, symbol_key; unsigned int register_count, i, j; struct vkd3d_shader_register r; - struct wine_rb_entry *entry; + struct rb_entry *entry; uint32_t indices[2]; for (i = 0, register_count = 0; i < signature->element_count; ++i) @@ -6713,7 +6744,7 @@ static void vkd3d_dxbc_compiler_emit_hull_shader_input_initialisation(struct vkd } type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 4); - length_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, compiler->input_control_point_count); + length_id = spirv_compiler_get_constant_uint(compiler, compiler->input_control_point_count); type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id); type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPrivate, type_id); @@ -6728,18 +6759,18 @@ static void vkd3d_dxbc_compiler_emit_hull_shader_input_initialisation(struct vkd element = &signature->elements[i]; symbol_key.key.reg.idx = element->register_index; - entry = wine_rb_get(&compiler->symbol_table, &symbol_key); - symbol = WINE_RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); + entry = rb_get(&compiler->symbol_table, &symbol_key); + symbol = RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); vicp_id = symbol->id; - register_index_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, element->register_index); + register_index_id = spirv_compiler_get_constant_uint(compiler, element->register_index); dst_array_id = vkd3d_spirv_build_op_in_bounds_access_chain1(builder, type_id, vicp_id, register_index_id); if (element->sysval_semantic) { sysval = vkd3d_siv_from_sysval(element->sysval_semantic); builtin = get_spirv_builtin_for_sysval(compiler, sysval); - src_array_id = vkd3d_dxbc_compiler_emit_builtin_variable(compiler, builtin, + src_array_id = spirv_compiler_emit_builtin_variable(compiler, builtin, SpvStorageClassInput, compiler->input_control_point_count); if (builtin->component_count == 4) @@ -6754,12 +6785,12 @@ static void vkd3d_dxbc_compiler_emit_hull_shader_input_initialisation(struct vkd for (j = 0; j < compiler->input_control_point_count; ++j) { - point_index_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, j); + point_index_id = spirv_compiler_get_constant_uint(compiler, j); src_id = vkd3d_spirv_build_op_in_bounds_access_chain1(builder, src_type_id, src_array_id, point_index_id); indices[0] = point_index_id; - indices[1] = vkd3d_dxbc_compiler_get_constant_uint(compiler, 0); + indices[1] = spirv_compiler_get_constant_uint(compiler, 0); dst_id = vkd3d_spirv_build_op_in_bounds_access_chain(builder, dst_type_id, dst_array_id, indices, 2); @@ -6769,7 +6800,7 @@ static void vkd3d_dxbc_compiler_emit_hull_shader_input_initialisation(struct vkd } else { - src_array_id = vkd3d_dxbc_compiler_emit_array_variable(compiler, &builder->global_stream, + src_array_id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream, SpvStorageClassInput, VKD3D_SHADER_COMPONENT_FLOAT, 4, compiler->input_control_point_count); vkd3d_spirv_add_iface_variable(builder, src_array_id); vkd3d_spirv_build_op_decorate1(builder, src_array_id, SpvDecorationLocation, element->register_index); @@ -6781,7 +6812,7 @@ static void vkd3d_dxbc_compiler_emit_hull_shader_input_initialisation(struct vkd } } -static void vkd3d_dxbc_compiler_emit_shader_epilogue_invocation(struct vkd3d_dxbc_compiler *compiler) +static void spirv_compiler_emit_shader_epilogue_invocation(struct spirv_compiler *compiler) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t void_id, type_id, ptr_type_id, function_id; @@ -6820,7 +6851,7 @@ static void vkd3d_dxbc_compiler_emit_shader_epilogue_invocation(struct vkd3d_dxb } } -static void vkd3d_dxbc_compiler_emit_hull_shader_main(struct vkd3d_dxbc_compiler *compiler) +static void spirv_compiler_emit_hull_shader_main(struct spirv_compiler *compiler) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; const struct vkd3d_shader_phase *control_point_phase, *phase; @@ -6830,17 +6861,17 @@ static void vkd3d_dxbc_compiler_emit_hull_shader_main(struct vkd3d_dxbc_compiler vkd3d_spirv_builder_begin_main_function(builder); - vkd3d_dxbc_compiler_emit_hull_shader_input_initialisation(compiler); + spirv_compiler_emit_hull_shader_input_initialisation(compiler); void_id = vkd3d_spirv_get_op_type_void(builder); - if ((control_point_phase = vkd3d_dxbc_compiler_get_control_point_phase(compiler))) + if ((control_point_phase = spirv_compiler_get_control_point_phase(compiler))) vkd3d_spirv_build_op_function_call(builder, void_id, control_point_phase->function_id, NULL, 0); else - vkd3d_dxbc_compiler_emit_default_control_point_phase(compiler); + spirv_compiler_emit_default_control_point_phase(compiler); if (compiler->use_vocp) - vkd3d_dxbc_compiler_emit_hull_shader_barrier(compiler); + spirv_compiler_emit_hull_shader_barrier(compiler); for (i = 0; i < compiler->shader_phase_count; ++i) { @@ -6852,7 +6883,7 @@ static void vkd3d_dxbc_compiler_emit_hull_shader_main(struct vkd3d_dxbc_compiler { for (j = 0; j < phase->instance_count; ++j) { - phase_instance_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, j); + phase_instance_id = spirv_compiler_get_constant_uint(compiler, j); vkd3d_spirv_build_op_function_call(builder, void_id, phase->function_id, &phase_instance_id, 1); } @@ -6863,12 +6894,12 @@ static void vkd3d_dxbc_compiler_emit_hull_shader_main(struct vkd3d_dxbc_compiler } } - vkd3d_dxbc_compiler_emit_shader_epilogue_invocation(compiler); + spirv_compiler_emit_shader_epilogue_invocation(compiler); vkd3d_spirv_build_op_return(builder); vkd3d_spirv_build_op_function_end(builder); } -static SpvOp vkd3d_dxbc_compiler_map_alu_instruction(const struct vkd3d_shader_instruction *instruction) +static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instruction *instruction) { static const struct { @@ -6916,18 +6947,18 @@ static SpvOp vkd3d_dxbc_compiler_map_alu_instruction(const struct vkd3d_shader_i return SpvOpMax; } -static void vkd3d_dxbc_compiler_emit_alu_instruction(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_alu_instruction(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; const struct vkd3d_shader_dst_param *dst = instruction->dst; const struct vkd3d_shader_src_param *src = instruction->src; - uint32_t src_ids[VKD3D_DXBC_MAX_SOURCE_COUNT]; + uint32_t src_ids[SPIRV_MAX_SRC_COUNT]; uint32_t type_id, val_id; unsigned int i; SpvOp op; - op = vkd3d_dxbc_compiler_map_alu_instruction(instruction); + op = spirv_compiler_map_alu_instruction(instruction); if (op == SpvOpMax) { ERR("Unexpected instruction %#x.\n", instruction->handler_idx); @@ -6935,12 +6966,12 @@ static void vkd3d_dxbc_compiler_emit_alu_instruction(struct vkd3d_dxbc_compiler } assert(instruction->dst_count == 1); - assert(instruction->src_count <= VKD3D_DXBC_MAX_SOURCE_COUNT); + assert(instruction->src_count <= SPIRV_MAX_SRC_COUNT); - type_id = vkd3d_dxbc_compiler_get_type_id_for_dst(compiler, dst); + type_id = spirv_compiler_get_type_id_for_dst(compiler, dst); for (i = 0; i < instruction->src_count; ++i) - src_ids[i] = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[i], dst->write_mask); + src_ids[i] = spirv_compiler_emit_load_src(compiler, &src[i], dst->write_mask); /* The SPIR-V specification states, "The resulting value is undefined if * Shift is greater than or equal to the bit width of the components of @@ -6952,7 +6983,7 @@ static void vkd3d_dxbc_compiler_emit_alu_instruction(struct vkd3d_dxbc_compiler if (instruction->handler_idx == VKD3DSIH_ISHL || instruction->handler_idx == VKD3DSIH_ISHR || instruction->handler_idx == VKD3DSIH_USHR) { - uint32_t mask_id = vkd3d_dxbc_compiler_get_constant_vector(compiler, + uint32_t mask_id = spirv_compiler_get_constant_vector(compiler, VKD3D_SHADER_COMPONENT_UINT, vkd3d_write_mask_component_count(dst->write_mask), 0x1f); src_ids[1] = vkd3d_spirv_build_op_and(builder, type_id, src_ids[1], mask_id); } @@ -6962,10 +6993,10 @@ static void vkd3d_dxbc_compiler_emit_alu_instruction(struct vkd3d_dxbc_compiler if (instruction->flags & VKD3DSI_PRECISE_XYZW) vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0); - vkd3d_dxbc_compiler_emit_store_dst(compiler, dst, val_id); + spirv_compiler_emit_store_dst(compiler, dst, val_id); } -static enum GLSLstd450 vkd3d_dxbc_compiler_map_ext_glsl_instruction( +static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction( const struct vkd3d_shader_instruction *instruction) { static const struct @@ -7009,18 +7040,18 @@ static enum GLSLstd450 vkd3d_dxbc_compiler_map_ext_glsl_instruction( return GLSLstd450Bad; } -static void vkd3d_dxbc_compiler_emit_ext_glsl_instruction(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; const struct vkd3d_shader_dst_param *dst = instruction->dst; const struct vkd3d_shader_src_param *src = instruction->src; - uint32_t src_id[VKD3D_DXBC_MAX_SOURCE_COUNT]; + uint32_t src_id[SPIRV_MAX_SRC_COUNT]; uint32_t instr_set_id, type_id, val_id; enum GLSLstd450 glsl_inst; unsigned int i; - glsl_inst = vkd3d_dxbc_compiler_map_ext_glsl_instruction(instruction); + glsl_inst = spirv_compiler_map_ext_glsl_instruction(instruction); if (glsl_inst == GLSLstd450Bad) { ERR("Unexpected instruction %#x.\n", instruction->handler_idx); @@ -7030,12 +7061,12 @@ static void vkd3d_dxbc_compiler_emit_ext_glsl_instruction(struct vkd3d_dxbc_comp instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder); assert(instruction->dst_count == 1); - assert(instruction->src_count <= VKD3D_DXBC_MAX_SOURCE_COUNT); + assert(instruction->src_count <= SPIRV_MAX_SRC_COUNT); - type_id = vkd3d_dxbc_compiler_get_type_id_for_dst(compiler, dst); + type_id = spirv_compiler_get_type_id_for_dst(compiler, dst); for (i = 0; i < instruction->src_count; ++i) - src_id[i] = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[i], dst->write_mask); + src_id[i] = spirv_compiler_emit_load_src(compiler, &src[i], dst->write_mask); val_id = vkd3d_spirv_build_op_ext_inst(builder, type_id, instr_set_id, glsl_inst, src_id, instruction->src_count); @@ -7045,13 +7076,13 @@ static void vkd3d_dxbc_compiler_emit_ext_glsl_instruction(struct vkd3d_dxbc_comp { /* In D3D bits are numbered from the most significant bit. */ val_id = vkd3d_spirv_build_op_isub(builder, type_id, - vkd3d_dxbc_compiler_get_constant_uint(compiler, 31), val_id); + spirv_compiler_get_constant_uint(compiler, 31), val_id); } - vkd3d_dxbc_compiler_emit_store_dst(compiler, dst, val_id); + spirv_compiler_emit_store_dst(compiler, dst, val_id); } -static void vkd3d_dxbc_compiler_emit_mov(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -7065,8 +7096,8 @@ static void vkd3d_dxbc_compiler_emit_mov(struct vkd3d_dxbc_compiler *compiler, if (src->reg.type == VKD3DSPR_IMMCONST || src->reg.type == VKD3DSPR_IMMCONST64 || dst->modifiers || src->modifiers) goto general_implementation; - vkd3d_dxbc_compiler_get_register_info(compiler, &dst->reg, &dst_reg_info); - vkd3d_dxbc_compiler_get_register_info(compiler, &src->reg, &src_reg_info); + spirv_compiler_get_register_info(compiler, &dst->reg, &dst_reg_info); + spirv_compiler_get_register_info(compiler, &src->reg, &src_reg_info); if (dst_reg_info.component_type != src_reg_info.component_type || dst_reg_info.write_mask != src_reg_info.write_mask) @@ -7074,8 +7105,8 @@ static void vkd3d_dxbc_compiler_emit_mov(struct vkd3d_dxbc_compiler *compiler, if (vkd3d_swizzle_is_equal(dst_reg_info.write_mask, src->swizzle, src_reg_info.write_mask)) { - dst_id = vkd3d_dxbc_compiler_get_register_id(compiler, &dst->reg); - src_id = vkd3d_dxbc_compiler_get_register_id(compiler, &src->reg); + dst_id = spirv_compiler_get_register_id(compiler, &dst->reg); + src_id = spirv_compiler_get_register_id(compiler, &src->reg); vkd3d_spirv_build_op_copy_memory(builder, dst_id, src_id, SpvMemoryAccessMaskNone); return; @@ -7085,8 +7116,8 @@ static void vkd3d_dxbc_compiler_emit_mov(struct vkd3d_dxbc_compiler *compiler, if (component_count != 1 && component_count != VKD3D_VEC4_SIZE && dst_reg_info.write_mask == VKD3DSP_WRITEMASK_ALL) { - dst_id = vkd3d_dxbc_compiler_get_register_id(compiler, &dst->reg); - src_id = vkd3d_dxbc_compiler_get_register_id(compiler, &src->reg); + dst_id = spirv_compiler_get_register_id(compiler, &dst->reg); + src_id = spirv_compiler_get_register_id(compiler, &src->reg); type_id = vkd3d_spirv_get_type_id(builder, dst_reg_info.component_type, VKD3D_VEC4_SIZE); val_id = vkd3d_spirv_build_op_load(builder, type_id, src_id, SpvMemoryAccessMaskNone); @@ -7108,11 +7139,11 @@ static void vkd3d_dxbc_compiler_emit_mov(struct vkd3d_dxbc_compiler *compiler, } general_implementation: - val_id = vkd3d_dxbc_compiler_emit_load_src(compiler, src, dst->write_mask); - vkd3d_dxbc_compiler_emit_store_dst(compiler, dst, val_id); + val_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); + spirv_compiler_emit_store_dst(compiler, dst, val_id); } -static void vkd3d_dxbc_compiler_emit_movc(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_movc(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -7121,21 +7152,21 @@ static void vkd3d_dxbc_compiler_emit_movc(struct vkd3d_dxbc_compiler *compiler, uint32_t condition_id, src1_id, src2_id, type_id, val_id; unsigned int component_count; - condition_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], dst->write_mask); - src1_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[1], dst->write_mask); - src2_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[2], dst->write_mask); + condition_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask); + src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst->write_mask); + src2_id = spirv_compiler_emit_load_src(compiler, &src[2], dst->write_mask); component_count = vkd3d_write_mask_component_count(dst->write_mask); - type_id = vkd3d_dxbc_compiler_get_type_id_for_dst(compiler, dst); + type_id = spirv_compiler_get_type_id_for_dst(compiler, dst); - condition_id = vkd3d_dxbc_compiler_emit_int_to_bool(compiler, + condition_id = spirv_compiler_emit_int_to_bool(compiler, VKD3D_SHADER_CONDITIONAL_OP_NZ, component_count, condition_id); val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, src1_id, src2_id); - vkd3d_dxbc_compiler_emit_store_dst(compiler, dst, val_id); + spirv_compiler_emit_store_dst(compiler, dst, val_id); } -static void vkd3d_dxbc_compiler_emit_swapc(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_swapc(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -7146,23 +7177,23 @@ static void vkd3d_dxbc_compiler_emit_swapc(struct vkd3d_dxbc_compiler *compiler, assert(dst[0].write_mask == dst[1].write_mask); - condition_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], dst->write_mask); - src1_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[1], dst->write_mask); - src2_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[2], dst->write_mask); + condition_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask); + src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst->write_mask); + src2_id = spirv_compiler_emit_load_src(compiler, &src[2], dst->write_mask); component_count = vkd3d_write_mask_component_count(dst->write_mask); type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); - condition_id = vkd3d_dxbc_compiler_emit_int_to_bool(compiler, + condition_id = spirv_compiler_emit_int_to_bool(compiler, VKD3D_SHADER_CONDITIONAL_OP_NZ, component_count, condition_id); val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, src2_id, src1_id); - vkd3d_dxbc_compiler_emit_store_dst(compiler, &dst[0], val_id); + spirv_compiler_emit_store_dst(compiler, &dst[0], val_id); val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, src1_id, src2_id); - vkd3d_dxbc_compiler_emit_store_dst(compiler, &dst[1], val_id); + spirv_compiler_emit_store_dst(compiler, &dst[1], val_id); } -static void vkd3d_dxbc_compiler_emit_dot(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_dot(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -7185,7 +7216,7 @@ static void vkd3d_dxbc_compiler_emit_dot(struct vkd3d_dxbc_compiler *compiler, assert(instruction->src_count == ARRAY_SIZE(src_ids)); for (i = 0; i < ARRAY_SIZE(src_ids); ++i) - src_ids[i] = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[i], write_mask); + src_ids[i] = spirv_compiler_emit_load_src(compiler, &src[i], write_mask); type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); @@ -7193,16 +7224,16 @@ static void vkd3d_dxbc_compiler_emit_dot(struct vkd3d_dxbc_compiler *compiler, SpvOpDot, type_id, src_ids[0], src_ids[1]); if (component_count > 1) { - val_id = vkd3d_dxbc_compiler_emit_construct_vector(compiler, + val_id = spirv_compiler_emit_construct_vector(compiler, component_type, component_count, val_id, 0, 1); } if (instruction->flags & VKD3DSI_PRECISE_XYZW) vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0); - vkd3d_dxbc_compiler_emit_store_dst(compiler, dst, val_id); + spirv_compiler_emit_store_dst(compiler, dst, val_id); } -static void vkd3d_dxbc_compiler_emit_rcp(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_rcp(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -7212,18 +7243,18 @@ static void vkd3d_dxbc_compiler_emit_rcp(struct vkd3d_dxbc_compiler *compiler, unsigned int component_count; component_count = vkd3d_write_mask_component_count(dst->write_mask); - type_id = vkd3d_dxbc_compiler_get_type_id_for_dst(compiler, dst); + type_id = spirv_compiler_get_type_id_for_dst(compiler, dst); - src_id = vkd3d_dxbc_compiler_emit_load_src(compiler, src, dst->write_mask); + src_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); if (src->reg.data_type == VKD3D_DATA_DOUBLE) - div_id = vkd3d_dxbc_compiler_get_constant_double_vector(compiler, 1.0, component_count); + div_id = spirv_compiler_get_constant_double_vector(compiler, 1.0, component_count); else - div_id = vkd3d_dxbc_compiler_get_constant_float_vector(compiler, 1.0f, component_count); + div_id = spirv_compiler_get_constant_float_vector(compiler, 1.0f, component_count); val_id = vkd3d_spirv_build_op_fdiv(builder, type_id, div_id, src_id); - vkd3d_dxbc_compiler_emit_store_dst(compiler, dst, val_id); + spirv_compiler_emit_store_dst(compiler, dst, val_id); } -static void vkd3d_dxbc_compiler_emit_sincos(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_sincos(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { const struct vkd3d_shader_dst_param *dst_sin = &instruction->dst[0]; @@ -7234,8 +7265,8 @@ static void vkd3d_dxbc_compiler_emit_sincos(struct vkd3d_dxbc_compiler *compiler if (dst_sin->reg.type != VKD3DSPR_NULL) { - type_id = vkd3d_dxbc_compiler_get_type_id_for_dst(compiler, dst_sin); - src_id = vkd3d_dxbc_compiler_emit_load_src(compiler, src, dst_sin->write_mask); + type_id = spirv_compiler_get_type_id_for_dst(compiler, dst_sin); + src_id = spirv_compiler_emit_load_src(compiler, src, dst_sin->write_mask); sin_id = vkd3d_spirv_build_op_glsl_std450_sin(builder, type_id, src_id); } @@ -7244,21 +7275,21 @@ static void vkd3d_dxbc_compiler_emit_sincos(struct vkd3d_dxbc_compiler *compiler { if (dst_sin->reg.type == VKD3DSPR_NULL || dst_cos->write_mask != dst_sin->write_mask) { - type_id = vkd3d_dxbc_compiler_get_type_id_for_dst(compiler, dst_cos); - src_id = vkd3d_dxbc_compiler_emit_load_src(compiler, src, dst_cos->write_mask); + type_id = spirv_compiler_get_type_id_for_dst(compiler, dst_cos); + src_id = spirv_compiler_emit_load_src(compiler, src, dst_cos->write_mask); } cos_id = vkd3d_spirv_build_op_glsl_std450_cos(builder, type_id, src_id); } if (sin_id) - vkd3d_dxbc_compiler_emit_store_dst(compiler, dst_sin, sin_id); + spirv_compiler_emit_store_dst(compiler, dst_sin, sin_id); if (cos_id) - vkd3d_dxbc_compiler_emit_store_dst(compiler, dst_cos, cos_id); + spirv_compiler_emit_store_dst(compiler, dst_cos, cos_id); } -static void vkd3d_dxbc_compiler_emit_imul(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_imul(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -7272,17 +7303,17 @@ static void vkd3d_dxbc_compiler_emit_imul(struct vkd3d_dxbc_compiler *compiler, if (dst[1].reg.type == VKD3DSPR_NULL) return; - type_id = vkd3d_dxbc_compiler_get_type_id_for_dst(compiler, &dst[1]); + type_id = spirv_compiler_get_type_id_for_dst(compiler, &dst[1]); - src0_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], dst[1].write_mask); - src1_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[1], dst[1].write_mask); + src0_id = spirv_compiler_emit_load_src(compiler, &src[0], dst[1].write_mask); + src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst[1].write_mask); val_id = vkd3d_spirv_build_op_imul(builder, type_id, src0_id, src1_id); - vkd3d_dxbc_compiler_emit_store_dst(compiler, &dst[1], val_id); + spirv_compiler_emit_store_dst(compiler, &dst[1], val_id); } -static void vkd3d_dxbc_compiler_emit_imad(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_imad(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -7295,15 +7326,15 @@ static void vkd3d_dxbc_compiler_emit_imad(struct vkd3d_dxbc_compiler *compiler, type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_INT, component_count); for (i = 0; i < ARRAY_SIZE(src_ids); ++i) - src_ids[i] = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[i], dst->write_mask); + src_ids[i] = spirv_compiler_emit_load_src(compiler, &src[i], dst->write_mask); val_id = vkd3d_spirv_build_op_imul(builder, type_id, src_ids[0], src_ids[1]); val_id = vkd3d_spirv_build_op_iadd(builder, type_id, val_id, src_ids[2]); - vkd3d_dxbc_compiler_emit_store_dst(compiler, dst, val_id); + spirv_compiler_emit_store_dst(compiler, dst, val_id); } -static void vkd3d_dxbc_compiler_emit_udiv(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_udiv(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { uint32_t type_id, val_id, src0_id, src1_id, condition_id, uint_max_id; @@ -7315,21 +7346,21 @@ static void vkd3d_dxbc_compiler_emit_udiv(struct vkd3d_dxbc_compiler *compiler, if (dst[0].reg.type != VKD3DSPR_NULL) { component_count = vkd3d_write_mask_component_count(dst[0].write_mask); - type_id = vkd3d_dxbc_compiler_get_type_id_for_dst(compiler, &dst[0]); + type_id = spirv_compiler_get_type_id_for_dst(compiler, &dst[0]); - src0_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], dst[0].write_mask); - src1_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[1], dst[0].write_mask); + src0_id = spirv_compiler_emit_load_src(compiler, &src[0], dst[0].write_mask); + src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst[0].write_mask); - condition_id = vkd3d_dxbc_compiler_emit_int_to_bool(compiler, + condition_id = spirv_compiler_emit_int_to_bool(compiler, VKD3D_SHADER_CONDITIONAL_OP_NZ, component_count, src1_id); - uint_max_id = vkd3d_dxbc_compiler_get_constant_uint_vector(compiler, + uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, 0xffffffff, component_count); val_id = vkd3d_spirv_build_op_udiv(builder, type_id, src0_id, src1_id); /* The SPIR-V spec says: "The resulting value is undefined if Operand 2 is 0." */ val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, val_id, uint_max_id); - vkd3d_dxbc_compiler_emit_store_dst(compiler, &dst[0], val_id); + spirv_compiler_emit_store_dst(compiler, &dst[0], val_id); } if (dst[1].reg.type != VKD3DSPR_NULL) @@ -7337,14 +7368,14 @@ static void vkd3d_dxbc_compiler_emit_udiv(struct vkd3d_dxbc_compiler *compiler, if (!component_count || dst[0].write_mask != dst[1].write_mask) { component_count = vkd3d_write_mask_component_count(dst[1].write_mask); - type_id = vkd3d_dxbc_compiler_get_type_id_for_dst(compiler, &dst[1]); + type_id = spirv_compiler_get_type_id_for_dst(compiler, &dst[1]); - src0_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], dst[1].write_mask); - src1_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[1], dst[1].write_mask); + src0_id = spirv_compiler_emit_load_src(compiler, &src[0], dst[1].write_mask); + src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst[1].write_mask); - condition_id = vkd3d_dxbc_compiler_emit_int_to_bool(compiler, + condition_id = spirv_compiler_emit_int_to_bool(compiler, VKD3D_SHADER_CONDITIONAL_OP_NZ, component_count, src1_id); - uint_max_id = vkd3d_dxbc_compiler_get_constant_uint_vector(compiler, + uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, 0xffffffff, component_count); } @@ -7352,11 +7383,11 @@ static void vkd3d_dxbc_compiler_emit_udiv(struct vkd3d_dxbc_compiler *compiler, /* The SPIR-V spec says: "The resulting value is undefined if Operand 2 is 0." */ val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, val_id, uint_max_id); - vkd3d_dxbc_compiler_emit_store_dst(compiler, &dst[1], val_id); + spirv_compiler_emit_store_dst(compiler, &dst[1], val_id); } } -static void vkd3d_dxbc_compiler_emit_bitfield_instruction(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { uint32_t src_ids[4], constituents[VKD3D_VEC4_SIZE], type_id, mask_id; @@ -7373,7 +7404,7 @@ static void vkd3d_dxbc_compiler_emit_bitfield_instruction(struct vkd3d_dxbc_comp component_type = vkd3d_component_type_from_data_type(dst->reg.data_type); type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); - mask_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, 0x1f); + mask_id = spirv_compiler_get_constant_uint(compiler, 0x1f); switch (instruction->handler_idx) { @@ -7393,7 +7424,7 @@ static void vkd3d_dxbc_compiler_emit_bitfield_instruction(struct vkd3d_dxbc_comp for (j = 0; j < src_count; ++j) { - src_ids[src_count - j - 1] = vkd3d_dxbc_compiler_emit_load_src_with_type(compiler, + src_ids[src_count - j - 1] = spirv_compiler_emit_load_src_with_type(compiler, &src[j], write_mask, component_type); } @@ -7407,10 +7438,10 @@ static void vkd3d_dxbc_compiler_emit_bitfield_instruction(struct vkd3d_dxbc_comp op, type_id, src_ids, src_count); } - vkd3d_dxbc_compiler_emit_store_dst_components(compiler, dst, component_type, constituents); + spirv_compiler_emit_store_dst_components(compiler, dst, component_type, constituents); } -static void vkd3d_dxbc_compiler_emit_f16tof32(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_f16tof32(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { uint32_t instr_set_id, type_id, scalar_type_id, src_id, result_id; @@ -7425,25 +7456,25 @@ static void vkd3d_dxbc_compiler_emit_f16tof32(struct vkd3d_dxbc_compiler *compil type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); scalar_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 1); - /* FIXME: Consider a single UnpackHalf2x16 intruction per 2 components. */ + /* FIXME: Consider a single UnpackHalf2x16 instruction per 2 components. */ assert(dst->write_mask & VKD3DSP_WRITEMASK_ALL); for (i = 0, j = 0; i < VKD3D_VEC4_SIZE; ++i) { if (!(write_mask = dst->write_mask & (VKD3DSP_WRITEMASK_0 << i))) continue; - src_id = vkd3d_dxbc_compiler_emit_load_src(compiler, src, write_mask); + src_id = spirv_compiler_emit_load_src(compiler, src, write_mask); result_id = vkd3d_spirv_build_op_ext_inst(builder, type_id, instr_set_id, GLSLstd450UnpackHalf2x16, &src_id, 1); components[j++] = vkd3d_spirv_build_op_composite_extract1(builder, scalar_type_id, result_id, 0); } - vkd3d_dxbc_compiler_emit_store_dst_components(compiler, + spirv_compiler_emit_store_dst_components(compiler, dst, vkd3d_component_type_from_data_type(dst->reg.data_type), components); } -static void vkd3d_dxbc_compiler_emit_f32tof16(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_f32tof16(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { uint32_t instr_set_id, type_id, scalar_type_id, src_id, zero_id, constituents[2]; @@ -7457,16 +7488,16 @@ static void vkd3d_dxbc_compiler_emit_f32tof16(struct vkd3d_dxbc_compiler *compil instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder); type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); scalar_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - zero_id = vkd3d_dxbc_compiler_get_constant_float(compiler, 0.0f); + zero_id = spirv_compiler_get_constant_float(compiler, 0.0f); - /* FIXME: Consider a single PackHalf2x16 intruction per 2 components. */ + /* FIXME: Consider a single PackHalf2x16 instruction per 2 components. */ assert(dst->write_mask & VKD3DSP_WRITEMASK_ALL); for (i = 0, j = 0; i < VKD3D_VEC4_SIZE; ++i) { if (!(write_mask = dst->write_mask & (VKD3DSP_WRITEMASK_0 << i))) continue; - src_id = vkd3d_dxbc_compiler_emit_load_src(compiler, src, write_mask); + src_id = spirv_compiler_emit_load_src(compiler, src, write_mask); constituents[0] = src_id; constituents[1] = zero_id; src_id = vkd3d_spirv_build_op_composite_construct(builder, @@ -7475,11 +7506,11 @@ static void vkd3d_dxbc_compiler_emit_f32tof16(struct vkd3d_dxbc_compiler *compil instr_set_id, GLSLstd450PackHalf2x16, &src_id, 1); } - vkd3d_dxbc_compiler_emit_store_dst_components(compiler, + spirv_compiler_emit_store_dst_components(compiler, dst, vkd3d_component_type_from_data_type(dst->reg.data_type), components); } -static void vkd3d_dxbc_compiler_emit_comparison_instruction(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -7512,26 +7543,26 @@ static void vkd3d_dxbc_compiler_emit_comparison_instruction(struct vkd3d_dxbc_co component_count = vkd3d_write_mask_component_count(dst->write_mask); - src0_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], dst->write_mask); - src1_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[1], dst->write_mask); + src0_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask); + src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst->write_mask); type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); result_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, src0_id, src1_id); - result_id = vkd3d_dxbc_compiler_emit_bool_to_int(compiler, component_count, result_id); - vkd3d_dxbc_compiler_emit_store_reg(compiler, &dst->reg, dst->write_mask, result_id); + result_id = spirv_compiler_emit_bool_to_int(compiler, component_count, result_id); + spirv_compiler_emit_store_reg(compiler, &dst->reg, dst->write_mask, result_id); } -static uint32_t vkd3d_dxbc_compiler_emit_conditional_branch(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_conditional_branch(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction, uint32_t target_block_id) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; const struct vkd3d_shader_src_param *src = instruction->src; uint32_t condition_id, merge_block_id; - condition_id = vkd3d_dxbc_compiler_emit_load_src(compiler, src, VKD3DSP_WRITEMASK_0); - condition_id = vkd3d_dxbc_compiler_emit_int_to_bool(compiler, instruction->flags, 1, condition_id); + condition_id = spirv_compiler_emit_load_src(compiler, src, VKD3DSP_WRITEMASK_0); + condition_id = spirv_compiler_emit_int_to_bool(compiler, instruction->flags, 1, condition_id); merge_block_id = vkd3d_spirv_alloc_id(builder); @@ -7541,44 +7572,44 @@ static uint32_t vkd3d_dxbc_compiler_emit_conditional_branch(struct vkd3d_dxbc_co return merge_block_id; } -static void vkd3d_dxbc_compiler_emit_return(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_return(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { - const struct vkd3d_shader_phase *phase = vkd3d_dxbc_compiler_get_current_shader_phase(compiler); + const struct vkd3d_shader_phase *phase = spirv_compiler_get_current_shader_phase(compiler); struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; if (compiler->shader_type != VKD3D_SHADER_TYPE_GEOMETRY && (!phase || is_control_point_phase(phase))) - vkd3d_dxbc_compiler_emit_shader_epilogue_invocation(compiler); + spirv_compiler_emit_shader_epilogue_invocation(compiler); vkd3d_spirv_build_op_return(builder); } -static void vkd3d_dxbc_compiler_emit_retc(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_retc(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t target_id, merge_block_id; target_id = vkd3d_spirv_alloc_id(builder); - merge_block_id = vkd3d_dxbc_compiler_emit_conditional_branch(compiler, instruction, target_id); + merge_block_id = spirv_compiler_emit_conditional_branch(compiler, instruction, target_id); vkd3d_spirv_build_op_label(builder, target_id); - vkd3d_dxbc_compiler_emit_return(compiler, instruction); + spirv_compiler_emit_return(compiler, instruction); vkd3d_spirv_build_op_label(builder, merge_block_id); } -static void vkd3d_dxbc_compiler_emit_kill(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_kill(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t target_id, merge_block_id; target_id = vkd3d_spirv_alloc_id(builder); - merge_block_id = vkd3d_dxbc_compiler_emit_conditional_branch(compiler, instruction, target_id); + merge_block_id = spirv_compiler_emit_conditional_branch(compiler, instruction, target_id); vkd3d_spirv_build_op_label(builder, target_id); - if (vkd3d_dxbc_compiler_is_target_extension_supported(compiler, + if (spirv_compiler_is_target_extension_supported(compiler, VKD3D_SHADER_SPIRV_EXTENSION_EXT_DEMOTE_TO_HELPER_INVOCATION)) { vkd3d_spirv_enable_capability(builder, SpvCapabilityDemoteToHelperInvocationEXT); @@ -7593,8 +7624,8 @@ static void vkd3d_dxbc_compiler_emit_kill(struct vkd3d_dxbc_compiler *compiler, vkd3d_spirv_build_op_label(builder, merge_block_id); } -static struct vkd3d_control_flow_info *vkd3d_dxbc_compiler_push_control_flow_level( - struct vkd3d_dxbc_compiler *compiler) +static struct vkd3d_control_flow_info *spirv_compiler_push_control_flow_level( + struct spirv_compiler *compiler) { if (!vkd3d_array_reserve((void **)&compiler->control_flow_info, &compiler->control_flow_info_size, compiler->control_flow_depth + 1, sizeof(*compiler->control_flow_info))) @@ -7606,7 +7637,7 @@ static struct vkd3d_control_flow_info *vkd3d_dxbc_compiler_push_control_flow_lev return &compiler->control_flow_info[compiler->control_flow_depth++]; } -static void vkd3d_dxbc_compiler_pop_control_flow_level(struct vkd3d_dxbc_compiler *compiler) +static void spirv_compiler_pop_control_flow_level(struct spirv_compiler *compiler) { struct vkd3d_control_flow_info *cf_info; @@ -7616,8 +7647,8 @@ static void vkd3d_dxbc_compiler_pop_control_flow_level(struct vkd3d_dxbc_compile memset(cf_info, 0, sizeof(*cf_info)); } -static struct vkd3d_control_flow_info *vkd3d_dxbc_compiler_find_innermost_loop( - struct vkd3d_dxbc_compiler *compiler) +static struct vkd3d_control_flow_info *spirv_compiler_find_innermost_loop( + struct spirv_compiler *compiler) { int depth; @@ -7630,8 +7661,8 @@ static struct vkd3d_control_flow_info *vkd3d_dxbc_compiler_find_innermost_loop( return NULL; } -static struct vkd3d_control_flow_info *vkd3d_dxbc_compiler_find_innermost_breakable_cf_construct( - struct vkd3d_dxbc_compiler *compiler) +static struct vkd3d_control_flow_info *spirv_compiler_find_innermost_breakable_cf_construct( + struct spirv_compiler *compiler) { int depth; @@ -7645,7 +7676,7 @@ static struct vkd3d_control_flow_info *vkd3d_dxbc_compiler_find_innermost_breaka return NULL; } -static int vkd3d_dxbc_compiler_emit_control_flow_instruction(struct vkd3d_dxbc_compiler *compiler, +static int spirv_compiler_emit_control_flow_instruction(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { uint32_t loop_header_block_id, loop_body_block_id, continue_block_id; @@ -7660,11 +7691,11 @@ static int vkd3d_dxbc_compiler_emit_control_flow_instruction(struct vkd3d_dxbc_c switch (instruction->handler_idx) { case VKD3DSIH_IF: - if (!(cf_info = vkd3d_dxbc_compiler_push_control_flow_level(compiler))) + if (!(cf_info = spirv_compiler_push_control_flow_level(compiler))) return VKD3D_ERROR_OUT_OF_MEMORY; - val_id = vkd3d_dxbc_compiler_emit_load_src(compiler, src, VKD3DSP_WRITEMASK_0); - condition_id = vkd3d_dxbc_compiler_emit_int_to_bool(compiler, instruction->flags, 1, val_id); + val_id = spirv_compiler_emit_load_src(compiler, src, VKD3DSP_WRITEMASK_0); + condition_id = spirv_compiler_emit_int_to_bool(compiler, instruction->flags, 1, val_id); true_label = vkd3d_spirv_alloc_id(builder); merge_block_id = vkd3d_spirv_alloc_id(builder); @@ -7710,11 +7741,11 @@ static int vkd3d_dxbc_compiler_emit_control_flow_instruction(struct vkd3d_dxbc_c vkd3d_spirv_build_op_label(builder, cf_info->u.if_.merge_block_id); - vkd3d_dxbc_compiler_pop_control_flow_level(compiler); + spirv_compiler_pop_control_flow_level(compiler); break; case VKD3DSIH_LOOP: - if (!(cf_info = vkd3d_dxbc_compiler_push_control_flow_level(compiler))) + if (!(cf_info = spirv_compiler_push_control_flow_level(compiler))) return VKD3D_ERROR_OUT_OF_MEMORY; loop_header_block_id = vkd3d_spirv_alloc_id(builder); @@ -7755,17 +7786,17 @@ static int vkd3d_dxbc_compiler_emit_control_flow_instruction(struct vkd3d_dxbc_c vkd3d_spirv_build_op_branch(builder, cf_info->u.loop.header_block_id); vkd3d_spirv_build_op_label(builder, cf_info->u.loop.merge_block_id); - vkd3d_dxbc_compiler_pop_control_flow_level(compiler); + spirv_compiler_pop_control_flow_level(compiler); break; case VKD3DSIH_SWITCH: - if (!(cf_info = vkd3d_dxbc_compiler_push_control_flow_level(compiler))) + if (!(cf_info = spirv_compiler_push_control_flow_level(compiler))) return VKD3D_ERROR_OUT_OF_MEMORY; merge_block_id = vkd3d_spirv_alloc_id(builder); assert(src->reg.data_type == VKD3D_DATA_INT); - val_id = vkd3d_dxbc_compiler_emit_load_src(compiler, src, VKD3DSP_WRITEMASK_0); + val_id = spirv_compiler_emit_load_src(compiler, src, VKD3DSP_WRITEMASK_0); vkd3d_spirv_build_op_selection_merge(builder, merge_block_id, SpvSelectionControlMaskNone); @@ -7802,7 +7833,7 @@ static int vkd3d_dxbc_compiler_emit_control_flow_instruction(struct vkd3d_dxbc_c /* The OpSwitch instruction is inserted when the endswitch * instruction is processed because we do not know the number - * of case statments in advance.*/ + * of case statements in advance.*/ vkd3d_spirv_begin_function_stream_insertion(builder, cf_info->u.switch_.stream_location); vkd3d_spirv_build_op_switch(builder, cf_info->u.switch_.selector_id, cf_info->u.switch_.default_block_id, cf_info->u.switch_.case_blocks, @@ -7810,7 +7841,7 @@ static int vkd3d_dxbc_compiler_emit_control_flow_instruction(struct vkd3d_dxbc_c vkd3d_spirv_end_function_stream_insertion(builder); vkd3d_free(cf_info->u.switch_.case_blocks); - vkd3d_dxbc_compiler_pop_control_flow_level(compiler); + spirv_compiler_pop_control_flow_level(compiler); break; case VKD3DSIH_CASE: @@ -7862,7 +7893,7 @@ static int vkd3d_dxbc_compiler_emit_control_flow_instruction(struct vkd3d_dxbc_c assert(compiler->control_flow_depth); - if (!(breakable_cf_info = vkd3d_dxbc_compiler_find_innermost_breakable_cf_construct(compiler))) + if (!(breakable_cf_info = spirv_compiler_find_innermost_breakable_cf_construct(compiler))) { FIXME("Unhandled break instruction.\n"); return VKD3D_ERROR_INVALID_SHADER; @@ -7890,13 +7921,13 @@ static int vkd3d_dxbc_compiler_emit_control_flow_instruction(struct vkd3d_dxbc_c assert(compiler->control_flow_depth); - if (!(loop_cf_info = vkd3d_dxbc_compiler_find_innermost_loop(compiler))) + if (!(loop_cf_info = spirv_compiler_find_innermost_loop(compiler))) { ERR("Invalid 'breakc' instruction outside loop.\n"); return VKD3D_ERROR_INVALID_SHADER; } - merge_block_id = vkd3d_dxbc_compiler_emit_conditional_branch(compiler, + merge_block_id = spirv_compiler_emit_conditional_branch(compiler, instruction, loop_cf_info->u.loop.merge_block_id); vkd3d_spirv_build_op_label(builder, merge_block_id); break; @@ -7908,7 +7939,7 @@ static int vkd3d_dxbc_compiler_emit_control_flow_instruction(struct vkd3d_dxbc_c assert(compiler->control_flow_depth); - if (!(loop_cf_info = vkd3d_dxbc_compiler_find_innermost_loop(compiler))) + if (!(loop_cf_info = spirv_compiler_find_innermost_loop(compiler))) { ERR("Invalid 'continue' instruction outside loop.\n"); return VKD3D_ERROR_INVALID_SHADER; @@ -7924,31 +7955,31 @@ static int vkd3d_dxbc_compiler_emit_control_flow_instruction(struct vkd3d_dxbc_c { struct vkd3d_control_flow_info *loop_cf_info; - if (!(loop_cf_info = vkd3d_dxbc_compiler_find_innermost_loop(compiler))) + if (!(loop_cf_info = spirv_compiler_find_innermost_loop(compiler))) { ERR("Invalid 'continuec' instruction outside loop.\n"); return VKD3D_ERROR_INVALID_SHADER; } - merge_block_id = vkd3d_dxbc_compiler_emit_conditional_branch(compiler, + merge_block_id = spirv_compiler_emit_conditional_branch(compiler, instruction, loop_cf_info->u.loop.continue_block_id); vkd3d_spirv_build_op_label(builder, merge_block_id); break; } case VKD3DSIH_RET: - vkd3d_dxbc_compiler_emit_return(compiler, instruction); + spirv_compiler_emit_return(compiler, instruction); if (cf_info) cf_info->inside_block = false; break; case VKD3DSIH_RETP: - vkd3d_dxbc_compiler_emit_retc(compiler, instruction); + spirv_compiler_emit_retc(compiler, instruction); break; case VKD3DSIH_TEXKILL: - vkd3d_dxbc_compiler_emit_kill(compiler, instruction); + spirv_compiler_emit_kill(compiler, instruction); break; default: @@ -7959,7 +7990,7 @@ static int vkd3d_dxbc_compiler_emit_control_flow_instruction(struct vkd3d_dxbc_c return VKD3D_OK; } -static void vkd3d_dxbc_compiler_emit_deriv_instruction(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_deriv_instruction(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -8006,10 +8037,10 @@ static void vkd3d_dxbc_compiler_emit_deriv_instruction(struct vkd3d_dxbc_compile assert(instruction->dst_count == 1); assert(instruction->src_count == 1); - type_id = vkd3d_dxbc_compiler_get_type_id_for_dst(compiler, dst); - src_id = vkd3d_dxbc_compiler_emit_load_src(compiler, src, dst->write_mask); + type_id = spirv_compiler_get_type_id_for_dst(compiler, dst); + src_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); val_id = vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, info->op, type_id, src_id); - vkd3d_dxbc_compiler_emit_store_dst(compiler, dst, val_id); + spirv_compiler_emit_store_dst(compiler, dst, val_id); } struct vkd3d_shader_image @@ -8030,25 +8061,25 @@ struct vkd3d_shader_image #define VKD3D_IMAGE_FLAG_NO_LOAD 0x2 #define VKD3D_IMAGE_FLAG_SAMPLED 0x4 -static const struct vkd3d_symbol *vkd3d_dxbc_compiler_find_resource(struct vkd3d_dxbc_compiler *compiler, +static const struct vkd3d_symbol *spirv_compiler_find_resource(struct spirv_compiler *compiler, const struct vkd3d_shader_register *resource_reg) { struct vkd3d_symbol resource_key; - struct wine_rb_entry *entry; + struct rb_entry *entry; vkd3d_symbol_make_resource(&resource_key, resource_reg); - entry = wine_rb_get(&compiler->symbol_table, &resource_key); + entry = rb_get(&compiler->symbol_table, &resource_key); assert(entry); - return WINE_RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); + return RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); } -static const struct vkd3d_symbol *vkd3d_dxbc_compiler_find_combined_sampler(struct vkd3d_dxbc_compiler *compiler, +static const struct vkd3d_symbol *spirv_compiler_find_combined_sampler(struct spirv_compiler *compiler, const struct vkd3d_shader_register *resource_reg, const struct vkd3d_shader_register *sampler_reg) { const struct vkd3d_shader_interface_info *shader_interface = &compiler->shader_interface; unsigned int sampler_space, sampler_index; struct vkd3d_symbol key; - struct wine_rb_entry *entry; + struct rb_entry *entry; if (!shader_interface->combined_sampler_count) return NULL; @@ -8058,9 +8089,9 @@ static const struct vkd3d_symbol *vkd3d_dxbc_compiler_find_combined_sampler(stru const struct vkd3d_symbol *sampler_symbol; vkd3d_symbol_make_sampler(&key, sampler_reg); - if (!(entry = wine_rb_get(&compiler->symbol_table, &key))) + if (!(entry = rb_get(&compiler->symbol_table, &key))) return NULL; - sampler_symbol = WINE_RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); + sampler_symbol = RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); sampler_space = sampler_symbol->info.sampler.range.space; sampler_index = sampler_symbol->info.sampler.range.first; } @@ -8071,12 +8102,12 @@ static const struct vkd3d_symbol *vkd3d_dxbc_compiler_find_combined_sampler(stru } vkd3d_symbol_make_combined_sampler(&key, resource_reg, sampler_space, sampler_index); - if ((entry = wine_rb_get(&compiler->symbol_table, &key))) - return WINE_RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); + if ((entry = rb_get(&compiler->symbol_table, &key))) + return RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); return NULL; } -static void vkd3d_dxbc_compiler_prepare_image(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_prepare_image(struct spirv_compiler *compiler, struct vkd3d_shader_image *image, const struct vkd3d_shader_register *resource_reg, const struct vkd3d_shader_register *sampler_reg, unsigned int flags) { @@ -8090,16 +8121,16 @@ static void vkd3d_dxbc_compiler_prepare_image(struct vkd3d_dxbc_compiler *compil depth_comparison = flags & VKD3D_IMAGE_FLAG_DEPTH; if (resource_reg->type == VKD3DSPR_RESOURCE) - symbol = vkd3d_dxbc_compiler_find_combined_sampler(compiler, resource_reg, sampler_reg); + symbol = spirv_compiler_find_combined_sampler(compiler, resource_reg, sampler_reg); if (!symbol) - symbol = vkd3d_dxbc_compiler_find_resource(compiler, resource_reg); + symbol = spirv_compiler_find_resource(compiler, resource_reg); if (symbol->descriptor_array) { const struct vkd3d_symbol_descriptor_array_data *array_data = &symbol->descriptor_array->info.descriptor_array; uint32_t ptr_type_id, index_id; - index_id = vkd3d_dxbc_compiler_get_descriptor_index(compiler, resource_reg, symbol->descriptor_array, + index_id = spirv_compiler_get_descriptor_index(compiler, resource_reg, symbol->descriptor_array, symbol->info.resource.binding_base_idx, symbol->info.resource.resource_type_info->resource_type); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, array_data->storage_class, @@ -8132,14 +8163,14 @@ static void vkd3d_dxbc_compiler_prepare_image(struct vkd3d_dxbc_compiler *compil { image->image_id = vkd3d_spirv_build_op_load(builder, image->image_type_id, image->id, SpvMemoryAccessMaskNone); if (resource_reg->non_uniform) - vkd3d_dxbc_compiler_decorate_nonuniform(compiler, image->image_id); + spirv_compiler_decorate_nonuniform(compiler, image->image_id); } else { image->image_id = 0; } - image->image_type_id = vkd3d_dxbc_compiler_get_image_type_id(compiler, resource_reg, + image->image_type_id = spirv_compiler_get_image_type_id(compiler, resource_reg, &symbol->info.resource.range, image->resource_type_info, image->sampled_type, image->structure_stride || image->raw, depth_comparison); @@ -8150,7 +8181,7 @@ static void vkd3d_dxbc_compiler_prepare_image(struct vkd3d_dxbc_compiler *compil assert(image->image_id); assert(sampler_reg); - if (!vkd3d_dxbc_compiler_get_register_info(compiler, sampler_reg, ®ister_info)) + if (!spirv_compiler_get_register_info(compiler, sampler_reg, ®ister_info)) ERR("Failed to get sampler register info.\n"); sampler_var_id = register_info.id; if (register_info.descriptor_array) @@ -8159,7 +8190,7 @@ static void vkd3d_dxbc_compiler_prepare_image(struct vkd3d_dxbc_compiler *compil = ®ister_info.descriptor_array->info.descriptor_array; uint32_t ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, register_info.storage_class, array_data->contained_type_id); - uint32_t array_idx = vkd3d_dxbc_compiler_get_descriptor_index(compiler, sampler_reg, + uint32_t array_idx = spirv_compiler_get_descriptor_index(compiler, sampler_reg, register_info.descriptor_array, register_info.binding_base_idx, VKD3D_SHADER_RESOURCE_NONE); sampler_var_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, register_info.id, &array_idx, 1); } @@ -8167,13 +8198,13 @@ static void vkd3d_dxbc_compiler_prepare_image(struct vkd3d_dxbc_compiler *compil sampler_id = vkd3d_spirv_build_op_load(builder, vkd3d_spirv_get_op_type_sampler(builder), sampler_var_id, SpvMemoryAccessMaskNone); if (sampler_reg->non_uniform) - vkd3d_dxbc_compiler_decorate_nonuniform(compiler, sampler_id); + spirv_compiler_decorate_nonuniform(compiler, sampler_id); sampled_image_type_id = vkd3d_spirv_get_op_type_sampled_image(builder, image->image_type_id); image->sampled_image_id = vkd3d_spirv_build_op_sampled_image(builder, sampled_image_type_id, image->image_id, sampler_id); if (resource_reg->non_uniform) - vkd3d_dxbc_compiler_decorate_nonuniform(compiler, image->sampled_image_id); + spirv_compiler_decorate_nonuniform(compiler, image->sampled_image_id); } else { @@ -8181,18 +8212,18 @@ static void vkd3d_dxbc_compiler_prepare_image(struct vkd3d_dxbc_compiler *compil } } -static uint32_t vkd3d_dxbc_compiler_emit_texel_offset(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_texel_offset(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction, const struct vkd3d_spirv_resource_type *resource_type_info) { const struct vkd3d_shader_texel_offset *offset = &instruction->texel_offset; unsigned int component_count = resource_type_info->offset_component_count; int32_t data[4] = {offset->u, offset->v, offset->w, 0}; - return vkd3d_dxbc_compiler_get_constant(compiler, + return spirv_compiler_get_constant(compiler, VKD3D_SHADER_COMPONENT_INT, component_count, (const uint32_t *)data); } -static void vkd3d_dxbc_compiler_emit_ld(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_ld(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -8208,38 +8239,38 @@ static void vkd3d_dxbc_compiler_emit_ld(struct vkd3d_dxbc_compiler *compiler, multisample = instruction->handler_idx == VKD3DSIH_LD2DMS; - vkd3d_dxbc_compiler_prepare_image(compiler, &image, &src[1].reg, NULL, VKD3D_IMAGE_FLAG_NONE); + spirv_compiler_prepare_image(compiler, &image, &src[1].reg, NULL, VKD3D_IMAGE_FLAG_NONE); type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1; - coordinate_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], coordinate_mask); + coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], coordinate_mask); if (image.resource_type_info->resource_type != VKD3D_SHADER_RESOURCE_BUFFER && !multisample) { operands_mask |= SpvImageOperandsLodMask; - image_operands[image_operand_count++] = vkd3d_dxbc_compiler_emit_load_src(compiler, + image_operands[image_operand_count++] = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_3); } if (vkd3d_shader_instruction_has_texel_offset(instruction)) { operands_mask |= SpvImageOperandsConstOffsetMask; - image_operands[image_operand_count++] = vkd3d_dxbc_compiler_emit_texel_offset(compiler, + image_operands[image_operand_count++] = spirv_compiler_emit_texel_offset(compiler, instruction, image.resource_type_info); } if (multisample) { operands_mask |= SpvImageOperandsSampleMask; - image_operands[image_operand_count++] = vkd3d_dxbc_compiler_emit_load_src(compiler, + image_operands[image_operand_count++] = spirv_compiler_emit_load_src(compiler, &src[2], VKD3DSP_WRITEMASK_0); } assert(image_operand_count <= ARRAY_SIZE(image_operands)); val_id = vkd3d_spirv_build_op_image_fetch(builder, type_id, image.image_id, coordinate_id, operands_mask, image_operands, image_operand_count); - vkd3d_dxbc_compiler_emit_store_dst_swizzled(compiler, + spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, image.sampled_type, src[1].swizzle); } -static void vkd3d_dxbc_compiler_emit_lod(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_lod(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -8253,19 +8284,19 @@ static void vkd3d_dxbc_compiler_emit_lod(struct vkd3d_dxbc_compiler *compiler, resource = &src[1]; sampler = &src[2]; - vkd3d_dxbc_compiler_prepare_image(compiler, &image, + spirv_compiler_prepare_image(compiler, &image, &resource->reg, &sampler->reg, VKD3D_IMAGE_FLAG_SAMPLED); type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); - coordinate_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_ALL); + coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_ALL); val_id = vkd3d_spirv_build_op_image_query_lod(builder, type_id, image.sampled_image_id, coordinate_id); - vkd3d_dxbc_compiler_emit_store_dst_swizzled(compiler, + spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, image.sampled_type, resource->swizzle); } -static void vkd3d_dxbc_compiler_emit_sample(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_sample(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -8282,7 +8313,7 @@ static void vkd3d_dxbc_compiler_emit_sample(struct vkd3d_dxbc_compiler *compiler resource = &src[1]; sampler = &src[2]; - vkd3d_dxbc_compiler_prepare_image(compiler, &image, + spirv_compiler_prepare_image(compiler, &image, &resource->reg, &sampler->reg, VKD3D_IMAGE_FLAG_SAMPLED); switch (instruction->handler_idx) @@ -8293,22 +8324,22 @@ static void vkd3d_dxbc_compiler_emit_sample(struct vkd3d_dxbc_compiler *compiler case VKD3DSIH_SAMPLE_B: op = SpvOpImageSampleImplicitLod; operands_mask |= SpvImageOperandsBiasMask; - image_operands[image_operand_count++] = vkd3d_dxbc_compiler_emit_load_src(compiler, + image_operands[image_operand_count++] = spirv_compiler_emit_load_src(compiler, &src[3], VKD3DSP_WRITEMASK_0); break; case VKD3DSIH_SAMPLE_GRAD: op = SpvOpImageSampleExplicitLod; operands_mask |= SpvImageOperandsGradMask; coordinate_mask = (1u << image.resource_type_info->offset_component_count) - 1; - image_operands[image_operand_count++] = vkd3d_dxbc_compiler_emit_load_src(compiler, + image_operands[image_operand_count++] = spirv_compiler_emit_load_src(compiler, &src[3], coordinate_mask); - image_operands[image_operand_count++] = vkd3d_dxbc_compiler_emit_load_src(compiler, + image_operands[image_operand_count++] = spirv_compiler_emit_load_src(compiler, &src[4], coordinate_mask); break; case VKD3DSIH_SAMPLE_LOD: op = SpvOpImageSampleExplicitLod; operands_mask |= SpvImageOperandsLodMask; - image_operands[image_operand_count++] = vkd3d_dxbc_compiler_emit_load_src(compiler, + image_operands[image_operand_count++] = spirv_compiler_emit_load_src(compiler, &src[3], VKD3DSP_WRITEMASK_0); break; default: @@ -8319,27 +8350,27 @@ static void vkd3d_dxbc_compiler_emit_sample(struct vkd3d_dxbc_compiler *compiler if (vkd3d_shader_instruction_has_texel_offset(instruction)) { operands_mask |= SpvImageOperandsConstOffsetMask; - image_operands[image_operand_count++] = vkd3d_dxbc_compiler_emit_texel_offset(compiler, + image_operands[image_operand_count++] = spirv_compiler_emit_texel_offset(compiler, instruction, image.resource_type_info); } sampled_type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); - coordinate_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_ALL); + coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_ALL); assert(image_operand_count <= ARRAY_SIZE(image_operands)); val_id = vkd3d_spirv_build_op_image_sample(builder, op, sampled_type_id, image.sampled_image_id, coordinate_id, operands_mask, image_operands, image_operand_count); - vkd3d_dxbc_compiler_emit_store_dst_swizzled(compiler, + spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, image.sampled_type, resource->swizzle); } -static void vkd3d_dxbc_compiler_emit_sample_c(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_sample_c(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { - uint32_t sampled_type_id, coordinate_id, dref_id, val_id, type_id; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; const struct vkd3d_shader_dst_param *dst = instruction->dst; const struct vkd3d_shader_src_param *src = instruction->src; + uint32_t sampled_type_id, coordinate_id, dref_id, val_id; SpvImageOperandsMask operands_mask = 0; unsigned int image_operand_count = 0; struct vkd3d_shader_image image; @@ -8351,39 +8382,35 @@ static void vkd3d_dxbc_compiler_emit_sample_c(struct vkd3d_dxbc_compiler *compil op = SpvOpImageSampleDrefExplicitLod; operands_mask |= SpvImageOperandsLodMask; image_operands[image_operand_count++] - = vkd3d_dxbc_compiler_get_constant_float(compiler, 0.0f); + = spirv_compiler_get_constant_float(compiler, 0.0f); } else { op = SpvOpImageSampleDrefImplicitLod; } - vkd3d_dxbc_compiler_prepare_image(compiler, + spirv_compiler_prepare_image(compiler, &image, &src[1].reg, &src[2].reg, VKD3D_IMAGE_FLAG_SAMPLED | VKD3D_IMAGE_FLAG_DEPTH); if (vkd3d_shader_instruction_has_texel_offset(instruction)) { operands_mask |= SpvImageOperandsConstOffsetMask; - image_operands[image_operand_count++] = vkd3d_dxbc_compiler_emit_texel_offset(compiler, + image_operands[image_operand_count++] = spirv_compiler_emit_texel_offset(compiler, instruction, image.resource_type_info); } sampled_type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, 1); - coordinate_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_ALL); - dref_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[3], VKD3DSP_WRITEMASK_0); - /* XXX: Nvidia is broken and expects that the D_ref is packed together with coordinates. */ - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); - coordinate_id = vkd3d_spirv_build_op_composite_insert1(builder, - type_id, dref_id, coordinate_id, image.resource_type_info->coordinate_component_count); + coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_ALL); + dref_id = spirv_compiler_emit_load_src(compiler, &src[3], VKD3DSP_WRITEMASK_0); val_id = vkd3d_spirv_build_op_image_sample_dref(builder, op, sampled_type_id, image.sampled_image_id, coordinate_id, dref_id, operands_mask, image_operands, image_operand_count); - vkd3d_dxbc_compiler_emit_store_dst_scalar(compiler, + spirv_compiler_emit_store_dst_scalar(compiler, dst, val_id, image.sampled_type, src[1].swizzle); } -static void vkd3d_dxbc_compiler_emit_gather4(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { const struct vkd3d_shader_src_param *addr, *offset, *resource, *sampler; @@ -8412,29 +8439,29 @@ static void vkd3d_dxbc_compiler_emit_gather4(struct vkd3d_dxbc_compiler *compile resource = &src[1 + extended_offset]; sampler = &src[2 + extended_offset]; - vkd3d_dxbc_compiler_prepare_image(compiler, &image, + spirv_compiler_prepare_image(compiler, &image, &resource->reg, &sampler->reg, image_flags); if (offset) { vkd3d_spirv_enable_capability(builder, SpvCapabilityImageGatherExtended); operands_mask |= SpvImageOperandsOffsetMask; - image_operands[image_operand_count++] = vkd3d_dxbc_compiler_emit_load_src(compiler, + image_operands[image_operand_count++] = spirv_compiler_emit_load_src(compiler, offset, (1u << image.resource_type_info->offset_component_count) - 1); } else if (vkd3d_shader_instruction_has_texel_offset(instruction)) { operands_mask |= SpvImageOperandsConstOffsetMask; - image_operands[image_operand_count++] = vkd3d_dxbc_compiler_emit_texel_offset(compiler, + image_operands[image_operand_count++] = spirv_compiler_emit_texel_offset(compiler, instruction, image.resource_type_info); } sampled_type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1; - coordinate_id = vkd3d_dxbc_compiler_emit_load_src(compiler, addr, coordinate_mask); + coordinate_id = spirv_compiler_emit_load_src(compiler, addr, coordinate_mask); if (image_flags & VKD3D_IMAGE_FLAG_DEPTH) { - dref_id = vkd3d_dxbc_compiler_emit_load_src(compiler, + dref_id = spirv_compiler_emit_load_src(compiler, &src[3 + extended_offset], VKD3DSP_WRITEMASK_0); val_id = vkd3d_spirv_build_op_image_dref_gather(builder, sampled_type_id, image.sampled_image_id, coordinate_id, dref_id, @@ -8444,19 +8471,19 @@ static void vkd3d_dxbc_compiler_emit_gather4(struct vkd3d_dxbc_compiler *compile { component_idx = vkd3d_swizzle_get_component(sampler->swizzle, 0); /* Nvidia driver requires signed integer type. */ - component_id = vkd3d_dxbc_compiler_get_constant(compiler, + component_id = spirv_compiler_get_constant(compiler, VKD3D_SHADER_COMPONENT_INT, 1, &component_idx); val_id = vkd3d_spirv_build_op_image_gather(builder, sampled_type_id, image.sampled_image_id, coordinate_id, component_id, operands_mask, image_operands, image_operand_count); } - vkd3d_dxbc_compiler_emit_store_dst_swizzled(compiler, + spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, image.sampled_type, resource->swizzle); } -static uint32_t vkd3d_dxbc_compiler_emit_raw_structured_addressing( - struct vkd3d_dxbc_compiler *compiler, uint32_t type_id, unsigned int stride, +static uint32_t spirv_compiler_emit_raw_structured_addressing( + struct spirv_compiler *compiler, uint32_t type_id, unsigned int stride, const struct vkd3d_shader_src_param *src0, DWORD src0_mask, const struct vkd3d_shader_src_param *src1, DWORD src1_mask) { @@ -8467,16 +8494,16 @@ static uint32_t vkd3d_dxbc_compiler_emit_raw_structured_addressing( if (stride) { - structure_id = vkd3d_dxbc_compiler_emit_load_src(compiler, src0, src0_mask); + structure_id = spirv_compiler_emit_load_src(compiler, src0, src0_mask); structure_id = vkd3d_spirv_build_op_imul(builder, type_id, - structure_id, vkd3d_dxbc_compiler_get_constant_uint(compiler, stride)); + structure_id, spirv_compiler_get_constant_uint(compiler, stride)); } offset = stride ? src1 : src0; offset_write_mask = stride ? src1_mask : src0_mask; - offset_id = vkd3d_dxbc_compiler_emit_load_src(compiler, offset, offset_write_mask); + offset_id = spirv_compiler_emit_load_src(compiler, offset, offset_write_mask); offset_id = vkd3d_spirv_build_op_shift_right_logical(builder, type_id, - offset_id, vkd3d_dxbc_compiler_get_constant_uint(compiler, 2)); + offset_id, spirv_compiler_get_constant_uint(compiler, 2)); if (structure_id) return vkd3d_spirv_build_op_iadd(builder, type_id, structure_id, offset_id); @@ -8484,7 +8511,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_raw_structured_addressing( return offset_id; } -static void vkd3d_dxbc_compiler_emit_ld_raw_structured_srv_uav(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { uint32_t coordinate_id, type_id, val_id, texel_type_id, ptr_type_id, ptr_id; @@ -8501,16 +8528,16 @@ static void vkd3d_dxbc_compiler_emit_ld_raw_structured_srv_uav(struct vkd3d_dxbc SpvOp op; resource = &src[instruction->src_count - 1]; - resource_symbol = vkd3d_dxbc_compiler_find_resource(compiler, &resource->reg); + resource_symbol = spirv_compiler_find_resource(compiler, &resource->reg); if (resource->reg.type == VKD3DSPR_UAV - && vkd3d_dxbc_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) + && spirv_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) { texel_type_id = vkd3d_spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, texel_type_id); type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - base_coordinate_id = vkd3d_dxbc_compiler_emit_raw_structured_addressing(compiler, + base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, type_id, resource_symbol->info.resource.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); @@ -8524,8 +8551,8 @@ static void vkd3d_dxbc_compiler_emit_ld_raw_structured_srv_uav(struct vkd3d_dxbc coordinate_id = base_coordinate_id; if (component_idx) coordinate_id = vkd3d_spirv_build_op_iadd(builder, type_id, - coordinate_id, vkd3d_dxbc_compiler_get_constant_uint(compiler, component_idx)); - indices[0] = vkd3d_dxbc_compiler_get_constant_uint(compiler, 0); + coordinate_id, spirv_compiler_get_constant_uint(compiler, component_idx)); + indices[0] = spirv_compiler_get_constant_uint(compiler, 0); indices[1] = coordinate_id; ptr_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, resource_symbol->id, indices, 2); @@ -8539,10 +8566,10 @@ static void vkd3d_dxbc_compiler_emit_ld_raw_structured_srv_uav(struct vkd3d_dxbc else op = SpvOpImageRead; - vkd3d_dxbc_compiler_prepare_image(compiler, &image, &resource->reg, NULL, VKD3D_IMAGE_FLAG_NONE); + spirv_compiler_prepare_image(compiler, &image, &resource->reg, NULL, VKD3D_IMAGE_FLAG_NONE); type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - base_coordinate_id = vkd3d_dxbc_compiler_emit_raw_structured_addressing(compiler, + base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, type_id, image.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); texel_type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); @@ -8556,7 +8583,7 @@ static void vkd3d_dxbc_compiler_emit_ld_raw_structured_srv_uav(struct vkd3d_dxbc coordinate_id = base_coordinate_id; if (component_idx) coordinate_id = vkd3d_spirv_build_op_iadd(builder, type_id, - coordinate_id, vkd3d_dxbc_compiler_get_constant_uint(compiler, component_idx)); + coordinate_id, spirv_compiler_get_constant_uint(compiler, component_idx)); val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, texel_type_id, image.image_id, coordinate_id); @@ -8565,10 +8592,10 @@ static void vkd3d_dxbc_compiler_emit_ld_raw_structured_srv_uav(struct vkd3d_dxbc } } assert(dst->reg.data_type == VKD3D_DATA_UINT); - vkd3d_dxbc_compiler_emit_store_dst_components(compiler, dst, VKD3D_SHADER_COMPONENT_UINT, constituents); + spirv_compiler_emit_store_dst_components(compiler, dst, VKD3D_SHADER_COMPONENT_UINT, constituents); } -static void vkd3d_dxbc_compiler_emit_ld_tgsm(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_ld_tgsm(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -8582,12 +8609,12 @@ static void vkd3d_dxbc_compiler_emit_ld_tgsm(struct vkd3d_dxbc_compiler *compile unsigned int i, j; resource = &src[instruction->src_count - 1]; - if (!vkd3d_dxbc_compiler_get_register_info(compiler, &resource->reg, ®_info)) + if (!spirv_compiler_get_register_info(compiler, &resource->reg, ®_info)) return; type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, reg_info.storage_class, type_id); - base_coordinate_id = vkd3d_dxbc_compiler_emit_raw_structured_addressing(compiler, + base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, type_id, reg_info.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); assert(dst->write_mask & VKD3DSP_WRITEMASK_ALL); @@ -8600,16 +8627,16 @@ static void vkd3d_dxbc_compiler_emit_ld_tgsm(struct vkd3d_dxbc_compiler *compile coordinate_id = base_coordinate_id; if (component_idx) coordinate_id = vkd3d_spirv_build_op_iadd(builder, type_id, - coordinate_id, vkd3d_dxbc_compiler_get_constant_uint(compiler, component_idx)); + coordinate_id, spirv_compiler_get_constant_uint(compiler, component_idx)); ptr_id = vkd3d_spirv_build_op_access_chain1(builder, ptr_type_id, reg_info.id, coordinate_id); constituents[j++] = vkd3d_spirv_build_op_load(builder, type_id, ptr_id, SpvMemoryAccessMaskNone); } assert(dst->reg.data_type == VKD3D_DATA_UINT); - vkd3d_dxbc_compiler_emit_store_dst_components(compiler, dst, VKD3D_SHADER_COMPONENT_UINT, constituents); + spirv_compiler_emit_store_dst_components(compiler, dst, VKD3D_SHADER_COMPONENT_UINT, constituents); } -static void vkd3d_dxbc_compiler_emit_ld_raw_structured(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_ld_raw_structured(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { enum vkd3d_shader_register_type reg_type = instruction->src[instruction->src_count - 1].reg.type; @@ -8617,17 +8644,17 @@ static void vkd3d_dxbc_compiler_emit_ld_raw_structured(struct vkd3d_dxbc_compile { case VKD3DSPR_RESOURCE: case VKD3DSPR_UAV: - vkd3d_dxbc_compiler_emit_ld_raw_structured_srv_uav(compiler, instruction); + spirv_compiler_emit_ld_raw_structured_srv_uav(compiler, instruction); break; case VKD3DSPR_GROUPSHAREDMEM: - vkd3d_dxbc_compiler_emit_ld_tgsm(compiler, instruction); + spirv_compiler_emit_ld_tgsm(compiler, instruction); break; default: ERR("Unexpected register type %#x.\n", reg_type); } } -static void vkd3d_dxbc_compiler_emit_store_uav_raw_structured(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { uint32_t coordinate_id, type_id, val_id, data_id, ptr_type_id, ptr_id; @@ -8641,21 +8668,21 @@ static void vkd3d_dxbc_compiler_emit_store_uav_raw_structured(struct vkd3d_dxbc_ unsigned int component_count; uint32_t indices[2]; - resource_symbol = vkd3d_dxbc_compiler_find_resource(compiler, &dst->reg); + resource_symbol = spirv_compiler_find_resource(compiler, &dst->reg); - if (vkd3d_dxbc_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) + if (spirv_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) { type_id = vkd3d_spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - base_coordinate_id = vkd3d_dxbc_compiler_emit_raw_structured_addressing(compiler, + base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, type_id, resource_symbol->info.resource.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); data = &src[instruction->src_count - 1]; assert(data->reg.data_type == VKD3D_DATA_UINT); - val_id = vkd3d_dxbc_compiler_emit_load_src(compiler, data, dst->write_mask); + val_id = spirv_compiler_emit_load_src(compiler, data, dst->write_mask); component_count = vkd3d_write_mask_component_count(dst->write_mask); for (component_idx = 0; component_idx < component_count; ++component_idx) @@ -8666,8 +8693,8 @@ static void vkd3d_dxbc_compiler_emit_store_uav_raw_structured(struct vkd3d_dxbc_ coordinate_id = base_coordinate_id; if (component_idx) coordinate_id = vkd3d_spirv_build_op_iadd(builder, type_id, - coordinate_id, vkd3d_dxbc_compiler_get_constant_uint(compiler, component_idx)); - indices[0] = vkd3d_dxbc_compiler_get_constant_uint(compiler, 0); + coordinate_id, spirv_compiler_get_constant_uint(compiler, component_idx)); + indices[0] = spirv_compiler_get_constant_uint(compiler, 0); indices[1] = coordinate_id; ptr_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, resource_symbol->id, indices, 2); @@ -8677,26 +8704,26 @@ static void vkd3d_dxbc_compiler_emit_store_uav_raw_structured(struct vkd3d_dxbc_ else { type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - vkd3d_dxbc_compiler_prepare_image(compiler, &image, &dst->reg, NULL, VKD3D_IMAGE_FLAG_NONE); + spirv_compiler_prepare_image(compiler, &image, &dst->reg, NULL, VKD3D_IMAGE_FLAG_NONE); assert((instruction->handler_idx == VKD3DSIH_STORE_STRUCTURED) != !image.structure_stride); - base_coordinate_id = vkd3d_dxbc_compiler_emit_raw_structured_addressing(compiler, + base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, type_id, image.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); data = &src[instruction->src_count - 1]; assert(data->reg.data_type == VKD3D_DATA_UINT); - val_id = vkd3d_dxbc_compiler_emit_load_src(compiler, data, dst->write_mask); + val_id = spirv_compiler_emit_load_src(compiler, data, dst->write_mask); component_count = vkd3d_write_mask_component_count(dst->write_mask); for (component_idx = 0; component_idx < component_count; ++component_idx) { /* Mesa Vulkan drivers require the texel parameter to be a vector. */ - data_id = vkd3d_dxbc_compiler_emit_construct_vector(compiler, VKD3D_SHADER_COMPONENT_UINT, + data_id = spirv_compiler_emit_construct_vector(compiler, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE, val_id, component_idx, component_count); coordinate_id = base_coordinate_id; if (component_idx) coordinate_id = vkd3d_spirv_build_op_iadd(builder, type_id, - coordinate_id, vkd3d_dxbc_compiler_get_constant_uint(compiler, component_idx)); + coordinate_id, spirv_compiler_get_constant_uint(compiler, component_idx)); vkd3d_spirv_build_op_image_write(builder, image.image_id, coordinate_id, data_id, SpvImageOperandsMaskNone, NULL, 0); @@ -8705,7 +8732,7 @@ static void vkd3d_dxbc_compiler_emit_store_uav_raw_structured(struct vkd3d_dxbc_ } -static void vkd3d_dxbc_compiler_emit_store_tgsm(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_store_tgsm(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { uint32_t coordinate_id, type_id, val_id, ptr_type_id, ptr_id, data_id; @@ -8717,18 +8744,18 @@ static void vkd3d_dxbc_compiler_emit_store_tgsm(struct vkd3d_dxbc_compiler *comp struct vkd3d_shader_register_info reg_info; unsigned int component_count; - if (!vkd3d_dxbc_compiler_get_register_info(compiler, &dst->reg, ®_info)) + if (!spirv_compiler_get_register_info(compiler, &dst->reg, ®_info)) return; type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, reg_info.storage_class, type_id); assert((instruction->handler_idx == VKD3DSIH_STORE_STRUCTURED) != !reg_info.structure_stride); - base_coordinate_id = vkd3d_dxbc_compiler_emit_raw_structured_addressing(compiler, + base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, type_id, reg_info.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); data = &src[instruction->src_count - 1]; assert(data->reg.data_type == VKD3D_DATA_UINT); - val_id = vkd3d_dxbc_compiler_emit_load_src(compiler, data, dst->write_mask); + val_id = spirv_compiler_emit_load_src(compiler, data, dst->write_mask); component_count = vkd3d_write_mask_component_count(dst->write_mask); for (component_idx = 0; component_idx < component_count; ++component_idx) @@ -8739,31 +8766,31 @@ static void vkd3d_dxbc_compiler_emit_store_tgsm(struct vkd3d_dxbc_compiler *comp coordinate_id = base_coordinate_id; if (component_idx) coordinate_id = vkd3d_spirv_build_op_iadd(builder, type_id, - coordinate_id, vkd3d_dxbc_compiler_get_constant_uint(compiler, component_idx)); + coordinate_id, spirv_compiler_get_constant_uint(compiler, component_idx)); ptr_id = vkd3d_spirv_build_op_access_chain1(builder, ptr_type_id, reg_info.id, coordinate_id); vkd3d_spirv_build_op_store(builder, ptr_id, data_id, SpvMemoryAccessMaskNone); } } -static void vkd3d_dxbc_compiler_emit_store_raw_structured(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_store_raw_structured(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { enum vkd3d_shader_register_type reg_type = instruction->dst[0].reg.type; switch (reg_type) { case VKD3DSPR_UAV: - vkd3d_dxbc_compiler_emit_store_uav_raw_structured(compiler, instruction); + spirv_compiler_emit_store_uav_raw_structured(compiler, instruction); break; case VKD3DSPR_GROUPSHAREDMEM: - vkd3d_dxbc_compiler_emit_store_tgsm(compiler, instruction); + spirv_compiler_emit_store_tgsm(compiler, instruction); break; default: ERR("Unexpected register type %#x.\n", reg_type); } } -static void vkd3d_dxbc_compiler_emit_ld_uav_typed(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_ld_uav_typed(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -8775,38 +8802,38 @@ static void vkd3d_dxbc_compiler_emit_ld_uav_typed(struct vkd3d_dxbc_compiler *co DWORD coordinate_mask; uint32_t indices[2]; - resource_symbol = vkd3d_dxbc_compiler_find_resource(compiler, &src[1].reg); + resource_symbol = spirv_compiler_find_resource(compiler, &src[1].reg); - if (vkd3d_dxbc_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) + if (spirv_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) { type_id = vkd3d_spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); - coordinate_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0); - indices[0] = vkd3d_dxbc_compiler_get_constant_uint(compiler, 0); + coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0); + indices[0] = spirv_compiler_get_constant_uint(compiler, 0); indices[1] = coordinate_id; ptr_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, resource_symbol->id, indices, 2); val_id = vkd3d_spirv_build_op_load(builder, type_id, ptr_id, SpvMemoryAccessMaskNone); - vkd3d_dxbc_compiler_emit_store_dst_swizzled(compiler, dst, val_id, + spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, resource_symbol->info.resource.sampled_type, src[1].swizzle); } else { - vkd3d_dxbc_compiler_prepare_image(compiler, &image, &src[1].reg, NULL, VKD3D_IMAGE_FLAG_NONE); + spirv_compiler_prepare_image(compiler, &image, &src[1].reg, NULL, VKD3D_IMAGE_FLAG_NONE); type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1; - coordinate_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], coordinate_mask); + coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], coordinate_mask); val_id = vkd3d_spirv_build_op_image_read(builder, type_id, image.image_id, coordinate_id, SpvImageOperandsMaskNone, NULL, 0); - vkd3d_dxbc_compiler_emit_store_dst_swizzled(compiler, + spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, image.sampled_type, src[1].swizzle); } } -static void vkd3d_dxbc_compiler_emit_store_uav_typed(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_store_uav_typed(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { uint32_t coordinate_id, texel_id, type_id, val_id, ptr_type_id, ptr_id; @@ -8818,17 +8845,17 @@ static void vkd3d_dxbc_compiler_emit_store_uav_typed(struct vkd3d_dxbc_compiler DWORD coordinate_mask; uint32_t indices[2]; - resource_symbol = vkd3d_dxbc_compiler_find_resource(compiler, &dst->reg); + resource_symbol = spirv_compiler_find_resource(compiler, &dst->reg); - if (vkd3d_dxbc_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) + if (spirv_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) { type_id = vkd3d_spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); - coordinate_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0); - indices[0] = vkd3d_dxbc_compiler_get_constant_uint(compiler, 0); + coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0); + indices[0] = spirv_compiler_get_constant_uint(compiler, 0); indices[1] = coordinate_id; - val_id = vkd3d_dxbc_compiler_emit_load_src_with_type(compiler, &src[1], + val_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1], VKD3DSP_WRITEMASK_0, resource_symbol->info.resource.sampled_type); ptr_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, resource_symbol->id, indices, 2); vkd3d_spirv_build_op_store(builder, ptr_id, val_id, SpvMemoryAccessMaskNone); @@ -8837,17 +8864,17 @@ static void vkd3d_dxbc_compiler_emit_store_uav_typed(struct vkd3d_dxbc_compiler { vkd3d_spirv_enable_capability(builder, SpvCapabilityStorageImageWriteWithoutFormat); - vkd3d_dxbc_compiler_prepare_image(compiler, &image, &dst->reg, NULL, VKD3D_IMAGE_FLAG_NONE); + spirv_compiler_prepare_image(compiler, &image, &dst->reg, NULL, VKD3D_IMAGE_FLAG_NONE); coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1; - coordinate_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], coordinate_mask); - texel_id = vkd3d_dxbc_compiler_emit_load_src_with_type(compiler, &src[1], dst->write_mask, image.sampled_type); + coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], coordinate_mask); + texel_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1], dst->write_mask, image.sampled_type); vkd3d_spirv_build_op_image_write(builder, image.image_id, coordinate_id, texel_id, SpvImageOperandsMaskNone, NULL, 0); } } -static void vkd3d_dxbc_compiler_emit_uav_counter_instruction(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_uav_counter_instruction(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -8863,7 +8890,7 @@ static void vkd3d_dxbc_compiler_emit_uav_counter_instruction(struct vkd3d_dxbc_c op = instruction->handler_idx == VKD3DSIH_IMM_ATOMIC_ALLOC ? SpvOpAtomicIIncrement : SpvOpAtomicIDecrement; - resource_symbol = vkd3d_dxbc_compiler_find_resource(compiler, &src->reg); + resource_symbol = spirv_compiler_find_resource(compiler, &src->reg); counter_id = resource_symbol->info.resource.uav_counter_id; assert(counter_id); @@ -8874,7 +8901,7 @@ static void vkd3d_dxbc_compiler_emit_uav_counter_instruction(struct vkd3d_dxbc_c const struct vkd3d_symbol_descriptor_array_data *array_data; uint32_t index_id; - index_id = vkd3d_dxbc_compiler_get_descriptor_index(compiler, &src->reg, + index_id = spirv_compiler_get_descriptor_index(compiler, &src->reg, resource_symbol->info.resource.uav_counter_array, resource_symbol->info.resource.uav_counter_base_idx, resource_symbol->info.resource.resource_type_info->resource_type); @@ -8886,7 +8913,7 @@ static void vkd3d_dxbc_compiler_emit_uav_counter_instruction(struct vkd3d_dxbc_c counter_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, counter_id, &index_id, 1); } - if (vkd3d_dxbc_compiler_is_opengl_target(compiler)) + if (spirv_compiler_is_opengl_target(compiler)) { pointer_id = counter_id; memory_semantics |= SpvMemorySemanticsAtomicCounterMemoryMask; @@ -8894,8 +8921,8 @@ static void vkd3d_dxbc_compiler_emit_uav_counter_instruction(struct vkd3d_dxbc_c else if (compiler->ssbo_uavs) { ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); - coordinate_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, 0); - operands[0] = vkd3d_dxbc_compiler_get_constant_uint(compiler, 0); + coordinate_id = spirv_compiler_get_constant_uint(compiler, 0); + operands[0] = spirv_compiler_get_constant_uint(compiler, 0); operands[1] = coordinate_id; pointer_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, counter_id, operands, 2); @@ -8903,26 +8930,26 @@ static void vkd3d_dxbc_compiler_emit_uav_counter_instruction(struct vkd3d_dxbc_c else { ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassImage, type_id); - coordinate_id = sample_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, 0); + coordinate_id = sample_id = spirv_compiler_get_constant_uint(compiler, 0); pointer_id = vkd3d_spirv_build_op_image_texel_pointer(builder, ptr_type_id, counter_id, coordinate_id, sample_id); } operands[0] = pointer_id; - operands[1] = vkd3d_dxbc_compiler_get_constant_uint(compiler, SpvScopeDevice); - operands[2] = vkd3d_dxbc_compiler_get_constant_uint(compiler, memory_semantics); + operands[1] = spirv_compiler_get_constant_uint(compiler, SpvScopeDevice); + operands[2] = spirv_compiler_get_constant_uint(compiler, memory_semantics); result_id = vkd3d_spirv_build_op_trv(builder, &builder->function_stream, op, type_id, operands, ARRAY_SIZE(operands)); if (op == SpvOpAtomicIDecrement) { /* SpvOpAtomicIDecrement returns the original value. */ result_id = vkd3d_spirv_build_op_isub(builder, type_id, result_id, - vkd3d_dxbc_compiler_get_constant_uint(compiler, 1)); + spirv_compiler_get_constant_uint(compiler, 1)); } - vkd3d_dxbc_compiler_emit_store_dst(compiler, dst, result_id); + spirv_compiler_emit_store_dst(compiler, dst, result_id); } -static SpvOp vkd3d_dxbc_compiler_map_atomic_instruction(const struct vkd3d_shader_instruction *instruction) +static SpvOp spirv_compiler_map_atomic_instruction(const struct vkd3d_shader_instruction *instruction) { static const struct { @@ -8967,7 +8994,7 @@ static bool is_imm_atomic_instruction(enum vkd3d_shader_opcode handler_idx) return VKD3DSIH_IMM_ATOMIC_ALLOC <= handler_idx && handler_idx <= VKD3DSIH_IMM_ATOMIC_XOR; } -static void vkd3d_dxbc_compiler_emit_atomic_instruction(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -8990,7 +9017,7 @@ static void vkd3d_dxbc_compiler_emit_atomic_instruction(struct vkd3d_dxbc_compil resource = is_imm_atomic_instruction(instruction->handler_idx) ? &dst[1] : &dst[0]; - op = vkd3d_dxbc_compiler_map_atomic_instruction(instruction); + op = spirv_compiler_map_atomic_instruction(instruction); if (op == SpvOpMax) { ERR("Unexpected instruction %#x.\n", instruction->handler_idx); @@ -9001,7 +9028,7 @@ static void vkd3d_dxbc_compiler_emit_atomic_instruction(struct vkd3d_dxbc_compil { scope = SpvScopeWorkgroup; coordinate_mask = 1u; - if (!vkd3d_dxbc_compiler_get_register_info(compiler, &resource->reg, ®_info)) + if (!spirv_compiler_get_register_info(compiler, &resource->reg, ®_info)) return; structure_stride = reg_info.structure_stride; raw = !structure_stride; @@ -9009,9 +9036,9 @@ static void vkd3d_dxbc_compiler_emit_atomic_instruction(struct vkd3d_dxbc_compil else { scope = SpvScopeDevice; - resource_symbol = vkd3d_dxbc_compiler_find_resource(compiler, &resource->reg); + resource_symbol = spirv_compiler_find_resource(compiler, &resource->reg); - if (vkd3d_dxbc_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) + if (spirv_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) { coordinate_mask = VKD3DSP_WRITEMASK_0; structure_stride = resource_symbol->info.resource.structure_stride; @@ -9019,7 +9046,7 @@ static void vkd3d_dxbc_compiler_emit_atomic_instruction(struct vkd3d_dxbc_compil } else { - vkd3d_dxbc_compiler_prepare_image(compiler, &image, &resource->reg, NULL, VKD3D_IMAGE_FLAG_NO_LOAD); + spirv_compiler_prepare_image(compiler, &image, &resource->reg, NULL, VKD3D_IMAGE_FLAG_NO_LOAD); coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1; structure_stride = image.structure_stride; raw = image.raw; @@ -9030,14 +9057,14 @@ static void vkd3d_dxbc_compiler_emit_atomic_instruction(struct vkd3d_dxbc_compil if (structure_stride || raw) { assert(!raw != !structure_stride); - coordinate_id = vkd3d_dxbc_compiler_emit_raw_structured_addressing(compiler, + coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, type_id, structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[0], VKD3DSP_WRITEMASK_1); } else { assert(resource->reg.type != VKD3DSPR_GROUPSHAREDMEM); - coordinate_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], coordinate_mask); + coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], coordinate_mask); } if (resource->reg.type == VKD3DSPR_GROUPSHAREDMEM) @@ -9048,12 +9075,12 @@ static void vkd3d_dxbc_compiler_emit_atomic_instruction(struct vkd3d_dxbc_compil } else { - if (vkd3d_dxbc_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) + if (spirv_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) { component_type = resource_symbol->info.resource.sampled_type; type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); - operands[0] = vkd3d_dxbc_compiler_get_constant_uint(compiler, 0); + operands[0] = spirv_compiler_get_constant_uint(compiler, 0); operands[1] = coordinate_id; pointer_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, resource_symbol->id, operands, 2); } @@ -9062,31 +9089,31 @@ static void vkd3d_dxbc_compiler_emit_atomic_instruction(struct vkd3d_dxbc_compil component_type = image.sampled_type; type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassImage, type_id); - sample_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, 0); + sample_id = spirv_compiler_get_constant_uint(compiler, 0); pointer_id = vkd3d_spirv_build_op_image_texel_pointer(builder, ptr_type_id, image.id, coordinate_id, sample_id); } } - val_id = vkd3d_dxbc_compiler_emit_load_src_with_type(compiler, &src[1], VKD3DSP_WRITEMASK_0, component_type); + val_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1], VKD3DSP_WRITEMASK_0, component_type); operands[i++] = pointer_id; - operands[i++] = vkd3d_dxbc_compiler_get_constant_uint(compiler, scope); - operands[i++] = vkd3d_dxbc_compiler_get_constant_uint(compiler, SpvMemorySemanticsMaskNone); + operands[i++] = spirv_compiler_get_constant_uint(compiler, scope); + operands[i++] = spirv_compiler_get_constant_uint(compiler, SpvMemorySemanticsMaskNone); if (instruction->src_count >= 3) { - operands[i++] = vkd3d_dxbc_compiler_get_constant_uint(compiler, SpvMemorySemanticsMaskNone); - operands[i++] = vkd3d_dxbc_compiler_emit_load_src_with_type(compiler, &src[2], VKD3DSP_WRITEMASK_0, component_type); + operands[i++] = spirv_compiler_get_constant_uint(compiler, SpvMemorySemanticsMaskNone); + operands[i++] = spirv_compiler_emit_load_src_with_type(compiler, &src[2], VKD3DSP_WRITEMASK_0, component_type); } operands[i++] = val_id; result_id = vkd3d_spirv_build_op_trv(builder, &builder->function_stream, op, type_id, operands, i); if (is_imm_atomic_instruction(instruction->handler_idx)) - vkd3d_dxbc_compiler_emit_store_dst(compiler, dst, result_id); + spirv_compiler_emit_store_dst(compiler, dst, result_id); } -static void vkd3d_dxbc_compiler_emit_bufinfo(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -9100,7 +9127,7 @@ static void vkd3d_dxbc_compiler_emit_bufinfo(struct vkd3d_dxbc_compiler *compile if (compiler->ssbo_uavs && src->reg.type == VKD3DSPR_UAV) { - resource_symbol = vkd3d_dxbc_compiler_find_resource(compiler, &src->reg); + resource_symbol = spirv_compiler_find_resource(compiler, &src->reg); type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); val_id = vkd3d_spirv_build_op_array_length(builder, type_id, resource_symbol->id, 0); @@ -9110,7 +9137,7 @@ static void vkd3d_dxbc_compiler_emit_bufinfo(struct vkd3d_dxbc_compiler *compile { vkd3d_spirv_enable_capability(builder, SpvCapabilityImageQuery); - vkd3d_dxbc_compiler_prepare_image(compiler, &image, &src->reg, NULL, VKD3D_IMAGE_FLAG_NONE); + spirv_compiler_prepare_image(compiler, &image, &src->reg, NULL, VKD3D_IMAGE_FLAG_NONE); type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); val_id = vkd3d_spirv_build_op_image_query_size(builder, type_id, image.image_id); @@ -9119,7 +9146,7 @@ static void vkd3d_dxbc_compiler_emit_bufinfo(struct vkd3d_dxbc_compiler *compile if (image.structure_stride) { - stride_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, image.structure_stride); + stride_id = spirv_compiler_get_constant_uint(compiler, image.structure_stride); constituents[0] = vkd3d_spirv_build_op_udiv(builder, type_id, val_id, stride_id); constituents[1] = stride_id; type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, ARRAY_SIZE(constituents)); @@ -9130,15 +9157,15 @@ static void vkd3d_dxbc_compiler_emit_bufinfo(struct vkd3d_dxbc_compiler *compile else if (image.raw) { val_id = vkd3d_spirv_build_op_shift_left_logical(builder, type_id, - val_id, vkd3d_dxbc_compiler_get_constant_uint(compiler, 2)); + val_id, spirv_compiler_get_constant_uint(compiler, 2)); } - val_id = vkd3d_dxbc_compiler_emit_swizzle(compiler, val_id, write_mask, + val_id = spirv_compiler_emit_swizzle(compiler, val_id, write_mask, VKD3D_SHADER_COMPONENT_UINT, src->swizzle, dst->write_mask); - vkd3d_dxbc_compiler_emit_store_dst(compiler, dst, val_id); + spirv_compiler_emit_store_dst(compiler, dst, val_id); } -static void vkd3d_dxbc_compiler_emit_resinfo(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_resinfo(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -9152,7 +9179,7 @@ static void vkd3d_dxbc_compiler_emit_resinfo(struct vkd3d_dxbc_compiler *compile vkd3d_spirv_enable_capability(builder, SpvCapabilityImageQuery); - vkd3d_dxbc_compiler_prepare_image(compiler, &image, &src[1].reg, NULL, VKD3D_IMAGE_FLAG_NONE); + spirv_compiler_prepare_image(compiler, &image, &src[1].reg, NULL, VKD3D_IMAGE_FLAG_NONE); size_component_count = image.resource_type_info->coordinate_component_count; if (image.resource_type_info->dim == SpvDimCube) --size_component_count; @@ -9161,7 +9188,7 @@ static void vkd3d_dxbc_compiler_emit_resinfo(struct vkd3d_dxbc_compiler *compile supports_mipmaps = src[1].reg.type != VKD3DSPR_UAV && !image.resource_type_info->ms; if (supports_mipmaps) { - lod_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0); + lod_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0); val_id = vkd3d_spirv_build_op_image_query_size_lod(builder, type_id, image.image_id, lod_id); type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); miplevel_count_id = vkd3d_spirv_build_op_image_query_levels(builder, type_id, image.image_id); @@ -9170,12 +9197,12 @@ static void vkd3d_dxbc_compiler_emit_resinfo(struct vkd3d_dxbc_compiler *compile { val_id = vkd3d_spirv_build_op_image_query_size(builder, type_id, image.image_id); /* For UAVs the returned miplevel count is always 1. */ - miplevel_count_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, 1); + miplevel_count_id = spirv_compiler_get_constant_uint(compiler, 1); } constituents[0] = val_id; for (i = 0; i < 3 - size_component_count; ++i) - constituents[i + 1] = vkd3d_dxbc_compiler_get_constant_uint(compiler, 0); + constituents[i + 1] = spirv_compiler_get_constant_uint(compiler, 0); constituents[i + 1] = miplevel_count_id; type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE); val_id = vkd3d_spirv_build_op_composite_construct(builder, @@ -9192,13 +9219,13 @@ static void vkd3d_dxbc_compiler_emit_resinfo(struct vkd3d_dxbc_compiler *compile FIXME("Unhandled flags %#x.\n", instruction->flags); val_id = vkd3d_spirv_build_op_convert_utof(builder, type_id, val_id); } - val_id = vkd3d_dxbc_compiler_emit_swizzle(compiler, val_id, VKD3DSP_WRITEMASK_ALL, + val_id = spirv_compiler_emit_swizzle(compiler, val_id, VKD3DSP_WRITEMASK_ALL, VKD3D_SHADER_COMPONENT_FLOAT, src[1].swizzle, dst->write_mask); - vkd3d_dxbc_compiler_emit_store_dst(compiler, dst, val_id); + spirv_compiler_emit_store_dst(compiler, dst, val_id); } -static uint32_t vkd3d_dxbc_compiler_emit_query_sample_count(struct vkd3d_dxbc_compiler *compiler, +static uint32_t spirv_compiler_emit_query_sample_count(struct spirv_compiler *compiler, const struct vkd3d_shader_src_param *src) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -9207,14 +9234,14 @@ static uint32_t vkd3d_dxbc_compiler_emit_query_sample_count(struct vkd3d_dxbc_co if (src->reg.type == VKD3DSPR_RASTERIZER) { - val_id = vkd3d_dxbc_compiler_emit_uint_shader_parameter(compiler, + val_id = spirv_compiler_emit_uint_shader_parameter(compiler, VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT); } else { vkd3d_spirv_enable_capability(builder, SpvCapabilityImageQuery); - vkd3d_dxbc_compiler_prepare_image(compiler, &image, &src->reg, NULL, VKD3D_IMAGE_FLAG_NONE); + spirv_compiler_prepare_image(compiler, &image, &src->reg, NULL, VKD3D_IMAGE_FLAG_NONE); type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); val_id = vkd3d_spirv_build_op_image_query_samples(builder, type_id, image.image_id); } @@ -9222,7 +9249,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_query_sample_count(struct vkd3d_dxbc_co return val_id; } -static void vkd3d_dxbc_compiler_emit_sample_info(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_sample_info(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -9232,11 +9259,11 @@ static void vkd3d_dxbc_compiler_emit_sample_info(struct vkd3d_dxbc_compiler *com uint32_t type_id, val_id; unsigned int i; - val_id = vkd3d_dxbc_compiler_emit_query_sample_count(compiler, src); + val_id = spirv_compiler_emit_query_sample_count(compiler, src); constituents[0] = val_id; for (i = 1; i < VKD3D_VEC4_SIZE; ++i) - constituents[i] = vkd3d_dxbc_compiler_get_constant_uint(compiler, 0); + constituents[i] = spirv_compiler_get_constant_uint(compiler, 0); type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE); val_id = vkd3d_spirv_build_op_composite_construct(builder, type_id, constituents, VKD3D_VEC4_SIZE); @@ -9252,14 +9279,14 @@ static void vkd3d_dxbc_compiler_emit_sample_info(struct vkd3d_dxbc_compiler *com val_id = vkd3d_spirv_build_op_convert_utof(builder, type_id, val_id); } - val_id = vkd3d_dxbc_compiler_emit_swizzle(compiler, val_id, VKD3DSP_WRITEMASK_ALL, + val_id = spirv_compiler_emit_swizzle(compiler, val_id, VKD3DSP_WRITEMASK_ALL, VKD3D_SHADER_COMPONENT_FLOAT, src->swizzle, dst->write_mask); - vkd3d_dxbc_compiler_emit_store_dst(compiler, dst, val_id); + spirv_compiler_emit_store_dst(compiler, dst, val_id); } /* XXX: This is correct only when standard sample positions are used. */ -static void vkd3d_dxbc_compiler_emit_sample_position(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_sample_position(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { /* Standard sample locations from the Vulkan spec. */ @@ -9310,32 +9337,32 @@ static void vkd3d_dxbc_compiler_emit_sample_position(struct vkd3d_dxbc_compiler uint32_t type_id, bool_id, ptr_type_id; unsigned int i; - sample_count_id = vkd3d_dxbc_compiler_emit_query_sample_count(compiler, &instruction->src[0]); - sample_index_id = vkd3d_dxbc_compiler_emit_load_src(compiler, &instruction->src[1], VKD3DSP_WRITEMASK_0); + sample_count_id = spirv_compiler_emit_query_sample_count(compiler, &instruction->src[0]); + sample_index_id = spirv_compiler_emit_load_src(compiler, &instruction->src[1], VKD3DSP_WRITEMASK_0); type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); index_id = vkd3d_spirv_build_op_iadd(builder, type_id, sample_count_id, sample_index_id); index_id = vkd3d_spirv_build_op_isub(builder, - type_id, index_id, vkd3d_dxbc_compiler_get_constant_uint(compiler, 1)); + type_id, index_id, spirv_compiler_get_constant_uint(compiler, 1)); /* Validate sample index. */ bool_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, 1); id = vkd3d_spirv_build_op_logical_and(builder, bool_id, vkd3d_spirv_build_op_uless_than(builder, bool_id, sample_index_id, sample_count_id), vkd3d_spirv_build_op_uless_than_equal(builder, - bool_id, sample_index_id, vkd3d_dxbc_compiler_get_constant_uint(compiler, 16))); + bool_id, sample_index_id, spirv_compiler_get_constant_uint(compiler, 16))); index_id = vkd3d_spirv_build_op_select(builder, type_id, - id, index_id, vkd3d_dxbc_compiler_get_constant_uint(compiler, 0)); + id, index_id, spirv_compiler_get_constant_uint(compiler, 0)); type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); if (!(id = compiler->sample_positions_id)) { - length_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, ARRAY_SIZE(standard_sample_positions)); + length_id = spirv_compiler_get_constant_uint(compiler, ARRAY_SIZE(standard_sample_positions)); array_type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id); for (i = 0; i < ARRAY_SIZE(standard_sample_positions); ++ i) { - constituents[i] = vkd3d_dxbc_compiler_get_constant(compiler, + constituents[i] = spirv_compiler_get_constant(compiler, VKD3D_SHADER_COMPONENT_FLOAT, 2, (const uint32_t *)standard_sample_positions[i]); } @@ -9350,12 +9377,12 @@ static void vkd3d_dxbc_compiler_emit_sample_position(struct vkd3d_dxbc_compiler id = vkd3d_spirv_build_op_in_bounds_access_chain1(builder, ptr_type_id, id, index_id); id = vkd3d_spirv_build_op_load(builder, type_id, id, SpvMemoryAccessMaskNone); - id = vkd3d_dxbc_compiler_emit_swizzle(compiler, id, VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1, + id = spirv_compiler_emit_swizzle(compiler, id, VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1, VKD3D_SHADER_COMPONENT_FLOAT, instruction->src[0].swizzle, dst->write_mask); - vkd3d_dxbc_compiler_emit_store_dst(compiler, dst, id); + spirv_compiler_emit_store_dst(compiler, dst, id); } -static void vkd3d_dxbc_compiler_emit_eval_attrib(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_eval_attrib(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -9367,7 +9394,7 @@ static void vkd3d_dxbc_compiler_emit_eval_attrib(struct vkd3d_dxbc_compiler *com unsigned int src_count = 0; enum GLSLstd450 op; - if (!vkd3d_dxbc_compiler_get_register_info(compiler, input, ®ister_info)) + if (!spirv_compiler_get_register_info(compiler, input, ®ister_info)) return; if (register_info.storage_class != SpvStorageClassInput) @@ -9388,7 +9415,7 @@ static void vkd3d_dxbc_compiler_emit_eval_attrib(struct vkd3d_dxbc_compiler *com { assert(instruction->handler_idx == VKD3DSIH_EVAL_SAMPLE_INDEX); op = GLSLstd450InterpolateAtSample; - src_ids[src_count++] = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[1], VKD3DSP_WRITEMASK_0); + src_ids[src_count++] = spirv_compiler_emit_load_src(compiler, &src[1], VKD3DSP_WRITEMASK_0); } type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, @@ -9397,10 +9424,10 @@ static void vkd3d_dxbc_compiler_emit_eval_attrib(struct vkd3d_dxbc_compiler *com instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder); val_id = vkd3d_spirv_build_op_ext_inst(builder, type_id, instr_set_id, op, src_ids, src_count); - val_id = vkd3d_dxbc_compiler_emit_swizzle(compiler, val_id, register_info.write_mask, + val_id = spirv_compiler_emit_swizzle(compiler, val_id, register_info.write_mask, VKD3D_SHADER_COMPONENT_FLOAT, src[0].swizzle, dst->write_mask); - vkd3d_dxbc_compiler_emit_store_dst(compiler, dst, val_id); + spirv_compiler_emit_store_dst(compiler, dst, val_id); } /* From the Vulkan spec: @@ -9409,7 +9436,7 @@ static void vkd3d_dxbc_compiler_emit_eval_attrib(struct vkd3d_dxbc_compiler *com * * "Scope for memory must be limited to: * Device * Workgroup * Invocation" */ -static void vkd3d_dxbc_compiler_emit_sync(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_sync(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { unsigned int memory_semantics = SpvMemorySemanticsAcquireReleaseMask; @@ -9450,10 +9477,10 @@ static void vkd3d_dxbc_compiler_emit_sync(struct vkd3d_dxbc_compiler *compiler, | SpvMemorySemanticsImageMemoryMask; } - vkd3d_dxbc_compiler_emit_barrier(compiler, execution_scope, memory_scope, memory_semantics); + spirv_compiler_emit_barrier(compiler, execution_scope, memory_scope, memory_semantics); } -static void vkd3d_dxbc_compiler_emit_emit_stream(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_emit_stream(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -9470,11 +9497,11 @@ static void vkd3d_dxbc_compiler_emit_emit_stream(struct vkd3d_dxbc_compiler *com return; } - vkd3d_dxbc_compiler_emit_shader_epilogue_invocation(compiler); + spirv_compiler_emit_shader_epilogue_invocation(compiler); vkd3d_spirv_build_op_emit_vertex(builder); } -static void vkd3d_dxbc_compiler_emit_cut_stream(struct vkd3d_dxbc_compiler *compiler, +static void spirv_compiler_emit_cut_stream(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -9494,7 +9521,7 @@ static void vkd3d_dxbc_compiler_emit_cut_stream(struct vkd3d_dxbc_compiler *comp vkd3d_spirv_build_op_end_primitive(builder); } -static void vkd3d_dxbc_compiler_emit_hull_shader_inputs(struct vkd3d_dxbc_compiler *compiler) +static void spirv_compiler_emit_hull_shader_inputs(struct spirv_compiler *compiler) { const struct vkd3d_shader_signature *signature = compiler->input_signature; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -9502,7 +9529,7 @@ static void vkd3d_dxbc_compiler_emit_hull_shader_inputs(struct vkd3d_dxbc_compil unsigned int register_count, register_idx, i; struct vkd3d_shader_register r; struct vkd3d_symbol symbol; - struct wine_rb_entry *entry; + struct rb_entry *entry; for (i = 0, register_count = 0; i < signature->element_count; ++i) { @@ -9510,9 +9537,9 @@ static void vkd3d_dxbc_compiler_emit_hull_shader_inputs(struct vkd3d_dxbc_compil } type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 4); - length_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, compiler->input_control_point_count); + length_id = spirv_compiler_get_constant_uint(compiler, compiler->input_control_point_count); type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id); - length_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, register_count); + length_id = spirv_compiler_get_constant_uint(compiler, register_count); type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id); vicp_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPrivate, type_id); @@ -9531,9 +9558,9 @@ static void vkd3d_dxbc_compiler_emit_hull_shader_inputs(struct vkd3d_dxbc_compil register_idx = signature->elements[i].register_index; symbol.key.reg.idx = register_idx; - if ((entry = wine_rb_get(&compiler->symbol_table, &symbol))) + if ((entry = rb_get(&compiler->symbol_table, &symbol))) { - struct vkd3d_symbol *s = WINE_RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); + struct vkd3d_symbol *s = RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); s->info.reg.dcl_mask |= signature->elements[i].mask; continue; } @@ -9542,20 +9569,20 @@ static void vkd3d_dxbc_compiler_emit_hull_shader_inputs(struct vkd3d_dxbc_compil VKD3D_SHADER_COMPONENT_FLOAT, VKD3DSP_WRITEMASK_ALL); symbol.info.reg.dcl_mask = signature->elements[i].mask; symbol.info.reg.is_aggregate = true; - vkd3d_dxbc_compiler_put_symbol(compiler, &symbol); + spirv_compiler_put_symbol(compiler, &symbol); } } /* This function is called after declarations are processed. */ -static void vkd3d_dxbc_compiler_emit_main_prolog(struct vkd3d_dxbc_compiler *compiler) +static void spirv_compiler_emit_main_prolog(struct spirv_compiler *compiler) { - vkd3d_dxbc_compiler_emit_push_constant_buffers(compiler); + spirv_compiler_emit_push_constant_buffers(compiler); if (compiler->xfb_info && compiler->xfb_info->element_count && compiler->shader_type != VKD3D_SHADER_TYPE_GEOMETRY) - vkd3d_dxbc_compiler_emit_point_size(compiler); + spirv_compiler_emit_point_size(compiler); if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL) - vkd3d_dxbc_compiler_emit_hull_shader_inputs(compiler); + spirv_compiler_emit_hull_shader_inputs(compiler); } static bool is_dcl_instruction(enum vkd3d_shader_opcode handler_idx) @@ -9564,7 +9591,7 @@ static bool is_dcl_instruction(enum vkd3d_shader_opcode handler_idx) || handler_idx == VKD3DSIH_HS_DECLS; } -int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler, +static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { int ret = VKD3D_OK; @@ -9572,125 +9599,125 @@ int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler, if (!is_dcl_instruction(instruction->handler_idx) && !compiler->after_declarations_section) { compiler->after_declarations_section = true; - vkd3d_dxbc_compiler_emit_main_prolog(compiler); + spirv_compiler_emit_main_prolog(compiler); } switch (instruction->handler_idx) { case VKD3DSIH_DCL_GLOBAL_FLAGS: - vkd3d_dxbc_compiler_emit_dcl_global_flags(compiler, instruction); + spirv_compiler_emit_dcl_global_flags(compiler, instruction); break; case VKD3DSIH_DCL_TEMPS: - vkd3d_dxbc_compiler_emit_dcl_temps(compiler, instruction); + spirv_compiler_emit_dcl_temps(compiler, instruction); break; case VKD3DSIH_DCL_INDEXABLE_TEMP: - vkd3d_dxbc_compiler_emit_dcl_indexable_temp(compiler, instruction); + spirv_compiler_emit_dcl_indexable_temp(compiler, instruction); break; case VKD3DSIH_DCL_CONSTANT_BUFFER: - vkd3d_dxbc_compiler_emit_dcl_constant_buffer(compiler, instruction); + spirv_compiler_emit_dcl_constant_buffer(compiler, instruction); break; case VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER: - vkd3d_dxbc_compiler_emit_dcl_immediate_constant_buffer(compiler, instruction); + spirv_compiler_emit_dcl_immediate_constant_buffer(compiler, instruction); break; case VKD3DSIH_DCL_SAMPLER: - vkd3d_dxbc_compiler_emit_dcl_sampler(compiler, instruction); + spirv_compiler_emit_dcl_sampler(compiler, instruction); break; case VKD3DSIH_DCL: case VKD3DSIH_DCL_UAV_TYPED: - vkd3d_dxbc_compiler_emit_dcl_resource(compiler, instruction); + spirv_compiler_emit_dcl_resource(compiler, instruction); break; case VKD3DSIH_DCL_RESOURCE_RAW: case VKD3DSIH_DCL_UAV_RAW: - vkd3d_dxbc_compiler_emit_dcl_resource_raw(compiler, instruction); + spirv_compiler_emit_dcl_resource_raw(compiler, instruction); break; case VKD3DSIH_DCL_RESOURCE_STRUCTURED: case VKD3DSIH_DCL_UAV_STRUCTURED: - vkd3d_dxbc_compiler_emit_dcl_resource_structured(compiler, instruction); + spirv_compiler_emit_dcl_resource_structured(compiler, instruction); break; case VKD3DSIH_DCL_TGSM_RAW: - vkd3d_dxbc_compiler_emit_dcl_tgsm_raw(compiler, instruction); + spirv_compiler_emit_dcl_tgsm_raw(compiler, instruction); break; case VKD3DSIH_DCL_TGSM_STRUCTURED: - vkd3d_dxbc_compiler_emit_dcl_tgsm_structured(compiler, instruction); + spirv_compiler_emit_dcl_tgsm_structured(compiler, instruction); break; case VKD3DSIH_DCL_INPUT: - vkd3d_dxbc_compiler_emit_dcl_input(compiler, instruction); + spirv_compiler_emit_dcl_input(compiler, instruction); break; case VKD3DSIH_DCL_INPUT_PS: - vkd3d_dxbc_compiler_emit_dcl_input_ps(compiler, instruction); + spirv_compiler_emit_dcl_input_ps(compiler, instruction); break; case VKD3DSIH_DCL_INPUT_PS_SGV: case VKD3DSIH_DCL_INPUT_PS_SIV: - vkd3d_dxbc_compiler_emit_dcl_input_ps_sysval(compiler, instruction); + spirv_compiler_emit_dcl_input_ps_sysval(compiler, instruction); break; case VKD3DSIH_DCL_INPUT_SGV: case VKD3DSIH_DCL_INPUT_SIV: - vkd3d_dxbc_compiler_emit_dcl_input_sysval(compiler, instruction); + spirv_compiler_emit_dcl_input_sysval(compiler, instruction); break; case VKD3DSIH_DCL_OUTPUT: - vkd3d_dxbc_compiler_emit_dcl_output(compiler, instruction); + spirv_compiler_emit_dcl_output(compiler, instruction); break; case VKD3DSIH_DCL_OUTPUT_SIV: - vkd3d_dxbc_compiler_emit_dcl_output_siv(compiler, instruction); + spirv_compiler_emit_dcl_output_siv(compiler, instruction); break; case VKD3DSIH_DCL_INDEX_RANGE: - vkd3d_dxbc_compiler_emit_dcl_index_range(compiler, instruction); + spirv_compiler_emit_dcl_index_range(compiler, instruction); break; case VKD3DSIH_DCL_STREAM: - vkd3d_dxbc_compiler_emit_dcl_stream(compiler, instruction); + spirv_compiler_emit_dcl_stream(compiler, instruction); break; case VKD3DSIH_DCL_VERTICES_OUT: - vkd3d_dxbc_compiler_emit_output_vertex_count(compiler, instruction); + spirv_compiler_emit_output_vertex_count(compiler, instruction); break; case VKD3DSIH_DCL_INPUT_PRIMITIVE: - vkd3d_dxbc_compiler_emit_dcl_input_primitive(compiler, instruction); + spirv_compiler_emit_dcl_input_primitive(compiler, instruction); break; case VKD3DSIH_DCL_OUTPUT_TOPOLOGY: - vkd3d_dxbc_compiler_emit_dcl_output_topology(compiler, instruction); + spirv_compiler_emit_dcl_output_topology(compiler, instruction); break; case VKD3DSIH_DCL_GS_INSTANCES: - vkd3d_dxbc_compiler_emit_dcl_gs_instances(compiler, instruction); + spirv_compiler_emit_dcl_gs_instances(compiler, instruction); break; case VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT: compiler->input_control_point_count = instruction->declaration.count; break; case VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT: compiler->output_control_point_count = instruction->declaration.count; - vkd3d_dxbc_compiler_emit_output_vertex_count(compiler, instruction); + spirv_compiler_emit_output_vertex_count(compiler, instruction); break; case VKD3DSIH_DCL_TESSELLATOR_DOMAIN: - vkd3d_dxbc_compiler_emit_dcl_tessellator_domain(compiler, instruction); + spirv_compiler_emit_dcl_tessellator_domain(compiler, instruction); break; case VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE: - vkd3d_dxbc_compiler_emit_tessellator_output_primitive(compiler, + spirv_compiler_emit_tessellator_output_primitive(compiler, instruction->declaration.tessellator_output_primitive); break; case VKD3DSIH_DCL_TESSELLATOR_PARTITIONING: - vkd3d_dxbc_compiler_emit_tessellator_partitioning(compiler, + spirv_compiler_emit_tessellator_partitioning(compiler, instruction->declaration.tessellator_partitioning); break; case VKD3DSIH_DCL_THREAD_GROUP: - vkd3d_dxbc_compiler_emit_dcl_thread_group(compiler, instruction); + spirv_compiler_emit_dcl_thread_group(compiler, instruction); break; case VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT: case VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT: - ret = vkd3d_dxbc_compiler_emit_shader_phase_instance_count(compiler, instruction); + ret = spirv_compiler_emit_shader_phase_instance_count(compiler, instruction); break; case VKD3DSIH_HS_CONTROL_POINT_PHASE: case VKD3DSIH_HS_FORK_PHASE: case VKD3DSIH_HS_JOIN_PHASE: - vkd3d_dxbc_compiler_enter_shader_phase(compiler, instruction); + spirv_compiler_enter_shader_phase(compiler, instruction); break; case VKD3DSIH_DMOV: case VKD3DSIH_MOV: - vkd3d_dxbc_compiler_emit_mov(compiler, instruction); + spirv_compiler_emit_mov(compiler, instruction); break; case VKD3DSIH_DMOVC: case VKD3DSIH_MOVC: - vkd3d_dxbc_compiler_emit_movc(compiler, instruction); + spirv_compiler_emit_movc(compiler, instruction); break; case VKD3DSIH_SWAPC: - vkd3d_dxbc_compiler_emit_swapc(compiler, instruction); + spirv_compiler_emit_swapc(compiler, instruction); break; case VKD3DSIH_ADD: case VKD3DSIH_AND: @@ -9719,7 +9746,7 @@ int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler, case VKD3DSIH_UTOD: case VKD3DSIH_UTOF: case VKD3DSIH_XOR: - vkd3d_dxbc_compiler_emit_alu_instruction(compiler, instruction); + spirv_compiler_emit_alu_instruction(compiler, instruction); break; case VKD3DSIH_DFMA: case VKD3DSIH_DMAX: @@ -9743,28 +9770,28 @@ int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler, case VKD3DSIH_SQRT: case VKD3DSIH_UMAX: case VKD3DSIH_UMIN: - vkd3d_dxbc_compiler_emit_ext_glsl_instruction(compiler, instruction); + spirv_compiler_emit_ext_glsl_instruction(compiler, instruction); break; case VKD3DSIH_DP4: case VKD3DSIH_DP3: case VKD3DSIH_DP2: - vkd3d_dxbc_compiler_emit_dot(compiler, instruction); + spirv_compiler_emit_dot(compiler, instruction); break; case VKD3DSIH_DRCP: case VKD3DSIH_RCP: - vkd3d_dxbc_compiler_emit_rcp(compiler, instruction); + spirv_compiler_emit_rcp(compiler, instruction); break; case VKD3DSIH_SINCOS: - vkd3d_dxbc_compiler_emit_sincos(compiler, instruction); + spirv_compiler_emit_sincos(compiler, instruction); break; case VKD3DSIH_IMUL: - vkd3d_dxbc_compiler_emit_imul(compiler, instruction); + spirv_compiler_emit_imul(compiler, instruction); break; case VKD3DSIH_IMAD: - vkd3d_dxbc_compiler_emit_imad(compiler, instruction); + spirv_compiler_emit_imad(compiler, instruction); break; case VKD3DSIH_UDIV: - vkd3d_dxbc_compiler_emit_udiv(compiler, instruction); + spirv_compiler_emit_udiv(compiler, instruction); break; case VKD3DSIH_DEQ: case VKD3DSIH_DGE: @@ -9780,18 +9807,18 @@ int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler, case VKD3DSIH_NE: case VKD3DSIH_UGE: case VKD3DSIH_ULT: - vkd3d_dxbc_compiler_emit_comparison_instruction(compiler, instruction); + spirv_compiler_emit_comparison_instruction(compiler, instruction); break; case VKD3DSIH_BFI: case VKD3DSIH_IBFE: case VKD3DSIH_UBFE: - vkd3d_dxbc_compiler_emit_bitfield_instruction(compiler, instruction); + spirv_compiler_emit_bitfield_instruction(compiler, instruction); break; case VKD3DSIH_F16TOF32: - vkd3d_dxbc_compiler_emit_f16tof32(compiler, instruction); + spirv_compiler_emit_f16tof32(compiler, instruction); break; case VKD3DSIH_F32TOF16: - vkd3d_dxbc_compiler_emit_f32tof16(compiler, instruction); + spirv_compiler_emit_f32tof16(compiler, instruction); break; case VKD3DSIH_BREAK: case VKD3DSIH_BREAKP: @@ -9809,7 +9836,7 @@ int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler, case VKD3DSIH_RETP: case VKD3DSIH_SWITCH: case VKD3DSIH_TEXKILL: - ret = vkd3d_dxbc_compiler_emit_control_flow_instruction(compiler, instruction); + ret = spirv_compiler_emit_control_flow_instruction(compiler, instruction); break; case VKD3DSIH_DSX: case VKD3DSIH_DSX_COARSE: @@ -9817,48 +9844,48 @@ int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler, case VKD3DSIH_DSY: case VKD3DSIH_DSY_COARSE: case VKD3DSIH_DSY_FINE: - vkd3d_dxbc_compiler_emit_deriv_instruction(compiler, instruction); + spirv_compiler_emit_deriv_instruction(compiler, instruction); break; case VKD3DSIH_LD2DMS: case VKD3DSIH_LD: - vkd3d_dxbc_compiler_emit_ld(compiler, instruction); + spirv_compiler_emit_ld(compiler, instruction); break; case VKD3DSIH_LOD: - vkd3d_dxbc_compiler_emit_lod(compiler, instruction); + spirv_compiler_emit_lod(compiler, instruction); break; case VKD3DSIH_SAMPLE: case VKD3DSIH_SAMPLE_B: case VKD3DSIH_SAMPLE_GRAD: case VKD3DSIH_SAMPLE_LOD: - vkd3d_dxbc_compiler_emit_sample(compiler, instruction); + spirv_compiler_emit_sample(compiler, instruction); break; case VKD3DSIH_SAMPLE_C: case VKD3DSIH_SAMPLE_C_LZ: - vkd3d_dxbc_compiler_emit_sample_c(compiler, instruction); + spirv_compiler_emit_sample_c(compiler, instruction); break; case VKD3DSIH_GATHER4: case VKD3DSIH_GATHER4_C: case VKD3DSIH_GATHER4_PO: case VKD3DSIH_GATHER4_PO_C: - vkd3d_dxbc_compiler_emit_gather4(compiler, instruction); + spirv_compiler_emit_gather4(compiler, instruction); break; case VKD3DSIH_LD_RAW: case VKD3DSIH_LD_STRUCTURED: - vkd3d_dxbc_compiler_emit_ld_raw_structured(compiler, instruction); + spirv_compiler_emit_ld_raw_structured(compiler, instruction); break; case VKD3DSIH_STORE_RAW: case VKD3DSIH_STORE_STRUCTURED: - vkd3d_dxbc_compiler_emit_store_raw_structured(compiler, instruction); + spirv_compiler_emit_store_raw_structured(compiler, instruction); break; case VKD3DSIH_LD_UAV_TYPED: - vkd3d_dxbc_compiler_emit_ld_uav_typed(compiler, instruction); + spirv_compiler_emit_ld_uav_typed(compiler, instruction); break; case VKD3DSIH_STORE_UAV_TYPED: - vkd3d_dxbc_compiler_emit_store_uav_typed(compiler, instruction); + spirv_compiler_emit_store_uav_typed(compiler, instruction); break; case VKD3DSIH_IMM_ATOMIC_ALLOC: case VKD3DSIH_IMM_ATOMIC_CONSUME: - vkd3d_dxbc_compiler_emit_uav_counter_instruction(compiler, instruction); + spirv_compiler_emit_uav_counter_instruction(compiler, instruction); break; case VKD3DSIH_ATOMIC_AND: case VKD3DSIH_ATOMIC_CMP_STORE: @@ -9879,34 +9906,34 @@ int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler, case VKD3DSIH_IMM_ATOMIC_UMAX: case VKD3DSIH_IMM_ATOMIC_UMIN: case VKD3DSIH_IMM_ATOMIC_XOR: - vkd3d_dxbc_compiler_emit_atomic_instruction(compiler, instruction); + spirv_compiler_emit_atomic_instruction(compiler, instruction); break; case VKD3DSIH_BUFINFO: - vkd3d_dxbc_compiler_emit_bufinfo(compiler, instruction); + spirv_compiler_emit_bufinfo(compiler, instruction); break; case VKD3DSIH_RESINFO: - vkd3d_dxbc_compiler_emit_resinfo(compiler, instruction); + spirv_compiler_emit_resinfo(compiler, instruction); break; case VKD3DSIH_SAMPLE_INFO: - vkd3d_dxbc_compiler_emit_sample_info(compiler, instruction); + spirv_compiler_emit_sample_info(compiler, instruction); break; case VKD3DSIH_SAMPLE_POS: - vkd3d_dxbc_compiler_emit_sample_position(compiler, instruction); + spirv_compiler_emit_sample_position(compiler, instruction); break; case VKD3DSIH_EVAL_CENTROID: case VKD3DSIH_EVAL_SAMPLE_INDEX: - vkd3d_dxbc_compiler_emit_eval_attrib(compiler, instruction); + spirv_compiler_emit_eval_attrib(compiler, instruction); break; case VKD3DSIH_SYNC: - vkd3d_dxbc_compiler_emit_sync(compiler, instruction); + spirv_compiler_emit_sync(compiler, instruction); break; case VKD3DSIH_EMIT: case VKD3DSIH_EMIT_STREAM: - vkd3d_dxbc_compiler_emit_emit_stream(compiler, instruction); + spirv_compiler_emit_emit_stream(compiler, instruction); break; case VKD3DSIH_CUT: case VKD3DSIH_CUT_STREAM: - vkd3d_dxbc_compiler_emit_cut_stream(compiler, instruction); + spirv_compiler_emit_cut_stream(compiler, instruction); break; case VKD3DSIH_DCL_HS_MAX_TESSFACTOR: case VKD3DSIH_HS_DECLS: @@ -9920,30 +9947,42 @@ int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler, return ret; } -int vkd3d_dxbc_compiler_generate_spirv(struct vkd3d_dxbc_compiler *compiler, - const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *spirv) +int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, + const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_parser *parser, + struct vkd3d_shader_code *spirv) { + const struct vkd3d_shader_instruction_array *instructions = &parser->instructions; const struct vkd3d_shader_spirv_target_info *info = compiler->spirv_target_info; const struct vkd3d_shader_spirv_domain_shader_target_info *ds_info; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; const struct vkd3d_shader_phase *phase; + enum vkd3d_result result = VKD3D_OK; + unsigned int i; + + compiler->location.column = 0; + for (i = 0; i < instructions->count; ++i) + { + compiler->location.line = i + 1; + if ((result = spirv_compiler_handle_instruction(compiler, &instructions->elements[i])) < 0) + return result; + } - if ((phase = vkd3d_dxbc_compiler_get_current_shader_phase(compiler))) - vkd3d_dxbc_compiler_leave_shader_phase(compiler, phase); + if ((phase = spirv_compiler_get_current_shader_phase(compiler))) + spirv_compiler_leave_shader_phase(compiler, phase); else vkd3d_spirv_build_op_function_end(builder); if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL) - vkd3d_dxbc_compiler_emit_hull_shader_main(compiler); + spirv_compiler_emit_hull_shader_main(compiler); if (compiler->shader_type == VKD3D_SHADER_TYPE_DOMAIN) { if (info && (ds_info = vkd3d_find_struct(compile_info->next, SPIRV_DOMAIN_SHADER_TARGET_INFO))) { - vkd3d_dxbc_compiler_emit_tessellator_output_primitive(compiler, ds_info->output_primitive); - vkd3d_dxbc_compiler_emit_tessellator_partitioning(compiler, ds_info->partitioning); + spirv_compiler_emit_tessellator_output_primitive(compiler, ds_info->output_primitive); + spirv_compiler_emit_tessellator_partitioning(compiler, ds_info->partitioning); } - else if (vkd3d_dxbc_compiler_is_opengl_target(compiler)) + else if (spirv_compiler_is_opengl_target(compiler)) { ERR("vkd3d_shader_spirv_domain_shader_target_info is required for " "OpenGL tessellation evaluation shader.\n"); @@ -9953,18 +9992,18 @@ int vkd3d_dxbc_compiler_generate_spirv(struct vkd3d_dxbc_compiler *compiler, if (compiler->epilogue_function_id) { vkd3d_spirv_build_op_name(builder, compiler->epilogue_function_id, "epilogue"); - vkd3d_dxbc_compiler_emit_shader_epilogue_function(compiler); + spirv_compiler_emit_shader_epilogue_function(compiler); } if (compiler->strip_debug) vkd3d_spirv_stream_clear(&builder->debug_stream); - if (!vkd3d_spirv_compile_module(builder, spirv, vkd3d_dxbc_compiler_get_entry_point_name(compiler))) + if (!vkd3d_spirv_compile_module(builder, spirv, spirv_compiler_get_entry_point_name(compiler))) return VKD3D_ERROR; if (TRACE_ON()) { - enum vkd3d_shader_spirv_environment environment = vkd3d_dxbc_compiler_get_target_environment(compiler); + enum vkd3d_shader_spirv_environment environment = spirv_compiler_get_target_environment(compiler); vkd3d_spirv_dump(spirv, environment); vkd3d_spirv_validate(spirv, environment); } @@ -9975,7 +10014,7 @@ int vkd3d_dxbc_compiler_generate_spirv(struct vkd3d_dxbc_compiler *compiler, if (compile_info->target_type == VKD3D_SHADER_TARGET_SPIRV_TEXT) { struct vkd3d_shader_code text; - enum vkd3d_shader_spirv_environment environment = vkd3d_dxbc_compiler_get_target_environment(compiler); + enum vkd3d_shader_spirv_environment environment = spirv_compiler_get_target_environment(compiler); if (vkd3d_spirv_binary_to_text(spirv, environment, compiler->formatting, &text) != VKD3D_OK) return VKD3D_ERROR; *spirv = text; @@ -9984,7 +10023,7 @@ int vkd3d_dxbc_compiler_generate_spirv(struct vkd3d_dxbc_compiler *compiler, return VKD3D_OK; } -void vkd3d_dxbc_compiler_destroy(struct vkd3d_dxbc_compiler *compiler) +void spirv_compiler_destroy(struct spirv_compiler *compiler) { vkd3d_free(compiler->control_flow_info); @@ -9995,7 +10034,7 @@ void vkd3d_dxbc_compiler_destroy(struct vkd3d_dxbc_compiler *compiler) vkd3d_spirv_builder_free(&compiler->spirv_builder); - wine_rb_destroy(&compiler->symbol_table, vkd3d_symbol_free, NULL); + rb_destroy(&compiler->symbol_table, vkd3d_symbol_free, NULL); vkd3d_free(compiler->shader_phases); vkd3d_free(compiler->spec_constants); diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/trace.c b/dll/directx/wine/vkd3d/libs/vkd3d-shader/trace.c similarity index 99% rename from dll/directx/wine/d3d12/vkd3d/vkd3d-shader/trace.c rename to dll/directx/wine/vkd3d/libs/vkd3d-shader/trace.c index c292c84714703..6cd2dcb270c92 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/trace.c +++ b/dll/directx/wine/vkd3d/libs/vkd3d-shader/trace.c @@ -225,6 +225,7 @@ static const char * const shader_opcode_names[] = [VKD3DSIH_MOV ] = "mov", [VKD3DSIH_MOVA ] = "mova", [VKD3DSIH_MOVC ] = "movc", + [VKD3DSIH_MSAD ] = "msad", [VKD3DSIH_MUL ] = "mul", [VKD3DSIH_NE ] = "ne", [VKD3DSIH_NOP ] = "nop", @@ -662,8 +663,14 @@ static void shader_dump_decl_usage(struct vkd3d_d3d_asm_compiler *compiler, shader_addline(buffer, "_resource_"); shader_dump_resource_type(compiler, semantic->resource_type); + if (semantic->resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS + || semantic->resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY) + { + shader_addline(buffer, "(%u)", semantic->sample_count); + } if (semantic->resource.reg.reg.type == VKD3DSPR_UAV) shader_dump_uav_flags(compiler, flags); + shader_addline(buffer, " "); shader_dump_data_type(compiler, semantic->resource_data_type); } else @@ -1858,7 +1865,7 @@ enum vkd3d_result vkd3d_dxbc_binary_to_text(struct vkd3d_shader_parser *parser, struct vkd3d_d3d_asm_compiler compiler; enum vkd3d_result result = VKD3D_OK; struct vkd3d_string_buffer *buffer; - unsigned int indent, i; + unsigned int indent, i, j; const char *indent_str; void *code; @@ -1919,41 +1926,32 @@ enum vkd3d_result vkd3d_dxbc_binary_to_text(struct vkd3d_shader_parser *parser, shader_version->minor, compiler.colours.reset); indent = 0; - vkd3d_shader_parser_reset(parser); - while (!vkd3d_shader_parser_is_end(parser)) + for (i = 0; i < parser->instructions.count; ++i) { - struct vkd3d_shader_instruction ins; - - vkd3d_shader_parser_read_instruction(parser, &ins); - if (ins.handler_idx == VKD3DSIH_INVALID) - { - WARN("Skipping unrecognized instruction.\n"); - vkd3d_string_buffer_printf(buffer, "\n"); - result = VKD3D_ERROR; - continue; - } + struct vkd3d_shader_instruction *ins = &parser->instructions.elements[i]; - switch (ins.handler_idx) + switch (ins->handler_idx) { case VKD3DSIH_ELSE: case VKD3DSIH_ENDIF: case VKD3DSIH_ENDLOOP: case VKD3DSIH_ENDSWITCH: - --indent; + if (indent) + --indent; break; default: break; } - for (i = 0; i < indent; ++i) + for (j = 0; j < indent; ++j) { vkd3d_string_buffer_printf(buffer, "%s", indent_str); } - shader_dump_instruction(&compiler, &ins); + shader_dump_instruction(&compiler, ins); - switch (ins.handler_idx) + switch (ins->handler_idx) { case VKD3DSIH_ELSE: case VKD3DSIH_IF: @@ -1967,9 +1965,6 @@ enum vkd3d_result vkd3d_dxbc_binary_to_text(struct vkd3d_shader_parser *parser, } } - if (parser->failed) - result = VKD3D_ERROR_INVALID_SHADER; - if ((code = vkd3d_malloc(buffer->content_size))) { memcpy(code, buffer->buffer, buffer->content_size); diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/vkd3d_shader_main.c b/dll/directx/wine/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c similarity index 88% rename from dll/directx/wine/d3d12/vkd3d/vkd3d-shader/vkd3d_shader_main.c rename to dll/directx/wine/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c index 62baf17fbfc5e..c9c15f0115589 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/vkd3d_shader_main.c +++ b/dll/directx/wine/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c @@ -22,7 +22,37 @@ #include #include -VKD3D_DEBUG_ENV_NAME("VKD3D_SHADER_DEBUG"); +static inline int char_to_int(char c) +{ + if ('0' <= c && c <= '9') + return c - '0'; + if ('A' <= c && c <= 'F') + return c - 'A' + 10; + if ('a' <= c && c <= 'f') + return c - 'a' + 10; + return -1; +} + +uint32_t vkd3d_parse_integer(const char *s) +{ + uint32_t base = 10, ret = 0; + int digit; + + if (*s == '0') + { + base = 8; + ++s; + if (*s == 'x' || *s == 'X') + { + base = 16; + ++s; + } + } + + while ((digit = char_to_int(*s++)) >= 0) + ret = ret * base + (uint32_t)digit; + return ret; +} void vkd3d_string_buffer_init(struct vkd3d_string_buffer *buffer) { @@ -395,9 +425,10 @@ void vkd3d_shader_dump_shader(enum vkd3d_shader_source_type source_type, shader_get_source_type_suffix(source_type), shader->code, shader->size); } -void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, +bool vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vkd3d_shader_message_context *message_context, const char *source_name, - const struct vkd3d_shader_version *version, const struct vkd3d_shader_parser_ops *ops) + const struct vkd3d_shader_version *version, const struct vkd3d_shader_parser_ops *ops, + unsigned int instruction_reserve) { parser->message_context = message_context; parser->location.source_name = source_name; @@ -405,6 +436,7 @@ void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, parser->location.column = 0; parser->shader_version = *version; parser->ops = ops; + return shader_instruction_array_init(&parser->instructions, instruction_reserve); } void VKD3D_PRINTF_FUNC(3, 4) vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser, @@ -660,6 +692,25 @@ static void vkd3d_shader_scan_record_uav_counter(struct vkd3d_shader_scan_contex d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_COUNTER; } +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); +} + +static void vkd3d_shader_scan_record_uav_atomic_op(struct vkd3d_shader_scan_context *context, + const struct vkd3d_shader_register *reg) +{ + struct vkd3d_shader_descriptor_info *d; + + if (!context->scan_descriptor_info) + return; + + d = vkd3d_shader_scan_get_uav_descriptor_info(context, reg->idx[0].offset); + d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_ATOMICS; +} + static bool vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *context, enum vkd3d_shader_descriptor_type type, const struct vkd3d_shader_register_range *range, enum vkd3d_shader_resource_type resource_type, enum vkd3d_shader_resource_data_type resource_data_type, @@ -987,6 +1038,15 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte if (vkd3d_shader_instruction_is_uav_counter(instruction)) vkd3d_shader_scan_record_uav_counter(context, &instruction->src[0].reg); + if (vkd3d_shader_instruction_is_uav_atomic_op(instruction)) + { + for (i = 0; i < instruction->dst_count; ++i) + { + if (instruction->dst[i].reg.type == VKD3DSPR_UAV) + vkd3d_shader_scan_record_uav_atomic_op(context, &instruction->dst[i].reg); + } + } + ++context->location.line; return VKD3D_OK; } @@ -995,9 +1055,10 @@ static int scan_with_parser(const struct vkd3d_shader_compile_info *compile_info struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser *parser) { struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info; - struct vkd3d_shader_instruction instruction; + struct vkd3d_shader_instruction *instruction; struct vkd3d_shader_scan_context context; - int ret; + int ret = VKD3D_OK; + unsigned int i; if ((scan_descriptor_info = vkd3d_find_struct(compile_info->next, SCAN_DESCRIPTOR_INFO))) { @@ -1010,33 +1071,19 @@ static int scan_with_parser(const struct vkd3d_shader_compile_info *compile_info if (TRACE_ON()) { vkd3d_shader_trace(parser); - vkd3d_shader_parser_reset(parser); } - while (!vkd3d_shader_parser_is_end(parser)) + for (i = 0; i < parser->instructions.count; ++i) { - vkd3d_shader_parser_read_instruction(parser, &instruction); - - if (instruction.handler_idx == VKD3DSIH_INVALID) - { - WARN("Encountered unrecognized or invalid instruction.\n"); - if (scan_descriptor_info) - vkd3d_shader_free_scan_descriptor_info(scan_descriptor_info); - ret = VKD3D_ERROR_INVALID_SHADER; - goto done; - } - - if ((ret = vkd3d_shader_scan_instruction(&context, &instruction)) < 0) + instruction = &parser->instructions.elements[i]; + if ((ret = vkd3d_shader_scan_instruction(&context, instruction)) < 0) { if (scan_descriptor_info) vkd3d_shader_free_scan_descriptor_info(scan_descriptor_info); - goto done; + break; } } - ret = parser->failed ? VKD3D_ERROR_INVALID_SHADER : VKD3D_OK; - -done: vkd3d_shader_scan_context_cleanup(&context); return ret; } @@ -1124,9 +1171,8 @@ static int compile_dxbc_tpf(const struct vkd3d_shader_compile_info *compile_info struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) { struct vkd3d_shader_scan_descriptor_info scan_descriptor_info; - struct vkd3d_shader_instruction instruction; struct vkd3d_shader_compile_info scan_info; - struct vkd3d_dxbc_compiler *spirv_compiler; + struct spirv_compiler *spirv_compiler; struct vkd3d_shader_parser *parser; int ret; @@ -1176,7 +1222,7 @@ static int compile_dxbc_tpf(const struct vkd3d_shader_compile_info *compile_info return ret; } - if (!(spirv_compiler = vkd3d_dxbc_compiler_create(&parser->shader_version, &parser->shader_desc, + if (!(spirv_compiler = spirv_compiler_create(&parser->shader_version, &parser->shader_desc, compile_info, &scan_descriptor_info, message_context, &parser->location))) { ERR("Failed to create DXBC compiler.\n"); @@ -1185,28 +1231,9 @@ static int compile_dxbc_tpf(const struct vkd3d_shader_compile_info *compile_info return VKD3D_ERROR; } - while (!vkd3d_shader_parser_is_end(parser)) - { - vkd3d_shader_parser_read_instruction(parser, &instruction); - - if (instruction.handler_idx == VKD3DSIH_INVALID) - { - WARN("Encountered unrecognized or invalid instruction.\n"); - ret = VKD3D_ERROR_INVALID_SHADER; - break; - } - - if ((ret = vkd3d_dxbc_compiler_handle_instruction(spirv_compiler, &instruction)) < 0) - break; - } + ret = spirv_compiler_generate_spirv(spirv_compiler, compile_info, parser, out); - if (parser->failed) - ret = VKD3D_ERROR_INVALID_SHADER; - - if (ret >= 0) - ret = vkd3d_dxbc_compiler_generate_spirv(spirv_compiler, compile_info, out); - - vkd3d_dxbc_compiler_destroy(spirv_compiler); + spirv_compiler_destroy(spirv_compiler); vkd3d_shader_parser_destroy(parser); vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info); return ret; @@ -1282,7 +1309,7 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, break; default: - assert(0); + vkd3d_unreachable(); } vkd3d_shader_message_context_trace_messages(&message_context); @@ -1373,7 +1400,7 @@ int vkd3d_shader_parse_input_signature(const struct vkd3d_shader_code *dxbc, *messages = NULL; vkd3d_shader_message_context_init(&message_context, VKD3D_SHADER_LOG_INFO); - ret = shader_parse_input_signature(dxbc->code, dxbc->size, &message_context, signature); + ret = shader_parse_input_signature(dxbc, &message_context, signature); vkd3d_shader_message_context_trace_messages(&message_context); if (!vkd3d_shader_message_context_copy_messages(&message_context, messages)) ret = VKD3D_ERROR_OUT_OF_MEMORY; @@ -1518,3 +1545,111 @@ int vkd3d_shader_preprocess(const struct vkd3d_shader_compile_info *compile_info vkd3d_shader_message_context_cleanup(&message_context); return ret; } + +void vkd3d_shader_set_log_callback(PFN_vkd3d_log callback) +{ + vkd3d_dbg_set_log_callback(callback); +} + +static struct vkd3d_shader_param_node *shader_param_allocator_node_create( + struct vkd3d_shader_param_allocator *allocator) +{ + struct vkd3d_shader_param_node *node; + + if (!(node = vkd3d_malloc(offsetof(struct vkd3d_shader_param_node, param[allocator->count * allocator->stride])))) + return NULL; + node->next = NULL; + return node; +} + +static void shader_param_allocator_init(struct vkd3d_shader_param_allocator *allocator, + unsigned int count, unsigned int stride) +{ + allocator->count = max(count, 4); + allocator->stride = stride; + allocator->head = NULL; + allocator->current = NULL; + allocator->index = allocator->count; +} + +static void shader_param_allocator_destroy(struct vkd3d_shader_param_allocator *allocator) +{ + struct vkd3d_shader_param_node *current = allocator->head; + + while (current) + { + struct vkd3d_shader_param_node *next = current->next; + vkd3d_free(current); + current = next; + } +} + +void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, unsigned int count) +{ + void *params; + + if (!count) + return NULL; + + if (count > allocator->count - allocator->index) + { + struct vkd3d_shader_param_node *next = shader_param_allocator_node_create(allocator); + + if (!next) + return NULL; + if (allocator->current) + allocator->current->next = next; + else + allocator->head = next; + allocator->current = next; + allocator->index = 0; + } + + params = &allocator->current->param[allocator->index * allocator->stride]; + allocator->index += count; + return params; +} + +bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve) +{ + memset(instructions, 0, sizeof(*instructions)); + /* Size the parameter initial allocations so they are large enough for most shaders. The + * code path for chained allocations will be tested if a few shaders need to use it. */ + shader_param_allocator_init(&instructions->dst_params, reserve - reserve / 8u, + sizeof(*instructions->elements->dst)); + shader_param_allocator_init(&instructions->src_params, reserve * 2u, sizeof(*instructions->elements->src)); + return shader_instruction_array_reserve(instructions, reserve); +} + +bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve) +{ + if (!vkd3d_array_reserve((void **)&instructions->elements, &instructions->capacity, reserve, + sizeof(*instructions->elements))) + { + ERR("Failed to allocate instructions.\n"); + return false; + } + return true; +} + +bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions, + struct vkd3d_shader_immediate_constant_buffer *icb) +{ + if (!vkd3d_array_reserve((void **)&instructions->icbs, &instructions->icb_capacity, instructions->icb_count + 1, + sizeof(*instructions->icbs))) + return false; + instructions->icbs[instructions->icb_count++] = icb; + return true; +} + +void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *instructions) +{ + unsigned int i; + + vkd3d_free(instructions->elements); + shader_param_allocator_destroy(&instructions->dst_params); + shader_param_allocator_destroy(&instructions->src_params); + for (i = 0; i < instructions->icb_count; ++i) + vkd3d_free(instructions->icbs[i]); + vkd3d_free(instructions->icbs); +} diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/vkd3d_shader_private.h b/dll/directx/wine/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h similarity index 91% rename from dll/directx/wine/d3d12/vkd3d/vkd3d-shader/vkd3d_shader_private.h rename to dll/directx/wine/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h index 01e090ccd249a..79be999adf93a 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d-shader/vkd3d_shader_private.h +++ b/dll/directx/wine/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h @@ -49,7 +49,7 @@ #include "vkd3d_common.h" #include "vkd3d_memory.h" #include "vkd3d_shader.h" -#include "list.h" +#include "wine/list.h" #include #include @@ -68,9 +68,12 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_DXBC_INVALID_VERSION = 4, VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_OFFSET = 5, VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_SIZE = 6, + VKD3D_SHADER_ERROR_DXBC_OUT_OF_MEMORY = 7, + VKD3D_SHADER_ERROR_DXBC_INVALID_SIGNATURE = 8, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF = 1000, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_RANGE = 1001, + VKD3D_SHADER_ERROR_TPF_OUT_OF_MEMORY = 1002, VKD3D_SHADER_ERROR_SPV_DESCRIPTOR_BINDING_NOT_FOUND = 2000, VKD3D_SHADER_ERROR_SPV_INVALID_REGISTER_TYPE = 2001, @@ -117,8 +120,15 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_HLSL_INVALID_TEXEL_OFFSET = 5018, VKD3D_SHADER_ERROR_HLSL_OFFSET_OUT_OF_BOUNDS = 5019, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE = 5020, + VKD3D_SHADER_ERROR_HLSL_DIVISION_BY_ZERO = 5021, + VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF = 5022, + VKD3D_SHADER_ERROR_HLSL_INVALID_THREAD_COUNT = 5023, + VKD3D_SHADER_ERROR_HLSL_MISSING_ATTRIBUTE = 5024, + VKD3D_SHADER_ERROR_HLSL_RECURSIVE_CALL = 5025, VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300, + VKD3D_SHADER_WARNING_HLSL_DIVISION_BY_ZERO = 5301, + VKD3D_SHADER_WARNING_HLSL_UNKNOWN_ATTRIBUTE = 5302, VKD3D_SHADER_ERROR_GLSL_INTERNAL = 6000, @@ -126,6 +136,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_D3DBC_INVALID_VERSION_TOKEN = 7001, VKD3D_SHADER_ERROR_D3DBC_INVALID_OPCODE = 7002, VKD3D_SHADER_ERROR_D3DBC_INVALID_RESOURCE_TYPE = 7003, + VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY = 7004, VKD3D_SHADER_WARNING_D3DBC_IGNORED_INSTRUCTION_FLAGS= 7300, }; @@ -328,6 +339,7 @@ enum vkd3d_shader_opcode VKD3DSIH_MOV, VKD3DSIH_MOVA, VKD3DSIH_MOVC, + VKD3DSIH_MSAD, VKD3DSIH_MUL, VKD3DSIH_NE, VKD3DSIH_NOP, @@ -610,7 +622,6 @@ enum vkd3d_shader_conditional_op VKD3D_SHADER_CONDITIONAL_OP_Z = 1 }; -#define MAX_IMMEDIATE_CONSTANT_BUFFER_SIZE 4096 #define MAX_REG_OUTPUT 32 enum vkd3d_shader_type @@ -640,7 +651,7 @@ struct vkd3d_shader_version struct vkd3d_shader_immediate_constant_buffer { unsigned int vec4_count; - uint32_t data[MAX_IMMEDIATE_CONSTANT_BUFFER_SIZE]; + uint32_t data[]; }; struct vkd3d_shader_indexable_temp @@ -731,6 +742,7 @@ struct vkd3d_shader_semantic enum vkd3d_decl_usage usage; unsigned int usage_idx; enum vkd3d_shader_resource_type resource_type; + unsigned int sample_count; enum vkd3d_data_type resource_data_type[VKD3D_VEC4_SIZE]; struct vkd3d_shader_resource resource; }; @@ -921,6 +933,56 @@ struct vkd3d_shader_location unsigned int line, column; }; +struct vkd3d_shader_param_node +{ + struct vkd3d_shader_param_node *next; + uint8_t param[]; +}; + +struct vkd3d_shader_param_allocator +{ + struct vkd3d_shader_param_node *head; + struct vkd3d_shader_param_node *current; + unsigned int count; + unsigned int stride; + unsigned int index; +}; + +void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, unsigned int count); + +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)); + 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)); + return shader_param_allocator_get(allocator, count); +} + +struct vkd3d_shader_instruction_array +{ + struct vkd3d_shader_instruction *elements; + size_t capacity; + size_t count; + + struct vkd3d_shader_param_allocator src_params; + struct vkd3d_shader_param_allocator dst_params; + struct vkd3d_shader_immediate_constant_buffer **icbs; + size_t icb_capacity; + size_t icb_count; +}; + +bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve); +bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve); +bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions, + struct vkd3d_shader_immediate_constant_buffer *icb); +void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *instructions); + struct vkd3d_shader_parser { struct vkd3d_shader_message_context *message_context; @@ -931,43 +993,39 @@ struct vkd3d_shader_parser struct vkd3d_shader_version shader_version; const uint32_t *ptr; const struct vkd3d_shader_parser_ops *ops; + struct vkd3d_shader_instruction_array instructions; + size_t instruction_idx; }; struct vkd3d_shader_parser_ops { - void (*parser_reset)(struct vkd3d_shader_parser *parser); void (*parser_destroy)(struct vkd3d_shader_parser *parser); - void (*parser_read_instruction)(struct vkd3d_shader_parser *parser, struct vkd3d_shader_instruction *instruction); - bool (*parser_is_end)(struct vkd3d_shader_parser *parser); }; void vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser, enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4); -void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, +bool vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vkd3d_shader_message_context *message_context, const char *source_name, - const struct vkd3d_shader_version *version, const struct vkd3d_shader_parser_ops *ops); + const struct vkd3d_shader_version *version, const struct vkd3d_shader_parser_ops *ops, + unsigned int instruction_reserve); void vkd3d_shader_parser_warning(struct vkd3d_shader_parser *parser, enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4); -static inline void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parser) -{ - parser->ops->parser_destroy(parser); -} - -static inline bool vkd3d_shader_parser_is_end(struct vkd3d_shader_parser *parser) +static inline struct vkd3d_shader_dst_param *shader_parser_get_dst_params( + struct vkd3d_shader_parser *parser, unsigned int count) { - return parser->ops->parser_is_end(parser); + return shader_dst_param_allocator_get(&parser->instructions.dst_params, count); } -static inline void vkd3d_shader_parser_read_instruction(struct vkd3d_shader_parser *parser, - struct vkd3d_shader_instruction *instruction) +static inline struct vkd3d_shader_src_param *shader_parser_get_src_params( + struct vkd3d_shader_parser *parser, unsigned int count) { - parser->ops->parser_read_instruction(parser, instruction); + return shader_src_param_allocator_get(&parser->instructions.src_params, count); } -static inline void vkd3d_shader_parser_reset(struct vkd3d_shader_parser *parser) +static inline void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parser) { - parser->ops->parser_reset(parser); + parser->ops->parser_destroy(parser); } void vkd3d_shader_trace(struct vkd3d_shader_parser *parser); @@ -1032,6 +1090,8 @@ static inline size_t bytecode_get_size(struct vkd3d_bytecode_buffer *buffer) return buffer->size; } +uint32_t vkd3d_parse_integer(const char *s); + struct vkd3d_shader_message_context { enum vkd3d_shader_log_level log_level; @@ -1068,7 +1128,7 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi void free_shader_desc(struct vkd3d_shader_desc *desc); -int shader_parse_input_signature(const void *dxbc, size_t dxbc_length, +int shader_parse_input_signature(const struct vkd3d_shader_code *dxbc, struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_signature *signature); struct vkd3d_glsl_generator; @@ -1079,17 +1139,18 @@ int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *generator, struct vkd3d_shader_parser *parser, struct vkd3d_shader_code *out); void vkd3d_glsl_generator_destroy(struct vkd3d_glsl_generator *generator); -struct vkd3d_dxbc_compiler; +#define SPIRV_MAX_SRC_COUNT 6 -struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader_version *shader_version, +struct spirv_compiler; + +struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_version *shader_version, const struct vkd3d_shader_desc *shader_desc, const struct vkd3d_shader_compile_info *compile_info, const struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info, struct vkd3d_shader_message_context *message_context, const struct vkd3d_shader_location *location); -int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler, - const struct vkd3d_shader_instruction *instruction); -int vkd3d_dxbc_compiler_generate_spirv(struct vkd3d_dxbc_compiler *compiler, - const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *spirv); -void vkd3d_dxbc_compiler_destroy(struct vkd3d_dxbc_compiler *compiler); +int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, + const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_parser *parser, + struct vkd3d_shader_code *spirv); +void spirv_compiler_destroy(struct spirv_compiler *compiler); void vkd3d_compute_dxbc_checksum(const void *dxbc, size_t size, uint32_t checksum[4]); @@ -1231,7 +1292,6 @@ static inline void *vkd3d_find_struct_(const struct vkd3d_struct *chain, return NULL; } -#define VKD3D_DXBC_MAX_SOURCE_COUNT 6 #define VKD3D_DXBC_HEADER_SIZE (8 * sizeof(uint32_t)) #define TAG_AON9 VKD3D_MAKE_TAG('A', 'o', 'n', '9') @@ -1251,19 +1311,12 @@ static inline void *vkd3d_find_struct_(const struct vkd3d_struct *chain, #define TAG_SHEX VKD3D_MAKE_TAG('S', 'H', 'E', 'X') #define TAG_TEXT VKD3D_MAKE_TAG('T', 'E', 'X', 'T') -struct dxbc_writer_section -{ - uint32_t tag; - const uint8_t *data; - size_t size; -}; - #define DXBC_MAX_SECTION_COUNT 5 struct dxbc_writer { unsigned int section_count; - struct dxbc_writer_section sections[DXBC_MAX_SECTION_COUNT]; + struct vkd3d_shader_dxbc_section_desc sections[DXBC_MAX_SECTION_COUNT]; }; void dxbc_writer_add_section(struct dxbc_writer *dxbc, uint32_t tag, const void *data, size_t size); diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d/command.c b/dll/directx/wine/vkd3d/libs/vkd3d/command.c similarity index 86% rename from dll/directx/wine/d3d12/vkd3d/vkd3d/command.c rename to dll/directx/wine/vkd3d/libs/vkd3d/command.c index e7375fb805bef..6eddcfa2d1465 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d/command.c +++ b/dll/directx/wine/vkd3d/libs/vkd3d/command.c @@ -20,24 +20,25 @@ #include "vkd3d_private.h" -static HRESULT d3d12_fence_signal(struct d3d12_fence *fence, uint64_t value, VkFence vk_fence); +static void d3d12_fence_incref(struct d3d12_fence *fence); +static void d3d12_fence_decref(struct d3d12_fence *fence); +static HRESULT d3d12_fence_signal(struct d3d12_fence *fence, uint64_t value, VkFence vk_fence, bool on_cpu); +static void d3d12_fence_signal_timeline_semaphore(struct d3d12_fence *fence, uint64_t timeline_value); +static HRESULT d3d12_command_queue_signal(struct d3d12_command_queue *command_queue, + struct d3d12_fence *fence, uint64_t value); +static HRESULT d3d12_command_queue_flush_ops(struct d3d12_command_queue *queue, bool *flushed_any); +static HRESULT d3d12_command_queue_flush_ops_locked(struct d3d12_command_queue *queue, bool *flushed_any); HRESULT vkd3d_queue_create(struct d3d12_device *device, uint32_t family_index, const VkQueueFamilyProperties *properties, struct vkd3d_queue **queue) { const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; struct vkd3d_queue *object; - int rc; if (!(object = vkd3d_malloc(sizeof(*object)))) return E_OUTOFMEMORY; - if ((rc = vkd3d_mutex_init(&object->mutex))) - { - ERR("Failed to initialize mutex, error %d.\n", rc); - vkd3d_free(object); - return hresult_from_errno(rc); - } + vkd3d_mutex_init(&object->mutex); object->completed_sequence_number = 0; object->submitted_sequence_number = 0; @@ -65,10 +66,8 @@ void vkd3d_queue_destroy(struct vkd3d_queue *queue, struct d3d12_device *device) { const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; unsigned int i; - int rc; - if ((rc = vkd3d_mutex_lock(&queue->mutex))) - ERR("Failed to lock mutex, error %d.\n", rc); + vkd3d_mutex_lock(&queue->mutex); for (i = 0; i < queue->semaphore_count; ++i) VK_CALL(vkDestroySemaphore(device->vk_device, queue->semaphores[i].vk_semaphore, NULL)); @@ -81,8 +80,7 @@ void vkd3d_queue_destroy(struct vkd3d_queue *queue, struct d3d12_device *device) VK_CALL(vkDestroySemaphore(device->vk_device, queue->old_vk_semaphores[i], NULL)); } - if (!rc) - vkd3d_mutex_unlock(&queue->mutex); + vkd3d_mutex_unlock(&queue->mutex); vkd3d_mutex_destroy(&queue->mutex); vkd3d_free(queue); @@ -90,15 +88,9 @@ void vkd3d_queue_destroy(struct vkd3d_queue *queue, struct d3d12_device *device) VkQueue vkd3d_queue_acquire(struct vkd3d_queue *queue) { - int rc; - TRACE("queue %p.\n", queue); - if ((rc = vkd3d_mutex_lock(&queue->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return VK_NULL_HANDLE; - } + vkd3d_mutex_lock(&queue->mutex); assert(queue->vk_queue); return queue->vk_queue; @@ -142,13 +134,8 @@ static void vkd3d_queue_update_sequence_number(struct vkd3d_queue *queue, uint64_t completed_sequence_number; VkSemaphore vk_semaphore; unsigned int i, j; - int rc; - if ((rc = vkd3d_mutex_lock(&queue->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return; - } + vkd3d_mutex_lock(&queue->mutex); completed_sequence_number = queue->completed_sequence_number; queue->completed_sequence_number = max(sequence_number, queue->completed_sequence_number); @@ -249,33 +236,26 @@ static HRESULT vkd3d_enqueue_gpu_fence(struct vkd3d_fence_worker *worker, struct vkd3d_queue *queue, uint64_t queue_sequence_number) { struct vkd3d_waiting_fence *waiting_fence; - int rc; TRACE("worker %p, fence %p, value %#"PRIx64".\n", worker, fence, value); - if ((rc = vkd3d_mutex_lock(&worker->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return hresult_from_errno(rc); - } + vkd3d_mutex_lock(&worker->mutex); - if (!vkd3d_array_reserve((void **)&worker->enqueued_fences, &worker->enqueued_fences_size, - worker->enqueued_fence_count + 1, sizeof(*worker->enqueued_fences))) + if (!vkd3d_array_reserve((void **)&worker->fences, &worker->fences_size, + worker->fence_count + 1, sizeof(*worker->fences))) { ERR("Failed to add GPU fence.\n"); vkd3d_mutex_unlock(&worker->mutex); return E_OUTOFMEMORY; } - worker->enqueued_fences[worker->enqueued_fence_count].vk_fence = vk_fence; - waiting_fence = &worker->enqueued_fences[worker->enqueued_fence_count].waiting_fence; + waiting_fence = &worker->fences[worker->fence_count++]; waiting_fence->fence = fence; waiting_fence->value = value; - waiting_fence->queue = queue; + waiting_fence->u.vk_fence = vk_fence; waiting_fence->queue_sequence_number = queue_sequence_number; - ++worker->enqueued_fence_count; - InterlockedIncrement(&fence->pending_worker_operation_count); + d3d12_fence_incref(fence); vkd3d_cond_signal(&worker->cond); vkd3d_mutex_unlock(&worker->mutex); @@ -283,242 +263,145 @@ static HRESULT vkd3d_enqueue_gpu_fence(struct vkd3d_fence_worker *worker, return S_OK; } -static void vkd3d_fence_worker_remove_fence(struct vkd3d_fence_worker *worker, struct d3d12_fence *fence) +static void vkd3d_wait_for_gpu_timeline_semaphore(struct vkd3d_fence_worker *worker, + const struct vkd3d_waiting_fence *waiting_fence) { - LONG count; - int rc; - - if (!(count = InterlockedAdd(&fence->pending_worker_operation_count, 0))) - return; - - WARN("Waiting for %u pending fence operations (fence %p).\n", count, fence); - - if ((rc = vkd3d_mutex_lock(&worker->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return; - } - - while ((count = InterlockedAdd(&fence->pending_worker_operation_count, 0))) - { - TRACE("Still waiting for %u pending fence operations (fence %p).\n", count, fence); - - worker->pending_fence_destruction = true; - vkd3d_cond_signal(&worker->cond); - - vkd3d_cond_wait(&worker->fence_destruction_cond, &worker->mutex); - } - - TRACE("Removed fence %p.\n", fence); - - vkd3d_mutex_unlock(&worker->mutex); -} + const struct d3d12_device *device = worker->device; + const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + VkSemaphoreWaitInfoKHR wait_info; + VkResult vr; -static void vkd3d_fence_worker_move_enqueued_fences_locked(struct vkd3d_fence_worker *worker) -{ - unsigned int i; - size_t count; - bool ret; + wait_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR; + wait_info.pNext = NULL; + wait_info.flags = 0; + wait_info.semaphoreCount = 1; + wait_info.pSemaphores = &waiting_fence->u.vk_semaphore; + wait_info.pValues = &waiting_fence->value; - if (!worker->enqueued_fence_count) + vr = VK_CALL(vkWaitSemaphoresKHR(device->vk_device, &wait_info, ~(uint64_t)0)); + if (vr == VK_TIMEOUT) return; - - count = worker->fence_count + worker->enqueued_fence_count; - - ret = vkd3d_array_reserve((void **)&worker->vk_fences, &worker->vk_fences_size, - count, sizeof(*worker->vk_fences)); - ret &= vkd3d_array_reserve((void **)&worker->fences, &worker->fences_size, - count, sizeof(*worker->fences)); - if (!ret) + if (vr != VK_SUCCESS) { - ERR("Failed to reserve memory.\n"); + ERR("Failed to wait for Vulkan timeline semaphore, vr %d.\n", vr); return; } - for (i = 0; i < worker->enqueued_fence_count; ++i) - { - struct vkd3d_enqueued_fence *current = &worker->enqueued_fences[i]; + TRACE("Signaling fence %p value %#"PRIx64".\n", waiting_fence->fence, waiting_fence->value); + d3d12_fence_signal_timeline_semaphore(waiting_fence->fence, waiting_fence->value); - worker->vk_fences[worker->fence_count] = current->vk_fence; - worker->fences[worker->fence_count] = current->waiting_fence; - ++worker->fence_count; - } - assert(worker->fence_count == count); - worker->enqueued_fence_count = 0; + d3d12_fence_decref(waiting_fence->fence); } -static void vkd3d_wait_for_gpu_fences(struct vkd3d_fence_worker *worker) +static void vkd3d_wait_for_gpu_fence(struct vkd3d_fence_worker *worker, + const struct vkd3d_waiting_fence *waiting_fence) { struct d3d12_device *device = worker->device; const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; - unsigned int i, j; - VkFence vk_fence; HRESULT hr; int vr; - if (!worker->fence_count) - return; - - vr = VK_CALL(vkWaitForFences(device->vk_device, - worker->fence_count, worker->vk_fences, VK_FALSE, ~(uint64_t)0)); + vr = VK_CALL(vkWaitForFences(device->vk_device, 1, &waiting_fence->u.vk_fence, VK_FALSE, ~(uint64_t)0)); if (vr == VK_TIMEOUT) return; if (vr != VK_SUCCESS) { - ERR("Failed to wait for Vulkan fences, vr %d.\n", vr); + ERR("Failed to wait for Vulkan fence, vr %d.\n", vr); return; } - for (i = 0, j = 0; i < worker->fence_count; ++i) - { - vk_fence = worker->vk_fences[i]; - if (!(vr = VK_CALL(vkGetFenceStatus(device->vk_device, vk_fence)))) - { - struct vkd3d_waiting_fence *current = &worker->fences[i]; - - TRACE("Signaling fence %p value %#"PRIx64".\n", current->fence, current->value); - if (FAILED(hr = d3d12_fence_signal(current->fence, current->value, vk_fence))) - ERR("Failed to signal D3D12 fence, hr %#x.\n", hr); - - InterlockedDecrement(¤t->fence->pending_worker_operation_count); - - vkd3d_queue_update_sequence_number(current->queue, current->queue_sequence_number, device); - continue; - } + TRACE("Signaling fence %p value %#"PRIx64".\n", waiting_fence->fence, waiting_fence->value); + if (FAILED(hr = d3d12_fence_signal(waiting_fence->fence, waiting_fence->value, waiting_fence->u.vk_fence, false))) + ERR("Failed to signal D3D12 fence, hr %#x.\n", hr); - if (vr != VK_NOT_READY) - ERR("Failed to get Vulkan fence status, vr %d.\n", vr); + d3d12_fence_decref(waiting_fence->fence); - if (i != j) - { - worker->vk_fences[j] = worker->vk_fences[i]; - worker->fences[j] = worker->fences[i]; - } - ++j; - } - worker->fence_count = j; + vkd3d_queue_update_sequence_number(worker->queue, waiting_fence->queue_sequence_number, device); } static void *vkd3d_fence_worker_main(void *arg) { + size_t old_fences_size, cur_fences_size = 0, cur_fence_count = 0; + struct vkd3d_waiting_fence *old_fences, *cur_fences = NULL; struct vkd3d_fence_worker *worker = arg; - int rc; + unsigned int i; vkd3d_set_thread_name("vkd3d_fence"); for (;;) { - vkd3d_wait_for_gpu_fences(worker); + vkd3d_mutex_lock(&worker->mutex); + + if (!worker->fence_count && !worker->should_exit) + vkd3d_cond_wait(&worker->cond, &worker->mutex); - if (!worker->fence_count || InterlockedAdd(&worker->enqueued_fence_count, 0)) + if (worker->should_exit) { - if ((rc = vkd3d_mutex_lock(&worker->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - break; - } + vkd3d_mutex_unlock(&worker->mutex); + break; + } - if (worker->pending_fence_destruction) - { - vkd3d_cond_broadcast(&worker->fence_destruction_cond); - worker->pending_fence_destruction = false; - } + old_fences_size = cur_fences_size; + old_fences = cur_fences; - if (worker->enqueued_fence_count) - { - vkd3d_fence_worker_move_enqueued_fences_locked(worker); - } - else - { - if (worker->should_exit) - { - vkd3d_mutex_unlock(&worker->mutex); - break; - } + cur_fence_count = worker->fence_count; + cur_fences_size = worker->fences_size; + cur_fences = worker->fences; - if ((rc = vkd3d_cond_wait(&worker->cond, &worker->mutex))) - { - ERR("Failed to wait on condition variable, error %d.\n", rc); - vkd3d_mutex_unlock(&worker->mutex); - break; - } - } + worker->fence_count = 0; + worker->fences_size = old_fences_size; + worker->fences = old_fences; - vkd3d_mutex_unlock(&worker->mutex); - } + vkd3d_mutex_unlock(&worker->mutex); + + for (i = 0; i < cur_fence_count; ++i) + worker->wait_for_gpu_fence(worker, &cur_fences[i]); } + vkd3d_free(cur_fences); return NULL; } -HRESULT vkd3d_fence_worker_start(struct vkd3d_fence_worker *worker, - struct d3d12_device *device) +static HRESULT vkd3d_fence_worker_start(struct vkd3d_fence_worker *worker, + struct vkd3d_queue *queue, struct d3d12_device *device) { HRESULT hr; - int rc; TRACE("worker %p.\n", worker); worker->should_exit = false; - worker->pending_fence_destruction = false; + worker->queue = queue; worker->device = device; - worker->enqueued_fence_count = 0; - worker->enqueued_fences = NULL; - worker->enqueued_fences_size = 0; - worker->fence_count = 0; - - worker->vk_fences = NULL; - worker->vk_fences_size = 0; worker->fences = NULL; worker->fences_size = 0; - if ((rc = vkd3d_mutex_init(&worker->mutex))) - { - ERR("Failed to initialize mutex, error %d.\n", rc); - return hresult_from_errno(rc); - } + worker->wait_for_gpu_fence = device->vk_info.KHR_timeline_semaphore + ? vkd3d_wait_for_gpu_timeline_semaphore : vkd3d_wait_for_gpu_fence; - if ((rc = vkd3d_cond_init(&worker->cond))) - { - ERR("Failed to initialize condition variable, error %d.\n", rc); - vkd3d_mutex_destroy(&worker->mutex); - return hresult_from_errno(rc); - } + vkd3d_mutex_init(&worker->mutex); - if ((rc = vkd3d_cond_init(&worker->fence_destruction_cond))) - { - ERR("Failed to initialize condition variable, error %d.\n", rc); - vkd3d_mutex_destroy(&worker->mutex); - vkd3d_cond_destroy(&worker->cond); - return hresult_from_errno(rc); - } + vkd3d_cond_init(&worker->cond); if (FAILED(hr = vkd3d_create_thread(device->vkd3d_instance, vkd3d_fence_worker_main, worker, &worker->thread))) { vkd3d_mutex_destroy(&worker->mutex); vkd3d_cond_destroy(&worker->cond); - vkd3d_cond_destroy(&worker->fence_destruction_cond); } return hr; } -HRESULT vkd3d_fence_worker_stop(struct vkd3d_fence_worker *worker, +static HRESULT vkd3d_fence_worker_stop(struct vkd3d_fence_worker *worker, struct d3d12_device *device) { HRESULT hr; - int rc; TRACE("worker %p.\n", worker); - if ((rc = vkd3d_mutex_lock(&worker->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return hresult_from_errno(rc); - } + vkd3d_mutex_lock(&worker->mutex); worker->should_exit = true; vkd3d_cond_signal(&worker->cond); @@ -530,10 +413,7 @@ HRESULT vkd3d_fence_worker_stop(struct vkd3d_fence_worker *worker, vkd3d_mutex_destroy(&worker->mutex); vkd3d_cond_destroy(&worker->cond); - vkd3d_cond_destroy(&worker->fence_destruction_cond); - vkd3d_free(worker->enqueued_fences); - vkd3d_free(worker->vk_fences); vkd3d_free(worker->fences); return S_OK; @@ -585,15 +465,10 @@ static VkResult d3d12_fence_create_vk_fence(struct d3d12_fence *fence, VkFence * VkFenceCreateInfo fence_info; unsigned int i; VkResult vr; - int rc; *vk_fence = VK_NULL_HANDLE; - if ((rc = vkd3d_mutex_lock(&fence->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - goto create_fence; - } + vkd3d_mutex_lock(&fence->mutex); for (i = 0; i < ARRAY_SIZE(fence->old_vk_fences); ++i) { @@ -609,7 +484,6 @@ static VkResult d3d12_fence_create_vk_fence(struct d3d12_fence *fence, VkFence * if (*vk_fence) return VK_SUCCESS; -create_fence: vk_procs = &device->vk_procs; fence_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; @@ -629,32 +503,34 @@ static void d3d12_fence_garbage_collect_vk_semaphores_locked(struct d3d12_fence { struct d3d12_device *device = fence->device; const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; - struct vkd3d_signaled_semaphore *current, *p; - unsigned int semaphore_count; + struct vkd3d_signaled_semaphore *current; + unsigned int i, semaphore_count; semaphore_count = fence->semaphore_count; if (!destroy_all && semaphore_count < VKD3D_MAX_VK_SYNC_OBJECTS) return; - LIST_FOR_EACH_ENTRY_SAFE(current, p, &fence->semaphores, struct vkd3d_signaled_semaphore, entry) + i = 0; + while (i < fence->semaphore_count) { if (!destroy_all && fence->semaphore_count < VKD3D_MAX_VK_SYNC_OBJECTS) break; + current = &fence->semaphores[i]; /* The semaphore doesn't have a pending signal operation if the fence * was signaled. */ - if ((current->vk_fence || current->is_acquired) && !destroy_all) + if ((current->u.binary.vk_fence || current->u.binary.is_acquired) && !destroy_all) + { + ++i; continue; + } - if (current->vk_fence) + if (current->u.binary.vk_fence) WARN("Destroying potentially pending semaphore.\n"); - assert(!current->is_acquired); + assert(!current->u.binary.is_acquired); - VK_CALL(vkDestroySemaphore(device->vk_device, current->vk_semaphore, NULL)); - list_remove(¤t->entry); - vkd3d_free(current); - - --fence->semaphore_count; + VK_CALL(vkDestroySemaphore(device->vk_device, current->u.binary.vk_semaphore, NULL)); + fence->semaphores[i] = fence->semaphores[--fence->semaphore_count]; } if (semaphore_count != fence->semaphore_count) @@ -666,13 +542,8 @@ static void d3d12_fence_destroy_vk_objects(struct d3d12_fence *fence) const struct vkd3d_vk_device_procs *vk_procs; struct d3d12_device *device = fence->device; unsigned int i; - int rc; - if ((rc = vkd3d_mutex_lock(&fence->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return; - } + vkd3d_mutex_lock(&fence->mutex); vk_procs = &device->vk_procs; @@ -684,33 +555,29 @@ static void d3d12_fence_destroy_vk_objects(struct d3d12_fence *fence) } d3d12_fence_garbage_collect_vk_semaphores_locked(fence, true); + VK_CALL(vkDestroySemaphore(device->vk_device, fence->timeline_semaphore, NULL)); vkd3d_mutex_unlock(&fence->mutex); } -static struct vkd3d_signaled_semaphore *d3d12_fence_acquire_vk_semaphore(struct d3d12_fence *fence, +static struct vkd3d_signaled_semaphore *d3d12_fence_acquire_vk_semaphore_locked(struct d3d12_fence *fence, uint64_t value, uint64_t *completed_value) { struct vkd3d_signaled_semaphore *semaphore; struct vkd3d_signaled_semaphore *current; uint64_t semaphore_value; - int rc; + unsigned int i; TRACE("fence %p, value %#"PRIx64".\n", fence, value); - if ((rc = vkd3d_mutex_lock(&fence->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return VK_NULL_HANDLE; - } - semaphore = NULL; semaphore_value = ~(uint64_t)0; - LIST_FOR_EACH_ENTRY(current, &fence->semaphores, struct vkd3d_signaled_semaphore, entry) + for (i = 0; i < fence->semaphore_count; ++i) { + current = &fence->semaphores[i]; /* Prefer a semaphore with the smallest value. */ - if (!current->is_acquired && current->value >= value && semaphore_value >= current->value) + if (!current->u.binary.is_acquired && current->value >= value && semaphore_value >= current->value) { semaphore = current; semaphore_value = current->value; @@ -720,117 +587,177 @@ static struct vkd3d_signaled_semaphore *d3d12_fence_acquire_vk_semaphore(struct } if (semaphore) - semaphore->is_acquired = true; + semaphore->u.binary.is_acquired = true; *completed_value = fence->value; - vkd3d_mutex_unlock(&fence->mutex); - return semaphore; } static void d3d12_fence_remove_vk_semaphore(struct d3d12_fence *fence, struct vkd3d_signaled_semaphore *semaphore) { - int rc; + vkd3d_mutex_lock(&fence->mutex); - if ((rc = vkd3d_mutex_lock(&fence->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return; - } + assert(semaphore->u.binary.is_acquired); - assert(semaphore->is_acquired); + *semaphore = fence->semaphores[--fence->semaphore_count]; + + vkd3d_mutex_unlock(&fence->mutex); +} - list_remove(&semaphore->entry); - vkd3d_free(semaphore); +static void d3d12_fence_release_vk_semaphore(struct d3d12_fence *fence, struct vkd3d_signaled_semaphore *semaphore) +{ + vkd3d_mutex_lock(&fence->mutex); - --fence->semaphore_count; + assert(semaphore->u.binary.is_acquired); + semaphore->u.binary.is_acquired = false; vkd3d_mutex_unlock(&fence->mutex); } -static void d3d12_fence_release_vk_semaphore(struct d3d12_fence *fence, struct vkd3d_signaled_semaphore *semaphore) +static void d3d12_fence_update_pending_value_locked(struct d3d12_fence *fence) { - int rc; + uint64_t new_max_pending_value; + unsigned int i; - if ((rc = vkd3d_mutex_lock(&fence->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return; - } + for (i = 0, new_max_pending_value = 0; i < fence->semaphore_count; ++i) + new_max_pending_value = max(fence->semaphores[i].value, new_max_pending_value); - assert(semaphore->is_acquired); - semaphore->is_acquired = false; + fence->max_pending_value = max(fence->value, new_max_pending_value); +} + +static HRESULT d3d12_fence_update_pending_value(struct d3d12_fence *fence) +{ + vkd3d_mutex_lock(&fence->mutex); + + d3d12_fence_update_pending_value_locked(fence); vkd3d_mutex_unlock(&fence->mutex); + + return S_OK; } -static HRESULT d3d12_fence_add_vk_semaphore(struct d3d12_fence *fence, - VkSemaphore vk_semaphore, VkFence vk_fence, uint64_t value) +static HRESULT d3d12_command_queue_record_as_blocked(struct d3d12_command_queue *command_queue) { - struct vkd3d_signaled_semaphore *semaphore; + struct d3d12_device *device = command_queue->device; HRESULT hr = S_OK; - int rc; - TRACE("fence %p, value %#"PRIx64".\n", fence, value); + vkd3d_mutex_lock(&device->blocked_queues_mutex); - if (!(semaphore = vkd3d_malloc(sizeof(*semaphore)))) + if (device->blocked_queue_count < ARRAY_SIZE(device->blocked_queues)) { - ERR("Failed to add semaphore.\n"); - return E_OUTOFMEMORY; + device->blocked_queues[device->blocked_queue_count++] = command_queue; + } + else + { + WARN("Failed to add blocked command queue %p to device %p.\n", command_queue, device); + hr = E_FAIL; + } + + vkd3d_mutex_unlock(&device->blocked_queues_mutex); + return hr; +} + +static HRESULT d3d12_device_flush_blocked_queues_once(struct d3d12_device *device, bool *flushed_any) +{ + struct d3d12_command_queue *blocked_queues[VKD3D_MAX_DEVICE_BLOCKED_QUEUES]; + unsigned int i, blocked_queue_count; + HRESULT hr = S_OK; + + *flushed_any = false; + + vkd3d_mutex_lock(&device->blocked_queues_mutex); + + /* Flush any ops unblocked by a new pending value. These cannot be + * flushed while holding blocked_queue_mutex, so move the queue + * pointers to a local array. */ + blocked_queue_count = device->blocked_queue_count; + memcpy(blocked_queues, device->blocked_queues, blocked_queue_count * sizeof(blocked_queues[0])); + device->blocked_queue_count = 0; + + vkd3d_mutex_unlock(&device->blocked_queues_mutex); + + for (i = 0; i < blocked_queue_count; ++i) + { + HRESULT new_hr; + + new_hr = d3d12_command_queue_flush_ops(blocked_queues[i], flushed_any); + + if (SUCCEEDED(hr)) + hr = new_hr; } - if ((rc = vkd3d_mutex_lock(&fence->mutex))) + return hr; +} + +static HRESULT d3d12_device_flush_blocked_queues(struct d3d12_device *device) +{ + bool flushed_any; + HRESULT hr; + + /* Executing an op on one queue may unblock another, so repeat until nothing is flushed. */ + do { - ERR("Failed to lock mutex, error %d.\n", rc); - vkd3d_free(semaphore); - return E_FAIL; + if (FAILED(hr = d3d12_device_flush_blocked_queues_once(device, &flushed_any))) + return hr; } + while (flushed_any); + + return S_OK; +} + +static HRESULT d3d12_fence_add_vk_semaphore(struct d3d12_fence *fence, VkSemaphore vk_semaphore, + VkFence vk_fence, uint64_t value, const struct vkd3d_queue *signalling_queue) +{ + struct vkd3d_signaled_semaphore *semaphore; + + TRACE("fence %p, value %#"PRIx64".\n", fence, value); + + vkd3d_mutex_lock(&fence->mutex); d3d12_fence_garbage_collect_vk_semaphores_locked(fence, false); + if (!vkd3d_array_reserve((void**)&fence->semaphores, &fence->semaphores_size, + fence->semaphore_count + 1, sizeof(*fence->semaphores))) + { + ERR("Failed to add semaphore.\n"); + vkd3d_mutex_unlock(&fence->mutex); + return E_OUTOFMEMORY; + } + + semaphore = &fence->semaphores[fence->semaphore_count++]; semaphore->value = value; - semaphore->vk_semaphore = vk_semaphore; - semaphore->vk_fence = vk_fence; - semaphore->is_acquired = false; + semaphore->u.binary.vk_semaphore = vk_semaphore; + semaphore->u.binary.vk_fence = vk_fence; + semaphore->u.binary.is_acquired = false; + semaphore->signalling_queue = signalling_queue; - list_add_tail(&fence->semaphores, &semaphore->entry); - ++fence->semaphore_count; + d3d12_fence_update_pending_value_locked(fence); vkd3d_mutex_unlock(&fence->mutex); - return hr; + return d3d12_device_flush_blocked_queues(fence->device); } -static HRESULT d3d12_fence_signal(struct d3d12_fence *fence, uint64_t value, VkFence vk_fence) +static void d3d12_fence_signal_external_events_locked(struct d3d12_fence *fence) { struct d3d12_device *device = fence->device; - struct vkd3d_signaled_semaphore *current; bool signal_null_event_cond = false; unsigned int i, j; - int rc; - - if ((rc = vkd3d_mutex_lock(&fence->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return hresult_from_errno(rc); - } - - fence->value = value; for (i = 0, j = 0; i < fence->event_count; ++i) { struct vkd3d_waiting_event *current = &fence->events[i]; - if (current->value <= value) + if (current->value <= fence->value) { if (current->event) { - fence->device->signal_event(current->event); + device->signal_event(current->event); } else { - current->latch = true; + *current->latch = true; signal_null_event_cond = true; } } @@ -841,19 +768,34 @@ static HRESULT d3d12_fence_signal(struct d3d12_fence *fence, uint64_t value, VkF ++j; } } + fence->event_count = j; if (signal_null_event_cond) vkd3d_cond_broadcast(&fence->null_event_cond); +} + +static HRESULT d3d12_fence_signal(struct d3d12_fence *fence, uint64_t value, VkFence vk_fence, bool on_cpu) +{ + struct d3d12_device *device = fence->device; + struct vkd3d_signaled_semaphore *current; + unsigned int i; + + vkd3d_mutex_lock(&fence->mutex); + + fence->value = value; + + d3d12_fence_signal_external_events_locked(fence); if (vk_fence) { const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; - LIST_FOR_EACH_ENTRY(current, &fence->semaphores, struct vkd3d_signaled_semaphore, entry) + for (i = 0; i < fence->semaphore_count; ++i) { - if (current->vk_fence == vk_fence) - current->vk_fence = VK_NULL_HANDLE; + current = &fence->semaphores[i]; + if (current->u.binary.vk_fence == vk_fence) + current->u.binary.vk_fence = VK_NULL_HANDLE; } for (i = 0; i < ARRAY_SIZE(fence->old_vk_fences); ++i) @@ -870,9 +812,91 @@ static HRESULT d3d12_fence_signal(struct d3d12_fence *fence, uint64_t value, VkF VK_CALL(vkDestroyFence(device->vk_device, vk_fence, NULL)); } + d3d12_fence_update_pending_value_locked(fence); + vkd3d_mutex_unlock(&fence->mutex); - return S_OK; + return on_cpu ? d3d12_device_flush_blocked_queues(device) : S_OK; +} + +static uint64_t d3d12_fence_add_pending_timeline_signal(struct d3d12_fence *fence, uint64_t virtual_value, + const struct vkd3d_queue *signalling_queue) +{ + struct vkd3d_signaled_semaphore *semaphore; + + vkd3d_mutex_lock(&fence->mutex); + + if (!vkd3d_array_reserve((void **)&fence->semaphores, &fence->semaphores_size, + fence->semaphore_count + 1, sizeof(*fence->semaphores))) + { + return 0; + } + + semaphore = &fence->semaphores[fence->semaphore_count++]; + semaphore->value = virtual_value; + semaphore->u.timeline_value = ++fence->pending_timeline_value; + semaphore->signalling_queue = signalling_queue; + + vkd3d_mutex_unlock(&fence->mutex); + + return fence->pending_timeline_value; +} + +static uint64_t d3d12_fence_get_timeline_wait_value_locked(struct d3d12_fence *fence, uint64_t virtual_value) +{ + uint64_t target_timeline_value = UINT64_MAX; + unsigned int i; + + /* Find the smallest physical value which is at least the virtual value. */ + for (i = 0; i < fence->semaphore_count; ++i) + { + if (virtual_value <= fence->semaphores[i].value) + target_timeline_value = min(target_timeline_value, fence->semaphores[i].u.timeline_value); + } + + /* No timeline value will be found if it was already signaled on the GPU and handled in + * the worker thread. A wait must still be emitted as a barrier against command re-ordering. */ + return (target_timeline_value == UINT64_MAX) ? 0 : target_timeline_value; +} + +static void d3d12_fence_signal_timeline_semaphore(struct d3d12_fence *fence, uint64_t timeline_value) +{ + bool did_signal; + unsigned int i; + + vkd3d_mutex_lock(&fence->mutex); + + /* With multiple fence workers, it is possible that signal calls are out of + * order. The physical value itself is monotonic, but we need to make sure + * that all signals happen in correct order if there are fence rewinds. + * We don't expect the loop to run more than once, but there might be + * extreme edge cases where we signal 2 or more. */ + while (fence->timeline_value < timeline_value) + { + ++fence->timeline_value; + did_signal = false; + + for (i = 0; i < fence->semaphore_count; ++i) + { + if (fence->timeline_value == fence->semaphores[i].u.timeline_value) + { + fence->value = fence->semaphores[i].value; + d3d12_fence_signal_external_events_locked(fence); + fence->semaphores[i] = fence->semaphores[--fence->semaphore_count]; + did_signal = true; + break; + } + } + + if (!did_signal) + FIXME("Did not signal a virtual value.\n"); + } + + /* If a rewind remains queued, the virtual value deleted above may be + * greater than any pending value, so update the max pending value. */ + d3d12_fence_update_pending_value_locked(fence); + + vkd3d_mutex_unlock(&fence->mutex); } static HRESULT STDMETHODCALLTYPE d3d12_fence_QueryInterface(ID3D12Fence *iface, @@ -907,34 +931,44 @@ static ULONG STDMETHODCALLTYPE d3d12_fence_AddRef(ID3D12Fence *iface) return refcount; } +static void d3d12_fence_incref(struct d3d12_fence *fence) +{ + InterlockedIncrement(&fence->internal_refcount); +} + static ULONG STDMETHODCALLTYPE d3d12_fence_Release(ID3D12Fence *iface) { struct d3d12_fence *fence = impl_from_ID3D12Fence(iface); ULONG refcount = InterlockedDecrement(&fence->refcount); - int rc; TRACE("%p decreasing refcount to %u.\n", fence, refcount); if (!refcount) + d3d12_fence_decref(fence); + + return refcount; +} + +static void d3d12_fence_decref(struct d3d12_fence *fence) +{ + ULONG internal_refcount = InterlockedDecrement(&fence->internal_refcount); + + if (!internal_refcount) { struct d3d12_device *device = fence->device; vkd3d_private_store_destroy(&fence->private_store); - vkd3d_fence_worker_remove_fence(&device->fence_worker, fence); - d3d12_fence_destroy_vk_objects(fence); vkd3d_free(fence->events); - if ((rc = vkd3d_mutex_destroy(&fence->mutex))) - ERR("Failed to destroy mutex, error %d.\n", rc); + vkd3d_free(fence->semaphores); + vkd3d_mutex_destroy(&fence->mutex); vkd3d_cond_destroy(&fence->null_event_cond); vkd3d_free(fence); d3d12_device_release(device); } - - return refcount; } static HRESULT STDMETHODCALLTYPE d3d12_fence_GetPrivateData(ID3D12Fence *iface, @@ -991,15 +1025,10 @@ static UINT64 STDMETHODCALLTYPE d3d12_fence_GetCompletedValue(ID3D12Fence *iface { struct d3d12_fence *fence = impl_from_ID3D12Fence(iface); uint64_t completed_value; - int rc; TRACE("iface %p.\n", iface); - if ((rc = vkd3d_mutex_lock(&fence->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return 0; - } + vkd3d_mutex_lock(&fence->mutex); completed_value = fence->value; vkd3d_mutex_unlock(&fence->mutex); return completed_value; @@ -1010,16 +1039,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_fence_SetEventOnCompletion(ID3D12Fence *i { struct d3d12_fence *fence = impl_from_ID3D12Fence(iface); unsigned int i; - bool *latch; - int rc; + bool latch = false; TRACE("iface %p, value %#"PRIx64", event %p.\n", iface, value, event); - if ((rc = vkd3d_mutex_lock(&fence->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return hresult_from_errno(rc); - } + vkd3d_mutex_lock(&fence->mutex); if (value <= fence->value) { @@ -1051,8 +1075,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_fence_SetEventOnCompletion(ID3D12Fence *i fence->events[fence->event_count].value = value; fence->events[fence->event_count].event = event; - fence->events[fence->event_count].latch = false; - latch = &fence->events[fence->event_count].latch; + fence->events[fence->event_count].latch = &latch; ++fence->event_count; /* If event is NULL, we need to block until the fence value completes. @@ -1061,7 +1084,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_fence_SetEventOnCompletion(ID3D12Fence *i * and signal a condition variable instead of calling external signal_event callback. */ if (!event) { - while (!*latch) + while (!latch) vkd3d_cond_wait(&fence->null_event_cond, &fence->mutex); } @@ -1069,16 +1092,31 @@ static HRESULT STDMETHODCALLTYPE d3d12_fence_SetEventOnCompletion(ID3D12Fence *i return S_OK; } -static HRESULT STDMETHODCALLTYPE d3d12_fence_Signal(ID3D12Fence *iface, UINT64 value) +static HRESULT d3d12_fence_signal_cpu_timeline_semaphore(struct d3d12_fence *fence, uint64_t value) { - struct d3d12_fence *fence = impl_from_ID3D12Fence(iface); + vkd3d_mutex_lock(&fence->mutex); - TRACE("iface %p, value %#"PRIx64".\n", iface, value); + fence->value = value; + d3d12_fence_signal_external_events_locked(fence); + d3d12_fence_update_pending_value_locked(fence); + + vkd3d_mutex_unlock(&fence->mutex); - return d3d12_fence_signal(fence, value, VK_NULL_HANDLE); + return d3d12_device_flush_blocked_queues(fence->device); } -static const struct ID3D12FenceVtbl d3d12_fence_vtbl = +static HRESULT STDMETHODCALLTYPE d3d12_fence_Signal(ID3D12Fence *iface, UINT64 value) +{ + struct d3d12_fence *fence = impl_from_ID3D12Fence(iface); + + TRACE("iface %p, value %#"PRIx64".\n", iface, value); + + if (fence->timeline_semaphore) + return d3d12_fence_signal_cpu_timeline_semaphore(fence, value); + return d3d12_fence_signal(fence, value, VK_NULL_HANDLE, true); +} + +static const struct ID3D12FenceVtbl d3d12_fence_vtbl = { /* IUnknown methods */ d3d12_fence_QueryInterface, @@ -1108,26 +1146,20 @@ static struct d3d12_fence *unsafe_impl_from_ID3D12Fence(ID3D12Fence *iface) static HRESULT d3d12_fence_init(struct d3d12_fence *fence, struct d3d12_device *device, UINT64 initial_value, D3D12_FENCE_FLAGS flags) { + const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + VkResult vr; HRESULT hr; - int rc; fence->ID3D12Fence_iface.lpVtbl = &d3d12_fence_vtbl; + fence->internal_refcount = 1; fence->refcount = 1; fence->value = initial_value; + fence->max_pending_value = initial_value; - if ((rc = vkd3d_mutex_init(&fence->mutex))) - { - ERR("Failed to initialize mutex, error %d.\n", rc); - return hresult_from_errno(rc); - } + vkd3d_mutex_init(&fence->mutex); - if ((rc = vkd3d_cond_init(&fence->null_event_cond))) - { - ERR("Failed to initialize cond variable, error %d.\n", rc); - vkd3d_mutex_destroy(&fence->mutex); - return hresult_from_errno(rc); - } + vkd3d_cond_init(&fence->null_event_cond); if (flags) FIXME("Ignoring flags %#x.\n", flags); @@ -1136,23 +1168,39 @@ static HRESULT d3d12_fence_init(struct d3d12_fence *fence, struct d3d12_device * fence->events_size = 0; fence->event_count = 0; - list_init(&fence->semaphores); + fence->timeline_semaphore = VK_NULL_HANDLE; + fence->timeline_value = 0; + fence->pending_timeline_value = 0; + if (device->vk_info.KHR_timeline_semaphore && (vr = vkd3d_create_timeline_semaphore(device, 0, + &fence->timeline_semaphore)) < 0) + { + WARN("Failed to create timeline semaphore, vr %d.\n", vr); + hr = hresult_from_vk_result(vr); + goto fail_destroy_null_cond; + } + + fence->semaphores = NULL; + fence->semaphores_size = 0; fence->semaphore_count = 0; memset(fence->old_vk_fences, 0, sizeof(fence->old_vk_fences)); - fence->pending_worker_operation_count = 0; - if (FAILED(hr = vkd3d_private_store_init(&fence->private_store))) { - vkd3d_mutex_destroy(&fence->mutex); - vkd3d_cond_destroy(&fence->null_event_cond); - return hr; + goto fail_destroy_timeline_semaphore; } d3d12_device_add_ref(fence->device = device); return S_OK; + +fail_destroy_timeline_semaphore: + VK_CALL(vkDestroySemaphore(device->vk_device, fence->timeline_semaphore, NULL)); +fail_destroy_null_cond: + vkd3d_cond_destroy(&fence->null_event_cond); + vkd3d_mutex_destroy(&fence->mutex); + + return hr; } HRESULT d3d12_fence_create(struct d3d12_device *device, @@ -1172,6 +1220,25 @@ HRESULT d3d12_fence_create(struct d3d12_device *device, return S_OK; } +VkResult vkd3d_create_timeline_semaphore(const struct d3d12_device *device, uint64_t initial_value, + VkSemaphore *timeline_semaphore) +{ + const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + VkSemaphoreTypeCreateInfoKHR type_info; + VkSemaphoreCreateInfo info; + + info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + info.pNext = &type_info; + info.flags = 0; + + type_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR; + type_info.pNext = NULL; + type_info.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE_KHR; + type_info.initialValue = initial_value; + + return VK_CALL(vkCreateSemaphore(device->vk_device, &info, NULL, timeline_semaphore)); +} + /* Command buffers */ static void d3d12_command_list_mark_as_invalid(struct d3d12_command_list *list, const char *message, ...) @@ -1921,6 +1988,8 @@ static void d3d12_command_list_invalidate_root_parameters(struct d3d12_command_l bindings->descriptor_set_count = 0; bindings->descriptor_table_dirty_mask = bindings->descriptor_table_active_mask & bindings->root_signature->descriptor_table_mask; bindings->push_descriptor_dirty_mask = bindings->push_descriptor_active_mask & bindings->root_signature->push_descriptor_mask; + bindings->cbv_srv_uav_heap_id = 0; + bindings->sampler_heap_id = 0; } static bool vk_barrier_parameters_from_d3d12_resource_state(unsigned int state, unsigned int stencil_state, @@ -2595,7 +2664,6 @@ static void d3d12_command_list_prepare_descriptors(struct d3d12_command_list *li unsigned int variable_binding_size, unbounded_offset, table_index, heap_size, i; const struct d3d12_root_signature *root_signature = bindings->root_signature; const struct d3d12_descriptor_set_layout *layout; - struct d3d12_device *device = list->device; const struct d3d12_desc *base_descriptor; VkDescriptorSet vk_descriptor_set; @@ -2626,8 +2694,7 @@ static void d3d12_command_list_prepare_descriptors(struct d3d12_command_list *li /* Descriptors may not be set, eg. WoW. */ && (base_descriptor = bindings->descriptor_tables[table_index])) { - heap_size = vkd3d_gpu_descriptor_allocator_range_size_from_descriptor( - &device->gpu_descriptor_allocator, base_descriptor); + heap_size = d3d12_desc_heap_range_size(base_descriptor); if (heap_size < unbounded_offset) WARN("Descriptor heap size %u is less than the offset %u of an unbounded range in table %u, " @@ -2653,11 +2720,11 @@ static bool vk_write_descriptor_set_from_d3d12_desc(VkWriteDescriptorSet *vk_des unsigned int index, bool use_array) { uint32_t descriptor_range_magic = range->descriptor_magic; - const struct vkd3d_view *view = descriptor->u.view; + const struct vkd3d_view *view = descriptor->s.u.view_info.view; uint32_t vk_binding = range->binding; uint32_t set = range->set; - if (descriptor->magic != descriptor_range_magic) + if (descriptor->s.magic != descriptor_range_magic) return false; vk_descriptor_write->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; @@ -2666,15 +2733,15 @@ static bool vk_write_descriptor_set_from_d3d12_desc(VkWriteDescriptorSet *vk_des vk_descriptor_write->dstBinding = use_array ? vk_binding : vk_binding + index; vk_descriptor_write->dstArrayElement = use_array ? index : 0; vk_descriptor_write->descriptorCount = 1; - vk_descriptor_write->descriptorType = descriptor->vk_descriptor_type; + vk_descriptor_write->descriptorType = descriptor->s.vk_descriptor_type; vk_descriptor_write->pImageInfo = NULL; vk_descriptor_write->pBufferInfo = NULL; vk_descriptor_write->pTexelBufferView = NULL; - switch (descriptor->magic) + switch (descriptor->s.magic) { case VKD3D_DESCRIPTOR_MAGIC_CBV: - vk_descriptor_write->pBufferInfo = &descriptor->u.vk_cbv_info; + vk_descriptor_write->pBufferInfo = &descriptor->s.u.vk_cbv_info; break; case VKD3D_DESCRIPTOR_MAGIC_SRV: @@ -2685,8 +2752,8 @@ static bool vk_write_descriptor_set_from_d3d12_desc(VkWriteDescriptorSet *vk_des * in pairs in one set. */ if (range->descriptor_count == UINT_MAX) { - if (descriptor->vk_descriptor_type != VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER - && descriptor->vk_descriptor_type != VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) + if (descriptor->s.vk_descriptor_type != VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER + && descriptor->s.vk_descriptor_type != VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) { vk_descriptor_write->dstSet = vk_descriptor_sets[set + 1]; vk_descriptor_write->dstBinding = 0; @@ -2696,13 +2763,13 @@ static bool vk_write_descriptor_set_from_d3d12_desc(VkWriteDescriptorSet *vk_des { if (!use_array) vk_descriptor_write->dstBinding = vk_binding + 2 * index; - if (descriptor->vk_descriptor_type != VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER - && descriptor->vk_descriptor_type != VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) + if (descriptor->s.vk_descriptor_type != VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER + && descriptor->s.vk_descriptor_type != VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) ++vk_descriptor_write->dstBinding; } - if (descriptor->vk_descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER - || descriptor->vk_descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) + if (descriptor->s.vk_descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER + || descriptor->s.vk_descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) { vk_descriptor_write->pTexelBufferView = &view->u.vk_buffer_view; } @@ -2710,7 +2777,7 @@ static bool vk_write_descriptor_set_from_d3d12_desc(VkWriteDescriptorSet *vk_des { vk_image_info->sampler = VK_NULL_HANDLE; vk_image_info->imageView = view->u.vk_image_view; - vk_image_info->imageLayout = descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_SRV + vk_image_info->imageLayout = descriptor->s.magic == VKD3D_DESCRIPTOR_MAGIC_SRV ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL; vk_descriptor_write->pImageInfo = vk_image_info; @@ -2726,7 +2793,7 @@ static bool vk_write_descriptor_set_from_d3d12_desc(VkWriteDescriptorSet *vk_des break; default: - ERR("Invalid descriptor %#x.\n", descriptor->magic); + ERR("Invalid descriptor %#x.\n", descriptor->s.magic); return false; } @@ -2767,8 +2834,7 @@ static void d3d12_command_list_update_descriptor_table(struct d3d12_command_list descriptor_count = range->descriptor_count; if ((unbounded = descriptor_count == UINT_MAX)) { - descriptor_count = vkd3d_gpu_descriptor_allocator_range_size_from_descriptor( - &list->device->gpu_descriptor_allocator, descriptor); + descriptor_count = d3d12_desc_heap_range_size(descriptor); if (descriptor_count > range->vk_binding_count) { @@ -2790,8 +2856,8 @@ static void d3d12_command_list_update_descriptor_table(struct d3d12_command_list if (state->uav_counters.bindings[k].register_space == range->register_space && state->uav_counters.bindings[k].register_index == register_idx) { - VkBufferView vk_counter_view = descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_UAV - ? descriptor->u.view->vk_counter_view : VK_NULL_HANDLE; + VkBufferView vk_counter_view = descriptor->s.magic == VKD3D_DESCRIPTOR_MAGIC_UAV + ? descriptor->s.u.view_info.view->vk_counter_view : VK_NULL_HANDLE; if (bindings->vk_uav_counter_views[k] != vk_counter_view) bindings->uav_counters_dirty = true; bindings->vk_uav_counter_views[k] = vk_counter_view; @@ -2801,7 +2867,7 @@ static void d3d12_command_list_update_descriptor_table(struct d3d12_command_list } /* Not all descriptors are necessarily populated if the range is unbounded. */ - if (descriptor->magic == VKD3D_DESCRIPTOR_MAGIC_FREE) + if (descriptor->s.magic == VKD3D_DESCRIPTOR_MAGIC_FREE) continue; if (!vk_write_descriptor_set_from_d3d12_desc(current_descriptor_write, current_image_info, @@ -3021,6 +3087,146 @@ static void d3d12_command_list_update_descriptors(struct d3d12_command_list *lis d3d12_command_list_update_uav_counter_descriptors(list, bind_point); } +static unsigned int d3d12_command_list_bind_descriptor_table(struct d3d12_command_list *list, + struct vkd3d_pipeline_bindings *bindings, unsigned int index, + struct d3d12_descriptor_heap **cbv_srv_uav_heap, struct d3d12_descriptor_heap **sampler_heap) +{ + struct d3d12_descriptor_heap *heap; + const struct d3d12_desc *desc; + unsigned int offset; + + if (!(desc = bindings->descriptor_tables[index])) + return 0; + + /* AMD, Nvidia and Intel drivers on Windows work if SetDescriptorHeaps() + * is not called, so we bind heaps from the tables instead. No NULL check is + * needed here because it's checked when descriptor tables are set. */ + heap = d3d12_desc_get_descriptor_heap(desc); + offset = desc->index; + + if (heap->desc.Type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV) + { + if (*cbv_srv_uav_heap) + { + if (heap == *cbv_srv_uav_heap) + return offset; + /* This occurs occasionally in Rise of the Tomb Raider apparently due to a race + * condition (one of several), but adding a mutex for table updates has no effect. */ + WARN("List %p uses descriptors from more than one CBV/SRV/UAV heap.\n", list); + } + *cbv_srv_uav_heap = heap; + } + else + { + if (*sampler_heap) + { + if (heap == *sampler_heap) + return offset; + WARN("List %p uses descriptors from more than one sampler heap.\n", list); + } + *sampler_heap = heap; + } + + return offset; +} + +static void d3d12_command_list_update_descriptor_tables(struct d3d12_command_list *list, + struct vkd3d_pipeline_bindings *bindings, struct d3d12_descriptor_heap **cbv_srv_uav_heap, + struct d3d12_descriptor_heap **sampler_heap) +{ + const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs; + const struct d3d12_root_signature *rs = bindings->root_signature; + unsigned int offsets[D3D12_MAX_ROOT_COST]; + unsigned int i, j; + + for (i = 0, j = 0; i < ARRAY_SIZE(bindings->descriptor_tables); ++i) + { + if (!(rs->descriptor_table_mask & ((uint64_t)1 << i))) + continue; + offsets[j++] = d3d12_command_list_bind_descriptor_table(list, bindings, i, + cbv_srv_uav_heap, sampler_heap); + } + if (j) + { + VK_CALL(vkCmdPushConstants(list->vk_command_buffer, rs->vk_pipeline_layout, VK_SHADER_STAGE_ALL, + rs->descriptor_table_offset, j * sizeof(uint32_t), offsets)); + } +} + +static void d3d12_command_list_bind_descriptor_heap(struct d3d12_command_list *list, + enum vkd3d_pipeline_bind_point bind_point, struct d3d12_descriptor_heap *heap) +{ + struct vkd3d_pipeline_bindings *bindings = &list->pipeline_bindings[bind_point]; + const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs; + const struct d3d12_root_signature *rs = bindings->root_signature; + enum vkd3d_vk_descriptor_set_index set; + + if (!heap) + return; + + if (heap->desc.Type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV) + { + if (heap->serial_id == bindings->cbv_srv_uav_heap_id) + return; + bindings->cbv_srv_uav_heap_id = heap->serial_id; + } + else + { + if (heap->serial_id == bindings->sampler_heap_id) + return; + bindings->sampler_heap_id = heap->serial_id; + } + + /* These sets can be shared across multiple command lists, and therefore binding must + * be synchronised. On an experimental branch in which caching of Vk descriptor writes + * greatly increased the chance of multiple threads arriving here at the same time, + * GRID 2019 crashed without the mutex lock. */ + vkd3d_mutex_lock(&heap->vk_sets_mutex); + + for (set = 0; set < ARRAY_SIZE(heap->vk_descriptor_sets); ++set) + { + VkDescriptorSet vk_descriptor_set = heap->vk_descriptor_sets[set].vk_set; + + if (!vk_descriptor_set) + continue; + + VK_CALL(vkCmdBindDescriptorSets(list->vk_command_buffer, bindings->vk_bind_point, rs->vk_pipeline_layout, + rs->vk_set_count + set, 1, &vk_descriptor_set, 0, NULL)); + } + + vkd3d_mutex_unlock(&heap->vk_sets_mutex); +} + +static void d3d12_command_list_update_heap_descriptors(struct d3d12_command_list *list, + enum vkd3d_pipeline_bind_point bind_point) +{ + struct vkd3d_pipeline_bindings *bindings = &list->pipeline_bindings[bind_point]; + struct d3d12_descriptor_heap *cbv_srv_uav_heap = NULL, *sampler_heap = NULL; + const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs; + const struct d3d12_root_signature *rs = bindings->root_signature; + + if (!rs) + return; + + if (bindings->descriptor_table_dirty_mask || bindings->push_descriptor_dirty_mask) + d3d12_command_list_prepare_descriptors(list, bind_point); + if (bindings->descriptor_table_dirty_mask) + d3d12_command_list_update_descriptor_tables(list, bindings, &cbv_srv_uav_heap, &sampler_heap); + bindings->descriptor_table_dirty_mask = 0; + + d3d12_command_list_update_push_descriptors(list, bind_point); + + if (bindings->descriptor_set_count) + { + VK_CALL(vkCmdBindDescriptorSets(list->vk_command_buffer, bindings->vk_bind_point, rs->vk_pipeline_layout, + rs->main_set, bindings->descriptor_set_count, bindings->descriptor_sets, 0, NULL)); + bindings->in_use = true; + } + + d3d12_command_list_bind_descriptor_heap(list, bind_point, cbv_srv_uav_heap); + d3d12_command_list_bind_descriptor_heap(list, bind_point, sampler_heap); +} + static bool d3d12_command_list_update_compute_state(struct d3d12_command_list *list) { d3d12_command_list_end_current_render_pass(list); @@ -3028,7 +3234,7 @@ static bool d3d12_command_list_update_compute_state(struct d3d12_command_list *l if (!d3d12_command_list_update_compute_pipeline(list)) return false; - d3d12_command_list_update_descriptors(list, VKD3D_PIPELINE_BIND_POINT_COMPUTE); + list->update_descriptors(list, VKD3D_PIPELINE_BIND_POINT_COMPUTE); return true; } @@ -3045,7 +3251,7 @@ static bool d3d12_command_list_begin_render_pass(struct d3d12_command_list *list if (!d3d12_command_list_update_current_framebuffer(list)) return false; - d3d12_command_list_update_descriptors(list, VKD3D_PIPELINE_BIND_POINT_GRAPHICS); + list->update_descriptors(list, VKD3D_PIPELINE_BIND_POINT_GRAPHICS); if (list->current_render_pass != VK_NULL_HANDLE) return true; @@ -4113,6 +4319,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetDescriptorHeaps(ID3D12Graphi TRACE("iface %p, heap_count %u, heaps %p.\n", iface, heap_count, heaps); /* Our current implementation does not need this method. + * In Windows it doesn't need to be called at all for correct operation, and + * at least on AMD the wrong heaps can be set here and tests still succeed. * * It could be used to validate descriptor tables but we do not have an * equivalent of the D3D12 Debug Layer. */ @@ -4168,16 +4376,6 @@ static void d3d12_command_list_set_descriptor_table(struct d3d12_command_list *l if (bindings->descriptor_tables[index] == desc) return; - if (desc && !vkd3d_gpu_descriptor_allocator_heap_from_descriptor(&list->device->gpu_descriptor_allocator, - desc)) - { - /* Failure to find a heap means the descriptor handle is from - * the wrong heap type or not a handle at all. */ - ERR("Invalid heap for base descriptor %"PRIx64".\n", base_descriptor.ptr); - /* TODO: Mark list as invalid? */ - return; - } - bindings->descriptor_tables[index] = desc; bindings->descriptor_table_dirty_mask |= (uint64_t)1 << index; bindings->descriptor_table_active_mask |= (uint64_t)1 << index; @@ -5108,7 +5306,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID iface, gpu_handle.ptr, cpu_handle.ptr, resource, values, rect_count, rects); resource_impl = unsafe_impl_from_ID3D12Resource(resource); - view = d3d12_desc_from_cpu_handle(cpu_handle)->u.view; + view = d3d12_desc_from_cpu_handle(cpu_handle)->s.u.view_info.view; memcpy(colour.uint32, values, sizeof(colour.uint32)); if (view->format->type != VKD3D_FORMAT_TYPE_UINT) @@ -5167,7 +5365,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(I iface, gpu_handle.ptr, cpu_handle.ptr, resource, values, rect_count, rects); resource_impl = unsafe_impl_from_ID3D12Resource(resource); - view = d3d12_desc_from_cpu_handle(cpu_handle)->u.view; + view = d3d12_desc_from_cpu_handle(cpu_handle)->s.u.view_info.view; memcpy(colour.float32, values, sizeof(colour.float32)); d3d12_command_list_clear_uav(list, resource_impl, view, &colour, rect_count, rects); @@ -5706,6 +5904,9 @@ static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, struct d list->allocator = allocator; + list->update_descriptors = device->use_vk_heaps ? d3d12_command_list_update_heap_descriptors + : d3d12_command_list_update_descriptors; + if (SUCCEEDED(hr = d3d12_command_allocator_allocate_command_buffer(allocator, list))) { list->pipeline_bindings[VKD3D_PIPELINE_BIND_POINT_GRAPHICS].vk_uav_counter_views = NULL; @@ -5798,6 +5999,11 @@ static ULONG STDMETHODCALLTYPE d3d12_command_queue_AddRef(ID3D12CommandQueue *if return refcount; } +static void d3d12_command_queue_op_array_destroy(struct d3d12_command_queue_op_array *array) +{ + vkd3d_free(array->ops); +} + static ULONG STDMETHODCALLTYPE d3d12_command_queue_Release(ID3D12CommandQueue *iface) { struct d3d12_command_queue *command_queue = impl_from_ID3D12CommandQueue(iface); @@ -5809,6 +6015,12 @@ static ULONG STDMETHODCALLTYPE d3d12_command_queue_Release(ID3D12CommandQueue *i { struct d3d12_device *device = command_queue->device; + vkd3d_fence_worker_stop(&command_queue->fence_worker, device); + + vkd3d_mutex_destroy(&command_queue->op_mutex); + d3d12_command_queue_op_array_destroy(&command_queue->op_queue); + d3d12_command_queue_op_array_destroy(&command_queue->aux_op_queue); + vkd3d_private_store_destroy(&command_queue->private_store); vkd3d_free(command_queue); @@ -5878,20 +6090,24 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_GetDevice(ID3D12CommandQueu return d3d12_device_query_interface(command_queue->device, iid, device); } +static struct vkd3d_cs_op_data *d3d12_command_queue_op_array_require_space(struct d3d12_command_queue_op_array *array) +{ + if (!vkd3d_array_reserve((void **)&array->ops, &array->size, array->count + 1, sizeof(*array->ops))) + return NULL; + + return &array->ops[array->count++]; +} + static void STDMETHODCALLTYPE d3d12_command_queue_UpdateTileMappings(ID3D12CommandQueue *iface, ID3D12Resource *resource, UINT region_count, - const D3D12_TILED_RESOURCE_COORDINATE *region_start_coordinates, - const D3D12_TILE_REGION_SIZE *region_sizes, - UINT range_count, - const D3D12_TILE_RANGE_FLAGS *range_flags, - UINT *heap_range_offsets, - UINT *range_tile_counts, - D3D12_TILE_MAPPING_FLAGS flags) + const D3D12_TILED_RESOURCE_COORDINATE *region_start_coordinates, const D3D12_TILE_REGION_SIZE *region_sizes, + ID3D12Heap *heap, UINT range_count, const D3D12_TILE_RANGE_FLAGS *range_flags, + UINT *heap_range_offsets, UINT *range_tile_counts, D3D12_TILE_MAPPING_FLAGS flags) { FIXME("iface %p, resource %p, region_count %u, region_start_coordinates %p, " - "region_sizes %p, range_count %u, range_flags %p, heap_range_offsets %p, " + "region_sizes %p, heap %p, range_count %u, range_flags %p, heap_range_offsets %p, " "range_tile_counts %p, flags %#x stub!\n", - iface, resource, region_count, region_start_coordinates, region_sizes, range_count, + iface, resource, region_count, region_start_coordinates, region_sizes, heap, range_count, range_flags, heap_range_offsets, range_tile_counts, flags); } @@ -5909,22 +6125,61 @@ static void STDMETHODCALLTYPE d3d12_command_queue_CopyTileMappings(ID3D12Command src_region_start_coordinate, region_size, flags); } +static void d3d12_command_queue_execute(struct d3d12_command_queue *command_queue, + VkCommandBuffer *buffers, unsigned int count) +{ + const struct vkd3d_vk_device_procs *vk_procs = &command_queue->device->vk_procs; + struct vkd3d_queue *vkd3d_queue = command_queue->vkd3d_queue; + VkSubmitInfo submit_desc; + VkQueue vk_queue; + VkResult vr; + + memset(&submit_desc, 0, sizeof(submit_desc)); + + if (!(vk_queue = vkd3d_queue_acquire(vkd3d_queue))) + { + ERR("Failed to acquire queue %p.\n", vkd3d_queue); + return; + } + + submit_desc.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submit_desc.commandBufferCount = count; + submit_desc.pCommandBuffers = buffers; + + if ((vr = VK_CALL(vkQueueSubmit(vk_queue, 1, &submit_desc, VK_NULL_HANDLE))) < 0) + ERR("Failed to submit queue(s), vr %d.\n", vr); + + vkd3d_queue_release(vkd3d_queue); + + vkd3d_free(buffers); +} + +static void d3d12_command_queue_submit_locked(struct d3d12_command_queue *queue) +{ + bool flushed_any = false; + HRESULT hr; + + if (queue->op_queue.count == 1 && !queue->is_flushing) + { + if (FAILED(hr = d3d12_command_queue_flush_ops_locked(queue, &flushed_any))) + ERR("Cannot flush queue, hr %#x.\n", hr); + } +} + static void STDMETHODCALLTYPE d3d12_command_queue_ExecuteCommandLists(ID3D12CommandQueue *iface, UINT command_list_count, ID3D12CommandList * const *command_lists) { struct d3d12_command_queue *command_queue = impl_from_ID3D12CommandQueue(iface); - const struct vkd3d_vk_device_procs *vk_procs; struct d3d12_command_list *cmd_list; - struct VkSubmitInfo submit_desc; + struct vkd3d_cs_op_data *op; VkCommandBuffer *buffers; - VkQueue vk_queue; unsigned int i; - VkResult vr; TRACE("iface %p, command_list_count %u, command_lists %p.\n", iface, command_list_count, command_lists); - vk_procs = &command_queue->device->vk_procs; + if (!command_list_count) + return; if (!(buffers = vkd3d_calloc(command_list_count, sizeof(*buffers)))) { @@ -5947,29 +6202,21 @@ static void STDMETHODCALLTYPE d3d12_command_queue_ExecuteCommandLists(ID3D12Comm buffers[i] = cmd_list->vk_command_buffer; } - submit_desc.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submit_desc.pNext = NULL; - submit_desc.waitSemaphoreCount = 0; - submit_desc.pWaitSemaphores = NULL; - submit_desc.pWaitDstStageMask = NULL; - submit_desc.commandBufferCount = command_list_count; - submit_desc.pCommandBuffers = buffers; - submit_desc.signalSemaphoreCount = 0; - submit_desc.pSignalSemaphores = NULL; + vkd3d_mutex_lock(&command_queue->op_mutex); - if (!(vk_queue = vkd3d_queue_acquire(command_queue->vkd3d_queue))) + if (!(op = d3d12_command_queue_op_array_require_space(&command_queue->op_queue))) { - ERR("Failed to acquire queue %p.\n", command_queue->vkd3d_queue); - vkd3d_free(buffers); + ERR("Failed to add op.\n"); return; } + op->opcode = VKD3D_CS_OP_EXECUTE; + op->u.execute.buffers = buffers; + op->u.execute.buffer_count = command_list_count; - if ((vr = VK_CALL(vkQueueSubmit(vk_queue, 1, &submit_desc, VK_NULL_HANDLE))) < 0) - ERR("Failed to submit queue(s), vr %d.\n", vr); + d3d12_command_queue_submit_locked(command_queue); - vkd3d_queue_release(command_queue->vkd3d_queue); - - vkd3d_free(buffers); + vkd3d_mutex_unlock(&command_queue->op_mutex); + return; } static void STDMETHODCALLTYPE d3d12_command_queue_SetMarker(ID3D12CommandQueue *iface, @@ -5982,7 +6229,7 @@ static void STDMETHODCALLTYPE d3d12_command_queue_SetMarker(ID3D12CommandQueue * static void STDMETHODCALLTYPE d3d12_command_queue_BeginEvent(ID3D12CommandQueue *iface, UINT metadata, const void *data, UINT size) { - FIXME("iface %p, metatdata %#x, data %p, size %u stub!\n", + FIXME("iface %p, metadata %#x, data %p, size %u stub!\n", iface, metadata, data, size); } @@ -5991,34 +6238,104 @@ static void STDMETHODCALLTYPE d3d12_command_queue_EndEvent(ID3D12CommandQueue *i FIXME("iface %p stub!\n", iface); } +static HRESULT vkd3d_enqueue_timeline_semaphore(struct vkd3d_fence_worker *worker, VkSemaphore vk_semaphore, + struct d3d12_fence *fence, uint64_t value, struct vkd3d_queue *queue) +{ + struct vkd3d_waiting_fence *waiting_fence; + + TRACE("worker %p, fence %p, value %#"PRIx64".\n", worker, fence, value); + + vkd3d_mutex_lock(&worker->mutex); + + if (!vkd3d_array_reserve((void **)&worker->fences, &worker->fences_size, + worker->fence_count + 1, sizeof(*worker->fences))) + { + ERR("Failed to add GPU timeline semaphore.\n"); + vkd3d_mutex_unlock(&worker->mutex); + return E_OUTOFMEMORY; + } + + waiting_fence = &worker->fences[worker->fence_count++]; + waiting_fence->fence = fence; + waiting_fence->value = value; + waiting_fence->u.vk_semaphore = vk_semaphore; + + d3d12_fence_incref(fence); + + vkd3d_cond_signal(&worker->cond); + vkd3d_mutex_unlock(&worker->mutex); + + return S_OK; +} + static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Signal(ID3D12CommandQueue *iface, ID3D12Fence *fence_iface, UINT64 value) { struct d3d12_command_queue *command_queue = impl_from_ID3D12CommandQueue(iface); + struct d3d12_fence *fence = unsafe_impl_from_ID3D12Fence(fence_iface); + struct vkd3d_cs_op_data *op; + HRESULT hr = S_OK; + + TRACE("iface %p, fence %p, value %#"PRIx64".\n", iface, fence_iface, value); + + vkd3d_mutex_lock(&command_queue->op_mutex); + + if (!(op = d3d12_command_queue_op_array_require_space(&command_queue->op_queue))) + { + hr = E_OUTOFMEMORY; + goto done; + } + op->opcode = VKD3D_CS_OP_SIGNAL; + op->u.signal.fence = fence; + op->u.signal.value = value; + + d3d12_fence_incref(fence); + + d3d12_command_queue_submit_locked(command_queue); + +done: + vkd3d_mutex_unlock(&command_queue->op_mutex); + return hr; +} + +static HRESULT d3d12_command_queue_signal(struct d3d12_command_queue *command_queue, + struct d3d12_fence *fence, uint64_t value) +{ + VkTimelineSemaphoreSubmitInfoKHR timeline_submit_info; const struct vkd3d_vk_device_procs *vk_procs; VkSemaphore vk_semaphore = VK_NULL_HANDLE; VkFence vk_fence = VK_NULL_HANDLE; struct vkd3d_queue *vkd3d_queue; + uint64_t sequence_number = 0; + uint64_t timeline_value = 0; struct d3d12_device *device; - struct d3d12_fence *fence; VkSubmitInfo submit_info; - uint64_t sequence_number; VkQueue vk_queue; VkResult vr; HRESULT hr; - TRACE("iface %p, fence %p, value %#"PRIx64".\n", iface, fence_iface, value); - device = command_queue->device; vk_procs = &device->vk_procs; vkd3d_queue = command_queue->vkd3d_queue; - fence = unsafe_impl_from_ID3D12Fence(fence_iface); + if (device->vk_info.KHR_timeline_semaphore) + { + if (!(timeline_value = d3d12_fence_add_pending_timeline_signal(fence, value, vkd3d_queue))) + { + ERR("Failed to add pending signal.\n"); + return E_OUTOFMEMORY; + } - if ((vr = d3d12_fence_create_vk_fence(fence, &vk_fence)) < 0) + vk_semaphore = fence->timeline_semaphore; + assert(vk_semaphore); + } + else { - WARN("Failed to create Vulkan fence, vr %d.\n", vr); - goto fail_vkresult; + if ((vr = d3d12_fence_create_vk_fence(fence, &vk_fence)) < 0) + { + WARN("Failed to create Vulkan fence, vr %d.\n", vr); + goto fail_vkresult; + } } if (!(vk_queue = vkd3d_queue_acquire(vkd3d_queue))) @@ -6028,7 +6345,8 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Signal(ID3D12CommandQueue * goto fail; } - if ((vr = vkd3d_queue_create_vk_semaphore_locked(vkd3d_queue, device, &vk_semaphore)) < 0) + if (!device->vk_info.KHR_timeline_semaphore && (vr = vkd3d_queue_create_vk_semaphore_locked(vkd3d_queue, + device, &vk_semaphore)) < 0) { ERR("Failed to create Vulkan semaphore, vr %d.\n", vr); vk_semaphore = VK_NULL_HANDLE; @@ -6044,7 +6362,19 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Signal(ID3D12CommandQueue * submit_info.signalSemaphoreCount = vk_semaphore ? 1 : 0; submit_info.pSignalSemaphores = &vk_semaphore; - if ((vr = VK_CALL(vkQueueSubmit(vk_queue, 1, &submit_info, vk_fence))) >= 0) + if (device->vk_info.KHR_timeline_semaphore) + { + timeline_submit_info.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR; + timeline_submit_info.pNext = NULL; + timeline_submit_info.pSignalSemaphoreValues = &timeline_value; + timeline_submit_info.signalSemaphoreValueCount = submit_info.signalSemaphoreCount; + timeline_submit_info.waitSemaphoreValueCount = 0; + timeline_submit_info.pWaitSemaphoreValues = NULL; + submit_info.pNext = &timeline_submit_info; + } + + vr = VK_CALL(vkQueueSubmit(vk_queue, 1, &submit_info, vk_fence)); + if (!device->vk_info.KHR_timeline_semaphore && vr >= 0) { sequence_number = ++vkd3d_queue->submitted_sequence_number; @@ -6061,19 +6391,37 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Signal(ID3D12CommandQueue * goto fail_vkresult; } - if (vk_semaphore && SUCCEEDED(hr = d3d12_fence_add_vk_semaphore(fence, vk_semaphore, vk_fence, value))) + if (device->vk_info.KHR_timeline_semaphore) + { + if (FAILED(hr = d3d12_fence_update_pending_value(fence))) + return hr; + + if (FAILED(hr = d3d12_device_flush_blocked_queues(device))) + return hr; + + vk_semaphore = fence->timeline_semaphore; + assert(vk_semaphore); + + return vkd3d_enqueue_timeline_semaphore(&command_queue->fence_worker, + vk_semaphore, fence, timeline_value, vkd3d_queue); + } + + if (vk_semaphore && SUCCEEDED(hr = d3d12_fence_add_vk_semaphore(fence, vk_semaphore, vk_fence, value, vkd3d_queue))) vk_semaphore = VK_NULL_HANDLE; vr = VK_CALL(vkGetFenceStatus(device->vk_device, vk_fence)); if (vr == VK_NOT_READY) { - if (SUCCEEDED(hr = vkd3d_enqueue_gpu_fence(&device->fence_worker, vk_fence, fence, value, vkd3d_queue, sequence_number))) + if (SUCCEEDED(hr = vkd3d_enqueue_gpu_fence(&command_queue->fence_worker, + vk_fence, fence, value, vkd3d_queue, sequence_number))) + { vk_fence = VK_NULL_HANDLE; + } } else if (vr == VK_SUCCESS) { TRACE("Already signaled %p, value %#"PRIx64".\n", fence, value); - hr = d3d12_fence_signal(fence, value, vk_fence); + hr = d3d12_fence_signal(fence, value, vk_fence, false); vk_fence = VK_NULL_HANDLE; vkd3d_queue_update_sequence_number(vkd3d_queue, sequence_number, device); } @@ -6096,33 +6444,31 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Signal(ID3D12CommandQueue * hr = hresult_from_vk_result(vr); fail: VK_CALL(vkDestroyFence(device->vk_device, vk_fence, NULL)); - VK_CALL(vkDestroySemaphore(device->vk_device, vk_semaphore, NULL)); + if (!device->vk_info.KHR_timeline_semaphore) + VK_CALL(vkDestroySemaphore(device->vk_device, vk_semaphore, NULL)); return hr; } -static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Wait(ID3D12CommandQueue *iface, - ID3D12Fence *fence_iface, UINT64 value) +static HRESULT d3d12_command_queue_wait_binary_semaphore_locked(struct d3d12_command_queue *command_queue, + struct d3d12_fence *fence, uint64_t value) { static const VkPipelineStageFlagBits wait_stage_mask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; - struct d3d12_command_queue *command_queue = impl_from_ID3D12CommandQueue(iface); const struct vkd3d_vk_device_procs *vk_procs; struct vkd3d_signaled_semaphore *semaphore; uint64_t completed_value = 0; struct vkd3d_queue *queue; - struct d3d12_fence *fence; VkSubmitInfo submit_info; VkQueue vk_queue; VkResult vr; HRESULT hr; - TRACE("iface %p, fence %p, value %#"PRIx64".\n", iface, fence_iface, value); - vk_procs = &command_queue->device->vk_procs; queue = command_queue->vkd3d_queue; - fence = unsafe_impl_from_ID3D12Fence(fence_iface); + semaphore = d3d12_fence_acquire_vk_semaphore_locked(fence, value, &completed_value); + + vkd3d_mutex_unlock(&fence->mutex); - semaphore = d3d12_fence_acquire_vk_semaphore(fence, value, &completed_value); if (!semaphore && completed_value >= value) { /* We don't get a Vulkan semaphore if the fence was signaled on CPU. */ @@ -6145,7 +6491,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Wait(ID3D12CommandQueue *if } else { - FIXME("Failed to acquire Vulkan semaphore for fence %p, value %#"PRIx64 + WARN("Failed to acquire Vulkan semaphore for fence %p, value %#"PRIx64 ", completed value %#"PRIx64".\n", fence, value, completed_value); } @@ -6156,7 +6502,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Wait(ID3D12CommandQueue *if submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submit_info.pNext = NULL; submit_info.waitSemaphoreCount = 1; - submit_info.pWaitSemaphores = &semaphore->vk_semaphore; + submit_info.pWaitSemaphores = &semaphore->u.binary.vk_semaphore; submit_info.pWaitDstStageMask = &wait_stage_mask; submit_info.commandBufferCount = 0; submit_info.pCommandBuffers = NULL; @@ -6174,7 +6520,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Wait(ID3D12CommandQueue *if if ((vr = VK_CALL(vkQueueSubmit(vk_queue, 1, &submit_info, VK_NULL_HANDLE))) >= 0) { - queue->semaphores[queue->semaphore_count].vk_semaphore = semaphore->vk_semaphore; + queue->semaphores[queue->semaphore_count].vk_semaphore = semaphore->u.binary.vk_semaphore; queue->semaphores[queue->semaphore_count].sequence_number = queue->submitted_sequence_number + 1; ++queue->semaphore_count; @@ -6199,6 +6545,97 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Wait(ID3D12CommandQueue *if return hr; } +static HRESULT d3d12_command_queue_wait_locked(struct d3d12_command_queue *command_queue, + struct d3d12_fence *fence, uint64_t value) +{ + static const VkPipelineStageFlagBits wait_stage_mask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; + VkTimelineSemaphoreSubmitInfoKHR timeline_submit_info; + const struct vkd3d_vk_device_procs *vk_procs; + struct vkd3d_queue *queue; + VkSubmitInfo submit_info; + uint64_t wait_value; + VkQueue vk_queue; + VkResult vr; + + vk_procs = &command_queue->device->vk_procs; + queue = command_queue->vkd3d_queue; + + if (!command_queue->device->vk_info.KHR_timeline_semaphore) + return d3d12_command_queue_wait_binary_semaphore_locked(command_queue, fence, value); + + wait_value = d3d12_fence_get_timeline_wait_value_locked(fence, value); + + /* We can unlock the fence here. The queue semaphore will not be signalled to signal_value + * until we have submitted, so the semaphore cannot be destroyed before the call to vkQueueSubmit. */ + vkd3d_mutex_unlock(&fence->mutex); + + assert(fence->timeline_semaphore); + timeline_submit_info.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR; + timeline_submit_info.pNext = NULL; + timeline_submit_info.waitSemaphoreValueCount = 1; + timeline_submit_info.pWaitSemaphoreValues = &wait_value; + timeline_submit_info.signalSemaphoreValueCount = 0; + timeline_submit_info.pSignalSemaphoreValues = NULL; + + submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submit_info.pNext = &timeline_submit_info; + submit_info.waitSemaphoreCount = 1; + submit_info.pWaitSemaphores = &fence->timeline_semaphore; + submit_info.pWaitDstStageMask = &wait_stage_mask; + submit_info.commandBufferCount = 0; + submit_info.pCommandBuffers = NULL; + submit_info.signalSemaphoreCount = 0; + submit_info.pSignalSemaphores = NULL; + + if (!(vk_queue = vkd3d_queue_acquire(queue))) + { + ERR("Failed to acquire queue %p.\n", queue); + return E_FAIL; + } + + vr = VK_CALL(vkQueueSubmit(vk_queue, 1, &submit_info, VK_NULL_HANDLE)); + + vkd3d_queue_release(queue); + + if (vr < 0) + { + WARN("Failed to submit wait operation, vr %d.\n", vr); + return hresult_from_vk_result(vr); + } + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Wait(ID3D12CommandQueue *iface, + ID3D12Fence *fence_iface, UINT64 value) +{ + struct d3d12_command_queue *command_queue = impl_from_ID3D12CommandQueue(iface); + struct d3d12_fence *fence = unsafe_impl_from_ID3D12Fence(fence_iface); + struct vkd3d_cs_op_data *op; + HRESULT hr = S_OK; + + TRACE("iface %p, fence %p, value %#"PRIx64".\n", iface, fence_iface, value); + + vkd3d_mutex_lock(&command_queue->op_mutex); + + if (!(op = d3d12_command_queue_op_array_require_space(&command_queue->op_queue))) + { + hr = E_OUTOFMEMORY; + goto done; + } + op->opcode = VKD3D_CS_OP_WAIT; + op->u.wait.fence = fence; + op->u.wait.value = value; + + d3d12_fence_incref(fence); + + d3d12_command_queue_submit_locked(command_queue); + +done: + vkd3d_mutex_unlock(&command_queue->op_mutex); + return hr; +} + static HRESULT STDMETHODCALLTYPE d3d12_command_queue_GetTimestampFrequency(ID3D12CommandQueue *iface, UINT64 *frequency) { @@ -6320,6 +6757,141 @@ static const struct ID3D12CommandQueueVtbl d3d12_command_queue_vtbl = d3d12_command_queue_GetDesc, }; +static void d3d12_command_queue_swap_queues(struct d3d12_command_queue *queue) +{ + struct d3d12_command_queue_op_array array; + + array = queue->op_queue; + queue->op_queue = queue->aux_op_queue; + queue->aux_op_queue = array; +} + +static bool d3d12_command_queue_op_array_append(struct d3d12_command_queue_op_array *array, + size_t count, const struct vkd3d_cs_op_data *new_ops) +{ + if (!vkd3d_array_reserve((void **)&array->ops, &array->size, array->count + count, sizeof(*array->ops))) + { + ERR("Cannot reserve memory for %zu new ops.\n", count); + return false; + } + + memcpy(&array->ops[array->count], new_ops, count * sizeof(*array->ops)); + array->count += count; + + return true; +} + +static void d3d12_command_queue_delete_aux_ops(struct d3d12_command_queue *queue, + unsigned int done_count) +{ + queue->aux_op_queue.count -= done_count; + memmove(queue->aux_op_queue.ops, &queue->aux_op_queue.ops[done_count], + queue->aux_op_queue.count * sizeof(*queue->aux_op_queue.ops)); +} + +static HRESULT d3d12_command_queue_fixup_after_flush_locked(struct d3d12_command_queue *queue) +{ + d3d12_command_queue_swap_queues(queue); + + d3d12_command_queue_op_array_append(&queue->op_queue, queue->aux_op_queue.count, queue->aux_op_queue.ops); + + queue->aux_op_queue.count = 0; + queue->is_flushing = false; + + return d3d12_command_queue_record_as_blocked(queue); +} + +static HRESULT d3d12_command_queue_flush_ops(struct d3d12_command_queue *queue, bool *flushed_any) +{ + HRESULT hr; + + vkd3d_mutex_lock(&queue->op_mutex); + + /* This function may be re-entered when invoking + * d3d12_command_queue_signal(). The first call is responsible + * for re-adding the queue to the flush list. */ + if (queue->is_flushing) + { + vkd3d_mutex_unlock(&queue->op_mutex); + return S_OK; + } + + hr = d3d12_command_queue_flush_ops_locked(queue, flushed_any); + + vkd3d_mutex_unlock(&queue->op_mutex); + + return hr; +} + +/* flushed_any is initialised by the caller. */ +static HRESULT d3d12_command_queue_flush_ops_locked(struct d3d12_command_queue *queue, bool *flushed_any) +{ + struct vkd3d_cs_op_data *op; + struct d3d12_fence *fence; + unsigned int i; + + queue->is_flushing = true; + + assert(queue->aux_op_queue.count == 0); + + while (queue->op_queue.count != 0) + { + d3d12_command_queue_swap_queues(queue); + + vkd3d_mutex_unlock(&queue->op_mutex); + + for (i = 0; i < queue->aux_op_queue.count; ++i) + { + op = &queue->aux_op_queue.ops[i]; + switch (op->opcode) + { + case VKD3D_CS_OP_WAIT: + fence = op->u.wait.fence; + vkd3d_mutex_lock(&fence->mutex); + if (op->u.wait.value > fence->max_pending_value) + { + vkd3d_mutex_unlock(&fence->mutex); + d3d12_command_queue_delete_aux_ops(queue, i); + vkd3d_mutex_lock(&queue->op_mutex); + return d3d12_command_queue_fixup_after_flush_locked(queue); + } + d3d12_command_queue_wait_locked(queue, fence, op->u.wait.value); + d3d12_fence_decref(fence); + break; + + case VKD3D_CS_OP_SIGNAL: + d3d12_command_queue_signal(queue, op->u.signal.fence, op->u.signal.value); + d3d12_fence_decref(op->u.signal.fence); + break; + + case VKD3D_CS_OP_EXECUTE: + d3d12_command_queue_execute(queue, op->u.execute.buffers, op->u.execute.buffer_count); + break; + + default: + vkd3d_unreachable(); + } + + *flushed_any |= true; + } + + queue->aux_op_queue.count = 0; + + vkd3d_mutex_lock(&queue->op_mutex); + } + + queue->is_flushing = false; + + return S_OK; +} + +static void d3d12_command_queue_op_array_init(struct d3d12_command_queue_op_array *array) +{ + array->ops = NULL; + array->count = 0; + array->size = 0; +} + static HRESULT d3d12_command_queue_init(struct d3d12_command_queue *queue, struct d3d12_device *device, const D3D12_COMMAND_QUEUE_DESC *desc) { @@ -6338,6 +6910,11 @@ static HRESULT d3d12_command_queue_init(struct d3d12_command_queue *queue, queue->last_waited_fence = NULL; queue->last_waited_fence_value = 0; + d3d12_command_queue_op_array_init(&queue->op_queue); + queue->is_flushing = false; + + d3d12_command_queue_op_array_init(&queue->aux_op_queue); + if (desc->Priority == D3D12_COMMAND_QUEUE_PRIORITY_GLOBAL_REALTIME) { FIXME("Global realtime priority is not implemented.\n"); @@ -6352,9 +6929,19 @@ static HRESULT d3d12_command_queue_init(struct d3d12_command_queue *queue, if (FAILED(hr = vkd3d_private_store_init(&queue->private_store))) return hr; + vkd3d_mutex_init(&queue->op_mutex); + + if (FAILED(hr = vkd3d_fence_worker_start(&queue->fence_worker, queue->vkd3d_queue, device))) + goto fail_destroy_op_mutex; + d3d12_device_add_ref(queue->device = device); return S_OK; + +fail_destroy_op_mutex: + vkd3d_mutex_destroy(&queue->op_mutex); + vkd3d_private_store_destroy(&queue->private_store); + return hr; } HRESULT d3d12_command_queue_create(struct d3d12_device *device, @@ -6389,8 +6976,14 @@ uint32_t vkd3d_get_vk_queue_family_index(ID3D12CommandQueue *queue) VkQueue vkd3d_acquire_vk_queue(ID3D12CommandQueue *queue) { struct d3d12_command_queue *d3d12_queue = impl_from_ID3D12CommandQueue(queue); + VkQueue vk_queue = vkd3d_queue_acquire(d3d12_queue->vkd3d_queue); + + if (d3d12_queue->op_queue.count) + WARN("Acquired command queue %p with %zu remaining ops.\n", d3d12_queue, d3d12_queue->op_queue.count); + else if (d3d12_queue->is_flushing) + WARN("Acquired command queue %p which is flushing.\n", d3d12_queue); - return vkd3d_queue_acquire(d3d12_queue->vkd3d_queue); + return vk_queue; } void vkd3d_release_vk_queue(ID3D12CommandQueue *queue) diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d/device.c b/dll/directx/wine/vkd3d/libs/vkd3d/device.c similarity index 89% rename from dll/directx/wine/d3d12/vkd3d/vkd3d/device.c rename to dll/directx/wine/vkd3d/libs/vkd3d/device.c index 59fa9af9b317b..39a5ca013c75e 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d/device.c +++ b/dll/directx/wine/vkd3d/libs/vkd3d/device.c @@ -19,51 +19,6 @@ #include "vkd3d_private.h" #include "vkd3d_version.h" -#ifdef HAVE_DLFCN_H -#include - -static void *vkd3d_dlopen(const char *name) -{ - return dlopen(name, RTLD_NOW); -} - -static void *vkd3d_dlsym(void *handle, const char *symbol) -{ - return dlsym(handle, symbol); -} - -static int vkd3d_dlclose(void *handle) -{ - return dlclose(handle); -} - -static const char *vkd3d_dlerror(void) -{ - return dlerror(); -} -#else -static void *vkd3d_dlopen(const char *name) -{ - FIXME("Not implemented for this platform.\n"); - return NULL; -} - -static void *vkd3d_dlsym(void *handle, const char *symbol) -{ - return NULL; -} - -static int vkd3d_dlclose(void *handle) -{ - return 0; -} - -static const char *vkd3d_dlerror(void) -{ - return "Not implemented for this platform.\n"; -} -#endif - struct vkd3d_struct { enum vkd3d_structure_type type; @@ -129,12 +84,14 @@ static const struct vkd3d_optional_extension_info optional_device_extensions[] = VK_EXTENSION(KHR_MAINTENANCE3, KHR_maintenance3), VK_EXTENSION(KHR_PUSH_DESCRIPTOR, KHR_push_descriptor), VK_EXTENSION(KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE, KHR_sampler_mirror_clamp_to_edge), + VK_EXTENSION(KHR_TIMELINE_SEMAPHORE, KHR_timeline_semaphore), /* EXT extensions */ 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_EXTENSION(EXT_DEPTH_CLIP_ENABLE, EXT_depth_clip_enable), VK_EXTENSION(EXT_DESCRIPTOR_INDEXING, EXT_descriptor_indexing), + VK_EXTENSION(EXT_ROBUSTNESS_2, EXT_robustness2), VK_EXTENSION(EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION, EXT_shader_demote_to_helper_invocation), VK_EXTENSION(EXT_SHADER_STENCIL_EXPORT, EXT_shader_stencil_export), VK_EXTENSION(EXT_TEXEL_BUFFER_ALIGNMENT, EXT_texel_buffer_alignment), @@ -142,6 +99,112 @@ static const struct vkd3d_optional_extension_info optional_device_extensions[] = VK_EXTENSION(EXT_VERTEX_ATTRIBUTE_DIVISOR, EXT_vertex_attribute_divisor), }; +static HRESULT vkd3d_create_vk_descriptor_heap_layout(struct d3d12_device *device, unsigned int index) +{ + const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + VkDescriptorSetLayoutBindingFlagsCreateInfoEXT flags_info; + VkDescriptorSetLayoutCreateInfo set_desc; + VkDescriptorBindingFlagsEXT set_flags; + VkDescriptorSetLayoutBinding binding; + VkResult vr; + + binding.binding = 0; + binding.descriptorType = device->vk_descriptor_heap_layouts[index].type; + binding.descriptorCount = device->vk_descriptor_heap_layouts[index].count; + binding.stageFlags = VK_SHADER_STAGE_ALL; + binding.pImmutableSamplers = NULL; + + set_desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + set_desc.pNext = &flags_info; + set_desc.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT; + set_desc.bindingCount = 1; + set_desc.pBindings = &binding; + + set_flags = VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT + | VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT + | VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT; + + flags_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT; + flags_info.pNext = NULL; + flags_info.bindingCount = 1; + flags_info.pBindingFlags = &set_flags; + + if ((vr = VK_CALL(vkCreateDescriptorSetLayout(device->vk_device, &set_desc, NULL, + &device->vk_descriptor_heap_layouts[index].vk_set_layout))) < 0) + { + WARN("Failed to create Vulkan descriptor set layout, vr %d.\n", vr); + return hresult_from_vk_result(vr); + } + + return S_OK; +} + +static void vkd3d_vk_descriptor_heap_layouts_cleanup(struct d3d12_device *device) +{ + const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + enum vkd3d_vk_descriptor_set_index set; + + for (set = 0; set < ARRAY_SIZE(device->vk_descriptor_heap_layouts); ++set) + VK_CALL(vkDestroyDescriptorSetLayout(device->vk_device, device->vk_descriptor_heap_layouts[set].vk_set_layout, + NULL)); +} + +static HRESULT vkd3d_vk_descriptor_heap_layouts_init(struct d3d12_device *device) +{ + static const struct vkd3d_vk_descriptor_heap_layout vk_descriptor_heap_layouts[VKD3D_SET_INDEX_COUNT] = + { + {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, true, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV}, + {VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, true, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV}, + {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, false, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV}, + {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, true, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV}, + {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, false, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV}, + {VK_DESCRIPTOR_TYPE_SAMPLER, false, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER}, + /* UAV counters */ + {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, true, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV}, + }; + const struct vkd3d_device_descriptor_limits *limits = &device->vk_info.descriptor_limits; + enum vkd3d_vk_descriptor_set_index set; + HRESULT hr; + + for (set = 0; set < ARRAY_SIZE(device->vk_descriptor_heap_layouts); ++set) + device->vk_descriptor_heap_layouts[set] = vk_descriptor_heap_layouts[set]; + + if (!device->use_vk_heaps) + return S_OK; + + for (set = 0; set < ARRAY_SIZE(device->vk_descriptor_heap_layouts); ++set) + { + switch (device->vk_descriptor_heap_layouts[set].type) + { + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + device->vk_descriptor_heap_layouts[set].count = limits->uniform_buffer_max_descriptors; + break; + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + device->vk_descriptor_heap_layouts[set].count = limits->sampled_image_max_descriptors; + break; + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + device->vk_descriptor_heap_layouts[set].count = limits->storage_image_max_descriptors; + break; + case VK_DESCRIPTOR_TYPE_SAMPLER: + device->vk_descriptor_heap_layouts[set].count = limits->sampler_max_descriptors; + break; + default: + ERR("Unhandled descriptor type %#x.\n", device->vk_descriptor_heap_layouts[set].type); + break; + } + + if (FAILED(hr = vkd3d_create_vk_descriptor_heap_layout(device, set))) + { + vkd3d_vk_descriptor_heap_layouts_cleanup(device); + return hr; + } + } + + return S_OK; +} + static unsigned int get_spec_version(const VkExtensionProperties *extensions, unsigned int count, const char *extension_name) { @@ -431,6 +494,7 @@ static void vkd3d_init_debug_report(struct vkd3d_instance *instance) static const struct vkd3d_debug_option vkd3d_config_options[] = { + {"virtual_heaps", VKD3D_CONFIG_FLAG_VIRTUAL_HEAPS}, /* always use virtual descriptor heaps */ {"vk_debug", VKD3D_CONFIG_FLAG_VULKAN_DEBUG}, /* enable Vulkan debug extensions */ }; @@ -690,10 +754,12 @@ struct vkd3d_physical_device_info VkPhysicalDeviceConditionalRenderingFeaturesEXT conditional_rendering_features; VkPhysicalDeviceDepthClipEnableFeaturesEXT depth_clip_features; VkPhysicalDeviceDescriptorIndexingFeaturesEXT descriptor_indexing_features; + VkPhysicalDeviceRobustness2FeaturesEXT robustness2_features; VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT demote_features; VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT texel_buffer_alignment_features; VkPhysicalDeviceTransformFeedbackFeaturesEXT xfb_features; VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT vertex_divisor_features; + VkPhysicalDeviceTimelineSemaphoreFeaturesKHR timeline_semaphore_features; VkPhysicalDeviceFeatures2 features2; }; @@ -706,9 +772,11 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *vertex_divisor_properties; VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT *buffer_alignment_properties; VkPhysicalDeviceDescriptorIndexingFeaturesEXT *descriptor_indexing_features; + VkPhysicalDeviceRobustness2FeaturesEXT *robustness2_features; VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *vertex_divisor_features; VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT *buffer_alignment_features; VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT *demote_features; + VkPhysicalDeviceTimelineSemaphoreFeaturesKHR *timeline_semaphore_features; VkPhysicalDeviceDepthClipEnableFeaturesEXT *depth_clip_features; VkPhysicalDeviceMaintenance3Properties *maintenance3_properties; VkPhysicalDeviceTransformFeedbackPropertiesEXT *xfb_properties; @@ -720,6 +788,7 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i conditional_rendering_features = &info->conditional_rendering_features; depth_clip_features = &info->depth_clip_features; descriptor_indexing_features = &info->descriptor_indexing_features; + robustness2_features = &info->robustness2_features; descriptor_indexing_properties = &info->descriptor_indexing_properties; maintenance3_properties = &info->maintenance3_properties; demote_features = &info->demote_features; @@ -727,6 +796,7 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i 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; xfb_features = &info->xfb_features; xfb_properties = &info->xfb_properties; @@ -738,6 +808,8 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i vk_prepend_struct(&info->features2, depth_clip_features); descriptor_indexing_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT; vk_prepend_struct(&info->features2, descriptor_indexing_features); + robustness2_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT; + vk_prepend_struct(&info->features2, robustness2_features); demote_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT; vk_prepend_struct(&info->features2, demote_features); buffer_alignment_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT; @@ -746,6 +818,8 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i vk_prepend_struct(&info->features2, xfb_features); vertex_divisor_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT; vk_prepend_struct(&info->features2, vertex_divisor_features); + timeline_semaphore_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR; + vk_prepend_struct(&info->features2, timeline_semaphore_features); if (vulkan_info->KHR_get_physical_device_properties2) VK_CALL(vkGetPhysicalDeviceFeatures2KHR(physical_device, &info->features2)); @@ -1287,6 +1361,75 @@ static void vkd3d_device_descriptor_limits_init(struct vkd3d_device_descriptor_l limits->sampler_max_descriptors = min(device_limits->maxDescriptorSetSamplers, VKD3D_MAX_DESCRIPTOR_SET_SAMPLERS); } +static void vkd3d_device_vk_heaps_descriptor_limits_init(struct vkd3d_device_descriptor_limits *limits, + const VkPhysicalDeviceDescriptorIndexingPropertiesEXT *properties) +{ + const unsigned int root_provision = D3D12_MAX_ROOT_COST / 2; + unsigned int srv_divisor = 1, uav_divisor = 1; + + /* The total number of populated sampled image or storage image descriptors never exceeds the size of + * one set (or two sets if every UAV has a counter), but the total size of bound layouts will exceed + * device limits if each set size is maxDescriptorSet*, because of the D3D12 buffer + image allowance + * (and UAV counters). Breaking limits for layouts seems to work with RADV and Nvidia drivers at + * least, but let's try to stay within them if limits are high enough. */ + if (properties->maxDescriptorSetUpdateAfterBindSampledImages >= (1u << 21)) + { + srv_divisor = 2; + uav_divisor = properties->maxDescriptorSetUpdateAfterBindSampledImages >= (3u << 20) ? 3 : 2; + } + + limits->uniform_buffer_max_descriptors = min(properties->maxDescriptorSetUpdateAfterBindUniformBuffers, + properties->maxPerStageDescriptorUpdateAfterBindUniformBuffers - root_provision); + limits->sampled_image_max_descriptors = min(properties->maxDescriptorSetUpdateAfterBindSampledImages, + properties->maxPerStageDescriptorUpdateAfterBindSampledImages / srv_divisor - root_provision); + limits->storage_buffer_max_descriptors = min(properties->maxDescriptorSetUpdateAfterBindStorageBuffers, + properties->maxPerStageDescriptorUpdateAfterBindStorageBuffers - root_provision); + limits->storage_image_max_descriptors = min(properties->maxDescriptorSetUpdateAfterBindStorageImages, + properties->maxPerStageDescriptorUpdateAfterBindStorageImages / uav_divisor - root_provision); + limits->sampler_max_descriptors = min(properties->maxDescriptorSetUpdateAfterBindSamplers, + properties->maxPerStageDescriptorUpdateAfterBindSamplers - root_provision); + limits->sampler_max_descriptors = min(limits->sampler_max_descriptors, VKD3D_MAX_DESCRIPTOR_SET_SAMPLERS); +} + +static bool d3d12_device_supports_typed_uav_load_additional_formats(const struct d3d12_device *device) +{ + const struct vkd3d_vk_instance_procs *vk_procs = &device->vkd3d_instance->vk_procs; + const struct vkd3d_format *format; + VkFormatProperties properties; + unsigned int i; + + static const DXGI_FORMAT additional_formats[] = + { + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_R16_FLOAT, + DXGI_FORMAT_R16_UINT, + DXGI_FORMAT_R16_SINT, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_R8_UINT, + DXGI_FORMAT_R8_SINT, + }; + + for (i = 0; i < ARRAY_SIZE(additional_formats); ++i) + { + format = vkd3d_get_format(device, additional_formats[i], false); + assert(format); + + VK_CALL(vkGetPhysicalDeviceFormatProperties(device->vk_physical_device, format->vk_format, &properties)); + if (!((properties.linearTilingFeatures | properties.optimalTilingFeatures) & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) + return false; + } + + return true; +} + static HRESULT vkd3d_init_device_caps(struct d3d12_device *device, const struct vkd3d_device_create_info *create_info, struct vkd3d_physical_device_info *physical_device_info, @@ -1321,6 +1464,7 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device, vulkan_info->sparse_properties = physical_device_info->properties2.properties.sparseProperties; vulkan_info->rasterization_stream = physical_device_info->xfb_properties.transformFeedbackRasterizationStreamSelect; vulkan_info->transform_feedback_queries = physical_device_info->xfb_properties.transformFeedbackQueries; + vulkan_info->uav_read_without_format = features->shaderStorageImageReadWithoutFormat; vulkan_info->max_vertex_attrib_divisor = max(physical_device_info->vertex_divisor_properties.maxVertexAttribDivisor, 1); device->feature_options.DoublePrecisionFloatShaderOps = features->shaderFloat64; @@ -1351,7 +1495,8 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device, else device->feature_options.ResourceBindingTier = D3D12_RESOURCE_BINDING_TIER_3; - device->feature_options.TypedUAVLoadAdditionalFormats = features->shaderStorageImageExtendedFormats; + device->feature_options.TypedUAVLoadAdditionalFormats = features->shaderStorageImageReadWithoutFormat + && d3d12_device_supports_typed_uav_load_additional_formats(device); /* GL_INTEL_fragment_shader_ordering, no Vulkan equivalent. */ device->feature_options.ROVsSupported = FALSE; /* GL_INTEL_conservative_rasterization, no Vulkan equivalent. */ @@ -1440,10 +1585,14 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device, vulkan_info->EXT_conditional_rendering = false; if (!physical_device_info->depth_clip_features.depthClipEnable) vulkan_info->EXT_depth_clip_enable = false; + if (!physical_device_info->robustness2_features.nullDescriptor) + vulkan_info->EXT_robustness2 = false; if (!physical_device_info->demote_features.shaderDemoteToHelperInvocation) vulkan_info->EXT_shader_demote_to_helper_invocation = false; if (!physical_device_info->texel_buffer_alignment_features.texelBufferAlignment) vulkan_info->EXT_texel_buffer_alignment = false; + if (!physical_device_info->timeline_semaphore_features.timelineSemaphore) + vulkan_info->KHR_timeline_semaphore = false; vulkan_info->texel_buffer_alignment_properties = physical_device_info->texel_buffer_alignment_properties; @@ -1492,16 +1641,13 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device, features->shaderTessellationAndGeometryPointSize = VK_FALSE; descriptor_indexing = &physical_device_info->descriptor_indexing_features; - if (descriptor_indexing) - { - descriptor_indexing->shaderInputAttachmentArrayDynamicIndexing = VK_FALSE; - descriptor_indexing->shaderInputAttachmentArrayNonUniformIndexing = VK_FALSE; + descriptor_indexing->shaderInputAttachmentArrayDynamicIndexing = VK_FALSE; + descriptor_indexing->shaderInputAttachmentArrayNonUniformIndexing = VK_FALSE; - /* We do not use storage buffers currently. */ - features->shaderStorageBufferArrayDynamicIndexing = VK_FALSE; - descriptor_indexing->shaderStorageBufferArrayNonUniformIndexing = VK_FALSE; - descriptor_indexing->descriptorBindingStorageBufferUpdateAfterBind = VK_FALSE; - } + /* We do not use storage buffers currently. */ + features->shaderStorageBufferArrayDynamicIndexing = VK_FALSE; + descriptor_indexing->shaderStorageBufferArrayNonUniformIndexing = VK_FALSE; + descriptor_indexing->descriptorBindingStorageBufferUpdateAfterBind = VK_FALSE; if (vulkan_info->EXT_descriptor_indexing && descriptor_indexing && (descriptor_indexing->descriptorBindingUniformBufferUpdateAfterBind @@ -1514,8 +1660,25 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device, features->robustBufferAccess = VK_FALSE; } - vkd3d_device_descriptor_limits_init(&vulkan_info->descriptor_limits, - &physical_device_info->properties2.properties.limits); + /* Select descriptor heap implementation. Forcing virtual heaps may be useful if + * a client allocates descriptor heaps too large for the Vulkan device, or the + * root signature cost exceeds the available push constant size. Virtual heaps + * use only enough descriptors for the descriptor tables of the currently bound + * root signature, and don't require a 32-bit push constant for each table. */ + device->use_vk_heaps = vulkan_info->EXT_descriptor_indexing + && !(device->vkd3d_instance->config_flags & VKD3D_CONFIG_FLAG_VIRTUAL_HEAPS) + && descriptor_indexing->descriptorBindingUniformBufferUpdateAfterBind + && descriptor_indexing->descriptorBindingSampledImageUpdateAfterBind + && descriptor_indexing->descriptorBindingStorageImageUpdateAfterBind + && descriptor_indexing->descriptorBindingUniformTexelBufferUpdateAfterBind + && descriptor_indexing->descriptorBindingStorageTexelBufferUpdateAfterBind; + + if (device->use_vk_heaps) + vkd3d_device_vk_heaps_descriptor_limits_init(&vulkan_info->descriptor_limits, + &physical_device_info->descriptor_indexing_properties); + else + vkd3d_device_descriptor_limits_init(&vulkan_info->descriptor_limits, + &physical_device_info->properties2.properties.limits); return S_OK; } @@ -1889,13 +2052,8 @@ static HRESULT d3d12_device_init_pipeline_cache(struct d3d12_device *device) const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; VkPipelineCacheCreateInfo cache_info; VkResult vr; - int rc; - if ((rc = vkd3d_mutex_init(&device->mutex))) - { - ERR("Failed to initialize mutex, error %d.\n", rc); - return hresult_from_errno(rc); - } + vkd3d_mutex_init(&device->mutex); cache_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; cache_info.pNext = NULL; @@ -1986,17 +2144,12 @@ D3D12_GPU_VIRTUAL_ADDRESS vkd3d_gpu_va_allocator_allocate(struct vkd3d_gpu_va_al size_t alignment, size_t size, void *ptr) { D3D12_GPU_VIRTUAL_ADDRESS address; - int rc; if (size > ~(size_t)0 - (alignment - 1)) return 0; size = align(size, alignment); - if ((rc = vkd3d_mutex_lock(&allocator->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return 0; - } + vkd3d_mutex_lock(&allocator->mutex); if (size <= VKD3D_VA_SLAB_SIZE && allocator->free_slab) address = vkd3d_gpu_va_allocator_allocate_slab(allocator, size, ptr); @@ -2062,7 +2215,6 @@ void *vkd3d_gpu_va_allocator_dereference(struct vkd3d_gpu_va_allocator *allocato D3D12_GPU_VIRTUAL_ADDRESS address) { void *ret; - int rc; /* If we land in the non-fallback region, dereferencing VA is lock-less. * The base pointer is immutable, and the only way we can have a data race @@ -2074,11 +2226,7 @@ void *vkd3d_gpu_va_allocator_dereference(struct vkd3d_gpu_va_allocator *allocato return vkd3d_gpu_va_allocator_dereference_slab(allocator, address); /* Slow fallback. */ - if ((rc = vkd3d_mutex_lock(&allocator->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return NULL; - } + vkd3d_mutex_lock(&allocator->mutex); ret = vkd3d_gpu_va_allocator_dereference_fallback(allocator, address); @@ -2135,13 +2283,7 @@ static void vkd3d_gpu_va_allocator_free_fallback(struct vkd3d_gpu_va_allocator * void vkd3d_gpu_va_allocator_free(struct vkd3d_gpu_va_allocator *allocator, D3D12_GPU_VIRTUAL_ADDRESS address) { - int rc; - - if ((rc = vkd3d_mutex_lock(&allocator->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return; - } + vkd3d_mutex_lock(&allocator->mutex); if (address < VKD3D_VA_FALLBACK_BASE) { @@ -2158,7 +2300,6 @@ void vkd3d_gpu_va_allocator_free(struct vkd3d_gpu_va_allocator *allocator, D3D12 static bool vkd3d_gpu_va_allocator_init(struct vkd3d_gpu_va_allocator *allocator) { unsigned int i; - int rc; memset(allocator, 0, sizeof(*allocator)); allocator->fallback_floor = VKD3D_VA_FALLBACK_BASE; @@ -2178,200 +2319,20 @@ static bool vkd3d_gpu_va_allocator_init(struct vkd3d_gpu_va_allocator *allocator allocator->slabs[i].ptr = &allocator->slabs[i + 1]; } - if ((rc = vkd3d_mutex_init(&allocator->mutex))) - { - ERR("Failed to initialize mutex, error %d.\n", rc); - vkd3d_free(allocator->slabs); - return false; - } + vkd3d_mutex_init(&allocator->mutex); return true; } static void vkd3d_gpu_va_allocator_cleanup(struct vkd3d_gpu_va_allocator *allocator) { - int rc; - - if ((rc = vkd3d_mutex_lock(&allocator->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return; - } + vkd3d_mutex_lock(&allocator->mutex); vkd3d_free(allocator->slabs); vkd3d_free(allocator->fallback_allocations); vkd3d_mutex_unlock(&allocator->mutex); vkd3d_mutex_destroy(&allocator->mutex); } -/* We could use bsearch() or recursion here, but it probably helps to omit - * all the extra function calls. */ -static struct vkd3d_gpu_descriptor_allocation *vkd3d_gpu_descriptor_allocator_binary_search( - const struct vkd3d_gpu_descriptor_allocator *allocator, const struct d3d12_desc *desc) -{ - struct vkd3d_gpu_descriptor_allocation *allocations = allocator->allocations; - const struct d3d12_desc *base; - size_t centre, count; - - for (count = allocator->allocation_count; count > 1; ) - { - centre = count >> 1; - base = allocations[centre].base; - if (base <= desc) - { - allocations += centre; - count -= centre; - } - else - { - count = centre; - } - } - - return allocations; -} - -bool vkd3d_gpu_descriptor_allocator_register_range(struct vkd3d_gpu_descriptor_allocator *allocator, - const struct d3d12_desc *base, size_t count) -{ - struct vkd3d_gpu_descriptor_allocation *allocation; - int rc; - - if ((rc = vkd3d_mutex_lock(&allocator->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return false; - } - - if (!vkd3d_array_reserve((void **)&allocator->allocations, &allocator->allocations_size, - allocator->allocation_count + 1, sizeof(*allocator->allocations))) - { - vkd3d_mutex_unlock(&allocator->mutex); - return false; - } - - if (allocator->allocation_count > 1) - allocation = vkd3d_gpu_descriptor_allocator_binary_search(allocator, base); - else - allocation = allocator->allocations; - allocation += allocator->allocation_count && base > allocation->base; - memmove(&allocation[1], allocation, (allocator->allocation_count++ - (allocation - allocator->allocations)) - * sizeof(*allocation)); - - allocation->base = base; - allocation->count = count; - - vkd3d_mutex_unlock(&allocator->mutex); - - return true; -} - -bool vkd3d_gpu_descriptor_allocator_unregister_range( - struct vkd3d_gpu_descriptor_allocator *allocator, const struct d3d12_desc *base) -{ - bool found; - size_t i; - int rc; - - if ((rc = vkd3d_mutex_lock(&allocator->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return false; - } - - for (i = 0, found = false; i < allocator->allocation_count; ++i) - { - if (allocator->allocations[i].base != base) - continue; - - memmove(&allocator->allocations[i], &allocator->allocations[i + 1], - (--allocator->allocation_count - i) * sizeof(allocator->allocations[0])); - - found = true; - break; - } - - vkd3d_mutex_unlock(&allocator->mutex); - - return found; -} - -static inline const struct vkd3d_gpu_descriptor_allocation *vkd3d_gpu_descriptor_allocator_allocation_from_descriptor( - const struct vkd3d_gpu_descriptor_allocator *allocator, const struct d3d12_desc *desc) -{ - const struct vkd3d_gpu_descriptor_allocation *allocation; - - allocation = vkd3d_gpu_descriptor_allocator_binary_search(allocator, desc); - return (desc >= allocation->base && desc - allocation->base < allocation->count) ? allocation : NULL; -} - -/* Return the available size from the specified descriptor to the heap end. */ -size_t vkd3d_gpu_descriptor_allocator_range_size_from_descriptor( - struct vkd3d_gpu_descriptor_allocator *allocator, const struct d3d12_desc *desc) -{ - const struct vkd3d_gpu_descriptor_allocation *allocation; - size_t remaining; - int rc; - - assert(allocator->allocation_count); - - if ((rc = vkd3d_mutex_lock(&allocator->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return 0; - } - - remaining = 0; - if ((allocation = vkd3d_gpu_descriptor_allocator_allocation_from_descriptor(allocator, desc))) - remaining = allocation->count - (desc - allocation->base); - - vkd3d_mutex_unlock(&allocator->mutex); - - return remaining; -} - -struct d3d12_descriptor_heap *vkd3d_gpu_descriptor_allocator_heap_from_descriptor( - struct vkd3d_gpu_descriptor_allocator *allocator, const struct d3d12_desc *desc) -{ - const struct vkd3d_gpu_descriptor_allocation *allocation; - int rc; - - if (!allocator->allocation_count) - return NULL; - - if ((rc = vkd3d_mutex_lock(&allocator->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return NULL; - } - - allocation = vkd3d_gpu_descriptor_allocator_allocation_from_descriptor(allocator, desc); - - vkd3d_mutex_unlock(&allocator->mutex); - - return allocation ? CONTAINING_RECORD(allocation->base, struct d3d12_descriptor_heap, descriptors) - : NULL; -} - -static bool vkd3d_gpu_descriptor_allocator_init(struct vkd3d_gpu_descriptor_allocator *allocator) -{ - int rc; - - memset(allocator, 0, sizeof(*allocator)); - if ((rc = vkd3d_mutex_init(&allocator->mutex))) - { - ERR("Failed to initialise mutex, error %d.\n", rc); - return false; - } - - return true; -} - -static void vkd3d_gpu_descriptor_allocator_cleanup(struct vkd3d_gpu_descriptor_allocator *allocator) -{ - vkd3d_free(allocator->allocations); - vkd3d_mutex_destroy(&allocator->mutex); -} - static bool have_vk_time_domain(VkTimeDomainEXT *domains, unsigned int count, VkTimeDomainEXT domain) { unsigned int i; @@ -2501,15 +2462,16 @@ static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device *iface) { const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + vkd3d_mutex_destroy(&device->blocked_queues_mutex); + vkd3d_private_store_destroy(&device->private_store); vkd3d_cleanup_format_info(device); + vkd3d_vk_descriptor_heap_layouts_cleanup(device); vkd3d_uav_clear_state_cleanup(&device->uav_clear_state, device); vkd3d_destroy_null_resources(&device->null_resources, device); vkd3d_gpu_va_allocator_cleanup(&device->gpu_va_allocator); - vkd3d_gpu_descriptor_allocator_cleanup(&device->gpu_descriptor_allocator); vkd3d_render_pass_cache_cleanup(&device->render_pass_cache, device); - vkd3d_fence_worker_stop(&device->fence_worker, device); d3d12_device_destroy_pipeline_cache(device); d3d12_device_destroy_vkd3d_queues(device); for (i = 0; i < ARRAY_SIZE(device->desc_mutex); ++i) @@ -3406,6 +3368,132 @@ static void STDMETHODCALLTYPE d3d12_device_CreateSampler(ID3D12Device *iface, d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device); } +static void flush_desc_writes(struct d3d12_desc_copy_location locations[][VKD3D_DESCRIPTOR_WRITE_BUFFER_SIZE], + struct d3d12_desc_copy_info *infos, struct d3d12_descriptor_heap *descriptor_heap, struct d3d12_device *device) +{ + enum vkd3d_vk_descriptor_set_index set; + for (set = 0; set < VKD3D_SET_INDEX_COUNT; ++set) + { + if (!infos[set].count) + continue; + d3d12_desc_copy_vk_heap_range(locations[set], &infos[set], descriptor_heap, set, device); + infos[set].count = 0; + infos[set].uav_counter = false; + } +} + +static void d3d12_desc_buffered_copy_atomic(struct d3d12_desc *dst, const struct d3d12_desc *src, + struct d3d12_desc_copy_location locations[][VKD3D_DESCRIPTOR_WRITE_BUFFER_SIZE], + struct d3d12_desc_copy_info *infos, struct d3d12_descriptor_heap *descriptor_heap, struct d3d12_device *device) +{ + struct d3d12_desc_copy_location *location; + enum vkd3d_vk_descriptor_set_index set; + struct vkd3d_mutex *mutex; + + mutex = d3d12_device_get_descriptor_mutex(device, src); + vkd3d_mutex_lock(mutex); + + if (src->s.magic == VKD3D_DESCRIPTOR_MAGIC_FREE) + { + /* Source must be unlocked first, and therefore can't be used as a null source. */ + static const struct d3d12_desc null = {0}; + vkd3d_mutex_unlock(mutex); + d3d12_desc_write_atomic(dst, &null, device); + return; + } + + set = vkd3d_vk_descriptor_set_index_from_vk_descriptor_type(src->s.vk_descriptor_type); + location = &locations[set][infos[set].count++]; + + location->src.s = src->s; + + if (location->src.s.magic & VKD3D_DESCRIPTOR_MAGIC_HAS_VIEW) + vkd3d_view_incref(location->src.s.u.view_info.view); + + vkd3d_mutex_unlock(mutex); + + infos[set].uav_counter |= (location->src.s.magic == VKD3D_DESCRIPTOR_MAGIC_UAV) + && !!location->src.s.u.view_info.view->vk_counter_view; + location->dst = dst; + + if (infos[set].count == ARRAY_SIZE(locations[0])) + { + d3d12_desc_copy_vk_heap_range(locations[set], &infos[set], descriptor_heap, set, device); + infos[set].count = 0; + infos[set].uav_counter = false; + } +} + +/* Some games, e.g. Control, copy a large number of descriptors per frame, so the + * speed of this function is critical. */ +static void d3d12_device_vk_heaps_copy_descriptors(struct d3d12_device *device, + UINT dst_descriptor_range_count, const D3D12_CPU_DESCRIPTOR_HANDLE *dst_descriptor_range_offsets, + const UINT *dst_descriptor_range_sizes, + UINT src_descriptor_range_count, const D3D12_CPU_DESCRIPTOR_HANDLE *src_descriptor_range_offsets, + const UINT *src_descriptor_range_sizes) +{ + struct d3d12_desc_copy_location locations[VKD3D_SET_INDEX_COUNT][VKD3D_DESCRIPTOR_WRITE_BUFFER_SIZE]; + unsigned int dst_range_idx, dst_idx, src_range_idx, src_idx; + /* The locations array is relatively large, and often mostly empty. Keeping these + * values together in a separate array will likely result in fewer cache misses. */ + struct d3d12_desc_copy_info infos[VKD3D_SET_INDEX_COUNT]; + struct d3d12_descriptor_heap *descriptor_heap = NULL; + const struct d3d12_desc *src, *heap_base, *heap_end; + unsigned int dst_range_size, src_range_size; + struct d3d12_desc *dst; + + descriptor_heap = d3d12_desc_get_descriptor_heap(d3d12_desc_from_cpu_handle(dst_descriptor_range_offsets[0])); + heap_base = (const struct d3d12_desc *)descriptor_heap->descriptors; + heap_end = heap_base + descriptor_heap->desc.NumDescriptors; + + memset(infos, 0, sizeof(infos)); + dst_range_idx = dst_idx = 0; + src_range_idx = src_idx = 0; + while (dst_range_idx < dst_descriptor_range_count && src_range_idx < src_descriptor_range_count) + { + dst_range_size = dst_descriptor_range_sizes ? dst_descriptor_range_sizes[dst_range_idx] : 1; + src_range_size = src_descriptor_range_sizes ? src_descriptor_range_sizes[src_range_idx] : 1; + + dst = d3d12_desc_from_cpu_handle(dst_descriptor_range_offsets[dst_range_idx]); + src = d3d12_desc_from_cpu_handle(src_descriptor_range_offsets[src_range_idx]); + + if (dst < heap_base || dst >= heap_end) + { + flush_desc_writes(locations, infos, descriptor_heap, device); + descriptor_heap = d3d12_desc_get_descriptor_heap(dst); + heap_base = (const struct d3d12_desc *)descriptor_heap->descriptors; + heap_end = heap_base + descriptor_heap->desc.NumDescriptors; + } + + for (; dst_idx < dst_range_size && src_idx < src_range_size; src_idx++, dst_idx++) + { + /* We don't need to lock either descriptor for the identity check. The descriptor + * mutex is only intended to prevent use-after-free of the vkd3d_view caused by a + * race condition in the calling app. It is unnecessary to protect this test as it's + * the app's race condition, not ours. */ + if (dst[dst_idx].s.magic == src[src_idx].s.magic && (dst[dst_idx].s.magic & VKD3D_DESCRIPTOR_MAGIC_HAS_VIEW) + && dst[dst_idx].s.u.view_info.written_serial_id == src[src_idx].s.u.view_info.view->serial_id) + continue; + d3d12_desc_buffered_copy_atomic(&dst[dst_idx], &src[src_idx], locations, infos, descriptor_heap, device); + } + + if (dst_idx >= dst_range_size) + { + ++dst_range_idx; + dst_idx = 0; + } + if (src_idx >= src_range_size) + { + ++src_range_idx; + src_idx = 0; + } + } + + flush_desc_writes(locations, infos, descriptor_heap, device); +} + +#define VKD3D_DESCRIPTOR_OPTIMISED_COPY_MIN_COUNT 8 + static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device *iface, UINT dst_descriptor_range_count, const D3D12_CPU_DESCRIPTOR_HANDLE *dst_descriptor_range_offsets, const UINT *dst_descriptor_range_sizes, @@ -3434,6 +3522,18 @@ static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device *iface, return; } + if (!dst_descriptor_range_count) + return; + + if (device->use_vk_heaps && (dst_descriptor_range_count > 1 || (dst_descriptor_range_sizes + && dst_descriptor_range_sizes[0] >= VKD3D_DESCRIPTOR_OPTIMISED_COPY_MIN_COUNT))) + { + d3d12_device_vk_heaps_copy_descriptors(device, dst_descriptor_range_count, dst_descriptor_range_offsets, + dst_descriptor_range_sizes, src_descriptor_range_count, src_descriptor_range_offsets, + src_descriptor_range_sizes); + return; + } + dst_range_idx = dst_idx = 0; src_range_idx = src_idx = 0; while (dst_range_idx < dst_descriptor_range_count && src_range_idx < src_descriptor_range_count) @@ -3470,6 +3570,17 @@ static void STDMETHODCALLTYPE d3d12_device_CopyDescriptorsSimple(ID3D12Device *i iface, descriptor_count, dst_descriptor_range_offset.ptr, src_descriptor_range_offset.ptr, descriptor_heap_type); + if (descriptor_count >= VKD3D_DESCRIPTOR_OPTIMISED_COPY_MIN_COUNT) + { + struct d3d12_device *device = impl_from_ID3D12Device(iface); + if (device->use_vk_heaps) + { + d3d12_device_vk_heaps_copy_descriptors(device, 1, &dst_descriptor_range_offset, + &descriptor_count, 1, &src_descriptor_range_offset, &descriptor_count); + return; + } + } + d3d12_device_CopyDescriptors(iface, 1, &dst_descriptor_range_offset, &descriptor_count, 1, &src_descriptor_range_offset, &descriptor_count, descriptor_heap_type); } @@ -3603,7 +3714,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource(ID3D12Devi struct d3d12_resource *object; HRESULT hr; - TRACE("iface %p, heap_properties %p, heap_flags %#x, desc %p, initial_state %#x, " + TRACE("iface %p, heap_properties %p, heap_flags %#x, desc %p, initial_state %#x, " "optimized_clear_value %p, iid %s, resource %p.\n", iface, heap_properties, heap_flags, desc, initial_state, optimized_clear_value, debugstr_guid(iid), resource); @@ -3736,7 +3847,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateFence(ID3D12Device *iface, struct d3d12_fence *object; HRESULT hr; - TRACE("iface %p, intial_value %#"PRIx64", flags %#x, riid %s, fence %p.\n", + TRACE("iface %p, initial_value %#"PRIx64", flags %#x, riid %s, fence %p.\n", iface, initial_value, flags, debugstr_guid(riid), fence); if (FAILED(hr = d3d12_fence_create(device, initial_value, flags, &object))) @@ -3993,11 +4104,8 @@ static HRESULT d3d12_device_init(struct d3d12_device *device, if (FAILED(hr = vkd3d_private_store_init(&device->private_store))) goto out_free_pipeline_cache; - if (FAILED(hr = vkd3d_fence_worker_start(&device->fence_worker, device))) - goto out_free_private_store; - if (FAILED(hr = vkd3d_init_format_info(device))) - goto out_stop_fence_worker; + goto out_free_private_store; if (FAILED(hr = vkd3d_init_null_resources(&device->null_resources, device))) goto out_cleanup_format_info; @@ -4005,11 +4113,16 @@ static HRESULT d3d12_device_init(struct d3d12_device *device, if (FAILED(hr = vkd3d_uav_clear_state_init(&device->uav_clear_state, device))) goto out_destroy_null_resources; + if (FAILED(hr = vkd3d_vk_descriptor_heap_layouts_init(device))) + goto out_cleanup_uav_clear_state; + vkd3d_render_pass_cache_init(&device->render_pass_cache); - vkd3d_gpu_descriptor_allocator_init(&device->gpu_descriptor_allocator); vkd3d_gpu_va_allocator_init(&device->gpu_va_allocator); vkd3d_time_domains_init(device); + device->blocked_queue_count = 0; + vkd3d_mutex_init(&device->blocked_queues_mutex); + for (i = 0; i < ARRAY_SIZE(device->desc_mutex); ++i) vkd3d_mutex_init(&device->desc_mutex[i]); @@ -4020,12 +4133,12 @@ static HRESULT d3d12_device_init(struct d3d12_device *device, return S_OK; +out_cleanup_uav_clear_state: + vkd3d_uav_clear_state_cleanup(&device->uav_clear_state, device); out_destroy_null_resources: vkd3d_destroy_null_resources(&device->null_resources, device); out_cleanup_format_info: vkd3d_cleanup_format_info(device); -out_stop_fence_worker: - vkd3d_fence_worker_stop(&device->fence_worker, device); out_free_private_store: vkd3d_private_store_destroy(&device->private_store); out_free_pipeline_cache: @@ -4094,7 +4207,6 @@ HRESULT vkd3d_create_thread(struct vkd3d_instance *instance, PFN_vkd3d_thread thread_main, void *data, union vkd3d_thread_handle *thread) { HRESULT hr = S_OK; - int rc; if (instance->create_thread) { @@ -4121,6 +4233,8 @@ HRESULT vkd3d_create_thread(struct vkd3d_instance *instance, hr = E_FAIL; } #else + int rc; + if ((rc = pthread_create(&thread->pthread, NULL, thread_main, data))) { ERR("Failed to create thread, error %d.\n", rc); diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d/resource.c b/dll/directx/wine/vkd3d/libs/vkd3d/resource.c similarity index 85% rename from dll/directx/wine/d3d12/vkd3d/vkd3d/resource.c rename to dll/directx/wine/vkd3d/libs/vkd3d/resource.c index 4c48e22e19482..8c050cfeb32bb 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d/resource.c +++ b/dll/directx/wine/vkd3d/libs/vkd3d/resource.c @@ -22,6 +22,8 @@ #define VKD3D_NULL_BUFFER_SIZE 16 #define VKD3D_NULL_VIEW_FORMAT DXGI_FORMAT_R8G8B8A8_UNORM +LONG64 object_global_serial_id; + static inline bool is_cpu_accessible_heap(const D3D12_HEAP_PROPERTIES *properties) { if (properties->Type == D3D12_HEAP_TYPE_DEFAULT) @@ -441,15 +443,8 @@ static HRESULT d3d12_heap_map(struct d3d12_heap *heap, uint64_t offset, struct d3d12_device *device = heap->device; HRESULT hr = S_OK; VkResult vr; - int rc; - if ((rc = vkd3d_mutex_lock(&heap->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - if (data) - *data = NULL; - return hresult_from_errno(rc); - } + vkd3d_mutex_lock(&heap->mutex); assert(!resource->map_count || heap->map_ptr); @@ -499,13 +494,8 @@ static HRESULT d3d12_heap_map(struct d3d12_heap *heap, uint64_t offset, static void d3d12_heap_unmap(struct d3d12_heap *heap, struct d3d12_resource *resource) { struct d3d12_device *device = heap->device; - int rc; - if ((rc = vkd3d_mutex_lock(&heap->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return; - } + vkd3d_mutex_lock(&heap->mutex); if (!resource->map_count) { @@ -568,7 +558,6 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap, VkMemoryRequirements memory_requirements; VkDeviceSize vk_memory_size; HRESULT hr; - int rc; heap->ID3D12Heap_iface.lpVtbl = &d3d12_heap_vtbl; heap->refcount = 1; @@ -594,11 +583,7 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap, if (FAILED(hr = validate_heap_desc(&heap->desc, resource))) return hr; - if ((rc = vkd3d_mutex_init(&heap->mutex))) - { - ERR("Failed to initialize mutex, error %d.\n", rc); - return hresult_from_errno(rc); - } + vkd3d_mutex_init(&heap->mutex); if (FAILED(hr = vkd3d_private_store_init(&heap->private_store))) { @@ -2085,6 +2070,7 @@ static struct vkd3d_view *vkd3d_view_create(enum vkd3d_view_type type) { view->refcount = 1; view->type = type; + view->serial_id = InterlockedIncrement64(&object_global_serial_id); view->vk_counter_view = VK_NULL_HANDLE; } return view; @@ -2128,6 +2114,181 @@ void vkd3d_view_decref(struct vkd3d_view *view, struct d3d12_device *device) vkd3d_view_destroy(view, device); } +/* TODO: write null descriptors to all applicable sets (invalid behaviour workaround). */ +static void d3d12_descriptor_heap_write_vk_descriptor_range(struct d3d12_descriptor_heap_vk_set *descriptor_set, + struct d3d12_desc_copy_location *locations, unsigned int write_count) +{ + unsigned int i, info_index = 0, write_index = 0; + + switch (locations[0].src.s.vk_descriptor_type) + { + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + for (; write_index < write_count; ++write_index) + { + descriptor_set->vk_descriptor_writes[write_index].pBufferInfo = &descriptor_set->vk_buffer_infos[info_index]; + for (i = 0; i < descriptor_set->vk_descriptor_writes[write_index].descriptorCount; ++i, ++info_index) + descriptor_set->vk_buffer_infos[info_index] = locations[info_index].src.s.u.vk_cbv_info; + } + break; + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + for (; write_index < write_count; ++write_index) + { + descriptor_set->vk_descriptor_writes[write_index].pImageInfo = &descriptor_set->vk_image_infos[info_index]; + for (i = 0; i < descriptor_set->vk_descriptor_writes[write_index].descriptorCount; ++i, ++info_index) + descriptor_set->vk_image_infos[info_index].imageView = locations[info_index].src.s.u.view_info.view->u.vk_image_view; + } + break; + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + for (; write_index < write_count; ++write_index) + { + descriptor_set->vk_descriptor_writes[write_index].pTexelBufferView = &descriptor_set->vk_buffer_views[info_index]; + for (i = 0; i < descriptor_set->vk_descriptor_writes[write_index].descriptorCount; ++i, ++info_index) + descriptor_set->vk_buffer_views[info_index] = locations[info_index].src.s.u.view_info.view->u.vk_buffer_view; + } + break; + case VK_DESCRIPTOR_TYPE_SAMPLER: + for (; write_index < write_count; ++write_index) + { + descriptor_set->vk_descriptor_writes[write_index].pImageInfo = &descriptor_set->vk_image_infos[info_index]; + for (i = 0; i < descriptor_set->vk_descriptor_writes[write_index].descriptorCount; ++i, ++info_index) + descriptor_set->vk_image_infos[info_index].sampler = locations[info_index].src.s.u.view_info.view->u.vk_sampler; + } + break; + default: + ERR("Unhandled descriptor type %#x.\n", locations[0].src.s.vk_descriptor_type); + break; + } +} + +static void d3d12_desc_write_vk_heap_null_descriptor(struct d3d12_descriptor_heap *descriptor_heap, + uint32_t dst_array_element, const struct d3d12_device *device) +{ + const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + struct d3d12_descriptor_heap_vk_set *descriptor_set; + VkBufferView vk_buffer_view = VK_NULL_HANDLE; + enum vkd3d_vk_descriptor_set_index i; + VkDescriptorBufferInfo vk_cbv_info; + + vk_cbv_info.buffer = VK_NULL_HANDLE; + vk_cbv_info.offset = 0; + vk_cbv_info.range = VK_WHOLE_SIZE; + + /* Binding a shader with the wrong null descriptor type works in Windows. + * To support that here we must write one to all applicable Vulkan sets. */ + for (i = VKD3D_SET_INDEX_UNIFORM_BUFFER; i <= VKD3D_SET_INDEX_STORAGE_IMAGE; ++i) + { + descriptor_set = &descriptor_heap->vk_descriptor_sets[i]; + descriptor_set->vk_descriptor_writes[0].dstArrayElement = dst_array_element; + descriptor_set->vk_descriptor_writes[0].descriptorCount = 1; + switch (i) + { + case VKD3D_SET_INDEX_UNIFORM_BUFFER: + descriptor_set->vk_descriptor_writes[0].pBufferInfo = &vk_cbv_info; + break; + case VKD3D_SET_INDEX_SAMPLED_IMAGE: + case VKD3D_SET_INDEX_STORAGE_IMAGE: + descriptor_set->vk_image_infos[0].imageView = VK_NULL_HANDLE; + break; + case VKD3D_SET_INDEX_UNIFORM_TEXEL_BUFFER: + case VKD3D_SET_INDEX_STORAGE_TEXEL_BUFFER: + descriptor_set->vk_descriptor_writes[0].pTexelBufferView = &vk_buffer_view; + break; + default: + assert(false); + break; + } + VK_CALL(vkUpdateDescriptorSets(device->vk_device, 1, descriptor_set->vk_descriptor_writes, 0, NULL)); + } +} + +/* dst and src contain the same data unless another thread overwrites dst. The array index is + * calculated from dst, and src is thread safe. */ +static void d3d12_desc_write_vk_heap(const struct d3d12_desc *dst, const struct d3d12_desc *src, + struct d3d12_device *device) +{ + struct d3d12_descriptor_heap_vk_set *descriptor_set; + struct d3d12_descriptor_heap *descriptor_heap; + const struct vkd3d_vk_device_procs *vk_procs; + bool is_null = false; + + descriptor_heap = d3d12_desc_get_descriptor_heap(dst); + descriptor_set = &descriptor_heap->vk_descriptor_sets[vkd3d_vk_descriptor_set_index_from_vk_descriptor_type( + src->s.vk_descriptor_type)]; + vk_procs = &device->vk_procs; + + vkd3d_mutex_lock(&descriptor_heap->vk_sets_mutex); + + descriptor_set->vk_descriptor_writes[0].dstArrayElement = dst->index; + descriptor_set->vk_descriptor_writes[0].descriptorCount = 1; + switch (src->s.vk_descriptor_type) + { + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + descriptor_set->vk_descriptor_writes[0].pBufferInfo = &src->s.u.vk_cbv_info; + is_null = !src->s.u.vk_cbv_info.buffer; + break; + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + is_null = !(descriptor_set->vk_image_infos[0].imageView = src->s.u.view_info.view->u.vk_image_view); + break; + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + descriptor_set->vk_descriptor_writes[0].pTexelBufferView = &src->s.u.view_info.view->u.vk_buffer_view; + is_null = !src->s.u.view_info.view->u.vk_buffer_view; + break; + case VK_DESCRIPTOR_TYPE_SAMPLER: + descriptor_set->vk_image_infos[0].sampler = src->s.u.view_info.view->u.vk_sampler; + break; + default: + ERR("Unhandled descriptor type %#x.\n", src->s.vk_descriptor_type); + break; + } + if (is_null && device->vk_info.EXT_robustness2) + { + d3d12_desc_write_vk_heap_null_descriptor(descriptor_heap, + descriptor_set->vk_descriptor_writes[0].dstArrayElement, device); + vkd3d_mutex_unlock(&descriptor_heap->vk_sets_mutex); + return; + } + + VK_CALL(vkUpdateDescriptorSets(device->vk_device, 1, descriptor_set->vk_descriptor_writes, 0, NULL)); + + if (src->s.magic == VKD3D_DESCRIPTOR_MAGIC_UAV && src->s.u.view_info.view->vk_counter_view) + { + descriptor_set = &descriptor_heap->vk_descriptor_sets[VKD3D_SET_INDEX_UAV_COUNTER]; + descriptor_set->vk_descriptor_writes[0].dstArrayElement = dst->index; + descriptor_set->vk_descriptor_writes[0].descriptorCount = 1; + descriptor_set->vk_descriptor_writes[0].pTexelBufferView = &src->s.u.view_info.view->vk_counter_view; + VK_CALL(vkUpdateDescriptorSets(device->vk_device, 1, descriptor_set->vk_descriptor_writes, 0, NULL)); + } + + vkd3d_mutex_unlock(&descriptor_heap->vk_sets_mutex); +} + +static void d3d12_desc_write_atomic_d3d12_only(struct d3d12_desc *dst, const struct d3d12_desc *src, struct d3d12_device *device) +{ + struct vkd3d_view *defunct_view; + struct vkd3d_mutex *mutex; + + mutex = d3d12_device_get_descriptor_mutex(device, dst); + vkd3d_mutex_lock(mutex); + + if (!(dst->s.magic & VKD3D_DESCRIPTOR_MAGIC_HAS_VIEW) || InterlockedDecrement(&dst->s.u.view_info.view->refcount)) + { + d3d12_desc_copy_raw(dst, src); + vkd3d_mutex_unlock(mutex); + return; + } + + defunct_view = dst->s.u.view_info.view; + d3d12_desc_copy_raw(dst, src); + vkd3d_mutex_unlock(mutex); + + /* Destroy the view after unlocking to reduce wait time. */ + vkd3d_view_destroy(defunct_view, device); +} + void d3d12_desc_write_atomic(struct d3d12_desc *dst, const struct d3d12_desc *src, struct d3d12_device *device) { @@ -2138,17 +2299,20 @@ void d3d12_desc_write_atomic(struct d3d12_desc *dst, const struct d3d12_desc *sr vkd3d_mutex_lock(mutex); /* Nothing to do for VKD3D_DESCRIPTOR_MAGIC_CBV. */ - if ((dst->magic & VKD3D_DESCRIPTOR_MAGIC_HAS_VIEW) - && !InterlockedDecrement(&dst->u.view->refcount)) - defunct_view = dst->u.view; + if ((dst->s.magic & VKD3D_DESCRIPTOR_MAGIC_HAS_VIEW) + && !InterlockedDecrement(&dst->s.u.view_info.view->refcount)) + defunct_view = dst->s.u.view_info.view; - *dst = *src; + d3d12_desc_copy_raw(dst, src); vkd3d_mutex_unlock(mutex); /* Destroy the view after unlocking to reduce wait time. */ if (defunct_view) vkd3d_view_destroy(defunct_view, device); + + if (device->use_vk_heaps && dst->s.magic) + d3d12_desc_write_vk_heap(dst, src, device); } static void d3d12_desc_destroy(struct d3d12_desc *descriptor, struct d3d12_device *device) @@ -2158,6 +2322,58 @@ static void d3d12_desc_destroy(struct d3d12_desc *descriptor, struct d3d12_devic d3d12_desc_write_atomic(descriptor, &null_desc, device); } +void d3d12_desc_copy_vk_heap_range(struct d3d12_desc_copy_location *locations, const struct d3d12_desc_copy_info *info, + struct d3d12_descriptor_heap *descriptor_heap, enum vkd3d_vk_descriptor_set_index set, + struct d3d12_device *device) +{ + struct d3d12_descriptor_heap_vk_set *descriptor_set = &descriptor_heap->vk_descriptor_sets[set]; + const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + unsigned int i, write_count; + + vkd3d_mutex_lock(&descriptor_heap->vk_sets_mutex); + + for (i = 0, write_count = 0; i < info->count; ++i) + { + d3d12_desc_write_atomic_d3d12_only(locations[i].dst, &locations[i].src, device); + + if (i && locations[i].dst == locations[i - 1].dst + 1) + { + ++descriptor_set->vk_descriptor_writes[write_count - 1].descriptorCount; + continue; + } + /* Accessing dst->index will be slow if a cache miss occurs, so calculate instead. */ + descriptor_set->vk_descriptor_writes[write_count].dstArrayElement = locations[i].dst + - (const struct d3d12_desc *)descriptor_heap->descriptors; + descriptor_set->vk_descriptor_writes[write_count++].descriptorCount = 1; + } + d3d12_descriptor_heap_write_vk_descriptor_range(descriptor_set, locations, write_count); + /* We could pass a VkCopyDescriptorSet array instead, but that would require also storing a src array index + * for each location, which means querying the src descriptor heap. Contiguous copies require contiguous src + * descriptors as well as dst, which is less likely to occur. And client race conditions may break it. */ + VK_CALL(vkUpdateDescriptorSets(device->vk_device, write_count, descriptor_set->vk_descriptor_writes, 0, NULL)); + + if (!info->uav_counter) + goto done; + + descriptor_set = &descriptor_heap->vk_descriptor_sets[VKD3D_SET_INDEX_UAV_COUNTER]; + + for (i = 0, write_count = 0; i < info->count; ++i) + { + if (!locations[i].src.s.u.view_info.view->vk_counter_view) + continue; + descriptor_set->vk_buffer_views[write_count] = locations[i].src.s.u.view_info.view->vk_counter_view; + descriptor_set->vk_descriptor_writes[write_count].pTexelBufferView = &descriptor_set->vk_buffer_views[write_count]; + /* Accessing dst->index will be slow if a cache miss occurs, so calculate instead. */ + descriptor_set->vk_descriptor_writes[write_count].dstArrayElement = locations[i].dst + - (const struct d3d12_desc *)descriptor_heap->descriptors; + descriptor_set->vk_descriptor_writes[write_count++].descriptorCount = 1; + } + VK_CALL(vkUpdateDescriptorSets(device->vk_device, write_count, descriptor_set->vk_descriptor_writes, 0, NULL)); + +done: + vkd3d_mutex_unlock(&descriptor_heap->vk_sets_mutex); +} + void d3d12_desc_copy(struct d3d12_desc *dst, const struct d3d12_desc *src, struct d3d12_device *device) { @@ -2171,10 +2387,10 @@ void d3d12_desc_copy(struct d3d12_desc *dst, const struct d3d12_desc *src, mutex = d3d12_device_get_descriptor_mutex(device, src); vkd3d_mutex_lock(mutex); - if (src->magic & VKD3D_DESCRIPTOR_MAGIC_HAS_VIEW) - vkd3d_view_incref(src->u.view); + if (src->s.magic & VKD3D_DESCRIPTOR_MAGIC_HAS_VIEW) + vkd3d_view_incref(src->s.u.view_info.view); - tmp = *src; + d3d12_desc_copy_raw(&tmp, src); vkd3d_mutex_unlock(mutex); @@ -2243,10 +2459,10 @@ bool vkd3d_create_buffer_view(struct d3d12_device *device, VkBuffer vk_buffer, c VkDeviceSize offset, VkDeviceSize size, struct vkd3d_view **view) { const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + VkBufferView vk_view = VK_NULL_HANDLE; struct vkd3d_view *object; - VkBufferView vk_view; - if (!vkd3d_create_vk_buffer_view(device, vk_buffer, format, offset, size, &vk_view)) + if (vk_buffer && !vkd3d_create_vk_buffer_view(device, vk_buffer, format, offset, size, &vk_view)) return false; if (!(object = vkd3d_view_create(VKD3D_VIEW_TYPE_BUFFER))) @@ -2531,28 +2747,31 @@ bool vkd3d_create_texture_view(struct d3d12_device *device, VkImage vk_image, const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; const struct vkd3d_format *format = desc->format; struct VkImageViewCreateInfo view_desc; + VkImageView vk_view = VK_NULL_HANDLE; struct vkd3d_view *object; - VkImageView vk_view; VkResult vr; - view_desc.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - view_desc.pNext = NULL; - view_desc.flags = 0; - view_desc.image = vk_image; - view_desc.viewType = desc->view_type; - view_desc.format = format->vk_format; - vkd3d_set_view_swizzle_for_format(&view_desc.components, format, desc->allowed_swizzle); - if (desc->allowed_swizzle) - vk_component_mapping_compose(&view_desc.components, &desc->components); - view_desc.subresourceRange.aspectMask = desc->vk_image_aspect; - view_desc.subresourceRange.baseMipLevel = desc->miplevel_idx; - view_desc.subresourceRange.levelCount = desc->miplevel_count; - view_desc.subresourceRange.baseArrayLayer = desc->layer_idx; - view_desc.subresourceRange.layerCount = desc->layer_count; - if ((vr = VK_CALL(vkCreateImageView(device->vk_device, &view_desc, NULL, &vk_view))) < 0) - { - WARN("Failed to create Vulkan image view, vr %d.\n", vr); - return false; + if (vk_image) + { + view_desc.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + view_desc.pNext = NULL; + view_desc.flags = 0; + view_desc.image = vk_image; + view_desc.viewType = desc->view_type; + view_desc.format = format->vk_format; + vkd3d_set_view_swizzle_for_format(&view_desc.components, format, desc->allowed_swizzle); + if (desc->allowed_swizzle) + vk_component_mapping_compose(&view_desc.components, &desc->components); + view_desc.subresourceRange.aspectMask = desc->vk_image_aspect; + view_desc.subresourceRange.baseMipLevel = desc->miplevel_idx; + view_desc.subresourceRange.levelCount = desc->miplevel_count; + view_desc.subresourceRange.baseArrayLayer = desc->layer_idx; + view_desc.subresourceRange.layerCount = desc->layer_count; + if ((vr = VK_CALL(vkCreateImageView(device->vk_device, &view_desc, NULL, &vk_view))) < 0) + { + WARN("Failed to create Vulkan image view, vr %d.\n", vr); + return false; + } } if (!(object = vkd3d_view_create(VKD3D_VIEW_TYPE_IMAGE))) @@ -2589,7 +2808,7 @@ void d3d12_desc_create_cbv(struct d3d12_desc *descriptor, return; } - buffer_info = &descriptor->u.vk_cbv_info; + buffer_info = &descriptor->s.u.vk_cbv_info; if (desc->BufferLocation) { resource = vkd3d_gpu_va_allocator_dereference(&device->gpu_va_allocator, desc->BufferLocation); @@ -2602,11 +2821,11 @@ void d3d12_desc_create_cbv(struct d3d12_desc *descriptor, /* NULL descriptor */ buffer_info->buffer = device->null_resources.vk_buffer; buffer_info->offset = 0; - buffer_info->range = VKD3D_NULL_BUFFER_SIZE; + buffer_info->range = VK_WHOLE_SIZE; } - descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_CBV; - descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + descriptor->s.magic = VKD3D_DESCRIPTOR_MAGIC_CBV; + descriptor->s.vk_descriptor_type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; } static unsigned int vkd3d_view_flags_from_d3d12_buffer_srv_flags(D3D12_BUFFER_SRV_FLAGS flags) @@ -2635,15 +2854,17 @@ static void vkd3d_create_null_srv(struct d3d12_desc *descriptor, switch (desc->ViewDimension) { case D3D12_SRV_DIMENSION_BUFFER: - WARN("Creating NULL buffer SRV %#x.\n", desc->Format); + if (!device->vk_info.EXT_robustness2) + WARN("Creating NULL buffer SRV %#x.\n", desc->Format); if (vkd3d_create_buffer_view(device, null_resources->vk_buffer, vkd3d_get_format(device, DXGI_FORMAT_R32_UINT, false), 0, VKD3D_NULL_BUFFER_SIZE, &view)) { - descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_SRV; - descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; - descriptor->u.view = view; + descriptor->s.magic = VKD3D_DESCRIPTOR_MAGIC_SRV; + descriptor->s.vk_descriptor_type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; + descriptor->s.u.view_info.view = view; + descriptor->s.u.view_info.written_serial_id = view->serial_id; } return; @@ -2657,17 +2878,26 @@ static void vkd3d_create_null_srv(struct d3d12_desc *descriptor, break; default: + if (device->vk_info.EXT_robustness2) + { + vk_image = VK_NULL_HANDLE; + /* view_type is not used for Vulkan null descriptors, but make it valid. */ + vkd3d_desc.view_type = VK_IMAGE_VIEW_TYPE_2D; + break; + } FIXME("Unhandled view dimension %#x.\n", desc->ViewDimension); return; } - WARN("Creating NULL SRV %#x.\n", desc->ViewDimension); + if (!device->vk_info.EXT_robustness2) + WARN("Creating NULL SRV %#x.\n", desc->ViewDimension); vkd3d_desc.format = vkd3d_get_format(device, VKD3D_NULL_VIEW_FORMAT, false); vkd3d_desc.miplevel_idx = 0; vkd3d_desc.miplevel_count = 1; vkd3d_desc.layer_idx = 0; vkd3d_desc.layer_count = 1; + vkd3d_desc.vk_image_aspect = VK_IMAGE_ASPECT_COLOR_BIT; vkd3d_desc.components.r = VK_COMPONENT_SWIZZLE_ZERO; vkd3d_desc.components.g = VK_COMPONENT_SWIZZLE_ZERO; vkd3d_desc.components.b = VK_COMPONENT_SWIZZLE_ZERO; @@ -2677,9 +2907,10 @@ static void vkd3d_create_null_srv(struct d3d12_desc *descriptor, if (!vkd3d_create_texture_view(device, vk_image, &vkd3d_desc, &view)) return; - descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_SRV; - descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; - descriptor->u.view = view; + descriptor->s.magic = VKD3D_DESCRIPTOR_MAGIC_SRV; + descriptor->s.vk_descriptor_type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + descriptor->s.u.view_info.view = view; + descriptor->s.u.view_info.written_serial_id = view->serial_id; } static void vkd3d_create_buffer_srv(struct d3d12_desc *descriptor, @@ -2707,9 +2938,10 @@ static void vkd3d_create_buffer_srv(struct d3d12_desc *descriptor, desc->u.Buffer.StructureByteStride, flags, &view)) return; - descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_SRV; - descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; - descriptor->u.view = view; + descriptor->s.magic = VKD3D_DESCRIPTOR_MAGIC_SRV; + descriptor->s.vk_descriptor_type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; + descriptor->s.u.view_info.view = view; + descriptor->s.u.view_info.written_serial_id = view->serial_id; } static VkImageAspectFlags vk_image_aspect_flags_from_d3d12_plane_slice(const struct vkd3d_format *format, @@ -2837,9 +3069,10 @@ void d3d12_desc_create_srv(struct d3d12_desc *descriptor, if (!vkd3d_create_texture_view(device, resource->u.vk_image, &vkd3d_desc, &view)) return; - descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_SRV; - descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; - descriptor->u.view = view; + descriptor->s.magic = VKD3D_DESCRIPTOR_MAGIC_SRV; + descriptor->s.vk_descriptor_type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + descriptor->s.u.view_info.view = view; + descriptor->s.u.view_info.written_serial_id = view->serial_id; } static unsigned int vkd3d_view_flags_from_d3d12_buffer_uav_flags(D3D12_BUFFER_UAV_FLAGS flags) @@ -2868,15 +3101,17 @@ static void vkd3d_create_null_uav(struct d3d12_desc *descriptor, switch (desc->ViewDimension) { case D3D12_UAV_DIMENSION_BUFFER: - WARN("Creating NULL buffer UAV %#x.\n", desc->Format); + if (!device->vk_info.EXT_robustness2) + WARN("Creating NULL buffer UAV %#x.\n", desc->Format); if (vkd3d_create_buffer_view(device, null_resources->vk_storage_buffer, vkd3d_get_format(device, DXGI_FORMAT_R32_UINT, false), 0, VKD3D_NULL_BUFFER_SIZE, &view)) { - descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_UAV; - descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; - descriptor->u.view = view; + descriptor->s.magic = VKD3D_DESCRIPTOR_MAGIC_UAV; + descriptor->s.vk_descriptor_type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; + descriptor->s.u.view_info.view = view; + descriptor->s.u.view_info.written_serial_id = view->serial_id; } return; @@ -2890,11 +3125,19 @@ static void vkd3d_create_null_uav(struct d3d12_desc *descriptor, break; default: + if (device->vk_info.EXT_robustness2) + { + vk_image = VK_NULL_HANDLE; + /* view_type is not used for Vulkan null descriptors, but make it valid. */ + vkd3d_desc.view_type = VK_IMAGE_VIEW_TYPE_2D; + break; + } FIXME("Unhandled view dimension %#x.\n", desc->ViewDimension); return; } - WARN("Creating NULL UAV %#x.\n", desc->ViewDimension); + if (!device->vk_info.EXT_robustness2) + WARN("Creating NULL UAV %#x.\n", desc->ViewDimension); vkd3d_desc.format = vkd3d_get_format(device, VKD3D_NULL_VIEW_FORMAT, false); vkd3d_desc.miplevel_idx = 0; @@ -2910,9 +3153,10 @@ static void vkd3d_create_null_uav(struct d3d12_desc *descriptor, if (!vkd3d_create_texture_view(device, vk_image, &vkd3d_desc, &view)) return; - descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_UAV; - descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; - descriptor->u.view = view; + descriptor->s.magic = VKD3D_DESCRIPTOR_MAGIC_UAV; + descriptor->s.vk_descriptor_type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + descriptor->s.u.view_info.view = view; + descriptor->s.u.view_info.written_serial_id = view->serial_id; } static void vkd3d_create_buffer_uav(struct d3d12_desc *descriptor, struct d3d12_device *device, @@ -2940,9 +3184,10 @@ static void vkd3d_create_buffer_uav(struct d3d12_desc *descriptor, struct d3d12_ desc->u.Buffer.StructureByteStride, flags, &view)) return; - descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_UAV; - descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; - descriptor->u.view = view; + descriptor->s.magic = VKD3D_DESCRIPTOR_MAGIC_UAV; + descriptor->s.vk_descriptor_type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; + descriptor->s.u.view_info.view = view; + descriptor->s.u.view_info.written_serial_id = view->serial_id; if (counter_resource) { @@ -3015,9 +3260,10 @@ static void vkd3d_create_texture_uav(struct d3d12_desc *descriptor, if (!vkd3d_create_texture_view(device, resource->u.vk_image, &vkd3d_desc, &view)) return; - descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_UAV; - descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; - descriptor->u.view = view; + descriptor->s.magic = VKD3D_DESCRIPTOR_MAGIC_UAV; + descriptor->s.vk_descriptor_type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + descriptor->s.u.view_info.view = view; + descriptor->s.u.view_info.written_serial_id = view->serial_id; } void d3d12_desc_create_uav(struct d3d12_desc *descriptor, struct d3d12_device *device, @@ -3177,9 +3423,10 @@ void d3d12_desc_create_sampler(struct d3d12_desc *sampler, return; } - sampler->magic = VKD3D_DESCRIPTOR_MAGIC_SAMPLER; - sampler->vk_descriptor_type = VK_DESCRIPTOR_TYPE_SAMPLER; - sampler->u.view = view; + sampler->s.magic = VKD3D_DESCRIPTOR_MAGIC_SAMPLER; + sampler->s.vk_descriptor_type = VK_DESCRIPTOR_TYPE_SAMPLER; + sampler->s.u.view_info.view = view; + sampler->s.u.view_info.written_serial_id = view->serial_id; } HRESULT vkd3d_create_static_sampler(struct d3d12_device *device, @@ -3425,9 +3672,12 @@ static ULONG STDMETHODCALLTYPE d3d12_descriptor_heap_Release(ID3D12DescriptorHea if (!refcount) { + const struct vkd3d_vk_device_procs *vk_procs; struct d3d12_device *device = heap->device; unsigned int i; + vk_procs = &device->vk_procs; + vkd3d_private_store_destroy(&heap->private_store); switch (heap->desc.Type) @@ -3442,9 +3692,6 @@ static ULONG STDMETHODCALLTYPE d3d12_descriptor_heap_Release(ID3D12DescriptorHea d3d12_desc_destroy(&descriptors[i], device); } - if (device->vk_info.EXT_descriptor_indexing && !vkd3d_gpu_descriptor_allocator_unregister_range( - &device->gpu_descriptor_allocator, descriptors)) - ERR("Failed to unregister descriptor range.\n"); break; } @@ -3474,6 +3721,9 @@ static ULONG STDMETHODCALLTYPE d3d12_descriptor_heap_Release(ID3D12DescriptorHea break; } + VK_CALL(vkDestroyDescriptorPool(device->vk_device, heap->vk_descriptor_pool, NULL)); + vkd3d_mutex_destroy(&heap->vk_sets_mutex); + vkd3d_free(heap); d3d12_device_release(device); @@ -3584,6 +3834,152 @@ static const struct ID3D12DescriptorHeapVtbl d3d12_descriptor_heap_vtbl = d3d12_descriptor_heap_GetGPUDescriptorHandleForHeapStart, }; +const enum vkd3d_vk_descriptor_set_index vk_descriptor_set_index_table[] = +{ + VKD3D_SET_INDEX_SAMPLER, + VKD3D_SET_INDEX_COUNT, + VKD3D_SET_INDEX_SAMPLED_IMAGE, + VKD3D_SET_INDEX_STORAGE_IMAGE, + VKD3D_SET_INDEX_UNIFORM_TEXEL_BUFFER, + VKD3D_SET_INDEX_STORAGE_TEXEL_BUFFER, + VKD3D_SET_INDEX_UNIFORM_BUFFER, +}; + +static HRESULT d3d12_descriptor_heap_create_descriptor_pool(struct d3d12_descriptor_heap *descriptor_heap, + struct d3d12_device *device, const D3D12_DESCRIPTOR_HEAP_DESC *desc) +{ + const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + VkDescriptorPoolSize pool_sizes[VKD3D_SET_INDEX_COUNT]; + struct VkDescriptorPoolCreateInfo pool_desc; + VkDevice vk_device = device->vk_device; + enum vkd3d_vk_descriptor_set_index set; + VkResult vr; + + for (set = 0, pool_desc.poolSizeCount = 0; set < ARRAY_SIZE(device->vk_descriptor_heap_layouts); ++set) + { + if (device->vk_descriptor_heap_layouts[set].applicable_heap_type == desc->Type) + { + pool_sizes[pool_desc.poolSizeCount].type = device->vk_descriptor_heap_layouts[set].type; + pool_sizes[pool_desc.poolSizeCount++].descriptorCount = desc->NumDescriptors; + } + } + + pool_desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + pool_desc.pNext = NULL; + pool_desc.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT; + pool_desc.maxSets = pool_desc.poolSizeCount; + pool_desc.pPoolSizes = pool_sizes; + if ((vr = VK_CALL(vkCreateDescriptorPool(vk_device, &pool_desc, NULL, &descriptor_heap->vk_descriptor_pool))) < 0) + ERR("Failed to create descriptor pool, vr %d.\n", vr); + + return hresult_from_vk_result(vr); +} + +static HRESULT d3d12_descriptor_heap_create_descriptor_set(struct d3d12_descriptor_heap *descriptor_heap, + struct d3d12_device *device, unsigned int set) +{ + struct d3d12_descriptor_heap_vk_set *descriptor_set = &descriptor_heap->vk_descriptor_sets[set]; + uint32_t variable_binding_size = descriptor_heap->desc.NumDescriptors; + const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + VkDescriptorSetVariableDescriptorCountAllocateInfoEXT set_size; + VkDescriptorSetAllocateInfo set_desc; + unsigned int i; + VkResult vr; + + set_desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + set_desc.pNext = &set_size; + set_desc.descriptorPool = descriptor_heap->vk_descriptor_pool; + set_desc.descriptorSetCount = 1; + set_desc.pSetLayouts = &device->vk_descriptor_heap_layouts[set].vk_set_layout; + set_size.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT; + set_size.pNext = NULL; + set_size.descriptorSetCount = 1; + set_size.pDescriptorCounts = &variable_binding_size; + if ((vr = VK_CALL(vkAllocateDescriptorSets(device->vk_device, &set_desc, &descriptor_set->vk_set))) >= 0) + { + for (i = 0; i < ARRAY_SIZE(descriptor_set->vk_descriptor_writes); ++i) + descriptor_set->vk_descriptor_writes[i].dstSet = descriptor_set->vk_set; + return S_OK; + } + + ERR("Failed to allocate descriptor set, vr %d.\n", vr); + return hresult_from_vk_result(vr); +} + +static HRESULT d3d12_descriptor_heap_vk_descriptor_sets_init(struct d3d12_descriptor_heap *descriptor_heap, + struct d3d12_device *device, const D3D12_DESCRIPTOR_HEAP_DESC *desc) +{ + enum vkd3d_vk_descriptor_set_index set; + HRESULT hr; + + descriptor_heap->vk_descriptor_pool = VK_NULL_HANDLE; + memset(descriptor_heap->vk_descriptor_sets, 0, sizeof(descriptor_heap->vk_descriptor_sets)); + vkd3d_mutex_init(&descriptor_heap->vk_sets_mutex); + + if (!device->use_vk_heaps || (desc->Type != D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV + && desc->Type != D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER)) + return S_OK; + + if (FAILED(hr = d3d12_descriptor_heap_create_descriptor_pool(descriptor_heap, device, desc))) + return hr; + + for (set = 0; set < ARRAY_SIZE(descriptor_heap->vk_descriptor_sets); ++set) + { + struct d3d12_descriptor_heap_vk_set *descriptor_set = &descriptor_heap->vk_descriptor_sets[set]; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(descriptor_set->vk_descriptor_writes); ++i) + { + descriptor_set->vk_descriptor_writes[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptor_set->vk_descriptor_writes[i].pNext = NULL; + descriptor_set->vk_descriptor_writes[i].dstBinding = 0; + descriptor_set->vk_descriptor_writes[i].descriptorType = device->vk_descriptor_heap_layouts[set].type; + descriptor_set->vk_descriptor_writes[i].pImageInfo = NULL; + descriptor_set->vk_descriptor_writes[i].pBufferInfo = NULL; + descriptor_set->vk_descriptor_writes[i].pTexelBufferView = NULL; + } + switch (device->vk_descriptor_heap_layouts[set].type) + { + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + break; + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + descriptor_set->vk_descriptor_writes[0].pImageInfo = &descriptor_set->vk_image_infos[0]; + for (i = 0; i < ARRAY_SIZE(descriptor_set->vk_image_infos); ++i) + { + descriptor_set->vk_image_infos[i].sampler = VK_NULL_HANDLE; + descriptor_set->vk_image_infos[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + } + break; + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + descriptor_set->vk_descriptor_writes[0].pImageInfo = &descriptor_set->vk_image_infos[0]; + for (i = 0; i < ARRAY_SIZE(descriptor_set->vk_image_infos); ++i) + { + descriptor_set->vk_image_infos[i].sampler = VK_NULL_HANDLE; + descriptor_set->vk_image_infos[i].imageLayout = VK_IMAGE_LAYOUT_GENERAL; + } + break; + case VK_DESCRIPTOR_TYPE_SAMPLER: + descriptor_set->vk_descriptor_writes[0].pImageInfo = &descriptor_set->vk_image_infos[0]; + for (i = 0; i < ARRAY_SIZE(descriptor_set->vk_image_infos); ++i) + { + descriptor_set->vk_image_infos[i].imageView = VK_NULL_HANDLE; + descriptor_set->vk_image_infos[i].imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; + } + break; + default: + ERR("Unhandled descriptor type %#x.\n", device->vk_descriptor_heap_layouts[set].type); + return E_FAIL; + } + if (device->vk_descriptor_heap_layouts[set].applicable_heap_type == desc->Type + && FAILED(hr = d3d12_descriptor_heap_create_descriptor_set(descriptor_heap, device, set))) + return hr; + } + + return S_OK; +} + static HRESULT d3d12_descriptor_heap_init(struct d3d12_descriptor_heap *descriptor_heap, struct d3d12_device *device, const D3D12_DESCRIPTOR_HEAP_DESC *desc) { @@ -3591,12 +3987,15 @@ static HRESULT d3d12_descriptor_heap_init(struct d3d12_descriptor_heap *descript descriptor_heap->ID3D12DescriptorHeap_iface.lpVtbl = &d3d12_descriptor_heap_vtbl; descriptor_heap->refcount = 1; + descriptor_heap->serial_id = InterlockedIncrement64(&object_global_serial_id); descriptor_heap->desc = *desc; if (FAILED(hr = vkd3d_private_store_init(&descriptor_heap->private_store))) return hr; + d3d12_descriptor_heap_vk_descriptor_sets_init(descriptor_heap, device, desc); + d3d12_device_add_ref(descriptor_heap->device = device); return S_OK; @@ -3607,6 +4006,8 @@ HRESULT d3d12_descriptor_heap_create(struct d3d12_device *device, { size_t max_descriptor_count, descriptor_size; struct d3d12_descriptor_heap *object; + struct d3d12_desc *dst; + unsigned int i; HRESULT hr; if (!(descriptor_size = d3d12_device_get_descriptor_handle_increment_size(device, desc->Type))) @@ -3639,12 +4040,19 @@ HRESULT d3d12_descriptor_heap_create(struct d3d12_device *device, return hr; } - memset(object->descriptors, 0, descriptor_size * desc->NumDescriptors); - - if ((desc->Type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV || desc->Type == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER) - && device->vk_info.EXT_descriptor_indexing && !vkd3d_gpu_descriptor_allocator_register_range( - &device->gpu_descriptor_allocator, (struct d3d12_desc *)object->descriptors, desc->NumDescriptors)) - ERR("Failed to register descriptor range.\n"); + if (desc->Type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV || desc->Type == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER) + { + dst = (struct d3d12_desc *)object->descriptors; + for (i = 0; i < desc->NumDescriptors; ++i) + { + memset(&dst[i].s, 0, sizeof(dst[i].s)); + dst[i].index = i; + } + } + else + { + memset(object->descriptors, 0, descriptor_size * desc->NumDescriptors); + } TRACE("Created descriptor heap %p.\n", object); @@ -4077,6 +4485,9 @@ HRESULT vkd3d_init_null_resources(struct vkd3d_null_resources *null_resources, memset(null_resources, 0, sizeof(*null_resources)); + if (device->vk_info.EXT_robustness2) + return S_OK; + memset(&heap_properties, 0, sizeof(heap_properties)); heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT; diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d/state.c b/dll/directx/wine/vkd3d/libs/vkd3d/state.c similarity index 92% rename from dll/directx/wine/d3d12/vkd3d/vkd3d/state.c rename to dll/directx/wine/vkd3d/libs/vkd3d/state.c index 2d3954d29aecf..c964ea8fe3a28 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d/state.c +++ b/dll/directx/wine/vkd3d/libs/vkd3d/state.c @@ -92,6 +92,8 @@ static void d3d12_root_signature_cleanup(struct d3d12_root_signature *root_signa if (root_signature->descriptor_mapping) vkd3d_free(root_signature->descriptor_mapping); vkd3d_free(root_signature->descriptor_offsets); + vkd3d_free(root_signature->uav_counter_mapping); + vkd3d_free(root_signature->uav_counter_offsets); if (root_signature->root_constants) vkd3d_free(root_signature->root_constants); @@ -327,6 +329,7 @@ static bool vk_binding_from_d3d12_descriptor_range(struct VkDescriptorSetLayoutB struct d3d12_root_signature_info { size_t binding_count; + size_t uav_range_count; size_t root_constant_count; size_t root_descriptor_count; @@ -401,6 +404,7 @@ static HRESULT d3d12_root_signature_info_count_descriptors(struct d3d12_root_sig info->binding_count += binding_count; info->uav_count += count * 2u; uav_unbounded_range |= unbounded; + ++info->uav_range_count; break; case D3D12_DESCRIPTOR_RANGE_TYPE_CBV: info->cbv_count += count; @@ -495,6 +499,7 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat uint32_t *push_constant_range_count) { uint32_t push_constants_offset[D3D12_SHADER_VISIBILITY_PIXEL + 1]; + bool use_vk_heaps = root_signature->device->use_vk_heaps; unsigned int i, j, push_constant_count; uint32_t offset; @@ -507,7 +512,8 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat continue; assert(p->ShaderVisibility <= D3D12_SHADER_VISIBILITY_PIXEL); - push_constants[p->ShaderVisibility].stageFlags = stage_flags_from_visibility(p->ShaderVisibility); + push_constants[p->ShaderVisibility].stageFlags = use_vk_heaps ? VK_SHADER_STAGE_ALL + : stage_flags_from_visibility(p->ShaderVisibility); push_constants[p->ShaderVisibility].size += p->u.Constants.Num32BitValues * sizeof(uint32_t); } if (push_constants[D3D12_SHADER_VISIBILITY_ALL].size) @@ -586,6 +592,8 @@ struct vkd3d_descriptor_set_context unsigned int table_index; unsigned int unbounded_offset; unsigned int descriptor_index; + unsigned int uav_counter_index; + unsigned int push_constant_index; uint32_t descriptor_binding; }; @@ -595,6 +603,7 @@ static bool vkd3d_validate_descriptor_set_count(struct d3d12_device *device, uns if (set_count > max_count) { + /* NOTE: If maxBoundDescriptorSets is < 9, try VKD3D_CONFIG=virtual_heaps */ ERR("Required descriptor set count exceeds maximum allowed count of %u.\n", max_count); return false; } @@ -802,6 +811,122 @@ static void d3d12_root_signature_map_vk_unbounded_binding(struct d3d12_root_sign offset->dynamic_offset_index = ~0u; } +static unsigned int vk_heap_binding_count_from_descriptor_range(const struct d3d12_root_descriptor_table_range *range, + unsigned int descriptor_set_size) +{ + unsigned int max_count; + + if (descriptor_set_size <= range->offset) + { + ERR("Descriptor range offset %u exceeds maximum available offset %u.\n", range->offset, descriptor_set_size - 1); + max_count = 0; + } + else + { + max_count = descriptor_set_size - range->offset; + } + + if (range->descriptor_count != UINT_MAX) + { + if (range->descriptor_count > max_count) + ERR("Range size %u exceeds available descriptor count %u.\n", range->descriptor_count, max_count); + return range->descriptor_count; + } + else + { + /* Prefer an unsupported binding count vs a zero count, because shader compilation will fail + * to match a declaration to a zero binding, resulting in failure of pipline state creation. */ + return max_count + !max_count; + } +} + +static void vkd3d_descriptor_heap_binding_from_descriptor_range(const struct d3d12_root_descriptor_table_range *range, + bool is_buffer, const struct d3d12_root_signature *root_signature, + struct vkd3d_shader_descriptor_binding *binding) +{ + const struct vkd3d_device_descriptor_limits *descriptor_limits = &root_signature->device->vk_info.descriptor_limits; + unsigned int descriptor_set_size; + + switch (range->type) + { + case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV: + binding->set = is_buffer ? VKD3D_SET_INDEX_UNIFORM_TEXEL_BUFFER : VKD3D_SET_INDEX_SAMPLED_IMAGE; + descriptor_set_size = descriptor_limits->sampled_image_max_descriptors; + break; + case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV: + binding->set = is_buffer ? VKD3D_SET_INDEX_STORAGE_TEXEL_BUFFER : VKD3D_SET_INDEX_STORAGE_IMAGE; + descriptor_set_size = descriptor_limits->storage_image_max_descriptors; + break; + case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV: + binding->set = VKD3D_SET_INDEX_UNIFORM_BUFFER; + descriptor_set_size = descriptor_limits->uniform_buffer_max_descriptors; + break; + case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER: + binding->set = VKD3D_SET_INDEX_SAMPLER; + descriptor_set_size = descriptor_limits->sampler_max_descriptors; + break; + default: + FIXME("Unhandled descriptor range type type %#x.\n", range->type); + binding->set = VKD3D_SET_INDEX_SAMPLED_IMAGE; + descriptor_set_size = descriptor_limits->sampled_image_max_descriptors; + break; + } + binding->set += root_signature->vk_set_count; + binding->binding = 0; + binding->count = vk_heap_binding_count_from_descriptor_range(range, descriptor_set_size); +} + +static void d3d12_root_signature_map_vk_heap_binding(struct d3d12_root_signature *root_signature, + const struct d3d12_root_descriptor_table_range *range, bool buffer_descriptor, + enum vkd3d_shader_visibility shader_visibility, struct vkd3d_descriptor_set_context *context) +{ + struct vkd3d_shader_resource_binding *mapping = &root_signature->descriptor_mapping[context->descriptor_index]; + struct vkd3d_shader_descriptor_offset *offset = &root_signature->descriptor_offsets[context->descriptor_index++]; + + mapping->type = range->type; + mapping->register_space = range->register_space; + mapping->register_index = range->base_register_idx; + mapping->shader_visibility = shader_visibility; + mapping->flags = buffer_descriptor ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE; + vkd3d_descriptor_heap_binding_from_descriptor_range(range, buffer_descriptor, root_signature, &mapping->binding); + offset->static_offset = range->offset; + offset->dynamic_offset_index = context->push_constant_index; +} + +static void d3d12_root_signature_map_vk_heap_uav_counter(struct d3d12_root_signature *root_signature, + const struct d3d12_root_descriptor_table_range *range, enum vkd3d_shader_visibility shader_visibility, + struct vkd3d_descriptor_set_context *context) +{ + struct vkd3d_shader_uav_counter_binding *mapping = &root_signature->uav_counter_mapping[context->uav_counter_index]; + struct vkd3d_shader_descriptor_offset *offset = &root_signature->uav_counter_offsets[context->uav_counter_index++]; + + mapping->register_space = range->register_space; + mapping->register_index = range->base_register_idx; + mapping->shader_visibility = shader_visibility; + mapping->binding.set = root_signature->vk_set_count + VKD3D_SET_INDEX_UAV_COUNTER; + mapping->binding.binding = 0; + mapping->binding.count = vk_heap_binding_count_from_descriptor_range(range, + root_signature->device->vk_info.descriptor_limits.storage_image_max_descriptors); + offset->static_offset = range->offset; + offset->dynamic_offset_index = context->push_constant_index; +} + +static void d3d12_root_signature_map_descriptor_heap_binding(struct d3d12_root_signature *root_signature, + const struct d3d12_root_descriptor_table_range *range, enum vkd3d_shader_visibility shader_visibility, + struct vkd3d_descriptor_set_context *context) +{ + bool is_buffer = range->type == VKD3D_SHADER_DESCRIPTOR_TYPE_CBV; + + if (range->type == VKD3D_SHADER_DESCRIPTOR_TYPE_SRV || range->type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV) + { + d3d12_root_signature_map_vk_heap_binding(root_signature, range, true, shader_visibility, context); + if (range->type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV) + d3d12_root_signature_map_vk_heap_uav_counter(root_signature, range, shader_visibility, context); + } + + d3d12_root_signature_map_vk_heap_binding(root_signature, range, is_buffer, shader_visibility, context); +} + static void d3d12_root_signature_map_descriptor_unbounded_binding(struct d3d12_root_signature *root_signature, const struct d3d12_root_descriptor_table_range *range, unsigned int descriptor_offset, enum vkd3d_shader_visibility shader_visibility, struct vkd3d_descriptor_set_context *context) @@ -868,6 +993,7 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo struct vkd3d_descriptor_set_context *context) { const struct d3d12_device *device = root_signature->device; + bool use_vk_heaps = root_signature->device->use_vk_heaps; struct d3d12_root_descriptor_table *table; unsigned int i, j, k, range_count; uint32_t vk_binding; @@ -935,6 +1061,16 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo range = &table->ranges[j]; + if (use_vk_heaps) + { + /* set, binding and vk_binding_count are not used. */ + range->set = 0; + range->binding = 0; + range->vk_binding_count = 0; + d3d12_root_signature_map_descriptor_heap_binding(root_signature, range, shader_visibility, context); + continue; + } + range->set = root_signature->vk_set_count - root_signature->main_set; if (root_signature->use_descriptor_arrays) @@ -1014,6 +1150,7 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo context->current_binding = cur_binding; } + ++context->push_constant_index; } return S_OK; @@ -1084,9 +1221,36 @@ static HRESULT d3d12_root_signature_init_static_samplers(struct d3d12_root_signa } context->current_binding = cur_binding; + if (device->use_vk_heaps) + return d3d12_root_signature_append_descriptor_set_layout(root_signature, context, 0); + return S_OK; } +static void d3d12_root_signature_init_descriptor_table_push_constants(struct d3d12_root_signature *root_signature, + const struct vkd3d_descriptor_set_context *context) +{ + root_signature->descriptor_table_offset = 0; + if ((root_signature->descriptor_table_count = context->push_constant_index)) + { + VkPushConstantRange *range = &root_signature->push_constant_ranges[D3D12_SHADER_VISIBILITY_ALL]; + + root_signature->descriptor_table_offset = align(range->size, 16); + range->size = root_signature->descriptor_table_offset + + root_signature->descriptor_table_count * sizeof(uint32_t); + + if (range->size > root_signature->device->vk_info.device_limits.maxPushConstantsSize) + FIXME("Push constants size %u exceeds maximum allowed size %u. Try VKD3D_CONFIG=virtual_heaps.\n", + range->size, root_signature->device->vk_info.device_limits.maxPushConstantsSize); + + if (!root_signature->push_constant_range_count) + { + root_signature->push_constant_range_count = 1; + range->stageFlags = VK_SHADER_STAGE_ALL; + } + } +} + static bool vk_binding_uses_partial_binding(const VkDescriptorSetLayoutBinding *binding) { if (binding->descriptorCount == 1) @@ -1194,11 +1358,19 @@ static HRESULT vkd3d_create_pipeline_layout(struct d3d12_device *device, static unsigned int d3d12_root_signature_copy_descriptor_set_layouts(const struct d3d12_root_signature *root_signature, VkDescriptorSetLayout *vk_set_layouts) { + const struct d3d12_device *device = root_signature->device; + enum vkd3d_vk_descriptor_set_index set; unsigned int i; for (i = 0; i < root_signature->vk_set_count; ++i) vk_set_layouts[i] = root_signature->descriptor_set_layouts[i].vk_layout; + if (device->use_vk_heaps) + { + for (set = 0; set < ARRAY_SIZE(device->vk_descriptor_heap_layouts); ++set) + vk_set_layouts[i++] = device->vk_descriptor_heap_layouts[set].vk_set_layout; + } + return i; } @@ -1210,6 +1382,7 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa struct vkd3d_descriptor_set_context context; VkDescriptorSetLayoutBinding *binding_desc; struct d3d12_root_signature_info info; + bool use_vk_heaps; unsigned int i; HRESULT hr; @@ -1226,6 +1399,8 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa root_signature->flags = desc->Flags; root_signature->descriptor_mapping = NULL; root_signature->descriptor_offsets = NULL; + root_signature->uav_counter_mapping = NULL; + root_signature->uav_counter_offsets = NULL; root_signature->static_sampler_count = 0; root_signature->static_samplers = NULL; root_signature->device = device; @@ -1243,9 +1418,13 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa } root_signature->binding_count = info.binding_count; + root_signature->uav_mapping_count = info.uav_range_count; root_signature->static_sampler_count = desc->NumStaticSamplers; root_signature->root_descriptor_count = info.root_descriptor_count; root_signature->use_descriptor_arrays = device->vk_info.EXT_descriptor_indexing; + root_signature->descriptor_table_count = 0; + + use_vk_heaps = device->use_vk_heaps; hr = E_OUTOFMEMORY; root_signature->parameter_count = desc->NumParameters; @@ -1255,6 +1434,11 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa if (!(root_signature->descriptor_mapping = vkd3d_calloc(root_signature->binding_count, sizeof(*root_signature->descriptor_mapping)))) goto fail; + if (use_vk_heaps && (!(root_signature->uav_counter_mapping = vkd3d_calloc(root_signature->uav_mapping_count, + sizeof(*root_signature->uav_counter_mapping))) + || !(root_signature->uav_counter_offsets = vkd3d_calloc(root_signature->uav_mapping_count, + sizeof(*root_signature->uav_counter_offsets))))) + goto fail; if (root_signature->use_descriptor_arrays && !(root_signature->descriptor_offsets = vkd3d_calloc( root_signature->binding_count, sizeof(*root_signature->descriptor_offsets)))) goto fail; @@ -1289,8 +1473,11 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa goto fail; if (FAILED(hr = d3d12_root_signature_init_static_samplers(root_signature, device, desc, &context))) goto fail; + context.push_constant_index = 0; if (FAILED(hr = d3d12_root_signature_init_root_descriptor_tables(root_signature, desc, &info, &context))) goto fail; + if (use_vk_heaps) + d3d12_root_signature_init_descriptor_table_push_constants(root_signature, &context); if (FAILED(hr = d3d12_root_signature_append_descriptor_set_layout(root_signature, &context, 0))) goto fail; @@ -1502,14 +1689,8 @@ HRESULT vkd3d_render_pass_cache_find(struct vkd3d_render_pass_cache *cache, bool found = false; HRESULT hr = S_OK; unsigned int i; - int rc; - if ((rc = vkd3d_mutex_lock(&device->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - *vk_render_pass = VK_NULL_HANDLE; - return hresult_from_errno(rc); - } + vkd3d_mutex_lock(&device->mutex); for (i = 0; i < cache->render_pass_count; ++i) { @@ -1757,6 +1938,13 @@ struct d3d12_pipeline_state *unsafe_impl_from_ID3D12PipelineState(ID3D12Pipeline return impl_from_ID3D12PipelineState(iface); } +static inline unsigned int typed_uav_compile_option(const struct d3d12_device *device) +{ + return device->vk_info.uav_read_without_format + ? VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV_READ_FORMAT_UNKNOWN + : VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV_READ_FORMAT_R32; +} + static HRESULT create_shader_stage(struct d3d12_device *device, struct VkPipelineShaderStageCreateInfo *stage_desc, enum VkShaderStageFlagBits stage, const D3D12_SHADER_BYTECODE *code, const struct vkd3d_shader_interface_info *shader_interface) @@ -1768,9 +1956,11 @@ static HRESULT create_shader_stage(struct d3d12_device *device, VkResult vr; int ret; - static const struct vkd3d_shader_compile_option options[] = + const struct vkd3d_shader_compile_option options[] = { - {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_3}, + {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_7}, + {VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV, typed_uav_compile_option(device)}, + {VKD3D_SHADER_COMPILE_OPTION_WRITE_TESS_GEOM_POINT_SIZE, 0}, }; stage_desc->sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; @@ -1814,14 +2004,15 @@ static HRESULT create_shader_stage(struct d3d12_device *device, return S_OK; } -static int vkd3d_scan_dxbc(const D3D12_SHADER_BYTECODE *code, +static int vkd3d_scan_dxbc(const struct d3d12_device *device, const D3D12_SHADER_BYTECODE *code, struct vkd3d_shader_scan_descriptor_info *descriptor_info) { struct vkd3d_shader_compile_info compile_info; - static const struct vkd3d_shader_compile_option options[] = + const struct vkd3d_shader_compile_option options[] = { - {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_3}, + {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_7}, + {VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV, typed_uav_compile_option(device)}, }; compile_info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; @@ -1862,7 +2053,7 @@ static HRESULT vkd3d_create_compute_pipeline(struct d3d12_device *device, VK_CALL(vkDestroyShaderModule(device->vk_device, pipeline_info.stage.module, NULL)); if (vr < 0) { - WARN("Failed to create Vulkan compute pipeline, hr %#x.", hr); + WARN("Failed to create Vulkan compute pipeline, hr %#x.\n", hr); return hresult_from_vk_result(vr); } @@ -1978,9 +2169,12 @@ static HRESULT d3d12_pipeline_state_find_and_init_uav_counters(struct d3d12_pipe HRESULT hr; int ret; + if (device->use_vk_heaps) + return S_OK; + shader_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO; shader_info.next = NULL; - if ((ret = vkd3d_scan_dxbc(code, &shader_info)) < 0) + if ((ret = vkd3d_scan_dxbc(device, code, &shader_info)) < 0) { WARN("Failed to scan shader bytecode, stage %#x, vkd3d result %d.\n", stage_flags, ret); return hresult_from_vkd3d_result(ret); @@ -2030,10 +2224,10 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st { offset_info.type = VKD3D_SHADER_STRUCTURE_TYPE_DESCRIPTOR_OFFSET_INFO; offset_info.next = NULL; - offset_info.descriptor_table_offset = 0; - offset_info.descriptor_table_count = 0; + offset_info.descriptor_table_offset = root_signature->descriptor_table_offset; + offset_info.descriptor_table_count = root_signature->descriptor_table_count; offset_info.binding_offsets = root_signature->descriptor_offsets; - offset_info.uav_counter_offsets = NULL; + offset_info.uav_counter_offsets = root_signature->uav_counter_offsets; vkd3d_prepend_struct(&target_info, &offset_info); } @@ -2045,8 +2239,16 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st shader_interface.push_constant_buffer_count = root_signature->root_constant_count; shader_interface.combined_samplers = NULL; shader_interface.combined_sampler_count = 0; - shader_interface.uav_counters = state->uav_counters.bindings; - shader_interface.uav_counter_count = state->uav_counters.binding_count; + if (root_signature->uav_counter_mapping) + { + shader_interface.uav_counters = root_signature->uav_counter_mapping; + shader_interface.uav_counter_count = root_signature->uav_mapping_count; + } + else + { + shader_interface.uav_counters = state->uav_counters.bindings; + shader_interface.uav_counter_count = state->uav_counters.binding_count; + } vk_pipeline_layout = state->uav_counters.vk_pipeline_layout ? state->uav_counters.vk_pipeline_layout : root_signature->vk_pipeline_layout; @@ -2430,9 +2632,9 @@ static HRESULT compute_input_layout_offsets(const struct d3d12_device *device, if (e->AlignedByteOffset != D3D12_APPEND_ALIGNED_ELEMENT) offsets[i] = e->AlignedByteOffset; else - offsets[i] = input_slot_offsets[e->InputSlot]; + offsets[i] = align(input_slot_offsets[e->InputSlot], min(4, format->byte_count)); - input_slot_offsets[e->InputSlot] = align(offsets[i] + format->byte_count, 4); + input_slot_offsets[e->InputSlot] = offsets[i] + format->byte_count; } return S_OK; @@ -2664,7 +2866,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s } if (rt_desc->BlendEnable && rt_desc->LogicOpEnable) { - WARN("Only one of BlendEnable or LogicOpEnable can be set to TRUE."); + WARN("Only one of BlendEnable or LogicOpEnable can be set to TRUE.\n"); hr = E_INVALIDARG; goto fail; } @@ -2807,10 +3009,10 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s { offset_info.type = VKD3D_SHADER_STRUCTURE_TYPE_DESCRIPTOR_OFFSET_INFO; offset_info.next = NULL; - offset_info.descriptor_table_offset = 0; - offset_info.descriptor_table_count = 0; + offset_info.descriptor_table_offset = root_signature->descriptor_table_offset; + offset_info.descriptor_table_count = root_signature->descriptor_table_count; offset_info.binding_offsets = root_signature->descriptor_offsets; - offset_info.uav_counter_offsets = NULL; + offset_info.uav_counter_offsets = root_signature->uav_counter_offsets; } for (i = 0; i < ARRAY_SIZE(shader_stages); ++i) @@ -2852,8 +3054,10 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s break; case VK_SHADER_STAGE_FRAGMENT_BIT: - shader_interface.uav_counters = state->uav_counters.bindings; - shader_interface.uav_counter_count = state->uav_counters.binding_count; + shader_interface.uav_counters = root_signature->uav_counter_mapping + ? root_signature->uav_counter_mapping : state->uav_counters.bindings; + shader_interface.uav_counter_count = root_signature->uav_counter_mapping + ? root_signature->uav_mapping_count : state->uav_counters.binding_count; stage_target_info = &ps_target_info; break; @@ -3161,28 +3365,23 @@ static VkPipeline d3d12_pipeline_state_find_compiled_pipeline(const struct d3d12 struct d3d12_device *device = state->device; VkPipeline vk_pipeline = VK_NULL_HANDLE; struct vkd3d_compiled_pipeline *current; - int rc; *vk_render_pass = VK_NULL_HANDLE; - if (!(rc = vkd3d_mutex_lock(&device->mutex))) + vkd3d_mutex_lock(&device->mutex); + + LIST_FOR_EACH_ENTRY(current, &graphics->compiled_pipelines, struct vkd3d_compiled_pipeline, entry) { - LIST_FOR_EACH_ENTRY(current, &graphics->compiled_pipelines, struct vkd3d_compiled_pipeline, entry) + if (!memcmp(¤t->key, key, sizeof(*key))) { - if (!memcmp(¤t->key, key, sizeof(*key))) - { - vk_pipeline = current->vk_pipeline; - *vk_render_pass = current->vk_render_pass; - break; - } + vk_pipeline = current->vk_pipeline; + *vk_render_pass = current->vk_render_pass; + break; } - vkd3d_mutex_unlock(&device->mutex); - } - else - { - ERR("Failed to lock mutex, error %d.\n", rc); } + vkd3d_mutex_unlock(&device->mutex); + return vk_pipeline; } @@ -3192,7 +3391,6 @@ static bool d3d12_pipeline_state_put_pipeline_to_cache(struct d3d12_pipeline_sta struct d3d12_graphics_pipeline_state *graphics = &state->u.graphics; struct vkd3d_compiled_pipeline *compiled_pipeline, *current; struct d3d12_device *device = state->device; - int rc; if (!(compiled_pipeline = vkd3d_malloc(sizeof(*compiled_pipeline)))) return false; @@ -3201,12 +3399,7 @@ static bool d3d12_pipeline_state_put_pipeline_to_cache(struct d3d12_pipeline_sta compiled_pipeline->vk_pipeline = vk_pipeline; compiled_pipeline->vk_render_pass = vk_render_pass; - if ((rc = vkd3d_mutex_lock(&device->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - vkd3d_free(compiled_pipeline); - return false; - } + vkd3d_mutex_lock(&device->mutex); LIST_FOR_EACH_ENTRY(current, &graphics->compiled_pipelines, struct vkd3d_compiled_pipeline, entry) { diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d/utils.c b/dll/directx/wine/vkd3d/libs/vkd3d/utils.c similarity index 98% rename from dll/directx/wine/d3d12/vkd3d/vkd3d/utils.c rename to dll/directx/wine/vkd3d/libs/vkd3d/utils.c index 5f67c8b95aac2..9b28068be51fa 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d/utils.c +++ b/dll/directx/wine/vkd3d/libs/vkd3d/utils.c @@ -948,16 +948,11 @@ HRESULT vkd3d_get_private_data(struct vkd3d_private_store *store, const struct vkd3d_private_data *data; HRESULT hr = S_OK; unsigned int size; - int rc; if (!out_size) return E_INVALIDARG; - if ((rc = vkd3d_mutex_lock(&store->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return hresult_from_errno(rc); - } + vkd3d_mutex_lock(&store->mutex); if (!(data = vkd3d_private_store_get_private_data(store, tag))) { @@ -990,13 +985,8 @@ HRESULT vkd3d_set_private_data(struct vkd3d_private_store *store, const GUID *tag, unsigned int data_size, const void *data) { HRESULT hr; - int rc; - if ((rc = vkd3d_mutex_lock(&store->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return hresult_from_errno(rc); - } + vkd3d_mutex_lock(&store->mutex); hr = vkd3d_private_store_set_private_data(store, tag, data, data_size, false); @@ -1009,13 +999,8 @@ HRESULT vkd3d_set_private_data_interface(struct vkd3d_private_store *store, { const void *data = object ? object : (void *)&object; HRESULT hr; - int rc; - if ((rc = vkd3d_mutex_lock(&store->mutex))) - { - ERR("Failed to lock mutex, error %d.\n", rc); - return hresult_from_errno(rc); - } + vkd3d_mutex_lock(&store->mutex); hr = vkd3d_private_store_set_private_data(store, tag, data, sizeof(object), !!object); diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d/vkd3d_main.c b/dll/directx/wine/vkd3d/libs/vkd3d/vkd3d_main.c similarity index 99% rename from dll/directx/wine/d3d12/vkd3d/vkd3d/vkd3d_main.c rename to dll/directx/wine/vkd3d/libs/vkd3d/vkd3d_main.c index 21d998bf94a00..88301fbb313c2 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d/vkd3d_main.c +++ b/dll/directx/wine/vkd3d/libs/vkd3d/vkd3d_main.c @@ -510,3 +510,9 @@ HRESULT vkd3d_serialize_versioned_root_signature(const D3D12_VERSIONED_ROOT_SIGN } return hr; } + +void vkd3d_set_log_callback(PFN_vkd3d_log callback) +{ + vkd3d_shader_set_log_callback(callback); + vkd3d_dbg_set_log_callback(callback); +} diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d/vkd3d_private.h b/dll/directx/wine/vkd3d/libs/vkd3d/vkd3d_private.h similarity index 83% rename from dll/directx/wine/d3d12/vkd3d/vkd3d/vkd3d_private.h rename to dll/directx/wine/vkd3d/libs/vkd3d/vkd3d_private.h index 459b372a1b778..77b795d6278ef 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d/vkd3d_private.h +++ b/dll/directx/wine/vkd3d/libs/vkd3d/vkd3d_private.h @@ -24,10 +24,8 @@ #define VK_NO_PROTOTYPES #ifdef _WIN32 -#ifndef _WIN32_WINNT # define _WIN32_WINNT 0x0600 /* for condition variables */ #endif -#endif #include "vkd3d_common.h" #include "vkd3d_blob.h" @@ -44,13 +42,6 @@ #include #include -/* hmmm.... */ -VkResult vkCreateDebugReportCallbackEXT( - VkInstance instance, - const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, - const VkAllocationCallbacks* pAllocator, - VkDebugReportCallbackEXT* pCallback); - #define VK_CALL(f) (vk_procs->f) #define VKD3D_DESCRIPTOR_MAGIC_HAS_VIEW 0x01000000u @@ -68,6 +59,7 @@ VkResult vkCreateDebugReportCallbackEXT( #define VKD3D_MAX_SHADER_EXTENSIONS 3u #define VKD3D_MAX_SHADER_STAGES 5u #define VKD3D_MAX_VK_SYNC_OBJECTS 4u +#define VKD3D_MAX_DEVICE_BLOCKED_QUEUES 16u #define VKD3D_MAX_DESCRIPTOR_SETS 64u /* D3D12 binding tier 3 has a limit of 2048 samplers. */ #define VKD3D_MAX_DESCRIPTOR_SET_SAMPLERS 2048u @@ -76,6 +68,8 @@ VkResult vkCreateDebugReportCallbackEXT( * this number to prevent excessive pool memory use. */ #define VKD3D_MAX_VIRTUAL_HEAP_DESCRIPTORS_PER_TYPE (16 * 1024u) +extern LONG64 object_global_serial_id; + struct d3d12_command_list; struct d3d12_device; struct d3d12_resource; @@ -132,12 +126,14 @@ struct vkd3d_vulkan_info bool KHR_maintenance3; bool KHR_push_descriptor; bool KHR_sampler_mirror_clamp_to_edge; + bool KHR_timeline_semaphore; /* EXT device extensions */ bool EXT_calibrated_timestamps; bool EXT_conditional_rendering; bool EXT_debug_marker; bool EXT_depth_clip_enable; bool EXT_descriptor_indexing; + bool EXT_robustness2; bool EXT_shader_demote_to_helper_invocation; bool EXT_shader_stencil_export; bool EXT_texel_buffer_alignment; @@ -147,6 +143,8 @@ struct vkd3d_vulkan_info bool rasterization_stream; bool transform_feedback_queries; + bool uav_read_without_format; + bool vertex_attrib_zero_divisor; unsigned int max_vertex_attrib_divisor; @@ -165,6 +163,7 @@ struct vkd3d_vulkan_info enum vkd3d_config_flags { VKD3D_CONFIG_FLAG_VULKAN_DEBUG = 0x00000001, + VKD3D_CONFIG_FLAG_VIRTUAL_HEAPS = 0x00000002, }; struct vkd3d_instance @@ -208,56 +207,49 @@ struct vkd3d_cond CONDITION_VARIABLE cond; }; -static inline int vkd3d_mutex_init(struct vkd3d_mutex *lock) +static inline void vkd3d_mutex_init(struct vkd3d_mutex *lock) { InitializeCriticalSection(&lock->lock); - return 0; } -static inline int vkd3d_mutex_lock(struct vkd3d_mutex *lock) +static inline void vkd3d_mutex_lock(struct vkd3d_mutex *lock) { EnterCriticalSection(&lock->lock); - return 0; } -static inline int vkd3d_mutex_unlock(struct vkd3d_mutex *lock) +static inline void vkd3d_mutex_unlock(struct vkd3d_mutex *lock) { LeaveCriticalSection(&lock->lock); - return 0; } -static inline int vkd3d_mutex_destroy(struct vkd3d_mutex *lock) +static inline void vkd3d_mutex_destroy(struct vkd3d_mutex *lock) { DeleteCriticalSection(&lock->lock); - return 0; } -static inline int vkd3d_cond_init(struct vkd3d_cond *cond) +static inline void vkd3d_cond_init(struct vkd3d_cond *cond) { InitializeConditionVariable(&cond->cond); - return 0; } -static inline int vkd3d_cond_signal(struct vkd3d_cond *cond) +static inline void vkd3d_cond_signal(struct vkd3d_cond *cond) { WakeConditionVariable(&cond->cond); - return 0; } -static inline int vkd3d_cond_broadcast(struct vkd3d_cond *cond) +static inline void vkd3d_cond_broadcast(struct vkd3d_cond *cond) { WakeAllConditionVariable(&cond->cond); - return 0; } -static inline int vkd3d_cond_wait(struct vkd3d_cond *cond, struct vkd3d_mutex *lock) +static inline void vkd3d_cond_wait(struct vkd3d_cond *cond, struct vkd3d_mutex *lock) { - return !SleepConditionVariableCS(&cond->cond, &lock->lock, INFINITE); + if (!SleepConditionVariableCS(&cond->cond, &lock->lock, INFINITE)) + ERR("Could not sleep on the condition variable, error %u.\n", GetLastError()); } -static inline int vkd3d_cond_destroy(struct vkd3d_cond *cond) +static inline void vkd3d_cond_destroy(struct vkd3d_cond *cond) { - return 0; } #else /* _WIN32 */ @@ -281,49 +273,85 @@ struct vkd3d_cond }; -static inline int vkd3d_mutex_init(struct vkd3d_mutex *lock) +static inline void vkd3d_mutex_init(struct vkd3d_mutex *lock) { - return pthread_mutex_init(&lock->lock, NULL); + int ret; + + ret = pthread_mutex_init(&lock->lock, NULL); + if (ret) + ERR("Could not initialize the mutex, error %d.\n", ret); } -static inline int vkd3d_mutex_lock(struct vkd3d_mutex *lock) +static inline void vkd3d_mutex_lock(struct vkd3d_mutex *lock) { - return pthread_mutex_lock(&lock->lock); + int ret; + + ret = pthread_mutex_lock(&lock->lock); + if (ret) + ERR("Could not lock the mutex, error %d.\n", ret); } -static inline int vkd3d_mutex_unlock(struct vkd3d_mutex *lock) +static inline void vkd3d_mutex_unlock(struct vkd3d_mutex *lock) { - return pthread_mutex_unlock(&lock->lock); + int ret; + + ret = pthread_mutex_unlock(&lock->lock); + if (ret) + ERR("Could not unlock the mutex, error %d.\n", ret); } -static inline int vkd3d_mutex_destroy(struct vkd3d_mutex *lock) +static inline void vkd3d_mutex_destroy(struct vkd3d_mutex *lock) { - return pthread_mutex_destroy(&lock->lock); + int ret; + + ret = pthread_mutex_destroy(&lock->lock); + if (ret) + ERR("Could not destroy the mutex, error %d.\n", ret); } -static inline int vkd3d_cond_init(struct vkd3d_cond *cond) +static inline void vkd3d_cond_init(struct vkd3d_cond *cond) { - return pthread_cond_init(&cond->cond, NULL); + int ret; + + ret = pthread_cond_init(&cond->cond, NULL); + if (ret) + ERR("Could not initialize the condition variable, error %d.\n", ret); } -static inline int vkd3d_cond_signal(struct vkd3d_cond *cond) +static inline void vkd3d_cond_signal(struct vkd3d_cond *cond) { - return pthread_cond_signal(&cond->cond); + int ret; + + ret = pthread_cond_signal(&cond->cond); + if (ret) + ERR("Could not signal the condition variable, error %d.\n", ret); } -static inline int vkd3d_cond_broadcast(struct vkd3d_cond *cond) +static inline void vkd3d_cond_broadcast(struct vkd3d_cond *cond) { - return pthread_cond_broadcast(&cond->cond); + int ret; + + ret = pthread_cond_broadcast(&cond->cond); + if (ret) + ERR("Could not broadcast the condition variable, error %d.\n", ret); } -static inline int vkd3d_cond_wait(struct vkd3d_cond *cond, struct vkd3d_mutex *lock) +static inline void vkd3d_cond_wait(struct vkd3d_cond *cond, struct vkd3d_mutex *lock) { - return pthread_cond_wait(&cond->cond, &lock->lock); + int ret; + + ret = pthread_cond_wait(&cond->cond, &lock->lock); + if (ret) + ERR("Could not wait on the condition variable, error %d.\n", ret); } -static inline int vkd3d_cond_destroy(struct vkd3d_cond *cond) +static inline void vkd3d_cond_destroy(struct vkd3d_cond *cond) { - return pthread_cond_destroy(&cond->cond); + int ret; + + ret = pthread_cond_destroy(&cond->cond); + if (ret) + ERR("Could not destroy the condition variable, error %d.\n", ret); } #endif /* _WIN32 */ @@ -336,7 +364,11 @@ struct vkd3d_waiting_fence { struct d3d12_fence *fence; uint64_t value; - struct vkd3d_queue *queue; + union + { + VkFence vk_fence; + VkSemaphore vk_semaphore; + } u; uint64_t queue_sequence_number; }; @@ -345,30 +377,18 @@ struct vkd3d_fence_worker union vkd3d_thread_handle thread; struct vkd3d_mutex mutex; struct vkd3d_cond cond; - struct vkd3d_cond fence_destruction_cond; bool should_exit; - bool pending_fence_destruction; - - LONG enqueued_fence_count; - struct vkd3d_enqueued_fence - { - VkFence vk_fence; - struct vkd3d_waiting_fence waiting_fence; - } *enqueued_fences; - size_t enqueued_fences_size; size_t fence_count; - VkFence *vk_fences; - size_t vk_fences_size; struct vkd3d_waiting_fence *fences; size_t fences_size; + void (*wait_for_gpu_fence)(struct vkd3d_fence_worker *worker, const struct vkd3d_waiting_fence *enqueued_fence); + + struct vkd3d_queue *queue; struct d3d12_device *device; }; -HRESULT vkd3d_fence_worker_start(struct vkd3d_fence_worker *worker, struct d3d12_device *device); -HRESULT vkd3d_fence_worker_stop(struct vkd3d_fence_worker *worker, struct d3d12_device *device); - struct vkd3d_gpu_va_allocation { D3D12_GPU_VIRTUAL_ADDRESS base; @@ -400,30 +420,6 @@ D3D12_GPU_VIRTUAL_ADDRESS vkd3d_gpu_va_allocator_allocate(struct vkd3d_gpu_va_al void *vkd3d_gpu_va_allocator_dereference(struct vkd3d_gpu_va_allocator *allocator, D3D12_GPU_VIRTUAL_ADDRESS address); void vkd3d_gpu_va_allocator_free(struct vkd3d_gpu_va_allocator *allocator, D3D12_GPU_VIRTUAL_ADDRESS address); -struct vkd3d_gpu_descriptor_allocation -{ - const struct d3d12_desc *base; - size_t count; -}; - -struct vkd3d_gpu_descriptor_allocator -{ - struct vkd3d_mutex mutex; - - struct vkd3d_gpu_descriptor_allocation *allocations; - size_t allocations_size; - size_t allocation_count; -}; - -size_t vkd3d_gpu_descriptor_allocator_range_size_from_descriptor( - struct vkd3d_gpu_descriptor_allocator *allocator, const struct d3d12_desc *desc); -bool vkd3d_gpu_descriptor_allocator_register_range(struct vkd3d_gpu_descriptor_allocator *allocator, - const struct d3d12_desc *base, size_t count); -bool vkd3d_gpu_descriptor_allocator_unregister_range( - struct vkd3d_gpu_descriptor_allocator *allocator, const struct d3d12_desc *base); -struct d3d12_descriptor_heap *vkd3d_gpu_descriptor_allocator_heap_from_descriptor( - struct vkd3d_gpu_descriptor_allocator *allocator, const struct d3d12_desc *desc); - struct vkd3d_render_pass_key { unsigned int attachment_count; @@ -480,14 +476,11 @@ static inline void vkd3d_private_data_destroy(struct vkd3d_private_data *data) static inline HRESULT vkd3d_private_store_init(struct vkd3d_private_store *store) { - int rc; - list_init(&store->content); - if ((rc = vkd3d_mutex_init(&store->mutex))) - ERR("Failed to initialize mutex, error %d.\n", rc); + vkd3d_mutex_init(&store->mutex); - return hresult_from_errno(rc); + return S_OK; } static inline void vkd3d_private_store_destroy(struct vkd3d_private_store *store) @@ -509,20 +502,29 @@ HRESULT vkd3d_set_private_data_interface(struct vkd3d_private_store *store, cons struct vkd3d_signaled_semaphore { - struct list entry; uint64_t value; - VkSemaphore vk_semaphore; - VkFence vk_fence; - bool is_acquired; + union + { + struct + { + VkSemaphore vk_semaphore; + VkFence vk_fence; + bool is_acquired; + } binary; + uint64_t timeline_value; + } u; + const struct vkd3d_queue *signalling_queue; }; /* ID3D12Fence */ struct d3d12_fence { ID3D12Fence ID3D12Fence_iface; + LONG internal_refcount; LONG refcount; uint64_t value; + uint64_t max_pending_value; struct vkd3d_mutex mutex; struct vkd3d_cond null_event_cond; @@ -530,15 +532,18 @@ struct d3d12_fence { uint64_t value; HANDLE event; - bool latch; + bool *latch; } *events; size_t events_size; size_t event_count; - struct list semaphores; - unsigned int semaphore_count; + VkSemaphore timeline_semaphore; + uint64_t timeline_value; + uint64_t pending_timeline_value; - LONG pending_worker_operation_count; + struct vkd3d_signaled_semaphore *semaphores; + size_t semaphores_size; + unsigned int semaphore_count; VkFence old_vk_fences[VKD3D_MAX_VK_SYNC_OBJECTS]; @@ -550,6 +555,9 @@ struct d3d12_fence HRESULT d3d12_fence_create(struct d3d12_device *device, uint64_t initial_value, D3D12_FENCE_FLAGS flags, struct d3d12_fence **fence); +VkResult vkd3d_create_timeline_semaphore(const struct d3d12_device *device, uint64_t initial_value, + VkSemaphore *timeline_semaphore); + /* ID3D12Heap */ struct d3d12_heap { @@ -657,6 +665,7 @@ struct vkd3d_view { LONG refcount; enum vkd3d_view_type type; + uint64_t serial_id; union { VkBufferView vk_buffer_view; @@ -703,15 +712,25 @@ bool vkd3d_create_buffer_view(struct d3d12_device *device, VkBuffer vk_buffer, c bool vkd3d_create_texture_view(struct d3d12_device *device, VkImage vk_image, const struct vkd3d_texture_view_desc *desc, struct vkd3d_view **view); +struct vkd3d_view_info +{ + uint64_t written_serial_id; + struct vkd3d_view *view; +}; + struct d3d12_desc { - uint32_t magic; - VkDescriptorType vk_descriptor_type; - union + struct { - VkDescriptorBufferInfo vk_cbv_info; - struct vkd3d_view *view; - } u; + uint32_t magic; + VkDescriptorType vk_descriptor_type; + union + { + VkDescriptorBufferInfo vk_cbv_info; + struct vkd3d_view_info view_info; + } u; + } s; + unsigned int index; }; static inline struct d3d12_desc *d3d12_desc_from_cpu_handle(D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle) @@ -724,6 +743,11 @@ static inline struct d3d12_desc *d3d12_desc_from_gpu_handle(D3D12_GPU_DESCRIPTOR return (struct d3d12_desc *)(intptr_t)gpu_handle.ptr; } +static inline void d3d12_desc_copy_raw(struct d3d12_desc *dst, const struct d3d12_desc *src) +{ + dst->s = src->s; +} + void d3d12_desc_copy(struct d3d12_desc *dst, const struct d3d12_desc *src, struct d3d12_device *device); void d3d12_desc_create_cbv(struct d3d12_desc *descriptor, struct d3d12_device *device, const D3D12_CONSTANT_BUFFER_VIEW_DESC *desc); @@ -781,11 +805,55 @@ static inline struct d3d12_dsv_desc *d3d12_dsv_desc_from_cpu_handle(D3D12_CPU_DE void d3d12_dsv_desc_create_dsv(struct d3d12_dsv_desc *dsv_desc, struct d3d12_device *device, struct d3d12_resource *resource, const D3D12_DEPTH_STENCIL_VIEW_DESC *desc); +enum vkd3d_vk_descriptor_set_index +{ + VKD3D_SET_INDEX_UNIFORM_BUFFER = 0, + VKD3D_SET_INDEX_UNIFORM_TEXEL_BUFFER = 1, + VKD3D_SET_INDEX_SAMPLED_IMAGE = 2, + VKD3D_SET_INDEX_STORAGE_TEXEL_BUFFER = 3, + VKD3D_SET_INDEX_STORAGE_IMAGE = 4, + VKD3D_SET_INDEX_SAMPLER = 5, + VKD3D_SET_INDEX_UAV_COUNTER = 6, + VKD3D_SET_INDEX_COUNT = 7 +}; + +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); + + return vk_descriptor_set_index_table[type]; +} + +struct vkd3d_vk_descriptor_heap_layout +{ + VkDescriptorType type; + bool buffer_dimension; + D3D12_DESCRIPTOR_HEAP_TYPE applicable_heap_type; + unsigned int count; + VkDescriptorSetLayout vk_set_layout; +}; + +#define VKD3D_DESCRIPTOR_WRITE_BUFFER_SIZE 64 + +struct d3d12_descriptor_heap_vk_set +{ + VkDescriptorSet vk_set; + VkDescriptorBufferInfo vk_buffer_infos[VKD3D_DESCRIPTOR_WRITE_BUFFER_SIZE]; + VkBufferView vk_buffer_views[VKD3D_DESCRIPTOR_WRITE_BUFFER_SIZE]; + VkDescriptorImageInfo vk_image_infos[VKD3D_DESCRIPTOR_WRITE_BUFFER_SIZE]; + VkWriteDescriptorSet vk_descriptor_writes[VKD3D_DESCRIPTOR_WRITE_BUFFER_SIZE]; +}; + /* ID3D12DescriptorHeap */ struct d3d12_descriptor_heap { ID3D12DescriptorHeap ID3D12DescriptorHeap_iface; LONG refcount; + uint64_t serial_id; D3D12_DESCRIPTOR_HEAP_DESC desc; @@ -793,12 +861,43 @@ struct d3d12_descriptor_heap struct vkd3d_private_store private_store; + VkDescriptorPool vk_descriptor_pool; + struct d3d12_descriptor_heap_vk_set vk_descriptor_sets[VKD3D_SET_INDEX_COUNT]; + struct vkd3d_mutex vk_sets_mutex; + BYTE descriptors[]; }; +static inline struct d3d12_descriptor_heap *d3d12_desc_get_descriptor_heap(const struct d3d12_desc *descriptor) +{ + return CONTAINING_RECORD(descriptor - descriptor->index, struct d3d12_descriptor_heap, descriptors); +} + +static inline unsigned int d3d12_desc_heap_range_size(const struct d3d12_desc *descriptor) +{ + const struct d3d12_descriptor_heap *heap = d3d12_desc_get_descriptor_heap(descriptor); + return heap->desc.NumDescriptors - descriptor->index; +} + HRESULT d3d12_descriptor_heap_create(struct d3d12_device *device, const D3D12_DESCRIPTOR_HEAP_DESC *desc, struct d3d12_descriptor_heap **descriptor_heap); +struct d3d12_desc_copy_location +{ + struct d3d12_desc src; + struct d3d12_desc *dst; +}; + +struct d3d12_desc_copy_info +{ + unsigned int count; + bool uav_counter; +}; + +void d3d12_desc_copy_vk_heap_range(struct d3d12_desc_copy_location *locations, const struct d3d12_desc_copy_info *info, + struct d3d12_descriptor_heap *descriptor_heap, enum vkd3d_vk_descriptor_set_index set, + struct d3d12_device *device); + /* ID3D12QueryHeap */ struct d3d12_query_heap { @@ -907,8 +1006,13 @@ struct d3d12_root_signature D3D12_ROOT_SIGNATURE_FLAGS flags; unsigned int binding_count; + unsigned int uav_mapping_count; struct vkd3d_shader_resource_binding *descriptor_mapping; struct vkd3d_shader_descriptor_offset *descriptor_offsets; + struct vkd3d_shader_uav_counter_binding *uav_counter_mapping; + struct vkd3d_shader_descriptor_offset *uav_counter_offsets; + unsigned int descriptor_table_offset; + unsigned int descriptor_table_count; unsigned int root_constant_count; struct vkd3d_shader_push_constant_buffer *root_constants; @@ -1127,6 +1231,8 @@ struct vkd3d_pipeline_bindings struct d3d12_desc *descriptor_tables[D3D12_MAX_ROOT_COST]; uint64_t descriptor_table_dirty_mask; uint64_t descriptor_table_active_mask; + uint64_t cbv_srv_uav_heap_id; + uint64_t sampler_heap_id; VkBufferView *vk_uav_counter_views; size_t vk_uav_counter_views_size; @@ -1188,6 +1294,8 @@ struct d3d12_command_list VkBuffer so_counter_buffers[D3D12_SO_BUFFER_SLOT_COUNT]; VkDeviceSize so_counter_buffer_offsets[D3D12_SO_BUFFER_SLOT_COUNT]; + void (*update_descriptors)(struct d3d12_command_list *list, enum vkd3d_pipeline_bind_point bind_point); + struct vkd3d_private_store private_store; }; @@ -1226,6 +1334,49 @@ HRESULT vkd3d_queue_create(struct d3d12_device *device, uint32_t family_index, void vkd3d_queue_destroy(struct vkd3d_queue *queue, struct d3d12_device *device); void vkd3d_queue_release(struct vkd3d_queue *queue); +enum vkd3d_cs_op +{ + VKD3D_CS_OP_WAIT, + VKD3D_CS_OP_SIGNAL, + VKD3D_CS_OP_EXECUTE, +}; + +struct vkd3d_cs_wait +{ + struct d3d12_fence *fence; + uint64_t value; +}; + +struct vkd3d_cs_signal +{ + struct d3d12_fence *fence; + uint64_t value; +}; + +struct vkd3d_cs_execute +{ + VkCommandBuffer *buffers; + unsigned int buffer_count; +}; + +struct vkd3d_cs_op_data +{ + enum vkd3d_cs_op opcode; + union + { + struct vkd3d_cs_wait wait; + struct vkd3d_cs_signal signal; + struct vkd3d_cs_execute execute; + } u; +}; + +struct d3d12_command_queue_op_array +{ + struct vkd3d_cs_op_data *ops; + size_t count; + size_t size; +}; + /* ID3D12CommandQueue */ struct d3d12_command_queue { @@ -1236,11 +1387,23 @@ struct d3d12_command_queue struct vkd3d_queue *vkd3d_queue; + struct vkd3d_fence_worker fence_worker; const struct d3d12_fence *last_waited_fence; uint64_t last_waited_fence_value; struct d3d12_device *device; + struct vkd3d_mutex op_mutex; + + /* These fields are protected by op_mutex. */ + struct d3d12_command_queue_op_array op_queue; + bool is_flushing; + + /* This field is not protected by op_mutex, but can only be used + * by the thread that set is_flushing; when is_flushing is not + * set, aux_op_queue.count must be zero. */ + struct d3d12_command_queue_op_array aux_op_queue; + struct vkd3d_private_store private_store; }; @@ -1336,9 +1499,7 @@ struct d3d12_device PFN_vkd3d_signal_event signal_event; size_t wchar_size; - struct vkd3d_gpu_descriptor_allocator gpu_descriptor_allocator; struct vkd3d_gpu_va_allocator gpu_va_allocator; - struct vkd3d_fence_worker fence_worker; struct vkd3d_mutex mutex; struct vkd3d_mutex desc_mutex[8]; @@ -1363,6 +1524,10 @@ struct d3d12_device unsigned int queue_family_count; VkTimeDomainEXT vk_host_time_domain; + struct vkd3d_mutex blocked_queues_mutex; + struct d3d12_command_queue *blocked_queues[VKD3D_MAX_DEVICE_BLOCKED_QUEUES]; + unsigned int blocked_queue_count; + struct vkd3d_instance *vkd3d_instance; IUnknown *parent; @@ -1379,6 +1544,8 @@ struct d3d12_device struct vkd3d_uav_clear_state uav_clear_state; VkDescriptorPoolSize vk_pool_sizes[VKD3D_DESCRIPTOR_POOL_COUNT]; + struct vkd3d_vk_descriptor_heap_layout vk_descriptor_heap_layouts[VKD3D_SET_INDEX_COUNT]; + bool use_vk_heaps; }; HRESULT d3d12_device_create(struct vkd3d_instance *instance, @@ -1552,15 +1719,6 @@ extern const char vkd3d_build[]; bool vkd3d_get_program_name(char program_name[PATH_MAX]); -static inline void vkd3d_set_thread_name(const char *name) -{ -#if defined(HAVE_PTHREAD_SETNAME_NP_2) - pthread_setname_np(pthread_self(), name); -#elif defined(HAVE_PTHREAD_SETNAME_NP_1) - pthread_setname_np(name); -#endif -} - VkResult vkd3d_set_vk_object_name_utf8(struct d3d12_device *device, uint64_t vk_object, VkDebugReportObjectTypeEXT vk_object_type, const char *name); HRESULT vkd3d_set_vk_object_name(struct d3d12_device *device, uint64_t vk_object, diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d/vkd3d_shaders.h b/dll/directx/wine/vkd3d/libs/vkd3d/vkd3d_shaders.h similarity index 100% rename from dll/directx/wine/d3d12/vkd3d/vkd3d/vkd3d_shaders.h rename to dll/directx/wine/vkd3d/libs/vkd3d/vkd3d_shaders.h diff --git a/dll/directx/wine/d3d12/vkd3d/vkd3d/vulkan_procs.h b/dll/directx/wine/vkd3d/libs/vkd3d/vulkan_procs.h similarity index 97% rename from dll/directx/wine/d3d12/vkd3d/vkd3d/vulkan_procs.h rename to dll/directx/wine/vkd3d/libs/vkd3d/vulkan_procs.h index 827f00e7f2742..34e0ab4be58f2 100644 --- a/dll/directx/wine/d3d12/vkd3d/vkd3d/vulkan_procs.h +++ b/dll/directx/wine/vkd3d/libs/vkd3d/vulkan_procs.h @@ -32,8 +32,6 @@ # define VK_DEVICE_EXT_PFN(x) #endif - - /* Instance functions (obtained by vkGetInstanceProcAddr). */ VK_INSTANCE_PFN(vkDestroyInstance) /* Load vkDestroyInstance() first. */ VK_INSTANCE_PFN(vkCreateDevice) @@ -197,6 +195,11 @@ VK_DEVICE_EXT_PFN(vkGetDescriptorSetLayoutSupportKHR) /* VK_KHR_push_descriptor */ VK_DEVICE_EXT_PFN(vkCmdPushDescriptorSetKHR) +/* VK_KHR_timeline_semaphore */ +VK_DEVICE_EXT_PFN(vkGetSemaphoreCounterValueKHR) +VK_DEVICE_EXT_PFN(vkWaitSemaphoresKHR) +VK_DEVICE_EXT_PFN(vkSignalSemaphoreKHR) + /* VK_EXT_calibrated_timestamps */ VK_DEVICE_EXT_PFN(vkGetCalibratedTimestampsEXT)