public static bool IsTPFCube(TPF.Texture tex, TPF.TPFPlatform platform) { if (platform == TPF.TPFPlatform.PC) { DDS dds = new DDS(tex.Bytes); return((dds.dwCaps2 & DDS.DDSCAPS2.CUBEMAP) > 0); } return(tex.Type == TPF.TexType.Cubemap); }
public unsafe void FillWithPS4TPF(GraphicsDevice d, CommandList cl, TPF.TPFPlatform platform, TPF.Texture tex, string name) { if (platform != TPF.TPFPlatform.PS4) { return; } uint width = (uint)tex.Header.Width; uint height = (uint)tex.Header.Height; uint mipCount = (uint)tex.Mipmaps; PixelFormat format; format = GetPixelFormatFromDXGI((DDS.DXGI_FORMAT)tex.Header.DXGIFormat); width = (uint)(Math.Ceiling(width / 4f) * 4f); height = (uint)(Math.Ceiling(height / 4f) * 4f); if (mipCount == 0) { mipCount = (uint)(1 + Math.Floor(Math.Log(Math.Max(width, height), 2))); } bool isCubemap = (tex.Type == TPF.TexType.Cubemap); var usage = (isCubemap) ? TextureUsage.Cubemap : 0; uint arrayCount = isCubemap ? 6u : 1; TextureDescription desc = new TextureDescription(); desc.Width = width; desc.Height = height; desc.MipLevels = mipCount; desc.SampleCount = TextureSampleCount.Count1; desc.ArrayLayers = arrayCount; desc.Depth = 1; desc.Type = TextureType.Texture2D; desc.Usage = TextureUsage.Staging; desc.Format = format; _staging = d.ResourceFactory.CreateTexture(desc); uint blockSize = (uint)GetBlockSize(tex.Format); uint paddedWidth = 0; uint paddedHeight = 0; uint paddedSize = 0; uint copyOffset = 0; for (int slice = 0; slice < arrayCount; slice++) { uint currentWidth = width; uint currentHeight = height; for (uint level = 0; level < mipCount; level++) { if (tex.Format == 105) { paddedWidth = currentWidth; paddedHeight = currentHeight; paddedSize = paddedWidth * paddedHeight * blockSize; } else { paddedWidth = (uint)(Math.Ceiling(currentWidth / 32f) * 32f); paddedHeight = (uint)(Math.Ceiling(currentHeight / 32f) * 32f); paddedSize = (uint)(Math.Ceiling(paddedWidth / 4f) * Math.Ceiling(paddedHeight / 4f) * blockSize); } var mipInfo = GetMipInfo(format, tex.Header.Width, tex.Header.Height, (int)level, false); MappedResource map = d.Map(_staging, MapMode.Write, (uint)slice * (uint)mipCount + level); //fixed (void* data = &tex.Bytes[copyOffset]) //{ //Unsafe.CopyBlock(map.Data.ToPointer(), data, (uint)paddedSize); DeswizzleDDSBytesPS4((int)currentWidth, (int)currentHeight, tex.Format, (int)blockSize, (int)paddedWidth, new Span <byte>(tex.Bytes, (int)copyOffset, (int)paddedSize), new Span <byte>(map.Data.ToPointer(), (int)mipInfo)); //} copyOffset += paddedSize; if (currentWidth > 1) { currentWidth /= 2; } if (currentHeight > 1) { currentHeight /= 2; } } } desc.Usage = TextureUsage.Sampled | usage; desc.ArrayLayers = 1; _texture = d.ResourceFactory.CreateTexture(desc); _texture.Name = name; cl.CopyTexture(_staging, _texture); Resident = true; _pool.DescriptorTableDirty = true; }
public unsafe void FillWithTPF(GraphicsDevice d, CommandList cl, TPF.TPFPlatform platform, TPF.Texture tex, string name) { DDS dds; var bytes = tex.Bytes; if (platform != TPF.TPFPlatform.PC) { bytes = tex.Headerize(); dds = new DDS(bytes); } else { dds = new DDS(tex.Bytes); } uint width = (uint)dds.dwWidth; uint height = (uint)dds.dwHeight; PixelFormat format; if (dds.header10 != null) { format = GetPixelFormatFromDXGI(dds.header10.dxgiFormat); } else { if (dds.ddspf.dwFlags == (DDS.DDPF.RGB | DDS.DDPF.ALPHAPIXELS) && dds.ddspf.dwRGBBitCount == 32) { format = PixelFormat.R8_G8_B8_A8_UNorm_SRgb; } else if (dds.ddspf.dwFlags == (DDS.DDPF.RGB) && dds.ddspf.dwRGBBitCount == 24) { format = PixelFormat.R8_G8_B8_A8_UNorm_SRgb; // 24-bit formats are annoying for now return; } else { format = GetPixelFormatFromFourCC(dds.ddspf.dwFourCC); } } if (!Utils.IsPowerTwo(width) || !Utils.IsPowerTwo(height)) { return; } width = IsCompressedFormat(format) ? (uint)((width + 3) & ~0x3) : width; height = IsCompressedFormat(format) ? (uint)((height + 3) & ~0x3) : height; bool isCubemap = false; if ((dds.dwCaps2 & DDS.DDSCAPS2.CUBEMAP) > 0) { isCubemap = true; } var usage = (isCubemap) ? TextureUsage.Cubemap : 0; uint arrayCount = isCubemap ? 6u : 1; TextureDescription desc = new TextureDescription(); desc.Width = width; desc.Height = height; desc.MipLevels = (uint)dds.dwMipMapCount; desc.SampleCount = TextureSampleCount.Count1; desc.ArrayLayers = arrayCount; desc.Depth = 1; desc.Type = TextureType.Texture2D; desc.Usage = TextureUsage.Staging; desc.Format = format; _staging = d.ResourceFactory.CreateTexture(desc); int paddedWidth = 0; int paddedHeight = 0; int paddedSize = 0; int copyOffset = dds.DataOffset; for (int slice = 0; slice < arrayCount; slice++) { for (uint level = 0; level < dds.dwMipMapCount; level++) { MappedResource map = d.Map(_staging, MapMode.Write, (uint)slice * (uint)dds.dwMipMapCount + level); var mipInfo = GetMipInfo(format, (int)dds.dwWidth, (int)dds.dwHeight, (int)level, false); //paddedSize = mipInfo.ByteCount; paddedSize = mipInfo; fixed(void *data = &bytes[copyOffset]) { Unsafe.CopyBlock(map.Data.ToPointer(), data, (uint)paddedSize); } copyOffset += paddedSize; } } desc.Usage = TextureUsage.Sampled | usage; desc.ArrayLayers = 1; _texture = d.ResourceFactory.CreateTexture(desc); _texture.Name = name; cl.CopyTexture(_staging, _texture); Resident = true; _pool.DescriptorTableDirty = true; }