mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-07 19:58:32 +09:00
[Fix, Test] (MG_Backend, MG_Impl, MG_State): advertise the uniform-block and stencil-texturing strings a 4.0 context hides behind, forward DEPTH_STENCIL_TEXTURE_MODE to both backends, and stop a reserved transform feedback name passing for an object
This commit is contained in:
@@ -940,6 +940,17 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// picks a whole different shader for draw_buffers without
|
||||
// explicit_attrib_location. DirectVulkan advertises both.
|
||||
E_GL_ARB_explicit_attrib_location, E_GL_ARB_texture_multisample, E_GL_ARB_shader_image_size,
|
||||
// Core since GL 3.1 and implemented for every version advertised here. The string
|
||||
// matters because applications gate the ENTRY POINTS on it rather than on the
|
||||
// version: a caller that finds the extension missing never resolves
|
||||
// glGetUniformBlockIndex / glUniformBlockBinding, and one that then uses uniform
|
||||
// blocks anyway calls through a null pointer.
|
||||
E_GL_ARB_uniform_buffer_object,
|
||||
// Sampling the stencil aspect through DEPTH_STENCIL_TEXTURE_MODE. Core from 4.3,
|
||||
// so on a 4.0 context the string is the only way to reach it. The host ES driver
|
||||
// has had the same texture parameter since ES 3.1, which every device MobileGL
|
||||
// runs on provides.
|
||||
E_GL_ARB_stencil_texturing,
|
||||
// Advertised with GL_NUM_PROGRAM_BINARY_FORMATS = 0, which the
|
||||
// extension explicitly permits. It is also the only thing that
|
||||
// exposes glProgramParameteri before GL 4.1.
|
||||
|
||||
@@ -3315,6 +3315,29 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
MGLOG_D("%s(%s:%d) ES error %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str());
|
||||
});
|
||||
}
|
||||
|
||||
// GL_DEPTH_STENCIL_TEXTURE_MODE (GL_ARB_stencil_texturing / ES 3.1 core): which aspect
|
||||
// of a packed depth/stencil image a sampler reads. Until this was forwarded the
|
||||
// frontend kept the mode as a pure shadow - glGetTexParameter answered it, sampling
|
||||
// ignored it - so a usampler2D bound to a D24S8 texture in STENCIL_INDEX mode read the
|
||||
// depth aspect. Texture state rather than sampler state, so multisample targets take
|
||||
// it too (ES 3.1 8.10 lists it among the three pnames they accept). It is only sent
|
||||
// when it has moved, which for the overwhelming majority of textures is never.
|
||||
const Bool supportsStencilTextureMode =
|
||||
g_GLESCapabilities.GLESVersion.Major > 3 ||
|
||||
(g_GLESCapabilities.GLESVersion.Major == 3 && g_GLESCapabilities.GLESVersion.Minor >= 1);
|
||||
if (supportsStencilTextureMode) {
|
||||
const GLenum depthStencilTextureMode = stateTextureObject->GetDepthStencilTextureMode();
|
||||
if (m_cacheDepthStencilTextureMode != depthStencilTextureMode) {
|
||||
g_GLESFuncs.glTexParameteri(target, GL_DEPTH_STENCIL_TEXTURE_MODE,
|
||||
static_cast<GLint>(depthStencilTextureMode));
|
||||
m_cacheDepthStencilTextureMode = depthStencilTextureMode;
|
||||
DebugImpl::ErrorLopper::Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) {
|
||||
MGLOG_D("%s(%s:%d) ES error %s", func, file, line,
|
||||
MG_Util::ConvertGLEnumToString(err).c_str());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ActivateTextureUnit(Uint unit) {
|
||||
|
||||
@@ -699,6 +699,12 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
FloatVec4 m_cacheBorderColor = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
Vec4<TextureSwizzleParam> m_cacheSwizzleParams = {TextureSwizzleParam::Red, TextureSwizzleParam::Green,
|
||||
TextureSwizzleParam::Blue, TextureSwizzleParam::Alpha};
|
||||
// GL_DEPTH_STENCIL_TEXTURE_MODE. GL_DEPTH_COMPONENT is the GL and ES default, so a
|
||||
// texture that never asks for the stencil aspect never emits the call. The
|
||||
// depth/stencil readback and replicate-blit emulations also write this parameter
|
||||
// raw, but only ever on their own scratch textures (never on an application
|
||||
// texture), so they cannot desynchronise this cache.
|
||||
GLenum m_cacheDepthStencilTextureMode = GL_DEPTH_COMPONENT;
|
||||
Uint16 m_syncedSamplerVersion = 0;
|
||||
Uint16 m_syncedTextureParamsVersion = 0;
|
||||
};
|
||||
|
||||
@@ -517,6 +517,15 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
E_GL_ARB_gpu_shader_int64, E_GL_KHR_debug, E_GL_ARB_gpu_shader5, E_GL_ARB_multi_bind,
|
||||
E_GL_ARB_shading_language_420pack, E_GL_ARB_vertex_attrib_binding, E_GL_ARB_shader_image_size,
|
||||
E_GL_ARB_explicit_attrib_location,
|
||||
// Core since GL 3.1 and implemented for every version advertised here. The string
|
||||
// matters because applications gate the ENTRY POINTS on it rather than on the
|
||||
// version: a caller that finds the extension missing never resolves
|
||||
// glGetUniformBlockIndex / glUniformBlockBinding, and one that then uses uniform
|
||||
// blocks anyway calls through a null pointer.
|
||||
E_GL_ARB_uniform_buffer_object,
|
||||
// Sampling the stencil aspect through DEPTH_STENCIL_TEXTURE_MODE. Core from 4.3,
|
||||
// so on a 4.0 context the string is the only way to reach it.
|
||||
E_GL_ARB_stencil_texturing,
|
||||
// Advertised with GL_NUM_PROGRAM_BINARY_FORMATS = 0, which the
|
||||
// extension explicitly permits. It is also the only thing that
|
||||
// exposes glProgramParameteri before GL 4.1.
|
||||
|
||||
@@ -950,7 +950,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
|
||||
const TextureFormatInfo formatInfo = ResolveTextureFormatInfo(texture.GetFormat());
|
||||
const VkComponentMapping sampledComponents = ResolveSampledViewComponents(texture, formatInfo);
|
||||
const VkImageAspectFlags sampledAspect = ResolveSampledImageViewAspectMask(resource->aspect);
|
||||
const VkImageAspectFlags sampledAspect =
|
||||
ResolveSampledImageViewAspectMask(resource->aspect, texture.GetDepthStencilTextureMode());
|
||||
perMipSampledView = CreateImageView(resource->image, resource->format, sampledAspect, resource->viewType,
|
||||
mipLevel, 1, 0, resource->arrayLayers, &sampledComponents);
|
||||
if (perMipSampledView == VK_NULL_HANDLE) {
|
||||
@@ -2238,7 +2239,8 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
if (resource.fullView == VK_NULL_HANDLE) {
|
||||
return false;
|
||||
}
|
||||
const VkImageAspectFlags sampledAspect = ResolveSampledImageViewAspectMask(resource.aspect);
|
||||
const VkImageAspectFlags sampledAspect =
|
||||
ResolveSampledImageViewAspectMask(resource.aspect, texture.GetDepthStencilTextureMode());
|
||||
resource.sampledView = CreateImageView(resource.image, resource.format, sampledAspect, resource.viewType,
|
||||
baseMipLevel, levelCount, 0, resource.arrayLayers, &sampledComponents);
|
||||
if (resource.sampledView == VK_NULL_HANDLE) {
|
||||
@@ -2860,10 +2862,19 @@ namespace MobileGL::MG_Backend::DirectVulkan {
|
||||
}
|
||||
}
|
||||
|
||||
VkImageAspectFlags VkTextureManager::ResolveSampledImageViewAspectMask(VkImageAspectFlags imageAspect) {
|
||||
VkImageAspectFlags VkTextureManager::ResolveSampledImageViewAspectMask(VkImageAspectFlags imageAspect,
|
||||
GLenum depthStencilTextureMode) {
|
||||
if ((imageAspect & VK_IMAGE_ASPECT_COLOR_BIT) != 0) {
|
||||
return VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
}
|
||||
// A sampled view of a combined depth/stencil image may name exactly one aspect
|
||||
// (VUID-VkDescriptorImageInfo-imageView-01976), and GL_DEPTH_STENCIL_TEXTURE_MODE is
|
||||
// what picks it - the whole content of GL_ARB_stencil_texturing. Depth stays the
|
||||
// default, so nothing that never sets the mode changes shape. The texture's params
|
||||
// version moves with the mode, which is what makes the cached views be rebuilt.
|
||||
if (depthStencilTextureMode == GL_STENCIL_INDEX && (imageAspect & VK_IMAGE_ASPECT_STENCIL_BIT) != 0) {
|
||||
return VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
}
|
||||
if ((imageAspect & VK_IMAGE_ASPECT_DEPTH_BIT) != 0) {
|
||||
return VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
}
|
||||
|
||||
@@ -379,7 +379,11 @@ public:
|
||||
// true - a false positive merely ends the render pass, a false negative would skip a barrier.
|
||||
Bool NeedsStorageImagePreparation(MG_State::GLState::ITextureObject& texture) const;
|
||||
|
||||
static VkImageAspectFlags ResolveSampledImageViewAspectMask(VkImageAspectFlags imageAspect);
|
||||
// `depthStencilTextureMode` is the texture's GL_DEPTH_STENCIL_TEXTURE_MODE; it only decides
|
||||
// anything for an image that carries both aspects. Defaulted so the call sites that have no
|
||||
// texture in hand keep the depth-aspect answer they have always given.
|
||||
static VkImageAspectFlags ResolveSampledImageViewAspectMask(VkImageAspectFlags imageAspect,
|
||||
GLenum depthStencilTextureMode = GL_DEPTH_COMPONENT);
|
||||
static VkFormat ResolveSampledImageViewFormat(VkFormat imageFormat, SamplerNumericDomain numericDomain);
|
||||
static Bool AreSampledImageViewFormatsCompatible(VkFormat imageFormat, VkFormat viewFormat);
|
||||
static Bool AreStorageImageViewFormatsCompatible(VkFormat imageFormat, VkFormat viewFormat);
|
||||
|
||||
@@ -1259,7 +1259,15 @@ namespace MobileGL::MG_Impl::GLImpl {
|
||||
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", functionName, "instancecount must be non-negative."));
|
||||
return;
|
||||
}
|
||||
if (!MG_State::pGLContext->ValidateTransformFeedbackName(id)) {
|
||||
// "id is not the name of a transform feedback object" has to mean the same thing here
|
||||
// as it does to glIsTransformFeedback, and the two predicates are not interchangeable:
|
||||
// a name glGenTransformFeedbacks handed out is only reserved until it is first bound,
|
||||
// and only the bind turns it into an object (GL 4.6 core 13.2.1). ValidateTransformFeedbackName
|
||||
// answers the reservation question - the right one for glBindTransformFeedback, which is
|
||||
// what turns a reserved name into an object - so using it here let a generated-but-unbound
|
||||
// name through to the completed-span check below and raised INVALID_OPERATION where the
|
||||
// spec asks for INVALID_VALUE. Name 0 is the default object and always drawable.
|
||||
if (id != 0 && !MG_State::pGLContext->IsTransformFeedbackObject(id)) {
|
||||
MG_State::pGLContext->RecordError(
|
||||
ErrorCode::InvalidValue,
|
||||
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", functionName,
|
||||
|
||||
@@ -117,7 +117,15 @@ namespace MobileGL::MG_State::GLState {
|
||||
void SetFixedSampleLocations(Bool fixedSampleLocations) override;
|
||||
Uint64 GetLifetimeId() const override;
|
||||
GLenum GetDepthStencilTextureMode() const override { return m_depthStencilTextureMode; }
|
||||
void SetDepthStencilTextureMode(GLenum mode) override { m_depthStencilTextureMode = mode; }
|
||||
// Bumps the params version like every other backend-visible texture parameter: the mode
|
||||
// decides which ASPECT of a packed depth/stencil image a sampler reads, which DirectGLES
|
||||
// forwards as a texture parameter and DirectVulkan bakes into the sampled image view. A
|
||||
// silent write here would leave both backends showing the aspect they last built.
|
||||
void SetDepthStencilTextureMode(GLenum mode) override {
|
||||
if (m_depthStencilTextureMode == mode) return;
|
||||
m_depthStencilTextureMode = mode;
|
||||
++m_textureParamsVersion;
|
||||
}
|
||||
|
||||
protected:
|
||||
static Uint64 AllocateLifetimeId();
|
||||
|
||||
@@ -198,6 +198,38 @@ TEST(DirectGLESSanity, AdvertisesDepthTextureForGlmarkShadowScenes) {
|
||||
EXPECT_NE(std::find(extensions.begin(), extensions.end(), MobileGL::E_GL_ARB_depth_texture), extensions.end());
|
||||
}
|
||||
|
||||
// Two strings that name capabilities MobileGL has always had, and that were missing from the
|
||||
// advertised list for as long as it existed.
|
||||
//
|
||||
// GL_ARB_uniform_buffer_object is the one with teeth: applications gate the ENTRY POINTS on the
|
||||
// string rather than on the context version. KHR-GL4x.transform_feedback.draw_xfb_instanced_test
|
||||
// resolves glGetUniformBlockIndex / glUniformBlockBinding only inside `if (is_arb_ubo)`, then
|
||||
// calls them unconditionally because the context claims >= 4.2 - so a missing string turned into
|
||||
// a call through a null pointer and took the whole process down with SIGSEGV. Withdrawing it
|
||||
// again would restore that crash on both backends.
|
||||
//
|
||||
// GL_ARB_stencil_texturing is what makes DEPTH_STENCIL_TEXTURE_MODE = GL_STENCIL_INDEX reachable
|
||||
// at all before GL 4.3, which is the whole of KHR-GL3x.packed_depth_stencil.stencil_texturing.
|
||||
TEST(DirectGLESSanity, AdvertisesUniformBufferObjectAndStencilTexturing) {
|
||||
MobileGL::MG_Backend::DirectGLES::BackendObject_DirectGLES backend;
|
||||
const auto& extensions = backend.GetRendererInfo().RendererGLInfo.Extensions;
|
||||
|
||||
EXPECT_NE(std::find(extensions.begin(), extensions.end(), MobileGL::E_GL_ARB_uniform_buffer_object),
|
||||
extensions.end());
|
||||
EXPECT_NE(std::find(extensions.begin(), extensions.end(), MobileGL::E_GL_ARB_stencil_texturing),
|
||||
extensions.end());
|
||||
}
|
||||
|
||||
TEST(DirectVulkanSanity, AdvertisesUniformBufferObjectAndStencilTexturing) {
|
||||
MobileGL::MG_Backend::DirectVulkan::BackendObject_DirectVulkan backend;
|
||||
const auto& extensions = backend.GetRendererInfo().RendererGLInfo.Extensions;
|
||||
|
||||
EXPECT_NE(std::find(extensions.begin(), extensions.end(), MobileGL::E_GL_ARB_uniform_buffer_object),
|
||||
extensions.end());
|
||||
EXPECT_NE(std::find(extensions.begin(), extensions.end(), MobileGL::E_GL_ARB_stencil_texturing),
|
||||
extensions.end());
|
||||
}
|
||||
|
||||
// Voxy only ever needed the extensions, which stay advertised whatever the version is; the version
|
||||
// assertion just pins what the backend really reports, now that V_OpenGL40 is in the list.
|
||||
TEST(DirectGLESSanity, AdvertisesVoxyRequiredRenderingExtensions) {
|
||||
@@ -435,6 +467,31 @@ TEST(DirectVulkanSanity, AdvertisesTextureStorageForDirectStateAccess) {
|
||||
EXPECT_NE(std::find(extensions.begin(), extensions.end(), MobileGL::E_GL_ARB_texture_storage), extensions.end());
|
||||
}
|
||||
|
||||
// A sampled view of a combined depth/stencil image may name exactly one aspect, and
|
||||
// GL_DEPTH_STENCIL_TEXTURE_MODE picks which - the whole of GL_ARB_stencil_texturing on this
|
||||
// backend. Depth remains the answer for everything that does not ask for stencil, including
|
||||
// depth-only images asked for the stencil aspect they do not have.
|
||||
TEST(DirectVulkanSanity, SampledViewAspectFollowsDepthStencilTextureMode) {
|
||||
using MobileGL::MG_Backend::DirectVulkan::VkTextureManager;
|
||||
constexpr VkImageAspectFlags kPacked = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
|
||||
EXPECT_EQ(VkTextureManager::ResolveSampledImageViewAspectMask(kPacked, GL_DEPTH_COMPONENT),
|
||||
static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_DEPTH_BIT));
|
||||
EXPECT_EQ(VkTextureManager::ResolveSampledImageViewAspectMask(kPacked, GL_STENCIL_INDEX),
|
||||
static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_STENCIL_BIT));
|
||||
// The default argument is the pre-existing behaviour, for the call sites with no texture.
|
||||
EXPECT_EQ(VkTextureManager::ResolveSampledImageViewAspectMask(kPacked),
|
||||
static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_DEPTH_BIT));
|
||||
|
||||
// Single-aspect images ignore the mode: there is only one aspect to name.
|
||||
EXPECT_EQ(VkTextureManager::ResolveSampledImageViewAspectMask(VK_IMAGE_ASPECT_DEPTH_BIT, GL_STENCIL_INDEX),
|
||||
static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_DEPTH_BIT));
|
||||
EXPECT_EQ(VkTextureManager::ResolveSampledImageViewAspectMask(VK_IMAGE_ASPECT_STENCIL_BIT, GL_DEPTH_COMPONENT),
|
||||
static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_STENCIL_BIT));
|
||||
EXPECT_EQ(VkTextureManager::ResolveSampledImageViewAspectMask(VK_IMAGE_ASPECT_COLOR_BIT, GL_STENCIL_INDEX),
|
||||
static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT));
|
||||
}
|
||||
|
||||
TEST(DirectVulkanSanity, RenderPassExtentUsesSwapchainSizeOnlyForDefaultFramebuffer) {
|
||||
using MobileGL::MG_Backend::DirectVulkan::ResolveRenderPassFramebufferExtent;
|
||||
|
||||
|
||||
@@ -323,6 +323,47 @@ namespace {
|
||||
static_cast<void>(parameterBuffer);
|
||||
}
|
||||
|
||||
// A transform feedback name has two different truths and glDrawTransformFeedback used to ask
|
||||
// for the wrong one. glGenTransformFeedbacks only RESERVES a name; the first
|
||||
// glBindTransformFeedback is what creates the object (GL 4.6 core 13.2.1), and
|
||||
// glIsTransformFeedback reports exactly that distinction. glDrawTransformFeedback's
|
||||
// "id is not the name of a transform feedback object" INVALID_VALUE has to agree with
|
||||
// glIsTransformFeedback, or a caller that picks an unused name the way
|
||||
// KHR-GL4x.transform_feedback.api_errors_test does - increment until glIsTransformFeedback
|
||||
// says false - gets a name the draw then accepts, and the draw falls through to a different
|
||||
// error entirely (INVALID_OPERATION, "glEndTransformFeedback has never been called").
|
||||
//
|
||||
// The draw path itself needs a backend and a linked program before it reaches the name, which
|
||||
// this GPU-free suite has neither of, so what is pinned here is the predicate pair the fix
|
||||
// turns on: the two must not collapse back into one.
|
||||
TEST_F(NegativeApiErrorsTest, ReservedTransformFeedbackNameIsNotYetAnObject) {
|
||||
GLuint name = 0;
|
||||
GenTransformFeedbacks(1, &name);
|
||||
ASSERT_NE(name, 0u);
|
||||
DrainErrors();
|
||||
|
||||
// Reserved, so it is a legal argument to glBindTransformFeedback...
|
||||
EXPECT_TRUE(MG_State::pGLContext->ValidateTransformFeedbackName(name));
|
||||
// ...but not an object yet, which is what a draw must key off.
|
||||
EXPECT_FALSE(MG_State::pGLContext->IsTransformFeedbackObject(name));
|
||||
EXPECT_EQ(IsTransformFeedback(name), GL_FALSE);
|
||||
|
||||
BindTransformFeedback(GL_TRANSFORM_FEEDBACK, name);
|
||||
EXPECT_EQ(GetError(), GL_NO_ERROR);
|
||||
|
||||
EXPECT_TRUE(MG_State::pGLContext->ValidateTransformFeedbackName(name));
|
||||
EXPECT_TRUE(MG_State::pGLContext->IsTransformFeedbackObject(name));
|
||||
EXPECT_EQ(IsTransformFeedback(name), GL_TRUE);
|
||||
|
||||
// The default object is never "an object" by this predicate and is always drawable, so
|
||||
// the draw path has to special-case it rather than reuse the answer directly.
|
||||
EXPECT_FALSE(MG_State::pGLContext->IsTransformFeedbackObject(0));
|
||||
EXPECT_TRUE(MG_State::pGLContext->ValidateTransformFeedbackName(0));
|
||||
|
||||
BindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
|
||||
DrainErrors();
|
||||
}
|
||||
|
||||
TEST_F(NegativeApiErrorsTest, TexStorage3DRejectsCompressedFormatsOnTexture3D) {
|
||||
GLuint texture = 0;
|
||||
GenTextures(1, &texture);
|
||||
|
||||
@@ -1651,6 +1651,43 @@ TEST_F(TextureTest, AnUncompressedRespecificationClearsTheCompressedTag) {
|
||||
EXPECT_EQ(MG_Impl::GLImpl::GetError(), GL_NO_ERROR);
|
||||
}
|
||||
|
||||
// GL_DEPTH_STENCIL_TEXTURE_MODE used to be a pure frontend shadow: stored, answered by
|
||||
// glGetTexParameter, and never shown to a backend. Sampling therefore always read the depth
|
||||
// aspect however the mode was set, which is the whole of
|
||||
// KHR-GL3x.packed_depth_stencil.stencil_texturing. Both backends pick the aspect up through the
|
||||
// texture-params version - DirectGLES re-emits glTexParameteri when it moves, DirectVulkan
|
||||
// rebuilds the sampled image view - so the version bump is the load-bearing part, and a
|
||||
// no-op write must not spend one (every bump costs DirectVulkan a view recreation).
|
||||
TEST_F(TextureTest, DepthStencilTextureModeIsBackendVisibleThroughTheParamsVersion) {
|
||||
GLuint texture = 0;
|
||||
MG_Impl::GLImpl::GenTextures(1, &texture);
|
||||
MG_Impl::GLImpl::BindTexture(GL_TEXTURE_2D, texture);
|
||||
MG_Impl::GLImpl::TexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, 8, 8);
|
||||
ASSERT_EQ(MG_Impl::GLImpl::GetError(), GL_NO_ERROR);
|
||||
|
||||
const auto textureObject = MG_State::pGLContext->GetTextureObject(texture);
|
||||
ASSERT_NE(textureObject, nullptr);
|
||||
EXPECT_EQ(textureObject->GetDepthStencilTextureMode(), static_cast<GLenum>(GL_DEPTH_COMPONENT));
|
||||
|
||||
const Uint16 initialVersion = textureObject->GetTextureParamsVersion();
|
||||
MG_Impl::GLImpl::TexParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
|
||||
ASSERT_EQ(MG_Impl::GLImpl::GetError(), GL_NO_ERROR);
|
||||
EXPECT_EQ(textureObject->GetDepthStencilTextureMode(), static_cast<GLenum>(GL_STENCIL_INDEX));
|
||||
EXPECT_NE(textureObject->GetTextureParamsVersion(), initialVersion);
|
||||
|
||||
// Re-writing the value already in force is not a change and must not invalidate anything.
|
||||
const Uint16 settledVersion = textureObject->GetTextureParamsVersion();
|
||||
MG_Impl::GLImpl::TexParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
|
||||
ASSERT_EQ(MG_Impl::GLImpl::GetError(), GL_NO_ERROR);
|
||||
EXPECT_EQ(textureObject->GetTextureParamsVersion(), settledVersion);
|
||||
|
||||
// ...and going back to the depth aspect is a change again.
|
||||
MG_Impl::GLImpl::TexParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT);
|
||||
ASSERT_EQ(MG_Impl::GLImpl::GetError(), GL_NO_ERROR);
|
||||
EXPECT_EQ(textureObject->GetDepthStencilTextureMode(), static_cast<GLenum>(GL_DEPTH_COMPONENT));
|
||||
EXPECT_NE(textureObject->GetTextureParamsVersion(), settledVersion);
|
||||
}
|
||||
|
||||
namespace {
|
||||
// 8x8 RGTC1: 2x2 blocks of 8 bytes, so the stored image is 32 bytes and one block row is 16.
|
||||
constexpr GLsizei kRgtc1Size8x8 = 32;
|
||||
|
||||
Reference in New Issue
Block a user