mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-13 07:14:49 +00:00
Merge branch 'master' of https://github.com/DHrpcs3/rpcs3
This commit is contained in:
commit
017e44cf4d
@ -50,6 +50,24 @@ enum
|
||||
CELL_GCM_LOCATION_MAIN = 1,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CELL_GCM_FREQUENCY_MODULO = 1,
|
||||
CELL_GCM_FREQUENCY_DIVIDE = 0,
|
||||
};
|
||||
|
||||
enum CellRescTableElement
|
||||
{
|
||||
CELL_RESC_ELEMENT_HALF = 0,
|
||||
CELL_RESC_ELEMENT_FLOAT = 1,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CELL_GCM_FLAT = 0x1D00,
|
||||
CELL_GCM_SMOOTH = 0x1D01,
|
||||
};
|
||||
|
||||
// GCM Texture
|
||||
enum
|
||||
{
|
||||
|
@ -559,6 +559,14 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3
|
||||
}
|
||||
break;
|
||||
|
||||
case NV4097_SET_DEPTH_BOUNDS_MAX:
|
||||
{
|
||||
m_set_depth_bounds = true;
|
||||
const u32 a0 = ARGS(0);
|
||||
m_depth_bounds_max = (float&)a0;
|
||||
}
|
||||
break;
|
||||
|
||||
// Viewport
|
||||
case NV4097_SET_VIEWPORT_VERTICAL:
|
||||
{
|
||||
@ -1620,6 +1628,12 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3
|
||||
}
|
||||
break;
|
||||
|
||||
case NV4097_SET_FREQUENCY_DIVIDER_OPERATION:
|
||||
{
|
||||
m_set_frequency_divider_operation = ARGS(0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x000002c8:
|
||||
case 0x000002d0:
|
||||
case 0x000002d8:
|
||||
|
@ -408,6 +408,9 @@ public:
|
||||
bool m_set_front_face;
|
||||
u32 m_front_face;
|
||||
|
||||
// Frequency divider
|
||||
u32 m_set_frequency_divider_operation;
|
||||
|
||||
u8 m_begin_end;
|
||||
bool m_read_buffer;
|
||||
|
||||
@ -490,19 +493,27 @@ protected:
|
||||
|
||||
void Reset()
|
||||
{
|
||||
m_set_dither = false;
|
||||
m_set_color_mask = false;
|
||||
m_set_clip = false;
|
||||
m_set_depth_func = false;
|
||||
m_set_depth_bounds = false;
|
||||
m_set_depth_test = false;
|
||||
m_set_depth_func = false;
|
||||
m_set_depth_mask = false;
|
||||
m_set_depth_bounds_test = false;
|
||||
m_set_depth_bounds = false;
|
||||
m_set_viewport_horizontal = false;
|
||||
m_set_viewport_vertical = false;
|
||||
m_set_scissor_horizontal = false;
|
||||
m_set_scissor_vertical = false;
|
||||
m_set_front_polygon_mode = false;
|
||||
m_set_back_polygon_mode = false;
|
||||
m_set_blend = false;
|
||||
m_set_blend_sfactor = false;
|
||||
m_set_blend_dfactor = false;
|
||||
m_set_blend_equation = false;
|
||||
m_set_blend_color = false;
|
||||
m_set_stencil_test = false;
|
||||
m_set_two_sided_stencil_test_enable = false;
|
||||
m_set_stencil_mask = false;
|
||||
m_set_stencil_func = false;
|
||||
m_set_stencil_func_ref = false;
|
||||
@ -517,12 +528,11 @@ protected:
|
||||
m_set_back_stencil_fail = false;
|
||||
m_set_back_stencil_zfail = false;
|
||||
m_set_back_stencil_zpass = false;
|
||||
m_set_blend_equation = false;
|
||||
m_set_depth_mask = false;
|
||||
m_set_point_sprite_control = false;
|
||||
m_set_point_size = false;
|
||||
m_set_line_width = false;
|
||||
m_set_line_smooth = false;
|
||||
m_set_shade_mode = false;
|
||||
m_set_blend_color = false;
|
||||
m_set_semaphore_offset = false;
|
||||
m_set_fog_mode = false;
|
||||
m_set_fog_params = false;
|
||||
@ -535,16 +545,21 @@ protected:
|
||||
m_set_context_dma_z = false;
|
||||
m_set_cull_face = false;
|
||||
m_set_front_face = false;
|
||||
m_set_alpha_test = false;
|
||||
m_set_alpha_func = false;
|
||||
m_set_alpha_ref = false;
|
||||
m_set_poly_smooth = false;
|
||||
m_set_poly_offset_fill = false;
|
||||
m_set_poly_offset_line = false;
|
||||
m_set_poly_offset_point = false;
|
||||
m_set_poly_offset_mode = false;
|
||||
m_set_restart_index = false;
|
||||
m_set_point_sprite_control = false;
|
||||
m_set_specular = false;
|
||||
m_set_line_stipple = false;
|
||||
m_set_logic_op = false;
|
||||
m_set_surface_format = false;
|
||||
m_set_surface_clip_horizontal = false;
|
||||
m_set_surface_clip_vertical = false;
|
||||
|
||||
m_clear_surface_mask = 0;
|
||||
m_begin_end = 0;
|
||||
|
@ -39,8 +39,8 @@ enum
|
||||
static const float
|
||||
PICTURE_SIZE = (1.0f),
|
||||
UV_DELTA_PS = (1.f / 8.f),
|
||||
UV_DELTA_LB = (1.f / 6.f);
|
||||
|
||||
UV_DELTA_LB = (1.f / 6.f),
|
||||
XY_DELTA_LB = (1.f / 8.f);
|
||||
|
||||
struct RescVertex_t
|
||||
{
|
||||
@ -51,6 +51,7 @@ struct RescVertex_t
|
||||
|
||||
// Defines
|
||||
#define roundup(x,a) (((x)+(a)-1)&(~((a)-1)))
|
||||
#define SEVIRITY 80.f
|
||||
|
||||
struct CCellRescInternal
|
||||
{
|
||||
@ -58,12 +59,17 @@ struct CCellRescInternal
|
||||
CellRescSrc m_rescSrc[SRC_BUFFER_NUM];
|
||||
u32 m_dstMode;
|
||||
CellRescDsts m_rescDsts[4], *m_pRescDsts;
|
||||
CellRescTableElement m_interlaceElement;
|
||||
|
||||
u32 m_colorBuffersEA_addr, m_vertexArrayEA_addr, m_fragmentUcodeEA_addr;
|
||||
u32 m_colorBuffersEA, m_vertexArrayEA, m_fragmentUcodeEA;
|
||||
u32 m_bufIdFront;
|
||||
s32 m_dstWidth, m_dstHeight, m_dstPitch;
|
||||
u16 m_srcWidthInterlace, m_srcHeightInterlace;
|
||||
u32 m_dstBufInterval, m_dstOffsets[MAX_DST_BUFFER_NUM];
|
||||
s32 m_nVertex;
|
||||
u32 m_bufIdFrontPrevDrop, m_bufIdPalMidPrev, m_bufIdPalMidNow;
|
||||
u32 m_interlaceTableEA;
|
||||
int m_interlaceTableLength;
|
||||
float m_ratioAdjX, m_ratioAdjY;
|
||||
bool m_bInitialized, m_bNewlyAdjustRatio;
|
||||
|
||||
@ -94,6 +100,7 @@ inline bool IsPalDrop() { return (IsPal() && s_rescInternalInstance->m_in
|
||||
inline bool IsPalInterpolate() { return (IsPal() && ((s_rescInternalInstance->m_initConfig.palTemporalMode == CELL_RESC_PAL_60_INTERPOLATE)
|
||||
|| (s_rescInternalInstance->m_initConfig.palTemporalMode == CELL_RESC_PAL_60_INTERPOLATE_30_DROP)
|
||||
|| (s_rescInternalInstance->m_initConfig.palTemporalMode == CELL_RESC_PAL_60_INTERPOLATE_DROP_FLEXIBLE))); }
|
||||
inline bool IsNotPalInterpolate() { return !IsPalInterpolate(); }
|
||||
inline int GetNumColorBuffers(){ return IsPalInterpolate() ? 6 : (IsPalDrop() ? 3 : 2); }
|
||||
inline bool IsInterlace() { return s_rescInternalInstance->m_initConfig.interlaceMode == CELL_RESC_INTERLACE_FILTER; }
|
||||
inline bool IsTextureNR() { return !IsInterlace(); }
|
||||
@ -118,7 +125,7 @@ void BuildupVertexBufferNR()
|
||||
float U_PS0 = UV_CENTER - U_PS;
|
||||
float U_PS1 = UV_CENTER + U_PS;
|
||||
|
||||
mem_ptr_t<RescVertex_t> vv(s_rescInternalInstance->m_vertexArrayEA_addr);
|
||||
mem_ptr_t<RescVertex_t> vv(s_rescInternalInstance->m_vertexArrayEA);
|
||||
|
||||
if(s_rescInternalInstance->m_dstMode == CELL_RESC_720x480 || s_rescInternalInstance->m_dstMode == CELL_RESC_720x576){
|
||||
switch((u32)s_rescInternalInstance->m_initConfig.ratioMode){
|
||||
@ -194,7 +201,7 @@ void BuildupVertexBufferUN(s32 srcIdx)
|
||||
float U2_FS1 = s_rescInternalInstance->m_dstWidth;
|
||||
float V2_FS1 = s_rescInternalInstance->m_dstHeight;
|
||||
|
||||
mem_ptr_t<RescVertex_t> vv(s_rescInternalInstance->m_vertexArrayEA_addr);
|
||||
mem_ptr_t<RescVertex_t> vv(s_rescInternalInstance->m_vertexArrayEA);
|
||||
|
||||
if(s_rescInternalInstance->m_dstMode == CELL_RESC_720x480 || s_rescInternalInstance->m_dstMode == CELL_RESC_720x576){
|
||||
switch((u32)s_rescInternalInstance->m_initConfig.ratioMode){
|
||||
@ -360,9 +367,81 @@ bool CheckInitConfig(mem_ptr_t<CellRescInitConfig> initConfig)
|
||||
|
||||
void InitMembers()
|
||||
{
|
||||
s_rescInternalInstance->m_dstMode = (CellRescBufferMode)0;
|
||||
s_rescInternalInstance->m_interlaceElement = CELL_RESC_ELEMENT_FLOAT;
|
||||
s_rescInternalInstance->m_colorBuffersEA = NULL;
|
||||
s_rescInternalInstance->m_vertexArrayEA = NULL;
|
||||
s_rescInternalInstance->m_fragmentUcodeEA = NULL;
|
||||
s_rescInternalInstance->m_interlaceTableEA = NULL;
|
||||
s_rescInternalInstance->m_bufIdFront = 0;
|
||||
s_rescInternalInstance->m_dstWidth = 0;
|
||||
s_rescInternalInstance->m_dstHeight = 0;
|
||||
s_rescInternalInstance->m_dstPitch = 0;
|
||||
s_rescInternalInstance->m_srcWidthInterlace = 0;
|
||||
s_rescInternalInstance->m_srcHeightInterlace = 0;
|
||||
s_rescInternalInstance->m_dstBufInterval = 0;
|
||||
s_rescInternalInstance->m_nVertex = 0;
|
||||
s_rescInternalInstance->m_ratioAdjX = 1.f;
|
||||
s_rescInternalInstance->m_ratioAdjY = 1.f;
|
||||
s_rescInternalInstance->m_interlaceTableLength = 32;
|
||||
s_rescInternalInstance->m_bInitialized = false;
|
||||
s_rescInternalInstance->m_bNewlyAdjustRatio = false;
|
||||
|
||||
//E PAL related variables
|
||||
//s_rescInternalInstance->m_intrThread50 = 0;
|
||||
//s_rescInternalInstance->m_lastDummyFlip = 0;
|
||||
//s_rescInternalInstance->m_lastVsync60 = 0;
|
||||
//s_rescInternalInstance->m_lastVsync50 = 0;
|
||||
s_rescInternalInstance->m_bufIdFrontPrevDrop = 2;
|
||||
s_rescInternalInstance->m_bufIdPalMidPrev = 4;
|
||||
s_rescInternalInstance->m_bufIdPalMidNow = 5;
|
||||
//s_rescInternalInstance->m_cgpTvalue = 0;
|
||||
//s_rescInternalInstance->m_isDummyFlipped = true;
|
||||
s_rescInternalInstance->m_flexRatio = 0.f; // interpolate
|
||||
//s_rescInternalInstance->m_commandIdxCaF = 1;
|
||||
//s_rescInternalInstance->m_rcvdCmdIdx = 0;
|
||||
|
||||
//s_rescInternalInstance->m_lastV60.idx = 0;
|
||||
//s_rescInternalInstance->m_lastV60.time = Util::GetSystemTime();
|
||||
//s_rescInternalInstance->m_lastV50.idx = 0;
|
||||
//s_rescInternalInstance->m_lastV50.time = Util::GetSystemTime();
|
||||
|
||||
//s_rescInternalInstance->m_feedback.interval60 = 1;
|
||||
|
||||
for (int i = 0; i<SRC_BUFFER_NUM; i++) {
|
||||
s_rescInternalInstance->m_rescSrc[i].format = 0;
|
||||
s_rescInternalInstance->m_rescSrc[i].pitch = 0;
|
||||
s_rescInternalInstance->m_rescSrc[i].width = 0;
|
||||
s_rescInternalInstance->m_rescSrc[i].height = 0;
|
||||
s_rescInternalInstance->m_rescSrc[i].offset = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i<MAX_DST_BUFFER_NUM; i++) {
|
||||
s_rescInternalInstance->m_dstOffsets[i] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
for (int i = 0; i<RESC_PARAM_NUM; i++) {
|
||||
s_rescInternalInstance->m_cgParamIndex[i] = 0xFF;
|
||||
}
|
||||
{
|
||||
s_rescInternalInstance->m_rescDsts[0].format = CELL_RESC_SURFACE_A8R8G8B8;
|
||||
s_rescInternalInstance->m_rescDsts[0].pitch = GcmSysTypePrefix::cellGcmGetTiledPitchSize(720 * 4);
|
||||
s_rescInternalInstance->m_rescDsts[0].heightAlign = 8;
|
||||
s_rescInternalInstance->m_rescDsts[1].format = CELL_RESC_SURFACE_A8R8G8B8;
|
||||
s_rescInternalInstance->m_rescDsts[1].pitch = GcmSysTypePrefix::cellGcmGetTiledPitchSize(720 * 4);
|
||||
s_rescInternalInstance->m_rescDsts[1].heightAlign = 8;
|
||||
s_rescInternalInstance->m_rescDsts[2].format = CELL_RESC_SURFACE_A8R8G8B8;
|
||||
s_rescInternalInstance->m_rescDsts[2].pitch = GcmSysTypePrefix::cellGcmGetTiledPitchSize(1280 * 4);
|
||||
s_rescInternalInstance->m_rescDsts[2].heightAlign = 8;
|
||||
s_rescInternalInstance->m_rescDsts[3].format = CELL_RESC_SURFACE_A8R8G8B8;
|
||||
s_rescInternalInstance->m_rescDsts[3].pitch = GcmSysTypePrefix::cellGcmGetTiledPitchSize(1920 * 4);
|
||||
s_rescInternalInstance->m_rescDsts[3].heightAlign = 8;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void InitContext(mem_ptr_t<CellGcmContextData>& cntxt)
|
||||
void SetupRsxRenderingStates(mem_ptr_t<CellGcmContextData>& cntxt)
|
||||
{
|
||||
//TODO: use cntxt
|
||||
GSLockCurrent lock(GS_LOCK_WAIT_FLUSH);
|
||||
@ -376,14 +455,13 @@ void InitContext(mem_ptr_t<CellGcmContextData>& cntxt)
|
||||
r.m_set_cull_face = false;
|
||||
r.m_set_depth_bounds_test = false;
|
||||
r.m_set_depth_test = false;
|
||||
//GcmCmdTypePrefix::cellGcmSetPolygonOffsetFillEnable(con, CELL_GCM_FALSE);
|
||||
r.m_set_poly_offset_fill = false;
|
||||
r.m_set_stencil_test = false;
|
||||
r.m_set_two_sided_stencil_test_enable = false;
|
||||
//GcmCmdTypePrefix::cellGcmSetPointSpriteControl(con, CELL_GCM_FALSE, 0, 0);
|
||||
r.m_set_point_sprite_control = false;
|
||||
r.m_set_dither = true;
|
||||
r.m_set_shade_mode = true; r.m_shade_mode = 0x1D01;
|
||||
//GcmCmdTypePrefix::cellGcmSetFrequencyDividerOperation(con, 0);
|
||||
r.m_set_specular = false;
|
||||
r.m_set_shade_mode = true; r.m_shade_mode = CELL_GCM_SMOOTH;
|
||||
r.m_set_frequency_divider_operation = CELL_GCM_FREQUENCY_DIVIDE;
|
||||
|
||||
r.m_set_viewport_horizontal = r.m_set_viewport_vertical = true;
|
||||
r.m_viewport_x = 0;
|
||||
@ -409,7 +487,7 @@ void InitContext(mem_ptr_t<CellGcmContextData>& cntxt)
|
||||
}
|
||||
}
|
||||
|
||||
void InitVertex(mem_ptr_t<CellGcmContextData>& cntxt)
|
||||
void SetupVertexArrays(mem_ptr_t<CellGcmContextData>& cntxt)
|
||||
{
|
||||
GSLockCurrent lock(GS_LOCK_WAIT_FLUSH);
|
||||
GSRender& r = Emu.GetGSManager().GetRender();
|
||||
@ -417,6 +495,51 @@ void InitVertex(mem_ptr_t<CellGcmContextData>& cntxt)
|
||||
//TODO
|
||||
}
|
||||
|
||||
void SetupSurfaces(mem_ptr_t<CellGcmContextData>& cntxt)
|
||||
{
|
||||
bool isMrt;
|
||||
u32 dstOffset0, dstOffset1;
|
||||
|
||||
if (IsNotPalInterpolate()) {
|
||||
isMrt = false;
|
||||
dstOffset0 = s_rescInternalInstance->m_dstOffsets[s_rescInternalInstance->m_bufIdFront];
|
||||
dstOffset1 = 0;
|
||||
}
|
||||
else {
|
||||
isMrt = true;
|
||||
dstOffset0 = s_rescInternalInstance->m_dstOffsets[s_rescInternalInstance->m_bufIdFront];
|
||||
dstOffset1 = s_rescInternalInstance->m_dstOffsets[s_rescInternalInstance->m_bufIdPalMidNow];
|
||||
}
|
||||
|
||||
GSLockCurrent lock(GS_LOCK_WAIT_FLUSH);
|
||||
GSRender& r = Emu.GetGSManager().GetRender();
|
||||
|
||||
r.m_surface_type = CELL_GCM_SURFACE_PITCH;
|
||||
r.m_surface_antialias = CELL_GCM_SURFACE_CENTER_1;
|
||||
r.m_surface_color_format = (u8)s_rescInternalInstance->m_pRescDsts->format;
|
||||
r.m_surface_colour_target = (!isMrt) ? CELL_GCM_SURFACE_TARGET_0 : CELL_GCM_SURFACE_TARGET_MRT1;
|
||||
//surface.colorLocation[0] = CELL_GCM_LOCATION_LOCAL;
|
||||
r.m_surface_offset_a = dstOffset0;
|
||||
r.m_surface_pitch_a = s_rescInternalInstance->m_dstPitch;
|
||||
//surface.colorLocation[1] = CELL_GCM_LOCATION_LOCAL;
|
||||
r.m_surface_offset_b = (!isMrt) ? 0 : dstOffset1;
|
||||
r.m_surface_pitch_b = (!isMrt) ? 64 : s_rescInternalInstance->m_dstPitch;
|
||||
//surface.colorLocation[2] = CELL_GCM_LOCATION_LOCAL;
|
||||
r.m_surface_offset_c = 0;
|
||||
r.m_surface_pitch_c = 64;
|
||||
//surface.colorLocation[3] = CELL_GCM_LOCATION_LOCAL;
|
||||
r.m_surface_offset_d = 0;
|
||||
r.m_surface_pitch_d = 64;
|
||||
r.m_surface_depth_format = CELL_GCM_SURFACE_Z24S8;
|
||||
//surface.depthLocation = CELL_GCM_LOCATION_LOCAL;
|
||||
r.m_surface_offset_z = 0;
|
||||
r.m_surface_pitch_z = 64;
|
||||
r.m_surface_width = s_rescInternalInstance->m_dstWidth;
|
||||
r.m_surface_height = s_rescInternalInstance->m_dstHeight;
|
||||
//surface.x = 0;
|
||||
//surface.y = 0;
|
||||
}
|
||||
|
||||
// Module Functions
|
||||
int cellRescInit(mem_ptr_t<CellRescInitConfig> initConfig)
|
||||
{
|
||||
@ -616,7 +739,7 @@ int cellRescAdjustAspectRatio(float horizontal, float vertical)
|
||||
s_rescInternalInstance->m_ratioAdjX = horizontal;
|
||||
s_rescInternalInstance->m_ratioAdjY = vertical;
|
||||
|
||||
if(s_rescInternalInstance->m_vertexArrayEA_addr)
|
||||
if(s_rescInternalInstance->m_vertexArrayEA)
|
||||
{
|
||||
if(IsTextureNR())
|
||||
BuildupVertexBufferNR();
|
||||
@ -789,8 +912,14 @@ int cellRescSetConvertAndFlip(mem_ptr_t<CellGcmContextData> cntxt, s32 idx)
|
||||
if(!IsTextureNR())
|
||||
BuildupVertexBufferUN(idx);
|
||||
|
||||
InitContext(cntxt);
|
||||
InitVertex(cntxt);
|
||||
// Setup GPU internal status
|
||||
SetupRsxRenderingStates(cntxt);
|
||||
|
||||
// Setup vertex array pointers
|
||||
SetupVertexArrays(cntxt);
|
||||
|
||||
// Setup surface
|
||||
SetupSurfaces(cntxt);
|
||||
|
||||
//TODO: ?
|
||||
|
||||
@ -831,12 +960,12 @@ int cellRescSetBufferAddress(mem32_t colorBuffers, mem32_t vertexArray, mem32_t
|
||||
return CELL_RESC_ERROR_BAD_ARGUMENT;
|
||||
}
|
||||
|
||||
s_rescInternalInstance->m_colorBuffersEA_addr = colorBuffers.GetAddr();
|
||||
s_rescInternalInstance->m_vertexArrayEA_addr = vertexArray.GetAddr();
|
||||
s_rescInternalInstance->m_fragmentUcodeEA_addr = fragmentShader.GetAddr();
|
||||
s_rescInternalInstance->m_colorBuffersEA = colorBuffers.GetAddr();
|
||||
s_rescInternalInstance->m_vertexArrayEA = vertexArray.GetAddr();
|
||||
s_rescInternalInstance->m_fragmentUcodeEA = fragmentShader.GetAddr();
|
||||
|
||||
MemoryAllocator<be_t<u32>> dstOffset;
|
||||
cellGcmAddressToOffset(s_rescInternalInstance->m_colorBuffersEA_addr, dstOffset.GetAddr());
|
||||
cellGcmAddressToOffset(s_rescInternalInstance->m_colorBuffersEA, dstOffset.GetAddr());
|
||||
|
||||
for(int i=0; i<GetNumColorBuffers(); i++)
|
||||
{
|
||||
@ -914,12 +1043,132 @@ void cellRescSetVBlankHandler(u32 handler_addr)
|
||||
Emu.GetGSManager().GetRender().m_vblank_handler.SetAddr(handler_addr);
|
||||
}
|
||||
|
||||
int cellRescCreateInterlaceTable()
|
||||
u16 FloatToHalf(float val)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellResc);
|
||||
u8 *tmp = (u8*)&val;
|
||||
u32 bits = ((u32)tmp[0] << 24) | ((u32)tmp[1] << 16) | ((u32)tmp[2] << 8) | (u32)tmp[3];
|
||||
|
||||
if (bits == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int32_t e = ((bits & 0x7f800000) >> 23) - 127 + 15;
|
||||
if (e < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (e > 31)
|
||||
{
|
||||
e = 31;
|
||||
}
|
||||
u32 s = bits & 0x80000000;
|
||||
u32 m = bits & 0x007fffff;
|
||||
|
||||
return ((s >> 16) & 0x8000) | ((e << 10) & 0x7c00) | ((m >> 13) & 0x03ff);
|
||||
}
|
||||
|
||||
static void blackman(float window[])
|
||||
{
|
||||
const float x0 = ((1.f * 2.f*M_PI) / 5.f) - M_PI;
|
||||
const float x1 = ((2.f * 2.f*M_PI) / 5.f) - M_PI;
|
||||
const float x2 = ((3.f * 2.f*M_PI) / 5.f) - M_PI;
|
||||
const float x3 = ((4.f * 2.f*M_PI) / 5.f) - M_PI;
|
||||
|
||||
const float a0 = 0.42f + (0.50f * cosf(x0)) + (0.08f * cosf(2.f*x0));
|
||||
const float a1 = 0.42f + (0.50f * cosf(x1)) + (0.08f * cosf(2.f*x1));
|
||||
const float a2 = 0.42f + (0.50f * cosf(x2)) + (0.08f * cosf(2.f*x2));
|
||||
const float a3 = 0.42f + (0.50f * cosf(x3)) + (0.08f * cosf(2.f*x3));
|
||||
|
||||
window[0] = ((100.f - SEVIRITY) / 100.f + SEVIRITY / 100.f*a0);
|
||||
window[1] = ((100.f - SEVIRITY) / 100.f + SEVIRITY / 100.f*a1);
|
||||
window[2] = ((100.f - SEVIRITY) / 100.f + SEVIRITY / 100.f*a2);
|
||||
window[3] = ((100.f - SEVIRITY) / 100.f + SEVIRITY / 100.f*a3);
|
||||
}
|
||||
|
||||
int CreateInterlaceTable(mem32_t ea, float srcH, float dstH, CellRescTableElement depth, int length)
|
||||
{
|
||||
float phi[4], transient[4], *buf32 = (float*)ea.GetAddr();
|
||||
float y_fraction;
|
||||
float bandwidth = 0.5f / (srcH / dstH);
|
||||
float phi_b = 2.f * M_PI * bandwidth;
|
||||
float window[4];
|
||||
u16 *buf16 = (u16*)ea.GetAddr();
|
||||
|
||||
blackman(window);
|
||||
|
||||
for (int i = 0; i<length; i++)
|
||||
{
|
||||
y_fraction = (float)i / (float)length;
|
||||
|
||||
phi[0] = phi_b * (-1.5f - y_fraction);
|
||||
phi[1] = phi_b * (-0.5f - y_fraction);
|
||||
phi[2] = phi_b * (0.5f - y_fraction);
|
||||
phi[3] = phi_b * (1.5f - y_fraction);
|
||||
|
||||
transient[0] = (fabsf(phi[0]) > 1E-10) ? (sinf(phi[0]) / phi[0] * window[0]) : window[0];
|
||||
transient[1] = (fabsf(phi[1]) > 1E-10) ? (sinf(phi[1]) / phi[1] * window[1]) : window[1];
|
||||
transient[2] = (fabsf(phi[2]) > 1E-10) ? (sinf(phi[2]) / phi[2] * window[2]) : window[2];
|
||||
transient[3] = (fabsf(phi[3]) > 1E-10) ? (sinf(phi[3]) / phi[3] * window[3]) : window[3];
|
||||
|
||||
float total4 = transient[0] + transient[1] + transient[2] + transient[3];
|
||||
|
||||
if (depth == CELL_RESC_ELEMENT_HALF)
|
||||
{
|
||||
buf16[0] = FloatToHalf(transient[0] / total4);
|
||||
buf16[1] = FloatToHalf(transient[1] / total4);
|
||||
buf16[2] = FloatToHalf(transient[2] / total4);
|
||||
buf16[3] = FloatToHalf(transient[3] / total4);
|
||||
buf16 += 4;
|
||||
}
|
||||
else {
|
||||
buf32[0] = transient[0] / total4;
|
||||
buf32[1] = transient[1] / total4;
|
||||
buf32[2] = transient[2] / total4;
|
||||
buf32[3] = transient[3] / total4;
|
||||
buf32 += 4;
|
||||
}
|
||||
}
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellRescCreateInterlaceTable(mem32_t ea, float srcH, CellRescTableElement depth, int length)
|
||||
{
|
||||
cellResc->Warning("cellRescCreateInterlaceTable(ea=0x%x, depth = %i, length = %i)", ea.GetAddr(), depth, length);
|
||||
|
||||
if (!s_rescInternalInstance->m_bInitialized)
|
||||
{
|
||||
cellResc->Error("cellRescCreateInterlaceTable : CELL_RESC_ERROR_NOT_INITIALIZED");
|
||||
return CELL_RESC_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if ((!ea.IsGood()) || (srcH <= 0.f) || (!(depth == CELL_RESC_ELEMENT_HALF || depth == CELL_RESC_ELEMENT_FLOAT)) || (length <= 0))
|
||||
{
|
||||
cellResc->Error("cellRescCreateInterlaceTable : CELL_RESC_ERROR_NOT_INITIALIZED");
|
||||
return CELL_RESC_ERROR_BAD_ARGUMENT;
|
||||
}
|
||||
|
||||
if (s_rescInternalInstance->m_dstHeight == 0)
|
||||
{
|
||||
cellResc->Error("cellRescCreateInterlaceTable : CELL_RESC_ERROR_BAD_COMBINATION");
|
||||
return CELL_RESC_ERROR_BAD_COMBINATION;
|
||||
}
|
||||
|
||||
float ratioModeCoefficient = (s_rescInternalInstance->m_initConfig.ratioMode != CELL_RESC_LETTERBOX) ? 1.f : (1.f - 2.f * XY_DELTA_LB);
|
||||
float dstH = s_rescInternalInstance->m_dstHeight * ratioModeCoefficient * s_rescInternalInstance->m_ratioAdjY;
|
||||
|
||||
if (int retValue = CreateInterlaceTable(ea, srcH, dstH, depth, length) == CELL_OK)
|
||||
{
|
||||
s_rescInternalInstance->m_interlaceTableEA = ea;
|
||||
s_rescInternalInstance->m_interlaceElement = depth;
|
||||
s_rescInternalInstance->m_interlaceTableLength = length;
|
||||
return CELL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return retValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void cellResc_init()
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user