use vendor sdl3 bindings
This commit is contained in:
parent
4664af5e2c
commit
73619fe6c5
80
input.c3
80
input.c3
@ -1,4 +1,4 @@
|
|||||||
module ugui::sdl::ren;
|
module ugui::sdl3::ren;
|
||||||
|
|
||||||
import std::io;
|
import std::io;
|
||||||
import std::ascii;
|
import std::ascii;
|
||||||
@ -13,33 +13,33 @@ fn bool? Ctx.handle_events(&ctx)
|
|||||||
bool quit = false;
|
bool quit = false;
|
||||||
ugui::ModKeys mod_set, mod_reset;
|
ugui::ModKeys mod_set, mod_reset;
|
||||||
ugui::MouseButtons btn;
|
ugui::MouseButtons btn;
|
||||||
sdl::Event e;
|
sdl3::Event e;
|
||||||
|
|
||||||
while (sdl::poll_event(&e)) {
|
while (sdl3::pollEvent(&e)) {
|
||||||
switch (e.type) {
|
switch (e.type) {
|
||||||
case EVENT_QUIT:
|
case QUIT:
|
||||||
quit = true;
|
quit = true;
|
||||||
case EVENT_KEY_UP:
|
case KEY_UP:
|
||||||
ctx.input_key_release();
|
ctx.input_key_release();
|
||||||
nextcase;
|
nextcase;
|
||||||
case EVENT_KEY_DOWN:
|
case KEY_DOWN:
|
||||||
ctx.input_key_press();
|
ctx.input_key_press();
|
||||||
if (e.key.repeat) ctx.input_key_repeat();
|
if (e.key.repeat) ctx.input_key_repeat();
|
||||||
|
|
||||||
bool down = e.type == EVENT_KEY_DOWN;
|
bool down = e.type == KEY_DOWN;
|
||||||
switch (e.key.key) {
|
switch (e.key.key) {
|
||||||
case K_RCTRL: mod_set.rctrl = down; mod_reset.rctrl = !down;
|
case sdl3::KEY_RCTRL: mod_set.rctrl = down; mod_reset.rctrl = !down;
|
||||||
case K_LCTRL: mod_set.lctrl = down; mod_reset.lctrl = !down;
|
case sdl3::KEY_LCTRL: mod_set.lctrl = down; mod_reset.lctrl = !down;
|
||||||
case K_RSHIFT: mod_set.rshift = down; mod_reset.rshift = !down;
|
case sdl3::KEY_RSHIFT: mod_set.rshift = down; mod_reset.rshift = !down;
|
||||||
case K_LSHIFT: mod_set.lshift = down; mod_reset.lshift = !down;
|
case sdl3::KEY_LSHIFT: mod_set.lshift = down; mod_reset.lshift = !down;
|
||||||
case K_BACKSPACE: mod_set.bkspc = down; mod_reset.bkspc = !down;
|
case sdl3::KEY_BACKSPACE: mod_set.bkspc = down; mod_reset.bkspc = !down;
|
||||||
case K_DELETE: mod_set.del = down; mod_reset.del = !down;
|
case sdl3::KEY_DELETE: mod_set.del = down; mod_reset.del = !down;
|
||||||
case K_HOME: mod_set.home = down; mod_reset.home = !down;
|
case sdl3::KEY_HOME: mod_set.home = down; mod_reset.home = !down;
|
||||||
case K_END: mod_set.end = down; mod_reset.end = !down;
|
case sdl3::KEY_END: mod_set.end = down; mod_reset.end = !down;
|
||||||
case K_UP: mod_set.up = down; mod_reset.up = !down;
|
case sdl3::KEY_UP: mod_set.up = down; mod_reset.up = !down;
|
||||||
case K_DOWN: mod_set.down = down; mod_reset.down = !down;
|
case sdl3::KEY_DOWN: mod_set.down = down; mod_reset.down = !down;
|
||||||
case K_LEFT: mod_set.left = down; mod_reset.left = !down;
|
case sdl3::KEY_LEFT: mod_set.left = down; mod_reset.left = !down;
|
||||||
case K_RIGHT: mod_set.right = down; mod_reset.right = !down;
|
case sdl3::KEY_RIGHT: mod_set.right = down; mod_reset.right = !down;
|
||||||
}
|
}
|
||||||
ctx.input_mod_keys(mod_set, true);
|
ctx.input_mod_keys(mod_set, true);
|
||||||
ctx.input_mod_keys(mod_reset, false);
|
ctx.input_mod_keys(mod_reset, false);
|
||||||
@ -48,38 +48,38 @@ fn bool? Ctx.handle_events(&ctx)
|
|||||||
// TEXT_INPUT event is generated. When those keys are pressed we have to
|
// TEXT_INPUT event is generated. When those keys are pressed we have to
|
||||||
// do manual text input, bummer
|
// do manual text input, bummer
|
||||||
ModKeys mod = ctx.get_mod();
|
ModKeys mod = ctx.get_mod();
|
||||||
if (e.type == EVENT_KEY_DOWN && (mod.lctrl || mod.rctrl)) {
|
if (e.type == KEY_DOWN && (mod.lctrl || mod.rctrl)) {
|
||||||
if (ascii::is_alnum_m((uint)e.key.key)) {
|
if (ascii::is_alnum_m((uint)e.key.key)) {
|
||||||
ctx.input_char((char)e.key.key);
|
ctx.input_char((char)e.key.key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.type == EVENT_KEY_DOWN && e.key.key == K_RETURN) ctx.input_char('\n');
|
if (e.type == KEY_DOWN && e.key.key == sdl3::KEY_RETURN) ctx.input_char('\n');
|
||||||
|
|
||||||
case EVENT_TEXT_INPUT:
|
case TEXT_INPUT:
|
||||||
ctx.input_text_utf8(e.text.text.str_view());
|
ctx.input_text_utf8(((ZString)e.text.text).str_view());
|
||||||
case EVENT_WINDOW_RESIZED:
|
case WINDOW_RESIZED:
|
||||||
ctx.input_window_size((short)e.window.data1, (short)e.window.data2)!;
|
ctx.input_window_size((short)e.window.data1, (short)e.window.data2)!;
|
||||||
case EVENT_WINDOW_FOCUS_GAINED:
|
case WINDOW_FOCUS_GAINED:
|
||||||
ctx.input_changefocus(true);
|
ctx.input_changefocus(true);
|
||||||
case EVENT_WINDOW_FOCUS_LOST:
|
case WINDOW_FOCUS_LOST:
|
||||||
ctx.input_changefocus(false);
|
ctx.input_changefocus(false);
|
||||||
case EVENT_MOUSE_MOTION:
|
case MOUSE_MOTION:
|
||||||
ctx.input_mouse_abs((short)e.motion.x, (short)e.motion.y);
|
ctx.input_mouse_abs((short)e.motion.x, (short)e.motion.y);
|
||||||
case EVENT_MOUSE_WHEEL:
|
case MOUSE_WHEEL:
|
||||||
ctx.input_mouse_wheel((short)e.wheel.integer_x, (short)e.wheel.integer_y);
|
ctx.input_mouse_wheel((short)e.wheel.integer_x, (short)e.wheel.integer_y);
|
||||||
case EVENT_MOUSE_BUTTON_DOWN: nextcase;
|
case MOUSE_BUTTON_DOWN: nextcase;
|
||||||
case EVENT_MOUSE_BUTTON_UP:
|
case MOUSE_BUTTON_UP:
|
||||||
sdl::MouseButtonFlags mb = sdl::get_mouse_state(null, null);
|
sdl3::MouseButtonFlags mb = sdl3::getMouseState(null, null);
|
||||||
btn = {
|
btn = {
|
||||||
.btn_left = !!(mb & BUTTON_LMASK),
|
.btn_left = !!(mb & sdl3::BUTTON_LMASK),
|
||||||
.btn_right = !!(mb & BUTTON_RMASK),
|
.btn_right = !!(mb & sdl3::BUTTON_RMASK),
|
||||||
.btn_middle = !!(mb & BUTTON_MMASK),
|
.btn_middle = !!(mb & sdl3::BUTTON_MMASK),
|
||||||
.btn_4 = !!(mb & BUTTON_X1MASK),
|
.btn_4 = !!(mb & sdl3::BUTTON_X1MASK),
|
||||||
.btn_5 = !!(mb & BUTTON_X2MASK),
|
.btn_5 = !!(mb & sdl3::BUTTON_X2MASK),
|
||||||
};
|
};
|
||||||
ctx.input_mouse_button(btn);
|
ctx.input_mouse_button(btn);
|
||||||
case EVENT_POLL_SENTINEL: break;
|
//case POLL_SENTINEL: break;
|
||||||
default:
|
default:
|
||||||
io::eprintfn("unhandled event: %s", e.type);
|
io::eprintfn("unhandled event: %s", e.type);
|
||||||
}
|
}
|
||||||
@ -88,10 +88,10 @@ fn bool? Ctx.handle_events(&ctx)
|
|||||||
return quit;
|
return quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn void pre(sdl::Window* win) => sdl::start_text_input(win);
|
fn void pre(sdl3::Window* win) => sdl3::startTextInput(win);
|
||||||
|
|
||||||
// TODO: this has to be a function of Ctx if we want to set the fps internally
|
// TODO: this has to be a function of Ctx if we want to set the fps internally
|
||||||
fn void wait_events(uint timeout_ms = 0)
|
fn void wait_events(uint timeout_ms = 0)
|
||||||
{
|
{
|
||||||
sdl::wait_event_timeout(null, timeout_ms);
|
sdl3::waitEventTimeout(null, timeout_ms);
|
||||||
}
|
}
|
||||||
|
|||||||
325
renderer.c3
325
renderer.c3
@ -29,10 +29,10 @@ macro Type* IdList.get_from_id(&self, id)
|
|||||||
|
|
||||||
|
|
||||||
// 2D renderer for ugui, based on SDL3 using the new GPU API
|
// 2D renderer for ugui, based on SDL3 using the new GPU API
|
||||||
module ugui::sdl::ren;
|
module ugui::sdl3::ren;
|
||||||
|
|
||||||
import std::io;
|
import std::io;
|
||||||
import sdl3::sdl;
|
import sdl3;
|
||||||
import std::core::mem;
|
import std::core::mem;
|
||||||
import idlist;
|
import idlist;
|
||||||
import ugui;
|
import ugui;
|
||||||
@ -83,30 +83,30 @@ struct ViewsizeUniform @align(16) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Shader {
|
struct Shader {
|
||||||
sdl::GPUShader* frag;
|
sdl3::GPUShader* frag;
|
||||||
sdl::GPUShader* vert;
|
sdl3::GPUShader* vert;
|
||||||
ugui::Id id;
|
ugui::Id id;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Pipeline {
|
struct Pipeline {
|
||||||
sdl::GPUGraphicsPipeline* pipeline;
|
sdl3::GPUGraphicsPipeline* pipeline;
|
||||||
ugui::Id id;
|
ugui::Id id;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Texture {
|
struct Texture {
|
||||||
sdl::GPUTexture* texture;
|
sdl3::GPUTexture* texture;
|
||||||
sdl::GPUSampler* sampler;
|
sdl3::GPUSampler* sampler;
|
||||||
ushort width, height;
|
ushort width, height;
|
||||||
ugui::Id id;
|
ugui::Id id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The GPU buffers that contain quad info, the size is determined by MAX_QUAD_BATCH
|
// The GPU buffers that contain quad info, the size is determined by MAX_QUAD_BATCH
|
||||||
struct QuadBuffer {
|
struct QuadBuffer {
|
||||||
sdl::GPUBuffer* vert_buf; // on-gpu vertex buffer
|
sdl3::GPUBuffer* vert_buf; // on-gpu vertex buffer
|
||||||
sdl::GPUBuffer* idx_buf; // on-gpu index buffer
|
sdl3::GPUBuffer* idx_buf; // on-gpu index buffer
|
||||||
sdl::GPUBuffer* attr_buf; // on-gpu quad attribute buffer
|
sdl3::GPUBuffer* attr_buf; // on-gpu quad attribute buffer
|
||||||
|
|
||||||
sdl::GPUTransferBuffer* attr_ts;
|
sdl3::GPUTransferBuffer* attr_ts;
|
||||||
|
|
||||||
QuadAttributes[] attr_ts_mapped;
|
QuadAttributes[] attr_ts_mapped;
|
||||||
|
|
||||||
@ -121,11 +121,11 @@ alias PipelineList = IdList{Pipeline};
|
|||||||
alias TextureList = IdList{Texture};
|
alias TextureList = IdList{Texture};
|
||||||
|
|
||||||
struct Renderer {
|
struct Renderer {
|
||||||
sdl::Window* win;
|
sdl3::Window* win;
|
||||||
sdl::GPUDevice* gpu;
|
sdl3::GPUDevice* gpu;
|
||||||
sdl::GPURenderPass* render_pass;
|
sdl3::GPURenderPass* render_pass;
|
||||||
sdl::GPUTexture* swapchain_texture;
|
sdl3::GPUTexture* swapchain_texture;
|
||||||
sdl::GPUCommandBuffer* render_cmdbuf;
|
sdl3::GPUCommandBuffer* render_cmdbuf;
|
||||||
|
|
||||||
QuadBuffer quad_buffer;
|
QuadBuffer quad_buffer;
|
||||||
ShaderList shaders;
|
ShaderList shaders;
|
||||||
@ -154,8 +154,8 @@ fn void Renderer.init(&self, ZString title, uint width, uint height, bool vsync)
|
|||||||
// set wayland hint automagically
|
// set wayland hint automagically
|
||||||
$if $feature(RENDER_DEBUG) == false && $feature(USE_WAYLAND) == true:
|
$if $feature(RENDER_DEBUG) == false && $feature(USE_WAYLAND) == true:
|
||||||
bool has_wayland = false;
|
bool has_wayland = false;
|
||||||
for (int i = 0; i < sdl::get_num_video_drivers(); i++) {
|
for (int i = 0; i < sdl3::getNumVideoDrivers(); i++) {
|
||||||
ZString driver = sdl::get_video_driver(i);
|
ZString driver = sdl3::getVideoDriver(i);
|
||||||
if (driver.str_view() == "wayland") {
|
if (driver.str_view() == "wayland") {
|
||||||
has_wayland = true;
|
has_wayland = true;
|
||||||
break;
|
break;
|
||||||
@ -163,39 +163,39 @@ $if $feature(RENDER_DEBUG) == false && $feature(USE_WAYLAND) == true:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (has_wayland) {
|
if (has_wayland) {
|
||||||
sdl::set_hint(sdl::HINT_VIDEO_DRIVER, "wayland");
|
sdl3::setHint("SDL_VIDEO_DRIVER", "wayland");
|
||||||
}
|
}
|
||||||
$else
|
$else
|
||||||
// in debug mode set the video driver to X11 because renderdoc
|
// in debug mode set the video driver to X11 because renderdoc
|
||||||
// doesn't support debugging in wayland yet.
|
// doesn't support debugging in wayland yet.
|
||||||
sdl::set_hint(sdl::HINT_VIDEO_DRIVER, "x11");
|
sdl3::setHint("SDL_VIDEO_DRIVER", "x11");
|
||||||
sdl::set_hint(sdl::HINT_RENDER_GPU_DEBUG, "1");
|
sdl3::setHint("SDL_RENDER_GPU_DEBUG", "1");
|
||||||
$endif
|
$endif
|
||||||
|
|
||||||
// init subsystems
|
// init subsystems
|
||||||
if (!sdl::init(INIT_VIDEO)) {
|
if (!sdl3::init({.video=true})) {
|
||||||
unreachable("sdl error: %s", sdl::get_error());
|
unreachable("sdl error: %s", sdl3::getError());
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the window
|
// create the window
|
||||||
self.win = sdl::create_window(title, width, height, WINDOW_RESIZABLE|WINDOW_VULKAN);
|
self.win = sdl3::createWindow(title, width, height, {.resizable=true, .vulkan=true});
|
||||||
if (self.win == null) {
|
if (self.win == null) {
|
||||||
unreachable("sdl error: %s", sdl::get_error());
|
unreachable("sdl error: %s", sdl3::getError());
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the gpu device handle
|
// get the gpu device handle
|
||||||
self.gpu = sdl::create_gpu_device(GPU_SHADERFORMAT_SPIRV, true, "vulkan");
|
self.gpu = sdl3::createGPUDevice({.spirv=true}, true, "vulkan");
|
||||||
if (self.gpu == null) {
|
if (self.gpu == null) {
|
||||||
unreachable("failed to create gpu device: %s", sdl::get_error());
|
unreachable("failed to create gpu device: %s", sdl3::getError());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sdl::claim_window_for_gpu_device(self.gpu, self.win)) {
|
if (!sdl3::claimWindowForGPUDevice(self.gpu, self.win)) {
|
||||||
unreachable("failed to claim window for use with gpu: %s", sdl::get_error());
|
unreachable("failed to claim window for use with gpu: %s", sdl3::getError());
|
||||||
}
|
}
|
||||||
|
|
||||||
// set swapchain parameters, like vsync
|
// set swapchain parameters, like vsync
|
||||||
GPUPresentMode present_mode = vsync ? GPU_PRESENTMODE_VSYNC : GPU_PRESENTMODE_IMMEDIATE;
|
GPUPresentMode present_mode = vsync ? VSYNC : IMMEDIATE;
|
||||||
sdl::set_gpu_swapchain_parameters(self.gpu, self.win, GPU_SWAPCHAINCOMPOSITION_SDR, present_mode);
|
sdl3::setGPUSwapchainParameters(self.gpu, self.win, SDR, present_mode);
|
||||||
|
|
||||||
//
|
//
|
||||||
// initialize the quad buffer
|
// initialize the quad buffer
|
||||||
@ -205,35 +205,35 @@ $endif
|
|||||||
// since instanced rendering is used, on the gpu there is only one mesh, a single quad.
|
// since instanced rendering is used, on the gpu there is only one mesh, a single quad.
|
||||||
|
|
||||||
// create the vertex and index buffer on the gpu
|
// create the vertex and index buffer on the gpu
|
||||||
qb.vert_buf = sdl::create_gpu_buffer(self.gpu,
|
qb.vert_buf = sdl3::createGPUBuffer(self.gpu,
|
||||||
&&(GPUBufferCreateInfo){.usage = GPU_BUFFERUSAGE_VERTEX, .size = Quad.vertices.sizeof}
|
&&(GPUBufferCreateInfo){.usage.vertex = true, .size = Quad.vertices.sizeof}
|
||||||
);
|
);
|
||||||
if (qb.vert_buf == null) {
|
if (qb.vert_buf == null) {
|
||||||
unreachable("failed to initialize quad buffer (vertex): %s", sdl::get_error());
|
unreachable("failed to initialize quad buffer (vertex): %s", sdl3::getError());
|
||||||
}
|
}
|
||||||
|
|
||||||
qb.idx_buf = sdl::create_gpu_buffer(self.gpu,
|
qb.idx_buf = sdl3::createGPUBuffer(self.gpu,
|
||||||
&&(GPUBufferCreateInfo){.usage = GPU_BUFFERUSAGE_INDEX, .size = Quad.indices.sizeof}
|
&&(GPUBufferCreateInfo){.usage.index = true, .size = Quad.indices.sizeof}
|
||||||
);
|
);
|
||||||
if (qb.idx_buf == null) {
|
if (qb.idx_buf == null) {
|
||||||
unreachable("failed to initialize quad buffer (index): %s", sdl::get_error());
|
unreachable("failed to initialize quad buffer (index): %s", sdl3::getError());
|
||||||
}
|
}
|
||||||
|
|
||||||
qb.attr_buf = sdl::create_gpu_buffer(self.gpu,
|
qb.attr_buf = sdl3::createGPUBuffer(self.gpu,
|
||||||
&&(GPUBufferCreateInfo){.usage = GPU_BUFFERUSAGE_VERTEX, .size = QuadAttributes.sizeof * MAX_QUAD_BATCH}
|
&&(GPUBufferCreateInfo){.usage.vertex = true, .size = QuadAttributes.sizeof * MAX_QUAD_BATCH}
|
||||||
);
|
);
|
||||||
if (qb.attr_buf == null) {
|
if (qb.attr_buf == null) {
|
||||||
unreachable("failed to initialize quad buffer (index): %s", sdl::get_error());
|
unreachable("failed to initialize quad buffer (index): %s", sdl3::getError());
|
||||||
}
|
}
|
||||||
|
|
||||||
// upload the quad mesh
|
// upload the quad mesh
|
||||||
GPUTransferBuffer *ts = sdl::create_gpu_transfer_buffer(self.gpu,
|
GPUTransferBuffer *ts = sdl3::createGPUTransferBuffer(self.gpu,
|
||||||
&&(GPUTransferBufferCreateInfo){.usage = GPU_TRANSFERBUFFERUSAGE_UPLOAD, .size = Quad.sizeof}
|
&&(GPUTransferBufferCreateInfo){.usage = UPLOAD, .size = Quad.sizeof}
|
||||||
);
|
);
|
||||||
if (ts == null) {
|
if (ts == null) {
|
||||||
unreachable("failed to create gpu transfer buffer: %s", sdl::get_error());
|
unreachable("failed to create gpu transfer buffer: %s", sdl3::getError());
|
||||||
}
|
}
|
||||||
Quad* quad = (Quad*)sdl::map_gpu_transfer_buffer(self.gpu, ts, false);
|
Quad* quad = (Quad*)sdl3::mapGPUTransferBuffer(self.gpu, ts, false);
|
||||||
|
|
||||||
/* v1 v4
|
/* v1 v4
|
||||||
* +-------------+
|
* +-------------+
|
||||||
@ -260,44 +260,44 @@ $endif
|
|||||||
quad.indices.i5 = 2; // v3
|
quad.indices.i5 = 2; // v3
|
||||||
quad.indices.i6 = 3; // v4
|
quad.indices.i6 = 3; // v4
|
||||||
|
|
||||||
sdl::unmap_gpu_transfer_buffer(self.gpu, ts);
|
sdl3::unmapGPUTransferBuffer(self.gpu, ts);
|
||||||
|
|
||||||
GPUCommandBuffer* cmd = sdl::acquire_gpu_command_buffer(self.gpu);
|
GPUCommandBuffer* cmd = sdl3::acquireGPUCommandBuffer(self.gpu);
|
||||||
if (cmd == null) {
|
if (cmd == null) {
|
||||||
unreachable("failed to upload quad at acquiring command buffer: %s", sdl::get_error());
|
unreachable("failed to upload quad at acquiring command buffer: %s", sdl3::getError());
|
||||||
}
|
}
|
||||||
GPUCopyPass* cpy = sdl::begin_gpu_copy_pass(cmd);
|
GPUCopyPass* cpy = sdl3::beginGPUCopyPass(cmd);
|
||||||
|
|
||||||
// upload vertices
|
// upload vertices
|
||||||
sdl::upload_to_gpu_buffer(cpy,
|
sdl3::uploadToGPUBuffer(cpy,
|
||||||
&&(GPUTransferBufferLocation){.transfer_buffer = ts, .offset = Quad.vertices.offsetof},
|
&&(GPUTransferBufferLocation){.transfer_buffer = ts, .offset = Quad.vertices.offsetof},
|
||||||
&&(GPUBufferRegion){.buffer = qb.vert_buf, .offset = 0, .size = Quad.vertices.sizeof},
|
&&(GPUBufferRegion){.buffer = qb.vert_buf, .offset = 0, .size = Quad.vertices.sizeof},
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
// upload indices
|
// upload indices
|
||||||
sdl::upload_to_gpu_buffer(cpy,
|
sdl3::uploadToGPUBuffer(cpy,
|
||||||
&&(GPUTransferBufferLocation){.transfer_buffer = ts, .offset = Quad.indices.offsetof},
|
&&(GPUTransferBufferLocation){.transfer_buffer = ts, .offset = Quad.indices.offsetof},
|
||||||
&&(GPUBufferRegion){.buffer = qb.idx_buf, .offset = 0, .size = Quad.indices.sizeof},
|
&&(GPUBufferRegion){.buffer = qb.idx_buf, .offset = 0, .size = Quad.indices.sizeof},
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
sdl::end_gpu_copy_pass(cpy);
|
sdl3::endGPUCopyPass(cpy);
|
||||||
if (!sdl::submit_gpu_command_buffer(cmd)) {
|
if (!sdl3::submitGPUCommandBuffer(cmd)) {
|
||||||
unreachable("failed to upload quads at submit command buffer: %s", sdl::get_error());
|
unreachable("failed to upload quads at submit command buffer: %s", sdl3::getError());
|
||||||
}
|
}
|
||||||
sdl::release_gpu_transfer_buffer(self.gpu, ts);
|
sdl3::releaseGPUTransferBuffer(self.gpu, ts);
|
||||||
|
|
||||||
|
|
||||||
// create and map the quad attributes transfer buffer
|
// create and map the quad attributes transfer buffer
|
||||||
qb.attr_ts = sdl::create_gpu_transfer_buffer(self.gpu,
|
qb.attr_ts = sdl3::createGPUTransferBuffer(self.gpu,
|
||||||
&&(GPUTransferBufferCreateInfo){.usage = GPU_TRANSFERBUFFERUSAGE_UPLOAD, .size = QuadAttributes.sizeof * MAX_QUAD_BATCH}
|
&&(GPUTransferBufferCreateInfo){.usage = UPLOAD, .size = QuadAttributes.sizeof * MAX_QUAD_BATCH}
|
||||||
);
|
);
|
||||||
if (qb.attr_ts == null) {
|
if (qb.attr_ts == null) {
|
||||||
unreachable("failed to create gpu transfer buffer: %s", sdl::get_error());
|
unreachable("failed to create gpu transfer buffer: %s", sdl3::getError());
|
||||||
}
|
}
|
||||||
qb.attr_ts_mapped = ((QuadAttributes*)sdl::map_gpu_transfer_buffer(self.gpu, qb.attr_ts, false))[:MAX_QUAD_BATCH];
|
qb.attr_ts_mapped = ((QuadAttributes*)sdl3::mapGPUTransferBuffer(self.gpu, qb.attr_ts, false))[:MAX_QUAD_BATCH];
|
||||||
if (qb.attr_ts_mapped.ptr == null) {
|
if (qb.attr_ts_mapped.ptr == null) {
|
||||||
unreachable("failed to map vertex or index buffers: %s", sdl::get_error());
|
unreachable("failed to map vertex or index buffers: %s", sdl3::getError());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -314,45 +314,45 @@ $endif
|
|||||||
fn void Renderer.free(&self)
|
fn void Renderer.free(&self)
|
||||||
{
|
{
|
||||||
foreach (&s: self.shaders) {
|
foreach (&s: self.shaders) {
|
||||||
sdl::release_gpu_shader(self.gpu, s.frag);
|
sdl3::releaseGPUShader(self.gpu, s.frag);
|
||||||
sdl::release_gpu_shader(self.gpu, s.vert);
|
sdl3::releaseGPUShader(self.gpu, s.vert);
|
||||||
}
|
}
|
||||||
self.shaders.free();
|
self.shaders.free();
|
||||||
|
|
||||||
foreach (&p: self.pipelines) {
|
foreach (&p: self.pipelines) {
|
||||||
sdl::release_gpu_graphics_pipeline(self.gpu, p.pipeline);
|
sdl3::releaseGPUGraphicsPipeline(self.gpu, p.pipeline);
|
||||||
}
|
}
|
||||||
self.pipelines.free();
|
self.pipelines.free();
|
||||||
|
|
||||||
foreach (&t: self.textures) {
|
foreach (&t: self.textures) {
|
||||||
sdl::release_gpu_texture(self.gpu, t.texture);
|
sdl3::releaseGPUTexture(self.gpu, t.texture);
|
||||||
sdl::release_gpu_sampler(self.gpu, t.sampler);
|
sdl3::releaseGPUSampler(self.gpu, t.sampler);
|
||||||
}
|
}
|
||||||
self.textures.free();
|
self.textures.free();
|
||||||
|
|
||||||
QuadBuffer* qb = &self.quad_buffer;
|
QuadBuffer* qb = &self.quad_buffer;
|
||||||
sdl::unmap_gpu_transfer_buffer(self.gpu, qb.attr_ts);
|
sdl3::unmapGPUTransferBuffer(self.gpu, qb.attr_ts);
|
||||||
sdl::release_gpu_transfer_buffer(self.gpu, qb.attr_ts);
|
sdl3::releaseGPUTransferBuffer(self.gpu, qb.attr_ts);
|
||||||
sdl::release_gpu_buffer(self.gpu, qb.vert_buf);
|
sdl3::releaseGPUBuffer(self.gpu, qb.vert_buf);
|
||||||
sdl::release_gpu_buffer(self.gpu, qb.idx_buf);
|
sdl3::releaseGPUBuffer(self.gpu, qb.idx_buf);
|
||||||
sdl::release_gpu_buffer(self.gpu, qb.attr_buf);
|
sdl3::releaseGPUBuffer(self.gpu, qb.attr_buf);
|
||||||
|
|
||||||
sdl::release_window_from_gpu_device(self.gpu, self.win);
|
sdl3::releaseWindowFromGPUDevice(self.gpu, self.win);
|
||||||
sdl::destroy_gpu_device(self.gpu);
|
sdl3::destroyGPUDevice(self.gpu);
|
||||||
sdl::destroy_window(self.win);
|
sdl3::destroyWindow(self.win);
|
||||||
sdl::quit();
|
sdl3::quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn void Renderer.resize_window(&self, uint width, uint height)
|
fn void Renderer.resize_window(&self, uint width, uint height)
|
||||||
{
|
{
|
||||||
sdl::set_window_size(self.win, width, height);
|
sdl3::setWindowSize(self.win, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn void Renderer.get_window_size(&self, int* width, int* height)
|
fn void Renderer.get_window_size(&self, int* width, int* height)
|
||||||
{
|
{
|
||||||
sdl::get_window_size_in_pixels(self.win, width, height);
|
sdl3::getWindowSizeInPixels(self.win, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -379,17 +379,17 @@ fn void Renderer.load_spirv_shader_from_mem(&self, String name, char[] vert_code
|
|||||||
.code = vert_code.ptr,
|
.code = vert_code.ptr,
|
||||||
.code_size = vert_code.len,
|
.code_size = vert_code.len,
|
||||||
.entrypoint = "main",
|
.entrypoint = "main",
|
||||||
.format = GPU_SHADERFORMAT_SPIRV,
|
.format.spirv = true,
|
||||||
.stage = GPU_SHADERSTAGE_VERTEX,
|
.stage = VERTEX,
|
||||||
.num_samplers = 0,
|
.num_samplers = 0,
|
||||||
.num_uniform_buffers = 1+uniforms,
|
.num_uniform_buffers = 1+uniforms,
|
||||||
.num_storage_buffers = 0,
|
.num_storage_buffers = 0,
|
||||||
.num_storage_textures = 0
|
.num_storage_textures = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
s.vert = sdl::create_gpu_shader(self.gpu, &shader_info);
|
s.vert = sdl3::createGPUShader(self.gpu, &shader_info);
|
||||||
if (s.vert == null) {
|
if (s.vert == null) {
|
||||||
unreachable("failed to create gpu vertex shader: %s", sdl::get_error());
|
unreachable("failed to create gpu vertex shader: %s", sdl3::getError());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -400,17 +400,17 @@ fn void Renderer.load_spirv_shader_from_mem(&self, String name, char[] vert_code
|
|||||||
.code = frag_code.ptr,
|
.code = frag_code.ptr,
|
||||||
.code_size = frag_code.len,
|
.code_size = frag_code.len,
|
||||||
.entrypoint = "main",
|
.entrypoint = "main",
|
||||||
.format = GPU_SHADERFORMAT_SPIRV,
|
.format.spirv = true,
|
||||||
.stage = GPU_SHADERSTAGE_FRAGMENT,
|
.stage = FRAGMENT,
|
||||||
.num_samplers = textures,
|
.num_samplers = textures,
|
||||||
.num_uniform_buffers = 1,
|
.num_uniform_buffers = 1,
|
||||||
.num_storage_buffers = 0,
|
.num_storage_buffers = 0,
|
||||||
.num_storage_textures = 0
|
.num_storage_textures = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
s.frag = sdl::create_gpu_shader(self.gpu, &shader_info);
|
s.frag = sdl3::createGPUShader(self.gpu, &shader_info);
|
||||||
if (s.frag == null) {
|
if (s.frag == null) {
|
||||||
unreachable("failed to create gpu fragment shader: %s", sdl::get_error());
|
unreachable("failed to create gpu fragment shader: %s", sdl3::getError());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -452,9 +452,9 @@ fn void Renderer.load_spirv_shader_from_file(&self, String name, String vert_pat
|
|||||||
// this describes what we want to draw, since for drawing different things we have to change
|
// this describes what we want to draw, since for drawing different things we have to change
|
||||||
// the GPUPrimitiveType and GPURasterizerState for the pipeline.
|
// the GPUPrimitiveType and GPURasterizerState for the pipeline.
|
||||||
enum PipelineType : (GPUPrimitiveType primitive_type, GPURasterizerState raster_state) {
|
enum PipelineType : (GPUPrimitiveType primitive_type, GPURasterizerState raster_state) {
|
||||||
RECT {GPU_PRIMITIVETYPE_TRIANGLELIST, {.fill_mode = GPU_FILLMODE_FILL, .cull_mode = GPU_CULLMODE_NONE, .front_face = GPU_FRONTFACE_COUNTER_CLOCKWISE}},
|
RECT {TRIANGLELIST, {.fill_mode = FILL, .cull_mode = NONE, .front_face = COUNTER_CLOCKWISE}},
|
||||||
SPRITE {GPU_PRIMITIVETYPE_TRIANGLELIST, {.fill_mode = GPU_FILLMODE_FILL, .cull_mode = GPU_CULLMODE_NONE, .front_face = GPU_FRONTFACE_COUNTER_CLOCKWISE}},
|
SPRITE {TRIANGLELIST, {.fill_mode = FILL, .cull_mode = NONE, .front_face = COUNTER_CLOCKWISE}},
|
||||||
LINE {GPU_PRIMITIVETYPE_LINELIST, {.fill_mode = GPU_FILLMODE_LINE, .cull_mode = GPU_CULLMODE_NONE, .front_face = GPU_FRONTFACE_COUNTER_CLOCKWISE}},
|
LINE {LINELIST, {.fill_mode = LINE, .cull_mode = NONE, .front_face = COUNTER_CLOCKWISE}},
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a graphics pipeline to draw to the window using a set of vertex/fragment shaders
|
// create a graphics pipeline to draw to the window using a set of vertex/fragment shaders
|
||||||
@ -480,12 +480,12 @@ fn void Renderer.create_pipeline(&self, String shader_name, PipelineType type)
|
|||||||
{ // first slot, per-vertex attributes
|
{ // first slot, per-vertex attributes
|
||||||
.slot = 0,
|
.slot = 0,
|
||||||
.pitch = Vertex.sizeof,
|
.pitch = Vertex.sizeof,
|
||||||
.input_rate = GPU_VERTEXINPUTRATE_VERTEX,
|
.input_rate = VERTEX,
|
||||||
},
|
},
|
||||||
{ // second slot, per-instance attributes
|
{ // second slot, per-instance attributes
|
||||||
.slot = 1,
|
.slot = 1,
|
||||||
.pitch = QuadAttributes.sizeof,
|
.pitch = QuadAttributes.sizeof,
|
||||||
.input_rate = GPU_VERTEXINPUTRATE_INSTANCE,
|
.input_rate = INSTANCE,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.num_vertex_buffers = 2,
|
.num_vertex_buffers = 2,
|
||||||
@ -494,31 +494,31 @@ fn void Renderer.create_pipeline(&self, String shader_name, PipelineType type)
|
|||||||
{ // at location zero there is the position of the vertex
|
{ // at location zero there is the position of the vertex
|
||||||
.location = 0,
|
.location = 0,
|
||||||
.buffer_slot = 0, // buffer slot zero so per-vertex
|
.buffer_slot = 0, // buffer slot zero so per-vertex
|
||||||
.format = GPU_VERTEXELEMENTFORMAT_SHORT2, // x,y
|
.format = SHORT2, // x,y
|
||||||
.offset = 0,
|
.offset = 0,
|
||||||
},
|
},
|
||||||
{ // at location one there is the per-quad position
|
{ // at location one there is the per-quad position
|
||||||
.location = 1,
|
.location = 1,
|
||||||
.buffer_slot = 1, // buffer slot one so per-instance
|
.buffer_slot = 1, // buffer slot one so per-instance
|
||||||
.format = GPU_VERTEXELEMENTFORMAT_SHORT4, // x,y,w,h
|
.format = SHORT4, // x,y,w,h
|
||||||
.offset = QuadAttributes.pos.offsetof,
|
.offset = QuadAttributes.pos.offsetof,
|
||||||
},
|
},
|
||||||
{ // at location two there are the per-quad uv coordinates
|
{ // at location two there are the per-quad uv coordinates
|
||||||
.location = 2,
|
.location = 2,
|
||||||
.buffer_slot = 1,
|
.buffer_slot = 1,
|
||||||
.format = GPU_VERTEXELEMENTFORMAT_SHORT4,
|
.format = SHORT4,
|
||||||
.offset = QuadAttributes.uv.offsetof,
|
.offset = QuadAttributes.uv.offsetof,
|
||||||
},
|
},
|
||||||
{ // at location three there is the quad color
|
{ // at location three there is the quad color
|
||||||
.location = 3,
|
.location = 3,
|
||||||
.buffer_slot = 1,
|
.buffer_slot = 1,
|
||||||
.format = GPU_VERTEXELEMENTFORMAT_UBYTE4,
|
.format = UBYTE4,
|
||||||
.offset = QuadAttributes.color.offsetof,
|
.offset = QuadAttributes.color.offsetof,
|
||||||
},
|
},
|
||||||
{ // at location four there is the quad type
|
{ // at location four there is the quad type
|
||||||
.location = 4,
|
.location = 4,
|
||||||
.buffer_slot = 1,
|
.buffer_slot = 1,
|
||||||
.format = GPU_VERTEXELEMENTFORMAT_UINT,
|
.format = UINT,
|
||||||
.offset = QuadAttributes.type.offsetof,
|
.offset = QuadAttributes.type.offsetof,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -533,16 +533,16 @@ fn void Renderer.create_pipeline(&self, String shader_name, PipelineType type)
|
|||||||
.target_info = { // the target (texture) description
|
.target_info = { // the target (texture) description
|
||||||
.color_target_descriptions = (GPUColorTargetDescription[]){{
|
.color_target_descriptions = (GPUColorTargetDescription[]){{
|
||||||
// rendering happens to the window, so get it's format
|
// rendering happens to the window, so get it's format
|
||||||
.format = sdl::get_gpu_swapchain_texture_format(self.gpu, self.win),
|
.format = sdl3::getGPUSwapchainTextureFormat(self.gpu, self.win),
|
||||||
.blend_state = {
|
.blend_state = {
|
||||||
// alpha blending on everything
|
// alpha blending on everything
|
||||||
// https://en.wikipedia.org/wiki/Alpha_compositing
|
// https://en.wikipedia.org/wiki/Alpha_compositing
|
||||||
.src_color_blendfactor = GPU_BLENDFACTOR_SRC_ALPHA,
|
.src_color_blendfactor = SRC_ALPHA,
|
||||||
.dst_color_blendfactor = GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
|
.dst_color_blendfactor = ONE_MINUS_SRC_ALPHA,
|
||||||
.color_blend_op = GPU_BLENDOP_ADD,
|
.color_blend_op = ADD,
|
||||||
.src_alpha_blendfactor = GPU_BLENDFACTOR_SRC_ALPHA,
|
.src_alpha_blendfactor = SRC_ALPHA,
|
||||||
.dst_alpha_blendfactor = GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
|
.dst_alpha_blendfactor = ONE_MINUS_SRC_ALPHA,
|
||||||
.alpha_blend_op = GPU_BLENDOP_ADD,
|
.alpha_blend_op = ADD,
|
||||||
.enable_blend = true,
|
.enable_blend = true,
|
||||||
// color write mask is not enabled so all rgba channels are written to
|
// color write mask is not enabled so all rgba channels are written to
|
||||||
},
|
},
|
||||||
@ -556,11 +556,11 @@ fn void Renderer.create_pipeline(&self, String shader_name, PipelineType type)
|
|||||||
// create the pipeline and add it to the pipeline list
|
// create the pipeline and add it to the pipeline list
|
||||||
Pipeline p = {
|
Pipeline p = {
|
||||||
.id = s.id,
|
.id = s.id,
|
||||||
.pipeline = sdl::create_gpu_graphics_pipeline(self.gpu, &ci),
|
.pipeline = sdl3::createGPUGraphicsPipeline(self.gpu, &ci),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (p.pipeline == null) {
|
if (p.pipeline == null) {
|
||||||
unreachable("failed to create pipeline (shaders: %s, type: %s): %s", shader_name, type.nameof, sdl::get_error());
|
unreachable("failed to create pipeline (shaders: %s, type: %s): %s", shader_name, type.nameof, sdl3::getError());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.pipelines.push(p);
|
self.pipelines.push(p);
|
||||||
@ -575,8 +575,8 @@ fn void Renderer.create_pipeline(&self, String shader_name, PipelineType type)
|
|||||||
|
|
||||||
// NOTE: with TEXTUREUSAGE_SAMPLER the texture format cannot be intger _UINT so it has to be nermalized
|
// NOTE: with TEXTUREUSAGE_SAMPLER the texture format cannot be intger _UINT so it has to be nermalized
|
||||||
enum TextureType : (GPUTextureFormat format) {
|
enum TextureType : (GPUTextureFormat format) {
|
||||||
FULL_COLOR {GPU_TEXTUREFORMAT_R8G8B8A8_UNORM},
|
FULL_COLOR {R8G8B8A8_UNORM},
|
||||||
JUST_ALPHA {GPU_TEXTUREFORMAT_R8_UNORM}
|
JUST_ALPHA {R8_UNORM}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -609,10 +609,10 @@ fn void Renderer.new_texture_by_id(&self, Id id, TextureType type, char[] pixels
|
|||||||
{
|
{
|
||||||
// the texture description
|
// the texture description
|
||||||
GPUTextureCreateInfo tci = {
|
GPUTextureCreateInfo tci = {
|
||||||
.type = GPU_TEXTURETYPE_2D,
|
.type = T2D,
|
||||||
.format = type.format,
|
.format = type.format,
|
||||||
// all textures are used with samplers, which means read-only textures that contain data to be sampled
|
// all textures are used with samplers, which means read-only textures that contain data to be sampled
|
||||||
.usage = GPU_TEXTUREUSAGE_SAMPLER,
|
.usage.sampler = true,
|
||||||
.width = width,
|
.width = width,
|
||||||
.height = height,
|
.height = height,
|
||||||
.layer_count_or_depth = 1,
|
.layer_count_or_depth = 1,
|
||||||
@ -620,25 +620,25 @@ fn void Renderer.new_texture_by_id(&self, Id id, TextureType type, char[] pixels
|
|||||||
// .sample_count not used since the texture is not a render target
|
// .sample_count not used since the texture is not a render target
|
||||||
};
|
};
|
||||||
|
|
||||||
GPUTexture* texture = sdl::create_gpu_texture(self.gpu, &tci);
|
GPUTexture* texture = sdl3::createGPUTexture(self.gpu, &tci);
|
||||||
if (texture == null) {
|
if (texture == null) {
|
||||||
unreachable("failed to create texture (id: %s, type: %s): %s", id, type.nameof, sdl::get_error());
|
unreachable("failed to create texture (id: %s, type: %s): %s", id, type.nameof, sdl3::getError());
|
||||||
}
|
}
|
||||||
|
|
||||||
// the sampler description, how the texture should be sampled
|
// the sampler description, how the texture should be sampled
|
||||||
GPUSamplerCreateInfo sci = {
|
GPUSamplerCreateInfo sci = {
|
||||||
.min_filter = GPU_FILTER_LINEAR, // linear interpolation for textures
|
.min_filter = LINEAR, // linear interpolation for textures
|
||||||
.mag_filter = GPU_FILTER_LINEAR,
|
.mag_filter = LINEAR,
|
||||||
.mipmap_mode = GPU_SAMPLERMIPMAPMODE_NEAREST,
|
.mipmap_mode = NEAREST,
|
||||||
.address_mode_u = GPU_SAMPLERADDRESSMODE_REPEAT, // tiling textures
|
.address_mode_u = REPEAT, // tiling textures
|
||||||
.address_mode_v = GPU_SAMPLERADDRESSMODE_REPEAT,
|
.address_mode_v = REPEAT,
|
||||||
.address_mode_w = GPU_SAMPLERADDRESSMODE_REPEAT,
|
.address_mode_w = REPEAT,
|
||||||
// everything else is not used and not needed
|
// everything else is not used and not needed
|
||||||
};
|
};
|
||||||
|
|
||||||
GPUSampler* sampler = sdl::create_gpu_sampler(self.gpu, &sci);
|
GPUSampler* sampler = sdl3::createGPUSampler(self.gpu, &sci);
|
||||||
if (sampler == null) {
|
if (sampler == null) {
|
||||||
unreachable("failed to create sampler (texture id: %s, type: %s): %s", id, type.nameof, sdl::get_error());
|
unreachable("failed to create sampler (texture id: %s, type: %s): %s", id, type.nameof, sdl3::getError());
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture t = {
|
Texture t = {
|
||||||
@ -671,42 +671,42 @@ fn void Renderer.update_texture_by_id(&self, Id id, char[] pixels, uint width, u
|
|||||||
}
|
}
|
||||||
|
|
||||||
// upload image data
|
// upload image data
|
||||||
GPUCommandBuffer* cmdbuf = sdl::acquire_gpu_command_buffer(self.gpu);
|
GPUCommandBuffer* cmdbuf = sdl3::acquireGPUCommandBuffer(self.gpu);
|
||||||
if (cmdbuf == null) {
|
if (cmdbuf == null) {
|
||||||
unreachable("failed to upload texture data at acquiring command buffer: %s", sdl::get_error());
|
unreachable("failed to upload texture data at acquiring command buffer: %s", sdl3::getError());
|
||||||
}
|
}
|
||||||
GPUCopyPass* copypass = sdl::begin_gpu_copy_pass(cmdbuf);
|
GPUCopyPass* copypass = sdl3::beginGPUCopyPass(cmdbuf);
|
||||||
if (copypass == null) {
|
if (copypass == null) {
|
||||||
unreachable("failed to upload texture data at beginning copy pass: %s", sdl::get_error());
|
unreachable("failed to upload texture data at beginning copy pass: %s", sdl3::getError());
|
||||||
}
|
}
|
||||||
|
|
||||||
GPUTransferBuffer* buf = sdl::create_gpu_transfer_buffer(self.gpu,
|
GPUTransferBuffer* buf = sdl3::createGPUTransferBuffer(self.gpu,
|
||||||
&&(GPUTransferBufferCreateInfo){.usage = GPU_TRANSFERBUFFERUSAGE_UPLOAD, .size = pixels.len}
|
&&(GPUTransferBufferCreateInfo){.usage = UPLOAD, .size = pixels.len}
|
||||||
);
|
);
|
||||||
if (buf == null) {
|
if (buf == null) {
|
||||||
unreachable("failed to upload texture data at creating the transfer buffer: %s", sdl::get_error());
|
unreachable("failed to upload texture data at creating the transfer buffer: %s", sdl3::getError());
|
||||||
}
|
}
|
||||||
|
|
||||||
char* gpu_mem = (char*)sdl::map_gpu_transfer_buffer(self.gpu, buf, CYCLE);
|
char* gpu_mem = (char*)sdl3::mapGPUTransferBuffer(self.gpu, buf, CYCLE);
|
||||||
if (gpu_mem == null) {
|
if (gpu_mem == null) {
|
||||||
unreachable("failed to upload texture data at mapping the transfer buffer: %s", sdl::get_error());
|
unreachable("failed to upload texture data at mapping the transfer buffer: %s", sdl3::getError());
|
||||||
}
|
}
|
||||||
// copy the data to the driver's memory
|
// copy the data to the driver's memory
|
||||||
gpu_mem[:pixels.len] = pixels[..];
|
gpu_mem[:pixels.len] = pixels[..];
|
||||||
sdl::unmap_gpu_transfer_buffer(self.gpu, buf);
|
sdl3::unmapGPUTransferBuffer(self.gpu, buf);
|
||||||
|
|
||||||
// upload the data to gpu memory
|
// upload the data to gpu memory
|
||||||
sdl::upload_to_gpu_texture(copypass,
|
sdl3::uploadToGPUTexture(copypass,
|
||||||
&&(GPUTextureTransferInfo){.transfer_buffer = buf, .offset = 0},
|
&&(GPUTextureTransferInfo){.transfer_buffer = buf, .offset = 0},
|
||||||
&&(GPUTextureRegion){.texture = texture, .x = x, .y = y, .w = width, .h = height, .d = 1},
|
&&(GPUTextureRegion){.texture = texture, .x = x, .y = y, .w = width, .h = height, .d = 1},
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
sdl::end_gpu_copy_pass(copypass);
|
sdl3::endGPUCopyPass(copypass);
|
||||||
if (!sdl::submit_gpu_command_buffer(cmdbuf)) {
|
if (!sdl3::submitGPUCommandBuffer(cmdbuf)) {
|
||||||
unreachable("failed to upload texture data at command buffer submission: %s", sdl::get_error());
|
unreachable("failed to upload texture data at command buffer submission: %s", sdl3::getError());
|
||||||
}
|
}
|
||||||
sdl::release_gpu_transfer_buffer(self.gpu, buf);
|
sdl3::releaseGPUTransferBuffer(self.gpu, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -768,22 +768,22 @@ fn void Renderer.upload_quads(&self)
|
|||||||
{
|
{
|
||||||
QuadBuffer* qb = &self.quad_buffer;
|
QuadBuffer* qb = &self.quad_buffer;
|
||||||
|
|
||||||
GPUCommandBuffer* cmd = sdl::acquire_gpu_command_buffer(self.gpu);
|
GPUCommandBuffer* cmd = sdl3::acquireGPUCommandBuffer(self.gpu);
|
||||||
if (cmd == null) {
|
if (cmd == null) {
|
||||||
unreachable("failed to upload quad at acquiring command buffer: %s", sdl::get_error());
|
unreachable("failed to upload quad at acquiring command buffer: %s", sdl3::getError());
|
||||||
}
|
}
|
||||||
GPUCopyPass* cpy = sdl::begin_gpu_copy_pass(cmd);
|
GPUCopyPass* cpy = sdl3::beginGPUCopyPass(cmd);
|
||||||
|
|
||||||
// upload quad attributes
|
// upload quad attributes
|
||||||
sdl::upload_to_gpu_buffer(cpy,
|
sdl3::uploadToGPUBuffer(cpy,
|
||||||
&&(GPUTransferBufferLocation){.transfer_buffer = qb.attr_ts, .offset = 0},
|
&&(GPUTransferBufferLocation){.transfer_buffer = qb.attr_ts, .offset = 0},
|
||||||
&&(GPUBufferRegion){.buffer = qb.attr_buf, .offset = 0, .size = QuadAttributes.sizeof * qb.count},
|
&&(GPUBufferRegion){.buffer = qb.attr_buf, .offset = 0, .size = QuadAttributes.sizeof * qb.count},
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
sdl::end_gpu_copy_pass(cpy);
|
sdl3::endGPUCopyPass(cpy);
|
||||||
if (!sdl::submit_gpu_command_buffer(cmd)) {
|
if (!sdl3::submitGPUCommandBuffer(cmd)) {
|
||||||
unreachable("failed to upload quads at submit command buffer: %s", sdl::get_error());
|
unreachable("failed to upload quads at submit command buffer: %s", sdl3::getError());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -798,14 +798,14 @@ fn void Renderer.draw_quads(&self, uint off, uint count)
|
|||||||
unreachable("too many quads, have %d, requested %d, offset %d", qb.count, count, off);
|
unreachable("too many quads, have %d, requested %d, offset %d", qb.count, count, off);
|
||||||
}
|
}
|
||||||
|
|
||||||
sdl::bind_gpu_vertex_buffers(self.render_pass, 0,
|
sdl3::bindGPUVertexBuffers(self.render_pass, 0,
|
||||||
(GPUBufferBinding[]){
|
(GPUBufferBinding[]){
|
||||||
{.buffer = qb.vert_buf, .offset = 0},
|
{.buffer = qb.vert_buf, .offset = 0},
|
||||||
{.buffer = qb.attr_buf, .offset = 0},
|
{.buffer = qb.attr_buf, .offset = 0},
|
||||||
}, 2);
|
}, 2);
|
||||||
sdl::bind_gpu_index_buffer(self.render_pass, &&(GPUBufferBinding){.buffer = qb.idx_buf, .offset = 0}, GPU_INDEXELEMENTSIZE_16BIT);
|
sdl3::bindGPUIndexBuffer(self.render_pass, &&(GPUBufferBinding){.buffer = qb.idx_buf, .offset = 0}, BIT16);
|
||||||
|
|
||||||
sdl::draw_gpu_indexed_primitives(self.render_pass, 6, count, 0, 0, off);
|
sdl3::drawGPUIndexedPrimitives(self.render_pass, 6, count, 0, 0, off);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn void Renderer.reset_quads(&self)
|
fn void Renderer.reset_quads(&self)
|
||||||
@ -816,25 +816,25 @@ fn void Renderer.reset_quads(&self)
|
|||||||
|
|
||||||
fn void Renderer.begin_render(&self, bool clear_screen)
|
fn void Renderer.begin_render(&self, bool clear_screen)
|
||||||
{
|
{
|
||||||
self.render_cmdbuf = sdl::acquire_gpu_command_buffer(self.gpu);
|
self.render_cmdbuf = sdl3::acquireGPUCommandBuffer(self.gpu);
|
||||||
sdl::wait_and_acquire_gpu_swapchain_texture(self.render_cmdbuf, self.win, &self.swapchain_texture, null, null);
|
sdl3::waitAndAcquireGPUSwapchainTexture(self.render_cmdbuf, self.win, &self.swapchain_texture, null, null);
|
||||||
|
|
||||||
// push the window size as a uniform
|
// push the window size as a uniform
|
||||||
// TODO: maybe make this configurable and/or add more things
|
// TODO: maybe make this configurable and/or add more things
|
||||||
ViewsizeUniform v;
|
ViewsizeUniform v;
|
||||||
self.get_window_size(&v.w, &v.h);
|
self.get_window_size(&v.w, &v.h);
|
||||||
sdl::push_gpu_vertex_uniform_data(self.render_cmdbuf, 0, &v, ViewsizeUniform.sizeof);
|
sdl3::pushGPUVertexUniformData(self.render_cmdbuf, 0, &v, ViewsizeUniform.sizeof);
|
||||||
sdl::push_gpu_fragment_uniform_data(self.render_cmdbuf, 0, &v, ViewsizeUniform.sizeof);
|
sdl3::pushGPUFragmentUniformData(self.render_cmdbuf, 0, &v, ViewsizeUniform.sizeof);
|
||||||
|
|
||||||
if (clear_screen) {
|
if (clear_screen) {
|
||||||
GPURenderPass* pass = sdl::begin_gpu_render_pass(self.render_cmdbuf,
|
GPURenderPass* pass = sdl3::beginGPURenderPass(self.render_cmdbuf,
|
||||||
&&(GPUColorTargetInfo){
|
&&(GPUColorTargetInfo){
|
||||||
.texture = self.swapchain_texture,
|
.texture = self.swapchain_texture,
|
||||||
.mip_level = 0,
|
.mip_level = 0,
|
||||||
.layer_or_depth_plane = 0,
|
.layer_or_depth_plane = 0,
|
||||||
.clear_color = {.r = 1.0, .g = 0.0, .b = 1.0, .a = 1.0},
|
.clear_color = {.r = 1.0, .g = 0.0, .b = 1.0, .a = 1.0},
|
||||||
.load_op = GPU_LOADOP_CLEAR, // clear the screen at the start of the render pass
|
.load_op = CLEAR, // clear the screen at the start of the render pass
|
||||||
.store_op = GPU_STOREOP_STORE,
|
.store_op = STORE,
|
||||||
.resolve_texture = null,
|
.resolve_texture = null,
|
||||||
.resolve_mip_level = 0,
|
.resolve_mip_level = 0,
|
||||||
.resolve_layer = 0,
|
.resolve_layer = 0,
|
||||||
@ -845,31 +845,31 @@ fn void Renderer.begin_render(&self, bool clear_screen)
|
|||||||
null // huh
|
null // huh
|
||||||
);
|
);
|
||||||
if (pass == null) {
|
if (pass == null) {
|
||||||
unreachable("render pass creation went wrong: %s", sdl::get_error());
|
unreachable("render pass creation went wrong: %s", sdl3::getError());
|
||||||
}
|
}
|
||||||
|
|
||||||
sdl::end_gpu_render_pass(pass);
|
sdl3::endGPURenderPass(pass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn void Renderer.end_render(&self)
|
fn void Renderer.end_render(&self)
|
||||||
{
|
{
|
||||||
sdl::submit_gpu_command_buffer(self.render_cmdbuf);
|
sdl3::submitGPUCommandBuffer(self.render_cmdbuf);
|
||||||
self.reset_quads();
|
self.reset_quads();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn void Renderer.start_render_pass(&self, String pipeline_name)
|
fn void Renderer.start_render_pass(&self, String pipeline_name)
|
||||||
{
|
{
|
||||||
self.render_pass = sdl::begin_gpu_render_pass(self.render_cmdbuf,
|
self.render_pass = sdl3::beginGPURenderPass(self.render_cmdbuf,
|
||||||
&&(GPUColorTargetInfo){
|
&&(GPUColorTargetInfo){
|
||||||
.texture = self.swapchain_texture,
|
.texture = self.swapchain_texture,
|
||||||
.mip_level = 0,
|
.mip_level = 0,
|
||||||
.layer_or_depth_plane = 0,
|
.layer_or_depth_plane = 0,
|
||||||
.clear_color = {.r = 0.0, .g = 0.0, .b = 0.0, .a = 1.0},
|
.clear_color = {.r = 0.0, .g = 0.0, .b = 0.0, .a = 1.0},
|
||||||
.load_op = GPU_LOADOP_DONT_CARE,
|
.load_op = DONT_CARE,
|
||||||
.store_op = GPU_STOREOP_STORE,
|
.store_op = STORE,
|
||||||
.resolve_texture = null,
|
.resolve_texture = null,
|
||||||
.resolve_mip_level = 0,
|
.resolve_mip_level = 0,
|
||||||
.resolve_layer = 0,
|
.resolve_layer = 0,
|
||||||
@ -881,22 +881,22 @@ fn void Renderer.start_render_pass(&self, String pipeline_name)
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (self.render_pass == null) {
|
if (self.render_pass == null) {
|
||||||
unreachable("render pass creation went wrong: %s", sdl::get_error());
|
unreachable("render pass creation went wrong: %s", sdl3::getError());
|
||||||
}
|
}
|
||||||
|
|
||||||
sdl::GPUGraphicsPipeline* p;
|
sdl3::GPUGraphicsPipeline* p;
|
||||||
p = self.pipelines.get_from_name(pipeline_name).pipeline;
|
p = self.pipelines.get_from_name(pipeline_name).pipeline;
|
||||||
if (p == null) {
|
if (p == null) {
|
||||||
unreachable("no pipeline");
|
unreachable("no pipeline");
|
||||||
}
|
}
|
||||||
|
|
||||||
sdl::bind_gpu_graphics_pipeline(self.render_pass, p);
|
sdl3::bindGPUGraphicsPipeline(self.render_pass, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn void Renderer.end_render_pass(&self)
|
fn void Renderer.end_render_pass(&self)
|
||||||
{
|
{
|
||||||
sdl::end_gpu_render_pass(self.render_pass);
|
sdl3::endGPURenderPass(self.render_pass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -908,7 +908,7 @@ fn void Renderer.bind_textures(&self, String... texture_names)
|
|||||||
if (tx == null) {
|
if (tx == null) {
|
||||||
unreachable("texture '%s' was not registered", name);
|
unreachable("texture '%s' was not registered", name);
|
||||||
}
|
}
|
||||||
sdl::bind_gpu_fragment_samplers(self.render_pass, (uint)idx,
|
sdl3::bindGPUFragmentSamplers(self.render_pass, (uint)idx,
|
||||||
(GPUTextureSamplerBinding[]){{.texture = tx.texture, .sampler = tx.sampler}}, 1
|
(GPUTextureSamplerBinding[]){{.texture = tx.texture, .sampler = tx.sampler}}, 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -923,7 +923,7 @@ fn void Renderer.bind_textures_id(&self, ugui::Id... texture_ids)
|
|||||||
if (tx == null) {
|
if (tx == null) {
|
||||||
unreachable("texture [%d] was not registered", id);
|
unreachable("texture [%d] was not registered", id);
|
||||||
}
|
}
|
||||||
sdl::bind_gpu_fragment_samplers(self.render_pass, (uint)idx,
|
sdl3::bindGPUFragmentSamplers(self.render_pass, (uint)idx,
|
||||||
(GPUTextureSamplerBinding[]){{.texture = tx.texture, .sampler = tx.sampler}}, 1
|
(GPUTextureSamplerBinding[]){{.texture = tx.texture, .sampler = tx.sampler}}, 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -935,13 +935,13 @@ fn void Renderer.set_scissor(&self, int x, int y, int w, int h)
|
|||||||
// in vulkan scissor size must be positive, clamp to zero
|
// in vulkan scissor size must be positive, clamp to zero
|
||||||
w = max(w, 0);
|
w = max(w, 0);
|
||||||
h = max(h, 0);
|
h = max(h, 0);
|
||||||
sdl::set_gpu_scissor(self.render_pass, &&(sdl::Rect){x,y,w,h});
|
sdl3::setGPUScissor(self.render_pass, &&(sdl3::Rect){x,y,w,h});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn void Renderer.reset_scissor(&self)
|
fn void Renderer.reset_scissor(&self)
|
||||||
{
|
{
|
||||||
int w, h;
|
int w, h;
|
||||||
sdl::get_window_size(self.win, &w, &h);
|
sdl3::getWindowSize(self.win, &w, &h);
|
||||||
self.set_scissor(0, 0, w, h);
|
self.set_scissor(0, 0, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1037,4 +1037,3 @@ fn void Renderer.render_ugui(&self, CmdQueue* queue)
|
|||||||
self.end_render_pass();
|
self.end_render_pass();
|
||||||
// ugui::println("calls: ", calls);
|
// ugui::println("calls: ", calls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user