nv2a: Handle zero sized surfaces

This commit is contained in:
Erik Abair
2026-01-14 21:17:54 -08:00
committed by GitHub
parent 3c8f99e3c2
commit 973e7f9f31
5 changed files with 46 additions and 12 deletions

View File

@ -378,7 +378,7 @@ void pgraph_gl_sync(NV2AState *d)
d->vga.get_params(&d->vga, &vga_display_params);
SurfaceBinding *surface = pgraph_gl_surface_get_within(d, d->pcrtc.start + vga_display_params.line_offset);
if (surface == NULL || !surface->color) {
if (surface == NULL || !surface->color || !surface->width || !surface->height) {
qemu_event_set(&d->pgraph.sync_complete);
return;
}

View File

@ -469,9 +469,13 @@ static void surface_access_callback(void *opaque, MemoryRegion *mr, hwaddr addr,
static void register_cpu_access_callback(NV2AState *d, SurfaceBinding *surface)
{
if (tcg_enabled()) {
surface->access_cb = mem_access_callback_insert(
qemu_get_cpu(0), d->vram, surface->vram_addr, surface->size,
&surface_access_callback, d);
if (surface->width && surface->height) {
surface->access_cb = mem_access_callback_insert(
qemu_get_cpu(0), d->vram, surface->vram_addr, surface->size,
&surface_access_callback, d);
} else {
surface->access_cb = NULL;
}
}
}
@ -684,6 +688,10 @@ static void surface_download_to_buffer(NV2AState *d, SurfaceBinding *surface,
swizzle &= surface->swizzle;
downscale &= (pg->surface_scale_factor != 1);
if (!surface->width || !surface->height) {
return;
}
trace_nv2a_pgraph_surface_download(
surface->color ? "COLOR" : "ZETA",
surface->swizzle ? "sz" : "lin", surface->vram_addr,
@ -756,7 +764,8 @@ static void surface_download_to_buffer(NV2AState *d, SurfaceBinding *surface,
static void surface_download(NV2AState *d, SurfaceBinding *surface, bool force)
{
if (!(surface->download_pending || force)) {
if (!(surface->download_pending || force) || !surface->width ||
!surface->height) {
return;
}
@ -877,6 +886,10 @@ void pgraph_gl_upload_surface_data(NV2AState *d, SurfaceBinding *surface,
surface->upload_pending = false;
surface->draw_time = pg->draw_time;
if (!surface->width || !surface->height) {
return;
}
// FIXME: Don't query GL for texture binding
GLint last_texture_binding;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture_binding);
@ -1209,7 +1222,8 @@ static void update_surface_part(NV2AState *d, bool upload, bool color)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
unsigned int width = entry.width, height = entry.height;
unsigned int width = entry.width ? entry.width : 1;
unsigned int height = entry.height ? entry.height : 1;
pgraph_apply_scaling_factor(pg, &width, &height);
glTexImage2D(GL_TEXTURE_2D, 0, entry.fmt.gl_internal_format, width,
height, 0, entry.fmt.gl_format, entry.fmt.gl_type,

View File

@ -1069,7 +1069,8 @@ void pgraph_vk_render_display(PGRAPHState *pg)
SurfaceBinding *surface = pgraph_vk_surface_get_within(
d, d->pcrtc.start + vga_display_params.line_offset);
if (surface == NULL || !surface->color) {
if (surface == NULL || !surface->color || !surface->width ||
!surface->height) {
return;
}

View File

@ -150,6 +150,10 @@ static void download_surface_to_buffer(NV2AState *d, SurfaceBinding *surface,
PGRAPHState *pg = &d->pgraph;
PGRAPHVkState *r = pg->vk_renderer_state;
if (!surface->width || !surface->height) {
return;
}
nv2a_profile_inc_counter(NV2A_PROF_SURF_DOWNLOAD);
bool use_compute_to_convert_depth_stencil_format =
@ -469,7 +473,8 @@ static void download_surface_to_buffer(NV2AState *d, SurfaceBinding *surface,
static void download_surface(NV2AState *d, SurfaceBinding *surface, bool force)
{
if (!(surface->download_pending || force)) {
if (!(surface->download_pending || force) || !surface->width ||
!surface->height) {
return;
}
@ -577,9 +582,13 @@ static void surface_access_callback(void *opaque, MemoryRegion *mr, hwaddr addr,
static void register_cpu_access_callback(NV2AState *d, SurfaceBinding *surface)
{
if (tcg_enabled()) {
surface->access_cb = mem_access_callback_insert(
qemu_get_cpu(0), d->vram, surface->vram_addr, surface->size,
&surface_access_callback, d);
if (surface->width && surface->height) {
surface->access_cb = mem_access_callback_insert(
qemu_get_cpu(0), d->vram, surface->vram_addr, surface->size,
&surface_access_callback, d);
} else {
surface->access_cb = NULL;
}
}
}
@ -754,7 +763,8 @@ static void create_surface_image(PGRAPHState *pg, SurfaceBinding *surface)
{
PGRAPHVkState *r = pg->vk_renderer_state;
unsigned int width = surface->width, height = surface->height;
unsigned int width = surface->width ? surface->width : 1;
unsigned int height = surface->height ? surface->height : 1;
pgraph_apply_scaling_factor(pg, &width, &height);
assert(!surface->image);
@ -956,6 +966,11 @@ void pgraph_vk_upload_surface_data(NV2AState *d, SurfaceBinding *surface,
surface->upload_pending = false;
surface->draw_time = pg->draw_time;
if (!surface->width || !surface->height) {
surface->initialized = true;
return;
}
uint8_t *data = d->vram_ptr;
uint8_t *buf = data + surface->vram_addr;

View File

@ -877,6 +877,10 @@ static void do_mem_access_callback_remove_by_ref(CPUState *cpu,
void mem_access_callback_remove_by_ref(CPUState *cpu, MemAccessCallback *cb)
{
if (!cb) {
return;
}
async_safe_run_on_cpu(cpu, do_mem_access_callback_remove_by_ref,
RUN_ON_CPU_HOST_PTR(cb));