diff options
author | 2013-06-05 23:29:25 +0000 | |
---|---|---|
committer | 2013-06-05 23:29:25 +0000 | |
commit | a15f7e5b96ee3d71fdbcb4f9cf02f6a09b4b11ac (patch) | |
tree | 5e7ada52ebeedc3850364b15ee8f99b58233f220 /src | |
parent | f51e125b949fdda350256c7132ee54c49ea53519 (diff) |
Use all available texture units.
R=robertphillips@google.com, jvanverth@google.com
Author: bsalomon@google.com
Review URL: https://chromiumcodereview.appspot.com/16452007
git-svn-id: http://skia.googlecode.com/svn/trunk@9451 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/gl/GrGLCaps.cpp | 9 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.h | 6 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.cpp | 65 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.h | 6 |
4 files changed, 30 insertions, 56 deletions
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index 8b296e360b..fd74d50d71 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -28,6 +28,7 @@ void GrGLCaps::reset() { fFBFetchType = kNone_FBFetchType; fMaxFragmentUniformVectors = 0; fMaxVertexAttributes = 0; + fMaxFragmentTextureUnits = 0; fRGBA8RenderbufferSupport = false; fBGRAFormatSupport = false; fBGRAIsInternalFormat = false; @@ -59,6 +60,7 @@ GrGLCaps& GrGLCaps::operator = (const GrGLCaps& caps) { fStencilVerifiedColorConfigs = caps.fStencilVerifiedColorConfigs; fMaxFragmentUniformVectors = caps.fMaxFragmentUniformVectors; fMaxVertexAttributes = caps.fMaxVertexAttributes; + fMaxFragmentTextureUnits = caps.fMaxFragmentTextureUnits; fMSFBOType = caps.fMSFBOType; fCoverageAAType = caps.fCoverageAAType; fMSAACoverageModes = caps.fMSAACoverageModes; @@ -109,6 +111,7 @@ void GrGLCaps::init(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) { fMaxFragmentUniformVectors = max / 4; } GR_GL_GetIntegerv(gli, GR_GL_MAX_VERTEX_ATTRIBS, &fMaxVertexAttributes); + GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &fMaxFragmentTextureUnits); if (kDesktop_GrGLBinding == binding) { fRGBA8RenderbufferSupport = true; @@ -222,12 +225,6 @@ void GrGLCaps::init(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) { /************************************************************************** * GrDrawTargetCaps fields **************************************************************************/ - GrGLint maxTextureUnits; - // check FS and fixed-function texture unit limits - // we only use textures in the fragment stage currently. - // checks are > to make sure we have a spare unit. - GR_GL_GetIntegerv(gli, GR_GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits); - GrGLint numFormats; GR_GL_GetIntegerv(gli, GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numFormats); if (numFormats) { diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h index 01fbceee04..0b625a5a3a 100644 --- a/src/gpu/gl/GrGLCaps.h +++ b/src/gpu/gl/GrGLCaps.h @@ -215,9 +215,12 @@ public: /// The maximum number of fragment uniform vectors (GLES has min. 16). int maxFragmentUniformVectors() const { return fMaxFragmentUniformVectors; } - // maximum number of attribute values per vertex + /// maximum number of attribute values per vertex int maxVertexAttributes() const { return fMaxVertexAttributes; } + /// maximum number of texture units accessible in the fragment shader. + int maxFragmentTextureUnits() const { return fMaxFragmentTextureUnits; } + /// ES requires an extension to support RGBA8 in RenderBufferStorage bool rgba8RenderbufferSupport() const { return fRGBA8RenderbufferSupport; } @@ -332,6 +335,7 @@ private: int fMaxFragmentUniformVectors; int fMaxVertexAttributes; + int fMaxFragmentTextureUnits; MSFBOType fMSFBOType; CoverageAAType fCoverageAAType; diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp index 0c47060e4f..2f218a0c86 100644 --- a/src/gpu/gl/GrGpuGL.cpp +++ b/src/gpu/gl/GrGpuGL.cpp @@ -20,9 +20,6 @@ static const GrGLint GR_INVAL_GLINT = ~0; #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X) #define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->glInterface(), RET, X) -// we use a spare texture unit to avoid -// mucking with the state of any of the stages. -static const int SPARE_TEX_UNIT = GrDrawState::kNumStages; #define SKIP_CACHE_CHECK true @@ -118,35 +115,6 @@ bool GrGpuGL::BlendCoeffReferencesConstant(GrBlendCoeff coeff) { static bool gPrintStartupSpew; -static bool fbo_test(const GrGLInterface* gl, int w, int h) { - - GR_GL_CALL(gl, ActiveTexture(GR_GL_TEXTURE0 + SPARE_TEX_UNIT)); - - GrGLuint testFBO; - GR_GL_CALL(gl, GenFramebuffers(1, &testFBO)); - GR_GL_CALL(gl, BindFramebuffer(GR_GL_FRAMEBUFFER, testFBO)); - GrGLuint testRTTex; - GR_GL_CALL(gl, GenTextures(1, &testRTTex)); - GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, testRTTex)); - // some implementations require texture to be mip-map complete before - // FBO with level 0 bound as color attachment will be framebuffer complete. - GR_GL_CALL(gl, TexParameteri(GR_GL_TEXTURE_2D, - GR_GL_TEXTURE_MIN_FILTER, - GR_GL_NEAREST)); - GR_GL_CALL(gl, TexImage2D(GR_GL_TEXTURE_2D, 0, GR_GL_RGBA, w, h, - 0, GR_GL_RGBA, GR_GL_UNSIGNED_BYTE, NULL)); - GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, 0)); - GR_GL_CALL(gl, FramebufferTexture2D(GR_GL_FRAMEBUFFER, - GR_GL_COLOR_ATTACHMENT0, - GR_GL_TEXTURE_2D, testRTTex, 0)); - GrGLenum status; - GR_GL_CALL_RET(gl, status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); - GR_GL_CALL(gl, DeleteFramebuffers(1, &testFBO)); - GR_GL_CALL(gl, DeleteTextures(1, &testRTTex)); - - return status == GR_GL_FRAMEBUFFER_COMPLETE; -} - GrGpuGL::GrGpuGL(const GrGLContext& ctx, GrContext* context) : GrGpu(context) , fGLContext(ctx) { @@ -155,6 +123,8 @@ GrGpuGL::GrGpuGL(const GrGLContext& ctx, GrContext* context) fCaps.reset(SkRef(ctx.info().caps())); + fHWBoundTextures.reset(ctx.info().caps()->maxFragmentTextureUnits()); + fillInConfigRenderableTable(); @@ -183,9 +153,6 @@ GrGpuGL::GrGpuGL(const GrGLContext& ctx, GrContext* context) GrAssert(this->glCaps().maxVertexAttributes() >= GrDrawState::kMaxVertexAttribCnt); fLastSuccessfulStencilFmtIdx = 0; - if (false) { // avoid bit rot, suppress warning - fbo_test(this->glInterface(), 0, 0); - } } GrGpuGL::~GrGpuGL() { @@ -361,7 +328,7 @@ void GrGpuGL::onResetContext() { fHWBlendState.invalidate(); - for (int s = 0; s < GrDrawState::kNumStages; ++s) { + for (int s = 0; s < fHWBoundTextures.count(); ++s) { fHWBoundTextures[s] = NULL; } @@ -473,7 +440,6 @@ GrTexture* GrGpuGL::onWrapBackendTexture(const GrBackendTextureDesc& desc) { return NULL; } - this->setSpareTextureUnit(); return texture; } @@ -527,7 +493,7 @@ bool GrGpuGL::onWriteTexturePixels(GrTexture* texture, } GrGLTexture* glTex = static_cast<GrGLTexture*>(texture); - this->setSpareTextureUnit(); + this->setScratchTextureUnit(); GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTex->textureID())); GrGLTexture::Desc desc; desc.fFlags = glTex->desc().fFlags; @@ -952,7 +918,7 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc, return return_null_texture(); } - this->setSpareTextureUnit(); + this->setScratchTextureUnit(); GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTexDesc.fTextureID)); // Some drivers like to know filter/wrap before seeing glTexImage2D. Some @@ -2102,7 +2068,7 @@ void GrGpuGL::notifyRenderTargetDelete(GrRenderTarget* renderTarget) { } void GrGpuGL::notifyTextureDelete(GrGLTexture* texture) { - for (int s = 0; s < GrDrawState::kNumStages; ++s) { + for (int s = 0; s < fHWBoundTextures.count(); ++s) { if (fHWBoundTextures[s] == texture) { // deleting bound texture does implied bind to 0 fHWBoundTextures[s] = NULL; @@ -2222,18 +2188,23 @@ bool GrGpuGL::configToGLFormats(GrPixelConfig config, } void GrGpuGL::setTextureUnit(int unit) { - GrAssert(unit >= 0 && unit < GrDrawState::kNumStages); - if (fHWActiveTextureUnitIdx != unit) { + GrAssert(unit >= 0 && unit < fHWBoundTextures.count()); + if (unit != fHWActiveTextureUnitIdx) { GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + unit)); fHWActiveTextureUnitIdx = unit; } } -void GrGpuGL::setSpareTextureUnit() { - if (fHWActiveTextureUnitIdx != (GR_GL_TEXTURE0 + SPARE_TEX_UNIT)) { - GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + SPARE_TEX_UNIT)); - fHWActiveTextureUnitIdx = SPARE_TEX_UNIT; +void GrGpuGL::setScratchTextureUnit() { + // Bind the last texture unit since it is the least likely to be used by GrGLProgram. + int lastUnitIdx = fHWBoundTextures.count() - 1; + if (lastUnitIdx != fHWActiveTextureUnitIdx) { + GL_CALL(ActiveTexture(GR_GL_TEXTURE0 + lastUnitIdx)); + fHWActiveTextureUnitIdx = lastUnitIdx; } + // clear out the this field so that if a program does use this unit it will rebind the correct + // texture. + fHWBoundTextures[lastUnitIdx] = NULL; } namespace { @@ -2370,7 +2341,7 @@ bool GrGpuGL::onCopySurface(GrSurface* dst, srcRect.height(), src->origin()); - this->setSpareTextureUnit(); + this->setScratchTextureUnit(); GL_CALL(BindTexture(GR_GL_TEXTURE_2D, dstTex->textureID())); GrGLint dstY; if (kBottomLeft_GrSurfaceOrigin == dst->origin()) { diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h index 094fca1f1b..85cace71fb 100644 --- a/src/gpu/gl/GrGpuGL.h +++ b/src/gpu/gl/GrGpuGL.h @@ -227,7 +227,9 @@ private: // determines valid stencil formats void initStencilFormats(); - void setSpareTextureUnit(); + // sets a texture unit to use for texture operations other than binding a texture to a program. + // ensures that such operations don't negatively interact with tracking bound textures. + void setScratchTextureUnit(); // bound is region that may be modified and therefore has to be resolved. // NULL means whole target. Can be an empty rect. @@ -425,7 +427,7 @@ private: TriState fHWWriteToColor; TriState fHWDitherEnabled; GrRenderTarget* fHWBoundRenderTarget; - GrTexture* fHWBoundTextures[GrDrawState::kNumStages]; + SkTArray<GrTexture*, true> fHWBoundTextures; ///@} // we record what stencil format worked last time to hopefully exit early |