Skip to content

Commit

Permalink
Added Slang example 001_HelloTriangle_Slang.cpp
Browse files Browse the repository at this point in the history
  • Loading branch information
corporateshark committed Aug 17, 2024
1 parent 5a3a4b8 commit d780cc2
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 26 deletions.
6 changes: 4 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ option(LVK_WITH_WAYLAND "Enable Wayland" OFF
option(LVK_WITH_IMPLOT "Enable ImPlot" ON)
option(LVK_WITH_OPENXR "Enable OpenXR" OFF)
option(LVK_WITH_ANDROID_VALIDATION "Enable validation layers on Android" ON)
option(LVK_WITH_SLANG "Enable Slang compiler" OFF)

cmake_dependent_option(LVK_WITH_VULKAN_PORTABILITY "Enable portability extension" ON "APPLE" OFF)

Expand All @@ -34,8 +35,9 @@ if(LVK_WITH_SAMPLES AND NOT LVK_WITH_GLFW)
endif()

if(ANDROID)
message(STATUS "WARNING: LVK_WITH_GLFW and LVK_WITH_SAMPLES were set to OFF for Android")
message(STATUS "WARNING: LVK_WITH_GLFW and LVK_WITH_SLANG were set to OFF for Android")
set(LVK_WITH_GLFW OFF)
set(LVK_WITH_SLANG OFF)
endif()

if(LVK_WITH_WAYLAND AND (ANDROID OR APPLE OR WIN32))
Expand Down Expand Up @@ -152,7 +154,7 @@ if(LVK_WITH_OPENXR)
endif()

# temporary
if(NOT LVK_USE_CUSTOM_MOLTENVK)
if(NOT LVK_USE_CUSTOM_MOLTENVK AND NOT LVK_WITH_SLANG)
find_package(Vulkan REQUIRED)
endif()

Expand Down
30 changes: 30 additions & 0 deletions lvk/vulkan/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,32 @@ lvk_set_folder(SPIRV "third-party/glslang")
lvk_set_folder(glslang-default-resource-limits "third-party/glslang")
# cmake-format: on

# slang
# cmake-format: off
if(LVK_WITH_SLANG)
set(SLANG_ENABLE_CUDA OFF CACHE BOOL "")
set(SLANG_ENABLE_OPTIX OFF CACHE BOOL "")
set(SLANG_ENABLE_NVAPI OFF CACHE BOOL "")
set(SLANG_ENABLE_XLIB OFF CACHE BOOL "")
set(SLANG_ENABLE_AFTERMATH OFF CACHE BOOL "")
set(SLANG_ENABLE_DX_ON_VK OFF CACHE BOOL "")
set(SLANG_ENABLE_GFX OFF CACHE BOOL "")
set(SLANG_ENABLE_SLANGC OFF CACHE BOOL "")
set(SLANG_ENABLE_SLANGRT ON CACHE BOOL "")
set(SLANG_ENABLE_SLANG_GLSLANG OFF CACHE BOOL "")
set(SLANG_ENABLE_TESTS OFF CACHE BOOL "")
set(SLANG_ENABLE_EXAMPLES OFF CACHE BOOL "")
set(SLANG_ENABLE_REPLAYER OFF CACHE BOOL "")
set(SLANG_ENABLE_PREBUILT_BINARIES OFF CACHE BOOL "")
add_subdirectory(${LVK_ROOT_DIR}/third-party/deps/src/slang "slang")
lvk_set_folder(compiler-core "third-party/slang")
lvk_set_folder(core "third-party/slang")
lvk_set_folder(slang "third-party/slang")
lvk_set_folder(slangd "third-party/slang")
lvk_set_folder(slang-rt "third-party/slang")
endif()
# cmake-format: on

# SPIRV-Reflect
set(SPIRV_REFLECT_EXECUTABLE OFF CACHE BOOL "")
set(SPIRV_REFLECT_STATIC_LIB ON CACHE BOOL "")
Expand All @@ -52,6 +78,10 @@ endif()
target_link_libraries(LVKVulkan PRIVATE LVKLibrary)
target_link_libraries(LVKVulkan PRIVATE glslang SPIRV glslang-default-resource-limits)
target_link_libraries(LVKVulkan PRIVATE spirv-reflect-static)
if(LVK_WITH_SLANG)
target_link_libraries(LVKVulkan PRIVATE slang)
target_link_libraries(LVKVulkan PRIVATE slang-rt)
endif()

if(LVK_USE_CUSTOM_MOLTENVK)
target_include_directories(LVKVulkan PUBLIC "${LVK_CUSTOM_MOLTENVK_PATH}/include")
Expand Down
164 changes: 140 additions & 24 deletions samples/001_HelloTriangle_Slang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,33 +16,55 @@
#include <GLFW/glfw3.h>
#endif

const char* codeVS = R"(
#version 460
layout (location=0) out vec3 color;
const vec2 pos[3] = vec2[3](
vec2(-0.6, -0.4),
vec2( 0.6, -0.4),
vec2( 0.0, 0.6)
#include <slang.h>
#include <slang-com-helper.h>
#include <slang-com-ptr.h>
#include <core/slang-basic.h>

#include <fstream>
#include <ios>
#include <iostream>
#include <vector>

const char* codeSlang = R"(
static const float2 pos[3] = float2[3](
float2(-0.6, -0.4),
float2( 0.6, -0.4),
float2( 0.0, 0.6)
);
const vec3 col[3] = vec3[3](
vec3(1.0, 0.0, 0.0),
vec3(0.0, 1.0, 0.0),
vec3(0.0, 0.0, 1.0)
static const float3 col[3] = float3[3](
float3(1.0, 0.0, 0.0),
float3(0.0, 1.0, 0.0),
float3(0.0, 0.0, 1.0)
);
void main() {
gl_Position = vec4(pos[gl_VertexIndex], 0.0, 1.0);
color = col[gl_VertexIndex];
}
)";
const char* codeFS = R"(
#version 460
layout (location=0) in vec3 color;
layout (location=0) out vec4 out_FragColor;
struct OutVertex {
float3 color;
};
void main() {
out_FragColor = vec4(color, 1.0);
struct Fragment {
float4 color;
};
struct VertexStageOutput {
OutVertex vertex : OutVertex;
float4 sv_position : SV_Position;
};
[shader("vertex")]
VertexStageOutput vertexMain(uint vertexID : SV_VertexID) {
VertexStageOutput output;
output.vertex.color = col[vertexID];
output.sv_position = float4(pos[vertexID], 0.0, 1.0);
return output;
}
[shader("fragment")]
float4 fragmentMain(OutVertex vertex : OutVertex) : SV_Target {
return float4(vertex.color, 1.0);
}
)";

int width_ = 800;
Expand All @@ -54,9 +76,103 @@ std::unique_ptr<lvk::IContext> ctx_;
lvk::Holder<lvk::ShaderModuleHandle> vert_;
lvk::Holder<lvk::ShaderModuleHandle> frag_;

std::vector<uint8_t> compileSlangToSPIRV(const char* code, lvk::ShaderStage stage) {
using namespace Slang;

ComPtr<slang::IGlobalSession> slangGlobalSession;
if (SLANG_FAILED(slang::createGlobalSession(slangGlobalSession.writeRef()))) {
return {};
}

const slang::TargetDesc targetDesc = {
.format = SLANG_SPIRV,
.profile = slangGlobalSession->findProfile("spirv_1_6"),
.flags = SLANG_TARGET_FLAG_GENERATE_SPIRV_DIRECTLY,
};

const slang::SessionDesc sessionDesc = {
.targets = &targetDesc,
.targetCount = 1,
};

ComPtr<slang::ISession> session;
if (SLANG_FAILED(slangGlobalSession->createSession(sessionDesc, session.writeRef()))) {
return {};
}

slang::IModule* slangModule = nullptr;
{
ComPtr<slang::IBlob> diagnosticBlob;
slangModule = session->loadModuleFromSourceString("", "", code, diagnosticBlob.writeRef());
if (diagnosticBlob) {
LLOGW("%s", (const char*)diagnosticBlob->getBufferPointer());
}
if (!slangModule) {
return {};
}
}

ComPtr<slang::IEntryPoint> entryPointVert;
ComPtr<slang::IEntryPoint> entryPointFrag;
slangModule->findEntryPointByName("vertexMain", entryPointVert.writeRef());
slangModule->findEntryPointByName("fragmentMain", entryPointFrag.writeRef());

Slang::List<slang::IComponentType*> componentTypes;
componentTypes.add(slangModule);
int entryPointCount = 0;
int vertexEntryPointIndex = entryPointCount++;
componentTypes.add(entryPointVert);
int fragmentEntryPointIndex = entryPointCount++;
componentTypes.add(entryPointFrag);

ComPtr<slang::IComponentType> composedProgram;
{
ComPtr<slang::IBlob> diagnosticBlob;
SlangResult result = session->createCompositeComponentType(
componentTypes.getBuffer(), componentTypes.getCount(), composedProgram.writeRef(), diagnosticBlob.writeRef());
if (diagnosticBlob) {
LLOGW("%s", (const char*)diagnosticBlob->getBufferPointer());
}
if (SLANG_FAILED(result)) {
return {};
}
}

ComPtr<slang::IBlob> spirvCode;
{
ComPtr<slang::IBlob> diagnosticBlob;
const int entryPoint = stage == lvk::Stage_Vert ? vertexEntryPointIndex : fragmentEntryPointIndex;
SlangResult result = composedProgram->getEntryPointCode(entryPoint, 0, spirvCode.writeRef(), diagnosticBlob.writeRef());
if (diagnosticBlob) {
LLOGW("%s", (const char*)diagnosticBlob->getBufferPointer());
}
if (SLANG_FAILED(result)) {
return {};
}
}

const uint8_t* ptr = reinterpret_cast<const uint8_t*>(spirvCode->getBufferPointer());

return std::vector<uint8_t>(ptr, ptr + spirvCode->getBufferSize());
}

lvk::Holder<lvk::ShaderModuleHandle> slangCreateShaderModule(const char* code,
lvk::ShaderStage stage,
const char* debugName,
const bool dumpSPIRV = false) {
const std::vector<uint8_t> spirv = compileSlangToSPIRV(code, stage);

if (dumpSPIRV) {
std::ofstream fout("dump." + std::to_string(stage), std::ios::out | std::ios::binary);
fout.write(reinterpret_cast<const char*>(spirv.data()), spirv.size());
}

return ctx_->createShaderModule({spirv.data(), spirv.size(), stage, debugName});
}

void init() {
vert_ = ctx_->createShaderModule({codeVS, lvk::Stage_Vert, "Shader Module: main (vert)"});
frag_ = ctx_->createShaderModule({codeFS, lvk::Stage_Frag, "Shader Module: main (frag)"});
vert_ = slangCreateShaderModule(codeSlang, lvk::Stage_Vert, "Shader Module: main (vert)");
frag_ = slangCreateShaderModule(codeSlang, lvk::Stage_Frag, "Shader Module: main (frag)");

renderPipelineState_Triangle_ = ctx_->createRenderPipeline(
{
Expand Down
2 changes: 2 additions & 0 deletions samples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -140,4 +140,6 @@ ADD_DEMO_LINK_LIBRARIES("Tiny_MeshLarge" ktx)
# Slang
if(LVK_WITH_SLANG)
ADD_DEMO("001_HelloTriangle_Slang")
target_link_libraries(001_HelloTriangle_Slang PRIVATE slang-rt)
target_link_libraries(001_HelloTriangle_Slang PRIVATE core)
endif()

0 comments on commit d780cc2

Please sign in to comment.