Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
AtitcTexLibrary.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using System.Collections.Generic;
5 using System.Runtime.InteropServices;
6 using SiliconStudio.Core.Diagnostics;
7 using SiliconStudio.TextureConverter.AtitcWrapper;
8 using SiliconStudio.TextureConverter.Requests;
9 
10 
11 namespace SiliconStudio.TextureConverter.TexLibraries
12 {
13 
14  /// <summary>
15  /// Class containing the needed native Data used by ATI Compress.
16  /// </summary>
17  internal class AtitcTextureLibraryData : ITextureLibraryData
18  {
19  /// <summary>
20  /// A pointer to the texture data
21  /// </summary>
22  public IntPtr Data;
23 
24  /// <summary>
25  /// An array of <see cref="Texture" />, one for each mip map level and / or array member
26  /// </summary>
27  public Texture[] Textures;
28 
29  /// <summary>
30  /// The compression/decompression options
31  /// </summary>
32  public CompressOptions Options;
33  }
34 
35 
36  /// <summary>
37  /// Peforms requests from <see cref="TextureTool" /> using ATI Compress.
38  /// </summary>
39  internal class AtitcTexLibrary : ITexLibrary
40  {
41  private static Logger Log = GlobalLogger.GetLogger("AtitcTexLibrary");
42 
43  /// <summary>
44  /// Initializes a new instance of the <see cref="AtitcTexLibrary"/> class.
45  /// </summary>
46  public AtitcTexLibrary() {}
47 
48  /// <summary>
49  /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. Nothing in this case.
50  /// </summary>
51  public void Dispose() {}
52 
53  public void Dispose(TexImage image)
54  {
55  AtitcTextureLibraryData libraryData = (AtitcTextureLibraryData)image.LibraryData[this];
56  if (libraryData.Data != IntPtr.Zero) Marshal.FreeHGlobal(libraryData.Data);
57  }
58 
59  public bool SupportBGRAOrder()
60  {
61  return false;
62  }
63 
64  public bool CanHandleRequest(TexImage image, IRequest request)
65  {
66  switch (request.Type)
67  {
68  case RequestType.Compressing:
69  return SupportFormat(((CompressingRequest)request).Format) && SupportFormat(image.Format);
70  case RequestType.Decompressing:
71  return SupportFormat(image.Format);
72 
73  default:
74  return false;
75  }
76  }
77 
78  public void StartLibrary(TexImage image)
79  {
80  AtitcTextureLibraryData libraryData = new AtitcTextureLibraryData();
81  image.LibraryData[this] = libraryData;
82 
83  libraryData.Textures = new Texture[image.SubImageArray.Length];
84 
85  int bpp = (int)Tools.GetBPP(image.Format);
86 
87  for (int i = 0; i < image.SubImageArray.Length; ++i)
88  {
89  libraryData.Textures[i] = new Texture(image.SubImageArray[i].Width, image.SubImageArray[i].Height, image.SubImageArray[i].RowPitch, RetrieveNativeFormat(image.Format), image.SubImageArray[i].DataSize, image.SubImageArray[i].Data);
90  }
91 
92  libraryData.Data = IntPtr.Zero;
93  }
94 
95 
96  public void EndLibrary(TexImage image)
97  {
98  if (!image.LibraryData.ContainsKey(this)) return;
99  AtitcTextureLibraryData libraryData = (AtitcTextureLibraryData)image.LibraryData[this];
100 
101  for (int i = 0; i < libraryData.Textures.Length; ++i)
102  {
103  image.SubImageArray[i].Data = libraryData.Textures[i].pData;
104  image.SubImageArray[i].DataSize = libraryData.Textures[i].dwDataSize;
105  image.SubImageArray[i].Width = libraryData.Textures[i].dwWidth;
106  image.SubImageArray[i].Height = libraryData.Textures[i].dwHeight;
107  image.SubImageArray[i].RowPitch = libraryData.Textures[i].dwPitch;
108  image.SubImageArray[i].SlicePitch = libraryData.Textures[i].dwDataSize;
109  }
110  }
111 
112  public void Execute(TexImage image, IRequest request)
113  {
114  AtitcTextureLibraryData libraryData = (AtitcTextureLibraryData) image.LibraryData[this];
115 
116  switch (request.Type)
117  {
118  case RequestType.Compressing:
119  Compress(image, libraryData, (CompressingRequest)request);
120  break;
121  case RequestType.Decompressing:
122  Decompress(image, libraryData);
123  break;
124  default:
125  Log.Error("DxtTexLib (DirectXTex) can't handle this request: " + request.Type);
126  throw new TextureToolsException("DxtTexLib (DirectXTex) can't handle this request: " + request.Type);
127  }
128  }
129 
130  /// <summary>
131  /// Compresses the specified image.
132  /// </summary>
133  /// <param name="image">The image.</param>
134  /// <param name="libraryData">The library data.</param>
135  /// <param name="request">The request.</param>
136  /// <exception cref="TexLibraryException">Compression failed</exception>
137  private void Compress(TexImage image, AtitcTextureLibraryData libraryData, CompressingRequest request)
138  {
139  Log.Info("Converting/Compressing with " + request.Format + " ...");
140 
141  int totalSize = 0;
142  Texture[] texOut = new Texture[image.SubImageArray.Length];
143  int pitch, slice;
144 
145  // Setting the new Texture array that will contained the compressed data
146  for (int i = 0; i < libraryData.Textures.Length; ++i)
147  {
148  Tools.ComputePitch(request.Format, libraryData.Textures[i].dwWidth, libraryData.Textures[i].dwHeight, out pitch, out slice);
149  texOut[i] = new Texture(libraryData.Textures[i].dwWidth, libraryData.Textures[i].dwHeight, pitch, RetrieveNativeFormat(request.Format), 0, IntPtr.Zero);
150  texOut[i].dwDataSize = Utilities.CalculateBufferSize(out texOut[i]);
151  totalSize += texOut[i].dwDataSize;
152  }
153 
154  // Allocating memory to store the compressed data
155  image.Data = Marshal.AllocHGlobal(totalSize);
156 
157  libraryData.Options = new CompressOptions(false, 0, 0, 0, false, false, 0, false, Speed.ATI_TC_Speed_Normal);
158 
159  Result res;
160  int offset = 0;
161 
162  // Compressing each sub image into the new allocated memory
163  for (int i = 0; i < libraryData.Textures.Length; ++i)
164  {
165  texOut[i].pData = new IntPtr(image.Data.ToInt64() + offset);
166  offset += texOut[i].dwDataSize;
167 
168  res = Utilities.ConvertTexture(out libraryData.Textures[i], out texOut[i], out libraryData.Options);
169  if (res != Result.ATI_TC_OK)
170  {
171  Log.Error("Compression failed: " + res);
172  throw new TextureToolsException("Compression failed: " + res);
173  }
174 
175  libraryData.Textures[i] = texOut[i];
176  }
177 
178  // Deleting old uncompressed data
179  if (image.DisposingLibrary != null) image.DisposingLibrary.Dispose(image);
180 
181  // Assigning the new compressed data to the current instance of <see cref="LibraryData" />
182  libraryData.Data = image.Data;
183 
184  // udpating various features
185  image.DataSize = totalSize;
186  image.RowPitch = libraryData.Textures[0].dwPitch;
187  image.Format = request.Format;
188  image.DisposingLibrary = this;
189  }
190 
191 
192  /// <summary>
193  /// Decompresses the specified image.
194  /// </summary>
195  /// <param name="image">The image.</param>
196  /// <param name="libraryData">The library data.</param>
197  /// <exception cref="TexLibraryException">Decompression failed</exception>
198  private void Decompress(TexImage image, AtitcTextureLibraryData libraryData)
199  {
200  Log.Info("Decompressing texture ...");
201 
202  int totalSize = 0;
203  Texture[] texOut = new Texture[image.SubImageArray.Length];
204  int rowPitch, slicePitch;
205 
206  // Setting the new Texture array that will contained the uncompressed data
207  for (int i = 0; i < libraryData.Textures.Length; ++i)
208  {
209  Tools.ComputePitch(SiliconStudio.Paradox.Graphics.PixelFormat.R8G8B8A8_UNorm, libraryData.Textures[i].dwWidth, libraryData.Textures[i].dwHeight, out rowPitch, out slicePitch);
210  texOut[i] = new Texture(libraryData.Textures[i].dwWidth, libraryData.Textures[i].dwHeight, libraryData.Textures[i].dwWidth * 4, Format.ATI_TC_FORMAT_ARGB_8888, 0, IntPtr.Zero);
211  texOut[i].dwDataSize = Utilities.CalculateBufferSize(out texOut[i]);
212  totalSize += texOut[i].dwDataSize;
213  }
214 
215  // Allocating memory to store the uncompressed data
216  image.Data = Marshal.AllocHGlobal(totalSize);
217 
218  libraryData.Options = new CompressOptions(false, 0, 0, 0, false, false, 0, false, Speed.ATI_TC_Speed_Normal);
219 
220  Result res;
221  long offset = 0;
222 
223  // Decompressing each sub image into the new allocated memory
224  for (int i = 0; i < libraryData.Textures.Length; ++i)
225  {
226  texOut[i].pData = new IntPtr(image.Data.ToInt64() + offset);
227  offset += texOut[i].dwDataSize;
228 
229  res = Utilities.ConvertTexture(out libraryData.Textures[i], out texOut[i], out libraryData.Options);
230  if (res != Result.ATI_TC_OK)
231  {
232  Log.Error("Decompression failed: " + res);
233  throw new TextureToolsException("Decompression failed: " + res);
234  }
235 
236  libraryData.Textures[i] = texOut[i];
237  }
238 
239  // Deleting old compressed data
240  if (image.DisposingLibrary != null) image.DisposingLibrary.Dispose(image);
241 
242  // udpating various features
243  libraryData.Data = image.Data;
244  image.DataSize = totalSize;
245  image.RowPitch = libraryData.Textures[0].dwPitch;
246  image.Format = SiliconStudio.Paradox.Graphics.PixelFormat.R8G8B8A8_UNorm;
247  image.DisposingLibrary = this;
248  }
249 
250 
251  /// <summary>
252  /// Determines whether this requested format is supported.
253  /// </summary>
254  /// <param name="format">The format.</param>
255  /// <returns>
256  /// <c>true</c> if the formats is supported; otherwise, <c>false</c>.
257  /// </returns>
258  public bool SupportFormat(SiliconStudio.Paradox.Graphics.PixelFormat format)
259  {
260  switch (format)
261  {
262  case SiliconStudio.Paradox.Graphics.PixelFormat.R8G8B8A8_UNorm:
263  case SiliconStudio.Paradox.Graphics.PixelFormat.B8G8R8A8_UNorm:
264  case SiliconStudio.Paradox.Graphics.PixelFormat.ATC_RGB:
265  case SiliconStudio.Paradox.Graphics.PixelFormat.ATC_RGBA_Explicit:
266  case SiliconStudio.Paradox.Graphics.PixelFormat.ATC_RGBA_Interpolated:
267  return true;
268  default:
269  return false;
270  }
271  }
272 
273  /// <summary>
274  /// Retrieves the native format from <see cref="SiliconStudio.Paradox.Graphics.PixelFormat"/>.
275  /// </summary>
276  /// <param name="format">The format.</param>
277  /// <returns>the corresponding <see cref="Format"/> format</returns>
278  private Format RetrieveNativeFormat(SiliconStudio.Paradox.Graphics.PixelFormat format)
279  {
280  switch (format)
281  {
282  case SiliconStudio.Paradox.Graphics.PixelFormat.R8G8B8A8_UNorm:
283  case SiliconStudio.Paradox.Graphics.PixelFormat.B8G8R8A8_UNorm:
284  return Format.ATI_TC_FORMAT_ARGB_8888;
285  case SiliconStudio.Paradox.Graphics.PixelFormat.ATC_RGB:
286  return Format.ATI_TC_FORMAT_ATC_RGB;
287  case SiliconStudio.Paradox.Graphics.PixelFormat.ATC_RGBA_Explicit:
288  return Format.ATI_TC_FORMAT_ATC_RGBA_Explicit;
289  case SiliconStudio.Paradox.Graphics.PixelFormat.ATC_RGBA_Interpolated:
290  return Format.ATI_TC_FORMAT_ATC_RGBA_Interpolated;
291  default:
292  throw new TextureToolsException("UnHandled compression format by ATI texture.");
293  }
294  }
295 
296 
297  }
298 }
Base implementation for ILogger.
Definition: Logger.cs:10
switch(inFormat)
Same as Deferred mode, except sprites are sorted by texture prior to drawing. This can improve perfor...
HRESULT Decompress(_In_ const Image &cImage, _In_ DXGI_FORMAT format, _Out_ ScratchImage &image)
_In_ size_t _In_ size_t _In_ DXGI_FORMAT format
Definition: DirectXTexP.h:175
Output message to log right away.
HRESULT Compress(_In_ const Image &srcImage, _In_ DXGI_FORMAT format, _In_ DWORD compress, _In_ float alphaRef, _Out_ ScratchImage &cImage)