vk/0.132: Add vkDestroyDescriptorSetLayout()
[mesa.git] / src / vulkan / device.c
1 /*
2 * Copyright © 2015 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include <assert.h>
25 #include <stdbool.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29
30 #include "private.h"
31 #include "mesa/main/git_sha1.h"
32
33 static int
34 anv_env_get_int(const char *name)
35 {
36 const char *val = getenv(name);
37
38 if (!val)
39 return 0;
40
41 return strtol(val, NULL, 0);
42 }
43
44 static void
45 anv_physical_device_finish(struct anv_physical_device *device)
46 {
47 if (device->fd >= 0)
48 close(device->fd);
49 }
50
51 static VkResult
52 anv_physical_device_init(struct anv_physical_device *device,
53 struct anv_instance *instance,
54 const char *path)
55 {
56 device->fd = open(path, O_RDWR | O_CLOEXEC);
57 if (device->fd < 0)
58 return vk_error(VK_ERROR_UNAVAILABLE);
59
60 device->instance = instance;
61 device->path = path;
62
63 device->chipset_id = anv_env_get_int("INTEL_DEVID_OVERRIDE");
64 device->no_hw = false;
65 if (device->chipset_id) {
66 /* INTEL_DEVID_OVERRIDE implies INTEL_NO_HW. */
67 device->no_hw = true;
68 } else {
69 device->chipset_id = anv_gem_get_param(device->fd, I915_PARAM_CHIPSET_ID);
70 }
71 if (!device->chipset_id)
72 goto fail;
73
74 device->name = brw_get_device_name(device->chipset_id);
75 device->info = brw_get_device_info(device->chipset_id, -1);
76 if (!device->info)
77 goto fail;
78
79 if (!anv_gem_get_param(device->fd, I915_PARAM_HAS_WAIT_TIMEOUT))
80 goto fail;
81
82 if (!anv_gem_get_param(device->fd, I915_PARAM_HAS_EXECBUF2))
83 goto fail;
84
85 if (!anv_gem_get_param(device->fd, I915_PARAM_HAS_LLC))
86 goto fail;
87
88 if (!anv_gem_get_param(device->fd, I915_PARAM_HAS_EXEC_CONSTANTS))
89 goto fail;
90
91 return VK_SUCCESS;
92
93 fail:
94 anv_physical_device_finish(device);
95 return vk_error(VK_ERROR_UNAVAILABLE);
96 }
97
98 static void *default_alloc(
99 void* pUserData,
100 size_t size,
101 size_t alignment,
102 VkSystemAllocType allocType)
103 {
104 return malloc(size);
105 }
106
107 static void default_free(
108 void* pUserData,
109 void* pMem)
110 {
111 free(pMem);
112 }
113
114 static const VkAllocCallbacks default_alloc_callbacks = {
115 .pUserData = NULL,
116 .pfnAlloc = default_alloc,
117 .pfnFree = default_free
118 };
119
120 VkResult anv_CreateInstance(
121 const VkInstanceCreateInfo* pCreateInfo,
122 VkInstance* pInstance)
123 {
124 struct anv_instance *instance;
125 const VkAllocCallbacks *alloc_callbacks = &default_alloc_callbacks;
126 void *user_data = NULL;
127
128 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO);
129
130 if (pCreateInfo->pAllocCb) {
131 alloc_callbacks = pCreateInfo->pAllocCb;
132 user_data = pCreateInfo->pAllocCb->pUserData;
133 }
134 instance = alloc_callbacks->pfnAlloc(user_data, sizeof(*instance), 8,
135 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
136 if (!instance)
137 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
138
139 instance->pAllocUserData = alloc_callbacks->pUserData;
140 instance->pfnAlloc = alloc_callbacks->pfnAlloc;
141 instance->pfnFree = alloc_callbacks->pfnFree;
142 instance->apiVersion = pCreateInfo->pAppInfo->apiVersion;
143 instance->physicalDeviceCount = 0;
144
145 *pInstance = anv_instance_to_handle(instance);
146
147 return VK_SUCCESS;
148 }
149
150 VkResult anv_DestroyInstance(
151 VkInstance _instance)
152 {
153 ANV_FROM_HANDLE(anv_instance, instance, _instance);
154
155 if (instance->physicalDeviceCount > 0) {
156 anv_physical_device_finish(&instance->physicalDevice);
157 }
158
159 instance->pfnFree(instance->pAllocUserData, instance);
160
161 return VK_SUCCESS;
162 }
163
164 VkResult anv_EnumeratePhysicalDevices(
165 VkInstance _instance,
166 uint32_t* pPhysicalDeviceCount,
167 VkPhysicalDevice* pPhysicalDevices)
168 {
169 ANV_FROM_HANDLE(anv_instance, instance, _instance);
170 VkResult result;
171
172 if (instance->physicalDeviceCount == 0) {
173 result = anv_physical_device_init(&instance->physicalDevice,
174 instance, "/dev/dri/renderD128");
175 if (result != VK_SUCCESS)
176 return result;
177
178 instance->physicalDeviceCount = 1;
179 }
180
181 /* pPhysicalDeviceCount is an out parameter if pPhysicalDevices is NULL;
182 * otherwise it's an inout parameter.
183 *
184 * The Vulkan spec (git aaed022) says:
185 *
186 * pPhysicalDeviceCount is a pointer to an unsigned integer variable
187 * that is initialized with the number of devices the application is
188 * prepared to receive handles to. pname:pPhysicalDevices is pointer to
189 * an array of at least this many VkPhysicalDevice handles [...].
190 *
191 * Upon success, if pPhysicalDevices is NULL, vkEnumeratePhysicalDevices
192 * overwrites the contents of the variable pointed to by
193 * pPhysicalDeviceCount with the number of physical devices in in the
194 * instance; otherwise, vkEnumeratePhysicalDevices overwrites
195 * pPhysicalDeviceCount with the number of physical handles written to
196 * pPhysicalDevices.
197 */
198 if (!pPhysicalDevices) {
199 *pPhysicalDeviceCount = instance->physicalDeviceCount;
200 } else if (*pPhysicalDeviceCount >= 1) {
201 pPhysicalDevices[0] = anv_physical_device_to_handle(&instance->physicalDevice);
202 *pPhysicalDeviceCount = 1;
203 } else {
204 *pPhysicalDeviceCount = 0;
205 }
206
207 return VK_SUCCESS;
208 }
209
210 VkResult anv_GetPhysicalDeviceFeatures(
211 VkPhysicalDevice physicalDevice,
212 VkPhysicalDeviceFeatures* pFeatures)
213 {
214 anv_finishme("Get correct values for PhysicalDeviceFeatures");
215
216 *pFeatures = (VkPhysicalDeviceFeatures) {
217 .robustBufferAccess = false,
218 .fullDrawIndexUint32 = false,
219 .imageCubeArray = false,
220 .independentBlend = false,
221 .geometryShader = true,
222 .tessellationShader = false,
223 .sampleRateShading = false,
224 .dualSourceBlend = true,
225 .logicOp = true,
226 .instancedDrawIndirect = true,
227 .depthClip = false,
228 .depthBiasClamp = false,
229 .fillModeNonSolid = true,
230 .depthBounds = false,
231 .wideLines = true,
232 .largePoints = true,
233 .textureCompressionETC2 = true,
234 .textureCompressionASTC_LDR = true,
235 .textureCompressionBC = true,
236 .pipelineStatisticsQuery = true,
237 .vertexSideEffects = false,
238 .tessellationSideEffects = false,
239 .geometrySideEffects = false,
240 .fragmentSideEffects = false,
241 .shaderTessellationPointSize = false,
242 .shaderGeometryPointSize = true,
243 .shaderTextureGatherExtended = true,
244 .shaderStorageImageExtendedFormats = false,
245 .shaderStorageImageMultisample = false,
246 .shaderStorageBufferArrayConstantIndexing = false,
247 .shaderStorageImageArrayConstantIndexing = false,
248 .shaderUniformBufferArrayDynamicIndexing = true,
249 .shaderSampledImageArrayDynamicIndexing = false,
250 .shaderStorageBufferArrayDynamicIndexing = false,
251 .shaderStorageImageArrayDynamicIndexing = false,
252 .shaderClipDistance = false,
253 .shaderCullDistance = false,
254 .shaderFloat64 = false,
255 .shaderInt64 = false,
256 .shaderFloat16 = false,
257 .shaderInt16 = false,
258 };
259
260 return VK_SUCCESS;
261 }
262
263 VkResult anv_GetPhysicalDeviceLimits(
264 VkPhysicalDevice physicalDevice,
265 VkPhysicalDeviceLimits* pLimits)
266 {
267 ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
268 const struct brw_device_info *devinfo = physical_device->info;
269
270 anv_finishme("Get correct values for PhysicalDeviceLimits");
271
272 *pLimits = (VkPhysicalDeviceLimits) {
273 .maxImageDimension1D = (1 << 14),
274 .maxImageDimension2D = (1 << 14),
275 .maxImageDimension3D = (1 << 10),
276 .maxImageDimensionCube = (1 << 14),
277 .maxImageArrayLayers = (1 << 10),
278 .maxTexelBufferSize = (1 << 14),
279 .maxUniformBufferSize = UINT32_MAX,
280 .maxStorageBufferSize = UINT32_MAX,
281 .maxPushConstantsSize = 128,
282 .maxMemoryAllocationCount = UINT32_MAX,
283 .maxBoundDescriptorSets = MAX_SETS,
284 .maxDescriptorSets = UINT32_MAX,
285 .maxPerStageDescriptorSamplers = 64,
286 .maxPerStageDescriptorUniformBuffers = 64,
287 .maxPerStageDescriptorStorageBuffers = 64,
288 .maxPerStageDescriptorSampledImages = 64,
289 .maxPerStageDescriptorStorageImages = 64,
290 .maxDescriptorSetSamplers = 256,
291 .maxDescriptorSetUniformBuffers = 256,
292 .maxDescriptorSetStorageBuffers = 256,
293 .maxDescriptorSetSampledImages = 256,
294 .maxDescriptorSetStorageImages = 256,
295 .maxVertexInputAttributes = 32,
296 .maxVertexInputAttributeOffset = 256,
297 .maxVertexInputBindingStride = 256,
298 .maxVertexOutputComponents = 32,
299 .maxTessGenLevel = 0,
300 .maxTessPatchSize = 0,
301 .maxTessControlPerVertexInputComponents = 0,
302 .maxTessControlPerVertexOutputComponents = 0,
303 .maxTessControlPerPatchOutputComponents = 0,
304 .maxTessControlTotalOutputComponents = 0,
305 .maxTessEvaluationInputComponents = 0,
306 .maxTessEvaluationOutputComponents = 0,
307 .maxGeometryShaderInvocations = 6,
308 .maxGeometryInputComponents = 16,
309 .maxGeometryOutputComponents = 16,
310 .maxGeometryOutputVertices = 16,
311 .maxGeometryTotalOutputComponents = 16,
312 .maxFragmentInputComponents = 16,
313 .maxFragmentOutputBuffers = 8,
314 .maxFragmentDualSourceBuffers = 2,
315 .maxFragmentCombinedOutputResources = 8,
316 .maxComputeSharedMemorySize = 1024,
317 .maxComputeWorkGroupCount = {
318 16 * devinfo->max_cs_threads,
319 16 * devinfo->max_cs_threads,
320 16 * devinfo->max_cs_threads,
321 },
322 .maxComputeWorkGroupInvocations = 16 * devinfo->max_cs_threads,
323 .maxComputeWorkGroupSize = {
324 16 * devinfo->max_cs_threads,
325 16 * devinfo->max_cs_threads,
326 16 * devinfo->max_cs_threads,
327 },
328 .subPixelPrecisionBits = 4 /* FIXME */,
329 .subTexelPrecisionBits = 4 /* FIXME */,
330 .mipmapPrecisionBits = 4 /* FIXME */,
331 .maxDrawIndexedIndexValue = UINT32_MAX,
332 .maxDrawIndirectInstanceCount = UINT32_MAX,
333 .primitiveRestartForPatches = UINT32_MAX,
334 .maxSamplerLodBias = 16,
335 .maxSamplerAnisotropy = 16,
336 .maxViewports = 16,
337 .maxDynamicViewportStates = UINT32_MAX,
338 .maxViewportDimensions = { (1 << 14), (1 << 14) },
339 .viewportBoundsRange = { -1.0, 1.0 }, /* FIXME */
340 .viewportSubPixelBits = 13, /* We take a float? */
341 .minMemoryMapAlignment = 64, /* A cache line */
342 .minTexelBufferOffsetAlignment = 1,
343 .minUniformBufferOffsetAlignment = 1,
344 .minStorageBufferOffsetAlignment = 1,
345 .minTexelOffset = 0, /* FIXME */
346 .maxTexelOffset = 0, /* FIXME */
347 .minTexelGatherOffset = 0, /* FIXME */
348 .maxTexelGatherOffset = 0, /* FIXME */
349 .minInterpolationOffset = 0, /* FIXME */
350 .maxInterpolationOffset = 0, /* FIXME */
351 .subPixelInterpolationOffsetBits = 0, /* FIXME */
352 .maxFramebufferWidth = (1 << 14),
353 .maxFramebufferHeight = (1 << 14),
354 .maxFramebufferLayers = (1 << 10),
355 .maxFramebufferColorSamples = 8,
356 .maxFramebufferDepthSamples = 8,
357 .maxFramebufferStencilSamples = 8,
358 .maxColorAttachments = MAX_RTS,
359 .maxSampledImageColorSamples = 8,
360 .maxSampledImageDepthSamples = 8,
361 .maxSampledImageIntegerSamples = 1,
362 .maxStorageImageSamples = 1,
363 .maxSampleMaskWords = 1,
364 .timestampFrequency = 1000 * 1000 * 1000 / 80,
365 .maxClipDistances = 0 /* FIXME */,
366 .maxCullDistances = 0 /* FIXME */,
367 .maxCombinedClipAndCullDistances = 0 /* FIXME */,
368 .pointSizeRange = { 0.125, 255.875 },
369 .lineWidthRange = { 0.0, 7.9921875 },
370 .pointSizeGranularity = (1.0 / 8.0),
371 .lineWidthGranularity = (1.0 / 128.0),
372 };
373
374 return VK_SUCCESS;
375 }
376
377 VkResult anv_GetPhysicalDeviceProperties(
378 VkPhysicalDevice physicalDevice,
379 VkPhysicalDeviceProperties* pProperties)
380 {
381 ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice);
382
383 *pProperties = (VkPhysicalDeviceProperties) {
384 .apiVersion = 1,
385 .driverVersion = 1,
386 .vendorId = 0x8086,
387 .deviceId = pdevice->chipset_id,
388 .deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
389 };
390
391 strcpy(pProperties->deviceName, pdevice->name);
392 snprintf((char *)pProperties->pipelineCacheUUID, VK_UUID_LENGTH,
393 "anv-%s", MESA_GIT_SHA1 + 4);
394
395 return VK_SUCCESS;
396 }
397
398 VkResult anv_GetPhysicalDeviceQueueCount(
399 VkPhysicalDevice physicalDevice,
400 uint32_t* pCount)
401 {
402 *pCount = 1;
403
404 return VK_SUCCESS;
405 }
406
407 VkResult anv_GetPhysicalDeviceQueueProperties(
408 VkPhysicalDevice physicalDevice,
409 uint32_t count,
410 VkPhysicalDeviceQueueProperties* pQueueProperties)
411 {
412 assert(count == 1);
413
414 *pQueueProperties = (VkPhysicalDeviceQueueProperties) {
415 .queueFlags = VK_QUEUE_GRAPHICS_BIT |
416 VK_QUEUE_COMPUTE_BIT |
417 VK_QUEUE_DMA_BIT,
418 .queueCount = 1,
419 .supportsTimestamps = true,
420 };
421
422 return VK_SUCCESS;
423 }
424
425 VkResult anv_GetPhysicalDeviceMemoryProperties(
426 VkPhysicalDevice physicalDevice,
427 VkPhysicalDeviceMemoryProperties* pMemoryProperties)
428 {
429 ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
430
431 size_t aperture_size;
432 size_t heap_size;
433
434 if (anv_gem_get_aperture(physical_device, &aperture_size) == -1)
435 return vk_error(VK_ERROR_UNAVAILABLE);
436
437 /* Reserve some wiggle room for the driver by exposing only 75% of the
438 * aperture to the heap.
439 */
440 heap_size = 3 * aperture_size / 4;
441
442 /* The property flags below are valid only for llc platforms. */
443 pMemoryProperties->memoryTypeCount = 1;
444 pMemoryProperties->memoryTypes[0] = (VkMemoryType) {
445 .propertyFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
446 .heapIndex = 1,
447 };
448
449 pMemoryProperties->memoryHeapCount = 1;
450 pMemoryProperties->memoryHeaps[0] = (VkMemoryHeap) {
451 .size = heap_size,
452 .flags = VK_MEMORY_HEAP_HOST_LOCAL,
453 };
454
455 return VK_SUCCESS;
456 }
457
458 PFN_vkVoidFunction anv_GetInstanceProcAddr(
459 VkInstance instance,
460 const char* pName)
461 {
462 return anv_lookup_entrypoint(pName);
463 }
464
465 PFN_vkVoidFunction anv_GetDeviceProcAddr(
466 VkDevice device,
467 const char* pName)
468 {
469 return anv_lookup_entrypoint(pName);
470 }
471
472 static void
473 parse_debug_flags(struct anv_device *device)
474 {
475 const char *debug, *p, *end;
476
477 debug = getenv("INTEL_DEBUG");
478 device->dump_aub = false;
479 if (debug) {
480 for (p = debug; *p; p = end + 1) {
481 end = strchrnul(p, ',');
482 if (end - p == 3 && memcmp(p, "aub", 3) == 0)
483 device->dump_aub = true;
484 if (end - p == 5 && memcmp(p, "no_hw", 5) == 0)
485 device->no_hw = true;
486 if (*end == '\0')
487 break;
488 }
489 }
490 }
491
492 static VkResult
493 anv_queue_init(struct anv_device *device, struct anv_queue *queue)
494 {
495 queue->device = device;
496 queue->pool = &device->surface_state_pool;
497
498 queue->completed_serial = anv_state_pool_alloc(queue->pool, 4, 4);
499 if (queue->completed_serial.map == NULL)
500 return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY);
501
502 *(uint32_t *)queue->completed_serial.map = 0;
503 queue->next_serial = 1;
504
505 return VK_SUCCESS;
506 }
507
508 static void
509 anv_queue_finish(struct anv_queue *queue)
510 {
511 #ifdef HAVE_VALGRIND
512 /* This gets torn down with the device so we only need to do this if
513 * valgrind is present.
514 */
515 anv_state_pool_free(queue->pool, queue->completed_serial);
516 #endif
517 }
518
519 static void
520 anv_device_init_border_colors(struct anv_device *device)
521 {
522 static const VkClearColorValue border_colors[] = {
523 [VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK] = { .f32 = { 0.0, 0.0, 0.0, 0.0 } },
524 [VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK] = { .f32 = { 0.0, 0.0, 0.0, 1.0 } },
525 [VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE] = { .f32 = { 1.0, 1.0, 1.0, 1.0 } },
526 [VK_BORDER_COLOR_INT_TRANSPARENT_BLACK] = { .u32 = { 0, 0, 0, 0 } },
527 [VK_BORDER_COLOR_INT_OPAQUE_BLACK] = { .u32 = { 0, 0, 0, 1 } },
528 [VK_BORDER_COLOR_INT_OPAQUE_WHITE] = { .u32 = { 1, 1, 1, 1 } },
529 };
530
531 device->border_colors =
532 anv_state_pool_alloc(&device->dynamic_state_pool,
533 sizeof(border_colors), 32);
534 memcpy(device->border_colors.map, border_colors, sizeof(border_colors));
535 }
536
537 static const uint32_t BATCH_SIZE = 8192;
538
539 VkResult anv_CreateDevice(
540 VkPhysicalDevice physicalDevice,
541 const VkDeviceCreateInfo* pCreateInfo,
542 VkDevice* pDevice)
543 {
544 ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
545 struct anv_instance *instance = physical_device->instance;
546 struct anv_device *device;
547
548 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO);
549
550 device = instance->pfnAlloc(instance->pAllocUserData,
551 sizeof(*device), 8,
552 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
553 if (!device)
554 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
555
556 device->no_hw = physical_device->no_hw;
557 parse_debug_flags(device);
558
559 device->instance = physical_device->instance;
560
561 /* XXX(chadv): Can we dup() physicalDevice->fd here? */
562 device->fd = open(physical_device->path, O_RDWR | O_CLOEXEC);
563 if (device->fd == -1)
564 goto fail_device;
565
566 device->context_id = anv_gem_create_context(device);
567 if (device->context_id == -1)
568 goto fail_fd;
569
570 anv_bo_pool_init(&device->batch_bo_pool, device, BATCH_SIZE);
571
572 anv_block_pool_init(&device->dynamic_state_block_pool, device, 2048);
573
574 anv_state_pool_init(&device->dynamic_state_pool,
575 &device->dynamic_state_block_pool);
576
577 anv_block_pool_init(&device->instruction_block_pool, device, 2048);
578 anv_block_pool_init(&device->surface_state_block_pool, device, 2048);
579
580 anv_state_pool_init(&device->surface_state_pool,
581 &device->surface_state_block_pool);
582
583 anv_block_pool_init(&device->scratch_block_pool, device, 0x10000);
584
585 device->info = *physical_device->info;
586
587 device->compiler = anv_compiler_create(device);
588 device->aub_writer = NULL;
589
590 pthread_mutex_init(&device->mutex, NULL);
591
592 anv_queue_init(device, &device->queue);
593
594 anv_device_init_meta(device);
595
596 anv_device_init_border_colors(device);
597
598 *pDevice = anv_device_to_handle(device);
599
600 return VK_SUCCESS;
601
602 fail_fd:
603 close(device->fd);
604 fail_device:
605 anv_device_free(device, device);
606
607 return vk_error(VK_ERROR_UNAVAILABLE);
608 }
609
610 VkResult anv_DestroyDevice(
611 VkDevice _device)
612 {
613 ANV_FROM_HANDLE(anv_device, device, _device);
614
615 anv_compiler_destroy(device->compiler);
616
617 anv_queue_finish(&device->queue);
618
619 anv_device_finish_meta(device);
620
621 #ifdef HAVE_VALGRIND
622 /* We only need to free these to prevent valgrind errors. The backing
623 * BO will go away in a couple of lines so we don't actually leak.
624 */
625 anv_state_pool_free(&device->dynamic_state_pool, device->border_colors);
626 #endif
627
628 anv_bo_pool_finish(&device->batch_bo_pool);
629 anv_block_pool_finish(&device->dynamic_state_block_pool);
630 anv_block_pool_finish(&device->instruction_block_pool);
631 anv_block_pool_finish(&device->surface_state_block_pool);
632
633 close(device->fd);
634
635 if (device->aub_writer)
636 anv_aub_writer_destroy(device->aub_writer);
637
638 anv_device_free(device, device);
639
640 return VK_SUCCESS;
641 }
642
643 static const VkExtensionProperties global_extensions[] = {
644 {
645 .extName = "VK_WSI_LunarG",
646 .version = 3
647 }
648 };
649
650 VkResult anv_GetGlobalExtensionCount(
651 uint32_t* pCount)
652 {
653 *pCount = ARRAY_SIZE(global_extensions);
654
655 return VK_SUCCESS;
656 }
657
658
659 VkResult anv_GetGlobalExtensionProperties(
660 uint32_t extensionIndex,
661 VkExtensionProperties* pProperties)
662 {
663 assert(extensionIndex < ARRAY_SIZE(global_extensions));
664
665 *pProperties = global_extensions[extensionIndex];
666
667 return VK_SUCCESS;
668 }
669
670 VkResult anv_GetPhysicalDeviceExtensionCount(
671 VkPhysicalDevice physicalDevice,
672 uint32_t* pCount)
673 {
674 /* None supported at this time */
675 *pCount = 0;
676
677 return VK_SUCCESS;
678 }
679
680 VkResult anv_GetPhysicalDeviceExtensionProperties(
681 VkPhysicalDevice physicalDevice,
682 uint32_t extensionIndex,
683 VkExtensionProperties* pProperties)
684 {
685 /* None supported at this time */
686 return vk_error(VK_ERROR_INVALID_EXTENSION);
687 }
688
689 VkResult anv_EnumerateLayers(
690 VkPhysicalDevice physicalDevice,
691 size_t maxStringSize,
692 size_t* pLayerCount,
693 char* const* pOutLayers,
694 void* pReserved)
695 {
696 *pLayerCount = 0;
697
698 return VK_SUCCESS;
699 }
700
701 VkResult anv_GetDeviceQueue(
702 VkDevice _device,
703 uint32_t queueNodeIndex,
704 uint32_t queueIndex,
705 VkQueue* pQueue)
706 {
707 ANV_FROM_HANDLE(anv_device, device, _device);
708
709 assert(queueIndex == 0);
710
711 *pQueue = anv_queue_to_handle(&device->queue);
712
713 return VK_SUCCESS;
714 }
715
716 VkResult
717 anv_reloc_list_init(struct anv_reloc_list *list, struct anv_device *device)
718 {
719 list->num_relocs = 0;
720 list->array_length = 256;
721 list->relocs =
722 anv_device_alloc(device, list->array_length * sizeof(*list->relocs), 8,
723 VK_SYSTEM_ALLOC_TYPE_INTERNAL);
724
725 if (list->relocs == NULL)
726 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
727
728 list->reloc_bos =
729 anv_device_alloc(device, list->array_length * sizeof(*list->reloc_bos), 8,
730 VK_SYSTEM_ALLOC_TYPE_INTERNAL);
731
732 if (list->relocs == NULL) {
733 anv_device_free(device, list->relocs);
734 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
735 }
736
737 return VK_SUCCESS;
738 }
739
740 void
741 anv_reloc_list_finish(struct anv_reloc_list *list, struct anv_device *device)
742 {
743 anv_device_free(device, list->relocs);
744 anv_device_free(device, list->reloc_bos);
745 }
746
747 static VkResult
748 anv_reloc_list_grow(struct anv_reloc_list *list, struct anv_device *device,
749 size_t num_additional_relocs)
750 {
751 if (list->num_relocs + num_additional_relocs <= list->array_length)
752 return VK_SUCCESS;
753
754 size_t new_length = list->array_length * 2;
755 while (new_length < list->num_relocs + num_additional_relocs)
756 new_length *= 2;
757
758 struct drm_i915_gem_relocation_entry *new_relocs =
759 anv_device_alloc(device, new_length * sizeof(*list->relocs), 8,
760 VK_SYSTEM_ALLOC_TYPE_INTERNAL);
761 if (new_relocs == NULL)
762 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
763
764 struct anv_bo **new_reloc_bos =
765 anv_device_alloc(device, new_length * sizeof(*list->reloc_bos), 8,
766 VK_SYSTEM_ALLOC_TYPE_INTERNAL);
767 if (new_relocs == NULL) {
768 anv_device_free(device, new_relocs);
769 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
770 }
771
772 memcpy(new_relocs, list->relocs, list->num_relocs * sizeof(*list->relocs));
773 memcpy(new_reloc_bos, list->reloc_bos,
774 list->num_relocs * sizeof(*list->reloc_bos));
775
776 anv_device_free(device, list->relocs);
777 anv_device_free(device, list->reloc_bos);
778
779 list->relocs = new_relocs;
780 list->reloc_bos = new_reloc_bos;
781
782 return VK_SUCCESS;
783 }
784
785 static VkResult
786 anv_batch_bo_create(struct anv_device *device, struct anv_batch_bo **bbo_out)
787 {
788 VkResult result;
789
790 struct anv_batch_bo *bbo =
791 anv_device_alloc(device, sizeof(*bbo), 8, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
792 if (bbo == NULL)
793 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
794
795 bbo->num_relocs = 0;
796 bbo->prev_batch_bo = NULL;
797
798 result = anv_bo_pool_alloc(&device->batch_bo_pool, &bbo->bo);
799 if (result != VK_SUCCESS) {
800 anv_device_free(device, bbo);
801 return result;
802 }
803
804 *bbo_out = bbo;
805
806 return VK_SUCCESS;
807 }
808
809 static void
810 anv_batch_bo_start(struct anv_batch_bo *bbo, struct anv_batch *batch,
811 size_t batch_padding)
812 {
813 batch->next = batch->start = bbo->bo.map;
814 batch->end = bbo->bo.map + bbo->bo.size - batch_padding;
815 bbo->first_reloc = batch->relocs.num_relocs;
816 }
817
818 static void
819 anv_batch_bo_finish(struct anv_batch_bo *bbo, struct anv_batch *batch)
820 {
821 assert(batch->start == bbo->bo.map);
822 bbo->length = batch->next - batch->start;
823 VG(VALGRIND_CHECK_MEM_IS_DEFINED(batch->start, bbo->length));
824 bbo->num_relocs = batch->relocs.num_relocs - bbo->first_reloc;
825 }
826
827 static void
828 anv_batch_bo_destroy(struct anv_batch_bo *bbo, struct anv_device *device)
829 {
830 anv_bo_pool_free(&device->batch_bo_pool, &bbo->bo);
831 anv_device_free(device, bbo);
832 }
833
834 void *
835 anv_batch_emit_dwords(struct anv_batch *batch, int num_dwords)
836 {
837 if (batch->next + num_dwords * 4 > batch->end)
838 batch->extend_cb(batch, batch->user_data);
839
840 void *p = batch->next;
841
842 batch->next += num_dwords * 4;
843 assert(batch->next <= batch->end);
844
845 return p;
846 }
847
848 static void
849 anv_reloc_list_append(struct anv_reloc_list *list, struct anv_device *device,
850 struct anv_reloc_list *other, uint32_t offset)
851 {
852 anv_reloc_list_grow(list, device, other->num_relocs);
853 /* TODO: Handle failure */
854
855 memcpy(&list->relocs[list->num_relocs], &other->relocs[0],
856 other->num_relocs * sizeof(other->relocs[0]));
857 memcpy(&list->reloc_bos[list->num_relocs], &other->reloc_bos[0],
858 other->num_relocs * sizeof(other->reloc_bos[0]));
859
860 for (uint32_t i = 0; i < other->num_relocs; i++)
861 list->relocs[i + list->num_relocs].offset += offset;
862
863 list->num_relocs += other->num_relocs;
864 }
865
866 static uint64_t
867 anv_reloc_list_add(struct anv_reloc_list *list, struct anv_device *device,
868 uint32_t offset, struct anv_bo *target_bo, uint32_t delta)
869 {
870 struct drm_i915_gem_relocation_entry *entry;
871 int index;
872
873 anv_reloc_list_grow(list, device, 1);
874 /* TODO: Handle failure */
875
876 /* XXX: Can we use I915_EXEC_HANDLE_LUT? */
877 index = list->num_relocs++;
878 list->reloc_bos[index] = target_bo;
879 entry = &list->relocs[index];
880 entry->target_handle = target_bo->gem_handle;
881 entry->delta = delta;
882 entry->offset = offset;
883 entry->presumed_offset = target_bo->offset;
884 entry->read_domains = 0;
885 entry->write_domain = 0;
886
887 return target_bo->offset + delta;
888 }
889
890 void
891 anv_batch_emit_batch(struct anv_batch *batch, struct anv_batch *other)
892 {
893 uint32_t size, offset;
894
895 size = other->next - other->start;
896 assert(size % 4 == 0);
897
898 if (batch->next + size > batch->end)
899 batch->extend_cb(batch, batch->user_data);
900
901 assert(batch->next + size <= batch->end);
902
903 memcpy(batch->next, other->start, size);
904
905 offset = batch->next - batch->start;
906 anv_reloc_list_append(&batch->relocs, batch->device,
907 &other->relocs, offset);
908
909 batch->next += size;
910 }
911
912 uint64_t
913 anv_batch_emit_reloc(struct anv_batch *batch,
914 void *location, struct anv_bo *bo, uint32_t delta)
915 {
916 return anv_reloc_list_add(&batch->relocs, batch->device,
917 location - batch->start, bo, delta);
918 }
919
920 VkResult anv_QueueSubmit(
921 VkQueue _queue,
922 uint32_t cmdBufferCount,
923 const VkCmdBuffer* pCmdBuffers,
924 VkFence _fence)
925 {
926 ANV_FROM_HANDLE(anv_queue, queue, _queue);
927 ANV_FROM_HANDLE(anv_fence, fence, _fence);
928 struct anv_device *device = queue->device;
929 int ret;
930
931 for (uint32_t i = 0; i < cmdBufferCount; i++) {
932 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, pCmdBuffers[i]);
933
934 if (device->dump_aub)
935 anv_cmd_buffer_dump(cmd_buffer);
936
937 if (!device->no_hw) {
938 ret = anv_gem_execbuffer(device, &cmd_buffer->execbuf);
939 if (ret != 0)
940 return vk_error(VK_ERROR_UNKNOWN);
941
942 if (fence) {
943 ret = anv_gem_execbuffer(device, &fence->execbuf);
944 if (ret != 0)
945 return vk_error(VK_ERROR_UNKNOWN);
946 }
947
948 for (uint32_t i = 0; i < cmd_buffer->bo_count; i++)
949 cmd_buffer->exec2_bos[i]->offset = cmd_buffer->exec2_objects[i].offset;
950 } else {
951 *(uint32_t *)queue->completed_serial.map = cmd_buffer->serial;
952 }
953 }
954
955 return VK_SUCCESS;
956 }
957
958 VkResult anv_QueueWaitIdle(
959 VkQueue _queue)
960 {
961 ANV_FROM_HANDLE(anv_queue, queue, _queue);
962
963 return vkDeviceWaitIdle(anv_device_to_handle(queue->device));
964 }
965
966 VkResult anv_DeviceWaitIdle(
967 VkDevice _device)
968 {
969 ANV_FROM_HANDLE(anv_device, device, _device);
970 struct anv_state state;
971 struct anv_batch batch;
972 struct drm_i915_gem_execbuffer2 execbuf;
973 struct drm_i915_gem_exec_object2 exec2_objects[1];
974 struct anv_bo *bo = NULL;
975 VkResult result;
976 int64_t timeout;
977 int ret;
978
979 state = anv_state_pool_alloc(&device->dynamic_state_pool, 32, 32);
980 bo = &device->dynamic_state_pool.block_pool->bo;
981 batch.start = batch.next = state.map;
982 batch.end = state.map + 32;
983 anv_batch_emit(&batch, GEN8_MI_BATCH_BUFFER_END);
984 anv_batch_emit(&batch, GEN8_MI_NOOP);
985
986 exec2_objects[0].handle = bo->gem_handle;
987 exec2_objects[0].relocation_count = 0;
988 exec2_objects[0].relocs_ptr = 0;
989 exec2_objects[0].alignment = 0;
990 exec2_objects[0].offset = bo->offset;
991 exec2_objects[0].flags = 0;
992 exec2_objects[0].rsvd1 = 0;
993 exec2_objects[0].rsvd2 = 0;
994
995 execbuf.buffers_ptr = (uintptr_t) exec2_objects;
996 execbuf.buffer_count = 1;
997 execbuf.batch_start_offset = state.offset;
998 execbuf.batch_len = batch.next - state.map;
999 execbuf.cliprects_ptr = 0;
1000 execbuf.num_cliprects = 0;
1001 execbuf.DR1 = 0;
1002 execbuf.DR4 = 0;
1003
1004 execbuf.flags =
1005 I915_EXEC_HANDLE_LUT | I915_EXEC_NO_RELOC | I915_EXEC_RENDER;
1006 execbuf.rsvd1 = device->context_id;
1007 execbuf.rsvd2 = 0;
1008
1009 if (!device->no_hw) {
1010 ret = anv_gem_execbuffer(device, &execbuf);
1011 if (ret != 0) {
1012 result = vk_error(VK_ERROR_UNKNOWN);
1013 goto fail;
1014 }
1015
1016 timeout = INT64_MAX;
1017 ret = anv_gem_wait(device, bo->gem_handle, &timeout);
1018 if (ret != 0) {
1019 result = vk_error(VK_ERROR_UNKNOWN);
1020 goto fail;
1021 }
1022 }
1023
1024 anv_state_pool_free(&device->dynamic_state_pool, state);
1025
1026 return VK_SUCCESS;
1027
1028 fail:
1029 anv_state_pool_free(&device->dynamic_state_pool, state);
1030
1031 return result;
1032 }
1033
1034 void *
1035 anv_device_alloc(struct anv_device * device,
1036 size_t size,
1037 size_t alignment,
1038 VkSystemAllocType allocType)
1039 {
1040 return device->instance->pfnAlloc(device->instance->pAllocUserData,
1041 size,
1042 alignment,
1043 allocType);
1044 }
1045
1046 void
1047 anv_device_free(struct anv_device * device,
1048 void * mem)
1049 {
1050 return device->instance->pfnFree(device->instance->pAllocUserData,
1051 mem);
1052 }
1053
1054 VkResult
1055 anv_bo_init_new(struct anv_bo *bo, struct anv_device *device, uint64_t size)
1056 {
1057 bo->gem_handle = anv_gem_create(device, size);
1058 if (!bo->gem_handle)
1059 return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY);
1060
1061 bo->map = NULL;
1062 bo->index = 0;
1063 bo->offset = 0;
1064 bo->size = size;
1065
1066 return VK_SUCCESS;
1067 }
1068
1069 VkResult anv_AllocMemory(
1070 VkDevice _device,
1071 const VkMemoryAllocInfo* pAllocInfo,
1072 VkDeviceMemory* pMem)
1073 {
1074 ANV_FROM_HANDLE(anv_device, device, _device);
1075 struct anv_device_memory *mem;
1076 VkResult result;
1077
1078 assert(pAllocInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO);
1079
1080 if (pAllocInfo->memoryTypeIndex != 0) {
1081 /* We support exactly one memory heap. */
1082 return vk_error(VK_ERROR_INVALID_VALUE);
1083 }
1084
1085 /* FINISHME: Fail if allocation request exceeds heap size. */
1086
1087 mem = anv_device_alloc(device, sizeof(*mem), 8,
1088 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1089 if (mem == NULL)
1090 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1091
1092 result = anv_bo_init_new(&mem->bo, device, pAllocInfo->allocationSize);
1093 if (result != VK_SUCCESS)
1094 goto fail;
1095
1096 *pMem = anv_device_memory_to_handle(mem);
1097
1098 return VK_SUCCESS;
1099
1100 fail:
1101 anv_device_free(device, mem);
1102
1103 return result;
1104 }
1105
1106 VkResult anv_FreeMemory(
1107 VkDevice _device,
1108 VkDeviceMemory _mem)
1109 {
1110 ANV_FROM_HANDLE(anv_device, device, _device);
1111 ANV_FROM_HANDLE(anv_device_memory, mem, _mem);
1112
1113 if (mem->bo.map)
1114 anv_gem_munmap(mem->bo.map, mem->bo.size);
1115
1116 if (mem->bo.gem_handle != 0)
1117 anv_gem_close(device, mem->bo.gem_handle);
1118
1119 anv_device_free(device, mem);
1120
1121 return VK_SUCCESS;
1122 }
1123
1124 VkResult anv_MapMemory(
1125 VkDevice _device,
1126 VkDeviceMemory _mem,
1127 VkDeviceSize offset,
1128 VkDeviceSize size,
1129 VkMemoryMapFlags flags,
1130 void** ppData)
1131 {
1132 ANV_FROM_HANDLE(anv_device, device, _device);
1133 ANV_FROM_HANDLE(anv_device_memory, mem, _mem);
1134
1135 /* FIXME: Is this supposed to be thread safe? Since vkUnmapMemory() only
1136 * takes a VkDeviceMemory pointer, it seems like only one map of the memory
1137 * at a time is valid. We could just mmap up front and return an offset
1138 * pointer here, but that may exhaust virtual memory on 32 bit
1139 * userspace. */
1140
1141 mem->map = anv_gem_mmap(device, mem->bo.gem_handle, offset, size);
1142 mem->map_size = size;
1143
1144 *ppData = mem->map;
1145
1146 return VK_SUCCESS;
1147 }
1148
1149 VkResult anv_UnmapMemory(
1150 VkDevice _device,
1151 VkDeviceMemory _mem)
1152 {
1153 ANV_FROM_HANDLE(anv_device_memory, mem, _mem);
1154
1155 anv_gem_munmap(mem->map, mem->map_size);
1156
1157 return VK_SUCCESS;
1158 }
1159
1160 VkResult anv_FlushMappedMemoryRanges(
1161 VkDevice device,
1162 uint32_t memRangeCount,
1163 const VkMappedMemoryRange* pMemRanges)
1164 {
1165 /* clflush here for !llc platforms */
1166
1167 return VK_SUCCESS;
1168 }
1169
1170 VkResult anv_InvalidateMappedMemoryRanges(
1171 VkDevice device,
1172 uint32_t memRangeCount,
1173 const VkMappedMemoryRange* pMemRanges)
1174 {
1175 return anv_FlushMappedMemoryRanges(device, memRangeCount, pMemRanges);
1176 }
1177
1178 VkResult anv_DestroyObject(
1179 VkDevice _device,
1180 VkObjectType objType,
1181 VkObject _object)
1182 {
1183 ANV_FROM_HANDLE(anv_device, device, _device);
1184 struct anv_object *object = (struct anv_object *) _object;
1185
1186 switch (objType) {
1187 case VK_OBJECT_TYPE_FENCE:
1188 return anv_DestroyFence(_device, (VkFence) _object);
1189
1190 case VK_OBJECT_TYPE_INSTANCE:
1191 return anv_DestroyInstance((VkInstance) _object);
1192
1193 case VK_OBJECT_TYPE_PHYSICAL_DEVICE:
1194 /* We don't want to actually destroy physical devices */
1195 return VK_SUCCESS;
1196
1197 case VK_OBJECT_TYPE_DEVICE:
1198 assert(_device == (VkDevice) _object);
1199 return anv_DestroyDevice((VkDevice) _object);
1200
1201 case VK_OBJECT_TYPE_QUEUE:
1202 /* TODO */
1203 return VK_SUCCESS;
1204
1205 case VK_OBJECT_TYPE_DEVICE_MEMORY:
1206 return anv_FreeMemory(_device, (VkDeviceMemory) _object);
1207
1208 case VK_OBJECT_TYPE_DESCRIPTOR_POOL:
1209 /* These are just dummys anyway, so we don't need to destroy them */
1210 return VK_SUCCESS;
1211
1212 case VK_OBJECT_TYPE_PIPELINE_CACHE:
1213 return anv_DestroyPipelineCache(_device, (VkPipelineCache) _object);
1214
1215 case VK_OBJECT_TYPE_BUFFER_VIEW:
1216 return anv_DestroyBufferView(_device, _object);
1217
1218 case VK_OBJECT_TYPE_IMAGE_VIEW:
1219 return anv_DestroyImageView(_device, _object);
1220
1221 case VK_OBJECT_TYPE_COLOR_ATTACHMENT_VIEW:
1222 return anv_DestroyColorAttachmentView(_device, _object);
1223
1224 case VK_OBJECT_TYPE_DEPTH_STENCIL_VIEW:
1225 return anv_DestroyDepthStencilView(_device, _object);
1226
1227 case VK_OBJECT_TYPE_IMAGE:
1228 return anv_DestroyImage(_device, _object);
1229
1230 case VK_OBJECT_TYPE_BUFFER:
1231 return anv_DestroyBuffer(_device, (VkBuffer) _object);
1232
1233 case VK_OBJECT_TYPE_SHADER_MODULE:
1234 return anv_DestroyShaderModule(_device, (VkShaderModule) _object);
1235
1236 case VK_OBJECT_TYPE_SHADER:
1237 return anv_DestroyShader(_device, (VkShader) _object);
1238
1239 case VK_OBJECT_TYPE_PIPELINE_LAYOUT:
1240 return anv_DestroyPipelineLayout(_device, (VkPipelineLayout) _object);
1241
1242 case VK_OBJECT_TYPE_SAMPLER:
1243 return anv_DestroySampler(_device, (VkSampler) _object);
1244
1245 case VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT:
1246 return anv_DestroyDescriptorSetLayout(_device, (VkDescriptorSetLayout) _object);
1247
1248 case VK_OBJECT_TYPE_DESCRIPTOR_SET:
1249 case VK_OBJECT_TYPE_DYNAMIC_RS_STATE:
1250 case VK_OBJECT_TYPE_DYNAMIC_CB_STATE:
1251 case VK_OBJECT_TYPE_DYNAMIC_DS_STATE:
1252 case VK_OBJECT_TYPE_RENDER_PASS:
1253 /* These are trivially destroyable */
1254 anv_device_free(device, (void *) _object);
1255 return VK_SUCCESS;
1256
1257 case VK_OBJECT_TYPE_COMMAND_BUFFER:
1258 case VK_OBJECT_TYPE_DYNAMIC_VP_STATE:
1259 case VK_OBJECT_TYPE_FRAMEBUFFER:
1260 (object->destructor)(device, object, objType);
1261 return VK_SUCCESS;
1262
1263 case VK_OBJECT_TYPE_PIPELINE:
1264 return anv_DestroyPipeline(_device, (VkPipeline) _object);
1265
1266 case VK_OBJECT_TYPE_QUERY_POOL:
1267 return anv_DestroyQueryPool(_device, (VkQueryPool) _object);
1268
1269 case VK_OBJECT_TYPE_SEMAPHORE:
1270 return anv_DestroySemaphore(_device, (VkSemaphore) _object);
1271
1272 case VK_OBJECT_TYPE_EVENT:
1273 return anv_DestroyEvent(_device, (VkEvent) _object);
1274
1275 default:
1276 unreachable("Invalid object type");
1277 }
1278 }
1279
1280 VkResult anv_GetObjectMemoryRequirements(
1281 VkDevice device,
1282 VkObjectType objType,
1283 VkObject object,
1284 VkMemoryRequirements* pMemoryRequirements)
1285 {
1286
1287 /* The Vulkan spec (git aaed022) says:
1288 *
1289 * memoryTypeBits is a bitfield and contains one bit set for every
1290 * supported memory type for the resource. The bit `1<<i` is set if and
1291 * only if the memory type `i` in the VkPhysicalDeviceMemoryProperties
1292 * structure for the physical device is supported.
1293 *
1294 * We support exactly one memory type.
1295 */
1296 pMemoryRequirements->memoryTypeBits = 1;
1297
1298 switch (objType) {
1299 case VK_OBJECT_TYPE_BUFFER: {
1300 struct anv_buffer *buffer = anv_buffer_from_handle(object);
1301 pMemoryRequirements->size = buffer->size;
1302 pMemoryRequirements->alignment = 16;
1303 break;
1304 }
1305 case VK_OBJECT_TYPE_IMAGE: {
1306 struct anv_image *image = anv_image_from_handle(object);
1307 pMemoryRequirements->size = image->size;
1308 pMemoryRequirements->alignment = image->alignment;
1309 break;
1310 }
1311 default:
1312 pMemoryRequirements->size = 0;
1313 break;
1314 }
1315
1316 return VK_SUCCESS;
1317 }
1318
1319 VkResult anv_BindObjectMemory(
1320 VkDevice device,
1321 VkObjectType objType,
1322 VkObject object,
1323 VkDeviceMemory _mem,
1324 VkDeviceSize memOffset)
1325 {
1326 ANV_FROM_HANDLE(anv_device_memory, mem, _mem);
1327 struct anv_buffer *buffer;
1328 struct anv_image *image;
1329
1330 switch (objType) {
1331 case VK_OBJECT_TYPE_BUFFER:
1332 buffer = anv_buffer_from_handle(object);
1333 buffer->bo = &mem->bo;
1334 buffer->offset = memOffset;
1335 break;
1336 case VK_OBJECT_TYPE_IMAGE:
1337 image = anv_image_from_handle(object);
1338 image->bo = &mem->bo;
1339 image->offset = memOffset;
1340 break;
1341 default:
1342 break;
1343 }
1344
1345 return VK_SUCCESS;
1346 }
1347
1348 VkResult anv_QueueBindSparseBufferMemory(
1349 VkQueue queue,
1350 VkBuffer buffer,
1351 VkDeviceSize rangeOffset,
1352 VkDeviceSize rangeSize,
1353 VkDeviceMemory mem,
1354 VkDeviceSize memOffset)
1355 {
1356 stub_return(VK_UNSUPPORTED);
1357 }
1358
1359 VkResult anv_QueueBindSparseImageMemory(
1360 VkQueue queue,
1361 VkImage image,
1362 const VkImageMemoryBindInfo* pBindInfo,
1363 VkDeviceMemory mem,
1364 VkDeviceSize memOffset)
1365 {
1366 stub_return(VK_UNSUPPORTED);
1367 }
1368
1369 static void
1370 anv_fence_destroy(struct anv_device *device,
1371 struct anv_object *object,
1372 VkObjectType obj_type)
1373 {
1374 struct anv_fence *fence = (struct anv_fence *) object;
1375
1376 assert(obj_type == VK_OBJECT_TYPE_FENCE);
1377
1378 anv_DestroyFence(anv_device_to_handle(device),
1379 anv_fence_to_handle(fence));
1380 }
1381
1382 VkResult anv_CreateFence(
1383 VkDevice _device,
1384 const VkFenceCreateInfo* pCreateInfo,
1385 VkFence* pFence)
1386 {
1387 ANV_FROM_HANDLE(anv_device, device, _device);
1388 struct anv_fence *fence;
1389 struct anv_batch batch;
1390 VkResult result;
1391
1392 const uint32_t fence_size = 128;
1393
1394 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FENCE_CREATE_INFO);
1395
1396 fence = anv_device_alloc(device, sizeof(*fence), 8,
1397 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1398 if (fence == NULL)
1399 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1400
1401 result = anv_bo_init_new(&fence->bo, device, fence_size);
1402 if (result != VK_SUCCESS)
1403 goto fail;
1404
1405 fence->base.destructor = anv_fence_destroy;
1406
1407 fence->bo.map =
1408 anv_gem_mmap(device, fence->bo.gem_handle, 0, fence->bo.size);
1409 batch.next = batch.start = fence->bo.map;
1410 batch.end = fence->bo.map + fence->bo.size;
1411 anv_batch_emit(&batch, GEN8_MI_BATCH_BUFFER_END);
1412 anv_batch_emit(&batch, GEN8_MI_NOOP);
1413
1414 fence->exec2_objects[0].handle = fence->bo.gem_handle;
1415 fence->exec2_objects[0].relocation_count = 0;
1416 fence->exec2_objects[0].relocs_ptr = 0;
1417 fence->exec2_objects[0].alignment = 0;
1418 fence->exec2_objects[0].offset = fence->bo.offset;
1419 fence->exec2_objects[0].flags = 0;
1420 fence->exec2_objects[0].rsvd1 = 0;
1421 fence->exec2_objects[0].rsvd2 = 0;
1422
1423 fence->execbuf.buffers_ptr = (uintptr_t) fence->exec2_objects;
1424 fence->execbuf.buffer_count = 1;
1425 fence->execbuf.batch_start_offset = 0;
1426 fence->execbuf.batch_len = batch.next - fence->bo.map;
1427 fence->execbuf.cliprects_ptr = 0;
1428 fence->execbuf.num_cliprects = 0;
1429 fence->execbuf.DR1 = 0;
1430 fence->execbuf.DR4 = 0;
1431
1432 fence->execbuf.flags =
1433 I915_EXEC_HANDLE_LUT | I915_EXEC_NO_RELOC | I915_EXEC_RENDER;
1434 fence->execbuf.rsvd1 = device->context_id;
1435 fence->execbuf.rsvd2 = 0;
1436
1437 *pFence = anv_fence_to_handle(fence);
1438
1439 return VK_SUCCESS;
1440
1441 fail:
1442 anv_device_free(device, fence);
1443
1444 return result;
1445 }
1446
1447 VkResult anv_DestroyFence(
1448 VkDevice _device,
1449 VkFence _fence)
1450 {
1451 ANV_FROM_HANDLE(anv_device, device, _device);
1452 ANV_FROM_HANDLE(anv_fence, fence, _fence);
1453
1454 anv_gem_munmap(fence->bo.map, fence->bo.size);
1455 anv_gem_close(device, fence->bo.gem_handle);
1456 anv_device_free(device, fence);
1457
1458 return VK_SUCCESS;
1459 }
1460
1461 VkResult anv_ResetFences(
1462 VkDevice _device,
1463 uint32_t fenceCount,
1464 const VkFence* pFences)
1465 {
1466 struct anv_fence **fences = (struct anv_fence **) pFences;
1467
1468 for (uint32_t i = 0; i < fenceCount; i++)
1469 fences[i]->ready = false;
1470
1471 return VK_SUCCESS;
1472 }
1473
1474 VkResult anv_GetFenceStatus(
1475 VkDevice _device,
1476 VkFence _fence)
1477 {
1478 ANV_FROM_HANDLE(anv_device, device, _device);
1479 ANV_FROM_HANDLE(anv_fence, fence, _fence);
1480 int64_t t = 0;
1481 int ret;
1482
1483 if (fence->ready)
1484 return VK_SUCCESS;
1485
1486 ret = anv_gem_wait(device, fence->bo.gem_handle, &t);
1487 if (ret == 0) {
1488 fence->ready = true;
1489 return VK_SUCCESS;
1490 }
1491
1492 return VK_NOT_READY;
1493 }
1494
1495 VkResult anv_WaitForFences(
1496 VkDevice _device,
1497 uint32_t fenceCount,
1498 const VkFence* pFences,
1499 VkBool32 waitAll,
1500 uint64_t timeout)
1501 {
1502 ANV_FROM_HANDLE(anv_device, device, _device);
1503 int64_t t = timeout;
1504 int ret;
1505
1506 /* FIXME: handle !waitAll */
1507
1508 for (uint32_t i = 0; i < fenceCount; i++) {
1509 ANV_FROM_HANDLE(anv_fence, fence, pFences[i]);
1510 ret = anv_gem_wait(device, fence->bo.gem_handle, &t);
1511 if (ret == -1 && errno == ETIME)
1512 return VK_TIMEOUT;
1513 else if (ret == -1)
1514 return vk_error(VK_ERROR_UNKNOWN);
1515 }
1516
1517 return VK_SUCCESS;
1518 }
1519
1520 // Queue semaphore functions
1521
1522 VkResult anv_CreateSemaphore(
1523 VkDevice device,
1524 const VkSemaphoreCreateInfo* pCreateInfo,
1525 VkSemaphore* pSemaphore)
1526 {
1527 stub_return(VK_UNSUPPORTED);
1528 }
1529
1530 VkResult anv_DestroySemaphore(
1531 VkDevice device,
1532 VkSemaphore semaphore)
1533 {
1534 stub_return(VK_UNSUPPORTED);
1535 }
1536
1537 VkResult anv_QueueSignalSemaphore(
1538 VkQueue queue,
1539 VkSemaphore semaphore)
1540 {
1541 stub_return(VK_UNSUPPORTED);
1542 }
1543
1544 VkResult anv_QueueWaitSemaphore(
1545 VkQueue queue,
1546 VkSemaphore semaphore)
1547 {
1548 stub_return(VK_UNSUPPORTED);
1549 }
1550
1551 // Event functions
1552
1553 VkResult anv_CreateEvent(
1554 VkDevice device,
1555 const VkEventCreateInfo* pCreateInfo,
1556 VkEvent* pEvent)
1557 {
1558 stub_return(VK_UNSUPPORTED);
1559 }
1560
1561 VkResult anv_DestroyEvent(
1562 VkDevice device,
1563 VkEvent event)
1564 {
1565 stub_return(VK_UNSUPPORTED);
1566 }
1567
1568 VkResult anv_GetEventStatus(
1569 VkDevice device,
1570 VkEvent event)
1571 {
1572 stub_return(VK_UNSUPPORTED);
1573 }
1574
1575 VkResult anv_SetEvent(
1576 VkDevice device,
1577 VkEvent event)
1578 {
1579 stub_return(VK_UNSUPPORTED);
1580 }
1581
1582 VkResult anv_ResetEvent(
1583 VkDevice device,
1584 VkEvent event)
1585 {
1586 stub_return(VK_UNSUPPORTED);
1587 }
1588
1589 // Buffer functions
1590
1591 VkResult anv_CreateBuffer(
1592 VkDevice _device,
1593 const VkBufferCreateInfo* pCreateInfo,
1594 VkBuffer* pBuffer)
1595 {
1596 ANV_FROM_HANDLE(anv_device, device, _device);
1597 struct anv_buffer *buffer;
1598
1599 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
1600
1601 buffer = anv_device_alloc(device, sizeof(*buffer), 8,
1602 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1603 if (buffer == NULL)
1604 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1605
1606 buffer->size = pCreateInfo->size;
1607 buffer->bo = NULL;
1608 buffer->offset = 0;
1609
1610 *pBuffer = anv_buffer_to_handle(buffer);
1611
1612 return VK_SUCCESS;
1613 }
1614
1615 VkResult anv_DestroyBuffer(
1616 VkDevice _device,
1617 VkBuffer _buffer)
1618 {
1619 ANV_FROM_HANDLE(anv_device, device, _device);
1620 ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
1621
1622 anv_device_free(device, buffer);
1623
1624 return VK_SUCCESS;
1625 }
1626
1627 // Buffer view functions
1628
1629 static void
1630 fill_buffer_surface_state(void *state, VkFormat format,
1631 uint32_t offset, uint32_t range)
1632 {
1633 const struct anv_format *info;
1634
1635 info = anv_format_for_vk_format(format);
1636 /* This assumes RGBA float format. */
1637 uint32_t stride = 4;
1638 uint32_t num_elements = range / stride;
1639
1640 struct GEN8_RENDER_SURFACE_STATE surface_state = {
1641 .SurfaceType = SURFTYPE_BUFFER,
1642 .SurfaceArray = false,
1643 .SurfaceFormat = info->surface_format,
1644 .SurfaceVerticalAlignment = VALIGN4,
1645 .SurfaceHorizontalAlignment = HALIGN4,
1646 .TileMode = LINEAR,
1647 .VerticalLineStride = 0,
1648 .VerticalLineStrideOffset = 0,
1649 .SamplerL2BypassModeDisable = true,
1650 .RenderCacheReadWriteMode = WriteOnlyCache,
1651 .MemoryObjectControlState = GEN8_MOCS,
1652 .BaseMipLevel = 0.0,
1653 .SurfaceQPitch = 0,
1654 .Height = (num_elements >> 7) & 0x3fff,
1655 .Width = num_elements & 0x7f,
1656 .Depth = (num_elements >> 21) & 0x3f,
1657 .SurfacePitch = stride - 1,
1658 .MinimumArrayElement = 0,
1659 .NumberofMultisamples = MULTISAMPLECOUNT_1,
1660 .XOffset = 0,
1661 .YOffset = 0,
1662 .SurfaceMinLOD = 0,
1663 .MIPCountLOD = 0,
1664 .AuxiliarySurfaceMode = AUX_NONE,
1665 .RedClearColor = 0,
1666 .GreenClearColor = 0,
1667 .BlueClearColor = 0,
1668 .AlphaClearColor = 0,
1669 .ShaderChannelSelectRed = SCS_RED,
1670 .ShaderChannelSelectGreen = SCS_GREEN,
1671 .ShaderChannelSelectBlue = SCS_BLUE,
1672 .ShaderChannelSelectAlpha = SCS_ALPHA,
1673 .ResourceMinLOD = 0.0,
1674 /* FIXME: We assume that the image must be bound at this time. */
1675 .SurfaceBaseAddress = { NULL, offset },
1676 };
1677
1678 GEN8_RENDER_SURFACE_STATE_pack(NULL, state, &surface_state);
1679 }
1680
1681 VkResult anv_CreateBufferView(
1682 VkDevice _device,
1683 const VkBufferViewCreateInfo* pCreateInfo,
1684 VkBufferView* pView)
1685 {
1686 ANV_FROM_HANDLE(anv_device, device, _device);
1687 ANV_FROM_HANDLE(anv_buffer, buffer, pCreateInfo->buffer);
1688 struct anv_surface_view *view;
1689
1690 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO);
1691
1692 view = anv_device_alloc(device, sizeof(*view), 8,
1693 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1694 if (view == NULL)
1695 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1696
1697 view->bo = buffer->bo;
1698 view->offset = buffer->offset + pCreateInfo->offset;
1699 view->surface_state =
1700 anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
1701 view->format = pCreateInfo->format;
1702 view->range = pCreateInfo->range;
1703
1704 fill_buffer_surface_state(view->surface_state.map,
1705 pCreateInfo->format, view->offset, pCreateInfo->range);
1706
1707 *pView = (VkBufferView) view;
1708
1709 return VK_SUCCESS;
1710 }
1711
1712 VkResult anv_DestroyBufferView(
1713 VkDevice _device,
1714 VkBufferView _view)
1715 {
1716 ANV_FROM_HANDLE(anv_device, device, _device);
1717
1718 anv_surface_view_destroy(device, (struct anv_surface_view *)_view);
1719
1720 return VK_SUCCESS;
1721 }
1722
1723 // Sampler functions
1724
1725 VkResult anv_CreateSampler(
1726 VkDevice _device,
1727 const VkSamplerCreateInfo* pCreateInfo,
1728 VkSampler* pSampler)
1729 {
1730 ANV_FROM_HANDLE(anv_device, device, _device);
1731 struct anv_sampler *sampler;
1732 uint32_t mag_filter, min_filter, max_anisotropy;
1733
1734 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
1735
1736 sampler = anv_device_alloc(device, sizeof(*sampler), 8,
1737 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1738 if (!sampler)
1739 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1740
1741 static const uint32_t vk_to_gen_tex_filter[] = {
1742 [VK_TEX_FILTER_NEAREST] = MAPFILTER_NEAREST,
1743 [VK_TEX_FILTER_LINEAR] = MAPFILTER_LINEAR
1744 };
1745
1746 static const uint32_t vk_to_gen_mipmap_mode[] = {
1747 [VK_TEX_MIPMAP_MODE_BASE] = MIPFILTER_NONE,
1748 [VK_TEX_MIPMAP_MODE_NEAREST] = MIPFILTER_NEAREST,
1749 [VK_TEX_MIPMAP_MODE_LINEAR] = MIPFILTER_LINEAR
1750 };
1751
1752 static const uint32_t vk_to_gen_tex_address[] = {
1753 [VK_TEX_ADDRESS_WRAP] = TCM_WRAP,
1754 [VK_TEX_ADDRESS_MIRROR] = TCM_MIRROR,
1755 [VK_TEX_ADDRESS_CLAMP] = TCM_CLAMP,
1756 [VK_TEX_ADDRESS_MIRROR_ONCE] = TCM_MIRROR_ONCE,
1757 [VK_TEX_ADDRESS_CLAMP_BORDER] = TCM_CLAMP_BORDER,
1758 };
1759
1760 static const uint32_t vk_to_gen_compare_op[] = {
1761 [VK_COMPARE_OP_NEVER] = PREFILTEROPNEVER,
1762 [VK_COMPARE_OP_LESS] = PREFILTEROPLESS,
1763 [VK_COMPARE_OP_EQUAL] = PREFILTEROPEQUAL,
1764 [VK_COMPARE_OP_LESS_EQUAL] = PREFILTEROPLEQUAL,
1765 [VK_COMPARE_OP_GREATER] = PREFILTEROPGREATER,
1766 [VK_COMPARE_OP_NOT_EQUAL] = PREFILTEROPNOTEQUAL,
1767 [VK_COMPARE_OP_GREATER_EQUAL] = PREFILTEROPGEQUAL,
1768 [VK_COMPARE_OP_ALWAYS] = PREFILTEROPALWAYS,
1769 };
1770
1771 if (pCreateInfo->maxAnisotropy > 1) {
1772 mag_filter = MAPFILTER_ANISOTROPIC;
1773 min_filter = MAPFILTER_ANISOTROPIC;
1774 max_anisotropy = (pCreateInfo->maxAnisotropy - 2) / 2;
1775 } else {
1776 mag_filter = vk_to_gen_tex_filter[pCreateInfo->magFilter];
1777 min_filter = vk_to_gen_tex_filter[pCreateInfo->minFilter];
1778 max_anisotropy = RATIO21;
1779 }
1780
1781 struct GEN8_SAMPLER_STATE sampler_state = {
1782 .SamplerDisable = false,
1783 .TextureBorderColorMode = DX10OGL,
1784 .LODPreClampMode = 0,
1785 .BaseMipLevel = 0.0,
1786 .MipModeFilter = vk_to_gen_mipmap_mode[pCreateInfo->mipMode],
1787 .MagModeFilter = mag_filter,
1788 .MinModeFilter = min_filter,
1789 .TextureLODBias = pCreateInfo->mipLodBias * 256,
1790 .AnisotropicAlgorithm = EWAApproximation,
1791 .MinLOD = pCreateInfo->minLod,
1792 .MaxLOD = pCreateInfo->maxLod,
1793 .ChromaKeyEnable = 0,
1794 .ChromaKeyIndex = 0,
1795 .ChromaKeyMode = 0,
1796 .ShadowFunction = vk_to_gen_compare_op[pCreateInfo->compareOp],
1797 .CubeSurfaceControlMode = 0,
1798
1799 .IndirectStatePointer =
1800 device->border_colors.offset +
1801 pCreateInfo->borderColor * sizeof(float) * 4,
1802
1803 .LODClampMagnificationMode = MIPNONE,
1804 .MaximumAnisotropy = max_anisotropy,
1805 .RAddressMinFilterRoundingEnable = 0,
1806 .RAddressMagFilterRoundingEnable = 0,
1807 .VAddressMinFilterRoundingEnable = 0,
1808 .VAddressMagFilterRoundingEnable = 0,
1809 .UAddressMinFilterRoundingEnable = 0,
1810 .UAddressMagFilterRoundingEnable = 0,
1811 .TrilinearFilterQuality = 0,
1812 .NonnormalizedCoordinateEnable = 0,
1813 .TCXAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressU],
1814 .TCYAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressV],
1815 .TCZAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressW],
1816 };
1817
1818 GEN8_SAMPLER_STATE_pack(NULL, sampler->state, &sampler_state);
1819
1820 *pSampler = anv_sampler_to_handle(sampler);
1821
1822 return VK_SUCCESS;
1823 }
1824
1825 VkResult anv_DestroySampler(
1826 VkDevice _device,
1827 VkSampler _sampler)
1828 {
1829 ANV_FROM_HANDLE(anv_device, device, _device);
1830 ANV_FROM_HANDLE(anv_sampler, sampler, _sampler);
1831
1832 anv_device_free(device, sampler);
1833
1834 return VK_SUCCESS;
1835 }
1836
1837 // Descriptor set functions
1838
1839 VkResult anv_CreateDescriptorSetLayout(
1840 VkDevice _device,
1841 const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
1842 VkDescriptorSetLayout* pSetLayout)
1843 {
1844 ANV_FROM_HANDLE(anv_device, device, _device);
1845 struct anv_descriptor_set_layout *set_layout;
1846
1847 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO);
1848
1849 uint32_t sampler_count[VK_SHADER_STAGE_NUM] = { 0, };
1850 uint32_t surface_count[VK_SHADER_STAGE_NUM] = { 0, };
1851 uint32_t num_dynamic_buffers = 0;
1852 uint32_t count = 0;
1853 uint32_t stages = 0;
1854 uint32_t s;
1855
1856 for (uint32_t i = 0; i < pCreateInfo->count; i++) {
1857 switch (pCreateInfo->pBinding[i].descriptorType) {
1858 case VK_DESCRIPTOR_TYPE_SAMPLER:
1859 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1860 for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
1861 sampler_count[s] += pCreateInfo->pBinding[i].arraySize;
1862 break;
1863 default:
1864 break;
1865 }
1866
1867 switch (pCreateInfo->pBinding[i].descriptorType) {
1868 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1869 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1870 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1871 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1872 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1873 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1874 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1875 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1876 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1877 for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
1878 surface_count[s] += pCreateInfo->pBinding[i].arraySize;
1879 break;
1880 default:
1881 break;
1882 }
1883
1884 switch (pCreateInfo->pBinding[i].descriptorType) {
1885 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1886 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1887 num_dynamic_buffers += pCreateInfo->pBinding[i].arraySize;
1888 break;
1889 default:
1890 break;
1891 }
1892
1893 stages |= pCreateInfo->pBinding[i].stageFlags;
1894 count += pCreateInfo->pBinding[i].arraySize;
1895 }
1896
1897 uint32_t sampler_total = 0;
1898 uint32_t surface_total = 0;
1899 for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) {
1900 sampler_total += sampler_count[s];
1901 surface_total += surface_count[s];
1902 }
1903
1904 size_t size = sizeof(*set_layout) +
1905 (sampler_total + surface_total) * sizeof(set_layout->entries[0]);
1906 set_layout = anv_device_alloc(device, size, 8,
1907 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1908 if (!set_layout)
1909 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1910
1911 set_layout->num_dynamic_buffers = num_dynamic_buffers;
1912 set_layout->count = count;
1913 set_layout->shader_stages = stages;
1914
1915 struct anv_descriptor_slot *p = set_layout->entries;
1916 struct anv_descriptor_slot *sampler[VK_SHADER_STAGE_NUM];
1917 struct anv_descriptor_slot *surface[VK_SHADER_STAGE_NUM];
1918 for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) {
1919 set_layout->stage[s].surface_count = surface_count[s];
1920 set_layout->stage[s].surface_start = surface[s] = p;
1921 p += surface_count[s];
1922 set_layout->stage[s].sampler_count = sampler_count[s];
1923 set_layout->stage[s].sampler_start = sampler[s] = p;
1924 p += sampler_count[s];
1925 }
1926
1927 uint32_t descriptor = 0;
1928 int8_t dynamic_slot = 0;
1929 bool is_dynamic;
1930 for (uint32_t i = 0; i < pCreateInfo->count; i++) {
1931 switch (pCreateInfo->pBinding[i].descriptorType) {
1932 case VK_DESCRIPTOR_TYPE_SAMPLER:
1933 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1934 for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
1935 for (uint32_t j = 0; j < pCreateInfo->pBinding[i].arraySize; j++) {
1936 sampler[s]->index = descriptor + j;
1937 sampler[s]->dynamic_slot = -1;
1938 sampler[s]++;
1939 }
1940 break;
1941 default:
1942 break;
1943 }
1944
1945 switch (pCreateInfo->pBinding[i].descriptorType) {
1946 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1947 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1948 is_dynamic = true;
1949 break;
1950 default:
1951 is_dynamic = false;
1952 break;
1953 }
1954
1955 switch (pCreateInfo->pBinding[i].descriptorType) {
1956 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1957 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1958 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1959 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1960 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1961 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1962 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1963 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1964 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1965 for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
1966 for (uint32_t j = 0; j < pCreateInfo->pBinding[i].arraySize; j++) {
1967 surface[s]->index = descriptor + j;
1968 if (is_dynamic)
1969 surface[s]->dynamic_slot = dynamic_slot + j;
1970 else
1971 surface[s]->dynamic_slot = -1;
1972 surface[s]++;
1973 }
1974 break;
1975 default:
1976 break;
1977 }
1978
1979 if (is_dynamic)
1980 dynamic_slot += pCreateInfo->pBinding[i].arraySize;
1981
1982 descriptor += pCreateInfo->pBinding[i].arraySize;
1983 }
1984
1985 *pSetLayout = anv_descriptor_set_layout_to_handle(set_layout);
1986
1987 return VK_SUCCESS;
1988 }
1989
1990 VkResult anv_DestroyDescriptorSetLayout(
1991 VkDevice _device,
1992 VkDescriptorSetLayout _set_layout)
1993 {
1994 ANV_FROM_HANDLE(anv_device, device, _device);
1995 ANV_FROM_HANDLE(anv_descriptor_set_layout, set_layout, _set_layout);
1996
1997 anv_device_free(device, set_layout);
1998
1999 return VK_SUCCESS;
2000 }
2001
2002 VkResult anv_CreateDescriptorPool(
2003 VkDevice device,
2004 VkDescriptorPoolUsage poolUsage,
2005 uint32_t maxSets,
2006 const VkDescriptorPoolCreateInfo* pCreateInfo,
2007 VkDescriptorPool* pDescriptorPool)
2008 {
2009 *pDescriptorPool = 1;
2010
2011 return VK_SUCCESS;
2012 }
2013
2014 VkResult anv_ResetDescriptorPool(
2015 VkDevice device,
2016 VkDescriptorPool descriptorPool)
2017 {
2018 return VK_SUCCESS;
2019 }
2020
2021 VkResult anv_AllocDescriptorSets(
2022 VkDevice _device,
2023 VkDescriptorPool descriptorPool,
2024 VkDescriptorSetUsage setUsage,
2025 uint32_t count,
2026 const VkDescriptorSetLayout* pSetLayouts,
2027 VkDescriptorSet* pDescriptorSets,
2028 uint32_t* pCount)
2029 {
2030 ANV_FROM_HANDLE(anv_device, device, _device);
2031 struct anv_descriptor_set *set;
2032 size_t size;
2033
2034 for (uint32_t i = 0; i < count; i++) {
2035 ANV_FROM_HANDLE(anv_descriptor_set_layout, layout, pSetLayouts[i]);
2036 size = sizeof(*set) + layout->count * sizeof(set->descriptors[0]);
2037 set = anv_device_alloc(device, size, 8,
2038 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
2039 if (!set) {
2040 *pCount = i;
2041 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2042 }
2043
2044 /* Descriptor sets may not be 100% filled out so we need to memset to
2045 * ensure that we can properly detect and handle holes.
2046 */
2047 memset(set, 0, size);
2048
2049 pDescriptorSets[i] = anv_descriptor_set_to_handle(set);
2050 }
2051
2052 *pCount = count;
2053
2054 return VK_SUCCESS;
2055 }
2056
2057 VkResult anv_UpdateDescriptorSets(
2058 VkDevice device,
2059 uint32_t writeCount,
2060 const VkWriteDescriptorSet* pDescriptorWrites,
2061 uint32_t copyCount,
2062 const VkCopyDescriptorSet* pDescriptorCopies)
2063 {
2064 for (uint32_t i = 0; i < writeCount; i++) {
2065 const VkWriteDescriptorSet *write = &pDescriptorWrites[i];
2066 ANV_FROM_HANDLE(anv_descriptor_set, set, write->destSet);
2067
2068 switch (write->descriptorType) {
2069 case VK_DESCRIPTOR_TYPE_SAMPLER:
2070 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2071 for (uint32_t j = 0; j < write->count; j++) {
2072 set->descriptors[write->destBinding + j].sampler =
2073 anv_sampler_from_handle(write->pDescriptors[j].sampler);
2074 }
2075
2076 if (write->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
2077 break;
2078
2079 /* fallthrough */
2080
2081 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
2082 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2083 for (uint32_t j = 0; j < write->count; j++) {
2084 set->descriptors[write->destBinding + j].view =
2085 (struct anv_surface_view *)write->pDescriptors[j].imageView;
2086 }
2087 break;
2088
2089 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2090 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2091 anv_finishme("texel buffers not implemented");
2092 break;
2093
2094 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2095 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2096 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
2097 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
2098 for (uint32_t j = 0; j < write->count; j++) {
2099 set->descriptors[write->destBinding + j].view =
2100 (struct anv_surface_view *)write->pDescriptors[j].bufferView;
2101 }
2102
2103 default:
2104 break;
2105 }
2106 }
2107
2108 for (uint32_t i = 0; i < copyCount; i++) {
2109 const VkCopyDescriptorSet *copy = &pDescriptorCopies[i];
2110 ANV_FROM_HANDLE(anv_descriptor_set, src, copy->destSet);
2111 ANV_FROM_HANDLE(anv_descriptor_set, dest, copy->destSet);
2112 for (uint32_t j = 0; j < copy->count; j++) {
2113 dest->descriptors[copy->destBinding + j] =
2114 src->descriptors[copy->srcBinding + j];
2115 }
2116 }
2117
2118 return VK_SUCCESS;
2119 }
2120
2121 // State object functions
2122
2123 static inline int64_t
2124 clamp_int64(int64_t x, int64_t min, int64_t max)
2125 {
2126 if (x < min)
2127 return min;
2128 else if (x < max)
2129 return x;
2130 else
2131 return max;
2132 }
2133
2134 static void
2135 anv_dynamic_vp_state_destroy(struct anv_device *device,
2136 struct anv_object *object,
2137 VkObjectType obj_type)
2138 {
2139 struct anv_dynamic_vp_state *state = (void *)object;
2140
2141 assert(obj_type == VK_OBJECT_TYPE_DYNAMIC_VP_STATE);
2142
2143 anv_state_pool_free(&device->dynamic_state_pool, state->sf_clip_vp);
2144 anv_state_pool_free(&device->dynamic_state_pool, state->cc_vp);
2145 anv_state_pool_free(&device->dynamic_state_pool, state->scissor);
2146
2147 anv_device_free(device, state);
2148 }
2149
2150 VkResult anv_CreateDynamicViewportState(
2151 VkDevice _device,
2152 const VkDynamicViewportStateCreateInfo* pCreateInfo,
2153 VkDynamicViewportState* pState)
2154 {
2155 ANV_FROM_HANDLE(anv_device, device, _device);
2156 struct anv_dynamic_vp_state *state;
2157
2158 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO);
2159
2160 state = anv_device_alloc(device, sizeof(*state), 8,
2161 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
2162 if (state == NULL)
2163 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2164
2165 state->base.destructor = anv_dynamic_vp_state_destroy;
2166
2167 unsigned count = pCreateInfo->viewportAndScissorCount;
2168 state->sf_clip_vp = anv_state_pool_alloc(&device->dynamic_state_pool,
2169 count * 64, 64);
2170 state->cc_vp = anv_state_pool_alloc(&device->dynamic_state_pool,
2171 count * 8, 32);
2172 state->scissor = anv_state_pool_alloc(&device->dynamic_state_pool,
2173 count * 32, 32);
2174
2175 for (uint32_t i = 0; i < pCreateInfo->viewportAndScissorCount; i++) {
2176 const VkViewport *vp = &pCreateInfo->pViewports[i];
2177 const VkRect2D *s = &pCreateInfo->pScissors[i];
2178
2179 struct GEN8_SF_CLIP_VIEWPORT sf_clip_viewport = {
2180 .ViewportMatrixElementm00 = vp->width / 2,
2181 .ViewportMatrixElementm11 = vp->height / 2,
2182 .ViewportMatrixElementm22 = (vp->maxDepth - vp->minDepth) / 2,
2183 .ViewportMatrixElementm30 = vp->originX + vp->width / 2,
2184 .ViewportMatrixElementm31 = vp->originY + vp->height / 2,
2185 .ViewportMatrixElementm32 = (vp->maxDepth + vp->minDepth) / 2,
2186 .XMinClipGuardband = -1.0f,
2187 .XMaxClipGuardband = 1.0f,
2188 .YMinClipGuardband = -1.0f,
2189 .YMaxClipGuardband = 1.0f,
2190 .XMinViewPort = vp->originX,
2191 .XMaxViewPort = vp->originX + vp->width - 1,
2192 .YMinViewPort = vp->originY,
2193 .YMaxViewPort = vp->originY + vp->height - 1,
2194 };
2195
2196 struct GEN8_CC_VIEWPORT cc_viewport = {
2197 .MinimumDepth = vp->minDepth,
2198 .MaximumDepth = vp->maxDepth
2199 };
2200
2201 /* Since xmax and ymax are inclusive, we have to have xmax < xmin or
2202 * ymax < ymin for empty clips. In case clip x, y, width height are all
2203 * 0, the clamps below produce 0 for xmin, ymin, xmax, ymax, which isn't
2204 * what we want. Just special case empty clips and produce a canonical
2205 * empty clip. */
2206 static const struct GEN8_SCISSOR_RECT empty_scissor = {
2207 .ScissorRectangleYMin = 1,
2208 .ScissorRectangleXMin = 1,
2209 .ScissorRectangleYMax = 0,
2210 .ScissorRectangleXMax = 0
2211 };
2212
2213 const int max = 0xffff;
2214 struct GEN8_SCISSOR_RECT scissor = {
2215 /* Do this math using int64_t so overflow gets clamped correctly. */
2216 .ScissorRectangleYMin = clamp_int64(s->offset.y, 0, max),
2217 .ScissorRectangleXMin = clamp_int64(s->offset.x, 0, max),
2218 .ScissorRectangleYMax = clamp_int64((uint64_t) s->offset.y + s->extent.height - 1, 0, max),
2219 .ScissorRectangleXMax = clamp_int64((uint64_t) s->offset.x + s->extent.width - 1, 0, max)
2220 };
2221
2222 GEN8_SF_CLIP_VIEWPORT_pack(NULL, state->sf_clip_vp.map + i * 64, &sf_clip_viewport);
2223 GEN8_CC_VIEWPORT_pack(NULL, state->cc_vp.map + i * 32, &cc_viewport);
2224
2225 if (s->extent.width <= 0 || s->extent.height <= 0) {
2226 GEN8_SCISSOR_RECT_pack(NULL, state->scissor.map + i * 32, &empty_scissor);
2227 } else {
2228 GEN8_SCISSOR_RECT_pack(NULL, state->scissor.map + i * 32, &scissor);
2229 }
2230 }
2231
2232 *pState = anv_dynamic_vp_state_to_handle(state);
2233
2234 return VK_SUCCESS;
2235 }
2236
2237 VkResult anv_CreateDynamicRasterState(
2238 VkDevice _device,
2239 const VkDynamicRasterStateCreateInfo* pCreateInfo,
2240 VkDynamicRasterState* pState)
2241 {
2242 ANV_FROM_HANDLE(anv_device, device, _device);
2243 struct anv_dynamic_rs_state *state;
2244
2245 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO);
2246
2247 state = anv_device_alloc(device, sizeof(*state), 8,
2248 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
2249 if (state == NULL)
2250 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2251
2252 struct GEN8_3DSTATE_SF sf = {
2253 GEN8_3DSTATE_SF_header,
2254 .LineWidth = pCreateInfo->lineWidth,
2255 };
2256
2257 GEN8_3DSTATE_SF_pack(NULL, state->state_sf, &sf);
2258
2259 bool enable_bias = pCreateInfo->depthBias != 0.0f ||
2260 pCreateInfo->slopeScaledDepthBias != 0.0f;
2261 struct GEN8_3DSTATE_RASTER raster = {
2262 .GlobalDepthOffsetEnableSolid = enable_bias,
2263 .GlobalDepthOffsetEnableWireframe = enable_bias,
2264 .GlobalDepthOffsetEnablePoint = enable_bias,
2265 .GlobalDepthOffsetConstant = pCreateInfo->depthBias,
2266 .GlobalDepthOffsetScale = pCreateInfo->slopeScaledDepthBias,
2267 .GlobalDepthOffsetClamp = pCreateInfo->depthBiasClamp
2268 };
2269
2270 GEN8_3DSTATE_RASTER_pack(NULL, state->state_raster, &raster);
2271
2272 *pState = anv_dynamic_rs_state_to_handle(state);
2273
2274 return VK_SUCCESS;
2275 }
2276
2277 VkResult anv_CreateDynamicColorBlendState(
2278 VkDevice _device,
2279 const VkDynamicColorBlendStateCreateInfo* pCreateInfo,
2280 VkDynamicColorBlendState* pState)
2281 {
2282 ANV_FROM_HANDLE(anv_device, device, _device);
2283 struct anv_dynamic_cb_state *state;
2284
2285 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_CB_STATE_CREATE_INFO);
2286
2287 state = anv_device_alloc(device, sizeof(*state), 8,
2288 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
2289 if (state == NULL)
2290 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2291
2292 struct GEN8_COLOR_CALC_STATE color_calc_state = {
2293 .BlendConstantColorRed = pCreateInfo->blendConst[0],
2294 .BlendConstantColorGreen = pCreateInfo->blendConst[1],
2295 .BlendConstantColorBlue = pCreateInfo->blendConst[2],
2296 .BlendConstantColorAlpha = pCreateInfo->blendConst[3]
2297 };
2298
2299 GEN8_COLOR_CALC_STATE_pack(NULL, state->state_color_calc, &color_calc_state);
2300
2301 *pState = anv_dynamic_cb_state_to_handle(state);
2302
2303 return VK_SUCCESS;
2304 }
2305
2306 VkResult anv_CreateDynamicDepthStencilState(
2307 VkDevice _device,
2308 const VkDynamicDepthStencilStateCreateInfo* pCreateInfo,
2309 VkDynamicDepthStencilState* pState)
2310 {
2311 ANV_FROM_HANDLE(anv_device, device, _device);
2312 struct anv_dynamic_ds_state *state;
2313
2314 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_DS_STATE_CREATE_INFO);
2315
2316 state = anv_device_alloc(device, sizeof(*state), 8,
2317 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
2318 if (state == NULL)
2319 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2320
2321 struct GEN8_3DSTATE_WM_DEPTH_STENCIL wm_depth_stencil = {
2322 GEN8_3DSTATE_WM_DEPTH_STENCIL_header,
2323
2324 /* Is this what we need to do? */
2325 .StencilBufferWriteEnable = pCreateInfo->stencilWriteMask != 0,
2326
2327 .StencilTestMask = pCreateInfo->stencilReadMask & 0xff,
2328 .StencilWriteMask = pCreateInfo->stencilWriteMask & 0xff,
2329
2330 .BackfaceStencilTestMask = pCreateInfo->stencilReadMask & 0xff,
2331 .BackfaceStencilWriteMask = pCreateInfo->stencilWriteMask & 0xff,
2332 };
2333
2334 GEN8_3DSTATE_WM_DEPTH_STENCIL_pack(NULL, state->state_wm_depth_stencil,
2335 &wm_depth_stencil);
2336
2337 struct GEN8_COLOR_CALC_STATE color_calc_state = {
2338 .StencilReferenceValue = pCreateInfo->stencilFrontRef,
2339 .BackFaceStencilReferenceValue = pCreateInfo->stencilBackRef
2340 };
2341
2342 GEN8_COLOR_CALC_STATE_pack(NULL, state->state_color_calc, &color_calc_state);
2343
2344 *pState = anv_dynamic_ds_state_to_handle(state);
2345
2346 return VK_SUCCESS;
2347 }
2348
2349 // Command buffer functions
2350
2351 static void
2352 anv_cmd_buffer_destroy(struct anv_device *device,
2353 struct anv_object *object,
2354 VkObjectType obj_type)
2355 {
2356 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) object;
2357
2358 assert(obj_type == VK_OBJECT_TYPE_COMMAND_BUFFER);
2359
2360 /* Destroy all of the batch buffers */
2361 struct anv_batch_bo *bbo = cmd_buffer->last_batch_bo;
2362 while (bbo) {
2363 struct anv_batch_bo *prev = bbo->prev_batch_bo;
2364 anv_batch_bo_destroy(bbo, device);
2365 bbo = prev;
2366 }
2367 anv_reloc_list_finish(&cmd_buffer->batch.relocs, device);
2368
2369 /* Destroy all of the surface state buffers */
2370 bbo = cmd_buffer->surface_batch_bo;
2371 while (bbo) {
2372 struct anv_batch_bo *prev = bbo->prev_batch_bo;
2373 anv_batch_bo_destroy(bbo, device);
2374 bbo = prev;
2375 }
2376 anv_reloc_list_finish(&cmd_buffer->surface_relocs, device);
2377
2378 anv_state_stream_finish(&cmd_buffer->surface_state_stream);
2379 anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);
2380 anv_device_free(device, cmd_buffer->exec2_objects);
2381 anv_device_free(device, cmd_buffer->exec2_bos);
2382 anv_device_free(device, cmd_buffer);
2383 }
2384
2385 static VkResult
2386 anv_cmd_buffer_chain_batch(struct anv_batch *batch, void *_data)
2387 {
2388 struct anv_cmd_buffer *cmd_buffer = _data;
2389
2390 struct anv_batch_bo *new_bbo, *old_bbo = cmd_buffer->last_batch_bo;
2391
2392 VkResult result = anv_batch_bo_create(cmd_buffer->device, &new_bbo);
2393 if (result != VK_SUCCESS)
2394 return result;
2395
2396 /* We set the end of the batch a little short so we would be sure we
2397 * have room for the chaining command. Since we're about to emit the
2398 * chaining command, let's set it back where it should go.
2399 */
2400 batch->end += GEN8_MI_BATCH_BUFFER_START_length * 4;
2401 assert(batch->end == old_bbo->bo.map + old_bbo->bo.size);
2402
2403 anv_batch_emit(batch, GEN8_MI_BATCH_BUFFER_START,
2404 GEN8_MI_BATCH_BUFFER_START_header,
2405 ._2ndLevelBatchBuffer = _1stlevelbatch,
2406 .AddressSpaceIndicator = ASI_PPGTT,
2407 .BatchBufferStartAddress = { &new_bbo->bo, 0 },
2408 );
2409
2410 /* Pad out to a 2-dword aligned boundary with zeros */
2411 if ((uintptr_t)batch->next % 8 != 0) {
2412 *(uint32_t *)batch->next = 0;
2413 batch->next += 4;
2414 }
2415
2416 anv_batch_bo_finish(cmd_buffer->last_batch_bo, batch);
2417
2418 new_bbo->prev_batch_bo = old_bbo;
2419 cmd_buffer->last_batch_bo = new_bbo;
2420
2421 anv_batch_bo_start(new_bbo, batch, GEN8_MI_BATCH_BUFFER_START_length * 4);
2422
2423 return VK_SUCCESS;
2424 }
2425
2426 VkResult anv_CreateCommandBuffer(
2427 VkDevice _device,
2428 const VkCmdBufferCreateInfo* pCreateInfo,
2429 VkCmdBuffer* pCmdBuffer)
2430 {
2431 ANV_FROM_HANDLE(anv_device, device, _device);
2432 struct anv_cmd_buffer *cmd_buffer;
2433 VkResult result;
2434
2435 assert(pCreateInfo->level == VK_CMD_BUFFER_LEVEL_PRIMARY);
2436
2437 cmd_buffer = anv_device_alloc(device, sizeof(*cmd_buffer), 8,
2438 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
2439 if (cmd_buffer == NULL)
2440 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2441
2442 cmd_buffer->base.destructor = anv_cmd_buffer_destroy;
2443
2444 cmd_buffer->device = device;
2445 cmd_buffer->rs_state = NULL;
2446 cmd_buffer->vp_state = NULL;
2447 cmd_buffer->cb_state = NULL;
2448 cmd_buffer->ds_state = NULL;
2449 memset(&cmd_buffer->state_vf, 0, sizeof(cmd_buffer->state_vf));
2450 memset(&cmd_buffer->descriptors, 0, sizeof(cmd_buffer->descriptors));
2451
2452 result = anv_batch_bo_create(device, &cmd_buffer->last_batch_bo);
2453 if (result != VK_SUCCESS)
2454 goto fail;
2455
2456 result = anv_reloc_list_init(&cmd_buffer->batch.relocs, device);
2457 if (result != VK_SUCCESS)
2458 goto fail_batch_bo;
2459
2460 cmd_buffer->batch.device = device;
2461 cmd_buffer->batch.extend_cb = anv_cmd_buffer_chain_batch;
2462 cmd_buffer->batch.user_data = cmd_buffer;
2463
2464 anv_batch_bo_start(cmd_buffer->last_batch_bo, &cmd_buffer->batch,
2465 GEN8_MI_BATCH_BUFFER_START_length * 4);
2466
2467 result = anv_batch_bo_create(device, &cmd_buffer->surface_batch_bo);
2468 if (result != VK_SUCCESS)
2469 goto fail_batch_relocs;
2470 cmd_buffer->surface_batch_bo->first_reloc = 0;
2471
2472 result = anv_reloc_list_init(&cmd_buffer->surface_relocs, device);
2473 if (result != VK_SUCCESS)
2474 goto fail_ss_batch_bo;
2475
2476 /* Start surface_next at 1 so surface offset 0 is invalid. */
2477 cmd_buffer->surface_next = 1;
2478
2479 cmd_buffer->exec2_objects = NULL;
2480 cmd_buffer->exec2_bos = NULL;
2481 cmd_buffer->exec2_array_length = 0;
2482
2483 anv_state_stream_init(&cmd_buffer->surface_state_stream,
2484 &device->surface_state_block_pool);
2485 anv_state_stream_init(&cmd_buffer->dynamic_state_stream,
2486 &device->dynamic_state_block_pool);
2487
2488 cmd_buffer->dirty = 0;
2489 cmd_buffer->vb_dirty = 0;
2490 cmd_buffer->descriptors_dirty = 0;
2491 cmd_buffer->pipeline = NULL;
2492 cmd_buffer->vp_state = NULL;
2493 cmd_buffer->rs_state = NULL;
2494 cmd_buffer->ds_state = NULL;
2495
2496 *pCmdBuffer = anv_cmd_buffer_to_handle(cmd_buffer);
2497
2498 return VK_SUCCESS;
2499
2500 fail_ss_batch_bo:
2501 anv_batch_bo_destroy(cmd_buffer->surface_batch_bo, device);
2502 fail_batch_relocs:
2503 anv_reloc_list_finish(&cmd_buffer->batch.relocs, device);
2504 fail_batch_bo:
2505 anv_batch_bo_destroy(cmd_buffer->last_batch_bo, device);
2506 fail:
2507 anv_device_free(device, cmd_buffer);
2508
2509 return result;
2510 }
2511
2512 static void
2513 anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer)
2514 {
2515 struct anv_device *device = cmd_buffer->device;
2516 struct anv_bo *scratch_bo = NULL;
2517
2518 cmd_buffer->scratch_size = device->scratch_block_pool.size;
2519 if (cmd_buffer->scratch_size > 0)
2520 scratch_bo = &device->scratch_block_pool.bo;
2521
2522 anv_batch_emit(&cmd_buffer->batch, GEN8_STATE_BASE_ADDRESS,
2523 .GeneralStateBaseAddress = { scratch_bo, 0 },
2524 .GeneralStateMemoryObjectControlState = GEN8_MOCS,
2525 .GeneralStateBaseAddressModifyEnable = true,
2526 .GeneralStateBufferSize = 0xfffff,
2527 .GeneralStateBufferSizeModifyEnable = true,
2528
2529 .SurfaceStateBaseAddress = { &cmd_buffer->surface_batch_bo->bo, 0 },
2530 .SurfaceStateMemoryObjectControlState = GEN8_MOCS,
2531 .SurfaceStateBaseAddressModifyEnable = true,
2532
2533 .DynamicStateBaseAddress = { &device->dynamic_state_block_pool.bo, 0 },
2534 .DynamicStateMemoryObjectControlState = GEN8_MOCS,
2535 .DynamicStateBaseAddressModifyEnable = true,
2536 .DynamicStateBufferSize = 0xfffff,
2537 .DynamicStateBufferSizeModifyEnable = true,
2538
2539 .IndirectObjectBaseAddress = { NULL, 0 },
2540 .IndirectObjectMemoryObjectControlState = GEN8_MOCS,
2541 .IndirectObjectBaseAddressModifyEnable = true,
2542 .IndirectObjectBufferSize = 0xfffff,
2543 .IndirectObjectBufferSizeModifyEnable = true,
2544
2545 .InstructionBaseAddress = { &device->instruction_block_pool.bo, 0 },
2546 .InstructionMemoryObjectControlState = GEN8_MOCS,
2547 .InstructionBaseAddressModifyEnable = true,
2548 .InstructionBufferSize = 0xfffff,
2549 .InstructionBuffersizeModifyEnable = true);
2550 }
2551
2552 VkResult anv_BeginCommandBuffer(
2553 VkCmdBuffer cmdBuffer,
2554 const VkCmdBufferBeginInfo* pBeginInfo)
2555 {
2556 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
2557
2558 anv_cmd_buffer_emit_state_base_address(cmd_buffer);
2559 cmd_buffer->current_pipeline = UINT32_MAX;
2560
2561 return VK_SUCCESS;
2562 }
2563
2564 static VkResult
2565 anv_cmd_buffer_add_bo(struct anv_cmd_buffer *cmd_buffer,
2566 struct anv_bo *bo,
2567 struct drm_i915_gem_relocation_entry *relocs,
2568 size_t num_relocs)
2569 {
2570 struct drm_i915_gem_exec_object2 *obj;
2571
2572 if (bo->index < cmd_buffer->bo_count &&
2573 cmd_buffer->exec2_bos[bo->index] == bo)
2574 return VK_SUCCESS;
2575
2576 if (cmd_buffer->bo_count >= cmd_buffer->exec2_array_length) {
2577 uint32_t new_len = cmd_buffer->exec2_objects ?
2578 cmd_buffer->exec2_array_length * 2 : 64;
2579
2580 struct drm_i915_gem_exec_object2 *new_objects =
2581 anv_device_alloc(cmd_buffer->device, new_len * sizeof(*new_objects),
2582 8, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
2583 if (new_objects == NULL)
2584 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2585
2586 struct anv_bo **new_bos =
2587 anv_device_alloc(cmd_buffer->device, new_len * sizeof(*new_bos),
2588 8, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
2589 if (new_objects == NULL) {
2590 anv_device_free(cmd_buffer->device, new_objects);
2591 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2592 }
2593
2594 if (cmd_buffer->exec2_objects) {
2595 memcpy(new_objects, cmd_buffer->exec2_objects,
2596 cmd_buffer->bo_count * sizeof(*new_objects));
2597 memcpy(new_bos, cmd_buffer->exec2_bos,
2598 cmd_buffer->bo_count * sizeof(*new_bos));
2599 }
2600
2601 cmd_buffer->exec2_objects = new_objects;
2602 cmd_buffer->exec2_bos = new_bos;
2603 cmd_buffer->exec2_array_length = new_len;
2604 }
2605
2606 assert(cmd_buffer->bo_count < cmd_buffer->exec2_array_length);
2607
2608 bo->index = cmd_buffer->bo_count++;
2609 obj = &cmd_buffer->exec2_objects[bo->index];
2610 cmd_buffer->exec2_bos[bo->index] = bo;
2611
2612 obj->handle = bo->gem_handle;
2613 obj->relocation_count = 0;
2614 obj->relocs_ptr = 0;
2615 obj->alignment = 0;
2616 obj->offset = bo->offset;
2617 obj->flags = 0;
2618 obj->rsvd1 = 0;
2619 obj->rsvd2 = 0;
2620
2621 if (relocs) {
2622 obj->relocation_count = num_relocs;
2623 obj->relocs_ptr = (uintptr_t) relocs;
2624 }
2625
2626 return VK_SUCCESS;
2627 }
2628
2629 static void
2630 anv_cmd_buffer_add_validate_bos(struct anv_cmd_buffer *cmd_buffer,
2631 struct anv_reloc_list *list)
2632 {
2633 for (size_t i = 0; i < list->num_relocs; i++)
2634 anv_cmd_buffer_add_bo(cmd_buffer, list->reloc_bos[i], NULL, 0);
2635 }
2636
2637 static void
2638 anv_cmd_buffer_process_relocs(struct anv_cmd_buffer *cmd_buffer,
2639 struct anv_reloc_list *list)
2640 {
2641 struct anv_bo *bo;
2642
2643 /* If the kernel supports I915_EXEC_NO_RELOC, it will compare offset in
2644 * struct drm_i915_gem_exec_object2 against the bos current offset and if
2645 * all bos haven't moved it will skip relocation processing alltogether.
2646 * If I915_EXEC_NO_RELOC is not supported, the kernel ignores the incoming
2647 * value of offset so we can set it either way. For that to work we need
2648 * to make sure all relocs use the same presumed offset.
2649 */
2650
2651 for (size_t i = 0; i < list->num_relocs; i++) {
2652 bo = list->reloc_bos[i];
2653 if (bo->offset != list->relocs[i].presumed_offset)
2654 cmd_buffer->need_reloc = true;
2655
2656 list->relocs[i].target_handle = bo->index;
2657 }
2658 }
2659
2660 VkResult anv_EndCommandBuffer(
2661 VkCmdBuffer cmdBuffer)
2662 {
2663 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
2664 struct anv_device *device = cmd_buffer->device;
2665 struct anv_batch *batch = &cmd_buffer->batch;
2666
2667 anv_batch_emit(batch, GEN8_MI_BATCH_BUFFER_END);
2668
2669 /* Round batch up to an even number of dwords. */
2670 if ((batch->next - batch->start) & 4)
2671 anv_batch_emit(batch, GEN8_MI_NOOP);
2672
2673 anv_batch_bo_finish(cmd_buffer->last_batch_bo, &cmd_buffer->batch);
2674 cmd_buffer->surface_batch_bo->num_relocs =
2675 cmd_buffer->surface_relocs.num_relocs - cmd_buffer->surface_batch_bo->first_reloc;
2676 cmd_buffer->surface_batch_bo->length = cmd_buffer->surface_next;
2677
2678 cmd_buffer->bo_count = 0;
2679 cmd_buffer->need_reloc = false;
2680
2681 /* Lock for access to bo->index. */
2682 pthread_mutex_lock(&device->mutex);
2683
2684 /* Add surface state bos first so we can add them with their relocs. */
2685 for (struct anv_batch_bo *bbo = cmd_buffer->surface_batch_bo;
2686 bbo != NULL; bbo = bbo->prev_batch_bo) {
2687 anv_cmd_buffer_add_bo(cmd_buffer, &bbo->bo,
2688 &cmd_buffer->surface_relocs.relocs[bbo->first_reloc],
2689 bbo->num_relocs);
2690 }
2691
2692 /* Add all of the BOs referenced by surface state */
2693 anv_cmd_buffer_add_validate_bos(cmd_buffer, &cmd_buffer->surface_relocs);
2694
2695 /* Add all but the first batch BO */
2696 struct anv_batch_bo *batch_bo = cmd_buffer->last_batch_bo;
2697 while (batch_bo->prev_batch_bo) {
2698 anv_cmd_buffer_add_bo(cmd_buffer, &batch_bo->bo,
2699 &batch->relocs.relocs[batch_bo->first_reloc],
2700 batch_bo->num_relocs);
2701 batch_bo = batch_bo->prev_batch_bo;
2702 }
2703
2704 /* Add everything referenced by the batches */
2705 anv_cmd_buffer_add_validate_bos(cmd_buffer, &batch->relocs);
2706
2707 /* Add the first batch bo last */
2708 assert(batch_bo->prev_batch_bo == NULL && batch_bo->first_reloc == 0);
2709 anv_cmd_buffer_add_bo(cmd_buffer, &batch_bo->bo,
2710 &batch->relocs.relocs[batch_bo->first_reloc],
2711 batch_bo->num_relocs);
2712 assert(batch_bo->bo.index == cmd_buffer->bo_count - 1);
2713
2714 anv_cmd_buffer_process_relocs(cmd_buffer, &cmd_buffer->surface_relocs);
2715 anv_cmd_buffer_process_relocs(cmd_buffer, &batch->relocs);
2716
2717 cmd_buffer->execbuf.buffers_ptr = (uintptr_t) cmd_buffer->exec2_objects;
2718 cmd_buffer->execbuf.buffer_count = cmd_buffer->bo_count;
2719 cmd_buffer->execbuf.batch_start_offset = 0;
2720 cmd_buffer->execbuf.batch_len = batch->next - batch->start;
2721 cmd_buffer->execbuf.cliprects_ptr = 0;
2722 cmd_buffer->execbuf.num_cliprects = 0;
2723 cmd_buffer->execbuf.DR1 = 0;
2724 cmd_buffer->execbuf.DR4 = 0;
2725
2726 cmd_buffer->execbuf.flags = I915_EXEC_HANDLE_LUT;
2727 if (!cmd_buffer->need_reloc)
2728 cmd_buffer->execbuf.flags |= I915_EXEC_NO_RELOC;
2729 cmd_buffer->execbuf.flags |= I915_EXEC_RENDER;
2730 cmd_buffer->execbuf.rsvd1 = device->context_id;
2731 cmd_buffer->execbuf.rsvd2 = 0;
2732
2733 pthread_mutex_unlock(&device->mutex);
2734
2735 return VK_SUCCESS;
2736 }
2737
2738 VkResult anv_ResetCommandBuffer(
2739 VkCmdBuffer cmdBuffer)
2740 {
2741 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
2742
2743 /* Delete all but the first batch bo */
2744 while (cmd_buffer->last_batch_bo->prev_batch_bo) {
2745 struct anv_batch_bo *prev = cmd_buffer->last_batch_bo->prev_batch_bo;
2746 anv_batch_bo_destroy(cmd_buffer->last_batch_bo, cmd_buffer->device);
2747 cmd_buffer->last_batch_bo = prev;
2748 }
2749 assert(cmd_buffer->last_batch_bo->prev_batch_bo == NULL);
2750
2751 cmd_buffer->batch.relocs.num_relocs = 0;
2752 anv_batch_bo_start(cmd_buffer->last_batch_bo, &cmd_buffer->batch,
2753 GEN8_MI_BATCH_BUFFER_START_length * 4);
2754
2755 /* Delete all but the first batch bo */
2756 while (cmd_buffer->surface_batch_bo->prev_batch_bo) {
2757 struct anv_batch_bo *prev = cmd_buffer->surface_batch_bo->prev_batch_bo;
2758 anv_batch_bo_destroy(cmd_buffer->surface_batch_bo, cmd_buffer->device);
2759 cmd_buffer->surface_batch_bo = prev;
2760 }
2761 assert(cmd_buffer->surface_batch_bo->prev_batch_bo == NULL);
2762
2763 cmd_buffer->surface_next = 1;
2764 cmd_buffer->surface_relocs.num_relocs = 0;
2765
2766 cmd_buffer->rs_state = NULL;
2767 cmd_buffer->vp_state = NULL;
2768 cmd_buffer->cb_state = NULL;
2769 cmd_buffer->ds_state = NULL;
2770
2771 return VK_SUCCESS;
2772 }
2773
2774 // Command buffer building functions
2775
2776 void anv_CmdBindPipeline(
2777 VkCmdBuffer cmdBuffer,
2778 VkPipelineBindPoint pipelineBindPoint,
2779 VkPipeline _pipeline)
2780 {
2781 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
2782 ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline);
2783
2784 switch (pipelineBindPoint) {
2785 case VK_PIPELINE_BIND_POINT_COMPUTE:
2786 cmd_buffer->compute_pipeline = pipeline;
2787 cmd_buffer->compute_dirty |= ANV_CMD_BUFFER_PIPELINE_DIRTY;
2788 break;
2789
2790 case VK_PIPELINE_BIND_POINT_GRAPHICS:
2791 cmd_buffer->pipeline = pipeline;
2792 cmd_buffer->vb_dirty |= pipeline->vb_used;
2793 cmd_buffer->dirty |= ANV_CMD_BUFFER_PIPELINE_DIRTY;
2794 break;
2795
2796 default:
2797 assert(!"invalid bind point");
2798 break;
2799 }
2800 }
2801
2802 void anv_CmdBindDynamicStateObject(
2803 VkCmdBuffer cmdBuffer,
2804 VkStateBindPoint stateBindPoint,
2805 VkDynamicStateObject dynamicState)
2806 {
2807 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
2808
2809 switch (stateBindPoint) {
2810 case VK_STATE_BIND_POINT_VIEWPORT:
2811 cmd_buffer->vp_state = anv_dynamic_vp_state_from_handle(dynamicState);
2812 cmd_buffer->dirty |= ANV_CMD_BUFFER_VP_DIRTY;
2813 break;
2814 case VK_STATE_BIND_POINT_RASTER:
2815 cmd_buffer->rs_state = anv_dynamic_rs_state_from_handle(dynamicState);
2816 cmd_buffer->dirty |= ANV_CMD_BUFFER_RS_DIRTY;
2817 break;
2818 case VK_STATE_BIND_POINT_COLOR_BLEND:
2819 cmd_buffer->cb_state = anv_dynamic_cb_state_from_handle(dynamicState);
2820 cmd_buffer->dirty |= ANV_CMD_BUFFER_CB_DIRTY;
2821 break;
2822 case VK_STATE_BIND_POINT_DEPTH_STENCIL:
2823 cmd_buffer->ds_state = anv_dynamic_ds_state_from_handle(dynamicState);
2824 cmd_buffer->dirty |= ANV_CMD_BUFFER_DS_DIRTY;
2825 break;
2826 default:
2827 break;
2828 };
2829 }
2830
2831 static struct anv_state
2832 anv_cmd_buffer_alloc_surface_state(struct anv_cmd_buffer *cmd_buffer,
2833 uint32_t size, uint32_t alignment)
2834 {
2835 struct anv_state state;
2836
2837 state.offset = align_u32(cmd_buffer->surface_next, alignment);
2838 if (state.offset + size > cmd_buffer->surface_batch_bo->bo.size)
2839 return (struct anv_state) { 0 };
2840
2841 state.map = cmd_buffer->surface_batch_bo->bo.map + state.offset;
2842 state.alloc_size = size;
2843 cmd_buffer->surface_next = state.offset + size;
2844
2845 assert(state.offset + size <= cmd_buffer->surface_batch_bo->bo.size);
2846
2847 return state;
2848 }
2849
2850 static VkResult
2851 anv_cmd_buffer_new_surface_state_bo(struct anv_cmd_buffer *cmd_buffer)
2852 {
2853 struct anv_batch_bo *new_bbo, *old_bbo = cmd_buffer->surface_batch_bo;
2854
2855 /* Finish off the old buffer */
2856 old_bbo->num_relocs =
2857 cmd_buffer->surface_relocs.num_relocs - old_bbo->first_reloc;
2858 old_bbo->length = cmd_buffer->surface_next;
2859
2860 VkResult result = anv_batch_bo_create(cmd_buffer->device, &new_bbo);
2861 if (result != VK_SUCCESS)
2862 return result;
2863
2864 new_bbo->first_reloc = cmd_buffer->surface_relocs.num_relocs;
2865 cmd_buffer->surface_next = 1;
2866
2867 new_bbo->prev_batch_bo = old_bbo;
2868 cmd_buffer->surface_batch_bo = new_bbo;
2869
2870 /* Re-emit state base addresses so we get the new surface state base
2871 * address before we start emitting binding tables etc.
2872 */
2873 anv_cmd_buffer_emit_state_base_address(cmd_buffer);
2874
2875 /* It seems like just changing the state base addresses isn't enough.
2876 * Invalidating the cache seems to be enough to cause things to
2877 * propagate. However, I'm not 100% sure what we're supposed to do.
2878 */
2879 anv_batch_emit(&cmd_buffer->batch, GEN8_PIPE_CONTROL,
2880 .TextureCacheInvalidationEnable = true);
2881
2882 return VK_SUCCESS;
2883 }
2884
2885 void anv_CmdBindDescriptorSets(
2886 VkCmdBuffer cmdBuffer,
2887 VkPipelineBindPoint pipelineBindPoint,
2888 VkPipelineLayout _layout,
2889 uint32_t firstSet,
2890 uint32_t setCount,
2891 const VkDescriptorSet* pDescriptorSets,
2892 uint32_t dynamicOffsetCount,
2893 const uint32_t* pDynamicOffsets)
2894 {
2895 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
2896 ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
2897 struct anv_descriptor_set_layout *set_layout;
2898
2899 assert(firstSet + setCount < MAX_SETS);
2900
2901 uint32_t dynamic_slot = 0;
2902 for (uint32_t i = 0; i < setCount; i++) {
2903 ANV_FROM_HANDLE(anv_descriptor_set, set, pDescriptorSets[i]);
2904 set_layout = layout->set[firstSet + i].layout;
2905
2906 cmd_buffer->descriptors[firstSet + i].set = set;
2907
2908 assert(set_layout->num_dynamic_buffers <
2909 ARRAY_SIZE(cmd_buffer->descriptors[0].dynamic_offsets));
2910 memcpy(cmd_buffer->descriptors[firstSet + i].dynamic_offsets,
2911 pDynamicOffsets + dynamic_slot,
2912 set_layout->num_dynamic_buffers * sizeof(*pDynamicOffsets));
2913
2914 cmd_buffer->descriptors_dirty |= set_layout->shader_stages;
2915
2916 dynamic_slot += set_layout->num_dynamic_buffers;
2917 }
2918 }
2919
2920 void anv_CmdBindIndexBuffer(
2921 VkCmdBuffer cmdBuffer,
2922 VkBuffer _buffer,
2923 VkDeviceSize offset,
2924 VkIndexType indexType)
2925 {
2926 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
2927 ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
2928
2929 static const uint32_t vk_to_gen_index_type[] = {
2930 [VK_INDEX_TYPE_UINT16] = INDEX_WORD,
2931 [VK_INDEX_TYPE_UINT32] = INDEX_DWORD,
2932 };
2933
2934 struct GEN8_3DSTATE_VF vf = {
2935 GEN8_3DSTATE_VF_header,
2936 .CutIndex = (indexType == VK_INDEX_TYPE_UINT16) ? UINT16_MAX : UINT32_MAX,
2937 };
2938 GEN8_3DSTATE_VF_pack(NULL, cmd_buffer->state_vf, &vf);
2939
2940 cmd_buffer->dirty |= ANV_CMD_BUFFER_INDEX_BUFFER_DIRTY;
2941
2942 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_INDEX_BUFFER,
2943 .IndexFormat = vk_to_gen_index_type[indexType],
2944 .MemoryObjectControlState = GEN8_MOCS,
2945 .BufferStartingAddress = { buffer->bo, buffer->offset + offset },
2946 .BufferSize = buffer->size - offset);
2947 }
2948
2949 void anv_CmdBindVertexBuffers(
2950 VkCmdBuffer cmdBuffer,
2951 uint32_t startBinding,
2952 uint32_t bindingCount,
2953 const VkBuffer* pBuffers,
2954 const VkDeviceSize* pOffsets)
2955 {
2956 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
2957 struct anv_vertex_binding *vb = cmd_buffer->vertex_bindings;
2958
2959 /* We have to defer setting up vertex buffer since we need the buffer
2960 * stride from the pipeline. */
2961
2962 assert(startBinding + bindingCount < MAX_VBS);
2963 for (uint32_t i = 0; i < bindingCount; i++) {
2964 vb[startBinding + i].buffer = anv_buffer_from_handle(pBuffers[i]);
2965 vb[startBinding + i].offset = pOffsets[i];
2966 cmd_buffer->vb_dirty |= 1 << (startBinding + i);
2967 }
2968 }
2969
2970 static VkResult
2971 cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
2972 unsigned stage, struct anv_state *bt_state)
2973 {
2974 struct anv_pipeline_layout *layout;
2975 uint32_t color_attachments, bias, size;
2976
2977 if (stage == VK_SHADER_STAGE_COMPUTE)
2978 layout = cmd_buffer->compute_pipeline->layout;
2979 else
2980 layout = cmd_buffer->pipeline->layout;
2981
2982 if (stage == VK_SHADER_STAGE_FRAGMENT) {
2983 bias = MAX_RTS;
2984 color_attachments = cmd_buffer->framebuffer->color_attachment_count;
2985 } else {
2986 bias = 0;
2987 color_attachments = 0;
2988 }
2989
2990 /* This is a little awkward: layout can be NULL but we still have to
2991 * allocate and set a binding table for the PS stage for render
2992 * targets. */
2993 uint32_t surface_count = layout ? layout->stage[stage].surface_count : 0;
2994
2995 if (color_attachments + surface_count == 0)
2996 return VK_SUCCESS;
2997
2998 size = (bias + surface_count) * sizeof(uint32_t);
2999 *bt_state = anv_cmd_buffer_alloc_surface_state(cmd_buffer, size, 32);
3000 uint32_t *bt_map = bt_state->map;
3001
3002 if (bt_state->map == NULL)
3003 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
3004
3005 for (uint32_t ca = 0; ca < color_attachments; ca++) {
3006 const struct anv_surface_view *view =
3007 cmd_buffer->framebuffer->color_attachments[ca];
3008
3009 struct anv_state state =
3010 anv_cmd_buffer_alloc_surface_state(cmd_buffer, 64, 64);
3011
3012 if (state.map == NULL)
3013 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
3014
3015 memcpy(state.map, view->surface_state.map, 64);
3016
3017 /* The address goes in dwords 8 and 9 of the SURFACE_STATE */
3018 *(uint64_t *)(state.map + 8 * 4) =
3019 anv_reloc_list_add(&cmd_buffer->surface_relocs,
3020 cmd_buffer->device,
3021 state.offset + 8 * 4,
3022 view->bo, view->offset);
3023
3024 bt_map[ca] = state.offset;
3025 }
3026
3027 if (layout == NULL)
3028 return VK_SUCCESS;
3029
3030 for (uint32_t set = 0; set < layout->num_sets; set++) {
3031 struct anv_descriptor_set_binding *d = &cmd_buffer->descriptors[set];
3032 struct anv_descriptor_set_layout *set_layout = layout->set[set].layout;
3033 struct anv_descriptor_slot *surface_slots =
3034 set_layout->stage[stage].surface_start;
3035
3036 uint32_t start = bias + layout->set[set].surface_start[stage];
3037
3038 for (uint32_t b = 0; b < set_layout->stage[stage].surface_count; b++) {
3039 struct anv_surface_view *view =
3040 d->set->descriptors[surface_slots[b].index].view;
3041
3042 if (!view)
3043 continue;
3044
3045 struct anv_state state =
3046 anv_cmd_buffer_alloc_surface_state(cmd_buffer, 64, 64);
3047
3048 if (state.map == NULL)
3049 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
3050
3051 uint32_t offset;
3052 if (surface_slots[b].dynamic_slot >= 0) {
3053 uint32_t dynamic_offset =
3054 d->dynamic_offsets[surface_slots[b].dynamic_slot];
3055
3056 offset = view->offset + dynamic_offset;
3057 fill_buffer_surface_state(state.map, view->format, offset,
3058 view->range - dynamic_offset);
3059 } else {
3060 offset = view->offset;
3061 memcpy(state.map, view->surface_state.map, 64);
3062 }
3063
3064 /* The address goes in dwords 8 and 9 of the SURFACE_STATE */
3065 *(uint64_t *)(state.map + 8 * 4) =
3066 anv_reloc_list_add(&cmd_buffer->surface_relocs,
3067 cmd_buffer->device,
3068 state.offset + 8 * 4,
3069 view->bo, offset);
3070
3071 bt_map[start + b] = state.offset;
3072 }
3073 }
3074
3075 return VK_SUCCESS;
3076 }
3077
3078 static VkResult
3079 cmd_buffer_emit_samplers(struct anv_cmd_buffer *cmd_buffer,
3080 unsigned stage, struct anv_state *state)
3081 {
3082 struct anv_pipeline_layout *layout;
3083 uint32_t sampler_count;
3084
3085 if (stage == VK_SHADER_STAGE_COMPUTE)
3086 layout = cmd_buffer->compute_pipeline->layout;
3087 else
3088 layout = cmd_buffer->pipeline->layout;
3089
3090 sampler_count = layout ? layout->stage[stage].sampler_count : 0;
3091 if (sampler_count == 0)
3092 return VK_SUCCESS;
3093
3094 uint32_t size = sampler_count * 16;
3095 *state = anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream, size, 32);
3096
3097 if (state->map == NULL)
3098 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
3099
3100 for (uint32_t set = 0; set < layout->num_sets; set++) {
3101 struct anv_descriptor_set_binding *d = &cmd_buffer->descriptors[set];
3102 struct anv_descriptor_set_layout *set_layout = layout->set[set].layout;
3103 struct anv_descriptor_slot *sampler_slots =
3104 set_layout->stage[stage].sampler_start;
3105
3106 uint32_t start = layout->set[set].sampler_start[stage];
3107
3108 for (uint32_t b = 0; b < set_layout->stage[stage].sampler_count; b++) {
3109 struct anv_sampler *sampler =
3110 d->set->descriptors[sampler_slots[b].index].sampler;
3111
3112 if (!sampler)
3113 continue;
3114
3115 memcpy(state->map + (start + b) * 16,
3116 sampler->state, sizeof(sampler->state));
3117 }
3118 }
3119
3120 return VK_SUCCESS;
3121 }
3122
3123 static VkResult
3124 flush_descriptor_set(struct anv_cmd_buffer *cmd_buffer, uint32_t stage)
3125 {
3126 struct anv_state surfaces = { 0, }, samplers = { 0, };
3127 VkResult result;
3128
3129 result = cmd_buffer_emit_samplers(cmd_buffer, stage, &samplers);
3130 if (result != VK_SUCCESS)
3131 return result;
3132 result = cmd_buffer_emit_binding_table(cmd_buffer, stage, &surfaces);
3133 if (result != VK_SUCCESS)
3134 return result;
3135
3136 static const uint32_t sampler_state_opcodes[] = {
3137 [VK_SHADER_STAGE_VERTEX] = 43,
3138 [VK_SHADER_STAGE_TESS_CONTROL] = 44, /* HS */
3139 [VK_SHADER_STAGE_TESS_EVALUATION] = 45, /* DS */
3140 [VK_SHADER_STAGE_GEOMETRY] = 46,
3141 [VK_SHADER_STAGE_FRAGMENT] = 47,
3142 [VK_SHADER_STAGE_COMPUTE] = 0,
3143 };
3144
3145 static const uint32_t binding_table_opcodes[] = {
3146 [VK_SHADER_STAGE_VERTEX] = 38,
3147 [VK_SHADER_STAGE_TESS_CONTROL] = 39,
3148 [VK_SHADER_STAGE_TESS_EVALUATION] = 40,
3149 [VK_SHADER_STAGE_GEOMETRY] = 41,
3150 [VK_SHADER_STAGE_FRAGMENT] = 42,
3151 [VK_SHADER_STAGE_COMPUTE] = 0,
3152 };
3153
3154 if (samplers.alloc_size > 0) {
3155 anv_batch_emit(&cmd_buffer->batch,
3156 GEN8_3DSTATE_SAMPLER_STATE_POINTERS_VS,
3157 ._3DCommandSubOpcode = sampler_state_opcodes[stage],
3158 .PointertoVSSamplerState = samplers.offset);
3159 }
3160
3161 if (surfaces.alloc_size > 0) {
3162 anv_batch_emit(&cmd_buffer->batch,
3163 GEN8_3DSTATE_BINDING_TABLE_POINTERS_VS,
3164 ._3DCommandSubOpcode = binding_table_opcodes[stage],
3165 .PointertoVSBindingTable = surfaces.offset);
3166 }
3167
3168 return VK_SUCCESS;
3169 }
3170
3171 static void
3172 flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer)
3173 {
3174 uint32_t s, dirty = cmd_buffer->descriptors_dirty &
3175 cmd_buffer->pipeline->active_stages;
3176
3177 VkResult result = VK_SUCCESS;
3178 for_each_bit(s, dirty) {
3179 result = flush_descriptor_set(cmd_buffer, s);
3180 if (result != VK_SUCCESS)
3181 break;
3182 }
3183
3184 if (result != VK_SUCCESS) {
3185 assert(result == VK_ERROR_OUT_OF_DEVICE_MEMORY);
3186
3187 result = anv_cmd_buffer_new_surface_state_bo(cmd_buffer);
3188 assert(result == VK_SUCCESS);
3189
3190 /* Re-emit all active binding tables */
3191 for_each_bit(s, cmd_buffer->pipeline->active_stages) {
3192 result = flush_descriptor_set(cmd_buffer, s);
3193
3194 /* It had better succeed this time */
3195 assert(result == VK_SUCCESS);
3196 }
3197 }
3198
3199 cmd_buffer->descriptors_dirty &= ~cmd_buffer->pipeline->active_stages;
3200 }
3201
3202 static struct anv_state
3203 anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer *cmd_buffer,
3204 uint32_t *a, uint32_t dwords, uint32_t alignment)
3205 {
3206 struct anv_state state;
3207
3208 state = anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream,
3209 dwords * 4, alignment);
3210 memcpy(state.map, a, dwords * 4);
3211
3212 VG(VALGRIND_CHECK_MEM_IS_DEFINED(state.map, dwords * 4));
3213
3214 return state;
3215 }
3216
3217 static struct anv_state
3218 anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer *cmd_buffer,
3219 uint32_t *a, uint32_t *b,
3220 uint32_t dwords, uint32_t alignment)
3221 {
3222 struct anv_state state;
3223 uint32_t *p;
3224
3225 state = anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream,
3226 dwords * 4, alignment);
3227 p = state.map;
3228 for (uint32_t i = 0; i < dwords; i++)
3229 p[i] = a[i] | b[i];
3230
3231 VG(VALGRIND_CHECK_MEM_IS_DEFINED(p, dwords * 4));
3232
3233 return state;
3234 }
3235
3236 static VkResult
3237 flush_compute_descriptor_set(struct anv_cmd_buffer *cmd_buffer)
3238 {
3239 struct anv_device *device = cmd_buffer->device;
3240 struct anv_pipeline *pipeline = cmd_buffer->compute_pipeline;
3241 struct anv_state surfaces = { 0, }, samplers = { 0, };
3242 VkResult result;
3243
3244 result = cmd_buffer_emit_samplers(cmd_buffer,
3245 VK_SHADER_STAGE_COMPUTE, &samplers);
3246 if (result != VK_SUCCESS)
3247 return result;
3248 result = cmd_buffer_emit_binding_table(cmd_buffer,
3249 VK_SHADER_STAGE_COMPUTE, &surfaces);
3250 if (result != VK_SUCCESS)
3251 return result;
3252
3253 struct GEN8_INTERFACE_DESCRIPTOR_DATA desc = {
3254 .KernelStartPointer = pipeline->cs_simd,
3255 .KernelStartPointerHigh = 0,
3256 .BindingTablePointer = surfaces.offset,
3257 .BindingTableEntryCount = 0,
3258 .SamplerStatePointer = samplers.offset,
3259 .SamplerCount = 0,
3260 .NumberofThreadsinGPGPUThreadGroup = 0 /* FIXME: Really? */
3261 };
3262
3263 uint32_t size = GEN8_INTERFACE_DESCRIPTOR_DATA_length * sizeof(uint32_t);
3264 struct anv_state state =
3265 anv_state_pool_alloc(&device->dynamic_state_pool, size, 64);
3266
3267 GEN8_INTERFACE_DESCRIPTOR_DATA_pack(NULL, state.map, &desc);
3268
3269 anv_batch_emit(&cmd_buffer->batch, GEN8_MEDIA_INTERFACE_DESCRIPTOR_LOAD,
3270 .InterfaceDescriptorTotalLength = size,
3271 .InterfaceDescriptorDataStartAddress = state.offset);
3272
3273 return VK_SUCCESS;
3274 }
3275
3276 static void
3277 anv_cmd_buffer_flush_compute_state(struct anv_cmd_buffer *cmd_buffer)
3278 {
3279 struct anv_pipeline *pipeline = cmd_buffer->compute_pipeline;
3280 VkResult result;
3281
3282 assert(pipeline->active_stages == VK_SHADER_STAGE_COMPUTE_BIT);
3283
3284 if (cmd_buffer->current_pipeline != GPGPU) {
3285 anv_batch_emit(&cmd_buffer->batch, GEN8_PIPELINE_SELECT,
3286 .PipelineSelection = GPGPU);
3287 cmd_buffer->current_pipeline = GPGPU;
3288 }
3289
3290 if (cmd_buffer->compute_dirty & ANV_CMD_BUFFER_PIPELINE_DIRTY)
3291 anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->batch);
3292
3293 if ((cmd_buffer->descriptors_dirty & VK_SHADER_STAGE_COMPUTE_BIT) ||
3294 (cmd_buffer->compute_dirty & ANV_CMD_BUFFER_PIPELINE_DIRTY)) {
3295 result = flush_compute_descriptor_set(cmd_buffer);
3296 if (result != VK_SUCCESS) {
3297 result = anv_cmd_buffer_new_surface_state_bo(cmd_buffer);
3298 assert(result == VK_SUCCESS);
3299 result = flush_compute_descriptor_set(cmd_buffer);
3300 assert(result == VK_SUCCESS);
3301 }
3302 cmd_buffer->descriptors_dirty &= ~VK_SHADER_STAGE_COMPUTE;
3303 }
3304
3305 cmd_buffer->compute_dirty = 0;
3306 }
3307
3308 static void
3309 anv_cmd_buffer_flush_state(struct anv_cmd_buffer *cmd_buffer)
3310 {
3311 struct anv_pipeline *pipeline = cmd_buffer->pipeline;
3312 uint32_t *p;
3313
3314 uint32_t vb_emit = cmd_buffer->vb_dirty & pipeline->vb_used;
3315
3316 assert((pipeline->active_stages & VK_SHADER_STAGE_COMPUTE_BIT) == 0);
3317
3318 if (cmd_buffer->current_pipeline != _3D) {
3319 anv_batch_emit(&cmd_buffer->batch, GEN8_PIPELINE_SELECT,
3320 .PipelineSelection = _3D);
3321 cmd_buffer->current_pipeline = _3D;
3322 }
3323
3324 if (vb_emit) {
3325 const uint32_t num_buffers = __builtin_popcount(vb_emit);
3326 const uint32_t num_dwords = 1 + num_buffers * 4;
3327
3328 p = anv_batch_emitn(&cmd_buffer->batch, num_dwords,
3329 GEN8_3DSTATE_VERTEX_BUFFERS);
3330 uint32_t vb, i = 0;
3331 for_each_bit(vb, vb_emit) {
3332 struct anv_buffer *buffer = cmd_buffer->vertex_bindings[vb].buffer;
3333 uint32_t offset = cmd_buffer->vertex_bindings[vb].offset;
3334
3335 struct GEN8_VERTEX_BUFFER_STATE state = {
3336 .VertexBufferIndex = vb,
3337 .MemoryObjectControlState = GEN8_MOCS,
3338 .AddressModifyEnable = true,
3339 .BufferPitch = pipeline->binding_stride[vb],
3340 .BufferStartingAddress = { buffer->bo, buffer->offset + offset },
3341 .BufferSize = buffer->size - offset
3342 };
3343
3344 GEN8_VERTEX_BUFFER_STATE_pack(&cmd_buffer->batch, &p[1 + i * 4], &state);
3345 i++;
3346 }
3347 }
3348
3349 if (cmd_buffer->dirty & ANV_CMD_BUFFER_PIPELINE_DIRTY) {
3350 /* If somebody compiled a pipeline after starting a command buffer the
3351 * scratch bo may have grown since we started this cmd buffer (and
3352 * emitted STATE_BASE_ADDRESS). If we're binding that pipeline now,
3353 * reemit STATE_BASE_ADDRESS so that we use the bigger scratch bo. */
3354 if (cmd_buffer->scratch_size < pipeline->total_scratch)
3355 anv_cmd_buffer_emit_state_base_address(cmd_buffer);
3356
3357 anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->batch);
3358 }
3359
3360 if (cmd_buffer->descriptors_dirty)
3361 flush_descriptor_sets(cmd_buffer);
3362
3363 if (cmd_buffer->dirty & ANV_CMD_BUFFER_VP_DIRTY) {
3364 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_SCISSOR_STATE_POINTERS,
3365 .ScissorRectPointer = cmd_buffer->vp_state->scissor.offset);
3366 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_CC,
3367 .CCViewportPointer = cmd_buffer->vp_state->cc_vp.offset);
3368 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP,
3369 .SFClipViewportPointer = cmd_buffer->vp_state->sf_clip_vp.offset);
3370 }
3371
3372 if (cmd_buffer->dirty & (ANV_CMD_BUFFER_PIPELINE_DIRTY | ANV_CMD_BUFFER_RS_DIRTY)) {
3373 anv_batch_emit_merge(&cmd_buffer->batch,
3374 cmd_buffer->rs_state->state_sf, pipeline->state_sf);
3375 anv_batch_emit_merge(&cmd_buffer->batch,
3376 cmd_buffer->rs_state->state_raster, pipeline->state_raster);
3377 }
3378
3379 if (cmd_buffer->ds_state &&
3380 (cmd_buffer->dirty & (ANV_CMD_BUFFER_PIPELINE_DIRTY | ANV_CMD_BUFFER_DS_DIRTY)))
3381 anv_batch_emit_merge(&cmd_buffer->batch,
3382 cmd_buffer->ds_state->state_wm_depth_stencil,
3383 pipeline->state_wm_depth_stencil);
3384
3385 if (cmd_buffer->dirty & (ANV_CMD_BUFFER_CB_DIRTY | ANV_CMD_BUFFER_DS_DIRTY)) {
3386 struct anv_state state;
3387 if (cmd_buffer->ds_state == NULL)
3388 state = anv_cmd_buffer_emit_dynamic(cmd_buffer,
3389 cmd_buffer->cb_state->state_color_calc,
3390 GEN8_COLOR_CALC_STATE_length, 64);
3391 else if (cmd_buffer->cb_state == NULL)
3392 state = anv_cmd_buffer_emit_dynamic(cmd_buffer,
3393 cmd_buffer->ds_state->state_color_calc,
3394 GEN8_COLOR_CALC_STATE_length, 64);
3395 else
3396 state = anv_cmd_buffer_merge_dynamic(cmd_buffer,
3397 cmd_buffer->ds_state->state_color_calc,
3398 cmd_buffer->cb_state->state_color_calc,
3399 GEN8_COLOR_CALC_STATE_length, 64);
3400
3401 anv_batch_emit(&cmd_buffer->batch,
3402 GEN8_3DSTATE_CC_STATE_POINTERS,
3403 .ColorCalcStatePointer = state.offset,
3404 .ColorCalcStatePointerValid = true);
3405 }
3406
3407 if (cmd_buffer->dirty & (ANV_CMD_BUFFER_PIPELINE_DIRTY | ANV_CMD_BUFFER_INDEX_BUFFER_DIRTY)) {
3408 anv_batch_emit_merge(&cmd_buffer->batch,
3409 cmd_buffer->state_vf, pipeline->state_vf);
3410 }
3411
3412 cmd_buffer->vb_dirty &= ~vb_emit;
3413 cmd_buffer->dirty = 0;
3414 }
3415
3416 void anv_CmdDraw(
3417 VkCmdBuffer cmdBuffer,
3418 uint32_t firstVertex,
3419 uint32_t vertexCount,
3420 uint32_t firstInstance,
3421 uint32_t instanceCount)
3422 {
3423 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
3424
3425 anv_cmd_buffer_flush_state(cmd_buffer);
3426
3427 anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
3428 .VertexAccessType = SEQUENTIAL,
3429 .VertexCountPerInstance = vertexCount,
3430 .StartVertexLocation = firstVertex,
3431 .InstanceCount = instanceCount,
3432 .StartInstanceLocation = firstInstance,
3433 .BaseVertexLocation = 0);
3434 }
3435
3436 void anv_CmdDrawIndexed(
3437 VkCmdBuffer cmdBuffer,
3438 uint32_t firstIndex,
3439 uint32_t indexCount,
3440 int32_t vertexOffset,
3441 uint32_t firstInstance,
3442 uint32_t instanceCount)
3443 {
3444 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
3445
3446 anv_cmd_buffer_flush_state(cmd_buffer);
3447
3448 anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
3449 .VertexAccessType = RANDOM,
3450 .VertexCountPerInstance = indexCount,
3451 .StartVertexLocation = firstIndex,
3452 .InstanceCount = instanceCount,
3453 .StartInstanceLocation = firstInstance,
3454 .BaseVertexLocation = vertexOffset);
3455 }
3456
3457 static void
3458 anv_batch_lrm(struct anv_batch *batch,
3459 uint32_t reg, struct anv_bo *bo, uint32_t offset)
3460 {
3461 anv_batch_emit(batch, GEN8_MI_LOAD_REGISTER_MEM,
3462 .RegisterAddress = reg,
3463 .MemoryAddress = { bo, offset });
3464 }
3465
3466 static void
3467 anv_batch_lri(struct anv_batch *batch, uint32_t reg, uint32_t imm)
3468 {
3469 anv_batch_emit(batch, GEN8_MI_LOAD_REGISTER_IMM,
3470 .RegisterOffset = reg,
3471 .DataDWord = imm);
3472 }
3473
3474 /* Auto-Draw / Indirect Registers */
3475 #define GEN7_3DPRIM_END_OFFSET 0x2420
3476 #define GEN7_3DPRIM_START_VERTEX 0x2430
3477 #define GEN7_3DPRIM_VERTEX_COUNT 0x2434
3478 #define GEN7_3DPRIM_INSTANCE_COUNT 0x2438
3479 #define GEN7_3DPRIM_START_INSTANCE 0x243C
3480 #define GEN7_3DPRIM_BASE_VERTEX 0x2440
3481
3482 void anv_CmdDrawIndirect(
3483 VkCmdBuffer cmdBuffer,
3484 VkBuffer _buffer,
3485 VkDeviceSize offset,
3486 uint32_t count,
3487 uint32_t stride)
3488 {
3489 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
3490 ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
3491 struct anv_bo *bo = buffer->bo;
3492 uint32_t bo_offset = buffer->offset + offset;
3493
3494 anv_cmd_buffer_flush_state(cmd_buffer);
3495
3496 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
3497 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
3498 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);
3499 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_INSTANCE, bo, bo_offset + 12);
3500 anv_batch_lri(&cmd_buffer->batch, GEN7_3DPRIM_BASE_VERTEX, 0);
3501
3502 anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
3503 .IndirectParameterEnable = true,
3504 .VertexAccessType = SEQUENTIAL);
3505 }
3506
3507 void anv_CmdDrawIndexedIndirect(
3508 VkCmdBuffer cmdBuffer,
3509 VkBuffer _buffer,
3510 VkDeviceSize offset,
3511 uint32_t count,
3512 uint32_t stride)
3513 {
3514 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
3515 ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
3516 struct anv_bo *bo = buffer->bo;
3517 uint32_t bo_offset = buffer->offset + offset;
3518
3519 anv_cmd_buffer_flush_state(cmd_buffer);
3520
3521 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
3522 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
3523 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);
3524 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_BASE_VERTEX, bo, bo_offset + 12);
3525 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_INSTANCE, bo, bo_offset + 16);
3526
3527 anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
3528 .IndirectParameterEnable = true,
3529 .VertexAccessType = RANDOM);
3530 }
3531
3532 void anv_CmdDispatch(
3533 VkCmdBuffer cmdBuffer,
3534 uint32_t x,
3535 uint32_t y,
3536 uint32_t z)
3537 {
3538 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
3539 struct anv_pipeline *pipeline = cmd_buffer->compute_pipeline;
3540 struct brw_cs_prog_data *prog_data = &pipeline->cs_prog_data;
3541
3542 anv_cmd_buffer_flush_compute_state(cmd_buffer);
3543
3544 anv_batch_emit(&cmd_buffer->batch, GEN8_GPGPU_WALKER,
3545 .SIMDSize = prog_data->simd_size / 16,
3546 .ThreadDepthCounterMaximum = 0,
3547 .ThreadHeightCounterMaximum = 0,
3548 .ThreadWidthCounterMaximum = pipeline->cs_thread_width_max,
3549 .ThreadGroupIDXDimension = x,
3550 .ThreadGroupIDYDimension = y,
3551 .ThreadGroupIDZDimension = z,
3552 .RightExecutionMask = pipeline->cs_right_mask,
3553 .BottomExecutionMask = 0xffffffff);
3554
3555 anv_batch_emit(&cmd_buffer->batch, GEN8_MEDIA_STATE_FLUSH);
3556 }
3557
3558 #define GPGPU_DISPATCHDIMX 0x2500
3559 #define GPGPU_DISPATCHDIMY 0x2504
3560 #define GPGPU_DISPATCHDIMZ 0x2508
3561
3562 void anv_CmdDispatchIndirect(
3563 VkCmdBuffer cmdBuffer,
3564 VkBuffer _buffer,
3565 VkDeviceSize offset)
3566 {
3567 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
3568 ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
3569 struct anv_pipeline *pipeline = cmd_buffer->compute_pipeline;
3570 struct brw_cs_prog_data *prog_data = &pipeline->cs_prog_data;
3571 struct anv_bo *bo = buffer->bo;
3572 uint32_t bo_offset = buffer->offset + offset;
3573
3574 anv_cmd_buffer_flush_compute_state(cmd_buffer);
3575
3576 anv_batch_lrm(&cmd_buffer->batch, GPGPU_DISPATCHDIMX, bo, bo_offset);
3577 anv_batch_lrm(&cmd_buffer->batch, GPGPU_DISPATCHDIMY, bo, bo_offset + 4);
3578 anv_batch_lrm(&cmd_buffer->batch, GPGPU_DISPATCHDIMZ, bo, bo_offset + 8);
3579
3580 anv_batch_emit(&cmd_buffer->batch, GEN8_GPGPU_WALKER,
3581 .IndirectParameterEnable = true,
3582 .SIMDSize = prog_data->simd_size / 16,
3583 .ThreadDepthCounterMaximum = 0,
3584 .ThreadHeightCounterMaximum = 0,
3585 .ThreadWidthCounterMaximum = pipeline->cs_thread_width_max,
3586 .RightExecutionMask = pipeline->cs_right_mask,
3587 .BottomExecutionMask = 0xffffffff);
3588
3589 anv_batch_emit(&cmd_buffer->batch, GEN8_MEDIA_STATE_FLUSH);
3590 }
3591
3592 void anv_CmdSetEvent(
3593 VkCmdBuffer cmdBuffer,
3594 VkEvent event,
3595 VkPipeEvent pipeEvent)
3596 {
3597 stub();
3598 }
3599
3600 void anv_CmdResetEvent(
3601 VkCmdBuffer cmdBuffer,
3602 VkEvent event,
3603 VkPipeEvent pipeEvent)
3604 {
3605 stub();
3606 }
3607
3608 void anv_CmdWaitEvents(
3609 VkCmdBuffer cmdBuffer,
3610 VkWaitEvent waitEvent,
3611 uint32_t eventCount,
3612 const VkEvent* pEvents,
3613 VkPipeEventFlags pipeEventMask,
3614 uint32_t memBarrierCount,
3615 const void* const* ppMemBarriers)
3616 {
3617 stub();
3618 }
3619
3620 void anv_CmdPipelineBarrier(
3621 VkCmdBuffer cmdBuffer,
3622 VkWaitEvent waitEvent,
3623 VkPipeEventFlags pipeEventMask,
3624 uint32_t memBarrierCount,
3625 const void* const* ppMemBarriers)
3626 {
3627 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
3628 uint32_t b, *dw;
3629
3630 struct GEN8_PIPE_CONTROL cmd = {
3631 GEN8_PIPE_CONTROL_header,
3632 .PostSyncOperation = NoWrite,
3633 };
3634
3635 /* XXX: I think waitEvent is a no-op on our HW. We should verify that. */
3636
3637 if (anv_clear_mask(&pipeEventMask, VK_PIPE_EVENT_TOP_OF_PIPE_BIT)) {
3638 /* This is just what PIPE_CONTROL does */
3639 }
3640
3641 if (anv_clear_mask(&pipeEventMask,
3642 VK_PIPE_EVENT_VERTEX_PROCESSING_COMPLETE_BIT |
3643 VK_PIPE_EVENT_LOCAL_FRAGMENT_PROCESSING_COMPLETE_BIT |
3644 VK_PIPE_EVENT_FRAGMENT_PROCESSING_COMPLETE_BIT)) {
3645 cmd.StallAtPixelScoreboard = true;
3646 }
3647
3648
3649 if (anv_clear_mask(&pipeEventMask,
3650 VK_PIPE_EVENT_GRAPHICS_PIPELINE_COMPLETE_BIT |
3651 VK_PIPE_EVENT_COMPUTE_PIPELINE_COMPLETE_BIT |
3652 VK_PIPE_EVENT_TRANSFER_COMPLETE_BIT |
3653 VK_PIPE_EVENT_COMMANDS_COMPLETE_BIT)) {
3654 cmd.CommandStreamerStallEnable = true;
3655 }
3656
3657 if (anv_clear_mask(&pipeEventMask, VK_PIPE_EVENT_CPU_SIGNAL_BIT)) {
3658 anv_finishme("VK_PIPE_EVENT_CPU_SIGNAL_BIT");
3659 }
3660
3661 /* We checked all known VkPipeEventFlags. */
3662 anv_assert(pipeEventMask == 0);
3663
3664 /* XXX: Right now, we're really dumb and just flush whatever categories
3665 * the app asks for. One of these days we may make this a bit better
3666 * but right now that's all the hardware allows for in most areas.
3667 */
3668 VkMemoryOutputFlags out_flags = 0;
3669 VkMemoryInputFlags in_flags = 0;
3670
3671 for (uint32_t i = 0; i < memBarrierCount; i++) {
3672 const struct anv_common *common = ppMemBarriers[i];
3673 switch (common->sType) {
3674 case VK_STRUCTURE_TYPE_MEMORY_BARRIER: {
3675 const VkMemoryBarrier *barrier = (VkMemoryBarrier *)common;
3676 out_flags |= barrier->outputMask;
3677 in_flags |= barrier->inputMask;
3678 break;
3679 }
3680 case VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER: {
3681 const VkBufferMemoryBarrier *barrier = (VkBufferMemoryBarrier *)common;
3682 out_flags |= barrier->outputMask;
3683 in_flags |= barrier->inputMask;
3684 break;
3685 }
3686 case VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER: {
3687 const VkImageMemoryBarrier *barrier = (VkImageMemoryBarrier *)common;
3688 out_flags |= barrier->outputMask;
3689 in_flags |= barrier->inputMask;
3690 break;
3691 }
3692 default:
3693 unreachable("Invalid memory barrier type");
3694 }
3695 }
3696
3697 for_each_bit(b, out_flags) {
3698 switch ((VkMemoryOutputFlags)(1 << b)) {
3699 case VK_MEMORY_OUTPUT_HOST_WRITE_BIT:
3700 break; /* FIXME: Little-core systems */
3701 case VK_MEMORY_OUTPUT_SHADER_WRITE_BIT:
3702 cmd.DCFlushEnable = true;
3703 break;
3704 case VK_MEMORY_OUTPUT_COLOR_ATTACHMENT_BIT:
3705 cmd.RenderTargetCacheFlushEnable = true;
3706 break;
3707 case VK_MEMORY_OUTPUT_DEPTH_STENCIL_ATTACHMENT_BIT:
3708 cmd.DepthCacheFlushEnable = true;
3709 break;
3710 case VK_MEMORY_OUTPUT_TRANSFER_BIT:
3711 cmd.RenderTargetCacheFlushEnable = true;
3712 cmd.DepthCacheFlushEnable = true;
3713 break;
3714 default:
3715 unreachable("Invalid memory output flag");
3716 }
3717 }
3718
3719 for_each_bit(b, out_flags) {
3720 switch ((VkMemoryInputFlags)(1 << b)) {
3721 case VK_MEMORY_INPUT_HOST_READ_BIT:
3722 break; /* FIXME: Little-core systems */
3723 case VK_MEMORY_INPUT_INDIRECT_COMMAND_BIT:
3724 case VK_MEMORY_INPUT_INDEX_FETCH_BIT:
3725 case VK_MEMORY_INPUT_VERTEX_ATTRIBUTE_FETCH_BIT:
3726 cmd.VFCacheInvalidationEnable = true;
3727 break;
3728 case VK_MEMORY_INPUT_UNIFORM_READ_BIT:
3729 cmd.ConstantCacheInvalidationEnable = true;
3730 /* fallthrough */
3731 case VK_MEMORY_INPUT_SHADER_READ_BIT:
3732 cmd.DCFlushEnable = true;
3733 cmd.TextureCacheInvalidationEnable = true;
3734 break;
3735 case VK_MEMORY_INPUT_COLOR_ATTACHMENT_BIT:
3736 case VK_MEMORY_INPUT_DEPTH_STENCIL_ATTACHMENT_BIT:
3737 break; /* XXX: Hunh? */
3738 case VK_MEMORY_INPUT_TRANSFER_BIT:
3739 cmd.TextureCacheInvalidationEnable = true;
3740 break;
3741 }
3742 }
3743
3744 dw = anv_batch_emit_dwords(&cmd_buffer->batch, GEN8_PIPE_CONTROL_length);
3745 GEN8_PIPE_CONTROL_pack(&cmd_buffer->batch, dw, &cmd);
3746 }
3747
3748 static void
3749 anv_framebuffer_destroy(struct anv_device *device,
3750 struct anv_object *object,
3751 VkObjectType obj_type)
3752 {
3753 struct anv_framebuffer *fb = (struct anv_framebuffer *)object;
3754
3755 assert(obj_type == VK_OBJECT_TYPE_FRAMEBUFFER);
3756
3757 anv_DestroyObject(anv_device_to_handle(device),
3758 VK_OBJECT_TYPE_DYNAMIC_VP_STATE,
3759 fb->vp_state);
3760
3761 anv_device_free(device, fb);
3762 }
3763
3764 VkResult anv_CreateFramebuffer(
3765 VkDevice _device,
3766 const VkFramebufferCreateInfo* pCreateInfo,
3767 VkFramebuffer* pFramebuffer)
3768 {
3769 ANV_FROM_HANDLE(anv_device, device, _device);
3770 struct anv_framebuffer *framebuffer;
3771
3772 static const struct anv_depth_stencil_view null_view =
3773 { .depth_format = D16_UNORM, .depth_stride = 0, .stencil_stride = 0 };
3774
3775 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO);
3776
3777 framebuffer = anv_device_alloc(device, sizeof(*framebuffer), 8,
3778 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
3779 if (framebuffer == NULL)
3780 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
3781
3782 framebuffer->base.destructor = anv_framebuffer_destroy;
3783
3784 framebuffer->color_attachment_count = pCreateInfo->colorAttachmentCount;
3785 for (uint32_t i = 0; i < pCreateInfo->colorAttachmentCount; i++) {
3786 framebuffer->color_attachments[i] =
3787 (struct anv_surface_view *) pCreateInfo->pColorAttachments[i].view;
3788 }
3789
3790 if (pCreateInfo->pDepthStencilAttachment) {
3791 framebuffer->depth_stencil =
3792 anv_depth_stencil_view_from_handle(pCreateInfo->pDepthStencilAttachment->view);
3793 } else {
3794 framebuffer->depth_stencil = &null_view;
3795 }
3796
3797 framebuffer->sample_count = pCreateInfo->sampleCount;
3798 framebuffer->width = pCreateInfo->width;
3799 framebuffer->height = pCreateInfo->height;
3800 framebuffer->layers = pCreateInfo->layers;
3801
3802 anv_CreateDynamicViewportState(anv_device_to_handle(device),
3803 &(VkDynamicViewportStateCreateInfo) {
3804 .sType = VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO,
3805 .viewportAndScissorCount = 1,
3806 .pViewports = (VkViewport[]) {
3807 {
3808 .originX = 0,
3809 .originY = 0,
3810 .width = pCreateInfo->width,
3811 .height = pCreateInfo->height,
3812 .minDepth = 0,
3813 .maxDepth = 1
3814 },
3815 },
3816 .pScissors = (VkRect2D[]) {
3817 { { 0, 0 },
3818 { pCreateInfo->width, pCreateInfo->height } },
3819 }
3820 },
3821 &framebuffer->vp_state);
3822
3823 *pFramebuffer = anv_framebuffer_to_handle(framebuffer);
3824
3825 return VK_SUCCESS;
3826 }
3827
3828 VkResult anv_CreateRenderPass(
3829 VkDevice _device,
3830 const VkRenderPassCreateInfo* pCreateInfo,
3831 VkRenderPass* pRenderPass)
3832 {
3833 ANV_FROM_HANDLE(anv_device, device, _device);
3834 struct anv_render_pass *pass;
3835 size_t size;
3836
3837 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO);
3838
3839 size = sizeof(*pass) +
3840 pCreateInfo->layers * sizeof(struct anv_render_pass_layer);
3841 pass = anv_device_alloc(device, size, 8,
3842 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
3843 if (pass == NULL)
3844 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
3845
3846 pass->render_area = pCreateInfo->renderArea;
3847
3848 pass->num_layers = pCreateInfo->layers;
3849
3850 pass->num_clear_layers = 0;
3851 for (uint32_t i = 0; i < pCreateInfo->layers; i++) {
3852 pass->layers[i].color_load_op = pCreateInfo->pColorLoadOps[i];
3853 pass->layers[i].clear_color = pCreateInfo->pColorLoadClearValues[i];
3854 if (pass->layers[i].color_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
3855 pass->num_clear_layers++;
3856 }
3857
3858 *pRenderPass = anv_render_pass_to_handle(pass);
3859
3860 return VK_SUCCESS;
3861 }
3862
3863 VkResult anv_DestroyRenderPass(
3864 VkDevice _device,
3865 VkRenderPass renderPass)
3866 {
3867 ANV_FROM_HANDLE(anv_device, device, _device);
3868
3869 anv_device_free(device, anv_render_pass_from_handle(renderPass));
3870
3871 return VK_SUCCESS;
3872 }
3873
3874 VkResult anv_GetRenderAreaGranularity(
3875 VkDevice device,
3876 VkRenderPass renderPass,
3877 VkExtent2D* pGranularity)
3878 {
3879 *pGranularity = (VkExtent2D) { 1, 1 };
3880
3881 return VK_SUCCESS;
3882 }
3883
3884 static void
3885 anv_cmd_buffer_emit_depth_stencil(struct anv_cmd_buffer *cmd_buffer,
3886 struct anv_render_pass *pass)
3887 {
3888 const struct anv_depth_stencil_view *view =
3889 cmd_buffer->framebuffer->depth_stencil;
3890
3891 /* FIXME: Implement the PMA stall W/A */
3892 /* FIXME: Width and Height are wrong */
3893
3894 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DEPTH_BUFFER,
3895 .SurfaceType = SURFTYPE_2D,
3896 .DepthWriteEnable = view->depth_stride > 0,
3897 .StencilWriteEnable = view->stencil_stride > 0,
3898 .HierarchicalDepthBufferEnable = false,
3899 .SurfaceFormat = view->depth_format,
3900 .SurfacePitch = view->depth_stride > 0 ? view->depth_stride - 1 : 0,
3901 .SurfaceBaseAddress = { view->bo, view->depth_offset },
3902 .Height = pass->render_area.extent.height - 1,
3903 .Width = pass->render_area.extent.width - 1,
3904 .LOD = 0,
3905 .Depth = 1 - 1,
3906 .MinimumArrayElement = 0,
3907 .DepthBufferObjectControlState = GEN8_MOCS,
3908 .RenderTargetViewExtent = 1 - 1,
3909 .SurfaceQPitch = view->depth_qpitch >> 2);
3910
3911 /* Disable hierarchial depth buffers. */
3912 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_HIER_DEPTH_BUFFER);
3913
3914 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_STENCIL_BUFFER,
3915 .StencilBufferEnable = view->stencil_stride > 0,
3916 .StencilBufferObjectControlState = GEN8_MOCS,
3917 .SurfacePitch = view->stencil_stride > 0 ? view->stencil_stride - 1 : 0,
3918 .SurfaceBaseAddress = { view->bo, view->stencil_offset },
3919 .SurfaceQPitch = view->stencil_qpitch >> 2);
3920
3921 /* Clear the clear params. */
3922 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_CLEAR_PARAMS);
3923 }
3924
3925 void anv_CmdPushConstants(
3926 VkCmdBuffer cmdBuffer,
3927 VkPipelineLayout layout,
3928 VkShaderStageFlags stageFlags,
3929 uint32_t start,
3930 uint32_t length,
3931 const void* values)
3932 {
3933 stub();
3934 }
3935
3936 void anv_CmdBeginRenderPass(
3937 VkCmdBuffer cmdBuffer,
3938 const VkRenderPassBegin* pRenderPassBegin)
3939 {
3940 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
3941 ANV_FROM_HANDLE(anv_render_pass, pass, pRenderPassBegin->renderPass);
3942 ANV_FROM_HANDLE(anv_framebuffer, framebuffer, pRenderPassBegin->framebuffer);
3943
3944 assert(pRenderPassBegin->contents == VK_RENDER_PASS_CONTENTS_INLINE);
3945
3946 cmd_buffer->framebuffer = framebuffer;
3947
3948 cmd_buffer->descriptors_dirty |= VK_SHADER_STAGE_FRAGMENT_BIT;
3949
3950 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DRAWING_RECTANGLE,
3951 .ClippedDrawingRectangleYMin = pass->render_area.offset.y,
3952 .ClippedDrawingRectangleXMin = pass->render_area.offset.x,
3953 .ClippedDrawingRectangleYMax =
3954 pass->render_area.offset.y + pass->render_area.extent.height - 1,
3955 .ClippedDrawingRectangleXMax =
3956 pass->render_area.offset.x + pass->render_area.extent.width - 1,
3957 .DrawingRectangleOriginY = 0,
3958 .DrawingRectangleOriginX = 0);
3959
3960 anv_cmd_buffer_emit_depth_stencil(cmd_buffer, pass);
3961
3962 anv_cmd_buffer_clear(cmd_buffer, pass);
3963 }
3964
3965 void anv_CmdEndRenderPass(
3966 VkCmdBuffer cmdBuffer)
3967 {
3968 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
3969
3970 /* Emit a flushing pipe control at the end of a pass. This is kind of a
3971 * hack but it ensures that render targets always actually get written.
3972 * Eventually, we should do flushing based on image format transitions
3973 * or something of that nature.
3974 */
3975 anv_batch_emit(&cmd_buffer->batch, GEN8_PIPE_CONTROL,
3976 .PostSyncOperation = NoWrite,
3977 .RenderTargetCacheFlushEnable = true,
3978 .InstructionCacheInvalidateEnable = true,
3979 .DepthCacheFlushEnable = true,
3980 .VFCacheInvalidationEnable = true,
3981 .TextureCacheInvalidationEnable = true,
3982 .CommandStreamerStallEnable = true);
3983 }
3984
3985 void anv_CmdExecuteCommands(
3986 VkCmdBuffer cmdBuffer,
3987 uint32_t cmdBuffersCount,
3988 const VkCmdBuffer* pCmdBuffers)
3989 {
3990 stub();
3991 }
3992
3993 void vkCmdDbgMarkerBegin(
3994 VkCmdBuffer cmdBuffer,
3995 const char* pMarker)
3996 __attribute__ ((visibility ("default")));
3997
3998 void vkCmdDbgMarkerEnd(
3999 VkCmdBuffer cmdBuffer)
4000 __attribute__ ((visibility ("default")));
4001
4002 VkResult vkDbgSetObjectTag(
4003 VkDevice device,
4004 VkObject object,
4005 size_t tagSize,
4006 const void* pTag)
4007 __attribute__ ((visibility ("default")));
4008
4009
4010 void vkCmdDbgMarkerBegin(
4011 VkCmdBuffer cmdBuffer,
4012 const char* pMarker)
4013 {
4014 }
4015
4016 void vkCmdDbgMarkerEnd(
4017 VkCmdBuffer cmdBuffer)
4018 {
4019 }
4020
4021 VkResult vkDbgSetObjectTag(
4022 VkDevice device,
4023 VkObject object,
4024 size_t tagSize,
4025 const void* pTag)
4026 {
4027 return VK_SUCCESS;
4028 }