English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Asm / Hardware

 
 
Thread Tools
Old 24 November 2020, 15:53   #1
Ernst Blofeld
<optimized out>

Ernst Blofeld's Avatar
 
Join Date: Sep 2020
Location: <optimized out>
Posts: 304
BLITHOG and Interrupts

I have a triple buffered display system that uses a copper interrupt to change the displayed buffer before the vertical blank happens.

I am using the blitter to clear my back buffer.

My WaitForBlitter function currently turns on BLITHOG while it's waiting.

Is this a mistake?

If I'm waiting for the blitter with BLITHOG on and the blit goes on past when the copper interrupt should trigger, will the interrupt be delayed until later, possibly late enough to cause issues, or will it just not happen at all?

If it's the former then I need to change stuff, if it's the latter, I probably need to think more and maybe do some tests and timings.

Edit:

How dangerous would it be to have the copper turn off BLITHOG just after triggering its interrupt?

Last edited by Ernst Blofeld; 24 November 2020 at 17:19.
Ernst Blofeld is offline  
Old 24 November 2020, 17:46   #2
defor
Registered User

 
Join Date: Jun 2020
Location: Brno
Posts: 55
Quote:
Originally Posted by Ernst Blofeld View Post
I have a triple buffered display system that uses a copper interrupt to change the displayed buffer before the vertical blank happens..........

Depends if CPU opcodes are read from chip or fast memory. CPU will be interrupted in any case (I think INTREQ bits are just compared with INTENA bits and CPU is interrupted accordingly, INTREQ bits are set by devices). In the first case, if there are no free memory cycles available for CPU then it will just wait. Even if a new same-level interrupt request arrives (INTREQ bit is set by a device again) it doesn't do anything because CPU must clear INTREQ bit first for interrupt to be triggered. And a bit clearing can't happen because CPU is waiting to get access to fetch a new instruction opcode. I think your interrupt code will be handled immediately after CPU will get the time to proceed.
In the latter case, CPU can fetch opcodes immediately therefore CPU will do all interrupt procedures immediately (storing return address, fetching jump address, ...).
Or maybe I'm completely wrong and therefore I apologize.
defor is offline  
Old 24 November 2020, 18:43   #3
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 1,144
Quote:
Originally Posted by Ernst Blofeld View Post
My WaitForBlitter function currently turns on BLITHOG while it's waiting.

Is this a mistake?
It depends. If the blitter leaves no free cycles to the CPU, which may happen depending on the blit mode, then the CPU cannot access the chip ram bus. Thus, if the autovectors are in chip ram (they typically are, at address 0) then the CPU cannot fetch the interrupt vector, and hence the system is stuck. If the interrupt processing routine is in chip ram, it will also require cycles to process the interrupt.


In particular, the Os requires(!) regular interrupt processing, which you cannot guarantee in such a setup, so it is in general not recommended.


Quote:
Originally Posted by Ernst Blofeld View Post
How dangerous would it be to have the copper turn off BLITHOG just after triggering its interrupt?
This would allow the CPU to process the interrupt, at least. Otherwise, the interrupt will be delayed until the CPU receives the bus to retrieve the interrupt auto vector.
Thomas Richter is online now  
Old 24 November 2020, 19:03   #4
Ernst Blofeld
<optimized out>

Ernst Blofeld's Avatar
 
Join Date: Sep 2020
Location: <optimized out>
Posts: 304
Quote:
Originally Posted by Thomas Richter View Post
his would allow the CPU to process the interrupt, at least. Otherwise, the interrupt will be delayed until the CPU receives the bus to retrieve the interrupt auto vector.
This sounds like a low risk option to try. If it doesn't work out, I'll drop using BLITHOG completely. The only thing that concerns me is whether there are any race conditions around the setting and clearing of BLITHOG, that's just something I don't yet know about well enough yet.
Ernst Blofeld is offline  
Old 25 November 2020, 10:54   #5
hooverphonique
ex. demoscener "Bigmama"

 
Join Date: Jun 2012
Location: Fyn / Denmark
Posts: 1,255
Be careful that you don't end up with something where (on rare occasion) the cpu could enable blithog just when the copper disabled it (and just before the actual cpu interrupt is triggered), thus locking itself out.
hooverphonique is offline  
Old 25 November 2020, 11:55   #6
defor
Registered User

 
Join Date: Jun 2020
Location: Brno
Posts: 55
May I ask you why do you turn the blitter-nasty bit on and off? I'm just curious. I know there was a long discussion about this bit here. It's often suggested to enable it so that the blitter can use (almost?) every available time cycle for the job. And sometimes it's better to let it be off so that CPU and blitter run in parallel...
Also, why do you use interrupts? Isn't it a waste of CPU time to go in and out of interrupt code? Again, I'm just curious what your scenario is.
defor is offline  
Old 25 November 2020, 12:19   #7
roondar
Registered User

 
Join Date: Jul 2015
Location: The Netherlands
Posts: 2,890
Waiting with BLITHOG on is normally more efficient than waiting without it for certain blits (compared to waiting with BLITHOG off). However, it's not always faster and causes some issues with interrupt handling as discussed above. If you're running with the OS & multitasking up I'd strongly recommend against doing this.

Regarding interrupt based blitting, this is generally less efficient on low-spec Amiga's than polling due to the high overhead for interrupts compared to other options. However, there are advantages as well so it may still be a good option.

It all depends
roondar is offline  
Old 25 November 2020, 12:27   #8
Ernst Blofeld
<optimized out>

Ernst Blofeld's Avatar
 
Join Date: Sep 2020
Location: <optimized out>
Posts: 304
Quote:
Originally Posted by defor View Post
May I ask you why do you turn the blitter-nasty bit on and off? I'm just curious. I know there was a long discussion about this bit here. It's often suggested to enable it so that the blitter can use (almost?) every available time cycle for the job. And sometimes it's better to let it be off so that CPU and blitter run in parallel...
Also, why do you use interrupts? Isn't it a waste of CPU time to go in and out of interrupt code? Again, I'm just curious what your scenario is.
The way I understand it is: If I'm waiting for the blitter then the CPU is accessing memory just to get those test and loop instructions, therefore not every possible cycle is available for the blitter. Setting BLITHOG gives the blitter priority and a few more precious cycles at a time when the CPU isn't doing any useful work. If I had useful work to do I would be doing it in parallel, but I don't. Maybe I should be striving for a more balanced work blitter balance to make this point moot, but at the moment I do have to wait for the blitter.

Regarding interrupts, they are how I make sure I switch display buffers at the right time, just before vertical blank, without busy waiting.
Ernst Blofeld is offline  
Old 25 November 2020, 12:52   #9
Ernst Blofeld
<optimized out>

Ernst Blofeld's Avatar
 
Join Date: Sep 2020
Location: <optimized out>
Posts: 304
Quote:
Originally Posted by roondar View Post
for certain blits
This might be the key. I'm only clearing the screen, using just the DEST channel, so the blitter isn't using enough cycles for it to matter.
Ernst Blofeld is offline  
Old 25 November 2020, 13:02   #10
defor
Registered User

 
Join Date: Jun 2020
Location: Brno
Posts: 55
Quote:
Originally Posted by Ernst Blofeld View Post
The way I understand it is: If I'm waiting for the blitter then the CPU is accessing memory just to get those test and loop instructions, therefore not every possible cycle is available for the blitter. Setting BLITHOG gives the blitter priority and a few more precious cycles at a time when the CPU isn't doing any useful work. If I had useful work to do I would be doing it in parallel, but I don't. Maybe I should be striving for a more balanced work blitter balance to make this point moot, but at the moment I do have to wait for the blitter.

Thank you. Now I understand.


Quote:
Originally Posted by Ernst Blofeld View Post
Regarding interrupts, they are how I make sure I switch display buffers at the right time, just before vertical blank, without busy waiting.
Is it possible to swap buffers (copper-list) directly by the copper instead of doing it by CPU?
defor is offline  
Old 25 November 2020, 13:14   #11
Ernst Blofeld
<optimized out>

Ernst Blofeld's Avatar
 
Join Date: Sep 2020
Location: <optimized out>
Posts: 304
Quote:
Originally Posted by defor View Post
Is it possible to swap buffers (copper-list) directly by the copper instead of doing it by CPU?
The actual swapping part, yes, but I don't know how you'd put the intelligence into a copper list to know which buffer to switch to and when. If you poke the addresses into the copper list then you get timing issues to deal with - you'd have to busy wait until you were at a safe time to do it. I don't know how the overhead of this would compare to a regular interrupt.

I haven't thought it through any more than that. I suspect you may need more than three buffers to make it work though.
Ernst Blofeld is offline  
Old 25 November 2020, 13:20   #12
roondar
Registered User

 
Join Date: Jul 2015
Location: The Netherlands
Posts: 2,890
Quote:
Originally Posted by Ernst Blofeld View Post
This might be the key. I'm only clearing the screen, using just the DEST channel, so the blitter isn't using enough cycles for it to matter.
Indeed, this is one of the blits where it doesn't matter: Blitter clear won't be faster using BLITHOG and the CPU won't be halted either because of the Blitter idle cycles during clearing.

It can even be worthwhile to use the CPU to clear some part of the bitmap you're clearing with the Blitter at the same time as the clear runs (in the optimal case this can greatly increase the clearing speed).
roondar is offline  
Old 25 November 2020, 13:31   #13
Ernst Blofeld
<optimized out>

Ernst Blofeld's Avatar
 
Join Date: Sep 2020
Location: <optimized out>
Posts: 304
Quote:
Originally Posted by roondar View Post
It can even be worthwhile to use the CPU to clear some part of the bitmap you're clearing with the Blitter at the same time as the clear runs (in the optimal case this can greatly increase the clearing speed).
I've thought about that too, and I may be regretting using interleaved bitmaps as I can't easily get the blitter to do some of them while I draw a background with the CPU into the others.
Ernst Blofeld is offline  
Old 25 November 2020, 13:40   #14
roondar
Registered User

 
Join Date: Jul 2015
Location: The Netherlands
Posts: 2,890
You could instead clear the top of the bitmap with the Blitter and bottom with the CPU (or vice versa) - no problems with interleaved that way
roondar is offline  
Old 25 November 2020, 13:42   #15
Ernst Blofeld
<optimized out>

Ernst Blofeld's Avatar
 
Join Date: Sep 2020
Location: <optimized out>
Posts: 304
Quote:
Originally Posted by roondar View Post
You could instead clear the top of the bitmap with the Blitter and bottom with the CPU (or vice versa) - no problems with interleaved that way
That feels a bit like hitting one bird with one stone though.
Ernst Blofeld is offline  
Old 25 November 2020, 13:45   #16
roondar
Registered User

 
Join Date: Jul 2015
Location: The Netherlands
Posts: 2,890
I feel that I might be missing something here, because I'm not sure why that would be. If you run both CPU and Blitter at the same time, you'll should get the benefit irrespective of whether you do it by plane or by Y position (for Blitter clearing that is).

Maybe I misunderstood what you wanted to do?
roondar is offline  
Old 25 November 2020, 14:05   #17
Ernst Blofeld
<optimized out>

Ernst Blofeld's Avatar
 
Join Date: Sep 2020
Location: <optimized out>
Posts: 304
Quote:
Originally Posted by roondar View Post
I feel that I might be missing something here, because I'm not sure why that would be. If you run both CPU and Blitter at the same time, you'll should get the benefit irrespective of whether you do it by plane or by Y position (for Blitter clearing that is).

Maybe I misunderstood what you wanted to do?
Well, we've drifted away from the original topic about whether BLITHOG could break my interrupt code, which turned out to be moot because I was never going to get any advantage from it, but, I just meant that if I was to clear part of the screen with the CPU, then maybe the very best thing to do would be to get rid of the interleaved bitmaps I'm currently using so that I could draw something with the CPU rather than just helping the blitter clear.

I have a vague idea about mixing 3D polygon objects with blitted objects, which is why I chose interleaved, to make the blitted stuff faster and easier. I think I need to flesh that out before deciding the details on screen clearing.
Ernst Blofeld is offline  
Old 25 November 2020, 14:17   #18
roondar
Registered User

 
Join Date: Jul 2015
Location: The Netherlands
Posts: 2,890
Oh, I see what you mean. I thought you wanted both CPU & Blitter to just clear. It does change a bit if you want one to clear and the other to draw. Anyway, I fully agree it's best to flesh out your idea further before committing to a detail such as how to clear the screen.

However, I do want to point out that it is in fact possible to clear/draw on just a some bitplanes using interleaved mode (albeit it's a bit less intuitive than having fully separated bitplanes in memory). All you really need to do is calculate the correct modulo value to add between planes when you move forward a line and you should be able to address single bitplanes in the bitmap just fine.

It gets a bit harder when you want to address multiple bitplanes in the same blit, but even that can be worked around to a certain degree (for instance, it's fairly simple to blit to either all the odd or even bitplanes if you have an even number of bitplanes in use).
roondar is offline  
Old 25 November 2020, 14:31   #19
Ernst Blofeld
<optimized out>

Ernst Blofeld's Avatar
 
Join Date: Sep 2020
Location: <optimized out>
Posts: 304
Quote:
Originally Posted by roondar View Post
...it is in fact possible to clear/draw on just a some bitplanes using interleaved mode (albeit it's a bit less intuitive than having fully separated bitplanes in memory). All you really need to do is calculate the correct modulo value to add between planes when you move forward a line and you should be able to address single bitplanes in the bitmap just fine.

It gets a bit harder when you want to address multiple bitplanes in the same blit, but even that can be worked around to a certain degree (for instance, it's fairly simple to blit to either all the odd or even bitplanes if you have an even number of bitplanes in use).
I hadn't thought about this until now, but now that you've pointed it out I can see that I should be able to blit clear the first three of my four bitplanes by setting the width to be that of 3 bitplanes and the modulo to be the width of 1.

I'm not sure why that didn't occur to me as I already have to pretend that my screen is twice as wide as it is to get around the 10:6 limit of BLTSIZE.

I'm going to go and check my maths, and maybe just implement it now, as it's an easy win.
Ernst Blofeld is offline  
Old 25 November 2020, 15:18   #20
Ernst Blofeld
<optimized out>

Ernst Blofeld's Avatar
 
Join Date: Sep 2020
Location: <optimized out>
Posts: 304
Quote:
Originally Posted by Ernst Blofeld View Post
I'm going to go and check my maths, and maybe just implement it now, as it's an easy win.
So, I've done that:

Code:
void FillScreen(void) {
    WaitForBlitter();

    custom->bltcon0 = DEST | 0xff;
    custom->bltcon1 = 0x0000;
    custom->bltdpt = currentBuffer;
    custom->bltdmod = DISPLAY_WIDTH_IN_BYTES;

    custom->bltsize = (DISPLAY_HEIGHT << 6) + 3 * DISPLAY_WIDTH_IN_WORDS;

    ULONG * p = (ULONG *) currentBuffer;
    for (UWORD i = 0; i < DISPLAY_HEIGHT; i++) {
        p += 3 * DISPLAY_WIDTH_IN_LONGS;
        for (UWORD j = 0; j < DISPLAY_WIDTH_IN_LONGS; j++)
            *p++ = 0xFFFFFFFF;
    }
}
And my blitter waits no longer show up in the profiler view, and I can see that the blitting now finished part way through the calculation phase I have before I start drawing my objects to the screen.

So, I have successfully removed the idle time my code spent waiting for the blitter.

My frames per second have increased... from 9.01 to 9.05.
Ernst Blofeld is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
VBL interrupts (VBCC) LastManStanding Coders. C/C++ 14 14 October 2020 12:14
Damn Interrupts mcgeezer Coders. Asm / Hardware 10 24 March 2019 16:50
CIA interrupts... bloodline Coders. System 6 18 January 2018 10:33
Blithog behavior ovale Coders. Asm / Hardware 5 12 January 2015 08:05
Advice on interrupts and jumps alexh Coders. General 11 20 May 2008 09:42

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 09:04.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2021, vBulletin Solutions Inc.
Page generated in 0.15101 seconds with 14 queries