Path: blob/main_old/src/tests/gl_tests/BPTCCompressedTextureTest.cpp
1693 views
//1// Copyright 2018 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//56// BPTCCompressedTextureTest.cpp: Tests of the GL_EXT_texture_compression_bptc extension78#include "test_utils/ANGLETest.h"9#include "test_utils/gl_raii.h"1011using namespace angle;1213namespace14{1516const unsigned int kPixelTolerance = 1u;1718// The pixel data represents a 4x4 pixel image with the left side colored red and the right side19// green. It was BC7 encoded using Microsoft's BC6HBC7Encoder.20const std::array<GLubyte, 16> kBC7Data4x4 = {0x50, 0x1f, 0xfc, 0xf, 0x0, 0xf0, 0xe3, 0xe1,210xe1, 0xe1, 0xc1, 0xf, 0xfc, 0xc0, 0xf, 0xfc};2223// The pixel data represents a 4x4 pixel image with the transparent black solid color.24// Sampling from a zero-filled block is undefined, so use a valid one.25const std::array<GLubyte, 16> kBC7BlackData4x4 = {0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};27} // anonymous namespace2829class BPTCCompressedTextureTest : public ANGLETest30{31protected:32BPTCCompressedTextureTest()33{34setWindowWidth(128);35setWindowHeight(128);36setConfigRedBits(8);37setConfigGreenBits(8);38setConfigBlueBits(8);39setConfigAlphaBits(8);40}4142void testSetUp() override43{44constexpr char kVS[] = R"(precision highp float;45attribute vec4 position;46varying vec2 texcoord;4748void main()49{50gl_Position = position;51texcoord = (position.xy * 0.5) + 0.5;52texcoord.y = 1.0 - texcoord.y;53})";5455constexpr char kFS[] = R"(precision highp float;56uniform sampler2D tex;57varying vec2 texcoord;5859void main()60{61gl_FragColor = texture2D(tex, texcoord);62})";6364mTextureProgram = CompileProgram(kVS, kFS);65if (mTextureProgram == 0)66{67FAIL() << "shader compilation failed.";68}6970mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex");7172ASSERT_GL_NO_ERROR();73}7475void testTearDown() override { glDeleteProgram(mTextureProgram); }7677void setupTextureParameters(GLuint texture)78{79glBindTexture(GL_TEXTURE_2D, texture);80glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);81glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);82glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);83glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);84}8586void drawTexture()87{88glUseProgram(mTextureProgram);89glUniform1i(mTextureUniformLocation, 0);90drawQuad(mTextureProgram, "position", 0.5f);91EXPECT_GL_NO_ERROR();92}9394GLuint mTextureProgram;95GLint mTextureUniformLocation;96};9798class BPTCCompressedTextureTestES3 : public BPTCCompressedTextureTest99{100public:101BPTCCompressedTextureTestES3() : BPTCCompressedTextureTest() {}102};103104// Test sampling from a BC7 non-SRGB image.105TEST_P(BPTCCompressedTextureTest, CompressedTexImageBC7)106{107ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));108109GLTexture texture;110setupTextureParameters(texture);111112glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4, 0,113kBC7Data4x4.size(), kBC7Data4x4.data());114115EXPECT_GL_NO_ERROR();116117drawTexture();118119EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::red, kPixelTolerance);120EXPECT_PIXEL_COLOR_NEAR(0, getWindowHeight() - 1, GLColor::red, kPixelTolerance);121EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, 0, GLColor::green, kPixelTolerance);122EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green,123kPixelTolerance);124}125126// Test sampling from a BC7 SRGB image.127TEST_P(BPTCCompressedTextureTest, CompressedTexImageBC7SRGB)128{129ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));130131GLTexture texture;132setupTextureParameters(texture);133134glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT, 4, 4, 0,135kBC7Data4x4.size(), kBC7Data4x4.data());136137EXPECT_GL_NO_ERROR();138139drawTexture();140141EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::red, kPixelTolerance);142EXPECT_PIXEL_COLOR_NEAR(0, getWindowHeight() - 1, GLColor::red, kPixelTolerance);143EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, 0, GLColor::green, kPixelTolerance);144EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green,145kPixelTolerance);146}147148// Test that using the BC6H floating point formats doesn't crash.149TEST_P(BPTCCompressedTextureTest, CompressedTexImageBC6HNoCrash)150{151ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));152153GLTexture texture;154setupTextureParameters(texture);155156// This fake pixel data represents a 4x4 pixel image.157// TODO(http://anglebug.com/2869): Add pixel tests for these formats. These need HDR source158// images.159std::vector<GLubyte> data;160data.resize(16u, 0u);161162glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT, 4, 4, 0,163data.size(), data.data());164glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT, 4, 4, 0,165data.size(), data.data());166167EXPECT_GL_NO_ERROR();168169drawTexture();170}171172// Test texStorage2D with a BPTC format.173TEST_P(BPTCCompressedTextureTestES3, CompressedTexStorage)174{175ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));176177ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);178179GLTexture texture;180setupTextureParameters(texture);181182glTexStorage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4);183EXPECT_GL_NO_ERROR();184glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT,185kBC7Data4x4.size(), kBC7Data4x4.data());186EXPECT_GL_NO_ERROR();187188drawTexture();189190EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::red, kPixelTolerance);191EXPECT_PIXEL_COLOR_NEAR(0, getWindowHeight() - 1, GLColor::red, kPixelTolerance);192EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, 0, GLColor::green, kPixelTolerance);193EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green,194kPixelTolerance);195}196197// Test validation of glCompressedTexSubImage2D with BPTC formats198TEST_P(BPTCCompressedTextureTest, CompressedTexSubImageValidation)199{200ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));201202GLTexture texture;203glBindTexture(GL_TEXTURE_2D, texture);204205std::vector<GLubyte> data(16 * 2 * 2); // 2x2 blocks, thats 8x8 pixels.206207// Size mip 0 to a large size.208glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 8, 8, 0,209data.size(), data.data());210ASSERT_GL_NO_ERROR();211212// Test a sub image with an offset that isn't a multiple of the block size.213glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 1, 0, 4, 4, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT,214kBC7Data4x4.size(), kBC7Data4x4.data());215ASSERT_GL_ERROR(GL_INVALID_OPERATION);216glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 3, 4, 4, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT,217kBC7Data4x4.size(), kBC7Data4x4.data());218ASSERT_GL_ERROR(GL_INVALID_OPERATION);219220// Test a sub image with a negative offset.221glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, -1, 0, 4, 4, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT,222kBC7Data4x4.size(), kBC7Data4x4.data());223ASSERT_GL_ERROR(GL_INVALID_VALUE);224glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, -1, 4, 4, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT,225kBC7Data4x4.size(), kBC7Data4x4.data());226ASSERT_GL_ERROR(GL_INVALID_VALUE);227}228229// Test that copying BPTC textures is not allowed. This restriction exists only in230// EXT_texture_compression_bptc, and not in the ARB variant.231TEST_P(BPTCCompressedTextureTest, CopyTexImage2DDisallowed)232{233ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));234235GLTexture texture;236setupTextureParameters(texture);237238glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 0, 0, 4, 4, 0);239ASSERT_GL_ERROR(GL_INVALID_OPERATION);240}241242// Test that copying BPTC textures is not allowed. This restriction exists only in243// EXT_texture_compression_bptc, and not in the ARB variant.244TEST_P(BPTCCompressedTextureTest, CopyTexSubImage2DDisallowed)245{246ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));247248GLTexture texture;249setupTextureParameters(texture);250251glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4, 0,252kBC7Data4x4.size(), kBC7Data4x4.data());253ASSERT_GL_NO_ERROR();254255glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 4, 4);256ASSERT_GL_ERROR(GL_INVALID_OPERATION);257}258259// Test that copying BPTC textures is not allowed. This restriction exists only in260// EXT_texture_compression_bptc, and not in the ARB variant.261TEST_P(BPTCCompressedTextureTestES3, CopyTexSubImage3DDisallowed)262{263ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));264265GLTexture texture;266glBindTexture(GL_TEXTURE_2D_ARRAY, texture);267268glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4, 1);269ASSERT_GL_NO_ERROR();270271glCopyTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, 0, 0, 4, 4);272ASSERT_GL_ERROR(GL_INVALID_OPERATION);273}274275// Test uploading texture data from a PBO to a texture.276TEST_P(BPTCCompressedTextureTestES3, PBOCompressedTexImage)277{278ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));279280GLTexture texture;281setupTextureParameters(texture);282283GLBuffer buffer;284glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);285glBufferData(GL_PIXEL_UNPACK_BUFFER, kBC7Data4x4.size(), kBC7Data4x4.data(), GL_STREAM_DRAW);286ASSERT_GL_NO_ERROR();287288glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4, 0,289kBC7Data4x4.size(), nullptr);290ASSERT_GL_NO_ERROR();291292drawTexture();293294EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::red, kPixelTolerance);295EXPECT_PIXEL_COLOR_NEAR(0, getWindowHeight() - 1, GLColor::red, kPixelTolerance);296EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, 0, GLColor::green, kPixelTolerance);297EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green,298kPixelTolerance);299300// Destroy the data301glBufferData(GL_PIXEL_UNPACK_BUFFER, kBC7BlackData4x4.size(), kBC7BlackData4x4.data(),302GL_STREAM_DRAW);303glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4, 0,304kBC7BlackData4x4.size(), nullptr);305ASSERT_GL_NO_ERROR();306307drawTexture();308EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);309310// Initialize again. This time, the texture's image is already allocated, so the PBO data311// upload could be directly done.312glBufferData(GL_PIXEL_UNPACK_BUFFER, kBC7Data4x4.size(), kBC7Data4x4.data(), GL_STREAM_DRAW);313glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4, 0,314kBC7Data4x4.size(), nullptr);315ASSERT_GL_NO_ERROR();316317drawTexture();318319EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::red, kPixelTolerance);320EXPECT_PIXEL_COLOR_NEAR(0, getWindowHeight() - 1, GLColor::red, kPixelTolerance);321EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, 0, GLColor::green, kPixelTolerance);322EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green,323kPixelTolerance);324}325326// Test uploading texture data from a PBO to a non-zero base texture.327TEST_P(BPTCCompressedTextureTestES3, PBOCompressedTexImageNonZeroBase)328{329ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));330331GLTexture texture;332setupTextureParameters(texture);333334GLBuffer buffer;335glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);336glBufferData(GL_PIXEL_UNPACK_BUFFER, kBC7Data4x4.size(), kBC7Data4x4.data(), GL_STREAM_DRAW);337ASSERT_GL_NO_ERROR();338339glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4, 0,340kBC7Data4x4.size(), nullptr);341glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);342ASSERT_GL_NO_ERROR();343344drawTexture();345346EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::red, kPixelTolerance);347EXPECT_PIXEL_COLOR_NEAR(0, getWindowHeight() - 1, GLColor::red, kPixelTolerance);348EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, 0, GLColor::green, kPixelTolerance);349EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green,350kPixelTolerance);351352// Destroy the data353glBufferData(GL_PIXEL_UNPACK_BUFFER, kBC7BlackData4x4.size(), kBC7BlackData4x4.data(),354GL_STREAM_DRAW);355glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4, 0,356kBC7BlackData4x4.size(), nullptr);357ASSERT_GL_NO_ERROR();358359drawTexture();360EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);361362// Initialize again. This time, the texture's image is already allocated, so the PBO data363// upload could be directly done.364glBufferData(GL_PIXEL_UNPACK_BUFFER, kBC7Data4x4.size(), kBC7Data4x4.data(), GL_STREAM_DRAW);365glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4, 0,366kBC7Data4x4.size(), nullptr);367ASSERT_GL_NO_ERROR();368369drawTexture();370371EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::red, kPixelTolerance);372EXPECT_PIXEL_COLOR_NEAR(0, getWindowHeight() - 1, GLColor::red, kPixelTolerance);373EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, 0, GLColor::green, kPixelTolerance);374EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green,375kPixelTolerance);376}377378// Test uploading texture data from a PBO to a texture allocated with texStorage2D.379TEST_P(BPTCCompressedTextureTestES3, PBOCompressedTexStorage)380{381ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));382383GLTexture texture;384setupTextureParameters(texture);385386glTexStorage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4);387ASSERT_GL_NO_ERROR();388389GLBuffer buffer;390glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);391glBufferData(GL_PIXEL_UNPACK_BUFFER, kBC7Data4x4.size(), kBC7Data4x4.data(), GL_STREAM_DRAW);392ASSERT_GL_NO_ERROR();393394glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT,395kBC7Data4x4.size(), nullptr);396397ASSERT_GL_NO_ERROR();398399drawTexture();400401EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::red, kPixelTolerance);402EXPECT_PIXEL_COLOR_NEAR(0, getWindowHeight() - 1, GLColor::red, kPixelTolerance);403EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, 0, GLColor::green, kPixelTolerance);404EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green,405kPixelTolerance);406}407408// Test validation of glCompressedTexSubImage3D with BPTC formats409TEST_P(BPTCCompressedTextureTestES3, CompressedTexSubImage3DValidation)410{411ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));412413GLTexture texture;414glBindTexture(GL_TEXTURE_2D_ARRAY, texture.get());415416std::vector<GLubyte> data(16 * 2 * 2); // 2x2x1 blocks, thats 8x8x1 pixels.417418// Size mip 0 to a large size.419glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 8, 8, 1, 0,420data.size(), data.data());421ASSERT_GL_NO_ERROR();422423// Test a sub image with an offset that isn't a multiple of the block size.424glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 2, 0, 0, 4, 4, 1,425GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, kBC7Data4x4.size(),426kBC7Data4x4.data());427ASSERT_GL_ERROR(GL_INVALID_OPERATION);428glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 2, 0, 4, 4, 1,429GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, kBC7Data4x4.size(),430kBC7Data4x4.data());431ASSERT_GL_ERROR(GL_INVALID_OPERATION);432433// Test a sub image with a negative offset.434glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, -1, 0, 0, 4, 4, 1,435GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, kBC7Data4x4.size(),436kBC7Data4x4.data());437ASSERT_GL_ERROR(GL_INVALID_VALUE);438glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, -1, 0, 4, 4, 1,439GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, kBC7Data4x4.size(),440kBC7Data4x4.data());441ASSERT_GL_ERROR(GL_INVALID_VALUE);442glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, -1, 4, 4, 1,443GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, kBC7Data4x4.size(),444kBC7Data4x4.data());445ASSERT_GL_ERROR(GL_INVALID_VALUE);446}447448// Use this to select which configurations (e.g. which renderer, which GLES major version) these449// tests should be run against.450ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(BPTCCompressedTextureTest);451452GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BPTCCompressedTextureTestES3);453ANGLE_INSTANTIATE_TEST_ES3(BPTCCompressedTextureTestES3);454455456