diff --git a/src/dawn/native/opengl/CommandBufferGL.cpp b/src/dawn/native/opengl/CommandBufferGL.cpp index 8971979836..ba5b8dd79c 100644 --- a/src/dawn/native/opengl/CommandBufferGL.cpp +++ b/src/dawn/native/opengl/CommandBufferGL.cpp @@ -244,6 +244,17 @@ namespace dawn::native::opengl { const auto& indices = ToBackend(mPipelineLayout)->GetBindingIndexInfo()[index]; uint32_t currentDynamicOffsetIndex = 0; + for (BindingIndex bindingIndex{0}; + bindingIndex < group->GetLayout()->GetBindingCount(); ++bindingIndex) { + const BindingInfo& bindingInfo = + group->GetLayout()->GetBindingInfo(bindingIndex); + + if (bindingInfo.bindingType == BindingInfoType::Texture) { + TextureView* view = ToBackend(group->GetBindingAsTextureView(bindingIndex)); + view->CopyIfNeeded(); + } + } + for (BindingIndex bindingIndex{0}; bindingIndex < group->GetLayout()->GetBindingCount(); ++bindingIndex) { const BindingInfo& bindingInfo = @@ -361,6 +372,7 @@ namespace dawn::native::opengl { gl.BindImageTexture(imageIndex, handle, view->GetBaseMipLevel(), isLayered, view->GetBaseArrayLayer(), access, texture->GetGLFormat().internalFormat); + texture->Touch(); break; } @@ -402,6 +414,7 @@ namespace dawn::native::opengl { gl.BlitFramebuffer(0, 0, renderPass->width, renderPass->height, 0, 0, renderPass->width, renderPass->height, GL_COLOR_BUFFER_BIT, GL_NEAREST); + ToBackend(resolveView->GetTexture())->Touch(); } } @@ -552,6 +565,7 @@ namespace dawn::native::opengl { DoTexSubImage(gl, dst, reinterpret_cast(src.offset), dataLayout, copy->copySize); gl.BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + ToBackend(dst.texture)->Touch(); break; } @@ -698,6 +712,7 @@ namespace dawn::native::opengl { srcTexture->GetGLTarget(), src.mipLevel, src.origin, dstTexture->GetHandle(), dstTexture->GetGLTarget(), dst.mipLevel, dst.origin, copySize); + ToBackend(dst.texture)->Touch(); break; } @@ -1134,6 +1149,17 @@ namespace dawn::native::opengl { case Command::EndRenderPass: { mCommands.NextCommand(); + for (ColorAttachmentIndex i : + IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) { + TextureView* textureView = + ToBackend(renderPass->colorAttachments[i].view.Get()); + ToBackend(textureView->GetTexture())->Touch(); + } + if (renderPass->attachmentState->HasDepthStencilAttachment()) { + TextureView* textureView = + ToBackend(renderPass->depthStencilAttachment.view.Get()); + ToBackend(textureView->GetTexture())->Touch(); + } if (renderPass->attachmentState->GetSampleCount() > 1) { ResolveMultisampledRenderTargets(gl, renderPass); } diff --git a/src/dawn/native/opengl/QueueGL.cpp b/src/dawn/native/opengl/QueueGL.cpp index 541d93be48..6456dfab14 100644 --- a/src/dawn/native/opengl/QueueGL.cpp +++ b/src/dawn/native/opengl/QueueGL.cpp @@ -74,6 +74,7 @@ namespace dawn::native::opengl { ToBackend(destination.texture)->EnsureSubresourceContentInitialized(range); } DoTexSubImage(ToBackend(GetDevice())->gl, textureCopy, data, dataLayout, writeSizePixel); + ToBackend(destination.texture)->Touch(); return {}; } diff --git a/src/dawn/native/opengl/TextureGL.cpp b/src/dawn/native/opengl/TextureGL.cpp index 0f5bf7b934..cbbe1db878 100644 --- a/src/dawn/native/opengl/TextureGL.cpp +++ b/src/dawn/native/opengl/TextureGL.cpp @@ -199,6 +199,14 @@ namespace dawn::native::opengl { } } + void Texture::Touch() { + mGenID++; + } + + uint32_t Texture::GetGenID() const { + return mGenID; + } + Texture::Texture(Device* device, const TextureDescriptor* descriptor, GLuint handle, @@ -538,6 +546,7 @@ namespace dawn::native::opengl { SetIsSubresourceContentInitialized(true, range); device->IncrementLazyClearCountForTesting(); } + Touch(); return {}; } @@ -565,23 +574,19 @@ namespace dawn::native::opengl { if (!RequiresCreatingNewTextureView(texture, descriptor)) { mHandle = ToBackend(texture)->GetHandle(); } else { - // glTextureView() is supported on OpenGL version >= 4.3 - // TODO(crbug.com/dawn/593): support texture view on OpenGL version <= 4.2 and ES const OpenGLFunctions& gl = ToBackend(GetDevice())->gl; - mHandle = GenTexture(gl); - const Texture* textureGL = ToBackend(texture); - - const Format& textureFormat = GetTexture()->GetFormat(); - // Depth/stencil don't support reinterpretation, and the aspect is specified at - // bind time. In that case, we use the base texture format. - const GLFormat& glFormat = textureFormat.HasDepthOrStencil() - ? ToBackend(GetDevice())->GetGLFormat(textureFormat) - : ToBackend(GetDevice())->GetGLFormat(GetFormat()); - - gl.TextureView(mHandle, mTarget, textureGL->GetHandle(), glFormat.internalFormat, - descriptor->baseMipLevel, descriptor->mipLevelCount, - descriptor->baseArrayLayer, descriptor->arrayLayerCount); - mOwnsHandle = true; + if (gl.IsAtLeastGL(4, 3)) { + mHandle = GenTexture(gl); + const Texture* textureGL = ToBackend(texture); + gl.TextureView(mHandle, mTarget, textureGL->GetHandle(), GetInternalFormat(), + descriptor->baseMipLevel, descriptor->mipLevelCount, + descriptor->baseArrayLayer, descriptor->arrayLayerCount); + mOwnsHandle = true; + } else { + // Simulate glTextureView() with texture-to-texture copies. + mUseCopy = true; + mHandle = 0; + } } } @@ -632,4 +637,50 @@ namespace dawn::native::opengl { } } + void TextureView::CopyIfNeeded() { + if (!mUseCopy) { + return; + } + + const Texture* texture = ToBackend(GetTexture()); + if (mGenID == texture->GetGenID()) { + return; + } + + Device* device = ToBackend(GetDevice()); + const OpenGLFunctions& gl = device->gl; + uint32_t srcLevel = GetBaseMipLevel(); + uint32_t numLevels = GetLevelCount(); + + uint32_t width = texture->GetWidth() >> srcLevel; + uint32_t height = texture->GetHeight() >> srcLevel; + Extent3D size{width, height, GetLayerCount()}; + + if (mHandle == 0) { + mHandle = GenTexture(gl); + gl.BindTexture(mTarget, mHandle); + AllocateTexture(gl, mTarget, texture->GetSampleCount(), numLevels, GetInternalFormat(), + size); + mOwnsHandle = true; + } + + Origin3D src{0, 0, GetBaseArrayLayer()}; + Origin3D dst{0, 0, 0}; + for (GLuint level = 0; level < numLevels; ++level) { + CopyImageSubData(gl, GetAspects(), texture->GetHandle(), texture->GetGLTarget(), + srcLevel + level, src, mHandle, mTarget, level, dst, size); + } + + mGenID = texture->GetGenID(); + } + + GLenum TextureView::GetInternalFormat() const { + // Depth/stencil don't support reinterpretation, and the aspect is specified at + // bind time. In that case, we use the base texture format. + const Format& format = + GetFormat().HasDepthOrStencil() ? GetTexture()->GetFormat() : GetFormat(); + const GLFormat& glFormat = ToBackend(GetDevice())->GetGLFormat(format); + return glFormat.internalFormat; + } + } // namespace dawn::native::opengl diff --git a/src/dawn/native/opengl/TextureGL.h b/src/dawn/native/opengl/TextureGL.h index 2b0b4b119b..cf77972f0c 100644 --- a/src/dawn/native/opengl/TextureGL.h +++ b/src/dawn/native/opengl/TextureGL.h @@ -35,6 +35,8 @@ namespace dawn::native::opengl { GLuint GetHandle() const; GLenum GetGLTarget() const; const GLFormat& GetGLFormat() const; + uint32_t GetGenID() const; + void Touch(); void EnsureSubresourceContentInitialized(const SubresourceRange& range); @@ -46,6 +48,7 @@ namespace dawn::native::opengl { GLuint mHandle; GLenum mTarget; + uint32_t mGenID = 0; }; class TextureView final : public TextureViewBase { @@ -55,15 +58,19 @@ namespace dawn::native::opengl { GLuint GetHandle() const; GLenum GetGLTarget() const; void BindToFramebuffer(GLenum target, GLenum attachment); + void CopyIfNeeded(); private: ~TextureView() override; void DestroyImpl() override; + GLenum GetInternalFormat() const; // TODO(crbug.com/dawn/1355): Delete this handle on texture destroy. GLuint mHandle; GLenum mTarget; bool mOwnsHandle; + bool mUseCopy = false; + uint32_t mGenID = 0; }; } // namespace dawn::native::opengl diff --git a/src/dawn/tests/end2end/BufferZeroInitTests.cpp b/src/dawn/tests/end2end/BufferZeroInitTests.cpp index 515e1875d7..5788ddd1a6 100644 --- a/src/dawn/tests/end2end/BufferZeroInitTests.cpp +++ b/src/dawn/tests/end2end/BufferZeroInitTests.cpp @@ -960,9 +960,6 @@ TEST_P(BufferZeroInitTest, Copy2DTextureToBuffer) { // Test that the code path of CopyTextureToBuffer clears the destination buffer correctly when it is // the first use of the buffer and the texture is a 2D array texture. TEST_P(BufferZeroInitTest, Copy2DArrayTextureToBuffer) { - // TODO(crbug.com/dawn/593): This test uses glTextureView() which is not supported on OpenGL ES. - DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES()); - constexpr wgpu::Extent3D kTextureSize = {64u, 4u, 3u}; // bytesPerRow == texelBlockSizeInBytes * copySize.width && rowsPerImage == copySize.height && diff --git a/src/dawn/tests/end2end/CompressedTextureFormatTests.cpp b/src/dawn/tests/end2end/CompressedTextureFormatTests.cpp index a8a998385a..5bc75abc52 100644 --- a/src/dawn/tests/end2end/CompressedTextureFormatTests.cpp +++ b/src/dawn/tests/end2end/CompressedTextureFormatTests.cpp @@ -694,7 +694,7 @@ TEST_P(CompressedTextureFormatTest, CopyIntoNonZeroArrayLayer) { DAWN_TEST_UNSUPPORTED_IF(!IsFormatSupported()); - // This test uses glTextureView() which is not supported in OpenGL ES. + // TODO(crbug.com/dawn/1328): ES3.1 does not support subsetting of compressed textures. DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES()); constexpr uint32_t kArrayLayerCount = 3; @@ -714,7 +714,7 @@ TEST_P(CompressedTextureFormatTest, CopyBufferIntoNonZeroMipmapLevel) { DAWN_TEST_UNSUPPORTED_IF(!IsFormatSupported()); - // This test uses glTextureView() which is not supported in OpenGL ES. + // TODO(crbug.com/dawn/1328): ES3.1 does not support subsetting of compressed textures. DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES()); CopyConfig config = GetDefaultFullConfig(); @@ -732,7 +732,7 @@ TEST_P(CompressedTextureFormatTest, CopyWholeTextureSubResourceIntoNonZeroMipmap DAWN_TEST_UNSUPPORTED_IF(!IsFormatSupported()); - // This test uses glTextureView() which is not supported in OpenGL ES. + // TODO(crbug.com/dawn/1328): ES3.1 does not support subsetting of compressed textures. DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES()); // TODO(crbug.com/dawn/816): This consistently fails on with the 12th pixel being opaque @@ -1083,7 +1083,7 @@ TEST_P(CompressedTextureFormatTest, LargeImageHeightAndClampedCopyExtent) { DAWN_TEST_UNSUPPORTED_IF(!IsFormatSupported()); - // This test uses glTextureView() which is not supported in OpenGL ES. + // TODO(crbug.com/dawn/1328): ES3.1 does not support subsetting of compressed textures. DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES()); CopyConfig config = GetDefaultFullConfig(); @@ -1105,7 +1105,7 @@ TEST_P(CompressedTextureFormatTest, CopyWhole2DArrayTexture) { DAWN_TEST_UNSUPPORTED_IF(!IsFormatSupported()); - // This test uses glTextureView() which is not supported in OpenGL ES. + // TODO(crbug.com/dawn/1328): ES3.1 does not support subsetting of compressed textures. DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES()); constexpr uint32_t kArrayLayerCount = 3; @@ -1125,7 +1125,7 @@ TEST_P(CompressedTextureFormatTest, CopyMultiple2DArrayLayers) { DAWN_TEST_UNSUPPORTED_IF(!IsFormatSupported()); - // This test uses glTextureView() which is not supported in OpenGL ES. + // TODO(crbug.com/dawn/1328): ES3.1 does not support subsetting of compressed textures. DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES()); constexpr uint32_t kArrayLayerCount = 3; @@ -1276,7 +1276,7 @@ TEST_P(CompressedTextureWriteTextureTest, WriteMultiple2DArrayLayers) { // TODO(crbug.com/dawn/976): Failing on Linux Intel OpenGL drivers. DAWN_SUPPRESS_TEST_IF(IsIntel() && IsOpenGL() && IsLinux()); - // TODO(crbug.com/dawn/593): This test uses glTextureView() which is not supported on OpenGLES. + // TODO(crbug.com/dawn/1328): ES3.1 does not support subsetting of compressed textures. DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES()); // TODO(b/198674734): Width multiplier set to 7 because 5 results in square size for ASTC6x5. @@ -1309,7 +1309,7 @@ TEST_P(CompressedTextureWriteTextureTest, // TODO(crbug.com/dawn/976): Failing on Linux Intel OpenGL drivers. DAWN_SUPPRESS_TEST_IF(IsIntel() && IsOpenGL() && IsLinux()); - // TODO(crbug.com/dawn/593): This test uses glTextureView() which is not supported on OpenGLES. + // TODO(crbug.com/dawn/1328): ES3.1 does not support subsetting of compressed textures. DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES()); CopyConfig config = GetDefaultFullConfig(); diff --git a/src/dawn/tests/end2end/DepthStencilSamplingTests.cpp b/src/dawn/tests/end2end/DepthStencilSamplingTests.cpp index 3047aeb535..6bd15823c1 100644 --- a/src/dawn/tests/end2end/DepthStencilSamplingTests.cpp +++ b/src/dawn/tests/end2end/DepthStencilSamplingTests.cpp @@ -604,8 +604,8 @@ class DepthStencilSamplingTest : public DawnTestWithParams