mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-14 15:46:28 +00:00
Clear OpenGL textures on first use if not initialized already
This prevents dirty textures to be used when memory is recycled while destroying/creating new textures. If a texture is being used for the first time and has not yet been initialized, it will be cleared to zeros. Bug: dawn:145 Change-Id: I1140ff0535241b247b855df2afefc01fbc003470 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/8380 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Natasha Lee <natlee@microsoft.com>
This commit is contained in:
committed by
Commit Bot service account
parent
ce32a94b37
commit
4886403b61
@@ -14,8 +14,10 @@
|
||||
|
||||
#include "dawn_native/opengl/TextureGL.h"
|
||||
#include "dawn_native/opengl/DeviceGL.h"
|
||||
#include "dawn_native/opengl/UtilsGL.h"
|
||||
|
||||
#include "common/Assert.h"
|
||||
#include "dawn_native/Commands.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
@@ -174,9 +176,8 @@ namespace dawn_native { namespace opengl {
|
||||
ASSERT(GetFormat().blockByteSize <= MAX_TEXEL_SIZE);
|
||||
GLubyte clearColor[MAX_TEXEL_SIZE];
|
||||
std::fill(clearColor, clearColor + MAX_TEXEL_SIZE, 255);
|
||||
|
||||
// TODO(natlee@microsoft.com): clear all subresources
|
||||
for (uint32_t i = 0; i < GL_TEXTURE_MAX_LEVEL; i++) {
|
||||
for (uint32_t i = 0; i < GetNumMipLevels(); i++) {
|
||||
gl.ClearTexImage(mHandle, i, formatInfo.format, formatInfo.type, clearColor);
|
||||
}
|
||||
}
|
||||
@@ -211,6 +212,60 @@ namespace dawn_native { namespace opengl {
|
||||
return GetGLFormatInfo(GetFormat().format);
|
||||
}
|
||||
|
||||
void Texture::ClearTexture(GLint baseMipLevel,
|
||||
GLint levelCount,
|
||||
GLint baseArrayLayer,
|
||||
uint32_t layerCount) {
|
||||
const OpenGLFunctions& gl = ToBackend(GetDevice())->gl;
|
||||
if (GetFormat().HasDepthOrStencil()) {
|
||||
bool doDepthClear = GetFormat().HasDepth();
|
||||
bool doStencilClear = GetFormat().HasStencil();
|
||||
GLfloat depth = 0.0f;
|
||||
GLint stencil = 0u;
|
||||
if (doDepthClear) {
|
||||
gl.DepthMask(GL_TRUE);
|
||||
}
|
||||
if (doStencilClear) {
|
||||
gl.StencilMask(GetStencilMaskFromStencilFormat(GetFormat().format));
|
||||
}
|
||||
|
||||
GLuint framebuffer = 0;
|
||||
gl.GenFramebuffers(1, &framebuffer);
|
||||
gl.BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
|
||||
gl.FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GetGLTarget(),
|
||||
GetHandle(), 0);
|
||||
if (doDepthClear && doStencilClear) {
|
||||
gl.ClearBufferfi(GL_DEPTH_STENCIL, 0, depth, stencil);
|
||||
} else if (doDepthClear) {
|
||||
gl.ClearBufferfv(GL_DEPTH, 0, &depth);
|
||||
} else if (doStencilClear) {
|
||||
gl.ClearBufferiv(GL_STENCIL, 0, &stencil);
|
||||
}
|
||||
gl.DeleteFramebuffers(1, &framebuffer);
|
||||
} else {
|
||||
auto formatInfo = GetGLFormatInfo(GetFormat().format);
|
||||
for (GLint level = baseMipLevel; level < baseMipLevel + levelCount; ++level) {
|
||||
gl.ClearTexSubImage(mHandle, level, 0, 0, baseArrayLayer, GetSize().width,
|
||||
GetSize().height, layerCount, formatInfo.format,
|
||||
formatInfo.type, nullptr);
|
||||
}
|
||||
}
|
||||
SetIsSubresourceContentInitialized(baseMipLevel, levelCount, baseArrayLayer, layerCount);
|
||||
}
|
||||
|
||||
void Texture::EnsureSubresourceContentInitialized(uint32_t baseMipLevel,
|
||||
uint32_t levelCount,
|
||||
uint32_t baseArrayLayer,
|
||||
uint32_t layerCount) {
|
||||
if (!GetDevice()->IsToggleEnabled(Toggle::LazyClearResourceOnFirstUse)) {
|
||||
return;
|
||||
}
|
||||
if (!IsSubresourceContentInitialized(baseMipLevel, levelCount, baseArrayLayer,
|
||||
layerCount)) {
|
||||
ClearTexture(baseMipLevel, levelCount, baseArrayLayer, layerCount);
|
||||
}
|
||||
}
|
||||
|
||||
// TextureView
|
||||
|
||||
TextureView::TextureView(TextureBase* texture, const TextureViewDescriptor* descriptor)
|
||||
|
||||
Reference in New Issue
Block a user