Skip to content

Commit 0af3eb8

Browse files
WIP
1 parent 93fdda9 commit 0af3eb8

File tree

2 files changed

+223
-39
lines changed

2 files changed

+223
-39
lines changed

extensions/pl_resource_ext.c

Lines changed: 219 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,11 @@ pl_resource_new_frame(void)
248248
plCommandBuffer* ptCommandBuffer = gptGfx->request_command_buffer(ptCmdPool, "resource update");
249249
gptGfx->begin_command_recording(ptCommandBuffer, NULL);
250250
plBlitEncoder* ptBlitEncoder = gptGfx->begin_blit_pass(ptCommandBuffer);
251-
gptGfx->pipeline_barrier_blit(ptBlitEncoder, PL_PIPELINE_STAGE_VERTEX_SHADER | PL_PIPELINE_STAGE_COMPUTE_SHADER | PL_PIPELINE_STAGE_TRANSFER, PL_ACCESS_SHADER_READ | PL_ACCESS_TRANSFER_READ, PL_PIPELINE_STAGE_TRANSFER, PL_ACCESS_TRANSFER_WRITE);
251+
gptGfx->pipeline_barrier_blit(ptBlitEncoder,
252+
PL_PIPELINE_STAGE_VERTEX_SHADER | PL_PIPELINE_STAGE_COMPUTE_SHADER | PL_PIPELINE_STAGE_TRANSFER,
253+
PL_ACCESS_SHADER_READ | PL_ACCESS_TRANSFER_READ,
254+
PL_PIPELINE_STAGE_TRANSFER,
255+
PL_ACCESS_TRANSFER_WRITE);
252256

253257
for(uint32_t i = 0; i < uJobCount; i++)
254258
{
@@ -260,7 +264,11 @@ pl_resource_new_frame(void)
260264
gptGfx->generate_mipmaps(ptBlitEncoder, ptJob->tTexture);
261265
}
262266

263-
gptGfx->pipeline_barrier_blit(ptBlitEncoder, PL_PIPELINE_STAGE_TRANSFER, PL_ACCESS_TRANSFER_WRITE, PL_PIPELINE_STAGE_VERTEX_SHADER | PL_PIPELINE_STAGE_COMPUTE_SHADER | PL_PIPELINE_STAGE_TRANSFER, PL_ACCESS_SHADER_READ | PL_ACCESS_TRANSFER_READ);
267+
gptGfx->pipeline_barrier_blit(ptBlitEncoder,
268+
PL_PIPELINE_STAGE_TRANSFER,
269+
PL_ACCESS_TRANSFER_WRITE,
270+
PL_PIPELINE_STAGE_VERTEX_SHADER | PL_PIPELINE_STAGE_COMPUTE_SHADER | PL_PIPELINE_STAGE_TRANSFER,
271+
PL_ACCESS_SHADER_READ | PL_ACCESS_TRANSFER_READ);
264272
gptGfx->end_blit_pass(ptBlitEncoder);
265273
gptGfx->end_command_recording(ptCommandBuffer);
266274
gptGfx->submit_command_buffer(ptCommandBuffer, NULL);
@@ -318,7 +326,7 @@ pl_resource_load_ex(const char* pcName, plResourceLoadFlags tFlags, uint8_t* puO
318326

319327
uint8_t* puFileData = puOriginalFileData;
320328

321-
// load file data
329+
// load file data if not manually loaded
322330
if(puFileData == NULL)
323331
{
324332
szFileByteSize = gptVfs->get_file_size_str(pcContainerFileName); //-V763
@@ -350,11 +358,10 @@ pl_resource_load_ex(const char* pcName, plResourceLoadFlags tFlags, uint8_t* puO
350358
tResource.puFileData = puFileData;
351359
}
352360

353-
354361
strncpy(tResource.acName, pcName, PL_MAX_NAME_LENGTH);
355362
strncpy(tResource.acContainerFileName, pcContainerFileName, PL_MAX_NAME_LENGTH);
356363

357-
// find our resource a home
364+
// find our resource a home slot
358365
uint64_t uIndex = pl_hm_get_free_index(&gptResourceManager->tNameHashmap);
359366
if(uIndex == PL_DS_HASH_INVALID)
360367
{
@@ -407,7 +414,6 @@ pl_resource_load_ex(const char* pcName, plResourceLoadFlags tFlags, uint8_t* puO
407414
int iTextureWidth = 0;
408415
int iTextureHeight = 0;
409416
int iTextureChannels = 0;
410-
plFormat tTextureFormat = PL_FORMAT_UNKNOWN;
411417

412418
if(tImageInfo.bHDR)
413419
{
@@ -427,7 +433,7 @@ pl_resource_load_ex(const char* pcName, plResourceLoadFlags tFlags, uint8_t* puO
427433
else if(gptResourceManager->tStagingBuffer.szOffset + szRequiredStagingSize >= gptResourceManager->tStagingBuffer.szSize)
428434
{
429435
pl_resource_new_frame();
430-
pl_resource_new_frame();
436+
pl_resource_new_frame(); // this one destroys the staging buffer
431437
pl__resource_create_staging_buffer(szRequiredStagingSize);
432438
}
433439

@@ -459,7 +465,7 @@ pl_resource_load_ex(const char* pcName, plResourceLoadFlags tFlags, uint8_t* puO
459465
else if(gptResourceManager->tStagingBuffer.szOffset + szRequiredStagingSize >= gptResourceManager->tStagingBuffer.szSize)
460466
{
461467
pl_resource_new_frame();
462-
pl_resource_new_frame();
468+
pl_resource_new_frame(); // this one destroys the staging buffer
463469
pl__resource_create_staging_buffer(szRequiredStagingSize);
464470
}
465471

@@ -470,8 +476,6 @@ pl_resource_load_ex(const char* pcName, plResourceLoadFlags tFlags, uint8_t* puO
470476

471477
gptImage->free(puRawBytes);
472478

473-
tTextureFormat = PL_FORMAT_R16G16B16A16_UNORM;
474-
475479
// create texture
476480
const plTextureDesc tTextureDesc = {
477481
.tDimensions = {(float)tImageInfo.iWidth, (float)tImageInfo.iHeight, 1},
@@ -484,6 +488,178 @@ pl_resource_load_ex(const char* pcName, plResourceLoadFlags tFlags, uint8_t* puO
484488

485489
tResource.tTexture = gptGfx->create_texture(ptDevice, &tTextureDesc, &ptTexture);
486490
}
491+
else if(bAttemptCompression)
492+
{
493+
unsigned char* puRawBytes = gptImage->load((unsigned char*)puFileData, (int)szFileByteSize, &iTextureWidth, &iTextureHeight, &iTextureChannels, 4);
494+
495+
if(bResizeNeeded)
496+
{
497+
unsigned char* puOldRawBytes = puRawBytes;
498+
puRawBytes = stbir_resize_uint8_linear(puRawBytes, iTextureWidth, iTextureHeight, 0, NULL, tImageInfo.iWidth, tImageInfo.iHeight, 0, STBIR_RGBA);
499+
PL_ASSERT(puRawBytes);
500+
gptImage->free(puOldRawBytes);
501+
}
502+
503+
// create texture
504+
const plTextureDesc tTextureDesc = {
505+
.tDimensions = {(float)tImageInfo.iWidth, (float)tImageInfo.iHeight, 1},
506+
.tFormat = PL_FORMAT_BC2_UNORM,
507+
.uLayers = 1,
508+
.uMips = 0,
509+
.tType = PL_TEXTURE_TYPE_2D,
510+
.tUsage = PL_TEXTURE_USAGE_SAMPLED
511+
};
512+
513+
tResource.tTexture = gptGfx->create_texture(ptDevice, &tTextureDesc, &ptTexture);
514+
515+
// choose allocator
516+
plDeviceMemoryAllocatorI* ptAllocator = gptResourceManager->ptLocalBuddyAllocator;
517+
if(ptTexture->tMemoryRequirements.ulSize > gptGpuAllocators->get_buddy_block_size())
518+
ptAllocator = gptResourceManager->ptLocalDedicatedAllocator;
519+
520+
// allocate memory
521+
const plDeviceMemoryAllocation tAllocation = ptAllocator->allocate(ptAllocator->ptInst,
522+
ptTexture->tMemoryRequirements.uMemoryTypeBits,
523+
ptTexture->tMemoryRequirements.ulSize,
524+
ptTexture->tMemoryRequirements.ulAlignment,
525+
pl_temp_allocator_sprintf(&gptResourceManager->tTempAllocator, "texture alloc %s", pcName));
526+
pl_temp_allocator_reset(&gptResourceManager->tTempAllocator);
527+
528+
// bind memory
529+
gptGfx->bind_texture_to_memory(ptDevice, tResource.tTexture, &tAllocation);
530+
531+
plDxtInfo tDxtInfoOriginal = {
532+
.tFlags = PL_DXT_FLAGS_HIGH_QUALITY,
533+
.uWidth = (uint32_t)tImageInfo.iWidth,
534+
.uHeight = (uint32_t)tImageInfo.iHeight,
535+
.uChannels = 4,
536+
.puData = puRawBytes
537+
};
538+
size_t szRequiredStagingSize = 0;
539+
gptDxt->compress(&tDxtInfoOriginal, NULL, &szRequiredStagingSize);
540+
541+
542+
if(!gptGfx->is_buffer_valid(ptDevice, gptResourceManager->tStagingBuffer.tStagingBufferHandle))
543+
pl__resource_create_staging_buffer(szRequiredStagingSize);
544+
else if(gptResourceManager->tStagingBuffer.szOffset + szRequiredStagingSize >= gptResourceManager->tStagingBuffer.szSize)
545+
{
546+
pl_resource_new_frame();
547+
pl_resource_new_frame(); // this one destroys the staging buffer
548+
pl__resource_create_staging_buffer(szRequiredStagingSize);
549+
}
550+
551+
552+
553+
554+
plBuffer* ptStagingBuffer = gptGfx->get_buffer(ptDevice, gptResourceManager->tStagingBuffer.tStagingBufferHandle);
555+
556+
gptDxt->compress(&tDxtInfoOriginal, (uint8_t*)&ptStagingBuffer->tMemoryAllocation.pHostMapped[szStagingOffset], &szRequiredStagingSize);
557+
558+
size_t szCurrentSize = szRequiredStagingSize;
559+
size_t szMaxBufferSize = tImageInfo.iWidth * tImageInfo.iHeight * 4;
560+
uint8_t* auWorkingBuffer[2] = {0};
561+
auWorkingBuffer[0] = PL_ALLOC(szMaxBufferSize);
562+
auWorkingBuffer[1] = puRawBytes;
563+
memset(auWorkingBuffer[0], 0, szMaxBufferSize);
564+
565+
566+
567+
const plBufferImageCopy tBufferImageCopy0 = {
568+
.uImageWidth = (uint32_t)tImageInfo.iWidth,
569+
.uImageHeight = (uint32_t)tImageInfo.iHeight,
570+
.uImageDepth = 1,
571+
.uLayerCount = 1,
572+
.szBufferOffset = szStagingOffset,
573+
.uMipLevel = 0
574+
};
575+
576+
plCommandPool* ptCmdPool = gptResourceManager->atCmdPools[gptGfx->get_current_frame_index()];
577+
plCommandBuffer* ptCommandBuffer = gptGfx->request_command_buffer(ptCmdPool, "resource update");
578+
gptGfx->begin_command_recording(ptCommandBuffer, NULL);
579+
plBlitEncoder* ptBlitEncoder = gptGfx->begin_blit_pass(ptCommandBuffer);
580+
gptGfx->set_texture_usage(ptBlitEncoder, tResource.tTexture, PL_TEXTURE_USAGE_SAMPLED, 0);
581+
582+
gptGfx->copy_buffer_to_texture(ptBlitEncoder, gptResourceManager->tStagingBuffer.tStagingBufferHandle, tResource.tTexture, 1, &tBufferImageCopy0);
583+
584+
szStagingOffset += szCurrentSize;
585+
586+
for(uint32_t uMipLevel = 1; uMipLevel < ptTexture->tDesc.uMips; uMipLevel++)
587+
{
588+
589+
uint8_t* puSrcBuffer = auWorkingBuffer[uMipLevel % 2];
590+
uint8_t* puDstBuffer = auWorkingBuffer[(uMipLevel + 1) % 2];
591+
592+
int iCurrentWidth = (int)tImageInfo.iWidth / ((1 << (int)uMipLevel));
593+
int iCurrentHeight = (int)tImageInfo.iHeight / ((1 << (int)uMipLevel));
594+
595+
int iLastWidth = iCurrentWidth * 2;
596+
int iLastHeight = iCurrentHeight * 2;
597+
598+
szCurrentSize = 0;
599+
600+
// manual mip mapping
601+
for(uint32_t i = 0; i < (uint32_t)iCurrentWidth; i++)
602+
{
603+
for(uint32_t j = 0; j < (uint32_t)iCurrentHeight; j++)
604+
{
605+
uint32_t uSrcOriginX = i * 2;
606+
uint32_t uSrcOriginY = j * 2;
607+
608+
uint8_t* ptPixel0 = &puSrcBuffer[uSrcOriginY * iLastWidth * 4 + uSrcOriginX * 4];
609+
uint8_t* ptPixel1 = &puSrcBuffer[uSrcOriginY * iLastWidth * 4 + (uSrcOriginX + 1) * 4];
610+
uint8_t* ptPixel2 = &puSrcBuffer[(uSrcOriginY + 1) * iLastWidth * 4 + uSrcOriginX * 4];
611+
uint8_t* ptPixel3 = &puSrcBuffer[(uSrcOriginY + 1) * iLastWidth * 4 + (uSrcOriginX + 1) * 4];
612+
613+
uint8_t uRed = (ptPixel0[0] + ptPixel1[0] + ptPixel2[0] + ptPixel3[0]) / 4;
614+
uint8_t uGreen = (ptPixel0[1] + ptPixel1[1] + ptPixel2[1] + ptPixel3[1]) / 4;
615+
uint8_t uBlue = (ptPixel0[2] + ptPixel1[2] + ptPixel2[2] + ptPixel3[2]) / 4;
616+
uint8_t uAlpha = (ptPixel0[3] + ptPixel1[3] + ptPixel2[3] + ptPixel3[3]) / 4;
617+
618+
619+
puDstBuffer[j * iCurrentWidth * 4 + i * 4 + 0] = uRed;
620+
puDstBuffer[j * iCurrentWidth * 4 + i * 4 + 1] = uGreen;
621+
puDstBuffer[j * iCurrentWidth * 4 + i * 4 + 2] = uBlue;
622+
puDstBuffer[j * iCurrentWidth * 4 + i * 4 + 3] = uAlpha;
623+
}
624+
}
625+
626+
// compression
627+
{
628+
plDxtInfo tDxtInfo = {
629+
.tFlags = PL_DXT_FLAGS_HIGH_QUALITY,
630+
.uWidth = (uint32_t)iCurrentWidth,
631+
.uHeight = (uint32_t)iCurrentHeight,
632+
.uChannels = 4,
633+
.puData = puDstBuffer
634+
};
635+
szRequiredStagingSize = 0;
636+
gptDxt->compress(&tDxtInfo, NULL, &szRequiredStagingSize);
637+
gptDxt->compress(&tDxtInfo, (uint8_t*)&ptStagingBuffer->tMemoryAllocation.pHostMapped[szStagingOffset], &szRequiredStagingSize);
638+
szCurrentSize = szRequiredStagingSize;
639+
}
640+
641+
const plBufferImageCopy tBufferImageCopy = {
642+
.uImageWidth = (uint32_t)iCurrentWidth,
643+
.uImageHeight = (uint32_t)iCurrentHeight,
644+
.uImageDepth = 1,
645+
.uLayerCount = 1,
646+
.szBufferOffset = szStagingOffset,
647+
.uMipLevel = uMipLevel
648+
};
649+
650+
gptGfx->copy_buffer_to_texture(ptBlitEncoder, gptResourceManager->tStagingBuffer.tStagingBufferHandle, tResource.tTexture, 1, &tBufferImageCopy);
651+
szStagingOffset += szCurrentSize;
652+
}
653+
654+
gptGfx->end_blit_pass(ptBlitEncoder);
655+
gptGfx->end_command_recording(ptCommandBuffer);
656+
gptGfx->submit_command_buffer(ptCommandBuffer, NULL);
657+
gptGfx->wait_on_command_buffer(ptCommandBuffer);
658+
gptGfx->return_command_buffer(ptCommandBuffer);
659+
660+
gptImage->free(puRawBytes);
661+
PL_FREE(auWorkingBuffer[0]);
662+
}
487663
else
488664
{
489665
unsigned char* puRawBytes = gptImage->load((unsigned char*)puFileData, (int)szFileByteSize, &iTextureWidth, &iTextureHeight, &iTextureChannels, 4);
@@ -502,7 +678,7 @@ pl_resource_load_ex(const char* pcName, plResourceLoadFlags tFlags, uint8_t* puO
502678
else if(gptResourceManager->tStagingBuffer.szOffset + szRequiredStagingSize >= gptResourceManager->tStagingBuffer.szSize)
503679
{
504680
pl_resource_new_frame();
505-
pl_resource_new_frame();
681+
pl_resource_new_frame(); // this one destroys the staging buffer
506682
pl__resource_create_staging_buffer(szRequiredStagingSize);
507683
}
508684

@@ -525,35 +701,39 @@ pl_resource_load_ex(const char* pcName, plResourceLoadFlags tFlags, uint8_t* puO
525701

526702
tResource.tTexture = gptGfx->create_texture(ptDevice, &tTextureDesc, &ptTexture);
527703
}
704+
705+
if(!bAttemptCompression)
706+
{
528707

529-
// choose allocator
530-
plDeviceMemoryAllocatorI* ptAllocator = gptResourceManager->ptLocalBuddyAllocator;
531-
if(ptTexture->tMemoryRequirements.ulSize > gptGpuAllocators->get_buddy_block_size())
532-
ptAllocator = gptResourceManager->ptLocalDedicatedAllocator;
533-
534-
// allocate memory
535-
const plDeviceMemoryAllocation tAllocation = ptAllocator->allocate(ptAllocator->ptInst,
536-
ptTexture->tMemoryRequirements.uMemoryTypeBits,
537-
ptTexture->tMemoryRequirements.ulSize,
538-
ptTexture->tMemoryRequirements.ulAlignment,
539-
pl_temp_allocator_sprintf(&gptResourceManager->tTempAllocator, "texture alloc %s", pcName));
540-
pl_temp_allocator_reset(&gptResourceManager->tTempAllocator);
541-
542-
// bind memory
543-
gptGfx->bind_texture_to_memory(ptDevice, tResource.tTexture, &tAllocation);
544-
545-
plTextureUploadJob tUpload = {
546-
.tTexture = tResource.tTexture,
547-
.tBufferImageCopy = {
548-
.uImageWidth = (uint32_t)ptTexture->tDesc.tDimensions.x,
549-
.uImageHeight = (uint32_t)ptTexture->tDesc.tDimensions.y,
550-
.uImageDepth = 1,
551-
.uLayerCount = 1,
552-
.szBufferOffset = szStagingOffset
553-
},
554-
.bGenerateMips = bGenerateMips
555-
};
556-
pl_sb_push(gptResourceManager->sbtTextureUploadJobs, tUpload);
708+
// choose allocator
709+
plDeviceMemoryAllocatorI* ptAllocator = gptResourceManager->ptLocalBuddyAllocator;
710+
if(ptTexture->tMemoryRequirements.ulSize > gptGpuAllocators->get_buddy_block_size())
711+
ptAllocator = gptResourceManager->ptLocalDedicatedAllocator;
712+
713+
// allocate memory
714+
const plDeviceMemoryAllocation tAllocation = ptAllocator->allocate(ptAllocator->ptInst,
715+
ptTexture->tMemoryRequirements.uMemoryTypeBits,
716+
ptTexture->tMemoryRequirements.ulSize,
717+
ptTexture->tMemoryRequirements.ulAlignment,
718+
pl_temp_allocator_sprintf(&gptResourceManager->tTempAllocator, "texture alloc %s", pcName));
719+
pl_temp_allocator_reset(&gptResourceManager->tTempAllocator);
720+
721+
// bind memory
722+
gptGfx->bind_texture_to_memory(ptDevice, tResource.tTexture, &tAllocation);
723+
724+
plTextureUploadJob tUpload = {
725+
.tTexture = tResource.tTexture,
726+
.tBufferImageCopy = {
727+
.uImageWidth = (uint32_t)ptTexture->tDesc.tDimensions.x,
728+
.uImageHeight = (uint32_t)ptTexture->tDesc.tDimensions.y,
729+
.uImageDepth = 1,
730+
.uLayerCount = 1,
731+
.szBufferOffset = szStagingOffset
732+
},
733+
.bGenerateMips = bGenerateMips
734+
};
735+
pl_sb_push(gptResourceManager->sbtTextureUploadJobs, tUpload);
736+
}
557737
}
558738
break;
559739
}

extensions/pl_resource_ext.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ Index of this file:
2828
* plGPUAllocatorsI (v1.x)
2929
* plVfsI (v1.x)
3030
* plImageI (v1.x)
31+
32+
unstable APIs:
33+
* plDdsI
34+
* plDxtI
3135
*/
3236

3337
//-----------------------------------------------------------------------------

0 commit comments

Comments
 (0)