mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-20 02:15:43 +00:00
OpenGLES: simulate glTextureView() with texture-to-texture copies.
This is obviously a non-optimal solution, but works in all cases except compressed textures. Change-Id: I3fd5fd89ef4978a18917b068632f25f75527c594 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/84160 Reviewed-by: Austin Eng <enga@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Stephen White <senorblanco@google.com>
This commit is contained in:
committed by
Dawn LUCI CQ
parent
03e1aaece5
commit
ca4a8cf02a
@@ -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<void*>(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<EndRenderPassCmd>();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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 {};
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user