summaryrefslogtreecommitdiff
path: root/Runtime/Shaders/GraphicsCaps.h
blob: 0e1e37d29df0244e9823bc0d971ca804836c53b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
#pragma once

#include <string>
#include "Runtime/GfxDevice/GfxDeviceTypes.h"

enum ShaderCapsLevel
{
	kShaderLevel2 = 20,		// shader model 2.0 & 2.x
	kShaderLevel3 = 30,		// shader model 3.0
	kShaderLevel4 = 40,		// shader model 4.0
	kShaderLevel4_1 = 41,	// shader model 4.1
	kShaderLevel5 = 50,		// shader model 5.0
};

enum NPOTCaps
{
	kNPOTNone = 0,		// no NPOT texture capability
	kNPOTRestricted,	// NPOT available with restrictions (no mips, no wrap mode, no compression)
	kNPOTFull,			// NPOT available, no restrictions
};


#if GFX_SUPPORTS_D3D9
#include "PlatformDependent/Win/WinDriverUtils.h"
#include "Runtime/GfxDevice/d3d/D3D9Includes.h"
struct GraphicsCapsD3D9
{
	D3DCAPS9	d3dcaps;
	bool		hasBaseTextureFormat[kTexFormatPCCount];
	bool		hasTextureFormatA8;
	bool		hasTextureFormatL8;
	bool		hasTextureFormatA8L8;
	bool		hasTextureFormatL16;
	bool		hasATIDepthFormat16; // Has ATI DF16 render texture format?
	bool		hasNVDepthFormatINTZ;
	bool		hasNVDepthFormatRAWZ;
	bool		hasNULLFormat;
	bool		hasDepthResolveRESZ;

	// ---- hardware/driver workarounds
	bool		slowINTZSampling;	// very slow at using depth testing and sampling INTZ at the same time; prefer RESZ copy into separate surface
};
#endif

#if GFX_SUPPORTS_D3D11
enum DX11FeatureLevel {
	kDX11Level9_1,
	kDX11Level9_2,
	kDX11Level9_3,
	kDX11Level10_0,
	kDX11Level10_1,
	kDX11Level11_0,
	kDX11LevelCount
};

struct GraphicsCapsD3D11
{
	UInt32			msaa; // regular backbuffer, bit for each sample count we want
	UInt32			msaaSRGB; // sRGB backbuffer, bit for each sample count we want
	DX11FeatureLevel	featureLevel;
	bool			hasShadows10Level9;
	bool			buggyPartialPrecision10Level9; // half precision broken on 10level9 shaders (crashes)
};
#endif

#if GFX_SUPPORTS_OPENGL
struct GraphicsCapsGL
{
	int  glVersion; // e.g. 20 for 2.0, 43 for 4.3
	int  vertexAttribCount;		// How many generic vertex attributes are supported?

	int	 nativeVPInstructions;
	int  nativeFPInstructions;
	int  nativeFPTexInstructions;
	int  nativeFPALUInstructions;
	int  nativeFPTemporaries;

	int  maxSamples;

	bool hasGLSL;				// GLSL

	bool hasTextureEnvCombine3ATI;	// GL_ATI_texture_env_combine3 - the preferred way
	bool hasTextureEnvCombine3NV;	// GL_NV_texture_env_combine4 - fallback to emulate with TNT combiners

	#if UNITY_WIN
	bool hasWglARBPixelFormat;
	bool hasWglSwapControl;
	#endif

	bool hasArbMapBufferRange;
	bool hasArbSync;

	#if UNITY_OSX
	bool hasAppleFence;
	bool hasAppleFlushBufferRange;
	#endif

	bool hasFrameBufferBlit;

	// ---- hardware/driver workarounds
	bool buggyArbPrecisionHint;		// ARB precision hint in FPs is broken, postprocess programs to remove it
	bool cacheFPParamsWithEnvs;		// For fragment programs, use Env parameters instead of Local ones, and cache their values
	bool forceColorBufferWithDepthFBO; // For depth FBO, always use color buffer, with no color buffer it will be wrong
	bool force24DepthForFBO; // 16 bit depth does not work for FBO depth textures
	bool buggyPackedDepthStencil;
	bool mustWriteToDepthBufferBeforeClear; // depth buffer will contain garbage if it isn't written to at least once per frame.
	bool originalHasNativeShadowMaps;
};
#endif



#if GFX_SUPPORTS_OPENGLES20
struct GraphicsCapsGLES20
{
	int	 maxAttributes;
	int  maxVaryings;
	int  maxSamples;
	bool hasGLSL;
	bool hasVBOOrphaning;
	bool slowAlphaTest;
	bool slowDynamicVBO;			// will force dynamic draw from mem (except static batch indices)
	bool forceStaticBatchFromMem;	// will force static batch indices to be used from mem

	// features

	bool hasBinaryShaders;
	bool has24DepthForFBO;
	bool hasMapbuffer;
	bool hasMapbufferRange;
	bool hasDebugMarkers;
	bool hasDiscardFramebuffer;
	bool hasHalfLinearFilter;

	bool hasAppleMSAA;
	bool hasImgMSAA;

	// bugs workaround

	bool buggyColorMaskBlendMSAA;	// on some ios msaa+color mask+blend results in crazy rendering artefacts
	bool buggyDisableVAttrKeepsActive;	// on some mali drivers vattrs are kept active even after disabling them
	bool forceHighpFSPrec;		// on some nvidia drivers there is a bug: they fail to report samplers if default prec is not high
	bool buggyVFetchPatching;	// some adreno drivers fails to patch vfetch instructions (if vertex layout changed)
	bool buggyVprogTextures;	// some mali drivers have crashes in shader compiler if vprog texture is used
	bool needToRenderWatermarkDueToDrawFromMemoryBuggy;	// on some pvr it may crash when rendering from mem (it seems one shader used is culprit)
	bool needFlushAfterTextureUpload;

	// vendor specific

	bool hasNLZ;				// nvidia non-linear z
	bool hasNVMRT;				// nvidia mrt support
	bool hasAlphaTestQCOM;		// adreno special gles11 alpha test
};
#endif

#if GFX_SUPPORTS_OPENGLES30
struct GraphicsCapsGLES30
{
	GraphicsCapsGLES30 (void)
		: maxAttributes				(16)
		, maxVaryings				(16)
		, maxSamples				(4)
		, useProgramBinary			(true)
		, useMapBuffer				(true)
		, useTFSkinning				(true)
		, hasDebugMarkers			(false)
		, hasAlphaTestQCOM			(false)
	{
	}

	// Limits.
	int		maxAttributes;
	int		maxVaryings;
	int		maxSamples;					// Max sample count for renderbuffers.

	// Feature configuration.
	bool	useProgramBinary;			// ProgramBinary support is in core, but in case of we want to ignore it on some platforms.
	bool	useMapBuffer;				// One some platforms mapping buffers is very slow.
	bool	useTFSkinning;				// Use transform feedback for skinning.

	// Extension bits.
	bool	hasDebugMarkers;
	bool	hasAlphaTestQCOM;
};
#endif

#if GFX_SUPPORTS_OPENGL || GFX_SUPPORTS_OPENGLES20
bool FindGLExtension (const char* extensions, const char* ext);
#endif

#if GFX_SUPPORTS_OPENGLES20
bool  QueryExtension (const char* ext);
#endif


struct GraphicsCaps
{
	GraphicsCaps()
	{
		::memset(this, 0x00, sizeof(GraphicsCaps));

		for (int i = 0 ; i < kTexFormatPCCount; ++i)
			supportsTextureFormat[i] = true;

		// Default RT format is always enabled until we don't have render-to-texture at all
		// It is dummy value used to select most appropriate rt format
		supportsRenderTextureFormat[kRTFormatDefault] = true;
		supportsRenderTextureFormat[kRTFormatDefaultHDR] = true;

		new (&rendererString) StaticString();
		new (&vendorString) StaticString();
		new (&driverVersionString) StaticString();
		new (&fixedVersionString) StaticString();
		new (&driverLibraryString) StaticString();

		shaderCaps = kShaderLevel2;
		videoMemoryMB = 16.0f;

		maxLights = 8;
		maxAnisoLevel = 1;
		maxTexImageUnits = 8;
		maxTexCoords = 1;
		maxTexUnits = 1;

		maxTextureSize = 256;
		maxCubeMapSize = 64;
		maxRenderTextureSize = 128;
		maxMRTs = 1;

		hasFixedFunction = true;
		npotRT = npot = kNPOTNone;
		hasNonFullscreenClear = true;
		hasShadowCollectorPass = true;
		hasHighPrecisionTextureCombiners = true;

		hasGrabPass = true;
	}

	void SharedCapsPostInitialize();

	// ---------- caps common for all devices
	StaticString		rendererString;	// graphics card name
	StaticString		vendorString;	// graphics card vendor name
	StaticString        driverVersionString; // (GL) version as reported by the driver
	StaticString		fixedVersionString; // (GL) correct GL version appended in front by us
	StaticString		driverLibraryString;	// Name of driver's DLL and version
	int				vendorID;
	int				rendererID;

	ShaderCapsLevel	shaderCaps;	// Generic "shader capability level"

	float videoMemoryMB;		// Approx. amount of video memory in MB. Used to limit texture, render target and so on sizes to sane values.

	int		maxVSyncInterval;	// Max frames that device can wait for vertical blank
	int		maxLights;			// vertex light count
	int		maxAnisoLevel;
	int		maxTexImageUnits;	// Part of arb-fragment program (otherwise they match textureUnitCount)
	int		maxTexCoords;
	int		maxTexUnits;

	int		maxTextureSize;
	int		maxCubeMapSize;
	int		maxRenderTextureSize;	// usually maxTextureSize, except on some crappy cards

	int		maxMRTs;

	bool	hasAnisoFilter;		// has anisotropic filtering?
	bool	hasMipLevelBias;	// can apply bias for mips?
	bool	hasMipMaxLevel;		// can specify max mip level

	bool	hasFixedFunction;	// Supports T&L and texture combine stages

	bool	hasMultiSample;
	bool	hasMultiSampleAutoResolve;	// uses texture instead, and under-the-hood rb will be auto-resolved to it

	bool	hasBlendSquare;
	bool	hasSeparateAlphaBlend;
	bool 	hasBlendSub;		// both sub and revsub
	bool	hasBlendMinMax;		// max,min
	bool	hasBlendLogicOps;	// kBlendOpLogical*

	bool	hasS3TCCompression;
	bool	hasVertexTextures;	// Can read textures in a vertex shader?

	bool    hasTimerQuery;

	bool	hasAutoMipMapGeneration; // can auto-generate mipmaps for textures?

	bool supportsTextureFormat[kTexFormatTotalCount];
	bool supportsRenderTextureFormat[kRTFormatCount];

	bool has3DTexture;

	NPOTCaps	npot;
	NPOTCaps	npotRT;

	bool hasSRGBReadWrite;
	bool hasComputeShader;
	bool hasInstancing;
	bool hasNonFullscreenClear;		// Can do clears on non-full screen? (e.g. D3D11 can not)

	bool hasRenderToTexture;		// We have render-to-texture functionality
	bool hasRenderToCubemap;		// We have render-to-cubemap functionality
	bool hasRenderTo3D;				// We have render-to-volume functionality
	bool hasStencil;				// Stencil support good enough to be used by the users via the shaderlab state.
	bool hasRenderTargetStencil;	// Has sane way of having stencil buffer on render targets
	bool hasNativeDepthTexture;		// Depth textures come from actual depth buffer
	bool hasStencilInDepthTexture;	// Has native depth texture AND stencil buffer of it can be used at the same time
	bool hasNativeShadowMap;		// Depth textures have native shadow map comparison sampling
	bool hasShadowCollectorPass;	// mobiles don't usage collector pass, go direct SMs!
	bool hasTiledGPU; 				// Uses tiled rendering (clear/discard preferred!)

	bool hasTwoSidedStencil;
	bool hasHighPrecisionTextureCombiners;

	bool has16BitFloatVertex;		 // Supports at least 2D and 4D vertex channels as 16 bit floats
	bool needsToSwizzleVertexColors; // Should vertex colors be passed as B,G,R,A bytes instead of R,G,B,A

	bool disableSubTextureUpload;		 // Can we do UploadTextureSubData2D?
	bool warnRenderTargetUnresolves;	// Warn when doing RT un-resolves

	bool hasGrabPass;				// Can read from active render target back into a render texture?

	// cross platform caps initialized in SharedCapsPostInitialize
	bool hasPrePassRenderLoop;

	bool SupportsRGBM() const { return maxTexUnits >= 3 && hasHighPrecisionTextureCombiners; }

	std::string CheckGPUSupported() const;

	// ---- hardware/driver workarounds for all renderers

	bool disableSoftShadows;		// Soft shadows should work, but the driver is buggy on those shaders
	bool buggyCameraRenderToCubemap;// Render to cubemap sort-of-does-not-work (but works for point light shadows).
	bool buggyFullscreenFSAA;		// FSAA in fullscreen is buggy.
	bool buggyTextureBothColorAndDepth; // Can't have render target where both color & depth will be sampled as textures
	bool buggyDynamicVBOWithTangents;	// DynamicVBO with tangents is buggy
	bool buggyMipmappedCubemaps;		// Cubemaps with mipmaps are buggy; keep only 1st mip level
	bool buggyMipmapped3DTextures;		// 3D textures with mipmaps are buggy; keep only 1st mip level
	bool buggyShadowMapBilinearSampling; // Never use hardware bilinear PCF on shadow maps due to bugs?
	bool buggySpotNativeShadowMap; // Never use hardware shadow maps on spot lights
	bool buggyTimerQuery; // Has timer queries, but they aren't very good!
	
	// ---- caps specific for renderers
	
#if GFX_SUPPORTS_OPENGL
	GraphicsCapsGL gl;
#endif
#if GFX_SUPPORTS_OPENGLES20
	GraphicsCapsGLES20 gles20;
#endif
#if GFX_SUPPORTS_D3D9
	GraphicsCapsD3D9 d3d;
#endif
#if GFX_SUPPORTS_D3D11
	GraphicsCapsD3D11 d3d11;
#endif
#if GFX_SUPPORTS_OPENGLES30
	GraphicsCapsGLES30 gles30;
#endif
	
	#if GFX_SUPPORTS_OPENGL
	void InitGL();
	#endif
	#if GFX_SUPPORTS_D3D9
	void InitD3D9();
	#endif
	#if GFX_SUPPORTS_D3D11
	void InitD3D11();
	#endif
	#if GFX_SUPPORTS_NULL
	void InitNull();
	#endif
	#if GFX_SUPPORTS_MOLEHILL
	void InitMolehill();
	#endif
	#if GFX_SUPPORTS_XENON
	void InitXenon();
	#endif
	#if GFX_SUPPORTS_GCM
	void InitGcm();
	UInt32 videoMemoryStart;
	#endif
	#if GFX_SUPPORTS_HOLLYWOOD
	void InitHollywood();
	#endif
	#if GFX_SUPPORTS_OPENGLES20
	void InitGLES20();
	#endif
	#if GFX_SUPPORTS_OPENGLES30
	void InitGLES30();
	#endif

	void InitWithBuildVersion();


	// Implemented in GraphicsCaps.cpp
	#if UNITY_EDITOR
	enum Emulation {
		kEmulNone,		// whatever card naturally has
		kEmulSM3,		// Shader Model 3.0
		kEmulSM2,		// Shader Model 2.0, but with 4 texture stages
		kEmulGLES20,	// OpenGL ES 2.0
		kEmulXBox360,
		kEmulPS3,
		kEmulDX11_9_1,	// DirectX 11 Feature Level 9.1, No Fixed Function shaders (Shader Model 2)
		kEmulDX11_9_3, // DirectX 11 Feature Level 9.1, Fixed Function shaders (Shader Model 3)
		kEmulCount
	};
	Emulation GetEmulation() const;
	void SetEmulation( Emulation emul );
	bool IsEmulatingGLES20() const;
	bool CheckEmulationSupported( Emulation emul );
	void InitializeOriginalEmulationCapsIfNeeded();
	void ResetOriginalEmulationCaps();

	static void ApplyEmulationSettingsAffectingGUI();

	private:
	void ApplyEmulationSetingsOnly( const GraphicsCaps& origCaps, const Emulation emul );
	#endif


private:

	#if GFX_SUPPORTS_OPENGL
	void AdjustBuggyVersionGL( int& version, int& major, int& minor ) const;
	void DetectDriverBugsGL( int version );
	#endif
	#if GFX_SUPPORTS_D3D9
	void DetectDriverBugsD3D9( UInt32 vendorCode, const windriverutils::VersionInfo& version );
	#endif
};

extern GraphicsCaps gGraphicsCaps;