mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-03-06 10:00:30 +01:00
svga: remove user-space vertex/index buffer code
The gallium vbuf module, which we've been using for some time now, takes care of uploading user-space vertex/index data into real buffers. The upload code in the svga driver was unused. Reviewed-by: José Fonseca <jfonseca@vmware.com>
This commit is contained in:
parent
2f6a315085
commit
8d7b913e4e
6 changed files with 13 additions and 259 deletions
|
|
@ -30,7 +30,6 @@
|
|||
#include "pipe/p_screen.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_bitmask.h"
|
||||
#include "util/u_upload_mgr.h"
|
||||
|
||||
#include "svga_context.h"
|
||||
#include "svga_screen.h"
|
||||
|
|
@ -69,9 +68,6 @@ static void svga_destroy( struct pipe_context *pipe )
|
|||
|
||||
svga_destroy_swtnl( svga );
|
||||
|
||||
u_upload_destroy( svga->upload_vb );
|
||||
u_upload_destroy( svga->upload_ib );
|
||||
|
||||
util_bitmask_destroy( svga->vs_bm );
|
||||
util_bitmask_destroy( svga->fs_bm );
|
||||
|
||||
|
|
@ -136,23 +132,7 @@ struct pipe_context *svga_context_create( struct pipe_screen *screen,
|
|||
if (svga->vs_bm == NULL)
|
||||
goto no_vs_bm;
|
||||
|
||||
svga->upload_ib = u_upload_create( &svga->pipe,
|
||||
32 * 1024,
|
||||
16,
|
||||
PIPE_BIND_INDEX_BUFFER );
|
||||
if (svga->upload_ib == NULL)
|
||||
goto no_upload_ib;
|
||||
|
||||
svga->upload_vb = u_upload_create( &svga->pipe,
|
||||
128 * 1024,
|
||||
16,
|
||||
PIPE_BIND_VERTEX_BUFFER );
|
||||
if (svga->upload_vb == NULL)
|
||||
goto no_upload_vb;
|
||||
|
||||
svga->hwtnl = svga_hwtnl_create( svga,
|
||||
svga->upload_ib,
|
||||
svga->swc );
|
||||
svga->hwtnl = svga_hwtnl_create(svga);
|
||||
if (svga->hwtnl == NULL)
|
||||
goto no_hwtnl;
|
||||
|
||||
|
|
@ -184,10 +164,6 @@ no_state:
|
|||
no_swtnl:
|
||||
svga_hwtnl_destroy( svga->hwtnl );
|
||||
no_hwtnl:
|
||||
u_upload_destroy( svga->upload_vb );
|
||||
no_upload_vb:
|
||||
u_upload_destroy( svga->upload_ib );
|
||||
no_upload_ib:
|
||||
util_bitmask_destroy( svga->vs_bm );
|
||||
no_vs_bm:
|
||||
util_bitmask_destroy( svga->fs_bm );
|
||||
|
|
@ -208,14 +184,6 @@ void svga_context_flush( struct svga_context *svga,
|
|||
|
||||
svga->curr.nr_fbs = 0;
|
||||
|
||||
/* Flush the upload managers to ensure recycling of upload buffers
|
||||
* without throttling. This should really be conditioned on
|
||||
* pipe_buffer_map_range not supporting PIPE_TRANSFER_UNSYNCHRONIZED.
|
||||
*/
|
||||
|
||||
u_upload_flush(svga->upload_vb);
|
||||
u_upload_flush(svga->upload_ib);
|
||||
|
||||
/* Ensure that texture dma uploads are processed
|
||||
* before submitting commands.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ struct draw_fragment_shader;
|
|||
struct svga_shader_result;
|
||||
struct SVGACmdMemory;
|
||||
struct util_bitmask;
|
||||
struct u_upload_mgr;
|
||||
|
||||
|
||||
struct svga_shader
|
||||
|
|
@ -367,8 +366,6 @@ struct svga_context
|
|||
unsigned texture_samplers:1;
|
||||
} rebind;
|
||||
|
||||
struct u_upload_mgr *upload_ib;
|
||||
struct u_upload_mgr *upload_vb;
|
||||
struct svga_hwtnl *hwtnl;
|
||||
|
||||
/** The occlusion query currently in progress */
|
||||
|
|
|
|||
|
|
@ -42,18 +42,16 @@
|
|||
#include "svga_cmd.h"
|
||||
|
||||
|
||||
struct svga_hwtnl *svga_hwtnl_create( struct svga_context *svga,
|
||||
struct u_upload_mgr *upload_ib,
|
||||
struct svga_winsys_context *swc )
|
||||
struct svga_hwtnl *
|
||||
svga_hwtnl_create(struct svga_context *svga)
|
||||
{
|
||||
struct svga_hwtnl *hwtnl = CALLOC_STRUCT(svga_hwtnl);
|
||||
if (hwtnl == NULL)
|
||||
goto fail;
|
||||
|
||||
hwtnl->svga = svga;
|
||||
hwtnl->upload_ib = upload_ib;
|
||||
|
||||
hwtnl->cmd.swc = swc;
|
||||
hwtnl->cmd.swc = svga->swc;
|
||||
|
||||
return hwtnl;
|
||||
|
||||
|
|
@ -177,10 +175,8 @@ svga_hwtnl_flush( struct svga_hwtnl *hwtnl )
|
|||
SVGA3dPrimitiveRange *prim;
|
||||
unsigned i;
|
||||
|
||||
/* Unmap upload manager vertex buffers */
|
||||
u_upload_unmap(svga->upload_vb);
|
||||
|
||||
for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
|
||||
assert(!svga_buffer_is_user_buffer(hwtnl->cmd.vdecl_vb[i]));
|
||||
handle = svga_buffer_handle(svga, hwtnl->cmd.vdecl_vb[i]);
|
||||
if (handle == NULL)
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
|
|
@ -188,11 +184,9 @@ svga_hwtnl_flush( struct svga_hwtnl *hwtnl )
|
|||
vb_handle[i] = handle;
|
||||
}
|
||||
|
||||
/* Unmap upload manager index buffers */
|
||||
u_upload_unmap(svga->upload_ib);
|
||||
|
||||
for (i = 0; i < hwtnl->cmd.prim_count; i++) {
|
||||
if (hwtnl->cmd.prim_ib[i]) {
|
||||
assert(!svga_buffer_is_user_buffer(hwtnl->cmd.prim_ib[i]));
|
||||
handle = svga_buffer_handle(svga, hwtnl->cmd.prim_ib[i]);
|
||||
if (handle == NULL)
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
|
|
|
|||
|
|
@ -35,11 +35,9 @@ struct svga_winsys_context;
|
|||
struct svga_screen;
|
||||
struct svga_context;
|
||||
struct pipe_resource;
|
||||
struct u_upload_mgr;
|
||||
|
||||
struct svga_hwtnl *svga_hwtnl_create( struct svga_context *svga,
|
||||
struct u_upload_mgr *upload_ib,
|
||||
struct svga_winsys_context *swc );
|
||||
struct svga_hwtnl *
|
||||
svga_hwtnl_create(struct svga_context *svga);
|
||||
|
||||
void svga_hwtnl_destroy( struct svga_hwtnl *hwtnl );
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@
|
|||
**********************************************************/
|
||||
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_upload_mgr.h"
|
||||
#include "indices/u_indices.h"
|
||||
|
||||
#include "svga_cmd.h"
|
||||
|
|
@ -117,27 +116,11 @@ svga_hwtnl_simple_draw_range_elements( struct svga_hwtnl *hwtnl,
|
|||
if (hw_count == 0)
|
||||
goto done;
|
||||
|
||||
if (index_buffer &&
|
||||
svga_buffer_is_user_buffer(index_buffer))
|
||||
{
|
||||
assert( index_buffer->width0 >= index_offset + count * index_size );
|
||||
|
||||
ret = u_upload_buffer( hwtnl->upload_ib,
|
||||
0,
|
||||
index_offset,
|
||||
count * index_size,
|
||||
index_buffer,
|
||||
&index_offset,
|
||||
&upload_buffer);
|
||||
if (ret != PIPE_OK)
|
||||
goto done;
|
||||
|
||||
/* Don't need to worry about refcounting index_buffer as this is
|
||||
* just a stack variable without a counted reference of its own.
|
||||
* The caller holds the reference.
|
||||
*/
|
||||
index_buffer = upload_buffer;
|
||||
}
|
||||
/* We should never see user-space buffers in the driver. The vbuf
|
||||
* module should have converted them into real buffers.
|
||||
*/
|
||||
if (index_buffer)
|
||||
assert(!svga_buffer_is_user_buffer(index_buffer));
|
||||
|
||||
range.primType = hw_prim;
|
||||
range.primitiveCount = hw_count;
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@
|
|||
#include "util/u_inlines.h"
|
||||
#include "util/u_prim.h"
|
||||
#include "util/u_time.h"
|
||||
#include "util/u_upload_mgr.h"
|
||||
#include "indices/u_indices.h"
|
||||
|
||||
#include "svga_hw_reg.h"
|
||||
|
|
@ -42,179 +41,6 @@
|
|||
#include "svga_resource_buffer.h"
|
||||
|
||||
|
||||
/**
|
||||
* Determine the ranges to upload for the user-buffers referenced
|
||||
* by the next draw command.
|
||||
*
|
||||
* TODO: It might be beneficial to support multiple ranges. In that case,
|
||||
* the struct svga_buffer::uploaded member should be made an array or a
|
||||
* list, since we need to account for the possibility that different ranges
|
||||
* may be uploaded to different hardware buffers chosen by the utility
|
||||
* upload manager.
|
||||
*/
|
||||
static void
|
||||
svga_user_buffer_range(struct svga_context *svga,
|
||||
unsigned start,
|
||||
unsigned count,
|
||||
unsigned instance_count)
|
||||
{
|
||||
const struct pipe_vertex_element *ve = svga->curr.velems->velem;
|
||||
unsigned i;
|
||||
|
||||
/*
|
||||
* Release old uploaded range (if not done already) and
|
||||
* initialize new ranges.
|
||||
*/
|
||||
|
||||
for (i=0; i < svga->curr.velems->count; i++) {
|
||||
struct pipe_vertex_buffer *vb =
|
||||
&svga->curr.vb[ve[i].vertex_buffer_index];
|
||||
|
||||
if (vb->buffer && svga_buffer_is_user_buffer(vb->buffer)) {
|
||||
struct svga_buffer *buffer = svga_buffer(vb->buffer);
|
||||
|
||||
pipe_resource_reference(&buffer->uploaded.buffer, NULL);
|
||||
buffer->uploaded.start = ~0;
|
||||
buffer->uploaded.end = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i < svga->curr.velems->count; i++) {
|
||||
struct pipe_vertex_buffer *vb =
|
||||
&svga->curr.vb[ve[i].vertex_buffer_index];
|
||||
|
||||
if (vb->buffer && svga_buffer_is_user_buffer(vb->buffer)) {
|
||||
struct svga_buffer *buffer = svga_buffer(vb->buffer);
|
||||
unsigned first, size;
|
||||
unsigned instance_div = ve[i].instance_divisor;
|
||||
unsigned elemSize = util_format_get_blocksize(ve[i].src_format);
|
||||
|
||||
svga->dirty |= SVGA_NEW_VBUFFER;
|
||||
|
||||
if (instance_div) {
|
||||
first = ve[i].src_offset;
|
||||
count = (instance_count + instance_div - 1) / instance_div;
|
||||
size = vb->stride * (count - 1) + elemSize;
|
||||
} else {
|
||||
first = vb->stride * start + ve[i].src_offset;
|
||||
size = vb->stride * (count - 1) + elemSize;
|
||||
}
|
||||
|
||||
buffer->uploaded.start = MIN2(buffer->uploaded.start, first);
|
||||
buffer->uploaded.end = MAX2(buffer->uploaded.end, first + size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* svga_upload_user_buffers - upload parts of user buffers
|
||||
*
|
||||
* This function streams a part of a user buffer to hw and fills
|
||||
* svga_buffer::uploaded with information on the upload.
|
||||
*/
|
||||
static int
|
||||
svga_upload_user_buffers(struct svga_context *svga,
|
||||
unsigned start,
|
||||
unsigned count,
|
||||
unsigned instance_count)
|
||||
{
|
||||
const struct pipe_vertex_element *ve = svga->curr.velems->velem;
|
||||
unsigned i;
|
||||
int ret;
|
||||
|
||||
svga_user_buffer_range(svga, start, count, instance_count);
|
||||
|
||||
for (i=0; i < svga->curr.velems->count; i++) {
|
||||
struct pipe_vertex_buffer *vb =
|
||||
&svga->curr.vb[ve[i].vertex_buffer_index];
|
||||
|
||||
if (vb->buffer && svga_buffer_is_user_buffer(vb->buffer)) {
|
||||
struct svga_buffer *buffer = svga_buffer(vb->buffer);
|
||||
|
||||
/*
|
||||
* Check if already uploaded. Otherwise go ahead and upload.
|
||||
*/
|
||||
|
||||
if (buffer->uploaded.buffer)
|
||||
continue;
|
||||
|
||||
ret = u_upload_buffer( svga->upload_vb,
|
||||
0,
|
||||
buffer->uploaded.start,
|
||||
buffer->uploaded.end - buffer->uploaded.start,
|
||||
&buffer->b.b,
|
||||
&buffer->uploaded.offset,
|
||||
&buffer->uploaded.buffer);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (0)
|
||||
debug_printf("%s: %d: orig buf %p upl buf %p ofs %d sofs %d"
|
||||
" sz %d\n",
|
||||
__FUNCTION__,
|
||||
i,
|
||||
buffer,
|
||||
buffer->uploaded.buffer,
|
||||
buffer->uploaded.offset,
|
||||
buffer->uploaded.start,
|
||||
buffer->uploaded.end - buffer->uploaded.start);
|
||||
|
||||
vb->buffer_offset = buffer->uploaded.offset;
|
||||
}
|
||||
}
|
||||
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* svga_release_user_upl_buffers - release uploaded parts of user buffers
|
||||
*
|
||||
* This function releases the hw copy of the uploaded fraction of the
|
||||
* user-buffer. It's important to do this as soon as all draw calls
|
||||
* affecting the uploaded fraction are issued, as this allows for
|
||||
* efficient reuse of the hardware surface backing the uploaded fraction.
|
||||
*
|
||||
* svga_buffer::source_offset is set to 0, and svga_buffer::uploaded::buffer
|
||||
* is set to 0.
|
||||
*/
|
||||
static void
|
||||
svga_release_user_upl_buffers(struct svga_context *svga)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned nr;
|
||||
|
||||
nr = svga->curr.num_vertex_buffers;
|
||||
|
||||
for (i = 0; i < nr; ++i) {
|
||||
struct pipe_vertex_buffer *vb = &svga->curr.vb[i];
|
||||
|
||||
if (vb->buffer && svga_buffer_is_user_buffer(vb->buffer)) {
|
||||
struct svga_buffer *buffer = svga_buffer(vb->buffer);
|
||||
|
||||
/* The buffer_offset is relative to the uploaded buffer.
|
||||
* Since we're discarding that buffer we need to reset this offset
|
||||
* so it's not inadvertantly applied to a subsequent draw.
|
||||
*
|
||||
* XXX a root problem here is that the svga->curr.vb[] information
|
||||
* is getting set both by gallium API calls and by code in
|
||||
* svga_upload_user_buffers(). We should instead have two copies
|
||||
* of the vertex buffer information and choose between as needed.
|
||||
*/
|
||||
vb->buffer_offset = 0;
|
||||
|
||||
buffer->uploaded.start = ~0;
|
||||
buffer->uploaded.end = 0;
|
||||
if (buffer->uploaded.buffer)
|
||||
pipe_resource_reference(&buffer->uploaded.buffer, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static enum pipe_error
|
||||
retry_draw_range_elements( struct svga_context *svga,
|
||||
struct pipe_resource *index_buffer,
|
||||
|
|
@ -237,11 +63,6 @@ retry_draw_range_elements( struct svga_context *svga,
|
|||
svga->curr.rast->templ.flatshade,
|
||||
svga->curr.rast->templ.flatshade_first );
|
||||
|
||||
ret = svga_upload_user_buffers( svga, min_index + index_bias,
|
||||
max_index - min_index + 1, instance_count );
|
||||
if (ret != PIPE_OK)
|
||||
goto retry;
|
||||
|
||||
ret = svga_update_state( svga, SVGA_STATE_HW_DRAW );
|
||||
if (ret != PIPE_OK)
|
||||
goto retry;
|
||||
|
|
@ -288,11 +109,6 @@ retry_draw_arrays( struct svga_context *svga,
|
|||
svga->curr.rast->templ.flatshade,
|
||||
svga->curr.rast->templ.flatshade_first );
|
||||
|
||||
ret = svga_upload_user_buffers( svga, start, count, instance_count );
|
||||
|
||||
if (ret != PIPE_OK)
|
||||
goto retry;
|
||||
|
||||
ret = svga_update_state( svga, SVGA_STATE_HW_DRAW );
|
||||
if (ret != PIPE_OK)
|
||||
goto retry;
|
||||
|
|
@ -409,8 +225,6 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
|
|||
/* XXX: Silence warnings, do something sensible here? */
|
||||
(void)ret;
|
||||
|
||||
svga_release_user_upl_buffers( svga );
|
||||
|
||||
if (SVGA_DEBUG & DEBUG_FLUSH) {
|
||||
svga_hwtnl_flush_retry( svga );
|
||||
svga_context_flush(svga, NULL);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue