SDL_FillRect problems?

Since I installed SDL1.1.8, calling SDL_FillRect to fill an area with some
color in a 32bpp mode seems to be segfaulting. It could be that I am
calling it wrongly but it worked in 1.1.7.

something like:

c = SDL_MapRGBA(screen->format, 100, 150, 0, 64);
r.x = 100; r.y = 100;
r.w = 100; r.h = 100;
SDL_FillRect(screen, &r, c);

would die, but not all the time, if I play around with the colors/alpha
value in MapRGBA it works sometimes. It only goes wrong in 32bpp modes
though - and is also still broken in CVS.
anyone else found this problem, or am i just doing something wrong? ;)–
Adam
@af7567_at_bris.ac.uk
adamf at one2one.net
adamf at snika.uklinux.net

Since I installed SDL1.1.8, calling SDL_FillRect to fill an area with some
color in a 32bpp mode seems to be segfaulting. It could be that I am
calling it wrongly but it worked in 1.1.7.

it could be a victim of my FillRect rewrite. please write a small complete
example and tell us what platform (arch, os, compiler etc) you are using

Ok, a small test program (which dies) is attached. seems to be crashing at
line 608 of SDL_surface.c when SDL_memset4 is called. and, SDL_memset4 is
#defined in SDL_memops.h as a load of scary assembly code which i know
nothing about :wink: [ this is from using the current CVS checkout at the
time of sending this email ]

This is using linux 2.2.18 on an i586 (pentium-166, old thingy) compiled
with gcc 2.95.2 / binutils-2.9.5
running under XFree86-4.0.2 with a Matrox mystique video card (mga1064sg
chipset)
Thats about everything I can thing of that might be useful :slight_smile: (no
particular linux distro)

I’m still not sure if i am actually doing this the “proper” way though,
but I have been playing for a while to try and get it working

gdb output:–
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1024 (LWP 7653)]
0x40040883 in SDL_FillRect (dst=0x804c4f0, dstrect=0xbffff5bc, color=6592000)
at SDL_surface.c:608
608 SDL_memset4(row, color, dstrect->w);

incase thats useful somehow…

On Tue, 20 Feb 2001, Mattias Engdegard wrote:

Since I installed SDL1.1.8, calling SDL_FillRect to fill an area with
some
color in a 32bpp mode seems to be segfaulting. It could be that I am
calling it wrongly but it worked in 1.1.7.

it could be a victim of my FillRect rewrite. please write a small
complete
example and tell us what platform (arch, os, compiler etc) you are using


Adam
@af7567_at_bris.ac.uk
adamf at one2one.net
adamf at snika.uklinux.net
-------------- next part --------------
#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>

int main(int argc, char **argv)
{
Uint32 color;
SDL_Surface *screen;
SDL_Rect r;

SDL_Init(SDL_INIT_VIDEO);
screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);

color = SDL_MapRGBA(screen->format, 100, 150, 0, 64);
r.x = 100; r.y = 100;
r.w = 100; r.h = 100;

fprintf(stdout, “color: %d\n”, color);
SDL_FillRect(screen, &r, color);
fprintf(stdout, “fillrect\n”);
SDL_UpdateRects(screen, 1, &r);
fprintf(stdout, “updatrects\n”);

SDL_Quit();

return(0);
}

Ok, a small test program (which dies) is attached. seems to be crashing at
line 608 of SDL_surface.c when SDL_memset4 is called.

This works fine for me with the current CVS using linux 2.4.1 on a
PII-300 compiled with gcc 2.95.2 running under XFree86 4.0.2 with
a Matrox G450.

I fixed a bug that looked very similar to this over the weekend.
Look in src/hermes/mmx_main.asm and make sure it has the following:

; Save the registers used by the blitters, necessary for optimized code
pusha

Then do “make clean; make install” to make sure you’re getting the
new fix. This was broken in SDL 1.1.8, so make sure you don’t have
that library around to confuse things.

See ya!
-Sam Lantinga, Lead Programmer, Loki Entertainment Software

This might be the error — my gcc didn’t zero-extend the len parameter
for the SDL_memset4 inline asm (generated a movw instead of a movzwl).
Try the following patch and see if it helps

Index: SDL_memops.h===================================================================
RCS file: /cvs/SDL/src/video/Attic/SDL_memops.h,v
retrieving revision 1.1.2.15
diff -u -r1.1.2.15 SDL_memops.h
— SDL_memops.h 2001/02/18 09:07:58 1.1.2.15
+++ SDL_memops.h 2001/02/21 11:05:03
@@ -89,12 +89,12 @@

#define SDL_memset4(dst, val, len)
do { \

  • int u0, u1, u2; \
  • int u0, u1, u2;
    asm volatile (
    “cld\n\t”
    “rep ; stosl\n\t”
    : “=&D” (u0), “=&a” (u1), “=&c” (u2) \
  •   : "0" (dst), "1" (val), "2" (len)		\
    
  •   : "0" (dst), "1" (val), "2" ((Uint32)len)	\
      : "memory" );					\
    

} while(0)

I fixed a bug that looked very similar to this over the weekend.
Look in src/hermes/mmx_main.asm and make sure it has the following:

; Save the registers used by the blitters, necessary for optimized code
pusha

what does the x86 ABIs (for win32, linux, bsd etc) say about what registers
are caller-saves and callee-saves? pusha/popa seems like an overkill unless
all of them are callee-saves, which sounds unlikely

(it’s nice to be back btw — a big hello to Sam and everyone else on the
list. I’m still not completely restored so I’m only working a couple of
hours a day, so we’ll see how it works out)

Hi,

I see the same problem when using my pixel-draw routine (see attached
source code). memset4 segfaults. I am using the stock Mandrake 7.2 and the
1.1.8 lib.

The patch didn’t work with 1.1.8 - can you send me one or a working
routine for manual patching.

Ciao
Andreas—

/* ----- Pixel - using single pixel blit with blending enabled. */

static SDL_Surface *gfxPrimitivesSinglePixel=NULL;

int pixelColor (SDL_Surface *dst, Sint16 x, Sint16 y, Uint32 color)
{
SDL_Rect srect;
SDL_Rect drect;
int result;

/* Setup source rectangle for pixel */
srect.x=0;
srect.y=0;
srect.w=1;
srect.h=1;

/* Setup destination rectangle for pixel */
drect.x=x;
drect.y=y;
drect.w=1;
drect.h=1;

/* Create single pixel from destination surface format and add alpha
channel t
if (gfxPrimitivesSinglePixel==NULL) {
gfxPrimitivesSinglePixel=SDL_CreateRGBSurface(SDL_SWSURFACE |
SDL_HWSURFACE |
SDL_SetAlpha (gfxPrimitivesSinglePixel, SDL_SRCALPHA, 255);
}

/* Draw color into pixel*/
SDL_FillRect (gfxPrimitivesSinglePixel, &srect, color);

/* Draw pixel onto destination surface */
result=SDL_BlitSurface (gfxPrimitivesSinglePixel, &srect, dst, &drect);

return(result);
}

Mattias Engdeg?rd wrote:

This might be the error — my gcc didn’t zero-extend the len parameter
for the SDL_memset4 inline asm (generated a movw instead of a movzwl).
Try the following patch and see if it helps

Index: SDL_memops.h

RCS file: /cvs/SDL/src/video/Attic/SDL_memops.h,v
retrieving revision 1.1.2.15
diff -u -r1.1.2.15 SDL_memops.h
— SDL_memops.h 2001/02/18 09:07:58 1.1.2.15
+++ SDL_memops.h 2001/02/21 11:05:03
@@ -89,12 +89,12 @@

#define SDL_memset4(dst, val, len)
do { \

  •   int u0, u1, u2;                                 \
    
  •   int u0, u1, u2;                                         \
      __asm__ __volatile__ (                                  \
              "cld\n\t"                                       \
              "rep ; stosl\n\t"                               \
              : "=&D" (u0), "=&a" (u1), "=&c" (u2)            \
    
  •           : "0" (dst), "1" (val), "2" (len)               \
    
  •           : "0" (dst), "1" (val), "2" ((Uint32)len)       \
              : "memory" );                                   \
    

} while(0)


| Andreas Schiffler aschiffler at home.com |
| Senior Systems Engineer - Deskplayer Inc., Buffalo |
| 4707 Eastwood Cres., Niagara Falls, Ont L2E 1B4, Canada |
| +1-905-371-3652 (private) - +1-905-371-8834 (work/fax) |

what does the x86 ABIs (for win32, linux, bsd etc) say about what registers
are caller-saves and callee-saves? pusha/popa seems like an overkill unless
all of them are callee-saves, which sounds unlikely

Well, the crash bug was caused by edx and edi being used by the optimized
code to store variables, which were clobbered inside the blitters. I’m
not an ASM guru or anything, but it looks like all general purpose registers
are callee saves, to allow that sort of optimization. I would have tracked
down exactly which registers were used by the blitters, but it looked like
all of the general purpose ones were being used when the source and/or
destination pointers weren’t aligned, so just to be safe I saved them all.

(it’s nice to be back btw — a big hello to Sam and everyone else on the
list. I’m still not completely restored so I’m only working a couple of
hours a day, so we’ll see how it works out)

I hope you feel better! :slight_smile:

See ya,
-Sam Lantinga, Lead Programmer, Loki Entertainment Software

The patch didn’t work with 1.1.8 - can you send me one or a working
routine for manual patching.

apply to the CVS SDL

Welcome back! Nice to see you here. :slight_smile:

//David

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------> http://www.linuxaudiodev.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |--------------------------------------> david at linuxdj.com -'On Wednesday 21 February 2001 12:25, Mattias Engdeg?rd wrote:

(it’s nice to be back btw — a big hello to Sam and everyone else on the
list. I’m still not completely restored so I’m only working a couple of
hours a day, so we’ll see how it works out)

what does the x86 ABIs (for win32, linux, bsd etc) say about what
registers
are caller-saves and callee-saves? pusha/popa seems like an overkill
unless
all of them are callee-saves, which sounds unlikely

EAX, ECX, and EDX may be modified by the callee withour
saving/restoring. EAX is used for integer return values, ST(0) for
floating point return values.

m.

----- Original Message -----
From: f91-men@nada.kth.se (Mattias Engdegard)
Subject: Re: [SDL] SDL_FillRect problems?

EAX, ECX, and EDX may be modified by the callee withour
saving/restoring. EAX is used for integer return values, ST(0) for
floating point return values.

With -O2 gcc was saving a variable in edx and checking it after the
blit function call. The blit of course modified edx and so the program
crashed, succeeding a following test because of the incorrect edx value.

It’s been a couple days since I fixed this, and the exact registers
used by gcc changed when I rearranged the code slightly, but I believe
that’s what was going on.

?
-Sam Lantinga, Lead Programmer, Loki Entertainment Software

EAX, ECX, and EDX may be modified by the callee withour
saving/restoring. EAX is used for integer return values, ST(0) for
floating point return values.

yes this seems to be the linux/svr4 i386 conventions: ebp, ebx, edi, esi
are callee-saves, and the rest are caller-saves

With -O2 gcc was saving a variable in edx and checking it after the
blit function call. The blit of course modified edx and so the program
crashed, succeeding a following test because of the incorrect edx value.

you sure? that sounds like a gcc bug. from the gcc 2.95.2 sources
(config/i386/i386.h):

/* 1 for registers not available across function calls.
These must include the FIXED_REGISTERS and also any
registers that can be used without being saved.
The latter must include the registers where values are returned
and the register where structure-value addresses are passed.
Aside from that, you can include as many other registers as you like. */

#define CALL_USED_REGISTERS
/ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg/
{ 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }

since we want to be able to write multi-platform asm I’ve tried to
find the win32 conventions but without success. I hope there’s a way
to run asm code through the C preprocessor for non-unixy platforms because
that would help us seriously in the future

Mattias Engdeg?rd wrote:

since we want to be able to write multi-platform asm I’ve tried to
find the win32 conventions but without success. I hope there’s a way
to run asm code through the C preprocessor for non-unixy platforms because
that would help us seriously in the future

This was being discussed yesterday in my assembly class. We were talking about
DOS, but I think it would carry over to win32. Volatile set is eax, ebx, ecx,
edx, everything else is callee-save.

~jfefrey :j