mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-07 19:58:32 +09:00
[Fix] (Texture): give glTexBuffer the sized-format check its TODO deferred and the target-taking forms their own INVALID_ENUM
This commit is contained in:
@@ -40,15 +40,21 @@ namespace MobileGL::MG_State::GLState {
|
||||
// binding array in the getter and its floor (the GL 4.5 core minimum of 84) is that same
|
||||
// array's width, so the backend's own number never moves it.
|
||||
limits.MaxUniformBufferBindings = bindingPoints;
|
||||
// The storage-buffer ceiling has the same shape as GetIndexedBufferQueryPointCount's: the
|
||||
// backend's count capped by the array, and the array alone when there is no backend. That
|
||||
// "no backend" arm is not a detail - it is what the GPU-free test binary runs under, and
|
||||
// it has to keep matching what glGetIntegerv answers there.
|
||||
limits.MaxShaderStorageBufferBindings =
|
||||
env.HasBackend()
|
||||
? std::min<Int>(bindingPoints, std::max<Int>(env.params.MaxShaderStorageBufferBindings, 0))
|
||||
: bindingPoints;
|
||||
if (!env.HasBackend()) {
|
||||
// No backend: the two backend-derived ceilings have nothing to be measured against,
|
||||
// and zero means "do not enforce this kind" rather than "reject everything".
|
||||
// The two genuinely per-DEVICE ceilings have nothing to be measured against here, and
|
||||
// zero means "do not enforce this kind" rather than "reject everything".
|
||||
return limits;
|
||||
}
|
||||
limits.MaxSamplerBindings = std::max<Int>(env.params.MaxCombinedTextureImageUnits, 0);
|
||||
limits.MaxImageBindings = std::max<Int>(env.params.MaxImageUnits, 0);
|
||||
limits.MaxShaderStorageBufferBindings =
|
||||
std::min<Int>(bindingPoints, std::max<Int>(env.params.MaxShaderStorageBufferBindings, 0));
|
||||
return limits;
|
||||
}
|
||||
|
||||
|
||||
@@ -5697,3 +5697,81 @@ TEST_F(TextureTest, CopyTexSubImage1DRejectsAnythingButTexture1D) {
|
||||
|
||||
MG_Impl::GLImpl::BindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
// The buffer-texture entry points' error taxonomy (GL 4.6 core 8.9 / GL_EXT_texture_buffer).
|
||||
// esextcTextureBufferErrors walks every OTHER texture target through glTexBuffer and
|
||||
// glTexBufferRange and reads the code back each time, then does the same for a format a buffer
|
||||
// texture cannot take. glTexBuffer carried `// TODO: make sure internalformat is in one of
|
||||
// supported format for TexBuffer` and never checked, and the wrong-target code came out of a
|
||||
// deeper "the bound object is not a buffer texture" arm whose code depends on which entry point
|
||||
// reached it - GL_INVALID_OPERATION, which belongs only to the name-taking DSA forms.
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
TEST_F(TextureTest, TexBufferAndTexBufferRangeRejectANonBufferTargetWithInvalidEnum) {
|
||||
GLuint buffer = 0;
|
||||
MG_Impl::GLImpl::GenBuffers(1, &buffer);
|
||||
MG_Impl::GLImpl::BindBuffer(GL_TEXTURE_BUFFER, buffer);
|
||||
MG_Impl::GLImpl::BufferData(GL_TEXTURE_BUFFER, 64, nullptr, GL_STATIC_DRAW);
|
||||
DrainPendingGlErrors();
|
||||
|
||||
static constexpr GLenum kWrongTargets[] = {
|
||||
GL_TEXTURE_2D, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_3D, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_ARRAY,
|
||||
};
|
||||
for (const GLenum target : kWrongTargets) {
|
||||
MG_Impl::GLImpl::TexBuffer(target, GL_RGBA32I, buffer);
|
||||
ExpectSingleGlError(GL_INVALID_ENUM);
|
||||
MG_Impl::GLImpl::TexBufferRange(target, GL_RGBA32I, buffer, 0, 64);
|
||||
ExpectSingleGlError(GL_INVALID_ENUM);
|
||||
}
|
||||
|
||||
MG_Impl::GLImpl::BindBuffer(GL_TEXTURE_BUFFER, 0);
|
||||
MG_Impl::GLImpl::DeleteBuffers(1, &buffer);
|
||||
DrainPendingGlErrors();
|
||||
}
|
||||
|
||||
TEST_F(TextureTest, TexBufferRejectsAnInternalFormatABufferTextureCannotTake) {
|
||||
GLuint texture = 0;
|
||||
MG_Impl::GLImpl::GenTextures(1, &texture);
|
||||
MG_Impl::GLImpl::BindTexture(GL_TEXTURE_BUFFER, texture);
|
||||
GLuint buffer = 0;
|
||||
MG_Impl::GLImpl::GenBuffers(1, &buffer);
|
||||
MG_Impl::GLImpl::BindBuffer(GL_TEXTURE_BUFFER, buffer);
|
||||
MG_Impl::GLImpl::BufferData(GL_TEXTURE_BUFFER, 64, nullptr, GL_STATIC_DRAW);
|
||||
DrainPendingGlErrors();
|
||||
|
||||
// GL_DEPTH_COMPONENT32F is the one the conformance suite passes: a sized format, just not one
|
||||
// of the sized formats table 8.15 lists for a buffer texture.
|
||||
MG_Impl::GLImpl::TexBuffer(GL_TEXTURE_BUFFER, GL_DEPTH_COMPONENT32F, buffer);
|
||||
ExpectSingleGlError(GL_INVALID_ENUM);
|
||||
MG_Impl::GLImpl::TexBufferRange(GL_TEXTURE_BUFFER, GL_DEPTH_COMPONENT32F, buffer, 0, 64);
|
||||
ExpectSingleGlError(GL_INVALID_ENUM);
|
||||
|
||||
// A format the table DOES list still goes through.
|
||||
MG_Impl::GLImpl::TexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32I, buffer);
|
||||
EXPECT_EQ(MG_Impl::GLImpl::GetError(), GL_NO_ERROR);
|
||||
|
||||
MG_Impl::GLImpl::BindTexture(GL_TEXTURE_BUFFER, 0);
|
||||
MG_Impl::GLImpl::BindBuffer(GL_TEXTURE_BUFFER, 0);
|
||||
MG_Impl::GLImpl::DeleteBuffers(1, &buffer);
|
||||
DrainPendingGlErrors();
|
||||
}
|
||||
|
||||
// The DSA form keeps its own, DIFFERENT code for the corresponding shape: a texture that is not a
|
||||
// buffer texture is a wrong OBJECT, not a wrong token. The two must not be unified.
|
||||
TEST_F(TextureTest, TextureBufferKeepsInvalidOperationForANonBufferTexture) {
|
||||
GLuint texture = 0;
|
||||
MG_Impl::GLImpl::CreateTextures(GL_TEXTURE_2D, 1, &texture);
|
||||
GLuint buffer = 0;
|
||||
MG_Impl::GLImpl::GenBuffers(1, &buffer);
|
||||
MG_Impl::GLImpl::BindBuffer(GL_TEXTURE_BUFFER, buffer);
|
||||
MG_Impl::GLImpl::BufferData(GL_TEXTURE_BUFFER, 64, nullptr, GL_STATIC_DRAW);
|
||||
DrainPendingGlErrors();
|
||||
|
||||
MG_Impl::GLImpl::TextureBuffer(texture, GL_RGBA32I, buffer);
|
||||
ExpectSingleGlError(GL_INVALID_OPERATION);
|
||||
|
||||
MG_Impl::GLImpl::BindBuffer(GL_TEXTURE_BUFFER, 0);
|
||||
MG_Impl::GLImpl::DeleteBuffers(1, &buffer);
|
||||
DrainPendingGlErrors();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user