| Index: src/gpu/gl/GrGpuGL.cpp
|
| diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
|
| index ebc34572fed1f1660e43246f7601edfd47afdc4c..4ebf341ceef6ed7744822fb19d5af75d0de274cb 100644
|
| --- a/src/gpu/gl/GrGpuGL.cpp
|
| +++ b/src/gpu/gl/GrGpuGL.cpp
|
| @@ -470,15 +470,16 @@ bool GrGpuGL::onWriteTexturePixels(GrTexture* texture,
|
| GrGLTexture* glTex = static_cast<GrGLTexture*>(texture);
|
|
|
| this->setScratchTextureUnit();
|
| - GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTex->textureID()));
|
| GrGLTexture::Desc desc;
|
| desc.fFlags = glTex->desc().fFlags;
|
| desc.fWidth = glTex->width();
|
| desc.fHeight = glTex->height();
|
| + desc.fDepth = glTex->desc().fDepth;
|
| desc.fConfig = glTex->config();
|
| desc.fSampleCnt = glTex->desc().fSampleCnt;
|
| desc.fTextureID = glTex->textureID();
|
| desc.fOrigin = glTex->origin();
|
| + GL_CALL(BindTexture((desc.fDepth > 0) ? GR_GL_TEXTURE_3D : GR_GL_TEXTURE_2D, desc.fTextureID));
|
|
|
| bool success = false;
|
| if (GrPixelConfigIsCompressed(desc.fConfig)) {
|
| @@ -548,6 +549,11 @@ bool GrGpuGL::uploadTexData(const GrGLTexture::Desc& desc,
|
| // If we're uploading compressed data then we should be using uploadCompressedTexData
|
| SkASSERT(!GrPixelConfigIsCompressed(dataConfig));
|
|
|
| + bool is3DTexture = (desc.fDepth > 0);
|
| + if (is3DTexture && !this->glCaps().has3DTexImageSupport()) {
|
| + return false;
|
| + }
|
| +
|
| size_t bpp = GrBytesPerPixel(dataConfig);
|
| if (!adjust_pixel_ops_params(desc.fWidth, desc.fHeight, bpp, &left, &top,
|
| &width, &height, &data, &rowBytes)) {
|
| @@ -563,7 +569,7 @@ bool GrGpuGL::uploadTexData(const GrGLTexture::Desc& desc,
|
| // MIP levels are all created when the texture is created. So for now we don't use
|
| // texture storage.
|
| bool useTexStorage = false &&
|
| - isNewTexture &&
|
| + isNewTexture && !is3DTexture &&
|
| this->glCaps().texStorageSupport();
|
|
|
| if (useTexStorage && kGL_GrGLStandard == this->glStandard()) {
|
| @@ -575,8 +581,8 @@ bool GrGpuGL::uploadTexData(const GrGLTexture::Desc& desc,
|
| }
|
|
|
| GrGLenum internalFormat;
|
| - GrGLenum externalFormat = 0x0; // suprress warning
|
| - GrGLenum externalType = 0x0;// suprress warning
|
| + GrGLenum externalFormat = 0x0; // suppress warning
|
| + GrGLenum externalType = 0x0;// suppress warning
|
|
|
| // glTexStorage requires sized internal formats on both desktop and ES. ES2 requires an unsized
|
| // format for glTexImage, unlike ES3 and desktop. However, we allow the driver to decide the
|
| @@ -658,6 +664,15 @@ bool GrGpuGL::uploadTexData(const GrGLTexture::Desc& desc,
|
| 1, // levels
|
| internalFormat,
|
| desc.fWidth, desc.fHeight));
|
| + } else if (is3DTexture) {
|
| + GL_ALLOC_CALL(this->glInterface(),
|
| + TexImage3D(GR_GL_TEXTURE_3D,
|
| + 0, // level
|
| + internalFormat,
|
| + desc.fWidth, desc.fHeight, desc.fDepth,
|
| + 0, // border
|
| + externalFormat, externalType,
|
| + data));
|
| } else {
|
| GL_ALLOC_CALL(this->glInterface(),
|
| TexImage2D(GR_GL_TEXTURE_2D,
|
| @@ -675,23 +690,43 @@ bool GrGpuGL::uploadTexData(const GrGLTexture::Desc& desc,
|
| // if we have data and we used TexStorage to create the texture, we
|
| // now upload with TexSubImage.
|
| if (data && useTexStorage) {
|
| - GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D,
|
| - 0, // level
|
| - left, top,
|
| - width, height,
|
| - externalFormat, externalType,
|
| - data));
|
| + if (is3DTexture) {
|
| + GL_CALL(TexSubImage3D(GR_GL_TEXTURE_3D,
|
| + 0, // level,
|
| + left, top,
|
| + left, // FIXME: left used as Z offset
|
| + desc.fWidth, desc.fHeight, desc.fDepth,
|
| + externalFormat, externalType,
|
| + data));
|
| + } else {
|
| + GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D,
|
| + 0, // level
|
| + left, top,
|
| + width, height,
|
| + externalFormat, externalType,
|
| + data));
|
| + }
|
| }
|
| }
|
| } else {
|
| if (swFlipY || glFlipY) {
|
| top = desc.fHeight - (top + height);
|
| }
|
| - GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D,
|
| - 0, // level
|
| - left, top,
|
| - width, height,
|
| - externalFormat, externalType, data));
|
| + if (is3DTexture) {
|
| + GL_CALL(TexSubImage3D(GR_GL_TEXTURE_3D,
|
| + 0, // level,
|
| + left, top,
|
| + left, // FIXME: left used as Z offset
|
| + desc.fWidth, desc.fHeight, desc.fDepth,
|
| + externalFormat, externalType,
|
| + data));
|
| + } else {
|
| + GL_CALL(TexSubImage2D(GR_GL_TEXTURE_2D,
|
| + 0, // level
|
| + left, top,
|
| + width, height,
|
| + externalFormat, externalType, data));
|
| + }
|
| }
|
|
|
| if (restoreGLRowLength) {
|
| @@ -742,7 +777,9 @@ bool GrGpuGL::uploadCompressedTexData(const GrGLTexture::Desc& desc,
|
|
|
| // We only need the internal format for compressed 2D textures.
|
| GrGLenum internalFormat = 0;
|
| - if (!this->configToGLFormats(desc.fConfig, false, &internalFormat, NULL, NULL)) {
|
| + if (!this->configToGLFormats(desc.fConfig, false, &internalFormat, NULL, NULL) ||
|
| + // Compressed 3D textures not supported
|
| + (desc.fDepth > 0)) {
|
| return false;
|
| }
|
|
|
| @@ -955,6 +992,7 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
|
| glTexDesc.fFlags = desc.fFlags;
|
| glTexDesc.fWidth = desc.fWidth;
|
| glTexDesc.fHeight = desc.fHeight;
|
| + glTexDesc.fDepth = desc.fDepth;
|
| glTexDesc.fConfig = desc.fConfig;
|
| glTexDesc.fIsWrapped = false;
|
|
|
| @@ -979,12 +1017,14 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
|
|
|
| if (renderTarget) {
|
| int maxRTSize = this->caps()->maxRenderTargetSize();
|
| - if (glTexDesc.fWidth > maxRTSize || glTexDesc.fHeight > maxRTSize) {
|
| + if (glTexDesc.fWidth > maxRTSize || glTexDesc.fHeight > maxRTSize ||
|
| + glTexDesc.fDepth > maxRTSize) {
|
| return return_null_texture();
|
| }
|
| } else {
|
| int maxSize = this->caps()->maxTextureSize();
|
| - if (glTexDesc.fWidth > maxSize || glTexDesc.fHeight > maxSize) {
|
| + if (glTexDesc.fWidth > maxSize || glTexDesc.fHeight > maxSize ||
|
| + glTexDesc.fDepth > maxSize) {
|
| return return_null_texture();
|
| }
|
| }
|
| @@ -996,11 +1036,12 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
|
| }
|
|
|
| this->setScratchTextureUnit();
|
| - GL_CALL(BindTexture(GR_GL_TEXTURE_2D, glTexDesc.fTextureID));
|
| + GrGLenum textureType = (glTexDesc.fDepth > 0) ? GR_GL_TEXTURE_3D : GR_GL_TEXTURE_2D;
|
| + GL_CALL(BindTexture(textureType, glTexDesc.fTextureID));
|
|
|
| if (renderTarget && this->glCaps().textureUsageSupport()) {
|
| // provides a hint about how this texture will be used
|
| - GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
|
| + GL_CALL(TexParameteri(textureType,
|
| GR_GL_TEXTURE_USAGE,
|
| GR_GL_FRAMEBUFFER_ATTACHMENT));
|
| }
|
| @@ -1015,18 +1056,23 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
|
| initialTexParams.fMagFilter = GR_GL_NEAREST;
|
| initialTexParams.fWrapS = GR_GL_CLAMP_TO_EDGE;
|
| initialTexParams.fWrapT = GR_GL_CLAMP_TO_EDGE;
|
| - GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
|
| + GL_CALL(TexParameteri(textureType,
|
| GR_GL_TEXTURE_MAG_FILTER,
|
| initialTexParams.fMagFilter));
|
| - GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
|
| + GL_CALL(TexParameteri(textureType,
|
| GR_GL_TEXTURE_MIN_FILTER,
|
| initialTexParams.fMinFilter));
|
| - GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
|
| + GL_CALL(TexParameteri(textureType,
|
| GR_GL_TEXTURE_WRAP_S,
|
| initialTexParams.fWrapS));
|
| - GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
|
| + GL_CALL(TexParameteri(textureType,
|
| GR_GL_TEXTURE_WRAP_T,
|
| initialTexParams.fWrapT));
|
| + if (GR_GL_TEXTURE_3D == textureType) {
|
| + GL_CALL(TexParameteri(textureType,
|
| + GR_GL_TEXTURE_WRAP_R,
|
| + initialTexParams.fWrapT));
|
| + }
|
| if (!this->uploadTexData(glTexDesc, true, 0, 0,
|
| glTexDesc.fWidth, glTexDesc.fHeight,
|
| desc.fConfig, srcData, rowBytes)) {
|
| @@ -1037,7 +1083,7 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
|
| GrGLTexture* tex;
|
| if (renderTarget) {
|
| // unbind the texture from the texture unit before binding it to the frame buffer
|
| - GL_CALL(BindTexture(GR_GL_TEXTURE_2D, 0));
|
| + GL_CALL(BindTexture(textureType, 0));
|
|
|
| if (!this->createRenderTargetObjects(glTexDesc.fWidth,
|
| glTexDesc.fHeight,
|
| @@ -1061,7 +1107,7 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
|
| GrTexture* GrGpuGL::onCreateCompressedTexture(const GrTextureDesc& desc,
|
| const void* srcData) {
|
|
|
| - if(SkToBool(desc.fFlags & kRenderTarget_GrTextureFlagBit)) {
|
| + if(SkToBool(desc.fFlags & kRenderTarget_GrTextureFlagBit) || (desc.fDepth > 0)) {
|
| return return_null_texture();
|
| }
|
|
|
| @@ -2024,10 +2070,12 @@ void GrGpuGL::bindTexture(int unitIdx, const GrTextureParams& params, GrGLTextur
|
| this->onResolveRenderTarget(texRT);
|
| }
|
|
|
| + GrGLenum textureType = (texture->desc().fDepth > 0) ? GR_GL_TEXTURE_3D : GR_GL_TEXTURE_2D;
|
| +
|
| uint32_t textureID = texture->getUniqueID();
|
| if (fHWBoundTextureUniqueIDs[unitIdx] != textureID) {
|
| this->setTextureUnit(unitIdx);
|
| - GL_CALL(BindTexture(GR_GL_TEXTURE_2D, texture->textureID()));
|
| + GL_CALL(BindTexture(textureType, texture->textureID()));
|
| fHWBoundTextureUniqueIDs[unitIdx] = textureID;
|
| }
|
|
|
| @@ -2055,7 +2103,7 @@ void GrGpuGL::bindTexture(int unitIdx, const GrTextureParams& params, GrGLTextur
|
|
|
| if (GrTextureParams::kMipMap_FilterMode == filterMode &&
|
| texture->mipMapsAreDirty() && !GrPixelConfigIsCompressed(texture->config())) {
|
| - GL_CALL(GenerateMipmap(GR_GL_TEXTURE_2D));
|
| + GL_CALL(GenerateMipmap(textureType));
|
| texture->dirtyMipMaps(false);
|
| }
|
|
|
| @@ -2066,27 +2114,32 @@ void GrGpuGL::bindTexture(int unitIdx, const GrTextureParams& params, GrGLTextur
|
| sizeof(newTexParams.fSwizzleRGBA));
|
| if (setAll || newTexParams.fMagFilter != oldTexParams.fMagFilter) {
|
| this->setTextureUnit(unitIdx);
|
| - GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
|
| + GL_CALL(TexParameteri(textureType,
|
| GR_GL_TEXTURE_MAG_FILTER,
|
| newTexParams.fMagFilter));
|
| }
|
| if (setAll || newTexParams.fMinFilter != oldTexParams.fMinFilter) {
|
| this->setTextureUnit(unitIdx);
|
| - GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
|
| + GL_CALL(TexParameteri(textureType,
|
| GR_GL_TEXTURE_MIN_FILTER,
|
| newTexParams.fMinFilter));
|
| }
|
| if (setAll || newTexParams.fWrapS != oldTexParams.fWrapS) {
|
| this->setTextureUnit(unitIdx);
|
| - GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
|
| + GL_CALL(TexParameteri(textureType,
|
| GR_GL_TEXTURE_WRAP_S,
|
| newTexParams.fWrapS));
|
| }
|
| if (setAll || newTexParams.fWrapT != oldTexParams.fWrapT) {
|
| this->setTextureUnit(unitIdx);
|
| - GL_CALL(TexParameteri(GR_GL_TEXTURE_2D,
|
| + GL_CALL(TexParameteri(textureType,
|
| GR_GL_TEXTURE_WRAP_T,
|
| newTexParams.fWrapT));
|
| + if (GR_GL_TEXTURE_3D == textureType) {
|
| + GL_CALL(TexParameteri(textureType,
|
| + GR_GL_TEXTURE_WRAP_R,
|
| + newTexParams.fWrapT));
|
| + }
|
| }
|
| if (this->glCaps().textureSwizzleSupport() &&
|
| (setAll || memcmp(newTexParams.fSwizzleRGBA,
|
| @@ -2096,14 +2149,14 @@ void GrGpuGL::bindTexture(int unitIdx, const GrTextureParams& params, GrGLTextur
|
| if (this->glStandard() == kGLES_GrGLStandard) {
|
| // ES3 added swizzle support but not GL_TEXTURE_SWIZZLE_RGBA.
|
| const GrGLenum* swizzle = newTexParams.fSwizzleRGBA;
|
| - GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_SWIZZLE_R, swizzle[0]));
|
| - GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_SWIZZLE_G, swizzle[1]));
|
| - GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_SWIZZLE_B, swizzle[2]));
|
| - GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_SWIZZLE_A, swizzle[3]));
|
| + GL_CALL(TexParameteri(textureType, GR_GL_TEXTURE_SWIZZLE_R, swizzle[0]));
|
| + GL_CALL(TexParameteri(textureType, GR_GL_TEXTURE_SWIZZLE_G, swizzle[1]));
|
| + GL_CALL(TexParameteri(textureType, GR_GL_TEXTURE_SWIZZLE_B, swizzle[2]));
|
| + GL_CALL(TexParameteri(textureType, 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(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_SWIZZLE_RGBA, swizzle));
|
| + GL_CALL(TexParameteriv(textureType, GR_GL_TEXTURE_SWIZZLE_RGBA, swizzle));
|
| }
|
| }
|
| texture->setCachedTexParams(newTexParams, this->getResetTimestamp());
|
|
|