English Amiga Board


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

View Poll Results: Can you end up with continuous 16 pixel wide output for this problem?
Yes, I believe it can be done! 3 42.86%
No, I don't think it can! 4 57.14%
Voters: 7. You may not vote on this poll

 
 
Thread Tools
Old 21 February 2012, 01:31   #1
Codetapper
2 contact me: email only!

Codetapper's Avatar
 
Join Date: May 2001
Location: Auckland / New Zealand
Posts: 3,150
Question Is it possible to combine 2 different sized images with the blitter?

I have 2 images, one is a large bitmap, let's say it's a standard Amiga screen of 320x200. I want to extract a 16 pixel wide rectangle from it starting at any X position. For the sake of the example, let's say I want to grab 16 pixels from 45 pixels in from the left. Call this source A and is the black rectangle in the pic. The white rectange A represents the word aligned version (2 words needed to be fetched to contain the valid data).

Then I want to combine it with another one bitplane image which is only 16 pixels wide, and always word aligned. The data is continuous, so the 1st word is the top 16 pixels, the very next word is the word underneath. Call this source B. Note that B is not part of the source A image, it's just drawn there so you can see it.

The optimal output of this blit operation would be a single 16 pixel wide image, combining the 2 sources (I've used an AND operation in this case). In the example the final data I want is the green D image and again continous in memory. Is it possible?

Because source A is shifted, to extract the data from 45 pixels indented you would assume that you require a blit width of 2 words and set the bltapt to the white rectangle address. Then source B would need a modulo of -2 since it's 1 word wide but we're having to process 2 words. And the destination D you would also expect to have a modulo of -2.

Now for the problem!

This seems to be a trivial problem IF you are happy to have the destination end up as a 32 pixel wide masked image. However I would like a 16 pixel wide image!

If you operate the blitter in ascending mode, use a right shift of 16 - 5 = 11 for source A with a mask of $0000ffff, and have source B pointing to 1 word before the B data with a modulo of -2 and using a minterm D=AB, I believe it will process the first line correctly but when it comes to the second line, it'll end up overwriting the first lines data as the 1st word is junk (masked away and shifted) and the 2nd word is valid. Then the modulo of -2 will kick in, and the next line's junk 1st word will end up overwriting the valid word that it's just processed.

Operating the blitter in descending mode will surely do exactly the same but in reverse, the blitter as it operates will end up destroying the valid data just above it in memory.

So my question is, can you actually do this operation to end up with a continuous 16 pixel width destination, or do you have to put up with an extraneous word between each line?
Attached Thumbnails
Click image for larger version

Name:	blitter_mask_question.png
Views:	300
Size:	4.3 KB
ID:	30621  
Codetapper is offline  
Old 21 February 2012, 01:52   #2
Lonewolf10
AMOS Extensions Developer
Lonewolf10's Avatar
 
Join Date: Jun 2007
Location: near Cambridge, UK
Age: 39
Posts: 1,919
I'm no expert, so take this with a pinch of salt, but I think you'd have to do it as a 32 pixel wide image onto another bit of memory (offscreen). Then take your 16 pixel wide image from that and copy it onto your intended destination screen.

I'm interested to see what the others think...


Regards,
Lonewolf10
Lonewolf10 is offline  
Old 21 February 2012, 02:28   #3
h0ffman
Registered User
 
Join Date: Aug 2008
Location: Salisbury
Posts: 469
You're modulo values are all out. If the screen width is 320 (40 bytes) and the blit with 2 words, then the modulo on all channels would be 40-4 = 36

Don't know if that helps.
h0ffman is offline  
Old 21 February 2012, 02:47   #4
Codetapper
2 contact me: email only!

Codetapper's Avatar
 
Join Date: May 2001
Location: Auckland / New Zealand
Posts: 3,150
Quote:
Originally Posted by Lonewolf10 View Post
I'm no expert, so take this with a pinch of salt, but I think you'd have to do it as a 32 pixel wide image onto another bit of memory (offscreen). Then take your 16 pixel wide image from that and copy it onto your intended destination screen.

I'm interested to see what the others think...
Indeed. Unless there's some magic way possibly using another blitter channel or something.

Quote:
Originally Posted by h0ffman View Post
You're modulo values are all out. If the screen width is 320 (40 bytes) and the blit with 2 words, then the modulo on all channels would be 40-4 = 36

Don't know if that helps.
I didn't specify the A channel modulo - I left it out as I thought it was obvious. Indeed it would be 36 in this case. The modulos for B and D channels however would be -2 not 36 because I am not blitting to the screen - just to a 16 pixel wide buffer.


Just to add to the question, I can get around the problem by outputting to the 32 pixel buffer and using that, but it's an interesting exercise to see if it can be done. The RKMs mention Amiga fonts being stored in a packed format and extracted using masks with the blitter so perhaps there's a way to do it without using a wider buffer!
Codetapper is offline  
Old 21 February 2012, 12:36   #5
mc6809e
Registered User
 
Join Date: Jan 2012
Location: USA
Posts: 293
Simply extracting the shifted 16 pixel wide bitmap and writing it to a 16 pixel wide bitmap requires at least two reads/shifts for each write. There's no way around that. The only way you're going to get two reads for each write is to use multiple channels to combine the reads or you can use multiple blits, and that's before you get to do anything with the resulting 16 pixel chunks.

If you're just blitting to the 16 pixel wide destination, then the two blit solution is obvious. You have to treat the original source bitmap as two strips of 16 pixels each with the appropriate shifts and masks and merge the two strips into the destination. That's easy.

Now you can almost get away with a ONE blit merge by using channel A for the left strip, and channel B for the right strip and channel C for a special mask that acts as a selector taking some part of A and some part of B and merging them together with D writing to your 16 pixel wide destination. Channel A reads the left strip and shifts it. Channel B reads the right strip and shifts it. Then with the right minterms and auxiliary bitmap , channel C can pick and merge the two halves.

That sounds good, but there's a problem because you need at least one read ahead by A before you can get to the bits shifted right and you need those bits to merge with the shifted data in channel B.

The almost solution is to start source A at the top line of the left strip and source B at the line BEFORE the top line.

When the first line of pixels are read by A, they're shifted, and the remaining pixels are merged with B and the (incorrect) result is written to a dummy line immediately before the top of the destination.

When the second line is read, part of the data in A is now from the first line. Since B was started one line before A, you can mask off the right bits of A and merge the shifted in bits (now on the left) with the right shifted bits in B by using C to select the halves.

Like I said, this is almost a solution because it forces you to reserve a dummy location one line before the destination. And you're limited in your choices for C. While channel A has mask registers, channel B doesn't so you have to mask out B's extra bits with C's data. If channel B also had mask registers, then channel C would be free and things would be simple.

Depending on what you're trying to do, though, maybe these aren't problems.
mc6809e is offline  
Old 29 February 2012, 15:36   #6
Photon
Moderator
Photon's Avatar
 
Join Date: Nov 2004
Location: Hult / Sweden
Posts: 4,591
Regarding the original topic title: no. The blitter window is the same for all sources and destination in that a line in each is the same number of words. Some things may seem like changing the size, such as tripling the height blitting a 3 bitplane interleaved bob. Where the destination modulo is 0 you can also do some tricks.

Here the only thing that requires a line width of 2 words is that the 16-pixel sliver A is non-word aligned in most cases. You will never get the bits that are sticking into the next word with just a 1-word wide blit, simple as that. You can remove the requirement with a coSTly trick, keeping 16 differently scrolled backgrounds in memory.

With masking, you can make the blit affect a window up to 2 words less wide. The 2 word width and desired 1 word wide destination graphic makes the blitter pipelining come into play, and usually setting descending mode fixes that fine if source and destination overlaps for the final OR ("affect") operation. But in this case where destination and destination overlaps the destination must be cleared to start with, then first/last word mask used to only affect the last or first word of each line.

On Amiga, whenever a coder is given the choice of wasting cycles or memory, the answer is always memory. Make it two words wide and skip all the trickery, and check if it happens to be aligned to save half the cycles in 1/16 of the cases.

Voted yes as it can be done, if the destination is cleared first. I can't see any replacement of pixels in the destination not causing pipeline trashing in asc/desc mode.
Photon is offline  
Old 04 January 2018, 04:22   #7
adrazar
Registered User

 
Join Date: Feb 2017
Location: Oslo
Posts: 40
This thread describes no less than exactly what I have been dabbling with lately, but after reading it I still fail to see why such a blit can't be done...!

To make it dead simple, let's say we have an 32 pixel wide image and that we want to copy some 16 pixel wide subimage of this. Consider the following example: the image looks like this


10101010101010101010101010101010
11001100110011001100110011001100
11110000111100001111000011110000
11111111111111110000000000000000


and we want the subimage starting at offset 5. The way I would go about doing this is quite similar, although somewhat different, from Codetapper's initial suggestion. I set channel A to point at the full image and both channel C and D to the word immediately before the destination address (which in this case is a 16x4 chunk of memory). Furthermore I would set the A-shift value to 16-5=11, the first and last mask $07FF and $F800 respectively, and the modulo values for channel C and D to -2.

I will now do a simulation of what happens using this setup together with a minterm value of %11111010 and blitter size 2 words and 4 lines:

Channel A:
w1: 1010101010101010 -> 0000010101010101 (applying first word mask)
----------------------> 0000000000000000 (shifting right by 11)

w2: 1010101010101010 -> 1010100000000000 (applying last word mask)
----------------------> 1010101010101010 (shifting in 11 bits from w1)

Since only zeros are shifted out of w2 in the last step, this is what will be shifted into w1 when continuing with the next line. The words produced by channel A during the course of the blit will therefore be as follows:

Line 1: 0000000000000000 1010101010101010
Line 2: 0000000000000000 1001100110011001
Line 3: 0000000000000000 0000111100001111
Line 4: 0000000000000000 1111111111100000

The first word in each line is always 0. According to the minterm the resulting word should then be equal to the value in channel C. The first word grabbed by C is not in the allocated memory area, and is correctly put back in place with no alterations. Next word processed in channel C is the first word from the allocated memory area. Assuming that it's initialized to zero, the resulting word becomes an exact copy of the value in cannel A. This word is then repeated when processing the first word of the second line, next followed by copying the second word from cannel A into the second word of the copy. And so on.

But alas, it does not work this way when I try it in the emulator. What could be the reason?
adrazar is offline  
Old 04 January 2018, 16:41   #8
chb
Registered User

 
Join Date: Dec 2014
Location: germany
Posts: 106
@adrazar: I may not completely get what you are doing, but did you take into account that the blitter is pipelined? See http://amigadev.elowar.com/read/ADCD.../node0127.html for details. Second word from C is fetched before first word is written to D.
chb is offline  
Old 04 January 2018, 20:29   #9
adrazar
Registered User

 
Join Date: Feb 2017
Location: Oslo
Posts: 40
Quote:
Originally Posted by chb View Post
@adrazar: I may not completely get what you are doing, but did you take into account that the blitter is pipelined? See http://amigadev.elowar.com/read/ADCD.../node0127.html for details. Second word from C is fetched before first word is written to D.
You got it! The pipelining thing explains it all, thank you
adrazar is offline  
Old 13 February 2018, 22:42   #10
Blueberry
Registered User
 
Join Date: Dec 2007
Location: Aarhus / Denmark
Posts: 33
You can do it using just one source channel, provided you can trash a single word after the destination:

Plain A to D copy, descending mode. Set A shift (x) to shift A into the first word: $x9F00002

Point A to the second word of the first row of the source. Point D to the second row of the destination. Set A modulo to -44 (if source is 320 pixel wide) and D modulo to -6. Set first and last word mask to all ones.

The blitter will first write garbage to the second word, then the correct result to the first word. Then garbage to the third word, then the correct result to the second word, and so on. You will end up with the correct result plus an extra garbage word at the end.
Blueberry 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
Combine split .dms files? Photon support.Demos 15 14 September 2017 22:39
Please help me!! Blitter pain! h0ffman Coders. Asm / Hardware 5 15 June 2013 19:59
Did Starglider use the blitter? mc6809e Retrogaming General Discussion 8 04 February 2012 16:19
Wanted: Decent sized A1200 HD Peanutuk MarketPlace 2 18 February 2004 12:33

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 08:37.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2018, vBulletin Solutions Inc.
Page generated in 0.07412 seconds with 15 queries