Add kRGB_888X_GrPixelConfig
This is needed to support importing of RGBX AHB into skia's vulkan backend.
With this CL we only enable the new pixel config to be textureable.
Bug: skia:
Change-Id: Iba9180c14f3ef633ae846091cf453d68f82ce544
Reviewed-on: https://skia-review.googlesource.com/c/192035
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/include/private/GrTypesPriv.h b/include/private/GrTypesPriv.h
index 53bc8ab..0445167 100644
--- a/include/private/GrTypesPriv.h
+++ b/include/private/GrTypesPriv.h
@@ -46,6 +46,7 @@
kRGBA_4444_GrPixelConfig,
kRGBA_8888_GrPixelConfig,
kRGB_888_GrPixelConfig,
+ kRGB_888X_GrPixelConfig,
kRG_88_GrPixelConfig,
kBGRA_8888_GrPixelConfig,
kSRGBA_8888_GrPixelConfig,
@@ -966,6 +967,7 @@
case kRGB_565_GrPixelConfig:
case kRGBA_4444_GrPixelConfig:
case kRGB_888_GrPixelConfig:
+ case kRGB_888X_GrPixelConfig:
case kRG_88_GrPixelConfig:
case kRGBA_8888_GrPixelConfig:
case kBGRA_8888_GrPixelConfig:
@@ -1003,6 +1005,7 @@
return 2;
case kRGBA_8888_GrPixelConfig:
case kRGB_888_GrPixelConfig: // Assuming GPUs store this 4-byte aligned.
+ case kRGB_888X_GrPixelConfig:
case kBGRA_8888_GrPixelConfig:
case kSRGBA_8888_GrPixelConfig:
case kSBGRA_8888_GrPixelConfig:
@@ -1026,6 +1029,7 @@
switch (config) {
case kRGB_565_GrPixelConfig:
case kRGB_888_GrPixelConfig:
+ case kRGB_888X_GrPixelConfig:
case kRG_88_GrPixelConfig:
case kGray_8_GrPixelConfig:
case kGray_8_as_Lum_GrPixelConfig:
@@ -1069,6 +1073,7 @@
case kRGBA_4444_GrPixelConfig:
case kRGBA_8888_GrPixelConfig:
case kRGB_888_GrPixelConfig:
+ case kRGB_888X_GrPixelConfig:
case kRG_88_GrPixelConfig:
case kBGRA_8888_GrPixelConfig:
case kSRGBA_8888_GrPixelConfig:
@@ -1096,6 +1101,7 @@
case kRGB_565_GrPixelConfig:
case kRGBA_4444_GrPixelConfig:
case kRGB_888_GrPixelConfig:
+ case kRGB_888X_GrPixelConfig:
case kRG_88_GrPixelConfig:
case kRGBA_8888_GrPixelConfig:
case kBGRA_8888_GrPixelConfig:
@@ -1133,6 +1139,7 @@
case kRGB_565_GrPixelConfig:
case kRGBA_4444_GrPixelConfig:
case kRGB_888_GrPixelConfig:
+ case kRGB_888X_GrPixelConfig:
case kRG_88_GrPixelConfig:
case kRGBA_8888_GrPixelConfig:
case kBGRA_8888_GrPixelConfig:
@@ -1167,6 +1174,7 @@
case kRGB_565_GrPixelConfig:
case kRGBA_4444_GrPixelConfig:
case kRGB_888_GrPixelConfig:
+ case kRGB_888X_GrPixelConfig:
case kRG_88_GrPixelConfig:
case kRGBA_8888_GrPixelConfig:
case kBGRA_8888_GrPixelConfig:
@@ -1207,6 +1215,7 @@
case kRGB_565_GrPixelConfig:
case kRGBA_4444_GrPixelConfig:
case kRGB_888_GrPixelConfig:
+ case kRGB_888X_GrPixelConfig:
case kRG_88_GrPixelConfig:
case kRGBA_8888_GrPixelConfig:
case kBGRA_8888_GrPixelConfig:
@@ -1242,6 +1251,7 @@
case kRGBA_4444_GrPixelConfig:
case kRGBA_8888_GrPixelConfig:
case kRGB_888_GrPixelConfig:
+ case kRGB_888X_GrPixelConfig:
case kRG_88_GrPixelConfig:
case kBGRA_8888_GrPixelConfig:
case kSRGBA_8888_GrPixelConfig:
@@ -1405,6 +1415,9 @@
case kRGB_888_GrPixelConfig:
*srgbEncoded = GrSRGBEncoded::kNo;
return GrColorType::kRGB_888x;
+ case kRGB_888X_GrPixelConfig:
+ *srgbEncoded = GrSRGBEncoded::kNo;
+ return GrColorType::kRGB_888x;
case kRG_88_GrPixelConfig:
*srgbEncoded = GrSRGBEncoded::kNo;
return GrColorType::kRG_88;
diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp
index 638a70f..ec8c872 100644
--- a/src/gpu/GrCaps.cpp
+++ b/src/gpu/GrCaps.cpp
@@ -138,6 +138,7 @@
case kRGBA_4444_GrPixelConfig: return "RGBA444";
case kRGBA_8888_GrPixelConfig: return "RGBA8888";
case kRGB_888_GrPixelConfig: return "RGB888";
+ case kRGB_888X_GrPixelConfig: return "RGB888X";
case kRG_88_GrPixelConfig: return "RG88";
case kBGRA_8888_GrPixelConfig: return "BGRA8888";
case kSRGBA_8888_GrPixelConfig: return "SRGBA8888";
diff --git a/src/gpu/GrContextPriv.cpp b/src/gpu/GrContextPriv.cpp
index b502bf8..1ba47c8 100644
--- a/src/gpu/GrContextPriv.cpp
+++ b/src/gpu/GrContextPriv.cpp
@@ -282,6 +282,7 @@
case kRGBA_4444_GrPixelConfig: return true;
case kRGBA_8888_GrPixelConfig: return true;
case kRGB_888_GrPixelConfig: return false;
+ case kRGB_888X_GrPixelConfig: return false;
case kRG_88_GrPixelConfig: return false;
case kBGRA_8888_GrPixelConfig: return true;
case kSRGBA_8888_GrPixelConfig: return true;
diff --git a/src/gpu/GrProgramDesc.cpp b/src/gpu/GrProgramDesc.cpp
index 952dc00..f39b666 100644
--- a/src/gpu/GrProgramDesc.cpp
+++ b/src/gpu/GrProgramDesc.cpp
@@ -39,72 +39,60 @@
return SkToU16(value);
}
-static uint16_t sampler_key(GrTextureType textureType, GrPixelConfig config,
+static uint32_t sampler_key(GrTextureType textureType, GrPixelConfig config,
const GrShaderCaps& caps) {
int samplerTypeKey = texture_type_key(textureType);
- GR_STATIC_ASSERT(1 == sizeof(caps.configTextureSwizzle(config).asKey()));
- return SkToU16(samplerTypeKey |
+ GR_STATIC_ASSERT(2 == sizeof(caps.configTextureSwizzle(config).asKey()));
+ return SkToU32(samplerTypeKey |
caps.configTextureSwizzle(config).asKey() << kSamplerOrImageTypeKeyBits |
- (GrSLSamplerPrecision(config) << (8 + kSamplerOrImageTypeKeyBits)));
+ (GrSLSamplerPrecision(config) << (16 + kSamplerOrImageTypeKeyBits)));
}
static void add_sampler_keys(GrProcessorKeyBuilder* b, const GrFragmentProcessor& fp,
GrGpu* gpu, const GrShaderCaps& caps) {
int numTextureSamplers = fp.numTextureSamplers();
- // Need two bytes per key.
- int word32Count = (numTextureSamplers + 1) / 2;
- if (0 == word32Count) {
+ if (!numTextureSamplers) {
return;
}
- uint16_t* k16 = reinterpret_cast<uint16_t*>(b->add32n(word32Count));
+ uint32_t* k32 = b->add32n(numTextureSamplers);
for (int i = 0; i < numTextureSamplers; ++i) {
const GrFragmentProcessor::TextureSampler& sampler = fp.textureSampler(i);
const GrTexture* tex = sampler.peekTexture();
- k16[i] = sampler_key(tex->texturePriv().textureType(), tex->config(), caps);
+ k32[i] = sampler_key(tex->texturePriv().textureType(), tex->config(), caps);
uint32_t extraSamplerKey = gpu->getExtraSamplerKeyForProgram(
sampler.samplerState(), sampler.proxy()->backendFormat());
if (extraSamplerKey) {
SkASSERT(sampler.proxy()->textureType() == GrTextureType::kExternal);
// We first mark the normal sampler key with last bit to flag that it has an extra
// sampler key. We then add all the extraSamplerKeys to the end of the normal ones.
- SkASSERT((k16[i] & (1 << 15)) == 0);
- k16[i] = k16[i] | (1 << 15);
+ SkASSERT((k32[i] & (1 << 31)) == 0);
+ k32[i] = k32[i] | (1 << 31);
b->add32(extraSamplerKey);
}
}
- // zero the last 16 bits if the number of uniforms for samplers is odd.
- if (numTextureSamplers & 0x1) {
- k16[numTextureSamplers] = 0;
- }
}
static void add_sampler_keys(GrProcessorKeyBuilder* b, const GrPrimitiveProcessor& pp,
const GrShaderCaps& caps) {
int numTextureSamplers = pp.numTextureSamplers();
- // Need two bytes per key.
- int word32Count = (numTextureSamplers + 1) / 2;
- if (0 == word32Count) {
+ if (!numTextureSamplers) {
return;
}
- uint16_t* k16 = reinterpret_cast<uint16_t*>(b->add32n(word32Count));
+ uint32_t* k32 = b->add32n(numTextureSamplers);
for (int i = 0; i < numTextureSamplers; ++i) {
const GrPrimitiveProcessor::TextureSampler& sampler = pp.textureSampler(i);
- k16[i] = sampler_key(sampler.textureType(), sampler.config(), caps);
+ k32[i] = sampler_key(sampler.textureType(), sampler.config(), caps);
uint32_t extraSamplerKey = sampler.extraSamplerKey();
if (extraSamplerKey) {
SkASSERT(sampler.textureType() == GrTextureType::kExternal);
// We first mark the normal sampler key with last bit to flag that it has an extra
// sampler key. We then add all the extraSamplerKeys to the end of the normal ones.
- SkASSERT((k16[i] & (1 << 15)) == 0);
- k16[i] = k16[i] | (1 << 15);
+ SkASSERT((k32[i] & (1 << 15)) == 0);
+ k32[i] = k32[i] | (1 << 15);
b->add32(extraSamplerKey);
}
}
- // zero the last 16 bits if the number of uniforms for samplers is odd.
- if (numTextureSamplers & 0x1) {
- k16[numTextureSamplers] = 0;
- }
}
/**
diff --git a/src/gpu/GrProgramDesc.h b/src/gpu/GrProgramDesc.h
index 08e03c9..274fcef 100644
--- a/src/gpu/GrProgramDesc.h
+++ b/src/gpu/GrProgramDesc.h
@@ -92,7 +92,7 @@
struct KeyHeader {
// Set to uniquely idenitify any swizzling of the shader's output color(s).
- uint8_t fOutputSwizzle;
+ uint16_t fOutputSwizzle;
uint8_t fColorFragmentProcessorCnt; // Can be packed into 4 bits if required.
uint8_t fCoverageFragmentProcessorCnt;
// Set to uniquely identify the rt's origin, or 0 if the shader does not require this info.
@@ -101,7 +101,7 @@
bool fHasPointSize : 1;
uint8_t fPad : 4;
};
- GR_STATIC_ASSERT(sizeof(KeyHeader) == 4);
+ GR_STATIC_ASSERT(sizeof(KeyHeader) == 6);
// This should really only be used internally, base classes should return their own headers
const KeyHeader& header() const { return *this->atOffset<KeyHeader, kHeaderOffset>(); }
diff --git a/src/gpu/GrSwizzle.h b/src/gpu/GrSwizzle.h
index 109c3a6..469740b 100644
--- a/src/gpu/GrSwizzle.h
+++ b/src/gpu/GrSwizzle.h
@@ -33,11 +33,11 @@
}
/** Recreates a GrSwizzle from the output of asKey() */
- constexpr void setFromKey(uint8_t key) {
+ constexpr void setFromKey(uint16_t key) {
fKey = key;
for (int i = 0; i < 4; ++i) {
- fSwiz[i] = IToC(key & 3);
- key >>= 2;
+ fSwiz[i] = IToC(key & 15);
+ key >>= 4;
}
SkASSERT(fSwiz[4] == 0);
}
@@ -46,7 +46,7 @@
constexpr bool operator!=(const GrSwizzle& that) const { return !(*this == that); }
/** Compact representation of the swizzle suitable for a key. */
- constexpr uint8_t asKey() const { return fKey; }
+ constexpr uint16_t asKey() const { return fKey; }
/** 4 char null terminated string consisting only of chars 'r', 'g', 'b', 'a'. */
const char* c_str() const { return fSwiz; }
@@ -56,22 +56,38 @@
return fSwiz[i];
}
+
+ // The normal component swizzles map to key values 0-3. We set the key for constant 1 to the
+ // next int.
+ static const int k1KeyValue = 4;
+
+ static float component_idx_to_float(const SkPMColor4f& color, int idx) {
+ if (idx <= 3) {
+ return color[idx];
+ }
+ if (idx == k1KeyValue) {
+ return 1.0f;
+ }
+ SK_ABORT("Unexpected swizzle component indx");
+ return -1.0f;
+ }
+
/** Applies this swizzle to the input color and returns the swizzled color. */
SkPMColor4f applyTo(const SkPMColor4f& color) const {
int idx;
uint32_t key = fKey;
// Index of the input color that should be mapped to output r.
- idx = (key & 3);
- float outR = color[idx];
- key >>= 2;
- idx = (key & 3);
- float outG = color[idx];
- key >>= 2;
- idx = (key & 3);
- float outB = color[idx];
- key >>= 2;
- idx = (key & 3);
- float outA = color[idx];
+ idx = (key & 15);
+ float outR = component_idx_to_float(color, idx);
+ key >>= 4;
+ idx = (key & 15);
+ float outG = component_idx_to_float(color, idx);
+ key >>= 4;
+ idx = (key & 15);
+ float outB = component_idx_to_float(color, idx);
+ key >>= 4;
+ idx = (key & 15);
+ float outA = component_idx_to_float(color, idx);
return { outR, outG, outB, outA };
}
@@ -81,10 +97,11 @@
static constexpr GrSwizzle RRRA() { return GrSwizzle("rrra"); }
static constexpr GrSwizzle BGRA() { return GrSwizzle("bgra"); }
static constexpr GrSwizzle RGRG() { return GrSwizzle("rgrg"); }
+ static constexpr GrSwizzle RGB1() { return GrSwizzle("rgb1"); }
private:
char fSwiz[5];
- uint8_t fKey;
+ uint16_t fKey;
static constexpr int CToI(char c) {
switch (c) {
@@ -92,23 +109,25 @@
case 'g': return (GrColor_SHIFT_G / 8);
case 'b': return (GrColor_SHIFT_B / 8);
case 'a': return (GrColor_SHIFT_A / 8);
+ case '1': return k1KeyValue;
default: return -1;
}
}
static constexpr char IToC(int idx) {
switch (8 * idx) {
- case GrColor_SHIFT_R : return 'r';
- case GrColor_SHIFT_G : return 'g';
- case GrColor_SHIFT_B : return 'b';
- case GrColor_SHIFT_A : return 'a';
- default: return -1;
+ case GrColor_SHIFT_R : return 'r';
+ case GrColor_SHIFT_G : return 'g';
+ case GrColor_SHIFT_B : return 'b';
+ case GrColor_SHIFT_A : return 'a';
+ case (k1KeyValue * 8) : return '1';
+ default: return -1;
}
}
constexpr GrSwizzle(const char c[4])
: fSwiz{c[0], c[1], c[2], c[3], '\0'}
- , fKey((CToI(c[0]) << 0) | (CToI(c[1]) << 2) | (CToI(c[2]) << 4) | (CToI(c[3]) << 6)) {}
+ , fKey((CToI(c[0]) << 0) | (CToI(c[1]) << 4) | (CToI(c[2]) << 8) | (CToI(c[3]) << 12)) {}
};
#endif
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index dd18074..5994657 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -341,6 +341,7 @@
case kGray_8_as_Red_GrPixelConfig:
case kRGBA_8888_GrPixelConfig:
case kRGB_888_GrPixelConfig:
+ case kRGB_888X_GrPixelConfig:
case kRG_88_GrPixelConfig:
case kBGRA_8888_GrPixelConfig:
return 0;
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index a3da939..31a05d1 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -1480,6 +1480,13 @@
fConfigTable[kRGB_888_GrPixelConfig].fFlags = 0;
}
+ fConfigTable[kRGB_888X_GrPixelConfig] = fConfigTable[kRGBA_8888_GrPixelConfig];
+ fConfigTable[kRGB_888X_GrPixelConfig].fSwizzle = GrSwizzle::RGB1();
+ // Currently we don't allow RGB_888X to be renderable because we don't have a way to handle
+ // blends that reference the dst alpha when the values in the dst alpha channel are
+ // uninitialized.
+ fConfigTable[kRGB_888X_GrPixelConfig].fFlags = ConfigInfo::kTextureable_Flag;
+
// ES2 Command Buffer has several TexStorage restrictions. It appears to fail for any format
// not explicitly allowed by GL_EXT_texture_storage, particularly those from other extensions.
bool isCommandBufferES2 = kChromium_GrGLDriver == ctxInfo.driver() && version < GR_GL_VER(3, 0);
@@ -2850,6 +2857,9 @@
// this as makes sense to increase performance and correctness.
switch (fConfigTable[config].fFormatType) {
case kNormalizedFixedPoint_FormatType:
+ if (kRGB_888X_GrPixelConfig == config) {
+ return GrColorType::kRGB_888x;
+ }
return GrColorType::kRGBA_8888;
case kFloat_FormatType:
if ((kAlpha_half_GrPixelConfig == config ||
@@ -2939,6 +2949,8 @@
case kRGB_888x_SkColorType:
if (GR_GL_RGB8 == format) {
return kRGB_888_GrPixelConfig;
+ } else if (GR_GL_RGBA8 == format) {
+ return kRGB_888X_GrPixelConfig;
}
break;
case kBGRA_8888_SkColorType:
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 7c4e12c..ebda8ac 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -870,6 +870,7 @@
return 2;
case kRGBA_8888_GrPixelConfig:
case kRGB_888_GrPixelConfig: // We're really talking about GrColorType::kRGB_888x here.
+ case kRGB_888X_GrPixelConfig:
case kBGRA_8888_GrPixelConfig:
case kSRGBA_8888_GrPixelConfig:
case kSBGRA_8888_GrPixelConfig:
diff --git a/src/gpu/mtl/GrMtlCaps.mm b/src/gpu/mtl/GrMtlCaps.mm
index 0ef3031..45ceb50 100644
--- a/src/gpu/mtl/GrMtlCaps.mm
+++ b/src/gpu/mtl/GrMtlCaps.mm
@@ -304,6 +304,8 @@
} else {
if (kGray_8_GrPixelConfig == config) {
shaderCaps->fConfigTextureSwizzle[i] = GrSwizzle::RRRA();
+ } else if (kRGB_888X_GrPixelConfig == config) {
+ shaderCaps->fConfigTextureSwizzle[i] = GrSwizzle::RGB1();
} else {
shaderCaps->fConfigTextureSwizzle[i] = GrSwizzle::RGBA();
}
@@ -382,6 +384,10 @@
info = &fConfigTable[kRGBA_8888_GrPixelConfig];
info->fFlags = ConfigInfo::kAllFlags;
+ // RGB_888X uses RGBA8Unorm and we will swizzle the 1
+ info = &fConfigTable[kRGB_888X_GrPixelConfig];
+ info->fFlags = ConfigInfo::kTextureable_Flag;
+
// BGRA_8888 uses BGRA8Unorm
info = &fConfigTable[kBGRA_8888_GrPixelConfig];
info->fFlags = ConfigInfo::kAllFlags;
@@ -460,6 +466,9 @@
}
break;
case kRGB_888x_SkColorType:
+ if (MTLPixelFormatRGBA8Unorm == format) {
+ return kRGB_888X_GrPixelConfig;
+ }
break;
case kBGRA_8888_SkColorType:
if (MTLPixelFormatBGRA8Unorm == format) {
diff --git a/src/gpu/mtl/GrMtlUtil.h b/src/gpu/mtl/GrMtlUtil.h
index fa43295..a622534 100644
--- a/src/gpu/mtl/GrMtlUtil.h
+++ b/src/gpu/mtl/GrMtlUtil.h
@@ -22,11 +22,6 @@
bool GrPixelConfigToMTLFormat(GrPixelConfig config, MTLPixelFormat* format);
/**
-* Returns the GrPixelConfig for the given Metal texture format
-*/
-GrPixelConfig GrMTLFormatToPixelConfig(MTLPixelFormat format);
-
-/**
* Returns a id<MTLTexture> to the MTLTexture pointed at by the const void*. Will use
* __bridge_transfer if we are adopting ownership.
*/
diff --git a/src/gpu/mtl/GrMtlUtil.mm b/src/gpu/mtl/GrMtlUtil.mm
index 824bbf5..6739b51 100644
--- a/src/gpu/mtl/GrMtlUtil.mm
+++ b/src/gpu/mtl/GrMtlUtil.mm
@@ -33,6 +33,9 @@
case kRGB_888_GrPixelConfig:
// TODO: MTLPixelFormatRGB8Unorm
return false;
+ case kRGB_888X_GrPixelConfig:
+ *format = MTLPixelFormatRGBA8Unorm;
+ return true;
case kRG_88_GrPixelConfig:
// TODO: MTLPixelFormatRG8Unorm
return false;
@@ -99,46 +102,6 @@
return false;
}
-GrPixelConfig GrMTLFormatToPixelConfig(MTLPixelFormat format) {
- switch (format) {
- case MTLPixelFormatRGBA8Unorm:
- return kRGBA_8888_GrPixelConfig;
- case MTLPixelFormatBGRA8Unorm:
- return kBGRA_8888_GrPixelConfig;
- case MTLPixelFormatRGBA8Unorm_sRGB:
- return kSRGBA_8888_GrPixelConfig;
- case MTLPixelFormatBGRA8Unorm_sRGB:
- return kSBGRA_8888_GrPixelConfig;
- case MTLPixelFormatRGB10A2Unorm:
- return kRGBA_1010102_GrPixelConfig;
-#ifdef SK_BUILD_FOR_IOS
- case MTLPixelFormatB5G6R5Unorm:
- return kRGB_565_GrPixelConfig;
- case MTLPixelFormatABGR4Unorm:
- return kRGBA_4444_GrPixelConfig;
-#endif
- case MTLPixelFormatRG8Unorm:
- return kRG_88_GrPixelConfig;
- case MTLPixelFormatR8Unorm:
- // We currently set this to be Alpha_8 and have no way to go to Gray_8
- return kAlpha_8_GrPixelConfig;
- case MTLPixelFormatRGBA32Float:
- return kRGBA_float_GrPixelConfig;
- case MTLPixelFormatRG32Float:
- return kRG_float_GrPixelConfig;
- case MTLPixelFormatRGBA16Float:
- return kRGBA_half_GrPixelConfig;
- case MTLPixelFormatR16Float:
- return kAlpha_half_GrPixelConfig;
-#ifdef SK_BUILD_FOR_IOS
- case MTLPixelFormatETC2_RGB8:
- return kRGB_ETC1_GrPixelConfig;
-#endif
- default:
- return kUnknown_GrPixelConfig;
- }
-}
-
id<MTLTexture> GrGetMTLTexture(const void* mtlTexture, GrWrapOwnership wrapOwnership) {
if (GrWrapOwnership::kAdopt_GrWrapOwnership == wrapOwnership) {
return (__bridge_transfer id<MTLTexture>)mtlTexture;
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index 1123325..55f632a 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -517,6 +517,8 @@
// only extra work is the swizzle in the shader for all operations.
shaderCaps->fConfigTextureSwizzle[i] = GrSwizzle::BGRA();
shaderCaps->fConfigOutputSwizzle[i] = GrSwizzle::BGRA();
+ } else if (kRGB_888X_GrPixelConfig == config) {
+ shaderCaps->fConfigTextureSwizzle[i] = GrSwizzle::RGB1();
} else {
shaderCaps->fConfigTextureSwizzle[i] = GrSwizzle::RGBA();
}
@@ -593,19 +595,27 @@
VkFormat format;
if (GrPixelConfigToVkFormat(static_cast<GrPixelConfig>(i), &format)) {
if (!GrPixelConfigIsSRGB(static_cast<GrPixelConfig>(i)) || fSRGBSupport) {
- fConfigTable[i].init(interface, physDev, properties, format);
+ bool disableRendering = false;
+ if (static_cast<GrPixelConfig>(i) == kRGB_888X_GrPixelConfig) {
+ // Currently we don't allow RGB_888X to be renderable because we don't have a
+ // way to handle blends that reference dst alpha when the values in the dst
+ // alpha channel are uninitialized.
+ disableRendering = true;
+ }
+ fConfigTable[i].init(interface, physDev, properties, format, disableRendering);
}
}
}
}
-void GrVkCaps::ConfigInfo::InitConfigFlags(VkFormatFeatureFlags vkFlags, uint16_t* flags) {
+void GrVkCaps::ConfigInfo::InitConfigFlags(VkFormatFeatureFlags vkFlags, uint16_t* flags,
+ bool disableRendering) {
if (SkToBool(VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT & vkFlags) &&
SkToBool(VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT & vkFlags)) {
*flags = *flags | kTextureable_Flag;
// Ganesh assumes that all renderable surfaces are also texturable
- if (SkToBool(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT & vkFlags)) {
+ if (SkToBool(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT & vkFlags) & !disableRendering) {
*flags = *flags | kRenderable_Flag;
}
}
@@ -666,12 +676,13 @@
void GrVkCaps::ConfigInfo::init(const GrVkInterface* interface,
VkPhysicalDevice physDev,
const VkPhysicalDeviceProperties& properties,
- VkFormat format) {
+ VkFormat format,
+ bool disableRendering) {
VkFormatProperties props;
memset(&props, 0, sizeof(VkFormatProperties));
GR_VK_CALL(interface, GetPhysicalDeviceFormatProperties(physDev, format, &props));
- InitConfigFlags(props.linearTilingFeatures, &fLinearFlags);
- InitConfigFlags(props.optimalTilingFeatures, &fOptimalFlags);
+ InitConfigFlags(props.linearTilingFeatures, &fLinearFlags, disableRendering);
+ InitConfigFlags(props.optimalTilingFeatures, &fOptimalFlags, disableRendering);
if (fOptimalFlags & kRenderable_Flag) {
this->initSampleCounts(interface, physDev, properties, format);
}
@@ -762,6 +773,9 @@
if (VK_FORMAT_R8G8B8_UNORM == format) {
return kRGB_888_GrPixelConfig;
}
+ if (VK_FORMAT_R8G8B8A8_UNORM == format) {
+ return kRGB_888X_GrPixelConfig;
+ }
break;
case kBGRA_8888_SkColorType:
if (VK_FORMAT_B8G8R8A8_UNORM == format) {
diff --git a/src/gpu/vk/GrVkCaps.h b/src/gpu/vk/GrVkCaps.h
index 2309541..41c31fb 100644
--- a/src/gpu/vk/GrVkCaps.h
+++ b/src/gpu/vk/GrVkCaps.h
@@ -191,8 +191,8 @@
ConfigInfo() : fOptimalFlags(0), fLinearFlags(0) {}
void init(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&,
- VkFormat);
- static void InitConfigFlags(VkFormatFeatureFlags, uint16_t* flags);
+ VkFormat, bool disableRendering);
+ static void InitConfigFlags(VkFormatFeatureFlags, uint16_t* flags, bool disableRendering);
void initSampleCounts(const GrVkInterface*, VkPhysicalDevice,
const VkPhysicalDeviceProperties&, VkFormat);
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 3a820d9..934d858 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -611,9 +611,8 @@
// For RGB_888x src data we are uploading it first to an RGBA texture and then copying it to the
// dst RGB texture. Thus we do not upload mip levels for that.
- if (dataColorType == GrColorType::kRGB_888x) {
- SkASSERT(tex->imageFormat() == VK_FORMAT_R8G8B8_UNORM &&
- tex->config() == kRGB_888_GrPixelConfig);
+ if (dataColorType == GrColorType::kRGB_888x && tex->imageFormat() == VK_FORMAT_R8G8B8_UNORM) {
+ SkASSERT(tex->config() == kRGB_888_GrPixelConfig);
// First check that we'll be able to do the copy to the to the R8G8B8 image in the end via a
// blit or draw.
if (!this->vkCaps().configCanBeDstofBlit(kRGB_888_GrPixelConfig, tex->isLinearTiled()) &&
@@ -681,7 +680,7 @@
// For uploading RGB_888x data to an R8G8B8_UNORM texture we must first upload the data to an
// R8G8B8A8_UNORM image and then copy it.
sk_sp<GrVkTexture> copyTexture;
- if (dataColorType == GrColorType::kRGB_888x) {
+ if (dataColorType == GrColorType::kRGB_888x && tex->imageFormat() == VK_FORMAT_R8G8B8_UNORM) {
GrSurfaceDesc surfDesc;
surfDesc.fFlags = kRenderTarget_GrSurfaceFlag;
surfDesc.fWidth = width;
@@ -2066,9 +2065,8 @@
// 32 bits, but the Vulkan format is only 24. So we first copy the surface into an R8G8B8A8
// image and then do the read pixels from that.
sk_sp<GrVkTextureRenderTarget> copySurface;
- if (dstColorType == GrColorType::kRGB_888x) {
- SkASSERT(image->imageFormat() == VK_FORMAT_R8G8B8_UNORM &&
- surface->config() == kRGB_888_GrPixelConfig);
+ if (dstColorType == GrColorType::kRGB_888x && image->imageFormat() == VK_FORMAT_R8G8B8_UNORM) {
+ SkASSERT(surface->config() == kRGB_888_GrPixelConfig);
// Make a new surface that is RGBA to copy the RGB surface into.
GrSurfaceDesc surfDesc;
diff --git a/src/gpu/vk/GrVkUtil.cpp b/src/gpu/vk/GrVkUtil.cpp
index 8dffe4c..cf8b9ec 100644
--- a/src/gpu/vk/GrVkUtil.cpp
+++ b/src/gpu/vk/GrVkUtil.cpp
@@ -25,6 +25,9 @@
case kRGB_888_GrPixelConfig:
*format = VK_FORMAT_R8G8B8_UNORM;
return true;
+ case kRGB_888X_GrPixelConfig:
+ *format = VK_FORMAT_R8G8B8A8_UNORM;
+ return true;
case kRG_88_GrPixelConfig:
*format = VK_FORMAT_R8G8_UNORM;
return true;
@@ -86,7 +89,8 @@
bool GrVkFormatPixelConfigPairIsValid(VkFormat format, GrPixelConfig config) {
switch (format) {
case VK_FORMAT_R8G8B8A8_UNORM:
- return kRGBA_8888_GrPixelConfig == config;
+ return kRGBA_8888_GrPixelConfig == config ||
+ kRGB_888X_GrPixelConfig == config;
case VK_FORMAT_B8G8R8A8_UNORM:
return kBGRA_8888_GrPixelConfig == config;
case VK_FORMAT_R8G8B8A8_SRGB:
diff --git a/tests/GrSurfaceTest.cpp b/tests/GrSurfaceTest.cpp
index e62d953..95f3794 100644
--- a/tests/GrSurfaceTest.cpp
+++ b/tests/GrSurfaceTest.cpp
@@ -88,6 +88,7 @@
kRGBA_4444_GrPixelConfig,
kRGBA_8888_GrPixelConfig,
kRGB_888_GrPixelConfig,
+ kRGB_888X_GrPixelConfig,
kRG_88_GrPixelConfig,
kBGRA_8888_GrPixelConfig,
kSRGBA_8888_GrPixelConfig,