GPU: Added Tests For Blend state And Immediate Mode #107834

Merged
Jeroen Bakker merged 1 commits from Jeroen-Bakker/blender:vulkan-test-cases into main 2023-05-11 09:15:46 +02:00
3 changed files with 260 additions and 0 deletions

View File

@ -841,9 +841,11 @@ if(WITH_GTESTS)
tests/gpu_testing.cc
tests/framebuffer_test.cc
tests/immediate_test.cc
tests/index_buffer_test.cc
tests/push_constants_test.cc
tests/shader_test.cc
tests/state_blend_test.cc
tests/storage_buffer_test.cc
tests/texture_test.cc

View File

@ -0,0 +1,126 @@
/* SPDX-License-Identifier: Apache-2.0 */
#include "testing/testing.h"
#include "GPU_framebuffer.h"
#include "GPU_immediate.h"
#include "GPU_shader_builtin.h"
#include "gpu_testing.hh"
#include "BLI_math_vector.hh"
namespace blender::gpu::tests {
static constexpr int Size = 256;
static void test_immediate_one_plane()
{
GPUOffScreen *offscreen = GPU_offscreen_create(Size,
Size,
false,
GPU_RGBA16F,
GPU_TEXTURE_USAGE_ATTACHMENT |
GPU_TEXTURE_USAGE_HOST_READ,
nullptr);
BLI_assert(offscreen != nullptr);
GPU_offscreen_bind(offscreen, false);
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
float4 color(1.0, 0.5, 0.25, 1.0);
immUniformColor4fv(color);
immBegin(GPU_PRIM_TRI_STRIP, 4);
immVertex3f(pos, -1.0f, 1.0f, 0.0f);
immVertex3f(pos, 1.0f, 1.0f, 0.0f);
immVertex3f(pos, -1.0f, -1.0f, 0.0f);
immVertex3f(pos, 1.0f, -1.0f, 0.0f);
immEnd();
GPU_offscreen_unbind(offscreen, false);
GPU_flush();
/* Read back data and perform some basic tests. */
float read_data[4 * Size * Size];
GPU_offscreen_read_color(offscreen, GPU_DATA_FLOAT, &read_data);
for (int pixel_index = 0; pixel_index < Size * Size; pixel_index++) {
float4 read_color = float4(&read_data[pixel_index * 4]);
EXPECT_EQ(read_color, color);
}
GPU_offscreen_free(offscreen);
}
GPU_TEST(immediate_one_plane)
/**
* Draws two planes with two different colors.
* - Tests that both planes are stored in the same buffer (depends on backend).
* - Test that data of the first plane isn't overwritten by the second plane.
* (push constants, buffer, bind points etc.)
*/
static void test_immediate_two_planes()
{
GPUOffScreen *offscreen = GPU_offscreen_create(Size,
Size,
false,
GPU_RGBA16F,
GPU_TEXTURE_USAGE_ATTACHMENT |
GPU_TEXTURE_USAGE_HOST_READ,
nullptr);
BLI_assert(offscreen != nullptr);
GPU_offscreen_bind(offscreen, false);
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
float4 color(1.0, 0.5, 0.25, 1.0);
immUniformColor4fv(color);
immBegin(GPU_PRIM_TRI_STRIP, 4);
immVertex3f(pos, -1.0f, 1.0f, 0.0f);
immVertex3f(pos, 0.0f, 1.0f, 0.0f);
immVertex3f(pos, -1.0f, -1.0f, 0.0f);
immVertex3f(pos, 0.0f, -1.0f, 0.0f);
immEnd();
float4 color2(0.25, 0.5, 1.0, 1.0);
immUniformColor4fv(color2);
immBegin(GPU_PRIM_TRI_STRIP, 4);
immVertex3f(pos, 0.0f, 1.0f, 0.0f);
immVertex3f(pos, 1.0f, 1.0f, 0.0f);
immVertex3f(pos, 0.0f, -1.0f, 0.0f);
immVertex3f(pos, 1.0f, -1.0f, 0.0f);
immEnd();
GPU_offscreen_unbind(offscreen, false);
GPU_flush();
/* Read back data and perform some basic tests.
* Not performing detailed tests as there might be driver specific limitations. */
float read_data[4 * Size * Size];
GPU_offscreen_read_color(offscreen, GPU_DATA_FLOAT, &read_data);
int64_t color_num = 0;
int64_t color2_num = 0;
for (int pixel_index = 0; pixel_index < Size * Size; pixel_index++) {
float4 read_color = float4(&read_data[pixel_index * 4]);
if (read_color == color) {
color_num++;
}
else if (read_color == color2) {
color2_num++;
}
else {
EXPECT_TRUE(read_color == color || read_color == color2);
}
}
EXPECT_TRUE(color_num > 0);
EXPECT_TRUE(color2_num > 0);
GPU_offscreen_free(offscreen);
}
GPU_TEST(immediate_two_planes)
} // namespace blender::gpu::tests

View File

@ -0,0 +1,132 @@
/* SPDX-License-Identifier: Apache-2.0 */
#include "testing/testing.h"
#include "gpu_testing.hh"
#include "GPU_batch.h"
#include "GPU_batch_presets.h"
#include "GPU_framebuffer.h"
#include "GPU_matrix.h"
#include "BLI_math_vector.hh"
#include "intern/draw_cache.h"
namespace blender::gpu::tests {
template<eGPUBlend blend_type>
void blend_test(float4 source_a, float4 source_b, float4 expected_result)
{
GPUOffScreen *offscreen = GPU_offscreen_create(1,
1,
false,
GPU_RGBA16F,
GPU_TEXTURE_USAGE_ATTACHMENT |
GPU_TEXTURE_USAGE_HOST_READ,
nullptr);
BLI_assert(offscreen != nullptr);
GPU_offscreen_bind(offscreen, false);
GPUTexture *color_texture = GPU_offscreen_color_texture(offscreen);
GPU_texture_clear(color_texture, GPU_DATA_FLOAT, source_a);
GPUBatch *batch = DRW_cache_quad_get();
GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
GPU_batch_uniform_4fv(batch, "color", source_b);
GPU_blend(blend_type);
GPU_batch_draw(batch);
GPU_offscreen_unbind(offscreen, false);
GPU_flush();
float4 read_back;
GPU_memory_barrier(GPU_BARRIER_TEXTURE_FETCH);
GPU_offscreen_read_color(offscreen, GPU_DATA_FLOAT, &read_back);
EXPECT_EQ(read_back, expected_result);
GPU_offscreen_free(offscreen);
DRW_shape_cache_free();
}
static void test_blend_none()
{
blend_test<GPU_BLEND_NONE>(float4(1.0f, 0.0f, 1.0f, 1.0f),
float4(0.0f, 1.0f, 0.0f, 0.5f),
float4(0.0f, 1.0f, 0.0f, 0.5f));
}
GPU_TEST(blend_none)
static void test_blend_alpha()
{
blend_test<GPU_BLEND_ALPHA>(float4(1.0f, 0.0f, 1.0f, 1.0f),
float4(0.0f, 1.0f, 0.0f, 0.5f),
float4(0.5f, 0.5f, 0.5f, 1.0f));
}
GPU_TEST(blend_alpha)
static void test_blend_alpha_premult()
{
blend_test<GPU_BLEND_ALPHA_PREMULT>(float4(1.0f, 0.0f, 1.0f, 1.0f),
float4(0.0f, 1.0f, 0.0f, 0.5f),
float4(0.5f, 1.0f, 0.5f, 1.0f));
}
GPU_TEST(blend_alpha_premult)
static void test_blend_additive()
{
blend_test<GPU_BLEND_ADDITIVE>(float4(1.0f, 0.0f, 1.0f, 1.0f),
float4(0.0f, 1.0f, 0.0f, 0.5f),
float4(1.0f, 0.5f, 1.0f, 1.0f));
}
GPU_TEST(blend_additive)
static void test_blend_additive_premult()
{
blend_test<GPU_BLEND_ADDITIVE_PREMULT>(float4(1.0f, 0.0f, 1.0f, 1.0f),
float4(0.0f, 1.0f, 0.0f, 0.5f),
float4(1.0f, 1.0f, 1.0f, 1.5f));
}
GPU_TEST(blend_additive_premult)
static void test_blend_multiply()
{
blend_test<GPU_BLEND_MULTIPLY>(float4(1.0f, 0.0f, 1.0f, 1.0f),
float4(0.0f, 1.0f, 0.0f, 0.5f),
float4(0.0f, 0.0f, 0.0f, 0.5f));
}
GPU_TEST(blend_multiply)
static void test_blend_subtract()
{
blend_test<GPU_BLEND_SUBTRACT>(float4(1.0f, 1.0f, 1.0f, 1.0f),
float4(0.0f, 1.0f, 0.0f, 0.5f),
float4(1.0f, 0.0f, 1.0f, 0.5f));
}
GPU_TEST(blend_subtract)
static void test_blend_invert()
{
blend_test<GPU_BLEND_INVERT>(float4(1.0f, 1.0f, 1.0f, 1.0f),
float4(0.0f, 1.0f, 0.0f, 0.5f),
float4(0.0f, 0.0f, 0.0f, 1.0f));
}
GPU_TEST(blend_invert)
static void test_blend_oit()
{
blend_test<GPU_BLEND_OIT>(float4(1.0f, 1.0f, 1.0f, 1.0f),
float4(0.0f, 1.0f, 0.0f, 0.5f),
float4(1.0f, 2.0f, 1.0f, 0.5f));
}
GPU_TEST(blend_oit)
static void test_blend_background()
{
blend_test<GPU_BLEND_BACKGROUND>(float4(1.0f, 1.0f, 1.0f, 1.0f),
float4(0.0f, 1.0f, 0.0f, 0.5f),
float4(0.5f, 0.5f, 0.5f, 0.5f));
}
GPU_TEST(blend_background)
} // namespace blender::gpu::tests