mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 21:58:31 +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
|
// 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.
|
// array's width, so the backend's own number never moves it.
|
||||||
limits.MaxUniformBufferBindings = bindingPoints;
|
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()) {
|
if (!env.HasBackend()) {
|
||||||
// No backend: the two backend-derived ceilings have nothing to be measured against,
|
// The two genuinely per-DEVICE ceilings have nothing to be measured against here, and
|
||||||
// and zero means "do not enforce this kind" rather than "reject everything".
|
// zero means "do not enforce this kind" rather than "reject everything".
|
||||||
return limits;
|
return limits;
|
||||||
}
|
}
|
||||||
limits.MaxSamplerBindings = std::max<Int>(env.params.MaxCombinedTextureImageUnits, 0);
|
limits.MaxSamplerBindings = std::max<Int>(env.params.MaxCombinedTextureImageUnits, 0);
|
||||||
limits.MaxImageBindings = std::max<Int>(env.params.MaxImageUnits, 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;
|
return limits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5697,3 +5697,81 @@ TEST_F(TextureTest, CopyTexSubImage1DRejectsAnythingButTexture1D) {
|
|||||||
|
|
||||||
MG_Impl::GLImpl::BindTexture(GL_TEXTURE_2D, 0);
|
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