diff options
-rw-r--r-- | src/vulkan/Makefile.am | 1 | ||||
-rw-r--r-- | src/vulkan/anv_aub.c | 293 | ||||
-rw-r--r-- | src/vulkan/anv_device.c | 92 | ||||
-rw-r--r-- | src/vulkan/anv_private.h | 10 |
4 files changed, 19 insertions, 377 deletions
diff --git a/src/vulkan/Makefile.am b/src/vulkan/Makefile.am index aeebca4b9f5..10179364bf8 100644 --- a/src/vulkan/Makefile.am +++ b/src/vulkan/Makefile.am @@ -58,7 +58,6 @@ libvulkan_la_CXXFLAGS = \ VULKAN_SOURCES = \ anv_allocator.c \ - anv_aub.c \ anv_cmd_buffer.c \ anv_batch_chain.c \ anv_compiler.cpp \ diff --git a/src/vulkan/anv_aub.c b/src/vulkan/anv_aub.c deleted file mode 100644 index e4a35873590..00000000000 --- a/src/vulkan/anv_aub.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright © 2015 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <stdint.h> -#include <string.h> -#include <unistd.h> -#include <assert.h> -#include <sys/types.h> -#include <sys/mman.h> - -#include <drm.h> -#include <i915_drm.h> - -#include "anv_private.h" -#include "anv_aub.h" - -struct anv_aub_writer { - FILE *file; - uint32_t offset; - int gen; -}; - -static void -aub_out(struct anv_aub_writer *writer, uint32_t data) -{ - fwrite(&data, 1, 4, writer->file); -} - -static void -aub_out_data(struct anv_aub_writer *writer, const void *data, size_t size) -{ - fwrite(data, 1, size, writer->file); -} - -static struct anv_aub_writer * -get_anv_aub_writer(struct anv_device *device) -{ - struct anv_aub_writer *writer = device->aub_writer; - int entry = 0x200003; - int i; - int gtt_size = 0x10000; - const char *filename; - - if (geteuid() != getuid()) - return NULL; - - if (writer) - return writer; - - writer = malloc(sizeof(*writer)); - if (writer == NULL) - return NULL; - - filename = "intel.aub"; - writer->gen = device->info.gen; - writer->file = fopen(filename, "w+"); - if (!writer->file) { - free(writer); - return NULL; - } - - /* Start allocating objects from just after the GTT. */ - writer->offset = gtt_size; - - /* Start with a (required) version packet. */ - aub_out(writer, CMD_AUB_HEADER | (13 - 2)); - aub_out(writer, - (4 << AUB_HEADER_MAJOR_SHIFT) | - (0 << AUB_HEADER_MINOR_SHIFT)); - for (i = 0; i < 8; i++) { - aub_out(writer, 0); /* app name */ - } - aub_out(writer, 0); /* timestamp */ - aub_out(writer, 0); /* timestamp */ - aub_out(writer, 0); /* comment len */ - - /* Set up the GTT. The max we can handle is 256M */ - aub_out(writer, CMD_AUB_TRACE_HEADER_BLOCK | ((writer->gen >= 8 ? 6 : 5) - 2)); - aub_out(writer, - AUB_TRACE_MEMTYPE_GTT_ENTRY | - AUB_TRACE_TYPE_NOTYPE | AUB_TRACE_OP_DATA_WRITE); - aub_out(writer, 0); /* subtype */ - aub_out(writer, 0); /* offset */ - aub_out(writer, gtt_size); /* size */ - if (writer->gen >= 8) - aub_out(writer, 0); - for (i = 0x000; i < gtt_size; i += 4, entry += 0x1000) { - aub_out(writer, entry); - } - - return device->aub_writer = writer; -} - -void -anv_aub_writer_destroy(struct anv_aub_writer *writer) -{ - fclose(writer->file); - free(writer); -} - - -/** - * Break up large objects into multiple writes. Otherwise a 128kb VBO - * would overflow the 16 bits of size field in the packet header and - * everything goes badly after that. - */ -static void -aub_write_trace_block(struct anv_aub_writer *writer, uint32_t type, - void *virtual, uint32_t size, uint32_t gtt_offset) -{ - uint32_t block_size; - uint32_t offset; - uint32_t subtype = 0; - static const char null_block[8 * 4096]; - - for (offset = 0; offset < size; offset += block_size) { - block_size = size - offset; - - if (block_size > 8 * 4096) - block_size = 8 * 4096; - - aub_out(writer, - CMD_AUB_TRACE_HEADER_BLOCK | - ((writer->gen >= 8 ? 6 : 5) - 2)); - aub_out(writer, - AUB_TRACE_MEMTYPE_GTT | - type | AUB_TRACE_OP_DATA_WRITE); - aub_out(writer, subtype); - aub_out(writer, gtt_offset + offset); - aub_out(writer, align_u32(block_size, 4)); - if (writer->gen >= 8) - aub_out(writer, 0); - - if (virtual) - aub_out_data(writer, (char *) virtual + offset, block_size); - else - aub_out_data(writer, null_block, block_size); - - /* Pad to a multiple of 4 bytes. */ - aub_out_data(writer, null_block, -block_size & 3); - } -} - -/* - * Make a ringbuffer on fly and dump it - */ -static void -aub_build_dump_ringbuffer(struct anv_aub_writer *writer, - uint32_t batch_offset, uint32_t offset, - int ring_flag) -{ - uint32_t ringbuffer[4096]; - int ring = AUB_TRACE_TYPE_RING_PRB0; /* The default ring */ - int ring_count = 0; - - if (ring_flag == I915_EXEC_BSD) - ring = AUB_TRACE_TYPE_RING_PRB1; - else if (ring_flag == I915_EXEC_BLT) - ring = AUB_TRACE_TYPE_RING_PRB2; - - /* Make a ring buffer to execute our batchbuffer. */ - memset(ringbuffer, 0, sizeof(ringbuffer)); - if (writer->gen >= 8) { - ringbuffer[ring_count++] = AUB_MI_BATCH_BUFFER_START | (3 - 2); - ringbuffer[ring_count++] = batch_offset; - ringbuffer[ring_count++] = 0; - } else { - ringbuffer[ring_count++] = AUB_MI_BATCH_BUFFER_START; - ringbuffer[ring_count++] = batch_offset; - } - - /* Write out the ring. This appears to trigger execution of - * the ring in the simulator. - */ - aub_out(writer, - CMD_AUB_TRACE_HEADER_BLOCK | - ((writer->gen >= 8 ? 6 : 5) - 2)); - aub_out(writer, - AUB_TRACE_MEMTYPE_GTT | ring | AUB_TRACE_OP_COMMAND_WRITE); - aub_out(writer, 0); /* general/surface subtype */ - aub_out(writer, offset); - aub_out(writer, ring_count * 4); - if (writer->gen >= 8) - aub_out(writer, 0); - - /* FIXME: Need some flush operations here? */ - aub_out_data(writer, ringbuffer, ring_count * 4); -} - -struct aub_bo { - uint32_t size; - uint32_t offset; - void *map; - void *relocated; -}; - -static void -relocate_bo(struct aub_bo *aub_bo, - const struct drm_i915_gem_exec_object2 *gem_obj, - struct aub_bo *aub_bos) -{ - const struct drm_i915_gem_relocation_entry *relocs = - (const struct drm_i915_gem_relocation_entry *) gem_obj->relocs_ptr; - uint32_t *dw; - - aub_bo->relocated = malloc(aub_bo->size); - memcpy(aub_bo->relocated, aub_bo->map, aub_bo->size); - for (size_t i = 0; i < gem_obj->relocation_count; i++) { - assert(relocs[i].offset < aub_bo->size); - dw = aub_bo->relocated + relocs[i].offset; - *dw = aub_bos[relocs[i].target_handle].offset + relocs[i].delta; - } -} - -void -anv_cmd_buffer_dump(struct anv_cmd_buffer *cmd_buffer) -{ - struct anv_device *device = cmd_buffer->device; - struct anv_aub_writer *writer; - struct anv_bo *bo; - uint32_t ring_flag = 0; - uint32_t offset; - struct aub_bo *aub_bos; - - writer = get_anv_aub_writer(device); - if (writer == NULL) - return; - - aub_bos = malloc(cmd_buffer->execbuf2.bo_count * sizeof(aub_bos[0])); - offset = writer->offset; - for (uint32_t i = 0; i < cmd_buffer->execbuf2.bo_count; i++) { - bo = cmd_buffer->execbuf2.bos[i]; - if (bo->map) - aub_bos[i].map = bo->map; - else - aub_bos[i].map = anv_gem_mmap(device, bo->gem_handle, 0, bo->size); - aub_bos[i].size = bo->size; - aub_bos[i].relocated = aub_bos[i].map; - aub_bos[i].offset = offset; - offset = align_u32(offset + bo->size + 4095, 4096); - } - - for (uint32_t i = 0; i < cmd_buffer->execbuf2.bo_count; i++) - relocate_bo(&aub_bos[i], &cmd_buffer->execbuf2.objects[i], aub_bos); - - struct aub_bo *batch_bo = &aub_bos[cmd_buffer->execbuf2.bo_count - 1]; - - for (uint32_t i = 0; i < cmd_buffer->execbuf2.bo_count; i++) { - bo = cmd_buffer->execbuf2.bos[i]; - if (&aub_bos[i] == batch_bo) { - aub_write_trace_block(writer, AUB_TRACE_TYPE_BATCH, - aub_bos[i].relocated, - bo->size, aub_bos[i].offset); - } else { - aub_write_trace_block(writer, AUB_TRACE_TYPE_NOTYPE, - aub_bos[i].relocated, - bo->size, aub_bos[i].offset); - } - if (aub_bos[i].relocated != aub_bos[i].map) - free(aub_bos[i].relocated); - if (aub_bos[i].map != bo->map) - anv_gem_munmap(aub_bos[i].map, bo->size); - } - - /* Dump ring buffer */ - aub_build_dump_ringbuffer(writer, batch_bo->offset, offset, ring_flag); - - free(aub_bos); - - fflush(writer->file); -} diff --git a/src/vulkan/anv_device.c b/src/vulkan/anv_device.c index 76381e615d3..0653f8bab16 100644 --- a/src/vulkan/anv_device.c +++ b/src/vulkan/anv_device.c @@ -31,17 +31,6 @@ #include "mesa/main/git_sha1.h" #include "util/strtod.h" -static int -anv_env_get_int(const char *name) -{ - const char *val = getenv(name); - - if (!val) - return 0; - - return strtol(val, NULL, 0); -} - static VkResult anv_physical_device_init(struct anv_physical_device *device, struct anv_instance *instance, @@ -56,14 +45,7 @@ anv_physical_device_init(struct anv_physical_device *device, device->instance = instance; device->path = path; - device->chipset_id = anv_env_get_int("INTEL_DEVID_OVERRIDE"); - device->no_hw = false; - if (device->chipset_id) { - /* INTEL_DEVID_OVERRIDE implies INTEL_NO_HW. */ - device->no_hw = true; - } else { - device->chipset_id = anv_gem_get_param(fd, I915_PARAM_CHIPSET_ID); - } + device->chipset_id = anv_gem_get_param(fd, I915_PARAM_CHIPSET_ID); if (!device->chipset_id) goto fail; @@ -494,26 +476,6 @@ PFN_vkVoidFunction anv_GetDeviceProcAddr( return anv_lookup_entrypoint(pName); } -static void -parse_debug_flags(struct anv_device *device) -{ - const char *debug, *p, *end; - - debug = getenv("INTEL_DEBUG"); - device->dump_aub = false; - if (debug) { - for (p = debug; *p; p = end + 1) { - end = strchrnul(p, ','); - if (end - p == 3 && memcmp(p, "aub", 3) == 0) - device->dump_aub = true; - if (end - p == 5 && memcmp(p, "no_hw", 5) == 0) - device->no_hw = true; - if (*end == '\0') - break; - } - } -} - static VkResult anv_queue_init(struct anv_device *device, struct anv_queue *queue) { @@ -575,9 +537,6 @@ VkResult anv_CreateDevice( if (!device) return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); - device->no_hw = physical_device->no_hw; - parse_debug_flags(device); - device->instance = physical_device->instance; /* XXX(chadv): Can we dup() physicalDevice->fd here? */ @@ -607,7 +566,6 @@ VkResult anv_CreateDevice( device->info = *physical_device->info; device->compiler = anv_compiler_create(device); - device->aub_writer = NULL; pthread_mutex_init(&device->mutex, NULL); @@ -657,9 +615,6 @@ VkResult anv_DestroyDevice( close(device->fd); - if (device->aub_writer) - anv_aub_writer_destroy(device->aub_writer); - anv_instance_free(device->instance, device); return VK_SUCCESS; @@ -763,25 +718,18 @@ VkResult anv_QueueSubmit( assert(cmd_buffer->level == VK_CMD_BUFFER_LEVEL_PRIMARY); - if (device->dump_aub) - anv_cmd_buffer_dump(cmd_buffer); + ret = anv_gem_execbuffer(device, &cmd_buffer->execbuf2.execbuf); + if (ret != 0) + return vk_error(VK_ERROR_UNKNOWN); - if (!device->no_hw) { - ret = anv_gem_execbuffer(device, &cmd_buffer->execbuf2.execbuf); + if (fence) { + ret = anv_gem_execbuffer(device, &fence->execbuf); if (ret != 0) return vk_error(VK_ERROR_UNKNOWN); - - if (fence) { - ret = anv_gem_execbuffer(device, &fence->execbuf); - if (ret != 0) - return vk_error(VK_ERROR_UNKNOWN); - } - - for (uint32_t i = 0; i < cmd_buffer->execbuf2.bo_count; i++) - cmd_buffer->execbuf2.bos[i]->offset = cmd_buffer->execbuf2.objects[i].offset; - } else { - *(uint32_t *)queue->completed_serial.map = cmd_buffer->serial; } + + for (uint32_t i = 0; i < cmd_buffer->execbuf2.bo_count; i++) + cmd_buffer->execbuf2.bos[i]->offset = cmd_buffer->execbuf2.objects[i].offset; } return VK_SUCCESS; @@ -838,19 +786,17 @@ VkResult anv_DeviceWaitIdle( execbuf.rsvd1 = device->context_id; execbuf.rsvd2 = 0; - if (!device->no_hw) { - ret = anv_gem_execbuffer(device, &execbuf); - if (ret != 0) { - result = vk_error(VK_ERROR_UNKNOWN); - goto fail; - } + ret = anv_gem_execbuffer(device, &execbuf); + if (ret != 0) { + result = vk_error(VK_ERROR_UNKNOWN); + goto fail; + } - timeout = INT64_MAX; - ret = anv_gem_wait(device, bo->gem_handle, &timeout); - if (ret != 0) { - result = vk_error(VK_ERROR_UNKNOWN); - goto fail; - } + timeout = INT64_MAX; + ret = anv_gem_wait(device, bo->gem_handle, &timeout); + if (ret != 0) { + result = vk_error(VK_ERROR_UNKNOWN); + goto fail; } anv_state_pool_free(&device->dynamic_state_pool, state); diff --git a/src/vulkan/anv_private.h b/src/vulkan/anv_private.h index d517814847c..a94dd63b6ae 100644 --- a/src/vulkan/anv_private.h +++ b/src/vulkan/anv_private.h @@ -209,11 +209,6 @@ struct anv_bo { uint32_t index; uint64_t offset; uint64_t size; - - /* This field is here for the benefit of the aub dumper. It can (and for - * userptr bos it must) be set to the cpu map of the buffer. Destroying - * the bo won't clean up the mmap, it's still the responsibility of the bo - * user to do that. */ void *map; }; @@ -335,7 +330,6 @@ void anv_bo_pool_free(struct anv_bo_pool *pool, const struct anv_bo *bo); struct anv_physical_device { struct anv_instance * instance; uint32_t chipset_id; - bool no_hw; const char * path; const char * name; const struct brw_device_info * info; @@ -395,8 +389,6 @@ struct anv_device { struct brw_device_info info; int context_id; int fd; - bool no_hw; - bool dump_aub; struct anv_bo_pool batch_bo_pool; @@ -416,7 +408,6 @@ struct anv_device { struct anv_block_pool scratch_block_pool; struct anv_compiler * compiler; - struct anv_aub_writer * aub_writer; pthread_mutex_t mutex; }; @@ -793,7 +784,6 @@ void anv_cmd_buffer_clear_attachments(struct anv_cmd_buffer *cmd_buffer, const VkClearValue *clear_values); void anv_cmd_buffer_dump(struct anv_cmd_buffer *cmd_buffer); -void anv_aub_writer_destroy(struct anv_aub_writer *writer); struct anv_fence { struct anv_bo bo; |