mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-07 19:58:32 +09:00
[Fix] (Espryt): allocate the packed16 probe's textures uploads-first, the order a minted backend texture performs and the one the Mali layout choice keys on
This commit is contained in:
@@ -1934,17 +1934,20 @@ namespace MobileGL::MG_Util::SelfTest {
|
|||||||
// 30/15/7 x12; the plain endpoints are 7/3/1), against plain-2D endpoints.
|
// 30/15/7 x12; the plain endpoints are 7/3/1), against plain-2D endpoints.
|
||||||
//
|
//
|
||||||
// WHAT THE DEVICE MEASUREMENTS ACTUALLY SHOWED (round 2): the mirrored field order is a
|
// WHAT THE DEVICE MEASUREMENTS ACTUALLY SHOWED (round 2): the mirrored field order is a
|
||||||
// property of the WHOLE ALLOCATION, not of a mip level. In MobileGL's live context this
|
// property of the WHOLE ALLOCATION, not of a mip level, and the driver picks it from
|
||||||
// array shape lands in the *_REV layout at EVERY level - the first deployment's control
|
// the texture state IN FORCE WHILE THE LEVELS ARE UPLOADED. Measured raw on the
|
||||||
// copy out of LEVEL 0 delivered the mirror too, which is what vetoed its own verdict -
|
// affected Mali (same shape, same data, same context): three uploads with NEAREST and
|
||||||
// while the small arrays the CTS's passing iterations used (7- and 15-texel bases; its
|
// MAX_LEVEL=2 already set land in the plain layout, while the same three uploads on a
|
||||||
// src/dst dim loop is {7, 15}, so a base-30 array only ever appears at level 1) land in
|
// fresh texture still at the driver defaults - parameters set only afterwards, which
|
||||||
// the plain layout. A raw standalone context on the same driver additionally showed one-
|
// is exactly the order a freshly minted MobileGL backend texture performs - land in
|
||||||
// and two-level 30x30x12 arrays mirrored where a fresh three-level one is not, so the
|
// the *_REV layout at EVERY level; one- and two-level allocations and params-first
|
||||||
// driver's layout choice depends on allocation shape AND context history. The probe
|
// uploads under a mipmapped MIN_FILTER mirror too. The small arrays the CTS's passing
|
||||||
// therefore measures IN SITU - this very context is the one the application's copies run
|
// iterations used (7- and 15-texel bases; its src/dst dim loop is {7, 15}, so a
|
||||||
// in - and treats a mirror delivered from ANY level as the finding, with the machinery
|
// base-30 array only ever appears at level 1) land plain, which is why the failures
|
||||||
// controls below instead of a per-level "clean" assumption that does not exist.
|
// looked per-mip-level from the QPA alone. The probe therefore allocates exactly the
|
||||||
|
// way MobileGL does (uploads first), measures IN SITU, and treats a mirror delivered
|
||||||
|
// from ANY level as the finding, with machinery controls below instead of a per-level
|
||||||
|
// "clean" assumption that does not exist.
|
||||||
constexpr GLsizei kPacked16BaseSize = 30;
|
constexpr GLsizei kPacked16BaseSize = 30;
|
||||||
constexpr GLsizei kPacked16Layers = 12;
|
constexpr GLsizei kPacked16Layers = 12;
|
||||||
constexpr GLsizei kPacked16DstSize = 7;
|
constexpr GLsizei kPacked16DstSize = 7;
|
||||||
@@ -1969,18 +1972,22 @@ namespace MobileGL::MG_Util::SelfTest {
|
|||||||
constexpr Int kPacked16Tolerance = 4;
|
constexpr Int kPacked16Tolerance = 4;
|
||||||
|
|
||||||
// A three-level GL_RGB5_A1 2D array (30/15/7, twelve layers each) allocated the way
|
// A three-level GL_RGB5_A1 2D array (30/15/7, twelve layers each) allocated the way
|
||||||
// MobileGL's own mutable-texture path allocates one (glTexImage3D per level), with
|
// MobileGL's own mutable-texture path allocates one, ORDER INCLUDED: glTexImage3D per
|
||||||
// every texel of every level holding kPacked16Word. MAX_LEVEL is clamped to the
|
// level FIRST, on a fresh texture still at the driver defaults, and the parameters
|
||||||
// CTS's makeTextureComplete(0, 2) shape, which also keeps the chain complete - some
|
// only afterwards. The order is load-bearing on the affected Mali: uploads-then-params
|
||||||
// drivers refuse glCopyImageSubData on an incomplete texture.
|
// (what a freshly minted backend texture gets - the storage sync runs before the
|
||||||
|
// parameter re-push, see SyncTextureObjectToBackend) lands this allocation in the
|
||||||
|
// mirrored layout at every level, while the same calls with NEAREST and MAX_LEVEL set
|
||||||
|
// BEFORE the uploads land it in the plain one - a params-first probe measured "clean"
|
||||||
|
// in the very context whose params-after textures were mirroring, which is exactly the
|
||||||
|
// miss round two exists to fix. MAX_LEVEL still ends at the CTS's
|
||||||
|
// makeTextureComplete(0, 2) shape, which keeps the chain complete - some drivers
|
||||||
|
// refuse glCopyImageSubData on an incomplete texture.
|
||||||
GLuint MakePacked16ArrayTexture(const GLESFunctionsTable& gl) {
|
GLuint MakePacked16ArrayTexture(const GLESFunctionsTable& gl) {
|
||||||
GLuint texture = 0;
|
GLuint texture = 0;
|
||||||
gl.glGenTextures(1, &texture);
|
gl.glGenTextures(1, &texture);
|
||||||
if (texture == 0) return 0;
|
if (texture == 0) return 0;
|
||||||
gl.glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
|
gl.glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
|
||||||
gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
||||||
gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, kPacked16Levels - 1);
|
|
||||||
for (GLint level = 0; level < kPacked16Levels; ++level) {
|
for (GLint level = 0; level < kPacked16Levels; ++level) {
|
||||||
const GLsizei size = kPacked16BaseSize >> level;
|
const GLsizei size = kPacked16BaseSize >> level;
|
||||||
const Vector<Uint16> words(
|
const Vector<Uint16> words(
|
||||||
@@ -1988,6 +1995,9 @@ namespace MobileGL::MG_Util::SelfTest {
|
|||||||
gl.glTexImage3D(GL_TEXTURE_2D_ARRAY, level, GL_RGB5_A1, size, size, kPacked16Layers, 0,
|
gl.glTexImage3D(GL_TEXTURE_2D_ARRAY, level, GL_RGB5_A1, size, size, kPacked16Layers, 0,
|
||||||
GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, words.data());
|
GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, words.data());
|
||||||
}
|
}
|
||||||
|
gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, kPacked16Levels - 1);
|
||||||
gl.glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
|
gl.glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
@@ -1998,21 +2008,24 @@ namespace MobileGL::MG_Util::SelfTest {
|
|||||||
// A plain-2D endpoint with the CTS's three-level 7/3/1 chain, every texel of every
|
// A plain-2D endpoint with the CTS's three-level 7/3/1 chain, every texel of every
|
||||||
// level holding `fill`: 0xFFFF (the CTS's own (1,1,1,1) destination fill, so a copy
|
// level holding `fill`: 0xFFFF (the CTS's own (1,1,1,1) destination fill, so a copy
|
||||||
// that silently did nothing reads as "no verdict" rather than as either prediction),
|
// that silently did nothing reads as "no verdict" rather than as either prediction),
|
||||||
// or kPacked16Word for the machinery control's source.
|
// or kPacked16Word for the machinery control's source. Uploads first, parameters
|
||||||
|
// after, for the same in-situ fidelity as the array above - this is the allocation
|
||||||
|
// discipline every MobileGL-minted texture gets, and the shape the failing bodies'
|
||||||
|
// clean plain endpoints had.
|
||||||
GLuint MakePacked16FlatTexture(const GLESFunctionsTable& gl, Uint16 fill) {
|
GLuint MakePacked16FlatTexture(const GLESFunctionsTable& gl, Uint16 fill) {
|
||||||
GLuint texture = 0;
|
GLuint texture = 0;
|
||||||
gl.glGenTextures(1, &texture);
|
gl.glGenTextures(1, &texture);
|
||||||
if (texture == 0) return 0;
|
if (texture == 0) return 0;
|
||||||
gl.glBindTexture(GL_TEXTURE_2D, texture);
|
gl.glBindTexture(GL_TEXTURE_2D, texture);
|
||||||
gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
||||||
gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, kPacked16Levels - 1);
|
|
||||||
for (GLint level = 0; level < kPacked16Levels; ++level) {
|
for (GLint level = 0; level < kPacked16Levels; ++level) {
|
||||||
const GLsizei size = std::max<GLsizei>(kPacked16DstSize >> level, 1);
|
const GLsizei size = std::max<GLsizei>(kPacked16DstSize >> level, 1);
|
||||||
const Vector<Uint16> texels(static_cast<SizeT>(size) * size, fill);
|
const Vector<Uint16> texels(static_cast<SizeT>(size) * size, fill);
|
||||||
gl.glTexImage2D(GL_TEXTURE_2D, level, GL_RGB5_A1, size, size, 0, GL_RGBA,
|
gl.glTexImage2D(GL_TEXTURE_2D, level, GL_RGB5_A1, size, size, 0, GL_RGBA,
|
||||||
GL_UNSIGNED_SHORT_5_5_5_1, texels.data());
|
GL_UNSIGNED_SHORT_5_5_5_1, texels.data());
|
||||||
}
|
}
|
||||||
|
gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, kPacked16Levels - 1);
|
||||||
gl.glBindTexture(GL_TEXTURE_2D, 0);
|
gl.glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user