glamor: Move to using shader objects.
This commit is contained in:
parent
fbbdd788cb
commit
f1dbed5456
|
@ -97,12 +97,21 @@ glamor_init(ScreenPtr screen)
|
||||||
|
|
||||||
dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, glamor_priv);
|
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,
|
if (!RegisterBlockAndWakeupHandlers(glamor_block_handler,
|
||||||
glamor_wakeup_handler,
|
glamor_wakeup_handler,
|
||||||
NULL)) {
|
NULL)) {
|
||||||
dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, NULL);
|
goto fail;
|
||||||
xfree(glamor_priv);
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glamor_priv->saved_create_gc = screen->CreateGC;
|
glamor_priv->saved_create_gc = screen->CreateGC;
|
||||||
|
@ -114,9 +123,14 @@ glamor_init(ScreenPtr screen)
|
||||||
glamor_priv->saved_destroy_pixmap = screen->DestroyPixmap;
|
glamor_priv->saved_destroy_pixmap = screen->DestroyPixmap;
|
||||||
screen->DestroyPixmap = glamor_destroy_pixmap;
|
screen->DestroyPixmap = glamor_destroy_pixmap;
|
||||||
|
|
||||||
glewInit();
|
glamor_init_solid_shader(screen);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
xfree(glamor_priv);
|
||||||
|
dixSetPrivate(&screen->devPrivates, glamor_screen_private_key, NULL);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -39,16 +39,7 @@
|
||||||
|
|
||||||
#include "glamor_priv.h"
|
#include "glamor_priv.h"
|
||||||
|
|
||||||
static void
|
Bool
|
||||||
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
|
|
||||||
glamor_set_destination_pixmap(PixmapPtr pixmap)
|
glamor_set_destination_pixmap(PixmapPtr pixmap)
|
||||||
{
|
{
|
||||||
ScreenPtr screen = pixmap->drawable.pScreen;
|
ScreenPtr screen = pixmap->drawable.pScreen;
|
||||||
|
@ -63,37 +54,103 @@ glamor_set_destination_pixmap(PixmapPtr pixmap)
|
||||||
screen_pixmap->drawable.width,
|
screen_pixmap->drawable.width,
|
||||||
screen_pixmap->drawable.height);
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
|
glamor_get_transform_uniform_locations(GLint prog,
|
||||||
unsigned char alu, unsigned long planemask, unsigned long fg_pixel)
|
glamor_transform_uniforms *uniform_locations)
|
||||||
{
|
{
|
||||||
int x1 = x;
|
uniform_locations->x_bias = glGetUniformLocationARB(prog, "x_bias");
|
||||||
int x2 = x + width;
|
uniform_locations->x_scale = glGetUniformLocationARB(prog, "x_scale");
|
||||||
int y1 = y;
|
uniform_locations->y_bias = glGetUniformLocationARB(prog, "y_bias");
|
||||||
int y2 = y + height;
|
uniform_locations->y_scale = glGetUniformLocationARB(prog, "y_scale");
|
||||||
|
}
|
||||||
|
|
||||||
if (!glamor_set_destination_pixmap(pixmap))
|
/* We don't use a full matrix for our transformations because it's
|
||||||
return;
|
* wasteful when all we want is to rescale to NDC and possibly do a flip
|
||||||
glamor_set_color_from_fgpixel(pixmap, fg_pixel);
|
* 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);
|
GLint
|
||||||
glVertex2f(x1, y1);
|
glamor_compile_glsl_prog(GLenum type, const char *source)
|
||||||
glVertex2f(x1, y2);
|
{
|
||||||
glVertex2f(x2, y2);
|
GLint ok;
|
||||||
glVertex2f(x2, y1);
|
GLint prog;
|
||||||
glEnd();
|
|
||||||
|
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
|
void
|
||||||
|
|
|
@ -82,3 +82,89 @@ glamor_fill(DrawablePtr drawable,
|
||||||
break;
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -31,10 +31,22 @@
|
||||||
#include "glamor.h"
|
#include "glamor.h"
|
||||||
#include <GL/glew.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 {
|
typedef struct glamor_screen_private {
|
||||||
CreateGCProcPtr saved_create_gc;
|
CreateGCProcPtr saved_create_gc;
|
||||||
CreatePixmapProcPtr saved_create_pixmap;
|
CreatePixmapProcPtr saved_create_pixmap;
|
||||||
DestroyPixmapProcPtr saved_destroy_pixmap;
|
DestroyPixmapProcPtr saved_destroy_pixmap;
|
||||||
|
|
||||||
|
/* glamor_solid */
|
||||||
|
GLint solid_prog;
|
||||||
|
GLint solid_color_uniform_location;
|
||||||
|
glamor_transform_uniforms solid_transform;
|
||||||
} glamor_screen_private;
|
} glamor_screen_private;
|
||||||
|
|
||||||
extern DevPrivateKey glamor_screen_private_key;
|
extern DevPrivateKey glamor_screen_private_key;
|
||||||
|
@ -50,9 +62,6 @@ PixmapPtr glamor_get_drawable_pixmap(DrawablePtr drawable);
|
||||||
|
|
||||||
/* glamor_core.c */
|
/* glamor_core.c */
|
||||||
Bool glamor_create_gc(GCPtr gc);
|
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,
|
void glamor_stipple(PixmapPtr pixmap, PixmapPtr stipple,
|
||||||
int x, int y, int width, int height,
|
int x, int y, int width, int height,
|
||||||
unsigned char alu, unsigned long planemask,
|
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,
|
int x, int y, int width, int height,
|
||||||
unsigned char alu, unsigned long planemask,
|
unsigned char alu, unsigned long planemask,
|
||||||
int tile_x, int tile_y);
|
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 */
|
/* glamor_fill.c */
|
||||||
void glamor_fill(DrawablePtr drawable,
|
void glamor_fill(DrawablePtr drawable,
|
||||||
|
@ -70,6 +88,9 @@ void glamor_fill(DrawablePtr drawable,
|
||||||
int y,
|
int y,
|
||||||
int width,
|
int width,
|
||||||
int height);
|
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 */
|
/* glamor_fillspans.c */
|
||||||
void glamor_fill_spans(DrawablePtr drawable,
|
void glamor_fill_spans(DrawablePtr drawable,
|
||||||
|
@ -79,4 +100,6 @@ void glamor_fill_spans(DrawablePtr drawable,
|
||||||
int *widths,
|
int *widths,
|
||||||
int sorted);
|
int sorted);
|
||||||
|
|
||||||
|
void glamor_init_solid_shader(ScreenPtr screen);
|
||||||
|
|
||||||
#endif /* GLAMOR_PRIV_H */
|
#endif /* GLAMOR_PRIV_H */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user