summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBen Skeggs <skeggsb@gmail.com>2008-06-29 12:16:13 +1000
committerBen Skeggs <skeggsb@gmail.com>2008-06-29 12:16:13 +1000
commit01de2293d5449ab6ca1d99b007c9ea4f0037fef5 (patch)
tree8560aab576c3d8504f8d7935ab6fcd46ea35182e /src
parentb831aa06dc0d099185bcaa180683ad10942feaa0 (diff)
parent9d94d133b019ef23ee03cc691fcb5602451604ae (diff)
Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
Diffstat (limited to 'src')
-rw-r--r--src/egl/drivers/xdri/egl_xdri.c2
-rw-r--r--src/egl/main/eglconfig.c14
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_aaline.c4
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_pstipple.c6
-rw-r--r--src/gallium/auxiliary/util/p_tile.c98
-rw-r--r--src/gallium/auxiliary/util/p_util.c100
-rw-r--r--src/gallium/auxiliary/util/u_blit.c2
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.c8
-rw-r--r--src/gallium/drivers/cell/ppu/cell_surface.c65
-rw-r--r--src/gallium/drivers/cell/ppu/cell_texture.c16
-rw-r--r--src/gallium/drivers/i915simple/i915_blit.c2
-rw-r--r--src/gallium/drivers/i915simple/i915_context.h6
-rw-r--r--src/gallium/drivers/i915simple/i915_state_emit.c4
-rw-r--r--src/gallium/drivers/i915simple/i915_state_sampler.c2
-rw-r--r--src/gallium/drivers/i915simple/i915_surface.c78
-rw-r--r--src/gallium/drivers/i915simple/i915_texture.c196
-rw-r--r--src/gallium/drivers/i965simple/SConscript1
-rw-r--r--src/gallium/drivers/i965simple/brw_context.h4
-rw-r--r--src/gallium/drivers/i965simple/brw_misc_state.c8
-rw-r--r--src/gallium/drivers/i965simple/brw_surface.c69
-rw-r--r--src/gallium/drivers/i965simple/brw_tex_layout.c117
-rw-r--r--src/gallium/drivers/i965simple/brw_wm_surface_state.c6
-rw-r--r--src/gallium/drivers/softpipe/sp_surface.c45
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c20
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.h2
-rw-r--r--src/gallium/include/pipe/p_format.h97
-rw-r--r--src/gallium/include/pipe/p_state.h17
-rw-r--r--src/gallium/include/pipe/p_util.h15
-rw-r--r--src/gallium/winsys/dri/intel/intel_screen.c10
-rw-r--r--src/gallium/winsys/dri/intel/intel_swapbuffers.c2
-rw-r--r--src/gallium/winsys/egl_xlib/egl_xlib.c10
-rw-r--r--src/gallium/winsys/egl_xlib/sw_winsys.c10
-rw-r--r--src/gallium/winsys/gdi/wmesa.c8
-rw-r--r--src/gallium/winsys/xlib/SConscript7
-rw-r--r--src/gallium/winsys/xlib/brw_aub.c9
-rw-r--r--src/gallium/winsys/xlib/xm_winsys.c24
-rw-r--r--src/gallium/winsys/xlib/xm_winsys_aub.c31
-rw-r--r--src/mesa/drivers/dri/common/utils.c97
-rw-r--r--src/mesa/drivers/dri/common/utils.h3
-rw-r--r--src/mesa/main/arrayobj.c9
-rw-r--r--src/mesa/main/enable.c12
-rw-r--r--src/mesa/main/ffvertex_prog.c36
-rw-r--r--src/mesa/main/glheader.h10
-rw-r--r--src/mesa/main/mfeatures.h1
-rw-r--r--src/mesa/main/mtypes.h5
-rw-r--r--src/mesa/main/state.c2
-rw-r--r--src/mesa/main/varray.c31
-rw-r--r--src/mesa/main/varray.h4
-rw-r--r--src/mesa/shader/prog_uniform.c4
-rw-r--r--src/mesa/shader/shader_api.c10
-rw-r--r--src/mesa/state_tracker/st_cb_accum.c26
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.c4
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c11
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.c12
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.h2
-rw-r--r--src/mesa/state_tracker/st_cb_readpixels.c6
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c17
-rw-r--r--src/mesa/state_tracker/st_framebuffer.c18
-rw-r--r--src/mesa/state_tracker/st_gen_mipmap.c4
-rw-r--r--src/mesa/state_tracker/st_program.c4
-rw-r--r--src/mesa/state_tracker/st_texture.c26
-rw-r--r--src/mesa/vbo/vbo_exec_array.c4
-rw-r--r--src/mesa/x86-64/glapi_x86-64.S2
63 files changed, 831 insertions, 644 deletions
diff --git a/src/egl/drivers/xdri/egl_xdri.c b/src/egl/drivers/xdri/egl_xdri.c
index df80c6a1c4..71d4f15371 100644
--- a/src/egl/drivers/xdri/egl_xdri.c
+++ b/src/egl/drivers/xdri/egl_xdri.c
@@ -828,7 +828,7 @@ _eglMain(_EGLDisplay *disp, const char *args)
xdri_drv->Base.API.DestroySurface = xdri_eglDestroySurface;
xdri_drv->Base.API.SwapBuffers = xdri_eglSwapBuffers;
- xdri_drv->Base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/;
+ xdri_drv->Base.ClientAPIsMask = EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT;
xdri_drv->Base.Name = "X/DRI";
_eglLog(_EGL_DEBUG, "XDRI: main(%s)", args);
diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c
index 3ef0564a54..b19988f49a 100644
--- a/src/egl/main/eglconfig.c
+++ b/src/egl/main/eglconfig.c
@@ -43,9 +43,7 @@ _eglInitConfig(_EGLConfig *config, EGLint id)
_eglSetConfigAttrib(config, EGL_NATIVE_VISUAL_TYPE, EGL_DONT_CARE);
_eglSetConfigAttrib(config, EGL_MIN_SWAP_INTERVAL, EGL_DONT_CARE);
_eglSetConfigAttrib(config, EGL_MAX_SWAP_INTERVAL, EGL_DONT_CARE);
- _eglSetConfigAttrib(config, EGL_SURFACE_TYPE,
- EGL_SCREEN_BIT_MESA | EGL_PBUFFER_BIT |
- EGL_PIXMAP_BIT | EGL_WINDOW_BIT);
+ _eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_WINDOW_BIT);
_eglSetConfigAttrib(config, EGL_TRANSPARENT_TYPE, EGL_NONE);
_eglSetConfigAttrib(config, EGL_TRANSPARENT_RED_VALUE, EGL_DONT_CARE);
_eglSetConfigAttrib(config, EGL_TRANSPARENT_GREEN_VALUE, EGL_DONT_CARE);
@@ -96,6 +94,14 @@ _eglAddConfig(_EGLDisplay *display, _EGLConfig *config)
_EGLConfig **newConfigs;
EGLint n;
+ /* do some sanity checks on the config's attribs */
+ assert(GET_CONFIG_ATTRIB(config, EGL_CONFIG_ID) > 0);
+ assert(GET_CONFIG_ATTRIB(config, EGL_RENDERABLE_TYPE) != 0x0);
+ assert(GET_CONFIG_ATTRIB(config, EGL_SURFACE_TYPE) != 0x0);
+ assert(GET_CONFIG_ATTRIB(config, EGL_RED_SIZE) > 0);
+ assert(GET_CONFIG_ATTRIB(config, EGL_GREEN_SIZE) > 0);
+ assert(GET_CONFIG_ATTRIB(config, EGL_BLUE_SIZE) > 0);
+
n = display->NumConfigs;
/* realloc array of ptrs */
@@ -147,7 +153,7 @@ _eglParseConfigAttribs(_EGLConfig *config, const EGLint *attrib_list)
}
else if (attr == EGL_RENDERABLE_TYPE) {
EGLint renType = attrib_list[++i];
- if (renType & ~(EGL_OPENGL_ES_BIT | EGL_OPENVG_BIT)) {
+ if (renType & ~(EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT | EGL_OPENVG_BIT)) {
_eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig");
return EGL_FALSE;
}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
index ecdebca5f1..3dd7ee19fd 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
@@ -398,7 +398,7 @@ aaline_create_texture(struct aaline_stage *aaline)
texTemp.width[0] = 1 << MAX_TEXTURE_LEVEL;
texTemp.height[0] = 1 << MAX_TEXTURE_LEVEL;
texTemp.depth[0] = 1;
- texTemp.cpp = 1;
+ pf_get_block(texTemp.format, &texTemp.block);
aaline->texture = screen->texture_create(screen, &texTemp);
if (!aaline->texture)
@@ -439,7 +439,7 @@ aaline_create_texture(struct aaline_stage *aaline)
else {
d = 255;
}
- data[i * surface->pitch + j] = d;
+ data[i * surface->stride + j] = d;
}
}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
index 4087cf7a49..1f63f94365 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
@@ -394,11 +394,11 @@ pstip_update_texture(struct pstip_stage *pstip)
for (j = 0; j < 32; j++) {
if (stipple[i] & (bit31 >> j)) {
/* fragment "on" */
- data[i * surface->pitch + j] = 0;
+ data[i * surface->stride + j] = 0;
}
else {
/* fragment "off" */
- data[i * surface->pitch + j] = 255;
+ data[i * surface->stride + j] = 255;
}
}
}
@@ -426,7 +426,7 @@ pstip_create_texture(struct pstip_stage *pstip)
texTemp.width[0] = 32;
texTemp.height[0] = 32;
texTemp.depth[0] = 1;
- texTemp.cpp = 1;
+ pf_get_block(texTemp.format, &texTemp.block);
pstip->texture = screen->texture_create(screen, &texTemp);
if (pstip->texture == NULL)
diff --git a/src/gallium/auxiliary/util/p_tile.c b/src/gallium/auxiliary/util/p_tile.c
index 5728757d2f..ab603ff6e4 100644
--- a/src/gallium/auxiliary/util/p_tile.c
+++ b/src/gallium/auxiliary/util/p_tile.c
@@ -48,34 +48,23 @@ void
pipe_get_tile_raw(struct pipe_context *pipe,
struct pipe_surface *ps,
uint x, uint y, uint w, uint h,
- void *p, int dst_stride)
+ void *dst, int dst_stride)
{
struct pipe_screen *screen = pipe->screen;
- const uint cpp = ps->cpp;
- const ubyte *pSrc;
- const uint src_stride = ps->pitch * cpp;
- ubyte *pDest;
- uint i;
-
- if (dst_stride == 0) {
- dst_stride = w * cpp;
- }
+ const void *src;
if (pipe_clip_tile(x, y, &w, &h, ps))
return;
- pSrc = (const ubyte *) screen->surface_map(screen, ps,
- PIPE_BUFFER_USAGE_CPU_READ);
- assert(pSrc); /* XXX: proper error handling! */
+ if (dst_stride == 0)
+ dst_stride = pf_get_nblocksx(&ps->block, w) * ps->block.size;
- pSrc += (y * ps->pitch + x) * cpp;
- pDest = (ubyte *) p;
+ src = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ);
+ assert(src);
+ if(!src)
+ return;
- for (i = 0; i < h; i++) {
- memcpy(pDest, pSrc, w * cpp);
- pDest += dst_stride;
- pSrc += src_stride;
- }
+ pipe_copy_rect(dst, &ps->block, dst_stride, 0, 0, w, h, src, ps->stride, x, y);
screen->surface_unmap(screen, ps);
}
@@ -89,34 +78,23 @@ void
pipe_put_tile_raw(struct pipe_context *pipe,
struct pipe_surface *ps,
uint x, uint y, uint w, uint h,
- const void *p, int src_stride)
+ const void *src, int src_stride)
{
struct pipe_screen *screen = pipe->screen;
- const uint cpp = ps->cpp;
- const ubyte *pSrc;
- const uint dst_stride = ps->pitch * cpp;
- ubyte *pDest;
- uint i;
-
- if (src_stride == 0) {
- src_stride = w * cpp;
- }
+ void *dst;
if (pipe_clip_tile(x, y, &w, &h, ps))
return;
- pSrc = (const ubyte *) p;
+ if (src_stride == 0)
+ src_stride = pf_get_nblocksx(&ps->block, w) * ps->block.size;
- pDest = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE);
- assert(pDest); /* XXX: proper error handling */
-
- pDest += (y * ps->pitch + x) * cpp;
+ dst = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE);
+ assert(dst);
+ if(!dst)
+ return;
- for (i = 0; i < h; i++) {
- memcpy(pDest, pSrc, w * cpp);
- pDest += dst_stride;
- pSrc += src_stride;
- }
+ pipe_copy_rect(dst, &ps->block, ps->stride, x, y, w, h, src, src_stride, 0, 0);
screen->surface_unmap(screen, ps);
}
@@ -692,12 +670,12 @@ pipe_get_tile_rgba(struct pipe_context *pipe,
if (pipe_clip_tile(x, y, &w, &h, ps))
return;
- packed = MALLOC(h * w * ps->cpp);
+ packed = MALLOC(pf_get_nblocks(&ps->block, w, h) * ps->block.size);
if (!packed)
return;
- pipe_get_tile_raw(pipe, ps, x, y, w, h, packed, w * ps->cpp);
+ pipe_get_tile_raw(pipe, ps, x, y, w, h, packed, 0);
switch (ps->format) {
case PIPE_FORMAT_A8R8G8B8_UNORM:
@@ -774,7 +752,7 @@ pipe_put_tile_rgba(struct pipe_context *pipe,
if (pipe_clip_tile(x, y, &w, &h, ps))
return;
- packed = MALLOC(h * w * ps->cpp);
+ packed = MALLOC(pf_get_nblocks(&ps->block, w, h) * ps->block.size);
if (!packed)
return;
@@ -829,7 +807,7 @@ pipe_put_tile_rgba(struct pipe_context *pipe,
assert(0);
}
- pipe_put_tile_raw(pipe, ps, x, y, w, h, packed, w * ps->cpp);
+ pipe_put_tile_raw(pipe, ps, x, y, w, h, packed, 0);
FREE(packed);
}
@@ -846,14 +824,14 @@ pipe_get_tile_z(struct pipe_context *pipe,
{
struct pipe_screen *screen = pipe->screen;
const uint dstStride = w;
- void *map;
+ ubyte *map;
uint *pDest = z;
uint i, j;
if (pipe_clip_tile(x, y, &w, &h, ps))
return;
- map = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ);
+ map = (ubyte *)screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ);
if (!map) {
assert(0);
return;
@@ -863,11 +841,11 @@ pipe_get_tile_z(struct pipe_context *pipe,
case PIPE_FORMAT_Z32_UNORM:
{
const uint *pSrc
- = (const uint *)map + (y * ps->pitch + x);
+ = (const uint *)(map + y * ps->stride + x*4);
for (i = 0; i < h; i++) {
memcpy(pDest, pSrc, 4 * w);
pDest += dstStride;
- pSrc += ps->pitch;
+ pSrc += ps->stride/4;
}
}
break;
@@ -875,28 +853,28 @@ pipe_get_tile_z(struct pipe_context *pipe,
case PIPE_FORMAT_X8Z24_UNORM:
{
const uint *pSrc
- = (const uint *)map + (y * ps->pitch + x);
+ = (const uint *)(map + y * ps->stride + x*4);
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
/* convert 24-bit Z to 32-bit Z */
pDest[j] = (pSrc[j] << 8) | (pSrc[j] & 0xff);
}
pDest += dstStride;
- pSrc += ps->pitch;
+ pSrc += ps->stride/4;
}
}
break;
case PIPE_FORMAT_Z16_UNORM:
{
const ushort *pSrc
- = (const ushort *)map + (y * ps->pitch + x);
+ = (const ushort *)(map + y * ps->stride + x*2);
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
/* convert 16-bit Z to 32-bit Z */
pDest[j] = (pSrc[j] << 16) | pSrc[j];
}
pDest += dstStride;
- pSrc += ps->pitch;
+ pSrc += ps->stride/2;
}
}
break;
@@ -917,13 +895,13 @@ pipe_put_tile_z(struct pipe_context *pipe,
struct pipe_screen *screen = pipe->screen;
const uint srcStride = w;
const uint *pSrc = zSrc;
- void *map;
+ ubyte *map;
uint i, j;
if (pipe_clip_tile(x, y, &w, &h, ps))
return;
- map = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE);
+ map = (ubyte *)screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_WRITE);
if (!map) {
assert(0);
return;
@@ -932,10 +910,10 @@ pipe_put_tile_z(struct pipe_context *pipe,
switch (ps->format) {
case PIPE_FORMAT_Z32_UNORM:
{
- uint *pDest = (uint *) map + (y * ps->pitch + x);
+ uint *pDest = (uint *) (map + y * ps->stride + x*4);
for (i = 0; i < h; i++) {
memcpy(pDest, pSrc, 4 * w);
- pDest += ps->pitch;
+ pDest += ps->stride/4;
pSrc += srcStride;
}
}
@@ -943,26 +921,26 @@ pipe_put_tile_z(struct pipe_context *pipe,
case PIPE_FORMAT_S8Z24_UNORM:
case PIPE_FORMAT_X8Z24_UNORM:
{
- uint *pDest = (uint *) map + (y * ps->pitch + x);
+ uint *pDest = (uint *) (map + y * ps->stride + x*4);
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
/* convert 32-bit Z to 24-bit Z (0 stencil) */
pDest[j] = pSrc[j] >> 8;
}
- pDest += ps->pitch;
+ pDest += ps->stride/4;
pSrc += srcStride;
}
}
break;
case PIPE_FORMAT_Z16_UNORM:
{
- ushort *pDest = (ushort *) map + (y * ps->pitch + x);
+ ushort *pDest = (ushort *) (map + y * ps->stride + x*2);
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
/* convert 32-bit Z to 16-bit Z */
pDest[j] = pSrc[j] >> 16;
}
- pDest += ps->pitch;
+ pDest += ps->stride/2;
pSrc += srcStride;
}
}
diff --git a/src/gallium/auxiliary/util/p_util.c b/src/gallium/auxiliary/util/p_util.c
index 4e60b1b841..271be4edf1 100644
--- a/src/gallium/auxiliary/util/p_util.c
+++ b/src/gallium/auxiliary/util/p_util.c
@@ -32,6 +32,7 @@
#include "pipe/p_defines.h"
#include "pipe/p_util.h"
+#include "pipe/p_format.h"
/**
@@ -41,42 +42,109 @@
*/
void
pipe_copy_rect(ubyte * dst,
- unsigned cpp,
- unsigned dst_pitch,
+ const struct pipe_format_block *block,
+ unsigned dst_stride,
unsigned dst_x,
unsigned dst_y,
unsigned width,
unsigned height,
const ubyte * src,
- int src_pitch,
+ int src_stride,
unsigned src_x,
int src_y)
{
unsigned i;
- int src_pitch_pos = src_pitch < 0 ? -src_pitch : src_pitch;
+ int src_stride_pos = src_stride < 0 ? -src_stride : src_stride;
- assert(cpp > 0);
+ assert(block->size > 0);
+ assert(block->width > 0);
+ assert(block->height > 0);
assert(src_x >= 0);
assert(src_y >= 0);
assert(dst_x >= 0);
assert(dst_y >= 0);
- dst_pitch *= cpp;
- src_pitch *= cpp;
- src_pitch_pos *= cpp;
- dst += dst_x * cpp;
- src += src_x * cpp;
- dst += dst_y * dst_pitch;
- src += src_y * src_pitch_pos;
- width *= cpp;
+ dst_x /= block->width;
+ dst_y /= block->height;
+ width = (width + block->width - 1)/block->width;
+ height = (height + block->height - 1)/block->height;
+ src_x /= block->width;
+ src_y /= block->height;
+
+ dst += dst_x * block->size;
+ src += src_x * block->size;
+ dst += dst_y * dst_stride;
+ src += src_y * src_stride_pos;
+ width *= block->size;
- if (width == dst_pitch && width == src_pitch)
+ if (width == dst_stride && width == src_stride)
memcpy(dst, src, height * width);
else {
for (i = 0; i < height; i++) {
memcpy(dst, src, width);
- dst += dst_pitch;
- src += src_pitch;
+ dst += dst_stride;
+ src += src_stride;
}
}
}
+
+void
+pipe_fill_rect(ubyte * dst,
+ const struct pipe_format_block *block,
+ unsigned dst_stride,
+ unsigned dst_x,
+ unsigned dst_y,
+ unsigned width,
+ unsigned height,
+ uint32_t value)
+{
+ unsigned i, j;
+ unsigned width_size;
+
+ assert(block->size > 0);
+ assert(block->width > 0);
+ assert(block->height > 0);
+ assert(dst_x >= 0);
+ assert(dst_y >= 0);
+
+ dst_x /= block->width;
+ dst_y /= block->height;
+ width = (width + block->width - 1)/block->width;
+ height = (height + block->height - 1)/block->height;
+
+ dst += dst_x * block->size;
+ dst += dst_y * dst_stride;
+ width_size = width * block->size;
+
+ switch (block->size) {
+ case 1:
+ if(dst_stride == width_size)
+ memset(dst, (ubyte) value, height * width_size);
+ else {
+ for (i = 0; i < height; i++) {
+ memset(dst, (ubyte) value, width_size);
+ dst += dst_stride;
+ }
+ }
+ break;
+ case 2:
+ for (i = 0; i < height; i++) {
+ uint16_t *row = (uint16_t *)dst;
+ for (j = 0; j < width; j++)
+ *row++ = (uint16_t) value;
+ dst += dst_stride;
+ }
+ break;
+ case 4:
+ for (i = 0; i < height; i++) {
+ uint32_t *row = (uint32_t *)dst;
+ for (j = 0; j < width; j++)
+ *row++ = value;
+ dst += dst_stride;
+ }
+ break;
+ default:
+ assert(0);
+ break;
+ }
+}
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index 6555dcd588..ae779335dc 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -324,7 +324,7 @@ util_blit_pixels(struct blit_state *ctx,
texTemp.height[0] = srcH;
texTemp.depth[0] = 1;
texTemp.compressed = 0;
- texTemp.cpp = pf_get_size(src->format);
+ pf_get_block(src->format, &texTemp.block);
tex = screen->texture_create(screen, &texTemp);
if (!tex)
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index 7d71aefda9..5313a8008a 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -625,7 +625,9 @@ make_2d_mipmap(struct gen_mipmap_state *ctx,
struct pipe_winsys *winsys = pipe->winsys;
const uint zslice = 0;
uint dstLevel;
- const int bpt = pf_get_size(pt->format);
+
+ assert(pt->block.width == 1);
+ assert(pt->block.height == 1);
for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
const uint srcLevel = dstLevel - 1;
@@ -646,9 +648,9 @@ make_2d_mipmap(struct gen_mipmap_state *ctx,
reduce_2d(pt->format,
srcSurf->width, srcSurf->height,
- srcSurf->pitch * bpt, srcMap,
+ srcSurf->stride, srcMap,
dstSurf->width, dstSurf->height,
- dstSurf->pitch * bpt, dstMap);
+ dstSurf->stride, dstMap);
winsys->buffer_unmap(winsys, srcSurf->buffer);
winsys->buffer_unmap(winsys, dstSurf->buffer);
diff --git a/src/gallium/drivers/cell/ppu/cell_surface.c b/src/gallium/drivers/cell/ppu/cell_surface.c
index 18f3791924..5549eb496d 100644
--- a/src/gallium/drivers/cell/ppu/cell_surface.c
+++ b/src/gallium/drivers/cell/ppu/cell_surface.c
@@ -34,30 +34,6 @@
#include "cell_surface.h"
-/* Upload data to a rectangular sub-region. Lots of choices how to do this:
- *
- * - memcpy by span to current destination
- * - upload data as new buffer and blit
- *
- * Currently always memcpy.
- */
-static void
-cell_surface_data(struct pipe_context *pipe,
- struct pipe_surface *dst,
- unsigned dstx, unsigned dsty,
- const void *src, unsigned src_pitch,
- unsigned srcx, unsigned srcy,
- unsigned width, unsigned height)
-{
- pipe_copy_rect(pipe_surface_map(dst),
- dst->cpp,
- dst->pitch,
- dstx, dsty, width, height, src, src_pitch, srcx, srcy);
-
- pipe_surface_unmap(dst);
-}
-
-
static void
cell_surface_copy(struct pipe_context *pipe,
boolean do_flip,
@@ -70,12 +46,12 @@ cell_surface_copy(struct pipe_context *pipe,
assert( dst->cpp == src->cpp );
pipe_copy_rect(pipe_surface_map(dst),
- dst->cpp,
- dst->pitch,
+ &dst->block,
+ dst->stride,
dstx, dsty,
width, height,
pipe_surface_map(src),
- do_flip ? -src->pitch : src->pitch,
+ do_flip ? -src->stride : src->stride,
srcx, do_flip ? height - 1 - srcy : srcy);
pipe_surface_unmap(src);
@@ -86,7 +62,7 @@ cell_surface_copy(struct pipe_context *pipe,
static void *
get_pointer(struct pipe_surface *dst, void *dst_map, unsigned x, unsigned y)
{
- return (char *)dst_map + (y * dst->pitch + x) * dst->cpp;
+ return (char *)dst_map + y / dst->block.height * dst->stride + x / dst->block.width * dst->block.size;
}
@@ -106,38 +82,13 @@ cell_surface_fill(struct pipe_context *pipe,
unsigned i, j;
void *dst_map = pipe_surface_map(dst);
- assert(dst->pitch > 0);
- assert(width <= dst->pitch);
+ assert(dst->stride > 0);
- switch (dst->cpp) {
+ switch (dst->block.size) {
case 1:
- {
- ubyte *row = get_pointer(dst, dst_map, dstx, dsty);
- for (i = 0; i < height; i++) {
- memset(row, value, width);
- row += dst->pitch;
- }
- }
- break;
case 2:
- {
- ushort *row = get_pointer(dst, dst_map, dstx, dsty);
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j++)
- row[j] = (ushort) value;
- row += dst->pitch;
- }
- }
- break;
case 4:
- {
- unsigned *row = get_pointer(dst, dst_map, dstx, dsty);
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j++)
- row[j] = value;
- row += dst->pitch;
- }
- }
+ pipe_fill_rect(dst_map, &dst->block, dst->stride, dstx, dsty, width, height, value);
break;
case 8:
{
@@ -158,7 +109,7 @@ cell_surface_fill(struct pipe_context *pipe,
row[j*4+2] = val2;
row[j*4+3] = val3;
}
- row += dst->pitch * 4;
+ row += dst->stride/2;
}
}
break;
diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c
index 07717da8f6..533b64227d 100644
--- a/src/gallium/drivers/cell/ppu/cell_texture.c
+++ b/src/gallium/drivers/cell/ppu/cell_texture.c
@@ -65,12 +65,14 @@ cell_texture_layout(struct cell_texture * spt)
pt->width[level] = width;
pt->height[level] = height;
pt->depth[level] = depth;
+ pt->nblocksx[level] = pf_get_nblocksx(&pt->block, width);
+ pt->nblocksy[level] = pf_get_nblocksy(&pt->block, height);
spt->level_offset[level] = spt->buffer_size;
- spt->buffer_size += ((pt->compressed) ? MAX2(1, height/4) : height) *
+ spt->buffer_size += (pt->nblocksy[level] *
((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) *
- width * pt->cpp;
+ pt->nblocksx[level] * pt->block.size;
width = minify(width);
height = minify(height);
@@ -157,16 +159,18 @@ cell_get_tex_surface_screen(struct pipe_screen *screen,
assert(ps->winsys);
pipe_buffer_reference(ws, &ps->buffer, spt->buffer);
ps->format = pt->format;
- ps->cpp = pt->cpp;
+ ps->block = pt->block;
ps->width = pt->width[level];
ps->height = pt->height[level];
- ps->pitch = ps->width;
+ ps->nblocksx = pt->nblocksx[level];
+ ps->nblocksy = pt->nblocksy[level];
+ ps->stride = spt->stride[level];
ps->offset = spt->level_offset[level];
if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) {
ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) *
- (pt->compressed ? ps->height/4 : ps->height) *
- ps->width * ps->cpp;
+ ps->nblocksy *
+ ps->stride;
} else {
assert(face == 0);
assert(zslice == 0);
diff --git a/src/gallium/drivers/i915simple/i915_blit.c b/src/gallium/drivers/i915simple/i915_blit.c
index 22f91fab92..45fae4c999 100644
--- a/src/gallium/drivers/i915simple/i915_blit.c
+++ b/src/gallium/drivers/i915simple/i915_blit.c
@@ -47,8 +47,6 @@ i915_fill_blit(struct i915_context *i915,
{
unsigned BR13, CMD;
- dst_pitch *= (short) cpp;
-
switch (cpp) {
case 1:
case 2:
diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h
index 5d411a6648..c8db4f608c 100644
--- a/src/gallium/drivers/i915simple/i915_context.h
+++ b/src/gallium/drivers/i915simple/i915_context.h
@@ -188,9 +188,9 @@ struct i915_texture {
/* Derived from the above:
*/
- unsigned pitch;
- unsigned depth_pitch; /* per-image on i945? */
- unsigned total_height;
+ unsigned stride;
+ unsigned depth_stride; /* per-image on i945? */
+ unsigned total_nblocksy;
unsigned tiled;
diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c
index 19d968fd8b..9bd6f92323 100644
--- a/src/gallium/drivers/i915simple/i915_state_emit.c
+++ b/src/gallium/drivers/i915simple/i915_state_emit.c
@@ -211,7 +211,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
struct pipe_surface *depth_surface = i915->framebuffer.zsbuf;
if (cbuf_surface) {
- unsigned cpitch = (cbuf_surface->pitch * cbuf_surface->cpp);
+ unsigned cpitch = cbuf_surface->stride;
unsigned ctile = BUF_3D_USE_FENCE;
if (cbuf_surface->texture &&
((struct i915_texture*)(cbuf_surface->texture))->tiled) {
@@ -232,7 +232,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
/* What happens if no zbuf??
*/
if (depth_surface) {
- unsigned zpitch = (depth_surface->pitch * depth_surface->cpp);
+ unsigned zpitch = depth_surface->stride;
unsigned ztile = BUF_3D_USE_FENCE;
if (depth_surface->texture &&
((struct i915_texture*)(depth_surface->texture))->tiled) {
diff --git a/src/gallium/drivers/i915simple/i915_state_sampler.c b/src/gallium/drivers/i915simple/i915_state_sampler.c
index 379aff3846..7868f21ca6 100644
--- a/src/gallium/drivers/i915simple/i915_state_sampler.c
+++ b/src/gallium/drivers/i915simple/i915_state_sampler.c
@@ -242,7 +242,7 @@ i915_update_texture(struct i915_context *i915,
assert(depth);
format = translate_texture_format(pt->format);
- pitch = tex->pitch * pt->cpp;
+ pitch = tex->stride;
assert(format);
assert(pitch);
diff --git a/src/gallium/drivers/i915simple/i915_surface.c b/src/gallium/drivers/i915simple/i915_surface.c
index cc55a0910e..4430e81626 100644
--- a/src/gallium/drivers/i915simple/i915_surface.c
+++ b/src/gallium/drivers/i915simple/i915_surface.c
@@ -48,7 +48,9 @@ i915_surface_copy(struct pipe_context *pipe,
unsigned srcx, unsigned srcy, unsigned width, unsigned height)
{
assert( dst != src );
- assert( dst->cpp == src->cpp );
+ assert( dst->block.size == src->block.size );
+ assert( dst->block.width == src->block.height );
+ assert( dst->block.height == src->block.height );
if (0) {
void *dst_map = pipe->screen->surface_map( pipe->screen,
@@ -60,38 +62,30 @@ i915_surface_copy(struct pipe_context *pipe,
PIPE_BUFFER_USAGE_CPU_READ );
pipe_copy_rect(dst_map,
- dst->cpp,
- dst->pitch,
- dstx, dsty,
- width, height,
- src_map,
- do_flip ? -(int) src->pitch : src->pitch,
+ &dst->block,
+ dst->stride,
+ dstx, dsty,
+ width, height,
+ src_map,
+ do_flip ? -(int) src->stride : src->stride,
srcx, do_flip ? height - 1 - srcy : srcy);
pipe->screen->surface_unmap(pipe->screen, src);
pipe->screen->surface_unmap(pipe->screen, dst);
}
else {
+ assert(dst->block.width == 1);
+ assert(dst->block.height == 1);
i915_copy_blit( i915_context(pipe),
do_flip,
- dst->cpp,
- (short) src->pitch, src->buffer, src->offset,
- (short) dst->pitch, dst->buffer, dst->offset,
+ dst->block.size,
+ (short) src->stride, src->buffer, src->offset,
+ (short) dst->stride, dst->buffer, dst->offset,
(short) srcx, (short) srcy, (short) dstx, (short) dsty, (short) width, (short) height );
}
}
-/* Fill a rectangular sub-region. Need better logic about when to
- * push buffers into AGP - will currently do so whenever possible.
- */
-static void *
-get_pointer(struct pipe_surface *dst, void *dst_map, unsigned x, unsigned y)
-{
- return (char *)dst_map + (y * dst->pitch + x) * dst->cpp;
-}
-
-
static void
i915_surface_fill(struct pipe_context *pipe,
struct pipe_surface *dst,
@@ -99,53 +93,23 @@ i915_surface_fill(struct pipe_context *pipe,
unsigned width, unsigned height, unsigned value)
{
if (0) {
- unsigned i, j;
void *dst_map = pipe->screen->surface_map( pipe->screen,
dst,
PIPE_BUFFER_USAGE_CPU_WRITE );
-
- switch (dst->cpp) {
- case 1: {
- ubyte *row = get_pointer(dst, dst_map, dstx, dsty);
- for (i = 0; i < height; i++) {
- memset(row, value, width);
- row += dst->pitch;
- }
- }
- break;
- case 2: {
- ushort *row = get_pointer(dst, dst_map, dstx, dsty);
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j++)
- row[j] = (ushort) value;
- row += dst->pitch;
- }
- }
- break;
- case 4: {
- unsigned *row = get_pointer(dst, dst_map, dstx, dsty);
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j++)
- row[j] = value;
- row += dst->pitch;
- }
- }
- break;
- default:
- assert(0);
- break;
- }
+ pipe_fill_rect(dst_map, &dst->block, dst->stride, dstx, dsty, width, height, value);
pipe->screen->surface_unmap(pipe->screen, dst);
}
else {
+ assert(dst->block.width == 1);
+ assert(dst->block.height == 1);
i915_fill_blit( i915_context(pipe),
- dst->cpp,
- (short) dst->pitch,
+ dst->block.size,
+ (short) dst->stride,
dst->buffer, dst->offset,
- (short) dstx, (short) dsty,
- (short) width, (short) height,
+ (short) dstx, (short) dsty,
+ (short) width, (short) height,
value );
}
}
diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c
index b2e490c7db..2815e61345 100644
--- a/src/gallium/drivers/i915simple/i915_texture.c
+++ b/src/gallium/drivers/i915simple/i915_texture.c
@@ -109,6 +109,9 @@ i915_miptree_set_level_info(struct i915_texture *tex,
pt->width[level] = w;
pt->height[level] = h;
pt->depth[level] = d;
+
+ pt->nblocksx[level] = pf_get_nblocksx(&pt->block, w);
+ pt->nblocksy[level] = pf_get_nblocksy(&pt->block, h);
tex->nr_images[level] = nr_images;
@@ -140,7 +143,7 @@ i915_miptree_set_image_offset(struct i915_texture *tex,
assert(img < tex->nr_images[level]);
- tex->image_offset[level][img] = (x + y * tex->pitch);
+ tex->image_offset[level][img] = y * tex->stride + x * tex->base.block.size;
/*
printf("%s level %d img %d pos %d,%d image_offset %x\n",
@@ -162,7 +165,7 @@ i915_displaytarget_layout(struct i915_texture *tex)
{
struct pipe_texture *pt = &tex->base;
- if (pt->last_level > 0 || pt->cpp != 4)
+ if (pt->last_level > 0 || pt->block.size != 4)
return 0;
i915_miptree_set_level_info( tex, 0, 1,
@@ -172,18 +175,18 @@ i915_displaytarget_layout(struct i915_texture *tex)
i915_miptree_set_image_offset( tex, 0, 0, 0, 0 );
if (tex->base.width[0] >= 128) {
- tex->pitch = power_of_two(tex->base.width[0] * pt->cpp) / pt->cpp;
- tex->total_height = round_up(tex->base.height[0], 8);
+ tex->stride = power_of_two(tex->base.nblocksx[0] * pt->block.size);
+ tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8);
tex->tiled = 1;
} else {
- tex->pitch = round_up(tex->base.width[0], 64 / pt->cpp);
- tex->total_height = tex->base.height[0];
+ tex->stride = round_up(tex->base.nblocksx[0] * pt->block.size, 64);
+ tex->total_nblocksy = tex->base.nblocksy[0];
}
/*
printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
- tex->base.width[0], tex->base.height[0], pt->cpp,
- tex->pitch, tex->total_height, tex->pitch * tex->total_height * 4);
+ tex->base.width[0], tex->base.height[0], pt->block.size,
+ tex->stride, tex->total_nblocksy, tex->stride * tex->total_nblocksy);
*/
return 1;
@@ -193,12 +196,14 @@ static void
i945_miptree_layout_2d( struct i915_texture *tex )
{
struct pipe_texture *pt = &tex->base;
- int align_h = 2, align_w = 4;
+ const int align_x = 2, align_y = 4;
unsigned level;
unsigned x = 0;
unsigned y = 0;
unsigned width = pt->width[0];
unsigned height = pt->height[0];
+ unsigned nblocksx = pt->nblocksx[0];
+ unsigned nblocksy = pt->nblocksy[0];
#if 0 /* used for tiled display targets */
if (pt->last_level == 0 && pt->cpp == 4)
@@ -206,7 +211,7 @@ i945_miptree_layout_2d( struct i915_texture *tex )
return;
#endif
- tex->pitch = pt->width[0];
+ tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
/* May need to adjust pitch to accomodate the placement of
* the 2nd mipmap level. This occurs when the alignment
@@ -214,47 +219,43 @@ i945_miptree_layout_2d( struct i915_texture *tex )
* 2nd mipmap level out past the width of its parent.
*/
if (pt->last_level > 0) {
- unsigned mip1_width = align_int(minify(pt->width[0]), align_w)
- + minify(minify(pt->width[0]));
+ unsigned mip1_nblocksx
+ = align_int(pf_get_nblocksx(&pt->block, minify(width)), align_x)
+ + pf_get_nblocksx(&pt->block, minify(minify(width)));
- if (mip1_width > pt->width[0])
- tex->pitch = mip1_width;
+ if (mip1_nblocksx > nblocksx)
+ tex->stride = mip1_nblocksx * pt->block.size;
}
- /* Pitch must be a whole number of dwords, even though we
- * express it in texels.
+ /* Pitch must be a whole number of dwords
*/
- tex->pitch = align_int(tex->pitch * pt->cpp, 64) / pt->cpp;
- tex->total_height = 0;
+ tex->stride = align_int(tex->stride, 64);
+ tex->total_nblocksy = 0;
for (level = 0; level <= pt->last_level; level++) {
- unsigned img_height;
-
i915_miptree_set_level_info(tex, level, 1, width, height, 1);
i915_miptree_set_image_offset(tex, level, 0, x, y);
- if (pt->compressed)
- img_height = MAX2(1, height/4);
- else
- img_height = align_int(height, align_h);
-
+ nblocksy = align_int(nblocksy, align_y);
/* Because the images are packed better, the final offset
* might not be the maximal one:
*/
- tex->total_height = MAX2(tex->total_height, y + img_height);
+ tex->total_nblocksy = MAX2(tex->total_nblocksy, y + nblocksy);
/* Layout_below: step right after second mipmap level.
*/
if (level == 1) {
- x += align_int(width, align_w);
+ x += align_int(nblocksx, align_x);
}
else {
- y += img_height;
+ y += nblocksy;
}
width = minify(width);
height = minify(height);
+ nblocksx = pf_get_nblocksx(&pt->block, width);
+ nblocksy = pf_get_nblocksy(&pt->block, height);
}
}
@@ -264,15 +265,16 @@ i945_miptree_layout_cube(struct i915_texture *tex)
struct pipe_texture *pt = &tex->base;
unsigned level;
- const unsigned dim = pt->width[0];
+ const unsigned nblocks = pt->nblocksx[0];
unsigned face;
- unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0];
+ unsigned width = pt->width[0];
+ unsigned height = pt->height[0];
/*
printf("%s %i, %i\n", __FUNCTION__, pt->width[0], pt->height[0]);
*/
- assert(lvlWidth == lvlHeight); /* cubemap images are square */
+ assert(width == height); /* cubemap images are square */
/*
* XXX Should only be used for compressed formats. But lets
@@ -282,35 +284,32 @@ i945_miptree_layout_cube(struct i915_texture *tex)
* determined either by the old-style packing of cubemap faces,
* or the final row of 4x4, 2x2 and 1x1 faces below this.
*/
- if (dim > 32)
- tex->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp;
+ if (nblocks > 32)
+ tex->stride = round_up(nblocks * pt->block.size * 2, 4);
else
- tex->pitch = 14 * 8;
+ tex->stride = 14 * 8 * pt->block.size;
- /*
- * XXX The 4 is only needed for compressed formats. See above.
- */
- tex->total_height = dim * 4 + 4;
+ tex->total_nblocksy = nblocks * 4;
/* Set all the levels to effectively occupy the whole rectangular region.
*/
for (level = 0; level <= pt->last_level; level++) {
- i915_miptree_set_level_info(tex, level, 6, lvlWidth, lvlHeight, 1);
- lvlWidth /= 2;
- lvlHeight /= 2;
+ i915_miptree_set_level_info(tex, level, 6, width, height, 1);
+ width /= 2;
+ height /= 2;
}
for (face = 0; face < 6; face++) {
- unsigned x = initial_offsets[face][0] * dim;
- unsigned y = initial_offsets[face][1] * dim;
- unsigned d = dim;
+ unsigned x = initial_offsets[face][0] * nblocks;
+ unsigned y = initial_offsets[face][1] * nblocks;
+ unsigned d = nblocks;
#if 0 /* Fix and enable this code for compressed formats */
- if (dim == 4 && face >= 4) {
+ if (nblocks == 4 && face >= 4) {
y = tex->total_height - 4;
x = (face - 4) * 8;
}
- else if (dim < 4 && (face > 0)) {
+ else if (nblocks < 4 && (face > 0)) {
y = tex->total_height - 4;
x = face * 8;
}
@@ -369,28 +368,28 @@ i915_miptree_layout(struct i915_texture * tex)
switch (pt->target) {
case PIPE_TEXTURE_CUBE: {
- const unsigned dim = pt->width[0];
+ const unsigned nblocks = pt->nblocksx[0];
unsigned face;
- unsigned lvlWidth = pt->width[0], lvlHeight = pt->height[0];
+ unsigned width = pt->width[0], height = pt->height[0];
- assert(lvlWidth == lvlHeight); /* cubemap images are square */
+ assert(width == height); /* cubemap images are square */
/* double pitch for cube layouts */
- tex->pitch = ((dim * pt->cpp * 2 + 3) & ~3) / pt->cpp;
- tex->total_height = dim * 4;
+ tex->stride = round_up(nblocks * pt->block.size * 2, 4);
+ tex->total_nblocksy = nblocks * 4;
for (level = 0; level <= pt->last_level; level++) {
i915_miptree_set_level_info(tex, level, 6,
- lvlWidth, lvlHeight,
+ width, height,
1);
- lvlWidth /= 2;
- lvlHeight /= 2;
+ width /= 2;
+ height /= 2;
}
for (face = 0; face < 6; face++) {
- unsigned x = initial_offsets[face][0] * dim;
- unsigned y = initial_offsets[face][1] * dim;
- unsigned d = dim;
+ unsigned x = initial_offsets[face][0] * nblocks;
+ unsigned y = initial_offsets[face][1] * nblocks;
+ unsigned d = nblocks;
for (level = 0; level <= pt->last_level; level++) {
i915_miptree_set_image_offset(tex, level, face, x, y);
@@ -405,25 +404,29 @@ i915_miptree_layout(struct i915_texture * tex)
unsigned width = pt->width[0];
unsigned height = pt->height[0];
unsigned depth = pt->depth[0];
- unsigned stack_height = 0;
+ unsigned nblocksx = pt->nblocksx[0];
+ unsigned nblocksy = pt->nblocksy[0];
+ unsigned stack_nblocksy = 0;
/* Calculate the size of a single slice.
*/
- tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp;
+ tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
/* XXX: hardware expects/requires 9 levels at minimum.
*/
for (level = 0; level <= MAX2(8, pt->last_level);
level++) {
i915_miptree_set_level_info(tex, level, depth,
- width, height, depth);
+ width, height, depth);
- stack_height += MAX2(2, height);
+ stack_nblocksy += MAX2(2, nblocksy);
width = minify(width);
height = minify(height);
depth = minify(depth);
+ nblocksx = pf_get_nblocksx(&pt->block, width);
+ nblocksy = pf_get_nblocksy(&pt->block, height);
}
/* Fixup depth image_offsets:
@@ -433,7 +436,7 @@ i915_miptree_layout(struct i915_texture * tex)
unsigned i;
for (i = 0; i < depth; i++)
i915_miptree_set_image_offset(tex, level, i,
- 0, i * stack_height);
+ 0, i * stack_nblocksy);
depth = minify(depth);
}
@@ -443,33 +446,33 @@ i915_miptree_layout(struct i915_texture * tex)
* remarkable how wasteful of memory the i915 texture layouts
* are. They are largely fixed in the i945.
*/
- tex->total_height = stack_height * pt->depth[0];
+ tex->total_nblocksy = stack_nblocksy * pt->depth[0];
break;
}
default:{
unsigned width = pt->width[0];
unsigned height = pt->height[0];
- unsigned img_height;
+ unsigned nblocksx = pt->nblocksx[0];
+ unsigned nblocksy = pt->nblocksy[0];
- tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp;
- tex->total_height = 0;
+ tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
+ tex->total_nblocksy = 0;
for (level = 0; level <= pt->last_level; level++) {
i915_miptree_set_level_info(tex, level, 1,
- width, height, 1);
+ width, height, 1);
i915_miptree_set_image_offset(tex, level, 0,
- 0, tex->total_height);
+ 0, tex->total_nblocksy);
- if (pt->compressed)
- img_height = MAX2(1, height / 4);
- else
- img_height = (MAX2(2, height) + 1) & ~1;
+ nblocksy = round_up(MAX2(2, nblocksy), 2);
- tex->total_height += img_height;
+ tex->total_nblocksy += nblocksy;
width = minify(width);
height = minify(height);
+ nblocksx = pf_get_nblocksx(&pt->block, width);
+ nblocksy = pf_get_nblocksy(&pt->block, height);
}
break;
}
@@ -477,7 +480,7 @@ i915_miptree_layout(struct i915_texture * tex)
/*
DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
tex->pitch,
- tex->total_height, pt->cpp, tex->pitch * tex->total_height * pt->cpp);
+ tex->total_nblocksy, pt->block.size, tex->stride * tex->total_nblocksy);
*/
return TRUE;
@@ -498,14 +501,16 @@ i945_miptree_layout(struct i915_texture * tex)
unsigned width = pt->width[0];
unsigned height = pt->height[0];
unsigned depth = pt->depth[0];
+ unsigned nblocksx = pt->nblocksx[0];
+ unsigned nblocksy = pt->nblocksy[0];
unsigned pack_x_pitch, pack_x_nr;
unsigned pack_y_pitch;
- tex->pitch = ((pt->width[0] * pt->cpp + 3) & ~3) / pt->cpp;
- tex->total_height = 0;
+ tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
+ tex->total_nblocksy = 0;
- pack_y_pitch = MAX2(pt->height[0], 2);
- pack_x_pitch = tex->pitch;
+ pack_y_pitch = MAX2(pt->nblocksy[0], 2);
+ pack_x_pitch = tex->stride / pt->block.size;
pack_x_nr = 1;
for (level = 0; level <= pt->last_level; level++) {
@@ -515,11 +520,11 @@ i945_miptree_layout(struct i915_texture * tex)
unsigned q, j;
i915_miptree_set_level_info(tex, level, nr_images,
- width, height, depth);
+ width, height, depth);
for (q = 0; q < nr_images;) {
for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) {
- i915_miptree_set_image_offset(tex, level, q, x, y + tex->total_height);
+ i915_miptree_set_image_offset(tex, level, q, x, y + tex->total_nblocksy);
x += pack_x_pitch;
}
@@ -528,12 +533,12 @@ i945_miptree_layout(struct i915_texture * tex)
}
- tex->total_height += y;
+ tex->total_nblocksy += y;
if (pack_x_pitch > 4) {
pack_x_pitch >>= 1;
pack_x_nr <<= 1;
- assert(pack_x_pitch * pack_x_nr <= tex->pitch);
+ assert(pack_x_pitch * pack_x_nr * pt->block.size <= tex->stride);
}
if (pack_y_pitch > 2) {
@@ -543,6 +548,8 @@ i945_miptree_layout(struct i915_texture * tex)
width = minify(width);
height = minify(height);
depth = minify(depth);
+ nblocksx = pf_get_nblocksx(&pt->block, width);
+ nblocksy = pf_get_nblocksy(&pt->block, height);
}
break;
}
@@ -560,7 +567,7 @@ i945_miptree_layout(struct i915_texture * tex)
/*
DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
tex->pitch,
- tex->total_height, pt->cpp, tex->pitch * tex->total_height * pt->cpp);
+ tex->total_nblocksy, pt->block.size, tex->stride * tex->total_nblocksy);
*/
return TRUE;
@@ -582,6 +589,9 @@ i915_texture_create(struct pipe_screen *screen,
tex->base.refcount = 1;
tex->base.screen = screen;
+ tex->base.nblocksx[0] = pf_get_nblocksx(&tex->base.block, tex->base.width[0]);
+ tex->base.nblocksy[0] = pf_get_nblocksy(&tex->base.block, tex->base.height[0]);
+
if (i915screen->is_i945) {
if (!i945_miptree_layout(tex))
goto fail;
@@ -592,8 +602,8 @@ i915_texture_create(struct pipe_screen *screen,
tex->buffer = ws->buffer_create(ws, 64,
PIPE_BUFFER_USAGE_PIXEL,
- tex->pitch * tex->base.cpp *
- tex->total_height);
+ tex->stride *
+ tex->total_nblocksy);
if (!tex->buffer)
goto fail;
@@ -648,13 +658,13 @@ i915_get_tex_surface(struct pipe_screen *screen,
unsigned offset; /* in bytes */
if (pt->target == PIPE_TEXTURE_CUBE) {
- offset = tex->image_offset[level][face] * pt->cpp;
+ offset = tex->image_offset[level][face];
}
else if (pt->target == PIPE_TEXTURE_3D) {
- offset = tex->image_offset[level][zslice] * pt->cpp;
+ offset = tex->image_offset[level][zslice];
}
else {
- offset = tex->image_offset[level][0] * pt->cpp;
+ offset = tex->image_offset[level][0];
assert(face == 0);
assert(zslice == 0);
}
@@ -666,10 +676,12 @@ i915_get_tex_surface(struct pipe_screen *screen,
pipe_texture_reference(&ps->texture, pt);
pipe_buffer_reference(ws, &ps->buffer, tex->buffer);
ps->format = pt->format;
- ps->cpp = pt->cpp;
ps->width = pt->width[level];
ps->height = pt->height[level];
- ps->pitch = tex->pitch;
+ ps->block = pt->block;
+ ps->nblocksx = pt->nblocksx[level];
+ ps->nblocksy = pt->nblocksy[level];
+ ps->stride = tex->stride;
ps->offset = offset;
ps->usage = flags;
ps->status = PIPE_SURFACE_STATUS_DEFINED;
@@ -680,7 +692,7 @@ i915_get_tex_surface(struct pipe_screen *screen,
static struct pipe_texture *
i915_texture_blanket(struct pipe_screen * screen,
const struct pipe_texture *base,
- const unsigned *pitch,
+ const unsigned *stride,
struct pipe_buffer *buffer)
{
struct i915_texture *tex;
@@ -699,7 +711,7 @@ i915_texture_blanket(struct pipe_screen * screen,
tex->base = *base;
- tex->pitch = pitch[0];
+ tex->stride = stride[0];
i915_miptree_set_level_info(tex, 0, 1, base->width[0], base->height[0], 1);
i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
diff --git a/src/gallium/drivers/i965simple/SConscript b/src/gallium/drivers/i965simple/SConscript
index c0825c4de3..43fc2a4005 100644
--- a/src/gallium/drivers/i965simple/SConscript
+++ b/src/gallium/drivers/i965simple/SConscript
@@ -26,6 +26,7 @@ i965simple = env.ConvenienceLibrary(
'brw_gs_emit.c',
'brw_gs_state.c',
'brw_misc_state.c',
+ 'brw_screen.c',
'brw_sf.c',
'brw_sf_emit.c',
'brw_sf_state.c',
diff --git a/src/gallium/drivers/i965simple/brw_context.h b/src/gallium/drivers/i965simple/brw_context.h
index 8ac6b4e689..2cae7665f7 100644
--- a/src/gallium/drivers/i965simple/brw_context.h
+++ b/src/gallium/drivers/i965simple/brw_context.h
@@ -231,9 +231,9 @@ struct brw_texture {
/* Derived from the above:
*/
- unsigned pitch;
+ unsigned stride;
unsigned depth_pitch; /* per-image on i945? */
- unsigned total_height;
+ unsigned total_nblocksy;
unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS];
diff --git a/src/gallium/drivers/i965simple/brw_misc_state.c b/src/gallium/drivers/i965simple/brw_misc_state.c
index 925049ecc1..be812c5da9 100644
--- a/src/gallium/drivers/i965simple/brw_misc_state.c
+++ b/src/gallium/drivers/i965simple/brw_misc_state.c
@@ -224,7 +224,9 @@ static void upload_depthbuffer(struct brw_context *brw)
} else {
unsigned int format;
- switch (depth_surface->cpp) {
+ assert(depth_surface->block.width == 1);
+ assert(depth_surface->block.height == 1);
+ switch (depth_surface->block.size) {
case 2:
format = BRW_DEPTHFORMAT_D16_UNORM;
break;
@@ -239,7 +241,7 @@ static void upload_depthbuffer(struct brw_context *brw)
return;
}
- OUT_BATCH(((depth_surface->pitch * depth_surface->cpp) - 1) |
+ OUT_BATCH((depth_surface->stride - 1) |
(format << 18) |
(BRW_TILEWALK_YMAJOR << 26) |
// (depth_surface->region->tiled << 27) |
@@ -247,7 +249,7 @@ static void upload_depthbuffer(struct brw_context *brw)
OUT_RELOC(depth_surface->buffer,
PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE, 0);
OUT_BATCH((BRW_SURFACE_MIPMAPLAYOUT_BELOW << 1) |
- ((depth_surface->pitch - 1) << 6) |
+ ((depth_surface->stride/depth_surface->block.size - 1) << 6) |
((depth_surface->height - 1) << 19));
OUT_BATCH(0);
}
diff --git a/src/gallium/drivers/i965simple/brw_surface.c b/src/gallium/drivers/i965simple/brw_surface.c
index 3d98a2bf19..0be3dfc743 100644
--- a/src/gallium/drivers/i965simple/brw_surface.c
+++ b/src/gallium/drivers/i965simple/brw_surface.c
@@ -47,8 +47,10 @@ brw_surface_copy(struct pipe_context *pipe,
struct pipe_surface *src,
unsigned srcx, unsigned srcy, unsigned width, unsigned height)
{
- assert(dst != src);
- assert(dst->cpp == src->cpp);
+ assert( dst != src );
+ assert( dst->block.size == src->block.size );
+ assert( dst->block.width == src->block.height );
+ assert( dst->block.height == src->block.height );
if (0) {
void *dst_map = pipe->screen->surface_map( pipe->screen,
@@ -60,37 +62,30 @@ brw_surface_copy(struct pipe_context *pipe,
PIPE_BUFFER_USAGE_CPU_READ );
pipe_copy_rect(dst_map,
- dst->cpp,
- dst->pitch,
+ &dst->block,
+ dst->stride,
dstx, dsty,
width, height,
src_map,
- do_flip ? -(int) src->pitch : src->pitch,
+ do_flip ? -(int) src->stride : src->stride,
srcx, do_flip ? height - 1 - srcy : srcy);
pipe->screen->surface_unmap(pipe->screen, src);
pipe->screen->surface_unmap(pipe->screen, dst);
}
else {
+ assert(dst->block.width == 1);
+ assert(dst->block.height == 1);
brw_copy_blit(brw_context(pipe),
do_flip,
- dst->cpp,
- (short) src->pitch, src->buffer, src->offset, FALSE,
- (short) dst->pitch, dst->buffer, dst->offset, FALSE,
+ dst->block.size,
+ (short) src->stride/src->block.size, src->buffer, src->offset, FALSE,
+ (short) dst->stride/dst->block.size, dst->buffer, dst->offset, FALSE,
(short) srcx, (short) srcy, (short) dstx, (short) dsty,
(short) width, (short) height, PIPE_LOGICOP_COPY);
}
}
-/* Fill a rectangular sub-region. Need better logic about when to
- * push buffers into AGP - will currently do so whenever possible.
- */
-static void *
-get_pointer(struct pipe_surface *dst, void *dst_map, unsigned x, unsigned y)
-{
- return (char *)dst_map + (y * dst->pitch + x) * dst->cpp;
-}
-
static void
brw_surface_fill(struct pipe_context *pipe,
@@ -99,50 +94,20 @@ brw_surface_fill(struct pipe_context *pipe,
unsigned width, unsigned height, unsigned value)
{
if (0) {
- unsigned i, j;
void *dst_map = pipe->screen->surface_map( pipe->screen,
dst,
PIPE_BUFFER_USAGE_CPU_WRITE );
-
- switch (dst->cpp) {
- case 1: {
- ubyte *row = get_pointer(dst, dst_map, dstx, dsty);
- for (i = 0; i < height; i++) {
- memset(row, value, width);
- row += dst->pitch;
- }
- }
- break;
- case 2: {
- ushort *row = get_pointer(dst, dst_map, dstx, dsty);
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j++)
- row[j] = (ushort) value;
- row += dst->pitch;
- }
- }
- break;
- case 4: {
- unsigned *row = get_pointer(dst, dst_map, dstx, dsty);
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j++)
- row[j] = value;
- row += dst->pitch;
- }
- }
- break;
- default:
- assert(0);
- break;
- }
+ pipe_fill_rect(dst_map, &dst->block, dst->stride, dstx, dsty, width, height, value);
pipe->screen->surface_unmap(pipe->screen, dst);
}
else {
+ assert(dst->block.width == 1);
+ assert(dst->block.height == 1);
brw_fill_blit(brw_context(pipe),
- dst->cpp,
- (short) dst->pitch,
+ dst->block.size,
+ (short) dst->stride/dst->block.size,
dst->buffer, dst->offset, FALSE,
(short) dstx, (short) dsty,
(short) width, (short) height,
diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c
index 78ae0b1223..8c7725605b 100644
--- a/src/gallium/drivers/i965simple/brw_tex_layout.c
+++ b/src/gallium/drivers/i965simple/brw_tex_layout.c
@@ -81,7 +81,7 @@ static void intel_miptree_set_image_offset(struct brw_texture *tex,
assert(x == 0 && y == 0);
assert(img < tex->nr_images[level]);
- tex->image_offset[level][img] = (x + y * tex->pitch) * pt->cpp;
+ tex->image_offset[level][img] = y * tex->stride + x * pt->block.size;
}
static void intel_miptree_set_level_info(struct brw_texture *tex,
@@ -97,8 +97,11 @@ static void intel_miptree_set_level_info(struct brw_texture *tex,
pt->width[level] = w;
pt->height[level] = h;
pt->depth[level] = d;
+
+ pt->nblocksx[level] = pf_get_nblocksx(&pt->block, w);
+ pt->nblocksy[level] = pf_get_nblocksy(&pt->block, h);
- tex->level_offset[level] = (x + y * tex->pitch) * pt->cpp;
+ tex->level_offset[level] = y * tex->stride + x * tex->base.block.size;
tex->nr_images[level] = nr_images;
/*
@@ -123,77 +126,60 @@ static void intel_miptree_set_level_info(struct brw_texture *tex,
static void i945_miptree_layout_2d(struct brw_texture *tex)
{
struct pipe_texture *pt = &tex->base;
- unsigned align_h = 2, align_w = 4;
+ const int align_x = 2, align_y = 4;
unsigned level;
unsigned x = 0;
unsigned y = 0;
unsigned width = pt->width[0];
unsigned height = pt->height[0];
+ unsigned nblocksx = pt->nblocksx[0];
+ unsigned nblocksy = pt->nblocksy[0];
- tex->pitch = pt->width[0];
-
-#if 0
- if (pt->compressed) {
- align_w = intel_compressed_alignment(pt->internal_format);
- tex->pitch = ALIGN(pt->width[0], align_w);
- }
-#endif
+ tex->stride = align(pt->nblocksx[0] * pt->block.size, 4);
/* May need to adjust pitch to accomodate the placement of
- * the 2nd mipmap. This occurs when the alignment
+ * the 2nd mipmap level. This occurs when the alignment
* constraints of mipmap placement push the right edge of the
- * 2nd mipmap out past the width of its parent.
+ * 2nd mipmap level out past the width of its parent.
*/
if (pt->last_level > 0) {
- unsigned mip1_width;
-
- if (pt->compressed) {
- mip1_width = align(minify(pt->width[0]), align_w)
- + align(minify(minify(pt->width[0])), align_w);
- } else {
- mip1_width = align(minify(pt->width[0]), align_w)
- + minify(minify(pt->width[0]));
- }
+ unsigned mip1_nblocksx
+ = align_int(pf_get_nblocksx(&pt->block, minify(width)), align_x)
+ + pf_get_nblocksx(&pt->block, minify(minify(width)));
- if (mip1_width > tex->pitch) {
- tex->pitch = mip1_width;
- }
+ if (mip1_nblocksx > nblocksx)
+ tex->stride = mip1_nblocksx * pt->block.size;
}
- /* Pitch must be a whole number of dwords, even though we
- * express it in texels.
+ /* Pitch must be a whole number of dwords
*/
- tex->pitch = align(tex->pitch * pt->cpp, 4) / pt->cpp;
- tex->total_height = 0;
+ tex->stride = align_int(tex->stride, 64);
+ tex->total_nblocksy = 0;
for (level = 0; level <= pt->last_level; level++) {
- unsigned img_height;
-
intel_miptree_set_level_info(tex, level, 1, x, y, width,
height, 1);
- if (pt->compressed)
- img_height = MAX2(1, height/4);
- else
- img_height = align(height, align_h);
-
+ nblocksy = align_int(nblocksy, align_y);
/* Because the images are packed better, the final offset
* might not be the maximal one:
*/
- tex->total_height = MAX2(tex->total_height, y + img_height);
+ tex->total_nblocksy = MAX2(tex->total_nblocksy, y + nblocksy);
- /* Layout_below: step right after second mipmap.
+ /* Layout_below: step right after second mipmap level.
*/
if (level == 1) {
- x += align(width, align_w);
+ x += align_int(nblocksx, align_x);
}
else {
- y += img_height;
+ y += nblocksy;
}
width = minify(width);
height = minify(height);
+ nblocksx = pf_get_nblocksx(&pt->block, width);
+ nblocksy = pf_get_nblocksy(&pt->block, height);
}
}
@@ -210,26 +196,20 @@ static boolean brw_miptree_layout(struct brw_texture *tex)
unsigned width = pt->width[0];
unsigned height = pt->height[0];
unsigned depth = pt->depth[0];
+ unsigned nblocksx = pt->nblocksx[0];
+ unsigned nblocksy = pt->nblocksy[0];
unsigned pack_x_pitch, pack_x_nr;
unsigned pack_y_pitch;
unsigned level;
unsigned align_h = 2;
unsigned align_w = 4;
- tex->total_height = 0;
-#if 0
- if (pt->compressed) {
- align_w = intel_compressed_alignment(pt->internal_format);
- pt->pitch = align(width, align_w);
- pack_y_pitch = (height + 3) / 4;
- } else
-#endif
- {
- tex->pitch = align(pt->width[0] * pt->cpp, 4) / pt->cpp;
- pack_y_pitch = align(pt->height[0], align_h);
- }
+ tex->total_nblocksy = 0;
+
+ tex->stride = align(pt->nblocksx[0], 4);
+ pack_y_pitch = align(pt->nblocksy[0], align_h);
- pack_x_pitch = tex->pitch;
+ pack_x_pitch = tex->stride / pt->block.size;
pack_x_nr = 1;
for (level = 0; level <= pt->last_level; level++) {
@@ -239,7 +219,7 @@ static boolean brw_miptree_layout(struct brw_texture *tex)
uint q, j;
intel_miptree_set_level_info(tex, level, nr_images,
- 0, tex->total_height,
+ 0, tex->total_nblocksy,
width, height, depth);
for (q = 0; q < nr_images;) {
@@ -253,10 +233,12 @@ static boolean brw_miptree_layout(struct brw_texture *tex)
}
- tex->total_height += y;
+ tex->total_nblocksy += y;
width = minify(width);
height = minify(height);
depth = minify(depth);
+ nblocksx = pf_get_nblocksx(&pt->block, width);
+ nblocksy = pf_get_nblocksy(&pt->block, height);
if (pt->compressed) {
pack_y_pitch = (height + 3) / 4;
@@ -269,7 +251,7 @@ static boolean brw_miptree_layout(struct brw_texture *tex)
if (pack_x_pitch > 4) {
pack_x_pitch >>= 1;
pack_x_nr <<= 1;
- assert(pack_x_pitch * pack_x_nr <= tex->pitch);
+ assert(pack_x_pitch * pack_x_nr * pt->block.size <= tex->stride);
}
if (pack_y_pitch > 2) {
@@ -289,9 +271,9 @@ static boolean brw_miptree_layout(struct brw_texture *tex)
#if 0
PRINT("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
pt->pitch,
- pt->total_height,
- pt->cpp,
- pt->pitch * pt->total_height * pt->cpp );
+ pt->total_nblocksy,
+ pt->block.size,
+ pt->stride * pt->total_nblocksy );
#endif
return TRUE;
@@ -309,11 +291,14 @@ brw_texture_create_screen(struct pipe_screen *screen,
tex->base = *templat;
tex->base.refcount = 1;
+ tex->base.nblocksx[0] = pf_get_nblocksx(&tex->base.block, tex->base.width[0]);
+ tex->base.nblocksy[0] = pf_get_nblocksy(&tex->base.block, tex->base.height[0]);
+
if (brw_miptree_layout(tex))
tex->buffer = ws->buffer_create(ws, 64,
PIPE_BUFFER_USAGE_PIXEL,
- tex->pitch * tex->base.cpp *
- tex->total_height);
+ tex->stride *
+ tex->total_nblocksy);
if (!tex->buffer) {
FREE(tex);
@@ -370,10 +355,10 @@ brw_get_tex_surface_screen(struct pipe_screen *screen,
offset = tex->level_offset[level];
if (pt->target == PIPE_TEXTURE_CUBE) {
- offset += tex->image_offset[level][face] * pt->cpp;
+ offset += tex->image_offset[level][face];
}
else if (pt->target == PIPE_TEXTURE_3D) {
- offset += tex->image_offset[level][zslice] * pt->cpp;
+ offset += tex->image_offset[level][zslice];
}
else {
assert(face == 0);
@@ -386,10 +371,12 @@ brw_get_tex_surface_screen(struct pipe_screen *screen,
assert(ps->refcount);
pipe_buffer_reference(ws, &ps->buffer, tex->buffer);
ps->format = pt->format;
- ps->cpp = pt->cpp;
ps->width = pt->width[level];
ps->height = pt->height[level];
- ps->pitch = tex->pitch;
+ ps->block = pt->block;
+ ps->nblocksx = pt->nblocksx[level];
+ ps->nblocksy = pt->nblocksy[level];
+ ps->stride = tex->stride;
ps->offset = offset;
}
return ps;
diff --git a/src/gallium/drivers/i965simple/brw_wm_surface_state.c b/src/gallium/drivers/i965simple/brw_wm_surface_state.c
index 69e56dc8bd..1a326f9918 100644
--- a/src/gallium/drivers/i965simple/brw_wm_surface_state.c
+++ b/src/gallium/drivers/i965simple/brw_wm_surface_state.c
@@ -160,7 +160,7 @@ void brw_update_texture_surface( struct brw_context *brw,
surf.ss3.tile_walk = BRW_TILEWALK_XMAJOR;
surf.ss3.tiled_surface = 0; /* always zero */
- surf.ss3.pitch = tObj->pitch - 1;
+ surf.ss3.pitch = tObj->stride - 1;
surf.ss3.depth = tObj->base.depth[0] - 1;
surf.ss4.min_lod = 0;
@@ -197,7 +197,7 @@ static void upload_wm_surfaces(struct brw_context *brw )
memset(&surf, 0, sizeof(surf));
if (pipe_surface != NULL) {
- if (pipe_surface->cpp == 4)
+ if (pipe_surface->block.size == 4)
surf.ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
else
surf.ss0.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
@@ -210,7 +210,7 @@ static void upload_wm_surfaces(struct brw_context *brw )
surf.ss2.height = pipe_surface->height - 1;
surf.ss3.tile_walk = BRW_TILEWALK_XMAJOR;
surf.ss3.tiled_surface = 0;
- surf.ss3.pitch = (pipe_surface->pitch * pipe_surface->cpp) - 1;
+ surf.ss3.pitch = pipe_surface->stride - 1;
} else {
surf.ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
surf.ss0.surface_type = BRW_SURFACE_NULL;
diff --git a/src/gallium/drivers/softpipe/sp_surface.c b/src/gallium/drivers/softpipe/sp_surface.c
index 9fd48aeccc..7dc15c38d1 100644
--- a/src/gallium/drivers/softpipe/sp_surface.c
+++ b/src/gallium/drivers/softpipe/sp_surface.c
@@ -58,18 +58,20 @@ sp_surface_copy(struct pipe_context *pipe,
src,
PIPE_BUFFER_USAGE_CPU_READ );
- assert(dst->cpp == src->cpp);
+ assert(dst->block.size == src->block.size);
+ assert(dst->block.width == src->block.width);
+ assert(dst->block.height == src->block.height);
assert(src_map);
assert(dst_map);
/* If do_flip, invert src_y position and pass negative src stride */
pipe_copy_rect(dst_map,
- dst->cpp,
- dst->pitch,
+ &dst->block,
+ dst->stride,
dstx, dsty,
width, height,
src_map,
- do_flip ? -(int) src->pitch : src->pitch,
+ do_flip ? -(int) src->stride : src->stride,
srcx, do_flip ? src->height - 1 - srcy : srcy);
pipe->screen->surface_unmap(pipe->screen, src);
@@ -80,7 +82,7 @@ sp_surface_copy(struct pipe_context *pipe,
static void *
get_pointer(struct pipe_surface *dst, void *dst_map, unsigned x, unsigned y)
{
- return (char *)dst_map + (y * dst->pitch + x) * dst->cpp;
+ return (char *)dst_map + y / dst->block.height * dst->stride + x / dst->block.width * dst->block.size;
}
@@ -102,39 +104,14 @@ sp_surface_fill(struct pipe_context *pipe,
dst,
PIPE_BUFFER_USAGE_CPU_WRITE );
- assert(dst->pitch > 0);
- assert(width <= dst->pitch);
+ assert(dst->stride > 0);
- switch (dst->cpp) {
+ switch (dst->block.size) {
case 1:
- {
- ubyte *row = get_pointer(dst, dst_map, dstx, dsty);
- for (i = 0; i < height; i++) {
- memset(row, value, width);
- row += dst->pitch;
- }
- }
- break;
case 2:
- {
- ushort *row = get_pointer(dst, dst_map, dstx, dsty);
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j++)
- row[j] = (ushort) value;
- row += dst->pitch;
- }
- }
- break;
case 4:
- {
- unsigned *row = get_pointer(dst, dst_map, dstx, dsty);
- for (i = 0; i < height; i++) {
- for (j = 0; j < width; j++)
- row[j] = value;
- row += dst->pitch;
- }
- }
+ pipe_fill_rect(dst_map, &dst->block, dst->stride, dstx, dsty, width, height, value);
break;
case 8:
{
@@ -155,7 +132,7 @@ sp_surface_fill(struct pipe_context *pipe,
row[j*4+2] = val2;
row[j*4+3] = val3;
}
- row += dst->pitch * 4;
+ row += dst->stride/2;
}
}
break;
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index 2ef17a220b..4db045cdc3 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -71,13 +71,15 @@ softpipe_texture_layout(struct pipe_screen *screen,
pt->width[level] = width;
pt->height[level] = height;
pt->depth[level] = depth;
- spt->pitch[level] = width;
+ pt->nblocksx[level] = pf_get_nblocksx(&pt->block, width);
+ pt->nblocksy[level] = pf_get_nblocksy(&pt->block, height);
+ spt->stride[level] = pt->nblocksx[level]*pt->block.size;
spt->level_offset[level] = buffer_size;
- buffer_size += (((pt->compressed) ? MAX2(1, height/4) : height) *
+ buffer_size += (pt->nblocksy[level] *
((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) *
- width * pt->cpp);
+ spt->stride[level]);
width = minify(width);
height = minify(height);
@@ -121,7 +123,7 @@ softpipe_displaytarget_layout(struct pipe_screen *screen,
/* Now extract the goodies:
*/
spt->buffer = surf.buffer;
- spt->pitch[0] = surf.pitch;
+ spt->stride[0] = surf.stride;
return spt->buffer != NULL;
}
@@ -195,10 +197,12 @@ softpipe_get_tex_surface(struct pipe_screen *screen,
assert(ps->winsys);
pipe_buffer_reference(ws, &ps->buffer, spt->buffer);
ps->format = pt->format;
- ps->cpp = pt->cpp;
+ ps->block = pt->block;
ps->width = pt->width[level];
ps->height = pt->height[level];
- ps->pitch = spt->pitch[level];
+ ps->nblocksx = pt->nblocksx[level];
+ ps->nblocksy = pt->nblocksy[level];
+ ps->stride = spt->stride[level];
ps->offset = spt->level_offset[level];
ps->usage = usage;
@@ -228,8 +232,8 @@ softpipe_get_tex_surface(struct pipe_screen *screen,
if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) {
ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) *
- (pt->compressed ? ps->height/4 : ps->height) *
- ps->width * ps->cpp;
+ ps->nblocksy *
+ ps->stride;
}
else {
assert(face == 0);
diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h
index 0e1017632c..bf437a7c61 100644
--- a/src/gallium/drivers/softpipe/sp_texture.h
+++ b/src/gallium/drivers/softpipe/sp_texture.h
@@ -42,7 +42,7 @@ struct softpipe_texture
struct pipe_texture base;
unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS];
- unsigned long pitch[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned long stride[PIPE_MAX_TEXTURE_LEVELS];
/* The data is held here:
*/
diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h
index 00aa02311c..a2c6155d01 100644
--- a/src/gallium/include/pipe/p_format.h
+++ b/src/gallium/include/pipe/p_format.h
@@ -445,6 +445,103 @@ static INLINE uint pf_get_size( enum pipe_format format )
return pf_get_bits(format) / 8;
}
+/**
+ * Describe accurately the pixel format.
+ *
+ * The chars-per-pixel concept falls apart with compressed and yuv images, where
+ * more than one pixel are coded in a single data block. This structure
+ * describes that block.
+ *
+ * Simple pixel formats are effectively a 1x1xcpp block.
+ */
+struct pipe_format_block
+{
+ /** Block size in bytes */
+ unsigned size;
+
+ /** Block width in pixels */
+ unsigned width;
+
+ /** Block height in pixels */
+ unsigned height;
+};
+
+/**
+ * Describe pixel format's block.
+ *
+ * @sa http://msdn2.microsoft.com/en-us/library/ms796147.aspx
+ */
+static INLINE void
+pf_get_block(enum pipe_format format, struct pipe_format_block *block)
+{
+ switch(format) {
+ case PIPE_FORMAT_DXT1_RGBA:
+ case PIPE_FORMAT_DXT1_RGB:
+ block->size = 8;
+ block->width = 4;
+ block->height = 4;
+ break;
+ case PIPE_FORMAT_DXT3_RGBA:
+ case PIPE_FORMAT_DXT5_RGBA:
+ block->size = 16;
+ block->width = 4;
+ block->height = 4;
+ break;
+ case PIPE_FORMAT_YCBCR:
+ case PIPE_FORMAT_YCBCR_REV:
+ block->size = 4; /* 2*cpp */
+ block->width = 2;
+ block->height = 1;
+ break;
+ default:
+ block->size = pf_get_size(format);
+ block->width = 1;
+ block->height = 1;
+ break;
+ }
+}
+
+static INLINE unsigned
+pf_get_nblocksx(const struct pipe_format_block *block, unsigned x)
+{
+ return (x + block->width - 1)/block->width;
+}
+
+static INLINE unsigned
+pf_get_nblocksy(const struct pipe_format_block *block, unsigned y)
+{
+ return (y + block->height - 1)/block->height;
+}
+
+static INLINE unsigned
+pf_get_nblocks(const struct pipe_format_block *block, unsigned width, unsigned height)
+{
+ return pf_get_nblocksx(block, width)*pf_get_nblocksy(block, height);
+}
+
+static INLINE void
+pipe_rect_to_blocks(const struct pipe_format_block *block,
+ unsigned *width, unsigned *height,
+ unsigned *src_x, unsigned *src_y,
+ unsigned *dst_x, unsigned *dst_y)
+{
+ assert(block->size > 0);
+ assert(block->width > 0);
+ assert(block->height > 0);
+ if(width)
+ *width = pf_get_nblocksx(block, *width);
+ if(height)
+ *height = pf_get_nblocksy(block, *height);
+ if(src_x)
+ *src_x /= block->width;
+ if(src_y)
+ *src_y /= block->height;
+ if(dst_x)
+ *dst_x /= block->width;
+ if(dst_y)
+ *dst_y /= block->height;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index e7ee8c97ed..5546796936 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -267,14 +267,16 @@ struct pipe_surface
enum pipe_format format; /**< PIPE_FORMAT_x */
unsigned status; /**< PIPE_SURFACE_STATUS_x */
unsigned clear_value; /**< XXX may be temporary */
- unsigned cpp; /**< bytes per pixel */
unsigned width;
unsigned height;
- unsigned pitch; /**< in pixels */
+ struct pipe_format_block block;
+ unsigned nblocksx;
+ unsigned nblocksy;
+ unsigned stride; /**< in bytes */
unsigned layout; /**< PIPE_SURFACE_LAYOUT_x */
unsigned offset; /**< offset from start of buffer, in bytes */
unsigned refcount;
- unsigned usage; /**< PIPE_BUFFER_USAGE_* */
+ unsigned usage; /**< PIPE_BUFFER_USAGE_* */
struct pipe_winsys *winsys; /**< winsys which owns/created the surface */
@@ -303,10 +305,15 @@ struct pipe_texture
unsigned height[PIPE_MAX_TEXTURE_LEVELS];
unsigned depth[PIPE_MAX_TEXTURE_LEVELS];
- unsigned cpp:8;
+ struct pipe_format_block block;
+ unsigned nblocksx[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned nblocksy[PIPE_MAX_TEXTURE_LEVELS];
+
unsigned last_level:8; /**< Index of last mipmap level present/defined */
unsigned compressed:1;
-
+
+ unsigned nr_samples:8; /**< for multisampled surfaces, nr of samples */
+
unsigned tex_usage; /* PIPE_TEXTURE_USAGE_* */
/* These are also refcounted:
diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h
index cf2447822a..7dcdd28287 100644
--- a/src/gallium/include/pipe/p_util.h
+++ b/src/gallium/include/pipe/p_util.h
@@ -31,6 +31,7 @@
#include "p_config.h"
#include "p_compiler.h"
#include "p_debug.h"
+#include "p_format.h"
#include "p_pointer.h"
#include <math.h>
#include <stdarg.h>
@@ -401,11 +402,15 @@ static INLINE int align(int value, int alignment)
/* util/p_util.c
*/
-extern void pipe_copy_rect(ubyte * dst, unsigned cpp, unsigned dst_pitch,
- unsigned dst_x, unsigned dst_y, unsigned width,
- unsigned height, const ubyte * src,
- int src_pitch, unsigned src_x, int src_y);
-
+extern void pipe_copy_rect(ubyte * dst, const struct pipe_format_block *block,
+ unsigned dst_stride, unsigned dst_x, unsigned dst_y,
+ unsigned width, unsigned height, const ubyte * src,
+ int src_stride, unsigned src_x, int src_y);
+
+extern void
+pipe_fill_rect(ubyte * dst, const struct pipe_format_block *block,
+ unsigned dst_stride, unsigned dst_x, unsigned dst_y,
+ unsigned width, unsigned height, uint32_t value);
#if defined(_MSC_VER)
diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c
index 18427a4586..cfecebdb8c 100644
--- a/src/gallium/winsys/dri/intel/intel_screen.c
+++ b/src/gallium/winsys/dri/intel/intel_screen.c
@@ -78,10 +78,10 @@ intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys,
templat.last_level = 0;
templat.depth[0] = 1;
templat.format = PIPE_FORMAT_A8R8G8B8_UNORM;
- templat.cpp = intelScreen->front.cpp;
templat.width[0] = intelScreen->front.width;
templat.height[0] = intelScreen->front.height;
- pitch = intelScreen->front.pitch / intelScreen->front.cpp;
+ pf_get_block(templat.format, &templat.block);
+ pitch = intelScreen->front.pitch;
texture = screen->texture_blanket(screen,
&templat,
@@ -483,11 +483,13 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits,
uint8_t depth_bits_array[3];
uint8_t stencil_bits_array[3];
+ uint8_t msaa_samples_array[1];
depth_bits_array[0] = 0;
depth_bits_array[1] = depth_bits;
depth_bits_array[2] = depth_bits;
+ msaa_samples_array[0] = 0;
/* Just like with the accumulation buffer, always provide some modes
* with a stencil buffer. It will be a sw fallback, but some apps won't
@@ -521,7 +523,7 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits,
if (!driFillInModes(&m, fb_format, fb_type,
depth_bits_array, stencil_bits_array,
depth_buffer_factor, back_buffer_modes,
- back_buffer_factor, GLX_TRUE_COLOR)) {
+ back_buffer_factor, msaa_samples_array, 1, GLX_TRUE_COLOR)) {
fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
__LINE__);
return NULL;
@@ -529,7 +531,7 @@ intelFillInModes(unsigned pixel_bits, unsigned depth_bits,
if (!driFillInModes(&m, fb_format, fb_type,
depth_bits_array, stencil_bits_array,
depth_buffer_factor, back_buffer_modes,
- back_buffer_factor, GLX_DIRECT_COLOR)) {
+ back_buffer_factor, msaa_samples_array, 1, GLX_DIRECT_COLOR)) {
fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
__LINE__);
return NULL;
diff --git a/src/gallium/winsys/dri/intel/intel_swapbuffers.c b/src/gallium/winsys/dri/intel/intel_swapbuffers.c
index 7f3babd98e..f58da97c64 100644
--- a/src/gallium/winsys/dri/intel/intel_swapbuffers.c
+++ b/src/gallium/winsys/dri/intel/intel_swapbuffers.c
@@ -89,7 +89,7 @@ intelDisplaySurface(__DRIdrawablePrivate *dPriv,
const drm_clip_rect_t *pbox = dPriv->pClipRects;
const int pitch = intelScreen->front.pitch / intelScreen->front.cpp;
const int cpp = intelScreen->front.cpp;
- const int srcpitch = surf->pitch;
+ const int srcpitch = surf->stride / cpp;
int BR13, CMD;
int i;
diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c
index eeb15e30a9..83b8bb95b1 100644
--- a/src/gallium/winsys/egl_xlib/egl_xlib.c
+++ b/src/gallium/winsys/egl_xlib/egl_xlib.c
@@ -133,6 +133,10 @@ bitcount(unsigned int n)
static void
create_configs(_EGLDriver *drv, EGLDisplay dpy)
{
+ static const EGLint all_apis = (EGL_OPENGL_ES_BIT |
+ EGL_OPENGL_ES2_BIT |
+ EGL_OPENVG_BIT |
+ EGL_OPENGL_BIT);
_EGLDisplay *disp = _eglLookupDisplay(dpy);
XVisualInfo *visInfo, visTemplate;
int num_visuals, i;
@@ -172,6 +176,10 @@ create_configs(_EGLDriver *drv, EGLDisplay dpy)
SET_CONFIG_ATTRIB(config, EGL_STENCIL_SIZE, sbits);
SET_CONFIG_ATTRIB(config, EGL_NATIVE_VISUAL_ID, visid);
SET_CONFIG_ATTRIB(config, EGL_NATIVE_VISUAL_TYPE, vistype);
+ SET_CONFIG_ATTRIB(config, EGL_NATIVE_RENDERABLE, EGL_FALSE);
+ SET_CONFIG_ATTRIB(config, EGL_CONFORMANT, all_apis);
+ SET_CONFIG_ATTRIB(config, EGL_RENDERABLE_TYPE, all_apis);
+ SET_CONFIG_ATTRIB(config, EGL_SURFACE_TYPE, EGL_WINDOW_BIT);
_eglAddConfig(disp, config);
}
@@ -290,7 +298,7 @@ display_surface(struct pipe_winsys *pws,
ximage->data = data;
ximage->width = psurf->width;
ximage->height = psurf->height;
- ximage->bytes_per_line = psurf->pitch * psurf->cpp;
+ ximage->bytes_per_line = psurf->stride;
XPutImage(xsurf->Dpy, xsurf->Win, xsurf->Gc,
ximage, 0, 0, 0, 0, psurf->width, psurf->height);
diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.c b/src/gallium/winsys/egl_xlib/sw_winsys.c
index 28cca9e581..f4199e6f89 100644
--- a/src/gallium/winsys/egl_xlib/sw_winsys.c
+++ b/src/gallium/winsys/egl_xlib/sw_winsys.c
@@ -190,16 +190,16 @@ surface_alloc_storage(struct pipe_winsys *winsys,
surf->width = width;
surf->height = height;
surf->format = format;
- surf->cpp = pf_get_size(format);
- surf->pitch = round_up(width, alignment / surf->cpp);
+ pf_get_block(surf->format, &surf->block);
+ surf->nblocksx = pf_get_nblocksx(&surf->block, width);
+ surf->nblocksy = pf_get_nblocksy(&surf->block, height);
+ surf->stride = round_up(surf->nblocksx * surf->block.size, alignment);
surf->usage = flags;
- assert(surf->cpp >= 1);
- assert(surf->cpp <= 16);
assert(!surf->buffer);
surf->buffer = winsys->buffer_create(winsys, alignment,
PIPE_BUFFER_USAGE_PIXEL,
- surf->pitch * surf->cpp * height);
+ surf->stride * height);
if(!surf->buffer)
return -1;
diff --git a/src/gallium/winsys/gdi/wmesa.c b/src/gallium/winsys/gdi/wmesa.c
index 0b93f8c4c3..86b085ab84 100644
--- a/src/gallium/winsys/gdi/wmesa.c
+++ b/src/gallium/winsys/gdi/wmesa.c
@@ -477,13 +477,15 @@ wm_surface_alloc_storage(struct pipe_winsys *winsys,
surf->width = width;
surf->height = height;
surf->format = format;
- surf->cpp = pf_get_size(format);
- surf->pitch = round_up(width, alignment / surf->cpp);
+ pf_get_block(format, &surf->block);
+ surf->nblocksx = pf_get_nblocksx(&surf->block, width);
+ surf->nblocksy = pf_get_nblocksy(&surf->block, height);
+ surf->stride = round_up(surf->nblocksx * surf->block.size, alignment);
assert(!surf->buffer);
surf->buffer = winsys->buffer_create(winsys, alignment,
PIPE_BUFFER_USAGE_PIXEL,
- surf->pitch * surf->cpp * height);
+ surf->nblocksy * surf->stride);
if(!surf->buffer)
return -1;
diff --git a/src/gallium/winsys/xlib/SConscript b/src/gallium/winsys/xlib/SConscript
index 5e98a36abc..14a85ae0f2 100644
--- a/src/gallium/winsys/xlib/SConscript
+++ b/src/gallium/winsys/xlib/SConscript
@@ -3,7 +3,11 @@
Import('*')
-if env['platform'] == 'linux' and 'mesa' in env['statetrackers'] and not env['dri']:
+if env['platform'] == 'linux' \
+ and 'mesa' in env['statetrackers'] \
+ and 'softpipe' in env['drivers'] \
+ and 'i965simple' in env['drivers'] \
+ and not env['dri']:
env = env.Clone()
@@ -24,6 +28,7 @@ if env['platform'] == 'linux' and 'mesa' in env['statetrackers'] and not env['dr
drivers = [
softpipe,
+ i965simple
]
# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
diff --git a/src/gallium/winsys/xlib/brw_aub.c b/src/gallium/winsys/xlib/brw_aub.c
index 10eedd8402..6e814ce5d1 100644
--- a/src/gallium/winsys/xlib/brw_aub.c
+++ b/src/gallium/winsys/xlib/brw_aub.c
@@ -322,7 +322,10 @@ void brw_aub_dump_bmp( struct brw_aubfile *aubfile,
struct aub_dump_bmp db;
unsigned format;
- if (surface->cpp == 4)
+ assert(surface->block.width == 1);
+ assert(surface->block.height == 1);
+
+ if (surface->block.size == 4)
format = 0x7;
else
format = 0x3;
@@ -331,8 +334,8 @@ void brw_aub_dump_bmp( struct brw_aubfile *aubfile,
db.xmin = 0;
db.ymin = 0;
db.format = format;
- db.bpp = surface->cpp * 8;
- db.pitch = surface->pitch;
+ db.bpp = surface->block.size * 8;
+ db.pitch = surface->stride/surface->block.size;
db.xsize = surface->width;
db.ysize = surface->height;
db.addr = gtt_offset;
diff --git a/src/gallium/winsys/xlib/xm_winsys.c b/src/gallium/winsys/xlib/xm_winsys.c
index b14758f333..9225ee510d 100644
--- a/src/gallium/winsys/xlib/xm_winsys.c
+++ b/src/gallium/winsys/xlib/xm_winsys.c
@@ -364,9 +364,10 @@ xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf)
return;
}
-
if (XSHM_ENABLED(xm_buf) && (xm_buf->tempImage == NULL)) {
- alloc_shm_ximage(xm_buf, b, surf->pitch, surf->height);
+ assert(surf->block.width == 1);
+ assert(surf->block.height == 1);
+ alloc_shm_ximage(xm_buf, b, surf->stride/surf->block.size, surf->height);
}
ximage = (XSHM_ENABLED(xm_buf)) ? xm_buf->tempImage : b->tempImage;
@@ -386,7 +387,7 @@ xmesa_display_surface(XMesaBuffer b, const struct pipe_surface *surf)
/* update XImage's fields */
ximage->width = surf->width;
ximage->height = surf->height;
- ximage->bytes_per_line = surf->pitch * surf->cpp;
+ ximage->bytes_per_line = surf->stride;
XPutImage(b->xm_visual->display, b->drawable, b->gc,
ximage, 0, 0, 0, 0, surf->width, surf->height);
@@ -497,18 +498,21 @@ xm_surface_alloc_storage(struct pipe_winsys *winsys,
surf->width = width;
surf->height = height;
surf->format = format;
- surf->cpp = pf_get_size(format);
- surf->pitch = round_up(width, alignment / surf->cpp);
+ pf_get_block(format, &surf->block);
+ surf->nblocksx = pf_get_nblocksx(&surf->block, width);
+ surf->nblocksy = pf_get_nblocksy(&surf->block, height);
+ surf->stride = round_up(surf->nblocksx * surf->block.size, alignment);
surf->usage = flags;
-#ifdef GALLIUM_CELL /* XXX a bit of a hack */
- height = round_up(height, TILE_SIZE);
-#endif
-
assert(!surf->buffer);
surf->buffer = winsys->buffer_create(winsys, alignment,
PIPE_BUFFER_USAGE_PIXEL,
- surf->pitch * surf->cpp * height);
+#ifdef GALLIUM_CELL /* XXX a bit of a hack */
+ surf->stride * round_up(surf->nblocksy, TILE_SIZE));
+#else
+ surf->stride * surf->nblocksy);
+#endif
+
if(!surf->buffer)
return -1;
diff --git a/src/gallium/winsys/xlib/xm_winsys_aub.c b/src/gallium/winsys/xlib/xm_winsys_aub.c
index 77376099f0..7fc9debdd5 100644
--- a/src/gallium/winsys/xlib/xm_winsys_aub.c
+++ b/src/gallium/winsys/xlib/xm_winsys_aub.c
@@ -279,22 +279,25 @@ aub_i915_surface_alloc_storage(struct pipe_winsys *winsys,
unsigned flags,
unsigned tex_usage)
{
- const unsigned alignment = 64;
-
- surf->width = width;
- surf->height = height;
- surf->format = format;
- surf->cpp = pf_get_size(format);
- surf->pitch = round_up(width, alignment / surf->cpp);
-
- assert(!surf->buffer);
- surf->buffer = winsys->buffer_create(winsys, alignment,
- PIPE_BUFFER_USAGE_PIXEL,
- surf->pitch * surf->cpp * height);
+ const unsigned alignment = 64;
+
+ surf->width = width;
+ surf->height = height;
+ surf->format = format;
+ pf_get_block(format, &surf->block);
+ surf->nblocksx = pf_get_nblocksx(&surf->block, width);
+ surf->nblocksy = pf_get_nblocksy(&surf->block, height);
+ surf->stride = round_up(surf->nblocksx * surf->block.size, alignment);
+ surf->usage = flags;
+
+ assert(!surf->buffer);
+ surf->buffer = winsys->buffer_create(winsys, alignment,
+ PIPE_BUFFER_USAGE_PIXEL,
+ surf->stride * surf->nblocksy);
if(!surf->buffer)
- return -1;
+ return -1;
- return 0;
+ return 0;
}
static void
diff --git a/src/mesa/drivers/dri/common/utils.c b/src/mesa/drivers/dri/common/utils.c
index 94db319928..3cf2146dce 100644
--- a/src/mesa/drivers/dri/common/utils.c
+++ b/src/mesa/drivers/dri/common/utils.c
@@ -521,6 +521,9 @@ GLboolean driClipRectToFramebuffer( const GLframebuffer *buffer,
* \c GLX_SWAP_UNDEFINED_OML. See the
* GLX_OML_swap_method extension spec for more details.
* \param num_db_modes Number of entries in \c db_modes.
+ * \param msaa_samples Array of msaa sample count. 0 represents a visual
+ * without a multisample buffer.
+ * \param num_msaa_modes Number of entries in \c msaa_samples.
* \param visType GLX visual type. Usually either \c GLX_TRUE_COLOR or
* \c GLX_DIRECT_COLOR.
*
@@ -542,6 +545,7 @@ driFillInModes( __GLcontextModes ** ptr_to_modes,
const uint8_t * depth_bits, const uint8_t * stencil_bits,
unsigned num_depth_stencil_bits,
const GLenum * db_modes, unsigned num_db_modes,
+ const u_int8_t * msaa_samples, unsigned num_msaa_modes,
int visType )
{
static const uint8_t bits_table[3][4] = {
@@ -607,9 +611,7 @@ driFillInModes( __GLcontextModes ** ptr_to_modes,
const uint32_t * masks;
const int index = fb_type & 0x07;
__GLcontextModes * modes = *ptr_to_modes;
- unsigned i;
- unsigned j;
- unsigned k;
+ unsigned i, j, k, h;
if ( bytes_per_pixel[ index ] == 0 ) {
@@ -659,49 +661,54 @@ driFillInModes( __GLcontextModes ** ptr_to_modes,
for ( k = 0 ; k < num_depth_stencil_bits ; k++ ) {
for ( i = 0 ; i < num_db_modes ; i++ ) {
- for ( j = 0 ; j < 2 ; j++ ) {
-
- modes->redBits = bits[0];
- modes->greenBits = bits[1];
- modes->blueBits = bits[2];
- modes->alphaBits = bits[3];
- modes->redMask = masks[0];
- modes->greenMask = masks[1];
- modes->blueMask = masks[2];
- modes->alphaMask = masks[3];
- modes->rgbBits = modes->redBits + modes->greenBits
- + modes->blueBits + modes->alphaBits;
-
- modes->accumRedBits = 16 * j;
- modes->accumGreenBits = 16 * j;
- modes->accumBlueBits = 16 * j;
- modes->accumAlphaBits = (masks[3] != 0) ? 16 * j : 0;
- modes->visualRating = (j == 0) ? GLX_NONE : GLX_SLOW_CONFIG;
-
- modes->stencilBits = stencil_bits[k];
- modes->depthBits = depth_bits[k];
-
- modes->visualType = visType;
- modes->renderType = GLX_RGBA_BIT;
- modes->drawableType = GLX_WINDOW_BIT;
- modes->rgbMode = GL_TRUE;
-
- if ( db_modes[i] == GLX_NONE ) {
- modes->doubleBufferMode = GL_FALSE;
+ for ( h = 0 ; h < num_msaa_modes; h++ ) {
+ for ( j = 0 ; j < 2 ; j++ ) {
+
+ modes->redBits = bits[0];
+ modes->greenBits = bits[1];
+ modes->blueBits = bits[2];
+ modes->alphaBits = bits[3];
+ modes->redMask = masks[0];
+ modes->greenMask = masks[1];
+ modes->blueMask = masks[2];
+ modes->alphaMask = masks[3];
+ modes->rgbBits = modes->redBits + modes->greenBits
+ + modes->blueBits + modes->alphaBits;
+
+ modes->accumRedBits = 16 * j;
+ modes->accumGreenBits = 16 * j;
+ modes->accumBlueBits = 16 * j;
+ modes->accumAlphaBits = (masks[3] != 0) ? 16 * j : 0;
+ modes->visualRating = (j == 0) ? GLX_NONE : GLX_SLOW_CONFIG;
+
+ modes->stencilBits = stencil_bits[k];
+ modes->depthBits = depth_bits[k];
+
+ modes->visualType = visType;
+ modes->renderType = GLX_RGBA_BIT;
+ modes->drawableType = GLX_WINDOW_BIT;
+ modes->rgbMode = GL_TRUE;
+
+ if ( db_modes[i] == GLX_NONE ) {
+ modes->doubleBufferMode = GL_FALSE;
+ }
+ else {
+ modes->doubleBufferMode = GL_TRUE;
+ modes->swapMethod = db_modes[i];
+ }
+
+ modes->samples = msaa_samples[h];
+ modes->sampleBuffers = modes->samples ? 1 : 0;
+
+ modes->haveAccumBuffer = ((modes->accumRedBits +
+ modes->accumGreenBits +
+ modes->accumBlueBits +
+ modes->accumAlphaBits) > 0);
+ modes->haveDepthBuffer = (modes->depthBits > 0);
+ modes->haveStencilBuffer = (modes->stencilBits > 0);
+
+ modes = modes->next;
}
- else {
- modes->doubleBufferMode = GL_TRUE;
- modes->swapMethod = db_modes[i];
- }
-
- modes->haveAccumBuffer = ((modes->accumRedBits +
- modes->accumGreenBits +
- modes->accumBlueBits +
- modes->accumAlphaBits) > 0);
- modes->haveDepthBuffer = (modes->depthBits > 0);
- modes->haveStencilBuffer = (modes->stencilBits > 0);
-
- modes = modes->next;
}
}
}
diff --git a/src/mesa/drivers/dri/common/utils.h b/src/mesa/drivers/dri/common/utils.h
index 1067d0a8bf..20940c21b4 100644
--- a/src/mesa/drivers/dri/common/utils.h
+++ b/src/mesa/drivers/dri/common/utils.h
@@ -115,6 +115,7 @@ extern GLboolean driFillInModes( __GLcontextModes ** modes,
GLenum fb_format, GLenum fb_type,
const uint8_t * depth_bits, const uint8_t * stencil_bits,
unsigned num_depth_stencil_bits,
- const GLenum * db_modes, unsigned num_db_modes, int visType );
+ const GLenum * db_modes, unsigned num_db_modes,
+ const u_int8_t * msaa_samples, unsigned num_msaa_modes, int visType );
#endif /* DRI_DEBUG_H */
diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c
index f08f99d8e1..d62661e2b5 100644
--- a/src/mesa/main/arrayobj.c
+++ b/src/mesa/main/arrayobj.c
@@ -164,6 +164,15 @@ _mesa_initialize_array_object( GLcontext *ctx,
obj->VertexAttrib[i].Normalized = GL_FALSE;
}
+#if FEATURE_point_size_array
+ obj->PointSize.Type = GL_FLOAT;
+ obj->PointSize.Stride = 0;
+ obj->PointSize.StrideB = 0;
+ obj->PointSize.Ptr = NULL;
+ obj->PointSize.Enabled = GL_FALSE;
+ obj->PointSize.BufferObj = ctx->Array.NullBufferObj;
+#endif
+
#if FEATURE_ARB_vertex_buffer_object
/* Vertex array buffers */
obj->Vertex.BufferObj = ctx->Array.NullBufferObj;
diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c
index 6b4ad8eea3..9dc55d4e69 100644
--- a/src/mesa/main/enable.c
+++ b/src/mesa/main/enable.c
@@ -92,6 +92,13 @@ client_state(GLcontext *ctx, GLenum cap, GLboolean state)
flag = _NEW_ARRAY_COLOR1;
break;
+#if FEATURE_point_size_array
+ case GL_POINT_SIZE_ARRAY_OES:
+ var = &ctx->Array.ArrayObj->PointSize.Enabled;
+ flag = _NEW_ARRAY_POINT_SIZE;
+ break;
+#endif
+
#if FEATURE_NV_vertex_program
case GL_VERTEX_ATTRIB_ARRAY0_NV:
case GL_VERTEX_ATTRIB_ARRAY1_NV:
@@ -652,6 +659,7 @@ _mesa_set_enable(GLcontext *ctx, GLenum cap, GLboolean state)
case GL_EDGE_FLAG_ARRAY:
case GL_FOG_COORDINATE_ARRAY_EXT:
case GL_SECONDARY_COLOR_ARRAY_EXT:
+ case GL_POINT_SIZE_ARRAY_OES:
client_state( ctx, cap, state );
return;
@@ -1174,6 +1182,10 @@ _mesa_IsEnabled( GLenum cap )
case GL_SECONDARY_COLOR_ARRAY_EXT:
CHECK_EXTENSION(EXT_secondary_color);
return (ctx->Array.ArrayObj->SecondaryColor.Enabled != 0);
+#if FEATURE_point_size_array
+ case GL_POINT_SIZE_ARRAY_OES:
+ return (ctx->Array.ArrayObj->PointSize.Enabled != 0);
+#endif
/* GL_EXT_histogram */
case GL_HISTOGRAM:
diff --git a/src/mesa/main/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c
index e6c7c1040f..5f3def257d 100644
--- a/src/mesa/main/ffvertex_prog.c
+++ b/src/mesa/main/ffvertex_prog.c
@@ -63,6 +63,7 @@ struct state_key {
unsigned separate_specular:1;
unsigned fog_mode:2;
unsigned point_attenuated:1;
+ unsigned point_array:1;
unsigned texture_enabled_global:1;
unsigned fragprog_inputs_read:12;
@@ -264,6 +265,11 @@ static struct state_key *make_state_key( GLcontext *ctx )
if (ctx->Point._Attenuated)
key->point_attenuated = 1;
+#if FEATURE_point_size_array
+ if (ctx->Array.ArrayObj->PointSize.Enabled)
+ key->point_array = 1;
+#endif
+
if (ctx->Texture._TexGenEnabled ||
ctx->Texture._TexMatEnabled ||
ctx->Texture._EnabledUnits)
@@ -444,12 +450,18 @@ static void release_temps( struct tnl_program *p )
+/**
+ * \param input one of VERT_ATTRIB_x tokens.
+ */
static struct ureg register_input( struct tnl_program *p, GLuint input )
{
p->program->Base.InputsRead |= (1<<input);
return make_ureg(PROGRAM_INPUT, input);
}
+/**
+ * \param input one of VERT_RESULT_x tokens.
+ */
static struct ureg register_output( struct tnl_program *p, GLuint output )
{
p->program->Base.OutputsWritten |= (1<<output);
@@ -1518,7 +1530,10 @@ static void build_texture_transform( struct tnl_program *p )
}
-static void build_pointsize( struct tnl_program *p )
+/**
+ * Point size attenuation computation.
+ */
+static void build_atten_pointsize( struct tnl_program *p )
{
struct ureg eye = get_eye_position_z(p);
struct ureg state_size = register_param1(p, STATE_POINT_SIZE);
@@ -1555,13 +1570,24 @@ static void build_pointsize( struct tnl_program *p )
/**
* Emit constant point size.
*/
-static void constant_pointsize( struct tnl_program *p )
+static void build_constant_pointsize( struct tnl_program *p )
{
struct ureg state_size = register_param1(p, STATE_POINT_SIZE);
struct ureg out = register_output(p, VERT_RESULT_PSIZ);
emit_op1(p, OPCODE_MOV, out, WRITEMASK_X, state_size);
}
+/**
+ * Pass-though per-vertex point size, from user's point size array.
+ */
+static void build_array_pointsize( struct tnl_program *p )
+{
+ struct ureg in = register_input(p, VERT_ATTRIB_POINT_SIZE);
+ struct ureg out = register_output(p, VERT_RESULT_PSIZ);
+ emit_op1(p, OPCODE_MOV, out, WRITEMASK_X, in);
+}
+
+
static void build_tnl_program( struct tnl_program *p )
{ /* Emit the program, starting with modelviewproject:
*/
@@ -1589,10 +1615,12 @@ static void build_tnl_program( struct tnl_program *p )
build_texture_transform(p);
if (p->state->point_attenuated)
- build_pointsize(p);
+ build_atten_pointsize(p);
+ else if (p->state->point_array)
+ build_array_pointsize(p);
#if 0
else
- constant_pointsize(p);
+ build_constant_pointsize(p);
#endif
/* Finish up:
diff --git a/src/mesa/main/glheader.h b/src/mesa/main/glheader.h
index 57d7e60ad3..3131a356b8 100644
--- a/src/mesa/main/glheader.h
+++ b/src/mesa/main/glheader.h
@@ -167,6 +167,16 @@
#endif
+#ifndef GL_OES_point_size_array
+#define GL_POINT_SIZE_ARRAY_OES 0x8B9C
+#define GL_POINT_SIZE_ARRAY_TYPE_OES 0x898A
+#define GL_POINT_SIZE_ARRAY_STRIDE_OES 0x898B
+#define GL_POINT_SIZE_ARRAY_POINTER_OES 0x898C
+#define GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES 0x8B9F
+#endif
+
+
+
#if !defined(CAPI) && defined(WIN32) && !defined(BUILD_FOR_SNAP)
#define CAPI _cdecl
#endif
diff --git a/src/mesa/main/mfeatures.h b/src/mesa/main/mfeatures.h
index a305bbd605..c3c337ea90 100644
--- a/src/mesa/main/mfeatures.h
+++ b/src/mesa/main/mfeatures.h
@@ -49,6 +49,7 @@
#define FEATURE_fixedpt 0
#define FEATURE_histogram _HAVE_FULL_GL
#define FEATURE_pixel_transfer _HAVE_FULL_GL
+#define FEATURE_point_size_array 0
#define FEATURE_texgen _HAVE_FULL_GL
#define FEATURE_texture_fxt1 _HAVE_FULL_GL
#define FEATURE_texture_s3tc _HAVE_FULL_GL
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 8a6c84368a..0a065541e1 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -151,6 +151,7 @@ enum
VERT_ATTRIB_COLOR1 = 4,
VERT_ATTRIB_FOG = 5,
VERT_ATTRIB_COLOR_INDEX = 6,
+ VERT_ATTRIB_POINT_SIZE = 6, /*alias*/
VERT_ATTRIB_EDGEFLAG = 7,
VERT_ATTRIB_TEX0 = 8,
VERT_ATTRIB_TEX1 = 9,
@@ -1707,6 +1708,7 @@ struct gl_array_object
struct gl_client_array Index;
struct gl_client_array EdgeFlag;
struct gl_client_array TexCoord[MAX_TEXTURE_COORD_UNITS];
+ struct gl_client_array PointSize;
/*@}*/
/** Generic arrays for vertex programs/shaders */
@@ -2267,6 +2269,7 @@ struct gl_renderbuffer
GLubyte IndexBits;
GLubyte DepthBits;
GLubyte StencilBits;
+ GLubyte Samples; /**< Number of samples - 0 if not multisampled */
GLvoid *Data; /**< This may not be used by some kinds of RBs */
/* Used to wrap one renderbuffer around another: */
@@ -2748,6 +2751,7 @@ struct gl_matrix_stack
#define _NEW_ARRAY_FOGCOORD VERT_BIT_FOG
#define _NEW_ARRAY_INDEX VERT_BIT_COLOR_INDEX
#define _NEW_ARRAY_EDGEFLAG VERT_BIT_EDGEFLAG
+#define _NEW_ARRAY_POINT_SIZE VERT_BIT_COLOR_INDEX /* aliased */
#define _NEW_ARRAY_TEXCOORD_0 VERT_BIT_TEX0
#define _NEW_ARRAY_TEXCOORD_1 VERT_BIT_TEX1
#define _NEW_ARRAY_TEXCOORD_2 VERT_BIT_TEX2
@@ -2765,6 +2769,7 @@ struct gl_matrix_stack
/*@}*/
+
/**
* \name A bunch of flags that we think might be useful to drivers.
*
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index 4d1fdbf47c..315253d90a 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -448,7 +448,7 @@ _mesa_update_state_locked( GLcontext *ctx )
prog_flags |= (_NEW_TEXTURE | _NEW_FOG | _DD_NEW_SEPARATE_SPECULAR);
}
if (ctx->VertexProgram._MaintainTnlProgram) {
- prog_flags |= (_NEW_TEXTURE | _NEW_TEXTURE_MATRIX |
+ prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE | _NEW_TEXTURE_MATRIX |
_NEW_TRANSFORM | _NEW_POINT |
_NEW_FOG | _NEW_LIGHT |
_MESA_NEW_NEED_EYE_COORDS);
diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c
index 220db35855..50fe874556 100644
--- a/src/mesa/main/varray.c
+++ b/src/mesa/main/varray.c
@@ -468,6 +468,37 @@ _mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr)
}
+void GLAPIENTRY
+_mesa_PointSizePointer(GLenum type, GLsizei stride, const GLvoid *ptr)
+{
+ GLsizei elementSize;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (stride < 0) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glPointSizePointer(stride)" );
+ return;
+ }
+
+ switch (type) {
+ case GL_FLOAT:
+ elementSize = sizeof(GLfloat);
+ break;
+#if FEATURE_fixedpt
+ case GL_FIXED:
+ elementSize = sizeof(GLfixed);
+ break;
+#endif
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glPointSizePointer(type)" );
+ return;
+ }
+
+ update_array(ctx, &ctx->Array.ArrayObj->PointSize, _NEW_ARRAY_POINT_SIZE,
+ elementSize, 1, type, stride, GL_FALSE, ptr);
+}
+
+
#if FEATURE_NV_vertex_program
void GLAPIENTRY
_mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type,
diff --git a/src/mesa/main/varray.h b/src/mesa/main/varray.h
index ba91ecf5f6..f557940738 100644
--- a/src/mesa/main/varray.h
+++ b/src/mesa/main/varray.h
@@ -112,6 +112,10 @@ _mesa_SecondaryColorPointerEXT(GLint size, GLenum type,
extern void GLAPIENTRY
+_mesa_PointSizePointer(GLenum type, GLsizei stride, const GLvoid *ptr);
+
+
+extern void GLAPIENTRY
_mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type,
GLsizei stride, const GLvoid *pointer);
diff --git a/src/mesa/shader/prog_uniform.c b/src/mesa/shader/prog_uniform.c
index d96a916533..f57df3d86d 100644
--- a/src/mesa/shader/prog_uniform.c
+++ b/src/mesa/shader/prog_uniform.c
@@ -119,7 +119,7 @@ GLint
_mesa_lookup_uniform(const struct gl_uniform_list *list, const char *name)
{
GLuint i;
- for (i = 0; i < list->NumUniforms; i++) {
+ for (i = 0; list && i < list->NumUniforms; i++) {
if (!_mesa_strcmp(list->Uniforms[i].Name, name)) {
return i;
}
@@ -133,7 +133,7 @@ _mesa_longest_uniform_name(const struct gl_uniform_list *list)
{
GLint max = 0;
GLuint i;
- for (i = 0; i < list->NumUniforms; i++) {
+ for (i = 0; list && i < list->NumUniforms; i++) {
GLuint len = _mesa_strlen(list->Uniforms[i].Name);
if (len > (GLuint)max)
max = len;
diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c
index 97edb25400..a005c902e1 100644
--- a/src/mesa/shader/shader_api.c
+++ b/src/mesa/shader/shader_api.c
@@ -892,8 +892,10 @@ _mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
struct gl_shader_program *shProg
= _mesa_lookup_shader_program(ctx, program);
if (shProg) {
- if (location < shProg->Uniforms->NumUniforms) {
- GLuint progPos, i;
+ if (shProg->Uniforms &&
+ location >= 0 && location < shProg->Uniforms->NumUniforms) {
+ GLint progPos;
+ GLuint i;
const struct gl_program *prog = NULL;
progPos = shProg->Uniforms->Uniforms[location].VertPos;
@@ -915,11 +917,11 @@ _mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
}
}
else {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGetUniformfv(location)");
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(location)");
}
}
else {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGetUniformfv(program)");
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)");
}
}
diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c
index 8098d75e18..2283905662 100644
--- a/src/mesa/state_tracker/st_cb_accum.c
+++ b/src/mesa/state_tracker/st_cb_accum.c
@@ -66,15 +66,17 @@ acc_get_tile_rgba(struct pipe_context *pipe, struct pipe_surface *acc_ps,
uint x, uint y, uint w, uint h, float *p)
{
const enum pipe_format f = acc_ps->format;
- const int cpp = acc_ps->cpp;
+ const struct pipe_format_block b = acc_ps->block;
acc_ps->format = DEFAULT_ACCUM_PIPE_FORMAT;
- acc_ps->cpp = 8;
+ acc_ps->block.size = 8;
+ acc_ps->block.width = 1;
+ acc_ps->block.height = 1;
pipe_get_tile_rgba(pipe, acc_ps, x, y, w, h, p);
acc_ps->format = f;
- acc_ps->cpp = cpp;
+ acc_ps->block = b;
}
@@ -88,15 +90,17 @@ acc_put_tile_rgba(struct pipe_context *pipe, struct pipe_surface *acc_ps,
uint x, uint y, uint w, uint h, const float *p)
{
enum pipe_format f = acc_ps->format;
- const int cpp = acc_ps->cpp;
+ const struct pipe_format_block b = acc_ps->block;
acc_ps->format = DEFAULT_ACCUM_PIPE_FORMAT;
- acc_ps->cpp = 8;
+ acc_ps->block.size = 8;
+ acc_ps->block.width = 1;
+ acc_ps->block.height = 1;
pipe_put_tile_rgba(pipe, acc_ps, x, y, w, h, p);
acc_ps->format = f;
- acc_ps->cpp = cpp;
+ acc_ps->block = b;
}
@@ -111,7 +115,7 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
const GLint ypos = ctx->DrawBuffer->_Ymin;
const GLint width = ctx->DrawBuffer->_Xmax - xpos;
const GLint height = ctx->DrawBuffer->_Ymax - ypos;
- GLvoid *map;
+ GLubyte *map;
acc_ps = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0,
PIPE_BUFFER_USAGE_CPU_WRITE);
@@ -128,8 +132,7 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
GLshort a = FLOAT_TO_SHORT(ctx->Accum.ClearColor[3]);
int i, j;
for (i = 0; i < height; i++) {
- GLshort *dst = ((GLshort *) map
- + ((ypos + i) * acc_ps->pitch + xpos) * 4);
+ GLshort *dst = (GLshort *) (map + (ypos + i) * acc_ps->stride + xpos * 8);
for (j = 0; j < width; j++) {
dst[0] = r;
dst[1] = g;
@@ -157,7 +160,7 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias,
{
struct pipe_screen *screen = ctx->st->pipe->screen;
struct pipe_surface *acc_ps = acc_strb->surface;
- GLvoid *map;
+ GLubyte *map;
map = screen->surface_map(screen, acc_ps,
PIPE_BUFFER_USAGE_CPU_WRITE);
@@ -168,8 +171,7 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias,
{
int i, j;
for (i = 0; i < height; i++) {
- GLshort *acc = ((GLshort *) map
- + ((ypos + i) * acc_ps->pitch + xpos) * 4);
+ GLshort *acc = (GLshort *) (map + (ypos + i) * acc_ps->stride + xpos * 8);
for (j = 0; j < width * 4; j++) {
float val = SHORT_TO_FLOAT(acc[j]) * scale + bias;
acc[j] = FLOAT_TO_SHORT(val);
diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
index 6fa3cbd533..f3bc3b8584 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/src/mesa/state_tracker/st_cb_bitmap.c
@@ -341,9 +341,9 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
dest = screen->surface_map(screen, surface, PIPE_BUFFER_USAGE_CPU_WRITE);
/* Put image into texture surface */
- memset(dest, 0xff, height * surface->pitch);
+ memset(dest, 0xff, height * surface->stride);
unpack_bitmap(ctx->st, 0, 0, width, height, unpack, bitmap,
- dest, surface->pitch);
+ dest, surface->stride);
_mesa_unmap_bitmap_pbo(ctx, unpack);
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index d8f1d2367c..a7781f3ab2 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -382,7 +382,7 @@ make_texture(struct st_context *st,
mformat, /* gl_texture_format */
dest, /* dest */
0, 0, 0, /* dstX/Y/Zoffset */
- surface->pitch * cpp, /* dstRowStride, bytes */
+ surface->stride, /* dstRowStride, bytes */
&dstImageOffsets, /* dstImageOffsets */
width, height, 1, /* size */
format, type, /* src format/type */
@@ -786,13 +786,13 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
switch (ps->format) {
case PIPE_FORMAT_S8_UNORM:
{
- ubyte *dest = stmap + spanY * ps->pitch + spanX;
+ ubyte *dest = stmap + spanY * ps->stride + spanX;
memcpy(dest, values, spanWidth);
}
break;
case PIPE_FORMAT_S8Z24_UNORM:
{
- uint *dest = (uint *) stmap + spanY * ps->pitch + spanX;
+ uint *dest = (uint *) (stmap + spanY * ps->stride + spanX*4);
GLint k;
for (k = 0; k < spanWidth; k++) {
uint p = dest[k];
@@ -903,6 +903,9 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
psDraw = screen->get_tex_surface(screen, rbDraw->texture, 0, 0, 0,
PIPE_BUFFER_USAGE_CPU_WRITE);
+ assert(psDraw->block.width == 1);
+ assert(psDraw->block.height == 1);
+
/* map the stencil buffer */
drawMap = screen->surface_map(screen, psDraw, PIPE_BUFFER_USAGE_CPU_WRITE);
@@ -919,7 +922,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
y = ctx->DrawBuffer->Height - y - 1;
}
- dst = drawMap + (y * psDraw->pitch + dstx) * psDraw->cpp;
+ dst = drawMap + y * psDraw->stride + dstx * psDraw->block.size;
src = buffer + i * width;
switch (psDraw->format) {
diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index db25ddd615..7245798d0d 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -113,11 +113,12 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
template.target = PIPE_TEXTURE_2D;
template.compressed = 0;
- template.cpp = pf_get_size(template.format);
+ pf_get_block(template.format, &template.block);
template.width[0] = width;
template.height[0] = height;
template.depth[0] = 1;
template.last_level = 0;
+ template.nr_samples = rb->Samples;
if (pf_is_depth_stencil(template.format)) {
template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
@@ -171,10 +172,12 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
assert(strb->surface->buffer);
assert(strb->surface->format);
- assert(strb->surface->cpp);
+ assert(strb->surface->block.size);
+ assert(strb->surface->block.width);
+ assert(strb->surface->block.height);
assert(strb->surface->width == width);
assert(strb->surface->height == height);
- assert(strb->surface->pitch);
+ assert(strb->surface->stride);
return strb->surface != NULL;
@@ -247,7 +250,7 @@ st_new_renderbuffer(GLcontext *ctx, GLuint name)
* renderbuffer). The window system code determines the format.
*/
struct gl_renderbuffer *
-st_new_renderbuffer_fb(enum pipe_format format)
+st_new_renderbuffer_fb(enum pipe_format format, int samples)
{
struct st_renderbuffer *strb;
@@ -259,6 +262,7 @@ st_new_renderbuffer_fb(enum pipe_format format)
_mesa_init_renderbuffer(&strb->Base, 0);
strb->Base.ClassID = 0x4242; /* just a unique value */
+ strb->Base.Samples = samples;
strb->format = format;
switch (format) {
diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h
index 87b0734a0c..ff56001a4e 100644
--- a/src/mesa/state_tracker/st_cb_fbo.h
+++ b/src/mesa/state_tracker/st_cb_fbo.h
@@ -58,7 +58,7 @@ st_renderbuffer(struct gl_renderbuffer *rb)
extern struct gl_renderbuffer *
-st_new_renderbuffer_fb(enum pipe_format format);
+st_new_renderbuffer_fb(enum pipe_format format, int samples);
extern void
st_init_fbo_functions(struct dd_function_table *functions);
diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c
index c5193631a7..09d9c29e44 100644
--- a/src/mesa/state_tracker/st_cb_readpixels.c
+++ b/src/mesa/state_tracker/st_cb_readpixels.c
@@ -94,13 +94,13 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
switch (ps->format) {
case PIPE_FORMAT_S8_UNORM:
{
- const ubyte *src = stmap + srcY * ps->pitch + x;
+ const ubyte *src = stmap + srcY * ps->stride + x;
memcpy(values, src, width);
}
break;
case PIPE_FORMAT_S8Z24_UNORM:
{
- const uint *src = (uint *) stmap + srcY * ps->pitch + x;
+ const uint *src = (uint *) (stmap + srcY * ps->stride + x*4);
GLint k;
for (k = 0; k < width; k++) {
values[k] = src[k] >> 24;
@@ -109,7 +109,7 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
break;
case PIPE_FORMAT_Z24S8_UNORM:
{
- const uint *src = (uint *) stmap + srcY * ps->pitch + x;
+ const uint *src = (uint *) (stmap + srcY * ps->stride + x*4);
GLint k;
for (k = 0; k < width; k++) {
values[k] = src[k] & 0xff;
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index 7d52d1da1b..b9aa513d72 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -658,7 +658,7 @@ st_TexImage(GLcontext * ctx,
texImage->Data = st_texture_image_map(ctx->st, stImage, 0,
PIPE_BUFFER_USAGE_CPU_WRITE);
if (stImage->surface)
- dstRowStride = stImage->surface->pitch * stImage->surface->cpp;
+ dstRowStride = stImage->surface->stride;
}
else {
/* Allocate regular memory and store the image there temporarily. */
@@ -820,7 +820,7 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
*/
texImage->Data = st_texture_image_map(ctx->st, stImage, 0,
PIPE_BUFFER_USAGE_CPU_READ);
- texImage->RowStride = stImage->surface->pitch;
+ texImage->RowStride = stImage->surface->stride / stImage->pt->block.size;
}
else {
/* Otherwise, the image should actually be stored in
@@ -925,7 +925,7 @@ st_TexSubimage(GLcontext * ctx,
texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset,
PIPE_BUFFER_USAGE_CPU_WRITE);
if (stImage->surface)
- dstRowStride = stImage->surface->pitch * stImage->surface->cpp;
+ dstRowStride = stImage->surface->stride;
}
if (!texImage->Data) {
@@ -1425,9 +1425,11 @@ copy_image_data_to_texture(struct st_context *st,
stImage->face,
dstLevel,
stImage->base.Data,
- stImage->base.RowStride,
+ stImage->base.RowStride *
+ stObj->pt->block.size,
stImage->base.RowStride *
- stImage->base.Height);
+ stImage->base.Height *
+ stObj->pt->block.size);
_mesa_align_free(stImage->base.Data);
stImage->base.Data = NULL;
}
@@ -1477,6 +1479,7 @@ st_finalize_texture(GLcontext *ctx,
pipe_texture_reference(&stObj->pt, firstImage->pt);
}
+ /* FIXME: determine format block instead of cpp */
if (firstImage->base.IsCompressed) {
comp_byte = compressed_num_bytes(firstImage->base.TexFormat->MesaFormat);
cpp = comp_byte;
@@ -1497,7 +1500,9 @@ st_finalize_texture(GLcontext *ctx,
stObj->pt->width[0] != firstImage->base.Width2 ||
stObj->pt->height[0] != firstImage->base.Height2 ||
stObj->pt->depth[0] != firstImage->base.Depth2 ||
- stObj->pt->cpp != cpp ||
+ stObj->pt->block.size != cpp ||
+ stObj->pt->block.width != 1 ||
+ stObj->pt->block.height != 1 ||
stObj->pt->compressed != firstImage->base.IsCompressed) {
pipe_texture_release(&stObj->pt);
ctx->st->dirty.st |= ST_NEW_FRAMEBUFFER;
diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c
index 1b6e68c2a1..1994a1c826 100644
--- a/src/mesa/state_tracker/st_framebuffer.c
+++ b/src/mesa/state_tracker/st_framebuffer.c
@@ -51,27 +51,29 @@ st_create_framebuffer( const __GLcontextModes *visual,
{
struct st_framebuffer *stfb = CALLOC_STRUCT(st_framebuffer);
if (stfb) {
+ int samples = 0;
_mesa_initialize_framebuffer(&stfb->Base, visual);
+ if (visual->sampleBuffers) samples = visual->samples;
{
/* fake frontbuffer */
/* XXX allocation should only happen in the unusual case
it's actually needed */
struct gl_renderbuffer *rb
- = st_new_renderbuffer_fb(colorFormat);
+ = st_new_renderbuffer_fb(colorFormat, samples);
_mesa_add_renderbuffer(&stfb->Base, BUFFER_FRONT_LEFT, rb);
}
if (visual->doubleBufferMode) {
struct gl_renderbuffer *rb
- = st_new_renderbuffer_fb(colorFormat);
+ = st_new_renderbuffer_fb(colorFormat, samples);
_mesa_add_renderbuffer(&stfb->Base, BUFFER_BACK_LEFT, rb);
}
if (visual->depthBits == 24 && visual->stencilBits == 8) {
/* combined depth/stencil buffer */
struct gl_renderbuffer *depthStencilRb
- = st_new_renderbuffer_fb(depthFormat);
+ = st_new_renderbuffer_fb(depthFormat, samples);
/* note: bind RB to two attachment points */
_mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthStencilRb);
_mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, depthStencilRb);
@@ -82,26 +84,26 @@ st_create_framebuffer( const __GLcontextModes *visual,
if (visual->depthBits == 32) {
/* 32-bit depth buffer */
struct gl_renderbuffer *depthRb
- = st_new_renderbuffer_fb(depthFormat);
+ = st_new_renderbuffer_fb(depthFormat, samples);
_mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb);
}
else if (visual->depthBits == 24) {
/* 24-bit depth buffer, ignore stencil bits */
struct gl_renderbuffer *depthRb
- = st_new_renderbuffer_fb(depthFormat);
+ = st_new_renderbuffer_fb(depthFormat, samples);
_mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb);
}
else if (visual->depthBits > 0) {
/* 16-bit depth buffer */
struct gl_renderbuffer *depthRb
- = st_new_renderbuffer_fb(depthFormat);
+ = st_new_renderbuffer_fb(depthFormat, samples);
_mesa_add_renderbuffer(&stfb->Base, BUFFER_DEPTH, depthRb);
}
if (visual->stencilBits > 0) {
/* 8-bit stencil */
struct gl_renderbuffer *stencilRb
- = st_new_renderbuffer_fb(stencilFormat);
+ = st_new_renderbuffer_fb(stencilFormat, samples);
_mesa_add_renderbuffer(&stfb->Base, BUFFER_STENCIL, stencilRb);
}
}
@@ -109,7 +111,7 @@ st_create_framebuffer( const __GLcontextModes *visual,
if (visual->accumRedBits > 0) {
/* 16-bit/channel accum */
struct gl_renderbuffer *accumRb
- = st_new_renderbuffer_fb(DEFAULT_ACCUM_PIPE_FORMAT);
+ = st_new_renderbuffer_fb(DEFAULT_ACCUM_PIPE_FORMAT, 0); /* XXX accum isn't multisampled right? */
_mesa_add_renderbuffer(&stfb->Base, BUFFER_ACCUM, accumRb);
}
diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c
index 851f17c3b4..2fc00df429 100644
--- a/src/mesa/state_tracker/st_gen_mipmap.c
+++ b/src/mesa/state_tracker/st_gen_mipmap.c
@@ -137,10 +137,10 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target,
_mesa_generate_mipmap_level(target, datatype, comps,
0 /*border*/,
pt->width[srcLevel], pt->height[srcLevel], pt->depth[srcLevel],
- srcSurf->pitch * srcSurf->cpp, /* stride in bytes */
+ srcSurf->stride, /* stride in bytes */
srcData,
pt->width[dstLevel], pt->height[dstLevel], pt->depth[dstLevel],
- dstSurf->pitch * dstSurf->cpp, /* stride in bytes */
+ dstSurf->stride, /* stride in bytes */
dstData);
pipe_buffer_unmap(pipe, srcSurf->buffer);
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
index d450c30694..958096f68e 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -136,6 +136,10 @@ st_translate_vertex_program(struct st_context *st,
vs_input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
vs_input_semantic_index[slot] = 0;
break;
+ case VERT_ATTRIB_POINT_SIZE:
+ vs_input_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
+ vs_input_semantic_index[slot] = 0;
+ break;
case VERT_ATTRIB_TEX0:
case VERT_ATTRIB_TEX1:
case VERT_ATTRIB_TEX2:
diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c
index 9553b34e31..8222826e7a 100644
--- a/src/mesa/state_tracker/st_texture.c
+++ b/src/mesa/state_tracker/st_texture.c
@@ -98,7 +98,7 @@ st_texture_create(struct st_context *st,
pt.height[0] = height0;
pt.depth[0] = depth0;
pt.compressed = compress_byte ? 1 : 0;
- pt.cpp = pt.compressed ? compress_byte : st_sizeof_format(format);
+ pf_get_block(format, &pt.block);
pt.tex_usage = usage;
newtex = screen->texture_create(screen, &pt);
@@ -231,16 +231,19 @@ static void
st_surface_data(struct pipe_context *pipe,
struct pipe_surface *dst,
unsigned dstx, unsigned dsty,
- const void *src, unsigned src_pitch,
+ const void *src, unsigned src_stride,
unsigned srcx, unsigned srcy, unsigned width, unsigned height)
{
struct pipe_screen *screen = pipe->screen;
void *map = screen->surface_map(screen, dst, PIPE_BUFFER_USAGE_CPU_WRITE);
pipe_copy_rect(map,
- dst->cpp,
- dst->pitch,
- dstx, dsty, width, height, src, src_pitch, srcx, srcy);
+ &dst->block,
+ dst->stride,
+ dstx, dsty,
+ width, height,
+ src, src_stride,
+ srcx, srcy);
screen->surface_unmap(screen, dst);
}
@@ -254,34 +257,29 @@ st_texture_image_data(struct pipe_context *pipe,
GLuint face,
GLuint level,
void *src,
- GLuint src_row_pitch, GLuint src_image_pitch)
+ GLuint src_row_stride, GLuint src_image_stride)
{
struct pipe_screen *screen = pipe->screen;
GLuint depth = dst->depth[level];
GLuint i;
- GLuint height = 0;
const GLubyte *srcUB = src;
struct pipe_surface *dst_surface;
DBG("%s\n", __FUNCTION__);
for (i = 0; i < depth; i++) {
- height = dst->height[level];
- if(dst->compressed)
- height /= 4;
-
dst_surface = screen->get_tex_surface(screen, dst, face, level, i,
PIPE_BUFFER_USAGE_CPU_WRITE);
st_surface_data(pipe, dst_surface,
0, 0, /* dstx, dsty */
srcUB,
- src_row_pitch,
+ src_row_stride,
0, 0, /* source x, y */
- dst->width[level], height); /* width, height */
+ dst->width[level], dst->height[level]); /* width, height */
screen->tex_surface_release(screen, &dst_surface);
- srcUB += src_image_pitch * dst->cpp;
+ srcUB += src_image_stride;
}
}
diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c
index e3d2fc51cb..bf97956286 100644
--- a/src/mesa/vbo/vbo_exec_array.c
+++ b/src/mesa/vbo/vbo_exec_array.c
@@ -107,6 +107,10 @@ static void bind_array_obj( GLcontext *ctx )
exec->array.legacy_array[VERT_ATTRIB_COLOR1] = &ctx->Array.ArrayObj->SecondaryColor;
exec->array.legacy_array[VERT_ATTRIB_FOG] = &ctx->Array.ArrayObj->FogCoord;
exec->array.legacy_array[VERT_ATTRIB_COLOR_INDEX] = &ctx->Array.ArrayObj->Index;
+ if (ctx->Array.ArrayObj->PointSize.Enabled) {
+ /* this aliases COLOR_INDEX */
+ exec->array.legacy_array[VERT_ATTRIB_POINT_SIZE] = &ctx->Array.ArrayObj->PointSize;
+ }
exec->array.legacy_array[VERT_ATTRIB_EDGEFLAG] = &ctx->Array.ArrayObj->EdgeFlag;
for (i = 0; i < 8; i++)
diff --git a/src/mesa/x86-64/glapi_x86-64.S b/src/mesa/x86-64/glapi_x86-64.S
index cb34061b36..f8337ff93e 100644
--- a/src/mesa/x86-64/glapi_x86-64.S
+++ b/src/mesa/x86-64/glapi_x86-64.S
@@ -73,7 +73,7 @@ _x86_64_get_dispatch:
.p2align 4,,15
_x86_64_get_dispatch:
- movq _gl_DispatchTSD(%rip), %rdi
+ movq _gl_DispatchTSD@GOTPCREL(%rip), %rdi
jmp pthread_getspecific@PLT
#elif defined(THREADS)