pvr: static init UB

Issue # #148
This commit is contained in:
Flyinghead 2021-03-26 18:39:19 +01:00
parent 972f945058
commit 2b41d9684f
3 changed files with 58 additions and 78 deletions

View File

@ -2,8 +2,6 @@
#include "ta_ctx.h"
#include "hw/holly/holly_intc.h"
extern u32 ta_type_lut[256];
/*
Threaded TA Implementation
@ -135,7 +133,7 @@ static void fill_fsm()
for (int k=0;k<32;k++)
{
u32 uid=ta_type_lut[k*4];
u32 uid = TaTypeLut::instance().table[k * 4];
u32 vt=uid & 0x7f;
bool v64 = vt == 5 || vt == 6 || vt == 11 || vt == 12 || vt == 13 || vt == 14;

View File

@ -13,3 +13,16 @@ void DYNACALL ta_vtx_data32(const SQBuffer *data);
void ta_vtx_data(const SQBuffer *data, u32 size);
bool ta_parse_vdrc(TA_context* ctx);
class TaTypeLut
{
public:
static const TaTypeLut& instance() {
static TaTypeLut _instance;
return _instance;
}
u32 table[256];
private:
TaTypeLut();
};

View File

@ -8,28 +8,17 @@
#include "ta_ctx.h"
#include "pvr_mem.h"
#include "Renderer_if.h"
#include "cfg/option.h"
#include <algorithm>
#include <cmath>
u32 ta_type_lut[256];
extern int screen_height;
#define TACALL DYNACALL
#ifdef NDEBUG
#undef verify
#define verify(x)
#endif
#define PLD(ptr,offs) // __asm __volatile ( "pld [%0, #" #offs "]\n"::"r" (ptr): );
#define TA_VTX
#define TA_SPR
#define TA_EOS
#define TA_PP
#define TA_SP
#define TA_EOL
#define TA_V64H
//cache state vars
static u32 tileclip_val = 0;
@ -70,13 +59,13 @@ alignas(4) static u8 FaceBaseColor[4];
alignas(4) static u8 FaceOffsColor[4];
alignas(4) static u8 FaceBaseColor1[4];
alignas(4) static u8 FaceOffsColor1[4];
alignas(4) static u32 SFaceBaseColor;
alignas(4) static u32 SFaceOffsColor;
static u32 SFaceBaseColor;
static u32 SFaceOffsColor;
//misc ones
static const u32 ListType_None = -1;
static const u32 SZ32 = 1;
static const u32 SZ64 = 2;
const u32 ListType_None = -1;
const u32 SZ32 = 1;
const u32 SZ64 = 2;
#include "ta_structs.h"
@ -99,10 +88,9 @@ static f32 f16(u16 v)
//Splitter function (normally ta_dma_main , modified for split dma's)
template<u32 instance>
class FifoSplitter
{
public:
static const u32 *ta_type_lut;
static void ta_list_start(u32 new_list)
{
@ -130,7 +118,6 @@ public:
if (part==2)
{
TA_V64H;
TaCmd=ta_main;
}
@ -139,7 +126,7 @@ public:
#define ver_32B_def(num) \
case num : {\
AppendPolyVertex##num(&vp->vtx##num);\
rv=SZ32; TA_VTX; }\
rv=SZ32; }\
break;
//32b , always in one pass :)
@ -160,7 +147,6 @@ case num : {\
/*process first half*/\
if (part!=2)\
{\
TA_VTX;\
rv+=SZ32;\
AppendPolyVertex##num##A(&vp->vtx##num##A);\
}\
@ -210,7 +196,6 @@ case num : {\
static Ta_Dma* TACALL ta_mod_vol_data(Ta_Dma* data,Ta_Dma* data_end)
{
TA_VertexParam* vp=(TA_VertexParam*)data;
TA_VTX;
if (data==data_end)
{
AppendModVolVertexA(&vp->mvolA);
@ -228,7 +213,6 @@ case num : {\
}
static Ta_Dma* TACALL ta_spriteB_data(Ta_Dma* data,Ta_Dma* data_end)
{
TA_V64H;
//32B more needed , 32B done :)
TaCmd=ta_main;
@ -238,7 +222,6 @@ case num : {\
}
static Ta_Dma* TACALL ta_sprite_data(Ta_Dma* data,Ta_Dma* data_end)
{
TA_SPR;
verify(data->pcw.ParaType==ParamType_Vertex_Parameter);
if (data==data_end)
{
@ -257,7 +240,6 @@ case num : {\
AppendSpriteVertexA(&vp->spr1A);
AppendSpriteVertexB(&vp->spr1B);
//all 64B doneisimooooo la la la :*iiiiii niarj
return data+SZ64;
}
}
@ -270,24 +252,17 @@ case num : {\
//If SZ64 && 32 bytes
#define IS_FIST_HALF ((poly_size!=SZ32) && (data==data_end))
//If SZ32 && >=32 bytes
//If SZ64 && > 32 bytes
#define HAS_FULL_DATA (poly_size==SZ32 ? (data<=data_end) : (data<data_end))
#define ITER verify(data->pcw.ParaType==ParamType_Vertex_Parameter);\
PLD(data,128); \
ta_handle_poly<poly_type,0>(data,0); \
if (data->pcw.EndOfStrip) \
goto strip_end; \
data+=poly_size;
if (IS_FIST_HALF)
goto fist_half;
do
{
ITER
} while (HAS_FULL_DATA);
verify(data->pcw.ParaType == ParamType_Vertex_Parameter);
ta_handle_poly<poly_type,0>(data, 0);
if (data->pcw.EndOfStrip)
goto strip_end;
data += poly_size;
} while (poly_size == SZ32 ? data <= data_end : data < data_end);
if (IS_FIST_HALF)
{
@ -305,7 +280,6 @@ strip_end:
TaCmd=ta_main;
if (data->pcw.EndOfStrip)
EndPolyStrip();
TA_EOS;
return data+poly_size;
}
@ -337,15 +311,12 @@ strip_end:
return data+SZ32;
}
public:
//Group_En bit seems ignored, thanks p1pkin
#define group_EN() /*if (data->pcw.Group_En) */{ TileClipMode(data->pcw.User_Clip); }
static Ta_Dma* TACALL ta_main(Ta_Dma* data,Ta_Dma* data_end)
{
do
{
PLD(data,128);
switch (data->pcw.ParaType)
{
//Control parameter
@ -369,7 +340,6 @@ public:
CurrentList=ListType_None;
VertexDataFP = NullVertexData;
data+=SZ32;
TA_EOL;
}
break;
@ -391,8 +361,6 @@ public:
//PolyType :32B/64B
case ParamType_Polygon_or_Modifier_Volume:
{
TA_PP;
group_EN();
//Yep , C++ IS lame & limited
#include "ta_const_df.h"
@ -409,7 +377,7 @@ public:
else
{
u32 uid=ta_type_lut[data->pcw.obj_ctrl];
u32 uid = ta_type_lut[data->pcw.obj_ctrl];
u32 psz=uid>>30;
u32 pdid=(u8)(uid);
u32 ppid=(u8)(uid>>8);
@ -442,7 +410,6 @@ public:
case ParamType_Sprite:
{
TA_SP;
group_EN();
if (CurrentList==ListType_None)
ta_list_start(data->pcw.ListType); //start a list ;)
@ -455,13 +422,7 @@ public:
//Variable size
case ParamType_Vertex_Parameter:
//log ("vtx");
{
//printf("VTX:0x%08X\n", VertexDataFP);
//verify(VertexDataFP != NullVertexData);
data = VertexDataFP(data, data_end);
}
data = VertexDataFP(data, data_end);
break;
//not handled
@ -475,30 +436,16 @@ public:
break;
}
}
while(data<=data_end);
while (data <= data_end);
return data;
}
public:
//Fill in lookup table
FifoSplitter()
{
for (int i=0;i<256;i++)
{
PCW pcw;
pcw.obj_ctrl=i;
u32 rv= poly_data_type_id(pcw);
u32 type= poly_header_type_size(pcw);
if (type& 0x80)
rv|=(SZ64<<30);
else
rv|=(SZ32<<30);
rv|=(type&0x7F)<<8;
ta_type_lut[i]=rv;
}
VertexDataFP = NullVertexData;
ta_type_lut = TaTypeLut::instance().table;
}
/*
Volume,Col_Type,Texture,Offset,Gouraud,16bit_UV
@ -677,7 +624,6 @@ public:
}
}
void vdec_init()
{
VDECInit();
@ -696,6 +642,7 @@ public:
CurrentPPlist = NULL;
}
private:
__forceinline
static void SetTileClip(u32 xmin,u32 ymin,u32 xmax,u32 ymax)
{
@ -1427,10 +1374,32 @@ public:
}
};
const u32 *FifoSplitter::ta_type_lut;
TaTypeLut::TaTypeLut()
{
for (int i = 0; i < 256; i++)
{
PCW pcw;
pcw.obj_ctrl = i;
u32 rv = FifoSplitter::poly_data_type_id(pcw);
u32 type = FifoSplitter::poly_header_type_size(pcw);
if (type & 0x80)
rv |= SZ64 << 30;
else
rv |= SZ32 << 30;
rv |= (type & 0x7F) << 8;
table[i] = rv;
}
}
static bool ClearZBeforePass(int pass_number);
static void getRegionTileClipping(u32& xmin, u32& xmax, u32& ymin, u32& ymax);
FifoSplitter<0> TAFifo0;
FifoSplitter TAFifo0;
//
// Check if a vertex has huge x,y,z values or negative z
@ -1639,7 +1608,7 @@ bool ta_parse_vdrc(TA_context* ctx)
bool overrun = ctx->rend.Overrun;
if (overrun)
WARN_LOG(PVR, "ERROR: TA context overrun");
else if (screen_height > 480)
else if (config::RenderResolution > 480)
{
fix_texture_bleeding(&vd_rc.global_param_op);
fix_texture_bleeding(&vd_rc.global_param_pt);