1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/********************************************************** 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2008-2009 VMware, Inc. All rights reserved. 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * obtaining a copy of this software and associated documentation 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * files (the "Software"), to deal in the Software without 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * restriction, including without limitation the rights to use, copy, 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * modify, merge, publish, distribute, sublicense, and/or sell copies 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software, and to permit persons to whom the Software is 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * furnished to do so, subject to the following conditions: 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice shall be 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * included in all copies or substantial portions of the Software. 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE. 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **********************************************************/ 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "svga_cmd.h" 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_format.h" 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_inlines.h" 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_prim.h" 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_time.h" 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "indices/u_indices.h" 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "svga_hw_reg.h" 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "svga_context.h" 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "svga_screen.h" 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "svga_draw.h" 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "svga_state.h" 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "svga_swtnl.h" 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "svga_debug.h" 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "svga_resource_buffer.h" 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_upload_mgr.h" 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Determine the ranges to upload for the user-buffers referenced 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * by the next draw command. 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TODO: It might be beneficial to support multiple ranges. In that case, 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the struct svga_buffer::uploaded member should be made an array or a 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * list, since we need to account for the possibility that different ranges 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * may be uploaded to different hardware buffers chosen by the utility 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * upload manager. 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsvga_user_buffer_range(struct svga_context *svga, 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned start, 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned count, 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned instance_count) 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct pipe_vertex_element *ve = svga->curr.velems->velem; 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int i; 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Release old uploaded range (if not done already) and 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * initialize new ranges. 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i=0; i < svga->curr.velems->count; i++) { 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_vertex_buffer *vb = 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &svga->curr.vb[ve[i].vertex_buffer_index]; 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (vb->buffer && svga_buffer_is_user_buffer(vb->buffer)) { 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_buffer *buffer = svga_buffer(vb->buffer); 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_resource_reference(&buffer->uploaded.buffer, NULL); 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer->uploaded.start = ~0; 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer->uploaded.end = 0; 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i=0; i < svga->curr.velems->count; i++) { 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_vertex_buffer *vb = 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &svga->curr.vb[ve[i].vertex_buffer_index]; 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (vb->buffer && svga_buffer_is_user_buffer(vb->buffer)) { 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_buffer *buffer = svga_buffer(vb->buffer); 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned first, size; 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned instance_div = ve[i].instance_divisor; 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned elemSize = util_format_get_blocksize(ve[i].src_format); 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga->dirty |= SVGA_NEW_VBUFFER; 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (instance_div) { 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org first = ve[i].src_offset; 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org count = (instance_count + instance_div - 1) / instance_div; 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org size = vb->stride * (count - 1) + elemSize; 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org first = vb->stride * start + ve[i].src_offset; 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org size = vb->stride * (count - 1) + elemSize; 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer->uploaded.start = MIN2(buffer->uploaded.start, first); 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer->uploaded.end = MAX2(buffer->uploaded.end, first + size); 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * svga_upload_user_buffers - upload parts of user buffers 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This function streams a part of a user buffer to hw and fills 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * svga_buffer::uploaded with information on the upload. 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsvga_upload_user_buffers(struct svga_context *svga, 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned start, 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned count, 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned instance_count) 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct pipe_vertex_element *ve = svga->curr.velems->velem; 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned i; 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int ret; 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga_user_buffer_range(svga, start, count, instance_count); 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i=0; i < svga->curr.velems->count; i++) { 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_vertex_buffer *vb = 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &svga->curr.vb[ve[i].vertex_buffer_index]; 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (vb->buffer && svga_buffer_is_user_buffer(vb->buffer)) { 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_buffer *buffer = svga_buffer(vb->buffer); 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Check if already uploaded. Otherwise go ahead and upload. 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (buffer->uploaded.buffer) 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ret = u_upload_buffer( svga->upload_vb, 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 0, 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer->uploaded.start, 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer->uploaded.end - buffer->uploaded.start, 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &buffer->b.b, 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &buffer->uploaded.offset, 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &buffer->uploaded.buffer); 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ret) 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ret; 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (0) 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("%s: %d: orig buf %p upl buf %p ofs %d sofs %d" 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org " sz %d\n", 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org __FUNCTION__, 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org i, 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer, 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer->uploaded.buffer, 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer->uploaded.offset, 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer->uploaded.start, 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer->uploaded.end - buffer->uploaded.start); 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vb->buffer_offset = buffer->uploaded.offset; 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return PIPE_OK; 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * svga_release_user_upl_buffers - release uploaded parts of user buffers 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This function releases the hw copy of the uploaded fraction of the 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * user-buffer. It's important to do this as soon as all draw calls 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * affecting the uploaded fraction are issued, as this allows for 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * efficient reuse of the hardware surface backing the uploaded fraction. 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * svga_buffer::source_offset is set to 0, and svga_buffer::uploaded::buffer 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is set to 0. 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsvga_release_user_upl_buffers(struct svga_context *svga) 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned i; 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned nr; 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org nr = svga->curr.num_vertex_buffers; 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < nr; ++i) { 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_vertex_buffer *vb = &svga->curr.vb[i]; 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (vb->buffer && svga_buffer_is_user_buffer(vb->buffer)) { 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_buffer *buffer = svga_buffer(vb->buffer); 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* The buffer_offset is relative to the uploaded buffer. 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Since we're discarding that buffer we need to reset this offset 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * so it's not inadvertantly applied to a subsequent draw. 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * XXX a root problem here is that the svga->curr.vb[] information 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is getting set both by gallium API calls and by code in 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * svga_upload_user_buffers(). We should instead have two copies 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the vertex buffer information and choose between as needed. 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vb->buffer_offset = 0; 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer->uploaded.start = ~0; 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer->uploaded.end = 0; 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (buffer->uploaded.buffer) 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_resource_reference(&buffer->uploaded.buffer, NULL); 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic enum pipe_error 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgretry_draw_range_elements( struct svga_context *svga, 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_resource *index_buffer, 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned index_size, 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int index_bias, 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned min_index, 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned max_index, 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned prim, 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned start, 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned count, 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned instance_count, 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean do_retry ) 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum pipe_error ret = PIPE_OK; 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga_hwtnl_set_unfilled( svga->hwtnl, 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga->curr.rast->hw_unfilled ); 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga_hwtnl_set_flatshade( svga->hwtnl, 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga->curr.rast->templ.flatshade, 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga->curr.rast->templ.flatshade_first ); 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ret = svga_upload_user_buffers( svga, min_index + index_bias, 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org max_index - min_index + 1, instance_count ); 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ret != PIPE_OK) 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto retry; 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ret = svga_update_state( svga, SVGA_STATE_HW_DRAW ); 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ret != PIPE_OK) 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto retry; 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ret = svga_hwtnl_draw_range_elements( svga->hwtnl, 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org index_buffer, index_size, index_bias, 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org min_index, max_index, 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prim, start, count ); 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ret != PIPE_OK) 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto retry; 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return PIPE_OK; 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgretry: 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga_context_flush( svga, NULL ); 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (do_retry) 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return retry_draw_range_elements( svga, 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org index_buffer, index_size, index_bias, 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org min_index, max_index, 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prim, start, count, 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instance_count, FALSE ); 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ret; 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic enum pipe_error 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgretry_draw_arrays( struct svga_context *svga, 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned prim, 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned start, 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned count, 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned instance_count, 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean do_retry ) 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum pipe_error ret; 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga_hwtnl_set_unfilled( svga->hwtnl, 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga->curr.rast->hw_unfilled ); 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga_hwtnl_set_flatshade( svga->hwtnl, 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga->curr.rast->templ.flatshade, 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga->curr.rast->templ.flatshade_first ); 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ret = svga_upload_user_buffers( svga, start, count, instance_count ); 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ret != PIPE_OK) 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto retry; 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ret = svga_update_state( svga, SVGA_STATE_HW_DRAW ); 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ret != PIPE_OK) 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto retry; 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ret = svga_hwtnl_draw_arrays( svga->hwtnl, prim, 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org start, count ); 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ret != PIPE_OK) 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto retry; 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return PIPE_OK; 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgretry: 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ret == PIPE_ERROR_OUT_OF_MEMORY && do_retry) 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga_context_flush( svga, NULL ); 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return retry_draw_arrays( svga, 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org prim, 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org start, 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org count, 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instance_count, 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FALSE ); 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ret; 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsvga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_context *svga = svga_context( pipe ); 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned reduced_prim = u_reduced_prim( info->mode ); 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned count = info->count; 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum pipe_error ret = 0; 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean needed_swtnl; 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!u_trim_pipe_prim( info->mode, &count )) 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Mark currently bound target surfaces as dirty 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * doesn't really matter if it is done before drawing. 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TODO If we ever normaly return something other then 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * true we should not mark it as dirty then. 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga_mark_surfaces_dirty(svga_context(pipe)); 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (svga->curr.reduced_prim != reduced_prim) { 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga->curr.reduced_prim = reduced_prim; 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga->dirty |= SVGA_NEW_REDUCED_PRIMITIVE; 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org needed_swtnl = svga->state.sw.need_swtnl; 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga_update_state_retry( svga, SVGA_STATE_NEED_SWTNL ); 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef DEBUG 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (svga->curr.vs->base.id == svga->debug.disable_shader || 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga->curr.fs->base.id == svga->debug.disable_shader) 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (svga->state.sw.need_swtnl) { 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!needed_swtnl) { 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * We're switching from HW to SW TNL. SW TNL will require mapping all 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * currently bound vertex buffers, some of which may already be 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * referenced in the current command buffer as result of previous HW 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TNL. So flush now, to prevent the context to flush while a referred 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * vertex buffer is mapped. 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga_context_flush(svga, NULL); 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Avoid leaking the previous hwtnl bias to swtnl */ 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga_hwtnl_set_index_bias( svga->hwtnl, 0 ); 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ret = svga_swtnl_draw_vbo( svga, info ); 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (info->indexed && svga->curr.ib.buffer) { 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned offset; 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(svga->curr.ib.offset % svga->curr.ib.index_size == 0); 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org offset = svga->curr.ib.offset / svga->curr.ib.index_size; 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ret = retry_draw_range_elements( svga, 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga->curr.ib.buffer, 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga->curr.ib.index_size, 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org info->index_bias, 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org info->min_index, 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org info->max_index, 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org info->mode, 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org info->start + offset, 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org info->count, 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org info->instance_count, 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TRUE ); 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ret = retry_draw_arrays( svga, 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org info->mode, 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org info->start, 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org info->count, 401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org info->instance_count, 402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TRUE ); 403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* XXX: Silence warnings, do something sensible here? */ 407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (void)ret; 408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga_release_user_upl_buffers( svga ); 410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (SVGA_DEBUG & DEBUG_FLUSH) { 412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga_hwtnl_flush_retry( svga ); 413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga_context_flush(svga, NULL); 414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid svga_init_draw_functions( struct svga_context *svga ) 419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga->pipe.draw_vbo = svga_draw_vbo; 421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 422