| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 |
- // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
- // All rights reserved.
- // Code licensed under the BSD License.
- // http://www.anki3d.org/LICENSE
- #include <Tests/Framework/Framework.h>
- #include <AnKi/ShaderCompiler/ShaderCompiler.h>
- #include <AnKi/ShaderCompiler/ShaderDump.h>
- #include <AnKi/Util/ThreadHive.h>
- ANKI_TEST(ShaderCompiler, ShaderProgramCompilerSimple)
- {
- const CString sourceCode = R"(
- #pragma anki mutator INSTANCE_COUNT 1 2 4
- struct Foo
- {
- Mat4 m_mat;
- };
- struct Instanced
- {
- Mat4 m_ankiMvp;
- Mat3 m_ankiRotationMat;
- Mat4 m_ankiModelViewMat;
- Mat4 m_ankiPrevMvp;
- Foo m_foo[2];
- };
- layout(push_constant) uniform ankiMaterial
- {
- Vec4 u_whatever;
- Instanced u_ankiPerInstance[INSTANCE_COUNT];
- Vec4 u_color;
- };
- layout(set = 0, binding = 1) uniform texture2D u_tex2d;
- layout(set = 0, binding = 1) uniform texture3D u_tex3d;
- layout(set = 0, binding = 2) uniform sampler u_sampler;
- layout(set = 0, binding = 3) buffer ssbo
- {
- Foo u_mats[];
- };
- #pragma anki start vert
- out gl_PerVertex
- {
- Vec4 gl_Position;
- };
- void main()
- {
- gl_Position = u_ankiPerInstance[gl_InstanceIndex].m_ankiMvp * u_mats[gl_InstanceIndex].m_mat * Vec4(gl_VertexID);
- }
- #pragma anki end vert
- #pragma anki start frag
- layout(location = 0) out Vec3 out_color;
- void main()
- {
- out_color = Vec3(0);
- if(INSTANCE_COUNT == 1)
- out_color += textureLod(sampler2D(u_tex2d, u_sampler), Vec2(0), 0.0).rgb;
- else if(INSTANCE_COUNT == 2)
- out_color += textureLod(sampler3D(u_tex3d, u_sampler), Vec3(0), 0.0).rgb;
- else
- out_color += textureLod(sampler2D(u_tex2d, u_sampler), Vec2(0), 0.0).rgb
- + textureLod(sampler3D(u_tex3d, u_sampler), Vec3(0), 0.0).rgb;
- out_color += u_color.xyz;
- }
- #pragma anki end frag
- )";
- // Write the file
- {
- File file;
- ANKI_TEST_EXPECT_NO_ERR(file.open("test.glslp", FileOpenFlag::kWrite));
- ANKI_TEST_EXPECT_NO_ERR(file.writeText(sourceCode));
- }
- class Fsystem : public ShaderCompilerFilesystemInterface
- {
- public:
- Error readAllText(CString filename, ShaderCompilerString& txt) final
- {
- File file;
- ANKI_CHECK(file.open(filename, FileOpenFlag::kRead));
- ANKI_CHECK(file.readAllText(txt));
- return Error::kNone;
- }
- } fsystem;
- HeapMemoryPool pool(allocAligned, nullptr);
- const U32 threadCount = 8;
- ThreadHive hive(threadCount, &pool);
- class TaskManager : public ShaderCompilerAsyncTaskInterface
- {
- public:
- ThreadHive* m_hive = nullptr;
- HeapMemoryPool* m_pool;
- void enqueueTask(void (*callback)(void* userData), void* userData)
- {
- struct Ctx
- {
- void (*m_callback)(void* userData);
- void* m_userData;
- HeapMemoryPool* m_pool;
- };
- Ctx* ctx = newInstance<Ctx>(*m_pool);
- ctx->m_callback = callback;
- ctx->m_userData = userData;
- ctx->m_pool = m_pool;
- m_hive->submitTask(
- [](void* userData, [[maybe_unused]] U32 threadId, [[maybe_unused]] ThreadHive& hive,
- [[maybe_unused]] ThreadHiveSemaphore* signalSemaphore) {
- Ctx* ctx = static_cast<Ctx*>(userData);
- ctx->m_callback(ctx->m_userData);
- deleteInstance(*ctx->m_pool, ctx);
- },
- ctx);
- }
- Error joinTasks()
- {
- m_hive->waitAllTasks();
- return Error::kNone;
- }
- } taskManager;
- taskManager.m_hive = &hive;
- taskManager.m_pool = &pool;
- ShaderBinary* binary;
- ANKI_TEST_EXPECT_NO_ERR(compileShaderProgram("test.glslp", true, true, ShaderModel::k6_8, fsystem, nullptr, &taskManager, {}, binary));
- #if 1
- ShaderCompilerString dis;
- ShaderDumpOptions options;
- dumpShaderBinary(options, *binary, dis);
- ANKI_LOGI("Binary disassembly:\n%s\n", dis.cstr());
- #endif
- }
- ANKI_TEST(ShaderCompiler, ShaderProgramCompiler)
- {
- const CString sourceCode = R"(
- #pragma anki mutator INSTANCE_COUNT 1 2 4 8 16 32 64
- #pragma anki mutator LOD 0 1 2
- #pragma anki mutator PASS 0 1 2 3
- #pragma anki mutator DIFFUSE_TEX 0 1
- #pragma anki mutator SPECULAR_TEX 0 1
- #pragma anki mutator ROUGHNESS_TEX 0 1
- #pragma anki mutator METAL_TEX 0 1
- #pragma anki mutator NORMAL_TEX 0 1
- #pragma anki mutator PARALLAX 0 1
- #pragma anki mutator EMISSIVE_TEX 0 1
- #pragma anki mutator BONES 0 1
- #pragma anki mutator VELOCITY 0 1
- #pragma anki rewrite_mutation PASS 1 DIFFUSE_TEX 1 to PASS 1 DIFFUSE_TEX 0
- #pragma anki rewrite_mutation PASS 2 DIFFUSE_TEX 1 to PASS 2 DIFFUSE_TEX 0
- #pragma anki rewrite_mutation PASS 3 DIFFUSE_TEX 1 to PASS 2 DIFFUSE_TEX 0
- #pragma anki rewrite_mutation PASS 1 SPECULAR_TEX 1 to PASS 1 SPECULAR_TEX 0
- #pragma anki rewrite_mutation PASS 2 SPECULAR_TEX 1 to PASS 2 SPECULAR_TEX 0
- #pragma anki rewrite_mutation PASS 3 SPECULAR_TEX 1 to PASS 2 SPECULAR_TEX 0
- #pragma anki rewrite_mutation PASS 1 ROUGHNESS_TEX 1 to PASS 1 ROUGHNESS_TEX 0
- #pragma anki rewrite_mutation PASS 2 ROUGHNESS_TEX 1 to PASS 2 ROUGHNESS_TEX 0
- #pragma anki rewrite_mutation PASS 3 ROUGHNESS_TEX 1 to PASS 2 ROUGHNESS_TEX 0
- #pragma anki rewrite_mutation PASS 1 METAL_TEX 1 to PASS 1 METAL_TEX 0
- #pragma anki rewrite_mutation PASS 2 METAL_TEX 1 to PASS 2 METAL_TEX 0
- #pragma anki rewrite_mutation PASS 3 METAL_TEX 1 to PASS 2 METAL_TEX 0
- #pragma anki rewrite_mutation PASS 1 NORMAL_TEX 1 to PASS 1 NORMAL_TEX 0
- #pragma anki rewrite_mutation PASS 2 NORMAL_TEX 1 to PASS 2 NORMAL_TEX 0
- #pragma anki rewrite_mutation PASS 3 NORMAL_TEX 1 to PASS 2 NORMAL_TEX 0
- #pragma anki rewrite_mutation PASS 1 EMISSIVE_TEX 1 to PASS 1 EMISSIVE_TEX 0
- #pragma anki rewrite_mutation PASS 2 EMISSIVE_TEX 1 to PASS 2 EMISSIVE_TEX 0
- #pragma anki rewrite_mutation PASS 3 EMISSIVE_TEX 1 to PASS 2 EMISSIVE_TEX 0
- #pragma anki rewrite_mutation PASS 1 VELOCITY 1 to PASS 1 VELOCITY 0
- #pragma anki rewrite_mutation PASS 2 VELOCITY 1 to PASS 2 VELOCITY 0
- #pragma anki rewrite_mutation PASS 3 VELOCITY 1 to PASS 2 VELOCITY 0
- layout(set = 0, binding = 0) uniform ankiMaterial
- {
- Mat4 u_ankiMvp[INSTANCE_COUNT];
- #if PASS == 0
- Mat3 u_ankiRotationMat[INSTANCE_COUNT];
- #endif
- #if PASS == 0 && PARALLAX == 1
- Mat4 u_ankiModelViewMat[INSTANCE_COUNT];
- #endif
- #if PASS == 0 && VELOCITY == 1
- Mat4 u_ankiPrevMvp[INSTANCE_COUNT];
- #endif
- };
- #if PASS == 0
- #if DIFFUSE_TEX == 0
- ANKI_SPECIALIZATION_CONSTANT_VEC3(diffColor, 0u);
- #else
- layout(set = 0, binding = 1) uniform texture2D diffTex;
- #endif
- #if SPECULAR_TEX == 0
- ANKI_SPECIALIZATION_CONSTANT_VEC3(specColor, 3u);
- #else
- layout(set = 0, binding = 2) uniform texture2D specTex;
- #endif
- #if ROUGHNESS_TEX == 0
- ANKI_SPECIALIZATION_CONSTANT_F32(roughness, 6u);
- #else
- layout(set = 0, binding = 3) uniform texture2D roughnessTex;
- #endif
- #if METAL_TEX == 0
- ANKI_SPECIALIZATION_CONSTANT_F32(metallic, 7u);
- #else
- layout(set = 0, binding = 4) uniform texture2D metallicTex;
- #endif
- #if EMISSIVE_TEX == 0
- ANKI_SPECIALIZATION_CONSTANT_VEC3(emission, 8u, Vec3(0.0));
- #else
- layout(set = 0, binding = 5) uniform texture2D emissiveTex;
- #endif
- #if PARALLAX == 1 && LOD == 0
- ANKI_SPECIALIZATION_CONSTANT_F32(heightMapScale, 11u);
- layout(set = 0, binding = 6) uniform texture2D heightTex;
- #endif
- #endif
- #pragma anki start vert
- out gl_PerVertex
- {
- Vec4 gl_Position;
- };
- void main()
- {
- gl_Position = Vec4(gl_VertexIndex);
- }
- #pragma anki end vert
- #pragma anki start frag
- layout(location = 0) out Vec3 out_color;
- void main()
- {
- out_color = Vec3(0.0);
- }
- #pragma anki end frag
- )";
- // Write the file
- {
- File file;
- ANKI_TEST_EXPECT_NO_ERR(file.open("test.glslp", FileOpenFlag::kWrite));
- ANKI_TEST_EXPECT_NO_ERR(file.writeText(sourceCode));
- }
- class Fsystem : public ShaderCompilerFilesystemInterface
- {
- public:
- Error readAllText(CString filename, ShaderCompilerString& txt) final
- {
- File file;
- ANKI_CHECK(file.open(filename, FileOpenFlag::kRead));
- ANKI_CHECK(file.readAllText(txt));
- return Error::kNone;
- }
- } fsystem;
- HeapMemoryPool pool(allocAligned, nullptr);
- const U32 threadCount = 24;
- ThreadHive hive(threadCount, &pool);
- class TaskManager : public ShaderCompilerAsyncTaskInterface
- {
- public:
- ThreadHive* m_hive = nullptr;
- HeapMemoryPool* m_pool = nullptr;
- void enqueueTask(void (*callback)(void* userData), void* userData)
- {
- struct Ctx
- {
- void (*m_callback)(void* userData);
- void* m_userData;
- HeapMemoryPool* m_pool;
- };
- Ctx* ctx = newInstance<Ctx>(*m_pool);
- ctx->m_callback = callback;
- ctx->m_userData = userData;
- ctx->m_pool = m_pool;
- m_hive->submitTask(
- [](void* userData, [[maybe_unused]] U32 threadId, [[maybe_unused]] ThreadHive& hive,
- [[maybe_unused]] ThreadHiveSemaphore* signalSemaphore) {
- Ctx* ctx = static_cast<Ctx*>(userData);
- ctx->m_callback(ctx->m_userData);
- deleteInstance(*ctx->m_pool, ctx);
- },
- ctx);
- }
- Error joinTasks()
- {
- m_hive->waitAllTasks();
- return Error::kNone;
- }
- } taskManager;
- taskManager.m_hive = &hive;
- taskManager.m_pool = &pool;
- ShaderBinary* binary;
- ANKI_TEST_EXPECT_NO_ERR(compileShaderProgram("test.glslp", true, true, ShaderModel::k6_8, fsystem, nullptr, &taskManager, {}, binary));
- #if 1
- ShaderCompilerString dis;
- ShaderDumpOptions options;
- dumpShaderBinary(options, *binary, dis);
- ANKI_LOGI("Binary disassembly:\n%s\n", dis.cstr());
- #endif
- }
|