2 * Copyright 2018 Henri Verbeet for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "wine/port.h"
21 #include "wined3d_private.h"
23 #include "wine/vulkan_driver.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(d3d
);
27 static const struct wined3d_state_entry_template misc_state_template_vk
[] =
29 {STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX
), {STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX
), state_nop
}},
30 {STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_HULL
), {STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_HULL
), state_nop
}},
31 {STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_DOMAIN
), {STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_DOMAIN
), state_nop
}},
32 {STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_GEOMETRY
), {STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_GEOMETRY
), state_nop
}},
33 {STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL
), {STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL
), state_nop
}},
34 {STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_COMPUTE
), {STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_COMPUTE
), state_nop
}},
35 {STATE_GRAPHICS_SHADER_RESOURCE_BINDING
, {STATE_GRAPHICS_SHADER_RESOURCE_BINDING
, state_nop
}},
36 {STATE_GRAPHICS_UNORDERED_ACCESS_VIEW_BINDING
, {STATE_GRAPHICS_UNORDERED_ACCESS_VIEW_BINDING
, state_nop
}},
37 {STATE_COMPUTE_SHADER_RESOURCE_BINDING
, {STATE_COMPUTE_SHADER_RESOURCE_BINDING
, state_nop
}},
38 {STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING
, {STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING
, state_nop
}},
39 {STATE_STREAM_OUTPUT
, {STATE_STREAM_OUTPUT
, state_nop
}},
40 {STATE_BLEND
, {STATE_BLEND
, state_nop
}},
41 {STATE_BLEND_FACTOR
, {STATE_BLEND_FACTOR
, state_nop
}},
42 {STATE_STREAMSRC
, {STATE_STREAMSRC
, state_nop
}},
43 {STATE_VDECL
, {STATE_VDECL
, state_nop
}},
44 {STATE_RASTERIZER
, {STATE_RASTERIZER
, state_nop
}},
45 {STATE_SCISSORRECT
, {STATE_SCISSORRECT
, state_nop
}},
46 {STATE_POINTSPRITECOORDORIGIN
, {STATE_POINTSPRITECOORDORIGIN
, state_nop
}},
48 {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00
), {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00
), state_nop
}},
49 {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT01
), {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00
)}},
50 {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT10
), {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00
)}},
51 {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT11
), {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00
)}},
52 {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00
), {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00
), state_nop
}},
53 {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT01
), {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00
)}},
54 {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT10
), {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00
)}},
55 {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT11
), {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00
)}},
56 {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00
), {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00
), state_nop
}},
57 {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT01
), {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00
)}},
58 {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT10
), {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00
)}},
59 {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT11
), {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00
)}},
60 {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00
), {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00
), state_nop
}},
61 {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT01
), {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00
)}},
62 {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT10
), {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00
)}},
63 {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT11
), {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00
)}},
64 {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00
), {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00
), state_nop
}},
65 {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT01
), {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00
)}},
66 {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT10
), {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00
)}},
67 {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT11
), {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00
)}},
68 {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00
), {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00
), state_nop
}},
69 {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT01
), {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00
)}},
70 {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT10
), {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00
)}},
71 {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT11
), {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00
)}},
72 {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00
), {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00
), state_nop
}},
73 {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT01
), {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00
)}},
74 {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT10
), {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00
)}},
75 {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT11
), {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00
)}},
76 {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00
), {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00
), state_nop
}},
77 {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT01
), {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00
)}},
78 {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT10
), {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00
)}},
79 {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT11
), {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00
)}},
80 {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE
), {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE
), state_nop
}},
81 {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LOFFSET
), {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE
)}},
82 {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE
), {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE
), state_nop
}},
83 {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LOFFSET
), {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE
)}},
84 {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE
), {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE
), state_nop
}},
85 {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LOFFSET
), {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE
)}},
86 {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE
), {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE
), state_nop
}},
87 {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LOFFSET
), {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE
)}},
88 {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE
), {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE
), state_nop
}},
89 {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LOFFSET
), {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE
)}},
90 {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE
), {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE
), state_nop
}},
91 {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LOFFSET
), {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE
)}},
92 {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE
), {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE
), state_nop
}},
93 {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LOFFSET
), {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE
)}},
94 {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE
), {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE
), state_nop
}},
95 {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LOFFSET
), {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE
)}},
97 {STATE_VIEWPORT
, {STATE_VIEWPORT
, state_nop
}},
98 {STATE_INDEXBUFFER
, {STATE_INDEXBUFFER
, state_nop
}},
99 {STATE_RENDER(WINED3D_RS_ANTIALIAS
), {STATE_RENDER(WINED3D_RS_ANTIALIAS
), state_nop
}},
100 {STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE
), {STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE
), state_nop
}},
101 {STATE_RENDER(WINED3D_RS_ZENABLE
), {STATE_RENDER(WINED3D_RS_ZENABLE
), state_nop
}},
102 {STATE_RENDER(WINED3D_RS_WRAPU
), {STATE_RENDER(WINED3D_RS_WRAPU
), state_nop
}},
103 {STATE_RENDER(WINED3D_RS_WRAPV
), {STATE_RENDER(WINED3D_RS_WRAPV
), state_nop
}},
104 {STATE_RENDER(WINED3D_RS_LINEPATTERN
), {STATE_RENDER(WINED3D_RS_LINEPATTERN
), state_nop
}},
105 {STATE_RENDER(WINED3D_RS_MONOENABLE
), {STATE_RENDER(WINED3D_RS_MONOENABLE
), state_nop
}},
106 {STATE_RENDER(WINED3D_RS_ROP2
), {STATE_RENDER(WINED3D_RS_ROP2
), state_nop
}},
107 {STATE_RENDER(WINED3D_RS_PLANEMASK
), {STATE_RENDER(WINED3D_RS_PLANEMASK
), state_nop
}},
108 {STATE_RENDER(WINED3D_RS_ZWRITEENABLE
), {STATE_RENDER(WINED3D_RS_ZENABLE
)}},
109 {STATE_RENDER(WINED3D_RS_LASTPIXEL
), {STATE_RENDER(WINED3D_RS_LASTPIXEL
), state_nop
}},
110 {STATE_RENDER(WINED3D_RS_ZFUNC
), {STATE_RENDER(WINED3D_RS_ZENABLE
)}},
111 {STATE_RENDER(WINED3D_RS_DITHERENABLE
), {STATE_RENDER(WINED3D_RS_DITHERENABLE
), state_nop
}},
112 {STATE_RENDER(WINED3D_RS_SUBPIXEL
), {STATE_RENDER(WINED3D_RS_SUBPIXEL
), state_nop
}},
113 {STATE_RENDER(WINED3D_RS_SUBPIXELX
), {STATE_RENDER(WINED3D_RS_SUBPIXELX
), state_nop
}},
114 {STATE_RENDER(WINED3D_RS_STIPPLEDALPHA
), {STATE_RENDER(WINED3D_RS_STIPPLEDALPHA
), state_nop
}},
115 {STATE_RENDER(WINED3D_RS_STIPPLEENABLE
), {STATE_RENDER(WINED3D_RS_STIPPLEENABLE
), state_nop
}},
116 {STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS
), {STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS
), state_nop
}},
117 {STATE_RENDER(WINED3D_RS_ANISOTROPY
), {STATE_RENDER(WINED3D_RS_ANISOTROPY
), state_nop
}},
118 {STATE_RENDER(WINED3D_RS_FLUSHBATCH
), {STATE_RENDER(WINED3D_RS_FLUSHBATCH
), state_nop
}},
119 {STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT
), {STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT
), state_nop
}},
120 {STATE_RENDER(WINED3D_RS_STENCILENABLE
), {STATE_RENDER(WINED3D_RS_ZENABLE
)}},
121 {STATE_RENDER(WINED3D_RS_STENCILFAIL
), {STATE_RENDER(WINED3D_RS_ZENABLE
)}},
122 {STATE_RENDER(WINED3D_RS_STENCILZFAIL
), {STATE_RENDER(WINED3D_RS_ZENABLE
)}},
123 {STATE_RENDER(WINED3D_RS_STENCILPASS
), {STATE_RENDER(WINED3D_RS_ZENABLE
)}},
124 {STATE_RENDER(WINED3D_RS_STENCILFUNC
), {STATE_RENDER(WINED3D_RS_ZENABLE
)}},
125 {STATE_RENDER(WINED3D_RS_STENCILREF
), {STATE_RENDER(WINED3D_RS_ZENABLE
)}},
126 {STATE_RENDER(WINED3D_RS_STENCILMASK
), {STATE_RENDER(WINED3D_RS_ZENABLE
)}},
127 {STATE_RENDER(WINED3D_RS_STENCILWRITEMASK
), {STATE_RENDER(WINED3D_RS_ZENABLE
)}},
128 {STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE
), {STATE_RENDER(WINED3D_RS_ZENABLE
)}},
129 {STATE_RENDER(WINED3D_RS_BACK_STENCILFAIL
), {STATE_RENDER(WINED3D_RS_ZENABLE
)}},
130 {STATE_RENDER(WINED3D_RS_BACK_STENCILZFAIL
), {STATE_RENDER(WINED3D_RS_ZENABLE
)}},
131 {STATE_RENDER(WINED3D_RS_BACK_STENCILPASS
), {STATE_RENDER(WINED3D_RS_ZENABLE
)}},
132 {STATE_RENDER(WINED3D_RS_BACK_STENCILFUNC
), {STATE_RENDER(WINED3D_RS_ZENABLE
)}},
133 {STATE_RENDER(WINED3D_RS_WRAP0
), {STATE_RENDER(WINED3D_RS_WRAP0
), state_nop
}},
134 {STATE_RENDER(WINED3D_RS_WRAP1
), {STATE_RENDER(WINED3D_RS_WRAP0
)}},
135 {STATE_RENDER(WINED3D_RS_WRAP2
), {STATE_RENDER(WINED3D_RS_WRAP0
)}},
136 {STATE_RENDER(WINED3D_RS_WRAP3
), {STATE_RENDER(WINED3D_RS_WRAP0
)}},
137 {STATE_RENDER(WINED3D_RS_WRAP4
), {STATE_RENDER(WINED3D_RS_WRAP0
)}},
138 {STATE_RENDER(WINED3D_RS_WRAP5
), {STATE_RENDER(WINED3D_RS_WRAP0
)}},
139 {STATE_RENDER(WINED3D_RS_WRAP6
), {STATE_RENDER(WINED3D_RS_WRAP0
)}},
140 {STATE_RENDER(WINED3D_RS_WRAP7
), {STATE_RENDER(WINED3D_RS_WRAP0
)}},
141 {STATE_RENDER(WINED3D_RS_WRAP8
), {STATE_RENDER(WINED3D_RS_WRAP0
)}},
142 {STATE_RENDER(WINED3D_RS_WRAP9
), {STATE_RENDER(WINED3D_RS_WRAP0
)}},
143 {STATE_RENDER(WINED3D_RS_WRAP10
), {STATE_RENDER(WINED3D_RS_WRAP0
)}},
144 {STATE_RENDER(WINED3D_RS_WRAP11
), {STATE_RENDER(WINED3D_RS_WRAP0
)}},
145 {STATE_RENDER(WINED3D_RS_WRAP12
), {STATE_RENDER(WINED3D_RS_WRAP0
)}},
146 {STATE_RENDER(WINED3D_RS_WRAP13
), {STATE_RENDER(WINED3D_RS_WRAP0
)}},
147 {STATE_RENDER(WINED3D_RS_WRAP14
), {STATE_RENDER(WINED3D_RS_WRAP0
)}},
148 {STATE_RENDER(WINED3D_RS_WRAP15
), {STATE_RENDER(WINED3D_RS_WRAP0
)}},
149 {STATE_RENDER(WINED3D_RS_EXTENTS
), {STATE_RENDER(WINED3D_RS_EXTENTS
), state_nop
}},
150 {STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE
), {STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE
), state_nop
}},
151 {STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING
), {STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING
), state_nop
}},
152 {STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE
), {STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE
), state_nop
}},
153 {STATE_RENDER(WINED3D_RS_PATCHSEGMENTS
), {STATE_RENDER(WINED3D_RS_PATCHSEGMENTS
), state_nop
}},
154 {STATE_RENDER(WINED3D_RS_POSITIONDEGREE
), {STATE_RENDER(WINED3D_RS_POSITIONDEGREE
), state_nop
}},
155 {STATE_RENDER(WINED3D_RS_NORMALDEGREE
), {STATE_RENDER(WINED3D_RS_NORMALDEGREE
), state_nop
}},
156 {STATE_RENDER(WINED3D_RS_MINTESSELLATIONLEVEL
), {STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION
)}},
157 {STATE_RENDER(WINED3D_RS_MAXTESSELLATIONLEVEL
), {STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION
)}},
158 {STATE_RENDER(WINED3D_RS_ADAPTIVETESS_X
), {STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION
)}},
159 {STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Y
), {STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION
)}},
160 {STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Z
), {STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION
)}},
161 {STATE_RENDER(WINED3D_RS_ADAPTIVETESS_W
), {STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION
)}},
162 {STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION
), {STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION
), state_nop
}},
163 {STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS
), {STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS
), state_nop
}},
164 {STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK
), {STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK
), state_nop
}},
165 {STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN
), {STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN
), state_nop
}},
166 {STATE_RENDER(WINED3D_RS_ZVISIBLE
), {STATE_RENDER(WINED3D_RS_ZVISIBLE
), state_nop
}},
168 {STATE_SAMPLER(0), {STATE_SAMPLER(0), state_nop
}},
169 {STATE_SAMPLER(1), {STATE_SAMPLER(1), state_nop
}},
170 {STATE_SAMPLER(2), {STATE_SAMPLER(2), state_nop
}},
171 {STATE_SAMPLER(3), {STATE_SAMPLER(3), state_nop
}},
172 {STATE_SAMPLER(4), {STATE_SAMPLER(4), state_nop
}},
173 {STATE_SAMPLER(5), {STATE_SAMPLER(5), state_nop
}},
174 {STATE_SAMPLER(6), {STATE_SAMPLER(6), state_nop
}},
175 {STATE_SAMPLER(7), {STATE_SAMPLER(7), state_nop
}},
176 {STATE_SAMPLER(8), {STATE_SAMPLER(8), state_nop
}},
177 {STATE_SAMPLER(9), {STATE_SAMPLER(9), state_nop
}},
178 {STATE_SAMPLER(10), {STATE_SAMPLER(10), state_nop
}},
179 {STATE_SAMPLER(11), {STATE_SAMPLER(11), state_nop
}},
180 {STATE_SAMPLER(12), {STATE_SAMPLER(12), state_nop
}},
181 {STATE_SAMPLER(13), {STATE_SAMPLER(13), state_nop
}},
182 {STATE_SAMPLER(14), {STATE_SAMPLER(14), state_nop
}},
183 {STATE_SAMPLER(15), {STATE_SAMPLER(15), state_nop
}},
184 {STATE_SAMPLER(16), /* Vertex sampler 0 */ {STATE_SAMPLER(16), state_nop
}},
185 {STATE_SAMPLER(17), /* Vertex sampler 1 */ {STATE_SAMPLER(17), state_nop
}},
186 {STATE_SAMPLER(18), /* Vertex sampler 2 */ {STATE_SAMPLER(18), state_nop
}},
187 {STATE_SAMPLER(19), /* Vertex sampler 3 */ {STATE_SAMPLER(19), state_nop
}},
188 {STATE_BASEVERTEXINDEX
, {STATE_STREAMSRC
}},
189 {STATE_FRAMEBUFFER
, {STATE_FRAMEBUFFER
, state_nop
}},
190 {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL
), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL
), state_nop
}},
191 {STATE_SHADER(WINED3D_SHADER_TYPE_HULL
), {STATE_SHADER(WINED3D_SHADER_TYPE_HULL
), state_nop
}},
192 {STATE_SHADER(WINED3D_SHADER_TYPE_DOMAIN
), {STATE_SHADER(WINED3D_SHADER_TYPE_DOMAIN
), state_nop
}},
193 {STATE_SHADER(WINED3D_SHADER_TYPE_GEOMETRY
), {STATE_SHADER(WINED3D_SHADER_TYPE_GEOMETRY
), state_nop
}},
194 {STATE_SHADER(WINED3D_SHADER_TYPE_COMPUTE
), {STATE_SHADER(WINED3D_SHADER_TYPE_COMPUTE
), state_nop
}},
198 static inline const struct wined3d_adapter_vk
*wined3d_adapter_vk_const(const struct wined3d_adapter
*adapter
)
200 return CONTAINING_RECORD(adapter
, struct wined3d_adapter_vk
, a
);
203 static const char *debug_vk_version(uint32_t version
)
205 return wine_dbg_sprintf("%u.%u.%u",
206 VK_VERSION_MAJOR(version
), VK_VERSION_MINOR(version
), VK_VERSION_PATCH(version
));
209 static HRESULT
hresult_from_vk_result(VkResult vr
)
215 case VK_ERROR_OUT_OF_HOST_MEMORY
:
216 WARN("Out of host memory.\n");
217 return E_OUTOFMEMORY
;
218 case VK_ERROR_OUT_OF_DEVICE_MEMORY
:
219 WARN("Out of device memory.\n");
220 return E_OUTOFMEMORY
;
221 case VK_ERROR_DEVICE_LOST
:
222 WARN("Device lost.\n");
224 case VK_ERROR_EXTENSION_NOT_PRESENT
:
225 WARN("Extension not present.\n");
228 FIXME("Unhandled VkResult %d.\n", vr
);
233 #ifdef USE_WIN32_VULKAN
234 static BOOL
wined3d_load_vulkan(struct wined3d_vk_info
*vk_info
)
236 struct vulkan_ops
*vk_ops
= &vk_info
->vk_ops
;
238 if (!(vk_info
->vulkan_lib
= LoadLibraryA("vulkan-1.dll")))
240 WARN("Failed to load vulkan-1.dll.\n");
244 vk_ops
->vkGetInstanceProcAddr
= (void *)GetProcAddress(vk_info
->vulkan_lib
, "vkGetInstanceProcAddr");
245 if (!vk_ops
->vkGetInstanceProcAddr
)
247 FreeLibrary(vk_info
->vulkan_lib
);
254 static void wined3d_unload_vulkan(struct wined3d_vk_info
*vk_info
)
256 if (vk_info
->vulkan_lib
)
258 FreeLibrary(vk_info
->vulkan_lib
);
259 vk_info
->vulkan_lib
= NULL
;
263 static BOOL
wined3d_load_vulkan(struct wined3d_vk_info
*vk_info
)
265 struct vulkan_ops
*vk_ops
= &vk_info
->vk_ops
;
266 const struct vulkan_funcs
*vk_funcs
;
270 vk_funcs
= __wine_get_vulkan_driver(dc
, WINE_VULKAN_DRIVER_VERSION
);
276 vk_ops
->vkGetInstanceProcAddr
= (void *)vk_funcs
->p_vkGetInstanceProcAddr
;
280 static void wined3d_unload_vulkan(struct wined3d_vk_info
*vk_info
) {}
283 static void adapter_vk_destroy(struct wined3d_adapter
*adapter
)
285 struct wined3d_adapter_vk
*adapter_vk
= wined3d_adapter_vk(adapter
);
286 struct wined3d_vk_info
*vk_info
= &adapter_vk
->vk_info
;
288 VK_CALL(vkDestroyInstance(vk_info
->instance
, NULL
));
289 wined3d_unload_vulkan(vk_info
);
290 wined3d_adapter_cleanup(&adapter_vk
->a
);
291 heap_free(adapter_vk
);
294 static HRESULT
wined3d_select_vulkan_queue_family(const struct wined3d_adapter_vk
*adapter_vk
,
295 uint32_t *queue_family_index
, uint32_t *timestamp_bits
)
297 VkPhysicalDevice physical_device
= adapter_vk
->physical_device
;
298 const struct wined3d_vk_info
*vk_info
= &adapter_vk
->vk_info
;
299 VkQueueFamilyProperties
*queue_properties
;
302 VK_CALL(vkGetPhysicalDeviceQueueFamilyProperties(physical_device
, &count
, NULL
));
304 if (!(queue_properties
= heap_calloc(count
, sizeof(*queue_properties
))))
305 return E_OUTOFMEMORY
;
307 VK_CALL(vkGetPhysicalDeviceQueueFamilyProperties(physical_device
, &count
, queue_properties
));
309 for (i
= 0; i
< count
; ++i
)
311 if (queue_properties
[i
].queueFlags
& VK_QUEUE_GRAPHICS_BIT
)
313 *queue_family_index
= i
;
314 *timestamp_bits
= queue_properties
[i
].timestampValidBits
;
315 heap_free(queue_properties
);
319 heap_free(queue_properties
);
321 WARN("Failed to find graphics queue.\n");
325 struct wined3d_physical_device_info
327 VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT vertex_divisor_features
;
329 VkPhysicalDeviceFeatures2 features2
;
332 static void wined3d_disable_vulkan_features(struct wined3d_physical_device_info
*info
)
334 VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT
*vertex_divisor_features
= &info
->vertex_divisor_features
;
335 VkPhysicalDeviceFeatures
*features
= &info
->features2
.features
;
337 vertex_divisor_features
->vertexAttributeInstanceRateZeroDivisor
= VK_FALSE
;
339 features
->depthBounds
= VK_FALSE
;
340 features
->alphaToOne
= VK_FALSE
;
341 features
->textureCompressionETC2
= VK_FALSE
;
342 features
->textureCompressionASTC_LDR
= VK_FALSE
;
343 features
->shaderStorageImageMultisample
= VK_FALSE
;
344 features
->shaderUniformBufferArrayDynamicIndexing
= VK_FALSE
;
345 features
->shaderSampledImageArrayDynamicIndexing
= VK_FALSE
;
346 features
->shaderStorageBufferArrayDynamicIndexing
= VK_FALSE
;
347 features
->shaderStorageImageArrayDynamicIndexing
= VK_FALSE
;
348 features
->shaderInt16
= VK_FALSE
;
349 features
->shaderResourceResidency
= VK_FALSE
;
350 features
->shaderResourceMinLod
= VK_FALSE
;
351 features
->sparseBinding
= VK_FALSE
;
352 features
->sparseResidencyBuffer
= VK_FALSE
;
353 features
->sparseResidencyImage2D
= VK_FALSE
;
354 features
->sparseResidencyImage3D
= VK_FALSE
;
355 features
->sparseResidency2Samples
= VK_FALSE
;
356 features
->sparseResidency4Samples
= VK_FALSE
;
357 features
->sparseResidency8Samples
= VK_FALSE
;
358 features
->sparseResidency16Samples
= VK_FALSE
;
359 features
->sparseResidencyAliased
= VK_FALSE
;
360 features
->inheritedQueries
= VK_FALSE
;
363 static struct wined3d_allocator_chunk
*wined3d_allocator_vk_create_chunk(struct wined3d_allocator
*allocator
,
364 struct wined3d_context
*context
, unsigned int memory_type
, size_t chunk_size
)
366 struct wined3d_context_vk
*context_vk
= wined3d_context_vk(context
);
367 struct wined3d_allocator_chunk_vk
*chunk_vk
;
369 if (!(chunk_vk
= heap_alloc(sizeof(*chunk_vk
))))
372 if (!wined3d_allocator_chunk_init(&chunk_vk
->c
, allocator
))
378 if (!(chunk_vk
->vk_memory
= wined3d_context_vk_allocate_vram_chunk_memory(context_vk
, memory_type
, chunk_size
)))
380 wined3d_allocator_chunk_cleanup(&chunk_vk
->c
);
384 list_add_head(&allocator
->pools
[memory_type
].chunks
, &chunk_vk
->c
.entry
);
389 static void wined3d_allocator_vk_destroy_chunk(struct wined3d_allocator_chunk
*chunk
)
391 struct wined3d_allocator_chunk_vk
*chunk_vk
= wined3d_allocator_chunk_vk(chunk
);
392 const struct wined3d_vk_info
*vk_info
;
393 struct wined3d_device_vk
*device_vk
;
395 TRACE("chunk %p.\n", chunk
);
397 device_vk
= CONTAINING_RECORD(chunk_vk
->c
.allocator
, struct wined3d_device_vk
, allocator
);
398 vk_info
= &device_vk
->vk_info
;
400 if (chunk_vk
->c
.map_ptr
)
401 VK_CALL(vkUnmapMemory(device_vk
->vk_device
, chunk_vk
->vk_memory
));
402 VK_CALL(vkFreeMemory(device_vk
->vk_device
, chunk_vk
->vk_memory
, NULL
));
403 TRACE("Freed memory 0x%s.\n", wine_dbgstr_longlong(chunk_vk
->vk_memory
));
404 wined3d_allocator_chunk_cleanup(&chunk_vk
->c
);
408 static const struct wined3d_allocator_ops wined3d_allocator_vk_ops
=
410 .allocator_create_chunk
= wined3d_allocator_vk_create_chunk
,
411 .allocator_destroy_chunk
= wined3d_allocator_vk_destroy_chunk
,
417 unsigned int core_since_version
;
419 vulkan_device_extensions
[] =
421 {VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME
, ~0u},
422 {VK_KHR_MAINTENANCE1_EXTENSION_NAME
, VK_API_VERSION_1_1
},
423 {VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME
, VK_API_VERSION_1_1
},
424 {VK_KHR_SWAPCHAIN_EXTENSION_NAME
, ~0u},
427 static bool enable_vulkan_device_extensions(VkPhysicalDevice physical_device
, uint32_t *extension_count
,
428 const char *enabled_extensions
[], const struct wined3d_vk_info
*vk_info
)
430 VkExtensionProperties
*extensions
= NULL
;
431 bool success
= false, found
;
432 unsigned int i
, j
, count
;
435 *extension_count
= 0;
437 if ((vr
= VK_CALL(vkEnumerateDeviceExtensionProperties(physical_device
, NULL
, &count
, NULL
))) < 0)
439 ERR("Failed to enumerate device extensions, vr %s.\n", wined3d_debug_vkresult(vr
));
442 if (!(extensions
= heap_calloc(count
, sizeof(*extensions
))))
444 WARN("Out of memory.\n");
447 if ((vr
= VK_CALL(vkEnumerateDeviceExtensionProperties(physical_device
, NULL
, &count
, extensions
))) < 0)
449 ERR("Failed to enumerate device extensions, vr %s.\n", wined3d_debug_vkresult(vr
));
453 for (i
= 0; i
< ARRAY_SIZE(vulkan_device_extensions
); ++i
)
455 if (vulkan_device_extensions
[i
].core_since_version
<= vk_info
->api_version
)
458 for (j
= 0, found
= false; j
< count
; ++j
)
460 if (!strcmp(extensions
[j
].extensionName
, vulkan_device_extensions
[i
].name
))
469 WARN("Required extension '%s' is not available.\n", vulkan_device_extensions
[i
].name
);
473 TRACE("Enabling instance extension '%s'.\n", vulkan_device_extensions
[i
].name
);
474 enabled_extensions
[(*extension_count
)++] = vulkan_device_extensions
[i
].name
;
479 heap_free(extensions
);
483 static HRESULT
adapter_vk_create_device(struct wined3d
*wined3d
, const struct wined3d_adapter
*adapter
,
484 enum wined3d_device_type device_type
, HWND focus_window
, unsigned int flags
, BYTE surface_alignment
,
485 const enum wined3d_feature_level
*levels
, unsigned int level_count
,
486 struct wined3d_device_parent
*device_parent
, struct wined3d_device
**device
)
488 const struct wined3d_adapter_vk
*adapter_vk
= wined3d_adapter_vk_const(adapter
);
489 const char *enabled_device_extensions
[ARRAY_SIZE(vulkan_device_extensions
)];
490 VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT
*vertex_divisor_features
;
491 const struct wined3d_vk_info
*vk_info
= &adapter_vk
->vk_info
;
492 struct wined3d_physical_device_info physical_device_info
;
493 static const float priorities
[] = {1.0f
};
494 VkPhysicalDeviceFeatures2
*features2
;
495 struct wined3d_device_vk
*device_vk
;
496 VkDevice vk_device
= VK_NULL_HANDLE
;
497 VkDeviceQueueCreateInfo queue_info
;
498 VkPhysicalDevice physical_device
;
499 VkDeviceCreateInfo device_info
;
500 uint32_t queue_family_index
;
501 uint32_t timestamp_bits
;
505 if (!(device_vk
= heap_alloc_zero(sizeof(*device_vk
))))
506 return E_OUTOFMEMORY
;
508 if (FAILED(hr
= wined3d_select_vulkan_queue_family(adapter_vk
, &queue_family_index
, ×tamp_bits
)))
511 physical_device
= adapter_vk
->physical_device
;
513 memset(&physical_device_info
, 0, sizeof(physical_device_info
));
515 vertex_divisor_features
= &physical_device_info
.vertex_divisor_features
;
516 vertex_divisor_features
->sType
= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT
;
518 features2
= &physical_device_info
.features2
;
519 features2
->sType
= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2
;
520 features2
->pNext
= vertex_divisor_features
;
522 if (vk_info
->vk_ops
.vkGetPhysicalDeviceFeatures2
)
523 VK_CALL(vkGetPhysicalDeviceFeatures2(physical_device
, features2
));
525 VK_CALL(vkGetPhysicalDeviceFeatures(physical_device
, &features2
->features
));
527 if (!vertex_divisor_features
->vertexAttributeInstanceRateDivisor
)
529 WARN("Vertex attribute divisors not supported.\n");
534 wined3d_disable_vulkan_features(&physical_device_info
);
536 queue_info
.sType
= VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO
;
537 queue_info
.pNext
= NULL
;
538 queue_info
.flags
= 0;
539 queue_info
.queueFamilyIndex
= queue_family_index
;
540 queue_info
.queueCount
= ARRAY_SIZE(priorities
);
541 queue_info
.pQueuePriorities
= priorities
;
543 device_info
.sType
= VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO
;
544 device_info
.pNext
= features2
->pNext
;
545 device_info
.flags
= 0;
546 device_info
.queueCreateInfoCount
= 1;
547 device_info
.pQueueCreateInfos
= &queue_info
;
548 device_info
.enabledLayerCount
= 0;
549 device_info
.ppEnabledLayerNames
= NULL
;
550 device_info
.ppEnabledExtensionNames
= enabled_device_extensions
;
551 if (!enable_vulkan_device_extensions(physical_device
,
552 &device_info
.enabledExtensionCount
, enabled_device_extensions
, vk_info
))
557 device_info
.pEnabledFeatures
= &features2
->features
;
559 if ((vr
= VK_CALL(vkCreateDevice(physical_device
, &device_info
, NULL
, &vk_device
))) < 0)
561 WARN("Failed to create Vulkan device, vr %s.\n", wined3d_debug_vkresult(vr
));
562 vk_device
= VK_NULL_HANDLE
;
563 hr
= hresult_from_vk_result(vr
);
567 device_vk
->vk_device
= vk_device
;
568 VK_CALL(vkGetDeviceQueue(vk_device
, queue_family_index
, 0, &device_vk
->vk_queue
));
569 device_vk
->vk_queue_family_index
= queue_family_index
;
570 device_vk
->timestamp_bits
= timestamp_bits
;
572 device_vk
->vk_info
= *vk_info
;
573 #define LOAD_DEVICE_PFN(name) \
574 if (!(device_vk->vk_info.vk_ops.name = (void *)VK_CALL(vkGetDeviceProcAddr(vk_device, #name)))) \
576 WARN("Could not get device proc addr for '" #name "'.\n"); \
580 #define VK_DEVICE_PFN LOAD_DEVICE_PFN
584 if (!wined3d_allocator_init(&device_vk
->allocator
,
585 adapter_vk
->memory_properties
.memoryTypeCount
, &wined3d_allocator_vk_ops
))
587 WARN("Failed to initialise allocator.\n");
592 if (FAILED(hr
= wined3d_device_init(&device_vk
->d
, wined3d
, adapter
->ordinal
, device_type
, focus_window
,
593 flags
, surface_alignment
, levels
, level_count
, vk_info
->supported
, device_parent
)))
595 WARN("Failed to initialize device, hr %#x.\n", hr
);
596 wined3d_allocator_cleanup(&device_vk
->allocator
);
600 *device
= &device_vk
->d
;
605 VK_CALL(vkDestroyDevice(vk_device
, NULL
));
606 heap_free(device_vk
);
610 static void adapter_vk_destroy_device(struct wined3d_device
*device
)
612 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(device
);
613 const struct wined3d_vk_info
*vk_info
= &device_vk
->vk_info
;
615 wined3d_device_cleanup(&device_vk
->d
);
616 wined3d_allocator_cleanup(&device_vk
->allocator
);
617 VK_CALL(vkDestroyDevice(device_vk
->vk_device
, NULL
));
618 heap_free(device_vk
);
621 struct wined3d_context
*adapter_vk_acquire_context(struct wined3d_device
*device
,
622 struct wined3d_texture
*texture
, unsigned int sub_resource_idx
)
624 TRACE("device %p, texture %p, sub_resource_idx %u.\n", device
, texture
, sub_resource_idx
);
626 wined3d_from_cs(device
->cs
);
628 if (!device
->context_count
)
631 return &wined3d_device_vk(device
)->context_vk
.c
;
634 void adapter_vk_release_context(struct wined3d_context
*context
)
636 TRACE("context %p.\n", context
);
639 static void adapter_vk_get_wined3d_caps(const struct wined3d_adapter
*adapter
, struct wined3d_caps
*caps
)
641 const struct wined3d_adapter_vk
*adapter_vk
= wined3d_adapter_vk_const(adapter
);
642 const VkPhysicalDeviceLimits
*limits
= &adapter_vk
->device_limits
;
643 BOOL sampler_anisotropy
= limits
->maxSamplerAnisotropy
> 1.0f
;
645 caps
->ddraw_caps
.dds_caps
|= WINEDDSCAPS_BACKBUFFER
646 | WINEDDSCAPS_COMPLEX
647 | WINEDDSCAPS_FRONTBUFFER
648 | WINEDDSCAPS_3DDEVICE
649 | WINEDDSCAPS_VIDEOMEMORY
651 | WINEDDSCAPS_LOCALVIDMEM
652 | WINEDDSCAPS_NONLOCALVIDMEM
;
653 caps
->ddraw_caps
.caps
|= WINEDDCAPS_3D
;
655 caps
->Caps2
|= WINED3DCAPS2_CANGENMIPMAP
;
657 caps
->PrimitiveMiscCaps
|= WINED3DPMISCCAPS_BLENDOP
658 | WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS
659 | WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
660 | WINED3DPMISCCAPS_POSTBLENDSRGBCONVERT
661 | WINED3DPMISCCAPS_SEPARATEALPHABLEND
;
663 caps
->RasterCaps
|= WINED3DPRASTERCAPS_MIPMAPLODBIAS
;
665 if (sampler_anisotropy
)
667 caps
->RasterCaps
|= WINED3DPRASTERCAPS_ANISOTROPY
;
669 caps
->TextureFilterCaps
|= WINED3DPTFILTERCAPS_MAGFANISOTROPIC
670 | WINED3DPTFILTERCAPS_MINFANISOTROPIC
;
672 caps
->MaxAnisotropy
= limits
->maxSamplerAnisotropy
;
675 caps
->SrcBlendCaps
|= WINED3DPBLENDCAPS_BLENDFACTOR
;
676 caps
->DestBlendCaps
|= WINED3DPBLENDCAPS_BLENDFACTOR
677 | WINED3DPBLENDCAPS_SRCALPHASAT
;
679 caps
->TextureCaps
|= WINED3DPTEXTURECAPS_VOLUMEMAP
680 | WINED3DPTEXTURECAPS_MIPVOLUMEMAP
681 | WINED3DPTEXTURECAPS_VOLUMEMAP_POW2
;
682 caps
->VolumeTextureFilterCaps
|= WINED3DPTFILTERCAPS_MAGFLINEAR
683 | WINED3DPTFILTERCAPS_MAGFPOINT
684 | WINED3DPTFILTERCAPS_MINFLINEAR
685 | WINED3DPTFILTERCAPS_MINFPOINT
686 | WINED3DPTFILTERCAPS_MIPFLINEAR
687 | WINED3DPTFILTERCAPS_MIPFPOINT
688 | WINED3DPTFILTERCAPS_LINEAR
689 | WINED3DPTFILTERCAPS_LINEARMIPLINEAR
690 | WINED3DPTFILTERCAPS_LINEARMIPNEAREST
691 | WINED3DPTFILTERCAPS_MIPLINEAR
692 | WINED3DPTFILTERCAPS_MIPNEAREST
693 | WINED3DPTFILTERCAPS_NEAREST
;
694 caps
->VolumeTextureAddressCaps
|= WINED3DPTADDRESSCAPS_INDEPENDENTUV
695 | WINED3DPTADDRESSCAPS_CLAMP
696 | WINED3DPTADDRESSCAPS_WRAP
;
697 caps
->VolumeTextureAddressCaps
|= WINED3DPTADDRESSCAPS_BORDER
698 | WINED3DPTADDRESSCAPS_MIRROR
699 | WINED3DPTADDRESSCAPS_MIRRORONCE
;
701 caps
->MaxVolumeExtent
= limits
->maxImageDimension3D
;
703 caps
->TextureCaps
|= WINED3DPTEXTURECAPS_CUBEMAP
704 | WINED3DPTEXTURECAPS_MIPCUBEMAP
705 | WINED3DPTEXTURECAPS_CUBEMAP_POW2
;
706 caps
->CubeTextureFilterCaps
|= WINED3DPTFILTERCAPS_MAGFLINEAR
707 | WINED3DPTFILTERCAPS_MAGFPOINT
708 | WINED3DPTFILTERCAPS_MINFLINEAR
709 | WINED3DPTFILTERCAPS_MINFPOINT
710 | WINED3DPTFILTERCAPS_MIPFLINEAR
711 | WINED3DPTFILTERCAPS_MIPFPOINT
712 | WINED3DPTFILTERCAPS_LINEAR
713 | WINED3DPTFILTERCAPS_LINEARMIPLINEAR
714 | WINED3DPTFILTERCAPS_LINEARMIPNEAREST
715 | WINED3DPTFILTERCAPS_MIPLINEAR
716 | WINED3DPTFILTERCAPS_MIPNEAREST
717 | WINED3DPTFILTERCAPS_NEAREST
;
719 if (sampler_anisotropy
)
721 caps
->CubeTextureFilterCaps
|= WINED3DPTFILTERCAPS_MAGFANISOTROPIC
722 | WINED3DPTFILTERCAPS_MINFANISOTROPIC
;
725 caps
->TextureAddressCaps
|= WINED3DPTADDRESSCAPS_BORDER
726 | WINED3DPTADDRESSCAPS_MIRROR
727 | WINED3DPTADDRESSCAPS_MIRRORONCE
;
729 caps
->StencilCaps
|= WINED3DSTENCILCAPS_DECR
730 | WINED3DSTENCILCAPS_INCR
731 | WINED3DSTENCILCAPS_TWOSIDED
;
733 caps
->DeclTypes
|= WINED3DDTCAPS_FLOAT16_2
| WINED3DDTCAPS_FLOAT16_4
;
735 caps
->MaxPixelShader30InstructionSlots
= WINED3DMAX30SHADERINSTRUCTIONS
;
736 caps
->MaxVertexShader30InstructionSlots
= WINED3DMAX30SHADERINSTRUCTIONS
;
737 caps
->PS20Caps
.temp_count
= WINED3DPS20_MAX_NUMTEMPS
;
738 caps
->VS20Caps
.temp_count
= WINED3DVS20_MAX_NUMTEMPS
;
741 static BOOL
adapter_vk_check_format(const struct wined3d_adapter
*adapter
,
742 const struct wined3d_format
*adapter_format
, const struct wined3d_format
*rt_format
,
743 const struct wined3d_format
*ds_format
)
748 static HRESULT
adapter_vk_init_3d(struct wined3d_device
*device
)
750 struct wined3d_context_vk
*context_vk
;
751 struct wined3d_device_vk
*device_vk
;
754 TRACE("device %p.\n", device
);
756 device_vk
= wined3d_device_vk(device
);
757 context_vk
= &device_vk
->context_vk
;
758 if (FAILED(hr
= wined3d_context_vk_init(context_vk
, device
->swapchains
[0])))
760 WARN("Failed to initialise context.\n");
764 if (FAILED(hr
= device
->shader_backend
->shader_alloc_private(device
,
765 device
->adapter
->vertex_pipe
, device
->adapter
->fragment_pipe
)))
767 ERR("Failed to allocate shader private data, hr %#x.\n", hr
);
768 wined3d_context_vk_cleanup(context_vk
);
772 if (!device_context_add(device
, &context_vk
->c
))
774 ERR("Failed to add the newly created context to the context list.\n");
775 device
->shader_backend
->shader_free_private(device
, NULL
);
776 wined3d_context_vk_cleanup(context_vk
);
780 TRACE("Initialised context %p.\n", context_vk
);
782 if (!(device_vk
->d
.blitter
= wined3d_cpu_blitter_create()))
784 ERR("Failed to create CPU blitter.\n");
785 device_context_remove(device
, &context_vk
->c
);
786 device
->shader_backend
->shader_free_private(device
, NULL
);
787 wined3d_context_vk_cleanup(context_vk
);
790 wined3d_vk_blitter_create(&device_vk
->d
.blitter
);
792 wined3d_device_create_default_samplers(device
, &context_vk
->c
);
793 wined3d_device_vk_create_null_resources(device_vk
, context_vk
);
794 wined3d_device_vk_create_null_views(device_vk
, context_vk
);
799 static void adapter_vk_uninit_3d_cs(void *object
)
801 struct wined3d_device_vk
*device_vk
= object
;
802 struct wined3d_context_vk
*context_vk
;
803 struct wined3d_device
*device
;
804 struct wined3d_shader
*shader
;
806 TRACE("device_vk %p.\n", device_vk
);
808 context_vk
= &device_vk
->context_vk
;
809 device
= &device_vk
->d
;
811 LIST_FOR_EACH_ENTRY(shader
, &device
->shaders
, struct wined3d_shader
, shader_list_entry
)
813 device
->shader_backend
->shader_destroy(shader
);
816 device
->blitter
->ops
->blitter_destroy(device
->blitter
, NULL
);
817 device
->shader_backend
->shader_free_private(device
, &context_vk
->c
);
818 wined3d_device_vk_destroy_null_views(device_vk
, context_vk
);
819 wined3d_device_vk_destroy_null_resources(device_vk
, context_vk
);
820 wined3d_device_destroy_default_samplers(device
, &context_vk
->c
);
823 static void adapter_vk_uninit_3d(struct wined3d_device
*device
)
825 struct wined3d_context_vk
*context_vk
;
826 struct wined3d_device_vk
*device_vk
;
828 TRACE("device %p.\n", device
);
830 device_vk
= wined3d_device_vk(device
);
831 context_vk
= &device_vk
->context_vk
;
833 wined3d_cs_destroy_object(device
->cs
, adapter_vk_uninit_3d_cs
, device_vk
);
834 wined3d_cs_finish(device
->cs
, WINED3D_CS_QUEUE_DEFAULT
);
836 device_context_remove(device
, &context_vk
->c
);
837 wined3d_context_vk_cleanup(context_vk
);
840 static void *wined3d_bo_vk_map(struct wined3d_bo_vk
*bo
, struct wined3d_context_vk
*context_vk
)
842 const struct wined3d_vk_info
*vk_info
;
843 struct wined3d_device_vk
*device_vk
;
844 struct wined3d_bo_slab_vk
*slab
;
851 vk_info
= context_vk
->vk_info
;
852 device_vk
= wined3d_device_vk(context_vk
->c
.device
);
854 if ((slab
= bo
->slab
))
856 if (!(map_ptr
= slab
->map_ptr
) && !(map_ptr
= wined3d_bo_vk_map(&slab
->bo
, context_vk
)))
858 ERR("Failed to map slab.\n");
865 struct wined3d_allocator_chunk_vk
*chunk_vk
= wined3d_allocator_chunk_vk(bo
->memory
->chunk
);
867 if (!(map_ptr
= wined3d_allocator_chunk_vk_map(chunk_vk
, context_vk
)))
869 ERR("Failed to map chunk.\n");
873 else if ((vr
= VK_CALL(vkMapMemory(device_vk
->vk_device
, bo
->vk_memory
, 0, VK_WHOLE_SIZE
, 0, &map_ptr
))) < 0)
875 ERR("Failed to map memory, vr %s.\n", wined3d_debug_vkresult(vr
));
879 if (sizeof(map_ptr
) >= sizeof(uint64_t))
880 bo
->map_ptr
= map_ptr
;
885 static void wined3d_bo_vk_unmap(struct wined3d_bo_vk
*bo
, struct wined3d_context_vk
*context_vk
)
887 const struct wined3d_vk_info
*vk_info
;
888 struct wined3d_device_vk
*device_vk
;
889 struct wined3d_bo_slab_vk
*slab
;
894 if ((slab
= bo
->slab
))
896 if (--slab
->map_count
)
899 wined3d_bo_vk_unmap(&slab
->bo
, context_vk
);
900 slab
->map_ptr
= NULL
;
904 vk_info
= context_vk
->vk_info
;
905 device_vk
= wined3d_device_vk(context_vk
->c
.device
);
908 wined3d_allocator_chunk_vk_unmap(wined3d_allocator_chunk_vk(bo
->memory
->chunk
), context_vk
);
910 VK_CALL(vkUnmapMemory(device_vk
->vk_device
, bo
->vk_memory
));
913 static VkAccessFlags
vk_access_mask_from_buffer_usage(VkBufferUsageFlags usage
)
915 VkAccessFlags flags
= 0;
917 if (usage
& VK_BUFFER_USAGE_VERTEX_BUFFER_BIT
)
918 flags
|= VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT
;
919 if (usage
& VK_BUFFER_USAGE_INDEX_BUFFER_BIT
)
920 flags
|= VK_ACCESS_INDEX_READ_BIT
;
921 if (usage
& VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
)
922 flags
|= VK_ACCESS_UNIFORM_READ_BIT
;
923 if (usage
& VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT
)
924 flags
|= VK_ACCESS_SHADER_READ_BIT
;
925 if (usage
& VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT
)
926 flags
|= VK_ACCESS_SHADER_READ_BIT
| VK_ACCESS_SHADER_WRITE_BIT
;
927 if (usage
& VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT
)
928 flags
|= VK_ACCESS_INDIRECT_COMMAND_READ_BIT
;
933 static void *adapter_vk_map_bo_address(struct wined3d_context
*context
,
934 const struct wined3d_bo_address
*data
, size_t size
, uint32_t map_flags
)
936 struct wined3d_context_vk
*context_vk
= wined3d_context_vk(context
);
937 const struct wined3d_vk_info
*vk_info
;
938 struct wined3d_bo_user_vk
*bo_user_vk
;
939 struct wined3d_device_vk
*device_vk
;
940 VkCommandBuffer vk_command_buffer
;
941 VkBufferMemoryBarrier vk_barrier
;
942 struct wined3d_bo_vk
*bo
, tmp
;
943 VkMappedMemoryRange range
;
946 if (!(bo
= (struct wined3d_bo_vk
*)data
->buffer_object
))
949 vk_info
= context_vk
->vk_info
;
950 device_vk
= wined3d_device_vk(context
->device
);
952 if (map_flags
& WINED3D_MAP_NOOVERWRITE
)
955 if ((map_flags
& WINED3D_MAP_DISCARD
) && bo
->command_buffer_id
> context_vk
->completed_command_buffer_id
)
957 if (wined3d_context_vk_create_bo(context_vk
, bo
->size
, bo
->usage
, bo
->memory_type
, &tmp
))
959 list_move_head(&tmp
.users
, &bo
->users
);
960 wined3d_context_vk_destroy_bo(context_vk
, bo
);
962 list_init(&bo
->users
);
963 list_move_head(&bo
->users
, &tmp
.users
);
964 LIST_FOR_EACH_ENTRY(bo_user_vk
, &bo
->users
, struct wined3d_bo_user_vk
, entry
)
966 bo_user_vk
->valid
= false;
972 ERR("Failed to create new buffer object.\n");
975 if (map_flags
& WINED3D_MAP_READ
)
977 if (!(vk_command_buffer
= wined3d_context_vk_get_command_buffer(context_vk
)))
979 ERR("Failed to get command buffer.\n");
983 wined3d_context_vk_end_current_render_pass(context_vk
);
985 vk_barrier
.sType
= VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER
;
986 vk_barrier
.pNext
= NULL
;
987 vk_barrier
.srcAccessMask
= vk_access_mask_from_buffer_usage(bo
->usage
);
988 vk_barrier
.dstAccessMask
= VK_ACCESS_HOST_READ_BIT
;
989 vk_barrier
.srcQueueFamilyIndex
= VK_QUEUE_FAMILY_IGNORED
;
990 vk_barrier
.dstQueueFamilyIndex
= VK_QUEUE_FAMILY_IGNORED
;
991 vk_barrier
.buffer
= bo
->vk_buffer
;
992 vk_barrier
.offset
= bo
->buffer_offset
+ (uintptr_t)data
->addr
;
993 vk_barrier
.size
= size
;
994 VK_CALL(vkCmdPipelineBarrier(vk_command_buffer
, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT
,
995 VK_PIPELINE_STAGE_HOST_BIT
, 0, 0, NULL
, 1, &vk_barrier
, 0, NULL
));
997 if (!(bo
->memory_type
& VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
))
999 range
.sType
= VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE
;
1001 range
.memory
= bo
->vk_memory
;
1002 range
.offset
= bo
->memory_offset
+ (uintptr_t)data
->addr
;
1004 VK_CALL(vkInvalidateMappedMemoryRanges(device_vk
->vk_device
, 1, &range
));
1007 wined3d_context_vk_reference_bo(context_vk
, bo
);
1010 if (bo
->command_buffer_id
== context_vk
->current_command_buffer
.id
)
1011 wined3d_context_vk_submit_command_buffer(context_vk
, 0, NULL
, NULL
, 0, NULL
);
1012 wined3d_context_vk_wait_command_buffer(context_vk
, bo
->command_buffer_id
);
1015 if (!(map_ptr
= wined3d_bo_vk_map(bo
, context_vk
)))
1017 ERR("Failed to map bo.\n");
1021 return (uint8_t *)map_ptr
+ bo
->memory_offset
+ (uintptr_t)data
->addr
;
1024 static void adapter_vk_unmap_bo_address(struct wined3d_context
*context
,
1025 const struct wined3d_bo_address
*data
, unsigned int range_count
, const struct wined3d_range
*ranges
)
1027 struct wined3d_context_vk
*context_vk
= wined3d_context_vk(context
);
1028 const struct wined3d_vk_info
*vk_info
;
1029 struct wined3d_device_vk
*device_vk
;
1030 VkMappedMemoryRange range
;
1031 struct wined3d_bo_vk
*bo
;
1034 if (!(bo
= (struct wined3d_bo_vk
*)data
->buffer_object
))
1037 vk_info
= context_vk
->vk_info
;
1038 device_vk
= wined3d_device_vk(context
->device
);
1040 if (!(bo
->memory_type
& VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
))
1042 range
.sType
= VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE
;
1044 range
.memory
= bo
->vk_memory
;
1046 for (i
= 0; i
< range_count
; ++i
)
1048 range
.offset
= bo
->memory_offset
+ ranges
[i
].offset
;
1049 range
.size
= ranges
[i
].size
;
1050 VK_CALL(vkFlushMappedMemoryRanges(device_vk
->vk_device
, 1, &range
));
1054 wined3d_bo_vk_unmap(bo
, context_vk
);
1057 static void adapter_vk_copy_bo_address(struct wined3d_context
*context
,
1058 const struct wined3d_bo_address
*dst
, const struct wined3d_bo_address
*src
, size_t size
)
1060 struct wined3d_context_vk
*context_vk
= wined3d_context_vk(context
);
1061 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
1062 struct wined3d_bo_vk staging_bo
, *src_bo
, *dst_bo
;
1063 VkAccessFlags src_access_mask
, dst_access_mask
;
1064 VkBufferMemoryBarrier vk_barrier
[2];
1065 struct wined3d_bo_address staging
;
1066 VkCommandBuffer vk_command_buffer
;
1067 struct wined3d_range range
;
1068 void *dst_ptr
, *src_ptr
;
1069 VkBufferCopy region
;
1071 src_bo
= (struct wined3d_bo_vk
*)src
->buffer_object
;
1072 dst_bo
= (struct wined3d_bo_vk
*)dst
->buffer_object
;
1074 if (src_bo
&& dst_bo
)
1076 if (!(vk_command_buffer
= wined3d_context_vk_get_command_buffer(context_vk
)))
1078 ERR("Failed to get command buffer.\n");
1082 wined3d_context_vk_end_current_render_pass(context_vk
);
1084 src_access_mask
= vk_access_mask_from_buffer_usage(src_bo
->usage
);
1085 dst_access_mask
= vk_access_mask_from_buffer_usage(dst_bo
->usage
);
1087 region
.srcOffset
= src_bo
->buffer_offset
+ (uintptr_t)src
->addr
;
1088 region
.dstOffset
= dst_bo
->buffer_offset
+ (uintptr_t)dst
->addr
;
1091 vk_barrier
[0].sType
= VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER
;
1092 vk_barrier
[0].pNext
= NULL
;
1093 vk_barrier
[0].srcAccessMask
= src_access_mask
;
1094 vk_barrier
[0].dstAccessMask
= VK_ACCESS_TRANSFER_READ_BIT
;
1095 vk_barrier
[0].srcQueueFamilyIndex
= VK_QUEUE_FAMILY_IGNORED
;
1096 vk_barrier
[0].dstQueueFamilyIndex
= VK_QUEUE_FAMILY_IGNORED
;
1097 vk_barrier
[0].buffer
= src_bo
->vk_buffer
;
1098 vk_barrier
[0].offset
= region
.srcOffset
;
1099 vk_barrier
[0].size
= region
.size
;
1101 vk_barrier
[1].sType
= VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER
;
1102 vk_barrier
[1].pNext
= NULL
;
1103 vk_barrier
[1].srcAccessMask
= dst_access_mask
;
1104 vk_barrier
[1].dstAccessMask
= VK_ACCESS_TRANSFER_WRITE_BIT
;
1105 vk_barrier
[1].srcQueueFamilyIndex
= VK_QUEUE_FAMILY_IGNORED
;
1106 vk_barrier
[1].dstQueueFamilyIndex
= VK_QUEUE_FAMILY_IGNORED
;
1107 vk_barrier
[1].buffer
= dst_bo
->vk_buffer
;
1108 vk_barrier
[1].offset
= region
.dstOffset
;
1109 vk_barrier
[1].size
= region
.size
;
1111 VK_CALL(vkCmdPipelineBarrier(vk_command_buffer
, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT
,
1112 VK_PIPELINE_STAGE_TRANSFER_BIT
, 0, 0, NULL
, 2, vk_barrier
, 0, NULL
));
1114 VK_CALL(vkCmdCopyBuffer(vk_command_buffer
, src_bo
->vk_buffer
, dst_bo
->vk_buffer
, 1, ®ion
));
1116 vk_barrier
[0].srcAccessMask
= VK_ACCESS_TRANSFER_READ_BIT
;
1117 vk_barrier
[0].dstAccessMask
= src_access_mask
;
1119 vk_barrier
[1].srcAccessMask
= VK_ACCESS_TRANSFER_WRITE_BIT
;
1120 vk_barrier
[1].dstAccessMask
= dst_access_mask
;
1122 VK_CALL(vkCmdPipelineBarrier(vk_command_buffer
, VK_PIPELINE_STAGE_TRANSFER_BIT
,
1123 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT
, 0, 0, NULL
, 2, vk_barrier
, 0, NULL
));
1125 wined3d_context_vk_reference_bo(context_vk
, src_bo
);
1126 wined3d_context_vk_reference_bo(context_vk
, dst_bo
);
1131 if (src_bo
&& !(src_bo
->memory_type
& VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
))
1133 if (!(wined3d_context_vk_create_bo(context_vk
, size
, VK_BUFFER_USAGE_TRANSFER_DST_BIT
,
1134 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
, &staging_bo
)))
1136 ERR("Failed to create staging bo.\n");
1140 staging
.buffer_object
= (uintptr_t)&staging_bo
;
1141 staging
.addr
= NULL
;
1142 adapter_vk_copy_bo_address(context
, &staging
, src
, size
);
1143 adapter_vk_copy_bo_address(context
, dst
, &staging
, size
);
1145 wined3d_context_vk_destroy_bo(context_vk
, &staging_bo
);
1150 if (dst_bo
&& (dst_bo
->command_buffer_id
> context_vk
->completed_command_buffer_id
1151 || !(dst_bo
->memory_type
& VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
)))
1153 if (!(wined3d_context_vk_create_bo(context_vk
, size
, VK_BUFFER_USAGE_TRANSFER_SRC_BIT
,
1154 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
, &staging_bo
)))
1156 ERR("Failed to create staging bo.\n");
1160 staging
.buffer_object
= (uintptr_t)&staging_bo
;
1161 staging
.addr
= NULL
;
1162 adapter_vk_copy_bo_address(context
, &staging
, src
, size
);
1163 adapter_vk_copy_bo_address(context
, dst
, &staging
, size
);
1165 wined3d_context_vk_destroy_bo(context_vk
, &staging_bo
);
1170 src_ptr
= adapter_vk_map_bo_address(context
, src
, size
, WINED3D_MAP_READ
);
1171 dst_ptr
= adapter_vk_map_bo_address(context
, dst
, size
, WINED3D_MAP_WRITE
);
1173 memcpy(dst_ptr
, src_ptr
, size
);
1177 adapter_vk_unmap_bo_address(context
, dst
, 1, &range
);
1178 adapter_vk_unmap_bo_address(context
, src
, 0, NULL
);
1181 static HRESULT
adapter_vk_create_swapchain(struct wined3d_device
*device
, struct wined3d_swapchain_desc
*desc
,
1182 void *parent
, const struct wined3d_parent_ops
*parent_ops
, struct wined3d_swapchain
**swapchain
)
1184 struct wined3d_swapchain_vk
*swapchain_vk
;
1187 TRACE("device %p, desc %p, parent %p, parent_ops %p, swapchain %p.\n",
1188 device
, desc
, parent
, parent_ops
, swapchain
);
1190 if (!(swapchain_vk
= heap_alloc_zero(sizeof(*swapchain_vk
))))
1191 return E_OUTOFMEMORY
;
1193 if (FAILED(hr
= wined3d_swapchain_vk_init(swapchain_vk
, device
, desc
, parent
, parent_ops
)))
1195 WARN("Failed to initialise swapchain, hr %#x.\n", hr
);
1196 heap_free(swapchain_vk
);
1200 TRACE("Created swapchain %p.\n", swapchain_vk
);
1201 *swapchain
= &swapchain_vk
->s
;
1206 static void adapter_vk_destroy_swapchain(struct wined3d_swapchain
*swapchain
)
1208 struct wined3d_swapchain_vk
*swapchain_vk
= wined3d_swapchain_vk(swapchain
);
1210 wined3d_swapchain_vk_cleanup(swapchain_vk
);
1211 heap_free(swapchain_vk
);
1214 unsigned int wined3d_adapter_vk_get_memory_type_index(const struct wined3d_adapter_vk
*adapter_vk
,
1215 uint32_t memory_type_mask
, VkMemoryPropertyFlags flags
)
1217 const VkPhysicalDeviceMemoryProperties
*memory_info
= &adapter_vk
->memory_properties
;
1220 for (i
= 0; i
< memory_info
->memoryTypeCount
; ++i
)
1222 if (!(memory_type_mask
& (1u << i
)))
1224 if ((memory_info
->memoryTypes
[i
].propertyFlags
& flags
) == flags
)
1231 static HRESULT
adapter_vk_create_buffer(struct wined3d_device
*device
,
1232 const struct wined3d_buffer_desc
*desc
, const struct wined3d_sub_resource_data
*data
,
1233 void *parent
, const struct wined3d_parent_ops
*parent_ops
, struct wined3d_buffer
**buffer
)
1235 struct wined3d_buffer_vk
*buffer_vk
;
1238 TRACE("device %p, desc %p, data %p, parent %p, parent_ops %p, buffer %p.\n",
1239 device
, desc
, data
, parent
, parent_ops
, buffer
);
1241 if (!(buffer_vk
= heap_alloc_zero(sizeof(*buffer_vk
))))
1242 return E_OUTOFMEMORY
;
1244 if (FAILED(hr
= wined3d_buffer_vk_init(buffer_vk
, device
, desc
, data
, parent
, parent_ops
)))
1246 WARN("Failed to initialise buffer, hr %#x.\n", hr
);
1247 heap_free(buffer_vk
);
1251 TRACE("Created buffer %p.\n", buffer_vk
);
1252 *buffer
= &buffer_vk
->b
;
1257 static void adapter_vk_destroy_buffer(struct wined3d_buffer
*buffer
)
1259 struct wined3d_buffer_vk
*buffer_vk
= wined3d_buffer_vk(buffer
);
1260 struct wined3d_device
*device
= buffer_vk
->b
.resource
.device
;
1261 unsigned int swapchain_count
= device
->swapchain_count
;
1263 TRACE("buffer_vk %p.\n", buffer_vk
);
1265 /* Take a reference to the device, in case releasing the buffer would
1266 * cause the device to be destroyed. However, swapchain resources don't
1267 * take a reference to the device, and we wouldn't want to increment the
1268 * refcount on a device that's in the process of being destroyed. */
1269 if (swapchain_count
)
1270 wined3d_device_incref(device
);
1271 wined3d_buffer_cleanup(&buffer_vk
->b
);
1272 wined3d_cs_destroy_object(device
->cs
, heap_free
, buffer_vk
);
1273 if (swapchain_count
)
1274 wined3d_device_decref(device
);
1277 static HRESULT
adapter_vk_create_texture(struct wined3d_device
*device
,
1278 const struct wined3d_resource_desc
*desc
, unsigned int layer_count
, unsigned int level_count
,
1279 uint32_t flags
, void *parent
, const struct wined3d_parent_ops
*parent_ops
, struct wined3d_texture
**texture
)
1281 struct wined3d_texture_vk
*texture_vk
;
1284 TRACE("device %p, desc %p, layer_count %u, level_count %u, flags %#x, parent %p, parent_ops %p, texture %p.\n",
1285 device
, desc
, layer_count
, level_count
, flags
, parent
, parent_ops
, texture
);
1287 if (!(texture_vk
= wined3d_texture_allocate_object_memory(sizeof(*texture_vk
), level_count
, layer_count
)))
1288 return E_OUTOFMEMORY
;
1290 if (FAILED(hr
= wined3d_texture_vk_init(texture_vk
, device
, desc
,
1291 layer_count
, level_count
, flags
, parent
, parent_ops
)))
1293 WARN("Failed to initialise texture, hr %#x.\n", hr
);
1294 heap_free(texture_vk
);
1298 TRACE("Created texture %p.\n", texture_vk
);
1299 *texture
= &texture_vk
->t
;
1304 static void adapter_vk_destroy_texture(struct wined3d_texture
*texture
)
1306 struct wined3d_texture_vk
*texture_vk
= wined3d_texture_vk(texture
);
1307 struct wined3d_device
*device
= texture_vk
->t
.resource
.device
;
1308 unsigned int swapchain_count
= device
->swapchain_count
;
1310 TRACE("texture_vk %p.\n", texture_vk
);
1312 /* Take a reference to the device, in case releasing the texture would
1313 * cause the device to be destroyed. However, swapchain resources don't
1314 * take a reference to the device, and we wouldn't want to increment the
1315 * refcount on a device that's in the process of being destroyed. */
1316 if (swapchain_count
)
1317 wined3d_device_incref(device
);
1319 wined3d_texture_sub_resources_destroyed(texture
);
1320 texture
->resource
.parent_ops
->wined3d_object_destroyed(texture
->resource
.parent
);
1322 wined3d_texture_cleanup(&texture_vk
->t
);
1323 wined3d_cs_destroy_object(device
->cs
, heap_free
, texture_vk
);
1325 if (swapchain_count
)
1326 wined3d_device_decref(device
);
1329 static HRESULT
adapter_vk_create_rendertarget_view(const struct wined3d_view_desc
*desc
,
1330 struct wined3d_resource
*resource
, void *parent
, const struct wined3d_parent_ops
*parent_ops
,
1331 struct wined3d_rendertarget_view
**view
)
1333 struct wined3d_rendertarget_view_vk
*view_vk
;
1336 TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n",
1337 wined3d_debug_view_desc(desc
, resource
), resource
, parent
, parent_ops
, view
);
1339 if (!(view_vk
= heap_alloc_zero(sizeof(*view_vk
))))
1340 return E_OUTOFMEMORY
;
1342 if (FAILED(hr
= wined3d_rendertarget_view_vk_init(view_vk
, desc
, resource
, parent
, parent_ops
)))
1344 WARN("Failed to initialise view, hr %#x.\n", hr
);
1349 TRACE("Created render target view %p.\n", view_vk
);
1350 *view
= &view_vk
->v
;
1355 struct wined3d_view_vk_destroy_ctx
1357 struct wined3d_device_vk
*device_vk
;
1358 VkBufferView
*vk_buffer_view
;
1359 VkImageView
*vk_image_view
;
1360 struct wined3d_bo_vk
*vk_counter_bo
;
1361 VkBufferView
*vk_counter_view
;
1362 uint64_t *command_buffer_id
;
1364 struct wined3d_view_vk_destroy_ctx
*free
;
1367 static void wined3d_view_vk_destroy_object(void *object
)
1369 struct wined3d_view_vk_destroy_ctx
*ctx
= object
;
1370 const struct wined3d_vk_info
*vk_info
;
1371 struct wined3d_device_vk
*device_vk
;
1372 struct wined3d_context
*context
;
1374 device_vk
= ctx
->device_vk
;
1375 vk_info
= &wined3d_adapter_vk(device_vk
->d
.adapter
)->vk_info
;
1376 context
= context_acquire(&device_vk
->d
, NULL
, 0);
1378 if (ctx
->vk_buffer_view
)
1382 wined3d_context_vk_destroy_buffer_view(wined3d_context_vk(context
),
1383 *ctx
->vk_buffer_view
, *ctx
->command_buffer_id
);
1387 VK_CALL(vkDestroyBufferView(device_vk
->vk_device
, *ctx
->vk_buffer_view
, NULL
));
1388 TRACE("Destroyed buffer view 0x%s.\n", wine_dbgstr_longlong(*ctx
->vk_buffer_view
));
1391 if (ctx
->vk_image_view
)
1395 wined3d_context_vk_destroy_image_view(wined3d_context_vk(context
),
1396 *ctx
->vk_image_view
, *ctx
->command_buffer_id
);
1400 VK_CALL(vkDestroyImageView(device_vk
->vk_device
, *ctx
->vk_image_view
, NULL
));
1401 TRACE("Destroyed image view 0x%s.\n", wine_dbgstr_longlong(*ctx
->vk_image_view
));
1404 if (ctx
->vk_counter_bo
&& ctx
->vk_counter_bo
->vk_buffer
)
1405 wined3d_context_vk_destroy_bo(wined3d_context_vk(context
), ctx
->vk_counter_bo
);
1406 if (ctx
->vk_counter_view
)
1410 wined3d_context_vk_destroy_buffer_view(wined3d_context_vk(context
),
1411 *ctx
->vk_counter_view
, *ctx
->command_buffer_id
);
1415 VK_CALL(vkDestroyBufferView(device_vk
->vk_device
, *ctx
->vk_counter_view
, NULL
));
1416 TRACE("Destroyed counter buffer view 0x%s.\n", wine_dbgstr_longlong(*ctx
->vk_counter_view
));
1421 context_release(context
);
1423 heap_free(ctx
->object
);
1424 heap_free(ctx
->free
);
1427 static void wined3d_view_vk_destroy(struct wined3d_device
*device
, VkBufferView
*vk_buffer_view
,
1428 VkImageView
*vk_image_view
, struct wined3d_bo_vk
*vk_counter_bo
,
1429 VkBufferView
*vk_counter_view
, uint64_t *command_buffer_id
, void *view_vk
)
1431 struct wined3d_view_vk_destroy_ctx
*ctx
, c
;
1433 if (!(ctx
= heap_alloc(sizeof(*ctx
))))
1435 ctx
->device_vk
= wined3d_device_vk(device
);
1436 ctx
->vk_buffer_view
= vk_buffer_view
;
1437 ctx
->vk_image_view
= vk_image_view
;
1438 ctx
->vk_counter_bo
= vk_counter_bo
;
1439 ctx
->vk_counter_view
= vk_counter_view
;
1440 ctx
->command_buffer_id
= command_buffer_id
;
1441 ctx
->object
= view_vk
;
1442 ctx
->free
= ctx
!= &c
? ctx
: NULL
;
1444 wined3d_cs_destroy_object(device
->cs
, wined3d_view_vk_destroy_object
, ctx
);
1446 device
->cs
->ops
->finish(device
->cs
, WINED3D_CS_QUEUE_DEFAULT
);
1449 static void adapter_vk_destroy_rendertarget_view(struct wined3d_rendertarget_view
*view
)
1451 struct wined3d_rendertarget_view_vk
*view_vk
= wined3d_rendertarget_view_vk(view
);
1452 struct wined3d_device
*device
= view_vk
->v
.resource
->device
;
1453 unsigned int swapchain_count
= device
->swapchain_count
;
1455 TRACE("view_vk %p.\n", view_vk
);
1457 /* Take a reference to the device, in case releasing the view's resource
1458 * would cause the device to be destroyed. However, swapchain resources
1459 * don't take a reference to the device, and we wouldn't want to increment
1460 * the refcount on a device that's in the process of being destroyed. */
1461 if (swapchain_count
)
1462 wined3d_device_incref(device
);
1463 wined3d_rendertarget_view_cleanup(&view_vk
->v
);
1464 wined3d_view_vk_destroy(device
, NULL
, &view_vk
->vk_image_view
,
1465 NULL
, NULL
, &view_vk
->command_buffer_id
, view_vk
);
1466 if (swapchain_count
)
1467 wined3d_device_decref(device
);
1470 static HRESULT
adapter_vk_create_shader_resource_view(const struct wined3d_view_desc
*desc
,
1471 struct wined3d_resource
*resource
, void *parent
, const struct wined3d_parent_ops
*parent_ops
,
1472 struct wined3d_shader_resource_view
**view
)
1474 struct wined3d_shader_resource_view_vk
*view_vk
;
1477 TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n",
1478 wined3d_debug_view_desc(desc
, resource
), resource
, parent
, parent_ops
, view
);
1480 if (!(view_vk
= heap_alloc_zero(sizeof(*view_vk
))))
1481 return E_OUTOFMEMORY
;
1483 if (FAILED(hr
= wined3d_shader_resource_view_vk_init(view_vk
, desc
, resource
, parent
, parent_ops
)))
1485 WARN("Failed to initialise view, hr %#x.\n", hr
);
1490 TRACE("Created shader resource view %p.\n", view_vk
);
1491 *view
= &view_vk
->v
;
1496 static void adapter_vk_destroy_shader_resource_view(struct wined3d_shader_resource_view
*view
)
1498 struct wined3d_shader_resource_view_vk
*srv_vk
= wined3d_shader_resource_view_vk(view
);
1499 struct wined3d_device
*device
= srv_vk
->v
.resource
->device
;
1500 unsigned int swapchain_count
= device
->swapchain_count
;
1501 struct wined3d_view_vk
*view_vk
= &srv_vk
->view_vk
;
1502 VkBufferView
*vk_buffer_view
= NULL
;
1503 VkImageView
*vk_image_view
= NULL
;
1505 TRACE("srv_vk %p.\n", srv_vk
);
1507 /* Take a reference to the device, in case releasing the view's resource
1508 * would cause the device to be destroyed. However, swapchain resources
1509 * don't take a reference to the device, and we wouldn't want to increment
1510 * the refcount on a device that's in the process of being destroyed. */
1511 if (swapchain_count
)
1512 wined3d_device_incref(device
);
1513 if (srv_vk
->v
.resource
->type
== WINED3D_RTYPE_BUFFER
)
1514 vk_buffer_view
= &view_vk
->u
.vk_buffer_view
;
1516 vk_image_view
= &view_vk
->u
.vk_image_info
.imageView
;
1517 list_remove(&view_vk
->bo_user
.entry
);
1518 wined3d_shader_resource_view_cleanup(&srv_vk
->v
);
1519 wined3d_view_vk_destroy(device
, vk_buffer_view
, vk_image_view
,
1520 NULL
, NULL
, &view_vk
->command_buffer_id
, srv_vk
);
1521 if (swapchain_count
)
1522 wined3d_device_decref(device
);
1525 static HRESULT
adapter_vk_create_unordered_access_view(const struct wined3d_view_desc
*desc
,
1526 struct wined3d_resource
*resource
, void *parent
, const struct wined3d_parent_ops
*parent_ops
,
1527 struct wined3d_unordered_access_view
**view
)
1529 struct wined3d_unordered_access_view_vk
*view_vk
;
1532 TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n",
1533 wined3d_debug_view_desc(desc
, resource
), resource
, parent
, parent_ops
, view
);
1535 if (!(view_vk
= heap_alloc_zero(sizeof(*view_vk
))))
1536 return E_OUTOFMEMORY
;
1538 if (FAILED(hr
= wined3d_unordered_access_view_vk_init(view_vk
, desc
, resource
, parent
, parent_ops
)))
1540 WARN("Failed to initialise view, hr %#x.\n", hr
);
1545 TRACE("Created unordered access view %p.\n", view_vk
);
1546 *view
= &view_vk
->v
;
1551 static void adapter_vk_destroy_unordered_access_view(struct wined3d_unordered_access_view
*view
)
1553 struct wined3d_unordered_access_view_vk
*uav_vk
= wined3d_unordered_access_view_vk(view
);
1554 struct wined3d_device
*device
= uav_vk
->v
.resource
->device
;
1555 unsigned int swapchain_count
= device
->swapchain_count
;
1556 struct wined3d_view_vk
*view_vk
= &uav_vk
->view_vk
;
1557 VkBufferView
*vk_buffer_view
= NULL
;
1558 VkImageView
*vk_image_view
= NULL
;
1560 TRACE("uav_vk %p.\n", uav_vk
);
1562 /* Take a reference to the device, in case releasing the view's resource
1563 * would cause the device to be destroyed. However, swapchain resources
1564 * don't take a reference to the device, and we wouldn't want to increment
1565 * the refcount on a device that's in the process of being destroyed. */
1566 if (swapchain_count
)
1567 wined3d_device_incref(device
);
1568 if (uav_vk
->v
.resource
->type
== WINED3D_RTYPE_BUFFER
)
1569 vk_buffer_view
= &view_vk
->u
.vk_buffer_view
;
1571 vk_image_view
= &view_vk
->u
.vk_image_info
.imageView
;
1572 list_remove(&view_vk
->bo_user
.entry
);
1573 wined3d_unordered_access_view_cleanup(&uav_vk
->v
);
1574 wined3d_view_vk_destroy(device
, vk_buffer_view
, vk_image_view
, &uav_vk
->counter_bo
,
1575 &uav_vk
->vk_counter_view
, &view_vk
->command_buffer_id
, uav_vk
);
1576 if (swapchain_count
)
1577 wined3d_device_decref(device
);
1580 static HRESULT
adapter_vk_create_sampler(struct wined3d_device
*device
, const struct wined3d_sampler_desc
*desc
,
1581 void *parent
, const struct wined3d_parent_ops
*parent_ops
, struct wined3d_sampler
**sampler
)
1583 struct wined3d_sampler_vk
*sampler_vk
;
1585 TRACE("device %p, desc %p, parent %p, parent_ops %p, sampler %p.\n",
1586 device
, desc
, parent
, parent_ops
, sampler
);
1588 if (!(sampler_vk
= heap_alloc_zero(sizeof(*sampler_vk
))))
1589 return E_OUTOFMEMORY
;
1591 wined3d_sampler_vk_init(sampler_vk
, device
, desc
, parent
, parent_ops
);
1593 TRACE("Created sampler %p.\n", sampler_vk
);
1594 *sampler
= &sampler_vk
->s
;
1599 static void wined3d_sampler_vk_destroy_object(void *object
)
1601 struct wined3d_sampler_vk
*sampler_vk
= object
;
1602 struct wined3d_context_vk
*context_vk
;
1604 context_vk
= wined3d_context_vk(context_acquire(sampler_vk
->s
.device
, NULL
, 0));
1606 wined3d_context_vk_destroy_sampler(context_vk
, sampler_vk
->vk_image_info
.sampler
, sampler_vk
->command_buffer_id
);
1607 heap_free(sampler_vk
);
1609 context_release(&context_vk
->c
);
1612 static void adapter_vk_destroy_sampler(struct wined3d_sampler
*sampler
)
1614 struct wined3d_sampler_vk
*sampler_vk
= wined3d_sampler_vk(sampler
);
1616 TRACE("sampler_vk %p.\n", sampler_vk
);
1618 wined3d_cs_destroy_object(sampler
->device
->cs
, wined3d_sampler_vk_destroy_object
, sampler_vk
);
1621 static HRESULT
adapter_vk_create_query(struct wined3d_device
*device
, enum wined3d_query_type type
,
1622 void *parent
, const struct wined3d_parent_ops
*parent_ops
, struct wined3d_query
**query
)
1624 TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n",
1625 device
, type
, parent
, parent_ops
, query
);
1627 return wined3d_query_vk_create(device
, type
, parent
, parent_ops
, query
);
1630 static void wined3d_query_vk_destroy_object(void *object
)
1632 struct wined3d_query_vk
*query_vk
= object
;
1634 query_vk
->q
.query_ops
->query_destroy(&query_vk
->q
);
1637 static void adapter_vk_destroy_query(struct wined3d_query
*query
)
1639 struct wined3d_query_vk
*query_vk
= wined3d_query_vk(query
);
1641 TRACE("query_vk %p.\n", query_vk
);
1643 wined3d_cs_destroy_object(query
->device
->cs
, wined3d_query_vk_destroy_object
, query_vk
);
1646 static void adapter_vk_flush_context(struct wined3d_context
*context
)
1648 struct wined3d_context_vk
*context_vk
= wined3d_context_vk(context
);
1650 TRACE("context_vk %p.\n", context_vk
);
1652 wined3d_context_vk_submit_command_buffer(context_vk
, 0, NULL
, NULL
, 0, NULL
);
1655 static void adapter_vk_draw_primitive(struct wined3d_device
*device
,
1656 const struct wined3d_state
*state
, const struct wined3d_draw_parameters
*parameters
)
1658 struct wined3d_buffer_vk
*indirect_vk
= NULL
;
1659 const struct wined3d_vk_info
*vk_info
;
1660 struct wined3d_context_vk
*context_vk
;
1661 VkCommandBuffer vk_command_buffer
;
1662 uint32_t instance_count
;
1664 TRACE("device %p, state %p, parameters %p.\n", device
, state
, parameters
);
1666 context_vk
= wined3d_context_vk(context_acquire(device
, NULL
, 0));
1667 vk_info
= context_vk
->vk_info
;
1669 if (parameters
->indirect
)
1670 indirect_vk
= wined3d_buffer_vk(parameters
->u
.indirect
.buffer
);
1672 if (!(vk_command_buffer
= wined3d_context_vk_apply_draw_state(context_vk
,
1673 state
, indirect_vk
, parameters
->indexed
)))
1675 ERR("Failed to apply draw state.\n");
1676 context_release(&context_vk
->c
);
1680 if (parameters
->indirect
)
1682 struct wined3d_bo_vk
*bo
= &indirect_vk
->bo
;
1683 uint32_t stride
, size
;
1685 wined3d_context_vk_reference_bo(context_vk
, bo
);
1686 size
= indirect_vk
->b
.resource
.size
- parameters
->u
.indirect
.offset
;
1688 if (parameters
->indexed
)
1690 stride
= sizeof(VkDrawIndexedIndirectCommand
);
1691 VK_CALL(vkCmdDrawIndexedIndirect(vk_command_buffer
, bo
->vk_buffer
,
1692 bo
->buffer_offset
+ parameters
->u
.indirect
.offset
, size
/ stride
, stride
));
1696 stride
= sizeof(VkDrawIndirectCommand
);
1697 VK_CALL(vkCmdDrawIndirect(vk_command_buffer
, bo
->vk_buffer
,
1698 bo
->buffer_offset
+ parameters
->u
.indirect
.offset
, size
/ stride
, stride
));
1703 instance_count
= parameters
->u
.direct
.instance_count
;
1704 if (context_vk
->c
.instance_count
)
1705 instance_count
= context_vk
->c
.instance_count
;
1706 if (!instance_count
)
1709 if (parameters
->indexed
)
1710 VK_CALL(vkCmdDrawIndexed(vk_command_buffer
, parameters
->u
.direct
.index_count
,
1711 instance_count
, parameters
->u
.direct
.start_idx
, parameters
->u
.direct
.base_vertex_idx
,
1712 parameters
->u
.direct
.start_instance
));
1714 VK_CALL(vkCmdDraw(vk_command_buffer
, parameters
->u
.direct
.index_count
, instance_count
,
1715 parameters
->u
.direct
.start_idx
, parameters
->u
.direct
.start_instance
));
1718 context_release(&context_vk
->c
);
1721 static void adapter_vk_dispatch_compute(struct wined3d_device
*device
,
1722 const struct wined3d_state
*state
, const struct wined3d_dispatch_parameters
*parameters
)
1724 struct wined3d_buffer_vk
*indirect_vk
= NULL
;
1725 const struct wined3d_vk_info
*vk_info
;
1726 struct wined3d_context_vk
*context_vk
;
1727 VkCommandBuffer vk_command_buffer
;
1729 TRACE("device %p, state %p, parameters %p.\n", device
, state
, parameters
);
1731 context_vk
= wined3d_context_vk(context_acquire(device
, NULL
, 0));
1732 vk_info
= context_vk
->vk_info
;
1734 if (parameters
->indirect
)
1735 indirect_vk
= wined3d_buffer_vk(parameters
->u
.indirect
.buffer
);
1737 if (!(vk_command_buffer
= wined3d_context_vk_apply_compute_state(context_vk
, state
, indirect_vk
)))
1739 ERR("Failed to apply compute state.\n");
1740 context_release(&context_vk
->c
);
1744 if (parameters
->indirect
)
1746 struct wined3d_bo_vk
*bo
= &indirect_vk
->bo
;
1748 wined3d_context_vk_reference_bo(context_vk
, bo
);
1749 VK_CALL(vkCmdDispatchIndirect(vk_command_buffer
, bo
->vk_buffer
,
1750 bo
->buffer_offset
+ parameters
->u
.indirect
.offset
));
1754 const struct wined3d_direct_dispatch_parameters
*direct
= ¶meters
->u
.direct
;
1756 VK_CALL(vkCmdDispatch(vk_command_buffer
, direct
->group_count_x
, direct
->group_count_y
, direct
->group_count_z
));
1759 VK_CALL(vkCmdPipelineBarrier(vk_command_buffer
, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
,
1760 VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT
, 0, 0, NULL
, 0, NULL
, 0, NULL
));
1762 context_release(&context_vk
->c
);
1765 void adapter_vk_clear_uav(struct wined3d_context
*context
,
1766 struct wined3d_unordered_access_view
*view
, const struct wined3d_uvec4
*clear_value
)
1768 TRACE("context %p, view %p, clear_value %s.\n", context
, view
, debug_uvec4(clear_value
));
1770 wined3d_unordered_access_view_vk_clear_uint(wined3d_unordered_access_view_vk(view
),
1771 clear_value
, wined3d_context_vk(context
));
1774 static const struct wined3d_adapter_ops wined3d_adapter_vk_ops
=
1776 .adapter_destroy
= adapter_vk_destroy
,
1777 .adapter_create_device
= adapter_vk_create_device
,
1778 .adapter_destroy_device
= adapter_vk_destroy_device
,
1779 .adapter_acquire_context
= adapter_vk_acquire_context
,
1780 .adapter_release_context
= adapter_vk_release_context
,
1781 .adapter_get_wined3d_caps
= adapter_vk_get_wined3d_caps
,
1782 .adapter_check_format
= adapter_vk_check_format
,
1783 .adapter_init_3d
= adapter_vk_init_3d
,
1784 .adapter_uninit_3d
= adapter_vk_uninit_3d
,
1785 .adapter_map_bo_address
= adapter_vk_map_bo_address
,
1786 .adapter_unmap_bo_address
= adapter_vk_unmap_bo_address
,
1787 .adapter_copy_bo_address
= adapter_vk_copy_bo_address
,
1788 .adapter_create_swapchain
= adapter_vk_create_swapchain
,
1789 .adapter_destroy_swapchain
= adapter_vk_destroy_swapchain
,
1790 .adapter_create_buffer
= adapter_vk_create_buffer
,
1791 .adapter_destroy_buffer
= adapter_vk_destroy_buffer
,
1792 .adapter_create_texture
= adapter_vk_create_texture
,
1793 .adapter_destroy_texture
= adapter_vk_destroy_texture
,
1794 .adapter_create_rendertarget_view
= adapter_vk_create_rendertarget_view
,
1795 .adapter_destroy_rendertarget_view
= adapter_vk_destroy_rendertarget_view
,
1796 .adapter_create_shader_resource_view
= adapter_vk_create_shader_resource_view
,
1797 .adapter_destroy_shader_resource_view
= adapter_vk_destroy_shader_resource_view
,
1798 .adapter_create_unordered_access_view
= adapter_vk_create_unordered_access_view
,
1799 .adapter_destroy_unordered_access_view
= adapter_vk_destroy_unordered_access_view
,
1800 .adapter_create_sampler
= adapter_vk_create_sampler
,
1801 .adapter_destroy_sampler
= adapter_vk_destroy_sampler
,
1802 .adapter_create_query
= adapter_vk_create_query
,
1803 .adapter_destroy_query
= adapter_vk_destroy_query
,
1804 .adapter_flush_context
= adapter_vk_flush_context
,
1805 .adapter_draw_primitive
= adapter_vk_draw_primitive
,
1806 .adapter_dispatch_compute
= adapter_vk_dispatch_compute
,
1807 .adapter_clear_uav
= adapter_vk_clear_uav
,
1810 static unsigned int wined3d_get_wine_vk_version(void)
1812 const char *ptr
= PACKAGE_VERSION
;
1817 while (isdigit(*ptr
))
1824 return VK_MAKE_VERSION(major
, minor
, 0);
1830 unsigned int core_since_version
;
1833 vulkan_instance_extensions
[] =
1835 {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME
, VK_API_VERSION_1_1
, FALSE
},
1836 {VK_KHR_SURFACE_EXTENSION_NAME
, ~0u, TRUE
},
1837 {VK_KHR_WIN32_SURFACE_EXTENSION_NAME
, ~0u, TRUE
},
1840 static BOOL
enable_vulkan_instance_extensions(uint32_t *extension_count
,
1841 const char *enabled_extensions
[], const struct wined3d_vk_info
*vk_info
)
1843 PFN_vkEnumerateInstanceExtensionProperties pfn_vkEnumerateInstanceExtensionProperties
;
1844 VkExtensionProperties
*extensions
= NULL
;
1845 BOOL success
= FALSE
, found
;
1846 unsigned int i
, j
, count
;
1849 *extension_count
= 0;
1851 if (!(pfn_vkEnumerateInstanceExtensionProperties
1852 = (void *)VK_CALL(vkGetInstanceProcAddr(NULL
, "vkEnumerateInstanceExtensionProperties"))))
1854 WARN("Failed to get 'vkEnumerateInstanceExtensionProperties'.\n");
1858 if ((vr
= pfn_vkEnumerateInstanceExtensionProperties(NULL
, &count
, NULL
)) < 0)
1860 WARN("Failed to count instance extensions, vr %s.\n", wined3d_debug_vkresult(vr
));
1863 if (!(extensions
= heap_calloc(count
, sizeof(*extensions
))))
1865 WARN("Out of memory.\n");
1868 if ((vr
= pfn_vkEnumerateInstanceExtensionProperties(NULL
, &count
, extensions
)) < 0)
1870 WARN("Failed to enumerate extensions, vr %s.\n", wined3d_debug_vkresult(vr
));
1874 for (i
= 0; i
< ARRAY_SIZE(vulkan_instance_extensions
); ++i
)
1876 if (vulkan_instance_extensions
[i
].core_since_version
<= vk_info
->api_version
)
1879 for (j
= 0, found
= FALSE
; j
< count
; ++j
)
1881 if (!strcmp(extensions
[j
].extensionName
, vulkan_instance_extensions
[i
].name
))
1889 TRACE("Enabling instance extension '%s'.\n", vulkan_instance_extensions
[i
].name
);
1890 enabled_extensions
[(*extension_count
)++] = vulkan_instance_extensions
[i
].name
;
1892 else if (!found
&& vulkan_instance_extensions
[i
].required
)
1894 WARN("Required extension '%s' is not available.\n", vulkan_instance_extensions
[i
].name
);
1901 heap_free(extensions
);
1905 static BOOL
wined3d_init_vulkan(struct wined3d_vk_info
*vk_info
)
1907 const char *enabled_instance_extensions
[ARRAY_SIZE(vulkan_instance_extensions
)];
1908 PFN_vkEnumerateInstanceVersion pfn_vkEnumerateInstanceVersion
;
1909 struct vulkan_ops
*vk_ops
= &vk_info
->vk_ops
;
1910 VkInstance instance
= VK_NULL_HANDLE
;
1911 VkInstanceCreateInfo instance_info
;
1912 VkApplicationInfo app_info
;
1913 uint32_t api_version
= 0;
1914 char app_name
[MAX_PATH
];
1917 if (!wined3d_load_vulkan(vk_info
))
1920 if (!(vk_ops
->vkCreateInstance
= (void *)VK_CALL(vkGetInstanceProcAddr(NULL
, "vkCreateInstance"))))
1922 ERR("Failed to get 'vkCreateInstance'.\n");
1926 vk_info
->api_version
= VK_API_VERSION_1_0
;
1927 if ((pfn_vkEnumerateInstanceVersion
= (void *)VK_CALL(vkGetInstanceProcAddr(NULL
, "vkEnumerateInstanceVersion")))
1928 && pfn_vkEnumerateInstanceVersion(&api_version
) == VK_SUCCESS
)
1930 TRACE("Vulkan instance API version %s.\n", debug_vk_version(api_version
));
1932 if (api_version
>= VK_API_VERSION_1_1
)
1933 vk_info
->api_version
= VK_API_VERSION_1_1
;
1936 memset(&app_info
, 0, sizeof(app_info
));
1937 app_info
.sType
= VK_STRUCTURE_TYPE_APPLICATION_INFO
;
1938 if (wined3d_get_app_name(app_name
, ARRAY_SIZE(app_name
)))
1939 app_info
.pApplicationName
= app_name
;
1940 app_info
.pEngineName
= "Damavand";
1941 app_info
.engineVersion
= wined3d_get_wine_vk_version();
1942 app_info
.apiVersion
= vk_info
->api_version
;
1944 memset(&instance_info
, 0, sizeof(instance_info
));
1945 instance_info
.sType
= VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO
;
1946 instance_info
.pApplicationInfo
= &app_info
;
1947 instance_info
.ppEnabledExtensionNames
= enabled_instance_extensions
;
1948 if (!enable_vulkan_instance_extensions(&instance_info
.enabledExtensionCount
, enabled_instance_extensions
, vk_info
))
1951 memset(vk_info
->supported
, 0, sizeof(vk_info
->supported
));
1952 vk_info
->supported
[WINED3D_VK_EXT_NONE
] = TRUE
;
1954 if ((vr
= VK_CALL(vkCreateInstance(&instance_info
, NULL
, &instance
))) < 0)
1956 WARN("Failed to create Vulkan instance, vr %s.\n", wined3d_debug_vkresult(vr
));
1960 TRACE("Created Vulkan instance %p.\n", instance
);
1962 #define LOAD_INSTANCE_PFN(name) \
1963 if (!(vk_ops->name = (void *)VK_CALL(vkGetInstanceProcAddr(instance, #name)))) \
1965 WARN("Could not get instance proc addr for '" #name "'.\n"); \
1968 #define LOAD_INSTANCE_OPT_PFN(name) \
1969 vk_ops->name = (void *)VK_CALL(vkGetInstanceProcAddr(instance, #name));
1970 #define VK_INSTANCE_PFN LOAD_INSTANCE_PFN
1971 #define VK_INSTANCE_EXT_PFN LOAD_INSTANCE_OPT_PFN
1972 #define VK_DEVICE_PFN LOAD_INSTANCE_PFN
1975 #undef VK_INSTANCE_PFN
1976 #undef VK_INSTANCE_EXT_PFN
1977 #undef VK_DEVICE_PFN
1979 #define MAP_INSTANCE_FUNCTION(core_pfn, ext_pfn) \
1980 if (!vk_ops->core_pfn) \
1981 vk_ops->core_pfn = (void *)VK_CALL(vkGetInstanceProcAddr(instance, #ext_pfn));
1982 MAP_INSTANCE_FUNCTION(vkGetPhysicalDeviceProperties2
, vkGetPhysicalDeviceProperties2KHR
)
1983 MAP_INSTANCE_FUNCTION(vkGetPhysicalDeviceFeatures2
, vkGetPhysicalDeviceFeatures2KHR
)
1984 #undef MAP_INSTANCE_FUNCTION
1986 vk_info
->instance
= instance
;
1991 if (vk_ops
->vkDestroyInstance
)
1992 VK_CALL(vkDestroyInstance(instance
, NULL
));
1993 wined3d_unload_vulkan(vk_info
);
1997 static VkPhysicalDevice
get_vulkan_physical_device(struct wined3d_vk_info
*vk_info
)
1999 VkPhysicalDevice physical_devices
[1];
2003 if ((vr
= VK_CALL(vkEnumeratePhysicalDevices(vk_info
->instance
, &count
, NULL
))) < 0)
2005 WARN("Failed to enumerate physical devices, vr %s.\n", wined3d_debug_vkresult(vr
));
2006 return VK_NULL_HANDLE
;
2010 WARN("No physical device.\n");
2011 return VK_NULL_HANDLE
;
2015 /* TODO: Create wined3d_adapter for each device. */
2016 FIXME("Multiple physical devices available.\n");
2020 if ((vr
= VK_CALL(vkEnumeratePhysicalDevices(vk_info
->instance
, &count
, physical_devices
))) < 0)
2022 WARN("Failed to get physical devices, vr %s.\n", wined3d_debug_vkresult(vr
));
2023 return VK_NULL_HANDLE
;
2026 return physical_devices
[0];
2029 static enum wined3d_display_driver
guess_display_driver(enum wined3d_pci_vendor vendor
)
2033 case HW_VENDOR_AMD
: return DRIVER_AMD_RX
;
2034 case HW_VENDOR_INTEL
: return DRIVER_INTEL_HD4000
;
2035 case HW_VENDOR_NVIDIA
: return DRIVER_NVIDIA_GEFORCE8
;
2036 default: return DRIVER_WINE
;
2040 static void adapter_vk_init_driver_info(struct wined3d_adapter_vk
*adapter_vk
,
2041 const VkPhysicalDeviceProperties
*properties
)
2043 const VkPhysicalDeviceMemoryProperties
*memory_properties
= &adapter_vk
->memory_properties
;
2044 const struct wined3d_gpu_description
*gpu_description
;
2045 struct wined3d_gpu_description description
;
2046 UINT64 vram_bytes
, sysmem_bytes
;
2047 const VkMemoryHeap
*heap
;
2050 TRACE("Device name: %s.\n", debugstr_a(properties
->deviceName
));
2051 TRACE("Vendor ID: 0x%04x, Device ID: 0x%04x.\n", properties
->vendorID
, properties
->deviceID
);
2052 TRACE("Driver version: %#x.\n", properties
->driverVersion
);
2053 TRACE("API version: %s.\n", debug_vk_version(properties
->apiVersion
));
2055 for (i
= 0, vram_bytes
= 0, sysmem_bytes
= 0; i
< memory_properties
->memoryHeapCount
; ++i
)
2057 heap
= &memory_properties
->memoryHeaps
[i
];
2058 TRACE("Memory heap [%u]: flags %#x, size 0x%s.\n",
2059 i
, heap
->flags
, wine_dbgstr_longlong(heap
->size
));
2060 if (heap
->flags
& VK_MEMORY_HEAP_DEVICE_LOCAL_BIT
)
2061 vram_bytes
+= heap
->size
;
2063 sysmem_bytes
+= heap
->size
;
2065 TRACE("Total device memory: 0x%s.\n", wine_dbgstr_longlong(vram_bytes
));
2066 TRACE("Total shared system memory: 0x%s.\n", wine_dbgstr_longlong(sysmem_bytes
));
2068 if (!(gpu_description
= wined3d_get_user_override_gpu_description(properties
->vendorID
, properties
->deviceID
)))
2069 gpu_description
= wined3d_get_gpu_description(properties
->vendorID
, properties
->deviceID
);
2071 if (!gpu_description
)
2073 FIXME("Failed to retrieve GPU description for device %s %04x:%04x.\n",
2074 debugstr_a(properties
->deviceName
), properties
->vendorID
, properties
->deviceID
);
2076 description
.vendor
= properties
->vendorID
;
2077 description
.device
= properties
->deviceID
;
2078 description
.description
= properties
->deviceName
;
2079 description
.driver
= guess_display_driver(properties
->vendorID
);
2080 description
.vidmem
= vram_bytes
;
2082 gpu_description
= &description
;
2085 wined3d_driver_info_init(&adapter_vk
->a
.driver_info
, gpu_description
, vram_bytes
, sysmem_bytes
);
2088 static enum wined3d_feature_level
feature_level_from_caps(const struct shader_caps
*shader_caps
)
2090 unsigned int shader_model
;
2092 shader_model
= min(shader_caps
->vs_version
, shader_caps
->ps_version
);
2093 shader_model
= min(shader_model
, max(shader_caps
->gs_version
, 3));
2094 shader_model
= min(shader_model
, max(shader_caps
->hs_version
, 4));
2095 shader_model
= min(shader_model
, max(shader_caps
->ds_version
, 4));
2097 if (shader_model
>= 5)
2098 return WINED3D_FEATURE_LEVEL_11_1
;
2100 if (shader_model
>= 4)
2101 return WINED3D_FEATURE_LEVEL_10_1
;
2103 return WINED3D_FEATURE_LEVEL_NONE
;
2106 static void wined3d_adapter_vk_init_d3d_info(struct wined3d_adapter_vk
*adapter_vk
, uint32_t wined3d_creation_flags
)
2108 struct wined3d_d3d_info
*d3d_info
= &adapter_vk
->a
.d3d_info
;
2109 struct wined3d_vertex_caps vertex_caps
;
2110 struct fragment_caps fragment_caps
;
2111 struct shader_caps shader_caps
;
2113 adapter_vk
->a
.shader_backend
->shader_get_caps(&adapter_vk
->a
, &shader_caps
);
2114 adapter_vk
->a
.vertex_pipe
->vp_get_caps(&adapter_vk
->a
, &vertex_caps
);
2115 adapter_vk
->a
.fragment_pipe
->get_caps(&adapter_vk
->a
, &fragment_caps
);
2117 d3d_info
->limits
.vs_version
= shader_caps
.vs_version
;
2118 d3d_info
->limits
.hs_version
= shader_caps
.hs_version
;
2119 d3d_info
->limits
.ds_version
= shader_caps
.ds_version
;
2120 d3d_info
->limits
.gs_version
= shader_caps
.gs_version
;
2121 d3d_info
->limits
.ps_version
= shader_caps
.ps_version
;
2122 d3d_info
->limits
.cs_version
= shader_caps
.cs_version
;
2123 d3d_info
->limits
.vs_uniform_count
= shader_caps
.vs_uniform_count
;
2124 d3d_info
->limits
.ps_uniform_count
= shader_caps
.ps_uniform_count
;
2125 d3d_info
->limits
.varying_count
= shader_caps
.varying_count
;
2126 d3d_info
->limits
.ffp_textures
= fragment_caps
.MaxSimultaneousTextures
;
2127 d3d_info
->limits
.ffp_blend_stages
= fragment_caps
.MaxTextureBlendStages
;
2128 d3d_info
->limits
.ffp_vertex_blend_matrices
= vertex_caps
.max_vertex_blend_matrices
;
2129 d3d_info
->limits
.active_light_count
= vertex_caps
.max_active_lights
;
2131 d3d_info
->limits
.max_rt_count
= WINED3D_MAX_RENDER_TARGETS
;
2132 d3d_info
->limits
.max_clip_distances
= WINED3D_MAX_CLIP_DISTANCES
;
2133 d3d_info
->limits
.texture_size
= adapter_vk
->device_limits
.maxImageDimension2D
;
2134 d3d_info
->limits
.pointsize_max
= adapter_vk
->device_limits
.pointSizeRange
[1];
2136 d3d_info
->wined3d_creation_flags
= wined3d_creation_flags
;
2138 d3d_info
->xyzrhw
= vertex_caps
.xyzrhw
;
2139 d3d_info
->emulated_flatshading
= vertex_caps
.emulated_flatshading
;
2140 d3d_info
->ffp_generic_attributes
= vertex_caps
.ffp_generic_attributes
;
2141 d3d_info
->ffp_alpha_test
= false;
2142 d3d_info
->vs_clipping
= !!(shader_caps
.wined3d_caps
& WINED3D_SHADER_CAP_VS_CLIPPING
);
2143 d3d_info
->shader_color_key
= !!(fragment_caps
.wined3d_caps
& WINED3D_FRAGMENT_CAP_COLOR_KEY
);
2144 d3d_info
->shader_double_precision
= !!(shader_caps
.wined3d_caps
& WINED3D_SHADER_CAP_DOUBLE_PRECISION
);
2145 d3d_info
->shader_output_interpolation
= !!(shader_caps
.wined3d_caps
& WINED3D_SHADER_CAP_OUTPUT_INTERPOLATION
);
2146 d3d_info
->viewport_array_index_any_shader
= false; /* VK_EXT_shader_viewport_index_layer */
2147 d3d_info
->texture_npot
= true;
2148 d3d_info
->texture_npot_conditional
= true;
2149 d3d_info
->draw_base_vertex_offset
= true;
2150 d3d_info
->vertex_bgra
= true;
2151 d3d_info
->texture_swizzle
= true;
2152 d3d_info
->srgb_read_control
= false;
2153 d3d_info
->srgb_write_control
= false;
2154 d3d_info
->clip_control
= true;
2155 d3d_info
->full_ffp_varyings
= !!(shader_caps
.wined3d_caps
& WINED3D_SHADER_CAP_FULL_FFP_VARYINGS
);
2156 d3d_info
->scaled_resolve
= false;
2157 d3d_info
->feature_level
= feature_level_from_caps(&shader_caps
);
2159 d3d_info
->multisample_draw_location
= WINED3D_LOCATION_TEXTURE_RGB
;
2162 static BOOL
wined3d_adapter_vk_init(struct wined3d_adapter_vk
*adapter_vk
,
2163 unsigned int ordinal
, unsigned int wined3d_creation_flags
)
2165 struct wined3d_vk_info
*vk_info
= &adapter_vk
->vk_info
;
2166 struct wined3d_adapter
*adapter
= &adapter_vk
->a
;
2167 VkPhysicalDeviceIDProperties id_properties
;
2168 VkPhysicalDeviceProperties2 properties2
;
2170 TRACE("adapter_vk %p, ordinal %u, wined3d_creation_flags %#x.\n",
2171 adapter_vk
, ordinal
, wined3d_creation_flags
);
2173 if (!wined3d_adapter_init(adapter
, ordinal
, &wined3d_adapter_vk_ops
))
2176 if (!wined3d_init_vulkan(vk_info
))
2178 WARN("Failed to initialize Vulkan.\n");
2182 if (!(adapter_vk
->physical_device
= get_vulkan_physical_device(vk_info
)))
2185 memset(&id_properties
, 0, sizeof(id_properties
));
2186 id_properties
.sType
= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES
;
2187 properties2
.sType
= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2
;
2188 properties2
.pNext
= &id_properties
;
2190 if (vk_info
->vk_ops
.vkGetPhysicalDeviceProperties2
)
2191 VK_CALL(vkGetPhysicalDeviceProperties2(adapter_vk
->physical_device
, &properties2
));
2193 VK_CALL(vkGetPhysicalDeviceProperties(adapter_vk
->physical_device
, &properties2
.properties
));
2194 adapter_vk
->device_limits
= properties2
.properties
.limits
;
2196 VK_CALL(vkGetPhysicalDeviceMemoryProperties(adapter_vk
->physical_device
, &adapter_vk
->memory_properties
));
2198 adapter_vk_init_driver_info(adapter_vk
, &properties2
.properties
);
2199 adapter
->vram_bytes_used
= 0;
2200 TRACE("Emulating 0x%s bytes of video ram.\n", wine_dbgstr_longlong(adapter
->driver_info
.vram_bytes
));
2202 memcpy(&adapter
->driver_uuid
, id_properties
.driverUUID
, sizeof(adapter
->driver_uuid
));
2203 memcpy(&adapter
->device_uuid
, id_properties
.deviceUUID
, sizeof(adapter
->device_uuid
));
2205 if (!wined3d_adapter_vk_init_format_info(adapter_vk
, vk_info
))
2208 adapter
->vertex_pipe
= wined3d_spirv_vertex_pipe_init_vk();
2209 adapter
->fragment_pipe
= wined3d_spirv_fragment_pipe_init_vk();
2210 adapter
->misc_state_template
= misc_state_template_vk
;
2211 adapter
->shader_backend
= wined3d_spirv_shader_backend_init_vk();
2213 wined3d_adapter_vk_init_d3d_info(adapter_vk
, wined3d_creation_flags
);
2218 VK_CALL(vkDestroyInstance(vk_info
->instance
, NULL
));
2219 wined3d_unload_vulkan(vk_info
);
2221 wined3d_adapter_cleanup(adapter
);
2225 struct wined3d_adapter
*wined3d_adapter_vk_create(unsigned int ordinal
,
2226 unsigned int wined3d_creation_flags
)
2228 struct wined3d_adapter_vk
*adapter_vk
;
2230 if (!(adapter_vk
= heap_alloc_zero(sizeof(*adapter_vk
))))
2233 if (!wined3d_adapter_vk_init(adapter_vk
, ordinal
, wined3d_creation_flags
))
2235 heap_free(adapter_vk
);
2239 TRACE("Created adapter %p.\n", adapter_vk
);
2241 return &adapter_vk
->a
;