[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Another blitting surface to itself crash



No mmx/sse instructions are used when source and destination are identical. Just a string move, "rep movsl". I isolated the reverse copy code in a simple C program. It is attached. There is definitely something wrong, though I don't know yet. It appears to run just fine unless I redirect output, then it hangs. Comment out SDL_revcpy and it runs to completion. So something is being stomped.

Lenard


René Dudfield wrote:
maybe it is memory alignment?  Maybe the mmx/sse routines require 8
byte alignment or something?


On Mon, Aug 18, 2008 at 4:55 PM, Lenard Lindstrom <len-l@xxxxxxxxx> wrote:
Thanks Nicholas,

That is kind of interesting, and kind of confusing. Hugo Arts got a Pygame
parachute on XP that was traced to SDL itself. I get a Fatal Python error,
as do you. But unless you use a vintage Windows system as I do then it would
seem the type of error is independent of Windows version. It behaves as a
memory violation, but where. And it is MinGW specific.

I ran gdb on a small C program that does a self blit. I saw no place where
pointers go astray. The obvious way in which MinGW and VC code differs is
some inline assembly happens with MinGW. But a test on the inlined assembly
code involved with an overlapping blit showed no problems. I must be making
a faulty assumption somewhere.

Lenard


Nicholas Dudfield wrote:
Lenard,

"Fatal Python error: Inconsistent interned string state."


On Mon, Aug 18, 2008 at 8:17 AM, Lenard Lindstrom <len-l@xxxxxxxxx
<mailto:len-l@xxxxxxxxx>> wrote:

   Yes, debug print statements show the crash happens when the SDL
   blit funcion SDL_BlitSurface is called. Did you get a Pygame
   parachute or a Python interned string violation?

   Lenard


   Nicholas Dudfield wrote:

       Ok, I have been informed there is are PyGame blits not derived
       from SDL, so that explains that.

       {pygame_AlphaBlit, pygame_Blit} from clip above looks like

       Seems oblivious (sic) now it's pointed out.


       On Sat, Aug 16, 2008 at 4:37 PM, Nicholas Dudfield
       <ndudfield@xxxxxxxxx <mailto:ndudfield@xxxxxxxxx>
       <mailto:ndudfield@xxxxxxxxx <mailto:ndudfield@xxxxxxxxx>>> wrote:

          I had a little play with the test_blit_to_self.py:
          SDL VERSION:

          1.2.13 prebuilts

          PYGAME:

          Mingw compiled, svn r 1619

          OBSERVATIONS:

          Unmodified the test wouldn't run at all as noted earlier.

          I don't know if it's any help but I noticed after
       commenting out
          the "blitting screen to self" section that I could get the
          "blitting surface to self" test and "blitting surface to
       screen"
          to run the full 100 cycles if I instantiated the Surface
       `a` with
          pygame.SRCALPHA flags.

          Also, if using BLEND_RGB_ADD flags "blitting screen to self"
          worked. Also screen.copy() worked as a source... but eh.

          CONCLUSIONS:

          s.blit(s, (0,0)) works if SRCALPHA bits set for s
          screen.blit(screen, step, None, pygame.BLEND_RGB_ADD)

          Is that any help for you guys in debugging?? I have no C-fu
       or I
          would have a tinker myself.


#include <stdio.h>
#include <stdlib.h>

#define SDL_revcpy(dst, src, len)			\
do {							\
	int u0, u1, u2;					\
	char *dstp = (char *)(dst);			\
	char *srcp = (char *)(src);			\
	int n = (len);					\
	if ( n >= 4 ) {					\
	__asm__ __volatile__ (				\
		"std\n\t"				\
		"rep ; movsl\n\t"			\
		: "=&c" (u0), "=&D" (u1), "=&S" (u2)	\
		: "0" (n >> 2),				\
		  "1" (dstp+(n-4)), "2" (srcp+(n-4))	\
		: "memory" );				\
	}						\
	switch (n & 3) {				\
		case 3: dstp[2] = srcp[2];		\
		case 2: dstp[1] = srcp[1];		\
		case 1: dstp[0] = srcp[0];		\
			break;				\
		default:				\
			break;				\
	}						\
} while(0)

int main(int argc, char *argv[])
{
  const int bufsize = 40;
  const int padding = 8;
  const int blocksize = 20;
  char buffer[bufsize+1], *b;
  int alignment, dstoffset, i;
  
  buffer[bufsize] = 0; /* null terminated string */

  for (alignment = 0; alignment < 4; ++alignment)
  {
    b = buffer + padding + alignment;
    for (dstoffset = 0; dstoffset < 5; ++dstoffset)
    { 
      for (i = 0; i < bufsize; ++i)
      {
        buffer[i] = '.';
      }
      for (i = 0; i < blocksize; ++i)
      {
        b[i] = 'a' + i;
      }
      printf("%s\n", buffer);
  
      SDL_revcpy(b+dstoffset, b, blocksize);
  
      printf("%s\n\n", buffer);
    }
  }
  
/*  system("PAUSE");	*/
  return 0;
}