glamor: Move to using shader objects.

This commit is contained in:
Eric Anholt 2009-08-20 12:32:53 -07:00 committed by Zhigang Gong
parent fbbdd788cb
commit f1dbed5456
4 changed files with 221 additions and 41 deletions

View File

@ -97,12 +97,21 @@ glamor_init(ScreenPtr screen)
dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, glamor_priv);
glewInit();
if (!GLEW_ARB_shader_objects) {
ErrorF("GL_ARB_shader_objects required\n");
goto fail;
}
if (!GLEW_ARB_vertex_shader) {
ErrorF("GL_ARB_vertex_shader required\n");
goto fail;
}
if (!RegisterBlockAndWakeupHandlers(glamor_block_handler,
glamor_wakeup_handler,
NULL)) {
dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, NULL);
xfree(glamor_priv);
return FALSE;
goto fail;
}
glamor_priv->saved_create_gc = screen->CreateGC;
@ -114,9 +123,14 @@ glamor_init(ScreenPtr screen)
glamor_priv->saved_destroy_pixmap = screen->DestroyPixmap;
screen->DestroyPixmap = glamor_destroy_pixmap;
glewInit();
glamor_init_solid_shader(screen);
return TRUE;
fail:
xfree(glamor_priv);
dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, NULL);
return FALSE;
}
void

View File

@ -39,16 +39,7 @@
#include "glamor_priv.h"
static void
glamor_set_color_from_fgpixel(PixmapPtr pixmap, unsigned long fg_pixel)
{
glColor4ub((fg_pixel >> 16) & 0xff,
(fg_pixel >> 8) & 0xff,
(fg_pixel) & 0xff,
(fg_pixel >> 24) & 0xff);
}
static Bool
Bool
glamor_set_destination_pixmap(PixmapPtr pixmap)
{
ScreenPtr screen = pixmap->drawable.pScreen;
@ -63,37 +54,103 @@ glamor_set_destination_pixmap(PixmapPtr pixmap)
screen_pixmap->drawable.width,
screen_pixmap->drawable.height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, screen_pixmap->drawable.width,
0, screen_pixmap->drawable.height,
-1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
return TRUE;
}
void
glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
unsigned char alu, unsigned long planemask, unsigned long fg_pixel)
glamor_get_transform_uniform_locations(GLint prog,
glamor_transform_uniforms *uniform_locations)
{
int x1 = x;
int x2 = x + width;
int y1 = y;
int y2 = y + height;
uniform_locations->x_bias = glGetUniformLocationARB(prog, "x_bias");
uniform_locations->x_scale = glGetUniformLocationARB(prog, "x_scale");
uniform_locations->y_bias = glGetUniformLocationARB(prog, "y_bias");
uniform_locations->y_scale = glGetUniformLocationARB(prog, "y_scale");
}
if (!glamor_set_destination_pixmap(pixmap))
return;
glamor_set_color_from_fgpixel(pixmap, fg_pixel);
/* We don't use a full matrix for our transformations because it's
* wasteful when all we want is to rescale to NDC and possibly do a flip
* if it's the front buffer.
*/
void
glamor_set_transform_for_pixmap(PixmapPtr pixmap,
glamor_transform_uniforms *uniform_locations)
{
glUniform1fARB(uniform_locations->x_bias, -pixmap->drawable.width / 2.0f);
glUniform1fARB(uniform_locations->x_scale, 2.0f / pixmap->drawable.width);
glUniform1fARB(uniform_locations->y_bias, -pixmap->drawable.height / 2.0f);
glUniform1fARB(uniform_locations->y_scale, -2.0f / pixmap->drawable.height);
}
glBegin(GL_TRIANGLE_FAN);
glVertex2f(x1, y1);
glVertex2f(x1, y2);
glVertex2f(x2, y2);
glVertex2f(x2, y1);
glEnd();
GLint
glamor_compile_glsl_prog(GLenum type, const char *source)
{
GLint ok;
GLint prog;
prog = glCreateShaderObjectARB(type);
glShaderSourceARB(prog, 1, (const GLchar **)&source, NULL);
glCompileShaderARB(prog);
glGetObjectParameterivARB(prog, GL_OBJECT_COMPILE_STATUS_ARB, &ok);
if (!ok) {
GLchar *info;
GLint size;
glGetObjectParameterivARB(prog, GL_OBJECT_INFO_LOG_LENGTH_ARB, &size);
info = malloc(size);
glGetInfoLogARB(prog, size, NULL, info);
ErrorF("Failed to compile %s: %s\n",
type == GL_FRAGMENT_SHADER ? "FS" : "VS",
info);
ErrorF("Program source:\n%s", source);
FatalError("GLSL compile failure\n");
}
return prog;
}
void
glamor_link_glsl_prog(GLint prog)
{
GLint ok;
glLinkProgram(prog);
glGetObjectParameterivARB(prog, GL_OBJECT_LINK_STATUS_ARB, &ok);
if (!ok) {
GLchar *info;
GLint size;
glGetObjectParameterivARB(prog, GL_OBJECT_INFO_LOG_LENGTH_ARB, &size);
info = malloc(size);
glGetInfoLogARB(prog, size, NULL, info);
ErrorF("Failed to link: %s\n",
info);
FatalError("GLSL link failure\n");
}
}
static float ubyte_to_float(uint8_t b)
{
return b / 255.0f;
}
void
glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel,
GLfloat *color)
{
if (pixmap->drawable.depth < 24) {
ErrorF("pixmap with bad depth\n");
color[0] = 1.0;
color[1] = 0.0;
color[2] = 1.0;
color[3] = 1.0;
} else {
color[0] = ubyte_to_float(fg_pixel >> 16);
color[1] = ubyte_to_float(fg_pixel >> 8);
color[2] = ubyte_to_float(fg_pixel >> 0);
color[3] = ubyte_to_float(fg_pixel >> 24);
}
}
void

View File

@ -82,3 +82,89 @@ glamor_fill(DrawablePtr drawable,
break;
}
}
void
glamor_init_solid_shader(ScreenPtr screen)
{
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
const char *solid_vs_only =
"uniform vec4 color;\n"
"uniform float x_bias;\n"
"uniform float x_scale;\n"
"uniform float y_bias;\n"
"uniform float y_scale;\n"
"void main()\n"
"{\n"
" gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n"
" (gl_Vertex.y + y_bias) * y_scale,\n"
" 0,\n"
" 1);\n"
" gl_Color = color;\n"
"}\n";
const char *solid_vs =
"uniform float x_bias;\n"
"uniform float x_scale;\n"
"uniform float y_bias;\n"
"uniform float y_scale;\n"
"void main()\n"
"{\n"
" gl_Position = vec4((gl_Vertex.x + x_bias) * x_scale,\n"
" (gl_Vertex.y + y_bias) * y_scale,\n"
" 0,\n"
" 1);\n"
"}\n";
const char *solid_fs =
"uniform vec4 color;\n"
"void main()\n"
"{\n"
" gl_FragColor = color;\n"
"}\n";
GLint fs_prog, vs_prog;
glamor_priv->solid_prog = glCreateProgramObjectARB();
if (GLEW_ARB_fragment_shader) {
vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, solid_vs);
fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER_ARB, solid_fs);
glAttachObjectARB(glamor_priv->solid_prog, vs_prog);
glAttachObjectARB(glamor_priv->solid_prog, fs_prog);
} else {
vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER_ARB, solid_vs_only);
glAttachObjectARB(glamor_priv->solid_prog, vs_prog);
}
glamor_link_glsl_prog(glamor_priv->solid_prog);
glamor_priv->solid_color_uniform_location =
glGetUniformLocationARB(glamor_priv->solid_prog, "color");
glamor_get_transform_uniform_locations(glamor_priv->solid_prog,
&glamor_priv->solid_transform);
}
void
glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
unsigned char alu, unsigned long planemask, unsigned long fg_pixel)
{
ScreenPtr screen = pixmap->drawable.pScreen;
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
int x1 = x;
int x2 = x + width;
int y1 = y;
int y2 = y + height;
GLfloat color[4];
if (!glamor_set_destination_pixmap(pixmap))
return;
glUseProgramObjectARB(glamor_priv->solid_prog);
glamor_get_color_4f_from_pixel(pixmap, fg_pixel, color);
glUniform4fvARB(glamor_priv->solid_color_uniform_location, 1, color);
glamor_set_transform_for_pixmap(pixmap, &glamor_priv->solid_transform);
glBegin(GL_TRIANGLE_FAN);
glVertex2f(x1, y1);
glVertex2f(x1, y2);
glVertex2f(x2, y2);
glVertex2f(x2, y1);
glEnd();
glUseProgramObjectARB(0);
}

View File

@ -31,10 +31,22 @@
#include "glamor.h"
#include <GL/glew.h>
typedef struct glamor_transform_uniforms {
GLint x_bias;
GLint x_scale;
GLint y_bias;
GLint y_scale;
} glamor_transform_uniforms;
typedef struct glamor_screen_private {
CreateGCProcPtr saved_create_gc;
CreatePixmapProcPtr saved_create_pixmap;
DestroyPixmapProcPtr saved_destroy_pixmap;
/* glamor_solid */
GLint solid_prog;
GLint solid_color_uniform_location;
glamor_transform_uniforms solid_transform;
} glamor_screen_private;
extern DevPrivateKey glamor_screen_private_key;
@ -50,9 +62,6 @@ PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable);
/* glamor_core.c */
Bool glamor_create_gc(GCPtr gc);
void glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
unsigned char alu, unsigned long planemask,
unsigned long fg_pixel);
void glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
int x, int y, int width, int height,
unsigned char alu, unsigned long planemask,
@ -62,6 +71,15 @@ void glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
int x, int y, int width, int height,
unsigned char alu, unsigned long planemask,
int tile_x, int tile_y);
GLint glamor_compile_glsl_prog(GLenum type, const char *source);
void glamor_link_glsl_prog(GLint prog);
void glamor_get_color_4f_from_pixel(PixmapPtr pixmap, unsigned long fg_pixel,
GLfloat *color);
Bool glamor_set_destination_pixmap(PixmapPtr pixmap);
void glamor_get_transform_uniform_locations(GLint prog,
glamor_transform_uniforms *uniform_locations);
void glamor_set_transform_for_pixmap(PixmapPtr pixmap,
glamor_transform_uniforms *uniform_locations);
/* glamor_fill.c */
void glamor_fill(DrawablePtr drawable,
@ -70,6 +88,9 @@ void glamor_fill(DrawablePtr drawable,
int y,
int width,
int height);
void glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
unsigned char alu, unsigned long planemask,
unsigned long fg_pixel);
/* glamor_fillspans.c */
void glamor_fill_spans(DrawablePtr drawable,
@ -79,4 +100,6 @@ void glamor_fill_spans(DrawablePtr drawable,
int *widths,
int sorted);
void glamor_init_solid_shader(ScreenPtr screen);
#endif /* GLAMOR_PRIV_H */