66#include " le_pipeline_builder.h"
77#include " le_ui_event.h"
88#include " le_pixels.h"
9+ #include " shared/interfaces/le_image_decoder_interface.h"
10+
911#include " le_log.h"
1012
1113#define GLM_FORCE_DEPTH_ZERO_TO_ONE // vulkan clip space is from 0 to 1
1921#include < vector>
2022#include < stdlib.h> // for random
2123
24+ // Wrapper for format enum so that we can pass this around in a c-style api without
25+ // completely losing type safety.
26+ struct le_image_decoder_format_o {
27+ le::Format format;
28+ };
29+
2230struct pixels_data_t {
2331 le_buf_resource_handle handle;
2432 uint32_t w; // let's make sure that w is a power of 2
@@ -103,10 +111,10 @@ static bitonic_merge_sort_example_app_o* bitonic_merge_sort_example_app_create()
103111// ----------------------------------------------------------------------
104112
105113static void bitonic_merge_sort_example_app_destroy ( bitonic_merge_sort_example_app_o* self ) {
106- if (self) {
107- delete self->pixels_data ;
108- }
109- delete ( self );
114+ if ( self ) {
115+ delete self->pixels_data ;
116+ }
117+ delete ( self );
110118}
111119
112120// ----------------------------------------------------------------------
@@ -225,7 +233,7 @@ static bool pass_sort_setup( le_renderpass_o* rp_, void* user_data ) {
225233
226234static void pass_noise_execute ( le_command_buffer_encoder_o* encoder_, void * user_data ) {
227235 le::TransferEncoder encoder{ encoder_ };
228- auto app = static_cast <app_o*>( user_data );
236+ auto app = static_cast <app_o*>( user_data );
229237
230238 std::vector<uint32_t > buffer_initial_data;
231239 buffer_initial_data.reserve ( app->pixels_data ->w * app->pixels_data ->h * app->pixels_data ->num_channels );
@@ -256,20 +264,28 @@ static void pass_upload_image_execute( le_command_buffer_encoder_o* encoder_, vo
256264
257265 // we must load image from disk
258266
259- le::Pixels pixels ( app->dropped_image_path .c_str (), 4 );
267+ le_image_decoder_interface_t * image_decoder_api = le_pixels::api->le_pixels_image_decoder_i ;
268+ le_image_decoder_o* image_decoder = image_decoder_api->create_image_decoder ( app->dropped_image_path .c_str () );
260269
261- if ( !pixels. isValid () ) {
270+ if ( nullptr == image_decoder ) {
262271 log.warn ( " Could not load image '%s'" , app->dropped_image_path .c_str () );
263272 app->dropped_image_path .clear ();
264273 return ;
265274 }
266275
267276 // invariant: pixels must be valid
268277
269- le_pixels_info info = pixels.getInfo ();
278+ uint32_t width;
279+ uint32_t height;
280+
281+ // request that the image decoder provide us with a float image
282+ le_image_decoder_format_o format = { le::Format::eR8G8B8A8Unorm };
283+
284+ image_decoder_api->set_requested_format ( image_decoder, &format );
285+ image_decoder_api->get_image_data_description ( image_decoder, &format, &width, &height );
270286
271- if ( info. width * info. height < app->pixels_data ->w * app->pixels_data ->h ) {
272- log.warn ( " Could not load image '%s': Too small: w: %d, h: %d" , app->dropped_image_path .c_str (), info. width , info. height );
287+ if ( width * height < app->pixels_data ->w * app->pixels_data ->h || format. format != le::Format::eR8G8B8A8Unorm ) {
288+ log.warn ( " Could not load image '%s': Too small: w: %d, h: %d" , app->dropped_image_path .c_str (), width, height );
273289 app->dropped_image_path .clear ();
274290
275291 app->pixels_data ->unsorted = false ;
@@ -287,8 +303,21 @@ static void pass_upload_image_execute( le_command_buffer_encoder_o* encoder_, vo
287303
288304 uint32_t num_bytes = app->pixels_data ->w * app->pixels_data ->h * app->pixels_data ->bytes_per_channel * app->pixels_data ->num_channels ;
289305
290- // upload pixels
291- encoder.writeToBuffer ( app->pixels_data ->handle , 0 , pixels.getData (), num_bytes );
306+ // Allocate data so that the image decoder can read pixels into
307+ uint8_t * data = ( uint8_t * )malloc ( num_bytes );
308+
309+ if ( data ) {
310+
311+ // Use the image decoder to read pixels into `data`
312+ image_decoder_api->read_pixels ( image_decoder, data, num_bytes );
313+
314+ // Upload pixels to buffer GPU memory
315+ encoder.writeToBuffer ( app->pixels_data ->handle , 0 , data, num_bytes );
316+
317+ free ( data );
318+ } else {
319+ LeLog ( " app" ).error ( " Could not allocate data to hold image. %d bytes requested" , num_bytes );
320+ }
292321
293322 app->dropped_image_path .clear ();
294323}
@@ -302,7 +331,7 @@ static void pass_sort_execute( le_command_buffer_encoder_o* encoder_, void* user
302331 log.info ( " running compute pass..." );
303332
304333 le::ComputeEncoder encoder{ encoder_ };
305- auto app = static_cast <app_o*>( user_data );
334+ auto app = static_cast <app_o*>( user_data );
306335
307336 size_t n = app->pixels_data ->w * app->pixels_data ->h ;
308337
@@ -452,7 +481,7 @@ static void pass_sort_execute( le_command_buffer_encoder_o* encoder_, void* user
452481// ----------------------------------------------------------------------
453482// Draw contents of buffer to screen
454483static void pass_draw_exec ( le_command_buffer_encoder_o* encoder_, void * user_data ) {
455- auto app = static_cast <bitonic_merge_sort_example_app_o*>( user_data );
484+ auto app = static_cast <bitonic_merge_sort_example_app_o*>( user_data );
456485 le::GraphicsEncoder encoder{ encoder_ };
457486
458487 // Draw main scene
0 commit comments