Browse Source

sokol_gfx_imgui.h: remove calls to internal _sg_lookup_*() funcs and direct access to private resource attributes

Andre Weissflog 6 years ago
parent
commit
ecf0ba1952
1 changed files with 195 additions and 180 deletions
  1. 195 180
      imgui/sokol_gfx_imgui.h

+ 195 - 180
imgui/sokol_gfx_imgui.h

@@ -180,40 +180,41 @@ typedef struct {
     sg_imgui_str_t label;
     float color_image_scale[SG_MAX_COLOR_ATTACHMENTS];
     float ds_image_scale;
+    sg_pass_desc desc;
 } sg_imgui_pass_t;
 
 typedef struct {
     bool open;
     int num_slots;
-    uint32_t sel_id;
+    sg_buffer sel_buf;
     sg_imgui_buffer_t* slots;
 } sg_imgui_buffers_t;
 
 typedef struct {
     bool open;
     int num_slots;
-    uint32_t sel_id;
+    sg_image sel_img;
     sg_imgui_image_t* slots;
 } sg_imgui_images_t;
 
 typedef struct {
     bool open;
     int num_slots;
-    uint32_t sel_id;
+    sg_shader sel_shd;
     sg_imgui_shader_t* slots;
 } sg_imgui_shaders_t;
 
 typedef struct {
     bool open;
     int num_slots;
-    uint32_t sel_id;
+    sg_pipeline sel_pip;
     sg_imgui_pipeline_t* slots;
 } sg_imgui_pipelines_t;
 
 typedef struct {
     bool open;
     int num_slots;
-    uint32_t sel_id;
+    sg_pass sel_pass;
     sg_imgui_pass_t* slots;
 } sg_imgui_passes_t;
 
@@ -706,8 +707,8 @@ _SOKOL_PRIVATE const char* _sg_imgui_resourcestate_string(sg_resource_state s) {
     }
 }
 
-_SOKOL_PRIVATE void _sg_imgui_draw_resource_slot(const _sg_slot_t* slot) {
-    ImGui::Text("ResId: %08X", slot->id);
+_SOKOL_PRIVATE void _sg_imgui_draw_resource_slot(const sg_slot_info* slot) {
+    ImGui::Text("ResId: %08X", slot->res_id);
     ImGui::Text("CtxId: %08X", slot->ctx_id);
     ImGui::Text("State: %s", _sg_imgui_resourcestate_string(slot->state));
 }
@@ -1164,6 +1165,7 @@ _SOKOL_PRIVATE void _sg_imgui_pass_created(sg_imgui_t* ctx, sg_pass res_id, int
     }
     pass->ds_image_scale = 0.25f;
     pass->label = _sg_imgui_make_str(desc->label);
+    pass->desc = *desc;
 }
 
 _SOKOL_PRIVATE void _sg_imgui_pass_destroyed(sg_imgui_t* ctx, int slot_index) {
@@ -2470,46 +2472,46 @@ _SOKOL_PRIVATE bool _sg_imgui_draw_resid_link(uint32_t res_id, const char* label
     return res;
 }
 
-_SOKOL_PRIVATE bool _sg_imgui_draw_buffer_link(sg_imgui_t* ctx, uint32_t buf_id) {
+_SOKOL_PRIVATE bool _sg_imgui_draw_buffer_link(sg_imgui_t* ctx, sg_buffer buf) {
     bool retval = false;
-    if (buf_id != SG_INVALID_ID) {
-        const sg_imgui_buffer_t* buf_ui = &ctx->buffers.slots[_sg_imgui_slot_index(buf_id)];
-        retval = _sg_imgui_draw_resid_link(buf_id, buf_ui->label.buf);
+    if (buf.id != SG_INVALID_ID) {
+        const sg_imgui_buffer_t* buf_ui = &ctx->buffers.slots[_sg_imgui_slot_index(buf.id)];
+        retval = _sg_imgui_draw_resid_link(buf.id, buf_ui->label.buf);
     }
     return retval;
 }
 
-_SOKOL_PRIVATE bool _sg_imgui_draw_image_link(sg_imgui_t* ctx, uint32_t img_id) {
+_SOKOL_PRIVATE bool _sg_imgui_draw_image_link(sg_imgui_t* ctx, sg_image img) {
     bool retval = false;
-    if (img_id != SG_INVALID_ID) {
-        const sg_imgui_image_t* img_ui = &ctx->images.slots[_sg_imgui_slot_index(img_id)];
-        retval = _sg_imgui_draw_resid_link(img_id, img_ui->label.buf);
+    if (img.id != SG_INVALID_ID) {
+        const sg_imgui_image_t* img_ui = &ctx->images.slots[_sg_imgui_slot_index(img.id)];
+        retval = _sg_imgui_draw_resid_link(img.id, img_ui->label.buf);
     }
     return retval;
 }
 
-_SOKOL_PRIVATE bool _sg_imgui_draw_shader_link(sg_imgui_t* ctx, uint32_t shd_id) {
+_SOKOL_PRIVATE bool _sg_imgui_draw_shader_link(sg_imgui_t* ctx, sg_shader shd) {
     bool retval = false;
-    if (shd_id != SG_INVALID_ID) {
-        const sg_imgui_shader_t* shd_ui = &ctx->shaders.slots[_sg_imgui_slot_index(shd_id)];
-        retval = _sg_imgui_draw_resid_link(shd_id, shd_ui->label.buf);
+    if (shd.id != SG_INVALID_ID) {
+        const sg_imgui_shader_t* shd_ui = &ctx->shaders.slots[_sg_imgui_slot_index(shd.id)];
+        retval = _sg_imgui_draw_resid_link(shd.id, shd_ui->label.buf);
     }
     return retval;
 }
 
-_SOKOL_PRIVATE void _sg_imgui_show_buffer(sg_imgui_t* ctx, uint32_t buf_id) {
+_SOKOL_PRIVATE void _sg_imgui_show_buffer(sg_imgui_t* ctx, sg_buffer buf) {
     ctx->buffers.open = true;
-    ctx->buffers.sel_id = buf_id;
+    ctx->buffers.sel_buf = buf;
 }
 
-_SOKOL_PRIVATE void _sg_imgui_show_image(sg_imgui_t* ctx, uint32_t img_id) {
+_SOKOL_PRIVATE void _sg_imgui_show_image(sg_imgui_t* ctx, sg_image img) {
     ctx->images.open = true;
-    ctx->images.sel_id = img_id;
+    ctx->images.sel_img = img;
 }
 
-_SOKOL_PRIVATE void _sg_imgui_show_shader(sg_imgui_t* ctx, uint32_t shd_id) {
+_SOKOL_PRIVATE void _sg_imgui_show_shader(sg_imgui_t* ctx, sg_shader shd) {
     ctx->shaders.open = true;
-    ctx->shaders.sel_id = shd_id;
+    ctx->shaders.sel_shd = shd;
 }
 
 _SOKOL_PRIVATE void _sg_imgui_draw_buffer_list(sg_imgui_t* ctx) {
@@ -2517,9 +2519,9 @@ _SOKOL_PRIVATE void _sg_imgui_draw_buffer_list(sg_imgui_t* ctx) {
     for (int i = 1; i < _sg.pools.buffer_pool.size; i++) {
         const _sg_buffer_t* buf = &_sg.pools.buffers[i];
         if (buf->slot.state != SG_RESOURCESTATE_INITIAL) {
-            bool selected = ctx->buffers.sel_id == buf->slot.id;
+            bool selected = ctx->buffers.sel_buf.id == buf->slot.id;
             if (_sg_imgui_draw_resid_list_item(buf->slot.id, ctx->buffers.slots[i].label.buf, selected)) {
-                ctx->buffers.sel_id = buf->slot.id;
+                ctx->buffers.sel_buf.id = buf->slot.id;
             }
         }
     }
@@ -2531,9 +2533,9 @@ _SOKOL_PRIVATE void _sg_imgui_draw_image_list(sg_imgui_t* ctx) {
     for (int i = 1; i < _sg.pools.image_pool.size; i++) {
         const _sg_image_t* img = &_sg.pools.images[i];
         if (img->slot.state != SG_RESOURCESTATE_INITIAL) {
-            bool selected = ctx->images.sel_id == img->slot.id;
+            bool selected = ctx->images.sel_img.id == img->slot.id;
             if (_sg_imgui_draw_resid_list_item(img->slot.id, ctx->images.slots[i].label.buf, selected)) {
-                ctx->images.sel_id = img->slot.id;
+                ctx->images.sel_img.id = img->slot.id;
             }
         }
     }
@@ -2545,9 +2547,9 @@ _SOKOL_PRIVATE void _sg_imgui_draw_shader_list(sg_imgui_t* ctx) {
     for (int i = 1; i < _sg.pools.shader_pool.size; i++) {
         const _sg_shader_t* shd = &_sg.pools.shaders[i];
         if (shd->slot.state != SG_RESOURCESTATE_INITIAL) {
-            bool selected = ctx->shaders.sel_id == shd->slot.id;
+            bool selected = ctx->shaders.sel_shd.id == shd->slot.id;
             if (_sg_imgui_draw_resid_list_item(shd->slot.id, ctx->shaders.slots[i].label.buf, selected)) {
-                ctx->shaders.sel_id = shd->slot.id;
+                ctx->shaders.sel_shd.id = shd->slot.id;
             }
         }
     }
@@ -2559,9 +2561,9 @@ _SOKOL_PRIVATE void _sg_imgui_draw_pipeline_list(sg_imgui_t* ctx) {
     for (int i = 1; i < _sg.pools.pipeline_pool.size; i++) {
         const _sg_pipeline_t* pip = &_sg.pools.pipelines[i];
         if (pip->slot.state != SG_RESOURCESTATE_INITIAL) {
-            bool selected = ctx->pipelines.sel_id == pip->slot.id;
+            bool selected = ctx->pipelines.sel_pip.id == pip->slot.id;
             if (_sg_imgui_draw_resid_list_item(pip->slot.id, ctx->pipelines.slots[i].label.buf, selected)) {
-                ctx->pipelines.sel_id = pip->slot.id;
+                ctx->pipelines.sel_pip.id = pip->slot.id;
             }
         }
     }
@@ -2573,9 +2575,9 @@ _SOKOL_PRIVATE void _sg_imgui_draw_pass_list(sg_imgui_t* ctx) {
     for (int i = 1; i < _sg.pools.pass_pool.size; i++) {
         const _sg_pass_t* pass = &_sg.pools.passes[i];
         if (pass->slot.state != SG_RESOURCESTATE_INITIAL) {
-            bool selected = ctx->passes.sel_id == pass->slot.id;
+            bool selected = ctx->passes.sel_pass.id == pass->slot.id;
             if (_sg_imgui_draw_resid_list_item(pass->slot.id, ctx->passes.slots[i].label.buf, selected)) {
-                ctx->passes.sel_id = pass->slot.id;
+                ctx->passes.sel_pass.id = pass->slot.id;
             }
         }
     }
@@ -2623,68 +2625,72 @@ _SOKOL_PRIVATE void _sg_imgui_draw_capture_list(sg_imgui_t* ctx) {
     ImGui::EndChild();
 }
 
-_SOKOL_PRIVATE void _sg_imgui_draw_buffer_panel(sg_imgui_t* ctx, uint32_t buf_id) {
-    if (buf_id != SG_INVALID_ID) {
+_SOKOL_PRIVATE void _sg_imgui_draw_buffer_panel(sg_imgui_t* ctx, sg_buffer buf) {
+    if (buf.id != SG_INVALID_ID) {
         ImGui::BeginChild("buffer", ImVec2(0,0), false);
-        const _sg_buffer_t* buf = _sg_lookup_buffer(&_sg.pools, buf_id);
-        if (buf) {
-            const sg_imgui_buffer_t* buf_ui = &ctx->buffers.slots[_sg_imgui_slot_index(buf_id)];
+        sg_buffer_info info = sg_query_buffer_info(buf);
+        if (info.slot.res_id != SG_INVALID_ID) {
+            const sg_imgui_buffer_t* buf_ui = &ctx->buffers.slots[_sg_imgui_slot_index(buf.id)];
             ImGui::Text("Label: %s", buf_ui->label.buf[0] ? buf_ui->label.buf : "---");
-            _sg_imgui_draw_resource_slot(&buf->slot);
+            _sg_imgui_draw_resource_slot(&info.slot);
             ImGui::Separator();
             ImGui::Text("Type:  %s", _sg_imgui_buffertype_string(buf_ui->desc.type));
             ImGui::Text("Usage: %s", _sg_imgui_usage_string(buf_ui->desc.usage));
             ImGui::Text("Size:  %d", buf_ui->desc.size);
             if (buf_ui->desc.usage != SG_USAGE_IMMUTABLE) {
                 ImGui::Separator();
-                #if !defined(SOKOL_D3D11)
-                ImGui::Text("Num Slots:     %d", buf->num_slots);
-                ImGui::Text("Active Slot:   %d", buf->active_slot);
-                #endif
-                ImGui::Text("Update Frame Index: %d", buf->update_frame_index);
-                ImGui::Text("Append Frame Index: %d", buf->append_frame_index);
-                ImGui::Text("Append Pos:         %d", buf->append_pos);
-                ImGui::Text("Append Overflow:    %s", buf->append_overflow ? "YES":"NO");
+                ImGui::Text("Num Slots:     %d", info.num_slots);
+                ImGui::Text("Active Slot:   %d", info.active_slot);
+                ImGui::Text("Update Frame Index: %d", info.update_frame_index);
+                ImGui::Text("Append Frame Index: %d", info.append_frame_index);
+                ImGui::Text("Append Pos:         %d", info.append_pos);
+                ImGui::Text("Append Overflow:    %s", info.append_overflow ? "YES":"NO");
             }
         }
         else {
-            ImGui::Text("Buffer 0x%08X no longer alive", buf_id);
+            ImGui::Text("Buffer 0x%08X not alive.", buf.id);
         }
         ImGui::EndChild();
     }
 }
 
-_SOKOL_PRIVATE void _sg_imgui_draw_embedded_image(sg_imgui_t* ctx, uint32_t img_id, float* scale) {
-    const _sg_image_t* img = _sg_lookup_image(&_sg.pools, img_id);
-    if (img) {
-        if ((SG_IMAGETYPE_2D == img->type) && !_sg_is_valid_rendertarget_depth_format(img->pixel_format)) {
-            ImGui::PushID((int)img_id);
+_SOKOL_PRIVATE bool _sg_imgui_image_renderable(sg_imgui_t* ctx, sg_image_type type, sg_pixel_format fmt) {
+    if ((SG_IMAGETYPE_2D != type) || (SG_PIXELFORMAT_DEPTH == fmt) || (SG_PIXELFORMAT_DEPTHSTENCIL == fmt)) {
+        return false;
+    }
+    else {
+        return true;
+    }
+}
+
+_SOKOL_PRIVATE void _sg_imgui_draw_embedded_image(sg_imgui_t* ctx, sg_image img, float* scale) {
+    if (sg_query_image_state(img) == SG_RESOURCESTATE_VALID) {
+        sg_imgui_image_t* img_ui = &ctx->images.slots[_sg_imgui_slot_index(img.id)];
+        if (_sg_imgui_image_renderable(ctx, img_ui->desc.type, img_ui->desc.pixel_format)) {
+            ImGui::PushID((int)img.id);
             ImGui::SliderFloat("Scale", scale, 0.125f, 8.0f, "%.3f", 2.0f);
-            float w = (float)img->width * (*scale);
-            float h = (float)img->height * (*scale);
-            ImGui::Image((ImTextureID)(intptr_t)img_id, ImVec2(w, h));
+            float w = (float)img_ui->desc.width * (*scale);
+            float h = (float)img_ui->desc.height * (*scale);
+            ImGui::Image((ImTextureID)(intptr_t)img.id, ImVec2(w, h));
             ImGui::PopID();
         }
         else {
             ImGui::Text("Image not renderable.");
         }
     }
-    else {
-        ImGui::Text("Image 0x%08X no longer alive", img_id);
-    }
 }
 
-_SOKOL_PRIVATE void _sg_imgui_draw_image_panel(sg_imgui_t* ctx, uint32_t img_id) {
-    if (img_id != SG_INVALID_ID) {
+_SOKOL_PRIVATE void _sg_imgui_draw_image_panel(sg_imgui_t* ctx, sg_image img) {
+    if (img.id != SG_INVALID_ID) {
         ImGui::BeginChild("image", ImVec2(0,0), false);
-        const _sg_image_t* img = _sg_lookup_image(&_sg.pools, img_id);
-        if (img) {
-            sg_imgui_image_t* img_ui = &ctx->images.slots[_sg_imgui_slot_index(img_id)];
+        sg_image_info info = sg_query_image_info(img);
+        if (info.slot.state != SG_INVALID_ID) {
+            sg_imgui_image_t* img_ui = &ctx->images.slots[_sg_imgui_slot_index(img.id)];
             const sg_image_desc* desc = &img_ui->desc;
             ImGui::Text("Label: %s", img_ui->label.buf[0] ? img_ui->label.buf : "---");
-            _sg_imgui_draw_resource_slot(&img->slot);
+            _sg_imgui_draw_resource_slot(&info.slot);
             ImGui::Separator();
-            _sg_imgui_draw_embedded_image(ctx, img_id, &img_ui->ui_scale);
+            _sg_imgui_draw_embedded_image(ctx, img, &img_ui->ui_scale);
             ImGui::Separator();
             ImGui::Text("Type:              %s", _sg_imgui_imagetype_string(desc->type));
             ImGui::Text("Usage:             %s", _sg_imgui_usage_string(desc->usage));
@@ -2703,17 +2709,15 @@ _SOKOL_PRIVATE void _sg_imgui_draw_image_panel(sg_imgui_t* ctx, uint32_t img_id)
             ImGui::Text("Max Anisotropy:    %d", desc->max_anisotropy);
             ImGui::Text("Min LOD:           %.3f", desc->min_lod);
             ImGui::Text("Max LOD:           %.3f", desc->max_lod);
-            if (img->usage != SG_USAGE_IMMUTABLE) {
+            if (desc->usage != SG_USAGE_IMMUTABLE) {
                 ImGui::Separator();
-                #if !defined(SOKOL_D3D11)
-                ImGui::Text("Num Slots:     %d", img->num_slots);
-                ImGui::Text("Active Slot:   %d", img->active_slot);
-                #endif
-                ImGui::Text("Update Frame Index: %d", img->upd_frame_index);
+                ImGui::Text("Num Slots:     %d", info.num_slots);
+                ImGui::Text("Active Slot:   %d", info.active_slot);
+                ImGui::Text("Update Frame Index: %d", info.upd_frame_index);
             }
         }
         else {
-            ImGui::Text("Image 0x%08X no longer alive", img_id);
+            ImGui::Text("Image 0x%08X not alive.", img.id);
         }
         ImGui::EndChild();
     }
@@ -2791,14 +2795,14 @@ _SOKOL_PRIVATE void _sg_imgui_draw_shader_stage(sg_imgui_t* ctx, const sg_shader
     }
 }
 
-_SOKOL_PRIVATE void _sg_imgui_draw_shader_panel(sg_imgui_t* ctx, uint32_t shd_id) {
-    if (shd_id != SG_INVALID_ID) {
+_SOKOL_PRIVATE void _sg_imgui_draw_shader_panel(sg_imgui_t* ctx, sg_shader shd) {
+    if (shd.id != SG_INVALID_ID) {
         ImGui::BeginChild("shader", ImVec2(0,0), false, ImGuiWindowFlags_HorizontalScrollbar);
-        const _sg_shader_t* shd = _sg_lookup_shader(&_sg.pools, shd_id);
-        if (shd) {
-            const sg_imgui_shader_t* shd_ui = &ctx->shaders.slots[_sg_imgui_slot_index(shd_id)];
+        sg_shader_info info = sg_query_shader_info(shd);
+        if (info.slot.state != SG_INVALID_ID) {
+            const sg_imgui_shader_t* shd_ui = &ctx->shaders.slots[_sg_imgui_slot_index(shd.id)];
             ImGui::Text("Label: %s", shd_ui->label.buf[0] ? shd_ui->label.buf : "---");
-            _sg_imgui_draw_resource_slot(&shd->slot);
+            _sg_imgui_draw_resource_slot(&info.slot);
             ImGui::Separator();
             if (ImGui::TreeNode("Vertex Shader Stage")) {
                 _sg_imgui_draw_shader_stage(ctx, &shd_ui->desc.vs);
@@ -2810,7 +2814,7 @@ _SOKOL_PRIVATE void _sg_imgui_draw_shader_panel(sg_imgui_t* ctx, uint32_t shd_id
             }
         }
         else {
-            ImGui::Text("Shader 0x%08X no longer alive", shd_id);
+            ImGui::Text("Shader 0x%08X no longer alive", shd.id);
         }
         ImGui::EndChild();
     }
@@ -2895,18 +2899,18 @@ _SOKOL_PRIVATE void _sg_imgui_draw_rasterizer_state(const sg_rasterizer_state* r
     ImGui::Text("Depth Bias Clamp:  %f", rs->depth_bias_clamp);
 }
 
-_SOKOL_PRIVATE void _sg_imgui_draw_pipeline_panel(sg_imgui_t* ctx, uint32_t pip_id) {
-    if (pip_id != SG_INVALID_ID) {
+_SOKOL_PRIVATE void _sg_imgui_draw_pipeline_panel(sg_imgui_t* ctx, sg_pipeline pip) {
+    if (pip.id != SG_INVALID_ID) {
         ImGui::BeginChild("pipeline", ImVec2(0,0), false);
-        const _sg_pipeline_t* pip = _sg_lookup_pipeline(&_sg.pools, pip_id);
-        if (pip) {
-            const sg_imgui_pipeline_t* pip_ui = &ctx->pipelines.slots[_sg_imgui_slot_index(pip_id)];
+        sg_pipeline_info info = sg_query_pipeline_info(pip);
+        if (info.slot.state != SG_INVALID_ID) {
+            const sg_imgui_pipeline_t* pip_ui = &ctx->pipelines.slots[_sg_imgui_slot_index(pip.id)];
             ImGui::Text("Label: %s", pip_ui->label.buf[0] ? pip_ui->label.buf : "---");
-            _sg_imgui_draw_resource_slot(&pip->slot);
+            _sg_imgui_draw_resource_slot(&info.slot);
             ImGui::Separator();
             ImGui::Text("Shader:    "); ImGui::SameLine();
-            if (_sg_imgui_draw_shader_link(ctx, pip->shader_id.id)) {
-                _sg_imgui_show_shader(ctx, pip->shader_id.id);
+            if (_sg_imgui_draw_shader_link(ctx, pip_ui->desc.shader)) {
+                _sg_imgui_show_shader(ctx, pip_ui->desc.shader);
             }
             ImGui::Text("Prim Type:  %s", _sg_imgui_primitivetype_string(pip_ui->desc.primitive_type));
             ImGui::Text("Index Type: %s", _sg_imgui_indextype_string(pip_ui->desc.index_type));
@@ -2928,44 +2932,46 @@ _SOKOL_PRIVATE void _sg_imgui_draw_pipeline_panel(sg_imgui_t* ctx, uint32_t pip_
             }
         }
         else {
-            ImGui::Text("Pipeline 0x%08X no longer alive.", pip_id);
+            ImGui::Text("Pipeline 0x%08X not alive.", pip.id);
         }
         ImGui::EndChild();
     }
 }
 
-_SOKOL_PRIVATE void _sg_imgui_draw_attachment(sg_imgui_t* ctx, const _sg_attachment_t* att, float* img_scale) {
-    SOKOL_ASSERT(att->image && (att->image->slot.id == att->image_id.id));
+_SOKOL_PRIVATE void _sg_imgui_draw_attachment(sg_imgui_t* ctx, const sg_attachment_desc* att, float* img_scale) {
     ImGui::Text("  Image: "); ImGui::SameLine();
-    if (_sg_imgui_draw_image_link(ctx, att->image_id.id)) {
-        _sg_imgui_show_image(ctx, att->image_id.id);
+    if (_sg_imgui_draw_image_link(ctx, att->image)) {
+        _sg_imgui_show_image(ctx, att->image);
     }
     ImGui::Text("  Mip Level: %d", att->mip_level);
-    ImGui::Text("  Slice: %d", att->slice);
-    _sg_imgui_draw_embedded_image(ctx, att->image_id.id, img_scale);
+    ImGui::Text("  Face/Layer/Slice: %d", att->layer);
+    _sg_imgui_draw_embedded_image(ctx, att->image, img_scale);
 }
 
-_SOKOL_PRIVATE void _sg_imgui_draw_pass_panel(sg_imgui_t* ctx, uint32_t pass_id) {
-    if (pass_id != SG_INVALID_ID) {
+_SOKOL_PRIVATE void _sg_imgui_draw_pass_panel(sg_imgui_t* ctx, sg_pass pass) {
+    if (pass.id != SG_INVALID_ID) {
         ImGui::BeginChild("pass", ImVec2(0,0), false);
-        const _sg_pass_t* pass = _sg_lookup_pass(&_sg.pools, pass_id);
-        if (pass) {
-            sg_imgui_pass_t* pass_ui = &ctx->passes.slots[_sg_imgui_slot_index(pass_id)];
+        sg_pass_info info = sg_query_pass_info(pass);
+        if (info.slot.res_id != SG_INVALID_ID) {
+            sg_imgui_pass_t* pass_ui = &ctx->passes.slots[_sg_imgui_slot_index(pass.id)];
             ImGui::Text("Label: %s", pass_ui->label.buf[0] ? pass_ui->label.buf : "---");
-            _sg_imgui_draw_resource_slot(&pass->slot);
-            for (int i = 0; i < pass->num_color_atts; i++) {
+            _sg_imgui_draw_resource_slot(&info.slot);
+            for (int i = 0; i < SG_MAX_COLOR_ATTACHMENTS; i++) {
+                if (pass_ui->desc.color_attachments[i].image.id == SG_INVALID_ID) {
+                    break;
+                }
                 ImGui::Separator();
                 ImGui::Text("Color Attachment #%d:", i);
-                _sg_imgui_draw_attachment(ctx, &pass->color_atts[i], &pass_ui->color_image_scale[i]);
+                _sg_imgui_draw_attachment(ctx, &pass_ui->desc.color_attachments[i], &pass_ui->color_image_scale[i]);
             }
-            if (pass->ds_att.image_id.id != SG_INVALID_ID) {
+            if (pass_ui->desc.depth_stencil_attachment.image.id != SG_INVALID_ID) {
                 ImGui::Separator();
                 ImGui::Text("Depth-Stencil Attachemnt:");
-                _sg_imgui_draw_attachment(ctx, &pass->ds_att, &pass_ui->ds_image_scale);
+                _sg_imgui_draw_attachment(ctx, &pass_ui->desc.depth_stencil_attachment, &pass_ui->ds_image_scale);
             }
         }
         else {
-            ImGui::Text("Pass 0x%08X no longer alive.", pass_id);
+            ImGui::Text("Pass 0x%08X no longer alive.", pass.id);
         }
         ImGui::EndChild();
     }
@@ -2973,13 +2979,13 @@ _SOKOL_PRIVATE void _sg_imgui_draw_pass_panel(sg_imgui_t* ctx, uint32_t pass_id)
 
 _SOKOL_PRIVATE void _sg_imgui_draw_bindings_panel(sg_imgui_t* ctx, const sg_bindings* bnd) {
     for (int i = 0; i < SG_MAX_SHADERSTAGE_BUFFERS; i++) {
-        uint32_t buf_id = bnd->vertex_buffers[i].id;
-        if (buf_id != SG_INVALID_ID) {
+        sg_buffer buf = bnd->vertex_buffers[i];
+        if (buf.id != SG_INVALID_ID) {
             ImGui::Separator();
             ImGui::Text("Vertex Buffer Slot #%d:", i);
             ImGui::Text("  Buffer: "); ImGui::SameLine();
-            if (_sg_imgui_draw_buffer_link(ctx, buf_id)) {
-                _sg_imgui_show_buffer(ctx, buf_id);
+            if (_sg_imgui_draw_buffer_link(ctx, buf)) {
+                _sg_imgui_show_buffer(ctx, buf);
             }
             ImGui::Text("  Offset: %d", bnd->vertex_buffer_offsets[i]);
         }
@@ -2988,25 +2994,25 @@ _SOKOL_PRIVATE void _sg_imgui_draw_bindings_panel(sg_imgui_t* ctx, const sg_bind
         }
     }
     if (bnd->index_buffer.id != SG_INVALID_ID) {
-        uint32_t buf_id = bnd->index_buffer.id;
-        if (buf_id != SG_INVALID_ID) {
+        sg_buffer buf = bnd->index_buffer;
+        if (buf.id != SG_INVALID_ID) {
             ImGui::Separator();
             ImGui::Text("Index Buffer Slot:");
             ImGui::Text("  Buffer: "); ImGui::SameLine();
-            if (_sg_imgui_draw_buffer_link(ctx, buf_id)) {
-                _sg_imgui_show_buffer(ctx, buf_id);
+            if (_sg_imgui_draw_buffer_link(ctx, buf)) {
+                _sg_imgui_show_buffer(ctx, buf);
             }
             ImGui::Text("  Offset: %d", bnd->index_buffer_offset);
         }
     }
     for (int i = 0; i < SG_MAX_SHADERSTAGE_IMAGES; i++) {
-        uint32_t img_id = bnd->vs_images[i].id;
-        if (img_id != SG_INVALID_ID) {
+        sg_image img = bnd->vs_images[i];
+        if (img.id != SG_INVALID_ID) {
             ImGui::Separator();
             ImGui::Text("Vertex Stage Image Slot #%d:", i);
             ImGui::Text("  Image: "); ImGui::SameLine();
-            if (_sg_imgui_draw_image_link(ctx, img_id)) {
-                _sg_imgui_show_image(ctx, img_id);
+            if (_sg_imgui_draw_image_link(ctx, img)) {
+                _sg_imgui_show_image(ctx, img);
             }
         }
         else {
@@ -3014,13 +3020,13 @@ _SOKOL_PRIVATE void _sg_imgui_draw_bindings_panel(sg_imgui_t* ctx, const sg_bind
         }
     }
     for (int i = 0; i < SG_MAX_SHADERSTAGE_IMAGES; i++) {
-        uint32_t img_id = bnd->fs_images[i].id;
-        if (img_id != SG_INVALID_ID) {
+        sg_image img = bnd->fs_images[i];
+        if (img.id != SG_INVALID_ID) {
             ImGui::Separator();
             ImGui::Text("Fragment Stage Image Slot #%d:", i);
             ImGui::Text("  Image: "); ImGui::SameLine();
-            if (_sg_imgui_draw_image_link(ctx, img_id)) {
-                _sg_imgui_show_image(ctx, img_id);
+            if (_sg_imgui_draw_image_link(ctx, img)) {
+                _sg_imgui_show_image(ctx, img);
             }
         }
     }
@@ -3032,18 +3038,17 @@ _SOKOL_PRIVATE void _sg_imgui_draw_uniforms_panel(sg_imgui_t* ctx, const sg_imgu
     /* check if all the required information for drawing the structured uniform block content
         is available, otherwise just render a generic hexdump
     */
-    _sg_pipeline_t* pip = _sg_lookup_pipeline(&_sg.pools, args->pipeline.id);
-    if (!pip) {
+   if (sg_query_pipeline_state(args->pipeline) == SG_INVALID_ID) {
         ImGui::Text("Pipeline object no longer alive!");
         return;
-    }
-    _sg_shader_t* shd = _sg_lookup_shader(&_sg.pools, pip->shader_id.id);
-    if (!shd) {
+   }
+    sg_imgui_pipeline_t* pip_ui = &ctx->pipelines.slots[_sg_imgui_slot_index(args->pipeline.id)];
+    if (sg_query_shader_state(pip_ui->desc.shader) == SG_INVALID_ID) {
         ImGui::Text("Shader object no longer alive!");
         return;
     }
-    const sg_imgui_shader_t* shd_ui = &ctx->shaders.slots[_sg_imgui_slot_index(pip->shader_id.id)];
-    SOKOL_ASSERT(shd_ui->res_id.id == pip->shader_id.id);
+    sg_imgui_shader_t* shd_ui = &ctx->shaders.slots[_sg_imgui_slot_index(pip_ui->desc.shader.id)];
+    SOKOL_ASSERT(shd_ui->res_id.id == pip_ui->desc.shader.id);
     const sg_shader_uniform_block_desc* ub_desc = (args->stage == SG_SHADERSTAGE_VS) ?
         ub_desc = &shd_ui->desc.vs.uniform_blocks[args->ub_index] :
         ub_desc = &shd_ui->desc.fs.uniform_blocks[args->ub_index];
@@ -3112,12 +3117,19 @@ _SOKOL_PRIVATE void _sg_imgui_draw_uniforms_panel(sg_imgui_t* ctx, const sg_imgu
     }
 }
 
-_SOKOL_PRIVATE void _sg_imgui_draw_passaction_panel(sg_imgui_t* ctx, uint32_t pass_id, const sg_pass_action* action) {
-    int num_color_atts = 1;
-    if (SG_INVALID_ID != pass_id) {
-        const _sg_pass_t* pass = _sg_lookup_pass(&_sg.pools, pass_id);
-        if (pass) {
-            num_color_atts = pass->num_color_atts;
+_SOKOL_PRIVATE void _sg_imgui_draw_passaction_panel(sg_imgui_t* ctx, sg_pass pass, const sg_pass_action* action) {
+    /* determine number of valid color attachments in the pass */
+    int num_color_atts = 0;
+    if (SG_INVALID_ID == pass.id) {
+        /* default pass: one color attachment */
+        num_color_atts = 1;
+    }
+    else {
+        const sg_imgui_pass_t* pass_ui = &ctx->passes.slots[_sg_imgui_slot_index(pass.id)];
+        for (int i = 0; i < SG_MAX_COLOR_ATTACHMENTS; i++) {
+            if (pass_ui->desc.color_attachments[i].image.id != SG_INVALID_ID) {
+                num_color_atts++;
+            }
         }
     }
 
@@ -3170,75 +3182,78 @@ _SOKOL_PRIVATE void _sg_imgui_draw_capture_panel(sg_imgui_t* ctx) {
         case SG_IMGUI_CMD_RESET_STATE_CACHE:
             break;
         case SG_IMGUI_CMD_MAKE_BUFFER:
-            _sg_imgui_draw_buffer_panel(ctx, item->args.make_buffer.result.id);
+            _sg_imgui_draw_buffer_panel(ctx, item->args.make_buffer.result);
             break;
         case SG_IMGUI_CMD_MAKE_IMAGE:
-            _sg_imgui_draw_image_panel(ctx, item->args.make_image.result.id);
+            _sg_imgui_draw_image_panel(ctx, item->args.make_image.result);
             break;
         case SG_IMGUI_CMD_MAKE_SHADER:
-            _sg_imgui_draw_shader_panel(ctx, item->args.make_shader.result.id);
+            _sg_imgui_draw_shader_panel(ctx, item->args.make_shader.result);
             break;
         case SG_IMGUI_CMD_MAKE_PIPELINE:
-            _sg_imgui_draw_pipeline_panel(ctx, item->args.make_pipeline.result.id);
+            _sg_imgui_draw_pipeline_panel(ctx, item->args.make_pipeline.result);
             break;
         case SG_IMGUI_CMD_MAKE_PASS:
-            _sg_imgui_draw_pass_panel(ctx, item->args.make_pass.result.id);
+            _sg_imgui_draw_pass_panel(ctx, item->args.make_pass.result);
             break;
         case SG_IMGUI_CMD_DESTROY_BUFFER:
-            _sg_imgui_draw_buffer_panel(ctx, item->args.destroy_buffer.buffer.id);
+            _sg_imgui_draw_buffer_panel(ctx, item->args.destroy_buffer.buffer);
             break;
         case SG_IMGUI_CMD_DESTROY_IMAGE:
-            _sg_imgui_draw_image_panel(ctx, item->args.destroy_image.image.id);
+            _sg_imgui_draw_image_panel(ctx, item->args.destroy_image.image);
             break;
         case SG_IMGUI_CMD_DESTROY_SHADER:
-            _sg_imgui_draw_shader_panel(ctx, item->args.destroy_shader.shader.id);
+            _sg_imgui_draw_shader_panel(ctx, item->args.destroy_shader.shader);
             break;
         case SG_IMGUI_CMD_DESTROY_PIPELINE:
-            _sg_imgui_draw_pipeline_panel(ctx, item->args.destroy_pipeline.pipeline.id);
+            _sg_imgui_draw_pipeline_panel(ctx, item->args.destroy_pipeline.pipeline);
             break;
         case SG_IMGUI_CMD_DESTROY_PASS:
-            _sg_imgui_draw_pass_panel(ctx, item->args.destroy_pass.pass.id);
+            _sg_imgui_draw_pass_panel(ctx, item->args.destroy_pass.pass);
             break;
         case SG_IMGUI_CMD_UPDATE_BUFFER:
-            _sg_imgui_draw_buffer_panel(ctx, item->args.update_buffer.buffer.id);
+            _sg_imgui_draw_buffer_panel(ctx, item->args.update_buffer.buffer);
             break;
         case SG_IMGUI_CMD_UPDATE_IMAGE:
-            _sg_imgui_draw_image_panel(ctx, item->args.update_image.image.id);
+            _sg_imgui_draw_image_panel(ctx, item->args.update_image.image);
             break;
         case SG_IMGUI_CMD_APPEND_BUFFER:
-            _sg_imgui_draw_buffer_panel(ctx, item->args.update_buffer.buffer.id);
+            _sg_imgui_draw_buffer_panel(ctx, item->args.update_buffer.buffer);
             break;
         case SG_IMGUI_CMD_QUERY_BUFFER_OVERFLOW:
-            _sg_imgui_draw_buffer_panel(ctx, item->args.query_buffer_overflow.buffer.id);
+            _sg_imgui_draw_buffer_panel(ctx, item->args.query_buffer_overflow.buffer);
             break;
         case SG_IMGUI_CMD_QUERY_BUFFER_STATE:
-            _sg_imgui_draw_buffer_panel(ctx, item->args.query_buffer_state.buffer.id);
+            _sg_imgui_draw_buffer_panel(ctx, item->args.query_buffer_state.buffer);
             break;
         case SG_IMGUI_CMD_QUERY_IMAGE_STATE:
-            _sg_imgui_draw_image_panel(ctx, item->args.query_image_state.image.id);
+            _sg_imgui_draw_image_panel(ctx, item->args.query_image_state.image);
             break;
         case SG_IMGUI_CMD_QUERY_SHADER_STATE:
-            _sg_imgui_draw_shader_panel(ctx, item->args.query_shader_state.shader.id);
+            _sg_imgui_draw_shader_panel(ctx, item->args.query_shader_state.shader);
             break;
         case SG_IMGUI_CMD_QUERY_PIPELINE_STATE:
-            _sg_imgui_draw_pipeline_panel(ctx, item->args.query_pipeline_state.pipeline.id);
+            _sg_imgui_draw_pipeline_panel(ctx, item->args.query_pipeline_state.pipeline);
             break;
         case SG_IMGUI_CMD_QUERY_PASS_STATE:
-            _sg_imgui_draw_pass_panel(ctx, item->args.query_pass_state.pass.id);
+            _sg_imgui_draw_pass_panel(ctx, item->args.query_pass_state.pass);
             break;
         case SG_IMGUI_CMD_BEGIN_DEFAULT_PASS:
-            _sg_imgui_draw_passaction_panel(ctx, SG_INVALID_ID, &item->args.begin_default_pass.action);
+            {
+                sg_pass inv_pass = { SG_INVALID_ID };
+                _sg_imgui_draw_passaction_panel(ctx, inv_pass, &item->args.begin_default_pass.action);
+            }
             break;
         case SG_IMGUI_CMD_BEGIN_PASS:
-            _sg_imgui_draw_passaction_panel(ctx, item->args.begin_pass.pass.id, &item->args.begin_pass.action);
+            _sg_imgui_draw_passaction_panel(ctx, item->args.begin_pass.pass, &item->args.begin_pass.action);
             ImGui::Separator();
-            _sg_imgui_draw_pass_panel(ctx, item->args.begin_pass.pass.id);
+            _sg_imgui_draw_pass_panel(ctx, item->args.begin_pass.pass);
             break;
         case SG_IMGUI_CMD_APPLY_VIEWPORT:
         case SG_IMGUI_CMD_APPLY_SCISSOR_RECT:
             break;
         case SG_IMGUI_CMD_APPLY_PIPELINE:
-            _sg_imgui_draw_pipeline_panel(ctx, item->args.apply_pipeline.pipeline.id);
+            _sg_imgui_draw_pipeline_panel(ctx, item->args.apply_pipeline.pipeline);
             break;
         case SG_IMGUI_CMD_APPLY_BINDINGS:
             _sg_imgui_draw_bindings_panel(ctx, &item->args.apply_bindings.bindings);
@@ -3251,49 +3266,49 @@ _SOKOL_PRIVATE void _sg_imgui_draw_capture_panel(sg_imgui_t* ctx) {
         case SG_IMGUI_CMD_COMMIT:
             break;
         case SG_IMGUI_CMD_ALLOC_BUFFER:
-            _sg_imgui_draw_buffer_panel(ctx, item->args.alloc_buffer.result.id);
+            _sg_imgui_draw_buffer_panel(ctx, item->args.alloc_buffer.result);
             break;
         case SG_IMGUI_CMD_ALLOC_IMAGE:
-            _sg_imgui_draw_image_panel(ctx, item->args.alloc_image.result.id);
+            _sg_imgui_draw_image_panel(ctx, item->args.alloc_image.result);
             break;
         case SG_IMGUI_CMD_ALLOC_SHADER:
-            _sg_imgui_draw_shader_panel(ctx, item->args.alloc_shader.result.id);
+            _sg_imgui_draw_shader_panel(ctx, item->args.alloc_shader.result);
             break;
         case SG_IMGUI_CMD_ALLOC_PIPELINE:
-            _sg_imgui_draw_pipeline_panel(ctx, item->args.alloc_pipeline.result.id);
+            _sg_imgui_draw_pipeline_panel(ctx, item->args.alloc_pipeline.result);
             break;
         case SG_IMGUI_CMD_ALLOC_PASS:
-            _sg_imgui_draw_pass_panel(ctx, item->args.alloc_pass.result.id);
+            _sg_imgui_draw_pass_panel(ctx, item->args.alloc_pass.result);
             break;
         case SG_IMGUI_CMD_INIT_BUFFER:
-            _sg_imgui_draw_buffer_panel(ctx, item->args.init_buffer.buffer.id);
+            _sg_imgui_draw_buffer_panel(ctx, item->args.init_buffer.buffer);
             break;
         case SG_IMGUI_CMD_INIT_IMAGE:
-            _sg_imgui_draw_image_panel(ctx, item->args.init_image.image.id);
+            _sg_imgui_draw_image_panel(ctx, item->args.init_image.image);
             break;
         case SG_IMGUI_CMD_INIT_SHADER:
-            _sg_imgui_draw_shader_panel(ctx, item->args.init_shader.shader.id);
+            _sg_imgui_draw_shader_panel(ctx, item->args.init_shader.shader);
             break;
         case SG_IMGUI_CMD_INIT_PIPELINE:
-            _sg_imgui_draw_pipeline_panel(ctx, item->args.init_pipeline.pipeline.id);
+            _sg_imgui_draw_pipeline_panel(ctx, item->args.init_pipeline.pipeline);
             break;
         case SG_IMGUI_CMD_INIT_PASS:
-            _sg_imgui_draw_pass_panel(ctx, item->args.init_pass.pass.id);
+            _sg_imgui_draw_pass_panel(ctx, item->args.init_pass.pass);
             break;
         case SG_IMGUI_CMD_FAIL_BUFFER:
-            _sg_imgui_draw_buffer_panel(ctx, item->args.fail_buffer.buffer.id);
+            _sg_imgui_draw_buffer_panel(ctx, item->args.fail_buffer.buffer);
             break;
         case SG_IMGUI_CMD_FAIL_IMAGE:
-            _sg_imgui_draw_image_panel(ctx, item->args.fail_image.image.id);
+            _sg_imgui_draw_image_panel(ctx, item->args.fail_image.image);
             break;
         case SG_IMGUI_CMD_FAIL_SHADER:
-            _sg_imgui_draw_shader_panel(ctx, item->args.fail_shader.shader.id);
+            _sg_imgui_draw_shader_panel(ctx, item->args.fail_shader.shader);
             break;
         case SG_IMGUI_CMD_FAIL_PIPELINE:
-            _sg_imgui_draw_pipeline_panel(ctx, item->args.fail_pipeline.pipeline.id);
+            _sg_imgui_draw_pipeline_panel(ctx, item->args.fail_pipeline.pipeline);
             break;
         case SG_IMGUI_CMD_FAIL_PASS:
-            _sg_imgui_draw_pass_panel(ctx, item->args.fail_pass.pass.id);
+            _sg_imgui_draw_pass_panel(ctx, item->args.fail_pass.pass);
             break;
         default:
             break;
@@ -3544,35 +3559,35 @@ SOKOL_API_IMPL void sg_imgui_draw_buffers_content(sg_imgui_t* ctx) {
     SOKOL_ASSERT(ctx && (ctx->init_tag == 0xABCDABCD));
     _sg_imgui_draw_buffer_list(ctx);
     ImGui::SameLine();
-    _sg_imgui_draw_buffer_panel(ctx, ctx->buffers.sel_id);
+    _sg_imgui_draw_buffer_panel(ctx, ctx->buffers.sel_buf);
 }
 
 SOKOL_API_IMPL void sg_imgui_draw_images_content(sg_imgui_t* ctx) {
     SOKOL_ASSERT(ctx && (ctx->init_tag == 0xABCDABCD));
     _sg_imgui_draw_image_list(ctx);
     ImGui::SameLine();
-    _sg_imgui_draw_image_panel(ctx, ctx->images.sel_id);
+    _sg_imgui_draw_image_panel(ctx, ctx->images.sel_img);
 }
 
 SOKOL_API_IMPL void sg_imgui_draw_shaders_content(sg_imgui_t* ctx) {
     SOKOL_ASSERT(ctx && (ctx->init_tag == 0xABCDABCD));
     _sg_imgui_draw_shader_list(ctx);
     ImGui::SameLine();
-    _sg_imgui_draw_shader_panel(ctx, ctx->shaders.sel_id);
+    _sg_imgui_draw_shader_panel(ctx, ctx->shaders.sel_shd);
 }
 
 SOKOL_API_IMPL void sg_imgui_draw_pipelines_content(sg_imgui_t* ctx) {
     SOKOL_ASSERT(ctx && (ctx->init_tag == 0xABCDABCD));
     _sg_imgui_draw_pipeline_list(ctx);
     ImGui::SameLine();
-    _sg_imgui_draw_pipeline_panel(ctx, ctx->pipelines.sel_id);
+    _sg_imgui_draw_pipeline_panel(ctx, ctx->pipelines.sel_pip);
 }
 
 SOKOL_API_IMPL void sg_imgui_draw_passes_content(sg_imgui_t* ctx) {
     SOKOL_ASSERT(ctx && (ctx->init_tag == 0xABCDABCD));
     _sg_imgui_draw_pass_list(ctx);
     ImGui::SameLine();
-    _sg_imgui_draw_pass_panel(ctx, ctx->passes.sel_id);
+    _sg_imgui_draw_pass_panel(ctx, ctx->passes.sel_pass);
 }
 
 SOKOL_API_IMPL void sg_imgui_draw_capture_content(sg_imgui_t* ctx) {