gfxstream: intercept vkCmdClearColor(...) and do linear->SRGB conversion

Reviewed-by: Marcin Radomski <dextero@google.com>
Reviewed-by: Aaron Ruby <aruby@qnx.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35323>
This commit is contained in:
sergiuferentz 2025-05-27 14:25:35 +01:00 committed by Marge Bot
parent fd40649768
commit de3361d050
5 changed files with 60 additions and 0 deletions

View file

@ -85,6 +85,7 @@ RESOURCE_TRACKER_ENTRIES = [
"vkQueueSignalReleaseImageANDROID",
"vkCmdPipelineBarrier",
"vkCreateGraphicsPipelines",
"vkCmdClearColorImage",
# Fuchsia
"vkGetMemoryZirconHandleFUCHSIA",
"vkGetMemoryZirconHandlePropertiesFUCHSIA",

View file

@ -14,6 +14,7 @@
#include "goldfish_address_space.h"
#include "goldfish_vk_private_defs.h"
#include "util/anon_file.h"
#include "util/log.h"
#include "util/macros.h"
#include "vulkan/vulkan_core.h"
#include "util/detect_os.h"
@ -7369,6 +7370,39 @@ void ResourceTracker::on_vkCmdPipelineBarrier(
updatedImageMemoryBarriers.data(), true /* do lock */);
}
void ResourceTracker::on_vkCmdClearColorImage(void* context, VkCommandBuffer commandBuffer, VkImage image,
VkImageLayout imageLayout, const VkClearColorValue* pColor,
uint32_t rangeCount, const VkImageSubresourceRange* pRanges) {
VkEncoder* enc = (VkEncoder*)context;
auto imageInfoIt = info_VkImage.find(image);
if (!pColor) {
mesa_loge("%s: Null VkClearColorValue requested", __func__);
return;
}
if (imageInfoIt == info_VkImage.end()) {
mesa_loge("%s: Failed to find image required for vkCmdClearColorImage", __func__);
return;
}
auto& imageInfo = imageInfoIt->second;
VkFormat actualFormat = imageInfo.createInfo.format;
VkClearColorValue convertedColor = *pColor;
// Color buffer image on the host will be created with UNORM format to ensure
// it'll have the identical parameters, so we need to convert the linearized
// clear color back to sRGB at this point.
// TODO(b/420857458): revise the allocation logic to support mutable formats better
if (srgbFormatNeedsConversionForClearColor(actualFormat)) {
// Perform linear to srgb conversion
// Backing image is UNORM for vkCmdClearColorImage so we convert pColor
convertedColor.float32[0] = linearChannelToSRGB(convertedColor.float32[0]);
convertedColor.float32[1] = linearChannelToSRGB(convertedColor.float32[1]);
convertedColor.float32[2] = linearChannelToSRGB(convertedColor.float32[2]);
}
enc->vkCmdClearColorImage(commandBuffer, image, imageLayout, &convertedColor, rangeCount, pRanges, true);
return;
}
void ResourceTracker::on_vkDestroyDescriptorSetLayout(void* context, VkDevice device,
VkDescriptorSetLayout descriptorSetLayout,
const VkAllocationCallbacks* pAllocator) {

View file

@ -24,6 +24,7 @@
#include "goldfish_vk_transform_guest.h"
#include "util/perf/cpu_trace.h"
#include "util/detect_os.h"
#include "vulkan/vulkan_core.h"
/// Use installed headers or locally defined Fuchsia-specific bits
#ifdef VK_USE_PLATFORM_FUCHSIA
@ -562,6 +563,10 @@ class ResourceTracker {
uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers,
uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers);
void on_vkCmdClearColorImage(void* context, VkCommandBuffer commandBuffer, VkImage image,
VkImageLayout imageLayout, const VkClearColorValue* pColor,
uint32_t rangeCount, const VkImageSubresourceRange* pRanges);
void on_vkDestroyDescriptorSetLayout(void* context, VkDevice device,
VkDescriptorSetLayout descriptorSetLayout,
const VkAllocationCallbacks* pAllocator);

View file

@ -6,6 +6,7 @@
#include "gfxstream_vk_private.h"
#include "vk_sync_dummy.h"
#include "vulkan/vulkan_core.h"
/* Under the assumption that Mesa VK runtime queue submission is used, WSI flow
* sets this temporary state to a dummy sync type (when no explicit dma-buf
@ -58,3 +59,19 @@ std::vector<VkSemaphoreSubmitInfo> transformVkSemaphoreSubmitInfoList(
}
return outSemaphoreSubmitInfo;
}
float linearChannelToSRGB(float cl)
{
if (cl <= 0.0f)
return 0.0f;
else if (cl < 0.0031308f)
return 12.92f * cl;
else if (cl < 1.0f)
return 1.055f * pow(cl, 0.41666f) - 0.055f;
else
return 1.0f;
}
float srgbFormatNeedsConversionForClearColor(const VkFormat& format) {
return format == VK_FORMAT_R8G8B8A8_SRGB;
}

View file

@ -142,4 +142,7 @@ std::vector<VkFence> transformVkFenceList(const VkFence* pFences, uint32_t fence
std::vector<VkSemaphoreSubmitInfo> transformVkSemaphoreSubmitInfoList(
const VkSemaphoreSubmitInfo* pSemaphoreSubmitInfos, uint32_t semaphoreSubmitInfoCount);
float linearChannelToSRGB(float cl);
float srgbFormatNeedsConversionForClearColor(const VkFormat& format);
#endif /* GFXSTREAM_VK_PRIVATE_H */