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:
parent
fcf273dd11
commit
e6a9d3e661
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue