glamor: Extract the streamed vertex data code used by Render.
We should be uploading any vertex data using this kind of upload style, since it saves a bunch of extra copies of our vertex data. v2: - Add a simple comment about what the function does. - Use get_vbo_space()'s return in trapezoids, instead of dereffing glamor_priv->vb (by Markus Wick). - Fix the double-unmapping by moving put_vbo_space() outside of flush_composite_rects(). - Remove the rest of the composite_vbo_offset usage, and just always use get_vbo_space()'s return value. v3: - Fix failure to put_vbo_space in traps when no prims were generated. - Unbind the VBO from put_vbo_space(). Keeps callers from forgetting to do so. v4: - Split out some changes into the previous 3 commits while trying to track down a regression. - Fix regression due to rebase fail where glamor_priv->vbo_offset wasn't incremented. v5: - Fix GLES2 VBO sizing. - Add a comment about resize behavior. - Move glamor_vbo.c init code to glamor_vbo.c from glamor_render.c. (Derived from Markus's changes, but the GLES2 fix dropped almost all of the code in the functions). v6: - Drop the initial BufferData on GLES2 (it happens at put() time). - Don't forget to set vbo_offset to the size on GLES2. - Use char * instead of void * in the cast to return the vbo_offset. - Resize the default FBO to 512kb, to be similar to previous behavior. +1.66124% +/- 0.284223% (n=679) on aa10text. Signed-off-by: Eric Anholt <eric@anholt.net> Reviewed-by: Markus Wick <markus at selfnet.de>
This commit is contained in:
parent
ffc8423077
commit
d310d566b1
|
@ -34,6 +34,7 @@ libglamor_la_SOURCES = \
|
||||||
glamor_pixmap.c\
|
glamor_pixmap.c\
|
||||||
glamor_largepixmap.c\
|
glamor_largepixmap.c\
|
||||||
glamor_picture.c\
|
glamor_picture.c\
|
||||||
|
glamor_vbo.c \
|
||||||
glamor_window.c\
|
glamor_window.c\
|
||||||
glamor_fbo.c\
|
glamor_fbo.c\
|
||||||
glamor_compositerects.c\
|
glamor_compositerects.c\
|
||||||
|
|
|
@ -439,6 +439,7 @@ glamor_init(ScreenPtr screen, unsigned int flags)
|
||||||
ps->DestroyPicture = glamor_destroy_picture;
|
ps->DestroyPicture = glamor_destroy_picture;
|
||||||
glamor_init_composite_shaders(screen);
|
glamor_init_composite_shaders(screen);
|
||||||
#endif
|
#endif
|
||||||
|
glamor_init_vbo(screen);
|
||||||
glamor_init_pixmap_fbo(screen);
|
glamor_init_pixmap_fbo(screen);
|
||||||
glamor_init_solid_shader(screen);
|
glamor_init_solid_shader(screen);
|
||||||
glamor_init_tile_shader(screen);
|
glamor_init_tile_shader(screen);
|
||||||
|
@ -478,6 +479,7 @@ glamor_release_screen_priv(ScreenPtr screen)
|
||||||
#ifdef RENDER
|
#ifdef RENDER
|
||||||
glamor_fini_composite_shaders(screen);
|
glamor_fini_composite_shaders(screen);
|
||||||
#endif
|
#endif
|
||||||
|
glamor_fini_vbo(screen);
|
||||||
glamor_fini_pixmap_fbo(screen);
|
glamor_fini_pixmap_fbo(screen);
|
||||||
glamor_fini_solid_shader(screen);
|
glamor_fini_solid_shader(screen);
|
||||||
glamor_fini_tile_shader(screen);
|
glamor_fini_tile_shader(screen);
|
||||||
|
|
|
@ -324,6 +324,7 @@ extern _X_EXPORT int glamor_create_gc(GCPtr gc);
|
||||||
|
|
||||||
extern _X_EXPORT void glamor_validate_gc(GCPtr gc, unsigned long changes,
|
extern _X_EXPORT void glamor_validate_gc(GCPtr gc, unsigned long changes,
|
||||||
DrawablePtr drawable);
|
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
|
* nf means no fallback within glamor internal if possible. If glamor
|
||||||
* fail to accelerate the operation, glamor will return a false, and the
|
* fail to accelerate the operation, glamor will return a false, and the
|
||||||
|
|
|
@ -220,8 +220,15 @@ typedef struct glamor_screen_private {
|
||||||
|
|
||||||
/* vertext/elment_index buffer object for render */
|
/* vertext/elment_index buffer object for render */
|
||||||
GLuint vbo, ebo;
|
GLuint vbo, ebo;
|
||||||
|
/** Next offset within the VBO that glamor_get_vbo_space() will use. */
|
||||||
int vbo_offset;
|
int vbo_offset;
|
||||||
int vbo_size;
|
int vbo_size;
|
||||||
|
/**
|
||||||
|
* Pointer to glamor_get_vbo_space()'s current VBO mapping.
|
||||||
|
*
|
||||||
|
* Note that this is not necessarily equal to the pointer returned
|
||||||
|
* by glamor_get_vbo_space(), so it can't be used in place of that.
|
||||||
|
*/
|
||||||
char *vb;
|
char *vb;
|
||||||
int vb_stride;
|
int vb_stride;
|
||||||
Bool has_source_coords, has_mask_coords;
|
Bool has_source_coords, has_mask_coords;
|
||||||
|
@ -744,6 +751,17 @@ void glamor_triangles(CARD8 op,
|
||||||
void glamor_pixmap_init(ScreenPtr screen);
|
void glamor_pixmap_init(ScreenPtr screen);
|
||||||
void glamor_pixmap_fini(ScreenPtr screen);
|
void glamor_pixmap_fini(ScreenPtr screen);
|
||||||
|
|
||||||
|
/* glamor_vbo.c */
|
||||||
|
|
||||||
|
void glamor_init_vbo(ScreenPtr screen);
|
||||||
|
void glamor_fini_vbo(ScreenPtr screen);
|
||||||
|
|
||||||
|
void *
|
||||||
|
glamor_get_vbo_space(ScreenPtr screen, unsigned size, char **vbo_offset);
|
||||||
|
|
||||||
|
void
|
||||||
|
glamor_put_vbo_space(ScreenPtr screen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Download a pixmap's texture to cpu memory. If success,
|
* Download a pixmap's texture to cpu memory. If success,
|
||||||
* One copy of current pixmap's texture will be put into
|
* One copy of current pixmap's texture will be put into
|
||||||
|
|
|
@ -403,12 +403,10 @@ glamor_init_composite_shaders(ScreenPtr screen)
|
||||||
{
|
{
|
||||||
glamor_screen_private *glamor_priv;
|
glamor_screen_private *glamor_priv;
|
||||||
unsigned short *eb;
|
unsigned short *eb;
|
||||||
float *vb = NULL;
|
|
||||||
int eb_size;
|
int eb_size;
|
||||||
|
|
||||||
glamor_priv = glamor_get_screen_private(screen);
|
glamor_priv = glamor_get_screen_private(screen);
|
||||||
glamor_get_context(glamor_priv);
|
glamor_get_context(glamor_priv);
|
||||||
glGenBuffers(1, &glamor_priv->vbo);
|
|
||||||
glGenBuffers(1, &glamor_priv->ebo);
|
glGenBuffers(1, &glamor_priv->ebo);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
|
||||||
|
|
||||||
|
@ -419,9 +417,6 @@ glamor_init_composite_shaders(ScreenPtr screen)
|
||||||
eb = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
|
eb = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
vb = malloc(GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(float) * 2);
|
|
||||||
if (vb == NULL)
|
|
||||||
FatalError("Failed to allocate vb memory.\n");
|
|
||||||
eb = malloc(eb_size);
|
eb = malloc(eb_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,14 +433,7 @@ glamor_init_composite_shaders(ScreenPtr screen)
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, eb_size, eb, GL_STATIC_DRAW);
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, eb_size, eb, GL_STATIC_DRAW);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER,
|
|
||||||
GLAMOR_COMPOSITE_VBO_VERT_CNT * sizeof(float) *
|
|
||||||
2, NULL, GL_DYNAMIC_DRAW);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
|
|
||||||
free(eb);
|
free(eb);
|
||||||
glamor_priv->vb = (char *) vb;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glamor_put_context(glamor_priv);
|
glamor_put_context(glamor_priv);
|
||||||
|
@ -460,7 +448,6 @@ glamor_fini_composite_shaders(ScreenPtr screen)
|
||||||
|
|
||||||
glamor_priv = glamor_get_screen_private(screen);
|
glamor_priv = glamor_get_screen_private(screen);
|
||||||
glamor_get_context(glamor_priv);
|
glamor_get_context(glamor_priv);
|
||||||
glDeleteBuffers(1, &glamor_priv->vbo);
|
|
||||||
glDeleteBuffers(1, &glamor_priv->ebo);
|
glDeleteBuffers(1, &glamor_priv->ebo);
|
||||||
|
|
||||||
for (i = 0; i < SHADER_SOURCE_COUNT; i++)
|
for (i = 0; i < SHADER_SOURCE_COUNT; i++)
|
||||||
|
@ -470,8 +457,6 @@ glamor_fini_composite_shaders(ScreenPtr screen)
|
||||||
if (shader->prog)
|
if (shader->prog)
|
||||||
glDeleteProgram(shader->prog);
|
glDeleteProgram(shader->prog);
|
||||||
}
|
}
|
||||||
if (glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP && glamor_priv->vb)
|
|
||||||
free(glamor_priv->vb);
|
|
||||||
|
|
||||||
glamor_put_context(glamor_priv);
|
glamor_put_context(glamor_priv);
|
||||||
}
|
}
|
||||||
|
@ -706,6 +691,8 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
|
||||||
{
|
{
|
||||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||||
int vert_size;
|
int vert_size;
|
||||||
|
char *vbo_offset;
|
||||||
|
float *vb;
|
||||||
|
|
||||||
glamor_priv->render_nr_verts = 0;
|
glamor_priv->render_nr_verts = 0;
|
||||||
glamor_priv->vb_stride = 2 * sizeof(float);
|
glamor_priv->vb_stride = 2 * sizeof(float);
|
||||||
|
@ -717,56 +704,32 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
|
||||||
vert_size = n_verts * glamor_priv->vb_stride;
|
vert_size = n_verts * glamor_priv->vb_stride;
|
||||||
|
|
||||||
glamor_get_context(glamor_priv);
|
glamor_get_context(glamor_priv);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
|
vb = glamor_get_vbo_space(screen, vert_size, &vbo_offset);
|
||||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
|
||||||
if (glamor_priv->vbo_size < (glamor_priv->vbo_offset + vert_size)) {
|
|
||||||
glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_VERT_CNT *
|
|
||||||
glamor_priv->vb_stride;
|
|
||||||
glamor_priv->vbo_offset = 0;
|
|
||||||
glBufferData(GL_ARRAY_BUFFER,
|
|
||||||
glamor_priv->vbo_size, NULL, GL_STREAM_DRAW);
|
|
||||||
}
|
|
||||||
|
|
||||||
glamor_priv->vb = glMapBufferRange(GL_ARRAY_BUFFER,
|
|
||||||
glamor_priv->vbo_offset,
|
|
||||||
vert_size,
|
|
||||||
GL_MAP_WRITE_BIT |
|
|
||||||
GL_MAP_UNSYNCHRONIZED_BIT |
|
|
||||||
GL_MAP_INVALIDATE_RANGE_BIT);
|
|
||||||
assert(glamor_priv->vb != NULL);
|
|
||||||
glamor_priv->vb -= glamor_priv->vbo_offset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
glamor_priv->vbo_offset = 0;
|
|
||||||
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
|
||||||
|
|
||||||
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
|
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
|
||||||
glamor_priv->vb_stride,
|
glamor_priv->vb_stride, vbo_offset);
|
||||||
(void *) ((long)
|
|
||||||
glamor_priv->vbo_offset));
|
|
||||||
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||||
|
|
||||||
if (glamor_priv->has_source_coords) {
|
if (glamor_priv->has_source_coords) {
|
||||||
glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
|
glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2,
|
||||||
GL_FLOAT, GL_FALSE,
|
GL_FLOAT, GL_FALSE,
|
||||||
glamor_priv->vb_stride,
|
glamor_priv->vb_stride,
|
||||||
(void *) ((long) glamor_priv->vbo_offset +
|
vbo_offset + 2 * sizeof(float));
|
||||||
2 * sizeof(float)));
|
|
||||||
glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
|
glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (glamor_priv->has_mask_coords) {
|
if (glamor_priv->has_mask_coords) {
|
||||||
glVertexAttribPointer(GLAMOR_VERTEX_MASK, 2, GL_FLOAT, GL_FALSE,
|
glVertexAttribPointer(GLAMOR_VERTEX_MASK, 2, GL_FLOAT, GL_FALSE,
|
||||||
glamor_priv->vb_stride,
|
glamor_priv->vb_stride,
|
||||||
(void *) ((long) glamor_priv->vbo_offset +
|
vbo_offset + (glamor_priv->has_source_coords ?
|
||||||
(glamor_priv->has_source_coords ?
|
4 : 2) * sizeof(float));
|
||||||
4 : 2) * sizeof(float)));
|
|
||||||
glEnableVertexAttribArray(GLAMOR_VERTEX_MASK);
|
glEnableVertexAttribArray(GLAMOR_VERTEX_MASK);
|
||||||
}
|
}
|
||||||
glamor_put_context(glamor_priv);
|
glamor_put_context(glamor_priv);
|
||||||
|
|
||||||
return glamor_priv->vb + glamor_priv->vbo_offset;
|
return vb;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -775,14 +738,6 @@ glamor_flush_composite_rects(ScreenPtr screen)
|
||||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||||
|
|
||||||
glamor_get_context(glamor_priv);
|
glamor_get_context(glamor_priv);
|
||||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
|
|
||||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
|
||||||
else {
|
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset,
|
|
||||||
glamor_priv->vb, GL_DYNAMIC_DRAW);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!glamor_priv->render_nr_verts)
|
if (!glamor_priv->render_nr_verts)
|
||||||
return;
|
return;
|
||||||
|
@ -1334,8 +1289,6 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
x_dest, y_dest, x_source, y_source, x_mask, y_mask, width,
|
x_dest, y_dest, x_source, y_source, x_mask, y_mask, width,
|
||||||
height);
|
height);
|
||||||
|
|
||||||
assert(glamor_priv->vbo_offset <
|
|
||||||
glamor_priv->vbo_size - glamor_priv->vb_stride);
|
|
||||||
glamor_set_normalize_vcoords_ext(dest_pixmap_priv, dst_xscale,
|
glamor_set_normalize_vcoords_ext(dest_pixmap_priv, dst_xscale,
|
||||||
dst_yscale, x_dest, y_dest,
|
dst_yscale, x_dest, y_dest,
|
||||||
x_dest + width, y_dest + height,
|
x_dest + width, y_dest + height,
|
||||||
|
@ -1366,12 +1319,12 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
vertices += 2;
|
vertices += 2;
|
||||||
}
|
}
|
||||||
glamor_priv->render_nr_verts += 4;
|
glamor_priv->render_nr_verts += 4;
|
||||||
glamor_priv->vbo_offset += glamor_priv->vb_stride * 4;
|
|
||||||
rects++;
|
rects++;
|
||||||
|
|
||||||
/* We've incremented by one of our 4 verts, now do the other 3. */
|
/* We've incremented by one of our 4 verts, now do the other 3. */
|
||||||
vertices += 3 * vb_stride;
|
vertices += 3 * vb_stride;
|
||||||
}
|
}
|
||||||
|
glamor_put_vbo_space(screen);
|
||||||
glamor_flush_composite_rects(screen);
|
glamor_flush_composite_rects(screen);
|
||||||
nrect -= rect_processed;
|
nrect -= rect_processed;
|
||||||
if (two_pass_ca) {
|
if (two_pass_ca) {
|
||||||
|
@ -1384,7 +1337,6 @@ glamor_composite_with_shader(CARD8 op,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||||
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
|
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
|
||||||
|
|
|
@ -213,7 +213,6 @@ glamor_emit_composite_vert(ScreenPtr screen,
|
||||||
}
|
}
|
||||||
|
|
||||||
glamor_priv->render_nr_verts++;
|
glamor_priv->render_nr_verts++;
|
||||||
glamor_priv->vbo_offset += glamor_priv->vb_stride;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -237,14 +236,7 @@ glamor_flush_composite_triangles(ScreenPtr screen)
|
||||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||||
|
|
||||||
glamor_get_context(glamor_priv);
|
glamor_get_context(glamor_priv);
|
||||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
|
glamor_put_vbo_space(screen);
|
||||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
|
||||||
else {
|
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset,
|
|
||||||
glamor_priv->vb, GL_DYNAMIC_DRAW);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!glamor_priv->render_nr_verts)
|
if (!glamor_priv->render_nr_verts)
|
||||||
return;
|
return;
|
||||||
|
@ -613,6 +605,8 @@ glamor_setup_composite_vbo_for_trapezoid(ScreenPtr screen, int n_verts)
|
||||||
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||||
int stride;
|
int stride;
|
||||||
int vert_size;
|
int vert_size;
|
||||||
|
char *vbo_offset;
|
||||||
|
void *vb;
|
||||||
|
|
||||||
glamor_priv->render_nr_verts = 0;
|
glamor_priv->render_nr_verts = 0;
|
||||||
|
|
||||||
|
@ -641,68 +635,43 @@ glamor_setup_composite_vbo_for_trapezoid(ScreenPtr screen, int n_verts)
|
||||||
glDisableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
|
glDisableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
|
||||||
glDisableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
|
glDisableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
|
vb = glamor_get_vbo_space(screen, vert_size, &vbo_offset);
|
||||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
|
||||||
if (glamor_priv->vbo_size < (glamor_priv->vbo_offset + vert_size)) {
|
|
||||||
glamor_priv->vbo_size = GLAMOR_COMPOSITE_VBO_VERT_CNT *
|
|
||||||
glamor_priv->vb_stride;
|
|
||||||
glamor_priv->vbo_offset = 0;
|
|
||||||
glBufferData(GL_ARRAY_BUFFER,
|
|
||||||
glamor_priv->vbo_size, NULL, GL_STREAM_DRAW);
|
|
||||||
}
|
|
||||||
|
|
||||||
glamor_priv->vb = glMapBufferRange(GL_ARRAY_BUFFER,
|
|
||||||
glamor_priv->vbo_offset,
|
|
||||||
vert_size,
|
|
||||||
GL_MAP_WRITE_BIT |
|
|
||||||
GL_MAP_UNSYNCHRONIZED_BIT);
|
|
||||||
|
|
||||||
assert(glamor_priv->vb != NULL);
|
|
||||||
glamor_priv->vb -= glamor_priv->vbo_offset;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
glamor_priv->vbo_offset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
|
||||||
|
|
||||||
/* Set the vertex pointer. */
|
/* Set the vertex pointer. */
|
||||||
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
|
glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
|
||||||
GL_FALSE, glamor_priv->vb_stride,
|
GL_FALSE, glamor_priv->vb_stride,
|
||||||
(void *) ((long) glamor_priv->vbo_offset));
|
vbo_offset);
|
||||||
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||||
stride = 2;
|
stride = 2;
|
||||||
|
|
||||||
glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
|
glVertexAttribPointer(GLAMOR_VERTEX_SOURCE, 2, GL_FLOAT,
|
||||||
GL_FALSE, glamor_priv->vb_stride,
|
GL_FALSE, glamor_priv->vb_stride,
|
||||||
(void *) ((long) glamor_priv->vbo_offset +
|
vbo_offset + stride * sizeof(float));
|
||||||
stride * sizeof(float)));
|
|
||||||
glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
|
glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
|
||||||
stride += 2;
|
stride += 2;
|
||||||
|
|
||||||
glVertexAttribPointer(GLAMOR_VERTEX_TOP_BOTTOM, 2, GL_FLOAT,
|
glVertexAttribPointer(GLAMOR_VERTEX_TOP_BOTTOM, 2, GL_FLOAT,
|
||||||
GL_FALSE, glamor_priv->vb_stride,
|
GL_FALSE, glamor_priv->vb_stride,
|
||||||
(void *) ((long) glamor_priv->vbo_offset +
|
vbo_offset + stride * sizeof(float));
|
||||||
stride * sizeof(float)));
|
|
||||||
glEnableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM);
|
glEnableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM);
|
||||||
stride += 2;
|
stride += 2;
|
||||||
|
|
||||||
glVertexAttribPointer(GLAMOR_VERTEX_LEFT_PARAM, 4, GL_FLOAT,
|
glVertexAttribPointer(GLAMOR_VERTEX_LEFT_PARAM, 4, GL_FLOAT,
|
||||||
GL_FALSE, glamor_priv->vb_stride,
|
GL_FALSE, glamor_priv->vb_stride,
|
||||||
(void *) ((long) glamor_priv->vbo_offset +
|
vbo_offset + stride * sizeof(float));
|
||||||
stride * sizeof(float)));
|
|
||||||
glEnableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
|
glEnableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
|
||||||
stride += 4;
|
stride += 4;
|
||||||
|
|
||||||
glVertexAttribPointer(GLAMOR_VERTEX_RIGHT_PARAM, 4, GL_FLOAT,
|
glVertexAttribPointer(GLAMOR_VERTEX_RIGHT_PARAM, 4, GL_FLOAT,
|
||||||
GL_FALSE, glamor_priv->vb_stride,
|
GL_FALSE, glamor_priv->vb_stride,
|
||||||
(void *) ((long) glamor_priv->vbo_offset +
|
vbo_offset + stride * sizeof(float));
|
||||||
stride * sizeof(float)));
|
|
||||||
glEnableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
|
glEnableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
|
||||||
|
|
||||||
glamor_put_context(glamor_priv);
|
glamor_put_context(glamor_priv);
|
||||||
|
|
||||||
return glamor_priv->vb + glamor_priv->vbo_offset;
|
return vb;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool
|
static Bool
|
||||||
|
@ -1008,7 +977,6 @@ _glamor_trapezoids_with_shader(CARD8 op,
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
|
||||||
TRAPEZOID_RESET_GL:
|
TRAPEZOID_RESET_GL:
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
|
||||||
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
|
glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
|
||||||
|
@ -1450,7 +1418,6 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
|
||||||
|
|
||||||
pixmap_priv_get_dest_scale(pixmap_priv, (&xscale), (&yscale));
|
pixmap_priv_get_dest_scale(pixmap_priv, (&xscale), (&yscale));
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
/* Now draw the Trapezoid mask. */
|
/* Now draw the Trapezoid mask. */
|
||||||
|
@ -1575,25 +1542,17 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
|
||||||
((float) ptrap->right.p1.y) / 65536, right_slope);
|
((float) ptrap->right.p1.y) / 65536, right_slope);
|
||||||
|
|
||||||
glamor_priv->render_nr_verts += 4;
|
glamor_priv->render_nr_verts += 4;
|
||||||
glamor_priv->vbo_offset += glamor_priv->vb_stride * 4;
|
|
||||||
|
|
||||||
vertices += 3 * stride;
|
vertices += 3 * stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
i += mrect;
|
i += mrect;
|
||||||
|
|
||||||
|
glamor_put_vbo_space(screen);
|
||||||
|
|
||||||
/* Now rendering. */
|
/* Now rendering. */
|
||||||
if (!glamor_priv->render_nr_verts)
|
if (!glamor_priv->render_nr_verts)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
|
|
||||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
|
||||||
else {
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset,
|
|
||||||
glamor_priv->vb, GL_DYNAMIC_DRAW);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
||||||
glDrawRangeElements(GL_TRIANGLES, 0,
|
glDrawRangeElements(GL_TRIANGLES, 0,
|
||||||
glamor_priv->render_nr_verts,
|
glamor_priv->render_nr_verts,
|
||||||
|
@ -1606,7 +1565,6 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
glBlendFunc(GL_ONE, GL_ZERO);
|
glBlendFunc(GL_ONE, GL_ZERO);
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2014 Intel Corporation
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (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 NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
* IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file glamor_vbo.c
|
||||||
|
*
|
||||||
|
* Helpers for managing streamed vertex bufffers used in glamor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "glamor_priv.h"
|
||||||
|
|
||||||
|
/** Default size of the VBO, in bytes.
|
||||||
|
*
|
||||||
|
* If a single request is larger than this size, we'll resize the VBO
|
||||||
|
* and return an appropriate mapping, but we'll resize back down after
|
||||||
|
* that to avoid hogging that memory forever. We don't anticipate
|
||||||
|
* normal usage actually requiring larger VBO sizes.
|
||||||
|
*/
|
||||||
|
#define GLAMOR_VBO_SIZE (512 * 1024)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a pointer to @size bytes of VBO storage, which should be
|
||||||
|
* accessed by the GL using vbo_offset within the VBO.
|
||||||
|
*/
|
||||||
|
void *
|
||||||
|
glamor_get_vbo_space(ScreenPtr screen, unsigned size, char **vbo_offset)
|
||||||
|
{
|
||||||
|
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||||
|
void *data;
|
||||||
|
|
||||||
|
glamor_get_context(glamor_priv);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
|
||||||
|
|
||||||
|
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
||||||
|
if (glamor_priv->vbo_size < glamor_priv->vbo_offset + size) {
|
||||||
|
glamor_priv->vbo_size = MAX(GLAMOR_VBO_SIZE, size);
|
||||||
|
glamor_priv->vbo_offset = 0;
|
||||||
|
glBufferData(GL_ARRAY_BUFFER,
|
||||||
|
glamor_priv->vbo_size, NULL, GL_STREAM_DRAW);
|
||||||
|
}
|
||||||
|
|
||||||
|
data = glMapBufferRange(GL_ARRAY_BUFFER,
|
||||||
|
glamor_priv->vbo_offset,
|
||||||
|
size,
|
||||||
|
GL_MAP_WRITE_BIT |
|
||||||
|
GL_MAP_UNSYNCHRONIZED_BIT |
|
||||||
|
GL_MAP_INVALIDATE_RANGE_BIT);
|
||||||
|
assert(data != NULL);
|
||||||
|
*vbo_offset = (char *)(uintptr_t)glamor_priv->vbo_offset;
|
||||||
|
glamor_priv->vbo_offset += size;
|
||||||
|
} else {
|
||||||
|
/* Return a pointer to the statically allocated non-VBO
|
||||||
|
* memory. We'll upload it through glBufferData() later.
|
||||||
|
*/
|
||||||
|
if (glamor_priv->vbo_size < size) {
|
||||||
|
glamor_priv->vbo_size = MAX(GLAMOR_VBO_SIZE, size);
|
||||||
|
free(glamor_priv->vb);
|
||||||
|
glamor_priv->vb = XNFalloc(size);
|
||||||
|
}
|
||||||
|
*vbo_offset = NULL;
|
||||||
|
/* We point to the start of glamor_priv->vb every time, and
|
||||||
|
* the vbo_offset determines the size of the glBufferData().
|
||||||
|
*/
|
||||||
|
glamor_priv->vbo_offset = size;
|
||||||
|
data = glamor_priv->vb;
|
||||||
|
}
|
||||||
|
|
||||||
|
glamor_put_context(glamor_priv);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
glamor_put_vbo_space(ScreenPtr screen)
|
||||||
|
{
|
||||||
|
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||||
|
|
||||||
|
glamor_get_context(glamor_priv);
|
||||||
|
|
||||||
|
if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP) {
|
||||||
|
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||||
|
} else {
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, glamor_priv->vbo_offset,
|
||||||
|
glamor_priv->vb, GL_DYNAMIC_DRAW);
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
glamor_put_context(glamor_priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
glamor_init_vbo(ScreenPtr screen)
|
||||||
|
{
|
||||||
|
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||||
|
|
||||||
|
glamor_get_context(glamor_priv);
|
||||||
|
|
||||||
|
glGenBuffers(1, &glamor_priv->vbo);
|
||||||
|
|
||||||
|
glamor_put_context(glamor_priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
glamor_fini_vbo(ScreenPtr screen)
|
||||||
|
{
|
||||||
|
glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
|
||||||
|
|
||||||
|
glamor_get_context(glamor_priv);
|
||||||
|
|
||||||
|
glDeleteBuffers(1, &glamor_priv->vbo);
|
||||||
|
if (glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP)
|
||||||
|
free(glamor_priv->vb);
|
||||||
|
|
||||||
|
glamor_put_context(glamor_priv);
|
||||||
|
}
|
Loading…
Reference in New Issue