@@ -42,6 +42,9 @@ Index of this file:
4242#include "pl_shader_ext.h"
4343#include "pl_starter_ext.h"
4444#include "pl_vfs_ext.h"
45+ #include "pl_resource_ext.h"
46+ #include "pl_dxt_ext.h"
47+ #include "pl_dds_ext.h"
4548
4649//-----------------------------------------------------------------------------
4750// [SECTION] structs
@@ -56,6 +59,7 @@ typedef struct _plAppData
5659 plShaderHandle tShader ;
5760
5861 // buffers
62+ plBufferHandle tMipStagingBuffer ;
5963 plBufferHandle tStagingBuffer ;
6064 plBufferHandle tIndexBuffer ;
6165 plBufferHandle tVertexBuffer ;
@@ -87,6 +91,9 @@ const plShaderI* gptShader = NULL;
8791const plFileI * gptFile = NULL ;
8892const plStarterI * gptStarter = NULL ;
8993const plVfsI * gptVfs = NULL ;
94+ const plResourceI * gptResource = NULL ;
95+ const plDxtI * gptDxt = NULL ;
96+ const plDdsI * gptDds = NULL ;
9097
9198//-----------------------------------------------------------------------------
9299// [SECTION] pl_app_load
@@ -116,6 +123,9 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plAppData* ptAppData)
116123 gptFile = pl_get_api_latest (ptApiRegistry , plFileI );
117124 gptStarter = pl_get_api_latest (ptApiRegistry , plStarterI );
118125 gptVfs = pl_get_api_latest (ptApiRegistry , plVfsI );
126+ gptResource = pl_get_api_latest (ptApiRegistry , plResourceI );
127+ gptDxt = pl_get_api_latest (ptApiRegistry , plDxtI );
128+ gptDds = pl_get_api_latest (ptApiRegistry , plDdsI );
119129
120130 return ptAppData ;
121131 }
@@ -137,12 +147,15 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plAppData* ptAppData)
137147 gptWindows = pl_get_api_latest (ptApiRegistry , plWindowI );
138148
139149 // load required apis (these are provided though extensions)
140- gptGfx = pl_get_api_latest (ptApiRegistry , plGraphicsI );
141- gptShader = pl_get_api_latest (ptApiRegistry , plShaderI );
142- gptImage = pl_get_api_latest (ptApiRegistry , plImageI );
143- gptFile = pl_get_api_latest (ptApiRegistry , plFileI );
144- gptStarter = pl_get_api_latest (ptApiRegistry , plStarterI );
145- gptVfs = pl_get_api_latest (ptApiRegistry , plVfsI );
150+ gptGfx = pl_get_api_latest (ptApiRegistry , plGraphicsI );
151+ gptShader = pl_get_api_latest (ptApiRegistry , plShaderI );
152+ gptImage = pl_get_api_latest (ptApiRegistry , plImageI );
153+ gptFile = pl_get_api_latest (ptApiRegistry , plFileI );
154+ gptStarter = pl_get_api_latest (ptApiRegistry , plStarterI );
155+ gptVfs = pl_get_api_latest (ptApiRegistry , plVfsI );
156+ gptResource = pl_get_api_latest (ptApiRegistry , plResourceI );
157+ gptDxt = pl_get_api_latest (ptApiRegistry , plDxtI );
158+ gptDds = pl_get_api_latest (ptApiRegistry , plDdsI );
146159
147160 gptVfs -> mount_directory ("/assets" , "../data/pilotlight-assets-master" , PL_VFS_MOUNT_FLAGS_NONE );
148161
@@ -172,6 +185,11 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plAppData* ptAppData)
172185
173186 plDevice * ptDevice = gptStarter -> get_device ();
174187
188+ plResourceManagerInit tResourceInit = {
189+ .ptDevice = ptDevice
190+ };
191+ gptResource -> initialize (tResourceInit );
192+
175193 // initialize shader extension (we are doing this ourselves so we can add additional shader directories)
176194 static const plShaderOptions tDefaultShaderOptions = {
177195 .apcIncludeDirectories = {
@@ -301,9 +319,10 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plAppData* ptAppData)
301319 // create texture
302320 const plTextureDesc tTextureDesc = {
303321 .tDimensions = { (float )iImageWidth , (float )iImageHeight , 1 },
304- .tFormat = PL_FORMAT_R8G8B8A8_UNORM ,
322+ // .tFormat = PL_FORMAT_R8G8B8A8_UNORM,
323+ .tFormat = PL_FORMAT_BC2_UNORM ,
305324 .uLayers = 1 ,
306- .uMips = 1 ,
325+ .uMips = 0 ,
307326 .tType = PL_TEXTURE_TYPE_2D ,
308327 .tUsage = PL_TEXTURE_USAGE_SAMPLED ,
309328 .pcDebugName = "texture"
@@ -313,6 +332,32 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plAppData* ptAppData)
313332 // retrieve new texture (also could have used out param from create_texture above)
314333 plTexture * ptTexture = gptGfx -> get_texture (ptDevice , ptAppData -> tTexture );
315334
335+ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~mip buffer~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
336+
337+ // create vertex buffer
338+ const plBufferDesc tMipBufferDesc = {
339+ .tUsage = PL_BUFFER_USAGE_STAGING ,
340+ .szByteSize = ptTexture -> tMemoryRequirements .ulSize ,
341+ .pcDebugName = "mip buffer"
342+ };
343+ ptAppData -> tMipStagingBuffer = gptGfx -> create_buffer (ptDevice , & tMipBufferDesc , NULL );
344+ ptStagingBuffer = gptGfx -> get_buffer (ptDevice , ptAppData -> tStagingBuffer );
345+
346+ // retrieve buffer to get memory allocation requirements (do not store buffer pointer)
347+ plBuffer * ptMipBuffer = gptGfx -> get_buffer (ptDevice , ptAppData -> tMipStagingBuffer );
348+
349+ // allocate memory for the vertex buffer
350+ const plDeviceMemoryAllocation tMipBufferAllocation = gptGfx -> allocate_memory (ptDevice ,
351+ ptMipBuffer -> tMemoryRequirements .ulSize ,
352+ PL_MEMORY_FLAGS_HOST_VISIBLE | PL_MEMORY_FLAGS_HOST_COHERENT ,
353+ ptMipBuffer -> tMemoryRequirements .uMemoryTypeBits ,
354+ "mip buffer memory" );
355+
356+ // bind the buffer to the new memory allocation
357+ gptGfx -> bind_buffer_to_memory (ptDevice , ptAppData -> tMipStagingBuffer , & tMipBufferAllocation );
358+
359+ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~buffer~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
360+
316361 // allocate memory
317362 const plDeviceMemoryAllocation tTextureAllocation = gptGfx -> allocate_memory (ptDevice ,
318363 ptTexture -> tMemoryRequirements .ulSize ,
@@ -327,18 +372,117 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plAppData* ptAppData)
327372 gptGfx -> set_texture_usage (ptEncoder , ptAppData -> tTexture , PL_TEXTURE_USAGE_SAMPLED , 0 );
328373
329374 // copy memory to mapped staging buffer
330- memcpy (& ptStagingBuffer -> tMemoryAllocation .pHostMapped [2048 ], pucImageData , iImageWidth * iImageHeight * 4 );
375+ size_t szCurrentOffset = 0 ;
376+
377+ size_t szMaxBufferSize = iImageWidth * iImageHeight * 4 ;
378+ uint8_t * auWorkingBuffer [2 ] = {0 };
379+ auWorkingBuffer [0 ] = malloc (szMaxBufferSize );
380+ auWorkingBuffer [1 ] = pucImageData ;
381+ memset (auWorkingBuffer [0 ], 0 , szMaxBufferSize );
382+
383+ size_t szCurrentSize = 0 ;
331384
332- const plBufferImageCopy tBufferImageCopy = {
385+ // compression
386+ {
387+ plDxtInfo tDxtInfo = {
388+ .tFlags = PL_DXT_FLAGS_HIGH_QUALITY ,
389+ .uWidth = (uint32_t )iImageWidth ,
390+ .uHeight = (uint32_t )iImageHeight ,
391+ .uChannels = 4 ,
392+ .puData = pucImageData
393+ };
394+ size_t szRequiredStagingSize = 0 ;
395+ gptDxt -> compress (& tDxtInfo , NULL , & szRequiredStagingSize );
396+ gptDxt -> compress (& tDxtInfo , (uint8_t * )& ptMipBuffer -> tMemoryAllocation .pHostMapped [szCurrentOffset ], & szRequiredStagingSize );
397+ szCurrentSize = szRequiredStagingSize ;
398+ }
399+
400+ const plBufferImageCopy tBufferImageCopy0 = {
333401 .uImageWidth = (uint32_t )iImageWidth ,
334402 .uImageHeight = (uint32_t )iImageHeight ,
335403 .uImageDepth = 1 ,
336404 .uLayerCount = 1 ,
337- .szBufferOffset = 2048
405+ .szBufferOffset = szCurrentOffset ,
406+ .uMipLevel = 0
338407 };
339408
340- gptGfx -> copy_buffer_to_texture (ptEncoder , ptAppData -> tStagingBuffer , ptAppData -> tTexture , 1 , & tBufferImageCopy );
409+ gptGfx -> copy_buffer_to_texture (ptEncoder , ptAppData -> tMipStagingBuffer , ptAppData -> tTexture , 1 , & tBufferImageCopy0 );
341410
411+ szCurrentOffset += szCurrentSize ;
412+
413+ for (uint32_t uMipLevel = 1 ; uMipLevel < ptTexture -> tDesc .uMips ; uMipLevel ++ )
414+ {
415+
416+ uint8_t * puSrcBuffer = auWorkingBuffer [uMipLevel % 2 ];
417+ uint8_t * puDstBuffer = auWorkingBuffer [(uMipLevel + 1 ) % 2 ];
418+
419+ int iCurrentWidth = (int )iImageWidth / ((1 << (int )uMipLevel ));
420+ int iCurrentHeight = (int )iImageHeight / ((1 << (int )uMipLevel ));
421+
422+ int iLastWidth = iCurrentWidth * 2 ;
423+ int iLastHeight = iCurrentHeight * 2 ;
424+
425+ szCurrentSize = 0 ;
426+
427+ // manual mip mapping
428+ for (uint32_t i = 0 ; i < (uint32_t )iCurrentWidth ; i ++ )
429+ {
430+ for (uint32_t j = 0 ; j < (uint32_t )iCurrentHeight ; j ++ )
431+ {
432+ uint32_t uSrcOriginX = i * 2 ;
433+ uint32_t uSrcOriginY = j * 2 ;
434+
435+ uint8_t * ptPixel0 = & puSrcBuffer [uSrcOriginY * iLastWidth * 4 + uSrcOriginX * 4 ];
436+ uint8_t * ptPixel1 = & puSrcBuffer [uSrcOriginY * iLastWidth * 4 + (uSrcOriginX + 1 ) * 4 ];
437+ uint8_t * ptPixel2 = & puSrcBuffer [(uSrcOriginY + 1 ) * iLastWidth * 4 + uSrcOriginX * 4 ];
438+ uint8_t * ptPixel3 = & puSrcBuffer [(uSrcOriginY + 1 ) * iLastWidth * 4 + (uSrcOriginX + 1 ) * 4 ];
439+
440+ uint8_t uRed = (ptPixel0 [0 ] + ptPixel1 [0 ] + ptPixel2 [0 ] + ptPixel3 [0 ]) / 4 ;
441+ uint8_t uGreen = (ptPixel0 [1 ] + ptPixel1 [1 ] + ptPixel2 [1 ] + ptPixel3 [1 ]) / 4 ;
442+ uint8_t uBlue = (ptPixel0 [2 ] + ptPixel1 [2 ] + ptPixel2 [2 ] + ptPixel3 [2 ]) / 4 ;
443+ uint8_t uAlpha = (ptPixel0 [3 ] + ptPixel1 [3 ] + ptPixel2 [3 ] + ptPixel3 [3 ]) / 4 ;
444+
445+
446+ puDstBuffer [j * iCurrentWidth * 4 + i * 4 + 0 ] = uRed ;
447+ puDstBuffer [j * iCurrentWidth * 4 + i * 4 + 1 ] = uGreen ;
448+ puDstBuffer [j * iCurrentWidth * 4 + i * 4 + 2 ] = uBlue ;
449+ puDstBuffer [j * iCurrentWidth * 4 + i * 4 + 3 ] = uAlpha ;
450+ }
451+ }
452+
453+ // compression
454+ {
455+ plDxtInfo tDxtInfo = {
456+ .tFlags = PL_DXT_FLAGS_HIGH_QUALITY ,
457+ .uWidth = (uint32_t )iCurrentWidth ,
458+ .uHeight = (uint32_t )iCurrentHeight ,
459+ .uChannels = 4 ,
460+ .puData = puDstBuffer
461+ };
462+ size_t szRequiredStagingSize = 0 ;
463+ gptDxt -> compress (& tDxtInfo , NULL , & szRequiredStagingSize );
464+ gptDxt -> compress (& tDxtInfo , (uint8_t * )& ptMipBuffer -> tMemoryAllocation .pHostMapped [szCurrentOffset ], & szRequiredStagingSize );
465+ szCurrentSize = szRequiredStagingSize ;
466+
467+ // memcpy(&ptStagingBuffer->tMemoryAllocation.pHostMapped[2048], pucImageData, iImageWidth * iImageHeight * 4);
468+ }
469+
470+ // not compressed
471+ // memcpy(&ptMipBuffer->tMemoryAllocation.pHostMapped[szCurrentOffset], puDstBuffer, szCurrentSize);
472+
473+ const plBufferImageCopy tBufferImageCopy = {
474+ .uImageWidth = (uint32_t )iCurrentWidth ,
475+ .uImageHeight = (uint32_t )iCurrentHeight ,
476+ .uImageDepth = 1 ,
477+ .uLayerCount = 1 ,
478+ .szBufferOffset = szCurrentOffset ,
479+ .uMipLevel = uMipLevel
480+ };
481+
482+ gptGfx -> copy_buffer_to_texture (ptEncoder , ptAppData -> tMipStagingBuffer , ptAppData -> tTexture , 1 , & tBufferImageCopy );
483+ szCurrentOffset += szCurrentSize ;
484+ }
485+
342486 gptStarter -> return_blit_encoder (ptEncoder );
343487
344488 // free image data
@@ -479,6 +623,8 @@ pl_app_shutdown(plAppData* ptAppData)
479623 gptGfx -> destroy_texture (ptDevice , ptAppData -> tTexture );
480624 gptGfx -> cleanup_bind_group_pool (ptAppData -> ptBindGroupPool );
481625
626+ gptResource -> cleanup ();
627+
482628 gptShader -> cleanup ();
483629 gptStarter -> cleanup ();
484630 gptWindows -> destroy (ptAppData -> ptWindow );
@@ -505,6 +651,8 @@ pl_app_update(plAppData* ptAppData)
505651 if (!gptStarter -> begin_frame ())
506652 return ;
507653
654+ gptResource -> new_frame ();
655+
508656 plDevice * ptDevice = gptStarter -> get_device ();
509657
510658 // start main pass & return the encoder being used
0 commit comments