Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 74 additions & 11 deletions src/vulkan/wrapper/artifacts.cpp
Original file line number Diff line number Diff line change
@@ -1,33 +1,96 @@
#include "artifacts.h"
#include "wrapper_objects.h"
#include "wrapper_private.h"
#include "wrapper_entrypoints.h"
#include "wrapper_checks.h"
#include "vk_printers.h"

#include <string>
#include <sstream>
#include <iomanip>

static FILE* open_log_file(const char* postfix, int id) {
static char dir[256];
static FILE* open_log_file(const std::string postfix, VkFormat original_format, int id, const char* mode) {
static std::string dir;
static bool initialized = false;
if (!initialized) {
initialized = true;
char time_str[20];
get_current_time_string(time_str, sizeof(time_str));
sprintf(dir, "/sdcard/Documents/Wrapper/artifacts_%s.%s.%d", time_str, getprogname(), getpid());
if (mkdir(dir, 0777) == 0) {
WLOGE("Failed to create the artifacts directory %s", dir);
dir = std::string("/sdcard/Documents/Wrapper/artifacts_") + time_str + "." + getprogname() + "." + std::to_string(getpid());
if (mkdir(dir.c_str(), 0777) == 0) {
WLOGE("Failed to create the artifacts directory %s", dir.c_str());
} else {
WLOGD("Logging artifacts to %s", dir);
WLOGD("Logging artifacts to %s", dir.c_str());
}
}
std::string path = std::string(dir) + "/" + std::to_string(id) + "_" + postfix;
return fopen(path.c_str(), "w");
std::stringstream padded_id;
padded_id << std::setw(5) << std::setfill('0') << id;

std::string path = dir + "/" + padded_id.str() + "_fmt" + std::to_string(original_format) + postfix;
return fopen(path.c_str(), mode);
}

extern "C"
void RecordBCnArtifacts(struct wrapper_device* device, const VkBufferImageCopy* region, VkBuffer srcBuffer, VkBuffer stagingBuffer, int decode_id) {
// auto fd = open_log_file("region.txt", decode_id);
void RecordBCnArtifacts(struct wrapper_device* device, VkFormat original_format,
const VkBufferImageCopy* region, VkBuffer srcBuffer, VkBuffer stagingBuffer, int decode_id) {
if (region) {
auto fd = open_log_file("_region.txt", original_format, decode_id, "w");
fprintf(fd, "src: %p\n", srcBuffer);
vk_print_VkBufferImageCopy(0, 0, fd, "", region);
fclose(fd);
}

struct wrapper_buffer* wbuf = get_wrapper_buffer(device, srcBuffer);
if (!wbuf) {
WLOGE("srcBuffer not tracked, skipping (decode_id=%d)", decode_id);
} else if (wbuf->memory == VK_NULL_HANDLE) {
WLOGE("srcBuffer not bound, skipping (decode_id=%d)", decode_id);
} else {
void* srcData;
VkMemoryMapInfoKHR mapInfoSrc = {
.sType = VK_STRUCTURE_TYPE_MEMORY_MAP_INFO_KHR,
.memory = wbuf->memory,
.offset = wbuf->memoryOffset,
.size = VK_WHOLE_SIZE,
};
VkResult result = WCHECK(MapMemory2KHR((VkDevice) device, &mapInfoSrc, &srcData));
if (result != VK_SUCCESS) {
WLOGE("ERROR: Failed to map srcBuffer memory: %d", result);
} else {
int w = region->bufferRowLength ? region->bufferRowLength : region->imageExtent.width;
int h = region->bufferImageHeight ? region->bufferImageHeight : region->imageExtent.height;
int blocks_stride = (w + 3) / 4;
int block_rows = (h + 3) / 4;
int blocks = blocks_stride * block_rows;
int block_size = get_bc_block_size(original_format);
auto fd = open_log_file("_src.dat", original_format, decode_id, "wb");
fwrite(srcData, block_size, blocks, fd);
fclose(fd);
}
}

wbuf = get_wrapper_buffer(device, stagingBuffer);
if (!wbuf) {
WLOGE("dstBuffer not tracked, skipping (decode_id=%d)", decode_id);
} else if (wbuf->memory == VK_NULL_HANDLE) {
WLOGE("dstBuffer not bound, skipping (decode_id=%d)", decode_id);
} else {
void* dstData;
VkMemoryMapInfoKHR mapInfoSrc = {
.sType = VK_STRUCTURE_TYPE_MEMORY_MAP_INFO_KHR,
.memory = wbuf->memory,
.offset = 0,
.size = VK_WHOLE_SIZE,
};
VkResult result = WCHECK(MapMemory2KHR((VkDevice) device, &mapInfoSrc, &dstData));
if (result != VK_SUCCESS) {
WLOGE("ERROR: Failed to map dstBuffer memory: %d", result);
} else {
int block_size = get_bc_target_size(device->physical, original_format);
auto fd = open_log_file("_dst.dat", original_format, decode_id, "wb");
fwrite(dstData, block_size, region->imageExtent.width * region->imageExtent.height, fd);
fclose(fd);
WCHECKV(UnmapMemory((VkDevice) device, wbuf->memory));
}
}
// TODO: Implement this
}
2 changes: 1 addition & 1 deletion src/vulkan/wrapper/artifacts.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ extern "C" {

#include <vulkan/vulkan_core.h>

void RecordBCnArtifacts(struct wrapper_device* device, const VkBufferImageCopy* region, VkBuffer srcBuffer, VkBuffer stagingBuffer, int decode_id);
void RecordBCnArtifacts(struct wrapper_device* device, VkFormat original_format, const VkBufferImageCopy* region, VkBuffer srcBuffer, VkBuffer stagingBuffer, int decode_id);

#ifdef __cplusplus
}
Expand Down
15 changes: 8 additions & 7 deletions src/vulkan/wrapper/wrapper_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,8 +336,8 @@ WRAPPER_CreateDevice(VkPhysicalDevice physicalDevice,
device->dispatch_handle);

// Initialize the BCn interceptor states
bool record_artifacts = CHECK_FLAG("RECORD_ARTIFACTS");
bool use_image_view = use_image_view_mode() && !record_artifacts;
bool dump_artifacts = CHECK_FLAG("DUMP_BCN_ARTIFACTS");
bool use_image_view = use_image_view_mode() && !dump_artifacts;

result = InterceptorState_Init(&device->s3tc,
wrapper_device_to_handle(device),
Expand Down Expand Up @@ -1414,6 +1414,7 @@ static VkResult HostSideDecompression(
.sType = VK_STRUCTURE_TYPE_MEMORY_MAP_INFO_KHR,
.memory = dstMemory,
.offset = 0, // Assuming dstMemory is large enough to hold the decompressed
// TODO: FIX THIS for non rgba8 data
.size = region->imageExtent.width * region->imageExtent.height * 4, // 4 bytes per pixel for RGBA
};
result = WCHECK(MapMemory2KHR((VkDevice) _device, &mapInfoDst, &dstData));
Expand Down Expand Up @@ -1804,10 +1805,10 @@ WRAPPER_CmdCopyBufferToImage(VkCommandBuffer commandBuffer,
int decode_id = counter++;
WLOG("Emulating support for format=%d, decode_id=%d", wimg->original_format, decode_id);

bool record_artifacts = CHECK_FLAG("RECORD_ARTIFACTS");
bool dump_artifacts = CHECK_FLAG("DUMP_BCN_ARTIFACTS");
bool use_cpu_bcn = (get_host_decoding_bcn_masks() & (1 << (wimg->original_format - 131))) != 0;
bool use_compute_shader = use_compute_shader_mode() && !use_cpu_bcn;
bool use_image_view = use_image_view_mode() && !use_cpu_bcn && !record_artifacts;
bool use_image_view = use_image_view_mode() && !use_cpu_bcn && !dump_artifacts;

// Check if the queues are the same
struct wrapper_command_pool *pool = get_wrapper_command_pool(_device, wcb->pool);
Expand Down Expand Up @@ -1877,7 +1878,7 @@ WRAPPER_CmdCopyBufferToImage(VkCommandBuffer commandBuffer,
args.stagingBuffer = stagingBuffer;
}

if (CHECK_FLAG("WRAPPER_ONE_BY_ONE") || record_artifacts) {
if (CHECK_FLAG("WRAPPER_ONE_BY_ONE") || dump_artifacts) {
WLOGD("Submitting decode_id %d", decode_id);
result = SubmitOneTimeCommands(
_device,
Expand All @@ -1900,9 +1901,9 @@ WRAPPER_CmdCopyBufferToImage(VkCommandBuffer commandBuffer,
}
}

if (record_artifacts) {
if (dump_artifacts) {
// Invariant: srcBuffer contains the BCn blocks, stagingBuffer contains the output
RecordBCnArtifacts(_device, region, srcBuffer, stagingBuffer, decode_id);
RecordBCnArtifacts(_device, wimg->original_format, region, srcBuffer, stagingBuffer, decode_id);
}

if (!use_image_view) {
Expand Down
15 changes: 15 additions & 0 deletions src/vulkan/wrapper/wrapper_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,21 @@ static VkFormat unwrap_vk_format(struct wrapper_device* device, VkFormat in_form
return unwrap_vk_format_physical_device(device->physical, in_format);
}

static inline uint32_t get_bc_target_size(struct wrapper_physical_device* pdevice, VkFormat in_format) {
VkFormat out_format = unwrap_vk_format_physical_device(pdevice, in_format);
switch (out_format) {
case VK_FORMAT_R8G8B8A8_UNORM:
case VK_FORMAT_R8G8B8A8_SNORM:
return 4;
case VK_FORMAT_R16G16B16A16_SFLOAT:
return 8;
default:
WLOGE("Unknown out_format: %d", out_format);
return 4;
break;
}
}

typedef struct {
uint32_t srcFormat;
uint32_t srcRowLength;
Expand Down
Loading