Commit c7e79d6a authored by Zhigang Gong's avatar Zhigang Gong Committed by Eric Anholt

glamor-fbo-pool: Implement fbo cache mechanism.

We classify the cache according to the texture's format/width/height.
As openGL doesn't allow us to change a texture's format/width/height
after the internal texture object is already allocated, we can't
just calculate the size and then according ths size to put the
fbo to an bucket which is just like SNA does. We can only put
the fbo to the corresponding format/width/height bucket.

This commit only support the exact size match. The following patch
will remove this restriction, just need to handle the repeat/tile
case when the size is not exactly match.

Should use fls instead of ffs when decide the width/height bucket,
thanks for Chris to point this out.
Signed-off-by: default avatarZhigang Gong <zhigang.gong@linux.intel.com>
parent 2ff41008
......@@ -210,8 +210,10 @@ glamor_block_handler(ScreenPtr screen)
glamor_get_screen_private(screen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
glamor_priv->tick++;
dispatch->glFlush();
dispatch->glFinish();
glamor_fbo_expire(glamor_priv);
}
static void
......@@ -381,6 +383,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
ps->DestroyPicture = glamor_destroy_picture;
glamor_init_composite_shaders(screen);
#endif
glamor_init_pixmap_fbo(screen);
glamor_init_solid_shader(screen);
glamor_init_tile_shader(screen);
glamor_init_putimage_shaders(screen);
......@@ -392,6 +395,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
#else
glamor_priv->gl_flavor = GLAMOR_GL_DESKTOP;
#endif
glamor_priv->flags = flags;
return TRUE;
......@@ -402,26 +406,54 @@ glamor_init(ScreenPtr screen, unsigned int flags)
return FALSE;
}
static void
glamor_release_screen_priv(ScreenPtr screen)
{
glamor_screen_private *glamor_priv;
glamor_priv = glamor_get_screen_private(screen);
#ifdef RENDER
glamor_fini_composite_shaders(screen);
#endif
glamor_fini_pixmap_fbo(screen);
glamor_fini_solid_shader(screen);
glamor_fini_tile_shader(screen);
glamor_fini_putimage_shaders(screen);
glamor_fini_finish_access_shaders(screen);
glamor_pixmap_fini(screen);
free(glamor_priv);
dixSetPrivate(&screen->devPrivates, glamor_screen_private_key,
NULL);
}
Bool
glamor_close_screen(int idx, ScreenPtr screen)
{
glamor_screen_private *glamor_priv =
glamor_get_screen_private(screen);
glamor_screen_private *glamor_priv;
int flags;
glamor_priv = glamor_get_screen_private(screen);
flags = glamor_priv->flags;
#ifdef RENDER
PictureScreenPtr ps = GetPictureScreenIfSet(screen);
#endif
glamor_glyphs_fini(screen);
screen->CloseScreen = glamor_priv->saved_procs.close_screen;
screen->CreateGC = glamor_priv->saved_procs.create_gc;
screen->CreatePixmap = glamor_priv->saved_procs.create_pixmap;
screen->DestroyPixmap = glamor_priv->saved_procs.destroy_pixmap;
screen->GetSpans = glamor_priv->saved_procs.get_spans;
screen->ChangeWindowAttributes =
glamor_priv->saved_procs.change_window_attributes;
screen->CopyWindow = glamor_priv->saved_procs.copy_window;
screen->BitmapToRegion = glamor_priv->saved_procs.bitmap_to_region;
if (flags & GLAMOR_USE_SCREEN) {
screen->CloseScreen = glamor_priv->saved_procs.close_screen;
screen->CreateGC = glamor_priv->saved_procs.create_gc;
screen->CreatePixmap = glamor_priv->saved_procs.create_pixmap;
screen->DestroyPixmap = glamor_priv->saved_procs.destroy_pixmap;
screen->GetSpans = glamor_priv->saved_procs.get_spans;
screen->ChangeWindowAttributes =
glamor_priv->saved_procs.change_window_attributes;
screen->CopyWindow = glamor_priv->saved_procs.copy_window;
screen->BitmapToRegion = glamor_priv->saved_procs.bitmap_to_region;
}
#ifdef RENDER
if (ps) {
if (ps && (flags & GLAMOR_USE_PICTURE_SCREEN)) {
ps->Composite = glamor_priv->saved_procs.composite;
ps->Trapezoids = glamor_priv->saved_procs.trapezoids;
ps->Glyphs = glamor_priv->saved_procs.glyphs;
......@@ -429,13 +461,15 @@ glamor_close_screen(int idx, ScreenPtr screen)
ps->CreatePicture = glamor_priv->saved_procs.create_picture;
}
#endif
if (glamor_priv->vb)
free(glamor_priv->vb);
free(glamor_priv);
return screen->CloseScreen(idx, screen);
glamor_release_screen_priv(screen);
if (flags & GLAMOR_USE_SCREEN)
return screen->CloseScreen(idx, screen);
else
return TRUE;
}
void
glamor_fini(ScreenPtr screen)
{
......
......@@ -42,7 +42,7 @@
#endif /* GLAMOR_H */
/* @GLAMOR_INVERTED_Y_AXIS:
* set 1 means the GL env's origin (0,0) is at top-left.
* set 1 means the GL env's origin (0,0) is at top-left.
* EGL/DRM platform is an example need to set this bit.
* glx platform's origin is at bottom-left thus need to
* clear this bit.*/
......@@ -54,7 +54,7 @@
* create/destroy pixmap and handle the gc ops. need to
* set this bit. Standalone glamor DDX driver need to set
* this bit.
* Otherwise, need to clear this bit, as the intel video
* Otherwise, need to clear this bit, as the intel video
* driver with glamor enabled.
* */
#define GLAMOR_USE_SCREEN 2
......@@ -97,12 +97,24 @@ typedef enum glamor_pixmap_type {
*
* This function initializes necessary internal data structure
* for glamor. And before calling into this function, the OpenGL
* environment should be ready. Should be called before any real
* glamor rendering or texture allocation functions.
* environment should be ready. Should be called before any real
* glamor rendering or texture allocation functions.
*/
extern _X_EXPORT Bool glamor_init(ScreenPtr screen, unsigned int flags);
extern _X_EXPORT void glamor_fini(ScreenPtr screen);
/* This function is used to free the glamor private screen's
* resources. If the DDX driver is not set GLAMOR_USE_SCREEN,
* then, DDX need to call this function at proper stage, if
* it is the xorg DDX driver,then it should be called at free
* screen stage not the close screen stage. The reason is after
* call to this function, the xorg DDX may need to destroy the
* screen pixmap which must be a glamor pixmap and requires
* the internal data structure still exist at that time.
* Otherwise, the glamor internal structure will not be freed.*/
extern _X_EXPORT Bool glamor_close_screen(int idx, ScreenPtr screen);
/* Let glamor to know the screen's fbo. The low level
* driver should already assign a tex
* to this pixmap through the set_pixmap_texture. */
......@@ -133,7 +145,7 @@ extern _X_EXPORT PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h,
* @scrn: Current screen info pointer.
* @fd: Current drm fd.
*
* This function creates and intialize EGL contexts.
* This function creates and intialize EGL contexts.
* Should be called from DDX's preInit function.
* Return TRUE if success, otherwise return FALSE.
* */
......@@ -165,7 +177,7 @@ extern _X_EXPORT Bool glamor_egl_create_textured_screen(ScreenPtr screen,
/*
* @glamor_egl_create_textured_pixmap: Try to create a textured pixmap from
* a BO handle.
*
*
* @pixmap: The pixmap need to be processed.
* @handle: The BO's handle attached to this pixmap at DDX layer.
* @stride: Stride in bytes for this pixmap.
......@@ -188,24 +200,24 @@ extern _X_EXPORT void glamor_egl_free_screen(int scrnIndex, int flags);
extern _X_EXPORT int glamor_create_gc(GCPtr gc);
extern _X_EXPORT void glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable);
/* Glamor rendering/drawing functions with XXX_nf.
/* Glamor rendering/drawing functions with XXX_nf.
* nf means no fallback within glamor internal if possible. If glamor
* fail to accelerate the operation, glamor will return a false, and the
* caller need to implement fallback method. Return a true means the
* rendering request get done successfully. */
extern _X_EXPORT Bool glamor_fill_spans_nf(DrawablePtr drawable,
GCPtr gc,
int n, DDXPointPtr points,
int n, DDXPointPtr points,
int *widths, int sorted);
extern _X_EXPORT Bool glamor_poly_fill_rect_nf(DrawablePtr drawable,
GCPtr gc,
int nrect,
GCPtr gc,
int nrect,
xRectangle * prect);
extern _X_EXPORT Bool glamor_put_image_nf(DrawablePtr drawable,
extern _X_EXPORT Bool glamor_put_image_nf(DrawablePtr drawable,
GCPtr gc, int depth, int x, int y,
int w, int h, int left_pad,
int w, int h, int left_pad,
int image_format, char *bits);
extern _X_EXPORT Bool glamor_copy_n_to_n_nf(DrawablePtr src,
......@@ -216,7 +228,7 @@ extern _X_EXPORT Bool glamor_copy_n_to_n_nf(DrawablePtr src,
int dx,
int dy,
Bool reverse,
Bool upsidedown, Pixel bitplane,
Bool upsidedown, Pixel bitplane,
void *closure);
extern _X_EXPORT Bool glamor_composite_nf(CARD8 op,
......@@ -227,12 +239,12 @@ extern _X_EXPORT Bool glamor_composite_nf(CARD8 op,
INT16 y_source,
INT16 x_mask,
INT16 y_mask,
INT16 x_dest, INT16 y_dest,
INT16 x_dest, INT16 y_dest,
CARD16 width, CARD16 height);
extern _X_EXPORT Bool glamor_trapezoids_nf(CARD8 op,
PicturePtr src, PicturePtr dst,
PictFormatPtr mask_format,
PictFormatPtr mask_format,
INT16 x_src, INT16 y_src,
int ntrap, xTrapezoid * traps);
......@@ -241,14 +253,14 @@ extern _X_EXPORT Bool glamor_glyphs_nf(CARD8 op,
PicturePtr dst,
PictFormatPtr mask_format,
INT16 x_src,
INT16 y_src, int nlist,
INT16 y_src, int nlist,
GlyphListPtr list, GlyphPtr * glyphs);
extern _X_EXPORT Bool glamor_triangles_nf(CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc, INT16 ySrc,
INT16 xSrc, INT16 ySrc,
int ntris, xTriangle * tris);
......@@ -270,7 +282,7 @@ extern _X_EXPORT Bool glamor_get_image_nf(DrawablePtr pDrawable, int x, int y, i
unsigned int format, unsigned long planeMask, char *d);
extern _X_EXPORT Bool glamor_add_traps_nf(PicturePtr pPicture,
INT16 x_off,
INT16 x_off,
INT16 y_off, int ntrap, xTrap * traps);
extern _X_EXPORT Bool glamor_copy_plane_nf(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
......
......@@ -114,9 +114,8 @@ glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
void
glamor_init_finish_access_shaders(ScreenPtr screen)
{
glamor_screen_private *glamor_priv =
glamor_get_screen_private(screen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
glamor_screen_private *glamor_priv;
glamor_gl_dispatch *dispatch;
const char *vs_source =
"attribute vec4 v_position;\n"
"attribute vec4 v_texcoord0;\n"
......@@ -174,25 +173,23 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
GLint fs_prog, vs_prog, avs_prog, set_alpha_prog;
GLint sampler_uniform_location;
glamor_priv = glamor_get_screen_private(screen);
dispatch = &glamor_priv->dispatch;
glamor_priv->finish_access_prog[0] = dispatch->glCreateProgram();
glamor_priv->finish_access_prog[1] = dispatch->glCreateProgram();
vs_prog =
glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER,
vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER,
vs_source);
fs_prog =
glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
fs_source);
dispatch->glAttachShader(glamor_priv->finish_access_prog[0],
vs_prog);
dispatch->glAttachShader(glamor_priv->finish_access_prog[0],
fs_prog);
avs_prog =
glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER,
avs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER,
vs_source);
set_alpha_prog =
glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
set_alpha_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
set_alpha_source);
dispatch->glAttachShader(glamor_priv->finish_access_prog[1],
avs_prog);
......@@ -254,6 +251,20 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
}
void
glamor_fini_finish_access_shaders(ScreenPtr screen)
{
glamor_screen_private *glamor_priv;
glamor_gl_dispatch *dispatch;
glamor_priv = glamor_get_screen_private(screen);
dispatch = &glamor_priv->dispatch;
dispatch->glDeleteProgram(glamor_priv->finish_access_prog[0]);
dispatch->glDeleteProgram(glamor_priv->finish_access_prog[1]);
}
void
glamor_finish_access(DrawablePtr drawable, glamor_access_t access_mode)
{
......
......@@ -77,7 +77,6 @@ glamor_identify(int flags)
struct glamor_egl_screen_private {
EGLDisplay display;
EGLContext context;
EGLImageKHR root;
EGLint major, minor;
CreateScreenResourcesProcPtr CreateScreenResources;
......@@ -250,10 +249,6 @@ glamor_egl_close_screen(ScreenPtr screen)
glamor_egl_get_screen_private(scrn);
glamor_fini(screen);
eglDestroyImageKHR(glamor_egl->display, glamor_egl->root);
glamor_egl->root = EGL_NO_IMAGE_KHR;
return TRUE;
}
......@@ -402,6 +397,8 @@ glamor_egl_free_screen(int scrnIndex, int flags)
}
free(glamor_egl);
}
glamor_close_screen(scrn->scrnIndex, scrn->pScreen);
}
Bool
......
......@@ -6,6 +6,132 @@
#include "glamor_priv.h"
#define GLAMOR_CACHE_EXPIRE_MAX 1000
#define GLAMOR_CACHE_DEFAULT 0
#define GLAMOR_CACHE_EXACT_SIZE 1
/* Loop from the tail to the head. */
#define list_for_each_entry_reverse(pos, head, member) \
for (pos = __container_of((head)->prev, pos, member); \
&pos->member != (head); \
pos = __container_of(pos->member.prev, pos, member))
#define list_for_each_entry_safe_reverse(pos, tmp, head, member) \
for (pos = __container_of((head)->prev, pos, member), \
tmp = __container_of(pos->member.prev, pos, member); \
&pos->member != (head); \
pos = tmp, tmp = __container_of(pos->member.prev, tmp, member))
#ifdef __i386__
static inline unsigned long __fls(unsigned long x)
{
asm("bsr %1,%0"
: "=r" (x)
: "rm" (x));
return x;
}
#else
static inline unsigned long __fls(unsigned long x)
{
int n;
if (x == 0) return(0);
n = 0;
if (x <= 0x0000FFFF) {n = n +16; x = x <<16;}
if (x <= 0x00FFFFFF) {n = n + 8; x = x << 8;}
if (x <= 0x0FFFFFFF) {n = n + 4; x = x << 4;}
if (x <= 0x3FFFFFFF) {n = n + 2; x = x << 2;}
if (x <= 0x7FFFFFFF) {n = n + 1;}
return 31 - n;
}
#endif
inline static int cache_wbucket(int size)
{
int order = __fls(size / 256);
if (order >= CACHE_BUCKET_WCOUNT)
order = CACHE_BUCKET_WCOUNT - 1;
return order;
}
inline static int cache_hbucket(int size)
{
int order = __fls(size / 256);
if (order >= CACHE_BUCKET_HCOUNT)
order = CACHE_BUCKET_HCOUNT - 1;
return order;
}
inline static int cache_format(GLenum format)
{
switch (format) {
#if 0
case GL_ALPHA:
return 1;
#endif
case GL_RGBA:
default:
return 0;
}
}
glamor_pixmap_fbo *
glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
int w, int h, GLenum format, int flag)
{
struct list *cache;
glamor_pixmap_fbo *fbo_entry;
int size;
cache = &glamor_priv->fbo_cache[cache_format(format)]
[cache_wbucket(w)]
[cache_hbucket(h)];
if (flag != GLAMOR_CACHE_EXACT_SIZE) {
list_for_each_entry(fbo_entry, cache, list) {
if (fbo_entry->width == w && fbo_entry->height == h) {
DEBUGF("Request w %d h %d \n", w, h);
DEBUGF("got cache entry %p w %d h %d fbo %d tex %d\n",
fbo_entry, fbo_entry->width, fbo_entry->height,
fbo_entry->fb, fbo_entry->tex);
list_del(&fbo_entry->list);
return fbo_entry;
}
}
}
else {
list_for_each_entry(fbo_entry, cache, list) {
if (fbo_entry->width == w && fbo_entry->height == h) {
DEBUGF("Request w %d h %d \n", w, h);
DEBUGF("got cache entry %p w %d h %d fbo %d tex %d\n",
fbo_entry, fbo_entry->width, fbo_entry->height,
fbo_entry->fb, fbo_entry->tex);
list_del(&fbo_entry->list);
return fbo_entry;
}
}
}
return NULL;
}
void
glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
{
struct list *cache;
cache = &fbo->glamor_priv->fbo_cache[cache_format(fbo->format)]
[cache_wbucket(fbo->width)]
[cache_hbucket(fbo->height)];
DEBUGF("Put cache entry %p to cache %p w %d h %d format %x fbo %d tex %d \n", fbo, cache,
fbo->width, fbo->height, fbo->format, fbo->fb, fbo->tex);
list_add(&fbo->list, cache);
fbo->expire = fbo->glamor_priv->tick + GLAMOR_CACHE_EXPIRE_MAX;
}
glamor_pixmap_fbo *
glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
int w, int h, int depth, GLint tex, int flag)
......@@ -18,6 +144,7 @@ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
if (fbo == NULL)
return NULL;
list_init(&fbo->list);
gl_iformat_for_depth(depth, &format);
fbo->tex = tex;
......@@ -31,13 +158,11 @@ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
return fbo;
}
/* Make sure already detached from any pixmap. */
void
glamor_destroy_fbo(glamor_pixmap_fbo *fbo)
static void
glamor_purge_fbo(glamor_pixmap_fbo *fbo)
{
glamor_gl_dispatch *dispatch = &fbo->glamor_priv->dispatch;
DEBUGF("Destroy fbo %p tex %d fb %d \n", fbo, fbo->tex, fbo->fb);
DEBUGF("Purge fbo %p tex %d fb %d \n", fbo, fbo->tex, fbo->fb);
if (fbo->fb)
dispatch->glDeleteFramebuffers(1, &fbo->fb);
if (fbo->tex)
......@@ -48,6 +173,79 @@ glamor_destroy_fbo(glamor_pixmap_fbo *fbo)
free(fbo);
}
void
glamor_fbo_expire(glamor_screen_private *glamor_priv)
{
struct list *cache;
glamor_pixmap_fbo *fbo_entry, *tmp;
int i,j,k;
int empty_cache = TRUE;
for(i = 0; i < CACHE_FORMAT_COUNT; i++)
for(j = 0; j < CACHE_BUCKET_WCOUNT; j++)
for(k = 0; k < CACHE_BUCKET_HCOUNT; k++) {
cache = &glamor_priv->fbo_cache[i][j][k];
list_for_each_entry_safe_reverse(fbo_entry, tmp, cache, list) {
if (GLAMOR_TICK_AFTER(fbo_entry->expire, glamor_priv->tick)) {
empty_cache = FALSE;
break;
}
list_del(&fbo_entry->list);
DEBUGF("cache %p fbo %p expired %d current %d \n", cache, fbo_entry,
fbo_entry->expire, glamor_priv->tick);
glamor_purge_fbo(fbo_entry);
}
}
}
void
glamor_init_pixmap_fbo(ScreenPtr screen)
{
glamor_screen_private *glamor_priv;
int i,j,k;
glamor_priv = glamor_get_screen_private(screen);
for(i = 0; i < CACHE_FORMAT_COUNT; i++)
for(j = 0; j < CACHE_BUCKET_WCOUNT; j++)
for(k = 0; k < CACHE_BUCKET_HCOUNT; k++)
{
list_init(&glamor_priv->fbo_cache[i][j][k]);
}
}
void
glamor_fini_pixmap_fbo(ScreenPtr screen)
{
struct list *cache;
glamor_screen_private *glamor_priv;
glamor_pixmap_fbo *fbo_entry, *tmp;
int i,j,k;
glamor_priv = glamor_get_screen_private(screen);
for(i = 0; i < CACHE_FORMAT_COUNT; i++)
for(j = 0; j < CACHE_BUCKET_WCOUNT; j++)
for(k = 0; k < CACHE_BUCKET_HCOUNT; k++)
{
cache = &glamor_priv->fbo_cache[i][j][k];
list_for_each_entry_safe_reverse(fbo_entry, tmp, cache, list) {
list_del(&fbo_entry->list);
glamor_purge_fbo(fbo_entry);
}
}
}
void
glamor_destroy_fbo(glamor_pixmap_fbo *fbo)
{
glamor_gl_dispatch *dispatch = &fbo->glamor_priv->dispatch;
list_del(&fbo->list);
glamor_pixmap_fbo_cache_put(fbo);
}
glamor_pixmap_fbo *
glamor_create_fbo(glamor_screen_private *glamor_priv,
int w, int h, int depth, int flag)
......@@ -56,8 +254,19 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
glamor_pixmap_fbo *fbo;
GLenum format;
GLint tex;
int cache_flag;
if (flag == GLAMOR_CREATE_PIXMAP_FIXUP)
cache_flag = GLAMOR_CACHE_EXACT_SIZE;
else
cache_flag = 0;
gl_iformat_for_depth(depth, &format);
fbo = glamor_pixmap_fbo_cache_get(glamor_priv, w, h,
format, GLAMOR_CACHE_EXACT_SIZE);
if (fbo)
return fbo;
dispatch = &glamor_priv->dispatch;
dispatch->glGenTextures(1, &tex);
dispatch->glBindTexture(GL_TEXTURE_2D, tex);
......@@ -69,8 +278,8 @@ glamor_create_fbo(glamor_screen_private *glamor_priv,
GL_UNSIGNED_BYTE, NULL);
fbo = glamor_create_fbo_from_tex(glamor_priv, w, h, depth, tex, flag);
DEBUGF("Creat fbo %p tex %d width %d height %d \n", fbo, tex, w, h);
DEBUGF("Creat new fbo %p tex %d width %d height %d \n", fbo, tex, w, h);
return fbo;
}
......
......@@ -101,9 +101,8 @@ glamor_fill(DrawablePtr drawable,
void
glamor_init_solid_shader(ScreenPtr screen)
{
glamor_screen_private *glamor_priv =
glamor_get_screen_private(screen);
glamor_gl_dispatch *dispatch = &glamor_priv->dispatch;
glamor_screen_private *glamor_priv;
glamor_gl_dispatch *dispatch;
const char *solid_vs =
"attribute vec4 v_position;"
"void main()\n" "{\n" " gl_Position = v_position;\n"
......@@ -113,12 +112,12 @@ glamor_init_solid_shader(ScreenPtr screen)
"void main()\n" "{\n" " gl_FragColor = color;\n" "}\n";
GLint fs_prog, vs_prog;
glamor_priv = glamor_get_screen_private(screen);
dispatch = &glamor_priv->dispatch;
glamor_priv->solid_prog = dispatch->glCreateProgram();
vs_prog =
glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, solid_vs);
fs_prog =
glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
solid_fs);
vs_prog = glamor_compile_glsl_prog(dispatch, GL_VERTEX_SHADER, solid_vs);
fs_prog = glamor_compile_glsl_prog(dispatch, GL_FRAGMENT_SHADER,
solid_fs);
dispatch->glAttachShader(glamor_priv->solid_prog, vs_prog);
dispatch->glAttachShader(glamor_priv->solid_prog, fs_prog);
......@@ -131,6 +130,17 @@ glamor_init_solid_shader(ScreenPtr screen)
"color");
}
void
glamor_fini_solid_shader(ScreenPtr screen)
{
glamor_screen_private *glamor_priv;
glamor_gl_dispatch *dispatch;
glamor_priv = glamor_get_screen_private(screen);
dispatch = &glamor_priv->dispatch;
dispatch->glDeleteProgram(glamor_priv->solid_prog);
}
Bool
glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
unsigned char alu, unsigned long planemask,
......
......@@ -61,6 +61,7 @@ glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
INIT_FUNC(dispatch, glUniform4f, get_proc_address);
INIT_FUNC(dispatch, glUniform4fv, get_proc_address);
INIT_FUNC(dispatch, glCreateProgram, get_proc_address);
INIT_FUNC(dispatch, glDeleteProgram, get_proc_address);
INIT_FUNC(dispatch, glCreateShader, get_proc_address);
INIT_FUNC(dispatch, glCompileShader, get_proc_address);
INIT_FUNC(dispatch, glAttachShader, get_proc_address);
......
......@@ -97,6 +97,7 @@ typedef struct glamor_gl_dispatch {
void (*glUniform4fv) (GLint location, GLsizei count,
const GLfloat * value);
GLuint(*glCreateProgram) (void);
GLuint(*glDeleteProgram) (GLuint);
GLuint(*glCreateShader) (GLenum type);
void (*glCompileShader) (GLuint shader);
void (*glAttachShader) (GLuint program, GLuint shader);
......
......@@ -63,11 +63,17 @@ glamor_pixmap_validate_function_t pixmap_validate_funcs[] = {
void
glamor_pixmap_init(ScreenPtr screen)
{
glamor_screen_private *glamor_priv =
glamor_get_screen_private(screen);
glamor_screen_private *glamor_priv;
glamor_priv = glamor_get_screen_private(screen);
glamor_priv->pixmap_validate_funcs = pixmap_validate_funcs;
}
void
glamor_pixmap_fini(ScreenPtr screen)
{
}
void
glamor_validate_pixmap(PixmapPtr pixmap)
{
......