diff --git a/hw/xbox/nv2a/pgraph/gl/display.c b/hw/xbox/nv2a/pgraph/gl/display.c index fd324b2901..fafcd72061 100644 --- a/hw/xbox/nv2a/pgraph/gl/display.c +++ b/hw/xbox/nv2a/pgraph/gl/display.c @@ -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; } diff --git a/hw/xbox/nv2a/pgraph/gl/surface.c b/hw/xbox/nv2a/pgraph/gl/surface.c index 1adfbd9ac4..714121e6bd 100644 --- a/hw/xbox/nv2a/pgraph/gl/surface.c +++ b/hw/xbox/nv2a/pgraph/gl/surface.c @@ -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, diff --git a/hw/xbox/nv2a/pgraph/vk/display.c b/hw/xbox/nv2a/pgraph/vk/display.c index 6efb13e248..6b9e5851c4 100644 --- a/hw/xbox/nv2a/pgraph/vk/display.c +++ b/hw/xbox/nv2a/pgraph/vk/display.c @@ -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; } diff --git a/hw/xbox/nv2a/pgraph/vk/surface.c b/hw/xbox/nv2a/pgraph/vk/surface.c index d4f9a74871..f59c689251 100644 --- a/hw/xbox/nv2a/pgraph/vk/surface.c +++ b/hw/xbox/nv2a/pgraph/vk/surface.c @@ -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; diff --git a/system/physmem.c b/system/physmem.c index 035284d27d..fb9a1b33e5 100644 --- a/system/physmem.c +++ b/system/physmem.c @@ -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));