diff options
author | Ben Skeggs <[email protected]> | 2008-06-29 12:16:13 +1000 |
---|---|---|
committer | Ben Skeggs <[email protected]> | 2008-06-29 12:16:13 +1000 |
commit | 01de2293d5449ab6ca1d99b007c9ea4f0037fef5 (patch) | |
tree | 8560aab576c3d8504f8d7935ab6fcd46ea35182e | |
parent | b831aa06dc0d099185bcaa180683ad10942feaa0 (diff) | |
parent | 9d94d133b019ef23ee03cc691fcb5602451604ae (diff) |
Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
68 files changed, 853 insertions, 661 deletions
diff --git a/SConstruct b/SConstruct index 4f19b16a0d2..a3bf5c5d579 100644 --- a/SConstruct +++ b/SConstruct @@ -44,7 +44,7 @@ else: opts = Options('config.py') common.AddOptions(opts) -opts.Add(ListOption('statetrackers', 'state_trackers to build', default_statetrackers, +opts.Add(ListOption('statetrackers', 'state trackers to build', default_statetrackers, ['mesa'])) opts.Add(ListOption('drivers', 'pipe drivers to build', default_drivers, ['softpipe', 'failover', 'i915simple', 'i965simple', 'cell'])) diff --git a/include/EGL/eglplatform.h b/include/EGL/eglplatform.h index 6a67a3d29ff..ab3b7398ca7 100644 --- a/include/EGL/eglplatform.h +++ b/include/EGL/eglplatform.h @@ -8,12 +8,14 @@ /* Windows calling convention boilerplate */ #if (defined(WIN32) || defined(_WIN32_WCE)) #ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#define WIN32_LEAN_AND_MEAN /* Exclude rarely-used stuff from Windows headers */ #endif #include <windows.h> #endif +#if !defined(_WIN32_WCE) #include <sys/types.h> +#endif /* Macros used in EGL function prototype declarations. * diff --git a/include/GLES/glplatform.h b/include/GLES/glplatform.h index afbec74ea5f..5ce0cbe84a2 100644 --- a/include/GLES/glplatform.h +++ b/include/GLES/glplatform.h @@ -45,14 +45,13 @@ extern "C" { * Definition of GL_API and GL_APIENTRY *-----------------------------------------------------------------------*/ -#define __GL_EXPORTS - #ifdef _WIN32 # ifdef __GL_EXPORTS # define GL_API __declspec(dllexport) # else # define GL_API __declspec(dllimport) # endif +# define GLAPIENTRY __stdcall #else # ifdef __GL_EXPORTS # define GL_API diff --git a/include/GLES2/gl2platform.h b/include/GLES2/gl2platform.h index 62798c34fe2..077571e4eaa 100644 --- a/include/GLES2/gl2platform.h +++ b/include/GLES2/gl2platform.h @@ -45,25 +45,22 @@ extern "C" { * Definition of GL_APICALL and GL_APIENTRY *-----------------------------------------------------------------------*/ -#if defined(_WIN32) || defined(__VC32__) /* Win32 */ -# if defined (_DLL_EXPORTS) +#ifdef _WIN32 +# ifdef __GL_EXPORTS # define GL_APICALL __declspec(dllexport) # else # define GL_APICALL __declspec(dllimport) # endif -#elif defined (__ARMCC_VERSION) /* ADS */ -# define GL_APICALL -#elif defined (__SYMBIAN32__) && defined (__GCC32__) /* Symbian GCC */ -# define GL_APICALL __declspec(dllexport) -#elif defined (__GNUC__) /* GCC dependencies (kludge) */ -# define GL_APICALL -#endif - -#if !defined (GL_APICALL) -# error Unsupported platform! +# define GLAPIENTRY __stdcall +#else +# ifdef __GL_EXPORTS +# define GL_APICALL +# else +# define GL_APICALL extern +# endif #endif -#define GL_APIENTRY +#define GL_APIENTRY #ifdef __cplusplus } diff --git a/scons/gallium.py b/scons/gallium.py index 217a1d61d36..c4a5c65be40 100644 --- a/scons/gallium.py +++ b/scons/gallium.py @@ -286,6 +286,13 @@ def generate(env): env.Append(CFLAGS = cflags) env.Append(CXXFLAGS = cflags) + # Assembler options + if gcc: + if env['machine'] == 'x86': + env.Append(ASFLAGS = ['-m32']) + if env['machine'] == 'x86_64': + env.Append(ASFLAGS = ['-m64']) + # Linker options linkflags = [] if gcc: diff --git a/src/egl/drivers/xdri/egl_xdri.c b/src/egl/drivers/xdri/egl_xdri.c index df80c6a1c4e..71d4f15371d 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 3ef0564a548..b19988f49a9 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 ecdebca5f12..3dd7ee19fd1 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 4087cf7a491..1f63f943656 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 5728757d2fb..ab603ff6e4d 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 4e60b1b8418..271be4edf14 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 6555dcd5882..ae779335dc0 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 7d71aefda9d..5313a8008a9 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 18f37919241..5549eb496d8 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 07717da8f6a..533b64227d6 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 22f91fab926..45fae4c9995 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 5d411a66486..c8db4f608c5 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 19d968fd8b6..9bd6f92323d 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 379aff38460..7868f21ca6a 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 cc55a0910ed..4430e816263 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 b2e490c7db1..2815e61345c 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 c0825c4de37..43fc2a40052 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 8ac6b4e6897..2cae7665f78 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 925049ecc19..be812c5da92 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 3d98a2bf199..0be3dfc7438 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 78ae0b1223e..8c7725605be 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 69e56dc8bd3..1a326f99186 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 9fd48aeccc5..7dc15c38d10 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 2ef17a220b4..4db045cdc3d 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 0e1017632c9..bf437a7c618 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 00aa02311c4..a2c6155d018 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 e7ee8c97ed7..55467969361 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 cf2447822ab..7dcdd282875 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 18427a4586f..cfecebdb8c7 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 7f3babd98ef..f58da97c64a 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 eeb15e30a92..83b8bb95b18 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 28cca9e581f..f4199e6f891 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 0b93f8c4c32..86b085ab841 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 5e98a36abc2..14a85ae0f2b 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 10eedd8402d..6e814ce5d11 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 b14758f3336..9225ee510df 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 77376099f0d..7fc9debdd54 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 94db3199287..3cf2146dceb 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 1067d0a8bfd..20940c21b4e 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 f08f99d8e17..d62661e2b52 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 6b4ad8eea35..9dc55d4e69f 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 e6c7c1040fa..5f3def257de 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 57d7e60ad3d..3131a356b86 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 a305bbd6059..c3c337ea904 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 8a6c84368a4..0a065541e1f 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 4d1fdbf47c4..315253d90a7 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 220db35855f..50fe8745563 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 ba91ecf5f6a..f557940738e 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 d96a916533b..f57df3d86dc 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 97edb254003..a005c902e19 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 8098d75e18f..2283905662f 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 6fa3cbd533c..f3bc3b85841 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 d8f1d2367c1..a7781f3ab2a 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 db25ddd6152..7245798d0da 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 87b0734a0c8..ff56001a4e1 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 c5193631a75..09d9c29e446 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 7d52d1da1b6..b9aa513d723 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 1b6e68c2a11..1994a1c8260 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 851f17c3b46..2fc00df4298 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 d450c306947..958096f68e6 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 9553b34e317..8222826e7a7 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 e3d2fc51cb7..bf97956286a 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 cb34061b36c..f8337ff93ee 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) |