blob: cf88d8cc875fce0f420787e24998345f3b7782af [file] [log] [blame]
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +00001#include "precompiled.h"
2//
3// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style license that can be
5// found in the LICENSE file.
6//
7
8// formatutils9.cpp: Queries for GL image formats and their translations to D3D9
9// formats.
10
11#include "libGLESv2/renderer/formatutils9.h"
12#include "libGLESv2/renderer/Renderer9.h"
13#include "libGLESv2/renderer/generatemip.h"
14#include "libGLESv2/renderer/loadimage.h"
15
16namespace rx
17{
18
19// Each GL internal format corresponds to one D3D format and data loading function.
20// Due to not all formats being available all the time, some of the function/format types are wrapped
21// in templates that perform format support queries on a Renderer9 object which is supplied
22// when requesting the function or format.
23
24typedef bool ((Renderer9::*Renderer9FormatCheckFunction)(void) const);
25typedef LoadImageFunction (*RendererCheckLoadFunction)(const Renderer9 *renderer);
26
27template <Renderer9FormatCheckFunction pred, LoadImageFunction prefered, LoadImageFunction fallback>
28LoadImageFunction RendererCheckLoad(const Renderer9 *renderer)
29{
30 return ((renderer->*pred)()) ? prefered : fallback;
31}
32
33template <LoadImageFunction loadFunc>
34LoadImageFunction SimpleLoad(const Renderer9 *renderer)
35{
36 return loadFunc;
37}
38
39LoadImageFunction UnreachableLoad(const Renderer9 *renderer)
40{
41 UNREACHABLE();
42 return NULL;
43}
44
45typedef bool (*FallbackPredicateFunction)(void);
46
47template <FallbackPredicateFunction pred, LoadImageFunction prefered, LoadImageFunction fallback>
48LoadImageFunction FallbackLoadFunction(const Renderer9 *renderer)
49{
50 return pred() ? prefered : fallback;
51}
52
53typedef D3DFORMAT (*FormatQueryFunction)(const rx::Renderer9 *renderer);
54
55template <Renderer9FormatCheckFunction pred, D3DFORMAT prefered, D3DFORMAT fallback>
56D3DFORMAT CheckFormatSupport(const rx::Renderer9 *renderer)
57{
58 return (renderer->*pred)() ? prefered : fallback;
59}
60
61template <D3DFORMAT format>
62D3DFORMAT D3D9Format(const rx::Renderer9 *renderer)
63{
64 return format;
65}
66
67struct D3D9FormatInfo
68{
69 FormatQueryFunction mTexFormat;
70 FormatQueryFunction mRenderFormat;
71 RendererCheckLoadFunction mLoadFunction;
72
73 D3D9FormatInfo()
74 : mTexFormat(NULL), mRenderFormat(NULL), mLoadFunction(NULL)
75 { }
76
77 D3D9FormatInfo(FormatQueryFunction textureFormat, FormatQueryFunction renderFormat, RendererCheckLoadFunction loadFunc)
78 : mTexFormat(textureFormat), mRenderFormat(renderFormat), mLoadFunction(loadFunc)
79 { }
80};
81
82const D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I','N','T','Z')));
83const D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N','U','L','L')));
84
85typedef std::pair<GLint, D3D9FormatInfo> D3D9FormatPair;
86typedef std::map<GLint, D3D9FormatInfo> D3D9FormatMap;
87
Geoff Lang18591b72013-06-07 12:00:15 -040088static D3D9FormatMap BuildD3D9FormatMap()
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +000089{
90 D3D9FormatMap map;
91
92 // | Internal format | Texture format | Render format | Load function |
93 map.insert(D3D9FormatPair(GL_NONE, D3D9FormatInfo(D3D9Format<D3DFMT_NULL>, D3D9Format<D3DFMT_NULL>, UnreachableLoad )));
94
95 map.insert(D3D9FormatPair(GL_DEPTH_COMPONENT16, D3D9FormatInfo(D3D9Format<D3DFMT_INTZ>, D3D9Format<D3DFMT_D24S8>, UnreachableLoad )));
96 map.insert(D3D9FormatPair(GL_DEPTH_COMPONENT32_OES, D3D9FormatInfo(D3D9Format<D3DFMT_INTZ>, D3D9Format<D3DFMT_D32>, UnreachableLoad )));
97 map.insert(D3D9FormatPair(GL_DEPTH24_STENCIL8_OES, D3D9FormatInfo(D3D9Format<D3DFMT_INTZ>, D3D9Format<D3DFMT_D24S8>, UnreachableLoad )));
98 map.insert(D3D9FormatPair(GL_STENCIL_INDEX8, D3D9FormatInfo(D3D9Format<D3DFMT_UNKNOWN>, D3D9Format<D3DFMT_D24S8>, UnreachableLoad ))); // TODO: What's the texture format?
99
shannonwoods@chromium.org8d46e912013-05-30 00:14:32 +0000100 map.insert(D3D9FormatPair(GL_RGBA32F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A32B32G32R32F>, D3D9Format<D3DFMT_A32B32G32R32F>, SimpleLoad<loadToNative<GLfloat, 4> > )));
shannonwoods@chromium.org27125342013-05-30 00:17:42 +0000101 map.insert(D3D9FormatPair(GL_RGB32F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A32B32G32R32F>, D3D9Format<D3DFMT_A32B32G32R32F>, SimpleLoad<loadToNative3To4<GLfloat, gl::Float32One> >)));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000102 map.insert(D3D9FormatPair(GL_ALPHA32F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A32B32G32R32F>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadAlphaFloatDataToRGBA> )));
103 map.insert(D3D9FormatPair(GL_LUMINANCE32F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A32B32G32R32F>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadLuminanceFloatDataToRGBA> )));
104 map.insert(D3D9FormatPair(GL_LUMINANCE_ALPHA32F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A32B32G32R32F>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadLuminanceAlphaFloatDataToRGBA> )));
105
shannonwoods@chromium.org8d46e912013-05-30 00:14:32 +0000106 map.insert(D3D9FormatPair(GL_RGBA16F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A16B16G16R16F>, D3D9Format<D3DFMT_A16B16G16R16F>, SimpleLoad<loadToNative<GLhalf, 4>> )));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000107 map.insert(D3D9FormatPair(GL_RGB16F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A16B16G16R16F>, D3D9Format<D3DFMT_A16B16G16R16F>, SimpleLoad<loadRGBHalfFloatDataToRGBA> )));
108 map.insert(D3D9FormatPair(GL_ALPHA16F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A16B16G16R16F>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadAlphaHalfFloatDataToRGBA> )));
109 map.insert(D3D9FormatPair(GL_LUMINANCE16F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A16B16G16R16F>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadLuminanceHalfFloatDataToRGBA> )));
110 map.insert(D3D9FormatPair(GL_LUMINANCE_ALPHA16F_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A16B16G16R16F>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadLuminanceAlphaHalfFloatDataToRGBA>)));
111
112 map.insert(D3D9FormatPair(GL_ALPHA8_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, FallbackLoadFunction<gl::supportsSSE2, loadAlphaDataToBGRASSE2, loadAlphaDataToBGRA>)));
113
114 map.insert(D3D9FormatPair(GL_RGB8_OES, D3D9FormatInfo(D3D9Format<D3DFMT_X8R8G8B8>, D3D9Format<D3DFMT_X8R8G8B8>, SimpleLoad<loadRGBUByteDataToBGRX> )));
115 map.insert(D3D9FormatPair(GL_RGB565, D3D9FormatInfo(D3D9Format<D3DFMT_X8R8G8B8>, D3D9Format<D3DFMT_R5G6B5>, SimpleLoad<loadRGB565DataToBGRA> )));
116 map.insert(D3D9FormatPair(GL_RGBA8_OES, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, FallbackLoadFunction<gl::supportsSSE2, loadRGBAUByteDataToBGRASSE2, loadRGBAUByteDataToBGRA>)));
117 map.insert(D3D9FormatPair(GL_RGBA4, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, SimpleLoad<loadRGBA4444DataToBGRA> )));
118 map.insert(D3D9FormatPair(GL_RGB5_A1, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, SimpleLoad<loadRGBA5551DataToBGRA> )));
119
shannonwoods@chromium.org8d46e912013-05-30 00:14:32 +0000120 map.insert(D3D9FormatPair(GL_BGRA8_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, SimpleLoad<loadToNative<GLubyte, 4> > )));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000121 map.insert(D3D9FormatPair(GL_BGRA4_ANGLEX, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, SimpleLoad<loadRGBA4444DataToRGBA> )));
122 map.insert(D3D9FormatPair(GL_BGR5_A1_ANGLEX, D3D9FormatInfo(D3D9Format<D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_A8R8G8B8>, SimpleLoad<loadRGBA5551DataToRGBA> )));
123
124 map.insert(D3D9FormatPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_DXT1>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadCompressedBlockDataToNative<4, 4, 8> >)));
125 map.insert(D3D9FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, D3D9FormatInfo(D3D9Format<D3DFMT_DXT1>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadCompressedBlockDataToNative<4, 4, 8> >)));
126 map.insert(D3D9FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, D3D9FormatInfo(D3D9Format<D3DFMT_DXT3>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadCompressedBlockDataToNative<4, 4, 16> >)));
127 map.insert(D3D9FormatPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, D3D9FormatInfo(D3D9Format<D3DFMT_DXT5>, D3D9Format<D3DFMT_UNKNOWN>, SimpleLoad<loadCompressedBlockDataToNative<4, 4, 16> >)));
128
129 // These formats require checking if the renderer supports D3DFMT_L8 or D3DFMT_A8L8 and
130 // then changing the format and loading function appropriately.
shannonwoods@chromium.org8d46e912013-05-30 00:14:32 +0000131 map.insert(D3D9FormatPair(GL_LUMINANCE8_EXT, D3D9FormatInfo(CheckFormatSupport<&Renderer9::getLuminanceTextureSupport, D3DFMT_L8, D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_UNKNOWN>, RendererCheckLoad<&Renderer9::getLuminanceTextureSupport, loadToNative<GLubyte, 1>, loadLuminanceDataToBGRA>)));
132 map.insert(D3D9FormatPair(GL_LUMINANCE8_ALPHA8_EXT, D3D9FormatInfo(CheckFormatSupport<&Renderer9::getLuminanceAlphaTextureSupport, D3DFMT_A8L8, D3DFMT_A8R8G8B8>, D3D9Format<D3DFMT_UNKNOWN>, RendererCheckLoad<&Renderer9::getLuminanceTextureSupport, loadToNative<GLubyte, 2>, loadLuminanceAlphaDataToBGRA>)));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000133
134 return map;
135}
136
Geoff Lang18591b72013-06-07 12:00:15 -0400137static bool GetD3D9FormatInfo(GLint internalFormat, D3D9FormatInfo *outFormatInfo)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000138{
Geoff Lang18591b72013-06-07 12:00:15 -0400139 static const D3D9FormatMap formatMap = BuildD3D9FormatMap();
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000140 D3D9FormatMap::const_iterator iter = formatMap.find(internalFormat);
141 if (iter != formatMap.end())
142 {
143 if (outFormatInfo)
144 {
145 *outFormatInfo = iter->second;
146 }
147 return true;
148 }
149 else
150 {
151 return false;
152 }
153}
154
shannonwoods@chromium.orgba9d7502013-05-30 00:14:58 +0000155// A map to determine the pixel size and mip generation function of a given D3D format
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000156struct D3DFormatInfo
157{
158 GLuint mPixelBits;
159 GLuint mBlockWidth;
160 GLuint mBlockHeight;
161 GLint mInternalFormat;
162
shannonwoods@chromium.orgba9d7502013-05-30 00:14:58 +0000163 MipGenerationFunction mMipGenerationFunction;
164
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000165 D3DFormatInfo()
shannonwoods@chromium.orgba9d7502013-05-30 00:14:58 +0000166 : mPixelBits(0), mBlockWidth(0), mBlockHeight(0), mInternalFormat(GL_NONE), mMipGenerationFunction(NULL)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000167 { }
168
shannonwoods@chromium.orgba9d7502013-05-30 00:14:58 +0000169 D3DFormatInfo(GLuint pixelBits, GLuint blockWidth, GLuint blockHeight, GLint internalFormat,
170 MipGenerationFunction mipFunc)
171 : mPixelBits(pixelBits), mBlockWidth(blockWidth), mBlockHeight(blockHeight), mInternalFormat(internalFormat),
172 mMipGenerationFunction(mipFunc)
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000173 { }
174};
175
176typedef std::pair<D3DFORMAT, D3DFormatInfo> D3D9FormatInfoPair;
177typedef std::map<D3DFORMAT, D3DFormatInfo> D3D9FormatInfoMap;
178
Geoff Lang18591b72013-06-07 12:00:15 -0400179static D3D9FormatInfoMap BuildD3D9FormatInfoMap()
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000180{
181 D3D9FormatInfoMap map;
182
shannonwoods@chromium.orgba9d7502013-05-30 00:14:58 +0000183 // | D3DFORMAT | | S |W |H | Internal format | Mip generation function |
184 map.insert(D3D9FormatInfoPair(D3DFMT_NULL, D3DFormatInfo( 0, 0, 0, GL_NONE, NULL )));
185 map.insert(D3D9FormatInfoPair(D3DFMT_UNKNOWN, D3DFormatInfo( 0, 0, 0, GL_NONE, NULL )));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000186
shannonwoods@chromium.orgba9d7502013-05-30 00:14:58 +0000187 map.insert(D3D9FormatInfoPair(D3DFMT_L8, D3DFormatInfo( 8, 1, 1, GL_LUMINANCE8_EXT, GenerateMip<L8> )));
188 map.insert(D3D9FormatInfoPair(D3DFMT_A8, D3DFormatInfo( 8, 1, 1, GL_ALPHA8_EXT, GenerateMip<A8> )));
189 map.insert(D3D9FormatInfoPair(D3DFMT_A8L8, D3DFormatInfo( 16, 1, 1, GL_LUMINANCE8_ALPHA8_EXT, GenerateMip<A8L8> )));
190 map.insert(D3D9FormatInfoPair(D3DFMT_A4R4G4B4, D3DFormatInfo( 16, 1, 1, GL_RGBA4, NULL )));
191 map.insert(D3D9FormatInfoPair(D3DFMT_A1R5G5B5, D3DFormatInfo( 16, 1, 1, GL_RGB5_A1, NULL )));
192 map.insert(D3D9FormatInfoPair(D3DFMT_R5G6B5, D3DFormatInfo( 16, 1, 1, GL_RGB565, NULL )));
193 map.insert(D3D9FormatInfoPair(D3DFMT_X8R8G8B8, D3DFormatInfo( 32, 1, 1, GL_RGB8_OES, GenerateMip<A8R8G8B8> )));
194 map.insert(D3D9FormatInfoPair(D3DFMT_A8R8G8B8, D3DFormatInfo( 32, 1, 1, GL_RGBA8_OES, GenerateMip<A8R8G8B8> )));
195 map.insert(D3D9FormatInfoPair(D3DFMT_A16B16G16R16F, D3DFormatInfo( 64, 1, 1, GL_RGBA16F_EXT, GenerateMip<A16B16G16R16F>)));
196 map.insert(D3D9FormatInfoPair(D3DFMT_A32B32G32R32F, D3DFormatInfo(128, 1, 1, GL_RGBA32F_EXT, GenerateMip<A32B32G32R32F>)));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000197
shannonwoods@chromium.orgba9d7502013-05-30 00:14:58 +0000198 map.insert(D3D9FormatInfoPair(D3DFMT_D16, D3DFormatInfo( 16, 1, 1, GL_DEPTH_COMPONENT16, NULL )));
199 map.insert(D3D9FormatInfoPair(D3DFMT_D24S8, D3DFormatInfo( 32, 1, 1, GL_DEPTH24_STENCIL8_OES, NULL )));
200 map.insert(D3D9FormatInfoPair(D3DFMT_D24X8, D3DFormatInfo( 32, 1, 1, GL_DEPTH_COMPONENT16, NULL )));
201 map.insert(D3D9FormatInfoPair(D3DFMT_D32, D3DFormatInfo( 32, 1, 1, GL_DEPTH_COMPONENT32_OES, NULL )));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000202
shannonwoods@chromium.orgba9d7502013-05-30 00:14:58 +0000203 map.insert(D3D9FormatInfoPair(D3DFMT_INTZ, D3DFormatInfo( 32, 1, 1, GL_DEPTH24_STENCIL8_OES, NULL )));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000204
shannonwoods@chromium.orgba9d7502013-05-30 00:14:58 +0000205 map.insert(D3D9FormatInfoPair(D3DFMT_DXT1, D3DFormatInfo( 64, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, NULL )));
206 map.insert(D3D9FormatInfoPair(D3DFMT_DXT3, D3DFormatInfo(128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, NULL )));
207 map.insert(D3D9FormatInfoPair(D3DFMT_DXT5, D3DFormatInfo(128, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, NULL )));
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000208
209 return map;
210}
211
Geoff Lang61e49a52013-05-29 10:22:58 -0400212static const D3D9FormatInfoMap &GetD3D9FormatInfoMap()
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000213{
Geoff Lang18591b72013-06-07 12:00:15 -0400214 static const D3D9FormatInfoMap infoMap = BuildD3D9FormatInfoMap();
Geoff Lang61e49a52013-05-29 10:22:58 -0400215 return infoMap;
216}
217
Geoff Lang18591b72013-06-07 12:00:15 -0400218static bool GetD3D9FormatInfo(D3DFORMAT format, D3DFormatInfo *outFormatInfo)
Geoff Lang61e49a52013-05-29 10:22:58 -0400219{
220 const D3D9FormatInfoMap &infoMap = GetD3D9FormatInfoMap();
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000221 D3D9FormatInfoMap::const_iterator iter = infoMap.find(format);
222 if (iter != infoMap.end())
223 {
224 if (outFormatInfo)
225 {
226 *outFormatInfo = iter->second;
227 }
228 return true;
229 }
230 else
231 {
232 return false;
233 }
234}
Geoff Lang61e49a52013-05-29 10:22:58 -0400235static d3d9::D3DFormatSet BuildAllD3DFormatSet()
236{
237 d3d9::D3DFormatSet set;
238
239 const D3D9FormatInfoMap &infoMap = GetD3D9FormatInfoMap();
240 for (D3D9FormatInfoMap::const_iterator i = infoMap.begin(); i != infoMap.end(); ++i)
241 {
242 set.insert(i->first);
243 }
244
245 return set;
246}
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000247
248namespace d3d9
249{
250
251MipGenerationFunction GetMipGenerationFunction(D3DFORMAT format)
252{
shannonwoods@chromium.orgba9d7502013-05-30 00:14:58 +0000253 D3DFormatInfo d3dFormatInfo;
Geoff Lang18591b72013-06-07 12:00:15 -0400254 if (GetD3D9FormatInfo(format, &d3dFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000255 {
shannonwoods@chromium.orgba9d7502013-05-30 00:14:58 +0000256 return d3dFormatInfo.mMipGenerationFunction;
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000257 }
258 else
259 {
260 UNREACHABLE();
261 return NULL;
262 }
263}
264
265LoadImageFunction GetImageLoadFunction(GLint internalFormat, const Renderer9 *renderer)
266{
267 if (!renderer)
268 {
269 return NULL;
270 }
271
272 ASSERT(renderer->getCurrentClientVersion() == 2);
273
274 D3D9FormatInfo d3d9FormatInfo;
Geoff Lang18591b72013-06-07 12:00:15 -0400275 if (GetD3D9FormatInfo(internalFormat, &d3d9FormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000276 {
277 return d3d9FormatInfo.mLoadFunction(renderer);
278 }
279 else
280 {
281 UNREACHABLE();
282 return NULL;
283 }
284}
285
286GLuint GetFormatPixelBytes(D3DFORMAT format)
287{
288 D3DFormatInfo d3dFormatInfo;
Geoff Lang18591b72013-06-07 12:00:15 -0400289 if (GetD3D9FormatInfo(format, &d3dFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000290 {
291 return d3dFormatInfo.mPixelBits / 8;
292 }
293 else
294 {
295 UNREACHABLE();
296 return 0;
297 }
298}
299
300GLuint GetBlockWidth(D3DFORMAT format)
301{
302 D3DFormatInfo d3dFormatInfo;
Geoff Lang18591b72013-06-07 12:00:15 -0400303 if (GetD3D9FormatInfo(format, &d3dFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000304 {
305 return d3dFormatInfo.mBlockWidth;
306 }
307 else
308 {
309 UNREACHABLE();
310 return 0;
311 }
312}
313
314GLuint GetBlockHeight(D3DFORMAT format)
315{
316 D3DFormatInfo d3dFormatInfo;
Geoff Lang18591b72013-06-07 12:00:15 -0400317 if (GetD3D9FormatInfo(format, &d3dFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000318 {
319 return d3dFormatInfo.mBlockHeight;
320 }
321 else
322 {
323 UNREACHABLE();
324 return 0;
325 }
326}
327
328GLuint GetBlockSize(D3DFORMAT format, GLuint width, GLuint height)
329{
330 D3DFormatInfo d3dFormatInfo;
Geoff Lang18591b72013-06-07 12:00:15 -0400331 if (GetD3D9FormatInfo(format, &d3dFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000332 {
333 GLuint numBlocksWide = (width + d3dFormatInfo.mBlockWidth - 1) / d3dFormatInfo.mBlockWidth;
334 GLuint numBlocksHight = (height + d3dFormatInfo.mBlockHeight - 1) / d3dFormatInfo.mBlockHeight;
335
336 return (d3dFormatInfo.mPixelBits * numBlocksWide * numBlocksHight) / 8;
337 }
338 else
339 {
340 UNREACHABLE();
341 return 0;
342 }
343}
344
345void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset)
346{
347 D3DFormatInfo d3dFormatInfo;
Geoff Lang18591b72013-06-07 12:00:15 -0400348 if (GetD3D9FormatInfo(format, &d3dFormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000349 {
350 int upsampleCount = 0;
351
352 GLsizei blockWidth = d3dFormatInfo.mBlockWidth;
353 GLsizei blockHeight = d3dFormatInfo.mBlockHeight;
354
355 // Don't expand the size of full textures that are at least (blockWidth x blockHeight) already.
356 if (isImage || *requestWidth < blockWidth || *requestHeight < blockHeight)
357 {
358 while (*requestWidth % blockWidth != 0 || *requestHeight % blockHeight != 0)
359 {
360 *requestWidth <<= 1;
361 *requestHeight <<= 1;
362 upsampleCount++;
363 }
364 }
365 *levelOffset = upsampleCount;
366 }
367}
368
Geoff Lang61e49a52013-05-29 10:22:58 -0400369const D3DFormatSet &GetAllUsedD3DFormats()
370{
371 static const D3DFormatSet formatSet = BuildAllD3DFormatSet();
372 return formatSet;
373}
374
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000375}
376
377namespace gl_d3d9
378{
379
380D3DFORMAT GetTexureFormat(GLint internalFormat, const Renderer9 *renderer)
381{
382 if (!renderer)
383 {
384 UNREACHABLE();
385 return D3DFMT_UNKNOWN;
386 }
387
388 ASSERT(renderer->getCurrentClientVersion() == 2);
389
390 D3D9FormatInfo d3d9FormatInfo;
Geoff Lang18591b72013-06-07 12:00:15 -0400391 if (GetD3D9FormatInfo(internalFormat, &d3d9FormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000392 {
393 return d3d9FormatInfo.mTexFormat(renderer);
394 }
395 else
396 {
397 UNREACHABLE();
398 return D3DFMT_UNKNOWN;
399 }
400}
401
402D3DFORMAT GetRenderFormat(GLint internalFormat, const Renderer9 *renderer)
403{
404 if (!renderer)
405 {
406 UNREACHABLE();
407 return D3DFMT_UNKNOWN;
408 }
409
410 ASSERT(renderer->getCurrentClientVersion() == 2);
411
412 D3D9FormatInfo d3d9FormatInfo;
Geoff Lang18591b72013-06-07 12:00:15 -0400413 if (GetD3D9FormatInfo(internalFormat, &d3d9FormatInfo))
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000414 {
415 return d3d9FormatInfo.mRenderFormat(renderer);
416 }
417 else
418 {
419 UNREACHABLE();
420 return D3DFMT_UNKNOWN;
421 }
422}
423
424D3DMULTISAMPLE_TYPE GetMultisampleType(GLsizei samples)
425{
426 return (samples > 1) ? static_cast<D3DMULTISAMPLE_TYPE>(samples) : D3DMULTISAMPLE_NONE;
427}
428
429}
430
431namespace d3d9_gl
432{
433
434GLint GetInternalFormat(D3DFORMAT format)
435{
Geoff Lang18591b72013-06-07 12:00:15 -0400436 static const D3D9FormatInfoMap infoMap = BuildD3D9FormatInfoMap();
shannonwoods@chromium.orgb8490f32013-05-30 00:08:00 +0000437 D3D9FormatInfoMap::const_iterator iter = infoMap.find(format);
438 if (iter != infoMap.end())
439 {
440 return iter->second.mInternalFormat;
441 }
442 else
443 {
444 UNREACHABLE();
445 return GL_NONE;
446 }
447}
448
449GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type)
450{
451 return (type != D3DMULTISAMPLE_NONMASKABLE) ? type : 0;
452}
453
454bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format, GLuint clientVersion)
455{
456 GLint internalFormat = d3d9_gl::GetInternalFormat(d3dformat);
457 GLenum convertedFormat = gl::GetFormat(internalFormat, clientVersion);
458 return convertedFormat == format;
459}
460
461}
462
463}