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>
This commit is contained in:
Jiawei Shao 2018-10-29 09:07:25 +00:00 committed by Commit Bot service account
parent c35103dc19
commit c72ab8ce84
6 changed files with 64 additions and 33 deletions

View File

@ -258,12 +258,11 @@ namespace dawn_native { namespace opengl {
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);
}

View File

@ -204,7 +204,7 @@ namespace dawn_native { namespace opengl {
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];
}

View File

@ -40,7 +40,7 @@ namespace dawn_native { namespace opengl {
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();

View File

@ -31,6 +31,19 @@ namespace dawn_native { namespace opengl {
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 @@ namespace dawn_native { namespace opengl {
GL_FLOAT_32_UNSIGNED_INT_24_8_REV};
default:
UNREACHABLE();
return {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE};
}
}
@ -86,23 +100,20 @@ namespace dawn_native { namespace opengl {
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 @@ namespace dawn_native { namespace opengl {
// 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

View File

@ -47,6 +47,14 @@ namespace dawn_native { namespace opengl {
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

View File

@ -163,10 +163,6 @@ protected:
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 @@ protected:
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);