init
This commit is contained in:
commit
bba0a3a389
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/build
|
15
.gitmodules
vendored
Normal file
15
.gitmodules
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
[submodule "third_party/imgui/imgui"]
|
||||
path = third_party/imgui/imgui
|
||||
url = https://github.com/ocornut/imgui.git
|
||||
[submodule "third_party/sdl"]
|
||||
path = third_party/sdl
|
||||
url = https://github.com/libsdl-org/SDL.git
|
||||
[submodule "third_party/portaudio"]
|
||||
path = third_party/portaudio
|
||||
url = https://github.com/PortAudio/portaudio.git
|
||||
[submodule "third_party/spdlog"]
|
||||
path = third_party/spdlog
|
||||
url = https://github.com/gabime/spdlog.git
|
||||
[submodule "third_party/HLSLcc"]
|
||||
path = third_party/HLSLcc
|
||||
url = https://github.com/Unity-Technologies/HLSLcc.git
|
142
CMakeLists.txt
Normal file
142
CMakeLists.txt
Normal file
@ -0,0 +1,142 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(arona_core)
|
||||
|
||||
function(retrieve_files out_files)
|
||||
set(source_list)
|
||||
|
||||
# 递归查找文件夹下的 .h .hpp. ini 文件保存到 HEAD_FILES
|
||||
file(GLOB_RECURSE HEAD_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} CONFIGURE_DEPENDS *.h *.hpp *.ini)
|
||||
|
||||
# 递归查找文件夹下的 *.cpp *.c 文件保存到 SRC_FILES
|
||||
file(GLOB_RECURSE SRC_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} CONFIGURE_DEPENDS *.cpp *.c)
|
||||
|
||||
# 将 HEDADER_FILES 和 SRC_FILES 保存到 ALL_FILES 变量
|
||||
set(ALL_FILES ${HEAD_FILES} ${SRC_FILES})
|
||||
|
||||
set(RESULT "")
|
||||
|
||||
# 对 ALL_FILES 变量里面的所有文件分类(保留资源管理器的目录结构)
|
||||
foreach(fileItem ${ALL_FILES})
|
||||
# Get the directory of the source file
|
||||
get_filename_component(PARENT_DIR "${fileItem}" DIRECTORY)
|
||||
|
||||
# 用于检查平台的条件
|
||||
if(PARENT_DIR STREQUAL "windows")
|
||||
if(WIN32)
|
||||
set(RESULT "${RESULT};${fileItem}")
|
||||
else()
|
||||
continue()
|
||||
endif()
|
||||
elseif(PARENT_DIR STREQUAL "linux")
|
||||
if(UNIX AND NOT APPLE)
|
||||
set(RESULT "${RESULT};${fileItem}")
|
||||
else()
|
||||
continue()
|
||||
endif()
|
||||
elseif(PARENT_DIR STREQUAL "mac")
|
||||
if(APPLE)
|
||||
set(RESULT "${RESULT};${fileItem}")
|
||||
else()
|
||||
continue()
|
||||
endif()
|
||||
else()
|
||||
# 如果文件夹名称不是平台,则始终包含
|
||||
set(RESULT "${RESULT};${fileItem}")
|
||||
endif()
|
||||
|
||||
# Remove common directory prefix to make the group
|
||||
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}" "" GROUP "${PARENT_DIR}")
|
||||
# Make sure we are using windows slashes
|
||||
string(REPLACE "/" "\\" GROUP "${GROUP}")
|
||||
# Group into "Source Files" and "Header Files"
|
||||
set(GROUP "${GROUP}")
|
||||
source_group("${GROUP}" FILES "${fileItem}")
|
||||
endforeach()
|
||||
|
||||
set(${out_files} ${RESULT} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
add_subdirectory(core)
|
||||
add_subdirectory(third_party/imgui)
|
||||
add_subdirectory(third_party/sdl)
|
||||
add_subdirectory(third_party/portaudio)
|
||||
add_subdirectory(third_party/spdlog)
|
||||
add_subdirectory(third_party/HLSLcc)
|
||||
|
||||
# setup portaudio
|
||||
set(PA_USE_ASIO ON CACHE BOOL "" FORCE)
|
||||
set(PA_BUILD_SHARED_LIBS ON CACHE BOOL "" FORCE)
|
||||
|
||||
if (WIN32)
|
||||
set(PA_USE_WMME OFF CACHE BOOL "" FORCE)
|
||||
set(PA_USE_WDMKS OFF CACHE BOOL "" FORCE)
|
||||
set(PA_USE_WDMKS_DEVICE_INFO OFF CACHE BOOL "" FORCE)
|
||||
set(PA_USE_DS OFF CACHE BOOL "" FORCE)
|
||||
elseif(APPLE)
|
||||
set(PA_USE_COREAUDIO ON CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
|
||||
# setup SDL
|
||||
set(SDL_ASSEMBLY OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_ATOMIC OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_AUDIO OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_AVX OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_AVX2 OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_AVX512F OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_CPUINFO OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_DIRECTX OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_DISKAUDIO OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_DUMMYAUDIO OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_DUMMYVIDEO OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_FILE OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_FILESYSTEM OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_HAPTIC OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_HIDAPI OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_HIDAPI_JOYSTICK OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_JOYSTICK OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_LIBUDEV OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_LOCALE OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_MISC OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_MMX OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_OFFSCREEN OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_OPENGLES OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_POWER OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_RENDER OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_RENDER_D3D OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_SENSOR OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_SSE OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_SSE2 OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_SSE3 OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_SSE4_1 OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_SSE4_2 OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_TEST OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_TIMERS OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_VIRTUAL_JOYSTICK OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_TEST_LIBRARY OFF CACHE BOOL "" FORCE)
|
||||
|
||||
if (WIN32 OR (UNIX AND NOT APPLE))
|
||||
set(SDL_VULKAN ON CACHE BOOL "" FORCE)
|
||||
else()
|
||||
set(SDL_VULKAN OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_METAL ON CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
|
||||
set(SDL_WASAPI OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_XINPUT OFF CACHE BOOL "" FORCE)
|
||||
set(SDL_DISABLE_UNINSTALL ON CACHE BOOL "" FORCE)
|
||||
set(SDL_OPENGL OFF CACHE BOOL "" FORCE)
|
||||
|
||||
|
||||
# setup spdlog
|
||||
set(SPDLOG_BUILD_SHARED ON CACHE BOOL "" FORCE)
|
||||
set(SPDLOG_BUILD_EXAMPLE OFF CACHE BOOL "" FORCE)
|
||||
set(SPDLOG_BUILD_TESTS OFF CACHE BOOL "" FORCE)
|
||||
set(SPDLOG_BUILD_BENCH OFF CACHE BOOL "" FORCE)
|
||||
set(SPDLOG_FMT_EXTERNAL OFF CACHE BOOL "" FORCE)
|
||||
set(SPDLOG_FMT_EXTERNAL_HO OFF CACHE BOOL "" FORCE)
|
||||
set(SPDLOG_WCHAR_SUPPORT ON CACHE BOOL "" FORCE)
|
||||
set(SPDLOG_ENABLE_PCH ON CACHE BOOL "" FORCE)
|
||||
set(SPDLOG_USE_STD_FORMAT OFF CACHE BOOL "" FORCE)
|
||||
|
||||
# install
|
||||
install(DIRECTORY ${CMAKE_SOURCE_DIR}/third_party/imgui/imgui/misc/fonts DESTINATION ${CMAKE_BINARY_DIR}/bin)
|
18
core/CMakeLists.txt
Normal file
18
core/CMakeLists.txt
Normal file
@ -0,0 +1,18 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(core)
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
|
||||
set(ALL_FILES "")
|
||||
retrieve_files(ALL_FILES)
|
||||
|
||||
add_library(${PROJECT_NAME} SHARED ${ALL_FILES})
|
||||
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} spdlog imgui HLSLcc)
|
||||
|
||||
target_link_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} spdlog imgui HLSLcc)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC imgui spdlog ${SDL2_LIBRARIES} HLSLcc)
|
||||
|
||||
|
||||
target_precompile_headers(${PROJECT_NAME} PUBLIC extern.h)
|
||||
add_definitions(-Dcore_EXPORTS -DSTB_IMAGE_IMPLEMENTATION -DSTBI_WINDOWS_UTF8)
|
183
core/application/application.cpp
Normal file
183
core/application/application.cpp
Normal file
@ -0,0 +1,183 @@
|
||||
#include "application.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
|
||||
#include "command_line.h"
|
||||
#include "imgui_impl_sdl3.h"
|
||||
#include "imgui_internal.h"
|
||||
#include "filesystem/stb_image.h"
|
||||
#include "rhi/texture.h"
|
||||
#include "spdlog/async.h"
|
||||
#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;
|
||||
|
||||
application::~application()
|
||||
{
|
||||
application::shutdown();
|
||||
}
|
||||
|
||||
void application::init(window_params in_window_params, int argc, char** argv)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto async_file = spdlog::basic_logger_mt<spdlog::async_factory>("async_file_logger", "logs/log.txt");
|
||||
}
|
||||
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;
|
||||
|
||||
#if WIN32
|
||||
bool use_dx11 = false;
|
||||
bool use_dx12 = false;
|
||||
bool use_vulkan = false;
|
||||
#else
|
||||
bool use_vulkan = true;
|
||||
#endif
|
||||
|
||||
#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);
|
||||
// only one renderer can be used at a time
|
||||
const int renderer_count = use_dx11 + use_dx12 + use_vulkan;
|
||||
assert(renderer_count <= 1);
|
||||
|
||||
// if no renderer is specified, use dx11
|
||||
if (!(use_dx11 || use_dx12 || use_vulkan))
|
||||
{
|
||||
use_dx11 = true;
|
||||
}
|
||||
|
||||
if (use_dx11)
|
||||
{
|
||||
renderer_ = new renderer_dx11();
|
||||
}
|
||||
// if (use_dx12)
|
||||
// {
|
||||
// renderer_ = new renderer_dx12();
|
||||
// }
|
||||
// if (use_vulkan)
|
||||
// {
|
||||
// renderer_ = new renderer_vulkan();
|
||||
// window_flags |= SDL_WINDOW_VULKAN;
|
||||
// }
|
||||
#else
|
||||
if (use_vulkan)
|
||||
{
|
||||
renderer_ = new renderer_vulkan();
|
||||
window_flags |= SDL_WINDOW_VULKAN;
|
||||
}
|
||||
#endif
|
||||
|
||||
// if (!renderer_)
|
||||
// renderer_ = new renderer_null();
|
||||
|
||||
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());
|
||||
return;
|
||||
}
|
||||
SDL_SetWindowPosition(window_, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
||||
SDL_ShowWindow(window_);
|
||||
|
||||
renderer_->init(window_);
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (g_exit_requested)
|
||||
break;
|
||||
|
||||
renderer_->new_frame();
|
||||
draw_gui();
|
||||
renderer_->end_frame();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void application::shutdown()
|
||||
{
|
||||
renderer_->shutdown();
|
||||
ImGui::DestroyContext();
|
||||
|
||||
delete renderer_;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
spdlog::error("Failed to load texture: {}", path.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
const auto texture = renderer_->create_texture(image_data, width, height);
|
||||
stbi_image_free(image_data);
|
||||
return texture;
|
||||
}
|
||||
|
||||
texture* application::create_texture(const unsigned char* data, const int width, const int height) const
|
||||
{
|
||||
return renderer_->create_texture(data, width, height);
|
||||
}
|
47
core/application/application.h
Normal file
47
core/application/application.h
Normal file
@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "SDL.h"
|
||||
#include "imgui.h"
|
||||
|
||||
class renderer;
|
||||
class texture;
|
||||
|
||||
extern bool g_is_running;
|
||||
extern bool g_exit_requested;
|
||||
|
||||
struct window_params
|
||||
{
|
||||
std::string title;
|
||||
int width;
|
||||
int height;
|
||||
bool fullscreen;
|
||||
bool borderless;
|
||||
bool resizable;
|
||||
bool minimized;
|
||||
bool maximized;
|
||||
bool hi_dpi;
|
||||
bool always_on_top;
|
||||
};
|
||||
|
||||
class CORE_API application
|
||||
{
|
||||
public:
|
||||
application() = default;
|
||||
virtual ~application();
|
||||
application(const application&) = delete;
|
||||
application(application&&) = delete;
|
||||
|
||||
virtual void init(window_params in_window_params, int argc, char** argv);
|
||||
virtual int run();
|
||||
virtual void shutdown();
|
||||
virtual void draw_gui() = 0;
|
||||
virtual void init_imgui(ImGuiContext* in_context) = 0;
|
||||
texture* load_texture(const std::string& path) const;
|
||||
texture* create_texture(const unsigned char* data, const int width, const int height) const;
|
||||
|
||||
renderer* get_renderer() const { return renderer_; }
|
||||
SDL_Window* get_window() const { return window_; }
|
||||
protected:
|
||||
renderer* renderer_ = nullptr;
|
||||
SDL_Window* window_ = nullptr;
|
||||
};
|
78
core/application/command_line.cpp
Normal file
78
core/application/command_line.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
#include "command_line.h"
|
||||
|
||||
void command_line::init(int argc, char** argv)
|
||||
{
|
||||
// parser argv
|
||||
args_.clear();
|
||||
for (int i = 0; i < argc; ++i)
|
||||
{
|
||||
std::string arg = argv[i];
|
||||
if (arg[0] == '-')
|
||||
{
|
||||
std::string key = arg.substr(1);
|
||||
std::string value;
|
||||
if (i + 1 < argc)
|
||||
{
|
||||
std::string next_arg = argv[i + 1];
|
||||
if (next_arg[0] != '-')
|
||||
{
|
||||
value = next_arg;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
args_[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void command_line::get_arg(const std::string& key, std::string& out) const
|
||||
{
|
||||
const auto it = args_.find(key);
|
||||
if (it != args_.end())
|
||||
{
|
||||
out = it->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
out = "";
|
||||
}
|
||||
}
|
||||
|
||||
void command_line::get_arg(const std::string& key, int& out) const
|
||||
{
|
||||
const auto it = args_.find(key);
|
||||
if (it != args_.end())
|
||||
{
|
||||
out = std::stoi(it->second);
|
||||
}
|
||||
else
|
||||
{
|
||||
out = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void command_line::get_arg(const std::string& key, float& out) const
|
||||
{
|
||||
const auto it = args_.find(key);
|
||||
if (it != args_.end())
|
||||
{
|
||||
out = std::stof(it->second);
|
||||
}
|
||||
else
|
||||
{
|
||||
out = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void command_line::get_arg(const std::string& key, bool& out) const
|
||||
{
|
||||
const auto it = args_.find(key);
|
||||
if (it != args_.end())
|
||||
{
|
||||
out = it->second != "false";
|
||||
}
|
||||
else
|
||||
{
|
||||
out = false;
|
||||
}
|
||||
}
|
21
core/application/command_line.h
Normal file
21
core/application/command_line.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
class command_line
|
||||
{
|
||||
public:
|
||||
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;
|
||||
private:
|
||||
std::map<std::string, std::string> args_; // key-value pairs
|
||||
command_line() = default;
|
||||
};
|
9
core/extern.h
Normal file
9
core/extern.h
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "rhi/rhi_defintion.h"
|
||||
|
||||
#ifdef core_EXPORTS
|
||||
#define CORE_API __declspec(dllexport)
|
||||
#else
|
||||
#define CORE_API __declspec(dllimport)
|
||||
#endif
|
7986
core/filesystem/stb_image.h
Normal file
7986
core/filesystem/stb_image.h
Normal file
File diff suppressed because it is too large
Load Diff
2
core/misc/ref_counting.cpp
Normal file
2
core/misc/ref_counting.cpp
Normal file
@ -0,0 +1,2 @@
|
||||
#include "E:/Projects/Arona/build/core/CMakeFiles/core.dir/Debug/cmake_pch.hxx"
|
||||
#include "ref_counting.h"
|
207
core/misc/ref_counting.h
Normal file
207
core/misc/ref_counting.h
Normal file
@ -0,0 +1,207 @@
|
||||
#pragma once
|
||||
#include <assert.h>
|
||||
|
||||
/**
|
||||
* A smart pointer to an object which implements AddRef/Release.
|
||||
*/
|
||||
template<typename ReferencedType>
|
||||
class ref_count_ptr
|
||||
{
|
||||
typedef ReferencedType* reference_type;
|
||||
|
||||
public:
|
||||
|
||||
ref_count_ptr():
|
||||
reference_(nullptr)
|
||||
{ }
|
||||
|
||||
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& copy)
|
||||
{
|
||||
reference_ = copy.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;
|
||||
}
|
||||
|
||||
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& 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_;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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_;
|
||||
}
|
||||
|
||||
operator reference_type() const
|
||||
{
|
||||
return reference_;
|
||||
}
|
||||
|
||||
ReferencedType** get_init_reference()
|
||||
{
|
||||
*this = nullptr;
|
||||
return &reference_;
|
||||
}
|
||||
|
||||
ReferencedType* get_reference() const
|
||||
{
|
||||
return reference_;
|
||||
}
|
||||
|
||||
friend bool is_valid_ref(const ref_count_ptr& in_reference)
|
||||
{
|
||||
return in_reference.reference_ != nullptr;
|
||||
}
|
||||
|
||||
bool is_valid() const
|
||||
{
|
||||
return reference_ != 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;
|
||||
}
|
||||
|
||||
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;
|
||||
// }
|
||||
// }
|
||||
|
||||
private:
|
||||
|
||||
ReferencedType* reference_;
|
||||
|
||||
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==(ReferencedType* b) const
|
||||
{
|
||||
return get_reference() == b;
|
||||
}
|
||||
};
|
1
core/rhi/render_resource.cpp
Normal file
1
core/rhi/render_resource.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "render_resource.h"
|
13
core/rhi/render_resource.h
Normal file
13
core/rhi/render_resource.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include "imgui.h"
|
||||
|
||||
class 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() { ImGui::Image(get_texture_id(), ImVec2(static_cast<float>(get_width()), static_cast<float>(get_height()))); }
|
||||
};
|
1
core/rhi/render_target.cpp
Normal file
1
core/rhi/render_target.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "render_target.h"
|
37
core/rhi/render_target.h
Normal file
37
core/rhi/render_target.h
Normal file
@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
#include "render_resource.h"
|
||||
#include "rhi_defintion.h"
|
||||
|
||||
enum class lock_state
|
||||
{
|
||||
NONE,
|
||||
WRITE,
|
||||
READ,
|
||||
READ_WRITE
|
||||
};
|
||||
|
||||
class render_target : public render_resource
|
||||
{
|
||||
public:
|
||||
int get_height() const override { return height_; }
|
||||
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)
|
||||
{
|
||||
if (width_ == width && height_ == height)
|
||||
return;
|
||||
|
||||
width_ = width;
|
||||
height_ = height;
|
||||
on_resize(width, height);
|
||||
}
|
||||
|
||||
virtual void* lock(lock_state state) = 0;
|
||||
virtual void unlock() = 0;
|
||||
protected:
|
||||
virtual void on_resize(int width, int height) = 0;
|
||||
int width_ = 0;
|
||||
int height_ = 0;
|
||||
};
|
0
core/rhi/renderer.cpp
Normal file
0
core/rhi/renderer.cpp
Normal file
25
core/rhi/renderer.h
Normal file
25
core/rhi/renderer.h
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
#include <SDL_video.h>
|
||||
|
||||
class render_target;
|
||||
class texture;
|
||||
|
||||
class renderer
|
||||
{
|
||||
public:
|
||||
virtual ~renderer() = default;
|
||||
virtual bool init(SDL_Window* window_handle) = 0;
|
||||
virtual void shutdown() = 0;
|
||||
|
||||
virtual void new_frame() = 0;
|
||||
virtual void end_frame() = 0;
|
||||
|
||||
virtual void resize(int width, int height) = 0;
|
||||
virtual texture* create_texture(const unsigned char* data, int width, int height) = 0;
|
||||
virtual render_target* create_render_target(int width, int height, texture_format format) = 0;
|
||||
virtual bool compile_shader() = 0;
|
||||
|
||||
void set_vsync(const bool vsync) { vsync_ = vsync; }
|
||||
protected:
|
||||
bool vsync_ = true;
|
||||
};
|
8
core/rhi/rhi_defintion.h
Normal file
8
core/rhi/rhi_defintion.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
enum class texture_format
|
||||
{
|
||||
RGBA8,
|
||||
RGBA16_FLOAT,
|
||||
RGBA32_FLOAT,
|
||||
};
|
1
core/rhi/texture.cpp
Normal file
1
core/rhi/texture.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "texture.h"
|
21
core/rhi/texture.h
Normal file
21
core/rhi/texture.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include "imgui.h"
|
||||
#include <string>
|
||||
|
||||
#include "render_resource.h"
|
||||
|
||||
class texture : public render_resource
|
||||
{
|
||||
public:
|
||||
texture(): width_(0), 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_;
|
||||
};
|
297
core/rhi/windows/dx11/find_best_device_dx11.cpp
Normal file
297
core/rhi/windows/dx11/find_best_device_dx11.cpp
Normal file
@ -0,0 +1,297 @@
|
||||
#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 NumAllowedFeatureLevels = 2;
|
||||
HRESULT create_device_result = D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, DeviceFlags,
|
||||
requested_feature_levels, NumAllowedFeatureLevels, 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;
|
||||
}
|
37
core/rhi/windows/dx11/find_best_device_dx11.h
Normal file
37
core/rhi/windows/dx11/find_best_device_dx11.h
Normal file
@ -0,0 +1,37 @@
|
||||
#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_;
|
||||
};
|
177
core/rhi/windows/dx11/render_target_dx11.cpp
Normal file
177
core/rhi/windows/dx11/render_target_dx11.cpp
Normal file
@ -0,0 +1,177 @@
|
||||
#include "render_target_dx11.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "renderer_dx11.h"
|
||||
#include "rhi/windows/dx_format.h"
|
||||
|
||||
render_target_dx11::render_target_dx11() : lock_state_(lock_state::NONE)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
render_target_dx11::~render_target_dx11()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void render_target_dx11::init(int width, int height, texture_format format)
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC texture_desc;
|
||||
texture_desc.Width = width;
|
||||
texture_desc.Height = height;
|
||||
texture_desc.MipLevels = 1;
|
||||
texture_desc.ArraySize = 1;
|
||||
texture_desc.Format = ToDXFormat(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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
27
core/rhi/windows/dx11/render_target_dx11.h
Normal file
27
core/rhi/windows/dx11/render_target_dx11.h
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
#include "rhi/render_target.h"
|
||||
#include <d3d11.h>
|
||||
|
||||
#include "misc/ref_counting.h"
|
||||
|
||||
class render_target_dx11 : public render_target
|
||||
{
|
||||
public:
|
||||
render_target_dx11();
|
||||
~render_target_dx11() override;
|
||||
|
||||
void init(int width, int height, texture_format format) override;
|
||||
ImTextureID get_texture_id() override { return shader_resource_view_; }
|
||||
void* lock(lock_state state) override;
|
||||
void unlock() override;
|
||||
|
||||
void release();
|
||||
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_;
|
||||
};
|
128
core/rhi/windows/dx11/renderer_dx11.cpp
Normal file
128
core/rhi/windows/dx11/renderer_dx11.cpp
Normal file
@ -0,0 +1,128 @@
|
||||
#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 "render_target_dx11.h"
|
||||
#include "texture_dx11.h"
|
||||
#include "CompilerHlsl/compileHlsl.hpp"
|
||||
#include "ShaderWriter/VertexWriter.hpp"
|
||||
|
||||
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()
|
||||
{
|
||||
// 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::new_frame()
|
||||
{
|
||||
// Start the Dear ImGui frame
|
||||
ImGui_ImplDX11_NewFrame();
|
||||
ImGui_ImplSDL3_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
}
|
||||
|
||||
void renderer_dx11::end_frame()
|
||||
{
|
||||
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 };
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
texture* renderer_dx11::create_texture(const unsigned char* data, const int width, const int height)
|
||||
{
|
||||
auto out = new texture_dx11();
|
||||
if (!out->init_data(data, width, height))
|
||||
{
|
||||
delete out;
|
||||
out = nullptr;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
render_target* renderer_dx11::create_render_target(int width, int height, texture_format format)
|
||||
{
|
||||
const auto target_dx11 = new render_target_dx11();
|
||||
target_dx11->init(width, height, format);
|
||||
return target_dx11;
|
||||
}
|
||||
|
||||
bool renderer_dx11::compile_shader()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
30
core/rhi/windows/dx11/renderer_dx11.h
Normal file
30
core/rhi/windows/dx11/renderer_dx11.h
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
#include <d3d11.h>
|
||||
|
||||
#include "misc/ref_counting.h"
|
||||
#include "rhi/renderer.h"
|
||||
|
||||
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 new_frame() override;
|
||||
void end_frame() override;
|
||||
|
||||
void resize(int width, int height) override;
|
||||
texture* create_texture(const unsigned char* data, int width, int height) override;
|
||||
render_target* create_render_target(int width, int height, texture_format format) override;
|
||||
bool compile_shader() override;
|
||||
protected:
|
||||
void create_render_target();
|
||||
bool create_device(HWND in_hwnd);
|
||||
bool has_initialized_ = false;
|
||||
};
|
49
core/rhi/windows/dx11/texture_dx11.cpp
Normal file
49
core/rhi/windows/dx11/texture_dx11.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
#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;
|
||||
}
|
15
core/rhi/windows/dx11/texture_dx11.h
Normal file
15
core/rhi/windows/dx11/texture_dx11.h
Normal file
@ -0,0 +1,15 @@
|
||||
#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_; }
|
||||
bool init_data(const unsigned char* data, int width, int height) override;
|
||||
[[nodiscard]] bool is_valid() const override { return shader_resource_view_.is_valid(); }
|
||||
private:
|
||||
ref_count_ptr<ID3D11ShaderResourceView> shader_resource_view_;
|
||||
};
|
18
core/rhi/windows/dx_format.h
Normal file
18
core/rhi/windows/dx_format.h
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include <dxgiformat.h>
|
||||
|
||||
#include "rhi/rhi_defintion.h"
|
||||
|
||||
DXGI_FORMAT ToDXFormat(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;
|
||||
}
|
||||
return DXGI_FORMAT_UNKNOWN;
|
||||
}
|
1
third_party/HLSLcc
vendored
Submodule
1
third_party/HLSLcc
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 3ea1fcd6bd0ac445bc078de0bf32f0950188577b
|
55
third_party/imgui/CMakeLists.txt
vendored
Normal file
55
third_party/imgui/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
project(imgui)
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
|
||||
add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")
|
||||
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
|
||||
|
||||
add_library(${PROJECT_NAME} STATIC
|
||||
imgui/imgui.cpp
|
||||
imgui/imgui.h
|
||||
imgui/imgui_draw.cpp
|
||||
imgui/imgui_internal.h
|
||||
imgui/imconfig.h
|
||||
imgui/imgui_widgets.cpp
|
||||
imgui/imstb_rectpack.h
|
||||
imgui/imstb_textedit.h
|
||||
imgui/imstb_truetype.h
|
||||
imgui/imgui_tables.cpp
|
||||
)
|
||||
|
||||
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_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)
|
||||
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
|
||||
)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC vulkan SDL3-shared)
|
||||
elseif(APPLE)
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
imgui/backends/imgui_impl_sdl3.cpp
|
||||
imgui/backends/imgui_impl_sdl3.h
|
||||
imgui/backends/imgui_impl_metal.h
|
||||
imgui/backends/imgui_impl_metal.mm
|
||||
)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC vulkan SDL3-shared)
|
||||
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)
|
1
third_party/imgui/imgui
vendored
Submodule
1
third_party/imgui/imgui
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 96839b445e32e46d87a44fd43a9cdd60c806f7e1
|
1
third_party/portaudio
vendored
Submodule
1
third_party/portaudio
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit daaf637f6f9fce670031221abfd7dfde92e5cce3
|
1
third_party/sdl
vendored
Submodule
1
third_party/sdl
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 7fbd85ad5cf30d46ef20628a212bbec3c1ffec2b
|
1
third_party/spdlog
vendored
Submodule
1
third_party/spdlog
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 696db97f672e9082e50e50af315d0f4234c82397
|
Loading…
x
Reference in New Issue
Block a user