Skip to content

Commit 33c9620

Browse files
authored
Update ImGui to v1.92.4 (#200)
Overview: Updates ImGui to version 1.92.4 * Updated the backend to handle the new "Texture Request" approach. * Updated the backend to use the new "Input Event" API. Features: * AssetStorage now allows to bind arbitrary data and metadata as an Asset object. * Finished implementation of a "Image Loader" trait that allows to request "Runtime" states for Image assets. Changes: * Added new utility 'ice::data_copy' function. * Added missing license headers to various files. * Improved debug information of Asset objects in Debug and Develop builds. * WebAssembly example now references 'iceshard-pipelines' to access 'texture resource compiler' definition. Fixed: * Possible crash due to AssetStorage API not preserving the Asset object when scheduled on a worker. * Possible crash in "World Manager" debug window when accessing worlds in specific order. Known issues: * The ImGui backend only handles "Create" requests for now. "Update" and "Destroy" requests are ignored.
1 parent 9ee9ede commit 33c9620

File tree

68 files changed

+1132
-580
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+1132
-580
lines changed

source/code/core/core/public/ice/concept/pimpl_type.hxx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
/// Copyright 2025 - 2025, Dandielo <[email protected]>
2+
/// SPDX-License-Identifier: MIT
3+
14
#pragma once
25
#include <ice/concept/enum_flags.hxx>
36

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/// Copyright 2025 - 2025, Dandielo <[email protected]>
2+
/// SPDX-License-Identifier: MIT
3+
4+
#pragma once
5+
#include <ice/mem_allocator.hxx>
6+
7+
namespace ice
8+
{
9+
10+
inline auto data_copy(ice::Allocator& alloc, ice::Data data) noexcept -> ice::Memory
11+
{
12+
ice::Memory const result = alloc.allocate({ data.size, data.alignment });
13+
if (result.location != nullptr)
14+
{
15+
ice::memcpy(result, data);
16+
}
17+
return result;
18+
}
19+
20+
} // namespace ice

source/code/core/utils/private/detail/refcounted.cxx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
/// Copyright 2025 - 2025, Dandielo <[email protected]>
2+
/// SPDX-License-Identifier: MIT
3+
14
#include <ice/detail/refcounted.hxx>
25
#include <ice/assert.hxx>
36

source/code/core/utils/public/ice/detail/refcounted.hxx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
/// Copyright 2025 - 2025, Dandielo <[email protected]>
2+
/// SPDX-License-Identifier: MIT
3+
14
#pragma once
25
#include <ice/base.hxx>
36
#include <ice/mem_allocator.hxx>

source/code/core/utils/public/ice/ptr.hxx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
/// Copyright 2025 - 2025, Dandielo <[email protected]>
2+
/// SPDX-License-Identifier: MIT
3+
14
#pragma once
25
#include <ice/detail/refcounted.hxx>
36

source/code/example/android/simple/private/example_android.cxx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,9 @@ void TestGame::on_resume(ice::Engine& engine) noexcept
166166
ice::StringID traits[]{
167167
"test"_sid,
168168
"test2"_sid,
169+
ice::devui_trait_name(),
169170
ice::TraitID_GfxShaderStorage,
170-
ice::devui_trait_name()
171+
ice::TraitID_GfxImageStorage,
171172
};
172173

173174
engine.worlds().create_world({ .name = "world"_sid, .traits = traits });

source/code/example/webasm/private/example_webasm.cxx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,9 @@ void TestGame::on_resume(ice::Engine& engine) noexcept
301301
ice::StringID traits[]{
302302
"act"_sid,
303303
"test2"_sid,
304-
ice::TraitID_GfxShaderStorage,
305304
ice::devui_trait_name(),
305+
ice::TraitID_GfxShaderStorage,
306+
ice::TraitID_GfxImageStorage,
306307
};
307308
ice::StringID traits2[]{
308309
"test"_sid,

source/code/example/webasm/webasm.bff

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
'imgui_module'
4343
'shader_tools'
4444
'webgpu_renderer'
45+
'iceshard_pipelines'
4546
}
4647
]
4748
]

source/code/iceshard/engine/public/ice/ecs/ecs_entity_storage_details.hxx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
/// Copyright 2025 - 2025, Dandielo <[email protected]>
2+
/// SPDX-License-Identifier: MIT
3+
14
#pragma once
25
#include <ice/ecs/ecs_types.hxx>
36

source/code/iceshard/iceshard/private/gfx/traits/iceshard_gfx_image_storage_trait.cxx

Lines changed: 83 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
#include <ice/gfx/gfx_context.hxx>
1212
#include <ice/render/render_buffer.hxx>
1313
#include <ice/render/render_command_buffer.hxx>
14+
#include <ice/render/render_pipeline.hxx>
1415
#include <ice/render/render_device.hxx>
16+
#include <ice/render/render_pass.hxx>
1517
#include <ice/resource_tracker.hxx>
1618
#include <ice/resource.hxx>
1719
#include <ice/shard_container.hxx>
@@ -36,10 +38,11 @@ namespace ice::gfx
3638
: ice::Trait{ ctx }
3739
, _loaded_images{ alloc }
3840
{
39-
_context.bind<&Trait_GfxImageStorage::gfx_update>(ice::gfx::ShardID_RenderFrameUpdate);
41+
_context.bind<&Trait_GfxImageStorage::gfx_update, Render>(ice::gfx::ShardID_RenderFrameUpdate);
42+
_context.bind<&Trait_GfxImageStorage::gfx_shutdown, Render>(ice::gfx::ShardID_GfxShutdown);
4043
}
4144

42-
auto Trait_GfxImageStorage::on_asset_released(ice::Asset const &asset) noexcept -> ice::Task<>
45+
auto Trait_GfxImageStorage::on_asset_released(ice::Asset const& asset) noexcept -> ice::Task<>
4346
{
4447
GfxImageEntry* entry = ice::hashmap::try_get(_loaded_images, ice::hash(asset.name()));
4548
ICE_ASSERT_CORE(entry != nullptr);
@@ -59,8 +62,8 @@ namespace ice::gfx
5962
ice::AssetState const state = request->state();
6063
ICE_ASSERT_CORE(state == AssetState::Loaded); // The image needs to be loaded.
6164

62-
ice::u64 const image_hash = ice::hash(request->asset_name());
63-
GfxImageEntry* entry = ice::hashmap::try_get(_loaded_images, image_hash);
65+
ice::StringID const image_hash = request->asset_name();
66+
GfxImageEntry* entry = ice::hashmap::try_get(_loaded_images, ice::hash(image_hash));
6467
ICE_ASSERT_CORE(entry == nullptr || entry->released);
6568

6669
using namespace ice::render;
@@ -76,6 +79,7 @@ namespace ice::gfx
7679
if (metadata_data.location == nullptr)
7780
{
7881
request->resolve({ .result = ice::AssetRequestResult::Error });
82+
request = assets.aquire_request(ice::render::AssetCategory_Texture2D, AssetState::Runtime);
7983
continue;
8084
}
8185

@@ -90,7 +94,7 @@ namespace ice::gfx
9094
valid_data &= ice::config::get(meta, "texture.size.y", size.y);
9195

9296
[[maybe_unused]]
93-
ice::Data const* d = reinterpret_cast<ice::Data const*>(request->data().location);
97+
ice::Data const texture_data = request->data();
9498

9599
// Creates the image object
96100
ImageInfo image_info{
@@ -100,54 +104,106 @@ namespace ice::gfx
100104
.width = (ice::u32) size.x,
101105
.height = (ice::u32) size.y,
102106
};
103-
Image image = device.create_image(image_info, {});
107+
Image image = device.create_image(image_info, texture_data);
104108
if (image == Image::Invalid)
105109
{
106110
request->resolve({ .result = AssetRequestResult::Error });
107111
co_return;
108112
}
109113

110-
ice::render::Buffer buffer = device.create_buffer(BufferType::Transfer, size.x * size.y);
114+
ice::render::Buffer transfer_buffer = device.create_buffer(BufferType::Transfer, ice::u32(texture_data.size.value));
111115
BufferUpdateInfo const buffer_updates[]{
112116
BufferUpdateInfo{
113-
.buffer = buffer,
114-
.data = *d,
117+
.buffer = transfer_buffer,
118+
.data = texture_data,
115119
.offset = 0
116120
}
117121
};
118122

119123
device.update_buffers(buffer_updates);
120124

121-
// RenderCommands& api = device.get_commands();
122-
// CommandBuffer const cmds = co_await params.frame_transfer;
125+
RenderCommands& api = device.get_commands();
126+
CommandBuffer const cmds = co_await params.stages.frame_transfer;
123127

124-
// api.update_texture_v2(
125-
// cmds,
126-
// image,
127-
// buffer,
128-
// ice::vec2u{ size }
129-
// );
128+
ImageBarrier barriers[4]{ };
130129

131-
// co_await params.frame_end;
130+
for (ice::u32 idx = 0; idx < 1; ++idx)
131+
{
132+
barriers[idx].image = image;
133+
barriers[idx].source_layout = ImageLayout::Undefined;
134+
barriers[idx].destination_layout = ImageLayout::TransferDstOptimal;
135+
barriers[idx].source_access = AccessFlags::None;
136+
barriers[idx].destination_access = AccessFlags::TransferWrite;
137+
}
138+
139+
api.pipeline_image_barrier(
140+
cmds,
141+
PipelineStage::TopOfPipe,
142+
PipelineStage::Transfer,
143+
{ barriers, 1 }
144+
);
145+
146+
api.update_texture_v2(
147+
cmds,
148+
image,
149+
transfer_buffer,
150+
ice::vec2u{ size }
151+
);
152+
153+
for (ice::u32 idx = 0; idx < 1; ++idx)
154+
{
155+
barriers[idx].image = image;
156+
barriers[idx].source_layout = ImageLayout::TransferDstOptimal;
157+
barriers[idx].destination_layout = ImageLayout::ShaderReadOnly;
158+
barriers[idx].source_access = AccessFlags::TransferWrite;
159+
barriers[idx].destination_access = AccessFlags::ShaderRead;
160+
}
161+
162+
api.pipeline_image_barrier(
163+
cmds,
164+
PipelineStage::Transfer,
165+
PipelineStage::FramentShader,
166+
{ barriers, 1 }
167+
);
168+
169+
co_await params.stages.frame_end;
170+
171+
device.destroy_buffer(transfer_buffer);
132172

133-
// device.destroy_buffer(data_buffer);
173+
ICE_LOG(LogSeverity::Info, LogTag::Game, "TextureStorage - Loaded image: {}", request->asset_name());
134174

135-
// ICE_LOG(LogSeverity::Info, LogTag::Game, "ShaderStorage - Loaded image: {}", request->asset_name());
175+
// Allocates a handle for it... (TODO: Rework?)
176+
ice::Memory const result = request->allocate(ice::size_of<ice::render::Image>);
177+
*reinterpret_cast<Image*>(result.location) = image;
136178

137-
// // Allocates a handle for it... (TODO: Rework?)
138-
// ice::Memory const result = request->allocate(ice::size_of<ice::render::Image>);
139-
// *reinterpret_cast<Image*>(result.location) = image;
179+
// Reslove the request (will resume all awaiting tasks)
180+
ice::Asset asset = request->resolve({ .resolver = this, .result = AssetRequestResult::Success, .memory = result });
181+
// send("iceshard:images-internal:loaded"_shardid, asset);
140182

141-
// // Save the image handle
142-
// ice::hashmap::set(_loaded_images, image_hash, { .image = image });
183+
// Save the image handle
184+
ice::hashmap::set(_loaded_images, ice::hash(image_hash), { .asset = ice::move(asset), .image = image});
143185

144186
// // Reslove the request (will resume all awaiting tasks)
145187
// request->resolve({ .resolver = this, .result = AssetRequestResult::Success, .memory = result });
146188

147-
// // Get the next queued request
148-
// request = update.assets.aquire_request(ice::render::AssetCategory_Texture2D, AssetState::Runtime);
189+
// Get the next queued request
190+
request = assets.aquire_request(ice::render::AssetCategory_Texture2D, AssetState::Runtime);
191+
}
192+
193+
co_return;
194+
}
195+
196+
auto Trait_GfxImageStorage::gfx_shutdown(
197+
ice::render::RenderDevice& device
198+
) noexcept -> ice::Task<>
199+
{
200+
for (ice::gfx::GfxImageEntry& entry : ice::hashmap::values(_loaded_images))
201+
{
202+
device.destroy_image(entry.image);
203+
entry.asset.release();
149204
}
150205

206+
ice::hashmap::clear(_loaded_images);
151207
co_return;
152208
}
153209

0 commit comments

Comments
 (0)