ISrvBindable CreateNewTexture(Vector2I resolution) { string debugName = string.Format("Debug-mipmap-{0}x{1}", resolution.X, resolution.Y); int mipmapLevels = MyResourceUtils.GetMipmapsCount(Math.Max(resolution.X, resolution.Y)); resolution.X = MyResourceUtils.GetMipmapStride(resolution.X, 0); // this is required by texture compression resolution.Y = MyResourceUtils.GetMipmapStride(resolution.Y, 0); // this is required by texture compression ISrvTexture dstTex = MyManagers.RwTextures.CreateSrv(debugName, resolution.X, resolution.Y, Format.BC7_UNorm_SRgb, mipmapLevels: mipmapLevels); for (int i = 0; i < mipmapLevels; i++) { ISrvBindable srcTex = m_fileTextures[i % m_fileTextures.Length]; Vector2I mipmapResolution = new Vector2I(MyResourceUtils.GetMipmapSize(resolution.X, i), MyResourceUtils.GetMipmapSize(resolution.Y, i)); for (int x = 0; x < mipmapResolution.X; x += srcTex.Size.X) { for (int y = 0; y < mipmapResolution.Y; y += srcTex.Size.Y) { MyRender11.RC.CopySubresourceRegion(srcTex, 0, null, dstTex, i, x, y); } } } return(dstTex); }
unsafe void InitDxObjects(string name, Vector2I size, Format format, byte[] bytePattern) { Texture2DDescription desc = new Texture2DDescription(); desc.Format = format; desc.ArraySize = 1; desc.Height = size.Y; desc.Width = size.X; desc.MipLevels = MyResourceUtils.GetMipmapsCount(Math.Max(size.X, size.Y)); desc.BindFlags = BindFlags.ShaderResource; desc.CpuAccessFlags = CpuAccessFlags.None; desc.OptionFlags = ResourceOptionFlags.None; desc.Usage = ResourceUsage.Immutable; desc.SampleDescription = new SampleDescription(1, 0); Vector2I strides0; strides0.X = MyResourceUtils.GetMipmapStride(desc.Width, 0); strides0.Y = MyResourceUtils.GetMipmapStride(desc.Height, 0); byte[] dataBoxData = CreateTextureDataByPattern(strides0, bytePattern); DataBox[] dataBoxes = new DataBox[desc.MipLevels]; int blocksOffset = 0; fixed(void *ptr = dataBoxData) { for (int i = 0; i < dataBoxes.Length; i++) { dataBoxes[i].SlicePitch = 0; dataBoxes[i].RowPitch = MyResourceUtils.GetMipmapStride(size.X, i) * bytePattern.Length / 16; dataBoxes[i].DataPointer = new IntPtr(((byte *)ptr) + blocksOffset * bytePattern.Length); Vector2I blocksInMipmap; blocksInMipmap.X = MyResourceUtils.GetMipmapStride(size.X, i) / 4; blocksInMipmap.Y = MyResourceUtils.GetMipmapStride(size.Y, i) / 4; blocksOffset += blocksInMipmap.X * blocksInMipmap.Y; } m_resource = new Texture2D(MyRender11.Device, desc, dataBoxes); m_resource.DebugName = name; } m_srv = new ShaderResourceView(MyRender11.Device, m_resource); m_srv.DebugName = name; }
byte[] CreateTextureDataByPattern(Vector2I strides, byte[] pattern4x4) { MyRenderProxy.Assert(strides.X % 4 == 0); MyRenderProxy.Assert(strides.Y % 4 == 0); int blocksCount = 0; for (int i = 0; i < MyResourceUtils.GetMipmapsCount(Math.Max(strides.X, strides.Y)); i++) { Vector2I blocksInMipmap; blocksInMipmap.X = MyResourceUtils.GetMipmapStride(strides.X, i); blocksInMipmap.Y = MyResourceUtils.GetMipmapStride(strides.Y, i); blocksCount += blocksInMipmap.X * blocksInMipmap.Y / 16; } byte[] data = new byte[blocksCount * pattern4x4.Length]; for (int i = 0; i < blocksCount; i++) { Array.Copy(pattern4x4, 0, data, pattern4x4.Length * i, pattern4x4.Length); } return(data); }