blob: b1cc2e9c170f7d41f851b4e32b932e7d4dbf4e4e [file] [log] [blame]
Nicolas Capens0bac2852016-05-07 06:09:58 -04001// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
John Bauman89401822014-05-06 15:04:28 -04002//
Nicolas Capens0bac2852016-05-07 06:09:58 -04003// 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
John Bauman89401822014-05-06 15:04:28 -04006//
Nicolas Capens0bac2852016-05-07 06:09:58 -04007// http://www.apache.org/licenses/LICENSE-2.0
John Bauman89401822014-05-06 15:04:28 -04008//
Nicolas Capens0bac2852016-05-07 06:09:58 -04009// 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.
John Bauman89401822014-05-06 15:04:28 -040014
15#include "SwiftConfig.hpp"
16
17#include "Configurator.hpp"
18#include "Debug.hpp"
19#include "Config.hpp"
20#include "Version.h"
21
22#include <sstream>
23#include <stdio.h>
24#include <time.h>
25#include <sys/stat.h>
John Bauman66b8ab22014-05-06 15:57:45 -040026#include <string.h>
John Bauman89401822014-05-06 15:04:28 -040027
John Bauman89401822014-05-06 15:04:28 -040028namespace sw
29{
Nicolas Capensb663f712016-04-18 12:02:39 -040030 extern Profiler profiler;
31
John Bauman89401822014-05-06 15:04:28 -040032 std::string itoa(int number)
33 {
34 std::stringstream ss;
35 ss << number;
36 return ss.str();
37 }
Nicolas Capens0bac2852016-05-07 06:09:58 -040038
John Bauman89401822014-05-06 15:04:28 -040039 std::string ftoa(double number)
40 {
41 std::stringstream ss;
42 ss << number;
43 return ss.str();
44 }
45
John Bauman66b8ab22014-05-06 15:57:45 -040046 SwiftConfig::SwiftConfig(bool disableServerOverride) : listenSocket(0)
John Bauman89401822014-05-06 15:04:28 -040047 {
John Bauman89401822014-05-06 15:04:28 -040048 readConfiguration(disableServerOverride);
49
50 if(!disableServerOverride)
51 {
52 writeConfiguration();
53 }
54
55 receiveBuffer = 0;
56
57 if(!config.disableServer)
58 {
59 createServer();
60 }
61 }
62
63 SwiftConfig::~SwiftConfig()
64 {
65 destroyServer();
John Bauman89401822014-05-06 15:04:28 -040066 }
67
68 void SwiftConfig::createServer()
69 {
70 bufferLength = 16 * 1024;
71 receiveBuffer = new char[bufferLength];
72
John Bauman66b8ab22014-05-06 15:57:45 -040073 Socket::startup();
74 listenSocket = new Socket("localhost", "8080");
75 listenSocket->listen();
John Bauman89401822014-05-06 15:04:28 -040076
John Bauman66b8ab22014-05-06 15:57:45 -040077 terminate = false;
78 serverThread = new Thread(serverRoutine, this);
John Bauman89401822014-05-06 15:04:28 -040079 }
80
81 void SwiftConfig::destroyServer()
82 {
83 if(receiveBuffer)
84 {
85 terminate = true;
John Bauman66b8ab22014-05-06 15:57:45 -040086 serverThread->join();
87 delete serverThread;
John Bauman89401822014-05-06 15:04:28 -040088
John Bauman66b8ab22014-05-06 15:57:45 -040089 delete listenSocket;
90 listenSocket = 0;
John Bauman89401822014-05-06 15:04:28 -040091
John Bauman66b8ab22014-05-06 15:57:45 -040092 Socket::cleanup();
John Bauman89401822014-05-06 15:04:28 -040093
94 delete[] receiveBuffer;
95 receiveBuffer = 0;
96 }
97 }
98
99 bool SwiftConfig::hasNewConfiguration(bool reset)
100 {
101 bool value = newConfig;
102
103 if(reset)
104 {
105 newConfig = false;
106 }
107
108 return value;
109 }
110
111 void SwiftConfig::getConfiguration(Configuration &configuration)
112 {
John Bauman66b8ab22014-05-06 15:57:45 -0400113 criticalSection.lock();
John Bauman89401822014-05-06 15:04:28 -0400114 configuration = config;
John Bauman66b8ab22014-05-06 15:57:45 -0400115 criticalSection.unlock();
John Bauman89401822014-05-06 15:04:28 -0400116 }
117
John Bauman66b8ab22014-05-06 15:57:45 -0400118 void SwiftConfig::serverRoutine(void *parameters)
John Bauman89401822014-05-06 15:04:28 -0400119 {
120 SwiftConfig *swiftConfig = (SwiftConfig*)parameters;
121
122 swiftConfig->serverLoop();
John Bauman89401822014-05-06 15:04:28 -0400123 }
124
125 void SwiftConfig::serverLoop()
126 {
127 readConfiguration();
128
129 while(!terminate)
130 {
John Bauman66b8ab22014-05-06 15:57:45 -0400131 if(listenSocket->select(100000))
John Bauman89401822014-05-06 15:04:28 -0400132 {
John Bauman66b8ab22014-05-06 15:57:45 -0400133 Socket *clientSocket = listenSocket->accept();
John Bauman89401822014-05-06 15:04:28 -0400134 int bytesReceived = 1;
135
136 while(bytesReceived > 0 && !terminate)
137 {
John Bauman66b8ab22014-05-06 15:57:45 -0400138 if(clientSocket->select(10))
John Bauman89401822014-05-06 15:04:28 -0400139 {
John Bauman66b8ab22014-05-06 15:57:45 -0400140 bytesReceived = clientSocket->receive(receiveBuffer, bufferLength);
John Bauman89401822014-05-06 15:04:28 -0400141
142 if(bytesReceived > 0)
143 {
144 receiveBuffer[bytesReceived] = 0;
Nicolas Capens0bac2852016-05-07 06:09:58 -0400145
John Bauman66b8ab22014-05-06 15:57:45 -0400146 respond(clientSocket, receiveBuffer);
John Bauman89401822014-05-06 15:04:28 -0400147 }
148 }
149 }
150
John Bauman66b8ab22014-05-06 15:57:45 -0400151 delete clientSocket;
John Bauman89401822014-05-06 15:04:28 -0400152 }
153 }
154 }
155
Alexis Hetu0085c442015-06-12 15:19:20 -0400156 bool match(const char **url, const char *string)
John Bauman89401822014-05-06 15:04:28 -0400157 {
158 size_t length = strlen(string);
159
160 if(strncmp(*url, string, length) == 0)
161 {
162 *url += length;
163
164 return true;
165 }
166
167 return false;
168 }
169
John Bauman66b8ab22014-05-06 15:57:45 -0400170 void SwiftConfig::respond(Socket *clientSocket, const char *request)
John Bauman89401822014-05-06 15:04:28 -0400171 {
172 if(match(&request, "GET /"))
173 {
174 if(match(&request, "swiftshader") || match(&request, "swiftconfig"))
175 {
176 if(match(&request, " ") || match(&request, "/ "))
177 {
John Bauman66b8ab22014-05-06 15:57:45 -0400178 return send(clientSocket, OK, page());
John Bauman89401822014-05-06 15:04:28 -0400179 }
180 }
181 }
182 else if(match(&request, "POST /"))
183 {
184 if(match(&request, "swiftshader") || match(&request, "swiftconfig"))
185 {
186 if(match(&request, " ") || match(&request, "/ "))
187 {
John Bauman66b8ab22014-05-06 15:57:45 -0400188 criticalSection.lock();
John Bauman89401822014-05-06 15:04:28 -0400189
190 const char *postData = strstr(request, "\r\n\r\n");
191 postData = postData ? postData + 4 : 0;
192
193 if(postData && strlen(postData) > 0)
194 {
195 parsePost(postData);
196 }
197 else // POST data in next packet
198 {
John Bauman66b8ab22014-05-06 15:57:45 -0400199 int bytesReceived = clientSocket->receive(receiveBuffer, bufferLength);
Nicolas Capens0bac2852016-05-07 06:09:58 -0400200
John Bauman89401822014-05-06 15:04:28 -0400201 if(bytesReceived > 0)
202 {
203 receiveBuffer[bytesReceived] = 0;
204 parsePost(receiveBuffer);
205 }
206 }
207
208 writeConfiguration();
209 newConfig = true;
210
211 if(config.disableServer)
212 {
213 destroyServer();
214 }
215
John Bauman66b8ab22014-05-06 15:57:45 -0400216 criticalSection.unlock();
John Bauman89401822014-05-06 15:04:28 -0400217
John Bauman66b8ab22014-05-06 15:57:45 -0400218 return send(clientSocket, OK, page());
John Bauman89401822014-05-06 15:04:28 -0400219 }
220 else if(match(&request, "/profile "))
221 {
John Bauman66b8ab22014-05-06 15:57:45 -0400222 return send(clientSocket, OK, profile());
John Bauman89401822014-05-06 15:04:28 -0400223 }
224 }
225 }
226
John Bauman66b8ab22014-05-06 15:57:45 -0400227 return send(clientSocket, NotFound);
John Bauman89401822014-05-06 15:04:28 -0400228 }
229
230 std::string SwiftConfig::page()
231 {
232 std::string html;
233
234 const std::string selected = "selected='selected'";
235 const std::string checked = "checked='checked'";
236 const std::string empty = "";
237
238 html += "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'>\n";
239 html += "<html>\n";
240 html += "<head>\n";
241 html += "<meta http-equiv='content-type' content='text/html; charset=UTF-8'>\n";
242 html += "<title>SwiftShader Configuration Panel</title>\n";
243 html += "</head>\n";
244 html += "<body>\n";
John Bauman89401822014-05-06 15:04:28 -0400245 html += "<script type='text/javascript'>\n";
246 html += "request();\n";
247 html += "function request()\n";
248 html += "{\n";
249 html += "var xhr = new XMLHttpRequest();\n";
250 html += "xhr.open('POST', 'http://localhost:8080/swiftshader/profile', true);\n";
251 html += "xhr.onreadystatechange = function()\n";
252 html += "{\n";
253 html += "if(xhr.readyState == 4 && xhr.status == 200)\n";
254 html += "{\n";
255 html += "document.getElementById('profile').innerHTML = xhr.responseText;\n";
256 html += "setTimeout('request()', 1000);\n";
257 html += "}\n";
258 html += "}\n";
259 html += "xhr.send();\n";
260 html += "}\n";
261 html += "</script>\n";
262 html += "<form method='POST' action=''>\n";
263 html += "<h1>SwiftShader Configuration Panel</h1>\n";
Nicolas Capens6ef6d2a2015-02-23 14:23:11 -0500264 html += "<div id='profile'>" + profile() + "</div>\n";
John Bauman89401822014-05-06 15:04:28 -0400265 html += "<hr><p>\n";
266 html += "<input type='submit' value='Apply changes' title='Click to apply all settings.'>\n";
267 // html += "<input type='reset' value='Reset changes' title='Click to reset your changes to the previous value.'>\n";
268 html += "</p><hr>\n";
269 html += "<h2><em>Device capabilities</em></h2>\n";
270 html += "<table>\n";
271 html += "<tr><td>Build revision:</td><td>" REVISION_STRING "</td></tr>\n";
272 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";
273 html += "<option value='0'" + (config.pixelShaderVersion == 0 ? selected : empty) + ">0.0</option>\n";
274 html += "<option value='11'" + (config.pixelShaderVersion == 11 ? selected : empty) + ">1.1</option>\n";
275 html += "<option value='12'" + (config.pixelShaderVersion == 12 ? selected : empty) + ">1.2</option>\n";
276 html += "<option value='13'" + (config.pixelShaderVersion == 13 ? selected : empty) + ">1.3</option>\n";
277 html += "<option value='14'" + (config.pixelShaderVersion == 14 ? selected : empty) + ">1.4</option>\n";
278 html += "<option value='20'" + (config.pixelShaderVersion == 20 ? selected : empty) + ">2.0</option>\n";
279 html += "<option value='21'" + (config.pixelShaderVersion == 21 ? selected : empty) + ">2.x</option>\n";
280 html += "<option value='30'" + (config.pixelShaderVersion == 30 ? selected : empty) + ">3.0 (default)</option>\n";
281 html += "</select></td></tr>\n";
282 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";
283 html += "<option value='0'" + (config.vertexShaderVersion == 0 ? selected : empty) + ">0.0</option>\n";
284 html += "<option value='11'" + (config.vertexShaderVersion == 11 ? selected : empty) + ">1.1</option>\n";
285 html += "<option value='20'" + (config.vertexShaderVersion == 20 ? selected : empty) + ">2.0</option>\n";
286 html += "<option value='21'" + (config.vertexShaderVersion == 21 ? selected : empty) + ">2.x</option>\n";
287 html += "<option value='30'" + (config.vertexShaderVersion == 30 ? selected : empty) + ">3.0 (default)</option>\n";
288 html += "</select></td></tr>\n";
289 html += "<tr><td>Texture memory:</td><td><select name='textureMemory' title='The maximum amount of memory used for textures and other resources.'>\n";
290 html += "<option value='128'" + (config.textureMemory == 128 ? selected : empty) + ">128 MB</option>\n";
291 html += "<option value='256'" + (config.textureMemory == 256 ? selected : empty) + ">256 MB (default)</option>\n";
292 html += "<option value='512'" + (config.textureMemory == 512 ? selected : empty) + ">512 MB</option>\n";
293 html += "<option value='1024'" + (config.textureMemory == 1024 ? selected : empty) + ">1024 MB</option>\n";
294 html += "<option value='2048'" + (config.textureMemory == 2048 ? selected : empty) + ">2048 MB</option>\n";
295 html += "</select></td></tr>\n";
296 html += "<tr><td>Device identifier:</td><td><select name='identifier' title='The information used by some applications to determine device capabilities.'>\n";
Nicolas Capens0bac2852016-05-07 06:09:58 -0400297 html += "<option value='0'" + (config.identifier == 0 ? selected : empty) + ">Google SwiftShader (default)</option>\n";
John Bauman89401822014-05-06 15:04:28 -0400298 html += "<option value='1'" + (config.identifier == 1 ? selected : empty) + ">NVIDIA GeForce 7900 GS</option>\n";
299 html += "<option value='2'" + (config.identifier == 2 ? selected : empty) + ">ATI Mobility Radeon X1600</option>\n";
300 html += "<option value='3'" + (config.identifier == 3 ? selected : empty) + ">Intel GMA X3100</option>\n";
301 html += "<option value='4'" + (config.identifier == 4 ? selected : empty) + ">System device</option>\n";
302 html += "</select></td></tr>\n";
303 html += "</table>\n";
304 html += "<h2><em>Cache sizes</em></h2>\n";
305 html += "<table>\n";
306 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";
307 html += "<option value='64'" + (config.vertexRoutineCacheSize == 64 ? selected : empty) + ">64</option>\n";
308 html += "<option value='128'" + (config.vertexRoutineCacheSize == 128 ? selected : empty) + ">128</option>\n";
309 html += "<option value='256'" + (config.vertexRoutineCacheSize == 256 ? selected : empty) + ">256</option>\n";
310 html += "<option value='512'" + (config.vertexRoutineCacheSize == 512 ? selected : empty) + ">512</option>\n";
311 html += "<option value='1024'" + (config.vertexRoutineCacheSize == 1024 ? selected : empty) + ">1024 (default)</option>\n";
312 html += "<option value='2048'" + (config.vertexRoutineCacheSize == 2048 ? selected : empty) + ">2048</option>\n";
313 html += "<option value='4096'" + (config.vertexRoutineCacheSize == 4096 ? selected : empty) + ">4096</option>\n";
314 html += "</select></td>\n";
315 html += "</tr>\n";
316 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";
317 html += "<option value='64'" + (config.pixelRoutineCacheSize == 64 ? selected : empty) + ">64</option>\n";
318 html += "<option value='128'" + (config.pixelRoutineCacheSize == 128 ? selected : empty) + ">128</option>\n";
319 html += "<option value='256'" + (config.pixelRoutineCacheSize == 256 ? selected : empty) + ">256</option>\n";
320 html += "<option value='512'" + (config.pixelRoutineCacheSize == 512 ? selected : empty) + ">512</option>\n";
321 html += "<option value='1024'" + (config.pixelRoutineCacheSize == 1024 ? selected : empty) + ">1024 (default)</option>\n";
322 html += "<option value='2048'" + (config.pixelRoutineCacheSize == 2048 ? selected : empty) + ">2048</option>\n";
323 html += "<option value='4096'" + (config.pixelRoutineCacheSize == 4096 ? selected : empty) + ">4096</option>\n";
324 html += "</select></td>\n";
325 html += "</tr>\n";
326 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";
327 html += "<option value='64'" + (config.setupRoutineCacheSize == 64 ? selected : empty) + ">64</option>\n";
328 html += "<option value='128'" + (config.setupRoutineCacheSize == 128 ? selected : empty) + ">128</option>\n";
329 html += "<option value='256'" + (config.setupRoutineCacheSize == 256 ? selected : empty) + ">256</option>\n";
330 html += "<option value='512'" + (config.setupRoutineCacheSize == 512 ? selected : empty) + ">512</option>\n";
331 html += "<option value='1024'" + (config.setupRoutineCacheSize == 1024 ? selected : empty) + ">1024 (default)</option>\n";
332 html += "<option value='2048'" + (config.setupRoutineCacheSize == 2048 ? selected : empty) + ">2048</option>\n";
333 html += "<option value='4096'" + (config.setupRoutineCacheSize == 4096 ? selected : empty) + ">4096</option>\n";
334 html += "</select></td>\n";
335 html += "</tr>\n";
336 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";
337 html += "<option value='64'" + (config.vertexCacheSize == 64 ? selected : empty) + ">64 (default)</option>\n";
338 html += "</select></td>\n";
339 html += "</tr>\n";
340 html += "</table>\n";
341 html += "<h2><em>Quality</em></h2>\n";
342 html += "<table>\n";
343 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";
344 html += "<option value='0'" + (config.textureSampleQuality == 0 ? selected : empty) + ">Point</option>\n";
345 html += "<option value='1'" + (config.textureSampleQuality == 1 ? selected : empty) + ">Linear</option>\n";
346 html += "<option value='2'" + (config.textureSampleQuality == 2 ? selected : empty) + ">Anisotropic (default)</option>\n";
347 html += "</select></td>\n";
348 html += "</tr>\n";
349 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";
350 html += "<option value='0'" + (config.mipmapQuality == 0 ? selected : empty) + ">Point</option>\n";
351 html += "<option value='1'" + (config.mipmapQuality == 1 ? selected : empty) + ">Linear (default)</option>\n";
352 html += "</select></td>\n";
353 html += "</tr>\n";
354 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";
355 html += "<option value='0'" + (config.perspectiveCorrection == 0 ? selected : empty) + ">Off</option>\n";
356 html += "<option value='1'" + (config.perspectiveCorrection == 1 ? selected : empty) + ">On (default)</option>\n";
357 html += "</select></td>\n";
358 html += "</tr>\n";
359 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";
360 html += "<option value='0'" + (config.transcendentalPrecision == 0 ? selected : empty) + ">Approximate</option>\n";
361 html += "<option value='1'" + (config.transcendentalPrecision == 1 ? selected : empty) + ">Partial</option>\n";
362 html += "<option value='2'" + (config.transcendentalPrecision == 2 ? selected : empty) + ">Accurate (default)</option>\n";
363 html += "<option value='3'" + (config.transcendentalPrecision == 3 ? selected : empty) + ">WHQL</option>\n";
364 html += "<option value='4'" + (config.transcendentalPrecision == 4 ? selected : empty) + ">IEEE</option>\n";
365 html += "</select></td>\n";
366 html += "</tr>\n";
367 html += "<tr><td>Transparency anti-aliasing:</td><td><select name='transparencyAntialiasing' title='The technique used to anti-alias alpha-tested transparent textures.'>\n";
368 html += "<option value='0'" + (config.transparencyAntialiasing == 0 ? selected : empty) + ">None (default)</option>\n";
369 html += "<option value='1'" + (config.transparencyAntialiasing == 1 ? selected : empty) + ">Alpha-to-Coverage</option>\n";
370 html += "</select></td>\n";
371 html += "</table>\n";
372 html += "<h2><em>Processor settings</em></h2>\n";
373 html += "<table>\n";
374 html += "<tr><td>Number of threads:</td><td><select name='threadCount' title='The number of rendering threads to be used.'>\n";
375 html += "<option value='-1'" + (config.threadCount == -1 ? selected : empty) + ">Core count</option>\n";
376 html += "<option value='0'" + (config.threadCount == 0 ? selected : empty) + ">Process affinity (default)</option>\n";
377 html += "<option value='1'" + (config.threadCount == 1 ? selected : empty) + ">1</option>\n";
378 html += "<option value='2'" + (config.threadCount == 2 ? selected : empty) + ">2</option>\n";
379 html += "<option value='3'" + (config.threadCount == 3 ? selected : empty) + ">3</option>\n";
380 html += "<option value='4'" + (config.threadCount == 4 ? selected : empty) + ">4</option>\n";
381 html += "<option value='5'" + (config.threadCount == 5 ? selected : empty) + ">5</option>\n";
382 html += "<option value='6'" + (config.threadCount == 6 ? selected : empty) + ">6</option>\n";
383 html += "<option value='7'" + (config.threadCount == 7 ? selected : empty) + ">7</option>\n";
384 html += "<option value='8'" + (config.threadCount == 8 ? selected : empty) + ">8</option>\n";
385 html += "<option value='9'" + (config.threadCount == 9 ? selected : empty) + ">9</option>\n";
386 html += "<option value='10'" + (config.threadCount == 10 ? selected : empty) + ">10</option>\n";
387 html += "<option value='11'" + (config.threadCount == 11 ? selected : empty) + ">11</option>\n";
388 html += "<option value='12'" + (config.threadCount == 12 ? selected : empty) + ">12</option>\n";
389 html += "<option value='13'" + (config.threadCount == 13 ? selected : empty) + ">13</option>\n";
390 html += "<option value='14'" + (config.threadCount == 14 ? selected : empty) + ">14</option>\n";
391 html += "<option value='15'" + (config.threadCount == 15 ? selected : empty) + ">15</option>\n";
392 html += "<option value='16'" + (config.threadCount == 16 ? selected : empty) + ">16</option>\n";
393 html += "</select></td></tr>\n";
Nicolas Capens6ef6d2a2015-02-23 14:23:11 -0500394 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>";
395 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>";
396 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>";
397 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>";
398 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>";
John Bauman89401822014-05-06 15:04:28 -0400399 html += "</table>\n";
400 html += "<h2><em>Compiler optimizations</em></h2>\n";
401 html += "<table>\n";
402
403 for(int pass = 0; pass < 10; pass++)
404 {
405 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";
406 html += "<option value='0'" + (config.optimization[pass] == 0 ? selected : empty) + ">Disabled" + (pass > 0 ? " (default)" : "") + "</option>\n";
407 html += "<option value='1'" + (config.optimization[pass] == 1 ? selected : empty) + ">Instruction Combining" + (pass == 0 ? " (default)" : "") + "</option>\n";
408 html += "<option value='2'" + (config.optimization[pass] == 2 ? selected : empty) + ">Control Flow Simplification</option>\n";
409 html += "<option value='3'" + (config.optimization[pass] == 3 ? selected : empty) + ">Loop Invariant Code Motion</option>\n";
410 html += "<option value='4'" + (config.optimization[pass] == 4 ? selected : empty) + ">Aggressive Dead Code Elimination</option>\n";
411 html += "<option value='5'" + (config.optimization[pass] == 5 ? selected : empty) + ">Global Value Numbering</option>\n";
412 html += "<option value='6'" + (config.optimization[pass] == 6 ? selected : empty) + ">Commutative Expressions Reassociation</option>\n";
413 html += "<option value='7'" + (config.optimization[pass] == 7 ? selected : empty) + ">Dead Store Elimination</option>\n";
414 html += "<option value='8'" + (config.optimization[pass] == 8 ? selected : empty) + ">Sparse Conditional Copy Propagation</option>\n";
John Bauman19bac1e2014-05-06 15:23:49 -0400415 html += "<option value='9'" + (config.optimization[pass] == 9 ? selected : empty) + ">Scalar Replacement of Aggregates</option>\n";
John Bauman89401822014-05-06 15:04:28 -0400416 html += "</select></td></tr>\n";
417 }
418
419 html += "</table>\n";
420 html += "<h2><em>Testing & Experimental</em></h2>\n";
421 html += "<table>\n";
422 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>";
423 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>";
424 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>";
425 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>";
426 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>";
427 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>";
428 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>";
429 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";
430 html += "<option value='0'" + (config.frameBufferAPI == 0 ? selected : empty) + ">DirectDraw (default)</option>\n";
431 html += "<option value='1'" + (config.frameBufferAPI == 1 ? selected : empty) + ">GDI</option>\n";
432 html += "</select></td>\n";
John Bauman66b8ab22014-05-06 15:57:45 -0400433 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>";
John Bauman89401822014-05-06 15:04:28 -0400434 html += "<tr><td>Shadow mapping extensions:</td><td><select name='shadowMapping' title='Features that may accelerate or improve the quality of shadow mapping.'>\n";
435 html += "<option value='0'" + (config.shadowMapping == 0 ? selected : empty) + ">None</option>\n";
436 html += "<option value='1'" + (config.shadowMapping == 1 ? selected : empty) + ">Fetch4</option>\n";
437 html += "<option value='2'" + (config.shadowMapping == 2 ? selected : empty) + ">DST</option>\n";
438 html += "<option value='3'" + (config.shadowMapping == 3 ? selected : empty) + ">Fetch4 & DST (default)</option>\n";
439 html += "</select></td>\n";
440 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>";
441 html += "</table>\n";
442 #ifndef NDEBUG
443 html += "<h2><em>Debugging</em></h2>\n";
444 html += "<table>\n";
445 html += "<tr><td>Minimum primitives:</td><td><input type='text' size='10' maxlength='10' name='minPrimitives' value='" + itoa(config.minPrimitives) + "'></td></tr>\n";
446 html += "<tr><td>Maximum primitives:</td><td><input type='text' size='10' maxlength='10' name='maxPrimitives' value='" + itoa(config.maxPrimitives) + "'></td></tr>\n";
447 html += "</table>\n";
448 #endif
449 html += "<hr><p>\n";
450 html += "<span style='font-size:10pt'>Hover the mouse pointer over a control to get additional information.</span><br>\n";
451 html += "<span style='font-size:10pt'>Some settings can be applied interactively, some need a restart of the application.</span><br>\n";
452 html += "<span style='font-size:10pt'>Removing the SwiftShader.ini file results in resetting the options to their default.</span></p>\n";
453 html += "</form>\n";
454 html += "</body>\n";
455 html += "</html>\n";
456
Nicolas Capens6ef6d2a2015-02-23 14:23:11 -0500457 profiler.reset();
John Bauman89401822014-05-06 15:04:28 -0400458
459 return html;
460 }
461
462 std::string SwiftConfig::profile()
463 {
464 std::string html;
465
Nicolas Capens6ef6d2a2015-02-23 14:23:11 -0500466 html += "<p>FPS: " + ftoa(profiler.FPS) + "</p>\n";
467 html += "<p>Frame: " + itoa(profiler.framesTotal) + "</p>\n";
468
John Bauman89401822014-05-06 15:04:28 -0400469 #if PERF_PROFILE
470 int texTime = (int)(1000 * profiler.cycles[PERF_TEX] / profiler.cycles[PERF_PIXEL] + 0.5);
471 int shaderTime = (int)(1000 * profiler.cycles[PERF_SHADER] / profiler.cycles[PERF_PIXEL] + 0.5);
472 int pipeTime = (int)(1000 * profiler.cycles[PERF_PIPE] / profiler.cycles[PERF_PIXEL] + 0.5);
473 int ropTime = (int)(1000 * profiler.cycles[PERF_ROP] / profiler.cycles[PERF_PIXEL] + 0.5);
474 int interpTime = (int)(1000 * profiler.cycles[PERF_INTERP] / profiler.cycles[PERF_PIXEL] + 0.5);
475 int rastTime = 1000 - pipeTime;
476
477 pipeTime -= shaderTime + ropTime + interpTime;
478 shaderTime -= texTime;
479
480 double texTimeF = (double)texTime / 10;
481 double shaderTimeF = (double)shaderTime / 10;
482 double pipeTimeF = (double)pipeTime / 10;
483 double ropTimeF = (double)ropTime / 10;
484 double interpTimeF = (double)interpTime / 10;
485 double rastTimeF = (double)rastTime / 10;
486
487 double averageRopOperations = profiler.ropOperationsTotal / std::max(profiler.framesTotal, 1) / 1.0e6f;
488 double averageCompressedTex = profiler.compressedTexTotal / std::max(profiler.framesTotal, 1) / 1.0e6f;
489 double averageTexOperations = profiler.texOperationsTotal / std::max(profiler.framesTotal, 1) / 1.0e6f;
490
John Bauman89401822014-05-06 15:04:28 -0400491 html += "<p>Raster operations (million): " + ftoa(profiler.ropOperationsFrame / 1.0e6f) + " (current), " + ftoa(averageRopOperations) + " (average)</p>\n";
492 html += "<p>Texture operations (million): " + ftoa(profiler.texOperationsFrame / 1.0e6f) + " (current), " + ftoa(averageTexOperations) + " (average)</p>\n";
493 html += "<p>Compressed texture operations (million): " + ftoa(profiler.compressedTexFrame / 1.0e6f) + " (current), " + ftoa(averageCompressedTex) + " (average)</p>\n";
494 html += "<div id='profile' style='position:relative; width:1010px; height:50px; background-color:silver;'>";
495 html += "<div style='position:relative; width:1000px; height:40px; background-color:white; left:5px; top:5px;'>";
496 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";
497 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";
498 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";
499 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";
500 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";
501 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";
502 html += "</div></div>\n";
503
504 for(int i = 0; i < PERF_TIMERS; i++)
505 {
506 profiler.cycles[i] = 0;
507 }
508 #endif
509
510 return html;
511 }
512
John Bauman66b8ab22014-05-06 15:57:45 -0400513 void SwiftConfig::send(Socket *clientSocket, Status code, std::string body)
John Bauman89401822014-05-06 15:04:28 -0400514 {
515 std::string status;
516 char header[1024];
517
518 switch(code)
519 {
520 case OK: status += "HTTP/1.1 200 OK\r\n"; break;
521 case NotFound: status += "HTTP/1.1 404 Not Found\r\n"; break;
522 }
523
524 sprintf(header, "Content-Type: text/html; charset=UTF-8\r\n"
Alexis Hetu7208e932016-06-02 11:19:24 -0400525 "Content-Length: %zd\r\n"
John Bauman89401822014-05-06 15:04:28 -0400526 "Host: localhost\r\n"
527 "\r\n", body.size());
528
529 std::string message = status + header + body;
John Bauman66b8ab22014-05-06 15:57:45 -0400530 clientSocket->send(message.c_str(), (int)message.length());
John Bauman89401822014-05-06 15:04:28 -0400531 }
532
533 void SwiftConfig::parsePost(const char *post)
534 {
535 // Only enabled checkboxes appear in the POST
536 config.enableSSE = true;
John Bauman19bac1e2014-05-06 15:23:49 -0400537 config.enableSSE2 = false;
John Bauman89401822014-05-06 15:04:28 -0400538 config.enableSSE3 = false;
539 config.enableSSSE3 = false;
540 config.enableSSE4_1 = false;
541 config.disableServer = false;
542 config.forceWindowed = false;
543 config.complementaryDepthBuffer = false;
544 config.postBlendSRGB = false;
545 config.exactColorRounding = false;
546 config.disableAlphaMode = false;
547 config.disable10BitMode = false;
John Bauman66b8ab22014-05-06 15:57:45 -0400548 config.precache = false;
John Bauman89401822014-05-06 15:04:28 -0400549 config.forceClearRegisters = false;
550
551 while(*post != 0)
552 {
553 int integer;
554 int index;
555
556 if(sscanf(post, "pixelShaderVersion=%d", &integer))
557 {
558 config.pixelShaderVersion = integer;
559 }
560 else if(sscanf(post, "vertexShaderVersion=%d", &integer))
561 {
562 config.vertexShaderVersion = integer;
563 }
564 else if(sscanf(post, "textureMemory=%d", &integer))
565 {
566 config.textureMemory = integer;
567 }
568 else if(sscanf(post, "identifier=%d", &integer))
569 {
570 config.identifier = integer;
571 }
572 else if(sscanf(post, "vertexRoutineCacheSize=%d", &integer))
573 {
574 config.vertexRoutineCacheSize = integer;
575 }
576 else if(sscanf(post, "pixelRoutineCacheSize=%d", &integer))
577 {
578 config.pixelRoutineCacheSize = integer;
579 }
580 else if(sscanf(post, "setupRoutineCacheSize=%d", &integer))
581 {
582 config.setupRoutineCacheSize = integer;
583 }
584 else if(sscanf(post, "vertexCacheSize=%d", &integer))
585 {
586 config.vertexCacheSize = integer;
587 }
588 else if(sscanf(post, "textureSampleQuality=%d", &integer))
589 {
590 config.textureSampleQuality = integer;
591 }
592 else if(sscanf(post, "mipmapQuality=%d", &integer))
593 {
594 config.mipmapQuality = integer;
595 }
596 else if(sscanf(post, "perspectiveCorrection=%d", &integer))
597 {
598 config.perspectiveCorrection = integer != 0;
599 }
600 else if(sscanf(post, "transcendentalPrecision=%d", &integer))
601 {
602 config.transcendentalPrecision = integer;
603 }
604 else if(sscanf(post, "transparencyAntialiasing=%d", &integer))
605 {
606 config.transparencyAntialiasing = integer;
607 }
608 else if(sscanf(post, "threadCount=%d", &integer))
609 {
610 config.threadCount = integer;
611 }
612 else if(sscanf(post, "frameBufferAPI=%d", &integer))
613 {
614 config.frameBufferAPI = integer;
615 }
616 else if(sscanf(post, "shadowMapping=%d", &integer))
617 {
618 config.shadowMapping = integer;
619 }
620 else if(strstr(post, "enableSSE=on"))
621 {
622 config.enableSSE = true;
623 }
624 else if(strstr(post, "enableSSE2=on"))
625 {
626 if(config.enableSSE)
627 {
628 config.enableSSE2 = true;
629 }
630 }
631 else if(strstr(post, "enableSSE3=on"))
632 {
633 if(config.enableSSE2)
634 {
635 config.enableSSE3 = true;
636 }
637 }
638 else if(strstr(post, "enableSSSE3=on"))
639 {
640 if(config.enableSSE3)
641 {
642 config.enableSSSE3 = true;
643 }
644 }
645 else if(strstr(post, "enableSSE4_1=on"))
646 {
647 if(config.enableSSSE3)
648 {
649 config.enableSSE4_1 = true;
650 }
651 }
652 else if(sscanf(post, "optimization%d=%d", &index, &integer))
653 {
654 config.optimization[index - 1] = (Optimization)integer;
655 }
656 else if(strstr(post, "disableServer=on"))
657 {
658 config.disableServer = true;
659 }
660 else if(strstr(post, "forceWindowed=on"))
661 {
662 config.forceWindowed = true;
663 }
664 else if(strstr(post, "complementaryDepthBuffer=on"))
665 {
666 config.complementaryDepthBuffer = true;
667 }
668 else if(strstr(post, "postBlendSRGB=on"))
669 {
670 config.postBlendSRGB = true;
671 }
672 else if(strstr(post, "exactColorRounding=on"))
673 {
674 config.exactColorRounding = true;
675 }
676 else if(strstr(post, "disableAlphaMode=on"))
677 {
678 config.disableAlphaMode = true;
679 }
680 else if(strstr(post, "disable10BitMode=on"))
681 {
682 config.disable10BitMode = true;
683 }
John Bauman66b8ab22014-05-06 15:57:45 -0400684 else if(strstr(post, "precache=on"))
685 {
686 config.precache = true;
687 }
John Bauman89401822014-05-06 15:04:28 -0400688 else if(strstr(post, "forceClearRegisters=on"))
689 {
690 config.forceClearRegisters = true;
691 }
Nicolas Capens0bac2852016-05-07 06:09:58 -0400692 #ifndef NDEBUG
John Bauman89401822014-05-06 15:04:28 -0400693 else if(sscanf(post, "minPrimitives=%d", &integer))
694 {
695 config.minPrimitives = integer;
696 }
697 else if(sscanf(post, "maxPrimitives=%d", &integer))
698 {
699 config.maxPrimitives = integer;
700 }
701 #endif
702 else
703 {
704 ASSERT(false);
705 }
706
707 do
708 {
709 post++;
710 }
711 while(post[-1] != '&' && *post != 0);
712 }
713 }
714
715 void SwiftConfig::readConfiguration(bool disableServerOverride)
716 {
717 Configurator ini("SwiftShader.ini");
718
719 config.pixelShaderVersion = ini.getInteger("Capabilities", "PixelShaderVersion", 30);
720 config.vertexShaderVersion = ini.getInteger("Capabilities", "VertexShaderVersion", 30);
721 config.textureMemory = ini.getInteger("Capabilities", "TextureMemory", 256);
722 config.identifier = ini.getInteger("Capabilities", "Identifier", 0);
723 config.vertexRoutineCacheSize = ini.getInteger("Caches", "VertexRoutineCacheSize", 1024);
724 config.pixelRoutineCacheSize = ini.getInteger("Caches", "PixelRoutineCacheSize", 1024);
725 config.setupRoutineCacheSize = ini.getInteger("Caches", "SetupRoutineCacheSize", 1024);
726 config.vertexCacheSize = ini.getInteger("Caches", "VertexCacheSize", 64);
727 config.textureSampleQuality = ini.getInteger("Quality", "TextureSampleQuality", 2);
728 config.mipmapQuality = ini.getInteger("Quality", "MipmapQuality", 1);
729 config.perspectiveCorrection = ini.getBoolean("Quality", "PerspectiveCorrection", true);
730 config.transcendentalPrecision = ini.getInteger("Quality", "TranscendentalPrecision", 2);
731 config.transparencyAntialiasing = ini.getInteger("Quality", "TransparencyAntialiasing", 0);
Nicolas Capensa0355b72015-08-10 14:35:51 -0400732 config.threadCount = ini.getInteger("Processor", "ThreadCount", DEFAULT_THREAD_COUNT);
John Bauman89401822014-05-06 15:04:28 -0400733 config.enableSSE = ini.getBoolean("Processor", "EnableSSE", true);
734 config.enableSSE2 = ini.getBoolean("Processor", "EnableSSE2", true);
735 config.enableSSE3 = ini.getBoolean("Processor", "EnableSSE3", true);
736 config.enableSSSE3 = ini.getBoolean("Processor", "EnableSSSE3", true);
737 config.enableSSE4_1 = ini.getBoolean("Processor", "EnableSSE4_1", true);
738
739 for(int pass = 0; pass < 10; pass++)
740 {
741 config.optimization[pass] = (Optimization)ini.getInteger("Optimization", "OptimizationPass" + itoa(pass + 1), pass == 0 ? InstructionCombining : Disabled);
742 }
743
John Bauman19bac1e2014-05-06 15:23:49 -0400744 config.disableServer = ini.getBoolean("Testing", "DisableServer", false);
John Bauman89401822014-05-06 15:04:28 -0400745 config.forceWindowed = ini.getBoolean("Testing", "ForceWindowed", false);
746 config.complementaryDepthBuffer = ini.getBoolean("Testing", "ComplementaryDepthBuffer", false);
747 config.postBlendSRGB = ini.getBoolean("Testing", "PostBlendSRGB", false);
John Bauman19bac1e2014-05-06 15:23:49 -0400748 config.exactColorRounding = ini.getBoolean("Testing", "ExactColorRounding", true);
John Bauman89401822014-05-06 15:04:28 -0400749 config.disableAlphaMode = ini.getBoolean("Testing", "DisableAlphaMode", false);
750 config.disable10BitMode = ini.getBoolean("Testing", "Disable10BitMode", false);
751 config.frameBufferAPI = ini.getInteger("Testing", "FrameBufferAPI", 0);
John Bauman66b8ab22014-05-06 15:57:45 -0400752 config.precache = ini.getBoolean("Testing", "Precache", false);
John Bauman89401822014-05-06 15:04:28 -0400753 config.shadowMapping = ini.getInteger("Testing", "ShadowMapping", 3);
754 config.forceClearRegisters = ini.getBoolean("Testing", "ForceClearRegisters", false);
755
756 #ifndef NDEBUG
757 config.minPrimitives = 1;
758 config.maxPrimitives = 1 << 21;
759 #endif
760
761 struct stat status;
762 int lastModified = ini.getInteger("LastModified", "Time", 0);
763
764 bool noConfig = stat("SwiftShader.ini", &status) != 0;
765 newConfig = !noConfig && abs((int)status.st_mtime - lastModified) > 1;
766
767 if(disableServerOverride)
768 {
769 config.disableServer = true;
770 }
771 }
772
773 void SwiftConfig::writeConfiguration()
774 {
775 Configurator ini("SwiftShader.ini");
Nicolas Capens0bac2852016-05-07 06:09:58 -0400776
John Bauman89401822014-05-06 15:04:28 -0400777 ini.addValue("Capabilities", "PixelShaderVersion", itoa(config.pixelShaderVersion));
778 ini.addValue("Capabilities", "VertexShaderVersion", itoa(config.vertexShaderVersion));
779 ini.addValue("Capabilities", "TextureMemory", itoa(config.textureMemory));
780 ini.addValue("Capabilities", "Identifier", itoa(config.identifier));
781 ini.addValue("Caches", "VertexRoutineCacheSize", itoa(config.vertexRoutineCacheSize));
782 ini.addValue("Caches", "PixelRoutineCacheSize", itoa(config.pixelRoutineCacheSize));
783 ini.addValue("Caches", "SetupRoutineCacheSize", itoa(config.setupRoutineCacheSize));
784 ini.addValue("Caches", "VertexCacheSize", itoa(config.vertexCacheSize));
785 ini.addValue("Quality", "TextureSampleQuality", itoa(config.textureSampleQuality));
786 ini.addValue("Quality", "MipmapQuality", itoa(config.mipmapQuality));
787 ini.addValue("Quality", "PerspectiveCorrection", itoa(config.perspectiveCorrection));
788 ini.addValue("Quality", "TranscendentalPrecision", itoa(config.transcendentalPrecision));
789 ini.addValue("Quality", "TransparencyAntialiasing", itoa(config.transparencyAntialiasing));
790 ini.addValue("Processor", "ThreadCount", itoa(config.threadCount));
791 // ini.addValue("Processor", "EnableSSE", itoa(config.enableSSE));
John Bauman19bac1e2014-05-06 15:23:49 -0400792 ini.addValue("Processor", "EnableSSE2", itoa(config.enableSSE2));
John Bauman89401822014-05-06 15:04:28 -0400793 ini.addValue("Processor", "EnableSSE3", itoa(config.enableSSE3));
794 ini.addValue("Processor", "EnableSSSE3", itoa(config.enableSSSE3));
795 ini.addValue("Processor", "EnableSSE4_1", itoa(config.enableSSE4_1));
796
797 for(int pass = 0; pass < 10; pass++)
798 {
799 ini.addValue("Optimization", "OptimizationPass" + itoa(pass + 1), itoa(config.optimization[pass]));
800 }
801
802 ini.addValue("Testing", "DisableServer", itoa(config.disableServer));
803 ini.addValue("Testing", "ForceWindowed", itoa(config.forceWindowed));
804 ini.addValue("Testing", "ComplementaryDepthBuffer", itoa(config.complementaryDepthBuffer));
805 ini.addValue("Testing", "PostBlendSRGB", itoa(config.postBlendSRGB));
806 ini.addValue("Testing", "ExactColorRounding", itoa(config.exactColorRounding));
807 ini.addValue("Testing", "DisableAlphaMode", itoa(config.disableAlphaMode));
808 ini.addValue("Testing", "Disable10BitMode", itoa(config.disable10BitMode));
809 ini.addValue("Testing", "FrameBufferAPI", itoa(config.frameBufferAPI));
John Bauman66b8ab22014-05-06 15:57:45 -0400810 ini.addValue("Testing", "Precache", itoa(config.precache));
John Bauman89401822014-05-06 15:04:28 -0400811 ini.addValue("Testing", "ShadowMapping", itoa(config.shadowMapping));
812 ini.addValue("Testing", "ForceClearRegisters", itoa(config.forceClearRegisters));
813 ini.addValue("LastModified", "Time", itoa((int)time(0)));
814
815 ini.writeFile("SwiftShader Configuration File\n"
816 ";\n"
817 "; To get an overview of the valid settings and their meaning,\n"
818 "; run the application in windowed mode and open the\n"
819 "; SwiftConfig application or go to http://localhost:8080/swiftconfig.");
820 }
821}