blob: cc00057b8267e93da16234a7f0958d9437bbda92 [file] [log] [blame]
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001/*
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
32static int
33anv_env_get_int(const char *name)
34{
35 const char *val = getenv(name);
36
37 if (!val)
38 return 0;
39
40 return strtol(val, NULL, 0);
41}
42
43static VkResult
44fill_physical_device(struct anv_physical_device *device,
45 struct anv_instance *instance,
46 const char *path)
47{
48 int fd;
49
50 fd = open("/dev/dri/renderD128", O_RDWR | O_CLOEXEC);
51 if (fd < 0)
52 return vk_error(VK_ERROR_UNAVAILABLE);
53
54 device->instance = instance;
55 device->path = path;
56
57 device->chipset_id = anv_env_get_int("INTEL_DEVID_OVERRIDE");
58 device->no_hw = false;
59 if (device->chipset_id) {
60 /* INTEL_DEVID_OVERRIDE implies INTEL_NO_HW. */
61 device->no_hw = true;
62 } else {
63 device->chipset_id = anv_gem_get_param(fd, I915_PARAM_CHIPSET_ID);
64 }
65 if (!device->chipset_id)
66 goto fail;
67
68 device->name = brw_get_device_name(device->chipset_id);
69 device->info = brw_get_device_info(device->chipset_id, -1);
70 if (!device->info)
71 goto fail;
72
73 if (!anv_gem_get_param(fd, I915_PARAM_HAS_WAIT_TIMEOUT))
74 goto fail;
75
76 if (!anv_gem_get_param(fd, I915_PARAM_HAS_EXECBUF2))
77 goto fail;
78
79 if (!anv_gem_get_param(fd, I915_PARAM_HAS_LLC))
80 goto fail;
81
82 if (!anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_CONSTANTS))
83 goto fail;
84
85 close(fd);
86
87 return VK_SUCCESS;
88
89 fail:
90 close(fd);
91
92 return vk_error(VK_ERROR_UNAVAILABLE);
93}
94
95static void *default_alloc(
96 void* pUserData,
97 size_t size,
98 size_t alignment,
99 VkSystemAllocType allocType)
100{
101 return malloc(size);
102}
103
104static void default_free(
105 void* pUserData,
106 void* pMem)
107{
108 free(pMem);
109}
110
111static const VkAllocCallbacks default_alloc_callbacks = {
112 .pUserData = NULL,
113 .pfnAlloc = default_alloc,
114 .pfnFree = default_free
115};
116
Kristian Høgsberg454345d2015-05-17 16:33:48 -0700117VkResult anv_CreateInstance(
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700118 const VkInstanceCreateInfo* pCreateInfo,
119 VkInstance* pInstance)
120{
121 struct anv_instance *instance;
122 const VkAllocCallbacks *alloc_callbacks = &default_alloc_callbacks;
123 void *user_data = NULL;
124 VkResult result;
125
126 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO);
127
128 if (pCreateInfo->pAllocCb) {
129 alloc_callbacks = pCreateInfo->pAllocCb;
130 user_data = pCreateInfo->pAllocCb->pUserData;
131 }
132 instance = alloc_callbacks->pfnAlloc(user_data, sizeof(*instance), 8,
133 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
134 if (!instance)
135 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
136
137 instance->pAllocUserData = alloc_callbacks->pUserData;
138 instance->pfnAlloc = alloc_callbacks->pfnAlloc;
139 instance->pfnFree = alloc_callbacks->pfnFree;
140 instance->apiVersion = pCreateInfo->pAppInfo->apiVersion;
141
142 instance->physicalDeviceCount = 0;
143 result = fill_physical_device(&instance->physicalDevice,
144 instance, "/dev/dri/renderD128");
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700145
Chad Versacea61f3072015-05-20 19:51:10 -0700146 if (result != VK_SUCCESS)
147 return result;
148
149 instance->physicalDeviceCount++;
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700150 *pInstance = (VkInstance) instance;
151
152 return VK_SUCCESS;
153}
154
Kristian Høgsberg454345d2015-05-17 16:33:48 -0700155VkResult anv_DestroyInstance(
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700156 VkInstance _instance)
157{
158 struct anv_instance *instance = (struct anv_instance *) _instance;
159
160 instance->pfnFree(instance->pAllocUserData, instance);
161
162 return VK_SUCCESS;
163}
164
Kristian Høgsberg454345d2015-05-17 16:33:48 -0700165VkResult anv_EnumeratePhysicalDevices(
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700166 VkInstance _instance,
167 uint32_t* pPhysicalDeviceCount,
168 VkPhysicalDevice* pPhysicalDevices)
169{
170 struct anv_instance *instance = (struct anv_instance *) _instance;
171
172 if (*pPhysicalDeviceCount >= 1)
173 pPhysicalDevices[0] = (VkPhysicalDevice) &instance->physicalDevice;
174 *pPhysicalDeviceCount = instance->physicalDeviceCount;
175
176 return VK_SUCCESS;
177}
178
Kristian Høgsberg454345d2015-05-17 16:33:48 -0700179VkResult anv_GetPhysicalDeviceInfo(
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700180 VkPhysicalDevice physicalDevice,
181 VkPhysicalDeviceInfoType infoType,
182 size_t* pDataSize,
183 void* pData)
184{
185 struct anv_physical_device *device = (struct anv_physical_device *) physicalDevice;
186 VkPhysicalDeviceProperties *properties;
187 VkPhysicalDevicePerformance *performance;
188 VkPhysicalDeviceQueueProperties *queue_properties;
189 VkPhysicalDeviceMemoryProperties *memory_properties;
Kristian Høgsberga29df712015-05-15 22:04:52 -0700190 VkDisplayPropertiesWSI *display_properties;
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700191 uint64_t ns_per_tick = 80;
192
Kristian Høgsberga29df712015-05-15 22:04:52 -0700193 switch ((uint32_t) infoType) {
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700194 case VK_PHYSICAL_DEVICE_INFO_TYPE_PROPERTIES:
195 properties = pData;
Kristian Høgsberg783e6212015-05-17 19:22:52 -0700196
197 *pDataSize = sizeof(*properties);
198 if (pData == NULL)
199 return VK_SUCCESS;
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700200
201 properties->apiVersion = 1;
202 properties->driverVersion = 1;
203 properties->vendorId = 0x8086;
204 properties->deviceId = device->chipset_id;
205 properties->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
206 strcpy(properties->deviceName, device->name);
207 properties->maxInlineMemoryUpdateSize = 0;
Kristian Høgsberg5286ef72015-05-18 10:17:53 -0700208 properties->maxBoundDescriptorSets = MAX_SETS;
209 properties->maxThreadGroupSize = 512;
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700210 properties->timestampFrequency = 1000 * 1000 * 1000 / ns_per_tick;
Kristian Høgsberg5286ef72015-05-18 10:17:53 -0700211 properties->multiColorAttachmentClears = true;
212 properties->maxDescriptorSets = 8;
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700213 properties->maxViewports = 16;
214 properties->maxColorAttachments = 8;
215 return VK_SUCCESS;
216
217 case VK_PHYSICAL_DEVICE_INFO_TYPE_PERFORMANCE:
218 performance = pData;
Kristian Høgsberg783e6212015-05-17 19:22:52 -0700219
220 *pDataSize = sizeof(*performance);
221 if (pData == NULL)
222 return VK_SUCCESS;
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700223
224 performance->maxDeviceClock = 1.0;
225 performance->aluPerClock = 1.0;
226 performance->texPerClock = 1.0;
227 performance->primsPerClock = 1.0;
228 performance->pixelsPerClock = 1.0;
229 return VK_SUCCESS;
230
231 case VK_PHYSICAL_DEVICE_INFO_TYPE_QUEUE_PROPERTIES:
232 queue_properties = pData;
Kristian Høgsberg783e6212015-05-17 19:22:52 -0700233
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700234 *pDataSize = sizeof(*queue_properties);
Kristian Høgsberg783e6212015-05-17 19:22:52 -0700235 if (pData == NULL)
236 return VK_SUCCESS;
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700237
238 queue_properties->queueFlags = 0;
239 queue_properties->queueCount = 1;
Kristian Høgsberg5286ef72015-05-18 10:17:53 -0700240 queue_properties->supportsTimestamps = true;
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700241 return VK_SUCCESS;
242
243 case VK_PHYSICAL_DEVICE_INFO_TYPE_MEMORY_PROPERTIES:
244 memory_properties = pData;
Kristian Høgsberg783e6212015-05-17 19:22:52 -0700245
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700246 *pDataSize = sizeof(*memory_properties);
Kristian Høgsberg783e6212015-05-17 19:22:52 -0700247 if (pData == NULL)
248 return VK_SUCCESS;
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700249
250 memory_properties->supportsMigration = false;
251 memory_properties->supportsPinning = false;
252 return VK_SUCCESS;
253
Kristian Høgsberga29df712015-05-15 22:04:52 -0700254 case VK_PHYSICAL_DEVICE_INFO_TYPE_DISPLAY_PROPERTIES_WSI:
255 anv_finishme("VK_PHYSICAL_DEVICE_INFO_TYPE_DISPLAY_PROPERTIES_WSI");
256
257 *pDataSize = sizeof(*display_properties);
258 if (pData == NULL)
259 return VK_SUCCESS;
260
261 display_properties = pData;
262 display_properties->display = 0;
263 display_properties->physicalResolution = (VkExtent2D) { 0, 0 };
264 return VK_SUCCESS;
265
266 case VK_PHYSICAL_DEVICE_INFO_TYPE_QUEUE_PRESENT_PROPERTIES_WSI:
267 anv_finishme("VK_PHYSICAL_DEVICE_INFO_TYPE_QUEUE_PRESENT_PROPERTIES_WSI");
268 return VK_SUCCESS;
269
270
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700271 default:
272 return VK_UNSUPPORTED;
273 }
274
275}
276
277void * vkGetProcAddr(
278 VkPhysicalDevice physicalDevice,
279 const char* pName)
280{
Kristian Høgsberg454345d2015-05-17 16:33:48 -0700281 return anv_lookup_entrypoint(pName);
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700282}
283
284static void
285parse_debug_flags(struct anv_device *device)
286{
287 const char *debug, *p, *end;
288
289 debug = getenv("INTEL_DEBUG");
290 device->dump_aub = false;
291 if (debug) {
292 for (p = debug; *p; p = end + 1) {
293 end = strchrnul(p, ',');
294 if (end - p == 3 && memcmp(p, "aub", 3) == 0)
295 device->dump_aub = true;
296 if (end - p == 5 && memcmp(p, "no_hw", 5) == 0)
297 device->no_hw = true;
298 if (*end == '\0')
299 break;
300 }
301 }
302}
303
Jason Ekstrand66b00d52015-06-09 12:28:58 -0700304static VkResult
305anv_queue_init(struct anv_device *device, struct anv_queue *queue)
306{
307 queue->device = device;
308 queue->pool = &device->surface_state_pool;
309
310 queue->completed_serial = anv_state_pool_alloc(queue->pool, 4, 4);
311 if (queue->completed_serial.map == NULL)
312 return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY);
313
314 *(uint32_t *)queue->completed_serial.map = 0;
315 queue->next_serial = 1;
316
317 return VK_SUCCESS;
318}
319
320static void
321anv_queue_finish(struct anv_queue *queue)
322{
323#ifdef HAVE_VALGRIND
324 /* This gets torn down with the device so we only need to do this if
325 * valgrind is present.
326 */
327 anv_state_pool_free(queue->pool, queue->completed_serial);
328#endif
329}
330
Kristian Høgsberg Kristensendc56e4f2015-05-29 16:06:06 -0700331static void
332anv_device_init_border_colors(struct anv_device *device)
333{
334 float float_border_colors[][4] = {
335 [VK_BORDER_COLOR_OPAQUE_WHITE] = { 1.0, 1.0, 1.0, 1.0 },
336 [VK_BORDER_COLOR_TRANSPARENT_BLACK] = { 0.0, 0.0, 0.0, 0.0 },
337 [VK_BORDER_COLOR_OPAQUE_BLACK] = { 0.0, 0.0, 0.0, 1.0 }
338 };
339
340 uint32_t uint32_border_colors[][4] = {
341 [VK_BORDER_COLOR_OPAQUE_WHITE] = { 1, 1, 1, 1 },
342 [VK_BORDER_COLOR_TRANSPARENT_BLACK] = { 0, 0, 0, 0 },
343 [VK_BORDER_COLOR_OPAQUE_BLACK] = { 0, 0, 0, 1 }
344 };
345
346 device->float_border_colors =
347 anv_state_pool_alloc(&device->dynamic_state_pool,
348 sizeof(float_border_colors), 32);
349 memcpy(device->float_border_colors.map,
350 float_border_colors, sizeof(float_border_colors));
351
352 device->uint32_border_colors =
353 anv_state_pool_alloc(&device->dynamic_state_pool,
354 sizeof(uint32_border_colors), 32);
355 memcpy(device->uint32_border_colors.map,
356 uint32_border_colors, sizeof(uint32_border_colors));
357
358}
359
Jason Ekstrand730ca0e2015-05-28 10:20:18 -0700360static const uint32_t BATCH_SIZE = 8192;
Jason Ekstrand5ef81f02015-05-25 15:46:48 -0700361
Kristian Høgsberg454345d2015-05-17 16:33:48 -0700362VkResult anv_CreateDevice(
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700363 VkPhysicalDevice _physicalDevice,
364 const VkDeviceCreateInfo* pCreateInfo,
365 VkDevice* pDevice)
366{
367 struct anv_physical_device *physicalDevice =
368 (struct anv_physical_device *) _physicalDevice;
369 struct anv_instance *instance = physicalDevice->instance;
370 struct anv_device *device;
371
372 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO);
373
374 device = instance->pfnAlloc(instance->pAllocUserData,
375 sizeof(*device), 8,
376 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
377 if (!device)
378 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
379
380 device->no_hw = physicalDevice->no_hw;
381 parse_debug_flags(device);
382
383 device->instance = physicalDevice->instance;
384 device->fd = open("/dev/dri/renderD128", O_RDWR | O_CLOEXEC);
385 if (device->fd == -1)
386 goto fail_device;
387
388 device->context_id = anv_gem_create_context(device);
389 if (device->context_id == -1)
390 goto fail_fd;
391
Jason Ekstrand5ef81f02015-05-25 15:46:48 -0700392 anv_bo_pool_init(&device->batch_bo_pool, device, BATCH_SIZE);
393
Kristian Høgsberg0a775e12015-05-13 15:34:34 -0700394 anv_block_pool_init(&device->dynamic_state_block_pool, device, 2048);
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700395
Kristian Høgsberg0a775e12015-05-13 15:34:34 -0700396 anv_state_pool_init(&device->dynamic_state_pool,
397 &device->dynamic_state_block_pool);
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700398
399 anv_block_pool_init(&device->instruction_block_pool, device, 2048);
400 anv_block_pool_init(&device->surface_state_block_pool, device, 2048);
401
402 anv_state_pool_init(&device->surface_state_pool,
403 &device->surface_state_block_pool);
404
Kristian Høgsberg Kristensen9b9f9732015-06-19 15:41:30 -0700405 anv_block_pool_init(&device->scratch_block_pool, device, 0x10000);
406
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700407 device->info = *physicalDevice->info;
408
Kristian Høgsberg Kristensen9eab70e2015-06-03 23:03:29 -0700409 device->compiler = anv_compiler_create(device);
410 device->aub_writer = NULL;
411
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700412 pthread_mutex_init(&device->mutex, NULL);
413
Jason Ekstrand66b00d52015-06-09 12:28:58 -0700414 anv_queue_init(device, &device->queue);
415
Kristian Høgsbergd77c34d2015-05-11 23:25:06 -0700416 anv_device_init_meta(device);
417
Kristian Høgsberg Kristensendc56e4f2015-05-29 16:06:06 -0700418 anv_device_init_border_colors(device);
419
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700420 *pDevice = (VkDevice) device;
421
422 return VK_SUCCESS;
423
424 fail_fd:
425 close(device->fd);
426 fail_device:
427 anv_device_free(device, device);
428
429 return vk_error(VK_ERROR_UNAVAILABLE);
430}
431
Kristian Høgsberg454345d2015-05-17 16:33:48 -0700432VkResult anv_DestroyDevice(
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700433 VkDevice _device)
434{
435 struct anv_device *device = (struct anv_device *) _device;
436
437 anv_compiler_destroy(device->compiler);
438
Jason Ekstrand66b00d52015-06-09 12:28:58 -0700439 anv_queue_finish(&device->queue);
440
Jason Ekstrand3a38b0d2015-06-09 11:08:51 -0700441 anv_device_finish_meta(device);
Jason Ekstrand5ef81f02015-05-25 15:46:48 -0700442
Jason Ekstrand38f5eef2015-06-09 11:41:31 -0700443#ifdef HAVE_VALGRIND
444 /* We only need to free these to prevent valgrind errors. The backing
445 * BO will go away in a couple of lines so we don't actually leak.
446 */
447 anv_state_pool_free(&device->dynamic_state_pool,
448 device->float_border_colors);
449 anv_state_pool_free(&device->dynamic_state_pool,
450 device->uint32_border_colors);
451#endif
452
Jason Ekstrand5ef81f02015-05-25 15:46:48 -0700453 anv_bo_pool_finish(&device->batch_bo_pool);
Kristian Høgsberg0a775e12015-05-13 15:34:34 -0700454 anv_block_pool_finish(&device->dynamic_state_block_pool);
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700455 anv_block_pool_finish(&device->instruction_block_pool);
456 anv_block_pool_finish(&device->surface_state_block_pool);
457
458 close(device->fd);
459
460 if (device->aub_writer)
461 anv_aub_writer_destroy(device->aub_writer);
462
463 anv_device_free(device, device);
464
465 return VK_SUCCESS;
466}
467
Kristian Høgsberg454345d2015-05-17 16:33:48 -0700468VkResult anv_GetGlobalExtensionInfo(
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700469 VkExtensionInfoType infoType,
470 uint32_t extensionIndex,
471 size_t* pDataSize,
472 void* pData)
473{
Kristian Høgsberga29df712015-05-15 22:04:52 -0700474 static const VkExtensionProperties extensions[] = {
475 {
476 .extName = "VK_WSI_LunarG",
477 .version = 3
478 }
479 };
480 uint32_t count = ARRAY_SIZE(extensions);
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700481
482 switch (infoType) {
483 case VK_EXTENSION_INFO_TYPE_COUNT:
Kristian Høgsberga29df712015-05-15 22:04:52 -0700484 memcpy(pData, &count, sizeof(count));
485 *pDataSize = sizeof(count);
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700486 return VK_SUCCESS;
Kristian Høgsberga29df712015-05-15 22:04:52 -0700487
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700488 case VK_EXTENSION_INFO_TYPE_PROPERTIES:
Kristian Høgsberga29df712015-05-15 22:04:52 -0700489 if (extensionIndex >= count)
490 return vk_error(VK_ERROR_INVALID_EXTENSION);
491
492 memcpy(pData, &extensions[extensionIndex], sizeof(extensions[0]));
493 *pDataSize = sizeof(extensions[0]);
494 return VK_SUCCESS;
495
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700496 default:
497 return VK_UNSUPPORTED;
498 }
499}
500
Kristian Høgsberg454345d2015-05-17 16:33:48 -0700501VkResult anv_GetPhysicalDeviceExtensionInfo(
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700502 VkPhysicalDevice physicalDevice,
503 VkExtensionInfoType infoType,
504 uint32_t extensionIndex,
505 size_t* pDataSize,
506 void* pData)
507{
508 uint32_t *count;
509
510 switch (infoType) {
511 case VK_EXTENSION_INFO_TYPE_COUNT:
Kristian Høgsberg783e6212015-05-17 19:22:52 -0700512 *pDataSize = 4;
513 if (pData == NULL)
514 return VK_SUCCESS;
515
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700516 count = pData;
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700517 *count = 0;
518 return VK_SUCCESS;
519
520 case VK_EXTENSION_INFO_TYPE_PROPERTIES:
521 return vk_error(VK_ERROR_INVALID_EXTENSION);
522
523 default:
524 return VK_UNSUPPORTED;
525 }
526}
527
Kristian Høgsberg454345d2015-05-17 16:33:48 -0700528VkResult anv_EnumerateLayers(
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700529 VkPhysicalDevice physicalDevice,
530 size_t maxStringSize,
531 size_t* pLayerCount,
532 char* const* pOutLayers,
533 void* pReserved)
534{
535 *pLayerCount = 0;
536
537 return VK_SUCCESS;
538}
539
Kristian Høgsberg454345d2015-05-17 16:33:48 -0700540VkResult anv_GetDeviceQueue(
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700541 VkDevice _device,
542 uint32_t queueNodeIndex,
543 uint32_t queueIndex,
544 VkQueue* pQueue)
545{
546 struct anv_device *device = (struct anv_device *) _device;
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700547
Jason Ekstrand66b00d52015-06-09 12:28:58 -0700548 assert(queueIndex == 0);
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700549
Jason Ekstrand66b00d52015-06-09 12:28:58 -0700550 *pQueue = (VkQueue) &device->queue;
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700551
552 return VK_SUCCESS;
553}
554
Jason Ekstrand59def432015-05-27 11:41:28 -0700555VkResult
Jason Ekstrand403266b2015-05-25 17:38:15 -0700556anv_reloc_list_init(struct anv_reloc_list *list, struct anv_device *device)
557{
558 list->num_relocs = 0;
559 list->array_length = 256;
560 list->relocs =
561 anv_device_alloc(device, list->array_length * sizeof(*list->relocs), 8,
562 VK_SYSTEM_ALLOC_TYPE_INTERNAL);
563
564 if (list->relocs == NULL)
565 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
566
567 list->reloc_bos =
568 anv_device_alloc(device, list->array_length * sizeof(*list->reloc_bos), 8,
569 VK_SYSTEM_ALLOC_TYPE_INTERNAL);
570
571 if (list->relocs == NULL) {
572 anv_device_free(device, list->relocs);
573 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
574 }
575
576 return VK_SUCCESS;
577}
578
Jason Ekstrand59def432015-05-27 11:41:28 -0700579void
Jason Ekstrand403266b2015-05-25 17:38:15 -0700580anv_reloc_list_finish(struct anv_reloc_list *list, struct anv_device *device)
581{
582 anv_device_free(device, list->relocs);
583 anv_device_free(device, list->reloc_bos);
584}
585
586static VkResult
587anv_reloc_list_grow(struct anv_reloc_list *list, struct anv_device *device,
588 size_t num_additional_relocs)
589{
590 if (list->num_relocs + num_additional_relocs <= list->array_length)
591 return VK_SUCCESS;
592
593 size_t new_length = list->array_length * 2;
594 while (new_length < list->num_relocs + num_additional_relocs)
595 new_length *= 2;
596
597 struct drm_i915_gem_relocation_entry *new_relocs =
598 anv_device_alloc(device, new_length * sizeof(*list->relocs), 8,
599 VK_SYSTEM_ALLOC_TYPE_INTERNAL);
600 if (new_relocs == NULL)
601 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
602
603 struct anv_bo **new_reloc_bos =
604 anv_device_alloc(device, new_length * sizeof(*list->reloc_bos), 8,
605 VK_SYSTEM_ALLOC_TYPE_INTERNAL);
606 if (new_relocs == NULL) {
607 anv_device_free(device, new_relocs);
608 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
609 }
610
611 memcpy(new_relocs, list->relocs, list->num_relocs * sizeof(*list->relocs));
612 memcpy(new_reloc_bos, list->reloc_bos,
613 list->num_relocs * sizeof(*list->reloc_bos));
614
615 anv_device_free(device, list->relocs);
616 anv_device_free(device, list->reloc_bos);
617
618 list->relocs = new_relocs;
619 list->reloc_bos = new_reloc_bos;
620
621 return VK_SUCCESS;
622}
623
Jason Ekstrandda8f1482015-05-27 11:42:55 -0700624static VkResult
625anv_batch_bo_create(struct anv_device *device, struct anv_batch_bo **bbo_out)
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700626{
627 VkResult result;
628
Jason Ekstrandda8f1482015-05-27 11:42:55 -0700629 struct anv_batch_bo *bbo =
630 anv_device_alloc(device, sizeof(*bbo), 8, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
631 if (bbo == NULL)
632 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700633
Jason Ekstrandda8f1482015-05-27 11:42:55 -0700634 bbo->num_relocs = 0;
635 bbo->prev_batch_bo = NULL;
636
637 result = anv_bo_pool_alloc(&device->batch_bo_pool, &bbo->bo);
Jason Ekstrand403266b2015-05-25 17:38:15 -0700638 if (result != VK_SUCCESS) {
Jason Ekstrandda8f1482015-05-27 11:42:55 -0700639 anv_device_free(device, bbo);
Jason Ekstrand403266b2015-05-25 17:38:15 -0700640 return result;
641 }
642
Jason Ekstrandda8f1482015-05-27 11:42:55 -0700643 *bbo_out = bbo;
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700644
645 return VK_SUCCESS;
646}
647
Jason Ekstrandda8f1482015-05-27 11:42:55 -0700648static void
649anv_batch_bo_start(struct anv_batch_bo *bbo, struct anv_batch *batch,
650 size_t batch_padding)
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700651{
Jason Ekstrandda8f1482015-05-27 11:42:55 -0700652 batch->next = batch->start = bbo->bo.map;
653 batch->end = bbo->bo.map + bbo->bo.size - batch_padding;
654 bbo->first_reloc = batch->relocs.num_relocs;
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700655}
656
Jason Ekstrandda8f1482015-05-27 11:42:55 -0700657static void
658anv_batch_bo_finish(struct anv_batch_bo *bbo, struct anv_batch *batch)
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700659{
Jason Ekstrandda8f1482015-05-27 11:42:55 -0700660 assert(batch->start == bbo->bo.map);
661 bbo->length = batch->next - batch->start;
Jason Ekstrand9cae3d12015-06-09 21:36:12 -0700662 VG(VALGRIND_CHECK_MEM_IS_DEFINED(batch->start, bbo->length));
Jason Ekstrandda8f1482015-05-27 11:42:55 -0700663 bbo->num_relocs = batch->relocs.num_relocs - bbo->first_reloc;
664}
665
666static void
667anv_batch_bo_destroy(struct anv_batch_bo *bbo, struct anv_device *device)
668{
669 anv_bo_pool_free(&device->batch_bo_pool, &bbo->bo);
670 anv_device_free(device, bbo);
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700671}
672
673void *
674anv_batch_emit_dwords(struct anv_batch *batch, int num_dwords)
675{
Jason Ekstrandda8f1482015-05-27 11:42:55 -0700676 if (batch->next + num_dwords * 4 > batch->end)
677 batch->extend_cb(batch, batch->user_data);
678
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700679 void *p = batch->next;
680
681 batch->next += num_dwords * 4;
Jason Ekstrandda8f1482015-05-27 11:42:55 -0700682 assert(batch->next <= batch->end);
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700683
684 return p;
685}
686
687static void
Jason Ekstrand403266b2015-05-25 17:38:15 -0700688anv_reloc_list_append(struct anv_reloc_list *list, struct anv_device *device,
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700689 struct anv_reloc_list *other, uint32_t offset)
690{
Jason Ekstrand403266b2015-05-25 17:38:15 -0700691 anv_reloc_list_grow(list, device, other->num_relocs);
692 /* TODO: Handle failure */
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700693
Jason Ekstrand403266b2015-05-25 17:38:15 -0700694 memcpy(&list->relocs[list->num_relocs], &other->relocs[0],
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700695 other->num_relocs * sizeof(other->relocs[0]));
Jason Ekstrand403266b2015-05-25 17:38:15 -0700696 memcpy(&list->reloc_bos[list->num_relocs], &other->reloc_bos[0],
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700697 other->num_relocs * sizeof(other->reloc_bos[0]));
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700698
Jason Ekstrand403266b2015-05-25 17:38:15 -0700699 for (uint32_t i = 0; i < other->num_relocs; i++)
700 list->relocs[i + list->num_relocs].offset += offset;
701
702 list->num_relocs += other->num_relocs;
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700703}
704
705static uint64_t
Jason Ekstrand403266b2015-05-25 17:38:15 -0700706anv_reloc_list_add(struct anv_reloc_list *list, struct anv_device *device,
707 uint32_t offset, struct anv_bo *target_bo, uint32_t delta)
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700708{
709 struct drm_i915_gem_relocation_entry *entry;
710 int index;
711
Jason Ekstrand403266b2015-05-25 17:38:15 -0700712 anv_reloc_list_grow(list, device, 1);
713 /* TODO: Handle failure */
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700714
715 /* XXX: Can we use I915_EXEC_HANDLE_LUT? */
716 index = list->num_relocs++;
717 list->reloc_bos[index] = target_bo;
718 entry = &list->relocs[index];
719 entry->target_handle = target_bo->gem_handle;
720 entry->delta = delta;
721 entry->offset = offset;
722 entry->presumed_offset = target_bo->offset;
723 entry->read_domains = 0;
724 entry->write_domain = 0;
725
726 return target_bo->offset + delta;
727}
728
729void
730anv_batch_emit_batch(struct anv_batch *batch, struct anv_batch *other)
731{
732 uint32_t size, offset;
733
Jason Ekstrandda8f1482015-05-27 11:42:55 -0700734 size = other->next - other->start;
735 assert(size % 4 == 0);
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700736
Jason Ekstrandda8f1482015-05-27 11:42:55 -0700737 if (batch->next + size > batch->end)
738 batch->extend_cb(batch, batch->user_data);
739
740 assert(batch->next + size <= batch->end);
741
742 memcpy(batch->next, other->start, size);
743
744 offset = batch->next - batch->start;
745 anv_reloc_list_append(&batch->relocs, batch->device,
746 &other->relocs, offset);
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700747
748 batch->next += size;
749}
750
751uint64_t
752anv_batch_emit_reloc(struct anv_batch *batch,
753 void *location, struct anv_bo *bo, uint32_t delta)
754{
Jason Ekstrandda8f1482015-05-27 11:42:55 -0700755 return anv_reloc_list_add(&batch->relocs, batch->device,
756 location - batch->start, bo, delta);
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700757}
758
Kristian Høgsberg454345d2015-05-17 16:33:48 -0700759VkResult anv_QueueSubmit(
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700760 VkQueue _queue,
761 uint32_t cmdBufferCount,
762 const VkCmdBuffer* pCmdBuffers,
Kristian Høgsberg6afb2642015-05-18 08:49:15 -0700763 VkFence _fence)
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700764{
765 struct anv_queue *queue = (struct anv_queue *) _queue;
766 struct anv_device *device = queue->device;
Kristian Høgsberg6afb2642015-05-18 08:49:15 -0700767 struct anv_fence *fence = (struct anv_fence *) _fence;
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700768 int ret;
769
Kristian Høgsbergcb986ef2015-05-12 14:38:12 -0700770 for (uint32_t i = 0; i < cmdBufferCount; i++) {
771 struct anv_cmd_buffer *cmd_buffer =
772 (struct anv_cmd_buffer *) pCmdBuffers[i];
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700773
Kristian Høgsbergcb986ef2015-05-12 14:38:12 -0700774 if (device->dump_aub)
775 anv_cmd_buffer_dump(cmd_buffer);
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700776
Kristian Høgsbergcb986ef2015-05-12 14:38:12 -0700777 if (!device->no_hw) {
778 ret = anv_gem_execbuffer(device, &cmd_buffer->execbuf);
779 if (ret != 0)
Kristian Høgsberg2b7a0602015-05-12 14:38:58 -0700780 return vk_error(VK_ERROR_UNKNOWN);
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700781
Kristian Høgsberg6afb2642015-05-18 08:49:15 -0700782 if (fence) {
783 ret = anv_gem_execbuffer(device, &fence->execbuf);
784 if (ret != 0)
785 return vk_error(VK_ERROR_UNKNOWN);
786 }
787
Kristian Høgsbergcb986ef2015-05-12 14:38:12 -0700788 for (uint32_t i = 0; i < cmd_buffer->bo_count; i++)
789 cmd_buffer->exec2_bos[i]->offset = cmd_buffer->exec2_objects[i].offset;
790 } else {
791 *(uint32_t *)queue->completed_serial.map = cmd_buffer->serial;
792 }
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700793 }
794
795 return VK_SUCCESS;
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700796}
797
Kristian Høgsberg454345d2015-05-17 16:33:48 -0700798VkResult anv_QueueWaitIdle(
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700799 VkQueue _queue)
800{
801 struct anv_queue *queue = (struct anv_queue *) _queue;
802
803 return vkDeviceWaitIdle((VkDevice) queue->device);
804}
805
Kristian Høgsberg454345d2015-05-17 16:33:48 -0700806VkResult anv_DeviceWaitIdle(
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700807 VkDevice _device)
808{
809 struct anv_device *device = (struct anv_device *) _device;
810 struct anv_state state;
811 struct anv_batch batch;
812 struct drm_i915_gem_execbuffer2 execbuf;
813 struct drm_i915_gem_exec_object2 exec2_objects[1];
814 struct anv_bo *bo = NULL;
815 VkResult result;
816 int64_t timeout;
817 int ret;
818
Kristian Høgsberg0a775e12015-05-13 15:34:34 -0700819 state = anv_state_pool_alloc(&device->dynamic_state_pool, 32, 32);
820 bo = &device->dynamic_state_pool.block_pool->bo;
Jason Ekstrandda8f1482015-05-27 11:42:55 -0700821 batch.start = batch.next = state.map;
822 batch.end = state.map + 32;
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700823 anv_batch_emit(&batch, GEN8_MI_BATCH_BUFFER_END);
824 anv_batch_emit(&batch, GEN8_MI_NOOP);
825
826 exec2_objects[0].handle = bo->gem_handle;
827 exec2_objects[0].relocation_count = 0;
828 exec2_objects[0].relocs_ptr = 0;
829 exec2_objects[0].alignment = 0;
830 exec2_objects[0].offset = bo->offset;
831 exec2_objects[0].flags = 0;
832 exec2_objects[0].rsvd1 = 0;
833 exec2_objects[0].rsvd2 = 0;
834
835 execbuf.buffers_ptr = (uintptr_t) exec2_objects;
836 execbuf.buffer_count = 1;
837 execbuf.batch_start_offset = state.offset;
838 execbuf.batch_len = batch.next - state.map;
839 execbuf.cliprects_ptr = 0;
840 execbuf.num_cliprects = 0;
841 execbuf.DR1 = 0;
842 execbuf.DR4 = 0;
843
844 execbuf.flags =
845 I915_EXEC_HANDLE_LUT | I915_EXEC_NO_RELOC | I915_EXEC_RENDER;
846 execbuf.rsvd1 = device->context_id;
847 execbuf.rsvd2 = 0;
848
849 if (!device->no_hw) {
850 ret = anv_gem_execbuffer(device, &execbuf);
851 if (ret != 0) {
852 result = vk_error(VK_ERROR_UNKNOWN);
853 goto fail;
854 }
855
856 timeout = INT64_MAX;
857 ret = anv_gem_wait(device, bo->gem_handle, &timeout);
858 if (ret != 0) {
859 result = vk_error(VK_ERROR_UNKNOWN);
860 goto fail;
861 }
862 }
863
Kristian Høgsberg0a775e12015-05-13 15:34:34 -0700864 anv_state_pool_free(&device->dynamic_state_pool, state);
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700865
866 return VK_SUCCESS;
867
868 fail:
Kristian Høgsberg0a775e12015-05-13 15:34:34 -0700869 anv_state_pool_free(&device->dynamic_state_pool, state);
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700870
871 return result;
872}
873
874void *
875anv_device_alloc(struct anv_device * device,
876 size_t size,
877 size_t alignment,
878 VkSystemAllocType allocType)
879{
880 return device->instance->pfnAlloc(device->instance->pAllocUserData,
881 size,
882 alignment,
883 allocType);
884}
885
886void
887anv_device_free(struct anv_device * device,
888 void * mem)
889{
890 return device->instance->pfnFree(device->instance->pAllocUserData,
891 mem);
892}
893
894VkResult
895anv_bo_init_new(struct anv_bo *bo, struct anv_device *device, uint64_t size)
896{
897 bo->gem_handle = anv_gem_create(device, size);
898 if (!bo->gem_handle)
899 return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY);
900
901 bo->map = NULL;
902 bo->index = 0;
903 bo->offset = 0;
904 bo->size = size;
905
906 return VK_SUCCESS;
907}
908
Kristian Høgsberg454345d2015-05-17 16:33:48 -0700909VkResult anv_AllocMemory(
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700910 VkDevice _device,
911 const VkMemoryAllocInfo* pAllocInfo,
912 VkDeviceMemory* pMem)
913{
914 struct anv_device *device = (struct anv_device *) _device;
915 struct anv_device_memory *mem;
916 VkResult result;
917
918 assert(pAllocInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO);
919
920 mem = anv_device_alloc(device, sizeof(*mem), 8,
921 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
922 if (mem == NULL)
923 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
924
925 result = anv_bo_init_new(&mem->bo, device, pAllocInfo->allocationSize);
926 if (result != VK_SUCCESS)
927 goto fail;
928
929 *pMem = (VkDeviceMemory) mem;
930
931 return VK_SUCCESS;
932
933 fail:
934 anv_device_free(device, mem);
935
936 return result;
937}
938
Kristian Høgsberg454345d2015-05-17 16:33:48 -0700939VkResult anv_FreeMemory(
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700940 VkDevice _device,
941 VkDeviceMemory _mem)
942{
943 struct anv_device *device = (struct anv_device *) _device;
944 struct anv_device_memory *mem = (struct anv_device_memory *) _mem;
945
946 if (mem->bo.map)
947 anv_gem_munmap(mem->bo.map, mem->bo.size);
948
949 if (mem->bo.gem_handle != 0)
950 anv_gem_close(device, mem->bo.gem_handle);
951
952 anv_device_free(device, mem);
953
954 return VK_SUCCESS;
955}
956
Kristian Høgsberg454345d2015-05-17 16:33:48 -0700957VkResult anv_MapMemory(
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700958 VkDevice _device,
959 VkDeviceMemory _mem,
960 VkDeviceSize offset,
961 VkDeviceSize size,
962 VkMemoryMapFlags flags,
963 void** ppData)
964{
965 struct anv_device *device = (struct anv_device *) _device;
966 struct anv_device_memory *mem = (struct anv_device_memory *) _mem;
967
968 /* FIXME: Is this supposed to be thread safe? Since vkUnmapMemory() only
969 * takes a VkDeviceMemory pointer, it seems like only one map of the memory
970 * at a time is valid. We could just mmap up front and return an offset
971 * pointer here, but that may exhaust virtual memory on 32 bit
972 * userspace. */
973
974 mem->map = anv_gem_mmap(device, mem->bo.gem_handle, offset, size);
975 mem->map_size = size;
976
977 *ppData = mem->map;
978
979 return VK_SUCCESS;
980}
981
Kristian Høgsberg454345d2015-05-17 16:33:48 -0700982VkResult anv_UnmapMemory(
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700983 VkDevice _device,
984 VkDeviceMemory _mem)
985{
986 struct anv_device_memory *mem = (struct anv_device_memory *) _mem;
987
988 anv_gem_munmap(mem->map, mem->map_size);
989
990 return VK_SUCCESS;
991}
992
Kristian Høgsberg454345d2015-05-17 16:33:48 -0700993VkResult anv_FlushMappedMemory(
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700994 VkDevice device,
995 VkDeviceMemory mem,
996 VkDeviceSize offset,
997 VkDeviceSize size)
998{
999 /* clflush here for !llc platforms */
1000
1001 return VK_SUCCESS;
1002}
1003
Kristian Høgsberg454345d2015-05-17 16:33:48 -07001004VkResult anv_PinSystemMemory(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001005 VkDevice device,
1006 const void* pSysMem,
1007 size_t memSize,
1008 VkDeviceMemory* pMem)
1009{
1010 return VK_SUCCESS;
1011}
1012
Kristian Høgsberg454345d2015-05-17 16:33:48 -07001013VkResult anv_DestroyObject(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001014 VkDevice _device,
1015 VkObjectType objType,
Jason Ekstrand57153da2015-05-22 15:15:08 -07001016 VkObject _object)
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001017{
1018 struct anv_device *device = (struct anv_device *) _device;
Jason Ekstrand57153da2015-05-22 15:15:08 -07001019 struct anv_object *object = (struct anv_object *) _object;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001020
Jason Ekstrand57153da2015-05-22 15:15:08 -07001021 switch (objType) {
1022 case VK_OBJECT_TYPE_INSTANCE:
1023 return anv_DestroyInstance((VkInstance) _object);
1024
1025 case VK_OBJECT_TYPE_PHYSICAL_DEVICE:
1026 /* We don't want to actually destroy physical devices */
1027 return VK_SUCCESS;
1028
1029 case VK_OBJECT_TYPE_DEVICE:
1030 assert(_device == (VkDevice) _object);
1031 return anv_DestroyDevice((VkDevice) _object);
1032
1033 case VK_OBJECT_TYPE_QUEUE:
1034 /* TODO */
1035 return VK_SUCCESS;
1036
1037 case VK_OBJECT_TYPE_DEVICE_MEMORY:
1038 return anv_FreeMemory(_device, (VkDeviceMemory) _object);
1039
1040 case VK_OBJECT_TYPE_DESCRIPTOR_POOL:
1041 /* These are just dummys anyway, so we don't need to destroy them */
1042 return VK_SUCCESS;
1043
1044 case VK_OBJECT_TYPE_BUFFER:
Jason Ekstrand57153da2015-05-22 15:15:08 -07001045 case VK_OBJECT_TYPE_IMAGE:
Jason Ekstrand57153da2015-05-22 15:15:08 -07001046 case VK_OBJECT_TYPE_DEPTH_STENCIL_VIEW:
1047 case VK_OBJECT_TYPE_SHADER:
1048 case VK_OBJECT_TYPE_PIPELINE_LAYOUT:
1049 case VK_OBJECT_TYPE_SAMPLER:
1050 case VK_OBJECT_TYPE_DESCRIPTOR_SET:
1051 case VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT:
1052 case VK_OBJECT_TYPE_DYNAMIC_RS_STATE:
1053 case VK_OBJECT_TYPE_DYNAMIC_CB_STATE:
1054 case VK_OBJECT_TYPE_DYNAMIC_DS_STATE:
1055 case VK_OBJECT_TYPE_RENDER_PASS:
1056 /* These are trivially destroyable */
1057 anv_device_free(device, (void *) _object);
1058 return VK_SUCCESS;
1059
1060 case VK_OBJECT_TYPE_COMMAND_BUFFER:
1061 case VK_OBJECT_TYPE_PIPELINE:
1062 case VK_OBJECT_TYPE_DYNAMIC_VP_STATE:
1063 case VK_OBJECT_TYPE_FENCE:
1064 case VK_OBJECT_TYPE_QUERY_POOL:
1065 case VK_OBJECT_TYPE_FRAMEBUFFER:
Jason Ekstrand9d6f55d2015-06-09 11:08:03 -07001066 case VK_OBJECT_TYPE_BUFFER_VIEW:
1067 case VK_OBJECT_TYPE_IMAGE_VIEW:
1068 case VK_OBJECT_TYPE_COLOR_ATTACHMENT_VIEW:
Jason Ekstrand57153da2015-05-22 15:15:08 -07001069 (object->destructor)(device, object, objType);
1070 return VK_SUCCESS;
1071
1072 case VK_OBJECT_TYPE_SEMAPHORE:
1073 case VK_OBJECT_TYPE_EVENT:
1074 stub_return(VK_UNSUPPORTED);
1075
1076 default:
1077 unreachable("Invalid object type");
1078 }
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001079}
1080
1081static void
1082fill_memory_requirements(
1083 VkObjectType objType,
1084 VkObject object,
1085 VkMemoryRequirements * memory_requirements)
1086{
1087 struct anv_buffer *buffer;
1088 struct anv_image *image;
1089
1090 memory_requirements->memPropsAllowed =
1091 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
Jason Ekstrand68fa7502015-07-06 17:32:28 -07001092 /* VK_MEMORY_PROPERTY_HOST_NON_COHERENT_BIT | */
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001093 /* VK_MEMORY_PROPERTY_HOST_UNCACHED_BIT | */
Jason Ekstrand65f9ccb2015-07-06 17:33:43 -07001094 VK_MEMORY_PROPERTY_HOST_WRITE_COMBINED_BIT;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001095
1096 memory_requirements->memPropsRequired = 0;
1097
1098 switch (objType) {
1099 case VK_OBJECT_TYPE_BUFFER:
1100 buffer = (struct anv_buffer *) object;
1101 memory_requirements->size = buffer->size;
1102 memory_requirements->alignment = 16;
1103 break;
1104 case VK_OBJECT_TYPE_IMAGE:
1105 image = (struct anv_image *) object;
1106 memory_requirements->size = image->size;
1107 memory_requirements->alignment = image->alignment;
1108 break;
1109 default:
1110 memory_requirements->size = 0;
1111 break;
1112 }
1113}
1114
Kristian Høgsbergb7fac7a2015-05-17 19:25:28 -07001115static uint32_t
1116get_allocation_count(VkObjectType objType)
1117{
1118 switch (objType) {
1119 case VK_OBJECT_TYPE_BUFFER:
1120 case VK_OBJECT_TYPE_IMAGE:
1121 return 1;
1122 default:
1123 return 0;
1124 }
1125}
1126
Kristian Høgsberg454345d2015-05-17 16:33:48 -07001127VkResult anv_GetObjectInfo(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001128 VkDevice _device,
1129 VkObjectType objType,
1130 VkObject object,
1131 VkObjectInfoType infoType,
1132 size_t* pDataSize,
1133 void* pData)
1134{
1135 VkMemoryRequirements memory_requirements;
Kristian Høgsberg05754542015-05-18 08:50:04 -07001136 uint32_t *count;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001137
1138 switch (infoType) {
1139 case VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS:
Kristian Høgsberg783e6212015-05-17 19:22:52 -07001140 *pDataSize = sizeof(memory_requirements);
1141 if (pData == NULL)
1142 return VK_SUCCESS;
1143
Kristian Høgsberg05754542015-05-18 08:50:04 -07001144 fill_memory_requirements(objType, object, pData);
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001145 return VK_SUCCESS;
1146
1147 case VK_OBJECT_INFO_TYPE_MEMORY_ALLOCATION_COUNT:
Kristian Høgsbergb7fac7a2015-05-17 19:25:28 -07001148 *pDataSize = sizeof(count);
1149 if (pData == NULL)
1150 return VK_SUCCESS;
1151
Kristian Høgsberg05754542015-05-18 08:50:04 -07001152 count = pData;
1153 *count = get_allocation_count(objType);
Kristian Høgsbergb7fac7a2015-05-17 19:25:28 -07001154 return VK_SUCCESS;
1155
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001156 default:
Jason Ekstrandc8b62d12015-06-10 21:04:13 -07001157 return vk_error(VK_UNSUPPORTED);
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001158 }
1159
1160}
1161
Kristian Høgsberg454345d2015-05-17 16:33:48 -07001162VkResult anv_QueueBindObjectMemory(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001163 VkQueue queue,
1164 VkObjectType objType,
1165 VkObject object,
1166 uint32_t allocationIdx,
1167 VkDeviceMemory _mem,
1168 VkDeviceSize memOffset)
1169{
1170 struct anv_buffer *buffer;
1171 struct anv_image *image;
1172 struct anv_device_memory *mem = (struct anv_device_memory *) _mem;
1173
1174 switch (objType) {
1175 case VK_OBJECT_TYPE_BUFFER:
1176 buffer = (struct anv_buffer *) object;
Kristian Høgsberg099faa12015-05-11 22:19:58 -07001177 buffer->bo = &mem->bo;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001178 buffer->offset = memOffset;
1179 break;
1180 case VK_OBJECT_TYPE_IMAGE:
1181 image = (struct anv_image *) object;
Kristian Høgsberg099faa12015-05-11 22:19:58 -07001182 image->bo = &mem->bo;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001183 image->offset = memOffset;
1184 break;
1185 default:
1186 break;
1187 }
1188
1189 return VK_SUCCESS;
1190}
1191
Kristian Høgsberg454345d2015-05-17 16:33:48 -07001192VkResult anv_QueueBindObjectMemoryRange(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001193 VkQueue queue,
1194 VkObjectType objType,
1195 VkObject object,
1196 uint32_t allocationIdx,
1197 VkDeviceSize rangeOffset,
1198 VkDeviceSize rangeSize,
1199 VkDeviceMemory mem,
1200 VkDeviceSize memOffset)
1201{
Jason Ekstrandffe9f602015-05-12 13:44:43 -07001202 stub_return(VK_UNSUPPORTED);
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001203}
1204
Kristian Høgsberg454345d2015-05-17 16:33:48 -07001205VkResult anv_QueueBindImageMemoryRange(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001206 VkQueue queue,
1207 VkImage image,
1208 uint32_t allocationIdx,
1209 const VkImageMemoryBindInfo* pBindInfo,
1210 VkDeviceMemory mem,
1211 VkDeviceSize memOffset)
1212{
Jason Ekstrandffe9f602015-05-12 13:44:43 -07001213 stub_return(VK_UNSUPPORTED);
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001214}
1215
Jason Ekstrand57153da2015-05-22 15:15:08 -07001216static void
1217anv_fence_destroy(struct anv_device *device,
1218 struct anv_object *object,
1219 VkObjectType obj_type)
1220{
1221 struct anv_fence *fence = (struct anv_fence *) object;
1222
1223 assert(obj_type == VK_OBJECT_TYPE_FENCE);
1224
1225 anv_gem_munmap(fence->bo.map, fence->bo.size);
1226 anv_gem_close(device, fence->bo.gem_handle);
1227 anv_device_free(device, fence);
1228}
1229
Kristian Høgsberg454345d2015-05-17 16:33:48 -07001230VkResult anv_CreateFence(
Kristian Høgsberg6afb2642015-05-18 08:49:15 -07001231 VkDevice _device,
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001232 const VkFenceCreateInfo* pCreateInfo,
1233 VkFence* pFence)
1234{
Kristian Høgsberg6afb2642015-05-18 08:49:15 -07001235 struct anv_device *device = (struct anv_device *) _device;
1236 struct anv_fence *fence;
1237 struct anv_batch batch;
1238 VkResult result;
1239
1240 const uint32_t fence_size = 128;
1241
1242 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FENCE_CREATE_INFO);
1243
1244 fence = anv_device_alloc(device, sizeof(*fence), 8,
1245 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1246 if (fence == NULL)
1247 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1248
1249 result = anv_bo_init_new(&fence->bo, device, fence_size);
1250 if (result != VK_SUCCESS)
1251 goto fail;
1252
Jason Ekstrand57153da2015-05-22 15:15:08 -07001253 fence->base.destructor = anv_fence_destroy;
1254
Kristian Høgsberg6afb2642015-05-18 08:49:15 -07001255 fence->bo.map =
1256 anv_gem_mmap(device, fence->bo.gem_handle, 0, fence->bo.size);
Jason Ekstrandda8f1482015-05-27 11:42:55 -07001257 batch.next = batch.start = fence->bo.map;
1258 batch.end = fence->bo.map + fence->bo.size;
Kristian Høgsberg6afb2642015-05-18 08:49:15 -07001259 anv_batch_emit(&batch, GEN8_MI_BATCH_BUFFER_END);
1260 anv_batch_emit(&batch, GEN8_MI_NOOP);
1261
1262 fence->exec2_objects[0].handle = fence->bo.gem_handle;
1263 fence->exec2_objects[0].relocation_count = 0;
1264 fence->exec2_objects[0].relocs_ptr = 0;
1265 fence->exec2_objects[0].alignment = 0;
1266 fence->exec2_objects[0].offset = fence->bo.offset;
1267 fence->exec2_objects[0].flags = 0;
1268 fence->exec2_objects[0].rsvd1 = 0;
1269 fence->exec2_objects[0].rsvd2 = 0;
1270
1271 fence->execbuf.buffers_ptr = (uintptr_t) fence->exec2_objects;
1272 fence->execbuf.buffer_count = 1;
1273 fence->execbuf.batch_start_offset = 0;
1274 fence->execbuf.batch_len = batch.next - fence->bo.map;
1275 fence->execbuf.cliprects_ptr = 0;
1276 fence->execbuf.num_cliprects = 0;
1277 fence->execbuf.DR1 = 0;
1278 fence->execbuf.DR4 = 0;
1279
1280 fence->execbuf.flags =
1281 I915_EXEC_HANDLE_LUT | I915_EXEC_NO_RELOC | I915_EXEC_RENDER;
1282 fence->execbuf.rsvd1 = device->context_id;
1283 fence->execbuf.rsvd2 = 0;
1284
Chad Versace87d98e12015-06-04 14:31:53 -07001285 *pFence = (VkFence) fence;
Kristian Høgsberg6afb2642015-05-18 08:49:15 -07001286
1287 return VK_SUCCESS;
1288
1289 fail:
1290 anv_device_free(device, fence);
1291
1292 return result;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001293}
1294
Kristian Høgsberg454345d2015-05-17 16:33:48 -07001295VkResult anv_ResetFences(
Kristian Høgsberg6afb2642015-05-18 08:49:15 -07001296 VkDevice _device,
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001297 uint32_t fenceCount,
1298 VkFence* pFences)
1299{
Kristian Høgsberg6afb2642015-05-18 08:49:15 -07001300 struct anv_fence **fences = (struct anv_fence **) pFences;
1301
Kristian Høgsberg Kristensen52637c02015-06-05 11:51:30 -07001302 for (uint32_t i = 0; i < fenceCount; i++)
Kristian Høgsberg6afb2642015-05-18 08:49:15 -07001303 fences[i]->ready = false;
1304
1305 return VK_SUCCESS;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001306}
1307
Kristian Høgsberg454345d2015-05-17 16:33:48 -07001308VkResult anv_GetFenceStatus(
Kristian Høgsberg6afb2642015-05-18 08:49:15 -07001309 VkDevice _device,
1310 VkFence _fence)
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001311{
Kristian Høgsberg6afb2642015-05-18 08:49:15 -07001312 struct anv_device *device = (struct anv_device *) _device;
1313 struct anv_fence *fence = (struct anv_fence *) _fence;
1314 int64_t t = 0;
1315 int ret;
1316
1317 if (fence->ready)
1318 return VK_SUCCESS;
1319
1320 ret = anv_gem_wait(device, fence->bo.gem_handle, &t);
1321 if (ret == 0) {
1322 fence->ready = true;
1323 return VK_SUCCESS;
1324 }
1325
1326 return VK_NOT_READY;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001327}
1328
Kristian Høgsberg454345d2015-05-17 16:33:48 -07001329VkResult anv_WaitForFences(
Kristian Høgsberg6afb2642015-05-18 08:49:15 -07001330 VkDevice _device,
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001331 uint32_t fenceCount,
1332 const VkFence* pFences,
1333 bool32_t waitAll,
1334 uint64_t timeout)
1335{
Kristian Høgsberg6afb2642015-05-18 08:49:15 -07001336 struct anv_device *device = (struct anv_device *) _device;
1337 struct anv_fence **fences = (struct anv_fence **) pFences;
1338 int64_t t = timeout;
1339 int ret;
1340
1341 /* FIXME: handle !waitAll */
1342
1343 for (uint32_t i = 0; i < fenceCount; i++) {
1344 ret = anv_gem_wait(device, fences[i]->bo.gem_handle, &t);
1345 if (ret == -1 && errno == ETIME)
1346 return VK_TIMEOUT;
1347 else if (ret == -1)
1348 return vk_error(VK_ERROR_UNKNOWN);
1349 }
1350
1351 return VK_SUCCESS;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001352}
1353
1354// Queue semaphore functions
1355
Kristian Høgsberg454345d2015-05-17 16:33:48 -07001356VkResult anv_CreateSemaphore(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001357 VkDevice device,
1358 const VkSemaphoreCreateInfo* pCreateInfo,
1359 VkSemaphore* pSemaphore)
1360{
Jason Ekstrandffe9f602015-05-12 13:44:43 -07001361 stub_return(VK_UNSUPPORTED);
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001362}
1363
Kristian Høgsberg454345d2015-05-17 16:33:48 -07001364VkResult anv_QueueSignalSemaphore(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001365 VkQueue queue,
1366 VkSemaphore semaphore)
1367{
Jason Ekstrandffe9f602015-05-12 13:44:43 -07001368 stub_return(VK_UNSUPPORTED);
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001369}
1370
Kristian Høgsberg454345d2015-05-17 16:33:48 -07001371VkResult anv_QueueWaitSemaphore(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001372 VkQueue queue,
1373 VkSemaphore semaphore)
1374{
Jason Ekstrandffe9f602015-05-12 13:44:43 -07001375 stub_return(VK_UNSUPPORTED);
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001376}
1377
1378// Event functions
1379
Kristian Høgsberg454345d2015-05-17 16:33:48 -07001380VkResult anv_CreateEvent(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001381 VkDevice device,
1382 const VkEventCreateInfo* pCreateInfo,
1383 VkEvent* pEvent)
1384{
Jason Ekstrandffe9f602015-05-12 13:44:43 -07001385 stub_return(VK_UNSUPPORTED);
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001386}
1387
Kristian Høgsberg454345d2015-05-17 16:33:48 -07001388VkResult anv_GetEventStatus(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001389 VkDevice device,
1390 VkEvent event)
1391{
Jason Ekstrandffe9f602015-05-12 13:44:43 -07001392 stub_return(VK_UNSUPPORTED);
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001393}
1394
Kristian Høgsberg454345d2015-05-17 16:33:48 -07001395VkResult anv_SetEvent(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001396 VkDevice device,
1397 VkEvent event)
1398{
Jason Ekstrandffe9f602015-05-12 13:44:43 -07001399 stub_return(VK_UNSUPPORTED);
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001400}
1401
Kristian Høgsberg454345d2015-05-17 16:33:48 -07001402VkResult anv_ResetEvent(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001403 VkDevice device,
1404 VkEvent event)
1405{
Jason Ekstrandffe9f602015-05-12 13:44:43 -07001406 stub_return(VK_UNSUPPORTED);
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001407}
1408
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001409// Buffer functions
1410
Kristian Høgsberg454345d2015-05-17 16:33:48 -07001411VkResult anv_CreateBuffer(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001412 VkDevice _device,
1413 const VkBufferCreateInfo* pCreateInfo,
1414 VkBuffer* pBuffer)
1415{
1416 struct anv_device *device = (struct anv_device *) _device;
1417 struct anv_buffer *buffer;
1418
1419 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
1420
1421 buffer = anv_device_alloc(device, sizeof(*buffer), 8,
1422 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1423 if (buffer == NULL)
1424 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1425
1426 buffer->size = pCreateInfo->size;
Kristian Høgsberg099faa12015-05-11 22:19:58 -07001427 buffer->bo = NULL;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001428 buffer->offset = 0;
1429
1430 *pBuffer = (VkBuffer) buffer;
1431
1432 return VK_SUCCESS;
1433}
1434
1435// Buffer view functions
1436
Kristian Høgsberg Kristensenfad418f2015-05-27 14:05:50 -07001437static void
1438fill_buffer_surface_state(void *state, VkFormat format,
1439 uint32_t offset, uint32_t range)
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001440{
Kristian Høgsberg Kristensenfad418f2015-05-27 14:05:50 -07001441 const struct anv_format *info;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001442
Kristian Høgsberg Kristensenfad418f2015-05-27 14:05:50 -07001443 info = anv_format_for_vk_format(format);
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001444 /* This assumes RGBA float format. */
1445 uint32_t stride = 4;
Kristian Høgsberg Kristensenfad418f2015-05-27 14:05:50 -07001446 uint32_t num_elements = range / stride;
1447
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001448 struct GEN8_RENDER_SURFACE_STATE surface_state = {
1449 .SurfaceType = SURFTYPE_BUFFER,
1450 .SurfaceArray = false,
Chad Versace4c814632015-06-25 18:18:06 -07001451 .SurfaceFormat = info->surface_format,
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001452 .SurfaceVerticalAlignment = VALIGN4,
1453 .SurfaceHorizontalAlignment = HALIGN4,
1454 .TileMode = LINEAR,
1455 .VerticalLineStride = 0,
1456 .VerticalLineStrideOffset = 0,
1457 .SamplerL2BypassModeDisable = true,
1458 .RenderCacheReadWriteMode = WriteOnlyCache,
Kristian Høgsberg0997a7b2015-05-21 14:35:34 -07001459 .MemoryObjectControlState = GEN8_MOCS,
Kristian Høgsberg Kristensena5b49d22015-06-10 23:11:37 -07001460 .BaseMipLevel = 0.0,
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001461 .SurfaceQPitch = 0,
1462 .Height = (num_elements >> 7) & 0x3fff,
1463 .Width = num_elements & 0x7f,
1464 .Depth = (num_elements >> 21) & 0x3f,
1465 .SurfacePitch = stride - 1,
1466 .MinimumArrayElement = 0,
1467 .NumberofMultisamples = MULTISAMPLECOUNT_1,
1468 .XOffset = 0,
1469 .YOffset = 0,
1470 .SurfaceMinLOD = 0,
1471 .MIPCountLOD = 0,
1472 .AuxiliarySurfaceMode = AUX_NONE,
1473 .RedClearColor = 0,
1474 .GreenClearColor = 0,
1475 .BlueClearColor = 0,
1476 .AlphaClearColor = 0,
1477 .ShaderChannelSelectRed = SCS_RED,
1478 .ShaderChannelSelectGreen = SCS_GREEN,
1479 .ShaderChannelSelectBlue = SCS_BLUE,
1480 .ShaderChannelSelectAlpha = SCS_ALPHA,
Kristian Høgsberg Kristensena5b49d22015-06-10 23:11:37 -07001481 .ResourceMinLOD = 0.0,
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001482 /* FIXME: We assume that the image must be bound at this time. */
Kristian Høgsberg Kristensenfad418f2015-05-27 14:05:50 -07001483 .SurfaceBaseAddress = { NULL, offset },
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001484 };
1485
Kristian Høgsberg Kristensenfad418f2015-05-27 14:05:50 -07001486 GEN8_RENDER_SURFACE_STATE_pack(NULL, state, &surface_state);
1487}
1488
1489VkResult anv_CreateBufferView(
1490 VkDevice _device,
1491 const VkBufferViewCreateInfo* pCreateInfo,
1492 VkBufferView* pView)
1493{
1494 struct anv_device *device = (struct anv_device *) _device;
1495 struct anv_buffer *buffer = (struct anv_buffer *) pCreateInfo->buffer;
1496 struct anv_surface_view *view;
1497
1498 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO);
1499
1500 view = anv_device_alloc(device, sizeof(*view), 8,
1501 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1502 if (view == NULL)
1503 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1504
Jason Ekstrand9d6f55d2015-06-09 11:08:03 -07001505 view->base.destructor = anv_surface_view_destroy;
1506
Kristian Høgsberg Kristensenfad418f2015-05-27 14:05:50 -07001507 view->bo = buffer->bo;
1508 view->offset = buffer->offset + pCreateInfo->offset;
1509 view->surface_state =
1510 anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
1511 view->format = pCreateInfo->format;
1512 view->range = pCreateInfo->range;
1513
1514 fill_buffer_surface_state(view->surface_state.map,
1515 pCreateInfo->format, view->offset, pCreateInfo->range);
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001516
Chad Versace87d98e12015-06-04 14:31:53 -07001517 *pView = (VkBufferView) view;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001518
1519 return VK_SUCCESS;
1520}
1521
1522// Sampler functions
1523
Kristian Høgsberg454345d2015-05-17 16:33:48 -07001524VkResult anv_CreateSampler(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001525 VkDevice _device,
1526 const VkSamplerCreateInfo* pCreateInfo,
1527 VkSampler* pSampler)
1528{
1529 struct anv_device *device = (struct anv_device *) _device;
1530 struct anv_sampler *sampler;
Kristian Høgsberg Kristensen76bb6582015-05-31 22:15:34 -07001531 uint32_t mag_filter, min_filter, max_anisotropy;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001532
Kristian Høgsberg18acfa72015-05-13 13:53:01 -07001533 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001534
1535 sampler = anv_device_alloc(device, sizeof(*sampler), 8,
1536 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1537 if (!sampler)
1538 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1539
Kristian Høgsberga3fd1362015-05-12 21:44:59 -07001540 static const uint32_t vk_to_gen_tex_filter[] = {
Kristian Høgsberg Kristensen5caa4082015-05-31 22:35:11 -07001541 [VK_TEX_FILTER_NEAREST] = MAPFILTER_NEAREST,
1542 [VK_TEX_FILTER_LINEAR] = MAPFILTER_LINEAR
Kristian Høgsberga3fd1362015-05-12 21:44:59 -07001543 };
1544
1545 static const uint32_t vk_to_gen_mipmap_mode[] = {
Kristian Høgsberg Kristensen5caa4082015-05-31 22:35:11 -07001546 [VK_TEX_MIPMAP_MODE_BASE] = MIPFILTER_NONE,
1547 [VK_TEX_MIPMAP_MODE_NEAREST] = MIPFILTER_NEAREST,
1548 [VK_TEX_MIPMAP_MODE_LINEAR] = MIPFILTER_LINEAR
Kristian Høgsberga3fd1362015-05-12 21:44:59 -07001549 };
1550
1551 static const uint32_t vk_to_gen_tex_address[] = {
Kristian Høgsberg Kristensen5caa4082015-05-31 22:35:11 -07001552 [VK_TEX_ADDRESS_WRAP] = TCM_WRAP,
1553 [VK_TEX_ADDRESS_MIRROR] = TCM_MIRROR,
1554 [VK_TEX_ADDRESS_CLAMP] = TCM_CLAMP,
1555 [VK_TEX_ADDRESS_MIRROR_ONCE] = TCM_MIRROR_ONCE,
1556 [VK_TEX_ADDRESS_CLAMP_BORDER] = TCM_CLAMP_BORDER,
Kristian Høgsberga3fd1362015-05-12 21:44:59 -07001557 };
1558
1559 static const uint32_t vk_to_gen_compare_op[] = {
Kristian Høgsberg Kristensen5caa4082015-05-31 22:35:11 -07001560 [VK_COMPARE_OP_NEVER] = PREFILTEROPNEVER,
1561 [VK_COMPARE_OP_LESS] = PREFILTEROPLESS,
1562 [VK_COMPARE_OP_EQUAL] = PREFILTEROPEQUAL,
1563 [VK_COMPARE_OP_LESS_EQUAL] = PREFILTEROPLEQUAL,
1564 [VK_COMPARE_OP_GREATER] = PREFILTEROPGREATER,
1565 [VK_COMPARE_OP_NOT_EQUAL] = PREFILTEROPNOTEQUAL,
1566 [VK_COMPARE_OP_GREATER_EQUAL] = PREFILTEROPGEQUAL,
1567 [VK_COMPARE_OP_ALWAYS] = PREFILTEROPALWAYS,
Kristian Høgsberga3fd1362015-05-12 21:44:59 -07001568 };
1569
Kristian Høgsberg Kristensen76bb6582015-05-31 22:15:34 -07001570 if (pCreateInfo->maxAnisotropy > 1) {
1571 mag_filter = MAPFILTER_ANISOTROPIC;
1572 min_filter = MAPFILTER_ANISOTROPIC;
1573 max_anisotropy = (pCreateInfo->maxAnisotropy - 2) / 2;
1574 } else {
1575 mag_filter = vk_to_gen_tex_filter[pCreateInfo->magFilter];
1576 min_filter = vk_to_gen_tex_filter[pCreateInfo->minFilter];
1577 max_anisotropy = RATIO21;
1578 }
1579
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001580 struct GEN8_SAMPLER_STATE sampler_state = {
Kristian Høgsberga3fd1362015-05-12 21:44:59 -07001581 .SamplerDisable = false,
1582 .TextureBorderColorMode = DX10OGL,
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001583 .LODPreClampMode = 0,
Kristian Høgsberg Kristensena5b49d22015-06-10 23:11:37 -07001584 .BaseMipLevel = 0.0,
Kristian Høgsberga3fd1362015-05-12 21:44:59 -07001585 .MipModeFilter = vk_to_gen_mipmap_mode[pCreateInfo->mipMode],
Kristian Høgsberg Kristensen76bb6582015-05-31 22:15:34 -07001586 .MagModeFilter = mag_filter,
1587 .MinModeFilter = min_filter,
Kristian Høgsberga3fd1362015-05-12 21:44:59 -07001588 .TextureLODBias = pCreateInfo->mipLodBias * 256,
1589 .AnisotropicAlgorithm = EWAApproximation,
Kristian Høgsberg Kristensena5b49d22015-06-10 23:11:37 -07001590 .MinLOD = pCreateInfo->minLod,
1591 .MaxLOD = pCreateInfo->maxLod,
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001592 .ChromaKeyEnable = 0,
1593 .ChromaKeyIndex = 0,
1594 .ChromaKeyMode = 0,
Kristian Høgsberga3fd1362015-05-12 21:44:59 -07001595 .ShadowFunction = vk_to_gen_compare_op[pCreateInfo->compareOp],
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001596 .CubeSurfaceControlMode = 0,
Kristian Høgsberg Kristensendc56e4f2015-05-29 16:06:06 -07001597
1598 .IndirectStatePointer =
1599 device->float_border_colors.offset +
Kristian Høgsberg Kristensen76bb6582015-05-31 22:15:34 -07001600 pCreateInfo->borderColor * sizeof(float) * 4,
Kristian Høgsberg Kristensendc56e4f2015-05-29 16:06:06 -07001601
Kristian Høgsberga3fd1362015-05-12 21:44:59 -07001602 .LODClampMagnificationMode = MIPNONE,
Kristian Høgsberg Kristensen76bb6582015-05-31 22:15:34 -07001603 .MaximumAnisotropy = max_anisotropy,
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001604 .RAddressMinFilterRoundingEnable = 0,
1605 .RAddressMagFilterRoundingEnable = 0,
1606 .VAddressMinFilterRoundingEnable = 0,
1607 .VAddressMagFilterRoundingEnable = 0,
1608 .UAddressMinFilterRoundingEnable = 0,
1609 .UAddressMagFilterRoundingEnable = 0,
1610 .TrilinearFilterQuality = 0,
1611 .NonnormalizedCoordinateEnable = 0,
Kristian Høgsberga3fd1362015-05-12 21:44:59 -07001612 .TCXAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressU],
1613 .TCYAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressV],
1614 .TCZAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressW],
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001615 };
1616
1617 GEN8_SAMPLER_STATE_pack(NULL, sampler->state, &sampler_state);
1618
1619 *pSampler = (VkSampler) sampler;
1620
1621 return VK_SUCCESS;
1622}
1623
1624// Descriptor set functions
1625
Kristian Høgsberg454345d2015-05-17 16:33:48 -07001626VkResult anv_CreateDescriptorSetLayout(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001627 VkDevice _device,
1628 const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
1629 VkDescriptorSetLayout* pSetLayout)
1630{
1631 struct anv_device *device = (struct anv_device *) _device;
1632 struct anv_descriptor_set_layout *set_layout;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001633
1634 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO);
1635
Jason Ekstrand8c5e48f2015-07-06 16:43:28 -07001636 uint32_t sampler_count[VK_SHADER_STAGE_NUM] = { 0, };
1637 uint32_t surface_count[VK_SHADER_STAGE_NUM] = { 0, };
Kristian Høgsbergbf096c92015-05-15 15:03:21 -07001638 uint32_t num_dynamic_buffers = 0;
1639 uint32_t count = 0;
Jason Ekstrand22513052015-05-30 10:07:29 -07001640 uint32_t stages = 0;
Kristian Høgsbergbf096c92015-05-15 15:03:21 -07001641 uint32_t s;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001642
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001643 for (uint32_t i = 0; i < pCreateInfo->count; i++) {
Kristian Høgsberg83c7e1f2015-05-13 14:43:08 -07001644 switch (pCreateInfo->pBinding[i].descriptorType) {
1645 case VK_DESCRIPTOR_TYPE_SAMPLER:
Kristian Høgsberg83c7e1f2015-05-13 14:43:08 -07001646 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
Kristian Høgsbergbf096c92015-05-15 15:03:21 -07001647 for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
Jason Ekstrand63c11902015-07-06 17:43:58 -07001648 sampler_count[s] += pCreateInfo->pBinding[i].arraySize;
Kristian Høgsberg Kristensenfad418f2015-05-27 14:05:50 -07001649 break;
1650 default:
1651 break;
1652 }
Kristian Høgsbergbf096c92015-05-15 15:03:21 -07001653
Kristian Høgsberg Kristensenfad418f2015-05-27 14:05:50 -07001654 switch (pCreateInfo->pBinding[i].descriptorType) {
1655 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
Kristian Høgsberg83c7e1f2015-05-13 14:43:08 -07001656 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1657 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1658 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1659 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1660 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1661 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1662 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1663 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
Kristian Høgsbergbf096c92015-05-15 15:03:21 -07001664 for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
Jason Ekstrand63c11902015-07-06 17:43:58 -07001665 surface_count[s] += pCreateInfo->pBinding[i].arraySize;
Kristian Høgsberg83c7e1f2015-05-13 14:43:08 -07001666 break;
Kristian Høgsberg83c7e1f2015-05-13 14:43:08 -07001667 default:
Kristian Høgsbergbf096c92015-05-15 15:03:21 -07001668 break;
1669 }
1670
Kristian Høgsbergbf096c92015-05-15 15:03:21 -07001671 switch (pCreateInfo->pBinding[i].descriptorType) {
1672 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1673 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
Jason Ekstrand63c11902015-07-06 17:43:58 -07001674 num_dynamic_buffers += pCreateInfo->pBinding[i].arraySize;
Kristian Høgsbergbf096c92015-05-15 15:03:21 -07001675 break;
1676 default:
1677 break;
Kristian Høgsberg83c7e1f2015-05-13 14:43:08 -07001678 }
Kristian Høgsberg Kristensenfad418f2015-05-27 14:05:50 -07001679
Jason Ekstrand22513052015-05-30 10:07:29 -07001680 stages |= pCreateInfo->pBinding[i].stageFlags;
Jason Ekstrand63c11902015-07-06 17:43:58 -07001681 count += pCreateInfo->pBinding[i].arraySize;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001682 }
1683
Kristian Høgsbergbf096c92015-05-15 15:03:21 -07001684 uint32_t sampler_total = 0;
1685 uint32_t surface_total = 0;
Jason Ekstrand8c5e48f2015-07-06 16:43:28 -07001686 for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) {
Kristian Høgsbergbf096c92015-05-15 15:03:21 -07001687 sampler_total += sampler_count[s];
1688 surface_total += surface_count[s];
1689 }
1690
1691 size_t size = sizeof(*set_layout) +
Kristian Høgsberg Kristensenfad418f2015-05-27 14:05:50 -07001692 (sampler_total + surface_total) * sizeof(set_layout->entries[0]);
Kristian Høgsbergbf096c92015-05-15 15:03:21 -07001693 set_layout = anv_device_alloc(device, size, 8,
1694 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1695 if (!set_layout)
1696 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1697
1698 set_layout->num_dynamic_buffers = num_dynamic_buffers;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001699 set_layout->count = count;
Jason Ekstrand22513052015-05-30 10:07:29 -07001700 set_layout->shader_stages = stages;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001701
Kristian Høgsberg Kristensenfad418f2015-05-27 14:05:50 -07001702 struct anv_descriptor_slot *p = set_layout->entries;
Jason Ekstrand8c5e48f2015-07-06 16:43:28 -07001703 struct anv_descriptor_slot *sampler[VK_SHADER_STAGE_NUM];
1704 struct anv_descriptor_slot *surface[VK_SHADER_STAGE_NUM];
1705 for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) {
Kristian Høgsbergbf096c92015-05-15 15:03:21 -07001706 set_layout->stage[s].surface_count = surface_count[s];
1707 set_layout->stage[s].surface_start = surface[s] = p;
1708 p += surface_count[s];
1709 set_layout->stage[s].sampler_count = sampler_count[s];
1710 set_layout->stage[s].sampler_start = sampler[s] = p;
1711 p += sampler_count[s];
1712 }
1713
1714 uint32_t descriptor = 0;
Kristian Høgsberg Kristensen4aecec02015-05-29 11:32:53 -07001715 int8_t dynamic_slot = 0;
1716 bool is_dynamic;
Kristian Høgsbergbf096c92015-05-15 15:03:21 -07001717 for (uint32_t i = 0; i < pCreateInfo->count; i++) {
1718 switch (pCreateInfo->pBinding[i].descriptorType) {
1719 case VK_DESCRIPTOR_TYPE_SAMPLER:
Kristian Høgsbergbf096c92015-05-15 15:03:21 -07001720 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1721 for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
Jason Ekstrand63c11902015-07-06 17:43:58 -07001722 for (uint32_t j = 0; j < pCreateInfo->pBinding[i].arraySize; j++) {
Kristian Høgsberg Kristensenfad418f2015-05-27 14:05:50 -07001723 sampler[s]->index = descriptor + j;
Kristian Høgsberg Kristensen4aecec02015-05-29 11:32:53 -07001724 sampler[s]->dynamic_slot = -1;
Kristian Høgsberg Kristensenfad418f2015-05-27 14:05:50 -07001725 sampler[s]++;
1726 }
1727 break;
1728 default:
1729 break;
1730 }
Kristian Høgsbergbf096c92015-05-15 15:03:21 -07001731
Kristian Høgsberg Kristensenfad418f2015-05-27 14:05:50 -07001732 switch (pCreateInfo->pBinding[i].descriptorType) {
1733 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1734 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
Kristian Høgsberg Kristensen4aecec02015-05-29 11:32:53 -07001735 is_dynamic = true;
Kristian Høgsberg Kristensenfad418f2015-05-27 14:05:50 -07001736 break;
1737 default:
Kristian Høgsberg Kristensen4aecec02015-05-29 11:32:53 -07001738 is_dynamic = false;
Kristian Høgsberg Kristensenfad418f2015-05-27 14:05:50 -07001739 break;
1740 }
Kristian Høgsbergbf096c92015-05-15 15:03:21 -07001741
Kristian Høgsberg Kristensenfad418f2015-05-27 14:05:50 -07001742 switch (pCreateInfo->pBinding[i].descriptorType) {
1743 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
Kristian Høgsbergbf096c92015-05-15 15:03:21 -07001744 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1745 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1746 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1747 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1748 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1749 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1750 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1751 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1752 for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
Jason Ekstrand63c11902015-07-06 17:43:58 -07001753 for (uint32_t j = 0; j < pCreateInfo->pBinding[i].arraySize; j++) {
Kristian Høgsberg Kristensenfad418f2015-05-27 14:05:50 -07001754 surface[s]->index = descriptor + j;
Kristian Høgsberg Kristensen4aecec02015-05-29 11:32:53 -07001755 if (is_dynamic)
1756 surface[s]->dynamic_slot = dynamic_slot + j;
1757 else
1758 surface[s]->dynamic_slot = -1;
Kristian Høgsberg Kristensenfad418f2015-05-27 14:05:50 -07001759 surface[s]++;
Kristian Høgsbergbf096c92015-05-15 15:03:21 -07001760 }
1761 break;
1762 default:
Kristian Høgsberg Kristensenfad418f2015-05-27 14:05:50 -07001763 break;
Kristian Høgsbergbf096c92015-05-15 15:03:21 -07001764 }
Kristian Høgsberg Kristensen4aecec02015-05-29 11:32:53 -07001765
1766 if (is_dynamic)
Jason Ekstrand63c11902015-07-06 17:43:58 -07001767 dynamic_slot += pCreateInfo->pBinding[i].arraySize;
Kristian Høgsberg Kristensen4aecec02015-05-29 11:32:53 -07001768
Jason Ekstrand63c11902015-07-06 17:43:58 -07001769 descriptor += pCreateInfo->pBinding[i].arraySize;
Kristian Høgsbergbf096c92015-05-15 15:03:21 -07001770 }
1771
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001772 *pSetLayout = (VkDescriptorSetLayout) set_layout;
1773
1774 return VK_SUCCESS;
1775}
1776
Kristian Høgsberg454345d2015-05-17 16:33:48 -07001777VkResult anv_CreateDescriptorPool(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001778 VkDevice device,
1779 VkDescriptorPoolUsage poolUsage,
1780 uint32_t maxSets,
1781 const VkDescriptorPoolCreateInfo* pCreateInfo,
1782 VkDescriptorPool* pDescriptorPool)
1783{
Kristian Høgsberga9f21152015-05-17 18:38:34 -07001784 *pDescriptorPool = 1;
1785
1786 return VK_SUCCESS;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001787}
1788
Kristian Høgsberg454345d2015-05-17 16:33:48 -07001789VkResult anv_ResetDescriptorPool(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001790 VkDevice device,
1791 VkDescriptorPool descriptorPool)
1792{
Kristian Høgsberga9f21152015-05-17 18:38:34 -07001793 return VK_SUCCESS;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001794}
1795
Kristian Høgsberg454345d2015-05-17 16:33:48 -07001796VkResult anv_AllocDescriptorSets(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001797 VkDevice _device,
1798 VkDescriptorPool descriptorPool,
1799 VkDescriptorSetUsage setUsage,
1800 uint32_t count,
1801 const VkDescriptorSetLayout* pSetLayouts,
1802 VkDescriptorSet* pDescriptorSets,
1803 uint32_t* pCount)
1804{
1805 struct anv_device *device = (struct anv_device *) _device;
1806 const struct anv_descriptor_set_layout *layout;
1807 struct anv_descriptor_set *set;
1808 size_t size;
1809
1810 for (uint32_t i = 0; i < count; i++) {
1811 layout = (struct anv_descriptor_set_layout *) pSetLayouts[i];
Kristian Høgsberga77229c2015-05-13 11:49:30 -07001812 size = sizeof(*set) + layout->count * sizeof(set->descriptors[0]);
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001813 set = anv_device_alloc(device, size, 8,
1814 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1815 if (!set) {
1816 *pCount = i;
1817 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1818 }
1819
Jason Ekstrand0a547512015-05-21 16:33:04 -07001820 /* Descriptor sets may not be 100% filled out so we need to memset to
1821 * ensure that we can properly detect and handle holes.
1822 */
1823 memset(set, 0, size);
1824
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001825 pDescriptorSets[i] = (VkDescriptorSet) set;
1826 }
1827
1828 *pCount = count;
1829
Kristian Høgsbergb4b3bd12015-05-17 18:39:12 -07001830 return VK_SUCCESS;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001831}
1832
Kristian Høgsberg454345d2015-05-17 16:33:48 -07001833void anv_UpdateDescriptors(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001834 VkDevice _device,
1835 VkDescriptorSet descriptorSet,
1836 uint32_t updateCount,
1837 const void** ppUpdateArray)
1838{
1839 struct anv_descriptor_set *set = (struct anv_descriptor_set *) descriptorSet;
1840 VkUpdateSamplers *update_samplers;
1841 VkUpdateSamplerTextures *update_sampler_textures;
1842 VkUpdateImages *update_images;
1843 VkUpdateBuffers *update_buffers;
1844 VkUpdateAsCopy *update_as_copy;
1845
1846 for (uint32_t i = 0; i < updateCount; i++) {
1847 const struct anv_common *common = ppUpdateArray[i];
1848
1849 switch (common->sType) {
1850 case VK_STRUCTURE_TYPE_UPDATE_SAMPLERS:
1851 update_samplers = (VkUpdateSamplers *) common;
1852
1853 for (uint32_t j = 0; j < update_samplers->count; j++) {
Kristian Høgsberg4f9eaf72015-05-13 14:02:35 -07001854 set->descriptors[update_samplers->binding + j].sampler =
1855 (struct anv_sampler *) update_samplers->pSamplers[j];
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001856 }
1857 break;
1858
1859 case VK_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES:
1860 /* FIXME: Shouldn't this be *_UPDATE_SAMPLER_IMAGES? */
1861 update_sampler_textures = (VkUpdateSamplerTextures *) common;
1862
1863 for (uint32_t j = 0; j < update_sampler_textures->count; j++) {
Kristian Høgsbergf5b0f132015-05-13 15:31:26 -07001864 set->descriptors[update_sampler_textures->binding + j].view =
1865 (struct anv_surface_view *)
Kristian Høgsberg4f9eaf72015-05-13 14:02:35 -07001866 update_sampler_textures->pSamplerImageViews[j].pImageView->view;
1867 set->descriptors[update_sampler_textures->binding + j].sampler =
1868 (struct anv_sampler *)
1869 update_sampler_textures->pSamplerImageViews[j].sampler;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001870 }
1871 break;
1872
1873 case VK_STRUCTURE_TYPE_UPDATE_IMAGES:
1874 update_images = (VkUpdateImages *) common;
1875
1876 for (uint32_t j = 0; j < update_images->count; j++) {
Kristian Høgsbergf5b0f132015-05-13 15:31:26 -07001877 set->descriptors[update_images->binding + j].view =
1878 (struct anv_surface_view *) update_images->pImageViews[j].view;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001879 }
1880 break;
1881
1882 case VK_STRUCTURE_TYPE_UPDATE_BUFFERS:
1883 update_buffers = (VkUpdateBuffers *) common;
1884
1885 for (uint32_t j = 0; j < update_buffers->count; j++) {
Kristian Høgsbergf5b0f132015-05-13 15:31:26 -07001886 set->descriptors[update_buffers->binding + j].view =
1887 (struct anv_surface_view *) update_buffers->pBufferViews[j].view;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001888 }
1889 /* FIXME: descriptor arrays? */
1890 break;
1891
1892 case VK_STRUCTURE_TYPE_UPDATE_AS_COPY:
1893 update_as_copy = (VkUpdateAsCopy *) common;
1894 (void) update_as_copy;
1895 break;
1896
1897 default:
1898 break;
1899 }
1900 }
1901}
1902
1903// State object functions
1904
1905static inline int64_t
1906clamp_int64(int64_t x, int64_t min, int64_t max)
1907{
1908 if (x < min)
1909 return min;
1910 else if (x < max)
1911 return x;
1912 else
1913 return max;
1914}
1915
Jason Ekstrand57153da2015-05-22 15:15:08 -07001916static void
1917anv_dynamic_vp_state_destroy(struct anv_device *device,
1918 struct anv_object *object,
1919 VkObjectType obj_type)
1920{
1921 struct anv_dynamic_vp_state *state = (void *)object;
1922
1923 assert(obj_type == VK_OBJECT_TYPE_DYNAMIC_VP_STATE);
1924
1925 anv_state_pool_free(&device->dynamic_state_pool, state->sf_clip_vp);
1926 anv_state_pool_free(&device->dynamic_state_pool, state->cc_vp);
1927 anv_state_pool_free(&device->dynamic_state_pool, state->scissor);
1928
1929 anv_device_free(device, state);
1930}
1931
Kristian Høgsberg454345d2015-05-17 16:33:48 -07001932VkResult anv_CreateDynamicViewportState(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001933 VkDevice _device,
1934 const VkDynamicVpStateCreateInfo* pCreateInfo,
1935 VkDynamicVpState* pState)
1936{
1937 struct anv_device *device = (struct anv_device *) _device;
1938 struct anv_dynamic_vp_state *state;
1939
1940 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO);
1941
1942 state = anv_device_alloc(device, sizeof(*state), 8,
1943 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1944 if (state == NULL)
1945 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1946
Jason Ekstrand57153da2015-05-22 15:15:08 -07001947 state->base.destructor = anv_dynamic_vp_state_destroy;
1948
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001949 unsigned count = pCreateInfo->viewportAndScissorCount;
Kristian Høgsberg0a775e12015-05-13 15:34:34 -07001950 state->sf_clip_vp = anv_state_pool_alloc(&device->dynamic_state_pool,
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001951 count * 64, 64);
Kristian Høgsberg0a775e12015-05-13 15:34:34 -07001952 state->cc_vp = anv_state_pool_alloc(&device->dynamic_state_pool,
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001953 count * 8, 32);
Kristian Høgsberg0a775e12015-05-13 15:34:34 -07001954 state->scissor = anv_state_pool_alloc(&device->dynamic_state_pool,
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001955 count * 32, 32);
1956
1957 for (uint32_t i = 0; i < pCreateInfo->viewportAndScissorCount; i++) {
1958 const VkViewport *vp = &pCreateInfo->pViewports[i];
Jason Ekstrand1f1b26b2015-07-06 17:47:18 -07001959 const VkRect2D *s = &pCreateInfo->pScissors[i];
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001960
1961 struct GEN8_SF_CLIP_VIEWPORT sf_clip_viewport = {
1962 .ViewportMatrixElementm00 = vp->width / 2,
1963 .ViewportMatrixElementm11 = vp->height / 2,
1964 .ViewportMatrixElementm22 = (vp->maxDepth - vp->minDepth) / 2,
1965 .ViewportMatrixElementm30 = vp->originX + vp->width / 2,
1966 .ViewportMatrixElementm31 = vp->originY + vp->height / 2,
1967 .ViewportMatrixElementm32 = (vp->maxDepth + vp->minDepth) / 2,
1968 .XMinClipGuardband = -1.0f,
1969 .XMaxClipGuardband = 1.0f,
1970 .YMinClipGuardband = -1.0f,
1971 .YMaxClipGuardband = 1.0f,
1972 .XMinViewPort = vp->originX,
1973 .XMaxViewPort = vp->originX + vp->width - 1,
1974 .YMinViewPort = vp->originY,
1975 .YMaxViewPort = vp->originY + vp->height - 1,
1976 };
1977
1978 struct GEN8_CC_VIEWPORT cc_viewport = {
1979 .MinimumDepth = vp->minDepth,
1980 .MaximumDepth = vp->maxDepth
1981 };
1982
1983 /* Since xmax and ymax are inclusive, we have to have xmax < xmin or
1984 * ymax < ymin for empty clips. In case clip x, y, width height are all
1985 * 0, the clamps below produce 0 for xmin, ymin, xmax, ymax, which isn't
1986 * what we want. Just special case empty clips and produce a canonical
1987 * empty clip. */
1988 static const struct GEN8_SCISSOR_RECT empty_scissor = {
1989 .ScissorRectangleYMin = 1,
1990 .ScissorRectangleXMin = 1,
1991 .ScissorRectangleYMax = 0,
1992 .ScissorRectangleXMax = 0
1993 };
1994
1995 const int max = 0xffff;
1996 struct GEN8_SCISSOR_RECT scissor = {
1997 /* Do this math using int64_t so overflow gets clamped correctly. */
1998 .ScissorRectangleYMin = clamp_int64(s->offset.y, 0, max),
1999 .ScissorRectangleXMin = clamp_int64(s->offset.x, 0, max),
2000 .ScissorRectangleYMax = clamp_int64((uint64_t) s->offset.y + s->extent.height - 1, 0, max),
2001 .ScissorRectangleXMax = clamp_int64((uint64_t) s->offset.x + s->extent.width - 1, 0, max)
2002 };
2003
2004 GEN8_SF_CLIP_VIEWPORT_pack(NULL, state->sf_clip_vp.map + i * 64, &sf_clip_viewport);
2005 GEN8_CC_VIEWPORT_pack(NULL, state->cc_vp.map + i * 32, &cc_viewport);
2006
2007 if (s->extent.width <= 0 || s->extent.height <= 0) {
2008 GEN8_SCISSOR_RECT_pack(NULL, state->scissor.map + i * 32, &empty_scissor);
2009 } else {
2010 GEN8_SCISSOR_RECT_pack(NULL, state->scissor.map + i * 32, &scissor);
2011 }
2012 }
2013
2014 *pState = (VkDynamicVpState) state;
2015
2016 return VK_SUCCESS;
2017}
2018
Kristian Høgsberg454345d2015-05-17 16:33:48 -07002019VkResult anv_CreateDynamicRasterState(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002020 VkDevice _device,
2021 const VkDynamicRsStateCreateInfo* pCreateInfo,
2022 VkDynamicRsState* pState)
2023{
2024 struct anv_device *device = (struct anv_device *) _device;
2025 struct anv_dynamic_rs_state *state;
2026
2027 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO);
2028
2029 state = anv_device_alloc(device, sizeof(*state), 8,
2030 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
2031 if (state == NULL)
2032 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2033
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002034 struct GEN8_3DSTATE_SF sf = {
2035 GEN8_3DSTATE_SF_header,
2036 .LineWidth = pCreateInfo->lineWidth,
Jason Ekstrand1fb859e2015-07-07 12:35:32 -07002037 .PointWidth = 1.0,
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002038 };
2039
2040 GEN8_3DSTATE_SF_pack(NULL, state->state_sf, &sf);
2041
Kristian Høgsberg99883772015-05-26 09:40:10 -07002042 bool enable_bias = pCreateInfo->depthBias != 0.0f ||
2043 pCreateInfo->slopeScaledDepthBias != 0.0f;
2044 struct GEN8_3DSTATE_RASTER raster = {
2045 .GlobalDepthOffsetEnableSolid = enable_bias,
2046 .GlobalDepthOffsetEnableWireframe = enable_bias,
2047 .GlobalDepthOffsetEnablePoint = enable_bias,
2048 .GlobalDepthOffsetConstant = pCreateInfo->depthBias,
2049 .GlobalDepthOffsetScale = pCreateInfo->slopeScaledDepthBias,
2050 .GlobalDepthOffsetClamp = pCreateInfo->depthBiasClamp
2051 };
2052
2053 GEN8_3DSTATE_RASTER_pack(NULL, state->state_raster, &raster);
2054
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002055 *pState = (VkDynamicRsState) state;
2056
2057 return VK_SUCCESS;
2058}
2059
Kristian Høgsberg454345d2015-05-17 16:33:48 -07002060VkResult anv_CreateDynamicColorBlendState(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002061 VkDevice _device,
2062 const VkDynamicCbStateCreateInfo* pCreateInfo,
2063 VkDynamicCbState* pState)
2064{
2065 struct anv_device *device = (struct anv_device *) _device;
2066 struct anv_dynamic_cb_state *state;
2067
2068 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_CB_STATE_CREATE_INFO);
2069
2070 state = anv_device_alloc(device, sizeof(*state), 8,
2071 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
2072 if (state == NULL)
2073 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2074
Kristian Høgsbergb29f4422015-05-26 11:22:12 -07002075 struct GEN8_COLOR_CALC_STATE color_calc_state = {
2076 .BlendConstantColorRed = pCreateInfo->blendConst[0],
2077 .BlendConstantColorGreen = pCreateInfo->blendConst[1],
2078 .BlendConstantColorBlue = pCreateInfo->blendConst[2],
2079 .BlendConstantColorAlpha = pCreateInfo->blendConst[3]
2080 };
2081
2082 GEN8_COLOR_CALC_STATE_pack(NULL, state->state_color_calc, &color_calc_state);
2083
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002084 *pState = (VkDynamicCbState) state;
2085
2086 return VK_SUCCESS;
2087}
2088
Kristian Høgsberg454345d2015-05-17 16:33:48 -07002089VkResult anv_CreateDynamicDepthStencilState(
Kristian Høgsbergcbe7ed42015-05-24 21:19:26 -07002090 VkDevice _device,
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002091 const VkDynamicDsStateCreateInfo* pCreateInfo,
2092 VkDynamicDsState* pState)
2093{
Kristian Høgsbergcbe7ed42015-05-24 21:19:26 -07002094 struct anv_device *device = (struct anv_device *) _device;
2095 struct anv_dynamic_ds_state *state;
2096
2097 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_DS_STATE_CREATE_INFO);
2098
2099 state = anv_device_alloc(device, sizeof(*state), 8,
2100 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
2101 if (state == NULL)
2102 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2103
2104 struct GEN8_3DSTATE_WM_DEPTH_STENCIL wm_depth_stencil = {
2105 GEN8_3DSTATE_WM_DEPTH_STENCIL_header,
2106
Kristian Høgsbergcbe7ed42015-05-24 21:19:26 -07002107 /* Is this what we need to do? */
2108 .StencilBufferWriteEnable = pCreateInfo->stencilWriteMask != 0,
2109
Jason Ekstrand251aea82015-06-03 16:59:13 -07002110 .StencilTestMask = pCreateInfo->stencilReadMask & 0xff,
2111 .StencilWriteMask = pCreateInfo->stencilWriteMask & 0xff,
Kristian Høgsbergcbe7ed42015-05-24 21:19:26 -07002112
Jason Ekstrand251aea82015-06-03 16:59:13 -07002113 .BackfaceStencilTestMask = pCreateInfo->stencilReadMask & 0xff,
2114 .BackfaceStencilWriteMask = pCreateInfo->stencilWriteMask & 0xff,
Kristian Høgsbergcbe7ed42015-05-24 21:19:26 -07002115 };
2116
2117 GEN8_3DSTATE_WM_DEPTH_STENCIL_pack(NULL, state->state_wm_depth_stencil,
2118 &wm_depth_stencil);
2119
Kristian Høgsbergb29f4422015-05-26 11:22:12 -07002120 struct GEN8_COLOR_CALC_STATE color_calc_state = {
2121 .StencilReferenceValue = pCreateInfo->stencilFrontRef,
2122 .BackFaceStencilReferenceValue = pCreateInfo->stencilBackRef
2123 };
2124
2125 GEN8_COLOR_CALC_STATE_pack(NULL, state->state_color_calc, &color_calc_state);
2126
Kristian Høgsbergcbe7ed42015-05-24 21:19:26 -07002127 *pState = (VkDynamicDsState) state;
2128
2129 return VK_SUCCESS;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002130}
2131
2132// Command buffer functions
2133
Jason Ekstrand57153da2015-05-22 15:15:08 -07002134static void
2135anv_cmd_buffer_destroy(struct anv_device *device,
2136 struct anv_object *object,
2137 VkObjectType obj_type)
2138{
2139 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) object;
2140
2141 assert(obj_type == VK_OBJECT_TYPE_COMMAND_BUFFER);
2142
Jason Ekstrand2dc0f7f2015-05-28 13:08:21 -07002143 /* Destroy all of the batch buffers */
2144 struct anv_batch_bo *bbo = cmd_buffer->last_batch_bo;
Jason Ekstrand999b56c2015-06-09 11:40:22 -07002145 while (bbo) {
Jason Ekstrand2dc0f7f2015-05-28 13:08:21 -07002146 struct anv_batch_bo *prev = bbo->prev_batch_bo;
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002147 anv_batch_bo_destroy(bbo, device);
Jason Ekstrand2dc0f7f2015-05-28 13:08:21 -07002148 bbo = prev;
2149 }
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002150 anv_reloc_list_finish(&cmd_buffer->batch.relocs, device);
Jason Ekstrand2dc0f7f2015-05-28 13:08:21 -07002151
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002152 /* Destroy all of the surface state buffers */
2153 bbo = cmd_buffer->surface_batch_bo;
Jason Ekstrand999b56c2015-06-09 11:40:22 -07002154 while (bbo) {
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002155 struct anv_batch_bo *prev = bbo->prev_batch_bo;
2156 anv_batch_bo_destroy(bbo, device);
2157 bbo = prev;
2158 }
Jason Ekstrand403266b2015-05-25 17:38:15 -07002159 anv_reloc_list_finish(&cmd_buffer->surface_relocs, device);
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002160
Jason Ekstrand57153da2015-05-22 15:15:08 -07002161 anv_state_stream_finish(&cmd_buffer->surface_state_stream);
2162 anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);
Jason Ekstrand57153da2015-05-22 15:15:08 -07002163 anv_device_free(device, cmd_buffer->exec2_objects);
2164 anv_device_free(device, cmd_buffer->exec2_bos);
2165 anv_device_free(device, cmd_buffer);
2166}
2167
Jason Ekstrandda8f1482015-05-27 11:42:55 -07002168static VkResult
2169anv_cmd_buffer_chain_batch(struct anv_batch *batch, void *_data)
2170{
2171 struct anv_cmd_buffer *cmd_buffer = _data;
Jason Ekstrand730ca0e2015-05-28 10:20:18 -07002172
Jason Ekstrandda8f1482015-05-27 11:42:55 -07002173 struct anv_batch_bo *new_bbo, *old_bbo = cmd_buffer->last_batch_bo;
2174
2175 VkResult result = anv_batch_bo_create(cmd_buffer->device, &new_bbo);
2176 if (result != VK_SUCCESS)
2177 return result;
2178
Jason Ekstrand468c89a2015-05-28 15:25:02 -07002179 /* We set the end of the batch a little short so we would be sure we
2180 * have room for the chaining command. Since we're about to emit the
2181 * chaining command, let's set it back where it should go.
2182 */
2183 batch->end += GEN8_MI_BATCH_BUFFER_START_length * 4;
2184 assert(batch->end == old_bbo->bo.map + old_bbo->bo.size);
2185
2186 anv_batch_emit(batch, GEN8_MI_BATCH_BUFFER_START,
Jason Ekstrandda8f1482015-05-27 11:42:55 -07002187 GEN8_MI_BATCH_BUFFER_START_header,
2188 ._2ndLevelBatchBuffer = _1stlevelbatch,
2189 .AddressSpaceIndicator = ASI_PPGTT,
2190 .BatchBufferStartAddress = { &new_bbo->bo, 0 },
Jason Ekstrand468c89a2015-05-28 15:25:02 -07002191 );
Jason Ekstrandda8f1482015-05-27 11:42:55 -07002192
2193 /* Pad out to a 2-dword aligned boundary with zeros */
Jason Ekstrand730ca0e2015-05-28 10:20:18 -07002194 if ((uintptr_t)batch->next % 8 != 0) {
Jason Ekstrandda8f1482015-05-27 11:42:55 -07002195 *(uint32_t *)batch->next = 0;
Jason Ekstrand730ca0e2015-05-28 10:20:18 -07002196 batch->next += 4;
2197 }
Jason Ekstrandda8f1482015-05-27 11:42:55 -07002198
2199 anv_batch_bo_finish(cmd_buffer->last_batch_bo, batch);
2200
2201 new_bbo->prev_batch_bo = old_bbo;
2202 cmd_buffer->last_batch_bo = new_bbo;
2203
2204 anv_batch_bo_start(new_bbo, batch, GEN8_MI_BATCH_BUFFER_START_length * 4);
2205
2206 return VK_SUCCESS;
2207}
2208
Kristian Høgsberg454345d2015-05-17 16:33:48 -07002209VkResult anv_CreateCommandBuffer(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002210 VkDevice _device,
2211 const VkCmdBufferCreateInfo* pCreateInfo,
2212 VkCmdBuffer* pCmdBuffer)
2213{
2214 struct anv_device *device = (struct anv_device *) _device;
2215 struct anv_cmd_buffer *cmd_buffer;
2216 VkResult result;
2217
2218 cmd_buffer = anv_device_alloc(device, sizeof(*cmd_buffer), 8,
2219 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
2220 if (cmd_buffer == NULL)
2221 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2222
Jason Ekstrand57153da2015-05-22 15:15:08 -07002223 cmd_buffer->base.destructor = anv_cmd_buffer_destroy;
2224
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002225 cmd_buffer->device = device;
Kristian Høgsbergd77c34d2015-05-11 23:25:06 -07002226 cmd_buffer->rs_state = NULL;
2227 cmd_buffer->vp_state = NULL;
Kristian Høgsberg Kristensen5744d172015-06-02 22:51:42 -07002228 cmd_buffer->cb_state = NULL;
Jason Ekstrand5d4b6a02015-06-09 16:27:55 -07002229 cmd_buffer->ds_state = NULL;
Jason Ekstrand7fbed522015-07-07 15:11:56 -07002230 memset(&cmd_buffer->state_vf, 0, sizeof(cmd_buffer->state_vf));
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002231 memset(&cmd_buffer->descriptors, 0, sizeof(cmd_buffer->descriptors));
Kristian Høgsbergd77c34d2015-05-11 23:25:06 -07002232
Jason Ekstrandda8f1482015-05-27 11:42:55 -07002233 result = anv_batch_bo_create(device, &cmd_buffer->last_batch_bo);
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002234 if (result != VK_SUCCESS)
2235 goto fail;
2236
Jason Ekstrandda8f1482015-05-27 11:42:55 -07002237 result = anv_reloc_list_init(&cmd_buffer->batch.relocs, device);
2238 if (result != VK_SUCCESS)
2239 goto fail_batch_bo;
2240
2241 cmd_buffer->batch.device = device;
2242 cmd_buffer->batch.extend_cb = anv_cmd_buffer_chain_batch;
2243 cmd_buffer->batch.user_data = cmd_buffer;
2244
2245 anv_batch_bo_start(cmd_buffer->last_batch_bo, &cmd_buffer->batch,
2246 GEN8_MI_BATCH_BUFFER_START_length * 4);
2247
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002248 result = anv_batch_bo_create(device, &cmd_buffer->surface_batch_bo);
Kristian Høgsberga1bd4262015-05-19 14:14:24 -07002249 if (result != VK_SUCCESS)
Jason Ekstrandda8f1482015-05-27 11:42:55 -07002250 goto fail_batch_relocs;
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002251 cmd_buffer->surface_batch_bo->first_reloc = 0;
2252
2253 result = anv_reloc_list_init(&cmd_buffer->surface_relocs, device);
2254 if (result != VK_SUCCESS)
2255 goto fail_ss_batch_bo;
Kristian Høgsberga1bd4262015-05-19 14:14:24 -07002256
Kristian Høgsberga1bd4262015-05-19 14:14:24 -07002257 /* Start surface_next at 1 so surface offset 0 is invalid. */
2258 cmd_buffer->surface_next = 1;
Kristian Høgsberga1bd4262015-05-19 14:14:24 -07002259
Jason Ekstrandda8f1482015-05-27 11:42:55 -07002260 cmd_buffer->exec2_objects = NULL;
2261 cmd_buffer->exec2_bos = NULL;
2262 cmd_buffer->exec2_array_length = 0;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002263
2264 anv_state_stream_init(&cmd_buffer->surface_state_stream,
2265 &device->surface_state_block_pool);
Kristian Høgsberga1ec7892015-05-13 13:51:08 -07002266 anv_state_stream_init(&cmd_buffer->dynamic_state_stream,
Kristian Høgsberg0a775e12015-05-13 15:34:34 -07002267 &device->dynamic_state_block_pool);
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002268
2269 cmd_buffer->dirty = 0;
2270 cmd_buffer->vb_dirty = 0;
Jason Ekstrand22513052015-05-30 10:07:29 -07002271 cmd_buffer->descriptors_dirty = 0;
Jason Ekstrandae8c93e2015-05-25 17:08:11 -07002272 cmd_buffer->pipeline = NULL;
Kristian Høgsberg Kristensen5a317ef2015-05-27 21:45:23 -07002273 cmd_buffer->vp_state = NULL;
2274 cmd_buffer->rs_state = NULL;
2275 cmd_buffer->ds_state = NULL;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002276
2277 *pCmdBuffer = (VkCmdBuffer) cmd_buffer;
2278
2279 return VK_SUCCESS;
2280
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002281 fail_ss_batch_bo:
2282 anv_batch_bo_destroy(cmd_buffer->surface_batch_bo, device);
Jason Ekstrandda8f1482015-05-27 11:42:55 -07002283 fail_batch_relocs:
2284 anv_reloc_list_finish(&cmd_buffer->batch.relocs, device);
2285 fail_batch_bo:
2286 anv_batch_bo_destroy(cmd_buffer->last_batch_bo, device);
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002287 fail:
2288 anv_device_free(device, cmd_buffer);
2289
2290 return result;
2291}
2292
Jason Ekstrand9ffc1be2015-05-28 15:34:08 -07002293static void
2294anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer)
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002295{
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002296 struct anv_device *device = cmd_buffer->device;
Kristian Høgsberg Kristensen9b9f9732015-06-19 15:41:30 -07002297 struct anv_bo *scratch_bo = NULL;
2298
2299 cmd_buffer->scratch_size = device->scratch_block_pool.size;
2300 if (cmd_buffer->scratch_size > 0)
2301 scratch_bo = &device->scratch_block_pool.bo;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002302
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002303 anv_batch_emit(&cmd_buffer->batch, GEN8_STATE_BASE_ADDRESS,
Kristian Høgsberg Kristensen9b9f9732015-06-19 15:41:30 -07002304 .GeneralStateBaseAddress = { scratch_bo, 0 },
Kristian Høgsberg0997a7b2015-05-21 14:35:34 -07002305 .GeneralStateMemoryObjectControlState = GEN8_MOCS,
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002306 .GeneralStateBaseAddressModifyEnable = true,
2307 .GeneralStateBufferSize = 0xfffff,
2308 .GeneralStateBufferSizeModifyEnable = true,
2309
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002310 .SurfaceStateBaseAddress = { &cmd_buffer->surface_batch_bo->bo, 0 },
Kristian Høgsberg0997a7b2015-05-21 14:35:34 -07002311 .SurfaceStateMemoryObjectControlState = GEN8_MOCS,
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002312 .SurfaceStateBaseAddressModifyEnable = true,
2313
Kristian Høgsberg0a775e12015-05-13 15:34:34 -07002314 .DynamicStateBaseAddress = { &device->dynamic_state_block_pool.bo, 0 },
Kristian Høgsberg0997a7b2015-05-21 14:35:34 -07002315 .DynamicStateMemoryObjectControlState = GEN8_MOCS,
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002316 .DynamicStateBaseAddressModifyEnable = true,
2317 .DynamicStateBufferSize = 0xfffff,
2318 .DynamicStateBufferSizeModifyEnable = true,
2319
2320 .IndirectObjectBaseAddress = { NULL, 0 },
Kristian Høgsberg0997a7b2015-05-21 14:35:34 -07002321 .IndirectObjectMemoryObjectControlState = GEN8_MOCS,
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002322 .IndirectObjectBaseAddressModifyEnable = true,
2323 .IndirectObjectBufferSize = 0xfffff,
2324 .IndirectObjectBufferSizeModifyEnable = true,
Jason Ekstrand9ffc1be2015-05-28 15:34:08 -07002325
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002326 .InstructionBaseAddress = { &device->instruction_block_pool.bo, 0 },
Kristian Høgsberg0997a7b2015-05-21 14:35:34 -07002327 .InstructionMemoryObjectControlState = GEN8_MOCS,
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002328 .InstructionBaseAddressModifyEnable = true,
2329 .InstructionBufferSize = 0xfffff,
2330 .InstructionBuffersizeModifyEnable = true);
Jason Ekstrand9ffc1be2015-05-28 15:34:08 -07002331}
2332
2333VkResult anv_BeginCommandBuffer(
2334 VkCmdBuffer cmdBuffer,
2335 const VkCmdBufferBeginInfo* pBeginInfo)
2336{
2337 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2338
Jason Ekstrand9ffc1be2015-05-28 15:34:08 -07002339 anv_cmd_buffer_emit_state_base_address(cmd_buffer);
Kristian Høgsberg Kristensen7637b022015-06-11 15:21:49 -07002340 cmd_buffer->current_pipeline = UINT32_MAX;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002341
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002342 return VK_SUCCESS;
2343}
2344
Jason Ekstrandda8f1482015-05-27 11:42:55 -07002345static VkResult
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002346anv_cmd_buffer_add_bo(struct anv_cmd_buffer *cmd_buffer,
Jason Ekstrand730ca0e2015-05-28 10:20:18 -07002347 struct anv_bo *bo,
2348 struct drm_i915_gem_relocation_entry *relocs,
2349 size_t num_relocs)
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002350{
2351 struct drm_i915_gem_exec_object2 *obj;
2352
Jason Ekstrandda8f1482015-05-27 11:42:55 -07002353 if (bo->index < cmd_buffer->bo_count &&
2354 cmd_buffer->exec2_bos[bo->index] == bo)
2355 return VK_SUCCESS;
2356
2357 if (cmd_buffer->bo_count >= cmd_buffer->exec2_array_length) {
2358 uint32_t new_len = cmd_buffer->exec2_objects ?
2359 cmd_buffer->exec2_array_length * 2 : 64;
2360
2361 struct drm_i915_gem_exec_object2 *new_objects =
2362 anv_device_alloc(cmd_buffer->device, new_len * sizeof(*new_objects),
2363 8, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
2364 if (new_objects == NULL)
2365 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2366
2367 struct anv_bo **new_bos =
2368 anv_device_alloc(cmd_buffer->device, new_len * sizeof(*new_bos),
2369 8, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
2370 if (new_objects == NULL) {
2371 anv_device_free(cmd_buffer->device, new_objects);
2372 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2373 }
2374
2375 if (cmd_buffer->exec2_objects) {
2376 memcpy(new_objects, cmd_buffer->exec2_objects,
2377 cmd_buffer->bo_count * sizeof(*new_objects));
2378 memcpy(new_bos, cmd_buffer->exec2_bos,
2379 cmd_buffer->bo_count * sizeof(*new_bos));
2380 }
2381
2382 cmd_buffer->exec2_objects = new_objects;
2383 cmd_buffer->exec2_bos = new_bos;
2384 cmd_buffer->exec2_array_length = new_len;
2385 }
2386
2387 assert(cmd_buffer->bo_count < cmd_buffer->exec2_array_length);
2388
2389 bo->index = cmd_buffer->bo_count++;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002390 obj = &cmd_buffer->exec2_objects[bo->index];
2391 cmd_buffer->exec2_bos[bo->index] = bo;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002392
2393 obj->handle = bo->gem_handle;
2394 obj->relocation_count = 0;
2395 obj->relocs_ptr = 0;
2396 obj->alignment = 0;
2397 obj->offset = bo->offset;
2398 obj->flags = 0;
2399 obj->rsvd1 = 0;
2400 obj->rsvd2 = 0;
2401
Jason Ekstrand730ca0e2015-05-28 10:20:18 -07002402 if (relocs) {
2403 obj->relocation_count = num_relocs;
2404 obj->relocs_ptr = (uintptr_t) relocs;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002405 }
Jason Ekstrandda8f1482015-05-27 11:42:55 -07002406
2407 return VK_SUCCESS;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002408}
2409
2410static void
2411anv_cmd_buffer_add_validate_bos(struct anv_cmd_buffer *cmd_buffer,
2412 struct anv_reloc_list *list)
2413{
Jason Ekstrandda8f1482015-05-27 11:42:55 -07002414 for (size_t i = 0; i < list->num_relocs; i++)
Jason Ekstrand730ca0e2015-05-28 10:20:18 -07002415 anv_cmd_buffer_add_bo(cmd_buffer, list->reloc_bos[i], NULL, 0);
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002416}
2417
2418static void
2419anv_cmd_buffer_process_relocs(struct anv_cmd_buffer *cmd_buffer,
2420 struct anv_reloc_list *list)
2421{
2422 struct anv_bo *bo;
2423
2424 /* If the kernel supports I915_EXEC_NO_RELOC, it will compare offset in
2425 * struct drm_i915_gem_exec_object2 against the bos current offset and if
2426 * all bos haven't moved it will skip relocation processing alltogether.
2427 * If I915_EXEC_NO_RELOC is not supported, the kernel ignores the incoming
2428 * value of offset so we can set it either way. For that to work we need
2429 * to make sure all relocs use the same presumed offset.
2430 */
2431
2432 for (size_t i = 0; i < list->num_relocs; i++) {
2433 bo = list->reloc_bos[i];
2434 if (bo->offset != list->relocs[i].presumed_offset)
2435 cmd_buffer->need_reloc = true;
2436
2437 list->relocs[i].target_handle = bo->index;
2438 }
2439}
2440
Kristian Høgsberg454345d2015-05-17 16:33:48 -07002441VkResult anv_EndCommandBuffer(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002442 VkCmdBuffer cmdBuffer)
2443{
2444 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2445 struct anv_device *device = cmd_buffer->device;
2446 struct anv_batch *batch = &cmd_buffer->batch;
2447
2448 anv_batch_emit(batch, GEN8_MI_BATCH_BUFFER_END);
2449
2450 /* Round batch up to an even number of dwords. */
Jason Ekstrandda8f1482015-05-27 11:42:55 -07002451 if ((batch->next - batch->start) & 4)
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002452 anv_batch_emit(batch, GEN8_MI_NOOP);
2453
Jason Ekstrandda8f1482015-05-27 11:42:55 -07002454 anv_batch_bo_finish(cmd_buffer->last_batch_bo, &cmd_buffer->batch);
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002455 cmd_buffer->surface_batch_bo->num_relocs =
2456 cmd_buffer->surface_relocs.num_relocs - cmd_buffer->surface_batch_bo->first_reloc;
2457 cmd_buffer->surface_batch_bo->length = cmd_buffer->surface_next;
Jason Ekstrandda8f1482015-05-27 11:42:55 -07002458
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002459 cmd_buffer->bo_count = 0;
2460 cmd_buffer->need_reloc = false;
2461
2462 /* Lock for access to bo->index. */
2463 pthread_mutex_lock(&device->mutex);
2464
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002465 /* Add surface state bos first so we can add them with their relocs. */
2466 for (struct anv_batch_bo *bbo = cmd_buffer->surface_batch_bo;
2467 bbo != NULL; bbo = bbo->prev_batch_bo) {
2468 anv_cmd_buffer_add_bo(cmd_buffer, &bbo->bo,
2469 &cmd_buffer->surface_relocs.relocs[bbo->first_reloc],
2470 bbo->num_relocs);
2471 }
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002472
Jason Ekstrand730ca0e2015-05-28 10:20:18 -07002473 /* Add all of the BOs referenced by surface state */
Kristian Høgsberga1bd4262015-05-19 14:14:24 -07002474 anv_cmd_buffer_add_validate_bos(cmd_buffer, &cmd_buffer->surface_relocs);
Jason Ekstrand730ca0e2015-05-28 10:20:18 -07002475
2476 /* Add all but the first batch BO */
2477 struct anv_batch_bo *batch_bo = cmd_buffer->last_batch_bo;
2478 while (batch_bo->prev_batch_bo) {
2479 anv_cmd_buffer_add_bo(cmd_buffer, &batch_bo->bo,
2480 &batch->relocs.relocs[batch_bo->first_reloc],
2481 batch_bo->num_relocs);
2482 batch_bo = batch_bo->prev_batch_bo;
2483 }
2484
2485 /* Add everything referenced by the batches */
Jason Ekstrandda8f1482015-05-27 11:42:55 -07002486 anv_cmd_buffer_add_validate_bos(cmd_buffer, &batch->relocs);
Jason Ekstrand730ca0e2015-05-28 10:20:18 -07002487
2488 /* Add the first batch bo last */
2489 assert(batch_bo->prev_batch_bo == NULL && batch_bo->first_reloc == 0);
2490 anv_cmd_buffer_add_bo(cmd_buffer, &batch_bo->bo,
2491 &batch->relocs.relocs[batch_bo->first_reloc],
2492 batch_bo->num_relocs);
2493 assert(batch_bo->bo.index == cmd_buffer->bo_count - 1);
2494
Kristian Høgsberga1bd4262015-05-19 14:14:24 -07002495 anv_cmd_buffer_process_relocs(cmd_buffer, &cmd_buffer->surface_relocs);
Jason Ekstrandda8f1482015-05-27 11:42:55 -07002496 anv_cmd_buffer_process_relocs(cmd_buffer, &batch->relocs);
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002497
2498 cmd_buffer->execbuf.buffers_ptr = (uintptr_t) cmd_buffer->exec2_objects;
2499 cmd_buffer->execbuf.buffer_count = cmd_buffer->bo_count;
2500 cmd_buffer->execbuf.batch_start_offset = 0;
Jason Ekstrandda8f1482015-05-27 11:42:55 -07002501 cmd_buffer->execbuf.batch_len = batch->next - batch->start;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002502 cmd_buffer->execbuf.cliprects_ptr = 0;
2503 cmd_buffer->execbuf.num_cliprects = 0;
2504 cmd_buffer->execbuf.DR1 = 0;
2505 cmd_buffer->execbuf.DR4 = 0;
2506
2507 cmd_buffer->execbuf.flags = I915_EXEC_HANDLE_LUT;
2508 if (!cmd_buffer->need_reloc)
2509 cmd_buffer->execbuf.flags |= I915_EXEC_NO_RELOC;
2510 cmd_buffer->execbuf.flags |= I915_EXEC_RENDER;
2511 cmd_buffer->execbuf.rsvd1 = device->context_id;
2512 cmd_buffer->execbuf.rsvd2 = 0;
2513
2514 pthread_mutex_unlock(&device->mutex);
2515
2516 return VK_SUCCESS;
2517}
2518
Kristian Høgsberg454345d2015-05-17 16:33:48 -07002519VkResult anv_ResetCommandBuffer(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002520 VkCmdBuffer cmdBuffer)
2521{
2522 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2523
Jason Ekstrandda8f1482015-05-27 11:42:55 -07002524 /* Delete all but the first batch bo */
2525 while (cmd_buffer->last_batch_bo->prev_batch_bo) {
2526 struct anv_batch_bo *prev = cmd_buffer->last_batch_bo->prev_batch_bo;
2527 anv_batch_bo_destroy(cmd_buffer->last_batch_bo, cmd_buffer->device);
2528 cmd_buffer->last_batch_bo = prev;
2529 }
2530 assert(cmd_buffer->last_batch_bo->prev_batch_bo == NULL);
2531
2532 cmd_buffer->batch.relocs.num_relocs = 0;
2533 anv_batch_bo_start(cmd_buffer->last_batch_bo, &cmd_buffer->batch,
2534 GEN8_MI_BATCH_BUFFER_START_length * 4);
2535
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002536 /* Delete all but the first batch bo */
2537 while (cmd_buffer->surface_batch_bo->prev_batch_bo) {
2538 struct anv_batch_bo *prev = cmd_buffer->surface_batch_bo->prev_batch_bo;
2539 anv_batch_bo_destroy(cmd_buffer->surface_batch_bo, cmd_buffer->device);
2540 cmd_buffer->surface_batch_bo = prev;
2541 }
2542 assert(cmd_buffer->surface_batch_bo->prev_batch_bo == NULL);
2543
2544 cmd_buffer->surface_next = 1;
Kristian Høgsberga1bd4262015-05-19 14:14:24 -07002545 cmd_buffer->surface_relocs.num_relocs = 0;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002546
Jason Ekstrand5d4b6a02015-06-09 16:27:55 -07002547 cmd_buffer->rs_state = NULL;
2548 cmd_buffer->vp_state = NULL;
2549 cmd_buffer->cb_state = NULL;
2550 cmd_buffer->ds_state = NULL;
2551
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002552 return VK_SUCCESS;
2553}
2554
2555// Command buffer building functions
2556
Kristian Høgsberg454345d2015-05-17 16:33:48 -07002557void anv_CmdBindPipeline(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002558 VkCmdBuffer cmdBuffer,
2559 VkPipelineBindPoint pipelineBindPoint,
2560 VkPipeline _pipeline)
2561{
2562 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
Jason Ekstrand0f0b5ae2015-05-21 16:49:55 -07002563 struct anv_pipeline *pipeline = (struct anv_pipeline *) _pipeline;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002564
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07002565 switch (pipelineBindPoint) {
2566 case VK_PIPELINE_BIND_POINT_COMPUTE:
2567 cmd_buffer->compute_pipeline = pipeline;
2568 cmd_buffer->compute_dirty |= ANV_CMD_BUFFER_PIPELINE_DIRTY;
2569 break;
2570
2571 case VK_PIPELINE_BIND_POINT_GRAPHICS:
2572 cmd_buffer->pipeline = pipeline;
2573 cmd_buffer->vb_dirty |= pipeline->vb_used;
2574 cmd_buffer->dirty |= ANV_CMD_BUFFER_PIPELINE_DIRTY;
2575 break;
2576
2577 default:
2578 assert(!"invalid bind point");
2579 break;
2580 }
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002581}
2582
Kristian Høgsberg454345d2015-05-17 16:33:48 -07002583void anv_CmdBindDynamicStateObject(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002584 VkCmdBuffer cmdBuffer,
2585 VkStateBindPoint stateBindPoint,
2586 VkDynamicStateObject dynamicState)
2587{
2588 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002589
2590 switch (stateBindPoint) {
2591 case VK_STATE_BIND_POINT_VIEWPORT:
Kristian Høgsberg Kristensene7edde62015-06-11 15:04:09 -07002592 cmd_buffer->vp_state = (struct anv_dynamic_vp_state *) dynamicState;
2593 cmd_buffer->dirty |= ANV_CMD_BUFFER_VP_DIRTY;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002594 break;
2595 case VK_STATE_BIND_POINT_RASTER:
2596 cmd_buffer->rs_state = (struct anv_dynamic_rs_state *) dynamicState;
2597 cmd_buffer->dirty |= ANV_CMD_BUFFER_RS_DIRTY;
2598 break;
2599 case VK_STATE_BIND_POINT_COLOR_BLEND:
Kristian Høgsberga1d30f82015-05-26 17:12:18 -07002600 cmd_buffer->cb_state = (struct anv_dynamic_cb_state *) dynamicState;
2601 cmd_buffer->dirty |= ANV_CMD_BUFFER_CB_DIRTY;
Kristian Høgsbergcbe7ed42015-05-24 21:19:26 -07002602 break;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002603 case VK_STATE_BIND_POINT_DEPTH_STENCIL:
Kristian Høgsbergcbe7ed42015-05-24 21:19:26 -07002604 cmd_buffer->ds_state = (struct anv_dynamic_ds_state *) dynamicState;
2605 cmd_buffer->dirty |= ANV_CMD_BUFFER_DS_DIRTY;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002606 break;
2607 default:
2608 break;
2609 };
2610}
2611
Kristian Høgsberga1bd4262015-05-19 14:14:24 -07002612static struct anv_state
2613anv_cmd_buffer_alloc_surface_state(struct anv_cmd_buffer *cmd_buffer,
2614 uint32_t size, uint32_t alignment)
2615{
2616 struct anv_state state;
2617
Chad Versace55752fe2015-06-26 15:07:59 -07002618 state.offset = align_u32(cmd_buffer->surface_next, alignment);
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002619 if (state.offset + size > cmd_buffer->surface_batch_bo->bo.size)
2620 return (struct anv_state) { 0 };
2621
2622 state.map = cmd_buffer->surface_batch_bo->bo.map + state.offset;
Kristian Høgsberga1bd4262015-05-19 14:14:24 -07002623 state.alloc_size = size;
2624 cmd_buffer->surface_next = state.offset + size;
2625
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002626 assert(state.offset + size <= cmd_buffer->surface_batch_bo->bo.size);
Kristian Høgsberga1bd4262015-05-19 14:14:24 -07002627
2628 return state;
2629}
2630
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002631static VkResult
2632anv_cmd_buffer_new_surface_state_bo(struct anv_cmd_buffer *cmd_buffer)
2633{
2634 struct anv_batch_bo *new_bbo, *old_bbo = cmd_buffer->surface_batch_bo;
2635
2636 /* Finish off the old buffer */
2637 old_bbo->num_relocs =
2638 cmd_buffer->surface_relocs.num_relocs - old_bbo->first_reloc;
2639 old_bbo->length = cmd_buffer->surface_next;
2640
2641 VkResult result = anv_batch_bo_create(cmd_buffer->device, &new_bbo);
2642 if (result != VK_SUCCESS)
2643 return result;
2644
2645 new_bbo->first_reloc = cmd_buffer->surface_relocs.num_relocs;
2646 cmd_buffer->surface_next = 1;
2647
2648 new_bbo->prev_batch_bo = old_bbo;
2649 cmd_buffer->surface_batch_bo = new_bbo;
2650
2651 /* Re-emit state base addresses so we get the new surface state base
2652 * address before we start emitting binding tables etc.
2653 */
2654 anv_cmd_buffer_emit_state_base_address(cmd_buffer);
2655
Jason Ekstrande497ac22015-05-30 18:04:48 -07002656 /* It seems like just changing the state base addresses isn't enough.
2657 * Invalidating the cache seems to be enough to cause things to
2658 * propagate. However, I'm not 100% sure what we're supposed to do.
Jason Ekstrand33cccbb2015-05-30 08:02:52 -07002659 */
2660 anv_batch_emit(&cmd_buffer->batch, GEN8_PIPE_CONTROL,
2661 .TextureCacheInvalidationEnable = true);
2662
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002663 return VK_SUCCESS;
2664}
2665
Kristian Høgsberg454345d2015-05-17 16:33:48 -07002666void anv_CmdBindDescriptorSets(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002667 VkCmdBuffer cmdBuffer,
2668 VkPipelineBindPoint pipelineBindPoint,
2669 uint32_t firstSet,
2670 uint32_t setCount,
2671 const VkDescriptorSet* pDescriptorSets,
2672 uint32_t dynamicOffsetCount,
2673 const uint32_t* pDynamicOffsets)
2674{
2675 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
Kristian Høgsberg Kristensenfbc9fe32015-06-11 21:57:43 -07002676 struct anv_pipeline_layout *layout;
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002677 struct anv_descriptor_set *set;
2678 struct anv_descriptor_set_layout *set_layout;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002679
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002680 assert(firstSet + setCount < MAX_SETS);
2681
Kristian Høgsberg Kristensenfbc9fe32015-06-11 21:57:43 -07002682 if (pipelineBindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS)
2683 layout = cmd_buffer->pipeline->layout;
2684 else
2685 layout = cmd_buffer->compute_pipeline->layout;
2686
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002687 uint32_t dynamic_slot = 0;
Kristian Høgsbergbf096c92015-05-15 15:03:21 -07002688 for (uint32_t i = 0; i < setCount; i++) {
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002689 set = (struct anv_descriptor_set *) pDescriptorSets[i];
2690 set_layout = layout->set[firstSet + i].layout;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002691
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002692 cmd_buffer->descriptors[firstSet + i].set = set;
Kristian Høgsbergbf096c92015-05-15 15:03:21 -07002693
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002694 assert(set_layout->num_dynamic_buffers <
2695 ARRAY_SIZE(cmd_buffer->descriptors[0].dynamic_offsets));
2696 memcpy(cmd_buffer->descriptors[firstSet + i].dynamic_offsets,
2697 pDynamicOffsets + dynamic_slot,
2698 set_layout->num_dynamic_buffers * sizeof(*pDynamicOffsets));
Kristian Høgsbergbf096c92015-05-15 15:03:21 -07002699
Jason Ekstrand22513052015-05-30 10:07:29 -07002700 cmd_buffer->descriptors_dirty |= set_layout->shader_stages;
2701
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002702 dynamic_slot += set_layout->num_dynamic_buffers;
Kristian Høgsbergbf096c92015-05-15 15:03:21 -07002703 }
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002704}
2705
Kristian Høgsberg454345d2015-05-17 16:33:48 -07002706void anv_CmdBindIndexBuffer(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002707 VkCmdBuffer cmdBuffer,
2708 VkBuffer _buffer,
2709 VkDeviceSize offset,
2710 VkIndexType indexType)
2711{
2712 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2713 struct anv_buffer *buffer = (struct anv_buffer *) _buffer;
2714
2715 static const uint32_t vk_to_gen_index_type[] = {
Kristian Høgsberg Kristensen5caa4082015-05-31 22:35:11 -07002716 [VK_INDEX_TYPE_UINT16] = INDEX_WORD,
2717 [VK_INDEX_TYPE_UINT32] = INDEX_DWORD,
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002718 };
2719
Jason Ekstrand7fbed522015-07-07 15:11:56 -07002720 struct GEN8_3DSTATE_VF vf = {
2721 GEN8_3DSTATE_VF_header,
2722 .CutIndex = (indexType == VK_INDEX_TYPE_UINT16) ? UINT16_MAX : UINT32_MAX,
2723 };
2724 GEN8_3DSTATE_VF_pack(NULL, cmd_buffer->state_vf, &vf);
2725
2726 cmd_buffer->dirty |= ANV_CMD_BUFFER_INDEX_BUFFER_DIRTY;
2727
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002728 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_INDEX_BUFFER,
2729 .IndexFormat = vk_to_gen_index_type[indexType],
Kristian Høgsberg0997a7b2015-05-21 14:35:34 -07002730 .MemoryObjectControlState = GEN8_MOCS,
Kristian Høgsberg099faa12015-05-11 22:19:58 -07002731 .BufferStartingAddress = { buffer->bo, buffer->offset + offset },
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002732 .BufferSize = buffer->size - offset);
2733}
2734
Kristian Høgsberg454345d2015-05-17 16:33:48 -07002735void anv_CmdBindVertexBuffers(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002736 VkCmdBuffer cmdBuffer,
2737 uint32_t startBinding,
2738 uint32_t bindingCount,
2739 const VkBuffer* pBuffers,
2740 const VkDeviceSize* pOffsets)
2741{
2742 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002743 struct anv_vertex_binding *vb = cmd_buffer->vertex_bindings;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002744
2745 /* We have to defer setting up vertex buffer since we need the buffer
2746 * stride from the pipeline. */
2747
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002748 assert(startBinding + bindingCount < MAX_VBS);
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002749 for (uint32_t i = 0; i < bindingCount; i++) {
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002750 vb[startBinding + i].buffer = (struct anv_buffer *) pBuffers[i];
2751 vb[startBinding + i].offset = pOffsets[i];
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002752 cmd_buffer->vb_dirty |= 1 << (startBinding + i);
2753 }
2754}
2755
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002756static VkResult
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002757cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07002758 unsigned stage, struct anv_state *bt_state)
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002759{
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07002760 struct anv_pipeline_layout *layout;
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002761 uint32_t color_attachments, bias, size;
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07002762
2763 if (stage == VK_SHADER_STAGE_COMPUTE)
2764 layout = cmd_buffer->compute_pipeline->layout;
2765 else
2766 layout = cmd_buffer->pipeline->layout;
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002767
2768 if (stage == VK_SHADER_STAGE_FRAGMENT) {
2769 bias = MAX_RTS;
2770 color_attachments = cmd_buffer->framebuffer->color_attachment_count;
2771 } else {
2772 bias = 0;
2773 color_attachments = 0;
2774 }
2775
2776 /* This is a little awkward: layout can be NULL but we still have to
2777 * allocate and set a binding table for the PS stage for render
2778 * targets. */
2779 uint32_t surface_count = layout ? layout->stage[stage].surface_count : 0;
2780
2781 if (color_attachments + surface_count == 0)
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002782 return VK_SUCCESS;
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002783
2784 size = (bias + surface_count) * sizeof(uint32_t);
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07002785 *bt_state = anv_cmd_buffer_alloc_surface_state(cmd_buffer, size, 32);
2786 uint32_t *bt_map = bt_state->map;
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002787
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07002788 if (bt_state->map == NULL)
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002789 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
2790
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002791 for (uint32_t ca = 0; ca < color_attachments; ca++) {
2792 const struct anv_surface_view *view =
2793 cmd_buffer->framebuffer->color_attachments[ca];
2794
2795 struct anv_state state =
2796 anv_cmd_buffer_alloc_surface_state(cmd_buffer, 64, 64);
2797
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002798 if (state.map == NULL)
2799 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
2800
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002801 memcpy(state.map, view->surface_state.map, 64);
2802
2803 /* The address goes in dwords 8 and 9 of the SURFACE_STATE */
2804 *(uint64_t *)(state.map + 8 * 4) =
2805 anv_reloc_list_add(&cmd_buffer->surface_relocs,
2806 cmd_buffer->device,
2807 state.offset + 8 * 4,
2808 view->bo, view->offset);
2809
2810 bt_map[ca] = state.offset;
2811 }
2812
2813 if (layout == NULL)
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002814 return VK_SUCCESS;
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002815
2816 for (uint32_t set = 0; set < layout->num_sets; set++) {
2817 struct anv_descriptor_set_binding *d = &cmd_buffer->descriptors[set];
2818 struct anv_descriptor_set_layout *set_layout = layout->set[set].layout;
2819 struct anv_descriptor_slot *surface_slots =
2820 set_layout->stage[stage].surface_start;
2821
2822 uint32_t start = bias + layout->set[set].surface_start[stage];
2823
2824 for (uint32_t b = 0; b < set_layout->stage[stage].surface_count; b++) {
2825 struct anv_surface_view *view =
2826 d->set->descriptors[surface_slots[b].index].view;
2827
Jason Ekstrand03ffa9c2015-05-29 20:43:10 -07002828 if (!view)
2829 continue;
2830
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002831 struct anv_state state =
2832 anv_cmd_buffer_alloc_surface_state(cmd_buffer, 64, 64);
2833
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002834 if (state.map == NULL)
2835 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
2836
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002837 uint32_t offset;
2838 if (surface_slots[b].dynamic_slot >= 0) {
2839 uint32_t dynamic_offset =
2840 d->dynamic_offsets[surface_slots[b].dynamic_slot];
2841
2842 offset = view->offset + dynamic_offset;
2843 fill_buffer_surface_state(state.map, view->format, offset,
2844 view->range - dynamic_offset);
2845 } else {
2846 offset = view->offset;
2847 memcpy(state.map, view->surface_state.map, 64);
2848 }
2849
2850 /* The address goes in dwords 8 and 9 of the SURFACE_STATE */
2851 *(uint64_t *)(state.map + 8 * 4) =
2852 anv_reloc_list_add(&cmd_buffer->surface_relocs,
2853 cmd_buffer->device,
2854 state.offset + 8 * 4,
2855 view->bo, offset);
2856
2857 bt_map[start + b] = state.offset;
2858 }
2859 }
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002860
2861 return VK_SUCCESS;
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002862}
2863
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002864static VkResult
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07002865cmd_buffer_emit_samplers(struct anv_cmd_buffer *cmd_buffer,
2866 unsigned stage, struct anv_state *state)
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002867{
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07002868 struct anv_pipeline_layout *layout;
2869 uint32_t sampler_count;
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002870
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07002871 if (stage == VK_SHADER_STAGE_COMPUTE)
2872 layout = cmd_buffer->compute_pipeline->layout;
2873 else
2874 layout = cmd_buffer->pipeline->layout;
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002875
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07002876 sampler_count = layout ? layout->stage[stage].sampler_count : 0;
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002877 if (sampler_count == 0)
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002878 return VK_SUCCESS;
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002879
2880 uint32_t size = sampler_count * 16;
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07002881 *state = anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream, size, 32);
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002882
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07002883 if (state->map == NULL)
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002884 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
2885
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002886 for (uint32_t set = 0; set < layout->num_sets; set++) {
2887 struct anv_descriptor_set_binding *d = &cmd_buffer->descriptors[set];
2888 struct anv_descriptor_set_layout *set_layout = layout->set[set].layout;
2889 struct anv_descriptor_slot *sampler_slots =
2890 set_layout->stage[stage].sampler_start;
2891
2892 uint32_t start = layout->set[set].sampler_start[stage];
2893
2894 for (uint32_t b = 0; b < set_layout->stage[stage].sampler_count; b++) {
2895 struct anv_sampler *sampler =
2896 d->set->descriptors[sampler_slots[b].index].sampler;
2897
2898 if (!sampler)
2899 continue;
2900
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07002901 memcpy(state->map + (start + b) * 16,
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002902 sampler->state, sizeof(sampler->state));
2903 }
2904 }
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002905
2906 return VK_SUCCESS;
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002907}
2908
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07002909static VkResult
2910flush_descriptor_set(struct anv_cmd_buffer *cmd_buffer, uint32_t stage)
2911{
2912 struct anv_state surfaces = { 0, }, samplers = { 0, };
2913 VkResult result;
2914
2915 result = cmd_buffer_emit_samplers(cmd_buffer, stage, &samplers);
2916 if (result != VK_SUCCESS)
2917 return result;
2918 result = cmd_buffer_emit_binding_table(cmd_buffer, stage, &surfaces);
2919 if (result != VK_SUCCESS)
2920 return result;
2921
2922 static const uint32_t sampler_state_opcodes[] = {
2923 [VK_SHADER_STAGE_VERTEX] = 43,
2924 [VK_SHADER_STAGE_TESS_CONTROL] = 44, /* HS */
2925 [VK_SHADER_STAGE_TESS_EVALUATION] = 45, /* DS */
2926 [VK_SHADER_STAGE_GEOMETRY] = 46,
2927 [VK_SHADER_STAGE_FRAGMENT] = 47,
2928 [VK_SHADER_STAGE_COMPUTE] = 0,
2929 };
2930
2931 static const uint32_t binding_table_opcodes[] = {
2932 [VK_SHADER_STAGE_VERTEX] = 38,
2933 [VK_SHADER_STAGE_TESS_CONTROL] = 39,
2934 [VK_SHADER_STAGE_TESS_EVALUATION] = 40,
2935 [VK_SHADER_STAGE_GEOMETRY] = 41,
2936 [VK_SHADER_STAGE_FRAGMENT] = 42,
2937 [VK_SHADER_STAGE_COMPUTE] = 0,
2938 };
2939
2940 if (samplers.alloc_size > 0) {
2941 anv_batch_emit(&cmd_buffer->batch,
2942 GEN8_3DSTATE_SAMPLER_STATE_POINTERS_VS,
2943 ._3DCommandSubOpcode = sampler_state_opcodes[stage],
2944 .PointertoVSSamplerState = samplers.offset);
2945 }
2946
2947 if (surfaces.alloc_size > 0) {
2948 anv_batch_emit(&cmd_buffer->batch,
2949 GEN8_3DSTATE_BINDING_TABLE_POINTERS_VS,
2950 ._3DCommandSubOpcode = binding_table_opcodes[stage],
2951 .PointertoVSBindingTable = surfaces.offset);
2952 }
2953
2954 return VK_SUCCESS;
2955}
2956
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002957static void
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002958flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer)
2959{
Jason Ekstrand22513052015-05-30 10:07:29 -07002960 uint32_t s, dirty = cmd_buffer->descriptors_dirty &
2961 cmd_buffer->pipeline->active_stages;
2962
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002963 VkResult result;
Jason Ekstrand22513052015-05-30 10:07:29 -07002964 for_each_bit(s, dirty) {
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07002965 result = flush_descriptor_set(cmd_buffer, s);
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002966 if (result != VK_SUCCESS)
2967 break;
2968 }
2969
2970 if (result != VK_SUCCESS) {
2971 assert(result == VK_ERROR_OUT_OF_DEVICE_MEMORY);
2972
2973 result = anv_cmd_buffer_new_surface_state_bo(cmd_buffer);
2974 assert(result == VK_SUCCESS);
2975
Jason Ekstrand22513052015-05-30 10:07:29 -07002976 /* Re-emit all active binding tables */
2977 for_each_bit(s, cmd_buffer->pipeline->active_stages) {
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07002978 result = flush_descriptor_set(cmd_buffer, s);
Jason Ekstrand4ffbab52015-05-29 09:40:03 -07002979
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07002980 /* It had better succeed this time */
2981 assert(result == VK_SUCCESS);
2982 }
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002983 }
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07002984
Jason Ekstrand22513052015-05-30 10:07:29 -07002985 cmd_buffer->descriptors_dirty &= ~cmd_buffer->pipeline->active_stages;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07002986}
2987
Kristian Høgsbergb29f4422015-05-26 11:22:12 -07002988static struct anv_state
2989anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer *cmd_buffer,
2990 uint32_t *a, uint32_t dwords, uint32_t alignment)
2991{
Kristian Høgsbergb29f4422015-05-26 11:22:12 -07002992 struct anv_state state;
2993
Jason Ekstrandce002332015-06-05 17:14:41 -07002994 state = anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream,
2995 dwords * 4, alignment);
Kristian Høgsbergb29f4422015-05-26 11:22:12 -07002996 memcpy(state.map, a, dwords * 4);
2997
Jason Ekstrand9cae3d12015-06-09 21:36:12 -07002998 VG(VALGRIND_CHECK_MEM_IS_DEFINED(state.map, dwords * 4));
2999
Kristian Høgsbergb29f4422015-05-26 11:22:12 -07003000 return state;
3001}
3002
3003static struct anv_state
3004anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer *cmd_buffer,
Jason Ekstrandce002332015-06-05 17:14:41 -07003005 uint32_t *a, uint32_t *b,
3006 uint32_t dwords, uint32_t alignment)
Kristian Høgsbergb29f4422015-05-26 11:22:12 -07003007{
Kristian Høgsbergb29f4422015-05-26 11:22:12 -07003008 struct anv_state state;
3009 uint32_t *p;
3010
Jason Ekstrandce002332015-06-05 17:14:41 -07003011 state = anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream,
3012 dwords * 4, alignment);
Kristian Høgsbergb29f4422015-05-26 11:22:12 -07003013 p = state.map;
3014 for (uint32_t i = 0; i < dwords; i++)
3015 p[i] = a[i] | b[i];
3016
Jason Ekstrand9cae3d12015-06-09 21:36:12 -07003017 VG(VALGRIND_CHECK_MEM_IS_DEFINED(p, dwords * 4));
3018
Kristian Høgsbergb29f4422015-05-26 11:22:12 -07003019 return state;
3020}
3021
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07003022static VkResult
3023flush_compute_descriptor_set(struct anv_cmd_buffer *cmd_buffer)
3024{
3025 struct anv_device *device = cmd_buffer->device;
3026 struct anv_pipeline *pipeline = cmd_buffer->compute_pipeline;
3027 struct anv_state surfaces = { 0, }, samplers = { 0, };
3028 VkResult result;
3029
3030 result = cmd_buffer_emit_samplers(cmd_buffer,
3031 VK_SHADER_STAGE_COMPUTE, &samplers);
3032 if (result != VK_SUCCESS)
3033 return result;
3034 result = cmd_buffer_emit_binding_table(cmd_buffer,
3035 VK_SHADER_STAGE_COMPUTE, &surfaces);
3036 if (result != VK_SUCCESS)
3037 return result;
3038
3039 struct GEN8_INTERFACE_DESCRIPTOR_DATA desc = {
3040 .KernelStartPointer = pipeline->cs_simd,
3041 .KernelStartPointerHigh = 0,
3042 .BindingTablePointer = surfaces.offset,
3043 .BindingTableEntryCount = 0,
3044 .SamplerStatePointer = samplers.offset,
3045 .SamplerCount = 0,
3046 .NumberofThreadsinGPGPUThreadGroup = 0 /* FIXME: Really? */
3047 };
3048
3049 uint32_t size = GEN8_INTERFACE_DESCRIPTOR_DATA_length * sizeof(uint32_t);
3050 struct anv_state state =
3051 anv_state_pool_alloc(&device->dynamic_state_pool, size, 64);
3052
3053 GEN8_INTERFACE_DESCRIPTOR_DATA_pack(NULL, state.map, &desc);
3054
3055 anv_batch_emit(&cmd_buffer->batch, GEN8_MEDIA_INTERFACE_DESCRIPTOR_LOAD,
3056 .InterfaceDescriptorTotalLength = size,
3057 .InterfaceDescriptorDataStartAddress = state.offset);
3058
3059 return VK_SUCCESS;
3060}
3061
3062static void
3063anv_cmd_buffer_flush_compute_state(struct anv_cmd_buffer *cmd_buffer)
3064{
3065 struct anv_pipeline *pipeline = cmd_buffer->compute_pipeline;
3066 VkResult result;
3067
3068 assert(pipeline->active_stages == VK_SHADER_STAGE_COMPUTE_BIT);
3069
3070 if (cmd_buffer->current_pipeline != GPGPU) {
3071 anv_batch_emit(&cmd_buffer->batch, GEN8_PIPELINE_SELECT,
3072 .PipelineSelection = GPGPU);
3073 cmd_buffer->current_pipeline = GPGPU;
3074 }
3075
3076 if (cmd_buffer->compute_dirty & ANV_CMD_BUFFER_PIPELINE_DIRTY)
3077 anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->batch);
3078
3079 if ((cmd_buffer->descriptors_dirty & VK_SHADER_STAGE_COMPUTE_BIT) ||
3080 (cmd_buffer->compute_dirty & ANV_CMD_BUFFER_PIPELINE_DIRTY)) {
3081 result = flush_compute_descriptor_set(cmd_buffer);
3082 if (result != VK_SUCCESS) {
3083 result = anv_cmd_buffer_new_surface_state_bo(cmd_buffer);
3084 assert(result == VK_SUCCESS);
3085 result = flush_compute_descriptor_set(cmd_buffer);
3086 assert(result == VK_SUCCESS);
3087 }
3088 cmd_buffer->descriptors_dirty &= ~VK_SHADER_STAGE_COMPUTE;
3089 }
3090
3091 cmd_buffer->compute_dirty = 0;
3092}
3093
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003094static void
3095anv_cmd_buffer_flush_state(struct anv_cmd_buffer *cmd_buffer)
3096{
3097 struct anv_pipeline *pipeline = cmd_buffer->pipeline;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003098 uint32_t *p;
3099
Jason Ekstrand0f0b5ae2015-05-21 16:49:55 -07003100 uint32_t vb_emit = cmd_buffer->vb_dirty & pipeline->vb_used;
Jason Ekstrand0f0b5ae2015-05-21 16:49:55 -07003101
Kristian Høgsberg Kristensen7637b022015-06-11 15:21:49 -07003102 assert((pipeline->active_stages & VK_SHADER_STAGE_COMPUTE_BIT) == 0);
3103
3104 if (cmd_buffer->current_pipeline != _3D) {
3105 anv_batch_emit(&cmd_buffer->batch, GEN8_PIPELINE_SELECT,
3106 .PipelineSelection = _3D);
3107 cmd_buffer->current_pipeline = _3D;
3108 }
3109
Jason Ekstrand0f0b5ae2015-05-21 16:49:55 -07003110 if (vb_emit) {
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07003111 const uint32_t num_buffers = __builtin_popcount(vb_emit);
3112 const uint32_t num_dwords = 1 + num_buffers * 4;
3113
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003114 p = anv_batch_emitn(&cmd_buffer->batch, num_dwords,
3115 GEN8_3DSTATE_VERTEX_BUFFERS);
3116 uint32_t vb, i = 0;
Jason Ekstrand0f0b5ae2015-05-21 16:49:55 -07003117 for_each_bit(vb, vb_emit) {
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07003118 struct anv_buffer *buffer = cmd_buffer->vertex_bindings[vb].buffer;
3119 uint32_t offset = cmd_buffer->vertex_bindings[vb].offset;
Jason Ekstrand0f0b5ae2015-05-21 16:49:55 -07003120
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003121 struct GEN8_VERTEX_BUFFER_STATE state = {
3122 .VertexBufferIndex = vb,
Kristian Høgsberg0997a7b2015-05-21 14:35:34 -07003123 .MemoryObjectControlState = GEN8_MOCS,
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003124 .AddressModifyEnable = true,
3125 .BufferPitch = pipeline->binding_stride[vb],
Kristian Høgsberg099faa12015-05-11 22:19:58 -07003126 .BufferStartingAddress = { buffer->bo, buffer->offset + offset },
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003127 .BufferSize = buffer->size - offset
3128 };
3129
3130 GEN8_VERTEX_BUFFER_STATE_pack(&cmd_buffer->batch, &p[1 + i * 4], &state);
3131 i++;
3132 }
3133 }
3134
Kristian Høgsberg Kristensen9b9f9732015-06-19 15:41:30 -07003135 if (cmd_buffer->dirty & ANV_CMD_BUFFER_PIPELINE_DIRTY) {
3136 /* If somebody compiled a pipeline after starting a command buffer the
3137 * scratch bo may have grown since we started this cmd buffer (and
3138 * emitted STATE_BASE_ADDRESS). If we're binding that pipeline now,
3139 * reemit STATE_BASE_ADDRESS so that we use the bigger scratch bo. */
3140 if (cmd_buffer->scratch_size < pipeline->total_scratch)
3141 anv_cmd_buffer_emit_state_base_address(cmd_buffer);
3142
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003143 anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->batch);
Kristian Høgsberg Kristensen9b9f9732015-06-19 15:41:30 -07003144 }
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003145
Jason Ekstrand22513052015-05-30 10:07:29 -07003146 if (cmd_buffer->descriptors_dirty)
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003147 flush_descriptor_sets(cmd_buffer);
3148
Kristian Høgsberg Kristensene7edde62015-06-11 15:04:09 -07003149 if (cmd_buffer->dirty & ANV_CMD_BUFFER_VP_DIRTY) {
3150 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_SCISSOR_STATE_POINTERS,
3151 .ScissorRectPointer = cmd_buffer->vp_state->scissor.offset);
3152 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_CC,
3153 .CCViewportPointer = cmd_buffer->vp_state->cc_vp.offset);
3154 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP,
3155 .SFClipViewportPointer = cmd_buffer->vp_state->sf_clip_vp.offset);
3156 }
3157
Kristian Høgsberg99883772015-05-26 09:40:10 -07003158 if (cmd_buffer->dirty & (ANV_CMD_BUFFER_PIPELINE_DIRTY | ANV_CMD_BUFFER_RS_DIRTY)) {
Kristian Høgsberg55b9b702015-05-11 22:23:38 -07003159 anv_batch_emit_merge(&cmd_buffer->batch,
3160 cmd_buffer->rs_state->state_sf, pipeline->state_sf);
Kristian Høgsberg99883772015-05-26 09:40:10 -07003161 anv_batch_emit_merge(&cmd_buffer->batch,
3162 cmd_buffer->rs_state->state_raster, pipeline->state_raster);
3163 }
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003164
Kristian Høgsbergcbe7ed42015-05-24 21:19:26 -07003165 if (cmd_buffer->ds_state &&
3166 (cmd_buffer->dirty & (ANV_CMD_BUFFER_PIPELINE_DIRTY | ANV_CMD_BUFFER_DS_DIRTY)))
3167 anv_batch_emit_merge(&cmd_buffer->batch,
3168 cmd_buffer->ds_state->state_wm_depth_stencil,
3169 pipeline->state_wm_depth_stencil);
3170
Kristian Høgsbergb29f4422015-05-26 11:22:12 -07003171 if (cmd_buffer->dirty & (ANV_CMD_BUFFER_CB_DIRTY | ANV_CMD_BUFFER_DS_DIRTY)) {
3172 struct anv_state state;
Kristian Høgsberga1d30f82015-05-26 17:12:18 -07003173 if (cmd_buffer->ds_state == NULL)
3174 state = anv_cmd_buffer_emit_dynamic(cmd_buffer,
3175 cmd_buffer->cb_state->state_color_calc,
Jason Ekstrande69588b2015-06-05 17:26:01 -07003176 GEN8_COLOR_CALC_STATE_length, 64);
Kristian Høgsberga1d30f82015-05-26 17:12:18 -07003177 else if (cmd_buffer->cb_state == NULL)
3178 state = anv_cmd_buffer_emit_dynamic(cmd_buffer,
3179 cmd_buffer->ds_state->state_color_calc,
Jason Ekstrande69588b2015-06-05 17:26:01 -07003180 GEN8_COLOR_CALC_STATE_length, 64);
Kristian Høgsberga1d30f82015-05-26 17:12:18 -07003181 else
Kristian Høgsbergb29f4422015-05-26 11:22:12 -07003182 state = anv_cmd_buffer_merge_dynamic(cmd_buffer,
3183 cmd_buffer->ds_state->state_color_calc,
3184 cmd_buffer->cb_state->state_color_calc,
Jason Ekstrande69588b2015-06-05 17:26:01 -07003185 GEN8_COLOR_CALC_STATE_length, 64);
Kristian Høgsbergb29f4422015-05-26 11:22:12 -07003186
3187 anv_batch_emit(&cmd_buffer->batch,
3188 GEN8_3DSTATE_CC_STATE_POINTERS,
3189 .ColorCalcStatePointer = state.offset,
3190 .ColorCalcStatePointerValid = true);
3191 }
3192
Jason Ekstrand7fbed522015-07-07 15:11:56 -07003193 if (cmd_buffer->dirty & (ANV_CMD_BUFFER_PIPELINE_DIRTY | ANV_CMD_BUFFER_INDEX_BUFFER_DIRTY)) {
3194 anv_batch_emit_merge(&cmd_buffer->batch,
3195 cmd_buffer->state_vf, pipeline->state_vf);
3196 }
3197
Jason Ekstrand0f0b5ae2015-05-21 16:49:55 -07003198 cmd_buffer->vb_dirty &= ~vb_emit;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003199 cmd_buffer->dirty = 0;
3200}
3201
Kristian Høgsberg454345d2015-05-17 16:33:48 -07003202void anv_CmdDraw(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003203 VkCmdBuffer cmdBuffer,
3204 uint32_t firstVertex,
3205 uint32_t vertexCount,
3206 uint32_t firstInstance,
3207 uint32_t instanceCount)
3208{
3209 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
3210
3211 anv_cmd_buffer_flush_state(cmd_buffer);
3212
3213 anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
3214 .VertexAccessType = SEQUENTIAL,
3215 .VertexCountPerInstance = vertexCount,
3216 .StartVertexLocation = firstVertex,
3217 .InstanceCount = instanceCount,
3218 .StartInstanceLocation = firstInstance,
3219 .BaseVertexLocation = 0);
3220}
3221
Kristian Høgsberg454345d2015-05-17 16:33:48 -07003222void anv_CmdDrawIndexed(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003223 VkCmdBuffer cmdBuffer,
3224 uint32_t firstIndex,
3225 uint32_t indexCount,
3226 int32_t vertexOffset,
3227 uint32_t firstInstance,
3228 uint32_t instanceCount)
3229{
3230 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
3231
3232 anv_cmd_buffer_flush_state(cmd_buffer);
3233
3234 anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
3235 .VertexAccessType = RANDOM,
3236 .VertexCountPerInstance = indexCount,
3237 .StartVertexLocation = firstIndex,
3238 .InstanceCount = instanceCount,
3239 .StartInstanceLocation = firstInstance,
Kristian Høgsberg Kristensenc8f07852015-06-02 22:35:47 -07003240 .BaseVertexLocation = vertexOffset);
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003241}
3242
3243static void
3244anv_batch_lrm(struct anv_batch *batch,
3245 uint32_t reg, struct anv_bo *bo, uint32_t offset)
3246{
3247 anv_batch_emit(batch, GEN8_MI_LOAD_REGISTER_MEM,
3248 .RegisterAddress = reg,
3249 .MemoryAddress = { bo, offset });
3250}
3251
3252static void
3253anv_batch_lri(struct anv_batch *batch, uint32_t reg, uint32_t imm)
3254{
3255 anv_batch_emit(batch, GEN8_MI_LOAD_REGISTER_IMM,
3256 .RegisterOffset = reg,
3257 .DataDWord = imm);
3258}
3259
3260/* Auto-Draw / Indirect Registers */
3261#define GEN7_3DPRIM_END_OFFSET 0x2420
3262#define GEN7_3DPRIM_START_VERTEX 0x2430
3263#define GEN7_3DPRIM_VERTEX_COUNT 0x2434
3264#define GEN7_3DPRIM_INSTANCE_COUNT 0x2438
3265#define GEN7_3DPRIM_START_INSTANCE 0x243C
3266#define GEN7_3DPRIM_BASE_VERTEX 0x2440
3267
Kristian Høgsberg454345d2015-05-17 16:33:48 -07003268void anv_CmdDrawIndirect(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003269 VkCmdBuffer cmdBuffer,
3270 VkBuffer _buffer,
3271 VkDeviceSize offset,
3272 uint32_t count,
3273 uint32_t stride)
3274{
3275 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
3276 struct anv_buffer *buffer = (struct anv_buffer *) _buffer;
Kristian Høgsberg099faa12015-05-11 22:19:58 -07003277 struct anv_bo *bo = buffer->bo;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003278 uint32_t bo_offset = buffer->offset + offset;
3279
3280 anv_cmd_buffer_flush_state(cmd_buffer);
3281
3282 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
3283 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
3284 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);
3285 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_INSTANCE, bo, bo_offset + 12);
3286 anv_batch_lri(&cmd_buffer->batch, GEN7_3DPRIM_BASE_VERTEX, 0);
3287
3288 anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
3289 .IndirectParameterEnable = true,
3290 .VertexAccessType = SEQUENTIAL);
3291}
3292
Kristian Høgsberg454345d2015-05-17 16:33:48 -07003293void anv_CmdDrawIndexedIndirect(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003294 VkCmdBuffer cmdBuffer,
3295 VkBuffer _buffer,
3296 VkDeviceSize offset,
3297 uint32_t count,
3298 uint32_t stride)
3299{
3300 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
3301 struct anv_buffer *buffer = (struct anv_buffer *) _buffer;
Kristian Høgsberg099faa12015-05-11 22:19:58 -07003302 struct anv_bo *bo = buffer->bo;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003303 uint32_t bo_offset = buffer->offset + offset;
3304
3305 anv_cmd_buffer_flush_state(cmd_buffer);
3306
3307 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
3308 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
3309 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);
3310 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_BASE_VERTEX, bo, bo_offset + 12);
3311 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_INSTANCE, bo, bo_offset + 16);
3312
3313 anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
3314 .IndirectParameterEnable = true,
3315 .VertexAccessType = RANDOM);
3316}
3317
Kristian Høgsberg454345d2015-05-17 16:33:48 -07003318void anv_CmdDispatch(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003319 VkCmdBuffer cmdBuffer,
3320 uint32_t x,
3321 uint32_t y,
3322 uint32_t z)
3323{
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07003324 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
Kristian Høgsberg Kristensenfa8a0772015-06-12 17:21:01 -07003325 struct anv_pipeline *pipeline = cmd_buffer->compute_pipeline;
3326 struct brw_cs_prog_data *prog_data = &pipeline->cs_prog_data;
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07003327
3328 anv_cmd_buffer_flush_compute_state(cmd_buffer);
3329
3330 anv_batch_emit(&cmd_buffer->batch, GEN8_GPGPU_WALKER,
Kristian Høgsberg Kristensenfa8a0772015-06-12 17:21:01 -07003331 .SIMDSize = prog_data->simd_size / 16,
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07003332 .ThreadDepthCounterMaximum = 0,
3333 .ThreadHeightCounterMaximum = 0,
Kristian Høgsberg Kristensenfa8a0772015-06-12 17:21:01 -07003334 .ThreadWidthCounterMaximum = pipeline->cs_thread_width_max,
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07003335 .ThreadGroupIDXDimension = x,
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07003336 .ThreadGroupIDYDimension = y,
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07003337 .ThreadGroupIDZDimension = z,
Kristian Høgsberg Kristensenfa8a0772015-06-12 17:21:01 -07003338 .RightExecutionMask = pipeline->cs_right_mask,
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07003339 .BottomExecutionMask = 0xffffffff);
3340
3341 anv_batch_emit(&cmd_buffer->batch, GEN8_MEDIA_STATE_FLUSH);
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003342}
3343
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07003344#define GPGPU_DISPATCHDIMX 0x2500
3345#define GPGPU_DISPATCHDIMY 0x2504
3346#define GPGPU_DISPATCHDIMZ 0x2508
3347
Kristian Høgsberg454345d2015-05-17 16:33:48 -07003348void anv_CmdDispatchIndirect(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003349 VkCmdBuffer cmdBuffer,
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07003350 VkBuffer _buffer,
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003351 VkDeviceSize offset)
3352{
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07003353 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
Kristian Høgsberg Kristensenfa8a0772015-06-12 17:21:01 -07003354 struct anv_pipeline *pipeline = cmd_buffer->compute_pipeline;
3355 struct brw_cs_prog_data *prog_data = &pipeline->cs_prog_data;
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07003356 struct anv_buffer *buffer = (struct anv_buffer *) _buffer;
3357 struct anv_bo *bo = buffer->bo;
3358 uint32_t bo_offset = buffer->offset + offset;
3359
3360 anv_cmd_buffer_flush_compute_state(cmd_buffer);
3361
3362 anv_batch_lrm(&cmd_buffer->batch, GPGPU_DISPATCHDIMX, bo, bo_offset);
3363 anv_batch_lrm(&cmd_buffer->batch, GPGPU_DISPATCHDIMY, bo, bo_offset + 4);
3364 anv_batch_lrm(&cmd_buffer->batch, GPGPU_DISPATCHDIMZ, bo, bo_offset + 8);
3365
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07003366 anv_batch_emit(&cmd_buffer->batch, GEN8_GPGPU_WALKER,
3367 .IndirectParameterEnable = true,
Kristian Høgsberg Kristensenfa8a0772015-06-12 17:21:01 -07003368 .SIMDSize = prog_data->simd_size / 16,
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07003369 .ThreadDepthCounterMaximum = 0,
3370 .ThreadHeightCounterMaximum = 0,
Kristian Høgsberg Kristensenfa8a0772015-06-12 17:21:01 -07003371 .ThreadWidthCounterMaximum = pipeline->cs_thread_width_max,
3372 .RightExecutionMask = pipeline->cs_right_mask,
Kristian Høgsberg Kristensen765175f2015-06-11 15:31:42 -07003373 .BottomExecutionMask = 0xffffffff);
3374
3375 anv_batch_emit(&cmd_buffer->batch, GEN8_MEDIA_STATE_FLUSH);
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003376}
3377
Kristian Høgsberg454345d2015-05-17 16:33:48 -07003378void anv_CmdSetEvent(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003379 VkCmdBuffer cmdBuffer,
3380 VkEvent event,
3381 VkPipeEvent pipeEvent)
3382{
Jason Ekstrandffe9f602015-05-12 13:44:43 -07003383 stub();
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003384}
3385
Kristian Høgsberg454345d2015-05-17 16:33:48 -07003386void anv_CmdResetEvent(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003387 VkCmdBuffer cmdBuffer,
3388 VkEvent event,
3389 VkPipeEvent pipeEvent)
3390{
Jason Ekstrandffe9f602015-05-12 13:44:43 -07003391 stub();
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003392}
3393
Kristian Høgsberg454345d2015-05-17 16:33:48 -07003394void anv_CmdWaitEvents(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003395 VkCmdBuffer cmdBuffer,
3396 VkWaitEvent waitEvent,
3397 uint32_t eventCount,
3398 const VkEvent* pEvents,
Chad Versace85c0d692015-07-07 15:49:57 -07003399 VkPipeEventFlags pipeEventMask,
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003400 uint32_t memBarrierCount,
Chad Versace85c0d692015-07-07 15:49:57 -07003401 const void* const* ppMemBarriers)
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003402{
Jason Ekstrandffe9f602015-05-12 13:44:43 -07003403 stub();
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003404}
3405
Kristian Høgsberg454345d2015-05-17 16:33:48 -07003406void anv_CmdPipelineBarrier(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003407 VkCmdBuffer cmdBuffer,
3408 VkWaitEvent waitEvent,
Chad Versace18ee32e2015-07-07 15:42:38 -07003409 VkPipeEventFlags pipeEventMask,
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003410 uint32_t memBarrierCount,
Chad Versace18ee32e2015-07-07 15:42:38 -07003411 const void* const* ppMemBarriers)
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003412{
Jason Ekstrand29d2bbb2015-06-10 16:37:31 -07003413 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *)cmdBuffer;
3414 uint32_t b, *dw;
3415
3416 struct GEN8_PIPE_CONTROL cmd = {
3417 GEN8_PIPE_CONTROL_header,
3418 .PostSyncOperation = NoWrite,
3419 };
3420
3421 /* XXX: I think waitEvent is a no-op on our HW. We should verify that. */
3422
Chad Versace18ee32e2015-07-07 15:42:38 -07003423 if (anv_clear_mask(&pipeEventMask, VK_PIPE_EVENT_TOP_OF_PIPE_BIT)) {
3424 /* This is just what PIPE_CONTROL does */
Jason Ekstrand29d2bbb2015-06-10 16:37:31 -07003425 }
3426
Chad Versace18ee32e2015-07-07 15:42:38 -07003427 if (anv_clear_mask(&pipeEventMask,
3428 VK_PIPE_EVENT_VERTEX_PROCESSING_COMPLETE_BIT |
3429 VK_PIPE_EVENT_LOCAL_FRAGMENT_PROCESSING_COMPLETE_BIT |
3430 VK_PIPE_EVENT_FRAGMENT_PROCESSING_COMPLETE_BIT)) {
3431 cmd.StallAtPixelScoreboard = true;
3432 }
3433
3434
3435 if (anv_clear_mask(&pipeEventMask,
3436 VK_PIPE_EVENT_GRAPHICS_PIPELINE_COMPLETE_BIT |
3437 VK_PIPE_EVENT_COMPUTE_PIPELINE_COMPLETE_BIT |
3438 VK_PIPE_EVENT_TRANSFER_COMPLETE_BIT |
3439 VK_PIPE_EVENT_COMMANDS_COMPLETE_BIT)) {
3440 cmd.CommandStreamerStallEnable = true;
3441 }
3442
3443 if (anv_clear_mask(&pipeEventMask, VK_PIPE_EVENT_CPU_SIGNAL_BIT)) {
3444 anv_finishme("VK_PIPE_EVENT_CPU_SIGNAL_BIT");
3445 }
3446
3447 /* We checked all known VkPipeEventFlags. */
3448 anv_assert(pipeEventMask == 0);
3449
Jason Ekstrand29d2bbb2015-06-10 16:37:31 -07003450 /* XXX: Right now, we're really dumb and just flush whatever categories
3451 * the app asks for. One of these days we may make this a bit better
3452 * but right now that's all the hardware allows for in most areas.
3453 */
3454 VkMemoryOutputFlags out_flags = 0;
3455 VkMemoryInputFlags in_flags = 0;
3456
3457 for (uint32_t i = 0; i < memBarrierCount; i++) {
3458 const struct anv_common *common = ppMemBarriers[i];
3459 switch (common->sType) {
3460 case VK_STRUCTURE_TYPE_MEMORY_BARRIER: {
3461 const VkMemoryBarrier *barrier = (VkMemoryBarrier *)common;
3462 out_flags |= barrier->outputMask;
3463 in_flags |= barrier->inputMask;
3464 break;
3465 }
3466 case VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER: {
3467 const VkBufferMemoryBarrier *barrier = (VkBufferMemoryBarrier *)common;
3468 out_flags |= barrier->outputMask;
3469 in_flags |= barrier->inputMask;
3470 break;
3471 }
3472 case VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER: {
3473 const VkImageMemoryBarrier *barrier = (VkImageMemoryBarrier *)common;
3474 out_flags |= barrier->outputMask;
3475 in_flags |= barrier->inputMask;
3476 break;
3477 }
3478 default:
3479 unreachable("Invalid memory barrier type");
3480 }
3481 }
3482
3483 for_each_bit(b, out_flags) {
3484 switch ((VkMemoryOutputFlags)(1 << b)) {
Jason Ekstrand2b404e52015-07-06 17:18:25 -07003485 case VK_MEMORY_OUTPUT_HOST_WRITE_BIT:
Jason Ekstrand29d2bbb2015-06-10 16:37:31 -07003486 break; /* FIXME: Little-core systems */
3487 case VK_MEMORY_OUTPUT_SHADER_WRITE_BIT:
3488 cmd.DCFlushEnable = true;
3489 break;
3490 case VK_MEMORY_OUTPUT_COLOR_ATTACHMENT_BIT:
3491 cmd.RenderTargetCacheFlushEnable = true;
3492 break;
3493 case VK_MEMORY_OUTPUT_DEPTH_STENCIL_ATTACHMENT_BIT:
3494 cmd.DepthCacheFlushEnable = true;
3495 break;
3496 case VK_MEMORY_OUTPUT_TRANSFER_BIT:
3497 cmd.RenderTargetCacheFlushEnable = true;
3498 cmd.DepthCacheFlushEnable = true;
3499 break;
3500 default:
3501 unreachable("Invalid memory output flag");
3502 }
3503 }
3504
3505 for_each_bit(b, out_flags) {
3506 switch ((VkMemoryInputFlags)(1 << b)) {
Jason Ekstrand2b404e52015-07-06 17:18:25 -07003507 case VK_MEMORY_INPUT_HOST_READ_BIT:
Jason Ekstrand29d2bbb2015-06-10 16:37:31 -07003508 break; /* FIXME: Little-core systems */
3509 case VK_MEMORY_INPUT_INDIRECT_COMMAND_BIT:
3510 case VK_MEMORY_INPUT_INDEX_FETCH_BIT:
3511 case VK_MEMORY_INPUT_VERTEX_ATTRIBUTE_FETCH_BIT:
3512 cmd.VFCacheInvalidationEnable = true;
3513 break;
3514 case VK_MEMORY_INPUT_UNIFORM_READ_BIT:
3515 cmd.ConstantCacheInvalidationEnable = true;
3516 /* fallthrough */
3517 case VK_MEMORY_INPUT_SHADER_READ_BIT:
3518 cmd.DCFlushEnable = true;
3519 cmd.TextureCacheInvalidationEnable = true;
3520 break;
3521 case VK_MEMORY_INPUT_COLOR_ATTACHMENT_BIT:
3522 case VK_MEMORY_INPUT_DEPTH_STENCIL_ATTACHMENT_BIT:
3523 break; /* XXX: Hunh? */
3524 case VK_MEMORY_INPUT_TRANSFER_BIT:
3525 cmd.TextureCacheInvalidationEnable = true;
3526 break;
3527 }
3528 }
3529
3530 dw = anv_batch_emit_dwords(&cmd_buffer->batch, GEN8_PIPE_CONTROL_length);
3531 GEN8_PIPE_CONTROL_pack(&cmd_buffer->batch, dw, &cmd);
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003532}
3533
Jason Ekstrand57153da2015-05-22 15:15:08 -07003534static void
3535anv_framebuffer_destroy(struct anv_device *device,
3536 struct anv_object *object,
3537 VkObjectType obj_type)
3538{
3539 struct anv_framebuffer *fb = (struct anv_framebuffer *)object;
3540
3541 assert(obj_type == VK_OBJECT_TYPE_FRAMEBUFFER);
3542
3543 anv_DestroyObject((VkDevice) device,
3544 VK_OBJECT_TYPE_DYNAMIC_VP_STATE,
3545 fb->vp_state);
3546
3547 anv_device_free(device, fb);
3548}
3549
Kristian Høgsberg454345d2015-05-17 16:33:48 -07003550VkResult anv_CreateFramebuffer(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003551 VkDevice _device,
3552 const VkFramebufferCreateInfo* pCreateInfo,
3553 VkFramebuffer* pFramebuffer)
3554{
3555 struct anv_device *device = (struct anv_device *) _device;
3556 struct anv_framebuffer *framebuffer;
3557
Kristian Høgsberg37743f92015-05-22 22:59:12 -07003558 static const struct anv_depth_stencil_view null_view =
3559 { .depth_format = D16_UNORM, .depth_stride = 0, .stencil_stride = 0 };
3560
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003561 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO);
3562
3563 framebuffer = anv_device_alloc(device, sizeof(*framebuffer), 8,
3564 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
3565 if (framebuffer == NULL)
3566 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
3567
Jason Ekstrand57153da2015-05-22 15:15:08 -07003568 framebuffer->base.destructor = anv_framebuffer_destroy;
3569
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003570 framebuffer->color_attachment_count = pCreateInfo->colorAttachmentCount;
3571 for (uint32_t i = 0; i < pCreateInfo->colorAttachmentCount; i++) {
3572 framebuffer->color_attachments[i] =
Kristian Høgsbergf5b0f132015-05-13 15:31:26 -07003573 (struct anv_surface_view *) pCreateInfo->pColorAttachments[i].view;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003574 }
3575
3576 if (pCreateInfo->pDepthStencilAttachment) {
3577 framebuffer->depth_stencil =
3578 (struct anv_depth_stencil_view *) pCreateInfo->pDepthStencilAttachment->view;
Kristian Høgsberg37743f92015-05-22 22:59:12 -07003579 } else {
3580 framebuffer->depth_stencil = &null_view;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003581 }
3582
3583 framebuffer->sample_count = pCreateInfo->sampleCount;
3584 framebuffer->width = pCreateInfo->width;
3585 framebuffer->height = pCreateInfo->height;
3586 framebuffer->layers = pCreateInfo->layers;
3587
Jason Ekstrand919e7b72015-06-09 16:01:56 -07003588 anv_CreateDynamicViewportState((VkDevice) device,
Jason Ekstrand0599d392015-06-09 15:53:10 -07003589 &(VkDynamicVpStateCreateInfo) {
3590 .sType = VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO,
3591 .viewportAndScissorCount = 1,
3592 .pViewports = (VkViewport[]) {
3593 {
3594 .originX = 0,
3595 .originY = 0,
3596 .width = pCreateInfo->width,
3597 .height = pCreateInfo->height,
3598 .minDepth = 0,
3599 .maxDepth = 1
3600 },
3601 },
Jason Ekstrand1f1b26b2015-07-06 17:47:18 -07003602 .pScissors = (VkRect2D[]) {
Jason Ekstrand0599d392015-06-09 15:53:10 -07003603 { { 0, 0 },
3604 { pCreateInfo->width, pCreateInfo->height } },
3605 }
3606 },
3607 &framebuffer->vp_state);
Kristian Høgsbergd77c34d2015-05-11 23:25:06 -07003608
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003609 *pFramebuffer = (VkFramebuffer) framebuffer;
3610
3611 return VK_SUCCESS;
3612}
3613
Kristian Høgsberg454345d2015-05-17 16:33:48 -07003614VkResult anv_CreateRenderPass(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003615 VkDevice _device,
3616 const VkRenderPassCreateInfo* pCreateInfo,
3617 VkRenderPass* pRenderPass)
3618{
3619 struct anv_device *device = (struct anv_device *) _device;
3620 struct anv_render_pass *pass;
Kristian Høgsbergd77c34d2015-05-11 23:25:06 -07003621 size_t size;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003622
3623 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO);
3624
Kristian Høgsbergd77c34d2015-05-11 23:25:06 -07003625 size = sizeof(*pass) +
3626 pCreateInfo->layers * sizeof(struct anv_render_pass_layer);
3627 pass = anv_device_alloc(device, size, 8,
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003628 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
3629 if (pass == NULL)
3630 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
3631
3632 pass->render_area = pCreateInfo->renderArea;
3633
Kristian Høgsbergd77c34d2015-05-11 23:25:06 -07003634 pass->num_layers = pCreateInfo->layers;
3635
3636 pass->num_clear_layers = 0;
3637 for (uint32_t i = 0; i < pCreateInfo->layers; i++) {
3638 pass->layers[i].color_load_op = pCreateInfo->pColorLoadOps[i];
3639 pass->layers[i].clear_color = pCreateInfo->pColorLoadClearValues[i];
3640 if (pass->layers[i].color_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
3641 pass->num_clear_layers++;
3642 }
3643
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003644 *pRenderPass = (VkRenderPass) pass;
3645
3646 return VK_SUCCESS;
3647}
3648
Kristian Høgsberg37743f92015-05-22 22:59:12 -07003649static void
3650anv_cmd_buffer_emit_depth_stencil(struct anv_cmd_buffer *cmd_buffer,
3651 struct anv_render_pass *pass)
3652{
3653 const struct anv_depth_stencil_view *view =
3654 cmd_buffer->framebuffer->depth_stencil;
3655
3656 /* FIXME: Implement the PMA stall W/A */
Chad Versace709fa462015-06-26 22:15:03 -07003657 /* FIXME: Width and Height are wrong */
Kristian Høgsberg37743f92015-05-22 22:59:12 -07003658
3659 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DEPTH_BUFFER,
3660 .SurfaceType = SURFTYPE_2D,
3661 .DepthWriteEnable = view->depth_stride > 0,
3662 .StencilWriteEnable = view->stencil_stride > 0,
3663 .HierarchicalDepthBufferEnable = false,
3664 .SurfaceFormat = view->depth_format,
3665 .SurfacePitch = view->depth_stride > 0 ? view->depth_stride - 1 : 0,
3666 .SurfaceBaseAddress = { view->bo, view->depth_offset },
3667 .Height = pass->render_area.extent.height - 1,
3668 .Width = pass->render_area.extent.width - 1,
3669 .LOD = 0,
3670 .Depth = 1 - 1,
3671 .MinimumArrayElement = 0,
3672 .DepthBufferObjectControlState = GEN8_MOCS,
3673 .RenderTargetViewExtent = 1 - 1,
Chad Versace7ea707a2015-06-25 19:46:42 -07003674 .SurfaceQPitch = view->depth_qpitch >> 2);
Kristian Høgsberg37743f92015-05-22 22:59:12 -07003675
3676 /* Disable hierarchial depth buffers. */
3677 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_HIER_DEPTH_BUFFER);
3678
3679 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_STENCIL_BUFFER,
3680 .StencilBufferEnable = view->stencil_stride > 0,
3681 .StencilBufferObjectControlState = GEN8_MOCS,
3682 .SurfacePitch = view->stencil_stride > 0 ? view->stencil_stride - 1 : 0,
3683 .SurfaceBaseAddress = { view->bo, view->stencil_offset },
Chad Versace7ea707a2015-06-25 19:46:42 -07003684 .SurfaceQPitch = view->stencil_qpitch >> 2);
Kristian Høgsberg37743f92015-05-22 22:59:12 -07003685
3686 /* Clear the clear params. */
3687 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_CLEAR_PARAMS);
3688}
3689
Chad Versacef78d6842015-07-07 15:46:19 -07003690void anv_CmdPushConstants(
3691 VkCmdBuffer cmdBuffer,
3692 VkPipelineLayout layout,
3693 VkShaderStageFlags stageFlags,
3694 uint32_t start,
3695 uint32_t length,
3696 const void* values)
3697{
3698 stub();
3699}
3700
Kristian Høgsberg454345d2015-05-17 16:33:48 -07003701void anv_CmdBeginRenderPass(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003702 VkCmdBuffer cmdBuffer,
3703 const VkRenderPassBegin* pRenderPassBegin)
3704{
3705 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
3706 struct anv_render_pass *pass = (struct anv_render_pass *) pRenderPassBegin->renderPass;
Kristian Høgsbergbf096c92015-05-15 15:03:21 -07003707 struct anv_framebuffer *framebuffer =
3708 (struct anv_framebuffer *) pRenderPassBegin->framebuffer;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003709
Kristian Høgsbergbf096c92015-05-15 15:03:21 -07003710 cmd_buffer->framebuffer = framebuffer;
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003711
Jason Ekstrand22513052015-05-30 10:07:29 -07003712 cmd_buffer->descriptors_dirty |= VK_SHADER_STAGE_FRAGMENT_BIT;
Jason Ekstrandc4bd5f82015-05-29 15:16:58 -07003713
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003714 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DRAWING_RECTANGLE,
3715 .ClippedDrawingRectangleYMin = pass->render_area.offset.y,
3716 .ClippedDrawingRectangleXMin = pass->render_area.offset.x,
3717 .ClippedDrawingRectangleYMax =
3718 pass->render_area.offset.y + pass->render_area.extent.height - 1,
3719 .ClippedDrawingRectangleXMax =
3720 pass->render_area.offset.x + pass->render_area.extent.width - 1,
3721 .DrawingRectangleOriginY = 0,
3722 .DrawingRectangleOriginX = 0);
Kristian Høgsbergd77c34d2015-05-11 23:25:06 -07003723
Kristian Høgsberg37743f92015-05-22 22:59:12 -07003724 anv_cmd_buffer_emit_depth_stencil(cmd_buffer, pass);
3725
Kristian Høgsbergd77c34d2015-05-11 23:25:06 -07003726 anv_cmd_buffer_clear(cmd_buffer, pass);
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003727}
3728
Kristian Høgsberg454345d2015-05-17 16:33:48 -07003729void anv_CmdEndRenderPass(
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003730 VkCmdBuffer cmdBuffer,
3731 VkRenderPass renderPass)
3732{
Jason Ekstranda1309c52015-05-13 22:13:05 -07003733 /* Emit a flushing pipe control at the end of a pass. This is kind of a
3734 * hack but it ensures that render targets always actually get written.
3735 * Eventually, we should do flushing based on image format transitions
3736 * or something of that nature.
3737 */
3738 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *)cmdBuffer;
3739 anv_batch_emit(&cmd_buffer->batch, GEN8_PIPE_CONTROL,
3740 .PostSyncOperation = NoWrite,
3741 .RenderTargetCacheFlushEnable = true,
3742 .InstructionCacheInvalidateEnable = true,
3743 .DepthCacheFlushEnable = true,
3744 .VFCacheInvalidationEnable = true,
3745 .TextureCacheInvalidationEnable = true,
3746 .CommandStreamerStallEnable = true);
Kristian Høgsberg769785c2015-05-08 22:32:37 -07003747}
Kristian Høgsbergf8866472015-05-15 22:04:15 -07003748
3749void vkCmdDbgMarkerBegin(
3750 VkCmdBuffer cmdBuffer,
3751 const char* pMarker)
3752 __attribute__ ((visibility ("default")));
3753
3754void vkCmdDbgMarkerEnd(
3755 VkCmdBuffer cmdBuffer)
3756 __attribute__ ((visibility ("default")));
3757
3758VkResult vkDbgSetObjectTag(
3759 VkDevice device,
3760 VkObject object,
3761 size_t tagSize,
3762 const void* pTag)
3763 __attribute__ ((visibility ("default")));
3764
3765
3766void vkCmdDbgMarkerBegin(
3767 VkCmdBuffer cmdBuffer,
3768 const char* pMarker)
3769{
3770}
3771
3772void vkCmdDbgMarkerEnd(
3773 VkCmdBuffer cmdBuffer)
3774{
3775}
3776
3777VkResult vkDbgSetObjectTag(
3778 VkDevice device,
3779 VkObject object,
3780 size_t tagSize,
3781 const void* pTag)
3782{
3783 return VK_SUCCESS;
3784}