Browse Source

ref_soft: REF_SOFTWARE, resize support

pull/2/head
mittorn 6 years ago
parent
commit
3617e8e7a1
  1. 2
      r_context.c
  2. 4
      r_draw.c
  3. 172
      r_glblit.c
  4. 5
      r_local.h
  5. 14
      r_main.c
  6. 13
      r_surf.c

2
r_context.c

@ -326,7 +326,7 @@ void GL_SetTexCoordArrayMode()
void GL_OnContextCreated() void GL_OnContextCreated()
{ {
R_InitBlit(); //R_InitBlit();
} }

4
r_draw.c

@ -118,11 +118,13 @@ void R_DrawStretchPicImplementation (int x, int y, int w, int h, int s1, int t1,
#pragma omp parallel for schedule(static) #pragma omp parallel for schedule(static)
for (v=0 ; v<height ; v++) for (v=0 ; v<height ; v++)
{ {
int alpha1 = vid.alpha;
#ifdef _OPENMP #ifdef _OPENMP
pixel_t *dest = vid.buffer + (y + v) * vid.rowbytes + x; pixel_t *dest = vid.buffer + (y + v) * vid.rowbytes + x;
#endif #endif
sv = (skip + v)*(t2-t1)/h + t1; sv = (skip + v)*(t2-t1)/h + t1;
source = buffer + sv*pic->width + s1; source = buffer + sv*pic->width + s1;
{ {
f = 0; f = 0;
fstep = s2*0x10000/w; fstep = s2*0x10000/w;
@ -144,7 +146,7 @@ void R_DrawStretchPicImplementation (int x, int y, int w, int h, int s1, int t1,
for (u=0 ; u<w ; u++) for (u=0 ; u<w ; u++)
{ {
pixel_t src = source[f>>16]; pixel_t src = source[f>>16];
int alpha = vid.alpha; int alpha = alpha1;
f += fstep; f += fstep;
if( transparent ) if( transparent )

172
r_glblit.c

@ -1,6 +1,13 @@
#include "r_local.h" #include "r_local.h"
#include "../ref_gl/gl_export.h" #include "../ref_gl/gl_export.h"
struct swblit_s
{
uint stride;
uint bpp;
uint rmask, gmask, bmask;
} swblit;
/* /*
======================== ========================
@ -38,9 +45,35 @@ unsigned short *buffer;
#define LOAD(x) p##x = gEngfuncs.GL_GetProcAddress(#x) #define LOAD(x) p##x = gEngfuncs.GL_GetProcAddress(#x)
void R_BuildScreenMap() static int FIRST_BIT( uint mask )
{
uint i;
for( i = 0; !(BIT(i) & mask); i++ );
return i;
}
static int COUNT_BITS( uint mask )
{
uint i;
for( i = 0; mask; mask = mask >> 1 )
i += mask & 1;
return i;
}
void R_BuildScreenMap( void )
{ {
int i; int i;
uint rshift = FIRST_BIT(swblit.rmask), gshift = FIRST_BIT(swblit.gmask), bshift = FIRST_BIT(swblit.bmask);
uint rbits = COUNT_BITS(swblit.rmask), gbits = COUNT_BITS(swblit.gmask), bbits = COUNT_BITS(swblit.bmask);
uint rmult = BIT(rbits), gmult = BIT(gbits), bmult = BIT(bbits);
uint rdiv = MASK(5), gdiv = MASK(6), bdiv = MASK(5);
gEngfuncs.Con_Printf("Blit table: %d %d %d %d %d %d\n", rmult, gmult, bmult, rdiv, gdiv, bdiv );
#ifdef SEPARATE_BLIT #ifdef SEPARATE_BLIT
for( i = 0; i < 256; i++ ) for( i = 0; i < 256; i++ )
{ {
@ -69,16 +102,24 @@ void R_BuildScreenMap()
r = ((i >> (8 - 3) )<< 2 ) & MASK(5); r = ((i >> (8 - 3) )<< 2 ) & MASK(5);
g = ((i >> (8 - 3 - 3)) << 3) & MASK(6); g = ((i >> (8 - 3 - 3)) << 3) & MASK(6);
b = ((i >> (8 - 3 - 3 - 2)) << 3) & MASK(5); b = ((i >> (8 - 3 - 3 - 2)) << 3) & MASK(5);
major = r << (6 + 5) | (g << 5) | b; //major = r << (6 + 5) | (g << 5) | b;
major = (r * rmult / rdiv) << rshift | (g * gmult / gdiv) << gshift | (b * bmult / bdiv) << bshift;
for( j = 0; j < 256; j++ ) for( j = 0; j < 256; j++ )
{ {
uint minor;
// restore minor GBRGBRGB // restore minor GBRGBRGB
r = MOVE_BIT(j, 5, 1) | MOVE_BIT(j, 2, 0); r = MOVE_BIT(j, 5, 1) | MOVE_BIT(j, 2, 0);
g = MOVE_BIT(j, 7, 2) | MOVE_BIT(j, 4, 1) | MOVE_BIT(j, 1, 0); g = MOVE_BIT(j, 7, 2) | MOVE_BIT(j, 4, 1) | MOVE_BIT(j, 1, 0);
b = MOVE_BIT(j, 6, 2) | MOVE_BIT(j, 3, 1) | MOVE_BIT(j, 0, 0); b = MOVE_BIT(j, 6, 2) | MOVE_BIT(j, 3, 1) | MOVE_BIT(j, 0, 0);
vid.screen[(i<<8)|j] = r << (6 + 5) | (g << 5) | b | major; //vid.screen[(i<<8)|j] = r << (6 + 5) | (g << 5) | b | major;
minor = (r * rmult / rdiv) << rshift | (g * gmult / gdiv) << gshift | (b * bmult / bdiv) << bshift;
if( swblit.bpp == 2 )
vid.screen[(i<<8)|j] = major | minor;
else
vid.screen32[(i<<8)|j] = major | minor;
} }
@ -103,18 +144,18 @@ void R_BuildBlendMaps()
r = r1 + r2; r = r1 + r2;
g = g1 + g2; g = g1 + g2;
b = b1 + b2; b = b1 + b2;
if( r > MASK(2) ) if( r > MASK(3) )
r = MASK(2); r = MASK(3);
if( g > MASK(2) ) if( g > MASK(3) )
g = MASK(2); g = MASK(3);
if( b > MASK(1) ) if( b > MASK(2) )
b = MASK(1); b = MASK(2);
ASSERT(!vid.addmap[index2|index1]); ASSERT(!vid.addmap[index2|index1]);
vid.addmap[index2|index1] = r << (2 + 3) | g << 2 | b; vid.addmap[index2|index1] = r << (2 + 3) | g << 2 | b;
r = r1 * r2 / MASK(2); r = r1 * r2 / MASK(3);
g = g1 * g2 / MASK(2); g = g1 * g2 / MASK(3);
b = b1 * b2 / MASK(1); b = b1 * b2 / MASK(2);
vid.modmap[index2|index1] = r << (2 + 3) | g << 2 | b; vid.modmap[index2|index1] = r << (2 + 3) | g << 2 | b;
@ -130,10 +171,12 @@ void R_BuildBlendMaps()
} }
} }
void R_AllocScreen();
void R_InitBlit() void R_InitBlit()
{ {
LOAD(glBegin); /*LOAD(glBegin);
LOAD(glEnd); LOAD(glEnd);
LOAD(glTexCoord2f); LOAD(glTexCoord2f);
LOAD(glVertex2f); LOAD(glVertex2f);
@ -149,7 +192,7 @@ void R_InitBlit()
LOAD(glDebugMessageControlARB); LOAD(glDebugMessageControlARB);
LOAD(glGetError); LOAD(glGetError);
LOAD(glGenTextures); LOAD(glGenTextures);
LOAD(glTexParameteri); LOAD(glTexParameteri);*/
#ifdef GLDEBUG #ifdef GLDEBUG
if( gpGlobals->developer ) if( gpGlobals->developer )
{ {
@ -164,36 +207,100 @@ void R_InitBlit()
pglDebugMessageControlARB( GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, true ); pglDebugMessageControlARB( GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, true );
#endif #endif
buffer = Mem_Malloc( r_temppool, 1920*1080*2 ); //buffer = Mem_Malloc( r_temppool, 1920*1080*2 );
R_BuildScreenMap();
R_BuildBlendMaps(); R_BuildBlendMaps();
d_pzbuffer = malloc(vid.width*vid.height*2); R_AllocScreen();
R_InitCaches(); }
void R_AllocScreen()
{
if( gpGlobals->width < 320 )
gpGlobals->width = 320;
if( gpGlobals->height < 200 )
gpGlobals->height = 200;
R_InitCaches();
gEngfuncs.SW_CreateBuffer( gpGlobals->width, gpGlobals->height, &swblit.stride, &swblit.bpp,
&swblit.rmask, &swblit.gmask, &swblit.bmask);
R_BuildScreenMap();
vid.width = gpGlobals->width;
vid.height = gpGlobals->height;
vid.rowbytes = gpGlobals->width; // rowpixels
if( d_pzbuffer )
Mem_Free( d_pzbuffer );
d_pzbuffer = Mem_Calloc( r_temppool, vid.width*vid.height*2 + 64 );
if( vid.buffer )
Mem_Free( vid.buffer );
vid.buffer = Mem_Malloc( r_temppool, vid.width * vid.height*sizeof( pixel_t ) );
} }
void R_BlitScreen() void R_BlitScreen()
{ {
//memset( vid.buffer, 10, vid.width * vid.height ); //memset( vid.buffer, 10, vid.width * vid.height );
int i; int u, v;
byte *buf = vid.buffer; void *buffer = gEngfuncs.SW_LockBuffer();
if( !buffer || gpGlobals->width != vid.width || gpGlobals->height != vid.height )
{
R_AllocScreen();
return;
}
//byte *buf = vid.buffer;
#pragma omp parallel for schedule(static) //#pragma omp parallel for schedule(static)
for( i = 0; i < vid.width * vid.height;i++) if( swblit.bpp == 2 )
{ {
#ifdef SEPARATE_BLIT unsigned short *pbuf = buffer;
// need only 1024 bytes table, but slower for( v = 0; v < vid.height;v++)
// wtf?? maybe some prefetch??? {
byte major = buf[(i<<1)+1]; uint start = vid.rowbytes * v;
byte minor = buf[(i<<1)]; uint dstart = swblit.stride * v;
for( u = 0; u < vid.width; u++ )
{
unsigned int s = vid.screen[vid.buffer[start + u]];
pbuf[dstart + u] = s;
}
}
}
else if( swblit.bpp == 4 )
{
unsigned int *pbuf = buffer;
buffer[i] = vid.screen_major[major] |vid.screen_minor[minor]; for( v = 0; v < vid.height;v++)
#else {
buffer[i] = vid.screen[vid.buffer[i]]; uint start = vid.rowbytes * v;
#endif uint dstart = swblit.stride * v;
for( u = 0; u < vid.width; u++ )
{
unsigned int s = vid.screen32[vid.buffer[start + u]];
pbuf[dstart + u] = s;
}
}
}
else if( swblit.bpp == 3 )
{
byte *pbuf = buffer;
for( v = 0; v < vid.height;v++)
{
uint start = vid.rowbytes * v;
uint dstart = swblit.stride * v;
for( u = 0; u < vid.width; u++ )
{
unsigned int s = vid.screen32[vid.buffer[start + u]];
pbuf[(dstart+u)*3] = s;
s = s >> 8;
pbuf[(dstart+u)*3+1] = s;
s = s >> 8;
pbuf[(dstart+u)*3+2] = s;
}
}
} }
#if 0
pglViewport( 0, 0, gpGlobals->width, gpGlobals->height ); pglViewport( 0, 0, gpGlobals->width, gpGlobals->height );
pglMatrixMode( GL_PROJECTION ); pglMatrixMode( GL_PROJECTION );
pglLoadIdentity(); pglLoadIdentity();
@ -223,4 +330,7 @@ void R_BlitScreen()
pglDisable( GL_TEXTURE_2D ); pglDisable( GL_TEXTURE_2D );
gEngfuncs.GL_SwapBuffers(); gEngfuncs.GL_SwapBuffers();
// memset( vid.buffer, 0, vid.width * vid.height * 2 ); // memset( vid.buffer, 0, vid.width * vid.height * 2 );
#else
gEngfuncs.SW_UnlockBuffer();
#endif
} }

5
r_local.h

@ -93,7 +93,7 @@ extern byte *r_temppool;
#define CULL_OTHER 4 // culled by other reason #define CULL_OTHER 4 // culled by other reason
// bit operation helpers // bit operation helpers
#define MASK(x) (BIT(x+1)-1) #define MASK(x) (BIT(x)-1)
#define GET_BIT(s,b) ((s & (1 << b)) >> b) #define GET_BIT(s,b) ((s & (1 << b)) >> b)
#define MOVE_BIT(s, f, t) (GET_BIT(s,f) << t ) #define MOVE_BIT(s, f, t) (GET_BIT(s,f) << t )
@ -140,6 +140,7 @@ typedef struct
pixel_t screen_major[256]; pixel_t screen_major[256];
#else #else
pixel_t screen[256*256]; pixel_t screen[256*256];
unsigned int screen32[256*256];
#endif #endif
byte addmap[256*256]; byte addmap[256*256];
byte modmap[256*256]; byte modmap[256*256];
@ -832,7 +833,7 @@ extern cvar_t *r_showhull;
#define NEAR_CLIP 0.01 #define NEAR_CLIP 0.01
#define MAXALIASVERTS 2000 // TODO: tune this //#define MAXALIASVERTS 2000 // TODO: tune this
#define ALIAS_Z_CLIP_PLANE 4 #define ALIAS_Z_CLIP_PLANE 4
// turbulence stuff // turbulence stuff

14
r_main.c

@ -458,7 +458,7 @@ static void R_Clear( int bitMask )
pglDepthFunc( GL_LEQUAL ); pglDepthFunc( GL_LEQUAL );
pglDepthRange( gldepthmin, gldepthmax ); pglDepthRange( gldepthmin, gldepthmax );
#endif #endif
memset( vid.buffer, 0, 1920*1080*2); memset( vid.buffer, 0, vid.width * vid.height *2);
} }
//============================================================================= //=============================================================================
@ -1686,6 +1686,10 @@ int R_RenderFrame( const ref_viewpass_t *rvp )
if( r_norefresh->value ) if( r_norefresh->value )
return 1; return 1;
// prevent cache overrun
if( gpGlobals->height > vid.height || gpGlobals->width > vid.width )
return 1;
// setup the initial render params // setup the initial render params
R_SetupRefParams( rvp ); R_SetupRefParams( rvp );
@ -1842,12 +1846,7 @@ qboolean R_Init()
// create the window and set up the context // create the window and set up the context
r_temppool = Mem_AllocPool( "ref_sw zone" ); r_temppool = Mem_AllocPool( "ref_sw zone" );
vid.width = 1920; if( !gEngfuncs.R_Init_Video( REF_SOFTWARE )) // request GL context
vid.height = 1080;
vid.rowbytes = 1920; // rowpixels
vid.buffer = Mem_Malloc( r_temppool, 1920*1080*sizeof( pixel_t ) );
if( !gEngfuncs.R_Init_Video( REF_GL )) // request GL context
{ {
gEngfuncs.R_Free_Video(); gEngfuncs.R_Free_Video();
@ -1855,6 +1854,7 @@ qboolean R_Init()
return false; return false;
} }
R_InitBlit();
R_InitImages(); R_InitImages();
// init draw stack // init draw stack

13
r_surf.c

@ -256,6 +256,8 @@ void R_DrawSurface (void)
pcolumndest += horzblockstep; pcolumndest += horzblockstep;
} }
// test what if we have very slow cache building
//usleep(10000);
} }
@ -490,9 +492,9 @@ void R_InitCaches (void)
} }
else else
{ {
size = SURFCACHE_SIZE_AT_320X240; size = SURFCACHE_SIZE_AT_320X240 * 2;
pix =1920 * 1080 * 16; pix = vid.width * vid.height * 2;
if (pix > 64000) if (pix > 64000)
size += (pix-64000)*3; size += (pix-64000)*3;
} }
@ -503,7 +505,12 @@ void R_InitCaches (void)
gEngfuncs.Con_Printf ("%ik surface cache\n", size/1024); gEngfuncs.Con_Printf ("%ik surface cache\n", size/1024);
sc_size = size; sc_size = size;
sc_base = (surfcache_t *)malloc(size); if( sc_base )
{
D_FlushCaches();
Mem_Free( sc_base );
}
sc_base = (surfcache_t *)Mem_Calloc(r_temppool,size);
sc_rover = sc_base; sc_rover = sc_base;
sc_base->next = NULL; sc_base->next = NULL;

Loading…
Cancel
Save