Initial setup of sokol_gfx to replace the raylib impl for rendering.
Next I need to setup sokol_gp
This commit is contained in:
@ -11,7 +11,10 @@ import "core:strings"
|
||||
import "core:time"
|
||||
import "core:prof/spall"
|
||||
|
||||
import sokol_app "thirdparty:sokol/app"
|
||||
import sokol_app "thirdparty:sokol/app"
|
||||
import sokol_gfx "thirdparty:sokol/gfx"
|
||||
import sokol_app_gfx_glue "thirdparty:sokol/glue"
|
||||
|
||||
import rl "vendor:raylib"
|
||||
|
||||
Path_Assets :: "../assets/"
|
||||
@ -188,6 +191,79 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
|
||||
}
|
||||
}
|
||||
|
||||
// Setup sokol_gfx
|
||||
{
|
||||
glue_env := sokol_app_gfx_glue.environment()
|
||||
|
||||
desc := sokol_gfx.Desc {
|
||||
buffer_pool_size = 128,
|
||||
image_pool_size = 128,
|
||||
sampler_pool_size = 64,
|
||||
shader_pool_size = 32,
|
||||
pipeline_pool_size = 64,
|
||||
// pass_pool_size = 16, // (No longer exists)
|
||||
attachments_pool_size = 16,
|
||||
uniform_buffer_size = 4 * Megabyte,
|
||||
max_commit_listeners = Kilo,
|
||||
allocator = { sokol_gfx_alloc, sokol_gfx_free, nil },
|
||||
logger = { sokol_gfx_log_callback, nil },
|
||||
environment = glue_env,
|
||||
}
|
||||
sokol_gfx.setup(desc)
|
||||
|
||||
backend := sokol_gfx.query_backend()
|
||||
switch backend
|
||||
{
|
||||
case .D3D11: logf("sokol_gfx: using D3D11 backend")
|
||||
case .GLCORE, .GLES3: logf("sokol_gfx: using GL backend")
|
||||
|
||||
case .METAL_MACOS, .METAL_IOS, .METAL_SIMULATOR:
|
||||
logf("sokol_gfx: using Metal backend")
|
||||
|
||||
case .WGPU: logf("sokol_gfx: using WebGPU backend")
|
||||
case .DUMMY: logf("sokol_gfx: using dummy backend")
|
||||
}
|
||||
|
||||
// Learning examples
|
||||
{
|
||||
|
||||
debug.gfx_clear_demo_pass_action.colors[0] = {
|
||||
load_action = .CLEAR,
|
||||
clear_value = { 1, 0, 0, 1 }
|
||||
}
|
||||
vertices := [?]f32 {
|
||||
// positions // colors
|
||||
0.0, 0.5, 0.5, 1.0, 0.0, 0.0, 1.0,
|
||||
0.5, -0.5, 0.5, 0.0, 1.0, 0.0, 1.0,
|
||||
-0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 1.0,
|
||||
}
|
||||
|
||||
tri_shader_attr_vs_position :: 0
|
||||
tri_shader_attr_vs_color0 :: 1
|
||||
|
||||
using debug.gfx_tri_demo_state
|
||||
bindings.vertex_buffers[0] = sokol_gfx.make_buffer( sokol_gfx.Buffer_Desc {
|
||||
data = {
|
||||
ptr = & vertices,
|
||||
size = size_of(vertices)
|
||||
}
|
||||
})
|
||||
pipeline = sokol_gfx.make_pipeline( sokol_gfx.Pipeline_Desc {
|
||||
shader = sokol_gfx.make_shader( triangle_shader_desc(backend)),
|
||||
layout = sokol_gfx.Vertex_Layout_State {
|
||||
attrs = {
|
||||
tri_shader_attr_vs_position = { format = .FLOAT3 },
|
||||
tri_shader_attr_vs_color0 = { format = .FLOAT4 },
|
||||
}
|
||||
}
|
||||
})
|
||||
pass_action.colors[0] = {
|
||||
load_action = .CLEAR,
|
||||
clear_value = { 0, 0, 0, 1 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Basic Font Setup
|
||||
if false
|
||||
{
|
||||
@ -205,7 +281,7 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
|
||||
}
|
||||
|
||||
// Setup the screen ui state
|
||||
if false
|
||||
if true
|
||||
{
|
||||
ui_startup( & screen_ui.base, cache_allocator = persistent_slab_allocator() )
|
||||
ui_floating_startup( & screen_ui.floating, persistent_slab_allocator(), 1 * Kilobyte, 1 * Kilobyte, "screen ui floating manager" )
|
||||
@ -220,7 +296,7 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
|
||||
|
||||
// Demo project setup
|
||||
// TODO(Ed): This will eventually have to occur when the user either creates or loads a workspace. I don't know
|
||||
if false
|
||||
if true
|
||||
{
|
||||
using project
|
||||
path = str_intern("./")
|
||||
@ -345,48 +421,55 @@ tick :: proc( host_delta_time_ms : f64, host_delta_ns : Duration ) -> b32
|
||||
state := get_state(); using state
|
||||
|
||||
client_tick := time.tick_now()
|
||||
tick_work_frame()
|
||||
should_close |= tick_work_frame( host_delta_time_ms)
|
||||
tick_frametime( & client_tick, host_delta_time_ms, host_delta_ns )
|
||||
|
||||
profile_begin("sokol_app: post_client_tick")
|
||||
sokol_app.post_client_frame()
|
||||
profile_end()
|
||||
return ! should_close
|
||||
}
|
||||
|
||||
|
||||
// Lifted out of tick so that sokol_app_frame_callback can do it as well.
|
||||
tick_work_frame :: #force_inline proc()
|
||||
tick_work_frame :: #force_inline proc( host_delta_time_ms : f64 ) -> b32
|
||||
{
|
||||
context.logger = to_odin_logger( & Memory_App.logger )
|
||||
state := get_state(); using state
|
||||
profile("Work frame")
|
||||
context.logger = to_odin_logger( & Memory_App.logger )
|
||||
state := get_state(); using state
|
||||
profile("Work frame")
|
||||
|
||||
// Setup Frame Slab
|
||||
{
|
||||
alloc_error : AllocatorError
|
||||
frame_slab, alloc_error = slab_init( & default_slab_policy, bucket_reserve_num = 0,
|
||||
allocator = frame_allocator(),
|
||||
dbg_name = Frame_Slab_DBG_Name,
|
||||
should_zero_buckets = true )
|
||||
verify( alloc_error == .None, "Failed to allocate frame slab" )
|
||||
}
|
||||
should_close : b32
|
||||
|
||||
// The policy for the work tick is that the default allocator is the frame's slab.
|
||||
// Transient's is the temp allocator.
|
||||
context.allocator = frame_slab_allocator()
|
||||
context.temp_allocator = transient_allocator()
|
||||
// Setup Frame Slab
|
||||
{
|
||||
alloc_error : AllocatorError
|
||||
frame_slab, alloc_error = slab_init( & default_slab_policy, bucket_reserve_num = 0,
|
||||
allocator = frame_allocator(),
|
||||
dbg_name = Frame_Slab_DBG_Name,
|
||||
should_zero_buckets = true )
|
||||
verify( alloc_error == .None, "Failed to allocate frame slab" )
|
||||
}
|
||||
|
||||
// rl.PollInputEvents()
|
||||
// The policy for the work tick is that the default allocator is the frame's slab.
|
||||
// Transient's is the temp allocator.
|
||||
context.allocator = frame_slab_allocator()
|
||||
context.temp_allocator = transient_allocator()
|
||||
|
||||
debug.draw_ui_box_bounds_points = false
|
||||
debug.draw_UI_padding_bounds = false
|
||||
debug.draw_ui_content_bounds = false
|
||||
// rl.PollInputEvents()
|
||||
|
||||
// config.color_theme = App_Thm_Light
|
||||
// config.color_theme = App_Thm_Dusk
|
||||
config.color_theme = App_Thm_Dark
|
||||
debug.draw_ui_box_bounds_points = false
|
||||
debug.draw_UI_padding_bounds = false
|
||||
debug.draw_ui_content_bounds = false
|
||||
|
||||
// should_close |= update( host_delta_time )
|
||||
// render()
|
||||
// config.color_theme = App_Thm_Light
|
||||
// config.color_theme = App_Thm_Dusk
|
||||
config.color_theme = App_Thm_Dark
|
||||
|
||||
// rl.SwapScreenBuffer()
|
||||
should_close |= update( host_delta_time_ms )
|
||||
render()
|
||||
|
||||
// rl.SwapScreenBuffer()
|
||||
return should_close
|
||||
}
|
||||
|
||||
// Lifted out of tick so that sokol_app_frame_callback can do it as well.
|
||||
@ -440,10 +523,6 @@ tick_frametime :: #force_inline proc( client_tick : ^time.Tick, host_delta_time_
|
||||
if frametime_elapsed_ms > 60.0 {
|
||||
log( str_fmt("Big tick! %v ms", frametime_elapsed_ms), LogLevel.Warning )
|
||||
}
|
||||
|
||||
profile_begin("sokol_app: post_client_tick")
|
||||
sokol_app.post_client_frame()
|
||||
profile_end()
|
||||
}
|
||||
|
||||
@export
|
||||
|
@ -6,17 +6,20 @@ import str "core:strings"
|
||||
|
||||
import sokol_app "thirdparty:sokol/app"
|
||||
|
||||
#region("Sokol App")
|
||||
|
||||
sokol_app_init_callback :: proc "c" () {
|
||||
context = get_state().sokol_context
|
||||
log("sokol_app: Confirmed initialization")
|
||||
}
|
||||
|
||||
// This is being filled in but we're directly controlling the lifetime of sokol_app's execution.
|
||||
// So this will only get called during resize events (on Win32 at least)
|
||||
// So this will only get called during window pan or resize events (on Win32 at least)
|
||||
sokol_app_frame_callback :: proc "c" () {
|
||||
context = get_state().sokol_context
|
||||
state := get_state()
|
||||
|
||||
state := get_state()
|
||||
should_close : b32
|
||||
|
||||
sokol_width := sokol_app.widthf()
|
||||
sokol_height := sokol_app.heightf()
|
||||
@ -33,7 +36,7 @@ sokol_app_frame_callback :: proc "c" () {
|
||||
sokol_delta_ns := transmute(Duration) sokol_delta_ms * MS_To_NS
|
||||
|
||||
client_tick := time.tick_now()
|
||||
tick_work_frame()
|
||||
should_close |= tick_work_frame( sokol_delta_ms )
|
||||
tick_frametime( & client_tick, sokol_delta_ms, sokol_delta_ns )
|
||||
}
|
||||
|
||||
@ -45,7 +48,7 @@ sokol_app_cleanup_callback :: proc "c" () {
|
||||
sokol_app_alloc :: proc "c" ( size : u64, user_data : rawptr ) -> rawptr {
|
||||
context = get_state().sokol_context
|
||||
block, error := alloc( int(size), allocator = persistent_slab_allocator() )
|
||||
ensure(error != AllocatorError.None, "sokol_app allocation failed")
|
||||
ensure(error == AllocatorError.None, "sokol_app allocation failed")
|
||||
return block
|
||||
}
|
||||
|
||||
@ -95,3 +98,52 @@ sokol_app_event_callback :: proc "c" (event : ^sokol_app.Event)
|
||||
monitor_refresh_hz := sokol_app.refresh_rate()
|
||||
}
|
||||
}
|
||||
|
||||
#endregion("Sokol App")
|
||||
|
||||
#region("Sokol GFX")
|
||||
|
||||
sokol_gfx_alloc :: proc "c" ( size : u64, user_data : rawptr ) -> rawptr {
|
||||
context = get_state().sokol_context
|
||||
block, error := alloc( int(size), allocator = persistent_slab_allocator() )
|
||||
ensure(error == AllocatorError.None, "sokol_gfx allocation failed")
|
||||
return block
|
||||
}
|
||||
|
||||
sokol_gfx_free :: proc "c" ( data : rawptr, user_data : rawptr ) {
|
||||
context = get_state().sokol_context
|
||||
free(data, allocator = persistent_slab_allocator() )
|
||||
}
|
||||
|
||||
sokol_gfx_log_callback :: proc "c" (
|
||||
tag: cstring,
|
||||
log_level: u32,
|
||||
log_item_id: u32,
|
||||
message_or_null: cstring,
|
||||
line_nr: u32,
|
||||
filename_or_null: cstring,
|
||||
user_data: rawptr) {
|
||||
context = get_state().sokol_context
|
||||
|
||||
odin_level : LogLevel
|
||||
switch log_level {
|
||||
case 0: odin_level = .Fatal
|
||||
case 1: odin_level = .Error
|
||||
case 2: odin_level = .Warning
|
||||
case 3: odin_level = .Info
|
||||
}
|
||||
|
||||
cloned_msg : string = ""
|
||||
if message_or_null != nil {
|
||||
cloned_msg = str.clone_from_cstring(message_or_null, context.temp_allocator)
|
||||
}
|
||||
cloned_fname : string = ""
|
||||
if filename_or_null != nil {
|
||||
cloned_fname = str.clone_from_cstring(filename_or_null, context.temp_allocator)
|
||||
}
|
||||
|
||||
cloned_tag := str.clone_from_cstring(tag, context.temp_allocator)
|
||||
logf( "%-80s %s::%v", cloned_msg, cloned_tag, line_nr, level = odin_level )
|
||||
}
|
||||
|
||||
#endregion("Sokol GFX")
|
||||
|
@ -4,6 +4,7 @@ import "core:fmt"
|
||||
|
||||
import rl "vendor:raylib"
|
||||
|
||||
when false {
|
||||
range2_to_rl_rect :: #force_inline proc "contextless"( range : Range2 ) -> rl.Rectangle
|
||||
{
|
||||
rect := rl.Rectangle {
|
||||
@ -399,3 +400,4 @@ render_screen_ui :: proc()
|
||||
}
|
||||
//endregion App UI
|
||||
}
|
||||
} // when false
|
||||
|
@ -1,2 +1,37 @@
|
||||
package sectr
|
||||
|
||||
import sokol_gfx "thirdparty:sokol/gfx"
|
||||
import sokol_glue "thirdparty:sokol/glue"
|
||||
|
||||
render :: proc()
|
||||
{
|
||||
state := get_state(); using state
|
||||
|
||||
// Clear Demo
|
||||
if false
|
||||
{
|
||||
green_value := debug.gfx_clear_demo_pass_action.colors[0].clear_value.g + 0.01
|
||||
debug.gfx_clear_demo_pass_action.colors[0].clear_value.g = green_value > 1.0 ? 0.0 : green_value
|
||||
|
||||
sokol_gfx.begin_pass( sokol_gfx.Pass {
|
||||
action = debug.gfx_clear_demo_pass_action,
|
||||
swapchain = sokol_glue.swapchain()
|
||||
})
|
||||
sokol_gfx.end_pass()
|
||||
sokol_gfx.commit()
|
||||
}
|
||||
|
||||
// Triangle Demo
|
||||
if true
|
||||
{
|
||||
using debug.gfx_tri_demo_state
|
||||
sokol_gfx.begin_pass(sokol_gfx.Pass { action = pass_action, swapchain = sokol_glue.swapchain() })
|
||||
sokol_gfx.apply_pipeline( pipeline )
|
||||
sokol_gfx.apply_bindings( bindings )
|
||||
|
||||
sokol_gfx.draw( 0, 3, 1 )
|
||||
|
||||
sokol_gfx.end_pass()
|
||||
sokol_gfx.commit()
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import "core:strings"
|
||||
import "core:unicode/utf8"
|
||||
import rl "vendor:raylib"
|
||||
|
||||
when false {
|
||||
debug_draw_text :: proc( content : string, pos : Vec2, size : f32, color : rl.Color = rl.WHITE, font : FontID = Font_Default )
|
||||
{
|
||||
// profile(#procedure)
|
||||
@ -222,3 +223,4 @@ measure_text_size_raylib :: proc( text : string, font : FontID, font_size := Fon
|
||||
|
||||
return text_size
|
||||
}
|
||||
} // when false
|
||||
|
@ -66,6 +66,7 @@ frametime_delta32 :: #force_inline proc "contextless" () -> f32 {
|
||||
return cast(f32) get_state().frametime_avg_ms
|
||||
}
|
||||
|
||||
//TODO(Ed): Just use avg delta not this.
|
||||
update :: proc( delta_time : f64 ) -> b32
|
||||
{
|
||||
profile(#procedure)
|
||||
|
Reference in New Issue
Block a user