/** * BC7 Compression function */ static void IntelBC7CompressScans(bc7_enc_settings* pEncSettings, FImage* pInImage, FCompressedImage2D* pOutImage, int yStart, int yEnd) { check(pInImage->Format == ERawImageFormat::BGRA8); check((yStart % 4) == 0); check((yStart >= 0) && (yStart <= pInImage->SizeY)); check((yEnd >= 0) && (yEnd <= pInImage->SizeY)); uint8* pInTexels = reinterpret_cast<uint8*>(&pInImage->RawData[0]); const int iInStride = pInImage->SizeX * 4; uint8* pOutTexels = reinterpret_cast<uint8*>(&pOutImage->RawData[0]); // Switch byte order for compressors input for ( int y=yStart; y < yEnd; ++y ) { uint8* pInTexelsSwap = pInTexels + (y * iInStride); for ( int x=0; x < pInImage->SizeX; ++x ) { const uint8 r = pInTexelsSwap[0]; pInTexelsSwap[0] = pInTexelsSwap[2]; pInTexelsSwap[2] = r; pInTexelsSwap += 4; } } rgba_surface insurface; insurface.ptr = pInTexels + (yStart * iInStride); insurface.width = pInImage->SizeX; insurface.height = yEnd - yStart; insurface.stride = pInImage->SizeX * 4; pOutTexels += ((yStart + 3) / 4) * ((pInImage->SizeX + 3) / 4) * 16; CompressBlocksBC7(&insurface, pOutTexels, pEncSettings); }
static std::unique_ptr<DirectX::ScratchImage> compress_with_ispc(std::unique_ptr<DirectX::ScratchImage> image, const std::shared_ptr<Spec> spec) { HRESULT hr; auto& meta = image->GetMetadata(); if (meta.format != DXGI_FORMAT_R8G8B8A8_UNORM) { auto temp = std::make_unique<DirectX::ScratchImage>(); hr = DirectX::Convert(image->GetImages(), image->GetImageCount(), image->GetMetadata(), DXGI_FORMAT_R8G8B8A8_UNORM, DirectX::TEX_FILTER_DEFAULT, 0.5f, *temp); if (FAILED(hr)) { printf(_T(" DirectX::Convert failed. ret = 0x%x\n"), hr); return nullptr; } image = std::move(temp); } auto width = static_cast<uint32_t>(image->GetMetadata().width); auto height = static_cast<uint32_t>(image->GetMetadata().height); DirectX::Blob blob; hr = blob.Initialize(compute_image_size(spec->format, width, height)); if (FAILED(hr)) { printf(_T(" DirectX::Blob::Initialize failed. ret = 0x%x\n"), hr); return nullptr; } rgba_surface surface; surface.ptr = image->GetPixels(); surface.width = width; surface.height = height; surface.stride = width * 4; // The format must be DXGI_FORMAT_R8G8B8A8_UNORM. switch (spec->format) { case DXGI_FORMAT_BC1_UNORM: CompressBlocksBC1(&surface, static_cast<uint8_t*>(blob.GetBufferPointer())); break; case DXGI_FORMAT_BC3_UNORM: CompressBlocksBC3(&surface, static_cast<uint8_t*>(blob.GetBufferPointer())); break; case DXGI_FORMAT_BC6H_UF16: { bc6h_enc_settings setting; init_bc6h_enc_settings(&setting, spec->level); CompressBlocksBC6H(&surface, static_cast<uint8_t*>(blob.GetBufferPointer()), &setting); } break; case DXGI_FORMAT_BC7_UNORM: { bc7_enc_settings setting; init_bc7_enc_settings(&setting, spec->level, spec->rgb_mode); CompressBlocksBC7(&surface, static_cast<uint8_t*>(blob.GetBufferPointer()), &setting); } break; } hr = image->Initialize2D(spec->format, width, height, 1, 1); if (FAILED(hr)) { printf(_T(" DirectX::ScratchImage::Initialize2D failed. ret = 0x%x\n"), hr); return nullptr; } memcpy(image->GetPixels(), blob.GetBufferPointer(), blob.GetBufferSize()); return image; }