static enum pipe_error draw_vgpu9(struct svga_hwtnl *hwtnl) { struct svga_winsys_context *swc = hwtnl->cmd.swc; struct svga_context *svga = hwtnl->svga; enum pipe_error ret; struct svga_winsys_surface *vb_handle[SVGA3D_INPUTREG_MAX]; struct svga_winsys_surface *ib_handle[QSZ]; struct svga_winsys_surface *handle; SVGA3dVertexDecl *vdecl; SVGA3dPrimitiveRange *prim; unsigned i; for (i = 0; i < hwtnl->cmd.vdecl_count; i++) { unsigned j = hwtnl->cmd.vdecl_buffer_index[i]; handle = svga_buffer_handle(svga, hwtnl->cmd.vbufs[j].buffer); if (handle == NULL) return PIPE_ERROR_OUT_OF_MEMORY; vb_handle[i] = handle; } for (i = 0; i < hwtnl->cmd.prim_count; i++) { if (hwtnl->cmd.prim_ib[i]) { handle = svga_buffer_handle(svga, hwtnl->cmd.prim_ib[i]); if (handle == NULL) return PIPE_ERROR_OUT_OF_MEMORY; } else handle = NULL; ib_handle[i] = handle; } if (svga->rebind.flags.rendertargets) { ret = svga_reemit_framebuffer_bindings(svga); if (ret != PIPE_OK) { return ret; } } if (svga->rebind.flags.texture_samplers) { ret = svga_reemit_tss_bindings(svga); if (ret != PIPE_OK) { return ret; } } if (svga->rebind.flags.vs) { ret = svga_reemit_vs_bindings(svga); if (ret != PIPE_OK) { return ret; } } if (svga->rebind.flags.fs) { ret = svga_reemit_fs_bindings(svga); if (ret != PIPE_OK) { return ret; } } SVGA_DBG(DEBUG_DMA, "draw to sid %p, %d prims\n", svga->curr.framebuffer.cbufs[0] ? svga_surface(svga->curr.framebuffer.cbufs[0])->handle : NULL, hwtnl->cmd.prim_count); ret = SVGA3D_BeginDrawPrimitives(swc, &vdecl, hwtnl->cmd.vdecl_count, &prim, hwtnl->cmd.prim_count); if (ret != PIPE_OK) return ret; memcpy(vdecl, hwtnl->cmd.vdecl, hwtnl->cmd.vdecl_count * sizeof hwtnl->cmd.vdecl[0]); for (i = 0; i < hwtnl->cmd.vdecl_count; i++) { /* check for 4-byte alignment */ assert(vdecl[i].array.offset % 4 == 0); assert(vdecl[i].array.stride % 4 == 0); /* Given rangeHint is considered to be relative to indexBias, and * indexBias varies per primitive, we cannot accurately supply an * rangeHint when emitting more than one primitive per draw command. */ if (hwtnl->cmd.prim_count == 1) { vdecl[i].rangeHint.first = hwtnl->cmd.min_index[0]; vdecl[i].rangeHint.last = hwtnl->cmd.max_index[0] + 1; } else { vdecl[i].rangeHint.first = 0; vdecl[i].rangeHint.last = 0; } swc->surface_relocation(swc, &vdecl[i].array.surfaceId, NULL, vb_handle[i], SVGA_RELOC_READ); } memcpy(prim, hwtnl->cmd.prim, hwtnl->cmd.prim_count * sizeof hwtnl->cmd.prim[0]); for (i = 0; i < hwtnl->cmd.prim_count; i++) { swc->surface_relocation(swc, &prim[i].indexArray.surfaceId, NULL, ib_handle[i], SVGA_RELOC_READ); pipe_resource_reference(&hwtnl->cmd.prim_ib[i], NULL); } SVGA_FIFOCommitAll(swc); hwtnl->cmd.prim_count = 0; return PIPE_OK; }
static enum pipe_error try_clear(struct svga_context *svga, unsigned buffers, const union pipe_color_union *color, double depth, unsigned stencil) { enum pipe_error ret = PIPE_OK; SVGA3dRect rect = { 0, 0, 0, 0 }; boolean restore_viewport = FALSE; SVGA3dClearFlag flags = 0; struct pipe_framebuffer_state *fb = &svga->curr.framebuffer; union util_color uc = {0}; ret = svga_update_state(svga, SVGA_STATE_HW_CLEAR); if (ret != PIPE_OK) return ret; if (svga->rebind.rendertargets) { ret = svga_reemit_framebuffer_bindings(svga); if (ret != PIPE_OK) { return ret; } } if (buffers & PIPE_CLEAR_COLOR) { flags |= SVGA3D_CLEAR_COLOR; util_pack_color(color->f, PIPE_FORMAT_B8G8R8A8_UNORM, &uc); rect.w = fb->width; rect.h = fb->height; } if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && fb->zsbuf) { if (buffers & PIPE_CLEAR_DEPTH) flags |= SVGA3D_CLEAR_DEPTH; if ((svga->curr.framebuffer.zsbuf->format == PIPE_FORMAT_S8_UINT_Z24_UNORM) && (buffers & PIPE_CLEAR_STENCIL)) flags |= SVGA3D_CLEAR_STENCIL; rect.w = MAX2(rect.w, fb->zsbuf->width); rect.h = MAX2(rect.h, fb->zsbuf->height); } if (memcmp(&rect, &svga->state.hw_clear.viewport, sizeof(rect)) != 0) { restore_viewport = TRUE; ret = SVGA3D_SetViewport(svga->swc, &rect); if (ret != PIPE_OK) return ret; } ret = SVGA3D_ClearRect(svga->swc, flags, uc.ui, (float) depth, stencil, rect.x, rect.y, rect.w, rect.h); if (ret != PIPE_OK) return ret; if (restore_viewport) { memcpy(&rect, &svga->state.hw_clear.viewport, sizeof rect); ret = SVGA3D_SetViewport(svga->swc, &rect); } return ret; }
static enum pipe_error try_clear(struct svga_context *svga, unsigned buffers, const union pipe_color_union *color, double depth, unsigned stencil) { enum pipe_error ret = PIPE_OK; SVGA3dRect rect = { 0, 0, 0, 0 }; boolean restore_viewport = FALSE; SVGA3dClearFlag flags = 0; struct pipe_framebuffer_state *fb = &svga->curr.framebuffer; union util_color uc = {0}; ret = svga_update_state(svga, SVGA_STATE_HW_CLEAR); if (ret != PIPE_OK) return ret; if (svga->rebind.flags.rendertargets) { ret = svga_reemit_framebuffer_bindings(svga); if (ret != PIPE_OK) { return ret; } } if (buffers & PIPE_CLEAR_COLOR) { flags |= SVGA3D_CLEAR_COLOR; util_pack_color(color->f, PIPE_FORMAT_B8G8R8A8_UNORM, &uc); rect.w = fb->width; rect.h = fb->height; } if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && fb->zsbuf) { if (buffers & PIPE_CLEAR_DEPTH) flags |= SVGA3D_CLEAR_DEPTH; if (buffers & PIPE_CLEAR_STENCIL) flags |= SVGA3D_CLEAR_STENCIL; rect.w = MAX2(rect.w, fb->zsbuf->width); rect.h = MAX2(rect.h, fb->zsbuf->height); } if (!svga_have_vgpu10(svga) && !svga_rects_equal(&rect, &svga->state.hw_clear.viewport)) { restore_viewport = TRUE; ret = SVGA3D_SetViewport(svga->swc, &rect); if (ret != PIPE_OK) return ret; } if (svga_have_vgpu10(svga)) { if (flags & SVGA3D_CLEAR_COLOR) { unsigned i; if (is_integer_target(fb, buffers) && !ints_fit_in_floats(color)) { clear_buffers_with_quad(svga, buffers, color, depth, stencil); /* We also cleared depth/stencil, so that's done */ flags &= ~(SVGA3D_CLEAR_DEPTH | SVGA3D_CLEAR_STENCIL); } else { struct pipe_surface *rtv; /* Issue VGPU10 Clear commands */ for (i = 0; i < fb->nr_cbufs; i++) { if ((fb->cbufs[i] == NULL) || !(buffers & (PIPE_CLEAR_COLOR0 << i))) continue; rtv = svga_validate_surface_view(svga, svga_surface(fb->cbufs[i])); if (!rtv) return PIPE_ERROR_OUT_OF_MEMORY; ret = SVGA3D_vgpu10_ClearRenderTargetView(svga->swc, rtv, color->f); if (ret != PIPE_OK) return ret; } } } if (flags & (SVGA3D_CLEAR_DEPTH | SVGA3D_CLEAR_STENCIL)) { struct pipe_surface *dsv = svga_validate_surface_view(svga, svga_surface(fb->zsbuf)); if (!dsv) return PIPE_ERROR_OUT_OF_MEMORY; ret = SVGA3D_vgpu10_ClearDepthStencilView(svga->swc, dsv, flags, stencil, (float) depth); if (ret != PIPE_OK) return ret; } } else { ret = SVGA3D_ClearRect(svga->swc, flags, uc.ui[0], (float) depth, stencil, rect.x, rect.y, rect.w, rect.h); if (ret != PIPE_OK) return ret; } if (restore_viewport) { ret = SVGA3D_SetViewport(svga->swc, &svga->state.hw_clear.viewport); } return ret; }