1bf215546Sopenharmony_ci/********************************************************** 2bf215546Sopenharmony_ci * Copyright 2008-2009 VMware, Inc. All rights reserved. 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person 5bf215546Sopenharmony_ci * obtaining a copy of this software and associated documentation 6bf215546Sopenharmony_ci * files (the "Software"), to deal in the Software without 7bf215546Sopenharmony_ci * restriction, including without limitation the rights to use, copy, 8bf215546Sopenharmony_ci * modify, merge, publish, distribute, sublicense, and/or sell copies 9bf215546Sopenharmony_ci * of the Software, and to permit persons to whom the Software is 10bf215546Sopenharmony_ci * furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be 13bf215546Sopenharmony_ci * included in all copies or substantial portions of the Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16bf215546Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18bf215546Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19bf215546Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20bf215546Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21bf215546Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22bf215546Sopenharmony_ci * SOFTWARE. 23bf215546Sopenharmony_ci * 24bf215546Sopenharmony_ci **********************************************************/ 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci#include "svga_cmd.h" 27bf215546Sopenharmony_ci#include "svga_debug.h" 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci#include "pipe/p_defines.h" 30bf215546Sopenharmony_ci#include "util/u_pack_color.h" 31bf215546Sopenharmony_ci#include "util/u_surface.h" 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_ci#include "svga_context.h" 34bf215546Sopenharmony_ci#include "svga_state.h" 35bf215546Sopenharmony_ci#include "svga_surface.h" 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ci/** 39bf215546Sopenharmony_ci * Saving blitter states before doing any blitter operation 40bf215546Sopenharmony_ci */ 41bf215546Sopenharmony_cistatic void 42bf215546Sopenharmony_cibegin_blit(struct svga_context *svga) 43bf215546Sopenharmony_ci{ 44bf215546Sopenharmony_ci util_blitter_save_vertex_buffer_slot(svga->blitter, svga->curr.vb); 45bf215546Sopenharmony_ci util_blitter_save_vertex_elements(svga->blitter, (void*)svga->curr.velems); 46bf215546Sopenharmony_ci util_blitter_save_vertex_shader(svga->blitter, svga->curr.vs); 47bf215546Sopenharmony_ci util_blitter_save_geometry_shader(svga->blitter, svga->curr.gs); 48bf215546Sopenharmony_ci util_blitter_save_tessctrl_shader(svga->blitter, svga->curr.tcs); 49bf215546Sopenharmony_ci util_blitter_save_tesseval_shader(svga->blitter, svga->curr.tes); 50bf215546Sopenharmony_ci util_blitter_save_so_targets(svga->blitter, svga->num_so_targets, 51bf215546Sopenharmony_ci (struct pipe_stream_output_target**)svga->so_targets); 52bf215546Sopenharmony_ci util_blitter_save_rasterizer(svga->blitter, (void*)svga->curr.rast); 53bf215546Sopenharmony_ci util_blitter_save_viewport(svga->blitter, &svga->curr.viewport[0]); 54bf215546Sopenharmony_ci util_blitter_save_scissor(svga->blitter, &svga->curr.scissor[0]); 55bf215546Sopenharmony_ci util_blitter_save_fragment_shader(svga->blitter, svga->curr.fs); 56bf215546Sopenharmony_ci util_blitter_save_blend(svga->blitter, (void*)svga->curr.blend); 57bf215546Sopenharmony_ci util_blitter_save_depth_stencil_alpha(svga->blitter, 58bf215546Sopenharmony_ci (void*)svga->curr.depth); 59bf215546Sopenharmony_ci util_blitter_save_stencil_ref(svga->blitter, &svga->curr.stencil_ref); 60bf215546Sopenharmony_ci util_blitter_save_sample_mask(svga->blitter, svga->curr.sample_mask, 0); 61bf215546Sopenharmony_ci util_blitter_save_fragment_constant_buffer_slot(svga->blitter, 62bf215546Sopenharmony_ci &svga->curr.constbufs[PIPE_SHADER_FRAGMENT][0]); 63bf215546Sopenharmony_ci} 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_ci/** 67bf215546Sopenharmony_ci * Clear the whole color buffer(s) by drawing a quad. For VGPU10 we use 68bf215546Sopenharmony_ci * this when clearing integer render targets. We'll also clear the 69bf215546Sopenharmony_ci * depth and/or stencil buffers if the clear_buffers mask specifies them. 70bf215546Sopenharmony_ci */ 71bf215546Sopenharmony_cistatic void 72bf215546Sopenharmony_ciclear_buffers_with_quad(struct svga_context *svga, 73bf215546Sopenharmony_ci unsigned clear_buffers, 74bf215546Sopenharmony_ci const union pipe_color_union *color, 75bf215546Sopenharmony_ci double depth, unsigned stencil) 76bf215546Sopenharmony_ci{ 77bf215546Sopenharmony_ci const struct pipe_framebuffer_state *fb = &svga->curr.framebuffer; 78bf215546Sopenharmony_ci 79bf215546Sopenharmony_ci begin_blit(svga); 80bf215546Sopenharmony_ci util_blitter_clear(svga->blitter, 81bf215546Sopenharmony_ci fb->width, fb->height, 82bf215546Sopenharmony_ci 1, /* num_layers */ 83bf215546Sopenharmony_ci clear_buffers, color, 84bf215546Sopenharmony_ci depth, stencil, 85bf215546Sopenharmony_ci util_framebuffer_get_num_samples(fb) > 1); 86bf215546Sopenharmony_ci} 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_ci/** 90bf215546Sopenharmony_ci * Check if any of the color buffers are integer buffers. 91bf215546Sopenharmony_ci */ 92bf215546Sopenharmony_cistatic boolean 93bf215546Sopenharmony_ciis_integer_target(struct pipe_framebuffer_state *fb, unsigned buffers) 94bf215546Sopenharmony_ci{ 95bf215546Sopenharmony_ci unsigned i; 96bf215546Sopenharmony_ci 97bf215546Sopenharmony_ci for (i = 0; i < fb->nr_cbufs; i++) { 98bf215546Sopenharmony_ci if ((buffers & (PIPE_CLEAR_COLOR0 << i)) && 99bf215546Sopenharmony_ci fb->cbufs[i] && 100bf215546Sopenharmony_ci util_format_is_pure_integer(fb->cbufs[i]->format)) { 101bf215546Sopenharmony_ci return TRUE; 102bf215546Sopenharmony_ci } 103bf215546Sopenharmony_ci } 104bf215546Sopenharmony_ci return FALSE; 105bf215546Sopenharmony_ci} 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_ci/** 109bf215546Sopenharmony_ci * Check if the integer values in the clear color can be represented 110bf215546Sopenharmony_ci * by floats. If so, we can use the VGPU10 ClearRenderTargetView command. 111bf215546Sopenharmony_ci * Otherwise, we need to clear with a quad. 112bf215546Sopenharmony_ci */ 113bf215546Sopenharmony_cistatic boolean 114bf215546Sopenharmony_ciints_fit_in_floats(const union pipe_color_union *color) 115bf215546Sopenharmony_ci{ 116bf215546Sopenharmony_ci const int max = 1 << 24; 117bf215546Sopenharmony_ci return (color->i[0] <= max && 118bf215546Sopenharmony_ci color->i[1] <= max && 119bf215546Sopenharmony_ci color->i[2] <= max && 120bf215546Sopenharmony_ci color->i[3] <= max); 121bf215546Sopenharmony_ci} 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_cistatic enum pipe_error 125bf215546Sopenharmony_citry_clear(struct svga_context *svga, 126bf215546Sopenharmony_ci unsigned buffers, 127bf215546Sopenharmony_ci const union pipe_color_union *color, 128bf215546Sopenharmony_ci double depth, 129bf215546Sopenharmony_ci unsigned stencil) 130bf215546Sopenharmony_ci{ 131bf215546Sopenharmony_ci enum pipe_error ret = PIPE_OK; 132bf215546Sopenharmony_ci SVGA3dRect rect = { 0, 0, 0, 0 }; 133bf215546Sopenharmony_ci boolean restore_viewport = FALSE; 134bf215546Sopenharmony_ci SVGA3dClearFlag flags = 0; 135bf215546Sopenharmony_ci struct pipe_framebuffer_state *fb = &svga->curr.framebuffer; 136bf215546Sopenharmony_ci union util_color uc = {0}; 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci ret = svga_update_state(svga, SVGA_STATE_HW_CLEAR); 139bf215546Sopenharmony_ci if (ret != PIPE_OK) 140bf215546Sopenharmony_ci return ret; 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci if (svga->rebind.flags.rendertargets) { 143bf215546Sopenharmony_ci ret = svga_reemit_framebuffer_bindings(svga); 144bf215546Sopenharmony_ci if (ret != PIPE_OK) { 145bf215546Sopenharmony_ci return ret; 146bf215546Sopenharmony_ci } 147bf215546Sopenharmony_ci } 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_ci if (buffers & PIPE_CLEAR_COLOR) { 150bf215546Sopenharmony_ci flags |= SVGA3D_CLEAR_COLOR; 151bf215546Sopenharmony_ci util_pack_color(color->f, PIPE_FORMAT_B8G8R8A8_UNORM, &uc); 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci rect.w = fb->width; 154bf215546Sopenharmony_ci rect.h = fb->height; 155bf215546Sopenharmony_ci } 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_ci if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && fb->zsbuf) { 158bf215546Sopenharmony_ci if (buffers & PIPE_CLEAR_DEPTH) 159bf215546Sopenharmony_ci flags |= SVGA3D_CLEAR_DEPTH; 160bf215546Sopenharmony_ci 161bf215546Sopenharmony_ci if (buffers & PIPE_CLEAR_STENCIL) 162bf215546Sopenharmony_ci flags |= SVGA3D_CLEAR_STENCIL; 163bf215546Sopenharmony_ci 164bf215546Sopenharmony_ci rect.w = MAX2(rect.w, fb->zsbuf->width); 165bf215546Sopenharmony_ci rect.h = MAX2(rect.h, fb->zsbuf->height); 166bf215546Sopenharmony_ci } 167bf215546Sopenharmony_ci 168bf215546Sopenharmony_ci if (!svga_have_vgpu10(svga) && 169bf215546Sopenharmony_ci !svga_rects_equal(&rect, &svga->state.hw_clear.viewport)) { 170bf215546Sopenharmony_ci restore_viewport = TRUE; 171bf215546Sopenharmony_ci ret = SVGA3D_SetViewport(svga->swc, &rect); 172bf215546Sopenharmony_ci if (ret != PIPE_OK) 173bf215546Sopenharmony_ci return ret; 174bf215546Sopenharmony_ci } 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_ci if (svga_have_vgpu10(svga)) { 177bf215546Sopenharmony_ci if (flags & SVGA3D_CLEAR_COLOR) { 178bf215546Sopenharmony_ci unsigned i; 179bf215546Sopenharmony_ci bool int_target = is_integer_target(fb, buffers); 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci if (int_target && !ints_fit_in_floats(color)) { 182bf215546Sopenharmony_ci clear_buffers_with_quad(svga, buffers, color, depth, stencil); 183bf215546Sopenharmony_ci /* We also cleared depth/stencil, so that's done */ 184bf215546Sopenharmony_ci flags &= ~(SVGA3D_CLEAR_DEPTH | SVGA3D_CLEAR_STENCIL); 185bf215546Sopenharmony_ci } 186bf215546Sopenharmony_ci else { 187bf215546Sopenharmony_ci struct pipe_surface *rtv; 188bf215546Sopenharmony_ci float rgba[4]; 189bf215546Sopenharmony_ci 190bf215546Sopenharmony_ci if (int_target) { 191bf215546Sopenharmony_ci rgba[0] = (float) color->i[0]; 192bf215546Sopenharmony_ci rgba[1] = (float) color->i[1]; 193bf215546Sopenharmony_ci rgba[2] = (float) color->i[2]; 194bf215546Sopenharmony_ci rgba[3] = (float) color->i[3]; 195bf215546Sopenharmony_ci } 196bf215546Sopenharmony_ci else { 197bf215546Sopenharmony_ci rgba[0] = color->f[0]; 198bf215546Sopenharmony_ci rgba[1] = color->f[1]; 199bf215546Sopenharmony_ci rgba[2] = color->f[2]; 200bf215546Sopenharmony_ci rgba[3] = color->f[3]; 201bf215546Sopenharmony_ci } 202bf215546Sopenharmony_ci 203bf215546Sopenharmony_ci /* Issue VGPU10 Clear commands */ 204bf215546Sopenharmony_ci for (i = 0; i < fb->nr_cbufs; i++) { 205bf215546Sopenharmony_ci if ((fb->cbufs[i] == NULL) || 206bf215546Sopenharmony_ci !(buffers & (PIPE_CLEAR_COLOR0 << i))) 207bf215546Sopenharmony_ci continue; 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_ci rtv = svga_validate_surface_view(svga, 210bf215546Sopenharmony_ci svga_surface(fb->cbufs[i])); 211bf215546Sopenharmony_ci if (!rtv) 212bf215546Sopenharmony_ci return PIPE_ERROR_OUT_OF_MEMORY; 213bf215546Sopenharmony_ci 214bf215546Sopenharmony_ci ret = SVGA3D_vgpu10_ClearRenderTargetView(svga->swc, rtv, rgba); 215bf215546Sopenharmony_ci if (ret != PIPE_OK) 216bf215546Sopenharmony_ci return ret; 217bf215546Sopenharmony_ci } 218bf215546Sopenharmony_ci } 219bf215546Sopenharmony_ci } 220bf215546Sopenharmony_ci if (flags & (SVGA3D_CLEAR_DEPTH | SVGA3D_CLEAR_STENCIL)) { 221bf215546Sopenharmony_ci struct pipe_surface *dsv = 222bf215546Sopenharmony_ci svga_validate_surface_view(svga, svga_surface(fb->zsbuf)); 223bf215546Sopenharmony_ci if (!dsv) 224bf215546Sopenharmony_ci return PIPE_ERROR_OUT_OF_MEMORY; 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_ci ret = SVGA3D_vgpu10_ClearDepthStencilView(svga->swc, dsv, flags, 227bf215546Sopenharmony_ci stencil, (float) depth); 228bf215546Sopenharmony_ci if (ret != PIPE_OK) 229bf215546Sopenharmony_ci return ret; 230bf215546Sopenharmony_ci } 231bf215546Sopenharmony_ci } 232bf215546Sopenharmony_ci else { 233bf215546Sopenharmony_ci ret = SVGA3D_ClearRect(svga->swc, flags, uc.ui[0], (float) depth, stencil, 234bf215546Sopenharmony_ci rect.x, rect.y, rect.w, rect.h); 235bf215546Sopenharmony_ci if (ret != PIPE_OK) 236bf215546Sopenharmony_ci return ret; 237bf215546Sopenharmony_ci } 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_ci if (restore_viewport) { 240bf215546Sopenharmony_ci ret = SVGA3D_SetViewport(svga->swc, &svga->state.hw_clear.viewport); 241bf215546Sopenharmony_ci } 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci return ret; 244bf215546Sopenharmony_ci} 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_ci/** 247bf215546Sopenharmony_ci * Clear the given surface to the specified value. 248bf215546Sopenharmony_ci * No masking, no scissor (clear entire buffer). 249bf215546Sopenharmony_ci */ 250bf215546Sopenharmony_cistatic void 251bf215546Sopenharmony_cisvga_clear(struct pipe_context *pipe, unsigned buffers, const struct pipe_scissor_state *scissor_state, 252bf215546Sopenharmony_ci const union pipe_color_union *color, 253bf215546Sopenharmony_ci double depth, unsigned stencil) 254bf215546Sopenharmony_ci{ 255bf215546Sopenharmony_ci struct svga_context *svga = svga_context( pipe ); 256bf215546Sopenharmony_ci enum pipe_error ret; 257bf215546Sopenharmony_ci 258bf215546Sopenharmony_ci if (buffers & PIPE_CLEAR_COLOR) { 259bf215546Sopenharmony_ci struct svga_winsys_surface *h = NULL; 260bf215546Sopenharmony_ci if (svga->curr.framebuffer.cbufs[0]) { 261bf215546Sopenharmony_ci h = svga_surface(svga->curr.framebuffer.cbufs[0])->handle; 262bf215546Sopenharmony_ci } 263bf215546Sopenharmony_ci SVGA_DBG(DEBUG_DMA, "clear sid %p\n", h); 264bf215546Sopenharmony_ci } 265bf215546Sopenharmony_ci 266bf215546Sopenharmony_ci /* flush any queued prims (don't want them to appear after the clear!) */ 267bf215546Sopenharmony_ci svga_hwtnl_flush_retry(svga); 268bf215546Sopenharmony_ci 269bf215546Sopenharmony_ci SVGA_RETRY_OOM(svga, ret, try_clear( svga, buffers, color, depth, stencil)); 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_ci /* 272bf215546Sopenharmony_ci * Mark target surfaces as dirty 273bf215546Sopenharmony_ci * TODO Mark only cleared surfaces. 274bf215546Sopenharmony_ci */ 275bf215546Sopenharmony_ci svga_mark_surfaces_dirty(svga); 276bf215546Sopenharmony_ci 277bf215546Sopenharmony_ci assert (ret == PIPE_OK); 278bf215546Sopenharmony_ci} 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_ci 281bf215546Sopenharmony_cistatic void 282bf215546Sopenharmony_cisvga_clear_texture(struct pipe_context *pipe, 283bf215546Sopenharmony_ci struct pipe_resource *res, 284bf215546Sopenharmony_ci unsigned level, 285bf215546Sopenharmony_ci const struct pipe_box *box, 286bf215546Sopenharmony_ci const void *data) 287bf215546Sopenharmony_ci{ 288bf215546Sopenharmony_ci struct svga_context *svga = svga_context(pipe); 289bf215546Sopenharmony_ci struct svga_surface *svga_surface_dst; 290bf215546Sopenharmony_ci struct pipe_surface tmpl; 291bf215546Sopenharmony_ci struct pipe_surface *surface; 292bf215546Sopenharmony_ci 293bf215546Sopenharmony_ci memset(&tmpl, 0, sizeof(tmpl)); 294bf215546Sopenharmony_ci tmpl.format = res->format; 295bf215546Sopenharmony_ci tmpl.u.tex.first_layer = box->z; 296bf215546Sopenharmony_ci tmpl.u.tex.last_layer = box->z + box->depth - 1; 297bf215546Sopenharmony_ci tmpl.u.tex.level = level; 298bf215546Sopenharmony_ci 299bf215546Sopenharmony_ci surface = pipe->create_surface(pipe, res, &tmpl); 300bf215546Sopenharmony_ci if (surface == NULL) { 301bf215546Sopenharmony_ci debug_printf("failed to create surface\n"); 302bf215546Sopenharmony_ci return; 303bf215546Sopenharmony_ci } 304bf215546Sopenharmony_ci svga_surface_dst = svga_surface(surface); 305bf215546Sopenharmony_ci 306bf215546Sopenharmony_ci union pipe_color_union color; 307bf215546Sopenharmony_ci const struct util_format_description *desc = 308bf215546Sopenharmony_ci util_format_description(surface->format); 309bf215546Sopenharmony_ci 310bf215546Sopenharmony_ci if (util_format_is_depth_or_stencil(surface->format)) { 311bf215546Sopenharmony_ci float depth; 312bf215546Sopenharmony_ci uint8_t stencil; 313bf215546Sopenharmony_ci unsigned clear_flags = 0; 314bf215546Sopenharmony_ci 315bf215546Sopenharmony_ci /* If data is NULL, then set depthValue and stencilValue to zeros */ 316bf215546Sopenharmony_ci if (data == NULL) { 317bf215546Sopenharmony_ci depth = 0.0; 318bf215546Sopenharmony_ci stencil = 0; 319bf215546Sopenharmony_ci } 320bf215546Sopenharmony_ci else { 321bf215546Sopenharmony_ci util_format_unpack_z_float(surface->format, &depth, data, 1); 322bf215546Sopenharmony_ci util_format_unpack_s_8uint(surface->format, &stencil, data, 1); 323bf215546Sopenharmony_ci } 324bf215546Sopenharmony_ci 325bf215546Sopenharmony_ci if (util_format_has_depth(desc)) { 326bf215546Sopenharmony_ci clear_flags |= PIPE_CLEAR_DEPTH; 327bf215546Sopenharmony_ci } 328bf215546Sopenharmony_ci if (util_format_has_stencil(desc)) { 329bf215546Sopenharmony_ci clear_flags |= PIPE_CLEAR_STENCIL; 330bf215546Sopenharmony_ci } 331bf215546Sopenharmony_ci 332bf215546Sopenharmony_ci /* Setup depth stencil view */ 333bf215546Sopenharmony_ci struct pipe_surface *dsv = 334bf215546Sopenharmony_ci svga_validate_surface_view(svga, svga_surface_dst); 335bf215546Sopenharmony_ci 336bf215546Sopenharmony_ci if (!dsv) { 337bf215546Sopenharmony_ci pipe_surface_reference(&surface, NULL); 338bf215546Sopenharmony_ci return; 339bf215546Sopenharmony_ci } 340bf215546Sopenharmony_ci 341bf215546Sopenharmony_ci if (box->x == 0 && box->y == 0 && box->width == surface->width && 342bf215546Sopenharmony_ci box->height == surface->height) { 343bf215546Sopenharmony_ci /* clearing whole surface, use direct VGPU10 command */ 344bf215546Sopenharmony_ci assert(svga_surface(dsv)->view_id != SVGA3D_INVALID_ID); 345bf215546Sopenharmony_ci 346bf215546Sopenharmony_ci SVGA_RETRY(svga, SVGA3D_vgpu10_ClearDepthStencilView(svga->swc, dsv, 347bf215546Sopenharmony_ci clear_flags, 348bf215546Sopenharmony_ci stencil, depth)); 349bf215546Sopenharmony_ci } 350bf215546Sopenharmony_ci else { 351bf215546Sopenharmony_ci /* To clear subtexture use software fallback */ 352bf215546Sopenharmony_ci 353bf215546Sopenharmony_ci util_blitter_save_framebuffer(svga->blitter, 354bf215546Sopenharmony_ci &svga->curr.framebuffer); 355bf215546Sopenharmony_ci begin_blit(svga); 356bf215546Sopenharmony_ci util_blitter_clear_depth_stencil(svga->blitter, 357bf215546Sopenharmony_ci dsv, clear_flags, 358bf215546Sopenharmony_ci depth,stencil, 359bf215546Sopenharmony_ci box->x, box->y, 360bf215546Sopenharmony_ci box->width, box->height); 361bf215546Sopenharmony_ci } 362bf215546Sopenharmony_ci } 363bf215546Sopenharmony_ci else { 364bf215546Sopenharmony_ci /* non depth-stencil formats */ 365bf215546Sopenharmony_ci 366bf215546Sopenharmony_ci if (data == NULL) { 367bf215546Sopenharmony_ci /* If data is NULL, the texture image is filled with zeros */ 368bf215546Sopenharmony_ci color.f[0] = color.f[1] = color.f[2] = color.f[3] = 0; 369bf215546Sopenharmony_ci } 370bf215546Sopenharmony_ci else { 371bf215546Sopenharmony_ci util_format_unpack_rgba(surface->format, &color, data, 1); 372bf215546Sopenharmony_ci } 373bf215546Sopenharmony_ci 374bf215546Sopenharmony_ci /* Setup render target view */ 375bf215546Sopenharmony_ci struct pipe_surface *rtv = 376bf215546Sopenharmony_ci svga_validate_surface_view(svga, svga_surface_dst); 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_ci if (!rtv) { 379bf215546Sopenharmony_ci pipe_surface_reference(&surface, NULL); 380bf215546Sopenharmony_ci return; 381bf215546Sopenharmony_ci } 382bf215546Sopenharmony_ci 383bf215546Sopenharmony_ci if (box->x == 0 && box->y == 0 && box->width == surface->width && 384bf215546Sopenharmony_ci box->height == surface->height) { 385bf215546Sopenharmony_ci struct pipe_framebuffer_state *curr = &svga->curr.framebuffer; 386bf215546Sopenharmony_ci bool int_target = is_integer_target(curr, PIPE_CLEAR_COLOR); 387bf215546Sopenharmony_ci 388bf215546Sopenharmony_ci if (int_target && !ints_fit_in_floats(&color)) { 389bf215546Sopenharmony_ci /* To clear full texture with integer format */ 390bf215546Sopenharmony_ci clear_buffers_with_quad(svga, PIPE_CLEAR_COLOR, &color, 0.0, 0); 391bf215546Sopenharmony_ci } 392bf215546Sopenharmony_ci else { 393bf215546Sopenharmony_ci float rgba[4]; 394bf215546Sopenharmony_ci 395bf215546Sopenharmony_ci if (int_target) { 396bf215546Sopenharmony_ci rgba[0] = (float) color.i[0]; 397bf215546Sopenharmony_ci rgba[1] = (float) color.i[1]; 398bf215546Sopenharmony_ci rgba[2] = (float) color.i[2]; 399bf215546Sopenharmony_ci rgba[3] = (float) color.i[3]; 400bf215546Sopenharmony_ci } 401bf215546Sopenharmony_ci else { 402bf215546Sopenharmony_ci rgba[0] = color.f[0]; 403bf215546Sopenharmony_ci rgba[1] = color.f[1]; 404bf215546Sopenharmony_ci rgba[2] = color.f[2]; 405bf215546Sopenharmony_ci rgba[3] = color.f[3]; 406bf215546Sopenharmony_ci } 407bf215546Sopenharmony_ci 408bf215546Sopenharmony_ci /* clearing whole surface using VGPU10 command */ 409bf215546Sopenharmony_ci assert(svga_surface(rtv)->view_id != SVGA3D_INVALID_ID); 410bf215546Sopenharmony_ci SVGA_RETRY(svga, SVGA3D_vgpu10_ClearRenderTargetView(svga->swc, rtv, 411bf215546Sopenharmony_ci rgba)); 412bf215546Sopenharmony_ci } 413bf215546Sopenharmony_ci } 414bf215546Sopenharmony_ci else { 415bf215546Sopenharmony_ci /* To clear subtexture use software fallback */ 416bf215546Sopenharmony_ci 417bf215546Sopenharmony_ci /** 418bf215546Sopenharmony_ci * util_blitter_clear_render_target doesn't support PIPE_TEXTURE_3D 419bf215546Sopenharmony_ci * It tries to draw quad with depth 0 for PIPE_TEXTURE_3D so use 420bf215546Sopenharmony_ci * util_clear_render_target() for PIPE_TEXTURE_3D. 421bf215546Sopenharmony_ci */ 422bf215546Sopenharmony_ci if (rtv->texture->target != PIPE_TEXTURE_3D && 423bf215546Sopenharmony_ci pipe->screen->is_format_supported(pipe->screen, rtv->format, 424bf215546Sopenharmony_ci rtv->texture->target, 425bf215546Sopenharmony_ci rtv->texture->nr_samples, 426bf215546Sopenharmony_ci rtv->texture->nr_storage_samples, 427bf215546Sopenharmony_ci PIPE_BIND_RENDER_TARGET)) { 428bf215546Sopenharmony_ci /* clear with quad drawing */ 429bf215546Sopenharmony_ci util_blitter_save_framebuffer(svga->blitter, 430bf215546Sopenharmony_ci &svga->curr.framebuffer); 431bf215546Sopenharmony_ci begin_blit(svga); 432bf215546Sopenharmony_ci util_blitter_clear_render_target(svga->blitter, 433bf215546Sopenharmony_ci rtv, 434bf215546Sopenharmony_ci &color, 435bf215546Sopenharmony_ci box->x, box->y, 436bf215546Sopenharmony_ci box->width, box->height); 437bf215546Sopenharmony_ci } 438bf215546Sopenharmony_ci else { 439bf215546Sopenharmony_ci /* clear with map/write/unmap */ 440bf215546Sopenharmony_ci 441bf215546Sopenharmony_ci /* store layer values */ 442bf215546Sopenharmony_ci unsigned first_layer = rtv->u.tex.first_layer; 443bf215546Sopenharmony_ci unsigned last_layer = rtv->u.tex.last_layer; 444bf215546Sopenharmony_ci unsigned box_depth = last_layer - first_layer + 1; 445bf215546Sopenharmony_ci 446bf215546Sopenharmony_ci for (unsigned i = 0; i < box_depth; i++) { 447bf215546Sopenharmony_ci rtv->u.tex.first_layer = rtv->u.tex.last_layer = 448bf215546Sopenharmony_ci first_layer + i; 449bf215546Sopenharmony_ci util_clear_render_target(pipe, rtv, &color, box->x, box->y, 450bf215546Sopenharmony_ci box->width, box->height); 451bf215546Sopenharmony_ci } 452bf215546Sopenharmony_ci /* restore layer values */ 453bf215546Sopenharmony_ci rtv->u.tex.first_layer = first_layer; 454bf215546Sopenharmony_ci rtv->u.tex.last_layer = last_layer; 455bf215546Sopenharmony_ci } 456bf215546Sopenharmony_ci } 457bf215546Sopenharmony_ci } 458bf215546Sopenharmony_ci pipe_surface_reference(&surface, NULL); 459bf215546Sopenharmony_ci} 460bf215546Sopenharmony_ci 461bf215546Sopenharmony_ci/** 462bf215546Sopenharmony_ci * \brief Clear the whole render target using vgpu10 functionality 463bf215546Sopenharmony_ci * 464bf215546Sopenharmony_ci * \param svga[in] The svga context 465bf215546Sopenharmony_ci * \param dst[in] The surface to clear 466bf215546Sopenharmony_ci * \param color[in] Clear color 467bf215546Sopenharmony_ci * \return PIPE_OK if all well, PIPE_ERROR_OUT_OF_MEMORY if ran out of 468bf215546Sopenharmony_ci * command submission resources. 469bf215546Sopenharmony_ci */ 470bf215546Sopenharmony_cistatic enum pipe_error 471bf215546Sopenharmony_cisvga_try_clear_render_target(struct svga_context *svga, 472bf215546Sopenharmony_ci struct pipe_surface *dst, 473bf215546Sopenharmony_ci const union pipe_color_union *color) 474bf215546Sopenharmony_ci{ 475bf215546Sopenharmony_ci struct pipe_surface *rtv = 476bf215546Sopenharmony_ci svga_validate_surface_view(svga, svga_surface(dst)); 477bf215546Sopenharmony_ci 478bf215546Sopenharmony_ci if (!rtv) 479bf215546Sopenharmony_ci return PIPE_ERROR_OUT_OF_MEMORY; 480bf215546Sopenharmony_ci 481bf215546Sopenharmony_ci assert(svga_surface(rtv)->view_id != SVGA3D_INVALID_ID); 482bf215546Sopenharmony_ci return SVGA3D_vgpu10_ClearRenderTargetView(svga->swc, rtv, color->f); 483bf215546Sopenharmony_ci } 484bf215546Sopenharmony_ci 485bf215546Sopenharmony_ci/** 486bf215546Sopenharmony_ci * \brief Clear part of render target using gallium blitter utilities 487bf215546Sopenharmony_ci * 488bf215546Sopenharmony_ci * \param svga[in] The svga context 489bf215546Sopenharmony_ci * \param dst[in] The surface to clear 490bf215546Sopenharmony_ci * \param color[in] Clear color 491bf215546Sopenharmony_ci * \param dstx[in] Clear region left 492bf215546Sopenharmony_ci * \param dsty[in] Clear region top 493bf215546Sopenharmony_ci * \param width[in] Clear region width 494bf215546Sopenharmony_ci * \param height[in] Clear region height 495bf215546Sopenharmony_ci */ 496bf215546Sopenharmony_cistatic void 497bf215546Sopenharmony_cisvga_blitter_clear_render_target(struct svga_context *svga, 498bf215546Sopenharmony_ci struct pipe_surface *dst, 499bf215546Sopenharmony_ci const union pipe_color_union *color, 500bf215546Sopenharmony_ci unsigned dstx, unsigned dsty, 501bf215546Sopenharmony_ci unsigned width, unsigned height) 502bf215546Sopenharmony_ci{ 503bf215546Sopenharmony_ci begin_blit(svga); 504bf215546Sopenharmony_ci util_blitter_save_framebuffer(svga->blitter, &svga->curr.framebuffer); 505bf215546Sopenharmony_ci 506bf215546Sopenharmony_ci util_blitter_clear_render_target(svga->blitter, dst, color, 507bf215546Sopenharmony_ci dstx, dsty, width, height); 508bf215546Sopenharmony_ci} 509bf215546Sopenharmony_ci 510bf215546Sopenharmony_ci 511bf215546Sopenharmony_ci/** 512bf215546Sopenharmony_ci * \brief Clear render target pipe callback 513bf215546Sopenharmony_ci * 514bf215546Sopenharmony_ci * \param pipe[in] The pipe context 515bf215546Sopenharmony_ci * \param dst[in] The surface to clear 516bf215546Sopenharmony_ci * \param color[in] Clear color 517bf215546Sopenharmony_ci * \param dstx[in] Clear region left 518bf215546Sopenharmony_ci * \param dsty[in] Clear region top 519bf215546Sopenharmony_ci * \param width[in] Clear region width 520bf215546Sopenharmony_ci * \param height[in] Clear region height 521bf215546Sopenharmony_ci * \param render_condition_enabled[in] Whether to use conditional rendering 522bf215546Sopenharmony_ci * to clear (if elsewhere enabled). 523bf215546Sopenharmony_ci */ 524bf215546Sopenharmony_cistatic void 525bf215546Sopenharmony_cisvga_clear_render_target(struct pipe_context *pipe, 526bf215546Sopenharmony_ci struct pipe_surface *dst, 527bf215546Sopenharmony_ci const union pipe_color_union *color, 528bf215546Sopenharmony_ci unsigned dstx, unsigned dsty, 529bf215546Sopenharmony_ci unsigned width, unsigned height, 530bf215546Sopenharmony_ci bool render_condition_enabled) 531bf215546Sopenharmony_ci{ 532bf215546Sopenharmony_ci struct svga_context *svga = svga_context( pipe ); 533bf215546Sopenharmony_ci 534bf215546Sopenharmony_ci svga_toggle_render_condition(svga, render_condition_enabled, FALSE); 535bf215546Sopenharmony_ci if (!svga_have_vgpu10(svga) || dstx != 0 || dsty != 0 || 536bf215546Sopenharmony_ci width != dst->width || height != dst->height) { 537bf215546Sopenharmony_ci svga_blitter_clear_render_target(svga, dst, color, dstx, dsty, width, 538bf215546Sopenharmony_ci height); 539bf215546Sopenharmony_ci } else { 540bf215546Sopenharmony_ci enum pipe_error ret; 541bf215546Sopenharmony_ci 542bf215546Sopenharmony_ci SVGA_RETRY_OOM(svga, ret, svga_try_clear_render_target(svga, dst, 543bf215546Sopenharmony_ci color)); 544bf215546Sopenharmony_ci assert (ret == PIPE_OK); 545bf215546Sopenharmony_ci } 546bf215546Sopenharmony_ci svga_toggle_render_condition(svga, render_condition_enabled, TRUE); 547bf215546Sopenharmony_ci} 548bf215546Sopenharmony_ci 549bf215546Sopenharmony_civoid svga_init_clear_functions(struct svga_context *svga) 550bf215546Sopenharmony_ci{ 551bf215546Sopenharmony_ci svga->pipe.clear_render_target = svga_clear_render_target; 552bf215546Sopenharmony_ci svga->pipe.clear_texture = svga_clear_texture; 553bf215546Sopenharmony_ci svga->pipe.clear = svga_clear; 554bf215546Sopenharmony_ci} 555