1 | // Copyright 2016 The SwiftShader Authors. All Rights Reserved. |
2 | // |
3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | // you may not use this file except in compliance with the License. |
5 | // You may obtain a copy of the License at |
6 | // |
7 | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | // |
9 | // Unless required by applicable law or agreed to in writing, software |
10 | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | // See the License for the specific language governing permissions and |
13 | // limitations under the License. |
14 | |
15 | #include "SwiftConfig.hpp" |
16 | |
17 | #include "Config.hpp" |
18 | #include "Common/Configurator.hpp" |
19 | #include "Common/Debug.hpp" |
20 | #include "Common/Version.h" |
21 | |
22 | #include <sstream> |
23 | #include <stdio.h> |
24 | #include <time.h> |
25 | #include <sys/stat.h> |
26 | #include <string.h> |
27 | #include <algorithm> |
28 | |
29 | namespace sw |
30 | { |
31 | extern Profiler profiler; |
32 | |
33 | std::string itoa(int number) |
34 | { |
35 | std::stringstream ss; |
36 | ss << number; |
37 | return ss.str(); |
38 | } |
39 | |
40 | std::string ftoa(double number) |
41 | { |
42 | std::stringstream ss; |
43 | ss << number; |
44 | return ss.str(); |
45 | } |
46 | |
47 | SwiftConfig::SwiftConfig(bool disableServerOverride) : listenSocket(0) |
48 | { |
49 | readConfiguration(disableServerOverride); |
50 | |
51 | if(!disableServerOverride) |
52 | { |
53 | writeConfiguration(); |
54 | } |
55 | |
56 | receiveBuffer = 0; |
57 | |
58 | if(!config.disableServer) |
59 | { |
60 | createServer(); |
61 | } |
62 | } |
63 | |
64 | SwiftConfig::~SwiftConfig() |
65 | { |
66 | destroyServer(); |
67 | } |
68 | |
69 | void SwiftConfig::createServer() |
70 | { |
71 | bufferLength = 16 * 1024; |
72 | receiveBuffer = new char[bufferLength]; |
73 | |
74 | Socket::startup(); |
75 | listenSocket = new Socket("localhost" , "8080" ); |
76 | listenSocket->listen(); |
77 | |
78 | terminate = false; |
79 | serverThread = new Thread(serverRoutine, this); |
80 | } |
81 | |
82 | void SwiftConfig::destroyServer() |
83 | { |
84 | if(receiveBuffer) |
85 | { |
86 | terminate = true; |
87 | serverThread->join(); |
88 | delete serverThread; |
89 | |
90 | delete listenSocket; |
91 | listenSocket = 0; |
92 | |
93 | Socket::cleanup(); |
94 | |
95 | delete[] receiveBuffer; |
96 | receiveBuffer = 0; |
97 | } |
98 | } |
99 | |
100 | bool SwiftConfig::hasNewConfiguration(bool reset) |
101 | { |
102 | bool value = newConfig; |
103 | |
104 | if(reset) |
105 | { |
106 | newConfig = false; |
107 | } |
108 | |
109 | return value; |
110 | } |
111 | |
112 | void SwiftConfig::getConfiguration(Configuration &configuration) |
113 | { |
114 | criticalSection.lock(); |
115 | configuration = config; |
116 | criticalSection.unlock(); |
117 | } |
118 | |
119 | void SwiftConfig::serverRoutine(void *parameters) |
120 | { |
121 | SwiftConfig *swiftConfig = (SwiftConfig*)parameters; |
122 | |
123 | swiftConfig->serverLoop(); |
124 | } |
125 | |
126 | void SwiftConfig::serverLoop() |
127 | { |
128 | readConfiguration(); |
129 | |
130 | while(!terminate) |
131 | { |
132 | if(listenSocket->select(100000)) |
133 | { |
134 | Socket *clientSocket = listenSocket->accept(); |
135 | int bytesReceived = 1; |
136 | |
137 | while(bytesReceived > 0 && !terminate) |
138 | { |
139 | if(clientSocket->select(10)) |
140 | { |
141 | bytesReceived = clientSocket->receive(receiveBuffer, bufferLength); |
142 | |
143 | if(bytesReceived > 0) |
144 | { |
145 | receiveBuffer[bytesReceived] = 0; |
146 | |
147 | respond(clientSocket, receiveBuffer); |
148 | } |
149 | } |
150 | } |
151 | |
152 | delete clientSocket; |
153 | } |
154 | } |
155 | } |
156 | |
157 | bool match(const char **url, const char *string) |
158 | { |
159 | size_t length = strlen(string); |
160 | |
161 | if(strncmp(*url, string, length) == 0) |
162 | { |
163 | *url += length; |
164 | |
165 | return true; |
166 | } |
167 | |
168 | return false; |
169 | } |
170 | |
171 | void SwiftConfig::respond(Socket *clientSocket, const char *request) |
172 | { |
173 | if(match(&request, "GET /" )) |
174 | { |
175 | if(match(&request, "swiftshader" ) || match(&request, "swiftconfig" )) |
176 | { |
177 | if(match(&request, " " ) || match(&request, "/ " )) |
178 | { |
179 | return send(clientSocket, OK, page()); |
180 | } |
181 | } |
182 | } |
183 | else if(match(&request, "POST /" )) |
184 | { |
185 | if(match(&request, "swiftshader" ) || match(&request, "swiftconfig" )) |
186 | { |
187 | if(match(&request, " " ) || match(&request, "/ " )) |
188 | { |
189 | criticalSection.lock(); |
190 | |
191 | const char *postData = strstr(request, "\r\n\r\n" ); |
192 | postData = postData ? postData + 4 : 0; |
193 | |
194 | if(postData && strlen(postData) > 0) |
195 | { |
196 | parsePost(postData); |
197 | } |
198 | else // POST data in next packet |
199 | { |
200 | int bytesReceived = clientSocket->receive(receiveBuffer, bufferLength); |
201 | |
202 | if(bytesReceived > 0) |
203 | { |
204 | receiveBuffer[bytesReceived] = 0; |
205 | parsePost(receiveBuffer); |
206 | } |
207 | } |
208 | |
209 | writeConfiguration(); |
210 | newConfig = true; |
211 | |
212 | if(config.disableServer) |
213 | { |
214 | destroyServer(); |
215 | } |
216 | |
217 | criticalSection.unlock(); |
218 | |
219 | return send(clientSocket, OK, page()); |
220 | } |
221 | else if(match(&request, "/profile " )) |
222 | { |
223 | return send(clientSocket, OK, profile()); |
224 | } |
225 | } |
226 | } |
227 | |
228 | return send(clientSocket, NotFound); |
229 | } |
230 | |
231 | std::string SwiftConfig::page() |
232 | { |
233 | std::string html; |
234 | |
235 | const std::string selected = "selected='selected'" ; |
236 | const std::string checked = "checked='checked'" ; |
237 | const std::string empty = "" ; |
238 | |
239 | html += "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'>\n" ; |
240 | html += "<html>\n" ; |
241 | html += "<head>\n" ; |
242 | html += "<meta http-equiv='content-type' content='text/html; charset=UTF-8'>\n" ; |
243 | html += "<title>SwiftShader Configuration Panel</title>\n" ; |
244 | html += "</head>\n" ; |
245 | html += "<body>\n" ; |
246 | html += "<script type='text/javascript'>\n" ; |
247 | html += "request();\n" ; |
248 | html += "function request()\n" ; |
249 | html += "{\n" ; |
250 | html += "var xhr = new XMLHttpRequest();\n" ; |
251 | html += "xhr.open('POST', '/swiftshader/profile', true);\n" ; |
252 | html += "xhr.onreadystatechange = function()\n" ; |
253 | html += "{\n" ; |
254 | html += "if(xhr.readyState == 4 && xhr.status == 200)\n" ; |
255 | html += "{\n" ; |
256 | html += "document.getElementById('profile').innerHTML = xhr.responseText;\n" ; |
257 | html += "setTimeout('request()', 1000);\n" ; |
258 | html += "}\n" ; |
259 | html += "}\n" ; |
260 | html += "xhr.send();\n" ; |
261 | html += "}\n" ; |
262 | html += "</script>\n" ; |
263 | html += "<form method='POST' action=''>\n" ; |
264 | html += "<h1>SwiftShader Configuration Panel</h1>\n" ; |
265 | html += "<div id='profile'>" + profile() + "</div>\n" ; |
266 | html += "<hr><p>\n" ; |
267 | html += "<input type='submit' value='Apply changes' title='Click to apply all settings.'>\n" ; |
268 | // html += "<input type='reset' value='Reset changes' title='Click to reset your changes to the previous value.'>\n"; |
269 | html += "</p><hr>\n" ; |
270 | html += "<h2><em>Device capabilities</em></h2>\n" ; |
271 | html += "<table>\n" ; |
272 | html += "<tr><td>Build revision:</td><td>" REVISION_STRING "</td></tr>\n" ; |
273 | html += "<tr><td>Pixel shader model:</td><td><select name='pixelShaderVersion' title='The highest version of pixel shader supported by SwiftShader. Lower versions might be faster if supported by the application. Only effective after restarting the application.'>\n" ; |
274 | html += "<option value='0'" + (config.pixelShaderVersion == 0 ? selected : empty) + ">0.0</option>\n" ; |
275 | html += "<option value='11'" + (config.pixelShaderVersion == 11 ? selected : empty) + ">1.1</option>\n" ; |
276 | html += "<option value='12'" + (config.pixelShaderVersion == 12 ? selected : empty) + ">1.2</option>\n" ; |
277 | html += "<option value='13'" + (config.pixelShaderVersion == 13 ? selected : empty) + ">1.3</option>\n" ; |
278 | html += "<option value='14'" + (config.pixelShaderVersion == 14 ? selected : empty) + ">1.4</option>\n" ; |
279 | html += "<option value='20'" + (config.pixelShaderVersion == 20 ? selected : empty) + ">2.0</option>\n" ; |
280 | html += "<option value='21'" + (config.pixelShaderVersion == 21 ? selected : empty) + ">2.x</option>\n" ; |
281 | html += "<option value='30'" + (config.pixelShaderVersion == 30 ? selected : empty) + ">3.0 (default)</option>\n" ; |
282 | html += "</select></td></tr>\n" ; |
283 | html += "<tr><td>Vertex shader model:</td><td><select name='vertexShaderVersion' title='The highest version of vertex shader supported by SwiftShader. Lower versions might be faster if supported by the application. Only effective after restarting the application.'>\n" ; |
284 | html += "<option value='0'" + (config.vertexShaderVersion == 0 ? selected : empty) + ">0.0</option>\n" ; |
285 | html += "<option value='11'" + (config.vertexShaderVersion == 11 ? selected : empty) + ">1.1</option>\n" ; |
286 | html += "<option value='20'" + (config.vertexShaderVersion == 20 ? selected : empty) + ">2.0</option>\n" ; |
287 | html += "<option value='21'" + (config.vertexShaderVersion == 21 ? selected : empty) + ">2.x</option>\n" ; |
288 | html += "<option value='30'" + (config.vertexShaderVersion == 30 ? selected : empty) + ">3.0 (default)</option>\n" ; |
289 | html += "</select></td></tr>\n" ; |
290 | html += "<tr><td>Texture memory:</td><td><select name='textureMemory' title='The maximum amount of memory used for textures and other resources.'>\n" ; |
291 | html += "<option value='128'" + (config.textureMemory == 128 ? selected : empty) + ">128 MB</option>\n" ; |
292 | html += "<option value='256'" + (config.textureMemory == 256 ? selected : empty) + ">256 MB (default)</option>\n" ; |
293 | html += "<option value='512'" + (config.textureMemory == 512 ? selected : empty) + ">512 MB</option>\n" ; |
294 | html += "<option value='1024'" + (config.textureMemory == 1024 ? selected : empty) + ">1024 MB</option>\n" ; |
295 | html += "<option value='2048'" + (config.textureMemory == 2048 ? selected : empty) + ">2048 MB</option>\n" ; |
296 | html += "</select></td></tr>\n" ; |
297 | html += "<tr><td>Device identifier:</td><td><select name='identifier' title='The information used by some applications to determine device capabilities.'>\n" ; |
298 | html += "<option value='0'" + (config.identifier == 0 ? selected : empty) + ">Google SwiftShader (default)</option>\n" ; |
299 | html += "<option value='1'" + (config.identifier == 1 ? selected : empty) + ">NVIDIA GeForce 7900 GS</option>\n" ; |
300 | html += "<option value='2'" + (config.identifier == 2 ? selected : empty) + ">ATI Mobility Radeon X1600</option>\n" ; |
301 | html += "<option value='3'" + (config.identifier == 3 ? selected : empty) + ">Intel GMA X3100</option>\n" ; |
302 | html += "<option value='4'" + (config.identifier == 4 ? selected : empty) + ">System device</option>\n" ; |
303 | html += "</select></td></tr>\n" ; |
304 | html += "</table>\n" ; |
305 | html += "<h2><em>Cache sizes</em></h2>\n" ; |
306 | html += "<table>\n" ; |
307 | html += "<tr><td>Vertex routine cache size:</td><td><select name='vertexRoutineCacheSize' title='The number of dynamically generated vertex processing routines being cached for reuse. Lower numbers save memory but require more routines to be regenerated.'>\n" ; |
308 | html += "<option value='64'" + (config.vertexRoutineCacheSize == 64 ? selected : empty) + ">64</option>\n" ; |
309 | html += "<option value='128'" + (config.vertexRoutineCacheSize == 128 ? selected : empty) + ">128</option>\n" ; |
310 | html += "<option value='256'" + (config.vertexRoutineCacheSize == 256 ? selected : empty) + ">256</option>\n" ; |
311 | html += "<option value='512'" + (config.vertexRoutineCacheSize == 512 ? selected : empty) + ">512</option>\n" ; |
312 | html += "<option value='1024'" + (config.vertexRoutineCacheSize == 1024 ? selected : empty) + ">1024 (default)</option>\n" ; |
313 | html += "<option value='2048'" + (config.vertexRoutineCacheSize == 2048 ? selected : empty) + ">2048</option>\n" ; |
314 | html += "<option value='4096'" + (config.vertexRoutineCacheSize == 4096 ? selected : empty) + ">4096</option>\n" ; |
315 | html += "</select></td>\n" ; |
316 | html += "</tr>\n" ; |
317 | html += "<tr><td>Pixel routine cache size:</td><td><select name='pixelRoutineCacheSize' title='The number of dynamically generated pixel processing routines being cached for reuse. Lower numbers save memory but require more routines to be regenerated.'>\n" ; |
318 | html += "<option value='64'" + (config.pixelRoutineCacheSize == 64 ? selected : empty) + ">64</option>\n" ; |
319 | html += "<option value='128'" + (config.pixelRoutineCacheSize == 128 ? selected : empty) + ">128</option>\n" ; |
320 | html += "<option value='256'" + (config.pixelRoutineCacheSize == 256 ? selected : empty) + ">256</option>\n" ; |
321 | html += "<option value='512'" + (config.pixelRoutineCacheSize == 512 ? selected : empty) + ">512</option>\n" ; |
322 | html += "<option value='1024'" + (config.pixelRoutineCacheSize == 1024 ? selected : empty) + ">1024 (default)</option>\n" ; |
323 | html += "<option value='2048'" + (config.pixelRoutineCacheSize == 2048 ? selected : empty) + ">2048</option>\n" ; |
324 | html += "<option value='4096'" + (config.pixelRoutineCacheSize == 4096 ? selected : empty) + ">4096</option>\n" ; |
325 | html += "</select></td>\n" ; |
326 | html += "</tr>\n" ; |
327 | html += "<tr><td>Setup routine cache size:</td><td><select name='setupRoutineCacheSize' title='The number of dynamically generated primitive setup routines being cached for reuse. Lower numbers save memory but require more routines to be regenerated.'>\n" ; |
328 | html += "<option value='64'" + (config.setupRoutineCacheSize == 64 ? selected : empty) + ">64</option>\n" ; |
329 | html += "<option value='128'" + (config.setupRoutineCacheSize == 128 ? selected : empty) + ">128</option>\n" ; |
330 | html += "<option value='256'" + (config.setupRoutineCacheSize == 256 ? selected : empty) + ">256</option>\n" ; |
331 | html += "<option value='512'" + (config.setupRoutineCacheSize == 512 ? selected : empty) + ">512</option>\n" ; |
332 | html += "<option value='1024'" + (config.setupRoutineCacheSize == 1024 ? selected : empty) + ">1024 (default)</option>\n" ; |
333 | html += "<option value='2048'" + (config.setupRoutineCacheSize == 2048 ? selected : empty) + ">2048</option>\n" ; |
334 | html += "<option value='4096'" + (config.setupRoutineCacheSize == 4096 ? selected : empty) + ">4096</option>\n" ; |
335 | html += "</select></td>\n" ; |
336 | html += "</tr>\n" ; |
337 | html += "<tr><td>Vertex cache size:</td><td><select name='vertexCacheSize' title='The number of processed vertices being cached for reuse. Lower numbers save memory but require more vertices to be reprocessed.'>\n" ; |
338 | html += "<option value='64'" + (config.vertexCacheSize == 64 ? selected : empty) + ">64 (default)</option>\n" ; |
339 | html += "</select></td>\n" ; |
340 | html += "</tr>\n" ; |
341 | html += "</table>\n" ; |
342 | html += "<h2><em>Quality</em></h2>\n" ; |
343 | html += "<table>\n" ; |
344 | html += "<tr><td>Maximum texture sampling quality:</td><td><select name='textureSampleQuality' title='The maximum texture filtering quality. Lower settings can be faster but cause visual artifacts.'>\n" ; |
345 | html += "<option value='0'" + (config.textureSampleQuality == 0 ? selected : empty) + ">Point</option>\n" ; |
346 | html += "<option value='1'" + (config.textureSampleQuality == 1 ? selected : empty) + ">Linear</option>\n" ; |
347 | html += "<option value='2'" + (config.textureSampleQuality == 2 ? selected : empty) + ">Anisotropic (default)</option>\n" ; |
348 | html += "</select></td>\n" ; |
349 | html += "</tr>\n" ; |
350 | html += "<tr><td>Maximum mipmapping quality:</td><td><select name='mipmapQuality' title='The maximum mipmap filtering quality. Higher settings can be more visually appealing but are slower.'>\n" ; |
351 | html += "<option value='0'" + (config.mipmapQuality == 0 ? selected : empty) + ">Point</option>\n" ; |
352 | html += "<option value='1'" + (config.mipmapQuality == 1 ? selected : empty) + ">Linear (default)</option>\n" ; |
353 | html += "</select></td>\n" ; |
354 | html += "</tr>\n" ; |
355 | html += "<tr><td>Perspective correction:</td><td><select name='perspectiveCorrection' title='Enables or disables perspective correction. Disabling it is faster but can causes distortion. Recommended for 2D applications only.'>\n" ; |
356 | html += "<option value='0'" + (config.perspectiveCorrection == 0 ? selected : empty) + ">Off</option>\n" ; |
357 | html += "<option value='1'" + (config.perspectiveCorrection == 1 ? selected : empty) + ">On (default)</option>\n" ; |
358 | html += "</select></td>\n" ; |
359 | html += "</tr>\n" ; |
360 | html += "<tr><td>Transcendental function precision:</td><td><select name='transcendentalPrecision' title='The precision at which log/exp/pow/rcp/rsq/nrm shader instructions are computed. Lower settings can be faster but cause visual artifacts.'>\n" ; |
361 | html += "<option value='0'" + (config.transcendentalPrecision == 0 ? selected : empty) + ">Approximate</option>\n" ; |
362 | html += "<option value='1'" + (config.transcendentalPrecision == 1 ? selected : empty) + ">Partial</option>\n" ; |
363 | html += "<option value='2'" + (config.transcendentalPrecision == 2 ? selected : empty) + ">Accurate (default)</option>\n" ; |
364 | html += "<option value='3'" + (config.transcendentalPrecision == 3 ? selected : empty) + ">WHQL</option>\n" ; |
365 | html += "<option value='4'" + (config.transcendentalPrecision == 4 ? selected : empty) + ">IEEE</option>\n" ; |
366 | html += "</select></td>\n" ; |
367 | html += "</tr>\n" ; |
368 | html += "<tr><td>Transparency anti-aliasing:</td><td><select name='transparencyAntialiasing' title='The technique used to anti-alias alpha-tested transparent textures.'>\n" ; |
369 | html += "<option value='0'" + (config.transparencyAntialiasing == 0 ? selected : empty) + ">None (default)</option>\n" ; |
370 | html += "<option value='1'" + (config.transparencyAntialiasing == 1 ? selected : empty) + ">Alpha-to-Coverage</option>\n" ; |
371 | html += "</select></td>\n" ; |
372 | html += "</table>\n" ; |
373 | html += "<h2><em>Processor settings</em></h2>\n" ; |
374 | html += "<table>\n" ; |
375 | html += "<tr><td>Number of threads:</td><td><select name='threadCount' title='The number of rendering threads to be used.'>\n" ; |
376 | html += "<option value='-1'" + (config.threadCount == -1 ? selected : empty) + ">Core count</option>\n" ; |
377 | html += "<option value='0'" + (config.threadCount == 0 ? selected : empty) + ">Process affinity (default)</option>\n" ; |
378 | html += "<option value='1'" + (config.threadCount == 1 ? selected : empty) + ">1</option>\n" ; |
379 | html += "<option value='2'" + (config.threadCount == 2 ? selected : empty) + ">2</option>\n" ; |
380 | html += "<option value='3'" + (config.threadCount == 3 ? selected : empty) + ">3</option>\n" ; |
381 | html += "<option value='4'" + (config.threadCount == 4 ? selected : empty) + ">4</option>\n" ; |
382 | html += "<option value='5'" + (config.threadCount == 5 ? selected : empty) + ">5</option>\n" ; |
383 | html += "<option value='6'" + (config.threadCount == 6 ? selected : empty) + ">6</option>\n" ; |
384 | html += "<option value='7'" + (config.threadCount == 7 ? selected : empty) + ">7</option>\n" ; |
385 | html += "<option value='8'" + (config.threadCount == 8 ? selected : empty) + ">8</option>\n" ; |
386 | html += "<option value='9'" + (config.threadCount == 9 ? selected : empty) + ">9</option>\n" ; |
387 | html += "<option value='10'" + (config.threadCount == 10 ? selected : empty) + ">10</option>\n" ; |
388 | html += "<option value='11'" + (config.threadCount == 11 ? selected : empty) + ">11</option>\n" ; |
389 | html += "<option value='12'" + (config.threadCount == 12 ? selected : empty) + ">12</option>\n" ; |
390 | html += "<option value='13'" + (config.threadCount == 13 ? selected : empty) + ">13</option>\n" ; |
391 | html += "<option value='14'" + (config.threadCount == 14 ? selected : empty) + ">14</option>\n" ; |
392 | html += "<option value='15'" + (config.threadCount == 15 ? selected : empty) + ">15</option>\n" ; |
393 | html += "<option value='16'" + (config.threadCount == 16 ? selected : empty) + ">16</option>\n" ; |
394 | html += "</select></td></tr>\n" ; |
395 | html += "<tr><td>Enable SSE:</td><td><input name = 'enableSSE' type='checkbox'" + (config.enableSSE ? checked : empty) + " disabled='disabled' title='If checked enables the use of SSE instruction set extentions if supported by the CPU.'></td></tr>" ; |
396 | html += "<tr><td>Enable SSE2:</td><td><input name = 'enableSSE2' type='checkbox'" + (config.enableSSE2 ? checked : empty) + " title='If checked enables the use of SSE2 instruction set extentions if supported by the CPU.'></td></tr>" ; |
397 | html += "<tr><td>Enable SSE3:</td><td><input name = 'enableSSE3' type='checkbox'" + (config.enableSSE3 ? checked : empty) + " title='If checked enables the use of SSE3 instruction set extentions if supported by the CPU.'></td></tr>" ; |
398 | html += "<tr><td>Enable SSSE3:</td><td><input name = 'enableSSSE3' type='checkbox'" + (config.enableSSSE3 ? checked : empty) + " title='If checked enables the use of SSSE3 instruction set extentions if supported by the CPU.'></td></tr>" ; |
399 | html += "<tr><td>Enable SSE4.1:</td><td><input name = 'enableSSE4_1' type='checkbox'" + (config.enableSSE4_1 ? checked : empty) + " title='If checked enables the use of SSE4.1 instruction set extentions if supported by the CPU.'></td></tr>" ; |
400 | html += "</table>\n" ; |
401 | html += "<h2><em>Compiler optimizations</em></h2>\n" ; |
402 | html += "<table>\n" ; |
403 | |
404 | for(size_t pass = 0; pass < config.optimization.size(); pass++) |
405 | { |
406 | html += "<tr><td>Optimization pass " + itoa(pass + 1) + ":</td><td><select name='optimization" + itoa(pass + 1) + "' title='An optimization pass for the shader compiler.'>\n" ; |
407 | html += "<option value='0'" + (config.optimization[pass] == rr::Optimization::Pass::Disabled ? selected : empty) + ">Disabled" + (pass > 0 ? " (default)" : "" ) + "</option>\n" ; |
408 | html += "<option value='1'" + (config.optimization[pass] == rr::Optimization::Pass::InstructionCombining ? selected : empty) + ">Instruction Combining" + (pass == 0 ? " (default)" : "" ) + "</option>\n" ; |
409 | html += "<option value='2'" + (config.optimization[pass] == rr::Optimization::Pass::CFGSimplification ? selected : empty) + ">Control Flow Simplification</option>\n" ; |
410 | html += "<option value='3'" + (config.optimization[pass] == rr::Optimization::Pass::LICM ? selected : empty) + ">Loop Invariant Code Motion</option>\n" ; |
411 | html += "<option value='4'" + (config.optimization[pass] == rr::Optimization::Pass::AggressiveDCE ? selected : empty) + ">Aggressive Dead Code Elimination</option>\n" ; |
412 | html += "<option value='5'" + (config.optimization[pass] == rr::Optimization::Pass::GVN ? selected : empty) + ">Global Value Numbering</option>\n" ; |
413 | html += "<option value='6'" + (config.optimization[pass] == rr::Optimization::Pass::Reassociate ? selected : empty) + ">Commutative Expressions Reassociation</option>\n" ; |
414 | html += "<option value='7'" + (config.optimization[pass] == rr::Optimization::Pass::DeadStoreElimination ? selected : empty) + ">Dead Store Elimination</option>\n" ; |
415 | html += "<option value='8'" + (config.optimization[pass] == rr::Optimization::Pass::SCCP ? selected : empty) + ">Sparse Conditional Copy Propagation</option>\n" ; |
416 | html += "<option value='9'" + (config.optimization[pass] == rr::Optimization::Pass::ScalarReplAggregates ? selected : empty) + ">Scalar Replacement of Aggregates</option>\n" ; |
417 | html += "<option value='10'" + (config.optimization[pass] == rr::Optimization::Pass::EarlyCSEPass ? selected : empty) + ">Eliminate trivially redundant instructions</option>\n" ; |
418 | html += "</select></td></tr>\n" ; |
419 | } |
420 | |
421 | html += "</table>\n" ; |
422 | html += "<h2><em>Testing & Experimental</em></h2>\n" ; |
423 | html += "<table>\n" ; |
424 | html += "<tr><td>Disable SwiftConfig server:</td><td><input name = 'disableServer' type='checkbox'" + (config.disableServer == true ? checked : empty) + " title='If checked disables the web browser based control panel.'></td></tr>" ; |
425 | html += "<tr><td>Force windowed mode:</td><td><input name = 'forceWindowed' type='checkbox'" + (config.forceWindowed == true ? checked : empty) + " title='If checked prevents the application from switching to full-screen mode.'></td></tr>" ; |
426 | html += "<tr><td>Complementary depth buffer:</td><td><input name = 'complementaryDepthBuffer' type='checkbox'" + (config.complementaryDepthBuffer == true ? checked : empty) + " title='If checked causes 1 - z to be stored in the depth buffer.'></td></tr>" ; |
427 | html += "<tr><td>Post alpha blend sRGB conversion:</td><td><input name = 'postBlendSRGB' type='checkbox'" + (config.postBlendSRGB == true ? checked : empty) + " title='If checked alpha blending is performed in linear color space.'></td></tr>" ; |
428 | html += "<tr><td>Exact color rounding:</td><td><input name = 'exactColorRounding' type='checkbox'" + (config.exactColorRounding == true ? checked : empty) + " title='If checked color rounding is done at high accuracy.'></td></tr>" ; |
429 | html += "<tr><td>Disable alpha display formats:</td><td><input name = 'disableAlphaMode' type='checkbox'" + (config.disableAlphaMode == true ? checked : empty) + " title='If checked the device does not advertise the A8R8G8B8 display mode.'></td></tr>" ; |
430 | html += "<tr><td>Disable 10-bit display formats:</td><td><input name = 'disable10BitMode' type='checkbox'" + (config.disable10BitMode == true ? checked : empty) + " title='If checked the device does not advertise the A2R10G10B10 display mode.'></td></tr>" ; |
431 | html += "<tr><td>Frame-buffer API:</td><td><select name='frameBufferAPI' title='The API used for displaying the rendered result on screen (requires restart).'>\n" ; |
432 | html += "<option value='0'" + (config.frameBufferAPI == 0 ? selected : empty) + ">DirectDraw (default)</option>\n" ; |
433 | html += "<option value='1'" + (config.frameBufferAPI == 1 ? selected : empty) + ">GDI</option>\n" ; |
434 | html += "</select></td>\n" ; |
435 | html += "<tr><td>DLL precaching:</td><td><input name = 'precache' type='checkbox'" + (config.precache == true ? checked : empty) + " title='If checked dynamically generated routines will be stored in a DLL for faster loading on application restart.'></td></tr>" ; |
436 | html += "<tr><td>Shadow mapping extensions:</td><td><select name='shadowMapping' title='Features that may accelerate or improve the quality of shadow mapping.'>\n" ; |
437 | html += "<option value='0'" + (config.shadowMapping == 0 ? selected : empty) + ">None</option>\n" ; |
438 | html += "<option value='1'" + (config.shadowMapping == 1 ? selected : empty) + ">Fetch4</option>\n" ; |
439 | html += "<option value='2'" + (config.shadowMapping == 2 ? selected : empty) + ">DST</option>\n" ; |
440 | html += "<option value='3'" + (config.shadowMapping == 3 ? selected : empty) + ">Fetch4 & DST (default)</option>\n" ; |
441 | html += "</select></td>\n" ; |
442 | html += "<tr><td>Force clearing registers that have no default value:</td><td><input name = 'forceClearRegisters' type='checkbox'" + (config.forceClearRegisters == true ? checked : empty) + " title='Initializes shader register values to 0 even if they have no default.'></td></tr>" ; |
443 | html += "</table>\n" ; |
444 | #ifndef NDEBUG |
445 | html += "<h2><em>Debugging</em></h2>\n" ; |
446 | html += "<table>\n" ; |
447 | html += "<tr><td>Minimum primitives:</td><td><input type='text' size='10' maxlength='10' name='minPrimitives' value='" + itoa(config.minPrimitives) + "'></td></tr>\n" ; |
448 | html += "<tr><td>Maximum primitives:</td><td><input type='text' size='10' maxlength='10' name='maxPrimitives' value='" + itoa(config.maxPrimitives) + "'></td></tr>\n" ; |
449 | html += "</table>\n" ; |
450 | #endif |
451 | html += "<hr><p>\n" ; |
452 | html += "<span style='font-size:10pt'>Hover the mouse pointer over a control to get additional information.</span><br>\n" ; |
453 | html += "<span style='font-size:10pt'>Some settings can be applied interactively, some need a restart of the application.</span><br>\n" ; |
454 | html += "<span style='font-size:10pt'>Removing the SwiftShader.ini file results in resetting the options to their default.</span></p>\n" ; |
455 | html += "</form>\n" ; |
456 | html += "</body>\n" ; |
457 | html += "</html>\n" ; |
458 | |
459 | profiler.reset(); |
460 | |
461 | return html; |
462 | } |
463 | |
464 | std::string SwiftConfig::profile() |
465 | { |
466 | std::string html; |
467 | |
468 | html += "<p>FPS: " + ftoa(profiler.FPS) + "</p>\n" ; |
469 | html += "<p>Frame: " + itoa(profiler.framesTotal) + "</p>\n" ; |
470 | |
471 | #if PERF_PROFILE |
472 | int texTime = (int)(1000 * profiler.cycles[PERF_TEX] / profiler.cycles[PERF_PIXEL] + 0.5); |
473 | int shaderTime = (int)(1000 * profiler.cycles[PERF_SHADER] / profiler.cycles[PERF_PIXEL] + 0.5); |
474 | int pipeTime = (int)(1000 * profiler.cycles[PERF_PIPE] / profiler.cycles[PERF_PIXEL] + 0.5); |
475 | int ropTime = (int)(1000 * profiler.cycles[PERF_ROP] / profiler.cycles[PERF_PIXEL] + 0.5); |
476 | int interpTime = (int)(1000 * profiler.cycles[PERF_INTERP] / profiler.cycles[PERF_PIXEL] + 0.5); |
477 | int rastTime = 1000 - pipeTime; |
478 | |
479 | pipeTime -= shaderTime + ropTime + interpTime; |
480 | shaderTime -= texTime; |
481 | |
482 | double texTimeF = (double)texTime / 10; |
483 | double shaderTimeF = (double)shaderTime / 10; |
484 | double pipeTimeF = (double)pipeTime / 10; |
485 | double ropTimeF = (double)ropTime / 10; |
486 | double interpTimeF = (double)interpTime / 10; |
487 | double rastTimeF = (double)rastTime / 10; |
488 | |
489 | double averageRopOperations = profiler.ropOperationsTotal / std::max(profiler.framesTotal, 1) / 1.0e6f; |
490 | double averageCompressedTex = profiler.compressedTexTotal / std::max(profiler.framesTotal, 1) / 1.0e6f; |
491 | double averageTexOperations = profiler.texOperationsTotal / std::max(profiler.framesTotal, 1) / 1.0e6f; |
492 | |
493 | html += "<p>Raster operations (million): " + ftoa(profiler.ropOperationsFrame / 1.0e6f) + " (current), " + ftoa(averageRopOperations) + " (average)</p>\n" ; |
494 | html += "<p>Texture operations (million): " + ftoa(profiler.texOperationsFrame / 1.0e6f) + " (current), " + ftoa(averageTexOperations) + " (average)</p>\n" ; |
495 | html += "<p>Compressed texture operations (million): " + ftoa(profiler.compressedTexFrame / 1.0e6f) + " (current), " + ftoa(averageCompressedTex) + " (average)</p>\n" ; |
496 | html += "<div id='profile' style='position:relative; width:1010px; height:50px; background-color:silver;'>" ; |
497 | html += "<div style='position:relative; width:1000px; height:40px; background-color:white; left:5px; top:5px;'>" ; |
498 | html += "<div style='position:relative; float:left; width:" + itoa(rastTime) + "px; height:40px; border-style:none; text-align:center; line-height:40px; background-color:#FFFF7F; overflow:hidden;'>" + ftoa(rastTimeF) + "% rast</div>\n" ; |
499 | html += "<div style='position:relative; float:left; width:" + itoa(pipeTime) + "px; height:40px; border-style:none; text-align:center; line-height:40px; background-color:#FF7F7F; overflow:hidden;'>" + ftoa(pipeTimeF) + "% pipe</div>\n" ; |
500 | html += "<div style='position:relative; float:left; width:" + itoa(interpTime) + "px; height:40px; border-style:none; text-align:center; line-height:40px; background-color:#7FFFFF; overflow:hidden;'>" + ftoa(interpTimeF) + "% interp</div>\n" ; |
501 | html += "<div style='position:relative; float:left; width:" + itoa(shaderTime) + "px; height:40px; border-style:none; text-align:center; line-height:40px; background-color:#7FFF7F; overflow:hidden;'>" + ftoa(shaderTimeF) + "% shader</div>\n" ; |
502 | html += "<div style='position:relative; float:left; width:" + itoa(texTime) + "px; height:40px; border-style:none; text-align:center; line-height:40px; background-color:#FF7FFF; overflow:hidden;'>" + ftoa(texTimeF) + "% tex</div>\n" ; |
503 | html += "<div style='position:relative; float:left; width:" + itoa(ropTime) + "px; height:40px; border-style:none; text-align:center; line-height:40px; background-color:#7F7FFF; overflow:hidden;'>" + ftoa(ropTimeF) + "% rop</div>\n" ; |
504 | html += "</div></div>\n" ; |
505 | |
506 | for(int i = 0; i < PERF_TIMERS; i++) |
507 | { |
508 | profiler.cycles[i] = 0; |
509 | } |
510 | #endif |
511 | |
512 | return html; |
513 | } |
514 | |
515 | void SwiftConfig::send(Socket *clientSocket, Status code, std::string body) |
516 | { |
517 | std::string status; |
518 | char [1024]; |
519 | |
520 | switch(code) |
521 | { |
522 | case OK: status += "HTTP/1.1 200 OK\r\n" ; break; |
523 | case NotFound: status += "HTTP/1.1 404 Not Found\r\n" ; break; |
524 | } |
525 | |
526 | sprintf(header, "Content-Type: text/html; charset=UTF-8\r\n" |
527 | "Content-Length: %zd\r\n" |
528 | "Host: localhost\r\n" |
529 | "\r\n" , body.size()); |
530 | |
531 | std::string message = status + header + body; |
532 | clientSocket->send(message.c_str(), (int)message.length()); |
533 | } |
534 | |
535 | void SwiftConfig::parsePost(const char *post) |
536 | { |
537 | // Only enabled checkboxes appear in the POST |
538 | config.enableSSE = true; |
539 | config.enableSSE2 = false; |
540 | config.enableSSE3 = false; |
541 | config.enableSSSE3 = false; |
542 | config.enableSSE4_1 = false; |
543 | config.disableServer = false; |
544 | config.forceWindowed = false; |
545 | config.complementaryDepthBuffer = false; |
546 | config.postBlendSRGB = false; |
547 | config.exactColorRounding = false; |
548 | config.disableAlphaMode = false; |
549 | config.disable10BitMode = false; |
550 | config.precache = false; |
551 | config.forceClearRegisters = false; |
552 | |
553 | while(*post != 0) |
554 | { |
555 | int integer; |
556 | int index; |
557 | |
558 | if(sscanf(post, "pixelShaderVersion=%d" , &integer)) |
559 | { |
560 | config.pixelShaderVersion = integer; |
561 | } |
562 | else if(sscanf(post, "vertexShaderVersion=%d" , &integer)) |
563 | { |
564 | config.vertexShaderVersion = integer; |
565 | } |
566 | else if(sscanf(post, "textureMemory=%d" , &integer)) |
567 | { |
568 | config.textureMemory = integer; |
569 | } |
570 | else if(sscanf(post, "identifier=%d" , &integer)) |
571 | { |
572 | config.identifier = integer; |
573 | } |
574 | else if(sscanf(post, "vertexRoutineCacheSize=%d" , &integer)) |
575 | { |
576 | config.vertexRoutineCacheSize = integer; |
577 | } |
578 | else if(sscanf(post, "pixelRoutineCacheSize=%d" , &integer)) |
579 | { |
580 | config.pixelRoutineCacheSize = integer; |
581 | } |
582 | else if(sscanf(post, "setupRoutineCacheSize=%d" , &integer)) |
583 | { |
584 | config.setupRoutineCacheSize = integer; |
585 | } |
586 | else if(sscanf(post, "vertexCacheSize=%d" , &integer)) |
587 | { |
588 | config.vertexCacheSize = integer; |
589 | } |
590 | else if(sscanf(post, "textureSampleQuality=%d" , &integer)) |
591 | { |
592 | config.textureSampleQuality = integer; |
593 | } |
594 | else if(sscanf(post, "mipmapQuality=%d" , &integer)) |
595 | { |
596 | config.mipmapQuality = integer; |
597 | } |
598 | else if(sscanf(post, "perspectiveCorrection=%d" , &integer)) |
599 | { |
600 | config.perspectiveCorrection = integer != 0; |
601 | } |
602 | else if(sscanf(post, "transcendentalPrecision=%d" , &integer)) |
603 | { |
604 | config.transcendentalPrecision = integer; |
605 | } |
606 | else if(sscanf(post, "transparencyAntialiasing=%d" , &integer)) |
607 | { |
608 | config.transparencyAntialiasing = integer; |
609 | } |
610 | else if(sscanf(post, "threadCount=%d" , &integer)) |
611 | { |
612 | config.threadCount = integer; |
613 | } |
614 | else if(sscanf(post, "frameBufferAPI=%d" , &integer)) |
615 | { |
616 | config.frameBufferAPI = integer; |
617 | } |
618 | else if(sscanf(post, "shadowMapping=%d" , &integer)) |
619 | { |
620 | config.shadowMapping = integer; |
621 | } |
622 | else if(strstr(post, "enableSSE=on" )) |
623 | { |
624 | config.enableSSE = true; |
625 | } |
626 | else if(strstr(post, "enableSSE2=on" )) |
627 | { |
628 | if(config.enableSSE) |
629 | { |
630 | config.enableSSE2 = true; |
631 | } |
632 | } |
633 | else if(strstr(post, "enableSSE3=on" )) |
634 | { |
635 | if(config.enableSSE2) |
636 | { |
637 | config.enableSSE3 = true; |
638 | } |
639 | } |
640 | else if(strstr(post, "enableSSSE3=on" )) |
641 | { |
642 | if(config.enableSSE3) |
643 | { |
644 | config.enableSSSE3 = true; |
645 | } |
646 | } |
647 | else if(strstr(post, "enableSSE4_1=on" )) |
648 | { |
649 | if(config.enableSSSE3) |
650 | { |
651 | config.enableSSE4_1 = true; |
652 | } |
653 | } |
654 | else if(sscanf(post, "optimization%d=%d" , &index, &integer)) |
655 | { |
656 | config.optimization[index - 1] = (rr::Optimization::Pass)integer; |
657 | } |
658 | else if(strstr(post, "disableServer=on" )) |
659 | { |
660 | config.disableServer = true; |
661 | } |
662 | else if(strstr(post, "forceWindowed=on" )) |
663 | { |
664 | config.forceWindowed = true; |
665 | } |
666 | else if(strstr(post, "complementaryDepthBuffer=on" )) |
667 | { |
668 | config.complementaryDepthBuffer = true; |
669 | } |
670 | else if(strstr(post, "postBlendSRGB=on" )) |
671 | { |
672 | config.postBlendSRGB = true; |
673 | } |
674 | else if(strstr(post, "exactColorRounding=on" )) |
675 | { |
676 | config.exactColorRounding = true; |
677 | } |
678 | else if(strstr(post, "disableAlphaMode=on" )) |
679 | { |
680 | config.disableAlphaMode = true; |
681 | } |
682 | else if(strstr(post, "disable10BitMode=on" )) |
683 | { |
684 | config.disable10BitMode = true; |
685 | } |
686 | else if(strstr(post, "precache=on" )) |
687 | { |
688 | config.precache = true; |
689 | } |
690 | else if(strstr(post, "forceClearRegisters=on" )) |
691 | { |
692 | config.forceClearRegisters = true; |
693 | } |
694 | #ifndef NDEBUG |
695 | else if(sscanf(post, "minPrimitives=%d" , &integer)) |
696 | { |
697 | config.minPrimitives = integer; |
698 | } |
699 | else if(sscanf(post, "maxPrimitives=%d" , &integer)) |
700 | { |
701 | config.maxPrimitives = integer; |
702 | } |
703 | #endif |
704 | else |
705 | { |
706 | ASSERT(false); |
707 | } |
708 | |
709 | do |
710 | { |
711 | post++; |
712 | } |
713 | while(post[-1] != '&' && *post != 0); |
714 | } |
715 | } |
716 | |
717 | void SwiftConfig::readConfiguration(bool disableServerOverride) |
718 | { |
719 | Configurator ini("SwiftShader.ini" ); |
720 | |
721 | config.pixelShaderVersion = ini.getInteger("Capabilities" , "PixelShaderVersion" , 30); |
722 | config.vertexShaderVersion = ini.getInteger("Capabilities" , "VertexShaderVersion" , 30); |
723 | config.textureMemory = ini.getInteger("Capabilities" , "TextureMemory" , 256); |
724 | config.identifier = ini.getInteger("Capabilities" , "Identifier" , 0); |
725 | config.vertexRoutineCacheSize = ini.getInteger("Caches" , "VertexRoutineCacheSize" , 1024); |
726 | config.pixelRoutineCacheSize = ini.getInteger("Caches" , "PixelRoutineCacheSize" , 1024); |
727 | config.setupRoutineCacheSize = ini.getInteger("Caches" , "SetupRoutineCacheSize" , 1024); |
728 | config.vertexCacheSize = ini.getInteger("Caches" , "VertexCacheSize" , 64); |
729 | config.textureSampleQuality = ini.getInteger("Quality" , "TextureSampleQuality" , 2); |
730 | config.mipmapQuality = ini.getInteger("Quality" , "MipmapQuality" , 1); |
731 | config.perspectiveCorrection = ini.getBoolean("Quality" , "PerspectiveCorrection" , true); |
732 | config.transcendentalPrecision = ini.getInteger("Quality" , "TranscendentalPrecision" , 2); |
733 | config.transparencyAntialiasing = ini.getInteger("Quality" , "TransparencyAntialiasing" , 0); |
734 | config.threadCount = ini.getInteger("Processor" , "ThreadCount" , DEFAULT_THREAD_COUNT); |
735 | config.enableSSE = ini.getBoolean("Processor" , "EnableSSE" , true); |
736 | config.enableSSE2 = ini.getBoolean("Processor" , "EnableSSE2" , true); |
737 | config.enableSSE3 = ini.getBoolean("Processor" , "EnableSSE3" , true); |
738 | config.enableSSSE3 = ini.getBoolean("Processor" , "EnableSSSE3" , true); |
739 | config.enableSSE4_1 = ini.getBoolean("Processor" , "EnableSSE4_1" , true); |
740 | |
741 | for(size_t pass = 0; pass < config.optimization.size(); pass++) |
742 | { |
743 | auto def = pass == 0 ? rr::Optimization::Pass::InstructionCombining : rr::Optimization::Pass::Disabled; |
744 | config.optimization[pass] = (rr::Optimization::Pass)ini.getInteger("Optimization" , "OptimizationPass" + itoa(pass + 1), (int)def); |
745 | } |
746 | |
747 | config.disableServer = ini.getBoolean("Testing" , "DisableServer" , false); |
748 | config.forceWindowed = ini.getBoolean("Testing" , "ForceWindowed" , false); |
749 | config.complementaryDepthBuffer = ini.getBoolean("Testing" , "ComplementaryDepthBuffer" , false); |
750 | config.postBlendSRGB = ini.getBoolean("Testing" , "PostBlendSRGB" , false); |
751 | config.exactColorRounding = ini.getBoolean("Testing" , "ExactColorRounding" , true); |
752 | config.disableAlphaMode = ini.getBoolean("Testing" , "DisableAlphaMode" , false); |
753 | config.disable10BitMode = ini.getBoolean("Testing" , "Disable10BitMode" , false); |
754 | config.frameBufferAPI = ini.getInteger("Testing" , "FrameBufferAPI" , 0); |
755 | config.precache = ini.getBoolean("Testing" , "Precache" , false); |
756 | config.shadowMapping = ini.getInteger("Testing" , "ShadowMapping" , 3); |
757 | config.forceClearRegisters = ini.getBoolean("Testing" , "ForceClearRegisters" , false); |
758 | |
759 | #ifndef NDEBUG |
760 | config.minPrimitives = 1; |
761 | config.maxPrimitives = 1 << 21; |
762 | #endif |
763 | |
764 | struct stat status; |
765 | int lastModified = ini.getInteger("LastModified" , "Time" , 0); |
766 | |
767 | bool noConfig = stat("SwiftShader.ini" , &status) != 0; |
768 | newConfig = !noConfig && abs((int)status.st_mtime - lastModified) > 1; |
769 | |
770 | if(disableServerOverride) |
771 | { |
772 | config.disableServer = true; |
773 | } |
774 | } |
775 | |
776 | void SwiftConfig::writeConfiguration() |
777 | { |
778 | Configurator ini("SwiftShader.ini" ); |
779 | |
780 | ini.addValue("Capabilities" , "PixelShaderVersion" , itoa(config.pixelShaderVersion)); |
781 | ini.addValue("Capabilities" , "VertexShaderVersion" , itoa(config.vertexShaderVersion)); |
782 | ini.addValue("Capabilities" , "TextureMemory" , itoa(config.textureMemory)); |
783 | ini.addValue("Capabilities" , "Identifier" , itoa(config.identifier)); |
784 | ini.addValue("Caches" , "VertexRoutineCacheSize" , itoa(config.vertexRoutineCacheSize)); |
785 | ini.addValue("Caches" , "PixelRoutineCacheSize" , itoa(config.pixelRoutineCacheSize)); |
786 | ini.addValue("Caches" , "SetupRoutineCacheSize" , itoa(config.setupRoutineCacheSize)); |
787 | ini.addValue("Caches" , "VertexCacheSize" , itoa(config.vertexCacheSize)); |
788 | ini.addValue("Quality" , "TextureSampleQuality" , itoa(config.textureSampleQuality)); |
789 | ini.addValue("Quality" , "MipmapQuality" , itoa(config.mipmapQuality)); |
790 | ini.addValue("Quality" , "PerspectiveCorrection" , itoa(config.perspectiveCorrection)); |
791 | ini.addValue("Quality" , "TranscendentalPrecision" , itoa(config.transcendentalPrecision)); |
792 | ini.addValue("Quality" , "TransparencyAntialiasing" , itoa(config.transparencyAntialiasing)); |
793 | ini.addValue("Processor" , "ThreadCount" , itoa(config.threadCount)); |
794 | // ini.addValue("Processor", "EnableSSE", itoa(config.enableSSE)); |
795 | ini.addValue("Processor" , "EnableSSE2" , itoa(config.enableSSE2)); |
796 | ini.addValue("Processor" , "EnableSSE3" , itoa(config.enableSSE3)); |
797 | ini.addValue("Processor" , "EnableSSSE3" , itoa(config.enableSSSE3)); |
798 | ini.addValue("Processor" , "EnableSSE4_1" , itoa(config.enableSSE4_1)); |
799 | |
800 | for(size_t pass = 0; pass < config.optimization.size(); pass++) |
801 | { |
802 | ini.addValue("Optimization" , "OptimizationPass" + itoa(pass + 1), itoa((int)config.optimization[pass])); |
803 | } |
804 | |
805 | ini.addValue("Testing" , "DisableServer" , itoa(config.disableServer)); |
806 | ini.addValue("Testing" , "ForceWindowed" , itoa(config.forceWindowed)); |
807 | ini.addValue("Testing" , "ComplementaryDepthBuffer" , itoa(config.complementaryDepthBuffer)); |
808 | ini.addValue("Testing" , "PostBlendSRGB" , itoa(config.postBlendSRGB)); |
809 | ini.addValue("Testing" , "ExactColorRounding" , itoa(config.exactColorRounding)); |
810 | ini.addValue("Testing" , "DisableAlphaMode" , itoa(config.disableAlphaMode)); |
811 | ini.addValue("Testing" , "Disable10BitMode" , itoa(config.disable10BitMode)); |
812 | ini.addValue("Testing" , "FrameBufferAPI" , itoa(config.frameBufferAPI)); |
813 | ini.addValue("Testing" , "Precache" , itoa(config.precache)); |
814 | ini.addValue("Testing" , "ShadowMapping" , itoa(config.shadowMapping)); |
815 | ini.addValue("Testing" , "ForceClearRegisters" , itoa(config.forceClearRegisters)); |
816 | ini.addValue("LastModified" , "Time" , itoa((int)time(0))); |
817 | |
818 | ini.writeFile("SwiftShader Configuration File\n" |
819 | ";\n" |
820 | "; To get an overview of the valid settings and their meaning,\n" |
821 | "; run the application in windowed mode and open the\n" |
822 | "; SwiftConfig application or go to http://localhost:8080/swiftconfig." ); |
823 | } |
824 | } |
825 | |