mirror of https://github.com/inolen/redream.git
updated pvr_video_size to calculate internal resolution based on FB_R_SIZE
This commit is contained in:
parent
cdfbb58a6b
commit
e53b23c073
|
@ -48,6 +48,29 @@ static uint32_t VRAM64(uint32_t addr32) {
|
|||
memory is copied and passed to the client to render */
|
||||
#define PVR_FB_COOKIE 0xdeadbeef
|
||||
|
||||
static void pvr_framebuffer_size(struct pvr *pvr, int *width, int *height) {
|
||||
*width = pvr->FB_R_SIZE->x + 1;
|
||||
*height = pvr->FB_R_SIZE->y + 1;
|
||||
|
||||
/* FB_R_SIZE specifies x in 32-bit units, scale as necessary if framebuffer
|
||||
depth is less than 32-bit */
|
||||
switch (pvr->FB_R_CTRL->fb_depth) {
|
||||
case 0:
|
||||
case 1:
|
||||
*width *= 2;
|
||||
break;
|
||||
case 2:
|
||||
*width *= 4;
|
||||
*width /= 3;
|
||||
break;
|
||||
}
|
||||
|
||||
/* if interlacing, full framebuffer height is double */
|
||||
if (pvr->SPG_CONTROL->interlace) {
|
||||
*height *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
static int pvr_test_framebuffer(struct pvr *pvr, uint32_t addr) {
|
||||
uint32_t data = *(uint32_t *)&pvr->vram[VRAM64(addr)];
|
||||
return data != PVR_FB_COOKIE;
|
||||
|
@ -92,30 +115,20 @@ static int pvr_update_framebuffer(struct pvr *pvr) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* values in FB_R_SIZE are in 32-bit units */
|
||||
int line_mod = (pvr->FB_R_SIZE->mod << 2) - 4;
|
||||
int x_size = (pvr->FB_R_SIZE->x + 1) << 2;
|
||||
int y_size = (pvr->FB_R_SIZE->y + 1);
|
||||
|
||||
pvr->framebuffer_w = pvr->FB_R_SIZE->x + 1;
|
||||
pvr->framebuffer_h = pvr->FB_R_SIZE->y + 1;
|
||||
|
||||
/* final fb will be 2x height when interlacing */
|
||||
if (pvr->SPG_CONTROL->interlace) {
|
||||
pvr->framebuffer_h *= 2;
|
||||
}
|
||||
pvr_framebuffer_size(pvr, &pvr->framebuffer_w, &pvr->framebuffer_h);
|
||||
|
||||
/* convert framebuffer into a 24-bit RGB pixel buffer */
|
||||
uint8_t *dst = pvr->framebuffer;
|
||||
uint8_t *src = pvr->vram;
|
||||
|
||||
/* values in FB_R_SIZE are in 32-bit units */
|
||||
int line_mod = (pvr->FB_R_SIZE->mod << 2) - 4;
|
||||
int x_size = (pvr->FB_R_SIZE->x + 1) << 2;
|
||||
int y_size = (pvr->FB_R_SIZE->y + 1);
|
||||
|
||||
switch (pvr->FB_R_CTRL->fb_depth) {
|
||||
case 0:
|
||||
case 1: {
|
||||
/* FB_R_SIZE specifies x in 32-bit units, if the framebuffer is using a
|
||||
16-bit format this needs to be doubled */
|
||||
pvr->framebuffer_w *= 2;
|
||||
|
||||
for (int y = 0; y < y_size; y++) {
|
||||
for (int n = 0; n < num_fields; n++) {
|
||||
for (int x = 0; x < x_size; x += 2) {
|
||||
|
@ -274,11 +287,11 @@ static void pvr_reconfigure_spg(struct pvr *pvr) {
|
|||
}
|
||||
|
||||
LOG_INFO(
|
||||
"pvr_reconfigure_spg mode=%s pixel_clock=%d line_clock=%d vcount=%d "
|
||||
"hcount=%d interlace=%d vbstart=%d vbend=%d",
|
||||
mode, pixel_clock, pvr->line_clock, pvr->SPG_LOAD->vcount,
|
||||
pvr->SPG_LOAD->hcount, pvr->SPG_CONTROL->interlace,
|
||||
pvr->SPG_VBLANK->vbstart, pvr->SPG_VBLANK->vbend);
|
||||
"pvr_reconfigure_spg mode=%s interlace=%d pixel_clock=%d line_clock=%d "
|
||||
"hcount=%d hbstart=%d hbend=%d vcount=%d vbstart=%d vbend=%d",
|
||||
mode, pvr->SPG_CONTROL->interlace, pixel_clock, pvr->line_clock,
|
||||
pvr->SPG_LOAD->hcount, pvr->SPG_HBLANK->hbstart, pvr->SPG_HBLANK->hbend,
|
||||
pvr->SPG_LOAD->vcount, pvr->SPG_VBLANK->vbstart, pvr->SPG_VBLANK->vbend);
|
||||
|
||||
if (pvr->line_timer) {
|
||||
sched_cancel_timer(sched, pvr->line_timer);
|
||||
|
@ -361,37 +374,31 @@ uint32_t pvr_reg_read(struct pvr *pvr, uint32_t addr, uint32_t mask) {
|
|||
return pvr->reg[offset];
|
||||
}
|
||||
|
||||
void pvr_video_size(struct pvr *pvr, int *video_width, int *video_height) {
|
||||
int vga_mode = !pvr->SPG_CONTROL->NTSC && !pvr->SPG_CONTROL->PAL &&
|
||||
!pvr->SPG_CONTROL->interlace;
|
||||
void pvr_video_size(struct pvr *pvr, int *width, int *height) {
|
||||
/* calculate the original internal resolution used by the game based on the
|
||||
framebuffer size. this is used to scale the screen space x,y coordinates
|
||||
passed to the ta when rendering */
|
||||
pvr_framebuffer_size(pvr, width, height);
|
||||
|
||||
if (vga_mode) {
|
||||
*video_width = 640;
|
||||
*video_height = 480;
|
||||
} else {
|
||||
*video_width = 640;
|
||||
*video_height = 240;
|
||||
}
|
||||
|
||||
if (pvr->VO_CONTROL->pixel_double) {
|
||||
*video_width /= 2;
|
||||
}
|
||||
|
||||
if (pvr->SPG_CONTROL->interlace) {
|
||||
*video_height *= 2;
|
||||
}
|
||||
|
||||
/* scale_x signals to scale the framebuffer down by half. do so by scaling
|
||||
up the width used by the projection matrix */
|
||||
/* scale_x signals to scale down the accumulation buffer by half when copying
|
||||
to the framebuffer (providing horizontal fsaa), meaning the original video
|
||||
width is double the framebufffer width */
|
||||
if (pvr->SCALER_CTL->scale_x) {
|
||||
*video_width *= 2;
|
||||
*width *= 2;
|
||||
}
|
||||
|
||||
/* scale_y is a fixed-point scaler, with 6-bits in the integer and 10-bits
|
||||
in the decimal. this scale value is ignored when used for interlacing
|
||||
which is not emulated */
|
||||
if (!pvr->SCALER_CTL->interlace) {
|
||||
*video_height = (*video_height * pvr->SCALER_CTL->scale_y) >> 10;
|
||||
/* scale_y is a fixed-point scaler, with 6-bits in the integer and 10-bits in
|
||||
the decimal. the accumulation buffer is scaled by 1/scale_y, for example:
|
||||
0x200: 2.0x scale
|
||||
0x400: 1.0x scale
|
||||
0x800: 0.5x scale
|
||||
reversing this operation should give us the original video height */
|
||||
*height = (*height * pvr->SCALER_CTL->scale_y) >> 10;
|
||||
|
||||
/* if flicker-free type B interlacing is being used, scale the height back
|
||||
down, nullifying the effect of scale_y */
|
||||
if (pvr->SCALER_CTL->interlace) {
|
||||
*height /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ PVR_REG(0x005f80c4, SPG_TRIGGER_POS, 0x00000000, uint32_t)
|
|||
PVR_REG(0x005f80c8, SPG_HBLANK_INT, 0x031d0000, union spg_hblank_int)
|
||||
PVR_REG(0x005f80cc, SPG_VBLANK_INT, 0x01500104, union spg_vblank_int)
|
||||
PVR_REG(0x005f80d0, SPG_CONTROL, 0x00000000, union spg_control)
|
||||
PVR_REG(0x005f80d4, SPG_HBLANK, 0x007e0345, uint32_t)
|
||||
PVR_REG(0x005f80d4, SPG_HBLANK, 0x007e0345, union spg_hblank)
|
||||
PVR_REG(0x005f80d8, SPG_LOAD, 0x01060359, union spg_load)
|
||||
PVR_REG(0x005f80dc, SPG_VBLANK, 0x01500104, union spg_vblank)
|
||||
PVR_REG(0x005f80e0, SPG_WIDTH, 0x07f1933f, uint32_t)
|
||||
|
|
|
@ -11,7 +11,7 @@ union param_base {
|
|||
uint32_t full;
|
||||
struct {
|
||||
uint32_t base_address : 24;
|
||||
uint32_t reserved : 8;
|
||||
uint32_t : 8;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -58,7 +58,7 @@ union fpu_shad_scale {
|
|||
struct {
|
||||
uint32_t scale_factor : 8;
|
||||
uint32_t intensity_volume_mode : 1;
|
||||
uint32_t reserved : 23;
|
||||
uint32_t : 23;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -69,7 +69,7 @@ union fpu_param_cfg {
|
|||
uint32_t ptr_burst_size : 4;
|
||||
uint32_t isp_burst_threshold : 6;
|
||||
uint32_t tsp_burst_threshold : 6;
|
||||
uint32_t reserved : 1;
|
||||
uint32_t : 1;
|
||||
uint32_t region_header_type : 1;
|
||||
uint32_t reserved1 : 10;
|
||||
};
|
||||
|
@ -90,7 +90,7 @@ union isp_feed_cfg {
|
|||
uint32_t full;
|
||||
struct {
|
||||
uint32_t presort : 1;
|
||||
uint32_t reserved : 2;
|
||||
uint32_t : 2;
|
||||
uint32_t discard : 1;
|
||||
uint32_t punch_size : 10;
|
||||
uint32_t cache_size : 10;
|
||||
|
@ -102,9 +102,9 @@ union spg_hblank_int {
|
|||
uint32_t full;
|
||||
struct {
|
||||
uint32_t line_comp_val : 10;
|
||||
uint32_t reserved : 2;
|
||||
uint32_t : 2;
|
||||
uint32_t hblank_int_mode : 2;
|
||||
uint32_t reserved2 : 2;
|
||||
uint32_t : 2;
|
||||
uint32_t hblank_in_interrupt : 10;
|
||||
uint32_t reserved3 : 6;
|
||||
};
|
||||
|
@ -114,9 +114,9 @@ union spg_vblank_int {
|
|||
uint32_t full;
|
||||
struct {
|
||||
uint32_t vblank_in_line_number : 10;
|
||||
uint32_t reserved : 6;
|
||||
uint32_t : 6;
|
||||
uint32_t vblank_out_line_number : 10;
|
||||
uint32_t reserved2 : 6;
|
||||
uint32_t : 6;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -133,7 +133,7 @@ union spg_control {
|
|||
uint32_t PAL : 1;
|
||||
uint32_t sync_direction : 1;
|
||||
uint32_t csync_on_h : 1;
|
||||
uint32_t reserved : 22;
|
||||
uint32_t : 22;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -141,9 +141,19 @@ union spg_load {
|
|||
uint32_t full;
|
||||
struct {
|
||||
uint32_t hcount : 10;
|
||||
uint32_t reserved : 6;
|
||||
uint32_t : 6;
|
||||
uint32_t vcount : 10;
|
||||
uint32_t reserved2 : 6;
|
||||
uint32_t : 6;
|
||||
};
|
||||
};
|
||||
|
||||
union spg_hblank {
|
||||
uint32_t full;
|
||||
struct {
|
||||
uint32_t hbstart : 10;
|
||||
uint32_t : 6;
|
||||
uint32_t hbend : 10;
|
||||
uint32_t : 6;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -151,9 +161,9 @@ union spg_vblank {
|
|||
uint32_t full;
|
||||
struct {
|
||||
uint32_t vbstart : 10;
|
||||
uint32_t reserved : 6;
|
||||
uint32_t : 6;
|
||||
uint32_t vbend : 10;
|
||||
uint32_t reserved2 : 6;
|
||||
uint32_t : 6;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -161,9 +171,9 @@ union text_control {
|
|||
uint32_t full;
|
||||
struct {
|
||||
uint32_t stride : 5;
|
||||
uint32_t reserved : 3;
|
||||
uint32_t : 3;
|
||||
uint32_t bankbit : 5;
|
||||
uint32_t reserved2 : 3;
|
||||
uint32_t : 3;
|
||||
uint32_t index_endian : 1;
|
||||
uint32_t codebook_endian : 1;
|
||||
uint32_t reserved3 : 14;
|
||||
|
@ -212,7 +222,7 @@ union spg_status {
|
|||
uint32_t blank : 1;
|
||||
uint32_t hsync : 1;
|
||||
uint32_t vsync : 1;
|
||||
uint32_t reserved : 18;
|
||||
uint32_t : 18;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -228,7 +238,7 @@ union ta_isp_base {
|
|||
uint32_t full;
|
||||
struct {
|
||||
uint32_t base_address : 24;
|
||||
uint32_t reserved : 8;
|
||||
uint32_t : 8;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -236,7 +246,7 @@ union ta_yuv_tex_base {
|
|||
uint32_t full;
|
||||
struct {
|
||||
uint32_t base_address : 24;
|
||||
uint32_t reserved : 8;
|
||||
uint32_t : 8;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue