rhi新增设置参数接口

This commit is contained in:
Nanako 2024-02-07 21:38:26 +08:00
parent c302939176
commit 93980885a6
44 changed files with 1095 additions and 99 deletions

3
.gitmodules vendored
View File

@ -10,3 +10,6 @@
[submodule "third_party/spdlog"]
path = third_party/spdlog
url = https://github.com/gabime/spdlog.git
[submodule "third_party/glslang"]
path = third_party/glslang
url = https://github.com/KhronosGroup/glslang.git

View File

@ -63,6 +63,7 @@ add_subdirectory(third_party/portaudio)
add_subdirectory(third_party/spdlog)
add_subdirectory(third_party/slang)
add_subdirectory(third_party/glad)
add_subdirectory(third_party/glslang)
# setup portaudio
set(PA_USE_ASIO ON CACHE BOOL "" FORCE)
@ -140,5 +141,8 @@ set(SPDLOG_WCHAR_SUPPORT ON CACHE BOOL "" FORCE)
set(SPDLOG_ENABLE_PCH ON CACHE BOOL "" FORCE)
set(SPDLOG_USE_STD_FORMAT OFF CACHE BOOL "" FORCE)
# setup glslang
set(ENABLE_OPT OFF CACHE BOOL "" FORCE)
# install
install(DIRECTORY ${CMAKE_SOURCE_DIR}/third_party/imgui/imgui/misc/fonts DESTINATION ${CMAKE_BINARY_DIR}/bin)

View File

@ -8,10 +8,10 @@ retrieve_files(ALL_FILES)
add_library(${PROJECT_NAME} SHARED ${ALL_FILES})
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} spdlog imgui slang glad)
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} spdlog imgui slang glad glslang)
target_link_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} spdlog imgui glad)
target_link_libraries(${PROJECT_NAME} PUBLIC imgui spdlog ${SDL2_LIBRARIES} slang glad)
target_link_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} spdlog imgui glad glslang)
target_link_libraries(${PROJECT_NAME} PUBLIC imgui spdlog ${SDL2_LIBRARIES} slang glad glslang)
target_precompile_headers(${PROJECT_NAME} PUBLIC extern.h)

View File

@ -19,21 +19,16 @@
bool g_is_running = true;
bool g_exit_requested = false;
slang::IGlobalSession* g_slang_global_session = nullptr;
Slang::ComPtr<slang::IGlobalSession> g_slang_global_session = nullptr;
application* g_app_instance = nullptr;
application::~application()
{
application::shutdown();
}
void application::init(window_params in_window_params, int argc, char** argv)
{
slang::createGlobalSession(&g_slang_global_session);
slang::createGlobalSession(g_slang_global_session.writeRef());
try
{
auto async_file = spdlog::basic_logger_mt<spdlog::async_factory>("async_file_logger", "logs/log.txt");
async_spdlog_ = spdlog::basic_logger_mt<spdlog::async_factory>("async_file_logger", "logs/log.txt");
}
catch (const spdlog::spdlog_ex &ex)
{
@ -208,15 +203,28 @@ int application::run()
draw_gui();
renderer_->end_frame(window_);
}
shutdown();
return 0;
}
void application::shutdown()
{
init_imgui(nullptr);
renderer_->shutdown();
ImGui::DestroyContext();
SDL_HideWindow(window_);
SDL_DestroyWindow(window_);
window_ = nullptr;
renderer_->post_shutdown();
delete renderer_;
renderer_ = nullptr;
SDL_Quit();
}
std::shared_ptr<texture> application::load_texture(const std::string& path) const

View File

@ -2,6 +2,7 @@
#include <string>
#include "SDL.h"
#include "imgui.h"
#include "slang-com-ptr.h"
#include "slang.h"
class render_target;
@ -11,7 +12,7 @@ class application;
extern bool g_is_running;
extern bool g_exit_requested;
extern slang::IGlobalSession* g_slang_global_session;
extern Slang::ComPtr<slang::IGlobalSession>g_slang_global_session;
extern application* g_app_instance;
struct window_params
@ -35,7 +36,7 @@ public:
{
g_app_instance = this;
}
virtual ~application();
virtual ~application() = default;
application(const application&) = delete;
application(application&&) = delete;
static application* get()
@ -60,4 +61,5 @@ public:
protected:
renderer* renderer_ = nullptr;
SDL_Window* window_ = nullptr;
std::shared_ptr<spdlog::logger> async_spdlog_;
};

21
core/misc/likely.h Normal file
View File

@ -0,0 +1,21 @@
#pragma once
/** Branch prediction hints */
#ifndef LIKELY /* Hints compiler that expression is likely to be true, much softer than UE_ASSUME - allows (penalized by worse performance) expression to be false */
#if ( defined(__clang__) || defined(__GNUC__) ) && defined(PLATFORM_UNIX) // effect of these on non-Linux platform has not been analyzed as of 2016-03-21
#define LIKELY(x) __builtin_expect(!!(x), 1)
#else
// the additional "!!" is added to silence "warning: equality comparison with exteraneous parenthese" messages on android
#define LIKELY(x) (!!(x))
#endif
#endif
#ifndef UNLIKELY /* Hints compiler that expression is unlikely to be true, allows (penalized by worse performance) expression to be true */
#if ( defined(__clang__) || defined(__GNUC__) ) && defined(PLATFORM_UNIX) // effect of these on non-Linux platform has not been analyzed as of 2016-03-21
#define UNLIKELY(x) __builtin_expect(!!(x), 0)
#else
// the additional "!!" is added to silence "warning: equality comparison with exteraneous parenthese" messages on android
#define UNLIKELY(x) (!!(x))
#endif
#endif

View File

@ -6,25 +6,3 @@
if (Error != 0)\
spdlog::critical("GL error: 0x{:x}", Error);\
}
struct im_gui_impl_open_gl3_data
{
GLuint GlVersion; // Extracted at runtime using GL_MAJOR_VERSION, GL_MINOR_VERSION queries (e.g. 320 for GL 3.2)
char GlslVersionString[32]; // Specified by user or detected based on compile time GL settings.
bool GlProfileIsES2;
bool GlProfileIsES3;
bool GlProfileIsCompat;
GLint GlProfileMask;
GLuint FontTexture;
GLuint ShaderHandle;
GLint AttribLocationTex; // Uniforms location
GLint AttribLocationProjMtx;
GLuint AttribLocationVtxPos; // Vertex attributes location
GLuint AttribLocationVtxUV;
GLuint AttribLocationVtxColor;
unsigned int VboHandle, ElementsHandle;
GLsizeiptr VertexBufferSize;
GLsizeiptr IndexBufferSize;
bool HasClipOrigin;
bool UseBufferSubData;
};

View File

@ -2,11 +2,84 @@
#include "opengl_def.h"
GLint to_internal_format(texture_format format)
{
switch (format)
{
case texture_format::RGBA8:
return GL_RGBA8;
case texture_format::RGBA16_FLOAT:
return GL_RGBA16F;
case texture_format::RGBA32_FLOAT:
return GL_RGBA32F;
case texture_format::R32_FLOAT:
return GL_R32F;
case texture_format::RG32_FLOAT:
return GL_RG32F;
case texture_format::R11F_G11F_B10F:
return GL_R11F_G11F_B10F;
case texture_format::R16_FLOAT:
return GL_R16F;
case texture_format::RGBA16:
return GL_RGBA16;
case texture_format::RGB10_A2:
return GL_RGB10_A2;
case texture_format::RG16:
return GL_RG16;
case texture_format::RG8:
return GL_RG8;
case texture_format::R16:
return GL_R16;
case texture_format::R8:
return GL_R8;
case texture_format::RG16_SNORM:
return GL_RG16_SNORM;
case texture_format::RG8_SNORM:
return GL_RG8_SNORM;
case texture_format::R16_SNORM:
return GL_R16_SNORM;
case texture_format::R8_SNORM:
return GL_R8_SNORM;
case texture_format::R32I:
return GL_R32I;
case texture_format::R32UI:
return GL_R32UI;
case texture_format::R8I:
return GL_R8I;
case texture_format::R16I:
return GL_R16I;
case texture_format::R32F:
return GL_R32F;
case texture_format::R8UI:
return GL_R8UI;
case texture_format::R16UI:
return GL_R16UI;
case texture_format::RG32I:
return GL_RG32I;
case texture_format::RG32UI:
return GL_RG32UI;
case texture_format::RG8I:
return GL_RG8I;
case texture_format::RG16I:
return GL_RG16I;
case texture_format::RGB10_A2UI:
return GL_RGB10_A2UI;
case texture_format::RG16UI:
return GL_RG16UI;
default:
return GL_RGBA8;
}
return 0;
}
void render_target_opengl::init(int width, int height, texture_format format)
{
width_ = width;
height_ = height;
glGenFramebuffers(1, &fbo_);
CHECK_GL_ERRORS
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_);
glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
CHECK_GL_ERRORS
#if defined(__APPLE__)
@ -21,17 +94,27 @@ LockGLContext([NSOpenGLContext currentContext]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
internal_format_ = to_internal_format(format);
glTexImage2D(GL_TEXTURE_2D, 0, internal_format_, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
CHECK_GL_ERRORS
glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_, 0);
CHECK_GL_ERRORS
glBindFramebuffer(GL_FRAMEBUFFER, 0);
#if defined(__APPLE__)
UnlockGLContext([NSOpenGLContext currentContext]);
#endif
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_, 0);
CHECK_GL_ERRORS
}
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
render_target_opengl::~render_target_opengl()
{
glDeleteFramebuffers(1, &fbo_);
glDeleteTextures(1, &texture_);
}
void* render_target_opengl::lock(lock_state state)
@ -79,16 +162,32 @@ void render_target_opengl::on_resize(int width, int height)
width_ = width;
height_ = height;
glDeleteTextures(1, &texture_);
glDeleteFramebuffers(1, &fbo_);
texture_ = 0;
fbo_ = 0;
#if defined(__APPLE__)
LockGLContext([NSOpenGLContext currentContext]);
#endif
glGenTextures(1, &texture_);
CHECK_GL_ERRORS
glBindTexture(GL_TEXTURE_2D, texture_);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
CHECK_GL_ERRORS
glGenFramebuffers(1, &fbo_);
glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_, 0);
CHECK_GL_ERRORS
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
#if defined(__APPLE__)
UnlockGLContext([NSOpenGLContext currentContext]);

View File

@ -6,10 +6,14 @@
class render_target_opengl : public render_target
{
public:
void init(int width, int height, texture_format format) override;
ImTextureID get_texture_id() override { return (void*)static_cast<intptr_t>(fbo_); }
~render_target_opengl() override;
ImTextureID get_texture_id() override { return (void*)static_cast<intptr_t>(texture_); }
[[nodiscard]] GLuint get_fbo() const { return fbo_; }
[[nodiscard]] GLuint get_texture() const { return texture_; }
[[nodiscard]] GLint get_internal_format() const { return internal_format_; }
void* lock(lock_state state) override;
void unlock() override;
protected:
@ -17,5 +21,6 @@ protected:
private:
GLuint fbo_ = 0;
GLuint texture_ = 0;
GLint internal_format_ = 0;
void* locked_texture_ = nullptr;
};

View File

@ -62,13 +62,19 @@ bool renderer_opengl::init(SDL_Window* window_handle)
void renderer_opengl::shutdown()
{
renderer::shutdown();
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplSDL3_Shutdown();
SDL_GL_DeleteContext(g_gl_context);
}
Slang::ComPtr<slang::ISession> renderer_opengl::create_slang_session(const std::string& shader_path)
void renderer_opengl::post_shutdown()
{
SDL_GL_DeleteContext(g_gl_context);
g_gl_context = nullptr;
renderer::post_shutdown();
}
void renderer_opengl::create_slang_session(const std::string& shader_path, slang::ISession** out_session)
{
slang::TargetDesc target_desc;
target_desc.format = SLANG_GLSL;
@ -80,10 +86,9 @@ Slang::ComPtr<slang::ISession> renderer_opengl::create_slang_session(const std::
session_desc.searchPathCount = 1;
session_desc.targets = &target_desc;
session_desc.targetCount = 1;
session_desc.defaultMatrixLayoutMode = SLANG_MATRIX_LAYOUT_COLUMN_MAJOR; // in OpenGL, matrices are row-major by default
Slang::ComPtr<slang::ISession> out;
g_slang_global_session->createSession(session_desc, out.writeRef());
return out;
g_slang_global_session->createSession(session_desc, out_session);
}
std::shared_ptr<shader> renderer_opengl::load_shader(const std::string& entry_name)

View File

@ -8,8 +8,9 @@ public:
void pre_init() override;
bool init(SDL_Window* window_handle) override;
void shutdown() override;
void post_shutdown() override;
Slang::ComPtr<slang::ISession> create_slang_session(const std::string& shader_path) override;
void create_slang_session(const std::string& shader_path, slang::ISession** out_session) override;
std::shared_ptr<shader> load_shader(const std::string& entry_name) override;
void new_frame(SDL_Window* window_handle) override;

View File

@ -1 +1,26 @@
#include "shader_cs_opengl.h"
#include "shader_program_opengl.h"
shader_cs_opengl::shader_cs_opengl(const std::shared_ptr<slang_handle>& handle): shader_opengl(handle)
{
}
bool shader_cs_opengl::init()
{
if (!shader_opengl::init())
return false;
program_ = std::make_shared<shader_program_opengl>();
std::shared_ptr<shader_opengl> in_compute_shader = std::static_pointer_cast<shader_opengl>(shared_from_this());
program_->create_program(in_compute_shader);
return true;
}
void shader_cs_opengl::compute(int x, int y, int z)
{
program_->use_program();
glDispatchCompute(x, y, z);
program_->unuse_program();
}

View File

@ -1,10 +1,14 @@
#pragma once
#include "shader_opengl.h"
#include "rhi/opengl/opengl_def.h"
class shader_cs_opengl : public shader_opengl
{
public:
shader_cs_opengl(const std::shared_ptr<slang_handle>& handle) : shader_opengl(handle) {}
GLenum get_shader_type() const override { return GL_COMPUTE_SHADER; }
explicit shader_cs_opengl(const std::shared_ptr<slang_handle>& handle);
bool init() override;
[[nodiscard]] GLenum get_shader_type() const override { return GL_COMPUTE_SHADER; }
void compute(int x, int y, int z) override;
private:
std::shared_ptr<shader_program_opengl> program_;
};

View File

@ -7,5 +7,5 @@ class shader_gs_opengl : public shader_opengl
public:
shader_gs_opengl(const std::shared_ptr<slang_handle>& handle) : shader_opengl(handle) {}
GLenum get_shader_type() const override { return GL_GEOMETRY_SHADER; }
[[nodiscard]] GLenum get_shader_type() const override { return GL_GEOMETRY_SHADER; }
};

View File

@ -1,8 +1,204 @@
#include "shader_opengl.h"
#include "imgui.h"
#include "shader_program_opengl.h"
#include "rhi/slang_handle.h"
#include "rhi/opengl/opengl_def.h"
#include "glslang/Include/intermediate.h"
#include "glslang/MachineIndependent/localintermediate.h"
#include "glslang/Public/ShaderLang.h"
#include <string>
GLint to_internal_format(glslang::TLayoutFormat format)
{
switch (format)
{
case glslang::TLayoutFormat::ElfR32f:
return GL_R32F;
case glslang::TLayoutFormat::ElfRg32f:
return GL_RG32F;
case glslang::TLayoutFormat::ElfRgba32f:
return GL_RGBA32F;
case glslang::TLayoutFormat::ElfRgba8:
return GL_RGBA8;
case glslang::TLayoutFormat::ElfRgba16f:
return GL_RGBA16F;
case glslang::TLayoutFormat::ElfRgba32i:
return GL_RGBA32I;
case glslang::TLayoutFormat::ElfRgba32ui:
return GL_RGBA32UI;
case glslang::TLayoutFormat::ElfRgba8i:
return GL_RGBA8I;
case glslang::TLayoutFormat::ElfRgba8ui:
return GL_RGBA8UI;
case glslang::TLayoutFormat::ElfRgba16i:
return GL_RGBA16I;
case glslang::TLayoutFormat::ElfRgba16ui:
return GL_RGBA16UI;
case glslang::TLayoutFormat::ElfRgba8Snorm:
return GL_RGBA8_SNORM;
case glslang::TLayoutFormat::ElfRgba16Snorm:
return GL_RGBA16_SNORM;
case glslang::ElfEsFloatGuard:
return GL_R32F;
case glslang::ElfRg16f:
return GL_RG16F;
case glslang::ElfR11fG11fB10f:
return GL_R11F_G11F_B10F;
case glslang::ElfR16f:
return GL_R16F;
case glslang::ElfRgba16:
return GL_RGBA16;
case glslang::ElfRgb10A2:
return GL_RGB10_A2;
case glslang::ElfRg16:
return GL_RG16;
case glslang::ElfRg8:
return GL_RG8;
case glslang::ElfR16:
return GL_R16;
case glslang::ElfR8:
return GL_R8;
case glslang::ElfRg16Snorm:
return GL_RG16_SNORM;
case glslang::ElfRg8Snorm:
return GL_RG8_SNORM;
case glslang::ElfR16Snorm:
return GL_R16_SNORM;
case glslang::ElfR8Snorm:
return GL_R8_SNORM;
case glslang::ElfFloatGuard:
return GL_R32F;
case glslang::ElfR32i:
return GL_R32I;
case glslang::ElfEsIntGuard:
return GL_R32I;
case glslang::ElfRg32i:
return GL_RG32I;
case glslang::ElfRg16i:
return GL_RG16I;
case glslang::ElfRg8i:
return GL_RG8I;
case glslang::ElfR16i:
return GL_R16I;
case glslang::ElfR8i:
return GL_R8I;
case glslang::ElfIntGuard:
return GL_R32I;
case glslang::ElfR32ui:
return GL_R32UI;
case glslang::ElfEsUintGuard:
return GL_R32UI;
case glslang::ElfRg32ui:
return GL_RG32UI;
case glslang::ElfRg16ui:
return GL_RG16UI;
case glslang::ElfRgb10a2ui:
return GL_RGB10_A2UI;
case glslang::ElfRg8ui:
return GL_RG8UI;
case glslang::ElfR16ui:
return GL_R16UI;
case glslang::ElfR8ui:
return GL_R8UI;
}
return 0;
}
// return uniform map
void opengl_get_refletion_data(const std::string& src, std::map<std::string, opengl_uniform_data>& out_uniform, std::map<std::string, opengl_texture_data>& out_texture)
{
glslang::InitializeProcess();
{
const char* const sources[] = { src.c_str() };
const int source_lengths[] = {static_cast<int>(src.size())};
const char* source_names[] = {""};
const int sources_num = 1;
const auto shader_stage = EShLanguage::EShLangCompute;
glslang::TShader shader { shader_stage };
shader.setStringsWithLengthsAndNames(sources, source_lengths, source_names, sources_num);
shader.setEnvClient(glslang::EShClientOpenGL, glslang::EShTargetOpenGL_450);
shader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_0);
TBuiltInResource default_builtin_resources{};
shader.parse(&default_builtin_resources, 450, ECoreProfile, false, true, EShMsgDefault);
class RefrectionTraverser : public glslang::TIntermTraverser
{
public:
std::map<std::string, opengl_uniform_data> uniform_map;
std::map<std::string, opengl_texture_data> texture_map;
virtual void visitSymbol(glslang::TIntermSymbol* symbol) override
{
if (symbol->getQualifier().isUniformOrBuffer())
{
auto t_name = symbol->getName();
std::string name = t_name.c_str();
auto basic_type = symbol->getBasicType();
const glslang::TType& type = symbol->getType();
if (basic_type == glslang::EbtSampler)
{
auto qualifier = symbol->getQualifier();
opengl_texture_data data;
data.sampler_name = name;
if (qualifier.hasBinding())
{
data.binding = qualifier.layoutBinding;
}
if (qualifier.hasFormat())
{
data.format = to_internal_format(qualifier.layoutFormat);
}
const size_t& clean_name_index = name.find('_');
std::string clean_name = name.substr(0, clean_name_index);
texture_map.insert(std::pair(clean_name, data));
}
else
{
auto qualifier = symbol->getQualifier();
opengl_uniform_data data;
data.name = name;
data.type_name = type.getTypeName();
if (qualifier.hasLocation())
{
data.location = qualifier.layoutLocation;
}
if (qualifier.hasBinding())
{
data.binding = qualifier.layoutBinding;
}
if (qualifier.hasFormat())
{
data.format = to_internal_format(qualifier.layoutFormat);
}
const size_t& clean_name_index = name.find('_');
std::string clean_name = name.substr(0, clean_name_index);
uniform_map.insert(std::pair(clean_name, data));
}
}
}
};
RefrectionTraverser traverser;
auto root = shader.getIntermediate()->getTreeRoot();
root->traverse(&traverser);
out_uniform = traverser.uniform_map;
out_texture = traverser.texture_map;
}
glslang::FinalizeProcess();
}
bool shader_opengl::init()
{
@ -17,6 +213,8 @@ bool shader_opengl::init()
const GLint code_size = static_cast<GLint>(code_blob->getBufferSize());
glShaderSource(shader_id_, 1, &code_array, &code_size);
opengl_get_refletion_data(code_array, uniform_map_, texture_map_); // slow
glCompileShader(shader_id_);
GLint compile_status = GL_FALSE;
glGetShaderiv(shader_id_, GL_COMPILE_STATUS, &compile_status);
@ -32,18 +230,39 @@ bool shader_opengl::init()
shader_id_ = 0;
return false;
}
return true;
}
void shader_opengl::bind()
void shader_opengl::set_using_program(std::shared_ptr<shader_program_opengl> in_program)
{
glUseProgram(shader_id_);
if (using_program_.lock())
{
spdlog::error("Shader is already used by another program");
return;
}
using_program_ = in_program;
}
void shader_opengl::unbind()
void shader_opengl::set_cbuffer(const char* name, void* buffer, int size)
{
const ImGuiIO& io = ImGui::GetIO();
const auto open_gl3_data = static_cast<im_gui_impl_open_gl3_data*>(io.BackendRendererUserData);
glUseProgram(open_gl3_data->ShaderHandle);
if (const auto program = using_program_.lock())
program->set_uniform(name, buffer, size);
}
void shader_opengl::set_uav_buffer(const char* name, void* buffer, int size, int element_size)
{
if (const auto program = using_program_.lock())
program->set_ssbo(name, buffer, size, element_size);
}
void shader_opengl::set_render_target(const char* name, std::shared_ptr<render_target> in_render_target)
{
if (const auto program = using_program_.lock())
program->set_render_target(name, in_render_target);
}
void shader_opengl::set_texture(const char* name, std::shared_ptr<texture> in_texture)
{
if (const auto program = using_program_.lock())
program->set_texture(name, in_texture);
}

View File

@ -1,21 +1,55 @@
#pragma once
#include <map>
#include "slang.h"
#include "rhi/shader.h"
class shader_program_opengl;
struct opengl_uniform_data
{
std::string type_name;
std::string name;
GLuint location = 0;
GLuint binding = 0;
GLint format = 0;
};
struct opengl_texture_data
{
std::string sampler_name;
GLuint binding = 0;
GLint format = 0;
};
class shader_opengl : public shader
{
public:
shader_opengl(const std::shared_ptr<slang_handle>& handle) : shader(handle) {}
explicit shader_opengl(const std::shared_ptr<slang_handle>& handle) : shader(handle), shader_id_(0)
{
}
bool init() override;
[[nodiscard]] bool is_initialized() const override { return shader_id_ != 0; }
void bind() override;
void unbind() override;
void bind() override {}
void unbind() override {}
void set_constant_buffer(const char* name, void* buffer, int size) override {}
void set_render_target(const char* name, std::shared_ptr<render_target> in_render_target) override {}
void set_texture(const char* name, std::shared_ptr<texture> in_texture) override {}
void set_using_program(std::shared_ptr<shader_program_opengl> in_program);
void set_cbuffer(const char* name, void* buffer, int size) override;
void set_uav_buffer(const char* name, void* buffer, int size, int element_size) override;
void set_render_target(const char* name, std::shared_ptr<render_target> in_render_target) override;
void set_texture(const char* name, std::shared_ptr<texture> in_texture) override;
[[nodiscard]] virtual GLenum get_shader_type() const = 0;
[[nodiscard]] GLuint get_shader_id() const { return shader_id_; }
[[nodiscard]] const std::map<std::string, opengl_uniform_data>& get_uniform_map() const { return uniform_map_; }
[[nodiscard]] const std::map<std::string, opengl_texture_data>& get_texture_map() const { return texture_map_; }
protected:
GLuint shader_id_;
std::weak_ptr<shader_program_opengl> using_program_;
std::map<std::string, opengl_uniform_data> uniform_map_;
std::map<std::string, opengl_texture_data> texture_map_;
};

View File

@ -0,0 +1,214 @@
#include "shader_program_opengl.h"
#include <ranges>
#include "shader_opengl.h"
#include "rhi/slang_handle.h"
#include "rhi/opengl/render_target_opengl.h"
#include "rhi/opengl/texture_opengl.h"
bool shader_program_opengl::create_program(std::shared_ptr<shader_opengl> in_pixel_shader, std::shared_ptr<shader_opengl> in_vertex_shader)
{
if (program_id_)
{
destroy_program();
}
if (!in_pixel_shader || !in_pixel_shader->is_initialized())
{
spdlog::error("Pixel shader is not initialized");
return false;
}
if (!in_vertex_shader || !in_vertex_shader->is_initialized())
{
spdlog::error("Vertex shader is not initialized");
return false;
}
const GLuint pixel_id = in_pixel_shader->get_shader_id();
const GLuint vertex_id = in_vertex_shader->get_shader_id();
program_id_ = glCreateProgram();
if (program_id_ == 0)
{
spdlog::error("Failed to create program");
return false;
}
glAttachShader(program_id_, vertex_id);
glAttachShader(program_id_, pixel_id);
glLinkProgram(program_id_);
GLint link_status = GL_FALSE;
glGetProgramiv(program_id_, GL_LINK_STATUS, &link_status);
if (link_status == GL_FALSE)
{
GLint log_length = 0;
glGetProgramiv(program_id_, GL_INFO_LOG_LENGTH, &log_length);
std::vector<GLchar> log(log_length);
glGetProgramInfoLog(program_id_, log_length, nullptr, log.data());
spdlog::error("Failed to link program: {}", log.data());
glDeleteProgram(program_id_);
program_id_ = 0;
return false;
}
glDetachShader(program_id_, vertex_id);
glDetachShader(program_id_, pixel_id);
pixel_shader_ = in_pixel_shader;
vertex_shader_ = in_vertex_shader;
in_pixel_shader->set_using_program(shared_from_this());
in_vertex_shader->set_using_program(shared_from_this());
uniform_map_.clear();
texture_map_.clear();
update_param_map(in_pixel_shader);
update_param_map(in_vertex_shader);
return true;
}
bool shader_program_opengl::create_program(std::shared_ptr<shader_opengl> in_compute_shader)
{
if (program_id_)
{
destroy_program();
}
if (!in_compute_shader || !in_compute_shader->is_initialized())
{
spdlog::error("Compute shader is not initialized");
return false;
}
const GLuint compute_id = in_compute_shader->get_shader_id();
program_id_ = glCreateProgram();
if (program_id_ == 0)
{
spdlog::error("Failed to create program");
return false;
}
glAttachShader(program_id_, compute_id);
glLinkProgram(program_id_);
GLint link_status = GL_FALSE;
glGetProgramiv(program_id_, GL_LINK_STATUS, &link_status);
if (link_status == GL_FALSE)
{
GLint log_length = 0;
glGetProgramiv(program_id_, GL_INFO_LOG_LENGTH, &log_length);
std::vector<GLchar> log(log_length);
glGetProgramInfoLog(program_id_, log_length, nullptr, log.data());
spdlog::error("Failed to link program: {}", log.data());
glDeleteProgram(program_id_);
program_id_ = 0;
return false;
}
glDetachShader(program_id_, compute_id);
compute_shader_ = in_compute_shader;
in_compute_shader->set_using_program(shared_from_this());
uniform_map_.clear();
texture_map_.clear();
update_param_map(in_compute_shader);
return true;
}
void shader_program_opengl::destroy_program()
{
for (const auto& val : ubo_map_ | std::views::values)
glDeleteBuffers(1, &val);
if (const auto shader = pixel_shader_.lock())
shader->set_using_program(nullptr);
if (const auto shader = vertex_shader_.lock())
shader->set_using_program(nullptr);
if (const auto shader = compute_shader_.lock())
shader->set_using_program(nullptr);
if (!program_id_)
return;
glDeleteProgram(program_id_);
program_id_ = 0;
ubo_map_.clear();
uniform_map_.clear();
texture_map_.clear();
}
void shader_program_opengl::set_uniform(const char* slang_name, void* buffer, int size)
{
const auto& uniform_name = uniform_map_.find(slang_name);
if (uniform_name == uniform_map_.end())
return;
const auto& uniform_data = uniform_name->second;
GLuint using_bind_point = uniform_data.binding;
const auto find_ubo = ubo_map_.find(using_bind_point);
if (find_ubo != ubo_map_.end())
{
glBindBuffer(GL_UNIFORM_BUFFER, find_ubo->second);
glBufferSubData(GL_UNIFORM_BUFFER, 0, size, buffer);
return;
}
const GLint block_index = glGetUniformBlockIndex(program_id_, uniform_data.type_name.c_str());
glUniformBlockBinding(program_id_, block_index, uniform_data.binding);
// Create a buffer and copy the projection matrix to it.
GLuint ubo = 0;
glGenBuffers(1, &ubo);
glBindBuffer(GL_UNIFORM_BUFFER, ubo);
glBufferData(GL_UNIFORM_BUFFER, size, buffer, GL_STATIC_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER, using_bind_point, ubo);
ubo_map_.insert(std::pair(using_bind_point, ubo));
}
void shader_program_opengl::set_ssbo(const char* slang_name, void* buffer, int size, int element_size)
{
const auto& uniform_name = uniform_map_.find(slang_name);
if (uniform_name == uniform_map_.end())
return;
const auto& uniform_data = uniform_name->second;
const GLint location = glGetProgramResourceIndex(program_id_, GL_SHADER_STORAGE_BLOCK, uniform_data.name.c_str());
if (location == -1)
{
spdlog::error("Failed to find ssbo: {}", slang_name);
return;
}
}
void shader_program_opengl::set_render_target(const char* name, std::shared_ptr<render_target> in_render_target)
{
const auto& texture_name = texture_map_.find(name);
if (texture_name == texture_map_.end())
return;
std::shared_ptr<render_target_opengl> rt = std::static_pointer_cast<render_target_opengl>(in_render_target);
const opengl_texture_data& texture_data = texture_name->second;
if (texture_data.format != rt->get_internal_format())
spdlog::error("Mismatched texture format: {}, need{}, yours {}", name, texture_data.format, rt->get_internal_format());
glBindImageTexture(texture_data.binding, rt->get_texture(), 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
}
void shader_program_opengl::set_texture(const char* name, std::shared_ptr<texture> in_texture)
{
const auto& texture_name = texture_map_.find(name);
if (texture_name == texture_map_.end())
return;
std::shared_ptr<texture_opengl> t = std::static_pointer_cast<texture_opengl>(in_texture);
const opengl_texture_data& texture_data = texture_name->second;
glBindImageTexture(texture_data.binding, t->get_texture(), 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
}
void shader_program_opengl::update_param_map(std::shared_ptr<shader_opengl> in_shader)
{
const auto& uniform_pairs = in_shader->get_uniform_map();
const auto& texture_pairs = in_shader->get_texture_map();
uniform_map_.insert(uniform_pairs.begin(), uniform_pairs.end());
texture_map_.insert(texture_pairs.begin(), texture_pairs.end());
}

View File

@ -0,0 +1,77 @@
#pragma once
#include <map>
#include <memory>
#include <SDL_opengl.h>
#include "shader_opengl.h"
class texture;
class render_target;
class shader;
class shader_opengl;
class shader_program_opengl : public std::enable_shared_from_this<shader_program_opengl>
{
public:
~shader_program_opengl()
{
destroy_program();
}
void use_program()
{
GLint prev_program_id = 0;
glGetIntegerv(GL_CURRENT_PROGRAM, &prev_program_id);
prev_program_id_ = prev_program_id;
glUseProgram(program_id_);
}
void unuse_program() const { glUseProgram(prev_program_id_); }
[[nodiscard]] GLuint get_program_id() const { return program_id_; }
bool create_program(std::shared_ptr<shader_opengl> in_pixel_shader, std::shared_ptr<shader_opengl> in_vertex_shader);
bool create_program(std::shared_ptr<shader_opengl> in_compute_shader);
void destroy_program();
void set_uniform(const char* slang_name, void* buffer, int size);
void set_ssbo(const char* slang_name, void* buffer, int size, int element_size);
void set_render_target(const char* name, std::shared_ptr<render_target> in_render_target);
void set_texture(const char* name, std::shared_ptr<texture> in_texture);
template<typename T>
void set_uniform(const char* name, const T& buffer)
{
set_uniform(name, (void*)&buffer, sizeof(T));
}
template<typename T>
void set_uniform(const char* name, const std::vector<T>& buffer)
{
set_uniform(name, (void*)buffer.data(), sizeof(T) * buffer.size());
}
template<typename T>
void set_ssbo(const char* name, const T& buffer)
{
set_ssbo(name, (void*)&buffer, sizeof(T));
}
template<typename T>
void set_ssbo(const char* name, const std::vector<T>& buffer)
{
set_ssbo(name, (void*)buffer.data(), sizeof(T) * buffer.size());
}
[[nodiscard]] bool is_initialized() const { return program_id_ != 0; }
private:
void update_param_map(std::shared_ptr<shader_opengl> in_shader);
std::map<std::string, opengl_uniform_data> uniform_map_; // slang_name -> uniform_data
std::map<std::string, opengl_texture_data> texture_map_; // slang_name -> uniform_data
std::map<GLuint, GLuint> ubo_map_; // binding -> ubo
GLuint program_id_ = 0;
GLuint prev_program_id_ = 0;
std::weak_ptr<shader_opengl> pixel_shader_;
std::weak_ptr<shader_opengl> vertex_shader_;
std::weak_ptr<shader_opengl> compute_shader_;
};

View File

@ -1 +1,133 @@
#include "shader_ps_opengl.h"
#include "shader_program_opengl.h"
#include "shader_vs_opengl.h"
#include "application/application.h"
#include "misc/likely.h"
#include "rhi/renderer.h"
void ps_opengl_compute_callback(const ImDrawList* parent_list, const ImDrawCmd* cmd)
{
const auto data = (shader_ps_opengl::ps_data*)cmd->UserCallbackData;
std::shared_ptr<render_target_opengl>& rt = data->rt;
const auto program = data->program;
program->use_program();
// do on callback
float x = 0;
float width = rt->get_width();
float y = 0;
float height = rt->get_height();
const float ortho_projection[4][4] =
{
{ 2.0f/(width-x), 0.0f, 0.0f, 0.0f },
{ 0.0f, 2.0f/(y-height), 0.0f, 0.0f },
{ 0.0f, 0.0f, -1.0f, 0.0f },
{ (width+x)/(x-width), (y+height)/(height-y), 0.0f, 1.0f },
};
// glUseProgram(bd->ShaderHandle);
// glUniform1i(bd->AttribLocationTex, 0);
// glUniformMatrix4fv(bd->AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
program->set_uniform("viewMatrix", ortho_projection);
ImVec2 clip_min(x, y);
ImVec2 clip_max(width, height);
glViewport(0, 0, width, height);
// Apply scissor/clipping rectangle (Y is inverted in OpenGL)
glScissor(0, 0, width, height);
// glScissor((int)clip_min.x, (int)(0 - clip_max.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y));
ImDrawVert& vert1 = data->vtx_buffer[0];
ImDrawVert& vert2 = data->vtx_buffer[1];
ImDrawVert& vert3 = data->vtx_buffer[2];
ImDrawVert& vert4 = data->vtx_buffer[3];
vert1.pos = ImVec2(0, 0);
vert2.pos = ImVec2(width, 0);
vert3.pos = ImVec2(width, height);
vert4.pos = ImVec2(0, height);
vert1.uv = ImVec2(0, 0);
vert2.uv = ImVec2(1, 0);
vert3.uv = ImVec2(1, 1);
vert4.uv = ImVec2(0, 1);
vert1.col = 0xFFFFFFFF;
vert2.col = 0xFFFFFFFF;
vert3.col = 0xFFFFFFFF;
vert4.col = 0xFFFFFFFF;
const size_t vtx_size = data->vtx_buffer.size() * sizeof(ImDrawVert);
const size_t idx_size = data->idx_buffer.size() * sizeof(ImDrawIdx);
glBufferSubData(GL_ARRAY_BUFFER, 0, vtx_size, data->vtx_buffer.data());
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, idx_size, data->idx_buffer.data());
glBindBuffer(GL_ARRAY_BUFFER, data->vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data->ibo);
glBindFramebuffer(GL_FRAMEBUFFER, rt->get_fbo());
glDrawElementsBaseVertex(GL_TRIANGLES, 6, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, 0, 0);
// glDrawElements(GL_TRIANGLES, 6, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, 0);
program->unuse_program();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
void shader_ps_opengl::draw(int width, int height, std::shared_ptr<shader> in_vertex_shader)
{
const bool is_default_vtx_shader = in_vertex_shader == nullptr;
if (is_default_vtx_shader)
{
in_vertex_shader = application::get()->get_renderer()->get_pixel_shader_render_default_vs();
}
const std::shared_ptr<shader_vs_opengl> vs = std::static_pointer_cast<shader_vs_opengl>(in_vertex_shader);
const std::shared_ptr<shader_ps_opengl> ps = std::static_pointer_cast<shader_ps_opengl>(shared_from_this());
if (draw_data.fragment_shader_id != get_shader_id() || draw_data.vertex_shader_id != vs->get_shader_id())
{
if (!draw_data.program)
draw_data.program = std::make_shared<shader_program_opengl>();
draw_data.program->create_program(ps, vs);
draw_data.fragment_shader_id = get_shader_id();
draw_data.vertex_shader_id = vs->get_shader_id();
}
if (UNLIKELY(!draw_data.rt))
{
draw_data.rt = std::static_pointer_cast<render_target_opengl>(application::get()->create_render_target(width, height, texture_format::RGBA8));
}
draw_data.rt->resize(width, height);
if (draw_data.vbo == 0)
{
glGenBuffers(1, &draw_data.vbo);
glGenBuffers(1, &draw_data.ibo);
glBindBuffer(GL_ARRAY_BUFFER, draw_data.vbo);
const size_t vtx_size = draw_data.vtx_buffer.size() * sizeof(ImDrawVert);
glBufferData(GL_ARRAY_BUFFER, vtx_size, draw_data.vtx_buffer.data(), GL_STREAM_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, draw_data.ibo);
const size_t idx_size = draw_data.idx_buffer.size() * sizeof(ImDrawIdx);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_size, draw_data.idx_buffer.data(), GL_STREAM_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
ImGui::GetWindowDrawList()->AddCallback(ps_opengl_compute_callback, &draw_data);
ImGui::GetWindowDrawList()->AddCallback(ImDrawCallback_ResetRenderState, nullptr);
draw_data.rt->draw();
}
shader_ps_opengl::ps_data::~ps_data()
{
if (vbo)
glDeleteBuffers(1, &vbo);
if (ibo)
glDeleteBuffers(1, &ibo);
}

View File

@ -1,9 +1,33 @@
#pragma once
#include "shader_opengl.h"
#include "rhi/opengl/render_target_opengl.h"
class shader_vs_opengl;
class shader_ps_opengl : public shader_opengl
{
public:
shader_ps_opengl(const std::shared_ptr<slang_handle>& handle) : shader_opengl(handle) {}
GLenum get_shader_type() const override { return GL_FRAGMENT_SHADER; }
explicit shader_ps_opengl(const std::shared_ptr<slang_handle>& handle) : shader_opengl(handle), draw_data({})
{
draw_data.idx_buffer = {0, 1, 2, 0, 2, 3};
draw_data.vtx_buffer.resize(4);
}
[[nodiscard]] GLenum get_shader_type() const override { return GL_FRAGMENT_SHADER; }
void draw(int width, int height, std::shared_ptr<shader> in_vertex_shader) override;
struct ps_data
{
~ps_data();
std::shared_ptr<render_target_opengl> rt;
std::shared_ptr<shader_program_opengl> program;
std::vector<ImDrawVert> vtx_buffer;
std::vector<ImDrawIdx> idx_buffer;
GLuint vbo = 0;
GLuint ibo = 0;
GLuint vertex_shader_id;
GLuint fragment_shader_id;
} draw_data;
};

View File

@ -2,6 +2,14 @@
#include "opengl_def.h"
texture_opengl::~texture_opengl()
{
if (texture_id_ != 0)
{
glDeleteTextures(1, &texture_id_);
}
}
bool texture_opengl::init_data(const unsigned char* data, int width, int height)
{
width_ = width;

View File

@ -6,7 +6,9 @@
class texture_opengl : public texture
{
public:
~texture_opengl() override;
ImTextureID get_texture_id() override { return (void*)static_cast<intptr_t>(texture_id_); }
GLuint get_texture() const { return texture_id_; }
bool init_data(const unsigned char* data, int width, int height) override;
[[nodiscard]] bool is_valid() const override { return texture_id_ != 0; }
private:

View File

@ -2,9 +2,15 @@
#include "application/application.h"
void renderer::shutdown()
{
default_vs_ = nullptr;
session_ = nullptr;
}
void renderer::init_slang(const std::string& shader_path)
{
session_ = create_slang_session(shader_path);
create_slang_session(shader_path, session_.writeRef());
}
std::shared_ptr<shader> renderer::get_pixel_shader_render_default_vs()

View File

@ -16,10 +16,11 @@ public:
virtual ~renderer() = default;
virtual void pre_init() {}
virtual bool init(SDL_Window* window_handle) = 0;
virtual void shutdown() = 0;
virtual void shutdown();
virtual void post_shutdown() {}
void init_slang(const std::string& shader_path);
virtual Slang::ComPtr<slang::ISession> create_slang_session(const std::string& shader_path) = 0;
virtual void create_slang_session(const std::string& shader_path, slang::ISession** out_session) = 0;
virtual Slang::ComPtr<slang::ISession> get_slang_session() { return session_; }
virtual std::shared_ptr<shader> load_shader(const std::string& entry_name) = 0;
virtual std::shared_ptr<shader> get_pixel_shader_render_default_vs();

View File

@ -5,4 +5,31 @@ enum class texture_format
RGBA8,
RGBA16_FLOAT,
RGBA32_FLOAT,
R32_FLOAT,
RG32_FLOAT,
R11F_G11F_B10F,
R16_FLOAT,
RGBA16,
RGB10_A2,
RG16,
RG8,
R16,
R8,
RG16_SNORM,
RG8_SNORM,
R16_SNORM,
R8_SNORM,
R32I,
R32UI,
R8I,
R16I,
R32F,
R8UI,
R16UI,
RG32I,
RG32UI,
RG8I,
RG16I,
RGB10_A2UI,
RG16UI,
};

View File

@ -4,7 +4,7 @@ class render_target;
class texture;
class slang_handle;
class shader
class shader : public std::enable_shared_from_this<shader>
{
public:
virtual ~shader() = default;
@ -13,6 +13,7 @@ public:
virtual bool init() { return false; }
[[nodiscard]] virtual bool is_initialized() const = 0;
[[nodiscard]] virtual bool is_valid() const { return handle_ != nullptr && is_initialized(); }
[[nodiscard]] std::shared_ptr<slang_handle> get_handle() { return handle_; }
virtual void bind() = 0;
virtual void unbind() = 0;
@ -20,20 +21,20 @@ public:
virtual void draw(int width, int height, std::shared_ptr<shader> in_vertex_shader = nullptr) {}
// param setters
virtual void set_constant_buffer(const char* name, void* buffer, int size) = 0;
virtual void set_cbuffer(const char* name, void* buffer, int size) = 0;
virtual void set_uav_buffer(const char* name, void* buffer, int size, int element_size) {}
virtual void set_texture(const char* name, std::shared_ptr<texture> in_texture) = 0;
virtual void set_render_target(const char* name, std::shared_ptr<render_target> in_render_target) = 0;
template<typename T>
void set_constant_buffer(const char* name, const T& buffer)
void set_cbuffer(const char* name, const T& buffer)
{
set_constant_buffer(name, (void*)&buffer, sizeof(T));
set_cbuffer(name, (void*)&buffer, sizeof(T));
}
template<typename T>
void set_constant_buffer(const char* name, const std::vector<T>& buffer)
void set_cbuffer(const char* name, const std::vector<T>& buffer)
{
set_constant_buffer(name, (void*)buffer.data(), sizeof(T) * buffer.size());
set_cbuffer(name, (void*)buffer.data(), sizeof(T) * buffer.size());
}
template<typename T>

View File

@ -59,6 +59,7 @@ Slang::ComPtr<slang::IBlob> slang_handle::get_entry_point_code() const
{
Slang::ComPtr<slang::IBlob> diagnostics;
Slang::ComPtr<slang::IBlob> code_blob;
program->getEntryPointCode(
entry_point_index_,
target_index,
@ -72,3 +73,27 @@ Slang::ComPtr<slang::IBlob> slang_handle::get_entry_point_code() const
}
return code_blob;
}
std::map<std::string, slang::BindingType> slang_handle::get_binding_types() const
{
std::map<std::string, slang::BindingType> out;
slang::ProgramLayout* layout = program->getLayout(target_index);
layout->getGlobalConstantBufferBinding();
return out;
}
unsigned int slang_handle::get_bind_index(const char* param_name) const
{
slang::ProgramLayout* layout = program->getLayout(target_index);
// const auto entry_reflection = layout->getEntryPointByIndex(entry_point_index_);
const auto param_reflection = layout->getParameterCount();
for (unsigned int i = 0; i < param_reflection; ++i)
{
const auto param = layout->getParameterByIndex(i);
if (strcmp(param->getName(), param_name) == 0)
{
return param->getBindingIndex();
}
}
return -1;
}

View File

@ -1,4 +1,6 @@
#pragma once
#include <map>
#include "slang-com-ptr.h"
#include <string>
@ -19,6 +21,8 @@ public:
return entry_reflection->getName();
}
[[nodiscard]] SlangStage get_shader_type() const { return shader_type_; }
[[nodiscard]] std::map<std::string, slang::BindingType> get_binding_types() const;
[[nodiscard]] unsigned int get_bind_index(const char* param_name) const;
private:
int entry_point_index_ = -1;
SlangStage shader_type_ = SLANG_STAGE_NONE;

View File

@ -13,6 +13,60 @@ inline DXGI_FORMAT to_dx_format(texture_format format)
return DXGI_FORMAT_R16G16B16A16_FLOAT;
case texture_format::RGBA32_FLOAT:
return DXGI_FORMAT_R32G32B32A32_FLOAT;
case texture_format::R32_FLOAT:
return DXGI_FORMAT_R32_FLOAT;
case texture_format::RG32_FLOAT:
return DXGI_FORMAT_R32G32_FLOAT;
case texture_format::R11F_G11F_B10F:
return DXGI_FORMAT_R11G11B10_FLOAT;
case texture_format::R16_FLOAT:
return DXGI_FORMAT_R16_FLOAT;
case texture_format::RGBA16:
return DXGI_FORMAT_R16G16B16A16_UNORM;
case texture_format::RGB10_A2:
return DXGI_FORMAT_R10G10B10A2_UNORM;
case texture_format::RG16:
return DXGI_FORMAT_R16G16_UNORM;
case texture_format::RG8:
return DXGI_FORMAT_R8G8_UNORM;
case texture_format::R16:
return DXGI_FORMAT_R16_UNORM;
case texture_format::R8:
return DXGI_FORMAT_R8_UNORM;
case texture_format::RG16_SNORM:
return DXGI_FORMAT_R16G16_SNORM;
case texture_format::RG8_SNORM:
return DXGI_FORMAT_R8G8_SNORM;
case texture_format::R16_SNORM:
return DXGI_FORMAT_R16_SNORM;
case texture_format::R8_SNORM:
return DXGI_FORMAT_R8_SNORM;
case texture_format::R32I:
return DXGI_FORMAT_R32_SINT;
case texture_format::R32UI:
return DXGI_FORMAT_R32_UINT;
case texture_format::R8I:
return DXGI_FORMAT_R8_SINT;
case texture_format::R16I:
return DXGI_FORMAT_R16_SINT;
case texture_format::R32F:
return DXGI_FORMAT_R32_FLOAT;
case texture_format::R8UI:
return DXGI_FORMAT_R8_UINT;
case texture_format::R16UI:
return DXGI_FORMAT_R16_UINT;
case texture_format::RG32I:
return DXGI_FORMAT_R32G32_SINT;
case texture_format::RG32UI:
return DXGI_FORMAT_R32G32_UINT;
case texture_format::RG8I:
return DXGI_FORMAT_R8G8_SINT;
case texture_format::RG16I:
return DXGI_FORMAT_R16G16_SINT;
case texture_format::RGB10_A2UI:
return DXGI_FORMAT_R10G10B10A2_UINT;
case texture_format::RG16UI:
return DXGI_FORMAT_R16G16_UINT;
}
return DXGI_FORMAT_UNKNOWN;
}

View File

@ -138,6 +138,7 @@ void find_best_device_dx11::select_adapter()
for (unsigned int adapter_index = 0; enumerate_adapters(adapter_index, testing_adapter.get_init_reference()) != DXGI_ERROR_NOT_FOUND; ++adapter_index)
{
DXGI_ADAPTER_DESC adapter_desc;
const HRESULT desc_result = testing_adapter->GetDesc(&adapter_desc);
if (FAILED(desc_result))
{

View File

@ -47,6 +47,7 @@ bool renderer_dx11::init(SDL_Window* window_handle)
void renderer_dx11::shutdown()
{
renderer::shutdown();
// Cleanup
ImGui_ImplDX11_Shutdown();
ImGui_ImplSDL3_Shutdown();
@ -56,7 +57,7 @@ void renderer_dx11::shutdown()
g_d3d11_swap_chain.safe_release();
}
Slang::ComPtr<slang::ISession> renderer_dx11::create_slang_session(const std::string& shader_path)
void renderer_dx11::create_slang_session(const std::string& shader_path, slang::ISession** out_session)
{
slang::TargetDesc target_desc;
target_desc.format = SLANG_HLSL;
@ -68,10 +69,9 @@ Slang::ComPtr<slang::ISession> renderer_dx11::create_slang_session(const std::st
session_desc.searchPathCount = 1;
session_desc.targets = &target_desc;
session_desc.targetCount = 1;
session_desc.defaultMatrixLayoutMode = SLANG_MATRIX_LAYOUT_COLUMN_MAJOR;
Slang::ComPtr<slang::ISession> out;
g_slang_global_session->createSession(session_desc, out.writeRef());
return out;
g_slang_global_session->createSession(session_desc, out_session);
}
std::shared_ptr<shader> renderer_dx11::load_shader(const std::string& entry_name)

View File

@ -19,8 +19,8 @@ public:
renderer_dx11();
bool init(SDL_Window* window_handle) override;
void shutdown() override;
Slang::ComPtr<slang::ISession> create_slang_session(const std::string& shader_path) override;
void create_slang_session(const std::string& shader_path, slang::ISession** out_session) override;
std::shared_ptr<shader> load_shader(const std::string& entry_name) override;
void new_frame(SDL_Window* window_handle) override;

View File

@ -15,7 +15,7 @@ public:
malloc_size_ = (malloc_size_ + 15) & ~15;
// and less than D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT
malloc_size_ = min(malloc_size_, D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT);
D3D11_BUFFER_DESC desc;
D3D11_BUFFER_DESC desc = {};
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.ByteWidth = malloc_size_;
@ -39,6 +39,7 @@ public:
void set_buffer_data(const void* in_buffer_data) const
{
memcpy(buffer_data_, in_buffer_data, element_size_);
// g_d3d11_device_context->UpdateSubresource(buffer_, 0, nullptr, in_buffer_data, 0, 0);
}
void update_buffer() const
{

View File

@ -65,7 +65,7 @@ bool shader_dx11::init()
return true;
}
void shader_dx11::set_constant_buffer(const char* name, void* buffer, int size)
void shader_dx11::set_cbuffer(const char* name, void* buffer, int size)
{
auto find = constant_buffers_.find(name);
if (find == constant_buffers_.end())

View File

@ -23,7 +23,7 @@ public:
[[nodiscard]] virtual ID3D11DeviceChild* get_shader() = 0;
[[nodiscard]] virtual const char* get_shader_model() const = 0;
void set_constant_buffer(const char* name, void* buffer, int size) override;
void set_cbuffer(const char* name, void* buffer, int size) override;
void set_texture(const char* name, std::shared_ptr<texture> in_texture) override;
void set_render_target(const char* name, std::shared_ptr<render_target> in_render_target) override;
protected:

View File

@ -177,14 +177,22 @@ void shader_ps_dx11::draw(int width, int height, std::shared_ptr<shader> in_vert
const float R = width;
const float T = 0;
const float B = height;
// float mvp[4][4] =
// {
// { 2.0f/(R-L), 0.0f, 0.0f, (R+L)/(L-R) },
// { 0.0f, 2.0f/(T-B), 0.0f, (T+B)/(B-T) },
// { 0.0f, 0.0f, 0.5f, 0.5f },
// { 0.0f, 0.0f, 0.0f, 1.0f },
// };
float mvp[4][4] =
{
{ 2.0f/(R-L), 0.0f, 0.0f, (R+L)/(L-R) },
{ 0.0f, 2.0f/(T-B), 0.0f, (T+B)/(B-T) },
{ 0.0f, 0.0f, 0.5f, 0.5f },
{ 0.0f, 0.0f, 0.0f, 1.0f },
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
{ 0.0f, 0.0f, -1.0f, 0.0f },
{ (R+L)/(L-R), (T+B)/(B-T), 0.0f, 1.0f },
};
in_vertex_shader->set_constant_buffer("ProjectionMatrix", mvp, sizeof(mvp));
in_vertex_shader->set_cbuffer("viewMatrix", mvp, sizeof(mvp));
}
draw_data.vertex_shader = in_vertex_shader;

1
third_party/glslang vendored Submodule

@ -0,0 +1 @@
Subproject commit 8c3dbb3596e552d8e89c16350b07373ac36262bb

View File

@ -1 +1 @@
#define SLANG_TAG_VERSION "v2024.0.0"
#define SLANG_TAG_VERSION "v2024.0.1"

View File

@ -4179,6 +4179,8 @@ namespace slang
virtual SLANG_NO_THROW void SLANG_MCALL setReportPerfBenchmark(bool value) = 0;
virtual SLANG_NO_THROW void SLANG_MCALL setSkipSPIRVValidation(bool value) = 0;
};
#define SLANG_UUID_ICompileRequest ICompileRequest::getTypeGuid()

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.