blob: b1867fba9f0ac338fea4d6d7e63e9e5f5aabd8f6 [file] [log] [blame]
daniel@transgaming.comfeae9b32012-11-28 19:34:56 +00001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.comfeae9b32012-11-28 19:34:56 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// renderer11_utils.cpp: Conversion functions and other utility routines
8// specific to the D3D11 renderer.
9
Brandon Jonesc7a41042014-06-23 12:03:25 -070010#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
11#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
Jamie Madill9f0b42a2014-09-12 10:25:27 -040012#include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
Jamie Madill3f2e61d2014-09-05 10:38:05 -040013#include "libGLESv2/ProgramBinary.h"
Jamie Madill9f0b42a2014-09-12 10:25:27 -040014#include "libGLESv2/Framebuffer.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040015
daniel@transgaming.comfeae9b32012-11-28 19:34:56 +000016#include "common/debug.h"
17
Geoff Lang0b7eef72014-06-12 14:10:47 -040018#include <algorithm>
19
shannonwoods@chromium.orged0adcf2013-05-30 00:08:20 +000020namespace rx
21{
22
daniel@transgaming.com6b147712012-11-28 19:37:24 +000023namespace gl_d3d11
24{
25
daniel@transgaming.com90c634a2013-01-11 04:10:01 +000026D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha)
daniel@transgaming.com6b147712012-11-28 19:37:24 +000027{
28 D3D11_BLEND d3dBlend = D3D11_BLEND_ZERO;
29
30 switch (glBlend)
31 {
32 case GL_ZERO: d3dBlend = D3D11_BLEND_ZERO; break;
33 case GL_ONE: d3dBlend = D3D11_BLEND_ONE; break;
daniel@transgaming.com90c634a2013-01-11 04:10:01 +000034 case GL_SRC_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_SRC_ALPHA : D3D11_BLEND_SRC_COLOR); break;
35 case GL_ONE_MINUS_SRC_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_INV_SRC_ALPHA : D3D11_BLEND_INV_SRC_COLOR); break;
36 case GL_DST_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_DEST_ALPHA : D3D11_BLEND_DEST_COLOR); break;
37 case GL_ONE_MINUS_DST_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_INV_DEST_ALPHA : D3D11_BLEND_INV_DEST_COLOR); break;
daniel@transgaming.com6b147712012-11-28 19:37:24 +000038 case GL_SRC_ALPHA: d3dBlend = D3D11_BLEND_SRC_ALPHA; break;
39 case GL_ONE_MINUS_SRC_ALPHA: d3dBlend = D3D11_BLEND_INV_SRC_ALPHA; break;
40 case GL_DST_ALPHA: d3dBlend = D3D11_BLEND_DEST_ALPHA; break;
41 case GL_ONE_MINUS_DST_ALPHA: d3dBlend = D3D11_BLEND_INV_DEST_ALPHA; break;
42 case GL_CONSTANT_COLOR: d3dBlend = D3D11_BLEND_BLEND_FACTOR; break;
43 case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR; break;
44 case GL_CONSTANT_ALPHA: d3dBlend = D3D11_BLEND_BLEND_FACTOR; break;
45 case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR; break;
46 case GL_SRC_ALPHA_SATURATE: d3dBlend = D3D11_BLEND_SRC_ALPHA_SAT; break;
47 default: UNREACHABLE();
48 }
49
50 return d3dBlend;
51}
52
53D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp)
54{
55 D3D11_BLEND_OP d3dBlendOp = D3D11_BLEND_OP_ADD;
56
57 switch (glBlendOp)
58 {
59 case GL_FUNC_ADD: d3dBlendOp = D3D11_BLEND_OP_ADD; break;
60 case GL_FUNC_SUBTRACT: d3dBlendOp = D3D11_BLEND_OP_SUBTRACT; break;
61 case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3D11_BLEND_OP_REV_SUBTRACT; break;
shannon.woods%transgaming.com@gtempaccount.com00b6a0e2013-04-13 03:38:00 +000062 case GL_MIN: d3dBlendOp = D3D11_BLEND_OP_MIN; break;
63 case GL_MAX: d3dBlendOp = D3D11_BLEND_OP_MAX; break;
daniel@transgaming.com6b147712012-11-28 19:37:24 +000064 default: UNREACHABLE();
65 }
66
67 return d3dBlendOp;
68}
69
70UINT8 ConvertColorMask(bool red, bool green, bool blue, bool alpha)
71{
72 UINT8 mask = 0;
73 if (red)
74 {
75 mask |= D3D11_COLOR_WRITE_ENABLE_RED;
76 }
77 if (green)
78 {
79 mask |= D3D11_COLOR_WRITE_ENABLE_GREEN;
80 }
81 if (blue)
82 {
83 mask |= D3D11_COLOR_WRITE_ENABLE_BLUE;
84 }
85 if (alpha)
86 {
87 mask |= D3D11_COLOR_WRITE_ENABLE_ALPHA;
88 }
89 return mask;
90}
91
daniel@transgaming.comfa34b342012-11-28 19:38:01 +000092D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, GLenum cullMode)
93{
94 D3D11_CULL_MODE cull = D3D11_CULL_NONE;
95
96 if (cullEnabled)
97 {
98 switch (cullMode)
99 {
100 case GL_FRONT: cull = D3D11_CULL_FRONT; break;
101 case GL_BACK: cull = D3D11_CULL_BACK; break;
102 case GL_FRONT_AND_BACK: cull = D3D11_CULL_NONE; break;
103 default: UNREACHABLE();
104 }
105 }
106 else
107 {
108 cull = D3D11_CULL_NONE;
109 }
110
111 return cull;
112}
113
daniel@transgaming.comc820c122012-11-28 19:38:30 +0000114D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison)
115{
116 D3D11_COMPARISON_FUNC d3dComp = D3D11_COMPARISON_NEVER;
117 switch (comparison)
118 {
119 case GL_NEVER: d3dComp = D3D11_COMPARISON_NEVER; break;
120 case GL_ALWAYS: d3dComp = D3D11_COMPARISON_ALWAYS; break;
121 case GL_LESS: d3dComp = D3D11_COMPARISON_LESS; break;
122 case GL_LEQUAL: d3dComp = D3D11_COMPARISON_LESS_EQUAL; break;
123 case GL_EQUAL: d3dComp = D3D11_COMPARISON_EQUAL; break;
124 case GL_GREATER: d3dComp = D3D11_COMPARISON_GREATER; break;
125 case GL_GEQUAL: d3dComp = D3D11_COMPARISON_GREATER_EQUAL; break;
126 case GL_NOTEQUAL: d3dComp = D3D11_COMPARISON_NOT_EQUAL; break;
127 default: UNREACHABLE();
128 }
129
130 return d3dComp;
131}
132
133D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled)
134{
135 return depthWriteEnabled ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
136}
137
138UINT8 ConvertStencilMask(GLuint stencilmask)
139{
140 return static_cast<UINT8>(stencilmask);
141}
142
143D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp)
144{
145 D3D11_STENCIL_OP d3dStencilOp = D3D11_STENCIL_OP_KEEP;
146
147 switch (stencilOp)
148 {
149 case GL_ZERO: d3dStencilOp = D3D11_STENCIL_OP_ZERO; break;
150 case GL_KEEP: d3dStencilOp = D3D11_STENCIL_OP_KEEP; break;
151 case GL_REPLACE: d3dStencilOp = D3D11_STENCIL_OP_REPLACE; break;
152 case GL_INCR: d3dStencilOp = D3D11_STENCIL_OP_INCR_SAT; break;
153 case GL_DECR: d3dStencilOp = D3D11_STENCIL_OP_DECR_SAT; break;
154 case GL_INVERT: d3dStencilOp = D3D11_STENCIL_OP_INVERT; break;
155 case GL_INCR_WRAP: d3dStencilOp = D3D11_STENCIL_OP_INCR; break;
156 case GL_DECR_WRAP: d3dStencilOp = D3D11_STENCIL_OP_DECR; break;
157 default: UNREACHABLE();
158 }
159
160 return d3dStencilOp;
161}
162
Geoff Langc82fc412013-07-10 14:43:42 -0400163D3D11_FILTER ConvertFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy, GLenum comparisonMode)
daniel@transgaming.com3d34a8a2013-01-11 04:07:48 +0000164{
Geoff Langc82fc412013-07-10 14:43:42 -0400165 bool comparison = comparisonMode != GL_NONE;
166
daniel@transgaming.com3d34a8a2013-01-11 04:07:48 +0000167 if (maxAnisotropy > 1.0f)
168 {
Jamie Madillfc2521e2014-05-16 16:21:57 -0400169 return D3D11_ENCODE_ANISOTROPIC_FILTER(static_cast<D3D11_COMPARISON_FUNC>(comparison));
daniel@transgaming.com3d34a8a2013-01-11 04:07:48 +0000170 }
171 else
172 {
173 D3D11_FILTER_TYPE dxMin = D3D11_FILTER_TYPE_POINT;
174 D3D11_FILTER_TYPE dxMip = D3D11_FILTER_TYPE_POINT;
175 switch (minFilter)
176 {
177 case GL_NEAREST: dxMin = D3D11_FILTER_TYPE_POINT; dxMip = D3D11_FILTER_TYPE_POINT; break;
178 case GL_LINEAR: dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_POINT; break;
179 case GL_NEAREST_MIPMAP_NEAREST: dxMin = D3D11_FILTER_TYPE_POINT; dxMip = D3D11_FILTER_TYPE_POINT; break;
180 case GL_LINEAR_MIPMAP_NEAREST: dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_POINT; break;
181 case GL_NEAREST_MIPMAP_LINEAR: dxMin = D3D11_FILTER_TYPE_POINT; dxMip = D3D11_FILTER_TYPE_LINEAR; break;
182 case GL_LINEAR_MIPMAP_LINEAR: dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_LINEAR; break;
183 default: UNREACHABLE();
184 }
185
186 D3D11_FILTER_TYPE dxMag = D3D11_FILTER_TYPE_POINT;
187 switch (magFilter)
188 {
189 case GL_NEAREST: dxMag = D3D11_FILTER_TYPE_POINT; break;
190 case GL_LINEAR: dxMag = D3D11_FILTER_TYPE_LINEAR; break;
191 default: UNREACHABLE();
192 }
193
Jamie Madillfc2521e2014-05-16 16:21:57 -0400194 return D3D11_ENCODE_BASIC_FILTER(dxMin, dxMag, dxMip, static_cast<D3D11_COMPARISON_FUNC>(comparison));
daniel@transgaming.com3d34a8a2013-01-11 04:07:48 +0000195 }
196}
197
198D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap)
199{
200 switch (wrap)
201 {
202 case GL_REPEAT: return D3D11_TEXTURE_ADDRESS_WRAP;
203 case GL_CLAMP_TO_EDGE: return D3D11_TEXTURE_ADDRESS_CLAMP;
204 case GL_MIRRORED_REPEAT: return D3D11_TEXTURE_ADDRESS_MIRROR;
205 default: UNREACHABLE();
206 }
207
208 return D3D11_TEXTURE_ADDRESS_WRAP;
209}
210
Geoff Lang37dde692014-01-31 16:34:54 -0500211D3D11_QUERY ConvertQueryType(GLenum queryType)
212{
213 switch (queryType)
214 {
215 case GL_ANY_SAMPLES_PASSED_EXT:
216 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: return D3D11_QUERY_OCCLUSION;
217 case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: return D3D11_QUERY_SO_STATISTICS;
218 default: UNREACHABLE(); return D3D11_QUERY_EVENT;
219 }
220}
221
daniel@transgaming.com6b147712012-11-28 19:37:24 +0000222}
223
Geoff Langcec35902014-04-16 10:52:36 -0400224
225namespace d3d11_gl
226{
227
Geoff Lange4a492b2014-06-19 14:14:41 -0400228static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, ID3D11Device *device)
Geoff Langcec35902014-04-16 10:52:36 -0400229{
230 gl::TextureCaps textureCaps;
231
Geoff Lang9aa00bb2014-07-07 12:33:25 -0400232 const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat);
Geoff Langcec35902014-04-16 10:52:36 -0400233
234 UINT formatSupport;
Geoff Lang9aa00bb2014-07-07 12:33:25 -0400235 if (SUCCEEDED(device->CheckFormatSupport(formatInfo.texFormat, &formatSupport)))
Geoff Langcec35902014-04-16 10:52:36 -0400236 {
Geoff Lang5d601382014-07-22 15:14:06 -0400237 const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
238 if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
Geoff Lang6cf8e1b2014-07-03 13:03:57 -0400239 {
240 textureCaps.texturable = ((formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0);
241 }
242 else
243 {
244 textureCaps.texturable = ((formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0) &&
245 ((formatSupport & D3D11_FORMAT_SUPPORT_TEXTURECUBE) != 0) &&
246 ((formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE3D) != 0);
247 }
Geoff Langcec35902014-04-16 10:52:36 -0400248 }
249
Geoff Lang9aa00bb2014-07-07 12:33:25 -0400250 if (SUCCEEDED(device->CheckFormatSupport(formatInfo.renderFormat, &formatSupport)) &&
Geoff Lang6cf8e1b2014-07-03 13:03:57 -0400251 ((formatSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET) != 0))
Geoff Langcec35902014-04-16 10:52:36 -0400252 {
253 for (size_t sampleCount = 1; sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; sampleCount++)
254 {
255 UINT qualityCount = 0;
Geoff Lang9aa00bb2014-07-07 12:33:25 -0400256 if (SUCCEEDED(device->CheckMultisampleQualityLevels(formatInfo.renderFormat, sampleCount, &qualityCount)) &&
Geoff Langcec35902014-04-16 10:52:36 -0400257 qualityCount > 0)
258 {
259 textureCaps.sampleCounts.insert(sampleCount);
260 }
261 }
262 }
263
Geoff Lang9aa00bb2014-07-07 12:33:25 -0400264 textureCaps.filterable = SUCCEEDED(device->CheckFormatSupport(formatInfo.srvFormat, &formatSupport)) &&
Geoff Lang6cf8e1b2014-07-03 13:03:57 -0400265 ((formatSupport & D3D11_FORMAT_SUPPORT_SHADER_SAMPLE)) != 0;
Geoff Lang9aa00bb2014-07-07 12:33:25 -0400266 textureCaps.renderable = (SUCCEEDED(device->CheckFormatSupport(formatInfo.rtvFormat, &formatSupport)) &&
Geoff Lang6cf8e1b2014-07-03 13:03:57 -0400267 ((formatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET)) != 0) ||
Geoff Lang9aa00bb2014-07-07 12:33:25 -0400268 (SUCCEEDED(device->CheckFormatSupport(formatInfo.dsvFormat, &formatSupport)) &&
Geoff Lang6cf8e1b2014-07-03 13:03:57 -0400269 ((formatSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL) != 0));
Geoff Langcec35902014-04-16 10:52:36 -0400270
271 return textureCaps;
272}
273
Geoff Langaae65a42014-05-26 12:43:44 -0400274static bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel)
275{
276 switch (featureLevel)
277 {
278 case D3D_FEATURE_LEVEL_11_1:
279 case D3D_FEATURE_LEVEL_11_0:
280 case D3D_FEATURE_LEVEL_10_1:
281 case D3D_FEATURE_LEVEL_10_0: return true;
282
283 // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx
284 case D3D_FEATURE_LEVEL_9_3:
285 case D3D_FEATURE_LEVEL_9_2:
286 case D3D_FEATURE_LEVEL_9_1: return false;
287
288 default: UNREACHABLE(); return false;
289 }
290}
291
292static float GetMaximumAnisotropy(D3D_FEATURE_LEVEL featureLevel)
293{
294 switch (featureLevel)
295 {
296 case D3D_FEATURE_LEVEL_11_1:
297 case D3D_FEATURE_LEVEL_11_0: return D3D11_MAX_MAXANISOTROPY;
298
299 case D3D_FEATURE_LEVEL_10_1:
300 case D3D_FEATURE_LEVEL_10_0: return D3D10_MAX_MAXANISOTROPY;
301
302 // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx
303 case D3D_FEATURE_LEVEL_9_3:
304 case D3D_FEATURE_LEVEL_9_2: return 16;
305
306 case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_DEFAULT_MAX_ANISOTROPY;
307
308 default: UNREACHABLE(); return 0;
309 }
310}
311
312static bool GetOcclusionQuerySupport(D3D_FEATURE_LEVEL featureLevel)
313{
314 switch (featureLevel)
315 {
316 case D3D_FEATURE_LEVEL_11_1:
317 case D3D_FEATURE_LEVEL_11_0:
318 case D3D_FEATURE_LEVEL_10_1:
319 case D3D_FEATURE_LEVEL_10_0: return true;
320
321 // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx ID3D11Device::CreateQuery
322 case D3D_FEATURE_LEVEL_9_3:
323 case D3D_FEATURE_LEVEL_9_2: return true;
324 case D3D_FEATURE_LEVEL_9_1: return false;
325
326 default: UNREACHABLE(); return false;
327 }
328}
329
330static bool GetEventQuerySupport(D3D_FEATURE_LEVEL featureLevel)
331{
332 // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx ID3D11Device::CreateQuery
333
334 switch (featureLevel)
335 {
336 case D3D_FEATURE_LEVEL_11_1:
337 case D3D_FEATURE_LEVEL_11_0:
338 case D3D_FEATURE_LEVEL_10_1:
339 case D3D_FEATURE_LEVEL_10_0:
340 case D3D_FEATURE_LEVEL_9_3:
341 case D3D_FEATURE_LEVEL_9_2:
342 case D3D_FEATURE_LEVEL_9_1: return true;
343
344 default: UNREACHABLE(); return false;
345 }
346}
347
348static bool GetInstancingSupport(D3D_FEATURE_LEVEL featureLevel)
349{
350 // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx ID3D11Device::CreateInputLayout
351
352 switch (featureLevel)
353 {
354 case D3D_FEATURE_LEVEL_11_1:
355 case D3D_FEATURE_LEVEL_11_0:
356 case D3D_FEATURE_LEVEL_10_1:
357 case D3D_FEATURE_LEVEL_10_0:
358 case D3D_FEATURE_LEVEL_9_3: return true;
359
360 case D3D_FEATURE_LEVEL_9_2:
361 case D3D_FEATURE_LEVEL_9_1: return false;
362
363 default: UNREACHABLE(); return false;
364 }
365}
366
367static bool GetDerivativeInstructionSupport(D3D_FEATURE_LEVEL featureLevel)
368{
369 // http://msdn.microsoft.com/en-us/library/windows/desktop/bb509588.aspx states that shader model
370 // ps_2_x is required for the ddx (and other derivative functions).
371
372 // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx states that feature level
373 // 9.3 supports shader model ps_2_x.
374
375 switch (featureLevel)
376 {
377 case D3D_FEATURE_LEVEL_11_1:
378 case D3D_FEATURE_LEVEL_11_0:
379 case D3D_FEATURE_LEVEL_10_1:
380 case D3D_FEATURE_LEVEL_10_0:
381 case D3D_FEATURE_LEVEL_9_3: return true;
382 case D3D_FEATURE_LEVEL_9_2:
383 case D3D_FEATURE_LEVEL_9_1: return false;
384
385 default: UNREACHABLE(); return false;
386 }
387}
388
389static size_t GetMaximumSimultaneousRenderTargets(D3D_FEATURE_LEVEL featureLevel)
390{
391 // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx ID3D11Device::CreateInputLayout
392
393 switch (featureLevel)
394 {
395 case D3D_FEATURE_LEVEL_11_1:
396 case D3D_FEATURE_LEVEL_11_0: return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT;
397
Geoff Langaae65a42014-05-26 12:43:44 -0400398 case D3D_FEATURE_LEVEL_10_1:
Jamie Madillf9479ef2014-09-05 10:38:05 -0400399 case D3D_FEATURE_LEVEL_10_0: return D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT;
Geoff Langaae65a42014-05-26 12:43:44 -0400400
401 case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT;
402 case D3D_FEATURE_LEVEL_9_2:
403 case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT;
404
405 default: UNREACHABLE(); return 0;
406 }
407}
408
409static size_t GetMaximum2DTextureSize(D3D_FEATURE_LEVEL featureLevel)
410{
411 switch (featureLevel)
412 {
413 case D3D_FEATURE_LEVEL_11_1:
414 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
415
416 case D3D_FEATURE_LEVEL_10_1:
417 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;
418
419 case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION;
420 case D3D_FEATURE_LEVEL_9_2:
421 case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION;
422
423 default: UNREACHABLE(); return 0;
424 }
425}
426
427static size_t GetMaximumCubeMapTextureSize(D3D_FEATURE_LEVEL featureLevel)
428{
429 switch (featureLevel)
430 {
431 case D3D_FEATURE_LEVEL_11_1:
432 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURECUBE_DIMENSION;
433
434 case D3D_FEATURE_LEVEL_10_1:
435 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURECUBE_DIMENSION;
436
437 case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_REQ_TEXTURECUBE_DIMENSION;
438 case D3D_FEATURE_LEVEL_9_2:
439 case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION;
440
441 default: UNREACHABLE(); return 0;
442 }
443}
444
445static size_t GetMaximum2DTextureArraySize(D3D_FEATURE_LEVEL featureLevel)
446{
447 switch (featureLevel)
448 {
449 case D3D_FEATURE_LEVEL_11_1:
450 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
451
452 case D3D_FEATURE_LEVEL_10_1:
453 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
454
455 case D3D_FEATURE_LEVEL_9_3:
456 case D3D_FEATURE_LEVEL_9_2:
457 case D3D_FEATURE_LEVEL_9_1: return 0;
458
459 default: UNREACHABLE(); return 0;
460 }
461}
462
463static size_t GetMaximum3DTextureSize(D3D_FEATURE_LEVEL featureLevel)
464{
465 switch (featureLevel)
466 {
467 case D3D_FEATURE_LEVEL_11_1:
468 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
469
470 case D3D_FEATURE_LEVEL_10_1:
471 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
472
473 case D3D_FEATURE_LEVEL_9_3:
474 case D3D_FEATURE_LEVEL_9_2:
475 case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
476
477 default: UNREACHABLE(); return 0;
478 }
479}
480
481static size_t GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel)
482{
483 switch (featureLevel)
484 {
485 case D3D_FEATURE_LEVEL_11_1:
486 case D3D_FEATURE_LEVEL_11_0: return D3D11_VIEWPORT_BOUNDS_MAX;
487
488 case D3D_FEATURE_LEVEL_10_1:
489 case D3D_FEATURE_LEVEL_10_0: return D3D10_VIEWPORT_BOUNDS_MAX;
490
491 // No constants for D3D9 viewport size limits, use the maximum texture sizes
492 case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION;
493 case D3D_FEATURE_LEVEL_9_2:
494 case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION;
495
496 default: UNREACHABLE(); return 0;
497 }
498}
499
Geoff Lang900013c2014-07-07 11:32:19 -0400500static size_t GetMaximumDrawIndexedIndexCount(D3D_FEATURE_LEVEL featureLevel)
501{
502 // D3D11 allows up to 2^32 elements, but we report max signed int for convenience since that's what's
503 // returned from glGetInteger
504 META_ASSERT(D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32);
505 META_ASSERT(D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32);
506
507 switch (featureLevel)
508 {
509 case D3D_FEATURE_LEVEL_11_1:
510 case D3D_FEATURE_LEVEL_11_0:
511 case D3D_FEATURE_LEVEL_10_1:
512 case D3D_FEATURE_LEVEL_10_0: return std::numeric_limits<GLint>::max();
513
514 case D3D_FEATURE_LEVEL_9_3:
515 case D3D_FEATURE_LEVEL_9_2: return D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT;
516 case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT;
517
518 default: UNREACHABLE(); return 0;
519 }
520}
521
522static size_t GetMaximumDrawVertexCount(D3D_FEATURE_LEVEL featureLevel)
523{
524 // D3D11 allows up to 2^32 elements, but we report max signed int for convenience since that's what's
525 // returned from glGetInteger
526 META_ASSERT(D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32);
527 META_ASSERT(D3D10_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32);
528
529 switch (featureLevel)
530 {
531 case D3D_FEATURE_LEVEL_11_1:
532 case D3D_FEATURE_LEVEL_11_0:
533 case D3D_FEATURE_LEVEL_10_1:
534 case D3D_FEATURE_LEVEL_10_0: return std::numeric_limits<GLint>::max();
535
536 case D3D_FEATURE_LEVEL_9_3:
537 case D3D_FEATURE_LEVEL_9_2: return D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT;
538 case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT;
539
540 default: UNREACHABLE(); return 0;
541 }
542}
543
Geoff Lang301d1612014-07-09 10:34:37 -0400544static size_t GetMaximumVertexInputSlots(D3D_FEATURE_LEVEL featureLevel)
545{
546 switch (featureLevel)
547 {
548 case D3D_FEATURE_LEVEL_11_1:
549 case D3D_FEATURE_LEVEL_11_0: return D3D11_STANDARD_VERTEX_ELEMENT_COUNT;
550
551 case D3D_FEATURE_LEVEL_10_1: return D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT;
552 case D3D_FEATURE_LEVEL_10_0: return D3D10_STANDARD_VERTEX_ELEMENT_COUNT;
553
554 // From http://http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx "Max Input Slots"
555 case D3D_FEATURE_LEVEL_9_3:
556 case D3D_FEATURE_LEVEL_9_2:
557 case D3D_FEATURE_LEVEL_9_1: return 16;
558
559 default: UNREACHABLE(); return 0;
560 }
561}
562
563static size_t GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel)
564{
Geoff Lang1fecbc82014-08-25 16:26:14 -0400565 // TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass
Geoff Lang301d1612014-07-09 10:34:37 -0400566 switch (featureLevel)
567 {
568 case D3D_FEATURE_LEVEL_11_1:
Geoff Lang1fecbc82014-08-25 16:26:14 -0400569 case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
Geoff Lang301d1612014-07-09 10:34:37 -0400570
571 case D3D_FEATURE_LEVEL_10_1:
Geoff Lang1fecbc82014-08-25 16:26:14 -0400572 case D3D_FEATURE_LEVEL_10_0: return 1024; // D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
Geoff Lang301d1612014-07-09 10:34:37 -0400573
574 // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx ID3D11DeviceContext::VSSetConstantBuffers
575 case D3D_FEATURE_LEVEL_9_3:
576 case D3D_FEATURE_LEVEL_9_2:
577 case D3D_FEATURE_LEVEL_9_1: return 255;
578
579 default: UNREACHABLE(); return 0;
580 }
581}
582
583static size_t GetReservedVertexUniformBuffers()
584{
585 // Reserve one buffer for the application uniforms, and one for driver uniforms
586 return 2;
587}
588
589static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
590{
591 switch (featureLevel)
592 {
593 case D3D_FEATURE_LEVEL_11_1:
594 case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers();
595
596 case D3D_FEATURE_LEVEL_10_1:
597 case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers();
598
599 // Uniform blocks not supported in D3D9 feature levels
600 case D3D_FEATURE_LEVEL_9_3:
601 case D3D_FEATURE_LEVEL_9_2:
602 case D3D_FEATURE_LEVEL_9_1: return 0;
603
604 default: UNREACHABLE(); return 0;
605 }
606}
607
608static size_t GetReservedVertexOutputVectors()
609{
610 // We potentially reserve varyings for gl_Position, dx_Position, gl_FragCoord and gl_PointSize
611 return 4;
612}
613
614static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel)
615{
Geoff Lang3a61c322014-07-10 13:01:54 -0400616 META_ASSERT(gl::IMPLEMENTATION_MAX_VARYING_VECTORS == D3D11_VS_OUTPUT_REGISTER_COUNT);
617
Geoff Lang301d1612014-07-09 10:34:37 -0400618 switch (featureLevel)
619 {
620 case D3D_FEATURE_LEVEL_11_1:
621 case D3D_FEATURE_LEVEL_11_0: return D3D11_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
622
623 case D3D_FEATURE_LEVEL_10_1: return D3D10_1_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
624 case D3D_FEATURE_LEVEL_10_0: return D3D10_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
625
626 // Use D3D9 SM3 and SM2 limits
627 case D3D_FEATURE_LEVEL_9_3: return 10 - GetReservedVertexOutputVectors();
628 case D3D_FEATURE_LEVEL_9_2:
629 case D3D_FEATURE_LEVEL_9_1: return 8 - GetReservedVertexOutputVectors();
630
631 default: UNREACHABLE(); return 0;
632 }
633}
634
635static size_t GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel)
636{
637 switch (featureLevel)
638 {
639 case D3D_FEATURE_LEVEL_11_1:
640 case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
641
642 case D3D_FEATURE_LEVEL_10_1:
643 case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT;
644
645 // Vertex textures not supported in D3D9 feature levels according to
646 // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx
647 // ID3D11DeviceContext::VSSetSamplers and ID3D11DeviceContext::VSSetShaderResources
648 case D3D_FEATURE_LEVEL_9_3:
649 case D3D_FEATURE_LEVEL_9_2:
650 case D3D_FEATURE_LEVEL_9_1: return 0;
651
652 default: UNREACHABLE(); return 0;
653 }
654}
655
656static size_t GetMaximumPixelUniformVectors(D3D_FEATURE_LEVEL featureLevel)
657{
Geoff Lang1fecbc82014-08-25 16:26:14 -0400658 // TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass
Geoff Lang301d1612014-07-09 10:34:37 -0400659 switch (featureLevel)
660 {
661 case D3D_FEATURE_LEVEL_11_1:
Geoff Lang1fecbc82014-08-25 16:26:14 -0400662 case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
Geoff Lang301d1612014-07-09 10:34:37 -0400663
664 case D3D_FEATURE_LEVEL_10_1:
Geoff Lang1fecbc82014-08-25 16:26:14 -0400665 case D3D_FEATURE_LEVEL_10_0: return 1024; // D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
Geoff Lang301d1612014-07-09 10:34:37 -0400666
667 // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx ID3D11DeviceContext::PSSetConstantBuffers
668 case D3D_FEATURE_LEVEL_9_3:
669 case D3D_FEATURE_LEVEL_9_2:
670 case D3D_FEATURE_LEVEL_9_1: return 32;
671
672 default: UNREACHABLE(); return 0;
673 }
674}
675
676static size_t GetReservedPixelUniformBuffers()
677{
678 // Reserve one buffer for the application uniforms, and one for driver uniforms
679 return 2;
680}
681
682static size_t GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
683{
684 switch (featureLevel)
685 {
686 case D3D_FEATURE_LEVEL_11_1:
687 case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers();
688
689 case D3D_FEATURE_LEVEL_10_1:
690 case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers();
691
692 // Uniform blocks not supported in D3D9 feature levels
693 case D3D_FEATURE_LEVEL_9_3:
694 case D3D_FEATURE_LEVEL_9_2:
695 case D3D_FEATURE_LEVEL_9_1: return 0;
696
697 default: UNREACHABLE(); return 0;
698 }
699}
700
701static size_t GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel)
702{
703 switch (featureLevel)
704 {
705 case D3D_FEATURE_LEVEL_11_1:
706 case D3D_FEATURE_LEVEL_11_0: return D3D11_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
707
708 case D3D_FEATURE_LEVEL_10_1:
709 case D3D_FEATURE_LEVEL_10_0: return D3D10_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors();
710
711 // Use D3D9 SM3 and SM2 limits
712 case D3D_FEATURE_LEVEL_9_3: return 10 - GetReservedVertexOutputVectors();
713 case D3D_FEATURE_LEVEL_9_2:
714 case D3D_FEATURE_LEVEL_9_1: return 8 - GetReservedVertexOutputVectors();
715
716 default: UNREACHABLE(); return 0;
717 }
718}
719
720static size_t GetMaximumPixelTextureUnits(D3D_FEATURE_LEVEL featureLevel)
721{
722 switch (featureLevel)
723 {
724 case D3D_FEATURE_LEVEL_11_1:
725 case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
726
727 case D3D_FEATURE_LEVEL_10_1:
728 case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT;
729
730 // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx ID3D11DeviceContext::PSSetShaderResources
731 case D3D_FEATURE_LEVEL_9_3:
732 case D3D_FEATURE_LEVEL_9_2:
733 case D3D_FEATURE_LEVEL_9_1: return 16;
734
735 default: UNREACHABLE(); return 0;
736 }
737}
738
739static int GetMinimumTexelOffset(D3D_FEATURE_LEVEL featureLevel)
740{
741 switch (featureLevel)
742 {
743 case D3D_FEATURE_LEVEL_11_1:
744 case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE;
745
746 case D3D_FEATURE_LEVEL_10_1:
747 case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE;
748
749 // Sampling functions with offsets are not available below shader model 4.0.
750 case D3D_FEATURE_LEVEL_9_3:
751 case D3D_FEATURE_LEVEL_9_2:
752 case D3D_FEATURE_LEVEL_9_1: return 0;
753
754 default: UNREACHABLE(); return 0;
755 }
756}
757
758static int GetMaximumTexelOffset(D3D_FEATURE_LEVEL featureLevel)
759{
760 switch (featureLevel)
761 {
762 case D3D_FEATURE_LEVEL_11_1:
763 case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE;
764 case D3D_FEATURE_LEVEL_10_1:
765 case D3D_FEATURE_LEVEL_10_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE;
766
767 // Sampling functions with offsets are not available below shader model 4.0.
768 case D3D_FEATURE_LEVEL_9_3:
769 case D3D_FEATURE_LEVEL_9_2:
770 case D3D_FEATURE_LEVEL_9_1: return 0;
771
772 default: UNREACHABLE(); return 0;
773 }
774}
775
Geoff Lang3a61c322014-07-10 13:01:54 -0400776static size_t GetMaximumConstantBufferSize(D3D_FEATURE_LEVEL featureLevel)
777{
778 // Returns a size_t despite the limit being a GLuint64 because size_t is the maximum size of
779 // any buffer that could be allocated.
780
781 const size_t bytesPerComponent = 4 * sizeof(float);
782
783 switch (featureLevel)
784 {
785 case D3D_FEATURE_LEVEL_11_1:
786 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent;
787
788 case D3D_FEATURE_LEVEL_10_1:
789 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent;
790
791 // Limits from http://msdn.microsoft.com/en-us/library/windows/desktop/ff476501.aspx remarks section
792 case D3D_FEATURE_LEVEL_9_3:
793 case D3D_FEATURE_LEVEL_9_2:
794 case D3D_FEATURE_LEVEL_9_1: return 4096 * bytesPerComponent;
795
796 default: UNREACHABLE(); return 0;
797 }
798}
799
Geoff Lang05881a02014-07-10 14:05:30 -0400800static size_t GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel)
801{
802 switch (featureLevel)
803 {
804 case D3D_FEATURE_LEVEL_11_1:
805 case D3D_FEATURE_LEVEL_11_0: return D3D11_SO_BUFFER_SLOT_COUNT;
806
807 case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SO_BUFFER_SLOT_COUNT;
808 case D3D_FEATURE_LEVEL_10_0: return D3D10_SO_BUFFER_SLOT_COUNT;
809
810 case D3D_FEATURE_LEVEL_9_3:
811 case D3D_FEATURE_LEVEL_9_2:
812 case D3D_FEATURE_LEVEL_9_1: return 0;
813
814 default: UNREACHABLE(); return 0;
815 }
816}
817
818static size_t GetMaximumStreamOutputInterleavedComponenets(D3D_FEATURE_LEVEL featureLevel)
819{
820 switch (featureLevel)
821 {
822 case D3D_FEATURE_LEVEL_11_1:
823 case D3D_FEATURE_LEVEL_11_0:
824
825 case D3D_FEATURE_LEVEL_10_1:
826 case D3D_FEATURE_LEVEL_10_0: return GetMaximumVertexOutputVectors(featureLevel) * 4;
827
828 case D3D_FEATURE_LEVEL_9_3:
829 case D3D_FEATURE_LEVEL_9_2:
830 case D3D_FEATURE_LEVEL_9_1: return 0;
831
832 default: UNREACHABLE(); return 0;
833 }
834}
835
836static size_t GetMaximumStreamOutputSeparateCompeonents(D3D_FEATURE_LEVEL featureLevel)
837{
838 switch (featureLevel)
839 {
840 case D3D_FEATURE_LEVEL_11_1:
841 case D3D_FEATURE_LEVEL_11_0: return GetMaximumStreamOutputInterleavedComponenets(featureLevel) /
842 GetMaximumStreamOutputBuffers(featureLevel);
843
844
845 // D3D 10 and 10.1 only allow one output per output slot if an output slot other than zero is used.
846 case D3D_FEATURE_LEVEL_10_1:
847 case D3D_FEATURE_LEVEL_10_0: return 4;
848
849 case D3D_FEATURE_LEVEL_9_3:
850 case D3D_FEATURE_LEVEL_9_2:
851 case D3D_FEATURE_LEVEL_9_1: return 0;
852
853 default: UNREACHABLE(); return 0;
854 }
855}
856
Geoff Langc0b9ef42014-07-02 10:02:37 -0400857void GenerateCaps(ID3D11Device *device, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions)
Geoff Langcec35902014-04-16 10:52:36 -0400858{
Geoff Lang5f4c4632014-07-03 13:46:52 -0400859 GLuint maxSamples = 0;
Geoff Lange4a492b2014-06-19 14:14:41 -0400860 const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
Geoff Langcec35902014-04-16 10:52:36 -0400861 for (gl::FormatSet::const_iterator internalFormat = allFormats.begin(); internalFormat != allFormats.end(); ++internalFormat)
862 {
Geoff Langc0b9ef42014-07-02 10:02:37 -0400863 gl::TextureCaps textureCaps = GenerateTextureFormatCaps(*internalFormat, device);
864 textureCapsMap->insert(*internalFormat, textureCaps);
Geoff Lang5f4c4632014-07-03 13:46:52 -0400865
866 maxSamples = std::max(maxSamples, textureCaps.getMaxSamples());
Geoff Lang900013c2014-07-07 11:32:19 -0400867
868 if (gl::GetInternalFormatInfo(*internalFormat).compressed)
869 {
870 caps->compressedTextureFormats.push_back(*internalFormat);
871 }
Geoff Langcec35902014-04-16 10:52:36 -0400872 }
873
874 D3D_FEATURE_LEVEL featureLevel = device->GetFeatureLevel();
875
Geoff Langaae65a42014-05-26 12:43:44 -0400876 // GL core feature limits
Geoff Langc0b9ef42014-07-02 10:02:37 -0400877 caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max());
878 caps->max3DTextureSize = GetMaximum3DTextureSize(featureLevel);
879 caps->max2DTextureSize = GetMaximum2DTextureSize(featureLevel);
880 caps->maxCubeMapTextureSize = GetMaximumCubeMapTextureSize(featureLevel);
881 caps->maxArrayTextureLayers = GetMaximum2DTextureArraySize(featureLevel);
Geoff Langaae65a42014-05-26 12:43:44 -0400882
883 // Unimplemented, set to minimum required
Geoff Langc0b9ef42014-07-02 10:02:37 -0400884 caps->maxLODBias = 2.0f;
Geoff Langaae65a42014-05-26 12:43:44 -0400885
886 // No specific limits on render target size, maximum 2D texture size is equivalent
Geoff Langc0b9ef42014-07-02 10:02:37 -0400887 caps->maxRenderbufferSize = caps->max2DTextureSize;
Geoff Langaae65a42014-05-26 12:43:44 -0400888
889 // Maximum draw buffers and color attachments are the same, max color attachments could eventually be
890 // increased to 16
Geoff Langc0b9ef42014-07-02 10:02:37 -0400891 caps->maxDrawBuffers = GetMaximumSimultaneousRenderTargets(featureLevel);
892 caps->maxColorAttachments = GetMaximumSimultaneousRenderTargets(featureLevel);
Geoff Langaae65a42014-05-26 12:43:44 -0400893
894 // D3D11 has the same limit for viewport width and height
Geoff Langc0b9ef42014-07-02 10:02:37 -0400895 caps->maxViewportWidth = GetMaximumViewportSize(featureLevel);
896 caps->maxViewportHeight = caps->maxViewportWidth;
Geoff Langaae65a42014-05-26 12:43:44 -0400897
898 // Choose a reasonable maximum, enforced in the shader.
Geoff Langc0b9ef42014-07-02 10:02:37 -0400899 caps->minAliasedPointSize = 1.0f;
900 caps->maxAliasedPointSize = 1024.0f;
Geoff Langaae65a42014-05-26 12:43:44 -0400901
902 // Wide lines not supported
Geoff Langc0b9ef42014-07-02 10:02:37 -0400903 caps->minAliasedLineWidth = 1.0f;
904 caps->maxAliasedLineWidth = 1.0f;
Geoff Langaae65a42014-05-26 12:43:44 -0400905
Geoff Lang900013c2014-07-07 11:32:19 -0400906 // Primitive count limits
907 caps->maxElementsIndices = GetMaximumDrawIndexedIndexCount(featureLevel);
908 caps->maxElementsVertices = GetMaximumDrawVertexCount(featureLevel);
909
910 // Program and shader binary formats (no supported shader binary formats)
911 caps->programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE);
912
913 // We do not wait for server fence objects internally, so report a max timeout of zero.
914 caps->maxServerWaitTimeout = 0;
915
Geoff Lang301d1612014-07-09 10:34:37 -0400916 // Vertex shader limits
917 caps->maxVertexAttributes = GetMaximumVertexInputSlots(featureLevel);
918 caps->maxVertexUniformComponents = GetMaximumVertexUniformVectors(featureLevel) * 4;
919 caps->maxVertexUniformVectors = GetMaximumVertexUniformVectors(featureLevel);
920 caps->maxVertexUniformBlocks = GetMaximumVertexUniformBlocks(featureLevel);
921 caps->maxVertexOutputComponents = GetMaximumVertexOutputVectors(featureLevel) * 4;
922 caps->maxVertexTextureImageUnits = GetMaximumVertexTextureUnits(featureLevel);
923
924 // Fragment shader limits
925 caps->maxFragmentUniformComponents = GetMaximumPixelUniformVectors(featureLevel) * 4;
926 caps->maxFragmentUniformVectors = GetMaximumPixelUniformVectors(featureLevel);
927 caps->maxFragmentUniformBlocks = GetMaximumPixelUniformBlocks(featureLevel);
928 caps->maxFragmentInputComponents = GetMaximumPixelInputVectors(featureLevel) * 4;
929 caps->maxTextureImageUnits = GetMaximumPixelTextureUnits(featureLevel);
930 caps->minProgramTexelOffset = GetMinimumTexelOffset(featureLevel);
931 caps->maxProgramTexelOffset = GetMaximumTexelOffset(featureLevel);
932
Geoff Lang3a61c322014-07-10 13:01:54 -0400933 // Aggregate shader limits
934 caps->maxUniformBufferBindings = caps->maxVertexUniformBlocks + caps->maxFragmentUniformBlocks;
935 caps->maxUniformBlockSize = GetMaximumConstantBufferSize(featureLevel);
936
937 // Setting a large alignment forces uniform buffers to bind with zero offset
938 caps->uniformBufferOffsetAlignment = static_cast<GLuint>(std::numeric_limits<GLint>::max());
939
940 caps->maxCombinedUniformBlocks = caps->maxVertexUniformBlocks + caps->maxFragmentUniformBlocks;
941 caps->maxCombinedVertexUniformComponents = (static_cast<GLint64>(caps->maxVertexUniformBlocks) * static_cast<GLint64>(caps->maxUniformBlockSize / 4)) +
942 static_cast<GLint64>(caps->maxVertexUniformComponents);
943 caps->maxCombinedFragmentUniformComponents = (static_cast<GLint64>(caps->maxFragmentUniformBlocks) * static_cast<GLint64>(caps->maxUniformBlockSize / 4)) +
944 static_cast<GLint64>(caps->maxFragmentUniformComponents);
945 caps->maxVaryingComponents = GetMaximumVertexOutputVectors(featureLevel) * 4;
946 caps->maxVaryingVectors = GetMaximumVertexOutputVectors(featureLevel);
Geoff Lang76b10c92014-09-05 16:28:14 -0400947 caps->maxCombinedTextureImageUnits = caps->maxVertexTextureImageUnits + caps->maxTextureImageUnits;
Geoff Lang3a61c322014-07-10 13:01:54 -0400948
Geoff Lang05881a02014-07-10 14:05:30 -0400949 // Transform feedback limits
950 caps->maxTransformFeedbackInterleavedComponents = GetMaximumStreamOutputInterleavedComponenets(featureLevel);
951 caps->maxTransformFeedbackSeparateAttributes = GetMaximumStreamOutputBuffers(featureLevel);
952 caps->maxTransformFeedbackSeparateComponents = GetMaximumStreamOutputSeparateCompeonents(featureLevel);
953
Geoff Langaae65a42014-05-26 12:43:44 -0400954 // GL extension support
Geoff Langc0b9ef42014-07-02 10:02:37 -0400955 extensions->setTextureExtensionSupport(*textureCapsMap);
956 extensions->elementIndexUint = true;
957 extensions->packedDepthStencil = true;
958 extensions->getProgramBinary = true;
959 extensions->rgb8rgba8 = true;
960 extensions->readFormatBGRA = true;
961 extensions->pixelBufferObject = true;
962 extensions->mapBuffer = true;
963 extensions->mapBufferRange = true;
964 extensions->textureNPOT = GetNPOTTextureSupport(featureLevel);
965 extensions->drawBuffers = GetMaximumSimultaneousRenderTargets(featureLevel) > 1;
966 extensions->textureStorage = true;
967 extensions->textureFilterAnisotropic = true;
968 extensions->maxTextureAnisotropy = GetMaximumAnisotropy(featureLevel);
969 extensions->occlusionQueryBoolean = GetOcclusionQuerySupport(featureLevel);
970 extensions->fence = GetEventQuerySupport(featureLevel);
971 extensions->timerQuery = false; // Unimplemented
972 extensions->robustness = true;
973 extensions->blendMinMax = true;
974 extensions->framebufferBlit = true;
975 extensions->framebufferMultisample = true;
Geoff Lang5f4c4632014-07-03 13:46:52 -0400976 extensions->maxSamples = maxSamples;
Geoff Langc0b9ef42014-07-02 10:02:37 -0400977 extensions->instancedArrays = GetInstancingSupport(featureLevel);
978 extensions->packReverseRowOrder = true;
979 extensions->standardDerivatives = GetDerivativeInstructionSupport(featureLevel);
980 extensions->shaderTextureLOD = true;
981 extensions->fragDepth = true;
982 extensions->textureUsage = true; // This could be false since it has no effect in D3D11
983 extensions->translatedShaderSource = true;
Geoff Langcec35902014-04-16 10:52:36 -0400984}
985
986}
987
daniel@transgaming.com8fb65c82012-12-20 21:07:49 +0000988namespace d3d11
989{
daniel@transgaming.com3d34a8a2013-01-11 04:07:48 +0000990
Geoff Lang9aa00bb2014-07-07 12:33:25 -0400991void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset)
992{
993 const DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(format);
994
995 int upsampleCount = 0;
996 // Don't expand the size of full textures that are at least (blockWidth x blockHeight) already.
997 if (isImage || *requestWidth < static_cast<GLsizei>(dxgiFormatInfo.blockWidth) ||
998 *requestHeight < static_cast<GLsizei>(dxgiFormatInfo.blockHeight))
999 {
1000 while (*requestWidth % dxgiFormatInfo.blockWidth != 0 || *requestHeight % dxgiFormatInfo.blockHeight != 0)
1001 {
1002 *requestWidth <<= 1;
1003 *requestHeight <<= 1;
1004 upsampleCount++;
1005 }
1006 }
1007 *levelOffset = upsampleCount;
1008}
1009
Geoff Lange4a492b2014-06-19 14:14:41 -04001010void GenerateInitialTextureData(GLint internalFormat, GLuint width, GLuint height, GLuint depth,
Geoff Lang34256ed2013-09-30 15:15:52 -04001011 GLuint mipLevels, std::vector<D3D11_SUBRESOURCE_DATA> *outSubresourceData,
1012 std::vector< std::vector<BYTE> > *outData)
1013{
Geoff Lang9aa00bb2014-07-07 12:33:25 -04001014 const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(internalFormat);
1015 ASSERT(d3dFormatInfo.dataInitializerFunction != NULL);
1016
1017 const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3dFormatInfo.texFormat);
Geoff Lang34256ed2013-09-30 15:15:52 -04001018
1019 outSubresourceData->resize(mipLevels);
1020 outData->resize(mipLevels);
1021
1022 for (unsigned int i = 0; i < mipLevels; i++)
1023 {
1024 unsigned int mipWidth = std::max(width >> i, 1U);
1025 unsigned int mipHeight = std::max(height >> i, 1U);
1026 unsigned int mipDepth = std::max(depth >> i, 1U);
1027
Geoff Lang9aa00bb2014-07-07 12:33:25 -04001028 unsigned int rowWidth = dxgiFormatInfo.pixelBytes * mipWidth;
Geoff Lang34256ed2013-09-30 15:15:52 -04001029 unsigned int imageSize = rowWidth * height;
1030
1031 outData->at(i).resize(rowWidth * mipHeight * mipDepth);
Geoff Lang9aa00bb2014-07-07 12:33:25 -04001032 d3dFormatInfo.dataInitializerFunction(mipWidth, mipHeight, mipDepth, outData->at(i).data(), rowWidth, imageSize);
Geoff Lang34256ed2013-09-30 15:15:52 -04001033
1034 outSubresourceData->at(i).pSysMem = outData->at(i).data();
1035 outSubresourceData->at(i).SysMemPitch = rowWidth;
1036 outSubresourceData->at(i).SysMemSlicePitch = imageSize;
1037 }
1038}
1039
shannon.woods@transgaming.comf3d82072013-01-25 21:50:43 +00001040void SetPositionTexCoordVertex(PositionTexCoordVertex* vertex, float x, float y, float u, float v)
1041{
1042 vertex->x = x;
1043 vertex->y = y;
1044 vertex->u = u;
1045 vertex->v = v;
1046}
1047
shannonwoods@chromium.org7b61d5c2013-05-30 00:04:12 +00001048void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex* vertex, float x, float y,
1049 unsigned int layer, float u, float v, float s)
1050{
1051 vertex->x = x;
1052 vertex->y = y;
1053 vertex->l = layer;
1054 vertex->u = u;
1055 vertex->v = v;
1056 vertex->s = s;
1057}
1058
daniel@transgaming.com00f2d9c2013-01-11 04:11:08 +00001059HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name)
1060{
1061#if defined(_DEBUG)
1062 return resource->SetPrivateData(WKPDID_D3DDebugObjectName, strlen(name), name);
1063#else
1064 return S_OK;
1065#endif
1066}
1067
Jamie Madill9f0b42a2014-09-12 10:25:27 -04001068RenderTarget11 *GetAttachmentRenderTarget(gl::FramebufferAttachment *attachment)
1069{
1070 RenderTarget *renderTarget = rx::GetAttachmentRenderTarget(attachment);
1071 return RenderTarget11::makeRenderTarget11(renderTarget);
1072}
1073
daniel@transgaming.com3d34a8a2013-01-11 04:07:48 +00001074}
shannonwoods@chromium.orged0adcf2013-05-30 00:08:20 +00001075
1076}