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, " ShaderStorage - 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