void vc4_flush(struct pipe_context *pctx) { struct vc4_context *vc4 = vc4_context(pctx); if (!vc4->needs_flush) return; /* The RCL setup would choke if the draw bounds cause no drawing, so * just drop the drawing if that's the case. */ if (vc4->draw_max_x <= vc4->draw_min_x || vc4->draw_max_y <= vc4->draw_min_y) { vc4_job_reset(vc4); return; } /* Increment the semaphore indicating that binning is done and * unblocking the render thread. Note that this doesn't act until the * FLUSH completes. */ cl_ensure_space(&vc4->bcl, 8); cl_u8(&vc4->bcl, VC4_PACKET_INCREMENT_SEMAPHORE); /* The FLUSH caps all of our bin lists with a VC4_PACKET_RETURN. */ cl_u8(&vc4->bcl, VC4_PACKET_FLUSH); vc4_setup_rcl(vc4); vc4_job_submit(vc4); }
void vc4_flush(struct pipe_context *pctx) { struct vc4_context *vc4 = vc4_context(pctx); struct pipe_surface *cbuf = vc4->framebuffer.cbufs[0]; struct pipe_surface *zsbuf = vc4->framebuffer.zsbuf; if (!vc4->needs_flush) return; /* The RCL setup would choke if the draw bounds cause no drawing, so * just drop the drawing if that's the case. */ if (vc4->draw_max_x <= vc4->draw_min_x || vc4->draw_max_y <= vc4->draw_min_y) { vc4_job_reset(vc4); return; } /* Increment the semaphore indicating that binning is done and * unblocking the render thread. Note that this doesn't act until the * FLUSH completes. */ cl_ensure_space(&vc4->bcl, 8); struct vc4_cl_out *bcl = cl_start(&vc4->bcl); cl_u8(&bcl, VC4_PACKET_INCREMENT_SEMAPHORE); /* The FLUSH caps all of our bin lists with a VC4_PACKET_RETURN. */ cl_u8(&bcl, VC4_PACKET_FLUSH); cl_end(&vc4->bcl, bcl); if (cbuf && (vc4->resolve & PIPE_CLEAR_COLOR0)) { pipe_surface_reference(&vc4->color_write, cbuf); if (!(vc4->cleared & PIPE_CLEAR_COLOR0)) { pipe_surface_reference(&vc4->color_read, cbuf); } else { pipe_surface_reference(&vc4->color_read, NULL); } } else { pipe_surface_reference(&vc4->color_write, NULL); pipe_surface_reference(&vc4->color_read, NULL); } if (vc4->framebuffer.zsbuf && (vc4->resolve & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL))) { pipe_surface_reference(&vc4->zs_write, zsbuf); if (!(vc4->cleared & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL))) { pipe_surface_reference(&vc4->zs_read, zsbuf); } else { pipe_surface_reference(&vc4->zs_read, NULL); } } else { pipe_surface_reference(&vc4->zs_write, NULL); pipe_surface_reference(&vc4->zs_read, NULL); } vc4_job_submit(vc4); }
void vc4_job_init(struct vc4_context *vc4) { vc4_init_cl(vc4, &vc4->bcl); vc4_init_cl(vc4, &vc4->shader_rec); vc4_init_cl(vc4, &vc4->uniforms); vc4_init_cl(vc4, &vc4->bo_handles); vc4_init_cl(vc4, &vc4->bo_pointers); vc4_job_reset(vc4); }
/** * Submits the job to the kernel and then reinitializes it. */ void vc4_job_submit(struct vc4_context *vc4) { if (vc4_debug & VC4_DEBUG_CL) { fprintf(stderr, "BCL:\n"); vc4_dump_cl(vc4->bcl.base, vc4->bcl.next - vc4->bcl.base, false); fprintf(stderr, "RCL:\n"); vc4_dump_cl(vc4->rcl.base, vc4->rcl.next - vc4->rcl.base, true); } struct drm_vc4_submit_cl submit; memset(&submit, 0, sizeof(submit)); submit.bo_handles = (uintptr_t)vc4->bo_handles.base; submit.bo_handle_count = (vc4->bo_handles.next - vc4->bo_handles.base) / 4; submit.bin_cl = (uintptr_t)vc4->bcl.base; submit.bin_cl_size = vc4->bcl.next - vc4->bcl.base; submit.render_cl = (uintptr_t)vc4->rcl.base; submit.render_cl_size = vc4->rcl.next - vc4->rcl.base; submit.shader_rec = (uintptr_t)vc4->shader_rec.base; submit.shader_rec_size = vc4->shader_rec.next - vc4->shader_rec.base; submit.shader_rec_count = vc4->shader_rec_count; submit.uniforms = (uintptr_t)vc4->uniforms.base; submit.uniforms_size = vc4->uniforms.next - vc4->uniforms.base; if (!(vc4_debug & VC4_DEBUG_NORAST)) { int ret; #ifndef USE_VC4_SIMULATOR ret = drmIoctl(vc4->fd, DRM_IOCTL_VC4_SUBMIT_CL, &submit); #else ret = vc4_simulator_flush(vc4, &submit); #endif if (ret) { fprintf(stderr, "VC4 submit failed\n"); abort(); } } vc4->last_emit_seqno = submit.seqno; if (vc4_debug & VC4_DEBUG_ALWAYS_SYNC) { if (!vc4_wait_seqno(vc4->screen, vc4->last_emit_seqno, PIPE_TIMEOUT_INFINITE)) { fprintf(stderr, "Wait failed.\n"); abort(); } } vc4_job_reset(vc4); }
/** * Submits the job to the kernel and then reinitializes it. */ void vc4_job_submit(struct vc4_context *vc4) { if (vc4_debug & VC4_DEBUG_CL) { fprintf(stderr, "BCL:\n"); vc4_dump_cl(vc4->bcl.base, cl_offset(&vc4->bcl), false); } struct drm_vc4_submit_cl submit; memset(&submit, 0, sizeof(submit)); cl_ensure_space(&vc4->bo_handles, 6 * sizeof(uint32_t)); cl_ensure_space(&vc4->bo_pointers, 6 * sizeof(struct vc4_bo *)); vc4_submit_setup_rcl_surface(vc4, &submit.color_read, vc4->color_read, false, false); vc4_submit_setup_rcl_render_config_surface(vc4, &submit.color_write, vc4->color_write); vc4_submit_setup_rcl_surface(vc4, &submit.zs_read, vc4->zs_read, true, false); vc4_submit_setup_rcl_surface(vc4, &submit.zs_write, vc4->zs_write, true, true); vc4_submit_setup_rcl_msaa_surface(vc4, &submit.msaa_color_write, vc4->msaa_color_write); vc4_submit_setup_rcl_msaa_surface(vc4, &submit.msaa_zs_write, vc4->msaa_zs_write); if (vc4->msaa) { /* This bit controls how many pixels the general * (i.e. subsampled) loads/stores are iterating over * (multisample loads replicate out to the other samples). */ submit.color_write.bits |= VC4_RENDER_CONFIG_MS_MODE_4X; /* Controls whether color_write's * VC4_PACKET_STORE_MS_TILE_BUFFER does 4x decimation */ submit.color_write.bits |= VC4_RENDER_CONFIG_DECIMATE_MODE_4X; } submit.bo_handles = (uintptr_t)vc4->bo_handles.base; submit.bo_handle_count = cl_offset(&vc4->bo_handles) / 4; submit.bin_cl = (uintptr_t)vc4->bcl.base; submit.bin_cl_size = cl_offset(&vc4->bcl); submit.shader_rec = (uintptr_t)vc4->shader_rec.base; submit.shader_rec_size = cl_offset(&vc4->shader_rec); submit.shader_rec_count = vc4->shader_rec_count; submit.uniforms = (uintptr_t)vc4->uniforms.base; submit.uniforms_size = cl_offset(&vc4->uniforms); assert(vc4->draw_min_x != ~0 && vc4->draw_min_y != ~0); submit.min_x_tile = vc4->draw_min_x / vc4->tile_width; submit.min_y_tile = vc4->draw_min_y / vc4->tile_height; submit.max_x_tile = (vc4->draw_max_x - 1) / vc4->tile_width; submit.max_y_tile = (vc4->draw_max_y - 1) / vc4->tile_height; submit.width = vc4->draw_width; submit.height = vc4->draw_height; if (vc4->cleared) { submit.flags |= VC4_SUBMIT_CL_USE_CLEAR_COLOR; submit.clear_color[0] = vc4->clear_color[0]; submit.clear_color[1] = vc4->clear_color[1]; submit.clear_z = vc4->clear_depth; submit.clear_s = vc4->clear_stencil; } if (!(vc4_debug & VC4_DEBUG_NORAST)) { int ret; #ifndef USE_VC4_SIMULATOR ret = drmIoctl(vc4->fd, DRM_IOCTL_VC4_SUBMIT_CL, &submit); #else ret = vc4_simulator_flush(vc4, &submit); #endif static bool warned = false; if (ret && !warned) { fprintf(stderr, "Draw call returned %s. " "Expect corruption.\n", strerror(errno)); warned = true; } } vc4->last_emit_seqno = submit.seqno; if (vc4_debug & VC4_DEBUG_ALWAYS_SYNC) { if (!vc4_wait_seqno(vc4->screen, vc4->last_emit_seqno, PIPE_TIMEOUT_INFINITE, "sync")) { fprintf(stderr, "Wait failed.\n"); abort(); } } vc4_job_reset(vc4); }
/** * Submits the job to the kernel and then reinitializes it. */ void vc4_job_submit(struct vc4_context *vc4) { if (vc4_debug & VC4_DEBUG_CL) { fprintf(stderr, "BCL:\n"); vc4_dump_cl(vc4->bcl.base, cl_offset(&vc4->bcl), false); } struct drm_vc4_submit_cl submit; memset(&submit, 0, sizeof(submit)); cl_ensure_space(&vc4->bo_handles, 4 * sizeof(uint32_t)); cl_ensure_space(&vc4->bo_pointers, 4 * sizeof(struct vc4_bo *)); vc4_submit_setup_rcl_surface(vc4, &submit.color_read, vc4->color_read, false, false); vc4_submit_setup_ms_rcl_surface(vc4, &submit.color_ms_write, vc4->color_write); vc4_submit_setup_rcl_surface(vc4, &submit.zs_read, vc4->zs_read, true, false); vc4_submit_setup_rcl_surface(vc4, &submit.zs_write, vc4->zs_write, true, true); submit.bo_handles = (uintptr_t)vc4->bo_handles.base; submit.bo_handle_count = cl_offset(&vc4->bo_handles) / 4; submit.bin_cl = (uintptr_t)vc4->bcl.base; submit.bin_cl_size = cl_offset(&vc4->bcl); submit.shader_rec = (uintptr_t)vc4->shader_rec.base; submit.shader_rec_size = cl_offset(&vc4->shader_rec); submit.shader_rec_count = vc4->shader_rec_count; submit.uniforms = (uintptr_t)vc4->uniforms.base; submit.uniforms_size = cl_offset(&vc4->uniforms); assert(vc4->draw_min_x != ~0 && vc4->draw_min_y != ~0); submit.min_x_tile = vc4->draw_min_x / 64; submit.min_y_tile = vc4->draw_min_y / 64; submit.max_x_tile = (vc4->draw_max_x - 1) / 64; submit.max_y_tile = (vc4->draw_max_y - 1) / 64; submit.width = vc4->draw_width; submit.height = vc4->draw_height; if (vc4->cleared) { submit.flags |= VC4_SUBMIT_CL_USE_CLEAR_COLOR; submit.clear_color[0] = vc4->clear_color[0]; submit.clear_color[1] = vc4->clear_color[1]; submit.clear_z = vc4->clear_depth; submit.clear_s = vc4->clear_stencil; } if (!(vc4_debug & VC4_DEBUG_NORAST)) { int ret; #ifndef USE_VC4_SIMULATOR ret = drmIoctl(vc4->fd, DRM_IOCTL_VC4_SUBMIT_CL, &submit); #else ret = vc4_simulator_flush(vc4, &submit); #endif if (ret) { fprintf(stderr, "VC4 submit failed\n"); abort(); } } vc4->last_emit_seqno = submit.seqno; if (vc4_debug & VC4_DEBUG_ALWAYS_SYNC) { if (!vc4_wait_seqno(vc4->screen, vc4->last_emit_seqno, PIPE_TIMEOUT_INFINITE, "sync")) { fprintf(stderr, "Wait failed.\n"); abort(); } } vc4_job_reset(vc4); }