Recent

Author Topic: Баги CYBERGRAPHICS AmigaOS 4.1  (Read 4430 times)

Smalovsky

  • Newbie
  • Posts: 5
Баги CYBERGRAPHICS AmigaOS 4.1
« on: September 18, 2023, 02:29:56 pm »
Попробовал использовать библиотеку сайберграфикс для FreePascal 3.2.2 for AmigaOS 4.1 PPC. У меня эмулятор амиги 4000 WinUAE с эмуляцией видеокарты Picasso4 на шине Zorro3  и ускорителя Cyberstorm с 126 МБ fast RAM и процессором 604e.
Я попробовал узнать характеристики видеорежимов с помощью листинга:
Code: Pascal  [Select][+][-]
  1. Program CGX_Test;
  2. uses  exec, sysutils, utility, intuition,agraphics,cybergraphics;
  3. var
  4.  
  5.         execlist:PList;
  6.         cybernode:PCyberModeNode;
  7.  
  8. begin
  9.  
  10.  
  11.  
  12.         execlist:=AllocCModeListTagList(nil);
  13.         if execlist <> nil then writeln('cyber');
  14.         cybernode:=PCyberModeNode(execlist^.lh_Head);
  15.         while cybernode<>nil do
  16.         begin
  17.                 writeln('Mode ',cybernode^.ModeText);
  18.                 writeln('Width ',cybernode^.Width);
  19.                 writeln('Height ',cybernode^.Height);
  20.                 writeln('Depth ',cybernode^.Depth);
  21.                 writeln();
  22.                 cybernode:=PCyberModeNode(cybernode^.Node.ln_Succ);
  23.         end;
  24.  
  25. end.
  26.  

Информация о видеорежимах содержит ошибки. Значения высоты, ширины, глубины цвета и другие поля перепутаны в записи типа TCyberModeNode.
Сделал небольшую коррекцию через указатель:

Code: Pascal  [Select][+][-]
  1. Program CGX_Test;
  2. uses  exec, sysutils, utility, intuition,agraphics,cybergraphics;
  3. var
  4.  
  5.         execlist:PList;
  6.         cybernode:PCyberModeNode;
  7.         p:^Word;
  8.  
  9. begin
  10.         execlist:=AllocCModeListTagList(nil);
  11.         if execlist <> nil then writeln('cyber');
  12.         cybernode:=PCyberModeNode(execlist^.lh_Head);
  13.         while cybernode<>nil do
  14.         begin
  15.                 writeln('Mode ',cybernode^.ModeText);
  16.                 p:=@cybernode^.Width;
  17.                  writeln('Width ',(p-1)^);
  18.                 // writeln('Width ',cybernode^.Width);
  19.                 p:=@cybernode^.Height;
  20.                  writeln('Height ',(p-1)^);
  21.                 //writeln('Height ',cybernode^.Height);
  22.                 p:=@cybernode^.Depth;
  23.                 writeln('Depth ',(p-1)^);
  24.                 //writeln('Depth ',cybernode^.Depth);
  25.                 writeln();
  26.                 cybernode:=PCyberModeNode(cybernode^.Node.ln_Succ);
  27.         end;
  28.  

Теперь вывело правильно ширину, высоту и глубину для видеорежимов. Другие поля я не трогал, но в них тоже напутано.

Как  и кому отправить мне этот баг?

Сам баг:
Неправильное выполнение функции AllocCModeListTagList. Функция возвращает список, элементы которого при приведении к типу указателя PCyberModeNode и получении записи типа TCyberModeNode  по этому указателю содержат неправильные значения( значения перепутаны для полей записи).
« Last Edit: September 20, 2023, 04:07:46 pm by Smalovsky »

AlexTP

  • Hero Member
  • *****
  • Posts: 2488
    • UVviewsoft
Re: Баги CHYBERGRAPHICS AmigaOS 4.1
« Reply #1 on: September 18, 2023, 04:55:52 pm »
исправьте заголовок поста. там опечатка в названии.

так как либа из поставки FPC, то отправлять это надо на FPC bugtracker, вот сюда
https://gitlab.com/freepascal.org/fpc/source/-/issues

нужен акаунт Гитхаб или Гитлаб.
нужен пост на английском.
« Last Edit: September 18, 2023, 04:57:57 pm by AlexTP »

TRon

  • Hero Member
  • *****
  • Posts: 3647
Re: Баги CYBERGRAPHICS AmigaOS 4.1
« Reply #2 on: September 18, 2023, 06:37:55 pm »
If you can wait a day with reporting it as a bug then I can have it verified. I believe you have a mistake in your code.
This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

TRon

  • Hero Member
  • *****
  • Posts: 3647
Re: Баги CYBERGRAPHICS AmigaOS 4.1
« Reply #3 on: September 20, 2023, 12:15:32 am »
Sorry to say that I have managed to wreck my (custom) fs-uae installation before I was able to verify. Go ahead and report so that it won't be forgotten (I need time to set up fs-uae correctly for OS4 again).

Sorry for the inconvenience.

On a side note: the (original) code as presented should work (it does work for/on Amiga/AROS) but there are some minor nitpicking things such as the fact that the list is not traversed entirely correct (last entry is not a valid mode entry but a list end entry) and you forgot to free the allocated modelist.

At first glance it seems to me that one of the record fields is wrongly aligned (which is an RTL related issue if the case).
This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

Smalovsky

  • Newbie
  • Posts: 5
Re: Баги CYBERGRAPHICS AmigaOS 4.1
« Reply #4 on: September 21, 2023, 03:36:37 pm »
Мне помогли с переводом. Попробую отослать на багтрейкер. Вот перевод первого сообщения:

Hi,

While using AmigaOS4 PPC OS (on WinUAE emulator emulating Amiga4000 with graphics card for me) and FreePascal 3.2.2 for AmigaOS4.1 i do have a problem when trying to use CyberGraphics library:

Firstly, i tried to get videomode's properties with this kind of code:

Code: Pascal  [Select][+][-]
  1. Program CGX_Test;
  2. uses  exec, sysutils, utility, intuition,agraphics,cybergraphics;
  3. var
  4.  
  5.         execlist:PList;
  6.         cybernode:PCyberModeNode;
  7.  
  8. begin
  9.  
  10.  
  11.  
  12.         execlist:=AllocCModeListTagList(nil);
  13.         if execlist <> nil then writeln('cyber');
  14.         cybernode:=PCyberModeNode(execlist^.lh_Head);
  15.         while cybernode<>nil do
  16.         begin
  17.                 writeln('Mode ',cybernode^.ModeText);
  18.                 writeln('Width ',cybernode^.Width);
  19.                 writeln('Height ',cybernode^.Height);
  20.                 writeln('Depth ',cybernode^.Depth);
  21.                 writeln();
  22.                 cybernode:=PCyberModeNode(cybernode^.Node.ln_Succ);
  23.         end;
  24.  
  25. end.
  26.  

But returned information contain bugs. Height, width, depth and other fields just messed around into TCyberModeNode. So i made a small modification via pointer:

Code: Pascal  [Select][+][-]
  1. Program CGX_Test;
  2. uses  exec, sysutils, utility, intuition,agraphics,cybergraphics;
  3. var
  4.  
  5.         execlist:PList;
  6.         cybernode:PCyberModeNode;
  7.         p:^Word;
  8.  
  9. begin
  10.         execlist:=AllocCModeListTagList(nil);
  11.         if execlist <> nil then writeln('cyber');
  12.         cybernode:=PCyberModeNode(execlist^.lh_Head);
  13.         while cybernode<>nil do
  14.         begin
  15.                 writeln('Mode ',cybernode^.ModeText);
  16.                 p:=@cybernode^.Width;
  17.                  writeln('Width ',(p-1)^);
  18.                 // writeln('Width ',cybernode^.Width);
  19.                 p:=@cybernode^.Height;
  20.                  writeln('Height ',(p-1)^);
  21.                 //writeln('Height ',cybernode^.Height);
  22.                 p:=@cybernode^.Depth;
  23.                 writeln('Depth ',(p-1)^);
  24.                 //writeln('Depth ',cybernode^.Depth);
  25.                 writeln();
  26.                 cybernode:=PCyberModeNode(cybernode^.Node.ln_Succ);
  27.         end;
  28. end.
  29.  

So then i have correct width, height and depth. Other fields i didn't touch, but they messed too.

To whom i should send a bug report ?

The bug itself are:

Wrong return of the AllocCModeListTagList(): Function return a list, elements of which when casting to a pointer type PCyberModeNode and returning of TCyberModeNode by this pointer contain wrong values (they just messed around in wrong fields).
« Last Edit: September 21, 2023, 03:50:47 pm by Smalovsky »

TRon

  • Hero Member
  • *****
  • Posts: 3647
Re: Баги CYBERGRAPHICS AmigaOS 4.1
« Reply #5 on: September 22, 2023, 06:40:22 am »
@Smalovsky:
I was able to confirm this issue for fpc 3.2.2. I have not checked if it is already fixed in fpc trunk (the default os alignment for records should usually take care of this)

It is indeed an alignment issue for the record structure TCyberModeNode in unit cybergraphics (OS4units).

In order to fix it you have to change that structure to a packed record.

Currently you can use two options to workaround the issue:
1: declare the fixed correct structure inside your program
2: copy the cybergraphics.pas header-file next to your project and in that copied file, fix the record structure. During compilation the compiler will then automatically pick up on the (modified/fixed) cybergraphics unit in your project directory first.

So for example, for using the workaround inside a project you could use:
Code: Pascal  [Select][+][-]
  1. program ListCGFXModes;
  2.  
  3. uses
  4.   exec, agraphics, cybergraphics;
  5.  
  6. type
  7.    PCyberModeNode = ^TCyberModeNode;
  8.    TCyberModeNode = packed record   // <--- make it a packed record
  9.      Node: TNode;
  10.      ModeText: array[0..DISPLAYNAMELEN - 1] of Char; // name for this mode
  11.      DisplayID: ULONG;                               // display id associated with the node
  12.      Width: UWORD;                                   // visible width
  13.      Height: UWORD;                                  // visible height
  14.      Depth: UWORD;                                   // display depth
  15.      DisplayTagList: PTagItem;                       // taglist with extended ModeID information
  16.    end;
  17.  
  18. procedure ListModes;
  19. var
  20.   nodeList: PList;
  21.   node: PNode;
  22.   cgxNode: PCyberModeNode absolute node;
  23. begin
  24.   nodeList := AllocCModeListTagList(nil);
  25.   if assigned(nodeList) then
  26.   begin
  27.     node := nodelist^.lh_head;
  28.     while assigned(node^.ln_succ) do
  29.     begin
  30.       write('Mode = '    , cgxNode^.ModeText);
  31.       write('  Width  = ', cgxNode^.Width);
  32.       write('  Height = ', cgxNode^.Height);
  33.       write('  Depth  = ', cgxNode^.Depth);
  34.       writeln;
  35.       node := node^.ln_succ;
  36.     end;
  37.     FreeCModeList(nodeList);
  38.   end
  39.   else
  40.     writeln('Unable to obtain CGFX Mode list');
  41. end;
  42.  
  43. begin
  44.   ListModes;
  45. end.
  46.  

Also note the use of a more correct way to travers the nodelist (for more information about exec lists and how to use them see here and in particular this) as well as freeing the allocated list.


As written by alextp, bugs can be reported at gitlab: https://gitlab.com/freepascal.org/fpc/source/-/issues

Sorry for me to keep corresponding in English, I meant no disrespect by doing so (I just can't read/write Russian and I do not like butchering my response by using a online translator). Thank you for reporting !
« Last Edit: September 22, 2023, 07:05:49 am by TRon »
This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

Smalovsky

  • Newbie
  • Posts: 5
Re: Баги CYBERGRAPHICS AmigaOS 4.1
« Reply #6 on: December 08, 2024, 09:39:52 am »
Из-за того что я использую эмулятор, мне трудно оценить скорость библиотеки.
Я написал два теста для оценки скорости библиотеки.
Первый тест статический, в котором оценивается скорость вывода пиксельного массива в окно размером 640 на 480 пикселей. Пиксельный массив 500 раз выводится на экран, и затем оценивается показатель fps.
Второй тест динамический, который длится около 50 секунд. Пиксельный массив формируется каждый кадр по определённым правилам. Этот тест показывает общую производительность системы  с помощью показателя fps.
Пожалуйста, помогите мне определить степень замедления эмулятора по сравнению с реальными компьютерами. Проведите тесты и напишите - какую машину использовали и результаты тестов(fps).
У меня вышло: первый тест 9.4 fps , второй 2.2 fps.
Google translation:
Because I use an emulator, it is difficult for me to estimate the speed of the library.
I wrote two tests to estimate the speed of the library.
The first test is static, which estimates the speed of outputting a pixel array to a window of 640 by 480 pixels. The pixel array is output to the screen 500 times, and then the fps indicator is estimated.
The second test is dynamic, which lasts about 50 seconds. The pixel array is formed every frame according to certain rules. This test shows the overall performance of the system using the fps indicator.
Please help me determine the degree of slowdown of the emulator compared to real computers. Run the tests and write - which machine was used and the test results (fps).
I got: the first test 9.4 fps, the second 2.2 fps.

1. Static test

Code: Pascal  [Select][+][-]
  1. Program Cyber_fps;
  2. uses  exec, sysutils, utility, intuition,agraphics,cybergraphics,timer,math;
  3.  
  4. var
  5.         win:PWindow;
  6.         done:Boolean=False;
  7.         Msg:PMessage;
  8.         pix_array:ARRAY[0..307199] of ULONG;
  9.         x,y:Integer;
  10.         color_part1,color_part2,color_part3:ULONG;
  11.         tr:PTimerequest;
  12.         tp:PMsgPort;
  13.         start_sec,end_sec:ULONG;
  14.         start_micro,end_micro:ULONG;
  15.         ptm:PTimeval;
  16.         test_time:float;
  17.         n,i:Integer;
  18.         fps:float;
  19.         err:longint;
  20.  
  21. begin
  22.         tp:=createport(nil,0);
  23.         if tp=nil then
  24.           halt()
  25.         else
  26.           begin
  27.            tr:=PTimerequest(CreateExtIO(tp,Sizeof(TTimerequest)));
  28.            if tr=nil  then
  29.             begin
  30.              deleteport(tp);
  31.              halt();
  32.             end
  33.           else
  34.              begin
  35.               err:=OpenDevice(TIMERNAME,UNIT_MICROHZ,PIORequest(tr),0);
  36.               if  err<>0 then
  37.                begin
  38.                 DeleteExtIO(PIORequest(tr));
  39.                 DeletePort(tp);
  40.                 halt();
  41.                end;
  42.               end;
  43.              end;
  44.  
  45.         tr^.tr_Node.io_Command:=TR_GETSYSTIME;
  46.  
  47.         win:=OpenWindowTags(nil,
  48.         [WA_InnerWidth,AsTag(640),
  49.         WA_InnerHeight,AsTag(480),
  50.         WA_MinWidth,AsTag(100),
  51.         WA_MinHeight,AsTag(100),
  52.         WA_Left,AsTag(300),
  53.         WA_Top,AsTag(50),
  54.         WA_Title,AsTag('My Window'),
  55.         WA_DepthGadget,AsTag(True),
  56.         WA_SizeGadget,AsTag(True),
  57.         WA_DragBar,AsTag(True),
  58.         WA_Flags,WFLG_Closegadget or WFLG_GIMMEZEROZERO,
  59.         WA_IDCMP,IDCMP_CLOSEWINDOW or IDCMP_REFRESHWINDOW,
  60.         TAG_END]);
  61.  
  62.         for y:=0 to 479 do
  63.         begin
  64.         for x:=0 to 639 do
  65.         begin
  66.          color_part1:=x;
  67.          color_part2:=$F00;
  68.          color_part3:=(x+y);
  69.          pix_array[y*640+x]:=(color_part1 xor color_part2 or color_part3) and $00FFFFFF;
  70.         end;
  71.        end;
  72.        n:=500;
  73.        DoIO(PIORequest(tr));
  74.        ptm:=@tr^.tr_time;
  75.        start_sec:=ptm^.tv_secs;
  76.        start_micro:=ptm^.tv_micro;
  77.        for i:=0 to n do
  78.        WritePixelArray(@pix_array,0,0,640*SizeOf(ULONG),win^.RPort,0,0,640,480,RECTFMT_ARGB);
  79.  
  80.        DoIO(PIORequest(tr));
  81.        ptm:=@tr^.tr_time;
  82.        end_sec:=ptm^.tv_secs;
  83.        end_micro:=ptm^.tv_micro;
  84.        test_time:=end_sec-start_sec+(end_micro-start_micro)/1000000;
  85.        fps:=n/test_time;
  86.        writeln('start sec= ',start_sec,' start micro= ',start_micro);
  87.        writeln('end sec= ',end_sec,' end micro= ',end_micro);
  88.        writeln('test time= ',test_time:10:5);
  89.        writeln('fps= ',fps:10:5);
  90.        repeat
  91.                 WaitPort(Win^.UserPort);
  92.                 Msg:=GetMsg(Win^.UserPort);
  93.                 case PIntuiMessage(Msg)^.IClass of
  94.                         IDCMP_CloseWindow:
  95.                                 done:=True;
  96.  
  97.                 end;
  98.                 ReplyMsg(Msg);
  99.         Until done;
  100.         CloseDevice(PIORequest(tr));
  101.         DeleteExtIO(PIORequest(tr));
  102.         DeletePort(tp);
  103.         CloseWindow(Win);
  104. end.
  105.  

2. Dynamic test

Code: Pascal  [Select][+][-]
  1. Program Cyber_fps2;
  2. uses  exec, sysutils, utility, intuition,agraphics,cybergraphics,timer,math;
  3.  
  4. var
  5.         win:PWindow;
  6.         done:Boolean=False;
  7.         Msg:PMessage;
  8.         pix_array:ARRAY[0..307199] of ULONG;
  9.         x,y:Integer;
  10.         color_part1,color_part2,color_part3:ULONG;
  11.         tr:PTimerequest;
  12.         tp:PMsgPort;
  13.         start_sec,end_sec:ULONG;
  14.         start_micro,end_micro:ULONG;
  15.         ptm:PTimeval;
  16.         test_time:float;
  17.         n:LongInt;
  18.         fps:float;
  19.         err:LongInt;
  20.         r,dir:UBYTE;
  21. begin
  22.         tp:=createport(nil,0);
  23.         if tp=nil then
  24.           halt()
  25.         else
  26.           begin
  27.            tr:=PTimerequest(CreateExtIO(tp,Sizeof(TTimerequest)));
  28.            if tr=nil  then
  29.             begin
  30.              deleteport(tp);
  31.              halt();
  32.             end
  33.           else
  34.              begin
  35.               err:=OpenDevice(TIMERNAME,UNIT_MICROHZ,PIORequest(tr),0);
  36.               if  err<>0 then
  37.                begin
  38.                 DeleteExtIO(PIORequest(tr));
  39.                 DeletePort(tp);
  40.                 halt();
  41.                end;
  42.               end;
  43.              end;
  44.  
  45.         tr^.tr_Node.io_Command:=TR_GETSYSTIME;
  46.  
  47.         win:=OpenWindowTags(nil,
  48.         [WA_InnerWidth,AsTag(640),
  49.         WA_InnerHeight,AsTag(480),
  50.         WA_MinWidth,AsTag(100),
  51.         WA_MinHeight,AsTag(100),
  52.         WA_Left,AsTag(300),
  53.         WA_Top,AsTag(50),
  54.         WA_Title,AsTag('My Window'),
  55.         WA_DepthGadget,AsTag(True),
  56.         WA_SizeGadget,AsTag(True),
  57.         WA_DragBar,AsTag(True),
  58.         WA_Flags,WFLG_Closegadget or WFLG_GIMMEZEROZERO,
  59.         WA_IDCMP,IDCMP_CLOSEWINDOW or IDCMP_REFRESHWINDOW,
  60.         TAG_END]);
  61.         randomize;
  62.  
  63.        n:=0;
  64.        test_time:=0;
  65.        r:=0;
  66.        dir:=1;
  67.        DoIO(PIORequest(tr));
  68.        ptm:=@tr^.tr_time;
  69.        start_sec:=ptm^.tv_secs;
  70.        start_micro:=ptm^.tv_micro;
  71.        repeat
  72.         for y:=0 to 479 do
  73.          begin
  74.           for x:=0 to 639 do
  75.            begin
  76.             color_part1:=x+system.random(r);
  77.             color_part2:=y+system.random(r);
  78.             color_part3:=(x+y)+system.random(r);
  79.             pix_array[y*640+x]:=(color_part1 or color_part2 or color_part3) and $00FFFFFF;
  80.            end;
  81.          end;
  82.        if dir=1 then
  83.         begin
  84.          r:=r+1;
  85.          if r=50 then dir:=2;
  86.         end
  87.        else
  88.         begin
  89.          r:=r-1;
  90.          if r=0 then dir:=1;
  91.         end;
  92.        WritePixelArray(@pix_array,0,0,640*SizeOf(ULONG),win^.RPort,0,0,640,480,RECTFMT_ARGB);
  93.        DoIO(PIORequest(tr));
  94.        ptm:=@tr^.tr_time;
  95.        end_sec:=ptm^.tv_secs;
  96.        end_micro:=ptm^.tv_micro;
  97.        test_time:=end_sec-start_sec+(end_micro-start_micro)/1000000;
  98.        n:=n+1;
  99.       until test_time>50;
  100.  
  101.        fps:=n/test_time;
  102.        writeln('start sec= ',start_sec,' start micro= ',start_micro);
  103.        writeln('end sec= ',end_sec,' end micro= ',end_micro);
  104.        writeln('test time= ',test_time:10:5);
  105.        writeln('fps= ',fps:10:5);
  106.        repeat
  107.                 WaitPort(Win^.UserPort);
  108.                 Msg:=GetMsg(Win^.UserPort);
  109.                 case PIntuiMessage(Msg)^.IClass of
  110.                         IDCMP_CloseWindow:
  111.                                 done:=True;
  112.  
  113.                 end;
  114.                 ReplyMsg(Msg);
  115.         Until done;
  116.         CloseDevice(PIORequest(tr));
  117.         DeleteExtIO(PIORequest(tr));
  118.         DeletePort(tp);
  119.         CloseWindow(Win);
  120. end.
  121.  
 

 

TinyPortal © 2005-2018