mirror of https://github.com/xemu-project/xemu.git
nv2a: Handle SIZE_IN > SIZE_OUT case
`NV_PVIDEO_SIZE_IN` is set to 0xFFFFFFFF during initialization and teardown of the PVIDEO overlay. In some cases this can happen before the overlay is explicitly stopped, leading to an assert. On hardware SIZE_IN values larger than SIZE_OUT are capped (content is not scaled). Fixes #330 [Test](https://github.com/abaire/nxdk_pgraph_tests/blob/main/src/tests/pvideo_tests.cpp)
This commit is contained in:
parent
8d274e5f9a
commit
a675666051
|
@ -278,6 +278,7 @@ static void nv2a_reset(NV2AState *d)
|
|||
|
||||
memset(d->pfifo.regs, 0, sizeof(d->pfifo.regs));
|
||||
memset(d->pgraph.regs, 0, sizeof(d->pgraph.regs));
|
||||
memset(d->pvideo.regs, 0, sizeof(d->pvideo.regs));
|
||||
|
||||
d->pcrtc.start = 0;
|
||||
d->pramdac.core_clock_coeff = 0x00011C01; /* 189MHz...? */
|
||||
|
|
|
@ -5054,8 +5054,9 @@ static uint8_t *convert_texture_data__CR8YB8CB8YA8(const uint8_t *data,
|
|||
int x, y;
|
||||
for (y = 0; y < height; y++) {
|
||||
const uint8_t *line = &data[y * pitch];
|
||||
const uint32_t row_offset = y * width;
|
||||
for (x = 0; x < width; x++) {
|
||||
uint8_t *pixel = &converted_data[(y * width + x) * 4];
|
||||
uint8_t *pixel = &converted_data[(row_offset + x) * 4];
|
||||
convert_yuy2_to_rgb(line, x, &pixel[0], &pixel[1], &pixel[2]);
|
||||
pixel[3] = 255;
|
||||
}
|
||||
|
@ -5093,14 +5094,25 @@ static void pgraph_render_display_pvideo_overlay(NV2AState *d)
|
|||
int in_color =
|
||||
GET_MASK(d->pvideo.regs[NV_PVIDEO_FORMAT], NV_PVIDEO_FORMAT_COLOR);
|
||||
|
||||
/* TODO: support other color formats */
|
||||
assert(in_color == NV_PVIDEO_FORMAT_COLOR_LE_CR8YB8CB8YA8);
|
||||
assert(in_pitch >= in_width * 2);
|
||||
|
||||
unsigned int out_width =
|
||||
GET_MASK(d->pvideo.regs[NV_PVIDEO_SIZE_OUT], NV_PVIDEO_SIZE_OUT_WIDTH);
|
||||
unsigned int out_height =
|
||||
GET_MASK(d->pvideo.regs[NV_PVIDEO_SIZE_OUT], NV_PVIDEO_SIZE_OUT_HEIGHT);
|
||||
|
||||
// On HW, setting NV_PVIDEO_SIZE_IN larger than NV_PVIDEO_SIZE_OUT results
|
||||
// in them being capped to the output size, content is not scaled. This is
|
||||
// particularly important as NV_PVIDEO_SIZE_IN may be set to 0xFFFFFFFF
|
||||
// during initialization or teardown.
|
||||
if (in_width > out_width) {
|
||||
in_width = out_width;
|
||||
}
|
||||
if (in_height > out_height) {
|
||||
in_height = out_height;
|
||||
}
|
||||
|
||||
/* TODO: support other color formats */
|
||||
assert(in_color == NV_PVIDEO_FORMAT_COLOR_LE_CR8YB8CB8YA8);
|
||||
|
||||
unsigned int out_x =
|
||||
GET_MASK(d->pvideo.regs[NV_PVIDEO_POINT_OUT], NV_PVIDEO_POINT_OUT_X);
|
||||
unsigned int out_y =
|
||||
|
|
Loading…
Reference in New Issue