1 /*
2 -----------------------------------------------------------------------------
3 This source file is part of OGRE
4 (Object-oriented Graphics Rendering Engine)
5 For the latest info, see http://www.ogre3d.org/
6 
7 Copyright (c) 2000-2014 Torus Knot Software Ltd
8 
9 Permission is hereby granted, free of charge, to any person obtaining a copy
10 of this software and associated documentation files (the "Software"), to deal
11 in the Software without restriction, including without limitation the rights
12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom the Software is
14 furnished to do so, subject to the following conditions:
15 
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
18 
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 THE SOFTWARE.
26 -----------------------------------------------------------------------------
27 */
28 #include "OgreStableHeaders.h"
29 
30 #include "OgreRenderSystemCapabilities.h"
31 
32 namespace Ogre {
33 
34     //-----------------------------------------------------------------------
RenderSystemCapabilities()35     RenderSystemCapabilities::RenderSystemCapabilities()
36         : mVendor(GPU_UNKNOWN)
37         , mNumTextureUnits(0)
38         , mStencilBufferBitDepth(0)
39         , mNumVertexBlendMatrices(0)
40         , mNumMultiRenderTargets(1)
41         , mNonPOW2TexturesLimited(false)
42         , mMaxSupportedAnisotropy(0)
43         , mVertexTextureUnitsShared(0)
44         , mGeometryProgramNumOutputVertices(0)
45         , mNumVertexAttributes(1)
46     {
47         for(int i = 0; i < CAPS_CATEGORY_COUNT; i++)
48         {
49             mCapabilities[i] = 0;
50         }
51         mCategoryRelevant[CAPS_CATEGORY_COMMON] = true;
52         mCategoryRelevant[CAPS_CATEGORY_COMMON_2] = true;
53         // each rendersystem should enable these
54         mCategoryRelevant[CAPS_CATEGORY_D3D9] = false;
55         mCategoryRelevant[CAPS_CATEGORY_GL] = false;
56     }
57 
58     //-----------------------------------------------------------------------
log(Log * pLog) const59     void RenderSystemCapabilities::log(Log* pLog) const
60     {
61         pLog->logMessage("RenderSystem capabilities");
62         pLog->logMessage("-------------------------");
63         pLog->logMessage("RenderSystem Name: " + getRenderSystemName());
64         pLog->logMessage("GPU Vendor: " + vendorToString(getVendor()));
65         pLog->logMessage("Device Name: " + getDeviceName());
66         pLog->logMessage("Driver Version: " + getDriverVersion().toString());
67         pLog->logMessage(" * Fixed function pipeline: "
68             + StringConverter::toString(hasCapability(RSC_FIXED_FUNCTION), true));
69         pLog->logMessage(
70             " * Anisotropic texture filtering: "
71             + StringConverter::toString(hasCapability(RSC_ANISOTROPY), true));
72         pLog->logMessage(
73             " * Cube mapping: "
74             + StringConverter::toString(hasCapability(RSC_CUBEMAPPING), true));
75         pLog->logMessage(
76             " * Hardware stencil buffer: "
77             + StringConverter::toString(hasCapability(RSC_HWSTENCIL), true));
78         if (hasCapability(RSC_HWSTENCIL))
79         {
80             pLog->logMessage(
81                 "   - Stencil depth: "
82                 + StringConverter::toString(getStencilBufferBitDepth()));
83             pLog->logMessage(
84                 "   - Two sided stencil support: "
85                 + StringConverter::toString(hasCapability(RSC_TWO_SIDED_STENCIL), true));
86             pLog->logMessage(
87                 "   - Wrap stencil values: "
88                 + StringConverter::toString(hasCapability(RSC_STENCIL_WRAP), true));
89         }
90         pLog->logMessage(
91             " * 32-bit index buffers: "
92             + StringConverter::toString(hasCapability(RSC_32BIT_INDEX), true));
93         pLog->logMessage(
94             " * Vertex programs: "
95             + StringConverter::toString(hasCapability(RSC_VERTEX_PROGRAM), true));
96         pLog->logMessage(
97              " * Number of floating-point constants for vertex programs: "
98              + StringConverter::toString(mVertexProgramConstantFloatCount));
99         pLog->logMessage(
100              " * Number of integer constants for vertex programs: "
101              + StringConverter::toString(mVertexProgramConstantIntCount));
102         pLog->logMessage(
103              " * Number of boolean constants for vertex programs: "
104              + StringConverter::toString(mVertexProgramConstantBoolCount));
105         pLog->logMessage(
106             " * Fragment programs: "
107             + StringConverter::toString(hasCapability(RSC_FRAGMENT_PROGRAM), true));
108         pLog->logMessage(
109              " * Number of floating-point constants for fragment programs: "
110              + StringConverter::toString(mFragmentProgramConstantFloatCount));
111         pLog->logMessage(
112              " * Number of integer constants for fragment programs: "
113              + StringConverter::toString(mFragmentProgramConstantIntCount));
114         pLog->logMessage(
115              " * Number of boolean constants for fragment programs: "
116              + StringConverter::toString(mFragmentProgramConstantBoolCount));
117         pLog->logMessage(
118             " * Geometry programs: "
119             + StringConverter::toString(hasCapability(RSC_GEOMETRY_PROGRAM), true));
120         pLog->logMessage(
121              " * Number of floating-point constants for geometry programs: "
122              + StringConverter::toString(mGeometryProgramConstantFloatCount));
123         pLog->logMessage(
124              " * Number of integer constants for geometry programs: "
125              + StringConverter::toString(mGeometryProgramConstantIntCount));
126         pLog->logMessage(
127              " * Number of boolean constants for geometry programs: "
128              + StringConverter::toString(mGeometryProgramConstantBoolCount));
129         pLog->logMessage(
130             " * Tessellation Hull programs: "
131             + StringConverter::toString(hasCapability(RSC_TESSELLATION_HULL_PROGRAM), true));
132         pLog->logMessage(
133              " * Number of floating-point constants for tessellation hull programs: "
134              + StringConverter::toString(mTessellationHullProgramConstantFloatCount));
135         pLog->logMessage(
136              " * Number of integer constants for tessellation hull programs: "
137              + StringConverter::toString(mTessellationHullProgramConstantIntCount));
138         pLog->logMessage(
139              " * Number of boolean constants for tessellation hull programs: "
140              + StringConverter::toString(mTessellationHullProgramConstantBoolCount));
141         pLog->logMessage(
142             " * Tessellation Domain programs: "
143             + StringConverter::toString(hasCapability(RSC_TESSELLATION_DOMAIN_PROGRAM), true));
144         pLog->logMessage(
145              " * Number of floating-point constants for tessellation domain programs: "
146              + StringConverter::toString(mTessellationDomainProgramConstantFloatCount));
147         pLog->logMessage(
148              " * Number of integer constants for tessellation domain programs: "
149              + StringConverter::toString(mTessellationDomainProgramConstantIntCount));
150         pLog->logMessage(
151              " * Number of boolean constants for tessellation domain programs: "
152              + StringConverter::toString(mTessellationDomainProgramConstantBoolCount));
153         pLog->logMessage(
154             " * Compute programs: "
155             + StringConverter::toString(hasCapability(RSC_COMPUTE_PROGRAM), true));
156         pLog->logMessage(
157              " * Number of floating-point constants for compute programs: "
158              + StringConverter::toString(mComputeProgramConstantFloatCount));
159         pLog->logMessage(
160              " * Number of integer constants for compute programs: "
161              + StringConverter::toString(mComputeProgramConstantIntCount));
162         pLog->logMessage(
163              " * Number of boolean constants for compute programs: "
164              + StringConverter::toString(mComputeProgramConstantBoolCount));
165         String profileList = "";
166         for(ShaderProfiles::iterator iter = mSupportedShaderProfiles.begin(), end = mSupportedShaderProfiles.end();
167             iter != end; ++iter)
168         {
169             profileList += " " + *iter;
170         }
171         pLog->logMessage(" * Supported Shader Profiles:" + profileList);
172 
173         pLog->logMessage(
174             " * Texture Compression: "
175             + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION), true));
176         if (hasCapability(RSC_TEXTURE_COMPRESSION))
177         {
178             pLog->logMessage(
179                 "   - DXT: "
180                 + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION_DXT), true));
181             pLog->logMessage(
182                 "   - VTC: "
183                 + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION_VTC), true));
184             pLog->logMessage(
185                  "   - PVRTC: "
186                  + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION_PVRTC), true));
187             pLog->logMessage(
188                  "   - ATC: "
189                  + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION_ATC), true));
190             pLog->logMessage(
191                  "   - ETC1: "
192                  + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION_ETC1), true));
193             pLog->logMessage(
194                  "   - ETC2: "
195                  + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION_ETC2), true));
196             pLog->logMessage(
197                  "   - BC4/BC5: "
198                  + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION_BC4_BC5), true));
199             pLog->logMessage(
200                  "   - BC6H/BC7: "
201                  + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION_BC6H_BC7), true));
202             pLog->logMessage(
203                  "   - ASTC: "
204                  + StringConverter::toString(hasCapability(RSC_TEXTURE_COMPRESSION_ASTC), true));
205             pLog->logMessage(
206                 "   - Mipmaps for compressed formats: "
207                 + StringConverter::toString(hasCapability(RSC_AUTOMIPMAP_COMPRESSED), true));
208         }
209 
210         pLog->logMessage(
211             " * Hardware Occlusion Query: "
212             + StringConverter::toString(hasCapability(RSC_HWOCCLUSION), true));
213         pLog->logMessage(
214             " * User clip planes: "
215             + StringConverter::toString(hasCapability(RSC_USER_CLIP_PLANES), true));
216         pLog->logMessage(
217             " * VET_UBYTE4 vertex element type: "
218             + StringConverter::toString(hasCapability(RSC_VERTEX_FORMAT_UBYTE4), true));
219         pLog->logMessage(
220             " * Infinite far plane projection: "
221             + StringConverter::toString(hasCapability(RSC_INFINITE_FAR_PLANE), true));
222         pLog->logMessage(
223             " * Hardware render-to-texture: "
224             + StringConverter::toString(hasCapability(RSC_HWRENDER_TO_TEXTURE), true));
225         pLog->logMessage(
226             " * Floating point textures: "
227             + StringConverter::toString(hasCapability(RSC_TEXTURE_FLOAT), true));
228         pLog->logMessage(
229             " * Non-power-of-two textures: "
230             + StringConverter::toString(hasCapability(RSC_NON_POWER_OF_2_TEXTURES), true)
231             + (mNonPOW2TexturesLimited ? " (limited)" : ""));
232         pLog->logMessage(
233             " * 1d textures: "
234             + StringConverter::toString(hasCapability(RSC_TEXTURE_1D), true));
235         pLog->logMessage(
236             " * Volume textures: "
237             + StringConverter::toString(hasCapability(RSC_TEXTURE_3D), true));
238         pLog->logMessage(
239             " * Multiple Render Targets: "
240             + StringConverter::toString(mNumMultiRenderTargets));
241         pLog->logMessage(
242             "   - With different bit depths: " + StringConverter::toString(hasCapability(RSC_MRT_DIFFERENT_BIT_DEPTHS), true));
243         pLog->logMessage(
244             " * Point Sprites: "
245             + StringConverter::toString(hasCapability(RSC_POINT_SPRITES), true));
246         pLog->logMessage(
247             " * Wide Lines: "
248             + StringConverter::toString(hasCapability(RSC_WIDE_LINES), true));
249         pLog->logMessage(
250             " * Hardware Gamma: "
251             + StringConverter::toString(hasCapability(RSC_HW_GAMMA), true));
252         pLog->logMessage(
253             " * Extended point parameters: "
254             + StringConverter::toString(hasCapability(RSC_POINT_EXTENDED_PARAMETERS), true));
255         if(hasCapability(RSC_POINT_SPRITES))
256         {
257             pLog->logMessage(
258                 " * Max Point Size: "
259                 + StringConverter::toString(mMaxPointSize));
260         }
261         pLog->logMessage(
262             " * Vertex texture fetch: "
263             + StringConverter::toString(hasCapability(RSC_VERTEX_TEXTURE_FETCH), true));
264         pLog->logMessage(
265              " * Number of texture units: "
266              + StringConverter::toString(mNumTextureUnits));
267         pLog->logMessage(
268              " * Number of vertex attributes: "
269              + StringConverter::toString(mNumVertexAttributes));
270         pLog->logMessage(
271              " * Stencil buffer depth: "
272              + StringConverter::toString(mStencilBufferBitDepth));
273         pLog->logMessage(
274              " * Number of vertex blend matrices: "
275              + StringConverter::toString(mNumVertexBlendMatrices));
276         if (hasCapability(RSC_VERTEX_TEXTURE_FETCH))
277         {
278             pLog->logMessage(
279                 "   - Max vertex textures: "
280                 + StringConverter::toString(mNumVertexTextureUnits));
281             pLog->logMessage(
282                 "   - Vertex textures shared: "
283                 + StringConverter::toString(mVertexTextureUnitsShared, true));
284 
285         }
286         pLog->logMessage(
287             " * Render to Vertex Buffer : "
288             + StringConverter::toString(hasCapability(RSC_HWRENDER_TO_VERTEX_BUFFER), true));
289         pLog->logMessage(
290             " * Hardware Atomic Counters: "
291             + StringConverter::toString(hasCapability(RSC_ATOMIC_COUNTERS), true));
292 
293         if (mCategoryRelevant[CAPS_CATEGORY_GL])
294         {
295             pLog->logMessage(
296                 " * PBuffer support: "
297                 + StringConverter::toString(hasCapability(RSC_PBUFFER), true));
298             pLog->logMessage(
299                 " * Vertex Array Objects: "
300                 + StringConverter::toString(hasCapability(RSC_VAO), true));
301             pLog->logMessage(
302                 " * Separate shader objects: "
303                 + StringConverter::toString(hasCapability(RSC_SEPARATE_SHADER_OBJECTS), true));
304             pLog->logMessage(
305                 " * GLSL SSO redeclare interface block: "
306                 + StringConverter::toString(hasCapability(RSC_GLSL_SSO_REDECLARE), true));
307             pLog->logMessage(
308                 " * Debugging/ profiling events: "
309                 + StringConverter::toString(hasCapability(RSC_DEBUG), true));
310             pLog->logMessage(
311                 " * Map buffer storage: "
312                 + StringConverter::toString(hasCapability(RSC_MAPBUFFER), true));
313         }
314 
315         if (mCategoryRelevant[CAPS_CATEGORY_D3D9])
316         {
317             pLog->logMessage(
318                 " * DirectX per stage constants: "
319                 + StringConverter::toString(hasCapability(RSC_PERSTAGECONSTANT), true));
320             pLog->logMessage(
321                 " * W-Buffer supported: "
322                 + StringConverter::toString(hasCapability(RSC_WBUFFER), true));
323         }
324     }
325     //---------------------------------------------------------------------
326     String RenderSystemCapabilities::msGPUVendorStrings[GPU_VENDOR_COUNT];
327     //---------------------------------------------------------------------
vendorFromString(const String & vendorString)328     GPUVendor RenderSystemCapabilities::vendorFromString(const String& vendorString)
329     {
330         initVendorStrings();
331         GPUVendor ret = GPU_UNKNOWN;
332         String cmpString = vendorString;
333         StringUtil::toLowerCase(cmpString);
334         for (int i = 0; i < GPU_VENDOR_COUNT; ++i)
335         {
336             // case insensitive (lower case)
337             if (msGPUVendorStrings[i] == cmpString)
338             {
339                 ret = static_cast<GPUVendor>(i);
340                 break;
341             }
342         }
343 
344         return ret;
345 
346     }
347     //---------------------------------------------------------------------
vendorToString(GPUVendor v)348     const String& RenderSystemCapabilities::vendorToString(GPUVendor v)
349     {
350         initVendorStrings();
351         return msGPUVendorStrings[v];
352     }
353     //---------------------------------------------------------------------
initVendorStrings()354     void RenderSystemCapabilities::initVendorStrings()
355     {
356         if (msGPUVendorStrings[0].empty())
357         {
358             // Always lower case!
359             msGPUVendorStrings[GPU_UNKNOWN] = "unknown";
360             msGPUVendorStrings[GPU_NVIDIA] = "nvidia";
361             msGPUVendorStrings[GPU_AMD] = "amd";
362             msGPUVendorStrings[GPU_INTEL] = "intel";
363             msGPUVendorStrings[GPU_IMAGINATION_TECHNOLOGIES] = "imagination technologies";
364             msGPUVendorStrings[GPU_APPLE] = "apple";    // iOS Simulator
365             msGPUVendorStrings[GPU_NOKIA] = "nokia";
366             msGPUVendorStrings[GPU_MS_SOFTWARE] = "microsoft"; // Microsoft software device
367             msGPUVendorStrings[GPU_MS_WARP] = "ms warp";
368             msGPUVendorStrings[GPU_ARM] = "arm";
369             msGPUVendorStrings[GPU_QUALCOMM] = "qualcomm";
370             msGPUVendorStrings[GPU_MOZILLA] = "mozilla";
371             msGPUVendorStrings[GPU_WEBKIT] = "webkit";
372         }
373     }
374 
375 }
376