新增dx11 shader支持

This commit is contained in:
Nanako 2024-02-02 00:37:22 +08:00
parent bbd2b83e7a
commit 2f6c08adb2
44 changed files with 35050 additions and 103 deletions

View File

@ -62,6 +62,7 @@ add_subdirectory(third_party/sdl)
add_subdirectory(third_party/portaudio)
add_subdirectory(third_party/spdlog)
add_subdirectory(third_party/slang)
add_subdirectory(third_party/glad)
# setup portaudio
set(PA_USE_ASIO ON CACHE BOOL "" FORCE)

View File

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

View File

@ -20,6 +20,7 @@
bool g_is_running = true;
bool g_exit_requested = false;
slang::IGlobalSession* g_slang_global_session = nullptr;
application* g_app_instance = nullptr;
application::~application()
{
@ -58,6 +59,10 @@ void application::init(window_params in_window_params, int argc, char** argv)
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;
@ -97,7 +102,39 @@ void application::init(window_params in_window_params, int argc, char** argv)
// 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();
@ -201,3 +238,8 @@ std::shared_ptr<texture> application::create_texture(const unsigned char* data,
{
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
{
return renderer_->create_render_target(width, height, format);
}

View File

@ -4,6 +4,7 @@
#include "imgui.h"
#include "slang.h"
class render_target;
class renderer;
class texture;
class application;
@ -11,7 +12,7 @@ class application;
extern bool g_is_running;
extern bool g_exit_requested;
extern slang::IGlobalSession* g_slang_global_session;
static application* g_app_instance = nullptr;
extern application* g_app_instance;
struct window_params
{
@ -49,6 +50,7 @@ public:
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;
renderer* get_renderer() const { return renderer_; }
SDL_Window* get_window() const { return window_; }

View File

@ -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)

View File

@ -7,45 +7,24 @@
spdlog::critical("GL error: 0x{:x}", Error);\
}
#define GL_READ_FRAMEBUFFER 0x8CA8
#define GL_DRAW_FRAMEBUFFER 0x8CA9
#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA
#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF
#define GL_COLOR_ATTACHMENT0 0x8CE0
#define GL_COLOR_ATTACHMENT1 0x8CE1
#define GL_COLOR_ATTACHMENT2 0x8CE2
#define GL_COLOR_ATTACHMENT3 0x8CE3
#define GL_COLOR_ATTACHMENT4 0x8CE4
#define GL_COLOR_ATTACHMENT5 0x8CE5
#define GL_COLOR_ATTACHMENT6 0x8CE6
#define GL_COLOR_ATTACHMENT7 0x8CE7
#define GL_COLOR_ATTACHMENT8 0x8CE8
#define GL_COLOR_ATTACHMENT9 0x8CE9
#define GL_COLOR_ATTACHMENT10 0x8CEA
#define GL_COLOR_ATTACHMENT11 0x8CEB
#define GL_COLOR_ATTACHMENT12 0x8CEC
#define GL_COLOR_ATTACHMENT13 0x8CED
#define GL_COLOR_ATTACHMENT14 0x8CEE
#define GL_COLOR_ATTACHMENT15 0x8CEF
#define GL_COLOR_ATTACHMENT16 0x8CF0
#define GL_COLOR_ATTACHMENT17 0x8CF1
#define GL_COLOR_ATTACHMENT18 0x8CF2
#define GL_COLOR_ATTACHMENT19 0x8CF3
#define GL_COLOR_ATTACHMENT20 0x8CF4
#define GL_COLOR_ATTACHMENT21 0x8CF5
#define GL_COLOR_ATTACHMENT22 0x8CF6
#define GL_COLOR_ATTACHMENT23 0x8CF7
#define GL_COLOR_ATTACHMENT24 0x8CF8
#define GL_COLOR_ATTACHMENT25 0x8CF9
#define GL_COLOR_ATTACHMENT26 0x8CFA
#define GL_COLOR_ATTACHMENT27 0x8CFB
#define GL_COLOR_ATTACHMENT28 0x8CFC
#define GL_COLOR_ATTACHMENT29 0x8CFD
#define GL_COLOR_ATTACHMENT30 0x8CFE
#define GL_COLOR_ATTACHMENT31 0x8CFF
#define GL_DEPTH_ATTACHMENT 0x8D00
#define GL_STENCIL_ATTACHMENT 0x8D20
#define GL_COMPUTE_SHADER 0x91B9
#define GL_GEOMETRY_SHADER 0x8DD9
struct im_gui_impl_open_gl3_data
{
GLuint GlVersion; // Extracted at runtime using GL_MAJOR_VERSION, GL_MINOR_VERSION queries (e.g. 320 for GL 3.2)
char GlslVersionString[32]; // Specified by user or detected based on compile time GL settings.
bool GlProfileIsES2;
bool GlProfileIsES3;
bool GlProfileIsCompat;
GLint GlProfileMask;
GLuint FontTexture;
GLuint ShaderHandle;
GLint AttribLocationTex; // Uniforms location
GLint AttribLocationProjMtx;
GLuint AttribLocationVtxPos; // Vertex attributes location
GLuint AttribLocationVtxUV;
GLuint AttribLocationVtxColor;
unsigned int VboHandle, ElementsHandle;
GLsizeiptr VertexBufferSize;
GLsizeiptr IndexBufferSize;
bool HasClipOrigin;
bool UseBufferSubData;
};

View File

@ -1,19 +0,0 @@
#pragma once
typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers);
typedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer);
typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
typedef void (APIENTRYP PFNGLGETTEXIMAGEPROC) (GLenum target, GLint level, GLenum format, GLenum type, void *pixels);
inline PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
inline PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
inline PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
inline PFNGLGETTEXIMAGEPROC glGetTexImage;
inline void load_opengl_func()
{
glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)imgl3wGetProcAddress("glGenFramebuffers");
glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)imgl3wGetProcAddress("glBindFramebuffer");
glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)imgl3wGetProcAddress("glFramebufferTexture2D");
glGetTexImage = (PFNGLGETTEXIMAGEPROC)imgl3wGetProcAddress("glGetTexImage");
}

View File

@ -1,7 +1,6 @@
#include "render_target_opengl.h"
#include "opengl_def.h"
#include "opengl_func.h"
void render_target_opengl::init(int width, int height, texture_format format)
{

View File

@ -1,5 +1,6 @@
#pragma once
#include "imgui_impl_opengl3_loader.h"
#include <SDL_opengl.h>
#include "rhi/render_target.h"
class render_target_opengl : public render_target

View File

@ -3,9 +3,7 @@
#include <SDL_hints.h>
#include "imgui_impl_opengl3.h"
#include "imgui_impl_opengl3_loader.h"
#include "imgui_impl_sdl3.h"
#include "opengl_func.h"
#include "render_target_opengl.h"
#include "texture_opengl.h"
#include "application/application.h"
@ -37,16 +35,20 @@ void renderer_opengl::pre_init()
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)
{
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");
}
SDL_GL_MakeCurrent(window_handle, g_gl_context);
SDL_GL_SetSwapInterval(1); // Enable vsync
SDL_ShowWindow(window_handle);
@ -54,7 +56,6 @@ bool renderer_opengl::init(SDL_Window* window_handle)
// Setup Platform/Renderer backends
ImGui_ImplSDL3_InitForOpenGL(window_handle, g_gl_context);
ImGui_ImplOpenGL3_Init(glsl_version);
load_opengl_func();
return true;
}

View File

@ -1,7 +1,8 @@
#include "shader_opengl.h"
#include "imgui_impl_opengl3_loader.h"
#include "imgui.h"
#include "rhi/slang_handle.h"
#include "rhi/opengl/opengl_def.h"
bool shader_opengl::init()
{
@ -15,7 +16,8 @@ bool shader_opengl::init()
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);
glCompileShader(shader_id_);
GLint compile_status = GL_FALSE;
glGetShaderiv(shader_id_, GL_COMPILE_STATUS, &compile_status);
if (compile_status == GL_FALSE)
@ -33,3 +35,15 @@ bool shader_opengl::init()
return true;
}
void shader_opengl::bind()
{
glUseProgram(shader_id_);
}
void shader_opengl::unbind()
{
const ImGuiIO& io = ImGui::GetIO();
const auto open_gl3_data = static_cast<im_gui_impl_open_gl3_data*>(io.BackendRendererUserData);
glUseProgram(open_gl3_data->ShaderHandle);
}

View File

@ -1,5 +1,4 @@
#pragma once
#include "imgui_impl_opengl3_loader.h"
#include "rhi/shader.h"
class shader_opengl : public shader
@ -8,8 +7,15 @@ public:
shader_opengl(const std::shared_ptr<slang_handle>& handle) : shader(handle) {}
bool init() override;
[[nodiscard]] virtual GLenum get_shader_type() const = 0;
[[nodiscard]] bool is_initialized() const override { return shader_id_ != 0; }
void bind() override;
void unbind() override;
void set_constant_buffer(const char* name, void* buffer, int size) override {}
void set_render_target(const char* name, std::shared_ptr<render_target> in_render_target) override {}
void set_texture(const char* name, std::shared_ptr<texture> in_texture) override {}
[[nodiscard]] virtual GLenum get_shader_type() const = 0;
protected:
GLuint shader_id_;
};

View File

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

View File

@ -1,5 +1,6 @@
#pragma once
#include "imgui_impl_opengl3_loader.h"
#include <SDL_opengl.h>
#include "rhi/texture.h"
class texture_opengl : public texture

View File

@ -9,5 +9,8 @@ public:
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()))); }
void draw()
{
ImGui::Image(get_texture_id(), ImVec2(static_cast<float>(get_width()), static_cast<float>(get_height())));
}
};

View File

@ -13,8 +13,8 @@ enum class lock_state
class render_target : public render_resource
{
public:
int get_height() const override { return height_; }
int get_width() const override { return width_; }
[[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;

View File

@ -1,5 +1,7 @@
#pragma once
class render_target;
class texture;
class slang_handle;
class shader
@ -12,8 +14,38 @@ public:
[[nodiscard]] virtual bool is_initialized() const = 0;
[[nodiscard]] virtual bool is_valid() const { return handle_ != nullptr && is_initialized(); }
virtual void bind() = 0;
virtual void unbind() = 0;
virtual void compute(int x, int y, int z) {}
virtual void draw(int width, int height) {}
// param setters
// virtual void set_int(const char* name, int value) = 0;
virtual void set_constant_buffer(const char* name, void* buffer, int size) = 0;
virtual void set_uav_buffer(const char* name, void* buffer, int size, int element_size) {}
virtual void set_texture(const char* name, std::shared_ptr<texture> in_texture) = 0;
virtual void set_render_target(const char* name, std::shared_ptr<render_target> in_render_target) = 0;
template<typename T>
void set_constant_buffer(const char* name, const T& buffer)
{
set_constant_buffer(name, (void*)&buffer, sizeof(T));
}
template<typename T>
void set_constant_buffer(const char* name, const std::vector<T>& buffer)
{
set_constant_buffer(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(T));
}
template<typename T>
void set_uav_buffer(const char* name, const std::vector<T>& buffer)
{
set_uav_buffer(name, (void*)buffer.data(), sizeof(T) * buffer.size());
}
protected:
std::shared_ptr<slang_handle> handle_;
};

View File

@ -273,10 +273,10 @@ bool find_best_device_dx11::create_testing_device(IDXGIAdapter* adapter, D3D_FEA
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);
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();

View File

@ -4,19 +4,18 @@
#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)
{
}
render_target_dx11::~render_target_dx11()
{
}
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;

View File

@ -4,14 +4,21 @@
#include "misc/ref_counting.h"
class uav_buffer_dx11;
class render_target_dx11 : public render_target
{
public:
render_target_dx11();
~render_target_dx11() override;
~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;
@ -23,5 +30,6 @@ private:
ref_count_ptr<ID3D11Texture2D> texture_;
ref_count_ptr<ID3D11RenderTargetView> render_target_view_;
ref_count_ptr<ID3D11ShaderResourceView> shader_resource_view_;
lock_state lock_state_;
};

View File

@ -0,0 +1,66 @@
#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_);
}
void update_buffer() const
{
void* data = lock();
memcpy(data, buffer_data_, element_size_);
unlock();
}
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;
};

View File

@ -1,10 +1,125 @@
#include "shader_cs_dx11.h"
#include "rhi/slang_handle.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);
if (const unsigned int constant_num = constant_buffers_.size(); constant_num > 0)
{
std::vector<ID3D11Buffer*> buffers;
buffers.reserve(constant_num);
for (const auto& buffer : constant_buffers_ | std::views::values)
{
buffers.push_back(buffer->get_resource());
}
g_d3d11_device_context->CSSetConstantBuffers(0, constant_num, buffers.data());
}
if (const size_t uav_buffer_num = uav_buffers_.size(); uav_buffer_num > 0)
{
std::vector<ID3D11UnorderedAccessView*> uavs;
uavs.reserve(uav_buffer_num);
for (const auto& buffer : uav_buffers_ | std::views::values)
{
buffer->update_buffer();
uavs.push_back(buffer->get_uav());
}
g_d3d11_device_context->CSSetUnorderedAccessViews(0, uav_buffer_num, uavs.data(), nullptr);
}
{
const unsigned int texture_num = textures_.size();
const unsigned int render_target_num = render_targets_.size();
if (const unsigned int num = texture_num + render_target_num; num > 0)
{
std::vector<ID3D11ShaderResourceView*> srvs;
srvs.reserve(num);
for (const auto& texture : textures_ | std::views::values)
{
srvs.push_back(texture->get_srv());
}
for (const auto& render_target : render_targets_ | std::views::values)
{
srvs.push_back(render_target->get_srv());
}
g_d3d11_device_context->CSSetShaderResources(0, texture_num, srvs.data());
}
}
}
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 find = uav_buffers_.find(name);
if (find == uav_buffers_.end())
{
auto uav_buffer = std::make_shared<uav_buffer_dx11>();
uav_buffer->create(buffer, size, element_size);
uav_buffers_.insert({name, uav_buffer});
return;
}
find->second->set_buffer_data(buffer, size);
}
void shader_cs_dx11::set_render_target(const char* name, std::shared_ptr<render_target> in_render_target)
{
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_buffers_.insert({name, uav_buffer});
return;
}
}
void cs_dx11_compute_callback(const ImDrawList* parent_list, const ImDrawCmd* cmd)
{
const shader_cs_dx11::dx11_cs_data* data = static_cast<shader_cs_dx11::dx11_cs_data*>(cmd->UserCallbackData);
data->cs->bind();
g_d3d11_device_context->Dispatch(data->x, data->y, data->z);
data->cs->unbind();
}
void shader_cs_dx11::compute(int x, int y, int z)
{
cs_data.x = x;
cs_data.y = y;
cs_data.z = z;
ImGui::GetWindowDrawList()->AddCallback(cs_dx11_compute_callback, &cs_data);
}

View File

@ -6,15 +6,36 @@ class shader_cs_dx11 : public shader_dx11
{
public:
explicit shader_cs_dx11(const std::shared_ptr<slang_handle>& handle)
: shader_dx11(handle)
: shader_dx11(handle), cs_data({ this, 0, 0, 0 })
{
}
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;
struct dx11_cs_data
{
shader_cs_dx11* cs;
int x;
int y;
int z;
} cs_data;
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;
};

View File

@ -1,5 +1,63 @@
#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);
if (const unsigned int constant_num = constant_buffers_.size(); constant_num > 0)
{
std::vector<ID3D11Buffer*> buffers;
buffers.reserve(constant_num);
for (const auto& buffer : constant_buffers_ | std::views::values)
{
buffers.push_back(buffer->get_resource());
}
g_d3d11_device_context->DSSetConstantBuffers(0, constant_num, buffers.data());
}
{
const size_t render_target_num = render_targets_.size();
const size_t texture_num = textures_.size();
if (const unsigned int num = render_target_num + texture_num; num > 0)
{
std::vector<ID3D11ShaderResourceView*> srvs;
srvs.reserve(num);
for (const auto& texture : textures_ | std::views::values)
{
srvs.push_back(texture->get_srv());
}
for (const auto& render_target : render_targets_ | std::views::values)
{
srvs.push_back(render_target->get_srv());
}
g_d3d11_device_context->DSSetShaderResources(0, texture_num, srvs.data());
}
}
}
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());

View File

@ -9,7 +9,8 @@ public:
: 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_; }
@ -17,4 +18,8 @@ public:
[[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;
};

View File

@ -2,9 +2,13 @@
#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()
{
@ -60,3 +64,39 @@ bool shader_dx11::init()
return true;
}
void shader_dx11::set_constant_buffer(const char* name, void* buffer, int size)
{
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_buffers_.insert({name, constant_buffer});
find = constant_buffers_.find(name);
}
find->second->set_buffer_data(buffer);
}
void shader_dx11::set_texture(const char* name, std::shared_ptr<texture> in_texture)
{
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())
{
textures_.insert({name, dx11_t});
return;
}
}
void shader_dx11::set_render_target(const char* name, std::shared_ptr<render_target> in_render_target)
{
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())
{
render_targets_.insert({name, rt});
return;
}
}

View File

@ -1,6 +1,12 @@
#pragma once
#include "rhi/shader.h"
#include <d3d11.h>
#include <map>
class render_target_dx11;
class texture_dx11;
class uav_buffer_dx11;
class constant_buffer_dx11;
class shader_dx11 : public shader
{
@ -11,8 +17,17 @@ public:
}
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_constant_buffer(const char* name, void* buffer, int size) override;
void set_texture(const char* name, std::shared_ptr<texture> in_texture) override;
void set_render_target(const char* name, std::shared_ptr<render_target> in_render_target) override;
protected:
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_;
};

View File

@ -1,5 +1,63 @@
#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);
if (const unsigned int constant_num = constant_buffers_.size(); constant_num > 0)
{
std::vector<ID3D11Buffer*> buffers;
buffers.reserve(constant_num);
for (const auto& buffer : constant_buffers_ | std::views::values)
{
buffers.push_back(buffer->get_resource());
}
g_d3d11_device_context->GSSetConstantBuffers(0, constant_num, buffers.data());
}
{
const size_t render_target_num = render_targets_.size();
const size_t texture_num = textures_.size();
if (const unsigned int num = render_target_num + texture_num; num > 0)
{
std::vector<ID3D11ShaderResourceView*> srvs;
srvs.reserve(num);
for (const auto& texture : textures_ | std::views::values)
{
srvs.push_back(texture->get_srv());
}
for (const auto& render_target : render_targets_ | std::views::values)
{
srvs.push_back(render_target->get_srv());
}
g_d3d11_device_context->GSSetShaderResources(0, texture_num, srvs.data());
}
}
}
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());

View File

@ -9,7 +9,8 @@ public:
: 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_; }
@ -17,4 +18,8 @@ public:
[[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;
};

View File

@ -1,5 +1,63 @@
#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);
if (const unsigned int constant_num = constant_buffers_.size(); constant_num > 0)
{
std::vector<ID3D11Buffer*> buffers;
buffers.reserve(constant_num);
for (const auto& buffer : constant_buffers_ | std::views::values)
{
buffers.push_back(buffer->get_resource());
}
g_d3d11_device_context->HSSetConstantBuffers(0, constant_num, buffers.data());
}
{
const size_t render_target_num = render_targets_.size();
const size_t texture_num = textures_.size();
if (const unsigned int num = render_target_num + texture_num; num > 0)
{
std::vector<ID3D11ShaderResourceView*> srvs;
srvs.reserve(num);
for (const auto& texture : textures_ | std::views::values)
{
srvs.push_back(texture->get_srv());
}
for (const auto& render_target : render_targets_ | std::views::values)
{
srvs.push_back(render_target->get_srv());
}
g_d3d11_device_context->HSSetShaderResources(0, texture_num, srvs.data());
}
}
}
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());

View File

@ -10,6 +10,8 @@ public:
{
}
void bind() override;
void unbind() override;
HRESULT create_shader(ID3DBlob* blob, ID3D11Device* device) override;
[[nodiscard]] ID3D11DeviceChild* get_shader() override { return hull_shader_; }
@ -17,4 +19,8 @@ public:
[[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;
};

View File

@ -1,5 +1,64 @@
#include "shader_ps_dx11.h"
#include <ranges>
#include "constant_buffer_dx11.h"
#include "uav_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_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);
if (const unsigned int constant_num = constant_buffers_.size(); constant_num > 0)
{
std::vector<ID3D11Buffer*> buffers;
buffers.reserve(constant_num);
for (const auto& buffer : constant_buffers_ | std::views::values)
{
buffers.push_back(buffer->get_resource());
}
g_d3d11_device_context->PSSetConstantBuffers(0, constant_num, buffers.data());
}
{
const size_t render_target_num = render_targets_.size();
const size_t texture_num = textures_.size();
if (const unsigned int num = render_target_num + texture_num; num > 0)
{
std::vector<ID3D11ShaderResourceView*> srvs;
srvs.reserve(num);
for (const auto& texture : textures_ | std::views::values)
{
srvs.push_back(texture->get_srv());
}
for (const auto& render_target : render_targets_ | std::views::values)
{
srvs.push_back(render_target->get_srv());
}
g_d3d11_device_context->PSSetShaderResources(0, texture_num, srvs.data());
}
}
}
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());

View File

@ -9,6 +9,8 @@ public:
: shader_dx11(handle)
{
}
void bind() override;
void unbind() override;
HRESULT create_shader(ID3DBlob* blob, ID3D11Device* device) override;
@ -17,4 +19,8 @@ public:
[[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;
};

View File

@ -1,5 +1,63 @@
#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->VSSetShader(vertex_shader_, nullptr, 0);
if (const unsigned int constant_num = constant_buffers_.size(); constant_num > 0)
{
std::vector<ID3D11Buffer*> buffers;
buffers.reserve(constant_num);
for (const auto& buffer : constant_buffers_ | std::views::values)
{
buffers.push_back(buffer->get_resource());
}
g_d3d11_device_context->VSSetConstantBuffers(0, constant_num, buffers.data());
}
{
const size_t render_target_num = render_targets_.size();
const size_t texture_num = textures_.size();
if (const unsigned int num = render_target_num + texture_num; num > 0)
{
std::vector<ID3D11ShaderResourceView*> srvs;
srvs.reserve(num);
for (const auto& texture : textures_ | std::views::values)
{
srvs.push_back(texture->get_srv());
}
for (const auto& render_target : render_targets_ | std::views::values)
{
srvs.push_back(render_target->get_srv());
}
g_d3d11_device_context->VSSetShaderResources(0, texture_num, srvs.data());
}
}
}
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;
}
HRESULT shader_vs_dx11::create_shader(ID3DBlob* blob, ID3D11Device* device)
{
return device->CreateVertexShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, vertex_shader_.writeRef());

View File

@ -9,7 +9,8 @@ public:
: 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_; }
@ -17,4 +18,8 @@ public:
[[nodiscard]] bool is_initialized() const override { return vertex_shader_ != nullptr; }
private:
Slang::ComPtr<ID3D11VertexShader> vertex_shader_;
ID3D11VertexShader* prev_shader_ = nullptr;
ID3D11ClassInstance** prev_class_instances_ = nullptr;
unsigned int prev_class_instances_num_ = 0;
};

View File

@ -0,0 +1,139 @@
#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;
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);
}

View File

@ -0,0 +1,34 @@
#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_; }
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
};

View File

@ -8,6 +8,7 @@ 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(); }
private:

7
third_party/glad/CMakeLists.txt vendored Normal file
View 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
View 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

File diff suppressed because one or more lines are too long

20971
third_party/glad/glad/glad.h vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -25,7 +25,6 @@ if (WIN32)
imgui/backends/imgui_impl_vulkan.h
imgui/backends/imgui_impl_opengl3.cpp
imgui/backends/imgui_impl_opengl3.h
imgui/backends/imgui_impl_opengl3_loader.h
imgui/backends/imgui_impl_dx11.h
imgui/backends/imgui_impl_dx11.cpp
imgui/backends/imgui_impl_dx12.h
@ -33,7 +32,7 @@ if (WIN32)
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)
target_link_libraries(${PROJECT_NAME} PUBLIC opengl32.lib SDL3-shared d3d11 d3dcompiler dxgi d3d12 glad)
elseif(UNIX AND NOT APPLE)
target_sources(${PROJECT_NAME} PRIVATE
imgui/backends/imgui_impl_sdl3.cpp
@ -42,9 +41,8 @@ elseif(UNIX AND NOT APPLE)
imgui/backends/imgui_impl_vulkan.h
imgui/backends/imgui_impl_opengl3.cpp
imgui/backends/imgui_impl_opengl3.h
imgui/backends/imgui_impl_opengl3_loader.h
)
target_link_libraries(${PROJECT_NAME} PUBLIC vulkan SDL3-shared)
target_link_libraries(${PROJECT_NAME} PUBLIC vulkan SDL3-shared glad)
elseif(APPLE)
target_sources(${PROJECT_NAME} PRIVATE
imgui/backends/imgui_impl_sdl3.cpp
@ -53,14 +51,18 @@ elseif(APPLE)
imgui/backends/imgui_impl_vulkan.h
imgui/backends/imgui_impl_opengl3.cpp
imgui/backends/imgui_impl_opengl3.h
imgui/backends/imgui_impl_opengl3_loader.h
imgui/backends/imgui_impl_metal.h
imgui/backends/imgui_impl_metal.mm
)
target_link_libraries(${PROJECT_NAME} PUBLIC vulkan SDL3-shared)
target_link_libraries(${PROJECT_NAME} PUBLIC vulkan SDL3-shared 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_precompile_headers(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/pch.h)
add_definitions(-DIMGUI_IMPL_OPENGL_LOADER_CUSTOM)

1
third_party/imgui/pch.h vendored Normal file
View File

@ -0,0 +1 @@
#include "glad/glad.h"