Changeset View
Changeset View
Standalone View
Standalone View
source/blender/gpu/tests/gpu_shader_test.cc
| Show All 9 Lines | |||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include "gpu_testing.hh" | #include "gpu_testing.hh" | ||||
| namespace blender::gpu::tests { | namespace blender::gpu::tests { | ||||
| TEST_F(GPUTest, gpu_shader_compute) | TEST_F(GPUTest, gpu_shader_compute) | ||||
| { | { | ||||
| static constexpr int WIDTH = 512; | |||||
| static constexpr int HEIGHT = 512; | |||||
| if (!GPU_compute_shader_support()) { | if (!GPU_compute_shader_support()) { | ||||
| /* We can't test as a the platform does not support compute shaders. */ | /* We can't test as a the platform does not support compute shaders. */ | ||||
| std::cout << "Skipping compute shader test: platform not supported"; | std::cout << "Skipping compute shader test: platform not supported"; | ||||
| return; | return; | ||||
| } | } | ||||
| static constexpr int SIZE = 512; | |||||
| /* Build compute shader. */ | |||||
| const char *compute_glsl = R"( | const char *compute_glsl = R"( | ||||
| uniform float roll; | layout(local_size_x = 1, local_size_y = 1) in; | ||||
| uniform writeonly image2D destTex; | layout(rgba32f, binding = 0) uniform image2D img_output; | ||||
| layout (local_size_x = 16, local_size_y = 16) in; | |||||
| void main() { | void main() { | ||||
| ivec2 storePos = ivec2(gl_GlobalInvocationID.xy); | // base pixel colour for image | ||||
| float localCoef = length(vec2(ivec2(gl_LocalInvocationID.xy)-8)/8.0); | vec4 pixel = vec4(1.0, 0.5, 0.2, 1.0); | ||||
| float globalCoef = sin(float(gl_WorkGroupID.x+gl_WorkGroupID.y)*0.1 + roll)*0.5; | |||||
| imageStore(destTex, storePos, vec4(1.0-globalCoef*localCoef, 0.0, 0.0, 0.0)); | // output to a specific pixel in the image | ||||
| imageStore(img_output, ivec2(gl_GlobalInvocationID.xy), pixel); | |||||
| } | } | ||||
| )"; | )"; | ||||
| GPUShader *shader = GPU_shader_create_compute(compute_glsl, nullptr, nullptr, __func__); | GPUShader *shader = GPU_shader_create_compute( | ||||
| compute_glsl, nullptr, nullptr, "gpu_shader_compute"); | |||||
| EXPECT_NE(shader, nullptr); | EXPECT_NE(shader, nullptr); | ||||
| GPUTexture *texture = GPU_texture_create_2d(__func__, WIDTH, HEIGHT, 1, GPU_R32F, nullptr); | /* Create texture to store result and attach to shader. */ | ||||
| int binding = GPU_shader_get_texture_binding(shader, "destTex"); | GPUTexture *texture = GPU_texture_create_2d( | ||||
| "gpu_shader_compute", SIZE, SIZE, 0, GPU_RGBA32F, nullptr); | |||||
| EXPECT_NE(texture, nullptr); | |||||
| GPU_shader_bind(shader); | GPU_shader_bind(shader); | ||||
| GPU_shader_uniform_1f(shader, "roll", 1.0f); | GPU_texture_image_bind(texture, GPU_shader_get_texture_binding(shader, "img_output")); | ||||
| GPU_texture_bind(texture, binding); | |||||
| GPU_compute_dispatch(WIDTH / 16, HEIGHT / 16, 1); | /* Dispatch compute task. */ | ||||
| GPU_flush(); | GPU_compute_dispatch(shader, SIZE, SIZE, 1); | ||||
| GPU_finish(); | |||||
| GPU_shader_unbind(); | |||||
| /* Check if compute has been done. */ | |||||
| GPU_memory_barrier(GPU_BARRIER_TEXTURE_FETCH); | |||||
| float *data = static_cast<float *>(GPU_texture_read(texture, GPU_DATA_FLOAT, 0)); | float *data = static_cast<float *>(GPU_texture_read(texture, GPU_DATA_FLOAT, 0)); | ||||
| EXPECT_NE(data, nullptr); | EXPECT_NE(data, nullptr); | ||||
| for (int index = 0; index < SIZE * SIZE; index++) { | |||||
| for (int index = 0; index < WIDTH * HEIGHT; index++) { | EXPECT_FLOAT_EQ(data[index * 4 + 0], 1.0f); | ||||
| printf("%d: %f\n", index, data[index]); | EXPECT_FLOAT_EQ(data[index * 4 + 1], 0.5f); | ||||
| EXPECT_FLOAT_EQ(data[index * 4 + 2], 0.2f); | |||||
| EXPECT_FLOAT_EQ(data[index * 4 + 3], 1.0f); | |||||
| } | } | ||||
| MEM_freeN(data); | MEM_freeN(data); | ||||
| /* Cleanup. */ | |||||
| GPU_shader_unbind(); | |||||
| GPU_texture_unbind(texture); | GPU_texture_unbind(texture); | ||||
| GPU_texture_free(texture); | GPU_texture_free(texture); | ||||
| GPU_shader_free(shader); | GPU_shader_free(shader); | ||||
| } | } | ||||
| } // namespace blender::gpu::tests | } // namespace blender::gpu::tests | ||||