Update gpu caps for valid sample counts.
Instead of query and maxSampleCount and using that to cap, we now have each config store its supported values and when requested returns either the next highest or equal supported value, or if non the max config supported. Bug: skia: Change-Id: I8802d44c13b3b1703ee54a7e69b82102d4b8dc2d Reviewed-on: https://skia-review.googlesource.com/24302 Commit-Queue: Greg Daniel <egdaniel@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
fc3afa921b
commit
81e7bf8d6d
@ -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,
|
||||
|
@ -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; }
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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*);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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];
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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; \
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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];
|
||||
}
|
||||
|
||||
|
@ -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];
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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());
|
||||
|
@ -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()) {
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user