Commit 90b4045f authored by Keith Whitwell's avatar Keith Whitwell

wip

parent a80e33f4
This diff is collapsed.
......@@ -32,7 +32,7 @@
struct pipe_transfer;
#if 0
/**
* Clip tile against transfer dims.
* \return TRUE if tile is totally clipped, FALSE otherwise
......@@ -50,6 +50,7 @@ pipe_clip_tile(uint x, uint y, uint *w, uint *h, const struct pipe_transfer *pt)
*h = pt->height - y;
return FALSE;
}
#endif
#ifdef __cplusplus
extern "C" {
......
......@@ -291,22 +291,9 @@ struct pipe_context {
* \param level mipmap level.
* \return mask of PIPE_REFERENCED_FOR_READ/WRITE or PIPE_UNREFERENCED
*/
unsigned int (*is_texture_referenced)(struct pipe_context *pipe,
struct pipe_texture *texture,
unsigned face, unsigned level);
/**
* Check whether a buffer is referenced by an unflushed hw command.
* The state-tracker uses this function to avoid unnecessary flushes.
* It is safe (but wasteful) to always return
* PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE.
* \param pipe context whose unflushed hw commands will be checked.
* \param buf buffer to check.
* \return mask of PIPE_REFERENCED_FOR_READ/WRITE or PIPE_UNREFERENCED
*/
unsigned int (*is_buffer_referenced)(struct pipe_context *pipe,
struct pipe_buffer *buf);
unsigned int (*is_resource_referenced)(struct pipe_context *pipe,
struct pipe_resource *texture,
unsigned face, unsigned level);
/**
......@@ -315,24 +302,50 @@ struct pipe_context {
* Transfers are (by default) context-private and allow uploads to be
* interleaved with
*/
struct pipe_transfer *(*get_tex_transfer)(struct pipe_context *,
struct pipe_texture *texture,
unsigned face, unsigned level,
unsigned zslice,
enum pipe_transfer_usage usage,
unsigned x, unsigned y,
unsigned w, unsigned h);
void (*tex_transfer_destroy)(struct pipe_context *,
struct pipe_transfer *(*get_transfer)(struct pipe_context *,
struct pipe_resource *resource,
struct pipe_subresource,
enum pipe_transfer_usage,
const struct pipe_box *);
void (*transfer_destroy)(struct pipe_context *,
struct pipe_transfer *);
void *(*transfer_map)( struct pipe_context *,
struct pipe_transfer *transfer );
/* If transfer was created with WRITE|FLUSH_EXPLICIT, only the
* regions specified with this call are guaranteed to be written to
* the resource.
*/
void (*transfer_flush_region)( struct pipe_context *,
struct pipe_transfer *transfer,
const struct pipe_box *);
void (*transfer_unmap)( struct pipe_context *,
struct pipe_transfer *transfer );
/* One-shot transfer operation with data supplied in a user
* pointer. XXX: strides??
*/
void (*transfer_inline_write)( struct pipe_context *,
struct pipe_resource *,
struct pipe_subresource,
enum pipe_transfer_usage,
const struct pipe_box *,
const void *data );
/* One-shot read transfer operation with data returned in a user
* pointer. XXX: strides??
*/
void (*transfer_inline_read)( struct pipe_context *,
struct pipe_resource *,
struct pipe_subresource,
enum pipe_transfer_usage,
const struct pipe_box *,
void *data );
};
......
......@@ -137,10 +137,11 @@ enum pipe_error {
/** Texture types */
enum pipe_texture_target {
PIPE_TEXTURE_1D = 0,
PIPE_TEXTURE_2D = 1,
PIPE_TEXTURE_3D = 2,
PIPE_TEXTURE_CUBE = 3,
PIPE_BUFFER = 0,
PIPE_TEXTURE_1D = 1,
PIPE_TEXTURE_2D = 2,
PIPE_TEXTURE_3D = 3,
PIPE_TEXTURE_CUBE = 4,
PIPE_MAX_TEXTURE_TYPES
};
......@@ -208,10 +209,23 @@ enum pipe_texture_target {
* Transfer object usage flags
*/
enum pipe_transfer_usage {
/**
* Resource contents read back (or accessed directly) at transfer
* create time.
*/
PIPE_TRANSFER_READ = (1 << 0),
/**
* Resource contents will be written back at transfer_destroy
* time (or modified as a result of being accessed directly).
*/
PIPE_TRANSFER_WRITE = (1 << 1),
/** Read/modify/write */
/**
* Read/modify/write
*/
PIPE_TRANSFER_READ_WRITE = PIPE_TRANSFER_READ | PIPE_TRANSFER_WRITE,
/**
* The transfer should map the texture storage directly. The driver may
* return NULL if that isn't possible, and the state tracker needs to cope
......@@ -221,7 +235,54 @@ enum pipe_transfer_usage {
* does read/modify/write cycles on them directly, and a more complicated
* path which uses minimal read and write transfers.
*/
PIPE_TRANSFER_MAP_DIRECTLY = (1 << 2)
PIPE_TRANSFER_MAP_DIRECTLY = (1 << 2),
/**
* Discards the memory within the mapped region.
*
* It should not be used with PIPE_TRANSFER_CPU_READ.
*
* See also:
* - OpenGL's ARB_map_buffer_range extension, MAP_INVALIDATE_RANGE_BIT flag.
* - Direct3D's D3DLOCK_DISCARD flag.
*/
PIPE_TRANSFER_DISCARD = (1 << 8),
/**
* Fail if the resource cannot be mapped immediately.
*
* See also:
* - Direct3D's D3DLOCK_DONOTWAIT flag.
* - Mesa3D's MESA_MAP_NOWAIT_BIT flag.
* - WDDM's D3DDDICB_LOCKFLAGS.DonotWait flag.
*/
PIPE_TRANSFER_DONTBLOCK = (1 << 9),
/**
* Do not attempt to synchronize pending operations on the resource when mapping.
*
* It should not be used with PIPE_TRANSFER_CPU_READ.
*
* See also:
* - OpenGL's ARB_map_buffer_range extension, MAP_UNSYNCHRONIZED_BIT flag.
* - Direct3D's D3DLOCK_NOOVERWRITE flag.
* - WDDM's D3DDDICB_LOCKFLAGS.IgnoreSync flag.
*/
PIPE_TRANSFER_UNSYNCHRONIZED = (1 << 10),
PIPE_TRANSFER_NOOVERWRITE = (1 << 10), /* are these really the same?? */
/**
* Written ranges will be notified later with
* pipe_context::transfer_flush_region.
*
* It should not be used with PIPE_TRANSFER_CPU_READ.
*
* See also:
* - pipe_context::transfer_flush_region
* - OpenGL's ARB_map_buffer_range extension, MAP_FLUSH_EXPLICIT_BIT flag.
*/
PIPE_TRANSFER_FLUSH_EXPLICIT = (1 << 11),
};
......@@ -238,73 +299,6 @@ enum pipe_transfer_usage {
#define PIPE_BUFFER_USAGE_INDEX (1 << 6)
#define PIPE_BUFFER_USAGE_CONSTANT (1 << 7)
/*
* CPU access flags.
*
* These flags should only be used for texture transfers or when mapping
* buffers.
*
* Note that the PIPE_BUFFER_USAGE_CPU_xxx flags above are also used for
* mapping. Either PIPE_BUFFER_USAGE_CPU_READ or PIPE_BUFFER_USAGE_CPU_WRITE
* must be set.
*/
/**
* Discards the memory within the mapped region.
*
* It should not be used with PIPE_BUFFER_USAGE_CPU_READ.
*
* See also:
* - OpenGL's ARB_map_buffer_range extension, MAP_INVALIDATE_RANGE_BIT flag.
* - Direct3D's D3DLOCK_DISCARD flag.
*/
#define PIPE_BUFFER_USAGE_DISCARD (1 << 8)
/**
* Fail if the resource cannot be mapped immediately.
*
* See also:
* - Direct3D's D3DLOCK_DONOTWAIT flag.
* - Mesa3D's MESA_MAP_NOWAIT_BIT flag.
* - WDDM's D3DDDICB_LOCKFLAGS.DonotWait flag.
*/
#define PIPE_BUFFER_USAGE_DONTBLOCK (1 << 9)
/**
* Do not attempt to synchronize pending operations on the resource when mapping.
*
* It should not be used with PIPE_BUFFER_USAGE_CPU_READ.
*
* See also:
* - OpenGL's ARB_map_buffer_range extension, MAP_UNSYNCHRONIZED_BIT flag.
* - Direct3D's D3DLOCK_NOOVERWRITE flag.
* - WDDM's D3DDDICB_LOCKFLAGS.IgnoreSync flag.
*/
#define PIPE_BUFFER_USAGE_UNSYNCHRONIZED (1 << 10)
/**
* Written ranges will be notified later with
* pipe_screen::buffer_flush_mapped_range.
*
* It should not be used with PIPE_BUFFER_USAGE_CPU_READ.
*
* See also:
* - pipe_screen::buffer_flush_mapped_range
* - OpenGL's ARB_map_buffer_range extension, MAP_FLUSH_EXPLICIT_BIT flag.
*/
#define PIPE_BUFFER_USAGE_FLUSH_EXPLICIT (1 << 11)
/** Pipe driver custom usage flags should be greater or equal to this value */
#define PIPE_BUFFER_USAGE_CUSTOM (1 << 16)
/* Convenient shortcuts */
#define PIPE_BUFFER_USAGE_CPU_READ_WRITE \
( PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE )
#define PIPE_BUFFER_USAGE_GPU_READ_WRITE \
( PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE )
#define PIPE_BUFFER_USAGE_WRITE \
( PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_GPU_WRITE )
/**
* Flush types:
......
......@@ -56,6 +56,7 @@ struct pipe_fence_handle;
struct pipe_winsys;
struct pipe_buffer;
struct pipe_texture;
struct pipe_resource;
struct pipe_surface;
struct pipe_video_surface;
struct pipe_transfer;
......@@ -106,35 +107,35 @@ struct pipe_screen {
/**
* Create a new texture object, using the given template info.
*/
struct pipe_texture * (*texture_create)(struct pipe_screen *,
const struct pipe_texture *templat);
struct pipe_resource * (*resource_create)(struct pipe_screen *,
const struct pipe_resource *template);
/**
* Create a texture from a winsys_handle. The handle is often created in
* another process by first creating a pipe texture and then calling
* texture_get_handle.
*/
struct pipe_texture * (*texture_from_handle)(struct pipe_screen *,
const struct pipe_texture *templat,
struct winsys_handle *handle);
struct pipe_resource * (*resource_from_handle)(struct pipe_screen *,
const struct pipe_resource *template,
struct winsys_handle *handle);
/**
* Get a winsys_handle from a texture. Some platforms/winsys requires
* that the texture is created with a special usage flag like
* DISPLAYTARGET or PRIMARY.
*/
boolean (*texture_get_handle)(struct pipe_screen *,
struct pipe_texture *tex,
struct winsys_handle *handle);
boolean (*resource_get_handle)(struct pipe_screen *,
struct pipe_resource *tex,
struct winsys_handle *handle);
void (*texture_destroy)(struct pipe_texture *pt);
void (*resource_destroy)(struct pipe_resource *pt);
/** Get a 2D surface which is a "view" into a texture
* \param usage bitmaks of PIPE_BUFFER_USAGE_* read/write flags
*/
struct pipe_surface *(*get_tex_surface)(struct pipe_screen *,
struct pipe_texture *texture,
struct pipe_resource *resource,
unsigned face, unsigned level,
unsigned zslice,
unsigned usage );
......@@ -143,98 +144,6 @@ struct pipe_screen {
/**
* Create a new buffer.
* \param alignment buffer start address alignment in bytes
* \param usage bitmask of PIPE_BUFFER_USAGE_x
* \param size size in bytes
*/
struct pipe_buffer *(*buffer_create)( struct pipe_screen *screen,
unsigned alignment,
unsigned usage,
unsigned size );
/**
* Create a buffer that wraps user-space data.
*
* Effectively this schedules a delayed call to buffer_create
* followed by an upload of the data at *some point in the future*,
* or perhaps never. Basically the allocate/upload is delayed
* until the buffer is actually passed to hardware.
*
* The intention is to provide a quick way to turn regular data
* into a buffer, and secondly to avoid a copy operation if that
* data subsequently turns out to be only accessed by the CPU.
*
* Common example is OpenGL vertex buffers that are subsequently
* processed either by software TNL in the driver or by passing to
* hardware.
*
* XXX: What happens if the delayed call to buffer_create() fails?
*
* Note that ptr may be accessed at any time upto the time when the
* buffer is destroyed, so the data must not be freed before then.
*/
struct pipe_buffer *(*user_buffer_create)(struct pipe_screen *screen,
void *ptr,
unsigned bytes);
/**
* Map the entire data store of a buffer object into the client's address.
* flags is bitmask of PIPE_BUFFER_USAGE_CPU_READ/WRITE flags.
*/
void *(*buffer_map)( struct pipe_screen *screen,
struct pipe_buffer *buf,
unsigned usage );
/**
* Map a subrange of the buffer data store into the client's address space.
*
* The returned pointer is always relative to buffer start, regardless of
* the specified range. This is different from the ARB_map_buffer_range
* semantics because we don't forbid multiple mappings of the same buffer
* (yet).
*/
void *(*buffer_map_range)( struct pipe_screen *screen,
struct pipe_buffer *buf,
unsigned offset,
unsigned length,
unsigned usage);
/**
* Notify a range that was actually written into.
*
* Can only be used if the buffer was mapped with the
* PIPE_BUFFER_USAGE_CPU_WRITE and PIPE_BUFFER_USAGE_FLUSH_EXPLICIT flags
* set.
*
* The range is relative to the buffer start, regardless of the range
* specified to buffer_map_range. This is different from the
* ARB_map_buffer_range semantics because we don't forbid multiple mappings
* of the same buffer (yet).
*
*/
void (*buffer_flush_mapped_range)( struct pipe_screen *screen,
struct pipe_buffer *buf,
unsigned offset,
unsigned length);
/**
* Unmap buffer.
*
* If the buffer was mapped with PIPE_BUFFER_USAGE_CPU_WRITE flag but not
* PIPE_BUFFER_USAGE_FLUSH_EXPLICIT then the pipe driver will
* assume that the whole buffer was written. This is mostly for backward
* compatibility purposes and may affect performance -- the state tracker
* should always specify exactly what got written while the buffer was
* mapped.
*/
void (*buffer_unmap)( struct pipe_screen *screen,
struct pipe_buffer *buf );
void (*buffer_destroy)( struct pipe_buffer *buf );
/**
* Create a video surface suitable for use as a decoding target by the
* driver's pipe_video_context.
......
......@@ -71,19 +71,6 @@ struct pipe_reference
};
/**
* The driver will certainly subclass this to include actual memory
* management information.
*/
struct pipe_buffer
{
struct pipe_reference reference;
unsigned size;
struct pipe_screen *screen;
unsigned alignment;
unsigned usage;
};
/**
* Primitive (point/line/tri) rasterization info
......@@ -285,62 +272,86 @@ struct pipe_sampler_state
struct pipe_surface
{
struct pipe_reference reference;
struct pipe_resource *resource; /**< resource into which this is a view */
enum pipe_format format;
unsigned width; /**< logical width in pixels */
unsigned height; /**< logical height in pixels */
unsigned layout; /**< PIPE_SURFACE_LAYOUT_x */
unsigned offset; /**< offset from start of buffer, in bytes */
unsigned usage; /**< bitmask of PIPE_BUFFER_USAGE_x */
unsigned zslice;
struct pipe_texture *texture; /**< texture into which this is a view */
unsigned face;
unsigned level;
};
/**
* Transfer object. For data transfer to/from a texture.
*/
struct pipe_transfer
{
unsigned x; /**< x offset from start of texture image */
unsigned y; /**< y offset from start of texture image */
unsigned width; /**< logical width in pixels */
unsigned height; /**< logical height in pixels */
unsigned stride; /**< stride in bytes between rows of blocks */
enum pipe_transfer_usage usage; /**< PIPE_TRANSFER_* */
struct pipe_texture *texture; /**< texture to transfer to/from */
unsigned face;
unsigned level;
unsigned zslice;
struct pipe_resource *texture; /**< resource to transfer to/from */
unsigned stride;
unsigned slice_stride;
void *data;
};
/**
* Texture object.
*/
struct pipe_texture
{
struct pipe_reference reference;
#define PIPE_RESOURCE_BUFFER 1
#define PIPE_RESOURCE_TEXTURE 2
/* etc */
struct pipe_resource
{
struct pipe_reference reference;
struct pipe_screen *screen; /**< screen that this texture belongs to */
enum pipe_texture_target target; /**< PIPE_TEXTURE_x */
enum pipe_format format; /**< PIPE_FORMAT_x */
unsigned width0;
unsigned height0;
unsigned depth0;
unsigned last_level:8; /**< Index of last mipmap level present/defined */
unsigned nr_samples:8; /**< for multisampled surfaces, nr of samples */
unsigned usage; /* xxx: unify with tex_usage */
unsigned tex_usage; /**< bitmask of PIPE_TEXTURE_USAGE_* */
};
struct pipe_screen *screen; /**< screen that this texture belongs to */
/* Transition helpers:
*/
struct pipe_buffer {
struct pipe_resource base;
};
struct pipe_texture {
struct pipe_resource base;
};
struct pipe_subresource
{
unsigned face:16;
unsigned level:16;
};
struct pipe_box
{
unsigned x;
unsigned y;
unsigned z;
unsigned w;
unsigned h;
unsigned d;
};
/**
* A vertex buffer. Typically, all the vertex data/attributes for
......@@ -352,7 +363,7 @@ struct pipe_vertex_buffer
unsigned stride; /**< stride to same attrib in next vertex, in bytes */
unsigned max_index; /**< number of vertices in this buffer */
unsigned buffer_offset; /**< offset to start of data in buffer, in bytes */
struct pipe_buffer *buffer; /**< the actual buffer */
struct pipe_resource *buffer; /**< the actual buffer */
};
......
......@@ -63,7 +63,7 @@ struct pipe_video_context
/*@{*/
void (*decode_bitstream)(struct pipe_video_context *vpipe,
unsigned num_bufs,
struct pipe_buffer **bitstream_buf);
struct pipe_resource **bitstream_buf);
void (*decode_macroblocks)(struct pipe_video_context *vpipe,
struct pipe_video_surface *past,
......
......@@ -171,10 +171,10 @@ struct pipe_mpeg12_picture_desc
unsigned alternate_scan;
unsigned full_pel_forward_vector;
unsigned full_pel_backward_vector;
struct pipe_buffer *intra_quantizer_matrix;
struct pipe_buffer *non_intra_quantizer_matrix;
struct pipe_buffer *chroma_intra_quantizer_matrix;
struct pipe_buffer *chroma_non_intra_quantizer_matrix;
struct pipe_resource *intra_quantizer_matrix;
struct pipe_resource *non_intra_quantizer_matrix;
struct pipe_resource *chroma_intra_quantizer_matrix;
struct pipe_resource *chroma_non_intra_quantizer_matrix;
};
#endif
......
......@@ -264,15 +264,20 @@ ExaPrepareAccess(PixmapPtr pPix, int index)
assert(pPix->drawable.width <= priv->tex->width0);
assert(pPix->drawable.height <= priv->tex->height0);
u_box_wh(&box,
pPix->drawable.width,
pPix->drawable.height);
priv->map_transfer =
exa->pipe->get_tex_transfer(exa->pipe, priv->tex, 0, 0, 0,
exa->pipe->get_transfer(exa->pipe,
priv->tex,
u_subresource(0, 0),
#ifdef EXA_MIXED_PIXMAPS
PIPE_TRANSFER_MAP_DIRECTLY |
PIPE_TRANSFER_MAP_DIRECTLY |
#endif
PIPE_TRANSFER_READ_WRITE,
0, 0,
pPix->drawable.width,
pPix->drawable.height );
PIPE_TRANSFER_READ_WRITE,
&box );
if (!priv->map_transfer)
#ifdef EXA_MIXED_PIXMAPS
return FALSE;
......
......@@ -46,7 +46,7 @@
/**
* When doing GL render to texture, we have to be sure that finalize_texture()
* didn't yank out the pipe_texture that we earlier created a surface for.
* didn't yank out the pipe_resource that we earlier created a surface for.
* Check for that here and create a new surface if needed.
*/
static void
......@@ -54,29 +54,29 @@ update_renderbuffer_surface(struct st_context *st,
struct st_renderbuffer *strb)
{
struct pipe_screen *screen = st->pipe->screen;
struct pipe_texture *texture = strb->rtt->pt;
struct pipe_resource *resource = strb->rtt->pt;
int rtt_width = strb->Base.Width;
int rtt_height = strb->Base.Height;
if (!strb->surface ||
strb->surface->texture != texture ||
strb->surface->resource != resource ||
strb->surface->width != rtt_width ||
strb->surface->height != rtt_height) {
GLuint level;
/* find matching mipmap level size */
for (level = 0; level <= texture->last_level; level++) {
if (u_minify(texture->width0, level) == rtt_width &&
u_minify(texture->height0, level) == rtt_height) {
for (level = 0; level <= resource->last_level; level++) {
if (u_minify(resource->width0, level) == rtt_width &&
u_minify(resource->height0, level) == rtt_height) {
pipe_surface_reference(&strb->surface, NULL);
strb->surface = screen->get_tex_surface(screen,
texture,
strb->rtt_face,
level,
strb->rtt_slice,
PIPE_BUFFER_USAGE_GPU_READ |
PIPE_BUFFER_USAGE_GPU_WRITE);
resource,
strb->rtt_face,
level,
strb->rtt_slice,
PIPE_BUFFER_USAGE_GPU_READ |
PIPE_BUFFER_USAGE_GPU_WRITE);
#if 0
printf("-- alloc new surface %d x %d into tex %p\n",
strb->surface->width, strb->surface->height,
......
......@@ -112,11 +112,11 @@ make_state_key(GLcontext *ctx, struct state_key *key)
}
static struct pipe_texture *
static struct pipe_resource *
create_color_map_texture(GLcontext *ctx)
{
struct pipe_context *pipe = ctx->st->pipe;
struct pipe_texture *pt;
struct pipe_resource *pt;
enum pipe_format format;
const uint texSize = 256; /* simple, and usually perfect */