summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/softpipe/sp_texture.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/softpipe/sp_texture.c')
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c97
1 files changed, 76 insertions, 21 deletions
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index 70f0932431..1c64d58372 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -30,26 +30,21 @@
* Michel Dänzer <michel@tungstengraphics.com>
*/
-#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_inlines.h"
-#include "pipe/internal/p_winsys_screen.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include "sp_context.h"
#include "sp_state.h"
#include "sp_texture.h"
-#include "sp_tile_cache.h"
#include "sp_screen.h"
#include "sp_winsys.h"
-/* Simple, maximally packed layout.
- */
-
-
-/* Conventional allocation path for non-display textures:
+/**
+ * Conventional allocation path for non-display textures:
+ * Use a simple, maximally packed layout.
*/
static boolean
softpipe_texture_layout(struct pipe_screen *screen,
@@ -89,6 +84,10 @@ softpipe_texture_layout(struct pipe_screen *screen,
return spt->buffer != NULL;
}
+
+/**
+ * Texture layout for simple color buffers.
+ */
static boolean
softpipe_displaytarget_layout(struct pipe_screen *screen,
struct softpipe_texture * spt)
@@ -112,21 +111,22 @@ softpipe_displaytarget_layout(struct pipe_screen *screen,
}
-
-
-
static struct pipe_texture *
softpipe_texture_create(struct pipe_screen *screen,
- const struct pipe_texture *templat)
+ const struct pipe_texture *template)
{
struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture);
if (!spt)
return NULL;
- spt->base = *templat;
+ spt->base = *template;
pipe_reference_init(&spt->base.reference, 1);
spt->base.screen = screen;
+ spt->pot = (util_is_power_of_two(template->width[0]) &&
+ util_is_power_of_two(template->height[0]) &&
+ util_is_power_of_two(template->depth[0]));
+
if (spt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_PRIMARY)) {
if (!softpipe_displaytarget_layout(screen, spt))
@@ -222,6 +222,13 @@ softpipe_get_tex_surface(struct pipe_screen *screen,
if (ps->usage & PIPE_BUFFER_USAGE_GPU_READ)
ps->usage |= PIPE_BUFFER_USAGE_CPU_READ;
+ if (ps->usage & (PIPE_BUFFER_USAGE_CPU_WRITE |
+ PIPE_BUFFER_USAGE_GPU_WRITE)) {
+ /* Mark the surface as dirty. The tile cache will look for this. */
+ spt->timestamp++;
+ softpipe_screen(screen)->timestamp++;
+ }
+
ps->face = face;
ps->level = level;
ps->zslice = zslice;
@@ -342,14 +349,13 @@ softpipe_transfer_map( struct pipe_screen *screen,
/* May want to different things here depending on read/write nature
* of the map:
*/
- if (transfer->texture && transfer->usage != PIPE_TRANSFER_READ)
- {
+ if (transfer->texture && transfer->usage != PIPE_TRANSFER_READ) {
/* Do something to notify sharing contexts of a texture change.
* In softpipe, that would mean flushing the texture cache.
*/
softpipe_screen(screen)->timestamp++;
}
-
+
xfer_map = map + softpipe_transfer(transfer)->offset +
transfer->y / transfer->block.height * transfer->stride +
transfer->x / transfer->block.width * transfer->block.size;
@@ -360,7 +366,7 @@ softpipe_transfer_map( struct pipe_screen *screen,
static void
softpipe_transfer_unmap(struct pipe_screen *screen,
- struct pipe_transfer *transfer)
+ struct pipe_transfer *transfer)
{
struct softpipe_texture *spt;
@@ -371,14 +377,60 @@ softpipe_transfer_unmap(struct pipe_screen *screen,
if (transfer->usage != PIPE_TRANSFER_READ) {
/* Mark the texture as dirty to expire the tile caches. */
- spt->modified = TRUE;
+ spt->timestamp++;
}
}
+static struct pipe_video_surface*
+softpipe_video_surface_create(struct pipe_screen *screen,
+ enum pipe_video_chroma_format chroma_format,
+ unsigned width, unsigned height)
+{
+ struct softpipe_video_surface *sp_vsfc;
+ struct pipe_texture template;
-void
-softpipe_init_texture_funcs(struct softpipe_context *sp)
+ assert(screen);
+ assert(width && height);
+
+ sp_vsfc = CALLOC_STRUCT(softpipe_video_surface);
+ if (!sp_vsfc)
+ return NULL;
+
+ pipe_reference_init(&sp_vsfc->base.reference, 1);
+ sp_vsfc->base.screen = screen;
+ sp_vsfc->base.chroma_format = chroma_format;
+ /*sp_vsfc->base.surface_format = PIPE_VIDEO_SURFACE_FORMAT_VUYA;*/
+ sp_vsfc->base.width = width;
+ sp_vsfc->base.height = height;
+
+ memset(&template, 0, sizeof(struct pipe_texture));
+ template.target = PIPE_TEXTURE_2D;
+ template.format = PIPE_FORMAT_X8R8G8B8_UNORM;
+ template.last_level = 0;
+ /* vl_mpeg12_mc_renderer expects this when it's initialized with pot_buffers=true */
+ template.width[0] = util_next_power_of_two(width);
+ template.height[0] = util_next_power_of_two(height);
+ template.depth[0] = 1;
+ pf_get_block(template.format, &template.block);
+ template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_RENDER_TARGET;
+
+ sp_vsfc->tex = screen->texture_create(screen, &template);
+ if (!sp_vsfc->tex) {
+ FREE(sp_vsfc);
+ return NULL;
+ }
+
+ return &sp_vsfc->base;
+}
+
+
+static void
+softpipe_video_surface_destroy(struct pipe_video_surface *vsfc)
{
+ struct softpipe_video_surface *sp_vsfc = softpipe_video_surface(vsfc);
+
+ pipe_texture_reference(&sp_vsfc->tex, NULL);
+ FREE(sp_vsfc);
}
@@ -396,6 +448,9 @@ softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
screen->tex_transfer_destroy = softpipe_tex_transfer_destroy;
screen->transfer_map = softpipe_transfer_map;
screen->transfer_unmap = softpipe_transfer_unmap;
+
+ screen->video_surface_create = softpipe_video_surface_create;
+ screen->video_surface_destroy = softpipe_video_surface_destroy;
}
@@ -404,7 +459,7 @@ softpipe_get_texture_buffer( struct pipe_texture *texture,
struct pipe_buffer **buf,
unsigned *stride )
{
- struct softpipe_texture *tex = (struct softpipe_texture *)texture;
+ struct softpipe_texture *tex = (struct softpipe_texture *) texture;
if (!tex)
return FALSE;