aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--bench/nanobench.cpp17
-rw-r--r--include/gpu/GrCaps.h19
-rw-r--r--include/gpu/gl/GrGLFunctions.h3
-rw-r--r--include/gpu/gl/GrGLInterface.h3
-rw-r--r--src/gpu/GrContext.cpp3
-rw-r--r--src/gpu/GrGpu.cpp2
-rw-r--r--src/gpu/GrSurfaceProxy.cpp2
-rw-r--r--src/gpu/SkGr.cpp10
-rw-r--r--src/gpu/SkGr.h1
-rw-r--r--src/gpu/gl/GrGLAssembleInterface.cpp9
-rw-r--r--src/gpu/gl/GrGLCaps.cpp55
-rw-r--r--src/gpu/gl/GrGLCaps.h6
-rw-r--r--src/gpu/gl/GrGLDefines.h3
-rw-r--r--src/gpu/gl/GrGLGpu.cpp6
-rw-r--r--src/gpu/gl/GrGLInterface.cpp9
-rw-r--r--src/gpu/gl/GrGLTestInterface.cpp1
-rw-r--r--src/gpu/gl/GrGLTestInterface.h1
-rw-r--r--src/gpu/gl/GrGLUtil.h6
-rw-r--r--src/gpu/mock/GrMockCaps.h3
-rw-r--r--src/gpu/vk/GrVkCaps.cpp59
-rw-r--r--src/gpu/vk/GrVkCaps.h5
-rw-r--r--src/gpu/vk/GrVkGpu.cpp4
-rw-r--r--tests/GLProgramsTest.cpp2
-rw-r--r--tests/GpuSampleLocationsTest.cpp3
-rw-r--r--tests/ProxyTest.cpp9
-rw-r--r--tests/ResourceCacheTest.cpp38
-rw-r--r--tools/skpbench/skpbench.cpp12
27 files changed, 232 insertions, 59 deletions
diff --git a/bench/nanobench.cpp b/bench/nanobench.cpp
index 8cbaa2339a..7148bc26fd 100644
--- a/bench/nanobench.cpp
+++ b/bench/nanobench.cpp
@@ -61,6 +61,7 @@ extern bool gSkForceRasterPipelineBlitter;
#include "GrCaps.h"
#include "GrContextFactory.h"
#include "gl/GrGLUtil.h"
+ #include "SkGr.h"
using sk_gpu_test::GrContextFactory;
using sk_gpu_test::TestContext;
std::unique_ptr<GrContextFactory> gGrFactory;
@@ -416,12 +417,16 @@ static void create_config(const SkCommandLineConfig* config, SkTArray<Config>* c
const auto ctxType = gpuConfig->getContextType();
const auto ctxOverrides = gpuConfig->getContextOverrides();
const auto sampleCount = gpuConfig->getSamples();
+ const auto colorType = gpuConfig->getColorType();
+ auto colorSpace = gpuConfig->getColorSpace();
if (const GrContext* ctx = gGrFactory->get(ctxType, ctxOverrides)) {
- const auto maxSampleCount = ctx->caps()->maxSampleCount();
- if (sampleCount > ctx->caps()->maxSampleCount()) {
- SkDebugf("Configuration sample count %d exceeds maximum %d.\n",
- sampleCount, maxSampleCount);
+ GrPixelConfig grPixConfig = SkImageInfo2GrPixelConfig(colorType, colorSpace,
+ *ctx->caps());
+ int supportedSampleCount = ctx->caps()->getSampleCount(sampleCount, grPixConfig);
+ if (sampleCount != supportedSampleCount) {
+ SkDebugf("Configuration sample count %d is not a supported sample count.\n",
+ sampleCount);
return;
}
} else {
@@ -432,9 +437,9 @@ static void create_config(const SkCommandLineConfig* config, SkTArray<Config>* c
Config target = {
gpuConfig->getTag(),
Benchmark::kGPU_Backend,
- gpuConfig->getColorType(),
+ colorType,
kPremul_SkAlphaType,
- sk_ref_sp(gpuConfig->getColorSpace()),
+ sk_ref_sp(colorSpace),
sampleCount,
ctxType,
ctxOverrides,
diff --git a/include/gpu/GrCaps.h b/include/gpu/GrCaps.h
index cc24846091..a1a1826676 100644
--- a/include/gpu/GrCaps.h
+++ b/include/gpu/GrCaps.h
@@ -132,22 +132,11 @@ public:
It is usually the max texture size, unless we're overriding it for testing. */
int maxTileSize() const { SkASSERT(fMaxTileSize <= fMaxTextureSize); return fMaxTileSize; }
- // Will be 0 if MSAA is not supported
- int maxColorSampleCount() const { return fMaxColorSampleCount; }
- // Will be 0 if MSAA is not supported
- int maxStencilSampleCount() const { return fMaxStencilSampleCount; }
- // Will be 0 if raster multisample is not supported. Raster multisample is a special HW mode
- // where the rasterizer runs with more samples than are in the target framebuffer.
int maxRasterSamples() const { return fMaxRasterSamples; }
- // We require the sample count to be less than maxColorSampleCount and maxStencilSampleCount.
- // If we are using mixed samples, we only care about stencil.
- int maxSampleCount() const {
- if (this->usesMixedSamples()) {
- return this->maxStencilSampleCount();
- } else {
- return SkTMin(this->maxColorSampleCount(), this->maxStencilSampleCount());
- }
- }
+
+ // Find a sample count greater than or equal to the requested count which is supported for a
+ // color buffer of the given config. If MSAA is not support for the config we will return 0.
+ virtual int getSampleCount(int requestedCount, GrPixelConfig config) const = 0;
int maxWindowRectangles() const { return fMaxWindowRectangles; }
diff --git a/include/gpu/gl/GrGLFunctions.h b/include/gpu/gl/GrGLFunctions.h
index 930a0c1aad..5166a4b099 100644
--- a/include/gpu/gl/GrGLFunctions.h
+++ b/include/gpu/gl/GrGLFunctions.h
@@ -357,6 +357,9 @@ typedef GrGLenum (GR_GL_FUNCTION_TYPE* GrGLClientWaitSyncProc)(GrGLsync sync, Gr
typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLWaitSyncProc)(GrGLsync sync, GrGLbitfield flags, GrGLuint64 timeout);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDeleteSyncProc)(GrGLsync sync);
+/* ARB_internalformat_query */
+typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetInternalformativProc)(GrGLenum target, GrGLenum internalformat, GrGLenum pname, GrGLsizei bufSize, GrGLint *params);
+
/* KHR_debug */
typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDebugMessageControlProc)(GrGLenum source, GrGLenum type, GrGLenum severity, GrGLsizei count, const GrGLuint* ids, GrGLboolean enabled);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDebugMessageInsertProc)(GrGLenum source, GrGLenum type, GrGLuint id, GrGLenum severity, GrGLsizei length, const GrGLchar* buf);
diff --git a/include/gpu/gl/GrGLInterface.h b/include/gpu/gl/GrGLInterface.h
index e5479eb466..10880471ce 100644
--- a/include/gpu/gl/GrGLInterface.h
+++ b/include/gpu/gl/GrGLInterface.h
@@ -460,6 +460,9 @@ public:
GrGLFunction<GrGLWaitSyncProc> fWaitSync;
GrGLFunction<GrGLDeleteSyncProc> fDeleteSync;
+ /* ARB_internalforamt_query */
+ GrGLFunction<GrGLGetInternalformativProc> fGetInternalformativ;
+
/* KHR_debug */
GrGLFunction<GrGLDebugMessageControlProc> fDebugMessageControl;
GrGLFunction<GrGLDebugMessageInsertProc> fDebugMessageInsert;
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 0c227e3f32..ecf4398288 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -636,7 +636,8 @@ int GrContext::getRecommendedSampleCount(GrPixelConfig config,
chosenSampleCount = 16;
}
}
- return chosenSampleCount <= fGpu->caps()->maxSampleCount() ? chosenSampleCount : 0;
+ int supportedSampleCount = fGpu->caps()->getSampleCount(chosenSampleCount, config);
+ return chosenSampleCount <= supportedSampleCount ? supportedSampleCount : 0;
}
sk_sp<GrSurfaceContext> GrContextPriv::makeWrappedSurfaceContext(sk_sp<GrSurfaceProxy> proxy,
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index cab5d15458..038ffef0cd 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -143,7 +143,7 @@ sk_sp<GrTexture> GrGpu::createTexture(const GrSurfaceDesc& origDesc, SkBudgeted
return nullptr;
}
- desc.fSampleCnt = SkTMin(desc.fSampleCnt, caps->maxSampleCount());
+ desc.fSampleCnt = caps->getSampleCount(desc.fSampleCnt, desc.fConfig);
// Attempt to catch un- or wrongly initialized sample counts.
SkASSERT(desc.fSampleCnt >= 0 && desc.fSampleCnt <= 64);
diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp
index b07366265c..f300770690 100644
--- a/src/gpu/GrSurfaceProxy.cpp
+++ b/src/gpu/GrSurfaceProxy.cpp
@@ -185,7 +185,7 @@ sk_sp<GrTextureProxy> GrSurfaceProxy::MakeDeferred(GrResourceProvider* resourceP
}
GrSurfaceDesc copyDesc = desc;
- copyDesc.fSampleCnt = SkTMin(desc.fSampleCnt, caps->maxSampleCount());
+ copyDesc.fSampleCnt = caps->getSampleCount(desc.fSampleCnt, desc.fConfig);
if (willBeRT) {
// We know anything we instantiate later from this deferred path will be
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 6d8e46ddca..af0a55a156 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -308,11 +308,11 @@ GrColor4f SkColorToUnpremulGrColor4f(SkColor c, SkColorSpace* dstColorSpace,
///////////////////////////////////////////////////////////////////////////////
-GrPixelConfig SkImageInfo2GrPixelConfig(const SkImageInfo& info, const GrCaps& caps) {
+GrPixelConfig SkImageInfo2GrPixelConfig(const SkColorType type, SkColorSpace* cs,
+ const GrCaps& caps) {
// We intentionally ignore profile type for non-8888 formats. Anything we can't support
// in hardware will be expanded to sRGB 8888 in GrUploadPixmapToTexture.
- SkColorSpace* cs = info.colorSpace();
- switch (info.colorType()) {
+ switch (type) {
case kUnknown_SkColorType:
return kUnknown_GrPixelConfig;
case kAlpha_8_SkColorType:
@@ -336,6 +336,10 @@ GrPixelConfig SkImageInfo2GrPixelConfig(const SkImageInfo& info, const GrCaps& c
return kUnknown_GrPixelConfig;
}
+GrPixelConfig SkImageInfo2GrPixelConfig(const SkImageInfo& info, const GrCaps& caps) {
+ return SkImageInfo2GrPixelConfig(info.colorType(), info.colorSpace(), caps);
+}
+
bool GrPixelConfigToColorType(GrPixelConfig config, SkColorType* ctOut) {
SkColorType ct;
switch (config) {
diff --git a/src/gpu/SkGr.h b/src/gpu/SkGr.h
index 3ed82a8523..1f7f2ad425 100644
--- a/src/gpu/SkGr.h
+++ b/src/gpu/SkGr.h
@@ -151,6 +151,7 @@ bool SkPaintToGrPaintWithTexture(GrContext* context,
// Misc Sk to Gr type conversions
GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo&, const GrCaps&);
+GrPixelConfig SkImageInfo2GrPixelConfig(const SkColorType, SkColorSpace*, const GrCaps& caps);
GrPixelConfig SkImageInfo2GrPixelConfig(const SkImageInfo& info, const GrCaps& caps);
bool GrPixelConfigToColorType(GrPixelConfig, SkColorType*);
diff --git a/src/gpu/gl/GrGLAssembleInterface.cpp b/src/gpu/gl/GrGLAssembleInterface.cpp
index d61b38bbed..64bed32136 100644
--- a/src/gpu/gl/GrGLAssembleInterface.cpp
+++ b/src/gpu/gl/GrGLAssembleInterface.cpp
@@ -529,6 +529,11 @@ const GrGLInterface* GrGLAssembleGLInterface(void* ctx, GrGLGetProc get) {
GET_PROC(MemoryBarrierByRegion);
}
+
+ if (glVer >= GR_GL_VER(4,2) || extensions.has("GL_ARB_internalformat_query")) {
+ GET_PROC(GetInternalformativ);
+ }
+
interface->fStandard = kGL_GrGLStandard;
interface->fExtensions.swap(&extensions);
@@ -951,6 +956,10 @@ const GrGLInterface* GrGLAssembleGLESInterface(void* ctx, GrGLGetProc get) {
GET_PROC(MemoryBarrierByRegion);
}
+ if (version >= GR_GL_VER(3,0)) {
+ GET_PROC(GetInternalformativ);
+ }
+
interface->fStandard = kGLES_GrGLStandard;
interface->fExtensions.swap(&extensions);
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index a7ec88ea87..766b438d2b 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -2109,6 +2109,46 @@ void GrGLCaps::initConfigTable(const GrContextOptions& contextOptions,
}
}
+ bool hasInternalformatFunction = gli->fFunctions.fGetInternalformativ != nullptr;
+ for (int i = 0; i < kGrPixelConfigCnt; ++i) {
+ if (ConfigInfo::kRenderableWithMSAA_Flag & fConfigTable[i].fFlags) {
+ if (hasInternalformatFunction && // This check is temporary until chrome is updated
+ ((kGL_GrGLStandard == ctxInfo.standard() &&
+ (ctxInfo.version() >= GR_GL_VER(4,2) ||
+ ctxInfo.hasExtension("GL_ARB_internalformat_query"))) ||
+ (kGLES_GrGLStandard == ctxInfo.standard() && ctxInfo.version() >= GR_GL_VER(3,0)))) {
+ int count;
+ GrGLenum format = fConfigTable[i].fFormats.fInternalFormatRenderbuffer;
+ GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, format, GR_GL_NUM_SAMPLE_COUNTS,
+ 1, &count);
+ if (count) {
+ int* temp = new int[count];
+ GR_GL_GetInternalformativ(gli, GR_GL_RENDERBUFFER, format, GR_GL_SAMPLES, count,
+ temp);
+ fConfigTable[i].fColorSampleCounts.setCount(count+1);
+ // We initialize our supported values with 0 (no msaa) and reverse the order
+ // returned by GL so that the array is ascending.
+ fConfigTable[i].fColorSampleCounts[0] = 0;
+ for (int j = 0; j < count; ++j) {
+ fConfigTable[i].fColorSampleCounts[j+1] = temp[count - j - 1];
+ }
+ delete[] temp;
+ }
+ } else {
+ static const int kDefaultSamples[] = {0,1,2,4,8};
+ int count = SK_ARRAY_COUNT(kDefaultSamples);
+ for (; count > 0; --count) {
+ if (kDefaultSamples[count-i] <= fMaxColorSampleCount) {
+ break;
+ }
+ }
+ if (count > 0) {
+ fConfigTable[i].fColorSampleCounts.append(count, kDefaultSamples);
+ }
+ }
+ }
+ }
+
#ifdef SK_DEBUG
// Make sure we initialized everything.
ConfigInfo defaultEntry;
@@ -2231,3 +2271,18 @@ void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {
fUseDrawInsteadOfAllRenderTargetWrites = true;
}
}
+
+int GrGLCaps::getSampleCount(int requestedCount, GrPixelConfig config) const {
+ int count = fConfigTable[config].fColorSampleCounts.count();
+ if (!count || !this->isConfigRenderable(config, true)) {
+ return 0;
+ }
+
+ for (int i = 0; i < count; ++i) {
+ if (fConfigTable[config].fColorSampleCounts[i] >= requestedCount) {
+ return fConfigTable[config].fColorSampleCounts[i];
+ }
+ }
+ return fConfigTable[config].fColorSampleCounts[count-1];
+}
+
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index 43da5f86cd..707c65e13d 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -112,6 +112,8 @@ public:
GrGLCaps(const GrContextOptions& contextOptions, const GrGLContextInfo& ctxInfo,
const GrGLInterface* glInterface);
+ int getSampleCount(int requestedCount, GrPixelConfig config) const override;
+
bool isConfigTexturable(GrPixelConfig config) const override {
return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kTextureable_Flag);
}
@@ -529,7 +531,9 @@ private:
};
// Index fStencilFormats.
- int fStencilFormatIndex;
+ int fStencilFormatIndex;
+
+ SkTDArray<int> fColorSampleCounts;
enum {
kVerifiedColorAttachment_Flag = 0x1,
diff --git a/src/gpu/gl/GrGLDefines.h b/src/gpu/gl/GrGLDefines.h
index a986ce80c3..b62c26bcc2 100644
--- a/src/gpu/gl/GrGLDefines.h
+++ b/src/gpu/gl/GrGLDefines.h
@@ -1065,6 +1065,9 @@
/* GL_EXT_geometry_shader */
#define GR_GL_LINES_ADJACENCY 0x000A
+/* GL_ARB_internalformat_query */
+#define GR_GL_NUM_SAMPLE_COUNTS 0x9380
+
/* EGL Defines */
#define GR_EGL_NO_DISPLAY ((GrEGLDisplay)0)
#define GR_EGL_EXTENSIONS 0x3055
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index a73f97c97f..b310df4f7a 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -572,7 +572,7 @@ sk_sp<GrTexture> GrGLGpu::onWrapBackendTexture(const GrBackendTexture& backendTe
surfDesc.fWidth = backendTex.width();
surfDesc.fHeight = backendTex.height();
surfDesc.fConfig = backendTex.config();
- surfDesc.fSampleCnt = SkTMin(sampleCnt, this->caps()->maxSampleCount());
+ surfDesc.fSampleCnt = this->caps()->getSampleCount(sampleCnt, backendTex.config());
// FIXME: this should be calling resolve_origin(), but Chrome code is currently
// assuming the old behaviour, which is that backend textures are always
// BottomLeft, even for non-RT's. Once Chrome is fixed, change this to:
@@ -616,7 +616,7 @@ sk_sp<GrRenderTarget> GrGLGpu::onWrapBackendRenderTarget(const GrBackendRenderTa
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fWidth = backendRT.width();
desc.fHeight = backendRT.height();
- desc.fSampleCnt = SkTMin(backendRT.sampleCnt(), this->caps()->maxSampleCount());
+ desc.fSampleCnt = this->caps()->getSampleCount(backendRT.sampleCnt(), backendRT.config());
SkASSERT(kDefault_GrSurfaceOrigin != origin);
desc.fOrigin = origin;
@@ -647,7 +647,7 @@ sk_sp<GrRenderTarget> GrGLGpu::onWrapBackendTextureAsRenderTarget(const GrBacken
surfDesc.fWidth = tex.width();
surfDesc.fHeight = tex.height();
surfDesc.fConfig = tex.config();
- surfDesc.fSampleCnt = SkTMin(sampleCnt, this->caps()->maxSampleCount());
+ surfDesc.fSampleCnt = this->caps()->getSampleCount(sampleCnt, tex.config());
// FIXME: this should be calling resolve_origin(), but Chrome code is currently
// assuming the old behaviour, which is that backend textures are always
// BottomLeft, even for non-RT's. Once Chrome is fixed, change this to:
diff --git a/src/gpu/gl/GrGLInterface.cpp b/src/gpu/gl/GrGLInterface.cpp
index a71127f577..09d7a4fad3 100644
--- a/src/gpu/gl/GrGLInterface.cpp
+++ b/src/gpu/gl/GrGLInterface.cpp
@@ -808,5 +808,14 @@ bool GrGLInterface::validate() const {
}
}
+ // getInternalformativ was added in GL 4.2, ES 3.0, and with extension ARB_internalformat_query
+ if ((kGL_GrGLStandard == fStandard &&
+ (glVer >= GR_GL_VER(4,2) || fExtensions.has("GL_ARB_internalformat_query"))) ||
+ (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,0))) {
+ if (nullptr == fFunctions.fGetInternalformativ) {
+ // RETURN_FALSE_INTERFACE;
+ }
+ }
+
return true;
}
diff --git a/src/gpu/gl/GrGLTestInterface.cpp b/src/gpu/gl/GrGLTestInterface.cpp
index 25d66a94fc..ef86ea71b9 100644
--- a/src/gpu/gl/GrGLTestInterface.cpp
+++ b/src/gpu/gl/GrGLTestInterface.cpp
@@ -324,4 +324,5 @@ GrGLTestInterface::GrGLTestInterface() {
fFunctions.fPushDebugGroup = bind_to_member(this, &GrGLTestInterface::pushDebugGroup);
fFunctions.fPopDebugGroup = bind_to_member(this, &GrGLTestInterface::popDebugGroup);
fFunctions.fObjectLabel = bind_to_member(this, &GrGLTestInterface::objectLabel);
+ fFunctions.fGetInternalformativ = bind_to_member(this, &GrGLTestInterface::getInternalformativ);
}
diff --git a/src/gpu/gl/GrGLTestInterface.h b/src/gpu/gl/GrGLTestInterface.h
index 636f493037..69427f8d5a 100644
--- a/src/gpu/gl/GrGLTestInterface.h
+++ b/src/gpu/gl/GrGLTestInterface.h
@@ -329,6 +329,7 @@ public:
virtual GrGLvoid pushDebugGroup(GrGLenum source, GrGLuint id, GrGLsizei length, const GrGLchar * message) {}
virtual GrGLvoid popDebugGroup() {}
virtual GrGLvoid objectLabel(GrGLenum identifier, GrGLuint name, GrGLsizei length, const GrGLchar *label) {}
+ virtual GrGLvoid getInternalformativ(GrGLenum target, GrGLenum internalformat, GrGLenum pname, GrGLsizei bufSize, GrGLint *params) {}
protected:
// This must be called by leaf class
diff --git a/src/gpu/gl/GrGLUtil.h b/src/gpu/gl/GrGLUtil.h
index b798385cf6..834b68204b 100644
--- a/src/gpu/gl/GrGLUtil.h
+++ b/src/gpu/gl/GrGLUtil.h
@@ -90,6 +90,12 @@ enum GrGLDriver {
GR_GL_CALL(gl, GetFramebufferAttachmentParameteriv(t, a, pname, p)); \
} while (0)
+#define GR_GL_GetInternalformativ(gl, t, f, n, s, p) \
+ do { \
+ *(p) = GR_GL_INIT_ZERO; \
+ GR_GL_CALL(gl, GetInternalformativ(t, f, n, s, p)); \
+ } while (0)
+
#define GR_GL_GetNamedFramebufferAttachmentParameteriv(gl, fb, a, pname, p) \
do { \
*(p) = GR_GL_INIT_ZERO; \
diff --git a/src/gpu/mock/GrMockCaps.h b/src/gpu/mock/GrMockCaps.h
index 721ac83142..b1d9a84bcf 100644
--- a/src/gpu/mock/GrMockCaps.h
+++ b/src/gpu/mock/GrMockCaps.h
@@ -22,6 +22,9 @@ public:
fShaderCaps.reset(new GrShaderCaps(contextOptions));
this->applyOptionsOverrides(contextOptions);
}
+ int getSampleCount(int /*requestCount*/, GrPixelConfig /*config*/) const override {
+ return 0;
+ }
bool isConfigTexturable(GrPixelConfig config) const override {
return fOptions.fConfigOptions[config].fTexturable;
}
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index db926179be..909b4fbd4c 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -340,6 +340,47 @@ void GrVkCaps::ConfigInfo::InitConfigFlags(VkFormatFeatureFlags vkFlags, uint16_
}
}
+void GrVkCaps::ConfigInfo::initSampleCounts(const GrVkInterface* interface,
+ VkPhysicalDevice physDev,
+ VkFormat format) {
+ VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
+ VK_IMAGE_USAGE_TRANSFER_DST_BIT |
+ VK_IMAGE_USAGE_SAMPLED_BIT |
+ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+ VkImageCreateFlags createFlags = GrVkFormatIsSRGB(format, nullptr)
+ ? VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT : 0;
+ VkImageFormatProperties properties;
+ GR_VK_CALL(interface, GetPhysicalDeviceImageFormatProperties(physDev,
+ format,
+ VK_IMAGE_TYPE_2D,
+ VK_IMAGE_TILING_OPTIMAL,
+ usage,
+ createFlags,
+ &properties));
+ VkSampleCountFlags flags = properties.sampleCounts;
+ if (flags & VK_SAMPLE_COUNT_1_BIT) {
+ fColorSampleCounts.push(0);
+ }
+ if (flags & VK_SAMPLE_COUNT_2_BIT) {
+ fColorSampleCounts.push(2);
+ }
+ if (flags & VK_SAMPLE_COUNT_4_BIT) {
+ fColorSampleCounts.push(4);
+ }
+ if (flags & VK_SAMPLE_COUNT_8_BIT) {
+ fColorSampleCounts.push(8);
+ }
+ if (flags & VK_SAMPLE_COUNT_16_BIT) {
+ fColorSampleCounts.push(16);
+ }
+ if (flags & VK_SAMPLE_COUNT_32_BIT) {
+ fColorSampleCounts.push(32);
+ }
+ if (flags & VK_SAMPLE_COUNT_64_BIT) {
+ fColorSampleCounts.push(64);
+ }
+}
+
void GrVkCaps::ConfigInfo::init(const GrVkInterface* interface,
VkPhysicalDevice physDev,
VkFormat format) {
@@ -348,4 +389,22 @@ void GrVkCaps::ConfigInfo::init(const GrVkInterface* interface,
GR_VK_CALL(interface, GetPhysicalDeviceFormatProperties(physDev, format, &props));
InitConfigFlags(props.linearTilingFeatures, &fLinearFlags);
InitConfigFlags(props.optimalTilingFeatures, &fOptimalFlags);
+ if (fOptimalFlags & kRenderable_Flag) {
+ this->initSampleCounts(interface, physDev, format);
+ }
}
+
+int GrVkCaps::getSampleCount(int requestedCount, GrPixelConfig config) const {
+ int count = fConfigTable[config].fColorSampleCounts.count();
+ if (!count || !this->isConfigRenderable(config, true)) {
+ return 0;
+ }
+
+ for (int i = 0; i < count; ++i) {
+ if (fConfigTable[config].fColorSampleCounts[i] >= requestedCount) {
+ return fConfigTable[config].fColorSampleCounts[i];
+ }
+ }
+ return fConfigTable[config].fColorSampleCounts[count-1];
+}
+
diff --git a/src/gpu/vk/GrVkCaps.h b/src/gpu/vk/GrVkCaps.h
index f599d22cb5..b0854867c8 100644
--- a/src/gpu/vk/GrVkCaps.h
+++ b/src/gpu/vk/GrVkCaps.h
@@ -29,6 +29,8 @@ public:
GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
VkPhysicalDevice device, uint32_t featureFlags, uint32_t extensionFlags);
+ int getSampleCount(int requestedCount, GrPixelConfig config) const override;
+
bool isConfigTexturable(GrPixelConfig config) const override {
return SkToBool(ConfigInfo::kTextureable_Flag & fConfigTable[config].fOptimalFlags);
}
@@ -132,6 +134,7 @@ private:
void init(const GrVkInterface*, VkPhysicalDevice, VkFormat);
static void InitConfigFlags(VkFormatFeatureFlags, uint16_t* flags);
+ void initSampleCounts(const GrVkInterface*, VkPhysicalDevice, VkFormat);
enum {
kTextureable_Flag = 0x1,
@@ -142,6 +145,8 @@ private:
uint16_t fOptimalFlags;
uint16_t fLinearFlags;
+
+ SkTDArray<int> fColorSampleCounts;
};
ConfigInfo fConfigTable[kGrPixelConfigCnt];
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 17fccfb1bb..cd0fc99b4b 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -882,7 +882,7 @@ sk_sp<GrTexture> GrVkGpu::onWrapBackendTexture(const GrBackendTexture& backendTe
surfDesc.fWidth = backendTex.width();
surfDesc.fHeight = backendTex.height();
surfDesc.fConfig = backendTex.config();
- surfDesc.fSampleCnt = SkTMin(sampleCnt, this->caps()->maxSampleCount());
+ surfDesc.fSampleCnt = this->caps()->getSampleCount(sampleCnt, backendTex.config());
bool renderTarget = SkToBool(flags & kRenderTarget_GrBackendTextureFlag);
// In GL, Chrome assumes all textures are BottomLeft
// In VK, we don't have this restriction
@@ -948,7 +948,7 @@ sk_sp<GrRenderTarget> GrVkGpu::onWrapBackendTextureAsRenderTarget(const GrBacken
desc.fConfig = tex.config();
desc.fWidth = tex.width();
desc.fHeight = tex.height();
- desc.fSampleCnt = SkTMin(sampleCnt, this->caps()->maxSampleCount());
+ desc.fSampleCnt = this->caps()->getSampleCount(sampleCnt, tex.config());
desc.fOrigin = resolve_origin(origin);
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index 178676431f..f8cb6efb67 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -145,7 +145,7 @@ static sk_sp<GrRenderTargetContext> random_render_target_context(GrContext* cont
const GrCaps* caps) {
GrSurfaceOrigin origin = random->nextBool() ? kTopLeft_GrSurfaceOrigin
: kBottomLeft_GrSurfaceOrigin;
- int sampleCnt = random->nextBool() ? SkTMin(4, caps->maxSampleCount()) : 0;
+ int sampleCnt = random->nextBool() ? caps->getSampleCount(4, kRGBA_8888_GrPixelConfig) : 0;
sk_sp<GrRenderTargetContext> renderTargetContext(context->makeDeferredRenderTargetContext(
SkBackingFit::kExact,
diff --git a/tests/GpuSampleLocationsTest.cpp b/tests/GpuSampleLocationsTest.cpp
index ff87a33725..6c5d4a6d37 100644
--- a/tests/GpuSampleLocationsTest.cpp
+++ b/tests/GpuSampleLocationsTest.cpp
@@ -189,7 +189,8 @@ DEF_GPUTEST(GLSampleLocations, reporter, /*factory*/) {
sk_sp<GrContext> ctx(GrContext::Create(kOpenGL_GrBackend, testInterface));
// This test relies on at least 2 samples.
- if (ctx->caps()->maxSampleCount() < 2) {
+ int supportedSample = ctx->caps()->getSampleCount(2, kRGBA_8888_GrPixelConfig);
+ if (supportedSample < 2) {
return;
}
test_sampleLocations(reporter, &testInterface, ctx.get());
diff --git a/tests/ProxyTest.cpp b/tests/ProxyTest.cpp
index f9cefc5b89..c2a7734901 100644
--- a/tests/ProxyTest.cpp
+++ b/tests/ProxyTest.cpp
@@ -157,9 +157,10 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DeferredProxyTest, reporter, ctxInfo) {
check_surface(reporter, proxy.get(), origin,
widthHeight, widthHeight, config,
kInvalidResourceID, budgeted);
+ int supportedSamples = caps.getSampleCount(numSamples, config);
check_rendertarget(reporter, caps, provider,
proxy->asRenderTargetProxy(),
- SkTMin(numSamples, caps.maxSampleCount()),
+ supportedSamples,
fit, caps.maxWindowRectangles(), false);
}
}
@@ -214,9 +215,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(WrappedProxyTest, reporter, ctxInfo) {
for (auto config : { kAlpha_8_GrPixelConfig, kRGBA_8888_GrPixelConfig }) {
for (auto budgeted : { SkBudgeted::kYes, SkBudgeted::kNo }) {
for (auto numSamples: { 0, 4}) {
- if (caps.maxSampleCount() < numSamples) {
- continue;
- }
+ int supportedNumSamples = caps.getSampleCount(numSamples, config);
bool renderable = caps.isConfigRenderable(config, numSamples > 0);
@@ -225,7 +224,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(WrappedProxyTest, reporter, ctxInfo) {
desc.fWidth = kWidthHeight;
desc.fHeight = kWidthHeight;
desc.fConfig = config;
- desc.fSampleCnt = numSamples;
+ desc.fSampleCnt = supportedNumSamples;
// External on-screen render target.
if (renderable && kOpenGL_GrBackend == ctxInfo.backend()) {
diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp
index 83d316fcbc..50ddd00e8a 100644
--- a/tests/ResourceCacheTest.cpp
+++ b/tests/ResourceCacheTest.cpp
@@ -150,10 +150,11 @@ DEF_GPUTEST_FOR_CONTEXTS(ResourceCacheStencilBuffers, &is_rendering_and_not_angl
resourceProvider->attachStencilAttachment(smallRT0->asRenderTarget()) !=
resourceProvider->attachStencilAttachment(bigRT->asRenderTarget()));
- if (context->caps()->maxSampleCount() >= 4) {
+ int supportedSampleCount = context->caps()->getSampleCount(4, smallDesc.fConfig);
+ if (supportedSampleCount > 0) {
// An RT with a different sample count should not share.
GrSurfaceDesc smallMSAADesc = smallDesc;
- smallMSAADesc.fSampleCnt = 4;
+ smallMSAADesc.fSampleCnt = supportedSampleCount;
sk_sp<GrTexture> smallMSAART0(resourceProvider->createTexture(smallMSAADesc,
SkBudgeted::kNo));
if (smallMSAART0 && smallMSAART0->asRenderTarget()) {
@@ -184,10 +185,10 @@ DEF_GPUTEST_FOR_CONTEXTS(ResourceCacheStencilBuffers, &is_rendering_and_not_angl
resourceProvider->attachStencilAttachment(smallMSAART1->asRenderTarget()));
// But not one with a larger sample count should not. (Also check that the request for 4
// samples didn't get rounded up to >= 8 or else they could share.).
- if (context->caps()->maxSampleCount() >= 8 &&
- smallMSAART0 && smallMSAART0->asRenderTarget() &&
- smallMSAART0->asRenderTarget()->numColorSamples() < 8) {
- smallMSAADesc.fSampleCnt = 8;
+ supportedSampleCount = context->caps()->getSampleCount(8, smallDesc.fConfig);
+ if (supportedSampleCount != smallMSAADesc.fSampleCnt &&
+ smallMSAART0 && smallMSAART0->asRenderTarget()) {
+ smallMSAADesc.fSampleCnt = supportedSampleCount;
smallMSAART1 = resourceProvider->createTexture(smallMSAADesc, SkBudgeted::kNo);
sk_sp<GrTexture> smallMSAART1(
resourceProvider->createTexture(smallMSAADesc, SkBudgeted::kNo));
@@ -1700,12 +1701,15 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GPUMemorySize, reporter, ctxInfo) {
size_t size = tex->gpuMemorySize();
REPORTER_ASSERT(reporter, kSize*kSize*4 == size);
- if (context->caps()->maxSampleCount() >= 4) {
- tex = make_normal_texture(provider, kRenderTarget_GrSurfaceFlag, kSize, kSize, 4);
+ size_t sampleCount = (size_t)context->caps()->getSampleCount(4, kRGBA_8888_GrPixelConfig);
+ if (sampleCount >= 4) {
+ tex = make_normal_texture(provider, kRenderTarget_GrSurfaceFlag, kSize, kSize,
+ sampleCount);
size = tex->gpuMemorySize();
- REPORTER_ASSERT(reporter, kSize*kSize*4 == size || // msaa4 failed
- kSize*kSize*4*4 == size || // auto-resolving
- kSize*kSize*4*5 == size); // explicit resolve buffer
+ REPORTER_ASSERT(reporter,
+ kSize*kSize*4 == size || // msaa4 failed
+ kSize*kSize*4*sampleCount == size || // auto-resolving
+ kSize*kSize*4*(sampleCount+1) == size); // explicit resolve buffer
}
tex = make_normal_texture(provider, kNone_GrSurfaceFlags, kSize, kSize, 0);
@@ -1722,13 +1726,15 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GPUMemorySize, reporter, ctxInfo) {
size_t size = proxy->gpuMemorySize();
REPORTER_ASSERT(reporter, kSize*kSize*4+(kSize*kSize*4)/3 == size);
- if (context->caps()->maxSampleCount() >= 4) {
- proxy = make_mipmap_proxy(provider, kRenderTarget_GrSurfaceFlag, kSize, kSize, 4);
+ size_t sampleCount = (size_t)context->caps()->getSampleCount(4, kRGBA_8888_GrPixelConfig);
+ if (sampleCount >= 4) {
+ proxy = make_mipmap_proxy(provider, kRenderTarget_GrSurfaceFlag, kSize, kSize,
+ sampleCount);
size = proxy->gpuMemorySize();
REPORTER_ASSERT(reporter,
- kSize*kSize*4+(kSize*kSize*4)/3 == size || // msaa4 failed
- kSize*kSize*4*4+(kSize*kSize*4)/3 == size || // auto-resolving
- kSize*kSize*4*5+(kSize*kSize*4)/3 == size); // explicit resolve buffer
+ kSize*kSize*4+(kSize*kSize*4)/3 == size || // msaa4 failed
+ kSize*kSize*4*sampleCount+(kSize*kSize*4)/3 == size || // auto-resolving
+ kSize*kSize*4*(sampleCount+1)+(kSize*kSize*4)/3 == size); // explicit resolve buffer
}
proxy = make_mipmap_proxy(provider, kNone_GrSurfaceFlags, kSize, kSize, 0);
diff --git a/tools/skpbench/skpbench.cpp b/tools/skpbench/skpbench.cpp
index 8898da25d5..c0ead46155 100644
--- a/tools/skpbench/skpbench.cpp
+++ b/tools/skpbench/skpbench.cpp
@@ -7,6 +7,8 @@
#include "GpuTimer.h"
#include "GrContextFactory.h"
+#include "SkGr.h"
+
#include "SkCanvas.h"
#include "SkCommonFlagsPathRenderer.h"
#include "SkOSFile.h"
@@ -287,9 +289,13 @@ int main(int argc, char** argv) {
exitf(ExitErr::kUnavailable, "render target size %ix%i not supported by platform (max: %i)",
width, height, ctx->caps()->maxRenderTargetSize());
}
- if (ctx->caps()->maxSampleCount() < config->getSamples()) {
- exitf(ExitErr::kUnavailable, "sample count %i not supported by platform (max: %i)",
- config->getSamples(), ctx->caps()->maxSampleCount());
+ GrPixelConfig grPixConfig = SkImageInfo2GrPixelConfig(config->getColorType(),
+ config->getColorSpace(),
+ *ctx->caps());
+ int supportedSampleCount = ctx->caps()->getSampleCount(config->getSamples(), grPixConfig);
+ if (supportedSampleCount != config->getSamples()) {
+ exitf(ExitErr::kUnavailable, "sample count %i not supported by platform",
+ config->getSamples());
}
sk_gpu_test::TestContext* testCtx = ctxInfo.testContext();
if (!testCtx) {