Skip to content

Commit 93fdda9

Browse files
committed
WIP
1 parent 324eb84 commit 93fdda9

File tree

2 files changed

+213
-31
lines changed

2 files changed

+213
-31
lines changed

examples/example_gfx_2.c

Lines changed: 160 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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;
8791
const plFileI* gptFile = NULL;
8892
const plStarterI* gptStarter = NULL;
8993
const 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

Comments
 (0)