Index: src/gpu/gl/GrGpuGL.cpp |
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp |
index a01f7b74ff7a08a8369cc411535c55fc34fb40db..6179bf203244228def10b7954dbd7090b6014e86 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(); |
bsalomon
2014/09/26 14:23:50
Is texture storage not supported for 3D?
|
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(); |
} |
@@ -2023,10 +2069,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; |
bsalomon
2014/09/26 14:23:51
Why don't we have GrGLTexture::textureType()? (Act
|
+ |
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; |
} |
@@ -2054,7 +2102,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); |
} |
@@ -2065,27 +2113,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) { |
bsalomon
2014/09/26 14:23:51
Do all ES contexts that support 3D textures also s
|
+ GL_CALL(TexParameteri(textureType, |
+ GR_GL_TEXTURE_WRAP_R, |
+ newTexParams.fWrapT)); |
+ } |
} |
if (this->glCaps().textureSwizzleSupport() && |
(setAll || memcmp(newTexParams.fSwizzleRGBA, |
@@ -2095,14 +2148,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()); |