vk: Drop aub dumper and PCI ID override feature

These are now available in intel_aubdump from intel-gpu-tools.

Signed-off-by: Kristian Høgsberg Kristensen <kristian.h.kristensen@intel.com>
This commit is contained in:
Kristian Høgsberg Kristensen 2015-08-14 09:39:01 -07:00
parent 6d09d0644b
commit aac6f7c3bb
4 changed files with 19 additions and 377 deletions

View File

@ -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 \

View File

@ -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);
}

View File

@ -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);

View File

@ -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;