diff --git a/src/gfxstream/codegen/scripts/cereal/functable.py b/src/gfxstream/codegen/scripts/cereal/functable.py index 0f42ff9ed23..d47982f4eae 100644 --- a/src/gfxstream/codegen/scripts/cereal/functable.py +++ b/src/gfxstream/codegen/scripts/cereal/functable.py @@ -85,6 +85,7 @@ RESOURCE_TRACKER_ENTRIES = [ "vkQueueSignalReleaseImageANDROID", "vkCmdPipelineBarrier", "vkCreateGraphicsPipelines", + "vkCmdClearColorImage", # Fuchsia "vkGetMemoryZirconHandleFUCHSIA", "vkGetMemoryZirconHandlePropertiesFUCHSIA", diff --git a/src/gfxstream/guest/vulkan_enc/ResourceTracker.cpp b/src/gfxstream/guest/vulkan_enc/ResourceTracker.cpp index 6fdca3b64a0..f7ad45409a1 100644 --- a/src/gfxstream/guest/vulkan_enc/ResourceTracker.cpp +++ b/src/gfxstream/guest/vulkan_enc/ResourceTracker.cpp @@ -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) { diff --git a/src/gfxstream/guest/vulkan_enc/ResourceTracker.h b/src/gfxstream/guest/vulkan_enc/ResourceTracker.h index fc70fb5adc3..4912d7b4b28 100644 --- a/src/gfxstream/guest/vulkan_enc/ResourceTracker.h +++ b/src/gfxstream/guest/vulkan_enc/ResourceTracker.h @@ -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); diff --git a/src/gfxstream/guest/vulkan_enc/gfxstream_vk_private.cpp b/src/gfxstream/guest/vulkan_enc/gfxstream_vk_private.cpp index d1e0c8349b2..13078eba335 100644 --- a/src/gfxstream/guest/vulkan_enc/gfxstream_vk_private.cpp +++ b/src/gfxstream/guest/vulkan_enc/gfxstream_vk_private.cpp @@ -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 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; +} \ No newline at end of file diff --git a/src/gfxstream/guest/vulkan_enc/gfxstream_vk_private.h b/src/gfxstream/guest/vulkan_enc/gfxstream_vk_private.h index 255279352c8..ec9d886334f 100644 --- a/src/gfxstream/guest/vulkan_enc/gfxstream_vk_private.h +++ b/src/gfxstream/guest/vulkan_enc/gfxstream_vk_private.h @@ -142,4 +142,7 @@ std::vector transformVkFenceList(const VkFence* pFences, uint32_t fence std::vector transformVkSemaphoreSubmitInfoList( const VkSemaphoreSubmitInfo* pSemaphoreSubmitInfos, uint32_t semaphoreSubmitInfoCount); +float linearChannelToSRGB(float cl); +float srgbFormatNeedsConversionForClearColor(const VkFormat& format); + #endif /* GFXSTREAM_VK_PRIVATE_H */