aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar cdalton <cdalton@nvidia.com>2016-04-11 12:03:08 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-04-11 12:03:08 -0700
commita6b92ad1f7b79106caef6a4c721903544f507a02 (patch)
treef91503b26a515e060202000ecd6bb1923de1e7ed /src
parent21a465d7f4c5e639044e79971aeaa1194fc73078 (diff)
Infer sampler precision from pixel config
Adds a "samplerPrecision" method to GrGLSLCaps and updates GrGLSLProgramBuilder to infer a sampler's precision based on its config and visibility. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1846963004 Review URL: https://codereview.chromium.org/1846963004
Diffstat (limited to 'src')
-rw-r--r--src/gpu/GrTextureAccess.cpp13
-rw-r--r--src/gpu/gl/GrGLCaps.cpp1
-rw-r--r--src/gpu/gl/GrGLProgramDesc.cpp34
-rwxr-xr-xsrc/gpu/glsl/GrGLSLCaps.cpp55
-rwxr-xr-xsrc/gpu/glsl/GrGLSLCaps.h10
-rw-r--r--src/gpu/glsl/GrGLSLProgramBuilder.cpp6
-rw-r--r--src/gpu/vk/GrVkCaps.cpp15
-rw-r--r--src/gpu/vk/GrVkProgramDesc.cpp5
8 files changed, 110 insertions, 29 deletions
diff --git a/src/gpu/GrTextureAccess.cpp b/src/gpu/GrTextureAccess.cpp
index a62a4ddce0..675bc20777 100644
--- a/src/gpu/GrTextureAccess.cpp
+++ b/src/gpu/GrTextureAccess.cpp
@@ -18,30 +18,25 @@ GrTextureAccess::GrTextureAccess(GrTexture* texture, const GrTextureParams& para
GrTextureAccess::GrTextureAccess(GrTexture* texture,
GrTextureParams::FilterMode filterMode,
SkShader::TileMode tileXAndY,
- GrShaderFlags visibility,
- GrSLPrecision precision) {
- this->reset(texture, filterMode, tileXAndY, visibility, precision);
+ GrShaderFlags visibility) {
+ this->reset(texture, filterMode, tileXAndY, visibility);
}
void GrTextureAccess::reset(GrTexture* texture,
const GrTextureParams& params,
- GrShaderFlags visibility,
- GrSLPrecision precision) {
+ GrShaderFlags visibility) {
SkASSERT(texture);
fTexture.set(SkRef(texture), kRead_GrIOType);
fParams = params;
fVisibility = visibility;
- fPrecision = precision;
}
void GrTextureAccess::reset(GrTexture* texture,
GrTextureParams::FilterMode filterMode,
SkShader::TileMode tileXAndY,
- GrShaderFlags visibility,
- GrSLPrecision precision) {
+ GrShaderFlags visibility) {
SkASSERT(texture);
fTexture.set(SkRef(texture), kRead_GrIOType);
fParams.reset(tileXAndY, filterMode);
fVisibility = visibility;
- fPrecision = precision;
}
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index e850dcabaf..fc2c8ce398 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -1197,6 +1197,7 @@ void GrGLCaps::initShaderPrecisionTable(const GrGLContextInfo& ctxInfo,
glslCaps->fFloatPrecisions[kVertex_GrShaderType][p];
}
}
+ glslCaps->initSamplerPrecisionTable();
}
bool GrGLCaps::bgraIsInternalFormat() const {
diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp
index 68020a92d5..5e9fe5fcc6 100644
--- a/src/gpu/gl/GrGLProgramDesc.cpp
+++ b/src/gpu/gl/GrGLProgramDesc.cpp
@@ -17,24 +17,27 @@
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLCaps.h"
-static uint8_t texture_target_key(GrGLenum target) {
- switch (target) {
- case GR_GL_TEXTURE_2D:
- return 0;
- case GR_GL_TEXTURE_EXTERNAL:
- return 1;
- case GR_GL_TEXTURE_RECTANGLE:
- return 2;
- default:
- SkFAIL("Unexpected texture target.");
- return 0;
- }
+static uint16_t texture_key(GrSLType samplerType, GrPixelConfig config, GrShaderFlags visibility,
+ const GrGLSLCaps& caps) {
+ enum {
+ kFirstSamplerType = kSampler2D_GrSLType,
+ kLastSamplerType = kSampler2DRect_GrSLType,
+ kSamplerTypeKeyBits = 4
+ };
+ GR_STATIC_ASSERT(kLastSamplerType - kFirstSamplerType < (1 << kSamplerTypeKeyBits));
+
+ SkASSERT((int)samplerType >= kFirstSamplerType && (int)samplerType <= kLastSamplerType);
+ int samplerTypeKey = samplerType - kFirstSamplerType;
+
+ return SkToU16(caps.configTextureSwizzle(config).asKey() |
+ (samplerTypeKey << 8) |
+ (caps.samplerPrecision(config, visibility) << (8 + kSamplerTypeKeyBits)));
}
static void add_texture_key(GrProcessorKeyBuilder* b, const GrProcessor& proc,
const GrGLSLCaps& caps) {
int numTextures = proc.numTextures();
- // Need two bytes per key (swizzle and target).
+ // Need two bytes per key (swizzle, sampler type, and precision).
int word32Count = (proc.numTextures() + 1) / 2;
if (0 == word32Count) {
return;
@@ -42,9 +45,8 @@ static void add_texture_key(GrProcessorKeyBuilder* b, const GrProcessor& proc,
uint16_t* k16 = SkTCast<uint16_t*>(b->add32n(word32Count));
for (int i = 0; i < numTextures; ++i) {
const GrTextureAccess& access = proc.textureAccess(i);
- GrGLTexture* texture = static_cast<GrGLTexture*>(access.getTexture());
- k16[i] = SkToU16(caps.configTextureSwizzle(texture->config()).asKey() |
- (texture_target_key(texture->target()) << 8));
+ const GrTexture* tex = access.getTexture();
+ k16[i] = texture_key(tex->samplerType(), tex->config(), access.getVisibility(), caps);
}
// zero the last 16 bits if the number of textures is odd.
if (numTextures & 0x1) {
diff --git a/src/gpu/glsl/GrGLSLCaps.cpp b/src/gpu/glsl/GrGLSLCaps.cpp
index c2404c6e52..60bea8663a 100755
--- a/src/gpu/glsl/GrGLSLCaps.cpp
+++ b/src/gpu/glsl/GrGLSLCaps.cpp
@@ -92,5 +92,60 @@ SkString GrGLSLCaps::dump() const {
return r;
}
+void GrGLSLCaps::initSamplerPrecisionTable() {
+ // Determine the largest precision qualifiers that are effectively the same as lowp/mediump.
+ // e.g. if lowp == mediump, then use mediump instead of lowp.
+ GrSLPrecision effectiveMediumP[kGrShaderTypeCount];
+ GrSLPrecision effectiveLowP[kGrShaderTypeCount];
+ for (int s = 0; s < kGrShaderTypeCount; ++s) {
+ const PrecisionInfo* info = fFloatPrecisions[s];
+ effectiveMediumP[s] = info[kHigh_GrSLPrecision] == info[kMedium_GrSLPrecision] ?
+ kHigh_GrSLPrecision : kMedium_GrSLPrecision;
+ effectiveLowP[s] = info[kMedium_GrSLPrecision] == info[kLow_GrSLPrecision] ?
+ effectiveMediumP[s] : kLow_GrSLPrecision;
+ }
+
+ // Determine which precision qualifiers should be used with samplers.
+ for (int visibility = 0; visibility < (1 << kGrShaderTypeCount); ++visibility) {
+ GrSLPrecision mediump = kHigh_GrSLPrecision;
+ GrSLPrecision lowp = kHigh_GrSLPrecision;
+ for (int s = 0; s < kGrShaderTypeCount; ++s) {
+ if (visibility & (1 << s)) {
+ mediump = SkTMin(mediump, effectiveMediumP[s]);
+ lowp = SkTMin(lowp, effectiveLowP[s]);
+ }
+
+ GR_STATIC_ASSERT(0 == kLow_GrSLPrecision);
+ GR_STATIC_ASSERT(1 == kMedium_GrSLPrecision);
+ GR_STATIC_ASSERT(2 == kHigh_GrSLPrecision);
+
+ GR_STATIC_ASSERT((1 << kVertex_GrShaderType) == kVertex_GrShaderFlag);
+ GR_STATIC_ASSERT((1 << kGeometry_GrShaderType) == kGeometry_GrShaderFlag);
+ GR_STATIC_ASSERT((1 << kFragment_GrShaderType) == kFragment_GrShaderFlag);
+ GR_STATIC_ASSERT(3 == kGrShaderTypeCount);
+ }
+
+ uint8_t* table = fSamplerPrecisions[visibility];
+ table[kUnknown_GrPixelConfig] = kDefault_GrSLPrecision;
+ table[kAlpha_8_GrPixelConfig] = lowp;
+ table[kIndex_8_GrPixelConfig] = lowp;
+ table[kRGB_565_GrPixelConfig] = lowp;
+ table[kRGBA_4444_GrPixelConfig] = lowp;
+ table[kRGBA_8888_GrPixelConfig] = lowp;
+ table[kBGRA_8888_GrPixelConfig] = lowp;
+ table[kSRGBA_8888_GrPixelConfig] = lowp;
+ table[kSBGRA_8888_GrPixelConfig] = lowp;
+ table[kETC1_GrPixelConfig] = lowp;
+ table[kLATC_GrPixelConfig] = lowp;
+ table[kR11_EAC_GrPixelConfig] = lowp;
+ table[kASTC_12x12_GrPixelConfig] = lowp;
+ table[kRGBA_float_GrPixelConfig] = kHigh_GrSLPrecision;
+ table[kAlpha_half_GrPixelConfig] = mediump;
+ table[kRGBA_half_GrPixelConfig] = mediump;
+
+ GR_STATIC_ASSERT(16 == kGrPixelConfigCnt);
+ }
+}
+
void GrGLSLCaps::onApplyOptionsOverrides(const GrContextOptions& options) {
}
diff --git a/src/gpu/glsl/GrGLSLCaps.h b/src/gpu/glsl/GrGLSLCaps.h
index 7b0868ea92..a1d458a547 100755
--- a/src/gpu/glsl/GrGLSLCaps.h
+++ b/src/gpu/glsl/GrGLSLCaps.h
@@ -162,6 +162,11 @@ public:
return fConfigOutputSwizzle[config];
}
+ /** Precision qualifier that should be used with a sampler, given its config and visibility. */
+ GrSLPrecision samplerPrecision(GrPixelConfig config, GrShaderFlags visibility) const {
+ return static_cast<GrSLPrecision>(fSamplerPrecisions[visibility][config]);
+ }
+
GrGLSLGeneration generation() const { return fGLSLGeneration; }
/**
@@ -170,6 +175,9 @@ public:
SkString dump() const override;
private:
+ /** GrCaps subclasses must call this after filling in the shader precision table. */
+ void initSamplerPrecisionTable();
+
void onApplyOptionsOverrides(const GrContextOptions& options) override;
GrGLSLGeneration fGLSLGeneration;
@@ -216,6 +224,8 @@ private:
GrSwizzle fConfigTextureSwizzle[kGrPixelConfigCnt];
GrSwizzle fConfigOutputSwizzle[kGrPixelConfigCnt];
+ uint8_t fSamplerPrecisions[(1 << kGrShaderTypeCount)][kGrPixelConfigCnt];
+
friend class GrGLCaps; // For initialization.
friend class GrVkCaps;
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.cpp b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
index 512d9d14d9..4e90452925 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
@@ -241,10 +241,12 @@ void GrGLSLProgramBuilder::emitSamplers(const GrProcessor& processor,
1 << GrGLSLShaderBuilder::kExternalTexture_GLSLPrivateFeature,
externalFeatureString);
}
+ GrSLPrecision precision = this->glslCaps()->samplerPrecision(access.getTexture()->config(),
+ visibility);
name.printf("Sampler%d", t);
- localSamplerUniforms[t] = this->uniformHandler()->addUniform(access.getVisibility(),
+ localSamplerUniforms[t] = this->uniformHandler()->addUniform(visibility,
samplerType,
- access.getPrecision(),
+ precision,
name.c_str());
outSamplers->emplace_back(localSamplerUniforms[t], access);
}
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index b72a512523..5b62a3767c 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -154,6 +154,21 @@ void GrVkCaps::initGLSLCaps(const VkPhysicalDeviceProperties& properties,
glslCaps->fIntegerSupport = true;
+ // Assume the minimum precisions mandated by the SPIR-V spec.
+ glslCaps->fShaderPrecisionVaries = true;
+ for (int s = 0; s < kGrShaderTypeCount; ++s) {
+ auto& highp = glslCaps->fFloatPrecisions[s][kHigh_GrSLPrecision];
+ highp.fLogRangeLow = highp.fLogRangeHigh = 127;
+ highp.fBits = 23;
+
+ auto& mediump = glslCaps->fFloatPrecisions[s][kMedium_GrSLPrecision];
+ mediump.fLogRangeLow = mediump.fLogRangeHigh = 14;
+ mediump.fBits = 10;
+
+ glslCaps->fFloatPrecisions[s][kLow_GrSLPrecision] = mediump;
+ }
+ glslCaps->initSamplerPrecisionTable();
+
glslCaps->fMaxVertexSamplers =
glslCaps->fMaxGeometrySamplers =
glslCaps->fMaxFragmentSamplers = SkTMin(properties.limits.maxPerStageDescriptorSampledImages,
diff --git a/src/gpu/vk/GrVkProgramDesc.cpp b/src/gpu/vk/GrVkProgramDesc.cpp
index 74e6bbb59d..f4bd2bf506 100644
--- a/src/gpu/vk/GrVkProgramDesc.cpp
+++ b/src/gpu/vk/GrVkProgramDesc.cpp
@@ -22,7 +22,7 @@
static void add_texture_key(GrProcessorKeyBuilder* b, const GrProcessor& proc,
const GrGLSLCaps& caps) {
int numTextures = proc.numTextures();
- // Need two bytes per key (swizzle and target).
+ // Need two bytes per key (swizzle, sampler type, and precision).
int word32Count = (proc.numTextures() + 1) / 2;
if (0 == word32Count) {
return;
@@ -31,7 +31,8 @@ static void add_texture_key(GrProcessorKeyBuilder* b, const GrProcessor& proc,
for (int i = 0; i < numTextures; ++i) {
const GrTextureAccess& access = proc.textureAccess(i);
GrTexture* texture = access.getTexture();
- k16[i] = SkToU16(caps.configTextureSwizzle(texture->config()).asKey());
+ k16[i] = SkToU16(caps.configTextureSwizzle(texture->config()).asKey() |
+ (caps.samplerPrecision(texture->config(), access.getVisibility()) << 8));
}
// zero the last 16 bits if the number of textures is odd.
if (numTextures & 0x1) {