@@ -111,6 +111,7 @@ static void pgraph_gl_process_pending(NV2AState *d)
111111
112112 if (qatomic_read (& r -> downloads_pending ) ||
113113 qatomic_read (& r -> download_dirty_surfaces_pending ) ||
114+ qatomic_read (& r -> download_dirty_surfaces_in_range_pending ) ||
114115 qatomic_read (& d -> pgraph .sync_pending ) ||
115116 qatomic_read (& d -> pgraph .flush_pending ) ||
116117 qatomic_read (& r -> shader_cache_writeback_pending )) {
@@ -122,6 +123,13 @@ static void pgraph_gl_process_pending(NV2AState *d)
122123 if (qatomic_read (& r -> download_dirty_surfaces_pending )) {
123124 pgraph_gl_download_dirty_surfaces (d );
124125 }
126+ if (qatomic_read (& r -> download_dirty_surfaces_in_range_pending )) {
127+ pgraph_gl_download_surfaces_in_range_if_dirty (
128+ d , r -> download_dirty_surfaces_in_range_start ,
129+ r -> download_dirty_surfaces_in_range_size );
130+ qatomic_set (& r -> download_dirty_surfaces_in_range_pending , false);
131+ qemu_event_set (& r -> dirty_surfaces_download_complete );
132+ }
125133 if (qatomic_read (& d -> pgraph .sync_pending )) {
126134 pgraph_gl_sync (d );
127135 }
@@ -153,6 +161,46 @@ static void pgraph_gl_pre_savevm_wait(NV2AState *d)
153161 qemu_event_wait (& r -> dirty_surfaces_download_complete );
154162}
155163
164+ static bool pgraph_gl_have_overlapping_dirty_surfaces (NV2AState * d ,
165+ hwaddr start , hwaddr size )
166+ {
167+ PGRAPHState * pg = & d -> pgraph ;
168+ PGRAPHGLState * r = pg -> gl_renderer_state ;
169+
170+ SurfaceBinding * surface ;
171+
172+ hwaddr end = start + size - 1 ;
173+
174+ QTAILQ_FOREACH (surface , & r -> surfaces , entry ) {
175+ hwaddr surf_end = surface -> vram_addr + surface -> size - 1 ;
176+ bool overlapping = !(surface -> vram_addr >= end || start >= surf_end );
177+ if (overlapping && surface -> draw_dirty ) {
178+ return true;
179+ }
180+ }
181+
182+ return false;
183+ }
184+
185+ static void pgraph_gl_download_overlapping_surfaces_trigger (NV2AState * d ,
186+ hwaddr start ,
187+ hwaddr size )
188+ {
189+ PGRAPHState * pg = & d -> pgraph ;
190+ PGRAPHGLState * r = pg -> gl_renderer_state ;
191+
192+ r -> download_dirty_surfaces_in_range_start = start ;
193+ r -> download_dirty_surfaces_in_range_size = size ;
194+ qemu_event_reset (& r -> dirty_surfaces_download_complete );
195+ qatomic_set (& r -> download_dirty_surfaces_in_range_pending , true);
196+ }
197+
198+ static void pgraph_gl_download_overlapping_surfaces_wait (NV2AState * d )
199+ {
200+ qemu_event_wait (
201+ & d -> pgraph .gl_renderer_state -> dirty_surfaces_download_complete );
202+ }
203+
156204static void pgraph_gl_pre_shutdown_trigger (NV2AState * d )
157205{
158206 PGRAPHState * pg = & d -> pgraph ;
@@ -170,33 +218,45 @@ static void pgraph_gl_pre_shutdown_wait(NV2AState *d)
170218 qemu_event_wait (& r -> shader_cache_writeback_complete );
171219}
172220
173- static PGRAPHRenderer pgraph_gl_renderer = {
174- .type = CONFIG_DISPLAY_RENDERER_OPENGL ,
175- .name = "OpenGL" ,
176- .ops = {
177- .init = pgraph_gl_init ,
178- .early_context_init = early_context_init ,
179- .finalize = pgraph_gl_finalize ,
180- .clear_report_value = pgraph_gl_clear_report_value ,
181- .clear_surface = pgraph_gl_clear_surface ,
182- .draw_begin = pgraph_gl_draw_begin ,
183- .draw_end = pgraph_gl_draw_end ,
184- .flip_stall = pgraph_gl_flip_stall ,
185- .flush_draw = pgraph_gl_flush_draw ,
186- .get_report = pgraph_gl_get_report ,
187- .image_blit = pgraph_gl_image_blit ,
188- .pre_savevm_trigger = pgraph_gl_pre_savevm_trigger ,
189- .pre_savevm_wait = pgraph_gl_pre_savevm_wait ,
190- .pre_shutdown_trigger = pgraph_gl_pre_shutdown_trigger ,
191- .pre_shutdown_wait = pgraph_gl_pre_shutdown_wait ,
192- .process_pending = pgraph_gl_process_pending ,
193- .process_pending_reports = pgraph_gl_process_pending_reports ,
194- .surface_update = pgraph_gl_surface_update ,
195- .set_surface_scale_factor = pgraph_gl_set_surface_scale_factor ,
196- .get_surface_scale_factor = pgraph_gl_get_surface_scale_factor ,
197- .get_framebuffer_surface = pgraph_gl_get_framebuffer_surface ,
198- }
199- };
221+ static PGRAPHRenderer
222+ pgraph_gl_renderer = { .type = CONFIG_DISPLAY_RENDERER_OPENGL ,
223+ .name = "OpenGL" ,
224+ .ops = {
225+ .init = pgraph_gl_init ,
226+ .early_context_init = early_context_init ,
227+ .finalize = pgraph_gl_finalize ,
228+ .clear_report_value =
229+ pgraph_gl_clear_report_value ,
230+ .clear_surface = pgraph_gl_clear_surface ,
231+ .draw_begin = pgraph_gl_draw_begin ,
232+ .draw_end = pgraph_gl_draw_end ,
233+ .flip_stall = pgraph_gl_flip_stall ,
234+ .flush_draw = pgraph_gl_flush_draw ,
235+ .get_report = pgraph_gl_get_report ,
236+ .image_blit = pgraph_gl_image_blit ,
237+ .pre_savevm_trigger =
238+ pgraph_gl_pre_savevm_trigger ,
239+ .pre_savevm_wait = pgraph_gl_pre_savevm_wait ,
240+ .pre_shutdown_trigger =
241+ pgraph_gl_pre_shutdown_trigger ,
242+ .pre_shutdown_wait = pgraph_gl_pre_shutdown_wait ,
243+ .process_pending = pgraph_gl_process_pending ,
244+ .process_pending_reports =
245+ pgraph_gl_process_pending_reports ,
246+ .surface_update = pgraph_gl_surface_update ,
247+ .have_overlapping_dirty_surfaces =
248+ pgraph_gl_have_overlapping_dirty_surfaces ,
249+ .download_overlapping_surfaces_trigger =
250+ pgraph_gl_download_overlapping_surfaces_trigger ,
251+ .download_overlapping_surfaces_wait =
252+ pgraph_gl_download_overlapping_surfaces_wait ,
253+ .set_surface_scale_factor =
254+ pgraph_gl_set_surface_scale_factor ,
255+ .get_surface_scale_factor =
256+ pgraph_gl_get_surface_scale_factor ,
257+ .get_framebuffer_surface =
258+ pgraph_gl_get_framebuffer_surface ,
259+ } };
200260
201261static void __attribute__((constructor )) register_renderer (void )
202262{
0 commit comments