move the tests under the debug folder
[AROS.git] / debug / test / smp / smp-smallpt / main.c
blob99697562a5f9e7015983963a6941e4f018d84a4e
1 /*
2 Copyright 2017, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define DEBUG 1
7 #include <aros/debug.h>
9 #include <proto/exec.h>
10 #include <proto/dos.h>
11 #include <proto/processor.h>
12 #include <proto/kernel.h>
14 #include <proto/dos.h>
15 #include <proto/graphics.h>
16 #include <proto/cybergraphics.h>
17 #include <proto/intuition.h>
18 #include <proto/timer.h>
20 #include <exec/tasks.h>
21 #include <exec/ports.h>
22 #include <exec/lists.h>
23 #include <exec/rawfmt.h>
24 #include <resources/processor.h>
25 #include <cybergraphx/cybergraphics.h>
27 #include "renderer.h"
29 CONST_STRPTR version = "$VER: SMP-Smallpt 1.0 (03.03.2017) ©2017 The AROS Development Team";
31 APTR KernelBase;
33 struct Window * createMainWindow(int req_width, int req_height)
35 struct Screen *pubScreen;
36 struct Window *displayWin = NULL;
37 int width, height;
39 pubScreen = LockPubScreen(0);
41 if (pubScreen)
43 width = ((pubScreen->Width * 4) / 5) & ~0x1f;
44 height = (width * 3 / 4) & ~0x1f;
46 if (req_width && req_width < width)
47 width = req_width & ~0x1f;
48 if (req_height && req_height < height)
49 height = req_height & ~0x1f;
51 if (height >= (pubScreen->Height * 4) / 5)
53 height = ((pubScreen->Height * 4) / 5) & ~0x1f;
54 width = (height * 4 / 3) & ~0x1f;
57 else
59 width = 320;
60 height = 240;
63 if ((displayWin = OpenWindowTags(0,
64 WA_PubScreen, (IPTR)pubScreen,
65 WA_Left, 0,
66 WA_Top, (pubScreen) ? pubScreen->BarHeight : 10,
67 WA_InnerWidth, width,
68 WA_InnerHeight, height,
69 WA_Title, (IPTR) "SMP-Smallpt renderer",
70 WA_SimpleRefresh, TRUE,
71 WA_CloseGadget, TRUE,
72 WA_DepthGadget, TRUE,
73 WA_DragBar, TRUE,
74 WA_SizeGadget, FALSE,
75 WA_SizeBBottom, FALSE,
76 WA_SizeBRight, FALSE,
77 WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW,
78 TAG_DONE)) != NULL)
80 if (pubScreen)
81 UnlockPubScreen(0, pubScreen);
84 return displayWin;
87 #define ARG_TEMPLATE "MAXCPU/N,MAXITER/N,WIDTH/N,HEIGHT/N,RAYDEPTH/N,EXPLICIT/S"
88 #define ARG_MAXCPU 0
89 #define ARG_MAXITER 1
90 #define ARG_WIDTH 2
91 #define ARG_HEIGHT 3
92 #define ARG_RAYDEPTH 4
93 #define ARG_EXPLICIT 5
95 int main()
97 APTR ProcessorBase;
98 IPTR args[6] = { 0, 0, 0, 0, 0, 0 };
99 struct RDArgs *rda;
100 int max_cpus = 0;
101 int max_iter = 0;
102 int req_width = 0, req_height = 0;
103 char tmpbuf[200];
104 int explicit_mode = 0;
105 struct MsgPort *timerPort = CreateMsgPort();
106 struct timerequest *tr = CreateIORequest(timerPort, sizeof(struct timerequest));
107 struct TimerBase *TimerBase = NULL;
108 struct timeval start_time;
109 struct timeval now;
111 struct Window *displayWin;
112 struct BitMap *outputBMap = NULL;
114 IPTR coreCount = 1;
115 struct TagItem tags[] =
117 {GCIT_NumberOfProcessors, (IPTR)&coreCount},
118 {0, (IPTR)NULL}};
120 ProcessorBase = OpenResource(PROCESSORNAME);
121 if (!ProcessorBase)
122 return 0;
124 KernelBase = OpenResource("kernel.resource");
125 if (!KernelBase)
126 return 0;
128 if (timerPort)
130 FreeSignal(timerPort->mp_SigBit);
131 timerPort->mp_SigBit = -1;
132 timerPort->mp_Flags = PA_IGNORE;
135 if (tr)
137 if (!OpenDevice("timer.device", UNIT_VBLANK, (struct IORequest *)tr, 0))
139 TimerBase = (struct TimerBase *)tr->tr_node.io_Device;
141 } else return 0;
143 GetCPUInfo(tags);
145 D(bug("[SMP-Smallpt] %s: detected %d CPU cores\n", __func__, coreCount);)
147 rda = ReadArgs(ARG_TEMPLATE, args, NULL);
148 if (rda != NULL)
150 LONG *ptr = (LONG *)args[ARG_MAXCPU];
151 if (ptr)
152 max_cpus = *ptr;
154 ptr = (LONG *)args[ARG_RAYDEPTH];
155 if (ptr) {
156 maximal_ray_depth = *ptr;
157 if (maximal_ray_depth < 2)
158 maximal_ray_depth = 2;
161 ptr = (LONG *)args[ARG_MAXITER];
162 if (ptr)
164 max_iter = *ptr;
165 if (max_iter < 2)
166 max_iter = 2;
167 else if (max_iter > 10000)
168 max_iter = 10000;
171 ptr = (LONG *)args[ARG_WIDTH];
172 if (ptr)
173 req_width = *ptr;
175 if (req_width && req_width < 160)
176 req_width = 160;
178 if (req_height && req_height < 128)
179 req_height = 128;
181 ptr = (LONG *)args[ARG_HEIGHT];
182 if (ptr)
183 req_height = *ptr;
185 if (max_cpus > 0 && coreCount > max_cpus)
186 coreCount = max_cpus;
188 if (max_iter == 0)
189 max_iter = 16;
191 explicit_mode = args[ARG_EXPLICIT];
194 // NewRawDoFmt("Hello %s", RAWFMTFUNC_STRING, buffer, "world!");
196 displayWin = createMainWindow(req_width, req_height);
197 if (displayWin)
199 int width, height;
200 struct RastPort *outBMRastPort;
201 ULONG *workBuffer;
202 int windowClosing = FALSE;
203 struct MsgPort *mainPort = CreateMsgPort();
204 struct MsgPort *rendererPort = NULL;
205 ULONG signals;
206 struct Task *renderer;
207 struct Message *msg;
208 struct MyMessage cmd;
209 BOOL busyPointer = FALSE;
210 int tasksWork = 0;
211 int tasksIn = 0;
212 int tasksOut = 0;
214 width = (displayWin->Width - displayWin->BorderLeft - displayWin->BorderRight);
215 height = (displayWin->Height - displayWin->BorderTop - displayWin->BorderBottom);
217 D(bug("[SMP-Smallpt] %s: Created window with inner size of %dx%d\n", __func__, width, height);)
218 D(bug("[SMP-Smallpt] %s: Tiles amount %dx%d\n", __func__, width / 32, height / 32);)
220 outputBMap = AllocBitMap(
221 width,
222 height,
223 GetBitMapAttr(displayWin->WScreen->RastPort.BitMap, BMA_DEPTH),
224 BMF_DISPLAYABLE, displayWin->WScreen->RastPort.BitMap);
226 outBMRastPort = CreateRastPort();
227 outBMRastPort->BitMap = outputBMap;
229 workBuffer = AllocMem(width * height * sizeof(ULONG), MEMF_ANY|MEMF_CLEAR);
231 WritePixelArray(workBuffer,
232 0, 0, width * sizeof(ULONG),
233 outBMRastPort,
234 0, 0,
235 width, height,
236 RECTFMT_ARGB);
238 BltBitMapRastPort (outputBMap, 0, 0,
239 displayWin->RPort, displayWin->BorderLeft, displayWin->BorderTop,
240 width, height, 0xC0);
242 D(bug("[SMP-Smallpt] %s: Creating renderer task\n", __func__);)
244 renderer = NewCreateTask(TASKTAG_NAME, "SMP-Smallpt Master",
245 TASKTAG_AFFINITY, TASKAFFINITY_ANY,
246 TASKTAG_PRI, 0,
247 TASKTAG_PC, Renderer,
248 TASKTAG_ARG1, SysBase,
249 TASKTAG_ARG2, mainPort,
250 //TASKTAG_STACKSIZE, 10000000,
251 //TASKTAG_USERDATA , &workMaster,
252 TAG_DONE);
253 (void)renderer;
255 D(bug("[SMP-Smallpt] %s: waiting for welcome message form renderer\n", __func__);)
256 WaitPort(mainPort);
257 msg = GetMsg(mainPort);
258 rendererPort = msg->mn_ReplyPort;
259 ReplyMsg(msg);
261 cmd.mm_Type = MSG_STARTUP;
262 cmd.mm_Message.mn_Length = sizeof(cmd);
263 cmd.mm_Message.mn_ReplyPort = mainPort;
264 cmd.mm_Body.Startup.ChunkyBM = workBuffer;
265 cmd.mm_Body.Startup.Width = width;
266 cmd.mm_Body.Startup.Height = height;
267 cmd.mm_Body.Startup.coreCount = coreCount;
268 cmd.mm_Body.Startup.numberOfSamples = max_iter;
269 cmd.mm_Body.Startup.explicitMode = explicit_mode;
271 D(bug("[SMP-Smallpt] %s: renderer alive. sending startup message\n", __func__);)
273 PutMsg(rendererPort, &cmd.mm_Message);
274 WaitPort(mainPort);
275 GetMsg(mainPort);
277 D(bug("[SMP-Smallpt] %s: enter main loop\n", __func__);)
279 GetSysTime(&start_time);
281 while ((!windowClosing) && ((signals = Wait(SIGBREAKF_CTRL_D | (1 << displayWin->UserPort->mp_SigBit) | (1 << mainPort->mp_SigBit))) != 0))
283 // CTRL_D is redraw signal
284 if (signals & SIGBREAKF_CTRL_D)
286 WritePixelArray(workBuffer,
287 0, 0, width * sizeof(ULONG),
288 outBMRastPort,
289 0, 0,
290 width, height,
291 RECTFMT_ARGB);
293 BltBitMapRastPort (outputBMap, 0, 0,
294 displayWin->RPort, displayWin->BorderLeft, displayWin->BorderTop,
295 width, height, 0xC0);
297 if (signals & (1 << displayWin->UserPort->mp_SigBit))
299 struct IntuiMessage *msg;
300 while ((msg = (struct IntuiMessage *)GetMsg(displayWin->UserPort)))
302 switch(msg->Class)
304 case IDCMP_CLOSEWINDOW:
305 D(bug("[SMP-Smallpt] %s: window closing pressed\n", __func__);)
307 windowClosing = TRUE;
308 break;
310 case IDCMP_REFRESHWINDOW:
311 D(bug("[SMP-Smallpt] %s: Displaying output BitMap (REFRESHWINDOW)\n", __func__);)
312 BeginRefresh(msg->IDCMPWindow);
313 BltBitMapRastPort (outputBMap, 0, 0,
314 msg->IDCMPWindow->RPort, msg->IDCMPWindow->BorderLeft, msg->IDCMPWindow->BorderTop,
315 width, height, 0xC0);
316 EndRefresh(msg->IDCMPWindow, TRUE);
317 break;
319 ReplyMsg((struct Message *)msg);
322 if (signals & (1 << mainPort->mp_SigBit))
324 struct MyMessage *msg;
326 while ((msg = (struct MyMessage *)GetMsg(mainPort)))
328 if (msg->mm_Message.mn_Length == sizeof(struct MyMessage))
330 switch (msg->mm_Type)
332 case MSG_REDRAWTILE:
333 WritePixelArray(workBuffer,
334 msg->mm_Body.RedrawTile.TileX * TILE_SIZE,
335 msg->mm_Body.RedrawTile.TileY * TILE_SIZE, width * sizeof(ULONG),
336 outBMRastPort,
337 msg->mm_Body.RedrawTile.TileX * TILE_SIZE,
338 msg->mm_Body.RedrawTile.TileY * TILE_SIZE,
339 TILE_SIZE, TILE_SIZE, RECTFMT_ARGB);
341 BltBitMapRastPort (outputBMap,
342 msg->mm_Body.RedrawTile.TileX * TILE_SIZE,
343 msg->mm_Body.RedrawTile.TileY * TILE_SIZE,
344 displayWin->RPort,
345 displayWin->BorderLeft + msg->mm_Body.RedrawTile.TileX * TILE_SIZE, displayWin->BorderTop + msg->mm_Body.RedrawTile.TileY * TILE_SIZE,
346 TILE_SIZE, TILE_SIZE, 0xC0);
347 break;
349 case MSG_STATS:
350 tasksWork = msg->mm_Body.Stats.tasksWork;
351 tasksIn = msg->mm_Body.Stats.tasksIn;
352 tasksOut = msg->mm_Body.Stats.tasksOut;
354 GetSysTime(&now);
355 SubTime(&now, &start_time);
356 NewRawDoFmt("SMP-Smallpt renderer (%d in work, %d waiting, %d done): %d:%02d:%02d", RAWFMTFUNC_STRING,
357 tmpbuf, tasksWork, tasksIn, tasksOut,
358 now.tv_secs / 3600,
359 (now.tv_secs / 60) % 60,
360 now.tv_secs % 60);
361 SetWindowTitles(displayWin, tmpbuf, NULL);
362 if ((busyPointer) && (msg->mm_Body.Stats.tasksWork == 0))
364 SetWindowPointer(displayWin, WA_BusyPointer, FALSE, TAG_DONE);
365 busyPointer = FALSE;
367 else if ((!busyPointer) && (msg->mm_Body.Stats.tasksWork > 0))
369 SetWindowPointer(displayWin, WA_BusyPointer, TRUE, TAG_DONE);
370 busyPointer = TRUE;
372 break;
374 default:
375 D(bug("[SMP-Smallpt] %s: unhandled message (%d) arrived\n", __func__, msg->mm_Type);)
377 ReplyMsg(&msg->mm_Message);
383 D(bug("[SMP-Smallpt] %s: Send DIE msg to renderer\n", __func__);)
385 struct MyMessage quitmsg;
386 quitmsg.mm_Message.mn_ReplyPort = mainPort;
387 quitmsg.mm_Message.mn_Length = sizeof(quitmsg);
388 quitmsg.mm_Type = MSG_DIE;
390 PutMsg(rendererPort, &quitmsg.mm_Message);
391 int can_quit = 0;
392 do {
393 WaitPort(mainPort);
394 struct MyMessage *msg;
395 while ((msg = (struct MyMessage *)GetMsg(mainPort)))
396 if (msg->mm_Type == MSG_DIE)
397 can_quit = 1;
398 } while(!can_quit);
400 DeleteMsgPort(mainPort);
402 CloseWindow(displayWin);
403 FreeRastPort(outBMRastPort);
404 FreeBitMap(outputBMap);
405 FreeMem(workBuffer, width * height * sizeof(ULONG));
407 D(bug("[SMP-Smallpt] %s: goodbye\n", __func__);)
408 #if 0
409 for (int ty = 0; ty < height/32; ty++)
411 for (int tx = 0; tx < width/32; tx++)
413 D(bug("[SMP-Smallpt] %s: Rendering tile %d,%d\n", __func__, tx, ty));
415 render_tile(width, height, 1024, tx, ty, workBuffer);
417 D(bug("[SMP-Smallpt] %s: Redrawing\n", __func__));
419 WritePixelArray(workBuffer,
420 tx*32, ty*32, width * sizeof(ULONG),
421 outBMRastPort,
422 tx*32, ty*32,
423 32, 32,
424 RECTFMT_ARGB);
426 BltBitMapRastPort (outputBMap, tx*32, ty*32,
427 displayWin->RPort, displayWin->BorderLeft + tx*32, displayWin->BorderTop + ty*32,
428 32, 32, 0xC0);
431 #endif
434 return 0;