2 * Copyright 2002-2004 Jason Edmeades
3 * Copyright 2002-2004 Raphael Junqueira
4 * Copyright 2004 Christian Costa
5 * Copyright 2005 Oliver Stieber
6 * Copyright 2006, 2008 Henri Verbeet
7 * Copyright 2007-2011, 2013 Stefan Dösinger for CodeWeavers
8 * Copyright 2009-2020 Henri Verbeet for CodeWeavers
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wined3d_private.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(d3d
);
31 VkCompareOp
vk_compare_op_from_wined3d(enum wined3d_cmp_func op
)
35 case WINED3D_CMP_NEVER
:
36 return VK_COMPARE_OP_NEVER
;
37 case WINED3D_CMP_LESS
:
38 return VK_COMPARE_OP_LESS
;
39 case WINED3D_CMP_EQUAL
:
40 return VK_COMPARE_OP_EQUAL
;
41 case WINED3D_CMP_LESSEQUAL
:
42 return VK_COMPARE_OP_LESS_OR_EQUAL
;
43 case WINED3D_CMP_GREATER
:
44 return VK_COMPARE_OP_GREATER
;
45 case WINED3D_CMP_NOTEQUAL
:
46 return VK_COMPARE_OP_NOT_EQUAL
;
47 case WINED3D_CMP_GREATEREQUAL
:
48 return VK_COMPARE_OP_GREATER_OR_EQUAL
;
49 case WINED3D_CMP_ALWAYS
:
50 return VK_COMPARE_OP_ALWAYS
;
53 WARN("Unhandled compare operation %#x.\n", op
);
55 FIXME("Unhandled compare operation %#x.\n", op
);
56 return VK_COMPARE_OP_NEVER
;
60 VkShaderStageFlagBits
vk_shader_stage_from_wined3d(enum wined3d_shader_type shader_type
)
64 case WINED3D_SHADER_TYPE_VERTEX
:
65 return VK_SHADER_STAGE_VERTEX_BIT
;
66 case WINED3D_SHADER_TYPE_HULL
:
67 return VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT
;
68 case WINED3D_SHADER_TYPE_DOMAIN
:
69 return VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT
;
70 case WINED3D_SHADER_TYPE_GEOMETRY
:
71 return VK_SHADER_STAGE_GEOMETRY_BIT
;
72 case WINED3D_SHADER_TYPE_PIXEL
:
73 return VK_SHADER_STAGE_FRAGMENT_BIT
;
74 case WINED3D_SHADER_TYPE_COMPUTE
:
75 return VK_SHADER_STAGE_COMPUTE_BIT
;
77 ERR("Unhandled shader type %s.\n", debug_shader_type(shader_type
));
82 static VkBlendFactor
vk_blend_factor_from_wined3d(enum wined3d_blend blend
,
83 const struct wined3d_format
*dst_format
, bool alpha
)
87 case WINED3D_BLEND_ZERO
:
88 return VK_BLEND_FACTOR_ZERO
;
89 case WINED3D_BLEND_ONE
:
90 return VK_BLEND_FACTOR_ONE
;
91 case WINED3D_BLEND_SRCCOLOR
:
92 return VK_BLEND_FACTOR_SRC_COLOR
;
93 case WINED3D_BLEND_INVSRCCOLOR
:
94 return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR
;
95 case WINED3D_BLEND_SRCALPHA
:
96 return VK_BLEND_FACTOR_SRC_ALPHA
;
97 case WINED3D_BLEND_INVSRCALPHA
:
98 return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA
;
99 case WINED3D_BLEND_DESTALPHA
:
100 if (dst_format
->alpha_size
)
101 return VK_BLEND_FACTOR_DST_ALPHA
;
102 return VK_BLEND_FACTOR_ONE
;
103 case WINED3D_BLEND_INVDESTALPHA
:
104 if (dst_format
->alpha_size
)
105 return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA
;
106 return VK_BLEND_FACTOR_ZERO
;
107 case WINED3D_BLEND_DESTCOLOR
:
108 return VK_BLEND_FACTOR_DST_COLOR
;
109 case WINED3D_BLEND_INVDESTCOLOR
:
110 return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR
;
111 case WINED3D_BLEND_SRCALPHASAT
:
112 return VK_BLEND_FACTOR_SRC_ALPHA_SATURATE
;
113 case WINED3D_BLEND_BLENDFACTOR
:
115 return VK_BLEND_FACTOR_CONSTANT_ALPHA
;
116 return VK_BLEND_FACTOR_CONSTANT_COLOR
;
117 case WINED3D_BLEND_INVBLENDFACTOR
:
119 return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA
;
120 return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR
;
121 case WINED3D_BLEND_SRC1COLOR
:
122 return VK_BLEND_FACTOR_SRC1_COLOR
;
123 case WINED3D_BLEND_INVSRC1COLOR
:
124 return VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR
;
125 case WINED3D_BLEND_SRC1ALPHA
:
126 return VK_BLEND_FACTOR_SRC1_ALPHA
;
127 case WINED3D_BLEND_INVSRC1ALPHA
:
128 return VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA
;
130 FIXME("Unhandled blend %#x.\n", blend
);
131 return VK_BLEND_FACTOR_ZERO
;
135 static VkBlendOp
vk_blend_op_from_wined3d(enum wined3d_blend_op op
)
139 case WINED3D_BLEND_OP_ADD
:
140 return VK_BLEND_OP_ADD
;
141 case WINED3D_BLEND_OP_SUBTRACT
:
142 return VK_BLEND_OP_SUBTRACT
;
143 case WINED3D_BLEND_OP_REVSUBTRACT
:
144 return VK_BLEND_OP_REVERSE_SUBTRACT
;
145 case WINED3D_BLEND_OP_MIN
:
146 return VK_BLEND_OP_MIN
;
147 case WINED3D_BLEND_OP_MAX
:
148 return VK_BLEND_OP_MAX
;
150 FIXME("Unhandled blend op %#x.\n", op
);
151 return VK_BLEND_OP_ADD
;
155 static VkColorComponentFlags
vk_colour_write_mask_from_wined3d(uint32_t wined3d_mask
)
157 VkColorComponentFlags vk_mask
= 0;
159 if (wined3d_mask
& WINED3DCOLORWRITEENABLE_RED
)
160 vk_mask
|= VK_COLOR_COMPONENT_R_BIT
;
161 if (wined3d_mask
& WINED3DCOLORWRITEENABLE_GREEN
)
162 vk_mask
|= VK_COLOR_COMPONENT_G_BIT
;
163 if (wined3d_mask
& WINED3DCOLORWRITEENABLE_BLUE
)
164 vk_mask
|= VK_COLOR_COMPONENT_B_BIT
;
165 if (wined3d_mask
& WINED3DCOLORWRITEENABLE_ALPHA
)
166 vk_mask
|= VK_COLOR_COMPONENT_A_BIT
;
171 static VkCullModeFlags
vk_cull_mode_from_wined3d(enum wined3d_cull mode
)
175 case WINED3D_CULL_NONE
:
176 return VK_CULL_MODE_NONE
;
177 case WINED3D_CULL_FRONT
:
178 return VK_CULL_MODE_FRONT_BIT
;
179 case WINED3D_CULL_BACK
:
180 return VK_CULL_MODE_BACK_BIT
;
182 FIXME("Unhandled cull mode %#x.\n", mode
);
183 return VK_CULL_MODE_NONE
;
187 static VkPrimitiveTopology
vk_topology_from_wined3d(enum wined3d_primitive_type t
)
191 case WINED3D_PT_POINTLIST
:
192 return VK_PRIMITIVE_TOPOLOGY_POINT_LIST
;
193 case WINED3D_PT_LINELIST
:
194 return VK_PRIMITIVE_TOPOLOGY_LINE_LIST
;
195 case WINED3D_PT_LINESTRIP
:
196 return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP
;
197 case WINED3D_PT_TRIANGLELIST
:
198 return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST
;
199 case WINED3D_PT_TRIANGLESTRIP
:
200 return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP
;
201 case WINED3D_PT_TRIANGLEFAN
:
202 return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN
;
203 case WINED3D_PT_LINELIST_ADJ
:
204 return VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY
;
205 case WINED3D_PT_LINESTRIP_ADJ
:
206 return VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY
;
207 case WINED3D_PT_TRIANGLELIST_ADJ
:
208 return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY
;
209 case WINED3D_PT_TRIANGLESTRIP_ADJ
:
210 return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY
;
211 case WINED3D_PT_PATCH
:
212 return VK_PRIMITIVE_TOPOLOGY_PATCH_LIST
;
214 FIXME("Unhandled primitive type %s.\n", debug_d3dprimitivetype(t
));
215 case WINED3D_PT_UNDEFINED
:
220 static VkStencilOp
vk_stencil_op_from_wined3d(enum wined3d_stencil_op op
)
224 case WINED3D_STENCIL_OP_KEEP
:
225 return VK_STENCIL_OP_KEEP
;
226 case WINED3D_STENCIL_OP_ZERO
:
227 return VK_STENCIL_OP_ZERO
;
228 case WINED3D_STENCIL_OP_REPLACE
:
229 return VK_STENCIL_OP_REPLACE
;
230 case WINED3D_STENCIL_OP_INCR_SAT
:
231 return VK_STENCIL_OP_INCREMENT_AND_CLAMP
;
232 case WINED3D_STENCIL_OP_DECR_SAT
:
233 return VK_STENCIL_OP_DECREMENT_AND_CLAMP
;
234 case WINED3D_STENCIL_OP_INVERT
:
235 return VK_STENCIL_OP_INVERT
;
236 case WINED3D_STENCIL_OP_INCR
:
237 return VK_STENCIL_OP_INCREMENT_AND_WRAP
;
238 case WINED3D_STENCIL_OP_DECR
:
239 return VK_STENCIL_OP_DECREMENT_AND_WRAP
;
242 WARN("Unhandled stencil operation %#x.\n", op
);
244 FIXME("Unhandled stencil operation %#x.\n", op
);
245 return VK_STENCIL_OP_KEEP
;
249 static void wined3d_allocator_chunk_vk_lock(struct wined3d_allocator_chunk_vk
*chunk_vk
)
251 wined3d_device_vk_allocator_lock(wined3d_device_vk_from_allocator(chunk_vk
->c
.allocator
));
254 static void wined3d_allocator_chunk_vk_unlock(struct wined3d_allocator_chunk_vk
*chunk_vk
)
256 wined3d_device_vk_allocator_unlock(wined3d_device_vk_from_allocator(chunk_vk
->c
.allocator
));
259 void *wined3d_allocator_chunk_vk_map(struct wined3d_allocator_chunk_vk
*chunk_vk
,
260 struct wined3d_context_vk
*context_vk
)
262 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
263 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
267 TRACE("chunk %p, memory 0x%s, map_ptr %p.\n", chunk_vk
,
268 wine_dbgstr_longlong(chunk_vk
->vk_memory
), chunk_vk
->c
.map_ptr
);
270 wined3d_allocator_chunk_vk_lock(chunk_vk
);
272 if (!chunk_vk
->c
.map_ptr
&& (vr
= VK_CALL(vkMapMemory(device_vk
->vk_device
,
273 chunk_vk
->vk_memory
, 0, VK_WHOLE_SIZE
, 0, &chunk_vk
->c
.map_ptr
))) < 0)
275 ERR("Failed to map chunk memory, vr %s.\n", wined3d_debug_vkresult(vr
));
276 wined3d_allocator_chunk_vk_unlock(chunk_vk
);
280 ++chunk_vk
->c
.map_count
;
281 map_ptr
= chunk_vk
->c
.map_ptr
;
283 wined3d_allocator_chunk_vk_unlock(chunk_vk
);
288 void wined3d_allocator_chunk_vk_unmap(struct wined3d_allocator_chunk_vk
*chunk_vk
,
289 struct wined3d_context_vk
*context_vk
)
291 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
292 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
294 TRACE("chunk_vk %p, context_vk %p.\n", chunk_vk
, context_vk
);
296 wined3d_allocator_chunk_vk_lock(chunk_vk
);
298 if (--chunk_vk
->c
.map_count
)
300 wined3d_allocator_chunk_vk_unlock(chunk_vk
);
304 VK_CALL(vkUnmapMemory(device_vk
->vk_device
, chunk_vk
->vk_memory
));
305 chunk_vk
->c
.map_ptr
= NULL
;
307 wined3d_allocator_chunk_vk_unlock(chunk_vk
);
310 VkDeviceMemory
wined3d_context_vk_allocate_vram_chunk_memory(struct wined3d_context_vk
*context_vk
,
311 unsigned int pool
, size_t size
)
313 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
314 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
315 VkMemoryAllocateInfo allocate_info
;
316 VkDeviceMemory vk_memory
;
319 allocate_info
.sType
= VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO
;
320 allocate_info
.pNext
= NULL
;
321 allocate_info
.allocationSize
= size
;
322 allocate_info
.memoryTypeIndex
= pool
;
323 if ((vr
= VK_CALL(vkAllocateMemory(device_vk
->vk_device
, &allocate_info
, NULL
, &vk_memory
))) < 0)
325 ERR("Failed to allocate memory, vr %s.\n", wined3d_debug_vkresult(vr
));
326 return VK_NULL_HANDLE
;
332 static struct wined3d_allocator_block
*wined3d_context_vk_allocate_memory(struct wined3d_context_vk
*context_vk
,
333 unsigned int memory_type
, VkDeviceSize size
, VkDeviceMemory
*vk_memory
)
335 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
336 struct wined3d_allocator
*allocator
= &device_vk
->allocator
;
337 struct wined3d_allocator_block
*block
;
339 wined3d_device_vk_allocator_lock(device_vk
);
341 if (size
> WINED3D_ALLOCATOR_CHUNK_SIZE
/ 2)
343 *vk_memory
= wined3d_context_vk_allocate_vram_chunk_memory(context_vk
, memory_type
, size
);
344 wined3d_device_vk_allocator_unlock(device_vk
);
348 if (!(block
= wined3d_allocator_allocate(allocator
, &context_vk
->c
, memory_type
, size
)))
350 wined3d_device_vk_allocator_unlock(device_vk
);
351 *vk_memory
= VK_NULL_HANDLE
;
355 *vk_memory
= wined3d_allocator_chunk_vk(block
->chunk
)->vk_memory
;
357 wined3d_device_vk_allocator_unlock(device_vk
);
361 static void wined3d_context_vk_free_memory(struct wined3d_context_vk
*context_vk
, struct wined3d_allocator_block
*block
)
363 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
365 assert(block
->chunk
->allocator
== &device_vk
->allocator
);
366 wined3d_device_vk_allocator_lock(device_vk
);
367 wined3d_allocator_block_free(block
);
368 wined3d_device_vk_allocator_unlock(device_vk
);
371 static bool wined3d_context_vk_create_slab_bo(struct wined3d_context_vk
*context_vk
,
372 VkDeviceSize size
, VkBufferUsageFlags usage
, VkMemoryPropertyFlags memory_type
, struct wined3d_bo_vk
*bo
)
374 const struct wined3d_adapter_vk
*adapter_vk
= wined3d_adapter_vk(context_vk
->c
.device
->adapter
);
375 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
376 const VkPhysicalDeviceLimits
*limits
= &adapter_vk
->device_limits
;
377 struct wined3d_bo_slab_vk_key key
;
378 struct wined3d_bo_slab_vk
*slab
;
379 struct wine_rb_entry
*entry
;
380 size_t object_size
, idx
;
383 if (size
> WINED3D_ALLOCATOR_MIN_BLOCK_SIZE
/ 2)
386 alignment
= WINED3D_SLAB_BO_MIN_OBJECT_ALIGN
;
387 if ((usage
& (VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT
| VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT
))
388 && limits
->minTexelBufferOffsetAlignment
> alignment
)
389 alignment
= limits
->minTexelBufferOffsetAlignment
;
390 if ((usage
& VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
) && limits
->minUniformBufferOffsetAlignment
)
391 alignment
= limits
->minUniformBufferOffsetAlignment
;
392 if ((usage
& VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
) && limits
->minStorageBufferOffsetAlignment
)
393 alignment
= limits
->minStorageBufferOffsetAlignment
;
395 object_size
= (size
+ (alignment
- 1)) & ~(alignment
- 1);
396 if (object_size
< WINED3D_ALLOCATOR_MIN_BLOCK_SIZE
/ 32)
397 object_size
= WINED3D_ALLOCATOR_MIN_BLOCK_SIZE
/ 32;
398 key
.memory_type
= memory_type
;
400 key
.size
= 32 * object_size
;
402 wined3d_device_vk_allocator_lock(device_vk
);
404 if ((entry
= wine_rb_get(&context_vk
->bo_slab_available
, &key
)))
406 slab
= WINE_RB_ENTRY_VALUE(entry
, struct wined3d_bo_slab_vk
, entry
);
407 TRACE("Using existing bo slab %p.\n", slab
);
411 if (!(slab
= heap_alloc_zero(sizeof(*slab
))))
413 wined3d_device_vk_allocator_unlock(device_vk
);
414 ERR("Failed to allocate bo slab.\n");
418 if (wine_rb_put(&context_vk
->bo_slab_available
, &key
, &slab
->entry
) < 0)
420 wined3d_device_vk_allocator_unlock(device_vk
);
421 ERR("Failed to add slab to available tree.\n");
426 slab
->requested_memory_type
= memory_type
;
427 if (!wined3d_context_vk_create_bo(context_vk
, key
.size
, usage
, memory_type
, &slab
->bo
))
429 wined3d_device_vk_allocator_unlock(device_vk
);
430 ERR("Failed to create slab bo.\n");
431 wine_rb_remove(&context_vk
->bo_slab_available
, &slab
->entry
);
437 TRACE("Created new bo slab %p.\n", slab
);
440 idx
= wined3d_bit_scan(&slab
->map
);
445 wine_rb_replace(&context_vk
->bo_slab_available
, &slab
->entry
, &slab
->next
->entry
);
450 wine_rb_remove(&context_vk
->bo_slab_available
, &slab
->entry
);
454 wined3d_device_vk_allocator_unlock(device_vk
);
459 bo
->b
.buffer_offset
= idx
* object_size
;
460 bo
->b
.memory_offset
= slab
->bo
.b
.memory_offset
+ bo
->b
.buffer_offset
;
462 list_init(&bo
->b
.users
);
463 bo
->command_buffer_id
= 0;
464 bo
->host_synced
= false;
466 TRACE("Using buffer 0x%s, memory 0x%s, offset 0x%s for bo %p.\n",
467 wine_dbgstr_longlong(bo
->vk_buffer
), wine_dbgstr_longlong(bo
->vk_memory
),
468 wine_dbgstr_longlong(bo
->b
.buffer_offset
), bo
);
473 BOOL
wined3d_context_vk_create_bo(struct wined3d_context_vk
*context_vk
, VkDeviceSize size
,
474 VkBufferUsageFlags usage
, VkMemoryPropertyFlags memory_type
, struct wined3d_bo_vk
*bo
)
476 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
477 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
478 VkMemoryRequirements memory_requirements
;
479 struct wined3d_adapter_vk
*adapter_vk
;
480 VkBufferCreateInfo create_info
;
481 unsigned int memory_type_idx
;
484 if (wined3d_context_vk_create_slab_bo(context_vk
, size
, usage
, memory_type
, bo
))
487 adapter_vk
= wined3d_adapter_vk(device_vk
->d
.adapter
);
489 create_info
.sType
= VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO
;
490 create_info
.pNext
= NULL
;
491 create_info
.flags
= 0;
492 create_info
.size
= size
;
493 create_info
.usage
= usage
;
494 create_info
.sharingMode
= VK_SHARING_MODE_EXCLUSIVE
;
495 create_info
.queueFamilyIndexCount
= 0;
496 create_info
.pQueueFamilyIndices
= NULL
;
498 if ((vr
= VK_CALL(vkCreateBuffer(device_vk
->vk_device
, &create_info
, NULL
, &bo
->vk_buffer
))) < 0)
500 ERR("Failed to create Vulkan buffer, vr %s.\n", wined3d_debug_vkresult(vr
));
504 VK_CALL(vkGetBufferMemoryRequirements(device_vk
->vk_device
, bo
->vk_buffer
, &memory_requirements
));
506 memory_type_idx
= wined3d_adapter_vk_get_memory_type_index(adapter_vk
,
507 memory_requirements
.memoryTypeBits
, memory_type
);
508 if (memory_type_idx
== ~0u)
510 ERR("Failed to find suitable memory type.\n");
511 VK_CALL(vkDestroyBuffer(device_vk
->vk_device
, bo
->vk_buffer
, NULL
));
514 bo
->memory
= wined3d_context_vk_allocate_memory(context_vk
,
515 memory_type_idx
, memory_requirements
.size
, &bo
->vk_memory
);
518 ERR("Failed to allocate buffer memory.\n");
519 VK_CALL(vkDestroyBuffer(device_vk
->vk_device
, bo
->vk_buffer
, NULL
));
522 bo
->b
.memory_offset
= bo
->memory
? bo
->memory
->offset
: 0;
524 if ((vr
= VK_CALL(vkBindBufferMemory(device_vk
->vk_device
, bo
->vk_buffer
,
525 bo
->vk_memory
, bo
->b
.memory_offset
))) < 0)
527 ERR("Failed to bind buffer memory, vr %s.\n", wined3d_debug_vkresult(vr
));
529 wined3d_context_vk_free_memory(context_vk
, bo
->memory
);
531 VK_CALL(vkFreeMemory(device_vk
->vk_device
, bo
->vk_memory
, NULL
));
532 VK_CALL(vkDestroyBuffer(device_vk
->vk_device
, bo
->vk_buffer
, NULL
));
536 bo
->b
.map_ptr
= NULL
;
537 bo
->b
.buffer_offset
= 0;
540 bo
->memory_type
= adapter_vk
->memory_properties
.memoryTypes
[memory_type_idx
].propertyFlags
;
541 bo
->b
.coherent
= !!(bo
->memory_type
& VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
);
542 list_init(&bo
->b
.users
);
543 bo
->command_buffer_id
= 0;
545 bo
->host_synced
= false;
547 TRACE("Created buffer 0x%s, memory 0x%s for bo %p.\n",
548 wine_dbgstr_longlong(bo
->vk_buffer
), wine_dbgstr_longlong(bo
->vk_memory
), bo
);
553 BOOL
wined3d_context_vk_create_image(struct wined3d_context_vk
*context_vk
, VkImageType vk_image_type
,
554 VkImageUsageFlags usage
, VkFormat vk_format
, unsigned int width
, unsigned int height
, unsigned int depth
,
555 unsigned int sample_count
, unsigned int mip_levels
, unsigned int layer_count
, unsigned int flags
,
556 struct wined3d_image_vk
*image
)
558 struct wined3d_adapter_vk
*adapter_vk
= wined3d_adapter_vk(context_vk
->c
.device
->adapter
);
559 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
560 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
561 VkMemoryRequirements memory_requirements
;
562 VkImageCreateInfo create_info
;
563 unsigned int memory_type_idx
;
566 create_info
.sType
= VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
;
567 create_info
.pNext
= NULL
;
568 create_info
.flags
= flags
;
569 create_info
.imageType
= vk_image_type
;
570 create_info
.format
= vk_format
;
571 create_info
.extent
.width
= width
;
572 create_info
.extent
.height
= height
;
573 create_info
.extent
.depth
= depth
;
574 create_info
.mipLevels
= mip_levels
;
575 create_info
.arrayLayers
= layer_count
;
576 create_info
.samples
= sample_count
;
577 create_info
.tiling
= VK_IMAGE_TILING_OPTIMAL
;
578 create_info
.usage
= usage
;
579 create_info
.sharingMode
= VK_SHARING_MODE_EXCLUSIVE
;
580 create_info
.queueFamilyIndexCount
= 0;
581 create_info
.pQueueFamilyIndices
= NULL
;
582 create_info
.initialLayout
= VK_IMAGE_LAYOUT_UNDEFINED
;
584 image
->command_buffer_id
= 0;
586 vr
= VK_CALL(vkCreateImage(device_vk
->vk_device
, &create_info
, NULL
, &image
->vk_image
));
587 if (vr
!= VK_SUCCESS
)
589 ERR("Failed to create image, vr %s.\n", wined3d_debug_vkresult(vr
));
590 image
->vk_image
= VK_NULL_HANDLE
;
594 VK_CALL(vkGetImageMemoryRequirements(device_vk
->vk_device
, image
->vk_image
,
595 &memory_requirements
));
597 memory_type_idx
= wined3d_adapter_vk_get_memory_type_index(adapter_vk
,
598 memory_requirements
.memoryTypeBits
, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
);
599 if (memory_type_idx
== ~0u)
601 ERR("Failed to find suitable image memory type.\n");
602 VK_CALL(vkDestroyImage(device_vk
->vk_device
, image
->vk_image
, NULL
));
603 image
->vk_image
= VK_NULL_HANDLE
;
607 image
->memory
= wined3d_context_vk_allocate_memory(context_vk
, memory_type_idx
,
608 memory_requirements
.size
, &image
->vk_memory
);
609 if (!image
->vk_memory
)
611 ERR("Failed to allocate image memory.\n");
612 VK_CALL(vkDestroyImage(device_vk
->vk_device
, image
->vk_image
, NULL
));
613 image
->vk_image
= VK_NULL_HANDLE
;
617 vr
= VK_CALL(vkBindImageMemory(device_vk
->vk_device
, image
->vk_image
, image
->vk_memory
,
618 image
->memory
? image
->memory
->offset
: 0));
619 if (vr
!= VK_SUCCESS
)
621 VK_CALL(vkDestroyImage(device_vk
->vk_device
, image
->vk_image
, NULL
));
623 wined3d_context_vk_free_memory(context_vk
, image
->memory
);
625 VK_CALL(vkFreeMemory(device_vk
->vk_device
, image
->vk_memory
, NULL
));
626 ERR("Failed to bind image memory, vr %s.\n", wined3d_debug_vkresult(vr
));
627 image
->memory
= NULL
;
628 image
->vk_memory
= VK_NULL_HANDLE
;
629 image
->vk_image
= VK_NULL_HANDLE
;
636 static struct wined3d_retired_object_vk
*wined3d_context_vk_get_retired_object_vk(struct wined3d_context_vk
*context_vk
)
638 struct wined3d_retired_objects_vk
*retired
= &context_vk
->retired
;
639 struct wined3d_retired_object_vk
*o
;
644 retired
->free
= o
->u
.next
;
648 if (!wined3d_array_reserve((void **)&retired
->objects
, &retired
->size
,
649 retired
->count
+ 1, sizeof(*retired
->objects
)))
652 return &retired
->objects
[retired
->count
++];
655 void wined3d_context_vk_destroy_vk_framebuffer(struct wined3d_context_vk
*context_vk
,
656 VkFramebuffer vk_framebuffer
, uint64_t command_buffer_id
)
658 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
659 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
660 struct wined3d_retired_object_vk
*o
;
662 if (context_vk
->completed_command_buffer_id
> command_buffer_id
)
664 VK_CALL(vkDestroyFramebuffer(device_vk
->vk_device
, vk_framebuffer
, NULL
));
665 TRACE("Destroyed framebuffer 0x%s.\n", wine_dbgstr_longlong(vk_framebuffer
));
669 if (!(o
= wined3d_context_vk_get_retired_object_vk(context_vk
)))
671 ERR("Leaking framebuffer 0x%s.\n", wine_dbgstr_longlong(vk_framebuffer
));
675 o
->type
= WINED3D_RETIRED_FRAMEBUFFER_VK
;
676 o
->u
.vk_framebuffer
= vk_framebuffer
;
677 o
->command_buffer_id
= command_buffer_id
;
680 static void wined3d_context_vk_destroy_vk_descriptor_pool(struct wined3d_context_vk
*context_vk
,
681 VkDescriptorPool vk_descriptor_pool
, uint64_t command_buffer_id
)
683 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
684 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
685 struct wined3d_retired_object_vk
*o
;
687 if (context_vk
->completed_command_buffer_id
> command_buffer_id
)
689 VK_CALL(vkDestroyDescriptorPool(device_vk
->vk_device
, vk_descriptor_pool
, NULL
));
690 TRACE("Destroyed descriptor pool 0x%s.\n", wine_dbgstr_longlong(vk_descriptor_pool
));
694 if (!(o
= wined3d_context_vk_get_retired_object_vk(context_vk
)))
696 ERR("Leaking descriptor pool 0x%s.\n", wine_dbgstr_longlong(vk_descriptor_pool
));
700 o
->type
= WINED3D_RETIRED_DESCRIPTOR_POOL_VK
;
701 o
->u
.vk_descriptor_pool
= vk_descriptor_pool
;
702 o
->command_buffer_id
= command_buffer_id
;
705 void wined3d_context_vk_destroy_vk_memory(struct wined3d_context_vk
*context_vk
,
706 VkDeviceMemory vk_memory
, uint64_t command_buffer_id
)
708 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
709 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
710 struct wined3d_retired_object_vk
*o
;
712 if (context_vk
->completed_command_buffer_id
> command_buffer_id
)
714 VK_CALL(vkFreeMemory(device_vk
->vk_device
, vk_memory
, NULL
));
715 TRACE("Freed memory 0x%s.\n", wine_dbgstr_longlong(vk_memory
));
719 if (!(o
= wined3d_context_vk_get_retired_object_vk(context_vk
)))
721 ERR("Leaking memory 0x%s.\n", wine_dbgstr_longlong(vk_memory
));
725 o
->type
= WINED3D_RETIRED_MEMORY_VK
;
726 o
->u
.vk_memory
= vk_memory
;
727 o
->command_buffer_id
= command_buffer_id
;
730 void wined3d_context_vk_destroy_allocator_block(struct wined3d_context_vk
*context_vk
,
731 struct wined3d_allocator_block
*block
, uint64_t command_buffer_id
)
733 struct wined3d_retired_object_vk
*o
;
735 if (context_vk
->completed_command_buffer_id
> command_buffer_id
)
737 wined3d_context_vk_free_memory(context_vk
, block
);
738 TRACE("Freed block %p.\n", block
);
742 if (!(o
= wined3d_context_vk_get_retired_object_vk(context_vk
)))
744 ERR("Leaking block %p.\n", block
);
748 o
->type
= WINED3D_RETIRED_ALLOCATOR_BLOCK_VK
;
750 o
->command_buffer_id
= command_buffer_id
;
753 static void wined3d_bo_slab_vk_free_slice(struct wined3d_bo_slab_vk
*slab
,
754 SIZE_T idx
, struct wined3d_context_vk
*context_vk
)
756 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
757 struct wined3d_bo_slab_vk_key key
;
758 struct wine_rb_entry
*entry
;
760 TRACE("slab %p, idx %lu, context_vk %p.\n", slab
, idx
, context_vk
);
762 wined3d_device_vk_allocator_lock(device_vk
);
766 key
.memory_type
= slab
->requested_memory_type
;
767 key
.usage
= slab
->bo
.usage
;
768 key
.size
= slab
->bo
.size
;
770 if ((entry
= wine_rb_get(&context_vk
->bo_slab_available
, &key
)))
772 slab
->next
= WINE_RB_ENTRY_VALUE(entry
, struct wined3d_bo_slab_vk
, entry
);
773 wine_rb_replace(&context_vk
->bo_slab_available
, entry
, &slab
->entry
);
775 else if (wine_rb_put(&context_vk
->bo_slab_available
, &key
, &slab
->entry
) < 0)
777 ERR("Unable to return slab %p (map 0x%08x) to available tree.\n", slab
, slab
->map
);
780 slab
->map
|= 1u << idx
;
782 wined3d_device_vk_allocator_unlock(device_vk
);
785 static void wined3d_context_vk_destroy_bo_slab_slice(struct wined3d_context_vk
*context_vk
,
786 struct wined3d_bo_slab_vk
*slab
, SIZE_T idx
, uint64_t command_buffer_id
)
788 struct wined3d_retired_object_vk
*o
;
790 if (context_vk
->completed_command_buffer_id
> command_buffer_id
)
792 wined3d_bo_slab_vk_free_slice(slab
, idx
, context_vk
);
796 if (!(o
= wined3d_context_vk_get_retired_object_vk(context_vk
)))
798 ERR("Leaking slab %p, slice %#lx.\n", slab
, idx
);
802 o
->type
= WINED3D_RETIRED_BO_SLAB_SLICE_VK
;
803 o
->u
.slice
.slab
= slab
;
804 o
->u
.slice
.idx
= idx
;
805 o
->command_buffer_id
= command_buffer_id
;
808 static void wined3d_context_vk_destroy_vk_buffer(struct wined3d_context_vk
*context_vk
,
809 VkBuffer vk_buffer
, uint64_t command_buffer_id
)
811 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
812 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
813 struct wined3d_retired_object_vk
*o
;
815 if (context_vk
->completed_command_buffer_id
> command_buffer_id
)
817 VK_CALL(vkDestroyBuffer(device_vk
->vk_device
, vk_buffer
, NULL
));
818 TRACE("Destroyed buffer 0x%s.\n", wine_dbgstr_longlong(vk_buffer
));
822 if (!(o
= wined3d_context_vk_get_retired_object_vk(context_vk
)))
824 ERR("Leaking buffer 0x%s.\n", wine_dbgstr_longlong(vk_buffer
));
828 o
->type
= WINED3D_RETIRED_BUFFER_VK
;
829 o
->u
.vk_buffer
= vk_buffer
;
830 o
->command_buffer_id
= command_buffer_id
;
833 void wined3d_context_vk_destroy_vk_image(struct wined3d_context_vk
*context_vk
,
834 VkImage vk_image
, uint64_t command_buffer_id
)
836 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
837 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
838 struct wined3d_retired_object_vk
*o
;
840 if (context_vk
->completed_command_buffer_id
> command_buffer_id
)
842 VK_CALL(vkDestroyImage(device_vk
->vk_device
, vk_image
, NULL
));
843 TRACE("Destroyed image 0x%s.\n", wine_dbgstr_longlong(vk_image
));
847 if (!(o
= wined3d_context_vk_get_retired_object_vk(context_vk
)))
849 ERR("Leaking image 0x%s.\n", wine_dbgstr_longlong(vk_image
));
853 o
->type
= WINED3D_RETIRED_IMAGE_VK
;
854 o
->u
.vk_image
= vk_image
;
855 o
->command_buffer_id
= command_buffer_id
;
858 void wined3d_context_vk_destroy_vk_buffer_view(struct wined3d_context_vk
*context_vk
,
859 VkBufferView vk_view
, uint64_t command_buffer_id
)
861 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
862 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
863 struct wined3d_retired_object_vk
*o
;
865 if (context_vk
->completed_command_buffer_id
> command_buffer_id
)
867 VK_CALL(vkDestroyBufferView(device_vk
->vk_device
, vk_view
, NULL
));
868 TRACE("Destroyed buffer view 0x%s.\n", wine_dbgstr_longlong(vk_view
));
872 if (!(o
= wined3d_context_vk_get_retired_object_vk(context_vk
)))
874 ERR("Leaking buffer view 0x%s.\n", wine_dbgstr_longlong(vk_view
));
878 o
->type
= WINED3D_RETIRED_BUFFER_VIEW_VK
;
879 o
->u
.vk_buffer_view
= vk_view
;
880 o
->command_buffer_id
= command_buffer_id
;
883 void wined3d_context_vk_destroy_vk_image_view(struct wined3d_context_vk
*context_vk
,
884 VkImageView vk_view
, uint64_t command_buffer_id
)
886 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
887 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
888 struct wined3d_retired_object_vk
*o
;
890 if (context_vk
->completed_command_buffer_id
> command_buffer_id
)
892 VK_CALL(vkDestroyImageView(device_vk
->vk_device
, vk_view
, NULL
));
893 TRACE("Destroyed image view 0x%s.\n", wine_dbgstr_longlong(vk_view
));
897 if (!(o
= wined3d_context_vk_get_retired_object_vk(context_vk
)))
899 ERR("Leaking image view 0x%s.\n", wine_dbgstr_longlong(vk_view
));
903 o
->type
= WINED3D_RETIRED_IMAGE_VIEW_VK
;
904 o
->u
.vk_image_view
= vk_view
;
905 o
->command_buffer_id
= command_buffer_id
;
908 void wined3d_context_vk_destroy_vk_sampler(struct wined3d_context_vk
*context_vk
,
909 VkSampler vk_sampler
, uint64_t command_buffer_id
)
911 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
912 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
913 struct wined3d_retired_object_vk
*o
;
915 if (context_vk
->completed_command_buffer_id
> command_buffer_id
)
917 VK_CALL(vkDestroySampler(device_vk
->vk_device
, vk_sampler
, NULL
));
918 TRACE("Destroyed sampler 0x%s.\n", wine_dbgstr_longlong(vk_sampler
));
922 if (!(o
= wined3d_context_vk_get_retired_object_vk(context_vk
)))
924 ERR("Leaking sampler 0x%s.\n", wine_dbgstr_longlong(vk_sampler
));
928 o
->type
= WINED3D_RETIRED_SAMPLER_VK
;
929 o
->u
.vk_sampler
= vk_sampler
;
930 o
->command_buffer_id
= command_buffer_id
;
933 void wined3d_context_vk_destroy_image(struct wined3d_context_vk
*context_vk
, struct wined3d_image_vk
*image
)
935 wined3d_context_vk_destroy_vk_image(context_vk
, image
->vk_image
, image
->command_buffer_id
);
937 wined3d_context_vk_destroy_allocator_block(context_vk
, image
->memory
,
938 image
->command_buffer_id
);
940 wined3d_context_vk_destroy_vk_memory(context_vk
, image
->vk_memory
, image
->command_buffer_id
);
942 image
->vk_image
= VK_NULL_HANDLE
;
943 image
->vk_memory
= VK_NULL_HANDLE
;
944 image
->memory
= NULL
;
947 void wined3d_context_vk_destroy_bo(struct wined3d_context_vk
*context_vk
, const struct wined3d_bo_vk
*bo
)
949 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
950 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
951 struct wined3d_bo_slab_vk
*slab_vk
;
952 size_t object_size
, idx
;
954 TRACE("context_vk %p, bo %p.\n", context_vk
, bo
);
956 if (bo
->command_buffer_id
== context_vk
->current_command_buffer
.id
)
957 context_vk
->retired_bo_size
+= bo
->size
;
959 if ((slab_vk
= bo
->slab
))
962 wined3d_bo_slab_vk_unmap(slab_vk
, context_vk
);
963 object_size
= slab_vk
->bo
.size
/ 32;
964 idx
= bo
->b
.buffer_offset
/ object_size
;
965 wined3d_context_vk_destroy_bo_slab_slice(context_vk
, slab_vk
, idx
, bo
->command_buffer_id
);
969 wined3d_context_vk_destroy_vk_buffer(context_vk
, bo
->vk_buffer
, bo
->command_buffer_id
);
973 wined3d_allocator_chunk_vk_unmap(wined3d_allocator_chunk_vk(bo
->memory
->chunk
), context_vk
);
974 wined3d_context_vk_destroy_allocator_block(context_vk
, bo
->memory
, bo
->command_buffer_id
);
979 VK_CALL(vkUnmapMemory(device_vk
->vk_device
, bo
->vk_memory
));
980 wined3d_context_vk_destroy_vk_memory(context_vk
, bo
->vk_memory
, bo
->command_buffer_id
);
983 void wined3d_context_vk_poll_command_buffers(struct wined3d_context_vk
*context_vk
)
985 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
986 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
987 struct wined3d_command_buffer_vk
*buffer
;
990 while (i
< context_vk
->submitted
.buffer_count
)
992 buffer
= &context_vk
->submitted
.buffers
[i
];
993 if (VK_CALL(vkGetFenceStatus(device_vk
->vk_device
, buffer
->vk_fence
)) == VK_NOT_READY
)
999 TRACE("Command buffer %p with id 0x%s has finished.\n",
1000 buffer
->vk_command_buffer
, wine_dbgstr_longlong(buffer
->id
));
1001 VK_CALL(vkDestroyFence(device_vk
->vk_device
, buffer
->vk_fence
, NULL
));
1002 VK_CALL(vkFreeCommandBuffers(device_vk
->vk_device
,
1003 context_vk
->vk_command_pool
, 1, &buffer
->vk_command_buffer
));
1005 if (buffer
->id
> context_vk
->completed_command_buffer_id
)
1006 context_vk
->completed_command_buffer_id
= buffer
->id
;
1007 *buffer
= context_vk
->submitted
.buffers
[--context_vk
->submitted
.buffer_count
];
1011 static void wined3d_context_vk_cleanup_resources(struct wined3d_context_vk
*context_vk
)
1013 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
1014 struct wined3d_retired_objects_vk
*retired
= &context_vk
->retired
;
1015 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
1016 struct wined3d_retired_object_vk
*o
;
1017 uint64_t command_buffer_id
;
1020 wined3d_context_vk_poll_command_buffers(context_vk
);
1021 command_buffer_id
= context_vk
->completed_command_buffer_id
;
1023 retired
->free
= NULL
;
1024 for (i
= retired
->count
; i
; --i
)
1026 o
= &retired
->objects
[i
- 1];
1028 if (o
->type
!= WINED3D_RETIRED_FREE_VK
&& o
->command_buffer_id
> command_buffer_id
)
1033 case WINED3D_RETIRED_FREE_VK
:
1034 /* Nothing to do. */
1037 case WINED3D_RETIRED_FRAMEBUFFER_VK
:
1038 VK_CALL(vkDestroyFramebuffer(device_vk
->vk_device
, o
->u
.vk_framebuffer
, NULL
));
1039 TRACE("Destroyed framebuffer 0x%s.\n", wine_dbgstr_longlong(o
->u
.vk_framebuffer
));
1042 case WINED3D_RETIRED_DESCRIPTOR_POOL_VK
:
1043 VK_CALL(vkDestroyDescriptorPool(device_vk
->vk_device
, o
->u
.vk_descriptor_pool
, NULL
));
1044 TRACE("Destroyed descriptor pool 0x%s.\n", wine_dbgstr_longlong(o
->u
.vk_descriptor_pool
));
1047 case WINED3D_RETIRED_MEMORY_VK
:
1048 VK_CALL(vkFreeMemory(device_vk
->vk_device
, o
->u
.vk_memory
, NULL
));
1049 TRACE("Freed memory 0x%s.\n", wine_dbgstr_longlong(o
->u
.vk_memory
));
1052 case WINED3D_RETIRED_ALLOCATOR_BLOCK_VK
:
1053 TRACE("Destroying block %p.\n", o
->u
.block
);
1054 wined3d_context_vk_free_memory(context_vk
, o
->u
.block
);
1057 case WINED3D_RETIRED_BO_SLAB_SLICE_VK
:
1058 wined3d_bo_slab_vk_free_slice(o
->u
.slice
.slab
, o
->u
.slice
.idx
, context_vk
);
1061 case WINED3D_RETIRED_BUFFER_VK
:
1062 VK_CALL(vkDestroyBuffer(device_vk
->vk_device
, o
->u
.vk_buffer
, NULL
));
1063 TRACE("Destroyed buffer 0x%s.\n", wine_dbgstr_longlong(o
->u
.vk_buffer
));
1066 case WINED3D_RETIRED_IMAGE_VK
:
1067 VK_CALL(vkDestroyImage(device_vk
->vk_device
, o
->u
.vk_image
, NULL
));
1068 TRACE("Destroyed image 0x%s.\n", wine_dbgstr_longlong(o
->u
.vk_image
));
1071 case WINED3D_RETIRED_BUFFER_VIEW_VK
:
1072 VK_CALL(vkDestroyBufferView(device_vk
->vk_device
, o
->u
.vk_buffer_view
, NULL
));
1073 TRACE("Destroyed buffer view 0x%s.\n", wine_dbgstr_longlong(o
->u
.vk_buffer_view
));
1076 case WINED3D_RETIRED_IMAGE_VIEW_VK
:
1077 VK_CALL(vkDestroyImageView(device_vk
->vk_device
, o
->u
.vk_image_view
, NULL
));
1078 TRACE("Destroyed image view 0x%s.\n", wine_dbgstr_longlong(o
->u
.vk_image_view
));
1081 case WINED3D_RETIRED_SAMPLER_VK
:
1082 VK_CALL(vkDestroySampler(device_vk
->vk_device
, o
->u
.vk_sampler
, NULL
));
1083 TRACE("Destroyed sampler 0x%s.\n", wine_dbgstr_longlong(o
->u
.vk_sampler
));
1087 ERR("Unhandled object type %#x.\n", o
->type
);
1091 if (i
== retired
->count
)
1097 o
->type
= WINED3D_RETIRED_FREE_VK
;
1098 o
->u
.next
= retired
->free
;
1103 static void wined3d_context_vk_destroy_bo_slab(struct wine_rb_entry
*entry
, void *ctx
)
1105 struct wined3d_context_vk
*context_vk
= ctx
;
1106 struct wined3d_bo_slab_vk
*slab
, *next
;
1108 slab
= WINE_RB_ENTRY_VALUE(entry
, struct wined3d_bo_slab_vk
, entry
);
1112 wined3d_context_vk_destroy_bo(context_vk
, &slab
->bo
);
1118 static void wined3d_context_vk_destroy_graphics_pipeline(struct wine_rb_entry
*entry
, void *ctx
)
1120 struct wined3d_graphics_pipeline_vk
*pipeline_vk
= WINE_RB_ENTRY_VALUE(entry
,
1121 struct wined3d_graphics_pipeline_vk
, entry
);
1122 struct wined3d_context_vk
*context_vk
= ctx
;
1123 const struct wined3d_vk_info
*vk_info
;
1124 struct wined3d_device_vk
*device_vk
;
1126 vk_info
= context_vk
->vk_info
;
1127 device_vk
= wined3d_device_vk(context_vk
->c
.device
);
1129 VK_CALL(vkDestroyPipeline(device_vk
->vk_device
, pipeline_vk
->vk_pipeline
, NULL
));
1130 heap_free(pipeline_vk
);
1133 static void wined3d_context_vk_destroy_pipeline_layout(struct wine_rb_entry
*entry
, void *ctx
)
1135 struct wined3d_pipeline_layout_vk
*layout
= WINE_RB_ENTRY_VALUE(entry
,
1136 struct wined3d_pipeline_layout_vk
, entry
);
1137 struct wined3d_context_vk
*context_vk
= ctx
;
1138 const struct wined3d_vk_info
*vk_info
;
1139 struct wined3d_device_vk
*device_vk
;
1141 vk_info
= context_vk
->vk_info
;
1142 device_vk
= wined3d_device_vk(context_vk
->c
.device
);
1144 VK_CALL(vkDestroyPipelineLayout(device_vk
->vk_device
, layout
->vk_pipeline_layout
, NULL
));
1145 VK_CALL(vkDestroyDescriptorSetLayout(device_vk
->vk_device
, layout
->vk_set_layout
, NULL
));
1146 heap_free(layout
->key
.bindings
);
1150 static void wined3d_render_pass_key_vk_init(struct wined3d_render_pass_key_vk
*key
,
1151 const struct wined3d_fb_state
*fb
, unsigned int rt_count
, bool depth_stencil
, uint32_t clear_flags
)
1153 struct wined3d_render_pass_attachment_vk
*a
;
1154 struct wined3d_rendertarget_view
*view
;
1157 memset(key
, 0, sizeof(*key
));
1159 for (i
= 0; i
< rt_count
; ++i
)
1161 if (!(view
= fb
->render_targets
[i
]) || view
->format
->id
== WINED3DFMT_NULL
)
1165 a
->vk_format
= wined3d_format_vk(view
->format
)->vk_format
;
1166 a
->vk_samples
= max(1, wined3d_resource_get_sample_count(view
->resource
));
1167 a
->vk_layout
= wined3d_texture_vk(wined3d_texture_from_resource(view
->resource
))->layout
;
1168 key
->rt_mask
|= 1u << i
;
1171 if (depth_stencil
&& (view
= fb
->depth_stencil
))
1174 a
->vk_format
= wined3d_format_vk(view
->format
)->vk_format
;
1175 a
->vk_samples
= max(1, wined3d_resource_get_sample_count(view
->resource
));
1176 a
->vk_layout
= wined3d_texture_vk(wined3d_texture_from_resource(view
->resource
))->layout
;
1177 key
->rt_mask
|= 1u << WINED3D_MAX_RENDER_TARGETS
;
1180 key
->clear_flags
= clear_flags
;
1183 static void wined3d_render_pass_vk_cleanup(struct wined3d_render_pass_vk
*pass
,
1184 struct wined3d_context_vk
*context_vk
)
1186 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
1187 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
1189 VK_CALL(vkDestroyRenderPass(device_vk
->vk_device
, pass
->vk_render_pass
, NULL
));
1192 static bool wined3d_render_pass_vk_init(struct wined3d_render_pass_vk
*pass
,
1193 struct wined3d_context_vk
*context_vk
, const struct wined3d_render_pass_key_vk
*key
)
1195 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
1196 VkAttachmentReference attachment_references
[WINED3D_MAX_RENDER_TARGETS
];
1197 VkAttachmentDescription attachments
[WINED3D_MAX_RENDER_TARGETS
+ 1];
1198 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
1199 const struct wined3d_render_pass_attachment_vk
*a
;
1200 VkAttachmentReference ds_attachment_reference
;
1201 VkAttachmentReference
*ds_reference
= NULL
;
1202 unsigned int attachment_count
, rt_count
, i
;
1203 VkAttachmentDescription
*attachment
;
1204 VkSubpassDescription sub_pass_desc
;
1205 VkRenderPassCreateInfo pass_desc
;
1210 attachment_count
= 0;
1211 mask
= key
->rt_mask
& wined3d_mask_from_size(WINED3D_MAX_RENDER_TARGETS
);
1214 i
= wined3d_bit_scan(&mask
);
1217 attachment
= &attachments
[attachment_count
];
1218 attachment
->flags
= 0;
1219 attachment
->format
= a
->vk_format
;
1220 attachment
->samples
= a
->vk_samples
;
1221 if (key
->clear_flags
& WINED3DCLEAR_TARGET
)
1222 attachment
->loadOp
= VK_ATTACHMENT_LOAD_OP_CLEAR
;
1224 attachment
->loadOp
= VK_ATTACHMENT_LOAD_OP_LOAD
;
1225 attachment
->storeOp
= VK_ATTACHMENT_STORE_OP_STORE
;
1226 attachment
->stencilLoadOp
= VK_ATTACHMENT_LOAD_OP_DONT_CARE
;
1227 attachment
->stencilStoreOp
= VK_ATTACHMENT_STORE_OP_DONT_CARE
;
1228 attachment
->initialLayout
= a
->vk_layout
;
1229 attachment
->finalLayout
= a
->vk_layout
;
1231 attachment_references
[i
].attachment
= attachment_count
;
1232 attachment_references
[i
].layout
= a
->vk_layout
;
1238 mask
= ~key
->rt_mask
& wined3d_mask_from_size(rt_count
);
1241 i
= wined3d_bit_scan(&mask
);
1242 attachment_references
[i
].attachment
= VK_ATTACHMENT_UNUSED
;
1243 attachment_references
[i
].layout
= VK_IMAGE_LAYOUT_UNDEFINED
;
1246 if (key
->rt_mask
& (1u << WINED3D_MAX_RENDER_TARGETS
))
1250 attachment
= &attachments
[attachment_count
];
1251 attachment
->flags
= 0;
1252 attachment
->format
= a
->vk_format
;
1253 attachment
->samples
= a
->vk_samples
;
1254 if (key
->clear_flags
& WINED3DCLEAR_ZBUFFER
)
1255 attachment
->loadOp
= VK_ATTACHMENT_LOAD_OP_CLEAR
;
1257 attachment
->loadOp
= VK_ATTACHMENT_LOAD_OP_LOAD
;
1258 attachment
->storeOp
= VK_ATTACHMENT_STORE_OP_STORE
;
1259 if (key
->clear_flags
& WINED3DCLEAR_STENCIL
)
1260 attachment
->stencilLoadOp
= VK_ATTACHMENT_LOAD_OP_CLEAR
;
1262 attachment
->stencilLoadOp
= VK_ATTACHMENT_LOAD_OP_LOAD
;
1263 attachment
->stencilStoreOp
= VK_ATTACHMENT_STORE_OP_STORE
;
1264 attachment
->initialLayout
= a
->vk_layout
;
1265 attachment
->finalLayout
= a
->vk_layout
;
1267 ds_reference
= &ds_attachment_reference
;
1268 ds_reference
->attachment
= attachment_count
;
1269 ds_reference
->layout
= a
->vk_layout
;
1274 sub_pass_desc
.flags
= 0;
1275 sub_pass_desc
.pipelineBindPoint
= VK_PIPELINE_BIND_POINT_GRAPHICS
;
1276 sub_pass_desc
.inputAttachmentCount
= 0;
1277 sub_pass_desc
.pInputAttachments
= NULL
;
1278 sub_pass_desc
.colorAttachmentCount
= rt_count
;
1279 sub_pass_desc
.pColorAttachments
= attachment_references
;
1280 sub_pass_desc
.pResolveAttachments
= NULL
;
1281 sub_pass_desc
.pDepthStencilAttachment
= ds_reference
;
1282 sub_pass_desc
.preserveAttachmentCount
= 0;
1283 sub_pass_desc
.pPreserveAttachments
= NULL
;
1285 pass_desc
.sType
= VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO
;
1286 pass_desc
.pNext
= NULL
;
1287 pass_desc
.flags
= 0;
1288 pass_desc
.attachmentCount
= attachment_count
;
1289 pass_desc
.pAttachments
= attachments
;
1290 pass_desc
.subpassCount
= 1;
1291 pass_desc
.pSubpasses
= &sub_pass_desc
;
1292 pass_desc
.dependencyCount
= 0;
1293 pass_desc
.pDependencies
= NULL
;
1296 if ((vr
= VK_CALL(vkCreateRenderPass(device_vk
->vk_device
,
1297 &pass_desc
, NULL
, &pass
->vk_render_pass
))) < 0)
1299 WARN("Failed to create Vulkan render pass, vr %d.\n", vr
);
1306 VkRenderPass
wined3d_context_vk_get_render_pass(struct wined3d_context_vk
*context_vk
,
1307 const struct wined3d_fb_state
*fb
, unsigned int rt_count
, bool depth_stencil
, uint32_t clear_flags
)
1309 struct wined3d_render_pass_key_vk key
;
1310 struct wined3d_render_pass_vk
*pass
;
1311 struct wine_rb_entry
*entry
;
1313 wined3d_render_pass_key_vk_init(&key
, fb
, rt_count
, depth_stencil
, clear_flags
);
1314 if ((entry
= wine_rb_get(&context_vk
->render_passes
, &key
)))
1315 return WINE_RB_ENTRY_VALUE(entry
, struct wined3d_render_pass_vk
, entry
)->vk_render_pass
;
1317 if (!(pass
= heap_alloc(sizeof(*pass
))))
1318 return VK_NULL_HANDLE
;
1320 if (!wined3d_render_pass_vk_init(pass
, context_vk
, &key
))
1323 return VK_NULL_HANDLE
;
1326 if (wine_rb_put(&context_vk
->render_passes
, &pass
->key
, &pass
->entry
) == -1)
1328 ERR("Failed to insert render pass.\n");
1329 wined3d_render_pass_vk_cleanup(pass
, context_vk
);
1331 return VK_NULL_HANDLE
;
1334 return pass
->vk_render_pass
;
1337 void wined3d_context_vk_end_current_render_pass(struct wined3d_context_vk
*context_vk
)
1339 VkCommandBuffer vk_command_buffer
= context_vk
->current_command_buffer
.vk_command_buffer
;
1340 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
1341 struct wined3d_query_pool_vk
*pool_vk
, *pool_vk_next
;
1342 struct wined3d_query_vk
*query_vk
;
1344 if (context_vk
->vk_render_pass
)
1346 LIST_FOR_EACH_ENTRY(query_vk
, &context_vk
->render_pass_queries
, struct wined3d_query_vk
, entry
)
1347 wined3d_query_vk_suspend(query_vk
, context_vk
);
1349 VK_CALL(vkCmdEndRenderPass(vk_command_buffer
));
1350 context_vk
->vk_render_pass
= VK_NULL_HANDLE
;
1351 VK_CALL(vkCmdPipelineBarrier(vk_command_buffer
, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT
,
1352 VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
, 0, 0, NULL
, 0, NULL
, 0, NULL
));
1354 LIST_FOR_EACH_ENTRY(query_vk
, &context_vk
->render_pass_queries
, struct wined3d_query_vk
, entry
)
1356 if (!wined3d_context_vk_allocate_query(context_vk
, query_vk
->q
.type
, &query_vk
->pool_idx
))
1358 ERR("Failed to allocate new query.\n");
1364 if (context_vk
->vk_framebuffer
)
1366 wined3d_context_vk_destroy_vk_framebuffer(context_vk
,
1367 context_vk
->vk_framebuffer
, context_vk
->current_command_buffer
.id
);
1368 context_vk
->vk_framebuffer
= VK_NULL_HANDLE
;
1371 if (vk_command_buffer
)
1373 LIST_FOR_EACH_ENTRY_SAFE(pool_vk
, pool_vk_next
, &context_vk
->completed_query_pools
,
1374 struct wined3d_query_pool_vk
, completed_entry
)
1376 list_remove(&pool_vk
->completed_entry
);
1377 list_init(&pool_vk
->completed_entry
);
1378 wined3d_query_pool_vk_reset(pool_vk
, context_vk
, vk_command_buffer
);
1383 static void wined3d_context_vk_destroy_render_pass(struct wine_rb_entry
*entry
, void *ctx
)
1385 struct wined3d_render_pass_vk
*pass
= WINE_RB_ENTRY_VALUE(entry
,
1386 struct wined3d_render_pass_vk
, entry
);
1388 wined3d_render_pass_vk_cleanup(pass
, ctx
);
1392 static void wined3d_shader_descriptor_writes_vk_cleanup(struct wined3d_shader_descriptor_writes_vk
*writes
)
1394 heap_free(writes
->writes
);
1397 static void wined3d_context_vk_destroy_query_pools(struct wined3d_context_vk
*context_vk
, struct list
*free_pools
)
1399 struct wined3d_query_pool_vk
*pool_vk
, *entry
;
1401 LIST_FOR_EACH_ENTRY_SAFE(pool_vk
, entry
, free_pools
, struct wined3d_query_pool_vk
, entry
)
1403 wined3d_query_pool_vk_cleanup(pool_vk
, context_vk
);
1408 bool wined3d_context_vk_allocate_query(struct wined3d_context_vk
*context_vk
,
1409 enum wined3d_query_type type
, struct wined3d_query_pool_idx_vk
*pool_idx
)
1411 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
1412 struct wined3d_query_pool_vk
*pool_vk
, *entry
;
1413 struct list
*free_pools
;
1418 case WINED3D_QUERY_TYPE_OCCLUSION
:
1419 free_pools
= &context_vk
->free_occlusion_query_pools
;
1422 case WINED3D_QUERY_TYPE_TIMESTAMP
:
1423 free_pools
= &context_vk
->free_timestamp_query_pools
;
1426 case WINED3D_QUERY_TYPE_PIPELINE_STATISTICS
:
1427 free_pools
= &context_vk
->free_pipeline_statistics_query_pools
;
1430 case WINED3D_QUERY_TYPE_SO_STATISTICS
:
1431 case WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM0
:
1432 case WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM1
:
1433 case WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM2
:
1434 case WINED3D_QUERY_TYPE_SO_STATISTICS_STREAM3
:
1435 free_pools
= &context_vk
->free_stream_output_statistics_query_pools
;
1439 FIXME("Unhandled query type %#x.\n", type
);
1443 LIST_FOR_EACH_ENTRY_SAFE(pool_vk
, entry
, free_pools
, struct wined3d_query_pool_vk
, entry
)
1445 if (wined3d_query_pool_vk_allocate_query(pool_vk
, &idx
))
1447 list_remove(&pool_vk
->entry
);
1450 if (!(pool_vk
= heap_alloc_zero(sizeof(*pool_vk
))))
1452 if (!wined3d_query_pool_vk_init(pool_vk
, context_vk
, type
, free_pools
))
1458 if (vk_info
->supported
[WINED3D_VK_EXT_HOST_QUERY_RESET
])
1460 VK_CALL(vkResetQueryPoolEXT(wined3d_device_vk(context_vk
->c
.device
)->vk_device
,
1461 pool_vk
->vk_query_pool
, 0, WINED3D_QUERY_POOL_SIZE
));
1465 wined3d_context_vk_end_current_render_pass(context_vk
);
1466 VK_CALL(vkCmdResetQueryPool(wined3d_context_vk_get_command_buffer(context_vk
),
1467 pool_vk
->vk_query_pool
, 0, WINED3D_QUERY_POOL_SIZE
));
1470 if (!wined3d_query_pool_vk_allocate_query(pool_vk
, &idx
))
1472 wined3d_query_pool_vk_cleanup(pool_vk
, context_vk
);
1478 pool_idx
->pool_vk
= pool_vk
;
1479 pool_idx
->idx
= idx
;
1484 void wined3d_context_vk_cleanup(struct wined3d_context_vk
*context_vk
)
1486 struct wined3d_command_buffer_vk
*buffer
= &context_vk
->current_command_buffer
;
1487 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
1488 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
1490 if (buffer
->vk_command_buffer
)
1492 VK_CALL(vkFreeCommandBuffers(device_vk
->vk_device
,
1493 context_vk
->vk_command_pool
, 1, &buffer
->vk_command_buffer
));
1494 buffer
->vk_command_buffer
= VK_NULL_HANDLE
;
1497 wined3d_context_vk_wait_command_buffer(context_vk
, buffer
->id
- 1);
1498 context_vk
->completed_command_buffer_id
= buffer
->id
;
1500 heap_free(context_vk
->compute
.bindings
.bindings
);
1501 heap_free(context_vk
->graphics
.bindings
.bindings
);
1502 if (context_vk
->vk_descriptor_pool
)
1503 VK_CALL(vkDestroyDescriptorPool(device_vk
->vk_device
, context_vk
->vk_descriptor_pool
, NULL
));
1504 if (context_vk
->vk_framebuffer
)
1505 VK_CALL(vkDestroyFramebuffer(device_vk
->vk_device
, context_vk
->vk_framebuffer
, NULL
));
1506 VK_CALL(vkDestroyCommandPool(device_vk
->vk_device
, context_vk
->vk_command_pool
, NULL
));
1507 if (context_vk
->vk_so_counter_bo
.vk_buffer
)
1508 wined3d_context_vk_destroy_bo(context_vk
, &context_vk
->vk_so_counter_bo
);
1509 wined3d_context_vk_cleanup_resources(context_vk
);
1510 wined3d_context_vk_destroy_query_pools(context_vk
, &context_vk
->free_occlusion_query_pools
);
1511 wined3d_context_vk_destroy_query_pools(context_vk
, &context_vk
->free_timestamp_query_pools
);
1512 wined3d_context_vk_destroy_query_pools(context_vk
, &context_vk
->free_pipeline_statistics_query_pools
);
1513 wined3d_context_vk_destroy_query_pools(context_vk
, &context_vk
->free_stream_output_statistics_query_pools
);
1514 wine_rb_destroy(&context_vk
->bo_slab_available
, wined3d_context_vk_destroy_bo_slab
, context_vk
);
1515 heap_free(context_vk
->pending_queries
.queries
);
1516 heap_free(context_vk
->submitted
.buffers
);
1517 heap_free(context_vk
->retired
.objects
);
1519 wined3d_shader_descriptor_writes_vk_cleanup(&context_vk
->descriptor_writes
);
1520 wine_rb_destroy(&context_vk
->graphics_pipelines
, wined3d_context_vk_destroy_graphics_pipeline
, context_vk
);
1521 wine_rb_destroy(&context_vk
->pipeline_layouts
, wined3d_context_vk_destroy_pipeline_layout
, context_vk
);
1522 wine_rb_destroy(&context_vk
->render_passes
, wined3d_context_vk_destroy_render_pass
, context_vk
);
1524 wined3d_context_cleanup(&context_vk
->c
);
1527 void wined3d_context_vk_remove_pending_queries(struct wined3d_context_vk
*context_vk
,
1528 struct wined3d_query_vk
*query_vk
)
1530 struct wined3d_pending_queries_vk
*pending
= &context_vk
->pending_queries
;
1531 struct wined3d_pending_query_vk
*p
;
1534 pending
->free_idx
= ~(size_t)0;
1535 for (i
= pending
->count
; i
; --i
)
1537 p
= &pending
->queries
[i
- 1];
1541 if (p
->query_vk
!= query_vk
&& !wined3d_query_vk_accumulate_data(p
->query_vk
, context_vk
, &p
->pool_idx
))
1543 --p
->query_vk
->pending_count
;
1546 if (i
== pending
->count
)
1553 p
->pool_idx
.pool_vk
= NULL
;
1554 p
->pool_idx
.idx
= pending
->free_idx
;
1555 pending
->free_idx
= i
- 1;
1559 void wined3d_context_vk_accumulate_pending_queries(struct wined3d_context_vk
*context_vk
)
1561 wined3d_context_vk_remove_pending_queries(context_vk
, NULL
);
1564 void wined3d_context_vk_add_pending_query(struct wined3d_context_vk
*context_vk
, struct wined3d_query_vk
*query_vk
)
1566 struct wined3d_pending_queries_vk
*pending
= &context_vk
->pending_queries
;
1567 struct wined3d_pending_query_vk
*p
;
1569 if (pending
->free_idx
!= ~(size_t)0)
1571 p
= &pending
->queries
[pending
->free_idx
];
1572 pending
->free_idx
= p
->pool_idx
.idx
;
1576 if (!wined3d_array_reserve((void **)&pending
->queries
, &pending
->size
,
1577 pending
->count
+ 1, sizeof(*pending
->queries
)))
1579 ERR("Failed to allocate entry.\n");
1582 p
= &pending
->queries
[pending
->count
++];
1585 p
->query_vk
= query_vk
;
1586 p
->pool_idx
= query_vk
->pool_idx
;
1587 ++query_vk
->pending_count
;
1590 VkCommandBuffer
wined3d_context_vk_get_command_buffer(struct wined3d_context_vk
*context_vk
)
1592 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
1593 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
1594 VkCommandBufferAllocateInfo command_buffer_info
;
1595 struct wined3d_command_buffer_vk
*buffer
;
1596 VkCommandBufferBeginInfo begin_info
;
1597 struct wined3d_query_vk
*query_vk
;
1600 TRACE("context_vk %p.\n", context_vk
);
1602 buffer
= &context_vk
->current_command_buffer
;
1603 if (buffer
->vk_command_buffer
)
1605 if (context_vk
->retired_bo_size
> WINED3D_RETIRED_BO_SIZE_THRESHOLD
)
1606 wined3d_context_vk_submit_command_buffer(context_vk
, 0, NULL
, NULL
, 0, NULL
);
1609 TRACE("Returning existing command buffer %p with id 0x%s.\n",
1610 buffer
->vk_command_buffer
, wine_dbgstr_longlong(buffer
->id
));
1611 return buffer
->vk_command_buffer
;
1615 command_buffer_info
.sType
= VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO
;
1616 command_buffer_info
.pNext
= NULL
;
1617 command_buffer_info
.commandPool
= context_vk
->vk_command_pool
;
1618 command_buffer_info
.level
= VK_COMMAND_BUFFER_LEVEL_PRIMARY
;
1619 command_buffer_info
.commandBufferCount
= 1;
1620 if ((vr
= VK_CALL(vkAllocateCommandBuffers(device_vk
->vk_device
,
1621 &command_buffer_info
, &buffer
->vk_command_buffer
))) < 0)
1623 WARN("Failed to allocate Vulkan command buffer, vr %s.\n", wined3d_debug_vkresult(vr
));
1624 return VK_NULL_HANDLE
;
1627 begin_info
.sType
= VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO
;
1628 begin_info
.pNext
= NULL
;
1629 begin_info
.flags
= 0;
1630 begin_info
.pInheritanceInfo
= NULL
;
1631 if ((vr
= VK_CALL(vkBeginCommandBuffer(buffer
->vk_command_buffer
, &begin_info
))) < 0)
1633 WARN("Failed to begin command buffer, vr %s.\n", wined3d_debug_vkresult(vr
));
1634 VK_CALL(vkFreeCommandBuffers(device_vk
->vk_device
, context_vk
->vk_command_pool
,
1635 1, &buffer
->vk_command_buffer
));
1636 return buffer
->vk_command_buffer
= VK_NULL_HANDLE
;
1639 wined3d_context_vk_accumulate_pending_queries(context_vk
);
1640 LIST_FOR_EACH_ENTRY(query_vk
, &context_vk
->active_queries
, struct wined3d_query_vk
, entry
)
1642 if (!wined3d_context_vk_allocate_query(context_vk
, query_vk
->q
.type
, &query_vk
->pool_idx
))
1644 ERR("Failed to allocate new query.\n");
1648 wined3d_query_vk_resume(query_vk
, context_vk
);
1651 TRACE("Created new command buffer %p with id 0x%s.\n",
1652 buffer
->vk_command_buffer
, wine_dbgstr_longlong(buffer
->id
));
1654 return buffer
->vk_command_buffer
;
1657 void wined3d_context_vk_submit_command_buffer(struct wined3d_context_vk
*context_vk
,
1658 unsigned int wait_semaphore_count
, const VkSemaphore
*wait_semaphores
, const VkPipelineStageFlags
*wait_stages
,
1659 unsigned int signal_semaphore_count
, const VkSemaphore
*signal_semaphores
)
1661 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
1662 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
1663 struct wined3d_command_buffer_vk
*buffer
;
1664 struct wined3d_query_vk
*query_vk
;
1665 VkFenceCreateInfo fence_desc
;
1666 VkSubmitInfo submit_info
;
1669 TRACE("context_vk %p, wait_semaphore_count %u, wait_semaphores %p, wait_stages %p,"
1670 "signal_semaphore_count %u, signal_semaphores %p.\n",
1671 context_vk
, wait_semaphore_count
, wait_semaphores
, wait_stages
,
1672 signal_semaphore_count
, signal_semaphores
);
1674 buffer
= &context_vk
->current_command_buffer
;
1675 if (!buffer
->vk_command_buffer
)
1678 TRACE("Submitting command buffer %p with id 0x%s.\n",
1679 buffer
->vk_command_buffer
, wine_dbgstr_longlong(buffer
->id
));
1681 wined3d_context_vk_end_current_render_pass(context_vk
);
1683 LIST_FOR_EACH_ENTRY(query_vk
, &context_vk
->active_queries
, struct wined3d_query_vk
, entry
)
1684 wined3d_query_vk_suspend(query_vk
, context_vk
);
1686 context_vk
->graphics
.vk_pipeline
= VK_NULL_HANDLE
;
1687 context_vk
->update_compute_pipeline
= 1;
1688 context_vk
->update_stream_output
= 1;
1689 context_vk
->c
.update_shader_resource_bindings
= 1;
1690 context_vk
->c
.update_compute_shader_resource_bindings
= 1;
1691 context_vk
->c
.update_unordered_access_view_bindings
= 1;
1692 context_vk
->c
.update_compute_unordered_access_view_bindings
= 1;
1693 context_invalidate_state(&context_vk
->c
, STATE_STREAMSRC
);
1694 context_invalidate_state(&context_vk
->c
, STATE_INDEXBUFFER
);
1695 context_invalidate_state(&context_vk
->c
, STATE_BLEND_FACTOR
);
1696 context_invalidate_state(&context_vk
->c
, STATE_STENCIL_REF
);
1698 VK_CALL(vkEndCommandBuffer(buffer
->vk_command_buffer
));
1700 fence_desc
.sType
= VK_STRUCTURE_TYPE_FENCE_CREATE_INFO
;
1701 fence_desc
.pNext
= NULL
;
1702 fence_desc
.flags
= 0;
1703 if ((vr
= VK_CALL(vkCreateFence(device_vk
->vk_device
, &fence_desc
, NULL
, &buffer
->vk_fence
))) < 0)
1704 ERR("Failed to create fence, vr %s.\n", wined3d_debug_vkresult(vr
));
1706 submit_info
.sType
= VK_STRUCTURE_TYPE_SUBMIT_INFO
;
1707 submit_info
.pNext
= NULL
;
1708 submit_info
.waitSemaphoreCount
= wait_semaphore_count
;
1709 submit_info
.pWaitSemaphores
= wait_semaphores
;
1710 submit_info
.pWaitDstStageMask
= wait_stages
;
1711 submit_info
.commandBufferCount
= 1;
1712 submit_info
.pCommandBuffers
= &buffer
->vk_command_buffer
;
1713 submit_info
.signalSemaphoreCount
= signal_semaphore_count
;
1714 submit_info
.pSignalSemaphores
= signal_semaphores
;
1716 if ((vr
= VK_CALL(vkQueueSubmit(device_vk
->vk_queue
, 1, &submit_info
, buffer
->vk_fence
))) < 0)
1717 ERR("Failed to submit command buffer %p, vr %s.\n",
1718 buffer
->vk_command_buffer
, wined3d_debug_vkresult(vr
));
1720 if (!wined3d_array_reserve((void **)&context_vk
->submitted
.buffers
, &context_vk
->submitted
.buffers_size
,
1721 context_vk
->submitted
.buffer_count
+ 1, sizeof(*context_vk
->submitted
.buffers
)))
1722 ERR("Failed to grow submitted command buffer array.\n");
1724 context_vk
->submitted
.buffers
[context_vk
->submitted
.buffer_count
++] = *buffer
;
1726 buffer
->vk_command_buffer
= VK_NULL_HANDLE
;
1727 /* We don't expect this to ever happen, but handle it anyway. */
1730 wined3d_context_vk_wait_command_buffer(context_vk
, buffer
->id
- 1);
1731 context_vk
->completed_command_buffer_id
= 0;
1734 context_vk
->retired_bo_size
= 0;
1735 wined3d_context_vk_cleanup_resources(context_vk
);
1738 void wined3d_context_vk_wait_command_buffer(struct wined3d_context_vk
*context_vk
, uint64_t id
)
1740 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
1741 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
1744 if (id
<= context_vk
->completed_command_buffer_id
1745 || id
> context_vk
->current_command_buffer
.id
) /* In case the buffer ID wrapped. */
1748 for (i
= 0; i
< context_vk
->submitted
.buffer_count
; ++i
)
1750 if (context_vk
->submitted
.buffers
[i
].id
!= id
)
1753 VK_CALL(vkWaitForFences(device_vk
->vk_device
, 1,
1754 &context_vk
->submitted
.buffers
[i
].vk_fence
, VK_TRUE
, UINT64_MAX
));
1755 wined3d_context_vk_cleanup_resources(context_vk
);
1759 ERR("Failed to find fence for command buffer with id 0x%s.\n", wine_dbgstr_longlong(id
));
1762 void wined3d_context_vk_image_barrier(struct wined3d_context_vk
*context_vk
,
1763 VkCommandBuffer vk_command_buffer
, VkPipelineStageFlags src_stage_mask
, VkPipelineStageFlags dst_stage_mask
,
1764 VkAccessFlags src_access_mask
, VkAccessFlags dst_access_mask
, VkImageLayout old_layout
,
1765 VkImageLayout new_layout
, VkImage image
, const VkImageSubresourceRange
*range
)
1767 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
1768 VkImageMemoryBarrier barrier
;
1770 wined3d_context_vk_end_current_render_pass(context_vk
);
1772 barrier
.sType
= VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER
;
1773 barrier
.pNext
= NULL
;
1774 barrier
.srcAccessMask
= src_access_mask
;
1775 barrier
.dstAccessMask
= dst_access_mask
;
1776 barrier
.oldLayout
= old_layout
;
1777 barrier
.newLayout
= new_layout
;
1778 barrier
.srcQueueFamilyIndex
= VK_QUEUE_FAMILY_IGNORED
;
1779 barrier
.dstQueueFamilyIndex
= VK_QUEUE_FAMILY_IGNORED
;
1780 barrier
.image
= image
;
1781 barrier
.subresourceRange
= *range
;
1783 VK_CALL(vkCmdPipelineBarrier(vk_command_buffer
, src_stage_mask
, dst_stage_mask
, 0, 0, NULL
, 0, NULL
, 1, &barrier
));
1786 static int wined3d_render_pass_vk_compare(const void *key
, const struct wine_rb_entry
*entry
)
1788 const struct wined3d_render_pass_key_vk
*k
= key
;
1789 const struct wined3d_render_pass_vk
*pass
= WINE_RB_ENTRY_VALUE(entry
,
1790 const struct wined3d_render_pass_vk
, entry
);
1792 return memcmp(k
, &pass
->key
, sizeof(*k
));
1795 static int wined3d_pipeline_layout_vk_compare(const void *key
, const struct wine_rb_entry
*entry
)
1797 const struct wined3d_pipeline_layout_key_vk
*a
= key
;
1798 const struct wined3d_pipeline_layout_key_vk
*b
= &WINE_RB_ENTRY_VALUE(entry
,
1799 const struct wined3d_pipeline_layout_vk
, entry
)->key
;
1801 if (a
->binding_count
!= b
->binding_count
)
1802 return a
->binding_count
- b
->binding_count
;
1803 return memcmp(a
->bindings
, b
->bindings
, a
->binding_count
* sizeof(*a
->bindings
));
1806 static int wined3d_graphics_pipeline_vk_compare(const void *key
, const struct wine_rb_entry
*entry
)
1808 const struct wined3d_graphics_pipeline_key_vk
*a
= key
;
1809 const struct wined3d_graphics_pipeline_key_vk
*b
= &WINE_RB_ENTRY_VALUE(entry
,
1810 const struct wined3d_graphics_pipeline_vk
, entry
)->key
;
1814 if (a
->pipeline_desc
.stageCount
!= b
->pipeline_desc
.stageCount
)
1815 return a
->pipeline_desc
.stageCount
- b
->pipeline_desc
.stageCount
;
1816 for (i
= 0; i
< a
->pipeline_desc
.stageCount
; ++i
)
1818 if (a
->stages
[i
].module
!= b
->stages
[i
].module
)
1819 return a
->stages
[i
].module
- b
->stages
[i
].module
;
1822 if (a
->divisor_desc
.vertexBindingDivisorCount
!= b
->divisor_desc
.vertexBindingDivisorCount
)
1823 return a
->divisor_desc
.vertexBindingDivisorCount
- b
->divisor_desc
.vertexBindingDivisorCount
;
1824 if ((ret
= memcmp(a
->divisors
, b
->divisors
,
1825 a
->divisor_desc
.vertexBindingDivisorCount
* sizeof(*a
->divisors
))))
1828 if (a
->input_desc
.vertexAttributeDescriptionCount
!= b
->input_desc
.vertexAttributeDescriptionCount
)
1829 return a
->input_desc
.vertexAttributeDescriptionCount
- b
->input_desc
.vertexAttributeDescriptionCount
;
1830 if ((ret
= memcmp(a
->attributes
, b
->attributes
,
1831 a
->input_desc
.vertexAttributeDescriptionCount
* sizeof(*a
->attributes
))))
1833 if (a
->input_desc
.vertexBindingDescriptionCount
!= b
->input_desc
.vertexBindingDescriptionCount
)
1834 return a
->input_desc
.vertexBindingDescriptionCount
- b
->input_desc
.vertexBindingDescriptionCount
;
1835 if ((ret
= memcmp(a
->bindings
, b
->bindings
,
1836 a
->input_desc
.vertexBindingDescriptionCount
* sizeof(*a
->bindings
))))
1839 if (a
->ia_desc
.topology
!= b
->ia_desc
.topology
)
1840 return a
->ia_desc
.topology
- b
->ia_desc
.topology
;
1841 if (a
->ia_desc
.primitiveRestartEnable
!= b
->ia_desc
.primitiveRestartEnable
)
1842 return a
->ia_desc
.primitiveRestartEnable
- b
->ia_desc
.primitiveRestartEnable
;
1844 if (a
->ts_desc
.patchControlPoints
!= b
->ts_desc
.patchControlPoints
)
1845 return a
->ts_desc
.patchControlPoints
- b
->ts_desc
.patchControlPoints
;
1847 if ((ret
= memcmp(&a
->viewport
, &b
->viewport
, sizeof(a
->viewport
))))
1850 if ((ret
= memcmp(&a
->scissor
, &b
->scissor
, sizeof(a
->scissor
))))
1853 if ((ret
= memcmp(&a
->rs_desc
, &b
->rs_desc
, sizeof(a
->rs_desc
))))
1856 if (a
->ms_desc
.rasterizationSamples
!= b
->ms_desc
.rasterizationSamples
)
1857 return a
->ms_desc
.rasterizationSamples
- b
->ms_desc
.rasterizationSamples
;
1858 if (a
->ms_desc
.alphaToCoverageEnable
!= b
->ms_desc
.alphaToCoverageEnable
)
1859 return a
->ms_desc
.alphaToCoverageEnable
- b
->ms_desc
.alphaToCoverageEnable
;
1860 if (a
->sample_mask
!= b
->sample_mask
)
1861 return a
->sample_mask
- b
->sample_mask
;
1863 if ((ret
= memcmp(&a
->ds_desc
, &b
->ds_desc
, sizeof(a
->ds_desc
))))
1866 if (a
->blend_desc
.attachmentCount
!= b
->blend_desc
.attachmentCount
)
1867 return a
->blend_desc
.attachmentCount
- b
->blend_desc
.attachmentCount
;
1868 if ((ret
= memcmp(a
->blend_attachments
, b
->blend_attachments
,
1869 a
->blend_desc
.attachmentCount
* sizeof(*a
->blend_attachments
))))
1872 if (a
->pipeline_desc
.layout
!= b
->pipeline_desc
.layout
)
1873 return a
->pipeline_desc
.layout
- b
->pipeline_desc
.layout
;
1875 if (a
->pipeline_desc
.renderPass
!= b
->pipeline_desc
.renderPass
)
1876 return a
->pipeline_desc
.renderPass
- b
->pipeline_desc
.renderPass
;
1881 static int wined3d_bo_slab_vk_compare(const void *key
, const struct wine_rb_entry
*entry
)
1883 const struct wined3d_bo_slab_vk
*slab
= WINE_RB_ENTRY_VALUE(entry
, const struct wined3d_bo_slab_vk
, entry
);
1884 const struct wined3d_bo_slab_vk_key
*k
= key
;
1886 if (k
->memory_type
!= slab
->requested_memory_type
)
1887 return k
->memory_type
- slab
->requested_memory_type
;
1888 if (k
->usage
!= slab
->bo
.usage
)
1889 return k
->usage
- slab
->bo
.usage
;
1890 return k
->size
- slab
->bo
.size
;
1893 static void wined3d_context_vk_init_graphics_pipeline_key(struct wined3d_context_vk
*context_vk
)
1895 struct wined3d_graphics_pipeline_key_vk
*key
;
1896 VkPipelineShaderStageCreateInfo
*stage
;
1899 static const VkDynamicState dynamic_states
[] =
1901 VK_DYNAMIC_STATE_BLEND_CONSTANTS
,
1902 VK_DYNAMIC_STATE_STENCIL_REFERENCE
,
1905 key
= &context_vk
->graphics
.pipeline_key_vk
;
1906 memset(key
, 0, sizeof(*key
));
1908 for (i
= 0; i
< ARRAY_SIZE(context_vk
->graphics
.vk_modules
); ++i
)
1910 stage
= &key
->stages
[i
];
1911 stage
->sType
= VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO
;
1912 stage
->pName
= "main";
1915 key
->input_desc
.sType
= VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO
;
1916 key
->input_desc
.pVertexBindingDescriptions
= key
->bindings
;
1917 key
->input_desc
.pVertexAttributeDescriptions
= key
->attributes
;
1919 key
->divisor_desc
.sType
= VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT
;
1920 key
->divisor_desc
.pVertexBindingDivisors
= key
->divisors
;
1922 key
->ia_desc
.sType
= VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO
;
1924 key
->ts_desc
.sType
= VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO
;
1926 key
->vp_desc
.sType
= VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO
;
1927 key
->vp_desc
.viewportCount
= 1;
1928 key
->vp_desc
.pViewports
= &key
->viewport
;
1929 key
->vp_desc
.scissorCount
= 1;
1930 key
->vp_desc
.pScissors
= &key
->scissor
;
1932 key
->rs_desc
.sType
= VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO
;
1933 key
->rs_desc
.lineWidth
= 1.0f
;
1935 key
->ms_desc
.sType
= VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO
;
1936 key
->ms_desc
.pSampleMask
= &key
->sample_mask
;
1938 key
->ds_desc
.sType
= VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO
;
1939 key
->ds_desc
.maxDepthBounds
= 1.0f
;
1941 key
->blend_desc
.sType
= VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO
;
1942 key
->blend_desc
.logicOp
= VK_LOGIC_OP_COPY
;
1943 key
->blend_desc
.pAttachments
= key
->blend_attachments
;
1944 key
->blend_desc
.blendConstants
[0] = 1.0f
;
1945 key
->blend_desc
.blendConstants
[1] = 1.0f
;
1946 key
->blend_desc
.blendConstants
[2] = 1.0f
;
1947 key
->blend_desc
.blendConstants
[3] = 1.0f
;
1949 key
->dynamic_desc
.sType
= VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO
;
1950 key
->dynamic_desc
.dynamicStateCount
= ARRAY_SIZE(dynamic_states
);
1951 key
->dynamic_desc
.pDynamicStates
= dynamic_states
;
1953 key
->pipeline_desc
.sType
= VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO
;
1954 key
->pipeline_desc
.pStages
= key
->stages
;
1955 key
->pipeline_desc
.pVertexInputState
= &key
->input_desc
;
1956 key
->pipeline_desc
.pInputAssemblyState
= &key
->ia_desc
;
1957 key
->pipeline_desc
.pTessellationState
= &key
->ts_desc
;
1958 key
->pipeline_desc
.pViewportState
= &key
->vp_desc
;
1959 key
->pipeline_desc
.pRasterizationState
= &key
->rs_desc
;
1960 key
->pipeline_desc
.pMultisampleState
= &key
->ms_desc
;
1961 key
->pipeline_desc
.pDepthStencilState
= &key
->ds_desc
;
1962 key
->pipeline_desc
.pColorBlendState
= &key
->blend_desc
;
1963 key
->pipeline_desc
.pDynamicState
= &key
->dynamic_desc
;
1964 key
->pipeline_desc
.basePipelineIndex
= -1;
1967 static void wined3d_context_vk_update_rasterisation_state(const struct wined3d_context_vk
*context_vk
,
1968 const struct wined3d_state
*state
, struct wined3d_graphics_pipeline_key_vk
*key
)
1970 const struct wined3d_d3d_info
*d3d_info
= context_vk
->c
.d3d_info
;
1971 VkPipelineRasterizationStateCreateInfo
*desc
= &key
->rs_desc
;
1972 const struct wined3d_rasterizer_state_desc
*r
;
1980 if (!state
->rasterizer_state
)
1982 desc
->depthClampEnable
= VK_FALSE
;
1983 desc
->rasterizerDiscardEnable
= is_rasterization_disabled(state
->shader
[WINED3D_SHADER_TYPE_GEOMETRY
]);
1984 desc
->cullMode
= VK_CULL_MODE_BACK_BIT
;
1985 desc
->frontFace
= VK_FRONT_FACE_CLOCKWISE
;
1986 desc
->depthBiasEnable
= VK_FALSE
;
1987 desc
->depthBiasConstantFactor
= 0.0f
;
1988 desc
->depthBiasClamp
= 0.0f
;
1989 desc
->depthBiasSlopeFactor
= 0.0f
;
1994 r
= &state
->rasterizer_state
->desc
;
1995 desc
->depthClampEnable
= !r
->depth_clip
;
1996 desc
->rasterizerDiscardEnable
= is_rasterization_disabled(state
->shader
[WINED3D_SHADER_TYPE_GEOMETRY
]);
1997 desc
->cullMode
= vk_cull_mode_from_wined3d(r
->cull_mode
);
1998 desc
->frontFace
= r
->front_ccw
? VK_FRONT_FACE_COUNTER_CLOCKWISE
: VK_FRONT_FACE_CLOCKWISE
;
2000 scale_bias
= r
->scale_bias
;
2001 const_bias
.f32
= r
->depth_bias
;
2002 if (!scale_bias
&& !const_bias
.f32
)
2004 desc
->depthBiasEnable
= VK_FALSE
;
2005 desc
->depthBiasConstantFactor
= 0.0f
;
2006 desc
->depthBiasClamp
= 0.0f
;
2007 desc
->depthBiasSlopeFactor
= 0.0f
;
2012 desc
->depthBiasEnable
= VK_TRUE
;
2013 if (d3d_info
->wined3d_creation_flags
& WINED3D_LEGACY_DEPTH_BIAS
)
2015 const struct wined3d_rendertarget_view
*dsv
;
2017 if ((dsv
= state
->fb
.depth_stencil
))
2019 desc
->depthBiasConstantFactor
= -(float)const_bias
.u32
/ dsv
->format
->depth_bias_scale
;
2020 desc
->depthBiasSlopeFactor
= -(float)const_bias
.u32
;
2024 desc
->depthBiasConstantFactor
= 0.0f
;
2025 desc
->depthBiasSlopeFactor
= 0.0f
;
2030 desc
->depthBiasConstantFactor
= const_bias
.f32
;
2031 desc
->depthBiasSlopeFactor
= scale_bias
;
2033 desc
->depthBiasClamp
= r
->depth_bias_clamp
;
2036 static void wined3d_context_vk_update_blend_state(const struct wined3d_context_vk
*context_vk
,
2037 const struct wined3d_state
*state
, struct wined3d_graphics_pipeline_key_vk
*key
)
2039 VkPipelineColorBlendStateCreateInfo
*desc
= &key
->blend_desc
;
2040 const struct wined3d_blend_state_desc
*b
;
2043 desc
->attachmentCount
= context_vk
->rt_count
;
2045 memset(key
->blend_attachments
, 0, sizeof(key
->blend_attachments
));
2046 if (!state
->blend_state
)
2048 for (i
= 0; i
< context_vk
->rt_count
; ++i
)
2050 key
->blend_attachments
[i
].colorWriteMask
= VK_COLOR_COMPONENT_R_BIT
2051 | VK_COLOR_COMPONENT_G_BIT
2052 | VK_COLOR_COMPONENT_B_BIT
2053 | VK_COLOR_COMPONENT_A_BIT
;
2059 b
= &state
->blend_state
->desc
;
2060 for (i
= 0; i
< context_vk
->rt_count
; ++i
)
2062 const struct wined3d_rendertarget_blend_state_desc
*rt
= &b
->rt
[b
->independent
? i
: 0];
2063 const struct wined3d_rendertarget_view
*rtv
= state
->fb
.render_targets
[i
];
2064 VkPipelineColorBlendAttachmentState
*a
= &key
->blend_attachments
[i
];
2065 enum wined3d_blend src_blend
, dst_blend
;
2066 const struct wined3d_format
*rt_format
;
2068 a
->colorWriteMask
= vk_colour_write_mask_from_wined3d(rt
->writemask
);
2073 rt_format
= rtv
->format
;
2075 rt_format
= wined3d_get_format(context_vk
->c
.device
->adapter
, WINED3DFMT_NULL
, 0);
2076 a
->blendEnable
= VK_TRUE
;
2078 src_blend
= rt
->src
;
2079 dst_blend
= rt
->dst
;
2080 if (src_blend
== WINED3D_BLEND_BOTHSRCALPHA
)
2082 src_blend
= WINED3D_BLEND_SRCALPHA
;
2083 dst_blend
= WINED3D_BLEND_INVSRCALPHA
;
2085 else if (src_blend
== WINED3D_BLEND_BOTHINVSRCALPHA
)
2087 src_blend
= WINED3D_BLEND_INVSRCALPHA
;
2088 dst_blend
= WINED3D_BLEND_SRCALPHA
;
2090 a
->srcColorBlendFactor
= vk_blend_factor_from_wined3d(src_blend
, rt_format
, FALSE
);
2091 a
->dstColorBlendFactor
= vk_blend_factor_from_wined3d(dst_blend
, rt_format
, FALSE
);
2092 a
->colorBlendOp
= vk_blend_op_from_wined3d(rt
->op
);
2094 src_blend
= rt
->src_alpha
;
2095 dst_blend
= rt
->dst_alpha
;
2096 a
->srcAlphaBlendFactor
= vk_blend_factor_from_wined3d(src_blend
, rt_format
, TRUE
);
2097 a
->dstAlphaBlendFactor
= vk_blend_factor_from_wined3d(dst_blend
, rt_format
, TRUE
);
2098 a
->alphaBlendOp
= vk_blend_op_from_wined3d(rt
->op_alpha
);
2102 static VkFormat
vk_format_from_component_type(enum wined3d_component_type component_type
)
2104 switch (component_type
)
2106 case WINED3D_TYPE_UINT
:
2107 return VK_FORMAT_R32G32B32A32_UINT
;
2108 case WINED3D_TYPE_INT
:
2109 return VK_FORMAT_R32G32B32A32_SINT
;
2110 case WINED3D_TYPE_UNKNOWN
:
2111 case WINED3D_TYPE_FLOAT
:
2112 return VK_FORMAT_R32G32B32A32_SFLOAT
;
2114 return VK_FORMAT_UNDEFINED
;
2117 static bool wined3d_context_vk_update_graphics_pipeline_key(struct wined3d_context_vk
*context_vk
,
2118 const struct wined3d_state
*state
, VkPipelineLayout vk_pipeline_layout
, uint32_t *null_buffer_binding
)
2120 unsigned int i
, attribute_count
, binding_count
, divisor_count
, stage_count
;
2121 const struct wined3d_d3d_info
*d3d_info
= context_vk
->c
.d3d_info
;
2122 struct wined3d_graphics_pipeline_key_vk
*key
;
2123 VkPipelineShaderStageCreateInfo
*stage
;
2124 struct wined3d_stream_info stream_info
;
2125 struct wined3d_shader
*vertex_shader
;
2126 VkPrimitiveTopology vk_topology
;
2127 VkShaderModule module
;
2128 bool update
= false;
2131 *null_buffer_binding
= ~0u;
2132 key
= &context_vk
->graphics
.pipeline_key_vk
;
2134 if (context_vk
->c
.shader_update_mask
& ~(1u << WINED3D_SHADER_TYPE_COMPUTE
))
2137 for (i
= 0; i
< ARRAY_SIZE(context_vk
->graphics
.vk_modules
); ++i
)
2139 if (!(module
= context_vk
->graphics
.vk_modules
[i
]))
2142 stage
= &key
->stages
[stage_count
++];
2143 stage
->stage
= vk_shader_stage_from_wined3d(i
);
2144 stage
->module
= module
;
2147 key
->pipeline_desc
.stageCount
= stage_count
;
2152 if (wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_VDECL
)
2153 || wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_STREAMSRC
)
2154 || wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX
)))
2156 VkVertexInputAttributeDescription
*a
;
2157 VkVertexInputBindingDescription
*b
;
2159 wined3d_stream_info_from_declaration(&stream_info
, state
, d3d_info
);
2161 for (i
= 0, mask
= 0, attribute_count
= 0, binding_count
= 0; i
< ARRAY_SIZE(stream_info
.elements
); ++i
)
2163 VkVertexInputBindingDivisorDescriptionEXT
*d
;
2164 struct wined3d_stream_info_element
*e
;
2167 if (!(stream_info
.use_map
& (1u << i
)))
2170 a
= &key
->attributes
[attribute_count
++];
2171 e
= &stream_info
.elements
[i
];
2172 binding
= e
->stream_idx
;
2175 a
->binding
= binding
;
2176 a
->format
= wined3d_format_vk(e
->format
)->vk_format
;
2177 a
->offset
= (UINT_PTR
)e
->data
.addr
- state
->streams
[binding
].offset
;
2179 if (mask
& (1u << binding
))
2181 mask
|= 1u << binding
;
2183 b
= &key
->bindings
[binding_count
++];
2184 b
->binding
= binding
;
2185 b
->stride
= e
->stride
;
2186 b
->inputRate
= e
->instanced
? VK_VERTEX_INPUT_RATE_INSTANCE
: VK_VERTEX_INPUT_RATE_VERTEX
;
2190 d
= &key
->divisors
[divisor_count
++];
2191 d
->binding
= binding
;
2192 d
->divisor
= e
->divisor
;
2196 vertex_shader
= state
->shader
[WINED3D_SHADER_TYPE_VERTEX
];
2197 if (vertex_shader
&& (mask
= ~stream_info
.use_map
& vertex_shader
->reg_maps
.input_registers
))
2199 struct wined3d_shader_signature_element
*element
;
2200 struct wined3d_shader_signature
*signature
;
2201 uint32_t null_binding
, location
;
2203 for (i
= 0; i
< ARRAY_SIZE(state
->streams
); ++i
)
2205 if (!state
->streams
[i
].buffer
)
2212 if (i
== ARRAY_SIZE(state
->streams
))
2214 ERR("No streams left for a null buffer binding.\n");
2218 signature
= &vertex_shader
->input_signature
;
2219 for (i
= 0; i
< signature
->element_count
; ++i
)
2221 element
= &signature
->elements
[i
];
2222 location
= element
->register_idx
;
2224 if (!(mask
& (1u << location
)) || element
->sysval_semantic
)
2226 mask
&= ~(1u << location
);
2228 a
= &key
->attributes
[attribute_count
++];
2229 a
->location
= location
;
2230 a
->binding
= null_binding
;
2231 a
->format
= vk_format_from_component_type(element
->component_type
);
2235 if (mask
!= (~stream_info
.use_map
& vertex_shader
->reg_maps
.input_registers
))
2237 b
= &key
->bindings
[binding_count
++];
2238 *null_buffer_binding
= b
->binding
= null_binding
;
2240 b
->inputRate
= VK_VERTEX_INPUT_RATE_VERTEX
;
2245 key
->input_desc
.pNext
= NULL
;
2246 key
->input_desc
.vertexBindingDescriptionCount
= binding_count
;
2247 key
->input_desc
.vertexAttributeDescriptionCount
= attribute_count
;
2251 key
->input_desc
.pNext
= &key
->divisor_desc
;
2252 key
->divisor_desc
.vertexBindingDivisorCount
= divisor_count
;
2258 vk_topology
= vk_topology_from_wined3d(state
->primitive_type
);
2259 if (key
->ia_desc
.topology
!= vk_topology
)
2261 key
->ia_desc
.topology
= vk_topology
;
2262 key
->ia_desc
.primitiveRestartEnable
= !(d3d_info
->wined3d_creation_flags
& WINED3D_NO_PRIMITIVE_RESTART
)
2263 && !wined3d_primitive_type_is_list(state
->primitive_type
);
2268 if (key
->ts_desc
.patchControlPoints
!= state
->patch_vertex_count
)
2270 key
->ts_desc
.patchControlPoints
= state
->patch_vertex_count
;
2275 if (wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_VIEWPORT
)
2276 || wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_SCISSORRECT
)
2277 || wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_RASTERIZER
))
2279 key
->viewport
.x
= state
->viewports
[0].x
;
2280 key
->viewport
.y
= state
->viewports
[0].y
;
2281 key
->viewport
.width
= state
->viewports
[0].width
;
2282 key
->viewport
.height
= state
->viewports
[0].height
;
2283 key
->viewport
.minDepth
= state
->viewports
[0].min_z
;
2284 key
->viewport
.maxDepth
= state
->viewports
[0].max_z
;
2286 if (state
->rasterizer_state
&& state
->rasterizer_state
->desc
.scissor
)
2288 const RECT
*r
= &state
->scissor_rects
[0];
2290 key
->scissor
.offset
.x
= r
->left
;
2291 key
->scissor
.offset
.y
= r
->top
;
2292 key
->scissor
.extent
.width
= r
->right
- r
->left
;
2293 key
->scissor
.extent
.height
= r
->bottom
- r
->top
;
2297 key
->scissor
.offset
.x
= key
->viewport
.x
;
2298 key
->scissor
.offset
.y
= key
->viewport
.y
;
2299 key
->scissor
.extent
.width
= key
->viewport
.width
;
2300 key
->scissor
.extent
.height
= key
->viewport
.height
;
2302 /* Scissor offsets need to be non-negative (VUID-VkPipelineViewportStateCreateInfo-x-02821) */
2303 if (key
->scissor
.offset
.x
< 0)
2304 key
->scissor
.offset
.x
= 0;
2305 if (key
->scissor
.offset
.y
< 0)
2306 key
->scissor
.offset
.y
= 0;
2307 key
->viewport
.y
+= key
->viewport
.height
;
2308 key
->viewport
.height
= -key
->viewport
.height
;
2313 if (wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_RASTERIZER
)
2314 || wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_SHADER(WINED3D_SHADER_TYPE_GEOMETRY
)))
2316 wined3d_context_vk_update_rasterisation_state(context_vk
, state
, key
);
2321 if (key
->ms_desc
.rasterizationSamples
!= context_vk
->sample_count
2322 || isStateDirty(&context_vk
->c
, STATE_BLEND
) || isStateDirty(&context_vk
->c
, STATE_SAMPLE_MASK
))
2324 key
->ms_desc
.rasterizationSamples
= context_vk
->sample_count
;
2325 key
->ms_desc
.alphaToCoverageEnable
= state
->blend_state
&& state
->blend_state
->desc
.alpha_to_coverage
;
2326 key
->sample_mask
= state
->sample_mask
;
2331 if (wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_DEPTH_STENCIL
)
2332 || wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_FRAMEBUFFER
))
2334 const struct wined3d_depth_stencil_state
*d
= state
->depth_stencil_state
;
2338 key
->ds_desc
.depthTestEnable
= d
->desc
.depth
;
2339 key
->ds_desc
.depthWriteEnable
= d
->desc
.depth_write
;
2340 key
->ds_desc
.depthCompareOp
= vk_compare_op_from_wined3d(d
->desc
.depth_func
);
2341 key
->ds_desc
.stencilTestEnable
= state
->fb
.depth_stencil
&& d
->desc
.stencil
;
2342 if (key
->ds_desc
.stencilTestEnable
)
2344 key
->ds_desc
.front
.failOp
= vk_stencil_op_from_wined3d(d
->desc
.front
.fail_op
);
2345 key
->ds_desc
.front
.passOp
= vk_stencil_op_from_wined3d(d
->desc
.front
.pass_op
);
2346 key
->ds_desc
.front
.depthFailOp
= vk_stencil_op_from_wined3d(d
->desc
.front
.depth_fail_op
);
2347 key
->ds_desc
.front
.compareOp
= vk_compare_op_from_wined3d(d
->desc
.front
.func
);
2348 key
->ds_desc
.front
.compareMask
= d
->desc
.stencil_read_mask
;
2349 key
->ds_desc
.front
.writeMask
= d
->desc
.stencil_write_mask
;
2351 key
->ds_desc
.back
.failOp
= vk_stencil_op_from_wined3d(d
->desc
.back
.fail_op
);
2352 key
->ds_desc
.back
.passOp
= vk_stencil_op_from_wined3d(d
->desc
.back
.pass_op
);
2353 key
->ds_desc
.back
.depthFailOp
= vk_stencil_op_from_wined3d(d
->desc
.back
.depth_fail_op
);
2354 key
->ds_desc
.back
.compareOp
= vk_compare_op_from_wined3d(d
->desc
.back
.func
);
2355 key
->ds_desc
.back
.compareMask
= d
->desc
.stencil_read_mask
;
2356 key
->ds_desc
.back
.writeMask
= d
->desc
.stencil_write_mask
;
2360 memset(&key
->ds_desc
.front
, 0, sizeof(key
->ds_desc
.front
));
2361 memset(&key
->ds_desc
.back
, 0, sizeof(key
->ds_desc
.back
));
2366 key
->ds_desc
.depthTestEnable
= VK_TRUE
;
2367 key
->ds_desc
.depthWriteEnable
= VK_TRUE
;
2368 key
->ds_desc
.depthCompareOp
= VK_COMPARE_OP_LESS
;
2369 key
->ds_desc
.stencilTestEnable
= VK_FALSE
;
2375 if (wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_BLEND
)
2376 || wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_FRAMEBUFFER
))
2378 wined3d_context_vk_update_blend_state(context_vk
, state
, key
);
2383 if (key
->pipeline_desc
.layout
!= vk_pipeline_layout
)
2385 key
->pipeline_desc
.layout
= vk_pipeline_layout
;
2390 if (key
->pipeline_desc
.renderPass
!= context_vk
->vk_render_pass
)
2392 key
->pipeline_desc
.renderPass
= context_vk
->vk_render_pass
;
2400 static bool wined3d_context_vk_begin_render_pass(struct wined3d_context_vk
*context_vk
,
2401 VkCommandBuffer vk_command_buffer
, const struct wined3d_state
*state
, const struct wined3d_vk_info
*vk_info
)
2403 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
2404 VkImageView vk_views
[WINED3D_MAX_RENDER_TARGETS
+ 1];
2405 unsigned int fb_width
, fb_height
, fb_layer_count
;
2406 struct wined3d_rendertarget_view_vk
*rtv_vk
;
2407 struct wined3d_rendertarget_view
*view
;
2408 const VkPhysicalDeviceLimits
*limits
;
2409 struct wined3d_query_vk
*query_vk
;
2410 VkRenderPassBeginInfo begin_info
;
2411 unsigned int attachment_count
, i
;
2412 VkFramebufferCreateInfo fb_desc
;
2415 if (context_vk
->vk_render_pass
)
2418 limits
= &wined3d_adapter_vk(device_vk
->d
.adapter
)->device_limits
;
2419 fb_width
= limits
->maxFramebufferWidth
;
2420 fb_height
= limits
->maxFramebufferHeight
;
2421 fb_layer_count
= limits
->maxFramebufferLayers
;
2422 attachment_count
= 0;
2424 context_vk
->rt_count
= 0;
2425 for (i
= 0; i
< ARRAY_SIZE(state
->fb
.render_targets
); ++i
)
2427 if (!(view
= state
->fb
.render_targets
[i
]) || view
->format
->id
== WINED3DFMT_NULL
)
2430 rtv_vk
= wined3d_rendertarget_view_vk(view
);
2431 vk_views
[attachment_count
] = wined3d_rendertarget_view_vk_get_image_view(rtv_vk
, context_vk
);
2432 wined3d_rendertarget_view_vk_barrier(rtv_vk
, context_vk
, WINED3D_BIND_RENDER_TARGET
);
2433 wined3d_context_vk_reference_rendertarget_view(context_vk
, rtv_vk
);
2435 if (view
->width
< fb_width
)
2436 fb_width
= view
->width
;
2437 if (view
->height
< fb_height
)
2438 fb_height
= view
->height
;
2439 if (view
->layer_count
< fb_layer_count
)
2440 fb_layer_count
= view
->layer_count
;
2441 context_vk
->rt_count
= i
+ 1;
2445 if ((view
= state
->fb
.depth_stencil
))
2447 rtv_vk
= wined3d_rendertarget_view_vk(view
);
2448 vk_views
[attachment_count
] = wined3d_rendertarget_view_vk_get_image_view(rtv_vk
, context_vk
);
2449 wined3d_rendertarget_view_vk_barrier(rtv_vk
, context_vk
, WINED3D_BIND_DEPTH_STENCIL
);
2450 wined3d_context_vk_reference_rendertarget_view(context_vk
, rtv_vk
);
2452 if (view
->width
< fb_width
)
2453 fb_width
= view
->width
;
2454 if (view
->height
< fb_height
)
2455 fb_height
= view
->height
;
2456 if (view
->layer_count
< fb_layer_count
)
2457 fb_layer_count
= view
->layer_count
;
2461 if (!(context_vk
->vk_render_pass
= wined3d_context_vk_get_render_pass(context_vk
, &state
->fb
,
2462 ARRAY_SIZE(state
->fb
.render_targets
), !!state
->fb
.depth_stencil
, 0)))
2464 ERR("Failed to get render pass.\n");
2468 fb_desc
.sType
= VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO
;
2469 fb_desc
.pNext
= NULL
;
2471 fb_desc
.renderPass
= context_vk
->vk_render_pass
;
2472 fb_desc
.attachmentCount
= attachment_count
;
2473 fb_desc
.pAttachments
= vk_views
;
2474 fb_desc
.width
= fb_width
;
2475 fb_desc
.height
= fb_height
;
2476 fb_desc
.layers
= fb_layer_count
;
2478 if ((vr
= VK_CALL(vkCreateFramebuffer(device_vk
->vk_device
, &fb_desc
, NULL
, &context_vk
->vk_framebuffer
))) < 0)
2480 WARN("Failed to create Vulkan framebuffer, vr %s.\n", wined3d_debug_vkresult(vr
));
2484 begin_info
.sType
= VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO
;
2485 begin_info
.pNext
= NULL
;
2486 begin_info
.renderPass
= context_vk
->vk_render_pass
;
2487 begin_info
.framebuffer
= context_vk
->vk_framebuffer
;
2488 begin_info
.renderArea
.offset
.x
= 0;
2489 begin_info
.renderArea
.offset
.y
= 0;
2490 begin_info
.renderArea
.extent
.width
= fb_width
;
2491 begin_info
.renderArea
.extent
.height
= fb_height
;
2492 begin_info
.clearValueCount
= 0;
2493 begin_info
.pClearValues
= NULL
;
2494 VK_CALL(vkCmdBeginRenderPass(vk_command_buffer
, &begin_info
, VK_SUBPASS_CONTENTS_INLINE
));
2496 LIST_FOR_EACH_ENTRY(query_vk
, &context_vk
->render_pass_queries
, struct wined3d_query_vk
, entry
)
2497 wined3d_query_vk_resume(query_vk
, context_vk
);
2501 static void wined3d_context_vk_bind_vertex_buffers(struct wined3d_context_vk
*context_vk
,
2502 VkCommandBuffer vk_command_buffer
, const struct wined3d_state
*state
, const struct wined3d_vk_info
*vk_info
)
2504 VkDeviceSize offsets
[ARRAY_SIZE(state
->streams
)] = {0};
2505 VkBuffer buffers
[ARRAY_SIZE(state
->streams
)];
2506 const struct wined3d_stream_state
*stream
;
2507 const VkDescriptorBufferInfo
*buffer_info
;
2508 struct wined3d_buffer_vk
*buffer_vk
;
2509 struct wined3d_buffer
*buffer
;
2510 unsigned int i
, first
, count
;
2514 for (i
= 0; i
< ARRAY_SIZE(state
->streams
); ++i
)
2516 stream
= &state
->streams
[i
];
2518 if ((buffer
= stream
->buffer
))
2520 buffer_vk
= wined3d_buffer_vk(buffer
);
2521 buffer_info
= wined3d_buffer_vk_get_buffer_info(buffer_vk
);
2522 wined3d_context_vk_reference_bo(context_vk
, wined3d_bo_vk(buffer
->buffer_object
));
2523 buffers
[count
] = buffer_info
->buffer
;
2524 offsets
[count
] = buffer_info
->offset
+ stream
->offset
;
2530 VK_CALL(vkCmdBindVertexBuffers(vk_command_buffer
, first
, count
, buffers
, offsets
));
2536 VK_CALL(vkCmdBindVertexBuffers(vk_command_buffer
, first
, count
, buffers
, offsets
));
2539 static void wined3d_context_vk_bind_stream_output_buffers(struct wined3d_context_vk
*context_vk
,
2540 VkCommandBuffer vk_command_buffer
, const struct wined3d_state
*state
, const struct wined3d_vk_info
*vk_info
)
2542 VkDeviceSize offsets
[ARRAY_SIZE(state
->stream_output
)];
2543 VkDeviceSize sizes
[ARRAY_SIZE(state
->stream_output
)];
2544 VkBuffer buffers
[ARRAY_SIZE(state
->stream_output
)];
2545 const struct wined3d_stream_output
*stream
;
2546 const VkDescriptorBufferInfo
*buffer_info
;
2547 struct wined3d_buffer_vk
*buffer_vk
;
2548 struct wined3d_buffer
*buffer
;
2549 unsigned int i
, first
, count
;
2553 for (i
= 0; i
< ARRAY_SIZE(state
->stream_output
); ++i
)
2555 stream
= &state
->stream_output
[i
];
2557 if ((buffer
= stream
->buffer
))
2559 buffer_vk
= wined3d_buffer_vk(buffer
);
2560 buffer_info
= wined3d_buffer_vk_get_buffer_info(buffer_vk
);
2561 wined3d_context_vk_reference_bo(context_vk
, wined3d_bo_vk(buffer
->buffer_object
));
2562 buffers
[count
] = buffer_info
->buffer
;
2563 if ((offsets
[count
] = stream
->offset
) == ~0u)
2565 FIXME("Appending to stream output buffers not implemented.\n");
2568 sizes
[count
] = buffer_info
->range
- offsets
[count
];
2569 offsets
[count
] += buffer_info
->offset
;
2575 VK_CALL(vkCmdBindTransformFeedbackBuffersEXT(vk_command_buffer
, first
, count
, buffers
, offsets
, sizes
));
2581 VK_CALL(vkCmdBindTransformFeedbackBuffersEXT(vk_command_buffer
, first
, count
, buffers
, offsets
, sizes
));
2584 static VkResult
wined3d_context_vk_create_vk_descriptor_pool(struct wined3d_device_vk
*device_vk
,
2585 const struct wined3d_vk_info
*vk_info
, VkDescriptorPool
*vk_pool
)
2587 struct VkDescriptorPoolCreateInfo pool_desc
;
2590 static const VkDescriptorPoolSize pool_sizes
[] =
2592 {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
, 1024},
2593 {VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
, 1024},
2594 {VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
, 1024},
2595 {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
, 1024},
2596 {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
, 1024},
2597 {VK_DESCRIPTOR_TYPE_SAMPLER
, 1024},
2600 pool_desc
.sType
= VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO
;
2601 pool_desc
.pNext
= NULL
;
2602 pool_desc
.flags
= 0;
2603 pool_desc
.maxSets
= 512;
2604 pool_desc
.poolSizeCount
= ARRAY_SIZE(pool_sizes
);
2605 pool_desc
.pPoolSizes
= pool_sizes
;
2607 if ((vr
= VK_CALL(vkCreateDescriptorPool(device_vk
->vk_device
, &pool_desc
, NULL
, vk_pool
))) < 0)
2608 ERR("Failed to create descriptor pool, vr %s.\n", wined3d_debug_vkresult(vr
));
2613 VkResult
wined3d_context_vk_create_vk_descriptor_set(struct wined3d_context_vk
*context_vk
,
2614 VkDescriptorSetLayout vk_set_layout
, VkDescriptorSet
*vk_descriptor_set
)
2616 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
2617 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
2618 struct VkDescriptorSetAllocateInfo set_desc
;
2621 if (!context_vk
->vk_descriptor_pool
&& (vr
= wined3d_context_vk_create_vk_descriptor_pool(device_vk
,
2622 vk_info
, &context_vk
->vk_descriptor_pool
)))
2624 WARN("Failed to create descriptor pool, vr %s.\n", wined3d_debug_vkresult(vr
));
2628 set_desc
.sType
= VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO
;
2629 set_desc
.pNext
= NULL
;
2630 set_desc
.descriptorPool
= context_vk
->vk_descriptor_pool
;
2631 set_desc
.descriptorSetCount
= 1;
2632 set_desc
.pSetLayouts
= &vk_set_layout
;
2633 if ((vr
= VK_CALL(vkAllocateDescriptorSets(device_vk
->vk_device
, &set_desc
, vk_descriptor_set
))) >= 0)
2636 if (vr
== VK_ERROR_FRAGMENTED_POOL
|| vr
== VK_ERROR_OUT_OF_POOL_MEMORY
)
2638 wined3d_context_vk_destroy_vk_descriptor_pool(context_vk
,
2639 context_vk
->vk_descriptor_pool
, context_vk
->current_command_buffer
.id
);
2640 context_vk
->vk_descriptor_pool
= VK_NULL_HANDLE
;
2641 if ((vr
= wined3d_context_vk_create_vk_descriptor_pool(device_vk
, vk_info
, &context_vk
->vk_descriptor_pool
)))
2643 WARN("Failed to create descriptor pool, vr %s.\n", wined3d_debug_vkresult(vr
));
2647 set_desc
.descriptorPool
= context_vk
->vk_descriptor_pool
;
2648 if ((vr
= VK_CALL(vkAllocateDescriptorSets(device_vk
->vk_device
, &set_desc
, vk_descriptor_set
))) >= 0)
2652 WARN("Failed to allocate descriptor set, vr %s.\n", wined3d_debug_vkresult(vr
));
2657 static bool wined3d_shader_descriptor_writes_vk_add_write(struct wined3d_shader_descriptor_writes_vk
*writes
,
2658 VkDescriptorSet vk_descriptor_set
, size_t binding_idx
, VkDescriptorType type
,
2659 const VkDescriptorBufferInfo
*buffer_info
, const VkDescriptorImageInfo
*image_info
,
2660 const VkBufferView
*buffer_view
)
2662 SIZE_T write_count
= writes
->count
;
2663 VkWriteDescriptorSet
*write
;
2665 if (!wined3d_array_reserve((void **)&writes
->writes
, &writes
->size
,
2666 write_count
+ 1, sizeof(*writes
->writes
)))
2669 write
= &writes
->writes
[write_count
];
2670 write
->sType
= VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET
;
2671 write
->pNext
= NULL
;
2672 write
->dstSet
= vk_descriptor_set
;
2673 write
->dstBinding
= binding_idx
;
2674 write
->dstArrayElement
= 0;
2675 write
->descriptorCount
= 1;
2676 write
->descriptorType
= type
;
2677 write
->pImageInfo
= image_info
;
2678 write
->pBufferInfo
= buffer_info
;
2679 write
->pTexelBufferView
= buffer_view
;
2686 static bool wined3d_shader_resource_bindings_add_null_srv_binding(struct wined3d_shader_descriptor_writes_vk
*writes
,
2687 VkDescriptorSet vk_descriptor_set
, size_t binding_idx
, enum wined3d_shader_resource_type type
,
2688 enum wined3d_data_type data_type
, struct wined3d_context_vk
*context_vk
)
2690 const struct wined3d_null_views_vk
*v
= &wined3d_device_vk(context_vk
->c
.device
)->null_views_vk
;
2694 case WINED3D_SHADER_RESOURCE_BUFFER
:
2695 if (data_type
== WINED3D_DATA_FLOAT
)
2696 return wined3d_shader_descriptor_writes_vk_add_write(writes
, vk_descriptor_set
, binding_idx
,
2697 VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
, NULL
, NULL
, &v
->vk_view_buffer_float
);
2698 return wined3d_shader_descriptor_writes_vk_add_write(writes
, vk_descriptor_set
, binding_idx
,
2699 VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
, NULL
, NULL
, &v
->vk_view_buffer_uint
);
2701 case WINED3D_SHADER_RESOURCE_TEXTURE_1D
:
2702 return wined3d_shader_descriptor_writes_vk_add_write(writes
, vk_descriptor_set
,
2703 binding_idx
, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
, NULL
, &v
->vk_info_1d
, NULL
);
2705 case WINED3D_SHADER_RESOURCE_TEXTURE_2D
:
2706 return wined3d_shader_descriptor_writes_vk_add_write(writes
, vk_descriptor_set
,
2707 binding_idx
, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
, NULL
, &v
->vk_info_2d
, NULL
);
2709 case WINED3D_SHADER_RESOURCE_TEXTURE_2DMS
:
2710 return wined3d_shader_descriptor_writes_vk_add_write(writes
, vk_descriptor_set
,
2711 binding_idx
, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
, NULL
, &v
->vk_info_2dms
, NULL
);
2713 case WINED3D_SHADER_RESOURCE_TEXTURE_3D
:
2714 return wined3d_shader_descriptor_writes_vk_add_write(writes
, vk_descriptor_set
,
2715 binding_idx
, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
, NULL
, &v
->vk_info_3d
, NULL
);
2717 case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE
:
2718 return wined3d_shader_descriptor_writes_vk_add_write(writes
, vk_descriptor_set
,
2719 binding_idx
, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
, NULL
, &v
->vk_info_cube
, NULL
);
2721 case WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY
:
2722 return wined3d_shader_descriptor_writes_vk_add_write(writes
, vk_descriptor_set
,
2723 binding_idx
, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
, NULL
, &v
->vk_info_1d_array
, NULL
);
2725 case WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY
:
2726 return wined3d_shader_descriptor_writes_vk_add_write(writes
, vk_descriptor_set
,
2727 binding_idx
, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
, NULL
, &v
->vk_info_2d_array
, NULL
);
2729 case WINED3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY
:
2730 return wined3d_shader_descriptor_writes_vk_add_write(writes
, vk_descriptor_set
,
2731 binding_idx
, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
, NULL
, &v
->vk_info_2dms_array
, NULL
);
2733 case WINED3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY
:
2734 return wined3d_shader_descriptor_writes_vk_add_write(writes
, vk_descriptor_set
,
2735 binding_idx
, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
, NULL
, &v
->vk_info_cube_array
, NULL
);
2738 FIXME("Unhandled resource type %#x.\n", type
);
2743 static bool wined3d_shader_descriptor_writes_vk_add_cbv_write(struct wined3d_shader_descriptor_writes_vk
*writes
,
2744 struct wined3d_context_vk
*context_vk
, VkDescriptorSet vk_descriptor_set
, const struct wined3d_state
*state
,
2745 const struct wined3d_shader_resource_binding
*binding
, VkDescriptorBufferInfo
*buffer_info
)
2747 const struct wined3d_constant_buffer_state
*cb_state
= &state
->cb
[binding
->shader_type
][binding
->resource_idx
];
2748 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
2749 struct wined3d_buffer_vk
*buffer_vk
;
2750 struct wined3d_buffer
*buffer
;
2752 if (!(buffer
= cb_state
->buffer
))
2753 return wined3d_shader_descriptor_writes_vk_add_write(writes
, vk_descriptor_set
, binding
->binding_idx
,
2754 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
, &device_vk
->null_resources_vk
.buffer_info
, NULL
, NULL
);
2756 buffer_vk
= wined3d_buffer_vk(buffer
);
2757 *buffer_info
= *wined3d_buffer_vk_get_buffer_info(buffer_vk
);
2758 buffer_info
->offset
+= cb_state
->offset
;
2759 buffer_info
->range
= min(cb_state
->size
, buffer_info
->range
);
2760 if (!wined3d_shader_descriptor_writes_vk_add_write(writes
, vk_descriptor_set
,
2761 binding
->binding_idx
, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
, buffer_info
, NULL
, NULL
))
2763 wined3d_context_vk_reference_bo(context_vk
, wined3d_bo_vk(buffer
->buffer_object
));
2767 static bool wined3d_shader_descriptor_writes_vk_add_srv_write(struct wined3d_shader_descriptor_writes_vk
*writes
,
2768 struct wined3d_context_vk
*context_vk
, VkDescriptorSet vk_descriptor_set
, const struct wined3d_state
*state
,
2769 const struct wined3d_shader_resource_binding
*binding
)
2771 struct wined3d_shader_resource_view_vk
*srv_vk
;
2772 struct wined3d_shader_resource_view
*srv
;
2773 const VkDescriptorImageInfo
*image_info
;
2774 struct wined3d_resource
*resource
;
2775 struct wined3d_view_vk
*view_vk
;
2776 VkBufferView
*buffer_view
;
2777 VkDescriptorType type
;
2779 if (!(srv
= state
->shader_resource_view
[binding
->shader_type
][binding
->resource_idx
]))
2780 return wined3d_shader_resource_bindings_add_null_srv_binding(writes
, vk_descriptor_set
,
2781 binding
->binding_idx
, binding
->resource_type
, binding
->resource_data_type
, context_vk
);
2783 resource
= srv
->resource
;
2784 srv_vk
= wined3d_shader_resource_view_vk(srv
);
2785 view_vk
= &srv_vk
->view_vk
;
2786 if (resource
->type
== WINED3D_RTYPE_BUFFER
)
2789 buffer_view
= &view_vk
->u
.vk_buffer_view
;
2790 type
= VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
;
2794 struct wined3d_texture_vk
*texture_vk
= wined3d_texture_vk(texture_from_resource(resource
));
2796 if (view_vk
->u
.vk_image_info
.imageView
)
2797 image_info
= &view_vk
->u
.vk_image_info
;
2799 image_info
= wined3d_texture_vk_get_default_image_info(texture_vk
, context_vk
);
2801 type
= VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
;
2804 if (!wined3d_shader_descriptor_writes_vk_add_write(writes
, vk_descriptor_set
,
2805 binding
->binding_idx
, type
, NULL
, image_info
, buffer_view
))
2807 wined3d_context_vk_reference_shader_resource_view(context_vk
, srv_vk
);
2811 static bool wined3d_shader_descriptor_writes_vk_add_uav_write(struct wined3d_shader_descriptor_writes_vk
*writes
,
2812 struct wined3d_context_vk
*context_vk
, enum wined3d_pipeline pipeline
, VkDescriptorSet vk_descriptor_set
,
2813 const struct wined3d_state
*state
, const struct wined3d_shader_resource_binding
*binding
)
2815 struct wined3d_unordered_access_view_vk
*uav_vk
;
2816 struct wined3d_unordered_access_view
*uav
;
2817 const VkDescriptorImageInfo
*image_info
;
2818 struct wined3d_resource
*resource
;
2819 struct wined3d_view_vk
*view_vk
;
2820 VkBufferView
*buffer_view
;
2821 VkDescriptorType type
;
2823 if (!(uav
= state
->unordered_access_view
[pipeline
][binding
->resource_idx
]))
2825 FIXME("NULL unordered access views not implemented.\n");
2828 resource
= uav
->resource
;
2830 uav_vk
= wined3d_unordered_access_view_vk(uav
);
2831 view_vk
= &uav_vk
->view_vk
;
2832 if (resource
->type
== WINED3D_RTYPE_BUFFER
)
2835 buffer_view
= &view_vk
->u
.vk_buffer_view
;
2836 type
= VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
;
2840 struct wined3d_texture_vk
*texture_vk
= wined3d_texture_vk(texture_from_resource(resource
));
2842 if (view_vk
->u
.vk_image_info
.imageView
)
2843 image_info
= &view_vk
->u
.vk_image_info
;
2845 image_info
= wined3d_texture_vk_get_default_image_info(texture_vk
, context_vk
);
2847 type
= VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
;
2850 if (!wined3d_shader_descriptor_writes_vk_add_write(writes
, vk_descriptor_set
,
2851 binding
->binding_idx
, type
, NULL
, image_info
, buffer_view
))
2853 wined3d_context_vk_reference_unordered_access_view(context_vk
, uav_vk
);
2857 static bool wined3d_shader_descriptor_writes_vk_add_uav_counter_write(
2858 struct wined3d_shader_descriptor_writes_vk
*writes
, struct wined3d_context_vk
*context_vk
,
2859 enum wined3d_pipeline pipeline
, VkDescriptorSet vk_descriptor_set
,
2860 const struct wined3d_state
*state
, const struct wined3d_shader_resource_binding
*binding
)
2862 struct wined3d_unordered_access_view_vk
*uav_vk
;
2863 struct wined3d_unordered_access_view
*uav
;
2865 if (!(uav
= state
->unordered_access_view
[pipeline
][binding
->resource_idx
]))
2867 FIXME("NULL unordered access view counters not implemented.\n");
2871 uav_vk
= wined3d_unordered_access_view_vk(uav
);
2872 if (!uav_vk
->vk_counter_view
)
2875 return wined3d_shader_descriptor_writes_vk_add_write(writes
, vk_descriptor_set
, binding
->binding_idx
,
2876 VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
, NULL
, NULL
, &uav_vk
->vk_counter_view
);
2879 static bool wined3d_shader_descriptor_writes_vk_add_sampler_write(struct wined3d_shader_descriptor_writes_vk
*writes
,
2880 struct wined3d_context_vk
*context_vk
, VkDescriptorSet vk_descriptor_set
, const struct wined3d_state
*state
,
2881 const struct wined3d_shader_resource_binding
*binding
)
2883 struct wined3d_sampler
*sampler
;
2885 if (!(sampler
= state
->sampler
[binding
->shader_type
][binding
->resource_idx
]))
2886 sampler
= context_vk
->c
.device
->null_sampler
;
2887 if (!wined3d_shader_descriptor_writes_vk_add_write(writes
, vk_descriptor_set
, binding
->binding_idx
,
2888 VK_DESCRIPTOR_TYPE_SAMPLER
, NULL
, &wined3d_sampler_vk(sampler
)->vk_image_info
, NULL
))
2890 wined3d_context_vk_reference_sampler(context_vk
, wined3d_sampler_vk(sampler
));
2894 static bool wined3d_context_vk_update_descriptors(struct wined3d_context_vk
*context_vk
,
2895 VkCommandBuffer vk_command_buffer
, const struct wined3d_state
*state
, enum wined3d_pipeline pipeline
)
2897 struct wined3d_shader_descriptor_writes_vk
*writes
= &context_vk
->descriptor_writes
;
2898 VkDescriptorBufferInfo buffers
[WINED3D_SHADER_TYPE_COUNT
][MAX_CONSTANT_BUFFERS
];
2899 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
2900 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
2901 const struct wined3d_shader_resource_binding
*binding
;
2902 struct wined3d_shader_resource_bindings
*bindings
;
2903 VkDescriptorSetLayout vk_set_layout
;
2904 VkPipelineLayout vk_pipeline_layout
;
2905 VkPipelineBindPoint vk_bind_point
;
2906 VkDescriptorSet vk_descriptor_set
;
2912 case WINED3D_PIPELINE_GRAPHICS
:
2913 bindings
= &context_vk
->graphics
.bindings
;
2914 vk_bind_point
= VK_PIPELINE_BIND_POINT_GRAPHICS
;
2915 vk_set_layout
= context_vk
->graphics
.vk_set_layout
;
2916 vk_pipeline_layout
= context_vk
->graphics
.vk_pipeline_layout
;
2919 case WINED3D_PIPELINE_COMPUTE
:
2920 bindings
= &context_vk
->compute
.bindings
;
2921 vk_bind_point
= VK_PIPELINE_BIND_POINT_COMPUTE
;
2922 vk_set_layout
= context_vk
->compute
.vk_set_layout
;
2923 vk_pipeline_layout
= context_vk
->compute
.vk_pipeline_layout
;
2927 ERR("Invalid pipeline %#x.\n", pipeline
);
2931 if ((vr
= wined3d_context_vk_create_vk_descriptor_set(context_vk
, vk_set_layout
, &vk_descriptor_set
)))
2933 WARN("Failed to create descriptor set, vr %s.\n", wined3d_debug_vkresult(vr
));
2938 for (i
= 0; i
< bindings
->count
; ++i
)
2940 binding
= &bindings
->bindings
[i
];
2942 switch (binding
->shader_descriptor_type
)
2944 case WINED3D_SHADER_DESCRIPTOR_TYPE_CBV
:
2945 if (!wined3d_shader_descriptor_writes_vk_add_cbv_write(writes
, context_vk
, vk_descriptor_set
,
2946 state
, binding
, &buffers
[binding
->shader_type
][binding
->resource_idx
]))
2950 case WINED3D_SHADER_DESCRIPTOR_TYPE_SRV
:
2951 if (!wined3d_shader_descriptor_writes_vk_add_srv_write(writes
,
2952 context_vk
, vk_descriptor_set
, state
, binding
))
2956 case WINED3D_SHADER_DESCRIPTOR_TYPE_UAV
:
2957 if (!wined3d_shader_descriptor_writes_vk_add_uav_write(writes
,
2958 context_vk
, pipeline
, vk_descriptor_set
, state
, binding
))
2962 case WINED3D_SHADER_DESCRIPTOR_TYPE_UAV_COUNTER
:
2963 if (!wined3d_shader_descriptor_writes_vk_add_uav_counter_write(writes
,
2964 context_vk
, pipeline
, vk_descriptor_set
, state
, binding
))
2968 case WINED3D_SHADER_DESCRIPTOR_TYPE_SAMPLER
:
2969 if (!wined3d_shader_descriptor_writes_vk_add_sampler_write(writes
,
2970 context_vk
, vk_descriptor_set
, state
, binding
))
2975 ERR("Invalid descriptor type %#x.\n", binding
->shader_descriptor_type
);
2980 VK_CALL(vkUpdateDescriptorSets(device_vk
->vk_device
, writes
->count
, writes
->writes
, 0, NULL
));
2981 VK_CALL(vkCmdBindDescriptorSets(vk_command_buffer
, vk_bind_point
,
2982 vk_pipeline_layout
, 0, 1, &vk_descriptor_set
, 0, NULL
));
2987 static VkResult
wined3d_context_vk_create_vk_descriptor_set_layout(struct wined3d_device_vk
*device_vk
,
2988 const struct wined3d_vk_info
*vk_info
, const struct wined3d_pipeline_layout_key_vk
*key
,
2989 VkDescriptorSetLayout
*vk_set_layout
)
2991 VkDescriptorSetLayoutCreateInfo layout_desc
;
2994 layout_desc
.sType
= VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO
;
2995 layout_desc
.pNext
= NULL
;
2996 layout_desc
.flags
= 0;
2997 layout_desc
.bindingCount
= key
->binding_count
;
2998 layout_desc
.pBindings
= key
->bindings
;
3000 if ((vr
= VK_CALL(vkCreateDescriptorSetLayout(device_vk
->vk_device
, &layout_desc
, NULL
, vk_set_layout
))) < 0)
3001 WARN("Failed to create Vulkan descriptor set layout, vr %s.\n", wined3d_debug_vkresult(vr
));
3006 struct wined3d_pipeline_layout_vk
*wined3d_context_vk_get_pipeline_layout(
3007 struct wined3d_context_vk
*context_vk
, VkDescriptorSetLayoutBinding
*bindings
, SIZE_T binding_count
)
3009 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
3010 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
3011 struct wined3d_pipeline_layout_key_vk key
;
3012 struct wined3d_pipeline_layout_vk
*layout
;
3013 VkPipelineLayoutCreateInfo layout_desc
;
3014 struct wine_rb_entry
*entry
;
3017 key
.bindings
= bindings
;
3018 key
.binding_count
= binding_count
;
3019 if ((entry
= wine_rb_get(&context_vk
->pipeline_layouts
, &key
)))
3020 return WINE_RB_ENTRY_VALUE(entry
, struct wined3d_pipeline_layout_vk
, entry
);
3022 if (!(layout
= heap_alloc(sizeof(*layout
))))
3025 if (!(layout
->key
.bindings
= heap_alloc(sizeof(*layout
->key
.bindings
) * key
.binding_count
)))
3030 memcpy(layout
->key
.bindings
, key
.bindings
, sizeof(*layout
->key
.bindings
) * key
.binding_count
);
3031 layout
->key
.binding_count
= key
.binding_count
;
3033 if ((vr
= wined3d_context_vk_create_vk_descriptor_set_layout(device_vk
, vk_info
, &key
, &layout
->vk_set_layout
)))
3035 WARN("Failed to create descriptor set layout, vr %s.\n", wined3d_debug_vkresult(vr
));
3039 layout_desc
.sType
= VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO
;
3040 layout_desc
.pNext
= NULL
;
3041 layout_desc
.flags
= 0;
3042 layout_desc
.setLayoutCount
= 1;
3043 layout_desc
.pSetLayouts
= &layout
->vk_set_layout
;
3044 layout_desc
.pushConstantRangeCount
= 0;
3045 layout_desc
.pPushConstantRanges
= NULL
;
3047 if ((vr
= VK_CALL(vkCreatePipelineLayout(device_vk
->vk_device
,
3048 &layout_desc
, NULL
, &layout
->vk_pipeline_layout
))) < 0)
3050 WARN("Failed to create Vulkan pipeline layout, vr %s.\n", wined3d_debug_vkresult(vr
));
3051 VK_CALL(vkDestroyDescriptorSetLayout(device_vk
->vk_device
, layout
->vk_set_layout
, NULL
));
3055 if (wine_rb_put(&context_vk
->pipeline_layouts
, &layout
->key
, &layout
->entry
) == -1)
3057 ERR("Failed to insert pipeline layout.\n");
3058 VK_CALL(vkDestroyPipelineLayout(device_vk
->vk_device
, layout
->vk_pipeline_layout
, NULL
));
3059 VK_CALL(vkDestroyDescriptorSetLayout(device_vk
->vk_device
, layout
->vk_set_layout
, NULL
));
3066 heap_free(layout
->key
.bindings
);
3071 static VkPipeline
wined3d_context_vk_get_graphics_pipeline(struct wined3d_context_vk
*context_vk
)
3073 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
3074 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
3075 struct wined3d_graphics_pipeline_vk
*pipeline_vk
;
3076 struct wined3d_graphics_pipeline_key_vk
*key
;
3077 struct wine_rb_entry
*entry
;
3080 key
= &context_vk
->graphics
.pipeline_key_vk
;
3081 if ((entry
= wine_rb_get(&context_vk
->graphics_pipelines
, key
)))
3082 return WINE_RB_ENTRY_VALUE(entry
, struct wined3d_graphics_pipeline_vk
, entry
)->vk_pipeline
;
3084 if (!(pipeline_vk
= heap_alloc(sizeof(*pipeline_vk
))))
3085 return VK_NULL_HANDLE
;
3086 pipeline_vk
->key
= *key
;
3088 if ((vr
= VK_CALL(vkCreateGraphicsPipelines(device_vk
->vk_device
,
3089 VK_NULL_HANDLE
, 1, &key
->pipeline_desc
, NULL
, &pipeline_vk
->vk_pipeline
))) < 0)
3091 WARN("Failed to create graphics pipeline, vr %s.\n", wined3d_debug_vkresult(vr
));
3092 heap_free(pipeline_vk
);
3093 return VK_NULL_HANDLE
;
3096 if (wine_rb_put(&context_vk
->graphics_pipelines
, &pipeline_vk
->key
, &pipeline_vk
->entry
) == -1)
3097 ERR("Failed to insert pipeline.\n");
3099 return pipeline_vk
->vk_pipeline
;
3102 static void wined3d_context_vk_load_shader_resources(struct wined3d_context_vk
*context_vk
,
3103 const struct wined3d_state
*state
, enum wined3d_pipeline pipeline
)
3105 struct wined3d_shader_descriptor_writes_vk
*writes
= &context_vk
->descriptor_writes
;
3106 const struct wined3d_shader_resource_bindings
*bindings
;
3107 const struct wined3d_shader_resource_binding
*binding
;
3108 struct wined3d_unordered_access_view_vk
*uav_vk
;
3109 struct wined3d_shader_resource_view_vk
*srv_vk
;
3110 struct wined3d_unordered_access_view
*uav
;
3111 struct wined3d_shader_resource_view
*srv
;
3112 struct wined3d_buffer_vk
*buffer_vk
;
3113 struct wined3d_sampler
*sampler
;
3114 struct wined3d_buffer
*buffer
;
3119 case WINED3D_PIPELINE_GRAPHICS
:
3120 bindings
= &context_vk
->graphics
.bindings
;
3123 case WINED3D_PIPELINE_COMPUTE
:
3124 bindings
= &context_vk
->compute
.bindings
;
3128 ERR("Invalid pipeline %#x.\n", pipeline
);
3133 for (i
= 0; i
< bindings
->count
; ++i
)
3135 binding
= &bindings
->bindings
[i
];
3137 switch (binding
->shader_descriptor_type
)
3139 case WINED3D_SHADER_DESCRIPTOR_TYPE_CBV
:
3140 if (!(buffer
= state
->cb
[binding
->shader_type
][binding
->resource_idx
].buffer
))
3143 buffer_vk
= wined3d_buffer_vk(buffer
);
3144 wined3d_buffer_load(buffer
, &context_vk
->c
, state
);
3145 if (!buffer_vk
->b
.bo_user
.valid
)
3147 if (pipeline
== WINED3D_PIPELINE_GRAPHICS
)
3148 context_invalidate_state(&context_vk
->c
, STATE_GRAPHICS_CONSTANT_BUFFER(binding
->shader_type
));
3150 context_invalidate_compute_state(&context_vk
->c
, STATE_COMPUTE_CONSTANT_BUFFER
);
3152 wined3d_buffer_vk_barrier(buffer_vk
, context_vk
, WINED3D_BIND_CONSTANT_BUFFER
);
3155 case WINED3D_SHADER_DESCRIPTOR_TYPE_SRV
:
3156 if (!(srv
= state
->shader_resource_view
[binding
->shader_type
][binding
->resource_idx
]))
3159 srv_vk
= wined3d_shader_resource_view_vk(srv
);
3160 if (srv
->resource
->type
== WINED3D_RTYPE_BUFFER
)
3162 if (!srv_vk
->view_vk
.bo_user
.valid
)
3164 wined3d_shader_resource_view_vk_update(srv_vk
, context_vk
);
3165 if (pipeline
== WINED3D_PIPELINE_GRAPHICS
)
3166 context_invalidate_state(&context_vk
->c
, STATE_GRAPHICS_SHADER_RESOURCE_BINDING
);
3168 context_invalidate_compute_state(&context_vk
->c
, STATE_COMPUTE_SHADER_RESOURCE_BINDING
);
3170 wined3d_buffer_load(buffer_from_resource(srv
->resource
), &context_vk
->c
, state
);
3174 wined3d_texture_load(texture_from_resource(srv
->resource
), &context_vk
->c
, FALSE
);
3176 wined3d_shader_resource_view_vk_barrier(srv_vk
, context_vk
, WINED3D_BIND_SHADER_RESOURCE
);
3179 case WINED3D_SHADER_DESCRIPTOR_TYPE_UAV
:
3180 if (!(uav
= state
->unordered_access_view
[pipeline
][binding
->resource_idx
]))
3183 uav_vk
= wined3d_unordered_access_view_vk(uav
);
3184 if (uav
->resource
->type
== WINED3D_RTYPE_BUFFER
)
3186 if (!uav_vk
->view_vk
.bo_user
.valid
)
3188 wined3d_unordered_access_view_vk_update(uav_vk
, context_vk
);
3189 if (pipeline
== WINED3D_PIPELINE_GRAPHICS
)
3190 context_invalidate_state(&context_vk
->c
, STATE_GRAPHICS_UNORDERED_ACCESS_VIEW_BINDING
);
3192 context_invalidate_compute_state(&context_vk
->c
,
3193 STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING
);
3195 wined3d_buffer_load(buffer_from_resource(uav
->resource
), &context_vk
->c
, state
);
3196 wined3d_unordered_access_view_invalidate_location(uav
, ~WINED3D_LOCATION_BUFFER
);
3200 wined3d_texture_load(texture_from_resource(uav
->resource
), &context_vk
->c
, FALSE
);
3201 wined3d_unordered_access_view_invalidate_location(uav
, ~WINED3D_LOCATION_TEXTURE_RGB
);
3203 wined3d_unordered_access_view_vk_barrier(uav_vk
, context_vk
, WINED3D_BIND_UNORDERED_ACCESS
);
3206 case WINED3D_SHADER_DESCRIPTOR_TYPE_UAV_COUNTER
:
3209 case WINED3D_SHADER_DESCRIPTOR_TYPE_SAMPLER
:
3210 if (!(sampler
= state
->sampler
[binding
->shader_type
][binding
->resource_idx
]))
3211 sampler
= context_vk
->c
.device
->null_sampler
;
3215 ERR("Invalid descriptor type %#x.\n", binding
->shader_descriptor_type
);
3221 VkCommandBuffer
wined3d_context_vk_apply_draw_state(struct wined3d_context_vk
*context_vk
,
3222 const struct wined3d_state
*state
, struct wined3d_buffer_vk
*indirect_vk
, bool indexed
)
3224 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
3225 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
3226 struct wined3d_rendertarget_view
*dsv
;
3227 struct wined3d_buffer_vk
*buffer_vk
;
3228 VkSampleCountFlagBits sample_count
;
3229 VkCommandBuffer vk_command_buffer
;
3230 struct wined3d_buffer
*buffer
;
3231 uint32_t null_buffer_binding
;
3234 if (wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL
))
3235 || wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_FRAMEBUFFER
))
3236 context_vk
->c
.shader_update_mask
|= (1u << WINED3D_SHADER_TYPE_PIXEL
);
3237 if (wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX
)))
3238 context_vk
->c
.shader_update_mask
|= (1u << WINED3D_SHADER_TYPE_VERTEX
);
3239 if (wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_SHADER(WINED3D_SHADER_TYPE_GEOMETRY
)))
3240 context_vk
->c
.shader_update_mask
|= (1u << WINED3D_SHADER_TYPE_GEOMETRY
);
3241 if (wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_SHADER(WINED3D_SHADER_TYPE_HULL
)))
3242 context_vk
->c
.shader_update_mask
|= (1u << WINED3D_SHADER_TYPE_HULL
) | (1u << WINED3D_SHADER_TYPE_DOMAIN
);
3243 if (wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_SHADER(WINED3D_SHADER_TYPE_DOMAIN
)))
3244 context_vk
->c
.shader_update_mask
|= (1u << WINED3D_SHADER_TYPE_DOMAIN
);
3246 context_vk
->sample_count
= 0;
3247 for (i
= 0; i
< ARRAY_SIZE(state
->fb
.render_targets
); ++i
)
3249 struct wined3d_rendertarget_view
*rtv
;
3251 if (!(rtv
= state
->fb
.render_targets
[i
]) || rtv
->format
->id
== WINED3DFMT_NULL
)
3254 if (wined3d_blend_state_get_writemask(state
->blend_state
, i
))
3256 wined3d_rendertarget_view_load_location(rtv
, &context_vk
->c
, rtv
->resource
->draw_binding
);
3257 wined3d_rendertarget_view_invalidate_location(rtv
, ~rtv
->resource
->draw_binding
);
3261 wined3d_rendertarget_view_prepare_location(rtv
, &context_vk
->c
, rtv
->resource
->draw_binding
);
3264 sample_count
= max(1, wined3d_resource_get_sample_count(rtv
->resource
));
3265 if (!context_vk
->sample_count
)
3266 context_vk
->sample_count
= sample_count
;
3267 else if (context_vk
->sample_count
!= sample_count
)
3268 FIXME("Inconsistent sample counts (%u != %u).\n", context_vk
->sample_count
, sample_count
);
3271 if ((dsv
= state
->fb
.depth_stencil
))
3273 if (wined3d_state_uses_depth_buffer(state
))
3274 wined3d_rendertarget_view_load_location(dsv
, &context_vk
->c
, dsv
->resource
->draw_binding
);
3276 wined3d_rendertarget_view_prepare_location(dsv
, &context_vk
->c
, dsv
->resource
->draw_binding
);
3277 if (!state
->depth_stencil_state
|| state
->depth_stencil_state
->desc
.depth_write
)
3278 wined3d_rendertarget_view_invalidate_location(dsv
, ~dsv
->resource
->draw_binding
);
3280 sample_count
= max(1, wined3d_resource_get_sample_count(dsv
->resource
));
3281 if (!context_vk
->sample_count
)
3282 context_vk
->sample_count
= sample_count
;
3283 else if (context_vk
->sample_count
!= sample_count
)
3284 FIXME("Inconsistent sample counts (%u != %u).\n", context_vk
->sample_count
, sample_count
);
3287 if (!context_vk
->sample_count
)
3288 context_vk
->sample_count
= VK_SAMPLE_COUNT_1_BIT
;
3289 if (context_vk
->c
.shader_update_mask
& ~(1u << WINED3D_SHADER_TYPE_COMPUTE
))
3291 device_vk
->d
.shader_backend
->shader_select(device_vk
->d
.shader_priv
, &context_vk
->c
, state
);
3292 if (!context_vk
->graphics
.vk_pipeline_layout
)
3294 ERR("No pipeline layout set.\n");
3295 return VK_NULL_HANDLE
;
3297 context_vk
->c
.update_shader_resource_bindings
= 1;
3298 context_vk
->c
.update_unordered_access_view_bindings
= 1;
3301 wined3d_context_vk_load_shader_resources(context_vk
, state
, WINED3D_PIPELINE_GRAPHICS
);
3303 for (i
= 0; i
< ARRAY_SIZE(state
->streams
); ++i
)
3305 if (!(buffer
= state
->streams
[i
].buffer
))
3308 buffer_vk
= wined3d_buffer_vk(buffer
);
3309 wined3d_buffer_load(&buffer_vk
->b
, &context_vk
->c
, state
);
3310 wined3d_buffer_vk_barrier(buffer_vk
, context_vk
, WINED3D_BIND_VERTEX_BUFFER
);
3311 if (!buffer_vk
->b
.bo_user
.valid
)
3312 context_invalidate_state(&context_vk
->c
, STATE_STREAMSRC
);
3315 if (use_transform_feedback(state
) && vk_info
->supported
[WINED3D_VK_EXT_TRANSFORM_FEEDBACK
])
3317 for (i
= 0; i
< ARRAY_SIZE(state
->stream_output
); ++i
)
3319 if (!(buffer
= state
->stream_output
[i
].buffer
))
3322 buffer_vk
= wined3d_buffer_vk(buffer
);
3323 wined3d_buffer_load(&buffer_vk
->b
, &context_vk
->c
, state
);
3324 wined3d_buffer_vk_barrier(buffer_vk
, context_vk
, WINED3D_BIND_STREAM_OUTPUT
);
3325 wined3d_buffer_invalidate_location(&buffer_vk
->b
, ~WINED3D_LOCATION_BUFFER
);
3326 if (!buffer_vk
->b
.bo_user
.valid
)
3327 context_vk
->update_stream_output
= 1;
3329 context_vk
->c
.transform_feedback_active
= 1;
3332 if (indexed
|| (wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_INDEXBUFFER
) && state
->index_buffer
))
3334 buffer_vk
= wined3d_buffer_vk(state
->index_buffer
);
3335 wined3d_buffer_load(&buffer_vk
->b
, &context_vk
->c
, state
);
3336 wined3d_buffer_vk_barrier(buffer_vk
, context_vk
, WINED3D_BIND_INDEX_BUFFER
);
3337 if (!buffer_vk
->b
.bo_user
.valid
)
3338 context_invalidate_state(&context_vk
->c
, STATE_INDEXBUFFER
);
3343 wined3d_buffer_load(&indirect_vk
->b
, &context_vk
->c
, state
);
3344 wined3d_buffer_vk_barrier(indirect_vk
, context_vk
, WINED3D_BIND_INDIRECT_BUFFER
);
3347 if (!(vk_command_buffer
= wined3d_context_vk_get_command_buffer(context_vk
)))
3349 ERR("Failed to get command buffer.\n");
3350 return VK_NULL_HANDLE
;
3353 if (wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_FRAMEBUFFER
))
3354 wined3d_context_vk_end_current_render_pass(context_vk
);
3355 if (!wined3d_context_vk_begin_render_pass(context_vk
, vk_command_buffer
, state
, vk_info
))
3357 ERR("Failed to begin render pass.\n");
3358 return VK_NULL_HANDLE
;
3361 if (wined3d_context_vk_update_graphics_pipeline_key(context_vk
, state
, context_vk
->graphics
.vk_pipeline_layout
,
3362 &null_buffer_binding
) || !context_vk
->graphics
.vk_pipeline
)
3364 if (!(context_vk
->graphics
.vk_pipeline
= wined3d_context_vk_get_graphics_pipeline(context_vk
)))
3366 ERR("Failed to get graphics pipeline.\n");
3367 return VK_NULL_HANDLE
;
3370 VK_CALL(vkCmdBindPipeline(vk_command_buffer
,
3371 VK_PIPELINE_BIND_POINT_GRAPHICS
, context_vk
->graphics
.vk_pipeline
));
3372 if (null_buffer_binding
!= ~0u)
3374 VkDeviceSize offset
= 0;
3375 VK_CALL(vkCmdBindVertexBuffers(vk_command_buffer
, null_buffer_binding
, 1,
3376 &device_vk
->null_resources_vk
.buffer_info
.buffer
, &offset
));
3380 if (wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_STENCIL_REF
) && dsv
)
3382 VK_CALL(vkCmdSetStencilReference(vk_command_buffer
, VK_STENCIL_FACE_FRONT_AND_BACK
,
3383 state
->stencil_ref
& wined3d_mask_from_size(dsv
->format
->stencil_size
)));
3386 if (wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_STREAMSRC
))
3387 wined3d_context_vk_bind_vertex_buffers(context_vk
, vk_command_buffer
, state
, vk_info
);
3389 if (wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_STREAM_OUTPUT
))
3391 context_vk
->update_stream_output
= 1;
3392 context_vk
->c
.transform_feedback_paused
= 0;
3394 if (context_vk
->c
.transform_feedback_active
&& context_vk
->update_stream_output
)
3396 wined3d_context_vk_bind_stream_output_buffers(context_vk
, vk_command_buffer
, state
, vk_info
);
3397 context_vk
->update_stream_output
= 0;
3400 if (wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_INDEXBUFFER
) && state
->index_buffer
)
3402 const VkDescriptorBufferInfo
*buffer_info
;
3403 VkIndexType idx_type
;
3405 if (state
->index_format
== WINED3DFMT_R16_UINT
)
3406 idx_type
= VK_INDEX_TYPE_UINT16
;
3408 idx_type
= VK_INDEX_TYPE_UINT32
;
3409 buffer_vk
= wined3d_buffer_vk(state
->index_buffer
);
3410 buffer_info
= wined3d_buffer_vk_get_buffer_info(buffer_vk
);
3411 wined3d_context_vk_reference_bo(context_vk
, wined3d_bo_vk(buffer_vk
->b
.buffer_object
));
3412 VK_CALL(vkCmdBindIndexBuffer(vk_command_buffer
, buffer_info
->buffer
,
3413 buffer_info
->offset
+ state
->index_offset
, idx_type
));
3416 if (wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL
))
3417 || wined3d_context_is_graphics_state_dirty(&context_vk
->c
,
3418 STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX
))
3419 || wined3d_context_is_graphics_state_dirty(&context_vk
->c
,
3420 STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_GEOMETRY
))
3421 || wined3d_context_is_graphics_state_dirty(&context_vk
->c
,
3422 STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_HULL
))
3423 || wined3d_context_is_graphics_state_dirty(&context_vk
->c
,
3424 STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_DOMAIN
))
3425 || wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_GRAPHICS_SHADER_RESOURCE_BINDING
))
3426 context_vk
->c
.update_shader_resource_bindings
= 1;
3427 if (wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_GRAPHICS_UNORDERED_ACCESS_VIEW_BINDING
))
3428 context_vk
->c
.update_unordered_access_view_bindings
= 1;
3430 if (context_vk
->c
.update_shader_resource_bindings
|| context_vk
->c
.update_unordered_access_view_bindings
)
3432 if (!wined3d_context_vk_update_descriptors(context_vk
, vk_command_buffer
, state
, WINED3D_PIPELINE_GRAPHICS
))
3434 ERR("Failed to update shader descriptors.\n");
3435 return VK_NULL_HANDLE
;
3438 context_vk
->c
.update_shader_resource_bindings
= 0;
3439 context_vk
->c
.update_unordered_access_view_bindings
= 0;
3442 if (wined3d_context_is_graphics_state_dirty(&context_vk
->c
, STATE_BLEND_FACTOR
))
3443 VK_CALL(vkCmdSetBlendConstants(vk_command_buffer
, &state
->blend_factor
.r
));
3445 memset(context_vk
->c
.dirty_graphics_states
, 0, sizeof(context_vk
->c
.dirty_graphics_states
));
3446 context_vk
->c
.shader_update_mask
&= 1u << WINED3D_SHADER_TYPE_COMPUTE
;
3448 return vk_command_buffer
;
3451 VkCommandBuffer
wined3d_context_vk_apply_compute_state(struct wined3d_context_vk
*context_vk
,
3452 const struct wined3d_state
*state
, struct wined3d_buffer_vk
*indirect_vk
)
3454 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
3455 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
3456 VkCommandBuffer vk_command_buffer
;
3458 wined3d_context_vk_end_current_render_pass(context_vk
);
3460 if (wined3d_context_is_compute_state_dirty(&context_vk
->c
, STATE_COMPUTE_SHADER
))
3461 context_vk
->c
.shader_update_mask
|= 1u << WINED3D_SHADER_TYPE_COMPUTE
;
3463 if (context_vk
->c
.shader_update_mask
& (1u << WINED3D_SHADER_TYPE_COMPUTE
))
3465 device_vk
->d
.shader_backend
->shader_select_compute(device_vk
->d
.shader_priv
, &context_vk
->c
, state
);
3466 if (!context_vk
->compute
.vk_pipeline
)
3468 ERR("No compute pipeline set.\n");
3469 return VK_NULL_HANDLE
;
3471 context_vk
->c
.update_compute_shader_resource_bindings
= 1;
3472 context_vk
->c
.update_compute_unordered_access_view_bindings
= 1;
3473 context_vk
->update_compute_pipeline
= 1;
3476 wined3d_context_vk_load_shader_resources(context_vk
, state
, WINED3D_PIPELINE_COMPUTE
);
3480 wined3d_buffer_load_location(&indirect_vk
->b
, &context_vk
->c
, WINED3D_LOCATION_BUFFER
);
3481 wined3d_buffer_vk_barrier(indirect_vk
, context_vk
, WINED3D_BIND_INDIRECT_BUFFER
);
3484 if (!(vk_command_buffer
= wined3d_context_vk_get_command_buffer(context_vk
)))
3486 ERR("Failed to get command buffer.\n");
3487 return VK_NULL_HANDLE
;
3490 if (context_vk
->update_compute_pipeline
)
3492 VK_CALL(vkCmdBindPipeline(vk_command_buffer
,
3493 VK_PIPELINE_BIND_POINT_COMPUTE
, context_vk
->compute
.vk_pipeline
));
3494 context_vk
->update_compute_pipeline
= 0;
3497 if (wined3d_context_is_compute_state_dirty(&context_vk
->c
, STATE_COMPUTE_CONSTANT_BUFFER
)
3498 || wined3d_context_is_compute_state_dirty(&context_vk
->c
, STATE_COMPUTE_SHADER_RESOURCE_BINDING
))
3499 context_vk
->c
.update_compute_shader_resource_bindings
= 1;
3500 if (wined3d_context_is_compute_state_dirty(&context_vk
->c
, STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING
))
3501 context_vk
->c
.update_compute_unordered_access_view_bindings
= 1;
3503 if (context_vk
->c
.update_compute_shader_resource_bindings
3504 || context_vk
->c
.update_compute_unordered_access_view_bindings
)
3506 if (!wined3d_context_vk_update_descriptors(context_vk
, vk_command_buffer
, state
, WINED3D_PIPELINE_COMPUTE
))
3508 ERR("Failed to update shader descriptors.\n");
3509 return VK_NULL_HANDLE
;
3512 context_vk
->c
.update_compute_shader_resource_bindings
= 0;
3513 context_vk
->c
.update_compute_unordered_access_view_bindings
= 0;
3516 memset(context_vk
->c
.dirty_compute_states
, 0, sizeof(context_vk
->c
.dirty_compute_states
));
3517 context_vk
->c
.shader_update_mask
&= ~(1u << WINED3D_SHADER_TYPE_COMPUTE
);
3519 return vk_command_buffer
;
3522 HRESULT
wined3d_context_vk_init(struct wined3d_context_vk
*context_vk
, struct wined3d_swapchain
*swapchain
)
3524 VkCommandPoolCreateInfo command_pool_info
;
3525 const struct wined3d_vk_info
*vk_info
;
3526 struct wined3d_adapter_vk
*adapter_vk
;
3527 struct wined3d_device_vk
*device_vk
;
3530 TRACE("context_vk %p, swapchain %p.\n", context_vk
, swapchain
);
3532 memset(context_vk
, 0, sizeof(*context_vk
));
3533 wined3d_context_init(&context_vk
->c
, swapchain
);
3534 device_vk
= wined3d_device_vk(swapchain
->device
);
3535 adapter_vk
= wined3d_adapter_vk(device_vk
->d
.adapter
);
3536 context_vk
->vk_info
= vk_info
= &adapter_vk
->vk_info
;
3538 command_pool_info
.sType
= VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO
;
3539 command_pool_info
.pNext
= NULL
;
3540 command_pool_info
.flags
= VK_COMMAND_POOL_CREATE_TRANSIENT_BIT
;
3541 command_pool_info
.queueFamilyIndex
= device_vk
->vk_queue_family_index
;
3542 if ((vr
= VK_CALL(vkCreateCommandPool(device_vk
->vk_device
,
3543 &command_pool_info
, NULL
, &context_vk
->vk_command_pool
))) < 0)
3545 ERR("Failed to create Vulkan command pool, vr %s.\n", wined3d_debug_vkresult(vr
));
3546 wined3d_context_cleanup(&context_vk
->c
);
3549 context_vk
->current_command_buffer
.id
= 1;
3551 wined3d_context_vk_init_graphics_pipeline_key(context_vk
);
3553 list_init(&context_vk
->render_pass_queries
);
3554 list_init(&context_vk
->active_queries
);
3555 list_init(&context_vk
->completed_query_pools
);
3556 list_init(&context_vk
->free_occlusion_query_pools
);
3557 list_init(&context_vk
->free_timestamp_query_pools
);
3558 list_init(&context_vk
->free_pipeline_statistics_query_pools
);
3559 list_init(&context_vk
->free_stream_output_statistics_query_pools
);
3561 wine_rb_init(&context_vk
->render_passes
, wined3d_render_pass_vk_compare
);
3562 wine_rb_init(&context_vk
->pipeline_layouts
, wined3d_pipeline_layout_vk_compare
);
3563 wine_rb_init(&context_vk
->graphics_pipelines
, wined3d_graphics_pipeline_vk_compare
);
3564 wine_rb_init(&context_vk
->bo_slab_available
, wined3d_bo_slab_vk_compare
);