Commit 424b1210 authored by Thomas Hellstrom's avatar Thomas Hellstrom

Merge branch 'xa_branch'

Conflicts:
	configure.ac
Signed-off-by: 's avatarThomas Hellstrom <thellstrom@vmware.com>
parents a221807d f81ac184
......@@ -570,6 +570,11 @@ AC_ARG_ENABLE([xorg],
[enable support for X.Org DDX API @<:@default=no@:>@])],
[enable_xorg="$enableval"],
[enable_xorg=no])
AC_ARG_ENABLE([xa],
[AS_HELP_STRING([--enable-xa],
[enable build of the XA X Acceleration API @<:@default=no@:>@])],
[enable_xa="$enableval"],
[enable_xa=no])
AC_ARG_ENABLE([d3d1x],
[AS_HELP_STRING([--enable-d3d1x],
[enable support for Direct3D 10 & 11 low-level API @<:@default=no@:>@])],
......@@ -617,6 +622,7 @@ if test "x$enable_opengl" = xno -a \
"x$enable_gles2" = xno -a \
"x$enable_openvg" = xno -a \
"x$enable_xorg" = xno -a \
"x$enable_xa" = xno -a \
"x$enable_d3d1x" = xno; then
AC_MSG_ERROR([at least one API should be enabled])
fi
......@@ -1421,6 +1427,14 @@ if test "x$enable_xorg" = xyes; then
HAVE_ST_XORG=yes
fi
dnl
dnl XA configuration
dnl
if test "x$enable_xa" = xyes; then
GALLIUM_STATE_TRACKERS_DIRS="xa $GALLIUM_STATE_TRACKERS_DIRS"
HAVE_ST_XA=yes
fi
dnl
dnl OpenVG configuration
dnl
......@@ -1810,7 +1824,8 @@ dnl
dnl Gallium helper functions
dnl
gallium_check_st() {
if test "x$HAVE_ST_DRI" = xyes || test "x$HAVE_ST_XORG" = xyes; then
if test "x$HAVE_ST_DRI" = xyes || test "x$HAVE_ST_XORG" = xyes ||
test "x$HAVE_ST_XA" = xyes; then
if test "x$have_libdrm" != xyes; then
AC_MSG_ERROR([DRI or Xorg DDX requires libdrm >= $LIBDRM_REQUIRED])
fi
......@@ -1822,6 +1837,9 @@ gallium_check_st() {
if test "x$HAVE_ST_XORG" = xyes && test "x$3" != x; then
GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $3"
fi
if test "x$HAVE_ST_XA" = xyes && test "x$4" != x; then
GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $4"
fi
}
gallium_require_llvm() {
......@@ -1842,7 +1860,7 @@ if test "x$with_gallium_drivers" != x; then
for driver in $gallium_drivers; do
case "x$driver" in
xsvga)
gallium_check_st "svga/drm" "dri-vmwgfx" "xorg-vmwgfx"
gallium_check_st "svga/drm" "dri-vmwgfx" "xorg-vmwgfx" "xa-vmwgfx"
;;
xi915)
gallium_check_st "i915/drm" "dri-i915" "xorg-i915"
......
TOP = ../../../..
include $(TOP)/configs/current
##### MACROS #####
XA_MAJOR = 0
XA_MINOR = 4
XA_TINY = 0
XA_CFLAGS = -g -fPIC -Wall
XA_INCLUDES= -I$(TOP)/src/gallium/ \
-I$(TOP)/src/gallium/auxiliary \
-I$(TOP)/src/gallium/include \
-I$(TOP)/src/gallium/winsys \
-I$(TOP)/src/gallium/drivers
XA_LIB = xatracker
XA_LIB_NAME = lib$(XA_LIB).o
XA_LIB_DEPS =
COMMON_GALLIUM_SOURCES=
SOURCES = \
xa_tracker.c \
xa_context.c \
xa_renderer.c \
xa_tgsi.c \
xa_yuv.c \
xa_composite.c
OBJECTS = $(SOURCES:.c=.o)
##### RULES #####
.c.o:
$(CC) -c $(XA_CFLAGS) $(XA_INCLUDES) $<
##### TARGETS #####
default: $(XA_LIB_NAME)
# Make the library
$(XA_LIB_NAME): depend $(OBJECTS)
$(CC) -r -nostdlib -o $(XA_LIB_NAME) $(OBJECTS)
install: FORCE
clean:
-rm -f *.o *~
-rm -f *.lo
-rm -f *.la
-rm -f *.pc
-rm -rf .libs
-rm -f depend depend.bak
depend: $(SOURCES)
@ echo "running $(MKDEP)"
@ rm -f depend
@ touch depend
@ $(MKDEP) $(MKDEP_OPTIONS) -I$(TOP)/include $(XA_INCLUDES) $(SOURCES) \
> /dev/null
-include depend
FORCE:
/**********************************************************
* Copyright 2009-2011 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.
*
*********************************************************
* Authors:
* Zack Rusin <zackr-at-vmware-dot-com>
* Thomas Hellstrom <thellstrom-at-vmware-dot-com>
*/
The XA state tracker is intended as a versioned interface to gallium for
xorg driver writers. Initially it's mostly based on Zack Rusin's
composite / video work for the Xorg state tracker.
The motivation behind this state tracker is that the Xorg state tracker has
a number of interfaces to work with:
1) The Xorg sdk (versioned)
2) Gallium3D (not versioned)
3) KMS modesetting (versioned)
4) Driver-private (hopefully versioned)
Since Gallium3D is not versioned, the Xorg state tracker needs to be compiled
with Gallium, but it's really beneficial to be able to compile xorg drivers
standalone.
Therefore the xa state tracker is intended to supply the following
functionality:
1) Versioning.
2) Surface functionality (creation and copying for a basic dri2 implementation)
3) YUV blits for textured Xv.
4) Solid fills without ROP functionality.
5) Copies with format conversion and - reinterpretation but without ROP
6) Xrender- type compositing for general acceleration.
The first user will be the vmwgfx xorg driver. When there are more users,
we need to be able to load the appropriate gallium pipe driver, and we
should investigate sharing the loadig mechanism with the EGL state tracker.
IMPORTANT:
Version compatibilities:
While this library remains OUTSIDE any mesa release branch,
and the major version number is still 0. Any minor bump should be viewed as
an incompatibility event, and any user of this library should test for that
and refuse to use the library if minor versions differ.
As soon as the library enters a mesa release branch, if not earlier, major
will be bumped to 1, and normal incompatibility rules (major bump)
will be followed.
It is allowed to add function interfaces while only bumping minor. Any
user that uses these function interfaces must therefore use lazy symbol
lookups and test minor for compatibility before using such a function.
#
indent --linux-style -i4 -ip4 -bad -bap -psl $*
This diff is collapsed.
/**********************************************************
* Copyright 2009-2011 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.
*
*********************************************************
* Authors:
* Zack Rusin <zackr-at-vmware-dot-com>
* Thomas Hellstrom <thellstrom-at-vmware-dot-com>
*/
#ifndef _XA_COMPOSITE_H_
#define _XA_COMPOSITE_H_
#include "xa_tracker.h"
#include "xa_context.h"
/*
* Supported composite ops.
*/
enum xa_composite_op {
xa_op_clear,
xa_op_src,
xa_op_dst,
xa_op_over,
xa_op_over_reverse,
xa_op_in,
xa_op_in_reverse,
xa_op_out,
xa_op_out_reverse,
xa_op_atop,
xa_op_atop_reverse,
xa_op_xor,
xa_op_add
};
/*
* Supported filters.
*/
enum xa_composite_filter {
xa_filter_nearest,
xa_filter_linear
};
/*
* Supported clamp methods.
*/
enum xa_composite_wrap {
xa_wrap_clamp_to_border,
xa_wrap_repeat,
xa_wrap_mirror_repeat,
xa_wrap_clamp_to_edge
};
/*
* Src picture types.
*/
enum xa_composite_src_pict_type {
xa_src_pict_solid_fill
};
struct xa_pict_solid_fill {
enum xa_composite_src_pict_type type;
unsigned int class;
uint32_t color;
};
union xa_source_pict {
unsigned int type;
struct xa_pict_solid_fill solid_fill;
};
struct xa_picture {
enum xa_formats pict_format;
struct xa_surface *srf;
struct xa_surface *alpha_map;
float transform[9];
int has_transform;
int component_alpha;
enum xa_composite_wrap wrap;
enum xa_composite_filter filter;
union xa_source_pict *src_pict;
};
struct xa_composite {
struct xa_picture *src, *mask, *dst;
int op;
int no_solid;
};
struct xa_composite_allocation {
unsigned int xa_composite_size;
unsigned int xa_picture_size;
unsigned int xa_source_pict_size;
};
/*
* Get allocation sizes for minor bump compatibility.
*/
extern const struct xa_composite_allocation *
xa_composite_allocation(void);
/*
* This function checks most things except the format of the hardware
* surfaces, since they are generally not available at the time this
* function is called. Returns usual XA error codes.
*/
extern int
xa_composite_check_accelerated(const struct xa_composite *comp);
extern int
xa_composite_prepare(struct xa_context *ctx, const struct xa_composite *comp);
extern void
xa_composite_rect(struct xa_context *ctx,
int srcX, int srcY, int maskX, int maskY,
int dstX, int dstY, int width, int height);
extern void
xa_composite_done(struct xa_context *ctx);
#endif
/**********************************************************
* Copyright 2009-2011 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.
*
*********************************************************
* Authors:
* Zack Rusin <zackr-at-vmware-dot-com>
* Thomas Hellstrom <thellstrom-at-vmware-dot-com>
*/
#include "xa_context.h"
#include "xa_priv.h"
#include "cso_cache/cso_context.h"
#include "util/u_inlines.h"
#include "util/u_rect.h"
#include "util/u_surface.h"
#include "pipe/p_context.h"
struct xa_context *
xa_context_default(struct xa_tracker *xa)
{
return xa->default_ctx;
}
struct xa_context *
xa_context_create(struct xa_tracker *xa)
{
struct xa_context *ctx = calloc(1, sizeof(*ctx));
ctx->xa = xa;
ctx->pipe = xa->screen->context_create(xa->screen, NULL);
ctx->cso = cso_create_context(ctx->pipe);
ctx->shaders = xa_shaders_create(ctx);
renderer_init_state(ctx);
return ctx;
}
void
xa_context_destroy(struct xa_context *r)
{
struct pipe_resource **vsbuf = &r->vs_const_buffer;
struct pipe_resource **fsbuf = &r->fs_const_buffer;
if (*vsbuf)
pipe_resource_reference(vsbuf, NULL);
if (*fsbuf)
pipe_resource_reference(fsbuf, NULL);
if (r->shaders) {
xa_shaders_destroy(r->shaders);
r->shaders = NULL;
}
if (r->cso) {
cso_release_all(r->cso);
cso_destroy_context(r->cso);
r->cso = NULL;
}
}
int
xa_surface_dma(struct xa_context *ctx,
struct xa_surface *srf,
void *data,
unsigned int pitch,
int to_surface, struct xa_box *boxes, unsigned int num_boxes)
{
struct pipe_transfer *transfer;
void *map;
int w, h, i;
enum pipe_transfer_usage transfer_direction;
struct pipe_context *pipe = ctx->pipe;
transfer_direction = (to_surface ? PIPE_TRANSFER_WRITE :
PIPE_TRANSFER_READ);
for (i = 0; i < num_boxes; ++i, ++boxes) {
w = boxes->x2 - boxes->x1;
h = boxes->y2 - boxes->y1;
transfer = pipe_get_transfer(pipe, srf->tex, 0, 0,
transfer_direction, boxes->x1, boxes->y1,
w, h);
if (!transfer)
return -XA_ERR_NORES;
map = pipe_transfer_map(ctx->pipe, transfer);
if (!map)
goto out_no_map;
if (to_surface) {
util_copy_rect(map, srf->tex->format, transfer->stride,
0, 0, w, h, data, pitch, boxes->x1, boxes->y1);
} else {
util_copy_rect(data, srf->tex->format, pitch,
boxes->x1, boxes->y1, w, h, map, transfer->stride, 0,
0);
}
pipe->transfer_unmap(pipe, transfer);
pipe->transfer_destroy(pipe, transfer);
if (to_surface)
pipe->flush(pipe, &ctx->last_fence);
}
return XA_ERR_NONE;
out_no_map:
pipe->transfer_destroy(pipe, transfer);
return -XA_ERR_NORES;
}
void *
xa_surface_map(struct xa_context *ctx,
struct xa_surface *srf, unsigned int usage)
{
void *map;
unsigned int transfer_direction = 0;
struct pipe_context *pipe = ctx->pipe;
if (srf->transfer)
return NULL;
if (usage & XA_MAP_READ)
transfer_direction = PIPE_TRANSFER_READ;
if (usage & XA_MAP_WRITE)
transfer_direction = PIPE_TRANSFER_WRITE;
if (!transfer_direction)
return NULL;
srf->transfer = pipe_get_transfer(pipe, srf->tex, 0, 0,
transfer_direction, 0, 0,
srf->tex->width0, srf->tex->height0);
if (!srf->transfer)
return NULL;
map = pipe_transfer_map(pipe, srf->transfer);
if (!map)
pipe->transfer_destroy(pipe, srf->transfer);
srf->mapping_pipe = pipe;
return map;
}
void
xa_surface_unmap(struct xa_surface *srf)
{
if (srf->transfer) {
struct pipe_context *pipe = srf->mapping_pipe;
pipe->transfer_unmap(pipe, srf->transfer);
pipe->transfer_destroy(pipe, srf->transfer);
srf->transfer = NULL;
}
}
int
xa_surface_psurf_create(struct xa_context *ctx, struct xa_surface *dst)
{
struct pipe_screen *screen = ctx->pipe->screen;
struct pipe_surface srf_templ;
if (dst->srf)
return -XA_ERR_INVAL;
if (!screen->is_format_supported(screen, dst->tex->format,
PIPE_TEXTURE_2D, 0,
PIPE_BIND_RENDER_TARGET))
return -XA_ERR_INVAL;
u_surface_default_template(&srf_templ, dst->tex,
PIPE_BIND_RENDER_TARGET);
dst->srf = ctx->pipe->create_surface(ctx->pipe, dst->tex, &srf_templ);
if (!dst->srf)
return -XA_ERR_NORES;
return XA_ERR_NONE;
}
void
xa_surface_psurf_destroy(struct xa_surface *dst)
{
pipe_surface_reference(&dst->srf, NULL);
}
int
xa_copy_prepare(struct xa_context *ctx,
struct xa_surface *dst, struct xa_surface *src)
{
if (src == dst || dst->srf != NULL)
return -XA_ERR_INVAL;
if (src->tex->format != dst->tex->format) {
int ret = xa_surface_psurf_create(ctx, dst);
if (ret != XA_ERR_NONE)
return ret;
renderer_copy_prepare(ctx, dst->srf, src->tex);
ctx->simple_copy = 0;
} else
ctx->simple_copy = 1;
ctx->src = src;
ctx->dst = dst;
return 0;
}
void
xa_copy(struct xa_context *ctx,
int dx, int dy, int sx, int sy, int width, int height)
{
struct pipe_box src_box;
if (ctx->simple_copy) {
u_box_2d(sx, sy, width, height, &src_box);
ctx->pipe->resource_copy_region(ctx->pipe,
ctx->dst->tex, 0, dx, dy, 0,
ctx->src->tex,
0, &src_box);
} else
renderer_copy(ctx, dx, dy, sx, sy, width, height,
(float) width, (float) height);
}
void
xa_copy_done(struct xa_context *ctx)
{
if (!ctx->simple_copy) {
renderer_draw_flush(ctx);
ctx->pipe->flush(ctx->pipe, &ctx->last_fence);
xa_surface_psurf_destroy(ctx->dst);
} else
ctx->pipe->flush(ctx->pipe, &ctx->last_fence);
}
static void
bind_solid_blend_state(struct xa_context *ctx)
{
struct pipe_blend_state blend;
memset(&blend, 0, sizeof(struct pipe_blend_state));
blend.rt[0].blend_enable = 0;
blend.rt[0].colormask = PIPE_MASK_RGBA;
blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
cso_set_blend(ctx->cso, &blend);
}
int
xa_solid_prepare(struct xa_context *ctx, struct xa_surface *dst,
uint32_t fg)
{
unsigned vs_traits, fs_traits;
struct xa_shader shader;
int width, height;
int ret;
xa_pixel_to_float4(fg, ctx->solid_color);
ctx->has_solid_color = 1;
ret = xa_surface_psurf_create(ctx, dst);
if (ret != XA_ERR_NONE)
return ret;
ctx->dst = dst;
width = dst->srf->width;
height = dst->srf->height;
#if 0
debug_printf("Color Pixel=(%d, %d, %d, %d), RGBA=(%f, %f, %f, %f)\n",
(fg >> 24) & 0xff, (fg >> 16) & 0xff,
(fg >> 8) & 0xff, (fg >> 0) & 0xff,
exa->solid_color[0], exa->solid_color[1],
exa->solid_color[2], exa->solid_color[3]);
#endif
vs_traits = VS_SOLID_FILL;
fs_traits = FS_SOLID_FILL;
renderer_bind_destination(ctx, dst->srf, width, height);
bind_solid_blend_state(ctx);
cso_set_samplers(ctx->cso, 0, NULL);
cso_set_fragment_sampler_views(ctx->cso, 0, NULL);
shader = xa_shaders_get(ctx->shaders, vs_traits, fs_traits);
cso_set_vertex_shader_handle(ctx->cso, shader.vs);
cso_set_fragment_shader_handle(ctx->cso, shader.fs);
renderer_begin_solid(ctx);
xa_surface_psurf_destroy(dst);
return XA_ERR_NONE;
}
void
xa_solid(struct xa_context *ctx, int x, int y, int width, int height)
{
renderer_solid(ctx, x, y, x + width, y + height, ctx->solid_color);
}
void
xa_solid_done(struct xa_context *ctx)
{
renderer_draw_flush(ctx);
ctx->pipe->flush(ctx->pipe, &ctx->last_fence);
ctx->comp = NULL;
ctx->has_solid_color = FALSE;
ctx->num_bound_samplers = 0;
}
struct xa_fence *
xa_fence_get(struct xa_context *ctx)
{
struct xa_fence *fence = malloc(sizeof(*fence));
struct pipe_screen *screen = ctx->xa->screen;
if (!fence)
return NULL;
fence->xa = ctx->xa;
if (ctx->last_fence == NULL)
fence->pipe_fence = NULL;
else
screen->fence_reference(screen, &fence->pipe_fence, ctx->last_fence);
return fence;
}
int
xa_fence_wait(struct xa_fence *fence, uint64_t timeout)
{
if (!fence)
return XA_ERR_NONE;
if (fence->pipe_fence) {
struct pipe_screen *screen = fence->xa->screen;
boolean timed_out;
timed_out = !screen->fence_finish(screen, fence->pipe_fence, timeout);
if (timed_out)
return -XA_ERR_BUSY;
screen->fence_reference(screen, &fence->pipe_fence, NULL);
}
return XA_ERR_NONE;
}
void
xa_fence_destroy(struct xa_fence *fence)
{
if (!fence)
return;
if (fence->pipe_fence) {
struct pipe_screen *screen = fence->xa->screen;