Some initial implementation.
This commit is contained in:
parent
a8813349a1
commit
31af297bab
2
external/scons-plus-plus
vendored
2
external/scons-plus-plus
vendored
@ -1 +1 @@
|
|||||||
Subproject commit bdf063a16c6bafd137f57eee780c83345887c46c
|
Subproject commit 941f94a7b6ad9242ee1404663dfd855dcf203817
|
@ -11,8 +11,11 @@ prog_app = env.UnityProgram(
|
|||||||
dependencies = {
|
dependencies = {
|
||||||
'mijin': {},
|
'mijin': {},
|
||||||
'SDL': {
|
'SDL': {
|
||||||
|
'options': {
|
||||||
}
|
'ref': '76ce83801ade3ac922ad5ba6fddc49764c24206a'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'spdlog': {}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
env.Default(prog_app)
|
env.Default(prog_app)
|
||||||
|
@ -1,5 +1,49 @@
|
|||||||
|
|
||||||
|
#include <mijin/util/scope_guard.hpp>
|
||||||
|
#include <mijin/util/variant.hpp>
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
#include "./sdlpp/event.hpp"
|
||||||
|
#include "./sdlpp/gpu.hpp"
|
||||||
|
#include "./sdlpp/window.hpp"
|
||||||
|
|
||||||
int main(int, char**)
|
int main(int, char**)
|
||||||
{
|
{
|
||||||
return 0;
|
if (SDL_Init(0) != SDL_TRUE)
|
||||||
|
{
|
||||||
|
spdlog::error("Error initializing SDL.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
MIJIN_SCOPE_EXIT {
|
||||||
|
SDL_Quit();
|
||||||
|
};
|
||||||
|
|
||||||
|
sdlpp::Window window;
|
||||||
|
window.create({
|
||||||
|
.flags = {.vulkan = true}
|
||||||
|
});
|
||||||
|
|
||||||
|
sdlpp::GPUDevice gpuDevice;
|
||||||
|
gpuDevice.create({.formatFlags{.spirv = true}});
|
||||||
|
|
||||||
|
gpuDevice.claimWindow(window);
|
||||||
|
|
||||||
|
const SDL_GPUTextureFormat texForm = SDL_GetGPUSwapchainTextureFormat(gpuDevice, window);
|
||||||
|
(void) texForm;
|
||||||
|
|
||||||
|
bool running = true;
|
||||||
|
while(running)
|
||||||
|
{
|
||||||
|
std::optional<sdlpp::sdl_event_t> event;
|
||||||
|
while ((event = sdlpp::pollEvent()).has_value())
|
||||||
|
{
|
||||||
|
std::visit(mijin::Visitor{
|
||||||
|
[&](const sdlpp::QuitEvent&) { running = false; },
|
||||||
|
[](const auto&) {} // default handler
|
||||||
|
}, *event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
54
private/sdl_gpu_test/sdlpp/common.hpp
Normal file
54
private/sdl_gpu_test/sdlpp/common.hpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined(SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_SDLPP_COMMON_HPP_INCLUDED)
|
||||||
|
#define SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_SDLPP_COMMON_HPP_INCLUDED 1
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include <mijin/debug/assert.hpp>
|
||||||
|
#include <mijin/util/bitflags.hpp>
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
namespace sdlpp
|
||||||
|
{
|
||||||
|
template<typename THandle, typename TConcrete>
|
||||||
|
class Base
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
THandle* mHandle = nullptr;
|
||||||
|
protected:
|
||||||
|
Base() noexcept = default;
|
||||||
|
explicit Base(THandle* handle) noexcept : mHandle(handle) {}
|
||||||
|
Base(Base&& other) noexcept : mHandle(std::exchange(other.mHandle, nullptr)) {}
|
||||||
|
|
||||||
|
Base& operator=(Base&& other) noexcept
|
||||||
|
{
|
||||||
|
if (this != &other)
|
||||||
|
{
|
||||||
|
static_cast<TConcrete&>(*this).destroy();
|
||||||
|
mHandle = std::exchange(other.mHandle, nullptr);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
Base(const Base&) = delete;
|
||||||
|
~Base() noexcept
|
||||||
|
{
|
||||||
|
static_cast<TConcrete&>(*this).destroy();
|
||||||
|
}
|
||||||
|
Base& operator=(const Base&) = delete;
|
||||||
|
auto operator<=>(const Base& other) const noexcept = default;
|
||||||
|
|
||||||
|
operator THandle*() const noexcept { return mHandle; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class SDLError : std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SDLError() : std::runtime_error(SDL_GetError()) {}
|
||||||
|
};
|
||||||
|
} // namespace sdlpp
|
||||||
|
|
||||||
|
#endif // !defined(SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_SDLPP_COMMON_HPP_INCLUDED)
|
52
private/sdl_gpu_test/sdlpp/event.hpp
Normal file
52
private/sdl_gpu_test/sdlpp/event.hpp
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined(SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_SDLPP_EVENT_HPP_INCLUDED)
|
||||||
|
#define SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_SDLPP_EVENT_HPP_INCLUDED 1
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
|
namespace sdlpp
|
||||||
|
{
|
||||||
|
struct Event
|
||||||
|
{
|
||||||
|
Uint64 timestamp;
|
||||||
|
|
||||||
|
template<typename TBase>
|
||||||
|
explicit Event(const TBase& base) noexcept : timestamp(base.timestamp) {}
|
||||||
|
};
|
||||||
|
struct QuitEvent : Event
|
||||||
|
{
|
||||||
|
explicit QuitEvent(const SDL_QuitEvent& base) noexcept : Event(base) {}
|
||||||
|
};
|
||||||
|
struct WindowEvent : Event
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
using sdl_event_t = std::variant<
|
||||||
|
WindowEvent,
|
||||||
|
QuitEvent
|
||||||
|
>;
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
std::optional<sdl_event_t> pollEvent() noexcept
|
||||||
|
{
|
||||||
|
SDL_Event event;
|
||||||
|
while (SDL_PollEvent(&event))
|
||||||
|
{
|
||||||
|
switch (event.type)
|
||||||
|
{
|
||||||
|
case SDL_EVENT_QUIT:
|
||||||
|
return QuitEvent(event.quit);
|
||||||
|
default:
|
||||||
|
// can't translate this yet
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
} // namespace sdlpp
|
||||||
|
|
||||||
|
#endif // !defined(SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_SDLPP_EVENT_HPP_INCLUDED)
|
79
private/sdl_gpu_test/sdlpp/gpu.hpp
Normal file
79
private/sdl_gpu_test/sdlpp/gpu.hpp
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined(SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_SDLPP_GPU_HPP_INCLUDED)
|
||||||
|
#define SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_SDLPP_GPU_HPP_INCLUDED 1
|
||||||
|
|
||||||
|
#include <SDL3/SDL_gpu.h>
|
||||||
|
|
||||||
|
#include "./common.hpp"
|
||||||
|
|
||||||
|
namespace sdlpp
|
||||||
|
{
|
||||||
|
struct GpuShaderFormat : mijin::BitFlags<GpuShaderFormat>
|
||||||
|
{
|
||||||
|
bool private_ : 1 = false;
|
||||||
|
bool spirv : 1 = false;
|
||||||
|
bool dxbc : 1 = false;
|
||||||
|
bool dxil : 1 = false;
|
||||||
|
bool msl : 1 = false;
|
||||||
|
bool metallib : 1 = false;
|
||||||
|
|
||||||
|
constexpr operator SDL_GPUShaderFormat() const noexcept
|
||||||
|
{
|
||||||
|
return std::bit_cast<std::uint8_t>(*this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GPUDeviceCreateArgs
|
||||||
|
{
|
||||||
|
GpuShaderFormat formatFlags = {};
|
||||||
|
bool debugMode = false;
|
||||||
|
const char* name = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GPUDevice : public Base<SDL_GPUDevice, GPUDevice>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GPUDevice() noexcept = default;
|
||||||
|
GPUDevice(const GPUDevice&) = delete;
|
||||||
|
GPUDevice(GPUDevice&& other) noexcept : Base(std::move(other)) {}
|
||||||
|
|
||||||
|
GPUDevice& operator=(const GPUDevice&) = delete;
|
||||||
|
GPUDevice& operator=(GPUDevice&& other) noexcept
|
||||||
|
{
|
||||||
|
Base::operator=(std::move(other));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
auto operator<=>(const GPUDevice& other) const noexcept = default;
|
||||||
|
|
||||||
|
void create(const GPUDeviceCreateArgs& args = {})
|
||||||
|
{
|
||||||
|
MIJIN_ASSERT(mHandle == nullptr, "GPUDevice has already been created.");
|
||||||
|
mHandle = SDL_CreateGPUDevice(args.formatFlags, args.debugMode, args.name);
|
||||||
|
if (mHandle == nullptr)
|
||||||
|
{
|
||||||
|
throw SDLError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy() noexcept
|
||||||
|
{
|
||||||
|
if (mHandle != nullptr)
|
||||||
|
{
|
||||||
|
SDL_DestroyGPUDevice(mHandle);
|
||||||
|
mHandle = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void claimWindow(SDL_Window* window) const
|
||||||
|
{
|
||||||
|
if (!SDL_ClaimWindowForGPUDevice(*this, window))
|
||||||
|
{
|
||||||
|
throw SDLError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace sdlpp
|
||||||
|
|
||||||
|
#endif // !defined(SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_SDLPP_GPU_HPP_INCLUDED)
|
96
private/sdl_gpu_test/sdlpp/window.hpp
Normal file
96
private/sdl_gpu_test/sdlpp/window.hpp
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined(SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_SDLPP_WINDOW_HPP_INCLUDED)
|
||||||
|
#define SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_SDLPP_WINDOW_HPP_INCLUDED 1
|
||||||
|
|
||||||
|
#include "./common.hpp"
|
||||||
|
|
||||||
|
namespace sdlpp
|
||||||
|
{
|
||||||
|
struct WindowFlags : mijin::BitFlags<WindowFlags>
|
||||||
|
{
|
||||||
|
bool fullscreen : 1; // 0x0000000000000001 /**< window is in fullscreen mode */
|
||||||
|
bool opengl : 1; // 0x0000000000000002 /**< window usable with OpenGL context */
|
||||||
|
bool occluded : 1; // 0x0000000000000004 /**< window is occluded */
|
||||||
|
bool hidden : 1; // 0x0000000000000008) /**< window is neither mapped onto the desktop nor shown in the taskbar/dock/window list; SDL_ShowWindow( is required for it to become visible */
|
||||||
|
bool borderless : 1; // 0x0000000000000010 /**< no window decoration */
|
||||||
|
bool resizable : 1; // 0x0000000000000020 /**< window can be resized */
|
||||||
|
bool minimized : 1; // 0x0000000000000040 /**< window is minimized */
|
||||||
|
bool maximized : 1; // 0x0000000000000080 /**< window is maximized */
|
||||||
|
bool mouse_grabbed : 1; // 0x0000000000000100 /**< window has grabbed mouse input */
|
||||||
|
bool input_focus : 1; // 0x0000000000000200 /**< window has input focus */
|
||||||
|
bool mouse_focus : 1; // 0x0000000000000400 /**< window has mouse focus */
|
||||||
|
bool external : 1; // 0x0000000000000800 /**< window not created by SDL */
|
||||||
|
bool modal : 1; // 0x0000000000001000 /**< window is modal */
|
||||||
|
bool high_pixel_density : 1; // 0x0000000000002000 /**< window uses high pixel density back buffer if possible */
|
||||||
|
bool mouse_capture : 1; // 0x0000000000004000) /**< window has mouse captured (unrelated to MOUSE_GRABBED */
|
||||||
|
bool mouse_relative_mode : 1; // 0x0000000000008000 /**< window has relative mode enabled */
|
||||||
|
bool always_on_top : 1; // 0x0000000000010000 /**< window should always be above others */
|
||||||
|
bool utility : 1; // 0x0000000000020000 /**< window should be treated as a utility window, not showing in the task bar and window list */
|
||||||
|
bool tooltip : 1; // 0x0000000000040000 /**< window should be treated as a tooltip and does not get mouse or keyboard focus, requires a parent window */
|
||||||
|
bool popup_menu : 1; // 0x0000000000080000 /**< window should be treated as a popup menu, requires a parent window */
|
||||||
|
bool keyboard_grabbed : 1; // 0x0000000000100000 /**< window has grabbed keyboard input */
|
||||||
|
bool unused0 : 1; // 0x0000000000200000
|
||||||
|
bool unused1 : 1; // 0x0000000000400000
|
||||||
|
bool unused2 : 1; // 0x0000000000800000
|
||||||
|
bool unused3 : 1; // 0x0000000001000000
|
||||||
|
bool unused4 : 1; // 0x0000000002000000
|
||||||
|
bool unused5 : 1; // 0x0000000004000000
|
||||||
|
bool unused6 : 1; // 0x0000000008000000
|
||||||
|
bool vulkan : 1; // 0x0000000010000000 /**< window usable for Vulkan surface */
|
||||||
|
bool metal : 1; // 0x0000000020000000 /**< window usable for Metal view */
|
||||||
|
bool transparent : 1; // 0x0000000040000000 /**< window with transparent buffer */
|
||||||
|
bool notFocusable : 1; // 0x0000000080000000 /**< window should not be focusable */
|
||||||
|
|
||||||
|
constexpr operator SDL_WindowFlags () const noexcept
|
||||||
|
{
|
||||||
|
return std::bit_cast<std::uint32_t>(*this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WindowCreateArgs
|
||||||
|
{
|
||||||
|
const char* title = "Window";
|
||||||
|
int width = 1280;
|
||||||
|
int height = 720;
|
||||||
|
WindowFlags flags = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
class Window : public Base<SDL_Window, Window>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Window() noexcept = default;
|
||||||
|
Window(const Window&) = delete;
|
||||||
|
Window(Window&& other) noexcept : Base(std::move(other)) {}
|
||||||
|
|
||||||
|
Window& operator=(const Window&) = delete;
|
||||||
|
Window& operator=(Window&& other) noexcept
|
||||||
|
{
|
||||||
|
Base::operator=(std::move(other));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
auto operator<=>(const Window& other) const noexcept = default;
|
||||||
|
|
||||||
|
void create(const WindowCreateArgs& args = {})
|
||||||
|
{
|
||||||
|
MIJIN_ASSERT(mHandle == nullptr, "Window has already been created.");
|
||||||
|
mHandle = SDL_CreateWindow(args.title, args.width, args.height, args.flags);
|
||||||
|
if (mHandle == nullptr)
|
||||||
|
{
|
||||||
|
throw SDLError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy() noexcept
|
||||||
|
{
|
||||||
|
if (mHandle != nullptr)
|
||||||
|
{
|
||||||
|
SDL_DestroyWindow(mHandle);
|
||||||
|
mHandle = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace sdlpp
|
||||||
|
|
||||||
|
#endif // !defined(SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_SDLPP_WINDOW_HPP_INCLUDED)
|
Loading…
x
Reference in New Issue
Block a user