include: Add ID2D1PathGeometry1 definition.
[wine.git] / dlls / wined3d / adapter_vk.c
blobcd1748afe90c1ebe7eb4d096c1ed98aebee78896
1 /*
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
19 #include "wined3d_private.h"
21 #include "wine/vulkan_driver.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
25 static const struct wined3d_state_entry_template misc_state_template_vk[] =
27 {STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX), {STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX), state_nop}},
28 {STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_HULL), {STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_HULL), state_nop}},
29 {STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_DOMAIN), {STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_DOMAIN), state_nop}},
30 {STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_GEOMETRY), {STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_GEOMETRY), state_nop}},
31 {STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL), {STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL), state_nop}},
32 {STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_COMPUTE), {STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_COMPUTE), state_nop}},
33 {STATE_GRAPHICS_SHADER_RESOURCE_BINDING, {STATE_GRAPHICS_SHADER_RESOURCE_BINDING, state_nop}},
34 {STATE_GRAPHICS_UNORDERED_ACCESS_VIEW_BINDING, {STATE_GRAPHICS_UNORDERED_ACCESS_VIEW_BINDING, state_nop}},
35 {STATE_COMPUTE_SHADER_RESOURCE_BINDING, {STATE_COMPUTE_SHADER_RESOURCE_BINDING, state_nop}},
36 {STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING, {STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING, state_nop}},
37 {STATE_STREAM_OUTPUT, {STATE_STREAM_OUTPUT, state_nop}},
38 {STATE_BLEND, {STATE_BLEND, state_nop}},
39 {STATE_BLEND_FACTOR, {STATE_BLEND_FACTOR, state_nop}},
40 {STATE_SAMPLE_MASK, {STATE_SAMPLE_MASK, state_nop}},
41 {STATE_STREAMSRC, {STATE_STREAMSRC, state_nop}},
42 {STATE_VDECL, {STATE_VDECL, state_nop}},
43 {STATE_DEPTH_STENCIL, {STATE_DEPTH_STENCIL, state_nop}},
44 {STATE_STENCIL_REF, {STATE_STENCIL_REF, state_nop}},
45 {STATE_RASTERIZER, {STATE_RASTERIZER, state_nop}},
46 {STATE_SCISSORRECT, {STATE_SCISSORRECT, state_nop}},
47 {STATE_POINTSPRITECOORDORIGIN, {STATE_POINTSPRITECOORDORIGIN, state_nop}},
49 {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), state_nop}},
50 {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT01), {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00)}},
51 {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT10), {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00)}},
52 {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT11), {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00)}},
53 {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), state_nop}},
54 {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT01), {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00)}},
55 {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT10), {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00)}},
56 {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT11), {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00)}},
57 {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), state_nop}},
58 {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT01), {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00)}},
59 {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT10), {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00)}},
60 {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT11), {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00)}},
61 {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), state_nop}},
62 {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT01), {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00)}},
63 {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT10), {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00)}},
64 {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT11), {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00)}},
65 {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), state_nop}},
66 {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT01), {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00)}},
67 {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT10), {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00)}},
68 {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT11), {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00)}},
69 {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), state_nop}},
70 {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT01), {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00)}},
71 {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT10), {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00)}},
72 {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT11), {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00)}},
73 {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), state_nop}},
74 {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT01), {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00)}},
75 {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT10), {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00)}},
76 {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT11), {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00)}},
77 {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), state_nop}},
78 {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT01), {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00)}},
79 {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT10), {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00)}},
80 {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT11), {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00)}},
81 {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), state_nop}},
82 {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE)}},
83 {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), state_nop}},
84 {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE)}},
85 {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), state_nop}},
86 {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE)}},
87 {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), state_nop}},
88 {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE)}},
89 {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), state_nop}},
90 {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE)}},
91 {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), state_nop}},
92 {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE)}},
93 {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), state_nop}},
94 {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE)}},
95 {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), state_nop}},
96 {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LOFFSET), {STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE)}},
98 {STATE_VIEWPORT, {STATE_VIEWPORT, state_nop}},
99 {STATE_INDEXBUFFER, {STATE_INDEXBUFFER, state_nop}},
100 {STATE_RENDER(WINED3D_RS_ANTIALIAS), {STATE_RENDER(WINED3D_RS_ANTIALIAS), state_nop}},
101 {STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), {STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), 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_LASTPIXEL), {STATE_RENDER(WINED3D_RS_LASTPIXEL), state_nop}},
109 {STATE_RENDER(WINED3D_RS_DITHERENABLE), {STATE_RENDER(WINED3D_RS_DITHERENABLE), state_nop}},
110 {STATE_RENDER(WINED3D_RS_SUBPIXEL), {STATE_RENDER(WINED3D_RS_SUBPIXEL), state_nop}},
111 {STATE_RENDER(WINED3D_RS_SUBPIXELX), {STATE_RENDER(WINED3D_RS_SUBPIXELX), state_nop}},
112 {STATE_RENDER(WINED3D_RS_STIPPLEDALPHA), {STATE_RENDER(WINED3D_RS_STIPPLEDALPHA), state_nop}},
113 {STATE_RENDER(WINED3D_RS_STIPPLEENABLE), {STATE_RENDER(WINED3D_RS_STIPPLEENABLE), state_nop}},
114 {STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS), {STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS), state_nop}},
115 {STATE_RENDER(WINED3D_RS_ANISOTROPY), {STATE_RENDER(WINED3D_RS_ANISOTROPY), state_nop}},
116 {STATE_RENDER(WINED3D_RS_FLUSHBATCH), {STATE_RENDER(WINED3D_RS_FLUSHBATCH), state_nop}},
117 {STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT), {STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT), state_nop}},
118 {STATE_RENDER(WINED3D_RS_WRAP0), {STATE_RENDER(WINED3D_RS_WRAP0), state_nop}},
119 {STATE_RENDER(WINED3D_RS_WRAP1), {STATE_RENDER(WINED3D_RS_WRAP0)}},
120 {STATE_RENDER(WINED3D_RS_WRAP2), {STATE_RENDER(WINED3D_RS_WRAP0)}},
121 {STATE_RENDER(WINED3D_RS_WRAP3), {STATE_RENDER(WINED3D_RS_WRAP0)}},
122 {STATE_RENDER(WINED3D_RS_WRAP4), {STATE_RENDER(WINED3D_RS_WRAP0)}},
123 {STATE_RENDER(WINED3D_RS_WRAP5), {STATE_RENDER(WINED3D_RS_WRAP0)}},
124 {STATE_RENDER(WINED3D_RS_WRAP6), {STATE_RENDER(WINED3D_RS_WRAP0)}},
125 {STATE_RENDER(WINED3D_RS_WRAP7), {STATE_RENDER(WINED3D_RS_WRAP0)}},
126 {STATE_RENDER(WINED3D_RS_WRAP8), {STATE_RENDER(WINED3D_RS_WRAP0)}},
127 {STATE_RENDER(WINED3D_RS_WRAP9), {STATE_RENDER(WINED3D_RS_WRAP0)}},
128 {STATE_RENDER(WINED3D_RS_WRAP10), {STATE_RENDER(WINED3D_RS_WRAP0)}},
129 {STATE_RENDER(WINED3D_RS_WRAP11), {STATE_RENDER(WINED3D_RS_WRAP0)}},
130 {STATE_RENDER(WINED3D_RS_WRAP12), {STATE_RENDER(WINED3D_RS_WRAP0)}},
131 {STATE_RENDER(WINED3D_RS_WRAP13), {STATE_RENDER(WINED3D_RS_WRAP0)}},
132 {STATE_RENDER(WINED3D_RS_WRAP14), {STATE_RENDER(WINED3D_RS_WRAP0)}},
133 {STATE_RENDER(WINED3D_RS_WRAP15), {STATE_RENDER(WINED3D_RS_WRAP0)}},
134 {STATE_RENDER(WINED3D_RS_EXTENTS), {STATE_RENDER(WINED3D_RS_EXTENTS), state_nop}},
135 {STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE), {STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE), state_nop}},
136 {STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING), {STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING), state_nop}},
137 {STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE), {STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE), state_nop}},
138 {STATE_RENDER(WINED3D_RS_PATCHSEGMENTS), {STATE_RENDER(WINED3D_RS_PATCHSEGMENTS), state_nop}},
139 {STATE_RENDER(WINED3D_RS_POSITIONDEGREE), {STATE_RENDER(WINED3D_RS_POSITIONDEGREE), state_nop}},
140 {STATE_RENDER(WINED3D_RS_NORMALDEGREE), {STATE_RENDER(WINED3D_RS_NORMALDEGREE), state_nop}},
141 {STATE_RENDER(WINED3D_RS_MINTESSELLATIONLEVEL), {STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION)}},
142 {STATE_RENDER(WINED3D_RS_MAXTESSELLATIONLEVEL), {STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION)}},
143 {STATE_RENDER(WINED3D_RS_ADAPTIVETESS_X), {STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION)}},
144 {STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Y), {STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION)}},
145 {STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Z), {STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION)}},
146 {STATE_RENDER(WINED3D_RS_ADAPTIVETESS_W), {STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION)}},
147 {STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION), {STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION), state_nop}},
148 {STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), {STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_nop}},
149 {STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), {STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), state_nop}},
150 {STATE_RENDER(WINED3D_RS_ZVISIBLE), {STATE_RENDER(WINED3D_RS_ZVISIBLE), state_nop}},
151 /* Samplers */
152 {STATE_SAMPLER(0), {STATE_SAMPLER(0), state_nop}},
153 {STATE_SAMPLER(1), {STATE_SAMPLER(1), state_nop}},
154 {STATE_SAMPLER(2), {STATE_SAMPLER(2), state_nop}},
155 {STATE_SAMPLER(3), {STATE_SAMPLER(3), state_nop}},
156 {STATE_SAMPLER(4), {STATE_SAMPLER(4), state_nop}},
157 {STATE_SAMPLER(5), {STATE_SAMPLER(5), state_nop}},
158 {STATE_SAMPLER(6), {STATE_SAMPLER(6), state_nop}},
159 {STATE_SAMPLER(7), {STATE_SAMPLER(7), state_nop}},
160 {STATE_SAMPLER(8), {STATE_SAMPLER(8), state_nop}},
161 {STATE_SAMPLER(9), {STATE_SAMPLER(9), state_nop}},
162 {STATE_SAMPLER(10), {STATE_SAMPLER(10), state_nop}},
163 {STATE_SAMPLER(11), {STATE_SAMPLER(11), state_nop}},
164 {STATE_SAMPLER(12), {STATE_SAMPLER(12), state_nop}},
165 {STATE_SAMPLER(13), {STATE_SAMPLER(13), state_nop}},
166 {STATE_SAMPLER(14), {STATE_SAMPLER(14), state_nop}},
167 {STATE_SAMPLER(15), {STATE_SAMPLER(15), state_nop}},
168 {STATE_SAMPLER(16), /* Vertex sampler 0 */ {STATE_SAMPLER(16), state_nop}},
169 {STATE_SAMPLER(17), /* Vertex sampler 1 */ {STATE_SAMPLER(17), state_nop}},
170 {STATE_SAMPLER(18), /* Vertex sampler 2 */ {STATE_SAMPLER(18), state_nop}},
171 {STATE_SAMPLER(19), /* Vertex sampler 3 */ {STATE_SAMPLER(19), state_nop}},
172 {STATE_BASEVERTEXINDEX, {STATE_STREAMSRC}},
173 {STATE_FRAMEBUFFER, {STATE_FRAMEBUFFER, state_nop}},
174 {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), {STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), state_nop}},
175 {STATE_SHADER(WINED3D_SHADER_TYPE_HULL), {STATE_SHADER(WINED3D_SHADER_TYPE_HULL), state_nop}},
176 {STATE_SHADER(WINED3D_SHADER_TYPE_DOMAIN), {STATE_SHADER(WINED3D_SHADER_TYPE_DOMAIN), state_nop}},
177 {STATE_SHADER(WINED3D_SHADER_TYPE_GEOMETRY), {STATE_SHADER(WINED3D_SHADER_TYPE_GEOMETRY), state_nop}},
178 {STATE_SHADER(WINED3D_SHADER_TYPE_COMPUTE), {STATE_SHADER(WINED3D_SHADER_TYPE_COMPUTE), state_nop}},
179 {0}, /* Terminate */
182 static inline const struct wined3d_adapter_vk *wined3d_adapter_vk_const(const struct wined3d_adapter *adapter)
184 return CONTAINING_RECORD(adapter, struct wined3d_adapter_vk, a);
187 static const char *debug_vk_version(uint32_t version)
189 return wine_dbg_sprintf("%u.%u.%u",
190 VK_VERSION_MAJOR(version), VK_VERSION_MINOR(version), VK_VERSION_PATCH(version));
193 static HRESULT hresult_from_vk_result(VkResult vr)
195 switch (vr)
197 case VK_SUCCESS:
198 return S_OK;
199 case VK_ERROR_OUT_OF_HOST_MEMORY:
200 WARN("Out of host memory.\n");
201 return E_OUTOFMEMORY;
202 case VK_ERROR_OUT_OF_DEVICE_MEMORY:
203 WARN("Out of device memory.\n");
204 return E_OUTOFMEMORY;
205 case VK_ERROR_DEVICE_LOST:
206 WARN("Device lost.\n");
207 return E_FAIL;
208 case VK_ERROR_EXTENSION_NOT_PRESENT:
209 WARN("Extension not present.\n");
210 return E_FAIL;
211 default:
212 FIXME("Unhandled VkResult %d.\n", vr);
213 return E_FAIL;
217 #ifdef USE_WIN32_VULKAN
218 static BOOL wined3d_load_vulkan(struct wined3d_vk_info *vk_info)
220 struct vulkan_ops *vk_ops = &vk_info->vk_ops;
222 if (!(vk_info->vulkan_lib = LoadLibraryA("winevulkan.dll"))
223 && !(vk_info->vulkan_lib = LoadLibraryA("vulkan-1.dll")))
225 WARN("Failed to load vulkan-1.dll.\n");
226 return FALSE;
229 vk_ops->vkGetInstanceProcAddr = (void *)GetProcAddress(vk_info->vulkan_lib, "vkGetInstanceProcAddr");
230 if (!vk_ops->vkGetInstanceProcAddr)
232 FreeLibrary(vk_info->vulkan_lib);
233 return FALSE;
236 return TRUE;
239 static void wined3d_unload_vulkan(struct wined3d_vk_info *vk_info)
241 if (vk_info->vulkan_lib)
243 FreeLibrary(vk_info->vulkan_lib);
244 vk_info->vulkan_lib = NULL;
247 #else
248 static BOOL wined3d_load_vulkan(struct wined3d_vk_info *vk_info)
250 struct vulkan_ops *vk_ops = &vk_info->vk_ops;
251 const struct vulkan_funcs *vk_funcs;
253 vk_funcs = __wine_get_vulkan_driver(WINE_VULKAN_DRIVER_VERSION);
255 if (!vk_funcs)
256 return FALSE;
258 vk_ops->vkGetInstanceProcAddr = (void *)vk_funcs->p_vkGetInstanceProcAddr;
259 return TRUE;
262 static void wined3d_unload_vulkan(struct wined3d_vk_info *vk_info) {}
263 #endif
265 static void adapter_vk_destroy(struct wined3d_adapter *adapter)
267 struct wined3d_adapter_vk *adapter_vk = wined3d_adapter_vk(adapter);
268 struct wined3d_vk_info *vk_info = &adapter_vk->vk_info;
270 VK_CALL(vkDestroyInstance(vk_info->instance, NULL));
271 wined3d_unload_vulkan(vk_info);
272 wined3d_adapter_cleanup(&adapter_vk->a);
273 heap_free(adapter_vk->device_extensions);
274 heap_free(adapter_vk);
277 static HRESULT wined3d_select_vulkan_queue_family(const struct wined3d_adapter_vk *adapter_vk,
278 uint32_t *queue_family_index, uint32_t *timestamp_bits)
280 VkPhysicalDevice physical_device = adapter_vk->physical_device;
281 const struct wined3d_vk_info *vk_info = &adapter_vk->vk_info;
282 VkQueueFamilyProperties *queue_properties;
283 uint32_t count, i;
285 VK_CALL(vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &count, NULL));
287 if (!(queue_properties = heap_calloc(count, sizeof(*queue_properties))))
288 return E_OUTOFMEMORY;
290 VK_CALL(vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &count, queue_properties));
292 for (i = 0; i < count; ++i)
294 if (queue_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
296 *queue_family_index = i;
297 *timestamp_bits = queue_properties[i].timestampValidBits;
298 heap_free(queue_properties);
299 return WINED3D_OK;
302 heap_free(queue_properties);
304 WARN("Failed to find graphics queue.\n");
305 return E_FAIL;
308 struct wined3d_physical_device_info
310 VkPhysicalDeviceTransformFeedbackFeaturesEXT xfb_features;
311 VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT vertex_divisor_features;
312 VkPhysicalDeviceHostQueryResetFeatures host_query_reset_features;
314 VkPhysicalDeviceFeatures2 features2;
317 static void wined3d_disable_vulkan_features(struct wined3d_physical_device_info *info)
319 VkPhysicalDeviceFeatures *features = &info->features2.features;
321 features->depthBounds = VK_FALSE;
322 features->alphaToOne = VK_FALSE;
323 features->textureCompressionETC2 = VK_FALSE;
324 features->textureCompressionASTC_LDR = VK_FALSE;
325 features->shaderStorageImageMultisample = VK_FALSE;
326 features->shaderUniformBufferArrayDynamicIndexing = VK_FALSE;
327 features->shaderSampledImageArrayDynamicIndexing = VK_FALSE;
328 features->shaderStorageBufferArrayDynamicIndexing = VK_FALSE;
329 features->shaderStorageImageArrayDynamicIndexing = VK_FALSE;
330 features->shaderInt16 = VK_FALSE;
331 features->shaderResourceResidency = VK_FALSE;
332 features->shaderResourceMinLod = VK_FALSE;
333 features->sparseBinding = VK_FALSE;
334 features->sparseResidencyBuffer = VK_FALSE;
335 features->sparseResidencyImage2D = VK_FALSE;
336 features->sparseResidencyImage3D = VK_FALSE;
337 features->sparseResidency2Samples = VK_FALSE;
338 features->sparseResidency4Samples = VK_FALSE;
339 features->sparseResidency8Samples = VK_FALSE;
340 features->sparseResidency16Samples = VK_FALSE;
341 features->sparseResidencyAliased = VK_FALSE;
342 features->inheritedQueries = VK_FALSE;
345 static struct wined3d_allocator_chunk *wined3d_allocator_vk_create_chunk(struct wined3d_allocator *allocator,
346 struct wined3d_context *context, unsigned int memory_type, size_t chunk_size)
348 struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
349 struct wined3d_allocator_chunk_vk *chunk_vk;
351 if (!(chunk_vk = heap_alloc(sizeof(*chunk_vk))))
352 return NULL;
354 if (!wined3d_allocator_chunk_init(&chunk_vk->c, allocator))
356 heap_free(chunk_vk);
357 return NULL;
360 if (!(chunk_vk->vk_memory = wined3d_context_vk_allocate_vram_chunk_memory(context_vk, memory_type, chunk_size)))
362 wined3d_allocator_chunk_cleanup(&chunk_vk->c);
363 heap_free(chunk_vk);
364 return NULL;
366 list_add_head(&allocator->pools[memory_type].chunks, &chunk_vk->c.entry);
368 return &chunk_vk->c;
371 static void wined3d_allocator_vk_destroy_chunk(struct wined3d_allocator_chunk *chunk)
373 struct wined3d_allocator_chunk_vk *chunk_vk = wined3d_allocator_chunk_vk(chunk);
374 const struct wined3d_vk_info *vk_info;
375 struct wined3d_device_vk *device_vk;
377 TRACE("chunk %p.\n", chunk);
379 device_vk = wined3d_device_vk_from_allocator(chunk_vk->c.allocator);
380 vk_info = &device_vk->vk_info;
382 if (chunk_vk->c.map_ptr)
384 VK_CALL(vkUnmapMemory(device_vk->vk_device, chunk_vk->vk_memory));
385 adapter_adjust_mapped_memory(device_vk->d.adapter, -WINED3D_ALLOCATOR_CHUNK_SIZE);
387 VK_CALL(vkFreeMemory(device_vk->vk_device, chunk_vk->vk_memory, NULL));
388 TRACE("Freed memory 0x%s.\n", wine_dbgstr_longlong(chunk_vk->vk_memory));
389 wined3d_allocator_chunk_cleanup(&chunk_vk->c);
390 heap_free(chunk_vk);
393 static const struct wined3d_allocator_ops wined3d_allocator_vk_ops =
395 .allocator_create_chunk = wined3d_allocator_vk_create_chunk,
396 .allocator_destroy_chunk = wined3d_allocator_vk_destroy_chunk,
399 static HRESULT adapter_vk_create_device(struct wined3d *wined3d, const struct wined3d_adapter *adapter,
400 enum wined3d_device_type device_type, HWND focus_window, unsigned int flags, BYTE surface_alignment,
401 const enum wined3d_feature_level *levels, unsigned int level_count,
402 struct wined3d_device_parent *device_parent, struct wined3d_device **device)
404 const struct wined3d_adapter_vk *adapter_vk = wined3d_adapter_vk_const(adapter);
405 VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *vertex_divisor_features;
406 VkPhysicalDeviceHostQueryResetFeatures *host_query_reset_features;
407 const struct wined3d_vk_info *vk_info = &adapter_vk->vk_info;
408 VkPhysicalDeviceTransformFeedbackFeaturesEXT *xfb_features;
409 struct wined3d_physical_device_info physical_device_info;
410 static const float priorities[] = {1.0f};
411 VkPhysicalDeviceFeatures2 *features2;
412 struct wined3d_device_vk *device_vk;
413 VkDevice vk_device = VK_NULL_HANDLE;
414 VkDeviceQueueCreateInfo queue_info;
415 VkPhysicalDevice physical_device;
416 VkDeviceCreateInfo device_info;
417 uint32_t queue_family_index;
418 uint32_t timestamp_bits;
419 VkResult vr;
420 HRESULT hr;
422 if (!(device_vk = heap_alloc_zero(sizeof(*device_vk))))
423 return E_OUTOFMEMORY;
425 if (FAILED(hr = wined3d_select_vulkan_queue_family(adapter_vk, &queue_family_index, &timestamp_bits)))
426 goto fail;
428 physical_device = adapter_vk->physical_device;
430 memset(&physical_device_info, 0, sizeof(physical_device_info));
432 xfb_features = &physical_device_info.xfb_features;
433 xfb_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT;
435 vertex_divisor_features = &physical_device_info.vertex_divisor_features;
436 vertex_divisor_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT;
437 vertex_divisor_features->pNext = xfb_features;
439 host_query_reset_features = &physical_device_info.host_query_reset_features;
440 host_query_reset_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES;
441 host_query_reset_features->pNext = vertex_divisor_features;
443 features2 = &physical_device_info.features2;
444 features2->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
445 features2->pNext = host_query_reset_features;
447 if (vk_info->vk_ops.vkGetPhysicalDeviceFeatures2)
448 VK_CALL(vkGetPhysicalDeviceFeatures2(physical_device, features2));
449 else
450 VK_CALL(vkGetPhysicalDeviceFeatures(physical_device, &features2->features));
452 if (!vertex_divisor_features->vertexAttributeInstanceRateDivisor
453 || !vertex_divisor_features->vertexAttributeInstanceRateZeroDivisor)
455 WARN("Vertex attribute divisors not supported.\n");
456 hr = E_FAIL;
457 goto fail;
460 wined3d_disable_vulkan_features(&physical_device_info);
462 queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
463 queue_info.pNext = NULL;
464 queue_info.flags = 0;
465 queue_info.queueFamilyIndex = queue_family_index;
466 queue_info.queueCount = ARRAY_SIZE(priorities);
467 queue_info.pQueuePriorities = priorities;
469 device_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
470 device_info.pNext = features2->pNext;
471 device_info.flags = 0;
472 device_info.queueCreateInfoCount = 1;
473 device_info.pQueueCreateInfos = &queue_info;
474 device_info.enabledLayerCount = 0;
475 device_info.ppEnabledLayerNames = NULL;
476 device_info.enabledExtensionCount = adapter_vk->device_extension_count;
477 device_info.ppEnabledExtensionNames = adapter_vk->device_extensions;
478 device_info.pEnabledFeatures = &features2->features;
480 if ((vr = VK_CALL(vkCreateDevice(physical_device, &device_info, NULL, &vk_device))) < 0)
482 WARN("Failed to create Vulkan device, vr %s.\n", wined3d_debug_vkresult(vr));
483 vk_device = VK_NULL_HANDLE;
484 hr = hresult_from_vk_result(vr);
485 goto fail;
488 device_vk->vk_device = vk_device;
489 VK_CALL(vkGetDeviceQueue(vk_device, queue_family_index, 0, &device_vk->vk_queue));
490 device_vk->vk_queue_family_index = queue_family_index;
491 device_vk->timestamp_bits = timestamp_bits;
493 device_vk->vk_info = *vk_info;
494 #define VK_DEVICE_PFN(name) \
495 if (!(device_vk->vk_info.vk_ops.name = (void *)VK_CALL(vkGetDeviceProcAddr(vk_device, #name)))) \
497 WARN("Could not get device proc addr for '" #name "'.\n"); \
498 hr = E_FAIL; \
499 goto fail; \
501 #define VK_DEVICE_EXT_PFN(name) \
502 device_vk->vk_info.vk_ops.name = (void *)VK_CALL(vkGetDeviceProcAddr(vk_device, #name));
503 VK_DEVICE_FUNCS()
504 #undef VK_DEVICE_EXT_PFN
505 #undef VK_DEVICE_PFN
507 if (!wined3d_allocator_init(&device_vk->allocator,
508 adapter_vk->memory_properties.memoryTypeCount, &wined3d_allocator_vk_ops))
510 WARN("Failed to initialise allocator.\n");
511 hr = E_FAIL;
512 goto fail;
515 if (FAILED(hr = wined3d_device_init(&device_vk->d, wined3d, adapter->ordinal, device_type, focus_window,
516 flags, surface_alignment, levels, level_count, vk_info->supported, device_parent)))
518 WARN("Failed to initialize device, hr %#x.\n", hr);
519 wined3d_allocator_cleanup(&device_vk->allocator);
520 goto fail;
523 wined3d_lock_init(&device_vk->allocator_cs, "wined3d_device_vk.allocator_cs");
525 *device = &device_vk->d;
527 return WINED3D_OK;
529 fail:
530 VK_CALL(vkDestroyDevice(vk_device, NULL));
531 heap_free(device_vk);
532 return hr;
535 static void adapter_vk_destroy_device(struct wined3d_device *device)
537 struct wined3d_device_vk *device_vk = wined3d_device_vk(device);
538 const struct wined3d_vk_info *vk_info = &device_vk->vk_info;
540 wined3d_device_cleanup(&device_vk->d);
541 wined3d_allocator_cleanup(&device_vk->allocator);
543 wined3d_lock_cleanup(&device_vk->allocator_cs);
545 VK_CALL(vkDestroyDevice(device_vk->vk_device, NULL));
546 heap_free(device_vk);
549 static struct wined3d_context *adapter_vk_acquire_context(struct wined3d_device *device,
550 struct wined3d_texture *texture, unsigned int sub_resource_idx)
552 TRACE("device %p, texture %p, sub_resource_idx %u.\n", device, texture, sub_resource_idx);
554 wined3d_from_cs(device->cs);
556 if (!device->context_count)
557 return NULL;
559 return &wined3d_device_vk(device)->context_vk.c;
562 static void adapter_vk_release_context(struct wined3d_context *context)
564 TRACE("context %p.\n", context);
567 static void adapter_vk_get_wined3d_caps(const struct wined3d_adapter *adapter, struct wined3d_caps *caps)
569 const struct wined3d_adapter_vk *adapter_vk = wined3d_adapter_vk_const(adapter);
570 const VkPhysicalDeviceLimits *limits = &adapter_vk->device_limits;
571 bool sampler_anisotropy = limits->maxSamplerAnisotropy > 1.0f;
572 const struct wined3d_vk_info *vk_info = &adapter_vk->vk_info;
574 caps->ddraw_caps.dds_caps |= WINEDDSCAPS_BACKBUFFER
575 | WINEDDSCAPS_COMPLEX
576 | WINEDDSCAPS_FRONTBUFFER
577 | WINEDDSCAPS_3DDEVICE
578 | WINEDDSCAPS_VIDEOMEMORY
579 | WINEDDSCAPS_OWNDC
580 | WINEDDSCAPS_LOCALVIDMEM
581 | WINEDDSCAPS_NONLOCALVIDMEM;
582 caps->ddraw_caps.caps |= WINEDDCAPS_3D;
584 caps->Caps2 |= WINED3DCAPS2_CANGENMIPMAP;
586 caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_BLENDOP
587 | WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS
588 | WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
589 | WINED3DPMISCCAPS_POSTBLENDSRGBCONVERT
590 | WINED3DPMISCCAPS_SEPARATEALPHABLEND;
592 caps->RasterCaps |= WINED3DPRASTERCAPS_MIPMAPLODBIAS;
594 if (sampler_anisotropy)
596 caps->RasterCaps |= WINED3DPRASTERCAPS_ANISOTROPY;
598 caps->TextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC
599 | WINED3DPTFILTERCAPS_MINFANISOTROPIC;
601 caps->MaxAnisotropy = limits->maxSamplerAnisotropy;
604 caps->SrcBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR;
605 caps->DestBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR
606 | WINED3DPBLENDCAPS_SRCALPHASAT;
608 caps->TextureCaps |= WINED3DPTEXTURECAPS_VOLUMEMAP
609 | WINED3DPTEXTURECAPS_MIPVOLUMEMAP
610 | WINED3DPTEXTURECAPS_VOLUMEMAP_POW2;
611 caps->VolumeTextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFLINEAR
612 | WINED3DPTFILTERCAPS_MAGFPOINT
613 | WINED3DPTFILTERCAPS_MINFLINEAR
614 | WINED3DPTFILTERCAPS_MINFPOINT
615 | WINED3DPTFILTERCAPS_MIPFLINEAR
616 | WINED3DPTFILTERCAPS_MIPFPOINT
617 | WINED3DPTFILTERCAPS_LINEAR
618 | WINED3DPTFILTERCAPS_LINEARMIPLINEAR
619 | WINED3DPTFILTERCAPS_LINEARMIPNEAREST
620 | WINED3DPTFILTERCAPS_MIPLINEAR
621 | WINED3DPTFILTERCAPS_MIPNEAREST
622 | WINED3DPTFILTERCAPS_NEAREST;
623 caps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_INDEPENDENTUV
624 | WINED3DPTADDRESSCAPS_CLAMP
625 | WINED3DPTADDRESSCAPS_WRAP;
626 caps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER
627 | WINED3DPTADDRESSCAPS_MIRROR;
628 if (vk_info->supported[WINED3D_VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE])
629 caps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
631 caps->MaxVolumeExtent = limits->maxImageDimension3D;
633 caps->TextureCaps |= WINED3DPTEXTURECAPS_CUBEMAP
634 | WINED3DPTEXTURECAPS_MIPCUBEMAP
635 | WINED3DPTEXTURECAPS_CUBEMAP_POW2;
636 caps->CubeTextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFLINEAR
637 | WINED3DPTFILTERCAPS_MAGFPOINT
638 | WINED3DPTFILTERCAPS_MINFLINEAR
639 | WINED3DPTFILTERCAPS_MINFPOINT
640 | WINED3DPTFILTERCAPS_MIPFLINEAR
641 | WINED3DPTFILTERCAPS_MIPFPOINT
642 | WINED3DPTFILTERCAPS_LINEAR
643 | WINED3DPTFILTERCAPS_LINEARMIPLINEAR
644 | WINED3DPTFILTERCAPS_LINEARMIPNEAREST
645 | WINED3DPTFILTERCAPS_MIPLINEAR
646 | WINED3DPTFILTERCAPS_MIPNEAREST
647 | WINED3DPTFILTERCAPS_NEAREST;
649 if (sampler_anisotropy)
651 caps->CubeTextureFilterCaps |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC
652 | WINED3DPTFILTERCAPS_MINFANISOTROPIC;
655 caps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER
656 | WINED3DPTADDRESSCAPS_MIRROR;
657 if (vk_info->supported[WINED3D_VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE])
658 caps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
660 caps->StencilCaps |= WINED3DSTENCILCAPS_DECR
661 | WINED3DSTENCILCAPS_INCR
662 | WINED3DSTENCILCAPS_TWOSIDED;
664 caps->DeclTypes |= WINED3DDTCAPS_FLOAT16_2 | WINED3DDTCAPS_FLOAT16_4;
666 caps->MaxPixelShader30InstructionSlots = WINED3DMAX30SHADERINSTRUCTIONS;
667 caps->MaxVertexShader30InstructionSlots = WINED3DMAX30SHADERINSTRUCTIONS;
668 caps->PS20Caps.temp_count = WINED3DPS20_MAX_NUMTEMPS;
669 caps->VS20Caps.temp_count = WINED3DVS20_MAX_NUMTEMPS;
672 static BOOL adapter_vk_check_format(const struct wined3d_adapter *adapter,
673 const struct wined3d_format *adapter_format, const struct wined3d_format *rt_format,
674 const struct wined3d_format *ds_format)
676 return TRUE;
679 static HRESULT adapter_vk_init_3d(struct wined3d_device *device)
681 struct wined3d_context_vk *context_vk;
682 struct wined3d_device_vk *device_vk;
683 HRESULT hr;
685 TRACE("device %p.\n", device);
687 device_vk = wined3d_device_vk(device);
688 context_vk = &device_vk->context_vk;
689 if (FAILED(hr = wined3d_context_vk_init(context_vk, device->swapchains[0])))
691 WARN("Failed to initialise context.\n");
692 return hr;
695 if (FAILED(hr = device->shader_backend->shader_alloc_private(device,
696 device->adapter->vertex_pipe, device->adapter->fragment_pipe)))
698 ERR("Failed to allocate shader private data, hr %#x.\n", hr);
699 wined3d_context_vk_cleanup(context_vk);
700 return hr;
703 if (!device_context_add(device, &context_vk->c))
705 ERR("Failed to add the newly created context to the context list.\n");
706 device->shader_backend->shader_free_private(device, NULL);
707 wined3d_context_vk_cleanup(context_vk);
708 return E_FAIL;
711 TRACE("Initialised context %p.\n", context_vk);
713 if (!(device_vk->d.blitter = wined3d_cpu_blitter_create()))
715 ERR("Failed to create CPU blitter.\n");
716 device_context_remove(device, &context_vk->c);
717 device->shader_backend->shader_free_private(device, NULL);
718 wined3d_context_vk_cleanup(context_vk);
719 return E_FAIL;
721 wined3d_vk_blitter_create(&device_vk->d.blitter);
723 wined3d_device_create_default_samplers(device, &context_vk->c);
724 wined3d_device_vk_create_null_resources(device_vk, context_vk);
725 wined3d_device_vk_create_null_views(device_vk, context_vk);
726 if (device->adapter->d3d_info.feature_level >= WINED3D_FEATURE_LEVEL_11)
727 wined3d_device_vk_uav_clear_state_init(device_vk);
729 return WINED3D_OK;
732 static void adapter_vk_uninit_3d_cs(void *object)
734 struct wined3d_device_vk *device_vk = object;
735 struct wined3d_context_vk *context_vk;
736 struct wined3d_device *device;
737 struct wined3d_shader *shader;
739 TRACE("device_vk %p.\n", device_vk);
741 context_vk = &device_vk->context_vk;
742 device = &device_vk->d;
744 LIST_FOR_EACH_ENTRY(shader, &device->shaders, struct wined3d_shader, shader_list_entry)
746 device->shader_backend->shader_destroy(shader);
749 if (device->adapter->d3d_info.feature_level >= WINED3D_FEATURE_LEVEL_11)
750 wined3d_device_vk_uav_clear_state_cleanup(device_vk);
751 device->blitter->ops->blitter_destroy(device->blitter, NULL);
752 device->shader_backend->shader_free_private(device, &context_vk->c);
753 wined3d_device_vk_destroy_null_views(device_vk, context_vk);
754 wined3d_device_vk_destroy_null_resources(device_vk, context_vk);
757 static void adapter_vk_uninit_3d(struct wined3d_device *device)
759 struct wined3d_context_vk *context_vk;
760 struct wined3d_device_vk *device_vk;
762 TRACE("device %p.\n", device);
764 device_vk = wined3d_device_vk(device);
765 context_vk = &device_vk->context_vk;
767 wined3d_device_destroy_default_samplers(device);
768 wined3d_cs_destroy_object(device->cs, adapter_vk_uninit_3d_cs, device_vk);
769 wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
771 device_context_remove(device, &context_vk->c);
772 wined3d_context_vk_cleanup(context_vk);
775 static void *wined3d_bo_vk_map(struct wined3d_bo_vk *bo, struct wined3d_context_vk *context_vk)
777 const struct wined3d_vk_info *vk_info;
778 struct wined3d_device_vk *device_vk;
779 struct wined3d_bo_slab_vk *slab;
780 VkResult vr;
782 if (bo->b.map_ptr)
783 return bo->b.map_ptr;
785 vk_info = context_vk->vk_info;
786 device_vk = wined3d_device_vk(context_vk->c.device);
788 if ((slab = bo->slab))
790 if (!(bo->b.map_ptr = wined3d_bo_slab_vk_map(slab, context_vk)))
792 ERR("Failed to map slab.\n");
793 return NULL;
796 else if (bo->memory)
798 struct wined3d_allocator_chunk_vk *chunk_vk = wined3d_allocator_chunk_vk(bo->memory->chunk);
800 if (!(bo->b.map_ptr = wined3d_allocator_chunk_vk_map(chunk_vk, context_vk)))
802 ERR("Failed to map chunk.\n");
803 return NULL;
806 else
808 if ((vr = VK_CALL(vkMapMemory(device_vk->vk_device, bo->vk_memory, 0, VK_WHOLE_SIZE, 0, &bo->b.map_ptr))) < 0)
810 ERR("Failed to map memory, vr %s.\n", wined3d_debug_vkresult(vr));
811 return NULL;
814 adapter_adjust_mapped_memory(device_vk->d.adapter, bo->size);
817 return bo->b.map_ptr;
820 static void wined3d_bo_vk_unmap(struct wined3d_bo_vk *bo, struct wined3d_context_vk *context_vk)
822 struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
823 const struct wined3d_vk_info *vk_info;
824 struct wined3d_bo_slab_vk *slab;
826 /* This may race with the client thread, but it's not a hard limit anyway. */
827 if (device_vk->d.adapter->mapped_size <= MAX_PERSISTENT_MAPPED_BYTES)
829 TRACE("Not unmapping BO %p.\n", bo);
830 return;
833 wined3d_device_bo_map_lock(context_vk->c.device);
834 /* The mapping is still in use by the client (viz. for an accelerated
835 * NOOVERWRITE map). The client will trigger another unmap request when the
836 * d3d application requests to unmap the BO. */
837 if (bo->b.client_map_count)
839 wined3d_device_bo_map_unlock(context_vk->c.device);
840 TRACE("BO %p is still in use by a client thread; not unmapping.\n", bo);
841 return;
843 bo->b.map_ptr = NULL;
844 wined3d_device_bo_map_unlock(context_vk->c.device);
846 if ((slab = bo->slab))
848 wined3d_bo_slab_vk_unmap(slab, context_vk);
849 return;
852 if (bo->memory)
854 wined3d_allocator_chunk_vk_unmap(wined3d_allocator_chunk_vk(bo->memory->chunk), context_vk);
855 return;
858 vk_info = context_vk->vk_info;
859 VK_CALL(vkUnmapMemory(device_vk->vk_device, bo->vk_memory));
860 adapter_adjust_mapped_memory(device_vk->d.adapter, -bo->size);
863 static void wined3d_bo_slab_vk_lock(struct wined3d_bo_slab_vk *slab_vk, struct wined3d_context_vk *context_vk)
865 wined3d_device_vk_allocator_lock(wined3d_device_vk(context_vk->c.device));
868 static void wined3d_bo_slab_vk_unlock(struct wined3d_bo_slab_vk *slab_vk, struct wined3d_context_vk *context_vk)
870 wined3d_device_vk_allocator_unlock(wined3d_device_vk(context_vk->c.device));
873 void *wined3d_bo_slab_vk_map(struct wined3d_bo_slab_vk *slab_vk, struct wined3d_context_vk *context_vk)
875 void *map_ptr;
877 TRACE("slab_vk %p, context_vk %p.\n", slab_vk, context_vk);
879 wined3d_bo_slab_vk_lock(slab_vk, context_vk);
881 if (!slab_vk->map_ptr && !(slab_vk->map_ptr = wined3d_bo_vk_map(&slab_vk->bo, context_vk)))
883 wined3d_bo_slab_vk_unlock(slab_vk, context_vk);
884 ERR("Failed to map slab.\n");
885 return NULL;
888 ++slab_vk->map_count;
889 map_ptr = slab_vk->map_ptr;
891 wined3d_bo_slab_vk_unlock(slab_vk, context_vk);
893 return map_ptr;
896 void wined3d_bo_slab_vk_unmap(struct wined3d_bo_slab_vk *slab_vk, struct wined3d_context_vk *context_vk)
898 wined3d_bo_slab_vk_lock(slab_vk, context_vk);
900 if (--slab_vk->map_count)
902 wined3d_bo_slab_vk_unlock(slab_vk, context_vk);
903 return;
906 wined3d_bo_vk_unmap(&slab_vk->bo, context_vk);
907 slab_vk->map_ptr = NULL;
909 wined3d_bo_slab_vk_unlock(slab_vk, context_vk);
912 VkAccessFlags vk_access_mask_from_buffer_usage(VkBufferUsageFlags usage)
914 VkAccessFlags flags = 0;
916 if (usage & VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)
917 flags |= VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
918 if (usage & VK_BUFFER_USAGE_INDEX_BUFFER_BIT)
919 flags |= VK_ACCESS_INDEX_READ_BIT;
920 if (usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)
921 flags |= VK_ACCESS_UNIFORM_READ_BIT;
922 if (usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)
923 flags |= VK_ACCESS_SHADER_READ_BIT;
924 if (usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT)
925 flags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
926 if (usage & VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT)
927 flags |= VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
928 if (usage & VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT)
929 flags |= VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT;
930 if (usage & VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT)
931 flags |= VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT
932 | VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT;
933 if (usage & VK_BUFFER_USAGE_TRANSFER_SRC_BIT)
934 flags |= VK_ACCESS_TRANSFER_READ_BIT;
935 if (usage & VK_BUFFER_USAGE_TRANSFER_DST_BIT)
936 flags |= VK_ACCESS_TRANSFER_WRITE_BIT;
938 return flags;
941 VkPipelineStageFlags vk_pipeline_stage_mask_from_buffer_usage(VkBufferUsageFlags usage)
943 VkPipelineStageFlags flags = 0;
945 if (usage & (VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT))
946 flags |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
947 if (usage & (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT
948 | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT))
949 flags |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
950 | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
951 | VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
952 | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT;
953 if (usage & VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT)
954 flags |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT;
955 if (usage & (VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT
956 | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT))
957 flags |= VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT;
958 if (usage & (VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT))
959 flags |= VK_PIPELINE_STAGE_TRANSFER_BIT;
961 return flags;
964 static void *adapter_vk_map_bo_address(struct wined3d_context *context,
965 const struct wined3d_bo_address *data, size_t size, uint32_t map_flags)
967 struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
968 const struct wined3d_vk_info *vk_info;
969 struct wined3d_device_vk *device_vk;
970 VkCommandBuffer vk_command_buffer;
971 VkBufferMemoryBarrier vk_barrier;
972 struct wined3d_bo_user *bo_user;
973 struct wined3d_bo_vk *bo, tmp;
974 VkMappedMemoryRange range;
975 void *map_ptr;
977 if (!data->buffer_object)
978 return data->addr;
979 bo = wined3d_bo_vk(data->buffer_object);
981 vk_info = context_vk->vk_info;
982 device_vk = wined3d_device_vk(context->device);
984 if (map_flags & WINED3D_MAP_NOOVERWRITE)
985 goto map;
987 if ((map_flags & WINED3D_MAP_DISCARD) && bo->command_buffer_id > context_vk->completed_command_buffer_id)
989 if (wined3d_context_vk_create_bo(context_vk, bo->size, bo->usage, bo->memory_type, &tmp))
991 bool host_synced = bo->host_synced;
992 list_move_head(&tmp.b.users, &bo->b.users);
993 wined3d_context_vk_destroy_bo(context_vk, bo);
994 *bo = tmp;
995 bo->host_synced = host_synced;
996 list_init(&bo->b.users);
997 list_move_head(&bo->b.users, &tmp.b.users);
998 LIST_FOR_EACH_ENTRY(bo_user, &bo->b.users, struct wined3d_bo_user, entry)
1000 bo_user->valid = false;
1003 goto map;
1006 ERR("Failed to create new buffer object.\n");
1009 if (map_flags & WINED3D_MAP_READ)
1011 if (!bo->host_synced)
1013 if (!(vk_command_buffer = wined3d_context_vk_get_command_buffer(context_vk)))
1015 ERR("Failed to get command buffer.\n");
1016 return NULL;
1019 wined3d_context_vk_end_current_render_pass(context_vk);
1021 vk_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
1022 vk_barrier.pNext = NULL;
1023 vk_barrier.srcAccessMask = vk_access_mask_from_buffer_usage(bo->usage);
1024 vk_barrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT;
1025 vk_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1026 vk_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1027 vk_barrier.buffer = bo->vk_buffer;
1028 vk_barrier.offset = bo->b.buffer_offset + (uintptr_t)data->addr;
1029 vk_barrier.size = size;
1030 VK_CALL(vkCmdPipelineBarrier(vk_command_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
1031 VK_PIPELINE_STAGE_HOST_BIT, 0, 0, NULL, 1, &vk_barrier, 0, NULL));
1033 wined3d_context_vk_reference_bo(context_vk, bo);
1036 if (!bo->b.coherent)
1038 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
1039 range.pNext = NULL;
1040 range.memory = bo->vk_memory;
1041 range.offset = bo->b.memory_offset + (uintptr_t)data->addr;
1042 range.size = size;
1043 VK_CALL(vkInvalidateMappedMemoryRanges(device_vk->vk_device, 1, &range));
1047 if (bo->command_buffer_id == context_vk->current_command_buffer.id)
1048 wined3d_context_vk_submit_command_buffer(context_vk, 0, NULL, NULL, 0, NULL);
1049 wined3d_context_vk_wait_command_buffer(context_vk, bo->command_buffer_id);
1051 map:
1052 if (!(map_ptr = wined3d_bo_vk_map(bo, context_vk)))
1054 ERR("Failed to map bo.\n");
1055 return NULL;
1058 return (uint8_t *)map_ptr + bo->b.memory_offset + (uintptr_t)data->addr;
1061 static void flush_bo_range(struct wined3d_context_vk *context_vk,
1062 struct wined3d_bo_vk *bo, unsigned int offset, unsigned int size)
1064 struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
1065 const struct wined3d_vk_info *vk_info = context_vk->vk_info;
1066 VkMappedMemoryRange range;
1068 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
1069 range.pNext = NULL;
1070 range.memory = bo->vk_memory;
1071 range.offset = bo->b.memory_offset + offset;
1072 range.size = size;
1073 VK_CALL(vkFlushMappedMemoryRanges(device_vk->vk_device, 1, &range));
1076 static void adapter_vk_unmap_bo_address(struct wined3d_context *context,
1077 const struct wined3d_bo_address *data, unsigned int range_count, const struct wined3d_range *ranges)
1079 struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
1080 struct wined3d_bo_vk *bo;
1081 unsigned int i;
1083 if (!data->buffer_object)
1084 return;
1085 bo = wined3d_bo_vk(data->buffer_object);
1087 if (!bo->b.coherent)
1089 for (i = 0; i < range_count; ++i)
1090 flush_bo_range(context_vk, bo, ranges[i].offset, ranges[i].size);
1093 wined3d_bo_vk_unmap(bo, context_vk);
1096 void adapter_vk_copy_bo_address(struct wined3d_context *context,
1097 const struct wined3d_bo_address *dst, const struct wined3d_bo_address *src,
1098 unsigned int range_count, const struct wined3d_range *ranges)
1100 struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
1101 const struct wined3d_vk_info *vk_info = context_vk->vk_info;
1102 struct wined3d_bo_vk staging_bo, *src_bo, *dst_bo;
1103 VkAccessFlags src_access_mask, dst_access_mask;
1104 VkBufferMemoryBarrier vk_barrier[2];
1105 DWORD map_flags = WINED3D_MAP_WRITE;
1106 const struct wined3d_range *range;
1107 struct wined3d_bo_address staging;
1108 VkCommandBuffer vk_command_buffer;
1109 uint8_t *dst_ptr, *src_ptr;
1110 VkBufferCopy region;
1111 size_t size = 0;
1112 unsigned int i;
1114 src_bo = src->buffer_object ? wined3d_bo_vk(src->buffer_object) : NULL;
1115 dst_bo = dst->buffer_object ? wined3d_bo_vk(dst->buffer_object) : NULL;
1117 if (dst_bo && !dst->addr && !ranges->offset && ranges->size == dst_bo->size)
1118 map_flags |= WINED3D_MAP_DISCARD;
1120 if (src_bo && dst_bo)
1122 if (!(vk_command_buffer = wined3d_context_vk_get_command_buffer(context_vk)))
1124 ERR("Failed to get command buffer.\n");
1125 return;
1128 wined3d_context_vk_end_current_render_pass(context_vk);
1130 src_access_mask = vk_access_mask_from_buffer_usage(src_bo->usage);
1131 dst_access_mask = vk_access_mask_from_buffer_usage(dst_bo->usage);
1133 vk_barrier[0].sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
1134 vk_barrier[0].pNext = NULL;
1135 vk_barrier[0].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1136 vk_barrier[0].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1137 vk_barrier[0].buffer = src_bo->vk_buffer;
1139 vk_barrier[1].sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
1140 vk_barrier[1].pNext = NULL;
1141 vk_barrier[1].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1142 vk_barrier[1].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1143 vk_barrier[1].buffer = dst_bo->vk_buffer;
1145 for (i = 0; i < range_count; ++i)
1147 range = &ranges[i];
1149 region.srcOffset = src_bo->b.buffer_offset + (uintptr_t)src->addr + range->offset;
1150 region.dstOffset = dst_bo->b.buffer_offset + (uintptr_t)dst->addr + range->offset;
1151 region.size = range->size;
1153 vk_barrier[0].offset = region.srcOffset;
1154 vk_barrier[0].size = region.size;
1156 vk_barrier[1].offset = region.dstOffset;
1157 vk_barrier[1].size = region.size;
1159 vk_barrier[0].srcAccessMask = src_access_mask;
1160 vk_barrier[0].dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
1162 vk_barrier[1].srcAccessMask = dst_access_mask;
1163 vk_barrier[1].dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1165 VK_CALL(vkCmdPipelineBarrier(vk_command_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
1166 VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 2, vk_barrier, 0, NULL));
1168 VK_CALL(vkCmdCopyBuffer(vk_command_buffer, src_bo->vk_buffer, dst_bo->vk_buffer, 1, &region));
1170 vk_barrier[0].srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
1171 vk_barrier[0].dstAccessMask = src_access_mask;
1173 vk_barrier[1].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1174 vk_barrier[1].dstAccessMask = dst_access_mask;
1176 VK_CALL(vkCmdPipelineBarrier(vk_command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
1177 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, NULL, 2, vk_barrier, 0, NULL));
1180 wined3d_context_vk_reference_bo(context_vk, src_bo);
1181 wined3d_context_vk_reference_bo(context_vk, dst_bo);
1183 return;
1186 if (src_bo && !(src_bo->memory_type & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT))
1188 if (!(wined3d_context_vk_create_bo(context_vk, src_bo->size, VK_BUFFER_USAGE_TRANSFER_DST_BIT,
1189 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &staging_bo)))
1191 ERR("Failed to create staging bo.\n");
1192 return;
1195 staging.buffer_object = &staging_bo.b;
1196 staging.addr = NULL;
1197 adapter_vk_copy_bo_address(context, &staging, src, range_count, ranges);
1198 adapter_vk_copy_bo_address(context, dst, &staging, range_count, ranges);
1200 wined3d_context_vk_destroy_bo(context_vk, &staging_bo);
1202 return;
1205 if (dst_bo && (!(dst_bo->memory_type & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) || (!(map_flags & WINED3D_MAP_DISCARD)
1206 && dst_bo->command_buffer_id > context_vk->completed_command_buffer_id)))
1208 if (!(wined3d_context_vk_create_bo(context_vk, dst_bo->size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
1209 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &staging_bo)))
1211 ERR("Failed to create staging bo.\n");
1212 return;
1215 staging.buffer_object = &staging_bo.b;
1216 staging.addr = NULL;
1217 adapter_vk_copy_bo_address(context, &staging, src, range_count, ranges);
1218 adapter_vk_copy_bo_address(context, dst, &staging, range_count, ranges);
1220 wined3d_context_vk_destroy_bo(context_vk, &staging_bo);
1222 return;
1225 for (i = 0; i < range_count; ++i)
1226 size = max(size, ranges[i].offset + ranges[i].size);
1228 src_ptr = adapter_vk_map_bo_address(context, src, size, WINED3D_MAP_READ);
1229 dst_ptr = adapter_vk_map_bo_address(context, dst, size, map_flags);
1231 for (i = 0; i < range_count; ++i)
1232 memcpy(dst_ptr + ranges[i].offset, src_ptr + ranges[i].offset, ranges[i].size);
1234 adapter_vk_unmap_bo_address(context, dst, range_count, ranges);
1235 adapter_vk_unmap_bo_address(context, src, 0, NULL);
1238 static void adapter_vk_flush_bo_address(struct wined3d_context *context,
1239 const struct wined3d_const_bo_address *data, size_t size)
1241 struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
1242 struct wined3d_bo *bo;
1244 if (!(bo = data->buffer_object))
1245 return;
1247 flush_bo_range(context_vk, wined3d_bo_vk(bo), (uintptr_t)data->addr, size);
1250 static bool adapter_vk_alloc_bo(struct wined3d_device *device, struct wined3d_resource *resource,
1251 unsigned int sub_resource_idx, struct wined3d_bo_address *addr)
1253 struct wined3d_device_vk *device_vk = wined3d_device_vk(device);
1254 struct wined3d_context_vk *context_vk = &device_vk->context_vk;
1255 VkMemoryPropertyFlags memory_type;
1256 VkBufferUsageFlags buffer_usage;
1257 struct wined3d_bo_vk *bo_vk;
1258 VkDeviceSize size;
1260 wined3d_not_from_cs(device->cs);
1261 assert(device->context_count);
1263 if (resource->type == WINED3D_RTYPE_BUFFER)
1265 buffer_usage = vk_buffer_usage_from_bind_flags(resource->bind_flags);
1266 memory_type = vk_memory_type_from_access_flags(resource->access, resource->usage);
1267 size = resource->size;
1269 else
1271 struct wined3d_texture *texture = texture_from_resource(resource);
1273 buffer_usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
1274 memory_type = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
1275 size = texture->sub_resources[sub_resource_idx].size;
1278 if (!(bo_vk = heap_alloc(sizeof(*bo_vk))))
1279 return false;
1281 if (!(wined3d_context_vk_create_bo(context_vk, size, buffer_usage, memory_type, bo_vk)))
1283 WARN("Failed to create Vulkan buffer.\n");
1284 heap_free(bo_vk);
1285 return false;
1288 if (!bo_vk->b.map_ptr)
1290 if (!wined3d_bo_vk_map(bo_vk, context_vk))
1291 ERR("Failed to map bo.\n");
1294 addr->buffer_object = &bo_vk->b;
1295 addr->addr = NULL;
1296 return true;
1299 static void adapter_vk_destroy_bo(struct wined3d_context *context, struct wined3d_bo *bo)
1301 wined3d_context_vk_destroy_bo(wined3d_context_vk(context), wined3d_bo_vk(bo));
1304 static HRESULT adapter_vk_create_swapchain(struct wined3d_device *device,
1305 struct wined3d_swapchain_desc *desc, struct wined3d_swapchain_state_parent *state_parent,
1306 void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain)
1308 struct wined3d_swapchain_vk *swapchain_vk;
1309 HRESULT hr;
1311 TRACE("device %p, desc %p, state_parent %p, parent %p, parent_ops %p, swapchain %p.\n",
1312 device, desc, state_parent, parent, parent_ops, swapchain);
1314 if (!(swapchain_vk = heap_alloc_zero(sizeof(*swapchain_vk))))
1315 return E_OUTOFMEMORY;
1317 if (FAILED(hr = wined3d_swapchain_vk_init(swapchain_vk, device, desc, state_parent, parent,
1318 parent_ops)))
1320 WARN("Failed to initialise swapchain, hr %#x.\n", hr);
1321 heap_free(swapchain_vk);
1322 return hr;
1325 TRACE("Created swapchain %p.\n", swapchain_vk);
1326 *swapchain = &swapchain_vk->s;
1328 return hr;
1331 static void adapter_vk_destroy_swapchain(struct wined3d_swapchain *swapchain)
1333 struct wined3d_swapchain_vk *swapchain_vk = wined3d_swapchain_vk(swapchain);
1335 wined3d_swapchain_vk_cleanup(swapchain_vk);
1336 heap_free(swapchain_vk);
1339 unsigned int wined3d_adapter_vk_get_memory_type_index(const struct wined3d_adapter_vk *adapter_vk,
1340 uint32_t memory_type_mask, VkMemoryPropertyFlags flags)
1342 const VkPhysicalDeviceMemoryProperties *memory_info = &adapter_vk->memory_properties;
1343 unsigned int i;
1345 for (i = 0; i < memory_info->memoryTypeCount; ++i)
1347 if (!(memory_type_mask & (1u << i)))
1348 continue;
1349 if ((memory_info->memoryTypes[i].propertyFlags & flags) == flags)
1350 return i;
1353 return ~0u;
1356 static HRESULT adapter_vk_create_buffer(struct wined3d_device *device,
1357 const struct wined3d_buffer_desc *desc, const struct wined3d_sub_resource_data *data,
1358 void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_buffer **buffer)
1360 struct wined3d_buffer_vk *buffer_vk;
1361 HRESULT hr;
1363 TRACE("device %p, desc %p, data %p, parent %p, parent_ops %p, buffer %p.\n",
1364 device, desc, data, parent, parent_ops, buffer);
1366 if (!(buffer_vk = heap_alloc_zero(sizeof(*buffer_vk))))
1367 return E_OUTOFMEMORY;
1369 if (FAILED(hr = wined3d_buffer_vk_init(buffer_vk, device, desc, data, parent, parent_ops)))
1371 WARN("Failed to initialise buffer, hr %#x.\n", hr);
1372 heap_free(buffer_vk);
1373 return hr;
1376 TRACE("Created buffer %p.\n", buffer_vk);
1377 *buffer = &buffer_vk->b;
1379 return hr;
1382 static void adapter_vk_destroy_buffer(struct wined3d_buffer *buffer)
1384 struct wined3d_buffer_vk *buffer_vk = wined3d_buffer_vk(buffer);
1385 struct wined3d_device *device = buffer_vk->b.resource.device;
1386 unsigned int swapchain_count = device->swapchain_count;
1388 TRACE("buffer_vk %p.\n", buffer_vk);
1390 /* Take a reference to the device, in case releasing the buffer would
1391 * cause the device to be destroyed. However, swapchain resources don't
1392 * take a reference to the device, and we wouldn't want to increment the
1393 * refcount on a device that's in the process of being destroyed. */
1394 if (swapchain_count)
1395 wined3d_device_incref(device);
1396 wined3d_buffer_cleanup(&buffer_vk->b);
1397 wined3d_cs_destroy_object(device->cs, heap_free, buffer_vk);
1398 if (swapchain_count)
1399 wined3d_device_decref(device);
1402 static HRESULT adapter_vk_create_texture(struct wined3d_device *device,
1403 const struct wined3d_resource_desc *desc, unsigned int layer_count, unsigned int level_count,
1404 uint32_t flags, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture)
1406 struct wined3d_texture_vk *texture_vk;
1407 HRESULT hr;
1409 TRACE("device %p, desc %p, layer_count %u, level_count %u, flags %#x, parent %p, parent_ops %p, texture %p.\n",
1410 device, desc, layer_count, level_count, flags, parent, parent_ops, texture);
1412 if (!(texture_vk = wined3d_texture_allocate_object_memory(sizeof(*texture_vk), level_count, layer_count)))
1413 return E_OUTOFMEMORY;
1415 if (FAILED(hr = wined3d_texture_vk_init(texture_vk, device, desc,
1416 layer_count, level_count, flags, parent, parent_ops)))
1418 WARN("Failed to initialise texture, hr %#x.\n", hr);
1419 heap_free(texture_vk);
1420 return hr;
1423 TRACE("Created texture %p.\n", texture_vk);
1424 *texture = &texture_vk->t;
1426 return hr;
1429 static void adapter_vk_destroy_texture(struct wined3d_texture *texture)
1431 struct wined3d_texture_vk *texture_vk = wined3d_texture_vk(texture);
1432 struct wined3d_device *device = texture_vk->t.resource.device;
1433 unsigned int swapchain_count = device->swapchain_count;
1435 TRACE("texture_vk %p.\n", texture_vk);
1437 /* Take a reference to the device, in case releasing the texture would
1438 * cause the device to be destroyed. However, swapchain resources don't
1439 * take a reference to the device, and we wouldn't want to increment the
1440 * refcount on a device that's in the process of being destroyed. */
1441 if (swapchain_count)
1442 wined3d_device_incref(device);
1444 wined3d_texture_sub_resources_destroyed(texture);
1445 texture->resource.parent_ops->wined3d_object_destroyed(texture->resource.parent);
1447 wined3d_texture_cleanup(&texture_vk->t);
1448 wined3d_cs_destroy_object(device->cs, heap_free, texture_vk);
1450 if (swapchain_count)
1451 wined3d_device_decref(device);
1454 static HRESULT adapter_vk_create_rendertarget_view(const struct wined3d_view_desc *desc,
1455 struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
1456 struct wined3d_rendertarget_view **view)
1458 struct wined3d_rendertarget_view_vk *view_vk;
1459 HRESULT hr;
1461 TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n",
1462 wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops, view);
1464 if (!(view_vk = heap_alloc_zero(sizeof(*view_vk))))
1465 return E_OUTOFMEMORY;
1467 if (FAILED(hr = wined3d_rendertarget_view_vk_init(view_vk, desc, resource, parent, parent_ops)))
1469 WARN("Failed to initialise view, hr %#x.\n", hr);
1470 heap_free(view_vk);
1471 return hr;
1474 TRACE("Created render target view %p.\n", view_vk);
1475 *view = &view_vk->v;
1477 return hr;
1480 struct wined3d_view_vk_destroy_ctx
1482 struct wined3d_device_vk *device_vk;
1483 VkBufferView *vk_buffer_view;
1484 VkImageView *vk_image_view;
1485 struct wined3d_bo_user *bo_user;
1486 struct wined3d_bo_vk *vk_counter_bo;
1487 VkBufferView *vk_counter_view;
1488 uint64_t *command_buffer_id;
1489 void *object;
1490 struct wined3d_view_vk_destroy_ctx *free;
1493 static void wined3d_view_vk_destroy_object(void *object)
1495 struct wined3d_view_vk_destroy_ctx *ctx = object;
1496 const struct wined3d_vk_info *vk_info;
1497 struct wined3d_device_vk *device_vk;
1498 struct wined3d_context *context;
1500 TRACE("ctx %p.\n", ctx);
1502 device_vk = ctx->device_vk;
1503 vk_info = &wined3d_adapter_vk(device_vk->d.adapter)->vk_info;
1504 context = context_acquire(&device_vk->d, NULL, 0);
1506 if (ctx->vk_buffer_view)
1508 if (context)
1510 wined3d_context_vk_destroy_vk_buffer_view(wined3d_context_vk(context),
1511 *ctx->vk_buffer_view, *ctx->command_buffer_id);
1513 else
1515 VK_CALL(vkDestroyBufferView(device_vk->vk_device, *ctx->vk_buffer_view, NULL));
1516 TRACE("Destroyed buffer view 0x%s.\n", wine_dbgstr_longlong(*ctx->vk_buffer_view));
1519 if (ctx->vk_image_view)
1521 if (context)
1523 wined3d_context_vk_destroy_vk_image_view(wined3d_context_vk(context),
1524 *ctx->vk_image_view, *ctx->command_buffer_id);
1526 else
1528 VK_CALL(vkDestroyImageView(device_vk->vk_device, *ctx->vk_image_view, NULL));
1529 TRACE("Destroyed image view 0x%s.\n", wine_dbgstr_longlong(*ctx->vk_image_view));
1532 if (ctx->bo_user)
1533 list_remove(&ctx->bo_user->entry);
1534 if (ctx->vk_counter_bo && ctx->vk_counter_bo->vk_buffer)
1535 wined3d_context_vk_destroy_bo(wined3d_context_vk(context), ctx->vk_counter_bo);
1536 if (ctx->vk_counter_view)
1538 if (context)
1540 wined3d_context_vk_destroy_vk_buffer_view(wined3d_context_vk(context),
1541 *ctx->vk_counter_view, *ctx->command_buffer_id);
1543 else
1545 VK_CALL(vkDestroyBufferView(device_vk->vk_device, *ctx->vk_counter_view, NULL));
1546 TRACE("Destroyed counter buffer view 0x%s.\n", wine_dbgstr_longlong(*ctx->vk_counter_view));
1550 if (context)
1551 context_release(context);
1553 heap_free(ctx->object);
1554 heap_free(ctx->free);
1557 static void wined3d_view_vk_destroy(struct wined3d_device *device, VkBufferView *vk_buffer_view,
1558 VkImageView *vk_image_view, struct wined3d_bo_user *bo_user, struct wined3d_bo_vk *vk_counter_bo,
1559 VkBufferView *vk_counter_view, uint64_t *command_buffer_id, void *view_vk)
1561 struct wined3d_view_vk_destroy_ctx *ctx, c;
1563 if (!(ctx = heap_alloc(sizeof(*ctx))))
1564 ctx = &c;
1565 ctx->device_vk = wined3d_device_vk(device);
1566 ctx->vk_buffer_view = vk_buffer_view;
1567 ctx->vk_image_view = vk_image_view;
1568 ctx->bo_user = bo_user;
1569 ctx->vk_counter_bo = vk_counter_bo;
1570 ctx->vk_counter_view = vk_counter_view;
1571 ctx->command_buffer_id = command_buffer_id;
1572 ctx->object = view_vk;
1573 ctx->free = ctx != &c ? ctx : NULL;
1575 wined3d_cs_destroy_object(device->cs, wined3d_view_vk_destroy_object, ctx);
1576 if (ctx == &c)
1577 wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
1580 static void adapter_vk_destroy_rendertarget_view(struct wined3d_rendertarget_view *view)
1582 struct wined3d_rendertarget_view_vk *view_vk = wined3d_rendertarget_view_vk(view);
1583 struct wined3d_resource *resource = view_vk->v.resource;
1585 TRACE("view_vk %p.\n", view_vk);
1587 /* Take a reference to the resource, in case releasing the resource
1588 * would cause the device to be destroyed. */
1589 wined3d_resource_incref(resource);
1590 wined3d_rendertarget_view_cleanup(&view_vk->v);
1591 wined3d_view_vk_destroy(resource->device, NULL, &view_vk->vk_image_view,
1592 NULL, NULL, NULL, &view_vk->command_buffer_id, view_vk);
1593 wined3d_resource_decref(resource);
1596 static HRESULT adapter_vk_create_shader_resource_view(const struct wined3d_view_desc *desc,
1597 struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
1598 struct wined3d_shader_resource_view **view)
1600 struct wined3d_shader_resource_view_vk *view_vk;
1601 HRESULT hr;
1603 TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n",
1604 wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops, view);
1606 if (!(view_vk = heap_alloc_zero(sizeof(*view_vk))))
1607 return E_OUTOFMEMORY;
1609 if (FAILED(hr = wined3d_shader_resource_view_vk_init(view_vk, desc, resource, parent, parent_ops)))
1611 WARN("Failed to initialise view, hr %#x.\n", hr);
1612 heap_free(view_vk);
1613 return hr;
1616 TRACE("Created shader resource view %p.\n", view_vk);
1617 *view = &view_vk->v;
1619 return hr;
1622 static void adapter_vk_destroy_shader_resource_view(struct wined3d_shader_resource_view *view)
1624 struct wined3d_shader_resource_view_vk *srv_vk = wined3d_shader_resource_view_vk(view);
1625 struct wined3d_resource *resource = srv_vk->v.resource;
1626 struct wined3d_view_vk *view_vk = &srv_vk->view_vk;
1627 VkBufferView *vk_buffer_view = NULL;
1628 VkImageView *vk_image_view = NULL;
1630 TRACE("srv_vk %p.\n", srv_vk);
1632 /* Take a reference to the resource. There are two reasons for this:
1633 * - Releasing the resource could in turn cause the device to be
1634 * destroyed, but we still need the device for
1635 * wined3d_view_vk_destroy().
1636 * - We shouldn't free buffer resources until after we've removed the
1637 * view from its bo_user list. */
1638 wined3d_resource_incref(resource);
1639 if (resource->type == WINED3D_RTYPE_BUFFER)
1640 vk_buffer_view = &view_vk->u.vk_buffer_view;
1641 else
1642 vk_image_view = &view_vk->u.vk_image_info.imageView;
1643 wined3d_shader_resource_view_cleanup(&srv_vk->v);
1644 wined3d_view_vk_destroy(resource->device, vk_buffer_view, vk_image_view,
1645 &view_vk->bo_user, NULL, NULL, &view_vk->command_buffer_id, srv_vk);
1646 wined3d_resource_decref(resource);
1649 static HRESULT adapter_vk_create_unordered_access_view(const struct wined3d_view_desc *desc,
1650 struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
1651 struct wined3d_unordered_access_view **view)
1653 struct wined3d_unordered_access_view_vk *view_vk;
1654 HRESULT hr;
1656 TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n",
1657 wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops, view);
1659 if (!(view_vk = heap_alloc_zero(sizeof(*view_vk))))
1660 return E_OUTOFMEMORY;
1662 if (FAILED(hr = wined3d_unordered_access_view_vk_init(view_vk, desc, resource, parent, parent_ops)))
1664 WARN("Failed to initialise view, hr %#x.\n", hr);
1665 heap_free(view_vk);
1666 return hr;
1669 TRACE("Created unordered access view %p.\n", view_vk);
1670 *view = &view_vk->v;
1672 return hr;
1675 static void adapter_vk_destroy_unordered_access_view(struct wined3d_unordered_access_view *view)
1677 struct wined3d_unordered_access_view_vk *uav_vk = wined3d_unordered_access_view_vk(view);
1678 struct wined3d_resource *resource = uav_vk->v.resource;
1679 struct wined3d_view_vk *view_vk = &uav_vk->view_vk;
1680 VkBufferView *vk_buffer_view = NULL;
1681 VkImageView *vk_image_view = NULL;
1683 TRACE("uav_vk %p.\n", uav_vk);
1685 /* Take a reference to the resource. There are two reasons for this:
1686 * - Releasing the resource could in turn cause the device to be
1687 * destroyed, but we still need the device for
1688 * wined3d_view_vk_destroy().
1689 * - We shouldn't free buffer resources until after we've removed the
1690 * view from its bo_user list. */
1691 wined3d_resource_incref(resource);
1692 if (resource->type == WINED3D_RTYPE_BUFFER)
1693 vk_buffer_view = &view_vk->u.vk_buffer_view;
1694 else
1695 vk_image_view = &view_vk->u.vk_image_info.imageView;
1696 wined3d_unordered_access_view_cleanup(&uav_vk->v);
1697 wined3d_view_vk_destroy(resource->device, vk_buffer_view, vk_image_view, &view_vk->bo_user,
1698 &uav_vk->counter_bo, &uav_vk->vk_counter_view, &view_vk->command_buffer_id, uav_vk);
1699 wined3d_resource_decref(resource);
1702 static HRESULT adapter_vk_create_sampler(struct wined3d_device *device, const struct wined3d_sampler_desc *desc,
1703 void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_sampler **sampler)
1705 struct wined3d_sampler_vk *sampler_vk;
1707 TRACE("device %p, desc %p, parent %p, parent_ops %p, sampler %p.\n",
1708 device, desc, parent, parent_ops, sampler);
1710 if (!(sampler_vk = heap_alloc_zero(sizeof(*sampler_vk))))
1711 return E_OUTOFMEMORY;
1713 wined3d_sampler_vk_init(sampler_vk, device, desc, parent, parent_ops);
1715 TRACE("Created sampler %p.\n", sampler_vk);
1716 *sampler = &sampler_vk->s;
1718 return WINED3D_OK;
1721 static void wined3d_sampler_vk_destroy_object(void *object)
1723 struct wined3d_sampler_vk *sampler_vk = object;
1724 struct wined3d_context_vk *context_vk;
1726 TRACE("sampler_vk %p.\n", sampler_vk);
1728 context_vk = wined3d_context_vk(context_acquire(sampler_vk->s.device, NULL, 0));
1730 wined3d_context_vk_destroy_vk_sampler(context_vk, sampler_vk->vk_image_info.sampler, sampler_vk->command_buffer_id);
1731 heap_free(sampler_vk);
1733 context_release(&context_vk->c);
1736 static void adapter_vk_destroy_sampler(struct wined3d_sampler *sampler)
1738 struct wined3d_sampler_vk *sampler_vk = wined3d_sampler_vk(sampler);
1740 TRACE("sampler_vk %p.\n", sampler_vk);
1742 wined3d_cs_destroy_object(sampler->device->cs, wined3d_sampler_vk_destroy_object, sampler_vk);
1745 static HRESULT adapter_vk_create_query(struct wined3d_device *device, enum wined3d_query_type type,
1746 void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_query **query)
1748 TRACE("device %p, type %#x, parent %p, parent_ops %p, query %p.\n",
1749 device, type, parent, parent_ops, query);
1751 return wined3d_query_vk_create(device, type, parent, parent_ops, query);
1754 static void wined3d_query_vk_destroy_object(void *object)
1756 struct wined3d_query_vk *query_vk = object;
1758 TRACE("query_vk %p.\n", query_vk);
1760 query_vk->q.query_ops->query_destroy(&query_vk->q);
1763 static void adapter_vk_destroy_query(struct wined3d_query *query)
1765 struct wined3d_query_vk *query_vk = wined3d_query_vk(query);
1767 TRACE("query_vk %p.\n", query_vk);
1769 wined3d_cs_destroy_object(query->device->cs, wined3d_query_vk_destroy_object, query_vk);
1772 static void adapter_vk_flush_context(struct wined3d_context *context)
1774 struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
1776 TRACE("context_vk %p.\n", context_vk);
1778 wined3d_context_vk_submit_command_buffer(context_vk, 0, NULL, NULL, 0, NULL);
1781 static void adapter_vk_draw_primitive(struct wined3d_device *device,
1782 const struct wined3d_state *state, const struct wined3d_draw_parameters *parameters)
1784 struct wined3d_buffer_vk *indirect_vk = NULL;
1785 const struct wined3d_vk_info *vk_info;
1786 struct wined3d_context_vk *context_vk;
1787 VkCommandBuffer vk_command_buffer;
1788 uint32_t instance_count;
1789 unsigned int i;
1791 TRACE("device %p, state %p, parameters %p.\n", device, state, parameters);
1793 context_vk = wined3d_context_vk(context_acquire(device, NULL, 0));
1794 vk_info = context_vk->vk_info;
1796 if (parameters->indirect)
1797 indirect_vk = wined3d_buffer_vk(parameters->u.indirect.buffer);
1799 if (!(vk_command_buffer = wined3d_context_vk_apply_draw_state(context_vk,
1800 state, indirect_vk, parameters->indexed)))
1802 ERR("Failed to apply draw state.\n");
1803 context_release(&context_vk->c);
1804 return;
1807 if (context_vk->c.transform_feedback_active)
1809 if (!context_vk->vk_so_counter_bo.vk_buffer)
1811 struct wined3d_bo_vk *bo = &context_vk->vk_so_counter_bo;
1813 if (!wined3d_context_vk_create_bo(context_vk, ARRAY_SIZE(context_vk->vk_so_counters) * sizeof(uint32_t) * 2,
1814 VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, bo))
1815 ERR("Failed to create counter BO.\n");
1816 for (i = 0; i < ARRAY_SIZE(context_vk->vk_so_counters); ++i)
1818 context_vk->vk_so_counters[i] = bo->vk_buffer;
1819 context_vk->vk_so_offsets[i] = bo->b.buffer_offset + i * sizeof(uint32_t) * 2;
1823 wined3d_context_vk_reference_bo(context_vk, &context_vk->vk_so_counter_bo);
1824 if (context_vk->c.transform_feedback_paused)
1825 VK_CALL(vkCmdBeginTransformFeedbackEXT(vk_command_buffer, 0, ARRAY_SIZE(context_vk->vk_so_counters),
1826 context_vk->vk_so_counters, context_vk->vk_so_offsets));
1827 else
1828 VK_CALL(vkCmdBeginTransformFeedbackEXT(vk_command_buffer, 0, 0, NULL, NULL));
1831 if (parameters->indirect)
1833 struct wined3d_bo_vk *bo = wined3d_bo_vk(indirect_vk->b.buffer_object);
1834 uint32_t stride, size;
1836 wined3d_context_vk_reference_bo(context_vk, bo);
1837 size = indirect_vk->b.resource.size - parameters->u.indirect.offset;
1839 if (parameters->indexed)
1841 stride = sizeof(VkDrawIndexedIndirectCommand);
1842 VK_CALL(vkCmdDrawIndexedIndirect(vk_command_buffer, bo->vk_buffer,
1843 bo->b.buffer_offset + parameters->u.indirect.offset, size / stride, stride));
1845 else
1847 stride = sizeof(VkDrawIndirectCommand);
1848 VK_CALL(vkCmdDrawIndirect(vk_command_buffer, bo->vk_buffer,
1849 bo->b.buffer_offset + parameters->u.indirect.offset, size / stride, stride));
1852 else
1854 instance_count = parameters->u.direct.instance_count;
1855 if (context_vk->c.instance_count)
1856 instance_count = context_vk->c.instance_count;
1857 if (!instance_count)
1858 instance_count = 1;
1860 if (parameters->indexed)
1861 VK_CALL(vkCmdDrawIndexed(vk_command_buffer, parameters->u.direct.index_count,
1862 instance_count, parameters->u.direct.start_idx, parameters->u.direct.base_vertex_idx,
1863 parameters->u.direct.start_instance));
1864 else
1865 VK_CALL(vkCmdDraw(vk_command_buffer, parameters->u.direct.index_count, instance_count,
1866 parameters->u.direct.start_idx, parameters->u.direct.start_instance));
1869 if (context_vk->c.transform_feedback_active)
1871 VK_CALL(vkCmdEndTransformFeedbackEXT(vk_command_buffer, 0, ARRAY_SIZE(context_vk->vk_so_counters),
1872 context_vk->vk_so_counters, context_vk->vk_so_offsets));
1873 context_vk->c.transform_feedback_paused = 1;
1874 context_vk->c.transform_feedback_active = 0;
1877 context_release(&context_vk->c);
1880 static void adapter_vk_dispatch_compute(struct wined3d_device *device,
1881 const struct wined3d_state *state, const struct wined3d_dispatch_parameters *parameters)
1883 struct wined3d_buffer_vk *indirect_vk = NULL;
1884 const struct wined3d_vk_info *vk_info;
1885 struct wined3d_context_vk *context_vk;
1886 VkCommandBuffer vk_command_buffer;
1888 TRACE("device %p, state %p, parameters %p.\n", device, state, parameters);
1890 context_vk = wined3d_context_vk(context_acquire(device, NULL, 0));
1891 vk_info = context_vk->vk_info;
1893 if (parameters->indirect)
1894 indirect_vk = wined3d_buffer_vk(parameters->u.indirect.buffer);
1896 if (!(vk_command_buffer = wined3d_context_vk_apply_compute_state(context_vk, state, indirect_vk)))
1898 ERR("Failed to apply compute state.\n");
1899 context_release(&context_vk->c);
1900 return;
1903 if (parameters->indirect)
1905 struct wined3d_bo_vk *bo = wined3d_bo_vk(indirect_vk->b.buffer_object);
1907 wined3d_context_vk_reference_bo(context_vk, bo);
1908 VK_CALL(vkCmdDispatchIndirect(vk_command_buffer, bo->vk_buffer,
1909 bo->b.buffer_offset + parameters->u.indirect.offset));
1911 else
1913 const struct wined3d_direct_dispatch_parameters *direct = &parameters->u.direct;
1915 VK_CALL(vkCmdDispatch(vk_command_buffer, direct->group_count_x, direct->group_count_y, direct->group_count_z));
1918 VK_CALL(vkCmdPipelineBarrier(vk_command_buffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
1919 VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, 0, 0, NULL, 0, NULL, 0, NULL));
1921 context_release(&context_vk->c);
1924 static void adapter_vk_clear_uav(struct wined3d_context *context,
1925 struct wined3d_unordered_access_view *view, const struct wined3d_uvec4 *clear_value, bool fp)
1927 TRACE("context %p, view %p, clear_value %s.\n", context, view, debug_uvec4(clear_value));
1929 wined3d_unordered_access_view_vk_clear(wined3d_unordered_access_view_vk(view),
1930 clear_value, wined3d_context_vk(context), fp);
1933 static void adapter_vk_generate_mipmap(struct wined3d_context *context, struct wined3d_shader_resource_view *view)
1935 TRACE("context %p, view %p.\n", context, view);
1937 wined3d_shader_resource_view_vk_generate_mipmap(wined3d_shader_resource_view_vk(view),
1938 wined3d_context_vk(context));
1941 static const struct wined3d_adapter_ops wined3d_adapter_vk_ops =
1943 .adapter_destroy = adapter_vk_destroy,
1944 .adapter_create_device = adapter_vk_create_device,
1945 .adapter_destroy_device = adapter_vk_destroy_device,
1946 .adapter_acquire_context = adapter_vk_acquire_context,
1947 .adapter_release_context = adapter_vk_release_context,
1948 .adapter_get_wined3d_caps = adapter_vk_get_wined3d_caps,
1949 .adapter_check_format = adapter_vk_check_format,
1950 .adapter_init_3d = adapter_vk_init_3d,
1951 .adapter_uninit_3d = adapter_vk_uninit_3d,
1952 .adapter_map_bo_address = adapter_vk_map_bo_address,
1953 .adapter_unmap_bo_address = adapter_vk_unmap_bo_address,
1954 .adapter_copy_bo_address = adapter_vk_copy_bo_address,
1955 .adapter_flush_bo_address = adapter_vk_flush_bo_address,
1956 .adapter_alloc_bo = adapter_vk_alloc_bo,
1957 .adapter_destroy_bo = adapter_vk_destroy_bo,
1958 .adapter_create_swapchain = adapter_vk_create_swapchain,
1959 .adapter_destroy_swapchain = adapter_vk_destroy_swapchain,
1960 .adapter_create_buffer = adapter_vk_create_buffer,
1961 .adapter_destroy_buffer = adapter_vk_destroy_buffer,
1962 .adapter_create_texture = adapter_vk_create_texture,
1963 .adapter_destroy_texture = adapter_vk_destroy_texture,
1964 .adapter_create_rendertarget_view = adapter_vk_create_rendertarget_view,
1965 .adapter_destroy_rendertarget_view = adapter_vk_destroy_rendertarget_view,
1966 .adapter_create_shader_resource_view = adapter_vk_create_shader_resource_view,
1967 .adapter_destroy_shader_resource_view = adapter_vk_destroy_shader_resource_view,
1968 .adapter_create_unordered_access_view = adapter_vk_create_unordered_access_view,
1969 .adapter_destroy_unordered_access_view = adapter_vk_destroy_unordered_access_view,
1970 .adapter_create_sampler = adapter_vk_create_sampler,
1971 .adapter_destroy_sampler = adapter_vk_destroy_sampler,
1972 .adapter_create_query = adapter_vk_create_query,
1973 .adapter_destroy_query = adapter_vk_destroy_query,
1974 .adapter_flush_context = adapter_vk_flush_context,
1975 .adapter_draw_primitive = adapter_vk_draw_primitive,
1976 .adapter_dispatch_compute = adapter_vk_dispatch_compute,
1977 .adapter_clear_uav = adapter_vk_clear_uav,
1978 .adapter_generate_mipmap = adapter_vk_generate_mipmap,
1981 static unsigned int wined3d_get_wine_vk_version(void)
1983 const char * (CDECL *wine_get_version)(void) = (void *)GetProcAddress( GetModuleHandleW(L"ntdll.dll"),
1984 "wine_get_version" );
1985 const char *ptr;
1986 int major, minor;
1988 if (!wine_get_version) return VK_MAKE_VERSION(1, 0, 0);
1990 ptr = wine_get_version();
1991 major = atoi(ptr);
1993 while (isdigit(*ptr))
1994 ++ptr;
1995 if (*ptr == '.')
1996 ++ptr;
1998 minor = atoi(ptr);
2000 return VK_MAKE_VERSION(major, minor, 0);
2003 static const struct
2005 const char *name;
2006 unsigned int core_since_version;
2007 BOOL required;
2009 vulkan_instance_extensions[] =
2011 {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_API_VERSION_1_1, FALSE},
2012 {VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME, VK_API_VERSION_1_1, FALSE},
2013 {VK_KHR_SURFACE_EXTENSION_NAME, ~0u, TRUE},
2014 {VK_KHR_WIN32_SURFACE_EXTENSION_NAME, ~0u, TRUE},
2017 static BOOL enable_vulkan_instance_extensions(uint32_t *extension_count,
2018 const char *enabled_extensions[], const struct wined3d_vk_info *vk_info)
2020 PFN_vkEnumerateInstanceExtensionProperties pfn_vkEnumerateInstanceExtensionProperties;
2021 VkExtensionProperties *extensions = NULL;
2022 BOOL success = FALSE, found;
2023 unsigned int i, j, count;
2024 VkResult vr;
2026 *extension_count = 0;
2028 if (!(pfn_vkEnumerateInstanceExtensionProperties
2029 = (void *)VK_CALL(vkGetInstanceProcAddr(NULL, "vkEnumerateInstanceExtensionProperties"))))
2031 WARN("Failed to get 'vkEnumerateInstanceExtensionProperties'.\n");
2032 goto done;
2035 if ((vr = pfn_vkEnumerateInstanceExtensionProperties(NULL, &count, NULL)) < 0)
2037 WARN("Failed to count instance extensions, vr %s.\n", wined3d_debug_vkresult(vr));
2038 goto done;
2040 if (!(extensions = heap_calloc(count, sizeof(*extensions))))
2042 WARN("Out of memory.\n");
2043 goto done;
2045 if ((vr = pfn_vkEnumerateInstanceExtensionProperties(NULL, &count, extensions)) < 0)
2047 WARN("Failed to enumerate extensions, vr %s.\n", wined3d_debug_vkresult(vr));
2048 goto done;
2051 TRACE("Vulkan instance extensions reported:\n");
2052 for (i = 0; i < count; ++i)
2054 TRACE(" - %s.\n", debugstr_a(extensions[i].extensionName));
2057 for (i = 0; i < ARRAY_SIZE(vulkan_instance_extensions); ++i)
2059 if (vulkan_instance_extensions[i].core_since_version <= vk_info->api_version)
2060 continue;
2062 for (j = 0, found = FALSE; j < count; ++j)
2064 if (!strcmp(extensions[j].extensionName, vulkan_instance_extensions[i].name))
2066 found = TRUE;
2067 break;
2070 if (found)
2072 TRACE("Enabling instance extension '%s'.\n", vulkan_instance_extensions[i].name);
2073 enabled_extensions[(*extension_count)++] = vulkan_instance_extensions[i].name;
2075 else if (!found && vulkan_instance_extensions[i].required)
2077 WARN("Required extension '%s' is not available.\n", vulkan_instance_extensions[i].name);
2078 goto done;
2081 success = TRUE;
2083 done:
2084 heap_free(extensions);
2085 return success;
2088 static BOOL wined3d_init_vulkan(struct wined3d_vk_info *vk_info)
2090 const char *enabled_instance_extensions[ARRAY_SIZE(vulkan_instance_extensions)];
2091 PFN_vkEnumerateInstanceVersion pfn_vkEnumerateInstanceVersion;
2092 struct vulkan_ops *vk_ops = &vk_info->vk_ops;
2093 VkInstance instance = VK_NULL_HANDLE;
2094 VkInstanceCreateInfo instance_info;
2095 VkApplicationInfo app_info;
2096 uint32_t api_version = 0;
2097 char app_name[MAX_PATH];
2098 VkResult vr;
2100 if (!wined3d_load_vulkan(vk_info))
2101 return FALSE;
2103 if (!(vk_ops->vkCreateInstance = (void *)VK_CALL(vkGetInstanceProcAddr(NULL, "vkCreateInstance"))))
2105 ERR("Failed to get 'vkCreateInstance'.\n");
2106 goto fail;
2109 vk_info->api_version = VK_API_VERSION_1_0;
2110 if ((pfn_vkEnumerateInstanceVersion = (void *)VK_CALL(vkGetInstanceProcAddr(NULL, "vkEnumerateInstanceVersion")))
2111 && pfn_vkEnumerateInstanceVersion(&api_version) == VK_SUCCESS)
2113 TRACE("Vulkan instance API version %s.\n", debug_vk_version(api_version));
2115 if (api_version >= VK_API_VERSION_1_1)
2116 vk_info->api_version = VK_API_VERSION_1_1;
2119 memset(&app_info, 0, sizeof(app_info));
2120 app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
2121 if (wined3d_get_app_name(app_name, ARRAY_SIZE(app_name)))
2122 app_info.pApplicationName = app_name;
2123 app_info.pEngineName = "Damavand";
2124 app_info.engineVersion = wined3d_get_wine_vk_version();
2125 app_info.apiVersion = vk_info->api_version;
2127 memset(&instance_info, 0, sizeof(instance_info));
2128 instance_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
2129 instance_info.pApplicationInfo = &app_info;
2130 instance_info.ppEnabledExtensionNames = enabled_instance_extensions;
2131 if (!enable_vulkan_instance_extensions(&instance_info.enabledExtensionCount, enabled_instance_extensions, vk_info))
2132 goto fail;
2134 memset(vk_info->supported, 0, sizeof(vk_info->supported));
2135 vk_info->supported[WINED3D_VK_EXT_NONE] = TRUE;
2137 if ((vr = VK_CALL(vkCreateInstance(&instance_info, NULL, &instance))) < 0)
2139 WARN("Failed to create Vulkan instance, vr %s.\n", wined3d_debug_vkresult(vr));
2140 goto fail;
2143 TRACE("Created Vulkan instance %p.\n", instance);
2145 #define LOAD_INSTANCE_PFN(name) \
2146 if (!(vk_ops->name = (void *)VK_CALL(vkGetInstanceProcAddr(instance, #name)))) \
2148 WARN("Could not get instance proc addr for '" #name "'.\n"); \
2149 goto fail; \
2151 #define LOAD_INSTANCE_OPT_PFN(name) \
2152 vk_ops->name = (void *)VK_CALL(vkGetInstanceProcAddr(instance, #name));
2153 #define VK_INSTANCE_PFN LOAD_INSTANCE_PFN
2154 #define VK_INSTANCE_EXT_PFN LOAD_INSTANCE_OPT_PFN
2155 #define VK_DEVICE_PFN LOAD_INSTANCE_PFN
2156 #define VK_DEVICE_EXT_PFN LOAD_INSTANCE_OPT_PFN
2157 VK_INSTANCE_FUNCS()
2158 VK_DEVICE_FUNCS()
2159 #undef VK_INSTANCE_PFN
2160 #undef VK_INSTANCE_EXT_PFN
2161 #undef VK_DEVICE_PFN
2162 #undef VK_DEVICE_EXT_PFN
2164 #define MAP_INSTANCE_FUNCTION(core_pfn, ext_pfn) \
2165 if (!vk_ops->core_pfn) \
2166 vk_ops->core_pfn = (void *)VK_CALL(vkGetInstanceProcAddr(instance, #ext_pfn));
2167 MAP_INSTANCE_FUNCTION(vkGetPhysicalDeviceProperties2, vkGetPhysicalDeviceProperties2KHR)
2168 MAP_INSTANCE_FUNCTION(vkGetPhysicalDeviceFeatures2, vkGetPhysicalDeviceFeatures2KHR)
2169 #undef MAP_INSTANCE_FUNCTION
2171 vk_info->instance = instance;
2173 return TRUE;
2175 fail:
2176 if (vk_ops->vkDestroyInstance)
2177 VK_CALL(vkDestroyInstance(instance, NULL));
2178 wined3d_unload_vulkan(vk_info);
2179 return FALSE;
2182 static VkPhysicalDevice get_vulkan_physical_device(struct wined3d_vk_info *vk_info)
2184 VkPhysicalDevice physical_devices[1];
2185 uint32_t count;
2186 VkResult vr;
2188 if ((vr = VK_CALL(vkEnumeratePhysicalDevices(vk_info->instance, &count, NULL))) < 0)
2190 WARN("Failed to enumerate physical devices, vr %s.\n", wined3d_debug_vkresult(vr));
2191 return VK_NULL_HANDLE;
2193 if (!count)
2195 WARN("No physical device.\n");
2196 return VK_NULL_HANDLE;
2198 if (count > 1)
2200 /* TODO: Create wined3d_adapter for each device. */
2201 FIXME("Multiple physical devices available.\n");
2202 count = 1;
2205 if ((vr = VK_CALL(vkEnumeratePhysicalDevices(vk_info->instance, &count, physical_devices))) < 0)
2207 WARN("Failed to get physical devices, vr %s.\n", wined3d_debug_vkresult(vr));
2208 return VK_NULL_HANDLE;
2211 return physical_devices[0];
2214 static enum wined3d_display_driver guess_display_driver(enum wined3d_pci_vendor vendor)
2216 switch (vendor)
2218 case HW_VENDOR_AMD: return DRIVER_AMD_RX;
2219 case HW_VENDOR_INTEL: return DRIVER_INTEL_HD4000;
2220 case HW_VENDOR_NVIDIA: return DRIVER_NVIDIA_GEFORCE8;
2221 default: return DRIVER_WINE;
2225 static bool adapter_vk_init_driver_info(struct wined3d_adapter_vk *adapter_vk,
2226 const VkPhysicalDeviceProperties *properties)
2228 const VkPhysicalDeviceMemoryProperties *memory_properties = &adapter_vk->memory_properties;
2229 const struct wined3d_gpu_description *gpu_description;
2230 struct wined3d_gpu_description description;
2231 UINT64 vram_bytes, sysmem_bytes;
2232 const VkMemoryType *type;
2233 const VkMemoryHeap *heap;
2234 unsigned int i;
2236 TRACE("Device name: %s.\n", debugstr_a(properties->deviceName));
2237 TRACE("Vendor ID: 0x%04x, Device ID: 0x%04x.\n", properties->vendorID, properties->deviceID);
2238 TRACE("Driver version: %#x.\n", properties->driverVersion);
2239 TRACE("API version: %s.\n", debug_vk_version(properties->apiVersion));
2241 for (i = 0, vram_bytes = 0, sysmem_bytes = 0; i < memory_properties->memoryHeapCount; ++i)
2243 heap = &memory_properties->memoryHeaps[i];
2244 TRACE("Memory heap [%u]: flags %#x, size 0x%s.\n",
2245 i, heap->flags, wine_dbgstr_longlong(heap->size));
2246 if (heap->flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT)
2247 vram_bytes += heap->size;
2248 else
2249 sysmem_bytes += heap->size;
2251 TRACE("Total device memory: 0x%s.\n", wine_dbgstr_longlong(vram_bytes));
2252 TRACE("Total shared system memory: 0x%s.\n", wine_dbgstr_longlong(sysmem_bytes));
2254 for (i = 0; i < memory_properties->memoryTypeCount; ++i)
2256 type = &memory_properties->memoryTypes[i];
2257 TRACE("Memory type [%u]: flags %#x, heap %u.\n", i, type->propertyFlags, type->heapIndex);
2260 if (!(gpu_description = wined3d_get_user_override_gpu_description(properties->vendorID, properties->deviceID)))
2261 gpu_description = wined3d_get_gpu_description(properties->vendorID, properties->deviceID);
2263 if (!gpu_description)
2265 FIXME("Failed to retrieve GPU description for device %s %04x:%04x.\n",
2266 debugstr_a(properties->deviceName), properties->vendorID, properties->deviceID);
2268 description.vendor = properties->vendorID;
2269 description.device = properties->deviceID;
2270 description.description = properties->deviceName;
2271 description.driver = guess_display_driver(properties->vendorID);
2272 description.vidmem = vram_bytes;
2274 gpu_description = &description;
2277 return wined3d_driver_info_init(&adapter_vk->a.driver_info, gpu_description,
2278 adapter_vk->a.d3d_info.feature_level, vram_bytes, sysmem_bytes);
2281 static enum wined3d_feature_level feature_level_from_caps(const struct shader_caps *shader_caps)
2283 unsigned int shader_model;
2285 shader_model = min(shader_caps->vs_version, shader_caps->ps_version);
2286 shader_model = min(shader_model, max(shader_caps->gs_version, 3));
2287 shader_model = min(shader_model, max(shader_caps->hs_version, 4));
2288 shader_model = min(shader_model, max(shader_caps->ds_version, 4));
2290 if (shader_model >= 5)
2291 return WINED3D_FEATURE_LEVEL_11_1;
2293 if (shader_model >= 4)
2294 return WINED3D_FEATURE_LEVEL_10_1;
2296 return WINED3D_FEATURE_LEVEL_NONE;
2299 static void wined3d_adapter_vk_init_d3d_info(struct wined3d_adapter_vk *adapter_vk, uint32_t wined3d_creation_flags)
2301 struct wined3d_d3d_info *d3d_info = &adapter_vk->a.d3d_info;
2302 struct wined3d_vertex_caps vertex_caps;
2303 struct fragment_caps fragment_caps;
2304 struct shader_caps shader_caps;
2306 adapter_vk->a.shader_backend->shader_get_caps(&adapter_vk->a, &shader_caps);
2307 adapter_vk->a.vertex_pipe->vp_get_caps(&adapter_vk->a, &vertex_caps);
2308 adapter_vk->a.fragment_pipe->get_caps(&adapter_vk->a, &fragment_caps);
2310 d3d_info->limits.vs_version = shader_caps.vs_version;
2311 d3d_info->limits.hs_version = shader_caps.hs_version;
2312 d3d_info->limits.ds_version = shader_caps.ds_version;
2313 d3d_info->limits.gs_version = shader_caps.gs_version;
2314 d3d_info->limits.ps_version = shader_caps.ps_version;
2315 d3d_info->limits.cs_version = shader_caps.cs_version;
2316 d3d_info->limits.vs_uniform_count = shader_caps.vs_uniform_count;
2317 d3d_info->limits.ps_uniform_count = shader_caps.ps_uniform_count;
2318 d3d_info->limits.varying_count = shader_caps.varying_count;
2319 d3d_info->limits.ffp_textures = fragment_caps.MaxSimultaneousTextures;
2320 d3d_info->limits.ffp_blend_stages = fragment_caps.MaxTextureBlendStages;
2321 d3d_info->limits.ffp_vertex_blend_matrices = vertex_caps.max_vertex_blend_matrices;
2322 d3d_info->limits.active_light_count = vertex_caps.max_active_lights;
2324 d3d_info->limits.max_rt_count = WINED3D_MAX_RENDER_TARGETS;
2325 d3d_info->limits.max_clip_distances = WINED3D_MAX_CLIP_DISTANCES;
2326 d3d_info->limits.texture_size = adapter_vk->device_limits.maxImageDimension2D;
2327 d3d_info->limits.pointsize_max = adapter_vk->device_limits.pointSizeRange[1];
2329 d3d_info->wined3d_creation_flags = wined3d_creation_flags;
2331 d3d_info->xyzrhw = vertex_caps.xyzrhw;
2332 d3d_info->emulated_flatshading = vertex_caps.emulated_flatshading;
2333 d3d_info->ffp_generic_attributes = vertex_caps.ffp_generic_attributes;
2334 d3d_info->ffp_alpha_test = false;
2335 d3d_info->vs_clipping = !!(shader_caps.wined3d_caps & WINED3D_SHADER_CAP_VS_CLIPPING);
2336 d3d_info->shader_color_key = !!(fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_COLOR_KEY);
2337 d3d_info->shader_double_precision = !!(shader_caps.wined3d_caps & WINED3D_SHADER_CAP_DOUBLE_PRECISION);
2338 d3d_info->shader_output_interpolation = !!(shader_caps.wined3d_caps & WINED3D_SHADER_CAP_OUTPUT_INTERPOLATION);
2339 d3d_info->viewport_array_index_any_shader = false; /* VK_EXT_shader_viewport_index_layer */
2340 d3d_info->texture_npot = true;
2341 d3d_info->texture_npot_conditional = true;
2342 d3d_info->draw_base_vertex_offset = true;
2343 d3d_info->vertex_bgra = true;
2344 d3d_info->texture_swizzle = true;
2345 d3d_info->srgb_read_control = false;
2346 d3d_info->srgb_write_control = false;
2347 d3d_info->clip_control = true;
2348 d3d_info->full_ffp_varyings = !!(shader_caps.wined3d_caps & WINED3D_SHADER_CAP_FULL_FFP_VARYINGS);
2349 d3d_info->scaled_resolve = false;
2350 d3d_info->pbo = true;
2351 d3d_info->feature_level = feature_level_from_caps(&shader_caps);
2352 d3d_info->subpixel_viewport = true;
2353 d3d_info->fences = true;
2355 /* Like GL, Vulkan doesn't explicitly specify a filling convention and only mandates that a
2356 * shared edge of two adjacent triangles generate a fragment for exactly one of the triangles.
2358 * However, every Vulkan implementation we have seen so far uses a top-left rule. Hardware
2359 * that differs either predates Vulkan (d3d9 class HW, GeForce 9xxx) or behaves the way we
2360 * want in Vulkan (MacOS Radeon driver through MoltenVK). */
2361 d3d_info->filling_convention_offset = 0.0f;
2363 d3d_info->multisample_draw_location = WINED3D_LOCATION_TEXTURE_RGB;
2366 static bool wined3d_adapter_vk_init_device_extensions(struct wined3d_adapter_vk *adapter_vk)
2368 VkPhysicalDevice physical_device = adapter_vk->physical_device;
2369 struct wined3d_vk_info *vk_info = &adapter_vk->vk_info;
2370 unsigned int count, enable_count, i, j;
2371 const char **enabled_extensions = NULL;
2372 VkExtensionProperties *extensions;
2373 bool found, success = false;
2374 SIZE_T enable_size = 0;
2375 VkResult vr;
2377 static const struct
2379 const char *name;
2380 unsigned int core_since_version;
2381 bool required;
2383 info[] =
2385 {VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, ~0u},
2386 {VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, ~0u, true},
2387 {VK_KHR_MAINTENANCE1_EXTENSION_NAME, VK_API_VERSION_1_1, true},
2388 {VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME,VK_API_VERSION_1_2},
2389 {VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, VK_API_VERSION_1_1, true},
2390 {VK_KHR_SWAPCHAIN_EXTENSION_NAME, ~0u, true},
2391 {VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME, VK_API_VERSION_1_2},
2394 static const struct
2396 const char *name;
2397 enum wined3d_vk_extension extension;
2399 map[] =
2401 {VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, WINED3D_VK_EXT_TRANSFORM_FEEDBACK},
2402 {VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME, WINED3D_VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE},
2403 {VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME, WINED3D_VK_EXT_HOST_QUERY_RESET},
2406 if ((vr = VK_CALL(vkEnumerateDeviceExtensionProperties(physical_device, NULL, &count, NULL))) < 0)
2408 ERR("Failed to enumerate device extensions, vr %s.\n", wined3d_debug_vkresult(vr));
2409 return false;
2412 if (!(extensions = heap_calloc(count, sizeof(*extensions))))
2414 ERR("Failed to allocate extension properties array.\n");
2415 return false;
2418 if ((vr = VK_CALL(vkEnumerateDeviceExtensionProperties(physical_device, NULL, &count, extensions))) < 0)
2420 ERR("Failed to enumerate device extensions, vr %s.\n", wined3d_debug_vkresult(vr));
2421 goto done;
2424 TRACE("Vulkan device extensions reported:\n");
2425 for (i = 0; i < count; ++i)
2427 TRACE(" - %s.\n", debugstr_a(extensions[i].extensionName));
2430 for (i = 0, enable_count = 0; i < ARRAY_SIZE(info); ++i)
2432 if (info[i].core_since_version <= vk_info->api_version)
2433 continue;
2435 for (j = 0, found = false; j < count; ++j)
2437 if (!strcmp(extensions[j].extensionName, info[i].name))
2439 found = true;
2440 break;
2444 if (!found)
2446 if (!info[i].required)
2447 continue;
2448 WARN("Required extension '%s' is not available.\n", info[i].name);
2449 goto done;
2452 TRACE("Enabling device extension '%s'.\n", info[i].name);
2453 if (!wined3d_array_reserve((void **)&enabled_extensions, &enable_size,
2454 enable_count + 1, sizeof(*enabled_extensions)))
2456 ERR("Failed to allocate enabled extensions array.\n");
2457 goto done;
2459 enabled_extensions[enable_count++] = info[i].name;
2461 success = true;
2463 for (i = 0; i < ARRAY_SIZE(map); ++i)
2465 for (j = 0; j < enable_count; ++j)
2467 if (!strcmp(enabled_extensions[j], map[i].name))
2469 vk_info->supported[map[i].extension] = TRUE;
2470 break;
2475 done:
2476 if (success)
2478 adapter_vk->device_extension_count = enable_count;
2479 adapter_vk->device_extensions = enabled_extensions;
2481 else
2483 heap_free(enabled_extensions);
2485 heap_free(extensions);
2486 return success;
2489 static BOOL wined3d_adapter_vk_init(struct wined3d_adapter_vk *adapter_vk,
2490 unsigned int ordinal, unsigned int wined3d_creation_flags)
2492 struct wined3d_vk_info *vk_info = &adapter_vk->vk_info;
2493 struct wined3d_adapter *adapter = &adapter_vk->a;
2494 VkPhysicalDeviceIDProperties id_properties;
2495 VkPhysicalDeviceProperties2 properties2;
2496 LUID primary_luid, *luid = NULL;
2498 TRACE("adapter_vk %p, ordinal %u, wined3d_creation_flags %#x.\n",
2499 adapter_vk, ordinal, wined3d_creation_flags);
2501 if (!wined3d_init_vulkan(vk_info))
2503 WARN("Failed to initialize Vulkan.\n");
2504 return FALSE;
2507 if (!(adapter_vk->physical_device = get_vulkan_physical_device(vk_info)))
2508 goto fail_vulkan;
2510 if (!wined3d_adapter_vk_init_device_extensions(adapter_vk))
2511 goto fail_vulkan;
2513 memset(&id_properties, 0, sizeof(id_properties));
2514 id_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
2515 properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
2516 properties2.pNext = &id_properties;
2518 if (vk_info->vk_ops.vkGetPhysicalDeviceProperties2)
2519 VK_CALL(vkGetPhysicalDeviceProperties2(adapter_vk->physical_device, &properties2));
2520 else
2521 VK_CALL(vkGetPhysicalDeviceProperties(adapter_vk->physical_device, &properties2.properties));
2522 adapter_vk->device_limits = properties2.properties.limits;
2524 VK_CALL(vkGetPhysicalDeviceMemoryProperties(adapter_vk->physical_device, &adapter_vk->memory_properties));
2526 if (id_properties.deviceLUIDValid)
2527 luid = (LUID *)id_properties.deviceLUID;
2528 else if (ordinal == 0 && wined3d_get_primary_adapter_luid(&primary_luid))
2529 luid = &primary_luid;
2531 if (!wined3d_adapter_init(adapter, ordinal, luid, &wined3d_adapter_vk_ops))
2533 heap_free(adapter_vk->device_extensions);
2534 goto fail_vulkan;
2537 adapter->vertex_pipe = wined3d_spirv_vertex_pipe_init_vk();
2538 adapter->fragment_pipe = wined3d_spirv_fragment_pipe_init_vk();
2539 adapter->misc_state_template = misc_state_template_vk;
2540 adapter->shader_backend = wined3d_spirv_shader_backend_init_vk();
2542 wined3d_adapter_vk_init_d3d_info(adapter_vk, wined3d_creation_flags);
2544 if (!adapter_vk_init_driver_info(adapter_vk, &properties2.properties))
2545 goto fail;
2546 TRACE("Reporting (fake) driver version 0x%08x-0x%08x.\n",
2547 adapter_vk->a.driver_info.version_high, adapter_vk->a.driver_info.version_low);
2548 adapter->vram_bytes_used = 0;
2549 TRACE("Emulating 0x%s bytes of video ram.\n", wine_dbgstr_longlong(adapter->driver_info.vram_bytes));
2551 memcpy(&adapter->driver_uuid, id_properties.driverUUID, sizeof(adapter->driver_uuid));
2552 memcpy(&adapter->device_uuid, id_properties.deviceUUID, sizeof(adapter->device_uuid));
2554 if (!wined3d_adapter_vk_init_format_info(adapter_vk, vk_info))
2555 goto fail;
2557 return TRUE;
2559 fail:
2560 wined3d_adapter_cleanup(adapter);
2561 heap_free(adapter_vk->device_extensions);
2562 fail_vulkan:
2563 VK_CALL(vkDestroyInstance(vk_info->instance, NULL));
2564 wined3d_unload_vulkan(vk_info);
2565 return FALSE;
2568 struct wined3d_adapter *wined3d_adapter_vk_create(unsigned int ordinal,
2569 unsigned int wined3d_creation_flags)
2571 struct wined3d_adapter_vk *adapter_vk;
2573 if (!(adapter_vk = heap_alloc_zero(sizeof(*adapter_vk))))
2574 return NULL;
2576 if (!wined3d_adapter_vk_init(adapter_vk, ordinal, wined3d_creation_flags))
2578 heap_free(adapter_vk);
2579 return NULL;
2582 TRACE("Created adapter %p.\n", adapter_vk);
2584 return &adapter_vk->a;