}
bool GrDrawTarget::setupDstReadIfNecessary(DrawInfo* info) {
- if (!this->getDrawState().willEffectReadDst()) {
+ if (this->caps()->dstReadInShaderSupport() || !this->getDrawState().willEffectReadDst()) {
return true;
}
GrRenderTarget* rt = this->drawState()->getRenderTarget();
GrPrintf("Dual Source Blending Support: %s\n", gNY[fDualSourceBlendingSupport]);
GrPrintf("Buffer Lock Support : %s\n", gNY[fBufferLockSupport]);
GrPrintf("Path Stenciling Support : %s\n", gNY[fPathStencilingSupport]);
+ GrPrintf("Dst Read In Shader Support : %s\n", gNY[fDstReadInShaderSupport]);
GrPrintf("Max Texture Size : %d\n", fMaxTextureSize);
GrPrintf("Max Render Target Size : %d\n", fMaxRenderTargetSize);
GrPrintf("Max Sample Count : %d\n", fMaxSampleCount);
bool dualSourceBlendingSupport() const { return fDualSourceBlendingSupport; }
bool bufferLockSupport() const { return fBufferLockSupport; }
bool pathStencilingSupport() const { return fPathStencilingSupport; }
+ bool dstReadInShaderSupport() const { return fDstReadInShaderSupport; }
int maxRenderTargetSize() const { return fMaxRenderTargetSize; }
int maxTextureSize() const { return fMaxTextureSize; }
bool fDualSourceBlendingSupport : 1;
bool fBufferLockSupport : 1;
bool fPathStencilingSupport : 1;
+ bool fDstReadInShaderSupport : 1;
int fMaxRenderTargetSize;
int fMaxTextureSize;
fStencilVerifiedColorConfigs.reset();
fMSFBOType = kNone_MSFBOType;
fCoverageAAType = kNone_CoverageAAType;
+ fFBFetchType = kNone_FBFetchType;
fMaxFragmentUniformVectors = 0;
fMaxVertexAttributes = 0;
fRGBA8RenderbufferSupport = false;
fMSFBOType = caps.fMSFBOType;
fCoverageAAType = caps.fCoverageAAType;
fMSAACoverageModes = caps.fMSAACoverageModes;
+ fFBFetchType = caps.fFBFetchType;
fRGBA8RenderbufferSupport = caps.fRGBA8RenderbufferSupport;
fBGRAFormatSupport = caps.fBGRAFormatSupport;
fBGRAIsInternalFormat = caps.fBGRAIsInternalFormat;
fVertexArrayObjectSupport = ctxInfo.hasExtension("GL_OES_vertex_array_object");
}
+ if (kES2_GrGLBinding == binding) {
+ if (ctxInfo.hasExtension("GL_EXT_shader_framebuffer_fetch")) {
+ fFBFetchType = kEXT_FBFetchType;
+ } else if (ctxInfo.hasExtension("GL_NV_shader_framebuffer_fetch")) {
+ fFBFetchType = kNV_FBFetchType;
+ }
+ }
+
this->initFSAASupport(ctxInfo, gli);
this->initStencilFormats(ctxInfo);
fPathStencilingSupport = GR_GL_USE_NV_PATH_RENDERING &&
ctxInfo.hasExtension("GL_NV_path_rendering");
+ fDstReadInShaderSupport = kNone_FBFetchType != fFBFetchType;
+
// Enable supported shader-related caps
if (kDesktop_GrGLBinding == binding) {
fDualSourceBlendingSupport = ctxInfo.version() >= GR_GL_VER(3,3) ||
fStencilFormats[i].fTotalBits);
}
+ static const char* kMSFBOExtStr[] = {
+ "None",
+ "ARB",
+ "EXT",
+ "Apple",
+ "IMG MS To Texture",
+ "EXT MS To Texture",
+ };
GR_STATIC_ASSERT(0 == kNone_MSFBOType);
GR_STATIC_ASSERT(1 == kDesktop_ARB_MSFBOType);
GR_STATIC_ASSERT(2 == kDesktop_EXT_MSFBOType);
GR_STATIC_ASSERT(3 == kES_Apple_MSFBOType);
GR_STATIC_ASSERT(4 == kES_IMG_MsToTexture_MSFBOType);
GR_STATIC_ASSERT(5 == kES_EXT_MsToTexture_MSFBOType);
- static const char* gMSFBOExtStr[] = {
+ GR_STATIC_ASSERT(GR_ARRAY_COUNT(kMSFBOExtStr) == kLast_MSFBOType + 1);
+
+ static const char* kFBFetchTypeStr[] = {
"None",
- "ARB",
"EXT",
- "Apple",
- "IMG MS To Texture",
- "EXT MS To Texture",
+ "NV",
};
- GrPrintf("MSAA Type: %s\n", gMSFBOExtStr[fMSFBOType]);
+ GR_STATIC_ASSERT(0 == kNone_FBFetchType);
+ GR_STATIC_ASSERT(1 == kEXT_FBFetchType);
+ GR_STATIC_ASSERT(2 == kNV_FBFetchType);
+ GR_STATIC_ASSERT(GR_ARRAY_COUNT(kFBFetchTypeStr) == kLast_FBFetchType + 1);
+
+
+ GrPrintf("MSAA Type: %s\n", kMSFBOExtStr[fMSFBOType]);
+ GrPrintf("FB Fetch Type: %s\n", kFBFetchTypeStr[fFBFetchType]);
GrPrintf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors);
GrPrintf("Max Vertex Attributes: %d\n", fMaxVertexAttributes);
GrPrintf("Support RGBA8 Render Buffer: %s\n", (fRGBA8RenderbufferSupport ? "YES": "NO"));
* GL_MAX_SAMPLES value.
*/
kES_EXT_MsToTexture_MSFBOType,
+
+ 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 CoverageAAType {
*/
const MSAACoverageMode& getMSAACoverageMode(int desiredSampleCount) const;
+ FBFetchType fbFetchType() const { return fFBFetchType; }
+
/**
* Prints the caps info using GrPrintf.
*/
CoverageAAType fCoverageAAType;
SkTDArray<MSAACoverageMode> fMSAACoverageModes;
+ FBFetchType fFBFetchType;
+
bool fRGBA8RenderbufferSupport : 1;
bool fBGRAFormatSupport : 1;
bool fBGRAIsInternalFormat : 1;
}
if (readsDst) {
- GrAssert(NULL != dstCopy);
- desc->fDstRead = GrGLShaderBuilder::KeyForDstRead(dstCopy->texture(), gpu->glCaps());
+ GrAssert(NULL != dstCopy || gpu->caps()->dstReadInShaderSupport());
+ const GrTexture* dstCopyTexture = NULL;
+ if (NULL != dstCopy) {
+ dstCopyTexture = dstCopy->texture();
+ }
+ desc->fDstRead = GrGLShaderBuilder::KeyForDstRead(dstCopyTexture, gpu->glCaps());
GrAssert(0 != desc->fDstRead);
} else {
desc->fDstRead = 0;
}
-static const char kDstColorName[] = "_dstColor";
+static const char kDstCopyColorName[] = "_dstColor";
///////////////////////////////////////////////////////////////////////////////
} else {
fLocalCoordsVar = fPositionVar;
}
- if (kNoDstRead_DstReadKey != desc.fDstRead) {
+ // Emit code to read the dst copy textue if necessary.
+ if (kNoDstRead_DstReadKey != desc.fDstRead &&
+ GrGLCaps::kNone_FBFetchType == ctxInfo.caps()->fbFetchType()) {
bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & desc.fDstRead);
const char* dstCopyTopLeftName;
const char* dstCopyCoordScaleName;
if (!topDown) {
this->fsCodeAppend("\t_dstTexCoord.y = 1.0 - _dstTexCoord.y;\n");
}
- this->fsCodeAppendf("\tvec4 %s = ", kDstColorName);
+ this->fsCodeAppendf("\tvec4 %s = ", kDstCopyColorName);
this->appendTextureLookup(kFragment_ShaderType, fDstCopySampler, "_dstTexCoord");
this->fsCodeAppend(";\n\n");
}
"GL_ARB_fragment_coord_conventions");
}
return true;
+ case kEXTShaderFramebufferFetch_GLSLPrivateFeature:
+ if (GrGLCaps::kEXT_FBFetchType != fCtxInfo.caps()->fbFetchType()) {
+ return false;
+ }
+ this->addFSFeature(1 << kEXTShaderFramebufferFetch_GLSLPrivateFeature,
+ "GL_EXT_shader_framebuffer_fetch");
+ return true;
+ case kNVShaderFramebufferFetch_GLSLPrivateFeature:
+ if (GrGLCaps::kNV_FBFetchType != fCtxInfo.caps()->fbFetchType()) {
+ return false;
+ }
+ this->addFSFeature(1 << kNVShaderFramebufferFetch_GLSLPrivateFeature,
+ "GL_NV_shader_framebuffer_fetch");
+ return true;
default:
GrCrash("Unexpected GLSLPrivateFeature requested.");
return false;
}
}
-const char* GrGLShaderBuilder::dstColor() const {
- if (fDstCopySampler.isInitialized()) {
- return kDstColorName;
+const char* GrGLShaderBuilder::dstColor() {
+ static const char kFBFetchColorName[] = "gl_LastFragData[0]";
+ GrGLCaps::FBFetchType fetchType = fCtxInfo.caps()->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;
+ } else if (fDstCopySampler.isInitialized()) {
+ return kDstCopyColorName;
} else {
return NULL;
}
GrGLShaderBuilder::DstReadKey GrGLShaderBuilder::KeyForDstRead(const GrTexture* dstCopy,
const GrGLCaps& caps) {
uint32_t key = kYesDstRead_DstReadKeyBit;
+ if (GrGLCaps::kNone_FBFetchType != caps.fbFetchType()) {
+ return key;
+ }
+ GrAssert(NULL != dstCopy);
if (!caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(dstCopy->config())) {
// The fact that the config is alpha-only must be considered when generating code.
key |= kUseAlphaConfig_DstReadKeyBit;
/** Returns the color of the destination pixel. This may be NULL if no effect advertised
that it will read the destination. */
- const char* dstColor() const;
+ const char* dstColor();
/**
* Are explicit local coordinates provided as input to the vertex shader.
* Features that should only be enabled by GrGLShaderBuilder itself.
*/
enum GLSLPrivateFeature {
- kFragCoordConventions_GLSLPrivateFeature = kLastGLSLFeature + 1
+ kFragCoordConventions_GLSLPrivateFeature = kLastGLSLFeature + 1,
+ kEXTShaderFramebufferFetch_GLSLPrivateFeature,
+ kNVShaderFramebufferFetch_GLSLPrivateFeature,
};
bool enablePrivateFeature(GLSLPrivateFeature);