FBFetch refactor + arm support

BUG=skia:
R=krajcevski@google.com, bsalomon@google.com

Author: joshualitt@chromium.org

Review URL: https://codereview.chromium.org/433603002
This commit is contained in:
joshualitt 2014-08-01 06:44:53 -07:00 committed by Commit bot
parent 3836dc80a6
commit 5816233d23
6 changed files with 59 additions and 74 deletions

View File

@ -22,7 +22,6 @@ void GrGLCaps::reset() {
fStencilFormats.reset();
fStencilVerifiedColorConfigs.reset();
fMSFBOType = kNone_MSFBOType;
fFBFetchType = kNone_FBFetchType;
fInvalidateFBType = kNone_InvalidateFBType;
fLATCAlias = kLATC_LATCAlias;
fMapBufferType = kNone_MapBufferType;
@ -48,6 +47,9 @@ void GrGLCaps::reset() {
fIsCoreProfile = false;
fFullClearIsFree = false;
fDropsTileOnZeroDivide = false;
fFBFetchSupport = false;
fFBFetchColorName = NULL;
fFBFetchExtensionString = NULL;
}
GrGLCaps::GrGLCaps(const GrGLCaps& caps) : GrDrawTargetCaps() {
@ -65,7 +67,6 @@ GrGLCaps& GrGLCaps::operator= (const GrGLCaps& caps) {
fMaxFragmentTextureUnits = caps.fMaxFragmentTextureUnits;
fMaxFixedFunctionTextureCoords = caps.fMaxFixedFunctionTextureCoords;
fMSFBOType = caps.fMSFBOType;
fFBFetchType = caps.fFBFetchType;
fInvalidateFBType = caps.fInvalidateFBType;
fMapBufferType = caps.fMapBufferType;
fRGBA8RenderbufferSupport = caps.fRGBA8RenderbufferSupport;
@ -86,6 +87,9 @@ GrGLCaps& GrGLCaps::operator= (const GrGLCaps& caps) {
fIsCoreProfile = caps.fIsCoreProfile;
fFullClearIsFree = caps.fFullClearIsFree;
fDropsTileOnZeroDivide = caps.fDropsTileOnZeroDivide;
fFBFetchSupport = caps.fFBFetchSupport;
fFBFetchColorName = caps.fFBFetchColorName;
fFBFetchExtensionString = caps.fFBFetchExtensionString;
return *this;
}
@ -233,9 +237,19 @@ bool GrGLCaps::init(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
if (kGLES_GrGLStandard == standard) {
if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) {
fFBFetchType = kEXT_FBFetchType;
fFBFetchSupport = true;
fFBFetchColorName = "gl_LastFragData[0]";
fFBFetchExtensionString = "GL_EXT_shader_framebuffer_fetch";
} else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) {
fFBFetchType = kNV_FBFetchType;
fFBFetchSupport = true;
fFBFetchColorName = "gl_LastFragData[0]";
fFBFetchExtensionString = "GL_NV_shader_framebuffer_fetch";
} else if (ctxInfo.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
// The arm extension also requires an additional flag which we will set onResetContext
// This is all temporary.
fFBFetchSupport = true;
fFBFetchColorName = "gl_LastFragColorARM";
fFBFetchExtensionString = "GL_ARM_shader_framebuffer_fetch";
}
}
@ -335,7 +349,8 @@ bool GrGLCaps::init(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker");
fDstReadInShaderSupport = kNone_FBFetchType != fFBFetchType;
// For now these two are equivalent but we could have dst read in shader via some other method
fDstReadInShaderSupport = fFBFetchSupport;
// Disable scratch texture reuse on Mali and Adreno devices
fReuseScratchTextures = kARM_GrGLVendor != ctxInfo.vendor() &&
@ -777,16 +792,6 @@ SkString GrGLCaps::dump() const {
GR_STATIC_ASSERT(6 == kES_EXT_MsToTexture_MSFBOType);
GR_STATIC_ASSERT(SK_ARRAY_COUNT(kMSFBOExtStr) == kLast_MSFBOType + 1);
static const char* kFBFetchTypeStr[] = {
"None",
"EXT",
"NV",
};
GR_STATIC_ASSERT(0 == kNone_FBFetchType);
GR_STATIC_ASSERT(1 == kEXT_FBFetchType);
GR_STATIC_ASSERT(2 == kNV_FBFetchType);
GR_STATIC_ASSERT(SK_ARRAY_COUNT(kFBFetchTypeStr) == kLast_FBFetchType + 1);
static const char* kInvalidateFBTypeStr[] = {
"None",
"Discard",
@ -811,7 +816,7 @@ SkString GrGLCaps::dump() const {
r.appendf("Core Profile: %s\n", (fIsCoreProfile ? "YES" : "NO"));
r.appendf("MSAA Type: %s\n", kMSFBOExtStr[fMSFBOType]);
r.appendf("FB Fetch Type: %s\n", kFBFetchTypeStr[fFBFetchType]);
r.appendf("FB Fetch Support: %s\n", (fFBFetchSupport ? "YES" : "NO"));
r.appendf("Invalidate FB Type: %s\n", kInvalidateFBTypeStr[fInvalidateFBType]);
r.appendf("Map Buffer Type: %s\n", kMapBufferTypeStr[fMapBufferType]);
r.appendf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors);

View File

@ -68,16 +68,6 @@ public:
kLast_MSFBOType = kES_EXT_MsToTexture_MSFBOType
};
enum FBFetchType {
kNone_FBFetchType,
/** GL_EXT_shader_framebuffer_fetch */
kEXT_FBFetchType,
/** GL_NV_shader_framebuffer_fetch */
kNV_FBFetchType,
kLast_FBFetchType = kNV_FBFetchType
};
enum InvalidateFBType {
kNone_InvalidateFBType,
kDiscard_InvalidateFBType, //<! glDiscardFramebuffer()
@ -174,7 +164,16 @@ public:
kES_EXT_MsToTexture_MSFBOType == fMSFBOType;
}
FBFetchType fbFetchType() const { return fFBFetchType; }
/**
* Some helper functions for encapsulating various extensions to read FB Buffer on openglES
*
* TODO On desktop opengl 4.2+ we can achieve something similar to this effect
*/
bool fbFetchSupport() const { return fFBFetchSupport; }
const char* fbFetchColorName() const { return fFBFetchColorName; }
const char* fbFetchExtensionString() const { return fFBFetchExtensionString; }
InvalidateFBType invalidateFBType() const { return fInvalidateFBType; }
@ -340,7 +339,6 @@ private:
int fMaxFixedFunctionTextureCoords;
MSFBOType fMSFBOType;
FBFetchType fFBFetchType;
InvalidateFBType fInvalidateFBType;
MapBufferType fMapBufferType;
LATCAlias fLATCAlias;
@ -363,6 +361,10 @@ private:
bool fIsCoreProfile : 1;
bool fFullClearIsFree : 1;
bool fDropsTileOnZeroDivide : 1;
bool fFBFetchSupport : 1;
const char* fFBFetchColorName;
const char* fFBFetchExtensionString;
typedef GrDrawTargetCaps INHERITED;
};

View File

@ -900,4 +900,8 @@
// shader stage of <program> (if a fragment stage exists).
#define GR_GL_FRAGMENT_INPUT 0x936D
/* ARM specific define for MSAA support on framebuffer fetch */
#define GR_GL_FETCH_PER_SAMPLE_ARM 0x8F65
#endif

View File

@ -114,8 +114,7 @@ bool GrGLShaderBuilder::genProgram(const GrEffectStage* colorStages[],
///////////////////////////////////////////////////////////////////////////
// emit code to read the dst copy texture, if necessary
if (kNoDstRead_DstReadKey != header.fDstReadKey &&
GrGLCaps::kNone_FBFetchType == fGpu->glCaps().fbFetchType()) {
if (kNoDstRead_DstReadKey != header.fDstReadKey && !fGpu->glCaps().fbFetchSupport()) {
bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & header.fDstReadKey);
const char* dstCopyTopLeftName;
const char* dstCopyCoordScaleName;
@ -280,37 +279,6 @@ bool GrGLShaderBuilder::enableFeature(GLSLFeature feature) {
}
}
bool GrGLShaderBuilder::enablePrivateFeature(GLSLPrivateFeature feature) {
switch (feature) {
case kFragCoordConventions_GLSLPrivateFeature:
if (!fGpu->glCaps().fragCoordConventionsSupport()) {
return false;
}
if (fGpu->glslGeneration() < k150_GrGLSLGeneration) {
this->addFSFeature(1 << kFragCoordConventions_GLSLPrivateFeature,
"GL_ARB_fragment_coord_conventions");
}
return true;
case kEXTShaderFramebufferFetch_GLSLPrivateFeature:
if (GrGLCaps::kEXT_FBFetchType != fGpu->glCaps().fbFetchType()) {
return false;
}
this->addFSFeature(1 << kEXTShaderFramebufferFetch_GLSLPrivateFeature,
"GL_EXT_shader_framebuffer_fetch");
return true;
case kNVShaderFramebufferFetch_GLSLPrivateFeature:
if (GrGLCaps::kNV_FBFetchType != fGpu->glCaps().fbFetchType()) {
return false;
}
this->addFSFeature(1 << kNVShaderFramebufferFetch_GLSLPrivateFeature,
"GL_NV_shader_framebuffer_fetch");
return true;
default:
SkFAIL("Unexpected GLSLPrivateFeature requested.");
return false;
}
}
void GrGLShaderBuilder::addFSFeature(uint32_t featureBit, const char* extensionName) {
if (!(featureBit & fFSFeaturesAddedMask)) {
fFSExtensions.appendf("#extension %s: require\n", extensionName);
@ -342,14 +310,11 @@ const char* GrGLShaderBuilder::dstColor() {
return "";
}
}
static const char kFBFetchColorName[] = "gl_LastFragData[0]";
GrGLCaps::FBFetchType fetchType = fGpu->glCaps().fbFetchType();
if (GrGLCaps::kEXT_FBFetchType == fetchType) {
SkAssertResult(this->enablePrivateFeature(kEXTShaderFramebufferFetch_GLSLPrivateFeature));
return kFBFetchColorName;
} else if (GrGLCaps::kNV_FBFetchType == fetchType) {
SkAssertResult(this->enablePrivateFeature(kNVShaderFramebufferFetch_GLSLPrivateFeature));
return kFBFetchColorName;
if (fGpu->glCaps().fbFetchSupport()) {
this->addFSFeature(1 << (kLastGLSLPrivateFeature + 1),
fGpu->glCaps().fbFetchExtensionString());
return fGpu->glCaps().fbFetchColorName();
} else if (fOutput.fUniformHandles.fDstCopySamplerUni.isValid()) {
return kDstCopyColorName;
} else {
@ -389,7 +354,7 @@ void GrGLShaderBuilder::fsAppendTextureLookupAndModulate(
GrGLShaderBuilder::DstReadKey GrGLShaderBuilder::KeyForDstRead(const GrTexture* dstCopy,
const GrGLCaps& caps) {
uint32_t key = kYesDstRead_DstReadKeyBit;
if (GrGLCaps::kNone_FBFetchType != caps.fbFetchType()) {
if (caps.fbFetchSupport()) {
return key;
}
SkASSERT(NULL != dstCopy);
@ -500,7 +465,10 @@ const char* GrGLShaderBuilder::fragmentPosition() {
return "gl_FragCoord";
} else if (fGpu->glCaps().fragCoordConventionsSupport()) {
if (!fSetupFragPosition) {
SkAssertResult(this->enablePrivateFeature(kFragCoordConventions_GLSLPrivateFeature));
if (fGpu->glslGeneration() < k150_GrGLSLGeneration) {
this->addFSFeature(1 << kFragCoordConventions_GLSLPrivateFeature,
"GL_ARB_fragment_coord_conventions");
}
fFSInputs.push_back().set(kVec4f_GrSLType,
GrGLShaderVar::kIn_TypeModifier,
"gl_FragCoord",

View File

@ -371,8 +371,7 @@ private:
*/
enum GLSLPrivateFeature {
kFragCoordConventions_GLSLPrivateFeature = kLastGLSLFeature + 1,
kEXTShaderFramebufferFetch_GLSLPrivateFeature,
kNVShaderFramebufferFetch_GLSLPrivateFeature,
kLastGLSLPrivateFeature = kFragCoordConventions_GLSLPrivateFeature
};
bool enablePrivateFeature(GLSLPrivateFeature);

View File

@ -275,6 +275,13 @@ void GrGpuGL::onResetContext(uint32_t resetBits) {
// currently part of our gl interface. There are probably others as
// well.
}
if (kGLES_GrGLStandard == this->glStandard() &&
fGLContext.hasExtension("GL_ARM_shader_framebuffer_fetch")) {
// The arm extension requires specifically enabling MSAA fetching per sample.
// On some devices this may have a perf hit. Also multiple render targets are disabled
GL_CALL(Enable(GR_GL_FETCH_PER_SAMPLE_ARM));
}
fHWWriteToColor = kUnknown_TriState;
// we only ever use lines in hairline mode
GL_CALL(LineWidth(1));
@ -1490,7 +1497,7 @@ void GrGpuGL::discard(GrRenderTarget* renderTarget) {
GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, glRT->renderFBOID()));
}
switch (this->glCaps().invalidateFBType()) {
case GrGLCaps::kNone_FBFetchType:
case GrGLCaps::kNone_InvalidateFBType:
SkFAIL("Should never get here.");
break;
case GrGLCaps::kInvalidate_InvalidateFBType: