diff options
Diffstat (limited to 'src/gpu/gl')
-rw-r--r-- | src/gpu/gl/GrGLBuffer.cpp | 4 | ||||
-rw-r--r-- | src/gpu/gl/GrGLBuffer.h | 13 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.cpp | 18 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.h | 9 | ||||
-rw-r--r-- | src/gpu/gl/GrGLGpu.cpp | 124 | ||||
-rw-r--r-- | src/gpu/gl/GrGLGpu.h | 24 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.cpp | 42 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.h | 15 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgramDataManager.cpp | 3 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgramDesc.cpp | 29 |
10 files changed, 218 insertions, 63 deletions
diff --git a/src/gpu/gl/GrGLBuffer.cpp b/src/gpu/gl/GrGLBuffer.cpp index 6e1ce58588..24fd59267d 100644 --- a/src/gpu/gl/GrGLBuffer.cpp +++ b/src/gpu/gl/GrGLBuffer.cpp @@ -96,7 +96,8 @@ GrGLBuffer::GrGLBuffer(GrGLGpu* gpu, size_t size, GrBufferType intendedType, fBufferID(0), fSizeInBytes(size), fUsage(gr_to_gl_access_pattern(intendedType, accessPattern)), - fGLSizeInBytes(0) { + fGLSizeInBytes(0), + fHasAttachedToTexture(false) { if (this->isCPUBacked()) { // Core profile uses vertex array objects, which disallow client side arrays. SkASSERT(!gpu->glCaps().isCoreProfile()); @@ -151,6 +152,7 @@ void GrGLBuffer::onRelease() { GL_CALL(DeleteBuffers(1, &fBufferID)); fBufferID = 0; fGLSizeInBytes = 0; + this->glGpu()->notifyBufferReleased(this); } fMapPtr = nullptr; VALIDATE(); diff --git a/src/gpu/gl/GrGLBuffer.h b/src/gpu/gl/GrGLBuffer.h index b3b4feb002..84d05be382 100644 --- a/src/gpu/gl/GrGLBuffer.h +++ b/src/gpu/gl/GrGLBuffer.h @@ -27,6 +27,15 @@ public: GrGLuint bufferID() const { return fBufferID; } size_t baseOffset() const { return reinterpret_cast<size_t>(fCPUData); } + /** + * Returns the actual size of the underlying GL buffer object. In certain cases we may make this + * smaller than the size reported by GrBuffer. + */ + size_t glSizeInBytes() const { return fGLSizeInBytes; } + + void setHasAttachedToTexture() { fHasAttachedToTexture = true; } + bool hasAttachedToTexture() const { return fHasAttachedToTexture; } + protected: GrGLBuffer(GrGLGpu*, size_t size, GrBufferType intendedType, GrAccessPattern, bool cpuBacked, const void* data); @@ -53,8 +62,8 @@ private: GrGLuint fBufferID; size_t fSizeInBytes; GrGLenum fUsage; - size_t fGLSizeInBytes; // In certain cases we make the size of the GL buffer object - // smaller or larger than the size in fDesc. + size_t fGLSizeInBytes; + bool fHasAttachedToTexture; typedef GrBuffer INHERITED; }; diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index 0322a0f57c..f3e494acb9 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -1382,6 +1382,8 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa texStorageSupported = false; } + bool texelBufferSupport = this->shaderCaps()->texelBufferSupport(); + fConfigTable[kUnknown_GrPixelConfig].fFormats.fBaseInternalFormat = 0; fConfigTable[kUnknown_GrPixelConfig].fFormats.fSizedInternalFormat = 0; fConfigTable[kUnknown_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = 0; @@ -1408,6 +1410,9 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa if (texStorageSupported) { fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag; } + if (texelBufferSupport) { + fConfigTable[kRGBA_8888_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag; + } fConfigTable[kRGBA_8888_GrPixelConfig].fSwizzle = GrSwizzle::RGBA(); fConfigTable[kBGRA_8888_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = @@ -1567,6 +1572,9 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = GR_GL_RED; fConfigTable[kAlpha_8_GrPixelConfig].fSwizzle = GrSwizzle::RRRR(); + if (texelBufferSupport) { + fConfigTable[kAlpha_8_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag; + } } else { fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA; fConfigTable[kAlpha_8_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA8; @@ -1635,6 +1643,9 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa if (texStorageSupported) { fConfigTable[kRGBA_float_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag; } + if (texelBufferSupport) { + fConfigTable[kRGBA_float_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag; + } fConfigTable[kRGBA_float_GrPixelConfig].fSwizzle = GrSwizzle::RGBA(); if (this->textureRedSupport()) { @@ -1643,6 +1654,10 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fExternalFormat[kOther_ExternalFormatUsage] = GR_GL_RED; fConfigTable[kAlpha_half_GrPixelConfig].fSwizzle = GrSwizzle::RRRR(); + if (texelBufferSupport) { + fConfigTable[kAlpha_half_GrPixelConfig].fFlags |= + ConfigInfo::kCanUseWithTexelBuffer_Flag; + } } else { fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fBaseInternalFormat = GR_GL_ALPHA; fConfigTable[kAlpha_half_GrPixelConfig].fFormats.fSizedInternalFormat = GR_GL_ALPHA16F; @@ -1691,6 +1706,9 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa if (texStorageSupported) { fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseTexStorage_Flag; } + if (texelBufferSupport) { + fConfigTable[kRGBA_half_GrPixelConfig].fFlags |= ConfigInfo::kCanUseWithTexelBuffer_Flag; + } fConfigTable[kRGBA_half_GrPixelConfig].fSwizzle = GrSwizzle::RGBA(); // Compressed texture support diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h index e2bc100cae..1602a0f63d 100644 --- a/src/gpu/gl/GrGLCaps.h +++ b/src/gpu/gl/GrGLCaps.h @@ -135,11 +135,19 @@ public: return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kCanUseTexStorage_Flag); } + bool canUseConfigWithTexelBuffer(GrPixelConfig config) const { + return SkToBool(fConfigTable[config].fFlags & ConfigInfo::kCanUseWithTexelBuffer_Flag); + } + /** Returns the mapping between GrPixelConfig components and GL internal format components. */ const GrSwizzle& configSwizzle(GrPixelConfig config) const { return fConfigTable[config].fSwizzle; } + GrGLenum configSizedInternalFormat(GrPixelConfig config) const { + return fConfigTable[config].fFormats.fSizedInternalFormat; + } + bool getTexImageFormats(GrPixelConfig surfaceConfig, GrPixelConfig externalConfig, GrGLenum* internalFormat, GrGLenum* externalFormat, GrGLenum* externalType) const; @@ -468,6 +476,7 @@ private: kRenderable_Flag = 0x4, kRenderableWithMSAA_Flag = 0x8, kCanUseTexStorage_Flag = 0x10, + kCanUseWithTexelBuffer_Flag = 0x20, }; uint32_t fFlags; diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index e8b5755849..af5955014a 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -194,6 +194,7 @@ GrGLGpu::GrGLGpu(GrGLContext* ctx, GrContext* context) , fTempSrcFBOID(0) , fTempDstFBOID(0) , fStencilClearFBOID(0) + , fHWMaxUsedBufferTextureUnit(-1) , fHWPLSEnabled(false) , fPLSHasBeenUsed(false) , fHWMinSampleShading(0.0) { @@ -223,6 +224,10 @@ GrGLGpu::GrGLGpu(GrGLContext* ctx, GrContext* context) } GR_STATIC_ASSERT(6 == SK_ARRAY_COUNT(fHWBufferState)); + if (this->caps()->shaderCaps()->texelBufferSupport()) { + fHWBufferTextures.reset(this->glCaps().glslCaps()->maxCombinedSamplers()); + } + if (this->glCaps().shaderCaps()->pathRenderingSupport()) { fPathRendering.reset(new GrGLPathRendering(this)); } @@ -522,6 +527,10 @@ void GrGLGpu::onResetContext(uint32_t resetBits) { for (int s = 0; s < fHWBoundTextureUniqueIDs.count(); ++s) { fHWBoundTextureUniqueIDs[s] = SK_InvalidUniqueID; } + for (int b = 0; b < fHWBufferTextures.count(); ++b) { + SkASSERT(this->caps()->shaderCaps()->texelBufferSupport()); + fHWBufferTextures[b].fKnownBound = false; + } } if (resetBits & kBlend_GrGLBackendState) { @@ -2052,14 +2061,7 @@ bool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcesso this->flushBlend(blendInfo, swizzle); } - SkSTArray<8, const GrTextureAccess*> textureAccesses; - program->setData(primProc, pipeline, &textureAccesses); - - int numTextureAccesses = textureAccesses.count(); - for (int i = 0; i < numTextureAccesses; i++) { - this->bindTexture(i, textureAccesses[i]->getParams(), pipeline.getAllowSRGBInputs(), - static_cast<GrGLTexture*>(textureAccesses[i]->getTexture())); - } + program->setData(primProc, pipeline); GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTarget()); this->flushStencil(pipeline.getStencil()); @@ -2147,6 +2149,31 @@ GrGLenum GrGLGpu::bindBuffer(GrBufferType type, const GrGLBuffer* buffer) { return bufferState.fGLTarget; } +void GrGLGpu::notifyBufferReleased(const GrGLBuffer* buffer) { + if (buffer->hasAttachedToTexture()) { + // Detach this buffer from any textures to ensure the underlying memory is freed. + uint32_t uniqueID = buffer->getUniqueID(); + for (int i = fHWMaxUsedBufferTextureUnit; i >= 0; --i) { + auto& buffTex = fHWBufferTextures[i]; + if (uniqueID != buffTex.fAttachedBufferUniqueID) { + continue; + } + if (i == fHWMaxUsedBufferTextureUnit) { + --fHWMaxUsedBufferTextureUnit; + } + + this->setTextureUnit(i); + if (!buffTex.fKnownBound) { + SkASSERT(buffTex.fTextureID); + GL_CALL(BindTexture(GR_GL_TEXTURE_BUFFER, buffTex.fTextureID)); + buffTex.fKnownBound = true; + } + GL_CALL(TexBuffer(GR_GL_TEXTURE_BUFFER, + this->glCaps().configSizedInternalFormat(buffTex.fTexelConfig), 0)); + } + } +} + void GrGLGpu::disableScissor() { if (kNo_TriState != fHWScissorSettings.fEnabled) { GL_CALL(Disable(GR_GL_SCISSOR_TEST)); @@ -3264,21 +3291,78 @@ void GrGLGpu::bindTexture(int unitIdx, const GrTextureParams& params, bool dstCo (setAll || memcmp(newTexParams.fSwizzleRGBA, oldTexParams.fSwizzleRGBA, sizeof(newTexParams.fSwizzleRGBA)))) { + this->setTextureSwizzle(unitIdx, target, newTexParams.fSwizzleRGBA); + } + texture->setCachedTexParams(newTexParams, this->getResetTimestamp()); +} + +void GrGLGpu::bindTexelBuffer(int unitIdx, intptr_t offsetInBytes, GrPixelConfig texelConfig, + GrGLBuffer* buffer) { + SkASSERT(this->glCaps().canUseConfigWithTexelBuffer(texelConfig)); + SkASSERT(unitIdx >= 0 && unitIdx < fHWBufferTextures.count()); + SkASSERT(offsetInBytes >= 0 && offsetInBytes < (intptr_t) buffer->glSizeInBytes()); + + BufferTexture& buffTex = fHWBufferTextures[unitIdx]; + + if (!buffTex.fKnownBound) { + if (!buffTex.fTextureID) { + GL_CALL(GenTextures(1, &buffTex.fTextureID)); + if (!buffTex.fTextureID) { + return; + } + } + this->setTextureUnit(unitIdx); - if (this->glStandard() == kGLES_GrGLStandard) { - // ES3 added swizzle support but not GL_TEXTURE_SWIZZLE_RGBA. - const GrGLenum* swizzle = newTexParams.fSwizzleRGBA; - GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_R, swizzle[0])); - GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_G, swizzle[1])); - GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_B, swizzle[2])); - GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_A, swizzle[3])); - } else { - GR_STATIC_ASSERT(sizeof(newTexParams.fSwizzleRGBA[0]) == sizeof(GrGLint)); - const GrGLint* swizzle = reinterpret_cast<const GrGLint*>(newTexParams.fSwizzleRGBA); - GL_CALL(TexParameteriv(target, GR_GL_TEXTURE_SWIZZLE_RGBA, swizzle)); + GL_CALL(BindTexture(GR_GL_TEXTURE_BUFFER, buffTex.fTextureID)); + + buffTex.fKnownBound = true; + } + + if (buffer->getUniqueID() != buffTex.fAttachedBufferUniqueID || + buffTex.fOffsetInBytes != offsetInBytes || + buffTex.fTexelConfig != texelConfig || + buffTex.fAttachedSizeInBytes != buffer->glSizeInBytes() - offsetInBytes) { + + size_t attachmentSizeInBytes = buffer->glSizeInBytes() - offsetInBytes; + + this->setTextureUnit(unitIdx); + GL_CALL(TexBufferRange(GR_GL_TEXTURE_BUFFER, + this->glCaps().configSizedInternalFormat(texelConfig), + buffer->bufferID(), + offsetInBytes, + attachmentSizeInBytes)); + + buffTex.fOffsetInBytes = offsetInBytes; + buffTex.fTexelConfig = texelConfig; + buffTex.fAttachedSizeInBytes = attachmentSizeInBytes; + buffTex.fAttachedBufferUniqueID = buffer->getUniqueID(); + + if (this->glCaps().textureSwizzleSupport() && + this->glCaps().configSwizzle(texelConfig) != buffTex.fSwizzle) { + GrGLenum glSwizzle[4]; + get_tex_param_swizzle(texelConfig, this->glCaps(), glSwizzle); + this->setTextureSwizzle(unitIdx, GR_GL_TEXTURE_BUFFER, glSwizzle); + buffTex.fSwizzle = this->glCaps().configSwizzle(texelConfig); } + + buffer->setHasAttachedToTexture(); + fHWMaxUsedBufferTextureUnit = SkTMax(unitIdx, fHWMaxUsedBufferTextureUnit); + } +} + +void GrGLGpu::setTextureSwizzle(int unitIdx, GrGLenum target, const GrGLenum swizzle[]) { + this->setTextureUnit(unitIdx); + if (this->glStandard() == kGLES_GrGLStandard) { + // ES3 added swizzle support but not GL_TEXTURE_SWIZZLE_RGBA. + GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_R, swizzle[0])); + GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_G, swizzle[1])); + GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_B, swizzle[2])); + GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_A, swizzle[3])); + } else { + GR_STATIC_ASSERT(sizeof(swizzle[0]) == sizeof(GrGLint)); + GL_CALL(TexParameteriv(target, GR_GL_TEXTURE_SWIZZLE_RGBA, + reinterpret_cast<const GrGLint*>(swizzle))); } - texture->setCachedTexParams(newTexParams, this->getResetTimestamp()); } void GrGLGpu::flushColorWrite(bool writeColor) { diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h index c2dda0a222..c8b5d70f1b 100644 --- a/src/gpu/gl/GrGLGpu.h +++ b/src/gpu/gl/GrGLGpu.h @@ -60,6 +60,8 @@ public: void bindTexture(int unitIdx, const GrTextureParams& params, bool dstConfigAllowsSRGB, GrGLTexture* texture); + void bindTexelBuffer(int unitIdx, intptr_t offsetInBytes, GrPixelConfig, GrGLBuffer*); + bool onGetReadPixelsInfo(GrSurface* srcSurface, int readWidth, int readHeight, size_t rowBytes, GrPixelConfig readConfig, DrawPreference*, ReadPixelTempDrawInfo*) override; @@ -88,6 +90,9 @@ public: // If the caller wishes to bind an index buffer to a specific VAO, it can call glBind directly. GrGLenum bindBuffer(GrBufferType type, const GrGLBuffer*); + // Called by GrGLBuffer after its buffer object has been destroyed. + void notifyBufferReleased(const GrGLBuffer*); + const GrGLContext* glContextForTesting() const override { return &this->glContext(); } @@ -206,6 +211,8 @@ private: // binds texture unit in GL void setTextureUnit(int unitIdx); + void setTextureSwizzle(int unitIdx, GrGLenum target, const GrGLenum swizzle[]); + // Flushes state from GrPipeline to GL. Returns false if the state couldn't be set. bool flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcessor& primProc); @@ -498,6 +505,23 @@ private: TriState fHWSRGBFramebuffer; SkTArray<uint32_t, true> fHWBoundTextureUniqueIDs; + struct BufferTexture { + BufferTexture() : fTextureID(0), fKnownBound(false), + fAttachedBufferUniqueID(SK_InvalidUniqueID), + fSwizzle(GrSwizzle::RGBA()) {} + + GrGLuint fTextureID; + bool fKnownBound; + intptr_t fOffsetInBytes; + GrPixelConfig fTexelConfig; + size_t fAttachedSizeInBytes; + uint32_t fAttachedBufferUniqueID; + GrSwizzle fSwizzle; + }; + + SkTArray<BufferTexture, true> fHWBufferTextures; + int fHWMaxUsedBufferTextureUnit; + // EXT_raster_multisample. TriState fHWRasterMultisampleEnabled; int fHWNumRasterSamples; diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp index aa828a24c4..6a433e17c5 100644 --- a/src/gpu/gl/GrGLProgram.cpp +++ b/src/gpu/gl/GrGLProgram.cpp @@ -11,6 +11,7 @@ #include "GrProcessor.h" #include "GrCoordTransform.h" #include "GrGLGpu.h" +#include "GrGLBuffer.h" #include "GrGLPathRendering.h" #include "GrPathProcessor.h" #include "GrPipeline.h" @@ -66,46 +67,34 @@ void GrGLProgram::abandon() { /////////////////////////////////////////////////////////////////////////////// -static void append_texture_bindings(const GrProcessor& processor, - SkTArray<const GrTextureAccess*>* textureBindings) { - if (int numTextures = processor.numTextures()) { - const GrTextureAccess** bindings = textureBindings->push_back_n(numTextures); - int i = 0; - do { - bindings[i] = &processor.textureAccess(i); - } while (++i < numTextures); - } -} - -void GrGLProgram::setData(const GrPrimitiveProcessor& primProc, - const GrPipeline& pipeline, - SkTArray<const GrTextureAccess*>* textureBindings) { +void GrGLProgram::setData(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline) { this->setRenderTargetState(primProc, pipeline); // we set the textures, and uniforms for installed processors in a generic way, but subclasses // of GLProgram determine how to set coord transforms + int nextSamplerIdx = 0; fGeometryProcessor->setData(fProgramDataManager, primProc); - append_texture_bindings(primProc, textureBindings); + this->bindTextures(primProc, pipeline.getAllowSRGBInputs(), &nextSamplerIdx); - this->setFragmentData(primProc, pipeline, textureBindings); + this->setFragmentData(primProc, pipeline, &nextSamplerIdx); if (primProc.getPixelLocalStorageState() != GrPixelLocalStorageState::kDraw_GrPixelLocalStorageState) { const GrXferProcessor& xp = pipeline.getXferProcessor(); fXferProcessor->setData(fProgramDataManager, xp); - append_texture_bindings(xp, textureBindings); + this->bindTextures(xp, pipeline.getAllowSRGBInputs(), &nextSamplerIdx); } } void GrGLProgram::setFragmentData(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline, - SkTArray<const GrTextureAccess*>* textureBindings) { + int* nextSamplerIdx) { int numProcessors = fFragmentProcessors.count(); for (int i = 0; i < numProcessors; ++i) { const GrFragmentProcessor& processor = pipeline.getFragmentProcessor(i); fFragmentProcessors[i]->setData(fProgramDataManager, processor); this->setTransformData(primProc, processor, i); - append_texture_bindings(processor, textureBindings); + this->bindTextures(processor, pipeline.getAllowSRGBInputs(), nextSamplerIdx); } } void GrGLProgram::setTransformData(const GrPrimitiveProcessor& primProc, @@ -145,3 +134,18 @@ void GrGLProgram::setRenderTargetState(const GrPrimitiveProcessor& primProc, size, rt->origin()); } } + +void GrGLProgram::bindTextures(const GrProcessor& processor, + bool allowSRGBInputs, + int* nextSamplerIdx) { + for (int i = 0; i < processor.numTextures(); ++i) { + const GrTextureAccess& access = processor.textureAccess(i); + fGpu->bindTexture((*nextSamplerIdx)++, access.getParams(), + allowSRGBInputs, static_cast<GrGLTexture*>(access.getTexture())); + } + for (int i = 0; i < processor.numBuffers(); ++i) { + const GrBufferAccess& access = processor.bufferAccess(i); + fGpu->bindTexelBuffer((*nextSamplerIdx)++, access.offsetInBytes(), access.texelConfig(), + static_cast<GrGLBuffer*>(access.buffer())); + } +} diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h index 22678cb6a3..c70b1bd0e2 100644 --- a/src/gpu/gl/GrGLProgram.h +++ b/src/gpu/gl/GrGLProgram.h @@ -94,8 +94,7 @@ public: * the program is bound before calling, and to bind the outgoing textures to their respective * units upon return. (Each index in the array corresponds to its matching GL texture unit.) */ - void setData(const GrPrimitiveProcessor&, const GrPipeline&, - SkTArray<const GrTextureAccess*>* textureBindings); + void setData(const GrPrimitiveProcessor&, const GrPipeline&); protected: typedef GrGLSLProgramDataManager::UniformHandle UniformHandle; @@ -113,16 +112,16 @@ protected: const GrGLSLFragProcs& fragmentProcessors, SkTArray<UniformHandle>* passSamplerUniforms); - // A templated helper to loop over effects, set the transforms(via subclass) and bind textures - void setFragmentData(const GrPrimitiveProcessor&, const GrPipeline&, - SkTArray<const GrTextureAccess*>* textureBindings); - void setTransformData(const GrPrimitiveProcessor&, - const GrFragmentProcessor&, - int index); + // A helper to loop over effects, set the transforms (via subclass) and bind textures + void setFragmentData(const GrPrimitiveProcessor&, const GrPipeline&, int* nextSamplerIdx); + void setTransformData(const GrPrimitiveProcessor&, const GrFragmentProcessor&, int index); // Helper for setData() that sets the view matrix and loads the render target height uniform void setRenderTargetState(const GrPrimitiveProcessor&, const GrPipeline&); + // Helper for setData() that binds textures and texel buffers to the appropriate texture units + void bindTextures(const GrProcessor&, bool allowSRGBInputs, int* nextSamplerIdx); + // these reflect the current values of uniforms (GL uniform values travel with program) RenderTargetState fRenderTargetState; BuiltinUniformHandles fBuiltinUniformHandles; diff --git a/src/gpu/gl/GrGLProgramDataManager.cpp b/src/gpu/gl/GrGLProgramDataManager.cpp index d5b48f7061..6b2e1118cb 100644 --- a/src/gpu/gl/GrGLProgramDataManager.cpp +++ b/src/gpu/gl/GrGLProgramDataManager.cpp @@ -63,8 +63,7 @@ GrGLProgramDataManager::GrGLProgramDataManager(GrGLGpu* gpu, GrGLuint programID, void GrGLProgramDataManager::setSampler(UniformHandle u, int texUnit) const { const Uniform& uni = fUniforms[u.toIndex()]; - SkASSERT(uni.fType == kSampler2D_GrSLType || uni.fType == kSamplerExternal_GrSLType || - uni.fType == kSampler2DRect_GrSLType); + SkASSERT(GrSLTypeIsSamplerType(uni.fType)); SkASSERT(GrGLSLShaderVar::kNonArray == uni.fArrayCount); // FIXME: We still insert a single sampler uniform for every stage. If the shader does not // reference the sampler then the compiler may have optimized it out. Uncomment this assert diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp index 5e9fe5fcc6..801224c9b6 100644 --- a/src/gpu/gl/GrGLProgramDesc.cpp +++ b/src/gpu/gl/GrGLProgramDesc.cpp @@ -17,11 +17,11 @@ #include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLCaps.h" -static uint16_t texture_key(GrSLType samplerType, GrPixelConfig config, GrShaderFlags visibility, +static uint16_t sampler_key(GrSLType samplerType, GrPixelConfig config, GrShaderFlags visibility, const GrGLSLCaps& caps) { enum { kFirstSamplerType = kSampler2D_GrSLType, - kLastSamplerType = kSampler2DRect_GrSLType, + kLastSamplerType = kSamplerBuffer_GrSLType, kSamplerTypeKeyBits = 4 }; GR_STATIC_ASSERT(kLastSamplerType - kFirstSamplerType < (1 << kSamplerTypeKeyBits)); @@ -34,23 +34,30 @@ static uint16_t texture_key(GrSLType samplerType, GrPixelConfig config, GrShader (caps.samplerPrecision(config, visibility) << (8 + kSamplerTypeKeyBits))); } -static void add_texture_key(GrProcessorKeyBuilder* b, const GrProcessor& proc, - const GrGLSLCaps& caps) { +static void add_sampler_keys(GrProcessorKeyBuilder* b, const GrProcessor& proc, + const GrGLSLCaps& caps) { int numTextures = proc.numTextures(); + int numSamplers = numTextures + proc.numBuffers(); // Need two bytes per key (swizzle, sampler type, and precision). - int word32Count = (proc.numTextures() + 1) / 2; + int word32Count = (numSamplers + 1) / 2; if (0 == word32Count) { return; } uint16_t* k16 = SkTCast<uint16_t*>(b->add32n(word32Count)); - for (int i = 0; i < numTextures; ++i) { + int i = 0; + for (; i < numTextures; ++i) { const GrTextureAccess& access = proc.textureAccess(i); const GrTexture* tex = access.getTexture(); - k16[i] = texture_key(tex->samplerType(), tex->config(), access.getVisibility(), caps); + k16[i] = sampler_key(tex->samplerType(), tex->config(), access.getVisibility(), caps); + } + for (; i < numSamplers; ++i) { + const GrBufferAccess& access = proc.bufferAccess(i - numTextures); + k16[i] = sampler_key(kSamplerBuffer_GrSLType, access.texelConfig(), access.visibility(), + caps); } - // zero the last 16 bits if the number of textures is odd. - if (numTextures & 0x1) { - k16[numTextures] = 0; + // zero the last 16 bits if the number of samplers is odd. + if (numSamplers & 0x1) { + k16[numSamplers] = 0; } } @@ -76,7 +83,7 @@ static bool gen_meta_key(const GrProcessor& proc, return false; } - add_texture_key(b, proc, glslCaps); + add_sampler_keys(b, proc, glslCaps); uint32_t* key = b->add32n(2); key[0] = (classID << 16) | SkToU32(processorKeySize); |