* Chia-I Wu <olv@lunarg.com>
*/
-#include "util/u_memory.h"
-#include "util/u_inlines.h"
-
#include "xm_api.h"
#include "xm_st.h"
+#include "util/u_inlines.h"
+
struct xmesa_st_framebuffer {
XMesaDisplay display;
XMesaBuffer buffer;
struct pipe_screen *screen;
struct st_visual stvis;
+ enum pipe_texture_target target;
unsigned texture_width, texture_height, texture_mask;
struct pipe_resource *textures[ST_ATTACHMENT_COUNT];
- struct pipe_surface *display_surface;
+ struct pipe_resource *display_resource;
};
static INLINE struct xmesa_st_framebuffer *
{
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
struct pipe_resource *ptex = xstfb->textures[statt];
- struct pipe_surface *psurf;
+ struct pipe_resource *pres;
if (!ptex)
return TRUE;
- psurf = xstfb->display_surface;
+ pres = xstfb->display_resource;
/* (re)allocate the surface for the texture to be displayed */
- if (!psurf || psurf->texture != ptex) {
- pipe_surface_reference(&xstfb->display_surface, NULL);
-
- psurf = xstfb->screen->get_tex_surface(xstfb->screen,
- ptex, 0, 0, 0, PIPE_BIND_DISPLAY_TARGET);
- if (!psurf)
- return FALSE;
-
- xstfb->display_surface = psurf;
+ if (!pres || pres != ptex) {
+ pipe_resource_reference(&xstfb->display_resource, ptex);
+ pres = xstfb->display_resource;
}
- xstfb->screen->flush_frontbuffer(xstfb->screen, psurf, &xstfb->buffer->ws);
+ xstfb->screen->flush_frontbuffer(xstfb->screen, pres, 0, 0, &xstfb->buffer->ws);
return TRUE;
}
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
struct pipe_resource *src_ptex = xstfb->textures[src_statt];
struct pipe_resource *dst_ptex = xstfb->textures[dst_statt];
- struct pipe_surface *src, *dst;
+ struct pipe_box src_box;
struct pipe_context *pipe;
if (!src_ptex || !dst_ptex)
xstfb->display->pipe = pipe;
}
- src = xstfb->screen->get_tex_surface(xstfb->screen,
- src_ptex, 0, 0, 0, PIPE_BIND_BLIT_SOURCE);
- dst = xstfb->screen->get_tex_surface(xstfb->screen,
- dst_ptex, 0, 0, 0, PIPE_BIND_BLIT_DESTINATION);
-
- if (src && dst)
- pipe->surface_copy(pipe, dst, x, y, src, x, y, width, height);
+ u_box_2d(x, y, width, height, &src_box);
- pipe_surface_reference(&src, NULL);
- pipe_surface_reference(&dst, NULL);
+ if (src_ptex && dst_ptex)
+ pipe->resource_copy_region(pipe, dst_ptex, 0, x, y, 0,
+ src_ptex, 0, &src_box);
}
/**
* Remove outdated textures and create the requested ones.
+ * This is a helper used during framebuffer validation.
*/
static boolean
xmesa_st_framebuffer_validate_textures(struct st_framebuffer_iface *stfbi,
}
memset(&templ, 0, sizeof(templ));
- templ.target = PIPE_TEXTURE_2D;
+ templ.target = xstfb->target;
templ.width0 = width;
templ.height0 = height;
templ.depth0 = 1;
+ templ.array_size = 1;
templ.last_level = 0;
for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
return TRUE;
}
+
+/**
+ * Check that a framebuffer's attachments match the window's size.
+ *
+ * Called via st_framebuffer_iface::validate()
+ *
+ * \param statts array of framebuffer attachments
+ * \param count number of framebuffer attachments in statts[]
+ * \param out returns resources for each of the attachments
+ */
static boolean
xmesa_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
const enum st_attachment_type *statts,
boolean resized;
boolean ret;
+ /* build mask of ST_ATTACHMENT bits */
statt_mask = 0x0;
for (i = 0; i < count; i++)
statt_mask |= 1 << statts[i];
+
/* record newly allocated textures */
new_mask = statt_mask & ~xstfb->texture_mask;
+ /* If xmesa_strict_invalidate is not set, we will not yet have
+ * called XGetGeometry(). Do so here:
+ */
+ if (!xmesa_strict_invalidate)
+ xmesa_check_buffer_size(xstfb->buffer);
+
resized = (xstfb->buffer->width != xstfb->texture_width ||
xstfb->buffer->height != xstfb->texture_height);
return TRUE;
}
+/**
+ * Called via st_framebuffer_iface::flush_front()
+ */
static boolean
xmesa_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi,
enum st_attachment_type statt)
boolean ret;
ret = xmesa_st_framebuffer_display(stfbi, statt);
- if (ret)
+
+ if (ret && xmesa_strict_invalidate)
xmesa_check_buffer_size(xstfb->buffer);
return ret;
xstfb->buffer = b;
xstfb->screen = xmdpy->screen;
xstfb->stvis = b->xm_visual->stvis;
+ if(xstfb->screen->get_param(xstfb->screen, PIPE_CAP_NPOT_TEXTURES))
+ xstfb->target = PIPE_TEXTURE_2D;
+ else
+ xstfb->target = PIPE_TEXTURE_RECT;
stfbi->visual = &xstfb->stvis;
stfbi->flush_front = xmesa_st_framebuffer_flush_front;
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
int i;
- pipe_surface_reference(&xstfb->display_surface, NULL);
+ pipe_resource_reference(&xstfb->display_resource, NULL);
for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
pipe_resource_reference(&xstfb->textures[i], NULL);
tmp = *front;
*front = *back;
*back = tmp;
+
+ /* the current context should validate the buffer after swapping */
+ if (!xmesa_strict_invalidate)
+ xmesa_notify_invalid_buffer(xstfb->buffer);
}
- xmesa_check_buffer_size(xstfb->buffer);
+ if (xmesa_strict_invalidate)
+ xmesa_check_buffer_size(xstfb->buffer);
}
}