/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/.deps/blob_test.Po |
---|
0,0 → 1,0 |
# dummy |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/.deps/builtin_variable_test.Po |
---|
0,0 → 1,0 |
# dummy |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/.deps/common.Po |
---|
0,0 → 1,0 |
# dummy |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/.deps/copy_constant_to_storage_tests.Po |
---|
0,0 → 1,0 |
# dummy |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/.deps/general_ir_test.Po |
---|
0,0 → 1,0 |
# dummy |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/.deps/invalidate_locations_test.Po |
---|
0,0 → 1,0 |
# dummy |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/.deps/sampler_types_test.Po |
---|
0,0 → 1,0 |
# dummy |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/.deps/set_uniform_initializer_tests.Po |
---|
0,0 → 1,0 |
# dummy |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/.deps/tests_general_ir_test-common.Po |
---|
0,0 → 1,0 |
# dummy |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/.deps/tests_sampler_types_test-common.Po |
---|
0,0 → 1,0 |
# dummy |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/.deps/tests_uniform_initializer_test-common.Po |
---|
0,0 → 1,0 |
# dummy |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/.deps/uniform_initializer_utils.Po |
---|
0,0 → 1,0 |
# dummy |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/.deps/varyings_test.Po |
---|
0,0 → 1,0 |
# dummy |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/blob_test.c |
---|
0,0 → 1,320 |
/* |
* Copyright © 2014 Intel Corporation |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice (including the next |
* paragraph) shall be included in all copies or substantial portions of the |
* Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
* IN THE SOFTWARE. |
*/ |
/* A collection of unit tests for blob.c */ |
#include <stdio.h> |
#include <stdlib.h> |
#include <stdbool.h> |
#include <string.h> |
#include "util/ralloc.h" |
#include "blob.h" |
#define bytes_test_str "bytes_test" |
#define reserve_test_str "reserve_test" |
/* This placeholder must be the same length as the next overwrite_test_str */ |
#define placeholder_str "XXXXXXXXXXXXXX" |
#define overwrite_test_str "overwrite_test" |
#define uint32_test 0x12345678 |
#define uint32_placeholder 0xDEADBEEF |
#define uint32_overwrite 0xA1B2C3D4 |
#define uint64_test 0x1234567890ABCDEF |
#define string_test_str "string_test" |
bool error = false; |
static void |
expect_equal(uint64_t expected, uint64_t actual, const char *test) |
{ |
if (actual != expected) { |
fprintf (stderr, "Error: Test '%s' failed: Expected=%ld, Actual=%ld\n", |
test, expected, actual); |
error = true; |
} |
} |
static void |
expect_unequal(uint64_t expected, uint64_t actual, const char *test) |
{ |
if (actual == expected) { |
fprintf (stderr, "Error: Test '%s' failed: Result=%ld, but expected something different.\n", |
test, actual); |
error = true; |
} |
} |
static void |
expect_equal_str(const char *expected, const char *actual, const char *test) |
{ |
if (strcmp(expected, actual)) { |
fprintf (stderr, "Error: Test '%s' failed:\n\t" |
"Expected=\"%s\", Actual=\"%s\"\n", |
test, expected, actual); |
error = true; |
} |
} |
static void |
expect_equal_bytes(uint8_t *expected, uint8_t *actual, |
size_t num_bytes, const char *test) |
{ |
size_t i; |
if (memcmp(expected, actual, num_bytes)) { |
fprintf (stderr, "Error: Test '%s' failed:\n\t", test); |
fprintf (stderr, "Expected=["); |
for (i = 0; i < num_bytes; i++) { |
if (i != 0) |
fprintf(stderr, ", "); |
fprintf(stderr, "0x%02x", expected[i]); |
} |
fprintf (stderr, "]"); |
fprintf (stderr, "Actual=["); |
for (i = 0; i < num_bytes; i++) { |
if (i != 0) |
fprintf(stderr, ", "); |
fprintf(stderr, "0x%02x", actual[i]); |
} |
fprintf (stderr, "]\n"); |
error = true; |
} |
} |
/* Test at least one call of each blob_write_foo and blob_read_foo function, |
* verifying that we read out everything we wrote, that every bytes is |
* consumed, and that the overrun bit is not set. |
*/ |
static void |
test_write_and_read_functions (void) |
{ |
void *ctx = ralloc_context(NULL); |
struct blob *blob; |
struct blob_reader reader; |
uint8_t *reserved; |
size_t str_offset, uint_offset; |
uint8_t reserve_buf[sizeof(reserve_test_str)]; |
blob = blob_create(ctx); |
/*** Test blob by writing one of every possible kind of value. */ |
blob_write_bytes(blob, bytes_test_str, sizeof(bytes_test_str)); |
reserved = blob_reserve_bytes(blob, sizeof(reserve_test_str)); |
memcpy(reserved, reserve_test_str, sizeof(reserve_test_str)); |
/* Write a placeholder, (to be replaced later via overwrite_bytes) */ |
str_offset = blob->size; |
blob_write_bytes(blob, placeholder_str, sizeof(placeholder_str)); |
blob_write_uint32(blob, uint32_test); |
/* Write a placeholder, (to be replaced later via overwrite_uint32) */ |
uint_offset = blob->size; |
blob_write_uint32(blob, uint32_placeholder); |
blob_write_uint64(blob, uint64_test); |
blob_write_intptr(blob, (intptr_t) blob); |
blob_write_string(blob, string_test_str); |
/* Finally, overwrite our placeholders. */ |
blob_overwrite_bytes(blob, str_offset, overwrite_test_str, |
sizeof(overwrite_test_str)); |
blob_overwrite_uint32(blob, uint_offset, uint32_overwrite); |
/*** Now read each value and verify. */ |
blob_reader_init(&reader, blob->data, blob->size); |
expect_equal_str(bytes_test_str, |
blob_read_bytes(&reader, sizeof(bytes_test_str)), |
"blob_write/read_bytes"); |
blob_copy_bytes(&reader, reserve_buf, sizeof(reserve_buf)); |
expect_equal_str(reserve_test_str, (char *) reserve_buf, |
"blob_reserve_bytes/blob_copy_bytes"); |
expect_equal_str(overwrite_test_str, |
blob_read_bytes(&reader, sizeof(overwrite_test_str)), |
"blob_overwrite_bytes"); |
expect_equal(uint32_test, blob_read_uint32(&reader), |
"blob_write/read_uint32"); |
expect_equal(uint32_overwrite, blob_read_uint32(&reader), |
"blob_overwrite_uint32"); |
expect_equal(uint64_test, blob_read_uint64(&reader), |
"blob_write/read_uint64"); |
expect_equal((intptr_t) blob, blob_read_intptr(&reader), |
"blob_write/read_intptr"); |
expect_equal_str(string_test_str, blob_read_string(&reader), |
"blob_write/read_string"); |
expect_equal(reader.end - reader.data, reader.current - reader.data, |
"read_consumes_all_bytes"); |
expect_equal(false, reader.overrun, "read_does_not_overrun"); |
ralloc_free(ctx); |
} |
/* Test that data values are written and read with proper alignment. */ |
static void |
test_alignment(void) |
{ |
void *ctx = ralloc_context(NULL); |
struct blob *blob; |
struct blob_reader reader; |
uint8_t bytes[] = "ABCDEFGHIJKLMNOP"; |
size_t delta, last, num_bytes; |
blob = blob_create(ctx); |
/* First, write an intptr value to the blob and capture that size. This is |
* the expected offset between any pair of intptr values (if written with |
* alignment). |
*/ |
blob_write_intptr(blob, (intptr_t) blob); |
delta = blob->size; |
last = blob->size; |
/* Then loop doing the following: |
* |
* 1. Write an unaligned number of bytes |
* 2. Verify that write results in an unaligned size |
* 3. Write an intptr_t value |
* 2. Verify that that write results in an aligned size |
*/ |
for (num_bytes = 1; num_bytes < sizeof(intptr_t); num_bytes++) { |
blob_write_bytes(blob, bytes, num_bytes); |
expect_unequal(delta, blob->size - last, "unaligned write of bytes"); |
blob_write_intptr(blob, (intptr_t) blob); |
expect_equal(2 * delta, blob->size - last, "aligned write of intptr"); |
last = blob->size; |
} |
/* Finally, test that reading also does proper alignment. Since we know |
* that values were written with all the right alignment, all we have to do |
* here is verify that correct values are read. |
*/ |
blob_reader_init(&reader, blob->data, blob->size); |
expect_equal((intptr_t) blob, blob_read_intptr(&reader), |
"read of initial, aligned intptr_t"); |
for (num_bytes = 1; num_bytes < sizeof(intptr_t); num_bytes++) { |
expect_equal_bytes(bytes, blob_read_bytes(&reader, num_bytes), |
num_bytes, "unaligned read of bytes"); |
expect_equal((intptr_t) blob, blob_read_intptr(&reader), |
"aligned read of intptr_t"); |
} |
ralloc_free(ctx); |
} |
/* Test that we detect overrun. */ |
static void |
test_overrun(void) |
{ |
void *ctx =ralloc_context(NULL); |
struct blob *blob; |
struct blob_reader reader; |
uint32_t value = 0xdeadbeef; |
blob = blob_create(ctx); |
blob_write_uint32(blob, value); |
blob_reader_init(&reader, blob->data, blob->size); |
expect_equal(value, blob_read_uint32(&reader), "read before overrun"); |
expect_equal(false, reader.overrun, "overrun flag not set"); |
expect_equal(0, blob_read_uint32(&reader), "read at overrun"); |
expect_equal(true, reader.overrun, "overrun flag set"); |
ralloc_free(ctx); |
} |
/* Test that we can read and write some large objects, (exercising the code in |
* the blob_write functions to realloc blob->data. |
*/ |
static void |
test_big_objects(void) |
{ |
void *ctx = ralloc_context(NULL); |
struct blob *blob; |
struct blob_reader reader; |
int size = 1000; |
int count = 1000; |
size_t i; |
char *buf; |
blob = blob_create(ctx); |
/* Initialize our buffer. */ |
buf = ralloc_size(ctx, size); |
for (i = 0; i < size; i++) { |
buf[i] = i % 256; |
} |
/* Write it many times. */ |
for (i = 0; i < count; i++) { |
blob_write_bytes(blob, buf, size); |
} |
blob_reader_init(&reader, blob->data, blob->size); |
/* Read and verify it many times. */ |
for (i = 0; i < count; i++) { |
expect_equal_bytes((uint8_t *) buf, blob_read_bytes(&reader, size), size, |
"read of large objects"); |
} |
expect_equal(reader.end - reader.data, reader.current - reader.data, |
"number of bytes read reading large objects"); |
expect_equal(false, reader.overrun, |
"overrun flag not set reading large objects"); |
ralloc_free(ctx); |
} |
int |
main (void) |
{ |
test_write_and_read_functions (); |
test_alignment (); |
test_overrun (); |
test_big_objects (); |
return error ? 1 : 0; |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/builtin_variable_test.cpp |
---|
0,0 → 1,393 |
/* |
* Copyright © 2013 Intel Corporation |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice (including the next |
* paragraph) shall be included in all copies or substantial portions of the |
* Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
* DEALINGS IN THE SOFTWARE. |
*/ |
#include <gtest/gtest.h> |
#include "standalone_scaffolding.h" |
#include "main/compiler.h" |
#include "main/mtypes.h" |
#include "main/macros.h" |
#include "ir.h" |
#include "glsl_parser_extras.h" |
#include "glsl_symbol_table.h" |
class common_builtin : public ::testing::Test { |
public: |
common_builtin(GLenum shader_type) |
: shader_type(shader_type) |
{ |
/* empty */ |
} |
virtual void SetUp(); |
virtual void TearDown(); |
void string_starts_with_prefix(const char *str, const char *prefix); |
void names_start_with_gl(); |
void uniforms_and_system_values_dont_have_explicit_location(); |
void constants_are_constant(); |
void no_invalid_variable_modes(); |
GLenum shader_type; |
struct _mesa_glsl_parse_state *state; |
struct gl_shader *shader; |
void *mem_ctx; |
gl_context ctx; |
exec_list ir; |
}; |
void |
common_builtin::SetUp() |
{ |
this->mem_ctx = ralloc_context(NULL); |
this->ir.make_empty(); |
initialize_context_to_defaults(&this->ctx, API_OPENGL_COMPAT); |
this->shader = rzalloc(this->mem_ctx, gl_shader); |
this->shader->Type = this->shader_type; |
this->shader->Stage = _mesa_shader_enum_to_shader_stage(this->shader_type); |
this->state = |
new(mem_ctx) _mesa_glsl_parse_state(&this->ctx, this->shader->Stage, |
this->shader); |
_mesa_glsl_initialize_types(this->state); |
_mesa_glsl_initialize_variables(&this->ir, this->state); |
} |
void |
common_builtin::TearDown() |
{ |
ralloc_free(this->mem_ctx); |
this->mem_ctx = NULL; |
} |
void |
common_builtin::string_starts_with_prefix(const char *str, const char *prefix) |
{ |
const size_t len = strlen(prefix); |
char *const name_prefix = new char[len + 1]; |
strncpy(name_prefix, str, len); |
name_prefix[len] = '\0'; |
EXPECT_STREQ(prefix, name_prefix) << "Bad name " << str; |
delete [] name_prefix; |
} |
void |
common_builtin::names_start_with_gl() |
{ |
foreach_in_list(ir_instruction, node, &this->ir) { |
ir_variable *const var = node->as_variable(); |
string_starts_with_prefix(var->name, "gl_"); |
} |
} |
void |
common_builtin::uniforms_and_system_values_dont_have_explicit_location() |
{ |
foreach_in_list(ir_instruction, node, &this->ir) { |
ir_variable *const var = node->as_variable(); |
if (var->data.mode != ir_var_uniform && var->data.mode != ir_var_system_value) |
continue; |
EXPECT_FALSE(var->data.explicit_location); |
EXPECT_EQ(-1, var->data.location); |
} |
} |
void |
common_builtin::constants_are_constant() |
{ |
foreach_in_list(ir_instruction, node, &this->ir) { |
ir_variable *const var = node->as_variable(); |
if (var->data.mode != ir_var_auto) |
continue; |
EXPECT_FALSE(var->data.explicit_location); |
EXPECT_EQ(-1, var->data.location); |
EXPECT_TRUE(var->data.read_only); |
} |
} |
void |
common_builtin::no_invalid_variable_modes() |
{ |
foreach_in_list(ir_instruction, node, &this->ir) { |
ir_variable *const var = node->as_variable(); |
switch (var->data.mode) { |
case ir_var_auto: |
case ir_var_uniform: |
case ir_var_shader_in: |
case ir_var_shader_out: |
case ir_var_system_value: |
break; |
default: |
ADD_FAILURE() << "Built-in variable " << var->name |
<< " has an invalid mode " << int(var->data.mode); |
break; |
} |
} |
} |
/************************************************************/ |
class vertex_builtin : public common_builtin { |
public: |
vertex_builtin() |
: common_builtin(GL_VERTEX_SHADER) |
{ |
/* empty */ |
} |
}; |
TEST_F(vertex_builtin, names_start_with_gl) |
{ |
common_builtin::names_start_with_gl(); |
} |
TEST_F(vertex_builtin, inputs_have_explicit_location) |
{ |
foreach_in_list(ir_instruction, node, &this->ir) { |
ir_variable *const var = node->as_variable(); |
if (var->data.mode != ir_var_shader_in) |
continue; |
EXPECT_TRUE(var->data.explicit_location); |
EXPECT_NE(-1, var->data.location); |
EXPECT_GT(VERT_ATTRIB_GENERIC0, var->data.location); |
EXPECT_EQ(0u, var->data.location_frac); |
} |
} |
TEST_F(vertex_builtin, outputs_have_explicit_location) |
{ |
foreach_in_list(ir_instruction, node, &this->ir) { |
ir_variable *const var = node->as_variable(); |
if (var->data.mode != ir_var_shader_out) |
continue; |
EXPECT_TRUE(var->data.explicit_location); |
EXPECT_NE(-1, var->data.location); |
EXPECT_GT(VARYING_SLOT_VAR0, var->data.location); |
EXPECT_EQ(0u, var->data.location_frac); |
/* Several varyings only exist in the fragment shader. Be sure that no |
* outputs with these locations exist. |
*/ |
EXPECT_NE(VARYING_SLOT_PNTC, var->data.location); |
EXPECT_NE(VARYING_SLOT_FACE, var->data.location); |
EXPECT_NE(VARYING_SLOT_PRIMITIVE_ID, var->data.location); |
} |
} |
TEST_F(vertex_builtin, uniforms_and_system_values_dont_have_explicit_location) |
{ |
common_builtin::uniforms_and_system_values_dont_have_explicit_location(); |
} |
TEST_F(vertex_builtin, constants_are_constant) |
{ |
common_builtin::constants_are_constant(); |
} |
TEST_F(vertex_builtin, no_invalid_variable_modes) |
{ |
common_builtin::no_invalid_variable_modes(); |
} |
/********************************************************************/ |
class fragment_builtin : public common_builtin { |
public: |
fragment_builtin() |
: common_builtin(GL_FRAGMENT_SHADER) |
{ |
/* empty */ |
} |
}; |
TEST_F(fragment_builtin, names_start_with_gl) |
{ |
common_builtin::names_start_with_gl(); |
} |
TEST_F(fragment_builtin, inputs_have_explicit_location) |
{ |
foreach_in_list(ir_instruction, node, &this->ir) { |
ir_variable *const var = node->as_variable(); |
if (var->data.mode != ir_var_shader_in) |
continue; |
EXPECT_TRUE(var->data.explicit_location); |
EXPECT_NE(-1, var->data.location); |
EXPECT_GT(VARYING_SLOT_VAR0, var->data.location); |
EXPECT_EQ(0u, var->data.location_frac); |
/* Several varyings only exist in the vertex / geometry shader. Be sure |
* that no inputs with these locations exist. |
*/ |
EXPECT_TRUE(_mesa_varying_slot_in_fs((gl_varying_slot) var->data.location)); |
} |
} |
TEST_F(fragment_builtin, outputs_have_explicit_location) |
{ |
foreach_in_list(ir_instruction, node, &this->ir) { |
ir_variable *const var = node->as_variable(); |
if (var->data.mode != ir_var_shader_out) |
continue; |
EXPECT_TRUE(var->data.explicit_location); |
EXPECT_NE(-1, var->data.location); |
/* gl_FragData[] has location FRAG_RESULT_DATA0. Locations beyond that |
* are invalid. |
*/ |
EXPECT_GE(FRAG_RESULT_DATA0, var->data.location); |
EXPECT_EQ(0u, var->data.location_frac); |
} |
} |
TEST_F(fragment_builtin, uniforms_and_system_values_dont_have_explicit_location) |
{ |
common_builtin::uniforms_and_system_values_dont_have_explicit_location(); |
} |
TEST_F(fragment_builtin, constants_are_constant) |
{ |
common_builtin::constants_are_constant(); |
} |
TEST_F(fragment_builtin, no_invalid_variable_modes) |
{ |
common_builtin::no_invalid_variable_modes(); |
} |
/********************************************************************/ |
class geometry_builtin : public common_builtin { |
public: |
geometry_builtin() |
: common_builtin(GL_GEOMETRY_SHADER) |
{ |
/* empty */ |
} |
}; |
TEST_F(geometry_builtin, names_start_with_gl) |
{ |
common_builtin::names_start_with_gl(); |
} |
TEST_F(geometry_builtin, inputs_have_explicit_location) |
{ |
foreach_in_list(ir_instruction, node, &this->ir) { |
ir_variable *const var = node->as_variable(); |
if (var->data.mode != ir_var_shader_in) |
continue; |
if (var->is_interface_instance()) { |
EXPECT_STREQ("gl_in", var->name); |
EXPECT_FALSE(var->data.explicit_location); |
EXPECT_EQ(-1, var->data.location); |
ASSERT_TRUE(var->type->is_array()); |
const glsl_type *const instance_type = var->type->fields.array; |
for (unsigned i = 0; i < instance_type->length; i++) { |
const glsl_struct_field *const input = |
&instance_type->fields.structure[i]; |
string_starts_with_prefix(input->name, "gl_"); |
EXPECT_NE(-1, input->location); |
EXPECT_GT(VARYING_SLOT_VAR0, input->location); |
/* Several varyings only exist in the fragment shader. Be sure |
* that no inputs with these locations exist. |
*/ |
EXPECT_NE(VARYING_SLOT_PNTC, input->location); |
EXPECT_NE(VARYING_SLOT_FACE, input->location); |
} |
} else { |
EXPECT_TRUE(var->data.explicit_location); |
EXPECT_NE(-1, var->data.location); |
EXPECT_GT(VARYING_SLOT_VAR0, var->data.location); |
EXPECT_EQ(0u, var->data.location_frac); |
} |
/* Several varyings only exist in the fragment shader. Be sure that no |
* inputs with these locations exist. |
*/ |
EXPECT_NE(VARYING_SLOT_PNTC, var->data.location); |
EXPECT_NE(VARYING_SLOT_FACE, var->data.location); |
} |
} |
TEST_F(geometry_builtin, outputs_have_explicit_location) |
{ |
foreach_in_list(ir_instruction, node, &this->ir) { |
ir_variable *const var = node->as_variable(); |
if (var->data.mode != ir_var_shader_out) |
continue; |
EXPECT_TRUE(var->data.explicit_location); |
EXPECT_NE(-1, var->data.location); |
EXPECT_GT(VARYING_SLOT_VAR0, var->data.location); |
EXPECT_EQ(0u, var->data.location_frac); |
/* Several varyings only exist in the fragment shader. Be sure that no |
* outputs with these locations exist. |
*/ |
EXPECT_NE(VARYING_SLOT_PNTC, var->data.location); |
EXPECT_NE(VARYING_SLOT_FACE, var->data.location); |
} |
} |
TEST_F(geometry_builtin, uniforms_and_system_values_dont_have_explicit_location) |
{ |
common_builtin::uniforms_and_system_values_dont_have_explicit_location(); |
} |
TEST_F(geometry_builtin, constants_are_constant) |
{ |
common_builtin::constants_are_constant(); |
} |
TEST_F(geometry_builtin, no_invalid_variable_modes) |
{ |
common_builtin::no_invalid_variable_modes(); |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/common.c |
---|
0,0 → 1,30 |
/* |
* Copyright © 2014 Intel Corporation |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice (including the next |
* paragraph) shall be included in all copies or substantial portions of the |
* Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
* DEALINGS IN THE SOFTWARE. |
*/ |
#include <stdio.h> |
#include "main/errors.h" |
void |
_mesa_error_no_memory(const char *caller) |
{ |
fprintf(stderr, "Mesa error: out of memory in %s", caller); |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/compare_ir |
---|
0,0 → 1,59 |
#!/usr/bin/env python |
# coding=utf-8 |
# |
# Copyright © 2011 Intel Corporation |
# |
# Permission is hereby granted, free of charge, to any person obtaining a |
# copy of this software and associated documentation files (the "Software"), |
# to deal in the Software without restriction, including without limitation |
# the rights to use, copy, modify, merge, publish, distribute, sublicense, |
# and/or sell copies of the Software, and to permit persons to whom the |
# Software is furnished to do so, subject to the following conditions: |
# |
# The above copyright notice and this permission notice (including the next |
# paragraph) shall be included in all copies or substantial portions of the |
# Software. |
# |
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
# DEALINGS IN THE SOFTWARE. |
# Compare two files containing IR code. Ignore formatting differences |
# and declaration order. |
import os |
import os.path |
import subprocess |
import sys |
import tempfile |
from sexps import * |
if len(sys.argv) != 3: |
print 'Usage: compare_ir <file1> <file2>' |
exit(1) |
with open(sys.argv[1]) as f: |
ir1 = sort_decls(parse_sexp(f.read())) |
with open(sys.argv[2]) as f: |
ir2 = sort_decls(parse_sexp(f.read())) |
if ir1 == ir2: |
exit(0) |
else: |
file1, path1 = tempfile.mkstemp(os.path.basename(sys.argv[1])) |
file2, path2 = tempfile.mkstemp(os.path.basename(sys.argv[2])) |
try: |
os.write(file1, '{0}\n'.format(sexp_to_string(ir1))) |
os.close(file1) |
os.write(file2, '{0}\n'.format(sexp_to_string(ir2))) |
os.close(file2) |
subprocess.call(['diff', '-u', path1, path2]) |
finally: |
os.remove(path1) |
os.remove(path2) |
exit(1) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/copy_constant_to_storage_tests.cpp |
---|
0,0 → 1,300 |
/* |
* Copyright © 2012 Intel Corporation |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice (including the next |
* paragraph) shall be included in all copies or substantial portions of the |
* Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
* DEALINGS IN THE SOFTWARE. |
*/ |
#include <gtest/gtest.h> |
#include "main/compiler.h" |
#include "main/mtypes.h" |
#include "main/macros.h" |
#include "util/ralloc.h" |
#include "uniform_initializer_utils.h" |
namespace linker { |
extern void |
copy_constant_to_storage(union gl_constant_value *storage, |
const ir_constant *val, |
const enum glsl_base_type base_type, |
const unsigned int elements, |
unsigned int boolean_true); |
} |
class copy_constant_to_storage : public ::testing::Test { |
public: |
void int_test(unsigned rows); |
void uint_test(unsigned rows); |
void bool_test(unsigned rows); |
void sampler_test(); |
void float_test(unsigned columns, unsigned rows); |
virtual void SetUp(); |
virtual void TearDown(); |
gl_constant_value storage[17]; |
void *mem_ctx; |
}; |
void |
copy_constant_to_storage::SetUp() |
{ |
this->mem_ctx = ralloc_context(NULL); |
} |
void |
copy_constant_to_storage::TearDown() |
{ |
ralloc_free(this->mem_ctx); |
this->mem_ctx = NULL; |
} |
void |
copy_constant_to_storage::int_test(unsigned rows) |
{ |
ir_constant *val; |
generate_data(mem_ctx, GLSL_TYPE_INT, 1, rows, val); |
const unsigned red_zone_size = ARRAY_SIZE(storage) - val->type->components(); |
fill_storage_array_with_sentinels(storage, |
val->type->components(), |
red_zone_size); |
linker::copy_constant_to_storage(storage, |
val, |
val->type->base_type, |
val->type->components(), |
0xF00F); |
verify_data(storage, 0, val, red_zone_size, 0xF00F); |
} |
void |
copy_constant_to_storage::uint_test(unsigned rows) |
{ |
ir_constant *val; |
generate_data(mem_ctx, GLSL_TYPE_UINT, 1, rows, val); |
const unsigned red_zone_size = ARRAY_SIZE(storage) - val->type->components(); |
fill_storage_array_with_sentinels(storage, |
val->type->components(), |
red_zone_size); |
linker::copy_constant_to_storage(storage, |
val, |
val->type->base_type, |
val->type->components(), |
0xF00F); |
verify_data(storage, 0, val, red_zone_size, 0xF00F); |
} |
void |
copy_constant_to_storage::float_test(unsigned columns, unsigned rows) |
{ |
ir_constant *val; |
generate_data(mem_ctx, GLSL_TYPE_FLOAT, columns, rows, val); |
const unsigned red_zone_size = ARRAY_SIZE(storage) - val->type->components(); |
fill_storage_array_with_sentinels(storage, |
val->type->components(), |
red_zone_size); |
linker::copy_constant_to_storage(storage, |
val, |
val->type->base_type, |
val->type->components(), |
0xF00F); |
verify_data(storage, 0, val, red_zone_size, 0xF00F); |
} |
void |
copy_constant_to_storage::bool_test(unsigned rows) |
{ |
ir_constant *val; |
generate_data(mem_ctx, GLSL_TYPE_BOOL, 1, rows, val); |
const unsigned red_zone_size = ARRAY_SIZE(storage) - val->type->components(); |
fill_storage_array_with_sentinels(storage, |
val->type->components(), |
red_zone_size); |
linker::copy_constant_to_storage(storage, |
val, |
val->type->base_type, |
val->type->components(), |
0xF00F); |
verify_data(storage, 0, val, red_zone_size, 0xF00F); |
} |
/** |
* The only difference between this test and int_test is that the base type |
* passed to \c linker::copy_constant_to_storage is hard-coded to \c |
* GLSL_TYPE_SAMPLER instead of using the base type from the constant. |
*/ |
void |
copy_constant_to_storage::sampler_test(void) |
{ |
ir_constant *val; |
generate_data(mem_ctx, GLSL_TYPE_INT, 1, 1, val); |
const unsigned red_zone_size = ARRAY_SIZE(storage) - val->type->components(); |
fill_storage_array_with_sentinels(storage, |
val->type->components(), |
red_zone_size); |
linker::copy_constant_to_storage(storage, |
val, |
GLSL_TYPE_SAMPLER, |
val->type->components(), |
0xF00F); |
verify_data(storage, 0, val, red_zone_size, 0xF00F); |
} |
TEST_F(copy_constant_to_storage, bool_uniform) |
{ |
bool_test(1); |
} |
TEST_F(copy_constant_to_storage, bvec2_uniform) |
{ |
bool_test(2); |
} |
TEST_F(copy_constant_to_storage, bvec3_uniform) |
{ |
bool_test(3); |
} |
TEST_F(copy_constant_to_storage, bvec4_uniform) |
{ |
bool_test(4); |
} |
TEST_F(copy_constant_to_storage, int_uniform) |
{ |
int_test(1); |
} |
TEST_F(copy_constant_to_storage, ivec2_uniform) |
{ |
int_test(2); |
} |
TEST_F(copy_constant_to_storage, ivec3_uniform) |
{ |
int_test(3); |
} |
TEST_F(copy_constant_to_storage, ivec4_uniform) |
{ |
int_test(4); |
} |
TEST_F(copy_constant_to_storage, uint_uniform) |
{ |
uint_test(1); |
} |
TEST_F(copy_constant_to_storage, uvec2_uniform) |
{ |
uint_test(2); |
} |
TEST_F(copy_constant_to_storage, uvec3_uniform) |
{ |
uint_test(3); |
} |
TEST_F(copy_constant_to_storage, uvec4_uniform) |
{ |
uint_test(4); |
} |
TEST_F(copy_constant_to_storage, float_uniform) |
{ |
float_test(1, 1); |
} |
TEST_F(copy_constant_to_storage, vec2_uniform) |
{ |
float_test(1, 2); |
} |
TEST_F(copy_constant_to_storage, vec3_uniform) |
{ |
float_test(1, 3); |
} |
TEST_F(copy_constant_to_storage, vec4_uniform) |
{ |
float_test(1, 4); |
} |
TEST_F(copy_constant_to_storage, mat2x2_uniform) |
{ |
float_test(2, 2); |
} |
TEST_F(copy_constant_to_storage, mat2x3_uniform) |
{ |
float_test(2, 3); |
} |
TEST_F(copy_constant_to_storage, mat2x4_uniform) |
{ |
float_test(2, 4); |
} |
TEST_F(copy_constant_to_storage, mat3x2_uniform) |
{ |
float_test(3, 2); |
} |
TEST_F(copy_constant_to_storage, mat3x3_uniform) |
{ |
float_test(3, 3); |
} |
TEST_F(copy_constant_to_storage, mat3x4_uniform) |
{ |
float_test(3, 4); |
} |
TEST_F(copy_constant_to_storage, mat4x2_uniform) |
{ |
float_test(4, 2); |
} |
TEST_F(copy_constant_to_storage, mat4x3_uniform) |
{ |
float_test(4, 3); |
} |
TEST_F(copy_constant_to_storage, mat4x4_uniform) |
{ |
float_test(4, 4); |
} |
TEST_F(copy_constant_to_storage, sampler_uniform) |
{ |
sampler_test(); |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/general_ir_test.cpp |
---|
0,0 → 1,88 |
/* |
* Copyright © 2013 Intel Corporation |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice (including the next |
* paragraph) shall be included in all copies or substantial portions of the |
* Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
* DEALINGS IN THE SOFTWARE. |
*/ |
#include <gtest/gtest.h> |
#include "main/compiler.h" |
#include "main/mtypes.h" |
#include "main/macros.h" |
#include "ir.h" |
TEST(ir_variable_constructor, interface) |
{ |
void *mem_ctx = ralloc_context(NULL); |
static const glsl_struct_field f[] = { |
{ |
glsl_type::vec(4), |
"v", |
false |
} |
}; |
const glsl_type *const interface = |
glsl_type::get_interface_instance(f, |
ARRAY_SIZE(f), |
GLSL_INTERFACE_PACKING_STD140, |
"simple_interface"); |
static const char name[] = "named_instance"; |
ir_variable *const v = |
new(mem_ctx) ir_variable(interface, name, ir_var_uniform); |
EXPECT_STREQ(name, v->name); |
EXPECT_NE(name, v->name); |
EXPECT_EQ(interface, v->type); |
EXPECT_EQ(interface, v->get_interface_type()); |
} |
TEST(ir_variable_constructor, interface_array) |
{ |
void *mem_ctx = ralloc_context(NULL); |
static const glsl_struct_field f[] = { |
{ |
glsl_type::vec(4), |
"v", |
false |
} |
}; |
const glsl_type *const interface = |
glsl_type::get_interface_instance(f, |
ARRAY_SIZE(f), |
GLSL_INTERFACE_PACKING_STD140, |
"simple_interface"); |
const glsl_type *const interface_array = |
glsl_type::get_array_instance(interface, 2); |
static const char name[] = "array_instance"; |
ir_variable *const v = |
new(mem_ctx) ir_variable(interface_array, name, ir_var_uniform); |
EXPECT_STREQ(name, v->name); |
EXPECT_NE(name, v->name); |
EXPECT_EQ(interface_array, v->type); |
EXPECT_EQ(interface, v->get_interface_type()); |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/invalidate_locations_test.cpp |
---|
0,0 → 1,196 |
/* |
* Copyright © 2013 Intel Corporation |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice (including the next |
* paragraph) shall be included in all copies or substantial portions of the |
* Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
* DEALINGS IN THE SOFTWARE. |
*/ |
#include <gtest/gtest.h> |
#include "main/compiler.h" |
#include "main/mtypes.h" |
#include "main/macros.h" |
#include "util/ralloc.h" |
#include "ir.h" |
#include "linker.h" |
/** |
* \file varyings_test.cpp |
* |
* Test various aspects of linking shader stage inputs and outputs. |
*/ |
class invalidate_locations : public ::testing::Test { |
public: |
virtual void SetUp(); |
virtual void TearDown(); |
void *mem_ctx; |
exec_list ir; |
}; |
void |
invalidate_locations::SetUp() |
{ |
this->mem_ctx = ralloc_context(NULL); |
this->ir.make_empty(); |
} |
void |
invalidate_locations::TearDown() |
{ |
ralloc_free(this->mem_ctx); |
this->mem_ctx = NULL; |
} |
TEST_F(invalidate_locations, simple_vertex_in_generic) |
{ |
ir_variable *const var = |
new(mem_ctx) ir_variable(glsl_type::vec(4), |
"a", |
ir_var_shader_in); |
EXPECT_FALSE(var->data.explicit_location); |
EXPECT_EQ(-1, var->data.location); |
var->data.location = VERT_ATTRIB_GENERIC0; |
var->data.location_frac = 2; |
ir.push_tail(var); |
link_invalidate_variable_locations(&ir); |
EXPECT_EQ(-1, var->data.location); |
EXPECT_EQ(0u, var->data.location_frac); |
EXPECT_FALSE(var->data.explicit_location); |
EXPECT_TRUE(var->data.is_unmatched_generic_inout); |
} |
TEST_F(invalidate_locations, explicit_location_vertex_in_generic) |
{ |
ir_variable *const var = |
new(mem_ctx) ir_variable(glsl_type::vec(4), |
"a", |
ir_var_shader_in); |
EXPECT_FALSE(var->data.explicit_location); |
EXPECT_EQ(-1, var->data.location); |
var->data.location = VERT_ATTRIB_GENERIC0; |
var->data.explicit_location = true; |
ir.push_tail(var); |
link_invalidate_variable_locations(&ir); |
EXPECT_EQ(VERT_ATTRIB_GENERIC0, var->data.location); |
EXPECT_EQ(0u, var->data.location_frac); |
EXPECT_TRUE(var->data.explicit_location); |
EXPECT_FALSE(var->data.is_unmatched_generic_inout); |
} |
TEST_F(invalidate_locations, explicit_location_frac_vertex_in_generic) |
{ |
ir_variable *const var = |
new(mem_ctx) ir_variable(glsl_type::vec(4), |
"a", |
ir_var_shader_in); |
EXPECT_FALSE(var->data.explicit_location); |
EXPECT_EQ(-1, var->data.location); |
var->data.location = VERT_ATTRIB_GENERIC0; |
var->data.location_frac = 2; |
var->data.explicit_location = true; |
ir.push_tail(var); |
link_invalidate_variable_locations(&ir); |
EXPECT_EQ(VERT_ATTRIB_GENERIC0, var->data.location); |
EXPECT_EQ(2u, var->data.location_frac); |
EXPECT_TRUE(var->data.explicit_location); |
EXPECT_FALSE(var->data.is_unmatched_generic_inout); |
} |
TEST_F(invalidate_locations, vertex_in_builtin) |
{ |
ir_variable *const var = |
new(mem_ctx) ir_variable(glsl_type::vec(4), |
"gl_Vertex", |
ir_var_shader_in); |
EXPECT_FALSE(var->data.explicit_location); |
EXPECT_EQ(-1, var->data.location); |
var->data.location = VERT_ATTRIB_POS; |
var->data.explicit_location = true; |
ir.push_tail(var); |
link_invalidate_variable_locations(&ir); |
EXPECT_EQ(VERT_ATTRIB_POS, var->data.location); |
EXPECT_EQ(0u, var->data.location_frac); |
EXPECT_TRUE(var->data.explicit_location); |
EXPECT_FALSE(var->data.is_unmatched_generic_inout); |
} |
TEST_F(invalidate_locations, simple_vertex_out_generic) |
{ |
ir_variable *const var = |
new(mem_ctx) ir_variable(glsl_type::vec(4), |
"a", |
ir_var_shader_out); |
EXPECT_FALSE(var->data.explicit_location); |
EXPECT_EQ(-1, var->data.location); |
var->data.location = VARYING_SLOT_VAR0; |
ir.push_tail(var); |
link_invalidate_variable_locations(&ir); |
EXPECT_EQ(-1, var->data.location); |
EXPECT_EQ(0u, var->data.location_frac); |
EXPECT_FALSE(var->data.explicit_location); |
EXPECT_TRUE(var->data.is_unmatched_generic_inout); |
} |
TEST_F(invalidate_locations, vertex_out_builtin) |
{ |
ir_variable *const var = |
new(mem_ctx) ir_variable(glsl_type::vec(4), |
"gl_FrontColor", |
ir_var_shader_out); |
EXPECT_FALSE(var->data.explicit_location); |
EXPECT_EQ(-1, var->data.location); |
var->data.location = VARYING_SLOT_COL0; |
var->data.explicit_location = true; |
ir.push_tail(var); |
link_invalidate_variable_locations(&ir); |
EXPECT_EQ(VARYING_SLOT_COL0, var->data.location); |
EXPECT_EQ(0u, var->data.location_frac); |
EXPECT_TRUE(var->data.explicit_location); |
EXPECT_FALSE(var->data.is_unmatched_generic_inout); |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/lower_jumps/create_test_cases.py |
---|
0,0 → 1,643 |
# coding=utf-8 |
# |
# Copyright © 2011 Intel Corporation |
# |
# Permission is hereby granted, free of charge, to any person obtaining a |
# copy of this software and associated documentation files (the "Software"), |
# to deal in the Software without restriction, including without limitation |
# the rights to use, copy, modify, merge, publish, distribute, sublicense, |
# and/or sell copies of the Software, and to permit persons to whom the |
# Software is furnished to do so, subject to the following conditions: |
# |
# The above copyright notice and this permission notice (including the next |
# paragraph) shall be included in all copies or substantial portions of the |
# Software. |
# |
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
# DEALINGS IN THE SOFTWARE. |
import os |
import os.path |
import re |
import subprocess |
import sys |
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) # For access to sexps.py, which is in parent dir |
from sexps import * |
def make_test_case(f_name, ret_type, body): |
"""Create a simple optimization test case consisting of a single |
function with the given name, return type, and body. |
Global declarations are automatically created for any undeclared |
variables that are referenced by the function. All undeclared |
variables are assumed to be floats. |
""" |
check_sexp(body) |
declarations = {} |
def make_declarations(sexp, already_declared = ()): |
if isinstance(sexp, list): |
if len(sexp) == 2 and sexp[0] == 'var_ref': |
if sexp[1] not in already_declared: |
declarations[sexp[1]] = [ |
'declare', ['in'], 'float', sexp[1]] |
elif len(sexp) == 4 and sexp[0] == 'assign': |
assert sexp[2][0] == 'var_ref' |
if sexp[2][1] not in already_declared: |
declarations[sexp[2][1]] = [ |
'declare', ['out'], 'float', sexp[2][1]] |
make_declarations(sexp[3], already_declared) |
else: |
already_declared = set(already_declared) |
for s in sexp: |
if isinstance(s, list) and len(s) >= 4 and \ |
s[0] == 'declare': |
already_declared.add(s[3]) |
else: |
make_declarations(s, already_declared) |
make_declarations(body) |
return declarations.values() + \ |
[['function', f_name, ['signature', ret_type, ['parameters'], body]]] |
# The following functions can be used to build expressions. |
def const_float(value): |
"""Create an expression representing the given floating point value.""" |
return ['constant', 'float', ['{0:.6f}'.format(value)]] |
def const_bool(value): |
"""Create an expression representing the given boolean value. |
If value is not a boolean, it is converted to a boolean. So, for |
instance, const_bool(1) is equivalent to const_bool(True). |
""" |
return ['constant', 'bool', ['{0}'.format(1 if value else 0)]] |
def gt_zero(var_name): |
"""Create Construct the expression var_name > 0""" |
return ['expression', 'bool', '>', ['var_ref', var_name], const_float(0)] |
# The following functions can be used to build complex control flow |
# statements. All of these functions return statement lists (even |
# those which only create a single statement), so that statements can |
# be sequenced together using the '+' operator. |
def return_(value = None): |
"""Create a return statement.""" |
if value is not None: |
return [['return', value]] |
else: |
return [['return']] |
def break_(): |
"""Create a break statement.""" |
return ['break'] |
def continue_(): |
"""Create a continue statement.""" |
return ['continue'] |
def simple_if(var_name, then_statements, else_statements = None): |
"""Create a statement of the form |
if (var_name > 0.0) { |
<then_statements> |
} else { |
<else_statements> |
} |
else_statements may be omitted. |
""" |
if else_statements is None: |
else_statements = [] |
check_sexp(then_statements) |
check_sexp(else_statements) |
return [['if', gt_zero(var_name), then_statements, else_statements]] |
def loop(statements): |
"""Create a loop containing the given statements as its loop |
body. |
""" |
check_sexp(statements) |
return [['loop', statements]] |
def declare_temp(var_type, var_name): |
"""Create a declaration of the form |
(declare (temporary) <var_type> <var_name) |
""" |
return [['declare', ['temporary'], var_type, var_name]] |
def assign_x(var_name, value): |
"""Create a statement that assigns <value> to the variable |
<var_name>. The assignment uses the mask (x). |
""" |
check_sexp(value) |
return [['assign', ['x'], ['var_ref', var_name], value]] |
def complex_if(var_prefix, statements): |
"""Create a statement of the form |
if (<var_prefix>a > 0.0) { |
if (<var_prefix>b > 0.0) { |
<statements> |
} |
} |
This is useful in testing jump lowering, because if <statements> |
ends in a jump, lower_jumps.cpp won't try to combine this |
construct with the code that follows it, as it might do for a |
simple if. |
All variables used in the if statement are prefixed with |
var_prefix. This can be used to ensure uniqueness. |
""" |
check_sexp(statements) |
return simple_if(var_prefix + 'a', simple_if(var_prefix + 'b', statements)) |
def declare_execute_flag(): |
"""Create the statements that lower_jumps.cpp uses to declare and |
initialize the temporary boolean execute_flag. |
""" |
return declare_temp('bool', 'execute_flag') + \ |
assign_x('execute_flag', const_bool(True)) |
def declare_return_flag(): |
"""Create the statements that lower_jumps.cpp uses to declare and |
initialize the temporary boolean return_flag. |
""" |
return declare_temp('bool', 'return_flag') + \ |
assign_x('return_flag', const_bool(False)) |
def declare_return_value(): |
"""Create the statements that lower_jumps.cpp uses to declare and |
initialize the temporary variable return_value. Assume that |
return_value is a float. |
""" |
return declare_temp('float', 'return_value') |
def declare_break_flag(): |
"""Create the statements that lower_jumps.cpp uses to declare and |
initialize the temporary boolean break_flag. |
""" |
return declare_temp('bool', 'break_flag') + \ |
assign_x('break_flag', const_bool(False)) |
def lowered_return_simple(value = None): |
"""Create the statements that lower_jumps.cpp lowers a return |
statement to, in situations where it does not need to clear the |
execute flag. |
""" |
if value: |
result = assign_x('return_value', value) |
else: |
result = [] |
return result + assign_x('return_flag', const_bool(True)) |
def lowered_return(value = None): |
"""Create the statements that lower_jumps.cpp lowers a return |
statement to, in situations where it needs to clear the execute |
flag. |
""" |
return lowered_return_simple(value) + \ |
assign_x('execute_flag', const_bool(False)) |
def lowered_continue(): |
"""Create the statement that lower_jumps.cpp lowers a continue |
statement to. |
""" |
return assign_x('execute_flag', const_bool(False)) |
def lowered_break_simple(): |
"""Create the statement that lower_jumps.cpp lowers a break |
statement to, in situations where it does not need to clear the |
execute flag. |
""" |
return assign_x('break_flag', const_bool(True)) |
def lowered_break(): |
"""Create the statement that lower_jumps.cpp lowers a break |
statement to, in situations where it needs to clear the execute |
flag. |
""" |
return lowered_break_simple() + assign_x('execute_flag', const_bool(False)) |
def if_execute_flag(statements): |
"""Wrap statements in an if test so that they will only execute if |
execute_flag is True. |
""" |
check_sexp(statements) |
return [['if', ['var_ref', 'execute_flag'], statements, []]] |
def if_not_return_flag(statements): |
"""Wrap statements in an if test so that they will only execute if |
return_flag is False. |
""" |
check_sexp(statements) |
return [['if', ['var_ref', 'return_flag'], [], statements]] |
def final_return(): |
"""Create the return statement that lower_jumps.cpp places at the |
end of a function when lowering returns. |
""" |
return [['return', ['var_ref', 'return_value']]] |
def final_break(): |
"""Create the conditional break statement that lower_jumps.cpp |
places at the end of a function when lowering breaks. |
""" |
return [['if', ['var_ref', 'break_flag'], break_(), []]] |
def bash_quote(*args): |
"""Quote the arguments appropriately so that bash will understand |
each argument as a single word. |
""" |
def quote_word(word): |
for c in word: |
if not (c.isalpha() or c.isdigit() or c in '@%_-+=:,./'): |
break |
else: |
if not word: |
return "''" |
return word |
return "'{0}'".format(word.replace("'", "'\"'\"'")) |
return ' '.join(quote_word(word) for word in args) |
def create_test_case(doc_string, input_sexp, expected_sexp, test_name, |
pull_out_jumps=False, lower_sub_return=False, |
lower_main_return=False, lower_continue=False, |
lower_break=False): |
"""Create a test case that verifies that do_lower_jumps transforms |
the given code in the expected way. |
""" |
doc_lines = [line.strip() for line in doc_string.splitlines()] |
doc_string = ''.join('# {0}\n'.format(line) for line in doc_lines if line != '') |
check_sexp(input_sexp) |
check_sexp(expected_sexp) |
input_str = sexp_to_string(sort_decls(input_sexp)) |
expected_output = sexp_to_string(sort_decls(expected_sexp)) |
optimization = ( |
'do_lower_jumps({0:d}, {1:d}, {2:d}, {3:d}, {4:d})'.format( |
pull_out_jumps, lower_sub_return, lower_main_return, |
lower_continue, lower_break)) |
args = ['../../glsl_test', 'optpass', '--quiet', '--input-ir', optimization] |
test_file = '{0}.opt_test'.format(test_name) |
with open(test_file, 'w') as f: |
f.write('#!/usr/bin/env bash\n#\n# This file was generated by create_test_cases.py.\n#\n') |
f.write(doc_string) |
f.write('{0} <<EOF\n'.format(bash_quote(*args))) |
f.write('{0}\nEOF\n'.format(input_str)) |
os.chmod(test_file, 0774) |
expected_file = '{0}.opt_test.expected'.format(test_name) |
with open(expected_file, 'w') as f: |
f.write('{0}\n'.format(expected_output)) |
def test_lower_returns_main(): |
doc_string = """Test that do_lower_jumps respects the lower_main_return |
flag in deciding whether to lower returns in the main |
function. |
""" |
input_sexp = make_test_case('main', 'void', ( |
complex_if('', return_()) |
)) |
expected_sexp = make_test_case('main', 'void', ( |
declare_execute_flag() + |
declare_return_flag() + |
complex_if('', lowered_return()) |
)) |
create_test_case(doc_string, input_sexp, expected_sexp, 'lower_returns_main_true', |
lower_main_return=True) |
create_test_case(doc_string, input_sexp, input_sexp, 'lower_returns_main_false', |
lower_main_return=False) |
def test_lower_returns_sub(): |
doc_string = """Test that do_lower_jumps respects the lower_sub_return flag |
in deciding whether to lower returns in subroutines. |
""" |
input_sexp = make_test_case('sub', 'void', ( |
complex_if('', return_()) |
)) |
expected_sexp = make_test_case('sub', 'void', ( |
declare_execute_flag() + |
declare_return_flag() + |
complex_if('', lowered_return()) |
)) |
create_test_case(doc_string, input_sexp, expected_sexp, 'lower_returns_sub_true', |
lower_sub_return=True) |
create_test_case(doc_string, input_sexp, input_sexp, 'lower_returns_sub_false', |
lower_sub_return=False) |
def test_lower_returns_1(): |
doc_string = """Test that a void return at the end of a function is |
eliminated. |
""" |
input_sexp = make_test_case('main', 'void', ( |
assign_x('a', const_float(1)) + |
return_() |
)) |
expected_sexp = make_test_case('main', 'void', ( |
assign_x('a', const_float(1)) |
)) |
create_test_case(doc_string, input_sexp, expected_sexp, 'lower_returns_1', |
lower_main_return=True) |
def test_lower_returns_2(): |
doc_string = """Test that lowering is not performed on a non-void return at |
the end of subroutine. |
""" |
input_sexp = make_test_case('sub', 'float', ( |
assign_x('a', const_float(1)) + |
return_(const_float(1)) |
)) |
create_test_case(doc_string, input_sexp, input_sexp, 'lower_returns_2', |
lower_sub_return=True) |
def test_lower_returns_3(): |
doc_string = """Test lowering of returns when there is one nested inside a |
complex structure of ifs, and one at the end of a function. |
In this case, the latter return needs to be lowered because it |
will not be at the end of the function once the final return |
is inserted. |
""" |
input_sexp = make_test_case('sub', 'float', ( |
complex_if('', return_(const_float(1))) + |
return_(const_float(2)) |
)) |
expected_sexp = make_test_case('sub', 'float', ( |
declare_execute_flag() + |
declare_return_value() + |
declare_return_flag() + |
complex_if('', lowered_return(const_float(1))) + |
if_execute_flag(lowered_return(const_float(2))) + |
final_return() |
)) |
create_test_case(doc_string, input_sexp, expected_sexp, 'lower_returns_3', |
lower_sub_return=True) |
def test_lower_returns_4(): |
doc_string = """Test that returns are properly lowered when they occur in |
both branches of an if-statement. |
""" |
input_sexp = make_test_case('sub', 'float', ( |
simple_if('a', return_(const_float(1)), |
return_(const_float(2))) |
)) |
expected_sexp = make_test_case('sub', 'float', ( |
declare_execute_flag() + |
declare_return_value() + |
declare_return_flag() + |
simple_if('a', lowered_return(const_float(1)), |
lowered_return(const_float(2))) + |
final_return() |
)) |
create_test_case(doc_string, input_sexp, expected_sexp, 'lower_returns_4', |
lower_sub_return=True) |
def test_lower_unified_returns(): |
doc_string = """If both branches of an if statement end in a return, and |
pull_out_jumps is True, then those returns should be lifted |
outside the if and then properly lowered. |
Verify that this lowering occurs during the same pass as the |
lowering of other returns by checking that extra temporary |
variables aren't generated. |
""" |
input_sexp = make_test_case('main', 'void', ( |
complex_if('a', return_()) + |
simple_if('b', simple_if('c', return_(), return_())) |
)) |
expected_sexp = make_test_case('main', 'void', ( |
declare_execute_flag() + |
declare_return_flag() + |
complex_if('a', lowered_return()) + |
if_execute_flag(simple_if('b', (simple_if('c', [], []) + |
lowered_return()))) |
)) |
create_test_case(doc_string, input_sexp, expected_sexp, 'lower_unified_returns', |
lower_main_return=True, pull_out_jumps=True) |
def test_lower_pulled_out_jump(): |
doc_string = """If one branch of an if ends in a jump, and control cannot |
fall out the bottom of the other branch, and pull_out_jumps is |
True, then the jump is lifted outside the if. |
Verify that this lowering occurs during the same pass as the |
lowering of other jumps by checking that extra temporary |
variables aren't generated. |
""" |
input_sexp = make_test_case('main', 'void', ( |
complex_if('a', return_()) + |
loop(simple_if('b', simple_if('c', break_(), continue_()), |
return_())) + |
assign_x('d', const_float(1)) |
)) |
# Note: optimization produces two other effects: the break |
# gets lifted out of the if statements, and the code after the |
# loop gets guarded so that it only executes if the return |
# flag is clear. |
expected_sexp = make_test_case('main', 'void', ( |
declare_execute_flag() + |
declare_return_flag() + |
complex_if('a', lowered_return()) + |
if_execute_flag( |
loop(simple_if('b', simple_if('c', [], continue_()), |
lowered_return_simple()) + |
break_()) + |
if_not_return_flag(assign_x('d', const_float(1)))) |
)) |
create_test_case(doc_string, input_sexp, expected_sexp, 'lower_pulled_out_jump', |
lower_main_return=True, pull_out_jumps=True) |
def test_lower_breaks_1(): |
doc_string = """If a loop contains an unconditional break at the bottom of |
it, it should not be lowered.""" |
input_sexp = make_test_case('main', 'void', ( |
loop(assign_x('a', const_float(1)) + |
break_()) |
)) |
expected_sexp = input_sexp |
create_test_case(doc_string, input_sexp, expected_sexp, 'lower_breaks_1', lower_break=True) |
def test_lower_breaks_2(): |
doc_string = """If a loop contains a conditional break at the bottom of it, |
it should not be lowered if it is in the then-clause. |
""" |
input_sexp = make_test_case('main', 'void', ( |
loop(assign_x('a', const_float(1)) + |
simple_if('b', break_())) |
)) |
expected_sexp = input_sexp |
create_test_case(doc_string, input_sexp, expected_sexp, 'lower_breaks_2', lower_break=True) |
def test_lower_breaks_3(): |
doc_string = """If a loop contains a conditional break at the bottom of it, |
it should not be lowered if it is in the then-clause, even if |
there are statements preceding the break. |
""" |
input_sexp = make_test_case('main', 'void', ( |
loop(assign_x('a', const_float(1)) + |
simple_if('b', (assign_x('c', const_float(1)) + |
break_()))) |
)) |
expected_sexp = input_sexp |
create_test_case(doc_string, input_sexp, expected_sexp, 'lower_breaks_3', lower_break=True) |
def test_lower_breaks_4(): |
doc_string = """If a loop contains a conditional break at the bottom of it, |
it should not be lowered if it is in the else-clause. |
""" |
input_sexp = make_test_case('main', 'void', ( |
loop(assign_x('a', const_float(1)) + |
simple_if('b', [], break_())) |
)) |
expected_sexp = input_sexp |
create_test_case(doc_string, input_sexp, expected_sexp, 'lower_breaks_4', lower_break=True) |
def test_lower_breaks_5(): |
doc_string = """If a loop contains a conditional break at the bottom of it, |
it should not be lowered if it is in the else-clause, even if |
there are statements preceding the break. |
""" |
input_sexp = make_test_case('main', 'void', ( |
loop(assign_x('a', const_float(1)) + |
simple_if('b', [], (assign_x('c', const_float(1)) + |
break_()))) |
)) |
expected_sexp = input_sexp |
create_test_case(doc_string, input_sexp, expected_sexp, 'lower_breaks_5', lower_break=True) |
def test_lower_breaks_6(): |
doc_string = """If a loop contains conditional breaks and continues, and |
ends in an unconditional break, then the unconditional break |
needs to be lowered, because it will no longer be at the end |
of the loop after the final break is added. |
""" |
input_sexp = make_test_case('main', 'void', ( |
loop(simple_if('a', (complex_if('b', continue_()) + |
complex_if('c', break_()))) + |
break_()) |
)) |
expected_sexp = make_test_case('main', 'void', ( |
declare_break_flag() + |
loop(declare_execute_flag() + |
simple_if( |
'a', |
(complex_if('b', lowered_continue()) + |
if_execute_flag( |
complex_if('c', lowered_break())))) + |
if_execute_flag(lowered_break_simple()) + |
final_break()) |
)) |
create_test_case(doc_string, input_sexp, expected_sexp, 'lower_breaks_6', |
lower_break=True, lower_continue=True) |
def test_lower_guarded_conditional_break(): |
doc_string = """Normally a conditional break at the end of a loop isn't |
lowered, however if the conditional break gets placed inside |
an if(execute_flag) because of earlier lowering of continues, |
then the break needs to be lowered. |
""" |
input_sexp = make_test_case('main', 'void', ( |
loop(complex_if('a', continue_()) + |
simple_if('b', break_())) |
)) |
expected_sexp = make_test_case('main', 'void', ( |
declare_break_flag() + |
loop(declare_execute_flag() + |
complex_if('a', lowered_continue()) + |
if_execute_flag(simple_if('b', lowered_break())) + |
final_break()) |
)) |
create_test_case(doc_string, input_sexp, expected_sexp, 'lower_guarded_conditional_break', |
lower_break=True, lower_continue=True) |
def test_remove_continue_at_end_of_loop(): |
doc_string = """Test that a redundant continue-statement at the end of a |
loop is removed. |
""" |
input_sexp = make_test_case('main', 'void', ( |
loop(assign_x('a', const_float(1)) + |
continue_()) |
)) |
expected_sexp = make_test_case('main', 'void', ( |
loop(assign_x('a', const_float(1))) |
)) |
create_test_case(doc_string, input_sexp, expected_sexp, 'remove_continue_at_end_of_loop') |
def test_lower_return_void_at_end_of_loop(): |
doc_string = """Test that a return of void at the end of a loop is properly |
lowered. |
""" |
input_sexp = make_test_case('main', 'void', ( |
loop(assign_x('a', const_float(1)) + |
return_()) + |
assign_x('b', const_float(2)) |
)) |
expected_sexp = make_test_case('main', 'void', ( |
declare_return_flag() + |
loop(assign_x('a', const_float(1)) + |
lowered_return_simple() + |
break_()) + |
if_not_return_flag(assign_x('b', const_float(2))) |
)) |
create_test_case(doc_string, input_sexp, input_sexp, 'return_void_at_end_of_loop_lower_nothing') |
create_test_case(doc_string, input_sexp, expected_sexp, 'return_void_at_end_of_loop_lower_return', |
lower_main_return=True) |
create_test_case(doc_string, input_sexp, expected_sexp, 'return_void_at_end_of_loop_lower_return_and_break', |
lower_main_return=True, lower_break=True) |
def test_lower_return_non_void_at_end_of_loop(): |
doc_string = """Test that a non-void return at the end of a loop is |
properly lowered. |
""" |
input_sexp = make_test_case('sub', 'float', ( |
loop(assign_x('a', const_float(1)) + |
return_(const_float(2))) + |
assign_x('b', const_float(3)) + |
return_(const_float(4)) |
)) |
expected_sexp = make_test_case('sub', 'float', ( |
declare_execute_flag() + |
declare_return_value() + |
declare_return_flag() + |
loop(assign_x('a', const_float(1)) + |
lowered_return_simple(const_float(2)) + |
break_()) + |
if_not_return_flag(assign_x('b', const_float(3)) + |
lowered_return(const_float(4))) + |
final_return() |
)) |
create_test_case(doc_string, input_sexp, input_sexp, 'return_non_void_at_end_of_loop_lower_nothing') |
create_test_case(doc_string, input_sexp, expected_sexp, 'return_non_void_at_end_of_loop_lower_return', |
lower_sub_return=True) |
create_test_case(doc_string, input_sexp, expected_sexp, 'return_non_void_at_end_of_loop_lower_return_and_break', |
lower_sub_return=True, lower_break=True) |
if __name__ == '__main__': |
test_lower_returns_main() |
test_lower_returns_sub() |
test_lower_returns_1() |
test_lower_returns_2() |
test_lower_returns_3() |
test_lower_returns_4() |
test_lower_unified_returns() |
test_lower_pulled_out_jump() |
test_lower_breaks_1() |
test_lower_breaks_2() |
test_lower_breaks_3() |
test_lower_breaks_4() |
test_lower_breaks_5() |
test_lower_breaks_6() |
test_lower_guarded_conditional_break() |
test_remove_continue_at_end_of_loop() |
test_lower_return_void_at_end_of_loop() |
test_lower_return_non_void_at_end_of_loop() |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/optimization-test |
---|
0,0 → 1,42 |
#!/usr/bin/env bash |
if [ ! -z "$srcdir" ]; then |
compare_ir=`pwd`/tests/compare_ir |
else |
compare_ir=./compare_ir |
fi |
total=0 |
pass=0 |
echo "====== Generating tests ======" |
for dir in tests/*/; do |
if [ -e "${dir}create_test_cases.py" ]; then |
cd $dir; $PYTHON2 create_test_cases.py; cd .. |
fi |
echo "$dir" |
done |
echo "====== Testing optimization passes ======" |
for test in `find . -iname '*.opt_test'`; do |
echo -n "Testing $test..." |
(cd `dirname "$test"`; ./`basename "$test"`) > "$test.out" 2>&1 |
total=$((total+1)) |
if $PYTHON2 $PYTHON_FLAGS $compare_ir "$test.expected" "$test.out" >/dev/null 2>&1; then |
echo "PASS" |
pass=$((pass+1)) |
else |
echo "FAIL" |
$PYTHON2 $PYTHON_FLAGS $compare_ir "$test.expected" "$test.out" |
fi |
done |
echo "" |
echo "$pass/$total tests returned correct results" |
echo "" |
if [[ $pass == $total ]]; then |
exit 0 |
else |
exit 1 |
fi |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/sampler_types_test.cpp |
---|
0,0 → 1,100 |
/* |
* Copyright © 2013 Intel Corporation |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice (including the next |
* paragraph) shall be included in all copies or substantial portions of the |
* Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
* DEALINGS IN THE SOFTWARE. |
*/ |
#include <gtest/gtest.h> |
#include "main/compiler.h" |
#include "main/mtypes.h" |
#include "main/macros.h" |
#include "ir.h" |
/** |
* \file sampler_types_test.cpp |
* |
* Test that built-in sampler types have the right properties. |
*/ |
#define ARRAY EXPECT_TRUE(type->sampler_array); |
#define NONARRAY EXPECT_FALSE(type->sampler_array); |
#define SHADOW EXPECT_TRUE(type->sampler_shadow); |
#define COLOR EXPECT_FALSE(type->sampler_shadow); |
#define T(TYPE, DIM, DATA_TYPE, ARR, SHAD, COMPS) \ |
TEST(sampler_types, TYPE) \ |
{ \ |
const glsl_type *type = glsl_type::TYPE##_type; \ |
EXPECT_EQ(GLSL_TYPE_SAMPLER, type->base_type); \ |
EXPECT_EQ(DIM, type->sampler_dimensionality); \ |
EXPECT_EQ(DATA_TYPE, type->sampler_type); \ |
ARR; \ |
SHAD; \ |
EXPECT_EQ(COMPS, type->coordinate_components()); \ |
} |
T( sampler1D, GLSL_SAMPLER_DIM_1D, GLSL_TYPE_FLOAT, NONARRAY, COLOR, 1) |
T( sampler2D, GLSL_SAMPLER_DIM_2D, GLSL_TYPE_FLOAT, NONARRAY, COLOR, 2) |
T( sampler3D, GLSL_SAMPLER_DIM_3D, GLSL_TYPE_FLOAT, NONARRAY, COLOR, 3) |
T( samplerCube, GLSL_SAMPLER_DIM_CUBE, GLSL_TYPE_FLOAT, NONARRAY, COLOR, 3) |
T( sampler1DArray, GLSL_SAMPLER_DIM_1D, GLSL_TYPE_FLOAT, ARRAY, COLOR, 2) |
T( sampler2DArray, GLSL_SAMPLER_DIM_2D, GLSL_TYPE_FLOAT, ARRAY, COLOR, 3) |
T( samplerCubeArray, GLSL_SAMPLER_DIM_CUBE, GLSL_TYPE_FLOAT, ARRAY, COLOR, 4) |
T( sampler2DRect, GLSL_SAMPLER_DIM_RECT, GLSL_TYPE_FLOAT, NONARRAY, COLOR, 2) |
T( samplerBuffer, GLSL_SAMPLER_DIM_BUF, GLSL_TYPE_FLOAT, NONARRAY, COLOR, 1) |
T( sampler2DMS, GLSL_SAMPLER_DIM_MS, GLSL_TYPE_FLOAT, NONARRAY, COLOR, 2) |
T( sampler2DMSArray, GLSL_SAMPLER_DIM_MS, GLSL_TYPE_FLOAT, ARRAY, COLOR, 3) |
T(isampler1D, GLSL_SAMPLER_DIM_1D, GLSL_TYPE_INT, NONARRAY, COLOR, 1) |
T(isampler2D, GLSL_SAMPLER_DIM_2D, GLSL_TYPE_INT, NONARRAY, COLOR, 2) |
T(isampler3D, GLSL_SAMPLER_DIM_3D, GLSL_TYPE_INT, NONARRAY, COLOR, 3) |
T(isamplerCube, GLSL_SAMPLER_DIM_CUBE, GLSL_TYPE_INT, NONARRAY, COLOR, 3) |
T(isampler1DArray, GLSL_SAMPLER_DIM_1D, GLSL_TYPE_INT, ARRAY, COLOR, 2) |
T(isampler2DArray, GLSL_SAMPLER_DIM_2D, GLSL_TYPE_INT, ARRAY, COLOR, 3) |
T(isamplerCubeArray, GLSL_SAMPLER_DIM_CUBE, GLSL_TYPE_INT, ARRAY, COLOR, 4) |
T(isampler2DRect, GLSL_SAMPLER_DIM_RECT, GLSL_TYPE_INT, NONARRAY, COLOR, 2) |
T(isamplerBuffer, GLSL_SAMPLER_DIM_BUF, GLSL_TYPE_INT, NONARRAY, COLOR, 1) |
T(isampler2DMS, GLSL_SAMPLER_DIM_MS, GLSL_TYPE_INT, NONARRAY, COLOR, 2) |
T(isampler2DMSArray, GLSL_SAMPLER_DIM_MS, GLSL_TYPE_INT, ARRAY, COLOR, 3) |
T(usampler1D, GLSL_SAMPLER_DIM_1D, GLSL_TYPE_UINT, NONARRAY, COLOR, 1) |
T(usampler2D, GLSL_SAMPLER_DIM_2D, GLSL_TYPE_UINT, NONARRAY, COLOR, 2) |
T(usampler3D, GLSL_SAMPLER_DIM_3D, GLSL_TYPE_UINT, NONARRAY, COLOR, 3) |
T(usamplerCube, GLSL_SAMPLER_DIM_CUBE, GLSL_TYPE_UINT, NONARRAY, COLOR, 3) |
T(usampler1DArray, GLSL_SAMPLER_DIM_1D, GLSL_TYPE_UINT, ARRAY, COLOR, 2) |
T(usampler2DArray, GLSL_SAMPLER_DIM_2D, GLSL_TYPE_UINT, ARRAY, COLOR, 3) |
T(usamplerCubeArray, GLSL_SAMPLER_DIM_CUBE, GLSL_TYPE_UINT, ARRAY, COLOR, 4) |
T(usampler2DRect, GLSL_SAMPLER_DIM_RECT, GLSL_TYPE_UINT, NONARRAY, COLOR, 2) |
T(usamplerBuffer, GLSL_SAMPLER_DIM_BUF, GLSL_TYPE_UINT, NONARRAY, COLOR, 1) |
T(usampler2DMS, GLSL_SAMPLER_DIM_MS, GLSL_TYPE_UINT, NONARRAY, COLOR, 2) |
T(usampler2DMSArray, GLSL_SAMPLER_DIM_MS, GLSL_TYPE_UINT, ARRAY, COLOR, 3) |
T(sampler1DShadow, GLSL_SAMPLER_DIM_1D, GLSL_TYPE_FLOAT, NONARRAY, SHADOW, 1) |
T(sampler2DShadow, GLSL_SAMPLER_DIM_2D, GLSL_TYPE_FLOAT, NONARRAY, SHADOW, 2) |
T(samplerCubeShadow, GLSL_SAMPLER_DIM_CUBE, GLSL_TYPE_FLOAT, NONARRAY, SHADOW, 3) |
T(sampler1DArrayShadow, |
GLSL_SAMPLER_DIM_1D, GLSL_TYPE_FLOAT, ARRAY, SHADOW, 2) |
T(sampler2DArrayShadow, |
GLSL_SAMPLER_DIM_2D, GLSL_TYPE_FLOAT, ARRAY, SHADOW, 3) |
T(samplerCubeArrayShadow, |
GLSL_SAMPLER_DIM_CUBE, GLSL_TYPE_FLOAT, ARRAY, SHADOW, 4) |
T(sampler2DRectShadow, |
GLSL_SAMPLER_DIM_RECT, GLSL_TYPE_FLOAT, NONARRAY, SHADOW, 2) |
T(samplerExternalOES, |
GLSL_SAMPLER_DIM_EXTERNAL, GLSL_TYPE_FLOAT, NONARRAY, COLOR, 2) |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/set_uniform_initializer_tests.cpp |
---|
0,0 → 1,594 |
/* |
* Copyright © 2012 Intel Corporation |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice (including the next |
* paragraph) shall be included in all copies or substantial portions of the |
* Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
* DEALINGS IN THE SOFTWARE. |
*/ |
#include <gtest/gtest.h> |
#include "main/compiler.h" |
#include "main/mtypes.h" |
#include "main/macros.h" |
#include "util/ralloc.h" |
#include "uniform_initializer_utils.h" |
namespace linker { |
extern void |
set_uniform_initializer(void *mem_ctx, gl_shader_program *prog, |
const char *name, const glsl_type *type, |
ir_constant *val, unsigned int boolean_true); |
} |
class set_uniform_initializer : public ::testing::Test { |
public: |
virtual void SetUp(); |
virtual void TearDown(); |
/** |
* Index of the uniform to be tested. |
* |
* All of the \c set_uniform_initializer tests create several slots for |
* unifroms. All but one of the slots is fake. This field holds the index |
* of the slot for the uniform being tested. |
*/ |
unsigned actual_index; |
/** |
* Name of the uniform to be tested. |
*/ |
const char *name; |
/** |
* Shader program used in the test. |
*/ |
struct gl_shader_program *prog; |
/** |
* Ralloc memory context used for all temporary allocations. |
*/ |
void *mem_ctx; |
}; |
void |
set_uniform_initializer::SetUp() |
{ |
this->mem_ctx = ralloc_context(NULL); |
this->prog = rzalloc(NULL, struct gl_shader_program); |
/* Set default values used by the test cases. |
*/ |
this->actual_index = 1; |
this->name = "i"; |
} |
void |
set_uniform_initializer::TearDown() |
{ |
ralloc_free(this->mem_ctx); |
this->mem_ctx = NULL; |
ralloc_free(this->prog); |
this->prog = NULL; |
} |
/** |
* Create some uniform storage for a program. |
* |
* \param prog Program to get some storage |
* \param num_storage Total number of storage slots |
* \param index_to_set Storage slot that will actually get a value |
* \param name Name for the actual storage slot |
* \param type Type for the elements of the actual storage slot |
* \param array_size Size for the array of the actual storage slot. This |
* should be zero for non-arrays. |
*/ |
static unsigned |
establish_uniform_storage(struct gl_shader_program *prog, unsigned num_storage, |
unsigned index_to_set, const char *name, |
const glsl_type *type, unsigned array_size) |
{ |
const unsigned elements = MAX2(1, array_size); |
const unsigned data_components = elements * type->components(); |
const unsigned total_components = MAX2(17, (data_components |
+ type->components())); |
const unsigned red_zone_components = total_components - data_components; |
prog->UniformStorage = rzalloc_array(prog, struct gl_uniform_storage, |
num_storage); |
prog->NumUserUniformStorage = num_storage; |
prog->UniformStorage[index_to_set].name = (char *) name; |
prog->UniformStorage[index_to_set].type = type; |
prog->UniformStorage[index_to_set].array_elements = array_size; |
prog->UniformStorage[index_to_set].initialized = false; |
for (int sh = 0; sh < MESA_SHADER_STAGES; sh++) { |
prog->UniformStorage[index_to_set].sampler[sh].index = ~0; |
prog->UniformStorage[index_to_set].sampler[sh].active = false; |
} |
prog->UniformStorage[index_to_set].num_driver_storage = 0; |
prog->UniformStorage[index_to_set].driver_storage = NULL; |
prog->UniformStorage[index_to_set].storage = |
rzalloc_array(prog, union gl_constant_value, total_components); |
fill_storage_array_with_sentinels(prog->UniformStorage[index_to_set].storage, |
data_components, |
red_zone_components); |
for (unsigned i = 0; i < num_storage; i++) { |
if (i == index_to_set) |
continue; |
prog->UniformStorage[i].name = (char *) "invalid slot"; |
prog->UniformStorage[i].type = glsl_type::void_type; |
prog->UniformStorage[i].array_elements = 0; |
prog->UniformStorage[i].initialized = false; |
for (int sh = 0; sh < MESA_SHADER_STAGES; sh++) { |
prog->UniformStorage[i].sampler[sh].index = ~0; |
prog->UniformStorage[i].sampler[sh].active = false; |
} |
prog->UniformStorage[i].num_driver_storage = 0; |
prog->UniformStorage[i].driver_storage = NULL; |
prog->UniformStorage[i].storage = NULL; |
} |
return red_zone_components; |
} |
/** |
* Verify that the correct uniform is marked as having been initialized. |
*/ |
static void |
verify_initialization(struct gl_shader_program *prog, unsigned actual_index) |
{ |
for (unsigned i = 0; i < prog->NumUserUniformStorage; i++) { |
if (i == actual_index) { |
EXPECT_TRUE(prog->UniformStorage[actual_index].initialized); |
} else { |
EXPECT_FALSE(prog->UniformStorage[i].initialized); |
} |
} |
} |
static void |
non_array_test(void *mem_ctx, struct gl_shader_program *prog, |
unsigned actual_index, const char *name, |
enum glsl_base_type base_type, |
unsigned columns, unsigned rows) |
{ |
const glsl_type *const type = |
glsl_type::get_instance(base_type, rows, columns); |
unsigned red_zone_components = |
establish_uniform_storage(prog, 3, actual_index, name, type, 0); |
ir_constant *val; |
generate_data(mem_ctx, base_type, columns, rows, val); |
linker::set_uniform_initializer(mem_ctx, prog, name, type, val, 0xF00F); |
verify_initialization(prog, actual_index); |
verify_data(prog->UniformStorage[actual_index].storage, 0, val, |
red_zone_components, 0xF00F); |
} |
TEST_F(set_uniform_initializer, int_uniform) |
{ |
non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 1); |
} |
TEST_F(set_uniform_initializer, ivec2_uniform) |
{ |
non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 2); |
} |
TEST_F(set_uniform_initializer, ivec3_uniform) |
{ |
non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 3); |
} |
TEST_F(set_uniform_initializer, ivec4_uniform) |
{ |
non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 4); |
} |
TEST_F(set_uniform_initializer, uint_uniform) |
{ |
non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 1); |
} |
TEST_F(set_uniform_initializer, uvec2_uniform) |
{ |
non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 2); |
} |
TEST_F(set_uniform_initializer, uvec3_uniform) |
{ |
non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 3); |
} |
TEST_F(set_uniform_initializer, uvec4_uniform) |
{ |
non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 4); |
} |
TEST_F(set_uniform_initializer, bool_uniform) |
{ |
non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 1); |
} |
TEST_F(set_uniform_initializer, bvec2_uniform) |
{ |
non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 2); |
} |
TEST_F(set_uniform_initializer, bvec3_uniform) |
{ |
non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 3); |
} |
TEST_F(set_uniform_initializer, bvec4_uniform) |
{ |
non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 4); |
} |
TEST_F(set_uniform_initializer, float_uniform) |
{ |
non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 2); |
} |
TEST_F(set_uniform_initializer, vec2_uniform) |
{ |
non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 2); |
} |
TEST_F(set_uniform_initializer, vec3_uniform) |
{ |
non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 3); |
} |
TEST_F(set_uniform_initializer, vec4_uniform) |
{ |
non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 4); |
} |
TEST_F(set_uniform_initializer, mat2x2_uniform) |
{ |
non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 2); |
} |
TEST_F(set_uniform_initializer, mat2x3_uniform) |
{ |
non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 3); |
} |
TEST_F(set_uniform_initializer, mat2x4_uniform) |
{ |
non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 4); |
} |
TEST_F(set_uniform_initializer, mat3x2_uniform) |
{ |
non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 2); |
} |
TEST_F(set_uniform_initializer, mat3x3_uniform) |
{ |
non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 3); |
} |
TEST_F(set_uniform_initializer, mat3x4_uniform) |
{ |
non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 4); |
} |
TEST_F(set_uniform_initializer, mat4x2_uniform) |
{ |
non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 2); |
} |
TEST_F(set_uniform_initializer, mat4x3_uniform) |
{ |
non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 3); |
} |
TEST_F(set_uniform_initializer, mat4x4_uniform) |
{ |
non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 4); |
} |
static void |
array_test(void *mem_ctx, struct gl_shader_program *prog, |
unsigned actual_index, const char *name, |
enum glsl_base_type base_type, |
unsigned columns, unsigned rows, unsigned array_size, |
unsigned excess_data_size) |
{ |
const glsl_type *const element_type = |
glsl_type::get_instance(base_type, rows, columns); |
const unsigned red_zone_components = |
establish_uniform_storage(prog, 3, actual_index, name, element_type, |
array_size); |
/* The constant value generated may have more array elements than the |
* uniform that it initializes. In the real compiler and linker this can |
* happen when a uniform array is compacted because some of the tail |
* elements are not used. In this case, the type of the uniform will be |
* modified, but the initializer will not. |
*/ |
ir_constant *val; |
generate_array_data(mem_ctx, base_type, columns, rows, |
array_size + excess_data_size, val); |
linker::set_uniform_initializer(mem_ctx, prog, name, element_type, val, |
0xF00F); |
verify_initialization(prog, actual_index); |
verify_data(prog->UniformStorage[actual_index].storage, array_size, |
val, red_zone_components, 0xF00F); |
} |
TEST_F(set_uniform_initializer, int_array_uniform) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 1, 4, 0); |
} |
TEST_F(set_uniform_initializer, ivec2_array_uniform) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 2, 4, 0); |
} |
TEST_F(set_uniform_initializer, ivec3_array_uniform) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 3, 4, 0); |
} |
TEST_F(set_uniform_initializer, ivec4_array_uniform) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 4, 4, 0); |
} |
TEST_F(set_uniform_initializer, uint_array_uniform) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 1, 4, 0); |
} |
TEST_F(set_uniform_initializer, uvec2_array_uniform) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 2, 4, 0); |
} |
TEST_F(set_uniform_initializer, uvec3_array_uniform) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 3, 4, 0); |
} |
TEST_F(set_uniform_initializer, uvec4_array_uniform) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 4, 4, 0); |
} |
TEST_F(set_uniform_initializer, bool_array_uniform) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 1, 4, 0); |
} |
TEST_F(set_uniform_initializer, bvec2_array_uniform) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 2, 4, 0); |
} |
TEST_F(set_uniform_initializer, bvec3_array_uniform) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 3, 4, 0); |
} |
TEST_F(set_uniform_initializer, bvec4_array_uniform) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 4, 4, 0); |
} |
TEST_F(set_uniform_initializer, float_array_uniform) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 1, 4, 0); |
} |
TEST_F(set_uniform_initializer, vec2_array_uniform) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 2, 4, 0); |
} |
TEST_F(set_uniform_initializer, vec3_array_uniform) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 3, 4, 0); |
} |
TEST_F(set_uniform_initializer, vec4_array_uniform) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 4, 4, 0); |
} |
TEST_F(set_uniform_initializer, mat2x2_array_uniform) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 2, 4, 0); |
} |
TEST_F(set_uniform_initializer, mat2x3_array_uniform) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 3, 4, 0); |
} |
TEST_F(set_uniform_initializer, mat2x4_array_uniform) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 4, 4, 0); |
} |
TEST_F(set_uniform_initializer, mat3x2_array_uniform) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 2, 4, 0); |
} |
TEST_F(set_uniform_initializer, mat3x3_array_uniform) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 3, 4, 0); |
} |
TEST_F(set_uniform_initializer, mat3x4_array_uniform) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 4, 4, 0); |
} |
TEST_F(set_uniform_initializer, mat4x2_array_uniform) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 2, 4, 0); |
} |
TEST_F(set_uniform_initializer, mat4x3_array_uniform) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 3, 4, 0); |
} |
TEST_F(set_uniform_initializer, mat4x4_array_uniform) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 4, 4, 0); |
} |
TEST_F(set_uniform_initializer, int_array_uniform_excess_initializer) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 1, 4, 5); |
} |
TEST_F(set_uniform_initializer, ivec2_array_uniform_excess_initializer) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 2, 4, 5); |
} |
TEST_F(set_uniform_initializer, ivec3_array_uniform_excess_initializer) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 3, 4, 5); |
} |
TEST_F(set_uniform_initializer, ivec4_array_uniform_excess_initializer) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 4, 4, 5); |
} |
TEST_F(set_uniform_initializer, uint_array_uniform_excess_initializer) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 1, 4, 5); |
} |
TEST_F(set_uniform_initializer, uvec2_array_uniform_excess_initializer) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 2, 4, 5); |
} |
TEST_F(set_uniform_initializer, uvec3_array_uniform_excess_initializer) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 3, 4, 5); |
} |
TEST_F(set_uniform_initializer, uvec4_array_uniform_excess_initializer) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 4, 4, 5); |
} |
TEST_F(set_uniform_initializer, bool_array_uniform_excess_initializer) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 1, 4, 5); |
} |
TEST_F(set_uniform_initializer, bvec2_array_uniform_excess_initializer) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 2, 4, 5); |
} |
TEST_F(set_uniform_initializer, bvec3_array_uniform_excess_initializer) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 3, 4, 5); |
} |
TEST_F(set_uniform_initializer, bvec4_array_uniform_excess_initializer) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 4, 4, 5); |
} |
TEST_F(set_uniform_initializer, float_array_uniform_excess_initializer) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 1, 4, 5); |
} |
TEST_F(set_uniform_initializer, vec2_array_uniform_excess_initializer) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 2, 4, 5); |
} |
TEST_F(set_uniform_initializer, vec3_array_uniform_excess_initializer) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 3, 4, 5); |
} |
TEST_F(set_uniform_initializer, vec4_array_uniform_excess_initializer) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 4, 4, 5); |
} |
TEST_F(set_uniform_initializer, mat2x2_array_uniform_excess_initializer) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 2, 4, 5); |
} |
TEST_F(set_uniform_initializer, mat2x3_array_uniform_excess_initializer) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 3, 4, 5); |
} |
TEST_F(set_uniform_initializer, mat2x4_array_uniform_excess_initializer) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 4, 4, 5); |
} |
TEST_F(set_uniform_initializer, mat3x2_array_uniform_excess_initializer) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 2, 4, 5); |
} |
TEST_F(set_uniform_initializer, mat3x3_array_uniform_excess_initializer) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 3, 4, 5); |
} |
TEST_F(set_uniform_initializer, mat3x4_array_uniform_excess_initializer) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 4, 4, 5); |
} |
TEST_F(set_uniform_initializer, mat4x2_array_uniform_excess_initializer) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 2, 4, 5); |
} |
TEST_F(set_uniform_initializer, mat4x3_array_uniform_excess_initializer) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 3, 4, 5); |
} |
TEST_F(set_uniform_initializer, mat4x4_array_uniform_excess_initializer) |
{ |
array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 4, 4, 5); |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/sexps.py |
---|
0,0 → 1,103 |
# coding=utf-8 |
# |
# Copyright © 2011 Intel Corporation |
# |
# Permission is hereby granted, free of charge, to any person obtaining a |
# copy of this software and associated documentation files (the "Software"), |
# to deal in the Software without restriction, including without limitation |
# the rights to use, copy, modify, merge, publish, distribute, sublicense, |
# and/or sell copies of the Software, and to permit persons to whom the |
# Software is furnished to do so, subject to the following conditions: |
# |
# The above copyright notice and this permission notice (including the next |
# paragraph) shall be included in all copies or substantial portions of the |
# Software. |
# |
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
# DEALINGS IN THE SOFTWARE. |
# This file contains helper functions for manipulating sexps in Python. |
# |
# We represent a sexp in Python using nested lists containing strings. |
# So, for example, the sexp (constant float (1.000000)) is represented |
# as ['constant', 'float', ['1.000000']]. |
import re |
def check_sexp(sexp): |
"""Verify that the argument is a proper sexp. |
That is, raise an exception if the argument is not a string or a |
list, or if it contains anything that is not a string or a list at |
any nesting level. |
""" |
if isinstance(sexp, list): |
for s in sexp: |
check_sexp(s) |
elif not isinstance(sexp, basestring): |
raise Exception('Not a sexp: {0!r}'.format(sexp)) |
def parse_sexp(sexp): |
"""Convert a string, of the form that would be output by mesa, |
into a sexp represented as nested lists containing strings. |
""" |
sexp_token_regexp = re.compile( |
'[a-zA-Z_]+(@[0-9]+)?|[0-9]+(\\.[0-9]+)?|[^ \n]') |
stack = [[]] |
for match in sexp_token_regexp.finditer(sexp): |
token = match.group(0) |
if token == '(': |
stack.append([]) |
elif token == ')': |
if len(stack) == 1: |
raise Exception('Unmatched )') |
sexp = stack.pop() |
stack[-1].append(sexp) |
else: |
stack[-1].append(token) |
if len(stack) != 1: |
raise Exception('Unmatched (') |
if len(stack[0]) != 1: |
raise Exception('Multiple sexps') |
return stack[0][0] |
def sexp_to_string(sexp): |
"""Convert a sexp, represented as nested lists containing strings, |
into a single string of the form parseable by mesa. |
""" |
if isinstance(sexp, basestring): |
return sexp |
assert isinstance(sexp, list) |
result = '' |
for s in sexp: |
sub_result = sexp_to_string(s) |
if result == '': |
result = sub_result |
elif '\n' not in result and '\n' not in sub_result and \ |
len(result) + len(sub_result) + 1 <= 70: |
result += ' ' + sub_result |
else: |
result += '\n' + sub_result |
return '({0})'.format(result.replace('\n', '\n ')) |
def sort_decls(sexp): |
"""Sort all toplevel variable declarations in sexp. |
This is used to work around the fact that |
ir_reader::read_instructions reorders declarations. |
""" |
assert isinstance(sexp, list) |
decls = [] |
other_code = [] |
for s in sexp: |
if isinstance(s, list) and len(s) >= 4 and s[0] == 'declare': |
decls.append(s) |
else: |
other_code.append(s) |
return sorted(decls) + other_code |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/uniform_initializer_utils.cpp |
---|
0,0 → 1,252 |
/* |
* Copyright © 2012 Intel Corporation |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice (including the next |
* paragraph) shall be included in all copies or substantial portions of the |
* Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
* DEALINGS IN THE SOFTWARE. |
*/ |
#include <gtest/gtest.h> |
#include "main/mtypes.h" |
#include "main/macros.h" |
#include "util/ralloc.h" |
#include "uniform_initializer_utils.h" |
#include <stdio.h> |
void |
fill_storage_array_with_sentinels(gl_constant_value *storage, |
unsigned data_size, |
unsigned red_zone_size) |
{ |
for (unsigned i = 0; i < data_size; i++) |
storage[i].u = 0xDEADBEEF; |
for (unsigned i = 0; i < red_zone_size; i++) |
storage[data_size + i].u = 0xBADDC0DE; |
} |
/** |
* Verfiy that markers past the end of the real uniform are unmodified |
*/ |
static ::testing::AssertionResult |
red_zone_is_intact(gl_constant_value *storage, |
unsigned data_size, |
unsigned red_zone_size) |
{ |
for (unsigned i = 0; i < red_zone_size; i++) { |
const unsigned idx = data_size + i; |
if (storage[idx].u != 0xBADDC0DE) |
return ::testing::AssertionFailure() |
<< "storage[" << idx << "].u = " << storage[idx].u |
<< ", exepected data values = " << data_size |
<< ", red-zone size = " << red_zone_size; |
} |
return ::testing::AssertionSuccess(); |
} |
static const int values[] = { |
2, 0, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53 |
}; |
/** |
* Generate a single data element. |
* |
* This is by both \c generate_data and \c generate_array_data to create the |
* data. |
*/ |
static void |
generate_data_element(void *mem_ctx, const glsl_type *type, |
ir_constant *&val, unsigned data_index_base) |
{ |
/* Set the initial data values for the generated constant. |
*/ |
ir_constant_data data; |
memset(&data, 0, sizeof(data)); |
for (unsigned i = 0; i < type->components(); i++) { |
const unsigned idx = (i + data_index_base) % ARRAY_SIZE(values); |
switch (type->base_type) { |
case GLSL_TYPE_UINT: |
case GLSL_TYPE_INT: |
case GLSL_TYPE_SAMPLER: |
case GLSL_TYPE_IMAGE: |
data.i[i] = values[idx]; |
break; |
case GLSL_TYPE_FLOAT: |
data.f[i] = float(values[idx]); |
break; |
case GLSL_TYPE_BOOL: |
data.b[i] = bool(values[idx]); |
break; |
case GLSL_TYPE_DOUBLE: |
data.d[i] = double(values[idx]); |
break; |
case GLSL_TYPE_ATOMIC_UINT: |
case GLSL_TYPE_STRUCT: |
case GLSL_TYPE_ARRAY: |
case GLSL_TYPE_VOID: |
case GLSL_TYPE_ERROR: |
case GLSL_TYPE_INTERFACE: |
ASSERT_TRUE(false); |
break; |
} |
} |
/* Generate and verify the constant. |
*/ |
val = new(mem_ctx) ir_constant(type, &data); |
for (unsigned i = 0; i < type->components(); i++) { |
switch (type->base_type) { |
case GLSL_TYPE_UINT: |
case GLSL_TYPE_INT: |
case GLSL_TYPE_SAMPLER: |
case GLSL_TYPE_IMAGE: |
ASSERT_EQ(data.i[i], val->value.i[i]); |
break; |
case GLSL_TYPE_FLOAT: |
ASSERT_EQ(data.f[i], val->value.f[i]); |
break; |
case GLSL_TYPE_BOOL: |
ASSERT_EQ(data.b[i], val->value.b[i]); |
break; |
case GLSL_TYPE_DOUBLE: |
ASSERT_EQ(data.d[i], val->value.d[i]); |
break; |
case GLSL_TYPE_ATOMIC_UINT: |
case GLSL_TYPE_STRUCT: |
case GLSL_TYPE_ARRAY: |
case GLSL_TYPE_VOID: |
case GLSL_TYPE_ERROR: |
case GLSL_TYPE_INTERFACE: |
ASSERT_TRUE(false); |
break; |
} |
} |
} |
void |
generate_data(void *mem_ctx, enum glsl_base_type base_type, |
unsigned columns, unsigned rows, |
ir_constant *&val) |
{ |
/* Determine what the type of the generated constant should be. |
*/ |
const glsl_type *const type = |
glsl_type::get_instance(base_type, rows, columns); |
ASSERT_FALSE(type->is_error()); |
generate_data_element(mem_ctx, type, val, 0); |
} |
void |
generate_array_data(void *mem_ctx, enum glsl_base_type base_type, |
unsigned columns, unsigned rows, unsigned array_size, |
ir_constant *&val) |
{ |
/* Determine what the type of the generated constant should be. |
*/ |
const glsl_type *const element_type = |
glsl_type::get_instance(base_type, rows, columns); |
ASSERT_FALSE(element_type->is_error()); |
const glsl_type *const array_type = |
glsl_type::get_array_instance(element_type, array_size); |
ASSERT_FALSE(array_type->is_error()); |
/* Set the initial data values for the generated constant. |
*/ |
exec_list values_for_array; |
for (unsigned i = 0; i < array_size; i++) { |
ir_constant *element; |
generate_data_element(mem_ctx, element_type, element, i); |
values_for_array.push_tail(element); |
} |
val = new(mem_ctx) ir_constant(array_type, &values_for_array); |
} |
/** |
* Verify that the data stored for the uniform matches the initializer |
* |
* \param storage Backing storage for the uniform |
* \param storage_array_size Array size of the backing storage. This must be |
* less than or equal to the array size of the type |
* of \c val. If \c val is not an array, this must |
* be zero. |
* \param val Value of the initializer for the unifrom. |
* \param red_zone |
*/ |
void |
verify_data(gl_constant_value *storage, unsigned storage_array_size, |
ir_constant *val, unsigned red_zone_size, |
unsigned int boolean_true) |
{ |
if (val->type->base_type == GLSL_TYPE_ARRAY) { |
const glsl_type *const element_type = val->array_elements[0]->type; |
for (unsigned i = 0; i < storage_array_size; i++) { |
verify_data(storage + (i * element_type->components()), 0, |
val->array_elements[i], 0, boolean_true); |
} |
const unsigned components = element_type->components(); |
if (red_zone_size > 0) { |
EXPECT_TRUE(red_zone_is_intact(storage, |
storage_array_size * components, |
red_zone_size)); |
} |
} else { |
ASSERT_EQ(0u, storage_array_size); |
for (unsigned i = 0; i < val->type->components(); i++) { |
switch (val->type->base_type) { |
case GLSL_TYPE_UINT: |
case GLSL_TYPE_INT: |
case GLSL_TYPE_SAMPLER: |
case GLSL_TYPE_IMAGE: |
EXPECT_EQ(val->value.i[i], storage[i].i); |
break; |
case GLSL_TYPE_FLOAT: |
EXPECT_EQ(val->value.f[i], storage[i].f); |
break; |
case GLSL_TYPE_BOOL: |
EXPECT_EQ(val->value.b[i] ? boolean_true : 0, storage[i].i); |
break; |
case GLSL_TYPE_DOUBLE: |
EXPECT_EQ(val->value.d[i], *(double *)&storage[i*2].i); |
break; |
case GLSL_TYPE_ATOMIC_UINT: |
case GLSL_TYPE_STRUCT: |
case GLSL_TYPE_ARRAY: |
case GLSL_TYPE_VOID: |
case GLSL_TYPE_ERROR: |
case GLSL_TYPE_INTERFACE: |
ASSERT_TRUE(false); |
break; |
} |
} |
if (red_zone_size > 0) { |
EXPECT_TRUE(red_zone_is_intact(storage, |
val->type->components(), |
red_zone_size)); |
} |
} |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/uniform_initializer_utils.h |
---|
0,0 → 1,48 |
/* |
* Copyright © 2012 Intel Corporation |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice (including the next |
* paragraph) shall be included in all copies or substantial portions of the |
* Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
* DEALINGS IN THE SOFTWARE. |
*/ |
#pragma once |
#include "program/prog_parameter.h" |
#include "ir.h" |
#include "ir_uniform.h" |
extern void |
fill_storage_array_with_sentinels(gl_constant_value *storage, |
unsigned data_size, |
unsigned red_zone_size); |
extern void |
generate_data(void *mem_ctx, enum glsl_base_type base_type, |
unsigned columns, unsigned rows, |
ir_constant *&val); |
extern void |
generate_array_data(void *mem_ctx, enum glsl_base_type base_type, |
unsigned columns, unsigned rows, unsigned array_size, |
ir_constant *&val); |
extern void |
verify_data(gl_constant_value *storage, unsigned storage_array_size, |
ir_constant *val, unsigned red_zone_size, |
unsigned int boolean_true); |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/glsl/tests/varyings_test.cpp |
---|
0,0 → 1,357 |
/* |
* Copyright © 2013 Intel Corporation |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice (including the next |
* paragraph) shall be included in all copies or substantial portions of the |
* Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
* DEALINGS IN THE SOFTWARE. |
*/ |
#include <gtest/gtest.h> |
#include "main/compiler.h" |
#include "main/mtypes.h" |
#include "main/macros.h" |
#include "util/ralloc.h" |
#include "ir.h" |
#include "program/hash_table.h" |
/** |
* \file varyings_test.cpp |
* |
* Test various aspects of linking shader stage inputs and outputs. |
*/ |
namespace linker { |
bool |
populate_consumer_input_sets(void *mem_ctx, exec_list *ir, |
hash_table *consumer_inputs, |
hash_table *consumer_interface_inputs, |
ir_variable *consumer_inputs_with_locations[VARYING_SLOT_MAX]); |
ir_variable * |
get_matching_input(void *mem_ctx, |
const ir_variable *output_var, |
hash_table *consumer_inputs, |
hash_table *consumer_interface_inputs, |
ir_variable *consumer_inputs_with_locations[VARYING_SLOT_MAX]); |
} |
class link_varyings : public ::testing::Test { |
public: |
link_varyings(); |
virtual void SetUp(); |
virtual void TearDown(); |
char *interface_field_name(const glsl_type *iface, unsigned field = 0) |
{ |
return ralloc_asprintf(mem_ctx, |
"%s.%s", |
iface->name, |
iface->fields.structure[field].name); |
} |
void *mem_ctx; |
exec_list ir; |
hash_table *consumer_inputs; |
hash_table *consumer_interface_inputs; |
const glsl_type *simple_interface; |
ir_variable *junk[VARYING_SLOT_MAX]; |
}; |
link_varyings::link_varyings() |
{ |
static const glsl_struct_field f[] = { |
{ |
glsl_type::vec(4), |
"v", |
false, |
0, |
0, |
0, |
0 |
} |
}; |
this->simple_interface = |
glsl_type::get_interface_instance(f, |
ARRAY_SIZE(f), |
GLSL_INTERFACE_PACKING_STD140, |
"simple_interface"); |
} |
void |
link_varyings::SetUp() |
{ |
this->mem_ctx = ralloc_context(NULL); |
this->ir.make_empty(); |
this->consumer_inputs |
= hash_table_ctor(0, hash_table_string_hash, hash_table_string_compare); |
this->consumer_interface_inputs |
= hash_table_ctor(0, hash_table_string_hash, hash_table_string_compare); |
} |
void |
link_varyings::TearDown() |
{ |
ralloc_free(this->mem_ctx); |
this->mem_ctx = NULL; |
hash_table_dtor(this->consumer_inputs); |
this->consumer_inputs = NULL; |
hash_table_dtor(this->consumer_interface_inputs); |
this->consumer_interface_inputs = NULL; |
} |
/** |
* Hash table callback function that counts the elements in the table |
* |
* \sa num_elements |
*/ |
static void |
ht_count_callback(const void *, void *, void *closure) |
{ |
unsigned int *counter = (unsigned int *) closure; |
(*counter)++; |
} |
/** |
* Helper function to count the number of elements in a hash table. |
*/ |
static unsigned |
num_elements(hash_table *ht) |
{ |
unsigned int counter = 0; |
hash_table_call_foreach(ht, ht_count_callback, (void *) &counter); |
return counter; |
} |
/** |
* Helper function to determine whether a hash table is empty. |
*/ |
static bool |
is_empty(hash_table *ht) |
{ |
return num_elements(ht) == 0; |
} |
TEST_F(link_varyings, single_simple_input) |
{ |
ir_variable *const v = |
new(mem_ctx) ir_variable(glsl_type::vec(4), |
"a", |
ir_var_shader_in); |
ir.push_tail(v); |
ASSERT_TRUE(linker::populate_consumer_input_sets(mem_ctx, |
&ir, |
consumer_inputs, |
consumer_interface_inputs, |
junk)); |
EXPECT_EQ((void *) v, hash_table_find(consumer_inputs, "a")); |
EXPECT_EQ(1u, num_elements(consumer_inputs)); |
EXPECT_TRUE(is_empty(consumer_interface_inputs)); |
} |
TEST_F(link_varyings, gl_ClipDistance) |
{ |
const glsl_type *const array_8_of_float = |
glsl_type::get_array_instance(glsl_type::vec(1), 8); |
ir_variable *const clipdistance = |
new(mem_ctx) ir_variable(array_8_of_float, |
"gl_ClipDistance", |
ir_var_shader_in); |
clipdistance->data.explicit_location = true; |
clipdistance->data.location = VARYING_SLOT_CLIP_DIST0; |
clipdistance->data.explicit_index = 0; |
ir.push_tail(clipdistance); |
ASSERT_TRUE(linker::populate_consumer_input_sets(mem_ctx, |
&ir, |
consumer_inputs, |
consumer_interface_inputs, |
junk)); |
EXPECT_EQ(clipdistance, junk[VARYING_SLOT_CLIP_DIST0]); |
EXPECT_TRUE(is_empty(consumer_inputs)); |
EXPECT_TRUE(is_empty(consumer_interface_inputs)); |
} |
TEST_F(link_varyings, single_interface_input) |
{ |
ir_variable *const v = |
new(mem_ctx) ir_variable(simple_interface->fields.structure[0].type, |
simple_interface->fields.structure[0].name, |
ir_var_shader_in); |
v->init_interface_type(simple_interface); |
ir.push_tail(v); |
ASSERT_TRUE(linker::populate_consumer_input_sets(mem_ctx, |
&ir, |
consumer_inputs, |
consumer_interface_inputs, |
junk)); |
char *const full_name = interface_field_name(simple_interface); |
EXPECT_EQ((void *) v, hash_table_find(consumer_interface_inputs, full_name)); |
EXPECT_EQ(1u, num_elements(consumer_interface_inputs)); |
EXPECT_TRUE(is_empty(consumer_inputs)); |
} |
TEST_F(link_varyings, one_interface_and_one_simple_input) |
{ |
ir_variable *const v = |
new(mem_ctx) ir_variable(glsl_type::vec(4), |
"a", |
ir_var_shader_in); |
ir.push_tail(v); |
ir_variable *const iface = |
new(mem_ctx) ir_variable(simple_interface->fields.structure[0].type, |
simple_interface->fields.structure[0].name, |
ir_var_shader_in); |
iface->init_interface_type(simple_interface); |
ir.push_tail(iface); |
ASSERT_TRUE(linker::populate_consumer_input_sets(mem_ctx, |
&ir, |
consumer_inputs, |
consumer_interface_inputs, |
junk)); |
char *const iface_field_name = interface_field_name(simple_interface); |
EXPECT_EQ((void *) iface, hash_table_find(consumer_interface_inputs, |
iface_field_name)); |
EXPECT_EQ(1u, num_elements(consumer_interface_inputs)); |
EXPECT_EQ((void *) v, hash_table_find(consumer_inputs, "a")); |
EXPECT_EQ(1u, num_elements(consumer_inputs)); |
} |
TEST_F(link_varyings, invalid_interface_input) |
{ |
ir_variable *const v = |
new(mem_ctx) ir_variable(simple_interface, |
"named_interface", |
ir_var_shader_in); |
ASSERT_EQ(simple_interface, v->get_interface_type()); |
ir.push_tail(v); |
EXPECT_FALSE(linker::populate_consumer_input_sets(mem_ctx, |
&ir, |
consumer_inputs, |
consumer_interface_inputs, |
junk)); |
} |
TEST_F(link_varyings, interface_field_doesnt_match_noninterface) |
{ |
char *const iface_field_name = interface_field_name(simple_interface); |
/* The input shader has a single input variable name "a.v" |
*/ |
ir_variable *const in_v = |
new(mem_ctx) ir_variable(glsl_type::vec(4), |
iface_field_name, |
ir_var_shader_in); |
ir.push_tail(in_v); |
ASSERT_TRUE(linker::populate_consumer_input_sets(mem_ctx, |
&ir, |
consumer_inputs, |
consumer_interface_inputs, |
junk)); |
/* Create an output variable, "v", that is part of an interface block named |
* "a". They should not match. |
*/ |
ir_variable *const out_v = |
new(mem_ctx) ir_variable(simple_interface->fields.structure[0].type, |
simple_interface->fields.structure[0].name, |
ir_var_shader_in); |
out_v->init_interface_type(simple_interface); |
ir_variable *const match = |
linker::get_matching_input(mem_ctx, |
out_v, |
consumer_inputs, |
consumer_interface_inputs, |
junk); |
EXPECT_EQ(NULL, match); |
} |
TEST_F(link_varyings, interface_field_doesnt_match_noninterface_vice_versa) |
{ |
char *const iface_field_name = interface_field_name(simple_interface); |
/* In input shader has a single variable, "v", that is part of an interface |
* block named "a". |
*/ |
ir_variable *const in_v = |
new(mem_ctx) ir_variable(simple_interface->fields.structure[0].type, |
simple_interface->fields.structure[0].name, |
ir_var_shader_in); |
in_v->init_interface_type(simple_interface); |
ir.push_tail(in_v); |
ASSERT_TRUE(linker::populate_consumer_input_sets(mem_ctx, |
&ir, |
consumer_inputs, |
consumer_interface_inputs, |
junk)); |
/* Create an output variable "a.v". They should not match. |
*/ |
ir_variable *const out_v = |
new(mem_ctx) ir_variable(glsl_type::vec(4), |
iface_field_name, |
ir_var_shader_out); |
ir_variable *const match = |
linker::get_matching_input(mem_ctx, |
out_v, |
consumer_inputs, |
consumer_interface_inputs, |
junk); |
EXPECT_EQ(NULL, match); |
} |