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:
parent
6d09d0644b
commit
aac6f7c3bb
|
@ -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 \
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue