/**
 * 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);
}
Exemplo n.º 2
0
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;
}