Skip to content

Commit

Permalink
[graphite] Add Vulkan serialization for Android-style Precompile keys
Browse files Browse the repository at this point in the history
Bug: b/391403921
Change-Id: Ia74783b1ca621133484668ca7ceb96f8ce5c9b64
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/946736
Reviewed-by: Greg Daniel <[email protected]>
Commit-Queue: Robert Phillips <[email protected]>
  • Loading branch information
rphilli authored and SkCQ committed Feb 6, 2025
1 parent fe92499 commit d0abbb0
Show file tree
Hide file tree
Showing 10 changed files with 221 additions and 16 deletions.
28 changes: 16 additions & 12 deletions dm/DMSrcSink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2338,15 +2338,17 @@ void GraphitePrecompileTestingSink::LogMissingKey(
{
GraphicsPipelineDesc originalPipelineDesc;
RenderPassDesc originalRenderPassDesc;
UniqueKeyUtils::ExtractKeyDescs(precompileContext, missingKey,
&originalPipelineDesc,
&originalRenderPassDesc);
bool extracted = UniqueKeyUtils::ExtractKeyDescs(precompileContext, missingKey,
&originalPipelineDesc,
&originalRenderPassDesc);

SkDebugf("------- Key missing from %s keys:\n", poolName);
missingKey.dump(missingKeyName);
UniqueKeyUtils::DumpDescs(precompileContext,
originalPipelineDesc,
originalRenderPassDesc);
if (extracted) {
UniqueKeyUtils::DumpDescs(precompileContext,
originalPipelineDesc,
originalRenderPassDesc);
}
}

SkDebugf("Have %d %s keys -----------------\n", (int) pool.size(), poolName);
Expand All @@ -2355,15 +2357,17 @@ void GraphitePrecompileTestingSink::LogMissingKey(

GraphicsPipelineDesc recreatedPipelineDesc;
RenderPassDesc recreatedRenderPassDesc;
UniqueKeyUtils::ExtractKeyDescs(precompileContext, b,
&recreatedPipelineDesc,
&recreatedRenderPassDesc);
bool extracted = UniqueKeyUtils::ExtractKeyDescs(precompileContext, b,
&recreatedPipelineDesc,
&recreatedRenderPassDesc);

SkDebugf("%d: ----\n", count++);
b.dump("recreated key:");
UniqueKeyUtils::DumpDescs(precompileContext,
recreatedPipelineDesc,
recreatedRenderPassDesc);
if (extracted) {
UniqueKeyUtils::DumpDescs(precompileContext,
recreatedPipelineDesc,
recreatedRenderPassDesc);
}
}
}
#endif
Expand Down
11 changes: 8 additions & 3 deletions include/core/SkStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,12 @@ class SK_API SkStream {
[[nodiscard]] bool readS8(int8_t*);
[[nodiscard]] bool readS16(int16_t*);
[[nodiscard]] bool readS32(int32_t*);
[[nodiscard]] bool readS64(int64_t*);

[[nodiscard]] bool readU8(uint8_t* i) { return this->readS8((int8_t*)i); }
[[nodiscard]] bool readU8(uint8_t* i) { return this->readS8((int8_t*)i); }
[[nodiscard]] bool readU16(uint16_t* i) { return this->readS16((int16_t*)i); }
[[nodiscard]] bool readU32(uint32_t* i) { return this->readS32((int32_t*)i); }
[[nodiscard]] bool readU64(uint64_t* i) { return this->readS64((int64_t*)i); }

[[nodiscard]] bool readBool(bool* b) {
uint8_t i;
Expand Down Expand Up @@ -240,8 +242,11 @@ class SK_API SkWStream {
uint16_t v = SkToU16(value);
return this->write(&v, 2);
}
bool write32(uint32_t v) {
return this->write(&v, 4);
bool write32(uint32_t value) {
return this->write(&value, 4);
}
bool write64(uint64_t value) {
return this->write(&value, 8);
}

bool writeText(const char text[]) {
Expand Down
4 changes: 4 additions & 0 deletions src/core/SkStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ bool SkStream::readS32(int32_t* i) {
return this->read(i, sizeof(*i)) == sizeof(*i);
}

bool SkStream::readS64(int64_t* i) {
return this->read(i, sizeof(*i)) == sizeof(*i);
}

bool SkStream::readScalar(SkScalar* i) {
return this->read(i, sizeof(*i)) == sizeof(*i);
}
Expand Down
29 changes: 29 additions & 0 deletions src/gpu/graphite/vk/VulkanCaps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1535,6 +1535,35 @@ UniqueKey VulkanCaps::makeGraphicsPipelineKey(const GraphicsPipelineDesc& pipeli
return pipelineKey;
}

// c.f. VulkanTextureInfoData::serialize
bool VulkanCaps::deserializeTextureInfo(SkStream* stream,
BackendApi backendAPI,
Mipmapped mipmapped,
Protected isProtected,
uint32_t sampleCount,
TextureInfo* out) const {
SkASSERT(backendAPI == BackendApi::kVulkan);

VulkanTextureSpec spec;
if (!VulkanTextureSpec::Deserialize(stream, &spec)) {
return false;
}

SkASSERT((isProtected == Protected::kYes) ==
SkToBool(spec.fFlags & VK_IMAGE_CREATE_PROTECTED_BIT));

*out = TextureInfos::MakeVulkan(VulkanTextureInfo(sampleCount,
mipmapped,
spec.fFlags,
spec.fFormat,
spec.fImageTiling,
spec.fImageUsageFlags,
spec.fSharingMode,
spec.fAspectMask,
spec.fYcbcrConversionInfo));
return true;
}

void VulkanCaps::buildKeyForTexture(SkISize dimensions,
const TextureInfo& info,
ResourceType type,
Expand Down
7 changes: 7 additions & 0 deletions src/gpu/graphite/vk/VulkanCaps.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ class VulkanCaps final : public Caps {
const RenderPassDesc&) const override;
UniqueKey makeComputePipelineKey(const ComputePipelineDesc&) const override { return {}; }

bool deserializeTextureInfo(SkStream*,
BackendApi,
Mipmapped,
Protected,
uint32_t sampleCount,
TextureInfo* out) const override;

uint32_t channelMask(const TextureInfo&) const override;

bool isTexturable(const VulkanTextureInfo&) const;
Expand Down
50 changes: 49 additions & 1 deletion src/gpu/graphite/vk/VulkanGraphiteTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
* found in the LICENSE file.
*/

#include "include/core/SkStream.h"
#include "src/gpu/graphite/vk/VulkanGraphiteTypesPriv.h"
#include "src/gpu/vk/VulkanUtilsPriv.h"

namespace skgpu::graphite {

Expand All @@ -23,5 +25,51 @@ VulkanTextureInfo VulkanTextureSpecToTextureInfo(const VulkanTextureSpec& vkSpec
vkSpec.fYcbcrConversionInfo);
}

} // namespace skgpu::graphite

bool VulkanTextureSpec::serialize(SkWStream* stream) const {
SkASSERT(SkTFitsIn<uint64_t>(fFlags));
SkASSERT(SkTFitsIn<uint64_t>(fFormat));
SkASSERT(SkTFitsIn<uint64_t>(fImageUsageFlags));
SkASSERT(SkTFitsIn<uint8_t>(fImageTiling));
SkASSERT(SkTFitsIn<uint8_t>(fSharingMode));
SkASSERT(SkTFitsIn<uint32_t>(fAspectMask));

if (!stream->write64(static_cast<uint64_t>(fFlags))) { return false; }
if (!stream->write64(static_cast<uint64_t>(fFormat))) { return false; }
if (!stream->write64(static_cast<uint64_t>(fImageUsageFlags))) { return false; }
if (!stream->write8(static_cast<uint8_t>(fImageTiling))) { return false; }
if (!stream->write8(static_cast<uint8_t>(fSharingMode))) { return false; }
if (!stream->write32(static_cast<uint32_t>(fAspectMask))) { return false; }

return SerializeVkYCbCrInfo(stream, fYcbcrConversionInfo);
}

// TODO(robertphillips): add validity checks to deserialized values
bool VulkanTextureSpec::Deserialize(SkStream* stream, VulkanTextureSpec* out) {
uint64_t tmp64;

if (!stream->readU64(&tmp64)) { return false; }
out->fFlags = static_cast<VkImageCreateFlags>(tmp64);

if (!stream->readU64(&tmp64)) { return false; }
out->fFormat = static_cast<VkFormat>(tmp64);

if (!stream->readU64(&tmp64)) { return false; }
out->fImageUsageFlags = static_cast<VkImageUsageFlags>(tmp64);

uint32_t tmp32;
uint8_t tmp8;

if (!stream->readU8(&tmp8)) { return false; }
out->fImageTiling = static_cast<VkImageTiling>(tmp8);

if (!stream->readU8(&tmp8)) { return false; }
out->fSharingMode = static_cast<VkSharingMode>(tmp8);

if (!stream->readU32(&tmp32)) { return false; }
out->fAspectMask = static_cast<VkImageAspectFlags>(tmp32);

return DeserializeVkYCbCrInfo(stream, &out->fYcbcrConversionInfo);
}

} // namespace skgpu::graphite
6 changes: 6 additions & 0 deletions src/gpu/graphite/vk/VulkanGraphiteTypesPriv.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
#include "include/gpu/graphite/vk/VulkanGraphiteTypes.h"
#include "include/private/gpu/vk/SkiaVulkan.h"

class SkStream;
class SkWStream;

namespace skgpu::graphite {

struct VulkanTextureSpec {
Expand Down Expand Up @@ -66,6 +69,9 @@ struct VulkanTextureSpec {
fAspectMask);
}

bool serialize(SkWStream*) const;
static bool Deserialize(SkStream*, VulkanTextureSpec* out);

VkImageCreateFlags fFlags;
VkFormat fFormat;
VkImageTiling fImageTiling;
Expand Down
5 changes: 5 additions & 0 deletions src/gpu/graphite/vk/VulkanTextureInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ class VulkanTextureInfoData final : public TextureInfoData {
}
return false;
}

// c.f. VulkanCaps::deserializeTextureInfo
bool serialize(SkWStream* stream) const override {
return fVkSpec.serialize(stream);
}
};

static const VulkanTextureInfoData* get_and_cast_data(const TextureInfo& info) {
Expand Down
91 changes: 91 additions & 0 deletions src/gpu/vk/VulkanUtilsPriv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@

#include "src/gpu/vk/VulkanUtilsPriv.h"

#include "include/core/SkStream.h"
#include "include/gpu/vk/VulkanBackendContext.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkTFitsIn.h"
#include "include/private/base/SkTo.h"
#include "src/gpu/vk/VulkanInterface.h"

#include <algorithm>
Expand Down Expand Up @@ -76,6 +79,94 @@ void SetupSamplerYcbcrConversionInfo(VkSamplerYcbcrConversionCreateInfo* outInfo
outInfo->forceExplicitReconstruction = conversionInfo.fForceExplicitReconstruction;
}

bool SerializeVkYCbCrInfo(SkWStream* stream, const VulkanYcbcrConversionInfo& info) {
SkASSERT(SkTFitsIn<uint64_t>(info.fFormat));
// fExternalFormat is already a uint64_t
SkASSERT(SkTFitsIn<uint8_t>(info.fYcbcrModel));
SkASSERT(SkTFitsIn<uint8_t>(info.fYcbcrRange));
SkASSERT(SkTFitsIn<uint8_t>(info.fXChromaOffset));
SkASSERT(SkTFitsIn<uint8_t>(info.fYChromaOffset));
SkASSERT(SkTFitsIn<uint64_t>(info.fChromaFilter));
SkASSERT(SkTFitsIn<uint64_t>(info.fFormatFeatures));
SkASSERT(SkTFitsIn<uint8_t>(info.fComponents.r));
SkASSERT(SkTFitsIn<uint8_t>(info.fComponents.g));
SkASSERT(SkTFitsIn<uint8_t>(info.fComponents.b));
SkASSERT(SkTFitsIn<uint8_t>(info.fComponents.a));
// fForceExplicitReconstruction is a VkBool32

// TODO(robertphillips): this isn't as densely packed as possible
if (!stream->write64(static_cast<uint64_t>(info.fFormat))) { return false; }
if (!stream->write64(info.fExternalFormat)) { return false; }
if (!stream->write8(static_cast<uint8_t>(info.fYcbcrModel))) { return false; }
if (!info.isValid()) {
return true;
}

if (!stream->write8(static_cast<uint8_t>(info.fYcbcrRange))) { return false; }
if (!stream->write8(static_cast<uint8_t>(info.fXChromaOffset))) { return false; }
if (!stream->write8(static_cast<uint8_t>(info.fYChromaOffset))) { return false; }
if (!stream->write64(static_cast<uint64_t>(info.fChromaFilter))) { return false; }
if (!stream->write64(static_cast<uint64_t>(info.fFormatFeatures))) { return false; }
if (!stream->write8(static_cast<uint8_t>(info.fComponents.r))) { return false; }
if (!stream->write8(static_cast<uint8_t>(info.fComponents.g))) { return false; }
if (!stream->write8(static_cast<uint8_t>(info.fComponents.b))) { return false; }
if (!stream->write8(static_cast<uint8_t>(info.fComponents.a))) { return false; }
if (!stream->writeBool(SkToBool(info.fForceExplicitReconstruction))) { return false;}

return true;
}

bool DeserializeVkYCbCrInfo(SkStream* stream, VulkanYcbcrConversionInfo* out) {
uint64_t tmp64;
uint8_t tmp8;

if (!stream->readU64(&tmp64)) { return false; }
out->fFormat = static_cast<VkFormat>(tmp64);

if (!stream->readU64(&tmp64)) { return false; }
out->fExternalFormat = tmp64;

if (!stream->readU8(&tmp8)) { return false; }
out->fYcbcrModel = static_cast<VkSamplerYcbcrModelConversion>(tmp8);

if (!out->isValid()) {
return true;
}

if (!stream->readU8(&tmp8)) { return false; }
out->fYcbcrRange = static_cast<VkSamplerYcbcrRange>(tmp8);

if (!stream->readU8(&tmp8)) { return false; }
out->fXChromaOffset = static_cast<VkChromaLocation>(tmp8);

if (!stream->readU8(&tmp8)) { return false; }
out->fYChromaOffset = static_cast<VkChromaLocation>(tmp8);

if (!stream->readU64(&tmp64)) { return false; }
out->fChromaFilter = static_cast<VkFilter>(tmp64);

if (!stream->readU64(&tmp64)) { return false; }
out->fFormatFeatures = static_cast<VkFormatFeatureFlags>(tmp64);

if (!stream->readU8(&tmp8)) { return false; }
out->fComponents.r = static_cast<VkComponentSwizzle>(tmp8);

if (!stream->readU8(&tmp8)) { return false; }
out->fComponents.g = static_cast<VkComponentSwizzle>(tmp8);

if (!stream->readU8(&tmp8)) { return false; }
out->fComponents.b = static_cast<VkComponentSwizzle>(tmp8);

if (!stream->readU8(&tmp8)) { return false; }
out->fComponents.a = static_cast<VkComponentSwizzle>(tmp8);

bool tmpBool;
if (!stream->readBool(&tmpBool)) { return false; }
out->fForceExplicitReconstruction = tmpBool;

return false;
}

#ifdef SK_BUILD_FOR_ANDROID

/**
Expand Down
6 changes: 6 additions & 0 deletions src/gpu/vk/VulkanUtilsPriv.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#include <string>
#include <cstddef>

class SkStream;
class SkWStream;

namespace SkSL {

enum class ProgramKind : int8_t;
Expand Down Expand Up @@ -277,6 +280,9 @@ static constexpr const char* VkFormatToStr(VkFormat vkFormat) {
}
}

[[nodiscard]] bool SerializeVkYCbCrInfo(SkWStream*, const VulkanYcbcrConversionInfo&);
[[nodiscard]] bool DeserializeVkYCbCrInfo(SkStream*, VulkanYcbcrConversionInfo* out);

#ifdef SK_BUILD_FOR_ANDROID
/**
* Vulkan AHardwareBuffer utility functions shared between graphite and ganesh
Expand Down

0 comments on commit d0abbb0

Please sign in to comment.