mesa/st: Remove internal flushes from Mesa state tracker.

Now that transfers are context operations it is the driver's
responsibility to ensure that transfers happen in order with all other
context operations, so flushes and finishes inside Mesa should be no
longer necessary. The attached patch implements that.

This should proportionate significant improvements for hardware drivers
which are able to stream transfers in the command buffers.

You can use the softpipe/llvmpipe_flush_resource() as reference
implementation of the worst case scenario, where the driver is not able
to streamline transfers. But the expectation is that driver
implementators will want to avoid flushing as much as possible.
This commit is contained in:
José Fonseca 2010-05-11 13:57:11 +01:00
parent d99a7497ed
commit b0427bedde
13 changed files with 29 additions and 248 deletions

View File

@ -44,7 +44,6 @@
#include "st_atom.h"
#include "st_atom_constbuf.h"
#include "st_program.h"
#include "st_inlines.h"
/**
@ -84,7 +83,7 @@ void st_upload_constants( struct st_context *st,
}
/* load Mesa constants into the constant buffer */
st_no_flush_pipe_buffer_write(st, *cbuf,
pipe_buffer_write(st->pipe, *cbuf,
0, paramBytes,
params->ParameterValues);

View File

@ -44,10 +44,10 @@
#include "st_context.h"
#include "st_format.h"
#include "st_texture.h"
#include "st_inlines.h"
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
#include "util/u_inlines.h"
#include "util/u_pack_color.h"
@ -149,7 +149,7 @@ load_color_map_texture(GLcontext *ctx, struct pipe_resource *pt)
uint *dest;
uint i, j;
transfer = st_cond_flush_get_tex_transfer(st_context(ctx),
transfer = pipe_get_transfer(st_context(ctx)->pipe,
pt, 0, 0, 0, PIPE_TRANSFER_WRITE,
0, 0, texSize, texSize);
dest = (uint *) pipe_transfer_map(pipe, transfer);

View File

@ -39,7 +39,6 @@
#include "st_cb_accum.h"
#include "st_cb_fbo.h"
#include "st_texture.h"
#include "st_inlines.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
@ -136,7 +135,7 @@ accum_accum(struct st_context *st, GLfloat value,
if (ST_DEBUG & DEBUG_FALLBACK)
debug_printf("%s: fallback processing\n", __FUNCTION__);
color_trans = st_cond_flush_get_tex_transfer(st,
color_trans = pipe_get_transfer(st->pipe,
color_strb->texture,
0, 0, 0,
PIPE_TRANSFER_READ, xpos, ypos,
@ -185,7 +184,7 @@ accum_load(struct st_context *st, GLfloat value,
if (ST_DEBUG & DEBUG_FALLBACK)
debug_printf("%s: fallback processing\n", __FUNCTION__);
color_trans = st_cond_flush_get_tex_transfer(st, color_strb->texture,
color_trans = pipe_get_transfer(st->pipe, color_strb->texture,
0, 0, 0,
PIPE_TRANSFER_READ, xpos, ypos,
width, height);
@ -241,7 +240,7 @@ accum_return(GLcontext *ctx, GLfloat value,
else
usage = PIPE_TRANSFER_WRITE;
color_trans = st_cond_flush_get_tex_transfer(st_context(ctx),
color_trans = pipe_get_transfer(st_context(ctx)->pipe,
color_strb->texture, 0, 0, 0,
usage,
xpos, ypos,
@ -301,9 +300,6 @@ st_Accum(GLcontext *ctx, GLenum op, GLfloat value)
if(!acc_strb->data)
return;
/* make sure color bufs aren't cached */
st_flush( st, PIPE_FLUSH_RENDER_CACHE, NULL );
switch (op) {
case GL_ADD:
if (value != 0.0F) {

View File

@ -43,7 +43,6 @@
#include "st_program.h"
#include "st_cb_bitmap.h"
#include "st_texture.h"
#include "st_inlines.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
@ -282,7 +281,7 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
return NULL;
}
transfer = st_no_flush_get_tex_transfer(st, pt, 0, 0, 0,
transfer = pipe_get_transfer(st->pipe, pt, 0, 0, 0,
PIPE_TRANSFER_WRITE,
0, 0, width, height);
@ -382,7 +381,7 @@ setup_bitmap_vertex_data(struct st_context *st,
}
/* put vertex data into vbuf */
st_no_flush_pipe_buffer_write_nooverlap(st,
pipe_buffer_write_nooverlap(st->pipe,
st->bitmap.vbuf,
st->bitmap.vbuf_slot * sizeof st->bitmap.vertices,
sizeof st->bitmap.vertices,
@ -579,7 +578,7 @@ create_cache_trans(struct st_context *st)
/* Map the texture transfer.
* Subsequent glBitmap calls will write into the texture image.
*/
cache->trans = st_no_flush_get_tex_transfer(st, cache->texture, 0, 0, 0,
cache->trans = pipe_get_transfer(st->pipe, cache->texture, 0, 0, 0,
PIPE_TRANSFER_WRITE, 0, 0,
BITMAP_CACHE_WIDTH,
BITMAP_CACHE_HEIGHT);

View File

@ -36,7 +36,6 @@
#include "main/arrayobj.h"
#include "main/bufferobj.h"
#include "st_inlines.h"
#include "st_context.h"
#include "st_cb_bufferobjects.h"
@ -204,7 +203,7 @@ st_bufferobj_data(GLcontext *ctx,
}
if (data)
st_no_flush_pipe_buffer_write(st_context(ctx), st_obj->buffer, 0,
pipe_buffer_write(st_context(ctx)->pipe, st_obj->buffer, 0,
size, data);
return GL_TRUE;
}

View File

@ -43,7 +43,6 @@
#include "st_cb_clear.h"
#include "st_cb_fbo.h"
#include "st_program.h"
#include "st_inlines.h"
#include "pipe/p_context.h"
#include "pipe/p_state.h"
@ -163,7 +162,7 @@ draw_quad(struct st_context *st,
}
/* put vertex data into vbuf */
st_no_flush_pipe_buffer_write_nooverlap(st, st->clear.vbuf,
pipe_buffer_write_nooverlap(st->pipe, st->clear.vbuf,
st->clear.vbuf_slot
* sizeof(st->clear.vertices),
sizeof(st->clear.vertices),

View File

@ -49,7 +49,6 @@
#include "st_cb_fbo.h"
#include "st_format.h"
#include "st_texture.h"
#include "st_inlines.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
@ -384,7 +383,7 @@ make_texture(struct st_context *st,
/* we'll do pixel transfer in a fragment shader */
ctx->_ImageTransferState = 0x0;
transfer = st_no_flush_get_tex_transfer(st, pt, 0, 0, 0,
transfer = pipe_get_transfer(st->pipe, pt, 0, 0, 0,
PIPE_TRANSFER_WRITE, 0, 0,
width, height);
@ -508,7 +507,7 @@ draw_quad(GLcontext *ctx, GLfloat x0, GLfloat y0, GLfloat z,
buf = pipe_buffer_create(pipe->screen,
PIPE_BIND_VERTEX_BUFFER,
sizeof(verts));
st_no_flush_pipe_buffer_write(st, buf, 0, sizeof(verts), verts);
pipe_buffer_write(st->pipe, buf, 0, sizeof(verts), verts);
util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_QUADS,
@ -685,7 +684,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
else
usage = PIPE_TRANSFER_WRITE;
pt = st_cond_flush_get_tex_transfer(st_context(ctx), strb->texture, 0, 0, 0,
pt = pipe_get_transfer(st_context(ctx)->pipe, strb->texture, 0, 0, 0,
usage, x, y,
width, height);
@ -885,7 +884,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
dsty = rbDraw->Base.Height - dsty - height;
}
ptDraw = st_cond_flush_get_tex_transfer(st_context(ctx),
ptDraw = pipe_get_transfer(st_context(ctx)->pipe,
rbDraw->texture, 0, 0, 0,
usage, dstx, dsty,
width, height);
@ -970,8 +969,6 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
GLint readX, readY, readW, readH;
struct gl_pixelstore_attrib pack = ctx->DefaultPacking;
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
st_validate_state(st);
if (type == GL_STENCIL) {
@ -1075,7 +1072,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
else {
/* CPU-based fallback/conversion */
struct pipe_transfer *ptRead =
st_cond_flush_get_tex_transfer(st, rbRead->texture, 0, 0, 0,
pipe_get_transfer(st->pipe, rbRead->texture, 0, 0, 0,
PIPE_TRANSFER_READ,
readX, readY, readW, readH);
struct pipe_transfer *ptTex;
@ -1089,7 +1086,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
else
transfer_usage = PIPE_TRANSFER_WRITE;
ptTex = st_cond_flush_get_tex_transfer(st, pt, 0, 0, 0, transfer_usage,
ptTex = pipe_get_transfer(st->pipe, pt, 0, 0, 0, transfer_usage,
0, 0, width, height);
/* copy image from ptRead surface to ptTex surface */

View File

@ -49,7 +49,6 @@
#include "st_cb_readpixels.h"
#include "st_cb_fbo.h"
#include "st_texture.h"
#include "st_inlines.h"
/**
* Special case for reading stencil buffer.
@ -75,7 +74,7 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
/* Create a read transfer from the renderbuffer's texture */
pt = st_cond_flush_get_tex_transfer(st_context(ctx), strb->texture,
pt = pipe_get_transfer(st_context(ctx)->pipe, strb->texture,
0, 0, 0,
PIPE_TRANSFER_READ, x, y,
width, height);
@ -231,7 +230,7 @@ st_fast_readpixels(GLcontext *ctx, struct st_renderbuffer *strb,
y = strb->texture->height0 - y - height;
}
trans = st_cond_flush_get_tex_transfer(st_context(ctx), strb->texture,
trans = pipe_get_transfer(st_context(ctx)->pipe, strb->texture,
0, 0, 0,
PIPE_TRANSFER_READ, x, y,
width, height);
@ -350,8 +349,6 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
if (!dest)
return;
st_flush(st, PIPE_FLUSH_RENDER_CACHE, NULL);
if (format == GL_STENCIL_INDEX ||
format == GL_DEPTH_STENCIL) {
st_read_stencil_pixels(ctx, x, y, width, height,
@ -395,7 +392,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
}
/* Create a read transfer from the renderbuffer's texture */
trans = st_cond_flush_get_tex_transfer(st_context(ctx), strb->texture,
trans = pipe_get_transfer(st_context(ctx)->pipe, strb->texture,
0, 0, 0,
PIPE_TRANSFER_READ, x, y,
width, height);

View File

@ -44,11 +44,11 @@
#include "state_tracker/st_debug.h"
#include "state_tracker/st_context.h"
#include "state_tracker/st_cb_fbo.h"
#include "state_tracker/st_cb_flush.h"
#include "state_tracker/st_cb_texture.h"
#include "state_tracker/st_format.h"
#include "state_tracker/st_texture.h"
#include "state_tracker/st_gen_mipmap.h"
#include "state_tracker/st_inlines.h"
#include "state_tracker/st_atom.h"
#include "pipe/p_context.h"
@ -464,7 +464,7 @@ compress_with_blit(GLcontext * ctx,
/* Put user's tex data into the temporary texture
*/
tex_xfer = st_cond_flush_get_tex_transfer(st_context(ctx), src_tex,
tex_xfer = pipe_get_transfer(st_context(ctx)->pipe, src_tex,
0, 0, 0, /* face, level are zero */
PIPE_TRANSFER_WRITE,
0, 0, width, height); /* x, y, w, h */
@ -875,7 +875,7 @@ decompress_with_blit(GLcontext * ctx, GLenum target, GLint level,
PIPE_TEX_MIPFILTER_NEAREST);
/* map the dst_surface so we can read from it */
tex_xfer = st_cond_flush_get_tex_transfer(st_context(ctx),
tex_xfer = pipe_get_transfer(st_context(ctx)->pipe,
dst_texture, 0, 0, 0,
PIPE_TRANSFER_READ,
0, 0, width, height);
@ -961,11 +961,6 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
/* Image is stored in hardware format in a buffer managed by the
* kernel. Need to explicitly map and unmap it.
*/
unsigned face = _mesa_tex_target_to_face(target);
st_teximage_flush_before_map(st, stImage->pt, face, level,
PIPE_TRANSFER_READ);
texImage->Data = st_texture_image_map(st, stImage, 0,
PIPE_TRANSFER_READ, 0, 0,
stImage->base.Width,
@ -1097,16 +1092,12 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level,
* from uploading the buffer under us.
*/
if (stImage->pt) {
unsigned face = _mesa_tex_target_to_face(target);
if (format == GL_DEPTH_COMPONENT &&
util_format_is_depth_and_stencil(stImage->pt->format))
transfer_usage = PIPE_TRANSFER_READ_WRITE;
else
transfer_usage = PIPE_TRANSFER_WRITE;
st_teximage_flush_before_map(st, stImage->pt, face, level,
transfer_usage);
texImage->Data = st_texture_image_map(st, stImage, zoffset,
transfer_usage,
xoffset, yoffset,
@ -1229,11 +1220,8 @@ st_CompressedTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
enum pipe_format pformat;
if (stImage->pt) {
unsigned face = _mesa_tex_target_to_face(target);
pformat = stImage->pt->format;
st_teximage_flush_before_map(st, stImage->pt, face, level,
PIPE_TRANSFER_WRITE);
texImage->Data = st_texture_image_map(st, stImage, 0,
PIPE_TRANSFER_WRITE,
xoffset, yoffset,
@ -1317,7 +1305,7 @@ fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level,
srcY = strb->Base.Height - srcY - height;
}
src_trans = st_cond_flush_get_tex_transfer( st_context(ctx),
src_trans = pipe_get_transfer(st_context(ctx)->pipe,
strb->texture,
0, 0, 0,
PIPE_TRANSFER_READ,
@ -1331,9 +1319,6 @@ fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level,
else
transfer_usage = PIPE_TRANSFER_WRITE;
st_teximage_flush_before_map(st, stImage->pt, 0, 0,
transfer_usage);
texDest = st_texture_image_map(st, stImage, 0, transfer_usage,
destX, destY, width, height);
@ -1515,9 +1500,6 @@ st_copy_texsubimage(GLcontext *ctx,
struct pipe_surface *dest_surface = NULL;
GLboolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP);
/* any rendering in progress must flushed before we grab the fb image */
st_flush(st, PIPE_FLUSH_RENDER_CACHE, NULL);
/* make sure finalize_textures has been called?
*/
if (0) st_validate_state(st);
@ -1784,11 +1766,6 @@ copy_image_data_to_texture(struct st_context *st,
pipe_resource_reference(&stImage->pt, NULL);
}
else if (stImage->base.Data) {
/* More straightforward upload.
*/
st_teximage_flush_before_map(st, stObj->pt, stImage->face, dstLevel,
PIPE_TRANSFER_WRITE);
st_texture_image_data(st,
stObj->pt,
stImage->face,

View File

@ -39,9 +39,9 @@
#include "st_debug.h"
#include "st_context.h"
#include "st_texture.h"
#include "st_gen_mipmap.h"
#include "st_cb_texture.h"
#include "st_inlines.h"
/**
@ -199,13 +199,13 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target,
ubyte *dstData;
int srcStride, dstStride;
srcTrans = st_cond_flush_get_tex_transfer(st_context(ctx), pt, face,
srcTrans = pipe_get_transfer(st_context(ctx)->pipe, pt, face,
srcLevel, zslice,
PIPE_TRANSFER_READ, 0, 0,
srcWidth, srcHeight);
dstTrans = st_cond_flush_get_tex_transfer(st_context(ctx), pt, face,
dstTrans = pipe_get_transfer(st_context(ctx)->pipe, pt, face,
dstLevel, zslice,
PIPE_TRANSFER_WRITE, 0, 0,
dstWidth, dstHeight);

View File

@ -1,159 +0,0 @@
/**************************************************************************
*
* Copyright 2009 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
/**
* Functions for checking if buffers/textures are referenced when we need
* to read/write from/to them. Flush when needed.
*/
#ifndef ST_INLINES_H
#define ST_INLINES_H
#include "pipe/p_context.h"
#include "pipe/p_screen.h"
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
#include "util/u_box.h"
#include "pipe/p_state.h"
#include "st_context.h"
#include "st_texture.h"
#include "st_cb_flush.h"
static INLINE struct pipe_transfer *
st_cond_flush_get_tex_transfer(struct st_context *st,
struct pipe_resource *pt,
unsigned int face,
unsigned int level,
unsigned int zslice,
enum pipe_transfer_usage usage,
unsigned int x, unsigned int y,
unsigned int w, unsigned int h)
{
struct pipe_context *context = st->pipe;
struct pipe_subresource subresource;
struct pipe_box box;
subresource.face = face;
subresource.level = level;
u_box_2d_zslice(x, y, zslice, w, h, &box);
st_teximage_flush_before_map(st, pt, face, level, usage);
return context->get_transfer(context,
pt,
subresource,
usage,
&box);
}
static INLINE struct pipe_transfer *
st_no_flush_get_tex_transfer(struct st_context *st,
struct pipe_resource *pt,
unsigned int face,
unsigned int level,
unsigned int zslice,
enum pipe_transfer_usage usage,
unsigned int x, unsigned int y,
unsigned int w, unsigned int h)
{
struct pipe_context *context = st->pipe;
struct pipe_box box;
struct pipe_subresource subresource = u_subresource( face, level );
u_box_2d_zslice( x, y, zslice,
w, h,
&box );
return context->get_transfer(context,
pt,
subresource,
usage,
&box);
}
static INLINE void
st_cond_flush_pipe_buffer_write(struct st_context *st,
struct pipe_resource *buf,
unsigned int offset,
unsigned int size,
const void * data)
{
struct pipe_context *pipe = st->pipe;
pipe_buffer_write(pipe, buf, offset, size, data);
}
static INLINE void
st_no_flush_pipe_buffer_write(struct st_context *st,
struct pipe_resource *buf,
unsigned int offset,
unsigned int size,
const void * data)
{
pipe_buffer_write(st->pipe, buf, offset, size, data);
}
static INLINE void
st_no_flush_pipe_buffer_write_nooverlap(struct st_context *st,
struct pipe_resource *buf,
unsigned int offset,
unsigned int size,
const void * data)
{
pipe_buffer_write_nooverlap(st->pipe, buf, offset, size, data);
}
static INLINE void
st_cond_flush_pipe_buffer_read(struct st_context *st,
struct pipe_resource *buf,
unsigned int offset,
unsigned int size,
void * data)
{
struct pipe_context *pipe = st->pipe;
if (pipe->is_resource_referenced(pipe, buf, 0, 0) & PIPE_REFERENCED_FOR_WRITE)
st_flush(st, PIPE_FLUSH_RENDER_CACHE, NULL);
pipe_buffer_read(pipe, buf, offset, size, data);
}
static INLINE void
st_no_flush_pipe_buffer_read(struct st_context *st,
struct pipe_resource *buf,
unsigned int offset,
unsigned int size,
void * data)
{
pipe_buffer_read(st->pipe, buf, offset, size, data);
}
#endif

View File

@ -29,7 +29,6 @@
#include "st_format.h"
#include "st_texture.h"
#include "st_cb_fbo.h"
#include "st_inlines.h"
#include "main/enums.h"
#undef Elements /* fix re-defined macro warning */
@ -145,7 +144,7 @@ st_texture_image_map(struct st_context *st, struct st_texture_image *stImage,
DBG("%s \n", __FUNCTION__);
stImage->transfer = st_no_flush_get_tex_transfer(st, pt, stImage->face,
stImage->transfer = pipe_get_transfer(st->pipe, pt, stImage->face,
stImage->level, zoffset,
usage, x, y, w, h);
@ -220,7 +219,7 @@ st_texture_image_data(struct st_context *st,
DBG("%s\n", __FUNCTION__);
for (i = 0; i < depth; i++) {
dst_transfer = st_no_flush_get_tex_transfer(st, dst, face, level, i,
dst_transfer = pipe_get_transfer(st->pipe, dst, face, level, i,
PIPE_TRANSFER_WRITE, 0, 0,
u_minify(dst->width0, level),
u_minify(dst->height0, level));
@ -320,19 +319,3 @@ st_texture_image_copy(struct pipe_context *pipe,
}
}
void
st_teximage_flush_before_map(struct st_context *st,
struct pipe_resource *pt,
unsigned int face,
unsigned int level,
enum pipe_transfer_usage usage)
{
struct pipe_context *pipe = st->pipe;
unsigned referenced =
pipe->is_resource_referenced(pipe, pt, face, level);
if (referenced && ((referenced & PIPE_REFERENCED_FOR_WRITE) ||
(usage & PIPE_TRANSFER_WRITE)))
st->pipe->flush(st->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
}

View File

@ -208,10 +208,4 @@ st_texture_image_copy(struct pipe_context *pipe,
struct pipe_resource *src, GLuint srcLevel,
GLuint face);
extern void
st_teximage_flush_before_map(struct st_context *st,
struct pipe_resource *pt,
unsigned int face,
unsigned int level,
enum pipe_transfer_usage usage);
#endif