From bd12bfc20c592fba43050f99c0e6fe547f49f08c Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Wed, 17 May 2023 08:35:40 +1000 Subject: [PATCH 1/2] Updated vkd3d to 6a942581db3093a2e5b5a76334601868e217a60d. --- libs/vkd3d/include/list.h | 270 ++++ libs/vkd3d/include/private/list.h | 270 ++++ libs/vkd3d/include/private/rbtree.h | 378 +++++ libs/vkd3d/include/private/vkd3d_common.h | 2 +- libs/vkd3d/include/private/vkd3d_test.h | 432 ++++++ libs/vkd3d/include/vkd3d_d3d9types.h | 237 +++ libs/vkd3d/include/vkd3d_d3dcompiler.h | 74 + libs/vkd3d/include/vkd3d_shader.h | 34 +- libs/vkd3d/include/vkd3d_utils.h | 108 ++ libs/vkd3d/include/vkd3d_windows.h | 289 ++++ libs/vkd3d/libs/vkd3d-common/blob.c | 2 + libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 42 +- libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 74 +- libs/vkd3d/libs/vkd3d-shader/dxbc.c | 2 +- libs/vkd3d/libs/vkd3d-shader/dxil.c | 146 +- libs/vkd3d/libs/vkd3d-shader/hlsl.c | 54 +- libs/vkd3d/libs/vkd3d-shader/hlsl.h | 22 +- libs/vkd3d/libs/vkd3d-shader/hlsl.l | 2 + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 172 ++- libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 319 ++-- .../libs/vkd3d-shader/hlsl_constant_ops.c | 357 ++++- libs/vkd3d/libs/vkd3d-shader/ir.c | 326 +++- libs/vkd3d/libs/vkd3d-shader/preproc.h | 2 +- libs/vkd3d/libs/vkd3d-shader/spirv.c | 248 ++- libs/vkd3d/libs/vkd3d-shader/tpf.c | 1335 +++++++++-------- .../libs/vkd3d-shader/vkd3d_shader_main.c | 39 +- .../libs/vkd3d-shader/vkd3d_shader_private.h | 56 +- libs/vkd3d/libs/vkd3d/command.c | 350 +++-- libs/vkd3d/libs/vkd3d/device.c | 400 +++-- libs/vkd3d/libs/vkd3d/resource.c | 28 +- libs/vkd3d/libs/vkd3d/vkd3d_main.c | 4 +- libs/vkd3d/libs/vkd3d/vkd3d_private.h | 23 +- 32 files changed, 4846 insertions(+), 1251 deletions(-) create mode 100644 libs/vkd3d/include/list.h 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_utils.h create mode 100644 libs/vkd3d/include/vkd3d_windows.h diff --git a/libs/vkd3d/include/list.h b/libs/vkd3d/include/list.h new file mode 100644 index 00000000000..2e1d95f3fd4 --- /dev/null +++ b/libs/vkd3d/include/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/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_common.h b/libs/vkd3d/include/private/vkd3d_common.h index ee733ee0d76..f7d98f327f1 100644 --- a/libs/vkd3d/include/private/vkd3d_common.h +++ b/libs/vkd3d/include/private/vkd3d_common.h @@ -86,7 +86,7 @@ static inline unsigned int vkd3d_popcount(unsigned int v) { #ifdef _MSC_VER return __popcnt(v); -#elif defined(__MINGW32__) +#elif defined(HAVE_BUILTIN_POPCOUNT) return __builtin_popcount(v); #else v -= (v >> 1) & 0x55555555; 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..c934835dc0a --- /dev/null +++ b/libs/vkd3d/include/vkd3d_d3dcompiler.h @@ -0,0 +1,74 @@ +/* + * Copyright 2010 Matteo Bruni for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __VKD3D_D3DCOMPILER_H +#define __VKD3D_D3DCOMPILER_H +#ifndef __D3DCOMPILER_H__ + +#define D3DCOMPILE_DEBUG 0x00000001 +#define D3DCOMPILE_SKIP_VALIDATION 0x00000002 +#define D3DCOMPILE_SKIP_OPTIMIZATION 0x00000004 +#define D3DCOMPILE_PACK_MATRIX_ROW_MAJOR 0x00000008 +#define D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR 0x00000010 +#define D3DCOMPILE_PARTIAL_PRECISION 0x00000020 +#define D3DCOMPILE_FORCE_VS_SOFTWARE_NO_OPT 0x00000040 +#define D3DCOMPILE_FORCE_PS_SOFTWARE_NO_OPT 0x00000080 +#define D3DCOMPILE_NO_PRESHADER 0x00000100 +#define D3DCOMPILE_AVOID_FLOW_CONTROL 0x00000200 +#define D3DCOMPILE_PREFER_FLOW_CONTROL 0x00000400 +#define D3DCOMPILE_ENABLE_STRICTNESS 0x00000800 +#define D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY 0x00001000 +#define D3DCOMPILE_IEEE_STRICTNESS 0x00002000 +#define D3DCOMPILE_OPTIMIZATION_LEVEL0 0x00004000 +#define D3DCOMPILE_OPTIMIZATION_LEVEL1 0x00000000 +#define D3DCOMPILE_OPTIMIZATION_LEVEL2 0x0000c000 +#define D3DCOMPILE_OPTIMIZATION_LEVEL3 0x00008000 +#define D3DCOMPILE_RESERVED16 0x00010000 +#define D3DCOMPILE_RESERVED17 0x00020000 +#define D3DCOMPILE_WARNINGS_ARE_ERRORS 0x00040000 +#define D3DCOMPILE_RESOURCES_MAY_ALIAS 0x00080000 +#define D3DCOMPILE_ENABLE_UNBOUNDED_DESCRIPTOR_TABLES 0x00100000 +#define D3DCOMPILE_ALL_RESOURCES_BOUND 0x00200000 +#define D3DCOMPILE_DEBUG_NAME_FOR_SOURCE 0x00400000 +#define D3DCOMPILE_DEBUG_NAME_FOR_BINARY 0x00800000 + +#define D3DCOMPILE_EFFECT_CHILD_EFFECT 0x00000001 +#define D3DCOMPILE_EFFECT_ALLOW_SLOW_OPS 0x00000002 + +#define D3DCOMPILE_FLAGS2_FORCE_ROOT_SIGNATURE_LATEST 0x00000000 +#define D3DCOMPILE_FLAGS2_FORCE_ROOT_SIGNATURE_1_0 0x00000010 +#define D3DCOMPILE_FLAGS2_FORCE_ROOT_SIGNATURE_1_1 0x00000020 + +#define D3DCOMPILE_SECDATA_MERGE_UAV_SLOTS 0x00000001 +#define D3DCOMPILE_SECDATA_PRESERVE_TEMPLATE_SLOTS 0x00000002 +#define D3DCOMPILE_SECDATA_REQUIRE_TEMPLATE_MATCH 0x00000004 + +HRESULT WINAPI D3DCompile(const void *data, SIZE_T data_size, const char *filename, + const D3D_SHADER_MACRO *macros, ID3DInclude *include, const char *entrypoint, + const char *profile, UINT flags, UINT effect_flags, ID3DBlob **shader, ID3DBlob **error_messages); +HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filename, + const D3D_SHADER_MACRO *macros, ID3DInclude *include, const char *entrypoint, + const char *profile, UINT flags, UINT effect_flags, UINT secondary_flags, + const void *secondary_data, SIZE_T secondary_data_size, ID3DBlob **shader, + ID3DBlob **error_messages); +HRESULT WINAPI D3DCreateBlob(SIZE_T size, ID3DBlob **blob); +HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, const char *filename, const D3D_SHADER_MACRO *macros, + ID3DInclude *include, ID3DBlob **shader, ID3DBlob **error_messages); + +#endif /* __D3DCOMPILER_H__ */ +#endif /* __VKD3D_D3DCOMPILER_H */ diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h index 01356ce3931..9d0d768b43d 100644 --- a/libs/vkd3d/include/vkd3d_shader.h +++ b/libs/vkd3d/include/vkd3d_shader.h @@ -1383,16 +1383,30 @@ struct vkd3d_shader_descriptor_info * * This structure extends vkd3d_shader_compile_info. * - * When scanning a legacy Direct3D shader, vkd3d-shader enumerates each - * constant register set used by the shader as a single constant buffer - * descriptor, as follows: - * - The \ref vkd3d_shader_descriptor_info.type field is set to - * VKD3D_SHADER_DESCRIPTOR_TYPE_CBV. - * - The \ref vkd3d_shader_descriptor_info.register_space field is set to zero. - * - The \ref vkd3d_shader_descriptor_info.register_index field is set to a - * member of enum vkd3d_shader_d3dbc_constant_register denoting which set - * is used. - * - The \ref vkd3d_shader_descriptor_info.count field is set to one. + * When scanning a legacy Direct3D shader, vkd3d-shader enumerates descriptors + * as follows: + * + * - Each constant register set used by the shader is scanned as a single + * constant buffer descriptor, as follows: + * * The \ref vkd3d_shader_descriptor_info.type field is set to + * VKD3D_SHADER_DESCRIPTOR_TYPE_CBV. + * * The \ref vkd3d_shader_descriptor_info.register_space field is set to zero. + * * The \ref vkd3d_shader_descriptor_info.register_index field is set to a + * member of enum vkd3d_shader_d3dbc_constant_register denoting which set + * is used. + * * The \ref vkd3d_shader_descriptor_info.count field is set to one. + * - Each sampler used by the shader is scanned as two separate descriptors, + * one representing the texture, and one representing the sampler state. + * If desired, these may be mapped back into a single combined sampler using + * struct vkd3d_shader_combined_resource_sampler. + * The fields are set as follows: + * * The \ref vkd3d_shader_descriptor_info.type field is set to + * VKD3D_SHADER_DESCRIPTOR_TYPE_SRV and VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER + * respectively. + * * The \ref vkd3d_shader_descriptor_info.register_space field is set to zero. + * * The \ref vkd3d_shader_descriptor_info.register_index field is set to the + * binding index of the original sampler, for both descriptors. + * * The \ref vkd3d_shader_descriptor_info.count field is set to one. * * In summary, there may be up to three such descriptors, one for each register * set used by the shader: float, integer, and boolean. diff --git a/libs/vkd3d/include/vkd3d_utils.h b/libs/vkd3d/include/vkd3d_utils.h new file mode 100644 index 00000000000..e8462563576 --- /dev/null +++ b/libs/vkd3d/include/vkd3d_utils.h @@ -0,0 +1,108 @@ +/* + * Copyright 2016 Józef Kucia for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __VKD3D_UTILS_H +#define __VKD3D_UTILS_H + +#include + +#ifndef VKD3D_UTILS_API_VERSION +#define VKD3D_UTILS_API_VERSION VKD3D_API_VERSION_1_0 +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * \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); + +#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 30205088b1b..fa2812619ac 100644 --- a/libs/vkd3d/libs/vkd3d-common/blob.c +++ b/libs/vkd3d/libs/vkd3d-common/blob.c @@ -17,6 +17,8 @@ */ #define COBJMACROS + +#define CONST_VTABLE #include "vkd3d.h" #include "vkd3d_blob.h" #include "vkd3d_debug.h" diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c index f0c386f1b3a..38a607351fe 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c @@ -637,7 +637,7 @@ static void shader_dump_decl_usage(struct vkd3d_d3d_asm_compiler *compiler, { struct vkd3d_string_buffer *buffer = &compiler->buffer; - if (semantic->resource.reg.reg.type == VKD3DSPR_SAMPLER) + if (semantic->resource.reg.reg.type == VKD3DSPR_COMBINED_SAMPLER) { switch (semantic->resource_type) { @@ -880,9 +880,7 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const break; case VKD3DSPR_COLOROUT: - shader_addline(buffer, "o"); - if (!shader_ver_ge(&compiler->shader_version, 4, 0)) - shader_addline(buffer, "C"); + shader_addline(buffer, "oC"); break; case VKD3DSPR_DEPTHOUT: @@ -926,6 +924,7 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const shader_addline(buffer, "aL"); break; + case VKD3DSPR_COMBINED_SAMPLER: case VKD3DSPR_SAMPLER: shader_addline(buffer, "s"); is_descriptor = true; @@ -1066,6 +1065,14 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const shader_addline(buffer, "oStencilRef"); break; + case VKD3DSPR_UNDEF: + shader_addline(buffer, "undef"); + break; + + case VKD3DSPR_SSA: + shader_addline(buffer, "sr"); + break; + default: shader_addline(buffer, "", reg->type); break; @@ -1074,9 +1081,9 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const if (reg->type == VKD3DSPR_IMMCONST) { shader_addline(buffer, "%s(", compiler->colours.reset); - switch (reg->immconst_type) + switch (reg->dimension) { - case VKD3D_IMMCONST_SCALAR: + case VSIR_DIMENSION_SCALAR: switch (reg->data_type) { case VKD3D_DATA_FLOAT: @@ -1096,7 +1103,7 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const } break; - case VKD3D_IMMCONST_VEC4: + case VSIR_DIMENSION_VEC4: switch (reg->data_type) { case VKD3D_DATA_FLOAT: @@ -1126,7 +1133,7 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const break; default: - shader_addline(buffer, "", reg->immconst_type); + shader_addline(buffer, "", reg->dimension); break; } shader_addline(buffer, ")"); @@ -1134,13 +1141,13 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const else if (reg->type == VKD3DSPR_IMMCONST64) { shader_addline(buffer, "%s(", compiler->colours.reset); - /* A double2 vector is treated as a float4 vector in enum vkd3d_immconst_type. */ - if (reg->immconst_type == VKD3D_IMMCONST_SCALAR || reg->immconst_type == VKD3D_IMMCONST_VEC4) + /* A double2 vector is treated as a float4 vector in enum vsir_dimension. */ + if (reg->dimension == VSIR_DIMENSION_SCALAR || reg->dimension == VSIR_DIMENSION_VEC4) { if (reg->data_type == VKD3D_DATA_DOUBLE) { shader_print_double_literal(compiler, "", reg->u.immconst_double[0], ""); - if (reg->immconst_type == VKD3D_IMMCONST_VEC4) + if (reg->dimension == VSIR_DIMENSION_VEC4) shader_print_double_literal(compiler, ", ", reg->u.immconst_double[1], ""); } else @@ -1150,13 +1157,14 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const } else { - shader_addline(buffer, "", reg->immconst_type); + shader_addline(buffer, "", reg->dimension); } shader_addline(buffer, ")"); } else if (reg->type != VKD3DSPR_RASTOUT && reg->type != VKD3DSPR_MISCTYPE - && reg->type != VKD3DSPR_NULL) + && reg->type != VKD3DSPR_NULL + && reg->type != VKD3DSPR_DEPTHOUT) { if (offset != ~0u) { @@ -1181,7 +1189,7 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const { shader_print_subscript_range(compiler, reg->idx[1].offset, reg->idx[2].offset); } - else + else if (reg->type != VKD3DSPR_SSA) { /* For descriptors in sm < 5.1 we move the reg->idx values up one slot * to normalise with 5.1. @@ -1256,7 +1264,7 @@ static void shader_dump_dst_param(struct vkd3d_d3d_asm_compiler *compiler, shader_dump_register(compiler, ¶m->reg, is_declaration); - if (write_mask) + if (write_mask && param->reg.dimension == VSIR_DIMENSION_VEC4) { static const char write_mask_chars[] = "xyzw"; @@ -1322,7 +1330,7 @@ static void shader_dump_src_param(struct vkd3d_d3d_asm_compiler *compiler, } if (param->reg.type != VKD3DSPR_IMMCONST && param->reg.type != VKD3DSPR_IMMCONST64 - && param->reg.type != VKD3DSPR_SAMPLER) + && param->reg.dimension == VSIR_DIMENSION_VEC4) { unsigned int swizzle_x = vkd3d_swizzle_get_component(swizzle, 0); unsigned int swizzle_y = vkd3d_swizzle_get_component(swizzle, 1); @@ -1374,7 +1382,7 @@ static void shader_dump_ins_modifiers(struct vkd3d_d3d_asm_compiler *compiler, if (mmask & VKD3DSPDM_PARTIALPRECISION) shader_addline(buffer, "_pp"); if (mmask & VKD3DSPDM_MSAMPCENTROID) shader_addline(buffer, "_centroid"); - mmask &= ~(VKD3DSPDM_SATURATE | VKD3DSPDM_PARTIALPRECISION | VKD3DSPDM_MSAMPCENTROID); + mmask &= ~VKD3DSPDM_MASK; if (mmask) FIXME("Unrecognised modifier %#x.\n", mmask); } diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c index 1fd5ab2446d..598b7518394 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c @@ -261,7 +261,7 @@ static const struct vkd3d_sm1_opcode_info vs_opcode_table[] = {VKD3D_SM1_OP_M3x3, 1, 2, VKD3DSIH_M3x3}, {VKD3D_SM1_OP_M3x2, 1, 2, VKD3DSIH_M3x2}, /* Declarations */ - {VKD3D_SM1_OP_DCL, 0, 2, VKD3DSIH_DCL}, + {VKD3D_SM1_OP_DCL, 0, 0, VKD3DSIH_DCL}, /* Constant definitions */ {VKD3D_SM1_OP_DEF, 1, 1, VKD3DSIH_DEF}, {VKD3D_SM1_OP_DEFB, 1, 1, VKD3DSIH_DEFB}, @@ -328,7 +328,7 @@ static const struct vkd3d_sm1_opcode_info ps_opcode_table[] = {VKD3D_SM1_OP_M3x3, 1, 2, VKD3DSIH_M3x3}, {VKD3D_SM1_OP_M3x2, 1, 2, VKD3DSIH_M3x2}, /* Declarations */ - {VKD3D_SM1_OP_DCL, 0, 2, VKD3DSIH_DCL}, + {VKD3D_SM1_OP_DCL, 0, 0, VKD3DSIH_DCL}, /* Constant definitions */ {VKD3D_SM1_OP_DEF, 1, 1, VKD3DSIH_DEF}, {VKD3D_SM1_OP_DEFB, 1, 1, VKD3DSIH_DEFB}, @@ -457,18 +457,20 @@ static uint32_t swizzle_from_sm1(uint32_t swizzle) static void shader_sm1_parse_src_param(uint32_t param, const struct vkd3d_shader_src_param *rel_addr, struct vkd3d_shader_src_param *src) { - src->reg.type = ((param & VKD3D_SM1_REGISTER_TYPE_MASK) >> VKD3D_SM1_REGISTER_TYPE_SHIFT) + enum vkd3d_shader_register_type reg_type = ((param & VKD3D_SM1_REGISTER_TYPE_MASK) >> VKD3D_SM1_REGISTER_TYPE_SHIFT) | ((param & VKD3D_SM1_REGISTER_TYPE_MASK2) >> VKD3D_SM1_REGISTER_TYPE_SHIFT2); + + vsir_register_init(&src->reg, reg_type, VKD3D_DATA_FLOAT, 1); src->reg.precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT; src->reg.non_uniform = false; - src->reg.data_type = VKD3D_DATA_FLOAT; src->reg.idx[0].offset = param & VKD3D_SM1_REGISTER_NUMBER_MASK; src->reg.idx[0].rel_addr = rel_addr; - src->reg.idx[1].offset = ~0u; - src->reg.idx[1].rel_addr = NULL; - src->reg.idx[2].offset = ~0u; - src->reg.idx[2].rel_addr = NULL; - src->reg.idx_count = 1; + if (src->reg.type == VKD3DSPR_SAMPLER) + src->reg.dimension = VSIR_DIMENSION_NONE; + else if (src->reg.type == VKD3DSPR_DEPTHOUT) + src->reg.dimension = VSIR_DIMENSION_SCALAR; + else + src->reg.dimension = VSIR_DIMENSION_VEC4; src->swizzle = swizzle_from_sm1((param & VKD3D_SM1_SWIZZLE_MASK) >> VKD3D_SM1_SWIZZLE_SHIFT); src->modifiers = (param & VKD3D_SM1_SRC_MODIFIER_MASK) >> VKD3D_SM1_SRC_MODIFIER_SHIFT; } @@ -476,18 +478,20 @@ static void shader_sm1_parse_src_param(uint32_t param, const struct vkd3d_shader static void shader_sm1_parse_dst_param(uint32_t param, const struct vkd3d_shader_src_param *rel_addr, struct vkd3d_shader_dst_param *dst) { - dst->reg.type = ((param & VKD3D_SM1_REGISTER_TYPE_MASK) >> VKD3D_SM1_REGISTER_TYPE_SHIFT) + enum vkd3d_shader_register_type reg_type = ((param & VKD3D_SM1_REGISTER_TYPE_MASK) >> VKD3D_SM1_REGISTER_TYPE_SHIFT) | ((param & VKD3D_SM1_REGISTER_TYPE_MASK2) >> VKD3D_SM1_REGISTER_TYPE_SHIFT2); + + vsir_register_init(&dst->reg, reg_type, VKD3D_DATA_FLOAT, 1); dst->reg.precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT; dst->reg.non_uniform = false; - dst->reg.data_type = VKD3D_DATA_FLOAT; dst->reg.idx[0].offset = param & VKD3D_SM1_REGISTER_NUMBER_MASK; dst->reg.idx[0].rel_addr = rel_addr; - dst->reg.idx[1].offset = ~0u; - dst->reg.idx[1].rel_addr = NULL; - dst->reg.idx[2].offset = ~0u; - dst->reg.idx[2].rel_addr = NULL; - dst->reg.idx_count = 1; + if (dst->reg.type == VKD3DSPR_SAMPLER) + dst->reg.dimension = VSIR_DIMENSION_NONE; + else if (dst->reg.type == VKD3DSPR_DEPTHOUT) + dst->reg.dimension = VSIR_DIMENSION_SCALAR; + else + dst->reg.dimension = VSIR_DIMENSION_VEC4; dst->write_mask = (param & VKD3D_SM1_WRITEMASK_MASK) >> VKD3D_SM1_WRITEMASK_SHIFT; dst->modifiers = (param & VKD3D_SM1_DST_MODIFIER_MASK) >> VKD3D_SM1_DST_MODIFIER_SHIFT; dst->shift = (param & VKD3D_SM1_DSTSHIFT_MASK) >> VKD3D_SM1_DSTSHIFT_SHIFT; @@ -853,6 +857,14 @@ static void shader_sm1_skip_opcode(const struct vkd3d_shader_sm1_parser *sm1, co return; } + /* DCL instructions do not have sources or destinations, but they + * read two tokens to a semantic. See + * shader_sm1_read_semantic(). */ + if (opcode_info->vkd3d_opcode == VKD3DSIH_DCL) + { + *ptr += 2; + } + *ptr += (opcode_info->dst_count + opcode_info->src_count); } @@ -951,9 +963,9 @@ static void shader_sm1_read_semantic(struct vkd3d_shader_sm1_parser *sm1, } static void shader_sm1_read_immconst(struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr, - struct vkd3d_shader_src_param *src_param, enum vkd3d_immconst_type type, enum vkd3d_data_type data_type) + struct vkd3d_shader_src_param *src_param, enum vsir_dimension dimension, enum vkd3d_data_type data_type) { - unsigned int count = type == VKD3D_IMMCONST_VEC4 ? 4 : 1; + unsigned int count = dimension == VSIR_DIMENSION_VEC4 ? 4 : 1; if (*ptr >= sm1->end || sm1->end - *ptr < count) { @@ -975,7 +987,7 @@ static void shader_sm1_read_immconst(struct vkd3d_shader_sm1_parser *sm1, const src_param->reg.idx[2].offset = ~0u; src_param->reg.idx[2].rel_addr = NULL; src_param->reg.idx_count = 0; - src_param->reg.immconst_type = type; + src_param->reg.dimension = dimension; memcpy(src_param->reg.u.immconst_uint, *ptr, count * sizeof(uint32_t)); src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE; src_param->modifiers = 0; @@ -1090,7 +1102,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str goto fail; } - ins->handler_idx = opcode_info->vkd3d_opcode; + vsir_instruction_init(ins, &sm1->p.location, opcode_info->vkd3d_opcode); ins->flags = (opcode_token & VKD3D_SM1_INSTRUCTION_FLAGS_MASK) >> VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT; ins->coissue = opcode_token & VKD3D_SM1_COISSUE; ins->raw = false; @@ -1132,19 +1144,19 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str else if (ins->handler_idx == VKD3DSIH_DEF) { shader_sm1_read_dst_param(sm1, &p, dst_param); - shader_sm1_read_immconst(sm1, &p, &src_params[0], VKD3D_IMMCONST_VEC4, VKD3D_DATA_FLOAT); + shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_VEC4, VKD3D_DATA_FLOAT); shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true); } else if (ins->handler_idx == VKD3DSIH_DEFB) { shader_sm1_read_dst_param(sm1, &p, dst_param); - shader_sm1_read_immconst(sm1, &p, &src_params[0], VKD3D_IMMCONST_SCALAR, VKD3D_DATA_UINT); + shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_SCALAR, VKD3D_DATA_UINT); shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true); } else if (ins->handler_idx == VKD3DSIH_DEFI) { shader_sm1_read_dst_param(sm1, &p, dst_param); - shader_sm1_read_immconst(sm1, &p, &src_params[0], VKD3D_IMMCONST_VEC4, VKD3D_DATA_INT); + shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_VEC4, VKD3D_DATA_INT); shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true); } else @@ -1333,12 +1345,22 @@ int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compi ++instructions->count; } - *parser = &sm1->p; - for (i = 0; i < ARRAY_SIZE(sm1->p.shader_desc.flat_constant_count); ++i) sm1->p.shader_desc.flat_constant_count[i].external = get_external_constant_count(sm1, i); - return sm1->p.failed ? VKD3D_ERROR_INVALID_SHADER : VKD3D_OK; + if (!sm1->p.failed) + vsir_validate(&sm1->p); + + if (sm1->p.failed) + { + WARN("Failed to parse shader.\n"); + shader_sm1_destroy(&sm1->p); + return VKD3D_ERROR_INVALID_SHADER; + } + + *parser = &sm1->p; + + return VKD3D_OK; } bool hlsl_sm1_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic, diff --git a/libs/vkd3d/libs/vkd3d-shader/dxbc.c b/libs/vkd3d/libs/vkd3d-shader/dxbc.c index 1cb00688c76..dbbf8a5c458 100644 --- a/libs/vkd3d/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d/libs/vkd3d-shader/dxbc.c @@ -452,7 +452,7 @@ static int isgn_handler(const struct vkd3d_shader_dxbc_section_desc *section, { struct shader_signature *is = ctx; - if (section->tag != TAG_ISGN) + if (section->tag != TAG_ISGN && section->tag != TAG_ISG1) return VKD3D_OK; if (is->elements) diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c index b78c78d34a7..bb50ad62b68 100644 --- a/libs/vkd3d/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c @@ -141,6 +141,7 @@ enum bitcode_value_symtab_code enum dx_intrinsic_opcode { + DX_LOAD_INPUT = 4, DX_STORE_OUTPUT = 5, }; @@ -296,6 +297,7 @@ struct sm6_parser size_t global_symbol_count; struct vkd3d_shader_dst_param *output_params; + struct vkd3d_shader_dst_param *input_params; struct sm6_function *functions; size_t function_count; @@ -304,6 +306,7 @@ struct sm6_parser size_t value_count; size_t value_capacity; size_t cur_max_value; + unsigned int ssa_next_id; struct vkd3d_shader_parser p; }; @@ -1495,7 +1498,7 @@ static unsigned int register_get_uint_value(const struct vkd3d_shader_register * if (!register_is_constant(reg) || !data_type_is_integer(reg->data_type)) return UINT_MAX; - if (reg->immconst_type == VKD3D_IMMCONST_VEC4) + if (reg->dimension == VSIR_DIMENSION_VEC4) WARN("Returning vec4.x.\n"); if (reg->type == VKD3DSPR_IMMCONST64) @@ -1547,6 +1550,11 @@ static inline unsigned int sm6_value_get_constant_uint(const struct sm6_value *v return register_get_uint_value(&value->u.reg); } +static unsigned int sm6_parser_alloc_ssa_id(struct sm6_parser *sm6) +{ + return sm6->ssa_next_id++; +} + static struct vkd3d_shader_src_param *instruction_src_params_alloc(struct vkd3d_shader_instruction *ins, unsigned int count, struct sm6_parser *sm6) { @@ -1579,6 +1587,13 @@ static struct vkd3d_shader_dst_param *instruction_dst_params_alloc(struct vkd3d_ return params; } +static void register_init_with_id(struct vkd3d_shader_register *reg, + enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int id) +{ + vsir_register_init(reg, reg_type, data_type, 1); + reg->idx[0].offset = id; +} + static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type *type) { if (type->class == TYPE_CLASS_INTEGER) @@ -1612,6 +1627,24 @@ static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type return VKD3D_DATA_UINT; } +static void register_init_ssa_scalar(struct vkd3d_shader_register *reg, const struct sm6_type *type, + struct sm6_parser *sm6) +{ + enum vkd3d_data_type data_type; + unsigned int id; + + id = sm6_parser_alloc_ssa_id(sm6); + data_type = vkd3d_data_type_from_sm6_type(sm6_type_get_scalar_type(type, 0)); + register_init_with_id(reg, VKD3DSPR_SSA, data_type, id); +} + +static void dst_param_init(struct vkd3d_shader_dst_param *param) +{ + param->write_mask = VKD3DSP_WRITEMASK_0; + param->modifiers = 0; + param->shift = 0; +} + static inline void dst_param_init_scalar(struct vkd3d_shader_dst_param *param, unsigned int component_idx) { param->write_mask = 1u << component_idx; @@ -1619,12 +1652,25 @@ static inline void dst_param_init_scalar(struct vkd3d_shader_dst_param *param, u param->shift = 0; } +static void dst_param_init_ssa_scalar(struct vkd3d_shader_dst_param *param, const struct sm6_type *type, + struct sm6_parser *sm6) +{ + dst_param_init(param); + register_init_ssa_scalar(¶m->reg, type, sm6); +} + static inline void src_param_init(struct vkd3d_shader_src_param *param) { param->swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); param->modifiers = VKD3DSPSM_NONE; } +static void src_param_init_scalar(struct vkd3d_shader_src_param *param, unsigned int component_idx) +{ + param->swizzle = vkd3d_shader_create_swizzle(component_idx, component_idx, component_idx, component_idx); + param->modifiers = VKD3DSPSM_NONE; +} + static void src_param_init_from_value(struct vkd3d_shader_src_param *param, const struct sm6_value *src) { src_param_init(param); @@ -1653,6 +1699,16 @@ static void register_address_init(struct vkd3d_shader_register *reg, const struc } } +static void instruction_dst_param_init_ssa_scalar(struct vkd3d_shader_instruction *ins, struct sm6_parser *sm6) +{ + struct vkd3d_shader_dst_param *param = instruction_dst_params_alloc(ins, 1, sm6); + struct sm6_value *dst = sm6_parser_get_current_value(sm6); + + dst_param_init_ssa_scalar(param, dst->type, sm6); + param->write_mask = VKD3DSP_WRITEMASK_0; + dst->u.reg = param->reg; +} + /* Recurse through the block tree while maintaining a current value count. The current * count is the sum of the global count plus all declarations within the current function. * Store into value_capacity the highest count seen. */ @@ -1912,7 +1968,7 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const dst->type = type; dst->value_type = VALUE_TYPE_REG; dst->u.reg.type = reg_type; - dst->u.reg.immconst_type = VKD3D_IMMCONST_SCALAR; + dst->u.reg.dimension = VSIR_DIMENSION_SCALAR; dst->u.reg.data_type = reg_data_type; switch (record->code) @@ -1999,7 +2055,7 @@ static struct vkd3d_shader_instruction *sm6_parser_add_instruction(struct sm6_pa { struct vkd3d_shader_instruction *ins = sm6_parser_require_space(sm6, 1); assert(ins); - shader_instruction_init(ins, handler_idx); + vsir_instruction_init(ins, &sm6->p.location, handler_idx); ++sm6->p.instructions.count; return ins; } @@ -2063,7 +2119,7 @@ static void dst_param_io_init(struct vkd3d_shader_dst_param *param, param->shift = 0; /* DXIL types do not have signedness. Load signed elements as unsigned. */ component_type = e->component_type == VKD3D_SHADER_COMPONENT_INT ? VKD3D_SHADER_COMPONENT_UINT : e->component_type; - shader_register_init(¶m->reg, reg_type, vkd3d_data_type_from_component_type(component_type), 0); + vsir_register_init(¶m->reg, reg_type, vkd3d_data_type_from_component_type(component_type), 0); } static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shader_signature *s, @@ -2112,6 +2168,8 @@ static void sm6_parser_emit_signature(struct sm6_parser *sm6, const struct shade param = &ins->declaration.dst; } + /* TODO: set the interpolation mode when signatures are loaded from DXIL metadata. */ + ins->flags = (handler_idx == VKD3DSIH_DCL_INPUT_PS) ? VKD3DSIM_LINEAR_NOPERSPECTIVE : 0; *param = params[i]; } } @@ -2123,11 +2181,24 @@ static void sm6_parser_init_output_signature(struct sm6_parser *sm6, const struc sm6->output_params); } +static void sm6_parser_init_input_signature(struct sm6_parser *sm6, const struct shader_signature *input_signature) +{ + sm6_parser_init_signature(sm6, input_signature, VKD3DSPR_INPUT, sm6->input_params); +} + static void sm6_parser_emit_output_signature(struct sm6_parser *sm6, const struct shader_signature *output_signature) { sm6_parser_emit_signature(sm6, output_signature, VKD3DSIH_DCL_OUTPUT, VKD3DSIH_DCL_OUTPUT_SIV, sm6->output_params); } +static void sm6_parser_emit_input_signature(struct sm6_parser *sm6, const struct shader_signature *input_signature) +{ + sm6_parser_emit_signature(sm6, input_signature, + (sm6->p.shader_version.type == VKD3D_SHADER_TYPE_PIXEL) ? VKD3DSIH_DCL_INPUT_PS : VKD3DSIH_DCL_INPUT, + (sm6->p.shader_version.type == VKD3D_SHADER_TYPE_PIXEL) ? VKD3DSIH_DCL_INPUT_PS_SIV : VKD3DSIH_DCL_INPUT_SIV, + sm6->input_params); +} + static const struct sm6_value *sm6_parser_next_function_definition(struct sm6_parser *sm6) { size_t i, count = sm6->function_count; @@ -2150,6 +2221,38 @@ static struct sm6_block *sm6_block_create() return block; } +static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, struct sm6_block *code_block, + enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct vkd3d_shader_instruction *ins) +{ + struct vkd3d_shader_src_param *src_param; + const struct shader_signature *signature; + unsigned int row_index, column_index; + const struct signature_element *e; + + row_index = sm6_value_get_constant_uint(operands[0]); + column_index = sm6_value_get_constant_uint(operands[2]); + + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + + signature = &sm6->p.shader_desc.input_signature; + if (row_index >= signature->element_count) + { + WARN("Invalid row index %u.\n", row_index); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Invalid input row index %u.", row_index); + return; + } + e = &signature->elements[row_index]; + + src_param = instruction_src_params_alloc(ins, 1, sm6); + src_param->reg = sm6->input_params[row_index].reg; + src_param_init_scalar(src_param, column_index); + if (e->register_count > 1) + register_address_init(&src_param->reg, operands[1], 0, sm6); + + instruction_dst_param_init_ssa_scalar(ins, sm6); +} + static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, struct sm6_block *code_block, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct vkd3d_shader_instruction *ins) { @@ -2190,7 +2293,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, struct sm6_b return; } - shader_instruction_init(ins, VKD3DSIH_MOV); + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); if (!(dst_param = instruction_dst_params_alloc(ins, 1, sm6))) return; @@ -2219,6 +2322,7 @@ struct sm6_dx_opcode_info */ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = { + [DX_LOAD_INPUT ] = {'o', "ii8i", sm6_parser_emit_dx_load_input}, [DX_STORE_OUTPUT ] = {'v', "ii8o", sm6_parser_emit_dx_store_output}, }; @@ -2292,7 +2396,7 @@ static void sm6_parser_emit_unhandled(struct sm6_parser *sm6, struct vkd3d_shade return; type = sm6_type_get_scalar_type(dst->type, 0); - shader_register_init(&dst->u.reg, VKD3DSPR_UNDEF, vkd3d_data_type_from_sm6_type(type), 0); + vsir_register_init(&dst->u.reg, VKD3DSPR_UNDEF, vkd3d_data_type_from_sm6_type(type), 0); /* dst->is_undefined is not set here because it flags only explicitly undefined values. */ } @@ -2303,7 +2407,7 @@ static void sm6_parser_decode_dx_op(struct sm6_parser *sm6, struct sm6_block *co if (op >= ARRAY_SIZE(sm6_dx_op_table) || !sm6_dx_op_table[op].operand_info) { FIXME("Unhandled dx intrinsic function id %u, '%s'.\n", op, name); - vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_UNHANDLED_INTRINSIC, + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_UNHANDLED_INTRINSIC, "Call to intrinsic function %s is unhandled.", name); sm6_parser_emit_unhandled(sm6, ins, dst); return; @@ -2418,11 +2522,11 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const struct sm6_function *function) { struct vkd3d_shader_instruction *ins; + size_t i, block_idx, block_count; const struct dxil_record *record; bool ret_found, is_terminator; struct sm6_block *code_block; struct sm6_value *dst; - size_t i, block_idx; if (sm6->function_count) { @@ -2448,12 +2552,12 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const return VKD3D_ERROR_INVALID_SHADER; } - if (!(function->block_count = block->records[0]->operands[0])) + if (!(block_count = block->records[0]->operands[0])) { WARN("Function contains no blocks.\n"); return VKD3D_ERROR_INVALID_SHADER; } - if (function->block_count > 1) + if (block_count > 1) { FIXME("Branched shaders are not supported yet.\n"); return VKD3D_ERROR_INVALID_SHADER; @@ -2464,6 +2568,7 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const ERR("Failed to allocate code block.\n"); return VKD3D_ERROR_OUT_OF_MEMORY; } + function->block_count = block_count; code_block = function->blocks[0]; sm6->cur_max_value = function->value_count; @@ -2683,6 +2788,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t const char *source_name, struct vkd3d_shader_message_context *message_context) { const struct shader_signature *output_signature = &sm6->p.shader_desc.output_signature; + const struct shader_signature *input_signature = &sm6->p.shader_desc.input_signature; const struct vkd3d_shader_location location = {.source_name = source_name}; uint32_t version_token, dxil_version, token_count, magic; unsigned int chunk_offset, chunk_size; @@ -2838,11 +2944,12 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t return ret; } - if (!(sm6->output_params = shader_parser_get_dst_params(&sm6->p, output_signature->element_count))) + if (!(sm6->output_params = shader_parser_get_dst_params(&sm6->p, output_signature->element_count)) + || !(sm6->input_params = shader_parser_get_dst_params(&sm6->p, input_signature->element_count))) { - ERR("Failed to allocate output parameters.\n"); + ERR("Failed to allocate input/output parameters.\n"); vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, - "Out of memory allocating output parameters."); + "Out of memory allocating input/output parameters."); return VKD3D_ERROR_OUT_OF_MEMORY; } @@ -2869,6 +2976,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t "Out of memory allocating DXIL value array."); return VKD3D_ERROR_OUT_OF_MEMORY; } + sm6->ssa_next_id = 1; if ((ret = sm6_parser_globals_init(sm6)) < 0) { @@ -2877,6 +2985,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t } sm6_parser_init_output_signature(sm6, output_signature); + sm6_parser_init_input_signature(sm6, input_signature); if ((ret = sm6_parser_module_init(sm6, &sm6->root_block, 0)) < 0) { @@ -2889,13 +2998,16 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t return ret; } - if (!sm6_parser_require_space(sm6, output_signature->element_count)) + if (!sm6_parser_require_space(sm6, output_signature->element_count + input_signature->element_count)) { vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, "Out of memory emitting shader signature declarations."); return VKD3D_ERROR_OUT_OF_MEMORY; } sm6_parser_emit_output_signature(sm6, output_signature); + sm6_parser_emit_input_signature(sm6, input_signature); + + sm6->p.shader_desc.ssa_count = sm6->ssa_next_id; for (i = 0; i < sm6->function_count; ++i) { @@ -2955,6 +3067,12 @@ int vkd3d_shader_sm6_parser_create(const struct vkd3d_shader_compile_info *compi compile_info->source_name, message_context); vkd3d_free(byte_code); + if (!sm6->p.failed && ret >= 0) + vsir_validate(&sm6->p); + + if (sm6->p.failed && ret >= 0) + ret = VKD3D_ERROR_INVALID_SHADER; + if (ret < 0) { WARN("Failed to initialise shader parser.\n"); diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c index 5fe9047bf25..b42e30888a9 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c @@ -216,13 +216,15 @@ bool hlsl_type_is_resource(const struct hlsl_type *type) return false; } -enum hlsl_regset hlsl_type_get_regset(const struct hlsl_type *type) +/* Only intended to be used for derefs (after copies have been lowered to components or vectors) or + * resources, since for both their data types span across a single regset. */ +static enum hlsl_regset type_get_regset(const struct hlsl_type *type) { if (type->class <= HLSL_CLASS_LAST_NUMERIC) return HLSL_REGSET_NUMERIC; if (type->class == HLSL_CLASS_ARRAY) - return hlsl_type_get_regset(type->e.array.type); + return type_get_regset(type->e.array.type); if (type->class == HLSL_CLASS_OBJECT) { @@ -245,6 +247,18 @@ enum hlsl_regset hlsl_type_get_regset(const struct hlsl_type *type) vkd3d_unreachable(); } +enum hlsl_regset hlsl_deref_get_regset(struct hlsl_ctx *ctx, const struct hlsl_deref *deref) +{ + struct hlsl_type *type; + + if (deref->data_type) + type = deref->data_type; + else + type = hlsl_deref_get_type(ctx, deref); + + return type_get_regset(type); +} + unsigned int hlsl_type_get_sm4_offset(const struct hlsl_type *type, unsigned int offset) { /* Align to the next vec4 boundary if: @@ -324,7 +338,7 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type { if (hlsl_type_is_resource(type)) { - enum hlsl_regset regset = hlsl_type_get_regset(type); + enum hlsl_regset regset = type_get_regset(type); type->reg_size[regset] = 1; } @@ -452,11 +466,11 @@ struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl } unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_type *type, - enum hlsl_regset regset, unsigned int index) + unsigned int index, enum hlsl_regset *regset) { + unsigned int offset[HLSL_REGSET_LAST + 1] = {0}; struct hlsl_type *next_type; - unsigned int offset = 0; - unsigned int idx; + unsigned int idx, r; while (!type_is_single_component(type)) { @@ -468,19 +482,22 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty case HLSL_CLASS_SCALAR: case HLSL_CLASS_VECTOR: case HLSL_CLASS_MATRIX: - if (regset == HLSL_REGSET_NUMERIC) - offset += idx; + offset[HLSL_REGSET_NUMERIC] += idx; break; case HLSL_CLASS_STRUCT: - offset += type->e.record.fields[idx].reg_offset[regset]; + for (r = 0; r <= HLSL_REGSET_LAST; ++r) + offset[r] += type->e.record.fields[idx].reg_offset[r]; break; case HLSL_CLASS_ARRAY: - if (regset == HLSL_REGSET_NUMERIC) - offset += idx * align(type->e.array.type->reg_size[regset], 4); - else - offset += idx * type->e.array.type->reg_size[regset]; + for (r = 0; r <= HLSL_REGSET_LAST; ++r) + { + if (r == HLSL_REGSET_NUMERIC) + offset[r] += idx * align(type->e.array.type->reg_size[r], 4); + else + offset[r] += idx * type->e.array.type->reg_size[r]; + } break; case HLSL_CLASS_OBJECT: @@ -493,7 +510,8 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty type = next_type; } - return offset; + *regset = type_get_regset(type); + return offset[*regset]; } static bool init_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_var *var, @@ -2193,6 +2211,10 @@ struct vkd3d_string_buffer *hlsl_modifiers_to_string(struct hlsl_ctx *ctx, unsig vkd3d_string_buffer_printf(string, "extern "); if (modifiers & HLSL_STORAGE_NOINTERPOLATION) vkd3d_string_buffer_printf(string, "nointerpolation "); + if (modifiers & HLSL_STORAGE_CENTROID) + vkd3d_string_buffer_printf(string, "centroid "); + if (modifiers & HLSL_STORAGE_NOPERSPECTIVE) + vkd3d_string_buffer_printf(string, "noperspective "); if (modifiers & HLSL_MODIFIER_PRECISE) vkd3d_string_buffer_printf(string, "precise "); if (modifiers & HLSL_STORAGE_SHARED) @@ -2540,6 +2562,10 @@ static void dump_ir_jump(struct vkd3d_string_buffer *buffer, const struct hlsl_i case HLSL_IR_JUMP_RETURN: vkd3d_string_buffer_printf(buffer, "return"); break; + + case HLSL_IR_JUMP_UNRESOLVED_CONTINUE: + vkd3d_string_buffer_printf(buffer, "unresolved_continue"); + break; } } diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h index 743a746f2bf..29259767104 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h @@ -21,13 +21,10 @@ #define __VKD3D_SHADER_HLSL_H #include "vkd3d_shader_private.h" -#include "wine/rbtree.h" +#include "rbtree.h" #include "d3dcommon.h" #include "d3dx9shader.h" -enum vkd3d_sm4_register_type; -enum vkd3d_sm4_swizzle_type; - /* The general IR structure is inspired by Mesa GLSL hir, even though the code * ends up being quite different in practice. Anyway, here comes the relevant * licensing information. @@ -357,11 +354,16 @@ struct hlsl_attribute #define HLSL_STORAGE_IN 0x00000800 #define HLSL_STORAGE_OUT 0x00001000 #define HLSL_MODIFIER_INLINE 0x00002000 +#define HLSL_STORAGE_CENTROID 0x00004000 +#define HLSL_STORAGE_NOPERSPECTIVE 0x00008000 #define HLSL_TYPE_MODIFIERS_MASK (HLSL_MODIFIER_PRECISE | HLSL_MODIFIER_VOLATILE | \ HLSL_MODIFIER_CONST | HLSL_MODIFIER_ROW_MAJOR | \ HLSL_MODIFIER_COLUMN_MAJOR) +#define HLSL_INTERPOLATION_MODIFIERS_MASK (HLSL_STORAGE_NOINTERPOLATION | HLSL_STORAGE_CENTROID | \ + HLSL_STORAGE_NOPERSPECTIVE) + #define HLSL_MODIFIERS_MAJORITY_MASK (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR) #define HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT 0 @@ -577,6 +579,10 @@ enum hlsl_ir_jump_type HLSL_IR_JUMP_DISCARD_NEG, HLSL_IR_JUMP_DISCARD_NZ, HLSL_IR_JUMP_RETURN, + /* UNRESOLVED_CONTINUE type is used by the parser when 'continue' statement is found, + it never reaches code generation, and is resolved to CONTINUE type once iteration + and loop exit logic was properly applied. */ + HLSL_IR_JUMP_UNRESOLVED_CONTINUE, }; struct hlsl_ir_jump @@ -702,6 +708,8 @@ struct hlsl_scope struct rb_tree types; /* Scope containing this scope. This value is NULL for the global scope. */ struct hlsl_scope *upper; + /* The scope was created for the loop statement. */ + bool loop; }; struct hlsl_profile_info @@ -1232,13 +1240,12 @@ unsigned int hlsl_type_get_array_element_reg_size(const struct hlsl_type *type, struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl_type *type, unsigned int index); unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_type *type, - enum hlsl_regset regset, unsigned int index); + unsigned int index, enum hlsl_regset *regset); bool hlsl_type_is_row_major(const struct hlsl_type *type); unsigned int hlsl_type_minor_size(const struct hlsl_type *type); unsigned int hlsl_type_major_size(const struct hlsl_type *type); unsigned int hlsl_type_element_count(const struct hlsl_type *type); bool hlsl_type_is_resource(const struct hlsl_type *type); -enum hlsl_regset hlsl_type_get_regset(const struct hlsl_type *type); unsigned int hlsl_type_get_sm4_offset(const struct hlsl_type *type, unsigned int offset); bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2); @@ -1251,6 +1258,7 @@ unsigned int hlsl_map_swizzle(unsigned int swizzle, unsigned int writemask); unsigned int hlsl_swizzle_from_writemask(unsigned int writemask); struct hlsl_type *hlsl_deref_get_type(struct hlsl_ctx *ctx, const struct hlsl_deref *deref); +enum hlsl_regset hlsl_deref_get_regset(struct hlsl_ctx *ctx, const struct hlsl_deref *deref); bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, unsigned int *start, unsigned int *count); bool hlsl_regset_index_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, @@ -1273,7 +1281,7 @@ int hlsl_sm1_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun bool hlsl_sm4_usage_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic, bool output, D3D_NAME *usage); bool hlsl_sm4_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic, - bool output, enum vkd3d_shader_register_type *type, enum vkd3d_sm4_swizzle_type *swizzle_type, bool *has_idx); + bool output, enum vkd3d_shader_register_type *type, bool *has_idx); int hlsl_sm4_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out); struct hlsl_ir_function_decl *hlsl_compile_internal_function(struct hlsl_ctx *ctx, const char *name, const char *hlsl); diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.l b/libs/vkd3d/libs/vkd3d-shader/hlsl.l index e9ae3ccf3d3..90abd64a3c6 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.l +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.l @@ -74,6 +74,7 @@ BlendState {return KW_BLENDSTATE; } break {return KW_BREAK; } Buffer {return KW_BUFFER; } cbuffer {return KW_CBUFFER; } +centroid {return KW_CENTROID; } compile {return KW_COMPILE; } const {return KW_CONST; } continue {return KW_CONTINUE; } @@ -95,6 +96,7 @@ inout {return KW_INOUT; } matrix {return KW_MATRIX; } namespace {return KW_NAMESPACE; } nointerpolation {return KW_NOINTERPOLATION; } +noperspective {return KW_NOPERSPECTIVE; } out {return KW_OUT; } packoffset {return KW_PACKOFFSET; } pass {return KW_PASS; } diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y index fb6d485ea69..ba738473ffd 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y @@ -464,6 +464,50 @@ static bool attribute_list_has_duplicates(const struct parse_attribute_list *att return false; } +static void resolve_loop_continue(struct hlsl_ctx *ctx, struct hlsl_block *block, enum loop_type type, + struct hlsl_block *cond, struct hlsl_block *iter) +{ + struct hlsl_ir_node *instr, *next; + + LIST_FOR_EACH_ENTRY_SAFE(instr, next, &block->instrs, struct hlsl_ir_node, entry) + { + if (instr->type == HLSL_IR_IF) + { + struct hlsl_ir_if *iff = hlsl_ir_if(instr); + + resolve_loop_continue(ctx, &iff->then_block, type, cond, iter); + resolve_loop_continue(ctx, &iff->else_block, type, cond, iter); + } + else if (instr->type == HLSL_IR_JUMP) + { + struct hlsl_ir_jump *jump = hlsl_ir_jump(instr); + struct hlsl_block block; + + if (jump->type != HLSL_IR_JUMP_UNRESOLVED_CONTINUE) + continue; + + if (type == LOOP_DO_WHILE) + { + if (!hlsl_clone_block(ctx, &block, cond)) + return; + if (!append_conditional_break(ctx, &block)) + { + hlsl_block_cleanup(&block); + return; + } + list_move_before(&instr->entry, &block.instrs); + } + else if (type == LOOP_FOR) + { + if (!hlsl_clone_block(ctx, &block, iter)) + return; + list_move_before(&instr->entry, &block.instrs); + } + jump->type = HLSL_IR_JUMP_CONTINUE; + } + } +} + static struct hlsl_block *create_loop(struct hlsl_ctx *ctx, enum loop_type type, const struct parse_attribute_list *attributes, struct hlsl_block *init, struct hlsl_block *cond, struct hlsl_block *iter, struct hlsl_block *body, const struct vkd3d_shader_location *loc) @@ -501,6 +545,8 @@ static struct hlsl_block *create_loop(struct hlsl_ctx *ctx, enum loop_type type, } } + resolve_loop_continue(ctx, body, type, cond, iter); + if (!init && !(init = make_empty_block(ctx))) goto oom; @@ -2961,6 +3007,33 @@ static bool intrinsic_frac(struct hlsl_ctx *ctx, return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_FRACT, arg, loc); } +static bool intrinsic_fwidth(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_function_decl *func; + struct hlsl_type *type; + char *body; + + static const char template[] = + "%s fwidth(%s x)\n" + "{\n" + " return abs(ddx(x)) + abs(ddy(x));\n" + "}"; + + if (!elementwise_intrinsic_float_convert_args(ctx, params, loc)) + return false; + type = params->args[0]->data_type; + + if (!(body = hlsl_sprintf_alloc(ctx, template, type->name, type->name))) + return false; + func = hlsl_compile_internal_function(ctx, "fwidth", body); + vkd3d_free(body); + if (!func) + return false; + + return add_user_call(ctx, func, params, loc); +} + static bool intrinsic_ldexp(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -3423,6 +3496,20 @@ static bool intrinsic_step(struct hlsl_ctx *ctx, return !!add_implicit_conversion(ctx, params->instrs, ge, type, loc); } +static bool intrinsic_tan(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *arg = params->args[0], *sin, *cos; + + if (!(sin = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_SIN, arg, loc))) + return false; + + if (!(cos = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_COS, arg, loc))) + return false; + + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_DIV, sin, cos, loc); +} + static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc, const char *name, enum hlsl_sampler_dim dim) { @@ -3676,6 +3763,7 @@ intrinsic_functions[] = {"floor", 1, true, intrinsic_floor}, {"fmod", 2, true, intrinsic_fmod}, {"frac", 1, true, intrinsic_frac}, + {"fwidth", 1, true, intrinsic_fwidth}, {"ldexp", 2, true, intrinsic_ldexp}, {"length", 1, true, intrinsic_length}, {"lerp", 3, true, intrinsic_lerp}, @@ -3697,6 +3785,7 @@ intrinsic_functions[] = {"smoothstep", 3, true, intrinsic_smoothstep}, {"sqrt", 1, true, intrinsic_sqrt}, {"step", 2, true, intrinsic_step}, + {"tan", 1, true, intrinsic_tan}, {"tex1D", -1, false, intrinsic_tex1D}, {"tex2D", -1, false, intrinsic_tex2D}, {"tex3D", -1, false, intrinsic_tex3D}, @@ -4544,6 +4633,14 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type } } +static struct hlsl_scope *get_loop_scope(struct hlsl_scope *scope) +{ + if (scope->loop) + return scope; + + return scope->upper ? get_loop_scope(scope->upper) : NULL; +} + } %locations @@ -4588,6 +4685,7 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type %token KW_BREAK %token KW_BUFFER %token KW_CBUFFER +%token KW_CENTROID %token KW_COLUMN_MAJOR %token KW_COMPILE %token KW_CONST @@ -4610,6 +4708,7 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type %token KW_MATRIX %token KW_NAMESPACE %token KW_NOINTERPOLATION +%token KW_NOPERSPECTIVE %token KW_OUT %token KW_PACKOFFSET %token KW_PASS @@ -4952,7 +5051,7 @@ field: if (!(type = apply_type_modifiers(ctx, $2, &modifiers, true, &@1))) YYABORT; - if (modifiers & ~HLSL_STORAGE_NOINTERPOLATION) + if (modifiers & ~HLSL_INTERPOLATION_MODIFIERS_MASK) { struct vkd3d_string_buffer *string; @@ -5249,6 +5348,13 @@ scope_start: hlsl_push_scope(ctx); } +loop_scope_start: + %empty + { + hlsl_push_scope(ctx); + ctx->cur_scope->loop = true; + } + var_identifier: VAR_IDENTIFIER | NEW_IDENTIFIER @@ -5901,6 +6007,14 @@ var_modifiers: { $$ = add_modifiers(ctx, $2, HLSL_STORAGE_NOINTERPOLATION, &@1); } + | KW_CENTROID var_modifiers + { + $$ = add_modifiers(ctx, $2, HLSL_STORAGE_CENTROID, &@1); + } + | KW_NOPERSPECTIVE var_modifiers + { + $$ = add_modifiers(ctx, $2, HLSL_STORAGE_NOPERSPECTIVE, &@1); + } | KW_PRECISE var_modifiers { $$ = add_modifiers(ctx, $2, HLSL_MODIFIER_PRECISE, &@1); @@ -6061,7 +6175,43 @@ statement: | loop_statement jump_statement: - KW_RETURN expr ';' + KW_BREAK ';' + { + struct hlsl_ir_node *jump; + + /* TODO: allow 'break' in the 'switch' statements. */ + + if (!get_loop_scope(ctx->cur_scope)) + { + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, + "The 'break' statement must be used inside of a loop."); + } + + if (!($$ = make_empty_block(ctx))) + YYABORT; + if (!(jump = hlsl_new_jump(ctx, HLSL_IR_JUMP_BREAK, NULL, &@1))) + YYABORT; + hlsl_block_add_instr($$, jump); + } + | KW_CONTINUE ';' + { + struct hlsl_ir_node *jump; + struct hlsl_scope *scope; + + if (!(scope = get_loop_scope(ctx->cur_scope))) + { + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, + "The 'continue' statement must be used inside of a loop."); + } + + if (!($$ = make_empty_block(ctx))) + YYABORT; + + if (!(jump = hlsl_new_jump(ctx, HLSL_IR_JUMP_UNRESOLVED_CONTINUE, NULL, &@1))) + YYABORT; + hlsl_block_add_instr($$, jump); + } + | KW_RETURN expr ';' { $$ = $2; if (!add_return(ctx, $$, node_from_block($$), &@1)) @@ -6150,22 +6300,24 @@ if_body: } loop_statement: - attribute_list_optional KW_WHILE '(' expr ')' statement + attribute_list_optional loop_scope_start KW_WHILE '(' expr ')' statement { - $$ = create_loop(ctx, LOOP_WHILE, &$1, NULL, $4, NULL, $6, &@2); + $$ = create_loop(ctx, LOOP_WHILE, &$1, NULL, $5, NULL, $7, &@3); + hlsl_pop_scope(ctx); } - | attribute_list_optional KW_DO statement KW_WHILE '(' expr ')' ';' + | attribute_list_optional loop_scope_start KW_DO statement KW_WHILE '(' expr ')' ';' { - $$ = create_loop(ctx, LOOP_DO_WHILE, &$1, NULL, $6, NULL, $3, &@2); + $$ = create_loop(ctx, LOOP_DO_WHILE, &$1, NULL, $7, NULL, $4, &@3); + hlsl_pop_scope(ctx); } - | attribute_list_optional KW_FOR '(' scope_start expr_statement expr_statement expr_optional ')' statement + | attribute_list_optional loop_scope_start KW_FOR '(' expr_statement expr_statement expr_optional ')' statement { - $$ = create_loop(ctx, LOOP_FOR, &$1, $5, $6, $7, $9, &@2); + $$ = create_loop(ctx, LOOP_FOR, &$1, $5, $6, $7, $9, &@3); hlsl_pop_scope(ctx); } - | attribute_list_optional KW_FOR '(' scope_start declaration expr_statement expr_optional ')' statement + | attribute_list_optional loop_scope_start KW_FOR '(' declaration expr_statement expr_optional ')' statement { - $$ = create_loop(ctx, LOOP_FOR, &$1, $5, $6, $7, $9, &@2); + $$ = create_loop(ctx, LOOP_FOR, &$1, $5, $6, $7, $9, &@3); hlsl_pop_scope(ctx); } diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c index be024842164..5c816e89523 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c @@ -97,7 +97,7 @@ static struct hlsl_ir_node *new_offset_from_path_index(struct hlsl_ctx *ctx, str static struct hlsl_ir_node *new_offset_instr_from_deref(struct hlsl_ctx *ctx, struct hlsl_block *block, const struct hlsl_deref *deref, const struct vkd3d_shader_location *loc) { - enum hlsl_regset regset = hlsl_type_get_regset(deref->data_type); + enum hlsl_regset regset = hlsl_deref_get_regset(ctx, deref); struct hlsl_ir_node *offset = NULL; struct hlsl_type *type; unsigned int i; @@ -377,6 +377,8 @@ static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block * for (i = 0; i < hlsl_type_element_count(type); ++i) { + unsigned int element_modifiers = modifiers; + if (type->class == HLSL_CLASS_ARRAY) { elem_semantic_index = semantic_index @@ -391,6 +393,17 @@ static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block * semantic = &field->semantic; elem_semantic_index = semantic->index; loc = &field->loc; + element_modifiers |= field->storage_modifiers; + + /* TODO: 'sample' modifier is not supported yet */ + + /* 'nointerpolation' always takes precedence, next the same is done for 'sample', + remaining modifiers are combined. */ + if (element_modifiers & HLSL_STORAGE_NOINTERPOLATION) + { + element_modifiers &= ~HLSL_INTERPOLATION_MODIFIERS_MASK; + element_modifiers |= HLSL_STORAGE_NOINTERPOLATION; + } } if (!(c = hlsl_new_uint_constant(ctx, i, &var->loc))) @@ -402,7 +415,7 @@ static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block * return; list_add_after(&c->entry, &element_load->node.entry); - prepend_input_copy_recurse(ctx, block, element_load, modifiers, semantic, elem_semantic_index); + prepend_input_copy_recurse(ctx, block, element_load, element_modifiers, semantic, elem_semantic_index); } } else @@ -989,7 +1002,7 @@ static bool lower_matrix_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins * For the latter case, this pass takes care of lowering hlsl_ir_indexes into individual * hlsl_ir_loads, or individual hlsl_ir_resource_loads, in case the indexing is a * resource access. */ -static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *val, *store; struct hlsl_deref var_deref; @@ -1023,8 +1036,7 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, if (!(load = hlsl_new_resource_load(ctx, ¶ms, &instr->loc))) return false; - list_add_before(&instr->entry, &load->entry); - hlsl_replace_node(instr, load); + hlsl_block_add_instr(block, load); return true; } @@ -1034,7 +1046,7 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, if (!(store = hlsl_new_simple_store(ctx, var, val))) return false; - list_add_before(&instr->entry, &store->entry); + hlsl_block_add_instr(block, store); if (hlsl_index_is_noncontiguous(index)) { @@ -1054,38 +1066,36 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, if (!(c = hlsl_new_uint_constant(ctx, i, &instr->loc))) return false; - list_add_before(&instr->entry, &c->entry); + hlsl_block_add_instr(block, c); if (!(load = hlsl_new_load_index(ctx, &var_deref, c, &instr->loc))) return false; - list_add_before(&instr->entry, &load->node.entry); + hlsl_block_add_instr(block, &load->node); if (!(load = hlsl_new_load_index(ctx, &load->src, index->idx.node, &instr->loc))) return false; - list_add_before(&instr->entry, &load->node.entry); + hlsl_block_add_instr(block, &load->node); if (!(store = hlsl_new_store_index(ctx, &row_deref, c, &load->node, 0, &instr->loc))) return false; - list_add_before(&instr->entry, &store->entry); + hlsl_block_add_instr(block, store); } if (!(load = hlsl_new_var_load(ctx, var, &instr->loc))) return false; - list_add_before(&instr->entry, &load->node.entry); - hlsl_replace_node(instr, &load->node); + hlsl_block_add_instr(block, &load->node); } else { if (!(load = hlsl_new_load_index(ctx, &var_deref, index->idx.node, &instr->loc))) return false; - list_add_before(&instr->entry, &load->node.entry); - hlsl_replace_node(instr, &load->node); + hlsl_block_add_instr(block, &load->node); } return true; } /* Lower casts from vec1 to vecN to swizzles. */ -static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { const struct hlsl_type *src_type, *dst_type; struct hlsl_type *dst_scalar_type; @@ -1101,25 +1111,22 @@ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, v if (src_type->class <= HLSL_CLASS_VECTOR && dst_type->class <= HLSL_CLASS_VECTOR && src_type->dimx == 1) { - struct hlsl_ir_node *replacement, *new_cast, *swizzle; + struct hlsl_ir_node *new_cast, *swizzle; dst_scalar_type = hlsl_get_scalar_type(ctx, dst_type->base_type); /* We need to preserve the cast since it might be doing more than just * turning the scalar into a vector. */ if (!(new_cast = hlsl_new_cast(ctx, cast->operands[0].node, dst_scalar_type, &cast->node.loc))) return false; - list_add_after(&cast->node.entry, &new_cast->entry); - replacement = new_cast; + hlsl_block_add_instr(block, new_cast); if (dst_type->dimx != 1) { - if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X), dst_type->dimx, replacement, &cast->node.loc))) + if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X), dst_type->dimx, new_cast, &cast->node.loc))) return false; - list_add_after(&new_cast->entry, &swizzle->entry); - replacement = swizzle; + hlsl_block_add_instr(block, swizzle); } - hlsl_replace_node(&cast->node, replacement); return true; } @@ -1981,7 +1988,7 @@ static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr return true; } -static bool lower_narrowing_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +static bool lower_narrowing_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { const struct hlsl_type *src_type, *dst_type; struct hlsl_type *dst_vector_type; @@ -2004,12 +2011,12 @@ static bool lower_narrowing_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins * narrowing the vector. */ if (!(new_cast = hlsl_new_cast(ctx, cast->operands[0].node, dst_vector_type, &cast->node.loc))) return false; - list_add_after(&cast->node.entry, &new_cast->entry); + hlsl_block_add_instr(block, new_cast); + if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, Y, Z, W), dst_type->dimx, new_cast, &cast->node.loc))) return false; - list_add_after(&new_cast->entry, &swizzle->entry); + hlsl_block_add_instr(block, swizzle); - hlsl_replace_node(&cast->node, swizzle); return true; } @@ -2068,7 +2075,26 @@ static bool remove_trivial_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *i return true; } -static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +static bool remove_trivial_conditional_branches(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_ir_constant *condition; + struct hlsl_ir_if *iff; + + if (instr->type != HLSL_IR_IF) + return false; + iff = hlsl_ir_if(instr); + if (iff->condition.node->type != HLSL_IR_CONSTANT) + return false; + condition = hlsl_ir_constant(iff->condition.node); + + list_move_before(&instr->entry, condition->value.u[0].u ? &iff->then_block.instrs : &iff->else_block.instrs); + list_remove(&instr->entry); + hlsl_free_instr(instr); + + return true; +} + +static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *idx; struct hlsl_deref *deref; @@ -2099,11 +2125,11 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir if (!(vector_load = hlsl_new_load_parent(ctx, deref, &instr->loc))) return false; - list_add_before(&instr->entry, &vector_load->node.entry); + hlsl_block_add_instr(block, &vector_load->node); if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X), type->dimx, idx, &instr->loc))) return false; - list_add_before(&instr->entry, &swizzle->entry); + hlsl_block_add_instr(block, swizzle); value.u[0].u = 0; value.u[1].u = 1; @@ -2111,18 +2137,18 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir value.u[3].u = 3; if (!(c = hlsl_new_constant(ctx, hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, type->dimx), &value, &instr->loc))) return false; - list_add_before(&instr->entry, &c->entry); + hlsl_block_add_instr(block, c); operands[0] = swizzle; operands[1] = c; if (!(eq = hlsl_new_expr(ctx, HLSL_OP2_EQUAL, operands, hlsl_get_vector_type(ctx, HLSL_TYPE_BOOL, type->dimx), &instr->loc))) return false; - list_add_before(&instr->entry, &eq->entry); + hlsl_block_add_instr(block, eq); if (!(eq = hlsl_new_cast(ctx, eq, type, &instr->loc))) return false; - list_add_before(&instr->entry, &eq->entry); + hlsl_block_add_instr(block, eq); op = HLSL_OP2_DOT; if (type->dimx == 1) @@ -2134,8 +2160,7 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir operands[1] = eq; if (!(dot = hlsl_new_expr(ctx, op, operands, instr->data_type, &instr->loc))) return false; - list_add_before(&instr->entry, &dot->entry); - hlsl_replace_node(instr, dot); + hlsl_block_add_instr(block, dot); return true; } @@ -2184,7 +2209,7 @@ static bool lower_combined_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *in return false; } - assert(hlsl_type_get_regset(load->resource.var->data_type) == HLSL_REGSET_SAMPLERS); + assert(hlsl_deref_get_regset(ctx, &load->resource) == HLSL_REGSET_SAMPLERS); if (!(name = hlsl_get_string_buffer(ctx))) return false; @@ -2275,10 +2300,10 @@ static bool sort_synthetic_separated_samplers_first(struct hlsl_ctx *ctx) } /* Lower DIV to RCP + MUL. */ -static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { + struct hlsl_ir_node *rcp, *mul; struct hlsl_ir_expr *expr; - struct hlsl_ir_node *rcp; if (instr->type != HLSL_IR_EXPR) return false; @@ -2288,18 +2313,20 @@ static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, voi if (!(rcp = hlsl_new_unary_expr(ctx, HLSL_OP1_RCP, expr->operands[1].node, &instr->loc))) return false; - list_add_before(&expr->node.entry, &rcp->entry); - expr->op = HLSL_OP2_MUL; - hlsl_src_remove(&expr->operands[1]); - hlsl_src_from_node(&expr->operands[1], rcp); + hlsl_block_add_instr(block, rcp); + + if (!(mul = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, expr->operands[0].node, rcp))) + return false; + hlsl_block_add_instr(block, mul); + return true; } /* Lower SQRT to RSQ + RCP. */ -static bool lower_sqrt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +static bool lower_sqrt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { + struct hlsl_ir_node *rsq, *rcp; struct hlsl_ir_expr *expr; - struct hlsl_ir_node *rsq; if (instr->type != HLSL_IR_EXPR) return false; @@ -2309,15 +2336,16 @@ static bool lower_sqrt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *c if (!(rsq = hlsl_new_unary_expr(ctx, HLSL_OP1_RSQ, expr->operands[0].node, &instr->loc))) return false; - list_add_before(&expr->node.entry, &rsq->entry); - expr->op = HLSL_OP1_RCP; - hlsl_src_remove(&expr->operands[0]); - hlsl_src_from_node(&expr->operands[0], rsq); + hlsl_block_add_instr(block, rsq); + + if (!(rcp = hlsl_new_unary_expr(ctx, HLSL_OP1_RCP, rsq, &instr->loc))) + return false; + hlsl_block_add_instr(block, rcp); return true; } /* Lower DP2 to MUL + ADD */ -static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *arg1, *arg2, *mul, *replacement, *zero, *add_x, *add_y; struct hlsl_ir_expr *expr; @@ -2338,7 +2366,7 @@ static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *co if (!(zero = hlsl_new_float_constant(ctx, 0.0f, &expr->node.loc))) return false; - list_add_before(&instr->entry, &zero->entry); + hlsl_block_add_instr(block, zero); operands[0] = arg1; operands[1] = arg2; @@ -2351,27 +2379,26 @@ static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *co { if (!(mul = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, expr->operands[0].node, expr->operands[1].node))) return false; - list_add_before(&instr->entry, &mul->entry); + hlsl_block_add_instr(block, mul); if (!(add_x = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X), instr->data_type->dimx, mul, &expr->node.loc))) return false; - list_add_before(&instr->entry, &add_x->entry); + hlsl_block_add_instr(block, add_x); if (!(add_y = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Y, Y, Y, Y), instr->data_type->dimx, mul, &expr->node.loc))) return false; - list_add_before(&instr->entry, &add_y->entry); + hlsl_block_add_instr(block, add_y); if (!(replacement = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, add_x, add_y))) return false; } - list_add_before(&instr->entry, &replacement->entry); + hlsl_block_add_instr(block, replacement); - hlsl_replace_node(instr, replacement); return true; } /* Lower ABS to MAX */ -static bool lower_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +static bool lower_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *arg, *neg, *replacement; struct hlsl_ir_expr *expr; @@ -2385,18 +2412,17 @@ static bool lower_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *co if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg, &instr->loc))) return false; - list_add_before(&instr->entry, &neg->entry); + hlsl_block_add_instr(block, neg); if (!(replacement = hlsl_new_binary_expr(ctx, HLSL_OP2_MAX, neg, arg))) return false; - list_add_before(&instr->entry, &replacement->entry); + hlsl_block_add_instr(block, replacement); - hlsl_replace_node(instr, replacement); return true; } /* Lower ROUND using FRC, ROUND(x) -> ((x + 0.5) - FRC(x + 0.5)). */ -static bool lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +static bool lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *arg, *neg, *sum, *frc, *half, *replacement; struct hlsl_type *type = instr->data_type; @@ -2417,31 +2443,29 @@ static bool lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void * half_value.u[i].f = 0.5f; if (!(half = hlsl_new_constant(ctx, type, &half_value, &expr->node.loc))) return false; - - list_add_before(&instr->entry, &half->entry); + hlsl_block_add_instr(block, half); if (!(sum = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, arg, half))) return false; - list_add_before(&instr->entry, &sum->entry); + hlsl_block_add_instr(block, sum); if (!(frc = hlsl_new_unary_expr(ctx, HLSL_OP1_FRACT, sum, &instr->loc))) return false; - list_add_before(&instr->entry, &frc->entry); + hlsl_block_add_instr(block, frc); if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, frc, &instr->loc))) return false; - list_add_before(&instr->entry, &neg->entry); + hlsl_block_add_instr(block, neg); if (!(replacement = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, sum, neg))) return false; - list_add_before(&instr->entry, &replacement->entry); + hlsl_block_add_instr(block, replacement); - hlsl_replace_node(instr, replacement); return true; } /* Use 'movc' for the ternary operator. */ -static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], *replacement; struct hlsl_ir_node *zero, *cond, *first, *second; @@ -2464,7 +2488,7 @@ static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void { if (!(zero = hlsl_new_constant(ctx, cond->data_type, &zero_value, &instr->loc))) return false; - list_add_tail(&instr->entry, &zero->entry); + hlsl_block_add_instr(block, zero); memset(operands, 0, sizeof(operands)); operands[0] = zero; @@ -2473,7 +2497,7 @@ static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_BOOL, type->dimx, type->dimy); if (!(cond = hlsl_new_expr(ctx, HLSL_OP2_NEQUAL, operands, type, &instr->loc))) return false; - list_add_before(&instr->entry, &cond->entry); + hlsl_block_add_instr(block, cond); } memset(operands, 0, sizeof(operands)); @@ -2482,17 +2506,15 @@ static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void operands[2] = second; if (!(replacement = hlsl_new_expr(ctx, HLSL_OP3_MOVC, operands, first->data_type, &instr->loc))) return false; - list_add_before(&instr->entry, &replacement->entry); - - hlsl_replace_node(instr, replacement); + hlsl_block_add_instr(block, replacement); return true; } -static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_type *type = instr->data_type, *arg_type; static const struct hlsl_constant_value zero_value; - struct hlsl_ir_node *zero; + struct hlsl_ir_node *zero, *neq; struct hlsl_ir_expr *expr; if (instr->type != HLSL_IR_EXPR) @@ -2512,10 +2534,12 @@ static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr zero = hlsl_new_constant(ctx, arg_type, &zero_value, &instr->loc); if (!zero) return false; - list_add_before(&instr->entry, &zero->entry); + hlsl_block_add_instr(block, zero); - expr->op = HLSL_OP2_NEQUAL; - hlsl_src_from_node(&expr->operands[1], zero); + if (!(neq = hlsl_new_binary_expr(ctx, HLSL_OP2_NEQUAL, expr->operands[0].node, zero))) + return false; + neq->data_type = expr->node.data_type; + hlsl_block_add_instr(block, neq); return true; } @@ -2523,36 +2547,19 @@ static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct hlsl_block *instrs, struct hlsl_ir_node *condition, struct hlsl_ir_node *if_true, struct hlsl_ir_node *if_false) { - struct hlsl_block then_block, else_block; - struct hlsl_ir_node *iff, *store; - struct hlsl_ir_load *load; - struct hlsl_ir_var *var; + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS]; + struct hlsl_ir_node *cond; assert(hlsl_types_are_equal(if_true->data_type, if_false->data_type)); - if (!(var = hlsl_new_synthetic_var(ctx, "conditional", if_true->data_type, &condition->loc))) - return NULL; - - hlsl_block_init(&then_block); - hlsl_block_init(&else_block); - - if (!(store = hlsl_new_simple_store(ctx, var, if_true))) - return NULL; - hlsl_block_add_instr(&then_block, store); - - if (!(store = hlsl_new_simple_store(ctx, var, if_false))) - return NULL; - hlsl_block_add_instr(&else_block, store); - - if (!(iff = hlsl_new_if(ctx, condition, &then_block, &else_block, &condition->loc))) - return NULL; - hlsl_block_add_instr(instrs, iff); - - if (!(load = hlsl_new_var_load(ctx, var, &condition->loc))) - return NULL; - hlsl_block_add_instr(instrs, &load->node); + operands[0] = condition; + operands[1] = if_true; + operands[2] = if_false; + if (!(cond = hlsl_new_expr(ctx, HLSL_OP3_TERNARY, operands, if_true->data_type, &condition->loc))) + return false; + hlsl_block_add_instr(instrs, cond); - return &load->node; + return cond; } static bool lower_int_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) @@ -2683,10 +2690,10 @@ static bool lower_int_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, return hlsl_add_conditional(ctx, block, and, neg, cast3); } -static bool lower_int_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +static bool lower_int_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_type *type = instr->data_type; - struct hlsl_ir_node *arg, *neg; + struct hlsl_ir_node *arg, *neg, *max; struct hlsl_ir_expr *expr; if (instr->type != HLSL_IR_EXPR) @@ -2704,15 +2711,16 @@ static bool lower_int_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg, &instr->loc))) return false; - list_add_before(&instr->entry, &neg->entry); + hlsl_block_add_instr(block, neg); - expr->op = HLSL_OP2_MAX; - hlsl_src_from_node(&expr->operands[1], neg); + if (!(max = hlsl_new_binary_expr(ctx, HLSL_OP2_MAX, arg, neg))) + return false; + hlsl_block_add_instr(block, max); return true; } -static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *arg1, *arg2, *mult, *comps[4] = {0}, *res; struct hlsl_type *type = instr->data_type; @@ -2738,7 +2746,7 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void if (!(mult = hlsl_new_binary_expr(ctx, is_bool ? HLSL_OP2_LOGIC_AND : HLSL_OP2_MUL, arg1, arg2))) return false; - list_add_before(&instr->entry, &mult->entry); + hlsl_block_add_instr(block, mult); for (i = 0; i < dimx; ++i) { @@ -2746,7 +2754,7 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void if (!(comps[i] = hlsl_new_swizzle(ctx, s, 1, mult, &instr->loc))) return false; - list_add_before(&instr->entry, &comps[i]->entry); + hlsl_block_add_instr(block, comps[i]); } res = comps[0]; @@ -2754,10 +2762,9 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void { if (!(res = hlsl_new_binary_expr(ctx, is_bool ? HLSL_OP2_LOGIC_OR : HLSL_OP2_ADD, res, comps[i]))) return false; - list_add_before(&instr->entry, &res->entry); + hlsl_block_add_instr(block, res); } - hlsl_replace_node(instr, res); return true; } @@ -2993,31 +3000,39 @@ static void allocate_register_reservations(struct hlsl_ctx *ctx) LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { - enum hlsl_regset regset; + unsigned int r; if (!hlsl_type_is_resource(var->data_type)) continue; - regset = hlsl_type_get_regset(var->data_type); - if (var->reg_reservation.reg_type && var->regs[regset].allocation_size) + if (var->reg_reservation.reg_type) { - if (var->reg_reservation.reg_type != get_regset_name(regset)) - { - struct vkd3d_string_buffer *type_string; - - type_string = hlsl_type_to_string(ctx, var->data_type); - hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, - "Object of type '%s' must be bound to register type '%c'.", - type_string->buffer, get_regset_name(regset)); - hlsl_release_string_buffer(ctx, type_string); - } - else + for (r = 0; r <= HLSL_REGSET_LAST_OBJECT; ++r) { - var->regs[regset].allocated = true; - var->regs[regset].id = var->reg_reservation.reg_index; - TRACE("Allocated reserved %s to %c%u-%c%u.\n", var->name, var->reg_reservation.reg_type, - var->reg_reservation.reg_index, var->reg_reservation.reg_type, - var->reg_reservation.reg_index + var->regs[regset].allocation_size); + if (var->regs[r].allocation_size > 0) + { + if (var->reg_reservation.reg_type != get_regset_name(r)) + { + struct vkd3d_string_buffer *type_string; + + /* We can throw this error because resources can only span across a single + * regset, but we have to check for multiple regsets if we support register + * reservations for structs for SM5. */ + type_string = hlsl_type_to_string(ctx, var->data_type); + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, + "Object of type '%s' must be bound to register type '%c'.", + type_string->buffer, get_regset_name(r)); + hlsl_release_string_buffer(ctx, type_string); + } + else + { + var->regs[r].allocated = true; + var->regs[r].id = var->reg_reservation.reg_index; + TRACE("Allocated reserved %s to %c%u-%c%u.\n", var->name, var->reg_reservation.reg_type, + var->reg_reservation.reg_index, var->reg_reservation.reg_type, + var->reg_reservation.reg_index + var->regs[r].allocation_size); + } + } } } } @@ -3356,7 +3371,7 @@ static bool track_object_components_sampler_dim(struct hlsl_ctx *ctx, struct hls load = hlsl_ir_resource_load(instr); var = load->resource.var; - regset = hlsl_type_get_regset(hlsl_deref_get_type(ctx, &load->resource)); + regset = hlsl_deref_get_regset(ctx, &load->resource); if (!hlsl_regset_index_from_deref(ctx, &load->resource, regset, &index)) return false; @@ -3401,7 +3416,8 @@ static bool track_object_components_usage(struct hlsl_ctx *ctx, struct hlsl_ir_n load = hlsl_ir_resource_load(instr); var = load->resource.var; - regset = hlsl_type_get_regset(hlsl_deref_get_type(ctx, &load->resource)); + regset = hlsl_deref_get_regset(ctx, &load->resource); + if (!hlsl_regset_index_from_deref(ctx, &load->resource, regset, &index)) return false; @@ -3728,7 +3744,7 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var "Invalid semantic '%s'.", var->semantic.name); return; } - if ((builtin = hlsl_sm4_register_from_semantic(ctx, &var->semantic, output, &type, NULL, &has_idx))) + if ((builtin = hlsl_sm4_register_from_semantic(ctx, &var->semantic, output, &type, &has_idx))) reg = has_idx ? var->semantic.index : 0; } @@ -4208,7 +4224,7 @@ bool hlsl_offset_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref return false; *offset = hlsl_ir_constant(offset_node)->value.u[0].u; - regset = hlsl_type_get_regset(deref->data_type); + regset = hlsl_deref_get_regset(ctx, deref); size = deref->var->data_type->reg_size[regset]; if (*offset >= size) @@ -4345,7 +4361,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry while (hlsl_transform_ir(ctx, lower_calls, body, NULL)); lower_ir(ctx, lower_matrix_swizzles, body); - hlsl_transform_ir(ctx, lower_index_loads, body, NULL); + lower_ir(ctx, lower_index_loads, body); LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry) { @@ -4408,7 +4424,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry { hlsl_transform_ir(ctx, lower_discard_neg, body, NULL); } - hlsl_transform_ir(ctx, lower_broadcasts, body, NULL); + lower_ir(ctx, lower_broadcasts, body); while (hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL)); do { @@ -4418,12 +4434,12 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry while (progress); hlsl_transform_ir(ctx, split_matrix_copies, body, NULL); - hlsl_transform_ir(ctx, lower_narrowing_casts, body, NULL); - hlsl_transform_ir(ctx, lower_casts_to_bool, body, NULL); - hlsl_transform_ir(ctx, lower_int_dot, body, NULL); + lower_ir(ctx, lower_narrowing_casts, body); + lower_ir(ctx, lower_casts_to_bool, body); + lower_ir(ctx, lower_int_dot, body); lower_ir(ctx, lower_int_division, body); lower_ir(ctx, lower_int_modulus, body); - hlsl_transform_ir(ctx, lower_int_abs, body, NULL); + lower_ir(ctx, lower_int_abs, body); lower_ir(ctx, lower_float_modulus, body); hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL); do @@ -4433,12 +4449,13 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry progress |= hlsl_copy_propagation_execute(ctx, body); progress |= hlsl_transform_ir(ctx, fold_swizzle_chains, body, NULL); progress |= hlsl_transform_ir(ctx, remove_trivial_swizzles, body, NULL); + progress |= hlsl_transform_ir(ctx, remove_trivial_conditional_branches, body, NULL); } while (progress); - hlsl_transform_ir(ctx, lower_nonconstant_vector_derefs, body, NULL); - hlsl_transform_ir(ctx, lower_casts_to_bool, body, NULL); - hlsl_transform_ir(ctx, lower_int_dot, body, NULL); + lower_ir(ctx, lower_nonconstant_vector_derefs, body); + lower_ir(ctx, lower_casts_to_bool, body); + lower_ir(ctx, lower_int_dot, body); hlsl_transform_ir(ctx, validate_static_object_references, body, NULL); hlsl_transform_ir(ctx, track_object_components_sampler_dim, body, NULL); @@ -4448,18 +4465,18 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry sort_synthetic_separated_samplers_first(ctx); if (profile->major_version >= 4) - hlsl_transform_ir(ctx, lower_ternary, body, NULL); + lower_ir(ctx, lower_ternary, body); if (profile->major_version < 4) { - hlsl_transform_ir(ctx, lower_division, body, NULL); - hlsl_transform_ir(ctx, lower_sqrt, body, NULL); - hlsl_transform_ir(ctx, lower_dot, body, NULL); - hlsl_transform_ir(ctx, lower_round, body, NULL); + lower_ir(ctx, lower_division, body); + lower_ir(ctx, lower_sqrt, body); + lower_ir(ctx, lower_dot, body); + lower_ir(ctx, lower_round, body); } if (profile->major_version < 2) { - hlsl_transform_ir(ctx, lower_abs, body, NULL); + lower_ir(ctx, lower_abs, body); } /* TODO: move forward, remove when no longer needed */ diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c index 41a72ab6c0d..64629dc2959 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c @@ -63,6 +63,82 @@ static bool fold_abs(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, return true; } +static uint32_t float_to_uint(float x) +{ + if (isnan(x) || x <= 0) + return 0; + + if (x >= 4294967296.0f) + return UINT32_MAX; + + return x; +} + +static int32_t float_to_int(float x) +{ + if (isnan(x)) + return 0; + + if (x <= -2147483648.0f) + return INT32_MIN; + + if (x >= 2147483648.0f) + return INT32_MAX; + + return x; +} + +static uint32_t double_to_uint(double x) +{ + if (isnan(x) || x <= 0) + return 0; + + if (x >= 4294967296.0) + return UINT32_MAX; + + return x; +} + +static int32_t double_to_int(double x) +{ + if (isnan(x)) + return 0; + + if (x <= -2147483648.0) + return INT32_MIN; + + if (x >= 2147483648.0) + return INT32_MAX; + + return x; +} + +static bool fold_bit_not(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, + const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) +{ + enum hlsl_base_type type = dst_type->base_type; + unsigned int k; + + assert(type == src->node.data_type->base_type); + + for (k = 0; k < dst_type->dimx; ++k) + { + switch (type) + { + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + case HLSL_TYPE_BOOL: + dst->u[k].u = ~src->value.u[k].u; + break; + + default: + vkd3d_unreachable(); + } + } + + return true; +} + static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) { @@ -86,15 +162,15 @@ static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, { case HLSL_TYPE_FLOAT: case HLSL_TYPE_HALF: - u = src->value.u[k].f; - i = src->value.u[k].f; + u = float_to_uint(src->value.u[k].f); + i = float_to_int(src->value.u[k].f); f = src->value.u[k].f; d = src->value.u[k].f; break; case HLSL_TYPE_DOUBLE: - u = src->value.u[k].d; - i = src->value.u[k].d; + u = double_to_uint(src->value.u[k].d); + i = double_to_int(src->value.u[k].d); f = src->value.u[k].d; d = src->value.u[k].d; break; @@ -152,6 +228,59 @@ static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, return true; } +static bool fold_exp2(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, + const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) +{ + enum hlsl_base_type type = dst_type->base_type; + unsigned int k; + + assert(type == src->node.data_type->base_type); + + for (k = 0; k < dst_type->dimx; ++k) + { + switch (type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + dst->u[k].f = exp2f(src->value.u[k].f); + break; + + default: + FIXME("Fold 'exp2' for type %s.\n", debug_hlsl_type(ctx, dst_type)); + return false; + } + } + + return true; +} + +static bool fold_fract(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, + const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) +{ + enum hlsl_base_type type = dst_type->base_type; + unsigned int k; + float i; + + assert(type == src->node.data_type->base_type); + + for (k = 0; k < dst_type->dimx; ++k) + { + switch (type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + dst->u[k].f = modff(src->value.u[k].f, &i); + break; + + default: + FIXME("Fold 'fract' for type %s.\n", debug_hlsl_type(ctx, dst_type)); + return false; + } + } + + return true; +} + static bool fold_log2(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc) { @@ -231,6 +360,30 @@ static bool fold_neg(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, return true; } +static bool fold_not(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, + const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) +{ + enum hlsl_base_type type = dst_type->base_type; + unsigned int k; + + assert(type == src->node.data_type->base_type); + + for (k = 0; k < dst_type->dimx; ++k) + { + switch (type) + { + case HLSL_TYPE_BOOL: + dst->u[k].u = ~src->value.u[k].u; + break; + + default: + FIXME("Fold logic 'not' for type %s.\n", debug_hlsl_type(ctx, dst_type)); + return false; + } + } + return true; +} + static bool fold_rcp(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc) { @@ -276,6 +429,72 @@ static bool fold_rcp(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons return true; } +static bool fold_rsq(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, + const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc) +{ + enum hlsl_base_type type = dst_type->base_type; + unsigned int k; + + assert(type == src->node.data_type->base_type); + + for (k = 0; k < dst_type->dimx; ++k) + { + switch (type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + if (ctx->profile->major_version >= 4) + { + if (src->value.u[k].f < 0.0f) + hlsl_warning(ctx, loc, VKD3D_SHADER_WARNING_HLSL_IMAGINARY_NUMERIC_RESULT, + "Imaginary square root result."); + else if (src->value.u[k].f == 0.0f) + hlsl_warning(ctx, loc, VKD3D_SHADER_WARNING_HLSL_IMAGINARY_NUMERIC_RESULT, + "Floating point division by zero."); + } + dst->u[k].f = 1.0f / sqrtf(src->value.u[k].f); + if (ctx->profile->major_version < 4 && !isfinite(dst->u[k].f)) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_NON_FINITE_RESULT, + "Infinities and NaNs are not allowed by the shader model."); + } + break; + + default: + FIXME("Fold 'rsq' for type %s.\n", debug_hlsl_type(ctx, dst_type)); + return false; + } + } + + return true; +} + +static bool fold_sat(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, + const struct hlsl_ir_constant *src) +{ + enum hlsl_base_type type = dst_type->base_type; + unsigned int k; + + assert(type == src->node.data_type->base_type); + + for (k = 0; k < dst_type->dimx; ++k) + { + switch (type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + dst->u[k].f = min(max(0.0f, src->value.u[k].f), 1.0f); + break; + + default: + FIXME("Fold 'sat' for type %s.\n", debug_hlsl_type(ctx, dst_type)); + return false; + } + } + + return true; +} + static bool fold_sqrt(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc) { @@ -679,6 +898,36 @@ static bool fold_less(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, con return true; } +static bool fold_lshift(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, + const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2) +{ + unsigned int k; + + assert(dst_type->base_type == src1->node.data_type->base_type); + assert(src2->node.data_type->base_type == HLSL_TYPE_INT); + + for (k = 0; k < dst_type->dimx; ++k) + { + unsigned int shift = src2->value.u[k].u % 32; + + switch (src1->node.data_type->base_type) + { + case HLSL_TYPE_INT: + dst->u[k].i = src1->value.u[k].i << shift; + break; + + case HLSL_TYPE_UINT: + dst->u[k].u = src1->value.u[k].u << shift; + break; + + default: + vkd3d_unreachable(); + } + } + + return true; +} + static bool fold_max(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2) { @@ -869,6 +1118,70 @@ static bool fold_nequal(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, c return true; } +static bool fold_ternary(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, + const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2, const struct hlsl_ir_constant *src3) +{ + unsigned int k; + + assert(dst_type->base_type == src2->node.data_type->base_type); + assert(dst_type->base_type == src3->node.data_type->base_type); + + for (k = 0; k < dst_type->dimx; ++k) + { + switch (src1->node.data_type->base_type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + dst->u[k] = src1->value.u[k].f != 0.0f ? src2->value.u[k] : src3->value.u[k]; + break; + + case HLSL_TYPE_DOUBLE: + dst->u[k] = src1->value.u[k].d != 0.0 ? src2->value.u[k] : src3->value.u[k]; + break; + + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + case HLSL_TYPE_BOOL: + dst->u[k] = src1->value.u[k].u ? src2->value.u[k] : src3->value.u[k]; + break; + + default: + vkd3d_unreachable(); + } + } + return true; +} + +static bool fold_rshift(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, + const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2) +{ + unsigned int k; + + assert(dst_type->base_type == src1->node.data_type->base_type); + assert(src2->node.data_type->base_type == HLSL_TYPE_INT); + + for (k = 0; k < dst_type->dimx; ++k) + { + unsigned int shift = src2->value.u[k].u % 32; + + switch (src1->node.data_type->base_type) + { + case HLSL_TYPE_INT: + dst->u[k].i = src1->value.u[k].i >> shift; + break; + + case HLSL_TYPE_UINT: + dst->u[k].u = src1->value.u[k].u >> shift; + break; + + default: + vkd3d_unreachable(); + } + } + + return true; +} + bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { struct hlsl_ir_constant *arg1, *arg2 = NULL, *arg3 = NULL; @@ -908,10 +1221,22 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, success = fold_abs(ctx, &res, instr->data_type, arg1); break; + case HLSL_OP1_BIT_NOT: + success = fold_bit_not(ctx, &res, instr->data_type, arg1); + break; + case HLSL_OP1_CAST: success = fold_cast(ctx, &res, instr->data_type, arg1); break; + case HLSL_OP1_EXP2: + success = fold_exp2(ctx, &res, instr->data_type, arg1); + break; + + case HLSL_OP1_FRACT: + success = fold_fract(ctx, &res, instr->data_type, arg1); + break; + case HLSL_OP1_LOG2: success = fold_log2(ctx, &res, instr->data_type, arg1, &instr->loc); break; @@ -920,10 +1245,22 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, success = fold_neg(ctx, &res, instr->data_type, arg1); break; + case HLSL_OP1_LOGIC_NOT: + success = fold_not(ctx, &res, instr->data_type, arg1); + break; + case HLSL_OP1_RCP: success = fold_rcp(ctx, &res, instr->data_type, arg1, &instr->loc); break; + case HLSL_OP1_RSQ: + success = fold_rsq(ctx, &res, instr->data_type, arg1, &instr->loc); + break; + + case HLSL_OP1_SAT: + success = fold_sat(ctx, &res, instr->data_type, arg1); + break; + case HLSL_OP1_SQRT: success = fold_sqrt(ctx, &res, instr->data_type, arg1, &instr->loc); break; @@ -966,6 +1303,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, success = fold_less(ctx, &res, instr->data_type, arg1, arg2); break; + case HLSL_OP2_LSHIFT: + success = fold_lshift(ctx, &res, instr->data_type, arg1, arg2); + break; + case HLSL_OP2_MAX: success = fold_max(ctx, &res, instr->data_type, arg1, arg2); break; @@ -986,10 +1327,18 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, success = fold_nequal(ctx, &res, instr->data_type, arg1, arg2); break; + case HLSL_OP2_RSHIFT: + success = fold_rshift(ctx, &res, instr->data_type, arg1, arg2); + break; + case HLSL_OP3_DP2ADD: success = fold_dp2add(ctx, &res, instr->data_type, arg1, arg2, arg3); break; + case HLSL_OP3_TERNARY: + success = fold_ternary(ctx, &res, instr->data_type, arg1, arg2, arg3); + break; + default: FIXME("Fold \"%s\" expression.\n", debug_hlsl_expr_op(expr->op)); success = false; diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c index d2bfb933edc..511b0e8faf9 100644 --- a/libs/vkd3d/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d/libs/vkd3d-shader/ir.c @@ -31,11 +31,9 @@ static bool shader_instruction_is_dcl(const struct vkd3d_shader_instruction *ins static void vkd3d_shader_instruction_make_nop(struct vkd3d_shader_instruction *ins) { - ins->handler_idx = VKD3DSIH_NOP; - ins->dst_count = 0; - ins->src_count = 0; - ins->dst = NULL; - ins->src = NULL; + struct vkd3d_shader_location location = ins->location; + + vsir_instruction_init(ins, &location, VKD3DSIH_NOP); } static void shader_register_eliminate_phase_addressing(struct vkd3d_shader_register *reg, @@ -74,7 +72,7 @@ static void shader_instruction_eliminate_phase_instance_id(struct vkd3d_shader_i reg->idx[2].offset = ~0u; reg->idx[2].rel_addr = NULL; reg->idx_count = 0; - reg->immconst_type = VKD3D_IMMCONST_SCALAR; + reg->dimension = VSIR_DIMENSION_SCALAR; reg->u.immconst_uint[0] = instance_id; continue; } @@ -161,6 +159,7 @@ struct hull_flattener unsigned int instance_count; unsigned int phase_body_idx; enum vkd3d_shader_opcode phase; + struct vkd3d_shader_location last_ret_location; }; static bool flattener_is_in_fork_or_join_phase(const struct hull_flattener *flattener) @@ -233,6 +232,7 @@ static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normal if (ins->handler_idx == VKD3DSIH_RET) { + normaliser->last_ret_location = ins->location; vkd3d_shader_instruction_make_nop(ins); if (locations->count >= ARRAY_SIZE(locations->locations)) { @@ -296,7 +296,7 @@ static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normali return VKD3D_OK; } -void shader_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type, +void vsir_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int idx_count) { reg->type = reg_type; @@ -310,12 +310,14 @@ void shader_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_r reg->idx[2].offset = ~0u; reg->idx[2].rel_addr = NULL; reg->idx_count = idx_count; - reg->immconst_type = VKD3D_IMMCONST_SCALAR; + reg->dimension = VSIR_DIMENSION_SCALAR; } -void shader_instruction_init(struct vkd3d_shader_instruction *ins, enum vkd3d_shader_opcode handler_idx) +void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location, + enum vkd3d_shader_opcode handler_idx) { memset(ins, 0, sizeof(*ins)); + ins->location = *location; ins->handler_idx = handler_idx; } @@ -343,7 +345,7 @@ static enum vkd3d_result instruction_array_flatten_hull_shader_phases(struct vkd if (!shader_instruction_array_reserve(&flattener.instructions, flattener.instructions.count + 1)) return VKD3D_ERROR_OUT_OF_MEMORY; - shader_instruction_init(&instructions->elements[instructions->count++], VKD3DSIH_RET); + vsir_instruction_init(&instructions->elements[instructions->count++], &flattener.last_ret_location, VKD3DSIH_RET); } *src_instructions = flattener.instructions; @@ -370,7 +372,7 @@ static struct vkd3d_shader_src_param *instruction_array_create_outpointid_param( if (!(rel_addr = shader_src_param_allocator_get(&instructions->src_params, 1))) return NULL; - shader_register_init(&rel_addr->reg, VKD3DSPR_OUTPOINTID, VKD3D_DATA_UINT, 0); + vsir_register_init(&rel_addr->reg, VKD3DSPR_OUTPOINTID, VKD3D_DATA_UINT, 0); rel_addr->swizzle = 0; rel_addr->modifiers = 0; @@ -400,11 +402,12 @@ static void shader_dst_param_io_init(struct vkd3d_shader_dst_param *param, const param->write_mask = e->mask; param->modifiers = 0; param->shift = 0; - shader_register_init(¶m->reg, reg_type, vkd3d_data_type_from_component_type(e->component_type), idx_count); + vsir_register_init(¶m->reg, reg_type, vkd3d_data_type_from_component_type(e->component_type), idx_count); } static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_point_normaliser *normaliser, - const struct shader_signature *s, unsigned int input_control_point_count, unsigned int dst) + const struct shader_signature *s, unsigned int input_control_point_count, unsigned int dst, + const struct vkd3d_shader_location *location) { struct vkd3d_shader_instruction *ins; struct vkd3d_shader_dst_param *param; @@ -422,7 +425,7 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p normaliser->instructions.count += count; ins = &normaliser->instructions.elements[dst]; - shader_instruction_init(ins, VKD3DSIH_HS_CONTROL_POINT_PHASE); + vsir_instruction_init(ins, location, VKD3DSIH_HS_CONTROL_POINT_PHASE); ins->flags = 1; ++ins; @@ -434,13 +437,13 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p if (e->sysval_semantic != VKD3D_SHADER_SV_NONE) { - shader_instruction_init(ins, VKD3DSIH_DCL_INPUT_SIV); + vsir_instruction_init(ins, location, VKD3DSIH_DCL_INPUT_SIV); param = &ins->declaration.register_semantic.reg; ins->declaration.register_semantic.sysval_semantic = vkd3d_siv_from_sysval(e->sysval_semantic); } else { - shader_instruction_init(ins, VKD3DSIH_DCL_INPUT); + vsir_instruction_init(ins, location, VKD3DSIH_DCL_INPUT); param = &ins->declaration.dst; } @@ -511,7 +514,7 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i case VKD3DSIH_HS_FORK_PHASE: case VKD3DSIH_HS_JOIN_PHASE: ret = control_point_normaliser_emit_hs_input(&normaliser, input_signature, - input_control_point_count, i); + input_control_point_count, i, &ins->location); *src_instructions = normaliser.instructions; return ret; default: @@ -1014,7 +1017,6 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi struct io_normaliser *normaliser) { struct vkd3d_shader_register *reg; - bool keep = true; unsigned int i; switch (ins->handler_idx) @@ -1033,15 +1035,16 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi /* fall through */ case VKD3DSIH_DCL_INPUT_PS: case VKD3DSIH_DCL_OUTPUT: - keep = shader_dst_param_io_normalise(&ins->declaration.dst, true, normaliser); + if (!shader_dst_param_io_normalise(&ins->declaration.dst, true, normaliser)) + vkd3d_shader_instruction_make_nop(ins); break; case VKD3DSIH_DCL_INPUT_SGV: case VKD3DSIH_DCL_INPUT_SIV: case VKD3DSIH_DCL_INPUT_PS_SGV: case VKD3DSIH_DCL_INPUT_PS_SIV: case VKD3DSIH_DCL_OUTPUT_SIV: - keep = shader_dst_param_io_normalise(&ins->declaration.register_semantic.reg, true, - normaliser); + if (!shader_dst_param_io_normalise(&ins->declaration.register_semantic.reg, true, normaliser)) + vkd3d_shader_instruction_make_nop(ins); break; case VKD3DSIH_HS_CONTROL_POINT_PHASE: case VKD3DSIH_HS_FORK_PHASE: @@ -1060,9 +1063,6 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi shader_src_param_io_normalise((struct vkd3d_shader_src_param *)&ins->src[i], normaliser); break; } - - if (!keep) - shader_instruction_init(ins, VKD3DSIH_NOP); } static enum vkd3d_result instruction_array_normalise_io_registers(struct vkd3d_shader_instruction_array *instructions, @@ -1207,7 +1207,7 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par { param->reg.type = VKD3DSPR_IMMCONST; param->reg.idx_count = 0; - param->reg.immconst_type = VKD3D_IMMCONST_VEC4; + param->reg.dimension = VSIR_DIMENSION_VEC4; for (j = 0; j < 4; ++j) param->reg.u.immconst_uint[j] = normaliser->defs[i].value[j]; return; @@ -1260,6 +1260,164 @@ static enum vkd3d_result instruction_array_normalise_flat_constants(struct vkd3d return VKD3D_OK; } +static void remove_dead_code(struct vkd3d_shader_parser *parser) +{ + size_t i, depth = 0; + bool dead = false; + + for (i = 0; i < parser->instructions.count; ++i) + { + struct vkd3d_shader_instruction *ins = &parser->instructions.elements[i]; + + switch (ins->handler_idx) + { + case VKD3DSIH_IF: + case VKD3DSIH_LOOP: + case VKD3DSIH_SWITCH: + if (dead) + { + vkd3d_shader_instruction_make_nop(ins); + ++depth; + } + break; + + case VKD3DSIH_ENDIF: + case VKD3DSIH_ENDLOOP: + case VKD3DSIH_ENDSWITCH: + case VKD3DSIH_ELSE: + if (dead) + { + if (depth > 0) + { + vkd3d_shader_instruction_make_nop(ins); + if (ins->handler_idx != VKD3DSIH_ELSE) + --depth; + } + else + { + dead = false; + } + } + break; + + /* `depth' is counted with respect to where the dead code + * segment began. So it starts at zero and it signals the + * termination of the dead code segment when it would + * become negative. */ + case VKD3DSIH_BREAK: + case VKD3DSIH_RET: + case VKD3DSIH_CONTINUE: + if (dead) + { + vkd3d_shader_instruction_make_nop(ins); + } + else + { + dead = true; + depth = 0; + } + break; + + /* If `case' or `default' appears at zero depth, it means + * that they are a possible target for the corresponding + * switch, so the code is live again. */ + case VKD3DSIH_CASE: + case VKD3DSIH_DEFAULT: + if (dead) + { + if (depth == 0) + dead = false; + else + vkd3d_shader_instruction_make_nop(ins); + } + break; + + /* Phase instructions can only appear in hull shaders and + * outside of any block. When a phase returns, control is + * moved to the following phase, so they make code live + * again. */ + case VKD3DSIH_HS_CONTROL_POINT_PHASE: + case VKD3DSIH_HS_FORK_PHASE: + case VKD3DSIH_HS_JOIN_PHASE: + dead = false; + break; + + default: + if (dead) + vkd3d_shader_instruction_make_nop(ins); + break; + } + } +} + +static enum vkd3d_result normalise_combined_samplers(struct vkd3d_shader_parser *parser) +{ + unsigned int i; + + for (i = 0; i < parser->instructions.count; ++i) + { + struct vkd3d_shader_instruction *ins = &parser->instructions.elements[i]; + struct vkd3d_shader_src_param *srcs; + + switch (ins->handler_idx) + { + case VKD3DSIH_TEX: + if (!(srcs = shader_src_param_allocator_get(&parser->instructions.src_params, 3))) + return VKD3D_ERROR_OUT_OF_MEMORY; + memset(srcs, 0, sizeof(*srcs) * 3); + + ins->handler_idx = VKD3DSIH_SAMPLE; + + srcs[0] = ins->src[0]; + + srcs[1].reg.type = VKD3DSPR_RESOURCE; + srcs[1].reg.idx[0] = ins->src[1].reg.idx[0]; + srcs[1].reg.idx[1] = ins->src[1].reg.idx[0]; + srcs[1].reg.idx_count = 2; + srcs[1].reg.data_type = VKD3D_DATA_RESOURCE; + srcs[1].swizzle = VKD3D_SHADER_NO_SWIZZLE; + + srcs[2].reg.type = VKD3DSPR_SAMPLER; + srcs[2].reg.idx[0] = ins->src[1].reg.idx[0]; + srcs[2].reg.idx[1] = ins->src[1].reg.idx[0]; + srcs[2].reg.idx_count = 2; + srcs[2].reg.data_type = VKD3D_DATA_SAMPLER; + + ins->src = srcs; + ins->src_count = 3; + break; + + case VKD3DSIH_TEXBEM: + case VKD3DSIH_TEXBEML: + case VKD3DSIH_TEXCOORD: + case VKD3DSIH_TEXDEPTH: + case VKD3DSIH_TEXDP3: + case VKD3DSIH_TEXDP3TEX: + case VKD3DSIH_TEXLDD: + case VKD3DSIH_TEXLDL: + case VKD3DSIH_TEXM3x2PAD: + case VKD3DSIH_TEXM3x2TEX: + case VKD3DSIH_TEXM3x3DIFF: + case VKD3DSIH_TEXM3x3PAD: + case VKD3DSIH_TEXM3x3SPEC: + case VKD3DSIH_TEXM3x3TEX: + case VKD3DSIH_TEXM3x3VSPEC: + case VKD3DSIH_TEXREG2AR: + case VKD3DSIH_TEXREG2GB: + case VKD3DSIH_TEXREG2RGB: + vkd3d_shader_parser_error(parser, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, + "Aborting due to not yet implemented feature: " + "Combined sampler instruction %#x.", ins->handler_idx); + return VKD3D_ERROR_NOT_IMPLEMENTED; + + default: + break; + } + } + + return VKD3D_OK; +} + enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser, const struct vkd3d_shader_compile_info *compile_info) { @@ -1287,8 +1445,126 @@ enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser, if (result >= 0) result = instruction_array_normalise_flat_constants(parser); + if (result >= 0) + remove_dead_code(parser); + + if (result >= 0) + result = normalise_combined_samplers(parser); + if (result >= 0 && TRACE_ON()) vkd3d_shader_trace(instructions, &parser->shader_version); + if (result >= 0 && !parser->failed) + vsir_validate(parser); + + if (result >= 0 && parser->failed) + result = VKD3D_ERROR_INVALID_SHADER; + return result; } + +struct validation_context +{ + struct vkd3d_shader_parser *parser; + size_t instruction_idx; +}; + +static void VKD3D_PRINTF_FUNC(3, 4) validator_error(struct validation_context *ctx, + enum vkd3d_shader_error error, const char *format, ...) +{ + struct vkd3d_string_buffer buf; + va_list args; + + vkd3d_string_buffer_init(&buf); + + va_start(args, format); + vkd3d_string_buffer_vprintf(&buf, format, args); + va_end(args); + + vkd3d_shader_parser_error(ctx->parser, error, "instruction %zu: %s", ctx->instruction_idx + 1, buf.buffer); + + vkd3d_string_buffer_cleanup(&buf); +} + +static void vsir_validate_register(struct validation_context *ctx, + const struct vkd3d_shader_register *reg) +{ + if (reg->type >= VKD3DSPR_COUNT) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, "Invalid register type %#x.", + reg->type); +} + +static void vsir_validate_dst_param(struct validation_context *ctx, + const struct vkd3d_shader_dst_param *dst) +{ + vsir_validate_register(ctx, &dst->reg); + + if (dst->write_mask & ~VKD3DSP_WRITEMASK_ALL) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_WRITE_MASK, "Destination has invalid write mask %#x.", + dst->write_mask); + + if (dst->modifiers & ~VKD3DSPDM_MASK) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, "Destination has invalid modifiers %#x.", + dst->modifiers); + + switch (dst->shift) + { + case 0: + case 1: + case 2: + case 3: + case 13: + case 14: + case 15: + break; + + default: + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SHIFT, "Destination has invalid shift %#x.", + dst->shift); + } +} + +static void vsir_validate_src_param(struct validation_context *ctx, + const struct vkd3d_shader_src_param *src) +{ + vsir_validate_register(ctx, &src->reg); + + if (src->swizzle & ~0x03030303u) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SWIZZLE, "Source has invalid swizzle %#x.", + src->swizzle); + + if (src->modifiers >= VKD3DSPSM_COUNT) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, "Source has invalid modifiers %#x.", + src->modifiers); +} + +static void vsir_validate_instruction(struct validation_context *ctx) +{ + const struct vkd3d_shader_instruction *instruction = &ctx->parser->instructions.elements[ctx->instruction_idx]; + size_t i; + + ctx->parser->location = instruction->location; + + for (i = 0; i < instruction->dst_count; ++i) + vsir_validate_dst_param(ctx, &instruction->dst[i]); + + for (i = 0; i < instruction->src_count; ++i) + vsir_validate_src_param(ctx, &instruction->src[i]); + + if (instruction->handler_idx >= VKD3DSIH_INVALID) + { + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER, "Invalid instruction handler %#x.", + instruction->handler_idx); + } +} + +void vsir_validate(struct vkd3d_shader_parser *parser) +{ + struct validation_context ctx = { .parser = parser }; + + if (!(parser->config_flags & VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION)) + return; + + for (ctx.instruction_idx = 0; ctx.instruction_idx < parser->instructions.count; ++ctx.instruction_idx) + vsir_validate_instruction(&ctx); +} diff --git a/libs/vkd3d/libs/vkd3d-shader/preproc.h b/libs/vkd3d/libs/vkd3d-shader/preproc.h index 4860cf5f90e..e1cb75e177c 100644 --- a/libs/vkd3d/libs/vkd3d-shader/preproc.h +++ b/libs/vkd3d/libs/vkd3d-shader/preproc.h @@ -22,7 +22,7 @@ #define __VKD3D_SHADER_PREPROC_H #include "vkd3d_shader_private.h" -#include "wine/rbtree.h" +#include "rbtree.h" struct preproc_if_state { diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c index 638764b81bc..1c8b52e6d37 100644 --- a/libs/vkd3d/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c @@ -18,7 +18,7 @@ */ #include "vkd3d_shader_private.h" -#include "wine/rbtree.h" +#include "rbtree.h" #include #include @@ -1215,10 +1215,14 @@ static uint32_t vkd3d_spirv_build_op_function_call(struct vkd3d_spirv_builder *b SpvOpFunctionCall, result_type, function_id, arguments, argument_count); } -static uint32_t vkd3d_spirv_build_op_undef(struct vkd3d_spirv_builder *builder, - struct vkd3d_spirv_stream *stream, uint32_t type_id) +static uint32_t vkd3d_spirv_build_op_undef(struct vkd3d_spirv_builder *builder, uint32_t type_id) { - return vkd3d_spirv_build_op_tr(builder, stream, SpvOpUndef, type_id); + return vkd3d_spirv_build_op_tr(builder, &builder->global_stream, SpvOpUndef, type_id); +} + +static uint32_t vkd3d_spirv_get_op_undef(struct vkd3d_spirv_builder *builder, uint32_t type_id) +{ + return vkd3d_spirv_build_once1(builder, SpvOpUndef, type_id, vkd3d_spirv_build_op_undef); } static uint32_t vkd3d_spirv_build_op_access_chain(struct vkd3d_spirv_builder *builder, @@ -1710,6 +1714,15 @@ static uint32_t vkd3d_spirv_build_op_glsl_std450_cos(struct vkd3d_spirv_builder return vkd3d_spirv_build_op_glsl_std450_tr1(builder, GLSLstd450Cos, result_type, operand); } +static uint32_t vkd3d_spirv_build_op_glsl_std450_max(struct vkd3d_spirv_builder *builder, + uint32_t result_type, uint32_t x, uint32_t y) +{ + uint32_t glsl_std450_id = vkd3d_spirv_get_glsl_std450_instr_set(builder); + uint32_t operands[] = {x, y}; + return vkd3d_spirv_build_op_ext_inst(builder, result_type, glsl_std450_id, + GLSLstd450NMax, operands, ARRAY_SIZE(operands)); +} + static uint32_t vkd3d_spirv_build_op_glsl_std450_nclamp(struct vkd3d_spirv_builder *builder, uint32_t result_type, uint32_t x, uint32_t min, uint32_t max) { @@ -2323,6 +2336,9 @@ struct spirv_compiler bool write_tess_geom_point_size; struct vkd3d_string_buffer_cache string_buffers; + + uint32_t *ssa_register_ids; + unsigned int ssa_register_count; }; static bool is_in_default_phase(const struct spirv_compiler *compiler) @@ -2370,6 +2386,8 @@ static void spirv_compiler_destroy(struct spirv_compiler *compiler) shader_signature_cleanup(&compiler->output_signature); shader_signature_cleanup(&compiler->patch_constant_signature); + vkd3d_free(compiler->ssa_register_ids); + vkd3d_free(compiler); } @@ -2850,7 +2868,7 @@ static uint32_t spirv_compiler_get_constant(struct spirv_compiler *compiler, break; default: FIXME("Unhandled component_type %#x.\n", component_type); - return vkd3d_spirv_build_op_undef(builder, &builder->global_stream, type_id); + return vkd3d_spirv_get_op_undef(builder, type_id); } if (component_count == 1) @@ -2879,7 +2897,7 @@ static uint32_t spirv_compiler_get_constant64(struct spirv_compiler *compiler, if (component_type != VKD3D_SHADER_COMPONENT_DOUBLE) { FIXME("Unhandled component_type %#x.\n", component_type); - return vkd3d_spirv_build_op_undef(builder, &builder->global_stream, type_id); + return vkd3d_spirv_get_op_undef(builder, type_id); } if (component_count == 1) @@ -2914,6 +2932,12 @@ static uint32_t spirv_compiler_get_constant_vector(struct spirv_compiler *compil return spirv_compiler_get_constant(compiler, component_type, component_count, values); } +static uint32_t spirv_compiler_get_constant_int_vector(struct spirv_compiler *compiler, + uint32_t value, unsigned int component_count) +{ + return spirv_compiler_get_constant_vector(compiler, VKD3D_SHADER_COMPONENT_INT, component_count, value); +} + static uint32_t spirv_compiler_get_constant_uint_vector(struct spirv_compiler *compiler, uint32_t value, unsigned int component_count) { @@ -2979,9 +3003,11 @@ static bool spirv_compiler_get_register_name(char *buffer, unsigned int buffer_s snprintf(buffer, buffer_size, "vicp%u", idx); break; case VKD3DSPR_OUTPUT: - case VKD3DSPR_COLOROUT: snprintf(buffer, buffer_size, "o%u", idx); break; + case VKD3DSPR_COLOROUT: + snprintf(buffer, buffer_size, "oC%u", idx); + break; case VKD3DSPR_DEPTHOUT: case VKD3DSPR_DEPTHOUTGE: case VKD3DSPR_DEPTHOUTLE: @@ -3576,7 +3602,7 @@ static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compile assert(reg->type == VKD3DSPR_IMMCONST); - if (reg->immconst_type == VKD3D_IMMCONST_SCALAR) + if (reg->dimension == VSIR_DIMENSION_SCALAR) { for (i = 0; i < component_count; ++i) values[i] = *reg->u.immconst_uint; @@ -3603,7 +3629,7 @@ static uint32_t spirv_compiler_emit_load_constant64(struct spirv_compiler *compi assert(reg->type == VKD3DSPR_IMMCONST64); - if (reg->immconst_type == VKD3D_IMMCONST_SCALAR) + if (reg->dimension == VSIR_DIMENSION_SCALAR) { for (i = 0; i < component_count; ++i) values[i] = *reg->u.immconst_uint64; @@ -3631,7 +3657,7 @@ static uint32_t spirv_compiler_emit_load_undef(struct spirv_compiler *compiler, assert(reg->type == VKD3DSPR_UNDEF); type_id = vkd3d_spirv_get_type_id_for_data_type(builder, reg->data_type, component_count); - return vkd3d_spirv_build_op_undef(builder, &builder->global_stream, type_id); + return vkd3d_spirv_get_op_undef(builder, type_id); } static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, @@ -3682,6 +3708,22 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, return val_id; } +static uint32_t spirv_compiler_get_ssa_register_id(const struct spirv_compiler *compiler, + const struct vkd3d_shader_register *reg) +{ + assert(reg->idx[0].offset < compiler->ssa_register_count); + assert(reg->idx_count == 1); + return compiler->ssa_register_ids[reg->idx[0].offset]; +} + +static void spirv_compiler_set_ssa_register_id(const struct spirv_compiler *compiler, + const struct vkd3d_shader_register *reg, uint32_t val_id) +{ + unsigned int i = reg->idx[0].offset; + assert(i < compiler->ssa_register_count); + compiler->ssa_register_ids[i] = val_id; +} + static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask) { @@ -3701,10 +3743,14 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, component_count = vkd3d_write_mask_component_count(write_mask); component_type = vkd3d_component_type_from_data_type(reg->data_type); + + if (reg->type == VKD3DSPR_SSA) + return spirv_compiler_get_ssa_register_id(compiler, reg); + if (!spirv_compiler_get_register_info(compiler, reg, ®_info)) { type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); - return vkd3d_spirv_build_op_undef(builder, &builder->global_stream, type_id); + return vkd3d_spirv_get_op_undef(builder, type_id); } assert(reg_info.component_type != VKD3D_SHADER_COMPONENT_DOUBLE); spirv_compiler_emit_dereference_register(compiler, reg, ®_info); @@ -3912,6 +3958,12 @@ static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler, assert(!register_is_constant_or_undef(reg)); + if (reg->type == VKD3DSPR_SSA) + { + spirv_compiler_set_ssa_register_id(compiler, reg, val_id); + return; + } + if (!spirv_compiler_get_register_info(compiler, reg, ®_info)) return; spirv_compiler_emit_dereference_register(compiler, reg, ®_info); @@ -4361,11 +4413,7 @@ static uint32_t spirv_compiler_get_invocation_id(struct spirv_compiler *compiler assert(compiler->shader_type == VKD3D_SHADER_TYPE_HULL); - memset(&r, 0, sizeof(r)); - r.type = VKD3DSPR_OUTPOINTID; - r.idx[0].offset = ~0u; - r.idx[1].offset = ~0u; - r.idx_count = 0; + vsir_register_init(&r, VKD3DSPR_OUTPOINTID, VKD3D_DATA_FLOAT, 0); return spirv_compiler_get_register_id(compiler, &r); } @@ -5015,6 +5063,9 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, if (is_patch_constant) location += shader_signature_next_location(&compiler->output_signature); + else if (compiler->shader_type == VKD3D_SHADER_TYPE_PIXEL + && signature_element->sysval_semantic == VKD3D_SHADER_SV_TARGET) + location = signature_element->semantic_index; id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream, storage_class, component_type, output_component_count, array_sizes, 2); @@ -5262,10 +5313,7 @@ static void spirv_compiler_emit_hull_shader_builtins(struct spirv_compiler *comp struct vkd3d_shader_dst_param dst; memset(&dst, 0, sizeof(dst)); - dst.reg.type = VKD3DSPR_OUTPOINTID; - dst.reg.idx[0].offset = ~0u; - dst.reg.idx[1].offset = ~0u; - dst.reg.idx_count = 0; + vsir_register_init(&dst.reg, VKD3DSPR_OUTPOINTID, VKD3D_DATA_FLOAT, 0); dst.write_mask = VKD3DSP_WRITEMASK_0; spirv_compiler_emit_input_register(compiler, &dst); } @@ -5375,6 +5423,18 @@ static void spirv_compiler_emit_temps(struct spirv_compiler *compiler, uint32_t vkd3d_spirv_end_function_stream_insertion(builder); } +static void spirv_compiler_allocate_ssa_register_ids(struct spirv_compiler *compiler, unsigned int count) +{ + assert(!compiler->ssa_register_ids); + if (!(compiler->ssa_register_ids = vkd3d_calloc(count, sizeof(*compiler->ssa_register_ids)))) + { + ERR("Failed to allocate SSA register value id array, count %u.\n", count); + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_OUT_OF_MEMORY, + "Failed to allocate SSA register value id array of count %u.", count); + } + compiler->ssa_register_count = count; +} + static void spirv_compiler_emit_dcl_indexable_temp(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { @@ -5388,11 +5448,8 @@ static void spirv_compiler_emit_dcl_indexable_temp(struct spirv_compiler *compil if (temp->component_count != 4) FIXME("Unhandled component count %u.\n", temp->component_count); - memset(®, 0, sizeof(reg)); - reg.type = VKD3DSPR_IDXTEMP; + vsir_register_init(®, VKD3DSPR_IDXTEMP, VKD3D_DATA_FLOAT, 1); reg.idx[0].offset = temp->register_idx; - reg.idx[1].offset = ~0u; - reg.idx_count = 1; function_location = spirv_compiler_get_current_function_location(compiler); vkd3d_spirv_begin_function_stream_insertion(builder, function_location); @@ -5461,13 +5518,14 @@ static void spirv_compiler_emit_push_constant_buffers(struct spirv_compiler *com struct_id = vkd3d_spirv_build_op_type_struct(builder, member_ids, count); vkd3d_spirv_build_op_decorate(builder, struct_id, SpvDecorationBlock, NULL, 0); - vkd3d_spirv_build_op_name(builder, struct_id, "push_cb"); + vkd3d_spirv_build_op_name(builder, struct_id, "push_cb_struct"); vkd3d_free(member_ids); pointer_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, struct_id); var_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream, pointer_type_id, storage_class, 0); compiler->push_constants_var_id = var_id; + vkd3d_spirv_build_op_name(builder, var_id, "push_cb"); for (i = 0, j = 0; i < compiler->shader_interface.push_constant_buffer_count; ++i) { @@ -5571,15 +5629,14 @@ static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler, const SpvStorageClass storage_class = SpvStorageClassUniform; struct vkd3d_push_constant_buffer_binding *push_cb; struct vkd3d_descriptor_variable_info var_info; + struct vkd3d_shader_register reg; struct vkd3d_symbol reg_symbol; unsigned int size; - struct vkd3d_shader_register reg = - { - .type = VKD3DSPR_CONSTBUFFER, - .idx[0].offset = register_id, - .idx_count = 1, - }; + vsir_register_init(®, VKD3DSPR_CONSTBUFFER, VKD3D_DATA_FLOAT, 3); + reg.idx[0].offset = register_id; + reg.idx[1].offset = range->first; + reg.idx[2].offset = range->last; size = size_in_bytes / (VKD3D_VEC4_SIZE * sizeof(uint32_t)); @@ -5644,8 +5701,7 @@ static void spirv_compiler_emit_dcl_immediate_constant_buffer(struct spirv_compi vkd3d_spirv_build_op_name(builder, icb_id, "icb"); vkd3d_free(elements); - memset(®, 0, sizeof(reg)); - reg.type = VKD3DSPR_IMMCONSTBUFFER; + vsir_register_init(®, VKD3DSPR_IMMCONSTBUFFER, VKD3D_DATA_FLOAT, 0); vkd3d_symbol_make_register(®_symbol, ®); vkd3d_symbol_set_register_info(®_symbol, icb_id, SpvStorageClassPrivate, VKD3D_SHADER_COMPONENT_FLOAT, VKD3DSP_WRITEMASK_ALL); @@ -5658,15 +5714,12 @@ static void spirv_compiler_emit_sampler_declaration(struct spirv_compiler *compi const SpvStorageClass storage_class = SpvStorageClassUniformConstant; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; struct vkd3d_descriptor_variable_info var_info; + struct vkd3d_shader_register reg; struct vkd3d_symbol reg_symbol; uint32_t type_id, var_id; - const struct vkd3d_shader_register reg = - { - .type = VKD3DSPR_SAMPLER, - .idx[0].offset = register_id, - .idx_count = 1, - }; + vsir_register_init(®, VKD3DSPR_SAMPLER, VKD3D_DATA_FLOAT, 1); + reg.idx[0].offset = register_id; vkd3d_symbol_make_sampler(®_symbol, ®); reg_symbol.info.sampler.range = *range; @@ -5872,13 +5925,10 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp const struct vkd3d_spirv_resource_type *resource_type_info; enum vkd3d_shader_component_type sampled_type; struct vkd3d_symbol resource_symbol; + struct vkd3d_shader_register reg; - struct vkd3d_shader_register reg = - { - .type = is_uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE, - .idx[0].offset = register_id, - .idx_count = 1, - }; + vsir_register_init(®, is_uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE, VKD3D_DATA_FLOAT, 1); + reg.idx[0].offset = register_id; if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS && sample_count == 1) resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; @@ -6361,20 +6411,13 @@ static void spirv_compiler_emit_default_control_point_phase(struct spirv_compile invocation_id = spirv_compiler_emit_load_invocation_id(compiler); memset(&invocation, 0, sizeof(invocation)); - invocation.reg.type = VKD3DSPR_OUTPOINTID; - invocation.reg.data_type = VKD3D_DATA_INT; - invocation.reg.idx[0].offset = ~0u; - invocation.reg.idx[1].offset = ~0u; - invocation.reg.idx[2].offset = ~0u; - invocation.reg.idx_count = 0; + vsir_register_init(&invocation.reg, VKD3DSPR_OUTPOINTID, VKD3D_DATA_INT, 0); invocation.swizzle = VKD3D_SHADER_NO_SWIZZLE; - memset(&input_reg, 0, sizeof(input_reg)); - input_reg.type = VKD3DSPR_INPUT; - input_reg.data_type = VKD3D_DATA_FLOAT; + vsir_register_init(&input_reg, VKD3DSPR_INPUT, VKD3D_DATA_FLOAT, 2); + input_reg.idx[0].offset = 0; input_reg.idx[0].rel_addr = &invocation; - input_reg.idx[2].offset = ~0u; - input_reg.idx_count = 2; + input_reg.idx[1].offset = 0; input_id = spirv_compiler_get_register_id(compiler, &input_reg); assert(input_signature->element_count == output_signature->element_count); @@ -6521,8 +6564,6 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru {VKD3DSIH_DTOI, SpvOpConvertFToS}, {VKD3DSIH_DTOU, SpvOpConvertFToU}, {VKD3DSIH_FTOD, SpvOpFConvert}, - {VKD3DSIH_FTOI, SpvOpConvertFToS}, - {VKD3DSIH_FTOU, SpvOpConvertFToU}, {VKD3DSIH_IADD, SpvOpIAdd}, {VKD3DSIH_INEG, SpvOpSNegate}, {VKD3DSIH_ISHL, SpvOpShiftLeftLogical}, @@ -6694,7 +6735,8 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, uint32_t components[VKD3D_VEC4_SIZE]; unsigned int i, component_count; - if (register_is_constant_or_undef(&src->reg) || dst->modifiers || src->modifiers) + if (register_is_constant_or_undef(&src->reg) || src->reg.type == VKD3DSPR_SSA || dst->reg.type == VKD3DSPR_SSA + || dst->modifiers || src->modifiers) goto general_implementation; spirv_compiler_get_register_info(compiler, &dst->reg, &dst_reg_info); @@ -6988,6 +7030,84 @@ static void spirv_compiler_emit_udiv(struct spirv_compiler *compiler, } } +static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler, + const struct vkd3d_shader_instruction *instruction) +{ + uint32_t src_id, int_min_id, int_max_id, zero_id, float_max_id, condition_id, val_id; + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + const struct vkd3d_shader_dst_param *dst = instruction->dst; + const struct vkd3d_shader_src_param *src = instruction->src; + uint32_t src_type_id, dst_type_id, condition_type_id; + unsigned int component_count; + + assert(instruction->dst_count == 1); + assert(instruction->src_count == 1); + + /* OpConvertFToI has undefined results if the result cannot be represented + * as a signed integer, but Direct3D expects the result to saturate, + * and for NaN to yield zero. */ + + component_count = vkd3d_write_mask_component_count(dst->write_mask); + src_type_id = spirv_compiler_get_type_id_for_reg(compiler, &src->reg, dst->write_mask); + dst_type_id = spirv_compiler_get_type_id_for_dst(compiler, dst); + src_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); + + int_min_id = spirv_compiler_get_constant_float_vector(compiler, -2147483648.0f, component_count); + val_id = vkd3d_spirv_build_op_glsl_std450_max(builder, src_type_id, src_id, int_min_id); + + float_max_id = spirv_compiler_get_constant_float_vector(compiler, 2147483648.0f, component_count); + int_max_id = spirv_compiler_get_constant_int_vector(compiler, INT_MAX, component_count); + condition_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); + condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, + SpvOpFOrdGreaterThanEqual, condition_type_id, val_id, float_max_id); + + val_id = vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, SpvOpConvertFToS, dst_type_id, val_id); + val_id = vkd3d_spirv_build_op_select(builder, dst_type_id, condition_id, int_max_id, val_id); + + zero_id = spirv_compiler_get_constant_int_vector(compiler, 0, component_count); + condition_id = vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, SpvOpIsNan, condition_type_id, src_id); + val_id = vkd3d_spirv_build_op_select(builder, dst_type_id, condition_id, zero_id, val_id); + + spirv_compiler_emit_store_dst(compiler, dst, val_id); +} + +static void spirv_compiler_emit_ftou(struct spirv_compiler *compiler, + const struct vkd3d_shader_instruction *instruction) +{ + uint32_t src_id, zero_id, uint_max_id, float_max_id, condition_id, val_id; + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + const struct vkd3d_shader_dst_param *dst = instruction->dst; + const struct vkd3d_shader_src_param *src = instruction->src; + uint32_t src_type_id, dst_type_id, condition_type_id; + unsigned int component_count; + + assert(instruction->dst_count == 1); + assert(instruction->src_count == 1); + + /* OpConvertFToU has undefined results if the result cannot be represented + * as an unsigned integer, but Direct3D expects the result to saturate, + * and for NaN to yield zero. */ + + component_count = vkd3d_write_mask_component_count(dst->write_mask); + src_type_id = spirv_compiler_get_type_id_for_reg(compiler, &src->reg, dst->write_mask); + dst_type_id = spirv_compiler_get_type_id_for_dst(compiler, dst); + src_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); + + zero_id = spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count); + val_id = vkd3d_spirv_build_op_glsl_std450_max(builder, src_type_id, src_id, zero_id); + + float_max_id = spirv_compiler_get_constant_float_vector(compiler, 4294967296.0f, component_count); + uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, UINT_MAX, component_count); + condition_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); + condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, + SpvOpFOrdGreaterThanEqual, condition_type_id, val_id, float_max_id); + + val_id = vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, SpvOpConvertFToU, dst_type_id, val_id); + val_id = vkd3d_spirv_build_op_select(builder, dst_type_id, condition_id, uint_max_id, val_id); + + spirv_compiler_emit_store_dst(compiler, dst, val_id); +} + static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { @@ -9259,8 +9379,6 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VKD3DSIH_DTOI: case VKD3DSIH_DTOU: case VKD3DSIH_FTOD: - case VKD3DSIH_FTOI: - case VKD3DSIH_FTOU: case VKD3DSIH_IADD: case VKD3DSIH_INEG: case VKD3DSIH_ISHL: @@ -9321,6 +9439,12 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VKD3DSIH_UDIV: spirv_compiler_emit_udiv(compiler, instruction); break; + case VKD3DSIH_FTOI: + spirv_compiler_emit_ftoi(compiler, instruction); + break; + case VKD3DSIH_FTOU: + spirv_compiler_emit_ftou(compiler, instruction); + break; case VKD3DSIH_DEQ: case VKD3DSIH_DGE: case VKD3DSIH_DLT: @@ -9543,6 +9667,8 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, if (parser->shader_desc.temp_count) spirv_compiler_emit_temps(compiler, parser->shader_desc.temp_count); + if (parser->shader_desc.ssa_count) + spirv_compiler_allocate_ssa_register_ids(compiler, parser->shader_desc.ssa_count); spirv_compiler_emit_descriptor_declarations(compiler); diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c index 045fb6c5f64..c471d1c586b 100644 --- a/libs/vkd3d/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c @@ -383,6 +383,8 @@ enum vkd3d_sm4_opcode VKD3D_SM5_OP_SAMPLE_GRAD_CL_S = 0xe8, VKD3D_SM5_OP_SAMPLE_C_CL_S = 0xe9, VKD3D_SM5_OP_CHECK_ACCESS_FULLY_MAPPED = 0xea, + + VKD3D_SM4_OP_COUNT, }; enum vkd3d_sm4_instruction_modifier @@ -510,6 +512,8 @@ enum vkd3d_sm4_swizzle_type VKD3D_SM4_SWIZZLE_NONE = 0x0, /* swizzle bitfield contains a mask */ VKD3D_SM4_SWIZZLE_VEC4 = 0x1, VKD3D_SM4_SWIZZLE_SCALAR = 0x2, + + VKD3D_SM4_SWIZZLE_INVALID = ~0u, }; enum vkd3d_sm4_dimension @@ -519,6 +523,36 @@ enum vkd3d_sm4_dimension VKD3D_SM4_DIMENSION_VEC4 = 0x2, }; +static enum vsir_dimension vsir_dimension_from_sm4_dimension(enum vkd3d_sm4_dimension dim) +{ + switch (dim) + { + case VKD3D_SM4_DIMENSION_NONE: + return VSIR_DIMENSION_NONE; + case VKD3D_SM4_DIMENSION_SCALAR: + return VSIR_DIMENSION_SCALAR; + case VKD3D_SM4_DIMENSION_VEC4: + return VSIR_DIMENSION_VEC4; + default: + FIXME("Unknown SM4 dimension %#x.\n", dim); + return VSIR_DIMENSION_NONE; + } +} + +static enum vkd3d_sm4_dimension sm4_dimension_from_vsir_dimension(enum vsir_dimension dim) +{ + switch (dim) + { + case VSIR_DIMENSION_NONE: + return VKD3D_SM4_DIMENSION_NONE; + case VSIR_DIMENSION_SCALAR: + return VKD3D_SM4_DIMENSION_SCALAR; + case VSIR_DIMENSION_VEC4: + return VKD3D_SM4_DIMENSION_VEC4; + } + vkd3d_unreachable(); +} + enum vkd3d_sm4_resource_type { VKD3D_SM4_RESOURCE_BUFFER = 0x1, @@ -575,6 +609,7 @@ struct sm4_index_range_array struct vkd3d_sm4_lookup_tables { + const struct vkd3d_sm4_opcode_info *opcode_info_from_sm4[VKD3D_SM4_OP_COUNT]; const struct vkd3d_sm4_register_type_info *register_type_info_from_sm4[VKD3D_SM4_REGISTER_TYPE_COUNT]; const struct vkd3d_sm4_register_type_info *register_type_info_from_vkd3d[VKD3DSPR_COUNT]; }; @@ -583,8 +618,6 @@ struct vkd3d_shader_sm4_parser { const uint32_t *start, *end, *ptr; - unsigned int output_map[MAX_REG_OUTPUT]; - enum vkd3d_shader_opcode phase; bool has_control_point_phase; unsigned int input_register_masks[MAX_REG_OUTPUT]; @@ -1211,291 +1244,13 @@ static void shader_sm5_read_sync(struct vkd3d_shader_instruction *ins, uint32_t ins->flags = (opcode_token & VKD3D_SM5_SYNC_FLAGS_MASK) >> VKD3D_SM5_SYNC_FLAGS_SHIFT; } -/* - * d -> VKD3D_DATA_DOUBLE - * f -> VKD3D_DATA_FLOAT - * i -> VKD3D_DATA_INT - * u -> VKD3D_DATA_UINT - * O -> VKD3D_DATA_OPAQUE - * R -> VKD3D_DATA_RESOURCE - * S -> VKD3D_DATA_SAMPLER - * U -> VKD3D_DATA_UAV - */ -static const struct vkd3d_sm4_opcode_info opcode_table[] = -{ - {VKD3D_SM4_OP_ADD, VKD3DSIH_ADD, "f", "ff"}, - {VKD3D_SM4_OP_AND, VKD3DSIH_AND, "u", "uu"}, - {VKD3D_SM4_OP_BREAK, VKD3DSIH_BREAK, "", ""}, - {VKD3D_SM4_OP_BREAKC, VKD3DSIH_BREAKP, "", "u", - shader_sm4_read_conditional_op}, - {VKD3D_SM4_OP_CASE, VKD3DSIH_CASE, "", "u", - shader_sm4_read_case_condition}, - {VKD3D_SM4_OP_CONTINUE, VKD3DSIH_CONTINUE, "", ""}, - {VKD3D_SM4_OP_CONTINUEC, VKD3DSIH_CONTINUEP, "", "u", - shader_sm4_read_conditional_op}, - {VKD3D_SM4_OP_CUT, VKD3DSIH_CUT, "", ""}, - {VKD3D_SM4_OP_DEFAULT, VKD3DSIH_DEFAULT, "", ""}, - {VKD3D_SM4_OP_DERIV_RTX, VKD3DSIH_DSX, "f", "f"}, - {VKD3D_SM4_OP_DERIV_RTY, VKD3DSIH_DSY, "f", "f"}, - {VKD3D_SM4_OP_DISCARD, VKD3DSIH_DISCARD, "", "u", - shader_sm4_read_conditional_op}, - {VKD3D_SM4_OP_DIV, VKD3DSIH_DIV, "f", "ff"}, - {VKD3D_SM4_OP_DP2, VKD3DSIH_DP2, "f", "ff"}, - {VKD3D_SM4_OP_DP3, VKD3DSIH_DP3, "f", "ff"}, - {VKD3D_SM4_OP_DP4, VKD3DSIH_DP4, "f", "ff"}, - {VKD3D_SM4_OP_ELSE, VKD3DSIH_ELSE, "", ""}, - {VKD3D_SM4_OP_EMIT, VKD3DSIH_EMIT, "", ""}, - {VKD3D_SM4_OP_ENDIF, VKD3DSIH_ENDIF, "", ""}, - {VKD3D_SM4_OP_ENDLOOP, VKD3DSIH_ENDLOOP, "", ""}, - {VKD3D_SM4_OP_ENDSWITCH, VKD3DSIH_ENDSWITCH, "", ""}, - {VKD3D_SM4_OP_EQ, VKD3DSIH_EQ, "u", "ff"}, - {VKD3D_SM4_OP_EXP, VKD3DSIH_EXP, "f", "f"}, - {VKD3D_SM4_OP_FRC, VKD3DSIH_FRC, "f", "f"}, - {VKD3D_SM4_OP_FTOI, VKD3DSIH_FTOI, "i", "f"}, - {VKD3D_SM4_OP_FTOU, VKD3DSIH_FTOU, "u", "f"}, - {VKD3D_SM4_OP_GE, VKD3DSIH_GE, "u", "ff"}, - {VKD3D_SM4_OP_IADD, VKD3DSIH_IADD, "i", "ii"}, - {VKD3D_SM4_OP_IF, VKD3DSIH_IF, "", "u", - shader_sm4_read_conditional_op}, - {VKD3D_SM4_OP_IEQ, VKD3DSIH_IEQ, "u", "ii"}, - {VKD3D_SM4_OP_IGE, VKD3DSIH_IGE, "u", "ii"}, - {VKD3D_SM4_OP_ILT, VKD3DSIH_ILT, "u", "ii"}, - {VKD3D_SM4_OP_IMAD, VKD3DSIH_IMAD, "i", "iii"}, - {VKD3D_SM4_OP_IMAX, VKD3DSIH_IMAX, "i", "ii"}, - {VKD3D_SM4_OP_IMIN, VKD3DSIH_IMIN, "i", "ii"}, - {VKD3D_SM4_OP_IMUL, VKD3DSIH_IMUL, "ii", "ii"}, - {VKD3D_SM4_OP_INE, VKD3DSIH_INE, "u", "ii"}, - {VKD3D_SM4_OP_INEG, VKD3DSIH_INEG, "i", "i"}, - {VKD3D_SM4_OP_ISHL, VKD3DSIH_ISHL, "i", "ii"}, - {VKD3D_SM4_OP_ISHR, VKD3DSIH_ISHR, "i", "ii"}, - {VKD3D_SM4_OP_ITOF, VKD3DSIH_ITOF, "f", "i"}, - {VKD3D_SM4_OP_LABEL, VKD3DSIH_LABEL, "", "O"}, - {VKD3D_SM4_OP_LD, VKD3DSIH_LD, "u", "iR"}, - {VKD3D_SM4_OP_LD2DMS, VKD3DSIH_LD2DMS, "u", "iRi"}, - {VKD3D_SM4_OP_LOG, VKD3DSIH_LOG, "f", "f"}, - {VKD3D_SM4_OP_LOOP, VKD3DSIH_LOOP, "", ""}, - {VKD3D_SM4_OP_LT, VKD3DSIH_LT, "u", "ff"}, - {VKD3D_SM4_OP_MAD, VKD3DSIH_MAD, "f", "fff"}, - {VKD3D_SM4_OP_MIN, VKD3DSIH_MIN, "f", "ff"}, - {VKD3D_SM4_OP_MAX, VKD3DSIH_MAX, "f", "ff"}, - {VKD3D_SM4_OP_SHADER_DATA, VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER, "", "", - shader_sm4_read_shader_data}, - {VKD3D_SM4_OP_MOV, VKD3DSIH_MOV, "f", "f"}, - {VKD3D_SM4_OP_MOVC, VKD3DSIH_MOVC, "f", "uff"}, - {VKD3D_SM4_OP_MUL, VKD3DSIH_MUL, "f", "ff"}, - {VKD3D_SM4_OP_NE, VKD3DSIH_NE, "u", "ff"}, - {VKD3D_SM4_OP_NOP, VKD3DSIH_NOP, "", ""}, - {VKD3D_SM4_OP_NOT, VKD3DSIH_NOT, "u", "u"}, - {VKD3D_SM4_OP_OR, VKD3DSIH_OR, "u", "uu"}, - {VKD3D_SM4_OP_RESINFO, VKD3DSIH_RESINFO, "f", "iR"}, - {VKD3D_SM4_OP_RET, VKD3DSIH_RET, "", ""}, - {VKD3D_SM4_OP_RETC, VKD3DSIH_RETP, "", "u", - shader_sm4_read_conditional_op}, - {VKD3D_SM4_OP_ROUND_NE, VKD3DSIH_ROUND_NE, "f", "f"}, - {VKD3D_SM4_OP_ROUND_NI, VKD3DSIH_ROUND_NI, "f", "f"}, - {VKD3D_SM4_OP_ROUND_PI, VKD3DSIH_ROUND_PI, "f", "f"}, - {VKD3D_SM4_OP_ROUND_Z, VKD3DSIH_ROUND_Z, "f", "f"}, - {VKD3D_SM4_OP_RSQ, VKD3DSIH_RSQ, "f", "f"}, - {VKD3D_SM4_OP_SAMPLE, VKD3DSIH_SAMPLE, "u", "fRS"}, - {VKD3D_SM4_OP_SAMPLE_C, VKD3DSIH_SAMPLE_C, "f", "fRSf"}, - {VKD3D_SM4_OP_SAMPLE_C_LZ, VKD3DSIH_SAMPLE_C_LZ, "f", "fRSf"}, - {VKD3D_SM4_OP_SAMPLE_LOD, VKD3DSIH_SAMPLE_LOD, "u", "fRSf"}, - {VKD3D_SM4_OP_SAMPLE_GRAD, VKD3DSIH_SAMPLE_GRAD, "u", "fRSff"}, - {VKD3D_SM4_OP_SAMPLE_B, VKD3DSIH_SAMPLE_B, "u", "fRSf"}, - {VKD3D_SM4_OP_SQRT, VKD3DSIH_SQRT, "f", "f"}, - {VKD3D_SM4_OP_SWITCH, VKD3DSIH_SWITCH, "", "i"}, - {VKD3D_SM4_OP_SINCOS, VKD3DSIH_SINCOS, "ff", "f"}, - {VKD3D_SM4_OP_UDIV, VKD3DSIH_UDIV, "uu", "uu"}, - {VKD3D_SM4_OP_ULT, VKD3DSIH_ULT, "u", "uu"}, - {VKD3D_SM4_OP_UGE, VKD3DSIH_UGE, "u", "uu"}, - {VKD3D_SM4_OP_UMUL, VKD3DSIH_UMUL, "uu", "uu"}, - {VKD3D_SM4_OP_UMAX, VKD3DSIH_UMAX, "u", "uu"}, - {VKD3D_SM4_OP_UMIN, VKD3DSIH_UMIN, "u", "uu"}, - {VKD3D_SM4_OP_USHR, VKD3DSIH_USHR, "u", "uu"}, - {VKD3D_SM4_OP_UTOF, VKD3DSIH_UTOF, "f", "u"}, - {VKD3D_SM4_OP_XOR, VKD3DSIH_XOR, "u", "uu"}, - {VKD3D_SM4_OP_DCL_RESOURCE, VKD3DSIH_DCL, "", "", - shader_sm4_read_dcl_resource}, - {VKD3D_SM4_OP_DCL_CONSTANT_BUFFER, VKD3DSIH_DCL_CONSTANT_BUFFER, "", "", - shader_sm4_read_dcl_constant_buffer}, - {VKD3D_SM4_OP_DCL_SAMPLER, VKD3DSIH_DCL_SAMPLER, "", "", - shader_sm4_read_dcl_sampler}, - {VKD3D_SM4_OP_DCL_INDEX_RANGE, VKD3DSIH_DCL_INDEX_RANGE, "", "", - shader_sm4_read_dcl_index_range}, - {VKD3D_SM4_OP_DCL_OUTPUT_TOPOLOGY, VKD3DSIH_DCL_OUTPUT_TOPOLOGY, "", "", - shader_sm4_read_dcl_output_topology}, - {VKD3D_SM4_OP_DCL_INPUT_PRIMITIVE, VKD3DSIH_DCL_INPUT_PRIMITIVE, "", "", - shader_sm4_read_dcl_input_primitive}, - {VKD3D_SM4_OP_DCL_VERTICES_OUT, VKD3DSIH_DCL_VERTICES_OUT, "", "", - shader_sm4_read_declaration_count}, - {VKD3D_SM4_OP_DCL_INPUT, VKD3DSIH_DCL_INPUT, "", "", - shader_sm4_read_declaration_dst}, - {VKD3D_SM4_OP_DCL_INPUT_SGV, VKD3DSIH_DCL_INPUT_SGV, "", "", - shader_sm4_read_declaration_register_semantic}, - {VKD3D_SM4_OP_DCL_INPUT_SIV, VKD3DSIH_DCL_INPUT_SIV, "", "", - shader_sm4_read_declaration_register_semantic}, - {VKD3D_SM4_OP_DCL_INPUT_PS, VKD3DSIH_DCL_INPUT_PS, "", "", - shader_sm4_read_dcl_input_ps}, - {VKD3D_SM4_OP_DCL_INPUT_PS_SGV, VKD3DSIH_DCL_INPUT_PS_SGV, "", "", - shader_sm4_read_declaration_register_semantic}, - {VKD3D_SM4_OP_DCL_INPUT_PS_SIV, VKD3DSIH_DCL_INPUT_PS_SIV, "", "", - shader_sm4_read_dcl_input_ps_siv}, - {VKD3D_SM4_OP_DCL_OUTPUT, VKD3DSIH_DCL_OUTPUT, "", "", - shader_sm4_read_declaration_dst}, - {VKD3D_SM4_OP_DCL_OUTPUT_SIV, VKD3DSIH_DCL_OUTPUT_SIV, "", "", - shader_sm4_read_declaration_register_semantic}, - {VKD3D_SM4_OP_DCL_TEMPS, VKD3DSIH_DCL_TEMPS, "", "", - shader_sm4_read_declaration_count}, - {VKD3D_SM4_OP_DCL_INDEXABLE_TEMP, VKD3DSIH_DCL_INDEXABLE_TEMP, "", "", - shader_sm4_read_dcl_indexable_temp}, - {VKD3D_SM4_OP_DCL_GLOBAL_FLAGS, VKD3DSIH_DCL_GLOBAL_FLAGS, "", "", - shader_sm4_read_dcl_global_flags}, - {VKD3D_SM4_OP_LOD, VKD3DSIH_LOD, "f", "fRS"}, - {VKD3D_SM4_OP_GATHER4, VKD3DSIH_GATHER4, "u", "fRS"}, - {VKD3D_SM4_OP_SAMPLE_POS, VKD3DSIH_SAMPLE_POS, "f", "Ru"}, - {VKD3D_SM4_OP_SAMPLE_INFO, VKD3DSIH_SAMPLE_INFO, "f", "R"}, - {VKD3D_SM5_OP_HS_DECLS, VKD3DSIH_HS_DECLS, "", ""}, - {VKD3D_SM5_OP_HS_CONTROL_POINT_PHASE, VKD3DSIH_HS_CONTROL_POINT_PHASE, "", ""}, - {VKD3D_SM5_OP_HS_FORK_PHASE, VKD3DSIH_HS_FORK_PHASE, "", ""}, - {VKD3D_SM5_OP_HS_JOIN_PHASE, VKD3DSIH_HS_JOIN_PHASE, "", ""}, - {VKD3D_SM5_OP_EMIT_STREAM, VKD3DSIH_EMIT_STREAM, "", "f"}, - {VKD3D_SM5_OP_CUT_STREAM, VKD3DSIH_CUT_STREAM, "", "f"}, - {VKD3D_SM5_OP_FCALL, VKD3DSIH_FCALL, "", "O", - shader_sm5_read_fcall}, - {VKD3D_SM5_OP_BUFINFO, VKD3DSIH_BUFINFO, "i", "U"}, - {VKD3D_SM5_OP_DERIV_RTX_COARSE, VKD3DSIH_DSX_COARSE, "f", "f"}, - {VKD3D_SM5_OP_DERIV_RTX_FINE, VKD3DSIH_DSX_FINE, "f", "f"}, - {VKD3D_SM5_OP_DERIV_RTY_COARSE, VKD3DSIH_DSY_COARSE, "f", "f"}, - {VKD3D_SM5_OP_DERIV_RTY_FINE, VKD3DSIH_DSY_FINE, "f", "f"}, - {VKD3D_SM5_OP_GATHER4_C, VKD3DSIH_GATHER4_C, "f", "fRSf"}, - {VKD3D_SM5_OP_GATHER4_PO, VKD3DSIH_GATHER4_PO, "f", "fiRS"}, - {VKD3D_SM5_OP_GATHER4_PO_C, VKD3DSIH_GATHER4_PO_C, "f", "fiRSf"}, - {VKD3D_SM5_OP_RCP, VKD3DSIH_RCP, "f", "f"}, - {VKD3D_SM5_OP_F32TOF16, VKD3DSIH_F32TOF16, "u", "f"}, - {VKD3D_SM5_OP_F16TOF32, VKD3DSIH_F16TOF32, "f", "u"}, - {VKD3D_SM5_OP_COUNTBITS, VKD3DSIH_COUNTBITS, "u", "u"}, - {VKD3D_SM5_OP_FIRSTBIT_HI, VKD3DSIH_FIRSTBIT_HI, "u", "u"}, - {VKD3D_SM5_OP_FIRSTBIT_LO, VKD3DSIH_FIRSTBIT_LO, "u", "u"}, - {VKD3D_SM5_OP_FIRSTBIT_SHI, VKD3DSIH_FIRSTBIT_SHI, "u", "i"}, - {VKD3D_SM5_OP_UBFE, VKD3DSIH_UBFE, "u", "iiu"}, - {VKD3D_SM5_OP_IBFE, VKD3DSIH_IBFE, "i", "iii"}, - {VKD3D_SM5_OP_BFI, VKD3DSIH_BFI, "u", "iiuu"}, - {VKD3D_SM5_OP_BFREV, VKD3DSIH_BFREV, "u", "u"}, - {VKD3D_SM5_OP_SWAPC, VKD3DSIH_SWAPC, "ff", "uff"}, - {VKD3D_SM5_OP_DCL_STREAM, VKD3DSIH_DCL_STREAM, "", "O"}, - {VKD3D_SM5_OP_DCL_FUNCTION_BODY, VKD3DSIH_DCL_FUNCTION_BODY, "", "", - shader_sm5_read_dcl_function_body}, - {VKD3D_SM5_OP_DCL_FUNCTION_TABLE, VKD3DSIH_DCL_FUNCTION_TABLE, "", "", - shader_sm5_read_dcl_function_table}, - {VKD3D_SM5_OP_DCL_INTERFACE, VKD3DSIH_DCL_INTERFACE, "", "", - shader_sm5_read_dcl_interface}, - {VKD3D_SM5_OP_DCL_INPUT_CONTROL_POINT_COUNT, VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT, "", "", - shader_sm5_read_control_point_count}, - {VKD3D_SM5_OP_DCL_OUTPUT_CONTROL_POINT_COUNT, VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT, "", "", - shader_sm5_read_control_point_count}, - {VKD3D_SM5_OP_DCL_TESSELLATOR_DOMAIN, VKD3DSIH_DCL_TESSELLATOR_DOMAIN, "", "", - shader_sm5_read_dcl_tessellator_domain}, - {VKD3D_SM5_OP_DCL_TESSELLATOR_PARTITIONING, VKD3DSIH_DCL_TESSELLATOR_PARTITIONING, "", "", - shader_sm5_read_dcl_tessellator_partitioning}, - {VKD3D_SM5_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, "", "", - shader_sm5_read_dcl_tessellator_output_primitive}, - {VKD3D_SM5_OP_DCL_HS_MAX_TESSFACTOR, VKD3DSIH_DCL_HS_MAX_TESSFACTOR, "", "", - shader_sm5_read_dcl_hs_max_tessfactor}, - {VKD3D_SM5_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT, VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT, "", "", - shader_sm4_read_declaration_count}, - {VKD3D_SM5_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, "", "", - shader_sm4_read_declaration_count}, - {VKD3D_SM5_OP_DCL_THREAD_GROUP, VKD3DSIH_DCL_THREAD_GROUP, "", "", - shader_sm5_read_dcl_thread_group}, - {VKD3D_SM5_OP_DCL_UAV_TYPED, VKD3DSIH_DCL_UAV_TYPED, "", "", - shader_sm4_read_dcl_resource}, - {VKD3D_SM5_OP_DCL_UAV_RAW, VKD3DSIH_DCL_UAV_RAW, "", "", - shader_sm5_read_dcl_uav_raw}, - {VKD3D_SM5_OP_DCL_UAV_STRUCTURED, VKD3DSIH_DCL_UAV_STRUCTURED, "", "", - shader_sm5_read_dcl_uav_structured}, - {VKD3D_SM5_OP_DCL_TGSM_RAW, VKD3DSIH_DCL_TGSM_RAW, "", "", - shader_sm5_read_dcl_tgsm_raw}, - {VKD3D_SM5_OP_DCL_TGSM_STRUCTURED, VKD3DSIH_DCL_TGSM_STRUCTURED, "", "", - shader_sm5_read_dcl_tgsm_structured}, - {VKD3D_SM5_OP_DCL_RESOURCE_RAW, VKD3DSIH_DCL_RESOURCE_RAW, "", "", - shader_sm5_read_dcl_resource_raw}, - {VKD3D_SM5_OP_DCL_RESOURCE_STRUCTURED, VKD3DSIH_DCL_RESOURCE_STRUCTURED, "", "", - shader_sm5_read_dcl_resource_structured}, - {VKD3D_SM5_OP_LD_UAV_TYPED, VKD3DSIH_LD_UAV_TYPED, "u", "iU"}, - {VKD3D_SM5_OP_STORE_UAV_TYPED, VKD3DSIH_STORE_UAV_TYPED, "U", "iu"}, - {VKD3D_SM5_OP_LD_RAW, VKD3DSIH_LD_RAW, "u", "iU"}, - {VKD3D_SM5_OP_STORE_RAW, VKD3DSIH_STORE_RAW, "U", "uu"}, - {VKD3D_SM5_OP_LD_STRUCTURED, VKD3DSIH_LD_STRUCTURED, "u", "iiR"}, - {VKD3D_SM5_OP_STORE_STRUCTURED, VKD3DSIH_STORE_STRUCTURED, "U", "iiu"}, - {VKD3D_SM5_OP_ATOMIC_AND, VKD3DSIH_ATOMIC_AND, "U", "iu"}, - {VKD3D_SM5_OP_ATOMIC_OR, VKD3DSIH_ATOMIC_OR, "U", "iu"}, - {VKD3D_SM5_OP_ATOMIC_XOR, VKD3DSIH_ATOMIC_XOR, "U", "iu"}, - {VKD3D_SM5_OP_ATOMIC_CMP_STORE, VKD3DSIH_ATOMIC_CMP_STORE, "U", "iuu"}, - {VKD3D_SM5_OP_ATOMIC_IADD, VKD3DSIH_ATOMIC_IADD, "U", "ii"}, - {VKD3D_SM5_OP_ATOMIC_IMAX, VKD3DSIH_ATOMIC_IMAX, "U", "ii"}, - {VKD3D_SM5_OP_ATOMIC_IMIN, VKD3DSIH_ATOMIC_IMIN, "U", "ii"}, - {VKD3D_SM5_OP_ATOMIC_UMAX, VKD3DSIH_ATOMIC_UMAX, "U", "iu"}, - {VKD3D_SM5_OP_ATOMIC_UMIN, VKD3DSIH_ATOMIC_UMIN, "U", "iu"}, - {VKD3D_SM5_OP_IMM_ATOMIC_ALLOC, VKD3DSIH_IMM_ATOMIC_ALLOC, "u", "U"}, - {VKD3D_SM5_OP_IMM_ATOMIC_CONSUME, VKD3DSIH_IMM_ATOMIC_CONSUME, "u", "U"}, - {VKD3D_SM5_OP_IMM_ATOMIC_IADD, VKD3DSIH_IMM_ATOMIC_IADD, "uU", "ii"}, - {VKD3D_SM5_OP_IMM_ATOMIC_AND, VKD3DSIH_IMM_ATOMIC_AND, "uU", "iu"}, - {VKD3D_SM5_OP_IMM_ATOMIC_OR, VKD3DSIH_IMM_ATOMIC_OR, "uU", "iu"}, - {VKD3D_SM5_OP_IMM_ATOMIC_XOR, VKD3DSIH_IMM_ATOMIC_XOR, "uU", "iu"}, - {VKD3D_SM5_OP_IMM_ATOMIC_EXCH, VKD3DSIH_IMM_ATOMIC_EXCH, "uU", "iu"}, - {VKD3D_SM5_OP_IMM_ATOMIC_CMP_EXCH, VKD3DSIH_IMM_ATOMIC_CMP_EXCH, "uU", "iuu"}, - {VKD3D_SM5_OP_IMM_ATOMIC_IMAX, VKD3DSIH_IMM_ATOMIC_IMAX, "iU", "ii"}, - {VKD3D_SM5_OP_IMM_ATOMIC_IMIN, VKD3DSIH_IMM_ATOMIC_IMIN, "iU", "ii"}, - {VKD3D_SM5_OP_IMM_ATOMIC_UMAX, VKD3DSIH_IMM_ATOMIC_UMAX, "uU", "iu"}, - {VKD3D_SM5_OP_IMM_ATOMIC_UMIN, VKD3DSIH_IMM_ATOMIC_UMIN, "uU", "iu"}, - {VKD3D_SM5_OP_SYNC, VKD3DSIH_SYNC, "", "", - shader_sm5_read_sync}, - {VKD3D_SM5_OP_DADD, VKD3DSIH_DADD, "d", "dd"}, - {VKD3D_SM5_OP_DMAX, VKD3DSIH_DMAX, "d", "dd"}, - {VKD3D_SM5_OP_DMIN, VKD3DSIH_DMIN, "d", "dd"}, - {VKD3D_SM5_OP_DMUL, VKD3DSIH_DMUL, "d", "dd"}, - {VKD3D_SM5_OP_DEQ, VKD3DSIH_DEQ, "u", "dd"}, - {VKD3D_SM5_OP_DGE, VKD3DSIH_DGE, "u", "dd"}, - {VKD3D_SM5_OP_DLT, VKD3DSIH_DLT, "u", "dd"}, - {VKD3D_SM5_OP_DNE, VKD3DSIH_DNE, "u", "dd"}, - {VKD3D_SM5_OP_DMOV, VKD3DSIH_DMOV, "d", "d"}, - {VKD3D_SM5_OP_DMOVC, VKD3DSIH_DMOVC, "d", "udd"}, - {VKD3D_SM5_OP_DTOF, VKD3DSIH_DTOF, "f", "d"}, - {VKD3D_SM5_OP_FTOD, VKD3DSIH_FTOD, "d", "f"}, - {VKD3D_SM5_OP_EVAL_SAMPLE_INDEX, VKD3DSIH_EVAL_SAMPLE_INDEX, "f", "fi"}, - {VKD3D_SM5_OP_EVAL_CENTROID, VKD3DSIH_EVAL_CENTROID, "f", "f"}, - {VKD3D_SM5_OP_DCL_GS_INSTANCES, VKD3DSIH_DCL_GS_INSTANCES, "", "", - shader_sm4_read_declaration_count}, - {VKD3D_SM5_OP_DDIV, VKD3DSIH_DDIV, "d", "dd"}, - {VKD3D_SM5_OP_DFMA, VKD3DSIH_DFMA, "d", "ddd"}, - {VKD3D_SM5_OP_DRCP, VKD3DSIH_DRCP, "d", "d"}, - {VKD3D_SM5_OP_MSAD, VKD3DSIH_MSAD, "u", "uuu"}, - {VKD3D_SM5_OP_DTOI, VKD3DSIH_DTOI, "i", "d"}, - {VKD3D_SM5_OP_DTOU, VKD3DSIH_DTOU, "u", "d"}, - {VKD3D_SM5_OP_ITOD, VKD3DSIH_ITOD, "d", "i"}, - {VKD3D_SM5_OP_UTOD, VKD3DSIH_UTOD, "d", "u"}, - {VKD3D_SM5_OP_GATHER4_S, VKD3DSIH_GATHER4_S, "uu", "fRS"}, - {VKD3D_SM5_OP_GATHER4_C_S, VKD3DSIH_GATHER4_C_S, "fu", "fRSf"}, - {VKD3D_SM5_OP_GATHER4_PO_S, VKD3DSIH_GATHER4_PO_S, "fu", "fiRS"}, - {VKD3D_SM5_OP_GATHER4_PO_C_S, VKD3DSIH_GATHER4_PO_C_S, "fu", "fiRSf"}, - {VKD3D_SM5_OP_LD_S, VKD3DSIH_LD_S, "uu", "iR"}, - {VKD3D_SM5_OP_LD2DMS_S, VKD3DSIH_LD2DMS_S, "uu", "iRi"}, - {VKD3D_SM5_OP_LD_UAV_TYPED_S, VKD3DSIH_LD_UAV_TYPED_S, "uu", "iU"}, - {VKD3D_SM5_OP_LD_RAW_S, VKD3DSIH_LD_RAW_S, "uu", "iU"}, - {VKD3D_SM5_OP_LD_STRUCTURED_S, VKD3DSIH_LD_STRUCTURED_S, "uu", "iiR"}, - {VKD3D_SM5_OP_SAMPLE_LOD_S, VKD3DSIH_SAMPLE_LOD_S, "uu", "fRSf"}, - {VKD3D_SM5_OP_SAMPLE_C_LZ_S, VKD3DSIH_SAMPLE_C_LZ_S, "fu", "fRSf"}, - {VKD3D_SM5_OP_SAMPLE_CL_S, VKD3DSIH_SAMPLE_CL_S, "uu", "fRSf"}, - {VKD3D_SM5_OP_SAMPLE_B_CL_S, VKD3DSIH_SAMPLE_B_CL_S, "uu", "fRSff"}, - {VKD3D_SM5_OP_SAMPLE_GRAD_CL_S, VKD3DSIH_SAMPLE_GRAD_CL_S, "uu", "fRSfff"}, - {VKD3D_SM5_OP_SAMPLE_C_CL_S, VKD3DSIH_SAMPLE_C_CL_S, "fu", "fRSff"}, - {VKD3D_SM5_OP_CHECK_ACCESS_FULLY_MAPPED, VKD3DSIH_CHECK_ACCESS_FULLY_MAPPED, "u", "u"}, -}; - struct vkd3d_sm4_register_type_info { enum vkd3d_sm4_register_type sm4_type; enum vkd3d_shader_register_type vkd3d_type; + + /* Swizzle type to be used for src registers when their dimension is VKD3D_SM4_DIMENSION_VEC4. */ + enum vkd3d_sm4_swizzle_type default_src_swizzle_type; }; static const enum vkd3d_shader_register_precision register_precision_table[] = @@ -1515,69 +1270,344 @@ struct tpf_writer struct vkd3d_sm4_lookup_tables lookup; }; -static const struct vkd3d_sm4_opcode_info *get_opcode_info(enum vkd3d_sm4_opcode opcode) -{ - unsigned int i; - - for (i = 0; i < sizeof(opcode_table) / sizeof(*opcode_table); ++i) - { - if (opcode == opcode_table[i].opcode) - return &opcode_table[i]; - } - - return NULL; -} - static void init_sm4_lookup_tables(struct vkd3d_sm4_lookup_tables *lookup) { - const struct vkd3d_sm4_register_type_info *info; unsigned int i; + /* + * d -> VKD3D_DATA_DOUBLE + * f -> VKD3D_DATA_FLOAT + * i -> VKD3D_DATA_INT + * u -> VKD3D_DATA_UINT + * O -> VKD3D_DATA_OPAQUE + * R -> VKD3D_DATA_RESOURCE + * S -> VKD3D_DATA_SAMPLER + * U -> VKD3D_DATA_UAV + */ + static const struct vkd3d_sm4_opcode_info opcode_table[] = + { + {VKD3D_SM4_OP_ADD, VKD3DSIH_ADD, "f", "ff"}, + {VKD3D_SM4_OP_AND, VKD3DSIH_AND, "u", "uu"}, + {VKD3D_SM4_OP_BREAK, VKD3DSIH_BREAK, "", ""}, + {VKD3D_SM4_OP_BREAKC, VKD3DSIH_BREAKP, "", "u", + shader_sm4_read_conditional_op}, + {VKD3D_SM4_OP_CASE, VKD3DSIH_CASE, "", "u", + shader_sm4_read_case_condition}, + {VKD3D_SM4_OP_CONTINUE, VKD3DSIH_CONTINUE, "", ""}, + {VKD3D_SM4_OP_CONTINUEC, VKD3DSIH_CONTINUEP, "", "u", + shader_sm4_read_conditional_op}, + {VKD3D_SM4_OP_CUT, VKD3DSIH_CUT, "", ""}, + {VKD3D_SM4_OP_DEFAULT, VKD3DSIH_DEFAULT, "", ""}, + {VKD3D_SM4_OP_DERIV_RTX, VKD3DSIH_DSX, "f", "f"}, + {VKD3D_SM4_OP_DERIV_RTY, VKD3DSIH_DSY, "f", "f"}, + {VKD3D_SM4_OP_DISCARD, VKD3DSIH_DISCARD, "", "u", + shader_sm4_read_conditional_op}, + {VKD3D_SM4_OP_DIV, VKD3DSIH_DIV, "f", "ff"}, + {VKD3D_SM4_OP_DP2, VKD3DSIH_DP2, "f", "ff"}, + {VKD3D_SM4_OP_DP3, VKD3DSIH_DP3, "f", "ff"}, + {VKD3D_SM4_OP_DP4, VKD3DSIH_DP4, "f", "ff"}, + {VKD3D_SM4_OP_ELSE, VKD3DSIH_ELSE, "", ""}, + {VKD3D_SM4_OP_EMIT, VKD3DSIH_EMIT, "", ""}, + {VKD3D_SM4_OP_ENDIF, VKD3DSIH_ENDIF, "", ""}, + {VKD3D_SM4_OP_ENDLOOP, VKD3DSIH_ENDLOOP, "", ""}, + {VKD3D_SM4_OP_ENDSWITCH, VKD3DSIH_ENDSWITCH, "", ""}, + {VKD3D_SM4_OP_EQ, VKD3DSIH_EQ, "u", "ff"}, + {VKD3D_SM4_OP_EXP, VKD3DSIH_EXP, "f", "f"}, + {VKD3D_SM4_OP_FRC, VKD3DSIH_FRC, "f", "f"}, + {VKD3D_SM4_OP_FTOI, VKD3DSIH_FTOI, "i", "f"}, + {VKD3D_SM4_OP_FTOU, VKD3DSIH_FTOU, "u", "f"}, + {VKD3D_SM4_OP_GE, VKD3DSIH_GE, "u", "ff"}, + {VKD3D_SM4_OP_IADD, VKD3DSIH_IADD, "i", "ii"}, + {VKD3D_SM4_OP_IF, VKD3DSIH_IF, "", "u", + shader_sm4_read_conditional_op}, + {VKD3D_SM4_OP_IEQ, VKD3DSIH_IEQ, "u", "ii"}, + {VKD3D_SM4_OP_IGE, VKD3DSIH_IGE, "u", "ii"}, + {VKD3D_SM4_OP_ILT, VKD3DSIH_ILT, "u", "ii"}, + {VKD3D_SM4_OP_IMAD, VKD3DSIH_IMAD, "i", "iii"}, + {VKD3D_SM4_OP_IMAX, VKD3DSIH_IMAX, "i", "ii"}, + {VKD3D_SM4_OP_IMIN, VKD3DSIH_IMIN, "i", "ii"}, + {VKD3D_SM4_OP_IMUL, VKD3DSIH_IMUL, "ii", "ii"}, + {VKD3D_SM4_OP_INE, VKD3DSIH_INE, "u", "ii"}, + {VKD3D_SM4_OP_INEG, VKD3DSIH_INEG, "i", "i"}, + {VKD3D_SM4_OP_ISHL, VKD3DSIH_ISHL, "i", "ii"}, + {VKD3D_SM4_OP_ISHR, VKD3DSIH_ISHR, "i", "ii"}, + {VKD3D_SM4_OP_ITOF, VKD3DSIH_ITOF, "f", "i"}, + {VKD3D_SM4_OP_LABEL, VKD3DSIH_LABEL, "", "O"}, + {VKD3D_SM4_OP_LD, VKD3DSIH_LD, "u", "iR"}, + {VKD3D_SM4_OP_LD2DMS, VKD3DSIH_LD2DMS, "u", "iRi"}, + {VKD3D_SM4_OP_LOG, VKD3DSIH_LOG, "f", "f"}, + {VKD3D_SM4_OP_LOOP, VKD3DSIH_LOOP, "", ""}, + {VKD3D_SM4_OP_LT, VKD3DSIH_LT, "u", "ff"}, + {VKD3D_SM4_OP_MAD, VKD3DSIH_MAD, "f", "fff"}, + {VKD3D_SM4_OP_MIN, VKD3DSIH_MIN, "f", "ff"}, + {VKD3D_SM4_OP_MAX, VKD3DSIH_MAX, "f", "ff"}, + {VKD3D_SM4_OP_SHADER_DATA, VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER, "", "", + shader_sm4_read_shader_data}, + {VKD3D_SM4_OP_MOV, VKD3DSIH_MOV, "f", "f"}, + {VKD3D_SM4_OP_MOVC, VKD3DSIH_MOVC, "f", "uff"}, + {VKD3D_SM4_OP_MUL, VKD3DSIH_MUL, "f", "ff"}, + {VKD3D_SM4_OP_NE, VKD3DSIH_NE, "u", "ff"}, + {VKD3D_SM4_OP_NOP, VKD3DSIH_NOP, "", ""}, + {VKD3D_SM4_OP_NOT, VKD3DSIH_NOT, "u", "u"}, + {VKD3D_SM4_OP_OR, VKD3DSIH_OR, "u", "uu"}, + {VKD3D_SM4_OP_RESINFO, VKD3DSIH_RESINFO, "f", "iR"}, + {VKD3D_SM4_OP_RET, VKD3DSIH_RET, "", ""}, + {VKD3D_SM4_OP_RETC, VKD3DSIH_RETP, "", "u", + shader_sm4_read_conditional_op}, + {VKD3D_SM4_OP_ROUND_NE, VKD3DSIH_ROUND_NE, "f", "f"}, + {VKD3D_SM4_OP_ROUND_NI, VKD3DSIH_ROUND_NI, "f", "f"}, + {VKD3D_SM4_OP_ROUND_PI, VKD3DSIH_ROUND_PI, "f", "f"}, + {VKD3D_SM4_OP_ROUND_Z, VKD3DSIH_ROUND_Z, "f", "f"}, + {VKD3D_SM4_OP_RSQ, VKD3DSIH_RSQ, "f", "f"}, + {VKD3D_SM4_OP_SAMPLE, VKD3DSIH_SAMPLE, "u", "fRS"}, + {VKD3D_SM4_OP_SAMPLE_C, VKD3DSIH_SAMPLE_C, "f", "fRSf"}, + {VKD3D_SM4_OP_SAMPLE_C_LZ, VKD3DSIH_SAMPLE_C_LZ, "f", "fRSf"}, + {VKD3D_SM4_OP_SAMPLE_LOD, VKD3DSIH_SAMPLE_LOD, "u", "fRSf"}, + {VKD3D_SM4_OP_SAMPLE_GRAD, VKD3DSIH_SAMPLE_GRAD, "u", "fRSff"}, + {VKD3D_SM4_OP_SAMPLE_B, VKD3DSIH_SAMPLE_B, "u", "fRSf"}, + {VKD3D_SM4_OP_SQRT, VKD3DSIH_SQRT, "f", "f"}, + {VKD3D_SM4_OP_SWITCH, VKD3DSIH_SWITCH, "", "i"}, + {VKD3D_SM4_OP_SINCOS, VKD3DSIH_SINCOS, "ff", "f"}, + {VKD3D_SM4_OP_UDIV, VKD3DSIH_UDIV, "uu", "uu"}, + {VKD3D_SM4_OP_ULT, VKD3DSIH_ULT, "u", "uu"}, + {VKD3D_SM4_OP_UGE, VKD3DSIH_UGE, "u", "uu"}, + {VKD3D_SM4_OP_UMUL, VKD3DSIH_UMUL, "uu", "uu"}, + {VKD3D_SM4_OP_UMAX, VKD3DSIH_UMAX, "u", "uu"}, + {VKD3D_SM4_OP_UMIN, VKD3DSIH_UMIN, "u", "uu"}, + {VKD3D_SM4_OP_USHR, VKD3DSIH_USHR, "u", "uu"}, + {VKD3D_SM4_OP_UTOF, VKD3DSIH_UTOF, "f", "u"}, + {VKD3D_SM4_OP_XOR, VKD3DSIH_XOR, "u", "uu"}, + {VKD3D_SM4_OP_DCL_RESOURCE, VKD3DSIH_DCL, "", "", + shader_sm4_read_dcl_resource}, + {VKD3D_SM4_OP_DCL_CONSTANT_BUFFER, VKD3DSIH_DCL_CONSTANT_BUFFER, "", "", + shader_sm4_read_dcl_constant_buffer}, + {VKD3D_SM4_OP_DCL_SAMPLER, VKD3DSIH_DCL_SAMPLER, "", "", + shader_sm4_read_dcl_sampler}, + {VKD3D_SM4_OP_DCL_INDEX_RANGE, VKD3DSIH_DCL_INDEX_RANGE, "", "", + shader_sm4_read_dcl_index_range}, + {VKD3D_SM4_OP_DCL_OUTPUT_TOPOLOGY, VKD3DSIH_DCL_OUTPUT_TOPOLOGY, "", "", + shader_sm4_read_dcl_output_topology}, + {VKD3D_SM4_OP_DCL_INPUT_PRIMITIVE, VKD3DSIH_DCL_INPUT_PRIMITIVE, "", "", + shader_sm4_read_dcl_input_primitive}, + {VKD3D_SM4_OP_DCL_VERTICES_OUT, VKD3DSIH_DCL_VERTICES_OUT, "", "", + shader_sm4_read_declaration_count}, + {VKD3D_SM4_OP_DCL_INPUT, VKD3DSIH_DCL_INPUT, "", "", + shader_sm4_read_declaration_dst}, + {VKD3D_SM4_OP_DCL_INPUT_SGV, VKD3DSIH_DCL_INPUT_SGV, "", "", + shader_sm4_read_declaration_register_semantic}, + {VKD3D_SM4_OP_DCL_INPUT_SIV, VKD3DSIH_DCL_INPUT_SIV, "", "", + shader_sm4_read_declaration_register_semantic}, + {VKD3D_SM4_OP_DCL_INPUT_PS, VKD3DSIH_DCL_INPUT_PS, "", "", + shader_sm4_read_dcl_input_ps}, + {VKD3D_SM4_OP_DCL_INPUT_PS_SGV, VKD3DSIH_DCL_INPUT_PS_SGV, "", "", + shader_sm4_read_declaration_register_semantic}, + {VKD3D_SM4_OP_DCL_INPUT_PS_SIV, VKD3DSIH_DCL_INPUT_PS_SIV, "", "", + shader_sm4_read_dcl_input_ps_siv}, + {VKD3D_SM4_OP_DCL_OUTPUT, VKD3DSIH_DCL_OUTPUT, "", "", + shader_sm4_read_declaration_dst}, + {VKD3D_SM4_OP_DCL_OUTPUT_SIV, VKD3DSIH_DCL_OUTPUT_SIV, "", "", + shader_sm4_read_declaration_register_semantic}, + {VKD3D_SM4_OP_DCL_TEMPS, VKD3DSIH_DCL_TEMPS, "", "", + shader_sm4_read_declaration_count}, + {VKD3D_SM4_OP_DCL_INDEXABLE_TEMP, VKD3DSIH_DCL_INDEXABLE_TEMP, "", "", + shader_sm4_read_dcl_indexable_temp}, + {VKD3D_SM4_OP_DCL_GLOBAL_FLAGS, VKD3DSIH_DCL_GLOBAL_FLAGS, "", "", + shader_sm4_read_dcl_global_flags}, + {VKD3D_SM4_OP_LOD, VKD3DSIH_LOD, "f", "fRS"}, + {VKD3D_SM4_OP_GATHER4, VKD3DSIH_GATHER4, "u", "fRS"}, + {VKD3D_SM4_OP_SAMPLE_POS, VKD3DSIH_SAMPLE_POS, "f", "Ru"}, + {VKD3D_SM4_OP_SAMPLE_INFO, VKD3DSIH_SAMPLE_INFO, "f", "R"}, + {VKD3D_SM5_OP_HS_DECLS, VKD3DSIH_HS_DECLS, "", ""}, + {VKD3D_SM5_OP_HS_CONTROL_POINT_PHASE, VKD3DSIH_HS_CONTROL_POINT_PHASE, "", ""}, + {VKD3D_SM5_OP_HS_FORK_PHASE, VKD3DSIH_HS_FORK_PHASE, "", ""}, + {VKD3D_SM5_OP_HS_JOIN_PHASE, VKD3DSIH_HS_JOIN_PHASE, "", ""}, + {VKD3D_SM5_OP_EMIT_STREAM, VKD3DSIH_EMIT_STREAM, "", "f"}, + {VKD3D_SM5_OP_CUT_STREAM, VKD3DSIH_CUT_STREAM, "", "f"}, + {VKD3D_SM5_OP_FCALL, VKD3DSIH_FCALL, "", "O", + shader_sm5_read_fcall}, + {VKD3D_SM5_OP_BUFINFO, VKD3DSIH_BUFINFO, "i", "U"}, + {VKD3D_SM5_OP_DERIV_RTX_COARSE, VKD3DSIH_DSX_COARSE, "f", "f"}, + {VKD3D_SM5_OP_DERIV_RTX_FINE, VKD3DSIH_DSX_FINE, "f", "f"}, + {VKD3D_SM5_OP_DERIV_RTY_COARSE, VKD3DSIH_DSY_COARSE, "f", "f"}, + {VKD3D_SM5_OP_DERIV_RTY_FINE, VKD3DSIH_DSY_FINE, "f", "f"}, + {VKD3D_SM5_OP_GATHER4_C, VKD3DSIH_GATHER4_C, "f", "fRSf"}, + {VKD3D_SM5_OP_GATHER4_PO, VKD3DSIH_GATHER4_PO, "f", "fiRS"}, + {VKD3D_SM5_OP_GATHER4_PO_C, VKD3DSIH_GATHER4_PO_C, "f", "fiRSf"}, + {VKD3D_SM5_OP_RCP, VKD3DSIH_RCP, "f", "f"}, + {VKD3D_SM5_OP_F32TOF16, VKD3DSIH_F32TOF16, "u", "f"}, + {VKD3D_SM5_OP_F16TOF32, VKD3DSIH_F16TOF32, "f", "u"}, + {VKD3D_SM5_OP_COUNTBITS, VKD3DSIH_COUNTBITS, "u", "u"}, + {VKD3D_SM5_OP_FIRSTBIT_HI, VKD3DSIH_FIRSTBIT_HI, "u", "u"}, + {VKD3D_SM5_OP_FIRSTBIT_LO, VKD3DSIH_FIRSTBIT_LO, "u", "u"}, + {VKD3D_SM5_OP_FIRSTBIT_SHI, VKD3DSIH_FIRSTBIT_SHI, "u", "i"}, + {VKD3D_SM5_OP_UBFE, VKD3DSIH_UBFE, "u", "iiu"}, + {VKD3D_SM5_OP_IBFE, VKD3DSIH_IBFE, "i", "iii"}, + {VKD3D_SM5_OP_BFI, VKD3DSIH_BFI, "u", "iiuu"}, + {VKD3D_SM5_OP_BFREV, VKD3DSIH_BFREV, "u", "u"}, + {VKD3D_SM5_OP_SWAPC, VKD3DSIH_SWAPC, "ff", "uff"}, + {VKD3D_SM5_OP_DCL_STREAM, VKD3DSIH_DCL_STREAM, "", "O"}, + {VKD3D_SM5_OP_DCL_FUNCTION_BODY, VKD3DSIH_DCL_FUNCTION_BODY, "", "", + shader_sm5_read_dcl_function_body}, + {VKD3D_SM5_OP_DCL_FUNCTION_TABLE, VKD3DSIH_DCL_FUNCTION_TABLE, "", "", + shader_sm5_read_dcl_function_table}, + {VKD3D_SM5_OP_DCL_INTERFACE, VKD3DSIH_DCL_INTERFACE, "", "", + shader_sm5_read_dcl_interface}, + {VKD3D_SM5_OP_DCL_INPUT_CONTROL_POINT_COUNT, VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT, "", "", + shader_sm5_read_control_point_count}, + {VKD3D_SM5_OP_DCL_OUTPUT_CONTROL_POINT_COUNT, VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT, "", "", + shader_sm5_read_control_point_count}, + {VKD3D_SM5_OP_DCL_TESSELLATOR_DOMAIN, VKD3DSIH_DCL_TESSELLATOR_DOMAIN, "", "", + shader_sm5_read_dcl_tessellator_domain}, + {VKD3D_SM5_OP_DCL_TESSELLATOR_PARTITIONING, VKD3DSIH_DCL_TESSELLATOR_PARTITIONING, "", "", + shader_sm5_read_dcl_tessellator_partitioning}, + {VKD3D_SM5_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, "", "", + shader_sm5_read_dcl_tessellator_output_primitive}, + {VKD3D_SM5_OP_DCL_HS_MAX_TESSFACTOR, VKD3DSIH_DCL_HS_MAX_TESSFACTOR, "", "", + shader_sm5_read_dcl_hs_max_tessfactor}, + {VKD3D_SM5_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT, VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT, "", "", + shader_sm4_read_declaration_count}, + {VKD3D_SM5_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, "", "", + shader_sm4_read_declaration_count}, + {VKD3D_SM5_OP_DCL_THREAD_GROUP, VKD3DSIH_DCL_THREAD_GROUP, "", "", + shader_sm5_read_dcl_thread_group}, + {VKD3D_SM5_OP_DCL_UAV_TYPED, VKD3DSIH_DCL_UAV_TYPED, "", "", + shader_sm4_read_dcl_resource}, + {VKD3D_SM5_OP_DCL_UAV_RAW, VKD3DSIH_DCL_UAV_RAW, "", "", + shader_sm5_read_dcl_uav_raw}, + {VKD3D_SM5_OP_DCL_UAV_STRUCTURED, VKD3DSIH_DCL_UAV_STRUCTURED, "", "", + shader_sm5_read_dcl_uav_structured}, + {VKD3D_SM5_OP_DCL_TGSM_RAW, VKD3DSIH_DCL_TGSM_RAW, "", "", + shader_sm5_read_dcl_tgsm_raw}, + {VKD3D_SM5_OP_DCL_TGSM_STRUCTURED, VKD3DSIH_DCL_TGSM_STRUCTURED, "", "", + shader_sm5_read_dcl_tgsm_structured}, + {VKD3D_SM5_OP_DCL_RESOURCE_RAW, VKD3DSIH_DCL_RESOURCE_RAW, "", "", + shader_sm5_read_dcl_resource_raw}, + {VKD3D_SM5_OP_DCL_RESOURCE_STRUCTURED, VKD3DSIH_DCL_RESOURCE_STRUCTURED, "", "", + shader_sm5_read_dcl_resource_structured}, + {VKD3D_SM5_OP_LD_UAV_TYPED, VKD3DSIH_LD_UAV_TYPED, "u", "iU"}, + {VKD3D_SM5_OP_STORE_UAV_TYPED, VKD3DSIH_STORE_UAV_TYPED, "U", "iu"}, + {VKD3D_SM5_OP_LD_RAW, VKD3DSIH_LD_RAW, "u", "iU"}, + {VKD3D_SM5_OP_STORE_RAW, VKD3DSIH_STORE_RAW, "U", "uu"}, + {VKD3D_SM5_OP_LD_STRUCTURED, VKD3DSIH_LD_STRUCTURED, "u", "iiR"}, + {VKD3D_SM5_OP_STORE_STRUCTURED, VKD3DSIH_STORE_STRUCTURED, "U", "iiu"}, + {VKD3D_SM5_OP_ATOMIC_AND, VKD3DSIH_ATOMIC_AND, "U", "iu"}, + {VKD3D_SM5_OP_ATOMIC_OR, VKD3DSIH_ATOMIC_OR, "U", "iu"}, + {VKD3D_SM5_OP_ATOMIC_XOR, VKD3DSIH_ATOMIC_XOR, "U", "iu"}, + {VKD3D_SM5_OP_ATOMIC_CMP_STORE, VKD3DSIH_ATOMIC_CMP_STORE, "U", "iuu"}, + {VKD3D_SM5_OP_ATOMIC_IADD, VKD3DSIH_ATOMIC_IADD, "U", "ii"}, + {VKD3D_SM5_OP_ATOMIC_IMAX, VKD3DSIH_ATOMIC_IMAX, "U", "ii"}, + {VKD3D_SM5_OP_ATOMIC_IMIN, VKD3DSIH_ATOMIC_IMIN, "U", "ii"}, + {VKD3D_SM5_OP_ATOMIC_UMAX, VKD3DSIH_ATOMIC_UMAX, "U", "iu"}, + {VKD3D_SM5_OP_ATOMIC_UMIN, VKD3DSIH_ATOMIC_UMIN, "U", "iu"}, + {VKD3D_SM5_OP_IMM_ATOMIC_ALLOC, VKD3DSIH_IMM_ATOMIC_ALLOC, "u", "U"}, + {VKD3D_SM5_OP_IMM_ATOMIC_CONSUME, VKD3DSIH_IMM_ATOMIC_CONSUME, "u", "U"}, + {VKD3D_SM5_OP_IMM_ATOMIC_IADD, VKD3DSIH_IMM_ATOMIC_IADD, "uU", "ii"}, + {VKD3D_SM5_OP_IMM_ATOMIC_AND, VKD3DSIH_IMM_ATOMIC_AND, "uU", "iu"}, + {VKD3D_SM5_OP_IMM_ATOMIC_OR, VKD3DSIH_IMM_ATOMIC_OR, "uU", "iu"}, + {VKD3D_SM5_OP_IMM_ATOMIC_XOR, VKD3DSIH_IMM_ATOMIC_XOR, "uU", "iu"}, + {VKD3D_SM5_OP_IMM_ATOMIC_EXCH, VKD3DSIH_IMM_ATOMIC_EXCH, "uU", "iu"}, + {VKD3D_SM5_OP_IMM_ATOMIC_CMP_EXCH, VKD3DSIH_IMM_ATOMIC_CMP_EXCH, "uU", "iuu"}, + {VKD3D_SM5_OP_IMM_ATOMIC_IMAX, VKD3DSIH_IMM_ATOMIC_IMAX, "iU", "ii"}, + {VKD3D_SM5_OP_IMM_ATOMIC_IMIN, VKD3DSIH_IMM_ATOMIC_IMIN, "iU", "ii"}, + {VKD3D_SM5_OP_IMM_ATOMIC_UMAX, VKD3DSIH_IMM_ATOMIC_UMAX, "uU", "iu"}, + {VKD3D_SM5_OP_IMM_ATOMIC_UMIN, VKD3DSIH_IMM_ATOMIC_UMIN, "uU", "iu"}, + {VKD3D_SM5_OP_SYNC, VKD3DSIH_SYNC, "", "", + shader_sm5_read_sync}, + {VKD3D_SM5_OP_DADD, VKD3DSIH_DADD, "d", "dd"}, + {VKD3D_SM5_OP_DMAX, VKD3DSIH_DMAX, "d", "dd"}, + {VKD3D_SM5_OP_DMIN, VKD3DSIH_DMIN, "d", "dd"}, + {VKD3D_SM5_OP_DMUL, VKD3DSIH_DMUL, "d", "dd"}, + {VKD3D_SM5_OP_DEQ, VKD3DSIH_DEQ, "u", "dd"}, + {VKD3D_SM5_OP_DGE, VKD3DSIH_DGE, "u", "dd"}, + {VKD3D_SM5_OP_DLT, VKD3DSIH_DLT, "u", "dd"}, + {VKD3D_SM5_OP_DNE, VKD3DSIH_DNE, "u", "dd"}, + {VKD3D_SM5_OP_DMOV, VKD3DSIH_DMOV, "d", "d"}, + {VKD3D_SM5_OP_DMOVC, VKD3DSIH_DMOVC, "d", "udd"}, + {VKD3D_SM5_OP_DTOF, VKD3DSIH_DTOF, "f", "d"}, + {VKD3D_SM5_OP_FTOD, VKD3DSIH_FTOD, "d", "f"}, + {VKD3D_SM5_OP_EVAL_SAMPLE_INDEX, VKD3DSIH_EVAL_SAMPLE_INDEX, "f", "fi"}, + {VKD3D_SM5_OP_EVAL_CENTROID, VKD3DSIH_EVAL_CENTROID, "f", "f"}, + {VKD3D_SM5_OP_DCL_GS_INSTANCES, VKD3DSIH_DCL_GS_INSTANCES, "", "", + shader_sm4_read_declaration_count}, + {VKD3D_SM5_OP_DDIV, VKD3DSIH_DDIV, "d", "dd"}, + {VKD3D_SM5_OP_DFMA, VKD3DSIH_DFMA, "d", "ddd"}, + {VKD3D_SM5_OP_DRCP, VKD3DSIH_DRCP, "d", "d"}, + {VKD3D_SM5_OP_MSAD, VKD3DSIH_MSAD, "u", "uuu"}, + {VKD3D_SM5_OP_DTOI, VKD3DSIH_DTOI, "i", "d"}, + {VKD3D_SM5_OP_DTOU, VKD3DSIH_DTOU, "u", "d"}, + {VKD3D_SM5_OP_ITOD, VKD3DSIH_ITOD, "d", "i"}, + {VKD3D_SM5_OP_UTOD, VKD3DSIH_UTOD, "d", "u"}, + {VKD3D_SM5_OP_GATHER4_S, VKD3DSIH_GATHER4_S, "uu", "fRS"}, + {VKD3D_SM5_OP_GATHER4_C_S, VKD3DSIH_GATHER4_C_S, "fu", "fRSf"}, + {VKD3D_SM5_OP_GATHER4_PO_S, VKD3DSIH_GATHER4_PO_S, "fu", "fiRS"}, + {VKD3D_SM5_OP_GATHER4_PO_C_S, VKD3DSIH_GATHER4_PO_C_S, "fu", "fiRSf"}, + {VKD3D_SM5_OP_LD_S, VKD3DSIH_LD_S, "uu", "iR"}, + {VKD3D_SM5_OP_LD2DMS_S, VKD3DSIH_LD2DMS_S, "uu", "iRi"}, + {VKD3D_SM5_OP_LD_UAV_TYPED_S, VKD3DSIH_LD_UAV_TYPED_S, "uu", "iU"}, + {VKD3D_SM5_OP_LD_RAW_S, VKD3DSIH_LD_RAW_S, "uu", "iU"}, + {VKD3D_SM5_OP_LD_STRUCTURED_S, VKD3DSIH_LD_STRUCTURED_S, "uu", "iiR"}, + {VKD3D_SM5_OP_SAMPLE_LOD_S, VKD3DSIH_SAMPLE_LOD_S, "uu", "fRSf"}, + {VKD3D_SM5_OP_SAMPLE_C_LZ_S, VKD3DSIH_SAMPLE_C_LZ_S, "fu", "fRSf"}, + {VKD3D_SM5_OP_SAMPLE_CL_S, VKD3DSIH_SAMPLE_CL_S, "uu", "fRSf"}, + {VKD3D_SM5_OP_SAMPLE_B_CL_S, VKD3DSIH_SAMPLE_B_CL_S, "uu", "fRSff"}, + {VKD3D_SM5_OP_SAMPLE_GRAD_CL_S, VKD3DSIH_SAMPLE_GRAD_CL_S, "uu", "fRSfff"}, + {VKD3D_SM5_OP_SAMPLE_C_CL_S, VKD3DSIH_SAMPLE_C_CL_S, "fu", "fRSff"}, + {VKD3D_SM5_OP_CHECK_ACCESS_FULLY_MAPPED, VKD3DSIH_CHECK_ACCESS_FULLY_MAPPED, "u", "u"}, + }; + static const struct vkd3d_sm4_register_type_info register_type_table[] = { - {VKD3D_SM4_RT_TEMP, VKD3DSPR_TEMP}, - {VKD3D_SM4_RT_INPUT, VKD3DSPR_INPUT}, - {VKD3D_SM4_RT_OUTPUT, VKD3DSPR_OUTPUT}, - {VKD3D_SM4_RT_INDEXABLE_TEMP, VKD3DSPR_IDXTEMP}, - {VKD3D_SM4_RT_IMMCONST, VKD3DSPR_IMMCONST}, - {VKD3D_SM4_RT_IMMCONST64, VKD3DSPR_IMMCONST64}, - {VKD3D_SM4_RT_SAMPLER, VKD3DSPR_SAMPLER}, - {VKD3D_SM4_RT_RESOURCE, VKD3DSPR_RESOURCE}, - {VKD3D_SM4_RT_CONSTBUFFER, VKD3DSPR_CONSTBUFFER}, - {VKD3D_SM4_RT_IMMCONSTBUFFER, VKD3DSPR_IMMCONSTBUFFER}, - {VKD3D_SM4_RT_PRIMID, VKD3DSPR_PRIMID}, - {VKD3D_SM4_RT_DEPTHOUT, VKD3DSPR_DEPTHOUT}, - {VKD3D_SM4_RT_NULL, VKD3DSPR_NULL}, - {VKD3D_SM4_RT_RASTERIZER, VKD3DSPR_RASTERIZER}, - {VKD3D_SM4_RT_OMASK, VKD3DSPR_SAMPLEMASK}, - {VKD3D_SM5_RT_STREAM, VKD3DSPR_STREAM}, - {VKD3D_SM5_RT_FUNCTION_BODY, VKD3DSPR_FUNCTIONBODY}, - {VKD3D_SM5_RT_FUNCTION_POINTER, VKD3DSPR_FUNCTIONPOINTER}, - {VKD3D_SM5_RT_OUTPUT_CONTROL_POINT_ID, VKD3DSPR_OUTPOINTID}, - {VKD3D_SM5_RT_FORK_INSTANCE_ID, VKD3DSPR_FORKINSTID}, - {VKD3D_SM5_RT_JOIN_INSTANCE_ID, VKD3DSPR_JOININSTID}, - {VKD3D_SM5_RT_INPUT_CONTROL_POINT, VKD3DSPR_INCONTROLPOINT}, - {VKD3D_SM5_RT_OUTPUT_CONTROL_POINT, VKD3DSPR_OUTCONTROLPOINT}, - {VKD3D_SM5_RT_PATCH_CONSTANT_DATA, VKD3DSPR_PATCHCONST}, - {VKD3D_SM5_RT_DOMAIN_LOCATION, VKD3DSPR_TESSCOORD}, - {VKD3D_SM5_RT_UAV, VKD3DSPR_UAV}, - {VKD3D_SM5_RT_SHARED_MEMORY, VKD3DSPR_GROUPSHAREDMEM}, - {VKD3D_SM5_RT_THREAD_ID, VKD3DSPR_THREADID}, - {VKD3D_SM5_RT_THREAD_GROUP_ID, VKD3DSPR_THREADGROUPID}, - {VKD3D_SM5_RT_LOCAL_THREAD_ID, VKD3DSPR_LOCALTHREADID}, - {VKD3D_SM5_RT_COVERAGE, VKD3DSPR_COVERAGE}, - {VKD3D_SM5_RT_LOCAL_THREAD_INDEX, VKD3DSPR_LOCALTHREADINDEX}, - {VKD3D_SM5_RT_GS_INSTANCE_ID, VKD3DSPR_GSINSTID}, - {VKD3D_SM5_RT_DEPTHOUT_GREATER_EQUAL, VKD3DSPR_DEPTHOUTGE}, - {VKD3D_SM5_RT_DEPTHOUT_LESS_EQUAL, VKD3DSPR_DEPTHOUTLE}, - {VKD3D_SM5_RT_OUTPUT_STENCIL_REF, VKD3DSPR_OUTSTENCILREF}, + {VKD3D_SM4_RT_TEMP, VKD3DSPR_TEMP, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM4_RT_INPUT, VKD3DSPR_INPUT, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM4_RT_OUTPUT, VKD3DSPR_OUTPUT, VKD3D_SM4_SWIZZLE_INVALID}, + {VKD3D_SM4_RT_INDEXABLE_TEMP, VKD3DSPR_IDXTEMP, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM4_RT_IMMCONST, VKD3DSPR_IMMCONST, VKD3D_SM4_SWIZZLE_NONE}, + {VKD3D_SM4_RT_IMMCONST64, VKD3DSPR_IMMCONST64, VKD3D_SM4_SWIZZLE_NONE}, + {VKD3D_SM4_RT_SAMPLER, VKD3DSPR_SAMPLER, VKD3D_SM4_SWIZZLE_SCALAR}, + {VKD3D_SM4_RT_RESOURCE, VKD3DSPR_RESOURCE, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM4_RT_CONSTBUFFER, VKD3DSPR_CONSTBUFFER, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM4_RT_IMMCONSTBUFFER, VKD3DSPR_IMMCONSTBUFFER, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM4_RT_PRIMID, VKD3DSPR_PRIMID, VKD3D_SM4_SWIZZLE_NONE}, + {VKD3D_SM4_RT_DEPTHOUT, VKD3DSPR_DEPTHOUT, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM4_RT_NULL, VKD3DSPR_NULL, VKD3D_SM4_SWIZZLE_INVALID}, + {VKD3D_SM4_RT_RASTERIZER, VKD3DSPR_RASTERIZER, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM4_RT_OMASK, VKD3DSPR_SAMPLEMASK, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM5_RT_STREAM, VKD3DSPR_STREAM, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM5_RT_FUNCTION_BODY, VKD3DSPR_FUNCTIONBODY, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM5_RT_FUNCTION_POINTER, VKD3DSPR_FUNCTIONPOINTER, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM5_RT_OUTPUT_CONTROL_POINT_ID, VKD3DSPR_OUTPOINTID, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM5_RT_FORK_INSTANCE_ID, VKD3DSPR_FORKINSTID, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM5_RT_JOIN_INSTANCE_ID, VKD3DSPR_JOININSTID, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM5_RT_INPUT_CONTROL_POINT, VKD3DSPR_INCONTROLPOINT, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM5_RT_OUTPUT_CONTROL_POINT, VKD3DSPR_OUTCONTROLPOINT, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM5_RT_PATCH_CONSTANT_DATA, VKD3DSPR_PATCHCONST, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM5_RT_DOMAIN_LOCATION, VKD3DSPR_TESSCOORD, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM5_RT_UAV, VKD3DSPR_UAV, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM5_RT_SHARED_MEMORY, VKD3DSPR_GROUPSHAREDMEM, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM5_RT_THREAD_ID, VKD3DSPR_THREADID, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM5_RT_THREAD_GROUP_ID, VKD3DSPR_THREADGROUPID, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM5_RT_LOCAL_THREAD_ID, VKD3DSPR_LOCALTHREADID, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM5_RT_COVERAGE, VKD3DSPR_COVERAGE, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM5_RT_LOCAL_THREAD_INDEX, VKD3DSPR_LOCALTHREADINDEX,VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM5_RT_GS_INSTANCE_ID, VKD3DSPR_GSINSTID, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM5_RT_DEPTHOUT_GREATER_EQUAL, VKD3DSPR_DEPTHOUTGE, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM5_RT_DEPTHOUT_LESS_EQUAL, VKD3DSPR_DEPTHOUTLE, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM5_RT_OUTPUT_STENCIL_REF, VKD3DSPR_OUTSTENCILREF, VKD3D_SM4_SWIZZLE_VEC4}, }; memset(lookup, 0, sizeof(*lookup)); + for (i = 0; i < ARRAY_SIZE(opcode_table); ++i) + { + const struct vkd3d_sm4_opcode_info *info = &opcode_table[i]; + + lookup->opcode_info_from_sm4[info->opcode] = info; + } + for (i = 0; i < ARRAY_SIZE(register_type_table); ++i) { - info = ®ister_type_table[i]; + const struct vkd3d_sm4_register_type_info *info = ®ister_type_table[i]; + lookup->register_type_info_from_sm4[info->sm4_type] = info; lookup->register_type_info_from_vkd3d[info->vkd3d_type] = info; } @@ -1590,6 +1620,14 @@ static void tpf_writer_init(struct tpf_writer *tpf, struct hlsl_ctx *ctx, struct init_sm4_lookup_tables(&tpf->lookup); } +static const struct vkd3d_sm4_opcode_info *get_info_from_sm4_opcode( + const struct vkd3d_sm4_lookup_tables *lookup, enum vkd3d_sm4_opcode sm4_opcode) +{ + if (sm4_opcode >= VKD3D_SM4_OP_COUNT) + return NULL; + return lookup->opcode_info_from_sm4[sm4_opcode]; +} + static const struct vkd3d_sm4_register_type_info *get_info_from_sm4_register_type( const struct vkd3d_sm4_lookup_tables *lookup, enum vkd3d_sm4_register_type sm4_type) { @@ -1606,29 +1644,14 @@ static const struct vkd3d_sm4_register_type_info *get_info_from_vkd3d_register_t return lookup->register_type_info_from_vkd3d[vkd3d_type]; } -static void map_register(const struct vkd3d_shader_sm4_parser *sm4, struct vkd3d_shader_register *reg) +static enum vkd3d_sm4_swizzle_type vkd3d_sm4_get_default_swizzle_type( + const struct vkd3d_sm4_lookup_tables *lookup, enum vkd3d_shader_register_type vkd3d_type) { - switch (sm4->p.shader_version.type) - { - case VKD3D_SHADER_TYPE_PIXEL: - if (reg->type == VKD3DSPR_OUTPUT) - { - unsigned int reg_idx = reg->idx[0].offset; - - if (reg_idx >= ARRAY_SIZE(sm4->output_map)) - { - /* Validated later */ - break; - } + const struct vkd3d_sm4_register_type_info *register_type_info = + get_info_from_vkd3d_register_type(lookup, vkd3d_type); - reg->type = VKD3DSPR_COLOROUT; - reg->idx[0].offset = sm4->output_map[reg_idx]; - } - break; - - default: - break; - } + assert(register_type_info); + return register_type_info->default_src_swizzle_type; } static enum vkd3d_data_type map_data_type(char t) @@ -1713,10 +1736,12 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui enum vkd3d_data_type data_type, struct vkd3d_shader_register *param, enum vkd3d_shader_src_modifier *modifier) { const struct vkd3d_sm4_register_type_info *register_type_info; + enum vkd3d_shader_register_type vsir_register_type; enum vkd3d_sm4_register_precision precision; enum vkd3d_sm4_register_type register_type; enum vkd3d_sm4_extended_operand_type type; enum vkd3d_sm4_register_modifier m; + enum vkd3d_sm4_dimension sm4_dimension; uint32_t token, order, extended; if (*ptr >= end) @@ -1731,15 +1756,18 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui if (!register_type_info) { FIXME("Unhandled register type %#x.\n", register_type); - param->type = VKD3DSPR_TEMP; + vsir_register_type = VKD3DSPR_TEMP; } else { - param->type = register_type_info->vkd3d_type; + vsir_register_type = register_type_info->vkd3d_type; } + + order = (token & VKD3D_SM4_REGISTER_ORDER_MASK) >> VKD3D_SM4_REGISTER_ORDER_SHIFT; + + vsir_register_init(param, vsir_register_type, data_type, order); param->precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT; param->non_uniform = false; - param->data_type = data_type; *modifier = VKD3DSPSM_NONE; if (token & VKD3D_SM4_EXTENDED_OPERAND) @@ -1809,14 +1837,7 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui } } - order = (token & VKD3D_SM4_REGISTER_ORDER_MASK) >> VKD3D_SM4_REGISTER_ORDER_SHIFT; - - if (order < 1) - { - param->idx[0].offset = ~0u; - param->idx[0].rel_addr = NULL; - } - else + if (order >= 1) { DWORD addressing = (token & VKD3D_SM4_ADDRESSING_MASK0) >> VKD3D_SM4_ADDRESSING_SHIFT0; if (!(shader_sm4_read_reg_idx(priv, ptr, end, addressing, ¶m->idx[0]))) @@ -1826,12 +1847,7 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui } } - if (order < 2) - { - param->idx[1].offset = ~0u; - param->idx[1].rel_addr = NULL; - } - else + if (order >= 2) { DWORD addressing = (token & VKD3D_SM4_ADDRESSING_MASK1) >> VKD3D_SM4_ADDRESSING_SHIFT1; if (!(shader_sm4_read_reg_idx(priv, ptr, end, addressing, ¶m->idx[1]))) @@ -1841,12 +1857,7 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui } } - if (order < 3) - { - param->idx[2].offset = ~0u; - param->idx[2].rel_addr = NULL; - } - else + if (order >= 3) { DWORD addressing = (token & VKD3D_SM4_ADDRESSING_MASK2) >> VKD3D_SM4_ADDRESSING_SHIFT2; if (!(shader_sm4_read_reg_idx(priv, ptr, end, addressing, ¶m->idx[2]))) @@ -1862,17 +1873,16 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui return false; } - param->idx_count = order; + sm4_dimension = (token & VKD3D_SM4_DIMENSION_MASK) >> VKD3D_SM4_DIMENSION_SHIFT; + param->dimension = vsir_dimension_from_sm4_dimension(sm4_dimension); if (register_type == VKD3D_SM4_RT_IMMCONST || register_type == VKD3D_SM4_RT_IMMCONST64) { - enum vkd3d_sm4_dimension dimension = (token & VKD3D_SM4_DIMENSION_MASK) >> VKD3D_SM4_DIMENSION_SHIFT; unsigned int dword_count; - switch (dimension) + switch (param->dimension) { - case VKD3D_SM4_DIMENSION_SCALAR: - param->immconst_type = VKD3D_IMMCONST_SCALAR; + case VSIR_DIMENSION_SCALAR: dword_count = 1 + (register_type == VKD3D_SM4_RT_IMMCONST64); if (end - *ptr < dword_count) { @@ -1883,8 +1893,7 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui *ptr += dword_count; break; - case VKD3D_SM4_DIMENSION_VEC4: - param->immconst_type = VKD3D_IMMCONST_VEC4; + case VSIR_DIMENSION_VEC4: if (end - *ptr < VKD3D_VEC4_SIZE) { WARN("Invalid ptr %p, end %p.\n", *ptr, end); @@ -1895,7 +1904,7 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui break; default: - FIXME("Unhandled dimension %#x.\n", dimension); + FIXME("Unhandled dimension %#x.\n", param->dimension); break; } } @@ -1908,8 +1917,6 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui ++param->idx_count; } - map_register(priv, param); - return true; } @@ -1938,6 +1945,16 @@ static uint32_t swizzle_from_sm4(uint32_t s) return vkd3d_shader_create_swizzle(s & 0x3, (s >> 2) & 0x3, (s >> 4) & 0x3, (s >> 6) & 0x3); } +static uint32_t swizzle_to_sm4(uint32_t s) +{ + uint32_t ret = 0; + ret |= ((vkd3d_swizzle_get_component(s, 0)) & 0x3); + ret |= ((vkd3d_swizzle_get_component(s, 1)) & 0x3) << 2; + ret |= ((vkd3d_swizzle_get_component(s, 2)) & 0x3) << 4; + ret |= ((vkd3d_swizzle_get_component(s, 3)) & 0x3) << 6; + return ret; +} + static bool register_is_input_output(const struct vkd3d_shader_register *reg) { switch (reg->type) @@ -2319,7 +2336,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str } --len; - if (!(opcode_info = get_opcode_info(opcode))) + if (!(opcode_info = get_info_from_sm4_opcode(&sm4->lookup, opcode))) { FIXME("Unrecognized opcode %#x, opcode_token 0x%08x.\n", opcode, opcode_token); ins->handler_idx = VKD3DSIH_INVALID; @@ -2327,7 +2344,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str return; } - ins->handler_idx = opcode_info->handler_idx; + vsir_instruction_init(ins, &sm4->p.location, opcode_info->handler_idx); if (ins->handler_idx == VKD3DSIH_HS_CONTROL_POINT_PHASE || ins->handler_idx == VKD3DSIH_HS_FORK_PHASE || ins->handler_idx == VKD3DSIH_HS_JOIN_PHASE) sm4->phase = ins->handler_idx; @@ -2430,7 +2447,6 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, const uint32_t { struct vkd3d_shader_version version; uint32_t version_token, token_count; - unsigned int i; if (byte_code_size / sizeof(*byte_code) < 2) { @@ -2490,23 +2506,6 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, const uint32_t return false; sm4->ptr = sm4->start; - memset(sm4->output_map, 0xff, sizeof(sm4->output_map)); - for (i = 0; i < output_signature->element_count; ++i) - { - struct signature_element *e = &output_signature->elements[i]; - - if (version.type == VKD3D_SHADER_TYPE_PIXEL - && ascii_strcasecmp(e->semantic_name, "SV_Target")) - continue; - if (e->register_index >= ARRAY_SIZE(sm4->output_map)) - { - WARN("Invalid output index %u.\n", e->register_index); - continue; - } - - sm4->output_map[e->register_index] = e->semantic_index; - } - init_sm4_lookup_tables(&sm4->lookup); return true; @@ -2642,9 +2641,19 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi if (sm4->p.shader_version.type == VKD3D_SHADER_TYPE_HULL && !sm4->has_control_point_phase && !sm4->p.failed) shader_sm4_validate_default_phase_index_ranges(sm4); + if (!sm4->p.failed) + vsir_validate(&sm4->p); + + if (sm4->p.failed) + { + WARN("Failed to parse shader.\n"); + shader_sm4_destroy(&sm4->p); + return VKD3D_ERROR_INVALID_SHADER; + } + *parser = &sm4->p; - return sm4->p.failed ? VKD3D_ERROR_INVALID_SHADER : VKD3D_OK; + return VKD3D_OK; } static void write_sm4_block(const struct tpf_writer *tpf, const struct hlsl_block *block); @@ -2664,7 +2673,7 @@ static bool type_is_integer(const struct hlsl_type *type) } bool hlsl_sm4_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic, - bool output, enum vkd3d_shader_register_type *type, enum vkd3d_sm4_swizzle_type *swizzle_type, bool *has_idx) + bool output, enum vkd3d_shader_register_type *type, bool *has_idx) { unsigned int i; @@ -2673,25 +2682,24 @@ bool hlsl_sm4_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_sem const char *semantic; bool output; enum vkd3d_shader_type shader_type; - enum vkd3d_sm4_swizzle_type swizzle_type; enum vkd3d_shader_register_type type; bool has_idx; } register_table[] = { - {"sv_dispatchthreadid", false, VKD3D_SHADER_TYPE_COMPUTE, VKD3D_SM4_SWIZZLE_VEC4, VKD3DSPR_THREADID, false}, - {"sv_groupid", false, VKD3D_SHADER_TYPE_COMPUTE, VKD3D_SM4_SWIZZLE_VEC4, VKD3DSPR_THREADGROUPID, false}, - {"sv_groupthreadid", false, VKD3D_SHADER_TYPE_COMPUTE, VKD3D_SM4_SWIZZLE_VEC4, VKD3DSPR_LOCALTHREADID, false}, + {"sv_dispatchthreadid", false, VKD3D_SHADER_TYPE_COMPUTE, VKD3DSPR_THREADID, false}, + {"sv_groupid", false, VKD3D_SHADER_TYPE_COMPUTE, VKD3DSPR_THREADGROUPID, false}, + {"sv_groupthreadid", false, VKD3D_SHADER_TYPE_COMPUTE, VKD3DSPR_LOCALTHREADID, false}, - {"sv_primitiveid", false, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SM4_SWIZZLE_NONE, VKD3DSPR_PRIMID, false}, + {"sv_primitiveid", false, VKD3D_SHADER_TYPE_GEOMETRY, VKD3DSPR_PRIMID, false}, /* Put sv_target in this table, instead of letting it fall through to * default varying allocation, so that the register index matches the * usage index. */ - {"color", true, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SM4_SWIZZLE_VEC4, VKD3DSPR_OUTPUT, true}, - {"depth", true, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SM4_SWIZZLE_VEC4, VKD3DSPR_DEPTHOUT, false}, - {"sv_depth", true, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SM4_SWIZZLE_VEC4, VKD3DSPR_DEPTHOUT, false}, - {"sv_target", true, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SM4_SWIZZLE_VEC4, VKD3DSPR_OUTPUT, true}, + {"color", true, VKD3D_SHADER_TYPE_PIXEL, VKD3DSPR_OUTPUT, true}, + {"depth", true, VKD3D_SHADER_TYPE_PIXEL, VKD3DSPR_DEPTHOUT, false}, + {"sv_depth", true, VKD3D_SHADER_TYPE_PIXEL, VKD3DSPR_DEPTHOUT, false}, + {"sv_target", true, VKD3D_SHADER_TYPE_PIXEL, VKD3DSPR_OUTPUT, true}, }; for (i = 0; i < ARRAY_SIZE(register_table); ++i) @@ -2702,8 +2710,6 @@ bool hlsl_sm4_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_sem { if (type) *type = register_table[i].type; - if (swizzle_type) - *swizzle_type = register_table[i].swizzle_type; *has_idx = register_table[i].has_idx; return true; } @@ -2815,7 +2821,7 @@ static void write_sm4_signature(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc, continue; usage_idx = var->semantic.index; - if (hlsl_sm4_register_from_semantic(ctx, &var->semantic, output, NULL, NULL, &has_idx)) + if (hlsl_sm4_register_from_semantic(ctx, &var->semantic, output, NULL, &has_idx)) { reg_idx = has_idx ? var->semantic.index : ~0u; } @@ -3202,8 +3208,7 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un if (!hlsl_type_is_resource(component_type)) continue; - regset = hlsl_type_get_regset(component_type); - regset_offset = hlsl_type_get_component_offset(ctx, var->data_type, regset, k); + regset_offset = hlsl_type_get_component_offset(ctx, var->data_type, k, ®set); if (regset_offset > var->regs[regset].allocation_size) continue; @@ -3249,38 +3254,43 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un } else { + unsigned int r; + if (!hlsl_type_is_resource(var->data_type)) continue; - regset = hlsl_type_get_regset(var->data_type); - if (!var->regs[regset].allocated) - continue; - if (!(hlsl_array_reserve(ctx, (void **)&extern_resources, &capacity, *count + 1, - sizeof(*extern_resources)))) + for (r = 0; r <= HLSL_REGSET_LAST; ++r) { - sm4_free_extern_resources(extern_resources, *count); - *count = 0; - return NULL; - } + if (!var->regs[r].allocated) + continue; - if (!(name = hlsl_strdup(ctx, string_skip_tag(var->name)))) - { - sm4_free_extern_resources(extern_resources, *count); - *count = 0; - return NULL; - } + if (!(hlsl_array_reserve(ctx, (void **)&extern_resources, &capacity, *count + 1, + sizeof(*extern_resources)))) + { + sm4_free_extern_resources(extern_resources, *count); + *count = 0; + return NULL; + } + + if (!(name = hlsl_strdup(ctx, string_skip_tag(var->name)))) + { + sm4_free_extern_resources(extern_resources, *count); + *count = 0; + return NULL; + } - extern_resources[*count].var = var; + extern_resources[*count].var = var; - extern_resources[*count].name = name; - extern_resources[*count].data_type = var->data_type; - extern_resources[*count].is_user_packed = !!var->reg_reservation.reg_type; + extern_resources[*count].name = name; + extern_resources[*count].data_type = var->data_type; + extern_resources[*count].is_user_packed = !!var->reg_reservation.reg_type; - extern_resources[*count].regset = regset; - extern_resources[*count].id = var->regs[regset].id; - extern_resources[*count].bind_count = var->bind_count[regset]; + extern_resources[*count].regset = r; + extern_resources[*count].id = var->regs[r].id; + extern_resources[*count].bind_count = var->bind_count[r]; - ++*count; + ++*count; + } } } @@ -3577,36 +3587,18 @@ static uint32_t sm4_encode_instruction_modifier(const struct sm4_instruction_mod return word; } -struct sm4_register -{ - enum vkd3d_shader_register_type type; - struct vkd3d_shader_register_index idx[2]; - unsigned int idx_count; - enum vkd3d_sm4_dimension dim; - uint32_t immconst_uint[4]; - unsigned int mod; -}; - struct sm4_instruction { enum vkd3d_sm4_opcode opcode; + uint32_t extra_bits; struct sm4_instruction_modifier modifiers[1]; unsigned int modifier_count; - struct sm4_dst_register - { - struct sm4_register reg; - unsigned int writemask; - } dsts[2]; + struct vkd3d_shader_dst_param dsts[2]; unsigned int dst_count; - struct sm4_src_register - { - struct sm4_register reg; - enum vkd3d_sm4_swizzle_type swizzle_type; - unsigned int swizzle; - } srcs[5]; + struct vkd3d_shader_src_param srcs[5]; unsigned int src_count; unsigned int byte_stride; @@ -3615,23 +3607,20 @@ struct sm4_instruction unsigned int idx_count; }; -static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *reg, - unsigned int *writemask, enum vkd3d_sm4_swizzle_type *swizzle_type, - const struct hlsl_deref *deref) +static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct vkd3d_shader_register *reg, + uint32_t *writemask, const struct hlsl_deref *deref) { const struct hlsl_type *data_type = hlsl_deref_get_type(ctx, deref); const struct hlsl_ir_var *var = deref->var; if (var->is_uniform) { - enum hlsl_regset regset = hlsl_type_get_regset(data_type); + enum hlsl_regset regset = hlsl_deref_get_regset(ctx, deref); if (regset == HLSL_REGSET_TEXTURES) { reg->type = VKD3DSPR_RESOURCE; - reg->dim = VKD3D_SM4_DIMENSION_VEC4; - if (swizzle_type) - *swizzle_type = VKD3D_SM4_SWIZZLE_VEC4; + reg->dimension = VSIR_DIMENSION_VEC4; reg->idx[0].offset = var->regs[HLSL_REGSET_TEXTURES].id; reg->idx[0].offset += hlsl_offset_from_deref_safe(ctx, deref); assert(regset == HLSL_REGSET_TEXTURES); @@ -3641,9 +3630,7 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r else if (regset == HLSL_REGSET_UAVS) { reg->type = VKD3DSPR_UAV; - reg->dim = VKD3D_SM4_DIMENSION_VEC4; - if (swizzle_type) - *swizzle_type = VKD3D_SM4_SWIZZLE_VEC4; + reg->dimension = VSIR_DIMENSION_VEC4; reg->idx[0].offset = var->regs[HLSL_REGSET_UAVS].id; reg->idx[0].offset += hlsl_offset_from_deref_safe(ctx, deref); assert(regset == HLSL_REGSET_UAVS); @@ -3653,9 +3640,7 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r else if (regset == HLSL_REGSET_SAMPLERS) { reg->type = VKD3DSPR_SAMPLER; - reg->dim = VKD3D_SM4_DIMENSION_NONE; - if (swizzle_type) - *swizzle_type = VKD3D_SM4_SWIZZLE_NONE; + reg->dimension = VSIR_DIMENSION_NONE; reg->idx[0].offset = var->regs[HLSL_REGSET_SAMPLERS].id; reg->idx[0].offset += hlsl_offset_from_deref_safe(ctx, deref); assert(regset == HLSL_REGSET_SAMPLERS); @@ -3668,9 +3653,7 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r assert(data_type->class <= HLSL_CLASS_VECTOR); reg->type = VKD3DSPR_CONSTBUFFER; - reg->dim = VKD3D_SM4_DIMENSION_VEC4; - if (swizzle_type) - *swizzle_type = VKD3D_SM4_SWIZZLE_VEC4; + reg->dimension = VSIR_DIMENSION_VEC4; reg->idx[0].offset = var->buffer->reg.id; reg->idx[1].offset = offset / 4; reg->idx_count = 2; @@ -3681,7 +3664,7 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r { bool has_idx; - if (hlsl_sm4_register_from_semantic(ctx, &var->semantic, false, ®->type, swizzle_type, &has_idx)) + if (hlsl_sm4_register_from_semantic(ctx, &var->semantic, false, ®->type, &has_idx)) { unsigned int offset = hlsl_offset_from_deref_safe(ctx, deref); @@ -3691,7 +3674,7 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r reg->idx_count = 1; } - reg->dim = VKD3D_SM4_DIMENSION_VEC4; + reg->dimension = VSIR_DIMENSION_VEC4; *writemask = ((1u << data_type->dimx) - 1) << (offset % 4); } else @@ -3700,9 +3683,7 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r assert(hlsl_reg.allocated); reg->type = VKD3DSPR_INPUT; - reg->dim = VKD3D_SM4_DIMENSION_VEC4; - if (swizzle_type) - *swizzle_type = VKD3D_SM4_SWIZZLE_VEC4; + reg->dimension = VSIR_DIMENSION_VEC4; reg->idx[0].offset = hlsl_reg.id; reg->idx_count = 1; *writemask = hlsl_reg.writemask; @@ -3712,7 +3693,7 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r { bool has_idx; - if (hlsl_sm4_register_from_semantic(ctx, &var->semantic, true, ®->type, swizzle_type, &has_idx)) + if (hlsl_sm4_register_from_semantic(ctx, &var->semantic, true, ®->type, &has_idx)) { unsigned int offset = hlsl_offset_from_deref_safe(ctx, deref); @@ -3723,9 +3704,9 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r } if (reg->type == VKD3DSPR_DEPTHOUT) - reg->dim = VKD3D_SM4_DIMENSION_SCALAR; + reg->dimension = VSIR_DIMENSION_SCALAR; else - reg->dim = VKD3D_SM4_DIMENSION_VEC4; + reg->dimension = VSIR_DIMENSION_VEC4; *writemask = ((1u << data_type->dimx) - 1) << (offset % 4); } else @@ -3734,7 +3715,7 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r assert(hlsl_reg.allocated); reg->type = VKD3DSPR_OUTPUT; - reg->dim = VKD3D_SM4_DIMENSION_VEC4; + reg->dimension = VSIR_DIMENSION_VEC4; reg->idx[0].offset = hlsl_reg.id; reg->idx_count = 1; *writemask = hlsl_reg.writemask; @@ -3746,73 +3727,73 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r assert(hlsl_reg.allocated); reg->type = VKD3DSPR_TEMP; - reg->dim = VKD3D_SM4_DIMENSION_VEC4; - if (swizzle_type) - *swizzle_type = VKD3D_SM4_SWIZZLE_VEC4; + reg->dimension = VSIR_DIMENSION_VEC4; reg->idx[0].offset = hlsl_reg.id; reg->idx_count = 1; *writemask = hlsl_reg.writemask; } } -static void sm4_src_from_deref(struct hlsl_ctx *ctx, struct sm4_src_register *src, +static void sm4_src_from_deref(const struct tpf_writer *tpf, struct vkd3d_shader_src_param *src, const struct hlsl_deref *deref, unsigned int map_writemask) { - unsigned int writemask; + unsigned int hlsl_swizzle; + uint32_t writemask; - sm4_register_from_deref(ctx, &src->reg, &writemask, &src->swizzle_type, deref); - if (src->swizzle_type == VKD3D_SM4_SWIZZLE_VEC4) - src->swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), map_writemask); + sm4_register_from_deref(tpf->ctx, &src->reg, &writemask, deref); + if (vkd3d_sm4_get_default_swizzle_type(&tpf->lookup, src->reg.type) == VKD3D_SM4_SWIZZLE_VEC4) + { + hlsl_swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), map_writemask); + src->swizzle = swizzle_from_sm4(hlsl_swizzle); + } } -static void sm4_register_from_node(struct sm4_register *reg, unsigned int *writemask, - enum vkd3d_sm4_swizzle_type *swizzle_type, const struct hlsl_ir_node *instr) +static void sm4_register_from_node(struct vkd3d_shader_register *reg, uint32_t *writemask, + const struct hlsl_ir_node *instr) { assert(instr->reg.allocated); reg->type = VKD3DSPR_TEMP; - reg->dim = VKD3D_SM4_DIMENSION_VEC4; - *swizzle_type = VKD3D_SM4_SWIZZLE_VEC4; + reg->dimension = VSIR_DIMENSION_VEC4; reg->idx[0].offset = instr->reg.id; reg->idx_count = 1; *writemask = instr->reg.writemask; } -static void sm4_dst_from_node(struct sm4_dst_register *dst, const struct hlsl_ir_node *instr) +static void sm4_dst_from_node(struct vkd3d_shader_dst_param *dst, const struct hlsl_ir_node *instr) { - unsigned int swizzle_type; - - sm4_register_from_node(&dst->reg, &dst->writemask, &swizzle_type, instr); + sm4_register_from_node(&dst->reg, &dst->write_mask, instr); } -static void sm4_src_from_constant_value(struct sm4_src_register *src, +static void sm4_src_from_constant_value(struct vkd3d_shader_src_param *src, const struct hlsl_constant_value *value, unsigned int width, unsigned int map_writemask) { - src->swizzle_type = VKD3D_SM4_SWIZZLE_NONE; + src->swizzle = VKD3D_SHADER_NO_SWIZZLE; src->reg.type = VKD3DSPR_IMMCONST; if (width == 1) { - src->reg.dim = VKD3D_SM4_DIMENSION_SCALAR; - src->reg.immconst_uint[0] = value->u[0].u; + src->reg.dimension = VSIR_DIMENSION_SCALAR; + src->reg.u.immconst_uint[0] = value->u[0].u; } else { unsigned int i, j = 0; - src->reg.dim = VKD3D_SM4_DIMENSION_VEC4; + src->reg.dimension = VSIR_DIMENSION_VEC4; for (i = 0; i < 4; ++i) { if ((map_writemask & (1u << i)) && (j < width)) - src->reg.immconst_uint[i] = value->u[j++].u; + src->reg.u.immconst_uint[i] = value->u[j++].u; else - src->reg.immconst_uint[i] = 0; + src->reg.u.immconst_uint[i] = 0; } } } -static void sm4_src_from_node(struct sm4_src_register *src, - const struct hlsl_ir_node *instr, unsigned int map_writemask) +static void sm4_src_from_node(const struct tpf_writer *tpf, struct vkd3d_shader_src_param *src, + const struct hlsl_ir_node *instr, uint32_t map_writemask) { - unsigned int writemask; + unsigned int hlsl_swizzle; + uint32_t writemask; if (instr->type == HLSL_IR_CONSTANT) { @@ -3822,12 +3803,15 @@ static void sm4_src_from_node(struct sm4_src_register *src, return; } - sm4_register_from_node(&src->reg, &writemask, &src->swizzle_type, instr); - if (src->swizzle_type == VKD3D_SM4_SWIZZLE_VEC4) - src->swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), map_writemask); + sm4_register_from_node(&src->reg, &writemask, instr); + if (vkd3d_sm4_get_default_swizzle_type(&tpf->lookup, src->reg.type) == VKD3D_SM4_SWIZZLE_VEC4) + { + hlsl_swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), map_writemask); + src->swizzle = swizzle_from_sm4(hlsl_swizzle); + } } -static void sm4_write_dst_register(const struct tpf_writer *tpf, const struct sm4_dst_register *dst) +static void sm4_write_dst_register(const struct tpf_writer *tpf, const struct vkd3d_shader_dst_param *dst) { const struct vkd3d_sm4_register_type_info *register_type_info; struct vkd3d_bytecode_buffer *buffer = tpf->buffer; @@ -3846,13 +3830,13 @@ static void sm4_write_dst_register(const struct tpf_writer *tpf, const struct sm sm4_reg_type = register_type_info->sm4_type; } - reg_dim = dst->reg.dim; + reg_dim = sm4_dimension_from_vsir_dimension(dst->reg.dimension); token |= sm4_reg_type << VKD3D_SM4_REGISTER_TYPE_SHIFT; token |= dst->reg.idx_count << VKD3D_SM4_REGISTER_ORDER_SHIFT; token |= reg_dim << VKD3D_SM4_DIMENSION_SHIFT; if (reg_dim == VKD3D_SM4_DIMENSION_VEC4) - token |= dst->writemask << VKD3D_SM4_WRITEMASK_SHIFT; + token |= dst->write_mask << VKD3D_SM4_WRITEMASK_SHIFT; put_u32(buffer, token); for (j = 0; j < dst->reg.idx_count; ++j) @@ -3862,12 +3846,12 @@ static void sm4_write_dst_register(const struct tpf_writer *tpf, const struct sm } } -static void sm4_write_src_register(const struct tpf_writer *tpf, const struct sm4_src_register *src) +static void sm4_write_src_register(const struct tpf_writer *tpf, const struct vkd3d_shader_src_param *src) { const struct vkd3d_sm4_register_type_info *register_type_info; struct vkd3d_bytecode_buffer *buffer = tpf->buffer; uint32_t sm4_reg_type, reg_dim; - uint32_t token = 0; + uint32_t token = 0, mod_token = 0; unsigned int j; register_type_info = get_info_from_vkd3d_register_type(&tpf->lookup, src->reg.type); @@ -3881,23 +3865,59 @@ static void sm4_write_src_register(const struct tpf_writer *tpf, const struct sm sm4_reg_type = register_type_info->sm4_type; } - reg_dim = src->reg.dim; + reg_dim = sm4_dimension_from_vsir_dimension(src->reg.dimension); token |= sm4_reg_type << VKD3D_SM4_REGISTER_TYPE_SHIFT; token |= src->reg.idx_count << VKD3D_SM4_REGISTER_ORDER_SHIFT; token |= reg_dim << VKD3D_SM4_DIMENSION_SHIFT; if (reg_dim == VKD3D_SM4_DIMENSION_VEC4) { - token |= (uint32_t)src->swizzle_type << VKD3D_SM4_SWIZZLE_TYPE_SHIFT; - token |= src->swizzle << VKD3D_SM4_SWIZZLE_SHIFT; + uint32_t swizzle_type = (uint32_t)register_type_info->default_src_swizzle_type; + + token |= swizzle_type << VKD3D_SM4_SWIZZLE_TYPE_SHIFT; + if (swizzle_type == VKD3D_SM4_SWIZZLE_SCALAR) + token |= (swizzle_to_sm4(src->swizzle) & 0x3) << VKD3D_SM4_SWIZZLE_SHIFT; + else + token |= swizzle_to_sm4(src->swizzle) << VKD3D_SM4_SWIZZLE_SHIFT; } - if (src->reg.mod) - token |= VKD3D_SM4_EXTENDED_OPERAND; - put_u32(buffer, token); - if (src->reg.mod) - put_u32(buffer, (src->reg.mod << VKD3D_SM4_REGISTER_MODIFIER_SHIFT) - | VKD3D_SM4_EXTENDED_OPERAND_MODIFIER); + switch (src->modifiers) + { + case VKD3DSPSM_NONE: + mod_token = VKD3D_SM4_REGISTER_MODIFIER_NONE; + break; + + case VKD3DSPSM_ABS: + mod_token = (VKD3D_SM4_REGISTER_MODIFIER_ABS << VKD3D_SM4_REGISTER_MODIFIER_SHIFT) + | VKD3D_SM4_EXTENDED_OPERAND_MODIFIER; + break; + + case VKD3DSPSM_NEG: + mod_token = (VKD3D_SM4_REGISTER_MODIFIER_NEGATE << VKD3D_SM4_REGISTER_MODIFIER_SHIFT) + | VKD3D_SM4_EXTENDED_OPERAND_MODIFIER; + break; + + case VKD3DSPSM_ABSNEG: + mod_token = (VKD3D_SM4_REGISTER_MODIFIER_ABS_NEGATE << VKD3D_SM4_REGISTER_MODIFIER_SHIFT) + | VKD3D_SM4_EXTENDED_OPERAND_MODIFIER; + break; + + default: + ERR("Unhandled register modifier %#x.\n", src->modifiers); + vkd3d_unreachable(); + break; + } + + if (src->modifiers) + { + token |= VKD3D_SM4_EXTENDED_OPERAND; + put_u32(buffer, token); + put_u32(buffer, mod_token); + } + else + { + put_u32(buffer, token); + } for (j = 0; j < src->reg.idx_count; ++j) { @@ -3907,54 +3927,35 @@ static void sm4_write_src_register(const struct tpf_writer *tpf, const struct sm if (src->reg.type == VKD3DSPR_IMMCONST) { - put_u32(buffer, src->reg.immconst_uint[0]); + put_u32(buffer, src->reg.u.immconst_uint[0]); if (reg_dim == VKD3D_SM4_DIMENSION_VEC4) { - put_u32(buffer, src->reg.immconst_uint[1]); - put_u32(buffer, src->reg.immconst_uint[2]); - put_u32(buffer, src->reg.immconst_uint[3]); + put_u32(buffer, src->reg.u.immconst_uint[1]); + put_u32(buffer, src->reg.u.immconst_uint[2]); + put_u32(buffer, src->reg.u.immconst_uint[3]); } } } -static uint32_t sm4_register_order(const struct sm4_register *reg) -{ - uint32_t order = 1; - if (reg->type == VKD3DSPR_IMMCONST) - order += reg->dim == VKD3D_SM4_DIMENSION_VEC4 ? 4 : 1; - order += reg->idx_count; - if (reg->mod) - ++order; - return order; -} - static void write_sm4_instruction(const struct tpf_writer *tpf, const struct sm4_instruction *instr) { struct vkd3d_bytecode_buffer *buffer = tpf->buffer; - uint32_t token = instr->opcode; - unsigned int size = 1, i, j; - - size += instr->modifier_count; - for (i = 0; i < instr->dst_count; ++i) - size += sm4_register_order(&instr->dsts[i].reg); - for (i = 0; i < instr->src_count; ++i) - size += sm4_register_order(&instr->srcs[i].reg); - size += instr->idx_count; - if (instr->byte_stride) - ++size; - - token |= (size << VKD3D_SM4_INSTRUCTION_LENGTH_SHIFT); + uint32_t token = instr->opcode | instr->extra_bits; + unsigned int size, i, j; + size_t token_position; if (instr->modifier_count > 0) token |= VKD3D_SM4_INSTRUCTION_MODIFIER; - put_u32(buffer, token); + + token_position = put_u32(buffer, 0); for (i = 0; i < instr->modifier_count; ++i) { - token = sm4_encode_instruction_modifier(&instr->modifiers[i]); + uint32_t modifier_token = sm4_encode_instruction_modifier(&instr->modifiers[i]); + if (instr->modifier_count > i + 1) - token |= VKD3D_SM4_INSTRUCTION_MODIFIER; - put_u32(buffer, token); + modifier_token |= VKD3D_SM4_INSTRUCTION_MODIFIER; + put_u32(buffer, modifier_token); } for (i = 0; i < instr->dst_count; ++i) @@ -3968,6 +3969,10 @@ static void write_sm4_instruction(const struct tpf_writer *tpf, const struct sm4 for (j = 0; j < instr->idx_count; ++j) put_u32(buffer, instr->idx[j]); + + size = (bytecode_get_size(buffer) - token_position) / sizeof(uint32_t); + token |= (size << VKD3D_SM4_INSTRUCTION_LENGTH_SHIFT); + set_u32(buffer, token_position, token); } static bool encode_texel_offset_as_aoffimmi(struct sm4_instruction *instr, @@ -4003,13 +4008,12 @@ static void write_sm4_dcl_constant_buffer(const struct tpf_writer *tpf, const st { .opcode = VKD3D_SM4_OP_DCL_CONSTANT_BUFFER, - .srcs[0].reg.dim = VKD3D_SM4_DIMENSION_VEC4, + .srcs[0].reg.dimension = VSIR_DIMENSION_VEC4, .srcs[0].reg.type = VKD3DSPR_CONSTBUFFER, .srcs[0].reg.idx[0].offset = cbuffer->reg.id, .srcs[0].reg.idx[1].offset = (cbuffer->used_size + 3) / 4, .srcs[0].reg.idx_count = 2, - .srcs[0].swizzle_type = VKD3D_SM4_SWIZZLE_VEC4, - .srcs[0].swizzle = HLSL_SWIZZLE(X, Y, Z, W), + .srcs[0].swizzle = VKD3D_SHADER_NO_SWIZZLE, .src_count = 1, }; write_sm4_instruction(tpf, &instr); @@ -4031,7 +4035,7 @@ static void write_sm4_dcl_samplers(const struct tpf_writer *tpf, const struct ex component_type = hlsl_type_get_component_type(tpf->ctx, resource->data_type, 0); if (component_type->sampler_dim == HLSL_SAMPLER_DIM_COMPARISON) - instr.opcode |= VKD3D_SM4_SAMPLER_COMPARISON << VKD3D_SM4_SAMPLER_MODE_SHIFT; + instr.extra_bits |= VKD3D_SM4_SAMPLER_COMPARISON << VKD3D_SM4_SAMPLER_MODE_SHIFT; assert(resource->regset == HLSL_REGSET_SAMPLERS); @@ -4090,12 +4094,12 @@ static void write_sm4_dcl_textures(const struct tpf_writer *tpf, const struct ex { instr.opcode = VKD3D_SM4_OP_DCL_RESOURCE; } - instr.opcode |= (sm4_resource_dimension(component_type) << VKD3D_SM4_RESOURCE_TYPE_SHIFT); + instr.extra_bits |= (sm4_resource_dimension(component_type) << VKD3D_SM4_RESOURCE_TYPE_SHIFT); if (component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS || component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY) { - instr.opcode |= component_type->sample_count << VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT; + instr.extra_bits |= component_type->sample_count << VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT; } write_sm4_instruction(tpf, &instr); @@ -4111,11 +4115,11 @@ static void write_sm4_dcl_semantic(const struct tpf_writer *tpf, const struct hl struct sm4_instruction instr = { - .dsts[0].reg.dim = VKD3D_SM4_DIMENSION_VEC4, + .dsts[0].reg.dimension = VSIR_DIMENSION_VEC4, .dst_count = 1, }; - if (hlsl_sm4_register_from_semantic(tpf->ctx, &var->semantic, output, &instr.dsts[0].reg.type, NULL, &has_idx)) + if (hlsl_sm4_register_from_semantic(tpf->ctx, &var->semantic, output, &instr.dsts[0].reg.type, &has_idx)) { if (has_idx) { @@ -4126,18 +4130,18 @@ static void write_sm4_dcl_semantic(const struct tpf_writer *tpf, const struct hl { instr.dsts[0].reg.idx_count = 0; } - instr.dsts[0].writemask = (1 << var->data_type->dimx) - 1; + instr.dsts[0].write_mask = (1 << var->data_type->dimx) - 1; } else { instr.dsts[0].reg.type = output ? VKD3DSPR_OUTPUT : VKD3DSPR_INPUT; instr.dsts[0].reg.idx[0].offset = var->regs[HLSL_REGSET_NUMERIC].id; instr.dsts[0].reg.idx_count = 1; - instr.dsts[0].writemask = var->regs[HLSL_REGSET_NUMERIC].writemask; + instr.dsts[0].write_mask = var->regs[HLSL_REGSET_NUMERIC].writemask; } if (instr.dsts[0].reg.type == VKD3DSPR_DEPTHOUT) - instr.dsts[0].reg.dim = VKD3D_SM4_DIMENSION_SCALAR; + instr.dsts[0].reg.dimension = VSIR_DIMENSION_SCALAR; hlsl_sm4_usage_from_semantic(tpf->ctx, &var->semantic, output, &usage); if (usage == ~0u) @@ -4170,9 +4174,35 @@ static void write_sm4_dcl_semantic(const struct tpf_writer *tpf, const struct hl enum vkd3d_shader_interpolation_mode mode = VKD3DSIM_LINEAR; if ((var->storage_modifiers & HLSL_STORAGE_NOINTERPOLATION) || type_is_integer(var->data_type)) + { mode = VKD3DSIM_CONSTANT; + } + else + { + static const struct + { + unsigned int modifiers; + enum vkd3d_shader_interpolation_mode mode; + } + modes[] = + { + { HLSL_STORAGE_CENTROID | HLSL_STORAGE_NOPERSPECTIVE, VKD3DSIM_LINEAR_NOPERSPECTIVE_CENTROID }, + { HLSL_STORAGE_NOPERSPECTIVE, VKD3DSIM_LINEAR_NOPERSPECTIVE }, + { HLSL_STORAGE_CENTROID, VKD3DSIM_LINEAR_CENTROID }, + }; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(modes); ++i) + { + if ((var->storage_modifiers & modes[i].modifiers) == modes[i].modifiers) + { + mode = modes[i].mode; + break; + } + } + } - instr.opcode |= mode << VKD3D_SM4_INTERPOLATION_MODE_SHIFT; + instr.extra_bits |= mode << VKD3D_SM4_INTERPOLATION_MODE_SHIFT; } } else @@ -4241,7 +4271,7 @@ static void write_sm4_ret(const struct tpf_writer *tpf) } static void write_sm4_unary_op(const struct tpf_writer *tpf, enum vkd3d_sm4_opcode opcode, - const struct hlsl_ir_node *dst, const struct hlsl_ir_node *src, unsigned int src_mod) + const struct hlsl_ir_node *dst, const struct hlsl_ir_node *src, enum vkd3d_shader_src_modifier src_mod) { struct sm4_instruction instr; @@ -4251,8 +4281,8 @@ static void write_sm4_unary_op(const struct tpf_writer *tpf, enum vkd3d_sm4_opco sm4_dst_from_node(&instr.dsts[0], dst); instr.dst_count = 1; - sm4_src_from_node(&instr.srcs[0], src, instr.dsts[0].writemask); - instr.srcs[0].reg.mod = src_mod; + sm4_src_from_node(tpf, &instr.srcs[0], src, instr.dsts[0].write_mask); + instr.srcs[0].modifiers = src_mod; instr.src_count = 1; write_sm4_instruction(tpf, &instr); @@ -4270,11 +4300,11 @@ static void write_sm4_unary_op_with_two_destinations(const struct tpf_writer *tp sm4_dst_from_node(&instr.dsts[dst_idx], dst); assert(1 - dst_idx >= 0); instr.dsts[1 - dst_idx].reg.type = VKD3DSPR_NULL; - instr.dsts[1 - dst_idx].reg.dim = VKD3D_SM4_DIMENSION_NONE; + instr.dsts[1 - dst_idx].reg.dimension = VSIR_DIMENSION_NONE; instr.dsts[1 - dst_idx].reg.idx_count = 0; instr.dst_count = 2; - sm4_src_from_node(&instr.srcs[0], src, instr.dsts[dst_idx].writemask); + sm4_src_from_node(tpf, &instr.srcs[0], src, instr.dsts[dst_idx].write_mask); instr.src_count = 1; write_sm4_instruction(tpf, &instr); @@ -4291,8 +4321,8 @@ static void write_sm4_binary_op(const struct tpf_writer *tpf, enum vkd3d_sm4_opc sm4_dst_from_node(&instr.dsts[0], dst); instr.dst_count = 1; - sm4_src_from_node(&instr.srcs[0], src1, instr.dsts[0].writemask); - sm4_src_from_node(&instr.srcs[1], src2, instr.dsts[0].writemask); + sm4_src_from_node(tpf, &instr.srcs[0], src1, instr.dsts[0].write_mask); + sm4_src_from_node(tpf, &instr.srcs[1], src2, instr.dsts[0].write_mask); instr.src_count = 2; write_sm4_instruction(tpf, &instr); @@ -4310,8 +4340,8 @@ static void write_sm4_binary_op_dot(const struct tpf_writer *tpf, enum vkd3d_sm4 sm4_dst_from_node(&instr.dsts[0], dst); instr.dst_count = 1; - sm4_src_from_node(&instr.srcs[0], src1, VKD3DSP_WRITEMASK_ALL); - sm4_src_from_node(&instr.srcs[1], src2, VKD3DSP_WRITEMASK_ALL); + sm4_src_from_node(tpf, &instr.srcs[0], src1, VKD3DSP_WRITEMASK_ALL); + sm4_src_from_node(tpf, &instr.srcs[1], src2, VKD3DSP_WRITEMASK_ALL); instr.src_count = 2; write_sm4_instruction(tpf, &instr); @@ -4330,12 +4360,12 @@ static void write_sm4_binary_op_with_two_destinations(const struct tpf_writer *t sm4_dst_from_node(&instr.dsts[dst_idx], dst); assert(1 - dst_idx >= 0); instr.dsts[1 - dst_idx].reg.type = VKD3DSPR_NULL; - instr.dsts[1 - dst_idx].reg.dim = VKD3D_SM4_DIMENSION_NONE; + instr.dsts[1 - dst_idx].reg.dimension = VSIR_DIMENSION_NONE; instr.dsts[1 - dst_idx].reg.idx_count = 0; instr.dst_count = 2; - sm4_src_from_node(&instr.srcs[0], src1, instr.dsts[dst_idx].writemask); - sm4_src_from_node(&instr.srcs[1], src2, instr.dsts[dst_idx].writemask); + sm4_src_from_node(tpf, &instr.srcs[0], src1, instr.dsts[dst_idx].write_mask); + sm4_src_from_node(tpf, &instr.srcs[1], src2, instr.dsts[dst_idx].write_mask); instr.src_count = 2; write_sm4_instruction(tpf, &instr); @@ -4353,9 +4383,9 @@ static void write_sm4_ternary_op(const struct tpf_writer *tpf, enum vkd3d_sm4_op sm4_dst_from_node(&instr.dsts[0], dst); instr.dst_count = 1; - sm4_src_from_node(&instr.srcs[0], src1, instr.dsts[0].writemask); - sm4_src_from_node(&instr.srcs[1], src2, instr.dsts[0].writemask); - sm4_src_from_node(&instr.srcs[2], src3, instr.dsts[0].writemask); + sm4_src_from_node(tpf, &instr.srcs[0], src1, instr.dsts[0].write_mask); + sm4_src_from_node(tpf, &instr.srcs[1], src2, instr.dsts[0].write_mask); + sm4_src_from_node(tpf, &instr.srcs[2], src3, instr.dsts[0].write_mask); instr.src_count = 3; write_sm4_instruction(tpf, &instr); @@ -4369,7 +4399,7 @@ static void write_sm4_ld(const struct tpf_writer *tpf, const struct hlsl_ir_node const struct hlsl_type *resource_type = hlsl_deref_get_type(tpf->ctx, resource); bool multisampled = resource_type->base_type == HLSL_TYPE_TEXTURE && (resource_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS || resource_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY); - bool uav = (hlsl_type_get_regset(resource_type) == HLSL_REGSET_UAVS); + bool uav = (hlsl_deref_get_regset(tpf->ctx, resource) == HLSL_REGSET_UAVS); unsigned int coords_writemask = VKD3DSP_WRITEMASK_ALL; struct sm4_instruction instr; @@ -4404,9 +4434,9 @@ static void write_sm4_ld(const struct tpf_writer *tpf, const struct hlsl_ir_node coords_writemask = VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1 | VKD3DSP_WRITEMASK_3; } - sm4_src_from_node(&instr.srcs[0], coords, coords_writemask); + sm4_src_from_node(tpf, &instr.srcs[0], coords, coords_writemask); - sm4_src_from_deref(tpf->ctx, &instr.srcs[1], resource, instr.dsts[0].writemask); + sm4_src_from_deref(tpf, &instr.srcs[1], resource, instr.dsts[0].write_mask); instr.src_count = 2; @@ -4414,16 +4444,15 @@ static void write_sm4_ld(const struct tpf_writer *tpf, const struct hlsl_ir_node { if (sample_index->type == HLSL_IR_CONSTANT) { - struct sm4_register *reg = &instr.srcs[2].reg; + struct vkd3d_shader_register *reg = &instr.srcs[2].reg; struct hlsl_ir_constant *index; index = hlsl_ir_constant(sample_index); memset(&instr.srcs[2], 0, sizeof(instr.srcs[2])); - instr.srcs[2].swizzle_type = VKD3D_SM4_SWIZZLE_NONE; reg->type = VKD3DSPR_IMMCONST; - reg->dim = VKD3D_SM4_DIMENSION_SCALAR; - reg->immconst_uint[0] = index->value.u[0].u; + reg->dimension = VSIR_DIMENSION_SCALAR; + reg->u.immconst_uint[0] = index->value.u[0].u; } else if (tpf->ctx->profile->major_version == 4 && tpf->ctx->profile->minor_version == 0) { @@ -4431,7 +4460,7 @@ static void write_sm4_ld(const struct tpf_writer *tpf, const struct hlsl_ir_node } else { - sm4_src_from_node(&instr.srcs[2], sample_index, 0); + sm4_src_from_node(tpf, &instr.srcs[2], sample_index, 0); } ++instr.src_count; @@ -4493,27 +4522,27 @@ static void write_sm4_sample(const struct tpf_writer *tpf, const struct hlsl_ir_ sm4_dst_from_node(&instr.dsts[0], dst); instr.dst_count = 1; - sm4_src_from_node(&instr.srcs[0], coords, VKD3DSP_WRITEMASK_ALL); - sm4_src_from_deref(tpf->ctx, &instr.srcs[1], resource, instr.dsts[0].writemask); - sm4_src_from_deref(tpf->ctx, &instr.srcs[2], sampler, VKD3DSP_WRITEMASK_ALL); + sm4_src_from_node(tpf, &instr.srcs[0], coords, VKD3DSP_WRITEMASK_ALL); + sm4_src_from_deref(tpf, &instr.srcs[1], resource, instr.dsts[0].write_mask); + sm4_src_from_deref(tpf, &instr.srcs[2], sampler, VKD3DSP_WRITEMASK_ALL); instr.src_count = 3; if (load->load_type == HLSL_RESOURCE_SAMPLE_LOD || load->load_type == HLSL_RESOURCE_SAMPLE_LOD_BIAS) { - sm4_src_from_node(&instr.srcs[3], load->lod.node, VKD3DSP_WRITEMASK_ALL); + sm4_src_from_node(tpf, &instr.srcs[3], load->lod.node, VKD3DSP_WRITEMASK_ALL); ++instr.src_count; } else if (load->load_type == HLSL_RESOURCE_SAMPLE_GRAD) { - sm4_src_from_node(&instr.srcs[3], load->ddx.node, VKD3DSP_WRITEMASK_ALL); - sm4_src_from_node(&instr.srcs[4], load->ddy.node, VKD3DSP_WRITEMASK_ALL); + sm4_src_from_node(tpf, &instr.srcs[3], load->ddx.node, VKD3DSP_WRITEMASK_ALL); + sm4_src_from_node(tpf, &instr.srcs[4], load->ddy.node, VKD3DSP_WRITEMASK_ALL); instr.src_count += 2; } else if (load->load_type == HLSL_RESOURCE_SAMPLE_CMP || load->load_type == HLSL_RESOURCE_SAMPLE_CMP_LZ) { - sm4_src_from_node(&instr.srcs[3], load->cmp.node, VKD3DSP_WRITEMASK_ALL); + sm4_src_from_node(tpf, &instr.srcs[3], load->cmp.node, VKD3DSP_WRITEMASK_ALL); ++instr.src_count; } @@ -4531,12 +4560,12 @@ static void write_sm4_sampleinfo(const struct tpf_writer *tpf, const struct hlsl memset(&instr, 0, sizeof(instr)); instr.opcode = VKD3D_SM4_OP_SAMPLE_INFO; if (dst->data_type->base_type == HLSL_TYPE_UINT) - instr.opcode |= VKD3DSI_SAMPLE_INFO_UINT << VKD3D_SM4_INSTRUCTION_FLAGS_SHIFT; + instr.extra_bits |= VKD3DSI_SAMPLE_INFO_UINT << VKD3D_SM4_INSTRUCTION_FLAGS_SHIFT; sm4_dst_from_node(&instr.dsts[0], dst); instr.dst_count = 1; - sm4_src_from_deref(tpf->ctx, &instr.srcs[0], resource, instr.dsts[0].writemask); + sm4_src_from_deref(tpf, &instr.srcs[0], resource, instr.dsts[0].write_mask); instr.src_count = 1; write_sm4_instruction(tpf, &instr); @@ -4553,13 +4582,13 @@ static void write_sm4_resinfo(const struct tpf_writer *tpf, const struct hlsl_ir memset(&instr, 0, sizeof(instr)); instr.opcode = VKD3D_SM4_OP_RESINFO; if (dst->data_type->base_type == HLSL_TYPE_UINT) - instr.opcode |= VKD3DSI_RESINFO_UINT << VKD3D_SM4_INSTRUCTION_FLAGS_SHIFT; + instr.extra_bits |= VKD3DSI_RESINFO_UINT << VKD3D_SM4_INSTRUCTION_FLAGS_SHIFT; sm4_dst_from_node(&instr.dsts[0], dst); instr.dst_count = 1; - sm4_src_from_node(&instr.srcs[0], load->lod.node, VKD3DSP_WRITEMASK_ALL); - sm4_src_from_deref(tpf->ctx, &instr.srcs[1], resource, instr.dsts[0].writemask); + sm4_src_from_node(tpf, &instr.srcs[0], load->lod.node, VKD3DSP_WRITEMASK_ALL); + sm4_src_from_deref(tpf, &instr.srcs[1], resource, instr.dsts[0].write_mask); instr.src_count = 2; write_sm4_instruction(tpf, &instr); @@ -4581,11 +4610,10 @@ static void write_sm4_cast_from_bool(const struct tpf_writer *tpf, const struct sm4_dst_from_node(&instr.dsts[0], &expr->node); instr.dst_count = 1; - sm4_src_from_node(&instr.srcs[0], arg, instr.dsts[0].writemask); - instr.srcs[1].swizzle_type = VKD3D_SM4_SWIZZLE_NONE; + sm4_src_from_node(tpf, &instr.srcs[0], arg, instr.dsts[0].write_mask); instr.srcs[1].reg.type = VKD3DSPR_IMMCONST; - instr.srcs[1].reg.dim = VKD3D_SM4_DIMENSION_SCALAR; - instr.srcs[1].reg.immconst_uint[0] = mask; + instr.srcs[1].reg.dimension = VSIR_DIMENSION_SCALAR; + instr.srcs[1].reg.u.immconst_uint[0] = mask; instr.src_count = 2; write_sm4_instruction(tpf, &instr); @@ -4708,11 +4736,11 @@ static void write_sm4_store_uav_typed(const struct tpf_writer *tpf, const struct memset(&instr, 0, sizeof(instr)); instr.opcode = VKD3D_SM5_OP_STORE_UAV_TYPED; - sm4_register_from_deref(tpf->ctx, &instr.dsts[0].reg, &instr.dsts[0].writemask, NULL, dst); + sm4_register_from_deref(tpf->ctx, &instr.dsts[0].reg, &instr.dsts[0].write_mask, dst); instr.dst_count = 1; - sm4_src_from_node(&instr.srcs[0], coords, VKD3DSP_WRITEMASK_ALL); - sm4_src_from_node(&instr.srcs[1], value, VKD3DSP_WRITEMASK_ALL); + sm4_src_from_node(tpf, &instr.srcs[0], coords, VKD3DSP_WRITEMASK_ALL); + sm4_src_from_node(tpf, &instr.srcs[1], value, VKD3DSP_WRITEMASK_ALL); instr.src_count = 2; write_sm4_instruction(tpf, &instr); @@ -4737,7 +4765,7 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex switch (dst_type->base_type) { case HLSL_TYPE_FLOAT: - write_sm4_unary_op(tpf, VKD3D_SM4_OP_MOV, &expr->node, arg1, VKD3D_SM4_REGISTER_MODIFIER_ABS); + write_sm4_unary_op(tpf, VKD3D_SM4_OP_MOV, &expr->node, arg1, VKD3DSPSM_ABS); break; default: @@ -4818,7 +4846,7 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex switch (dst_type->base_type) { case HLSL_TYPE_FLOAT: - write_sm4_unary_op(tpf, VKD3D_SM4_OP_MOV, &expr->node, arg1, VKD3D_SM4_REGISTER_MODIFIER_NEGATE); + write_sm4_unary_op(tpf, VKD3D_SM4_OP_MOV, &expr->node, arg1, VKD3DSPSM_NEG); break; case HLSL_TYPE_INT: @@ -5169,7 +5197,7 @@ static void write_sm4_if(const struct tpf_writer *tpf, const struct hlsl_ir_if * assert(iff->condition.node->data_type->dimx == 1); - sm4_src_from_node(&instr.srcs[0], iff->condition.node, VKD3DSP_WRITEMASK_ALL); + sm4_src_from_node(tpf, &instr.srcs[0], iff->condition.node, VKD3DSP_WRITEMASK_ALL); write_sm4_instruction(tpf, &instr); write_sm4_block(tpf, &iff->then_block); @@ -5198,13 +5226,17 @@ static void write_sm4_jump(const struct tpf_writer *tpf, const struct hlsl_ir_ju instr.opcode = VKD3D_SM4_OP_BREAK; break; + case HLSL_IR_JUMP_CONTINUE: + instr.opcode = VKD3D_SM4_OP_CONTINUE; + break; + case HLSL_IR_JUMP_DISCARD_NZ: { instr.opcode = VKD3D_SM4_OP_DISCARD | VKD3D_SM4_CONDITIONAL_NZ; memset(&instr.srcs[0], 0, sizeof(*instr.srcs)); instr.src_count = 1; - sm4_src_from_node(&instr.srcs[0], jump->condition.node, VKD3DSP_WRITEMASK_ALL); + sm4_src_from_node(tpf, &instr.srcs[0], jump->condition.node, VKD3DSP_WRITEMASK_ALL); break; } @@ -5250,19 +5282,19 @@ static void write_sm4_load(const struct tpf_writer *tpf, const struct hlsl_ir_lo instr.opcode = VKD3D_SM4_OP_MOVC; - sm4_src_from_deref(tpf->ctx, &instr.srcs[0], &load->src, instr.dsts[0].writemask); + sm4_src_from_deref(tpf, &instr.srcs[0], &load->src, instr.dsts[0].write_mask); memset(&value, 0xff, sizeof(value)); - sm4_src_from_constant_value(&instr.srcs[1], &value, type->dimx, instr.dsts[0].writemask); + sm4_src_from_constant_value(&instr.srcs[1], &value, type->dimx, instr.dsts[0].write_mask); memset(&value, 0, sizeof(value)); - sm4_src_from_constant_value(&instr.srcs[2], &value, type->dimx, instr.dsts[0].writemask); + sm4_src_from_constant_value(&instr.srcs[2], &value, type->dimx, instr.dsts[0].write_mask); instr.src_count = 3; } else { instr.opcode = VKD3D_SM4_OP_MOV; - sm4_src_from_deref(tpf->ctx, &instr.srcs[0], &load->src, instr.dsts[0].writemask); + sm4_src_from_deref(tpf, &instr.srcs[0], &load->src, instr.dsts[0].write_mask); instr.src_count = 1; } @@ -5285,10 +5317,10 @@ static void write_sm4_loop(const struct tpf_writer *tpf, const struct hlsl_ir_lo } static void write_sm4_gather(const struct tpf_writer *tpf, const struct hlsl_ir_node *dst, - const struct hlsl_deref *resource, const struct hlsl_deref *sampler, const struct hlsl_ir_node *coords, - unsigned int swizzle, const struct hlsl_ir_node *texel_offset) + const struct hlsl_deref *resource, const struct hlsl_deref *sampler, + const struct hlsl_ir_node *coords, DWORD swizzle, const struct hlsl_ir_node *texel_offset) { - struct sm4_src_register *src; + struct vkd3d_shader_src_param *src; struct sm4_instruction instr; memset(&instr, 0, sizeof(instr)); @@ -5298,7 +5330,7 @@ static void write_sm4_gather(const struct tpf_writer *tpf, const struct hlsl_ir_ sm4_dst_from_node(&instr.dsts[0], dst); instr.dst_count = 1; - sm4_src_from_node(&instr.srcs[instr.src_count++], coords, VKD3DSP_WRITEMASK_ALL); + sm4_src_from_node(tpf, &instr.srcs[instr.src_count++], coords, VKD3DSP_WRITEMASK_ALL); if (texel_offset) { @@ -5311,16 +5343,15 @@ static void write_sm4_gather(const struct tpf_writer *tpf, const struct hlsl_ir_ return; } instr.opcode = VKD3D_SM5_OP_GATHER4_PO; - sm4_src_from_node(&instr.srcs[instr.src_count++], texel_offset, VKD3DSP_WRITEMASK_ALL); + sm4_src_from_node(tpf, &instr.srcs[instr.src_count++], texel_offset, VKD3DSP_WRITEMASK_ALL); } } - sm4_src_from_deref(tpf->ctx, &instr.srcs[instr.src_count++], resource, instr.dsts[0].writemask); + sm4_src_from_deref(tpf, &instr.srcs[instr.src_count++], resource, instr.dsts[0].write_mask); src = &instr.srcs[instr.src_count++]; - sm4_src_from_deref(tpf->ctx, src, sampler, VKD3DSP_WRITEMASK_ALL); - src->reg.dim = VKD3D_SM4_DIMENSION_VEC4; - src->swizzle_type = VKD3D_SM4_SWIZZLE_SCALAR; + sm4_src_from_deref(tpf, src, sampler, VKD3DSP_WRITEMASK_ALL); + src->reg.dimension = VSIR_DIMENSION_VEC4; src->swizzle = swizzle; write_sm4_instruction(tpf, &instr); @@ -5364,22 +5395,22 @@ static void write_sm4_resource_load(const struct tpf_writer *tpf, const struct h case HLSL_RESOURCE_GATHER_RED: write_sm4_gather(tpf, &load->node, &load->resource, &load->sampler, coords, - HLSL_SWIZZLE(X, X, X, X), texel_offset); + VKD3D_SHADER_SWIZZLE(X, X, X, X), texel_offset); break; case HLSL_RESOURCE_GATHER_GREEN: write_sm4_gather(tpf, &load->node, &load->resource, &load->sampler, coords, - HLSL_SWIZZLE(Y, Y, Y, Y), texel_offset); + VKD3D_SHADER_SWIZZLE(Y, Y, Y, Y), texel_offset); break; case HLSL_RESOURCE_GATHER_BLUE: write_sm4_gather(tpf, &load->node, &load->resource, &load->sampler, coords, - HLSL_SWIZZLE(Z, Z, Z, Z), texel_offset); + VKD3D_SHADER_SWIZZLE(Z, Z, Z, Z), texel_offset); break; case HLSL_RESOURCE_GATHER_ALPHA: write_sm4_gather(tpf, &load->node, &load->resource, &load->sampler, coords, - HLSL_SWIZZLE(W, W, W, W), texel_offset); + VKD3D_SHADER_SWIZZLE(W, W, W, W), texel_offset); break; case HLSL_RESOURCE_SAMPLE_INFO: @@ -5415,16 +5446,16 @@ static void write_sm4_store(const struct tpf_writer *tpf, const struct hlsl_ir_s { const struct hlsl_ir_node *rhs = store->rhs.node; struct sm4_instruction instr; - unsigned int writemask; + uint32_t writemask; memset(&instr, 0, sizeof(instr)); instr.opcode = VKD3D_SM4_OP_MOV; - sm4_register_from_deref(tpf->ctx, &instr.dsts[0].reg, &writemask, NULL, &store->lhs); - instr.dsts[0].writemask = hlsl_combine_writemasks(writemask, store->writemask); + sm4_register_from_deref(tpf->ctx, &instr.dsts[0].reg, &writemask, &store->lhs); + instr.dsts[0].write_mask = hlsl_combine_writemasks(writemask, store->writemask); instr.dst_count = 1; - sm4_src_from_node(&instr.srcs[0], rhs, instr.dsts[0].writemask); + sm4_src_from_node(tpf, &instr.srcs[0], rhs, instr.dsts[0].write_mask); instr.src_count = 1; write_sm4_instruction(tpf, &instr); @@ -5432,8 +5463,9 @@ static void write_sm4_store(const struct tpf_writer *tpf, const struct hlsl_ir_s static void write_sm4_swizzle(const struct tpf_writer *tpf, const struct hlsl_ir_swizzle *swizzle) { + unsigned int hlsl_swizzle; struct sm4_instruction instr; - unsigned int writemask; + uint32_t writemask; memset(&instr, 0, sizeof(instr)); instr.opcode = VKD3D_SM4_OP_MOV; @@ -5441,9 +5473,10 @@ static void write_sm4_swizzle(const struct tpf_writer *tpf, const struct hlsl_ir sm4_dst_from_node(&instr.dsts[0], &swizzle->node); instr.dst_count = 1; - sm4_register_from_node(&instr.srcs[0].reg, &writemask, &instr.srcs[0].swizzle_type, swizzle->val.node); - instr.srcs[0].swizzle = hlsl_map_swizzle(hlsl_combine_swizzles(hlsl_swizzle_from_writemask(writemask), - swizzle->swizzle, swizzle->node.data_type->dimx), instr.dsts[0].writemask); + sm4_register_from_node(&instr.srcs[0].reg, &writemask, swizzle->val.node); + hlsl_swizzle = hlsl_map_swizzle(hlsl_combine_swizzles(hlsl_swizzle_from_writemask(writemask), + swizzle->swizzle, swizzle->node.data_type->dimx), instr.dsts[0].write_mask); + instr.srcs[0].swizzle = swizzle_from_sm4(hlsl_swizzle); instr.src_count = 1; write_sm4_instruction(tpf, &instr); diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c index f25dbb04d69..d9b6995a11e 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c @@ -22,6 +22,8 @@ #include #include +/* VKD3D_DEBUG_ENV_NAME("VKD3D_SHADER_DEBUG"); */ + static inline int char_to_int(char c) { if ('0' <= c && c <= '9') @@ -452,6 +454,25 @@ static void init_scan_signature_info(const struct vkd3d_shader_compile_info *inf } } +static const struct vkd3d_debug_option vkd3d_shader_config_options[] = +{ + {"force_validation", VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION}, /* force validation of internal shader representations */ +}; + +static uint64_t vkd3d_shader_init_config_flags(void) +{ + uint64_t config_flags; + const char *config; + + config = getenv("VKD3D_SHADER_CONFIG"); + config_flags = vkd3d_parse_debug_options(config, vkd3d_shader_config_options, ARRAY_SIZE(vkd3d_shader_config_options)); + + if (config_flags) + TRACE("VKD3D_SHADER_CONFIG='%s'.\n", config); + + return config_flags; +} + bool vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vkd3d_shader_message_context *message_context, const char *source_name, const struct vkd3d_shader_version *version, const struct vkd3d_shader_parser_ops *ops, @@ -463,6 +484,7 @@ bool vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, parser->location.column = 0; parser->shader_version = *version; parser->ops = ops; + parser->config_flags = vkd3d_shader_init_config_flags(); return shader_instruction_array_init(&parser->instructions, instruction_reserve); } @@ -815,6 +837,15 @@ static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_conte d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE; } +static void vkd3d_shader_scan_combined_sampler_declaration( + struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_semantic *semantic) +{ + vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, &semantic->resource.reg.reg, + &semantic->resource.range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_SHADER_RESOURCE_DATA_UINT); + vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, &semantic->resource.reg.reg, + &semantic->resource.range, semantic->resource_type, VKD3D_SHADER_RESOURCE_DATA_FLOAT); +} + static void vkd3d_shader_scan_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, @@ -923,6 +954,12 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte vkd3d_shader_scan_sampler_declaration(context, instruction); break; case VKD3DSIH_DCL: + if (instruction->declaration.semantic.resource.reg.reg.type == VKD3DSPR_COMBINED_SAMPLER) + { + vkd3d_shader_scan_combined_sampler_declaration(context, &instruction->declaration.semantic); + break; + } + /* fall through */ case VKD3DSIH_DCL_UAV_TYPED: vkd3d_shader_scan_typed_resource_declaration(context, instruction); break; @@ -1751,7 +1788,7 @@ static struct vkd3d_shader_param_node *shader_param_allocator_node_create( static void shader_param_allocator_init(struct vkd3d_shader_param_allocator *allocator, unsigned int count, unsigned int stride) { - allocator->count = max(count, 4); + allocator->count = max(count, MAX_REG_OUTPUT); allocator->stride = stride; allocator->head = NULL; allocator->current = NULL; diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h index 9443df6c232..37c9625874f 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h @@ -49,7 +49,7 @@ #include "vkd3d_common.h" #include "vkd3d_memory.h" #include "vkd3d_shader.h" -#include "wine/list.h" +#include "list.h" #include #include @@ -92,6 +92,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_SPV_INVALID_DESCRIPTOR_BINDING = 2002, VKD3D_SHADER_ERROR_SPV_DESCRIPTOR_IDX_UNSUPPORTED = 2003, VKD3D_SHADER_ERROR_SPV_STENCIL_EXPORT_UNSUPPORTED = 2004, + VKD3D_SHADER_ERROR_SPV_OUT_OF_MEMORY = 2005, VKD3D_SHADER_WARNING_SPV_INVALID_SWIZZLE = 2300, @@ -174,15 +175,21 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_DXIL_INVALID_TYPE_ID = 8010, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE = 8011, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND = 8012, + VKD3D_SHADER_ERROR_DXIL_UNHANDLED_INTRINSIC = 8013, VKD3D_SHADER_WARNING_DXIL_UNKNOWN_MAGIC_NUMBER = 8300, VKD3D_SHADER_WARNING_DXIL_UNKNOWN_SHADER_TYPE = 8301, VKD3D_SHADER_WARNING_DXIL_INVALID_BLOCK_LENGTH = 8302, VKD3D_SHADER_WARNING_DXIL_INVALID_MODULE_LENGTH = 8303, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS = 8304, - VKD3D_SHADER_WARNING_DXIL_UNHANDLED_INTRINSIC = 8305, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED = 9000, + VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER = 9001, + VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE = 9002, + VKD3D_SHADER_ERROR_VSIR_INVALID_WRITE_MASK = 9003, + VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS = 9004, + VKD3D_SHADER_ERROR_VSIR_INVALID_SHIFT = 9005, + VKD3D_SHADER_ERROR_VSIR_INVALID_SWIZZLE = 9006, }; enum vkd3d_shader_opcode @@ -481,7 +488,7 @@ enum vkd3d_shader_register_type VKD3DSPR_CONSTINT = 7, VKD3DSPR_COLOROUT = 8, VKD3DSPR_DEPTHOUT = 9, - VKD3DSPR_SAMPLER = 10, + VKD3DSPR_COMBINED_SAMPLER = 10, VKD3DSPR_CONST2 = 11, VKD3DSPR_CONST3 = 12, VKD3DSPR_CONST4 = 13, @@ -497,6 +504,7 @@ enum vkd3d_shader_register_type VKD3DSPR_IMMCONSTBUFFER, VKD3DSPR_PRIMID, VKD3DSPR_NULL, + VKD3DSPR_SAMPLER, VKD3DSPR_RESOURCE, VKD3DSPR_UAV, VKD3DSPR_OUTPOINTID, @@ -523,6 +531,7 @@ enum vkd3d_shader_register_type VKD3DSPR_RASTERIZER, VKD3DSPR_OUTSTENCILREF, VKD3DSPR_UNDEF, + VKD3DSPR_SSA, VKD3DSPR_COUNT, @@ -563,10 +572,11 @@ static inline bool data_type_is_integer(enum vkd3d_data_type data_type) return data_type == VKD3D_DATA_INT || data_type == VKD3D_DATA_UINT8 || data_type == VKD3D_DATA_UINT; } -enum vkd3d_immconst_type +enum vsir_dimension { - VKD3D_IMMCONST_SCALAR, - VKD3D_IMMCONST_VEC4, + VSIR_DIMENSION_NONE, + VSIR_DIMENSION_SCALAR, + VSIR_DIMENSION_VEC4, }; enum vkd3d_shader_src_modifier @@ -585,6 +595,7 @@ enum vkd3d_shader_src_modifier VKD3DSPSM_ABS = 11, VKD3DSPSM_ABSNEG = 12, VKD3DSPSM_NOT = 13, + VKD3DSPSM_COUNT, }; #define VKD3DSP_WRITEMASK_0 0x1u /* .x r */ @@ -599,6 +610,7 @@ enum vkd3d_shader_dst_modifier VKD3DSPDM_SATURATE = 1, VKD3DSPDM_PARTIALPRECISION = 2, VKD3DSPDM_MSAMPCENTROID = 4, + VKD3DSPDM_MASK = 7, }; enum vkd3d_shader_interpolation_mode @@ -730,7 +742,7 @@ struct vkd3d_shader_register enum vkd3d_data_type data_type; struct vkd3d_shader_register_index idx[3]; unsigned int idx_count; - enum vkd3d_immconst_type immconst_type; + enum vsir_dimension dimension; union { DWORD immconst_uint[VKD3D_VEC4_SIZE]; @@ -741,13 +753,13 @@ struct vkd3d_shader_register } u; }; -void shader_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type, +void vsir_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int idx_count); struct vkd3d_shader_dst_param { struct vkd3d_shader_register reg; - DWORD write_mask; + uint32_t write_mask; DWORD modifiers; DWORD shift; }; @@ -872,6 +884,7 @@ struct vkd3d_shader_desc struct shader_signature patch_constant_signature; uint32_t temp_count; + unsigned int ssa_count; struct { @@ -968,8 +981,15 @@ struct vkd3d_shader_primitive_type unsigned int patch_vertex_count; }; +struct vkd3d_shader_location +{ + const char *source_name; + unsigned int line, column; +}; + struct vkd3d_shader_instruction { + struct vkd3d_shader_location location; enum vkd3d_shader_opcode handler_idx; DWORD flags; unsigned int dst_count; @@ -1008,7 +1028,8 @@ struct vkd3d_shader_instruction } declaration; }; -void shader_instruction_init(struct vkd3d_shader_instruction *ins, enum vkd3d_shader_opcode handler_idx); +void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location, + enum vkd3d_shader_opcode handler_idx); static inline bool vkd3d_shader_instruction_has_texel_offset(const struct vkd3d_shader_instruction *ins) { @@ -1035,12 +1056,6 @@ static inline bool register_is_constant(const struct vkd3d_shader_register *reg) return (reg->type == VKD3DSPR_IMMCONST || reg->type == VKD3DSPR_IMMCONST64); } -struct vkd3d_shader_location -{ - const char *source_name; - unsigned int line, column; -}; - struct vkd3d_shader_param_node { struct vkd3d_shader_param_node *next; @@ -1093,6 +1108,11 @@ bool shader_instruction_array_clone_instruction(struct vkd3d_shader_instruction_ unsigned int dst, unsigned int src); void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *instructions); +enum vkd3d_shader_config_flags +{ + VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION = 0x00000001, +}; + struct vkd3d_shader_parser { struct vkd3d_shader_message_context *message_context; @@ -1103,6 +1123,8 @@ struct vkd3d_shader_parser struct vkd3d_shader_version shader_version; const struct vkd3d_shader_parser_ops *ops; struct vkd3d_shader_instruction_array instructions; + + uint64_t config_flags; }; struct vkd3d_shader_parser_ops @@ -1291,6 +1313,8 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info, int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); +void vsir_validate(struct vkd3d_shader_parser *parser); + static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_type( enum vkd3d_data_type data_type) { diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c index 42a98763438..37484e5ea01 100644 --- a/libs/vkd3d/libs/vkd3d/command.c +++ b/libs/vkd3d/libs/vkd3d/command.c @@ -1942,9 +1942,9 @@ static void d3d12_command_signature_decref(struct d3d12_command_signature *signa } /* ID3D12CommandList */ -static inline struct d3d12_command_list *impl_from_ID3D12GraphicsCommandList3(ID3D12GraphicsCommandList3 *iface) +static inline struct d3d12_command_list *impl_from_ID3D12GraphicsCommandList5(ID3D12GraphicsCommandList5 *iface) { - return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandList3_iface); + return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandList5_iface); } static void d3d12_command_list_invalidate_current_framebuffer(struct d3d12_command_list *list) @@ -2290,12 +2290,14 @@ static void d3d12_command_list_track_resource_usage(struct d3d12_command_list *l } } -static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12GraphicsCommandList3 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12GraphicsCommandList5 *iface, REFIID iid, void **object) { TRACE("iface %p, iid %s, object %p.\n", iface, debugstr_guid(iid), object); - if (IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList3) + if (IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList5) + || IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList4) + || IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList3) || IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList2) || IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList1) || IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList) @@ -2304,7 +2306,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12Graphic || IsEqualGUID(iid, &IID_ID3D12Object) || IsEqualGUID(iid, &IID_IUnknown)) { - ID3D12GraphicsCommandList3_AddRef(iface); + ID3D12GraphicsCommandList5_AddRef(iface); *object = iface; return S_OK; } @@ -2315,9 +2317,9 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12Graphic return E_NOINTERFACE; } -static ULONG STDMETHODCALLTYPE d3d12_command_list_AddRef(ID3D12GraphicsCommandList3 *iface) +static ULONG STDMETHODCALLTYPE d3d12_command_list_AddRef(ID3D12GraphicsCommandList5 *iface) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); ULONG refcount = InterlockedIncrement(&list->refcount); TRACE("%p increasing refcount to %u.\n", list, refcount); @@ -2330,9 +2332,9 @@ static void vkd3d_pipeline_bindings_cleanup(struct vkd3d_pipeline_bindings *bind vkd3d_free(bindings->vk_uav_counter_views); } -static ULONG STDMETHODCALLTYPE d3d12_command_list_Release(ID3D12GraphicsCommandList3 *iface) +static ULONG STDMETHODCALLTYPE d3d12_command_list_Release(ID3D12GraphicsCommandList5 *iface) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); ULONG refcount = InterlockedDecrement(&list->refcount); TRACE("%p decreasing refcount to %u.\n", list, refcount); @@ -2358,66 +2360,66 @@ static ULONG STDMETHODCALLTYPE d3d12_command_list_Release(ID3D12GraphicsCommandL return refcount; } -static HRESULT STDMETHODCALLTYPE d3d12_command_list_GetPrivateData(ID3D12GraphicsCommandList3 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_command_list_GetPrivateData(ID3D12GraphicsCommandList5 *iface, REFGUID guid, UINT *data_size, void *data) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); return vkd3d_get_private_data(&list->private_store, guid, data_size, data); } -static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetPrivateData(ID3D12GraphicsCommandList3 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetPrivateData(ID3D12GraphicsCommandList5 *iface, REFGUID guid, UINT data_size, const void *data) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); return vkd3d_set_private_data(&list->private_store, guid, data_size, data); } -static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetPrivateDataInterface(ID3D12GraphicsCommandList3 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetPrivateDataInterface(ID3D12GraphicsCommandList5 *iface, REFGUID guid, const IUnknown *data) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); return vkd3d_set_private_data_interface(&list->private_store, guid, data); } -static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetName(ID3D12GraphicsCommandList3 *iface, const WCHAR *name) +static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetName(ID3D12GraphicsCommandList5 *iface, const WCHAR *name) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); TRACE("iface %p, name %s.\n", iface, debugstr_w(name, list->device->wchar_size)); return name ? S_OK : E_INVALIDARG; } -static HRESULT STDMETHODCALLTYPE d3d12_command_list_GetDevice(ID3D12GraphicsCommandList3 *iface, REFIID iid, void **device) +static HRESULT STDMETHODCALLTYPE d3d12_command_list_GetDevice(ID3D12GraphicsCommandList5 *iface, REFIID iid, void **device) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); TRACE("iface %p, iid %s, device %p.\n", iface, debugstr_guid(iid), device); return d3d12_device_query_interface(list->device, iid, device); } -static D3D12_COMMAND_LIST_TYPE STDMETHODCALLTYPE d3d12_command_list_GetType(ID3D12GraphicsCommandList3 *iface) +static D3D12_COMMAND_LIST_TYPE STDMETHODCALLTYPE d3d12_command_list_GetType(ID3D12GraphicsCommandList5 *iface) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); TRACE("iface %p.\n", iface); return list->type; } -static HRESULT STDMETHODCALLTYPE d3d12_command_list_Close(ID3D12GraphicsCommandList3 *iface) +static HRESULT STDMETHODCALLTYPE d3d12_command_list_Close(ID3D12GraphicsCommandList5 *iface) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); const struct vkd3d_vk_device_procs *vk_procs; VkResult vr; @@ -2461,7 +2463,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_Close(ID3D12GraphicsCommandL static void d3d12_command_list_reset_state(struct d3d12_command_list *list, ID3D12PipelineState *initial_pipeline_state) { - ID3D12GraphicsCommandList3 *iface = &list->ID3D12GraphicsCommandList3_iface; + ID3D12GraphicsCommandList5 *iface = &list->ID3D12GraphicsCommandList5_iface; memset(list->strides, 0, sizeof(list->strides)); list->primitive_topology = D3D_PRIMITIVE_TOPOLOGY_POINTLIST; @@ -2497,14 +2499,14 @@ static void d3d12_command_list_reset_state(struct d3d12_command_list *list, list->descriptor_heap_count = 0; - ID3D12GraphicsCommandList3_SetPipelineState(iface, initial_pipeline_state); + ID3D12GraphicsCommandList5_SetPipelineState(iface, initial_pipeline_state); } -static HRESULT STDMETHODCALLTYPE d3d12_command_list_Reset(ID3D12GraphicsCommandList3 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_command_list_Reset(ID3D12GraphicsCommandList5 *iface, ID3D12CommandAllocator *allocator, ID3D12PipelineState *initial_pipeline_state) { struct d3d12_command_allocator *allocator_impl = unsafe_impl_from_ID3D12CommandAllocator(allocator); - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); HRESULT hr; TRACE("iface %p, allocator %p, initial_pipeline_state %p.\n", @@ -2531,7 +2533,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_Reset(ID3D12GraphicsCommandL return hr; } -static void STDMETHODCALLTYPE d3d12_command_list_ClearState(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_ClearState(ID3D12GraphicsCommandList5 *iface, ID3D12PipelineState *pipeline_state) { FIXME("iface %p, pipline_state %p stub!\n", iface, pipeline_state); @@ -3390,11 +3392,11 @@ static void d3d12_command_list_check_index_buffer_strip_cut_value(struct d3d12_c } } -static void STDMETHODCALLTYPE d3d12_command_list_DrawInstanced(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_DrawInstanced(ID3D12GraphicsCommandList5 *iface, UINT vertex_count_per_instance, UINT instance_count, UINT start_vertex_location, UINT start_instance_location) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); const struct vkd3d_vk_device_procs *vk_procs; TRACE("iface %p, vertex_count_per_instance %u, instance_count %u, " @@ -3414,11 +3416,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_DrawInstanced(ID3D12GraphicsCom instance_count, start_vertex_location, start_instance_location)); } -static void STDMETHODCALLTYPE d3d12_command_list_DrawIndexedInstanced(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_DrawIndexedInstanced(ID3D12GraphicsCommandList5 *iface, UINT index_count_per_instance, UINT instance_count, UINT start_vertex_location, INT base_vertex_location, UINT start_instance_location) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); const struct vkd3d_vk_device_procs *vk_procs; TRACE("iface %p, index_count_per_instance %u, instance_count %u, start_vertex_location %u, " @@ -3440,10 +3442,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_DrawIndexedInstanced(ID3D12Grap instance_count, start_vertex_location, base_vertex_location, start_instance_location)); } -static void STDMETHODCALLTYPE d3d12_command_list_Dispatch(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_Dispatch(ID3D12GraphicsCommandList5 *iface, UINT x, UINT y, UINT z) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); const struct vkd3d_vk_device_procs *vk_procs; TRACE("iface %p, x %u, y %u, z %u.\n", iface, x, y, z); @@ -3459,10 +3461,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_Dispatch(ID3D12GraphicsCommandL VK_CALL(vkCmdDispatch(list->vk_command_buffer, x, y, z)); } -static void STDMETHODCALLTYPE d3d12_command_list_CopyBufferRegion(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_CopyBufferRegion(ID3D12GraphicsCommandList5 *iface, ID3D12Resource *dst, UINT64 dst_offset, ID3D12Resource *src, UINT64 src_offset, UINT64 byte_count) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); struct d3d12_resource *dst_resource, *src_resource; const struct vkd3d_vk_device_procs *vk_procs; VkBufferCopy buffer_copy; @@ -3744,11 +3746,11 @@ static bool validate_d3d12_box(const D3D12_BOX *box) && box->back > box->front; } -static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12GraphicsCommandList5 *iface, const D3D12_TEXTURE_COPY_LOCATION *dst, UINT dst_x, UINT dst_y, UINT dst_z, const D3D12_TEXTURE_COPY_LOCATION *src, const D3D12_BOX *src_box) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); struct d3d12_resource *dst_resource, *src_resource; const struct vkd3d_format *src_format, *dst_format; const struct vkd3d_vk_device_procs *vk_procs; @@ -3869,10 +3871,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12Graphic } } -static void STDMETHODCALLTYPE d3d12_command_list_CopyResource(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_CopyResource(ID3D12GraphicsCommandList5 *iface, ID3D12Resource *dst, ID3D12Resource *src) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); struct d3d12_resource *dst_resource, *src_resource; const struct vkd3d_format *dst_format, *src_format; const struct vkd3d_vk_device_procs *vk_procs; @@ -3939,7 +3941,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyResource(ID3D12GraphicsComm } } -static void STDMETHODCALLTYPE d3d12_command_list_CopyTiles(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_CopyTiles(ID3D12GraphicsCommandList5 *iface, ID3D12Resource *tiled_resource, const D3D12_TILED_RESOURCE_COORDINATE *tile_region_start_coordinate, const D3D12_TILE_REGION_SIZE *tile_region_size, ID3D12Resource *buffer, UINT64 buffer_offset, D3D12_TILE_COPY_FLAGS flags) @@ -3950,11 +3952,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyTiles(ID3D12GraphicsCommand buffer, buffer_offset, flags); } -static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresource(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresource(ID3D12GraphicsCommandList5 *iface, ID3D12Resource *dst, UINT dst_sub_resource_idx, ID3D12Resource *src, UINT src_sub_resource_idx, DXGI_FORMAT format) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); const struct vkd3d_format *src_format, *dst_format, *vk_format; struct d3d12_resource *dst_resource, *src_resource; const struct vkd3d_vk_device_procs *vk_procs; @@ -4017,10 +4019,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresource(ID3D12Graphi VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &vk_image_resolve)); } -static void STDMETHODCALLTYPE d3d12_command_list_IASetPrimitiveTopology(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_IASetPrimitiveTopology(ID3D12GraphicsCommandList5 *iface, D3D12_PRIMITIVE_TOPOLOGY topology) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); TRACE("iface %p, topology %#x.\n", iface, topology); @@ -4031,11 +4033,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetPrimitiveTopology(ID3D12Gr d3d12_command_list_invalidate_current_pipeline(list); } -static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCommandList5 *iface, UINT viewport_count, const D3D12_VIEWPORT *viewports) { VkViewport vk_viewports[D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); const struct vkd3d_vk_device_procs *vk_procs; unsigned int i; @@ -4069,10 +4071,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCo VK_CALL(vkCmdSetViewport(list->vk_command_buffer, 0, viewport_count, vk_viewports)); } -static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12GraphicsCommandList5 *iface, UINT rect_count, const D3D12_RECT *rects) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); VkRect2D vk_rects[D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; const struct vkd3d_vk_device_procs *vk_procs; unsigned int i; @@ -4097,10 +4099,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12Graphic VK_CALL(vkCmdSetScissor(list->vk_command_buffer, 0, rect_count, vk_rects)); } -static void STDMETHODCALLTYPE d3d12_command_list_OMSetBlendFactor(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_OMSetBlendFactor(ID3D12GraphicsCommandList5 *iface, const FLOAT blend_factor[4]) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); const struct vkd3d_vk_device_procs *vk_procs; TRACE("iface %p, blend_factor %p.\n", iface, blend_factor); @@ -4109,10 +4111,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetBlendFactor(ID3D12Graphics VK_CALL(vkCmdSetBlendConstants(list->vk_command_buffer, blend_factor)); } -static void STDMETHODCALLTYPE d3d12_command_list_OMSetStencilRef(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_OMSetStencilRef(ID3D12GraphicsCommandList5 *iface, UINT stencil_ref) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); const struct vkd3d_vk_device_procs *vk_procs; TRACE("iface %p, stencil_ref %u.\n", iface, stencil_ref); @@ -4121,11 +4123,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetStencilRef(ID3D12GraphicsC VK_CALL(vkCmdSetStencilReference(list->vk_command_buffer, VK_STENCIL_FRONT_AND_BACK, stencil_ref)); } -static void STDMETHODCALLTYPE d3d12_command_list_SetPipelineState(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SetPipelineState(ID3D12GraphicsCommandList5 *iface, ID3D12PipelineState *pipeline_state) { struct d3d12_pipeline_state *state = unsafe_impl_from_ID3D12PipelineState(pipeline_state); - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); TRACE("iface %p, pipeline_state %p.\n", iface, pipeline_state); @@ -4176,10 +4178,10 @@ static unsigned int d3d12_find_ds_multiplanar_transition(const D3D12_RESOURCE_BA return 0; } -static void STDMETHODCALLTYPE d3d12_command_list_ResourceBarrier(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_ResourceBarrier(ID3D12GraphicsCommandList5 *iface, UINT barrier_count, const D3D12_RESOURCE_BARRIER *barriers) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); bool have_aliasing_barriers = false, have_split_barriers = false; const struct vkd3d_vk_device_procs *vk_procs; const struct vkd3d_vulkan_info *vk_info; @@ -4402,13 +4404,13 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResourceBarrier(ID3D12GraphicsC WARN("Issuing split barrier(s) on D3D12_RESOURCE_BARRIER_FLAG_END_ONLY.\n"); } -static void STDMETHODCALLTYPE d3d12_command_list_ExecuteBundle(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_ExecuteBundle(ID3D12GraphicsCommandList5 *iface, ID3D12GraphicsCommandList *command_list) { FIXME("iface %p, command_list %p stub!\n", iface, command_list); } -static void STDMETHODCALLTYPE d3d12_command_list_SetDescriptorHeaps(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SetDescriptorHeaps(ID3D12GraphicsCommandList5 *iface, UINT heap_count, ID3D12DescriptorHeap *const *heaps) { TRACE("iface %p, heap_count %u, heaps %p.\n", iface, heap_count, heaps); @@ -4434,10 +4436,10 @@ static void d3d12_command_list_set_root_signature(struct d3d12_command_list *lis d3d12_command_list_invalidate_root_parameters(list, bind_point); } -static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootSignature(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootSignature(ID3D12GraphicsCommandList5 *iface, ID3D12RootSignature *root_signature) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); TRACE("iface %p, root_signature %p.\n", iface, root_signature); @@ -4445,10 +4447,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootSignature(ID3D12G unsafe_impl_from_ID3D12RootSignature(root_signature)); } -static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootSignature(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootSignature(ID3D12GraphicsCommandList5 *iface, ID3D12RootSignature *root_signature) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); TRACE("iface %p, root_signature %p.\n", iface, root_signature); @@ -4487,10 +4489,10 @@ static void d3d12_command_list_set_descriptor_table(struct d3d12_command_list *l bindings->descriptor_table_active_mask |= (uint64_t)1 << index; } -static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootDescriptorTable(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootDescriptorTable(ID3D12GraphicsCommandList5 *iface, UINT root_parameter_index, D3D12_GPU_DESCRIPTOR_HANDLE base_descriptor) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); TRACE("iface %p, root_parameter_index %u, base_descriptor %#"PRIx64".\n", iface, root_parameter_index, base_descriptor.ptr); @@ -4499,10 +4501,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootDescriptorTable(I root_parameter_index, base_descriptor); } -static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootDescriptorTable(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootDescriptorTable(ID3D12GraphicsCommandList5 *iface, UINT root_parameter_index, D3D12_GPU_DESCRIPTOR_HANDLE base_descriptor) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); TRACE("iface %p, root_parameter_index %u, base_descriptor %#"PRIx64".\n", iface, root_parameter_index, base_descriptor.ptr); @@ -4524,10 +4526,10 @@ static void d3d12_command_list_set_root_constants(struct d3d12_command_list *lis c->stage_flags, c->offset + offset * sizeof(uint32_t), count * sizeof(uint32_t), data)); } -static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstant(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstant(ID3D12GraphicsCommandList5 *iface, UINT root_parameter_index, UINT data, UINT dst_offset) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); TRACE("iface %p, root_parameter_index %u, data 0x%08x, dst_offset %u.\n", iface, root_parameter_index, data, dst_offset); @@ -4536,10 +4538,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstant(ID3 root_parameter_index, dst_offset, 1, &data); } -static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstant(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstant(ID3D12GraphicsCommandList5 *iface, UINT root_parameter_index, UINT data, UINT dst_offset) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); TRACE("iface %p, root_parameter_index %u, data 0x%08x, dst_offset %u.\n", iface, root_parameter_index, data, dst_offset); @@ -4548,10 +4550,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstant(ID root_parameter_index, dst_offset, 1, &data); } -static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstants(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstants(ID3D12GraphicsCommandList5 *iface, UINT root_parameter_index, UINT constant_count, const void *data, UINT dst_offset) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); TRACE("iface %p, root_parameter_index %u, constant_count %u, data %p, dst_offset %u.\n", iface, root_parameter_index, constant_count, data, dst_offset); @@ -4560,10 +4562,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstants(ID root_parameter_index, dst_offset, constant_count, data); } -static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstants(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstants(ID3D12GraphicsCommandList5 *iface, UINT root_parameter_index, UINT constant_count, const void *data, UINT dst_offset) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); TRACE("iface %p, root_parameter_index %u, constant_count %u, data %p, dst_offset %u.\n", iface, root_parameter_index, constant_count, data, dst_offset); @@ -4625,9 +4627,9 @@ static void d3d12_command_list_set_root_cbv(struct d3d12_command_list *list, } static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootConstantBufferView( - ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) + ID3D12GraphicsCommandList5 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", iface, root_parameter_index, address); @@ -4636,9 +4638,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootConstantBufferVie } static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootConstantBufferView( - ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) + ID3D12GraphicsCommandList5 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", iface, root_parameter_index, address); @@ -4697,9 +4699,9 @@ static void d3d12_command_list_set_root_descriptor(struct d3d12_command_list *li } static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootShaderResourceView( - ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) + ID3D12GraphicsCommandList5 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", iface, root_parameter_index, address); @@ -4709,9 +4711,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootShaderResourceVie } static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootShaderResourceView( - ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) + ID3D12GraphicsCommandList5 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", iface, root_parameter_index, address); @@ -4721,9 +4723,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootShaderResourceVi } static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootUnorderedAccessView( - ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) + ID3D12GraphicsCommandList5 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", iface, root_parameter_index, address); @@ -4733,9 +4735,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootUnorderedAccessVi } static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootUnorderedAccessView( - ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) + ID3D12GraphicsCommandList5 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", iface, root_parameter_index, address); @@ -4744,10 +4746,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootUnorderedAccessV root_parameter_index, address); } -static void STDMETHODCALLTYPE d3d12_command_list_IASetIndexBuffer(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_IASetIndexBuffer(ID3D12GraphicsCommandList5 *iface, const D3D12_INDEX_BUFFER_VIEW *view) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); const struct vkd3d_vk_device_procs *vk_procs; struct d3d12_resource *resource; enum VkIndexType index_type; @@ -4787,10 +4789,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetIndexBuffer(ID3D12Graphics view->BufferLocation - resource->gpu_address, index_type)); } -static void STDMETHODCALLTYPE d3d12_command_list_IASetVertexBuffers(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_IASetVertexBuffers(ID3D12GraphicsCommandList5 *iface, UINT start_slot, UINT view_count, const D3D12_VERTEX_BUFFER_VIEW *views) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); const struct vkd3d_null_resources *null_resources; struct vkd3d_gpu_va_allocator *gpu_va_allocator; VkDeviceSize offsets[ARRAY_SIZE(list->strides)]; @@ -4845,10 +4847,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetVertexBuffers(ID3D12Graphi d3d12_command_list_invalidate_current_pipeline(list); } -static void STDMETHODCALLTYPE d3d12_command_list_SOSetTargets(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SOSetTargets(ID3D12GraphicsCommandList5 *iface, UINT start_slot, UINT view_count, const D3D12_STREAM_OUTPUT_BUFFER_VIEW *views) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); VkDeviceSize offsets[ARRAY_SIZE(list->so_counter_buffers)]; VkDeviceSize sizes[ARRAY_SIZE(list->so_counter_buffers)]; VkBuffer buffers[ARRAY_SIZE(list->so_counter_buffers)]; @@ -4910,11 +4912,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_SOSetTargets(ID3D12GraphicsComm VK_CALL(vkCmdBindTransformFeedbackBuffersEXT(list->vk_command_buffer, first, count, buffers, offsets, sizes)); } -static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12GraphicsCommandList5 *iface, UINT render_target_descriptor_count, const D3D12_CPU_DESCRIPTOR_HANDLE *render_target_descriptors, BOOL single_descriptor_handle, const D3D12_CPU_DESCRIPTOR_HANDLE *depth_stencil_descriptor) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); const struct d3d12_rtv_desc *rtv_desc; const struct d3d12_dsv_desc *dsv_desc; VkFormat prev_dsv_format; @@ -5115,12 +5117,12 @@ static void d3d12_command_list_clear(struct d3d12_command_list *list, } } -static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12GraphicsCommandList5 *iface, D3D12_CPU_DESCRIPTOR_HANDLE dsv, D3D12_CLEAR_FLAGS flags, float depth, UINT8 stencil, UINT rect_count, const D3D12_RECT *rects) { const union VkClearValue clear_value = {.depthStencil = {depth, stencil}}; - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); const struct d3d12_dsv_desc *dsv_desc = d3d12_dsv_desc_from_cpu_handle(dsv); struct VkAttachmentDescription attachment_desc; struct VkAttachmentReference ds_reference; @@ -5164,10 +5166,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12Gra &clear_value, rect_count, rects); } -static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12GraphicsCommandList5 *iface, D3D12_CPU_DESCRIPTOR_HANDLE rtv, const FLOAT color[4], UINT rect_count, const D3D12_RECT *rects) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); const struct d3d12_rtv_desc *rtv_desc = d3d12_rtv_desc_from_cpu_handle(rtv); struct VkAttachmentDescription attachment_desc; struct VkAttachmentReference color_reference; @@ -5412,11 +5414,11 @@ static const struct vkd3d_format *vkd3d_fixup_clear_uav_uint_colour(struct d3d12 } } -static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID3D12GraphicsCommandList5 *iface, D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle, D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle, ID3D12Resource *resource, const UINT values[4], UINT rect_count, const D3D12_RECT *rects) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); struct vkd3d_view *descriptor, *uint_view = NULL; struct d3d12_device *device = list->device; struct vkd3d_texture_view_desc view_desc; @@ -5461,6 +5463,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID view_desc.miplevel_count = 1; view_desc.layer_idx = view->info.texture.layer_idx; view_desc.layer_count = view->info.texture.layer_count; + view_desc.vk_image_aspect = VK_IMAGE_ASPECT_COLOR_BIT; + view_desc.usage = VK_IMAGE_USAGE_STORAGE_BIT; if (!vkd3d_create_texture_view(device, VKD3D_DESCRIPTOR_MAGIC_UAV, resource_impl->u.vk_image, &view_desc, &uint_view)) @@ -5478,11 +5482,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID vkd3d_view_decref(uint_view, device); } -static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(ID3D12GraphicsCommandList5 *iface, D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle, D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle, ID3D12Resource *resource, const float values[4], UINT rect_count, const D3D12_RECT *rects) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); struct d3d12_resource *resource_impl; VkClearColorValue colour; struct vkd3d_view *view; @@ -5498,16 +5502,16 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(I d3d12_command_list_clear_uav(list, resource_impl, view, &colour, rect_count, rects); } -static void STDMETHODCALLTYPE d3d12_command_list_DiscardResource(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_DiscardResource(ID3D12GraphicsCommandList5 *iface, ID3D12Resource *resource, const D3D12_DISCARD_REGION *region) { FIXME_ONCE("iface %p, resource %p, region %p stub!\n", iface, resource, region); } -static void STDMETHODCALLTYPE d3d12_command_list_BeginQuery(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_BeginQuery(ID3D12GraphicsCommandList5 *iface, ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, UINT index) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); struct d3d12_query_heap *query_heap = unsafe_impl_from_ID3D12QueryHeap(heap); const struct vkd3d_vk_device_procs *vk_procs; VkQueryControlFlags flags = 0; @@ -5534,10 +5538,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_BeginQuery(ID3D12GraphicsComman VK_CALL(vkCmdBeginQuery(list->vk_command_buffer, query_heap->vk_query_pool, index, flags)); } -static void STDMETHODCALLTYPE d3d12_command_list_EndQuery(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_EndQuery(ID3D12GraphicsCommandList5 *iface, ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, UINT index) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); struct d3d12_query_heap *query_heap = unsafe_impl_from_ID3D12QueryHeap(heap); const struct vkd3d_vk_device_procs *vk_procs; @@ -5579,12 +5583,12 @@ static size_t get_query_stride(D3D12_QUERY_TYPE type) return sizeof(uint64_t); } -static void STDMETHODCALLTYPE d3d12_command_list_ResolveQueryData(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_ResolveQueryData(ID3D12GraphicsCommandList5 *iface, ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, UINT start_index, UINT query_count, ID3D12Resource *dst_buffer, UINT64 aligned_dst_buffer_offset) { const struct d3d12_query_heap *query_heap = unsafe_impl_from_ID3D12QueryHeap(heap); - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); struct d3d12_resource *buffer = unsafe_impl_from_ID3D12Resource(dst_buffer); const struct vkd3d_vk_device_procs *vk_procs; unsigned int i, first, count; @@ -5660,10 +5664,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveQueryData(ID3D12Graphics } } -static void STDMETHODCALLTYPE d3d12_command_list_SetPredication(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SetPredication(ID3D12GraphicsCommandList5 *iface, ID3D12Resource *buffer, UINT64 aligned_buffer_offset, D3D12_PREDICATION_OP operation) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); struct d3d12_resource *resource = unsafe_impl_from_ID3D12Resource(buffer); const struct vkd3d_vulkan_info *vk_info = &list->device->vk_info; const struct vkd3d_vk_device_procs *vk_procs; @@ -5732,19 +5736,19 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetPredication(ID3D12GraphicsCo } } -static void STDMETHODCALLTYPE d3d12_command_list_SetMarker(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SetMarker(ID3D12GraphicsCommandList5 *iface, UINT metadata, const void *data, UINT size) { FIXME("iface %p, metadata %#x, data %p, size %u stub!\n", iface, metadata, data, size); } -static void STDMETHODCALLTYPE d3d12_command_list_BeginEvent(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_BeginEvent(ID3D12GraphicsCommandList5 *iface, UINT metadata, const void *data, UINT size) { FIXME("iface %p, metadata %#x, data %p, size %u stub!\n", iface, metadata, data, size); } -static void STDMETHODCALLTYPE d3d12_command_list_EndEvent(ID3D12GraphicsCommandList3 *iface) +static void STDMETHODCALLTYPE d3d12_command_list_EndEvent(ID3D12GraphicsCommandList5 *iface) { FIXME("iface %p stub!\n", iface); } @@ -5753,14 +5757,14 @@ STATIC_ASSERT(sizeof(VkDispatchIndirectCommand) == sizeof(D3D12_DISPATCH_ARGUMEN STATIC_ASSERT(sizeof(VkDrawIndexedIndirectCommand) == sizeof(D3D12_DRAW_INDEXED_ARGUMENTS)); STATIC_ASSERT(sizeof(VkDrawIndirectCommand) == sizeof(D3D12_DRAW_ARGUMENTS)); -static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsCommandList5 *iface, ID3D12CommandSignature *command_signature, UINT max_command_count, ID3D12Resource *arg_buffer, UINT64 arg_buffer_offset, ID3D12Resource *count_buffer, UINT64 count_buffer_offset) { struct d3d12_command_signature *sig_impl = unsafe_impl_from_ID3D12CommandSignature(command_signature); struct d3d12_resource *count_impl = unsafe_impl_from_ID3D12Resource(count_buffer); struct d3d12_resource *arg_impl = unsafe_impl_from_ID3D12Resource(arg_buffer); - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); const D3D12_COMMAND_SIGNATURE_DESC *signature_desc; const struct vkd3d_vk_device_procs *vk_procs; unsigned int i; @@ -5859,7 +5863,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsC d3d12_command_signature_decref(sig_impl); } -static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT(ID3D12GraphicsCommandList5 *iface, ID3D12Resource *dst_buffer, UINT64 dst_offset, ID3D12Resource *src_buffer, UINT64 src_offset, UINT dependent_resource_count, ID3D12Resource * const *dependent_resources, @@ -5872,7 +5876,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT(ID3D12Grap dependent_resource_count, dependent_resources, dependent_sub_resource_ranges); } -static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT64(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT64(ID3D12GraphicsCommandList5 *iface, ID3D12Resource *dst_buffer, UINT64 dst_offset, ID3D12Resource *src_buffer, UINT64 src_offset, UINT dependent_resource_count, ID3D12Resource * const *dependent_resources, @@ -5885,20 +5889,20 @@ static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT64(ID3D12Gr dependent_resource_count, dependent_resources, dependent_sub_resource_ranges); } -static void STDMETHODCALLTYPE d3d12_command_list_OMSetDepthBounds(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_OMSetDepthBounds(ID3D12GraphicsCommandList5 *iface, FLOAT min, FLOAT max) { FIXME("iface %p, min %.8e, max %.8e stub!\n", iface, min, max); } -static void STDMETHODCALLTYPE d3d12_command_list_SetSamplePositions(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SetSamplePositions(ID3D12GraphicsCommandList5 *iface, UINT sample_count, UINT pixel_count, D3D12_SAMPLE_POSITION *sample_positions) { FIXME("iface %p, sample_count %u, pixel_count %u, sample_positions %p stub!\n", iface, sample_count, pixel_count, sample_positions); } -static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresourceRegion(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresourceRegion(ID3D12GraphicsCommandList5 *iface, ID3D12Resource *dst_resource, UINT dst_sub_resource_idx, UINT dst_x, UINT dst_y, ID3D12Resource *src_resource, UINT src_sub_resource_idx, D3D12_RECT *src_rect, DXGI_FORMAT format, D3D12_RESOLVE_MODE mode) @@ -5910,16 +5914,16 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresourceRegion(ID3D12 src_resource, src_sub_resource_idx, src_rect, format, mode); } -static void STDMETHODCALLTYPE d3d12_command_list_SetViewInstanceMask(ID3D12GraphicsCommandList3 *iface, UINT mask) +static void STDMETHODCALLTYPE d3d12_command_list_SetViewInstanceMask(ID3D12GraphicsCommandList5 *iface, UINT mask) { FIXME("iface %p, mask %#x stub!\n", iface, mask); } -static void STDMETHODCALLTYPE d3d12_command_list_WriteBufferImmediate(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_WriteBufferImmediate(ID3D12GraphicsCommandList5 *iface, UINT count, const D3D12_WRITEBUFFERIMMEDIATE_PARAMETER *parameters, const D3D12_WRITEBUFFERIMMEDIATE_MODE *modes) { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); struct d3d12_resource *resource; unsigned int i; @@ -5932,13 +5936,88 @@ static void STDMETHODCALLTYPE d3d12_command_list_WriteBufferImmediate(ID3D12Grap } } -static void STDMETHODCALLTYPE d3d12_command_list_SetProtectedResourceSession(ID3D12GraphicsCommandList3 *iface, +static void STDMETHODCALLTYPE d3d12_command_list_SetProtectedResourceSession(ID3D12GraphicsCommandList5 *iface, ID3D12ProtectedResourceSession *protected_session) { FIXME("iface %p, protected_session %p stub!\n", iface, protected_session); } -static const struct ID3D12GraphicsCommandList3Vtbl d3d12_command_list_vtbl = +static void STDMETHODCALLTYPE d3d12_command_list_BeginRenderPass(ID3D12GraphicsCommandList5 *iface, + UINT count, const D3D12_RENDER_PASS_RENDER_TARGET_DESC *render_targets, + const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC *depth_stencil, D3D12_RENDER_PASS_FLAGS flags) +{ + FIXME("iface %p, count %u, render_targets %p, depth_stencil %p, flags %#x stub!\n", iface, + count, render_targets, depth_stencil, flags); +} + +static void STDMETHODCALLTYPE d3d12_command_list_EndRenderPass(ID3D12GraphicsCommandList5 *iface) +{ + FIXME("iface %p stub!\n", iface); +} + +static void STDMETHODCALLTYPE d3d12_command_list_InitializeMetaCommand(ID3D12GraphicsCommandList5 *iface, + ID3D12MetaCommand *meta_command, const void *parameters_data, SIZE_T data_size_in_bytes) +{ + FIXME("iface %p, meta_command %p, parameters_data %p, data_size_in_bytes %lu stub!\n", iface, + meta_command, parameters_data, data_size_in_bytes); +} + +static void STDMETHODCALLTYPE d3d12_command_list_ExecuteMetaCommand(ID3D12GraphicsCommandList5 *iface, + ID3D12MetaCommand *meta_command, const void *parameters_data, SIZE_T data_size_in_bytes) +{ + FIXME("iface %p, meta_command %p, parameters_data %p, data_size_in_bytes %lu stub!\n", iface, + meta_command, parameters_data, data_size_in_bytes); +} + +static void STDMETHODCALLTYPE d3d12_command_list_BuildRaytracingAccelerationStructure(ID3D12GraphicsCommandList5 *iface, + const D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC *desc, UINT count, + const D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC *postbuild_info_descs) +{ + FIXME("iface %p, desc %p, count %u, postbuild_info_descs %p stub!\n", iface, desc, count, postbuild_info_descs); +} + +static void STDMETHODCALLTYPE d3d12_command_list_EmitRaytracingAccelerationStructurePostbuildInfo(ID3D12GraphicsCommandList5 *iface, + const D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC *desc, + UINT structures_count, const D3D12_GPU_VIRTUAL_ADDRESS *src_structure_data) +{ + FIXME("iface %p, desc %p, structures_count %u, src_structure_data %p stub!\n", + iface, desc, structures_count, src_structure_data); +} + +static void STDMETHODCALLTYPE d3d12_command_list_CopyRaytracingAccelerationStructure(ID3D12GraphicsCommandList5 *iface, + D3D12_GPU_VIRTUAL_ADDRESS dst_structure_data, + D3D12_GPU_VIRTUAL_ADDRESS src_structure_data, + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE mode) +{ + FIXME("iface %p, dst_structure_data %#"PRIx64", src_structure_data %#"PRIx64", mode %u stub!\n", + iface, dst_structure_data, src_structure_data, mode); +} + +static void STDMETHODCALLTYPE d3d12_command_list_SetPipelineState1(ID3D12GraphicsCommandList5 *iface, + ID3D12StateObject *state_object) +{ + FIXME("iface %p, state_object %p stub!\n", iface, state_object); +} + +static void STDMETHODCALLTYPE d3d12_command_list_DispatchRays(ID3D12GraphicsCommandList5 *iface, + const D3D12_DISPATCH_RAYS_DESC *desc) +{ + FIXME("iface %p, desc %p stub!\n", iface, desc); +} + +static void STDMETHODCALLTYPE d3d12_command_list_RSSetShadingRate(ID3D12GraphicsCommandList5 *iface, + D3D12_SHADING_RATE rate, const D3D12_SHADING_RATE_COMBINER *combiners) +{ + FIXME("iface %p, rate %#x, combiners %p stub!\n", iface, rate, combiners); +} + +static void STDMETHODCALLTYPE d3d12_command_list_RSSetShadingRateImage(ID3D12GraphicsCommandList5 *iface, + ID3D12Resource *rate_image) +{ + FIXME("iface %p, rate_image %p stub!\n", iface, rate_image); +} + +static const struct ID3D12GraphicsCommandList5Vtbl d3d12_command_list_vtbl = { /* IUnknown methods */ d3d12_command_list_QueryInterface, @@ -6016,6 +6095,19 @@ static const struct ID3D12GraphicsCommandList3Vtbl d3d12_command_list_vtbl = d3d12_command_list_WriteBufferImmediate, /* ID3D12GraphicsCommandList3 methods */ d3d12_command_list_SetProtectedResourceSession, + /* ID3D12GraphicsCommandList4 methods */ + d3d12_command_list_BeginRenderPass, + d3d12_command_list_EndRenderPass, + d3d12_command_list_InitializeMetaCommand, + d3d12_command_list_ExecuteMetaCommand, + d3d12_command_list_BuildRaytracingAccelerationStructure, + d3d12_command_list_EmitRaytracingAccelerationStructurePostbuildInfo, + d3d12_command_list_CopyRaytracingAccelerationStructure, + d3d12_command_list_SetPipelineState1, + d3d12_command_list_DispatchRays, + /* ID3D12GraphicsCommandList5 methods */ + d3d12_command_list_RSSetShadingRate, + d3d12_command_list_RSSetShadingRateImage, }; static struct d3d12_command_list *unsafe_impl_from_ID3D12CommandList(ID3D12CommandList *iface) @@ -6023,7 +6115,7 @@ static struct d3d12_command_list *unsafe_impl_from_ID3D12CommandList(ID3D12Comma if (!iface) return NULL; assert(iface->lpVtbl == (struct ID3D12CommandListVtbl *)&d3d12_command_list_vtbl); - return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandList3_iface); + return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandList5_iface); } static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, struct d3d12_device *device, @@ -6032,7 +6124,7 @@ static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, struct d { HRESULT hr; - list->ID3D12GraphicsCommandList3_iface.lpVtbl = &d3d12_command_list_vtbl; + list->ID3D12GraphicsCommandList5_iface.lpVtbl = &d3d12_command_list_vtbl; list->refcount = 1; list->type = type; diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c index c33061073a3..3e17400a78a 100644 --- a/libs/vkd3d/libs/vkd3d/device.c +++ b/libs/vkd3d/libs/vkd3d/device.c @@ -83,6 +83,7 @@ static const struct vkd3d_optional_extension_info optional_device_extensions[] = VK_EXTENSION(KHR_DRAW_INDIRECT_COUNT, KHR_draw_indirect_count), VK_EXTENSION(KHR_GET_MEMORY_REQUIREMENTS_2, KHR_get_memory_requirements2), VK_EXTENSION(KHR_IMAGE_FORMAT_LIST, KHR_image_format_list), + VK_EXTENSION(KHR_MAINTENANCE2, KHR_maintenance2), VK_EXTENSION(KHR_MAINTENANCE3, KHR_maintenance3), VK_EXTENSION(KHR_PUSH_DESCRIPTOR, KHR_push_descriptor), VK_EXTENSION(KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE, KHR_sampler_mirror_clamp_to_edge), @@ -2456,17 +2457,21 @@ static void vkd3d_desc_object_cache_cleanup(struct vkd3d_desc_object_cache *cach } /* ID3D12Device */ -static inline struct d3d12_device *impl_from_ID3D12Device1(ID3D12Device1 *iface) +static inline struct d3d12_device *impl_from_ID3D12Device5(ID3D12Device5 *iface) { - return CONTAINING_RECORD(iface, struct d3d12_device, ID3D12Device1_iface); + return CONTAINING_RECORD(iface, struct d3d12_device, ID3D12Device5_iface); } -static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(ID3D12Device1 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(ID3D12Device5 *iface, REFIID riid, void **object) { TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); - if (IsEqualGUID(riid, &IID_ID3D12Device1) + if (IsEqualGUID(riid, &IID_ID3D12Device5) + || IsEqualGUID(riid, &IID_ID3D12Device4) + || IsEqualGUID(riid, &IID_ID3D12Device3) + || IsEqualGUID(riid, &IID_ID3D12Device2) + || IsEqualGUID(riid, &IID_ID3D12Device1) || IsEqualGUID(riid, &IID_ID3D12Device) || IsEqualGUID(riid, &IID_ID3D12Object) || IsEqualGUID(riid, &IID_IUnknown)) @@ -2482,9 +2487,9 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(ID3D12Device1 *ifac return E_NOINTERFACE; } -static ULONG STDMETHODCALLTYPE d3d12_device_AddRef(ID3D12Device1 *iface) +static ULONG STDMETHODCALLTYPE d3d12_device_AddRef(ID3D12Device5 *iface) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); ULONG refcount = InterlockedIncrement(&device->refcount); TRACE("%p increasing refcount to %u.\n", device, refcount); @@ -2492,9 +2497,9 @@ static ULONG STDMETHODCALLTYPE d3d12_device_AddRef(ID3D12Device1 *iface) return refcount; } -static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device1 *iface) +static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device5 *iface) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); ULONG refcount = InterlockedDecrement(&device->refcount); TRACE("%p decreasing refcount to %u.\n", device, refcount); @@ -2528,10 +2533,10 @@ static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device1 *iface) return refcount; } -static HRESULT STDMETHODCALLTYPE d3d12_device_GetPrivateData(ID3D12Device1 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_device_GetPrivateData(ID3D12Device5 *iface, REFGUID guid, UINT *data_size, void *data) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data); @@ -2539,10 +2544,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_GetPrivateData(ID3D12Device1 *ifac return vkd3d_get_private_data(&device->private_store, guid, data_size, data); } -static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateData(ID3D12Device1 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateData(ID3D12Device5 *iface, REFGUID guid, UINT data_size, const void *data) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data); @@ -2550,19 +2555,19 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateData(ID3D12Device1 *ifac return vkd3d_set_private_data(&device->private_store, guid, data_size, data); } -static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateDataInterface(ID3D12Device1 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateDataInterface(ID3D12Device5 *iface, REFGUID guid, const IUnknown *data) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); return vkd3d_set_private_data_interface(&device->private_store, guid, data); } -static HRESULT STDMETHODCALLTYPE d3d12_device_SetName(ID3D12Device1 *iface, const WCHAR *name) +static HRESULT STDMETHODCALLTYPE d3d12_device_SetName(ID3D12Device5 *iface, const WCHAR *name) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); TRACE("iface %p, name %s.\n", iface, debugstr_w(name, device->wchar_size)); @@ -2570,17 +2575,17 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetName(ID3D12Device1 *iface, cons VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, name); } -static UINT STDMETHODCALLTYPE d3d12_device_GetNodeCount(ID3D12Device1 *iface) +static UINT STDMETHODCALLTYPE d3d12_device_GetNodeCount(ID3D12Device5 *iface) { TRACE("iface %p.\n", iface); return 1; } -static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandQueue(ID3D12Device1 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandQueue(ID3D12Device5 *iface, const D3D12_COMMAND_QUEUE_DESC *desc, REFIID riid, void **command_queue) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); struct d3d12_command_queue *object; HRESULT hr; @@ -2594,10 +2599,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandQueue(ID3D12Device1 * riid, command_queue); } -static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandAllocator(ID3D12Device1 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandAllocator(ID3D12Device5 *iface, D3D12_COMMAND_LIST_TYPE type, REFIID riid, void **command_allocator) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); struct d3d12_command_allocator *object; HRESULT hr; @@ -2611,10 +2616,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandAllocator(ID3D12Devic riid, command_allocator); } -static HRESULT STDMETHODCALLTYPE d3d12_device_CreateGraphicsPipelineState(ID3D12Device1 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_device_CreateGraphicsPipelineState(ID3D12Device5 *iface, const D3D12_GRAPHICS_PIPELINE_STATE_DESC *desc, REFIID riid, void **pipeline_state) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); struct d3d12_pipeline_state *object; HRESULT hr; @@ -2628,10 +2633,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateGraphicsPipelineState(ID3D12 &IID_ID3D12PipelineState, riid, pipeline_state); } -static HRESULT STDMETHODCALLTYPE d3d12_device_CreateComputePipelineState(ID3D12Device1 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_device_CreateComputePipelineState(ID3D12Device5 *iface, const D3D12_COMPUTE_PIPELINE_STATE_DESC *desc, REFIID riid, void **pipeline_state) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); struct d3d12_pipeline_state *object; HRESULT hr; @@ -2645,11 +2650,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateComputePipelineState(ID3D12D &IID_ID3D12PipelineState, riid, pipeline_state); } -static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList(ID3D12Device1 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList(ID3D12Device5 *iface, UINT node_mask, D3D12_COMMAND_LIST_TYPE type, ID3D12CommandAllocator *command_allocator, ID3D12PipelineState *initial_pipeline_state, REFIID riid, void **command_list) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); struct d3d12_command_list *object; HRESULT hr; @@ -2662,8 +2667,8 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList(ID3D12Device1 *i initial_pipeline_state, &object))) return hr; - return return_interface(&object->ID3D12GraphicsCommandList3_iface, - &IID_ID3D12GraphicsCommandList3, riid, command_list); + return return_interface(&object->ID3D12GraphicsCommandList5_iface, + &IID_ID3D12GraphicsCommandList5, riid, command_list); } /* Direct3D feature levels restrict which formats can be optionally supported. */ @@ -2772,10 +2777,10 @@ bool d3d12_device_is_uma(struct d3d12_device *device, bool *coherent) return true; } -static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device1 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device5 *iface, D3D12_FEATURE feature, void *feature_data, UINT feature_data_size) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); TRACE("iface %p, feature %#x, feature_data %p, feature_data_size %u.\n", iface, feature, feature_data, feature_data_size); @@ -3274,10 +3279,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device1 } } -static HRESULT STDMETHODCALLTYPE d3d12_device_CreateDescriptorHeap(ID3D12Device1 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_device_CreateDescriptorHeap(ID3D12Device5 *iface, const D3D12_DESCRIPTOR_HEAP_DESC *desc, REFIID riid, void **descriptor_heap) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); struct d3d12_descriptor_heap *object; HRESULT hr; @@ -3291,7 +3296,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateDescriptorHeap(ID3D12Device1 &IID_ID3D12DescriptorHeap, riid, descriptor_heap); } -static UINT STDMETHODCALLTYPE d3d12_device_GetDescriptorHandleIncrementSize(ID3D12Device1 *iface, +static UINT STDMETHODCALLTYPE d3d12_device_GetDescriptorHandleIncrementSize(ID3D12Device5 *iface, D3D12_DESCRIPTOR_HEAP_TYPE descriptor_heap_type) { TRACE("iface %p, descriptor_heap_type %#x.\n", iface, descriptor_heap_type); @@ -3314,11 +3319,11 @@ static UINT STDMETHODCALLTYPE d3d12_device_GetDescriptorHandleIncrementSize(ID3D } } -static HRESULT STDMETHODCALLTYPE d3d12_device_CreateRootSignature(ID3D12Device1 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_device_CreateRootSignature(ID3D12Device5 *iface, UINT node_mask, const void *bytecode, SIZE_T bytecode_length, REFIID riid, void **root_signature) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); struct d3d12_root_signature *object; HRESULT hr; @@ -3334,10 +3339,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateRootSignature(ID3D12Device1 &IID_ID3D12RootSignature, riid, root_signature); } -static void STDMETHODCALLTYPE d3d12_device_CreateConstantBufferView(ID3D12Device1 *iface, +static void STDMETHODCALLTYPE d3d12_device_CreateConstantBufferView(ID3D12Device5 *iface, const D3D12_CONSTANT_BUFFER_VIEW_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); struct d3d12_desc tmp = {0}; TRACE("iface %p, desc %p, descriptor %#lx.\n", iface, desc, descriptor.ptr); @@ -3346,11 +3351,11 @@ static void STDMETHODCALLTYPE d3d12_device_CreateConstantBufferView(ID3D12Device d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device); } -static void STDMETHODCALLTYPE d3d12_device_CreateShaderResourceView(ID3D12Device1 *iface, +static void STDMETHODCALLTYPE d3d12_device_CreateShaderResourceView(ID3D12Device5 *iface, ID3D12Resource *resource, const D3D12_SHADER_RESOURCE_VIEW_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); struct d3d12_desc tmp = {0}; TRACE("iface %p, resource %p, desc %p, descriptor %#lx.\n", @@ -3360,11 +3365,11 @@ static void STDMETHODCALLTYPE d3d12_device_CreateShaderResourceView(ID3D12Device d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device); } -static void STDMETHODCALLTYPE d3d12_device_CreateUnorderedAccessView(ID3D12Device1 *iface, +static void STDMETHODCALLTYPE d3d12_device_CreateUnorderedAccessView(ID3D12Device5 *iface, ID3D12Resource *resource, ID3D12Resource *counter_resource, const D3D12_UNORDERED_ACCESS_VIEW_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); struct d3d12_desc tmp = {0}; TRACE("iface %p, resource %p, counter_resource %p, desc %p, descriptor %#lx.\n", @@ -3375,7 +3380,7 @@ static void STDMETHODCALLTYPE d3d12_device_CreateUnorderedAccessView(ID3D12Devic d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device); } -static void STDMETHODCALLTYPE d3d12_device_CreateRenderTargetView(ID3D12Device1 *iface, +static void STDMETHODCALLTYPE d3d12_device_CreateRenderTargetView(ID3D12Device5 *iface, ID3D12Resource *resource, const D3D12_RENDER_TARGET_VIEW_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor) { @@ -3383,10 +3388,10 @@ static void STDMETHODCALLTYPE d3d12_device_CreateRenderTargetView(ID3D12Device1 iface, resource, desc, descriptor.ptr); d3d12_rtv_desc_create_rtv(d3d12_rtv_desc_from_cpu_handle(descriptor), - impl_from_ID3D12Device1(iface), unsafe_impl_from_ID3D12Resource(resource), desc); + impl_from_ID3D12Device5(iface), unsafe_impl_from_ID3D12Resource(resource), desc); } -static void STDMETHODCALLTYPE d3d12_device_CreateDepthStencilView(ID3D12Device1 *iface, +static void STDMETHODCALLTYPE d3d12_device_CreateDepthStencilView(ID3D12Device5 *iface, ID3D12Resource *resource, const D3D12_DEPTH_STENCIL_VIEW_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor) { @@ -3394,13 +3399,13 @@ static void STDMETHODCALLTYPE d3d12_device_CreateDepthStencilView(ID3D12Device1 iface, resource, desc, descriptor.ptr); d3d12_dsv_desc_create_dsv(d3d12_dsv_desc_from_cpu_handle(descriptor), - impl_from_ID3D12Device1(iface), unsafe_impl_from_ID3D12Resource(resource), desc); + impl_from_ID3D12Device5(iface), unsafe_impl_from_ID3D12Resource(resource), desc); } -static void STDMETHODCALLTYPE d3d12_device_CreateSampler(ID3D12Device1 *iface, +static void STDMETHODCALLTYPE d3d12_device_CreateSampler(ID3D12Device5 *iface, const D3D12_SAMPLER_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); struct d3d12_desc tmp = {0}; TRACE("iface %p, desc %p, descriptor %#lx.\n", iface, desc, descriptor.ptr); @@ -3409,14 +3414,14 @@ static void STDMETHODCALLTYPE d3d12_device_CreateSampler(ID3D12Device1 *iface, d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device); } -static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device1 *iface, +static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device5 *iface, UINT dst_descriptor_range_count, const D3D12_CPU_DESCRIPTOR_HANDLE *dst_descriptor_range_offsets, const UINT *dst_descriptor_range_sizes, UINT src_descriptor_range_count, const D3D12_CPU_DESCRIPTOR_HANDLE *src_descriptor_range_offsets, const UINT *src_descriptor_range_sizes, D3D12_DESCRIPTOR_HEAP_TYPE descriptor_heap_type) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); unsigned int dst_range_idx, dst_idx, src_range_idx, src_idx; unsigned int dst_range_size, src_range_size; struct d3d12_descriptor_heap *dst_heap; @@ -3472,7 +3477,7 @@ static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device1 *iface, } } -static void STDMETHODCALLTYPE d3d12_device_CopyDescriptorsSimple(ID3D12Device1 *iface, +static void STDMETHODCALLTYPE d3d12_device_CopyDescriptorsSimple(ID3D12Device5 *iface, UINT descriptor_count, const D3D12_CPU_DESCRIPTOR_HANDLE dst_descriptor_range_offset, const D3D12_CPU_DESCRIPTOR_HANDLE src_descriptor_range_offset, D3D12_DESCRIPTOR_HEAP_TYPE descriptor_heap_type) @@ -3487,10 +3492,10 @@ static void STDMETHODCALLTYPE d3d12_device_CopyDescriptorsSimple(ID3D12Device1 * } static D3D12_RESOURCE_ALLOCATION_INFO * STDMETHODCALLTYPE d3d12_device_GetResourceAllocationInfo( - ID3D12Device1 *iface, D3D12_RESOURCE_ALLOCATION_INFO *info, UINT visible_mask, + ID3D12Device5 *iface, D3D12_RESOURCE_ALLOCATION_INFO *info, UINT visible_mask, UINT count, const D3D12_RESOURCE_DESC *resource_descs) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); const D3D12_RESOURCE_DESC *desc; uint64_t requested_alignment; @@ -3563,10 +3568,10 @@ invalid: return info; } -static D3D12_HEAP_PROPERTIES * STDMETHODCALLTYPE d3d12_device_GetCustomHeapProperties(ID3D12Device1 *iface, +static D3D12_HEAP_PROPERTIES * STDMETHODCALLTYPE d3d12_device_GetCustomHeapProperties(ID3D12Device5 *iface, D3D12_HEAP_PROPERTIES *heap_properties, UINT node_mask, D3D12_HEAP_TYPE heap_type) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); bool coherent; TRACE("iface %p, heap_properties %p, node_mask 0x%08x, heap_type %#x.\n", @@ -3606,12 +3611,12 @@ static D3D12_HEAP_PROPERTIES * STDMETHODCALLTYPE d3d12_device_GetCustomHeapPrope return heap_properties; } -static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource(ID3D12Device1 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource(ID3D12Device5 *iface, const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags, const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state, const D3D12_CLEAR_VALUE *optimized_clear_value, REFIID iid, void **resource) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); struct d3d12_resource *object; HRESULT hr; @@ -3630,17 +3635,17 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource(ID3D12Devi return return_interface(&object->ID3D12Resource_iface, &IID_ID3D12Resource, iid, resource); } -static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap(ID3D12Device1 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap(ID3D12Device5 *iface, const D3D12_HEAP_DESC *desc, REFIID iid, void **heap) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); struct d3d12_heap *object; HRESULT hr; TRACE("iface %p, desc %p, iid %s, heap %p.\n", iface, desc, debugstr_guid(iid), heap); - if (FAILED(hr = d3d12_heap_create(device, desc, NULL, &object))) + if (FAILED(hr = d3d12_heap_create(device, desc, NULL, NULL, &object))) { *heap = NULL; return hr; @@ -3649,12 +3654,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap(ID3D12Device1 *iface, return return_interface(&object->ID3D12Heap_iface, &IID_ID3D12Heap, iid, heap); } -static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePlacedResource(ID3D12Device1 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePlacedResource(ID3D12Device5 *iface, ID3D12Heap *heap, UINT64 heap_offset, const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state, const D3D12_CLEAR_VALUE *optimized_clear_value, REFIID iid, void **resource) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); struct d3d12_heap *heap_object; struct d3d12_resource *object; HRESULT hr; @@ -3673,11 +3678,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePlacedResource(ID3D12Device1 return return_interface(&object->ID3D12Resource_iface, &IID_ID3D12Resource, iid, resource); } -static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource(ID3D12Device1 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource(ID3D12Device5 *iface, const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state, const D3D12_CLEAR_VALUE *optimized_clear_value, REFIID iid, void **resource) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); struct d3d12_resource *object; HRESULT hr; @@ -3691,11 +3696,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource(ID3D12Devic return return_interface(&object->ID3D12Resource_iface, &IID_ID3D12Resource, iid, resource); } -static HRESULT STDMETHODCALLTYPE d3d12_device_CreateSharedHandle(ID3D12Device1 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_device_CreateSharedHandle(ID3D12Device5 *iface, ID3D12DeviceChild *object, const SECURITY_ATTRIBUTES *attributes, DWORD access, const WCHAR *name, HANDLE *handle) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); FIXME("iface %p, object %p, attributes %p, access %#x, name %s, handle %p stub!\n", iface, object, attributes, access, debugstr_w(name, device->wchar_size), handle); @@ -3703,7 +3708,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateSharedHandle(ID3D12Device1 * return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandle(ID3D12Device1 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandle(ID3D12Device5 *iface, HANDLE handle, REFIID riid, void **object) { FIXME("iface %p, handle %p, riid %s, object %p stub!\n", @@ -3712,10 +3717,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandle(ID3D12Device1 *if return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandleByName(ID3D12Device1 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandleByName(ID3D12Device5 *iface, const WCHAR *name, DWORD access, HANDLE *handle) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); FIXME("iface %p, name %s, access %#x, handle %p stub!\n", iface, debugstr_w(name, device->wchar_size), access, handle); @@ -3723,7 +3728,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandleByName(ID3D12Devic return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE d3d12_device_MakeResident(ID3D12Device1 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_device_MakeResident(ID3D12Device5 *iface, UINT object_count, ID3D12Pageable * const *objects) { FIXME_ONCE("iface %p, object_count %u, objects %p stub!\n", @@ -3732,7 +3737,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_MakeResident(ID3D12Device1 *iface, return S_OK; } -static HRESULT STDMETHODCALLTYPE d3d12_device_Evict(ID3D12Device1 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_device_Evict(ID3D12Device5 *iface, UINT object_count, ID3D12Pageable * const *objects) { FIXME_ONCE("iface %p, object_count %u, objects %p stub!\n", @@ -3741,10 +3746,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_Evict(ID3D12Device1 *iface, return S_OK; } -static HRESULT STDMETHODCALLTYPE d3d12_device_CreateFence(ID3D12Device1 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_device_CreateFence(ID3D12Device5 *iface, UINT64 initial_value, D3D12_FENCE_FLAGS flags, REFIID riid, void **fence) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); struct d3d12_fence *object; HRESULT hr; @@ -3757,21 +3762,21 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateFence(ID3D12Device1 *iface, return return_interface(&object->ID3D12Fence1_iface, &IID_ID3D12Fence1, riid, fence); } -static HRESULT STDMETHODCALLTYPE d3d12_device_GetDeviceRemovedReason(ID3D12Device1 *iface) +static HRESULT STDMETHODCALLTYPE d3d12_device_GetDeviceRemovedReason(ID3D12Device5 *iface) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); TRACE("iface %p.\n", iface); return device->removed_reason; } -static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(ID3D12Device1 *iface, +static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(ID3D12Device5 *iface, const D3D12_RESOURCE_DESC *desc, UINT first_sub_resource, UINT sub_resource_count, UINT64 base_offset, D3D12_PLACED_SUBRESOURCE_FOOTPRINT *layouts, UINT *row_counts, UINT64 *row_sizes, UINT64 *total_bytes) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); unsigned int i, sub_resource_idx, miplevel_idx, row_count, row_size, row_pitch; unsigned int width, height, depth, plane_count, sub_resources_per_plane; @@ -3851,10 +3856,10 @@ static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(ID3D12Device1 * *total_bytes = total; } -static HRESULT STDMETHODCALLTYPE d3d12_device_CreateQueryHeap(ID3D12Device1 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_device_CreateQueryHeap(ID3D12Device5 *iface, const D3D12_QUERY_HEAP_DESC *desc, REFIID iid, void **heap) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); struct d3d12_query_heap *object; HRESULT hr; @@ -3867,18 +3872,18 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateQueryHeap(ID3D12Device1 *ifa return return_interface(&object->ID3D12QueryHeap_iface, &IID_ID3D12QueryHeap, iid, heap); } -static HRESULT STDMETHODCALLTYPE d3d12_device_SetStablePowerState(ID3D12Device1 *iface, BOOL enable) +static HRESULT STDMETHODCALLTYPE d3d12_device_SetStablePowerState(ID3D12Device5 *iface, BOOL enable) { FIXME("iface %p, enable %#x stub!\n", iface, enable); return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandSignature(ID3D12Device1 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandSignature(ID3D12Device5 *iface, const D3D12_COMMAND_SIGNATURE_DESC *desc, ID3D12RootSignature *root_signature, REFIID iid, void **command_signature) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); struct d3d12_command_signature *object; HRESULT hr; @@ -3892,14 +3897,14 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandSignature(ID3D12Devic &IID_ID3D12CommandSignature, iid, command_signature); } -static void STDMETHODCALLTYPE d3d12_device_GetResourceTiling(ID3D12Device1 *iface, +static void STDMETHODCALLTYPE d3d12_device_GetResourceTiling(ID3D12Device5 *iface, ID3D12Resource *resource, UINT *total_tile_count, D3D12_PACKED_MIP_INFO *packed_mip_info, D3D12_TILE_SHAPE *standard_tile_shape, UINT *sub_resource_tiling_count, UINT first_sub_resource_tiling, D3D12_SUBRESOURCE_TILING *sub_resource_tilings) { const struct d3d12_resource *resource_impl = impl_from_ID3D12Resource(resource); - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); TRACE("iface %p, resource %p, total_tile_count %p, packed_mip_info %p, " "standard_title_shape %p, sub_resource_tiling_count %p, " @@ -3912,9 +3917,9 @@ static void STDMETHODCALLTYPE d3d12_device_GetResourceTiling(ID3D12Device1 *ifac sub_resource_tiling_count, first_sub_resource_tiling, sub_resource_tilings); } -static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device1 *iface, LUID *luid) +static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device5 *iface, LUID *luid) { - struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_device *device = impl_from_ID3D12Device5(iface); TRACE("iface %p, luid %p.\n", iface, luid); @@ -3923,7 +3928,7 @@ static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device1 *iface return luid; } -static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineLibrary(ID3D12Device1 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineLibrary(ID3D12Device5 *iface, const void *blob, SIZE_T blob_size, REFIID iid, void **lib) { FIXME("iface %p, blob %p, blob_size %lu, iid %s, lib %p stub!\n", iface, blob, blob_size, debugstr_guid(iid), lib); @@ -3931,7 +3936,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineLibrary(ID3D12Device return DXGI_ERROR_UNSUPPORTED; } -static HRESULT STDMETHODCALLTYPE d3d12_device_SetEventOnMultipleFenceCompletion(ID3D12Device1 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_device_SetEventOnMultipleFenceCompletion(ID3D12Device5 *iface, ID3D12Fence *const *fences, const UINT64 *values, UINT fence_count, D3D12_MULTIPLE_FENCE_WAIT_FLAGS flags, HANDLE event) { @@ -3941,7 +3946,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetEventOnMultipleFenceCompletion( return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE d3d12_device_SetResidencyPriority(ID3D12Device1 *iface, +static HRESULT STDMETHODCALLTYPE d3d12_device_SetResidencyPriority(ID3D12Device5 *iface, UINT object_count, ID3D12Pageable *const *objects, const D3D12_RESIDENCY_PRIORITY *priorities) { FIXME_ONCE("iface %p, object_count %u, objects %p, priorities %p stub!\n", iface, object_count, objects, priorities); @@ -3949,7 +3954,186 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetResidencyPriority(ID3D12Device1 return S_OK; } -static const struct ID3D12Device1Vtbl d3d12_device_vtbl = +static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineState(ID3D12Device5 *iface, + const D3D12_PIPELINE_STATE_STREAM_DESC *desc, REFIID iid, void **pipeline_state) +{ + FIXME("iface %p, desc %p, iid %s, pipeline_state %p stub!\n", iface, desc, debugstr_guid(iid), pipeline_state); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_device_OpenExistingHeapFromAddress(ID3D12Device5 *iface, + const void *address, REFIID iid, void **heap) +{ + FIXME("iface %p, address %p, iid %s, heap %p stub!\n", iface, address, debugstr_guid(iid), heap); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_device_OpenExistingHeapFromFileMapping(ID3D12Device5 *iface, + HANDLE file_mapping, REFIID iid, void **heap) +{ + FIXME("iface %p, file_mapping %p, iid %s, heap %p stub!\n", iface, file_mapping, debugstr_guid(iid), heap); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_device_EnqueueMakeResident(ID3D12Device5 *iface, + D3D12_RESIDENCY_FLAGS flags, UINT num_objects, ID3D12Pageable *const *objects, + ID3D12Fence *fence, UINT64 fence_value) +{ + FIXME("iface %p, flags %#x, num_objects %u, objects %p, fence %p, fence_value %#"PRIx64" stub!\n", + iface, flags, num_objects, objects, fence, fence_value); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList1(ID3D12Device5 *iface, + UINT node_mask, D3D12_COMMAND_LIST_TYPE type, D3D12_COMMAND_LIST_FLAGS flags, + REFIID iid, void **command_list) +{ + FIXME("iface %p, node_mask 0x%08x, type %#x, flags %#x, iid %s, command_list %p stub!\n", + iface, node_mask, type, flags, debugstr_guid(iid), command_list); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_device_CreateProtectedResourceSession(ID3D12Device5 *iface, + const D3D12_PROTECTED_RESOURCE_SESSION_DESC *desc, REFIID iid, void **session) +{ + FIXME("iface %p, desc %p, iid %s, session %p stub!\n", iface, desc, debugstr_guid(iid), session); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource1(ID3D12Device5 *iface, + const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags, + const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state, + const D3D12_CLEAR_VALUE *optimized_clear_value, + ID3D12ProtectedResourceSession *protected_session, REFIID iid, void **resource) +{ + FIXME("iface %p, heap_properties %p, heap_flags %#x, desc %p, initial_state %#x, " + "optimized_clear_value %p, protected_session %p, iid %s, resource %p stub!\n", + iface, heap_properties, heap_flags, desc, initial_state, + optimized_clear_value, protected_session, debugstr_guid(iid), resource); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap1(ID3D12Device5 *iface, + const D3D12_HEAP_DESC *desc, ID3D12ProtectedResourceSession *protected_session, + REFIID iid, void **heap) +{ + struct d3d12_device *device = impl_from_ID3D12Device5(iface); + struct d3d12_heap *object; + HRESULT hr; + + TRACE("iface %p, desc %p, protected_session %p, iid %s, heap %p.\n", + iface, desc, protected_session, debugstr_guid(iid), heap); + + if (FAILED(hr = d3d12_heap_create(device, desc, NULL, protected_session, &object))) + { + *heap = NULL; + return hr; + } + + return return_interface(&object->ID3D12Heap_iface, &IID_ID3D12Heap, iid, heap); +} + +static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource1(ID3D12Device5 *iface, + const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state, + const D3D12_CLEAR_VALUE *optimized_clear_value, + ID3D12ProtectedResourceSession *protected_session, REFIID iid, void **resource) +{ + FIXME("iface %p, desc %p, initial_state %#x, optimized_clear_value %p, " + "protected_session %p, iid %s, resource %p stub!\n", + iface, desc, initial_state, optimized_clear_value, protected_session, + debugstr_guid(iid), resource); + + return E_NOTIMPL; +} + +static D3D12_RESOURCE_ALLOCATION_INFO * STDMETHODCALLTYPE d3d12_device_GetResourceAllocationInfo1( + ID3D12Device5 *iface, D3D12_RESOURCE_ALLOCATION_INFO *info, UINT visible_mask, + UINT count, const D3D12_RESOURCE_DESC *resource_descs, + D3D12_RESOURCE_ALLOCATION_INFO1 *info1) +{ + FIXME("iface %p, info %p, visible_mask 0x%08x, count %u, resource_descs %p, info1 %p stub!\n", + iface, info, visible_mask, count, resource_descs, info1); + + return info; +} + +static HRESULT STDMETHODCALLTYPE d3d12_device_CreateLifetimeTracker(ID3D12Device5 *iface, + ID3D12LifetimeOwner *owner, REFIID iid, void **tracker) +{ + FIXME("iface %p, owner %p, iid %s, tracker %p stub!\n", iface, owner, debugstr_guid(iid), tracker); + + return E_NOTIMPL; +} + +static void STDMETHODCALLTYPE d3d12_device_RemoveDevice(ID3D12Device5 *iface) +{ + FIXME("iface %p stub!\n", iface); +} + +static HRESULT STDMETHODCALLTYPE d3d12_device_EnumerateMetaCommands(ID3D12Device5 *iface, + UINT *num_meta_commands, D3D12_META_COMMAND_DESC *command_desc) +{ + FIXME("iface %p, num_meta_commands %p, command_desc %p stub!\n", iface, + num_meta_commands, command_desc); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_device_EnumerateMetaCommandParameters(ID3D12Device5 *iface, + REFGUID command_id, D3D12_META_COMMAND_PARAMETER_STAGE stage, + UINT *size_in_bytes, UINT *parameter_count, + D3D12_META_COMMAND_PARAMETER_DESC *parameter_desc) +{ + FIXME("iface %p, command_id %s, stage %u, size_in_bytes %p, " + "parameter_count %p, parameter_desc %p stub!\n", iface, + debugstr_guid(command_id), stage, size_in_bytes, parameter_count, parameter_desc); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_device_CreateMetaCommand(ID3D12Device5 *iface, + REFGUID command_id, UINT node_mask, const void *parameters_data, + SIZE_T data_size_in_bytes, REFIID iid, void **meta_command) +{ + FIXME("iface %p, command_id %s, node_mask %#x, parameters_data %p, " + "data_size_in_bytes %lu, iid %s, meta_command %p stub!\n", iface, + debugstr_guid(command_id), node_mask, parameters_data, + data_size_in_bytes, debugstr_guid(iid), meta_command); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_device_CreateStateObject(ID3D12Device5 *iface, + const D3D12_STATE_OBJECT_DESC *desc, REFIID iid, void **state_object) +{ + FIXME("iface %p, desc %p, iid %s, state_object %p stub!\n", iface, desc, debugstr_guid(iid), state_object); + + return E_NOTIMPL; +} + +static void STDMETHODCALLTYPE d3d12_device_GetRaytracingAccelerationStructurePrebuildInfo(ID3D12Device5 *iface, + const D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS *desc, + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO *info) +{ + FIXME("iface %p, desc %p, info %p stub!\n", iface, desc, info); +} + +static D3D12_DRIVER_MATCHING_IDENTIFIER_STATUS STDMETHODCALLTYPE d3d12_device_CheckDriverMatchingIdentifier(ID3D12Device5 *iface, + D3D12_SERIALIZED_DATA_TYPE data_type, const D3D12_SERIALIZED_DATA_DRIVER_MATCHING_IDENTIFIER *identifier) +{ + FIXME("iface %p, data_type %u, identifier %p stub!\n", iface, data_type, identifier); + + return D3D12_DRIVER_MATCHING_IDENTIFIER_UNRECOGNIZED; +} + +static const struct ID3D12Device5Vtbl d3d12_device_vtbl = { /* IUnknown methods */ d3d12_device_QueryInterface, @@ -4002,14 +4186,36 @@ static const struct ID3D12Device1Vtbl d3d12_device_vtbl = d3d12_device_CreatePipelineLibrary, d3d12_device_SetEventOnMultipleFenceCompletion, d3d12_device_SetResidencyPriority, + /* ID3D12Device2 methods */ + d3d12_device_CreatePipelineState, + /* ID3D12Device3 methods */ + d3d12_device_OpenExistingHeapFromAddress, + d3d12_device_OpenExistingHeapFromFileMapping, + d3d12_device_EnqueueMakeResident, + /* ID3D12Device4 methods */ + d3d12_device_CreateCommandList1, + d3d12_device_CreateProtectedResourceSession, + d3d12_device_CreateCommittedResource1, + d3d12_device_CreateHeap1, + d3d12_device_CreateReservedResource1, + d3d12_device_GetResourceAllocationInfo1, + /* ID3D12Device5 methods */ + d3d12_device_CreateLifetimeTracker, + d3d12_device_RemoveDevice, + d3d12_device_EnumerateMetaCommands, + d3d12_device_EnumerateMetaCommandParameters, + d3d12_device_CreateMetaCommand, + d3d12_device_CreateStateObject, + d3d12_device_GetRaytracingAccelerationStructurePrebuildInfo, + d3d12_device_CheckDriverMatchingIdentifier, }; -struct d3d12_device *unsafe_impl_from_ID3D12Device1(ID3D12Device1 *iface) +struct d3d12_device *unsafe_impl_from_ID3D12Device5(ID3D12Device5 *iface) { if (!iface) return NULL; assert(iface->lpVtbl == &d3d12_device_vtbl); - return impl_from_ID3D12Device1(iface); + return impl_from_ID3D12Device5(iface); } static HRESULT d3d12_device_init(struct d3d12_device *device, @@ -4018,7 +4224,7 @@ static HRESULT d3d12_device_init(struct d3d12_device *device, const struct vkd3d_vk_device_procs *vk_procs; HRESULT hr; - device->ID3D12Device1_iface.lpVtbl = &d3d12_device_vtbl; + device->ID3D12Device5_iface.lpVtbl = &d3d12_device_vtbl; device->refcount = 1; vkd3d_instance_incref(device->vkd3d_instance = instance); @@ -4215,28 +4421,28 @@ HRESULT vkd3d_join_thread(struct vkd3d_instance *instance, union vkd3d_thread_ha IUnknown *vkd3d_get_device_parent(ID3D12Device *device) { - struct d3d12_device *d3d12_device = impl_from_ID3D12Device1((ID3D12Device1 *)device); + struct d3d12_device *d3d12_device = impl_from_ID3D12Device5((ID3D12Device5 *)device); return d3d12_device->parent; } VkDevice vkd3d_get_vk_device(ID3D12Device *device) { - struct d3d12_device *d3d12_device = impl_from_ID3D12Device1((ID3D12Device1 *)device); + struct d3d12_device *d3d12_device = impl_from_ID3D12Device5((ID3D12Device5 *)device); return d3d12_device->vk_device; } VkPhysicalDevice vkd3d_get_vk_physical_device(ID3D12Device *device) { - struct d3d12_device *d3d12_device = impl_from_ID3D12Device1((ID3D12Device1 *)device); + struct d3d12_device *d3d12_device = impl_from_ID3D12Device5((ID3D12Device5 *)device); return d3d12_device->vk_physical_device; } struct vkd3d_instance *vkd3d_instance_from_device(ID3D12Device *device) { - struct d3d12_device *d3d12_device = impl_from_ID3D12Device1((ID3D12Device1 *)device); + struct d3d12_device *d3d12_device = impl_from_ID3D12Device5((ID3D12Device5 *)device); return d3d12_device->vkd3d_instance; } diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c index f3842958d96..ad1d2d66692 100644 --- a/libs/vkd3d/libs/vkd3d/resource.c +++ b/libs/vkd3d/libs/vkd3d/resource.c @@ -574,11 +574,15 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap, } HRESULT d3d12_heap_create(struct d3d12_device *device, const D3D12_HEAP_DESC *desc, - const struct d3d12_resource *resource, struct d3d12_heap **heap) + const struct d3d12_resource *resource, ID3D12ProtectedResourceSession *protected_session, + struct d3d12_heap **heap) { struct d3d12_heap *object; HRESULT hr; + if (protected_session) + FIXME("Protected session is not supported.\n"); + if (!(object = vkd3d_malloc(sizeof(*object)))) return E_OUTOFMEMORY; @@ -2064,7 +2068,7 @@ static HRESULT vkd3d_allocate_resource_memory( heap_desc.Properties = *heap_properties; heap_desc.Alignment = 0; heap_desc.Flags = heap_flags; - if (SUCCEEDED(hr = d3d12_heap_create(device, &heap_desc, resource, &resource->heap))) + if (SUCCEEDED(hr = d3d12_heap_create(device, &heap_desc, resource, NULL, &resource->heap))) resource->flags |= VKD3D_RESOURCE_DEDICATED_HEAP; return hr; } @@ -2220,7 +2224,7 @@ HRESULT d3d12_reserved_resource_create(struct d3d12_device *device, HRESULT vkd3d_create_image_resource(ID3D12Device *device, const struct vkd3d_image_resource_create_info *create_info, ID3D12Resource **resource) { - struct d3d12_device *d3d12_device = unsafe_impl_from_ID3D12Device1((ID3D12Device1 *)device); + struct d3d12_device *d3d12_device = unsafe_impl_from_ID3D12Device5((ID3D12Device5 *)device); struct d3d12_resource *object; HRESULT hr; @@ -2998,6 +3002,7 @@ static bool init_default_texture_view_desc(struct vkd3d_texture_view_desc *desc, desc->components.b = VK_COMPONENT_SWIZZLE_IDENTITY; desc->components.a = VK_COMPONENT_SWIZZLE_IDENTITY; desc->allowed_swizzle = false; + desc->usage = 0; return true; } @@ -3039,6 +3044,7 @@ bool vkd3d_create_texture_view(struct d3d12_device *device, uint32_t magic, VkIm { const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; const struct vkd3d_format *format = desc->format; + VkImageViewUsageCreateInfoKHR usage_desc; struct VkImageViewCreateInfo view_desc; VkImageView vk_view = VK_NULL_HANDLE; struct vkd3d_view *object; @@ -3060,6 +3066,13 @@ bool vkd3d_create_texture_view(struct d3d12_device *device, uint32_t magic, VkIm view_desc.subresourceRange.levelCount = desc->miplevel_count; view_desc.subresourceRange.baseArrayLayer = desc->layer_idx; view_desc.subresourceRange.layerCount = desc->layer_count; + if (device->vk_info.KHR_maintenance2) + { + usage_desc.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO; + usage_desc.pNext = NULL; + usage_desc.usage = desc->usage; + view_desc.pNext = &usage_desc; + } if ((vr = VK_CALL(vkCreateImageView(device->vk_device, &view_desc, NULL, &vk_view))) < 0) { WARN("Failed to create Vulkan image view, vr %d.\n", vr); @@ -3196,6 +3209,7 @@ static void vkd3d_create_null_srv(struct d3d12_desc *descriptor, vkd3d_desc.components.b = VK_COMPONENT_SWIZZLE_ZERO; vkd3d_desc.components.a = VK_COMPONENT_SWIZZLE_ZERO; vkd3d_desc.allowed_swizzle = true; + vkd3d_desc.usage = VK_IMAGE_USAGE_SAMPLED_BIT; vkd3d_create_texture_view(device, VKD3D_DESCRIPTOR_MAGIC_SRV, vk_image, &vkd3d_desc, &descriptor->s.u.view); } @@ -3268,6 +3282,7 @@ void d3d12_desc_create_srv(struct d3d12_desc *descriptor, vkd3d_desc.miplevel_count = VK_REMAINING_MIP_LEVELS; vkd3d_desc.allowed_swizzle = true; + vkd3d_desc.usage = VK_IMAGE_USAGE_SAMPLED_BIT; if (desc) { @@ -3421,6 +3436,7 @@ static void vkd3d_create_null_uav(struct d3d12_desc *descriptor, vkd3d_desc.components.b = VK_COMPONENT_SWIZZLE_B; vkd3d_desc.components.a = VK_COMPONENT_SWIZZLE_A; vkd3d_desc.allowed_swizzle = false; + vkd3d_desc.usage = VK_IMAGE_USAGE_STORAGE_BIT; vkd3d_create_texture_view(device, VKD3D_DESCRIPTOR_MAGIC_UAV, vk_image, &vkd3d_desc, &descriptor->s.u.view); } @@ -3480,6 +3496,8 @@ static void vkd3d_create_texture_uav(struct d3d12_desc *descriptor, if (!init_default_texture_view_desc(&vkd3d_desc, resource, desc ? desc->Format : 0)) return; + vkd3d_desc.usage = VK_IMAGE_USAGE_STORAGE_BIT; + if (vkd3d_format_is_compressed(vkd3d_desc.format)) { WARN("UAVs cannot be created for compressed formats.\n"); @@ -3747,6 +3765,8 @@ void d3d12_rtv_desc_create_rtv(struct d3d12_rtv_desc *rtv_desc, struct d3d12_dev if (!init_default_texture_view_desc(&vkd3d_desc, resource, desc ? desc->Format : 0)) return; + vkd3d_desc.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + if (vkd3d_desc.format->vk_aspect_mask != VK_IMAGE_ASPECT_COLOR_BIT) { WARN("Trying to create RTV for depth/stencil format %#x.\n", vkd3d_desc.format->dxgi_format); @@ -3847,6 +3867,8 @@ void d3d12_dsv_desc_create_dsv(struct d3d12_dsv_desc *dsv_desc, struct d3d12_dev if (!init_default_texture_view_desc(&vkd3d_desc, resource, desc ? desc->Format : 0)) return; + vkd3d_desc.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + if (!(vkd3d_desc.format->vk_aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))) { WARN("Trying to create DSV for format %#x.\n", vkd3d_desc.format->dxgi_format); diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_main.c b/libs/vkd3d/libs/vkd3d/vkd3d_main.c index 159560afd8e..245edb5aeac 100644 --- a/libs/vkd3d/libs/vkd3d/vkd3d_main.c +++ b/libs/vkd3d/libs/vkd3d/vkd3d_main.c @@ -71,11 +71,11 @@ HRESULT vkd3d_create_device(const struct vkd3d_device_create_info *create_info, if (!device) { - ID3D12Device_Release(&object->ID3D12Device1_iface); + ID3D12Device_Release(&object->ID3D12Device5_iface); return S_FALSE; } - return return_interface(&object->ID3D12Device1_iface, &IID_ID3D12Device, iid, device); + return return_interface(&object->ID3D12Device5_iface, &IID_ID3D12Device, iid, device); } /* ID3D12RootSignatureDeserializer */ diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h index 363a7132c3a..625a43125c9 100644 --- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h @@ -22,6 +22,7 @@ #define COBJMACROS #define NONAMELESSUNION #define VK_NO_PROTOTYPES +#define CONST_VTABLE #ifdef _WIN32 # define _WIN32_WINNT 0x0600 /* for condition variables */ @@ -31,8 +32,8 @@ #include "vkd3d_blob.h" #include "vkd3d_memory.h" #include "vkd3d_utf8.h" -#include "wine/list.h" -#include "wine/rbtree.h" +#include "list.h" +#include "rbtree.h" #include "vkd3d.h" #include "vkd3d_shader.h" @@ -121,6 +122,7 @@ struct vkd3d_vulkan_info bool KHR_draw_indirect_count; bool KHR_get_memory_requirements2; bool KHR_image_format_list; + bool KHR_maintenance2; bool KHR_maintenance3; bool KHR_push_descriptor; bool KHR_sampler_mirror_clamp_to_edge; @@ -680,7 +682,7 @@ struct d3d12_heap }; HRESULT d3d12_heap_create(struct d3d12_device *device, const D3D12_HEAP_DESC *desc, - const struct d3d12_resource *resource, struct d3d12_heap **heap); + const struct d3d12_resource *resource, ID3D12ProtectedResourceSession *protected_session, struct d3d12_heap **heap); struct d3d12_heap *unsafe_impl_from_ID3D12Heap(ID3D12Heap *iface); #define VKD3D_RESOURCE_PUBLIC_FLAGS \ @@ -835,6 +837,7 @@ struct vkd3d_texture_view_desc VkImageAspectFlags vk_image_aspect; VkComponentMapping components; bool allowed_swizzle; + VkImageUsageFlags usage; }; struct vkd3d_desc_header @@ -1426,7 +1429,7 @@ enum vkd3d_pipeline_bind_point /* ID3D12CommandList */ struct d3d12_command_list { - ID3D12GraphicsCommandList3 ID3D12GraphicsCommandList3_iface; + ID3D12GraphicsCommandList5 ID3D12GraphicsCommandList5_iface; LONG refcount; D3D12_COMMAND_LIST_TYPE type; @@ -1709,7 +1712,7 @@ struct vkd3d_desc_object_cache /* ID3D12Device */ struct d3d12_device { - ID3D12Device1 ID3D12Device1_iface; + ID3D12Device5 ID3D12Device5_iface; LONG refcount; VkDevice vk_device; @@ -1775,27 +1778,27 @@ struct vkd3d_queue *d3d12_device_get_vkd3d_queue(struct d3d12_device *device, D3 bool d3d12_device_is_uma(struct d3d12_device *device, bool *coherent); void d3d12_device_mark_as_removed(struct d3d12_device *device, HRESULT reason, const char *message, ...) VKD3D_PRINTF_FUNC(3, 4); -struct d3d12_device *unsafe_impl_from_ID3D12Device1(ID3D12Device1 *iface); +struct d3d12_device *unsafe_impl_from_ID3D12Device5(ID3D12Device5 *iface); static inline HRESULT d3d12_device_query_interface(struct d3d12_device *device, REFIID iid, void **object) { - return ID3D12Device1_QueryInterface(&device->ID3D12Device1_iface, iid, object); + return ID3D12Device5_QueryInterface(&device->ID3D12Device5_iface, iid, object); } static inline ULONG d3d12_device_add_ref(struct d3d12_device *device) { - return ID3D12Device1_AddRef(&device->ID3D12Device1_iface); + return ID3D12Device5_AddRef(&device->ID3D12Device5_iface); } static inline ULONG d3d12_device_release(struct d3d12_device *device) { - return ID3D12Device1_Release(&device->ID3D12Device1_iface); + return ID3D12Device5_Release(&device->ID3D12Device5_iface); } static inline unsigned int d3d12_device_get_descriptor_handle_increment_size(struct d3d12_device *device, D3D12_DESCRIPTOR_HEAP_TYPE descriptor_type) { - return ID3D12Device1_GetDescriptorHandleIncrementSize(&device->ID3D12Device1_iface, descriptor_type); + return ID3D12Device5_GetDescriptorHandleIncrementSize(&device->ID3D12Device5_iface, descriptor_type); } /* utils */ -- 2.42.0