#include "glcRobustBufferAccessBehaviorTests.hpp"
+#include "deSharedPtr.hpp"
#include "gluContextInfo.hpp"
#include "gluDefs.hpp"
#include "gluShaderUtil.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
+#include "tcuCommandLine.hpp"
+#include "tcuStringTemplate.hpp"
#include "tcuTestLog.hpp"
#include <cstring>
using namespace glw;
-namespace deqp
+namespace glcts
{
namespace RobustBufferAccessBehavior
{
*
* @param context CTS context.
**/
-Buffer::Buffer(deqp::Context& context) : m_id(m_invalid_id), m_context(context), m_target(GL_ARRAY_BUFFER)
+Buffer::Buffer(const glw::Functions& gl) : m_id(m_invalid_id), m_gl(gl), m_target(GL_ARRAY_BUFFER)
{
}
m_target = target;
- const Functions& gl = m_context.getRenderContext().getFunctions();
-
- Generate(gl, m_id);
- Bind(gl, m_id, m_target);
- Data(gl, m_target, usage, size, data);
+ Generate(m_gl, m_id);
+ Bind(m_gl, m_id, m_target);
+ Data(m_gl, m_target, usage, size, data);
}
/** Release buffer instance
{
if (m_invalid_id != m_id)
{
- const Functions& gl = m_context.getRenderContext().getFunctions();
-
- gl.deleteBuffers(1, &m_id);
+ m_gl.deleteBuffers(1, &m_id);
m_id = m_invalid_id;
}
}
**/
void Buffer::Bind() const
{
- const Functions& gl = m_context.getRenderContext().getFunctions();
-
- Bind(gl, m_id, m_target);
+ Bind(m_gl, m_id, m_target);
}
/** Binds indexed buffer
**/
void Buffer::BindBase(glw::GLuint index) const
{
- const Functions& gl = m_context.getRenderContext().getFunctions();
-
- BindBase(gl, m_id, m_target, index);
+ BindBase(m_gl, m_id, m_target, index);
}
/** Bind buffer to given target
*
* @param context CTS context.
**/
-Framebuffer::Framebuffer(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
+Framebuffer::Framebuffer(const glw::Functions& gl) : m_id(m_invalid_id), m_gl(gl)
{
/* Nothing to done here */
}
{
if (m_invalid_id != m_id)
{
- const Functions& gl = m_context.getRenderContext().getFunctions();
-
- gl.deleteFramebuffers(1, &m_id);
+ m_gl.deleteFramebuffers(1, &m_id);
m_id = m_invalid_id;
}
}
*
* @param context CTS context.
**/
-Program::Program(deqp::Context& context)
+Program::Program(const glw::Functions& gl)
: m_id(m_invalid_id)
- , m_compute(context)
- , m_fragment(context)
- , m_geometry(context)
- , m_tess_ctrl(context)
- , m_tess_eval(context)
- , m_vertex(context)
- , m_context(context)
+ , m_compute(gl)
+ , m_fragment(gl)
+ , m_geometry(gl)
+ , m_tess_ctrl(gl)
+ , m_tess_eval(gl)
+ , m_vertex(gl)
+ , m_gl(gl)
{
/* Nothing to be done here */
}
/* Delete previous program */
Release();
- /* GL entry points */
- const Functions& gl = m_context.getRenderContext().getFunctions();
-
/* Initialize shaders */
m_compute.Init(GL_COMPUTE_SHADER, compute_shader);
m_fragment.Init(GL_FRAGMENT_SHADER, fragment_shader);
m_vertex.Init(GL_VERTEX_SHADER, vertex_shader);
/* Create program, set up transform feedback and attach shaders */
- Create(gl, m_id);
- Attach(gl, m_id, m_compute.m_id);
- Attach(gl, m_id, m_fragment.m_id);
- Attach(gl, m_id, m_geometry.m_id);
- Attach(gl, m_id, m_tess_ctrl.m_id);
- Attach(gl, m_id, m_tess_eval.m_id);
- Attach(gl, m_id, m_vertex.m_id);
+ Create(m_gl, m_id);
+ Attach(m_gl, m_id, m_compute.m_id);
+ Attach(m_gl, m_id, m_fragment.m_id);
+ Attach(m_gl, m_id, m_geometry.m_id);
+ Attach(m_gl, m_id, m_tess_ctrl.m_id);
+ Attach(m_gl, m_id, m_tess_eval.m_id);
+ Attach(m_gl, m_id, m_vertex.m_id);
/* Link program */
- Link(gl, m_id);
+ Link(m_gl, m_id);
}
/** Release program instance
**/
void Program::Release()
{
- const Functions& gl = m_context.getRenderContext().getFunctions();
-
if (m_invalid_id != m_id)
{
- Use(gl, m_invalid_id);
+ Use(m_gl, m_invalid_id);
- gl.deleteProgram(m_id);
+ m_gl.deleteProgram(m_id);
m_id = m_invalid_id;
}
**/
void Program::Use() const
{
- const Functions& gl = m_context.getRenderContext().getFunctions();
-
- Use(gl, m_id);
+ Use(m_gl, m_id);
}
/** Attach shader to program
*
* @param context CTS context.
**/
-Shader::Shader(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
+Shader::Shader(const glw::Functions& gl) : m_id(m_invalid_id), m_gl(gl)
{
/* Nothing to be done here */
}
/* Delete any previous shader */
Release();
- /* Create, set source and compile */
- const Functions& gl = m_context.getRenderContext().getFunctions();
+ Create(m_gl, stage, m_id);
+ Source(m_gl, m_id, source);
- Create(gl, stage, m_id);
- Source(gl, m_id, source);
-
- Compile(gl, m_id);
+ Compile(m_gl, m_id);
}
/** Release shader instance
{
if (m_invalid_id != m_id)
{
- const Functions& gl = m_context.getRenderContext().getFunctions();
-
- gl.deleteShader(m_id);
+ m_gl.deleteShader(m_id);
m_id = m_invalid_id;
}
}
*
* @param context CTS context.
**/
-Texture::Texture(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
+Texture::Texture(const glw::Functions& gl) : m_id(m_invalid_id), m_gl(gl)
{
/* Nothing to done here */
}
{
if (m_invalid_id != m_id)
{
- const Functions& gl = m_context.getRenderContext().getFunctions();
-
- gl.deleteTextures(1, &m_id);
+ m_gl.deleteTextures(1, &m_id);
m_id = m_invalid_id;
}
}
*
* @param context CTS context.
**/
-VertexArray::VertexArray(deqp::Context& context) : m_id(m_invalid_id), m_context(context)
+VertexArray::VertexArray(const glw::Functions& gl) : m_id(m_invalid_id), m_gl(gl)
{
}
{
if (m_invalid_id != m_id)
{
- const Functions& gl = m_context.getRenderContext().getFunctions();
+ Bind(m_gl, 0);
- Bind(gl, 0);
-
- gl.deleteVertexArrays(1, &m_id);
+ m_gl.deleteVertexArrays(1, &m_id);
m_id = m_invalid_id;
}
out_id = id;
}
-/** Replace first occurance of <token> with <text> in <string> starting at <search_posistion>
- *
- * @param token Token string
- * @param search_position Position at which find will start, it is updated to position at which replaced text ends
- * @param text String that will be used as replacement for <token>
- * @param string String to work on
- **/
-void replaceToken(const GLchar* token, size_t& search_position, const GLchar* text, std::string& string)
+template <typename TYPE>
+void initPixels(std::vector<TYPE>& pixels, GLuint n_pixels, GLuint n_channels)
{
- const size_t text_length = strlen(text);
- const size_t token_length = strlen(token);
- const size_t token_position = string.find(token, search_position);
-
- string.replace(token_position, token_length, text, text_length);
+ if (n_channels == 1)
+ {
+ for (GLuint i = 0; i < n_pixels; ++i)
+ pixels[i] = static_cast<TYPE>(i);
+ }
+ else if (n_channels == 2)
+ {
+ for (GLuint i = 0; i < n_pixels; ++i)
+ {
+ GLuint idx = i * 2;
+ pixels[idx] = static_cast<TYPE>(i);
+ pixels[idx + 1] = pixels[idx];
+ }
+ }
+ else if (n_channels == 4)
+ {
+ for (GLuint i = 0; i < n_pixels; ++i)
+ {
+ GLuint idx = i * 4;
+ pixels[idx] = static_cast<TYPE>(i);
+ pixels[idx + 1] = pixels[idx];
+ pixels[idx + 2] = pixels[idx];
+ pixels[idx + 3] = pixels[idx];
+ }
+ }
+ else
+ TCU_FAIL("Unsuported number of channels");
+}
- search_position = token_position + text_length;
+RobustnessBase::RobustnessBase(tcu::TestContext& testCtx, const char* name, const char* description,
+ glu::ApiType apiType)
+ : tcu::TestCase(testCtx, name, description), m_api_type(apiType), m_has_khr_robust_buffer_access(false)
+{
}
-bool isRobustBufferAccessBehaviorFeatureSupported(deqp::Context& context)
+glu::RenderContext* RobustnessBase::createRobustContext(glu::ResetNotificationStrategy reset)
{
- glu::ContextType context_type = context.getRenderContext().getType();
- if (context.getContextInfo().isExtensionSupported("GL_KHR_robust_buffer_access_behavior") ||
- context.getContextInfo().isExtensionSupported("GL_ARB_robust_buffer_access_behavior") ||
- contextSupports(context_type, glu::ApiType::core(4, 3)))
+ // Create test context to verify if required extensions are available
{
- return true;
+ deqp::Context context(m_testCtx, glu::ContextType(m_api_type));
+ const glu::ContextInfo& contextInfo = context.getContextInfo();
+ glu::ContextType context_type = context.getRenderContext().getType();
+ if (!contextInfo.isExtensionSupported("GL_KHR_robustness") &&
+ !contextSupports(context_type, glu::ApiType::es(3, 2)))
+ {
+ m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "GL_KHR_robustness extension not supported");
+ return NULL;
+ }
+
+ m_has_khr_robust_buffer_access = contextInfo.isExtensionSupported("GL_KHR_robust_buffer_access_behavior") ||
+ contextInfo.isExtensionSupported("GL_ARB_robust_buffer_access_behavior") ||
+ contextSupports(context_type, glu::ApiType::core(4, 5));
+ if (!m_has_khr_robust_buffer_access && !contextSupports(context_type, glu::ApiType::core(4, 3)))
+ {
+ m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED,
+ "robust_buffer_access_behavior extension not supported");
+ return NULL;
+ }
+
+ glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(context_type);
+ m_specializationMap["VERSION"] = glu::getGLSLVersionDeclaration(glslVersion);
+ m_context_is_es = glu::isContextTypeES(context_type);
}
- context.getTestContext().setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
- return false;
-}
-/** Constructor
- *
- * @param context Test context
- **/
-VertexBufferObjectsTest::VertexBufferObjectsTest(deqp::Context& context)
- : TestCase(context, "vertex_buffer_objects", "Verifies that out-of-bound reads from VB result in zero")
-{
- /* Nothing to be done */
+ glu::RenderConfig renderCfg(glu::ContextType(m_api_type, glu::CONTEXT_ROBUST));
+ const tcu::CommandLine& commandLine = m_testCtx.getCommandLine();
+ glu::parseRenderConfig(&renderCfg, commandLine);
+
+ if (commandLine.getSurfaceType() == tcu::SURFACETYPE_WINDOW)
+ renderCfg.resetNotificationStrategy = reset;
+ else
+ throw tcu::NotSupportedError("Test not supported in non-windowed context");
+
+ /* Try to create core/es robusness context */
+ return createRenderContext(m_testCtx.getPlatform(), commandLine, renderCfg);
}
/** Constructor
*
- * @param context Test context
+ * @param testCtx Test context
**/
-VertexBufferObjectsTest::VertexBufferObjectsTest(deqp::Context& context, const char* name, const char* description)
- : TestCase(context, name, description)
+VertexBufferObjectsTest::VertexBufferObjectsTest(tcu::TestContext& testCtx, glu::ApiType apiType)
+ : RobustnessBase(testCtx, "vertex_buffer_objects", "Verifies that out-of-bound reads from VB result in zero",
+ apiType)
{
/* Nothing to be done */
}
**/
tcu::TestNode::IterateResult VertexBufferObjectsTest::iterate()
{
- if (!isRobustBufferAccessBehaviorFeatureSupported(m_context))
+ de::SharedPtr<glu::RenderContext> robustContext(createRobustContext());
+ if (!robustContext.get())
return STOP;
static const GLuint invalid_elements[] = {
static const GLuint width = 8;
/* GL entry points */
- const Functions& gl = m_context.getRenderContext().getFunctions();
+ const Functions& gl = robustContext->getFunctions();
/* Test case objects */
- Framebuffer framebuffer(m_context);
- Program program(m_context);
- Texture texture(m_context);
- Buffer elements_buffer(m_context);
- Buffer vertices_buffer(m_context);
- VertexArray vao(m_context);
+ Framebuffer framebuffer(gl);
+ Program program(gl);
+ Texture texture(gl);
+ Buffer elements_buffer(gl);
+ Buffer vertices_buffer(gl);
+ VertexArray vao(gl);
/* Vertex array */
VertexArray::Generate(gl, vao.m_id);
/* Binding elements/indices buffer */
elements_buffer.Bind();
- cleanTexture(texture.m_id);
+ cleanTexture(gl, texture.m_id);
gl.drawElements(GL_TRIANGLES, n_vertices, GL_UNSIGNED_INT, 0 /* indices */);
GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElements");
- if (false == verifyValidResults(texture.m_id))
+ if (false == verifyValidResults(gl, texture.m_id))
{
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid result for valid input"
- << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Invalid result for valid input" << tcu::TestLog::EndMessage;
- m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+ m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
return tcu::TestNode::STOP;
}
invalid_elements_set[buffer_index]);
elements_buffer.Bind();
- cleanTexture(texture.m_id);
+ cleanTexture(gl, texture.m_id);
gl.drawElements(GL_TRIANGLES, n_vertices, GL_UNSIGNED_INT, 0 /* indices */);
GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElements");
- if (false == verifyInvalidResults(texture.m_id))
+ if (false == verifyInvalidResults(gl, texture.m_id))
{
- m_context.getTestContext().getLog()
- << tcu::TestLog::Message << "Invalid result for invalid input" << tcu::TestLog::EndMessage;
- m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+ m_testCtx.getLog() << tcu::TestLog::Message << "Invalid result for invalid input"
+ << tcu::TestLog::EndMessage;
+ m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
return tcu::TestNode::STOP;
}
}
/* Done */
- m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
+ m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
return tcu::TestNode::STOP;
}
**/
std::string VertexBufferObjectsTest::getFragmentShader()
{
- return std::string("#version 430 core\n"
- "\n"
- "layout (location = 0) out vec4 out_fs_color;\n"
- "\n"
- "void main()\n"
- "{\n"
- " out_fs_color = vec4(1.0 / 256.0, 1.0, 1.0, 1.0);\n"
- "}\n"
- "\n");
+ const char* source = "${VERSION}\n"
+ "layout (location = 0) out lowp uvec4 out_fs_color;\n"
+ "void main()\n"
+ "{\n"
+ " out_fs_color = uvec4(1, 255, 255, 255);\n"
+ "}\n";
+ return tcu::StringTemplate(source).specialize(m_specializationMap);
}
/** Prepare shader for current test case
**/
std::string VertexBufferObjectsTest::getVertexShader()
{
- return std::string("#version 430 core\n"
- "\n"
- "layout (location = 0) in vec4 in_vs_position;\n"
- "\n"
- "void main()\n"
- "{\n"
- " gl_Position = in_vs_position;\n"
- "}\n"
- "\n");
+ const char* source = "${VERSION}\n"
+ "layout (location = 0) in vec4 in_vs_position;\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = in_vs_position;\n"
+ "}\n";
+
+ return tcu::StringTemplate(source).specialize(m_specializationMap);
}
/** Fill texture with value 128
*
* @param texture_id Id of texture
**/
-void VertexBufferObjectsTest::cleanTexture(glw::GLuint texture_id)
+void VertexBufferObjectsTest::cleanTexture(const Functions& gl, glw::GLuint texture_id)
{
static const GLuint height = 8;
static const GLuint width = 8;
- const Functions& gl = m_context.getRenderContext().getFunctions();
-
GLubyte pixels[width * height];
for (GLuint i = 0; i < width * height; ++i)
{
*
* @return false when image is filled with 1, true otherwise
**/
-bool VertexBufferObjectsTest::verifyInvalidResults(glw::GLuint texture_id)
+bool VertexBufferObjectsTest::verifyInvalidResults(const Functions& gl, glw::GLuint texture_id)
{
- return !verifyResults(texture_id);
+ // In OpenGL ES there is undefined out-of-bound behavior - no verification
+ if (m_context_is_es)
+ return true;
+ return !verifyResults(gl, texture_id);
}
/** Verifies that texutre is filled with 1
*
* @return true when image is filled with 1, false otherwise
**/
-bool VertexBufferObjectsTest::verifyValidResults(glw::GLuint texture_id)
+bool VertexBufferObjectsTest::verifyValidResults(const Functions& gl, glw::GLuint texture_id)
{
- return verifyResults(texture_id);
+ return verifyResults(gl, texture_id);
}
/** Verifies that texutre is filled with 1
*
* @return true when image is filled with 1, false otherwise
**/
-bool VertexBufferObjectsTest::verifyResults(glw::GLuint texture_id)
+bool VertexBufferObjectsTest::verifyResults(const Functions& gl, glw::GLuint texture_id)
{
static const GLuint height = 8;
static const GLuint width = 8;
+ GLuint pixel_size = 4 * sizeof(GLuint);
+ GLuint expected_value = 1;
- const Functions& gl = m_context.getRenderContext().getFunctions();
-
- GLubyte pixels[width * height];
- for (GLuint i = 0; i < width * height; ++i)
- {
- pixels[i] = 0;
- }
-
+ std::vector<GLubyte> pixels(width * height * pixel_size, 0);
Texture::Bind(gl, texture_id, GL_TEXTURE_2D);
-
- Texture::GetData(gl, 0 /* level */, GL_TEXTURE_2D, GL_RED_INTEGER, GL_UNSIGNED_BYTE, pixels);
-
- /* Unbind */
+ Texture::GetData(gl, texture_id, 0 /* level */, width, height, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &pixels[0]);
Texture::Bind(gl, 0, GL_TEXTURE_2D);
/* Verify */
- for (GLuint i = 0; i < width * height; ++i)
+ for (GLuint i = 0; i < pixels.size(); i += pixel_size)
{
- if (255 != pixels[i])
+ if (expected_value != pixels[i])
return false;
}
/** Constructor
*
- * @param context Test context
+ * @param testCtx Test context
**/
-TexelFetchTest::TexelFetchTest(deqp::Context& context)
- : TestCase(context, "texel_fetch", "Verifies that out-of-bound fetches from texture result in zero")
+TexelFetchTest::TexelFetchTest(tcu::TestContext& testCtx, glu::ApiType apiType)
+ : RobustnessBase(testCtx, "texel_fetch", "Verifies that out-of-bound fetches from texture result in zero", apiType)
, m_test_case(R8)
{
/* Nothing to be done */
/** Constructor
*
- * @param context Test context
+ * @param testCtx Test context
+ * @param name Test name
+ * @param description Test description
+ * @param apiType Api type
**/
-TexelFetchTest::TexelFetchTest(deqp::Context& context, const glw::GLchar* name, const glw::GLchar* description)
- : TestCase(context, name, description), m_test_case(R8)
+TexelFetchTest::TexelFetchTest(tcu::TestContext& testCtx, const char* name, const char* description,
+ glu::ApiType apiType)
+ : RobustnessBase(testCtx, name, description, apiType), m_test_case(R8)
{
/* Nothing to be done */
}
**/
tcu::TestNode::IterateResult TexelFetchTest::iterate()
{
- if (!isRobustBufferAccessBehaviorFeatureSupported(m_context))
+ de::SharedPtr<glu::RenderContext> robustContext(createRobustContext());
+ if (!robustContext.get())
return STOP;
/* Constants */
static const GLuint width = 16;
/* GL entry points */
- const Functions& gl = m_context.getRenderContext().getFunctions();
+ const Functions& gl = robustContext->getFunctions();
/* Test result indicator */
bool test_result = true;
1008, // high fetch
};
GLuint fetch_offsets_count = sizeof(invalid_fetch_offsets) / sizeof(GLuint);
+ glu::ContextType contextType = robustContext->getType();
/* Iterate over all cases */
for (; m_test_case < LAST; m_test_case = (TEST_CASES)((GLuint)m_test_case + 1))
}
/* */
- Texture destination_texture(m_context);
- Framebuffer framebuffer(m_context);
- Texture source_texture(m_context);
- Program program(m_context);
- VertexArray vao(m_context);
+ Texture destination_texture(gl);
+ Framebuffer framebuffer(gl);
+ Texture source_texture(gl);
+ Program program(gl);
+ VertexArray vao(gl);
/* Prepare VAO */
VertexArray::Generate(gl, vao.m_id);
* to upload the texture so max_image_samples >= 4
* is also required.
*/
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case: " << getTestCaseName()
- << " not supported" << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Test case: " << getTestCaseName() << " not supported"
+ << tcu::TestLog::EndMessage;
continue;
}
}
- prepareTexture(false, destination_texture.m_id);
- prepareTexture(true, source_texture.m_id);
+ prepareTexture(gl, false, destination_texture.m_id);
+ prepareTexture(gl, true, source_texture.m_id);
/* Select FBO settings */
if (R32UI_MIPMAP == m_test_case)
width, height);
/* Prepare valid program */
- program.Init("" /* cs */, getFragmentShader(true), getGeometryShader(), "" /* tcs */, "" /* tes */,
+ program.Init("" /* cs */, getFragmentShader(contextType, true), getGeometryShader(), "" /* tcs */, "" /* tes */,
getVertexShader());
/* Test valid case */
GLU_EXPECT_NO_ERROR(gl.getError(), "CheckFramebufferStatus");
if (GL_FRAMEBUFFER_COMPLETE != fbo_status)
{
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case: " << getTestCaseName()
- << " not supported" << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Test case: " << getTestCaseName() << " not supported"
+ << tcu::TestLog::EndMessage;
continue;
}
}
/* Verification */
- if (false == verifyValidResults(destination_texture.m_id))
+ if (false == verifyValidResults(gl, destination_texture.m_id))
{
test_result = false;
}
for (GLuint index = 0; index < fetch_offsets_count; ++index)
{
/* Prepare invalid program */
- program.Init("" /* cs */, getFragmentShader(false, invalid_fetch_offsets[index]), getGeometryShader(),
- "" /* tcs */, "" /* tes */, getVertexShader());
+ program.Init("" /* cs */, getFragmentShader(contextType, false, invalid_fetch_offsets[index]),
+ getGeometryShader(), "" /* tcs */, "" /* tes */, getVertexShader());
Program::Use(gl, program.m_id);
+ Framebuffer::Bind(gl, GL_DRAW_FRAMEBUFFER, framebuffer.m_id);
/* Set texture */
gl.activeTexture(GL_TEXTURE0); /* location = 0 */
GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
/* Draw */
+ gl.clear(GL_COLOR_BUFFER_BIT);
gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays");
/* Verification */
- if (false == verifyInvalidResults(destination_texture.m_id))
+ if (false == verifyInvalidResults(gl, destination_texture.m_id))
{
test_result = false;
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case: " << getTestCaseName()
- << " failed" << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Test case: " << getTestCaseName() << " failed for "
+ << invalid_fetch_offsets[index] << " offset" << tcu::TestLog::EndMessage;
}
}
}
/* Set result */
if (true == test_result)
{
- m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
+ m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
}
else
{
- m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+ m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
}
/* Done */
*
* @return string with prepared code
**/
-std::string TexelFetchTest::getFragmentShader(bool is_case_valid, GLuint fetch_offset)
+std::string TexelFetchTest::getFragmentShader(const glu::ContextType&, bool is_case_valid, GLuint fetch_offset)
{
- static const GLchar* plane_0 = " int plane = 0;\n";
-
- static const GLchar* plane_1 = " int plane = 1;\n";
-
- static const GLchar* plane_2 = " int plane = 2;\n";
-
- static const GLchar* plane_sample_invalid = " int plane = 9;\n";
- //" int plane = gl_SampleID + 4;\n";
+ const GLchar* source = "${VERSION}\n"
+ "in lowp vec2 gs_fs_tex_coord;\n"
+ "layout (location = 0) out lowp ${TYPE} out_fs_color;\n"
+ "layout (location = 0) uniform lowp ${SAMPLER} uni_texture;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " ivec2 point = ivec2(gs_fs_tex_coord * 16.0 + float(${OFFSET}));\n"
+ " out_fs_color = texelFetch(uni_texture, point, ${PLANE});\n"
+ "}\n";
- static const GLchar* plane_sample_valid = " int plane = gl_SampleID;\n";
-
- static const GLchar* sampler_regular = "sampler2D";
- static const GLchar* sampler_regular_u = "usampler2D";
- static const GLchar* sampler_multisampled_u = "usampler2DMS";
-
- static const GLchar* template_code = "VERSION"
- "\n"
- " in lowp vec2 gs_fs_tex_coord;\n"
- "layout (location = 0) out lowp TYPE out_fs_color;\n"
- "layout (location = 0) uniform lowp SAMPLER uni_texture;\n"
- "\n"
- "void main()\n"
- "{\n"
- "PLANE\n"
- " ivec2 point = ivec2(gs_fs_tex_coord * 16.0) + ivec2(OFFSET);\n"
- " out_fs_color = texelFetch(uni_texture, point, plane);\n"
- "}\n"
- "\n";
-
- static const GLchar* type_vec4 = "vec4";
- static const GLchar* type_uvec4 = "uvec4";
-
- const GLchar* plane = plane_0;
- const GLchar* sampler = sampler_regular;
- const GLchar* type = type_vec4;
+ m_specializationMap["PLANE"] = "0";
+ m_specializationMap["SAMPLER"] = "sampler2D";
+ m_specializationMap["TYPE"] = "vec4";
if (R32UI_MIPMAP == m_test_case)
{
- plane = plane_1;
- sampler = sampler_regular_u;
- type = type_uvec4;
+ m_specializationMap["PLANE"] = "1";
+ m_specializationMap["SAMPLER"] = "usampler2D";
+ m_specializationMap["TYPE"] = "uvec4";
if (false == is_case_valid)
{
fetch_offset = 0;
- plane = plane_2;
+ m_specializationMap["PLANE"] = "2";
}
}
else if (R32UI_MULTISAMPLE == m_test_case)
{
- plane = plane_sample_valid;
- sampler = sampler_multisampled_u;
- type = type_uvec4;
+ m_specializationMap["PLANE"] = "9";
+ m_specializationMap["SAMPLER"] = "usampler2DMS";
+ m_specializationMap["TYPE"] = "uvec4";
if (false == is_case_valid)
{
fetch_offset = 0;
- plane = plane_sample_invalid;
+ m_specializationMap["PLANE"] = "gl_SampleID";
}
}
- glu::ContextType contextType = m_context.getRenderContext().getType();
- glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(contextType);
- const GLchar* version = glu::getGLSLVersionDeclaration(glslVersion);
-
- size_t position = 0;
- std::string source = template_code;
std::stringstream offset;
offset << fetch_offset;
- std::string offset_str = offset.str();
-
- replaceToken("VERSION", position, version, source);
- replaceToken("TYPE", position, type, source);
- replaceToken("SAMPLER", position, sampler, source);
- replaceToken("PLANE", position, plane, source);
- replaceToken("OFFSET", position, offset_str.c_str(), source);
+ m_specializationMap["OFFSET"] = offset.str();
- return source;
+ return tcu::StringTemplate(source).specialize(m_specializationMap);
}
/** Prepare shader for current test case
**/
std::string TexelFetchTest::getGeometryShader()
{
- return std::string("#version 430 core\n"
- "\n"
- "layout(points) in;\n"
- "layout(triangle_strip, max_vertices = 4) out;\n"
- "\n"
- "out vec2 gs_fs_tex_coord;\n"
- "\n"
- "void main()\n"
- "{\n"
- " gs_fs_tex_coord = vec2(0, 0);\n"
- " gl_Position = vec4(-1, -1, 0, 1);\n"
- " EmitVertex();\n"
- "\n"
- " gs_fs_tex_coord = vec2(0, 1);\n"
- " gl_Position = vec4(-1, 1, 0, 1);\n"
- " EmitVertex();\n"
- "\n"
- " gs_fs_tex_coord = vec2(1, 0);\n"
- " gl_Position = vec4(1, -1, 0, 1);\n"
- " EmitVertex();\n"
- "\n"
- " gs_fs_tex_coord = vec2(1, 1);\n"
- " gl_Position = vec4(1, 1, 0, 1);\n"
- " EmitVertex();\n"
- "}\n"
- "\n");
+ static const GLchar* source = "${VERSION}\n"
+ "layout(points) in;\n"
+ "layout(triangle_strip, max_vertices = 4) out;\n"
+ "\n"
+ "out vec2 gs_fs_tex_coord;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " gs_fs_tex_coord = vec2(0, 0);\n"
+ " gl_Position = vec4(-1, -1, 0, 1);\n"
+ " EmitVertex();\n"
+ "\n"
+ " gs_fs_tex_coord = vec2(0, 1);\n"
+ " gl_Position = vec4(-1, 1, 0, 1);\n"
+ " EmitVertex();\n"
+ "\n"
+ " gs_fs_tex_coord = vec2(1, 0);\n"
+ " gl_Position = vec4(1, -1, 0, 1);\n"
+ " EmitVertex();\n"
+ "\n"
+ " gs_fs_tex_coord = vec2(1, 1);\n"
+ " gl_Position = vec4(1, 1, 0, 1);\n"
+ " EmitVertex();\n"
+ "}\n";
+
+ return tcu::StringTemplate(source).specialize(m_specializationMap);
}
/** Prepare shader for current test case
**/
std::string TexelFetchTest::getVertexShader()
{
- return std::string("#version 430 core\n"
- "\n"
- "void main()\n"
- "{\n"
- " gl_Position = vec4(0, 0, 0, 1);\n"
- "}\n"
- "\n");
+ static const GLchar* source = "${VERSION}\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(0, 0, 0, 1);\n"
+ "}\n";
+ return tcu::StringTemplate(source).specialize(m_specializationMap);
}
/** Returns name of current test case
switch (m_test_case)
{
case R8:
- name = "\"Sampling GL_R8 texture\"";
+ name = "Sampling GL_R8 texture";
break;
case RG8_SNORM:
- name = "\"Sampling GL_RG8_SNORM texture\"";
+ name = "Sampling GL_RG8_SNORM texture";
break;
case RGBA32F:
- name = "\"Sampling GL_RGBA32F texture\"";
+ name = "Sampling GL_RGBA32F texture";
break;
case R32UI_MIPMAP:
- name = "\"Sampling mipmap of GL_32UI texture\"";
+ name = "Sampling mipmap of GL_32UI texture";
break;
case R32UI_MULTISAMPLE:
- name = "\"Sampling GL_32UI multisampled texture\"";
+ name = "Sampling GL_32UI multisampled texture";
break;
default:
TCU_FAIL("Invalid enum");
* @param is_source Selects if texutre will be used as source or destination
* @param texture_id Id of texutre
**/
-void TexelFetchTest::prepareTexture(bool is_source, glw::GLuint texture_id)
+void TexelFetchTest::prepareTexture(const Functions& gl, bool is_source, glw::GLuint texture_id)
{
/* Image size */
static const GLuint image_height = 16;
static const GLuint image_width = 16;
- /* GL entry points */
- const Functions& gl = m_context.getRenderContext().getFunctions();
-
/* Texture storage parameters */
GLuint height = image_height;
GLenum internal_format = 0;
Texture::Bind(gl, texture_id, target);
Texture::Storage(gl, target, n_levels, internal_format, width, height, 0);
- gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ /* Set samplers to NEAREST/NEAREST if required */
+ if (R32UI_MULTISAMPLE != m_test_case)
+ {
+ gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ }
/* Destination image can be left empty */
if (false == is_source)
else if (R32UI_MULTISAMPLE == m_test_case)
{
/* Compute shader */
- static const GLchar* cs = "#version 430 core\n"
- "\n"
- "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
- "\n"
- "layout (location = 0) writeonly uniform uimage2DMS uni_image;\n"
- "\n"
- "void main()\n"
- "{\n"
- " const ivec2 point = ivec2(gl_WorkGroupID.x, gl_WorkGroupID.y);\n"
- " const uint index = gl_WorkGroupID.y * 16 + gl_WorkGroupID.x;\n"
- "\n"
- " imageStore(uni_image, point, 0, uvec4(index + 0, 0, 0, 0));\n"
- " imageStore(uni_image, point, 1, uvec4(index + 1, 0, 0, 0));\n"
- " imageStore(uni_image, point, 2, uvec4(index + 2, 0, 0, 0));\n"
- " imageStore(uni_image, point, 3, uvec4(index + 3, 0, 0, 0));\n"
- "}\n"
- "\n";
+ static const GLchar* source =
+ "${VERSION}\n"
+ "\n"
+ "layout (local_size_x = ${LOCAL_SIZE}, local_size_y = ${LOCAL_SIZE}, local_size_z = 1) in;\n"
+ "layout (${QUALIFIER​S}) writeonly uniform highp uimage2DMS uni_image;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " const ivec2 point = ivec2(gl_WorkGroupID.x, gl_WorkGroupID.y);\n"
+ " const uint index = gl_WorkGroupID.y * 16U + gl_WorkGroupID.x;\n"
+ "\n"
+ " imageStore(uni_image, point, 0, uvec4(index + 0U, 0, 0, 0));\n"
+ " imageStore(uni_image, point, 1, uvec4(index + 1U, 0, 0, 0));\n"
+ " imageStore(uni_image, point, 2, uvec4(index + 2U, 0, 0, 0));\n"
+ " imageStore(uni_image, point, 3, uvec4(index + 3U, 0, 0, 0));\n"
+ "}\n"
+ "\n";
+
+ if (m_context_is_es)
+ {
+ m_specializationMap["LOCAL_SIZE"] = "16";
+ m_specializationMap["QUALIFIER​S"] = "binding = 0, r32ui";
+ }
+ else
+ {
+ m_specializationMap["LOCAL_SIZE"] = "1";
+ m_specializationMap["QUALIFIER​S"] = "location = 0";
+ }
- Program program(m_context);
+ Program program(gl);
+ std::string cs = tcu::StringTemplate(source).specialize(m_specializationMap);
program.Init(cs, "", "", "", "", "");
program.Use();
GL_WRITE_ONLY, GL_R32UI);
GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture");
- gl.uniform1i(0 /* location */, 0 /* image unit*/);
- GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
+ if (!m_context_is_es)
+ {
+ gl.uniform1i(0 /* location */, 0 /* image unit*/);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
+ }
gl.dispatchCompute(16, 16, 1);
GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
*
* @return true when image is filled with 0, 1 or biggest represetable integer number, false otherwise
**/
-bool TexelFetchTest::verifyInvalidResults(glw::GLuint texture_id)
+bool TexelFetchTest::verifyInvalidResults(const Functions& gl, glw::GLuint texture_id)
{
static const GLuint height = 16;
static const GLuint width = 16;
static const GLuint n_pixels = height * width;
- const Functions& gl = m_context.getRenderContext().getFunctions();
+ // OpenGL ES has undefined out-of-bound behavior - no verification
+ if (m_context_is_es)
+ return true;
bool result = true;
if (R8 == m_test_case)
{
- static const GLuint n_channels = 1;
+ static const GLuint n_channels = 4;
- std::vector<GLubyte> pixels;
- pixels.resize(n_pixels * n_channels);
- for (GLuint i = 0; i < n_pixels; ++i)
- {
- pixels[i] = static_cast<GLubyte>(i);
- }
+ std::vector<GLubyte> pixels(n_pixels * n_channels);
+ initPixels(pixels, n_pixels, n_channels);
Texture::Bind(gl, texture_id, GL_TEXTURE_2D);
- Texture::GetData(gl, 0 /* level */, GL_TEXTURE_2D, GL_RED, GL_UNSIGNED_BYTE, &pixels[0]);
+ Texture::GetData(gl, 0 /* level */, GL_TEXTURE_2D, GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]);
/* Unbind */
Texture::Bind(gl, 0, GL_TEXTURE_2D);
for (GLuint i = 0; i < n_pixels; ++i)
{
const GLubyte expected_red = 0;
- const GLubyte drawn_red = pixels[i];
+ const GLubyte drawn_red = pixels[i * n_channels];
if (expected_red != drawn_red)
{
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid value: " << (GLuint)drawn_red
- << ". Expected value: " << (GLuint)expected_red
- << " at offset: " << i << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value: " << (GLuint)drawn_red
+ << ". Expected value: " << (GLuint)expected_red << " at offset: " << i
+ << tcu::TestLog::EndMessage;
result = false;
break;
}
else if (RG8_SNORM == m_test_case)
{
- static const GLuint n_channels = 2;
+ static const GLuint n_channels = 4;
- std::vector<GLbyte> pixels;
- pixels.resize(n_pixels * n_channels);
- for (GLuint i = 0; i < n_pixels; ++i)
- {
- pixels[i * n_channels + 0] = static_cast<GLubyte>(i);
- pixels[i * n_channels + 1] = static_cast<GLubyte>(i);
- }
+ std::vector<GLbyte> pixels(n_pixels * n_channels);
+ initPixels(pixels, n_pixels, n_channels);
Texture::Bind(gl, texture_id, GL_TEXTURE_2D);
- Texture::GetData(gl, 0 /* level */, GL_TEXTURE_2D, GL_RG, GL_BYTE, &pixels[0]);
+ Texture::GetData(gl, 0 /* level */, GL_TEXTURE_2D, GL_RGBA, GL_BYTE, &pixels[0]);
/* Unbind */
Texture::Bind(gl, 0, GL_TEXTURE_2D);
if ((expected_red != drawn_red) || (expected_green != drawn_green))
{
- m_context.getTestContext().getLog()
- << tcu::TestLog::Message << "Invalid value: " << (GLint)drawn_red << ", " << (GLint)drawn_green
- << ". Expected value: " << (GLint)expected_red << ", " << (GLint)expected_green
- << ". At offset: " << i << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value: " << (GLint)drawn_red << ", "
+ << (GLint)drawn_green << ". Expected value: " << (GLint)expected_red << ", "
+ << (GLint)expected_green << ". At offset: " << i << tcu::TestLog::EndMessage;
result = false;
break;
{
static const GLuint n_channels = 4;
- std::vector<GLfloat> pixels;
- pixels.resize(n_pixels * n_channels);
+ std::vector<GLfloat> pixels(n_pixels * n_channels);
for (GLuint i = 0; i < n_pixels; ++i)
{
- pixels[i * n_channels + 0] = (GLfloat)i / (GLfloat)n_pixels;
- pixels[i * n_channels + 1] = (GLfloat)i / (GLfloat)n_pixels;
- pixels[i * n_channels + 2] = (GLfloat)i / (GLfloat)n_pixels;
- pixels[i * n_channels + 3] = (GLfloat)i / (GLfloat)n_pixels;
+ const GLuint idx = i * n_channels;
+ const GLfloat value = static_cast<GLfloat>(i) / n_pixels;
+ pixels[idx + 0] = value;
+ pixels[idx + 1] = value;
+ pixels[idx + 2] = value;
+ pixels[idx + 3] = value;
}
Texture::Bind(gl, texture_id, GL_TEXTURE_2D);
((de::abs(expected_alpha_0 - drawn_alpha) > precision) &&
(de::abs(expected_alpha_1 - drawn_alpha) > precision)))
{
- m_context.getTestContext().getLog()
- << tcu::TestLog::Message << "Invalid value: " << drawn_red << ", " << drawn_green << ", "
- << drawn_blue << ", " << drawn_alpha << ". Expected value: " << expected_red << ", "
- << expected_green << ", " << expected_blue << ", " << expected_alpha_0 << " or " << expected_alpha_1
- << ". At offset: " << i << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value: " << drawn_red << ", " << drawn_green
+ << ", " << drawn_blue << ", " << drawn_alpha << ". Expected value: " << expected_red
+ << ", " << expected_green << ", " << expected_blue << ", " << expected_alpha_0
+ << " or " << expected_alpha_1 << ". At offset: " << i << tcu::TestLog::EndMessage;
result = false;
break;
}
else if (R32UI_MIPMAP == m_test_case)
{
- static const GLuint n_channels = 1;
+ static const GLuint n_channels = 4;
- std::vector<GLuint> pixels;
- pixels.resize(n_pixels * n_channels);
- for (GLuint i = 0; i < n_pixels; ++i)
- {
- pixels[i] = i;
- }
+ std::vector<GLuint> pixels(n_pixels * n_channels);
+ initPixels(pixels, n_pixels, n_channels);
Texture::Bind(gl, texture_id, GL_TEXTURE_2D);
- Texture::GetData(gl, 1 /* level */, GL_TEXTURE_2D, GL_RED_INTEGER, GL_UNSIGNED_INT, &pixels[0]);
+ Texture::GetData(gl, texture_id, 1 /* level */, width, height, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &pixels[0]);
/* Unbind */
Texture::Bind(gl, 0, GL_TEXTURE_2D);
for (GLuint i = 0; i < n_pixels; ++i)
{
const GLuint expected_red = 0;
- const GLuint drawn_red = pixels[i];
+ const GLuint drawn_red = pixels[i * n_channels];
if (expected_red != drawn_red)
{
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid value: " << drawn_red
- << ". Expected value: " << expected_red << " at offset: " << i
- << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value: " << drawn_red
+ << ". Expected value: " << expected_red << " at offset: " << i
+ << tcu::TestLog::EndMessage;
result = false;
break;
}
else if (R32UI_MULTISAMPLE == m_test_case)
{
- static const GLuint n_channels = 1;
+ static const GLuint n_channels = 4;
/* Compute shader */
- static const GLchar* cs = "#version 430 core\n"
- "\n"
- "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
- "\n"
- "layout (location = 1) writeonly uniform uimage2D uni_destination_image;\n"
- "layout (location = 0, r32ui) readonly uniform uimage2DMS uni_source_image;\n"
- "\n"
- "void main()\n"
- "{\n"
- " const ivec2 point = ivec2(gl_WorkGroupID.x, gl_WorkGroupID.y);\n"
- "\n"
- " const uvec4 color_0 = imageLoad(uni_source_image, point, 0);\n"
- " const uvec4 color_1 = imageLoad(uni_source_image, point, 1);\n"
- " const uvec4 color_2 = imageLoad(uni_source_image, point, 2);\n"
- " const uvec4 color_3 = imageLoad(uni_source_image, point, 3);\n"
- "\n"
- " if (any(equal(uvec4(color_0.r, color_1.r, color_2.r, color_3.r), uvec4(0))))\n"
- " {\n"
- " imageStore(uni_destination_image, point, uvec4(1, 1, 1, 1));\n"
- " }\n"
- " else\n"
- " {\n"
- " imageStore(uni_destination_image, point, uvec4(0, 0, 0, 0));\n"
- " }\n"
- "}\n"
- "\n";
+ static const GLchar* source =
+ "${VERSION}\n"
+ "\n"
+ "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
+ "\n"
+ "layout (location = 1) writeonly uniform uimage2D uni_destination_image;\n"
+ "layout (location = 0, r32ui) readonly uniform uimage2DMS uni_source_image;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " const ivec2 point = ivec2(gl_WorkGroupID.x, gl_WorkGroupID.y);\n"
+ "\n"
+ " const uvec4 color_0 = imageLoad(uni_source_image, point, 0);\n"
+ " const uvec4 color_1 = imageLoad(uni_source_image, point, 1);\n"
+ " const uvec4 color_2 = imageLoad(uni_source_image, point, 2);\n"
+ " const uvec4 color_3 = imageLoad(uni_source_image, point, 3);\n"
+ "\n"
+ " if (any(equal(uvec4(color_0.r, color_1.r, color_2.r, color_3.r), uvec4(0))))\n"
+ " {\n"
+ " imageStore(uni_destination_image, point, uvec4(1, 1, 1, 1));\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " imageStore(uni_destination_image, point, uvec4(0, 0, 0, 0));\n"
+ " }\n"
+ "}\n"
+ "\n";
- Program program(m_context);
- Texture destination_texture(m_context);
+ Program program(gl);
+ Texture destination_texture(gl);
Texture::Generate(gl, destination_texture.m_id);
Texture::Bind(gl, destination_texture.m_id, GL_TEXTURE_2D);
Texture::Storage(gl, GL_TEXTURE_2D, 1, GL_R32UI, width, height, 0 /* depth */);
+ std::string cs = tcu::StringTemplate(source).specialize(m_specializationMap);
program.Init(cs, "", "", "", "", "");
program.Use();
gl.bindImageTexture(0 /* unit */, texture_id, 0 /* level */, GL_FALSE /* layered */, 0 /* layer */,
GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
/* Pixels buffer initialization */
- std::vector<GLuint> pixels;
- pixels.resize(n_pixels * n_channels);
- for (GLuint i = 0; i < n_pixels; ++i)
- {
- pixels[i] = i;
- }
+ std::vector<GLuint> pixels(n_pixels * n_channels);
+ initPixels(pixels, n_pixels, n_channels);
- Texture::GetData(gl, 0 /* level */, GL_TEXTURE_2D, GL_RED_INTEGER, GL_UNSIGNED_INT, &pixels[0]);
+ Texture::GetData(gl, 0 /* level */, GL_TEXTURE_2D, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &pixels[0]);
/* Unbind */
Texture::Bind(gl, 0, GL_TEXTURE_2D);
for (GLuint i = 0; i < n_pixels; ++i)
{
const GLuint expected_red = 1;
- const GLuint drawn_red = pixels[i];
+ const GLuint drawn_red = pixels[i * n_channels];
if (expected_red != drawn_red)
{
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid value: " << drawn_red
- << ". Expected value: " << expected_red << " at offset: " << i
- << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value: " << drawn_red
+ << ". Expected value: " << expected_red << " at offset: " << i
+ << tcu::TestLog::EndMessage;
result = false;
break;
*
* @return true when image is filled with increasing values, false otherwise
**/
-bool TexelFetchTest::verifyValidResults(glw::GLuint texture_id)
+bool TexelFetchTest::verifyValidResults(const Functions& gl, glw::GLuint texture_id)
{
static const GLuint height = 16;
static const GLuint width = 16;
static const GLuint n_pixels = height * width;
- const Functions& gl = m_context.getRenderContext().getFunctions();
-
bool result = true;
if (R8 == m_test_case)
{
- static const GLuint n_channels = 1;
+ static const GLuint n_channels = 4;
Texture::Bind(gl, texture_id, GL_TEXTURE_2D);
- std::vector<GLubyte> pixels;
- pixels.resize(n_pixels * n_channels);
- for (GLuint i = 0; i < n_pixels; ++i)
- {
- pixels[i] = static_cast<GLubyte>(i);
- }
+ std::vector<GLubyte> pixels(n_pixels * n_channels);
+ initPixels(pixels, n_pixels, n_channels);
- Texture::GetData(gl, 0 /* level */, GL_TEXTURE_2D, GL_RED, GL_UNSIGNED_BYTE, &pixels[0]);
+ Texture::GetData(gl, texture_id, 0 /* level */, width, height, GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]);
/* Unbind */
Texture::Bind(gl, 0, GL_TEXTURE_2D);
for (GLuint i = 0; i < n_pixels; ++i)
{
const GLubyte expected_red = static_cast<GLubyte>(i);
- const GLubyte drawn_red = pixels[i];
+ const GLubyte drawn_red = pixels[i * n_channels];
if (expected_red != drawn_red)
{
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid value: " << (GLuint)drawn_red
- << ". Expected value: " << (GLuint)expected_red
- << " at offset: " << i << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value: " << (GLuint)drawn_red
+ << ". Expected value: " << (GLuint)expected_red << " at offset: " << i
+ << tcu::TestLog::EndMessage;
result = false;
break;
}
else if (RG8_SNORM == m_test_case)
{
- static const GLuint n_channels = 2;
+ static const GLuint n_channels = 4;
Texture::Bind(gl, texture_id, GL_TEXTURE_2D);
- std::vector<GLbyte> pixels;
- pixels.resize(n_pixels * n_channels);
- for (GLuint i = 0; i < n_pixels; ++i)
- {
- pixels[i * n_channels + 0] = static_cast<GLubyte>(i);
- pixels[i * n_channels + 1] = static_cast<GLubyte>(i);
- }
+ std::vector<GLbyte> pixels(n_pixels * n_channels);
+ initPixels(pixels, n_pixels, n_channels);
- Texture::GetData(gl, 0 /* level */, GL_TEXTURE_2D, GL_RG, GL_BYTE, &pixels[0]);
+ Texture::GetData(gl, texture_id, 0 /* level */, width, height, GL_RGBA, GL_BYTE, &pixels[0]);
/* Unbind */
Texture::Bind(gl, 0, GL_TEXTURE_2D);
if ((expected_red != drawn_red) || (expected_green != drawn_green))
{
- m_context.getTestContext().getLog()
- << tcu::TestLog::Message << "Invalid value: " << (GLint)drawn_red << ", " << (GLint)drawn_green
- << ". Expected value: " << (GLint)expected_red << ", " << (GLint)expected_green
- << ". At offset: " << i << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value: " << (GLint)drawn_red << ", "
+ << (GLint)drawn_green << ". Expected value: " << (GLint)expected_red << ", "
+ << (GLint)expected_green << ". At offset: " << i << tcu::TestLog::EndMessage;
result = false;
break;
Texture::Bind(gl, texture_id, GL_TEXTURE_2D);
- std::vector<GLfloat> pixels;
- pixels.resize(n_pixels * n_channels);
+ std::vector<GLfloat> pixels(n_pixels * n_channels);
for (GLuint i = 0; i < n_pixels; ++i)
{
- pixels[i * n_channels + 0] = (GLfloat)i / (GLfloat)n_pixels;
- pixels[i * n_channels + 1] = (GLfloat)i / (GLfloat)n_pixels;
- pixels[i * n_channels + 2] = (GLfloat)i / (GLfloat)n_pixels;
- pixels[i * n_channels + 3] = (GLfloat)i / (GLfloat)n_pixels;
+ const GLuint idx = i * n_channels;
+ const GLfloat value = static_cast<GLfloat>(i) / n_pixels;
+ pixels[idx + 0] = value;
+ pixels[idx + 1] = value;
+ pixels[idx + 2] = value;
+ pixels[idx + 3] = value;
}
- Texture::GetData(gl, 0 /* level */, GL_TEXTURE_2D, GL_RGBA, GL_FLOAT, &pixels[0]);
+ Texture::GetData(gl, texture_id, 0 /* level */, width, height, GL_RGBA, GL_FLOAT, &pixels[0]);
/* Unbind */
Texture::Bind(gl, 0, GL_TEXTURE_2D);
const GLfloat expected_green = (GLfloat)(i / 16) / 16.0f;
const GLfloat expected_blue = (GLfloat)i / 256.0f;
const GLfloat expected_alpha = 1.0f;
- const GLfloat drawn_red = pixels[i * n_channels + 0];
- const GLfloat drawn_green = pixels[i * n_channels + 1];
- const GLfloat drawn_blue = pixels[i * n_channels + 2];
- const GLfloat drawn_alpha = pixels[i * n_channels + 3];
+ const GLuint idx = i * n_channels;
+ const GLfloat drawn_red = pixels[idx + 0];
+ const GLfloat drawn_green = pixels[idx + 1];
+ const GLfloat drawn_blue = pixels[idx + 2];
+ const GLfloat drawn_alpha = pixels[idx + 3];
if ((expected_red != drawn_red) || (expected_green != drawn_green) || (expected_blue != drawn_blue) ||
(expected_alpha != drawn_alpha))
{
- m_context.getTestContext().getLog()
- << tcu::TestLog::Message << "Invalid value: " << drawn_red << ", " << drawn_green << ", "
- << drawn_blue << ", " << drawn_alpha << ". Expected value: " << expected_red << ", "
- << expected_green << ", " << expected_blue << ", " << expected_alpha << ". At offset: " << i
- << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value: " << drawn_red << ", " << drawn_green
+ << ", " << drawn_blue << ", " << drawn_alpha << ". Expected value: " << expected_red
+ << ", " << expected_green << ", " << expected_blue << ", " << expected_alpha
+ << ". At offset: " << i << tcu::TestLog::EndMessage;
result = false;
break;
}
else if (R32UI_MIPMAP == m_test_case)
{
- static const GLuint n_channels = 1;
+ static const GLuint n_channels = 4;
Texture::Bind(gl, texture_id, GL_TEXTURE_2D);
- std::vector<GLuint> pixels;
- pixels.resize(n_pixels * n_channels * 4);
- for (GLuint i = 0; i < n_pixels; ++i)
- {
- pixels[i] = 0;
- }
+ std::vector<GLuint> pixels(n_pixels * n_channels, 0);
- Texture::GetData(gl, 1 /* level */, GL_TEXTURE_2D, GL_RED_INTEGER, GL_UNSIGNED_INT, &pixels[0]);
+ Texture::GetData(gl, texture_id, 1 /* level */, width, height, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &pixels[0]);
/* Unbind */
Texture::Bind(gl, 0, GL_TEXTURE_2D);
for (GLuint i = 0; i < n_pixels; ++i)
{
const GLuint expected_red = i;
- const GLuint drawn_red = pixels[i];
+ const GLuint drawn_red = pixels[i * n_channels];
if (expected_red != drawn_red)
{
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid value: " << drawn_red
- << ". Expected value: " << expected_red << " at offset: " << i
- << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value: " << drawn_red
+ << ". Expected value: " << expected_red << " at offset: " << i
+ << tcu::TestLog::EndMessage;
result = false;
break;
}
else if (R32UI_MULTISAMPLE == m_test_case)
{
- static const GLuint n_channels = 1;
+ static const GLuint n_channels = 4;
/* Compute shader */
- static const GLchar* cs =
- "#version 430 core\n"
+ static const GLchar* source =
+ "${VERSION}\n"
"\n"
"layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
"\n"
- "layout (location = 1) writeonly uniform uimage2D uni_destination_image;\n"
+ "layout (location = 1, r32ui) writeonly uniform uimage2D uni_destination_image;\n"
"layout (location = 0, r32ui) readonly uniform uimage2DMS uni_source_image;\n"
"\n"
"void main()\n"
"{\n"
" const ivec2 point = ivec2(gl_WorkGroupID.x, gl_WorkGroupID.y);\n"
- " const uint index = gl_WorkGroupID.y * 16 + gl_WorkGroupID.x;\n"
+ " const uint index = gl_WorkGroupID.y * 16U + gl_WorkGroupID.x;\n"
"\n"
" const uvec4 color_0 = imageLoad(uni_source_image, point, 0);\n"
" const uvec4 color_1 = imageLoad(uni_source_image, point, 1);\n"
" const uvec4 color_2 = imageLoad(uni_source_image, point, 2);\n"
" const uvec4 color_3 = imageLoad(uni_source_image, point, 3);\n"
"\n"
- " if (any(equal(uvec4(color_0.r, color_1.r, color_2.r, color_3.r), uvec4(index + 3))))\n"
+ " if (any(equal(uvec4(color_0.r, color_1.r, color_2.r, color_3.r), uvec4(index + 3U))))\n"
" {\n"
- " imageStore(uni_destination_image, point, uvec4(1, 1, 1, 1));\n"
+ " imageStore(uni_destination_image, point, uvec4(1U));\n"
" }\n"
" else\n"
" {\n"
- " imageStore(uni_destination_image, point, uvec4(0, 0, 0, 0));\n"
+ " imageStore(uni_destination_image, point, uvec4(0U));\n"
" }\n"
"}\n"
"\n";
- Program program(m_context);
- Texture destination_texture(m_context);
+ Program program(gl);
+ Texture destination_texture(gl);
Texture::Generate(gl, destination_texture.m_id);
Texture::Bind(gl, destination_texture.m_id, GL_TEXTURE_2D);
Texture::Storage(gl, GL_TEXTURE_2D, 1, GL_R32UI, width, height, 0 /* depth */);
+ std::string cs = tcu::StringTemplate(source).specialize(m_specializationMap);
program.Init(cs, "", "", "", "", "");
program.Use();
gl.bindImageTexture(0 /* unit */, texture_id, 0 /* level */, GL_FALSE /* layered */, 0 /* layer */,
0 /* layer */, GL_WRITE_ONLY, GL_R32UI);
GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture");
- gl.uniform1i(0 /* location */, 0 /* image unit*/);
- GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
+ if (!m_context_is_es)
+ {
+ gl.uniform1i(0 /* location */, 0 /* image unit*/);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
- gl.uniform1i(1 /* location */, 1 /* image unit*/);
- GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
+ gl.uniform1i(1 /* location */, 1 /* image unit*/);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
+ }
gl.dispatchCompute(16, 16, 1);
GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
/* Pixels buffer initialization */
- std::vector<GLuint> pixels;
- pixels.resize(n_pixels * n_channels);
- for (GLuint i = 0; i < n_pixels; ++i)
- {
- pixels[i] = i;
- }
+ std::vector<GLuint> pixels(n_pixels * n_channels);
+ initPixels(pixels, n_pixels, n_channels);
- Texture::GetData(gl, 0 /* level */, GL_TEXTURE_2D, GL_RED_INTEGER, GL_UNSIGNED_INT, &pixels[0]);
+ Texture::GetData(gl, destination_texture.m_id, 0 /* level */, width, height, GL_RGBA_INTEGER, GL_UNSIGNED_INT,
+ &pixels[0]);
/* Unbind */
Texture::Bind(gl, 0, GL_TEXTURE_2D);
for (GLuint i = 0; i < n_pixels; ++i)
{
const GLuint expected_red = 1;
- const GLuint drawn_red = pixels[i];
+ const GLuint drawn_red = pixels[i * n_channels];
if (expected_red != drawn_red)
{
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid value: " << drawn_red
- << ". Expected value: " << expected_red << " at offset: " << i
- << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value: " << drawn_red
+ << ". Expected value: " << expected_red << " at offset: " << i
+ << tcu::TestLog::EndMessage;
result = false;
break;
/** Constructor
*
- * @param context Test context
+ * @param testCtx Test context
+ * @param apiType Api type
**/
-ImageLoadStoreTest::ImageLoadStoreTest(deqp::Context& context)
- : TexelFetchTest(context, "image_load_store", "Verifies that out-of-bound to image result in zero or is discarded")
+ImageLoadStoreTest::ImageLoadStoreTest(tcu::TestContext& testCtx, glu::ApiType apiType)
+ : TexelFetchTest(testCtx, "image_load_store", "Verifies that out-of-bound to image result in zero or is discarded",
+ apiType)
{
- /* Nothing to be done */
-}
-
-/** Constructor
- *
- * @param context Test context
- **/
-ImageLoadStoreTest::ImageLoadStoreTest(deqp::Context& context, const glw::GLchar* name, const glw::GLchar* description)
- : TexelFetchTest(context, name, description)
-{
- /* Nothing to be done */
}
/** Execute test
**/
tcu::TestNode::IterateResult ImageLoadStoreTest::iterate()
{
- if (!isRobustBufferAccessBehaviorFeatureSupported(m_context))
+ de::SharedPtr<glu::RenderContext> robustContext(createRobustContext());
+ if (!robustContext.get())
return STOP;
/* Constants */
static const GLuint width = 16;
/* GL entry points */
- const Functions& gl = m_context.getRenderContext().getFunctions();
+ const Functions& gl = robustContext->getFunctions();
struct FetchingOffset
{
{ 16, 4 }, { 512, 4 }, { 1024, 8 }, { 2048, 8 },
};
+ /* For ES start from RGBA32F as R8, R32UI_MULTISAMPLE and R8_SNORM are not supported */
+ if (m_context_is_es)
+ m_test_case = RGBA32F;
+
/* Test result indicator */
bool test_result = true;
// Skip invalid program test in multi sample case
// texelFetch with invalid lod plane results undefined value
// OpenGL 4.5 Core Spec, around page 377
- m_test_case = (TEST_CASES)((GLuint)m_test_case + 1);
continue;
}
/* Test case objects */
- Texture destination_texture(m_context);
- Texture source_texture(m_context);
- Program program(m_context);
+ Texture destination_texture(gl);
+ Texture source_texture(gl);
+ Program program(gl);
/* Prepare textures */
Texture::Generate(gl, destination_texture.m_id);
* to upload the texture so max_image_samples >= 4
* is also required.
*/
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case: " << getTestCaseName()
- << " not supported" << tcu::TestLog::EndMessage;
-
+ m_testCtx.getLog() << tcu::TestLog::Message << "Test case: " << getTestCaseName() << " not supported"
+ << tcu::TestLog::EndMessage;
continue;
}
}
- prepareTexture(false, destination_texture.m_id);
- prepareTexture(true, source_texture.m_id);
+ prepareTexture(gl, false, destination_texture.m_id);
+ prepareTexture(gl, true, source_texture.m_id);
/* Test invalid source cases */
for (GLuint i = 0; i < DE_LENGTH_OF_ARRAY(fetching_offsets); ++i)
program.Use();
/* Set texture */
- setTextures(destination_texture.m_id, source_texture.m_id);
+ setTextures(gl, destination_texture.m_id, source_texture.m_id);
/* Dispatch */
gl.dispatchCompute(width, height, 1 /* depth */);
GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
/* Verification */
- if (false == verifyInvalidResults(destination_texture.m_id))
+ if (false == verifyInvalidResults(gl, destination_texture.m_id))
{
case_result = false;
}
program.Use();
/* Set texture */
- setTextures(destination_texture.m_id, source_texture.m_id);
+ setTextures(gl, destination_texture.m_id, source_texture.m_id);
/* Dispatch */
gl.dispatchCompute(width, height, 1 /* depth */);
GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
/* Verification */
- if (false == verifyValidResults(destination_texture.m_id))
+ if (false == verifyValidResults(gl, destination_texture.m_id))
{
case_result = false;
}
program.Use();
/* Set texture */
- setTextures(destination_texture.m_id, source_texture.m_id);
+ setTextures(gl, destination_texture.m_id, source_texture.m_id);
/* Dispatch */
gl.dispatchCompute(width, height, 1 /* depth */);
GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
/* Verification */
- if (false == verifyValidResults(destination_texture.m_id))
+ if (false == verifyValidResults(gl, destination_texture.m_id))
{
case_result = false;
}
/* Set test result */
if (false == case_result)
{
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case: " << getTestCaseName()
- << " failed" << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Test case: " << getTestCaseName() << " failed"
+ << tcu::TestLog::EndMessage;
test_result = false;
}
/* Set result */
if (true == test_result)
{
- m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
+ m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
}
else
{
- m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+ m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
}
/* Done */
**/
std::string ImageLoadStoreTest::getComputeShader(VERSION version, GLuint coord_offset, GLuint sample_offset)
{
- static const GLchar* template_code =
- "#version 430 core\n"
+ static const GLchar* source =
+ "${VERSION}\n"
"\n"
"layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
"\n"
- "layout (location = 1) writeonly uniform IMAGE uni_destination_image;\n"
- "layout (location = 0, FORMAT) readonly uniform IMAGE uni_source_image;\n"
+ "layout (${QUALIFIER} = 1, ${FORMAT}) writeonly uniform highp ${IMAGE} uni_destination_image;\n"
+ "layout (${QUALIFIER} = 0, ${FORMAT}) readonly uniform highp ${IMAGE} uni_source_image;\n"
"\n"
"void main()\n"
"{\n"
- " const ivec2 point_destination = ivec2(gl_WorkGroupID.xy) + ivec2(COORD_OFFSET);\n"
- " const ivec2 point_source = ivec2(gl_WorkGroupID.xy) + ivec2(COORD_OFFSET);\n"
+ " ivec2 point_destination = ivec2(gl_WorkGroupID.xy) + ivec2(${DST_COORD_OFFSET}U);\n"
+ " ivec2 point_source = ivec2(gl_WorkGroupID.xy) + ivec2(${SRC_COORD_OFFSET}U);\n"
"\n"
- "COPY"
- "}\n"
- "\n";
+ "${COPY}"
+ "}\n";
static const GLchar* copy_multisampled =
- " const TYPE color_0 = imageLoad(uni_source_image, point_source, 0 + SAMPLE_OFFSET);\n"
- " const TYPE color_1 = imageLoad(uni_source_image, point_source, 1 + SAMPLE_OFFSET);\n"
- " const TYPE color_2 = imageLoad(uni_source_image, point_source, 2 + SAMPLE_OFFSET);\n"
- " const TYPE color_3 = imageLoad(uni_source_image, point_source, 3 + SAMPLE_OFFSET);\n"
- " imageStore(uni_destination_image, point_destination, 0 + SAMPLE_OFFSET, color_0);\n"
- " imageStore(uni_destination_image, point_destination, 1 + SAMPLE_OFFSET, color_1);\n"
- " imageStore(uni_destination_image, point_destination, 2 + SAMPLE_OFFSET, color_2);\n"
- " imageStore(uni_destination_image, point_destination, 3 + SAMPLE_OFFSET, color_3);\n";
-
- static const GLchar* copy_regular =
- " const TYPE color = imageLoad(uni_source_image, point_source);\n"
- " imageStore(uni_destination_image, point_destination, color);\n";
-
- static const GLchar* format_r8 = "r8";
- static const GLchar* format_rg8_snorm = "rg8_snorm";
- static const GLchar* format_rgba32f = "rgba32f";
- static const GLchar* format_r32ui = "r32ui";
-
- static const GLchar* image_vec4 = "image2D";
- static const GLchar* image_uvec4 = "uimage2D";
- static const GLchar* image_uvec4_ms = "uimage2DMS";
-
- static const GLchar* type_vec4 = "vec4";
- static const GLchar* type_uvec4 = "uvec4";
-
- const GLchar* copy = copy_regular;
- const GLchar* format = format_r8;
- const GLchar* image = image_vec4;
- const GLchar* type = type_vec4;
+ " ${TYPE} color_0 = imageLoad(uni_source_image, point_source, 0 + ${SRC_SAMPLE_OFFSET});\n"
+ " ${TYPE} color_1 = imageLoad(uni_source_image, point_source, 1 + ${SRC_SAMPLE_OFFSET});\n"
+ " ${TYPE} color_2 = imageLoad(uni_source_image, point_source, 2 + ${SRC_SAMPLE_OFFSET});\n"
+ " ${TYPE} color_3 = imageLoad(uni_source_image, point_source, 3 + ${SRC_SAMPLE_OFFSET});\n"
+ " imageStore(uni_destination_image, point_destination, 0 + ${DST_SAMPLE_OFFSET}, color_0);\n"
+ " imageStore(uni_destination_image, point_destination, 1 + ${DST_SAMPLE_OFFSET}, color_1);\n"
+ " imageStore(uni_destination_image, point_destination, 2 + ${DST_SAMPLE_OFFSET}, color_2);\n"
+ " imageStore(uni_destination_image, point_destination, 3 + ${DST_SAMPLE_OFFSET}, color_3);\n";
+
+ static const GLchar* copy_regular = " ${TYPE} color = imageLoad(uni_source_image, point_source);\n"
+ " imageStore(uni_destination_image, point_destination, color);\n";
std::string src_coord_offset_str("0");
std::string dst_coord_offset_str("0");
std::stringstream sample_offset_stream;
sample_offset_stream << sample_offset;
- if (version == SOURCE_INVALID)
- {
- src_coord_offset_str = coord_offset_stream.str();
- src_sample_offset_str = sample_offset_stream.str();
- }
- else if (version == DESTINATION_INVALID)
- {
- dst_coord_offset_str = coord_offset_stream.str();
- dst_sample_offset_str = sample_offset_stream.str();
- }
-
+ m_specializationMap["QUALIFIER"] = m_context_is_es ? "binding" : "location";
+ m_specializationMap["IMAGE"] = "image2D";
+ m_specializationMap["TYPE"] = "vec4";
switch (m_test_case)
{
case R8:
+ m_specializationMap["FORMAT"] = "r8";
break;
case RG8_SNORM:
- format = format_rg8_snorm;
+ m_specializationMap["FORMAT"] = "rg8_snorm";
break;
case RGBA32F:
- format = format_rgba32f;
+ m_specializationMap["FORMAT"] = "rgba32f";
break;
case R32UI_MIPMAP:
- format = format_r32ui;
- image = image_uvec4;
- type = type_uvec4;
+ m_specializationMap["FORMAT"] = "r32ui";
+ m_specializationMap["IMAGE"] = "uimage2D";
+ m_specializationMap["TYPE"] = "uvec4";
break;
case R32UI_MULTISAMPLE:
- copy = copy_multisampled;
- format = format_r32ui;
- image = image_uvec4_ms;
- coord_offset = 0;
- type = type_uvec4;
+ m_specializationMap["FORMAT"] = "r32ui";
+ m_specializationMap["IMAGE"] = "uimage2DMS";
+ m_specializationMap["TYPE"] = "uvec4";
break;
default:
TCU_FAIL("Invalid enum");
};
- size_t position = 0;
- std::string source = template_code;
+ m_specializationMap["SRC_COORD_OFFSET"] = "0";
+ m_specializationMap["SRC_SAMPLE_OFFSET"] = "0";
+ m_specializationMap["DST_COORD_OFFSET"] = "0";
+ m_specializationMap["DST_SAMPLE_OFFSET"] = "0";
- replaceToken("IMAGE", position, image, source);
- replaceToken("FORMAT", position, format, source);
- replaceToken("IMAGE", position, image, source);
- replaceToken("COORD_OFFSET", position, dst_coord_offset_str.c_str(), source);
- replaceToken("COORD_OFFSET", position, src_coord_offset_str.c_str(), source);
-
- size_t temp_position = position;
- replaceToken("COPY", position, copy, source);
- position = temp_position;
-
- switch (m_test_case)
+ if (version == SOURCE_INVALID)
{
- case R8:
- case RG8_SNORM:
- case RGBA32F:
- case R32UI_MIPMAP:
- replaceToken("TYPE", position, type, source);
- break;
- case R32UI_MULTISAMPLE:
- replaceToken("TYPE", position, type, source);
- replaceToken("SAMPLE_OFFSET", position, src_sample_offset_str.c_str(), source);
- replaceToken("TYPE", position, type, source);
- replaceToken("SAMPLE_OFFSET", position, src_sample_offset_str.c_str(), source);
- replaceToken("TYPE", position, type, source);
- replaceToken("SAMPLE_OFFSET", position, src_sample_offset_str.c_str(), source);
- replaceToken("TYPE", position, type, source);
- replaceToken("SAMPLE_OFFSET", position, src_sample_offset_str.c_str(), source);
- replaceToken("SAMPLE_OFFSET", position, dst_sample_offset_str.c_str(), source);
- replaceToken("SAMPLE_OFFSET", position, dst_sample_offset_str.c_str(), source);
- replaceToken("SAMPLE_OFFSET", position, dst_sample_offset_str.c_str(), source);
- replaceToken("SAMPLE_OFFSET", position, dst_sample_offset_str.c_str(), source);
- break;
- default:
- TCU_FAIL("Invalid enum");
+ m_specializationMap["SRC_COORD_OFFSET"] = coord_offset_stream.str();
+ m_specializationMap["SRC_SAMPLE_OFFSET"] = sample_offset_stream.str();
+ }
+ else if (version == DESTINATION_INVALID)
+ {
+ m_specializationMap["DST_COORD_OFFSET"] = coord_offset_stream.str();
+ m_specializationMap["DST_SAMPLE_OFFSET"] = sample_offset_stream.str();
}
- return source;
+ const GLchar* copy = (m_test_case == R32UI_MULTISAMPLE) ? copy_multisampled : copy_regular;
+ m_specializationMap["COPY"] = tcu::StringTemplate(copy).specialize(m_specializationMap);
+
+ return tcu::StringTemplate(source).specialize(m_specializationMap);
}
/** Set textures as images
* @param id_destination Id of texture used as destination
* @param id_source Id of texture used as source
**/
-void ImageLoadStoreTest::setTextures(glw::GLuint id_destination, glw::GLuint id_source)
+void ImageLoadStoreTest::setTextures(const Functions& gl, glw::GLuint id_destination, glw::GLuint id_source)
{
- const Functions& gl = m_context.getRenderContext().getFunctions();
-
GLenum format = 0;
GLint level = 0;
format);
GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture");
- gl.uniform1i(0 /* location */, 0 /* image unit*/);
- GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
+ if (!m_context_is_es)
+ {
+ gl.uniform1i(0 /* location */, 0 /* image unit*/);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
- gl.uniform1i(1 /* location */, 1 /* image unit*/);
- GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
+ gl.uniform1i(1 /* location */, 1 /* image unit*/);
+ GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i");
+ }
}
/** Verifies that texutre is filled with 0
*
* @return true when image is filled with 0, false otherwise
**/
-bool ImageLoadStoreTest::verifyInvalidResults(glw::GLuint texture_id)
+bool ImageLoadStoreTest::verifyInvalidResults(const Functions& gl, glw::GLuint texture_id)
{
static const GLuint height = 16;
static const GLuint width = 16;
static const GLuint n_pixels = height * width;
- const Functions& gl = m_context.getRenderContext().getFunctions();
+ // OpenGL ES has undefined out-of-bound behavior - no verification
+ if (m_context_is_es)
+ return true;
+
gl.memoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
GLU_EXPECT_NO_ERROR(gl.getError(), "MemoryBarrier");
{
static const GLuint n_channels = 1;
- std::vector<GLubyte> pixels;
- pixels.resize(n_pixels * n_channels);
- for (GLuint i = 0; i < n_pixels; ++i)
- {
- pixels[i] = static_cast<GLubyte>(i);
- }
+ std::vector<GLubyte> pixels(n_pixels * n_channels);
+ initPixels(pixels, n_pixels, n_channels);
Texture::Bind(gl, texture_id, GL_TEXTURE_2D);
if (expected_red != drawn_red)
{
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid value: " << (GLuint)drawn_red
- << ". Expected value: " << (GLuint)expected_red
- << " at offset: " << i << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value: " << (GLuint)drawn_red
+ << ". Expected value: " << (GLuint)expected_red << " at offset: " << i
+ << tcu::TestLog::EndMessage;
result = false;
break;
{
static const GLuint n_channels = 2;
- std::vector<GLbyte> pixels;
- pixels.resize(n_pixels * n_channels);
- for (GLuint i = 0; i < n_pixels; ++i)
- {
- pixels[i * n_channels + 0] = static_cast<GLubyte>(i);
- pixels[i * n_channels + 1] = static_cast<GLubyte>(i);
- }
+ std::vector<GLbyte> pixels(n_pixels * n_channels);
+ initPixels(pixels, n_pixels, n_channels);
Texture::Bind(gl, texture_id, GL_TEXTURE_2D);
if ((expected_red != drawn_red) || (expected_green != drawn_green))
{
- m_context.getTestContext().getLog()
- << tcu::TestLog::Message << "Invalid value: " << (GLint)drawn_red << ", " << (GLint)drawn_green
- << ". Expected value: " << (GLint)expected_red << ", " << (GLint)expected_green
- << ". At offset: " << i << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value: " << (GLint)drawn_red << ", "
+ << (GLint)drawn_green << ". Expected value: " << (GLint)expected_red << ", "
+ << (GLint)expected_green << ". At offset: " << i << tcu::TestLog::EndMessage;
result = false;
break;
{
static const GLuint n_channels = 4;
- std::vector<GLfloat> pixels;
- pixels.resize(n_pixels * n_channels);
+ std::vector<GLfloat> pixels(n_pixels * n_channels);
for (GLuint i = 0; i < n_pixels; ++i)
{
- pixels[i * n_channels + 0] = (GLfloat)i / (GLfloat)n_pixels;
- pixels[i * n_channels + 1] = (GLfloat)i / (GLfloat)n_pixels;
- pixels[i * n_channels + 2] = (GLfloat)i / (GLfloat)n_pixels;
- pixels[i * n_channels + 3] = (GLfloat)i / (GLfloat)n_pixels;
+ GLuint idx = i * n_channels;
+ GLfloat value = static_cast<GLfloat>(i) / n_pixels;
+ pixels[idx + 0] = value;
+ pixels[idx + 1] = value;
+ pixels[idx + 2] = value;
+ pixels[idx + 3] = value;
}
Texture::Bind(gl, texture_id, GL_TEXTURE_2D);
const GLfloat expected_green = 0.0f;
const GLfloat expected_blue = 0.0f;
const GLfloat expected_alpha = 0.0f;
- const GLfloat drawn_red = pixels[i * n_channels + 0];
- const GLfloat drawn_green = pixels[i * n_channels + 1];
- const GLfloat drawn_blue = pixels[i * n_channels + 2];
- const GLfloat drawn_alpha = pixels[i * n_channels + 3];
+ const GLuint idx = i * n_channels;
+ const GLfloat drawn_red = pixels[idx + 0];
+ const GLfloat drawn_green = pixels[idx + 1];
+ const GLfloat drawn_blue = pixels[idx + 2];
+ const GLfloat drawn_alpha = pixels[idx + 3];
if ((expected_red != drawn_red) || (expected_green != drawn_green) || (expected_blue != drawn_blue) ||
(expected_alpha != drawn_alpha))
{
- m_context.getTestContext().getLog()
- << tcu::TestLog::Message << "Invalid value: " << drawn_red << ", " << drawn_green << ", "
- << drawn_blue << ", " << drawn_alpha << ". Expected value: " << expected_red << ", "
- << expected_green << ", " << expected_blue << ", " << expected_alpha << ". At offset: " << i
- << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value: " << drawn_red << ", " << drawn_green
+ << ", " << drawn_blue << ", " << drawn_alpha << ". Expected value: " << expected_red
+ << ", " << expected_green << ", " << expected_blue << ", " << expected_alpha
+ << ". At offset: " << i << tcu::TestLog::EndMessage;
result = false;
break;
{
static const GLuint n_channels = 1;
- std::vector<GLuint> pixels;
- pixels.resize(n_pixels * n_channels);
- for (GLuint i = 0; i < n_pixels; ++i)
- {
- pixels[i] = i;
- }
+ std::vector<GLuint> pixels(n_pixels * n_channels);
+ initPixels(pixels, n_pixels, n_channels);
Texture::Bind(gl, texture_id, GL_TEXTURE_2D);
if (expected_red != drawn_red)
{
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid value: " << drawn_red
- << ". Expected value: " << expected_red << " at offset: " << i
- << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value: " << drawn_red
+ << ". Expected value: " << expected_red << " at offset: " << i
+ << tcu::TestLog::EndMessage;
result = false;
break;
static const GLuint n_channels = 1;
/* Compute shader */
- static const GLchar* cs = "#version 430 core\n"
+ static const GLchar* cs = "${VERSION}\n"
"\n"
"layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
"\n"
"}\n"
"\n";
- Program program(m_context);
- Texture destination_texture(m_context);
+ Program program(gl);
+ Texture destination_texture(gl);
Texture::Generate(gl, destination_texture.m_id);
Texture::Bind(gl, destination_texture.m_id, GL_TEXTURE_2D);
GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
/* Pixels buffer initialization */
- std::vector<GLuint> pixels;
- pixels.resize(n_pixels * n_channels);
- for (GLuint i = 0; i < n_pixels; ++i)
- {
- pixels[i] = i;
- }
+ std::vector<GLuint> pixels(n_pixels * n_channels);
+ initPixels(pixels, n_pixels, n_channels);
Texture::GetData(gl, 0 /* level */, GL_TEXTURE_2D, GL_RED_INTEGER, GL_UNSIGNED_INT, &pixels[0]);
if (expected_red != drawn_red)
{
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid value: " << drawn_red
- << ". Expected value: " << expected_red << " at offset: " << i
- << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value: " << drawn_red
+ << ". Expected value: " << expected_red << " at offset: " << i
+ << tcu::TestLog::EndMessage;
result = false;
break;
*
* @return true when image is filled with increasing values, false otherwise
**/
-bool ImageLoadStoreTest::verifyValidResults(glw::GLuint texture_id)
+bool ImageLoadStoreTest::verifyValidResults(const glw::Functions& gl, glw::GLuint texture_id)
{
static const GLuint height = 16;
static const GLuint width = 16;
static const GLuint n_pixels = height * width;
- const Functions& gl = m_context.getRenderContext().getFunctions();
gl.memoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
GLU_EXPECT_NO_ERROR(gl.getError(), "MemoryBarrier");
Texture::Bind(gl, texture_id, GL_TEXTURE_2D);
- std::vector<GLubyte> pixels;
- pixels.resize(n_pixels * n_channels);
- for (GLuint i = 0; i < n_pixels; ++i)
- {
- pixels[i] = static_cast<GLubyte>(i);
- }
+ std::vector<GLubyte> pixels(n_pixels * n_channels);
+ initPixels(pixels, n_pixels, n_channels);
Texture::GetData(gl, 0 /* level */, GL_TEXTURE_2D, GL_RED, GL_UNSIGNED_BYTE, &pixels[0]);
if (expected_red != drawn_red)
{
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid value: " << (GLuint)drawn_red
- << ". Expected value: " << (GLuint)expected_red
- << " at offset: " << i << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value: " << (GLuint)drawn_red
+ << ". Expected value: " << (GLuint)expected_red << " at offset: " << i
+ << tcu::TestLog::EndMessage;
result = false;
break;
Texture::Bind(gl, texture_id, GL_TEXTURE_2D);
- std::vector<GLbyte> pixels;
- pixels.resize(n_pixels * n_channels);
- for (GLuint i = 0; i < n_pixels; ++i)
- {
- pixels[i * n_channels + 0] = static_cast<GLubyte>(i);
- pixels[i * n_channels + 1] = static_cast<GLubyte>(i);
- }
+ std::vector<GLbyte> pixels(n_pixels * n_channels);
+ initPixels(pixels, n_pixels, n_channels);
Texture::GetData(gl, 0 /* level */, GL_TEXTURE_2D, GL_RG, GL_BYTE, &pixels[0]);
if ((expected_red != drawn_red) || (expected_green != drawn_green))
{
- m_context.getTestContext().getLog()
- << tcu::TestLog::Message << "Invalid value: " << (GLint)drawn_red << ", " << (GLint)drawn_green
- << ". Expected value: " << (GLint)expected_red << ", " << (GLint)expected_green
- << ". At offset: " << i << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value: " << (GLint)drawn_red << ", "
+ << (GLint)drawn_green << ". Expected value: " << (GLint)expected_red << ", "
+ << (GLint)expected_green << ". At offset: " << i << tcu::TestLog::EndMessage;
result = false;
break;
Texture::Bind(gl, texture_id, GL_TEXTURE_2D);
- std::vector<GLfloat> pixels;
- pixels.resize(n_pixels * n_channels);
+ std::vector<GLfloat> pixels(n_pixels * n_channels);
for (GLuint i = 0; i < n_pixels; ++i)
{
- pixels[i * n_channels + 0] = (GLfloat)i / (GLfloat)n_pixels;
- pixels[i * n_channels + 1] = (GLfloat)i / (GLfloat)n_pixels;
- pixels[i * n_channels + 2] = (GLfloat)i / (GLfloat)n_pixels;
- pixels[i * n_channels + 3] = (GLfloat)i / (GLfloat)n_pixels;
+ GLfloat value = static_cast<GLfloat>(i) / n_pixels;
+ pixels[i * n_channels + 0] = value;
+ pixels[i * n_channels + 1] = value;
+ pixels[i * n_channels + 2] = value;
+ pixels[i * n_channels + 3] = value;
}
- Texture::GetData(gl, 0 /* level */, GL_TEXTURE_2D, GL_RGBA, GL_FLOAT, &pixels[0]);
+ Texture::GetData(gl, texture_id, 0 /* level */, width, height, GL_RGBA, GL_FLOAT, &pixels[0]);
/* Unbind */
Texture::Bind(gl, 0, GL_TEXTURE_2D);
const GLfloat expected_green = (GLfloat)(i / 16) / 16.0f;
const GLfloat expected_blue = (GLfloat)i / 256.0f;
const GLfloat expected_alpha = 1.0f;
- const GLfloat drawn_red = pixels[i * n_channels + 0];
- const GLfloat drawn_green = pixels[i * n_channels + 1];
- const GLfloat drawn_blue = pixels[i * n_channels + 2];
- const GLfloat drawn_alpha = pixels[i * n_channels + 3];
+ const GLuint idx = i * n_channels;
+ const GLfloat drawn_red = pixels[idx + 0];
+ const GLfloat drawn_green = pixels[idx + 1];
+ const GLfloat drawn_blue = pixels[idx + 2];
+ const GLfloat drawn_alpha = pixels[idx + 3];
if ((expected_red != drawn_red) || (expected_green != drawn_green) || (expected_blue != drawn_blue) ||
(expected_alpha != drawn_alpha))
{
- m_context.getTestContext().getLog()
- << tcu::TestLog::Message << "Invalid value: " << drawn_red << ", " << drawn_green << ", "
- << drawn_blue << ", " << drawn_alpha << ". Expected value: " << expected_red << ", "
- << expected_green << ", " << expected_blue << ", " << expected_alpha << ". At offset: " << i
- << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value: " << drawn_red << ", " << drawn_green
+ << ", " << drawn_blue << ", " << drawn_alpha << ". Expected value: " << expected_red
+ << ", " << expected_green << ", " << expected_blue << ", " << expected_alpha
+ << ". At offset: " << i << tcu::TestLog::EndMessage;
result = false;
break;
}
else if (R32UI_MIPMAP == m_test_case)
{
- static const GLuint n_channels = 1;
+ static const GLuint n_channels = 4;
Texture::Bind(gl, texture_id, GL_TEXTURE_2D);
- std::vector<GLuint> pixels;
- pixels.resize(n_pixels * n_channels * 4);
- for (GLuint i = 0; i < n_pixels; ++i)
- {
- pixels[i] = 0;
- }
+ std::vector<GLuint> pixels(n_pixels * n_channels);
+ initPixels(pixels, n_pixels, n_channels);
- Texture::GetData(gl, 1 /* level */, GL_TEXTURE_2D, GL_RED_INTEGER, GL_UNSIGNED_INT, &pixels[0]);
+ Texture::GetData(gl, texture_id, 1 /* level */, width, height, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &pixels[0]);
/* Unbind */
Texture::Bind(gl, 0, GL_TEXTURE_2D);
for (GLuint i = 0; i < n_pixels; ++i)
{
const GLuint expected_red = i;
- const GLuint drawn_red = pixels[i];
+ const GLuint drawn_red = pixels[i * n_channels];
if (expected_red != drawn_red)
{
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid value: " << drawn_red
- << ". Expected value: " << expected_red << " at offset: " << i
- << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value: " << drawn_red
+ << ". Expected value: " << expected_red << " at offset: " << i
+ << tcu::TestLog::EndMessage;
result = false;
break;
/* Compute shader */
static const GLchar* cs =
- "#version 430 core\n"
+ "${VERSION}\n"
"\n"
"layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
"\n"
"}\n"
"\n";
- Program program(m_context);
- Texture destination_texture(m_context);
+ Program program(gl);
+ Texture destination_texture(gl);
Texture::Generate(gl, destination_texture.m_id);
Texture::Bind(gl, destination_texture.m_id, GL_TEXTURE_2D);
GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
/* Pixels buffer initialization */
- std::vector<GLuint> pixels;
- pixels.resize(n_pixels * n_channels);
- for (GLuint i = 0; i < n_pixels; ++i)
- {
- pixels[i] = i;
- }
+ std::vector<GLuint> pixels(n_pixels * n_channels);
+ initPixels(pixels, n_pixels, n_channels);
Texture::GetData(gl, 0 /* level */, GL_TEXTURE_2D, GL_RED_INTEGER, GL_UNSIGNED_INT, &pixels[0]);
if (expected_red != drawn_red)
{
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid value: " << drawn_red
- << ". Expected value: " << expected_red << " at offset: " << i
- << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value: " << drawn_red
+ << ". Expected value: " << expected_red << " at offset: " << i
+ << tcu::TestLog::EndMessage;
result = false;
break;
/** Constructor
*
- * @param context Test context
+ * @param testCtx Test context
+ * @param apiType Api type
**/
-StorageBufferTest::StorageBufferTest(deqp::Context& context)
- : TestCase(context, "storage_buffer", "Verifies that out-of-bound access to SSBO is discared or resutls in 0")
+StorageBufferTest::StorageBufferTest(tcu::TestContext& testCtx, glu::ApiType apiType)
+ : RobustnessBase(testCtx, "storage_buffer", "Verifies that out-of-bound access to SSBO is discared or resutls in 0",
+ apiType)
, m_test_case(VALID)
- , m_hasKhrRobustBufferAccess(false)
{
/* Nothing to be done here */
}
-/** Constructor
- *
- * @param context Test context
- **/
-StorageBufferTest::StorageBufferTest(deqp::Context& context, const glw::GLchar* name, const glw::GLchar* description)
- : TestCase(context, name, description), m_test_case(VALID)
-{
- /* Nothing to be done */
-}
/** Execute test
*
**/
tcu::TestNode::IterateResult StorageBufferTest::iterate()
{
- if (!isRobustBufferAccessBehaviorFeatureSupported(m_context))
+ de::SharedPtr<glu::RenderContext> robustContext(createRobustContext());
+ if (!robustContext.get())
return STOP;
/* GL entry points */
- const Functions& gl = m_context.getRenderContext().getFunctions();
-
- glu::ContextType contextType = m_context.getRenderContext().getType();
- m_hasKhrRobustBufferAccess =
- m_context.getContextInfo().isExtensionSupported("GL_KHR_robust_buffer_access_behavior") ||
- contextSupports(contextType, glu::ApiType::core(4, 5));
+ const Functions& gl = robustContext->getFunctions();
/* Test result indicator */
bool test_result = true;
while (LAST != m_test_case)
{
/* Test case objects */
- Buffer destination_buffer(m_context);
- Buffer source_buffer(m_context);
- Program program(m_context);
+ Buffer destination_buffer(gl);
+ Buffer source_buffer(gl);
+ Program program(gl);
/* Buffers initialization */
destination_buffer.InitData(GL_SHADER_STORAGE_BUFFER, GL_DYNAMIC_COPY, sizeof(m_destination_data),
/* Set result */
if (true == test_result)
{
- m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
+ m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
}
else
{
- m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+ m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
}
/* Done */
**/
std::string StorageBufferTest::getComputeShader(GLuint offset)
{
- static const GLchar* cs = "#version 430 core\n"
- "\n"
- "layout (local_size_x = 4, local_size_y = 1, local_size_z = 1) in;\n"
- "\n"
- "layout (binding = 1, std430) buffer Source {\n"
- " float data[];\n"
- "} source;\n"
- "\n"
- "layout (binding = 0, std430) buffer Destination {\n"
- " float data[];\n"
- "} destination;\n"
- "\n"
- "void main()\n"
- "{\n"
- " const uint index_destination = gl_LocalInvocationID.x + OFFSET;\n"
- " const uint index_source = gl_LocalInvocationID.x + OFFSET;\n"
- "\n"
- " destination.data[index_destination] = source.data[index_source];\n"
- "}\n"
- "\n";
-
- std::string destination_offset("0");
- std::string source_offset("0");
- size_t position = 0;
- std::string source = cs;
+ static const GLchar* source = "${VERSION}\n"
+ "\n"
+ "layout (local_size_x = 4, local_size_y = 1, local_size_z = 1) in;\n"
+ "\n"
+ "layout (binding = 1, std430) buffer Source {\n"
+ " float data[];\n"
+ "} source;\n"
+ "\n"
+ "layout (binding = 0, std430) buffer Destination {\n"
+ " float data[];\n"
+ "} destination;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " uint index_destination = gl_LocalInvocationID.x + ${DST_OFFSET}U;\n"
+ " uint index_source = gl_LocalInvocationID.x + ${SRC_OFFSET}U;\n"
+ "\n"
+ " destination.data[index_destination] = source.data[index_source];\n"
+ "}\n"
+ "\n";
std::stringstream offset_stream;
offset_stream << offset;
+ m_specializationMap["DST_OFFSET"] = "0";
+ m_specializationMap["SRC_OFFSET"] = "0";
if (m_test_case == SOURCE_INVALID)
- source_offset = offset_stream.str();
+ m_specializationMap["SRC_OFFSET"] = offset_stream.str();
else if (m_test_case == DESTINATION_INVALID)
- destination_offset = offset_stream.str();
+ m_specializationMap["DST_OFFSET"] = offset_stream.str();
- replaceToken("OFFSET", position, destination_offset.c_str(), source);
- replaceToken("OFFSET", position, source_offset.c_str(), source);
-
- return source;
+ return tcu::StringTemplate(source).specialize(m_specializationMap);
}
/** Verify test case results
static const GLfloat expected_data_invalid_source[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
static const GLfloat expected_data_invalid_destination[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
+ /* OpenGL ES has undefined out-of-bound behavior - verify only valid result*/
+ if (m_context_is_es && (m_test_case != VALID))
+ return true;
+
/* Prepare expected data const for proper case*/
const GLchar* name = 0;
bool check_expected_data = false;
break;
case SOURCE_INVALID:
name = "invalid source indices";
- if (m_hasKhrRobustBufferAccess)
+ if (m_has_khr_robust_buffer_access)
{
for (int b = 0; b < 4; b++)
{
}
if (!valid)
{
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case: " << name << " failed"
- << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Test case: " << name << " failed"
+ << tcu::TestLog::EndMessage;
}
}
}
break;
case DESTINATION_INVALID:
name = "invalid destination indices";
- if (m_hasKhrRobustBufferAccess)
+ if (m_has_khr_robust_buffer_access)
{
for (int b = 0; b < 4; b++)
{
}
if (!valid)
{
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case: " << name << " failed"
- << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Test case: " << name << " failed"
+ << tcu::TestLog::EndMessage;
}
}
}
int size = static_cast<int>(sizeof(GLfloat) * 4);
if (0 != memcmp(expected_data, buffer_data, size))
{
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case: " << name << " failed"
- << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Test case: " << name << " failed"
+ << tcu::TestLog::EndMessage;
return false;
}
}
*
* @param context Test context
**/
-UniformBufferTest::UniformBufferTest(deqp::Context& context)
- : TestCase(context, "uniform_buffer", "Verifies that out-of-bound access to UBO resutls in 0"), m_test_case(VALID)
+UniformBufferTest::UniformBufferTest(tcu::TestContext& testCtx, glu::ApiType apiType)
+ : RobustnessBase(testCtx, "uniform_buffer", "Verifies that out-of-bound access to UBO resutls in 0", apiType)
+ , m_test_case(VALID)
{
/* Nothing to be done here */
}
-/** Constructor
- *
- * @param context Test context
- **/
-UniformBufferTest::UniformBufferTest(deqp::Context& context, const glw::GLchar* name, const glw::GLchar* description)
- : TestCase(context, name, description), m_test_case(VALID)
-{
- /* Nothing to be done */
-}
-
/** Execute test
*
* @return tcu::TestNode::STOP
**/
tcu::TestNode::IterateResult UniformBufferTest::iterate()
{
- if (!isRobustBufferAccessBehaviorFeatureSupported(m_context))
+ de::SharedPtr<glu::RenderContext> robustContext(createRobustContext());
+ if (!robustContext.get())
return STOP;
static const GLfloat destination_data[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
};
/* GL entry points */
- const Functions& gl = m_context.getRenderContext().getFunctions();
+ const Functions& gl = robustContext->getFunctions();
/* Test result indicator */
bool test_result = true;
while (LAST != m_test_case)
{
/* Test case objects */
- Buffer destination_buffer(m_context);
- Buffer source_buffer(m_context);
- Program program(m_context);
+ Buffer destination_buffer(gl);
+ Buffer source_buffer(gl);
+ Program program(gl);
/* Buffers initialization */
destination_buffer.InitData(GL_SHADER_STORAGE_BUFFER, GL_DYNAMIC_COPY, sizeof(destination_data),
/* Set result */
if (true == test_result)
{
- m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
+ m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
}
else
{
- m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+ m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
}
/* Done */
**/
std::string UniformBufferTest::getComputeShader(GLuint offset)
{
- static const GLchar* cs = "#version 430 core\n"
- "\n"
- "layout (local_size_x = 4, local_size_y = 1, local_size_z = 1) in;\n"
- "\n"
- "layout (binding = 0, std140) uniform Source {\n"
- " float data[16];\n"
- "} source;\n"
- "\n"
- "layout (binding = 0, std430) buffer Destination {\n"
- " float data[];\n"
- "} destination;\n"
- "\n"
- "void main()\n"
- "{\n"
- " const uint index_destination = gl_LocalInvocationID.x + OFFSET;\n"
- " const uint index_source = gl_LocalInvocationID.x + OFFSET;\n"
- "\n"
- " destination.data[index_destination] = source.data[index_source];\n"
- "}\n"
- "\n";
-
- const GLchar* destination_offset = "0";
- std::string source_offset("0");
- size_t position = 0;
- std::string source = cs;
-
- std::stringstream offset_stream;
- offset_stream << offset;
+ static const GLchar* source = "${VERSION}\n"
+ "\n"
+ "layout (local_size_x = 4, local_size_y = 1, local_size_z = 1) in;\n"
+ "\n"
+ "layout (binding = 0, std140) uniform Source {\n"
+ " float data[16];\n"
+ "} source;\n"
+ "\n"
+ "layout (binding = 0, std430) buffer Destination {\n"
+ " float data[];\n"
+ "} destination;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " uint index_destination = gl_LocalInvocationID.x;\n"
+ " uint index_source = gl_LocalInvocationID.x + ${OFFSET}U;\n"
+ "\n"
+ " destination.data[index_destination] = source.data[index_source];\n"
+ "}\n"
+ "\n";
+ m_specializationMap["OFFSET"] = "0";
if (m_test_case == SOURCE_INVALID)
- source_offset = offset_stream.str();
-
- replaceToken("OFFSET", position, destination_offset, source);
- replaceToken("OFFSET", position, source_offset.c_str(), source);
+ {
+ std::stringstream offset_stream;
+ offset_stream << offset;
+ m_specializationMap["OFFSET"] = offset_stream.str();
+ }
- return source;
+ return tcu::StringTemplate(source).specialize(m_specializationMap);
}
/** Verify test case results
/* Verify buffer data */
if (0 != memcmp(expected_data, buffer_data, size))
{
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case: " << name << " failed"
- << tcu::TestLog::EndMessage;
+ m_testCtx.getLog() << tcu::TestLog::Message << "Test case: " << name << " failed" << tcu::TestLog::EndMessage;
return false;
}
*
* @param context Rendering context.
**/
-RobustBufferAccessBehaviorTests::RobustBufferAccessBehaviorTests(deqp::Context& context)
- : TestCaseGroup(context, "robust_buffer_access_behavior",
- "Verifies \"robust buffer access behavior\" functionality")
+RobustBufferAccessBehaviorTests::RobustBufferAccessBehaviorTests(tcu::TestContext& testCtx, glu::ApiType apiType)
+ : tcu::TestCaseGroup(testCtx, "robust_buffer_access_behavior",
+ "Verifies \"robust buffer access behavior\" functionality")
+ , m_ApiType(apiType)
{
/* Left blank on purpose */
}
**/
void RobustBufferAccessBehaviorTests::init(void)
{
- addChild(new RobustBufferAccessBehavior::VertexBufferObjectsTest(m_context));
- addChild(new RobustBufferAccessBehavior::TexelFetchTest(m_context));
- addChild(new RobustBufferAccessBehavior::ImageLoadStoreTest(m_context));
- addChild(new RobustBufferAccessBehavior::StorageBufferTest(m_context));
- addChild(new RobustBufferAccessBehavior::UniformBufferTest(m_context));
+ addChild(new RobustBufferAccessBehavior::VertexBufferObjectsTest(m_testCtx, m_ApiType));
+ addChild(new RobustBufferAccessBehavior::TexelFetchTest(m_testCtx, m_ApiType));
+ addChild(new RobustBufferAccessBehavior::ImageLoadStoreTest(m_testCtx, m_ApiType));
+ addChild(new RobustBufferAccessBehavior::StorageBufferTest(m_testCtx, m_ApiType));
+ addChild(new RobustBufferAccessBehavior::UniformBufferTest(m_testCtx, m_ApiType));
}
-} /* deqp */
+} /* glcts */
+++ /dev/null
-/*-------------------------------------------------------------------------
- * OpenGL Conformance Test Suite
- * -----------------------------
- *
- * Copyright (c) 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 es32cRobustBufferAccessBehaviorTests.cpp
- * \brief Implements conformance tests for "Robust Buffer Access Behavior" functionality.
- */ /*-------------------------------------------------------------------*/
-
-#include "es32cRobustBufferAccessBehaviorTests.hpp"
-
-#include "gluContextInfo.hpp"
-#include "gluDefs.hpp"
-#include "gluStrUtil.hpp"
-#include "glwEnums.hpp"
-#include "glwFunctions.hpp"
-#include "tcuTestLog.hpp"
-
-#include <cstring>
-#include <string>
-
-using namespace glw;
-using namespace deqp::RobustBufferAccessBehavior;
-
-namespace es32cts
-{
-namespace RobustBufferAccessBehavior
-{
-/** Constructor
- *
- * @param context Test context
- **/
-VertexBufferObjectsTest::VertexBufferObjectsTest(deqp::Context& context)
- : deqp::RobustBufferAccessBehavior::VertexBufferObjectsTest(
- context, "vertex_buffer_objects", "Verifies that out-of-bound reads from VB result in zero")
-{
- /* Nothing to be done */
-}
-
-/** Prepare shader for current test case
- *
- * @return Source
- **/
-std::string VertexBufferObjectsTest::getFragmentShader()
-{
- return std::string("#version 320 es\n"
- "\n"
- "layout (location = 0) out lowp uvec4 out_fs_color;\n"
- "\n"
- "void main()\n"
- "{\n"
- " out_fs_color = uvec4(1, 255, 255, 255);\n"
- "}\n"
- "\n");
-}
-
-/** Prepare shader for current test case
- *
- * @return Source
- **/
-std::string VertexBufferObjectsTest::getVertexShader()
-{
- return std::string("#version 320 es\n"
- "\n"
- "layout (location = 0) in vec4 in_vs_position;\n"
- "\n"
- "void main()\n"
- "{\n"
- " gl_Position = in_vs_position;\n"
- "}\n"
- "\n");
-}
-
-/** No verification because of undefined out-of-bound behavior in OpenGL ES
- *
- * @param texture_id Id of texture
- *
- * @return true
- **/
-bool VertexBufferObjectsTest::verifyInvalidResults(glw::GLuint texture_id)
-{
- (void)texture_id;
- return true;
-}
-
-/** Verifies that texutre is filled with 1
- *
- * @param texture_id Id of texture
- *
- * @return true when image is filled with 1, false otherwise
- **/
-bool VertexBufferObjectsTest::verifyResults(glw::GLuint texture_id)
-{
- static const GLuint height = 8;
- static const GLuint width = 8;
- static const GLuint pixel_size = 4 * sizeof(GLuint);
-
- const Functions& gl = m_context.getRenderContext().getFunctions();
-
- const GLint buf_size = width * height * pixel_size;
- GLubyte pixels[buf_size];
- deMemset(pixels, 0, buf_size);
-
- Texture::Bind(gl, texture_id, GL_TEXTURE_2D);
-
- Texture::GetData(gl, texture_id, 0 /* level */, width, height, GL_RGBA_INTEGER, GL_UNSIGNED_INT, pixels);
-
- /* Unbind */
- Texture::Bind(gl, 0, GL_TEXTURE_2D);
-
- /* Verify */
- for (GLuint i = 0; i < buf_size; i += pixel_size)
- {
- if (1 != pixels[i])
- {
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid value: " << (GLuint)pixels[i]
- << " at offset: " << i << tcu::TestLog::EndMessage;
-
- return false;
- }
- }
-
- return true;
-}
-
-/** Constructor
- *
- * @param context Test context
- **/
-TexelFetchTest::TexelFetchTest(deqp::Context& context)
- : deqp::RobustBufferAccessBehavior::TexelFetchTest(context, "texel_fetch",
- "Verifies that out-of-bound fetches from texture result in zero")
-{
- /* Nothing to be done */
-}
-
-TexelFetchTest::TexelFetchTest(deqp::Context& context, const glw::GLchar* name, const glw::GLchar* description)
- : deqp::RobustBufferAccessBehavior::TexelFetchTest(context, name, description)
-{
- /* Nothing to be done */
-}
-
-/** Prepare shader for current test case
- *
- * @return Source
- **/
-std::string TexelFetchTest::getGeometryShader()
-{
- return std::string("#version 320 es\n"
- "\n"
- "layout(points) in;\n"
- "layout(triangle_strip, max_vertices = 4) out;\n"
- "\n"
- "out vec2 gs_fs_tex_coord;\n"
- "\n"
- "void main()\n"
- "{\n"
- " gs_fs_tex_coord = vec2(0, 0);\n"
- " gl_Position = vec4(-1, -1, 0, 1);\n"
- " EmitVertex();\n"
- "\n"
- " gs_fs_tex_coord = vec2(0, 1);\n"
- " gl_Position = vec4(-1, 1, 0, 1);\n"
- " EmitVertex();\n"
- "\n"
- " gs_fs_tex_coord = vec2(1, 0);\n"
- " gl_Position = vec4(1, -1, 0, 1);\n"
- " EmitVertex();\n"
- "\n"
- " gs_fs_tex_coord = vec2(1, 1);\n"
- " gl_Position = vec4(1, 1, 0, 1);\n"
- " EmitVertex();\n"
- "}\n"
- "\n");
-}
-
-/** Prepare shader for current test case
- *
- * @return Source
- **/
-std::string TexelFetchTest::getVertexShader()
-{
- return std::string("#version 320 es\n"
- "\n"
- "void main()\n"
- "{\n"
- " gl_Position = vec4(0, 0, 0, 1);\n"
- "}\n"
- "\n");
-}
-
-/** Prepare a texture
- *
- * @param is_source Selects if texutre will be used as source or destination
- * @param texture_id Id of texutre
- **/
-void TexelFetchTest::prepareTexture(bool is_source, glw::GLuint texture_id)
-{
- /* Image size */
- static const GLuint image_height = 16;
- static const GLuint image_width = 16;
-
- /* GL entry points */
- const Functions& gl = m_context.getRenderContext().getFunctions();
-
- /* Texture storage parameters */
- GLuint height = image_height;
- GLenum internal_format = 0;
- GLsizei n_levels = 1;
- GLenum target = GL_TEXTURE_2D;
- GLuint width = image_width;
-
- /* Prepare texture storage parameters */
- switch (m_test_case)
- {
- case R8:
- internal_format = GL_R8;
- break;
- case RG8_SNORM:
- internal_format = GL_RG8_SNORM;
- break;
- case RGBA32F:
- internal_format = GL_RGBA32F;
- break;
- case R32UI_MIPMAP:
- height = 2 * image_height;
- internal_format = GL_R32UI;
- n_levels = 2;
- width = 2 * image_width;
- break;
- case R32UI_MULTISAMPLE:
- internal_format = GL_R32UI;
- n_levels = 4;
- target = GL_TEXTURE_2D_MULTISAMPLE;
- break;
- default:
- TCU_FAIL("Invalid enum");
- }
-
- /* Prepare storage */
- Texture::Bind(gl, texture_id, target);
- Texture::Storage(gl, target, n_levels, internal_format, width, height, 0);
-
- /* Set samplers to NEAREST/NEAREST if required */
- if (R32UI_MULTISAMPLE != m_test_case)
- {
- gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- }
-
- /* Destination image can be left empty */
- if (false == is_source)
- {
- Texture::Bind(gl, 0, target);
- return;
- }
-
- /* Prepare texture */
- if (R8 == m_test_case)
- {
- GLubyte source_pixels[image_width * image_height];
- for (GLuint i = 0; i < image_width * image_height; ++i)
- {
- source_pixels[i] = (GLubyte)i;
- }
-
- Texture::SubImage(gl, GL_TEXTURE_2D, 0 /* level */, 0 /* x */, 0 /* y */, 0 /* z */, width, height,
- 0 /* depth */, GL_RED, GL_UNSIGNED_BYTE, source_pixels);
- }
- else if (RG8_SNORM == m_test_case)
- {
- static const GLuint n_components = 2;
-
- GLbyte source_pixels[image_width * image_height * n_components];
- for (GLuint i = 0; i < image_width * image_height; ++i)
- {
- source_pixels[i * n_components + 0] = (GLubyte)((i % 16));
- source_pixels[i * n_components + 1] = (GLubyte)((i / 16));
- }
-
- Texture::SubImage(gl, GL_TEXTURE_2D, 0 /* level */, 0 /* x */, 0 /* y */, 0 /* z */, width, height,
- 0 /* depth */, GL_RG, GL_BYTE, source_pixels);
- }
- else if (RGBA32F == m_test_case)
- {
- static const GLuint n_components = 4;
-
- GLfloat source_pixels[image_width * image_height * n_components];
- for (GLuint i = 0; i < image_width * image_height; ++i)
- {
- source_pixels[i * n_components + 0] = (GLfloat)(i % 16) / 16.0f;
- source_pixels[i * n_components + 1] = (GLfloat)(i / 16) / 16.0f;
- source_pixels[i * n_components + 2] = (GLfloat)i / 256.0f;
- source_pixels[i * n_components + 3] = 1.0f;
- }
-
- Texture::SubImage(gl, GL_TEXTURE_2D, 0 /* level */, 0 /* x */, 0 /* y */, 0 /* z */, width, height,
- 0 /* depth */, GL_RGBA, GL_FLOAT, source_pixels);
- }
- else if (R32UI_MIPMAP == m_test_case)
- {
- GLuint source_pixels[image_width * image_height];
- for (GLuint i = 0; i < image_width * image_height; ++i)
- {
- source_pixels[i] = i;
- }
-
- Texture::SubImage(gl, GL_TEXTURE_2D, 1 /* level */, 0 /* x */, 0 /* y */, 0 /* z */, image_width, image_height,
- 0 /* depth */, GL_RED_INTEGER, GL_UNSIGNED_INT, source_pixels);
-
- /* texelFetch() undefined if the computed level of detail is not the texture’s base level and the texture’s
- minification filter is NEAREST or LINEAR */
- gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
- }
- else if (R32UI_MULTISAMPLE == m_test_case)
- {
- /* Compute Shader */
- static const GLchar* cs = "#version 320 es\n"
- "\n"
- "layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in;\n"
- "\n"
- "layout (binding = 0, r32ui) writeonly uniform highp uimage2DMS uni_image;\n"
- "\n"
- "void main()\n"
- "{\n"
- " ivec2 point = ivec2(gl_WorkGroupID.x, gl_WorkGroupID.y);\n"
- " uint index = gl_WorkGroupID.y * 16U + gl_WorkGroupID.x;\n"
- "\n"
- " imageStore(uni_image, point, 0, uvec4(index + 0U, 0, 0, 0));\n"
- " imageStore(uni_image, point, 1, uvec4(index + 1U, 0, 0, 0));\n"
- " imageStore(uni_image, point, 2, uvec4(index + 2U, 0, 0, 0));\n"
- " imageStore(uni_image, point, 3, uvec4(index + 3U, 0, 0, 0));\n"
- "}\n"
- "\n";
-
- Program program(m_context);
- program.Init(cs, "", "", "", "", "");
- program.Use();
-
- gl.bindImageTexture(0 /* unit */, texture_id, 0 /* level */, GL_FALSE /* layered */, 0 /* layer */,
- GL_WRITE_ONLY, GL_R32UI);
- GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture");
-
- gl.dispatchCompute(16, 16, 1);
- GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
- }
-
- Texture::Bind(gl, 0, target);
-}
-
-/** No verification because of undefined out-of-bound behavior in OpenGL ES
- *
- * @param texture_id Id of texture
- *
- * @return true
- **/
-bool TexelFetchTest::verifyInvalidResults(glw::GLuint texture_id)
-{
- (void)texture_id;
- return true;
-}
-
-/** Verifies that texutre is filled with increasing values
- *
- * @param texture_id Id of texture
- *
- * @return true when image is filled with increasing values, false otherwise
- **/
-bool TexelFetchTest::verifyValidResults(glw::GLuint texture_id)
-{
- static const GLuint height = 16;
- static const GLuint width = 16;
- static const GLuint n_pixels = height * width;
-
- const Functions& gl = m_context.getRenderContext().getFunctions();
-
- bool result = true;
-
- if (R8 == m_test_case)
- {
- static const GLuint n_channels = 4;
-
- Texture::Bind(gl, texture_id, GL_TEXTURE_2D);
-
- std::vector<GLubyte> pixels;
- pixels.resize(n_pixels * n_channels);
- for (GLuint i = 0; i < n_pixels; ++i)
- {
- pixels[i] = (GLubyte)i;
- }
-
- Texture::GetData(gl, texture_id, 0 /* level */, width, height, GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]);
-
- /* Unbind */
- Texture::Bind(gl, 0, GL_TEXTURE_2D);
-
- /* Verify */
- for (GLuint i = 0; i < n_pixels; ++i)
- {
- const GLubyte expected_red = (GLubyte)i;
- const GLubyte drawn_red = pixels[i * n_channels];
-
- if (expected_red != drawn_red)
- {
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid value: " << (GLuint)drawn_red
- << ". Expected value: " << (GLuint)expected_red
- << " at offset: " << i << tcu::TestLog::EndMessage;
-
- result = false;
- break;
- }
- }
- }
- else if (RG8_SNORM == m_test_case)
- {
- static const GLuint n_channels = 4;
-
- Texture::Bind(gl, texture_id, GL_TEXTURE_2D);
-
- std::vector<GLubyte> pixels;
- pixels.resize(n_pixels * n_channels);
- for (GLuint i = 0; i < n_pixels; ++i)
- {
- pixels[i * n_channels + 0] = (GLubyte)i;
- pixels[i * n_channels + 1] = (GLubyte)i;
- }
-
- Texture::GetData(gl, texture_id, 0 /* level */, width, height, GL_RGBA, GL_BYTE, &pixels[0]);
-
- /* Unbind */
- Texture::Bind(gl, 0, GL_TEXTURE_2D);
-
- /* Verify */
- for (GLuint i = 0; i < n_pixels; ++i)
- {
- const GLbyte expected_red = (GLubyte)(i % 16);
- const GLbyte expected_green = (GLubyte)(i / 16);
- const GLbyte drawn_red = pixels[i * n_channels + 0];
- const GLbyte drawn_green = pixels[i * n_channels + 1];
-
- if ((expected_red != drawn_red) || (expected_green != drawn_green))
- {
- m_context.getTestContext().getLog()
- << tcu::TestLog::Message << "Invalid value: " << (GLint)drawn_red << ", " << (GLint)drawn_green
- << ". Expected value: " << (GLint)expected_red << ", " << (GLint)expected_green
- << ". At offset: " << i << tcu::TestLog::EndMessage;
-
- result = false;
- break;
- }
- }
- }
- else if (RGBA32F == m_test_case)
- {
- static const GLuint n_channels = 4;
-
- Texture::Bind(gl, texture_id, GL_TEXTURE_2D);
-
- std::vector<GLfloat> pixels;
- pixels.resize(n_pixels * n_channels);
- for (GLuint i = 0; i < n_pixels; ++i)
- {
- pixels[i * n_channels + 0] = (GLfloat)i / (GLfloat)n_pixels;
- pixels[i * n_channels + 1] = (GLfloat)i / (GLfloat)n_pixels;
- pixels[i * n_channels + 2] = (GLfloat)i / (GLfloat)n_pixels;
- pixels[i * n_channels + 3] = (GLfloat)i / (GLfloat)n_pixels;
- }
-
- Texture::GetData(gl, texture_id, 0 /* level */, width, height, GL_RGBA, GL_FLOAT, &pixels[0]);
-
- /* Unbind */
- Texture::Bind(gl, 0, GL_TEXTURE_2D);
-
- /* Verify */
- for (GLuint i = 0; i < n_pixels; ++i)
- {
- const GLfloat expected_red = (GLfloat)(i % 16) / 16.0f;
- const GLfloat expected_green = (GLfloat)(i / 16) / 16.0f;
- const GLfloat expected_blue = (GLfloat)i / 256.0f;
- const GLfloat expected_alpha = 1.0f;
- const GLfloat drawn_red = pixels[i * n_channels + 0];
- const GLfloat drawn_green = pixels[i * n_channels + 1];
- const GLfloat drawn_blue = pixels[i * n_channels + 2];
- const GLfloat drawn_alpha = pixels[i * n_channels + 3];
-
- if ((expected_red != drawn_red) || (expected_green != drawn_green) || (expected_blue != drawn_blue) ||
- (expected_alpha != drawn_alpha))
- {
- m_context.getTestContext().getLog()
- << tcu::TestLog::Message << "Invalid value: " << drawn_red << ", " << drawn_green << ", "
- << drawn_blue << ", " << drawn_alpha << ". Expected value: " << expected_red << ", "
- << expected_green << ", " << expected_blue << ", " << expected_alpha << ". At offset: " << i
- << tcu::TestLog::EndMessage;
-
- result = false;
- break;
- }
- }
- }
- else if (R32UI_MIPMAP == m_test_case)
- {
- static const GLuint n_channels = 4;
-
- Texture::Bind(gl, texture_id, GL_TEXTURE_2D);
-
- std::vector<GLuint> pixels;
- pixels.resize(n_pixels * n_channels);
- deMemset(&pixels[0], 0, n_pixels * n_channels * sizeof(GLuint));
-
- Texture::GetData(gl, texture_id, 1 /* level */, width, height, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &pixels[0]);
-
- /* Unbind */
- Texture::Bind(gl, 0, GL_TEXTURE_2D);
-
- /* Verify */
- for (GLuint i = 0; i < n_pixels; ++i)
- {
- const GLuint expected_red = i;
- const GLuint drawn_red = pixels[i * n_channels];
-
- if (expected_red != drawn_red)
- {
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid value: " << drawn_red
- << ". Expected value: " << expected_red << " at offset: " << i
- << tcu::TestLog::EndMessage;
-
- result = false;
- break;
- }
- }
- }
- else if (R32UI_MULTISAMPLE == m_test_case)
- {
- static const GLuint n_channels = 4;
-
- /* Compute Shader */
- static const GLchar* cs =
- "#version 320 es\n"
- "\n"
- "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
- "\n"
- "layout (binding = 1, r32ui) writeonly uniform lowp uimage2D uni_destination_image;\n"
- "layout (binding = 0, r32ui) readonly uniform lowp uimage2DMS uni_source_image;\n"
- "\n"
- "void main()\n"
- "{\n"
- " ivec2 point = ivec2(gl_WorkGroupID.x, gl_WorkGroupID.y);\n"
- " uint index = gl_WorkGroupID.y * 16U + gl_WorkGroupID.x;\n"
- "\n"
- " uvec4 color_0 = imageLoad(uni_source_image, point, 0);\n"
- " uvec4 color_1 = imageLoad(uni_source_image, point, 1);\n"
- " uvec4 color_2 = imageLoad(uni_source_image, point, 2);\n"
- " uvec4 color_3 = imageLoad(uni_source_image, point, 3);\n"
- "\n"
- " if (any(equal(uvec4(color_0.r, color_1.r, color_2.r, color_3.r), uvec4(index + 3U))))\n"
- " {\n"
- " imageStore(uni_destination_image, point, uvec4(1U));\n"
- " }\n"
- " else\n"
- " {\n"
- " imageStore(uni_destination_image, point, uvec4(0U));\n"
- " }\n"
- "}\n"
- "\n";
-
- Program program(m_context);
- Texture destination_texture(m_context);
-
- Texture::Generate(gl, destination_texture.m_id);
- Texture::Bind(gl, destination_texture.m_id, GL_TEXTURE_2D);
- Texture::Storage(gl, GL_TEXTURE_2D, 1, GL_R32UI, width, height, 0 /* depth */);
-
- program.Init(cs, "", "", "", "", "");
- program.Use();
- gl.bindImageTexture(0 /* unit */, texture_id, 0 /* level */, GL_FALSE /* layered */, 0 /* layer */,
- GL_READ_ONLY, GL_R32UI);
- GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture");
- gl.bindImageTexture(1 /* unit */, destination_texture.m_id, 0 /* level */, GL_FALSE /* layered */,
- 0 /* layer */, GL_WRITE_ONLY, GL_R32UI);
- GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture");
-
- gl.dispatchCompute(16, 16, 1);
- GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
-
- /* Pixels buffer initialization */
- std::vector<GLuint> pixels;
- pixels.resize(n_pixels * n_channels);
- for (GLuint i = 0; i < n_pixels * n_channels; ++i)
- {
- pixels[i] = i;
- }
-
- Texture::GetData(gl, destination_texture.m_id, 0 /* level */, width, height, GL_RGBA_INTEGER, GL_UNSIGNED_INT,
- &pixels[0]);
-
- /* Unbind */
- Texture::Bind(gl, 0, GL_TEXTURE_2D);
-
- /* Verify */
- for (GLuint i = 0; i < n_pixels; ++i)
- {
- const GLuint expected_red = 1;
- const GLuint drawn_red = pixels[i * n_channels];
-
- if (expected_red != drawn_red)
- {
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid value: " << drawn_red
- << ". Expected value: " << expected_red << " at offset: " << i
- << tcu::TestLog::EndMessage;
-
- result = false;
- break;
- }
- }
- }
-
- return result;
-}
-
-/** Constructor
- *
- * @param context Test context
- **/
-ImageLoadStoreTest::ImageLoadStoreTest(deqp::Context& context)
- : TexelFetchTest(context, "image_load_store", "Verifies that out-of-bound to image result in zero or is discarded")
-{
- /* start from RGBA32F as R8, R32UI_MULTISAMPLE and R8_SNORM are not supported under GLES */
- m_test_case = RGBA32F;
-}
-
-/** Execute test
- *
- * @return tcu::TestNode::STOP
- **/
-tcu::TestNode::IterateResult ImageLoadStoreTest::iterate()
-{
- if (!m_context.getContextInfo().isExtensionSupported("GL_KHR_robust_buffer_access_behavior"))
- {
- m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
- return STOP;
- }
-
- /* Constants */
- static const GLuint height = 16;
- static const GLuint width = 16;
-
- /* GL entry points */
- const Functions& gl = m_context.getRenderContext().getFunctions();
-
- const unsigned int coord_offsets[] = {
- 16, 512, 1024, 2048,
- };
-
- /* Test result indicator */
- bool test_result = true;
-
- /* Iterate over all cases */
- while (LAST != m_test_case)
- {
- /* Test case result indicator */
- bool case_result = true;
-
- /* Test case objects */
- Texture destination_texture(m_context);
- Texture source_texture(m_context);
- Program program(m_context);
-
- /* Prepare textures */
- Texture::Generate(gl, destination_texture.m_id);
- Texture::Generate(gl, source_texture.m_id);
-
- prepareTexture(false, destination_texture.m_id);
- prepareTexture(true, source_texture.m_id);
-
- /* Test invalid source cases */
- for (GLuint i = 0; i < DE_LENGTH_OF_ARRAY(coord_offsets); ++i)
- {
- const std::string& cs = getComputeShader(SOURCE_INVALID, coord_offsets[i]);
- program.Init(cs, "", "", "", "", "");
- program.Use();
-
- /* Set texture */
- setTextures(destination_texture.m_id, source_texture.m_id);
-
- /* Dispatch */
- gl.dispatchCompute(width, height, 1 /* depth */);
- GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
-
- /* Verification */
- if (false == verifyInvalidResults(destination_texture.m_id))
- {
- case_result = false;
- }
- }
-
- /* Test valid case */
- program.Init(getComputeShader(VALID), "", "", "", "", "");
- program.Use();
-
- /* Set texture */
- setTextures(destination_texture.m_id, source_texture.m_id);
-
- /* Dispatch */
- gl.dispatchCompute(width, height, 1 /* depth */);
- GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
-
- /* Verification */
- if (false == verifyValidResults(destination_texture.m_id))
- {
- case_result = false;
- }
-
- /* Test invalid destination cases */
- for (GLuint i = 0; i < DE_LENGTH_OF_ARRAY(coord_offsets); ++i)
- {
- const std::string& cs = getComputeShader(DESTINATION_INVALID, coord_offsets[i]);
- program.Init(cs, "", "", "", "", "");
- program.Use();
-
- /* Set texture */
- setTextures(destination_texture.m_id, source_texture.m_id);
-
- /* Dispatch */
- gl.dispatchCompute(width, height, 1 /* depth */);
- GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute");
-
- /* Verification */
- if (false == verifyValidResults(destination_texture.m_id))
- {
- case_result = false;
- }
- }
-
- /* Set test result */
- if (false == case_result)
- {
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case: " << getTestCaseName()
- << " failed" << tcu::TestLog::EndMessage;
-
- test_result = false;
- }
-
- /* Increment */
- m_test_case = (TEST_CASES)((GLuint)m_test_case + 1);
- }
-
- /* Set result */
- if (true == test_result)
- {
- m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
- }
- else
- {
- m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
- }
-
- /* Done */
- return tcu::TestNode::STOP;
-}
-
-/** Prepare shader for current test case
- *
- * @param version Specify which version should be prepared
- *
- * @return Source
- **/
-std::string ImageLoadStoreTest::getComputeShader(VERSION version, GLuint coord_offset)
-{
- static const GLchar* template_code =
- "#version 320 es\n"
- "\n"
- "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
- "\n"
- "layout (binding = 1, FORMAT) writeonly uniform highp IMAGE uni_destination_image;\n"
- "layout (binding = 0, FORMAT) readonly uniform highp IMAGE uni_source_image;\n"
- "\n"
- "void main()\n"
- "{\n"
- " ivec2 point_destination = ivec2(gl_WorkGroupID.xy) + ivec2(COORD_OFFSETU);\n"
- " ivec2 point_source = ivec2(gl_WorkGroupID.xy) + ivec2(COORD_OFFSETU);\n"
- "\n"
- "COPY"
- "}\n"
- "\n";
-
- static const GLchar* copy_regular = " TYPE color = imageLoad(uni_source_image, point_source);\n"
- " imageStore(uni_destination_image, point_destination, color);\n";
-
- static const GLchar* format_rgba32f = "rgba32f";
- static const GLchar* format_r32ui = "r32ui";
-
- static const GLchar* image_vec4 = "image2D";
-
- static const GLchar* image_uvec4 = "uimage2D";
-
- static const GLchar* type_vec4 = "vec4";
- static const GLchar* type_uvec4 = "uvec4";
-
- const GLchar* copy = copy_regular;
- const GLchar* format = format_rgba32f;
- const GLchar* image = image_vec4;
- const GLchar* type = type_vec4;
- const GLchar* src_coord_offset = "0";
- const GLchar* dst_coord_offset = "0";
-
- std::stringstream coord_offset_stream;
- coord_offset_stream << coord_offset;
- std::string coord_offset_str = coord_offset_stream.str();
-
- if (version == SOURCE_INVALID)
- src_coord_offset = coord_offset_str.c_str();
- else if (version == DESTINATION_INVALID)
- dst_coord_offset = coord_offset_str.c_str();
-
- switch (m_test_case)
- {
- case RGBA32F:
- format = format_rgba32f;
- break;
- case R32UI_MIPMAP:
- format = format_r32ui;
- image = image_uvec4;
- type = type_uvec4;
- break;
- default:
- TCU_FAIL("Invalid enum");
- };
-
- size_t position = 0;
- std::string source = template_code;
-
- replaceToken("FORMAT", position, format, source);
- replaceToken("IMAGE", position, image, source);
- replaceToken("FORMAT", position, format, source);
- replaceToken("IMAGE", position, image, source);
- replaceToken("COORD_OFFSET", position, dst_coord_offset, source);
- replaceToken("COORD_OFFSET", position, src_coord_offset, source);
-
- size_t temp_position = position;
- replaceToken("COPY", position, copy, source);
- position = temp_position;
-
- switch (m_test_case)
- {
- case RGBA32F:
- case R32UI_MIPMAP:
- replaceToken("TYPE", position, type, source);
- break;
- default:
- TCU_FAIL("Invalid enum");
- }
-
- return source;
-}
-
-/** Set textures as images
- *
- * @param id_destination Id of texture used as destination
- * @param id_source Id of texture used as source
- **/
-void ImageLoadStoreTest::setTextures(glw::GLuint id_destination, glw::GLuint id_source)
-{
- const Functions& gl = m_context.getRenderContext().getFunctions();
-
- GLenum format = 0;
- GLint level = 0;
-
- switch (m_test_case)
- {
- case RGBA32F:
- format = GL_RGBA32F;
- break;
- case R32UI_MIPMAP:
- format = GL_R32UI;
- level = 1;
- break;
- default:
- TCU_FAIL("Invalid enum");
- }
-
- gl.bindImageTexture(0 /* unit */, id_source, level, GL_FALSE /* layered */, 0 /* layer */, GL_READ_ONLY, format);
- GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture");
-
- gl.bindImageTexture(1 /* unit */, id_destination, level, GL_FALSE /* layered */, 0 /* layer */, GL_WRITE_ONLY,
- format);
- GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture");
-}
-
-/** No verification because of undefined out-of-bound behavior in OpenGL ES
- *
- * @param texture_id Id of texture
- *
- * @return true
- **/
-bool ImageLoadStoreTest::verifyInvalidResults(glw::GLuint texture_id)
-{
- (void)texture_id;
- return true;
-}
-
-/** Verifies that texutre is filled with increasing values
- *
- * @param texture_id Id of texture
- *
- * @return true when image is filled with increasing values, false otherwise
- **/
-bool ImageLoadStoreTest::verifyValidResults(glw::GLuint texture_id)
-{
- static const GLuint height = 16;
- static const GLuint width = 16;
- static const GLuint n_pixels = height * width;
-
- const Functions& gl = m_context.getRenderContext().getFunctions();
- gl.memoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
- GLU_EXPECT_NO_ERROR(gl.getError(), "MemoryBarrier");
-
- bool result = true;
-
- if (RGBA32F == m_test_case)
- {
- static const GLuint n_channels = 4;
-
- Texture::Bind(gl, texture_id, GL_TEXTURE_2D);
-
- std::vector<GLfloat> pixels;
- pixels.resize(n_pixels * n_channels);
- for (GLuint i = 0; i < n_pixels; ++i)
- {
- pixels[i * n_channels + 0] = (GLfloat)i / (GLfloat)n_pixels;
- pixels[i * n_channels + 1] = (GLfloat)i / (GLfloat)n_pixels;
- pixels[i * n_channels + 2] = (GLfloat)i / (GLfloat)n_pixels;
- pixels[i * n_channels + 3] = (GLfloat)i / (GLfloat)n_pixels;
- }
-
- Texture::GetData(gl, texture_id, 0 /* level */, width, height, GL_RGBA, GL_FLOAT, &pixels[0]);
-
- /* Unbind */
- Texture::Bind(gl, 0, GL_TEXTURE_2D);
-
- /* Verify */
- for (GLuint i = 0; i < n_pixels; ++i)
- {
- const GLfloat expected_red = (GLfloat)(i % 16) / 16.0f;
- const GLfloat expected_green = (GLfloat)(i / 16) / 16.0f;
- const GLfloat expected_blue = (GLfloat)i / 256.0f;
- const GLfloat expected_alpha = 1.0f;
- const GLfloat drawn_red = pixels[i * n_channels + 0];
- const GLfloat drawn_green = pixels[i * n_channels + 1];
- const GLfloat drawn_blue = pixels[i * n_channels + 2];
- const GLfloat drawn_alpha = pixels[i * n_channels + 3];
-
- if ((expected_red != drawn_red) || (expected_green != drawn_green) || (expected_blue != drawn_blue) ||
- (expected_alpha != drawn_alpha))
- {
- m_context.getTestContext().getLog()
- << tcu::TestLog::Message << "Invalid value: " << drawn_red << ", " << drawn_green << ", "
- << drawn_blue << ", " << drawn_alpha << ". Expected value: " << expected_red << ", "
- << expected_green << ", " << expected_blue << ", " << expected_alpha << ". At offset: " << i
- << tcu::TestLog::EndMessage;
-
- result = false;
- break;
- }
- }
- }
- else if (R32UI_MIPMAP == m_test_case)
- {
- static const GLuint n_channels = 4;
-
- Texture::Bind(gl, texture_id, GL_TEXTURE_2D);
-
- std::vector<GLuint> pixels;
- pixels.resize(n_pixels * n_channels);
- for (GLuint i = 0; i < n_pixels * n_channels; ++i)
- {
- pixels[i] = 0;
- }
-
- Texture::GetData(gl, texture_id, 1 /* level */, width, height, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &pixels[0]);
-
- /* Unbind */
- Texture::Bind(gl, 0, GL_TEXTURE_2D);
-
- /* Verify */
- for (GLuint i = 0; i < n_pixels; ++i)
- {
- const GLuint expected_red = i;
- const GLuint drawn_red = pixels[i * n_channels];
-
- if (expected_red != drawn_red)
- {
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid value: " << drawn_red
- << ". Expected value: " << expected_red << " at offset: " << i
- << tcu::TestLog::EndMessage;
-
- result = false;
- break;
- }
- }
- }
-
- return result;
-}
-
-/** Constructor
- *
- * @param context Test context
- **/
-StorageBufferTest::StorageBufferTest(deqp::Context& context)
- : deqp::RobustBufferAccessBehavior::StorageBufferTest(
- context, "storage_buffer", "Verifies that out-of-bound access to SSBO results with no error")
-{
- /* Nothing to be done here */
-}
-
-/** Prepare shader for current test case
- *
- * @return Source
- **/
-std::string StorageBufferTest::getComputeShader(glw::GLuint offset)
-{
- static const GLchar* cs = "#version 320 es\n"
- "\n"
- "layout (local_size_x = 4, local_size_y = 1, local_size_z = 1) in;\n"
- "\n"
- "layout (binding = 1) buffer Source {\n"
- " float data[];\n"
- "} source;\n"
- "\n"
- "layout (binding = 0) buffer Destination {\n"
- " float data[];\n"
- "} destination;\n"
- "\n"
- "void main()\n"
- "{\n"
- " uint index_destination = gl_LocalInvocationID.x + OFFSETU;\n"
- " uint index_source = gl_LocalInvocationID.x + OFFSETU;\n"
- "\n"
- " destination.data[index_destination] = source.data[index_source];\n"
- "}\n"
- "\n";
-
- std::string destination_offset("0");
- std::string source_offset("0");
- size_t position = 0;
- std::string source = cs;
-
- std::stringstream offset_stream;
- offset_stream << offset;
-
- if (m_test_case == SOURCE_INVALID)
- source_offset = offset_stream.str();
- else if (m_test_case == DESTINATION_INVALID)
- destination_offset = offset_stream.str();
-
- replaceToken("OFFSET", position, destination_offset.c_str(), source);
- replaceToken("OFFSET", position, source_offset.c_str(), source);
-
- return source;
-}
-
-/** Verify test case results
- *
- * @param buffer_data Buffer data to verify
- *
- * @return true if buffer_data is as expected, false othrewise
- **/
-bool StorageBufferTest::verifyResults(GLfloat* buffer_data)
-{
- static const GLfloat expected_data_valid[4] = { 2.0f, 3.0f, 4.0f, 5.0f };
- static const GLfloat expected_data_invalid_destination[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
- static const GLfloat expected_data_invalid_source[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
-
- int size = sizeof(GLfloat) * 4;
-
- /* Prepare expected data const for proper case*/
- const GLfloat* expected_data = 0;
- const GLchar* name = 0;
- switch (m_test_case)
- {
- case VALID:
- expected_data = expected_data_valid;
- name = "valid indices";
- break;
- case SOURCE_INVALID:
- expected_data = expected_data_invalid_source;
- name = "invalid source indices";
- break;
- case DESTINATION_INVALID:
- expected_data = expected_data_invalid_destination;
- name = "invalid destination indices";
- break;
- default:
- TCU_FAIL("Invalid enum");
- }
-
- /* Verify buffer data */
- if (m_test_case == VALID && memcmp(expected_data, buffer_data, size) != 0)
- {
- m_context.getTestContext().getLog() << tcu::TestLog::Message << "Test case: " << name << " failed"
- << tcu::TestLog::EndMessage;
- return false;
- }
-
- return true;
-}
-
-/** Constructor
- *
- * @param context Test context
- **/
-UniformBufferTest::UniformBufferTest(deqp::Context& context)
- : deqp::RobustBufferAccessBehavior::UniformBufferTest(
- context, "uniform_buffer", "Verifies that out-of-bound access to UBO resutls with no error")
-{
- /* Nothing to be done here */
-}
-
-/** Prepare shader for current test case
- *
- * @return Source
- **/
-std::string UniformBufferTest::getComputeShader(GLuint offset)
-{
- static const GLchar* cs = "#version 320 es\n"
- "\n"
- "layout (local_size_x = 4, local_size_y = 1, local_size_z = 1) in;\n"
- "\n"
- "layout (binding = 0, std140) uniform Source {\n"
- " float data[16];\n"
- "} source;\n"
- "\n"
- "layout (binding = 0, std430) buffer Destination {\n"
- " float data[];\n"
- "} destination;\n"
- "\n"
- "void main()\n"
- "{\n"
- " uint index_destination = gl_LocalInvocationID.x + OFFSETU;\n"
- " uint index_source = gl_LocalInvocationID.x + OFFSETU;\n"
- "\n"
- " destination.data[index_destination] = source.data[index_source];\n"
- "}\n"
- "\n";
-
- const GLchar* destination_offset = "0";
- std::string source_offset("0");
- size_t position = 0;
- std::string source = cs;
-
- std::stringstream offset_stream;
- offset_stream << offset;
-
- if (m_test_case == SOURCE_INVALID)
- source_offset = offset_stream.str();
-
- replaceToken("OFFSET", position, destination_offset, source);
- replaceToken("OFFSET", position, source_offset.c_str(), source);
-
- return source;
-}
-
-} /* RobustBufferAccessBehavior */
-
-/** Constructor.
- *
- * @param context Rendering context.
- **/
-RobustBufferAccessBehaviorTests::RobustBufferAccessBehaviorTests(deqp::Context& context)
- : deqp::RobustBufferAccessBehaviorTests(context)
-{
- /* Left blank on purpose */
-}
-
-/** Initializes a multi_bind test group.
- *
- **/
-void RobustBufferAccessBehaviorTests::init(void)
-{
- addChild(new RobustBufferAccessBehavior::VertexBufferObjectsTest(m_context));
- addChild(new RobustBufferAccessBehavior::TexelFetchTest(m_context));
- addChild(new RobustBufferAccessBehavior::ImageLoadStoreTest(m_context));
- addChild(new RobustBufferAccessBehavior::StorageBufferTest(m_context));
- addChild(new RobustBufferAccessBehavior::UniformBufferTest(m_context));
-}
-
-} /* es32cts namespace */