Bug 1655101 - Allow webgl.texImage gpu-blit for RGB8 if supported. r=gfx-reviewers,aosmond

Differential Revision: https://phabricator.services.mozilla.com/D194943
This commit is contained in:
Kelsey Gilbert 2024-01-04 18:38:52 +00:00
parent 72e17205ae
commit ef87b37f72
13 changed files with 110 additions and 59 deletions

View File

@ -4375,6 +4375,8 @@ void ClientWebGLContext::TexImage(uint8_t funcDims, GLenum imageTarget,
// -
// -
mozilla::ipc::Shmem* pShmem = nullptr;
// Image to release after WebGLContext::TexImage().
RefPtr<layers::Image> keepAliveImage;
@ -4385,7 +4387,12 @@ void ClientWebGLContext::TexImage(uint8_t funcDims, GLenum imageTarget,
const auto& contextInfo = mNotLost->info;
const auto fallbackReason = [&]() -> Maybe<std::string> {
auto fallbackReason = BlitPreventReason(level, offset, pi, *desc);
if (!respecFormat) {
return Some(std::string{
"Fast uploads not supported for TexSubImage. Use TexImage."});
}
auto fallbackReason = BlitPreventReason(
level, offset, respecFormat, pi, *desc, contextInfo.isRgb8Renderable);
if (fallbackReason) return fallbackReason;
const bool canUploadViaSd = contextInfo.uploadableSdTypes[sdType];

View File

@ -674,8 +674,10 @@ bool TexUnpackImage::Validate(const WebGLContext* const webgl,
}
Maybe<std::string> BlitPreventReason(const int32_t level, const ivec3& offset,
const GLenum internalFormat,
const webgl::PackingInfo& pi,
const TexUnpackBlobDesc& desc) {
const TexUnpackBlobDesc& desc,
const bool isRgb8Renderable) {
const auto& size = desc.size;
const auto& unpacking = desc.unpacking;
@ -706,13 +708,31 @@ Maybe<std::string> BlitPreventReason(const int32_t level, const ivec3& offset,
}();
if (premultReason) return premultReason;
if (pi.format != LOCAL_GL_RGBA) {
return "`format` is not RGBA";
}
const auto formatReason = [&]() -> const char* {
if (pi.type != LOCAL_GL_UNSIGNED_BYTE) {
return "`type` must be `UNSIGNED_BYTE`";
}
switch (internalFormat) {
case LOCAL_GL_RGBA:
case LOCAL_GL_RGBA8:
return nullptr;
case LOCAL_GL_RGB:
case LOCAL_GL_RGB8:
if (isRgb8Renderable) {
return nullptr;
}
break;
}
if (isRgb8Renderable) {
return "effective format must be RGB8 or RGBA8";
} else {
return "effective format must be RGBA8";
}
}();
if (formatReason) return formatReason;
if (pi.type != LOCAL_GL_UNSIGNED_BYTE) {
return "`type` is not UNSIGNED_BYTE";
}
return nullptr;
}();
if (ret) {
@ -740,7 +760,8 @@ bool TexUnpackImage::TexOrSubImage(bool isSubImage, bool needsRespec,
// -
const auto reason =
BlitPreventReason(level, {xOffset, yOffset, zOffset}, pi, mDesc);
BlitPreventReason(level, {xOffset, yOffset, zOffset}, dui->internalFormat,
pi, mDesc, webgl->mIsRgb8Renderable);
if (reason) {
webgl->GeneratePerfWarning(
"Failed to hit GPU-copy fast-path."

View File

@ -42,8 +42,10 @@ struct PackingInfo;
struct DriverUnpackInfo;
Maybe<std::string> BlitPreventReason(int32_t level, const ivec3& offset,
GLenum internalFormat,
const webgl::PackingInfo&,
const TexUnpackBlobDesc&);
const TexUnpackBlobDesc&,
bool isRgb8Renderable);
class TexUnpackBlob {
public:

View File

@ -652,6 +652,7 @@ RefPtr<WebGLContext> WebGLContext::Create(HostWebGLContext* host,
out->limits = *webgl->mLimits;
out->uploadableSdTypes = UploadableSdTypes();
out->vendor = webgl->gl->Vendor();
out->isRgb8Renderable = webgl->mIsRgb8Renderable;
return webgl;
}
@ -701,6 +702,24 @@ void WebGLContext::FinishInit() {
mShouldPresent = true;
//////
// mIsRgb8Renderable
{
const auto tex = gl::ScopedTexture(gl);
const auto fb = gl::ScopedFramebuffer(gl);
gl->fBindTexture(LOCAL_GL_TEXTURE_2D, tex);
gl->fTexImage2D(LOCAL_GL_TEXTURE_2D, 0, LOCAL_GL_RGB, 1, 1, 0, LOCAL_GL_RGB,
LOCAL_GL_UNSIGNED_BYTE, nullptr);
gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, fb);
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0,
LOCAL_GL_TEXTURE_2D, tex, 0);
const auto status = gl->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
mIsRgb8Renderable = (status == LOCAL_GL_FRAMEBUFFER_COMPLETE);
}
//////
gl->ResetSyncCallCount("WebGLContext Initialization");

View File

@ -317,6 +317,7 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr {
webgl::InitContextResult* out);
private:
bool mIsRgb8Renderable = false;
void FinishInit();
protected:

View File

@ -13,6 +13,8 @@
#include "mozilla/ipc/IPDLParamTraits.h"
#include "mozilla/ipc/Shmem.h"
#include "mozilla/layers/LayersSurfaces.h"
#include "TiedFields.h"
#include "TupleUtils.h"
#include "WebGLTypes.h"
namespace mozilla {
@ -214,6 +216,34 @@ struct ParamTraits<gfxAlphaType>
: public ContiguousEnumSerializerInclusive<
gfxAlphaType, gfxAlphaType::Opaque, gfxAlphaType::NonPremult> {};
// -
// ParamTraits_TiedFields
template <class T>
struct ParamTraits_TiedFields {
static_assert(mozilla::AreAllBytesTiedFields<T>());
static void Write(MessageWriter* const writer, const T& in) {
const auto& fields = mozilla::TiedFields(in);
MapTuple(fields, [&](const auto& field) {
WriteParam(writer, field);
return true; // ignored
});
}
static bool Read(MessageReader* const reader, T* const out) {
const auto& fields = mozilla::TiedFields(*out);
bool ok = true;
MapTuple(fields, [&](auto& field) {
if (ok) {
ok &= ReadParam(reader, &field);
}
return true; // ignored
});
return ok;
}
};
// -
template <typename T>
@ -298,24 +328,8 @@ struct ParamTraits<mozilla::webgl::EnumMask<T>> final
: public PlainOldDataSerializer<mozilla::webgl::EnumMask<T>> {};
template <>
struct ParamTraits<mozilla::webgl::InitContextResult> final {
using T = mozilla::webgl::InitContextResult;
static void Write(MessageWriter* const writer, const T& in) {
WriteParam(writer, in.error);
WriteParam(writer, in.options);
WriteParam(writer, in.limits);
WriteParam(writer, in.uploadableSdTypes);
WriteParam(writer, in.vendor);
}
static bool Read(MessageReader* const reader, T* const out) {
return ReadParam(reader, &out->error) && ReadParam(reader, &out->options) &&
ReadParam(reader, &out->limits) &&
ReadParam(reader, &out->uploadableSdTypes) &&
ReadParam(reader, &out->vendor);
}
};
struct ParamTraits<mozilla::webgl::InitContextResult> final
: public ParamTraits_TiedFields<mozilla::webgl::InitContextResult> {};
template <>
struct ParamTraits<mozilla::webgl::ExtensionBits> final

View File

@ -14,8 +14,8 @@
#include <unordered_map>
#include <vector>
#include "GLContextTypes.h"
#include "GLDefs.h"
#include "GLVendor.h"
#include "ImageContainer.h"
#include "mozilla/Casting.h"
#include "mozilla/CheckedInt.h"
@ -660,9 +660,16 @@ struct Limits final {
struct InitContextResult final {
std::string error;
WebGLContextOptions options;
gl::GLVendor vendor;
bool isRgb8Renderable;
uint8_t _padding;
webgl::Limits limits;
EnumMask<layers::SurfaceDescriptor::Type> uploadableSdTypes;
gl::GLVendor vendor;
auto MutTiedFields() {
return std::tie(error, options, vendor, isRgb8Renderable, _padding, limits,
uploadableSdTypes);
}
};
// -

View File

@ -7136,7 +7136,6 @@ subsuite = webgl2-core
subsuite = webgl2-core
[generated/test_2_conformance2__textures__misc__npot-video-sizing.html]
subsuite = webgl2-core
fail-if = (os == 'android')
[generated/test_2_conformance2__textures__misc__origin-clean-conformance-offscreencanvas.html]
subsuite = webgl2-core
skip-if = 1
@ -12909,7 +12908,7 @@ subsuite = webgl1-core
skip-if = (os == 'android')
[generated/test_conformance__textures__misc__texture-npot-video.html]
subsuite = webgl1-core
skip-if = (os == 'android') || win11_2009 # win11 - 50/50 intermittent
skip-if = win11_2009 # win11 - 50/50 intermittent
[generated/test_conformance__textures__misc__texture-npot.html]
subsuite = webgl1-core
skip-if = (os == 'android')

View File

@ -71,12 +71,8 @@ fail-if = (os == 'mac' && !apple_silicon)
[generated/test_2_conformance2__programs__gl-get-frag-data-location.html]
# gl.getFragDataLocation(programEs2, 'gl_FragColor') should be -1. Was 0.
fail-if = (os == 'android')
[generated/test_2_conformance2__textures__misc__npot-video-sizing.html]
# Should be green -- that indicates the video texture's height was correct
fail-if = (os == 'android')
[generated/test_conformance__textures__misc__texture-npot-video.html]
# application crashed [@ mozilla::layers::GLImage::GetAsSoure]
skip-if = (os == 'android') || win11_2009 # win11 - 50/50 intermittent
skip-if = win11_2009 # win11 - 50/50 intermittent
####################
# Bugs surfaced during fx93 CTS update

View File

@ -37,7 +37,6 @@
#include "GLConsts.h"
#include "GLDefs.h"
#include "GLTypes.h"
#include "GLVendor.h"
#include "nsRegionFwd.h"
#include "nsString.h"
#include "GLContextTypes.h"

View File

@ -7,6 +7,7 @@
#define GLCONTEXT_TYPES_H_
#include "GLTypes.h"
#include "mozilla/DefineEnum.h"
#include "mozilla/TypedEnumBits.h"
namespace mozilla {
@ -47,6 +48,12 @@ struct GLContextDesc final : public GLContextCreateDesc {
bool isOffscreen = false;
};
// -
MOZ_DEFINE_ENUM_CLASS_WITH_BASE(GLVendor, uint8_t,
(Intel, NVIDIA, ATI, Qualcomm, Imagination,
Nouveau, Vivante, VMware, ARM, Other));
} /* namespace gl */
} /* namespace mozilla */

View File

@ -1,20 +0,0 @@
/* -*- mode: c++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* this source code form is subject to the terms of the mozilla public
* license, v. 2.0. if a copy of the mpl was not distributed with this
* file, you can obtain one at http://mozilla.org/mpl/2.0/. */
#ifndef GLVENDOR_H_
#define GLVENDOR_H_
#include "mozilla/DefineEnum.h"
namespace mozilla {
namespace gl {
MOZ_DEFINE_ENUM(GLVendor, (Intel, NVIDIA, ATI, Qualcomm, Imagination, Nouveau,
Vivante, VMware, ARM, Other));
}
} // namespace mozilla
#endif /* GLVENDOR_H_ */

View File

@ -42,7 +42,6 @@ EXPORTS += [
"GLTextureImage.h",
"GLTypes.h",
"GLUploadHelpers.h",
"GLVendor.h",
"HeapCopyOfStackArray.h",
"MozFramebuffer.h",
"ScopedGLHelpers.h",