Author Topic: GCW-Zero IPU screen scaling implementation  (Read 21328 times)

mth

  • Posts: 317
Re: GCW-Zero IPU screen scaling implementation
« Reply #20 on: October 10, 2014, 12:57:03 pm »
While the JZ4770 documentation is currently not publicly available, the JZ4780 documentation is and the IPU most likely didn't change all that much.

slaanesh (OP)

  • Posts: 569
    • Slaanesh Dev
Re: GCW-Zero IPU screen scaling implementation
« Reply #21 on: October 13, 2014, 03:28:48 am »
Are multiple calls to SDL_SetVideoMode() with different resolutions honored?

For example, if there is an initial call of:

Code: [Select]
SDL_SetVideoMode(400, 300, 16, SDL_HWSURFACE|SDL_TRIPLEBUF);
and then later:

Code: [Select]
SDL_SetVideoMode(392, 300, 16, SDL_HWSURFACE|SDL_TRIPLEBUF);
will the IPU handle the change in resolution?

hi-ban

  • Posts: 886
Re: GCW-Zero IPU screen scaling implementation
« Reply #22 on: October 13, 2014, 03:45:06 am »
Are multiple calls to SDL_SetVideoMode() with different resolutions honored?

For example, if there is an initial call of:

Code: [Select]
SDL_SetVideoMode(400, 300, 16, SDL_HWSURFACE|SDL_TRIPLEBUF);
and then later:

Code: [Select]
SDL_SetVideoMode(392, 300, 16, SDL_HWSURFACE|SDL_TRIPLEBUF);
will the IPU handle the change in resolution?

Yes, every time you change the resolution, the IPU will scale it accordingly. For example, Pocketsnes uses 320x240 in menu, but (if scaler is set to hardware) automatically changes the resolution to 256x224 (or 256x240 for some PAL games) when going to the game. And, of course, when calling the menu, it changes the resolution again to 320x240.

You could make a game which changes its resolution every second, and the IPU would handle it.
« Last Edit: October 13, 2014, 03:47:22 am by hi-ban »

slaanesh (OP)

  • Posts: 569
    • Slaanesh Dev
Re: GCW-Zero IPU screen scaling implementation
« Reply #23 on: October 13, 2014, 03:46:30 am »
Ok thanks.

hi-ban

  • Posts: 886
Re: GCW-Zero IPU screen scaling implementation
« Reply #24 on: October 13, 2014, 04:10:40 am »
However, if you set a resolution to be, lets say, 256x224 you shouldn't copy more than 256x224 pixels to the screen surface when using the IPU, because the app will probably crash.

When adding IPU support to Pocketsnes, it always crashed with some specific PAL games, which we later realised they were the ones which the emulator outputted as 256x239. The cause was that the resolution we were setting when using the IPU was always 256x224, so in those PAL games, 15 extra lines were copied to the screen, corrupting nearby memory.

The first attempts to fix those crashes didn't work because we were changing the resolution one frame late. But fortunately, Nebuleon managed to somehow make it change the resolution in the right frame.

Of course, copying a smaller image works ok.
You can also play with resolutions to achieve different scaling effects. For example, if you want to do horizontal scaling only, you can request a screen height of 240 and that way the height wont be scaled. (you need to turn off the aspect ratio preserving for this)
« Last Edit: October 13, 2014, 04:29:25 am by hi-ban »

slaanesh (OP)

  • Posts: 569
    • Slaanesh Dev
Re: GCW-Zero IPU screen scaling implementation
« Reply #25 on: October 13, 2014, 09:37:14 pm »
Oh, you could also use a shader for the rotation and palette lookup.

Yes, the Raspberry PI implements GL and have found examples of how to do rotation and scaling using a combination of DispmanX and GLES2. I've ported my application to it and it runs... okay... The GCW-Zero seems *much* faster than Raspberry Pi - true given the relative CPU speeds but even with the PI overclocked and using assembler CPU cores it's substantially slower.

So it seems that the GCW-Zero has the pretty much the same set of libraries that the Pi has for GLES2, I wonder if that would provide an alternate approach to scaling and rotation?

Also, back to the IPU scaling, are there any issues with odd resolutions, say, 395x253? Does it round up/down? If so do I need to compensate for it?

Nebuleon

  • Guest
Re: GCW-Zero IPU screen scaling implementation
« Reply #26 on: October 13, 2014, 09:51:32 pm »
<1 level of nested quoting omitted, and the part of the post about OpenGL ~Nebuleon>
Also, back to the IPU scaling, are there any issues with odd resolutions, say, 395x253? Does it round up/down? If so do I need to compensate for it?
You can request 395x253, and if the user makes a screenshot of that, it'll also be 395x253. But for display, the driver may do adjustments transparently. See http://wiki.gcw-zero.com/Hardware_Scaling#Limitations .

I'm not exactly qualified to answer about OpenGL, so I'll leave that part up to others.

pcercuei

  • Posts: 1676
    • My devblog
Re: GCW-Zero IPU screen scaling implementation
« Reply #27 on: October 13, 2014, 10:09:08 pm »
Some resolutions are indeed problematic. When scaling with a ratio of X:Y, X must be < 32 if upscaling, and Y must be < 32 if downscaling. But typically you will never run into this, unless you want say 319x239. In that case, the driver will return a higher resolution that works (in this case, 320x240). But SDL will detect that and center the image accordingly so that it will always work.

About the GLES shader, doing scaling there would not be useful. The IPU can scale the output of the GPU, too.
« Last Edit: October 13, 2014, 10:11:16 pm by pcercuei »

slaanesh (OP)

  • Posts: 569
    • Slaanesh Dev
Re: GCW-Zero IPU screen scaling implementation
« Reply #28 on: October 13, 2014, 11:56:12 pm »
So I don't need to compensate for any padding?

if I request a horizontal resolution of say 395, I can just write 395 pixels per line?

ie. from my previous example, using 253 lines, I would write in total 395x253xsizeof(short) bytes and it should be fine?

Currently, using the IPU for scaling for 395x253 and 392x253 I don't get "square" images, they look shifted by a few pixels each row.
When I use my software scaler, these work fine.

But it could still be something I am doing wrong, I'm still investigating. I just wanted to narrow down where the issue is.

Nebuleon

  • Guest
Re: GCW-Zero IPU screen scaling implementation
« Reply #29 on: October 14, 2014, 12:17:59 am »
a) if I request a horizontal resolution of say 395, I can just write 395 pixels per line?

ie. from my previous example, using 253 lines, I would write in total 395x253xsizeof(short) bytes and it should be fine?

b) Currently, using the IPU for scaling for 395x253 and 392x253 I don't get "square" images, they look shifted by a few pixels each row.
When I use my software scaler, these work fine.

But it could still be something I am doing wrong, I'm still investigating. I just wanted to narrow down where the issue is.
a) Yes.

b) According to http://wiki.gcw-zero.com/Hardware_Scaling#Limitations

320/395 => 64/79. The denominator of the scaling fraction is larger than 32, so the IPU has to adjust it so you have at least 395 pixels in the source and the denominator is 32 or less. It must use 25.92405/32 as a starting point, which becomes 25/32. The new source width is 410.
240/253 => 240/253. The fraction is irreducible, and its denominator is larger than 32. It must use 30.35573/32 as a starting point, which becomes 30/32. The new source width is 256.

Your image, 395x253, is in the middle of a 410x256 image that gets resized to 320x240. You need to make sure that you handle the case where 395 * sizeof(uint16_t) is not necessarily the line pitch, which you get with SDL_Surface.pitch, though. In this case, the next line is not 395 * sizeof(uint16_t) away, but 410 * sizeof(uint16_t).

slaanesh (OP)

  • Posts: 569
    • Slaanesh Dev
Re: GCW-Zero IPU screen scaling implementation
« Reply #30 on: October 14, 2014, 12:50:47 am »
Thanks, got it! Now i've got rid of the wobbles and the IPU is scaling nicely again.

I didn't realize that I had to vary the pitch which may not be entirely clear. It's working now, weird resolutions are now all good.

Nice playable speeds too, thanks to the IPU hardware removing the burden of software scaling for these games.

Thanks Nebuleon for your help, I think that example would be good for the Wiki.
The current simple case example there is great if you have "IPU friendly" resolutions but if you have difficult ones, some extra info would good.

And thanks again for the work on the IPU hardware... it really is a super effort! It couldn't be easier to use and integrated really well into SDL (and the kernel I would think). Thumbs up all round. ;D
« Last Edit: October 14, 2014, 01:40:56 am by slaanesh »

slaanesh (OP)

  • Posts: 569
    • Slaanesh Dev
Re: GCW-Zero IPU screen scaling implementation
« Reply #31 on: October 20, 2014, 06:06:00 am »
Sorry guys, I've found a bug in the IPU Scaler. I've got the latest firmware.

Here's the test case:

Makefile
Code: [Select]
TOOLCHAIN = /opt/gcw0-toolchain/usr
CC = $(TOOLCHAIN)/bin/mipsel-linux-gcc
LD = $(TOOLCHAIN)/bin/mipsel-linux-gcc

LIBS = -lSDL -lpthread -lm -lgcc
LIB_PATH  = $(TOOLCHAIN)/lib

W_OPTS = -Wall -Wno-write-strings -Wno-sign-compare

F_OPTS =-falign-functions -falign-loops -falign-labels -falign-jumps \
    -ffast-math -fsingle-precision-constant -funsafe-math-optimizations \
    -fomit-frame-pointer -fno-builtin -fno-exceptions -fno-common \
    -fstrict-aliasing  -fexpensive-optimizations -fno-pic \
    -finline -finline-functions -fmerge-all-constants \
    -ftree-vectorize -fweb -frename-registers -ggdb

CFLAGS = -DGCW0 -pipe -O2 -march=mips32r2 -mtune=mips32r2 -mhard-float -mno-mips16 $(W_OPTS) $(F_OPTS)

LDFLAGS = $(CFLAGS) -L$(LIB_PATH) $(LIBS) -s

all: test_ipu

test_ipu: test_ipu.o
        $(LD) $(LDFLAGS) $< -o [email protected]

test_ipu.o: test_ipu.c
        $(CC) $(CFLAGS) -c $< -o [email protected]

clean: test_ipu
        @rm -f test_ipu test_ipu.o

Test program: test_ipu.c

Code: [Select]
#include <SDL/SDL.h>

int main(int argc, char **argv)
{
        int width = 410;
        int height = 256;
        SDL_Surface  *Surface;
        SDL_Init(SDL_INIT_VIDEO);
        printf("SDL_SetVideoMode(%d, %d, 16, SDL_TRIPLEBUF | SDL_HWSURFACE | SDL_FULLSCREEN );\n", width, height);

        Surface = SDL_SetVideoMode(width, height, 16, SDL_TRIPLEBUF | SDL_HWSURFACE | SDL_FULLSCREEN );

        printf("Success: Pitch=%d\n", Surface->pitch);

        SDL_Quit();

}

Those parameters cause the GCW-Zero to die...

I run the following to switch on IPU hardware:

Code: [Select]
opendingux:/media/data/local/share/test # cat full.sh
#!/bin/sh

echo "Setting allow_downscaling for IPU"

echo 1 > /sys/devices/platform/jz-lcd.0/allow_downscaling
echo 0 > /sys/devices/platform/jz-lcd.0/keep_aspect_ratio


opendingux:/media/data/local/share/test # ./test_ipu

Screen fades white and GCW0 reboots.

Other width values will work. ie 400 works but 410 seems to be bad. Maybe others are bad too.

pcercuei

  • Posts: 1676
    • My devblog
Re: GCW-Zero IPU screen scaling implementation
« Reply #32 on: October 20, 2014, 09:14:41 am »
The ratio is 41:31, and 41 > 32.
The algorithm doesn't handle the case where the numerator is a prime number, I think...

slaanesh (OP)

  • Posts: 569
    • Slaanesh Dev
Re: GCW-Zero IPU screen scaling implementation
« Reply #33 on: October 20, 2014, 12:28:17 pm »
How can we go about fixing this issue?
Obviously it shouldn't crash like it does.

Who needs to know about this bug?

pcercuei

  • Posts: 1676
    • My devblog
Re: GCW-Zero IPU screen scaling implementation
« Reply #34 on: October 20, 2014, 03:06:22 pm »
Who needs to know about this bug?
Just me ;)

slaanesh (OP)

  • Posts: 569
    • Slaanesh Dev
Re: GCW-Zero IPU screen scaling implementation
« Reply #35 on: October 20, 2014, 09:39:42 pm »
Can't play Smash TV on Mame 0.84 with IPU hardware scaling without it fixed! :)

If you create a fix, can you let me know so I can test it?

hi-ban

  • Posts: 886
Re: GCW-Zero IPU screen scaling implementation
« Reply #36 on: October 20, 2014, 10:08:42 pm »
until (if) that is fixed, you might have to use the next working resolution (420, i think). It will not be completely fullscreen , it will have some very tiny black bars (2 or 3 pixels) but it should work.
« Last Edit: October 20, 2014, 10:31:41 pm by hi-ban »

Gab1975

  • Posts: 1165
Re: GCW-Zero IPU screen scaling implementation
« Reply #37 on: October 20, 2014, 10:16:07 pm »
If I'm not wrong, "Smash TV" should be the only Midway/Williams "TMS34010" coin-op with horizontal resolution of 410 pixels, the other games (like Judge Dredd, Mortal Kombat, NBA Jam, Total Carnage, Trog, etc.) should have a horizontal resolution of about 396-400 pixels.
I'm looking forward to see how the GCW Zero is able to emulate these games! ;) 

slaanesh (OP)

  • Posts: 569
    • Slaanesh Dev
Re: GCW-Zero IPU screen scaling implementation
« Reply #38 on: October 20, 2014, 11:28:48 pm »
If I'm not wrong, "Smash TV" should be the only Midway/Williams "TMS34010" coin-op with horizontal resolution of 410 pixels, the other games (like Judge Dredd, Mortal Kombat, NBA Jam, Total Carnage, Trog, etc.) should have a horizontal resolution of about 396-400 pixels.
I'm looking forward to see how the GCW Zero is able to emulate these games! ;)

Correct!

Smash TV is one of my standard testing games - because of it's unusual resolution, fairly demanding on the host system and of course is fun to play :)

Smash TV on Mame 0.37b16 used to have a resolution of 396 pixels and works with the IPU scaler no problems. It runs at full speed w/ zero frameskip and most importantly looks and plays great!

Gab1975

  • Posts: 1165
Re: GCW-Zero IPU screen scaling implementation
« Reply #39 on: October 21, 2014, 06:29:08 am »
Smash TV on Mame 0.37b16 used to have a resolution of 396 pixels and works with the IPU scaler no problems. It runs at full speed w/ zero frameskip and most importantly looks and plays great!

Your forthcoming release promises to be really interesting! ;)

I'm curious (I hope you can give us a "little spoiler" ! :P )... are you making three different MAME4all(s) or a single release which supports three different ROMsets (37b16, 0.66 and 0.84) ?
« Last Edit: October 21, 2014, 06:31:21 am by Gab1975 »

 

Post a new topic