Framebuffer allocated for 32bit color formats

This commit is contained in:
Jens Hemprich 2007-08-22 19:03:50 +00:00
parent 629aeebb9d
commit b8e224a059
2 changed files with 51 additions and 57 deletions

View File

@ -55,7 +55,7 @@ grLfbLock( GrLock_t dwType,
} }
else if (OpenGL.WinOpen == false && Glide.ReadBuffer.Address) else if (OpenGL.WinOpen == false && Glide.ReadBuffer.Address)
{ {
BufferStruct* targetbuffer = Glide.ReadBuffer.Address ? &Glide.ReadBuffer : &Glide.TempBuffer; BufferStruct* targetbuffer = &Glide.ReadBuffer;
lfbInfo->lfbPtr = targetbuffer->Address; lfbInfo->lfbPtr = targetbuffer->Address;
lfbInfo->origin = GR_ORIGIN_UPPER_LEFT; lfbInfo->origin = GR_ORIGIN_UPPER_LEFT;
} }
@ -68,17 +68,20 @@ grLfbLock( GrLock_t dwType,
// Alloc readbuffer // Alloc readbuffer
if (Glide.ReadBuffer.Address == NULL) if (Glide.ReadBuffer.Address == NULL)
{ {
Glide.ReadBuffer.Address = (FxU16*) AllocFrameBuffer(Glide.WindowTotalPixels, sizeof(FxU16)); // @todo: 32bit read buffers are cureently not supported (any mac game using this format for reads?)
Glide.ReadBuffer.Address = (FxU16*) AllocFrameBuffer(Glide.WindowTotalPixels,
//dwWriteMode >= GR_LFBWRITEMODE_888 ? sizeof(FxU32) : sizeof(FxU16)
sizeof(FxU16)
);
#ifdef OPENGL_DEBUG #ifdef OPENGL_DEBUG
GlideMsg("Allocated Readbuffer(%dx%d) at 0x%x\n", GlideMsg("Allocated Readbuffer(%dx%d) at 0x%x\n",
Glide.WindowWidth, Glide.WindowHeight, Glide.ReadBuffer.Address); Glide.WindowWidth, Glide.WindowHeight, Glide.ReadBuffer.Address);
#endif #endif
} }
// select main memory buffers // select main memory buffers
// @todo Remove conditions for NULL ReadBuffer (usage of FrameBuffer as source is wrong because it might be 16bit only)
BufferStruct* targetbuffer = &Glide.ReadBuffer; BufferStruct* targetbuffer = &Glide.ReadBuffer;
const BufferStruct* sourcebuffer = &Glide.TempBuffer; const BufferStruct* sourcebuffer = &Glide.TempBuffer;
if (s_Framebuffer.GetRenderBufferChangedForRead() == true) if (s_Framebuffer.GetRenderBufferChangedForRead())
{ {
// select buffer size // select buffer size
const unsigned long bufferwidth = OpenGL.WindowWidth; const unsigned long bufferwidth = OpenGL.WindowWidth;
@ -89,26 +92,25 @@ grLfbLock( GrLock_t dwType,
GLint glWriteMode; GLint glWriteMode;
switch (dwWriteMode) switch (dwWriteMode)
{ {
case GR_LFBWRITEMODE_1555: glWriteMode = GL_UNSIGNED_SHORT_1_5_5_5_REV; break; case GR_LFBWRITEMODE_1555: glWriteMode = GL_UNSIGNED_SHORT_1_5_5_5_REV; break;
case GR_LFBWRITEMODE_565: glWriteMode = GL_UNSIGNED_SHORT_5_6_5; break; case GR_LFBWRITEMODE_565: glWriteMode = GL_UNSIGNED_SHORT_5_6_5; break;
default: glWriteMode = GL_UNSIGNED_SHORT_5_6_5; break; //case GR_LFBWRITEMODE_888: glWriteMode = GL_UNSIGNED_BYTE_8_8_8_8; break;
default: glWriteMode = GL_UNSIGNED_SHORT_5_6_5; break;
} }
// The read buffer is sized for Glide pixels. As a result we cannot be used it when the read buffer has to be resized // The read buffer is sized for Glide pixels. As a result we cannot be used it when the read buffer has to be resized
void* destination = (!scale && dwOrigin == GR_ORIGIN_LOWER_LEFT) ? targetbuffer->Address : sourcebuffer->Address; void* destination = (!scale && dwOrigin == GR_ORIGIN_LOWER_LEFT) ? targetbuffer->Address : sourcebuffer->Address;
#ifdef OPENGL_DEBUG #ifdef OPENGL_DEBUG
GlideMsg("Calling glReadPixels(%d, %d, 0x%x)\n", bufferwidth, bufferheight, destination); GlideMsg("Calling glReadPixels(%d, %d, 0x%x)\n", bufferwidth, bufferheight, destination);
#endif #endif
glReadPixels(0, 0, glReadPixels(0, 0, bufferwidth, bufferheight,
bufferwidth, bufferheight, (dwWriteMode == GR_LFBWRITEMODE_565) ? GL_RGB : GL_RGBA,
(dwWriteMode == GR_LFBWRITEMODE_1555) ? GL_RGBA : GL_RGB, glWriteMode, destination);
glWriteMode,
destination);
glReportError(); glReportError();
#ifdef OPENGL_DEBUG #ifdef OPENGL_DEBUG
if (scale) if (scale)
GlideMsg("Scaling to (%d, %d) from 0x%x to 0x%x\n", GlideMsg("Scaling to (%d, %d) from 0x%x to 0x%x\n",
Glide.WindowWidth, Glide.WindowHeight, sourcebuffer->Address, targetbuffer->Address); Glide.WindowWidth, Glide.WindowHeight, sourcebuffer->Address, targetbuffer->Address);
#endif #endif
if (dwOrigin == GR_ORIGIN_UPPER_LEFT) if (dwOrigin == GR_ORIGIN_UPPER_LEFT)
{ {
// When the OpenGL resolution differs from the Glide resolution, // When the OpenGL resolution differs from the Glide resolution,
@ -139,9 +141,9 @@ grLfbLock( GrLock_t dwType,
else else
{ {
#ifdef OPENGL_DEBUG #ifdef OPENGL_DEBUG
GlideMsg("Copying/Vertical mirroring pixels to destination buffer from 0x%x to 0x%x\n", GlideMsg("Copying/Vertical mirroring pixels to destination buffer from 0x%x to 0x%x\n",
sourcebuffer->Address, targetbuffer->Address); sourcebuffer->Address, targetbuffer->Address);
#endif #endif
// Swap pixels during copy from temp to read buffer // Swap pixels during copy from temp to read buffer
for ( int j = 0; j < Glide.WindowHeight; j++ ) for ( int j = 0; j < Glide.WindowHeight; j++ )
{ {
@ -180,8 +182,8 @@ grLfbLock( GrLock_t dwType,
else else
{ {
#ifdef OPENGL_DEBUG #ifdef OPENGL_DEBUG
GlideMsg("Copying/Vertical mirroring not necessary - pixels already in the right orientation\n"); GlideMsg("Copying/Vertical mirroring not necessary - pixels already in the right orientation\n");
#endif #endif
} }
} }
// Update with current framebuffer pixels not yet written to vram // Update with current framebuffer pixels not yet written to vram
@ -220,14 +222,13 @@ grLfbUnlock( GrLock_t dwType, GrBuffer_t dwBuffer )
} }
else else
{ {
BufferStruct* targetbuffer = Glide.ReadBuffer.Address ? &Glide.ReadBuffer : &Glide.TempBuffer; if (Glide.ReadBuffer.Lock)
if (targetbuffer->Lock)
{ {
// We're not interested in keeping track of unlocks since this breaks // We're not interested in keeping track of unlocks since this breaks
// Framebuffer updates when moving the cursor in Carmageddon movie mode // Framebuffer updates when moving the cursor in Carmageddon movie mode
// (because grLfbReadRegion() is called) // (because grLfbReadRegion() is called)
// @todo: -> Doesn't solve the issue // @todo: -> Doesn't solve the issue
targetbuffer->Lock = false; Glide.ReadBuffer.Lock = false;
return FXTRUE; return FXTRUE;
} }
else else

View File

@ -191,11 +191,10 @@ grSstWinOpen(FxU32 hwnd,
int num_buffers, int num_buffers,
int num_aux_buffers) int num_aux_buffers)
{ {
if ( OpenGL.WinOpen ) if (OpenGL.WinOpen)
{ {
grSstWinClose( ); grSstWinClose();
} }
// Some games read from the buffer after the window has been closed // Some games read from the buffer after the window has been closed
// As a result, freeing the read buffer must be deferred until the // As a result, freeing the read buffer must be deferred until the
// next call to grSstWinOpen() or unloading the library // next call to grSstWinOpen() or unloading the library
@ -204,15 +203,12 @@ grSstWinOpen(FxU32 hwnd,
FreeFrameBuffer(Glide.ReadBuffer.Address); FreeFrameBuffer(Glide.ReadBuffer.Address);
Glide.ReadBuffer.Address = NULL; Glide.ReadBuffer.Address = NULL;
} }
#ifdef OGL_DONE
#ifdef OGL_DONE
GlideMsg( "grSstWinOpen( %d, %d, %d, %d, %d, %d, %d )\n", GlideMsg( "grSstWinOpen( %d, %d, %d, %d, %d, %d, %d )\n",
hwnd, res, ref, cformat, org_loc, num_buffers, num_aux_buffers ); hwnd, res, ref, cformat, org_loc, num_buffers, num_aux_buffers );
#endif #endif
Glide.Resolution = res;
Glide.Resolution = res; #ifdef OGL_DEBUG
#ifdef OGL_DEBUG
if ( Glide.Resolution > GR_RESOLUTION_400x300 ) if ( Glide.Resolution > GR_RESOLUTION_400x300 )
{ {
GlideError( "grSstWinOpen: res = GR_RESOLUTION_NONE\n" ); GlideError( "grSstWinOpen: res = GR_RESOLUTION_NONE\n" );
@ -223,8 +219,7 @@ grSstWinOpen(FxU32 hwnd,
GlideError( "grSstWinOpen: Refresh Incorrect\n" ); GlideError( "grSstWinOpen: Refresh Incorrect\n" );
return FXFALSE; return FXFALSE;
} }
#endif #endif
Glide.WindowWidth = windowDimensions[Glide.Resolution].width; Glide.WindowWidth = windowDimensions[Glide.Resolution].width;
Glide.WindowHeight = windowDimensions[Glide.Resolution].height; Glide.WindowHeight = windowDimensions[Glide.Resolution].height;
// Set the size of the opengl window (might be different from Glide window size) // Set the size of the opengl window (might be different from Glide window size)
@ -270,24 +265,24 @@ grSstWinOpen(FxU32 hwnd,
memset(&Glide.TempBuffer, 0, sizeof(BufferStruct)); memset(&Glide.TempBuffer, 0, sizeof(BufferStruct));
memset(&Glide.ReadBuffer, 0, sizeof(BufferStruct)); memset(&Glide.ReadBuffer, 0, sizeof(BufferStruct));
// Initing OpenGL Window // Initing OpenGL Window
if ( !InitWindow(hwnd)) if (!InitWindow(hwnd))
{ {
return FXFALSE; return FXFALSE;
} }
// Note: The OpenGL resolution might have changed during the call to InitWindow(). // Note: The OpenGL resolution might have changed during the call to InitWindow().
// As a result, buffers must be allocated afterwards // As a result, buffers must be allocated afterwards
const unsigned long openglpixels = OpenGL.WindowWidth * OpenGL.WindowHeight; const unsigned long openglpixels = OpenGL.WindowWidth * OpenGL.WindowHeight;
// At first, allocate a framebuffer for 16bit pixel data only (will be expanded on demand) // As the lfb write format isn't known yet we must allocate a framebuffer for 32bit color formats
unsigned long buffertypesize = sizeof(FxU16); // (dwWriteMode >= GR_LFBWRITEMODE_888) ? sizeof(FxU32) : sizeof(FxU16); // although most games will use 16bit corlor formats only
Glide.FrameBuffer.Address = (FxU16*) AllocFrameBuffer(Glide.WindowTotalPixels * buffertypesize + openglpixels * sizeof(FxU32), 1); Glide.FrameBuffer.Address = (FxU16*) AllocFrameBuffer(Glide.WindowTotalPixels + openglpixels, 4);
Glide.TempBuffer.Address = &Glide.FrameBuffer.Address[Glide.WindowTotalPixels * buffertypesize >> 1]; // >> 1 as the framebuffer is allocated for 32 bit color formats but the pointer is declared as a short
memset( Glide.FrameBuffer.Address, 0, Glide.WindowTotalPixels * buffertypesize); Glide.TempBuffer.Address = &Glide.FrameBuffer.Address[Glide.WindowTotalPixels >> 1];
memset( Glide.TempBuffer.Address, 0, openglpixels * sizeof(FxU32)); memset(Glide.FrameBuffer.Address, 0, Glide.WindowTotalPixels * sizeof(FxU32));
memset(Glide.TempBuffer.Address, 0, openglpixels * sizeof(FxU32));
// Prealloc readbuffer for Carmageddon, because allocating it on demand // Prealloc readbuffer for Carmageddon, because allocating it on demand
// (when moving the cursor in Movie mode) would produce an OutOfMemory error) // (when moving the cursor in Movie mode) would produce an OutOfMemory error)
if (Glide.ReadBuffer.Address == NULL && const bool preallocateReadBuffer = s_GlideApplication.GetType() == GlideApplication::Carmageddon;
s_GlideApplication.GetType() == GlideApplication::Carmageddon) if (preallocateReadBuffer)
{ {
Glide.ReadBuffer.Address = (FxU16*) AllocFrameBuffer(Glide.WindowTotalPixels, sizeof(FxU16)); Glide.ReadBuffer.Address = (FxU16*) AllocFrameBuffer(Glide.WindowTotalPixels, sizeof(FxU16));
#ifdef OPENGL_DEBUG #ifdef OPENGL_DEBUG
@ -299,16 +294,14 @@ grSstWinOpen(FxU32 hwnd,
RenderInitialize(); RenderInitialize();
s_Framebuffer.initialise(&Glide.FrameBuffer, &Glide.TempBuffer); s_Framebuffer.initialise(&Glide.FrameBuffer, &Glide.TempBuffer);
Textures->initOpenGL(); Textures->initOpenGL();
#ifdef OGL_DONE #ifdef OGL_DONE
GlideMsg( "----Start of grSstWinOpen()\n" ); GlideMsg( "----Start of grSstWinOpen()\n" );
#endif #endif
// All should be disabled // All of this should be disabled: depth buffering, fog, chroma-key, alpha blending, alpha testing
//depth buffering, fog, chroma-key, alpha blending, alpha testing
#ifdef OPTIMISE_GLIDE_STATE_CHANGES #ifdef OPTIMISE_GLIDE_STATE_CHANGES
// When state change optimising is enabled, passing in default values of 0 // When state change optimising is enabled, passing in default values of 0
// will not initialise the corresponding values in the OpenGL struct, // would not initialise the corresponding values in the OpenGL struct,
// because the optimising code assumes, it has already been set earlier. // because the optimising code would assume that the state has already been set.
// By writing values other than 0 to glide state variables which will // By writing values other than 0 to glide state variables which will
// become 0 below, the OpenGL values are initialises as exspected. // become 0 below, the OpenGL values are initialises as exspected.
// For functions that are called by other functions during the // For functions that are called by other functions during the