From d3d2de28b797e7cadc772e43d39fb99c29c0d1f0 Mon Sep 17 00:00:00 2001 From: leegao Date: Thu, 14 Aug 2025 18:27:02 +1000 Subject: [PATCH] Finish DUMP_BCN_ARTIFACTS implementation --- src/vulkan/wrapper/artifacts.cpp | 85 ++++++++++++++++++++++++---- src/vulkan/wrapper/artifacts.h | 2 +- src/vulkan/wrapper/wrapper_device.c | 15 ++--- src/vulkan/wrapper/wrapper_private.h | 15 +++++ 4 files changed, 98 insertions(+), 19 deletions(-) diff --git a/src/vulkan/wrapper/artifacts.cpp b/src/vulkan/wrapper/artifacts.cpp index 7b588cb1545..2d24e714b1a 100644 --- a/src/vulkan/wrapper/artifacts.cpp +++ b/src/vulkan/wrapper/artifacts.cpp @@ -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 +#include +#include -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 } diff --git a/src/vulkan/wrapper/artifacts.h b/src/vulkan/wrapper/artifacts.h index 91333c6a6cf..021a2943338 100644 --- a/src/vulkan/wrapper/artifacts.h +++ b/src/vulkan/wrapper/artifacts.h @@ -6,7 +6,7 @@ extern "C" { #include -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 } diff --git a/src/vulkan/wrapper/wrapper_device.c b/src/vulkan/wrapper/wrapper_device.c index 73343310ae1..398da6e8148 100644 --- a/src/vulkan/wrapper/wrapper_device.c +++ b/src/vulkan/wrapper/wrapper_device.c @@ -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), @@ -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)); @@ -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); @@ -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, @@ -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) { diff --git a/src/vulkan/wrapper/wrapper_private.h b/src/vulkan/wrapper/wrapper_private.h index d9661730691..2aff95dcda2 100644 --- a/src/vulkan/wrapper/wrapper_private.h +++ b/src/vulkan/wrapper/wrapper_private.h @@ -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;