blob: 3909aa17e1a84233a85349cc18050e2f10636b49 [file] [log] [blame]
#ifndef _GL3CTEXTURESWIZZLETESTS_HPP
#define _GL3CTEXTURESWIZZLETESTS_HPP
/*-------------------------------------------------------------------------
* OpenGL Conformance Test Suite
* -----------------------------
*
* Copyright (c) 2015-2016 The Khronos Group Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/ /*!
* \file
* \brief
*/ /*-------------------------------------------------------------------*/
/**
* \file gl3cTextureSwizzleTests.hpp
* \brief Declares test classes for "Texture Swizzle" functionality.
*/ /*-------------------------------------------------------------------*/
#include "glcTestCase.hpp"
#include "glwDefs.hpp"
#include "glwEnums.hpp"
#include "tcuDefs.hpp"
#include "tcuVector.hpp"
#include <queue>
namespace gl3cts
{
namespace TextureSwizzle
{
class Utils
{
public:
/** Store information about program object
*
**/
struct programInfo
{
programInfo(deqp::Context& context);
~programInfo();
void build(const glw::GLchar* fragment_shader_code, const glw::GLchar* vertex_shader_code);
void compile(glw::GLuint shader_id, const glw::GLchar* shader_code) const;
void link() const;
deqp::Context& m_context;
glw::GLuint m_fragment_shader_id;
glw::GLuint m_program_object_id;
glw::GLuint m_vertex_shader_id;
};
/* Public static methods */
static void replaceToken(const glw::GLchar* token, size_t& search_position, const glw::GLchar* text,
std::string& string);
};
/** Implements APIErrors test, description follows:
*
* Verifies that errors are generated as expected.
*
* Check if:
* - INVALID_OPERATION is generated by TexParameter* routines when <pname> is
* one of [TEXTURE_SWIZZLE_R, TEXTURE_SWIZZLE_G, TEXTURE_SWIZZLE_B,
* TEXTURE_SWIZZLE_A] and <param> is not one of [RED, GREEN, BLUE, ALPHA, ZERO,
* ONE];
* - INVALID_OPERATION is generated by TexParameter*v routines when <pname> is
* TEXTURE_SWIZZLE_RGBA and any of four values pointed by <param> is not one of
* [RED, GREEN, BLUE, ALPHA, ZERO, ONE].
**/
class APIErrorsTest : public deqp::TestCase
{
public:
/* Public methods */
APIErrorsTest(deqp::Context& context);
virtual void deinit();
virtual tcu::TestNode::IterateResult iterate();
private:
/* Private methods */
void verifyError(const glw::GLenum expected_error);
/* Private fields */
glw::GLuint m_id;
};
/** Implements IntialState test, description follows:
*
* Verifies that intial state is as expected.
*
* Steps:
* - create a texture;
* - verify that query for TEXTURE_SWIZZLE_R results with RED;
* - verify that query for TEXTURE_SWIZZLE_G results with GREEN;
* - verify that query for TEXTURE_SWIZZLE_B results with BLUE;
* - verify that query for TEXTURE_SWIZZLE_A results with ALPHA;
* - verify that query for TEXTURE_SWIZZLE_RGBA results with [RED, GREEN, BLUE,
* ALPHA].
*
* Use GetTexParameter to query states. If GL_ARB_direct_state_access is
* supported than repeat the steps with GetTextureParameter.
* Repeat the steps for all supported texture targets.
**/
class IntialStateTest : public deqp::TestCase
{
public:
/* Public methods */
IntialStateTest(deqp::Context& context);
virtual void deinit();
virtual tcu::TestNode::IterateResult iterate();
private:
/* Private methods */
void verifyValues(const glw::GLenum texture_target);
/* Private fields */
glw::GLuint m_id;
};
/** Implements Smoke test, description follows:
*
* Verifies that all swizzle combinations work with all texture access
* routines.
*
* Steps:
* - prepare a source texture so that each channel is filled with specific
* value;
* - for each TEXTURE_SWIZZLE state combination:
* * for each channel [R, G, B, A]:
* + prepare a 2D single channeled texture with format matching sampled
* channel and set it up as output color in framebuffer;
* + prepare a program that will implement the following snippet in vertex
* stage and output the value of result:
*
* result = texture(source).C;
*
* + set swizzle states with channel specific enums;
* + draw a full-screen quad;
* + verify that the output texture is filled with correct value;
* + set swizzle states with RGBA enum;
* + draw a full-screen quad;
* + verify that the output texture is filled with correct value;
* + prepare a program that will implement the following snippet in
* fragment stage and output the value of result:
*
* result = texture(source).C;
*
* + set swizzle states with channel specific enums;
* + draw a full-screen quad;
* + verify that the output texture is filled with correct value;
* + set swizzle states with RGBA enum;
* + draw a full-screen quad;
* + verify that the output texture is filled with correct value.
*
* Value is correct when:
* - it matches value assigned to the specified channel;
* - it is one for missing alpha channel;
* - it is zero for missing channel;
* - it is one for ONE;
* - it is zero for ZERO.
*
* Before any draw output texture should be cleared.
* Source texture should be RGBA32UI 2D_ARRAY 1x1 of length 1 with
* single mipmap at level 0.
* Dimenssions of destination texture should be 8x8.
* Repeat the steps for the following texture access routines:
* - textureProj,
* - textureLod,
* - textureOffset,
* - texelFetch,
* - texelFetchOffset,
* - textureProjOffset,
* - textureLodOffset,
* - textureProjLod,
* - textureProjLodOffset,
* - textureGrad,
* - textureGradOffset,
* - textureProjGrad,
* - textureProjGradOffset.
**/
class SmokeTest : public deqp::TestCase
{
public:
/* Public methods */
SmokeTest(deqp::Context& context);
SmokeTest(deqp::Context& context, const glw::GLchar* name, const glw::GLchar* description);
virtual void deinit();
virtual tcu::TestNode::IterateResult iterate();
protected:
/* Protected types */
struct testCase
{
size_t m_channel_index;
size_t m_source_texture_format_index;
size_t m_source_texture_target_index;
size_t m_texture_access_index;
glw::GLint m_texture_swizzle_red;
glw::GLint m_texture_swizzle_green;
glw::GLint m_texture_swizzle_blue;
glw::GLint m_texture_swizzle_alpha;
glw::GLint m_texture_sizes[4];
};
/* Protected methods */
void captureAndVerify(const testCase& test_case, size_t output_format_index, glw::GLint output_channel_size,
size_t index_of_swizzled_channel);
void deinitOutputTexture();
void deinitTextures();
void draw(glw::GLenum target, const glw::GLint* texture_swizzle, bool use_rgba_enum);
void executeTestCase(const testCase& test_case);
virtual bool fillSourceTexture(size_t format_idx, size_t target_idx);
std::string getFragmentShader(const testCase& test_case, size_t output_format_index, bool is_tested_stage);
std::string getVertexShader(const testCase& test_case, bool is_tested_stage);
bool isTargetSupported(size_t target_idx);
bool isTargetSuppByAccess(size_t access_idx, size_t target_idx);
bool isTargetSuppByFormat(size_t format_idx, size_t target_idx);
void logTestCaseDetials(const testCase& test_case);
void prepareAndTestProgram(const testCase& test_case, size_t output_format_index, glw::GLint output_channel_size,
size_t index_of_swizzled_channel, bool test_vertex_stage);
std::string prepareArguments(const testCase& test_case);
std::string prepareCoordinates(const testCase& test_case);
std::string prepareDerivatives(const testCase& test_case, size_t index);
std::string prepareOffsets(const testCase& test_case);
void prepareOutputTexture(size_t format_idx);
std::string prepareSample();
void prepareSourceTexture(size_t format_idx, size_t target_idx, glw::GLint out_sizes[4]);
void testInit();
virtual void verifyOutputImage(const testCase& test_case, size_t output_format_index,
glw::GLint output_channel_size, size_t index_of_swizzled_channel,
const glw::GLubyte* data);
/* Protected fields */
bool m_is_ms_supported;
glw::GLuint m_prepare_fbo_id;
glw::GLuint m_out_tex_id;
glw::GLuint m_source_tex_id;
glw::GLuint m_test_fbo_id;
glw::GLuint m_vao_id;
/* Protected constants */
static const glw::GLsizei m_depth;
static const glw::GLsizei m_height;
static const glw::GLsizei m_width;
static const glw::GLsizei m_output_height;
static const glw::GLsizei m_output_width;
};
/** Implements Functional test, description follows:
*
* Verifies that swizzle is respected for textures of different formats and
* targets.
*
* Modify Smoke in the following aspects:
* - repeat the steps for all supported sized internal formats and
* texture targets;
* - repeat the steps for the texture_swizzle combinations listed below;
* - use only texelFetch routine.
*
* List of texture_swizzle combinations to test:
* - ABGR,
* - 01RA,
* - 0000,
* - 1111,
* - BBBB.
*
* Depth-stencil textures can be sampled only via RED channel. Test should set
* DEPTH_STENCIL_TEXTURE_MODE to select which channel will be accessed.
*
* For multisampled targets maximum supported number of samples should be used
* and fetch should be done to last sample.
*
* Support of multisampled targets by TexParameter* routines was introduced in
* extension GL_ARB_texture_storage_multisample, which is part of core
* specification since 4.3. Therefore texture_swizzle functionality may be used
* with multisampled targets only if either context is at least 4.3 or
* extension GL_ARB_texture_storage_multisample is supported.
**/
class FunctionalTest : public SmokeTest
{
public:
/* Public methods */
FunctionalTest(deqp::Context& context);
virtual tcu::TestNode::IterateResult iterate();
protected:
/* Protected methods */
virtual bool fillSourceTexture(size_t format_idx, size_t target_idx);
bool fillMSTexture(size_t format_idx, size_t target_idx);
void prepareProgram(size_t format_idx, Utils::programInfo& program);
std::string prepareValues(size_t format_idx);
virtual void verifyOutputImage(const testCase& test_case, size_t output_format_index,
glw::GLint output_channel_size, size_t index_of_swizzled_channel,
const glw::GLubyte* data);
private:
/* Private types */
class wrongResults : public std::exception
{
public:
wrongResults(const FunctionalTest::testCase& test_case) : m_test_case(test_case)
{
}
virtual ~wrongResults() throw()
{
}
virtual const char* what() const throw()
{
return "Found pixel with wrong value";
}
FunctionalTest::testCase m_test_case;
};
};
}
/** Group class for GPU Shader 5 conformance tests */
class TextureSwizzleTests : public deqp::TestCaseGroup
{
public:
/* Public methods */
TextureSwizzleTests(deqp::Context& context);
virtual ~TextureSwizzleTests()
{
}
virtual void init(void);
private:
/* Private methods */
TextureSwizzleTests(const TextureSwizzleTests&);
TextureSwizzleTests& operator=(const TextureSwizzleTests&);
};
} /* gl3cts namespace */
#endif // _GL3CTEXTURESWIZZLETESTS_HPP