ref_soft: REF_SOFTWARE, resize support

This commit is contained in:
mittorn 2019-03-25 03:34:30 +07:00
parent 65cf77c32b
commit 3617e8e7a1
6 changed files with 166 additions and 46 deletions

View File

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

View File

@ -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)
for (v=0 ; v<height ; v++)
{
int alpha1 = vid.alpha;
#ifdef _OPENMP
pixel_t *dest = vid.buffer + (y + v) * vid.rowbytes + x;
#endif
sv = (skip + v)*(t2-t1)/h + t1;
source = buffer + sv*pic->width + s1;
{
f = 0;
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++)
{
pixel_t src = source[f>>16];
int alpha = vid.alpha;
int alpha = alpha1;
f += fstep;
if( transparent )

View File

@ -1,6 +1,13 @@
#include "r_local.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)
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;
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
for( i = 0; i < 256; i++ )
{
@ -69,16 +102,24 @@ void R_BuildScreenMap()
r = ((i >> (8 - 3) )<< 2 ) & MASK(5);
g = ((i >> (8 - 3 - 3)) << 3) & MASK(6);
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++ )
{
uint minor;
// restore minor GBRGBRGB
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);
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;
g = g1 + g2;
b = b1 + b2;
if( r > MASK(2) )
r = MASK(2);
if( g > MASK(2) )
g = MASK(2);
if( b > MASK(1) )
b = MASK(1);
if( r > MASK(3) )
r = MASK(3);
if( g > MASK(3) )
g = MASK(3);
if( b > MASK(2) )
b = MASK(2);
ASSERT(!vid.addmap[index2|index1]);
vid.addmap[index2|index1] = r << (2 + 3) | g << 2 | b;
r = r1 * r2 / MASK(2);
g = g1 * g2 / MASK(2);
b = b1 * b2 / MASK(1);
r = r1 * r2 / MASK(3);
g = g1 * g2 / MASK(3);
b = b1 * b2 / MASK(2);
vid.modmap[index2|index1] = r << (2 + 3) | g << 2 | b;
@ -130,10 +171,12 @@ void R_BuildBlendMaps()
}
}
void R_AllocScreen();
void R_InitBlit()
{
LOAD(glBegin);
/*LOAD(glBegin);
LOAD(glEnd);
LOAD(glTexCoord2f);
LOAD(glVertex2f);
@ -149,7 +192,7 @@ void R_InitBlit()
LOAD(glDebugMessageControlARB);
LOAD(glGetError);
LOAD(glGenTextures);
LOAD(glTexParameteri);
LOAD(glTexParameteri);*/
#ifdef GLDEBUG
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 );
#endif
buffer = Mem_Malloc( r_temppool, 1920*1080*2 );
//buffer = Mem_Malloc( r_temppool, 1920*1080*2 );
R_BuildScreenMap();
R_BuildBlendMaps();
d_pzbuffer = malloc(vid.width*vid.height*2);
R_InitCaches();
R_AllocScreen();
}
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()
{
//memset( vid.buffer, 10, vid.width * vid.height );
int i;
byte *buf = vid.buffer;
#pragma omp parallel for schedule(static)
for( i = 0; i < vid.width * vid.height;i++)
int u, v;
void *buffer = gEngfuncs.SW_LockBuffer();
if( !buffer || gpGlobals->width != vid.width || gpGlobals->height != vid.height )
{
#ifdef SEPARATE_BLIT
// need only 1024 bytes table, but slower
// wtf?? maybe some prefetch???
byte major = buf[(i<<1)+1];
byte minor = buf[(i<<1)];
R_AllocScreen();
return;
}
//byte *buf = vid.buffer;
buffer[i] = vid.screen_major[major] |vid.screen_minor[minor];
#else
buffer[i] = vid.screen[vid.buffer[i]];
#endif
//#pragma omp parallel for schedule(static)
if( swblit.bpp == 2 )
{
unsigned short *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.screen[vid.buffer[start + u]];
pbuf[dstart + u] = s;
}
}
}
else if( swblit.bpp == 4 )
{
unsigned int *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] = 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 );
pglMatrixMode( GL_PROJECTION );
pglLoadIdentity();
@ -223,4 +330,7 @@ void R_BlitScreen()
pglDisable( GL_TEXTURE_2D );
gEngfuncs.GL_SwapBuffers();
// memset( vid.buffer, 0, vid.width * vid.height * 2 );
#else
gEngfuncs.SW_UnlockBuffer();
#endif
}

View File

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

View File

@ -458,7 +458,7 @@ static void R_Clear( int bitMask )
pglDepthFunc( GL_LEQUAL );
pglDepthRange( gldepthmin, gldepthmax );
#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 )
return 1;
// prevent cache overrun
if( gpGlobals->height > vid.height || gpGlobals->width > vid.width )
return 1;
// setup the initial render params
R_SetupRefParams( rvp );
@ -1842,12 +1846,7 @@ qboolean R_Init()
// create the window and set up the context
r_temppool = Mem_AllocPool( "ref_sw zone" );
vid.width = 1920;
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
if( !gEngfuncs.R_Init_Video( REF_SOFTWARE )) // request GL context
{
gEngfuncs.R_Free_Video();
@ -1855,6 +1854,7 @@ qboolean R_Init()
return false;
}
R_InitBlit();
R_InitImages();
// init draw stack

View File

@ -256,6 +256,8 @@ void R_DrawSurface (void)
pcolumndest += horzblockstep;
}
// test what if we have very slow cache building
//usleep(10000);
}
@ -490,9 +492,9 @@ void R_InitCaches (void)
}
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)
size += (pix-64000)*3;
}
@ -503,7 +505,12 @@ void R_InitCaches (void)
gEngfuncs.Con_Printf ("%ik surface cache\n", size/1024);
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_base->next = NULL;