Workaround GL error when creating texture view from external GL textures
This patch adds a workaround on the GL error when we use glTextureView() on a GL texture which is created outside DAWN and not configured by glTexStorage*d(). glTextureView() is only allowed to be used on the textures configured by glTexStorage*D(). When the external GL texture is configured by glTexImage2D() (for example, textures from GLFW), calling glTextureView() will cause an INVALID_OPERATION error. To workaround this issue, we refer the solution on the Metal backend that we avoid calling glTextureView() on the following senarios: 1. We may call glTextureView() only when the usage of the texture includes Sampled or Storage. 2. We won't call glTextureView() if the view uses the same format as the original texture, the whole mipmap levels and array slices. BUG=dawn:16 Change-Id: Ibdfaa122ac061a2e2bb47f76e0030f1d0fc548a2 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/5780 Reviewed-by: Kai Ninomiya <kainino@chromium.org> Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
This commit is contained in:
parent
07950e80fe
commit
24930b382a
|
@ -83,6 +83,37 @@ namespace dawn_native { namespace opengl {
|
|||
return handle;
|
||||
}
|
||||
|
||||
bool UsageNeedsTextureView(dawn::TextureUsageBit usage) {
|
||||
constexpr dawn::TextureUsageBit kUsageNeedingTextureView =
|
||||
dawn::TextureUsageBit::Storage | dawn::TextureUsageBit::Sampled;
|
||||
return usage & kUsageNeedingTextureView;
|
||||
}
|
||||
|
||||
bool RequiresCreatingNewTextureView(const TextureBase* texture,
|
||||
const TextureViewDescriptor* textureViewDescriptor) {
|
||||
if (texture->GetFormat() != textureViewDescriptor->format) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (texture->GetArrayLayers() != textureViewDescriptor->arrayLayerCount) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (texture->GetNumMipLevels() != textureViewDescriptor->mipLevelCount) {
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (textureViewDescriptor->dimension) {
|
||||
case dawn::TextureViewDimension::Cube:
|
||||
case dawn::TextureViewDimension::CubeArray:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Texture
|
||||
|
@ -144,24 +175,35 @@ namespace dawn_native { namespace opengl {
|
|||
// TextureView
|
||||
|
||||
TextureView::TextureView(TextureBase* texture, const TextureViewDescriptor* descriptor)
|
||||
: TextureViewBase(texture, descriptor) {
|
||||
: TextureViewBase(texture, descriptor), mOwnsHandle(false) {
|
||||
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->mipLevelCount,
|
||||
descriptor->baseArrayLayer, descriptor->arrayLayerCount);
|
||||
if (!UsageNeedsTextureView(texture->GetUsage())) {
|
||||
mHandle = 0;
|
||||
} else if (!RequiresCreatingNewTextureView(texture, descriptor)) {
|
||||
mHandle = ToBackend(texture)->GetHandle();
|
||||
} else {
|
||||
// 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->mipLevelCount, descriptor->baseArrayLayer,
|
||||
descriptor->arrayLayerCount);
|
||||
mOwnsHandle = true;
|
||||
}
|
||||
}
|
||||
|
||||
TextureView::~TextureView() {
|
||||
glDeleteTextures(1, &mHandle);
|
||||
if (mOwnsHandle) {
|
||||
glDeleteTextures(1, &mHandle);
|
||||
}
|
||||
}
|
||||
|
||||
GLuint TextureView::GetHandle() const {
|
||||
ASSERT(mHandle != 0);
|
||||
return mHandle;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ namespace dawn_native { namespace opengl {
|
|||
private:
|
||||
GLuint mHandle;
|
||||
GLenum mTarget;
|
||||
bool mOwnsHandle;
|
||||
};
|
||||
|
||||
}} // namespace dawn_native::opengl
|
||||
|
|
Loading…
Reference in New Issue