改为使用glfw, 并仅实现opengl rhi
This commit is contained in:
parent
0be061e397
commit
e50fcb1992
@ -61,6 +61,7 @@ add_subdirectory(third_party/imgui)
|
||||
add_subdirectory(third_party/portaudio)
|
||||
add_subdirectory(third_party/spdlog)
|
||||
add_subdirectory(third_party/glfw)
|
||||
add_subdirectory(third_party/glad)
|
||||
|
||||
# setup portaudio
|
||||
set(PA_USE_ASIO ON CACHE BOOL "" FORCE)
|
||||
@ -141,5 +142,7 @@ set(SPDLOG_USE_STD_FORMAT OFF CACHE BOOL "" FORCE)
|
||||
# setup glslang
|
||||
set(ENABLE_OPT OFF CACHE BOOL "" FORCE)
|
||||
|
||||
add_definitions(-DGLFW_INCLUDE_NONE)
|
||||
|
||||
# install
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/third_party/imgui/imgui/misc/fonts DESTINATION ${CMAKE_BINARY_DIR}/bin)
|
||||
|
@ -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 glfw)
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} spdlog imgui glfw glad)
|
||||
|
||||
target_link_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} spdlog imgui glfw)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC imgui spdlog glfw)
|
||||
target_link_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} spdlog imgui glfw glad)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC imgui spdlog glfw glad)
|
||||
|
||||
target_precompile_headers(${PROJECT_NAME} PUBLIC extern.h)
|
||||
add_definitions(-Dcore_EXPORTS -DSTB_IMAGE_IMPLEMENTATION -DSTBI_WINDOWS_UTF8)
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include "application.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
|
||||
#include "command_line.h"
|
||||
@ -13,227 +12,74 @@
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "spdlog/sinks/basic_file_sink.h"
|
||||
|
||||
#if WIN32
|
||||
#include "rhi/windows/dx11/renderer_dx11.h"
|
||||
#endif
|
||||
|
||||
bool g_is_running = true;
|
||||
bool g_exit_requested = false;
|
||||
Slang::ComPtr<slang::IGlobalSession> g_slang_global_session = nullptr;
|
||||
application* g_app_instance = nullptr;
|
||||
application *g_app_instance = nullptr;
|
||||
|
||||
void application::init(window_params in_window_params, int argc, char** argv)
|
||||
{
|
||||
slang::createGlobalSession(g_slang_global_session.writeRef());
|
||||
|
||||
try
|
||||
{
|
||||
static void glfw_error_callback(int error, const char *description) {
|
||||
spdlog::error("Glfw Error {}: {}", error, description);
|
||||
}
|
||||
|
||||
void application::init(window_params in_window_params, int argc, char **argv) {
|
||||
try {
|
||||
async_spdlog_ = spdlog::basic_logger_mt<spdlog::async_factory>("async_file_logger", "logs/log.txt");
|
||||
}
|
||||
catch (const spdlog::spdlog_ex &ex)
|
||||
{
|
||||
} catch (const spdlog::spdlog_ex &ex) {
|
||||
std::cout << "Log init failed: " << ex.what() << std::endl;
|
||||
}
|
||||
|
||||
|
||||
command_line::instance().init(argc, argv);
|
||||
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
|
||||
|
||||
// Setup Dear ImGui context
|
||||
IMGUI_CHECKVERSION();
|
||||
init_imgui(ImGui::CreateContext());
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
|
||||
unsigned int window_flags = 0;
|
||||
init_glfw();
|
||||
init_imgui();
|
||||
|
||||
#if WIN32
|
||||
bool use_dx11 = false;
|
||||
bool use_dx12 = false;
|
||||
bool use_vulkan = false;
|
||||
bool use_opengl = false;
|
||||
#elif __APPLE__
|
||||
bool use_vulkan = true;
|
||||
bool use_opengl = false;
|
||||
bool use_metal = false;
|
||||
#else
|
||||
bool use_vulkan = true;
|
||||
bool use_opengl = false;
|
||||
#endif
|
||||
renderer_ = new renderer_opengl();
|
||||
|
||||
#if WIN32
|
||||
command_line::instance().get_arg("dx11", use_dx11);
|
||||
command_line::instance().get_arg("dx12", use_dx12);
|
||||
command_line::instance().get_arg("vulkan", use_vulkan);
|
||||
command_line::instance().get_arg("opengl", use_opengl);
|
||||
|
||||
// only one renderer can be used at a time
|
||||
const int renderer_count = use_dx11 + use_dx12 + use_vulkan + use_opengl;
|
||||
assert(renderer_count <= 1);
|
||||
|
||||
// if no renderer is specified, use dx11
|
||||
if (!(use_dx11 || use_dx12 || use_vulkan || use_opengl))
|
||||
{
|
||||
use_dx11 = true;
|
||||
}
|
||||
|
||||
if (use_dx11)
|
||||
{
|
||||
renderer_ = new renderer_dx11();
|
||||
}
|
||||
else if (use_opengl)
|
||||
{
|
||||
renderer_ = new renderer_opengl();
|
||||
window_flags |= SDL_WINDOW_OPENGL;
|
||||
}
|
||||
// if (use_dx12)
|
||||
// {
|
||||
// renderer_ = new renderer_dx12();
|
||||
// }
|
||||
// if (use_vulkan)
|
||||
// {
|
||||
// renderer_ = new renderer_vulkan();
|
||||
// window_flags |= SDL_WINDOW_VULKAN;
|
||||
// }
|
||||
#elif __APPLE__
|
||||
const int renderer_count = use_metal || use_vulkan || use_opengl;
|
||||
assert(renderer_count <= 1);
|
||||
|
||||
if (!(use_metal || use_vulkan || use_opengl))
|
||||
{
|
||||
use_metal = true;
|
||||
}
|
||||
|
||||
if (use_metal)
|
||||
{
|
||||
renderer_ = new renderer_metal();
|
||||
window_flags |= SDL_WINDOW_METAL;
|
||||
}
|
||||
else if (use_vulkan)
|
||||
{
|
||||
renderer_ = new renderer_vulkan();
|
||||
window_flags |= SDL_WINDOW_VULKAN;
|
||||
}
|
||||
else if (use_opengl)
|
||||
{
|
||||
renderer_ = new renderer_opengl();
|
||||
window_flags |= SDL_WINDOW_OPENGL;
|
||||
}
|
||||
#else
|
||||
const int renderer_count = use_vulkan || use_opengl;
|
||||
assert(renderer_count <= 1);
|
||||
|
||||
if (!(use_vulkan || use_opengl))
|
||||
{
|
||||
use_vulkan = true;
|
||||
}
|
||||
|
||||
if (use_vulkan)
|
||||
{
|
||||
renderer_ = new renderer_vulkan();
|
||||
window_flags |= SDL_WINDOW_VULKAN;
|
||||
}
|
||||
else if (use_opengl)
|
||||
{
|
||||
renderer_ = new renderer_opengl();
|
||||
window_flags |= SDL_WINDOW_OPENGL;
|
||||
}
|
||||
#endif
|
||||
|
||||
// if (!renderer_)
|
||||
// renderer_ = new renderer_null();
|
||||
renderer_->pre_init();
|
||||
|
||||
if (in_window_params.fullscreen)
|
||||
window_flags |= SDL_WINDOW_FULLSCREEN;
|
||||
if (in_window_params.borderless)
|
||||
window_flags |= SDL_WINDOW_BORDERLESS;
|
||||
if (in_window_params.resizable)
|
||||
window_flags |= SDL_WINDOW_RESIZABLE;
|
||||
if (in_window_params.minimized)
|
||||
window_flags |= SDL_WINDOW_MINIMIZED;
|
||||
if (in_window_params.maximized)
|
||||
window_flags |= SDL_WINDOW_MAXIMIZED;
|
||||
if (in_window_params.hi_dpi)
|
||||
window_flags |= SDL_WINDOW_HIGH_PIXEL_DENSITY;
|
||||
if (in_window_params.always_on_top)
|
||||
window_flags |= SDL_WINDOW_ALWAYS_ON_TOP;
|
||||
|
||||
|
||||
// new SDL window
|
||||
window_ = SDL_CreateWindow(in_window_params.title.c_str(), in_window_params.width, in_window_params.height, window_flags);
|
||||
if (!window_)
|
||||
{
|
||||
spdlog::error("Failed to create SDL window: {}", SDL_GetError());
|
||||
window_ = glfwCreateWindow(in_window_params.width, in_window_params.height, in_window_params.title.c_str(), nullptr,
|
||||
nullptr);
|
||||
if (!window_) {
|
||||
spdlog::error("Failed to create glfw window");
|
||||
return;
|
||||
}
|
||||
SDL_SetWindowPosition(window_, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
||||
SDL_ShowWindow(window_);
|
||||
|
||||
renderer_->init(window_);
|
||||
renderer_->init_slang(get_shader_path());
|
||||
renderer_->resize(in_window_params.width, in_window_params.height);
|
||||
g_is_running = true;
|
||||
}
|
||||
|
||||
int application::run()
|
||||
{
|
||||
while (!g_exit_requested)
|
||||
{
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
ImGui_ImplSDL3_ProcessEvent(&event);
|
||||
if (event.type == SDL_EVENT_QUIT)
|
||||
g_exit_requested = true;
|
||||
if (event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && event.window.windowID == SDL_GetWindowID(window_))
|
||||
g_exit_requested = true;
|
||||
if (event.type == SDL_EVENT_WINDOW_RESIZED)
|
||||
{
|
||||
const int width = event.window.data1;
|
||||
const int height = event.window.data2;
|
||||
renderer_->resize(width, height);
|
||||
}
|
||||
}
|
||||
int application::run() {
|
||||
while (!g_exit_requested) {
|
||||
glfwPollEvents();
|
||||
g_exit_requested = glfwWindowShouldClose(window_);
|
||||
if (g_exit_requested)
|
||||
break;
|
||||
|
||||
|
||||
renderer_->new_frame(window_);
|
||||
draw_gui();
|
||||
renderer_->end_frame(window_);
|
||||
}
|
||||
|
||||
|
||||
shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void application::shutdown()
|
||||
{
|
||||
init_imgui(nullptr);
|
||||
void application::shutdown() {
|
||||
renderer_->shutdown();
|
||||
ImGui::DestroyContext();
|
||||
|
||||
SDL_HideWindow(window_);
|
||||
SDL_DestroyWindow(window_);
|
||||
window_ = nullptr;
|
||||
|
||||
destroy_imgui();
|
||||
renderer_->post_shutdown();
|
||||
|
||||
delete renderer_;
|
||||
renderer_ = nullptr;
|
||||
|
||||
|
||||
SDL_Quit();
|
||||
destroy_glfw();
|
||||
}
|
||||
|
||||
std::shared_ptr<texture> application::load_texture(const std::string& path) const
|
||||
{
|
||||
std::shared_ptr<texture> application::load_texture(const std::string &path) const {
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
unsigned char* image_data = stbi_load(path.c_str(), &width, &height, nullptr, 4);
|
||||
if (!image_data)
|
||||
{
|
||||
unsigned char *image_data = stbi_load(path.c_str(), &width, &height, nullptr, 4);
|
||||
if (!image_data) {
|
||||
spdlog::error("Failed to load texture: {}", path.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
@ -242,17 +88,46 @@ std::shared_ptr<texture> application::load_texture(const std::string& path) cons
|
||||
return texture;
|
||||
}
|
||||
|
||||
std::shared_ptr<texture> application::create_texture(const unsigned char* data, const int width, const int height) const
|
||||
{
|
||||
std::shared_ptr<texture>
|
||||
application::create_texture(const unsigned char *data, const int width, const int height) const {
|
||||
return renderer_->create_texture(data, width, height);
|
||||
}
|
||||
|
||||
std::shared_ptr<render_target> application::create_render_target(const int width, const int height, texture_format format) const
|
||||
{
|
||||
std::shared_ptr<render_target> application::create_render_target(const int width, const int height,
|
||||
texture_format format) const {
|
||||
return renderer_->create_render_target(width, height, format);
|
||||
}
|
||||
|
||||
std::shared_ptr<pixel_shader_drawer> application::create_pixel_shader_drawer() const
|
||||
{
|
||||
std::shared_ptr<pixel_shader_drawer> application::create_pixel_shader_drawer() const {
|
||||
return renderer_->create_pixel_shader_drawer();
|
||||
}
|
||||
|
||||
void application::init_glfw() {
|
||||
glfwSetErrorCallback(glfw_error_callback);
|
||||
if (!glfwInit()) {
|
||||
spdlog::error("Failed to initialize GLFW");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void application::init_imgui() {
|
||||
// Setup Dear ImGui context
|
||||
IMGUI_CHECKVERSION();
|
||||
init_imgui(ImGui::CreateContext());
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
}
|
||||
|
||||
void application::destroy_glfw() {
|
||||
glfwDestroyWindow(window_);
|
||||
window_ = nullptr;
|
||||
glfwTerminate();
|
||||
}
|
||||
|
||||
void application::destroy_imgui() {
|
||||
init_imgui(nullptr);
|
||||
ImGui::DestroyContext();
|
||||
}
|
||||
|
@ -1,9 +1,7 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "SDL.h"
|
||||
#include "imgui.h"
|
||||
#include "slang-com-ptr.h"
|
||||
#include "slang.h"
|
||||
#include "GLFW/glfw3.h"
|
||||
|
||||
class pixel_shader_drawer;
|
||||
class render_target;
|
||||
@ -13,11 +11,9 @@ class application;
|
||||
|
||||
extern bool g_is_running;
|
||||
extern bool g_exit_requested;
|
||||
extern Slang::ComPtr<slang::IGlobalSession>g_slang_global_session;
|
||||
extern application* g_app_instance;
|
||||
extern application *g_app_instance;
|
||||
|
||||
struct window_params
|
||||
{
|
||||
struct window_params {
|
||||
std::string title;
|
||||
int width;
|
||||
int height;
|
||||
@ -30,39 +26,61 @@ struct window_params
|
||||
bool always_on_top;
|
||||
};
|
||||
|
||||
class CORE_API application
|
||||
{
|
||||
class CORE_API application {
|
||||
public:
|
||||
application()
|
||||
{
|
||||
application() {
|
||||
g_app_instance = this;
|
||||
}
|
||||
|
||||
virtual ~application() = default;
|
||||
application(const application&) = delete;
|
||||
application(application&&) = delete;
|
||||
static application* get()
|
||||
{
|
||||
|
||||
application(const application &) = delete;
|
||||
|
||||
application(application &&) = delete;
|
||||
|
||||
static application *get() {
|
||||
return g_app_instance;
|
||||
}
|
||||
|
||||
virtual void init(window_params in_window_params, int argc, char** argv);
|
||||
virtual int run();
|
||||
virtual void shutdown();
|
||||
virtual void draw_gui() = 0;
|
||||
virtual const char* get_shader_path() = 0;
|
||||
virtual void init_imgui(ImGuiContext* in_context) = 0;
|
||||
std::shared_ptr<texture> load_texture(const std::string& path) const;
|
||||
std::shared_ptr<texture> create_texture(const unsigned char* data, const int width, const int height) const;
|
||||
std::shared_ptr<render_target> create_render_target(const int width, const int height, texture_format format) const;
|
||||
std::shared_ptr<pixel_shader_drawer> create_pixel_shader_drawer() const;
|
||||
|
||||
virtual const char* get_entry_model() const = 0;
|
||||
virtual const char* get_draw_ps_vertex_shader_entry() const = 0; // Vertex Shader used for drawing ps
|
||||
|
||||
renderer* get_renderer() const { return renderer_; }
|
||||
SDL_Window* get_window() const { return window_; }
|
||||
virtual void init(window_params in_window_params, int argc, char **argv);
|
||||
|
||||
virtual int run();
|
||||
|
||||
virtual void shutdown();
|
||||
|
||||
virtual void draw_gui() = 0;
|
||||
|
||||
virtual const char *get_shader_path() = 0;
|
||||
|
||||
virtual void init_imgui(ImGuiContext *in_context) = 0;
|
||||
|
||||
[[nodiscard]] std::shared_ptr<texture> load_texture(const std::string &path) const;
|
||||
|
||||
std::shared_ptr<texture> create_texture(const unsigned char *data, int width, int height) const;
|
||||
|
||||
[[nodiscard]] std::shared_ptr<render_target> create_render_target(int width, int height,
|
||||
texture_format format) const;
|
||||
|
||||
[[nodiscard]] std::shared_ptr<pixel_shader_drawer> create_pixel_shader_drawer() const;
|
||||
|
||||
[[nodiscard]] virtual const char *get_entry_model() const = 0;
|
||||
|
||||
[[nodiscard]] virtual const char *get_draw_ps_vertex_shader_entry() const = 0; // Vertex Shader used for drawing ps
|
||||
|
||||
[[nodiscard]] renderer *get_renderer() const { return renderer_; }
|
||||
[[nodiscard]] GLFWwindow *get_window() const { return window_; }
|
||||
|
||||
protected:
|
||||
renderer* renderer_ = nullptr;
|
||||
SDL_Window* window_ = nullptr;
|
||||
renderer *renderer_ = nullptr;
|
||||
GLFWwindow *window_ = nullptr;
|
||||
std::shared_ptr<spdlog::logger> async_spdlog_;
|
||||
|
||||
private:
|
||||
void init_glfw();
|
||||
|
||||
void init_imgui();
|
||||
|
||||
void destroy_glfw();
|
||||
|
||||
void destroy_imgui();
|
||||
};
|
||||
|
@ -1,21 +1,16 @@
|
||||
#include "command_line.h"
|
||||
|
||||
void command_line::init(int argc, char** argv)
|
||||
{
|
||||
void command_line::init(int argc, char **argv) {
|
||||
// parser argv
|
||||
args_.clear();
|
||||
for (int i = 0; i < argc; ++i)
|
||||
{
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
std::string arg = argv[i];
|
||||
if (arg[0] == '-')
|
||||
{
|
||||
if (arg[0] == '-') {
|
||||
std::string key = arg.substr(1);
|
||||
std::string value;
|
||||
if (i + 1 < argc)
|
||||
{
|
||||
if (i + 1 < argc) {
|
||||
std::string next_arg = argv[i + 1];
|
||||
if (next_arg[0] != '-')
|
||||
{
|
||||
if (next_arg[0] != '-') {
|
||||
value = next_arg;
|
||||
++i;
|
||||
}
|
||||
@ -25,54 +20,38 @@ void command_line::init(int argc, char** argv)
|
||||
}
|
||||
}
|
||||
|
||||
void command_line::get_arg(const std::string& key, std::string& out) const
|
||||
{
|
||||
void command_line::get_arg(const std::string &key, std::string &out) const {
|
||||
const auto it = args_.find(key);
|
||||
if (it != args_.end())
|
||||
{
|
||||
if (it != args_.end()) {
|
||||
out = it->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
out = "";
|
||||
}
|
||||
}
|
||||
|
||||
void command_line::get_arg(const std::string& key, int& out) const
|
||||
{
|
||||
void command_line::get_arg(const std::string &key, int &out) const {
|
||||
const auto it = args_.find(key);
|
||||
if (it != args_.end())
|
||||
{
|
||||
if (it != args_.end()) {
|
||||
out = std::stoi(it->second);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
out = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void command_line::get_arg(const std::string& key, float& out) const
|
||||
{
|
||||
void command_line::get_arg(const std::string &key, float &out) const {
|
||||
const auto it = args_.find(key);
|
||||
if (it != args_.end())
|
||||
{
|
||||
if (it != args_.end()) {
|
||||
out = std::stof(it->second);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
out = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void command_line::get_arg(const std::string& key, bool& out) const
|
||||
{
|
||||
void command_line::get_arg(const std::string &key, bool &out) const {
|
||||
const auto it = args_.find(key);
|
||||
if (it != args_.end())
|
||||
{
|
||||
if (it != args_.end()) {
|
||||
out = it->second != "false";
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
out = false;
|
||||
}
|
||||
}
|
||||
|
@ -2,19 +2,23 @@
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
class command_line
|
||||
{
|
||||
class command_line {
|
||||
public:
|
||||
static command_line& instance()
|
||||
{
|
||||
static command_line &instance() {
|
||||
static command_line instance;
|
||||
return instance;
|
||||
}
|
||||
void init(int argc, char** argv);
|
||||
void get_arg(const std::string& key, std::string& out) const;
|
||||
void get_arg(const std::string& key, int& out) const;
|
||||
void get_arg(const std::string& key, float& out) const;
|
||||
void get_arg(const std::string& key, bool& out) const;
|
||||
|
||||
void init(int argc, char **argv);
|
||||
|
||||
void get_arg(const std::string &key, std::string &out) const;
|
||||
|
||||
void get_arg(const std::string &key, int &out) const;
|
||||
|
||||
void get_arg(const std::string &key, float &out) const;
|
||||
|
||||
void get_arg(const std::string &key, bool &out) const;
|
||||
|
||||
private:
|
||||
std::map<std::string, std::string> args_; // key-value pairs
|
||||
command_line() = default;
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "rhi/rhi_defintion.h"
|
||||
#include "glad/glad.h"
|
||||
|
||||
#ifdef core_EXPORTS
|
||||
#define CORE_API __declspec(dllexport)
|
||||
|
@ -5,203 +5,168 @@
|
||||
* A smart pointer to an object which implements AddRef/Release.
|
||||
*/
|
||||
template<typename ReferencedType>
|
||||
class ref_count_ptr
|
||||
{
|
||||
typedef ReferencedType* reference_type;
|
||||
class ref_count_ptr {
|
||||
typedef ReferencedType *reference_type;
|
||||
|
||||
public:
|
||||
ref_count_ptr(): reference_(nullptr) {
|
||||
}
|
||||
|
||||
ref_count_ptr():
|
||||
reference_(nullptr)
|
||||
{ }
|
||||
explicit ref_count_ptr(ReferencedType *in_reference, bool bAddRef = true) {
|
||||
reference_ = in_reference;
|
||||
if (reference_ && bAddRef) {
|
||||
reference_->AddRef();
|
||||
}
|
||||
}
|
||||
|
||||
explicit ref_count_ptr(ReferencedType* in_reference,bool bAddRef = true)
|
||||
{
|
||||
reference_ = in_reference;
|
||||
if(reference_ && bAddRef)
|
||||
{
|
||||
reference_->AddRef();
|
||||
}
|
||||
}
|
||||
ref_count_ptr(const ref_count_ptr ©) {
|
||||
reference_ = copy.reference_;
|
||||
if (reference_) {
|
||||
reference_->AddRef();
|
||||
}
|
||||
}
|
||||
|
||||
ref_count_ptr(const ref_count_ptr& copy)
|
||||
{
|
||||
reference_ = copy.reference_;
|
||||
if(reference_)
|
||||
{
|
||||
reference_->AddRef();
|
||||
}
|
||||
}
|
||||
template<typename CopyReferencedType>
|
||||
explicit ref_count_ptr(const ref_count_ptr<CopyReferencedType> ©) {
|
||||
reference_ = static_cast<ReferencedType *>(copy.get_reference());
|
||||
if (reference_) {
|
||||
reference_->AddRef();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename CopyReferencedType>
|
||||
explicit ref_count_ptr(const ref_count_ptr<CopyReferencedType>& copy)
|
||||
{
|
||||
reference_ = static_cast<ReferencedType*>(copy.get_reference());
|
||||
if (reference_)
|
||||
{
|
||||
reference_->AddRef();
|
||||
}
|
||||
}
|
||||
ref_count_ptr(ref_count_ptr &&move) noexcept {
|
||||
reference_ = move.reference_;
|
||||
move.reference_ = nullptr;
|
||||
}
|
||||
|
||||
ref_count_ptr(ref_count_ptr&& move) noexcept
|
||||
{
|
||||
reference_ = move.reference_;
|
||||
move.reference_ = nullptr;
|
||||
}
|
||||
template<typename MoveReferencedType>
|
||||
explicit ref_count_ptr(ref_count_ptr<MoveReferencedType> &&move) {
|
||||
reference_ = static_cast<ReferencedType *>(move.get_reference());
|
||||
move.reference_ = nullptr;
|
||||
}
|
||||
|
||||
template<typename MoveReferencedType>
|
||||
explicit ref_count_ptr(ref_count_ptr<MoveReferencedType>&& move)
|
||||
{
|
||||
reference_ = static_cast<ReferencedType*>(move.get_reference());
|
||||
move.reference_ = nullptr;
|
||||
}
|
||||
~ref_count_ptr() {
|
||||
if (reference_) {
|
||||
reference_->Release();
|
||||
}
|
||||
}
|
||||
|
||||
~ref_count_ptr()
|
||||
{
|
||||
if(reference_)
|
||||
{
|
||||
reference_->Release();
|
||||
}
|
||||
}
|
||||
ref_count_ptr &operator=(ReferencedType *in_reference) {
|
||||
if (reference_ != in_reference) {
|
||||
// Call AddRef before Release, in case the new reference is the same as the old reference.
|
||||
ReferencedType *old_reference = reference_;
|
||||
reference_ = in_reference;
|
||||
if (reference_) {
|
||||
reference_->AddRef();
|
||||
}
|
||||
if (old_reference) {
|
||||
old_reference->Release();
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
ref_count_ptr& operator=(ReferencedType* in_reference)
|
||||
{
|
||||
if (reference_ != in_reference)
|
||||
{
|
||||
// Call AddRef before Release, in case the new reference is the same as the old reference.
|
||||
ReferencedType* old_reference = reference_;
|
||||
reference_ = in_reference;
|
||||
if (reference_)
|
||||
{
|
||||
reference_->AddRef();
|
||||
}
|
||||
if (old_reference)
|
||||
{
|
||||
old_reference->Release();
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
ref_count_ptr &operator=(const ref_count_ptr &in_ptr) {
|
||||
return *this = in_ptr.reference_;
|
||||
}
|
||||
|
||||
ref_count_ptr& operator=(const ref_count_ptr& in_ptr)
|
||||
{
|
||||
return *this = in_ptr.reference_;
|
||||
}
|
||||
template<typename CopyReferencedType>
|
||||
ref_count_ptr &operator=(const ref_count_ptr<CopyReferencedType> &in_ptr) {
|
||||
return *this = in_ptr.GetReference();
|
||||
}
|
||||
|
||||
template<typename CopyReferencedType>
|
||||
ref_count_ptr& operator=(const ref_count_ptr<CopyReferencedType>& in_ptr)
|
||||
{
|
||||
return *this = in_ptr.GetReference();
|
||||
}
|
||||
ref_count_ptr &operator=(ref_count_ptr &&in_ptr) noexcept {
|
||||
if (this != &in_ptr) {
|
||||
ReferencedType *old_reference = reference_;
|
||||
reference_ = in_ptr.reference_;
|
||||
in_ptr.reference_ = nullptr;
|
||||
if (old_reference) {
|
||||
old_reference->Release();
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
ref_count_ptr& operator=(ref_count_ptr&& in_ptr) noexcept
|
||||
{
|
||||
if (this != &in_ptr)
|
||||
{
|
||||
ReferencedType* old_reference = reference_;
|
||||
reference_ = in_ptr.reference_;
|
||||
in_ptr.reference_ = nullptr;
|
||||
if(old_reference)
|
||||
{
|
||||
old_reference->Release();
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
template<typename MoveReferencedType>
|
||||
ref_count_ptr &operator=(ref_count_ptr<MoveReferencedType> &&in_ptr) {
|
||||
// InPtr is a different type (or we would have called the other operator), so we need not test &InPtr != this
|
||||
ReferencedType *old_reference = reference_;
|
||||
reference_ = in_ptr.reference_;
|
||||
in_ptr.reference_ = nullptr;
|
||||
if (old_reference) {
|
||||
old_reference->Release();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename MoveReferencedType>
|
||||
ref_count_ptr& operator=(ref_count_ptr<MoveReferencedType>&& in_ptr)
|
||||
{
|
||||
// InPtr is a different type (or we would have called the other operator), so we need not test &InPtr != this
|
||||
ReferencedType* old_reference = reference_;
|
||||
reference_ = in_ptr.reference_;
|
||||
in_ptr.reference_ = nullptr;
|
||||
if (old_reference)
|
||||
{
|
||||
old_reference->Release();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
ReferencedType *operator->() const {
|
||||
return reference_;
|
||||
}
|
||||
|
||||
ReferencedType* operator->() const
|
||||
{
|
||||
return reference_;
|
||||
}
|
||||
operator reference_type() const {
|
||||
return reference_;
|
||||
}
|
||||
|
||||
operator reference_type() const
|
||||
{
|
||||
return reference_;
|
||||
}
|
||||
ReferencedType **get_init_reference() {
|
||||
*this = nullptr;
|
||||
return &reference_;
|
||||
}
|
||||
|
||||
ReferencedType** get_init_reference()
|
||||
{
|
||||
*this = nullptr;
|
||||
return &reference_;
|
||||
}
|
||||
ReferencedType *get_reference() const {
|
||||
return reference_;
|
||||
}
|
||||
|
||||
ReferencedType* get_reference() const
|
||||
{
|
||||
return reference_;
|
||||
}
|
||||
friend bool is_valid_ref(const ref_count_ptr &in_reference) {
|
||||
return in_reference.reference_ != nullptr;
|
||||
}
|
||||
|
||||
friend bool is_valid_ref(const ref_count_ptr& in_reference)
|
||||
{
|
||||
return in_reference.reference_ != nullptr;
|
||||
}
|
||||
bool is_valid() const {
|
||||
return reference_ != nullptr;
|
||||
}
|
||||
|
||||
bool is_valid() const
|
||||
{
|
||||
return reference_ != nullptr;
|
||||
}
|
||||
void safe_release() {
|
||||
*this = nullptr;
|
||||
}
|
||||
|
||||
void safe_release()
|
||||
{
|
||||
*this = nullptr;
|
||||
}
|
||||
unsigned int get_ref_count() {
|
||||
unsigned int result = 0;
|
||||
if (reference_) {
|
||||
result = reference_->GetRefCount();
|
||||
assert(result > 0);
|
||||
// you should never have a zero ref count if there is a live ref counted pointer (*this is live)
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned int get_ref_count()
|
||||
{
|
||||
unsigned int result = 0;
|
||||
if (reference_)
|
||||
{
|
||||
result = reference_->GetRefCount();
|
||||
assert(result > 0); // you should never have a zero ref count if there is a live ref counted pointer (*this is live)
|
||||
}
|
||||
return result;
|
||||
}
|
||||
void swap(ref_count_ptr &in_ptr) noexcept // this does not change the reference count, and so is faster
|
||||
{
|
||||
ReferencedType *old_reference = reference_;
|
||||
reference_ = in_ptr.reference_;
|
||||
in_ptr.reference_ = old_reference;
|
||||
}
|
||||
|
||||
void swap(ref_count_ptr& in_ptr) noexcept // this does not change the reference count, and so is faster
|
||||
{
|
||||
ReferencedType* old_reference = reference_;
|
||||
reference_ = in_ptr.reference_;
|
||||
in_ptr.reference_ = old_reference;
|
||||
}
|
||||
|
||||
// void Serialize(FArchive& Ar)
|
||||
// {
|
||||
// reference_type PtrReference = Reference;
|
||||
// Ar << PtrReference;
|
||||
// if(Ar.IsLoading())
|
||||
// {
|
||||
// *this = PtrReference;
|
||||
// }
|
||||
// }
|
||||
// void Serialize(FArchive& Ar)
|
||||
// {
|
||||
// reference_type PtrReference = Reference;
|
||||
// Ar << PtrReference;
|
||||
// if(Ar.IsLoading())
|
||||
// {
|
||||
// *this = PtrReference;
|
||||
// }
|
||||
// }
|
||||
|
||||
private:
|
||||
ReferencedType *reference_;
|
||||
|
||||
ReferencedType* reference_;
|
||||
|
||||
template <typename OtherType>
|
||||
friend class ref_count_ptr;
|
||||
template<typename OtherType>
|
||||
friend class ref_count_ptr;
|
||||
|
||||
public:
|
||||
bool operator==(const ref_count_ptr& b) const
|
||||
{
|
||||
return get_reference() == b.get_reference();
|
||||
}
|
||||
bool operator==(const ref_count_ptr &b) const {
|
||||
return get_reference() == b.get_reference();
|
||||
}
|
||||
|
||||
bool operator==(ReferencedType* b) const
|
||||
{
|
||||
return get_reference() == b;
|
||||
}
|
||||
};
|
||||
bool operator==(ReferencedType *b) const {
|
||||
return get_reference() == b;
|
||||
}
|
||||
};
|
||||
|
@ -2,31 +2,30 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace scope_exit_support
|
||||
{
|
||||
namespace scope_exit_support {
|
||||
/**
|
||||
* Not meant for direct consumption : use ON_SCOPE_EXIT instead.
|
||||
*
|
||||
* RAII class that calls a lambda when it is destroyed.
|
||||
*/
|
||||
template <typename FuncType>
|
||||
class scope_guard
|
||||
{
|
||||
scope_guard(scope_guard&&) = delete;
|
||||
scope_guard(const scope_guard&) = delete;
|
||||
scope_guard& operator=(scope_guard&&) = delete;
|
||||
scope_guard& operator=(const scope_guard&) = delete;
|
||||
template<typename FuncType>
|
||||
class scope_guard {
|
||||
scope_guard(scope_guard &&) = delete;
|
||||
|
||||
scope_guard(const scope_guard &) = delete;
|
||||
|
||||
scope_guard &operator=(scope_guard &&) = delete;
|
||||
|
||||
scope_guard &operator=(const scope_guard &) = delete;
|
||||
|
||||
public:
|
||||
// Given a lambda, constructs an RAII scope guard.
|
||||
explicit scope_guard(FuncType&& InFunc)
|
||||
: func_((FuncType&&)InFunc)
|
||||
{
|
||||
explicit scope_guard(FuncType &&InFunc)
|
||||
: func_((FuncType &&) InFunc) {
|
||||
}
|
||||
|
||||
// Causes the lambda to be executed.
|
||||
~scope_guard()
|
||||
{
|
||||
~scope_guard() {
|
||||
func_();
|
||||
}
|
||||
|
||||
@ -35,12 +34,10 @@ namespace scope_exit_support
|
||||
FuncType func_;
|
||||
};
|
||||
|
||||
struct scope_guard_syntax_support
|
||||
{
|
||||
template <typename FuncType>
|
||||
scope_guard<FuncType> operator+(FuncType&& in_func)
|
||||
{
|
||||
return scope_guard<FuncType>((FuncType&&)in_func);
|
||||
struct scope_guard_syntax_support {
|
||||
template<typename FuncType>
|
||||
scope_guard<FuncType> operator+(FuncType &&in_func) {
|
||||
return scope_guard<FuncType>((FuncType &&) in_func);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -5,10 +5,9 @@
|
||||
#include "shader/shader_ps_opengl.h"
|
||||
#include "shader/shader_vs_opengl.h"
|
||||
|
||||
void ps_opengl_compute_callback(const ImDrawList* parent_list, const ImDrawCmd* cmd)
|
||||
{
|
||||
const auto data = static_cast<pixel_shader_drawer_opengl*>(cmd->UserCallbackData);
|
||||
const std::shared_ptr<render_target_opengl>& rt = data->rt;
|
||||
void ps_opengl_compute_callback(const ImDrawList *parent_list, const ImDrawCmd *cmd) {
|
||||
const auto data = static_cast<pixel_shader_drawer_opengl *>(cmd->UserCallbackData);
|
||||
const std::shared_ptr<render_target_opengl> &rt = data->rt;
|
||||
const auto program = data->program;
|
||||
program->use_program();
|
||||
|
||||
@ -17,31 +16,31 @@ void ps_opengl_compute_callback(const ImDrawList* parent_list, const ImDrawCmd*
|
||||
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 },
|
||||
{
|
||||
{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];
|
||||
|
||||
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);
|
||||
@ -54,7 +53,7 @@ void ps_opengl_compute_callback(const ImDrawList* parent_list, const ImDrawCmd*
|
||||
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);
|
||||
@ -63,12 +62,12 @@ void ps_opengl_compute_callback(const ImDrawList* parent_list, const ImDrawCmd*
|
||||
|
||||
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);
|
||||
@ -77,18 +76,16 @@ void ps_opengl_compute_callback(const ImDrawList* parent_list, const ImDrawCmd*
|
||||
}
|
||||
|
||||
|
||||
pixel_shader_drawer_opengl::~pixel_shader_drawer_opengl()
|
||||
{
|
||||
pixel_shader_drawer_opengl::~pixel_shader_drawer_opengl() {
|
||||
if (vbo)
|
||||
glDeleteBuffers(1, &vbo);
|
||||
if (ibo)
|
||||
glDeleteBuffers(1, &ibo);
|
||||
}
|
||||
|
||||
void pixel_shader_drawer_opengl::init(int width, int height, std::shared_ptr<shader> in_pixel_shader, std::shared_ptr<shader> in_vertex_shader)
|
||||
{
|
||||
if (!in_vertex_shader)
|
||||
{
|
||||
void pixel_shader_drawer_opengl::init(int width, int height, std::shared_ptr<shader> in_pixel_shader,
|
||||
std::shared_ptr<shader> in_vertex_shader) {
|
||||
if (!in_vertex_shader) {
|
||||
in_vertex_shader = application::get()->get_renderer()->get_pixel_shader_render_default_vs();
|
||||
}
|
||||
|
||||
@ -96,13 +93,14 @@ void pixel_shader_drawer_opengl::init(int width, int height, std::shared_ptr<sha
|
||||
const auto gl_vs = std::static_pointer_cast<shader_vs_opengl>(in_vertex_shader);
|
||||
vertex_shader = gl_vs;
|
||||
pixel_shader = gl_ps;
|
||||
rt = std::static_pointer_cast<render_target_opengl>(application::get()->create_render_target(width, height, texture_format::RGBA32_FLOAT));
|
||||
rt = std::static_pointer_cast<render_target_opengl>(
|
||||
application::get()->create_render_target(width, height, texture_format::RGBA32_FLOAT));
|
||||
program = std::make_shared<shader_program_opengl>();
|
||||
program->create_program(gl_ps, gl_vs);
|
||||
|
||||
|
||||
idx_buffer = {0, 1, 2, 0, 2, 3};
|
||||
vtx_buffer.resize(4);
|
||||
|
||||
|
||||
glGenBuffers(1, &vbo);
|
||||
glGenBuffers(1, &ibo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
@ -116,13 +114,11 @@ void pixel_shader_drawer_opengl::init(int width, int height, std::shared_ptr<sha
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void pixel_shader_drawer_opengl::resize(int width, int height)
|
||||
{
|
||||
void pixel_shader_drawer_opengl::resize(int width, int height) {
|
||||
rt->resize(width, height);
|
||||
}
|
||||
|
||||
void pixel_shader_drawer_opengl::draw()
|
||||
{
|
||||
void pixel_shader_drawer_opengl::draw() {
|
||||
#if _DEBUG
|
||||
assert(!(pixel_shader.expired() || vertex_shader.expired()));
|
||||
#endif
|
||||
@ -131,8 +127,7 @@ void pixel_shader_drawer_opengl::draw()
|
||||
rt->draw();
|
||||
}
|
||||
|
||||
void pixel_shader_drawer_opengl::set_vertex_shader(std::shared_ptr<shader> in_vertex_shader)
|
||||
{
|
||||
void pixel_shader_drawer_opengl::set_vertex_shader(std::shared_ptr<shader> in_vertex_shader) {
|
||||
#if _DEBUG
|
||||
assert(!(pixel_shader.expired() || vertex_shader.expired()));
|
||||
#endif
|
||||
|
@ -6,14 +6,19 @@
|
||||
class shader_ps_opengl;
|
||||
class shader_vs_opengl;
|
||||
|
||||
class pixel_shader_drawer_opengl : public pixel_shader_drawer
|
||||
{
|
||||
class pixel_shader_drawer_opengl : public pixel_shader_drawer {
|
||||
public:
|
||||
pixel_shader_drawer_opengl() = default;
|
||||
|
||||
~pixel_shader_drawer_opengl() override;
|
||||
void init(int width, int height, std::shared_ptr<shader> in_pixel_shader, std::shared_ptr<shader> in_vertex_shader) override;
|
||||
|
||||
void init(int width, int height, std::shared_ptr<shader> in_pixel_shader,
|
||||
std::shared_ptr<shader> in_vertex_shader) override;
|
||||
|
||||
void resize(int width, int height) override;
|
||||
|
||||
void draw() override;
|
||||
|
||||
void set_vertex_shader(std::shared_ptr<shader> in_vertex_shader) override;
|
||||
|
||||
std::shared_ptr<render_target_opengl> rt;
|
||||
@ -22,7 +27,7 @@ public:
|
||||
std::vector<ImDrawIdx> idx_buffer;
|
||||
GLuint vbo = 0;
|
||||
GLuint ibo = 0;
|
||||
|
||||
|
||||
std::weak_ptr<shader_vs_opengl> vertex_shader;
|
||||
std::weak_ptr<shader_ps_opengl> pixel_shader;
|
||||
};
|
||||
|
@ -2,81 +2,78 @@
|
||||
|
||||
#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;
|
||||
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)
|
||||
{
|
||||
void render_target_opengl::init(int width, int height, texture_format format) {
|
||||
width_ = width;
|
||||
height_ = height;
|
||||
|
||||
|
||||
glGenFramebuffers(1, &fbo_);
|
||||
CHECK_GL_ERRORS
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
|
||||
@ -85,13 +82,13 @@ void render_target_opengl::init(int width, int height, texture_format format)
|
||||
#if defined(__APPLE__)
|
||||
LockGLContext([NSOpenGLContext currentContext]);
|
||||
#endif
|
||||
|
||||
|
||||
// Create a new OpenGL texture
|
||||
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);
|
||||
internal_format_ = to_internal_format(format);
|
||||
@ -102,42 +99,36 @@ LockGLContext([NSOpenGLContext currentContext]);
|
||||
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
|
||||
|
||||
}
|
||||
|
||||
render_target_opengl::~render_target_opengl()
|
||||
{
|
||||
render_target_opengl::~render_target_opengl() {
|
||||
glDeleteFramebuffers(1, &fbo_);
|
||||
glDeleteTextures(1, &texture_);
|
||||
}
|
||||
|
||||
void* render_target_opengl::lock(lock_state state)
|
||||
{
|
||||
void *render_target_opengl::lock(lock_state state) {
|
||||
locked_texture_ = malloc(width_ * height_ * 4);
|
||||
switch (state)
|
||||
{
|
||||
case lock_state::READ:
|
||||
case lock_state::READ_WRITE:
|
||||
{
|
||||
switch (state) {
|
||||
case lock_state::READ:
|
||||
case lock_state::READ_WRITE: {
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, locked_texture_);
|
||||
}
|
||||
break;
|
||||
case lock_state::WRITE:
|
||||
break;
|
||||
case lock_state::NONE:
|
||||
break;
|
||||
case lock_state::WRITE:
|
||||
break;
|
||||
case lock_state::NONE:
|
||||
break;
|
||||
}
|
||||
return locked_texture_;
|
||||
}
|
||||
|
||||
void render_target_opengl::unlock()
|
||||
{
|
||||
void render_target_opengl::unlock() {
|
||||
#if defined(__APPLE__)
|
||||
LockGLContext([NSOpenGLContext currentContext]);
|
||||
#endif
|
||||
@ -146,37 +137,36 @@ void render_target_opengl::unlock()
|
||||
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, locked_texture_);
|
||||
|
||||
#if defined(__APPLE__)
|
||||
UnlockGLContext([NSOpenGLContext currentContext]);
|
||||
#endif
|
||||
|
||||
|
||||
free(locked_texture_);
|
||||
locked_texture_ = nullptr;
|
||||
}
|
||||
|
||||
void render_target_opengl::on_resize(int width, int height)
|
||||
{
|
||||
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);
|
||||
CHECK_GL_ERRORS
|
||||
|
||||
@ -188,7 +178,7 @@ void render_target_opengl::on_resize(int width, int height)
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
|
||||
#if defined(__APPLE__)
|
||||
UnlockGLContext([NSOpenGLContext currentContext]);
|
||||
#endif
|
||||
|
@ -1,26 +1,28 @@
|
||||
#pragma once
|
||||
#include <SDL_opengl.h>
|
||||
|
||||
#include "rhi/render_target.h"
|
||||
|
||||
class render_target_opengl : public render_target
|
||||
{
|
||||
class render_target_opengl : public render_target {
|
||||
public:
|
||||
void init(int width, int height, texture_format format) override;
|
||||
|
||||
~render_target_opengl() override;
|
||||
|
||||
ImTextureID get_texture_id() override { return (void*)static_cast<intptr_t>(texture_); }
|
||||
|
||||
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 *lock(lock_state state) override;
|
||||
|
||||
void unlock() override;
|
||||
|
||||
protected:
|
||||
void on_resize(int width, int height) override;
|
||||
|
||||
private:
|
||||
GLuint fbo_ = 0;
|
||||
GLuint texture_ = 0;
|
||||
GLint internal_format_ = 0;
|
||||
void* locked_texture_ = nullptr;
|
||||
void *locked_texture_ = nullptr;
|
||||
};
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include "renderer_opengl.h"
|
||||
|
||||
#include <SDL_hints.h>
|
||||
|
||||
#include "imgui_impl_glfw.h"
|
||||
#include "imgui_impl_opengl3.h"
|
||||
#include "imgui_impl_sdl3.h"
|
||||
#include "pixel_shader_drawer_opengl.h"
|
||||
@ -14,163 +13,106 @@
|
||||
#include "shader/shader_ps_opengl.h"
|
||||
#include "shader/shader_vs_opengl.h"
|
||||
|
||||
SDL_GLContext g_gl_context = nullptr;
|
||||
|
||||
void renderer_opengl::pre_init()
|
||||
{
|
||||
#if defined(__APPLE__)
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); // Always required on Mac
|
||||
void renderer_opengl::pre_init() {
|
||||
// Decide GL+GLSL versions
|
||||
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
||||
// GL ES 2.0 + GLSL 100
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
|
||||
#elif defined(__APPLE__)
|
||||
// GL 3.2 + GLSL 150
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac
|
||||
#else
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
|
||||
// GL 3.0 + GLSL 130
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
|
||||
//glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only
|
||||
//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // 3.0+ only
|
||||
#endif
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6);
|
||||
// set sdl using graphics card
|
||||
|
||||
|
||||
// Enable native IME.
|
||||
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
|
||||
|
||||
// Create window with graphics context
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
||||
|
||||
}
|
||||
|
||||
bool renderer_opengl::init(SDL_Window* window_handle)
|
||||
{
|
||||
bool renderer_opengl::init(GLFWwindow *window_handle) {
|
||||
if (has_initialized_)
|
||||
return true;
|
||||
const auto glsl_version = "#version 460";
|
||||
|
||||
g_gl_context = SDL_GL_CreateContext(window_handle);
|
||||
// gladLoadGL();
|
||||
if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress)) {
|
||||
spdlog::critical("Failed to initialize OpenGL loader");
|
||||
|
||||
glfwMakeContextCurrent(window_handle);
|
||||
if (gladLoadGL() == 0) {
|
||||
spdlog::error("Failed to initialize OpenGL loader!");
|
||||
return false;
|
||||
}
|
||||
SDL_GL_MakeCurrent(window_handle, g_gl_context);
|
||||
SDL_GL_SetSwapInterval(1); // Enable vsync
|
||||
SDL_ShowWindow(window_handle);
|
||||
|
||||
|
||||
glfwSwapInterval(1); // Enable vsync
|
||||
|
||||
const auto glsl_version = "#version 460";
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplSDL3_InitForOpenGL(window_handle, g_gl_context);
|
||||
ImGui_ImplGlfw_InitForOpenGL(window_handle, false);
|
||||
#ifdef __EMSCRIPTEN__
|
||||
ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback("#canvas");
|
||||
#endif
|
||||
ImGui_ImplOpenGL3_Init(glsl_version);
|
||||
|
||||
has_initialized_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void renderer_opengl::shutdown()
|
||||
{
|
||||
void renderer_opengl::shutdown() {
|
||||
renderer::shutdown();
|
||||
#ifdef __EMSCRIPTEN__
|
||||
EMSCRIPTEN_MAINLOOP_END;
|
||||
#endif
|
||||
ImGui_ImplOpenGL3_Shutdown();
|
||||
ImGui_ImplSDL3_Shutdown();
|
||||
ImGui_ImplGlfw_Shutdown();
|
||||
}
|
||||
|
||||
void renderer_opengl::post_shutdown()
|
||||
{
|
||||
SDL_GL_DeleteContext(g_gl_context);
|
||||
g_gl_context = nullptr;
|
||||
void renderer_opengl::post_shutdown() {
|
||||
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;
|
||||
target_desc.profile = g_slang_global_session->findProfile("glsl_460");
|
||||
|
||||
const char* search_paths[] = { shader_path.c_str() };
|
||||
slang::SessionDesc session_desc;
|
||||
session_desc.searchPaths = search_paths;
|
||||
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
|
||||
|
||||
g_slang_global_session->createSession(session_desc, out_session);
|
||||
std::shared_ptr<shader> renderer_opengl::load_shader(const std::string &entry_name) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<shader> renderer_opengl::load_shader(const std::string& entry_name)
|
||||
{
|
||||
auto handle = std::make_shared<slang_handle>();
|
||||
if (!handle->init_slang_module(application::get()->get_entry_model(), entry_name))
|
||||
return nullptr;
|
||||
const auto shader_type = handle->get_shader_type();
|
||||
std::shared_ptr<shader> out;
|
||||
switch (shader_type)
|
||||
{
|
||||
case SLANG_STAGE_VERTEX:
|
||||
{
|
||||
out = std::make_shared<shader_vs_opengl>(handle);
|
||||
}
|
||||
break;
|
||||
case SLANG_STAGE_GEOMETRY:
|
||||
{
|
||||
out = std::make_shared<shader_gs_opengl>(handle);
|
||||
}
|
||||
break;
|
||||
case SLANG_STAGE_PIXEL:
|
||||
{
|
||||
out = std::make_shared<shader_ps_opengl>(handle);
|
||||
}
|
||||
break;
|
||||
case SLANG_STAGE_COMPUTE:
|
||||
{
|
||||
out = std::make_shared<shader_cs_opengl>(handle);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
spdlog::error("slang: unsupported shader type");
|
||||
return nullptr;
|
||||
}
|
||||
if (!out->init())
|
||||
return nullptr;
|
||||
return out;
|
||||
}
|
||||
|
||||
std::shared_ptr<pixel_shader_drawer> renderer_opengl::create_pixel_shader_drawer()
|
||||
{
|
||||
std::shared_ptr<pixel_shader_drawer> renderer_opengl::create_pixel_shader_drawer() {
|
||||
return std::make_shared<pixel_shader_drawer_opengl>();
|
||||
}
|
||||
|
||||
void renderer_opengl::new_frame(SDL_Window* window_handle)
|
||||
{
|
||||
void renderer_opengl::new_frame(GLFWwindow *window_handle) {
|
||||
// Start the Dear ImGui frame
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
ImGui_ImplSDL3_NewFrame();
|
||||
ImGui_ImplGlfw_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
}
|
||||
|
||||
void renderer_opengl::end_frame(SDL_Window* window_handle)
|
||||
{
|
||||
void renderer_opengl::end_frame(GLFWwindow *window_handle) {
|
||||
// Rendering
|
||||
ImGui::Render();
|
||||
const auto& io = ImGui::GetIO();
|
||||
|
||||
glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
|
||||
glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w);
|
||||
int display_w, display_h;
|
||||
glfwGetFramebufferSize(window_handle, &display_w, &display_h);
|
||||
glViewport(0, 0, display_w, display_h);
|
||||
glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w,
|
||||
clear_color.w);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
SDL_GL_SwapWindow(window_handle);
|
||||
|
||||
glfwSwapBuffers(window_handle);
|
||||
}
|
||||
|
||||
void renderer_opengl::resize(int width, int height)
|
||||
{
|
||||
void renderer_opengl::resize(int width, int height) {
|
||||
}
|
||||
|
||||
std::shared_ptr<texture> renderer_opengl::create_texture(const unsigned char* data, int width, int height)
|
||||
{
|
||||
std::shared_ptr<texture> renderer_opengl::create_texture(const unsigned char *data, int width, int height) {
|
||||
auto out = std::make_shared<texture_opengl>();
|
||||
if (!out->init_data(data, width, height))
|
||||
{
|
||||
if (!out->init_data(data, width, height)) {
|
||||
out = nullptr;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
std::shared_ptr<render_target> renderer_opengl::create_render_target(int width, int height, texture_format format)
|
||||
{
|
||||
std::shared_ptr<render_target> renderer_opengl::create_render_target(int width, int height, texture_format format) {
|
||||
const auto target_dx11 = std::make_shared<render_target_opengl>();
|
||||
target_dx11->init(width, height, format);
|
||||
return target_dx11;
|
||||
|
@ -1,25 +1,30 @@
|
||||
#pragma once
|
||||
#include "rhi/renderer.h"
|
||||
extern SDL_GLContext g_gl_context;
|
||||
|
||||
class renderer_opengl : public renderer
|
||||
{
|
||||
class renderer_opengl : public renderer {
|
||||
public:
|
||||
void pre_init() override;
|
||||
bool init(SDL_Window* window_handle) override;
|
||||
|
||||
bool init(GLFWwindow *window_handle) override;
|
||||
|
||||
void shutdown() override;
|
||||
|
||||
void post_shutdown() 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;
|
||||
std::shared_ptr<shader> load_shader(const std::string &entry_name) override;
|
||||
|
||||
std::shared_ptr<pixel_shader_drawer> create_pixel_shader_drawer() override;
|
||||
|
||||
void new_frame(SDL_Window* window_handle) override;
|
||||
void end_frame(SDL_Window* window_handle) override;
|
||||
void new_frame(GLFWwindow *window_handle) override;
|
||||
|
||||
void end_frame(GLFWwindow *window_handle) override;
|
||||
|
||||
void resize(int width, int height) override;
|
||||
std::shared_ptr<texture> create_texture(const unsigned char* data, int width, int height) override;
|
||||
|
||||
std::shared_ptr<texture> create_texture(const unsigned char *data, int width, int height) override;
|
||||
|
||||
std::shared_ptr<render_target> create_render_target(int width, int height, texture_format format) override;
|
||||
|
||||
private:
|
||||
bool has_initialized_ = false;
|
||||
};
|
||||
|
@ -3,13 +3,10 @@
|
||||
#include "shader_program_opengl.h"
|
||||
|
||||
|
||||
shader_cs_opengl::shader_cs_opengl(const std::shared_ptr<slang_handle>& handle): shader_opengl(handle)
|
||||
{
|
||||
|
||||
shader_cs_opengl::shader_cs_opengl(): shader_opengl() {
|
||||
}
|
||||
|
||||
bool shader_cs_opengl::init()
|
||||
{
|
||||
bool shader_cs_opengl::init() {
|
||||
if (!shader_opengl::init())
|
||||
return false;
|
||||
program_ = std::make_shared<shader_program_opengl>();
|
||||
@ -18,8 +15,7 @@ bool shader_cs_opengl::init()
|
||||
return true;
|
||||
}
|
||||
|
||||
void shader_cs_opengl::compute(int x, int y, int z)
|
||||
{
|
||||
void shader_cs_opengl::compute(int x, int y, int z) {
|
||||
program_->use_program();
|
||||
glDispatchCompute(x, y, z);
|
||||
program_->unuse_program();
|
||||
|
@ -1,14 +1,16 @@
|
||||
#pragma once
|
||||
#include "shader_opengl.h"
|
||||
|
||||
class shader_cs_opengl : public shader_opengl
|
||||
{
|
||||
class shader_cs_opengl : public shader_opengl {
|
||||
public:
|
||||
explicit shader_cs_opengl(const std::shared_ptr<slang_handle>& handle);
|
||||
explicit shader_cs_opengl();
|
||||
|
||||
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_;
|
||||
};
|
||||
|
@ -2,10 +2,10 @@
|
||||
#include "shader_opengl.h"
|
||||
#include "rhi/opengl/opengl_def.h"
|
||||
|
||||
class shader_gs_opengl : public shader_opengl
|
||||
{
|
||||
class shader_gs_opengl : public shader_opengl {
|
||||
public:
|
||||
shader_gs_opengl(const std::shared_ptr<slang_handle>& handle) : shader_opengl(handle) {}
|
||||
|
||||
shader_gs_opengl() : shader_opengl() {
|
||||
}
|
||||
|
||||
[[nodiscard]] GLenum get_shader_type() const override { return GL_GEOMETRY_SHADER; }
|
||||
};
|
||||
|
@ -1,225 +1,26 @@
|
||||
#include "shader_opengl.h"
|
||||
|
||||
#include "shader_program_opengl.h"
|
||||
#include "rhi/slang_handle.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()
|
||||
{
|
||||
bool shader_opengl::init() {
|
||||
shader_id_ = glCreateShader(get_shader_type());
|
||||
if (shader_id_ == 0)
|
||||
{
|
||||
if (shader_id_ == 0) {
|
||||
spdlog::error("Failed to create shader");
|
||||
return false;
|
||||
}
|
||||
const auto code_blob = handle_->get_entry_point_code();
|
||||
const auto code_array = static_cast<const char*>(code_blob->getBufferPointer());
|
||||
const GLint code_size = static_cast<GLint>(code_blob->getBufferSize());
|
||||
glShaderSource(shader_id_, 1, &code_array, &code_size);
|
||||
// const auto code_blob = handle_->get_entry_point_code();
|
||||
// const auto code_array = static_cast<const char*>(code_blob->getBufferPointer());
|
||||
// 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
|
||||
|
||||
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);
|
||||
if (compile_status == GL_FALSE)
|
||||
{
|
||||
if (compile_status == GL_FALSE) {
|
||||
GLint log_length = 0;
|
||||
glGetShaderiv(shader_id_, GL_INFO_LOG_LENGTH, &log_length);
|
||||
std::vector<GLchar> log(log_length);
|
||||
@ -233,36 +34,30 @@ bool shader_opengl::init()
|
||||
return true;
|
||||
}
|
||||
|
||||
void shader_opengl::set_using_program(std::shared_ptr<shader_program_opengl> in_program)
|
||||
{
|
||||
if (using_program_.lock())
|
||||
{
|
||||
void shader_opengl::set_using_program(std::shared_ptr<shader_program_opengl> in_program) {
|
||||
if (using_program_.lock()) {
|
||||
spdlog::error("Shader is already used by another program");
|
||||
return;
|
||||
}
|
||||
using_program_ = in_program;
|
||||
}
|
||||
|
||||
void shader_opengl::set_cbuffer(const char* name, void* buffer, int size)
|
||||
{
|
||||
void shader_opengl::set_cbuffer(const char *name, void *buffer, int size) {
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
@ -1,13 +1,11 @@
|
||||
#pragma once
|
||||
#include <map>
|
||||
|
||||
#include "slang.h"
|
||||
#include "rhi/shader.h"
|
||||
|
||||
class shader_program_opengl;
|
||||
|
||||
struct opengl_uniform_data
|
||||
{
|
||||
struct opengl_uniform_data {
|
||||
std::string type_name;
|
||||
std::string name;
|
||||
GLuint location = 0;
|
||||
@ -15,38 +13,44 @@ struct opengl_uniform_data
|
||||
GLint format = 0;
|
||||
};
|
||||
|
||||
struct opengl_texture_data
|
||||
{
|
||||
struct opengl_texture_data {
|
||||
std::string sampler_name;
|
||||
GLuint binding = 0;
|
||||
GLint format = 0;
|
||||
};
|
||||
|
||||
class shader_opengl : public shader
|
||||
{
|
||||
class shader_opengl : public shader {
|
||||
public:
|
||||
explicit shader_opengl(const std::shared_ptr<slang_handle>& handle) : shader(handle), shader_id_(0)
|
||||
{
|
||||
explicit shader_opengl() : shader(), 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_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;
|
||||
|
||||
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_; }
|
||||
|
||||
[[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_;
|
||||
|
@ -3,44 +3,38 @@
|
||||
#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_)
|
||||
{
|
||||
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())
|
||||
{
|
||||
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())
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (link_status == GL_FALSE) {
|
||||
GLint log_length = 0;
|
||||
glGetProgramiv(program_id_, GL_INFO_LOG_LENGTH, &log_length);
|
||||
std::vector<GLchar> log(log_length);
|
||||
@ -51,7 +45,7 @@ bool shader_program_opengl::create_program(std::shared_ptr<shader_opengl> in_pix
|
||||
program_id_ = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
glDetachShader(program_id_, vertex_id);
|
||||
glDetachShader(program_id_, pixel_id);
|
||||
|
||||
@ -67,33 +61,28 @@ bool shader_program_opengl::create_program(std::shared_ptr<shader_opengl> in_pix
|
||||
return true;
|
||||
}
|
||||
|
||||
bool shader_program_opengl::create_program(std::shared_ptr<shader_opengl> in_compute_shader)
|
||||
{
|
||||
if (program_id_)
|
||||
{
|
||||
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())
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (link_status == GL_FALSE) {
|
||||
GLint log_length = 0;
|
||||
glGetProgramiv(program_id_, GL_INFO_LOG_LENGTH, &log_length);
|
||||
std::vector<GLchar> log(log_length);
|
||||
@ -104,7 +93,7 @@ bool shader_program_opengl::create_program(std::shared_ptr<shader_opengl> in_com
|
||||
program_id_ = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
glDetachShader(program_id_, compute_id);
|
||||
compute_shader_ = in_compute_shader;
|
||||
in_compute_shader->set_using_program(shared_from_this());
|
||||
@ -115,11 +104,10 @@ bool shader_program_opengl::create_program(std::shared_ptr<shader_opengl> in_com
|
||||
return true;
|
||||
}
|
||||
|
||||
void shader_program_opengl::destroy_program()
|
||||
{
|
||||
for (const auto& val : ubo_map_ | std::views::values)
|
||||
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())
|
||||
@ -135,17 +123,15 @@ void shader_program_opengl::destroy_program()
|
||||
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);
|
||||
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;
|
||||
|
||||
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())
|
||||
{
|
||||
if (find_ubo != ubo_map_.end()) {
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, find_ubo->second);
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, size, buffer);
|
||||
return;
|
||||
@ -153,62 +139,58 @@ void shader_program_opengl::set_uniform(const char* slang_name, void* buffer, in
|
||||
|
||||
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);
|
||||
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 auto &uniform_data = uniform_name->second;
|
||||
const GLint location = glGetProgramResourceIndex(program_id_, GL_SHADER_STORAGE_BLOCK, uniform_data.name.c_str());
|
||||
if (location == -1)
|
||||
{
|
||||
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);
|
||||
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;
|
||||
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());
|
||||
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);
|
||||
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;
|
||||
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();
|
||||
|
||||
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());
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <SDL_opengl.h>
|
||||
|
||||
#include "shader_opengl.h"
|
||||
|
||||
@ -10,67 +9,73 @@ class render_target;
|
||||
class shader;
|
||||
class shader_opengl;
|
||||
|
||||
class shader_program_opengl : public std::enable_shared_from_this<shader_program_opengl>
|
||||
{
|
||||
class shader_program_opengl : public std::enable_shared_from_this<shader_program_opengl> {
|
||||
public:
|
||||
~shader_program_opengl()
|
||||
{
|
||||
~shader_program_opengl() {
|
||||
destroy_program();
|
||||
}
|
||||
|
||||
void use_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_); }
|
||||
|
||||
|
||||
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_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);
|
||||
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());
|
||||
void set_uniform(const char *name, const T &buffer) {
|
||||
set_uniform(name, (void *) &buffer, sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void set_ssbo(const char* name, const T& buffer)
|
||||
{
|
||||
set_ssbo(name, (void*)&buffer, sizeof(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 std::vector<T>& buffer)
|
||||
{
|
||||
set_ssbo(name, (void*)buffer.data(), sizeof(T) * buffer.size());
|
||||
void set_ssbo(const char *name, const T &buffer) {
|
||||
set_ssbo(name, (void *) &buffer, sizeof(T), 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(), sizeof(T));
|
||||
}
|
||||
|
||||
[[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_;
|
||||
|
@ -4,12 +4,9 @@
|
||||
|
||||
class shader_vs_opengl;
|
||||
|
||||
class shader_ps_opengl : public shader_opengl
|
||||
{
|
||||
class shader_ps_opengl : public shader_opengl {
|
||||
public:
|
||||
explicit shader_ps_opengl(const std::shared_ptr<slang_handle>& handle) : shader_opengl(handle)
|
||||
{
|
||||
|
||||
explicit shader_ps_opengl() : shader_opengl() {
|
||||
}
|
||||
|
||||
[[nodiscard]] GLenum get_shader_type() const override { return GL_FRAGMENT_SHADER; }
|
||||
|
@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
#include "shader_opengl.h"
|
||||
|
||||
class shader_vs_opengl : public shader_opengl
|
||||
{
|
||||
class shader_vs_opengl : public shader_opengl {
|
||||
public:
|
||||
shader_vs_opengl(const std::shared_ptr<slang_handle>& handle) : shader_opengl(handle) {}
|
||||
shader_vs_opengl() : shader_opengl() {
|
||||
}
|
||||
|
||||
[[nodiscard]] GLenum get_shader_type() const override { return GL_VERTEX_SHADER; }
|
||||
};
|
||||
|
@ -2,32 +2,29 @@
|
||||
|
||||
#include "opengl_def.h"
|
||||
|
||||
texture_opengl::~texture_opengl()
|
||||
{
|
||||
if (texture_id_ != 0)
|
||||
{
|
||||
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)
|
||||
{
|
||||
bool texture_opengl::init_data(const unsigned char *data, int width, int height) {
|
||||
width_ = width;
|
||||
height_ = height;
|
||||
|
||||
|
||||
#if defined(__APPLE__)
|
||||
LockGLContext([NSOpenGLContext currentContext]);
|
||||
#endif
|
||||
|
||||
|
||||
// Create a new OpenGL texture
|
||||
glGenTextures(1, &texture_id_);
|
||||
CHECK_GL_ERRORS
|
||||
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture_id_);
|
||||
|
||||
|
||||
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, data);
|
||||
CHECK_GL_ERRORS
|
||||
#if defined(__APPLE__)
|
||||
|
@ -1,16 +1,18 @@
|
||||
#pragma once
|
||||
#include <SDL_opengl.h>
|
||||
|
||||
#include "rhi/texture.h"
|
||||
|
||||
class texture_opengl : public texture
|
||||
{
|
||||
class texture_opengl : public texture {
|
||||
public:
|
||||
~texture_opengl() override;
|
||||
ImTextureID get_texture_id() override { return (void*)static_cast<intptr_t>(texture_id_); }
|
||||
|
||||
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;
|
||||
|
||||
bool init_data(const unsigned char *data, int width, int height) override;
|
||||
|
||||
[[nodiscard]] bool is_valid() const override { return texture_id_ != 0; }
|
||||
|
||||
private:
|
||||
GLuint texture_id_ = 0;
|
||||
};
|
||||
|
@ -1,2 +1 @@
|
||||
#include "E:/Projects/Arona/build/AronaCore/core/CMakeFiles/core.dir/Debug/cmake_pch.hxx"
|
||||
#include "pixel_shader_drawer.h"
|
||||
#include "pixel_shader_drawer.h"
|
||||
|
@ -3,14 +3,20 @@
|
||||
class shader;
|
||||
class render_target;
|
||||
|
||||
class pixel_shader_drawer
|
||||
{
|
||||
class pixel_shader_drawer {
|
||||
public:
|
||||
virtual ~pixel_shader_drawer() = default;
|
||||
virtual void init(int width, int height, std::shared_ptr<shader> in_pixel_shader, std::shared_ptr<shader> in_vertex_shader = nullptr) = 0;
|
||||
|
||||
virtual void init(int width, int height, std::shared_ptr<shader> in_pixel_shader,
|
||||
std::shared_ptr<shader> in_vertex_shader = nullptr) = 0;
|
||||
|
||||
virtual void resize(int width, int height) = 0;
|
||||
|
||||
virtual void draw() = 0;
|
||||
virtual void set_vertex_shader(std::shared_ptr<shader> in_vertex_shader) {}
|
||||
|
||||
virtual void set_vertex_shader(std::shared_ptr<shader> in_vertex_shader) {
|
||||
}
|
||||
|
||||
protected:
|
||||
std::shared_ptr<render_target> rt_;
|
||||
};
|
||||
|
@ -1,16 +1,17 @@
|
||||
#pragma once
|
||||
#include "imgui.h"
|
||||
|
||||
class render_resource : public std::enable_shared_from_this<render_resource>
|
||||
{
|
||||
class render_resource : public std::enable_shared_from_this<render_resource> {
|
||||
public:
|
||||
virtual ~render_resource() = default;
|
||||
|
||||
virtual int get_width() const = 0;
|
||||
|
||||
virtual int get_height() const = 0;
|
||||
|
||||
virtual ImTextureID get_texture_id() = 0;
|
||||
|
||||
void draw()
|
||||
{
|
||||
|
||||
void draw() {
|
||||
ImGui::Image(get_texture_id(), ImVec2(static_cast<float>(get_width()), static_cast<float>(get_height())));
|
||||
}
|
||||
};
|
||||
|
@ -2,24 +2,21 @@
|
||||
#include "render_resource.h"
|
||||
#include "rhi_defintion.h"
|
||||
|
||||
enum class lock_state
|
||||
{
|
||||
enum class lock_state {
|
||||
NONE,
|
||||
WRITE,
|
||||
READ,
|
||||
READ_WRITE
|
||||
};
|
||||
|
||||
class render_target : public render_resource
|
||||
{
|
||||
class render_target : public render_resource {
|
||||
public:
|
||||
[[nodiscard]] int get_height() const override { return height_; }
|
||||
[[nodiscard]] int get_width() const override { return width_; }
|
||||
|
||||
virtual void init(int width, int height, texture_format format) = 0;
|
||||
|
||||
virtual void resize(const int width, const int height)
|
||||
{
|
||||
virtual void resize(const int width, const int height) {
|
||||
if (width_ == width && height_ == height)
|
||||
return;
|
||||
|
||||
@ -29,13 +26,16 @@ public:
|
||||
if (on_resize_callback)
|
||||
on_resize_callback(shared_from_this());
|
||||
}
|
||||
|
||||
virtual void* lock(lock_state state) = 0;
|
||||
|
||||
virtual void *lock(lock_state state) = 0;
|
||||
|
||||
virtual void unlock() = 0;
|
||||
|
||||
std::function<void(std::shared_ptr<render_resource>)> on_resize_callback;
|
||||
|
||||
protected:
|
||||
virtual void on_resize(int width, int height) = 0;
|
||||
|
||||
int width_ = 0;
|
||||
int height_ = 0;
|
||||
};
|
||||
|
@ -5,12 +5,6 @@
|
||||
void renderer::shutdown()
|
||||
{
|
||||
default_vs_ = nullptr;
|
||||
session_ = nullptr;
|
||||
}
|
||||
|
||||
void renderer::init_slang(const std::string& shader_path)
|
||||
{
|
||||
create_slang_session(shader_path, session_.writeRef());
|
||||
}
|
||||
|
||||
std::shared_ptr<shader> renderer::get_pixel_shader_render_default_vs()
|
||||
|
@ -1,42 +1,50 @@
|
||||
#pragma once
|
||||
#include <SDL_video.h>
|
||||
|
||||
#include "imgui.h"
|
||||
#include "slang_handle.h"
|
||||
#include "GLFW/glfw3.h"
|
||||
|
||||
class pixel_shader_drawer;
|
||||
class shader;
|
||||
class render_target;
|
||||
class texture;
|
||||
constexpr ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
||||
constexpr float clear_color_with_alpha[4] = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w };
|
||||
constexpr float clear_color_with_alpha[4] = {
|
||||
clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w
|
||||
};
|
||||
|
||||
class renderer
|
||||
{
|
||||
class renderer {
|
||||
public:
|
||||
virtual ~renderer() = default;
|
||||
virtual void pre_init() {}
|
||||
virtual bool init(SDL_Window* window_handle) = 0;
|
||||
virtual void shutdown();
|
||||
virtual void post_shutdown() {}
|
||||
|
||||
void init_slang(const std::string& shader_path);
|
||||
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 void pre_init() {
|
||||
}
|
||||
|
||||
virtual bool init(GLFWwindow *window_handle) = 0;
|
||||
|
||||
virtual void shutdown();
|
||||
|
||||
virtual void post_shutdown() {
|
||||
}
|
||||
|
||||
virtual std::shared_ptr<shader> load_shader(const std::string &entry_name) = 0;
|
||||
|
||||
virtual std::shared_ptr<shader> get_pixel_shader_render_default_vs();
|
||||
|
||||
virtual std::shared_ptr<pixel_shader_drawer> create_pixel_shader_drawer() = 0;
|
||||
|
||||
virtual void new_frame(SDL_Window* window_handle) = 0;
|
||||
virtual void end_frame(SDL_Window* window_handle) = 0;
|
||||
|
||||
virtual void new_frame(GLFWwindow *window_handle) = 0;
|
||||
|
||||
virtual void end_frame(GLFWwindow *window_handle) = 0;
|
||||
|
||||
virtual void resize(int width, int height) = 0;
|
||||
virtual std::shared_ptr<texture> create_texture(const unsigned char* data, int width, int height) = 0;
|
||||
|
||||
virtual std::shared_ptr<texture> create_texture(const unsigned char *data, int width, int height) = 0;
|
||||
|
||||
virtual std::shared_ptr<render_target> create_render_target(int width, int height, texture_format format) = 0;
|
||||
|
||||
|
||||
void set_vsync(const bool vsync) { vsync_ = vsync; }
|
||||
|
||||
protected:
|
||||
Slang::ComPtr<slang::ISession> session_;
|
||||
std::shared_ptr<shader> default_vs_;
|
||||
bool vsync_ = true;
|
||||
};
|
||||
|
@ -2,59 +2,57 @@
|
||||
|
||||
class render_target;
|
||||
class texture;
|
||||
class slang_handle;
|
||||
|
||||
struct shader_draw_data
|
||||
{
|
||||
struct shader_draw_data {
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
class shader : public std::enable_shared_from_this<shader>
|
||||
{
|
||||
class shader : public std::enable_shared_from_this<shader> {
|
||||
public:
|
||||
virtual ~shader() = default;
|
||||
explicit shader(const std::shared_ptr<slang_handle>& handle) : handle_(handle) {}
|
||||
|
||||
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;
|
||||
virtual void compute(int x, int y, int z) {}
|
||||
|
||||
virtual void compute(int x, int y, int z) {
|
||||
}
|
||||
|
||||
// param setters
|
||||
virtual void set_cbuffer(const char* name, void* buffer, int size) = 0;
|
||||
virtual void set_uav_buffer(const char* name, void* buffer, int count, 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;
|
||||
virtual void set_cbuffer(const char *name, void *buffer, int size) = 0;
|
||||
|
||||
template<typename T>
|
||||
void set_cbuffer(const char* name, const T& buffer)
|
||||
{
|
||||
set_cbuffer(name, (void*)&buffer, sizeof(T));
|
||||
}
|
||||
template<typename T>
|
||||
void set_cbuffer(const char* name, const std::vector<T>& buffer)
|
||||
{
|
||||
set_cbuffer(name, (void*)buffer.data(), sizeof(T) * buffer.size());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void set_uav_buffer(const char* name, const T& buffer)
|
||||
{
|
||||
set_uav_buffer(name, (void*)&buffer, sizeof(buffer), sizeof(T));
|
||||
}
|
||||
template<typename T>
|
||||
void set_uav_buffer(const char* name, const std::vector<T>& buffer)
|
||||
{
|
||||
set_uav_buffer(name, (void*)buffer.data(), buffer.size(), sizeof(T));
|
||||
virtual void set_uav_buffer(const char *name, void *buffer, int count, int element_size) {
|
||||
}
|
||||
|
||||
void begin_draw(const shader_draw_data& in_data) { if (on_begin_draw) on_begin_draw(in_data, *this); }
|
||||
std::function<void(const shader_draw_data&, shader&)> on_begin_draw;
|
||||
protected:
|
||||
std::shared_ptr<slang_handle> handle_;
|
||||
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_cbuffer(const char *name, const T &buffer) {
|
||||
set_cbuffer(name, (void *) &buffer, sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void set_cbuffer(const char *name, const std::vector<T> &buffer) {
|
||||
set_cbuffer(name, (void *) buffer.data(), sizeof(T) * buffer.size());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void set_uav_buffer(const char *name, const T &buffer) {
|
||||
set_uav_buffer(name, (void *) &buffer, sizeof(buffer), sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void set_uav_buffer(const char *name, const std::vector<T> &buffer) {
|
||||
set_uav_buffer(name, (void *) buffer.data(), buffer.size(), sizeof(T));
|
||||
}
|
||||
|
||||
void begin_draw(const shader_draw_data &in_data) { if (on_begin_draw) on_begin_draw(in_data, *this); }
|
||||
std::function<void(const shader_draw_data &, shader &)> on_begin_draw;
|
||||
};
|
||||
|
@ -1,99 +0,0 @@
|
||||
#include "slang_handle.h"
|
||||
|
||||
#include "renderer.h"
|
||||
#include "application/application.h"
|
||||
|
||||
bool slang_handle::init_slang_module(const std::string& module_name, const std::string& entry_name)
|
||||
{
|
||||
spdlog::info("slang: init slang handle: module \"{}\", entry point \"{}\"", module_name.c_str(), entry_name.c_str());
|
||||
|
||||
const auto session = application::get()->get_renderer()->get_slang_session();
|
||||
|
||||
Slang::ComPtr<slang::IBlob> diagnostics;
|
||||
*module.writeRef() = session->loadModule(module_name.c_str(), diagnostics.writeRef());
|
||||
|
||||
if (diagnostics)
|
||||
{
|
||||
spdlog::error("slang: load module \"{}\" with diagnostics: {}", module_name.c_str(), (const char*)diagnostics->getBufferPointer());
|
||||
return false;
|
||||
}
|
||||
|
||||
auto r = module->findEntryPointByName(entry_name.c_str(), entry_point.writeRef());
|
||||
if (r != SLANG_OK)
|
||||
{
|
||||
spdlog::error("slang: can't find entry point \"{}\": {}", entry_name.c_str(), r);
|
||||
return false;
|
||||
}
|
||||
|
||||
slang::IComponentType* components[] = { module, entry_point };
|
||||
r = session->createCompositeComponentType(components, 2, program.writeRef());
|
||||
if (r != SLANG_OK)
|
||||
{
|
||||
spdlog::error("slang: create composite component type failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
slang::ProgramLayout* layout = program->getLayout(target_index);
|
||||
|
||||
// get entry point index and shader type
|
||||
for (int i = 0; i < layout->getEntryPointCount(); ++i)
|
||||
{
|
||||
const auto entry_reflection = layout->getEntryPointByIndex(i);
|
||||
if (strcmp(entry_reflection->getName(), entry_name.c_str()) == 0)
|
||||
{
|
||||
entry_point_index_ = i;
|
||||
shader_type_ = entry_reflection->getStage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if _DEBUG
|
||||
spdlog::info("slang: shader type: {}", shader_type_);
|
||||
#endif
|
||||
|
||||
spdlog::info("slang: init slang handle successfully");
|
||||
return true;
|
||||
}
|
||||
|
||||
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,
|
||||
code_blob.writeRef(),
|
||||
diagnostics.writeRef());
|
||||
|
||||
if (diagnostics)
|
||||
{
|
||||
spdlog::error("slang: get entry point code failed: {}", (const char*)diagnostics->getBufferPointer());
|
||||
return nullptr;
|
||||
}
|
||||
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;
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
#pragma once
|
||||
#include <map>
|
||||
|
||||
#include "slang-com-ptr.h"
|
||||
#include <string>
|
||||
|
||||
class slang_handle
|
||||
{
|
||||
public:
|
||||
Slang::ComPtr<slang::IModule> module;
|
||||
Slang::ComPtr<slang::IComponentType> program;
|
||||
Slang::ComPtr<slang::IEntryPoint> entry_point;
|
||||
static constexpr int target_index = 0; // only one target
|
||||
|
||||
bool init_slang_module(const std::string& module_name, const std::string& entry_name);
|
||||
[[nodiscard]] Slang::ComPtr<slang::IBlob> get_entry_point_code() const;
|
||||
[[nodiscard]] const char* get_entry_point_name() const
|
||||
{
|
||||
slang::ProgramLayout* layout = program->getLayout(0);
|
||||
const auto entry_reflection = layout->getEntryPointByIndex(entry_point_index_);
|
||||
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;
|
||||
};
|
@ -4,17 +4,18 @@
|
||||
|
||||
#include "render_resource.h"
|
||||
|
||||
class texture : public render_resource
|
||||
{
|
||||
class texture : public render_resource {
|
||||
public:
|
||||
texture(): width_(0), height_(0)
|
||||
{
|
||||
texture(): width_(0), height_(0) {
|
||||
}
|
||||
virtual bool init_data(const unsigned char* data, int width, int height) = 0;
|
||||
|
||||
virtual bool init_data(const unsigned char *data, int width, int height) = 0;
|
||||
|
||||
[[nodiscard]] virtual bool is_valid() const = 0;
|
||||
|
||||
[[nodiscard]] int get_width() const override { return width_; }
|
||||
[[nodiscard]] int get_height() const override { return height_; }
|
||||
|
||||
protected:
|
||||
int width_;
|
||||
int height_;
|
||||
|
@ -1,50 +0,0 @@
|
||||
#pragma once
|
||||
#include <d3dcompiler.h>
|
||||
|
||||
typedef HRESULT(WINAPI* pD3DReflect)
|
||||
(__in_bcount(SrcDataSize) LPCVOID pSrcData,
|
||||
__in SIZE_T SrcDataSize,
|
||||
__in REFIID pInterface,
|
||||
__out void** ppReflector);
|
||||
|
||||
#define DEFINE_GUID_FOR_CURRENT_COMPILER(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
||||
static const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
|
||||
|
||||
DEFINE_GUID_FOR_CURRENT_COMPILER(IID_ID3D11ShaderReflectionForCurrentCompiler, 0x8d536ca1, 0x0cca, 0x4956, 0xa8, 0x37, 0x78, 0x69, 0x63, 0x75, 0x55, 0x84);
|
||||
|
||||
inline HMODULE get_compiler_module()
|
||||
{
|
||||
static HMODULE compiler_dll = nullptr;
|
||||
|
||||
if (compiler_dll == nullptr)
|
||||
{
|
||||
// load the system one as the last resort
|
||||
compiler_dll = LoadLibrary(TEXT("d3dcompiler_47.dll"));
|
||||
}
|
||||
return compiler_dll;
|
||||
}
|
||||
|
||||
// @return pointer to the D3DCompile function
|
||||
inline pD3DCompile get_d3d_compile_func()
|
||||
{
|
||||
static HMODULE compiler_dll = get_compiler_module();
|
||||
|
||||
if (compiler_dll)
|
||||
{
|
||||
return static_cast<pD3DCompile>((void*)GetProcAddress(compiler_dll, "D3DCompile"));
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// @return pointer to the D3DCompile function
|
||||
inline pD3DReflect get_d3d_reflect_func()
|
||||
{
|
||||
static HMODULE CompilerDLL = get_compiler_module();
|
||||
if (CompilerDLL)
|
||||
{
|
||||
return (pD3DReflect)(void*)GetProcAddress(CompilerDLL, "D3DReflect");
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
#pragma once
|
||||
#include <dxgiformat.h>
|
||||
|
||||
#include "rhi/rhi_defintion.h"
|
||||
|
||||
inline DXGI_FORMAT to_dx_format(texture_format format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case texture_format::RGBA8:
|
||||
return DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
case texture_format::RGBA16_FLOAT:
|
||||
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;
|
||||
}
|
@ -1,298 +0,0 @@
|
||||
#include "find_best_device_dx11.h"
|
||||
|
||||
#include <delayimp.h>
|
||||
#include <cassert>
|
||||
#include <codecvt>
|
||||
|
||||
#include "spdlog/spdlog.h"
|
||||
bool is_delay_load_exception(PEXCEPTION_POINTERS ExceptionPointers)
|
||||
{
|
||||
switch (ExceptionPointers->ExceptionRecord->ExceptionCode)
|
||||
{
|
||||
case VcppException(ERROR_SEVERITY_ERROR, ERROR_MOD_NOT_FOUND):
|
||||
case VcppException(ERROR_SEVERITY_ERROR, ERROR_PROC_NOT_FOUND):
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
default:
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
}
|
||||
|
||||
const char* get_feature_level_string(D3D_FEATURE_LEVEL feature_level)
|
||||
{
|
||||
switch (feature_level)
|
||||
{
|
||||
case D3D_FEATURE_LEVEL_9_1: return "9_1";
|
||||
case D3D_FEATURE_LEVEL_9_2: return "9_2";
|
||||
case D3D_FEATURE_LEVEL_9_3: return "9_3";
|
||||
case D3D_FEATURE_LEVEL_10_0: return "10_0";
|
||||
case D3D_FEATURE_LEVEL_10_1: return "10_1";
|
||||
case D3D_FEATURE_LEVEL_11_0: return "11_0";
|
||||
case D3D_FEATURE_LEVEL_11_1: return "11_1";
|
||||
case D3D_FEATURE_LEVEL_12_0: return "12_0";
|
||||
case D3D_FEATURE_LEVEL_12_1: return "12_1";
|
||||
case D3D_FEATURE_LEVEL_12_2: return "12_2";
|
||||
case D3D_FEATURE_LEVEL_1_0_CORE: return "1_0_CORE";
|
||||
}
|
||||
return "X_X";
|
||||
}
|
||||
find_best_device_dx11::find_best_device_dx11()
|
||||
{
|
||||
chosen_feature_level_ = D3D_FEATURE_LEVEL_1_0_CORE;
|
||||
gpu_preference_ = DXGI_GPU_PREFERENCE_UNSPECIFIED;
|
||||
load_settings();
|
||||
select_adapter();
|
||||
}
|
||||
|
||||
find_best_device_dx11::~find_best_device_dx11()
|
||||
{
|
||||
chosen_adapter_.safe_release();
|
||||
dxgi_factory1_.safe_release();
|
||||
dxgi_factory6_.safe_release();
|
||||
}
|
||||
|
||||
bool find_best_device_dx11::is_valid() const
|
||||
{
|
||||
return chosen_adapter_.is_valid() && chosen_feature_level_ != D3D_FEATURE_LEVEL_1_0_CORE;
|
||||
}
|
||||
|
||||
bool find_best_device_dx11::create_device(HWND in_hwnd, ID3D11Device** out_device, ID3D11DeviceContext** out_device_context, IDXGISwapChain** out_swap_chain)
|
||||
{
|
||||
if (!is_valid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int device_flags = D3D11_CREATE_DEVICE_SINGLETHREADED;
|
||||
if (debug_)
|
||||
{
|
||||
device_flags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||
}
|
||||
|
||||
// Setup swap chain
|
||||
DXGI_SWAP_CHAIN_DESC sd;
|
||||
ZeroMemory(&sd, sizeof(sd));
|
||||
sd.BufferCount = 2;
|
||||
sd.BufferDesc.Width = 0;
|
||||
sd.BufferDesc.Height = 0;
|
||||
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
sd.BufferDesc.RefreshRate.Numerator = 60;
|
||||
sd.BufferDesc.RefreshRate.Denominator = 1;
|
||||
sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
|
||||
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
sd.OutputWindow = in_hwnd;
|
||||
sd.SampleDesc.Count = 1;
|
||||
sd.SampleDesc.Quality = 0;
|
||||
sd.Windowed = TRUE;
|
||||
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
|
||||
D3D_FEATURE_LEVEL created_feature_level = D3D_FEATURE_LEVEL_1_0_CORE;
|
||||
|
||||
HRESULT hr = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, device_flags, &chosen_feature_level_, 1, D3D11_SDK_VERSION, &sd, out_swap_chain, out_device, &created_feature_level, out_device_context);
|
||||
if (hr == DXGI_ERROR_UNSUPPORTED) // Try high-performance WARP software driver if hardware is not available.
|
||||
hr = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_WARP, nullptr, device_flags, &chosen_feature_level_, 1, D3D11_SDK_VERSION, &sd, out_swap_chain, out_device, &created_feature_level, out_device_context);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
spdlog::error("Failed to create D3D11 device.");
|
||||
}
|
||||
assert(created_feature_level == chosen_feature_level_);
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
void find_best_device_dx11::load_settings()
|
||||
{
|
||||
explicit_adapter_value_ = 0;
|
||||
prefered_adapter_vendor_ = 0;
|
||||
allow_software_rendering_ = true;
|
||||
prefered_minimal_power_ = false;
|
||||
prefered_high_performance_ = true;
|
||||
debug_ = false;
|
||||
|
||||
CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&dxgi_factory1_);
|
||||
if (dxgi_factory1_)
|
||||
{
|
||||
dxgi_factory1_->QueryInterface(__uuidof(IDXGIFactory6), (void**)&dxgi_factory6_);
|
||||
}
|
||||
|
||||
if (prefered_minimal_power_)
|
||||
{
|
||||
gpu_preference_ = DXGI_GPU_PREFERENCE_MINIMUM_POWER;
|
||||
}
|
||||
else
|
||||
{
|
||||
gpu_preference_ = DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE;
|
||||
}
|
||||
}
|
||||
|
||||
void find_best_device_dx11::select_adapter()
|
||||
{
|
||||
ref_count_ptr<IDXGIAdapter> first_dxgi_adapter_without_integrated_adapter;
|
||||
ref_count_ptr<IDXGIAdapter> first_dxgi_adapter_adapter;
|
||||
D3D_FEATURE_LEVEL first_feature_level_without_integrated_adapter = D3D_FEATURE_LEVEL_1_0_CORE;
|
||||
D3D_FEATURE_LEVEL first_feature_leve_adapter = D3D_FEATURE_LEVEL_1_0_CORE;
|
||||
|
||||
spdlog::info("Selecting D3D11 adapter.");
|
||||
|
||||
// Enumerate the DXGIFactory's adapters.
|
||||
ref_count_ptr<IDXGIAdapter> testing_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))
|
||||
{
|
||||
spdlog::warn("Failed to get description for adapter {}.", adapter_index);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
|
||||
std::string str = conv.to_bytes(adapter_desc.Description);
|
||||
spdlog::info("Testing D3D11 adapter: {}. Description: '{}'. VendorId: {:04x}. DeviceId: {:04x}.", adapter_index, str.c_str(), adapter_desc.VendorId, adapter_desc.DeviceId);
|
||||
}
|
||||
|
||||
D3D_FEATURE_LEVEL feature_level;
|
||||
if (!create_testing_device(testing_adapter, feature_level))
|
||||
{
|
||||
spdlog::info("Failed to create test device for adapter {}.", adapter_index);
|
||||
continue;
|
||||
}
|
||||
|
||||
{
|
||||
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
|
||||
std::string str = conv.to_bytes(adapter_desc.Description);
|
||||
spdlog::info(" {}. '{}'. Feature level: {}.", adapter_index, str.c_str(), get_feature_level_string(feature_level));
|
||||
}
|
||||
const bool is_microsoft = adapter_desc.VendorId == 0x1414;
|
||||
const bool is_software = is_microsoft;
|
||||
const bool skip_software_adapter = is_software && !allow_software_rendering_ && explicit_adapter_value_ < 0;
|
||||
const bool skip_explicit_adapter = explicit_adapter_value_ >= 0 && adapter_index != explicit_adapter_value_;
|
||||
const bool skip_adapter = skip_software_adapter || skip_explicit_adapter;
|
||||
|
||||
if (skip_adapter)
|
||||
{
|
||||
spdlog::info(" Skip adapter.");
|
||||
continue;
|
||||
}
|
||||
|
||||
bool is_non_local_memory_present = false;
|
||||
{
|
||||
ref_count_ptr<IDXGIAdapter3> temp_dxgi_adapter3;
|
||||
DXGI_QUERY_VIDEO_MEMORY_INFO non_local_video_memory_info;
|
||||
if (SUCCEEDED(testing_adapter->QueryInterface(_uuidof(IDXGIAdapter3), (void**)temp_dxgi_adapter3.get_init_reference())) &&
|
||||
temp_dxgi_adapter3.is_valid() && SUCCEEDED(temp_dxgi_adapter3->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, &non_local_video_memory_info)))
|
||||
{
|
||||
is_non_local_memory_present = non_local_video_memory_info.Budget != 0;
|
||||
}
|
||||
}
|
||||
const bool is_integrated = !is_non_local_memory_present;
|
||||
|
||||
if (!is_integrated && !first_dxgi_adapter_without_integrated_adapter.is_valid())
|
||||
{
|
||||
first_dxgi_adapter_without_integrated_adapter = testing_adapter;
|
||||
first_feature_level_without_integrated_adapter = feature_level;
|
||||
}
|
||||
else if (prefered_adapter_vendor_ == adapter_desc.VendorId && first_dxgi_adapter_without_integrated_adapter.is_valid())
|
||||
{
|
||||
first_dxgi_adapter_without_integrated_adapter = testing_adapter;
|
||||
first_feature_level_without_integrated_adapter = feature_level;
|
||||
}
|
||||
|
||||
if (!first_dxgi_adapter_adapter.is_valid())
|
||||
{
|
||||
first_dxgi_adapter_adapter = testing_adapter;
|
||||
first_feature_leve_adapter = feature_level;
|
||||
}
|
||||
else if (prefered_adapter_vendor_ == adapter_desc.VendorId && first_dxgi_adapter_adapter.is_valid())
|
||||
{
|
||||
first_dxgi_adapter_adapter = testing_adapter;
|
||||
first_feature_leve_adapter = feature_level;
|
||||
}
|
||||
}
|
||||
|
||||
const bool bFavorNonIntegrated = explicit_adapter_value_ == -1;
|
||||
if (bFavorNonIntegrated)
|
||||
{
|
||||
chosen_adapter_ = first_dxgi_adapter_without_integrated_adapter;
|
||||
chosen_feature_level_ = first_feature_level_without_integrated_adapter;
|
||||
|
||||
// We assume Intel is integrated graphics (slower than discrete) than NVIDIA or AMD cards and rather take a different one
|
||||
if (!chosen_adapter_.is_valid())
|
||||
{
|
||||
chosen_adapter_ = first_dxgi_adapter_adapter;
|
||||
chosen_feature_level_ = first_feature_leve_adapter;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
chosen_adapter_ = first_dxgi_adapter_adapter;
|
||||
chosen_feature_level_ = first_feature_leve_adapter;
|
||||
}
|
||||
|
||||
if (chosen_adapter_.is_valid())
|
||||
{
|
||||
DXGI_ADAPTER_DESC adapter_desc;
|
||||
const HRESULT desc_result = chosen_adapter_->GetDesc(&adapter_desc);
|
||||
if (FAILED(desc_result))
|
||||
{
|
||||
spdlog::warn("Failed to get description for selected adapter.");
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
|
||||
std::string str = conv.to_bytes(adapter_desc.Description);
|
||||
spdlog::info("Selected D3D11 adapter: {}. VendorId: {:04x}. DeviceId: {:04x}.", str.c_str(), adapter_desc.VendorId, adapter_desc.DeviceId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT find_best_device_dx11::enumerate_adapters(UINT adapter_index, IDXGIAdapter** out_adapter)
|
||||
{
|
||||
if (!dxgi_factory6_ || gpu_preference_ == DXGI_GPU_PREFERENCE_UNSPECIFIED)
|
||||
{
|
||||
return dxgi_factory1_->EnumAdapters(adapter_index, out_adapter);
|
||||
}
|
||||
else
|
||||
{
|
||||
return dxgi_factory6_->EnumAdapterByGpuPreference(adapter_index, (DXGI_GPU_PREFERENCE)gpu_preference_, __uuidof(IDXGIAdapter), (void**)out_adapter);
|
||||
}
|
||||
}
|
||||
|
||||
bool find_best_device_dx11::create_testing_device(IDXGIAdapter* adapter, D3D_FEATURE_LEVEL& out_feature_level)
|
||||
{
|
||||
ID3D11Device* D3DDevice = nullptr;
|
||||
ID3D11DeviceContext* D3DDeviceContext = nullptr;
|
||||
|
||||
unsigned int DeviceFlags = D3D11_CREATE_DEVICE_SINGLETHREADED;
|
||||
if (debug_)
|
||||
{
|
||||
DeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||
}
|
||||
|
||||
constexpr D3D_FEATURE_LEVEL requested_feature_levels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0 };
|
||||
|
||||
out_feature_level = D3D_FEATURE_LEVEL_1_0_CORE;
|
||||
__try
|
||||
{
|
||||
constexpr int num_allowed_feature_levels = 2;
|
||||
const HRESULT create_device_result = D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, DeviceFlags,
|
||||
requested_feature_levels, num_allowed_feature_levels, D3D11_SDK_VERSION,
|
||||
&D3DDevice, &out_feature_level, &D3DDeviceContext);
|
||||
if (SUCCEEDED(create_device_result))
|
||||
{
|
||||
D3DDevice->Release();
|
||||
D3DDeviceContext->Release();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
__except (is_delay_load_exception(GetExceptionInformation()))
|
||||
{
|
||||
// We suppress warning C6322: Empty _except block. Appropriate checks are made upon returning.
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
#pragma once
|
||||
#include <d3d11.h>
|
||||
#include "misc/ref_counting.h"
|
||||
#include <dxgi1_6.h>
|
||||
|
||||
struct IDXGIAdapter;
|
||||
struct IDXGIFactory1;
|
||||
struct IDXGIFactory6;
|
||||
|
||||
class find_best_device_dx11
|
||||
{
|
||||
public:
|
||||
find_best_device_dx11();
|
||||
~find_best_device_dx11();
|
||||
|
||||
bool is_valid() const;
|
||||
bool create_device(HWND in_hwnd, ID3D11Device** out_device, ID3D11DeviceContext** out_device_context, IDXGISwapChain** out_swap_chain);
|
||||
|
||||
private:
|
||||
void load_settings();
|
||||
void select_adapter();
|
||||
|
||||
HRESULT enumerate_adapters(UINT adapter_index, IDXGIAdapter** out_adapter);
|
||||
bool create_testing_device(IDXGIAdapter* adapter, D3D_FEATURE_LEVEL& out_feature_level);
|
||||
private:
|
||||
ref_count_ptr<IDXGIAdapter> chosen_adapter_;
|
||||
ref_count_ptr<IDXGIFactory1> dxgi_factory1_;
|
||||
ref_count_ptr<IDXGIFactory6> dxgi_factory6_;
|
||||
D3D_FEATURE_LEVEL chosen_feature_level_;
|
||||
int gpu_preference_;
|
||||
int explicit_adapter_value_;
|
||||
unsigned int prefered_adapter_vendor_;
|
||||
bool allow_software_rendering_;
|
||||
bool prefered_minimal_power_;
|
||||
bool prefered_high_performance_;
|
||||
bool debug_;
|
||||
};
|
@ -1,156 +0,0 @@
|
||||
#include "pixel_shader_drawer_dx11.h"
|
||||
|
||||
#include "renderer_dx11.h"
|
||||
#include "render_target_dx11.h"
|
||||
#include "application/application.h"
|
||||
#include "shader/shader_ps_dx11.h"
|
||||
|
||||
void ps_dx11_compute_callback(const ImDrawList* parent_list, const ImDrawCmd* cmd)
|
||||
{
|
||||
pixel_shader_drawer_dx11* data = static_cast<pixel_shader_drawer_dx11*>(cmd->UserCallbackData);
|
||||
auto& ps = data->pixel_shader;
|
||||
const auto& vertex_buffer = data->vertex_buffer;
|
||||
const auto& render_target = data->render_target;
|
||||
const auto& index_buffer = data->index_buffer;
|
||||
const auto vertex_shader = data->vertex_shader.lock();
|
||||
const int width = render_target->get_width();
|
||||
const int height = render_target->get_height();
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE vtx_resource;
|
||||
ID3D11Buffer* vb = vertex_buffer;
|
||||
if (g_d3d11_device_context->Map(vb, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK)
|
||||
return;
|
||||
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData;
|
||||
vtx_dst[0].pos = ImVec2(0, 0);
|
||||
vtx_dst[0].uv = ImVec2(0, 0);
|
||||
vtx_dst[0].col = 0xffffffff;
|
||||
|
||||
vtx_dst[1].pos = ImVec2(width, 0);
|
||||
vtx_dst[1].uv = ImVec2(1, 0);
|
||||
vtx_dst[1].col = 0xffffffff;
|
||||
|
||||
vtx_dst[2].pos = ImVec2(width, height);
|
||||
vtx_dst[2].uv = ImVec2(1, 1);
|
||||
vtx_dst[2].col = 0xffffffff;
|
||||
|
||||
vtx_dst[3].pos = ImVec2(0, height);
|
||||
vtx_dst[3].uv = ImVec2(0, 1);
|
||||
vtx_dst[3].col = 0xffffffff;
|
||||
g_d3d11_device_context->Unmap(vb, 0);
|
||||
|
||||
const auto target_rtv = render_target->get_render_target_view().get_reference();
|
||||
g_d3d11_device_context->OMSetRenderTargets(1, &target_rtv, nullptr);
|
||||
|
||||
g_d3d11_device_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
|
||||
D3D11_VIEWPORT vp = {};
|
||||
vp.Width = width;
|
||||
vp.Height = height;
|
||||
vp.MinDepth = 0.0f;
|
||||
vp.MaxDepth = 1.0f;
|
||||
vp.TopLeftX = vp.TopLeftY = 0;
|
||||
g_d3d11_device_context->RSSetViewports(1, &vp);
|
||||
|
||||
vertex_shader->bind();
|
||||
|
||||
const unsigned int stride = sizeof(ImDrawVert);
|
||||
const unsigned int offset = 0;
|
||||
g_d3d11_device_context->IASetVertexBuffers(0, 1, &vb, &stride, &offset);
|
||||
g_d3d11_device_context->IASetIndexBuffer(index_buffer, DXGI_FORMAT_R16_UINT, 0);
|
||||
|
||||
// setup new scissors
|
||||
D3D11_RECT new_scissors;
|
||||
new_scissors.left = 0;
|
||||
new_scissors.right = width;
|
||||
new_scissors.top = 0;
|
||||
new_scissors.bottom = height;
|
||||
g_d3d11_device_context->RSSetScissorRects(1, &new_scissors);
|
||||
|
||||
ps.lock()->bind();
|
||||
g_d3d11_device_context->DrawIndexed(6, 0, 0);
|
||||
vertex_shader->unbind();
|
||||
ps.lock()->unbind();
|
||||
|
||||
ID3D11RenderTargetView* main_render_target = g_main_render_target_view.get_reference();
|
||||
g_d3d11_device_context->OMSetRenderTargets(1, &main_render_target, nullptr);
|
||||
}
|
||||
|
||||
void pixel_shader_drawer_dx11::init(int width, int height, std::shared_ptr<shader> in_pixel_shader,
|
||||
std::shared_ptr<shader> in_vertex_shader)
|
||||
{
|
||||
if (!in_vertex_shader)
|
||||
{
|
||||
in_vertex_shader = application::get()->get_renderer()->get_pixel_shader_render_default_vs();
|
||||
}
|
||||
vertex_shader = in_vertex_shader;
|
||||
pixel_shader = in_pixel_shader;
|
||||
|
||||
render_target = std::static_pointer_cast<render_target_dx11>(application::get()->create_render_target(width, height, texture_format::RGBA8));
|
||||
|
||||
{
|
||||
D3D11_BUFFER_DESC desc = {};
|
||||
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
desc.ByteWidth = sizeof(ImDrawVert) * 4;
|
||||
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
g_d3d11_device->CreateBuffer(&desc, nullptr, vertex_buffer.get_init_reference());
|
||||
}
|
||||
{
|
||||
D3D11_BUFFER_DESC desc = {};
|
||||
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
desc.ByteWidth = sizeof(ImDrawIdx) * 6;
|
||||
desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
g_d3d11_device->CreateBuffer(&desc, nullptr, index_buffer.get_init_reference());
|
||||
|
||||
// init index buffer
|
||||
const ImDrawIdx indices[] = { 0, 1, 2, 0, 2, 3 };
|
||||
D3D11_MAPPED_SUBRESOURCE index_resource;
|
||||
g_d3d11_device_context->Map(index_buffer.get_reference(), 0, D3D11_MAP_WRITE_DISCARD, 0, &index_resource);
|
||||
memcpy(index_resource.pData, indices, sizeof(indices));
|
||||
g_d3d11_device_context->Unmap(index_buffer.get_reference(), 0);
|
||||
}
|
||||
|
||||
update_view_matrix(width, height);
|
||||
}
|
||||
|
||||
void pixel_shader_drawer_dx11::set_vertex_shader(std::shared_ptr<shader> in_vertex_shader)
|
||||
{
|
||||
vertex_shader = in_vertex_shader;
|
||||
}
|
||||
|
||||
void pixel_shader_drawer_dx11::draw()
|
||||
{
|
||||
#if _DEBUG
|
||||
assert(!(vertex_shader.expired() || pixel_shader.expired()));
|
||||
#endif
|
||||
ImGui::GetWindowDrawList()->AddCallback(ps_dx11_compute_callback, this);
|
||||
ImGui::GetWindowDrawList()->AddCallback(ImDrawCallback_ResetRenderState, nullptr);
|
||||
render_target->draw();
|
||||
}
|
||||
|
||||
void pixel_shader_drawer_dx11::resize(int width, int height)
|
||||
{
|
||||
render_target->resize(width, height);
|
||||
update_view_matrix(width, height);
|
||||
}
|
||||
|
||||
void pixel_shader_drawer_dx11::update_view_matrix(int width, int height) const
|
||||
{
|
||||
#if _DEBUG
|
||||
assert(!(vertex_shader.expired()));
|
||||
#endif
|
||||
const float L = 0;
|
||||
const float R = width;
|
||||
const float T = 0;
|
||||
const float B = height;
|
||||
|
||||
float mvp[4][4] =
|
||||
{
|
||||
{ 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 },
|
||||
};
|
||||
vertex_shader.lock()->set_cbuffer("viewMatrix", mvp, sizeof(mvp));
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
#pragma once
|
||||
#include "misc/ref_counting.h"
|
||||
#include "rhi/pixel_shader_drawer.h"
|
||||
#include <d3d11.h>
|
||||
|
||||
class render_target_dx11;
|
||||
|
||||
class pixel_shader_drawer_dx11 : public pixel_shader_drawer
|
||||
{
|
||||
public:
|
||||
void init(int width, int height, std::shared_ptr<shader> in_pixel_shader, std::shared_ptr<shader> in_vertex_shader) override;
|
||||
void set_vertex_shader(std::shared_ptr<shader> in_vertex_shader) override;
|
||||
void draw() override;
|
||||
void resize(int width, int height) override;
|
||||
|
||||
std::weak_ptr<shader> pixel_shader;
|
||||
std::weak_ptr<shader> vertex_shader;
|
||||
std::shared_ptr<render_target_dx11> render_target;
|
||||
ref_count_ptr<ID3D11Buffer> vertex_buffer;
|
||||
ref_count_ptr<ID3D11Buffer> index_buffer;
|
||||
protected:
|
||||
void update_view_matrix(int width, int height) const;
|
||||
};
|
@ -1,179 +0,0 @@
|
||||
#include "render_target_dx11.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "dx_format.h"
|
||||
#include "renderer_dx11.h"
|
||||
#include "shader/uav_buffer_dx11.h"
|
||||
|
||||
render_target_dx11::render_target_dx11() : lock_state_(lock_state::NONE)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void render_target_dx11::init(int width, int height, texture_format format)
|
||||
{
|
||||
width_ = width;
|
||||
height_ = height;
|
||||
|
||||
D3D11_TEXTURE2D_DESC texture_desc;
|
||||
texture_desc.Width = width;
|
||||
texture_desc.Height = height;
|
||||
texture_desc.MipLevels = 1;
|
||||
texture_desc.ArraySize = 1;
|
||||
texture_desc.Format = to_dx_format(format);
|
||||
texture_desc.SampleDesc.Count = 1;
|
||||
texture_desc.SampleDesc.Quality = 0;
|
||||
texture_desc.Usage = D3D11_USAGE_DEFAULT;
|
||||
texture_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
|
||||
texture_desc.CPUAccessFlags = 0;
|
||||
texture_desc.MiscFlags = 0;
|
||||
|
||||
HRESULT hr = g_d3d11_device->CreateTexture2D(&texture_desc, nullptr, texture_.get_init_reference());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
|
||||
D3D11_RENDER_TARGET_VIEW_DESC rtv_desc;
|
||||
rtv_desc.Format = texture_desc.Format;
|
||||
rtv_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
|
||||
rtv_desc.Texture2D.MipSlice = 0;
|
||||
hr = g_d3d11_device->CreateRenderTargetView(texture_, &rtv_desc, render_target_view_.get_init_reference());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc;
|
||||
srv_desc.Format = texture_desc.Format;
|
||||
srv_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
srv_desc.Texture2D.MipLevels = -1;
|
||||
srv_desc.Texture2D.MostDetailedMip = 0;
|
||||
hr = g_d3d11_device->CreateShaderResourceView(texture_, &srv_desc, shader_resource_view_.get_init_reference());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void* render_target_dx11::lock(lock_state state)
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC texture_desc;
|
||||
texture_->GetDesc(&texture_desc);
|
||||
texture_desc.BindFlags = 0;
|
||||
texture_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
|
||||
texture_desc.Usage = D3D11_USAGE_STAGING;
|
||||
|
||||
HRESULT hr = g_d3d11_device->CreateTexture2D(&texture_desc, nullptr, lock_texture_.get_init_reference());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
assert(false);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
D3D11_MAP map_type;
|
||||
lock_state_ = state;
|
||||
switch (state)
|
||||
{
|
||||
case lock_state::NONE:
|
||||
map_type = D3D11_MAP_READ_WRITE;
|
||||
break;
|
||||
case lock_state::READ:
|
||||
map_type = D3D11_MAP_READ;
|
||||
g_d3d11_device_context->CopyResource(lock_texture_, texture_);
|
||||
break;
|
||||
case lock_state::WRITE:
|
||||
map_type = D3D11_MAP_WRITE;
|
||||
break;
|
||||
case lock_state::READ_WRITE:
|
||||
map_type = D3D11_MAP_READ_WRITE;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE mapped_resource;
|
||||
hr = g_d3d11_device_context->Map(lock_texture_, 0, map_type, 0, &mapped_resource);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
assert(false);
|
||||
return nullptr;
|
||||
}
|
||||
return mapped_resource.pData;
|
||||
}
|
||||
|
||||
void render_target_dx11::unlock()
|
||||
{
|
||||
switch (lock_state_)
|
||||
{
|
||||
case lock_state::READ:
|
||||
break;
|
||||
case lock_state::NONE:
|
||||
case lock_state::WRITE:
|
||||
case lock_state::READ_WRITE:
|
||||
{
|
||||
g_d3d11_device_context->Unmap(lock_texture_, 0);
|
||||
g_d3d11_device_context->CopyResource(texture_, lock_texture_);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
lock_state_ = lock_state::NONE;
|
||||
lock_texture_.safe_release();
|
||||
}
|
||||
|
||||
void render_target_dx11::release()
|
||||
{
|
||||
assert(!lock_texture_);
|
||||
texture_.safe_release();
|
||||
render_target_view_.safe_release();
|
||||
shader_resource_view_.safe_release();
|
||||
}
|
||||
|
||||
void render_target_dx11::on_resize(int width, int height)
|
||||
{
|
||||
width_ = width;
|
||||
height_ = height;
|
||||
|
||||
D3D11_TEXTURE2D_DESC texture_desc;
|
||||
texture_->GetDesc(&texture_desc);
|
||||
texture_desc.Width = width;
|
||||
texture_desc.Height = height;
|
||||
|
||||
release();
|
||||
|
||||
HRESULT hr = g_d3d11_device->CreateTexture2D(&texture_desc, nullptr, texture_.get_init_reference());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
|
||||
D3D11_RENDER_TARGET_VIEW_DESC rtv_desc;
|
||||
rtv_desc.Format = texture_desc.Format;
|
||||
rtv_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
|
||||
rtv_desc.Texture2D.MipSlice = 0;
|
||||
hr = g_d3d11_device->CreateRenderTargetView(texture_, &rtv_desc, render_target_view_.get_init_reference());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc;
|
||||
srv_desc.Format = texture_desc.Format;
|
||||
srv_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
srv_desc.Texture2D.MipLevels = -1;
|
||||
srv_desc.Texture2D.MostDetailedMip = 0;
|
||||
hr = g_d3d11_device->CreateShaderResourceView(texture_, &srv_desc, shader_resource_view_.get_init_reference());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
#pragma once
|
||||
#include "rhi/render_target.h"
|
||||
#include <d3d11.h>
|
||||
|
||||
#include "misc/ref_counting.h"
|
||||
|
||||
class uav_buffer_dx11;
|
||||
|
||||
class render_target_dx11 : public render_target
|
||||
{
|
||||
public:
|
||||
render_target_dx11();
|
||||
~render_target_dx11() override = default;
|
||||
|
||||
void init(int width, int height, texture_format format) override;
|
||||
|
||||
ImTextureID get_texture_id() override { return shader_resource_view_; }
|
||||
ref_count_ptr<ID3D11Texture2D> get_texture() { return texture_; }
|
||||
ref_count_ptr<ID3D11RenderTargetView> get_render_target_view() { return render_target_view_; }
|
||||
ref_count_ptr<ID3D11ShaderResourceView> get_srv() { return shader_resource_view_; }
|
||||
|
||||
void* lock(lock_state state) override;
|
||||
void unlock() override;
|
||||
|
||||
void release();
|
||||
|
||||
int binding_point = -1;
|
||||
protected:
|
||||
void on_resize(int width, int height) override;
|
||||
private:
|
||||
ref_count_ptr<ID3D11Texture2D> lock_texture_;
|
||||
ref_count_ptr<ID3D11Texture2D> texture_;
|
||||
ref_count_ptr<ID3D11RenderTargetView> render_target_view_;
|
||||
ref_count_ptr<ID3D11ShaderResourceView> shader_resource_view_;
|
||||
|
||||
lock_state lock_state_;
|
||||
};
|
@ -1,198 +0,0 @@
|
||||
#include "renderer_dx11.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "find_best_device_dx11.h"
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_dx11.h"
|
||||
#include "imgui_impl_sdl3.h"
|
||||
#include "pixel_shader_drawer_dx11.h"
|
||||
#include "render_target_dx11.h"
|
||||
#include "texture_dx11.h"
|
||||
#include "application/application.h"
|
||||
#include "shader/shader_cs_dx11.h"
|
||||
#include "shader/shader_ds_dx11.h"
|
||||
#include "shader/shader_gs_dx11.h"
|
||||
#include "shader/shader_hs_dx11.h"
|
||||
#include "shader/shader_ps_dx11.h"
|
||||
#include "shader/shader_vs_dx11.h"
|
||||
|
||||
ref_count_ptr<ID3D11Device> g_d3d11_device;
|
||||
ref_count_ptr<ID3D11DeviceContext> g_d3d11_device_context;
|
||||
ref_count_ptr<IDXGISwapChain> g_d3d11_swap_chain;
|
||||
ref_count_ptr<ID3D11RenderTargetView> g_main_render_target_view;
|
||||
|
||||
|
||||
renderer_dx11::renderer_dx11()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool renderer_dx11::init(SDL_Window* window_handle)
|
||||
{
|
||||
if (has_initialized_)
|
||||
return true;
|
||||
|
||||
const HWND hwnd = static_cast<HWND>(SDL_GetProperty(SDL_GetWindowProperties(window_handle), SDL_PROP_WINDOW_WIN32_HWND_POINTER, nullptr));
|
||||
if (!create_device(hwnd))
|
||||
return false;
|
||||
|
||||
ImGui_ImplSDL3_InitForD3D(window_handle);
|
||||
ImGui_ImplDX11_Init(g_d3d11_device, g_d3d11_device_context);
|
||||
|
||||
create_render_target();
|
||||
|
||||
has_initialized_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void renderer_dx11::shutdown()
|
||||
{
|
||||
renderer::shutdown();
|
||||
// Cleanup
|
||||
ImGui_ImplDX11_Shutdown();
|
||||
ImGui_ImplSDL3_Shutdown();
|
||||
|
||||
g_d3d11_device.safe_release();
|
||||
g_d3d11_device_context.safe_release();
|
||||
g_d3d11_swap_chain.safe_release();
|
||||
}
|
||||
|
||||
void renderer_dx11::create_slang_session(const std::string& shader_path, slang::ISession** out_session)
|
||||
{
|
||||
slang::TargetDesc target_desc;
|
||||
target_desc.format = SLANG_HLSL;
|
||||
target_desc.profile = g_slang_global_session->findProfile("sm_5_1");
|
||||
|
||||
const char* search_paths[] = { shader_path.c_str() };
|
||||
slang::SessionDesc session_desc;
|
||||
session_desc.searchPaths = search_paths;
|
||||
session_desc.searchPathCount = 1;
|
||||
session_desc.targets = &target_desc;
|
||||
session_desc.targetCount = 1;
|
||||
session_desc.defaultMatrixLayoutMode = SLANG_MATRIX_LAYOUT_COLUMN_MAJOR;
|
||||
|
||||
g_slang_global_session->createSession(session_desc, out_session);
|
||||
}
|
||||
|
||||
std::shared_ptr<shader> renderer_dx11::load_shader(const std::string& entry_name)
|
||||
{
|
||||
auto handle = std::make_shared<slang_handle>();
|
||||
if (!handle->init_slang_module(application::get()->get_entry_model(), entry_name))
|
||||
return nullptr;
|
||||
|
||||
const auto shader_type = handle->get_shader_type();
|
||||
std::shared_ptr<shader> out;
|
||||
switch (shader_type)
|
||||
{
|
||||
case SLANG_STAGE_VERTEX:
|
||||
{
|
||||
out = std::make_shared<shader_vs_dx11>(handle);
|
||||
}
|
||||
break;
|
||||
case SLANG_STAGE_HULL:
|
||||
{
|
||||
out = std::make_shared<shader_hs_dx11>(handle);
|
||||
}
|
||||
break;
|
||||
case SLANG_STAGE_DOMAIN:
|
||||
{
|
||||
out = std::make_shared<shader_ds_dx11>(handle);
|
||||
}
|
||||
break;
|
||||
case SLANG_STAGE_GEOMETRY:
|
||||
{
|
||||
out = std::make_shared<shader_gs_dx11>(handle);
|
||||
}
|
||||
break;
|
||||
case SLANG_STAGE_PIXEL:
|
||||
{
|
||||
out = std::make_shared<shader_ps_dx11>(handle);
|
||||
}
|
||||
break;
|
||||
case SLANG_STAGE_COMPUTE:
|
||||
{
|
||||
out = std::make_shared<shader_cs_dx11>(handle);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
spdlog::error("slang: unsupported shader type");
|
||||
return nullptr;
|
||||
}
|
||||
if (!out->init())
|
||||
return nullptr;
|
||||
return out;
|
||||
}
|
||||
|
||||
std::shared_ptr<pixel_shader_drawer> renderer_dx11::create_pixel_shader_drawer()
|
||||
{
|
||||
return std::make_shared<pixel_shader_drawer_dx11>();
|
||||
}
|
||||
|
||||
void renderer_dx11::new_frame(SDL_Window* window_handle)
|
||||
{
|
||||
ImGui_ImplDX11_NewFrame();
|
||||
ImGui_ImplSDL3_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
}
|
||||
|
||||
void renderer_dx11::end_frame(SDL_Window* window_handle)
|
||||
{
|
||||
|
||||
ImGui::Render();
|
||||
|
||||
ID3D11RenderTargetView* target_view = g_main_render_target_view.get_reference();
|
||||
g_d3d11_device_context->OMSetRenderTargets(1, &target_view, nullptr);
|
||||
g_d3d11_device_context->ClearRenderTargetView(g_main_render_target_view, clear_color_with_alpha);
|
||||
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
(void)g_d3d11_swap_chain->Present(vsync_, 0); // Present with vsync
|
||||
}
|
||||
|
||||
void renderer_dx11::resize(int width, int height)
|
||||
{
|
||||
g_main_render_target_view.safe_release();
|
||||
(void)g_d3d11_swap_chain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
|
||||
create_render_target();
|
||||
}
|
||||
|
||||
std::shared_ptr<texture> renderer_dx11::create_texture(const unsigned char* data, const int width, const int height)
|
||||
{
|
||||
auto out = std::make_shared<texture_dx11>();
|
||||
if (!out->init_data(data, width, height))
|
||||
{
|
||||
out = nullptr;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
std::shared_ptr<render_target> renderer_dx11::create_render_target(int width, int height, texture_format format)
|
||||
{
|
||||
const auto target_dx11 = std::make_shared<render_target_dx11>();
|
||||
target_dx11->init(width, height, format);
|
||||
return target_dx11;
|
||||
}
|
||||
|
||||
void renderer_dx11::create_render_target()
|
||||
{
|
||||
ref_count_ptr<ID3D11Texture2D> p_back_buffer;
|
||||
(void)g_d3d11_swap_chain->GetBuffer(0, IID_PPV_ARGS(p_back_buffer.get_init_reference()));
|
||||
(void)g_d3d11_device->CreateRenderTargetView(p_back_buffer, nullptr, g_main_render_target_view.get_init_reference());
|
||||
p_back_buffer.safe_release();
|
||||
}
|
||||
|
||||
bool renderer_dx11::create_device(HWND in_hwnd)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
if(!g_d3d11_device.is_valid() || !g_d3d11_device_context.is_valid())
|
||||
{
|
||||
find_best_device_dx11 best_device_finder = find_best_device_dx11();
|
||||
if (best_device_finder.is_valid())
|
||||
{
|
||||
result = best_device_finder.create_device(in_hwnd, g_d3d11_device.get_init_reference(), g_d3d11_device_context.get_init_reference(), g_d3d11_swap_chain.get_init_reference());
|
||||
}
|
||||
}
|
||||
assert(result);
|
||||
return result;
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
#pragma once
|
||||
#include <d3d11.h>
|
||||
|
||||
#include "misc/ref_counting.h"
|
||||
#include "rhi/renderer.h"
|
||||
|
||||
#include "slang-com-ptr.h"
|
||||
#include "slang.h"
|
||||
|
||||
class shader_vs_dx11;
|
||||
extern ref_count_ptr<ID3D11Device> g_d3d11_device;
|
||||
extern ref_count_ptr<ID3D11DeviceContext> g_d3d11_device_context;
|
||||
extern ref_count_ptr<IDXGISwapChain> g_d3d11_swap_chain;
|
||||
extern ref_count_ptr<ID3D11RenderTargetView> g_main_render_target_view;
|
||||
|
||||
class renderer_dx11 : public renderer
|
||||
{
|
||||
public:
|
||||
renderer_dx11();
|
||||
bool init(SDL_Window* window_handle) override;
|
||||
void shutdown() 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;
|
||||
std::shared_ptr<pixel_shader_drawer> create_pixel_shader_drawer() override;
|
||||
|
||||
void new_frame(SDL_Window* window_handle) override;
|
||||
void end_frame(SDL_Window* window_handle) override;
|
||||
|
||||
void resize(int width, int height) override;
|
||||
std::shared_ptr<texture> create_texture(const unsigned char* data, int width, int height) override;
|
||||
std::shared_ptr<render_target> create_render_target(int width, int height, texture_format format) override;
|
||||
protected:
|
||||
void create_render_target();
|
||||
bool create_device(HWND in_hwnd);
|
||||
bool has_initialized_ = false;
|
||||
};
|
@ -1,69 +0,0 @@
|
||||
#pragma once
|
||||
#include <d3d11.h>
|
||||
|
||||
#include "misc/ref_counting.h"
|
||||
#include "rhi/windows/dx11/renderer_dx11.h"
|
||||
|
||||
class constant_buffer_dx11
|
||||
{
|
||||
public:
|
||||
void create(const int in_size)
|
||||
{
|
||||
element_size_ = in_size;
|
||||
malloc_size_ = in_size;
|
||||
// size must be a multiple of 16
|
||||
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 = {};
|
||||
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
desc.ByteWidth = malloc_size_;
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
desc.MiscFlags = 0;
|
||||
desc.StructureByteStride = 0;
|
||||
|
||||
if (HRESULT hr = g_d3d11_device->CreateBuffer(&desc, nullptr, buffer_.get_init_reference()); FAILED(hr))
|
||||
{
|
||||
spdlog::error("create constant buffer failed: {:x}", hr);
|
||||
return;
|
||||
}
|
||||
buffer_data_ = malloc(malloc_size_);
|
||||
}
|
||||
|
||||
ref_count_ptr<ID3D11Buffer> get_resource() { return buffer_; }
|
||||
|
||||
template<class T>
|
||||
T& get_buffer_data() { return *static_cast<T*>(buffer_data_); }
|
||||
|
||||
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
|
||||
{
|
||||
void* data = lock();
|
||||
memcpy(data, buffer_data_, element_size_);
|
||||
unlock();
|
||||
}
|
||||
|
||||
int binding_point = -1;
|
||||
private:
|
||||
[[nodiscard]] void* lock() const
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE resource;
|
||||
g_d3d11_device_context->Map(buffer_, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource);
|
||||
return resource.pData;
|
||||
}
|
||||
|
||||
void unlock() const
|
||||
{
|
||||
g_d3d11_device_context->Unmap( buffer_, 0 );
|
||||
}
|
||||
|
||||
ref_count_ptr<ID3D11Buffer> buffer_;
|
||||
void* buffer_data_ = nullptr;
|
||||
int malloc_size_ = 0;
|
||||
int element_size_ = 0;
|
||||
};
|
@ -1,127 +0,0 @@
|
||||
#include "shader_cs_dx11.h"
|
||||
|
||||
#include <ranges>
|
||||
|
||||
#include "constant_buffer_dx11.h"
|
||||
#include "uav_buffer_dx11.h"
|
||||
#include "rhi/windows/dx11/dx11_func.h"
|
||||
#include "rhi/windows/dx11/renderer_dx11.h"
|
||||
#include "rhi/windows/dx11/render_target_dx11.h"
|
||||
#include "rhi/windows/dx11/texture_dx11.h"
|
||||
|
||||
void shader_cs_dx11::bind()
|
||||
{
|
||||
#if _DEBUG
|
||||
if (prev_shader_ != nullptr)
|
||||
{
|
||||
spdlog::warn("shader_cs_dx11::bind() called before unbind()!");
|
||||
}
|
||||
#endif
|
||||
g_d3d11_device_context->CSGetShader(&prev_shader_, prev_class_instances_, &prev_class_instances_num_);
|
||||
|
||||
g_d3d11_device_context->CSSetShader(compute_shader_, nullptr, 0);
|
||||
|
||||
for (const auto& buffer : constant_buffers_ | std::views::values)
|
||||
{
|
||||
ref_count_ptr<ID3D11Buffer> cb = buffer->get_resource();
|
||||
ID3D11Buffer* b = cb.get_reference();
|
||||
g_d3d11_device_context->CSSetConstantBuffers(buffer->binding_point, 1, &b);
|
||||
}
|
||||
|
||||
for (const auto& buffer : uav_buffers_ | std::views::values)
|
||||
{
|
||||
buffer->update_buffer();
|
||||
auto u = buffer->get_uav();
|
||||
auto p = u.get_reference();
|
||||
|
||||
g_d3d11_device_context->CSSetUnorderedAccessViews(buffer->binding_point, 1, &p, nullptr);
|
||||
}
|
||||
|
||||
for (const auto& texture : textures_ | std::views::values)
|
||||
{
|
||||
auto srv = texture->get_srv();
|
||||
auto p = srv.get_reference();
|
||||
g_d3d11_device_context->CSSetShaderResources(texture->binding_point, 1, &p);
|
||||
}
|
||||
|
||||
for (const auto& texture : render_targets_ | std::views::values)
|
||||
{
|
||||
auto srv = texture->get_srv();
|
||||
auto p = srv.get_reference();
|
||||
|
||||
g_d3d11_device_context->CSSetShaderResources(texture->binding_point, 1, &p);
|
||||
}
|
||||
}
|
||||
|
||||
void shader_cs_dx11::unbind()
|
||||
{
|
||||
for (const auto& val : uav_buffers_ | std::views::values)
|
||||
{
|
||||
val->fetch_buffer();
|
||||
}
|
||||
g_d3d11_device_context->CSSetShader(prev_shader_, prev_class_instances_, prev_class_instances_num_);
|
||||
prev_shader_ = nullptr;
|
||||
prev_class_instances_ = nullptr;
|
||||
prev_class_instances_num_ = 0;
|
||||
}
|
||||
|
||||
HRESULT shader_cs_dx11::create_shader(ID3DBlob* blob, ID3D11Device* device)
|
||||
{
|
||||
return device->CreateComputeShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, compute_shader_.writeRef());
|
||||
}
|
||||
|
||||
void shader_cs_dx11::set_uav_buffer(const char* name, void* buffer, int size, int element_size)
|
||||
{
|
||||
const auto& binding = bindings_.find(name);
|
||||
if (binding == bindings_.end())
|
||||
{
|
||||
spdlog::warn("uav buffer {} not found in shader", name);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto find = uav_buffers_.find(name);
|
||||
if (find == uav_buffers_.end())
|
||||
{
|
||||
auto uav_buffer = std::make_shared<uav_buffer_dx11>();
|
||||
uav_buffer->binding_point = binding->second.binding;
|
||||
uav_buffer->create(buffer, size, element_size);
|
||||
uav_buffers_.insert({name, uav_buffer});
|
||||
return;
|
||||
}
|
||||
find->second->set_buffer_data(buffer, size);
|
||||
find->second->update_buffer();
|
||||
}
|
||||
|
||||
void shader_cs_dx11::set_render_target(const char* name, std::shared_ptr<render_target> in_render_target)
|
||||
{
|
||||
const auto& binding = bindings_.find(name);
|
||||
if (binding == bindings_.end())
|
||||
{
|
||||
spdlog::warn("render target {} not found in shader", name);
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<render_target_dx11> rt = std::static_pointer_cast<render_target_dx11>(in_render_target);
|
||||
const auto find = uav_buffers_.find(name);
|
||||
if (find == uav_buffers_.end())
|
||||
{
|
||||
auto uav_buffer = std::make_shared<uav_buffer_dx11>();
|
||||
uav_buffer->create_from_render_target(rt);
|
||||
uav_buffer->binding_point = binding->second.binding;
|
||||
uav_buffers_.insert({name, uav_buffer});
|
||||
rt->on_resize_callback = [this, name](std::shared_ptr<render_resource> in_rt)
|
||||
{
|
||||
std::shared_ptr<render_target_dx11> new_rt = std::static_pointer_cast<render_target_dx11>(in_rt);
|
||||
uav_buffers_[name]->create_from_render_target(new_rt);
|
||||
};
|
||||
return;
|
||||
}
|
||||
find->second->create_from_render_target(rt);
|
||||
}
|
||||
|
||||
void shader_cs_dx11::compute(int x, int y, int z)
|
||||
{
|
||||
bind();
|
||||
g_d3d11_device_context->Dispatch(x, y, z);
|
||||
unbind();
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
#pragma once
|
||||
#include "shader_dx11.h"
|
||||
#include "slang-com-ptr.h"
|
||||
|
||||
class shader_cs_dx11 : public shader_dx11
|
||||
{
|
||||
public:
|
||||
explicit shader_cs_dx11(const std::shared_ptr<slang_handle>& handle)
|
||||
: shader_dx11(handle)
|
||||
{
|
||||
}
|
||||
|
||||
void bind() override;
|
||||
void unbind() override;
|
||||
HRESULT create_shader(ID3DBlob* blob, ID3D11Device* device) override;
|
||||
|
||||
[[nodiscard]] ID3D11DeviceChild* get_shader() override { return compute_shader_; }
|
||||
[[nodiscard]] const char* get_shader_model() const override { return "cs_5_0"; }
|
||||
[[nodiscard]] bool is_initialized() const override { return compute_shader_ != nullptr; }
|
||||
|
||||
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 compute(int x, int y, int z) override;
|
||||
private:
|
||||
std::map<std::string, std::shared_ptr<uav_buffer_dx11>> uav_buffers_;
|
||||
|
||||
Slang::ComPtr<ID3D11ComputeShader> compute_shader_;
|
||||
|
||||
ID3D11ComputeShader* prev_shader_ = nullptr;
|
||||
ID3D11ClassInstance** prev_class_instances_ = nullptr;
|
||||
UINT prev_class_instances_num_ = 0;
|
||||
};
|
@ -1,55 +0,0 @@
|
||||
#include "shader_ds_dx11.h"
|
||||
|
||||
#include <ranges>
|
||||
|
||||
#include "constant_buffer_dx11.h"
|
||||
#include "rhi/windows/dx11/renderer_dx11.h"
|
||||
#include "rhi/windows/dx11/render_target_dx11.h"
|
||||
#include "rhi/windows/dx11/texture_dx11.h"
|
||||
|
||||
void shader_ds_dx11::bind()
|
||||
{
|
||||
#if _DEBUG
|
||||
if (prev_shader_ != nullptr)
|
||||
{
|
||||
spdlog::warn("shader_ds_dx11::bind() called before unbind()!");
|
||||
}
|
||||
#endif
|
||||
g_d3d11_device_context->DSGetShader(&prev_shader_, prev_class_instances_, &prev_class_instances_num_);
|
||||
|
||||
g_d3d11_device_context->DSSetShader(domain_shader_, nullptr, 0);
|
||||
|
||||
for (const auto& buffer : constant_buffers_ | std::views::values)
|
||||
{
|
||||
ref_count_ptr<ID3D11Buffer> cb = buffer->get_resource();
|
||||
ID3D11Buffer* b = cb.get_reference();
|
||||
g_d3d11_device_context->DSSetConstantBuffers(buffer->binding_point, 1, &b);
|
||||
}
|
||||
|
||||
for (const auto& texture : textures_ | std::views::values)
|
||||
{
|
||||
auto srv = texture->get_srv();
|
||||
auto p = srv.get_reference();
|
||||
g_d3d11_device_context->DSSetShaderResources(texture->binding_point, 1, &p);
|
||||
}
|
||||
|
||||
for (const auto& texture : render_targets_ | std::views::values)
|
||||
{
|
||||
auto srv = texture->get_srv();
|
||||
auto p = srv.get_reference();
|
||||
g_d3d11_device_context->DSSetShaderResources(texture->binding_point, 1, &p);
|
||||
}
|
||||
}
|
||||
|
||||
void shader_ds_dx11::unbind()
|
||||
{
|
||||
g_d3d11_device_context->DSSetShader(prev_shader_, prev_class_instances_, prev_class_instances_num_);
|
||||
prev_shader_ = nullptr;
|
||||
prev_class_instances_ = nullptr;
|
||||
prev_class_instances_num_ = 0;
|
||||
}
|
||||
|
||||
HRESULT shader_ds_dx11::create_shader(ID3DBlob* blob, ID3D11Device* device)
|
||||
{
|
||||
return device->CreateDomainShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, domain_shader_.writeRef());
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
#pragma once
|
||||
#include "shader_dx11.h"
|
||||
#include "slang-com-ptr.h"
|
||||
|
||||
class shader_ds_dx11 : public shader_dx11
|
||||
{
|
||||
public:
|
||||
explicit shader_ds_dx11(const std::shared_ptr<slang_handle>& handle)
|
||||
: shader_dx11(handle)
|
||||
{
|
||||
}
|
||||
void bind() override;
|
||||
void unbind() override;
|
||||
HRESULT create_shader(ID3DBlob* blob, ID3D11Device* device) override;
|
||||
|
||||
[[nodiscard]] ID3D11DeviceChild* get_shader() override { return domain_shader_; }
|
||||
[[nodiscard]] const char* get_shader_model() const override { return "ds_5_0"; }
|
||||
[[nodiscard]] bool is_initialized() const override { return domain_shader_ != nullptr; }
|
||||
private:
|
||||
Slang::ComPtr<ID3D11DomainShader> domain_shader_;
|
||||
|
||||
ID3D11DomainShader* prev_shader_ = nullptr;
|
||||
ID3D11ClassInstance** prev_class_instances_ = nullptr;
|
||||
unsigned int prev_class_instances_num_ = 0;
|
||||
};
|
@ -1,169 +0,0 @@
|
||||
#include "shader_dx11.h"
|
||||
|
||||
#include <d3dcommon.h>
|
||||
|
||||
#include "constant_buffer_dx11.h"
|
||||
#include "slang-com-ptr.h"
|
||||
#include "uav_buffer_dx11.h"
|
||||
#include "rhi/windows/dx11/dx11_func.h"
|
||||
#include "rhi/windows/dx11/renderer_dx11.h"
|
||||
#include "rhi/windows/dx11/render_target_dx11.h"
|
||||
#include "rhi/windows/dx11/texture_dx11.h"
|
||||
|
||||
bool shader_dx11::init()
|
||||
{
|
||||
Slang::ComPtr<ID3DBlob> kernel_blob;
|
||||
Slang::ComPtr<ID3DBlob> error_blob;
|
||||
|
||||
const auto code_blob = handle_->get_entry_point_code();
|
||||
if (!code_blob)
|
||||
{
|
||||
spdlog::error("slang: get entry point code failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto compile_func = get_d3d_compile_func();
|
||||
if (!compile_func)
|
||||
{
|
||||
spdlog::critical("slang: get D3DCompile function failed");
|
||||
return false;
|
||||
}
|
||||
const auto reflect_func = get_d3d_reflect_func();
|
||||
if (!reflect_func)
|
||||
{
|
||||
spdlog::critical("slang: get D3DReflect function failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int shader_flags = D3DCOMPILE_ENABLE_STRICTNESS;
|
||||
#if _DEBUG
|
||||
shader_flags |= D3DCOMPILE_DEBUG;
|
||||
#else
|
||||
shader_flags |= D3DCOMPILE_OPTIMIZATION_LEVEL3;
|
||||
#endif
|
||||
|
||||
const auto target = get_shader_model();
|
||||
|
||||
auto hr = compile_func(
|
||||
code_blob->getBufferPointer(),
|
||||
code_blob->getBufferSize(),
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
handle_->get_entry_point_name(),
|
||||
target,
|
||||
shader_flags,
|
||||
0,
|
||||
kernel_blob.writeRef(),
|
||||
error_blob.writeRef());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
spdlog::error("slang: compile shader failed: {}", (const char*)error_blob->GetBufferPointer());
|
||||
return false;
|
||||
}
|
||||
hr = create_shader(kernel_blob, g_d3d11_device);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
spdlog::error("slang: create compute shader failed: {:x}", hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
Slang::ComPtr<ID3D11ShaderReflection> reflector;
|
||||
hr = reflect_func(kernel_blob->GetBufferPointer(), kernel_blob->GetBufferSize(), IID_ID3D11ShaderReflectionForCurrentCompiler, (void**)reflector.writeRef());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
spdlog::error("reflect shader failed: {:x}", hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
init_shader_bindings(reflector);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void shader_dx11::set_cbuffer(const char* name, void* buffer, int size)
|
||||
{
|
||||
const auto& binding = bindings_.find(name);
|
||||
if (binding == bindings_.end())
|
||||
{
|
||||
spdlog::warn("constant buffer {} not found in shader", name);
|
||||
return;
|
||||
}
|
||||
|
||||
auto find = constant_buffers_.find(name);
|
||||
if (find == constant_buffers_.end())
|
||||
{
|
||||
auto constant_buffer = std::make_shared<constant_buffer_dx11>();
|
||||
constant_buffer->create(size);
|
||||
constant_buffer->binding_point = binding->second.binding;
|
||||
constant_buffers_.insert({name, constant_buffer});
|
||||
find = constant_buffers_.find(name);
|
||||
}
|
||||
find->second->set_buffer_data(buffer);
|
||||
find->second->update_buffer();
|
||||
}
|
||||
|
||||
void shader_dx11::set_texture(const char* name, std::shared_ptr<texture> in_texture)
|
||||
{
|
||||
const auto& binding = bindings_.find(name);
|
||||
if (binding == bindings_.end())
|
||||
{
|
||||
spdlog::warn("texture {} not found in shader", name);
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<texture_dx11> dx11_t = std::static_pointer_cast<texture_dx11>(in_texture);
|
||||
const auto find = textures_.find(name);
|
||||
if (find == textures_.end())
|
||||
{
|
||||
dx11_t->binding_point = binding->second.binding;
|
||||
textures_.insert({name, dx11_t});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void shader_dx11::set_render_target(const char* name, std::shared_ptr<render_target> in_render_target)
|
||||
{
|
||||
const auto& binding = bindings_.find(name);
|
||||
if (binding == bindings_.end())
|
||||
{
|
||||
spdlog::warn("render target {} not found in shader", name);
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<render_target_dx11> rt = std::static_pointer_cast<render_target_dx11>(in_render_target);
|
||||
|
||||
const auto find = render_targets_.find(name);
|
||||
if (find == render_targets_.end())
|
||||
{
|
||||
rt->binding_point = binding->second.binding;
|
||||
render_targets_.insert({name, rt});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void shader_dx11::init_shader_bindings(ID3D11ShaderReflection* reflector)
|
||||
{
|
||||
D3D11_SHADER_DESC shader_desc;
|
||||
auto hr = reflector->GetDesc(&shader_desc);
|
||||
|
||||
for (unsigned int i = 0; i < shader_desc.BoundResources; ++i)
|
||||
{
|
||||
D3D11_SHADER_INPUT_BIND_DESC desc;
|
||||
hr = reflector->GetResourceBindingDesc(i, &desc);
|
||||
dx11_binding_data binding_data;
|
||||
binding_data.binding = desc.BindPoint;
|
||||
binding_data.type = desc.Type;
|
||||
binding_data.return_type = desc.ReturnType;
|
||||
binding_data.dimension = desc.Dimension;
|
||||
binding_data.num_samples = desc.NumSamples;
|
||||
|
||||
std::string clean_name = desc.Name;
|
||||
if (const size_t clean_index = clean_name.find('_'); clean_index != std::string::npos)
|
||||
{
|
||||
clean_name = clean_name.substr(0, clean_index);
|
||||
}
|
||||
|
||||
bindings_.insert(std::pair(clean_name, binding_data));
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
#pragma once
|
||||
#include "rhi/shader.h"
|
||||
#include <d3d11.h>
|
||||
#include <d3d11shader.h>
|
||||
#include <map>
|
||||
|
||||
class render_target_dx11;
|
||||
class texture_dx11;
|
||||
class uav_buffer_dx11;
|
||||
class constant_buffer_dx11;
|
||||
|
||||
struct dx11_binding_data
|
||||
{
|
||||
D3D_SHADER_INPUT_TYPE type; // Type of resource (e.g. texture, cbuffer, etc.)
|
||||
unsigned int binding; // Starting bind point
|
||||
D3D_RESOURCE_RETURN_TYPE return_type; // Return type (if texture)
|
||||
D3D_SRV_DIMENSION dimension; // Dimension (if texture)
|
||||
unsigned int num_samples ;// Number of samples (0 if not MS texture)
|
||||
};
|
||||
|
||||
class shader_dx11 : public shader
|
||||
{
|
||||
public:
|
||||
explicit shader_dx11(const std::shared_ptr<slang_handle>& handle)
|
||||
: shader(handle)
|
||||
{
|
||||
}
|
||||
|
||||
bool init() override;
|
||||
|
||||
virtual HRESULT create_shader(ID3DBlob* blob, ID3D11Device* device) = 0;
|
||||
|
||||
[[nodiscard]] virtual ID3D11DeviceChild* get_shader() = 0;
|
||||
[[nodiscard]] virtual const char* get_shader_model() const = 0;
|
||||
|
||||
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;
|
||||
|
||||
const auto& get_bindings() const { return bindings_; }
|
||||
protected:
|
||||
std::map<std::string, std::shared_ptr<constant_buffer_dx11>> constant_buffers_;
|
||||
std::map<std::string, std::shared_ptr<texture_dx11>> textures_;
|
||||
std::map<std::string, std::shared_ptr<render_target_dx11>> render_targets_;
|
||||
std::map<std::string, dx11_binding_data> bindings_;
|
||||
private:
|
||||
void init_shader_bindings(ID3D11ShaderReflection* reflector);
|
||||
};
|
@ -1,55 +0,0 @@
|
||||
#include "shader_gs_dx11.h"
|
||||
|
||||
#include <ranges>
|
||||
|
||||
#include "constant_buffer_dx11.h"
|
||||
#include "rhi/windows/dx11/renderer_dx11.h"
|
||||
#include "rhi/windows/dx11/render_target_dx11.h"
|
||||
#include "rhi/windows/dx11/texture_dx11.h"
|
||||
|
||||
void shader_gs_dx11::bind()
|
||||
{
|
||||
#if _DEBUG
|
||||
if (prev_shader_ != nullptr)
|
||||
{
|
||||
spdlog::warn("shader_gs_dx11::bind() called before unbind()!");
|
||||
}
|
||||
#endif
|
||||
g_d3d11_device_context->GSGetShader(&prev_shader_, prev_class_instances_, &prev_class_instances_num_);
|
||||
|
||||
g_d3d11_device_context->GSSetShader(geometry_shader_, nullptr, 0);
|
||||
|
||||
for (const auto& buffer : constant_buffers_ | std::views::values)
|
||||
{
|
||||
ref_count_ptr<ID3D11Buffer> cb = buffer->get_resource();
|
||||
ID3D11Buffer* b = cb.get_reference();
|
||||
g_d3d11_device_context->GSSetConstantBuffers(buffer->binding_point, 1, &b);
|
||||
}
|
||||
|
||||
for (const auto& texture : textures_ | std::views::values)
|
||||
{
|
||||
auto srv = texture->get_srv();
|
||||
auto p = srv.get_reference();
|
||||
g_d3d11_device_context->GSSetShaderResources(texture->binding_point, 1, &p);
|
||||
}
|
||||
|
||||
for (const auto& texture : render_targets_ | std::views::values)
|
||||
{
|
||||
auto srv = texture->get_srv();
|
||||
auto p = srv.get_reference();
|
||||
g_d3d11_device_context->GSSetShaderResources(texture->binding_point, 1, &p);
|
||||
}
|
||||
}
|
||||
|
||||
void shader_gs_dx11::unbind()
|
||||
{
|
||||
g_d3d11_device_context->GSSetShader(prev_shader_, prev_class_instances_, prev_class_instances_num_);
|
||||
prev_shader_ = nullptr;
|
||||
prev_class_instances_ = nullptr;
|
||||
prev_class_instances_num_ = 0;
|
||||
}
|
||||
|
||||
HRESULT shader_gs_dx11::create_shader(ID3DBlob* blob, ID3D11Device* device)
|
||||
{
|
||||
return device->CreateGeometryShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, geometry_shader_.writeRef());
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
#pragma once
|
||||
#include "shader_dx11.h"
|
||||
#include "slang-com-ptr.h"
|
||||
|
||||
class shader_gs_dx11 : public shader_dx11
|
||||
{
|
||||
public:
|
||||
explicit shader_gs_dx11(const std::shared_ptr<slang_handle>& handle)
|
||||
: shader_dx11(handle)
|
||||
{
|
||||
}
|
||||
void bind() override;
|
||||
void unbind() override;
|
||||
HRESULT create_shader(ID3DBlob* blob, ID3D11Device* device) override;
|
||||
|
||||
[[nodiscard]] ID3D11DeviceChild* get_shader() override { return geometry_shader_; }
|
||||
[[nodiscard]] const char* get_shader_model() const override { return "gs_5_0"; }
|
||||
[[nodiscard]] bool is_initialized() const override { return geometry_shader_ != nullptr; }
|
||||
private:
|
||||
Slang::ComPtr<ID3D11GeometryShader> geometry_shader_;
|
||||
|
||||
ID3D11GeometryShader* prev_shader_ = nullptr;
|
||||
ID3D11ClassInstance** prev_class_instances_ = nullptr;
|
||||
UINT prev_class_instances_num_ = 0;
|
||||
};
|
@ -1,55 +0,0 @@
|
||||
#include "shader_hs_dx11.h"
|
||||
|
||||
#include <ranges>
|
||||
|
||||
#include "constant_buffer_dx11.h"
|
||||
#include "rhi/windows/dx11/renderer_dx11.h"
|
||||
#include "rhi/windows/dx11/render_target_dx11.h"
|
||||
#include "rhi/windows/dx11/texture_dx11.h"
|
||||
|
||||
void shader_hs_dx11::bind()
|
||||
{
|
||||
#if _DEBUG
|
||||
if (prev_shader_ != nullptr)
|
||||
{
|
||||
spdlog::warn("shader_gs_dx11::bind() called before unbind()!");
|
||||
}
|
||||
#endif
|
||||
g_d3d11_device_context->HSGetShader(&prev_shader_, prev_class_instances_, &prev_class_instances_num_);
|
||||
|
||||
g_d3d11_device_context->HSSetShader(hull_shader_, nullptr, 0);
|
||||
|
||||
for (const auto& buffer : constant_buffers_ | std::views::values)
|
||||
{
|
||||
ref_count_ptr<ID3D11Buffer> cb = buffer->get_resource();
|
||||
ID3D11Buffer* b = cb.get_reference();
|
||||
g_d3d11_device_context->HSSetConstantBuffers(buffer->binding_point, 1, &b);
|
||||
}
|
||||
|
||||
for (const auto& texture : textures_ | std::views::values)
|
||||
{
|
||||
auto srv = texture->get_srv();
|
||||
auto p = srv.get_reference();
|
||||
g_d3d11_device_context->HSSetShaderResources(texture->binding_point, 1, &p);
|
||||
}
|
||||
|
||||
for (const auto& texture : render_targets_ | std::views::values)
|
||||
{
|
||||
auto srv = texture->get_srv();
|
||||
auto p = srv.get_reference();
|
||||
g_d3d11_device_context->HSSetShaderResources(texture->binding_point, 1, &p);
|
||||
}
|
||||
}
|
||||
|
||||
void shader_hs_dx11::unbind()
|
||||
{
|
||||
g_d3d11_device_context->HSSetShader(prev_shader_, prev_class_instances_, prev_class_instances_num_);
|
||||
prev_shader_ = nullptr;
|
||||
prev_class_instances_ = nullptr;
|
||||
prev_class_instances_num_ = 0;
|
||||
}
|
||||
|
||||
HRESULT shader_hs_dx11::create_shader(ID3DBlob* blob, ID3D11Device* device)
|
||||
{
|
||||
return device->CreateHullShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, hull_shader_.writeRef());
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
#pragma once
|
||||
#include "shader_dx11.h"
|
||||
#include "slang-com-ptr.h"
|
||||
|
||||
class shader_hs_dx11 : public shader_dx11
|
||||
{
|
||||
public:
|
||||
explicit shader_hs_dx11(const std::shared_ptr<slang_handle>& handle)
|
||||
: shader_dx11(handle)
|
||||
{
|
||||
}
|
||||
|
||||
void bind() override;
|
||||
void unbind() override;
|
||||
HRESULT create_shader(ID3DBlob* blob, ID3D11Device* device) override;
|
||||
|
||||
[[nodiscard]] ID3D11DeviceChild* get_shader() override { return hull_shader_; }
|
||||
[[nodiscard]] const char* get_shader_model() const override { return "hs_5_0"; }
|
||||
[[nodiscard]] bool is_initialized() const override { return hull_shader_ != nullptr; }
|
||||
private:
|
||||
Slang::ComPtr<ID3D11HullShader> hull_shader_;
|
||||
|
||||
ID3D11HullShader* prev_shader_ = nullptr;
|
||||
ID3D11ClassInstance** prev_class_instances_ = nullptr;
|
||||
unsigned int prev_class_instances_num_ = 0;
|
||||
};
|
@ -1,59 +0,0 @@
|
||||
#include "shader_ps_dx11.h"
|
||||
|
||||
#include <ranges>
|
||||
|
||||
#include "constant_buffer_dx11.h"
|
||||
#include "imgui_internal.h"
|
||||
#include "uav_buffer_dx11.h"
|
||||
#include "application/application.h"
|
||||
#include "misc/scope_exit.h"
|
||||
#include "rhi/windows/dx11/renderer_dx11.h"
|
||||
#include "rhi/windows/dx11/render_target_dx11.h"
|
||||
#include "rhi/windows/dx11/texture_dx11.h"
|
||||
|
||||
void shader_ps_dx11::bind()
|
||||
{
|
||||
#if _DEBUG
|
||||
if (prev_shader_ != nullptr)
|
||||
{
|
||||
spdlog::warn("shader_ps_dx11::bind() called before unbind()!");
|
||||
}
|
||||
#endif
|
||||
g_d3d11_device_context->PSGetShader(&prev_shader_, prev_class_instances_, &prev_class_instances_num_);
|
||||
|
||||
g_d3d11_device_context->PSSetShader(pixel_shader_, nullptr, 0);
|
||||
|
||||
for (const auto& buffer : constant_buffers_ | std::views::values)
|
||||
{
|
||||
ref_count_ptr<ID3D11Buffer> cb = buffer->get_resource();
|
||||
ID3D11Buffer* b = cb.get_reference();
|
||||
g_d3d11_device_context->PSSetConstantBuffers(buffer->binding_point, 1, &b);
|
||||
}
|
||||
|
||||
for (const auto& texture : textures_ | std::views::values)
|
||||
{
|
||||
auto srv = texture->get_srv();
|
||||
auto p = srv.get_reference();
|
||||
g_d3d11_device_context->PSSetShaderResources(texture->binding_point, 1, &p);
|
||||
}
|
||||
|
||||
for (const auto& texture : render_targets_ | std::views::values)
|
||||
{
|
||||
auto srv = texture->get_srv();
|
||||
auto p = srv.get_reference();
|
||||
g_d3d11_device_context->PSSetShaderResources(texture->binding_point, 1, &p);
|
||||
}
|
||||
}
|
||||
|
||||
void shader_ps_dx11::unbind()
|
||||
{
|
||||
g_d3d11_device_context->PSSetShader(prev_shader_, prev_class_instances_, prev_class_instances_num_);
|
||||
prev_shader_ = nullptr;
|
||||
prev_class_instances_ = nullptr;
|
||||
prev_class_instances_num_ = 0;
|
||||
}
|
||||
|
||||
HRESULT shader_ps_dx11::create_shader(ID3DBlob* blob, ID3D11Device* device)
|
||||
{
|
||||
return device->CreatePixelShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, pixel_shader_.writeRef());
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
#pragma once
|
||||
#include "shader_dx11.h"
|
||||
#include "slang-com-ptr.h"
|
||||
|
||||
class shader_ps_dx11 : public shader_dx11
|
||||
{
|
||||
public:
|
||||
explicit shader_ps_dx11(const std::shared_ptr<slang_handle>& handle)
|
||||
: shader_dx11(handle)
|
||||
{
|
||||
}
|
||||
|
||||
void bind() override;
|
||||
void unbind() override;
|
||||
|
||||
HRESULT create_shader(ID3DBlob* blob, ID3D11Device* device) override;
|
||||
|
||||
[[nodiscard]] ID3D11DeviceChild* get_shader() override { return pixel_shader_; }
|
||||
[[nodiscard]] const char* get_shader_model() const override { return "ps_5_0"; }
|
||||
[[nodiscard]] bool is_initialized() const override { return pixel_shader_ != nullptr; }
|
||||
private:
|
||||
Slang::ComPtr<ID3D11PixelShader> pixel_shader_;
|
||||
|
||||
ID3D11PixelShader* prev_shader_ = nullptr;
|
||||
ID3D11ClassInstance** prev_class_instances_ = nullptr;
|
||||
UINT prev_class_instances_num_ = 0;
|
||||
};
|
@ -1,72 +0,0 @@
|
||||
#include "shader_vs_dx11.h"
|
||||
|
||||
#include <ranges>
|
||||
|
||||
#include "constant_buffer_dx11.h"
|
||||
#include "rhi/windows/dx11/renderer_dx11.h"
|
||||
#include "rhi/windows/dx11/render_target_dx11.h"
|
||||
#include "rhi/windows/dx11/texture_dx11.h"
|
||||
|
||||
void shader_vs_dx11::bind()
|
||||
{
|
||||
#if _DEBUG
|
||||
if (prev_shader_ != nullptr)
|
||||
{
|
||||
spdlog::warn("shader_vs_dx11::bind() called before unbind()!");
|
||||
}
|
||||
#endif
|
||||
g_d3d11_device_context->VSGetShader(&prev_shader_, prev_class_instances_, &prev_class_instances_num_);
|
||||
g_d3d11_device_context->IAGetInputLayout(&prev_input_layout_);
|
||||
|
||||
g_d3d11_device_context->IASetInputLayout(input_layout_);
|
||||
g_d3d11_device_context->VSSetShader(vertex_shader_, nullptr, 0);
|
||||
|
||||
for (const auto& buffer : constant_buffers_ | std::views::values)
|
||||
{
|
||||
ref_count_ptr<ID3D11Buffer> cb = buffer->get_resource();
|
||||
ID3D11Buffer* b = cb.get_reference();
|
||||
g_d3d11_device_context->VSSetConstantBuffers(buffer->binding_point, 1, &b);
|
||||
}
|
||||
|
||||
for (const auto& texture : textures_ | std::views::values)
|
||||
{
|
||||
auto srv = texture->get_srv();
|
||||
auto p = srv.get_reference();
|
||||
g_d3d11_device_context->VSSetShaderResources(texture->binding_point, 1, &p);
|
||||
}
|
||||
|
||||
for (const auto& texture : render_targets_ | std::views::values)
|
||||
{
|
||||
auto srv = texture->get_srv();
|
||||
auto p = srv.get_reference();
|
||||
g_d3d11_device_context->VSSetShaderResources(texture->binding_point, 1, &p);
|
||||
}
|
||||
}
|
||||
|
||||
void shader_vs_dx11::unbind()
|
||||
{
|
||||
g_d3d11_device_context->VSSetShader(prev_shader_, prev_class_instances_, prev_class_instances_num_);
|
||||
prev_shader_ = nullptr;
|
||||
prev_class_instances_ = nullptr;
|
||||
prev_class_instances_num_ = 0;
|
||||
|
||||
g_d3d11_device_context->IASetInputLayout(prev_input_layout_);
|
||||
prev_input_layout_ = nullptr;
|
||||
}
|
||||
|
||||
HRESULT shader_vs_dx11::create_shader(ID3DBlob* blob, ID3D11Device* device)
|
||||
{
|
||||
auto hr = device->CreateVertexShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, vertex_shader_.writeRef());
|
||||
if (hr != S_OK)
|
||||
{
|
||||
return hr;
|
||||
}
|
||||
// TODO: refactor this
|
||||
D3D11_INPUT_ELEMENT_DESC local_layout[] =
|
||||
{
|
||||
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, pos), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, uv), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)offsetof(ImDrawVert, col), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
};
|
||||
return g_d3d11_device->CreateInputLayout(local_layout, 3, blob->GetBufferPointer(), blob->GetBufferSize(), input_layout_.writeRef()) != S_OK;
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
#pragma once
|
||||
#include "shader_dx11.h"
|
||||
#include "slang-com-ptr.h"
|
||||
|
||||
class shader_vs_dx11 : public shader_dx11
|
||||
{
|
||||
public:
|
||||
explicit shader_vs_dx11(const std::shared_ptr<slang_handle>& handle)
|
||||
: shader_dx11(handle)
|
||||
{
|
||||
}
|
||||
void bind() override;
|
||||
void unbind() override;
|
||||
HRESULT create_shader(ID3DBlob* blob, ID3D11Device* device) override;
|
||||
|
||||
[[nodiscard]] ID3D11DeviceChild* get_shader() override { return vertex_shader_; }
|
||||
[[nodiscard]] const char* get_shader_model() const override { return "vs_5_0"; }
|
||||
[[nodiscard]] bool is_initialized() const override { return vertex_shader_ != nullptr; }
|
||||
private:
|
||||
Slang::ComPtr<ID3D11VertexShader> vertex_shader_;
|
||||
Slang::ComPtr<ID3D11InputLayout> input_layout_;
|
||||
|
||||
ID3D11VertexShader* prev_shader_ = nullptr;
|
||||
ID3D11ClassInstance** prev_class_instances_ = nullptr;
|
||||
unsigned int prev_class_instances_num_ = 0;
|
||||
ID3D11InputLayout* prev_input_layout_ = nullptr;
|
||||
};
|
@ -1,141 +0,0 @@
|
||||
#include "uav_buffer_dx11.h"
|
||||
|
||||
#include "rhi/windows/dx11/renderer_dx11.h"
|
||||
#include "rhi/windows/dx11/render_target_dx11.h"
|
||||
|
||||
void uav_buffer_dx11::create(const void* in_init_data, int in_count, int element_size)
|
||||
{
|
||||
D3D11_BUFFER_DESC buffer_desc;
|
||||
ZeroMemory(&buffer_desc, sizeof(buffer_desc));
|
||||
buffer_desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE;
|
||||
buffer_desc.ByteWidth = in_count * element_size;
|
||||
buffer_desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
|
||||
buffer_desc.StructureByteStride = element_size;
|
||||
|
||||
HRESULT hr;
|
||||
if (in_init_data)
|
||||
{
|
||||
D3D11_SUBRESOURCE_DATA init_data = {};
|
||||
init_data.pSysMem = in_init_data;
|
||||
init_data.SysMemPitch = 0;
|
||||
init_data.SysMemSlicePitch = 0;
|
||||
hr = g_d3d11_device->CreateBuffer(&buffer_desc, &init_data, buffer_.get_init_reference());
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = g_d3d11_device->CreateBuffer(&buffer_desc, nullptr, buffer_.get_init_reference());
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
spdlog::error("create uav buffer failed: {:x}", hr);
|
||||
return;
|
||||
}
|
||||
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc;
|
||||
ZeroMemory(&srv_desc, sizeof(srv_desc));
|
||||
srv_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFEREX;
|
||||
srv_desc.BufferEx.FirstElement = 0;
|
||||
srv_desc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
srv_desc.BufferEx.NumElements = buffer_desc.ByteWidth / buffer_desc.StructureByteStride;
|
||||
|
||||
hr = g_d3d11_device->CreateShaderResourceView(buffer_, &srv_desc, srv_.get_init_reference());
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
spdlog::error("create uav buffer srv failed: {:x}", hr);
|
||||
return;
|
||||
}
|
||||
|
||||
D3D11_UNORDERED_ACCESS_VIEW_DESC uav_desc;
|
||||
ZeroMemory(&uav_desc, sizeof(uav_desc));
|
||||
uav_desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
|
||||
uav_desc.Buffer.FirstElement = 0;
|
||||
|
||||
uav_desc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
uav_desc.Buffer.NumElements = buffer_desc.ByteWidth / buffer_desc.StructureByteStride;
|
||||
|
||||
hr = g_d3d11_device->CreateUnorderedAccessView(buffer_, &uav_desc, uav_.get_init_reference());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
spdlog::error("create uav buffer uav failed: {:x}", hr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void uav_buffer_dx11::create_from_render_target(std::shared_ptr<render_target_dx11> rt)
|
||||
{
|
||||
source_render_target_ = rt;
|
||||
|
||||
D3D11_TEXTURE2D_DESC texture_desc;
|
||||
rt->get_texture()->GetDesc(&texture_desc);
|
||||
texture_desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE;
|
||||
|
||||
|
||||
HRESULT hr = g_d3d11_device->CreateTexture2D(&texture_desc, nullptr, buffer_texture_.get_init_reference());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
spdlog::error("create uav buffer data texture failed: {:x}", hr);
|
||||
return;
|
||||
}
|
||||
|
||||
// SRV
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc;
|
||||
ZeroMemory(&srv_desc, sizeof(srv_desc));
|
||||
srv_desc.Format = texture_desc.Format;
|
||||
srv_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
srv_desc.Texture2D.MipLevels = 1;
|
||||
srv_desc.Texture2D.MostDetailedMip = 0;
|
||||
hr = g_d3d11_device->CreateShaderResourceView(buffer_texture_, &srv_desc, srv_.get_init_reference());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
spdlog::error("create uav buffer srv failed: {:x}", hr);
|
||||
return;
|
||||
}
|
||||
|
||||
D3D11_UNORDERED_ACCESS_VIEW_DESC uav_desc;
|
||||
ZeroMemory(&uav_desc, sizeof(uav_desc));
|
||||
uav_desc.Format = texture_desc.Format;
|
||||
uav_desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
|
||||
uav_desc.Texture2D.MipSlice = 0; // Mip level
|
||||
|
||||
hr = g_d3d11_device->CreateUnorderedAccessView(buffer_texture_, &uav_desc, uav_.get_init_reference());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
spdlog::error("create uav buffer uav failed: {:x}", hr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void uav_buffer_dx11::update_buffer()
|
||||
{
|
||||
if (source_render_target_.expired())
|
||||
return;
|
||||
g_d3d11_device_context->CopyResource(buffer_texture_, source_render_target_.lock()->get_texture());
|
||||
}
|
||||
|
||||
void uav_buffer_dx11::fetch_buffer()
|
||||
{
|
||||
if (source_render_target_.expired())
|
||||
return;
|
||||
g_d3d11_device_context->CopyResource(source_render_target_.lock()->get_texture(), buffer_texture_);
|
||||
}
|
||||
|
||||
void uav_buffer_dx11::set_buffer_data(const void* param, const int size) const
|
||||
{
|
||||
void* data = lock();
|
||||
memcpy(data, param, size);
|
||||
unlock();
|
||||
}
|
||||
|
||||
void* uav_buffer_dx11::lock() const
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE resource;
|
||||
g_d3d11_device_context->Map(buffer_, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource);
|
||||
return resource.pData;
|
||||
}
|
||||
|
||||
void uav_buffer_dx11::unlock() const
|
||||
{
|
||||
g_d3d11_device_context->Unmap(buffer_, 0);
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
#pragma once
|
||||
#include <d3d11.h>
|
||||
|
||||
#include "misc/ref_counting.h"
|
||||
|
||||
class render_target_dx11;
|
||||
|
||||
class uav_buffer_dx11
|
||||
{
|
||||
public:
|
||||
void create(const void* in_init_data, int in_count, int element_size);
|
||||
void create_from_render_target(std::shared_ptr<render_target_dx11> rt);
|
||||
|
||||
void update_buffer(); // update buffer from render target
|
||||
void fetch_buffer(); // set data to render target
|
||||
|
||||
void set_buffer_data(const void* param, int size) const;
|
||||
[[nodiscard]] void* lock() const;
|
||||
void unlock() const;
|
||||
|
||||
ref_count_ptr<ID3D11Buffer> get_resource() { return buffer_; }
|
||||
ref_count_ptr<ID3D11UnorderedAccessView> get_uav() { return uav_; }
|
||||
ref_count_ptr<ID3D11ShaderResourceView> get_srv() { return srv_; }
|
||||
|
||||
int binding_point = -1;
|
||||
private:
|
||||
ref_count_ptr<ID3D11Buffer> buffer_; // nullptr when created from render target
|
||||
|
||||
ref_count_ptr<ID3D11UnorderedAccessView> uav_;
|
||||
ref_count_ptr<ID3D11ShaderResourceView> srv_;
|
||||
|
||||
std::weak_ptr<render_target_dx11> source_render_target_;
|
||||
ref_count_ptr<ID3D11Texture2D> buffer_texture_; // nullptr when created from buffer
|
||||
};
|
||||
|
||||
|
@ -1,49 +0,0 @@
|
||||
#include "texture_dx11.h"
|
||||
|
||||
|
||||
#include "renderer_dx11.h"
|
||||
|
||||
bool texture_dx11::init_data(const unsigned char* data, int width, int height)
|
||||
{
|
||||
width_ = width;
|
||||
height_ = height;
|
||||
// Create texture
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(desc));
|
||||
desc.Width = width;
|
||||
desc.Height = height;
|
||||
desc.MipLevels = 1;
|
||||
desc.ArraySize = 1;
|
||||
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
desc.CPUAccessFlags = 0;
|
||||
|
||||
ref_count_ptr<ID3D11Texture2D> temp_texture;
|
||||
D3D11_SUBRESOURCE_DATA sub_resource;
|
||||
sub_resource.pSysMem = data;
|
||||
sub_resource.SysMemPitch = desc.Width * 4;
|
||||
sub_resource.SysMemSlicePitch = 0;
|
||||
auto hr = g_d3d11_device->CreateTexture2D(&desc, &sub_resource, temp_texture.get_init_reference());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
spdlog::error("Failed to create texture");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create texture view
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc;
|
||||
ZeroMemory(&srv_desc, sizeof(srv_desc));
|
||||
srv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
srv_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
srv_desc.Texture2D.MipLevels = desc.MipLevels;
|
||||
srv_desc.Texture2D.MostDetailedMip = 0;
|
||||
hr = g_d3d11_device->CreateShaderResourceView(temp_texture, &srv_desc, shader_resource_view_.get_init_reference());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
spdlog::error("Failed to create texture view");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
#pragma once
|
||||
#include <d3d11.h>
|
||||
|
||||
#include "misc/ref_counting.h"
|
||||
#include "rhi/texture.h"
|
||||
|
||||
class texture_dx11 : public texture
|
||||
{
|
||||
public:
|
||||
ImTextureID get_texture_id() override { return shader_resource_view_; }
|
||||
[[nodiscard]] ref_count_ptr<ID3D11ShaderResourceView> get_srv() { return shader_resource_view_; }
|
||||
bool init_data(const unsigned char* data, int width, int height) override;
|
||||
[[nodiscard]] bool is_valid() const override { return shader_resource_view_.is_valid(); }
|
||||
|
||||
int binding_point = -1;
|
||||
private:
|
||||
ref_count_ptr<ID3D11ShaderResourceView> shader_resource_view_;
|
||||
};
|
7
third_party/glad/CMakeLists.txt
vendored
Normal file
7
third_party/glad/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
project(glad)
|
||||
|
||||
set(ALL_FILES "")
|
||||
retrieve_files(ALL_FILES)
|
||||
|
||||
add_library(${PROJECT_NAME} STATIC ${ALL_FILES})
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
311
third_party/glad/KHR/khrplatform.h
vendored
Normal file
311
third_party/glad/KHR/khrplatform.h
vendored
Normal file
@ -0,0 +1,311 @@
|
||||
#ifndef __khrplatform_h_
|
||||
#define __khrplatform_h_
|
||||
|
||||
/*
|
||||
** Copyright (c) 2008-2018 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
/* Khronos platform-specific types and definitions.
|
||||
*
|
||||
* The master copy of khrplatform.h is maintained in the Khronos EGL
|
||||
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
|
||||
* The last semantic modification to khrplatform.h was at commit ID:
|
||||
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
|
||||
*
|
||||
* Adopters may modify this file to suit their platform. Adopters are
|
||||
* encouraged to submit platform specific modifications to the Khronos
|
||||
* group so that they can be included in future versions of this file.
|
||||
* Please submit changes by filing pull requests or issues on
|
||||
* the EGL Registry repository linked above.
|
||||
*
|
||||
*
|
||||
* See the Implementer's Guidelines for information about where this file
|
||||
* should be located on your system and for more details of its use:
|
||||
* http://www.khronos.org/registry/implementers_guide.pdf
|
||||
*
|
||||
* This file should be included as
|
||||
* #include <KHR/khrplatform.h>
|
||||
* by Khronos client API header files that use its types and defines.
|
||||
*
|
||||
* The types in khrplatform.h should only be used to define API-specific types.
|
||||
*
|
||||
* Types defined in khrplatform.h:
|
||||
* khronos_int8_t signed 8 bit
|
||||
* khronos_uint8_t unsigned 8 bit
|
||||
* khronos_int16_t signed 16 bit
|
||||
* khronos_uint16_t unsigned 16 bit
|
||||
* khronos_int32_t signed 32 bit
|
||||
* khronos_uint32_t unsigned 32 bit
|
||||
* khronos_int64_t signed 64 bit
|
||||
* khronos_uint64_t unsigned 64 bit
|
||||
* khronos_intptr_t signed same number of bits as a pointer
|
||||
* khronos_uintptr_t unsigned same number of bits as a pointer
|
||||
* khronos_ssize_t signed size
|
||||
* khronos_usize_t unsigned size
|
||||
* khronos_float_t signed 32 bit floating point
|
||||
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
|
||||
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
|
||||
* nanoseconds
|
||||
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
|
||||
* khronos_boolean_enum_t enumerated boolean type. This should
|
||||
* only be used as a base type when a client API's boolean type is
|
||||
* an enum. Client APIs which use an integer or other type for
|
||||
* booleans cannot use this as the base type for their boolean.
|
||||
*
|
||||
* Tokens defined in khrplatform.h:
|
||||
*
|
||||
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
|
||||
*
|
||||
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
|
||||
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
|
||||
*
|
||||
* Calling convention macros defined in this file:
|
||||
* KHRONOS_APICALL
|
||||
* KHRONOS_APIENTRY
|
||||
* KHRONOS_APIATTRIBUTES
|
||||
*
|
||||
* These may be used in function prototypes as:
|
||||
*
|
||||
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
|
||||
* int arg1,
|
||||
* int arg2) KHRONOS_APIATTRIBUTES;
|
||||
*/
|
||||
|
||||
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
|
||||
# define KHRONOS_STATIC 1
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APICALL
|
||||
*-------------------------------------------------------------------------
|
||||
* This precedes the return type of the function in the function prototype.
|
||||
*/
|
||||
#if defined(KHRONOS_STATIC)
|
||||
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
|
||||
* header compatible with static linking. */
|
||||
# define KHRONOS_APICALL
|
||||
#elif defined(_WIN32)
|
||||
# define KHRONOS_APICALL __declspec(dllimport)
|
||||
#elif defined (__SYMBIAN32__)
|
||||
# define KHRONOS_APICALL IMPORT_C
|
||||
#elif defined(__ANDROID__)
|
||||
# define KHRONOS_APICALL __attribute__((visibility("default")))
|
||||
#else
|
||||
# define KHRONOS_APICALL
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIENTRY
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the return type of the function and precedes the function
|
||||
* name in the function prototype.
|
||||
*/
|
||||
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
|
||||
/* Win32 but not WinCE */
|
||||
# define KHRONOS_APIENTRY __stdcall
|
||||
#else
|
||||
# define KHRONOS_APIENTRY
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIATTRIBUTES
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the closing parenthesis of the function prototype arguments.
|
||||
*/
|
||||
#if defined (__ARMCC_2__)
|
||||
#define KHRONOS_APIATTRIBUTES __softfp
|
||||
#else
|
||||
#define KHRONOS_APIATTRIBUTES
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* basic type definitions
|
||||
*-----------------------------------------------------------------------*/
|
||||
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
|
||||
|
||||
|
||||
/*
|
||||
* Using <stdint.h>
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
/*
|
||||
* To support platform where unsigned long cannot be used interchangeably with
|
||||
* inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t.
|
||||
* Ideally, we could just use (u)intptr_t everywhere, but this could result in
|
||||
* ABI breakage if khronos_uintptr_t is changed from unsigned long to
|
||||
* unsigned long long or similar (this results in different C++ name mangling).
|
||||
* To avoid changes for existing platforms, we restrict usage of intptr_t to
|
||||
* platforms where the size of a pointer is larger than the size of long.
|
||||
*/
|
||||
#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__)
|
||||
#if __SIZEOF_POINTER__ > __SIZEOF_LONG__
|
||||
#define KHRONOS_USE_INTPTR_T
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif defined(__VMS ) || defined(__sgi)
|
||||
|
||||
/*
|
||||
* Using <inttypes.h>
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
||||
|
||||
/*
|
||||
* Win32
|
||||
*/
|
||||
typedef __int32 khronos_int32_t;
|
||||
typedef unsigned __int32 khronos_uint32_t;
|
||||
typedef __int64 khronos_int64_t;
|
||||
typedef unsigned __int64 khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(__sun__) || defined(__digital__)
|
||||
|
||||
/*
|
||||
* Sun or Digital
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#if defined(__arch64__) || defined(_LP64)
|
||||
typedef long int khronos_int64_t;
|
||||
typedef unsigned long int khronos_uint64_t;
|
||||
#else
|
||||
typedef long long int khronos_int64_t;
|
||||
typedef unsigned long long int khronos_uint64_t;
|
||||
#endif /* __arch64__ */
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif 0
|
||||
|
||||
/*
|
||||
* Hypothetical platform with no float or int64 support
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#define KHRONOS_SUPPORT_INT64 0
|
||||
#define KHRONOS_SUPPORT_FLOAT 0
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Generic fallback
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Types that are (so far) the same on all platforms
|
||||
*/
|
||||
typedef signed char khronos_int8_t;
|
||||
typedef unsigned char khronos_uint8_t;
|
||||
typedef signed short int khronos_int16_t;
|
||||
typedef unsigned short int khronos_uint16_t;
|
||||
|
||||
/*
|
||||
* Types that differ between LLP64 and LP64 architectures - in LLP64,
|
||||
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
|
||||
* to be the only LLP64 architecture in current use.
|
||||
*/
|
||||
#ifdef KHRONOS_USE_INTPTR_T
|
||||
typedef intptr_t khronos_intptr_t;
|
||||
typedef uintptr_t khronos_uintptr_t;
|
||||
#elif defined(_WIN64)
|
||||
typedef signed long long int khronos_intptr_t;
|
||||
typedef unsigned long long int khronos_uintptr_t;
|
||||
#else
|
||||
typedef signed long int khronos_intptr_t;
|
||||
typedef unsigned long int khronos_uintptr_t;
|
||||
#endif
|
||||
|
||||
#if defined(_WIN64)
|
||||
typedef signed long long int khronos_ssize_t;
|
||||
typedef unsigned long long int khronos_usize_t;
|
||||
#else
|
||||
typedef signed long int khronos_ssize_t;
|
||||
typedef unsigned long int khronos_usize_t;
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_FLOAT
|
||||
/*
|
||||
* Float type
|
||||
*/
|
||||
typedef float khronos_float_t;
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_INT64
|
||||
/* Time types
|
||||
*
|
||||
* These types can be used to represent a time interval in nanoseconds or
|
||||
* an absolute Unadjusted System Time. Unadjusted System Time is the number
|
||||
* of nanoseconds since some arbitrary system event (e.g. since the last
|
||||
* time the system booted). The Unadjusted System Time is an unsigned
|
||||
* 64 bit value that wraps back to 0 every 584 years. Time intervals
|
||||
* may be either signed or unsigned.
|
||||
*/
|
||||
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
|
||||
typedef khronos_int64_t khronos_stime_nanoseconds_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Dummy value used to pad enum types to 32 bits.
|
||||
*/
|
||||
#ifndef KHRONOS_MAX_ENUM
|
||||
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Enumerated boolean type
|
||||
*
|
||||
* Values other than zero should be considered to be true. Therefore
|
||||
* comparisons should not be made against KHRONOS_TRUE.
|
||||
*/
|
||||
typedef enum {
|
||||
KHRONOS_FALSE = 0,
|
||||
KHRONOS_TRUE = 1,
|
||||
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
|
||||
} khronos_boolean_enum_t;
|
||||
|
||||
#endif /* __khrplatform_h_ */
|
12836
third_party/glad/glad.c
vendored
Normal file
12836
third_party/glad/glad.c
vendored
Normal file
File diff suppressed because one or more lines are too long
20971
third_party/glad/glad/glad.h
vendored
Normal file
20971
third_party/glad/glad/glad.h
vendored
Normal file
File diff suppressed because one or more lines are too long
34
third_party/imgui/CMakeLists.txt
vendored
34
third_party/imgui/CMakeLists.txt
vendored
@ -19,49 +19,35 @@ add_library(${PROJECT_NAME} STATIC
|
||||
|
||||
if (WIN32)
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
imgui/backends/imgui_impl_sdl3.cpp
|
||||
imgui/backends/imgui_impl_sdl3.h
|
||||
imgui/backends/imgui_impl_vulkan.cpp
|
||||
imgui/backends/imgui_impl_vulkan.h
|
||||
imgui/backends/imgui_impl_glfw.cpp
|
||||
imgui/backends/imgui_impl_glfw.h
|
||||
imgui/backends/imgui_impl_opengl3.cpp
|
||||
imgui/backends/imgui_impl_opengl3.h
|
||||
imgui/backends/imgui_impl_dx11.h
|
||||
imgui/backends/imgui_impl_dx11.cpp
|
||||
imgui/backends/imgui_impl_dx12.h
|
||||
imgui/backends/imgui_impl_dx12.cpp
|
||||
imgui/backends/imgui_impl_win32.h
|
||||
imgui/backends/imgui_impl_win32.cpp
|
||||
)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC opengl32.lib SDL3-shared d3d11 d3dcompiler dxgi d3d12 glad)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC glfw glad)
|
||||
elseif(UNIX AND NOT APPLE)
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
imgui/backends/imgui_impl_sdl3.cpp
|
||||
imgui/backends/imgui_impl_sdl3.h
|
||||
imgui/backends/imgui_impl_vulkan.cpp
|
||||
imgui/backends/imgui_impl_vulkan.h
|
||||
imgui/backends/imgui_impl_glfw.cpp
|
||||
imgui/backends/imgui_impl_glfw.h
|
||||
imgui/backends/imgui_impl_opengl3.cpp
|
||||
imgui/backends/imgui_impl_opengl3.h
|
||||
)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC vulkan SDL3-shared glad)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC glfw glad)
|
||||
elseif(APPLE)
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
imgui/backends/imgui_impl_sdl3.cpp
|
||||
imgui/backends/imgui_impl_sdl3.h
|
||||
imgui/backends/imgui_impl_vulkan.cpp
|
||||
imgui/backends/imgui_impl_vulkan.h
|
||||
imgui/backends/imgui_impl_glfw.cpp
|
||||
imgui/backends/imgui_impl_glfw.h
|
||||
imgui/backends/imgui_impl_opengl3.cpp
|
||||
imgui/backends/imgui_impl_opengl3.h
|
||||
imgui/backends/imgui_impl_metal.h
|
||||
imgui/backends/imgui_impl_metal.mm
|
||||
)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC vulkan SDL3-shared glad)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC glfw glad)
|
||||
endif()
|
||||
|
||||
include_directories(SDL3-shared)
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/imgui)
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/imgui/backends)
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} glad)
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} glfw glad)
|
||||
|
||||
target_precompile_headers(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/pch.h)
|
||||
|
||||
|
1
third_party/imgui/pch.h
vendored
1
third_party/imgui/pch.h
vendored
@ -0,0 +1 @@
|
||||
#include "glad/glad.h"
|
Loading…
x
Reference in New Issue
Block a user