From 9c85f8e97acdc7e75177b0d93bfaa669617f9760 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Sat, 27 Jan 2024 12:33:52 +1100 Subject: [PATCH] Updated vkd3d-latest patchset --- ...-3bafee344d8d50172d8da18512ba070c682.patch | 2 +- ...-68b898fcb6b4ab2a9660f35edf3554465ab.patch | 2 +- ...-cd77b2a9be23b9a34d2d6a5cb566ac3873f.patch | 2 +- ...-72e2eeaf146e856497890241213a98327c0.patch | 2 +- ...-bf628f0c74ae839bb20266cd10e07d1504e.patch | 2 +- ...-fd7d23f64bc8c33fe3b59431219e14c0865.patch | 2991 +++++++++++++++++ 6 files changed, 2996 insertions(+), 5 deletions(-) create mode 100644 patches/vkd3d-latest/0006-Updated-vkd3d-to-fd7d23f64bc8c33fe3b59431219e14c0865.patch diff --git a/patches/vkd3d-latest/0001-Updated-vkd3d-to-3bafee344d8d50172d8da18512ba070c682.patch b/patches/vkd3d-latest/0001-Updated-vkd3d-to-3bafee344d8d50172d8da18512ba070c682.patch index 3d4b54f7..a01f12bf 100644 --- a/patches/vkd3d-latest/0001-Updated-vkd3d-to-3bafee344d8d50172d8da18512ba070c682.patch +++ b/patches/vkd3d-latest/0001-Updated-vkd3d-to-3bafee344d8d50172d8da18512ba070c682.patch @@ -1,4 +1,4 @@ -From 0e56d61705e984093a7e54d0ec788e99545011df Mon Sep 17 00:00:00 2001 +From 71470ee302ed26329231d806f2ff18f187f714bc Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 8 Dec 2023 13:21:19 +1100 Subject: [PATCH] Updated vkd3d to 3bafee344d8d50172d8da18512ba070c6826b18d. diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-68b898fcb6b4ab2a9660f35edf3554465ab.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-68b898fcb6b4ab2a9660f35edf3554465ab.patch index 88445291..bf78743f 100644 --- a/patches/vkd3d-latest/0002-Updated-vkd3d-to-68b898fcb6b4ab2a9660f35edf3554465ab.patch +++ b/patches/vkd3d-latest/0002-Updated-vkd3d-to-68b898fcb6b4ab2a9660f35edf3554465ab.patch @@ -1,4 +1,4 @@ -From 9190b1dd7de2cb8c8be10168cab2bfd48339fc90 Mon Sep 17 00:00:00 2001 +From 6a4a01d3b258b8752a7c7ebe07c593a3876b72e2 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 5 Jan 2024 11:03:00 +1100 Subject: [PATCH] Updated vkd3d to 68b898fcb6b4ab2a9660f35edf3554465ab0efbe. diff --git a/patches/vkd3d-latest/0003-Updated-vkd3d-to-cd77b2a9be23b9a34d2d6a5cb566ac3873f.patch b/patches/vkd3d-latest/0003-Updated-vkd3d-to-cd77b2a9be23b9a34d2d6a5cb566ac3873f.patch index 14b94c59..45fe9906 100644 --- a/patches/vkd3d-latest/0003-Updated-vkd3d-to-cd77b2a9be23b9a34d2d6a5cb566ac3873f.patch +++ b/patches/vkd3d-latest/0003-Updated-vkd3d-to-cd77b2a9be23b9a34d2d6a5cb566ac3873f.patch @@ -1,4 +1,4 @@ -From d9449a4da7d77d156bc326b7224cf6d59919f142 Mon Sep 17 00:00:00 2001 +From fe0a784b52130405e5513f5ab20a169f6cae3a6a Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Thu, 18 Jan 2024 11:50:14 +1100 Subject: [PATCH] Updated vkd3d to cd77b2a9be23b9a34d2d6a5cb566ac3873ff29b5. diff --git a/patches/vkd3d-latest/0004-Updated-vkd3d-to-72e2eeaf146e856497890241213a98327c0.patch b/patches/vkd3d-latest/0004-Updated-vkd3d-to-72e2eeaf146e856497890241213a98327c0.patch index 5919f5aa..4cbd11df 100644 --- a/patches/vkd3d-latest/0004-Updated-vkd3d-to-72e2eeaf146e856497890241213a98327c0.patch +++ b/patches/vkd3d-latest/0004-Updated-vkd3d-to-72e2eeaf146e856497890241213a98327c0.patch @@ -1,4 +1,4 @@ -From 44cac4e33e21a03985145b177368bc7872ce9e73 Mon Sep 17 00:00:00 2001 +From 2d21093fb4c3716f6bb02e4021d23e3ead9d381a Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Wed, 24 Jan 2024 08:40:28 +1100 Subject: [PATCH] Updated vkd3d to 72e2eeaf146e856497890241213a98327c098c6d. diff --git a/patches/vkd3d-latest/0005-Updated-vkd3d-to-bf628f0c74ae839bb20266cd10e07d1504e.patch b/patches/vkd3d-latest/0005-Updated-vkd3d-to-bf628f0c74ae839bb20266cd10e07d1504e.patch index 84393093..f4145dcd 100644 --- a/patches/vkd3d-latest/0005-Updated-vkd3d-to-bf628f0c74ae839bb20266cd10e07d1504e.patch +++ b/patches/vkd3d-latest/0005-Updated-vkd3d-to-bf628f0c74ae839bb20266cd10e07d1504e.patch @@ -1,4 +1,4 @@ -From 9384c8b24d08cfdbbb913b8a6b229a8315123af6 Mon Sep 17 00:00:00 2001 +From 9a5b8e1dc86435ee994f9c960ede88767f5da27f Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Wed, 24 Jan 2024 12:27:59 +1100 Subject: [PATCH] Updated vkd3d to bf628f0c74ae839bb20266cd10e07d1504ebc1bf. diff --git a/patches/vkd3d-latest/0006-Updated-vkd3d-to-fd7d23f64bc8c33fe3b59431219e14c0865.patch b/patches/vkd3d-latest/0006-Updated-vkd3d-to-fd7d23f64bc8c33fe3b59431219e14c0865.patch new file mode 100644 index 00000000..3680e2e4 --- /dev/null +++ b/patches/vkd3d-latest/0006-Updated-vkd3d-to-fd7d23f64bc8c33fe3b59431219e14c0865.patch @@ -0,0 +1,2991 @@ +From d0677b700d8fc3f569a3353b788343b3267bd4ed Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Sat, 27 Jan 2024 12:22:22 +1100 +Subject: [PATCH] Updated vkd3d to fd7d23f64bc8c33fe3b59431219e14c0865be37a. + +--- + libs/vkd3d/include/private/list.h | 270 +++++++++++ + libs/vkd3d/include/private/rbtree.h | 378 +++++++++++++++ + libs/vkd3d/include/private/vkd3d_test.h | 432 ++++++++++++++++++ + libs/vkd3d/include/vkd3d_d3d9types.h | 237 ++++++++++ + libs/vkd3d/include/vkd3d_d3dcompiler.h | 93 ++++ + libs/vkd3d/include/vkd3d_d3dcompiler_types.h | 45 ++ + libs/vkd3d/include/vkd3d_shader.h | 1 + + libs/vkd3d/include/vkd3d_utils.h | 126 +++++ + libs/vkd3d/include/vkd3d_windows.h | 289 ++++++++++++ + libs/vkd3d/libs/vkd3d-common/blob.c | 1 + + libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 9 + + libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 20 +- + libs/vkd3d/libs/vkd3d-shader/dxil.c | 45 ++ + libs/vkd3d/libs/vkd3d-shader/ir.c | 138 +++++- + libs/vkd3d/libs/vkd3d-shader/spirv.c | 83 +++- + .../libs/vkd3d-shader/vkd3d_shader_main.c | 28 +- + .../libs/vkd3d-shader/vkd3d_shader_private.h | 9 + + libs/vkd3d/libs/vkd3d/command.c | 48 +- + libs/vkd3d/libs/vkd3d/state.c | 14 +- + libs/vkd3d/libs/vkd3d/vkd3d_main.c | 10 +- + libs/vkd3d/libs/vkd3d/vkd3d_private.h | 12 +- + 21 files changed, 2217 insertions(+), 71 deletions(-) + create mode 100644 libs/vkd3d/include/private/list.h + create mode 100644 libs/vkd3d/include/private/rbtree.h + create mode 100644 libs/vkd3d/include/private/vkd3d_test.h + create mode 100644 libs/vkd3d/include/vkd3d_d3d9types.h + create mode 100644 libs/vkd3d/include/vkd3d_d3dcompiler.h + create mode 100644 libs/vkd3d/include/vkd3d_d3dcompiler_types.h + create mode 100644 libs/vkd3d/include/vkd3d_utils.h + create mode 100644 libs/vkd3d/include/vkd3d_windows.h + +diff --git a/libs/vkd3d/include/private/list.h b/libs/vkd3d/include/private/list.h +new file mode 100644 +index 00000000000..2e1d95f3fd4 +--- /dev/null ++++ b/libs/vkd3d/include/private/list.h +@@ -0,0 +1,270 @@ ++/* ++ * 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 before the specified element */ ++static inline void list_move_before( 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 after the specified element */ ++static inline void list_move_after( 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); ++} ++ ++/* move all elements from src to the head of dst */ ++static inline void list_move_head( struct list *dst, struct list *src ) ++{ ++ list_move_after( dst, src ); ++} ++ ++/* move all elements from src to the tail of dst */ ++static inline void list_move_tail( struct list *dst, struct list *src ) ++{ ++ list_move_before( dst, src ); ++} ++ ++/* move the slice of elements from begin to end inclusive to the head of dst */ ++static inline void list_move_slice_head( struct list *dst, struct list *begin, struct list *end ) ++{ ++ struct list *dst_next = dst->next; ++ begin->prev->next = end->next; ++ end->next->prev = begin->prev; ++ dst->next = begin; ++ dst_next->prev = end; ++ begin->prev = dst; ++ end->next = dst_next; ++} ++ ++/* move the slice of elements from begin to end inclusive to the tail of dst */ ++static inline void list_move_slice_tail( struct list *dst, struct list *begin, struct list *end ) ++{ ++ struct list *dst_prev = dst->prev; ++ begin->prev->next = end->next; ++ end->next->prev = begin->prev; ++ dst_prev->next = begin; ++ dst->prev = end; ++ begin->prev = dst_prev; ++ end->next = dst; ++} ++ ++/* 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/libs/vkd3d/include/private/rbtree.h b/libs/vkd3d/include/private/rbtree.h +new file mode 100644 +index 00000000000..b5d38bca54c +--- /dev/null ++++ b/libs/vkd3d/include/private/rbtree.h +@@ -0,0 +1,378 @@ ++/* ++ * 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/libs/vkd3d/include/private/vkd3d_test.h b/libs/vkd3d/include/private/vkd3d_test.h +new file mode 100644 +index 00000000000..081443c4fa6 +--- /dev/null ++++ b/libs/vkd3d/include/private/vkd3d_test.h +@@ -0,0 +1,432 @@ ++/* ++ * 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[8][128]; ++ unsigned int context_count; ++}; ++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_printf(unsigned int line, const char *msg) ++{ ++ unsigned int i; ++ ++ printf("%s:%u: ", vkd3d_test_name, line); ++ for (i = 0; i < vkd3d_test_state.context_count; ++i) ++ printf("%s: ", vkd3d_test_state.context[i]); ++ printf("%s", msg); ++} ++ ++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) ++ vkd3d_test_printf(line, "Test succeeded.\n"); ++ } ++ else ++ { ++ InterlockedIncrement(&vkd3d_test_state.failure_count); ++ vkd3d_test_printf(line, "Test failed: "); ++ 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) ++ vkd3d_test_printf(line, "Fixed bug: "); ++ else ++ vkd3d_test_printf(line, "Bug: "); ++ vprintf(fmt, args); ++ } ++ else if (is_todo) ++ { ++ if (result) ++ { ++ InterlockedIncrement(&vkd3d_test_state.todo_success_count); ++ vkd3d_test_printf(line, "Todo succeeded: "); ++ } ++ else ++ { ++ InterlockedIncrement(&vkd3d_test_state.todo_count); ++ vkd3d_test_printf(line, "Todo: "); ++ } ++ 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); ++ vkd3d_test_printf(line, "Test skipped: "); ++ 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); ++ vkd3d_test_printf(line, ""); ++ 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_push_context(const char *fmt, ...) ++{ ++ va_list args; ++ ++ if (vkd3d_test_state.context_count < ARRAY_SIZE(vkd3d_test_state.context)) ++ { ++ va_start(args, fmt); ++ vsnprintf(vkd3d_test_state.context[vkd3d_test_state.context_count], ++ sizeof(vkd3d_test_state.context), fmt, args); ++ va_end(args); ++ vkd3d_test_state.context[vkd3d_test_state.context_count][sizeof(vkd3d_test_state.context[0]) - 1] = '\0'; ++ } ++ ++vkd3d_test_state.context_count; ++} ++ ++static inline void vkd3d_test_pop_context(void) ++{ ++ if (vkd3d_test_state.context_count) ++ --vkd3d_test_state.context_count; ++} ++ ++#define run_test(test_pfn) \ ++ vkd3d_run_test(#test_pfn, test_pfn) ++ ++#endif /* __VKD3D_TEST_H */ +diff --git a/libs/vkd3d/include/vkd3d_d3d9types.h b/libs/vkd3d/include/vkd3d_d3d9types.h +new file mode 100644 +index 00000000000..75d0461409d +--- /dev/null ++++ b/libs/vkd3d/include/vkd3d_d3d9types.h +@@ -0,0 +1,237 @@ ++/* ++ * 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/libs/vkd3d/include/vkd3d_d3dcompiler.h b/libs/vkd3d/include/vkd3d_d3dcompiler.h +new file mode 100644 +index 00000000000..1975f4f980a +--- /dev/null ++++ b/libs/vkd3d/include/vkd3d_d3dcompiler.h +@@ -0,0 +1,93 @@ ++/* ++ * 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__ ++ ++#include ++ ++#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 ++ ++typedef enum D3DCOMPILER_STRIP_FLAGS ++{ ++ D3DCOMPILER_STRIP_REFLECTION_DATA = 0x00000001, ++ D3DCOMPILER_STRIP_DEBUG_INFO = 0x00000002, ++ D3DCOMPILER_STRIP_TEST_BLOBS = 0x00000004, ++ D3DCOMPILER_STRIP_PRIVATE_DATA = 0x00000008, ++ D3DCOMPILER_STRIP_ROOT_SIGNATURE = 0x00000010, ++ D3DCOMPILER_STRIP_FORCE_DWORD = 0x7fffffff, ++} D3DCOMPILER_STRIP_FLAGS; ++ ++HRESULT WINAPI D3DCompile(const void *data, SIZE_T data_size, const char *filename, ++ const D3D_SHADER_MACRO *macros, ID3DInclude *include, const char *entrypoint, ++ const char *profile, UINT flags, UINT effect_flags, ID3DBlob **shader, ID3DBlob **error_messages); ++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 D3DGetBlobPart(const void *data, SIZE_T data_size, D3D_BLOB_PART part, UINT flags, ID3DBlob **blob); ++HRESULT WINAPI D3DGetDebugInfo(const void *data, SIZE_T data_size, ID3DBlob **blob); ++HRESULT WINAPI D3DGetInputAndOutputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob); ++HRESULT WINAPI D3DGetInputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob); ++HRESULT WINAPI D3DGetOutputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob); ++HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, const char *filename, const D3D_SHADER_MACRO *macros, ++ ID3DInclude *include, ID3DBlob **shader, ID3DBlob **error_messages); ++HRESULT WINAPI D3DReflect(const void *data, SIZE_T data_size, REFIID iid, void **reflection); ++HRESULT WINAPI D3DStripShader(const void *data, SIZE_T data_size, UINT flags, ID3DBlob **blob); ++ ++#endif /* __D3DCOMPILER_H__ */ ++#endif /* __VKD3D_D3DCOMPILER_H */ +diff --git a/libs/vkd3d/include/vkd3d_d3dcompiler_types.h b/libs/vkd3d/include/vkd3d_d3dcompiler_types.h +new file mode 100644 +index 00000000000..b3a47cdd912 +--- /dev/null ++++ b/libs/vkd3d/include/vkd3d_d3dcompiler_types.h +@@ -0,0 +1,45 @@ ++/* ++ * 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_TYPES_H ++#define __VKD3D_D3DCOMPILER_TYPES_H ++#ifndef __D3DCOMPILER_H__ ++ ++typedef enum D3D_BLOB_PART ++{ ++ D3D_BLOB_INPUT_SIGNATURE_BLOB, ++ D3D_BLOB_OUTPUT_SIGNATURE_BLOB, ++ D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB, ++ D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB, ++ D3D_BLOB_ALL_SIGNATURE_BLOB, ++ D3D_BLOB_DEBUG_INFO, ++ D3D_BLOB_LEGACY_SHADER, ++ D3D_BLOB_XNA_PREPASS_SHADER, ++ D3D_BLOB_XNA_SHADER, ++ D3D_BLOB_PDB, ++ D3D_BLOB_PRIVATE_DATA, ++ D3D_BLOB_ROOT_SIGNATURE, ++ D3D_BLOB_DEBUG_NAME, ++ D3D_BLOB_TEST_ALTERNATE_SHADER = 0x8000, ++ D3D_BLOB_TEST_COMPILE_DETAILS, ++ D3D_BLOB_TEST_COMPILE_PERF, ++ D3D_BLOB_TEST_COMPILE_REPORT ++} D3D_BLOB_PART; ++ ++#endif /* __D3DCOMPILER_H__ */ ++#endif /* __VKD3D_D3DCOMPILER_TYPES_H */ +diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h +index 449b3684a10..a8cc3a336a3 100644 +--- a/libs/vkd3d/include/vkd3d_shader.h ++++ b/libs/vkd3d/include/vkd3d_shader.h +@@ -200,6 +200,7 @@ enum vkd3d_shader_compile_option_fragment_coordinate_origin + enum vkd3d_shader_compile_option_feature_flags + { + VKD3D_SHADER_COMPILE_OPTION_FEATURE_INT64 = 0x00000001, ++ VKD3D_SHADER_COMPILE_OPTION_FEATURE_FLOAT64 = 0x00000002, + + VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_FEATURE_FLAGS), + }; +diff --git a/libs/vkd3d/include/vkd3d_utils.h b/libs/vkd3d/include/vkd3d_utils.h +new file mode 100644 +index 00000000000..adcac5fcf64 +--- /dev/null ++++ b/libs/vkd3d/include/vkd3d_utils.h +@@ -0,0 +1,126 @@ ++/* ++ * 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 ++#include ++ ++#ifndef VKD3D_UTILS_API_VERSION ++#define VKD3D_UTILS_API_VERSION VKD3D_API_VERSION_1_0 ++#endif ++ ++#ifdef __cplusplus ++extern "C" { ++#endif /* __cplusplus */ ++ ++/** ++ * \file vkd3d_utils.h ++ * ++ * This file contains definitions for the vkd3d-utils library. ++ * ++ * The vkd3d-utils library is a collections of routines to ease the ++ * porting of a Direct3D 12 application to vkd3d. ++ * ++ * \since 1.0 ++ */ ++ ++#define VKD3D_WAIT_OBJECT_0 (0) ++#define VKD3D_WAIT_TIMEOUT (1) ++#define VKD3D_WAIT_FAILED (~0u) ++#define VKD3D_INFINITE (~0u) ++ ++#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); ++ ++/** ++ * Set a callback to be called when vkd3d-utils outputs debug logging. ++ * ++ * If NULL, or if this function has not been called, libvkd3d-utils will print ++ * all enabled log output to stderr. ++ * ++ * Calling this function will also set the log callback for libvkd3d and ++ * libvkd3d-shader. ++ * ++ * \param callback Callback function to set. ++ * ++ * \since 1.4 ++ */ ++VKD3D_UTILS_API void vkd3d_utils_set_log_callback(PFN_vkd3d_log callback); ++ ++/** \since 1.10 */ ++VKD3D_UTILS_API HRESULT WINAPI D3DGetBlobPart(const void *data, ++ SIZE_T data_size, D3D_BLOB_PART part, UINT flags, ID3DBlob **blob); ++/** \since 1.10 */ ++VKD3D_UTILS_API HRESULT WINAPI D3DGetDebugInfo(const void *data, SIZE_T data_size, ID3DBlob **blob); ++/** \since 1.10 */ ++VKD3D_UTILS_API HRESULT WINAPI D3DGetInputAndOutputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob); ++/** \since 1.10 */ ++VKD3D_UTILS_API HRESULT WINAPI D3DGetInputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob); ++/** \since 1.10 */ ++VKD3D_UTILS_API HRESULT WINAPI D3DGetOutputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob); ++/** \since 1.10 */ ++VKD3D_UTILS_API HRESULT WINAPI D3DStripShader(const void *data, SIZE_T data_size, UINT flags, ID3DBlob **blob); ++ ++/** \since 1.11 */ ++VKD3D_UTILS_API HRESULT WINAPI D3DReflect(const void *data, SIZE_T data_size, REFIID iid, void **reflection); ++ ++#ifdef __cplusplus ++} ++#endif /* __cplusplus */ ++ ++#endif /* __VKD3D_UTILS_H */ +diff --git a/libs/vkd3d/include/vkd3d_windows.h b/libs/vkd3d/include/vkd3d_windows.h +new file mode 100644 +index 00000000000..7b0e972d828 +--- /dev/null ++++ b/libs/vkd3d/include/vkd3d_windows.h +@@ -0,0 +1,289 @@ ++/* ++ * 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 DXGI_ERROR_UNSUPPORTED _HRESULT_TYPEDEF_(0x887a0004) ++ ++# 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 INT64 LONG64; ++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; ++typedef GUID CLSID; ++typedef GUID UUID; ++ ++# 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 & ++# define REFCLSID const CLSID & ++# else ++# define REFIID const IID * const ++# define REFGUID const GUID * const ++# define REFCLSID const CLSID * 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/libs/vkd3d/libs/vkd3d-common/blob.c b/libs/vkd3d/libs/vkd3d-common/blob.c +index 4d347acef05..dbb26de7d73 100644 +--- a/libs/vkd3d/libs/vkd3d-common/blob.c ++++ b/libs/vkd3d/libs/vkd3d-common/blob.c +@@ -23,6 +23,7 @@ + #include "vkd3d_blob.h" + #include "vkd3d_debug.h" + #include "vkd3d_memory.h" ++#include "d3d12shader.h" + + struct vkd3d_blob + { +diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +index d9751945d8a..af939396a08 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c ++++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +@@ -198,8 +198,11 @@ static const char * const shader_opcode_names[] = + [VKD3DSIH_IMUL ] = "imul", + [VKD3DSIH_INE ] = "ine", + [VKD3DSIH_INEG ] = "ineg", ++ [VKD3DSIH_ISFINITE ] = "isfinite", + [VKD3DSIH_ISHL ] = "ishl", + [VKD3DSIH_ISHR ] = "ishr", ++ [VKD3DSIH_ISINF ] = "isinf", ++ [VKD3DSIH_ISNAN ] = "isnan", + [VKD3DSIH_ITOD ] = "itod", + [VKD3DSIH_ITOF ] = "itof", + [VKD3DSIH_ITOI ] = "itoi", +@@ -282,6 +285,7 @@ static const char * const shader_opcode_names[] = + [VKD3DSIH_SWITCH ] = "switch", + [VKD3DSIH_SWITCH_MONOLITHIC ] = "switch", + [VKD3DSIH_SYNC ] = "sync", ++ [VKD3DSIH_TAN ] = "tan", + [VKD3DSIH_TEX ] = "texld", + [VKD3DSIH_TEXBEM ] = "texbem", + [VKD3DSIH_TEXBEML ] = "texbeml", +@@ -442,6 +446,11 @@ static void shader_dump_sync_flags(struct vkd3d_d3d_asm_compiler *compiler, uint + vkd3d_string_buffer_printf(&compiler->buffer, "_uglobal"); + sync_flags &= ~VKD3DSSF_GLOBAL_UAV; + } ++ if (sync_flags & VKD3DSSF_THREAD_GROUP_UAV) ++ { ++ vkd3d_string_buffer_printf(&compiler->buffer, "_ugroup"); ++ sync_flags &= ~VKD3DSSF_THREAD_GROUP_UAV; ++ } + if (sync_flags & VKD3DSSF_GROUP_SHARED_MEMORY) + { + vkd3d_string_buffer_printf(&compiler->buffer, "_g"); +diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +index 035095d5b48..4ba001ea4cd 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c ++++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +@@ -2345,8 +2345,6 @@ static void write_sm1_resource_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_ + + sm1_instr = (struct sm1_instruction) + { +- .opcode = D3DSIO_TEX, +- + .dst.type = D3DSPR_TEMP, + .dst.reg = instr->reg.id, + .dst.writemask = instr->reg.writemask, +@@ -2362,8 +2360,22 @@ static void write_sm1_resource_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_ + + .src_count = 2, + }; +- if (load->load_type == HLSL_RESOURCE_SAMPLE_PROJ) +- sm1_instr.opcode |= VKD3DSI_TEXLD_PROJECT << VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT; ++ ++ switch (load->load_type) ++ { ++ case HLSL_RESOURCE_SAMPLE: ++ sm1_instr.opcode = D3DSIO_TEX; ++ break; ++ ++ case HLSL_RESOURCE_SAMPLE_PROJ: ++ sm1_instr.opcode = D3DSIO_TEX; ++ sm1_instr.opcode |= VKD3DSI_TEXLD_PROJECT << VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT; ++ break; ++ ++ default: ++ hlsl_fixme(ctx, &instr->loc, "Resource load type %u\n", load->load_type); ++ return; ++ } + + assert(instr->reg.allocated); + +diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c +index 2a0ff61cfeb..8a31d03c531 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c ++++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c +@@ -328,6 +328,12 @@ enum dx_intrinsic_opcode + { + DX_LOAD_INPUT = 4, + DX_STORE_OUTPUT = 5, ++ DX_ISNAN = 8, ++ DX_ISINF = 9, ++ DX_ISFINITE = 10, ++ DX_COS = 12, ++ DX_SIN = 13, ++ DX_TAN = 14, + DX_EXP = 21, + DX_FRC = 22, + DX_LOG = 23, +@@ -3494,6 +3500,14 @@ static enum vkd3d_shader_opcode map_dx_unary_op(enum dx_intrinsic_opcode op) + { + switch (op) + { ++ case DX_ISNAN: ++ return VKD3DSIH_ISNAN; ++ case DX_ISINF: ++ return VKD3DSIH_ISINF; ++ case DX_ISFINITE: ++ return VKD3DSIH_ISFINITE; ++ case DX_TAN: ++ return VKD3DSIH_TAN; + case DX_EXP: + return VKD3DSIH_EXP; + case DX_FRC: +@@ -3743,6 +3757,28 @@ static void sm6_parser_emit_dx_buffer_load(struct sm6_parser *sm6, enum dx_intri + instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6); + } + ++static void sm6_parser_emit_dx_sincos(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, ++ const struct sm6_value **operands, struct function_emission_state *state) ++{ ++ struct sm6_value *dst = sm6_parser_get_current_value(sm6); ++ struct vkd3d_shader_instruction *ins = state->ins; ++ struct vkd3d_shader_dst_param *dst_params; ++ struct vkd3d_shader_src_param *src_param; ++ unsigned int index; ++ ++ vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SINCOS); ++ src_param = instruction_src_params_alloc(ins, 1, sm6); ++ src_param_init_from_value(src_param, operands[0]); ++ ++ index = op == DX_COS; ++ dst_params = instruction_dst_params_alloc(ins, 2, sm6); ++ dst_param_init(&dst_params[0]); ++ dst_param_init(&dst_params[1]); ++ register_init_ssa_scalar(&dst_params[index].reg, dst->type, sm6); ++ vsir_register_init(&dst_params[index ^ 1].reg, VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); ++ dst->u.reg = dst_params[index].reg; ++} ++ + static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) + { +@@ -3806,6 +3842,7 @@ struct sm6_dx_opcode_info + }; + + /* ++ 1 -> int1 + 8 -> int8 + b -> constant int1 + c -> constant int8/16/32 +@@ -3824,6 +3861,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = + [DX_BFREV ] = {"m", "R", sm6_parser_emit_dx_unary}, + [DX_BUFFER_LOAD ] = {"o", "Hii", sm6_parser_emit_dx_buffer_load}, + [DX_CBUFFER_LOAD_LEGACY ] = {"o", "Hi", sm6_parser_emit_dx_cbuffer_load}, ++ [DX_COS ] = {"g", "R", sm6_parser_emit_dx_sincos}, + [DX_COUNT_BITS ] = {"i", "m", sm6_parser_emit_dx_unary}, + [DX_CREATE_HANDLE ] = {"H", "ccib", sm6_parser_emit_dx_create_handle}, + [DX_DERIV_COARSEX ] = {"e", "R", sm6_parser_emit_dx_unary}, +@@ -3839,6 +3877,9 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = + [DX_FRC ] = {"g", "R", sm6_parser_emit_dx_unary}, + [DX_IMAX ] = {"m", "RR", sm6_parser_emit_dx_binary}, + [DX_IMIN ] = {"m", "RR", sm6_parser_emit_dx_binary}, ++ [DX_ISFINITE ] = {"1", "g", sm6_parser_emit_dx_unary}, ++ [DX_ISINF ] = {"1", "g", sm6_parser_emit_dx_unary}, ++ [DX_ISNAN ] = {"1", "g", sm6_parser_emit_dx_unary}, + [DX_LEGACY_F16TOF32 ] = {"f", "i", sm6_parser_emit_dx_unary}, + [DX_LEGACY_F32TOF16 ] = {"i", "f", sm6_parser_emit_dx_unary}, + [DX_LOAD_INPUT ] = {"o", "ii8i", sm6_parser_emit_dx_load_input}, +@@ -3848,8 +3889,10 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = + [DX_ROUND_PI ] = {"g", "R", sm6_parser_emit_dx_unary}, + [DX_ROUND_Z ] = {"g", "R", sm6_parser_emit_dx_unary}, + [DX_RSQRT ] = {"g", "R", sm6_parser_emit_dx_unary}, ++ [DX_SIN ] = {"g", "R", sm6_parser_emit_dx_sincos}, + [DX_SQRT ] = {"g", "R", sm6_parser_emit_dx_unary}, + [DX_STORE_OUTPUT ] = {"v", "ii8o", sm6_parser_emit_dx_store_output}, ++ [DX_TAN ] = {"g", "R", sm6_parser_emit_dx_unary}, + [DX_UMAX ] = {"m", "RR", sm6_parser_emit_dx_binary}, + [DX_UMIN ] = {"m", "RR", sm6_parser_emit_dx_binary}, + }; +@@ -3867,6 +3910,8 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc + case 0: + FIXME("Invalid operand count.\n"); + return false; ++ case '1': ++ return sm6_type_is_bool(type); + case '8': + return sm6_type_is_i8(type); + case 'b': +diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c +index 865a292cd62..9079be48b4f 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/ir.c ++++ b/libs/vkd3d/libs/vkd3d-shader/ir.c +@@ -39,10 +39,11 @@ static inline bool shader_register_is_phase_instance_id(const struct vkd3d_shade + return reg->type == VKD3DSPR_FORKINSTID || reg->type == VKD3DSPR_JOININSTID; + } + +-static bool shader_instruction_is_dcl(const struct vkd3d_shader_instruction *ins) ++static bool vsir_instruction_is_dcl(const struct vkd3d_shader_instruction *instruction) + { +- return (VKD3DSIH_DCL <= ins->handler_idx && ins->handler_idx <= VKD3DSIH_DCL_VERTICES_OUT) +- || ins->handler_idx == VKD3DSIH_HS_DECLS; ++ enum vkd3d_shader_opcode handler_idx = instruction->handler_idx; ++ return (VKD3DSIH_DCL <= handler_idx && handler_idx <= VKD3DSIH_DCL_VERTICES_OUT) ++ || handler_idx == VKD3DSIH_HS_DECLS; + } + + static void vkd3d_shader_instruction_make_nop(struct vkd3d_shader_instruction *ins) +@@ -65,6 +66,116 @@ static void remove_dcl_temps(struct vsir_program *program) + } + } + ++static bool vsir_instruction_init_with_params(struct vkd3d_shader_parser *parser, ++ struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location, ++ enum vkd3d_shader_opcode handler_idx, unsigned int dst_count, unsigned int src_count) ++{ ++ vsir_instruction_init(ins, location, handler_idx); ++ ins->dst_count = dst_count; ++ ins->src_count = src_count; ++ ++ if (!(ins->dst = shader_parser_get_dst_params(parser, ins->dst_count))) ++ { ++ ERR("Failed to allocate %u destination parameters.\n", dst_count); ++ return false; ++ } ++ ++ if (!(ins->src = shader_parser_get_src_params(parser, ins->src_count))) ++ { ++ ERR("Failed to allocate %u source parameters.\n", src_count); ++ return false; ++ } ++ ++ memset(ins->dst, 0, sizeof(*ins->dst) * ins->dst_count); ++ memset(ins->src, 0, sizeof(*ins->src) * ins->src_count); ++ return true; ++} ++ ++static enum vkd3d_result instruction_array_lower_texkills(struct vkd3d_shader_parser *parser) ++{ ++ struct vsir_program *program = &parser->program; ++ struct vkd3d_shader_instruction_array *instructions = &program->instructions; ++ struct vkd3d_shader_instruction *texkill_ins, *ins; ++ unsigned int components_read = 3 + (program->shader_version.major >= 2); ++ unsigned int tmp_idx = ~0u; ++ unsigned int i, k; ++ ++ for (i = 0; i < instructions->count; ++i) ++ { ++ texkill_ins = &instructions->elements[i]; ++ ++ if (texkill_ins->handler_idx != VKD3DSIH_TEXKILL) ++ continue; ++ ++ if (!shader_instruction_array_insert_at(instructions, i + 1, components_read + 1)) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ ++ if (tmp_idx == ~0u) ++ tmp_idx = program->temp_count++; ++ ++ /* tmp = ins->dst[0] < 0 */ ++ ++ ins = &instructions->elements[i + 1]; ++ if (!vsir_instruction_init_with_params(parser, ins, &texkill_ins->location, VKD3DSIH_LTO, 1, 2)) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ ++ vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); ++ ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; ++ ins->dst[0].reg.idx[0].offset = tmp_idx; ++ ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL; ++ ++ ins->src[0].reg = texkill_ins->dst[0].reg; ++ vsir_register_init(&ins->src[1].reg, VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0); ++ ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; ++ ins->src[1].reg.u.immconst_f32[0] = 0.0f; ++ ins->src[1].reg.u.immconst_f32[1] = 0.0f; ++ ins->src[1].reg.u.immconst_f32[2] = 0.0f; ++ ins->src[1].reg.u.immconst_f32[3] = 0.0f; ++ ++ /* tmp.x = tmp.x || tmp.y */ ++ /* tmp.x = tmp.x || tmp.z */ ++ /* tmp.x = tmp.x || tmp.w, if sm >= 2.0 */ ++ ++ for (k = 1; k < components_read; ++k) ++ { ++ ins = &instructions->elements[i + 1 + k]; ++ if (!(vsir_instruction_init_with_params(parser, ins, &texkill_ins->location, VKD3DSIH_OR, 1, 2))) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ ++ vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); ++ ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; ++ ins->dst[0].reg.idx[0].offset = tmp_idx; ++ ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0; ++ ++ vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); ++ ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; ++ ins->src[0].reg.idx[0].offset = tmp_idx; ++ ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); ++ vsir_register_init(&ins->src[1].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); ++ ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; ++ ins->src[1].reg.idx[0].offset = tmp_idx; ++ ins->src[1].swizzle = vkd3d_shader_create_swizzle(k, k, k, k); ++ } ++ ++ /* discard_nz tmp.x */ ++ ++ ins = &instructions->elements[i + 1 + components_read]; ++ if (!(vsir_instruction_init_with_params(parser, ins, &texkill_ins->location, VKD3DSIH_DISCARD, 0, 1))) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ ins->flags = VKD3D_SHADER_CONDITIONAL_OP_NZ; ++ ++ vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); ++ ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; ++ ins->src[0].reg.idx[0].offset = tmp_idx; ++ ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); ++ ++ /* Make the original instruction no-op */ ++ vkd3d_shader_instruction_make_nop(texkill_ins); ++ } ++ ++ return VKD3D_OK; ++} ++ + static void shader_register_eliminate_phase_addressing(struct vkd3d_shader_register *reg, + unsigned int instance_id) + { +@@ -230,7 +341,7 @@ static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normal + return; + } + +- if (normaliser->phase == VKD3DSIH_INVALID || shader_instruction_is_dcl(ins)) ++ if (normaliser->phase == VKD3DSIH_INVALID || vsir_instruction_is_dcl(ins)) + return; + + if (normaliser->phase_body_idx == ~0u) +@@ -529,7 +640,7 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i + normaliser.phase = ins->handler_idx; + break; + default: +- if (shader_instruction_is_dcl(ins)) ++ if (vsir_instruction_is_dcl(ins)) + break; + for (j = 0; j < ins->dst_count; ++j) + shader_dst_param_normalise_outpointid(&ins->dst[j], &normaliser); +@@ -1222,7 +1333,7 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi + memset(normaliser->pc_dcl_params, 0, sizeof(normaliser->pc_dcl_params)); + break; + default: +- if (shader_instruction_is_dcl(ins)) ++ if (vsir_instruction_is_dcl(ins)) + break; + for (i = 0; i < ins->dst_count; ++i) + shader_dst_param_io_normalise(&ins->dst[i], false, normaliser); +@@ -1862,13 +1973,6 @@ static void VKD3D_PRINTF_FUNC(3, 4) cf_flattener_create_block_name(struct cf_fla + flattener->block_names[block_id] = buffer.buffer; + } + +-static bool vsir_instruction_is_dcl(const struct vkd3d_shader_instruction *instruction) +-{ +- enum vkd3d_shader_opcode handler_idx = instruction->handler_idx; +- return (VKD3DSIH_DCL <= handler_idx && handler_idx <= VKD3DSIH_DCL_VERTICES_OUT) +- || handler_idx == VKD3DSIH_HS_DECLS; +-} +- + static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flattener *flattener) + { + bool main_block_open, is_hull_shader, after_declarations_section; +@@ -2239,7 +2343,7 @@ static enum vkd3d_result flatten_control_flow_constructs(struct vkd3d_shader_par + } + + vkd3d_free(flattener.control_flow_info); +- /* Simpler to always free these in free_shader_desc(). */ ++ /* Simpler to always free these in vsir_program_cleanup(). */ + program->block_names = flattener.block_names; + program->block_name_count = flattener.block_name_count; + +@@ -2254,6 +2358,9 @@ enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser, + + remove_dcl_temps(&parser->program); + ++ if ((result = instruction_array_lower_texkills(parser)) < 0) ++ return result; ++ + if (!parser->shader_desc.is_dxil) + { + if (parser->program.shader_version.type != VKD3D_SHADER_TYPE_PIXEL) +@@ -2791,8 +2898,7 @@ static void vsir_validate_instruction(struct validation_context *ctx) + * purely structured. In principle we could allow structured + * constructs in a block, provided they are confined in a single + * block, but need for that hasn't arisen yet, so we don't. */ +- if (ctx->cf_type == CF_TYPE_UNKNOWN && !(instruction->handler_idx >= VKD3DSIH_DCL +- && instruction->handler_idx <= VKD3DSIH_DCL_VERTICES_OUT)) ++ if (ctx->cf_type == CF_TYPE_UNKNOWN && !vsir_instruction_is_dcl(instruction)) + { + if (instruction->handler_idx == VKD3DSIH_LABEL) + ctx->cf_type = CF_TYPE_BLOCKS; +diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c +index 3b2e45829fd..a86ca583e63 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c ++++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c +@@ -1515,6 +1515,25 @@ static uint32_t vkd3d_spirv_build_op_uless_than_equal(struct vkd3d_spirv_builder + SpvOpULessThanEqual, result_type, operand0, operand1); + } + ++static uint32_t vkd3d_spirv_build_op_is_inf(struct vkd3d_spirv_builder *builder, ++ uint32_t result_type, uint32_t operand) ++{ ++ return vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, SpvOpIsInf, result_type, operand); ++} ++ ++static uint32_t vkd3d_spirv_build_op_is_nan(struct vkd3d_spirv_builder *builder, ++ uint32_t result_type, uint32_t operand) ++{ ++ return vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, SpvOpIsNan, result_type, operand); ++} ++ ++static uint32_t vkd3d_spirv_build_op_logical_equal(struct vkd3d_spirv_builder *builder, ++ uint32_t result_type, uint32_t operand0, uint32_t operand1) ++{ ++ return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, ++ SpvOpLogicalEqual, result_type, operand0, operand1); ++} ++ + static uint32_t vkd3d_spirv_build_op_convert_utof(struct vkd3d_spirv_builder *builder, + uint32_t result_type, uint32_t unsigned_value) + { +@@ -2350,6 +2369,7 @@ struct spirv_compiler + size_t spec_constants_size; + enum vkd3d_shader_compile_option_formatting_flags formatting; + enum vkd3d_shader_compile_option_feature_flags features; ++ enum vkd3d_shader_api_version api_version; + bool write_tess_geom_point_size; + + struct vkd3d_string_buffer_cache string_buffers; +@@ -2494,6 +2514,7 @@ static struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_ve + break; + + case VKD3D_SHADER_COMPILE_OPTION_API_VERSION: ++ compiler->api_version = option->value; + break; + + case VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV: +@@ -2528,6 +2549,10 @@ static struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_ve + } + } + ++ /* Explicit enabling of float64 was not required for API versions <= 1.10. */ ++ if (compiler->api_version <= VKD3D_SHADER_API_VERSION_1_10) ++ compiler->features |= VKD3D_SHADER_COMPILE_OPTION_FEATURE_FLOAT64; ++ + rb_init(&compiler->symbol_table, vkd3d_symbol_compare); + + compiler->shader_type = shader_version->type; +@@ -5582,7 +5607,16 @@ static void spirv_compiler_emit_dcl_global_flags(struct spirv_compiler *compiler + + if (flags & (VKD3DSGF_ENABLE_DOUBLE_PRECISION_FLOAT_OPS | VKD3DSGF_ENABLE_11_1_DOUBLE_EXTENSIONS)) + { +- vkd3d_spirv_enable_capability(&compiler->spirv_builder, SpvCapabilityFloat64); ++ if (compiler->features & VKD3D_SHADER_COMPILE_OPTION_FEATURE_FLOAT64) ++ { ++ vkd3d_spirv_enable_capability(&compiler->spirv_builder, SpvCapabilityFloat64); ++ } ++ else ++ { ++ WARN("Unsupported 64-bit float ops.\n"); ++ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_UNSUPPORTED_FEATURE, ++ "The target environment does not support 64-bit floating point."); ++ } + flags &= ~(VKD3DSGF_ENABLE_DOUBLE_PRECISION_FLOAT_OPS | VKD3DSGF_ENABLE_11_1_DOUBLE_EXTENSIONS); + } + +@@ -6203,6 +6237,9 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp + if (!(d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ)) + vkd3d_spirv_build_op_decorate(builder, var_id, SpvDecorationNonReadable, NULL, 0); + ++ if (d->uav_flags & VKD3DSUF_GLOBALLY_COHERENT) ++ vkd3d_spirv_build_op_decorate(builder, var_id, SpvDecorationCoherent, NULL, 0); ++ + if (d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_COUNTER) + { + assert(structure_stride); /* counters are valid only for structured buffers */ +@@ -6749,6 +6786,8 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru + {VKD3DSIH_INEG, SpvOpSNegate}, + {VKD3DSIH_ISHL, SpvOpShiftLeftLogical}, + {VKD3DSIH_ISHR, SpvOpShiftRightArithmetic}, ++ {VKD3DSIH_ISINF, SpvOpIsInf}, ++ {VKD3DSIH_ISNAN, SpvOpIsNan}, + {VKD3DSIH_ITOD, SpvOpConvertSToF}, + {VKD3DSIH_ITOF, SpvOpConvertSToF}, + {VKD3DSIH_ITOI, SpvOpSConvert}, +@@ -6896,6 +6935,23 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil + return VKD3D_OK; + } + ++static void spirv_compiler_emit_isfinite(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 type_id, src_id, isinf_id, isnan_id, val_id; ++ ++ type_id = spirv_compiler_get_type_id_for_dst(compiler, dst); ++ src_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); ++ /* OpIsFinite is only available in Kernel mode. */ ++ isinf_id = vkd3d_spirv_build_op_is_inf(builder, type_id, src_id); ++ isnan_id = vkd3d_spirv_build_op_is_nan(builder, type_id, src_id); ++ val_id = vkd3d_spirv_build_op_logical_equal(builder, type_id, isinf_id, isnan_id); ++ spirv_compiler_emit_store_dst(compiler, dst, val_id); ++} ++ + static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction( + const struct vkd3d_shader_instruction *instruction) + { +@@ -6926,6 +6982,7 @@ static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction( + {VKD3DSIH_ROUND_Z, GLSLstd450Trunc}, + {VKD3DSIH_RSQ, GLSLstd450InverseSqrt}, + {VKD3DSIH_SQRT, GLSLstd450Sqrt}, ++ {VKD3DSIH_TAN, GLSLstd450Tan}, + {VKD3DSIH_UMAX, GLSLstd450UMax}, + {VKD3DSIH_UMIN, GLSLstd450UMin}, + }; +@@ -9287,11 +9344,20 @@ static void spirv_compiler_emit_sync(struct spirv_compiler *compiler, + flags &= ~VKD3DSSF_THREAD_GROUP; + } + +- if (flags & VKD3DSSF_GLOBAL_UAV) ++ if (flags & (VKD3DSSF_THREAD_GROUP_UAV | VKD3DSSF_GLOBAL_UAV)) + { +- memory_scope = SpvScopeDevice; +- memory_semantics |= SpvMemorySemanticsImageMemoryMask; +- flags &= ~VKD3DSSF_GLOBAL_UAV; ++ bool group_uav = flags & VKD3DSSF_THREAD_GROUP_UAV; ++ bool global_uav = flags & VKD3DSSF_GLOBAL_UAV; ++ ++ if (group_uav && global_uav) ++ { ++ WARN("Invalid UAV sync flag combination; assuming global.\n"); ++ spirv_compiler_warning(compiler, VKD3D_SHADER_WARNING_SPV_INVALID_UAV_FLAGS, ++ "The flags for a UAV sync instruction are contradictory; assuming global sync."); ++ } ++ memory_scope = global_uav ? SpvScopeDevice : SpvScopeWorkgroup; ++ memory_semantics |= SpvMemorySemanticsUniformMemoryMask | SpvMemorySemanticsImageMemoryMask; ++ flags &= ~(VKD3DSSF_THREAD_GROUP_UAV | VKD3DSSF_GLOBAL_UAV); + } + + if (flags) +@@ -9452,6 +9518,8 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, + case VKD3DSIH_INEG: + case VKD3DSIH_ISHL: + case VKD3DSIH_ISHR: ++ case VKD3DSIH_ISINF: ++ case VKD3DSIH_ISNAN: + case VKD3DSIH_ITOD: + case VKD3DSIH_ITOF: + case VKD3DSIH_ITOI: +@@ -9465,6 +9533,9 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, + case VKD3DSIH_XOR: + ret = spirv_compiler_emit_alu_instruction(compiler, instruction); + break; ++ case VKD3DSIH_ISFINITE: ++ spirv_compiler_emit_isfinite(compiler, instruction); ++ break; + case VKD3DSIH_DFMA: + case VKD3DSIH_DMAX: + case VKD3DSIH_DMIN: +@@ -9485,6 +9556,7 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, + case VKD3DSIH_ROUND_Z: + case VKD3DSIH_RSQ: + case VKD3DSIH_SQRT: ++ case VKD3DSIH_TAN: + case VKD3DSIH_UMAX: + case VKD3DSIH_UMIN: + spirv_compiler_emit_ext_glsl_instruction(compiler, instruction); +@@ -9558,7 +9630,6 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, + spirv_compiler_emit_retc(compiler, instruction); + break; + case VKD3DSIH_DISCARD: +- case VKD3DSIH_TEXKILL: + spirv_compiler_emit_discard(compiler, instruction); + break; + case VKD3DSIH_LABEL: +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +index 14d885fb666..1b7ea8dde9a 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +@@ -1016,7 +1016,7 @@ static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_co + static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_context *context, + const struct vkd3d_shader_resource *resource, enum vkd3d_shader_resource_type resource_type, + enum vkd3d_shader_resource_data_type resource_data_type, +- unsigned int sample_count, unsigned int structure_stride, bool raw) ++ unsigned int sample_count, unsigned int structure_stride, bool raw, uint32_t flags) + { + struct vkd3d_shader_descriptor_info1 *d; + enum vkd3d_shader_descriptor_type type; +@@ -1032,6 +1032,8 @@ static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_cont + d->structure_stride = structure_stride; + if (raw) + d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER; ++ if (type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV) ++ d->uav_flags = flags; + } + + static void vkd3d_shader_scan_typed_resource_declaration(struct vkd3d_shader_scan_context *context, +@@ -1090,7 +1092,7 @@ static void vkd3d_shader_scan_typed_resource_declaration(struct vkd3d_shader_sca + } + + vkd3d_shader_scan_resource_declaration(context, &semantic->resource, +- semantic->resource_type, resource_data_type, semantic->sample_count, 0, false); ++ semantic->resource_type, resource_data_type, semantic->sample_count, 0, false, instruction->flags); + } + + static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *context, +@@ -1126,15 +1128,16 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte + case VKD3DSIH_DCL_RESOURCE_RAW: + case VKD3DSIH_DCL_UAV_RAW: + vkd3d_shader_scan_resource_declaration(context, &instruction->declaration.raw_resource.resource, +- VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0, 0, true); ++ VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0, 0, true, instruction->flags); + break; + case VKD3DSIH_DCL_RESOURCE_STRUCTURED: + case VKD3DSIH_DCL_UAV_STRUCTURED: + vkd3d_shader_scan_resource_declaration(context, &instruction->declaration.structured_resource.resource, + VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0, +- instruction->declaration.structured_resource.byte_stride, false); ++ instruction->declaration.structured_resource.byte_stride, false, instruction->flags); + break; + case VKD3DSIH_IF: ++ case VKD3DSIH_IFC: + cf_info = vkd3d_shader_scan_push_cf_info(context); + cf_info->type = VKD3D_SHADER_BLOCK_IF; + cf_info->inside_block = true; +@@ -2084,6 +2087,23 @@ bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *ins + return true; + } + ++bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *instructions, ++ unsigned int idx, unsigned int count) ++{ ++ assert(idx <= instructions->count); ++ ++ if (!shader_instruction_array_reserve(instructions, instructions->count + count)) ++ return false; ++ ++ memmove(&instructions->elements[idx + count], &instructions->elements[idx], ++ (instructions->count - idx) * sizeof(*instructions->elements)); ++ memset(&instructions->elements[idx], 0, count * sizeof(*instructions->elements)); ++ ++ instructions->count += count; ++ ++ return true; ++} ++ + bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions, + struct vkd3d_shader_immediate_constant_buffer *icb) + { +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +index 115a7d8c83b..fd0f2f0f34a 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +@@ -99,6 +99,7 @@ enum vkd3d_shader_error + VKD3D_SHADER_ERROR_SPV_INVALID_SHADER = 2009, + + VKD3D_SHADER_WARNING_SPV_INVALID_SWIZZLE = 2300, ++ VKD3D_SHADER_WARNING_SPV_INVALID_UAV_FLAGS = 2301, + + VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY = 3000, + VKD3D_SHADER_ERROR_RS_INVALID_VERSION = 3001, +@@ -392,8 +393,11 @@ enum vkd3d_shader_opcode + VKD3DSIH_IMUL, + VKD3DSIH_INE, + VKD3DSIH_INEG, ++ VKD3DSIH_ISFINITE, + VKD3DSIH_ISHL, + VKD3DSIH_ISHR, ++ VKD3DSIH_ISINF, ++ VKD3DSIH_ISNAN, + VKD3DSIH_ITOD, + VKD3DSIH_ITOF, + VKD3DSIH_ITOI, +@@ -476,6 +480,7 @@ enum vkd3d_shader_opcode + VKD3DSIH_SWITCH, + VKD3DSIH_SWITCH_MONOLITHIC, + VKD3DSIH_SYNC, ++ VKD3DSIH_TAN, + VKD3DSIH_TEX, + VKD3DSIH_TEXBEM, + VKD3DSIH_TEXBEML, +@@ -727,6 +732,7 @@ enum vkd3d_shader_sync_flags + { + VKD3DSSF_THREAD_GROUP = 0x1, + VKD3DSSF_GROUP_SHARED_MEMORY = 0x2, ++ VKD3DSSF_THREAD_GROUP_UAV = 0x4, + VKD3DSSF_GLOBAL_UAV = 0x8, + }; + +@@ -1248,6 +1254,8 @@ struct vkd3d_shader_instruction_array + + bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve); + bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve); ++bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *instructions, ++ unsigned int idx, unsigned int count); + bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions, + struct vkd3d_shader_immediate_constant_buffer *icb); + bool shader_instruction_array_clone_instruction(struct vkd3d_shader_instruction_array *instructions, +@@ -1334,6 +1342,7 @@ struct vkd3d_shader_descriptor_info1 + unsigned int buffer_size; + unsigned int structure_stride; + unsigned int count; ++ uint32_t uav_flags; + }; + + struct vkd3d_shader_scan_descriptor_info1 +diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c +index d146e322d25..3cf58e06d40 100644 +--- a/libs/vkd3d/libs/vkd3d/command.c ++++ b/libs/vkd3d/libs/vkd3d/command.c +@@ -926,7 +926,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_fence_QueryInterface(ID3D12Fence1 *iface, + static ULONG STDMETHODCALLTYPE d3d12_fence_AddRef(ID3D12Fence1 *iface) + { + struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface); +- ULONG refcount = InterlockedIncrement(&fence->refcount); ++ unsigned int refcount = vkd3d_atomic_increment_u32(&fence->refcount); + + TRACE("%p increasing refcount to %u.\n", fence, refcount); + +@@ -935,13 +935,13 @@ static ULONG STDMETHODCALLTYPE d3d12_fence_AddRef(ID3D12Fence1 *iface) + + static void d3d12_fence_incref(struct d3d12_fence *fence) + { +- InterlockedIncrement(&fence->internal_refcount); ++ vkd3d_atomic_increment_u32(&fence->internal_refcount); + } + + static ULONG STDMETHODCALLTYPE d3d12_fence_Release(ID3D12Fence1 *iface) + { + struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface); +- ULONG refcount = InterlockedDecrement(&fence->refcount); ++ unsigned int refcount = vkd3d_atomic_decrement_u32(&fence->refcount); + + TRACE("%p decreasing refcount to %u.\n", fence, refcount); + +@@ -953,24 +953,24 @@ static ULONG STDMETHODCALLTYPE d3d12_fence_Release(ID3D12Fence1 *iface) + + static void d3d12_fence_decref(struct d3d12_fence *fence) + { +- ULONG internal_refcount = InterlockedDecrement(&fence->internal_refcount); ++ struct d3d12_device *device; + +- if (!internal_refcount) +- { +- struct d3d12_device *device = fence->device; ++ if (vkd3d_atomic_decrement_u32(&fence->internal_refcount)) ++ return; + +- vkd3d_private_store_destroy(&fence->private_store); ++ device = fence->device; + +- d3d12_fence_destroy_vk_objects(fence); ++ vkd3d_private_store_destroy(&fence->private_store); + +- vkd3d_free(fence->events); +- vkd3d_free(fence->semaphores); +- vkd3d_mutex_destroy(&fence->mutex); +- vkd3d_cond_destroy(&fence->null_event_cond); +- vkd3d_free(fence); ++ d3d12_fence_destroy_vk_objects(fence); + +- d3d12_device_release(device); +- } ++ vkd3d_free(fence->events); ++ vkd3d_free(fence->semaphores); ++ vkd3d_mutex_destroy(&fence->mutex); ++ vkd3d_cond_destroy(&fence->null_event_cond); ++ vkd3d_free(fence); ++ ++ d3d12_device_release(device); + } + + static HRESULT STDMETHODCALLTYPE d3d12_fence_GetPrivateData(ID3D12Fence1 *iface, +@@ -1635,7 +1635,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_allocator_QueryInterface(ID3D12Co + static ULONG STDMETHODCALLTYPE d3d12_command_allocator_AddRef(ID3D12CommandAllocator *iface) + { + struct d3d12_command_allocator *allocator = impl_from_ID3D12CommandAllocator(iface); +- ULONG refcount = InterlockedIncrement(&allocator->refcount); ++ unsigned int refcount = vkd3d_atomic_increment_u32(&allocator->refcount); + + TRACE("%p increasing refcount to %u.\n", allocator, refcount); + +@@ -1645,7 +1645,7 @@ static ULONG STDMETHODCALLTYPE d3d12_command_allocator_AddRef(ID3D12CommandAlloc + static ULONG STDMETHODCALLTYPE d3d12_command_allocator_Release(ID3D12CommandAllocator *iface) + { + struct d3d12_command_allocator *allocator = impl_from_ID3D12CommandAllocator(iface); +- ULONG refcount = InterlockedDecrement(&allocator->refcount); ++ unsigned int refcount = vkd3d_atomic_decrement_u32(&allocator->refcount); + + TRACE("%p decreasing refcount to %u.\n", allocator, refcount); + +@@ -2320,7 +2320,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12Graphic + static ULONG STDMETHODCALLTYPE d3d12_command_list_AddRef(ID3D12GraphicsCommandList5 *iface) + { + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); +- ULONG refcount = InterlockedIncrement(&list->refcount); ++ unsigned int refcount = vkd3d_atomic_increment_u32(&list->refcount); + + TRACE("%p increasing refcount to %u.\n", list, refcount); + +@@ -2335,7 +2335,7 @@ static void vkd3d_pipeline_bindings_cleanup(struct vkd3d_pipeline_bindings *bind + static ULONG STDMETHODCALLTYPE d3d12_command_list_Release(ID3D12GraphicsCommandList5 *iface) + { + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); +- ULONG refcount = InterlockedDecrement(&list->refcount); ++ unsigned int refcount = vkd3d_atomic_decrement_u32(&list->refcount); + + TRACE("%p decreasing refcount to %u.\n", list, refcount); + +@@ -6230,7 +6230,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_QueryInterface(ID3D12Comman + static ULONG STDMETHODCALLTYPE d3d12_command_queue_AddRef(ID3D12CommandQueue *iface) + { + struct d3d12_command_queue *command_queue = impl_from_ID3D12CommandQueue(iface); +- ULONG refcount = InterlockedIncrement(&command_queue->refcount); ++ unsigned int refcount = vkd3d_atomic_increment_u32(&command_queue->refcount); + + TRACE("%p increasing refcount to %u.\n", command_queue, refcount); + +@@ -6272,7 +6272,7 @@ static void d3d12_command_queue_op_array_destroy(struct d3d12_command_queue_op_a + static ULONG STDMETHODCALLTYPE d3d12_command_queue_Release(ID3D12CommandQueue *iface) + { + struct d3d12_command_queue *command_queue = impl_from_ID3D12CommandQueue(iface); +- ULONG refcount = InterlockedDecrement(&command_queue->refcount); ++ unsigned int refcount = vkd3d_atomic_decrement_u32(&command_queue->refcount); + + TRACE("%p decreasing refcount to %u.\n", command_queue, refcount); + +@@ -7442,7 +7442,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_signature_QueryInterface(ID3D12Co + static ULONG STDMETHODCALLTYPE d3d12_command_signature_AddRef(ID3D12CommandSignature *iface) + { + struct d3d12_command_signature *signature = impl_from_ID3D12CommandSignature(iface); +- ULONG refcount = InterlockedIncrement(&signature->refcount); ++ unsigned int refcount = vkd3d_atomic_increment_u32(&signature->refcount); + + TRACE("%p increasing refcount to %u.\n", signature, refcount); + +@@ -7452,7 +7452,7 @@ static ULONG STDMETHODCALLTYPE d3d12_command_signature_AddRef(ID3D12CommandSigna + static ULONG STDMETHODCALLTYPE d3d12_command_signature_Release(ID3D12CommandSignature *iface) + { + struct d3d12_command_signature *signature = impl_from_ID3D12CommandSignature(iface); +- ULONG refcount = InterlockedDecrement(&signature->refcount); ++ unsigned int refcount = vkd3d_atomic_decrement_u32(&signature->refcount); + + TRACE("%p decreasing refcount to %u.\n", signature, refcount); + +diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c +index 82782e7d5fc..5f383d256cc 100644 +--- a/libs/vkd3d/libs/vkd3d/state.c ++++ b/libs/vkd3d/libs/vkd3d/state.c +@@ -2154,6 +2154,8 @@ static unsigned int feature_flags_compile_option(const struct d3d12_device *devi + + if (device->feature_options1.Int64ShaderOps) + flags |= VKD3D_SHADER_COMPILE_OPTION_FEATURE_INT64; ++ if (device->feature_options.DoublePrecisionFloatShaderOps) ++ flags |= VKD3D_SHADER_COMPILE_OPTION_FEATURE_FLOAT64; + + return flags; + } +@@ -2270,7 +2272,7 @@ static HRESULT vkd3d_create_compute_pipeline(struct d3d12_device *device, + VK_CALL(vkDestroyShaderModule(device->vk_device, pipeline_info.stage.module, NULL)); + if (vr < 0) + { +- WARN("Failed to create Vulkan compute pipeline, hr %#x.\n", hr); ++ WARN("Failed to create Vulkan compute pipeline, hr %s.\n", debugstr_hresult(hr)); + return hresult_from_vk_result(vr); + } + +@@ -2398,7 +2400,7 @@ static HRESULT d3d12_pipeline_state_find_and_init_uav_counters(struct d3d12_pipe + } + + if (FAILED(hr = d3d12_pipeline_state_init_uav_counters(state, device, root_signature, &shader_info, stage_flags))) +- WARN("Failed to create descriptor set layout for UAV counters, hr %#x.\n", hr); ++ WARN("Failed to create descriptor set layout for UAV counters, hr %s.\n", debugstr_hresult(hr)); + + vkd3d_shader_free_scan_descriptor_info(&shader_info); + +@@ -2472,7 +2474,7 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st + if (FAILED(hr = vkd3d_create_compute_pipeline(device, &desc->cs, &shader_interface, + vk_pipeline_layout, &state->u.compute.vk_pipeline))) + { +- WARN("Failed to create Vulkan compute pipeline, hr %#x.\n", hr); ++ WARN("Failed to create Vulkan compute pipeline, hr %s.\n", debugstr_hresult(hr)); + d3d12_pipeline_uav_counter_state_cleanup(&state->uav_counters, device); + return hr; + } +@@ -4026,14 +4028,14 @@ HRESULT vkd3d_uav_clear_state_init(struct vkd3d_uav_clear_state *state, struct d + if (FAILED(hr = vkd3d_create_descriptor_set_layout(device, 0, + 1, false, &set_binding, set_layouts[i].set_layout))) + { +- ERR("Failed to create descriptor set layout %u, hr %#x.\n", i, hr); ++ ERR("Failed to create descriptor set layout %u, hr %s.\n", i, debugstr_hresult(hr)); + goto fail; + } + + if (FAILED(hr = vkd3d_create_pipeline_layout(device, 1, set_layouts[i].set_layout, + 1, &push_constant_range, set_layouts[i].pipeline_layout))) + { +- ERR("Failed to create pipeline layout %u, hr %#x.\n", i, hr); ++ ERR("Failed to create pipeline layout %u, hr %s.\n", i, debugstr_hresult(hr)); + goto fail; + } + } +@@ -4071,7 +4073,7 @@ HRESULT vkd3d_uav_clear_state_init(struct vkd3d_uav_clear_state *state, struct d + vkd3d_shader_free_shader_code(&dxbc); + if (FAILED(hr)) + { +- ERR("Failed to create compute pipeline %u, hr %#x.\n", i, hr); ++ ERR("Failed to create compute pipeline %u, hr %s.\n", i, debugstr_hresult(hr)); + goto fail; + } + } +diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_main.c b/libs/vkd3d/libs/vkd3d/vkd3d_main.c +index 245edb5aeac..0139de5dd23 100644 +--- a/libs/vkd3d/libs/vkd3d/vkd3d_main.c ++++ b/libs/vkd3d/libs/vkd3d/vkd3d_main.c +@@ -60,7 +60,7 @@ HRESULT vkd3d_create_device(const struct vkd3d_device_create_info *create_info, + } + else if (FAILED(hr = vkd3d_create_instance(create_info->instance_create_info, &instance))) + { +- WARN("Failed to create instance, hr %#x.\n", hr); ++ WARN("Failed to create instance, hr %s.\n", debugstr_hresult(hr)); + return E_FAIL; + } + +@@ -456,7 +456,7 @@ HRESULT vkd3d_serialize_root_signature(const D3D12_ROOT_SIGNATURE_DESC *desc, + if (error_blob && messages) + { + if (FAILED(hr = vkd3d_blob_create(messages, strlen(messages), error_blob))) +- ERR("Failed to create error blob, hr %#x.\n", hr); ++ ERR("Failed to create error blob, hr %s.\n", debugstr_hresult(hr)); + } + return hresult_from_vkd3d_result(ret); + } +@@ -464,7 +464,7 @@ HRESULT vkd3d_serialize_root_signature(const D3D12_ROOT_SIGNATURE_DESC *desc, + + if (FAILED(hr = vkd3d_blob_create((void *)dxbc.code, dxbc.size, blob))) + { +- WARN("Failed to create blob object, hr %#x.\n", hr); ++ WARN("Failed to create blob object, hr %s.\n", debugstr_hresult(hr)); + vkd3d_shader_free_shader_code(&dxbc); + } + return hr; +@@ -497,7 +497,7 @@ HRESULT vkd3d_serialize_versioned_root_signature(const D3D12_VERSIONED_ROOT_SIGN + if (error_blob && messages) + { + if (FAILED(hr = vkd3d_blob_create(messages, strlen(messages), error_blob))) +- ERR("Failed to create error blob, hr %#x.\n", hr); ++ ERR("Failed to create error blob, hr %s.\n", debugstr_hresult(hr)); + } + return hresult_from_vkd3d_result(ret); + } +@@ -505,7 +505,7 @@ HRESULT vkd3d_serialize_versioned_root_signature(const D3D12_VERSIONED_ROOT_SIGN + + if (FAILED(hr = vkd3d_blob_create((void *)dxbc.code, dxbc.size, blob))) + { +- WARN("Failed to create blob object, hr %#x.\n", hr); ++ WARN("Failed to create blob object, hr %s.\n", debugstr_hresult(hr)); + vkd3d_shader_free_shader_code(&dxbc); + } + return hr; +diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h +index 13802c97773..a6d5b94b778 100644 +--- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h ++++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h +@@ -621,8 +621,8 @@ struct vkd3d_signaled_semaphore + struct d3d12_fence + { + ID3D12Fence1 ID3D12Fence1_iface; +- LONG internal_refcount; +- LONG refcount; ++ unsigned int internal_refcount; ++ unsigned int refcount; + + D3D12_FENCE_FLAGS flags; + +@@ -1365,7 +1365,7 @@ struct vkd3d_buffer + struct d3d12_command_allocator + { + ID3D12CommandAllocator ID3D12CommandAllocator_iface; +- LONG refcount; ++ unsigned int refcount; + + D3D12_COMMAND_LIST_TYPE type; + VkQueueFlags vk_queue_flags; +@@ -1466,7 +1466,7 @@ enum vkd3d_pipeline_bind_point + struct d3d12_command_list + { + ID3D12GraphicsCommandList5 ID3D12GraphicsCommandList5_iface; +- LONG refcount; ++ unsigned int refcount; + + D3D12_COMMAND_LIST_TYPE type; + VkQueueFlags vk_queue_flags; +@@ -1622,7 +1622,7 @@ struct d3d12_command_queue_op_array + struct d3d12_command_queue + { + ID3D12CommandQueue ID3D12CommandQueue_iface; +- LONG refcount; ++ unsigned int refcount; + + D3D12_COMMAND_QUEUE_DESC desc; + +@@ -1657,7 +1657,7 @@ HRESULT d3d12_command_queue_create(struct d3d12_device *device, + struct d3d12_command_signature + { + ID3D12CommandSignature ID3D12CommandSignature_iface; +- LONG refcount; ++ unsigned int refcount; + unsigned int internal_refcount; + + D3D12_COMMAND_SIGNATURE_DESC desc; +-- +2.43.0 +