Page 1 of 2 12 LastLast
Results 1 to 10 of 18

Thread: FBGFX Plasma acceleration using asmosphere

  1. #1
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,128
    Rep Power
    732

    FBGFX Plasma acceleration using asmosphere

    Hi Charles and Misthema,

    I stole a work of you both to create hi-speed version of the plasma effect,
    here is the first optimization - replacing:
    [code=thinbasic]
    c= (Sin((x+y+t)/100)+Cos((x-t)/100)+Cos((y-t)/100)+Cos((x-y+t)/100))*2+Sin(t/100)*15
    [/code]
    ... with assembler.

    [code=thinbasic]
    'Plasma-like effect with FBGFX
    uses "FBGFX"
    uses "OXYGEN"

    Dim w,h As Double
    w=200
    h=150

    FBGFX_ScreenRes(w,h,32,2)

    Dim x,y,page As single
    Dim c,t As single
    dim divisor, two, fifteen As single
    divisor = 100
    two = 2
    fifteen = 15

    dim EvaluateC as string="
    ' (
    fld dword [#x] ' Sin((x+y+t)/100)
    fadd dword [#y]
    fadd dword [#t]
    fdiv DWORD [#divisor]
    fsin

    fld dword [#x] ' Cos((x-t)/100)
    fsub dword [#t]
    fdiv DWORD [#divisor]
    fcos
    faddp st(1)

    fld dword [#y] ' Cos((y-t)/100)
    fsub dword [#t]
    fdiv DWORD [#divisor]
    fcos
    faddp st(1)

    fld dword [#x] ' Cos((x-y+t)/100)
    fsub dword [#y]
    fadd dword [#t]
    fdiv DWORD [#divisor]
    fcos
    faddp st(1) ')

    fmul DWORD [#two] '*2

    fld dword [#t] ' Sin(t/100)*15
    fdiv DWORD [#divisor]
    fsin
    fmul DWORD [#fifteen]
    faddp st(1)

    fst dword [#c] ' -> store to c

    ret
    "

    dim codeToEvaluateC as string=O2_asm(EvaluateC)
    if codeToEvaluateC=chr$(&hc3) then msgbox 0, codeToEvaluateC

    while FBGFX_InKey() <> "q" 'Program runs until "q" is pressed
    t=t+1
    For x = 0 To w' step 3
    For y = 0 To h' step 3
    MC_EXEC(codeToEvaluateC)
    REM c= (Sin((x+y+t)/100)+Cos((x-t)/100)+Cos((y-t)/100)+Cos((x-y+t)/100))*2+Sin(t/100)*15

    FBGFX_Color(Rgb(Sin(c)*64+128,Cos(c)*64+128,Cos(-c/2)*64+12, 0)
    FBGFX_Circle(x,y,3)
    Next
    Next

    'pageflip
    page=-page+1
    FBGFX_Sync(1)
    FBGFX_ScreenSet(page,-page+1)

    wend
    [/code]

    It works ;D, at this stage this version is ~1.5x faster than original.

    Question for now - I want to use numbers in operations, not specified using variables ( currently managed as using "two", "divisor" and "fifteen" variables, which is a bit odd ).
    How that can be done in Asmosphere ?


    Thanks,
    Petr
    Learn 3D graphics with ThinBASIC, learn TBGL!
    Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB

  2. #2

    Re: FBGFX Plasma acceleration using asmosphere

    Hi Petr,

    Two problems to resolve.

    First you can't feed literal numbers into the FPU, nor can it read CPU registers. It can only access numbers which are already present in memory. This leads to the second problem: How do you get local workspace, to store the temporary numbers, without using thinBasic variables?

    The solution to the latter is to allocate memory on the stack by subtracting the required space from the stack pointer like this:

    sub esp,1000

    then using another register to index from.

    mov ecx,esp

    Now you can store integers

    mov dword [ecx+00],15
    mov dword [ecx+04],42

    ..etc

    then you can load them into the FPU as dword integers

    fild dword [ecx+00]

    When you have finished it is vital to disallocate the memory from the stack.
    This can be done by adding the space back to the stack pointer:

    add esp,1000
    ret


    To create local variables using macro symbols:

    def aa [ecx]
    def bb [ecx+04]
    def workspace 1000

    then

    add esp, workspace$
    mov ecx,esp
    mov aa$,15
    fild aa$
    ....
    add esp,workspace$
    ret


    In the next update I am about to send, the '$' will no longer be needed and further adjustments to the syntax allow system calls to be made in the same way as a high level language.




  3. #3
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,128
    Rep Power
    732

    Re: FBGFX Plasma acceleration using asmosphere

    Thanks for the explanation,

    I think I would not figure it out myself


    Thanks,
    Petr
    Learn 3D graphics with ThinBASIC, learn TBGL!
    Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB

  4. #4

    Re: FBGFX Plasma acceleration using asmosphere

    Petr,

    I think I've exposed a bug! So I have adjusted my above example to avoid it, moving the esp by 1000 instead of 100. I am just tracing through...

    Also 'ret 1000' should not be used in this method of allocation.

    I am delighted your program works and you have made sense of the FPU.

  5. #5
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,128
    Rep Power
    732

    Re: FBGFX Plasma acceleration using asmosphere

    Hi Charles,

    when I optimized further, I got some black screen - it is caused by code evaluating Red color component.
    As long as it is uncommented all work as it should, maybe this is side effect of some bug?

    But I like the module so far, as assembler is so similar to language use on my calculator I find it very comfortable.

    [code=thinbasic]
    'Plasma-like effect with FBGFX
    uses "FBGFX"
    uses "OXYGEN"

    Dim w,h As Double
    w=200
    h=150

    FBGFX_ScreenRes(w,h,32,2)

    Dim x,y,page As single
    Dim c,t As single
    dim divisor, two, fifteen As single
    divisor = 100
    two = 2
    fifteen = 15

    dim EvaluateC as string="
    ' (
    fld dword [#x] ' Sin((x+y+t)/100)
    fadd dword [#y]
    fadd dword [#t]
    fdiv DWORD [#divisor]
    fsin

    fld dword [#x] ' Cos((x-t)/100)
    fsub dword [#t]
    fdiv DWORD [#divisor]
    fcos
    faddp st(1)

    fld dword [#y] ' Cos((y-t)/100)
    fsub dword [#t]
    fdiv DWORD [#divisor]
    fcos
    faddp st(1)

    fld dword [#x] ' Cos((x-y+t)/100)
    fsub dword [#y]
    fadd dword [#t]
    fdiv DWORD [#divisor]
    fcos
    faddp st(1) ')

    fmul DWORD [#two] '*2

    fld dword [#t] ' Sin(t/100)*15
    fdiv DWORD [#divisor]
    fsin
    fmul DWORD [#fifteen]
    faddp st(1)

    fst dword [#c] ' -> store to c

    ret
    "

    dim v64, v128 as single
    dim Red, Green, Blue as single = 255
    v64 = 64
    v128 = 128
    dim EvaluateR as string = _
    "
    fld dword [#c]
    fsin
    fmul DWORD [#v64]
    fadd DWORD [#v128]
    fst dword [#Red] ' -> store to Red

    ret
    "
    dim EvaluateG as string = _
    "
    fld dword [#c]
    fcos
    fmul DWORD [#v64]
    fadd DWORD [#v128]
    fst dword [#Green] ' -> store to Green

    ret
    "
    dim EvaluateB as string = _
    "
    fld dword [#c]
    fchs ' change sign
    fdiv DWORD [#two]
    fcos
    fmul DWORD [#v64]
    fadd DWORD [#v128]
    fst dword [#Blue] ' -> store to Blue

    ret
    "


    dim codeToEvaluateC as string = O2_asm(EvaluateC)
    dim codeToEvaluateR as string = O2_asm(EvaluateR)
    dim codeToEvaluateG as string = O2_asm(EvaluateG)
    dim codeToEvaluateB as string = O2_asm(EvaluateB)

    if codeToEvaluateC = chr$(&hc3) then
    msgbox 0, "Error in EvaluateC, program will end now"
    stop
    elseif codeToEvaluateR = chr$(&hc3) then
    msgbox 0, "Error in EvaluateR, program will end now"
    stop
    elseif codeToEvaluateG = chr$(&hc3) then
    msgbox 0, "Error in EvaluateG, program will end now"
    stop
    elseif codeToEvaluateB = chr$(&hc3) then
    msgbox 0, "Error in EvaluateB, program will end now"
    stop
    end if


    dim t1, t2 as double

    while FBGFX_InKey() <> "q" 'Program runs until "q" is pressed
    t1 = gettickcount
    t=t+1
    For x = 0 To w' step 3
    For y = 0 To h' step 3
    REM MC_EXEC(codeToEvaluateR) ' -- If commented out, red defaults to 255
    MC_EXEC(codeToEvaluateC)
    MC_EXEC(codeToEvaluateG)
    MC_EXEC(codeToEvaluateB)
    FBGFX_Color(Rgb(red,green, blue), 0)

    FBGFX_circle(x, y, 3)
    Next
    Next

    'pageflip
    page=-page+1
    FBGFX_Sync(1)
    FBGFX_ScreenSet(page,-page+1)
    t2 = gettickcount
    wend

    msgbox 0, "FrameTime:"+STR$(t2-t1)
    [/code]

    Thanks,
    Petr
    Learn 3D graphics with ThinBASIC, learn TBGL!
    Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB

  6. #6

    Re: FBGFX Plasma acceleration using asmosphere


    Hi Petr

    If you comment out any one of the colors, it does not produce a black screen. The screen is black when all three are used.

    I tweaked the color code to end with FSTP insted of FST but I dont think this was causing any problems here.

    [code=thinbasic]
    dim EvaluateR as string = _
    "
    fld dword [#c]
    fsin
    fmul DWORD [#v64]
    fadd DWORD [#v128]
    fstp dword [#Red] ' -> store to Red

    ret
    "
    [/code]

  7. #7

    Re: FBGFX Plasma acceleration using asmosphere

    Wow, the assembler puts the word interpreted into a totally new contex. Amazing what is possible. I didn't try the code so far. But do I read it correctly? In the assembler code, you can interface easily with the thinBAsic variables? If yes, then it's awesome.

  8. #8
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,128
    Rep Power
    732

    Re: FBGFX Plasma acceleration using asmosphere

    Yes,

    it is pretty cool

    You just put assembler in the string, with links to thinBASIC variable, then perform kind of JIT using O2_ASM, and since then you can execute the resultant machine code using MC_EXEC.


    Bye,
    Petr
    Learn 3D graphics with ThinBASIC, learn TBGL!
    Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB

  9. #9
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,128
    Rep Power
    732

    Re: FBGFX Plasma acceleration using asmosphere

    Hi,

    just updating the version, works ok ( no black ) with latest Oxygen.

    [code=thinbasic]
    'Plasma-like effect with FBGFX
    uses "FBGFX"
    uses "OXYGEN"

    Dim w,h As Double
    w=200
    h=150

    FBGFX_ScreenRes(w,h,32,2)

    Dim x,y,page As single
    Dim c,t As single
    dim divisor, two, fifteen As single
    divisor = 100
    two = 2
    fifteen = 15

    dim EvaluateC as string="
    ' (
    fld dword [#x] ' Sin((x+y+t)/100)
    fadd dword [#y]
    fadd dword [#t]
    fdiv DWORD [#divisor]
    fsin

    fld dword [#x] ' Cos((x-t)/100)
    fsub dword [#t]
    fdiv DWORD [#divisor]
    fcos
    faddp st(1)

    fld dword [#y] ' Cos((y-t)/100)
    fsub dword [#t]
    fdiv DWORD [#divisor]
    fcos
    faddp st(1)

    fld dword [#x] ' Cos((x-y+t)/100)
    fsub dword [#y]
    fadd dword [#t]
    fdiv DWORD [#divisor]
    fcos
    faddp st(1) ')

    fmul DWORD [#two] '*2

    fld dword [#t] ' Sin(t/100)*15
    fdiv DWORD [#divisor]
    fsin
    fmul DWORD [#fifteen]
    faddp st(1)

    fst dword [#c] ' -> store to c

    ret
    "

    dim v64, v128 as single
    dim Red, Green, Blue as single = 255
    v64 = 64
    v128 = 128
    dim EvaluateR as string = _
    "
    fld dword [#c]
    fsin
    fmul DWORD [#v64]
    fadd DWORD [#v128]
    fstp dword [#Red] ' -> store to Red

    ret
    "
    dim EvaluateG as string = _
    "
    fld dword [#c]
    fcos
    fmul DWORD [#v64]
    fadd DWORD [#v128]
    fstp dword [#Green] ' -> store to Green

    ret
    "
    dim EvaluateB as string = _
    "
    fld dword [#c]
    fchs ' change sign
    fdiv DWORD [#two]
    fcos
    fmul DWORD [#v64]
    fadd DWORD [#v128]
    fstp dword [#Blue] ' -> store to Blue

    ret
    "


    dim codeToEvaluateC as string = O2_asm(EvaluateC)
    dim codeToEvaluateR as string = O2_asm(EvaluateR)
    dim codeToEvaluateG as string = O2_asm(EvaluateG)
    dim codeToEvaluateB as string = O2_asm(EvaluateB)

    if codeToEvaluateC = chr$(&hc3) then
    msgbox 0, "Error in EvaluateC, program will end now"
    stop
    elseif codeToEvaluateR = chr$(&hc3) then
    msgbox 0, "Error in EvaluateR, program will end now"
    stop
    elseif codeToEvaluateG = chr$(&hc3) then
    msgbox 0, "Error in EvaluateG, program will end now"
    stop
    elseif codeToEvaluateB = chr$(&hc3) then
    msgbox 0, "Error in EvaluateB, program will end now"
    stop
    end if


    dim t1, t2 as double

    while FBGFX_InKey() <> "q" 'Program runs until "q" is pressed
    t1 = gettickcount
    t=t+1
    For x = 0 To w' step 3
    For y = 0 To h' step 3
    MC_EXEC(codeToEvaluateR) ' -- If commented out, red defaults to 255
    MC_EXEC(codeToEvaluateC)
    MC_EXEC(codeToEvaluateG)
    MC_EXEC(codeToEvaluateB)
    FBGFX_Color(Rgb(red,green, blue), 0)

    FBGFX_circle(x, y, 3)
    Next
    Next

    'pageflip
    page=-page+1
    FBGFX_Sync(1)
    FBGFX_ScreenSet(page,-page+1)
    t2 = gettickcount
    wend

    msgbox 0, "FrameTime:"+STR$(t2-t1)
    [/code]


    Petr
    Learn 3D graphics with ThinBASIC, learn TBGL!
    Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB

  10. #10
    thinBasic MVPs kryton9's Avatar
    Join Date
    Nov 2006
    Location
    Naples, Florida & Duluth, Georgia
    Age
    67
    Posts
    3,869
    Rep Power
    404

    Re: FBGFX Plasma acceleration using asmosphere

    Petr, is the latest asmosphere in thinBasic preview the correct one to test the new script?
    Acer Notebook: Win 10 Home 64 Bit, Core i7-4702MQ @ 2.2Ghz, 12 GB RAM, nVidia GTX 760M and Intel HD 4600
    Raspberry Pi 3: Raspbian OS use for Home Samba Server and Test HTTP Server

Page 1 of 2 12 LastLast

Similar Threads

  1. FBGFX module for thinBasic, to handle 2D graphics
    By misthema in forum Experimental modules or library interface
    Replies: 39
    Last Post: 01-05-2008, 14:04

Members who have read this thread: 0

There are no members to list at the moment.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •