Support creating texture view with descriptor on OpenGL version >= 4.3
This patch implements creating texture view with texture view descriptor
with glTextureView, which is supported on OpenGL version >= 4.3. As is
required by glTextureView, we allocate storage for a texture by
glTexStorage*D instead of glTexImage*D.
BUG=dawn:16
TEST=dawn_end2end_tests
Change-Id: I29bcf6d538a70b4d6d1e5a21276b9e8d6e93ca51
Reviewed-on: https://dawn-review.googlesource.com/c/1980
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
diff --git a/src/dawn_native/opengl/CommandBufferGL.cpp b/src/dawn_native/opengl/CommandBufferGL.cpp
index 2f3737b..ec03c77 100644
--- a/src/dawn_native/opengl/CommandBufferGL.cpp
+++ b/src/dawn_native/opengl/CommandBufferGL.cpp
@@ -258,12 +258,11 @@
case dawn::BindingType::SampledTexture: {
TextureView* view = ToBackend(group->GetBindingAsTextureView(binding));
- Texture* texture = ToBackend(view->GetTexture());
- GLuint handle = texture->GetHandle();
- GLenum target = texture->GetGLTarget();
- GLuint textureIndex = indices[binding];
+ GLuint handle = view->GetHandle();
+ GLenum target = view->GetGLTarget();
+ GLuint viewIndex = indices[binding];
- for (auto unit : pipeline->GetTextureUnitsForTexture(textureIndex)) {
+ for (auto unit : pipeline->GetTextureUnitsForTextureView(viewIndex)) {
glActiveTexture(GL_TEXTURE0 + unit);
glBindTexture(target, handle);
}
diff --git a/src/dawn_native/opengl/PipelineGL.cpp b/src/dawn_native/opengl/PipelineGL.cpp
index c3cdc33..f03ab87 100644
--- a/src/dawn_native/opengl/PipelineGL.cpp
+++ b/src/dawn_native/opengl/PipelineGL.cpp
@@ -204,7 +204,7 @@
return mUnitsForSamplers[index];
}
- const std::vector<GLuint>& PipelineGL::GetTextureUnitsForTexture(GLuint index) const {
+ const std::vector<GLuint>& PipelineGL::GetTextureUnitsForTextureView(GLuint index) const {
ASSERT(index < mUnitsForSamplers.size());
return mUnitsForTextures[index];
}
diff --git a/src/dawn_native/opengl/PipelineGL.h b/src/dawn_native/opengl/PipelineGL.h
index 400e0f5..b3feeb9 100644
--- a/src/dawn_native/opengl/PipelineGL.h
+++ b/src/dawn_native/opengl/PipelineGL.h
@@ -40,7 +40,7 @@
const GLPushConstantInfo& GetGLPushConstants(dawn::ShaderStage stage) const;
const std::vector<GLuint>& GetTextureUnitsForSampler(GLuint index) const;
- const std::vector<GLuint>& GetTextureUnitsForTexture(GLuint index) const;
+ const std::vector<GLuint>& GetTextureUnitsForTextureView(GLuint index) const;
GLuint GetProgramHandle() const;
void ApplyNow();
diff --git a/src/dawn_native/opengl/TextureGL.cpp b/src/dawn_native/opengl/TextureGL.cpp
index 6b9d90c..bbe6a12 100644
--- a/src/dawn_native/opengl/TextureGL.cpp
+++ b/src/dawn_native/opengl/TextureGL.cpp
@@ -31,6 +31,19 @@
return (arrayLayer > 1) ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
default:
UNREACHABLE();
+ return GL_TEXTURE_2D;
+ }
+ }
+
+ GLenum TargetForTextureViewDimension(dawn::TextureViewDimension dimension) {
+ switch (dimension) {
+ case dawn::TextureViewDimension::e2D:
+ return GL_TEXTURE_2D;
+ case dawn::TextureViewDimension::e2DArray:
+ return GL_TEXTURE_2D_ARRAY;
+ default:
+ UNREACHABLE();
+ return GL_TEXTURE_2D;
}
}
@@ -56,6 +69,7 @@
GL_FLOAT_32_UNSIGNED_INT_24_8_REV};
default:
UNREACHABLE();
+ return {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE};
}
}
@@ -86,23 +100,20 @@
glBindTexture(mTarget, handle);
- for (uint32_t i = 0; i < levels; ++i) {
- switch (GetDimension()) {
- case dawn::TextureDimension::e2D:
- if (arrayLayers > 1) {
- glTexImage3D(mTarget, i, formatInfo.internalFormat, width, height,
- arrayLayers, 0, formatInfo.format, formatInfo.type, nullptr);
- } else {
- glTexImage2D(mTarget, i, formatInfo.internalFormat, width, height, 0,
- formatInfo.format, formatInfo.type, nullptr);
- }
- break;
- default:
- UNREACHABLE();
- }
-
- width = std::max(uint32_t(1), width / 2);
- height = std::max(uint32_t(1), height / 2);
+ // glTextureView() requires the value of GL_TEXTURE_IMMUTABLE_FORMAT for origtexture to be
+ // GL_TRUE, so the storage of the texture must be allocated with glTexStorage*D.
+ // https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTextureView.xhtml
+ switch (GetDimension()) {
+ case dawn::TextureDimension::e2D:
+ if (arrayLayers > 1) {
+ glTexStorage3D(mTarget, levels, formatInfo.internalFormat, width, height,
+ arrayLayers);
+ } else {
+ glTexStorage2D(mTarget, levels, formatInfo.internalFormat, width, height);
+ }
+ break;
+ default:
+ UNREACHABLE();
}
// The texture is not complete if it uses mipmapping and not all levels up to
@@ -129,9 +140,30 @@
// TextureView
- // TODO(jiawei.shao@intel.com): create texture view by TextureViewDescriptor
TextureView::TextureView(TextureBase* texture, const TextureViewDescriptor* descriptor)
: TextureViewBase(texture, descriptor) {
+ mTarget = TargetForTextureViewDimension(descriptor->dimension);
+
+ // glTextureView() is supported on OpenGL version >= 4.3
+ // TODO(jiawei.shao@intel.com): support texture view on OpenGL version <= 4.2
+ mHandle = GenTexture();
+ const Texture* textureGL = ToBackend(texture);
+ TextureFormatInfo textureViewFormat = GetGLFormatInfo(descriptor->format);
+ glTextureView(mHandle, mTarget, textureGL->GetHandle(), textureViewFormat.internalFormat,
+ descriptor->baseMipLevel, descriptor->levelCount, descriptor->baseArrayLayer,
+ descriptor->layerCount);
+ }
+
+ TextureView::~TextureView() {
+ glDeleteTextures(1, &mHandle);
+ }
+
+ GLuint TextureView::GetHandle() const {
+ return mHandle;
+ }
+
+ GLenum TextureView::GetGLTarget() const {
+ return mTarget;
}
}} // namespace dawn_native::opengl
diff --git a/src/dawn_native/opengl/TextureGL.h b/src/dawn_native/opengl/TextureGL.h
index be7d159..5b12da5 100644
--- a/src/dawn_native/opengl/TextureGL.h
+++ b/src/dawn_native/opengl/TextureGL.h
@@ -47,6 +47,14 @@
class TextureView : public TextureViewBase {
public:
TextureView(TextureBase* texture, const TextureViewDescriptor* descriptor);
+ ~TextureView();
+
+ GLuint GetHandle() const;
+ GLenum GetGLTarget() const;
+
+ private:
+ GLuint mHandle;
+ GLenum mTarget;
};
}} // namespace dawn_native::opengl
diff --git a/src/tests/end2end/TextureViewTests.cpp b/src/tests/end2end/TextureViewTests.cpp
index 1877cf4..f3fdcae 100644
--- a/src/tests/end2end/TextureViewTests.cpp
+++ b/src/tests/end2end/TextureViewTests.cpp
@@ -163,10 +163,6 @@
uint32_t textureMipLevels,
uint32_t textureViewBaseLayer,
uint32_t textureViewBaseMipLevel) {
- // TODO(jiawei.shao@intel.com): support creating texture view with a texture view descriptor
- // on OpenGL.
- DAWN_SKIP_TEST_IF(IsOpenGL());
-
ASSERT(textureViewBaseLayer < textureArrayLayers);
ASSERT(textureViewBaseMipLevel < textureMipLevels);
@@ -200,10 +196,6 @@
uint32_t textureMipLevels,
uint32_t textureViewBaseLayer,
uint32_t textureViewBaseMipLevel) {
- // TODO(jiawei.shao@intel.com): support creating texture view with a texture view descriptor
- // on OpenGL.
- DAWN_SKIP_TEST_IF(IsOpenGL());
-
ASSERT(textureViewBaseLayer < textureArrayLayers);
ASSERT(textureViewBaseMipLevel < textureMipLevels);