softrend: Resembling a pixel pipeline, textures, sort, cull

- Basic pixel pipeline, a bit better triangle tests, specialized render handlers
- Textures w/ point filtering. Not very smart is it goes 32 -> 16 -> 32 bpp, but works.
- The texture cache is shared rather inelegantly w/ OpenGL one
- Culling
- PParam sorting (shared w/ GL)

The texturing and color blending paths are ugly and slow
This commit is contained in:
Stefanos Kornilios Mitsis Poiitidis 2015-08-05 17:02:34 +02:00 committed by TwistedUmbrella
parent fcf273dd11
commit e6a9d3e661
4 changed files with 923 additions and 551 deletions

View File

@ -419,7 +419,7 @@ union FPU_SHAD_SCALE_type
#define FPU_SHAD_SCALE PvrReg(FPU_SHAD_SCALE_addr,FPU_SHAD_SCALE_type) // RW Intensity Volume mode
#define FPU_CULL_VAL PvrReg(FPU_CULL_VAL_addr,u32) // RW Comparison value for culling
#define FPU_CULL_VAL PvrReg(FPU_CULL_VAL_addr,f32) // RW Comparison value for culling
#define FPU_PARAM_CFG PvrReg(FPU_PARAM_CFG_addr,u32) // RW Parameter read control
#define HALF_OFFSET PvrReg(HALF_OFFSET_addr,u32) // RW Pixel sampling control
#define FPU_PERP_VAL PvrReg(FPU_PERP_VAL_addr,u32) // RW Comparison value for perpendicular polygons

View File

@ -100,8 +100,17 @@ struct gl_ctx
extern gl_ctx gl;
GLuint gl_GetTexture(TSP tsp,TCW tcw);
struct text_info {
u16* pdata;
u32 width;
u32 height;
u32 textype; // 0 565, 1 1555, 2 4444
};
text_info raw_GetTexture(TSP tsp, TCW tcw);
void CollectCleanup();
void DoCleanup();
void SortPParams();
void BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt);
int GetProgramID(u32 cp_AlphaTest, u32 pp_ClipTestMode,

View File

@ -69,6 +69,8 @@ struct TextureCacheData
TCW tcw;
GLuint texID; //gl texture
u16* pData;
int tex_type;
u32 Lookups;
@ -122,10 +124,18 @@ struct TextureCacheData
}
//Create GL texture from tsp/tcw
void Create()
void Create(bool isGL)
{
//ask GL for texture ID
glGenTextures(1,&texID);
if (isGL) {
glGenTextures(1, &texID);
}
else {
texID = 0;
}
pData = 0;
tex_type = 0;
//Reset state info ..
Lookups=0;
@ -141,30 +151,32 @@ struct TextureCacheData
w=8<<tsp.TexU; //tex width
h=8<<tsp.TexV; //tex height
//bind texture to set modes
glBindTexture(GL_TEXTURE_2D,texID);
if (texID) {
//bind texture to set modes
glBindTexture(GL_TEXTURE_2D, texID);
//set texture repeat mode
SetRepeatMode(GL_TEXTURE_WRAP_S,tsp.ClampU,tsp.FlipU); // glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (tsp.ClampU ? GL_CLAMP_TO_EDGE : (tsp.FlipU ? GL_MIRRORED_REPEAT : GL_REPEAT))) ;
SetRepeatMode(GL_TEXTURE_WRAP_T,tsp.ClampV,tsp.FlipV); // glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (tsp.ClampV ? GL_CLAMP_TO_EDGE : (tsp.FlipV ? GL_MIRRORED_REPEAT : GL_REPEAT))) ;
//set texture repeat mode
SetRepeatMode(GL_TEXTURE_WRAP_S, tsp.ClampU, tsp.FlipU); // glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (tsp.ClampU ? GL_CLAMP_TO_EDGE : (tsp.FlipU ? GL_MIRRORED_REPEAT : GL_REPEAT))) ;
SetRepeatMode(GL_TEXTURE_WRAP_T, tsp.ClampV, tsp.FlipV); // glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (tsp.ClampV ? GL_CLAMP_TO_EDGE : (tsp.FlipV ? GL_MIRRORED_REPEAT : GL_REPEAT))) ;
#ifdef GLES
glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
#endif
//set texture filter mode
if ( tsp.FilterMode == 0 )
{
//disable filtering, mipmaps
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
}
else
{
//bilinear filtering
//PowerVR supports also trilinear via two passes, but we ignore that for now
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, (tcw.MipMapped && settings.rend.UseMipmaps)?GL_LINEAR_MIPMAP_NEAREST:GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
//set texture filter mode
if (tsp.FilterMode == 0)
{
//disable filtering, mipmaps
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
}
else
{
//bilinear filtering
//PowerVR supports also trilinear via two passes, but we ignore that for now
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, (tcw.MipMapped && settings.rend.UseMipmaps)?GL_LINEAR_MIPMAP_NEAREST:GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
}
}
//PAL texture
@ -286,13 +298,29 @@ struct TextureCacheData
//lock the texture to detect changes in it
lock_block = libCore_vramlock_Lock(sa_tex,sa+size-1,this);
//upload to OpenGL !
glBindTexture(GL_TEXTURE_2D, texID);
GLuint comps=textype==GL_UNSIGNED_SHORT_5_6_5?GL_RGB:GL_RGBA;
glTexImage2D(GL_TEXTURE_2D, 0,comps , w, h, 0, comps, textype, temp_tex_buffer);
if (texID) {
//upload to OpenGL !
glBindTexture(GL_TEXTURE_2D, texID);
GLuint comps=textype==GL_UNSIGNED_SHORT_5_6_5?GL_RGB:GL_RGBA;
glTexImage2D(GL_TEXTURE_2D, 0,comps , w, h, 0, comps, textype, temp_tex_buffer);
if (tcw.MipMapped && settings.rend.UseMipmaps)
glGenerateMipmap(GL_TEXTURE_2D);
}
else {
if (textype == GL_UNSIGNED_SHORT_5_6_5)
tex_type = 0;
else if (textype == GL_UNSIGNED_SHORT_5_5_5_1)
tex_type = 1;
else if (textype == GL_UNSIGNED_SHORT_4_4_4_4)
tex_type = 2;
if (tcw.MipMapped && settings.rend.UseMipmaps)
glGenerateMipmap(GL_TEXTURE_2D);
if (pData) {
free(pData);
}
pData = (u16*)malloc(w * h * 2);
memcpy(pData, temp_tex_buffer, w * h * 2);
}
}
//true if : dirty or paletted texture and revs don't match
@ -300,7 +328,13 @@ struct TextureCacheData
void Delete()
{
glDeleteTextures(1,&texID);
if (pData) {
free(pData);
pData = 0;
}
if (texID) {
glDeleteTextures(1, &texID);
}
if (lock_block)
libCore_vramlock_Unlock_block(lock_block);
lock_block=0;
@ -414,7 +448,7 @@ GLuint gl_GetTexture(TSP tsp, TCW tcw)
tf->tsp=tsp;
tf->tcw=tcw;
tf->Create();
tf->Create(true);
}
//update if needed
@ -428,6 +462,52 @@ GLuint gl_GetTexture(TSP tsp, TCW tcw)
return tf->texID;
}
text_info raw_GetTexture(TSP tsp, TCW tcw)
{
text_info rv = { 0 };
//lookup texture
TextureCacheData* tf;
//= TexCache.Find(tcw.full,tsp.full);
u64 key = ((u64)tcw.full << 32) | tsp.full;
TexCacheIter tx = TexCache.find(key);
if (tx != TexCache.end())
{
tf = &tx->second;
}
else //create if not existing
{
TextureCacheData tfc = { 0 };
TexCache[key] = tfc;
tx = TexCache.find(key);
tf = &tx->second;
tf->tsp = tsp;
tf->tcw = tcw;
tf->Create(false);
}
//update if needed
if (tf->NeedsUpdate())
tf->Update();
//update state for opts/stuff
tf->Lookups++;
//return gl texture
rv.height = tf->h;
rv.width = tf->w;
rv.pdata = tf->pData;
rv.textype = tf->tex_type;
return rv;
}
void CollectCleanup() {
vector<u64> list;

File diff suppressed because it is too large Load Diff