summaryrefslogtreecommitdiff
path: root/src/gallium
diff options
context:
space:
mode:
authorKeith Whitwell <keithw@vmware.com>2010-03-14 20:59:36 +0000
committerKeith Whitwell <keithw@vmware.com>2010-03-14 20:59:36 +0000
commita79f6a4a0836fc64c07f9aeec21d914474fe3649 (patch)
tree401e15512f658cc3699dd96850ab091112c93429 /src/gallium
parent087fb54492fa5e3baf040c5efbf7dacd98a8849b (diff)
svga: convert to use pipe_resrource
As with others so far, a fairly shallow conversion.
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/svga/Makefile11
-rw-r--r--src/gallium/drivers/svga/svga_cmd.c11
-rw-r--r--src/gallium/drivers/svga/svga_context.c69
-rw-r--r--src/gallium/drivers/svga/svga_context.h2
-rw-r--r--src/gallium/drivers/svga/svga_draw.c15
-rw-r--r--src/gallium/drivers/svga/svga_draw_arrays.c12
-rw-r--r--src/gallium/drivers/svga/svga_draw_elements.c24
-rw-r--r--src/gallium/drivers/svga/svga_pipe_blit.c3
-rw-r--r--src/gallium/drivers/svga/svga_pipe_clear.c2
-rw-r--r--src/gallium/drivers/svga/svga_pipe_draw.c6
-rw-r--r--src/gallium/drivers/svga/svga_pipe_flush.c2
-rw-r--r--src/gallium/drivers/svga/svga_pipe_misc.c2
-rw-r--r--src/gallium/drivers/svga/svga_pipe_query.c2
-rw-r--r--src/gallium/drivers/svga/svga_pipe_sampler.c8
-rw-r--r--src/gallium/drivers/svga/svga_pipe_vertex.c8
-rw-r--r--src/gallium/drivers/svga/svga_resource.c202
-rw-r--r--src/gallium/drivers/svga/svga_resource.h43
-rw-r--r--src/gallium/drivers/svga/svga_resource_buffer.c354
-rw-r--r--src/gallium/drivers/svga/svga_resource_buffer.h (renamed from src/gallium/drivers/svga/svga_screen_buffer.h)35
-rw-r--r--src/gallium/drivers/svga/svga_resource_buffer_host.c2
-rw-r--r--src/gallium/drivers/svga/svga_resource_buffer_upload.c (renamed from src/gallium/drivers/svga/svga_screen_buffer.c)436
-rw-r--r--src/gallium/drivers/svga/svga_resource_buffer_upload.h54
-rw-r--r--src/gallium/drivers/svga/svga_resource_texture.c635
-rw-r--r--src/gallium/drivers/svga/svga_resource_texture.h (renamed from src/gallium/drivers/svga/svga_screen_texture.h)98
-rw-r--r--src/gallium/drivers/svga/svga_sampler_view.c198
-rw-r--r--src/gallium/drivers/svga/svga_sampler_view.h97
-rw-r--r--src/gallium/drivers/svga/svga_screen.c8
-rw-r--r--src/gallium/drivers/svga/svga_screen_texture.c1099
-rw-r--r--src/gallium/drivers/svga/svga_state_constants.c12
-rw-r--r--src/gallium/drivers/svga/svga_state_tss.c8
-rw-r--r--src/gallium/drivers/svga/svga_state_vdecl.c10
-rw-r--r--src/gallium/drivers/svga/svga_state_vs.c14
-rw-r--r--src/gallium/drivers/svga/svga_surface.c384
-rw-r--r--src/gallium/drivers/svga/svga_surface.h85
-rw-r--r--src/gallium/drivers/svga/svga_swtnl.h2
-rw-r--r--src/gallium/drivers/svga/svga_swtnl_backend.c33
-rw-r--r--src/gallium/drivers/svga/svga_swtnl_draw.c32
-rw-r--r--src/gallium/drivers/svga/svga_swtnl_private.h6
-rw-r--r--src/gallium/drivers/svga/svga_winsys.h8
39 files changed, 2150 insertions, 1882 deletions
diff --git a/src/gallium/drivers/svga/Makefile b/src/gallium/drivers/svga/Makefile
index f361908187..27287793bd 100644
--- a/src/gallium/drivers/svga/Makefile
+++ b/src/gallium/drivers/svga/Makefile
@@ -27,8 +27,6 @@ C_SOURCES = \
svga_pipe_vertex.c \
svga_pipe_vs.c \
svga_screen.c \
- svga_screen_buffer.c \
- svga_screen_texture.c \
svga_screen_cache.c \
svga_state.c \
svga_state_need_swtnl.c \
@@ -45,7 +43,14 @@ C_SOURCES = \
svga_tgsi.c \
svga_tgsi_decl_sm20.c \
svga_tgsi_decl_sm30.c \
- svga_tgsi_insn.c
+ svga_tgsi_insn.c \
+ svga_sampler_view.c \
+ svga_surface.c \
+ svga_resource.c \
+ svga_resource_texture.c \
+ svga_resource_buffer.c \
+ svga_resource_buffer_upload.c
+
LIBRARY_INCLUDES = \
-I$(TOP)/src/gallium/drivers/svga/include
diff --git a/src/gallium/drivers/svga/svga_cmd.c b/src/gallium/drivers/svga/svga_cmd.c
index 51dc5594a4..d58082cae3 100644
--- a/src/gallium/drivers/svga/svga_cmd.c
+++ b/src/gallium/drivers/svga/svga_cmd.c
@@ -31,8 +31,9 @@
*/
#include "svga_winsys.h"
-#include "svga_screen_buffer.h"
-#include "svga_screen_texture.h"
+#include "svga_resource_buffer.h"
+#include "svga_resource_texture.h"
+#include "svga_surface.h"
#include "svga_cmd.h"
/*
@@ -423,7 +424,7 @@ SVGA3D_SurfaceDMA(struct svga_winsys_context *swc,
const SVGA3dCopyBox *boxes, // IN
uint32 numBoxes) // IN
{
- struct svga_resource *resource = svga_texture(st->base.resource);
+ struct svga_texture *texture = svga_texture(st->base.resource);
SVGA3dCmdSurfaceDMA *cmd;
SVGA3dCmdSurfaceDMASuffix *pSuffix;
uint32 boxesSize = sizeof *boxes * numBoxes;
@@ -454,8 +455,8 @@ SVGA3D_SurfaceDMA(struct svga_winsys_context *swc,
cmd->guest.pitch = st->base.stride;
swc->surface_relocation(swc, &cmd->host.sid, texture->handle, surface_flags);
- cmd->host.face = st->base.face; /* PIPE_TEX_FACE_* and SVGA3D_CUBEFACE_* match */
- cmd->host.mipmap = st->base.level;
+ cmd->host.face = st->base.sr.face; /* PIPE_TEX_FACE_* and SVGA3D_CUBEFACE_* match */
+ cmd->host.mipmap = st->base.sr.level;
cmd->transfer = transfer;
diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c
index 3878a47e79..a6ffda0db6 100644
--- a/src/gallium/drivers/svga/svga_context.c
+++ b/src/gallium/drivers/svga/svga_context.c
@@ -34,8 +34,9 @@
#include "svga_context.h"
#include "svga_screen.h"
-#include "svga_screen_texture.h"
-#include "svga_screen_buffer.h"
+#include "svga_resource_texture.h"
+#include "svga_resource_buffer.h"
+#include "svga_resource.h"
#include "svga_winsys.h"
#include "svga_swtnl.h"
#include "svga_draw.h"
@@ -71,59 +72,6 @@ static void svga_destroy( struct pipe_context *pipe )
FREE( svga );
}
-static unsigned int
-svga_is_texture_referenced( struct pipe_context *pipe,
- struct pipe_texture *texture,
- unsigned face, unsigned level)
-{
- struct svga_texture *tex = svga_texture(texture);
- struct svga_screen *ss = svga_screen(pipe->screen);
-
- /**
- * The screen does not cache texture writes.
- */
-
- if (!tex->handle || ss->sws->surface_is_flushed(ss->sws, tex->handle))
- return PIPE_UNREFERENCED;
-
- /**
- * sws->surface_is_flushed() does not distinguish between read references
- * and write references. So assume a reference is both.
- */
-
- return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
-}
-
-static unsigned int
-svga_is_buffer_referenced( struct pipe_context *pipe,
- struct pipe_buffer *buf)
-
-{
- struct svga_screen *ss = svga_screen(pipe->screen);
- struct svga_buffer *sbuf = svga_buffer(buf);
-
- /**
- * XXX: Check this.
- * The screen may cache buffer writes, but when we map, we map out
- * of those cached writes, so we don't need to set a
- * PIPE_REFERENCED_FOR_WRITE flag for cached buffers.
- */
-
- if (!sbuf->handle || ss->sws->surface_is_flushed(ss->sws, sbuf->handle))
- return PIPE_UNREFERENCED;
-
- /**
- * sws->surface_is_flushed() does not distinguish between read references
- * and write references. So assume a reference is both,
- * however, we make an exception for index- and vertex buffers, to avoid
- * a flush in st_bufferobj_get_subdata, during display list replay.
- */
-
- if (sbuf->base.usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_INDEX))
- return PIPE_REFERENCED_FOR_READ;
-
- return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
-}
struct pipe_context *svga_context_create( struct pipe_screen *screen,
@@ -147,14 +95,7 @@ struct pipe_context *svga_context_create( struct pipe_screen *screen,
if(!svga->swc)
goto no_swc;
- /*
- svga->rm_context = rm_create_context( &svga->base,
- svgascreen->rm_screen,
- &svga_rm_context_callbacks );
svga_init_resource_functions(svga);
- */
- svga_init_texture_functions(&svga->pipe);
-
svga_init_blend_functions(svga);
svga_init_blit_functions(svga);
svga_init_depth_stencil_functions(svga);
@@ -187,14 +128,14 @@ 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.screen,
+ svga->upload_ib = u_upload_create( &svga->pipe,
32 * 1024,
16,
PIPE_BUFFER_USAGE_INDEX );
if (svga->upload_ib == NULL)
goto no_upload_ib;
- svga->upload_vb = u_upload_create( svga->pipe.screen,
+ svga->upload_vb = u_upload_create( &svga->pipe,
128 * 1024,
16,
PIPE_BUFFER_USAGE_VERTEX );
diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h
index d2ae3ea7cf..9a46de643f 100644
--- a/src/gallium/drivers/svga/svga_context.h
+++ b/src/gallium/drivers/svga/svga_context.h
@@ -254,7 +254,7 @@ struct svga_hw_clear_state
struct svga_hw_view_state
{
- struct pipe_texture *texture;
+ struct pipe_resource *texture;
struct svga_sampler_view *v;
unsigned min_lod;
unsigned max_lod;
diff --git a/src/gallium/drivers/svga/svga_draw.c b/src/gallium/drivers/svga/svga_draw.c
index c2107d7dce..efc84d56bd 100644
--- a/src/gallium/drivers/svga/svga_draw.c
+++ b/src/gallium/drivers/svga/svga_draw.c
@@ -34,8 +34,9 @@
#include "svga_draw_private.h"
#include "svga_debug.h"
#include "svga_screen.h"
-#include "svga_screen_buffer.h"
-#include "svga_screen_texture.h"
+#include "svga_resource_buffer.h"
+#include "svga_resource_texture.h"
+#include "svga_surface.h"
#include "svga_winsys.h"
#include "svga_cmd.h"
@@ -103,7 +104,7 @@ void svga_hwtnl_reset_vdecl( struct svga_hwtnl *hwtnl,
assert(hwtnl->cmd.prim_count == 0);
for (i = count; i < hwtnl->cmd.vdecl_count; i++) {
- pipe_buffer_reference(&hwtnl->cmd.vdecl_vb[i],
+ pipe_resource_reference(&hwtnl->cmd.vdecl_vb[i],
NULL);
}
@@ -209,7 +210,7 @@ svga_hwtnl_flush( struct svga_hwtnl *hwtnl )
&prim[i].indexArray.surfaceId,
ib_handle[i],
PIPE_BUFFER_USAGE_GPU_READ);
- pipe_buffer_reference(&hwtnl->cmd.prim_ib[i], NULL);
+ pipe_resource_reference(&hwtnl->cmd.prim_ib[i], NULL);
}
SVGA_FIFOCommitAll( swc );
@@ -240,7 +241,7 @@ enum pipe_error svga_hwtnl_prim( struct svga_hwtnl *hwtnl,
unsigned i;
for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
struct pipe_resource *vb = hwtnl->cmd.vdecl_vb[i];
- unsigned size = vb ? vb->size : 0;
+ unsigned size = vb ? vb->width0 : 0;
unsigned offset = hwtnl->cmd.vdecl[i].array.offset;
unsigned stride = hwtnl->cmd.vdecl[i].array.stride;
unsigned index_bias = range->indexBias;
@@ -323,7 +324,7 @@ enum pipe_error svga_hwtnl_prim( struct svga_hwtnl *hwtnl,
assert(range->indexWidth == range->indexArray.stride);
if(ib) {
- unsigned size = ib->size;
+ unsigned size = ib->width0;
unsigned offset = range->indexArray.offset;
unsigned stride = range->indexArray.stride;
unsigned count;
@@ -374,7 +375,7 @@ enum pipe_error svga_hwtnl_prim( struct svga_hwtnl *hwtnl,
hwtnl->cmd.prim[hwtnl->cmd.prim_count] = *range;
- pipe_buffer_reference(&hwtnl->cmd.prim_ib[hwtnl->cmd.prim_count], ib);
+ pipe_resource_reference(&hwtnl->cmd.prim_ib[hwtnl->cmd.prim_count], ib);
hwtnl->cmd.prim_count++;
return ret;
diff --git a/src/gallium/drivers/svga/svga_draw_arrays.c b/src/gallium/drivers/svga/svga_draw_arrays.c
index a7f58a6c0c..dc01a8c30a 100644
--- a/src/gallium/drivers/svga/svga_draw_arrays.c
+++ b/src/gallium/drivers/svga/svga_draw_arrays.c
@@ -98,7 +98,7 @@ static enum pipe_error retrieve_or_generate_indices( struct svga_hwtnl *hwtnl,
unsigned gen_nr,
unsigned gen_size,
u_generate_func generate,
- struct pipe_buffer **out_buf )
+ struct pipe_resource **out_buf )
{
enum pipe_error ret = PIPE_OK;
int i;
@@ -119,7 +119,7 @@ static enum pipe_error retrieve_or_generate_indices( struct svga_hwtnl *hwtnl,
}
else if (gen_type == U_GENERATE_REUSABLE)
{
- pipe_buffer_reference( &hwtnl->index_cache[prim][i].buffer,
+ pipe_resource_reference( &hwtnl->index_cache[prim][i].buffer,
NULL );
if (DBG)
@@ -151,7 +151,7 @@ static enum pipe_error retrieve_or_generate_indices( struct svga_hwtnl *hwtnl,
assert (smallest != IDX_CACHE_MAX);
- pipe_buffer_reference( &hwtnl->index_cache[prim][smallest].buffer,
+ pipe_resource_reference( &hwtnl->index_cache[prim][smallest].buffer,
NULL );
if (DBG)
@@ -173,7 +173,7 @@ static enum pipe_error retrieve_or_generate_indices( struct svga_hwtnl *hwtnl,
hwtnl->index_cache[prim][i].generate = generate;
hwtnl->index_cache[prim][i].gen_nr = gen_nr;
- pipe_buffer_reference( &hwtnl->index_cache[prim][i].buffer,
+ pipe_resource_reference( &hwtnl->index_cache[prim][i].buffer,
*out_buf );
if (DBG)
@@ -261,7 +261,7 @@ svga_hwtnl_draw_arrays( struct svga_hwtnl *hwtnl,
return simple_draw_arrays( hwtnl, gen_prim, start, count );
}
else {
- struct pipe_buffer *gen_buf = NULL;
+ struct pipe_resource *gen_buf = NULL;
/* Need to draw as indexed primitive.
* Potentially need to run the gen func to build an index buffer.
@@ -290,7 +290,7 @@ svga_hwtnl_draw_arrays( struct svga_hwtnl *hwtnl,
done:
if (gen_buf)
- pipe_buffer_reference( &gen_buf, NULL );
+ pipe_resource_reference( &gen_buf, NULL );
return ret;
}
diff --git a/src/gallium/drivers/svga/svga_draw_elements.c b/src/gallium/drivers/svga/svga_draw_elements.c
index eb625d42cb..e131686fd0 100644
--- a/src/gallium/drivers/svga/svga_draw_elements.c
+++ b/src/gallium/drivers/svga/svga_draw_elements.c
@@ -30,7 +30,7 @@
#include "svga_cmd.h"
#include "svga_draw.h"
#include "svga_draw_private.h"
-#include "svga_screen_buffer.h"
+#include "svga_resource_buffer.h"
#include "svga_winsys.h"
#include "svga_context.h"
@@ -39,22 +39,22 @@
static enum pipe_error
translate_indices( struct svga_hwtnl *hwtnl,
- struct pipe_buffer *src,
+ struct pipe_resource *src,
unsigned offset,
unsigned nr,
unsigned index_size,
u_translate_func translate,
- struct pipe_buffer **out_buf )
+ struct pipe_resource **out_buf )
{
struct pipe_context *pipe = &hwtnl->svga->pipe;
struct pipe_transfer *src_transfer = NULL;
struct pipe_transfer *dst_transfer = NULL;
unsigned size = index_size * nr;
const void *src_map = NULL;
- struct pipe_buffer *dst = NULL;
+ struct pipe_resource *dst = NULL;
void *dst_map = NULL;
- dst = pipe_buffer_create( screen, 32,
+ dst = pipe_buffer_create( pipe->screen, 32,
PIPE_BUFFER_USAGE_INDEX |
PIPE_BUFFER_USAGE_CPU_WRITE |
PIPE_BUFFER_USAGE_GPU_READ,
@@ -99,7 +99,7 @@ fail:
enum pipe_error
svga_hwtnl_simple_draw_range_elements( struct svga_hwtnl *hwtnl,
- struct pipe_buffer *index_buffer,
+ struct pipe_resource *index_buffer,
unsigned index_size,
unsigned min_index,
unsigned max_index,
@@ -108,7 +108,7 @@ svga_hwtnl_simple_draw_range_elements( struct svga_hwtnl *hwtnl,
unsigned count,
unsigned bias )
{
- struct pipe_buffer *upload_buffer = NULL;
+ struct pipe_resource *upload_buffer = NULL;
SVGA3dPrimitiveRange range;
unsigned hw_prim;
unsigned hw_count;
@@ -122,7 +122,7 @@ svga_hwtnl_simple_draw_range_elements( struct svga_hwtnl *hwtnl,
if (index_buffer &&
svga_buffer_is_user_buffer(index_buffer))
{
- assert( index_buffer->size >= index_offset + count * index_size );
+ assert( index_buffer->width0 >= index_offset + count * index_size );
ret = u_upload_buffer( hwtnl->upload_ib,
index_offset,
@@ -153,7 +153,7 @@ svga_hwtnl_simple_draw_range_elements( struct svga_hwtnl *hwtnl,
done:
if (upload_buffer)
- pipe_buffer_reference( &upload_buffer, NULL );
+ pipe_resource_reference( &upload_buffer, NULL );
return ret;
}
@@ -163,7 +163,7 @@ done:
enum pipe_error
svga_hwtnl_draw_range_elements( struct svga_hwtnl *hwtnl,
- struct pipe_buffer *index_buffer,
+ struct pipe_resource *index_buffer,
unsigned index_size,
unsigned min_index,
unsigned max_index,
@@ -211,7 +211,7 @@ svga_hwtnl_draw_range_elements( struct svga_hwtnl *hwtnl,
gen_prim, start, count, bias );
}
else {
- struct pipe_buffer *gen_buf = NULL;
+ struct pipe_resource *gen_buf = NULL;
/* Need to allocate a new index buffer and run the translate
* func to populate it. Could potentially cache this translated
@@ -244,7 +244,7 @@ svga_hwtnl_draw_range_elements( struct svga_hwtnl *hwtnl,
done:
if (gen_buf)
- pipe_buffer_reference( &gen_buf, NULL );
+ pipe_resource_reference( &gen_buf, NULL );
return ret;
}
diff --git a/src/gallium/drivers/svga/svga_pipe_blit.c b/src/gallium/drivers/svga/svga_pipe_blit.c
index 4f575b06e6..889da29e28 100644
--- a/src/gallium/drivers/svga/svga_pipe_blit.c
+++ b/src/gallium/drivers/svga/svga_pipe_blit.c
@@ -23,10 +23,11 @@
*
**********************************************************/
-#include "svga_screen_texture.h"
+#include "svga_resource_texture.h"
#include "svga_context.h"
#include "svga_debug.h"
#include "svga_cmd.h"
+#include "svga_surface.h"
#define FILE_DEBUG_FLAG DEBUG_BLIT
diff --git a/src/gallium/drivers/svga/svga_pipe_clear.c b/src/gallium/drivers/svga/svga_pipe_clear.c
index 8483a3fad7..b88425bb15 100644
--- a/src/gallium/drivers/svga/svga_pipe_clear.c
+++ b/src/gallium/drivers/svga/svga_pipe_clear.c
@@ -31,7 +31,7 @@
#include "svga_context.h"
#include "svga_state.h"
-#include "svga_screen_texture.h"
+#include "svga_surface.h"
static enum pipe_error
diff --git a/src/gallium/drivers/svga/svga_pipe_draw.c b/src/gallium/drivers/svga/svga_pipe_draw.c
index f00cf23935..a05272b2e4 100644
--- a/src/gallium/drivers/svga/svga_pipe_draw.c
+++ b/src/gallium/drivers/svga/svga_pipe_draw.c
@@ -42,7 +42,7 @@
static enum pipe_error
retry_draw_range_elements( struct svga_context *svga,
- struct pipe_buffer *index_buffer,
+ struct pipe_resource *index_buffer,
unsigned index_size,
unsigned min_index,
unsigned max_index,
@@ -150,7 +150,7 @@ retry:
static void
svga_draw_range_elements( struct pipe_context *pipe,
- struct pipe_buffer *index_buffer,
+ struct pipe_resource *index_buffer,
unsigned index_size,
unsigned min_index,
unsigned max_index,
@@ -224,7 +224,7 @@ svga_draw_range_elements( struct pipe_context *pipe,
static void
svga_draw_elements( struct pipe_context *pipe,
- struct pipe_buffer *index_buffer,
+ struct pipe_resource *index_buffer,
unsigned index_size,
unsigned prim, unsigned start, unsigned count)
{
diff --git a/src/gallium/drivers/svga/svga_pipe_flush.c b/src/gallium/drivers/svga/svga_pipe_flush.c
index 7fa2205ae5..ab243aa6ec 100644
--- a/src/gallium/drivers/svga/svga_pipe_flush.c
+++ b/src/gallium/drivers/svga/svga_pipe_flush.c
@@ -25,7 +25,7 @@
#include "pipe/p_defines.h"
#include "svga_screen.h"
-#include "svga_screen_texture.h"
+#include "svga_surface.h"
#include "svga_context.h"
#include "svga_debug.h"
diff --git a/src/gallium/drivers/svga/svga_pipe_misc.c b/src/gallium/drivers/svga/svga_pipe_misc.c
index 95bf0e6f91..b27a92a2d6 100644
--- a/src/gallium/drivers/svga/svga_pipe_misc.c
+++ b/src/gallium/drivers/svga/svga_pipe_misc.c
@@ -28,7 +28,7 @@
#include "util/u_inlines.h"
#include "svga_context.h"
-#include "svga_screen_texture.h"
+#include "svga_surface.h"
static void svga_set_scissor_state( struct pipe_context *pipe,
diff --git a/src/gallium/drivers/svga/svga_pipe_query.c b/src/gallium/drivers/svga/svga_pipe_query.c
index 08283e3731..04397790b4 100644
--- a/src/gallium/drivers/svga/svga_pipe_query.c
+++ b/src/gallium/drivers/svga/svga_pipe_query.c
@@ -30,7 +30,7 @@
#include "svga_cmd.h"
#include "svga_context.h"
#include "svga_screen.h"
-#include "svga_screen_buffer.h"
+#include "svga_resource_buffer.h"
#include "svga_winsys.h"
#include "svga_debug.h"
diff --git a/src/gallium/drivers/svga/svga_pipe_sampler.c b/src/gallium/drivers/svga/svga_pipe_sampler.c
index 82d525ca33..f44a0e1325 100644
--- a/src/gallium/drivers/svga/svga_pipe_sampler.c
+++ b/src/gallium/drivers/svga/svga_pipe_sampler.c
@@ -30,7 +30,7 @@
#include "tgsi/tgsi_parse.h"
#include "svga_context.h"
-#include "svga_screen_texture.h"
+#include "svga_resource_texture.h"
#include "svga_debug.h"
@@ -178,7 +178,7 @@ static void svga_delete_sampler_state(struct pipe_context *pipe,
static struct pipe_sampler_view *
svga_create_sampler_view(struct pipe_context *pipe,
- struct pipe_texture *texture,
+ struct pipe_resource *texture,
const struct pipe_sampler_view *templ)
{
struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
@@ -187,7 +187,7 @@ svga_create_sampler_view(struct pipe_context *pipe,
*view = *templ;
view->reference.count = 1;
view->texture = NULL;
- pipe_texture_reference(&view->texture, texture);
+ pipe_resource_reference(&view->texture, texture);
view->context = pipe;
}
@@ -199,7 +199,7 @@ static void
svga_sampler_view_destroy(struct pipe_context *pipe,
struct pipe_sampler_view *view)
{
- pipe_texture_reference(&view->texture, NULL);
+ pipe_resource_reference(&view->texture, NULL);
FREE(view);
}
diff --git a/src/gallium/drivers/svga/svga_pipe_vertex.c b/src/gallium/drivers/svga/svga_pipe_vertex.c
index 1715a47fc6..23808ad08e 100644
--- a/src/gallium/drivers/svga/svga_pipe_vertex.c
+++ b/src/gallium/drivers/svga/svga_pipe_vertex.c
@@ -30,7 +30,7 @@
#include "tgsi/tgsi_parse.h"
#include "svga_screen.h"
-#include "svga_screen_buffer.h"
+#include "svga_resource_buffer.h"
#include "svga_context.h"
@@ -49,13 +49,13 @@ static void svga_set_vertex_buffers(struct pipe_context *pipe,
/* Adjust refcounts */
for (i = 0; i < count; i++) {
- pipe_buffer_reference(&svga->curr.vb[i].buffer, buffers[i].buffer);
+ pipe_resource_reference(&svga->curr.vb[i].buffer, buffers[i].buffer);
if (svga_buffer_is_user_buffer(buffers[i].buffer))
any_user_buffer = TRUE;
}
for ( ; i < svga->curr.num_vertex_buffers; i++)
- pipe_buffer_reference(&svga->curr.vb[i].buffer, NULL);
+ pipe_resource_reference(&svga->curr.vb[i].buffer, NULL);
/* Copy remaining data */
memcpy(svga->curr.vb, buffers, count * sizeof buffers[0]);
@@ -102,7 +102,7 @@ void svga_cleanup_vertex_state( struct svga_context *svga )
unsigned i;
for (i = 0 ; i < svga->curr.num_vertex_buffers; i++)
- pipe_buffer_reference(&svga->curr.vb[i].buffer, NULL);
+ pipe_resource_reference(&svga->curr.vb[i].buffer, NULL);
}
diff --git a/src/gallium/drivers/svga/svga_resource.c b/src/gallium/drivers/svga/svga_resource.c
index 89c41af0ac..15258c1966 100644
--- a/src/gallium/drivers/svga/svga_resource.c
+++ b/src/gallium/drivers/svga/svga_resource.c
@@ -1,191 +1,55 @@
-/**********************************************************
- * Copyright 2008-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, sublicense, 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 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
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * 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.
- *
- **********************************************************/
+#include "util/u_debug.h"
-#include "svga_cmd.h"
-
-#include "pipe/p_state.h"
-#include "pipe/p_defines.h"
-#include "util/u_inlines.h"
-#include "os/os_thread.h"
-#include "util/u_format.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-
-#include "svga_screen.h"
+#include "svga_resource.h"
+#include "svga_resource_buffer.h"
+#include "svga_resource_texture.h"
#include "svga_context.h"
-#include "svga_screen_texture.h"
-#include "svga_screen_buffer.h"
-#include "svga_winsys.h"
-#include "svga_debug.h"
-#include "svga_screen_buffer.h"
+#include "svga_screen.h"
-#include <util/u_string.h>
-/* Use the pipe resource_manager module to implemen the new-style
- * driver functions in terms of the old ones we have already.
- */
static struct pipe_resource *
svga_resource_create(struct pipe_screen *screen,
- const struct pipe_resource *template)
-{
- struct svga_screen *ss = svga_screen(screen);
- return rm_resource_create(ss->rm_screen,
- template);
-}
-
-static struct pipe_resource *
-svga_resource_from_handle(struct pipe_screen *screen,
- const struct pipe_resource *template,
- struct winsys_handle *handle)
+ const struct pipe_resource *template)
{
- struct svga_screen *ss = svga_screen(screen);
- return rm_resource_from_handle(ss->rm_screen,
- template,
- handle);
-}
+ if (template->target == PIPE_BUFFER)
+ return svga_buffer_create(screen, template);
+ else
+ return svga_resource_create(screen, template);
-boolean svga_resource_get_handle(struct pipe_screen *screen,
- struct pipe_resource *resource,
- struct winsys_handle *handle)
-{
- struct svga_screen *ss = svga_screen(screen);
- return rm_resource_get_handle(ss->rm_screen,
- resource,
- handle);
}
-
-void svga_resource_destroy(struct pipe_screen *screen,
- struct pipe_resource *resource)
-{
- struct svga_screen *ss = svga_screen(screen);
- rm_resource_destroy(ss->rm_screen,
- resource);
-
-}
-
-struct pipe_transfer *svga_get_transfer(struct pipe_context *pipe,
- struct pipe_resource *resource,
- struct pipe_subresource sr,
- enum pipe_transfer_usage usage,
- const struct pipe_box *box)
-{
- struct svga_context *sc = svga_context(pipe);
- return rm_get_transfer(sc->rm_context,
- resource,
- sr,
- usage,
- box);
-}
-
-void svga_transfer_destroy(struct pipe_context *pipe,
- struct pipe_transfer *transfer)
-{
- struct svga_context *sc = svga_context(pipe);
- rm_transfer_destroy(sc->rm_context,
- transfer);
-}
-
-void *svga_transfer_map( struct pipe_context *pipe,
- struct pipe_transfer *transfer )
-{
- struct svga_context *sc = svga_context(pipe);
- return rm_transfer_map(sc->rm_context,
- transfer);
-}
-
-void svga_transfer_flush_region( struct pipe_context *pipe,
- struct pipe_transfer *transfer,
- const struct pipe_box *box )
-{
- struct svga_context *sc = svga_context(pipe);
- rm_transfer_flush_region(sc->rm_context,
- transfer,
- box);
-}
-
-void svga_transfer_unmap( struct pipe_context *pipe,
- struct pipe_transfer *transfer )
+static struct pipe_resource *
+svga_resource_from_handle(struct pipe_screen * screen,
+ const struct pipe_resource *template,
+ struct winsys_handle *whandle)
{
- struct svga_context *sc = svga_context(pipe);
- rm_transfer_unmap(sc->rm_context,
- transfer);
+ if (template->target == PIPE_BUFFER)
+ return NULL;
+ else
+ return svga_resource_from_handle(screen, template, whandle);
}
-void svga_transfer_inline_write( struct pipe_context *pipe,
- struct pipe_resource *resource,
- struct pipe_subresource sr,
- enum pipe_transfer_usage usage,
- const struct pipe_box *box,
- const void *data )
-{
- struct svga_context *sc = svga_context(pipe);
- rm_transfer_inline_write(sc->rm_context,
- resource,
- sr,
- usage,
- box,
- data);
-}
-
-void svga_transfer_inline_read( struct pipe_context *pipe,
- struct pipe_resource *resource,
- struct pipe_subresource sr,
- enum pipe_transfer_usage usage,
- const struct pipe_box *box,
- void *data )
+void
+svga_init_resource_functions(struct svga_context *svga)
{
- struct svga_context *sc = svga_context(pipe);
- rm_transfer_inline_read(sc->rm_context,
- resource,
- sr,
- usage,
- box,
- data);
+ svga->pipe.get_transfer = u_get_transfer_vtbl;
+ svga->pipe.transfer_map = u_transfer_map_vtbl;
+ svga->pipe.transfer_flush_region = u_transfer_flush_region_vtbl;
+ svga->pipe.transfer_unmap = u_transfer_unmap_vtbl;
+ svga->pipe.transfer_destroy = u_transfer_destroy_vtbl;
+ svga->pipe.transfer_inline_write = u_transfer_inline_write_vtbl;
}
-
-
void
-svga_init_resource_functions(struct pipe_context *pipe)
+svga_init_screen_resource_functions(struct svga_screen *is)
{
- pipe->get_transfer = svga_get_transfer;
- pipe->transfer_map = svga_transfer_map;
- pipe->transfer_unmap = svga_transfer_unmap;
- pipe->transfer_destroy = svga_transfer_destroy;
+ is->screen.resource_create = svga_resource_create;
+ is->screen.resource_from_handle = svga_resource_from_handle;
+ is->screen.resource_get_handle = u_resource_get_handle_vtbl;
+ is->screen.resource_destroy = u_resource_destroy_vtbl;
+ is->screen.user_buffer_create = svga_user_buffer_create;
}
-void
-svga_screen_init_resource_functions(struct pipe_screen *screen)
-{
- screen->texture_create = svga_texture_create;
- screen->texture_from_handle = svga_screen_texture_from_handle;
- screen->texture_get_handle = svga_screen_texture_get_handle;
- screen->texture_destroy = svga_texture_destroy;
- screen->get_tex_surface = svga_get_tex_surface;
- screen->tex_surface_destroy = svga_tex_surface_destroy;
-}
+
diff --git a/src/gallium/drivers/svga/svga_resource.h b/src/gallium/drivers/svga/svga_resource.h
new file mode 100644
index 0000000000..851e3b50ce
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_resource.h
@@ -0,0 +1,43 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#ifndef SVGA_RESOURCE_H
+#define SVGA_RESOURCE_H
+
+struct svga_screen;
+
+#include "util/u_debug.h"
+
+struct svga_context;
+struct svga_screen;
+
+
+void svga_init_screen_resource_functions(struct svga_screen *is);
+void svga_init_resource_functions(struct svga_context *svga );
+
+
+#endif /* SVGA_RESOURCE_H */
diff --git a/src/gallium/drivers/svga/svga_resource_buffer.c b/src/gallium/drivers/svga/svga_resource_buffer.c
new file mode 100644
index 0000000000..b35abc007e
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_resource_buffer.c
@@ -0,0 +1,354 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+#include "svga_cmd.h"
+
+#include "pipe/p_state.h"
+#include "pipe/p_defines.h"
+#include "util/u_inlines.h"
+#include "os/os_thread.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
+#include "svga_context.h"
+#include "svga_screen.h"
+#include "svga_resource_buffer.h"
+#include "svga_resource_buffer_upload.h"
+#include "svga_winsys.h"
+#include "svga_debug.h"
+
+
+/**
+ * Vertex and index buffers need hardware backing. Constant buffers
+ * do not. No other types of buffers currently supported.
+ */
+static INLINE boolean
+svga_buffer_needs_hw_storage(unsigned usage)
+{
+ return usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_INDEX);
+}
+
+
+static unsigned int
+svga_buffer_is_referenced( struct pipe_context *pipe,
+ struct pipe_resource *buf,
+ unsigned face, unsigned level)
+{
+ struct svga_screen *ss = svga_screen(pipe->screen);
+ struct svga_buffer *sbuf = svga_buffer(buf);
+
+ /**
+ * XXX: Check this.
+ * The screen may cache buffer writes, but when we map, we map out
+ * of those cached writes, so we don't need to set a
+ * PIPE_REFERENCED_FOR_WRITE flag for cached buffers.
+ */
+
+ if (!sbuf->handle || ss->sws->surface_is_flushed(ss->sws, sbuf->handle))
+ return PIPE_UNREFERENCED;
+
+ /**
+ * sws->surface_is_flushed() does not distinguish between read references
+ * and write references. So assume a reference is both,
+ * however, we make an exception for index- and vertex buffers, to avoid
+ * a flush in st_bufferobj_get_subdata, during display list replay.
+ */
+
+ if (sbuf->b.b.usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_INDEX))
+ return PIPE_REFERENCED_FOR_READ;
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+
+
+
+
+
+static void *
+svga_buffer_map_range( struct pipe_screen *screen,
+ struct pipe_resource *buf,
+ unsigned offset,
+ unsigned length,
+ unsigned usage )
+{
+ struct svga_screen *ss = svga_screen(screen);
+ struct svga_winsys_screen *sws = ss->sws;
+ struct svga_buffer *sbuf = svga_buffer( buf );
+ void *map;
+
+ if (!sbuf->swbuf && !sbuf->hwbuf) {
+ if (svga_buffer_create_hw_storage(ss, sbuf) != PIPE_OK) {
+ /*
+ * We can't create a hardware buffer big enough, so create a malloc
+ * buffer instead.
+ */
+ debug_printf("%s: failed to allocate %u KB of DMA, splitting DMA transfers\n",
+ __FUNCTION__,
+ (sbuf->b.b.width0 + 1023)/1024);
+
+ sbuf->swbuf = align_malloc(sbuf->b.b.width0, 16);
+ }
+ }
+
+ if (sbuf->swbuf) {
+ /* User/malloc buffer */
+ map = sbuf->swbuf;
+ }
+ else if (sbuf->hwbuf) {
+ map = sws->buffer_map(sws, sbuf->hwbuf, usage);
+ }
+ else {
+ map = NULL;
+ }
+
+ if(map) {
+ pipe_mutex_lock(ss->swc_mutex);
+
+ ++sbuf->map.count;
+
+ if (usage & PIPE_TRANSFER_WRITE) {
+ assert(sbuf->map.count <= 1);
+ sbuf->map.writing = TRUE;
+ if (usage & PIPE_TRANSFER_FLUSH_EXPLICIT)
+ sbuf->map.flush_explicit = TRUE;
+ }
+
+ pipe_mutex_unlock(ss->swc_mutex);
+ }
+
+ return map;
+}
+
+
+
+static void
+svga_buffer_flush_mapped_range( struct pipe_screen *screen,
+ struct pipe_resource *buf,
+ unsigned offset, unsigned length)
+{
+ struct svga_buffer *sbuf = svga_buffer( buf );
+ struct svga_screen *ss = svga_screen(screen);
+
+ pipe_mutex_lock(ss->swc_mutex);
+ assert(sbuf->map.writing);
+ if(sbuf->map.writing) {
+ assert(sbuf->map.flush_explicit);
+ svga_buffer_add_range(sbuf, offset, offset + length);
+ }
+ pipe_mutex_unlock(ss->swc_mutex);
+}
+
+static void
+svga_buffer_unmap( struct pipe_screen *screen,
+ struct pipe_resource *buf)
+{
+ struct svga_screen *ss = svga_screen(screen);
+ struct svga_winsys_screen *sws = ss->sws;
+ struct svga_buffer *sbuf = svga_buffer( buf );
+
+ pipe_mutex_lock(ss->swc_mutex);
+
+ assert(sbuf->map.count);
+ if(sbuf->map.count)
+ --sbuf->map.count;
+
+ if(sbuf->hwbuf)
+ sws->buffer_unmap(sws, sbuf->hwbuf);
+
+ if(sbuf->map.writing) {
+ if(!sbuf->map.flush_explicit) {
+ /* No mapped range was flushed -- flush the whole buffer */
+ SVGA_DBG(DEBUG_DMA, "flushing the whole buffer\n");
+
+ svga_buffer_add_range(sbuf, 0, sbuf->b.b.width0);
+ }
+
+ sbuf->map.writing = FALSE;
+ sbuf->map.flush_explicit = FALSE;
+ }
+
+ pipe_mutex_unlock(ss->swc_mutex);
+}
+
+
+
+static void
+svga_buffer_destroy( struct pipe_screen *screen,
+ struct pipe_resource *buf )
+{
+ struct svga_screen *ss = svga_screen(screen);
+ struct svga_buffer *sbuf = svga_buffer( buf );
+
+ assert(!p_atomic_read(&buf->reference.count));
+
+ assert(!sbuf->dma.pending);
+
+ if(sbuf->handle)
+ svga_buffer_destroy_host_surface(ss, sbuf);
+
+ if(sbuf->uploaded.buffer)
+ pipe_resource_reference(&sbuf->uploaded.buffer, NULL);
+
+ if(sbuf->hwbuf)
+ svga_buffer_destroy_hw_storage(ss, sbuf);
+
+ if(sbuf->swbuf && !sbuf->user)
+ align_free(sbuf->swbuf);
+
+ FREE(sbuf);
+}
+
+
+/* Keep the original code more or less intact, implement transfers in
+ * terms of the old functions.
+ */
+static void *
+svga_buffer_transfer_map( struct pipe_context *pipe,
+ struct pipe_transfer *transfer )
+{
+ uint8_t *map = svga_buffer_map_range( pipe->screen,
+ transfer->resource,
+ transfer->box.x,
+ transfer->box.width,
+ transfer->usage );
+ if (map == NULL)
+ return NULL;
+
+ /* map_buffer() returned a pointer to the beginning of the buffer,
+ * but transfers are expected to return a pointer to just the
+ * region specified in the box.
+ */
+ return map + transfer->box.x;
+}
+
+
+
+static void svga_buffer_transfer_flush_region( struct pipe_context *pipe,
+ struct pipe_transfer *transfer,
+ const struct pipe_box *box)
+{
+ assert(box->x + box->width <= transfer->box.width);
+
+ svga_buffer_flush_mapped_range(pipe->screen,
+ transfer->resource,
+ transfer->box.x + box->x,
+ box->width);
+}
+
+static void svga_buffer_transfer_unmap( struct pipe_context *pipe,
+ struct pipe_transfer *transfer )
+{
+ svga_buffer_unmap(pipe->screen,
+ transfer->resource);
+}
+
+
+
+
+
+
+
+struct u_resource_vtbl svga_buffer_vtbl =
+{
+ u_default_resource_get_handle, /* get_handle */
+ svga_buffer_destroy, /* resource_destroy */
+ svga_buffer_is_referenced, /* is_resource_referenced */
+ u_default_get_transfer, /* get_transfer */
+ u_default_transfer_destroy, /* transfer_destroy */
+ svga_buffer_transfer_map, /* transfer_map */
+ svga_buffer_transfer_flush_region, /* transfer_flush_region */
+ svga_buffer_transfer_unmap, /* transfer_unmap */
+ u_default_transfer_inline_write /* transfer_inline_write */
+};
+
+
+
+struct pipe_resource *
+svga_buffer_create(struct pipe_screen *screen,
+ const struct pipe_resource *template)
+{
+ struct svga_screen *ss = svga_screen(screen);
+ struct svga_buffer *sbuf;
+
+ sbuf = CALLOC_STRUCT(svga_buffer);
+ if(!sbuf)
+ goto error1;
+
+ sbuf->b.b = *template;
+ sbuf->b.vtbl = &svga_buffer_vtbl;
+ pipe_reference_init(&sbuf->b.b.reference, 1);
+ sbuf->b.b.screen = screen;
+
+ if(svga_buffer_needs_hw_storage(template->usage)) {
+ if(svga_buffer_create_host_surface(ss, sbuf) != PIPE_OK)
+ goto error2;
+ }
+ else {
+ sbuf->swbuf = align_malloc(template->width0, 64);
+ if(!sbuf->swbuf)
+ goto error2;
+ }
+
+ return &sbuf->b.b;
+
+error2:
+ FREE(sbuf);
+error1:
+ return NULL;
+}
+
+struct pipe_resource *
+svga_user_buffer_create(struct pipe_screen *screen,
+ void *ptr,
+ unsigned bytes,
+ unsigned usage)
+{
+ struct svga_buffer *sbuf;
+
+ sbuf = CALLOC_STRUCT(svga_buffer);
+ if(!sbuf)
+ goto no_sbuf;
+
+ pipe_reference_init(&sbuf->b.b.reference, 1);
+ sbuf->b.vtbl = &svga_buffer_vtbl;
+ sbuf->b.b.screen = screen;
+ sbuf->b.b.format = PIPE_FORMAT_R8_UNORM; /* ?? */
+ sbuf->b.b.usage = PIPE_BUFFER_USAGE_CPU_READ | usage;
+ sbuf->b.b.width0 = bytes;
+ sbuf->b.b.height0 = 1;
+ sbuf->b.b.depth0 = 1;
+
+ sbuf->swbuf = ptr;
+ sbuf->user = TRUE;
+
+ return &sbuf->b.b;
+
+no_sbuf:
+ return NULL;
+}
+
+
+
diff --git a/src/gallium/drivers/svga/svga_screen_buffer.h b/src/gallium/drivers/svga/svga_resource_buffer.h
index 2bd6077bba..55e7321184 100644
--- a/src/gallium/drivers/svga/svga_screen_buffer.h
+++ b/src/gallium/drivers/svga/svga_resource_buffer.h
@@ -29,15 +29,13 @@
#include "pipe/p_compiler.h"
#include "pipe/p_state.h"
-#include "piperesource/rm_public.h"
+#include "util/u_transfer.h"
#include "util/u_double_list.h"
#include "svga_screen_cache.h"
-#define SVGA_BUFFER_MAGIC 0x344f9005
-
/**
* Maximum number of discontiguous ranges
*/
@@ -50,6 +48,8 @@ struct svga_winsys_buffer;
struct svga_winsys_surface;
+extern struct u_resource_vtbl svga_buffer_vtbl;
+
struct svga_buffer_range
{
unsigned start;
@@ -62,12 +62,7 @@ struct svga_buffer_range
*/
struct svga_buffer
{
- struct pipe_buffer base;
-
- /**
- * Marker to detect bad casts in runtime.
- */
- uint32_t magic;
+ struct u_resource b;
/**
* Regular (non DMA'able) memory.
@@ -139,7 +134,7 @@ struct svga_buffer
* Information about uploaded version of user buffers.
*/
struct {
- struct pipe_buffer *buffer;
+ struct pipe_resource *buffer;
/**
* We combine multiple user buffers into the same hardware buffer. This
@@ -191,10 +186,10 @@ struct svga_buffer
static INLINE struct svga_buffer *
-svga_buffer(struct pipe_buffer *buffer)
+svga_buffer(struct pipe_resource *buffer)
{
if (buffer) {
- assert(((struct svga_buffer *)buffer)->magic == SVGA_BUFFER_MAGIC);
+ assert(((struct svga_buffer *)buffer)->b.vtbl == &svga_buffer_vtbl);
return (struct svga_buffer *)buffer;
}
return NULL;
@@ -206,14 +201,24 @@ svga_buffer(struct pipe_buffer *buffer)
* decide to use an alternate upload path for these buffers.
*/
static INLINE boolean
-svga_buffer_is_user_buffer( struct pipe_buffer *buffer )
+svga_buffer_is_user_buffer( struct pipe_resource *buffer )
{
return svga_buffer(buffer)->user;
}
-void
-svga_screen_init_buffer_functions(struct pipe_screen *screen);
+
+
+struct pipe_resource *
+svga_user_buffer_create(struct pipe_screen *screen,
+ void *ptr,
+ unsigned bytes,
+ unsigned usage);
+
+struct pipe_resource *
+svga_buffer_create(struct pipe_screen *screen,
+ const struct pipe_resource *template);
+
/**
diff --git a/src/gallium/drivers/svga/svga_resource_buffer_host.c b/src/gallium/drivers/svga/svga_resource_buffer_host.c
new file mode 100644
index 0000000000..139597f9cb
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_resource_buffer_host.c
@@ -0,0 +1,2 @@
+
+
diff --git a/src/gallium/drivers/svga/svga_screen_buffer.c b/src/gallium/drivers/svga/svga_resource_buffer_upload.c
index 1ff6a3a5b3..78fda66478 100644
--- a/src/gallium/drivers/svga/svga_screen_buffer.c
+++ b/src/gallium/drivers/svga/svga_resource_buffer_upload.c
@@ -34,88 +34,14 @@
#include "svga_context.h"
#include "svga_screen.h"
-#include "svga_screen_buffer.h"
+#include "svga_resource_buffer.h"
+#include "svga_resource_buffer_upload.h"
#include "svga_winsys.h"
#include "svga_debug.h"
-/**
- * Vertex and index buffers have to be treated slightly differently from
- * regular guest memory regions because the SVGA device sees them as
- * surfaces, and the state tracker can create/destroy without the pipe
- * driver, therefore we must do the uploads from the vws.
+/* Allocate a winsys_buffer (ie. DMA, aka GMR memory).
*/
-static INLINE boolean
-svga_buffer_needs_hw_storage(unsigned usage)
-{
- return usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_INDEX);
-}
-
-
-static INLINE enum pipe_error
-svga_buffer_create_host_surface(struct svga_screen *ss,
- struct svga_buffer *sbuf)
-{
- if(!sbuf->handle) {
- sbuf->key.flags = 0;
-
- sbuf->key.format = SVGA3D_BUFFER;
- if(sbuf->base.usage & PIPE_BUFFER_USAGE_VERTEX)
- sbuf->key.flags |= SVGA3D_SURFACE_HINT_VERTEXBUFFER;
- if(sbuf->base.usage & PIPE_BUFFER_USAGE_INDEX)
- sbuf->key.flags |= SVGA3D_SURFACE_HINT_INDEXBUFFER;
-
- sbuf->key.size.width = sbuf->base.size;
- sbuf->key.size.height = 1;
- sbuf->key.size.depth = 1;
-
- sbuf->key.numFaces = 1;
- sbuf->key.numMipLevels = 1;
- sbuf->key.cachable = 1;
-
- SVGA_DBG(DEBUG_DMA, "surface_create for buffer sz %d\n", sbuf->base.size);
-
- sbuf->handle = svga_screen_surface_create(ss, &sbuf->key);
- if(!sbuf->handle)
- return PIPE_ERROR_OUT_OF_MEMORY;
-
- /* Always set the discard flag on the first time the buffer is written
- * as svga_screen_surface_create might have passed a recycled host
- * buffer.
- */
- sbuf->dma.flags.discard = TRUE;
-
- SVGA_DBG(DEBUG_DMA, " --> got sid %p sz %d (buffer)\n", sbuf->handle, sbuf->base.size);
- }
-
- return PIPE_OK;
-}
-
-
-static INLINE void
-svga_buffer_destroy_host_surface(struct svga_screen *ss,
- struct svga_buffer *sbuf)
-{
- if(sbuf->handle) {
- SVGA_DBG(DEBUG_DMA, " ungrab sid %p sz %d\n", sbuf->handle, sbuf->base.size);
- svga_screen_surface_destroy(ss, &sbuf->key, &sbuf->handle);
- }
-}
-
-
-static INLINE void
-svga_buffer_destroy_hw_storage(struct svga_screen *ss, struct svga_buffer *sbuf)
-{
- struct svga_winsys_screen *sws = ss->sws;
-
- assert(!sbuf->map.count);
- assert(sbuf->hwbuf);
- if(sbuf->hwbuf) {
- sws->buffer_destroy(sws, sbuf->hwbuf);
- sbuf->hwbuf = NULL;
- }
-}
-
struct svga_winsys_buffer *
svga_winsys_buffer_create( struct svga_screen *ss,
unsigned alignment,
@@ -142,21 +68,36 @@ svga_winsys_buffer_create( struct svga_screen *ss,
}
+void
+svga_buffer_destroy_hw_storage(struct svga_screen *ss, struct svga_buffer *sbuf)
+{
+ struct svga_winsys_screen *sws = ss->sws;
+
+ assert(!sbuf->map.count);
+ assert(sbuf->hwbuf);
+ if(sbuf->hwbuf) {
+ sws->buffer_destroy(sws, sbuf->hwbuf);
+ sbuf->hwbuf = NULL;
+ }
+}
+
+
+
/**
* Allocate DMA'ble storage for the buffer.
*
* Called before mapping a buffer.
*/
-static INLINE enum pipe_error
+enum pipe_error
svga_buffer_create_hw_storage(struct svga_screen *ss,
struct svga_buffer *sbuf)
{
assert(!sbuf->user);
if(!sbuf->hwbuf) {
- unsigned alignment = sbuf->base.alignment;
+ unsigned alignment = 16;
unsigned usage = 0;
- unsigned size = sbuf->base.size;
+ unsigned size = sbuf->b.b.width0;
sbuf->hwbuf = svga_winsys_buffer_create(ss, alignment, usage, size);
if(!sbuf->hwbuf)
@@ -169,6 +110,58 @@ svga_buffer_create_hw_storage(struct svga_screen *ss,
}
+
+enum pipe_error
+svga_buffer_create_host_surface(struct svga_screen *ss,
+ struct svga_buffer *sbuf)
+{
+ if(!sbuf->handle) {
+ sbuf->key.flags = 0;
+
+ sbuf->key.format = SVGA3D_BUFFER;
+ if(sbuf->b.b.usage & PIPE_BUFFER_USAGE_VERTEX)
+ sbuf->key.flags |= SVGA3D_SURFACE_HINT_VERTEXBUFFER;
+ if(sbuf->b.b.usage & PIPE_BUFFER_USAGE_INDEX)
+ sbuf->key.flags |= SVGA3D_SURFACE_HINT_INDEXBUFFER;
+
+ sbuf->key.size.width = sbuf->b.b.width0;
+ sbuf->key.size.height = 1;
+ sbuf->key.size.depth = 1;
+
+ sbuf->key.numFaces = 1;
+ sbuf->key.numMipLevels = 1;
+ sbuf->key.cachable = 1;
+
+ SVGA_DBG(DEBUG_DMA, "surface_create for buffer sz %d\n", sbuf->b.b.width0);
+
+ sbuf->handle = svga_screen_surface_create(ss, &sbuf->key);
+ if(!sbuf->handle)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ /* Always set the discard flag on the first time the buffer is written
+ * as svga_screen_surface_create might have passed a recycled host
+ * buffer.
+ */
+ sbuf->dma.flags.discard = TRUE;
+
+ SVGA_DBG(DEBUG_DMA, " --> got sid %p sz %d (buffer)\n", sbuf->handle, sbuf->b.b.width0);
+ }
+
+ return PIPE_OK;
+}
+
+
+void
+svga_buffer_destroy_host_surface(struct svga_screen *ss,
+ struct svga_buffer *sbuf)
+{
+ if(sbuf->handle) {
+ SVGA_DBG(DEBUG_DMA, " ungrab sid %p sz %d\n", sbuf->handle, sbuf->b.b.width0);
+ svga_screen_surface_destroy(ss, &sbuf->key, &sbuf->handle);
+ }
+}
+
+
/**
* Variant of SVGA3D_BufferDMA which leaves the copy box temporarily in blank.
*/
@@ -186,7 +179,7 @@ svga_buffer_upload_command(struct svga_context *svga,
SVGA3dCmdSurfaceDMASuffix *pSuffix;
unsigned region_flags;
unsigned surface_flags;
- struct pipe_buffer *dummy;
+ struct pipe_resource *dummy;
if(transfer == SVGA3D_WRITE_HOST_VRAM) {
region_flags = PIPE_BUFFER_USAGE_GPU_READ;
@@ -224,11 +217,11 @@ svga_buffer_upload_command(struct svga_context *svga,
/* Increment reference count */
dummy = NULL;
- pipe_buffer_reference(&dummy, &sbuf->base);
+ pipe_resource_reference(&dummy, &sbuf->b.b);
pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + numBoxes * sizeof *boxes);
pSuffix->suffixSize = sizeof *pSuffix;
- pSuffix->maximumOffset = sbuf->base.size;
+ pSuffix->maximumOffset = sbuf->b.b.width0;
pSuffix->flags = sbuf->dma.flags;
SVGA_FIFOCommitAll(swc);
@@ -291,11 +284,12 @@ svga_buffer_upload_flush(struct svga_context *svga,
sbuf->dma.boxes = NULL;
/* Decrement reference count */
- pipe_reference(&(sbuf->base.reference), NULL);
+ pipe_reference(&(sbuf->b.b.reference), NULL);
sbuf = NULL;
}
+
/**
* Note a dirty range.
*
@@ -305,7 +299,7 @@ svga_buffer_upload_flush(struct svga_context *svga,
*
* We try to lump as many contiguous DMA transfers together as possible.
*/
-static void
+void
svga_buffer_add_range(struct svga_buffer *sbuf,
unsigned start,
unsigned end)
@@ -330,7 +324,7 @@ svga_buffer_add_range(struct svga_buffer *sbuf,
* Note that it is not this function task to care about overlapping ranges,
* as the GMR was already given so it is too late to do anything. Situations
* where overlapping ranges may pose a problem should be detected via
- * pipe_context::is_buffer_referenced and the context that refers to the
+ * pipe_context::is_resource_referenced and the context that refers to the
* buffer should be flushed.
*/
@@ -400,222 +394,6 @@ svga_buffer_add_range(struct svga_buffer *sbuf,
}
-static void *
-svga_buffer_map_range( struct pipe_screen *screen,
- struct pipe_buffer *buf,
- unsigned offset, unsigned length,
- unsigned usage )
-{
- struct svga_screen *ss = svga_screen(screen);
- struct svga_winsys_screen *sws = ss->sws;
- struct svga_buffer *sbuf = svga_buffer( buf );
- void *map;
-
- if (!sbuf->swbuf && !sbuf->hwbuf) {
- if (svga_buffer_create_hw_storage(ss, sbuf) != PIPE_OK) {
- /*
- * We can't create a hardware buffer big enough, so create a malloc
- * buffer instead.
- */
-
- debug_printf("%s: failed to allocate %u KB of DMA, splitting DMA transfers\n",
- __FUNCTION__,
- (sbuf->base.size + 1023)/1024);
-
- sbuf->swbuf = align_malloc(sbuf->base.size, sbuf->base.alignment);
- }
- }
-
- if (sbuf->swbuf) {
- /* User/malloc buffer */
- map = sbuf->swbuf;
- }
- else if (sbuf->hwbuf) {
- map = sws->buffer_map(sws, sbuf->hwbuf, usage);
- }
- else {
- map = NULL;
- }
-
- if(map) {
- pipe_mutex_lock(ss->swc_mutex);
-
- ++sbuf->map.count;
-
- if (usage & PIPE_BUFFER_USAGE_CPU_WRITE) {
- assert(sbuf->map.count <= 1);
- sbuf->map.writing = TRUE;
- if (usage & PIPE_BUFFER_USAGE_FLUSH_EXPLICIT)
- sbuf->map.flush_explicit = TRUE;
- }
-
- pipe_mutex_unlock(ss->swc_mutex);
- }
-
- return map;
-}
-
-static void
-svga_buffer_flush_mapped_range( struct pipe_screen *screen,
- struct pipe_buffer *buf,
- unsigned offset, unsigned length)
-{
- struct svga_buffer *sbuf = svga_buffer( buf );
- struct svga_screen *ss = svga_screen(screen);
-
- pipe_mutex_lock(ss->swc_mutex);
- assert(sbuf->map.writing);
- if(sbuf->map.writing) {
- assert(sbuf->map.flush_explicit);
- svga_buffer_add_range(sbuf, offset, offset + length);
- }
- pipe_mutex_unlock(ss->swc_mutex);
-}
-
-static void
-svga_buffer_unmap( struct pipe_screen *screen,
- struct pipe_buffer *buf)
-{
- struct svga_screen *ss = svga_screen(screen);
- struct svga_winsys_screen *sws = ss->sws;
- struct svga_buffer *sbuf = svga_buffer( buf );
-
- pipe_mutex_lock(ss->swc_mutex);
-
- assert(sbuf->map.count);
- if(sbuf->map.count)
- --sbuf->map.count;
-
- if(sbuf->hwbuf)
- sws->buffer_unmap(sws, sbuf->hwbuf);
-
- if(sbuf->map.writing) {
- if(!sbuf->map.flush_explicit) {
- /* No mapped range was flushed -- flush the whole buffer */
- SVGA_DBG(DEBUG_DMA, "flushing the whole buffer\n");
-
- svga_buffer_add_range(sbuf, 0, sbuf->base.size);
- }
-
- sbuf->map.writing = FALSE;
- sbuf->map.flush_explicit = FALSE;
- }
-
- pipe_mutex_unlock(ss->swc_mutex);
-}
-
-static void
-svga_buffer_destroy( struct pipe_buffer *buf )
-{
- struct svga_screen *ss = svga_screen(buf->screen);
- struct svga_buffer *sbuf = svga_buffer( buf );
-
- assert(!p_atomic_read(&buf->reference.count));
-
- assert(!sbuf->dma.pending);
-
- if(sbuf->handle)
- svga_buffer_destroy_host_surface(ss, sbuf);
-
- if(sbuf->uploaded.buffer)
- pipe_buffer_reference(&sbuf->uploaded.buffer, NULL);
-
- if(sbuf->hwbuf)
- svga_buffer_destroy_hw_storage(ss, sbuf);
-
- if(sbuf->swbuf && !sbuf->user)
- align_free(sbuf->swbuf);
-
- FREE(sbuf);
-}
-
-static struct pipe_buffer *
-svga_buffer_create(struct pipe_screen *screen,
- unsigned alignment,
- unsigned usage,
- unsigned size)
-{
- struct svga_screen *ss = svga_screen(screen);
- struct svga_buffer *sbuf;
-
- assert(size);
- assert(alignment);
-
- sbuf = CALLOC_STRUCT(svga_buffer);
- if(!sbuf)
- goto error1;
-
- sbuf->magic = SVGA_BUFFER_MAGIC;
-
- pipe_reference_init(&sbuf->base.reference, 1);
- sbuf->base.screen = screen;
- sbuf->base.alignment = alignment;
- sbuf->base.usage = usage;
- sbuf->base.size = size;
-
- if(svga_buffer_needs_hw_storage(usage)) {
- if(svga_buffer_create_host_surface(ss, sbuf) != PIPE_OK)
- goto error2;
- }
- else {
- if(alignment < sizeof(void*))
- alignment = sizeof(void*);
-
- usage |= PIPE_BUFFER_USAGE_CPU_READ_WRITE;
-
- sbuf->swbuf = align_malloc(size, alignment);
- if(!sbuf->swbuf)
- goto error2;
- }
-
- return &sbuf->base;
-
-error2:
- FREE(sbuf);
-error1:
- return NULL;
-}
-
-static struct pipe_buffer *
-svga_user_buffer_create(struct pipe_screen *screen,
- void *ptr,
- unsigned bytes)
-{
- struct svga_buffer *sbuf;
-
- sbuf = CALLOC_STRUCT(svga_buffer);
- if(!sbuf)
- goto no_sbuf;
-
- sbuf->magic = SVGA_BUFFER_MAGIC;
-
- sbuf->swbuf = ptr;
- sbuf->user = TRUE;
-
- pipe_reference_init(&sbuf->base.reference, 1);
- sbuf->base.screen = screen;
- sbuf->base.alignment = 1;
- sbuf->base.usage = 0;
- sbuf->base.size = bytes;
-
- return &sbuf->base;
-
-no_sbuf:
- return NULL;
-}
-
-
-void
-svga_screen_init_buffer_functions(struct pipe_screen *screen)
-{
- screen->buffer_create = svga_buffer_create;
- screen->user_buffer_create = svga_user_buffer_create;
- screen->buffer_map_range = svga_buffer_map_range;
- screen->buffer_flush_mapped_range = svga_buffer_flush_mapped_range;
- screen->buffer_unmap = svga_buffer_unmap;
- screen->buffer_destroy = svga_buffer_destroy;
-}
-
/**
* Copy the contents of the malloc buffer to a hardware buffer.
@@ -645,7 +423,7 @@ svga_buffer_update_hw(struct svga_screen *ss, struct svga_buffer *sbuf)
return PIPE_ERROR;
}
- memcpy(map, sbuf->swbuf, sbuf->base.size);
+ memcpy(map, sbuf->swbuf, sbuf->b.b.width0);
ss->sws->buffer_unmap(ss->sws, sbuf->hwbuf);
/* This user/malloc buffer is now indistinguishable from a gpu buffer */
@@ -710,8 +488,8 @@ svga_buffer_upload_piecewise(struct svga_screen *ss,
offset, offset + size);
map = sws->buffer_map(sws, hwbuf,
- PIPE_BUFFER_USAGE_CPU_WRITE |
- PIPE_BUFFER_USAGE_DISCARD);
+ PIPE_TRANSFER_WRITE |
+ PIPE_TRANSFER_DISCARD);
assert(map);
if (map) {
memcpy(map, sbuf->swbuf, size);
@@ -745,9 +523,14 @@ svga_buffer_upload_piecewise(struct svga_screen *ss,
}
+
+
+/* Get (or create/upload) the winsys surface handle so that we can
+ * refer to this buffer in fifo commands.
+ */
struct svga_winsys_surface *
svga_buffer_handle(struct svga_context *svga,
- struct pipe_buffer *buf)
+ struct pipe_resource *buf)
{
struct pipe_screen *screen = svga->pipe.screen;
struct svga_screen *ss = svga_screen(screen);
@@ -828,45 +611,6 @@ svga_buffer_handle(struct svga_context *svga,
}
-struct pipe_buffer *
-svga_screen_buffer_wrap_surface(struct pipe_screen *screen,
- enum SVGA3dSurfaceFormat format,
- struct svga_winsys_surface *srf)
-{
- struct pipe_buffer *buf;
- struct svga_buffer *sbuf;
- struct svga_winsys_screen *sws = svga_winsys_screen(screen);
-
- buf = svga_buffer_create(screen, 0, SVGA_BUFFER_USAGE_WRAPPED, 0);
- if (!buf)
- return NULL;
-
- sbuf = svga_buffer(buf);
-
- /*
- * We are not the creator of this surface and therefore we must not
- * cache it for reuse. Set the cacheable flag to zero in the key to
- * prevent this.
- */
- sbuf->key.format = format;
- sbuf->key.cachable = 0;
- sws->surface_reference(sws, &sbuf->handle, srf);
-
- return buf;
-}
-
-
-struct svga_winsys_surface *
-svga_screen_buffer_get_winsys_surface(struct pipe_buffer *buffer)
-{
- struct svga_winsys_screen *sws = svga_winsys_screen(buffer->screen);
- struct svga_winsys_surface *vsurf = NULL;
-
- assert(svga_buffer(buffer)->key.cachable == 0);
- svga_buffer(buffer)->key.cachable = 0;
- sws->surface_reference(sws, &vsurf, svga_buffer(buffer)->handle);
- return vsurf;
-}
void
svga_context_flush_buffers(struct svga_context *svga)
@@ -879,7 +623,7 @@ svga_context_flush_buffers(struct svga_context *svga)
while(curr != &svga->dirty_buffers) {
sbuf = LIST_ENTRY(struct svga_buffer, curr, head);
- assert(p_atomic_read(&sbuf->base.reference.count) != 0);
+ assert(p_atomic_read(&sbuf->b.b.reference.count) != 0);
assert(sbuf->dma.pending);
svga_buffer_upload_flush(svga, sbuf);
diff --git a/src/gallium/drivers/svga/svga_resource_buffer_upload.h b/src/gallium/drivers/svga/svga_resource_buffer_upload.h
new file mode 100644
index 0000000000..11df306526
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_resource_buffer_upload.h
@@ -0,0 +1,54 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+#ifndef SVGA_BUFFER_UPLOAD_H
+#define SVGA_BUFFER_UPLOAD_H
+
+
+void
+svga_buffer_add_range(struct svga_buffer *sbuf,
+ unsigned start,
+ unsigned end);
+
+enum pipe_error
+svga_buffer_create_hw_storage(struct svga_screen *ss,
+ struct svga_buffer *sbuf);
+
+void
+svga_buffer_destroy_hw_storage(struct svga_screen *ss,
+ struct svga_buffer *sbuf);
+
+enum pipe_error
+svga_buffer_create_host_surface(struct svga_screen *ss,
+ struct svga_buffer *sbuf);
+
+void
+svga_buffer_destroy_host_surface(struct svga_screen *ss,
+ struct svga_buffer *sbuf);
+
+
+
+
+#endif /* SVGA_BUFFER_H */
diff --git a/src/gallium/drivers/svga/svga_resource_texture.c b/src/gallium/drivers/svga/svga_resource_texture.c
new file mode 100644
index 0000000000..a288aa589e
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_resource_texture.c
@@ -0,0 +1,635 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+#include "svga_cmd.h"
+
+#include "pipe/p_state.h"
+#include "pipe/p_defines.h"
+#include "util/u_inlines.h"
+#include "os/os_thread.h"
+#include "util/u_format.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
+#include "svga_screen.h"
+#include "svga_context.h"
+#include "svga_resource_texture.h"
+#include "svga_resource_buffer.h"
+#include "svga_sampler_view.h"
+#include "svga_winsys.h"
+#include "svga_debug.h"
+
+#include <util/u_string.h>
+
+
+/* XXX: This isn't a real hardware flag, but just a hack for kernel to
+ * know about primary surfaces. Find a better way to accomplish this.
+ */
+#define SVGA3D_SURFACE_HINT_SCANOUT (1 << 9)
+
+
+static unsigned int
+svga_texture_is_referenced( struct pipe_context *pipe,
+ struct pipe_resource *texture,
+ unsigned face, unsigned level)
+{
+ struct svga_texture *tex = svga_texture(texture);
+ struct svga_screen *ss = svga_screen(pipe->screen);
+
+ /**
+ * The screen does not cache texture writes.
+ */
+
+ if (!tex->handle || ss->sws->surface_is_flushed(ss->sws, tex->handle))
+ return PIPE_UNREFERENCED;
+
+ /**
+ * sws->surface_is_flushed() does not distinguish between read references
+ * and write references. So assume a reference is both.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+
+
+/*
+ * Helper function and arrays
+ */
+
+SVGA3dSurfaceFormat
+svga_translate_format(enum pipe_format format)
+{
+ switch(format) {
+
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ return SVGA3D_A8R8G8B8;
+ case PIPE_FORMAT_B8G8R8X8_UNORM:
+ return SVGA3D_X8R8G8B8;
+
+ /* Required for GL2.1:
+ */
+ case PIPE_FORMAT_B8G8R8A8_SRGB:
+ return SVGA3D_A8R8G8B8;
+
+ case PIPE_FORMAT_B5G6R5_UNORM:
+ return SVGA3D_R5G6B5;
+ case PIPE_FORMAT_B5G5R5A1_UNORM:
+ return SVGA3D_A1R5G5B5;
+ case PIPE_FORMAT_B4G4R4A4_UNORM:
+ return SVGA3D_A4R4G4B4;
+
+
+ /* XXX: Doesn't seem to work properly.
+ case PIPE_FORMAT_Z32_UNORM:
+ return SVGA3D_Z_D32;
+ */
+ case PIPE_FORMAT_Z16_UNORM:
+ return SVGA3D_Z_D16;
+ case PIPE_FORMAT_S8Z24_UNORM:
+ return SVGA3D_Z_D24S8;
+ case PIPE_FORMAT_X8Z24_UNORM:
+ return SVGA3D_Z_D24X8;
+
+ case PIPE_FORMAT_A8_UNORM:
+ return SVGA3D_ALPHA8;
+ case PIPE_FORMAT_L8_UNORM:
+ return SVGA3D_LUMINANCE8;
+
+ case PIPE_FORMAT_DXT1_RGB:
+ case PIPE_FORMAT_DXT1_RGBA:
+ return SVGA3D_DXT1;
+ case PIPE_FORMAT_DXT3_RGBA:
+ return SVGA3D_DXT3;
+ case PIPE_FORMAT_DXT5_RGBA:
+ return SVGA3D_DXT5;
+
+ default:
+ return SVGA3D_FORMAT_INVALID;
+ }
+}
+
+
+SVGA3dSurfaceFormat
+svga_translate_format_render(enum pipe_format format)
+{
+ switch(format) {
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ case PIPE_FORMAT_B8G8R8X8_UNORM:
+ case PIPE_FORMAT_B5G5R5A1_UNORM:
+ case PIPE_FORMAT_B4G4R4A4_UNORM:
+ case PIPE_FORMAT_B5G6R5_UNORM:
+ case PIPE_FORMAT_S8Z24_UNORM:
+ case PIPE_FORMAT_X8Z24_UNORM:
+ case PIPE_FORMAT_Z32_UNORM:
+ case PIPE_FORMAT_Z16_UNORM:
+ case PIPE_FORMAT_L8_UNORM:
+ return svga_translate_format(format);
+
+#if 1
+ /* For on host conversion */
+ case PIPE_FORMAT_DXT1_RGB:
+ return SVGA3D_X8R8G8B8;
+ case PIPE_FORMAT_DXT1_RGBA:
+ case PIPE_FORMAT_DXT3_RGBA:
+ case PIPE_FORMAT_DXT5_RGBA:
+ return SVGA3D_A8R8G8B8;
+#endif
+
+ default:
+ return SVGA3D_FORMAT_INVALID;
+ }
+}
+
+
+static INLINE void
+svga_transfer_dma_band(struct svga_transfer *st,
+ SVGA3dTransferType transfer,
+ unsigned y, unsigned h, unsigned srcy)
+{
+ struct svga_texture *texture = svga_texture(st->base.resource);
+ struct svga_screen *screen = svga_screen(texture->b.b.screen);
+ SVGA3dCopyBox box;
+ enum pipe_error ret;
+
+ SVGA_DBG(DEBUG_DMA, "dma %s sid %p, face %u, (%u, %u, %u) - (%u, %u, %u), %ubpp\n",
+ transfer == SVGA3D_WRITE_HOST_VRAM ? "to" : "from",
+ texture->handle,
+ st->base.sr.face,
+ st->base.box.x,
+ y,
+ st->base.box.z,
+ st->base.box.x + st->base.box.width,
+ y + h,
+ st->base.box.z + 1,
+ util_format_get_blocksize(texture->b.b.format) * 8 /
+ (util_format_get_blockwidth(texture->b.b.format)*util_format_get_blockheight(texture->b.b.format)));
+
+ box.x = st->base.box.x;
+ box.y = y;
+ box.z = st->base.box.z;
+ box.w = st->base.box.width;
+ box.h = h;
+ box.d = 1;
+ box.srcx = 0;
+ box.srcy = srcy;
+ box.srcz = 0;
+
+ pipe_mutex_lock(screen->swc_mutex);
+ ret = SVGA3D_SurfaceDMA(screen->swc, st, transfer, &box, 1);
+ if(ret != PIPE_OK) {
+ screen->swc->flush(screen->swc, NULL);
+ ret = SVGA3D_SurfaceDMA(screen->swc, st, transfer, &box, 1);
+ assert(ret == PIPE_OK);
+ }
+ pipe_mutex_unlock(screen->swc_mutex);
+}
+
+
+static INLINE void
+svga_transfer_dma(struct svga_transfer *st,
+ SVGA3dTransferType transfer)
+{
+ struct svga_texture *texture = svga_texture(st->base.resource);
+ struct svga_screen *screen = svga_screen(texture->b.b.screen);
+ struct svga_winsys_screen *sws = screen->sws;
+ struct pipe_fence_handle *fence = NULL;
+
+ if (transfer == SVGA3D_READ_HOST_VRAM) {
+ SVGA_DBG(DEBUG_PERF, "%s: readback transfer\n", __FUNCTION__);
+ }
+
+
+ if(!st->swbuf) {
+ /* Do the DMA transfer in a single go */
+
+ svga_transfer_dma_band(st, transfer, st->base.box.y, st->base.box.height, 0);
+
+ if(transfer == SVGA3D_READ_HOST_VRAM) {
+ svga_screen_flush(screen, &fence);
+ sws->fence_finish(sws, fence, 0);
+ sws->fence_reference(sws, &fence, NULL);
+ }
+ }
+ else {
+ unsigned y, h, srcy;
+ unsigned blockheight = util_format_get_blockheight(st->base.resource->format);
+ h = st->hw_nblocksy * blockheight;
+ srcy = 0;
+ for(y = 0; y < st->base.box.height; y += h) {
+ unsigned offset, length;
+ void *hw, *sw;
+
+ if (y + h > st->base.box.height)
+ h = st->base.box.height - y;
+
+ /* Transfer band must be aligned to pixel block boundaries */
+ assert(y % blockheight == 0);
+ assert(h % blockheight == 0);
+
+ offset = y * st->base.stride / blockheight;
+ length = h * st->base.stride / blockheight;
+
+ sw = (uint8_t *)st->swbuf + offset;
+
+ if(transfer == SVGA3D_WRITE_HOST_VRAM) {
+ /* Wait for the previous DMAs to complete */
+ /* TODO: keep one DMA (at half the size) in the background */
+ if(y) {
+ svga_screen_flush(screen, &fence);
+ sws->fence_finish(sws, fence, 0);
+ sws->fence_reference(sws, &fence, NULL);
+ }
+
+ hw = sws->buffer_map(sws, st->hwbuf, PIPE_BUFFER_USAGE_CPU_WRITE);
+ assert(hw);
+ if(hw) {
+ memcpy(hw, sw, length);
+ sws->buffer_unmap(sws, st->hwbuf);
+ }
+ }
+
+ svga_transfer_dma_band(st, transfer, y, h, srcy);
+
+ if(transfer == SVGA3D_READ_HOST_VRAM) {
+ svga_screen_flush(screen, &fence);
+ sws->fence_finish(sws, fence, 0);
+
+ hw = sws->buffer_map(sws, st->hwbuf, PIPE_BUFFER_USAGE_CPU_READ);
+ assert(hw);
+ if(hw) {
+ memcpy(sw, hw, length);
+ sws->buffer_unmap(sws, st->hwbuf);
+ }
+ }
+ }
+ }
+}
+
+
+
+
+
+static boolean
+svga_texture_get_handle(struct pipe_screen *screen,
+ struct pipe_resource *texture,
+ struct winsys_handle *whandle)
+{
+ struct svga_winsys_screen *sws = svga_winsys_screen(texture->screen);
+ unsigned stride;
+
+ assert(svga_texture(texture)->key.cachable == 0);
+ svga_texture(texture)->key.cachable = 0;
+ stride = util_format_get_nblocksx(texture->format, texture->width0) *
+ util_format_get_blocksize(texture->format);
+ return sws->surface_get_handle(sws, svga_texture(texture)->handle, stride, whandle);
+}
+
+
+static void
+svga_texture_destroy(struct pipe_screen *screen,
+ struct pipe_resource *pt)
+{
+ struct svga_screen *ss = svga_screen(screen);
+ struct svga_texture *tex = (struct svga_texture *)pt;
+
+ ss->texture_timestamp++;
+
+ svga_sampler_view_reference(&tex->cached_view, NULL);
+
+ /*
+ DBG("%s deleting %p\n", __FUNCTION__, (void *) tex);
+ */
+ SVGA_DBG(DEBUG_DMA, "unref sid %p (texture)\n", tex->handle);
+ svga_screen_surface_destroy(ss, &tex->key, &tex->handle);
+
+ FREE(tex);
+}
+
+
+
+
+
+
+
+/* XXX: Still implementing this as if it was a screen function, but
+ * can now modify it to queue transfers on the context.
+ */
+static struct pipe_transfer *
+svga_texture_get_transfer(struct pipe_context *pipe,
+ struct pipe_resource *texture,
+ struct pipe_subresource sr,
+ enum pipe_transfer_usage usage,
+ const struct pipe_box *box)
+{
+ struct svga_screen *ss = svga_screen(pipe->screen);
+ struct svga_winsys_screen *sws = ss->sws;
+ struct svga_transfer *st;
+ unsigned nblocksx = util_format_get_nblocksx(texture->format, box->width);
+ unsigned nblocksy = util_format_get_nblocksy(texture->format, box->height);
+
+ /* We can't map texture storage directly */
+ if (usage & PIPE_TRANSFER_MAP_DIRECTLY)
+ return NULL;
+
+ st = CALLOC_STRUCT(svga_transfer);
+ if (!st)
+ return NULL;
+
+ pipe_resource_reference(&st->base.resource, texture);
+ st->base.sr = sr;
+ st->base.usage = usage;
+ st->base.box = *box;
+ st->base.stride = nblocksx*util_format_get_blocksize(texture->format);
+ st->base.slice_stride = 0;
+
+ st->hw_nblocksy = nblocksy;
+
+ st->hwbuf = svga_winsys_buffer_create(ss,
+ 1,
+ 0,
+ st->hw_nblocksy*st->base.stride);
+ while(!st->hwbuf && (st->hw_nblocksy /= 2)) {
+ st->hwbuf = svga_winsys_buffer_create(ss,
+ 1,
+ 0,
+ st->hw_nblocksy*st->base.stride);
+ }
+
+ if(!st->hwbuf)
+ goto no_hwbuf;
+
+ if(st->hw_nblocksy < nblocksy) {
+ /* We couldn't allocate a hardware buffer big enough for the transfer,
+ * so allocate regular malloc memory instead */
+ debug_printf("%s: failed to allocate %u KB of DMA, splitting into %u x %u KB DMA transfers\n",
+ __FUNCTION__,
+ (nblocksy*st->base.stride + 1023)/1024,
+ (nblocksy + st->hw_nblocksy - 1)/st->hw_nblocksy,
+ (st->hw_nblocksy*st->base.stride + 1023)/1024);
+ st->swbuf = MALLOC(nblocksy*st->base.stride);
+ if(!st->swbuf)
+ goto no_swbuf;
+ }
+
+ if (usage & PIPE_TRANSFER_READ)
+ svga_transfer_dma(st, SVGA3D_READ_HOST_VRAM);
+
+ return &st->base;
+
+no_swbuf:
+ sws->buffer_destroy(sws, st->hwbuf);
+no_hwbuf:
+ FREE(st);
+ return NULL;
+}
+
+
+/* XXX: Still implementing this as if it was a screen function, but
+ * can now modify it to queue transfers on the context.
+ */
+static void *
+svga_texture_transfer_map( struct pipe_context *pipe,
+ struct pipe_transfer *transfer )
+{
+ struct svga_screen *ss = svga_screen(pipe->screen);
+ struct svga_winsys_screen *sws = ss->sws;
+ struct svga_transfer *st = svga_transfer(transfer);
+
+ if(st->swbuf)
+ return st->swbuf;
+ else
+ /* The wait for read transfers already happened when svga_transfer_dma
+ * was called. */
+ return sws->buffer_map(sws, st->hwbuf, transfer->usage);
+}
+
+
+/* XXX: Still implementing this as if it was a screen function, but
+ * can now modify it to queue transfers on the context.
+ */
+static void
+svga_texture_transfer_unmap(struct pipe_context *pipe,
+ struct pipe_transfer *transfer)
+{
+ struct svga_screen *ss = svga_screen(pipe->screen);
+ struct svga_winsys_screen *sws = ss->sws;
+ struct svga_transfer *st = svga_transfer(transfer);
+
+ if(!st->swbuf)
+ sws->buffer_unmap(sws, st->hwbuf);
+}
+
+
+static void
+svga_texture_transfer_destroy(struct pipe_context *pipe,
+ struct pipe_transfer *transfer)
+{
+ struct svga_texture *tex = svga_texture(transfer->resource);
+ struct svga_screen *ss = svga_screen(pipe->screen);
+ struct svga_winsys_screen *sws = ss->sws;
+ struct svga_transfer *st = svga_transfer(transfer);
+
+ if (st->base.usage & PIPE_TRANSFER_WRITE) {
+ svga_transfer_dma(st, SVGA3D_WRITE_HOST_VRAM);
+ ss->texture_timestamp++;
+ tex->view_age[transfer->sr.level] = ++(tex->age);
+ tex->defined[transfer->sr.face][transfer->sr.level] = TRUE;
+ }
+
+ pipe_resource_reference(&st->base.resource, NULL);
+ FREE(st->swbuf);
+ sws->buffer_destroy(sws, st->hwbuf);
+ FREE(st);
+}
+
+
+
+
+
+struct u_resource_vtbl svga_texture_vtbl =
+{
+ svga_texture_get_handle, /* get_handle */
+ svga_texture_destroy, /* resource_destroy */
+ svga_texture_is_referenced, /* is_resource_referenced */
+ svga_texture_get_transfer, /* get_transfer */
+ svga_texture_transfer_destroy, /* transfer_destroy */
+ svga_texture_transfer_map, /* transfer_map */
+ u_default_transfer_flush_region, /* transfer_flush_region */
+ svga_texture_transfer_unmap, /* transfer_unmap */
+ u_default_transfer_inline_write /* transfer_inline_write */
+};
+
+
+
+
+struct pipe_resource *
+svga_texture_create(struct pipe_screen *screen,
+ const struct pipe_resource *template)
+{
+ struct svga_screen *svgascreen = svga_screen(screen);
+ struct svga_texture *tex = CALLOC_STRUCT(svga_texture);
+
+ if (!tex)
+ goto error1;
+
+ tex->b.b = *template;
+ tex->b.vtbl = &svga_texture_vtbl;
+ pipe_reference_init(&tex->b.b.reference, 1);
+ tex->b.b.screen = screen;
+
+ assert(template->last_level < SVGA_MAX_TEXTURE_LEVELS);
+ if(template->last_level >= SVGA_MAX_TEXTURE_LEVELS)
+ goto error2;
+
+ tex->key.flags = 0;
+ tex->key.size.width = template->width0;
+ tex->key.size.height = template->height0;
+ tex->key.size.depth = template->depth0;
+
+ if(template->target == PIPE_TEXTURE_CUBE) {
+ tex->key.flags |= SVGA3D_SURFACE_CUBEMAP;
+ tex->key.numFaces = 6;
+ }
+ else {
+ tex->key.numFaces = 1;
+ }
+
+ tex->key.cachable = 1;
+
+ if(template->tex_usage & PIPE_TEXTURE_USAGE_SAMPLER)
+ tex->key.flags |= SVGA3D_SURFACE_HINT_TEXTURE;
+
+ if(template->tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
+ tex->key.cachable = 0;
+ }
+
+ if(template->tex_usage & PIPE_TEXTURE_USAGE_SHARED) {
+ tex->key.cachable = 0;
+ }
+
+ if(template->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT) {
+ tex->key.flags |= SVGA3D_SURFACE_HINT_SCANOUT;
+ tex->key.cachable = 0;
+ }
+
+ /*
+ * XXX: Never pass the SVGA3D_SURFACE_HINT_RENDERTARGET hint. Mesa cannot
+ * know beforehand whether a texture will be used as a rendertarget or not
+ * and it always requests PIPE_TEXTURE_USAGE_RENDER_TARGET, therefore
+ * passing the SVGA3D_SURFACE_HINT_RENDERTARGET here defeats its purpose.
+ */
+#if 0
+ if((template->tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) &&
+ !util_format_is_compressed(template->format))
+ tex->key.flags |= SVGA3D_SURFACE_HINT_RENDERTARGET;
+#endif
+
+ if(template->tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL)
+ tex->key.flags |= SVGA3D_SURFACE_HINT_DEPTHSTENCIL;
+
+ tex->key.numMipLevels = template->last_level + 1;
+
+ tex->key.format = svga_translate_format(template->format);
+ if(tex->key.format == SVGA3D_FORMAT_INVALID)
+ goto error2;
+
+ SVGA_DBG(DEBUG_DMA, "surface_create for texture\n", tex->handle);
+ tex->handle = svga_screen_surface_create(svgascreen, &tex->key);
+ if (tex->handle)
+ SVGA_DBG(DEBUG_DMA, " --> got sid %p (texture)\n", tex->handle);
+
+ return &tex->b.b;
+
+error2:
+ FREE(tex);
+error1:
+ return NULL;
+}
+
+
+
+
+struct pipe_resource *
+svga_texture_from_handle(struct pipe_screen *screen,
+ const struct pipe_resource *template,
+ struct winsys_handle *whandle)
+{
+ struct svga_winsys_screen *sws = svga_winsys_screen(screen);
+ struct svga_winsys_surface *srf;
+ struct svga_texture *tex;
+ enum SVGA3dSurfaceFormat format = 0;
+ assert(screen);
+
+ /* Only supports one type */
+ if (template->target != PIPE_TEXTURE_2D ||
+ template->last_level != 0 ||
+ template->depth0 != 1) {
+ return NULL;
+ }
+
+ srf = sws->surface_from_handle(sws, whandle, &format);
+
+ if (!srf)
+ return NULL;
+
+ if (svga_translate_format(template->format) != format) {
+ unsigned f1 = svga_translate_format(template->format);
+ unsigned f2 = format;
+
+ /* It's okay for XRGB and ARGB or depth with/out stencil to get mixed up */
+ if ( !( (f1 == SVGA3D_X8R8G8B8 && f2 == SVGA3D_A8R8G8B8) ||
+ (f1 == SVGA3D_A8R8G8B8 && f2 == SVGA3D_X8R8G8B8) ||
+ (f1 == SVGA3D_Z_D24X8 && f2 == SVGA3D_Z_D24S8) ) ) {
+ debug_printf("%s wrong format %u != %u\n", __FUNCTION__, f1, f2);
+ return NULL;
+ }
+ }
+
+ tex = CALLOC_STRUCT(svga_texture);
+ if (!tex)
+ return NULL;
+
+ tex->b.b = *template;
+ tex->b.vtbl = &svga_texture_vtbl;
+ pipe_reference_init(&tex->b.b.reference, 1);
+ tex->b.b.screen = screen;
+
+ if (format == SVGA3D_X8R8G8B8)
+ tex->b.b.format = PIPE_FORMAT_B8G8R8X8_UNORM;
+ else if (format == SVGA3D_A8R8G8B8)
+ tex->b.b.format = PIPE_FORMAT_B8G8R8A8_UNORM;
+ else {
+ /* ?? */
+ }
+
+ SVGA_DBG(DEBUG_DMA, "wrap surface sid %p\n", srf);
+
+ tex->key.cachable = 0;
+ tex->handle = srf;
+
+ return &tex->b.b;
+}
+
diff --git a/src/gallium/drivers/svga/svga_screen_texture.h b/src/gallium/drivers/svga/svga_resource_texture.h
index c2da383455..631937f2eb 100644
--- a/src/gallium/drivers/svga/svga_screen_texture.h
+++ b/src/gallium/drivers/svga/svga_resource_texture.h
@@ -29,8 +29,8 @@
#include "pipe/p_compiler.h"
#include "pipe/p_state.h"
-#include "piperesource/rm_public.h"
#include "util/u_inlines.h"
+#include "util/u_transfer.h"
#include "svga_screen_cache.h"
struct pipe_context;
@@ -43,41 +43,12 @@ enum SVGA3dSurfaceFormat;
#define SVGA_MAX_TEXTURE_LEVELS 16
-/**
- * A sampler's view into a texture
- *
- * We currently cache one sampler view on
- * the texture and in there by holding a reference
- * from the texture to the sampler view.
- *
- * Because of this we can not hold a refernce to the
- * texture from the sampler view. So the user
- * of the sampler views must make sure that the
- * texture has a reference take for as long as
- * the sampler view is refrenced.
- *
- * Just unreferencing the sampler_view before the
- * texture is enough.
- */
-struct svga_sampler_view
-{
- struct pipe_reference reference;
-
- struct pipe_texture *texture;
-
- int min_lod;
- int max_lod;
-
- unsigned age;
-
- struct svga_host_surface_cache_key key;
- struct svga_winsys_surface *handle;
-};
+extern struct u_resource_vtbl svga_texture_vtbl;
struct svga_texture
{
- struct pipe_texture base;
+ struct u_resource b;
boolean defined[6][SVGA_MAX_TEXTURE_LEVELS];
@@ -107,21 +78,9 @@ struct svga_texture
};
-struct svga_surface
-{
- struct pipe_surface base;
-
- struct svga_host_surface_cache_key key;
- struct svga_winsys_surface *handle;
-
- unsigned real_face;
- unsigned real_level;
- unsigned real_zslice;
-
- boolean dirty;
-};
-
+/* Note this is only used for texture (not buffer) transfers:
+ */
struct svga_transfer
{
struct pipe_transfer base;
@@ -137,18 +96,13 @@ struct svga_transfer
};
-static INLINE struct svga_texture *
-svga_texture(struct pipe_texture *texture)
+static INLINE struct svga_texture *svga_texture( struct pipe_resource *resource )
{
- return (struct svga_texture *)texture;
+ struct svga_texture *tex = (struct svga_texture *)resource;
+ assert(tex == NULL || tex->b.vtbl == &svga_texture_vtbl);
+ return tex;
}
-static INLINE struct svga_surface *
-svga_surface(struct pipe_surface *surface)
-{
- assert(surface);
- return (struct svga_surface *)surface;
-}
static INLINE struct svga_transfer *
svga_transfer(struct pipe_transfer *transfer)
@@ -157,38 +111,18 @@ svga_transfer(struct pipe_transfer *transfer)
return (struct svga_transfer *)transfer;
}
-extern struct svga_sampler_view *
-svga_get_tex_sampler_view(struct pipe_context *pipe,
- struct pipe_texture *pt,
- unsigned min_lod, unsigned max_lod);
-
-void
-svga_validate_sampler_view(struct svga_context *svga, struct svga_sampler_view *v);
-
-void
-svga_destroy_sampler_view_priv(struct svga_sampler_view *v);
-static INLINE void
-svga_sampler_view_reference(struct svga_sampler_view **ptr, struct svga_sampler_view *v)
-{
- struct svga_sampler_view *old = *ptr;
-
- if (pipe_reference(&(*ptr)->reference, &v->reference))
- svga_destroy_sampler_view_priv(old);
- *ptr = v;
-}
-extern void
-svga_propagate_surface(struct pipe_context *pipe, struct pipe_surface *surf);
+struct pipe_resource *
+svga_texture_create(struct pipe_screen *screen,
+ const struct pipe_resource *template);
-extern boolean
-svga_surface_needs_propagation(struct pipe_surface *surf);
+struct pipe_resource *
+svga_texture_from_handle(struct pipe_screen * screen,
+ const struct pipe_resource *template,
+ struct winsys_handle *whandle);
-extern void
-svga_screen_init_texture_functions(struct pipe_screen *screen);
-void
-svga_init_texture_functions(struct pipe_context *pipe);
enum SVGA3dSurfaceFormat
svga_translate_format(enum pipe_format format);
diff --git a/src/gallium/drivers/svga/svga_sampler_view.c b/src/gallium/drivers/svga/svga_sampler_view.c
new file mode 100644
index 0000000000..f445e31b46
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_sampler_view.c
@@ -0,0 +1,198 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+#include "svga_cmd.h"
+
+#include "pipe/p_state.h"
+#include "pipe/p_defines.h"
+#include "util/u_inlines.h"
+#include "os/os_thread.h"
+#include "util/u_format.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
+#include "svga_screen.h"
+#include "svga_context.h"
+#include "svga_resource_texture.h"
+#include "svga_sampler_view.h"
+#include "svga_winsys.h"
+#include "svga_debug.h"
+
+#include <util/u_string.h>
+
+
+struct svga_sampler_view *
+svga_get_tex_sampler_view(struct pipe_context *pipe,
+ struct pipe_resource *pt,
+ unsigned min_lod, unsigned max_lod)
+{
+ struct svga_screen *ss = svga_screen(pt->screen);
+ struct svga_texture *tex = svga_texture(pt);
+ struct svga_sampler_view *sv = NULL;
+ SVGA3dSurfaceFormat format = svga_translate_format(pt->format);
+ boolean view = TRUE;
+
+ assert(pt);
+ assert(min_lod >= 0);
+ assert(min_lod <= max_lod);
+ assert(max_lod <= pt->last_level);
+
+
+ /* Is a view needed */
+ {
+ /*
+ * Can't control max lod. For first level views and when we only
+ * look at one level we disable mip filtering to achive the same
+ * results as a view.
+ */
+ if (min_lod == 0 && max_lod >= pt->last_level)
+ view = FALSE;
+
+ if (util_format_is_compressed(pt->format) && view) {
+ format = svga_translate_format_render(pt->format);
+ }
+
+ if (ss->debug.no_sampler_view)
+ view = FALSE;
+
+ if (ss->debug.force_sampler_view)
+ view = TRUE;
+ }
+
+ /* First try the cache */
+ if (view) {
+ pipe_mutex_lock(ss->tex_mutex);
+ if (tex->cached_view &&
+ tex->cached_view->min_lod == min_lod &&
+ tex->cached_view->max_lod == max_lod) {
+ svga_sampler_view_reference(&sv, tex->cached_view);
+ pipe_mutex_unlock(ss->tex_mutex);
+ SVGA_DBG(DEBUG_VIEWS, "svga: Sampler view: reuse %p, %u %u, last %u\n",
+ pt, min_lod, max_lod, pt->last_level);
+ svga_validate_sampler_view(svga_context(pipe), sv);
+ return sv;
+ }
+ pipe_mutex_unlock(ss->tex_mutex);
+ }
+
+ sv = CALLOC_STRUCT(svga_sampler_view);
+ pipe_reference_init(&sv->reference, 1);
+ pipe_resource_reference(&sv->texture, pt);
+ sv->min_lod = min_lod;
+ sv->max_lod = max_lod;
+
+ /* No view needed just use the whole texture */
+ if (!view) {
+ SVGA_DBG(DEBUG_VIEWS,
+ "svga: Sampler view: no %p, mips %u..%u, nr %u, size (%ux%ux%u), last %u\n",
+ pt, min_lod, max_lod,
+ max_lod - min_lod + 1,
+ pt->width0,
+ pt->height0,
+ pt->depth0,
+ pt->last_level);
+ sv->key.cachable = 0;
+ sv->handle = tex->handle;
+ return sv;
+ }
+
+ SVGA_DBG(DEBUG_VIEWS,
+ "svga: Sampler view: yes %p, mips %u..%u, nr %u, size (%ux%ux%u), last %u\n",
+ pt, min_lod, max_lod,
+ max_lod - min_lod + 1,
+ pt->width0,
+ pt->height0,
+ pt->depth0,
+ pt->last_level);
+
+ sv->age = tex->age;
+ sv->handle = svga_texture_view_surface(pipe, tex, format,
+ min_lod,
+ max_lod - min_lod + 1,
+ -1, -1,
+ &sv->key);
+
+ if (!sv->handle) {
+ assert(0);
+ sv->key.cachable = 0;
+ sv->handle = tex->handle;
+ return sv;
+ }
+
+ pipe_mutex_lock(ss->tex_mutex);
+ svga_sampler_view_reference(&tex->cached_view, sv);
+ pipe_mutex_unlock(ss->tex_mutex);
+
+ return sv;
+}
+
+void
+svga_validate_sampler_view(struct svga_context *svga, struct svga_sampler_view *v)
+{
+ struct svga_texture *tex = svga_texture(v->texture);
+ unsigned numFaces;
+ unsigned age = 0;
+ int i, k;
+
+ assert(svga);
+
+ if (v->handle == tex->handle)
+ return;
+
+ age = tex->age;
+
+ if(tex->b.b.target == PIPE_TEXTURE_CUBE)
+ numFaces = 6;
+ else
+ numFaces = 1;
+
+ for (i = v->min_lod; i <= v->max_lod; i++) {
+ for (k = 0; k < numFaces; k++) {
+ if (v->age < tex->view_age[i])
+ svga_texture_copy_handle(svga, NULL,
+ tex->handle, 0, 0, 0, i, k,
+ v->handle, 0, 0, 0, i - v->min_lod, k,
+ u_minify(tex->b.b.width0, i),
+ u_minify(tex->b.b.height0, i),
+ u_minify(tex->b.b.depth0, i));
+ }
+ }
+
+ v->age = age;
+}
+
+void
+svga_destroy_sampler_view_priv(struct svga_sampler_view *v)
+{
+ struct svga_texture *tex = svga_texture(v->texture);
+
+ if(v->handle != tex->handle) {
+ struct svga_screen *ss = svga_screen(v->texture->screen);
+ SVGA_DBG(DEBUG_DMA, "unref sid %p (sampler view)\n", v->handle);
+ svga_screen_surface_destroy(ss, &v->key, &v->handle);
+ }
+ pipe_resource_reference(&v->texture, NULL);
+ FREE(v);
+}
diff --git a/src/gallium/drivers/svga/svga_sampler_view.h b/src/gallium/drivers/svga/svga_sampler_view.h
new file mode 100644
index 0000000000..e64665f2e5
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_sampler_view.h
@@ -0,0 +1,97 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+#ifndef SVGA_SAMPLER_VIEW_H
+#define SVGA_SAMPLER_VIEW_H
+
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_state.h"
+#include "util/u_inlines.h"
+#include "svga_screen_cache.h"
+
+struct pipe_context;
+struct pipe_screen;
+struct svga_context;
+struct svga_winsys_surface;
+enum SVGA3dSurfaceFormat;
+
+
+/**
+ * A sampler's view into a texture
+ *
+ * We currently cache one sampler view on
+ * the texture and in there by holding a reference
+ * from the texture to the sampler view.
+ *
+ * Because of this we can not hold a refernce to the
+ * texture from the sampler view. So the user
+ * of the sampler views must make sure that the
+ * texture has a reference take for as long as
+ * the sampler view is refrenced.
+ *
+ * Just unreferencing the sampler_view before the
+ * texture is enough.
+ */
+struct svga_sampler_view
+{
+ struct pipe_reference reference;
+
+ struct pipe_resource *texture;
+
+ int min_lod;
+ int max_lod;
+
+ unsigned age;
+
+ struct svga_host_surface_cache_key key;
+ struct svga_winsys_surface *handle;
+};
+
+
+
+extern struct svga_sampler_view *
+svga_get_tex_sampler_view(struct pipe_context *pipe,
+ struct pipe_resource *pt,
+ unsigned min_lod, unsigned max_lod);
+
+void
+svga_validate_sampler_view(struct svga_context *svga, struct svga_sampler_view *v);
+
+void
+svga_destroy_sampler_view_priv(struct svga_sampler_view *v);
+
+static INLINE void
+svga_sampler_view_reference(struct svga_sampler_view **ptr, struct svga_sampler_view *v)
+{
+ struct svga_sampler_view *old = *ptr;
+
+ if (pipe_reference(&(*ptr)->reference, &v->reference))
+ svga_destroy_sampler_view_priv(old);
+ *ptr = v;
+}
+
+
+#endif
diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c
index 6022c38cfc..f64d8c3a7b 100644
--- a/src/gallium/drivers/svga/svga_screen.c
+++ b/src/gallium/drivers/svga/svga_screen.c
@@ -31,8 +31,9 @@
#include "svga_winsys.h"
#include "svga_context.h"
#include "svga_screen.h"
-#include "svga_screen_texture.h"
-#include "svga_screen_buffer.h"
+#include "svga_resource_texture.h"
+#include "svga_resource_buffer.h"
+#include "svga_resource.h"
#include "svga_debug.h"
#include "svga3d_shaderdefs.h"
@@ -397,8 +398,7 @@ svga_screen_create(struct svga_winsys_screen *sws)
screen->fence_finish = svga_fence_finish;
svgascreen->sws = sws;
- svga_screen_init_texture_functions(screen);
- svga_screen_init_buffer_functions(screen);
+ svga_init_screen_resource_functions(svgascreen);
svgascreen->use_ps30 =
sws->get_cap(sws, SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION, &result) &&
diff --git a/src/gallium/drivers/svga/svga_screen_texture.c b/src/gallium/drivers/svga/svga_screen_texture.c
deleted file mode 100644
index cdeec18744..0000000000
--- a/src/gallium/drivers/svga/svga_screen_texture.c
+++ /dev/null
@@ -1,1099 +0,0 @@
-/**********************************************************
- * Copyright 2008-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, sublicense, 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 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
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * 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.
- *
- **********************************************************/
-
-#include "svga_cmd.h"
-
-#include "pipe/p_state.h"
-#include "pipe/p_defines.h"
-#include "util/u_inlines.h"
-#include "os/os_thread.h"
-#include "util/u_format.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-
-#include "svga_screen.h"
-#include "svga_context.h"
-#include "svga_screen_texture.h"
-#include "svga_screen_buffer.h"
-#include "svga_winsys.h"
-#include "svga_debug.h"
-#include "svga_screen_buffer.h"
-
-#include <util/u_string.h>
-
-
-/* XXX: This isn't a real hardware flag, but just a hack for kernel to
- * know about primary surfaces. Find a better way to accomplish this.
- */
-#define SVGA3D_SURFACE_HINT_SCANOUT (1 << 9)
-
-
-/*
- * Helper function and arrays
- */
-
-SVGA3dSurfaceFormat
-svga_translate_format(enum pipe_format format)
-{
- switch(format) {
-
- case PIPE_FORMAT_B8G8R8A8_UNORM:
- return SVGA3D_A8R8G8B8;
- case PIPE_FORMAT_B8G8R8X8_UNORM:
- return SVGA3D_X8R8G8B8;
-
- /* Required for GL2.1:
- */
- case PIPE_FORMAT_B8G8R8A8_SRGB:
- return SVGA3D_A8R8G8B8;
-
- case PIPE_FORMAT_B5G6R5_UNORM:
- return SVGA3D_R5G6B5;
- case PIPE_FORMAT_B5G5R5A1_UNORM:
- return SVGA3D_A1R5G5B5;
- case PIPE_FORMAT_B4G4R4A4_UNORM:
- return SVGA3D_A4R4G4B4;
-
-
- /* XXX: Doesn't seem to work properly.
- case PIPE_FORMAT_Z32_UNORM:
- return SVGA3D_Z_D32;
- */
- case PIPE_FORMAT_Z16_UNORM:
- return SVGA3D_Z_D16;
- case PIPE_FORMAT_S8Z24_UNORM:
- return SVGA3D_Z_D24S8;
- case PIPE_FORMAT_X8Z24_UNORM:
- return SVGA3D_Z_D24X8;
-
- case PIPE_FORMAT_A8_UNORM:
- return SVGA3D_ALPHA8;
- case PIPE_FORMAT_L8_UNORM:
- return SVGA3D_LUMINANCE8;
-
- case PIPE_FORMAT_DXT1_RGB:
- case PIPE_FORMAT_DXT1_RGBA:
- return SVGA3D_DXT1;
- case PIPE_FORMAT_DXT3_RGBA:
- return SVGA3D_DXT3;
- case PIPE_FORMAT_DXT5_RGBA:
- return SVGA3D_DXT5;
-
- default:
- return SVGA3D_FORMAT_INVALID;
- }
-}
-
-
-SVGA3dSurfaceFormat
-svga_translate_format_render(enum pipe_format format)
-{
- switch(format) {
- case PIPE_FORMAT_B8G8R8A8_UNORM:
- case PIPE_FORMAT_B8G8R8X8_UNORM:
- case PIPE_FORMAT_B5G5R5A1_UNORM:
- case PIPE_FORMAT_B4G4R4A4_UNORM:
- case PIPE_FORMAT_B5G6R5_UNORM:
- case PIPE_FORMAT_S8Z24_UNORM:
- case PIPE_FORMAT_X8Z24_UNORM:
- case PIPE_FORMAT_Z32_UNORM:
- case PIPE_FORMAT_Z16_UNORM:
- case PIPE_FORMAT_L8_UNORM:
- return svga_translate_format(format);
-
-#if 1
- /* For on host conversion */
- case PIPE_FORMAT_DXT1_RGB:
- return SVGA3D_X8R8G8B8;
- case PIPE_FORMAT_DXT1_RGBA:
- case PIPE_FORMAT_DXT3_RGBA:
- case PIPE_FORMAT_DXT5_RGBA:
- return SVGA3D_A8R8G8B8;
-#endif
-
- default:
- return SVGA3D_FORMAT_INVALID;
- }
-}
-
-
-static INLINE void
-svga_transfer_dma_band(struct svga_transfer *st,
- SVGA3dTransferType transfer,
- unsigned y, unsigned h, unsigned srcy)
-{
- struct svga_texture *texture = svga_texture(st->base.texture);
- struct svga_screen *screen = svga_screen(texture->base.screen);
- SVGA3dCopyBox box;
- enum pipe_error ret;
-
- SVGA_DBG(DEBUG_DMA, "dma %s sid %p, face %u, (%u, %u, %u) - (%u, %u, %u), %ubpp\n",
- transfer == SVGA3D_WRITE_HOST_VRAM ? "to" : "from",
- texture->handle,
- st->base.face,
- st->base.x,
- y,
- st->base.zslice,
- st->base.x + st->base.width,
- y + h,
- st->base.zslice + 1,
- util_format_get_blocksize(texture->base.format)*8/
- (util_format_get_blockwidth(texture->base.format)*util_format_get_blockheight(texture->base.format)));
-
- box.x = st->base.x;
- box.y = y;
- box.z = st->base.zslice;
- box.w = st->base.width;
- box.h = h;
- box.d = 1;
- box.srcx = 0;
- box.srcy = srcy;
- box.srcz = 0;
-
- pipe_mutex_lock(screen->swc_mutex);
- ret = SVGA3D_SurfaceDMA(screen->swc, st, transfer, &box, 1);
- if(ret != PIPE_OK) {
- screen->swc->flush(screen->swc, NULL);
- ret = SVGA3D_SurfaceDMA(screen->swc, st, transfer, &box, 1);
- assert(ret == PIPE_OK);
- }
- pipe_mutex_unlock(screen->swc_mutex);
-}
-
-
-static INLINE void
-svga_transfer_dma(struct svga_transfer *st,
- SVGA3dTransferType transfer)
-{
- struct svga_texture *texture = svga_texture(st->base.texture);
- struct svga_screen *screen = svga_screen(texture->base.screen);
- struct svga_winsys_screen *sws = screen->sws;
- struct pipe_fence_handle *fence = NULL;
-
- if (transfer == SVGA3D_READ_HOST_VRAM) {
- SVGA_DBG(DEBUG_PERF, "%s: readback transfer\n", __FUNCTION__);
- }
-
-
- if(!st->swbuf) {
- /* Do the DMA transfer in a single go */
-
- svga_transfer_dma_band(st, transfer, st->base.y, st->base.height, 0);
-
- if(transfer == SVGA3D_READ_HOST_VRAM) {
- svga_screen_flush(screen, &fence);
- sws->fence_finish(sws, fence, 0);
- sws->fence_reference(sws, &fence, NULL);
- }
- }
- else {
- unsigned y, h, srcy;
- unsigned blockheight = util_format_get_blockheight(st->base.texture->format);
- h = st->hw_nblocksy * blockheight;
- srcy = 0;
- for(y = 0; y < st->base.height; y += h) {
- unsigned offset, length;
- void *hw, *sw;
-
- if (y + h > st->base.height)
- h = st->base.height - y;
-
- /* Transfer band must be aligned to pixel block boundaries */
- assert(y % blockheight == 0);
- assert(h % blockheight == 0);
-
- offset = y * st->base.stride / blockheight;
- length = h * st->base.stride / blockheight;
-
- sw = (uint8_t *)st->swbuf + offset;
-
- if(transfer == SVGA3D_WRITE_HOST_VRAM) {
- /* Wait for the previous DMAs to complete */
- /* TODO: keep one DMA (at half the size) in the background */
- if(y) {
- svga_screen_flush(screen, &fence);
- sws->fence_finish(sws, fence, 0);
- sws->fence_reference(sws, &fence, NULL);
- }
-
- hw = sws->buffer_map(sws, st->hwbuf, PIPE_BUFFER_USAGE_CPU_WRITE);
- assert(hw);
- if(hw) {
- memcpy(hw, sw, length);
- sws->buffer_unmap(sws, st->hwbuf);
- }
- }
-
- svga_transfer_dma_band(st, transfer, y, h, srcy);
-
- if(transfer == SVGA3D_READ_HOST_VRAM) {
- svga_screen_flush(screen, &fence);
- sws->fence_finish(sws, fence, 0);
-
- hw = sws->buffer_map(sws, st->hwbuf, PIPE_BUFFER_USAGE_CPU_READ);
- assert(hw);
- if(hw) {
- memcpy(sw, hw, length);
- sws->buffer_unmap(sws, st->hwbuf);
- }
- }
- }
- }
-}
-
-
-static struct pipe_texture *
-svga_texture_create(struct pipe_screen *screen,
- const struct pipe_texture *templat)
-{
- struct svga_screen *svgascreen = svga_screen(screen);
- struct svga_texture *tex = CALLOC_STRUCT(svga_texture);
- unsigned width, height, depth;
- unsigned level;
-
- if (!tex)
- goto error1;
-
- tex->base = *templat;
- pipe_reference_init(&tex->base.reference, 1);
- tex->base.screen = screen;
-
- assert(templat->last_level < SVGA_MAX_TEXTURE_LEVELS);
- if(templat->last_level >= SVGA_MAX_TEXTURE_LEVELS)
- goto error2;
-
- width = templat->width0;
- height = templat->height0;
- depth = templat->depth0;
- for(level = 0; level <= templat->last_level; ++level) {
- width = u_minify(width, 1);
- height = u_minify(height, 1);
- depth = u_minify(depth, 1);
- }
-
- tex->key.flags = 0;
- tex->key.size.width = templat->width0;
- tex->key.size.height = templat->height0;
- tex->key.size.depth = templat->depth0;
-
- if(templat->target == PIPE_TEXTURE_CUBE) {
- tex->key.flags |= SVGA3D_SURFACE_CUBEMAP;
- tex->key.numFaces = 6;
- }
- else {
- tex->key.numFaces = 1;
- }
-
- tex->key.cachable = 1;
-
- if(templat->tex_usage & PIPE_TEXTURE_USAGE_SAMPLER)
- tex->key.flags |= SVGA3D_SURFACE_HINT_TEXTURE;
-
- if(templat->tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
- tex->key.cachable = 0;
- }
-
- if(templat->tex_usage & PIPE_TEXTURE_USAGE_SHARED) {
- tex->key.cachable = 0;
- }
-
- if(templat->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT) {
- tex->key.flags |= SVGA3D_SURFACE_HINT_SCANOUT;
- tex->key.cachable = 0;
- }
-
- /*
- * XXX: Never pass the SVGA3D_SURFACE_HINT_RENDERTARGET hint. Mesa cannot
- * know beforehand whether a texture will be used as a rendertarget or not
- * and it always requests PIPE_TEXTURE_USAGE_RENDER_TARGET, therefore
- * passing the SVGA3D_SURFACE_HINT_RENDERTARGET here defeats its purpose.
- */
-#if 0
- if((templat->tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) &&
- !util_format_is_compressed(templat->format))
- tex->key.flags |= SVGA3D_SURFACE_HINT_RENDERTARGET;
-#endif
-
- if(templat->tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL)
- tex->key.flags |= SVGA3D_SURFACE_HINT_DEPTHSTENCIL;
-
- tex->key.numMipLevels = templat->last_level + 1;
-
- tex->key.format = svga_translate_format(templat->format);
- if(tex->key.format == SVGA3D_FORMAT_INVALID)
- goto error2;
-
- SVGA_DBG(DEBUG_DMA, "surface_create for texture\n", tex->handle);
- tex->handle = svga_screen_surface_create(svgascreen, &tex->key);
- if (tex->handle)
- SVGA_DBG(DEBUG_DMA, " --> got sid %p (texture)\n", tex->handle);
-
- return &tex->base;
-
-error2:
- FREE(tex);
-error1:
- return NULL;
-}
-
-
-
-
-
-static struct pipe_texture *
-svga_screen_texture_from_handle(struct pipe_screen *screen,
- const struct pipe_texture *base,
- struct winsys_handle *whandle)
-{
- struct svga_winsys_screen *sws = svga_winsys_screen(screen);
- struct svga_winsys_surface *srf;
- struct svga_texture *tex;
- enum SVGA3dSurfaceFormat format = 0;
- assert(screen);
-
- /* Only supports one type */
- if (base->target != PIPE_TEXTURE_2D ||
- base->last_level != 0 ||
- base->depth0 != 1) {
- return NULL;
- }
-
- srf = sws->surface_from_handle(sws, whandle, &format);
-
- if (!srf)
- return NULL;
-
- if (svga_translate_format(base->format) != format) {
- unsigned f1 = svga_translate_format(base->format);
- unsigned f2 = format;
-
- /* It's okay for XRGB and ARGB or depth with/out stencil to get mixed up */
- if ( !( (f1 == SVGA3D_X8R8G8B8 && f2 == SVGA3D_A8R8G8B8) ||
- (f1 == SVGA3D_A8R8G8B8 && f2 == SVGA3D_X8R8G8B8) ||
- (f1 == SVGA3D_Z_D24X8 && f2 == SVGA3D_Z_D24S8) ) ) {
- debug_printf("%s wrong format %u != %u\n", __FUNCTION__, f1, f2);
- return NULL;
- }
- }
-
- tex = CALLOC_STRUCT(svga_texture);
- if (!tex)
- return NULL;
-
- tex->base = *base;
-
-
- if (format == 1)
- tex->base.format = PIPE_FORMAT_B8G8R8X8_UNORM;
- else if (format == 2)
- tex->base.format = PIPE_FORMAT_B8G8R8A8_UNORM;
-
- pipe_reference_init(&tex->base.reference, 1);
- tex->base.screen = screen;
-
- SVGA_DBG(DEBUG_DMA, "wrap surface sid %p\n", srf);
-
- tex->key.cachable = 0;
- tex->handle = srf;
-
- return &tex->base;
-}
-
-
-static boolean
-svga_screen_texture_get_handle(struct pipe_screen *screen,
- struct pipe_texture *texture,
- struct winsys_handle *whandle)
-{
- struct svga_winsys_screen *sws = svga_winsys_screen(texture->screen);
- unsigned stride;
-
- assert(svga_texture(texture)->key.cachable == 0);
- svga_texture(texture)->key.cachable = 0;
- stride = util_format_get_nblocksx(texture->format, texture->width0) *
- util_format_get_blocksize(texture->format);
- return sws->surface_get_handle(sws, svga_texture(texture)->handle, stride, whandle);
-}
-
-
-static void
-svga_texture_destroy(struct pipe_texture *pt)
-{
- struct svga_screen *ss = svga_screen(pt->screen);
- struct svga_texture *tex = (struct svga_texture *)pt;
-
- ss->texture_timestamp++;
-
- svga_sampler_view_reference(&tex->cached_view, NULL);
-
- /*
- DBG("%s deleting %p\n", __FUNCTION__, (void *) tex);
- */
- SVGA_DBG(DEBUG_DMA, "unref sid %p (texture)\n", tex->handle);
- svga_screen_surface_destroy(ss, &tex->key, &tex->handle);
-
- FREE(tex);
-}
-
-
-static void
-svga_texture_copy_handle(struct svga_context *svga,
- struct svga_screen *ss,
- struct svga_winsys_surface *src_handle,
- unsigned src_x, unsigned src_y, unsigned src_z,
- unsigned src_level, unsigned src_face,
- struct svga_winsys_surface *dst_handle,
- unsigned dst_x, unsigned dst_y, unsigned dst_z,
- unsigned dst_level, unsigned dst_face,
- unsigned width, unsigned height, unsigned depth)
-{
- struct svga_surface dst, src;
- enum pipe_error ret;
- SVGA3dCopyBox box, *boxes;
-
- assert(svga || ss);
-
- src.handle = src_handle;
- src.real_level = src_level;
- src.real_face = src_face;
- src.real_zslice = 0;
-
- dst.handle = dst_handle;
- dst.real_level = dst_level;
- dst.real_face = dst_face;
- dst.real_zslice = 0;
-
- box.x = dst_x;
- box.y = dst_y;
- box.z = dst_z;
- box.w = width;
- box.h = height;
- box.d = depth;
- box.srcx = src_x;
- box.srcy = src_y;
- box.srcz = src_z;
-
-/*
- SVGA_DBG(DEBUG_VIEWS, "mipcopy src: %p %u (%ux%ux%u), dst: %p %u (%ux%ux%u)\n",
- src_handle, src_level, src_x, src_y, src_z,
- dst_handle, dst_level, dst_x, dst_y, dst_z);
-*/
-
- if (svga) {
- ret = SVGA3D_BeginSurfaceCopy(svga->swc,
- &src.base,
- &dst.base,
- &boxes, 1);
- if(ret != PIPE_OK) {
- svga_context_flush(svga, NULL);
- ret = SVGA3D_BeginSurfaceCopy(svga->swc,
- &src.base,
- &dst.base,
- &boxes, 1);
- assert(ret == PIPE_OK);
- }
- *boxes = box;
- SVGA_FIFOCommitAll(svga->swc);
- } else {
- pipe_mutex_lock(ss->swc_mutex);
- ret = SVGA3D_BeginSurfaceCopy(ss->swc,
- &src.base,
- &dst.base,
- &boxes, 1);
- if(ret != PIPE_OK) {
- ss->swc->flush(ss->swc, NULL);
- ret = SVGA3D_BeginSurfaceCopy(ss->swc,
- &src.base,
- &dst.base,
- &boxes, 1);
- assert(ret == PIPE_OK);
- }
- *boxes = box;
- SVGA_FIFOCommitAll(ss->swc);
- pipe_mutex_unlock(ss->swc_mutex);
- }
-}
-
-static struct svga_winsys_surface *
-svga_texture_view_surface(struct pipe_context *pipe,
- struct svga_texture *tex,
- SVGA3dSurfaceFormat format,
- unsigned start_mip,
- unsigned num_mip,
- int face_pick,
- int zslice_pick,
- struct svga_host_surface_cache_key *key) /* OUT */
-{
- struct svga_screen *ss = svga_screen(tex->base.screen);
- struct svga_winsys_surface *handle;
- uint32_t i, j;
- unsigned z_offset = 0;
-
- SVGA_DBG(DEBUG_PERF,
- "svga: Create surface view: face %d zslice %d mips %d..%d\n",
- face_pick, zslice_pick, start_mip, start_mip+num_mip-1);
-
- key->flags = 0;
- key->format = format;
- key->numMipLevels = num_mip;
- key->size.width = u_minify(tex->base.width0, start_mip);
- key->size.height = u_minify(tex->base.height0, start_mip);
- key->size.depth = zslice_pick < 0 ? u_minify(tex->base.depth0, start_mip) : 1;
- key->cachable = 1;
- assert(key->size.depth == 1);
-
- if(tex->base.target == PIPE_TEXTURE_CUBE && face_pick < 0) {
- key->flags |= SVGA3D_SURFACE_CUBEMAP;
- key->numFaces = 6;
- } else {
- key->numFaces = 1;
- }
-
- if(key->format == SVGA3D_FORMAT_INVALID) {
- key->cachable = 0;
- return NULL;
- }
-
- SVGA_DBG(DEBUG_DMA, "surface_create for texture view\n");
- handle = svga_screen_surface_create(ss, key);
- if (!handle) {
- key->cachable = 0;
- return NULL;
- }
-
- SVGA_DBG(DEBUG_DMA, " --> got sid %p (texture view)\n", handle);
-
- if (face_pick < 0)
- face_pick = 0;
-
- if (zslice_pick >= 0)
- z_offset = zslice_pick;
-
- for (i = 0; i < key->numMipLevels; i++) {
- for (j = 0; j < key->numFaces; j++) {
- if(tex->defined[j + face_pick][i + start_mip]) {
- unsigned depth = (zslice_pick < 0 ?
- u_minify(tex->base.depth0, i + start_mip) :
- 1);
-
- svga_texture_copy_handle(svga_context(pipe),
- ss,
- tex->handle,
- 0, 0, z_offset,
- i + start_mip,
- j + face_pick,
- handle, 0, 0, 0, i, j,
- u_minify(tex->base.width0, i + start_mip),
- u_minify(tex->base.height0, i + start_mip),
- depth);
- }
- }
- }
-
- return handle;
-}
-
-
-static struct pipe_surface *
-svga_get_tex_surface(struct pipe_screen *screen,
- struct pipe_texture *pt,
- unsigned face, unsigned level, unsigned zslice,
- unsigned flags)
-{
- struct svga_texture *tex = svga_texture(pt);
- struct svga_surface *s;
- boolean render = flags & PIPE_BUFFER_USAGE_GPU_WRITE ? TRUE : FALSE;
- boolean view = FALSE;
- SVGA3dSurfaceFormat format;
-
- s = CALLOC_STRUCT(svga_surface);
- if (!s)
- return NULL;
-
- pipe_reference_init(&s->base.reference, 1);
- pipe_texture_reference(&s->base.texture, pt);
- s->base.format = pt->format;
- s->base.width = u_minify(pt->width0, level);
- s->base.height = u_minify(pt->height0, level);
- s->base.usage = flags;
- s->base.level = level;
- s->base.face = face;
- s->base.zslice = zslice;
-
- if (!render)
- format = svga_translate_format(pt->format);
- else
- format = svga_translate_format_render(pt->format);
-
- assert(format != SVGA3D_FORMAT_INVALID);
- assert(!(flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE));
-
-
- if (svga_screen(screen)->debug.force_surface_view)
- view = TRUE;
-
- /* Currently only used for compressed textures */
- if (render &&
- format != svga_translate_format(pt->format)) {
- view = TRUE;
- }
-
- if (level != 0 &&
- svga_screen(screen)->debug.force_level_surface_view)
- view = TRUE;
-
- if (pt->target == PIPE_TEXTURE_3D)
- view = TRUE;
-
- if (svga_screen(screen)->debug.no_surface_view)
- view = FALSE;
-
- if (view) {
- SVGA_DBG(DEBUG_VIEWS, "svga: Surface view: yes %p, level %u face %u z %u, %p\n",
- pt, level, face, zslice, s);
-
- s->handle = svga_texture_view_surface(NULL, tex, format, level, 1, face, zslice,
- &s->key);
- s->real_face = 0;
- s->real_level = 0;
- s->real_zslice = 0;
- } else {
- SVGA_DBG(DEBUG_VIEWS, "svga: Surface view: no %p, level %u, face %u, z %u, %p\n",
- pt, level, face, zslice, s);
-
- memset(&s->key, 0, sizeof s->key);
- s->handle = tex->handle;
- s->real_face = face;
- s->real_level = level;
- s->real_zslice = zslice;
- }
-
- return &s->base;
-}
-
-
-static void
-svga_tex_surface_destroy(struct pipe_surface *surf)
-{
- struct svga_surface *s = svga_surface(surf);
- struct svga_texture *t = svga_texture(surf->texture);
- struct svga_screen *ss = svga_screen(surf->texture->screen);
-
- if(s->handle != t->handle) {
- SVGA_DBG(DEBUG_DMA, "unref sid %p (tex surface)\n", s->handle);
- svga_screen_surface_destroy(ss, &s->key, &s->handle);
- }
-
- pipe_texture_reference(&surf->texture, NULL);
- FREE(surf);
-}
-
-
-static INLINE void
-svga_mark_surface_dirty(struct pipe_surface *surf)
-{
- struct svga_surface *s = svga_surface(surf);
-
- if(!s->dirty) {
- struct svga_texture *tex = svga_texture(surf->texture);
-
- s->dirty = TRUE;
-
- if (s->handle == tex->handle)
- tex->defined[surf->face][surf->level] = TRUE;
- else {
- /* this will happen later in svga_propagate_surface */
- }
- }
-}
-
-
-void svga_mark_surfaces_dirty(struct svga_context *svga)
-{
- unsigned i;
-
- for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
- if (svga->curr.framebuffer.cbufs[i])
- svga_mark_surface_dirty(svga->curr.framebuffer.cbufs[i]);
- }
- if (svga->curr.framebuffer.zsbuf)
- svga_mark_surface_dirty(svga->curr.framebuffer.zsbuf);
-}
-
-/**
- * Progagate any changes from surfaces to texture.
- * pipe is optional context to inline the blit command in.
- */
-void
-svga_propagate_surface(struct pipe_context *pipe, struct pipe_surface *surf)
-{
- struct svga_surface *s = svga_surface(surf);
- struct svga_texture *tex = svga_texture(surf->texture);
- struct svga_screen *ss = svga_screen(surf->texture->screen);
-
- if (!s->dirty)
- return;
-
- s->dirty = FALSE;
- ss->texture_timestamp++;
- tex->view_age[surf->level] = ++(tex->age);
-
- if (s->handle != tex->handle) {
- SVGA_DBG(DEBUG_VIEWS, "svga: Surface propagate: tex %p, level %u, from %p\n", tex, surf->level, surf);
- svga_texture_copy_handle(svga_context(pipe), ss,
- s->handle, 0, 0, 0, s->real_level, s->real_face,
- tex->handle, 0, 0, surf->zslice, surf->level, surf->face,
- u_minify(tex->base.width0, surf->level),
- u_minify(tex->base.height0, surf->level), 1);
- tex->defined[surf->face][surf->level] = TRUE;
- }
-}
-
-/**
- * Check if we should call svga_propagate_surface on the surface.
- */
-extern boolean
-svga_surface_needs_propagation(struct pipe_surface *surf)
-{
- struct svga_surface *s = svga_surface(surf);
- struct svga_texture *tex = svga_texture(surf->texture);
-
- return s->dirty && s->handle != tex->handle;
-}
-
-/* XXX: Still implementing this as if it was a screen function, but
- * can now modify it to queue transfers on the context.
- */
-static struct pipe_tex_transfer *
-svga_get_tex_transfer(struct pipe_context *pipe,
- struct pipe_texture *texture,
- unsigned face, unsigned level, unsigned zslice,
- enum pipe_transfer_usage usage, unsigned x, unsigned y,
- unsigned w, unsigned h)
-{
- struct svga_screen *ss = svga_screen(pipe->screen);
- struct svga_winsys_screen *sws = ss->sws;
- struct svga_transfer *st;
- unsigned nblocksx = util_format_get_nblocksx(texture->format, w);
- unsigned nblocksy = util_format_get_nblocksy(texture->format, h);
-
- /* We can't map texture storage directly */
- if (usage & PIPE_TRANSFER_MAP_DIRECTLY)
- return NULL;
-
- st = CALLOC_STRUCT(svga_transfer);
- if (!st)
- return NULL;
-
- st->base.x = x;
- st->base.y = y;
- st->base.width = w;
- st->base.height = h;
- st->base.stride = nblocksx*util_format_get_blocksize(texture->format);
- st->base.usage = usage;
- st->base.face = face;
- st->base.level = level;
- st->base.zslice = zslice;
-
- st->hw_nblocksy = nblocksy;
-
- st->hwbuf = svga_winsys_buffer_create(ss,
- 1,
- 0,
- st->hw_nblocksy*st->base.stride);
- while(!st->hwbuf && (st->hw_nblocksy /= 2)) {
- st->hwbuf = svga_winsys_buffer_create(ss,
- 1,
- 0,
- st->hw_nblocksy*st->base.stride);
- }
-
- if(!st->hwbuf)
- goto no_hwbuf;
-
- if(st->hw_nblocksy < nblocksy) {
- /* We couldn't allocate a hardware buffer big enough for the transfer,
- * so allocate regular malloc memory instead */
- debug_printf("%s: failed to allocate %u KB of DMA, splitting into %u x %u KB DMA transfers\n",
- __FUNCTION__,
- (nblocksy*st->base.stride + 1023)/1024,
- (nblocksy + st->hw_nblocksy - 1)/st->hw_nblocksy,
- (st->hw_nblocksy*st->base.stride + 1023)/1024);
- st->swbuf = MALLOC(nblocksy*st->base.stride);
- if(!st->swbuf)
- goto no_swbuf;
- }
-
- pipe_texture_reference(&st->base.texture, texture);
-
- if (usage & PIPE_TRANSFER_READ)
- svga_transfer_dma(st, SVGA3D_READ_HOST_VRAM);
-
- return &st->base;
-
-no_swbuf:
- sws->buffer_destroy(sws, st->hwbuf);
-no_hwbuf:
- FREE(st);
- return NULL;
-}
-
-
-/* XXX: Still implementing this as if it was a screen function, but
- * can now modify it to queue transfers on the context.
- */
-static void *
-svga_transfer_map( struct pipe_context *pipe,
- struct pipe_tex_transfer *transfer )
-{
- struct svga_screen *ss = svga_screen(pipe->screen);
- struct svga_winsys_screen *sws = ss->sws;
- struct svga_transfer *st = svga_transfer(transfer);
-
- if(st->swbuf)
- return st->swbuf;
- else
- /* The wait for read transfers already happened when svga_transfer_dma
- * was called. */
- return sws->buffer_map(sws, st->hwbuf,
- pipe_transfer_buffer_flags(transfer));
-}
-
-
-/* XXX: Still implementing this as if it was a screen function, but
- * can now modify it to queue transfers on the context.
- */
-static void
-svga_transfer_unmap(struct pipe_context *pipe,
- struct pipe_tex_transfer *transfer)
-{
- struct svga_screen *ss = svga_screen(pipe->screen);
- struct svga_winsys_screen *sws = ss->sws;
- struct svga_transfer *st = svga_transfer(transfer);
-
- if(!st->swbuf)
- sws->buffer_unmap(sws, st->hwbuf);
-}
-
-
-static void
-svga_transfer_destroy(struct pipe_context *pipe,
- struct pipe_tex_transfer *transfer)
-{
- struct svga_texture *tex = svga_texture(transfer->texture);
- struct svga_screen *ss = svga_screen(pipe->screen);
- struct svga_winsys_screen *sws = ss->sws;
- struct svga_transfer *st = svga_transfer(transfer);
-
- if (st->base.usage & PIPE_TRANSFER_WRITE) {
- svga_transfer_dma(st, SVGA3D_WRITE_HOST_VRAM);
- ss->texture_timestamp++;
- tex->view_age[transfer->level] = ++(tex->age);
- tex->defined[transfer->face][transfer->level] = TRUE;
- }
-
- pipe_texture_reference(&st->base.texture, NULL);
- FREE(st->swbuf);
- sws->buffer_destroy(sws, st->hwbuf);
- FREE(st);
-}
-
-
-void
-svga_init_texture_functions(struct pipe_context *pipe)
-{
- pipe->tex_transfer = svga_get_transfer;
- pipe->transfer_map = svga_transfer_map;
- pipe->transfer_unmap = svga_transfer_unmap;
- pipe->transfer_destroy = svga_transfer_destroy;
-}
-
-
-void
-svga_screen_init_texture_functions(struct pipe_screen *screen)
-{
- screen->texture_create = svga_texture_create;
- screen->texture_from_handle = svga_screen_texture_from_handle;
- screen->texture_get_handle = svga_screen_texture_get_handle;
- screen->texture_destroy = svga_texture_destroy;
- screen->get_tex_surface = svga_get_tex_surface;
- screen->tex_surface_destroy = svga_tex_surface_destroy;
-}
-
-/***********************************************************************
- */
-
-struct svga_sampler_view *
-svga_get_tex_sampler_view(struct pipe_context *pipe, struct pipe_texture *pt,
- unsigned min_lod, unsigned max_lod)
-{
- struct svga_screen *ss = svga_screen(pt->screen);
- struct svga_texture *tex = svga_texture(pt);
- struct svga_sampler_view *sv = NULL;
- SVGA3dSurfaceFormat format = svga_translate_format(pt->format);
- boolean view = TRUE;
-
- assert(pt);
- assert(min_lod >= 0);
- assert(min_lod <= max_lod);
- assert(max_lod <= pt->last_level);
-
-
- /* Is a view needed */
- {
- /*
- * Can't control max lod. For first level views and when we only
- * look at one level we disable mip filtering to achive the same
- * results as a view.
- */
- if (min_lod == 0 && max_lod >= pt->last_level)
- view = FALSE;
-
- if (util_format_is_compressed(pt->format) && view) {
- format = svga_translate_format_render(pt->format);
- }
-
- if (ss->debug.no_sampler_view)
- view = FALSE;
-
- if (ss->debug.force_sampler_view)
- view = TRUE;
- }
-
- /* First try the cache */
- if (view) {
- pipe_mutex_lock(ss->tex_mutex);
- if (tex->cached_view &&
- tex->cached_view->min_lod == min_lod &&
- tex->cached_view->max_lod == max_lod) {
- svga_sampler_view_reference(&sv, tex->cached_view);
- pipe_mutex_unlock(ss->tex_mutex);
- SVGA_DBG(DEBUG_VIEWS, "svga: Sampler view: reuse %p, %u %u, last %u\n",
- pt, min_lod, max_lod, pt->last_level);
- svga_validate_sampler_view(svga_context(pipe), sv);
- return sv;
- }
- pipe_mutex_unlock(ss->tex_mutex);
- }
-
- sv = CALLOC_STRUCT(svga_sampler_view);
- pipe_reference_init(&sv->reference, 1);
- pipe_texture_reference(&sv->texture, pt);
- sv->min_lod = min_lod;
- sv->max_lod = max_lod;
-
- /* No view needed just use the whole texture */
- if (!view) {
- SVGA_DBG(DEBUG_VIEWS,
- "svga: Sampler view: no %p, mips %u..%u, nr %u, size (%ux%ux%u), last %u\n",
- pt, min_lod, max_lod,
- max_lod - min_lod + 1,
- pt->width0,
- pt->height0,
- pt->depth0,
- pt->last_level);
- sv->key.cachable = 0;
- sv->handle = tex->handle;
- return sv;
- }
-
- SVGA_DBG(DEBUG_VIEWS,
- "svga: Sampler view: yes %p, mips %u..%u, nr %u, size (%ux%ux%u), last %u\n",
- pt, min_lod, max_lod,
- max_lod - min_lod + 1,
- pt->width0,
- pt->height0,
- pt->depth0,
- pt->last_level);
-
- sv->age = tex->age;
- sv->handle = svga_texture_view_surface(pipe, tex, format,
- min_lod,
- max_lod - min_lod + 1,
- -1, -1,
- &sv->key);
-
- if (!sv->handle) {
- assert(0);
- sv->key.cachable = 0;
- sv->handle = tex->handle;
- return sv;
- }
-
- pipe_mutex_lock(ss->tex_mutex);
- svga_sampler_view_reference(&tex->cached_view, sv);
- pipe_mutex_unlock(ss->tex_mutex);
-
- return sv;
-}
-
-void
-svga_validate_sampler_view(struct svga_context *svga, struct svga_sampler_view *v)
-{
- struct svga_texture *tex = svga_texture(v->texture);
- unsigned numFaces;
- unsigned age = 0;
- int i, k;
-
- assert(svga);
-
- if (v->handle == tex->handle)
- return;
-
- age = tex->age;
-
- if(tex->base.target == PIPE_TEXTURE_CUBE)
- numFaces = 6;
- else
- numFaces = 1;
-
- for (i = v->min_lod; i <= v->max_lod; i++) {
- for (k = 0; k < numFaces; k++) {
- if (v->age < tex->view_age[i])
- svga_texture_copy_handle(svga, NULL,
- tex->handle, 0, 0, 0, i, k,
- v->handle, 0, 0, 0, i - v->min_lod, k,
- u_minify(tex->base.width0, i),
- u_minify(tex->base.height0, i),
- u_minify(tex->base.depth0, i));
- }
- }
-
- v->age = age;
-}
-
-void
-svga_destroy_sampler_view_priv(struct svga_sampler_view *v)
-{
- struct svga_texture *tex = svga_texture(v->texture);
-
- if(v->handle != tex->handle) {
- struct svga_screen *ss = svga_screen(v->texture->screen);
- SVGA_DBG(DEBUG_DMA, "unref sid %p (sampler view)\n", v->handle);
- svga_screen_surface_destroy(ss, &v->key, &v->handle);
- }
- pipe_texture_reference(&v->texture, NULL);
- FREE(v);
-}
diff --git a/src/gallium/drivers/svga/svga_state_constants.c b/src/gallium/drivers/svga/svga_state_constants.c
index 493f78a990..eeffa03cd2 100644
--- a/src/gallium/drivers/svga/svga_state_constants.c
+++ b/src/gallium/drivers/svga/svga_state_constants.c
@@ -82,6 +82,7 @@ static int emit_consts( struct svga_context *svga,
int offset,
int unit )
{
+ struct pipe_transfer *transfer = NULL;
struct pipe_screen *screen = svga->pipe.screen;
unsigned count;
const float (*data)[4] = NULL;
@@ -91,11 +92,12 @@ static int emit_consts( struct svga_context *svga,
if (svga->curr.cb[unit] == NULL)
goto done;
- count = svga->curr.cb[unit]->size / (4 * sizeof(float));
+ count = svga->curr.cb[unit]->width0 / (4 * sizeof(float));
- data = (const float (*)[4])pipe_buffer_map(screen,
+ data = (const float (*)[4])pipe_buffer_map(&svga->pipe,
svga->curr.cb[unit],
- PIPE_BUFFER_USAGE_CPU_READ);
+ PIPE_BUFFER_USAGE_CPU_READ,
+ &transfer);
if (data == NULL) {
ret = PIPE_ERROR_OUT_OF_MEMORY;
goto done;
@@ -109,7 +111,7 @@ static int emit_consts( struct svga_context *svga,
done:
if (data)
- pipe_buffer_unmap(screen, svga->curr.cb[unit]);
+ pipe_buffer_unmap(&svga->pipe, svga->curr.cb[unit], transfer);
return ret;
}
@@ -137,7 +139,7 @@ static int emit_fs_consts( struct svga_context *svga,
for (i = 0; i < key->num_textures; i++) {
if (key->tex[i].unnormalized) {
- struct pipe_texture *tex = svga->curr.sampler_views[i]->texture;
+ struct pipe_resource *tex = svga->curr.sampler_views[i]->texture;
float data[4];
data[0] = 1.0 / (float)tex->width0;
diff --git a/src/gallium/drivers/svga/svga_state_tss.c b/src/gallium/drivers/svga/svga_state_tss.c
index c08ec7c2e8..a8d9f6d5c1 100644
--- a/src/gallium/drivers/svga/svga_state_tss.c
+++ b/src/gallium/drivers/svga/svga_state_tss.c
@@ -27,7 +27,7 @@
#include "pipe/p_defines.h"
#include "util/u_math.h"
-#include "svga_screen_texture.h"
+#include "svga_sampler_view.h"
#include "svga_winsys.h"
#include "svga_context.h"
#include "svga_state.h"
@@ -45,7 +45,7 @@ void svga_cleanup_tss_binding(struct svga_context *svga)
svga_sampler_view_reference(&view->v, NULL);
pipe_sampler_view_reference( &svga->curr.sampler_views[i], NULL );
- pipe_texture_reference( &view->texture, NULL );
+ pipe_resource_reference( &view->texture, NULL );
view->dirty = 1;
}
@@ -77,7 +77,7 @@ update_tss_binding(struct svga_context *svga,
for (i = 0; i < count; i++) {
const struct svga_sampler_state *s = svga->curr.sampler[i];
struct svga_hw_view_state *view = &svga->state.hw_draw.views[i];
- struct pipe_texture *texture = NULL;
+ struct pipe_resource *texture = NULL;
/* get min max lod */
if (svga->curr.sampler_views[i]) {
@@ -94,7 +94,7 @@ update_tss_binding(struct svga_context *svga,
view->max_lod != max_lod) {
svga_sampler_view_reference(&view->v, NULL);
- pipe_texture_reference( &view->texture, texture );
+ pipe_resource_reference( &view->texture, texture );
view->dirty = TRUE;
view->min_lod = min_lod;
diff --git a/src/gallium/drivers/svga/svga_state_vdecl.c b/src/gallium/drivers/svga/svga_state_vdecl.c
index f531e22304..3af7bf2b35 100644
--- a/src/gallium/drivers/svga/svga_state_vdecl.c
+++ b/src/gallium/drivers/svga/svga_state_vdecl.c
@@ -33,7 +33,7 @@
#include "svga_draw.h"
#include "svga_tgsi.h"
#include "svga_screen.h"
-#include "svga_screen_buffer.h"
+#include "svga_resource_buffer.h"
#include "svga_hw_reg.h"
@@ -59,8 +59,8 @@ upload_user_buffers( struct svga_context *svga )
if (!buffer->uploaded.buffer) {
ret = u_upload_buffer( svga->upload_vb,
0,
- buffer->base.size,
- &buffer->base,
+ buffer->b.b.width0,
+ &buffer->b.b,
&buffer->uploaded.offset,
&buffer->uploaded.buffer );
if (ret)
@@ -73,10 +73,10 @@ upload_user_buffers( struct svga_context *svga )
buffer,
buffer->uploaded.buffer,
buffer->uploaded.offset,
- buffer->base.size);
+ buffer->b.b.width0);
}
- pipe_buffer_reference( &svga->curr.vb[i].buffer, buffer->uploaded.buffer );
+ pipe_resource_reference( &svga->curr.vb[i].buffer, buffer->uploaded.buffer );
svga->curr.vb[i].buffer_offset = buffer->uploaded.offset;
}
}
diff --git a/src/gallium/drivers/svga/svga_state_vs.c b/src/gallium/drivers/svga/svga_state_vs.c
index 781f7bf533..e9ed0f9d4f 100644
--- a/src/gallium/drivers/svga/svga_state_vs.c
+++ b/src/gallium/drivers/svga/svga_state_vs.c
@@ -190,9 +190,11 @@ static int update_zero_stride( struct svga_context *svga,
const struct pipe_vertex_element *vel = &svga->curr.velems->velem[i];
const struct pipe_vertex_buffer *vbuffer = &svga->curr.vb[
vel->vertex_buffer_index];
+
if (vbuffer->stride == 0) {
unsigned const_idx =
svga->curr.num_zero_stride_vertex_elements;
+ struct pipe_transfer *transfer;
struct translate *translate;
struct translate_key key;
void *mapped_buffer;
@@ -218,19 +220,23 @@ static int update_zero_stride( struct svga_context *svga,
assert(vel->src_offset == 0);
- mapped_buffer = pipe_buffer_map_range(svga->pipe.screen,
+ mapped_buffer = pipe_buffer_map_range(&svga->pipe,
vbuffer->buffer,
vel->src_offset,
util_format_get_blocksize(vel->src_format),
- PIPE_BUFFER_USAGE_CPU_READ);
+ PIPE_BUFFER_USAGE_CPU_READ,
+ &transfer);
+
translate->set_buffer(translate, vel->vertex_buffer_index,
mapped_buffer,
vbuffer->stride);
translate->run(translate, 0, 1, 0,
svga->curr.zero_stride_constants);
- pipe_buffer_unmap(svga->pipe.screen,
- vbuffer->buffer);
+ pipe_buffer_unmap(&svga->pipe,
+ vbuffer->buffer,
+ transfer);
+
translate->release(translate);
}
}
diff --git a/src/gallium/drivers/svga/svga_surface.c b/src/gallium/drivers/svga/svga_surface.c
new file mode 100644
index 0000000000..8ae80a0dcc
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_surface.c
@@ -0,0 +1,384 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+#include "svga_cmd.h"
+
+#include "pipe/p_state.h"
+#include "pipe/p_defines.h"
+#include "util/u_inlines.h"
+#include "os/os_thread.h"
+#include "util/u_format.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
+#include "svga_screen.h"
+#include "svga_context.h"
+#include "svga_resource_texture.h"
+#include "svga_surface.h"
+#include "svga_winsys.h"
+#include "svga_debug.h"
+
+#include <util/u_string.h>
+
+
+static void
+svga_texture_copy_handle(struct svga_context *svga,
+ struct svga_screen *ss,
+ struct svga_winsys_surface *src_handle,
+ unsigned src_x, unsigned src_y, unsigned src_z,
+ unsigned src_level, unsigned src_face,
+ struct svga_winsys_surface *dst_handle,
+ unsigned dst_x, unsigned dst_y, unsigned dst_z,
+ unsigned dst_level, unsigned dst_face,
+ unsigned width, unsigned height, unsigned depth)
+{
+ struct svga_surface dst, src;
+ enum pipe_error ret;
+ SVGA3dCopyBox box, *boxes;
+
+ assert(svga || ss);
+
+ src.handle = src_handle;
+ src.real_level = src_level;
+ src.real_face = src_face;
+ src.real_zslice = 0;
+
+ dst.handle = dst_handle;
+ dst.real_level = dst_level;
+ dst.real_face = dst_face;
+ dst.real_zslice = 0;
+
+ box.x = dst_x;
+ box.y = dst_y;
+ box.z = dst_z;
+ box.w = width;
+ box.h = height;
+ box.d = depth;
+ box.srcx = src_x;
+ box.srcy = src_y;
+ box.srcz = src_z;
+
+/*
+ SVGA_DBG(DEBUG_VIEWS, "mipcopy src: %p %u (%ux%ux%u), dst: %p %u (%ux%ux%u)\n",
+ src_handle, src_level, src_x, src_y, src_z,
+ dst_handle, dst_level, dst_x, dst_y, dst_z);
+*/
+
+ if (svga) {
+ ret = SVGA3D_BeginSurfaceCopy(svga->swc,
+ &src.base,
+ &dst.base,
+ &boxes, 1);
+ if(ret != PIPE_OK) {
+ svga_context_flush(svga, NULL);
+ ret = SVGA3D_BeginSurfaceCopy(svga->swc,
+ &src.base,
+ &dst.base,
+ &boxes, 1);
+ assert(ret == PIPE_OK);
+ }
+ *boxes = box;
+ SVGA_FIFOCommitAll(svga->swc);
+ } else {
+ pipe_mutex_lock(ss->swc_mutex);
+ ret = SVGA3D_BeginSurfaceCopy(ss->swc,
+ &src.base,
+ &dst.base,
+ &boxes, 1);
+ if(ret != PIPE_OK) {
+ ss->swc->flush(ss->swc, NULL);
+ ret = SVGA3D_BeginSurfaceCopy(ss->swc,
+ &src.base,
+ &dst.base,
+ &boxes, 1);
+ assert(ret == PIPE_OK);
+ }
+ *boxes = box;
+ SVGA_FIFOCommitAll(ss->swc);
+ pipe_mutex_unlock(ss->swc_mutex);
+ }
+}
+
+
+struct svga_winsys_surface *
+svga_texture_view_surface(struct pipe_context *pipe,
+ struct svga_texture *tex,
+ SVGA3dSurfaceFormat format,
+ unsigned start_mip,
+ unsigned num_mip,
+ int face_pick,
+ int zslice_pick,
+ struct svga_host_surface_cache_key *key) /* OUT */
+{
+ struct svga_screen *ss = svga_screen(pipe->screen);
+ struct svga_winsys_surface *handle;
+ uint32_t i, j;
+ unsigned z_offset = 0;
+
+ SVGA_DBG(DEBUG_PERF,
+ "svga: Create surface view: face %d zslice %d mips %d..%d\n",
+ face_pick, zslice_pick, start_mip, start_mip+num_mip-1);
+
+ key->flags = 0;
+ key->format = format;
+ key->numMipLevels = num_mip;
+ key->size.width = u_minify(tex->b.b.width0, start_mip);
+ key->size.height = u_minify(tex->b.b.height0, start_mip);
+ key->size.depth = zslice_pick < 0 ? u_minify(tex->b.b.depth0, start_mip) : 1;
+ key->cachable = 1;
+ assert(key->size.depth == 1);
+
+ if(tex->b.b.target == PIPE_TEXTURE_CUBE && face_pick < 0) {
+ key->flags |= SVGA3D_SURFACE_CUBEMAP;
+ key->numFaces = 6;
+ } else {
+ key->numFaces = 1;
+ }
+
+ if(key->format == SVGA3D_FORMAT_INVALID) {
+ key->cachable = 0;
+ return NULL;
+ }
+
+ SVGA_DBG(DEBUG_DMA, "surface_create for texture view\n");
+ handle = svga_screen_surface_create(ss, key);
+ if (!handle) {
+ key->cachable = 0;
+ return NULL;
+ }
+
+ SVGA_DBG(DEBUG_DMA, " --> got sid %p (texture view)\n", handle);
+
+ if (face_pick < 0)
+ face_pick = 0;
+
+ if (zslice_pick >= 0)
+ z_offset = zslice_pick;
+
+ for (i = 0; i < key->numMipLevels; i++) {
+ for (j = 0; j < key->numFaces; j++) {
+ if(tex->defined[j + face_pick][i + start_mip]) {
+ unsigned depth = (zslice_pick < 0 ?
+ u_minify(tex->b.b.depth0, i + start_mip) :
+ 1);
+
+ svga_texture_copy_handle(svga_context(pipe),
+ ss,
+ tex->handle,
+ 0, 0, z_offset,
+ i + start_mip,
+ j + face_pick,
+ handle, 0, 0, 0, i, j,
+ u_minify(tex->b.b.width0, i + start_mip),
+ u_minify(tex->b.b.height0, i + start_mip),
+ depth);
+ }
+ }
+ }
+
+ return handle;
+}
+
+
+static struct pipe_surface *
+svga_get_tex_surface(struct pipe_screen *screen,
+ struct pipe_resource *pt,
+ unsigned face, unsigned level, unsigned zslice,
+ unsigned flags)
+{
+ struct svga_texture *tex = svga_texture(pt);
+ struct svga_surface *s;
+ boolean render = flags & PIPE_BUFFER_USAGE_GPU_WRITE ? TRUE : FALSE;
+ boolean view = FALSE;
+ SVGA3dSurfaceFormat format;
+
+ s = CALLOC_STRUCT(svga_surface);
+ if (!s)
+ return NULL;
+
+ pipe_reference_init(&s->base.reference, 1);
+ pipe_resource_reference(&s->base.texture, pt);
+ s->base.format = pt->format;
+ s->base.width = u_minify(pt->width0, level);
+ s->base.height = u_minify(pt->height0, level);
+ s->base.usage = flags;
+ s->base.level = level;
+ s->base.face = face;
+ s->base.zslice = zslice;
+
+ if (!render)
+ format = svga_translate_format(pt->format);
+ else
+ format = svga_translate_format_render(pt->format);
+
+ assert(format != SVGA3D_FORMAT_INVALID);
+ assert(!(flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE));
+
+
+ if (svga_screen(screen)->debug.force_surface_view)
+ view = TRUE;
+
+ /* Currently only used for compressed textures */
+ if (render &&
+ format != svga_translate_format(pt->format)) {
+ view = TRUE;
+ }
+
+ if (level != 0 &&
+ svga_screen(screen)->debug.force_level_surface_view)
+ view = TRUE;
+
+ if (pt->target == PIPE_TEXTURE_3D)
+ view = TRUE;
+
+ if (svga_screen(screen)->debug.no_surface_view)
+ view = FALSE;
+
+ if (view) {
+ SVGA_DBG(DEBUG_VIEWS, "svga: Surface view: yes %p, level %u face %u z %u, %p\n",
+ pt, level, face, zslice, s);
+
+ s->handle = svga_texture_view_surface(NULL, tex, format, level, 1, face, zslice,
+ &s->key);
+ s->real_face = 0;
+ s->real_level = 0;
+ s->real_zslice = 0;
+ } else {
+ SVGA_DBG(DEBUG_VIEWS, "svga: Surface view: no %p, level %u, face %u, z %u, %p\n",
+ pt, level, face, zslice, s);
+
+ memset(&s->key, 0, sizeof s->key);
+ s->handle = tex->handle;
+ s->real_face = face;
+ s->real_level = level;
+ s->real_zslice = zslice;
+ }
+
+ return &s->base;
+}
+
+
+static void
+svga_tex_surface_destroy(struct pipe_surface *surf)
+{
+ struct svga_surface *s = svga_surface(surf);
+ struct svga_texture *t = svga_texture(surf->texture);
+ struct svga_screen *ss = svga_screen(surf->texture->screen);
+
+ if(s->handle != t->handle) {
+ SVGA_DBG(DEBUG_DMA, "unref sid %p (tex surface)\n", s->handle);
+ svga_screen_surface_destroy(ss, &s->key, &s->handle);
+ }
+
+ pipe_resource_reference(&surf->texture, NULL);
+ FREE(surf);
+}
+
+
+static INLINE void
+svga_mark_surface_dirty(struct pipe_surface *surf)
+{
+ struct svga_surface *s = svga_surface(surf);
+
+ if(!s->dirty) {
+ struct svga_texture *tex = svga_texture(surf->texture);
+
+ s->dirty = TRUE;
+
+ if (s->handle == tex->handle)
+ tex->defined[surf->face][surf->level] = TRUE;
+ else {
+ /* this will happen later in svga_propagate_surface */
+ }
+ }
+}
+
+
+void svga_mark_surfaces_dirty(struct svga_context *svga)
+{
+ unsigned i;
+
+ for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
+ if (svga->curr.framebuffer.cbufs[i])
+ svga_mark_surface_dirty(svga->curr.framebuffer.cbufs[i]);
+ }
+ if (svga->curr.framebuffer.zsbuf)
+ svga_mark_surface_dirty(svga->curr.framebuffer.zsbuf);
+}
+
+
+/**
+ * Progagate any changes from surfaces to texture.
+ * pipe is optional context to inline the blit command in.
+ */
+void
+svga_propagate_surface(struct pipe_context *pipe, struct pipe_surface *surf)
+{
+ struct svga_surface *s = svga_surface(surf);
+ struct svga_texture *tex = svga_texture(surf->texture);
+ struct svga_screen *ss = svga_screen(surf->texture->screen);
+
+ if (!s->dirty)
+ return;
+
+ s->dirty = FALSE;
+ ss->texture_timestamp++;
+ tex->view_age[surf->level] = ++(tex->age);
+
+ if (s->handle != tex->handle) {
+ SVGA_DBG(DEBUG_VIEWS, "svga: Surface propagate: tex %p, level %u, from %p\n", tex, surf->level, surf);
+ svga_texture_copy_handle(svga_context(pipe), ss,
+ s->handle, 0, 0, 0, s->real_level, s->real_face,
+ tex->handle, 0, 0, surf->zslice, surf->level, surf->face,
+ u_minify(tex->b.b.width0, surf->level),
+ u_minify(tex->b.b.height0, surf->level), 1);
+ tex->defined[surf->face][surf->level] = TRUE;
+ }
+}
+
+/**
+ * Check if we should call svga_propagate_surface on the surface.
+ */
+boolean
+svga_surface_needs_propagation(struct pipe_surface *surf)
+{
+ struct svga_surface *s = svga_surface(surf);
+ struct svga_texture *tex = svga_texture(surf->texture);
+
+ return s->dirty && s->handle != tex->handle;
+}
+
+
+
+
+
+
+void
+svga_screen_init_surface_functions(struct pipe_screen *screen)
+{
+ screen->get_tex_surface = svga_get_tex_surface;
+ screen->tex_surface_destroy = svga_tex_surface_destroy;
+}
+
diff --git a/src/gallium/drivers/svga/svga_surface.h b/src/gallium/drivers/svga/svga_surface.h
new file mode 100644
index 0000000000..618445927d
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_surface.h
@@ -0,0 +1,85 @@
+/**********************************************************
+ * Copyright 2008-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, sublicense, 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 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * 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.
+ *
+ **********************************************************/
+
+#ifndef SVGA_SURFACE_H
+#define SVGA_SURFACE_H
+
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_state.h"
+#include "util/u_inlines.h"
+#include "svga_screen_cache.h"
+
+struct pipe_context;
+struct pipe_screen;
+struct svga_context;
+struct svga_texture;
+struct svga_winsys_surface;
+enum SVGA3dSurfaceFormat;
+
+
+struct svga_surface
+{
+ struct pipe_surface base;
+
+ struct svga_host_surface_cache_key key;
+ struct svga_winsys_surface *handle;
+
+ unsigned real_face;
+ unsigned real_level;
+ unsigned real_zslice;
+
+ boolean dirty;
+};
+
+
+extern void
+svga_propagate_surface(struct pipe_context *pipe, struct pipe_surface *surf);
+
+extern boolean
+svga_surface_needs_propagation(struct pipe_surface *surf);
+
+struct svga_winsys_surface *
+svga_texture_view_surface(struct pipe_context *pipe,
+ struct svga_texture *tex,
+ SVGA3dSurfaceFormat format,
+ unsigned start_mip,
+ unsigned num_mip,
+ int face_pick,
+ int zslice_pick,
+ struct svga_host_surface_cache_key *key); /* OUT */
+
+
+static INLINE struct svga_surface *
+svga_surface(struct pipe_surface *surface)
+{
+ assert(surface);
+ return (struct svga_surface *)surface;
+}
+
+void
+svga_screen_init_surface_functions(struct pipe_screen *screen);
+
+#endif
diff --git a/src/gallium/drivers/svga/svga_swtnl.h b/src/gallium/drivers/svga/svga_swtnl.h
index 4882f26b17..096ed410b5 100644
--- a/src/gallium/drivers/svga/svga_swtnl.h
+++ b/src/gallium/drivers/svga/svga_swtnl.h
@@ -40,7 +40,7 @@ void svga_destroy_swtnl( struct svga_context *svga );
enum pipe_error
svga_swtnl_draw_range_elements(struct svga_context *svga,
- struct pipe_buffer *indexBuffer,
+ struct pipe_resource *indexBuffer,
unsigned indexSize,
unsigned min_index,
unsigned max_index,
diff --git a/src/gallium/drivers/svga/svga_swtnl_backend.c b/src/gallium/drivers/svga/svga_swtnl_backend.c
index e9d7942fb5..29b1be1cc8 100644
--- a/src/gallium/drivers/svga/svga_swtnl_backend.c
+++ b/src/gallium/drivers/svga/svga_swtnl_backend.c
@@ -79,9 +79,9 @@ svga_vbuf_render_allocate_vertices( struct vbuf_render *render,
new_vbuf = TRUE;
if (new_vbuf)
- pipe_buffer_reference(&svga_render->vbuf, NULL);
+ pipe_resource_reference(&svga_render->vbuf, NULL);
if (new_ibuf)
- pipe_buffer_reference(&svga_render->ibuf, NULL);
+ pipe_resource_reference(&svga_render->ibuf, NULL);
if (!svga_render->vbuf) {
svga_render->vbuf_size = MAX2(size, svga_render->vbuf_alloc_size);
@@ -117,14 +117,14 @@ svga_vbuf_render_map_vertices( struct vbuf_render *render )
{
struct svga_vbuf_render *svga_render = svga_vbuf_render(render);
struct svga_context *svga = svga_render->svga;
- struct pipe_screen *screen = svga->pipe.screen;
- char *ptr = (char*)pipe_buffer_map(screen,
+ char *ptr = (char*)pipe_buffer_map(&svga->pipe,
svga_render->vbuf,
- PIPE_BUFFER_USAGE_CPU_WRITE |
- PIPE_BUFFER_USAGE_FLUSH_EXPLICIT |
- PIPE_BUFFER_USAGE_DISCARD |
- PIPE_BUFFER_USAGE_UNSYNCHRONIZED);
+ PIPE_TRANSFER_WRITE |
+ PIPE_TRANSFER_FLUSH_EXPLICIT |
+ PIPE_TRANSFER_DISCARD |
+ PIPE_TRANSFER_UNSYNCHRONIZED,
+ &svga_render->vbuf_transfer);
return ptr + svga_render->vbuf_offset;
}
@@ -135,14 +135,15 @@ svga_vbuf_render_unmap_vertices( struct vbuf_render *render,
{
struct svga_vbuf_render *svga_render = svga_vbuf_render(render);
struct svga_context *svga = svga_render->svga;
- struct pipe_screen *screen = svga->pipe.screen;
unsigned offset, length;
size_t used = svga_render->vertex_size * ((size_t)max_index + 1);
offset = svga_render->vbuf_offset + svga_render->vertex_size * min_index;
length = svga_render->vertex_size * (max_index + 1 - min_index);
- pipe_buffer_flush_mapped_range(screen, svga_render->vbuf, offset, length);
- pipe_buffer_unmap(screen, svga_render->vbuf);
+ pipe_buffer_flush_mapped_range(&svga->pipe,
+ svga_render->vbuf_transfer,
+ offset, length);
+ pipe_buffer_unmap(&svga->pipe, svga_render->vbuf, svga_render->vbuf_transfer);
svga_render->min_index = min_index;
svga_render->max_index = max_index;
svga_render->vbuf_used = MAX2(svga_render->vbuf_used, used);
@@ -255,7 +256,7 @@ svga_vbuf_render_draw( struct vbuf_render *render,
assert(( svga_render->vbuf_offset - svga_render->vdecl_offset) % svga_render->vertex_size == 0);
if (svga_render->ibuf_size < svga_render->ibuf_offset + size)
- pipe_buffer_reference(&svga_render->ibuf, NULL);
+ pipe_resource_reference(&svga_render->ibuf, NULL);
if (!svga_render->ibuf) {
svga_render->ibuf_size = MAX2(size, svga_render->ibuf_alloc_size);
@@ -266,8 +267,8 @@ svga_vbuf_render_draw( struct vbuf_render *render,
svga_render->ibuf_offset = 0;
}
- pipe_buffer_write_nooverlap(screen, svga_render->ibuf,
- svga_render->ibuf_offset, 2 * nr_indices, indices);
+ pipe_buffer_write_nooverlap(&svga->pipe, svga_render->ibuf,
+ svga_render->ibuf_offset, 2 * nr_indices, indices);
/* off to hardware */
@@ -315,8 +316,8 @@ svga_vbuf_render_destroy( struct vbuf_render *render )
{
struct svga_vbuf_render *svga_render = svga_vbuf_render(render);
- pipe_buffer_reference(&svga_render->vbuf, NULL);
- pipe_buffer_reference(&svga_render->ibuf, NULL);
+ pipe_resource_reference(&svga_render->vbuf, NULL);
+ pipe_resource_reference(&svga_render->ibuf, NULL);
FREE(svga_render);
}
diff --git a/src/gallium/drivers/svga/svga_swtnl_draw.c b/src/gallium/drivers/svga/svga_swtnl_draw.c
index da15be155c..ee12c9ac36 100644
--- a/src/gallium/drivers/svga/svga_swtnl_draw.c
+++ b/src/gallium/drivers/svga/svga_swtnl_draw.c
@@ -37,12 +37,15 @@
enum pipe_error
svga_swtnl_draw_range_elements(struct svga_context *svga,
- struct pipe_buffer *indexBuffer,
+ struct pipe_resource *indexBuffer,
unsigned indexSize,
unsigned min_index,
unsigned max_index,
unsigned prim, unsigned start, unsigned count)
{
+ struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS];
+ struct pipe_transfer *ib_transfer;
+ struct pipe_transfer *cb_transfer;
struct draw_context *draw = svga->swtnl.draw;
unsigned i;
const void *map;
@@ -64,17 +67,19 @@ svga_swtnl_draw_range_elements(struct svga_context *svga,
* Map vertex buffers
*/
for (i = 0; i < svga->curr.num_vertex_buffers; i++) {
- map = pipe_buffer_map(svga->pipe.screen,
+ map = pipe_buffer_map(&svga->pipe,
svga->curr.vb[i].buffer,
- PIPE_BUFFER_USAGE_CPU_READ);
+ PIPE_BUFFER_USAGE_CPU_READ,
+ &vb_transfer[i]);
draw_set_mapped_vertex_buffer(draw, i, map);
}
/* Map index buffer, if present */
if (indexBuffer) {
- map = pipe_buffer_map(svga->pipe.screen, indexBuffer,
- PIPE_BUFFER_USAGE_CPU_READ);
+ map = pipe_buffer_map(&svga->pipe, indexBuffer,
+ PIPE_BUFFER_USAGE_CPU_READ,
+ &ib_transfer);
draw_set_mapped_element_buffer_range(draw,
indexSize,
@@ -84,14 +89,15 @@ svga_swtnl_draw_range_elements(struct svga_context *svga,
}
if (svga->curr.cb[PIPE_SHADER_VERTEX]) {
- map = pipe_buffer_map(svga->pipe.screen,
+ map = pipe_buffer_map(&svga->pipe,
svga->curr.cb[PIPE_SHADER_VERTEX],
- PIPE_BUFFER_USAGE_CPU_READ);
+ PIPE_BUFFER_USAGE_CPU_READ,
+ &cb_transfer);
assert(map);
draw_set_mapped_constant_buffer(
draw, PIPE_SHADER_VERTEX, 0,
map,
- svga->curr.cb[PIPE_SHADER_VERTEX]->size);
+ svga->curr.cb[PIPE_SHADER_VERTEX]->width0);
}
draw_arrays(svga->swtnl.draw, prim, start, count);
@@ -105,18 +111,20 @@ svga_swtnl_draw_range_elements(struct svga_context *svga,
* unmap vertex/index buffers
*/
for (i = 0; i < svga->curr.num_vertex_buffers; i++) {
- pipe_buffer_unmap(svga->pipe.screen, svga->curr.vb[i].buffer);
+ pipe_buffer_unmap(&svga->pipe, svga->curr.vb[i].buffer,
+ vb_transfer[i]);
draw_set_mapped_vertex_buffer(draw, i, NULL);
}
if (indexBuffer) {
- pipe_buffer_unmap(svga->pipe.screen, indexBuffer);
+ pipe_buffer_unmap(&svga->pipe, indexBuffer, ib_transfer);
draw_set_mapped_element_buffer(draw, 0, NULL);
}
if (svga->curr.cb[PIPE_SHADER_VERTEX]) {
- pipe_buffer_unmap(svga->pipe.screen,
- svga->curr.cb[PIPE_SHADER_VERTEX]);
+ pipe_buffer_unmap(&svga->pipe,
+ svga->curr.cb[PIPE_SHADER_VERTEX],
+ cb_transfer);
}
return ret;
diff --git a/src/gallium/drivers/svga/svga_swtnl_private.h b/src/gallium/drivers/svga/svga_swtnl_private.h
index 9bbb42910f..8d08070843 100644
--- a/src/gallium/drivers/svga/svga_swtnl_private.h
+++ b/src/gallium/drivers/svga/svga_swtnl_private.h
@@ -45,8 +45,10 @@ struct svga_vbuf_render {
unsigned prim;
- struct pipe_buffer *vbuf;
- struct pipe_buffer *ibuf;
+ struct pipe_resource *vbuf;
+ struct pipe_resource *ibuf;
+ struct pipe_transfer *vbuf_transfer;
+ struct pipe_transfer *ibuf_transfer;
/* current size of buffer */
size_t vbuf_size;
diff --git a/src/gallium/drivers/svga/svga_winsys.h b/src/gallium/drivers/svga/svga_winsys.h
index 00002e124f..225c2ba55f 100644
--- a/src/gallium/drivers/svga/svga_winsys.h
+++ b/src/gallium/drivers/svga/svga_winsys.h
@@ -189,7 +189,7 @@ struct svga_winsys_screen
/**
* Creates a surface from a winsys handle.
- * Used to implement pipe_screen::texture_from_handle.
+ * Used to implement pipe_screen::resource_from_handle.
*/
struct svga_winsys_surface *
(*surface_from_handle)(struct svga_winsys_screen *sws,
@@ -198,7 +198,7 @@ struct svga_winsys_screen
/**
* Get a winsys_handle from a surface.
- * Used to implement pipe_screen::texture_get_handle.
+ * Used to implement pipe_screen::resource_get_handle.
*/
boolean
(*surface_get_handle)(struct svga_winsys_screen *sws,
@@ -294,12 +294,12 @@ svga_screen_create(struct svga_winsys_screen *sws);
struct svga_winsys_screen *
svga_winsys_screen(struct pipe_screen *screen);
-struct pipe_buffer *
+struct pipe_resource *
svga_screen_buffer_wrap_surface(struct pipe_screen *screen,
enum SVGA3dSurfaceFormat format,
struct svga_winsys_surface *srf);
struct svga_winsys_surface *
-svga_screen_buffer_get_winsys_surface(struct pipe_buffer *buffer);
+svga_screen_buffer_get_winsys_surface(struct pipe_resource *buffer);
#endif /* SVGA_WINSYS_H_ */