vk: Split the dynamic state binding function into one per state
[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
1185 switch (objType) {
1186 case VK_OBJECT_TYPE_FENCE:
1187 return anv_DestroyFence(_device, (VkFence) _object);
1188
1189 case VK_OBJECT_TYPE_INSTANCE:
1190 return anv_DestroyInstance((VkInstance) _object);
1191
1192 case VK_OBJECT_TYPE_PHYSICAL_DEVICE:
1193 /* We don't want to actually destroy physical devices */
1194 return VK_SUCCESS;
1195
1196 case VK_OBJECT_TYPE_DEVICE:
1197 assert(_device == (VkDevice) _object);
1198 return anv_DestroyDevice((VkDevice) _object);
1199
1200 case VK_OBJECT_TYPE_QUEUE:
1201 /* TODO */
1202 return VK_SUCCESS;
1203
1204 case VK_OBJECT_TYPE_DEVICE_MEMORY:
1205 return anv_FreeMemory(_device, (VkDeviceMemory) _object);
1206
1207 case VK_OBJECT_TYPE_DESCRIPTOR_POOL:
1208 return anv_DestroyDescriptorPool(_device, (VkDescriptorPool) _object);
1209
1210 case VK_OBJECT_TYPE_PIPELINE_CACHE:
1211 return anv_DestroyPipelineCache(_device, (VkPipelineCache) _object);
1212
1213 case VK_OBJECT_TYPE_BUFFER_VIEW:
1214 return anv_DestroyBufferView(_device, _object);
1215
1216 case VK_OBJECT_TYPE_IMAGE_VIEW:
1217 return anv_DestroyImageView(_device, _object);
1218
1219 case VK_OBJECT_TYPE_ATTACHMENT_VIEW:
1220 return anv_DestroyAttachmentView(_device, _object);
1221
1222 case VK_OBJECT_TYPE_IMAGE:
1223 return anv_DestroyImage(_device, _object);
1224
1225 case VK_OBJECT_TYPE_BUFFER:
1226 return anv_DestroyBuffer(_device, (VkBuffer) _object);
1227
1228 case VK_OBJECT_TYPE_SHADER_MODULE:
1229 return anv_DestroyShaderModule(_device, (VkShaderModule) _object);
1230
1231 case VK_OBJECT_TYPE_SHADER:
1232 return anv_DestroyShader(_device, (VkShader) _object);
1233
1234 case VK_OBJECT_TYPE_PIPELINE_LAYOUT:
1235 return anv_DestroyPipelineLayout(_device, (VkPipelineLayout) _object);
1236
1237 case VK_OBJECT_TYPE_SAMPLER:
1238 return anv_DestroySampler(_device, (VkSampler) _object);
1239
1240 case VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT:
1241 return anv_DestroyDescriptorSetLayout(_device, (VkDescriptorSetLayout) _object);
1242
1243 case VK_OBJECT_TYPE_DESCRIPTOR_SET:
1244 case VK_OBJECT_TYPE_RENDER_PASS:
1245 /* These are trivially destroyable */
1246 anv_device_free(device, (void *) _object);
1247 return VK_SUCCESS;
1248
1249 case VK_OBJECT_TYPE_DYNAMIC_VP_STATE:
1250 return anv_DestroyDynamicViewportState(_device, (VkDynamicViewportState) _object);
1251
1252 case VK_OBJECT_TYPE_DYNAMIC_RS_STATE:
1253 return anv_DestroyDynamicRasterState(_device, (VkDynamicRasterState) _object);
1254
1255 case VK_OBJECT_TYPE_DYNAMIC_CB_STATE:
1256 return anv_DestroyDynamicColorBlendState(_device, (VkDynamicColorBlendState) _object);
1257
1258 case VK_OBJECT_TYPE_DYNAMIC_DS_STATE:
1259 return anv_DestroyDynamicDepthStencilState(_device, (VkDynamicDepthStencilState) _object);
1260
1261 case VK_OBJECT_TYPE_FRAMEBUFFER:
1262 return anv_DestroyFramebuffer(_device, (VkFramebuffer) _object);
1263
1264 case VK_OBJECT_TYPE_COMMAND_BUFFER:
1265 return anv_DestroyCommandBuffer(_device, (VkCmdBuffer) _object);
1266 return VK_SUCCESS;
1267
1268 case VK_OBJECT_TYPE_PIPELINE:
1269 return anv_DestroyPipeline(_device, (VkPipeline) _object);
1270
1271 case VK_OBJECT_TYPE_QUERY_POOL:
1272 return anv_DestroyQueryPool(_device, (VkQueryPool) _object);
1273
1274 case VK_OBJECT_TYPE_SEMAPHORE:
1275 return anv_DestroySemaphore(_device, (VkSemaphore) _object);
1276
1277 case VK_OBJECT_TYPE_EVENT:
1278 return anv_DestroyEvent(_device, (VkEvent) _object);
1279
1280 default:
1281 unreachable("Invalid object type");
1282 }
1283 }
1284
1285 VkResult anv_GetObjectMemoryRequirements(
1286 VkDevice device,
1287 VkObjectType objType,
1288 VkObject object,
1289 VkMemoryRequirements* pMemoryRequirements)
1290 {
1291
1292 /* The Vulkan spec (git aaed022) says:
1293 *
1294 * memoryTypeBits is a bitfield and contains one bit set for every
1295 * supported memory type for the resource. The bit `1<<i` is set if and
1296 * only if the memory type `i` in the VkPhysicalDeviceMemoryProperties
1297 * structure for the physical device is supported.
1298 *
1299 * We support exactly one memory type.
1300 */
1301 pMemoryRequirements->memoryTypeBits = 1;
1302
1303 switch (objType) {
1304 case VK_OBJECT_TYPE_BUFFER: {
1305 struct anv_buffer *buffer = anv_buffer_from_handle(object);
1306 pMemoryRequirements->size = buffer->size;
1307 pMemoryRequirements->alignment = 16;
1308 break;
1309 }
1310 case VK_OBJECT_TYPE_IMAGE: {
1311 struct anv_image *image = anv_image_from_handle(object);
1312 pMemoryRequirements->size = image->size;
1313 pMemoryRequirements->alignment = image->alignment;
1314 break;
1315 }
1316 default:
1317 pMemoryRequirements->size = 0;
1318 break;
1319 }
1320
1321 return VK_SUCCESS;
1322 }
1323
1324 VkResult anv_BindObjectMemory(
1325 VkDevice device,
1326 VkObjectType objType,
1327 VkObject object,
1328 VkDeviceMemory _mem,
1329 VkDeviceSize memOffset)
1330 {
1331 ANV_FROM_HANDLE(anv_device_memory, mem, _mem);
1332 struct anv_buffer *buffer;
1333 struct anv_image *image;
1334
1335 switch (objType) {
1336 case VK_OBJECT_TYPE_BUFFER:
1337 buffer = anv_buffer_from_handle(object);
1338 buffer->bo = &mem->bo;
1339 buffer->offset = memOffset;
1340 break;
1341 case VK_OBJECT_TYPE_IMAGE:
1342 image = anv_image_from_handle(object);
1343 image->bo = &mem->bo;
1344 image->offset = memOffset;
1345 break;
1346 default:
1347 break;
1348 }
1349
1350 return VK_SUCCESS;
1351 }
1352
1353 VkResult anv_QueueBindSparseBufferMemory(
1354 VkQueue queue,
1355 VkBuffer buffer,
1356 VkDeviceSize rangeOffset,
1357 VkDeviceSize rangeSize,
1358 VkDeviceMemory mem,
1359 VkDeviceSize memOffset)
1360 {
1361 stub_return(VK_UNSUPPORTED);
1362 }
1363
1364 VkResult anv_QueueBindSparseImageMemory(
1365 VkQueue queue,
1366 VkImage image,
1367 const VkImageMemoryBindInfo* pBindInfo,
1368 VkDeviceMemory mem,
1369 VkDeviceSize memOffset)
1370 {
1371 stub_return(VK_UNSUPPORTED);
1372 }
1373
1374 static void
1375 anv_fence_destroy(struct anv_device *device,
1376 struct anv_object *object,
1377 VkObjectType obj_type)
1378 {
1379 struct anv_fence *fence = (struct anv_fence *) object;
1380
1381 assert(obj_type == VK_OBJECT_TYPE_FENCE);
1382
1383 anv_DestroyFence(anv_device_to_handle(device),
1384 anv_fence_to_handle(fence));
1385 }
1386
1387 VkResult anv_CreateFence(
1388 VkDevice _device,
1389 const VkFenceCreateInfo* pCreateInfo,
1390 VkFence* pFence)
1391 {
1392 ANV_FROM_HANDLE(anv_device, device, _device);
1393 struct anv_fence *fence;
1394 struct anv_batch batch;
1395 VkResult result;
1396
1397 const uint32_t fence_size = 128;
1398
1399 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FENCE_CREATE_INFO);
1400
1401 fence = anv_device_alloc(device, sizeof(*fence), 8,
1402 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1403 if (fence == NULL)
1404 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1405
1406 result = anv_bo_init_new(&fence->bo, device, fence_size);
1407 if (result != VK_SUCCESS)
1408 goto fail;
1409
1410 fence->base.destructor = anv_fence_destroy;
1411
1412 fence->bo.map =
1413 anv_gem_mmap(device, fence->bo.gem_handle, 0, fence->bo.size);
1414 batch.next = batch.start = fence->bo.map;
1415 batch.end = fence->bo.map + fence->bo.size;
1416 anv_batch_emit(&batch, GEN8_MI_BATCH_BUFFER_END);
1417 anv_batch_emit(&batch, GEN8_MI_NOOP);
1418
1419 fence->exec2_objects[0].handle = fence->bo.gem_handle;
1420 fence->exec2_objects[0].relocation_count = 0;
1421 fence->exec2_objects[0].relocs_ptr = 0;
1422 fence->exec2_objects[0].alignment = 0;
1423 fence->exec2_objects[0].offset = fence->bo.offset;
1424 fence->exec2_objects[0].flags = 0;
1425 fence->exec2_objects[0].rsvd1 = 0;
1426 fence->exec2_objects[0].rsvd2 = 0;
1427
1428 fence->execbuf.buffers_ptr = (uintptr_t) fence->exec2_objects;
1429 fence->execbuf.buffer_count = 1;
1430 fence->execbuf.batch_start_offset = 0;
1431 fence->execbuf.batch_len = batch.next - fence->bo.map;
1432 fence->execbuf.cliprects_ptr = 0;
1433 fence->execbuf.num_cliprects = 0;
1434 fence->execbuf.DR1 = 0;
1435 fence->execbuf.DR4 = 0;
1436
1437 fence->execbuf.flags =
1438 I915_EXEC_HANDLE_LUT | I915_EXEC_NO_RELOC | I915_EXEC_RENDER;
1439 fence->execbuf.rsvd1 = device->context_id;
1440 fence->execbuf.rsvd2 = 0;
1441
1442 *pFence = anv_fence_to_handle(fence);
1443
1444 return VK_SUCCESS;
1445
1446 fail:
1447 anv_device_free(device, fence);
1448
1449 return result;
1450 }
1451
1452 VkResult anv_DestroyFence(
1453 VkDevice _device,
1454 VkFence _fence)
1455 {
1456 ANV_FROM_HANDLE(anv_device, device, _device);
1457 ANV_FROM_HANDLE(anv_fence, fence, _fence);
1458
1459 anv_gem_munmap(fence->bo.map, fence->bo.size);
1460 anv_gem_close(device, fence->bo.gem_handle);
1461 anv_device_free(device, fence);
1462
1463 return VK_SUCCESS;
1464 }
1465
1466 VkResult anv_ResetFences(
1467 VkDevice _device,
1468 uint32_t fenceCount,
1469 const VkFence* pFences)
1470 {
1471 struct anv_fence **fences = (struct anv_fence **) pFences;
1472
1473 for (uint32_t i = 0; i < fenceCount; i++)
1474 fences[i]->ready = false;
1475
1476 return VK_SUCCESS;
1477 }
1478
1479 VkResult anv_GetFenceStatus(
1480 VkDevice _device,
1481 VkFence _fence)
1482 {
1483 ANV_FROM_HANDLE(anv_device, device, _device);
1484 ANV_FROM_HANDLE(anv_fence, fence, _fence);
1485 int64_t t = 0;
1486 int ret;
1487
1488 if (fence->ready)
1489 return VK_SUCCESS;
1490
1491 ret = anv_gem_wait(device, fence->bo.gem_handle, &t);
1492 if (ret == 0) {
1493 fence->ready = true;
1494 return VK_SUCCESS;
1495 }
1496
1497 return VK_NOT_READY;
1498 }
1499
1500 VkResult anv_WaitForFences(
1501 VkDevice _device,
1502 uint32_t fenceCount,
1503 const VkFence* pFences,
1504 VkBool32 waitAll,
1505 uint64_t timeout)
1506 {
1507 ANV_FROM_HANDLE(anv_device, device, _device);
1508 int64_t t = timeout;
1509 int ret;
1510
1511 /* FIXME: handle !waitAll */
1512
1513 for (uint32_t i = 0; i < fenceCount; i++) {
1514 ANV_FROM_HANDLE(anv_fence, fence, pFences[i]);
1515 ret = anv_gem_wait(device, fence->bo.gem_handle, &t);
1516 if (ret == -1 && errno == ETIME)
1517 return VK_TIMEOUT;
1518 else if (ret == -1)
1519 return vk_error(VK_ERROR_UNKNOWN);
1520 }
1521
1522 return VK_SUCCESS;
1523 }
1524
1525 // Queue semaphore functions
1526
1527 VkResult anv_CreateSemaphore(
1528 VkDevice device,
1529 const VkSemaphoreCreateInfo* pCreateInfo,
1530 VkSemaphore* pSemaphore)
1531 {
1532 stub_return(VK_UNSUPPORTED);
1533 }
1534
1535 VkResult anv_DestroySemaphore(
1536 VkDevice device,
1537 VkSemaphore semaphore)
1538 {
1539 stub_return(VK_UNSUPPORTED);
1540 }
1541
1542 VkResult anv_QueueSignalSemaphore(
1543 VkQueue queue,
1544 VkSemaphore semaphore)
1545 {
1546 stub_return(VK_UNSUPPORTED);
1547 }
1548
1549 VkResult anv_QueueWaitSemaphore(
1550 VkQueue queue,
1551 VkSemaphore semaphore)
1552 {
1553 stub_return(VK_UNSUPPORTED);
1554 }
1555
1556 // Event functions
1557
1558 VkResult anv_CreateEvent(
1559 VkDevice device,
1560 const VkEventCreateInfo* pCreateInfo,
1561 VkEvent* pEvent)
1562 {
1563 stub_return(VK_UNSUPPORTED);
1564 }
1565
1566 VkResult anv_DestroyEvent(
1567 VkDevice device,
1568 VkEvent event)
1569 {
1570 stub_return(VK_UNSUPPORTED);
1571 }
1572
1573 VkResult anv_GetEventStatus(
1574 VkDevice device,
1575 VkEvent event)
1576 {
1577 stub_return(VK_UNSUPPORTED);
1578 }
1579
1580 VkResult anv_SetEvent(
1581 VkDevice device,
1582 VkEvent event)
1583 {
1584 stub_return(VK_UNSUPPORTED);
1585 }
1586
1587 VkResult anv_ResetEvent(
1588 VkDevice device,
1589 VkEvent event)
1590 {
1591 stub_return(VK_UNSUPPORTED);
1592 }
1593
1594 // Buffer functions
1595
1596 VkResult anv_CreateBuffer(
1597 VkDevice _device,
1598 const VkBufferCreateInfo* pCreateInfo,
1599 VkBuffer* pBuffer)
1600 {
1601 ANV_FROM_HANDLE(anv_device, device, _device);
1602 struct anv_buffer *buffer;
1603
1604 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
1605
1606 buffer = anv_device_alloc(device, sizeof(*buffer), 8,
1607 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1608 if (buffer == NULL)
1609 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1610
1611 buffer->size = pCreateInfo->size;
1612 buffer->bo = NULL;
1613 buffer->offset = 0;
1614
1615 *pBuffer = anv_buffer_to_handle(buffer);
1616
1617 return VK_SUCCESS;
1618 }
1619
1620 VkResult anv_DestroyBuffer(
1621 VkDevice _device,
1622 VkBuffer _buffer)
1623 {
1624 ANV_FROM_HANDLE(anv_device, device, _device);
1625 ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
1626
1627 anv_device_free(device, buffer);
1628
1629 return VK_SUCCESS;
1630 }
1631
1632 // Buffer view functions
1633
1634 static void
1635 fill_buffer_surface_state(void *state, VkFormat format,
1636 uint32_t offset, uint32_t range)
1637 {
1638 const struct anv_format *info;
1639
1640 info = anv_format_for_vk_format(format);
1641 /* This assumes RGBA float format. */
1642 uint32_t stride = 4;
1643 uint32_t num_elements = range / stride;
1644
1645 struct GEN8_RENDER_SURFACE_STATE surface_state = {
1646 .SurfaceType = SURFTYPE_BUFFER,
1647 .SurfaceArray = false,
1648 .SurfaceFormat = info->surface_format,
1649 .SurfaceVerticalAlignment = VALIGN4,
1650 .SurfaceHorizontalAlignment = HALIGN4,
1651 .TileMode = LINEAR,
1652 .VerticalLineStride = 0,
1653 .VerticalLineStrideOffset = 0,
1654 .SamplerL2BypassModeDisable = true,
1655 .RenderCacheReadWriteMode = WriteOnlyCache,
1656 .MemoryObjectControlState = GEN8_MOCS,
1657 .BaseMipLevel = 0.0,
1658 .SurfaceQPitch = 0,
1659 .Height = (num_elements >> 7) & 0x3fff,
1660 .Width = num_elements & 0x7f,
1661 .Depth = (num_elements >> 21) & 0x3f,
1662 .SurfacePitch = stride - 1,
1663 .MinimumArrayElement = 0,
1664 .NumberofMultisamples = MULTISAMPLECOUNT_1,
1665 .XOffset = 0,
1666 .YOffset = 0,
1667 .SurfaceMinLOD = 0,
1668 .MIPCountLOD = 0,
1669 .AuxiliarySurfaceMode = AUX_NONE,
1670 .RedClearColor = 0,
1671 .GreenClearColor = 0,
1672 .BlueClearColor = 0,
1673 .AlphaClearColor = 0,
1674 .ShaderChannelSelectRed = SCS_RED,
1675 .ShaderChannelSelectGreen = SCS_GREEN,
1676 .ShaderChannelSelectBlue = SCS_BLUE,
1677 .ShaderChannelSelectAlpha = SCS_ALPHA,
1678 .ResourceMinLOD = 0.0,
1679 /* FIXME: We assume that the image must be bound at this time. */
1680 .SurfaceBaseAddress = { NULL, offset },
1681 };
1682
1683 GEN8_RENDER_SURFACE_STATE_pack(NULL, state, &surface_state);
1684 }
1685
1686 VkResult anv_CreateBufferView(
1687 VkDevice _device,
1688 const VkBufferViewCreateInfo* pCreateInfo,
1689 VkBufferView* pView)
1690 {
1691 ANV_FROM_HANDLE(anv_device, device, _device);
1692 ANV_FROM_HANDLE(anv_buffer, buffer, pCreateInfo->buffer);
1693 struct anv_surface_view *view;
1694
1695 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO);
1696
1697 view = anv_device_alloc(device, sizeof(*view), 8,
1698 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1699 if (view == NULL)
1700 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1701
1702 view->bo = buffer->bo;
1703 view->offset = buffer->offset + pCreateInfo->offset;
1704 view->surface_state =
1705 anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
1706 view->format = pCreateInfo->format;
1707 view->range = pCreateInfo->range;
1708
1709 fill_buffer_surface_state(view->surface_state.map,
1710 pCreateInfo->format, view->offset, pCreateInfo->range);
1711
1712 *pView = (VkBufferView) view;
1713
1714 return VK_SUCCESS;
1715 }
1716
1717 VkResult anv_DestroyBufferView(
1718 VkDevice _device,
1719 VkBufferView _view)
1720 {
1721 ANV_FROM_HANDLE(anv_device, device, _device);
1722 struct anv_surface_view *view = (struct anv_surface_view *)_view;
1723
1724 anv_surface_view_fini(device, view);
1725 anv_device_free(device, view);
1726
1727 return VK_SUCCESS;
1728 }
1729
1730 // Sampler functions
1731
1732 VkResult anv_CreateSampler(
1733 VkDevice _device,
1734 const VkSamplerCreateInfo* pCreateInfo,
1735 VkSampler* pSampler)
1736 {
1737 ANV_FROM_HANDLE(anv_device, device, _device);
1738 struct anv_sampler *sampler;
1739 uint32_t mag_filter, min_filter, max_anisotropy;
1740
1741 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
1742
1743 sampler = anv_device_alloc(device, sizeof(*sampler), 8,
1744 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1745 if (!sampler)
1746 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1747
1748 static const uint32_t vk_to_gen_tex_filter[] = {
1749 [VK_TEX_FILTER_NEAREST] = MAPFILTER_NEAREST,
1750 [VK_TEX_FILTER_LINEAR] = MAPFILTER_LINEAR
1751 };
1752
1753 static const uint32_t vk_to_gen_mipmap_mode[] = {
1754 [VK_TEX_MIPMAP_MODE_BASE] = MIPFILTER_NONE,
1755 [VK_TEX_MIPMAP_MODE_NEAREST] = MIPFILTER_NEAREST,
1756 [VK_TEX_MIPMAP_MODE_LINEAR] = MIPFILTER_LINEAR
1757 };
1758
1759 static const uint32_t vk_to_gen_tex_address[] = {
1760 [VK_TEX_ADDRESS_WRAP] = TCM_WRAP,
1761 [VK_TEX_ADDRESS_MIRROR] = TCM_MIRROR,
1762 [VK_TEX_ADDRESS_CLAMP] = TCM_CLAMP,
1763 [VK_TEX_ADDRESS_MIRROR_ONCE] = TCM_MIRROR_ONCE,
1764 [VK_TEX_ADDRESS_CLAMP_BORDER] = TCM_CLAMP_BORDER,
1765 };
1766
1767 static const uint32_t vk_to_gen_compare_op[] = {
1768 [VK_COMPARE_OP_NEVER] = PREFILTEROPNEVER,
1769 [VK_COMPARE_OP_LESS] = PREFILTEROPLESS,
1770 [VK_COMPARE_OP_EQUAL] = PREFILTEROPEQUAL,
1771 [VK_COMPARE_OP_LESS_EQUAL] = PREFILTEROPLEQUAL,
1772 [VK_COMPARE_OP_GREATER] = PREFILTEROPGREATER,
1773 [VK_COMPARE_OP_NOT_EQUAL] = PREFILTEROPNOTEQUAL,
1774 [VK_COMPARE_OP_GREATER_EQUAL] = PREFILTEROPGEQUAL,
1775 [VK_COMPARE_OP_ALWAYS] = PREFILTEROPALWAYS,
1776 };
1777
1778 if (pCreateInfo->maxAnisotropy > 1) {
1779 mag_filter = MAPFILTER_ANISOTROPIC;
1780 min_filter = MAPFILTER_ANISOTROPIC;
1781 max_anisotropy = (pCreateInfo->maxAnisotropy - 2) / 2;
1782 } else {
1783 mag_filter = vk_to_gen_tex_filter[pCreateInfo->magFilter];
1784 min_filter = vk_to_gen_tex_filter[pCreateInfo->minFilter];
1785 max_anisotropy = RATIO21;
1786 }
1787
1788 struct GEN8_SAMPLER_STATE sampler_state = {
1789 .SamplerDisable = false,
1790 .TextureBorderColorMode = DX10OGL,
1791 .LODPreClampMode = 0,
1792 .BaseMipLevel = 0.0,
1793 .MipModeFilter = vk_to_gen_mipmap_mode[pCreateInfo->mipMode],
1794 .MagModeFilter = mag_filter,
1795 .MinModeFilter = min_filter,
1796 .TextureLODBias = pCreateInfo->mipLodBias * 256,
1797 .AnisotropicAlgorithm = EWAApproximation,
1798 .MinLOD = pCreateInfo->minLod,
1799 .MaxLOD = pCreateInfo->maxLod,
1800 .ChromaKeyEnable = 0,
1801 .ChromaKeyIndex = 0,
1802 .ChromaKeyMode = 0,
1803 .ShadowFunction = vk_to_gen_compare_op[pCreateInfo->compareOp],
1804 .CubeSurfaceControlMode = 0,
1805
1806 .IndirectStatePointer =
1807 device->border_colors.offset +
1808 pCreateInfo->borderColor * sizeof(float) * 4,
1809
1810 .LODClampMagnificationMode = MIPNONE,
1811 .MaximumAnisotropy = max_anisotropy,
1812 .RAddressMinFilterRoundingEnable = 0,
1813 .RAddressMagFilterRoundingEnable = 0,
1814 .VAddressMinFilterRoundingEnable = 0,
1815 .VAddressMagFilterRoundingEnable = 0,
1816 .UAddressMinFilterRoundingEnable = 0,
1817 .UAddressMagFilterRoundingEnable = 0,
1818 .TrilinearFilterQuality = 0,
1819 .NonnormalizedCoordinateEnable = 0,
1820 .TCXAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressU],
1821 .TCYAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressV],
1822 .TCZAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressW],
1823 };
1824
1825 GEN8_SAMPLER_STATE_pack(NULL, sampler->state, &sampler_state);
1826
1827 *pSampler = anv_sampler_to_handle(sampler);
1828
1829 return VK_SUCCESS;
1830 }
1831
1832 VkResult anv_DestroySampler(
1833 VkDevice _device,
1834 VkSampler _sampler)
1835 {
1836 ANV_FROM_HANDLE(anv_device, device, _device);
1837 ANV_FROM_HANDLE(anv_sampler, sampler, _sampler);
1838
1839 anv_device_free(device, sampler);
1840
1841 return VK_SUCCESS;
1842 }
1843
1844 // Descriptor set functions
1845
1846 VkResult anv_CreateDescriptorSetLayout(
1847 VkDevice _device,
1848 const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
1849 VkDescriptorSetLayout* pSetLayout)
1850 {
1851 ANV_FROM_HANDLE(anv_device, device, _device);
1852 struct anv_descriptor_set_layout *set_layout;
1853
1854 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO);
1855
1856 uint32_t sampler_count[VK_SHADER_STAGE_NUM] = { 0, };
1857 uint32_t surface_count[VK_SHADER_STAGE_NUM] = { 0, };
1858 uint32_t num_dynamic_buffers = 0;
1859 uint32_t count = 0;
1860 uint32_t stages = 0;
1861 uint32_t s;
1862
1863 for (uint32_t i = 0; i < pCreateInfo->count; i++) {
1864 switch (pCreateInfo->pBinding[i].descriptorType) {
1865 case VK_DESCRIPTOR_TYPE_SAMPLER:
1866 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1867 for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
1868 sampler_count[s] += pCreateInfo->pBinding[i].arraySize;
1869 break;
1870 default:
1871 break;
1872 }
1873
1874 switch (pCreateInfo->pBinding[i].descriptorType) {
1875 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1876 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1877 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1878 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1879 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1880 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1881 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1882 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1883 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1884 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1885 for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
1886 surface_count[s] += pCreateInfo->pBinding[i].arraySize;
1887 break;
1888 default:
1889 break;
1890 }
1891
1892 switch (pCreateInfo->pBinding[i].descriptorType) {
1893 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1894 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1895 num_dynamic_buffers += pCreateInfo->pBinding[i].arraySize;
1896 break;
1897 default:
1898 break;
1899 }
1900
1901 stages |= pCreateInfo->pBinding[i].stageFlags;
1902 count += pCreateInfo->pBinding[i].arraySize;
1903 }
1904
1905 uint32_t sampler_total = 0;
1906 uint32_t surface_total = 0;
1907 for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) {
1908 sampler_total += sampler_count[s];
1909 surface_total += surface_count[s];
1910 }
1911
1912 size_t size = sizeof(*set_layout) +
1913 (sampler_total + surface_total) * sizeof(set_layout->entries[0]);
1914 set_layout = anv_device_alloc(device, size, 8,
1915 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1916 if (!set_layout)
1917 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1918
1919 set_layout->num_dynamic_buffers = num_dynamic_buffers;
1920 set_layout->count = count;
1921 set_layout->shader_stages = stages;
1922
1923 struct anv_descriptor_slot *p = set_layout->entries;
1924 struct anv_descriptor_slot *sampler[VK_SHADER_STAGE_NUM];
1925 struct anv_descriptor_slot *surface[VK_SHADER_STAGE_NUM];
1926 for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) {
1927 set_layout->stage[s].surface_count = surface_count[s];
1928 set_layout->stage[s].surface_start = surface[s] = p;
1929 p += surface_count[s];
1930 set_layout->stage[s].sampler_count = sampler_count[s];
1931 set_layout->stage[s].sampler_start = sampler[s] = p;
1932 p += sampler_count[s];
1933 }
1934
1935 uint32_t descriptor = 0;
1936 int8_t dynamic_slot = 0;
1937 bool is_dynamic;
1938 for (uint32_t i = 0; i < pCreateInfo->count; i++) {
1939 switch (pCreateInfo->pBinding[i].descriptorType) {
1940 case VK_DESCRIPTOR_TYPE_SAMPLER:
1941 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1942 for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
1943 for (uint32_t j = 0; j < pCreateInfo->pBinding[i].arraySize; j++) {
1944 sampler[s]->index = descriptor + j;
1945 sampler[s]->dynamic_slot = -1;
1946 sampler[s]++;
1947 }
1948 break;
1949 default:
1950 break;
1951 }
1952
1953 switch (pCreateInfo->pBinding[i].descriptorType) {
1954 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1955 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1956 is_dynamic = true;
1957 break;
1958 default:
1959 is_dynamic = false;
1960 break;
1961 }
1962
1963 switch (pCreateInfo->pBinding[i].descriptorType) {
1964 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1965 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1966 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1967 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1968 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1969 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1970 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1971 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1972 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1973 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1974 for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
1975 for (uint32_t j = 0; j < pCreateInfo->pBinding[i].arraySize; j++) {
1976 surface[s]->index = descriptor + j;
1977 if (is_dynamic)
1978 surface[s]->dynamic_slot = dynamic_slot + j;
1979 else
1980 surface[s]->dynamic_slot = -1;
1981 surface[s]++;
1982 }
1983 break;
1984 default:
1985 break;
1986 }
1987
1988 if (is_dynamic)
1989 dynamic_slot += pCreateInfo->pBinding[i].arraySize;
1990
1991 descriptor += pCreateInfo->pBinding[i].arraySize;
1992 }
1993
1994 *pSetLayout = anv_descriptor_set_layout_to_handle(set_layout);
1995
1996 return VK_SUCCESS;
1997 }
1998
1999 VkResult anv_DestroyDescriptorSetLayout(
2000 VkDevice _device,
2001 VkDescriptorSetLayout _set_layout)
2002 {
2003 ANV_FROM_HANDLE(anv_device, device, _device);
2004 ANV_FROM_HANDLE(anv_descriptor_set_layout, set_layout, _set_layout);
2005
2006 anv_device_free(device, set_layout);
2007
2008 return VK_SUCCESS;
2009 }
2010
2011 VkResult anv_CreateDescriptorPool(
2012 VkDevice device,
2013 VkDescriptorPoolUsage poolUsage,
2014 uint32_t maxSets,
2015 const VkDescriptorPoolCreateInfo* pCreateInfo,
2016 VkDescriptorPool* pDescriptorPool)
2017 {
2018 *pDescriptorPool = 1;
2019
2020 return VK_SUCCESS;
2021 }
2022
2023 VkResult anv_DestroyDescriptorPool(
2024 VkDevice _device,
2025 VkDescriptorPool _pool)
2026 {
2027 /* VkDescriptorPool is a dummy object. */
2028 return VK_SUCCESS;
2029 }
2030
2031 VkResult anv_ResetDescriptorPool(
2032 VkDevice device,
2033 VkDescriptorPool descriptorPool)
2034 {
2035 return VK_SUCCESS;
2036 }
2037
2038 VkResult anv_AllocDescriptorSets(
2039 VkDevice _device,
2040 VkDescriptorPool descriptorPool,
2041 VkDescriptorSetUsage setUsage,
2042 uint32_t count,
2043 const VkDescriptorSetLayout* pSetLayouts,
2044 VkDescriptorSet* pDescriptorSets,
2045 uint32_t* pCount)
2046 {
2047 ANV_FROM_HANDLE(anv_device, device, _device);
2048 struct anv_descriptor_set *set;
2049 size_t size;
2050
2051 for (uint32_t i = 0; i < count; i++) {
2052 ANV_FROM_HANDLE(anv_descriptor_set_layout, layout, pSetLayouts[i]);
2053 size = sizeof(*set) + layout->count * sizeof(set->descriptors[0]);
2054 set = anv_device_alloc(device, size, 8,
2055 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
2056 if (!set) {
2057 *pCount = i;
2058 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2059 }
2060
2061 /* Descriptor sets may not be 100% filled out so we need to memset to
2062 * ensure that we can properly detect and handle holes.
2063 */
2064 memset(set, 0, size);
2065
2066 pDescriptorSets[i] = anv_descriptor_set_to_handle(set);
2067 }
2068
2069 *pCount = count;
2070
2071 return VK_SUCCESS;
2072 }
2073
2074 VkResult anv_UpdateDescriptorSets(
2075 VkDevice device,
2076 uint32_t writeCount,
2077 const VkWriteDescriptorSet* pDescriptorWrites,
2078 uint32_t copyCount,
2079 const VkCopyDescriptorSet* pDescriptorCopies)
2080 {
2081 for (uint32_t i = 0; i < writeCount; i++) {
2082 const VkWriteDescriptorSet *write = &pDescriptorWrites[i];
2083 ANV_FROM_HANDLE(anv_descriptor_set, set, write->destSet);
2084
2085 switch (write->descriptorType) {
2086 case VK_DESCRIPTOR_TYPE_SAMPLER:
2087 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2088 for (uint32_t j = 0; j < write->count; j++) {
2089 set->descriptors[write->destBinding + j].sampler =
2090 anv_sampler_from_handle(write->pDescriptors[j].sampler);
2091 }
2092
2093 if (write->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
2094 break;
2095
2096 /* fallthrough */
2097
2098 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
2099 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2100 for (uint32_t j = 0; j < write->count; j++) {
2101 set->descriptors[write->destBinding + j].view =
2102 (struct anv_surface_view *)write->pDescriptors[j].imageView;
2103 }
2104 break;
2105
2106 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
2107 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
2108 anv_finishme("texel buffers not implemented");
2109 break;
2110
2111 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
2112 anv_finishme("input attachments not implemented");
2113 break;
2114
2115 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2116 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2117 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
2118 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
2119 for (uint32_t j = 0; j < write->count; j++) {
2120 set->descriptors[write->destBinding + j].view =
2121 (struct anv_surface_view *)write->pDescriptors[j].bufferView;
2122 }
2123
2124 default:
2125 break;
2126 }
2127 }
2128
2129 for (uint32_t i = 0; i < copyCount; i++) {
2130 const VkCopyDescriptorSet *copy = &pDescriptorCopies[i];
2131 ANV_FROM_HANDLE(anv_descriptor_set, src, copy->destSet);
2132 ANV_FROM_HANDLE(anv_descriptor_set, dest, copy->destSet);
2133 for (uint32_t j = 0; j < copy->count; j++) {
2134 dest->descriptors[copy->destBinding + j] =
2135 src->descriptors[copy->srcBinding + j];
2136 }
2137 }
2138
2139 return VK_SUCCESS;
2140 }
2141
2142 // State object functions
2143
2144 static inline int64_t
2145 clamp_int64(int64_t x, int64_t min, int64_t max)
2146 {
2147 if (x < min)
2148 return min;
2149 else if (x < max)
2150 return x;
2151 else
2152 return max;
2153 }
2154
2155 static void
2156 anv_dynamic_vp_state_destroy(struct anv_device *device,
2157 struct anv_object *object,
2158 VkObjectType obj_type)
2159 {
2160 struct anv_dynamic_vp_state *vp_state = (void *) object;
2161
2162 assert(obj_type == VK_OBJECT_TYPE_DYNAMIC_VP_STATE);
2163
2164 anv_DestroyDynamicViewportState(anv_device_to_handle(device),
2165 anv_dynamic_vp_state_to_handle(vp_state));
2166 }
2167
2168 VkResult anv_CreateDynamicViewportState(
2169 VkDevice _device,
2170 const VkDynamicViewportStateCreateInfo* pCreateInfo,
2171 VkDynamicViewportState* pState)
2172 {
2173 ANV_FROM_HANDLE(anv_device, device, _device);
2174 struct anv_dynamic_vp_state *state;
2175
2176 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO);
2177
2178 state = anv_device_alloc(device, sizeof(*state), 8,
2179 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
2180 if (state == NULL)
2181 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2182
2183 state->base.destructor = anv_dynamic_vp_state_destroy;
2184
2185 unsigned count = pCreateInfo->viewportAndScissorCount;
2186 state->sf_clip_vp = anv_state_pool_alloc(&device->dynamic_state_pool,
2187 count * 64, 64);
2188 state->cc_vp = anv_state_pool_alloc(&device->dynamic_state_pool,
2189 count * 8, 32);
2190 state->scissor = anv_state_pool_alloc(&device->dynamic_state_pool,
2191 count * 32, 32);
2192
2193 for (uint32_t i = 0; i < pCreateInfo->viewportAndScissorCount; i++) {
2194 const VkViewport *vp = &pCreateInfo->pViewports[i];
2195 const VkRect2D *s = &pCreateInfo->pScissors[i];
2196
2197 struct GEN8_SF_CLIP_VIEWPORT sf_clip_viewport = {
2198 .ViewportMatrixElementm00 = vp->width / 2,
2199 .ViewportMatrixElementm11 = vp->height / 2,
2200 .ViewportMatrixElementm22 = (vp->maxDepth - vp->minDepth) / 2,
2201 .ViewportMatrixElementm30 = vp->originX + vp->width / 2,
2202 .ViewportMatrixElementm31 = vp->originY + vp->height / 2,
2203 .ViewportMatrixElementm32 = (vp->maxDepth + vp->minDepth) / 2,
2204 .XMinClipGuardband = -1.0f,
2205 .XMaxClipGuardband = 1.0f,
2206 .YMinClipGuardband = -1.0f,
2207 .YMaxClipGuardband = 1.0f,
2208 .XMinViewPort = vp->originX,
2209 .XMaxViewPort = vp->originX + vp->width - 1,
2210 .YMinViewPort = vp->originY,
2211 .YMaxViewPort = vp->originY + vp->height - 1,
2212 };
2213
2214 struct GEN8_CC_VIEWPORT cc_viewport = {
2215 .MinimumDepth = vp->minDepth,
2216 .MaximumDepth = vp->maxDepth
2217 };
2218
2219 /* Since xmax and ymax are inclusive, we have to have xmax < xmin or
2220 * ymax < ymin for empty clips. In case clip x, y, width height are all
2221 * 0, the clamps below produce 0 for xmin, ymin, xmax, ymax, which isn't
2222 * what we want. Just special case empty clips and produce a canonical
2223 * empty clip. */
2224 static const struct GEN8_SCISSOR_RECT empty_scissor = {
2225 .ScissorRectangleYMin = 1,
2226 .ScissorRectangleXMin = 1,
2227 .ScissorRectangleYMax = 0,
2228 .ScissorRectangleXMax = 0
2229 };
2230
2231 const int max = 0xffff;
2232 struct GEN8_SCISSOR_RECT scissor = {
2233 /* Do this math using int64_t so overflow gets clamped correctly. */
2234 .ScissorRectangleYMin = clamp_int64(s->offset.y, 0, max),
2235 .ScissorRectangleXMin = clamp_int64(s->offset.x, 0, max),
2236 .ScissorRectangleYMax = clamp_int64((uint64_t) s->offset.y + s->extent.height - 1, 0, max),
2237 .ScissorRectangleXMax = clamp_int64((uint64_t) s->offset.x + s->extent.width - 1, 0, max)
2238 };
2239
2240 GEN8_SF_CLIP_VIEWPORT_pack(NULL, state->sf_clip_vp.map + i * 64, &sf_clip_viewport);
2241 GEN8_CC_VIEWPORT_pack(NULL, state->cc_vp.map + i * 32, &cc_viewport);
2242
2243 if (s->extent.width <= 0 || s->extent.height <= 0) {
2244 GEN8_SCISSOR_RECT_pack(NULL, state->scissor.map + i * 32, &empty_scissor);
2245 } else {
2246 GEN8_SCISSOR_RECT_pack(NULL, state->scissor.map + i * 32, &scissor);
2247 }
2248 }
2249
2250 *pState = anv_dynamic_vp_state_to_handle(state);
2251
2252 return VK_SUCCESS;
2253 }
2254
2255 VkResult anv_DestroyDynamicViewportState(
2256 VkDevice _device,
2257 VkDynamicViewportState _vp_state)
2258 {
2259 ANV_FROM_HANDLE(anv_device, device, _device);
2260 ANV_FROM_HANDLE(anv_dynamic_vp_state, vp_state, _vp_state);
2261
2262 anv_state_pool_free(&device->dynamic_state_pool, vp_state->sf_clip_vp);
2263 anv_state_pool_free(&device->dynamic_state_pool, vp_state->cc_vp);
2264 anv_state_pool_free(&device->dynamic_state_pool, vp_state->scissor);
2265
2266 anv_device_free(device, vp_state);
2267
2268 return VK_SUCCESS;
2269 }
2270
2271 VkResult anv_CreateDynamicRasterState(
2272 VkDevice _device,
2273 const VkDynamicRasterStateCreateInfo* pCreateInfo,
2274 VkDynamicRasterState* pState)
2275 {
2276 ANV_FROM_HANDLE(anv_device, device, _device);
2277 struct anv_dynamic_rs_state *state;
2278
2279 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO);
2280
2281 state = anv_device_alloc(device, sizeof(*state), 8,
2282 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
2283 if (state == NULL)
2284 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2285
2286 struct GEN8_3DSTATE_SF sf = {
2287 GEN8_3DSTATE_SF_header,
2288 .LineWidth = pCreateInfo->lineWidth,
2289 };
2290
2291 GEN8_3DSTATE_SF_pack(NULL, state->state_sf, &sf);
2292
2293 bool enable_bias = pCreateInfo->depthBias != 0.0f ||
2294 pCreateInfo->slopeScaledDepthBias != 0.0f;
2295 struct GEN8_3DSTATE_RASTER raster = {
2296 .GlobalDepthOffsetEnableSolid = enable_bias,
2297 .GlobalDepthOffsetEnableWireframe = enable_bias,
2298 .GlobalDepthOffsetEnablePoint = enable_bias,
2299 .GlobalDepthOffsetConstant = pCreateInfo->depthBias,
2300 .GlobalDepthOffsetScale = pCreateInfo->slopeScaledDepthBias,
2301 .GlobalDepthOffsetClamp = pCreateInfo->depthBiasClamp
2302 };
2303
2304 GEN8_3DSTATE_RASTER_pack(NULL, state->state_raster, &raster);
2305
2306 *pState = anv_dynamic_rs_state_to_handle(state);
2307
2308 return VK_SUCCESS;
2309 }
2310
2311 VkResult anv_DestroyDynamicRasterState(
2312 VkDevice _device,
2313 VkDynamicRasterState _rs_state)
2314 {
2315 ANV_FROM_HANDLE(anv_device, device, _device);
2316 ANV_FROM_HANDLE(anv_dynamic_rs_state, rs_state, _rs_state);
2317
2318 anv_device_free(device, rs_state);
2319
2320 return VK_SUCCESS;
2321 }
2322
2323 VkResult anv_CreateDynamicColorBlendState(
2324 VkDevice _device,
2325 const VkDynamicColorBlendStateCreateInfo* pCreateInfo,
2326 VkDynamicColorBlendState* pState)
2327 {
2328 ANV_FROM_HANDLE(anv_device, device, _device);
2329 struct anv_dynamic_cb_state *state;
2330
2331 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_CB_STATE_CREATE_INFO);
2332
2333 state = anv_device_alloc(device, sizeof(*state), 8,
2334 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
2335 if (state == NULL)
2336 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2337
2338 struct GEN8_COLOR_CALC_STATE color_calc_state = {
2339 .BlendConstantColorRed = pCreateInfo->blendConst[0],
2340 .BlendConstantColorGreen = pCreateInfo->blendConst[1],
2341 .BlendConstantColorBlue = pCreateInfo->blendConst[2],
2342 .BlendConstantColorAlpha = pCreateInfo->blendConst[3]
2343 };
2344
2345 GEN8_COLOR_CALC_STATE_pack(NULL, state->state_color_calc, &color_calc_state);
2346
2347 *pState = anv_dynamic_cb_state_to_handle(state);
2348
2349 return VK_SUCCESS;
2350 }
2351
2352 VkResult anv_DestroyDynamicColorBlendState(
2353 VkDevice _device,
2354 VkDynamicColorBlendState _cb_state)
2355 {
2356 ANV_FROM_HANDLE(anv_device, device, _device);
2357 ANV_FROM_HANDLE(anv_dynamic_cb_state, cb_state, _cb_state);
2358
2359 anv_device_free(device, cb_state);
2360
2361 return VK_SUCCESS;
2362 }
2363
2364 VkResult anv_CreateDynamicDepthStencilState(
2365 VkDevice _device,
2366 const VkDynamicDepthStencilStateCreateInfo* pCreateInfo,
2367 VkDynamicDepthStencilState* pState)
2368 {
2369 ANV_FROM_HANDLE(anv_device, device, _device);
2370 struct anv_dynamic_ds_state *state;
2371
2372 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_DS_STATE_CREATE_INFO);
2373
2374 state = anv_device_alloc(device, sizeof(*state), 8,
2375 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
2376 if (state == NULL)
2377 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2378
2379 struct GEN8_3DSTATE_WM_DEPTH_STENCIL wm_depth_stencil = {
2380 GEN8_3DSTATE_WM_DEPTH_STENCIL_header,
2381
2382 /* Is this what we need to do? */
2383 .StencilBufferWriteEnable = pCreateInfo->stencilWriteMask != 0,
2384
2385 .StencilTestMask = pCreateInfo->stencilReadMask & 0xff,
2386 .StencilWriteMask = pCreateInfo->stencilWriteMask & 0xff,
2387
2388 .BackfaceStencilTestMask = pCreateInfo->stencilReadMask & 0xff,
2389 .BackfaceStencilWriteMask = pCreateInfo->stencilWriteMask & 0xff,
2390 };
2391
2392 GEN8_3DSTATE_WM_DEPTH_STENCIL_pack(NULL, state->state_wm_depth_stencil,
2393 &wm_depth_stencil);
2394
2395 struct GEN8_COLOR_CALC_STATE color_calc_state = {
2396 .StencilReferenceValue = pCreateInfo->stencilFrontRef,
2397 .BackFaceStencilReferenceValue = pCreateInfo->stencilBackRef
2398 };
2399
2400 GEN8_COLOR_CALC_STATE_pack(NULL, state->state_color_calc, &color_calc_state);
2401
2402 *pState = anv_dynamic_ds_state_to_handle(state);
2403
2404 return VK_SUCCESS;
2405 }
2406
2407 VkResult anv_DestroyDynamicDepthStencilState(
2408 VkDevice _device,
2409 VkDynamicDepthStencilState _ds_state)
2410 {
2411 ANV_FROM_HANDLE(anv_device, device, _device);
2412 ANV_FROM_HANDLE(anv_dynamic_ds_state, ds_state, _ds_state);
2413
2414 anv_device_free(device, ds_state);
2415
2416 return VK_SUCCESS;
2417 }
2418
2419 // Command buffer functions
2420
2421 static void
2422 anv_cmd_buffer_destroy(struct anv_device *device,
2423 struct anv_object *object,
2424 VkObjectType obj_type)
2425 {
2426 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) object;
2427
2428 assert(obj_type == VK_OBJECT_TYPE_COMMAND_BUFFER);
2429
2430 anv_DestroyCommandBuffer(anv_device_to_handle(device),
2431 anv_cmd_buffer_to_handle(cmd_buffer));
2432 }
2433
2434 static VkResult
2435 anv_cmd_buffer_chain_batch(struct anv_batch *batch, void *_data)
2436 {
2437 struct anv_cmd_buffer *cmd_buffer = _data;
2438
2439 struct anv_batch_bo *new_bbo, *old_bbo = cmd_buffer->last_batch_bo;
2440
2441 VkResult result = anv_batch_bo_create(cmd_buffer->device, &new_bbo);
2442 if (result != VK_SUCCESS)
2443 return result;
2444
2445 /* We set the end of the batch a little short so we would be sure we
2446 * have room for the chaining command. Since we're about to emit the
2447 * chaining command, let's set it back where it should go.
2448 */
2449 batch->end += GEN8_MI_BATCH_BUFFER_START_length * 4;
2450 assert(batch->end == old_bbo->bo.map + old_bbo->bo.size);
2451
2452 anv_batch_emit(batch, GEN8_MI_BATCH_BUFFER_START,
2453 GEN8_MI_BATCH_BUFFER_START_header,
2454 ._2ndLevelBatchBuffer = _1stlevelbatch,
2455 .AddressSpaceIndicator = ASI_PPGTT,
2456 .BatchBufferStartAddress = { &new_bbo->bo, 0 },
2457 );
2458
2459 /* Pad out to a 2-dword aligned boundary with zeros */
2460 if ((uintptr_t)batch->next % 8 != 0) {
2461 *(uint32_t *)batch->next = 0;
2462 batch->next += 4;
2463 }
2464
2465 anv_batch_bo_finish(cmd_buffer->last_batch_bo, batch);
2466
2467 new_bbo->prev_batch_bo = old_bbo;
2468 cmd_buffer->last_batch_bo = new_bbo;
2469
2470 anv_batch_bo_start(new_bbo, batch, GEN8_MI_BATCH_BUFFER_START_length * 4);
2471
2472 return VK_SUCCESS;
2473 }
2474
2475 VkResult anv_CreateCommandBuffer(
2476 VkDevice _device,
2477 const VkCmdBufferCreateInfo* pCreateInfo,
2478 VkCmdBuffer* pCmdBuffer)
2479 {
2480 ANV_FROM_HANDLE(anv_device, device, _device);
2481 struct anv_cmd_buffer *cmd_buffer;
2482 VkResult result;
2483
2484 assert(pCreateInfo->level == VK_CMD_BUFFER_LEVEL_PRIMARY);
2485
2486 cmd_buffer = anv_device_alloc(device, sizeof(*cmd_buffer), 8,
2487 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
2488 if (cmd_buffer == NULL)
2489 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2490
2491 cmd_buffer->base.destructor = anv_cmd_buffer_destroy;
2492
2493 cmd_buffer->device = device;
2494 cmd_buffer->rs_state = NULL;
2495 cmd_buffer->vp_state = NULL;
2496 cmd_buffer->cb_state = NULL;
2497 cmd_buffer->ds_state = NULL;
2498 memset(&cmd_buffer->state_vf, 0, sizeof(cmd_buffer->state_vf));
2499 memset(&cmd_buffer->descriptors, 0, sizeof(cmd_buffer->descriptors));
2500
2501 result = anv_batch_bo_create(device, &cmd_buffer->last_batch_bo);
2502 if (result != VK_SUCCESS)
2503 goto fail;
2504
2505 result = anv_reloc_list_init(&cmd_buffer->batch.relocs, device);
2506 if (result != VK_SUCCESS)
2507 goto fail_batch_bo;
2508
2509 cmd_buffer->batch.device = device;
2510 cmd_buffer->batch.extend_cb = anv_cmd_buffer_chain_batch;
2511 cmd_buffer->batch.user_data = cmd_buffer;
2512
2513 anv_batch_bo_start(cmd_buffer->last_batch_bo, &cmd_buffer->batch,
2514 GEN8_MI_BATCH_BUFFER_START_length * 4);
2515
2516 result = anv_batch_bo_create(device, &cmd_buffer->surface_batch_bo);
2517 if (result != VK_SUCCESS)
2518 goto fail_batch_relocs;
2519 cmd_buffer->surface_batch_bo->first_reloc = 0;
2520
2521 result = anv_reloc_list_init(&cmd_buffer->surface_relocs, device);
2522 if (result != VK_SUCCESS)
2523 goto fail_ss_batch_bo;
2524
2525 /* Start surface_next at 1 so surface offset 0 is invalid. */
2526 cmd_buffer->surface_next = 1;
2527
2528 cmd_buffer->exec2_objects = NULL;
2529 cmd_buffer->exec2_bos = NULL;
2530 cmd_buffer->exec2_array_length = 0;
2531
2532 anv_state_stream_init(&cmd_buffer->surface_state_stream,
2533 &device->surface_state_block_pool);
2534 anv_state_stream_init(&cmd_buffer->dynamic_state_stream,
2535 &device->dynamic_state_block_pool);
2536
2537 cmd_buffer->dirty = 0;
2538 cmd_buffer->vb_dirty = 0;
2539 cmd_buffer->descriptors_dirty = 0;
2540 cmd_buffer->pipeline = NULL;
2541 cmd_buffer->vp_state = NULL;
2542 cmd_buffer->rs_state = NULL;
2543 cmd_buffer->ds_state = NULL;
2544
2545 *pCmdBuffer = anv_cmd_buffer_to_handle(cmd_buffer);
2546
2547 return VK_SUCCESS;
2548
2549 fail_ss_batch_bo:
2550 anv_batch_bo_destroy(cmd_buffer->surface_batch_bo, device);
2551 fail_batch_relocs:
2552 anv_reloc_list_finish(&cmd_buffer->batch.relocs, device);
2553 fail_batch_bo:
2554 anv_batch_bo_destroy(cmd_buffer->last_batch_bo, device);
2555 fail:
2556 anv_device_free(device, cmd_buffer);
2557
2558 return result;
2559 }
2560
2561 VkResult anv_DestroyCommandBuffer(
2562 VkDevice _device,
2563 VkCmdBuffer _cmd_buffer)
2564 {
2565 ANV_FROM_HANDLE(anv_device, device, _device);
2566 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, _cmd_buffer);
2567
2568 /* Destroy all of the batch buffers */
2569 struct anv_batch_bo *bbo = cmd_buffer->last_batch_bo;
2570 while (bbo) {
2571 struct anv_batch_bo *prev = bbo->prev_batch_bo;
2572 anv_batch_bo_destroy(bbo, device);
2573 bbo = prev;
2574 }
2575 anv_reloc_list_finish(&cmd_buffer->batch.relocs, device);
2576
2577 /* Destroy all of the surface state buffers */
2578 bbo = cmd_buffer->surface_batch_bo;
2579 while (bbo) {
2580 struct anv_batch_bo *prev = bbo->prev_batch_bo;
2581 anv_batch_bo_destroy(bbo, device);
2582 bbo = prev;
2583 }
2584 anv_reloc_list_finish(&cmd_buffer->surface_relocs, device);
2585
2586 anv_state_stream_finish(&cmd_buffer->surface_state_stream);
2587 anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);
2588 anv_device_free(device, cmd_buffer->exec2_objects);
2589 anv_device_free(device, cmd_buffer->exec2_bos);
2590 anv_device_free(device, cmd_buffer);
2591
2592 return VK_SUCCESS;
2593 }
2594
2595 static void
2596 anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer)
2597 {
2598 struct anv_device *device = cmd_buffer->device;
2599 struct anv_bo *scratch_bo = NULL;
2600
2601 cmd_buffer->scratch_size = device->scratch_block_pool.size;
2602 if (cmd_buffer->scratch_size > 0)
2603 scratch_bo = &device->scratch_block_pool.bo;
2604
2605 anv_batch_emit(&cmd_buffer->batch, GEN8_STATE_BASE_ADDRESS,
2606 .GeneralStateBaseAddress = { scratch_bo, 0 },
2607 .GeneralStateMemoryObjectControlState = GEN8_MOCS,
2608 .GeneralStateBaseAddressModifyEnable = true,
2609 .GeneralStateBufferSize = 0xfffff,
2610 .GeneralStateBufferSizeModifyEnable = true,
2611
2612 .SurfaceStateBaseAddress = { &cmd_buffer->surface_batch_bo->bo, 0 },
2613 .SurfaceStateMemoryObjectControlState = GEN8_MOCS,
2614 .SurfaceStateBaseAddressModifyEnable = true,
2615
2616 .DynamicStateBaseAddress = { &device->dynamic_state_block_pool.bo, 0 },
2617 .DynamicStateMemoryObjectControlState = GEN8_MOCS,
2618 .DynamicStateBaseAddressModifyEnable = true,
2619 .DynamicStateBufferSize = 0xfffff,
2620 .DynamicStateBufferSizeModifyEnable = true,
2621
2622 .IndirectObjectBaseAddress = { NULL, 0 },
2623 .IndirectObjectMemoryObjectControlState = GEN8_MOCS,
2624 .IndirectObjectBaseAddressModifyEnable = true,
2625 .IndirectObjectBufferSize = 0xfffff,
2626 .IndirectObjectBufferSizeModifyEnable = true,
2627
2628 .InstructionBaseAddress = { &device->instruction_block_pool.bo, 0 },
2629 .InstructionMemoryObjectControlState = GEN8_MOCS,
2630 .InstructionBaseAddressModifyEnable = true,
2631 .InstructionBufferSize = 0xfffff,
2632 .InstructionBuffersizeModifyEnable = true);
2633 }
2634
2635 VkResult anv_BeginCommandBuffer(
2636 VkCmdBuffer cmdBuffer,
2637 const VkCmdBufferBeginInfo* pBeginInfo)
2638 {
2639 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
2640
2641 anv_cmd_buffer_emit_state_base_address(cmd_buffer);
2642 cmd_buffer->current_pipeline = UINT32_MAX;
2643
2644 return VK_SUCCESS;
2645 }
2646
2647 static VkResult
2648 anv_cmd_buffer_add_bo(struct anv_cmd_buffer *cmd_buffer,
2649 struct anv_bo *bo,
2650 struct drm_i915_gem_relocation_entry *relocs,
2651 size_t num_relocs)
2652 {
2653 struct drm_i915_gem_exec_object2 *obj;
2654
2655 if (bo->index < cmd_buffer->bo_count &&
2656 cmd_buffer->exec2_bos[bo->index] == bo)
2657 return VK_SUCCESS;
2658
2659 if (cmd_buffer->bo_count >= cmd_buffer->exec2_array_length) {
2660 uint32_t new_len = cmd_buffer->exec2_objects ?
2661 cmd_buffer->exec2_array_length * 2 : 64;
2662
2663 struct drm_i915_gem_exec_object2 *new_objects =
2664 anv_device_alloc(cmd_buffer->device, new_len * sizeof(*new_objects),
2665 8, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
2666 if (new_objects == NULL)
2667 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2668
2669 struct anv_bo **new_bos =
2670 anv_device_alloc(cmd_buffer->device, new_len * sizeof(*new_bos),
2671 8, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
2672 if (new_objects == NULL) {
2673 anv_device_free(cmd_buffer->device, new_objects);
2674 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2675 }
2676
2677 if (cmd_buffer->exec2_objects) {
2678 memcpy(new_objects, cmd_buffer->exec2_objects,
2679 cmd_buffer->bo_count * sizeof(*new_objects));
2680 memcpy(new_bos, cmd_buffer->exec2_bos,
2681 cmd_buffer->bo_count * sizeof(*new_bos));
2682 }
2683
2684 cmd_buffer->exec2_objects = new_objects;
2685 cmd_buffer->exec2_bos = new_bos;
2686 cmd_buffer->exec2_array_length = new_len;
2687 }
2688
2689 assert(cmd_buffer->bo_count < cmd_buffer->exec2_array_length);
2690
2691 bo->index = cmd_buffer->bo_count++;
2692 obj = &cmd_buffer->exec2_objects[bo->index];
2693 cmd_buffer->exec2_bos[bo->index] = bo;
2694
2695 obj->handle = bo->gem_handle;
2696 obj->relocation_count = 0;
2697 obj->relocs_ptr = 0;
2698 obj->alignment = 0;
2699 obj->offset = bo->offset;
2700 obj->flags = 0;
2701 obj->rsvd1 = 0;
2702 obj->rsvd2 = 0;
2703
2704 if (relocs) {
2705 obj->relocation_count = num_relocs;
2706 obj->relocs_ptr = (uintptr_t) relocs;
2707 }
2708
2709 return VK_SUCCESS;
2710 }
2711
2712 static void
2713 anv_cmd_buffer_add_validate_bos(struct anv_cmd_buffer *cmd_buffer,
2714 struct anv_reloc_list *list)
2715 {
2716 for (size_t i = 0; i < list->num_relocs; i++)
2717 anv_cmd_buffer_add_bo(cmd_buffer, list->reloc_bos[i], NULL, 0);
2718 }
2719
2720 static void
2721 anv_cmd_buffer_process_relocs(struct anv_cmd_buffer *cmd_buffer,
2722 struct anv_reloc_list *list)
2723 {
2724 struct anv_bo *bo;
2725
2726 /* If the kernel supports I915_EXEC_NO_RELOC, it will compare offset in
2727 * struct drm_i915_gem_exec_object2 against the bos current offset and if
2728 * all bos haven't moved it will skip relocation processing alltogether.
2729 * If I915_EXEC_NO_RELOC is not supported, the kernel ignores the incoming
2730 * value of offset so we can set it either way. For that to work we need
2731 * to make sure all relocs use the same presumed offset.
2732 */
2733
2734 for (size_t i = 0; i < list->num_relocs; i++) {
2735 bo = list->reloc_bos[i];
2736 if (bo->offset != list->relocs[i].presumed_offset)
2737 cmd_buffer->need_reloc = true;
2738
2739 list->relocs[i].target_handle = bo->index;
2740 }
2741 }
2742
2743 VkResult anv_EndCommandBuffer(
2744 VkCmdBuffer cmdBuffer)
2745 {
2746 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
2747 struct anv_device *device = cmd_buffer->device;
2748 struct anv_batch *batch = &cmd_buffer->batch;
2749
2750 anv_batch_emit(batch, GEN8_MI_BATCH_BUFFER_END);
2751
2752 /* Round batch up to an even number of dwords. */
2753 if ((batch->next - batch->start) & 4)
2754 anv_batch_emit(batch, GEN8_MI_NOOP);
2755
2756 anv_batch_bo_finish(cmd_buffer->last_batch_bo, &cmd_buffer->batch);
2757 cmd_buffer->surface_batch_bo->num_relocs =
2758 cmd_buffer->surface_relocs.num_relocs - cmd_buffer->surface_batch_bo->first_reloc;
2759 cmd_buffer->surface_batch_bo->length = cmd_buffer->surface_next;
2760
2761 cmd_buffer->bo_count = 0;
2762 cmd_buffer->need_reloc = false;
2763
2764 /* Lock for access to bo->index. */
2765 pthread_mutex_lock(&device->mutex);
2766
2767 /* Add surface state bos first so we can add them with their relocs. */
2768 for (struct anv_batch_bo *bbo = cmd_buffer->surface_batch_bo;
2769 bbo != NULL; bbo = bbo->prev_batch_bo) {
2770 anv_cmd_buffer_add_bo(cmd_buffer, &bbo->bo,
2771 &cmd_buffer->surface_relocs.relocs[bbo->first_reloc],
2772 bbo->num_relocs);
2773 }
2774
2775 /* Add all of the BOs referenced by surface state */
2776 anv_cmd_buffer_add_validate_bos(cmd_buffer, &cmd_buffer->surface_relocs);
2777
2778 /* Add all but the first batch BO */
2779 struct anv_batch_bo *batch_bo = cmd_buffer->last_batch_bo;
2780 while (batch_bo->prev_batch_bo) {
2781 anv_cmd_buffer_add_bo(cmd_buffer, &batch_bo->bo,
2782 &batch->relocs.relocs[batch_bo->first_reloc],
2783 batch_bo->num_relocs);
2784 batch_bo = batch_bo->prev_batch_bo;
2785 }
2786
2787 /* Add everything referenced by the batches */
2788 anv_cmd_buffer_add_validate_bos(cmd_buffer, &batch->relocs);
2789
2790 /* Add the first batch bo last */
2791 assert(batch_bo->prev_batch_bo == NULL && batch_bo->first_reloc == 0);
2792 anv_cmd_buffer_add_bo(cmd_buffer, &batch_bo->bo,
2793 &batch->relocs.relocs[batch_bo->first_reloc],
2794 batch_bo->num_relocs);
2795 assert(batch_bo->bo.index == cmd_buffer->bo_count - 1);
2796
2797 anv_cmd_buffer_process_relocs(cmd_buffer, &cmd_buffer->surface_relocs);
2798 anv_cmd_buffer_process_relocs(cmd_buffer, &batch->relocs);
2799
2800 cmd_buffer->execbuf.buffers_ptr = (uintptr_t) cmd_buffer->exec2_objects;
2801 cmd_buffer->execbuf.buffer_count = cmd_buffer->bo_count;
2802 cmd_buffer->execbuf.batch_start_offset = 0;
2803 cmd_buffer->execbuf.batch_len = batch->next - batch->start;
2804 cmd_buffer->execbuf.cliprects_ptr = 0;
2805 cmd_buffer->execbuf.num_cliprects = 0;
2806 cmd_buffer->execbuf.DR1 = 0;
2807 cmd_buffer->execbuf.DR4 = 0;
2808
2809 cmd_buffer->execbuf.flags = I915_EXEC_HANDLE_LUT;
2810 if (!cmd_buffer->need_reloc)
2811 cmd_buffer->execbuf.flags |= I915_EXEC_NO_RELOC;
2812 cmd_buffer->execbuf.flags |= I915_EXEC_RENDER;
2813 cmd_buffer->execbuf.rsvd1 = device->context_id;
2814 cmd_buffer->execbuf.rsvd2 = 0;
2815
2816 pthread_mutex_unlock(&device->mutex);
2817
2818 return VK_SUCCESS;
2819 }
2820
2821 VkResult anv_ResetCommandBuffer(
2822 VkCmdBuffer cmdBuffer)
2823 {
2824 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
2825
2826 /* Delete all but the first batch bo */
2827 while (cmd_buffer->last_batch_bo->prev_batch_bo) {
2828 struct anv_batch_bo *prev = cmd_buffer->last_batch_bo->prev_batch_bo;
2829 anv_batch_bo_destroy(cmd_buffer->last_batch_bo, cmd_buffer->device);
2830 cmd_buffer->last_batch_bo = prev;
2831 }
2832 assert(cmd_buffer->last_batch_bo->prev_batch_bo == NULL);
2833
2834 cmd_buffer->batch.relocs.num_relocs = 0;
2835 anv_batch_bo_start(cmd_buffer->last_batch_bo, &cmd_buffer->batch,
2836 GEN8_MI_BATCH_BUFFER_START_length * 4);
2837
2838 /* Delete all but the first batch bo */
2839 while (cmd_buffer->surface_batch_bo->prev_batch_bo) {
2840 struct anv_batch_bo *prev = cmd_buffer->surface_batch_bo->prev_batch_bo;
2841 anv_batch_bo_destroy(cmd_buffer->surface_batch_bo, cmd_buffer->device);
2842 cmd_buffer->surface_batch_bo = prev;
2843 }
2844 assert(cmd_buffer->surface_batch_bo->prev_batch_bo == NULL);
2845
2846 cmd_buffer->surface_next = 1;
2847 cmd_buffer->surface_relocs.num_relocs = 0;
2848
2849 cmd_buffer->rs_state = NULL;
2850 cmd_buffer->vp_state = NULL;
2851 cmd_buffer->cb_state = NULL;
2852 cmd_buffer->ds_state = NULL;
2853
2854 return VK_SUCCESS;
2855 }
2856
2857 // Command buffer building functions
2858
2859 void anv_CmdBindPipeline(
2860 VkCmdBuffer cmdBuffer,
2861 VkPipelineBindPoint pipelineBindPoint,
2862 VkPipeline _pipeline)
2863 {
2864 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
2865 ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline);
2866
2867 switch (pipelineBindPoint) {
2868 case VK_PIPELINE_BIND_POINT_COMPUTE:
2869 cmd_buffer->compute_pipeline = pipeline;
2870 cmd_buffer->compute_dirty |= ANV_CMD_BUFFER_PIPELINE_DIRTY;
2871 break;
2872
2873 case VK_PIPELINE_BIND_POINT_GRAPHICS:
2874 cmd_buffer->pipeline = pipeline;
2875 cmd_buffer->vb_dirty |= pipeline->vb_used;
2876 cmd_buffer->dirty |= ANV_CMD_BUFFER_PIPELINE_DIRTY;
2877 break;
2878
2879 default:
2880 assert(!"invalid bind point");
2881 break;
2882 }
2883 }
2884
2885 void anv_CmdBindDynamicViewportState(
2886 VkCmdBuffer cmdBuffer,
2887 VkDynamicViewportState dynamicViewportState)
2888 {
2889 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
2890 ANV_FROM_HANDLE(anv_dynamic_vp_state, vp_state, dynamicViewportState);
2891
2892 cmd_buffer->vp_state = vp_state;
2893 cmd_buffer->dirty |= ANV_CMD_BUFFER_VP_DIRTY;
2894 }
2895
2896 void anv_CmdBindDynamicRasterState(
2897 VkCmdBuffer cmdBuffer,
2898 VkDynamicRasterState dynamicRasterState)
2899 {
2900 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
2901 ANV_FROM_HANDLE(anv_dynamic_rs_state, rs_state, dynamicRasterState);
2902
2903 cmd_buffer->rs_state = rs_state;
2904 cmd_buffer->dirty |= ANV_CMD_BUFFER_RS_DIRTY;
2905 }
2906
2907 void anv_CmdBindDynamicColorBlendState(
2908 VkCmdBuffer cmdBuffer,
2909 VkDynamicColorBlendState dynamicColorBlendState)
2910 {
2911 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
2912 ANV_FROM_HANDLE(anv_dynamic_cb_state, cb_state, dynamicColorBlendState);
2913
2914 cmd_buffer->cb_state = cb_state;
2915 cmd_buffer->dirty |= ANV_CMD_BUFFER_CB_DIRTY;
2916 }
2917
2918 void anv_CmdBindDynamicDepthStencilState(
2919 VkCmdBuffer cmdBuffer,
2920 VkDynamicDepthStencilState dynamicDepthStencilState)
2921 {
2922 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
2923 ANV_FROM_HANDLE(anv_dynamic_ds_state, ds_state, dynamicDepthStencilState);
2924
2925 cmd_buffer->ds_state = ds_state;
2926 cmd_buffer->dirty |= ANV_CMD_BUFFER_DS_DIRTY;
2927 }
2928
2929 static struct anv_state
2930 anv_cmd_buffer_alloc_surface_state(struct anv_cmd_buffer *cmd_buffer,
2931 uint32_t size, uint32_t alignment)
2932 {
2933 struct anv_state state;
2934
2935 state.offset = align_u32(cmd_buffer->surface_next, alignment);
2936 if (state.offset + size > cmd_buffer->surface_batch_bo->bo.size)
2937 return (struct anv_state) { 0 };
2938
2939 state.map = cmd_buffer->surface_batch_bo->bo.map + state.offset;
2940 state.alloc_size = size;
2941 cmd_buffer->surface_next = state.offset + size;
2942
2943 assert(state.offset + size <= cmd_buffer->surface_batch_bo->bo.size);
2944
2945 return state;
2946 }
2947
2948 static VkResult
2949 anv_cmd_buffer_new_surface_state_bo(struct anv_cmd_buffer *cmd_buffer)
2950 {
2951 struct anv_batch_bo *new_bbo, *old_bbo = cmd_buffer->surface_batch_bo;
2952
2953 /* Finish off the old buffer */
2954 old_bbo->num_relocs =
2955 cmd_buffer->surface_relocs.num_relocs - old_bbo->first_reloc;
2956 old_bbo->length = cmd_buffer->surface_next;
2957
2958 VkResult result = anv_batch_bo_create(cmd_buffer->device, &new_bbo);
2959 if (result != VK_SUCCESS)
2960 return result;
2961
2962 new_bbo->first_reloc = cmd_buffer->surface_relocs.num_relocs;
2963 cmd_buffer->surface_next = 1;
2964
2965 new_bbo->prev_batch_bo = old_bbo;
2966 cmd_buffer->surface_batch_bo = new_bbo;
2967
2968 /* Re-emit state base addresses so we get the new surface state base
2969 * address before we start emitting binding tables etc.
2970 */
2971 anv_cmd_buffer_emit_state_base_address(cmd_buffer);
2972
2973 /* It seems like just changing the state base addresses isn't enough.
2974 * Invalidating the cache seems to be enough to cause things to
2975 * propagate. However, I'm not 100% sure what we're supposed to do.
2976 */
2977 anv_batch_emit(&cmd_buffer->batch, GEN8_PIPE_CONTROL,
2978 .TextureCacheInvalidationEnable = true);
2979
2980 return VK_SUCCESS;
2981 }
2982
2983 void anv_CmdBindDescriptorSets(
2984 VkCmdBuffer cmdBuffer,
2985 VkPipelineBindPoint pipelineBindPoint,
2986 VkPipelineLayout _layout,
2987 uint32_t firstSet,
2988 uint32_t setCount,
2989 const VkDescriptorSet* pDescriptorSets,
2990 uint32_t dynamicOffsetCount,
2991 const uint32_t* pDynamicOffsets)
2992 {
2993 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
2994 ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
2995 struct anv_descriptor_set_layout *set_layout;
2996
2997 assert(firstSet + setCount < MAX_SETS);
2998
2999 uint32_t dynamic_slot = 0;
3000 for (uint32_t i = 0; i < setCount; i++) {
3001 ANV_FROM_HANDLE(anv_descriptor_set, set, pDescriptorSets[i]);
3002 set_layout = layout->set[firstSet + i].layout;
3003
3004 cmd_buffer->descriptors[firstSet + i].set = set;
3005
3006 assert(set_layout->num_dynamic_buffers <
3007 ARRAY_SIZE(cmd_buffer->descriptors[0].dynamic_offsets));
3008 memcpy(cmd_buffer->descriptors[firstSet + i].dynamic_offsets,
3009 pDynamicOffsets + dynamic_slot,
3010 set_layout->num_dynamic_buffers * sizeof(*pDynamicOffsets));
3011
3012 cmd_buffer->descriptors_dirty |= set_layout->shader_stages;
3013
3014 dynamic_slot += set_layout->num_dynamic_buffers;
3015 }
3016 }
3017
3018 void anv_CmdBindIndexBuffer(
3019 VkCmdBuffer cmdBuffer,
3020 VkBuffer _buffer,
3021 VkDeviceSize offset,
3022 VkIndexType indexType)
3023 {
3024 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
3025 ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
3026
3027 static const uint32_t vk_to_gen_index_type[] = {
3028 [VK_INDEX_TYPE_UINT16] = INDEX_WORD,
3029 [VK_INDEX_TYPE_UINT32] = INDEX_DWORD,
3030 };
3031
3032 struct GEN8_3DSTATE_VF vf = {
3033 GEN8_3DSTATE_VF_header,
3034 .CutIndex = (indexType == VK_INDEX_TYPE_UINT16) ? UINT16_MAX : UINT32_MAX,
3035 };
3036 GEN8_3DSTATE_VF_pack(NULL, cmd_buffer->state_vf, &vf);
3037
3038 cmd_buffer->dirty |= ANV_CMD_BUFFER_INDEX_BUFFER_DIRTY;
3039
3040 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_INDEX_BUFFER,
3041 .IndexFormat = vk_to_gen_index_type[indexType],
3042 .MemoryObjectControlState = GEN8_MOCS,
3043 .BufferStartingAddress = { buffer->bo, buffer->offset + offset },
3044 .BufferSize = buffer->size - offset);
3045 }
3046
3047 void anv_CmdBindVertexBuffers(
3048 VkCmdBuffer cmdBuffer,
3049 uint32_t startBinding,
3050 uint32_t bindingCount,
3051 const VkBuffer* pBuffers,
3052 const VkDeviceSize* pOffsets)
3053 {
3054 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
3055 struct anv_vertex_binding *vb = cmd_buffer->vertex_bindings;
3056
3057 /* We have to defer setting up vertex buffer since we need the buffer
3058 * stride from the pipeline. */
3059
3060 assert(startBinding + bindingCount < MAX_VBS);
3061 for (uint32_t i = 0; i < bindingCount; i++) {
3062 vb[startBinding + i].buffer = anv_buffer_from_handle(pBuffers[i]);
3063 vb[startBinding + i].offset = pOffsets[i];
3064 cmd_buffer->vb_dirty |= 1 << (startBinding + i);
3065 }
3066 }
3067
3068 static VkResult
3069 cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
3070 unsigned stage, struct anv_state *bt_state)
3071 {
3072 struct anv_framebuffer *fb = cmd_buffer->framebuffer;
3073 struct anv_subpass *subpass = cmd_buffer->subpass;
3074 struct anv_pipeline_layout *layout;
3075 uint32_t attachments, bias, size;
3076
3077 if (stage == VK_SHADER_STAGE_COMPUTE)
3078 layout = cmd_buffer->compute_pipeline->layout;
3079 else
3080 layout = cmd_buffer->pipeline->layout;
3081
3082 if (stage == VK_SHADER_STAGE_FRAGMENT) {
3083 bias = MAX_RTS;
3084 attachments = subpass->color_count;
3085 } else {
3086 bias = 0;
3087 attachments = 0;
3088 }
3089
3090 /* This is a little awkward: layout can be NULL but we still have to
3091 * allocate and set a binding table for the PS stage for render
3092 * targets. */
3093 uint32_t surface_count = layout ? layout->stage[stage].surface_count : 0;
3094
3095 if (attachments + surface_count == 0)
3096 return VK_SUCCESS;
3097
3098 size = (bias + surface_count) * sizeof(uint32_t);
3099 *bt_state = anv_cmd_buffer_alloc_surface_state(cmd_buffer, size, 32);
3100 uint32_t *bt_map = bt_state->map;
3101
3102 if (bt_state->map == NULL)
3103 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
3104
3105 /* This is highly annoying. The Vulkan spec puts the depth-stencil
3106 * attachments in with the color attachments. Unfortunately, thanks to
3107 * other aspects of the API, we cana't really saparate them before this
3108 * point. Therefore, we have to walk all of the attachments but only
3109 * put the color attachments into the binding table.
3110 */
3111 for (uint32_t a = 0; a < attachments; a++) {
3112 const struct anv_attachment_view *attachment =
3113 fb->attachments[subpass->color_attachments[a]];
3114
3115 assert(attachment->attachment_type == ANV_ATTACHMENT_VIEW_TYPE_COLOR);
3116 const struct anv_color_attachment_view *view =
3117 (const struct anv_color_attachment_view *)attachment;
3118
3119 struct anv_state state =
3120 anv_cmd_buffer_alloc_surface_state(cmd_buffer, 64, 64);
3121
3122 if (state.map == NULL)
3123 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
3124
3125 memcpy(state.map, view->view.surface_state.map, 64);
3126
3127 /* The address goes in dwords 8 and 9 of the SURFACE_STATE */
3128 *(uint64_t *)(state.map + 8 * 4) =
3129 anv_reloc_list_add(&cmd_buffer->surface_relocs,
3130 cmd_buffer->device,
3131 state.offset + 8 * 4,
3132 view->view.bo, view->view.offset);
3133
3134 bt_map[a] = state.offset;
3135 }
3136
3137 if (layout == NULL)
3138 return VK_SUCCESS;
3139
3140 for (uint32_t set = 0; set < layout->num_sets; set++) {
3141 struct anv_descriptor_set_binding *d = &cmd_buffer->descriptors[set];
3142 struct anv_descriptor_set_layout *set_layout = layout->set[set].layout;
3143 struct anv_descriptor_slot *surface_slots =
3144 set_layout->stage[stage].surface_start;
3145
3146 uint32_t start = bias + layout->set[set].surface_start[stage];
3147
3148 for (uint32_t b = 0; b < set_layout->stage[stage].surface_count; b++) {
3149 struct anv_surface_view *view =
3150 d->set->descriptors[surface_slots[b].index].view;
3151
3152 if (!view)
3153 continue;
3154
3155 struct anv_state state =
3156 anv_cmd_buffer_alloc_surface_state(cmd_buffer, 64, 64);
3157
3158 if (state.map == NULL)
3159 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
3160
3161 uint32_t offset;
3162 if (surface_slots[b].dynamic_slot >= 0) {
3163 uint32_t dynamic_offset =
3164 d->dynamic_offsets[surface_slots[b].dynamic_slot];
3165
3166 offset = view->offset + dynamic_offset;
3167 fill_buffer_surface_state(state.map, view->format, offset,
3168 view->range - dynamic_offset);
3169 } else {
3170 offset = view->offset;
3171 memcpy(state.map, view->surface_state.map, 64);
3172 }
3173
3174 /* The address goes in dwords 8 and 9 of the SURFACE_STATE */
3175 *(uint64_t *)(state.map + 8 * 4) =
3176 anv_reloc_list_add(&cmd_buffer->surface_relocs,
3177 cmd_buffer->device,
3178 state.offset + 8 * 4,
3179 view->bo, offset);
3180
3181 bt_map[start + b] = state.offset;
3182 }
3183 }
3184
3185 return VK_SUCCESS;
3186 }
3187
3188 static VkResult
3189 cmd_buffer_emit_samplers(struct anv_cmd_buffer *cmd_buffer,
3190 unsigned stage, struct anv_state *state)
3191 {
3192 struct anv_pipeline_layout *layout;
3193 uint32_t sampler_count;
3194
3195 if (stage == VK_SHADER_STAGE_COMPUTE)
3196 layout = cmd_buffer->compute_pipeline->layout;
3197 else
3198 layout = cmd_buffer->pipeline->layout;
3199
3200 sampler_count = layout ? layout->stage[stage].sampler_count : 0;
3201 if (sampler_count == 0)
3202 return VK_SUCCESS;
3203
3204 uint32_t size = sampler_count * 16;
3205 *state = anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream, size, 32);
3206
3207 if (state->map == NULL)
3208 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
3209
3210 for (uint32_t set = 0; set < layout->num_sets; set++) {
3211 struct anv_descriptor_set_binding *d = &cmd_buffer->descriptors[set];
3212 struct anv_descriptor_set_layout *set_layout = layout->set[set].layout;
3213 struct anv_descriptor_slot *sampler_slots =
3214 set_layout->stage[stage].sampler_start;
3215
3216 uint32_t start = layout->set[set].sampler_start[stage];
3217
3218 for (uint32_t b = 0; b < set_layout->stage[stage].sampler_count; b++) {
3219 struct anv_sampler *sampler =
3220 d->set->descriptors[sampler_slots[b].index].sampler;
3221
3222 if (!sampler)
3223 continue;
3224
3225 memcpy(state->map + (start + b) * 16,
3226 sampler->state, sizeof(sampler->state));
3227 }
3228 }
3229
3230 return VK_SUCCESS;
3231 }
3232
3233 static VkResult
3234 flush_descriptor_set(struct anv_cmd_buffer *cmd_buffer, uint32_t stage)
3235 {
3236 struct anv_state surfaces = { 0, }, samplers = { 0, };
3237 VkResult result;
3238
3239 result = cmd_buffer_emit_samplers(cmd_buffer, stage, &samplers);
3240 if (result != VK_SUCCESS)
3241 return result;
3242 result = cmd_buffer_emit_binding_table(cmd_buffer, stage, &surfaces);
3243 if (result != VK_SUCCESS)
3244 return result;
3245
3246 static const uint32_t sampler_state_opcodes[] = {
3247 [VK_SHADER_STAGE_VERTEX] = 43,
3248 [VK_SHADER_STAGE_TESS_CONTROL] = 44, /* HS */
3249 [VK_SHADER_STAGE_TESS_EVALUATION] = 45, /* DS */
3250 [VK_SHADER_STAGE_GEOMETRY] = 46,
3251 [VK_SHADER_STAGE_FRAGMENT] = 47,
3252 [VK_SHADER_STAGE_COMPUTE] = 0,
3253 };
3254
3255 static const uint32_t binding_table_opcodes[] = {
3256 [VK_SHADER_STAGE_VERTEX] = 38,
3257 [VK_SHADER_STAGE_TESS_CONTROL] = 39,
3258 [VK_SHADER_STAGE_TESS_EVALUATION] = 40,
3259 [VK_SHADER_STAGE_GEOMETRY] = 41,
3260 [VK_SHADER_STAGE_FRAGMENT] = 42,
3261 [VK_SHADER_STAGE_COMPUTE] = 0,
3262 };
3263
3264 if (samplers.alloc_size > 0) {
3265 anv_batch_emit(&cmd_buffer->batch,
3266 GEN8_3DSTATE_SAMPLER_STATE_POINTERS_VS,
3267 ._3DCommandSubOpcode = sampler_state_opcodes[stage],
3268 .PointertoVSSamplerState = samplers.offset);
3269 }
3270
3271 if (surfaces.alloc_size > 0) {
3272 anv_batch_emit(&cmd_buffer->batch,
3273 GEN8_3DSTATE_BINDING_TABLE_POINTERS_VS,
3274 ._3DCommandSubOpcode = binding_table_opcodes[stage],
3275 .PointertoVSBindingTable = surfaces.offset);
3276 }
3277
3278 return VK_SUCCESS;
3279 }
3280
3281 static void
3282 flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer)
3283 {
3284 uint32_t s, dirty = cmd_buffer->descriptors_dirty &
3285 cmd_buffer->pipeline->active_stages;
3286
3287 VkResult result = VK_SUCCESS;
3288 for_each_bit(s, dirty) {
3289 result = flush_descriptor_set(cmd_buffer, s);
3290 if (result != VK_SUCCESS)
3291 break;
3292 }
3293
3294 if (result != VK_SUCCESS) {
3295 assert(result == VK_ERROR_OUT_OF_DEVICE_MEMORY);
3296
3297 result = anv_cmd_buffer_new_surface_state_bo(cmd_buffer);
3298 assert(result == VK_SUCCESS);
3299
3300 /* Re-emit all active binding tables */
3301 for_each_bit(s, cmd_buffer->pipeline->active_stages) {
3302 result = flush_descriptor_set(cmd_buffer, s);
3303
3304 /* It had better succeed this time */
3305 assert(result == VK_SUCCESS);
3306 }
3307 }
3308
3309 cmd_buffer->descriptors_dirty &= ~cmd_buffer->pipeline->active_stages;
3310 }
3311
3312 static struct anv_state
3313 anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer *cmd_buffer,
3314 uint32_t *a, uint32_t dwords, uint32_t alignment)
3315 {
3316 struct anv_state state;
3317
3318 state = anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream,
3319 dwords * 4, alignment);
3320 memcpy(state.map, a, dwords * 4);
3321
3322 VG(VALGRIND_CHECK_MEM_IS_DEFINED(state.map, dwords * 4));
3323
3324 return state;
3325 }
3326
3327 static struct anv_state
3328 anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer *cmd_buffer,
3329 uint32_t *a, uint32_t *b,
3330 uint32_t dwords, uint32_t alignment)
3331 {
3332 struct anv_state state;
3333 uint32_t *p;
3334
3335 state = anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream,
3336 dwords * 4, alignment);
3337 p = state.map;
3338 for (uint32_t i = 0; i < dwords; i++)
3339 p[i] = a[i] | b[i];
3340
3341 VG(VALGRIND_CHECK_MEM_IS_DEFINED(p, dwords * 4));
3342
3343 return state;
3344 }
3345
3346 static VkResult
3347 flush_compute_descriptor_set(struct anv_cmd_buffer *cmd_buffer)
3348 {
3349 struct anv_device *device = cmd_buffer->device;
3350 struct anv_pipeline *pipeline = cmd_buffer->compute_pipeline;
3351 struct anv_state surfaces = { 0, }, samplers = { 0, };
3352 VkResult result;
3353
3354 result = cmd_buffer_emit_samplers(cmd_buffer,
3355 VK_SHADER_STAGE_COMPUTE, &samplers);
3356 if (result != VK_SUCCESS)
3357 return result;
3358 result = cmd_buffer_emit_binding_table(cmd_buffer,
3359 VK_SHADER_STAGE_COMPUTE, &surfaces);
3360 if (result != VK_SUCCESS)
3361 return result;
3362
3363 struct GEN8_INTERFACE_DESCRIPTOR_DATA desc = {
3364 .KernelStartPointer = pipeline->cs_simd,
3365 .KernelStartPointerHigh = 0,
3366 .BindingTablePointer = surfaces.offset,
3367 .BindingTableEntryCount = 0,
3368 .SamplerStatePointer = samplers.offset,
3369 .SamplerCount = 0,
3370 .NumberofThreadsinGPGPUThreadGroup = 0 /* FIXME: Really? */
3371 };
3372
3373 uint32_t size = GEN8_INTERFACE_DESCRIPTOR_DATA_length * sizeof(uint32_t);
3374 struct anv_state state =
3375 anv_state_pool_alloc(&device->dynamic_state_pool, size, 64);
3376
3377 GEN8_INTERFACE_DESCRIPTOR_DATA_pack(NULL, state.map, &desc);
3378
3379 anv_batch_emit(&cmd_buffer->batch, GEN8_MEDIA_INTERFACE_DESCRIPTOR_LOAD,
3380 .InterfaceDescriptorTotalLength = size,
3381 .InterfaceDescriptorDataStartAddress = state.offset);
3382
3383 return VK_SUCCESS;
3384 }
3385
3386 static void
3387 anv_cmd_buffer_flush_compute_state(struct anv_cmd_buffer *cmd_buffer)
3388 {
3389 struct anv_pipeline *pipeline = cmd_buffer->compute_pipeline;
3390 VkResult result;
3391
3392 assert(pipeline->active_stages == VK_SHADER_STAGE_COMPUTE_BIT);
3393
3394 if (cmd_buffer->current_pipeline != GPGPU) {
3395 anv_batch_emit(&cmd_buffer->batch, GEN8_PIPELINE_SELECT,
3396 .PipelineSelection = GPGPU);
3397 cmd_buffer->current_pipeline = GPGPU;
3398 }
3399
3400 if (cmd_buffer->compute_dirty & ANV_CMD_BUFFER_PIPELINE_DIRTY)
3401 anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->batch);
3402
3403 if ((cmd_buffer->descriptors_dirty & VK_SHADER_STAGE_COMPUTE_BIT) ||
3404 (cmd_buffer->compute_dirty & ANV_CMD_BUFFER_PIPELINE_DIRTY)) {
3405 result = flush_compute_descriptor_set(cmd_buffer);
3406 if (result != VK_SUCCESS) {
3407 result = anv_cmd_buffer_new_surface_state_bo(cmd_buffer);
3408 assert(result == VK_SUCCESS);
3409 result = flush_compute_descriptor_set(cmd_buffer);
3410 assert(result == VK_SUCCESS);
3411 }
3412 cmd_buffer->descriptors_dirty &= ~VK_SHADER_STAGE_COMPUTE;
3413 }
3414
3415 cmd_buffer->compute_dirty = 0;
3416 }
3417
3418 static void
3419 anv_cmd_buffer_flush_state(struct anv_cmd_buffer *cmd_buffer)
3420 {
3421 struct anv_pipeline *pipeline = cmd_buffer->pipeline;
3422 uint32_t *p;
3423
3424 uint32_t vb_emit = cmd_buffer->vb_dirty & pipeline->vb_used;
3425
3426 assert((pipeline->active_stages & VK_SHADER_STAGE_COMPUTE_BIT) == 0);
3427
3428 if (cmd_buffer->current_pipeline != _3D) {
3429 anv_batch_emit(&cmd_buffer->batch, GEN8_PIPELINE_SELECT,
3430 .PipelineSelection = _3D);
3431 cmd_buffer->current_pipeline = _3D;
3432 }
3433
3434 if (vb_emit) {
3435 const uint32_t num_buffers = __builtin_popcount(vb_emit);
3436 const uint32_t num_dwords = 1 + num_buffers * 4;
3437
3438 p = anv_batch_emitn(&cmd_buffer->batch, num_dwords,
3439 GEN8_3DSTATE_VERTEX_BUFFERS);
3440 uint32_t vb, i = 0;
3441 for_each_bit(vb, vb_emit) {
3442 struct anv_buffer *buffer = cmd_buffer->vertex_bindings[vb].buffer;
3443 uint32_t offset = cmd_buffer->vertex_bindings[vb].offset;
3444
3445 struct GEN8_VERTEX_BUFFER_STATE state = {
3446 .VertexBufferIndex = vb,
3447 .MemoryObjectControlState = GEN8_MOCS,
3448 .AddressModifyEnable = true,
3449 .BufferPitch = pipeline->binding_stride[vb],
3450 .BufferStartingAddress = { buffer->bo, buffer->offset + offset },
3451 .BufferSize = buffer->size - offset
3452 };
3453
3454 GEN8_VERTEX_BUFFER_STATE_pack(&cmd_buffer->batch, &p[1 + i * 4], &state);
3455 i++;
3456 }
3457 }
3458
3459 if (cmd_buffer->dirty & ANV_CMD_BUFFER_PIPELINE_DIRTY) {
3460 /* If somebody compiled a pipeline after starting a command buffer the
3461 * scratch bo may have grown since we started this cmd buffer (and
3462 * emitted STATE_BASE_ADDRESS). If we're binding that pipeline now,
3463 * reemit STATE_BASE_ADDRESS so that we use the bigger scratch bo. */
3464 if (cmd_buffer->scratch_size < pipeline->total_scratch)
3465 anv_cmd_buffer_emit_state_base_address(cmd_buffer);
3466
3467 anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->batch);
3468 }
3469
3470 if (cmd_buffer->descriptors_dirty)
3471 flush_descriptor_sets(cmd_buffer);
3472
3473 if (cmd_buffer->dirty & ANV_CMD_BUFFER_VP_DIRTY) {
3474 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_SCISSOR_STATE_POINTERS,
3475 .ScissorRectPointer = cmd_buffer->vp_state->scissor.offset);
3476 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_CC,
3477 .CCViewportPointer = cmd_buffer->vp_state->cc_vp.offset);
3478 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP,
3479 .SFClipViewportPointer = cmd_buffer->vp_state->sf_clip_vp.offset);
3480 }
3481
3482 if (cmd_buffer->dirty & (ANV_CMD_BUFFER_PIPELINE_DIRTY | ANV_CMD_BUFFER_RS_DIRTY)) {
3483 anv_batch_emit_merge(&cmd_buffer->batch,
3484 cmd_buffer->rs_state->state_sf, pipeline->state_sf);
3485 anv_batch_emit_merge(&cmd_buffer->batch,
3486 cmd_buffer->rs_state->state_raster, pipeline->state_raster);
3487 }
3488
3489 if (cmd_buffer->ds_state &&
3490 (cmd_buffer->dirty & (ANV_CMD_BUFFER_PIPELINE_DIRTY | ANV_CMD_BUFFER_DS_DIRTY)))
3491 anv_batch_emit_merge(&cmd_buffer->batch,
3492 cmd_buffer->ds_state->state_wm_depth_stencil,
3493 pipeline->state_wm_depth_stencil);
3494
3495 if (cmd_buffer->dirty & (ANV_CMD_BUFFER_CB_DIRTY | ANV_CMD_BUFFER_DS_DIRTY)) {
3496 struct anv_state state;
3497 if (cmd_buffer->ds_state == NULL)
3498 state = anv_cmd_buffer_emit_dynamic(cmd_buffer,
3499 cmd_buffer->cb_state->state_color_calc,
3500 GEN8_COLOR_CALC_STATE_length, 64);
3501 else if (cmd_buffer->cb_state == NULL)
3502 state = anv_cmd_buffer_emit_dynamic(cmd_buffer,
3503 cmd_buffer->ds_state->state_color_calc,
3504 GEN8_COLOR_CALC_STATE_length, 64);
3505 else
3506 state = anv_cmd_buffer_merge_dynamic(cmd_buffer,
3507 cmd_buffer->ds_state->state_color_calc,
3508 cmd_buffer->cb_state->state_color_calc,
3509 GEN8_COLOR_CALC_STATE_length, 64);
3510
3511 anv_batch_emit(&cmd_buffer->batch,
3512 GEN8_3DSTATE_CC_STATE_POINTERS,
3513 .ColorCalcStatePointer = state.offset,
3514 .ColorCalcStatePointerValid = true);
3515 }
3516
3517 if (cmd_buffer->dirty & (ANV_CMD_BUFFER_PIPELINE_DIRTY | ANV_CMD_BUFFER_INDEX_BUFFER_DIRTY)) {
3518 anv_batch_emit_merge(&cmd_buffer->batch,
3519 cmd_buffer->state_vf, pipeline->state_vf);
3520 }
3521
3522 cmd_buffer->vb_dirty &= ~vb_emit;
3523 cmd_buffer->dirty = 0;
3524 }
3525
3526 void anv_CmdDraw(
3527 VkCmdBuffer cmdBuffer,
3528 uint32_t firstVertex,
3529 uint32_t vertexCount,
3530 uint32_t firstInstance,
3531 uint32_t instanceCount)
3532 {
3533 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
3534
3535 anv_cmd_buffer_flush_state(cmd_buffer);
3536
3537 anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
3538 .VertexAccessType = SEQUENTIAL,
3539 .VertexCountPerInstance = vertexCount,
3540 .StartVertexLocation = firstVertex,
3541 .InstanceCount = instanceCount,
3542 .StartInstanceLocation = firstInstance,
3543 .BaseVertexLocation = 0);
3544 }
3545
3546 void anv_CmdDrawIndexed(
3547 VkCmdBuffer cmdBuffer,
3548 uint32_t firstIndex,
3549 uint32_t indexCount,
3550 int32_t vertexOffset,
3551 uint32_t firstInstance,
3552 uint32_t instanceCount)
3553 {
3554 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
3555
3556 anv_cmd_buffer_flush_state(cmd_buffer);
3557
3558 anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
3559 .VertexAccessType = RANDOM,
3560 .VertexCountPerInstance = indexCount,
3561 .StartVertexLocation = firstIndex,
3562 .InstanceCount = instanceCount,
3563 .StartInstanceLocation = firstInstance,
3564 .BaseVertexLocation = vertexOffset);
3565 }
3566
3567 static void
3568 anv_batch_lrm(struct anv_batch *batch,
3569 uint32_t reg, struct anv_bo *bo, uint32_t offset)
3570 {
3571 anv_batch_emit(batch, GEN8_MI_LOAD_REGISTER_MEM,
3572 .RegisterAddress = reg,
3573 .MemoryAddress = { bo, offset });
3574 }
3575
3576 static void
3577 anv_batch_lri(struct anv_batch *batch, uint32_t reg, uint32_t imm)
3578 {
3579 anv_batch_emit(batch, GEN8_MI_LOAD_REGISTER_IMM,
3580 .RegisterOffset = reg,
3581 .DataDWord = imm);
3582 }
3583
3584 /* Auto-Draw / Indirect Registers */
3585 #define GEN7_3DPRIM_END_OFFSET 0x2420
3586 #define GEN7_3DPRIM_START_VERTEX 0x2430
3587 #define GEN7_3DPRIM_VERTEX_COUNT 0x2434
3588 #define GEN7_3DPRIM_INSTANCE_COUNT 0x2438
3589 #define GEN7_3DPRIM_START_INSTANCE 0x243C
3590 #define GEN7_3DPRIM_BASE_VERTEX 0x2440
3591
3592 void anv_CmdDrawIndirect(
3593 VkCmdBuffer cmdBuffer,
3594 VkBuffer _buffer,
3595 VkDeviceSize offset,
3596 uint32_t count,
3597 uint32_t stride)
3598 {
3599 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
3600 ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
3601 struct anv_bo *bo = buffer->bo;
3602 uint32_t bo_offset = buffer->offset + offset;
3603
3604 anv_cmd_buffer_flush_state(cmd_buffer);
3605
3606 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
3607 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
3608 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);
3609 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_INSTANCE, bo, bo_offset + 12);
3610 anv_batch_lri(&cmd_buffer->batch, GEN7_3DPRIM_BASE_VERTEX, 0);
3611
3612 anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
3613 .IndirectParameterEnable = true,
3614 .VertexAccessType = SEQUENTIAL);
3615 }
3616
3617 void anv_CmdDrawIndexedIndirect(
3618 VkCmdBuffer cmdBuffer,
3619 VkBuffer _buffer,
3620 VkDeviceSize offset,
3621 uint32_t count,
3622 uint32_t stride)
3623 {
3624 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
3625 ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
3626 struct anv_bo *bo = buffer->bo;
3627 uint32_t bo_offset = buffer->offset + offset;
3628
3629 anv_cmd_buffer_flush_state(cmd_buffer);
3630
3631 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
3632 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
3633 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);
3634 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_BASE_VERTEX, bo, bo_offset + 12);
3635 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_INSTANCE, bo, bo_offset + 16);
3636
3637 anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
3638 .IndirectParameterEnable = true,
3639 .VertexAccessType = RANDOM);
3640 }
3641
3642 void anv_CmdDispatch(
3643 VkCmdBuffer cmdBuffer,
3644 uint32_t x,
3645 uint32_t y,
3646 uint32_t z)
3647 {
3648 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
3649 struct anv_pipeline *pipeline = cmd_buffer->compute_pipeline;
3650 struct brw_cs_prog_data *prog_data = &pipeline->cs_prog_data;
3651
3652 anv_cmd_buffer_flush_compute_state(cmd_buffer);
3653
3654 anv_batch_emit(&cmd_buffer->batch, GEN8_GPGPU_WALKER,
3655 .SIMDSize = prog_data->simd_size / 16,
3656 .ThreadDepthCounterMaximum = 0,
3657 .ThreadHeightCounterMaximum = 0,
3658 .ThreadWidthCounterMaximum = pipeline->cs_thread_width_max,
3659 .ThreadGroupIDXDimension = x,
3660 .ThreadGroupIDYDimension = y,
3661 .ThreadGroupIDZDimension = z,
3662 .RightExecutionMask = pipeline->cs_right_mask,
3663 .BottomExecutionMask = 0xffffffff);
3664
3665 anv_batch_emit(&cmd_buffer->batch, GEN8_MEDIA_STATE_FLUSH);
3666 }
3667
3668 #define GPGPU_DISPATCHDIMX 0x2500
3669 #define GPGPU_DISPATCHDIMY 0x2504
3670 #define GPGPU_DISPATCHDIMZ 0x2508
3671
3672 void anv_CmdDispatchIndirect(
3673 VkCmdBuffer cmdBuffer,
3674 VkBuffer _buffer,
3675 VkDeviceSize offset)
3676 {
3677 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
3678 ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
3679 struct anv_pipeline *pipeline = cmd_buffer->compute_pipeline;
3680 struct brw_cs_prog_data *prog_data = &pipeline->cs_prog_data;
3681 struct anv_bo *bo = buffer->bo;
3682 uint32_t bo_offset = buffer->offset + offset;
3683
3684 anv_cmd_buffer_flush_compute_state(cmd_buffer);
3685
3686 anv_batch_lrm(&cmd_buffer->batch, GPGPU_DISPATCHDIMX, bo, bo_offset);
3687 anv_batch_lrm(&cmd_buffer->batch, GPGPU_DISPATCHDIMY, bo, bo_offset + 4);
3688 anv_batch_lrm(&cmd_buffer->batch, GPGPU_DISPATCHDIMZ, bo, bo_offset + 8);
3689
3690 anv_batch_emit(&cmd_buffer->batch, GEN8_GPGPU_WALKER,
3691 .IndirectParameterEnable = true,
3692 .SIMDSize = prog_data->simd_size / 16,
3693 .ThreadDepthCounterMaximum = 0,
3694 .ThreadHeightCounterMaximum = 0,
3695 .ThreadWidthCounterMaximum = pipeline->cs_thread_width_max,
3696 .RightExecutionMask = pipeline->cs_right_mask,
3697 .BottomExecutionMask = 0xffffffff);
3698
3699 anv_batch_emit(&cmd_buffer->batch, GEN8_MEDIA_STATE_FLUSH);
3700 }
3701
3702 void anv_CmdSetEvent(
3703 VkCmdBuffer cmdBuffer,
3704 VkEvent event,
3705 VkPipeEvent pipeEvent)
3706 {
3707 stub();
3708 }
3709
3710 void anv_CmdResetEvent(
3711 VkCmdBuffer cmdBuffer,
3712 VkEvent event,
3713 VkPipeEvent pipeEvent)
3714 {
3715 stub();
3716 }
3717
3718 void anv_CmdWaitEvents(
3719 VkCmdBuffer cmdBuffer,
3720 VkWaitEvent waitEvent,
3721 uint32_t eventCount,
3722 const VkEvent* pEvents,
3723 VkPipeEventFlags pipeEventMask,
3724 uint32_t memBarrierCount,
3725 const void* const* ppMemBarriers)
3726 {
3727 stub();
3728 }
3729
3730 void anv_CmdPipelineBarrier(
3731 VkCmdBuffer cmdBuffer,
3732 VkWaitEvent waitEvent,
3733 VkPipeEventFlags pipeEventMask,
3734 uint32_t memBarrierCount,
3735 const void* const* ppMemBarriers)
3736 {
3737 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
3738 uint32_t b, *dw;
3739
3740 struct GEN8_PIPE_CONTROL cmd = {
3741 GEN8_PIPE_CONTROL_header,
3742 .PostSyncOperation = NoWrite,
3743 };
3744
3745 /* XXX: I think waitEvent is a no-op on our HW. We should verify that. */
3746
3747 if (anv_clear_mask(&pipeEventMask, VK_PIPE_EVENT_TOP_OF_PIPE_BIT)) {
3748 /* This is just what PIPE_CONTROL does */
3749 }
3750
3751 if (anv_clear_mask(&pipeEventMask,
3752 VK_PIPE_EVENT_VERTEX_PROCESSING_COMPLETE_BIT |
3753 VK_PIPE_EVENT_LOCAL_FRAGMENT_PROCESSING_COMPLETE_BIT |
3754 VK_PIPE_EVENT_FRAGMENT_PROCESSING_COMPLETE_BIT)) {
3755 cmd.StallAtPixelScoreboard = true;
3756 }
3757
3758
3759 if (anv_clear_mask(&pipeEventMask,
3760 VK_PIPE_EVENT_GRAPHICS_PIPELINE_COMPLETE_BIT |
3761 VK_PIPE_EVENT_COMPUTE_PIPELINE_COMPLETE_BIT |
3762 VK_PIPE_EVENT_TRANSFER_COMPLETE_BIT |
3763 VK_PIPE_EVENT_COMMANDS_COMPLETE_BIT)) {
3764 cmd.CommandStreamerStallEnable = true;
3765 }
3766
3767 if (anv_clear_mask(&pipeEventMask, VK_PIPE_EVENT_CPU_SIGNAL_BIT)) {
3768 anv_finishme("VK_PIPE_EVENT_CPU_SIGNAL_BIT");
3769 }
3770
3771 /* We checked all known VkPipeEventFlags. */
3772 anv_assert(pipeEventMask == 0);
3773
3774 /* XXX: Right now, we're really dumb and just flush whatever categories
3775 * the app asks for. One of these days we may make this a bit better
3776 * but right now that's all the hardware allows for in most areas.
3777 */
3778 VkMemoryOutputFlags out_flags = 0;
3779 VkMemoryInputFlags in_flags = 0;
3780
3781 for (uint32_t i = 0; i < memBarrierCount; i++) {
3782 const struct anv_common *common = ppMemBarriers[i];
3783 switch (common->sType) {
3784 case VK_STRUCTURE_TYPE_MEMORY_BARRIER: {
3785 const VkMemoryBarrier *barrier = (VkMemoryBarrier *)common;
3786 out_flags |= barrier->outputMask;
3787 in_flags |= barrier->inputMask;
3788 break;
3789 }
3790 case VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER: {
3791 const VkBufferMemoryBarrier *barrier = (VkBufferMemoryBarrier *)common;
3792 out_flags |= barrier->outputMask;
3793 in_flags |= barrier->inputMask;
3794 break;
3795 }
3796 case VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER: {
3797 const VkImageMemoryBarrier *barrier = (VkImageMemoryBarrier *)common;
3798 out_flags |= barrier->outputMask;
3799 in_flags |= barrier->inputMask;
3800 break;
3801 }
3802 default:
3803 unreachable("Invalid memory barrier type");
3804 }
3805 }
3806
3807 for_each_bit(b, out_flags) {
3808 switch ((VkMemoryOutputFlags)(1 << b)) {
3809 case VK_MEMORY_OUTPUT_HOST_WRITE_BIT:
3810 break; /* FIXME: Little-core systems */
3811 case VK_MEMORY_OUTPUT_SHADER_WRITE_BIT:
3812 cmd.DCFlushEnable = true;
3813 break;
3814 case VK_MEMORY_OUTPUT_COLOR_ATTACHMENT_BIT:
3815 cmd.RenderTargetCacheFlushEnable = true;
3816 break;
3817 case VK_MEMORY_OUTPUT_DEPTH_STENCIL_ATTACHMENT_BIT:
3818 cmd.DepthCacheFlushEnable = true;
3819 break;
3820 case VK_MEMORY_OUTPUT_TRANSFER_BIT:
3821 cmd.RenderTargetCacheFlushEnable = true;
3822 cmd.DepthCacheFlushEnable = true;
3823 break;
3824 default:
3825 unreachable("Invalid memory output flag");
3826 }
3827 }
3828
3829 for_each_bit(b, out_flags) {
3830 switch ((VkMemoryInputFlags)(1 << b)) {
3831 case VK_MEMORY_INPUT_HOST_READ_BIT:
3832 break; /* FIXME: Little-core systems */
3833 case VK_MEMORY_INPUT_INDIRECT_COMMAND_BIT:
3834 case VK_MEMORY_INPUT_INDEX_FETCH_BIT:
3835 case VK_MEMORY_INPUT_VERTEX_ATTRIBUTE_FETCH_BIT:
3836 cmd.VFCacheInvalidationEnable = true;
3837 break;
3838 case VK_MEMORY_INPUT_UNIFORM_READ_BIT:
3839 cmd.ConstantCacheInvalidationEnable = true;
3840 /* fallthrough */
3841 case VK_MEMORY_INPUT_SHADER_READ_BIT:
3842 cmd.DCFlushEnable = true;
3843 cmd.TextureCacheInvalidationEnable = true;
3844 break;
3845 case VK_MEMORY_INPUT_COLOR_ATTACHMENT_BIT:
3846 case VK_MEMORY_INPUT_DEPTH_STENCIL_ATTACHMENT_BIT:
3847 break; /* XXX: Hunh? */
3848 case VK_MEMORY_INPUT_TRANSFER_BIT:
3849 cmd.TextureCacheInvalidationEnable = true;
3850 break;
3851 }
3852 }
3853
3854 dw = anv_batch_emit_dwords(&cmd_buffer->batch, GEN8_PIPE_CONTROL_length);
3855 GEN8_PIPE_CONTROL_pack(&cmd_buffer->batch, dw, &cmd);
3856 }
3857
3858 static void
3859 anv_framebuffer_destroy(struct anv_device *device,
3860 struct anv_object *object,
3861 VkObjectType obj_type)
3862 {
3863 struct anv_framebuffer *fb = (struct anv_framebuffer *)object;
3864
3865 assert(obj_type == VK_OBJECT_TYPE_FRAMEBUFFER);
3866
3867 anv_DestroyFramebuffer(anv_device_to_handle(device),
3868 anv_framebuffer_to_handle(fb));
3869 }
3870
3871 VkResult anv_CreateFramebuffer(
3872 VkDevice _device,
3873 const VkFramebufferCreateInfo* pCreateInfo,
3874 VkFramebuffer* pFramebuffer)
3875 {
3876 ANV_FROM_HANDLE(anv_device, device, _device);
3877 struct anv_framebuffer *framebuffer;
3878
3879 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO);
3880
3881 size_t size = sizeof(*framebuffer) +
3882 sizeof(struct anv_attachment_view *) * pCreateInfo->attachmentCount;
3883 framebuffer = anv_device_alloc(device, size, 8,
3884 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
3885 if (framebuffer == NULL)
3886 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
3887
3888 framebuffer->base.destructor = anv_framebuffer_destroy;
3889
3890 framebuffer->attachment_count = pCreateInfo->attachmentCount;
3891 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
3892 ANV_FROM_HANDLE(anv_attachment_view, view,
3893 pCreateInfo->pAttachments[i].view);
3894
3895 framebuffer->attachments[i] = view;
3896 }
3897
3898 framebuffer->width = pCreateInfo->width;
3899 framebuffer->height = pCreateInfo->height;
3900 framebuffer->layers = pCreateInfo->layers;
3901
3902 anv_CreateDynamicViewportState(anv_device_to_handle(device),
3903 &(VkDynamicViewportStateCreateInfo) {
3904 .sType = VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO,
3905 .viewportAndScissorCount = 1,
3906 .pViewports = (VkViewport[]) {
3907 {
3908 .originX = 0,
3909 .originY = 0,
3910 .width = pCreateInfo->width,
3911 .height = pCreateInfo->height,
3912 .minDepth = 0,
3913 .maxDepth = 1
3914 },
3915 },
3916 .pScissors = (VkRect2D[]) {
3917 { { 0, 0 },
3918 { pCreateInfo->width, pCreateInfo->height } },
3919 }
3920 },
3921 &framebuffer->vp_state);
3922
3923 *pFramebuffer = anv_framebuffer_to_handle(framebuffer);
3924
3925 return VK_SUCCESS;
3926 }
3927
3928 VkResult anv_DestroyFramebuffer(
3929 VkDevice _device,
3930 VkFramebuffer _fb)
3931 {
3932 ANV_FROM_HANDLE(anv_device, device, _device);
3933 ANV_FROM_HANDLE(anv_framebuffer, fb, _fb);
3934
3935 anv_DestroyDynamicViewportState(anv_device_to_handle(device),
3936 fb->vp_state);
3937 anv_device_free(device, fb);
3938
3939 return VK_SUCCESS;
3940 }
3941
3942 VkResult anv_CreateRenderPass(
3943 VkDevice _device,
3944 const VkRenderPassCreateInfo* pCreateInfo,
3945 VkRenderPass* pRenderPass)
3946 {
3947 ANV_FROM_HANDLE(anv_device, device, _device);
3948 struct anv_render_pass *pass;
3949 size_t size;
3950
3951 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO);
3952
3953 size = sizeof(*pass) +
3954 pCreateInfo->subpassCount * sizeof(struct anv_subpass);
3955 pass = anv_device_alloc(device, size, 8,
3956 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
3957 if (pass == NULL)
3958 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
3959
3960 pass->attachment_count = pCreateInfo->attachmentCount;
3961 size = pCreateInfo->attachmentCount * sizeof(*pass->attachments);
3962 pass->attachments = anv_device_alloc(device, size, 8,
3963 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
3964 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
3965 pass->attachments[i].format = pCreateInfo->pAttachments[i].format;
3966 pass->attachments[i].samples = pCreateInfo->pAttachments[i].samples;
3967 pass->attachments[i].load_op = pCreateInfo->pAttachments[i].loadOp;
3968 pass->attachments[i].stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;
3969 // pass->attachments[i].store_op = pCreateInfo->pAttachments[i].storeOp;
3970 // pass->attachments[i].stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
3971 }
3972
3973 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
3974 const VkSubpassDescription *desc = &pCreateInfo->pSubpasses[i];
3975 struct anv_subpass *subpass = &pass->subpasses[i];
3976
3977 subpass->input_count = desc->inputCount;
3978 subpass->input_attachments =
3979 anv_device_alloc(device, desc->inputCount * sizeof(uint32_t),
3980 8, VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
3981 for (uint32_t j = 0; j < desc->inputCount; j++)
3982 subpass->input_attachments[j] = desc->inputAttachments[j].attachment;
3983
3984 subpass->color_count = desc->colorCount;
3985 subpass->color_attachments =
3986 anv_device_alloc(device, desc->colorCount * sizeof(uint32_t),
3987 8, VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
3988 for (uint32_t j = 0; j < desc->colorCount; j++)
3989 subpass->color_attachments[j] = desc->colorAttachments[j].attachment;
3990
3991 if (desc->resolveAttachments) {
3992 subpass->resolve_attachments =
3993 anv_device_alloc(device, desc->colorCount * sizeof(uint32_t),
3994 8, VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
3995 for (uint32_t j = 0; j < desc->colorCount; j++)
3996 subpass->resolve_attachments[j] = desc->resolveAttachments[j].attachment;
3997 }
3998
3999 subpass->depth_stencil_attachment = desc->depthStencilAttachment.attachment;
4000 }
4001
4002 *pRenderPass = anv_render_pass_to_handle(pass);
4003
4004 return VK_SUCCESS;
4005 }
4006
4007 VkResult anv_DestroyRenderPass(
4008 VkDevice _device,
4009 VkRenderPass _pass)
4010 {
4011 ANV_FROM_HANDLE(anv_device, device, _device);
4012 ANV_FROM_HANDLE(anv_render_pass, pass, _pass);
4013
4014 anv_device_free(device, pass->attachments);
4015
4016 for (uint32_t i = 0; i < pass->attachment_count; i++) {
4017 anv_device_free(device, pass->subpasses[i].input_attachments);
4018 anv_device_free(device, pass->subpasses[i].color_attachments);
4019 anv_device_free(device, pass->subpasses[i].resolve_attachments);
4020 }
4021
4022 anv_device_free(device, pass);
4023
4024 return VK_SUCCESS;
4025 }
4026
4027 VkResult anv_GetRenderAreaGranularity(
4028 VkDevice device,
4029 VkRenderPass renderPass,
4030 VkExtent2D* pGranularity)
4031 {
4032 *pGranularity = (VkExtent2D) { 1, 1 };
4033
4034 return VK_SUCCESS;
4035 }
4036
4037 static void
4038 anv_cmd_buffer_emit_depth_stencil(struct anv_cmd_buffer *cmd_buffer)
4039 {
4040 struct anv_subpass *subpass = cmd_buffer->subpass;
4041 struct anv_framebuffer *fb = cmd_buffer->framebuffer;
4042 const struct anv_depth_stencil_view *view;
4043
4044 static const struct anv_depth_stencil_view null_view =
4045 { .depth_format = D16_UNORM, .depth_stride = 0, .stencil_stride = 0 };
4046
4047 if (subpass->depth_stencil_attachment != VK_ATTACHMENT_UNUSED) {
4048 const struct anv_attachment_view *aview =
4049 fb->attachments[subpass->depth_stencil_attachment];
4050 assert(aview->attachment_type == ANV_ATTACHMENT_VIEW_TYPE_DEPTH_STENCIL);
4051 view = (const struct anv_depth_stencil_view *)aview;
4052 } else {
4053 view = &null_view;
4054 }
4055
4056 /* FIXME: Implement the PMA stall W/A */
4057 /* FIXME: Width and Height are wrong */
4058
4059 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DEPTH_BUFFER,
4060 .SurfaceType = SURFTYPE_2D,
4061 .DepthWriteEnable = view->depth_stride > 0,
4062 .StencilWriteEnable = view->stencil_stride > 0,
4063 .HierarchicalDepthBufferEnable = false,
4064 .SurfaceFormat = view->depth_format,
4065 .SurfacePitch = view->depth_stride > 0 ? view->depth_stride - 1 : 0,
4066 .SurfaceBaseAddress = { view->bo, view->depth_offset },
4067 .Height = cmd_buffer->framebuffer->height - 1,
4068 .Width = cmd_buffer->framebuffer->width - 1,
4069 .LOD = 0,
4070 .Depth = 1 - 1,
4071 .MinimumArrayElement = 0,
4072 .DepthBufferObjectControlState = GEN8_MOCS,
4073 .RenderTargetViewExtent = 1 - 1,
4074 .SurfaceQPitch = view->depth_qpitch >> 2);
4075
4076 /* Disable hierarchial depth buffers. */
4077 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_HIER_DEPTH_BUFFER);
4078
4079 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_STENCIL_BUFFER,
4080 .StencilBufferEnable = view->stencil_stride > 0,
4081 .StencilBufferObjectControlState = GEN8_MOCS,
4082 .SurfacePitch = view->stencil_stride > 0 ? view->stencil_stride - 1 : 0,
4083 .SurfaceBaseAddress = { view->bo, view->stencil_offset },
4084 .SurfaceQPitch = view->stencil_qpitch >> 2);
4085
4086 /* Clear the clear params. */
4087 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_CLEAR_PARAMS);
4088 }
4089
4090 void anv_CmdPushConstants(
4091 VkCmdBuffer cmdBuffer,
4092 VkPipelineLayout layout,
4093 VkShaderStageFlags stageFlags,
4094 uint32_t start,
4095 uint32_t length,
4096 const void* values)
4097 {
4098 stub();
4099 }
4100
4101 void
4102 anv_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
4103 struct anv_subpass *subpass)
4104 {
4105 cmd_buffer->subpass = subpass;
4106
4107 cmd_buffer->descriptors_dirty |= VK_SHADER_STAGE_FRAGMENT_BIT;
4108
4109 anv_cmd_buffer_emit_depth_stencil(cmd_buffer);
4110 }
4111
4112 void anv_CmdBeginRenderPass(
4113 VkCmdBuffer cmdBuffer,
4114 const VkRenderPassBeginInfo* pRenderPassBegin,
4115 VkRenderPassContents contents)
4116 {
4117 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
4118 ANV_FROM_HANDLE(anv_render_pass, pass, pRenderPassBegin->renderPass);
4119 ANV_FROM_HANDLE(anv_framebuffer, framebuffer, pRenderPassBegin->framebuffer);
4120
4121 assert(contents == VK_RENDER_PASS_CONTENTS_INLINE);
4122
4123 cmd_buffer->framebuffer = framebuffer;
4124 cmd_buffer->pass = pass;
4125
4126 const VkRect2D *render_area = &pRenderPassBegin->renderArea;
4127
4128 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DRAWING_RECTANGLE,
4129 .ClippedDrawingRectangleYMin = render_area->offset.y,
4130 .ClippedDrawingRectangleXMin = render_area->offset.x,
4131 .ClippedDrawingRectangleYMax =
4132 render_area->offset.y + render_area->extent.height - 1,
4133 .ClippedDrawingRectangleXMax =
4134 render_area->offset.x + render_area->extent.width - 1,
4135 .DrawingRectangleOriginY = 0,
4136 .DrawingRectangleOriginX = 0);
4137
4138 anv_cmd_buffer_clear_attachments(cmd_buffer, pass,
4139 pRenderPassBegin->pAttachmentClearValues);
4140
4141 anv_cmd_buffer_begin_subpass(cmd_buffer, pass->subpasses);
4142 }
4143
4144 void anv_CmdNextSubpass(
4145 VkCmdBuffer cmdBuffer,
4146 VkRenderPassContents contents)
4147 {
4148 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
4149
4150 assert(contents == VK_RENDER_PASS_CONTENTS_INLINE);
4151
4152 cmd_buffer->subpass++;
4153 anv_cmd_buffer_begin_subpass(cmd_buffer, cmd_buffer->subpass + 1);
4154 }
4155
4156 void anv_CmdEndRenderPass(
4157 VkCmdBuffer cmdBuffer)
4158 {
4159 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
4160
4161 /* Emit a flushing pipe control at the end of a pass. This is kind of a
4162 * hack but it ensures that render targets always actually get written.
4163 * Eventually, we should do flushing based on image format transitions
4164 * or something of that nature.
4165 */
4166 anv_batch_emit(&cmd_buffer->batch, GEN8_PIPE_CONTROL,
4167 .PostSyncOperation = NoWrite,
4168 .RenderTargetCacheFlushEnable = true,
4169 .InstructionCacheInvalidateEnable = true,
4170 .DepthCacheFlushEnable = true,
4171 .VFCacheInvalidationEnable = true,
4172 .TextureCacheInvalidationEnable = true,
4173 .CommandStreamerStallEnable = true);
4174 }
4175
4176 void anv_CmdExecuteCommands(
4177 VkCmdBuffer cmdBuffer,
4178 uint32_t cmdBuffersCount,
4179 const VkCmdBuffer* pCmdBuffers)
4180 {
4181 stub();
4182 }
4183
4184 void vkCmdDbgMarkerBegin(
4185 VkCmdBuffer cmdBuffer,
4186 const char* pMarker)
4187 __attribute__ ((visibility ("default")));
4188
4189 void vkCmdDbgMarkerEnd(
4190 VkCmdBuffer cmdBuffer)
4191 __attribute__ ((visibility ("default")));
4192
4193 VkResult vkDbgSetObjectTag(
4194 VkDevice device,
4195 VkObject object,
4196 size_t tagSize,
4197 const void* pTag)
4198 __attribute__ ((visibility ("default")));
4199
4200
4201 void vkCmdDbgMarkerBegin(
4202 VkCmdBuffer cmdBuffer,
4203 const char* pMarker)
4204 {
4205 }
4206
4207 void vkCmdDbgMarkerEnd(
4208 VkCmdBuffer cmdBuffer)
4209 {
4210 }
4211
4212 VkResult vkDbgSetObjectTag(
4213 VkDevice device,
4214 VkObject object,
4215 size_t tagSize,
4216 const void* pTag)
4217 {
4218 return VK_SUCCESS;
4219 }