summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/svga
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/svga')
-rw-r--r--src/gallium/drivers/svga/Makefile11
-rw-r--r--src/gallium/drivers/svga/SConscript8
-rw-r--r--src/gallium/drivers/svga/svga_cmd.c45
-rw-r--r--src/gallium/drivers/svga/svga_cmd.h1
-rw-r--r--src/gallium/drivers/svga/svga_context.c73
-rw-r--r--src/gallium/drivers/svga/svga_context.h4
-rw-r--r--src/gallium/drivers/svga/svga_draw.c38
-rw-r--r--src/gallium/drivers/svga/svga_draw.h6
-rw-r--r--src/gallium/drivers/svga/svga_draw_arrays.c40
-rw-r--r--src/gallium/drivers/svga/svga_draw_elements.c48
-rw-r--r--src/gallium/drivers/svga/svga_draw_private.h10
-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_constants.c4
-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.c4
-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.c55
-rw-r--r--src/gallium/drivers/svga/svga_resource.h43
-rw-r--r--src/gallium/drivers/svga/svga_resource_buffer.c355
-rw-r--r--src/gallium/drivers/svga/svga_resource_buffer.h (renamed from src/gallium/drivers/svga/svga_screen_buffer.h)36
-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)446
-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)97
-rw-r--r--src/gallium/drivers/svga/svga_sampler_view.c199
-rw-r--r--src/gallium/drivers/svga/svga_sampler_view.h97
-rw-r--r--src/gallium/drivers/svga/svga_screen.c18
-rw-r--r--src/gallium/drivers/svga/svga_screen_texture.c1097
-rw-r--r--src/gallium/drivers/svga/svga_state_constants.c13
-rw-r--r--src/gallium/drivers/svga/svga_state_tss.c10
-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.c383
-rw-r--r--src/gallium/drivers/svga/svga_surface.h97
-rw-r--r--src/gallium/drivers/svga/svga_swtnl.h2
-rw-r--r--src/gallium/drivers/svga/svga_swtnl_backend.c42
-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.h33
44 files changed, 2288 insertions, 1811 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/SConscript b/src/gallium/drivers/svga/SConscript
index 737b791ceb..12ce4732d1 100644
--- a/src/gallium/drivers/svga/SConscript
+++ b/src/gallium/drivers/svga/SConscript
@@ -38,10 +38,13 @@ sources = [
'svga_pipe_sampler.c',
'svga_pipe_vertex.c',
'svga_pipe_vs.c',
+ 'svga_resource.c',
+ 'svga_resource_buffer.c',
+ 'svga_resource_buffer_upload.c',
+ 'svga_resource_texture.c',
+ 'svga_sampler_view.c',
'svga_screen.c',
- 'svga_screen_buffer.c',
'svga_screen_cache.c',
- 'svga_screen_texture.c',
'svga_state.c',
'svga_state_constants.c',
'svga_state_framebuffer.c',
@@ -51,6 +54,7 @@ sources = [
'svga_state_vdecl.c',
'svga_state_fs.c',
'svga_state_vs.c',
+ 'svga_surface.c',
'svga_swtnl_backend.c',
'svga_swtnl_draw.c',
'svga_swtnl_state.c',
diff --git a/src/gallium/drivers/svga/svga_cmd.c b/src/gallium/drivers/svga/svga_cmd.c
index 04307d17fe..7b2dfe2549 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"
/*
@@ -279,7 +280,7 @@ SVGA3D_BeginDefineSurface(struct svga_winsys_context *swc,
if(!cmd)
return PIPE_ERROR_OUT_OF_MEMORY;
- swc->surface_relocation(swc, &cmd->sid, sid, PIPE_BUFFER_USAGE_GPU_WRITE);
+ swc->surface_relocation(swc, &cmd->sid, sid, SVGA_RELOC_WRITE);
cmd->surfaceFlags = flags;
cmd->format = format;
@@ -365,7 +366,7 @@ SVGA3D_DestroySurface(struct svga_winsys_context *swc,
if(!cmd)
return PIPE_ERROR_OUT_OF_MEMORY;
- swc->surface_relocation(swc, &cmd->sid, sid, PIPE_BUFFER_USAGE_GPU_READ);
+ swc->surface_relocation(swc, &cmd->sid, sid, SVGA_RELOC_READ);
swc->commit(swc);;
return PIPE_OK;
@@ -423,7 +424,7 @@ SVGA3D_SurfaceDMA(struct svga_winsys_context *swc,
const SVGA3dCopyBox *boxes, // IN
uint32 numBoxes) // IN
{
- struct svga_texture *texture = svga_texture(st->base.texture);
+ struct svga_texture *texture = svga_texture(st->base.resource);
SVGA3dCmdSurfaceDMA *cmd;
SVGA3dCmdSurfaceDMASuffix *pSuffix;
uint32 boxesSize = sizeof *boxes * numBoxes;
@@ -431,12 +432,12 @@ SVGA3D_SurfaceDMA(struct svga_winsys_context *swc,
unsigned surface_flags;
if(transfer == SVGA3D_WRITE_HOST_VRAM) {
- region_flags = PIPE_BUFFER_USAGE_GPU_READ;
- surface_flags = PIPE_BUFFER_USAGE_GPU_WRITE;
+ region_flags = SVGA_RELOC_READ;
+ surface_flags = SVGA_RELOC_WRITE;
}
else if(transfer == SVGA3D_READ_HOST_VRAM) {
- region_flags = PIPE_BUFFER_USAGE_GPU_WRITE;
- surface_flags = PIPE_BUFFER_USAGE_GPU_READ;
+ region_flags = SVGA_RELOC_WRITE;
+ surface_flags = SVGA_RELOC_READ;
}
else {
assert(0);
@@ -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;
@@ -489,12 +490,12 @@ SVGA3D_BufferDMA(struct svga_winsys_context *swc,
unsigned surface_flags;
if(transfer == SVGA3D_WRITE_HOST_VRAM) {
- region_flags = PIPE_BUFFER_USAGE_GPU_READ;
- surface_flags = PIPE_BUFFER_USAGE_GPU_WRITE;
+ region_flags = SVGA_RELOC_READ;
+ surface_flags = SVGA_RELOC_WRITE;
}
else if(transfer == SVGA3D_READ_HOST_VRAM) {
- region_flags = PIPE_BUFFER_USAGE_GPU_WRITE;
- surface_flags = PIPE_BUFFER_USAGE_GPU_READ;
+ region_flags = SVGA_RELOC_WRITE;
+ surface_flags = SVGA_RELOC_READ;
}
else {
assert(0);
@@ -584,7 +585,7 @@ SVGA3D_SetRenderTarget(struct svga_winsys_context *swc,
cmd->type = type;
- surface_to_surfaceid(swc, surface, &cmd->target, PIPE_BUFFER_USAGE_GPU_WRITE);
+ surface_to_surfaceid(swc, surface, &cmd->target, SVGA_RELOC_WRITE);
swc->commit(swc);
@@ -1000,8 +1001,8 @@ SVGA3D_BeginSurfaceCopy(struct svga_winsys_context *swc,
if(!cmd)
return PIPE_ERROR_OUT_OF_MEMORY;
- surface_to_surfaceid(swc, src, &cmd->src, PIPE_BUFFER_USAGE_GPU_READ);
- surface_to_surfaceid(swc, dest, &cmd->dest, PIPE_BUFFER_USAGE_GPU_WRITE);
+ surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ);
+ surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE);
*boxes = (SVGA3dCopyBox*) &cmd[1];
memset(*boxes, 0, boxesSize);
@@ -1043,8 +1044,8 @@ SVGA3D_SurfaceStretchBlt(struct svga_winsys_context *swc,
if(!cmd)
return PIPE_ERROR_OUT_OF_MEMORY;
- surface_to_surfaceid(swc, src, &cmd->src, PIPE_BUFFER_USAGE_GPU_READ);
- surface_to_surfaceid(swc, dest, &cmd->dest, PIPE_BUFFER_USAGE_GPU_WRITE);
+ surface_to_surfaceid(swc, src, &cmd->src, SVGA_RELOC_READ);
+ surface_to_surfaceid(swc, dest, &cmd->dest, SVGA_RELOC_WRITE);
cmd->boxSrc = *boxSrc;
cmd->boxDest = *boxDest;
cmd->mode = mode;
@@ -1373,7 +1374,7 @@ SVGA3D_EndQuery(struct svga_winsys_context *swc,
cmd->type = type;
swc->region_relocation(swc, &cmd->guestResult, buffer, 0,
- PIPE_BUFFER_USAGE_GPU_WRITE);
+ SVGA_RELOC_WRITE);
swc->commit(swc);
@@ -1420,7 +1421,7 @@ SVGA3D_WaitForQuery(struct svga_winsys_context *swc,
cmd->type = type;
swc->region_relocation(swc, &cmd->guestResult, buffer, 0,
- PIPE_BUFFER_USAGE_GPU_WRITE);
+ SVGA_RELOC_WRITE);
swc->commit(swc);
diff --git a/src/gallium/drivers/svga/svga_cmd.h b/src/gallium/drivers/svga/svga_cmd.h
index da9fc4355f..0e568d78e6 100644
--- a/src/gallium/drivers/svga/svga_cmd.h
+++ b/src/gallium/drivers/svga/svga_cmd.h
@@ -41,7 +41,6 @@
#include "pipe/p_defines.h"
-struct pipe_buffer;
struct pipe_surface;
struct svga_transfer;
struct svga_winsys_context;
diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c
index adb7840182..3228a6d3d7 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"
@@ -66,64 +67,11 @@ static void svga_destroy( struct pipe_context *pipe )
util_bitmask_destroy( svga->fs_bm );
for(shader = 0; shader < PIPE_SHADER_TYPES; ++shader)
- pipe_buffer_reference( &svga->curr.cb[shader], NULL );
+ pipe_resource_reference( &svga->curr.cb[shader], NULL );
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,
@@ -143,13 +91,11 @@ struct pipe_context *svga_context_create( struct pipe_screen *screen,
svga->pipe.destroy = svga_destroy;
svga->pipe.clear = svga_clear;
- svga->pipe.is_texture_referenced = svga_is_texture_referenced;
- svga->pipe.is_buffer_referenced = svga_is_buffer_referenced;
-
svga->swc = svgascreen->sws->context_create(svgascreen->sws);
if(!svga->swc)
goto no_swc;
+ svga_init_resource_functions(svga);
svga_init_blend_functions(svga);
svga_init_blit_functions(svga);
svga_init_depth_stencil_functions(svga);
@@ -164,7 +110,6 @@ struct pipe_context *svga_context_create( struct pipe_screen *screen,
svga_init_constbuffer_functions(svga);
svga_init_query_functions(svga);
- svga_init_texture_functions(&svga->pipe);
/* debug */
svga->debug.no_swtnl = debug_get_bool_option("SVGA_NO_SWTNL", FALSE);
@@ -183,17 +128,17 @@ 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 );
+ PIPE_BIND_INDEX_BUFFER );
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 );
+ PIPE_BIND_VERTEX_BUFFER );
if (svga->upload_vb == NULL)
goto no_upload_vb;
diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h
index 1f66437dfe..9a46de643f 100644
--- a/src/gallium/drivers/svga/svga_context.h
+++ b/src/gallium/drivers/svga/svga_context.h
@@ -190,7 +190,7 @@ struct svga_state
struct svga_vertex_shader *vs;
struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS];
- struct pipe_buffer *cb[PIPE_SHADER_TYPES];
+ struct pipe_resource *cb[PIPE_SHADER_TYPES];
struct pipe_framebuffer_state framebuffer;
float depthscale;
@@ -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 8b7ca2e112..81dd4778d0 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"
@@ -65,16 +66,16 @@ void svga_hwtnl_destroy( struct svga_hwtnl *hwtnl )
for (i = 0; i < PIPE_PRIM_MAX; i++) {
for (j = 0; j < IDX_CACHE_MAX; j++) {
- pipe_buffer_reference( &hwtnl->index_cache[i][j].buffer,
+ pipe_resource_reference( &hwtnl->index_cache[i][j].buffer,
NULL );
}
}
for (i = 0; i < hwtnl->cmd.vdecl_count; i++)
- pipe_buffer_reference(&hwtnl->cmd.vdecl_vb[i], NULL);
+ pipe_resource_reference(&hwtnl->cmd.vdecl_vb[i], NULL);
for (i = 0; i < hwtnl->cmd.prim_count; i++)
- pipe_buffer_reference(&hwtnl->cmd.prim_ib[i], NULL);
+ pipe_resource_reference(&hwtnl->cmd.prim_ib[i], NULL);
FREE(hwtnl);
@@ -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);
}
@@ -112,9 +113,9 @@ void svga_hwtnl_reset_vdecl( struct svga_hwtnl *hwtnl,
void svga_hwtnl_vdecl( struct svga_hwtnl *hwtnl,
- unsigned i,
- const SVGA3dVertexDecl *decl,
- struct pipe_buffer *vb)
+ unsigned i,
+ const SVGA3dVertexDecl *decl,
+ struct pipe_resource *vb)
{
assert(hwtnl->cmd.prim_count == 0);
@@ -122,8 +123,7 @@ void svga_hwtnl_vdecl( struct svga_hwtnl *hwtnl,
hwtnl->cmd.vdecl[i] = *decl;
- pipe_buffer_reference(&hwtnl->cmd.vdecl_vb[i],
- vb);
+ pipe_resource_reference(&hwtnl->cmd.vdecl_vb[i], vb);
}
@@ -198,7 +198,7 @@ svga_hwtnl_flush( struct svga_hwtnl *hwtnl )
swc->surface_relocation(swc,
&vdecl[i].array.surfaceId,
vb_handle[i],
- PIPE_BUFFER_USAGE_GPU_READ);
+ SVGA_RELOC_READ);
}
memcpy( prim,
@@ -209,8 +209,8 @@ svga_hwtnl_flush( struct svga_hwtnl *hwtnl )
swc->surface_relocation(swc,
&prim[i].indexArray.surfaceId,
ib_handle[i],
- PIPE_BUFFER_USAGE_GPU_READ);
- pipe_buffer_reference(&hwtnl->cmd.prim_ib[i], NULL);
+ SVGA_RELOC_READ);
+ pipe_resource_reference(&hwtnl->cmd.prim_ib[i], NULL);
}
SVGA_FIFOCommitAll( swc );
@@ -232,7 +232,7 @@ enum pipe_error svga_hwtnl_prim( struct svga_hwtnl *hwtnl,
const SVGA3dPrimitiveRange *range,
unsigned min_index,
unsigned max_index,
- struct pipe_buffer *ib )
+ struct pipe_resource *ib )
{
int ret = PIPE_OK;
@@ -240,8 +240,8 @@ enum pipe_error svga_hwtnl_prim( struct svga_hwtnl *hwtnl,
{
unsigned i;
for (i = 0; i < hwtnl->cmd.vdecl_count; i++) {
- struct pipe_buffer *vb = hwtnl->cmd.vdecl_vb[i];
- unsigned size = vb ? vb->size : 0;
+ struct pipe_resource *vb = hwtnl->cmd.vdecl_vb[i];
+ 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;
@@ -324,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;
@@ -375,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.h b/src/gallium/drivers/svga/svga_draw.h
index 14553b17b5..81c7f8377d 100644
--- a/src/gallium/drivers/svga/svga_draw.h
+++ b/src/gallium/drivers/svga/svga_draw.h
@@ -34,7 +34,7 @@ struct svga_hwtnl;
struct svga_winsys_context;
struct svga_screen;
struct svga_context;
-struct pipe_buffer;
+struct pipe_resource;
struct u_upload_mgr;
struct svga_hwtnl *svga_hwtnl_create( struct svga_context *svga,
@@ -53,7 +53,7 @@ void svga_hwtnl_set_unfilled( struct svga_hwtnl *hwtnl,
void svga_hwtnl_vdecl( struct svga_hwtnl *hwtnl,
unsigned i,
const SVGA3dVertexDecl *decl,
- struct pipe_buffer *vb);
+ struct pipe_resource *vb);
void svga_hwtnl_reset_vdecl( struct svga_hwtnl *hwtnl,
unsigned count );
@@ -67,7 +67,7 @@ svga_hwtnl_draw_arrays( struct svga_hwtnl *hwtnl,
enum pipe_error
svga_hwtnl_draw_range_elements( struct svga_hwtnl *hwtnl,
- struct pipe_buffer *indexBuffer,
+ struct pipe_resource *indexBuffer,
unsigned index_size,
unsigned min_index,
unsigned max_index,
diff --git a/src/gallium/drivers/svga/svga_draw_arrays.c b/src/gallium/drivers/svga/svga_draw_arrays.c
index 6192aa96b1..005996d05d 100644
--- a/src/gallium/drivers/svga/svga_draw_arrays.c
+++ b/src/gallium/drivers/svga/svga_draw_arrays.c
@@ -43,40 +43,40 @@ static enum pipe_error generate_indices( struct svga_hwtnl *hwtnl,
unsigned nr,
unsigned index_size,
u_generate_func generate,
- struct pipe_buffer **out_buf )
+ struct pipe_resource **out_buf )
{
- struct pipe_screen *screen = hwtnl->svga->pipe.screen;
+ struct pipe_context *pipe = &hwtnl->svga->pipe;
+ struct pipe_transfer *transfer;
unsigned size = index_size * nr;
- struct pipe_buffer *dst = NULL;
+ struct pipe_resource *dst = NULL;
void *dst_map = NULL;
- dst = screen->buffer_create( screen, 32,
- PIPE_BUFFER_USAGE_INDEX |
- PIPE_BUFFER_USAGE_CPU_WRITE |
- PIPE_BUFFER_USAGE_GPU_READ,
- size );
+ dst = pipe_buffer_create( pipe->screen,
+ PIPE_BIND_INDEX_BUFFER,
+ size );
if (dst == NULL)
goto fail;
- dst_map = pipe_buffer_map( screen, dst, PIPE_BUFFER_USAGE_CPU_WRITE );
+ dst_map = pipe_buffer_map( pipe, dst, PIPE_TRANSFER_WRITE,
+ &transfer);
if (dst_map == NULL)
goto fail;
generate( nr,
dst_map );
- pipe_buffer_unmap( screen, dst );
+ pipe_buffer_unmap( pipe, dst, transfer );
*out_buf = dst;
return PIPE_OK;
fail:
if (dst_map)
- screen->buffer_unmap( screen, dst );
+ pipe_buffer_unmap( pipe, dst, transfer );
if (dst)
- screen->buffer_destroy( dst );
-
+ pipe->screen->resource_destroy( pipe->screen, dst );
+
return PIPE_ERROR_OUT_OF_MEMORY;
}
@@ -96,7 +96,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;
@@ -107,7 +107,7 @@ static enum pipe_error retrieve_or_generate_indices( struct svga_hwtnl *hwtnl,
{
if (compare(hwtnl->index_cache[prim][i].gen_nr, gen_nr, gen_type))
{
- pipe_buffer_reference( out_buf,
+ pipe_resource_reference( out_buf,
hwtnl->index_cache[prim][i].buffer );
if (DBG)
@@ -117,7 +117,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)
@@ -149,7 +149,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)
@@ -171,7 +171,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)
@@ -259,7 +259,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.
@@ -288,7 +288,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 e8097d82f1..7ec4a058fc 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,32 +39,32 @@
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_screen *screen = hwtnl->svga->pipe.screen;
+ 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 = screen->buffer_create( screen, 32,
- PIPE_BUFFER_USAGE_INDEX |
- PIPE_BUFFER_USAGE_CPU_WRITE |
- PIPE_BUFFER_USAGE_GPU_READ,
- size );
+ dst = pipe_buffer_create( pipe->screen,
+ PIPE_BIND_INDEX_BUFFER,
+ size );
if (dst == NULL)
goto fail;
- src_map = pipe_buffer_map( screen, src, PIPE_BUFFER_USAGE_CPU_READ );
+ src_map = pipe_buffer_map( pipe, src, PIPE_TRANSFER_READ, &src_transfer );
if (src_map == NULL)
goto fail;
- dst_map = pipe_buffer_map( screen, dst, PIPE_BUFFER_USAGE_CPU_WRITE );
+ dst_map = pipe_buffer_map( pipe, dst, PIPE_TRANSFER_WRITE, &dst_transfer );
if (dst_map == NULL)
goto fail;
@@ -72,21 +72,21 @@ translate_indices( struct svga_hwtnl *hwtnl,
nr,
dst_map );
- pipe_buffer_unmap( screen, src );
- pipe_buffer_unmap( screen, dst );
+ pipe_buffer_unmap( pipe, src, src_transfer );
+ pipe_buffer_unmap( pipe, dst, dst_transfer );
*out_buf = dst;
return PIPE_OK;
fail:
if (src_map)
- screen->buffer_unmap( screen, src );
+ pipe_buffer_unmap( pipe, src, src_transfer );
if (dst_map)
- screen->buffer_unmap( screen, dst );
+ pipe_buffer_unmap( pipe, dst, dst_transfer );
if (dst)
- screen->buffer_destroy( dst );
+ pipe->screen->resource_destroy( pipe->screen, dst );
return PIPE_ERROR_OUT_OF_MEMORY;
}
@@ -97,7 +97,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,
@@ -106,7 +106,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;
@@ -120,7 +120,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,
@@ -151,7 +151,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;
}
@@ -161,7 +161,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,
@@ -209,7 +209,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
@@ -242,7 +242,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_draw_private.h b/src/gallium/drivers/svga/svga_draw_private.h
index 9aa40e1664..b6fcd6854c 100644
--- a/src/gallium/drivers/svga/svga_draw_private.h
+++ b/src/gallium/drivers/svga/svga_draw_private.h
@@ -90,7 +90,7 @@ struct index_cache {
/* If non-null, this buffer is filled by calling
* generate(nr, map(buffer))
*/
- struct pipe_buffer *buffer;
+ struct pipe_resource *buffer;
};
#define QSZ 32
@@ -99,11 +99,11 @@ struct draw_cmd {
struct svga_winsys_context *swc;
SVGA3dVertexDecl vdecl[SVGA3D_INPUTREG_MAX];
- struct pipe_buffer *vdecl_vb[SVGA3D_INPUTREG_MAX];
+ struct pipe_resource *vdecl_vb[SVGA3D_INPUTREG_MAX];
unsigned vdecl_count;
SVGA3dPrimitiveRange prim[QSZ];
- struct pipe_buffer *prim_ib[QSZ];
+ struct pipe_resource *prim_ib[QSZ];
unsigned prim_count;
unsigned min_index[QSZ];
unsigned max_index[QSZ];
@@ -141,11 +141,11 @@ svga_hwtnl_prim( struct svga_hwtnl *hwtnl,
const SVGA3dPrimitiveRange *range,
unsigned min_index,
unsigned max_index,
- struct pipe_buffer *ib );
+ struct pipe_resource *ib );
enum pipe_error
svga_hwtnl_simple_draw_range_elements( struct svga_hwtnl *hwtnl,
- struct pipe_buffer *indexBuffer,
+ struct pipe_resource *indexBuffer,
unsigned index_size,
unsigned min_index,
unsigned max_index,
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 bb1664fbed..cbff95c917 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_constants.c b/src/gallium/drivers/svga/svga_pipe_constants.c
index 73a0cd6b3a..2fa2142d07 100644
--- a/src/gallium/drivers/svga/svga_pipe_constants.c
+++ b/src/gallium/drivers/svga/svga_pipe_constants.c
@@ -45,14 +45,14 @@ struct svga_constbuf
static void svga_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
- struct pipe_buffer *buf)
+ struct pipe_resource *buf)
{
struct svga_context *svga = svga_context(pipe);
assert(shader < PIPE_SHADER_TYPES);
assert(index == 0);
- pipe_buffer_reference( &svga->curr.cb[shader],
+ pipe_resource_reference( &svga->curr.cb[shader],
buf );
if (shader == PIPE_SHADER_FRAGMENT)
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 2c43f9a24f..8c24fb302f 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..9c6f5858ba 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"
@@ -89,7 +89,7 @@ static struct pipe_query *svga_create_query( struct pipe_context *pipe,
sq->queryResult = (SVGA3dQueryResult *)sws->buffer_map(sws,
sq->hwbuf,
- PIPE_BUFFER_USAGE_CPU_WRITE);
+ PIPE_TRANSFER_WRITE);
if(!sq->queryResult)
goto no_query_result;
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
new file mode 100644
index 0000000000..15258c1966
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_resource.c
@@ -0,0 +1,55 @@
+#include "util/u_debug.h"
+
+#include "svga_resource.h"
+#include "svga_resource_buffer.h"
+#include "svga_resource_texture.h"
+#include "svga_context.h"
+#include "svga_screen.h"
+
+
+static struct pipe_resource *
+svga_resource_create(struct pipe_screen *screen,
+ const struct pipe_resource *template)
+{
+ if (template->target == PIPE_BUFFER)
+ return svga_buffer_create(screen, template);
+ else
+ return svga_resource_create(screen, template);
+
+}
+
+static struct pipe_resource *
+svga_resource_from_handle(struct pipe_screen * screen,
+ const struct pipe_resource *template,
+ struct winsys_handle *whandle)
+{
+ if (template->target == PIPE_BUFFER)
+ return NULL;
+ else
+ return svga_resource_from_handle(screen, template, whandle);
+}
+
+
+void
+svga_init_resource_functions(struct svga_context *svga)
+{
+ 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_screen_resource_functions(struct svga_screen *is)
+{
+ 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;
+}
+
+
+
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..cfa7d1015e
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_resource_buffer.c
@@ -0,0 +1,355 @@
+/**********************************************************
+ * 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_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER);
+}
+
+
+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.bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER))
+ 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->bind)) {
+ 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 bind)
+{
+ 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_USAGE_IMMUTABLE;
+ sbuf->b.b.bind = bind;
+ 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 8c862fa62d..55e7321184 100644
--- a/src/gallium/drivers/svga/svga_screen_buffer.h
+++ b/src/gallium/drivers/svga/svga_resource_buffer.h
@@ -29,14 +29,13 @@
#include "pipe/p_compiler.h"
#include "pipe/p_state.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
*/
@@ -49,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;
@@ -61,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.
@@ -138,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
@@ -190,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;
@@ -205,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);
+
/**
@@ -226,7 +232,7 @@ svga_screen_init_buffer_functions(struct pipe_screen *screen);
*/
struct svga_winsys_surface *
svga_buffer_handle(struct svga_context *svga,
- struct pipe_buffer *buf);
+ struct pipe_resource *buf);
void
svga_context_flush_buffers(struct svga_context *svga);
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..acef60f464 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.bind & PIPE_BIND_VERTEX_BUFFER)
+ sbuf->key.flags |= SVGA3D_SURFACE_HINT_VERTEXBUFFER;
+ if(sbuf->b.b.bind & PIPE_BIND_INDEX_BUFFER)
+ 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,15 +179,15 @@ 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;
- surface_flags = PIPE_BUFFER_USAGE_GPU_WRITE;
+ region_flags = SVGA_RELOC_READ;
+ surface_flags = SVGA_RELOC_WRITE;
}
else if(transfer == SVGA3D_READ_HOST_VRAM) {
- region_flags = PIPE_BUFFER_USAGE_GPU_WRITE;
- surface_flags = PIPE_BUFFER_USAGE_GPU_READ;
+ region_flags = SVGA_RELOC_WRITE;
+ surface_flags = SVGA_RELOC_READ;
}
else {
assert(0);
@@ -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.
@@ -637,7 +415,7 @@ svga_buffer_update_hw(struct svga_screen *ss, struct svga_buffer *sbuf)
return ret;
pipe_mutex_lock(ss->swc_mutex);
- map = ss->sws->buffer_map(ss->sws, sbuf->hwbuf, PIPE_BUFFER_USAGE_CPU_WRITE);
+ map = ss->sws->buffer_map(ss->sws, sbuf->hwbuf, PIPE_TRANSFER_WRITE);
assert(map);
if(!map) {
pipe_mutex_unlock(ss->swc_mutex);
@@ -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..fd008bda09
--- /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_S8_USCALED_Z24_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_S8_USCALED_Z24_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_TRANSFER_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_TRANSFER_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,
+ unsigned 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->bind & PIPE_BIND_SAMPLER_VIEW)
+ tex->key.flags |= SVGA3D_SURFACE_HINT_TEXTURE;
+
+ if (template->bind & PIPE_BIND_DISPLAY_TARGET) {
+ tex->key.cachable = 0;
+ }
+
+ if (template->bind & PIPE_BIND_SHARED) {
+ tex->key.cachable = 0;
+ }
+
+ if (template->bind & PIPE_BIND_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_BIND_RENDER_TARGET, therefore
+ * passing the SVGA3D_SURFACE_HINT_RENDERTARGET here defeats its purpose.
+ */
+#if 0
+ if((template->bind & PIPE_BIND_RENDER_TARGET) &&
+ !util_format_is_s3tc(template->format))
+ tex->key.flags |= SVGA3D_SURFACE_HINT_RENDERTARGET;
+#endif
+
+ if(template->bind & PIPE_BIND_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 96d035b12d..631937f2eb 100644
--- a/src/gallium/drivers/svga/svga_screen_texture.h
+++ b/src/gallium/drivers/svga/svga_resource_texture.h
@@ -30,6 +30,7 @@
#include "pipe/p_compiler.h"
#include "pipe/p_state.h"
#include "util/u_inlines.h"
+#include "util/u_transfer.h"
#include "svga_screen_cache.h"
struct pipe_context;
@@ -42,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];
@@ -106,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;
@@ -136,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)
@@ -156,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..5386db7d1b
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_sampler_view.c
@@ -0,0 +1,199 @@
+/**********************************************************
+ * 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 "svga_surface.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_s3tc(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 9a2e7c6f5b..9a75e456cf 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"
@@ -248,7 +249,7 @@ svga_is_format_supported( struct pipe_screen *screen,
assert(tex_usage);
/* Override host capabilities */
- if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) {
+ if (tex_usage & PIPE_BIND_RENDER_TARGET) {
switch(format) {
/* Often unsupported/problematic. This means we end up with the same
@@ -278,11 +279,11 @@ svga_is_format_supported( struct pipe_screen *screen,
SVGA3dSurfaceFormatCaps mask;
mask.value = 0;
- if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET)
+ if (tex_usage & PIPE_BIND_RENDER_TARGET)
mask.offscreenRenderTarget = 1;
- if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL)
+ if (tex_usage & PIPE_BIND_DEPTH_STENCIL)
mask.zStencil = 1;
- if (tex_usage & PIPE_TEXTURE_USAGE_SAMPLER)
+ if (tex_usage & PIPE_BIND_SAMPLER_VIEW)
mask.texture = 1;
if ((result.u & mask.value) == mask.value)
@@ -295,7 +296,7 @@ svga_is_format_supported( struct pipe_screen *screen,
* duplicated list of supported formats which is prone to getting
* out of sync:
*/
- if(tex_usage & (PIPE_TEXTURE_USAGE_RENDER_TARGET | PIPE_TEXTURE_USAGE_DEPTH_STENCIL))
+ if(tex_usage & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DEPTH_STENCIL))
return svga_translate_format_render(format) != SVGA3D_FORMAT_INVALID;
else
return svga_translate_format(format) != SVGA3D_FORMAT_INVALID;
@@ -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 811c746695..0000000000
--- a/src/gallium/drivers/svga/svga_screen_texture.c
+++ /dev/null
@@ -1,1097 +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"
-
-
-/* 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_S8_USCALED_Z24_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_S8_USCALED_Z24_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_s3tc(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_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_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_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_tex_transfer_destroy(struct pipe_context *pipe,
- struct pipe_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->get_tex_transfer = svga_get_tex_transfer;
- pipe->transfer_map = svga_transfer_map;
- pipe->transfer_unmap = svga_transfer_unmap;
- pipe->tex_transfer_destroy = svga_tex_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_s3tc(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..97c818cd37 100644
--- a/src/gallium/drivers/svga/svga_state_constants.c
+++ b/src/gallium/drivers/svga/svga_state_constants.c
@@ -82,7 +82,7 @@ static int emit_consts( struct svga_context *svga,
int offset,
int unit )
{
- struct pipe_screen *screen = svga->pipe.screen;
+ struct pipe_transfer *transfer = NULL;
unsigned count;
const float (*data)[4] = NULL;
unsigned i;
@@ -91,11 +91,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_TRANSFER_READ,
+ &transfer);
if (data == NULL) {
ret = PIPE_ERROR_OUT_OF_MEMORY;
goto done;
@@ -109,7 +110,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 +138,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..76a2dae143 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;
@@ -135,7 +135,7 @@ update_tss_binding(struct svga_context *svga,
svga->swc->surface_relocation(svga->swc,
&ts[i].value,
queue.bind[i].view->v->handle,
- PIPE_BUFFER_USAGE_GPU_READ);
+ SVGA_RELOC_READ);
}
else {
ts[i].value = SVGA3D_INVALID_ID;
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..a6215c68cb 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_TRANSFER_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..126b078751
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_surface.c
@@ -0,0 +1,383 @@
+/**********************************************************
+ * 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>
+
+
+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_BIND_RENDER_TARGET |
+ PIPE_BIND_DEPTH_STENCIL)) ? 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);
+
+ 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..b50ecdc994
--- /dev/null
+++ b/src/gallium/drivers/svga/svga_surface.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_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 */
+
+
+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);
+
+
+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..e649813608 100644
--- a/src/gallium/drivers/svga/svga_swtnl_backend.c
+++ b/src/gallium/drivers/svga/svga_swtnl_backend.c
@@ -79,21 +79,19 @@ 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);
svga_render->vbuf = pipe_buffer_create(screen,
- 16,
- PIPE_BUFFER_USAGE_VERTEX,
+ PIPE_BIND_VERTEX_BUFFER,
svga_render->vbuf_size);
if(!svga_render->vbuf) {
svga_context_flush(svga, NULL);
svga_render->vbuf = pipe_buffer_create(screen,
- 16,
- PIPE_BUFFER_USAGE_VERTEX,
+ PIPE_BIND_VERTEX_BUFFER,
svga_render->vbuf_size);
assert(svga_render->vbuf);
}
@@ -117,14 +115,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 +133,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,19 +254,18 @@ 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);
svga_render->ibuf = pipe_buffer_create(screen,
- 2,
- PIPE_BUFFER_USAGE_VERTEX,
+ PIPE_BIND_INDEX_BUFFER,
svga_render->ibuf_size);
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 +313,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..0037bbd5fe 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_TRANSFER_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_TRANSFER_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_TRANSFER_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 d4bb176f9a..3892addafd 100644
--- a/src/gallium/drivers/svga/svga_winsys.h
+++ b/src/gallium/drivers/svga/svga_winsys.h
@@ -49,13 +49,18 @@ struct svga_winsys_buffer;
struct pipe_screen;
struct pipe_context;
struct pipe_fence_handle;
-struct pipe_texture;
+struct pipe_resource;
struct svga_region;
struct winsys_handle;
-#define SVGA_BUFFER_USAGE_PINNED (PIPE_BUFFER_USAGE_CUSTOM << 0)
-#define SVGA_BUFFER_USAGE_WRAPPED (PIPE_BUFFER_USAGE_CUSTOM << 1)
+#define SVGA_BUFFER_USAGE_PINNED (1 << 0)
+#define SVGA_BUFFER_USAGE_WRAPPED (1 << 1)
+
+
+#define SVGA_RELOC_WRITE 0x1
+#define SVGA_RELOC_READ 0x2
+
/** Opaque surface handle */
@@ -189,7 +194,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 +203,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,
@@ -225,13 +230,7 @@ struct svga_winsys_screen
/**
* Buffer management. Buffer attributes are mostly fixed over its lifetime.
*
- * Remember that gallium gets to choose the interface it needs, and the
- * window systems must then implement that interface (rather than the
- * other way around...).
- *
- * usage is a bitmask of PIPE_BUFFER_USAGE_PIXEL/VERTEX/INDEX/CONSTANT. This
- * usage argument is only an optimization hint, not a guarantee, therefore
- * proper behavior must be observed in all circumstances.
+ * XXX usage seems to be a bitmask of SVGA_BUFFER_USAGE_* flags.
*
* alignment indicates the client's alignment requirements, eg for
* SSE instructions.
@@ -245,9 +244,9 @@ struct svga_winsys_screen
/**
* Map the entire data store of a buffer object into the client's address.
* flags is a bitmask of:
- * - PIPE_BUFFER_USAGE_CPU_READ/WRITE
- * - PIPE_BUFFER_USAGE_DONTBLOCK
- * - PIPE_BUFFER_USAGE_UNSYNCHRONIZED
+ * - PB_USAGE_CPU_READ/WRITE
+ * - PB_USAGE_DONTBLOCK
+ * - PB_USAGE_UNSYNCHRONIZED
*/
void *
(*buffer_map)( struct svga_winsys_screen *sws,
@@ -298,12 +297,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_ */