diff options
Diffstat (limited to 'src/gallium/state_trackers/xorg')
-rw-r--r-- | src/gallium/state_trackers/xorg/Makefile | 18 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/SConscript | 27 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_composite.c | 1019 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_composite.h | 37 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_crtc.c | 331 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_dri2.c | 380 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_driver.c | 744 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_exa.c | 771 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_exa.h | 57 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_exa_tgsi.c | 489 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_exa_tgsi.h | 43 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_output.c | 296 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_tracker.h | 155 | ||||
-rw-r--r-- | src/gallium/state_trackers/xorg/xorg_winsys.h | 49 |
14 files changed, 4416 insertions, 0 deletions
diff --git a/src/gallium/state_trackers/xorg/Makefile b/src/gallium/state_trackers/xorg/Makefile new file mode 100644 index 0000000000..27a1990724 --- /dev/null +++ b/src/gallium/state_trackers/xorg/Makefile @@ -0,0 +1,18 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = xorgtracker + +LIBRARY_INCLUDES = \ + -DHAVE_CONFIG_H \ + $(shell pkg-config --cflags-only-I pixman-1 xorg-server libdrm xproto) \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/include \ + -I$(TOP)/src/mesa \ + -I$(TOP)/src/mesa/drivers/dri/common \ + -I$(TOP)/src/mesa/main + +C_SOURCES = $(wildcard ./*.c) + +include ../../Makefile.template diff --git a/src/gallium/state_trackers/xorg/SConscript b/src/gallium/state_trackers/xorg/SConscript new file mode 100644 index 0000000000..65f55ea378 --- /dev/null +++ b/src/gallium/state_trackers/xorg/SConscript @@ -0,0 +1,27 @@ +####################################################################### +# SConscript for xorg state_tracker + +Import('*') + +if 'xorg' in env['statetrackers']: + + env = env.Clone() + + env.Append(CPPPATH = [ + '#/src/mesa', + ]) + + env.ParseConfig('pkg-config --cflags --libs xorg-server') + + st_xorg = env.ConvenienceLibrary( + target = 'st_xorg', + source = [ 'xorg_composite.c', + 'xorg_crtc.c', + 'xorg_dri2.c', + 'xorg_driver.c', + 'xorg_exa.c', + 'xorg_exa_tgsi.c', + 'xorg_output.c', + ] + ) + Export('st_xorg') diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c new file mode 100644 index 0000000000..15c955450d --- /dev/null +++ b/src/gallium/state_trackers/xorg/xorg_composite.c @@ -0,0 +1,1019 @@ +#include "xorg_composite.h" + +#include "xorg_exa_tgsi.h" + +#include "cso_cache/cso_context.h" +#include "util/u_draw_quad.h" +#include "util/u_math.h" + +#include "pipe/p_inlines.h" + +struct xorg_composite_blend { + int op:8; + + unsigned rgb_src_factor:5; /**< PIPE_BLENDFACTOR_x */ + unsigned rgb_dst_factor:5; /**< PIPE_BLENDFACTOR_x */ + + unsigned alpha_src_factor:5; /**< PIPE_BLENDFACTOR_x */ + unsigned alpha_dst_factor:5; /**< PIPE_BLENDFACTOR_x */ +}; + +#define BLEND_OP_OVER 3 +static const struct xorg_composite_blend xorg_blends[] = { + { PictOpClear, + PIPE_BLENDFACTOR_CONST_COLOR, PIPE_BLENDFACTOR_CONST_ALPHA, + PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ZERO }, + + { PictOpSrc, + PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ONE, + PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ZERO }, + + { PictOpDst, + PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ZERO, + PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ONE }, + + { PictOpOver, + PIPE_BLENDFACTOR_SRC_ALPHA, PIPE_BLENDFACTOR_ONE, + PIPE_BLENDFACTOR_INV_SRC_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA }, + + { PictOpOverReverse, + PIPE_BLENDFACTOR_SRC_ALPHA, PIPE_BLENDFACTOR_ONE, + PIPE_BLENDFACTOR_INV_SRC_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA }, +}; + + +static INLINE void +pixel_to_float4(Pixel pixel, float *color) +{ + CARD32 r, g, b, a; + + a = (pixel >> 24) & 0xff; + r = (pixel >> 16) & 0xff; + g = (pixel >> 8) & 0xff; + b = (pixel >> 0) & 0xff; + color[0] = ((float)r) / 255.; + color[1] = ((float)g) / 255.; + color[2] = ((float)b) / 255.; + color[3] = ((float)a) / 255.; +} + +static INLINE void +render_pixel_to_float4(PictFormatPtr format, + CARD32 pixel, float *color) +{ + CARD32 r, g, b, a; + + debug_assert(format->type == PictTypeDirect); + + r = (pixel >> format->direct.red) & format->direct.redMask; + g = (pixel >> format->direct.green) & format->direct.greenMask; + b = (pixel >> format->direct.blue) & format->direct.blueMask; + a = (pixel >> format->direct.alpha) & format->direct.alphaMask; + color[0] = ((float)r) / ((float)format->direct.redMask); + color[1] = ((float)g) / ((float)format->direct.greenMask); + color[2] = ((float)b) / ((float)format->direct.blueMask); + color[3] = ((float)a) / ((float)format->direct.alphaMask); +} + +struct acceleration_info { + int op : 16; + int with_mask : 1; + int component_alpha : 1; +}; +static const struct acceleration_info accelerated_ops[] = { + {PictOpClear, 1, 0}, + {PictOpSrc, 1, 0}, + {PictOpDst, 1, 0}, + {PictOpOver, 1, 0}, + {PictOpOverReverse, 1, 0}, + {PictOpIn, 1, 0}, + {PictOpInReverse, 1, 0}, + {PictOpOut, 1, 0}, + {PictOpOutReverse, 1, 0}, + {PictOpAtop, 1, 0}, + {PictOpAtopReverse, 1, 0}, + {PictOpXor, 1, 0}, + {PictOpAdd, 1, 0}, + {PictOpSaturate, 1, 0}, +}; + +static struct xorg_composite_blend +blend_for_op(int op) +{ + const int num_blends = + sizeof(xorg_blends)/sizeof(struct xorg_composite_blend); + int i; + + for (i = 0; i < num_blends; ++i) { + if (xorg_blends[i].op == op) + return xorg_blends[i]; + } + return xorg_blends[BLEND_OP_OVER]; +} + +static INLINE int +render_repeat_to_gallium(int mode) +{ + switch(mode) { + case RepeatNone: + return PIPE_TEX_WRAP_CLAMP; + case RepeatNormal: + return PIPE_TEX_WRAP_REPEAT; + case RepeatReflect: + return PIPE_TEX_WRAP_MIRROR_REPEAT; + case RepeatPad: + return PIPE_TEX_WRAP_CLAMP_TO_EDGE; + default: + debug_printf("Unsupported repeat mode\n"); + } + return PIPE_TEX_WRAP_REPEAT; +} + + +static INLINE void +setup_vertex0(float vertex[2][4], float x, float y, + float color[4]) +{ + vertex[0][0] = x; + vertex[0][1] = y; + vertex[0][2] = 0.f; /*z*/ + vertex[0][3] = 1.f; /*w*/ + + vertex[1][0] = color[0]; /*r*/ + vertex[1][1] = color[1]; /*g*/ + vertex[1][2] = color[2]; /*b*/ + vertex[1][3] = color[3]; /*a*/ +} + +static struct pipe_buffer * +setup_vertex_data0(struct exa_context *ctx, + int srcX, int srcY, int maskX, int maskY, + int dstX, int dstY, int width, int height) +{ + float vertices[4][2][4]; + + /* 1st vertex */ + setup_vertex0(vertices[0], dstX, dstY, + ctx->solid_color); + /* 2nd vertex */ + setup_vertex0(vertices[1], dstX + width, dstY, + ctx->solid_color); + /* 3rd vertex */ + setup_vertex0(vertices[2], dstX + width, dstY + height, + ctx->solid_color); + /* 4th vertex */ + setup_vertex0(vertices[3], dstX, dstY + height, + ctx->solid_color); + + return pipe_user_buffer_create(ctx->pipe->screen, + vertices, + sizeof(vertices)); +} + +static INLINE void +setup_vertex1(float vertex[2][4], float x, float y, float s, float t) +{ + vertex[0][0] = x; + vertex[0][1] = y; + vertex[0][2] = 0.f; /*z*/ + vertex[0][3] = 1.f; /*w*/ + + vertex[1][0] = s; /*s*/ + vertex[1][1] = t; /*t*/ + vertex[1][2] = 0.f; /*r*/ + vertex[1][3] = 1.f; /*q*/ +} + +static struct pipe_buffer * +setup_vertex_data1(struct exa_context *ctx, + int srcX, int srcY, int maskX, int maskY, + int dstX, int dstY, int width, int height) +{ + float vertices[4][2][4]; + float s0, t0, s1, t1; + struct pipe_texture *src = ctx->bound_textures[0]; + + s0 = srcX / src->width[0]; + s1 = srcX + width / src->width[0]; + t0 = srcY / src->height[0]; + t1 = srcY + height / src->height[0]; + + /* 1st vertex */ + setup_vertex1(vertices[0], dstX, dstY, + s0, t0); + /* 2nd vertex */ + setup_vertex1(vertices[1], dstX + width, dstY, + s1, t0); + /* 3rd vertex */ + setup_vertex1(vertices[2], dstX + width, dstY + height, + s1, t1); + /* 4th vertex */ + setup_vertex1(vertices[3], dstX, dstY + height, + s0, t1); + + return pipe_user_buffer_create(ctx->pipe->screen, + vertices, + sizeof(vertices)); +} + +static struct pipe_buffer * +setup_vertex_data_tex(struct exa_context *ctx, + float x0, float y0, float x1, float y1, + float s0, float t0, float s1, float t1, + float z) +{ + float vertices[4][2][4]; + + /* 1st vertex */ + setup_vertex1(vertices[0], x0, y0, + s0, t0); + /* 2nd vertex */ + setup_vertex1(vertices[1], x1, y0, + s1, t0); + /* 3rd vertex */ + setup_vertex1(vertices[2], x1, y1, + s1, t1); + /* 4th vertex */ + setup_vertex1(vertices[3], x0, y1, + s0, t1); + + return pipe_user_buffer_create(ctx->pipe->screen, + vertices, + sizeof(vertices)); +} + + + +static INLINE void +setup_vertex2(float vertex[3][4], float x, float y, + float s0, float t0, float s1, float t1) +{ + vertex[0][0] = x; + vertex[0][1] = y; + vertex[0][2] = 0.f; /*z*/ + vertex[0][3] = 1.f; /*w*/ + + vertex[1][0] = s0; /*s*/ + vertex[1][1] = t0; /*t*/ + vertex[1][2] = 0.f; /*r*/ + vertex[1][3] = 1.f; /*q*/ + + vertex[2][0] = s1; /*s*/ + vertex[2][1] = t1; /*t*/ + vertex[2][2] = 0.f; /*r*/ + vertex[2][3] = 1.f; /*q*/ +} + +static struct pipe_buffer * +setup_vertex_data2(struct exa_context *ctx, + int srcX, int srcY, int maskX, int maskY, + int dstX, int dstY, int width, int height) +{ + float vertices[4][3][4]; + float st0[4], st1[4]; + struct pipe_texture *src = ctx->bound_textures[0]; + struct pipe_texture *mask = ctx->bound_textures[0]; + + st0[0] = srcX / src->width[0]; + st0[1] = srcY / src->height[0]; + st0[2] = srcX + width / src->width[0]; + st0[3] = srcY + height / src->height[0]; + + st1[0] = maskX / mask->width[0]; + st1[1] = maskY / mask->height[0]; + st1[2] = maskX + width / mask->width[0]; + st1[3] = maskY + height / mask->height[0]; + + /* 1st vertex */ + setup_vertex2(vertices[0], dstX, dstY, + st0[0], st0[1], st1[0], st1[1]); + /* 2nd vertex */ + setup_vertex2(vertices[1], dstX + width, dstY, + st0[2], st0[1], st1[2], st1[1]); + /* 3rd vertex */ + setup_vertex2(vertices[2], dstX + width, dstY + height, + st0[2], st0[3], st1[2], st1[3]); + /* 4th vertex */ + setup_vertex2(vertices[3], dstX, dstY + height, + st0[0], st0[3], st1[0], st1[3]); + + return pipe_user_buffer_create(ctx->pipe->screen, + vertices, + sizeof(vertices)); +} + +boolean xorg_composite_accelerated(int op, + PicturePtr pSrcPicture, + PicturePtr pMaskPicture, + PicturePtr pDstPicture) +{ + unsigned i; + unsigned accel_ops_count = + sizeof(accelerated_ops)/sizeof(struct acceleration_info); + + + /*FIXME: currently accel is disabled */ + return FALSE; + + if (pSrcPicture) { + /* component alpha not supported */ + if (pSrcPicture->componentAlpha) + return FALSE; + /* fills not supported */ + if (pSrcPicture->pSourcePict) + return FALSE; + } + + for (i = 0; i < accel_ops_count; ++i) { + if (op == accelerated_ops[i].op) { + if (pMaskPicture && !accelerated_ops[i].with_mask) + return FALSE; + return TRUE; + } + } + return FALSE; +} + +static void +bind_clip_state(struct exa_context *exa) +{ +} + +static void +bind_framebuffer_state(struct exa_context *exa, struct exa_pixmap_priv *pDst) +{ + unsigned i; + struct pipe_framebuffer_state state; + struct pipe_surface *surface = exa_gpu_surface(exa, pDst); + memset(&state, 0, sizeof(struct pipe_framebuffer_state)); + + state.width = pDst->tex->width[0]; + state.height = pDst->tex->height[0]; + + state.nr_cbufs = 1; + state.cbufs[0] = surface; + for (i = 1; i < PIPE_MAX_COLOR_BUFS; ++i) + state.cbufs[i] = 0; + + /* currently we don't use depth/stencil */ + state.zsbuf = 0; + + cso_set_framebuffer(exa->cso, &state); +} + +enum AxisOrientation { + Y0_BOTTOM, + Y0_TOP +}; + +static void +set_viewport(struct exa_context *exa, int width, int height, + enum AxisOrientation orientation) +{ + struct pipe_viewport_state viewport; + float y_scale = (orientation == Y0_BOTTOM) ? -2.f : 2.f; + + viewport.scale[0] = width / 2.f; + viewport.scale[1] = height / y_scale; + viewport.scale[2] = 1.0; + viewport.scale[3] = 1.0; + viewport.translate[0] = width / 2.f; + viewport.translate[1] = height / 2.f; + viewport.translate[2] = 0.0; + viewport.translate[3] = 0.0; + + cso_set_viewport(exa->cso, &viewport); +} + +static void +bind_viewport_state(struct exa_context *exa, struct exa_pixmap_priv *pDst) +{ + int width = pDst->tex->width[0]; + int height = pDst->tex->height[0]; + + debug_printf("Bind viewport (%d, %d)\n", width, height); + + set_viewport(exa, width, height, Y0_TOP); +} + +static void +bind_blend_state(struct exa_context *exa, int op, + PicturePtr pSrcPicture, PicturePtr pMaskPicture) +{ + boolean component_alpha = (pSrcPicture) ? + pSrcPicture->componentAlpha : FALSE; + struct xorg_composite_blend blend_opt; + struct pipe_blend_state blend; + + if (component_alpha) { + op = PictOpOver; + } + blend_opt = blend_for_op(op); + + memset(&blend, 0, sizeof(struct pipe_blend_state)); + blend.blend_enable = 1; + blend.colormask |= PIPE_MASK_R; + blend.colormask |= PIPE_MASK_G; + blend.colormask |= PIPE_MASK_B; + blend.colormask |= PIPE_MASK_A; + + blend.rgb_src_factor = blend_opt.rgb_src_factor; + blend.alpha_src_factor = blend_opt.alpha_src_factor; + blend.rgb_dst_factor = blend_opt.rgb_dst_factor; + blend.alpha_dst_factor = blend_opt.alpha_dst_factor; + + cso_set_blend(exa->cso, &blend); +} + +static void +bind_rasterizer_state(struct exa_context *exa) +{ + struct pipe_rasterizer_state raster; + memset(&raster, 0, sizeof(struct pipe_rasterizer_state)); + raster.gl_rasterization_rules = 1; + cso_set_rasterizer(exa->cso, &raster); +} + +static void +bind_shaders(struct exa_context *exa, int op, + PicturePtr pSrcPicture, PicturePtr pMaskPicture) +{ + unsigned vs_traits = 0, fs_traits = 0; + struct xorg_shader shader; + + exa->has_solid_color = FALSE; + + if (pSrcPicture) { + if (pSrcPicture->pSourcePict) { + if (pSrcPicture->pSourcePict->type == SourcePictTypeSolidFill) { + fs_traits |= FS_SOLID_FILL; + vs_traits |= VS_SOLID_FILL; + render_pixel_to_float4(pSrcPicture->pFormat, + pSrcPicture->pSourcePict->solidFill.color, + exa->solid_color); + exa->has_solid_color = TRUE; + } else { + debug_assert("!gradients not supported"); + } + } else { + fs_traits |= FS_COMPOSITE; + vs_traits |= VS_COMPOSITE; + } + } + + if (pMaskPicture) { + vs_traits |= VS_MASK; + fs_traits |= FS_MASK; + } + + shader = xorg_shaders_get(exa->shaders, vs_traits, fs_traits); + cso_set_vertex_shader_handle(exa->cso, shader.vs); + cso_set_fragment_shader_handle(exa->cso, shader.fs); +} + + +static void +bind_samplers(struct exa_context *exa, int op, + PicturePtr pSrcPicture, PicturePtr pMaskPicture, + PicturePtr pDstPicture, + struct exa_pixmap_priv *pSrc, + struct exa_pixmap_priv *pMask, + struct exa_pixmap_priv *pDst) +{ + struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS]; + struct pipe_sampler_state src_sampler, mask_sampler; + + exa->num_bound_samplers = 0; + + memset(&src_sampler, 0, sizeof(struct pipe_sampler_state)); + memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state)); + + if (pSrcPicture && pSrc) { + unsigned src_wrap = render_repeat_to_gallium( + pSrcPicture->repeatType); + src_sampler.wrap_s = src_wrap; + src_sampler.wrap_t = src_wrap; + src_sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST; + src_sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST; + src_sampler.normalized_coords = 1; + samplers[0] = &src_sampler; + exa->bound_textures[0] = pSrc->tex; + ++exa->num_bound_samplers; + } + + if (pMaskPicture && pMask) { + unsigned mask_wrap = render_repeat_to_gallium( + pMaskPicture->repeatType); + mask_sampler.wrap_s = mask_wrap; + mask_sampler.wrap_t = mask_wrap; + mask_sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST; + mask_sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST; + mask_sampler.normalized_coords = 1; + samplers[1] = &mask_sampler; + exa->bound_textures[1] = pMask->tex; + ++exa->num_bound_samplers; + } + + cso_set_samplers(exa->cso, exa->num_bound_samplers, + (const struct pipe_sampler_state **)samplers); + cso_set_sampler_textures(exa->cso, exa->num_bound_samplers, + exa->bound_textures); +} + +static void +setup_vs_constant_buffer(struct exa_context *exa, + int width, int height) +{ + const int param_bytes = 8 * sizeof(float); + float vs_consts[8] = { + 2.f/width, 2.f/height, 1, 1, + -1, -1, 0, 0 + }; + struct pipe_constant_buffer *cbuf = &exa->vs_const_buffer; + + pipe_buffer_reference(&cbuf->buffer, NULL); + cbuf->buffer = pipe_buffer_create(exa->pipe->screen, 16, + PIPE_BUFFER_USAGE_CONSTANT, + param_bytes); + + if (cbuf->buffer) { + pipe_buffer_write(exa->pipe->screen, cbuf->buffer, + 0, param_bytes, vs_consts); + } + exa->pipe->set_constant_buffer(exa->pipe, PIPE_SHADER_VERTEX, 0, cbuf); +} + + +static void +setup_fs_constant_buffer(struct exa_context *exa) +{ + const int param_bytes = 4 * sizeof(float); + float fs_consts[8] = { + 0, 0, 0, 1, + }; + struct pipe_constant_buffer *cbuf = &exa->fs_const_buffer; + + pipe_buffer_reference(&cbuf->buffer, NULL); + cbuf->buffer = pipe_buffer_create(exa->pipe->screen, 16, + PIPE_BUFFER_USAGE_CONSTANT, + param_bytes); + + if (cbuf->buffer) { + pipe_buffer_write(exa->pipe->screen, cbuf->buffer, + 0, param_bytes, fs_consts); + } + exa->pipe->set_constant_buffer(exa->pipe, PIPE_SHADER_FRAGMENT, 0, cbuf); +} + +static void +setup_constant_buffers(struct exa_context *exa, struct exa_pixmap_priv *pDst) +{ + int width = pDst->tex->width[0]; + int height = pDst->tex->height[0]; + + setup_vs_constant_buffer(exa, width, height); + setup_fs_constant_buffer(exa); +} + +boolean xorg_composite_bind_state(struct exa_context *exa, + int op, + PicturePtr pSrcPicture, + PicturePtr pMaskPicture, + PicturePtr pDstPicture, + struct exa_pixmap_priv *pSrc, + struct exa_pixmap_priv *pMask, + struct exa_pixmap_priv *pDst) +{ + bind_framebuffer_state(exa, pDst); + bind_viewport_state(exa, pDst); + bind_blend_state(exa, op, pSrcPicture, pMaskPicture); + bind_rasterizer_state(exa); + bind_shaders(exa, op, pSrcPicture, pMaskPicture); + bind_samplers(exa, op, pSrcPicture, pMaskPicture, + pDstPicture, pSrc, pMask, pDst); + bind_clip_state(exa); + setup_constant_buffers(exa, pDst); + + return FALSE; +} + +void xorg_composite(struct exa_context *exa, + struct exa_pixmap_priv *dst, + int srcX, int srcY, int maskX, int maskY, + int dstX, int dstY, int width, int height) +{ + struct pipe_context *pipe = exa->pipe; + struct pipe_buffer *buf = 0; + + if (exa->num_bound_samplers == 0 ) { /* solid fill */ + buf = setup_vertex_data0(exa, + srcX, srcY, maskX, maskY, + dstX, dstY, width, height); + } else if (exa->num_bound_samplers == 1 ) /* src */ + buf = setup_vertex_data1(exa, + srcX, srcY, maskX, maskY, + dstX, dstY, width, height); + else if (exa->num_bound_samplers == 2) /* src + mask */ + buf = setup_vertex_data2(exa, + srcX, srcY, maskX, maskY, + dstX, dstY, width, height); + else if (exa->num_bound_samplers == 3) { /* src + mask + dst */ + debug_assert(!"src/mask/dst not handled right now"); +#if 0 + buf = setup_vertex_data2(exa, + srcX, srcY, maskX, maskY, + dstX, dstY, width, height); +#endif + } + + if (buf) { + int num_attribs = 1; /*pos*/ + num_attribs += exa->num_bound_samplers; + if (exa->has_solid_color) + ++num_attribs; + + util_draw_vertex_buffer(pipe, buf, 0, + PIPE_PRIM_TRIANGLE_FAN, + 4, /* verts */ + num_attribs); /* attribs/vert */ + + pipe_buffer_reference(&buf, NULL); + } +} + +boolean xorg_solid_bind_state(struct exa_context *exa, + struct exa_pixmap_priv *pixmap, + Pixel fg) +{ + unsigned vs_traits, fs_traits; + struct xorg_shader shader; + + pixel_to_float4(fg, exa->solid_color); + exa->has_solid_color = TRUE; + + exa->solid_color[3] = 1.f; + + 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]); + +#if 0 + exa->solid_color[0] = 1.f; + exa->solid_color[1] = 0.f; + exa->solid_color[2] = 0.f; + exa->solid_color[3] = 1.f; +#endif + + vs_traits = VS_SOLID_FILL; + fs_traits = FS_SOLID_FILL; + + bind_framebuffer_state(exa, pixmap); + bind_viewport_state(exa, pixmap); + bind_rasterizer_state(exa); + bind_blend_state(exa, PictOpSrc, NULL, NULL); + setup_constant_buffers(exa, pixmap); + bind_clip_state(exa); + + shader = xorg_shaders_get(exa->shaders, vs_traits, fs_traits); + cso_set_vertex_shader_handle(exa->cso, shader.vs); + cso_set_fragment_shader_handle(exa->cso, shader.fs); + + return FALSE; +} + +void xorg_solid(struct exa_context *exa, + struct exa_pixmap_priv *pixmap, + int x0, int y0, int x1, int y1) +{ + struct pipe_context *pipe = exa->pipe; + struct pipe_buffer *buf = 0; + float vertices[4][2][4]; + + x0 = 10; y0 = 10; + x1 = 300; y1 = 300; + + /* 1st vertex */ + setup_vertex0(vertices[0], x0, y0, + exa->solid_color); + /* 2nd vertex */ + setup_vertex0(vertices[1], x1, y0, + exa->solid_color); + /* 3rd vertex */ + setup_vertex0(vertices[2], x1, y1, + exa->solid_color); + /* 4th vertex */ + setup_vertex0(vertices[3], x0, y1, + exa->solid_color); + + buf = pipe_user_buffer_create(exa->pipe->screen, + vertices, + sizeof(vertices)); + + + if (buf) { + debug_printf("Drawing buf is %p\n", buf); + util_draw_vertex_buffer(pipe, buf, 0, + PIPE_PRIM_TRIANGLE_FAN, + 4, /* verts */ + 2); /* attribs/vert */ + + pipe_buffer_reference(&buf, NULL); + } +} + + +static INLINE void shift_rectx(float coords[4], + const float *bounds, + const float shift) +{ + coords[0] += shift; + coords[2] -= shift; + if (bounds) { + coords[2] = MIN2(coords[2], bounds[2]); + /* bound x/y + width/height */ + if ((coords[0] + coords[2]) > (bounds[0] + bounds[2])) { + coords[2] = (bounds[0] + bounds[2]) - coords[0]; + } + } +} + +static INLINE void shift_recty(float coords[4], + const float *bounds, + const float shift) +{ + coords[1] += shift; + coords[3] -= shift; + if (bounds) { + coords[3] = MIN2(coords[3], bounds[3]); + if ((coords[1] + coords[3]) > (bounds[1] + bounds[3])) { + coords[3] = (bounds[1] + bounds[3]) - coords[1]; + } + } +} + +static INLINE void bound_rect(float coords[4], + const float bounds[4], + float shift[4]) +{ + /* if outside the bounds */ + if (coords[0] > (bounds[0] + bounds[2]) || + coords[1] > (bounds[1] + bounds[3]) || + (coords[0] + coords[2]) < bounds[0] || + (coords[1] + coords[3]) < bounds[1]) { + coords[0] = 0.f; + coords[1] = 0.f; + coords[2] = 0.f; + coords[3] = 0.f; + shift[0] = 0.f; + shift[1] = 0.f; + return; + } + + /* bound x */ + if (coords[0] < bounds[0]) { + shift[0] = bounds[0] - coords[0]; + coords[2] -= shift[0]; + coords[0] = bounds[0]; + } else + shift[0] = 0.f; + + /* bound y */ + if (coords[1] < bounds[1]) { + shift[1] = bounds[1] - coords[1]; + coords[3] -= shift[1]; + coords[1] = bounds[1]; + } else + shift[1] = 0.f; + + shift[2] = bounds[2] - coords[2]; + shift[3] = bounds[3] - coords[3]; + /* bound width/height */ + coords[2] = MIN2(coords[2], bounds[2]); + coords[3] = MIN2(coords[3], bounds[3]); + + /* bound x/y + width/height */ + if ((coords[0] + coords[2]) > (bounds[0] + bounds[2])) { + coords[2] = (bounds[0] + bounds[2]) - coords[0]; + } + if ((coords[1] + coords[3]) > (bounds[1] + bounds[3])) { + coords[3] = (bounds[1] + bounds[3]) - coords[1]; + } + + /* if outside the bounds */ + if ((coords[0] + coords[2]) < bounds[0] || + (coords[1] + coords[3]) < bounds[1]) { + coords[0] = 0.f; + coords[1] = 0.f; + coords[2] = 0.f; + coords[3] = 0.f; + return; + } +} + +static INLINE void sync_size(float *src_loc, float *dst_loc) +{ + src_loc[2] = MIN2(src_loc[2], dst_loc[2]); + src_loc[3] = MIN2(src_loc[3], dst_loc[3]); + dst_loc[2] = src_loc[2]; + dst_loc[3] = src_loc[3]; +} + + +static void renderer_copy_texture(struct exa_context *exa, + struct pipe_texture *src, + float sx1, float sy1, + float sx2, float sy2, + struct pipe_texture *dst, + float dx1, float dy1, + float dx2, float dy2) +{ + struct pipe_context *pipe = exa->pipe; + struct pipe_screen *screen = pipe->screen; + struct pipe_buffer *buf; + struct pipe_surface *dst_surf = screen->get_tex_surface( + screen, dst, 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_WRITE); + struct pipe_framebuffer_state fb; + float s0, t0, s1, t1; + struct xorg_shader shader; + + assert(src->width[0] != 0); + assert(src->height[0] != 0); + assert(dst->width[0] != 0); + assert(dst->height[0] != 0); + +#if 0 + debug_printf("copy texture [%f, %f, %f, %f], [%f, %f, %f, %f]\n", + sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2); +#endif + +#if 1 + s0 = sx1 / src->width[0]; + s1 = sx2 / src->width[0]; + t0 = sy1 / src->height[0]; + t1 = sy2 / src->height[0]; +#else + s0 = 0; + s1 = 1; + t0 = 0; + t1 = 1; +#endif + + assert(screen->is_format_supported(screen, dst_surf->format, PIPE_TEXTURE_2D, + PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)); + + /* save state (restored below) */ + cso_save_blend(exa->cso); + cso_save_samplers(exa->cso); + cso_save_sampler_textures(exa->cso); + cso_save_framebuffer(exa->cso); + cso_save_fragment_shader(exa->cso); + cso_save_vertex_shader(exa->cso); + + cso_save_viewport(exa->cso); + + + /* set misc state we care about */ + { + struct pipe_blend_state blend; + memset(&blend, 0, sizeof(blend)); + blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.colormask = PIPE_MASK_RGBA; + cso_set_blend(exa->cso, &blend); + } + + /* sampler */ + { + struct pipe_sampler_state sampler; + memset(&sampler, 0, sizeof(sampler)); + sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; + sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; + sampler.normalized_coords = 1; + cso_single_sampler(exa->cso, 0, &sampler); + cso_single_sampler_done(exa->cso); + } + + set_viewport(exa, dst_surf->width, dst_surf->height, Y0_TOP); + + /* texture */ + cso_set_sampler_textures(exa->cso, 1, &src); + + /* shaders */ + shader = xorg_shaders_get(exa->shaders, + VS_COMPOSITE, + FS_COMPOSITE); + cso_set_vertex_shader_handle(exa->cso, shader.vs); + cso_set_fragment_shader_handle(exa->cso, shader.fs); + + /* drawing dest */ + memset(&fb, 0, sizeof(fb)); + fb.width = dst_surf->width; + fb.height = dst_surf->height; + fb.nr_cbufs = 1; + fb.cbufs[0] = dst_surf; + { + int i; + for (i = 1; i < PIPE_MAX_COLOR_BUFS; ++i) + fb.cbufs[i] = 0; + } + cso_set_framebuffer(exa->cso, &fb); + + /* draw quad */ + buf = setup_vertex_data_tex(exa, + dx1, dy1, + dx2, dy2, + s0, t0, s1, t1, + 0.0f); + + if (buf) { + util_draw_vertex_buffer(exa->pipe, buf, 0, + PIPE_PRIM_TRIANGLE_FAN, + 4, /* verts */ + 2); /* attribs/vert */ + + pipe_buffer_reference(&buf, NULL); + } + + /* restore state we changed */ + cso_restore_blend(exa->cso); + cso_restore_samplers(exa->cso); + cso_restore_sampler_textures(exa->cso); + cso_restore_framebuffer(exa->cso); + cso_restore_vertex_shader(exa->cso); + cso_restore_fragment_shader(exa->cso); + cso_restore_viewport(exa->cso); + + pipe_surface_reference(&dst_surf, NULL); +} + +void xorg_copy_pixmap(struct exa_context *ctx, + struct exa_pixmap_priv *dst_priv, int dx, int dy, + struct exa_pixmap_priv *src_priv, int sx, int sy, + int width, int height) +{ + float dst_loc[4], src_loc[4]; + float dst_bounds[4], src_bounds[4]; + float src_shift[4], dst_shift[4], shift[4]; + struct pipe_texture *dst = dst_priv->tex; + struct pipe_texture *src = src_priv->tex; + + dst_loc[0] = dx; + dst_loc[1] = dy; + dst_loc[2] = width; + dst_loc[3] = height; + dst_bounds[0] = 0.f; + dst_bounds[1] = 0.f; + dst_bounds[2] = dst->width[0]; + dst_bounds[3] = dst->height[0]; + + src_loc[0] = sx; + src_loc[1] = sy; + src_loc[2] = width; + src_loc[3] = height; + src_bounds[0] = 0.f; + src_bounds[1] = 0.f; + src_bounds[2] = src->width[0]; + src_bounds[3] = src->height[0]; + + bound_rect(src_loc, src_bounds, src_shift); + bound_rect(dst_loc, dst_bounds, dst_shift); + shift[0] = src_shift[0] - dst_shift[0]; + shift[1] = src_shift[1] - dst_shift[1]; + + if (shift[0] < 0) + shift_rectx(src_loc, src_bounds, -shift[0]); + else + shift_rectx(dst_loc, dst_bounds, shift[0]); + + if (shift[1] < 0) + shift_recty(src_loc, src_bounds, -shift[1]); + else + shift_recty(dst_loc, dst_bounds, shift[1]); + + sync_size(src_loc, dst_loc); + + if (src_loc[2] >= 0 && src_loc[3] >= 0 && + dst_loc[2] >= 0 && dst_loc[3] >= 0) { + renderer_copy_texture(ctx, + src, + src_loc[0], + src_loc[1] + src_loc[3], + src_loc[0] + src_loc[2], + src_loc[1], + dst, + dst_loc[0], + dst_loc[1] + dst_loc[3], + dst_loc[0] + dst_loc[2], + dst_loc[1]); + } +} + diff --git a/src/gallium/state_trackers/xorg/xorg_composite.h b/src/gallium/state_trackers/xorg/xorg_composite.h new file mode 100644 index 0000000000..e73f1c704a --- /dev/null +++ b/src/gallium/state_trackers/xorg/xorg_composite.h @@ -0,0 +1,37 @@ +#ifndef XORG_COMPOSITE_H +#define XORG_COMPOSITE_H + +#include "xorg_exa.h" + +boolean xorg_composite_accelerated(int op, + PicturePtr pSrcPicture, + PicturePtr pMaskPicture, + PicturePtr pDstPicture); + +boolean xorg_composite_bind_state(struct exa_context *exa, + int op, + PicturePtr pSrcPicture, + PicturePtr pMaskPicture, + PicturePtr pDstPicture, + struct exa_pixmap_priv *pSrc, + struct exa_pixmap_priv *pMask, + struct exa_pixmap_priv *pDst); + +void xorg_composite(struct exa_context *exa, + struct exa_pixmap_priv *dst, + int srcX, int srcY, int maskX, int maskY, + int dstX, int dstY, int width, int height); + +boolean xorg_solid_bind_state(struct exa_context *exa, + struct exa_pixmap_priv *pixmap, + Pixel fg); +void xorg_solid(struct exa_context *exa, + struct exa_pixmap_priv *pixmap, + int x0, int y0, int x1, int y1); + +void xorg_copy_pixmap(struct exa_context *ctx, + struct exa_pixmap_priv *dst, int dx, int dy, + struct exa_pixmap_priv *src, int sx, int sy, + int width, int height); + +#endif diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c new file mode 100644 index 0000000000..fe08bde9ef --- /dev/null +++ b/src/gallium/state_trackers/xorg/xorg_crtc.c @@ -0,0 +1,331 @@ +/* + * 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. + * + * + * Author: Alan Hourihane <alanh@tungstengraphics.com> + * Author: Jakob Bornecrantz <wallbraker@gmail.com> + * + */ + +#include <unistd.h> +#include <string.h> +#include <assert.h> +#include <stdlib.h> +#include <math.h> +#include <stdint.h> + +#include "xorg-server.h" +#include <xf86.h> +#include <xf86i2c.h> +#include <xf86Crtc.h> +#include "xorg_tracker.h" +#include "xf86Modes.h" + +#define DPMS_SERVER +#include <X11/extensions/dpms.h> + +#include "pipe/p_inlines.h" +#include "util/u_rect.h" + +struct crtc_private +{ + drmModeCrtcPtr drm_crtc; + + /* hwcursor */ + struct pipe_texture *cursor_tex; + unsigned cursor_handle; +}; + +static void +crtc_dpms(xf86CrtcPtr crtc, int mode) +{ + //ScrnInfoPtr pScrn = crtc->scrn; + + switch (mode) { + case DPMSModeOn: + case DPMSModeStandby: + case DPMSModeSuspend: + break; + case DPMSModeOff: + break; + } +} + +static Bool +crtc_lock(xf86CrtcPtr crtc) +{ + return FALSE; +} + +static void +crtc_unlock(xf86CrtcPtr crtc) +{ +} + +static void +crtc_prepare(xf86CrtcPtr crtc) +{ +} + +static void +crtc_commit(xf86CrtcPtr crtc) +{ +} + +static Bool +crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + return TRUE; +} + +static void +crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, + DisplayModePtr adjusted_mode, int x, int y) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); + modesettingPtr ms = modesettingPTR(crtc->scrn); + xf86OutputPtr output = config->output[config->compat_output]; + drmModeConnectorPtr drm_connector = output->driver_private; + struct crtc_private *crtcp = crtc->driver_private; + drmModeCrtcPtr drm_crtc = crtcp->drm_crtc; + drmModeModeInfo drm_mode; + + drm_mode.clock = mode->Clock; + drm_mode.hdisplay = mode->HDisplay; + drm_mode.hsync_start = mode->HSyncStart; + drm_mode.hsync_end = mode->HSyncEnd; + drm_mode.htotal = mode->HTotal; + drm_mode.vdisplay = mode->VDisplay; + drm_mode.vsync_start = mode->VSyncStart; + drm_mode.vsync_end = mode->VSyncEnd; + drm_mode.vtotal = mode->VTotal; + drm_mode.flags = mode->Flags; + drm_mode.hskew = mode->HSkew; + drm_mode.vscan = mode->VScan; + drm_mode.vrefresh = mode->VRefresh; + if (!mode->name) + xf86SetModeDefaultName(mode); + strncpy(drm_mode.name, mode->name, DRM_DISPLAY_MODE_LEN); + + drmModeSetCrtc(ms->fd, drm_crtc->crtc_id, ms->fb_id, x, y, + &drm_connector->connector_id, 1, &drm_mode); +} + +#if 0 +static void +crtc_load_lut(xf86CrtcPtr crtc) +{ + //ScrnInfoPtr pScrn = crtc->scrn; +} +#endif + +static void +crtc_gamma_set(xf86CrtcPtr crtc, CARD16 * red, CARD16 * green, CARD16 * blue, + int size) +{ +} + +static void * +crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) +{ + //ScrnInfoPtr pScrn = crtc->scrn; + + return NULL; +} + +static PixmapPtr +crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) +{ + //ScrnInfoPtr pScrn = crtc->scrn; + + return NULL; +} + +static void +crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) +{ + //ScrnInfoPtr pScrn = crtc->scrn; +} + +static void +crtc_destroy(xf86CrtcPtr crtc) +{ + struct crtc_private *crtcp = crtc->driver_private; + + if (crtcp->cursor_tex) + pipe_texture_reference(&crtcp->cursor_tex, NULL); + + drmModeFreeCrtc(crtcp->drm_crtc); + xfree(crtcp); +} + +static void +crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image) +{ + unsigned char *ptr; + modesettingPtr ms = modesettingPTR(crtc->scrn); + struct crtc_private *crtcp = crtc->driver_private; + struct pipe_transfer *transfer; + + if (!crtcp->cursor_tex) { + struct pipe_texture templat; + unsigned pitch; + + memset(&templat, 0, sizeof(templat)); + templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET; + templat.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY; + templat.target = PIPE_TEXTURE_2D; + templat.last_level = 0; + templat.depth[0] = 1; + templat.format = PIPE_FORMAT_A8R8G8B8_UNORM; + templat.width[0] = 64; + templat.height[0] = 64; + pf_get_block(templat.format, &templat.block); + + crtcp->cursor_tex = ms->screen->texture_create(ms->screen, + &templat); + ms->api->local_handle_from_texture(ms->api, + ms->screen, + crtcp->cursor_tex, + &pitch, + &crtcp->cursor_handle); + } + + transfer = ms->screen->get_tex_transfer(ms->screen, crtcp->cursor_tex, + 0, 0, 0, + PIPE_TRANSFER_WRITE, + 0, 0, 64, 64); + ptr = ms->screen->transfer_map(ms->screen, transfer); + util_copy_rect(ptr, &crtcp->cursor_tex->block, + transfer->stride, 0, 0, + 64, 64, (void*)image, 64 * 4, 0, 0); + ms->screen->transfer_unmap(ms->screen, transfer); + ms->screen->tex_transfer_destroy(transfer); +} + +static void +crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y) +{ + modesettingPtr ms = modesettingPTR(crtc->scrn); + struct crtc_private *crtcp = crtc->driver_private; + + drmModeMoveCursor(ms->fd, crtcp->drm_crtc->crtc_id, x, y); +} + +static void +crtc_show_cursor(xf86CrtcPtr crtc) +{ + modesettingPtr ms = modesettingPTR(crtc->scrn); + struct crtc_private *crtcp = crtc->driver_private; + + if (crtcp->cursor_tex) + drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, + crtcp->cursor_handle, 64, 64); +} + +static void +crtc_hide_cursor(xf86CrtcPtr crtc) +{ + modesettingPtr ms = modesettingPTR(crtc->scrn); + struct crtc_private *crtcp = crtc->driver_private; + + drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, 0, 0, 0); +} + +static const xf86CrtcFuncsRec crtc_funcs = { + .dpms = crtc_dpms, + .save = NULL, + .restore = NULL, + .lock = crtc_lock, + .unlock = crtc_unlock, + .mode_fixup = crtc_mode_fixup, + .prepare = crtc_prepare, + .mode_set = crtc_mode_set, + .commit = crtc_commit, + .gamma_set = crtc_gamma_set, + .shadow_create = crtc_shadow_create, + .shadow_allocate = crtc_shadow_allocate, + .shadow_destroy = crtc_shadow_destroy, + .set_cursor_position = crtc_set_cursor_position, + .show_cursor = crtc_show_cursor, + .hide_cursor = crtc_hide_cursor, + .load_cursor_image = NULL, /* lets convert to argb only */ + .set_cursor_colors = NULL, /* using argb only */ + .load_cursor_argb = crtc_load_cursor_argb, + .destroy = crtc_destroy, +}; + +void +crtc_cursor_destroy(xf86CrtcPtr crtc) +{ + struct crtc_private *crtcp = crtc->driver_private; + + if (crtcp->cursor_tex) { + pipe_texture_reference(&crtcp->cursor_tex, NULL); + } +} + +void +crtc_init(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + xf86CrtcPtr crtc; + drmModeResPtr res; + drmModeCrtcPtr drm_crtc = NULL; + struct crtc_private *crtcp; + int c; + + res = drmModeGetResources(ms->fd); + if (res == 0) { + ErrorF("Failed drmModeGetResources %d\n", errno); + return; + } + + for (c = 0; c < res->count_crtcs; c++) { + drm_crtc = drmModeGetCrtc(ms->fd, res->crtcs[c]); + if (!drm_crtc) + continue; + + crtc = xf86CrtcCreate(pScrn, &crtc_funcs); + if (crtc == NULL) + goto out; + + crtcp = xcalloc(1, sizeof(struct crtc_private)); + if (!crtcp) { + xf86CrtcDestroy(crtc); + goto out; + } + + crtcp->drm_crtc = drm_crtc; + + crtc->driver_private = crtcp; + + } + + out: + drmModeFreeResources(res); +} + +/* vim: set sw=4 ts=8 sts=4: */ diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c new file mode 100644 index 0000000000..8a362596c7 --- /dev/null +++ b/src/gallium/state_trackers/xorg/xorg_dri2.c @@ -0,0 +1,380 @@ +/* + * 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. + * + * + * Author: Alan Hourihane <alanh@tungstengraphics.com> + * Author: Jakob Bornecrantz <wallbraker@gmail.com> + * + */ + +#include "xorg-server.h" +#include "xf86.h" +#include "xf86_OSproc.h" + +#include "xorg_tracker.h" +#include "xorg_exa.h" + +#include "dri2.h" + +#include "pipe/p_state.h" +#include "pipe/p_inlines.h" + +#include "util/u_rect.h" + +typedef struct { + PixmapPtr pPixmap; + struct pipe_texture *tex; + struct pipe_fence_handle *fence; +} *BufferPrivatePtr; + +static Bool +driDoCreateBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int format) +{ + struct pipe_texture *tex = NULL; + ScreenPtr pScreen = pDraw->pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_pixmap_priv *exa_priv; + BufferPrivatePtr private = buffer->driverPrivate; + PixmapPtr pPixmap; + unsigned stride, handle; + + if (pDraw->type == DRAWABLE_PIXMAP) + pPixmap = (PixmapPtr) pDraw; + else + pPixmap = (*pScreen->GetWindowPixmap)((WindowPtr) pDraw); + exa_priv = exaGetPixmapDriverPrivate(pPixmap); + + switch (buffer->attachment) { + default: + if (buffer->attachment != DRI2BufferFakeFrontLeft || + pDraw->type != DRAWABLE_PIXMAP) { + private->pPixmap = (*pScreen->CreatePixmap)(pScreen, pDraw->width, + pDraw->height, + pDraw->depth, + 0); + } + break; + case DRI2BufferFrontLeft: + break; + case DRI2BufferStencil: +#if defined(DRI2INFOREC_VERSION) && DRI2INFOREC_VERSION > 2 + case DRI2BufferDepthStencil: + if (exa_priv->depth_stencil_tex && + !pf_is_depth_stencil(exa_priv->depth_stencil_tex->format)) + exa_priv->depth_stencil_tex = NULL; + /* Fall through */ +#endif + case DRI2BufferDepth: + if (exa_priv->depth_stencil_tex) + pipe_texture_reference(&tex, exa_priv->depth_stencil_tex); + else { + struct pipe_texture template; + memset(&template, 0, sizeof(template)); + template.target = PIPE_TEXTURE_2D; + if (buffer->attachment == DRI2BufferDepth) + template.format = ms->ds_depth_bits_last ? + PIPE_FORMAT_X8Z24_UNORM : PIPE_FORMAT_Z24X8_UNORM; + else + template.format = ms->ds_depth_bits_last ? + PIPE_FORMAT_S8Z24_UNORM : PIPE_FORMAT_Z24S8_UNORM; + pf_get_block(template.format, &template.block); + template.width[0] = pDraw->width; + template.height[0] = pDraw->height; + template.depth[0] = 1; + template.last_level = 0; + template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL | + PIPE_TEXTURE_USAGE_DISPLAY_TARGET; + tex = ms->screen->texture_create(ms->screen, &template); + pipe_texture_reference(&exa_priv->depth_stencil_tex, tex); + } + break; + } + + if (!private->pPixmap) { + private->pPixmap = pPixmap; + pPixmap->refcnt++; + } + + if (!tex) { + exaMoveInPixmap(private->pPixmap); + xorg_exa_set_shared_usage(private->pPixmap); + pScreen->ModifyPixmapHeader(private->pPixmap, 0, 0, 0, 0, 0, NULL); + tex = xorg_exa_get_texture(private->pPixmap); + } + + if (!tex) + FatalError("NO TEXTURE IN DRI2\n"); + + ms->api->shared_handle_from_texture(ms->api, ms->screen, tex, &stride, &handle); + + buffer->name = handle; + buffer->pitch = stride; + buffer->cpp = 4; + buffer->driverPrivate = private; + buffer->flags = 0; /* not tiled */ + private->tex = tex; + + return TRUE; +} + +static void +driDoDestroyBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer) +{ + ScreenPtr pScreen = pDraw->pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + BufferPrivatePtr private = buffer->driverPrivate; + struct exa_pixmap_priv *exa_priv = exaGetPixmapDriverPrivate(private->pPixmap); + + pipe_texture_reference(&private->tex, NULL); + ms->screen->fence_reference(ms->screen, &private->fence, NULL); + pipe_texture_reference(&exa_priv->depth_stencil_tex, NULL); + (*pScreen->DestroyPixmap)(private->pPixmap); +} + +#if defined(DRI2INFOREC_VERSION) && DRI2INFOREC_VERSION > 2 + +static DRI2BufferPtr +driCreateBuffer(DrawablePtr pDraw, unsigned int attachment, unsigned int format) +{ + DRI2BufferPtr buffer; + BufferPrivatePtr private; + + buffer = xcalloc(1, sizeof *buffer); + if (!buffer) + return NULL; + + private = xcalloc(1, sizeof *private); + if (!private) { + goto fail; + } + + buffer->attachment = attachment; + buffer->driverPrivate = private; + + if (driDoCreateBuffer(pDraw, buffer, format)) + return buffer; + + xfree(private); +fail: + xfree(buffer); + return NULL; +} + +static void +driDestroyBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer) +{ + driDoDestroyBuffer(pDraw, buffer); + + xfree(buffer->driverPrivate); + xfree(buffer); +} + +#else /* DRI2INFOREC_VERSION <= 2 */ + +static DRI2BufferPtr +driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count) +{ + BufferPrivatePtr privates; + DRI2BufferPtr buffers; + int i; + + buffers = xcalloc(count, sizeof *buffers); + if (!buffers) + goto fail_buffers; + + privates = xcalloc(count, sizeof *privates); + if (!privates) + goto fail_privates; + + for (i = 0; i < count; i++) { + buffers[i].attachment = attachments[i]; + buffers[i].driverPrivate = &privates[i]; + + if (!driDoCreateBuffer(pDraw, &buffers[i], 0)) + goto fail; + } + + return buffers; + +fail: + xfree(privates); +fail_privates: + xfree(buffers); +fail_buffers: + return NULL; +} + +static void +driDestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count) +{ + int i; + + for (i = 0; i < count; i++) { + driDoDestroyBuffer(pDraw, &buffers[i]); + } + + if (buffers) { + xfree(buffers[0].driverPrivate); + xfree(buffers); + } +} + +#endif /* DRI2INFOREC_VERSION */ + +static void +driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion, + DRI2BufferPtr pDestBuffer, DRI2BufferPtr pSrcBuffer) +{ + ScreenPtr pScreen = pDraw->pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + BufferPrivatePtr dst_priv = pDestBuffer->driverPrivate; + BufferPrivatePtr src_priv = pSrcBuffer->driverPrivate; + PixmapPtr src_pixmap; + PixmapPtr dst_pixmap; + GCPtr gc; + RegionPtr copy_clip; + + /* + * In driCreateBuffers we dewrap windows into the + * backing pixmaps in order to get to the texture. + * We need to use the real drawable in CopyArea + * so that cliprects and offsets are correct. + */ + src_pixmap = src_priv->pPixmap; + dst_pixmap = dst_priv->pPixmap; + if (pSrcBuffer->attachment == DRI2BufferFrontLeft) + src_pixmap = (PixmapPtr)pDraw; + if (pDestBuffer->attachment == DRI2BufferFrontLeft) + dst_pixmap = (PixmapPtr)pDraw; + + /* + * The clients implements glXWaitX with a copy front to fake and then + * waiting on the server to signal its completion of it. While + * glXWaitGL is a client side flush and a copy from fake to front. + * This is how it is done in the DRI2 protocol, how ever depending + * which type of drawables the server does things a bit differently + * then what the protocol says as the fake and front are the same. + * + * for pixmaps glXWaitX is a server flush. + * for pixmaps glXWaitGL is a client flush. + * for windows glXWaitX is a copy from front to fake then a server flush. + * for windows glXWaitGL is a client flush then a copy from fake to front. + * + * XXX in the windows case this code always flushes but that isn't a + * must in the glXWaitGL case but we don't know if this is a glXWaitGL + * or a glFlush/glFinish call. + */ + if (dst_pixmap == src_pixmap) { + /* pixmap glXWaitX */ + if (pSrcBuffer->attachment == DRI2BufferFrontLeft && + pDestBuffer->attachment == DRI2BufferFakeFrontLeft) { + ms->ctx->flush(ms->ctx, PIPE_FLUSH_SWAPBUFFERS, NULL); + return; + } + /* pixmap glXWaitGL */ + if (pDestBuffer->attachment == DRI2BufferFrontLeft && + pSrcBuffer->attachment == DRI2BufferFakeFrontLeft) { + return; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "copying between the same pixmap\n"); + } + } + + gc = GetScratchGC(pDraw->depth, pScreen); + copy_clip = REGION_CREATE(pScreen, NULL, 0); + REGION_COPY(pScreen, copy_clip, pRegion); + (*gc->funcs->ChangeClip) (gc, CT_REGION, copy_clip, 0); + ValidateGC(&dst_pixmap->drawable, gc); + + /* If this is a full buffer swap, throttle on the previous one */ + if (dst_priv->fence && REGION_NUM_RECTS(pRegion) == 1) { + BoxPtr extents = REGION_EXTENTS(pScreen, pRegion); + + if (extents->x1 == 0 && extents->y1 == 0 && + extents->x2 == pDraw->width && extents->y2 == pDraw->height) { + ms->screen->fence_finish(ms->screen, dst_priv->fence, 0); + ms->screen->fence_reference(ms->screen, &dst_priv->fence, NULL); + } + } + + (*gc->ops->CopyArea)(&src_pixmap->drawable, &dst_pixmap->drawable, gc, + 0, 0, pDraw->width, pDraw->height, 0, 0); + + FreeScratchGC(gc); + + ms->ctx->flush(ms->ctx, PIPE_FLUSH_SWAPBUFFERS, + pDestBuffer->attachment == DRI2BufferFrontLeft ? + &dst_priv->fence : NULL); +} + +Bool +driScreenInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + DRI2InfoRec dri2info; + +#if defined(DRI2INFOREC_VERSION) + dri2info.version = DRI2INFOREC_VERSION; +#else + dri2info.version = 1; +#endif + dri2info.fd = ms->fd; + + dri2info.driverName = pScrn->driverName; + dri2info.deviceName = "/dev/dri/card0"; /* FIXME */ + +#if defined(DRI2INFOREC_VERSION) && DRI2INFOREC_VERSION > 2 + dri2info.CreateBuffer = driCreateBuffer; + dri2info.DestroyBuffer = driDestroyBuffer; +#else + dri2info.CreateBuffers = driCreateBuffers; + dri2info.DestroyBuffers = driDestroyBuffers; +#endif + dri2info.CopyRegion = driCopyRegion; + dri2info.Wait = NULL; + + ms->d_depth_bits_last = + ms->screen->is_format_supported(ms->screen, PIPE_FORMAT_X8Z24_UNORM, + PIPE_TEXTURE_2D, + PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); + ms->ds_depth_bits_last = + ms->screen->is_format_supported(ms->screen, PIPE_FORMAT_S8Z24_UNORM, + PIPE_TEXTURE_2D, + PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); + + return DRI2ScreenInit(pScreen, &dri2info); +} + +void +driCloseScreen(ScreenPtr pScreen) +{ + DRI2CloseScreen(pScreen); +} + +/* vim: set sw=4 ts=8 sts=4: */ diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c new file mode 100644 index 0000000000..643b6b3b9e --- /dev/null +++ b/src/gallium/state_trackers/xorg/xorg_driver.c @@ -0,0 +1,744 @@ +/* + * 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. + * + * + * Author: Alan Hourihane <alanh@tungstengraphics.com> + * Author: Jakob Bornecrantz <wallbraker@gmail.com> + * + */ + + +#include "xorg-server.h" +#include "xf86.h" +#include "xf86_OSproc.h" +#include "compiler.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "mipointer.h" +#include "micmap.h" +#include <X11/extensions/randr.h> +#include "fb.h" +#include "edid.h" +#include "xf86i2c.h" +#include "xf86Crtc.h" +#include "miscstruct.h" +#include "dixstruct.h" +#include "xf86xv.h" +#include <X11/extensions/Xv.h> +#ifndef XSERVER_LIBPCIACCESS +#error "libpciaccess needed" +#endif + +#include <pciaccess.h> + +#include "pipe/p_context.h" +#include "xorg_tracker.h" +#include "xorg_winsys.h" + +static void AdjustFrame(int scrnIndex, int x, int y, int flags); +static Bool CloseScreen(int scrnIndex, ScreenPtr pScreen); +static Bool EnterVT(int scrnIndex, int flags); +static Bool SaveHWState(ScrnInfoPtr pScrn); +static Bool RestoreHWState(ScrnInfoPtr pScrn); + + +static ModeStatus ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, + int flags); +static void FreeScreen(int scrnIndex, int flags); +static void LeaveVT(int scrnIndex, int flags); +static Bool SwitchMode(int scrnIndex, DisplayModePtr mode, int flags); +static Bool ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, + char **argv); +static Bool PreInit(ScrnInfoPtr pScrn, int flags); + +typedef enum +{ + OPTION_SW_CURSOR, +} modesettingOpts; + +static const OptionInfoRec Options[] = { + {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, + {-1, NULL, OPTV_NONE, {0}, FALSE} +}; + +/* + * Exported Xorg driver functions to winsys + */ + +const OptionInfoRec * +xorg_tracker_available_options(int chipid, int busid) +{ + return Options; +} + +void +xorg_tracker_set_functions(ScrnInfoPtr scrn) +{ + scrn->PreInit = PreInit; + scrn->ScreenInit = ScreenInit; + scrn->SwitchMode = SwitchMode; + scrn->AdjustFrame = AdjustFrame; + scrn->EnterVT = EnterVT; + scrn->LeaveVT = LeaveVT; + scrn->FreeScreen = FreeScreen; + scrn->ValidMode = ValidMode; +} + +/* + * Static Xorg funtctions + */ + +static Bool +GetRec(ScrnInfoPtr pScrn) +{ + if (pScrn->driverPrivate) + return TRUE; + + pScrn->driverPrivate = xnfcalloc(sizeof(modesettingRec), 1); + + return TRUE; +} + +static void +FreeRec(ScrnInfoPtr pScrn) +{ + if (!pScrn) + return; + + if (!pScrn->driverPrivate) + return; + + xfree(pScrn->driverPrivate); + + pScrn->driverPrivate = NULL; +} + +static void +ProbeDDC(ScrnInfoPtr pScrn, int index) +{ + ConfiguredMonitor = NULL; +} + +static Bool +CreateFrontBuffer(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + ScreenPtr pScreen = pScrn->pScreen; + PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); + unsigned handle, stride; + + ms->noEvict = TRUE; + xorg_exa_set_displayed_usage(rootPixmap); + pScreen->ModifyPixmapHeader(rootPixmap, + pScrn->virtualX, pScrn->virtualY, + pScrn->depth, pScrn->bitsPerPixel, + pScrn->displayWidth * pScrn->bitsPerPixel / 8, + NULL); + ms->noEvict = FALSE; + + handle = xorg_exa_get_pixmap_handle(rootPixmap, &stride); + + drmModeAddFB(ms->fd, + pScrn->virtualX, + pScrn->virtualY, + pScrn->depth, + pScrn->bitsPerPixel, + stride, + handle, + &ms->fb_id); + + pScrn->frameX0 = 0; + pScrn->frameY0 = 0; + AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + + return TRUE; +} + +static Bool +crtc_resize(ScrnInfoPtr pScrn, int width, int height) +{ + modesettingPtr ms = modesettingPTR(pScrn); + //ScreenPtr pScreen = pScrn->pScreen; + //PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); + //Bool fbAccessDisabled; + //CARD8 *fbstart; + + if (width == pScrn->virtualX && height == pScrn->virtualY) + return TRUE; + + ErrorF("RESIZING TO %dx%d\n", width, height); + + pScrn->virtualX = width; + pScrn->virtualY = height; + + /* HW dependent - FIXME */ + pScrn->displayWidth = pScrn->virtualX; + + drmModeRmFB(ms->fd, ms->fb_id); + + /* now create new frontbuffer */ + return CreateFrontBuffer(pScrn); +} + +static const xf86CrtcConfigFuncsRec crtc_config_funcs = { + crtc_resize +}; + +static Bool +PreInit(ScrnInfoPtr pScrn, int flags) +{ + xf86CrtcConfigPtr xf86_config; + modesettingPtr ms; + rgb defaultWeight = { 0, 0, 0 }; + EntityInfoPtr pEnt; + EntPtr msEnt = NULL; + char *BusID; + int max_width, max_height; + + if (pScrn->numEntities != 1) + return FALSE; + + pEnt = xf86GetEntityInfo(pScrn->entityList[0]); + + if (flags & PROBE_DETECT) { + ProbeDDC(pScrn, pEnt->index); + return TRUE; + } + + /* Allocate driverPrivate */ + if (!GetRec(pScrn)) + return FALSE; + + ms = modesettingPTR(pScrn); + ms->SaveGeneration = -1; + ms->pEnt = pEnt; + + pScrn->displayWidth = 640; /* default it */ + + if (ms->pEnt->location.type != BUS_PCI) + return FALSE; + + ms->PciInfo = xf86GetPciInfoForEntity(ms->pEnt->index); + + /* Allocate an entity private if necessary */ + if (xf86IsEntityShared(pScrn->entityList[0])) { + FatalError("Entity"); +#if 0 + msEnt = xf86GetEntityPrivate(pScrn->entityList[0], + modesettingEntityIndex)->ptr; + ms->entityPrivate = msEnt; +#else + (void)msEnt; +#endif + } else + ms->entityPrivate = NULL; + + if (xf86IsEntityShared(pScrn->entityList[0])) { + if (xf86IsPrimInitDone(pScrn->entityList[0])) { + /* do something */ + } else { + xf86SetPrimInitDone(pScrn->entityList[0]); + } + } + + BusID = xalloc(64); + sprintf(BusID, "PCI:%d:%d:%d", + ((ms->PciInfo->domain << 8) | ms->PciInfo->bus), + ms->PciInfo->dev, ms->PciInfo->func + ); + + ms->api = drm_api_create(); + ms->fd = drmOpen(NULL, BusID); + + if (ms->fd < 0) + return FALSE; + + pScrn->monitor = pScrn->confScreen->monitor; + pScrn->progClock = TRUE; + pScrn->rgbBits = 8; + + if (!xf86SetDepthBpp + (pScrn, 0, 0, 0, + PreferConvert24to32 | SupportConvert24to32 | Support32bppFb)) + return FALSE; + + switch (pScrn->depth) { + case 15: + case 16: + case 24: + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Given depth (%d) is not supported by the driver\n", + pScrn->depth); + return FALSE; + } + xf86PrintDepthBpp(pScrn); + + if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) + return FALSE; + if (!xf86SetDefaultVisual(pScrn, -1)) + return FALSE; + + /* Process the options */ + xf86CollectOptions(pScrn, NULL); + if (!(ms->Options = xalloc(sizeof(Options)))) + return FALSE; + memcpy(ms->Options, Options, sizeof(Options)); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, ms->Options); + + /* Allocate an xf86CrtcConfig */ + xf86CrtcConfigInit(pScrn, &crtc_config_funcs); + xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + + max_width = 8192; + max_height = 8192; + xf86CrtcSetSizeRange(pScrn, 320, 200, max_width, max_height); + + if (xf86ReturnOptValBool(ms->Options, OPTION_SW_CURSOR, FALSE)) { + ms->SWCursor = TRUE; + } + + SaveHWState(pScrn); + + crtc_init(pScrn); + output_init(pScrn); + + if (!xf86InitialConfiguration(pScrn, TRUE)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); + RestoreHWState(pScrn); + return FALSE; + } + + RestoreHWState(pScrn); + + /* + * If the driver can do gamma correction, it should call xf86SetGamma() here. + */ + { + Gamma zeros = { 0.0, 0.0, 0.0 }; + + if (!xf86SetGamma(pScrn, zeros)) { + return FALSE; + } + } + + if (pScrn->modes == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n"); + return FALSE; + } + + pScrn->currentMode = pScrn->modes; + + /* Set display resolution */ + xf86SetDpi(pScrn, 0, 0); + + /* Load the required sub modules */ + if (!xf86LoadSubModule(pScrn, "fb")) { + return FALSE; + } + + xf86LoadSubModule(pScrn, "exa"); + +#ifdef DRI2 + xf86LoadSubModule(pScrn, "dri2"); +#endif + + return TRUE; +} + +static Bool +SaveHWState(ScrnInfoPtr pScrn) +{ + /*xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);*/ + + return TRUE; +} + +static Bool +RestoreHWState(ScrnInfoPtr pScrn) +{ + /*xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);*/ + + return TRUE; +} + +static void xorgBlockHandler(int i, pointer blockData, pointer pTimeout, + pointer pReadmask) +{ + ScreenPtr pScreen = screenInfo.screens[i]; + modesettingPtr ms = modesettingPTR(xf86Screens[pScreen->myNum]); + + pScreen->BlockHandler = ms->blockHandler; + pScreen->BlockHandler(i, blockData, pTimeout, pReadmask); + pScreen->BlockHandler = xorgBlockHandler; + + ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE, NULL); + +#ifdef DRM_MODE_FEATURE_DIRTYFB + { + RegionPtr dirty = DamageRegion(ms->damage); + unsigned num_cliprects = REGION_NUM_RECTS(dirty); + + if (num_cliprects) { + drmModeClip *clip = alloca(num_cliprects * sizeof(drmModeClip)); + BoxPtr rect = REGION_RECTS(dirty); + int i; + + for (i = 0; i < num_cliprects; i++, rect++) { + clip[i].x = rect->x1; + clip[i].y = rect->y1; + clip[i].width = rect->x2 - rect->x1; + clip[i].height = rect->y2 - rect->y1; + } + + /* TODO query connector property to see if this is needed */ + drmModeDirtyFB(ms->fd, ms->fb_id, clip, num_cliprects); + + DamageEmpty(ms->damage); + } + } +#endif +} + +static Bool +CreateScreenResources(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + PixmapPtr rootPixmap; + Bool ret; + unsigned handle, stride; + + ms->noEvict = TRUE; + + pScreen->CreateScreenResources = ms->createScreenResources; + ret = pScreen->CreateScreenResources(pScreen); + pScreen->CreateScreenResources = CreateScreenResources; + + rootPixmap = pScreen->GetScreenPixmap(pScreen); + + xorg_exa_set_displayed_usage(rootPixmap); + xorg_exa_set_shared_usage(rootPixmap); + if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, NULL)) + FatalError("Couldn't adjust screen pixmap\n"); + + ms->noEvict = FALSE; + + handle = xorg_exa_get_pixmap_handle(rootPixmap, &stride); + + drmModeAddFB(ms->fd, + pScrn->virtualX, + pScrn->virtualY, + pScrn->depth, + pScrn->bitsPerPixel, + stride, + handle, + &ms->fb_id); + + AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + +#ifdef DRM_MODE_FEATURE_DIRTYFB + ms->damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE, + pScreen, rootPixmap); + + if (ms->damage) { + DamageRegister(&rootPixmap->drawable, ms->damage); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Damage tracking initialized\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to create screen damage record\n"); + return FALSE; + } +#endif + + return ret; +} + +static Bool +ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + VisualPtr visual; + + /* deal with server regeneration */ + if (ms->fd < 0) { + char *BusID; + + BusID = xalloc(64); + sprintf(BusID, "PCI:%d:%d:%d", + ((ms->PciInfo->domain << 8) | ms->PciInfo->bus), + ms->PciInfo->dev, ms->PciInfo->func + ); + + ms->fd = drmOpen(NULL, BusID); + + if (ms->fd < 0) + return FALSE; + } + + if (!ms->screen) { + ms->screen = ms->api->create_screen(ms->api, ms->fd, NULL); + + if (!ms->screen) { + FatalError("Could not init pipe_screen\n"); + return FALSE; + } + } + + pScrn->pScreen = pScreen; + + /* HW dependent - FIXME */ + pScrn->displayWidth = pScrn->virtualX; + + miClearVisualTypes(); + + if (!miSetVisualTypes(pScrn->depth, + miGetDefaultVisualMask(pScrn->depth), + pScrn->rgbBits, pScrn->defaultVisual)) + return FALSE; + + if (!miSetPixmapDepths()) + return FALSE; + + pScrn->memPhysBase = 0; + pScrn->fbOffset = 0; + + if (!fbScreenInit(pScreen, NULL, + pScrn->virtualX, pScrn->virtualY, + pScrn->xDpi, pScrn->yDpi, + pScrn->displayWidth, pScrn->bitsPerPixel)) + return FALSE; + + if (pScrn->bitsPerPixel > 8) { + /* Fixup RGB ordering */ + visual = pScreen->visuals + pScreen->numVisuals; + while (--visual >= pScreen->visuals) { + if ((visual->class | DynamicClass) == DirectColor) { + visual->offsetRed = pScrn->offset.red; + visual->offsetGreen = pScrn->offset.green; + visual->offsetBlue = pScrn->offset.blue; + visual->redMask = pScrn->mask.red; + visual->greenMask = pScrn->mask.green; + visual->blueMask = pScrn->mask.blue; + } + } + } + + fbPictureInit(pScreen, NULL, 0); + + ms->blockHandler = pScreen->BlockHandler; + pScreen->BlockHandler = xorgBlockHandler; + ms->createScreenResources = pScreen->CreateScreenResources; + pScreen->CreateScreenResources = CreateScreenResources; + + xf86SetBlackWhitePixels(pScreen); + + ms->exa = xorg_exa_init(pScrn); + + miInitializeBackingStore(pScreen); + xf86SetBackingStore(pScreen); + xf86SetSilkenMouse(pScreen); + miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); + + /* Need to extend HWcursor support to handle mask interleave */ + if (!ms->SWCursor) + xf86_cursors_init(pScreen, 64, 64, + HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 | + HARDWARE_CURSOR_ARGB); + + /* Must force it before EnterVT, so we are in control of VT and + * later memory should be bound when allocating, e.g rotate_mem */ + pScrn->vtSema = TRUE; + + pScreen->SaveScreen = xf86SaveScreen; + ms->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = CloseScreen; + + if (!xf86CrtcScreenInit(pScreen)) + return FALSE; + + if (!miCreateDefColormap(pScreen)) + return FALSE; + + xf86DPMSInit(pScreen, xf86DPMSSet, 0); + + if (serverGeneration == 1) + xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + +#if 1 +#ifdef DRI2 + driScreenInit(pScreen); +#endif +#endif + + return EnterVT(scrnIndex, 1); +} + +static void +AdjustFrame(int scrnIndex, int x, int y, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + xf86OutputPtr output = config->output[config->compat_output]; + xf86CrtcPtr crtc = output->crtc; + + if (crtc && crtc->enabled) { + crtc->funcs->mode_set(crtc, pScrn->currentMode, pScrn->currentMode, x, + y); + crtc->x = output->initial_x + x; + crtc->y = output->initial_y + y; + } +} + +static void +FreeScreen(int scrnIndex, int flags) +{ + FreeRec(xf86Screens[scrnIndex]); +} + +static void +LeaveVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + modesettingPtr ms = modesettingPTR(pScrn); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + int o; + + for (o = 0; o < config->num_crtc; o++) { + xf86CrtcPtr crtc = config->crtc[o]; + + crtc_cursor_destroy(crtc); + + if (crtc->rotatedPixmap || crtc->rotatedData) { + crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap, + crtc->rotatedData); + crtc->rotatedPixmap = NULL; + crtc->rotatedData = NULL; + } + } + + drmModeRmFB(ms->fd, ms->fb_id); + + RestoreHWState(pScrn); + + if (drmDropMaster(ms->fd)) + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "drmDropMaster failed: %s\n", strerror(errno)); + + pScrn->vtSema = FALSE; +} + +/* + * This gets called when gaining control of the VT, and from ScreenInit(). + */ +static Bool +EnterVT(int scrnIndex, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + modesettingPtr ms = modesettingPTR(pScrn); + + if (drmSetMaster(ms->fd)) { + if (errno == EINVAL) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "drmSetMaster failed: 2.6.29 or newer kernel required for " + "multi-server DRI\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "drmSetMaster failed: %s\n", strerror(errno)); + } + } + + /* + * Only save state once per server generation since that's what most + * drivers do. Could change this to save state at each VT enter. + */ + if (ms->SaveGeneration != serverGeneration) { + ms->SaveGeneration = serverGeneration; + SaveHWState(pScrn); + } + + if (!flags) /* signals startup as we'll do this in CreateScreenResources */ + CreateFrontBuffer(pScrn); + + if (!xf86SetDesiredModes(pScrn)) + return FALSE; + + return TRUE; +} + +static Bool +SwitchMode(int scrnIndex, DisplayModePtr mode, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + + return xf86SetSingleMode(pScrn, mode, RR_Rotate_0); +} + +static Bool +CloseScreen(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + modesettingPtr ms = modesettingPTR(pScrn); + + if (pScrn->vtSema) { + LeaveVT(scrnIndex, 0); + } +#ifdef DRI2 + driCloseScreen(pScreen); +#endif + + pScreen->BlockHandler = ms->blockHandler; + pScreen->CreateScreenResources = ms->createScreenResources; + +#ifdef DRM_MODE_FEATURE_DIRTYFB + if (ms->damage) { + DamageUnregister(&pScreen->GetScreenPixmap(pScreen)->drawable, ms->damage); + DamageDestroy(ms->damage); + ms->damage = NULL; + } +#endif + + if (ms->exa) + xorg_exa_close(pScrn); + + ms->api->destroy(ms->api); + ms->api = NULL; + drmClose(ms->fd); + ms->fd = -1; + + pScrn->vtSema = FALSE; + pScreen->CloseScreen = ms->CloseScreen; + return (*pScreen->CloseScreen) (scrnIndex, pScreen); +} + +static ModeStatus +ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) +{ + return MODE_OK; +} + +/* vim: set sw=4 ts=8 sts=4: */ diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c new file mode 100644 index 0000000000..312dab1544 --- /dev/null +++ b/src/gallium/state_trackers/xorg/xorg_exa.c @@ -0,0 +1,771 @@ +/* + * 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. + * + * + * Author: Alan Hourihane <alanh@tungstengraphics.com> + * Author: Jakob Bornecrantz <wallbraker@gmail.com> + * + */ + +#include "xorg_exa.h" +#include "xorg_tracker.h" +#include "xorg_composite.h" +#include "xorg_exa_tgsi.h" + +#include <xorg-server.h> +#include <xf86.h> +#include <picturestr.h> +#include <picture.h> + +#include "pipe/p_format.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "pipe/p_inlines.h" + +#include "cso_cache/cso_context.h" + +#include "util/u_rect.h" + +/* + * Helper functions + */ + +static void +exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp) +{ + switch (depth) { + case 32: + *format = PIPE_FORMAT_A8R8G8B8_UNORM; + assert(*bbp == 32); + break; + case 24: + *format = PIPE_FORMAT_X8R8G8B8_UNORM; + assert(*bbp == 32); + break; + case 16: + *format = PIPE_FORMAT_R5G6B5_UNORM; + assert(*bbp == 16); + break; + case 15: + *format = PIPE_FORMAT_A1R5G5B5_UNORM; + assert(*bbp == 16); + break; + case 8: + case 4: + case 1: + *format = PIPE_FORMAT_A8R8G8B8_UNORM; /* bad bad bad */ + break; + default: + assert(0); + break; + } +} + +static void +xorg_exa_init_state(struct exa_context *exa) +{ + struct pipe_depth_stencil_alpha_state dsa; + + /* set common initial clip state */ + memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state)); + cso_set_depth_stencil_alpha(exa->cso, &dsa); +} + +static void +xorg_exa_common_done(struct exa_context *exa) +{ + exa->copy.src = NULL; + exa->copy.dst = NULL; + exa->has_solid_color = FALSE; + exa->num_bound_samplers = 0; +} + +/* + * Static exported EXA functions + */ + +static void +ExaWaitMarker(ScreenPtr pScreen, int marker) +{ +} + +static int +ExaMarkSync(ScreenPtr pScreen) +{ + return 1; +} + +static Bool +ExaDownloadFromScreen(PixmapPtr pPix, int x, int y, int w, int h, char *dst, + int dst_pitch) +{ + ScreenPtr pScreen = pPix->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_context *exa = ms->exa; + struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPix); + struct pipe_transfer *transfer; + + if (!priv || !priv->tex) + return FALSE; + + if (exa->pipe->is_texture_referenced(exa->pipe, priv->tex, 0, 0) & + PIPE_REFERENCED_FOR_WRITE) + exa->pipe->flush(exa->pipe, 0, NULL); + + transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0, + PIPE_TRANSFER_READ, x, y, w, h); + if (!transfer) + return FALSE; + + util_copy_rect((unsigned char*)dst, &priv->tex->block, dst_pitch, 0, 0, + w, h, exa->scrn->transfer_map(exa->scrn, transfer), + transfer->stride, 0, 0); + + exa->scrn->transfer_unmap(exa->scrn, transfer); + exa->scrn->tex_transfer_destroy(transfer); + + return TRUE; +} + +static Bool +ExaUploadToScreen(PixmapPtr pPix, int x, int y, int w, int h, char *src, + int src_pitch) +{ + ScreenPtr pScreen = pPix->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_context *exa = ms->exa; + struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPix); + struct pipe_transfer *transfer; + + if (!priv || !priv->tex) + return FALSE; + + transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0, + PIPE_TRANSFER_WRITE, x, y, w, h); + if (!transfer) + return FALSE; + + util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer), + &priv->tex->block, transfer->stride, 0, 0, w, h, + (unsigned char*)src, src_pitch, 0, 0); + + exa->scrn->transfer_unmap(exa->scrn, transfer); + exa->scrn->tex_transfer_destroy(transfer); + + return TRUE; +} + +static Bool +ExaPrepareAccess(PixmapPtr pPix, int index) +{ + ScreenPtr pScreen = pPix->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_context *exa = ms->exa; + struct exa_pixmap_priv *priv; + + priv = exaGetPixmapDriverPrivate(pPix); + + if (!priv) + return FALSE; + + if (!priv->tex) + return FALSE; + + if (priv->map_count++ == 0) + { + if (exa->pipe->is_texture_referenced(exa->pipe, priv->tex, 0, 0) & + PIPE_REFERENCED_FOR_WRITE) + exa->pipe->flush(exa->pipe, 0, NULL); + + priv->map_transfer = + exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0, + PIPE_TRANSFER_READ_WRITE, + 0, 0, priv->tex->width[0], priv->tex->height[0]); + + pPix->devPrivate.ptr = + exa->scrn->transfer_map(exa->scrn, priv->map_transfer); + pPix->devKind = priv->map_transfer->stride; + } + + return TRUE; +} + +static void +ExaFinishAccess(PixmapPtr pPix, int index) +{ + ScreenPtr pScreen = pPix->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_context *exa = ms->exa; + struct exa_pixmap_priv *priv; + priv = exaGetPixmapDriverPrivate(pPix); + + if (!priv) + return; + + if (!priv->map_transfer) + return; + + if (--priv->map_count == 0) { + assert(priv->map_transfer); + exa->scrn->transfer_unmap(exa->scrn, priv->map_transfer); + exa->scrn->tex_transfer_destroy(priv->map_transfer); + priv->map_transfer = NULL; + pPix->devPrivate.ptr = NULL; + } +} + +static void +ExaDone(PixmapPtr pPixmap) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); + struct exa_context *exa = ms->exa; + + if (!priv) + return; + +#if 1 + xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, NULL); +#else + xorg_finish(exa); +#endif + xorg_exa_common_done(exa); +} + +static void +ExaDoneComposite(PixmapPtr pPixmap) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_context *exa = ms->exa; + + xorg_exa_common_done(exa); +} + +static Bool +ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); + struct exa_context *exa = ms->exa; + + debug_printf("ExaPrepareSolid - test\n"); + if (pPixmap->drawable.depth < 15) + return FALSE; + + if (!EXA_PM_IS_SOLID(&pPixmap->drawable, planeMask)) + return FALSE; + + if (!priv || !priv->tex) + return FALSE; + + if (alu != GXcopy) + return FALSE; + + if (!exa->pipe) + return FALSE; + + debug_printf(" ExaPrepareSolid(0x%x)\n", fg); + return xorg_solid_bind_state(exa, priv, fg); +} + +static void +ExaSolid(PixmapPtr pPixmap, int x0, int y0, int x1, int y1) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_context *exa = ms->exa; + struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); + + debug_printf("\tExaSolid(%d, %d, %d, %d)\n", x0, y0, x1, y1); + +#if 0 + if (x0 == 0 && y0 == 0 && + x1 == priv->tex->width[0] && + y1 == priv->tex->height[0]) { + exa->ctx->clear(exa->ctx, PIPE_CLEAR_COLOR | PIPE_CLEAR_DEPTHSTENCIL, + exa->solid_color, 1., 0); + } else +#endif + xorg_solid(exa, priv, x0, y0, x1, y1) ; +} + +static Bool +ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, + int ydir, int alu, Pixel planeMask) +{ + ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_context *exa = ms->exa; + struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDstPixmap); + struct exa_pixmap_priv *src_priv = exaGetPixmapDriverPrivate(pSrcPixmap); + + debug_printf("ExaPrepareCopy\n"); + + if (alu != GXcopy) + return FALSE; + + if (pSrcPixmap->drawable.depth < 15 || pDstPixmap->drawable.depth < 15) + return FALSE; + + if (!EXA_PM_IS_SOLID(&pSrcPixmap->drawable, planeMask)) + return FALSE; + + if (!priv || !src_priv) + return FALSE; + + if (!priv->tex || !src_priv->tex) + return FALSE; + + if (!exa->pipe) + return FALSE; + + exa->copy.src = src_priv; + exa->copy.dst = priv; + + /*XXX disabled until some issues with syncing are fixed */ + return FALSE; +} + +static void +ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, + int width, int height) +{ + ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_context *exa = ms->exa; + struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDstPixmap); + + debug_printf("\tExaCopy(srcx=%d, srcy=%d, dstX=%d, dstY=%d, w=%d, h=%d)\n", + srcX, srcY, dstX, dstY, width, height); + + debug_assert(priv == exa->copy.dst); + + xorg_copy_pixmap(exa, exa->copy.dst, dstX, dstY, + exa->copy.src, srcX, srcY, + width, height); +} + +static Bool +ExaPrepareComposite(int op, PicturePtr pSrcPicture, + PicturePtr pMaskPicture, PicturePtr pDstPicture, + PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) +{ + ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_context *exa = ms->exa; + + debug_printf("ExaPrepareComposite\n"); + + return xorg_composite_bind_state(exa, op, pSrcPicture, pMaskPicture, + pDstPicture, + exaGetPixmapDriverPrivate(pSrc), + exaGetPixmapDriverPrivate(pMask), + exaGetPixmapDriverPrivate(pDst)); +} + +static void +ExaComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, + int dstX, int dstY, int width, int height) +{ + ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_context *exa = ms->exa; + struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDst); + + debug_printf("\tExaComposite\n"); + + xorg_composite(exa, priv, srcX, srcY, maskX, maskY, + dstX, dstY, width, height); +} + +static Bool +ExaCheckComposite(int op, + PicturePtr pSrcPicture, PicturePtr pMaskPicture, + PicturePtr pDstPicture) +{ + return xorg_composite_accelerated(op, + pSrcPicture, + pMaskPicture, + pDstPicture); +} + +static void * +ExaCreatePixmap(ScreenPtr pScreen, int size, int align) +{ + struct exa_pixmap_priv *priv; + + priv = xcalloc(1, sizeof(struct exa_pixmap_priv)); + if (!priv) + return NULL; + + return priv; +} + +static void +ExaDestroyPixmap(ScreenPtr pScreen, void *dPriv) +{ + struct exa_pixmap_priv *priv = (struct exa_pixmap_priv *)dPriv; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + + if (!priv) + return; + + if (priv->tex) + ms->screen->texture_destroy(priv->tex); + + xfree(priv); +} + +static Bool +ExaPixmapIsOffscreen(PixmapPtr pPixmap) +{ + struct exa_pixmap_priv *priv; + + priv = exaGetPixmapDriverPrivate(pPixmap); + + if (!priv) + return FALSE; + + if (priv->tex) + return TRUE; + + return FALSE; +} + +int +xorg_exa_set_displayed_usage(PixmapPtr pPixmap) +{ + struct exa_pixmap_priv *priv; + priv = exaGetPixmapDriverPrivate(pPixmap); + + if (!priv) { + FatalError("NO PIXMAP PRIVATE\n"); + return 0; + } + + priv->flags |= PIPE_TEXTURE_USAGE_PRIMARY; + + return 0; +} + +int +xorg_exa_set_shared_usage(PixmapPtr pPixmap) +{ + struct exa_pixmap_priv *priv; + priv = exaGetPixmapDriverPrivate(pPixmap); + + if (!priv) { + FatalError("NO PIXMAP PRIVATE\n"); + return 0; + } + + priv->flags |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET; + + return 0; +} + +unsigned +xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride_out) +{ + ScreenPtr pScreen = pPixmap->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_pixmap_priv *priv; + unsigned handle; + unsigned stride; + + if (!ms->exa) { + FatalError("NO MS->EXA\n"); + return 0; + } + + priv = exaGetPixmapDriverPrivate(pPixmap); + + if (!priv) { + FatalError("NO PIXMAP PRIVATE\n"); + return 0; + } + + ms->api->local_handle_from_texture(ms->api, ms->screen, priv->tex, &stride, &handle); + if (stride_out) + *stride_out = stride; + + return handle; +} + +static Bool +ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, + int depth, int bitsPerPixel, int devKind, + pointer pPixData) +{ + ScreenPtr pScreen = pPixmap->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_context *exa = ms->exa; + + if (!priv || pPixData) + return FALSE; + + if (depth <= 0) + depth = pPixmap->drawable.depth; + + if (bitsPerPixel <= 0) + bitsPerPixel = pPixmap->drawable.bitsPerPixel; + + if (width <= 0) + width = pPixmap->drawable.width; + + if (height <= 0) + height = pPixmap->drawable.height; + + if (width <= 0 || height <= 0 || depth <= 0) + return FALSE; + + miModifyPixmapHeader(pPixmap, width, height, depth, + bitsPerPixel, devKind, NULL); + + /* Deal with screen resize */ + if (!priv->tex || + (priv->tex->width[0] != width || + priv->tex->height[0] != height || + priv->tex_flags != priv->flags)) { + struct pipe_texture *texture = NULL; + +#ifdef DRM_MODE_FEATURE_DIRTYFB + if (priv->flags) +#endif + { + struct pipe_texture template; + + memset(&template, 0, sizeof(template)); + template.target = PIPE_TEXTURE_2D; + exa_get_pipe_format(depth, &template.format, &bitsPerPixel); + pf_get_block(template.format, &template.block); + template.width[0] = width; + template.height[0] = height; + template.depth[0] = 1; + template.last_level = 0; + template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET | priv->flags; + priv->tex_flags = priv->flags; + texture = exa->scrn->texture_create(exa->scrn, &template); + + if (priv->tex) { + struct pipe_surface *dst_surf; + struct pipe_surface *src_surf; + + dst_surf = exa->scrn->get_tex_surface(exa->scrn, texture, 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_WRITE); + src_surf = exa_gpu_surface(exa, priv); + exa->pipe->surface_copy(exa->pipe, dst_surf, 0, 0, src_surf, + 0, 0, min(width, texture->width[0]), + min(height, texture->height[0])); + exa->scrn->tex_surface_destroy(dst_surf); + exa->scrn->tex_surface_destroy(src_surf); + } else if (pPixmap->devPrivate.ptr) { + struct pipe_transfer *transfer; + + if (priv->map_count != 0) + FatalError("doing ExaModifyPixmapHeader on mapped buffer\n"); + + transfer = + exa->scrn->get_tex_transfer(exa->scrn, texture, 0, 0, 0, + PIPE_TRANSFER_WRITE, + 0, 0, width, height); + util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer), + &texture->block, transfer->stride, 0, 0, + width, height, pPixmap->devPrivate.ptr, + pPixmap->devKind, 0, 0); + exa->scrn->transfer_unmap(exa->scrn, transfer); + exa->scrn->tex_transfer_destroy(transfer); + + xfree(pPixmap->devPrivate.ptr); + pPixmap->devPrivate.ptr = NULL; + } + } +#ifdef DRM_MODE_FEATURE_DIRTYFB + else { + xfree(pPixmap->devPrivate.ptr); + pPixmap->devPrivate.ptr = xalloc(pPixmap->drawable.height * + pPixmap->devKind); + } +#endif + + pipe_texture_reference(&priv->tex, texture); + } + + return TRUE; +} + +struct pipe_texture * +xorg_exa_get_texture(PixmapPtr pPixmap) +{ + struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap); + struct pipe_texture *tex = NULL; + pipe_texture_reference(&tex, priv->tex); + return tex; +} + +void +xorg_exa_close(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_context *exa = ms->exa; + struct pipe_constant_buffer *vsbuf = &exa->vs_const_buffer; + struct pipe_constant_buffer *fsbuf = &exa->fs_const_buffer; + + if (exa->shaders) { + xorg_shaders_destroy(exa->shaders); + } + + if (vsbuf && vsbuf->buffer) + pipe_buffer_reference(&vsbuf->buffer, NULL); + + if (fsbuf && fsbuf->buffer) + pipe_buffer_reference(&fsbuf->buffer, NULL); + + if (exa->cso) { + cso_release_all(exa->cso); + cso_destroy_context(exa->cso); + } + + if (exa->pipe) + exa->pipe->destroy(exa->pipe); + + exaDriverFini(pScrn->pScreen); + xfree(exa); + ms->exa = NULL; +} + +void * +xorg_exa_init(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + struct exa_context *exa; + ExaDriverPtr pExa; + + exa = xcalloc(1, sizeof(struct exa_context)); + if (!exa) + return NULL; + + pExa = exaDriverAlloc(); + if (!pExa) { + goto out_err; + } + + memset(pExa, 0, sizeof(*pExa)); + + pExa->exa_major = 2; + pExa->exa_minor = 2; + pExa->memoryBase = 0; + pExa->memorySize = 0; + pExa->offScreenBase = 0; + pExa->pixmapOffsetAlign = 0; + pExa->pixmapPitchAlign = 1; + pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS; +#ifdef EXA_SUPPORTS_PREPARE_AUX + pExa->flags |= EXA_SUPPORTS_PREPARE_AUX; +#endif +#ifdef EXA_MIXED_PIXMAPS + pExa->flags |= EXA_MIXED_PIXMAPS; +#endif + pExa->maxX = 8191; /* FIXME */ + pExa->maxY = 8191; /* FIXME */ + + pExa->WaitMarker = ExaWaitMarker; + pExa->MarkSync = ExaMarkSync; + pExa->PrepareSolid = ExaPrepareSolid; + pExa->Solid = ExaSolid; + pExa->DoneSolid = ExaDone; + pExa->PrepareCopy = ExaPrepareCopy; + pExa->Copy = ExaCopy; + pExa->DoneCopy = ExaDone; + pExa->CheckComposite = ExaCheckComposite; + pExa->PrepareComposite = ExaPrepareComposite; + pExa->Composite = ExaComposite; + pExa->DoneComposite = ExaDoneComposite; + pExa->PixmapIsOffscreen = ExaPixmapIsOffscreen; + pExa->DownloadFromScreen = ExaDownloadFromScreen; + pExa->UploadToScreen = ExaUploadToScreen; + pExa->PrepareAccess = ExaPrepareAccess; + pExa->FinishAccess = ExaFinishAccess; + pExa->CreatePixmap = ExaCreatePixmap; + pExa->DestroyPixmap = ExaDestroyPixmap; + pExa->ModifyPixmapHeader = ExaModifyPixmapHeader; + + if (!exaDriverInit(pScrn->pScreen, pExa)) { + goto out_err; + } + + exa->scrn = ms->screen; + exa->pipe = ms->api->create_context(ms->api, exa->scrn); + /* Share context with DRI */ + ms->ctx = exa->pipe; + + exa->cso = cso_create_context(exa->pipe); + exa->shaders = xorg_shaders_create(exa); + + xorg_exa_init_state(exa); + + return (void *)exa; + +out_err: + xorg_exa_close(pScrn); + + return NULL; +} + +struct pipe_surface * +exa_gpu_surface(struct exa_context *exa, struct exa_pixmap_priv *priv) +{ + return exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_GPU_WRITE); + +} + +void xorg_exa_flush(struct exa_context *exa, uint pipeFlushFlags, + struct pipe_fence_handle **fence) +{ + exa->pipe->flush(exa->pipe, pipeFlushFlags, fence); +} + +void xorg_exa_finish(struct exa_context *exa) +{ + struct pipe_fence_handle *fence = NULL; + + xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, &fence); + + exa->pipe->screen->fence_finish(exa->pipe->screen, fence, 0); + exa->pipe->screen->fence_reference(exa->pipe->screen, &fence, NULL); +} + diff --git a/src/gallium/state_trackers/xorg/xorg_exa.h b/src/gallium/state_trackers/xorg/xorg_exa.h new file mode 100644 index 0000000000..43949b04a4 --- /dev/null +++ b/src/gallium/state_trackers/xorg/xorg_exa.h @@ -0,0 +1,57 @@ +#ifndef XORG_EXA_H +#define XORG_EXA_H + +#include "xorg_tracker.h" + +#include <pipe/p_state.h> + +struct cso_context; +struct xorg_shaders; + +/* src + mask + dst */ +#define MAX_EXA_SAMPLERS 3 + +struct exa_context +{ + ExaDriverPtr pExa; + struct pipe_context *pipe; + struct pipe_screen *scrn; + struct cso_context *cso; + struct xorg_shaders *shaders; + + struct pipe_constant_buffer vs_const_buffer; + struct pipe_constant_buffer fs_const_buffer; + + struct pipe_texture *bound_textures[MAX_EXA_SAMPLERS]; + int num_bound_samplers; + + float solid_color[4]; + boolean has_solid_color; + + struct { + struct exa_pixmap_priv *src; + struct exa_pixmap_priv *dst; + } copy; +}; + + +struct exa_pixmap_priv +{ + int flags; + int tex_flags; + + struct pipe_texture *tex; + struct pipe_texture *depth_stencil_tex; + + struct pipe_transfer *map_transfer; + unsigned map_count; +}; + +struct pipe_surface * +exa_gpu_surface(struct exa_context *exa, struct exa_pixmap_priv *priv); + +void xorg_exa_flush(struct exa_context *exa, uint pipeFlushFlags, + struct pipe_fence_handle **fence); +void xorg_exa_finish(struct exa_context *exa); + +#endif diff --git a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c new file mode 100644 index 0000000000..694eded09a --- /dev/null +++ b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c @@ -0,0 +1,489 @@ +#include "xorg_exa_tgsi.h" + +/*### stupidity defined in X11/extensions/XI.h */ +#undef Absolute + +#include "pipe/p_format.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "pipe/p_inlines.h" +#include "pipe/p_shader_tokens.h" + +#include "util/u_memory.h" +#include "util/u_simple_shaders.h" + +#include "tgsi/tgsi_ureg.h" + +#include "cso_cache/cso_context.h" +#include "cso_cache/cso_hash.h" + +/* Vertex shader: + * IN[0] = vertex pos + * IN[1] = src tex coord | solid fill color + * IN[2] = mask tex coord + * IN[3] = dst tex coord + * CONST[0] = (2/dst_width, 2/dst_height, 1, 1) + * CONST[1] = (-1, -1, 0, 0) + * + * OUT[0] = vertex pos + * OUT[1] = src tex coord | solid fill color + * OUT[2] = mask tex coord + * OUT[3] = dst tex coord + */ + +/* Fragment shader: + * SAMP[0] = src + * SAMP[1] = mask + * SAMP[2] = dst + * IN[0] = pos src | solid fill color + * IN[1] = pos mask + * IN[2] = pos dst + * CONST[0] = (0, 0, 0, 1) + * + * OUT[0] = color + */ + +struct xorg_shaders { + struct exa_context *exa; + + struct cso_hash *vs_hash; + struct cso_hash *fs_hash; +}; + +static const char over_op[] = + "SUB TEMP[3], CONST[0].wwww, TEMP[1].wwww\n" + "MUL TEMP[3], TEMP[0], TEMP[3]\n" + "ADD TEMP[0], TEMP[3], TEMP[0]\n"; + + +static INLINE void +create_preamble(struct ureg_program *ureg) +{ +} + + +static INLINE void +src_in_mask(struct ureg_program *ureg, + struct ureg_dst dst, + struct ureg_src src, + struct ureg_src mask) +{ + /* MUL dst, src, mask.wwww */ + ureg_MUL(ureg, dst, src, + ureg_scalar(mask, TGSI_SWIZZLE_W)); +} + +static struct ureg_src +vs_normalize_coords(struct ureg_program *ureg, struct ureg_src coords, + struct ureg_src const0, struct ureg_src const1) +{ + struct ureg_dst tmp = ureg_DECL_temporary(ureg); + struct ureg_src ret; + ureg_MUL(ureg, tmp, coords, const0); + ureg_ADD(ureg, tmp, ureg_src(tmp), const1); + ret = ureg_src(tmp); + ureg_release_temporary(ureg, tmp); + return ret; +} + +static void +linear_gradient(struct ureg_program *ureg, + struct ureg_dst out, + struct ureg_src pos, + struct ureg_src sampler, + struct ureg_src coords, + struct ureg_src const0124, + struct ureg_src matrow0, + struct ureg_src matrow1, + struct ureg_src matrow2) +{ + struct ureg_dst temp0 = ureg_DECL_temporary(ureg); + struct ureg_dst temp1 = ureg_DECL_temporary(ureg); + struct ureg_dst temp2 = ureg_DECL_temporary(ureg); + struct ureg_dst temp3 = ureg_DECL_temporary(ureg); + struct ureg_dst temp4 = ureg_DECL_temporary(ureg); + struct ureg_dst temp5 = ureg_DECL_temporary(ureg); + + ureg_MOV(ureg, + ureg_writemask(temp0, TGSI_WRITEMASK_XY), pos); + ureg_MOV(ureg, + ureg_writemask(temp0, TGSI_WRITEMASK_Z), + ureg_scalar(const0124, TGSI_SWIZZLE_Y)); + + ureg_DP3(ureg, temp1, matrow0, ureg_src(temp0)); + ureg_DP3(ureg, temp2, matrow1, ureg_src(temp0)); + ureg_DP3(ureg, temp3, matrow2, ureg_src(temp0)); + ureg_RCP(ureg, temp3, ureg_src(temp3)); + ureg_MUL(ureg, temp1, ureg_src(temp1), ureg_src(temp3)); + ureg_MUL(ureg, temp2, ureg_src(temp2), ureg_src(temp3)); + + ureg_MOV(ureg, ureg_writemask(temp4, TGSI_WRITEMASK_X), + ureg_src(temp1)); + ureg_MOV(ureg, ureg_writemask(temp4, TGSI_WRITEMASK_Y), + ureg_src(temp2)); + + ureg_MUL(ureg, temp0, + ureg_scalar(coords, TGSI_SWIZZLE_Y), + ureg_scalar(ureg_src(temp4), TGSI_SWIZZLE_Y)); + ureg_MAD(ureg, temp1, + ureg_scalar(coords, TGSI_SWIZZLE_X), + ureg_scalar(ureg_src(temp4), TGSI_SWIZZLE_X), + ureg_src(temp0)); + + ureg_MUL(ureg, temp2, + ureg_src(temp1), + ureg_scalar(coords, TGSI_SWIZZLE_Z)); + + ureg_TEX(ureg, out, + TGSI_TEXTURE_1D, ureg_src(temp2), sampler); + + ureg_release_temporary(ureg, temp0); + ureg_release_temporary(ureg, temp1); + ureg_release_temporary(ureg, temp2); + ureg_release_temporary(ureg, temp3); + ureg_release_temporary(ureg, temp4); + ureg_release_temporary(ureg, temp5); +} + + +static void +radial_gradient(struct ureg_program *ureg, + struct ureg_dst out, + struct ureg_src pos, + struct ureg_src sampler, + struct ureg_src coords, + struct ureg_src const0124, + struct ureg_src matrow0, + struct ureg_src matrow1, + struct ureg_src matrow2) +{ + struct ureg_dst temp0 = ureg_DECL_temporary(ureg); + struct ureg_dst temp1 = ureg_DECL_temporary(ureg); + struct ureg_dst temp2 = ureg_DECL_temporary(ureg); + struct ureg_dst temp3 = ureg_DECL_temporary(ureg); + struct ureg_dst temp4 = ureg_DECL_temporary(ureg); + struct ureg_dst temp5 = ureg_DECL_temporary(ureg); + + ureg_MOV(ureg, + ureg_writemask(temp0, TGSI_WRITEMASK_XY), + pos); + ureg_MOV(ureg, + ureg_writemask(temp0, TGSI_WRITEMASK_Z), + ureg_scalar(const0124, TGSI_SWIZZLE_Y)); + + ureg_DP3(ureg, temp1, matrow0, ureg_src(temp0)); + ureg_DP3(ureg, temp2, matrow1, ureg_src(temp0)); + ureg_DP3(ureg, temp3, matrow2, ureg_src(temp0)); + ureg_RCP(ureg, temp3, ureg_src(temp3)); + ureg_MUL(ureg, temp1, ureg_src(temp1), ureg_src(temp3)); + ureg_MUL(ureg, temp2, ureg_src(temp2), ureg_src(temp3)); + + ureg_MOV(ureg, ureg_writemask(temp5, TGSI_WRITEMASK_X), + ureg_src(temp1)); + ureg_MOV(ureg, ureg_writemask(temp5, TGSI_WRITEMASK_Y), + ureg_src(temp2)); + + ureg_MUL(ureg, temp0, ureg_scalar(coords, TGSI_SWIZZLE_Y), + ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y)); + ureg_MAD(ureg, temp1, + ureg_scalar(coords, TGSI_SWIZZLE_X), + ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X), + ureg_src(temp0)); + ureg_ADD(ureg, temp1, + ureg_src(temp1), ureg_src(temp1)); + ureg_MUL(ureg, temp3, + ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y), + ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y)); + ureg_MAD(ureg, temp4, + ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X), + ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X), + ureg_src(temp3)); + ureg_MOV(ureg, temp4, ureg_negate(ureg_src(temp4))); + ureg_MUL(ureg, temp2, + ureg_scalar(coords, TGSI_SWIZZLE_Z), + ureg_src(temp4)); + ureg_MUL(ureg, temp0, + ureg_scalar(const0124, TGSI_SWIZZLE_W), + ureg_src(temp2)); + ureg_MUL(ureg, temp3, + ureg_src(temp1), ureg_src(temp1)); + ureg_SUB(ureg, temp2, + ureg_src(temp3), ureg_src(temp0)); + ureg_RSQ(ureg, temp2, ureg_abs(ureg_src(temp2))); + ureg_RCP(ureg, temp2, ureg_src(temp2)); + ureg_SUB(ureg, temp1, + ureg_src(temp2), ureg_src(temp1)); + ureg_ADD(ureg, temp0, + ureg_scalar(coords, TGSI_SWIZZLE_Z), + ureg_scalar(coords, TGSI_SWIZZLE_Z)); + ureg_RCP(ureg, temp0, ureg_src(temp0)); + ureg_MUL(ureg, temp2, + ureg_src(temp1), ureg_src(temp0)); + ureg_TEX(ureg, out, TGSI_TEXTURE_1D, + ureg_src(temp2), sampler); + + ureg_release_temporary(ureg, temp0); + ureg_release_temporary(ureg, temp1); + ureg_release_temporary(ureg, temp2); + ureg_release_temporary(ureg, temp3); + ureg_release_temporary(ureg, temp4); + ureg_release_temporary(ureg, temp5); +} + +static void * +create_vs(struct pipe_context *pipe, + unsigned vs_traits) +{ + struct ureg_program *ureg; + struct ureg_src src; + struct ureg_dst dst; + struct ureg_src const0, const1; + boolean is_fill = vs_traits & VS_FILL; + boolean is_composite = vs_traits & VS_COMPOSITE; + boolean has_mask = vs_traits & VS_MASK; + + ureg = ureg_create(TGSI_PROCESSOR_VERTEX); + if (ureg == NULL) + return 0; + + const0 = ureg_DECL_constant(ureg); + const1 = ureg_DECL_constant(ureg); + + /* it has to be either a fill or a composite op */ + debug_assert(is_fill ^ is_composite); + + src = ureg_DECL_vs_input(ureg, + TGSI_SEMANTIC_POSITION, 0); + dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0); + src = vs_normalize_coords(ureg, src, + const0, const1); + ureg_MOV(ureg, dst, src); + + + if (is_composite) { + src = ureg_DECL_vs_input(ureg, + TGSI_SEMANTIC_GENERIC, 1); + dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 1); + ureg_MOV(ureg, dst, src); + } + if (is_fill) { + src = ureg_DECL_vs_input(ureg, + TGSI_SEMANTIC_COLOR, 0); + dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); + ureg_MOV(ureg, dst, src); + } + + if (has_mask) { + src = ureg_DECL_vs_input(ureg, + TGSI_SEMANTIC_GENERIC, 2); + dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 2); + ureg_MOV(ureg, dst, src); + } + + ureg_END(ureg); + + return ureg_create_shader_and_destroy(ureg, pipe); +} + +static void * +create_fs(struct pipe_context *pipe, + unsigned fs_traits) +{ + struct ureg_program *ureg; + struct ureg_src /*dst_sampler,*/ src_sampler, mask_sampler; + struct ureg_src /*dst_pos,*/ src_input, mask_pos; + struct ureg_dst src, mask; + struct ureg_dst out; + boolean has_mask = fs_traits & FS_MASK; + boolean is_fill = fs_traits & FS_FILL; + boolean is_composite = fs_traits & FS_COMPOSITE; + boolean is_solid = fs_traits & FS_SOLID_FILL; + boolean is_lingrad = fs_traits & FS_LINGRAD_FILL; + boolean is_radgrad = fs_traits & FS_RADGRAD_FILL; + + ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT); + if (ureg == NULL) + return 0; + + /* it has to be either a fill or a composite op */ + debug_assert(is_fill ^ is_composite); + + out = ureg_DECL_output(ureg, + TGSI_SEMANTIC_COLOR, + 0); + + if (is_composite) { + src_sampler = ureg_DECL_sampler(ureg, 0); + src_input = ureg_DECL_fs_input(ureg, + TGSI_SEMANTIC_POSITION, + 0, + TGSI_INTERPOLATE_PERSPECTIVE); + } else { + debug_assert(is_fill); + if (is_solid) + src_input = ureg_DECL_fs_input(ureg, + TGSI_SEMANTIC_COLOR, + 0, + TGSI_INTERPOLATE_PERSPECTIVE); + else + src_input = ureg_DECL_fs_input(ureg, + TGSI_SEMANTIC_POSITION, + 0, + TGSI_INTERPOLATE_PERSPECTIVE); + } + + if (has_mask) { + mask_sampler = ureg_DECL_sampler(ureg, 1); + mask_pos = ureg_DECL_fs_input(ureg, + TGSI_SEMANTIC_POSITION, + 1, + TGSI_INTERPOLATE_PERSPECTIVE); + } + +#if 0 /* unused right now */ + dst_sampler = ureg_DECL_sampler(ureg, 2); + dst_pos = ureg_DECL_fs_input(ureg, + TGSI_SEMANTIC_POSITION, + 2, + TGSI_INTERPOLATE_PERSPECTIVE); +#endif + + if (is_composite) { + if (has_mask) + src = ureg_DECL_temporary(ureg); + else + src = out; + ureg_TEX(ureg, src, + TGSI_TEXTURE_2D, src_input, src_sampler); + } else if (is_fill) { + if (is_solid) { + if (has_mask) + src = ureg_dst(src_input); + else + ureg_MOV(ureg, out, src_input); + } else if (is_lingrad || is_radgrad) { + struct ureg_src coords, const0124, + matrow0, matrow1, matrow2; + + if (has_mask) + src = ureg_DECL_temporary(ureg); + else + src = out; + + coords = ureg_DECL_constant(ureg); + const0124 = ureg_DECL_constant(ureg); + matrow0 = ureg_DECL_constant(ureg); + matrow1 = ureg_DECL_constant(ureg); + matrow2 = ureg_DECL_constant(ureg); + + if (is_lingrad) { + linear_gradient(ureg, src, + src_input, src_sampler, + coords, const0124, + matrow0, matrow1, matrow2); + } else if (is_radgrad) { + radial_gradient(ureg, src, + src_input, src_sampler, + coords, const0124, + matrow0, matrow1, matrow2); + } + } else + debug_assert(!"Unknown fill type!"); + } + + if (has_mask) { + mask = ureg_DECL_temporary(ureg); + ureg_TEX(ureg, mask, + TGSI_TEXTURE_2D, mask_pos, mask_sampler); + /* src IN mask */ + src_in_mask(ureg, out, ureg_src(src), ureg_src(mask)); + ureg_release_temporary(ureg, mask); + } + + ureg_END(ureg); + + return ureg_create_shader_and_destroy(ureg, pipe); +} + +struct xorg_shaders * xorg_shaders_create(struct exa_context *exa) +{ + struct xorg_shaders *sc = CALLOC_STRUCT(xorg_shaders); + + sc->exa = exa; + sc->vs_hash = cso_hash_create(); + sc->fs_hash = cso_hash_create(); + + return sc; +} + +static void +cache_destroy(struct cso_context *cso, + struct cso_hash *hash, + unsigned processor) +{ + struct cso_hash_iter iter = cso_hash_first_node(hash); + while (!cso_hash_iter_is_null(iter)) { + void *shader = (void *)cso_hash_iter_data(iter); + if (processor == PIPE_SHADER_FRAGMENT) { + cso_delete_fragment_shader(cso, shader); + } else if (processor == PIPE_SHADER_VERTEX) { + cso_delete_vertex_shader(cso, shader); + } + iter = cso_hash_erase(hash, iter); + } + cso_hash_delete(hash); +} + +void xorg_shaders_destroy(struct xorg_shaders *sc) +{ + cache_destroy(sc->exa->cso, sc->vs_hash, + PIPE_SHADER_VERTEX); + cache_destroy(sc->exa->cso, sc->fs_hash, + PIPE_SHADER_FRAGMENT); + + free(sc); +} + +static INLINE void * +shader_from_cache(struct pipe_context *pipe, + unsigned type, + struct cso_hash *hash, + unsigned key) +{ + void *shader = 0; + + struct cso_hash_iter iter = cso_hash_find(hash, key); + + if (cso_hash_iter_is_null(iter)) { + if (type == PIPE_SHADER_VERTEX) + shader = create_vs(pipe, key); + else + shader = create_fs(pipe, key); + cso_hash_insert(hash, key, shader); + } else + shader = (void *)cso_hash_iter_data(iter); + + return shader; +} + +struct xorg_shader xorg_shaders_get(struct xorg_shaders *sc, + unsigned vs_traits, + unsigned fs_traits) +{ + struct xorg_shader shader = {0}; + void *vs, *fs; + + vs = shader_from_cache(sc->exa->pipe, PIPE_SHADER_VERTEX, + sc->vs_hash, vs_traits); + fs = shader_from_cache(sc->exa->pipe, PIPE_SHADER_FRAGMENT, + sc->fs_hash, fs_traits); + + debug_assert(vs && fs); + if (!vs || !fs) + return shader; + + shader.vs = vs; + shader.fs = fs; + + return shader; +} diff --git a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.h b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.h new file mode 100644 index 0000000000..1535a0c8c3 --- /dev/null +++ b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.h @@ -0,0 +1,43 @@ +#ifndef XORG_EXA_TGSI_H +#define XORG_EXA_TGSI_H + +#include "xorg_exa.h" + +enum xorg_vs_traits { + VS_COMPOSITE = 1 << 0, + VS_MASK = 1 << 1, + VS_SOLID_FILL = 1 << 2, + VS_LINGRAD_FILL = 1 << 3, + VS_RADGRAD_FILL = 1 << 4, + VS_FILL = (VS_SOLID_FILL | + VS_LINGRAD_FILL | + VS_RADGRAD_FILL) + /*VS_TRANSFORM = 1 << 5*/ +}; + +enum xorg_fs_traits { + FS_COMPOSITE = 1 << 0, + FS_MASK = 1 << 1, + FS_SOLID_FILL = 1 << 2, + FS_LINGRAD_FILL = 1 << 3, + FS_RADGRAD_FILL = 1 << 4, + FS_FILL = (FS_SOLID_FILL | + FS_LINGRAD_FILL | + FS_RADGRAD_FILL) +}; + +struct xorg_shader { + void *fs; + void *vs; +}; + +struct xorg_shaders; + +struct xorg_shaders *xorg_shaders_create(struct exa_context *exa); +void xorg_shaders_destroy(struct xorg_shaders *shaders); + +struct xorg_shader xorg_shaders_get(struct xorg_shaders *shaders, + unsigned vs_traits, + unsigned fs_traits); + +#endif diff --git a/src/gallium/state_trackers/xorg/xorg_output.c b/src/gallium/state_trackers/xorg/xorg_output.c new file mode 100644 index 0000000000..950af942f5 --- /dev/null +++ b/src/gallium/state_trackers/xorg/xorg_output.c @@ -0,0 +1,296 @@ +/* + * 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. + * + * + * Author: Alan Hourihane <alanh@tungstengraphics.com> + * Author: Jakob Bornecrantz <wallbraker@gmail.com> + * + */ + +#include "xorg-server.h" +#include <xf86.h> +#include <xf86i2c.h> +#include <xf86Crtc.h> +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> + +#define DPMS_SERVER +#include <X11/extensions/dpms.h> + +#include "X11/Xatom.h" + +#include "xorg_tracker.h" + +static char *connector_enum_list[] = { + "Unknown", + "VGA", + "DVI-I", + "DVI-D", + "DVI-A", + "Composite", + "SVIDEO", + "LVDS", + "Component", + "9-pin DIN", + "DisplayPort", + "HDMI Type A", + "HDMI Type B", +}; + +static void +dpms(xf86OutputPtr output, int mode) +{ +} + +static void +save(xf86OutputPtr output) +{ +} + +static void +restore(xf86OutputPtr output) +{ +} + +static int +mode_valid(xf86OutputPtr output, DisplayModePtr pMode) +{ + return MODE_OK; +} + +static Bool +mode_fixup(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + return TRUE; +} + +static void +prepare(xf86OutputPtr output) +{ + dpms(output, DPMSModeOff); +} + +static void +mode_set(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ +} + +static void +commit(xf86OutputPtr output) +{ + dpms(output, DPMSModeOn); + + if (output->scrn->pScreen != NULL) + xf86_reload_cursors(output->scrn->pScreen); +} + +static xf86OutputStatus +detect(xf86OutputPtr output) +{ + drmModeConnectorPtr drm_connector = output->driver_private; + + switch (drm_connector->connection) { + case DRM_MODE_CONNECTED: + return XF86OutputStatusConnected; + case DRM_MODE_DISCONNECTED: + return XF86OutputStatusDisconnected; + default: + return XF86OutputStatusUnknown; + } +} + +static DisplayModePtr +get_modes(xf86OutputPtr output) +{ + drmModeConnectorPtr drm_connector = output->driver_private; + drmModeModeInfoPtr drm_mode = NULL; + DisplayModePtr modes = NULL, mode = NULL; + int i; + + for (i = 0; i < drm_connector->count_modes; i++) { + drm_mode = &drm_connector->modes[i]; + if (drm_mode) { + mode = xcalloc(1, sizeof(DisplayModeRec)); + if (!mode) + continue; + mode->type = 0; + mode->Clock = drm_mode->clock; + mode->HDisplay = drm_mode->hdisplay; + mode->HSyncStart = drm_mode->hsync_start; + mode->HSyncEnd = drm_mode->hsync_end; + mode->HTotal = drm_mode->htotal; + mode->VDisplay = drm_mode->vdisplay; + mode->VSyncStart = drm_mode->vsync_start; + mode->VSyncEnd = drm_mode->vsync_end; + mode->VTotal = drm_mode->vtotal; + mode->Flags = drm_mode->flags; + mode->HSkew = drm_mode->hskew; + mode->VScan = drm_mode->vscan; + mode->VRefresh = xf86ModeVRefresh(mode); + mode->Private = (void *)drm_mode; + xf86SetModeDefaultName(mode); + modes = xf86ModesAdd(modes, mode); + xf86PrintModeline(0, mode); + } + } + + return modes; +} + +static void +destroy(xf86OutputPtr output) +{ + drmModeFreeConnector(output->driver_private); +} + +static void +create_resources(xf86OutputPtr output) +{ +#ifdef RANDR_12_INTERFACE +#endif /* RANDR_12_INTERFACE */ +} + +#ifdef RANDR_12_INTERFACE +static Bool +set_property(xf86OutputPtr output, Atom property, RRPropertyValuePtr value) +{ + return TRUE; +} +#endif /* RANDR_12_INTERFACE */ + +#ifdef RANDR_13_INTERFACE +static Bool +get_property(xf86OutputPtr output, Atom property) +{ + return TRUE; +} +#endif /* RANDR_13_INTERFACE */ + +#ifdef RANDR_GET_CRTC_INTERFACE +static xf86CrtcPtr +get_crtc(xf86OutputPtr output) +{ + return NULL; +} +#endif + +static const xf86OutputFuncsRec output_funcs = { + .create_resources = create_resources, + .dpms = dpms, + .save = save, + .restore = restore, + .mode_valid = mode_valid, + .mode_fixup = mode_fixup, + .prepare = prepare, + .mode_set = mode_set, + .commit = commit, + .detect = detect, + .get_modes = get_modes, +#ifdef RANDR_12_INTERFACE + .set_property = set_property, +#endif +#ifdef RANDR_13_INTERFACE + .get_property = get_property, +#endif + .destroy = destroy, +#ifdef RANDR_GET_CRTC_INTERFACE + .get_crtc = get_crtc, +#endif +}; + +void +output_init(ScrnInfoPtr pScrn) +{ + modesettingPtr ms = modesettingPTR(pScrn); + xf86OutputPtr output; + drmModeResPtr res; + drmModeConnectorPtr drm_connector = NULL; + drmModeEncoderPtr drm_encoder = NULL; + char *name; + int c, v, p; + + res = drmModeGetResources(ms->fd); + if (res == 0) { + DRV_ERROR("Failed drmModeGetResources\n"); + return; + } + + for (c = 0; c < res->count_connectors; c++) { + drm_connector = drmModeGetConnector(ms->fd, res->connectors[c]); + if (!drm_connector) + goto out; + +#if 0 + for (p = 0; p < drm_connector->count_props; p++) { + drmModePropertyPtr prop; + + prop = drmModeGetProperty(ms->fd, drm_connector->props[p]); + + name = NULL; + if (prop) { + ErrorF("VALUES %d\n", prop->count_values); + + for (v = 0; v < prop->count_values; v++) + ErrorF("%s %lld\n", prop->name, prop->values[v]); + } + } +#else + (void)p; + (void)v; +#endif + + name = connector_enum_list[drm_connector->connector_type]; + + output = xf86OutputCreate(pScrn, &output_funcs, name); + if (!output) + continue; + + drm_encoder = drmModeGetEncoder(ms->fd, drm_connector->encoders[0]); + if (drm_encoder) { + output->possible_crtcs = drm_encoder->possible_crtcs; + output->possible_clones = drm_encoder->possible_clones; + } else { + output->possible_crtcs = 0; + output->possible_clones = 0; + } + output->driver_private = drm_connector; + output->subpixel_order = SubPixelHorizontalRGB; + output->interlaceAllowed = FALSE; + output->doubleScanAllowed = FALSE; + } + + out: + drmModeFreeResources(res); +} + +/* vim: set sw=4 ts=8 sts=4: */ diff --git a/src/gallium/state_trackers/xorg/xorg_tracker.h b/src/gallium/state_trackers/xorg/xorg_tracker.h new file mode 100644 index 0000000000..b1ab783a15 --- /dev/null +++ b/src/gallium/state_trackers/xorg/xorg_tracker.h @@ -0,0 +1,155 @@ +/* + * 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. + * + * + * Author: Alan Hourihane <alanh@tungstengraphics.com> + * Author: Jakob Bornecrantz <wallbraker@gmail.com> + * + */ + +#ifndef _XORG_TRACKER_H_ +#define _XORG_TRACKER_H_ + +#include <stddef.h> +#include <stdint.h> +#include <errno.h> +#include <drm.h> +#include <xf86drm.h> +#include <xf86drmMode.h> +#include <xorg-server.h> +#include <xf86.h> +#include "xf86Crtc.h" +#include <exa.h> + +#ifdef DRM_MODE_FEATURE_DIRTYFB +#include <damage.h> +#endif + +#include "pipe/p_screen.h" +#include "state_tracker/drm_api.h" + +#define DRV_ERROR(msg) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, msg); + +typedef struct +{ + int lastInstance; + int refCount; + ScrnInfoPtr pScrn_1; + ScrnInfoPtr pScrn_2; +} EntRec, *EntPtr; + +typedef struct _modesettingRec +{ + /* drm */ + int fd; + unsigned fb_id; + + /* X */ + EntPtr entityPrivate; + + int Chipset; + EntityInfoPtr pEnt; + struct pci_device *PciInfo; + + Bool noAccel; + Bool SWCursor; + CloseScreenProcPtr CloseScreen; + + /* Broken-out options. */ + OptionInfoPtr Options; + + unsigned int SaveGeneration; + + void (*blockHandler)(int, pointer, pointer, pointer); + CreateScreenResourcesProcPtr createScreenResources; + + /* gallium */ + struct drm_api *api; + struct pipe_screen *screen; + struct pipe_context *ctx; + boolean d_depth_bits_last; + boolean ds_depth_bits_last; + + /* exa */ + void *exa; + Bool noEvict; + +#ifdef DRM_MODE_FEATURE_DIRTYFB + DamagePtr damage; +#endif +} modesettingRec, *modesettingPtr; + +#define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate)) + + +/*********************************************************************** + * xorg_exa.c + */ +struct pipe_texture * +xorg_exa_get_texture(PixmapPtr pPixmap); + +unsigned +xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride); + +int +xorg_exa_set_displayed_usage(PixmapPtr pPixmap); + +int +xorg_exa_set_shared_usage(PixmapPtr pPixmap); + +void * +xorg_exa_init(ScrnInfoPtr pScrn); + +void +xorg_exa_close(ScrnInfoPtr pScrn); + + +/*********************************************************************** + * xorg_dri2.c + */ +Bool +driScreenInit(ScreenPtr pScreen); + +void +driCloseScreen(ScreenPtr pScreen); + + +/*********************************************************************** + * xorg_crtc.c + */ +void +crtc_init(ScrnInfoPtr pScrn); + +void +crtc_cursor_destroy(xf86CrtcPtr crtc); + + +/*********************************************************************** + * xorg_output.c + */ +void +output_init(ScrnInfoPtr pScrn); + + +#endif /* _XORG_TRACKER_H_ */ diff --git a/src/gallium/state_trackers/xorg/xorg_winsys.h b/src/gallium/state_trackers/xorg/xorg_winsys.h new file mode 100644 index 0000000000..47ee4b9ffd --- /dev/null +++ b/src/gallium/state_trackers/xorg/xorg_winsys.h @@ -0,0 +1,49 @@ +/* + * 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. + * + * + * Author: Alan Hourihane <alanh@tungstengraphics.com> + * Author: Jakob Bornecrantz <wallbraker@gmail.com> + * + */ + +/* + * File with all the junk needed to personalize the a xorg driver. + */ + +#ifndef _XORG_WINSYS_H_ +#define _XORG_WINSYS_H_ + +#include "xorg-server.h" +#include "xf86.h" +#include "pciaccess.h" + +#ifndef XSERVER_LIBPCIACCESS +#error "libpciaccess needed" +#endif + +void xorg_tracker_set_functions(ScrnInfoPtr scrn); +const OptionInfoRec * xorg_tracker_available_options(int chipid, int busid); + +#endif |