From 5e180be9cd07221765a8c44c25996f38c415ab5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matheus=20Catarino=20Fran=C3=A7a?= Date: Sat, 6 Jan 2024 16:34:53 -0300 Subject: [PATCH] update: https://github.com/floooh/sokol/commit/daa88ad3ea9688f9e14ecb593f63760bf7aba25c --- src/sokol/c/sokol_app.h | 127 +++++++++------------------------------- src/sokol/c/sokol_gfx.h | 115 ++++++++++++++++++++++++++++-------- src/sokol/gfx.d | 12 +++- 3 files changed, 129 insertions(+), 125 deletions(-) diff --git a/src/sokol/c/sokol_app.h b/src/sokol/c/sokol_app.h index 1782b97..a9fca16 100644 --- a/src/sokol/c/sokol_app.h +++ b/src/sokol/c/sokol_app.h @@ -1665,7 +1665,7 @@ typedef struct sapp_desc { sapp_allocator allocator; // optional memory allocation overrides (default: malloc/free) sapp_logger logger; // logging callback override (default: NO LOGGING!) - /* backend-specific options */ + // backend-specific options int gl_major_version; // override GL major and minor version (the default GL version is 3.2) int gl_minor_version; bool win32_console_utf8; // if true, set the output console codepage to UTF-8 @@ -1894,8 +1894,8 @@ inline void sapp_run(const sapp_desc& desc) { return sapp_run(&desc); } // NOTE: the pixel format values *must* be compatible with sg_pixel_format #define _SAPP_PIXELFORMAT_RGBA8 (23) #define _SAPP_PIXELFORMAT_BGRA8 (28) -#define _SAPP_PIXELFORMAT_DEPTH (42) -#define _SAPP_PIXELFORMAT_DEPTH_STENCIL (43) +#define _SAPP_PIXELFORMAT_DEPTH (43) +#define _SAPP_PIXELFORMAT_DEPTH_STENCIL (44) #if defined(_SAPP_MACOS) || defined(_SAPP_IOS) // this is ARC compatible @@ -2411,9 +2411,6 @@ typedef struct { #endif typedef struct { - bool textfield_created; - bool wants_show_keyboard; - bool wants_hide_keyboard; bool mouse_lock_requested; uint16_t mouse_buttons; } _sapp_emsc_t; @@ -4648,13 +4645,6 @@ extern "C" { typedef void (*_sapp_html5_fetch_callback) (const sapp_html5_fetch_response*); -/* this function is called from a JS event handler when the user hides - the onscreen keyboard pressing the 'dismiss keyboard key' -*/ -EMSCRIPTEN_KEEPALIVE void _sapp_emsc_notify_keyboard_hidden(void) { - _sapp.onscreen_keyboard_shown = false; -} - EMSCRIPTEN_KEEPALIVE void _sapp_emsc_onpaste(const char* str) { if (_sapp.clipboard.enabled) { _sapp_strcpy(str, _sapp.clipboard.buffer, _sapp.clipboard.buf_size); @@ -4745,27 +4735,6 @@ EMSCRIPTEN_KEEPALIVE void _sapp_emsc_invoke_fetch_cb(int index, int success, int } /* extern "C" */ #endif -/* Javascript helper functions for mobile virtual keyboard input */ -EM_JS(void, sapp_js_create_textfield, (void), { - const _sapp_inp = document.createElement("input"); - _sapp_inp.type = "text"; - _sapp_inp.id = "_sokol_app_input_element"; - _sapp_inp.autocapitalize = "none"; - _sapp_inp.addEventListener("focusout", function(_sapp_event) { - __sapp_emsc_notify_keyboard_hidden() - - }); - document.body.append(_sapp_inp); -}); - -EM_JS(void, sapp_js_focus_textfield, (void), { - document.getElementById("_sokol_app_input_element").focus(); -}); - -EM_JS(void, sapp_js_unfocus_textfield, (void), { - document.getElementById("_sokol_app_input_element").blur(); -}); - EM_JS(void, sapp_js_add_beforeunload_listener, (void), { Module.sokol_beforeunload = (event) => { if (__sapp_html5_get_ask_leave_site() != 0) { @@ -4901,45 +4870,6 @@ EM_JS(void, sapp_js_remove_dragndrop_listeners, (const char* canvas_name_cstr), canvas.removeEventListener('drop', Module.sokol_drop); }); -/* called from the emscripten event handler to update the keyboard visibility - state, this must happen from an JS input event handler, otherwise - the request will be ignored by the browser -*/ -_SOKOL_PRIVATE void _sapp_emsc_update_keyboard_state(void) { - if (_sapp.emsc.wants_show_keyboard) { - /* create input text field on demand */ - if (!_sapp.emsc.textfield_created) { - _sapp.emsc.textfield_created = true; - sapp_js_create_textfield(); - } - /* focus the text input field, this will bring up the keyboard */ - _sapp.onscreen_keyboard_shown = true; - _sapp.emsc.wants_show_keyboard = false; - sapp_js_focus_textfield(); - } - if (_sapp.emsc.wants_hide_keyboard) { - /* unfocus the text input field */ - if (_sapp.emsc.textfield_created) { - _sapp.onscreen_keyboard_shown = false; - _sapp.emsc.wants_hide_keyboard = false; - sapp_js_unfocus_textfield(); - } - } -} - -/* actually showing the onscreen keyboard must be initiated from a JS - input event handler, so we'll just keep track of the desired - state, and the actual state change will happen with the next input event -*/ -_SOKOL_PRIVATE void _sapp_emsc_show_keyboard(bool show) { - if (show) { - _sapp.emsc.wants_show_keyboard = true; - } - else { - _sapp.emsc.wants_hide_keyboard = true; - } -} - EM_JS(void, sapp_js_init, (const char* c_str_target), { // lookup and store canvas object by name const target_str = UTF8ToString(c_str_target); @@ -5165,6 +5095,7 @@ _SOKOL_PRIVATE EM_BOOL _sapp_emsc_size_changed(int event_type, const EmscriptenU _SOKOL_PRIVATE EM_BOOL _sapp_emsc_mouse_cb(int emsc_type, const EmscriptenMouseEvent* emsc_event, void* user_data) { _SOKOL_UNUSED(user_data); + bool consume_event = false; _sapp.emsc.mouse_buttons = emsc_event->buttons; if (_sapp.mouse.locked) { _sapp.mouse.dx = (float) emsc_event->movementX; @@ -5225,15 +5156,14 @@ _SOKOL_PRIVATE EM_BOOL _sapp_emsc_mouse_cb(int emsc_type, const EmscriptenMouseE } else { _sapp.event.mouse_button = SAPP_MOUSEBUTTON_INVALID; } - _sapp_call_event(&_sapp.event); + consume_event = _sapp_call_event(&_sapp.event); } // mouse lock can only be activated in mouse button events (not in move, enter or leave) if (is_button_event) { _sapp_emsc_update_mouse_lock_state(); } } - _sapp_emsc_update_keyboard_state(); - return true; + return consume_event; } _SOKOL_PRIVATE EM_BOOL _sapp_emsc_wheel_cb(int emsc_type, const EmscriptenWheelEvent* emsc_event, void* user_data) { @@ -5255,8 +5185,9 @@ _SOKOL_PRIVATE EM_BOOL _sapp_emsc_wheel_cb(int emsc_type, const EmscriptenWheelE _sapp.event.scroll_y = scale * (float)emsc_event->deltaY; _sapp_call_event(&_sapp.event); } - _sapp_emsc_update_keyboard_state(); _sapp_emsc_update_mouse_lock_state(); + // NOTE: wheel events are always consumed because they try to scroll the + // page which looks pretty bad return true; } @@ -5383,7 +5314,7 @@ _SOKOL_PRIVATE sapp_keycode _sapp_emsc_translate_key(const char* str) { _SOKOL_PRIVATE EM_BOOL _sapp_emsc_key_cb(int emsc_type, const EmscriptenKeyboardEvent* emsc_event, void* user_data) { _SOKOL_UNUSED(user_data); - bool retval = true; + bool consume_event = false; if (_sapp_events_enabled()) { sapp_event_type type; switch (emsc_type) { @@ -5406,14 +5337,9 @@ _SOKOL_PRIVATE EM_BOOL _sapp_emsc_key_cb(int emsc_type, const EmscriptenKeyboard _sapp.event.key_repeat = emsc_event->repeat; _sapp.event.modifiers = _sapp_emsc_key_event_mods(emsc_event); if (type == SAPP_EVENTTYPE_CHAR) { - // FIXME: this doesn't appear to work on Android Chrome + // NOTE: charCode doesn't appear to be supported on Android Chrome _sapp.event.char_code = emsc_event->charCode; - /* workaround to make Cmd+V work on Safari */ - if ((emsc_event->metaKey) && (emsc_event->charCode == 118)) { - retval = false; - } - } - else { + } else { if (0 != emsc_event->code[0]) { // This code path is for desktop browsers which send untranslated 'physical' key code strings // (which is what we actually want for key events) @@ -5437,7 +5363,9 @@ _SOKOL_PRIVATE EM_BOOL _sapp_emsc_key_cb(int emsc_type, const EmscriptenKeyboard { send_keyup_followup = true; } - // only forward keys to the browser (can further be suppressed by sapp_consume_event()) + // Only forward alpha-numeric keys to the browser (can further be suppressed by sapp_consume_event()) + // NOTE: it should be possible to disable this behaviour via sapp_desc to give apps more + // controls over input event bubbling. switch (_sapp.event.key_code) { case SAPP_KEYCODE_WORLD_1: case SAPP_KEYCODE_WORLD_2: @@ -5494,34 +5422,34 @@ _SOKOL_PRIVATE EM_BOOL _sapp_emsc_key_cb(int emsc_type, const EmscriptenKeyboard case SAPP_KEYCODE_RIGHT_ALT: case SAPP_KEYCODE_RIGHT_SUPER: case SAPP_KEYCODE_MENU: - /* consume the event */ + // consume the event + consume_event = true; break; default: - /* forward key to browser */ - retval = false; + // forward key to browser + consume_event = false; break; } } if (_sapp_call_event(&_sapp.event)) { // event was consumed via sapp_consume_event() - retval = true; + consume_event = true; } if (send_keyup_followup) { _sapp.event.type = SAPP_EVENTTYPE_KEY_UP; if (_sapp_call_event(&_sapp.event)) { - retval = true; + consume_event = true; } } } } - _sapp_emsc_update_keyboard_state(); _sapp_emsc_update_mouse_lock_state(); - return retval; + return consume_event; } _SOKOL_PRIVATE EM_BOOL _sapp_emsc_touch_cb(int emsc_type, const EmscriptenTouchEvent* emsc_event, void* user_data) { _SOKOL_UNUSED(user_data); - bool retval = true; + bool consume_event = false; if (_sapp_events_enabled()) { sapp_event_type type; switch (emsc_type) { @@ -5539,7 +5467,6 @@ _SOKOL_PRIVATE EM_BOOL _sapp_emsc_touch_cb(int emsc_type, const EmscriptenTouchE break; default: type = SAPP_EVENTTYPE_INVALID; - retval = false; break; } if (type != SAPP_EVENTTYPE_INVALID) { @@ -5557,11 +5484,10 @@ _SOKOL_PRIVATE EM_BOOL _sapp_emsc_touch_cb(int emsc_type, const EmscriptenTouchE dst->pos_y = src->targetY * _sapp.dpi_scale; dst->changed = src->isChanged; } - _sapp_call_event(&_sapp.event); + consume_event = _sapp_call_event(&_sapp.event); } } - _sapp_emsc_update_keyboard_state(); - return retval; + return consume_event; } _SOKOL_PRIVATE EM_BOOL _sapp_emsc_focus_cb(int emsc_type, const EmscriptenFocusEvent* emsc_event, void* user_data) { @@ -5804,6 +5730,9 @@ _SOKOL_PRIVATE void _sapp_emsc_wgpu_frame(void) { #endif // SOKOL_WGPU _SOKOL_PRIVATE void _sapp_emsc_register_eventhandlers(void) { + // NOTE: HTML canvas doesn't receive input focus, this is why key event handlers are added + // to the window object (this could be worked around by adding a "tab index" to the + // canvas) emscripten_set_mousedown_callback(_sapp.html5_canvas_selector, 0, true, _sapp_emsc_mouse_cb); emscripten_set_mouseup_callback(_sapp.html5_canvas_selector, 0, true, _sapp_emsc_mouse_cb); emscripten_set_mousemove_callback(_sapp.html5_canvas_selector, 0, true, _sapp_emsc_mouse_cb); @@ -11309,8 +11238,6 @@ SOKOL_API_IMPL const void* sapp_egl_get_context(void) { SOKOL_API_IMPL void sapp_show_keyboard(bool show) { #if defined(_SAPP_IOS) _sapp_ios_show_keyboard(show); - #elif defined(_SAPP_EMSCRIPTEN) - _sapp_emsc_show_keyboard(show); #elif defined(_SAPP_ANDROID) _sapp_android_show_keyboard(show); #else diff --git a/src/sokol/c/sokol_gfx.h b/src/sokol/c/sokol_gfx.h index 572f690..6802e18 100644 --- a/src/sokol/c/sokol_gfx.h +++ b/src/sokol/c/sokol_gfx.h @@ -361,6 +361,25 @@ sg_backend sg_query_backend(void) + --- call the following helper functions to compute the number of + bytes in a texture row or surface for a specific pixel format. + These functions might be helpful when preparing image data for consumption + by sg_make_image() or sg_update_image(): + + int sg_query_row_pitch(sg_pixel_format fmt, int width, int int row_align_bytes); + int sg_query_surface_pitch(sg_pixel_format fmt, int width, int height, int row_align_bytes); + + Width and height are generally in number pixels, but note that 'row' has different meaning + for uncompressed vs compressed pixel formats: for uncompressed formats, a row is identical + with a single line if pixels, while in compressed formats, one row is a line of *compression blocks*. + + This is why calling sg_query_surface_pitch() for a compressed pixel format and height + N, N+1, N+2, ... may return the same result. + + The row_align_bytes parammeter is for added flexibility. For image data that goes into + the sg_make_image() or sg_update_image() this should generally be 1, because these + functions take tightly packed image data as input no matter what alignment restrictions + exist in the backend 3D APIs. ON INITIALIZATION: ================== @@ -1528,7 +1547,7 @@ typedef enum sg_backend { Not all pixel formats can be used for everything, call sg_query_pixelformat() to inspect the capabilities of a given pixelformat. The function returns - an sg_pixelformat_info struct with the following bool members: + an sg_pixelformat_info struct with the following members: - sample: the pixelformat can be sampled as texture at least with nearest filtering @@ -1540,6 +1559,8 @@ typedef enum sg_backend { - msaa: multisample-antialiasing is supported when using the pixelformat for render targets - depth: the pixelformat can be used for depth-stencil attachments + - compressed: this is a block-compressed format + - bytes_per_pixel: the numbers of bytes in a pixel (0 for compressed formats) The default pixel format for texture images is SG_PIXELFORMAT_RGBA8. @@ -1587,6 +1608,7 @@ typedef enum sg_pixel_format { SG_PIXELFORMAT_BGRA8, SG_PIXELFORMAT_RGB10A2, SG_PIXELFORMAT_RG11B10F, + SG_PIXELFORMAT_RGB9E5, SG_PIXELFORMAT_RG32UI, SG_PIXELFORMAT_RG32SI, @@ -1601,9 +1623,11 @@ typedef enum sg_pixel_format { SG_PIXELFORMAT_RGBA32SI, SG_PIXELFORMAT_RGBA32F, + // NOTE: when adding/removing pixel formats before DEPTH, also update sokol_app.h/SAPP_PIXELFORMAT_* SG_PIXELFORMAT_DEPTH, SG_PIXELFORMAT_DEPTH_STENCIL, + // NOTE: don't put any new compressed format in front of here SG_PIXELFORMAT_BC1_RGBA, SG_PIXELFORMAT_BC2_RGBA, SG_PIXELFORMAT_BC3_RGBA, @@ -1624,8 +1648,6 @@ typedef enum sg_pixel_format { SG_PIXELFORMAT_ETC2_RG11, SG_PIXELFORMAT_ETC2_RG11SN, - SG_PIXELFORMAT_RGB9E5, - _SG_PIXELFORMAT_NUM, _SG_PIXELFORMAT_FORCE_U32 = 0x7FFFFFFF } sg_pixel_format; @@ -1635,12 +1657,14 @@ typedef enum sg_pixel_format { by sg_query_pixelformat(). */ typedef struct sg_pixelformat_info { - bool sample; // pixel format can be sampled in shaders at least with nearest filtering - bool filter; // pixel format can be sampled with linear filtering - bool render; // pixel format can be used as render target - bool blend; // alpha-blending is supported - bool msaa; // pixel format can be used as MSAA render target - bool depth; // pixel format is a depth format + bool sample; // pixel format can be sampled in shaders at least with nearest filtering + bool filter; // pixel format can be sampled with linear filtering + bool render; // pixel format can be used as render target + bool blend; // alpha-blending is supported + bool msaa; // pixel format can be used as MSAA render target + bool depth; // pixel format is a depth format + bool compressed; // true if this is a hardware-compressed format + int bytes_per_pixel; // NOTE: this is 0 for compressed formats, use sg_query_row_pitch() / sg_query_surface_pitch() as alternative } sg_pixelformat_info; /* @@ -3751,6 +3775,8 @@ SOKOL_GFX_API_DECL sg_backend sg_query_backend(void); SOKOL_GFX_API_DECL sg_features sg_query_features(void); SOKOL_GFX_API_DECL sg_limits sg_query_limits(void); SOKOL_GFX_API_DECL sg_pixelformat_info sg_query_pixelformat(sg_pixel_format fmt); +SOKOL_GFX_API_DECL int sg_query_row_pitch(sg_pixel_format fmt, int width, int row_align_bytes); +SOKOL_GFX_API_DECL int sg_query_surface_pitch(sg_pixel_format fmt, int width, int height, int row_align_bytes); // get current state of a resource (INITIAL, ALLOC, VALID, FAILED, INVALID) SOKOL_GFX_API_DECL sg_resource_state sg_query_buffer_state(sg_buffer buf); SOKOL_GFX_API_DECL sg_resource_state sg_query_image_state(sg_image img); @@ -5582,6 +5608,15 @@ typedef struct { _sg_sampler_t* fs_smps[SG_MAX_SHADERSTAGE_SAMPLERS]; } _sg_bindings_t; +typedef struct { + bool sample; + bool filter; + bool render; + bool blend; + bool msaa; + bool depth; +} _sg_pixelformat_info_t; + typedef struct { bool valid; sg_desc desc; // original desc with default values patched in @@ -5599,7 +5634,7 @@ typedef struct { sg_backend backend; sg_features features; sg_limits limits; - sg_pixelformat_info formats[_SG_PIXELFORMAT_NUM]; + _sg_pixelformat_info_t formats[_SG_PIXELFORMAT_NUM]; bool stats_enabled; sg_frame_stats stats; sg_frame_stats prev_stats; @@ -5977,6 +6012,9 @@ _SOKOL_PRIVATE int _sg_pixelformat_bytesize(sg_pixel_format fmt) { case SG_PIXELFORMAT_RGBA32SI: case SG_PIXELFORMAT_RGBA32F: return 16; + case SG_PIXELFORMAT_DEPTH: + case SG_PIXELFORMAT_DEPTH_STENCIL: + return 4; default: SOKOL_UNREACHABLE; return 0; @@ -6113,7 +6151,7 @@ _SOKOL_PRIVATE int _sg_surface_pitch(sg_pixel_format fmt, int width, int height, } // capability table pixel format helper functions -_SOKOL_PRIVATE void _sg_pixelformat_all(sg_pixelformat_info* pfi) { +_SOKOL_PRIVATE void _sg_pixelformat_all(_sg_pixelformat_info_t* pfi) { pfi->sample = true; pfi->filter = true; pfi->blend = true; @@ -6121,53 +6159,53 @@ _SOKOL_PRIVATE void _sg_pixelformat_all(sg_pixelformat_info* pfi) { pfi->msaa = true; } -_SOKOL_PRIVATE void _sg_pixelformat_s(sg_pixelformat_info* pfi) { +_SOKOL_PRIVATE void _sg_pixelformat_s(_sg_pixelformat_info_t* pfi) { pfi->sample = true; } -_SOKOL_PRIVATE void _sg_pixelformat_sf(sg_pixelformat_info* pfi) { +_SOKOL_PRIVATE void _sg_pixelformat_sf(_sg_pixelformat_info_t* pfi) { pfi->sample = true; pfi->filter = true; } -_SOKOL_PRIVATE void _sg_pixelformat_sr(sg_pixelformat_info* pfi) { +_SOKOL_PRIVATE void _sg_pixelformat_sr(_sg_pixelformat_info_t* pfi) { pfi->sample = true; pfi->render = true; } -_SOKOL_PRIVATE void _sg_pixelformat_srmd(sg_pixelformat_info* pfi) { +_SOKOL_PRIVATE void _sg_pixelformat_srmd(_sg_pixelformat_info_t* pfi) { pfi->sample = true; pfi->render = true; pfi->msaa = true; pfi->depth = true; } -_SOKOL_PRIVATE void _sg_pixelformat_srm(sg_pixelformat_info* pfi) { +_SOKOL_PRIVATE void _sg_pixelformat_srm(_sg_pixelformat_info_t* pfi) { pfi->sample = true; pfi->render = true; pfi->msaa = true; } -_SOKOL_PRIVATE void _sg_pixelformat_sfrm(sg_pixelformat_info* pfi) { +_SOKOL_PRIVATE void _sg_pixelformat_sfrm(_sg_pixelformat_info_t* pfi) { pfi->sample = true; pfi->filter = true; pfi->render = true; pfi->msaa = true; } -_SOKOL_PRIVATE void _sg_pixelformat_sbrm(sg_pixelformat_info* pfi) { +_SOKOL_PRIVATE void _sg_pixelformat_sbrm(_sg_pixelformat_info_t* pfi) { pfi->sample = true; pfi->blend = true; pfi->render = true; pfi->msaa = true; } -_SOKOL_PRIVATE void _sg_pixelformat_sbr(sg_pixelformat_info* pfi) { +_SOKOL_PRIVATE void _sg_pixelformat_sbr(_sg_pixelformat_info_t* pfi) { pfi->sample = true; pfi->blend = true; pfi->render = true; } -_SOKOL_PRIVATE void _sg_pixelformat_sfbr(sg_pixelformat_info* pfi) { +_SOKOL_PRIVATE void _sg_pixelformat_sfbr(_sg_pixelformat_info_t* pfi) { pfi->sample = true; pfi->filter = true; pfi->blend = true; @@ -9804,7 +9842,7 @@ _SOKOL_PRIVATE void _sg_d3d11_init_caps(void) { const UINT srv_dxgi_fmt_caps = _sg_d3d11_dxgi_fmt_caps(_sg_d3d11_srv_pixel_format((sg_pixel_format)fmt)); const UINT rtv_dxgi_fmt_caps = _sg_d3d11_dxgi_fmt_caps(_sg_d3d11_rtv_pixel_format((sg_pixel_format)fmt)); const UINT dsv_dxgi_fmt_caps = _sg_d3d11_dxgi_fmt_caps(_sg_d3d11_dsv_pixel_format((sg_pixel_format)fmt)); - sg_pixelformat_info* info = &_sg.formats[fmt]; + _sg_pixelformat_info_t* info = &_sg.formats[fmt]; const bool render = 0 != (rtv_dxgi_fmt_caps & D3D11_FORMAT_SUPPORT_RENDER_TARGET); const bool depth = 0 != (dsv_dxgi_fmt_caps & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL); info->sample = 0 != (srv_dxgi_fmt_caps & D3D11_FORMAT_SUPPORT_TEXTURE2D); @@ -16202,7 +16240,7 @@ _SOKOL_PRIVATE bool _sg_validate_apply_bindings(const sg_bindings* bindings) { if (img && img->slot.state == SG_RESOURCESTATE_VALID) { _SG_VALIDATE(img->cmn.type == stage->images[i].image_type, VALIDATE_ABND_VS_IMAGE_TYPE_MISMATCH); _SG_VALIDATE(img->cmn.sample_count == 1, VALIDATE_ABND_VS_IMAGE_MSAA); - const sg_pixelformat_info* info = &_sg.formats[img->cmn.pixel_format]; + const _sg_pixelformat_info_t* info = &_sg.formats[img->cmn.pixel_format]; switch (stage->images[i].sample_type) { case SG_IMAGESAMPLETYPE_FLOAT: _SG_VALIDATE(info->filter, VALIDATE_ABND_VS_EXPECTED_FILTERABLE_IMAGE); @@ -16258,7 +16296,7 @@ _SOKOL_PRIVATE bool _sg_validate_apply_bindings(const sg_bindings* bindings) { if (img && img->slot.state == SG_RESOURCESTATE_VALID) { _SG_VALIDATE(img->cmn.type == stage->images[i].image_type, VALIDATE_ABND_FS_IMAGE_TYPE_MISMATCH); _SG_VALIDATE(img->cmn.sample_count == 1, VALIDATE_ABND_FS_IMAGE_MSAA); - const sg_pixelformat_info* info = &_sg.formats[img->cmn.pixel_format]; + const _sg_pixelformat_info_t* info = &_sg.formats[img->cmn.pixel_format]; switch (stage->images[i].sample_type) { case SG_IMAGESAMPLETYPE_FLOAT: _SG_VALIDATE(info->filter, VALIDATE_ABND_FS_EXPECTED_FILTERABLE_IMAGE); @@ -17048,7 +17086,36 @@ SOKOL_API_IMPL sg_pixelformat_info sg_query_pixelformat(sg_pixel_format fmt) { SOKOL_ASSERT(_sg.valid); int fmt_index = (int) fmt; SOKOL_ASSERT((fmt_index > SG_PIXELFORMAT_NONE) && (fmt_index < _SG_PIXELFORMAT_NUM)); - return _sg.formats[fmt_index]; + const _sg_pixelformat_info_t* src = &_sg.formats[fmt_index]; + sg_pixelformat_info res; + _sg_clear(&res, sizeof(res)); + res.sample = src->sample; + res.filter = src->filter; + res.render = src->render; + res.blend = src->blend; + res.msaa = src->msaa; + res.depth = src->depth; + res.compressed = _sg_is_compressed_pixel_format(fmt); + if (!res.compressed) { + res.bytes_per_pixel = _sg_pixelformat_bytesize(fmt); + } + return res; +} + +SOKOL_API_IMPL int sg_query_row_pitch(sg_pixel_format fmt, int width, int row_align_bytes) { + SOKOL_ASSERT(_sg.valid); + SOKOL_ASSERT(width > 0); + SOKOL_ASSERT((row_align_bytes > 0) && _sg_ispow2(row_align_bytes)); + SOKOL_ASSERT(((int)fmt > SG_PIXELFORMAT_NONE) && ((int)fmt < _SG_PIXELFORMAT_NUM)); + return _sg_row_pitch(fmt, width, row_align_bytes); +} + +SOKOL_API_IMPL int sg_query_surface_pitch(sg_pixel_format fmt, int width, int height, int row_align_bytes) { + SOKOL_ASSERT(_sg.valid); + SOKOL_ASSERT((width > 0) && (height > 0)); + SOKOL_ASSERT((row_align_bytes > 0) && _sg_ispow2(row_align_bytes)); + SOKOL_ASSERT(((int)fmt > SG_PIXELFORMAT_NONE) && ((int)fmt < _SG_PIXELFORMAT_NUM)); + return _sg_surface_pitch(fmt, width, height, row_align_bytes); } SOKOL_API_IMPL sg_frame_stats sg_query_frame_stats(void) { diff --git a/src/sokol/gfx.d b/src/sokol/gfx.d index fcda653..02d865f 100644 --- a/src/sokol/gfx.d +++ b/src/sokol/gfx.d @@ -117,6 +117,7 @@ enum PixelFormat { Bgra8, Rgb10a2, Rg11b10f, + Rgb9e5, Rg32ui, Rg32si, Rg32f, @@ -149,7 +150,6 @@ enum PixelFormat { Etc2_rgba8, Etc2_rg11, Etc2_rg11sn, - Rgb9e5, Num, } extern(C) @@ -160,6 +160,8 @@ struct PixelformatInfo { bool blend; bool msaa; bool depth; + bool compressed; + int bytes_per_pixel; } extern(C) struct Features { @@ -1433,6 +1435,14 @@ extern(C) PixelformatInfo sg_query_pixelformat(PixelFormat) @system @nogc nothro PixelformatInfo queryPixelformat(PixelFormat fmt) @trusted nothrow { return sg_query_pixelformat(fmt); } +extern(C) int sg_query_row_pitch(PixelFormat, int, int) @system @nogc nothrow; +int queryRowPitch(PixelFormat fmt, int width, int row_align_bytes) @trusted nothrow { + return sg_query_row_pitch(fmt, width, row_align_bytes); +} +extern(C) int sg_query_surface_pitch(PixelFormat, int, int, int) @system @nogc nothrow; +int querySurfacePitch(PixelFormat fmt, int width, int height, int row_align_bytes) @trusted nothrow { + return sg_query_surface_pitch(fmt, width, height, row_align_bytes); +} extern(C) ResourceState sg_query_buffer_state(Buffer) @system @nogc nothrow; ResourceState queryBufferState(Buffer buf) @trusted nothrow { return sg_query_buffer_state(buf);