diff options
author | marha <marha@users.sourceforge.net> | 2013-02-13 09:18:19 +0100 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2013-02-13 09:18:19 +0100 |
commit | ad7d3734fae59b63a1afe2d8e11411ac32a40f30 (patch) | |
tree | 80af4bcc936f46b31ba17a71905f20deeca066f5 | |
parent | c4583f59d8460f05ee211c2f8ed6208addfe3087 (diff) | |
parent | 8add148a4cf71b8bdab05a6b7e14824b5062da5e (diff) | |
download | vcxsrv-ad7d3734fae59b63a1afe2d8e11411ac32a40f30.tar.gz vcxsrv-ad7d3734fae59b63a1afe2d8e11411ac32a40f30.tar.bz2 vcxsrv-ad7d3734fae59b63a1afe2d8e11411ac32a40f30.zip |
Merge remote-tracking branch 'origin/released'
* origin/released:
mesa pixman xserver git update 13 Feb 2013
38 files changed, 1838 insertions, 1111 deletions
diff --git a/mesalib/docs/GL3.txt b/mesalib/docs/GL3.txt index 88621e330..025bef951 100644 --- a/mesalib/docs/GL3.txt +++ b/mesalib/docs/GL3.txt @@ -106,7 +106,7 @@ GL 4.1: GLSL 4.1 not started GL_ARB_ES2_compatibility DONE (i965, r300, r600) -GL_ARB_get_program_binary not started +GL_ARB_get_program_binary DONE (0 binary formats) GL_ARB_separate_shader_objects some infrastructure done GL_ARB_shader_precision not started GL_ARB_vertex_attrib_64bit not started @@ -125,7 +125,7 @@ GL_ARB_base_instance DONE (i965, nv50, nvc0, r60 GL_ARB_shader_image_load_store not started GL_ARB_conservative_depth DONE (softpipe) GL_ARB_shading_language_420pack not started -GL_ARB_internalformat_query not started +GL_ARB_internalformat_query DONE (i965, gallium) GL_ARB_map_buffer_alignment DONE (r300, r600, radeonsi) diff --git a/mesalib/docs/devinfo.html b/mesalib/docs/devinfo.html index 15a885fcf..d64171aee 100644 --- a/mesalib/docs/devinfo.html +++ b/mesalib/docs/devinfo.html @@ -217,7 +217,7 @@ Update <a href="index.html">docs/index.html</a>. <p> Tag the files with the release name (in the form <b>mesa-x.y</b>) -with: <code>git tag -a mesa-x.y</code> +with: <code>git tag -s mesa-x.y -m "Mesa x.y Release"</code> Then: <code>git push origin mesa-x.y</code> </p> @@ -226,6 +226,7 @@ Then: <code>git push origin mesa-x.y</code> <p> Make the distribution files. From inside the Mesa directory: <pre> + ./autogen.sh make tarballs </pre> @@ -242,15 +243,18 @@ compile everything, and run some demos to be sure everything works. <h3>Update the website and announce the release</h3> <p> -Follow the directions on SourceForge for creating a new "release" and -uploading the tarballs. +Make a new directory for the release on annarchy.freedesktop.org with: +<br> +<code> +mkdir /srv/ftp.freedesktop.org/pub/mesa/x.y +</code> </p> <p> Basically, to upload the tarball files with: <br> <code> -rsync -avP ssh Mesa*-X.Y.* USERNAME@frs.sourceforge.net:uploads/ +rsync -avP -e ssh MesaLib-x.y.* USERNAME@annarchy.freedesktop.org:/srv/ftp.freedesktop.org/pub/mesa/x.y/ </code> </p> diff --git a/mesalib/docs/index.html b/mesalib/docs/index.html index 5c922042c..5766df2f1 100644 --- a/mesalib/docs/index.html +++ b/mesalib/docs/index.html @@ -2,7 +2,7 @@ <html lang="en"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> - <title>Mesa News</title> + <title>The Mesa 3D Graphics Library</title> <link rel="stylesheet" type="text/css" href="mesa.css"> </head> <body> diff --git a/mesalib/docs/relnotes-9.1.html b/mesalib/docs/relnotes-9.1.html index 350ae2766..75e82ba99 100644 --- a/mesalib/docs/relnotes-9.1.html +++ b/mesalib/docs/relnotes-9.1.html @@ -72,6 +72,7 @@ Note: some of the new features are only available with certain drivers. <li>Removed swrast support for GL_NV_vertex_program</li> <li>Removed swrast support for GL_NV_fragment_program</li> <li>Removed OpenVMS support (unmaintained and broken)</li> +<li>Removed makedepend build dependency</li> </ul> </div> diff --git a/mesalib/docs/sourcedocs.html b/mesalib/docs/sourcedocs.html index 253e81c4a..0a0080dc6 100644 --- a/mesalib/docs/sourcedocs.html +++ b/mesalib/docs/sourcedocs.html @@ -25,7 +25,7 @@ produce cross-referenced documentation from the Mesa source code. <p> The Doxygen configuration files and generated files are not included in the normal Mesa distribution (they're very large). -To generate Doxygen documentation, download Mesa from CVS, change to +To generate Doxygen documentation, download Mesa from git, change to the <code>doxygen</code> directory and run <code>make</code>. </P> diff --git a/mesalib/docs/sourcetree.html b/mesalib/docs/sourcetree.html index deeda5dde..530c333c4 100644 --- a/mesalib/docs/sourcetree.html +++ b/mesalib/docs/sourcetree.html @@ -31,16 +31,17 @@ each directory. <ul> <li><b>docs</b> - EGL documentation <li><b>drivers</b> - EGL drivers - <li><b>glsl</b> - the GLSL compiler <li><b>main</b> - main EGL library implementation. This is where all the EGL API functions are implemented, like eglCreateContext(). </ul> - <li><b>mesa</b> - Main Mesa sources - <ul> + <li><b>glsl</b> - the GLSL compiler + <li><b>mapi</b> - Mesa APIs <li><b>glapi</b> - OpenGL API dispatch layer. This is where all the GL entrypoints like glClear, glBegin, etc. are generated, as well as the GL dispatch table. All GL function calls jump through the dispatch table to functions found in main/. + <li><b>mesa</b> - Main Mesa sources + <ul> <li><b>main</b> - The core Mesa code (mainly state management) <li><b>drivers</b> - Mesa drivers (not used with Gallium) <ul> @@ -56,15 +57,12 @@ each directory. </ul> <li><b>x11</b> - Xlib-based software driver <li><b>osmesa</b> - off-screen software driver - <li><b>glslcompiler</b> - a stand-alone GLSL compiler driver <li>XXX more </ul> <li><b>es</b> - OpenGL ES overlay, parallelly buildable with the core Mesa <li><b>math</b> - vertex array translation and transformation code (not used with Gallium) - <li><b>ppc</b> - Assembly code/optimizations for PPC systems - (not used with Gallium) - <li><b>shader</b> - Vertex/fragment shader and GLSL compiler code + <li><b>program</b> - Vertex/fragment shader and GLSL compiler code <li><b>sparc</b> - Assembly code/optimizations for SPARC systems (not used with Gallium) <li><b>state_tracker</b> - State tracker / driver for Gallium. This diff --git a/mesalib/docs/systems.html b/mesalib/docs/systems.html index 3659b9494..f84792863 100644 --- a/mesalib/docs/systems.html +++ b/mesalib/docs/systems.html @@ -25,8 +25,8 @@ software drivers. </p> <p> -The primary API is OpenGL but there's also support for OpenGL ES 1 -and ES 2, OpenVG and the EGL interface. +The primary API is OpenGL but there's also support for OpenGL ES 1, ES2 +and ES 3, OpenVG, OpenCL, VDPAU, XvMC and the EGL interface. </p> <p> diff --git a/mesalib/src/gallium/auxiliary/util/u_format.csv b/mesalib/src/gallium/auxiliary/util/u_format.csv index 1d274076b..f3925bb3c 100644 --- a/mesalib/src/gallium/auxiliary/util/u_format.csv +++ b/mesalib/src/gallium/auxiliary/util/u_format.csv @@ -360,3 +360,15 @@ PIPE_FORMAT_R16G16B16X16_SINT , plain, 1, 1, sp16, sp16, sp16, x16, xyz1, PIPE_FORMAT_R32G32B32X32_FLOAT , plain, 1, 1, f32, f32, f32, x32, xyz1, rgb PIPE_FORMAT_R32G32B32X32_UINT , plain, 1, 1, up32, up32, up32, x32, xyz1, rgb PIPE_FORMAT_R32G32B32X32_SINT , plain, 1, 1, sp32, sp32, sp32, x32, xyz1, rgb + +PIPE_FORMAT_R8A8_SNORM , plain, 1, 1, sn8 , sn8 , , , x00y, rgb +PIPE_FORMAT_R16A16_UNORM , plain, 1, 1, un16 , un16 , , , x00y, rgb +PIPE_FORMAT_R16A16_SNORM , plain, 1, 1, sn16 , sn16 , , , x00y, rgb +PIPE_FORMAT_R16A16_FLOAT , plain, 1, 1, f16 , f16 , , , x00y, rgb +PIPE_FORMAT_R32A32_FLOAT , plain, 1, 1, f32 , f32 , , , x00y, rgb +PIPE_FORMAT_R8A8_UINT , plain, 1, 1, up8 , up8 , , , x00y, rgb +PIPE_FORMAT_R8A8_SINT , plain, 1, 1, sp8 , sp8 , , , x00y, rgb +PIPE_FORMAT_R16A16_UINT , plain, 1, 1, up16 , up16 , , , x00y, rgb +PIPE_FORMAT_R16A16_SINT , plain, 1, 1, sp16 , sp16 , , , x00y, rgb +PIPE_FORMAT_R32A32_UINT , plain, 1, 1, up32 , up32 , , , x00y, rgb +PIPE_FORMAT_R32A32_SINT , plain, 1, 1, sp32 , sp32 , , , x00y, rgb diff --git a/mesalib/src/gallium/auxiliary/util/u_format.h b/mesalib/src/gallium/auxiliary/util/u_format.h index 63015dd50..00301265d 100644 --- a/mesalib/src/gallium/auxiliary/util/u_format.h +++ b/mesalib/src/gallium/auxiliary/util/u_format.h @@ -888,6 +888,123 @@ util_format_stencil_only(enum pipe_format format) } /** + * Converts PIPE_FORMAT_*I* to PIPE_FORMAT_*R*. + * This is identity for non-intensity formats. + */ +static INLINE enum pipe_format +util_format_intensity_to_red(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_I8_UNORM: + return PIPE_FORMAT_R8_UNORM; + case PIPE_FORMAT_I8_SNORM: + return PIPE_FORMAT_R8_SNORM; + case PIPE_FORMAT_I16_UNORM: + return PIPE_FORMAT_R16_UNORM; + case PIPE_FORMAT_I16_SNORM: + return PIPE_FORMAT_R16_SNORM; + case PIPE_FORMAT_I16_FLOAT: + return PIPE_FORMAT_R16_FLOAT; + case PIPE_FORMAT_I32_FLOAT: + return PIPE_FORMAT_R32_FLOAT; + case PIPE_FORMAT_I8_UINT: + return PIPE_FORMAT_R8_UINT; + case PIPE_FORMAT_I8_SINT: + return PIPE_FORMAT_R8_SINT; + case PIPE_FORMAT_I16_UINT: + return PIPE_FORMAT_R16_UINT; + case PIPE_FORMAT_I16_SINT: + return PIPE_FORMAT_R16_SINT; + case PIPE_FORMAT_I32_UINT: + return PIPE_FORMAT_R32_UINT; + case PIPE_FORMAT_I32_SINT: + return PIPE_FORMAT_R32_SINT; + default: + assert(!util_format_is_intensity(format)); + return format; + } +} + +/** + * Converts PIPE_FORMAT_*L* to PIPE_FORMAT_*R*. + * This is identity for non-luminance formats. + */ +static INLINE enum pipe_format +util_format_luminance_to_red(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_L8_UNORM: + return PIPE_FORMAT_R8_UNORM; + case PIPE_FORMAT_L8_SNORM: + return PIPE_FORMAT_R8_SNORM; + case PIPE_FORMAT_L16_UNORM: + return PIPE_FORMAT_R16_UNORM; + case PIPE_FORMAT_L16_SNORM: + return PIPE_FORMAT_R16_SNORM; + case PIPE_FORMAT_L16_FLOAT: + return PIPE_FORMAT_R16_FLOAT; + case PIPE_FORMAT_L32_FLOAT: + return PIPE_FORMAT_R32_FLOAT; + case PIPE_FORMAT_L8_UINT: + return PIPE_FORMAT_R8_UINT; + case PIPE_FORMAT_L8_SINT: + return PIPE_FORMAT_R8_SINT; + case PIPE_FORMAT_L16_UINT: + return PIPE_FORMAT_R16_UINT; + case PIPE_FORMAT_L16_SINT: + return PIPE_FORMAT_R16_SINT; + case PIPE_FORMAT_L32_UINT: + return PIPE_FORMAT_R32_UINT; + case PIPE_FORMAT_L32_SINT: + return PIPE_FORMAT_R32_SINT; + + case PIPE_FORMAT_LATC1_UNORM: + return PIPE_FORMAT_RGTC1_UNORM; + case PIPE_FORMAT_LATC1_SNORM: + return PIPE_FORMAT_RGTC1_SNORM; + + case PIPE_FORMAT_L4A4_UNORM: + /* XXX A4R4 is defined as x00y in u_format.csv */ + return PIPE_FORMAT_A4R4_UNORM; + + case PIPE_FORMAT_L8A8_UNORM: + return PIPE_FORMAT_R8A8_UNORM; + case PIPE_FORMAT_L8A8_SNORM: + return PIPE_FORMAT_R8A8_SNORM; + case PIPE_FORMAT_L16A16_UNORM: + return PIPE_FORMAT_R16A16_UNORM; + case PIPE_FORMAT_L16A16_SNORM: + return PIPE_FORMAT_R16A16_SNORM; + case PIPE_FORMAT_L16A16_FLOAT: + return PIPE_FORMAT_R16A16_FLOAT; + case PIPE_FORMAT_L32A32_FLOAT: + return PIPE_FORMAT_R32A32_FLOAT; + case PIPE_FORMAT_L8A8_UINT: + return PIPE_FORMAT_R8A8_UINT; + case PIPE_FORMAT_L8A8_SINT: + return PIPE_FORMAT_R8A8_SINT; + case PIPE_FORMAT_L16A16_UINT: + return PIPE_FORMAT_R16A16_UINT; + case PIPE_FORMAT_L16A16_SINT: + return PIPE_FORMAT_R16A16_SINT; + case PIPE_FORMAT_L32A32_UINT: + return PIPE_FORMAT_R32A32_UINT; + case PIPE_FORMAT_L32A32_SINT: + return PIPE_FORMAT_R32A32_SINT; + + /* We don't have compressed red-alpha variants for these. */ + case PIPE_FORMAT_LATC2_UNORM: + case PIPE_FORMAT_LATC2_SNORM: + return PIPE_FORMAT_NONE; + + default: + assert(!util_format_is_luminance(format) && + !util_format_is_luminance_alpha(format)); + return format; + } +} + +/** * Return the number of components stored. * Formats with block size != 1x1 will always have 1 component (the block). */ diff --git a/mesalib/src/gallium/auxiliary/util/u_surface.c b/mesalib/src/gallium/auxiliary/util/u_surface.c index 37f48154f..b948b46d2 100644 --- a/mesalib/src/gallium/auxiliary/util/u_surface.c +++ b/mesalib/src/gallium/auxiliary/util/u_surface.c @@ -421,10 +421,10 @@ util_clear_depth_stencil(struct pipe_context *pipe, else { uint32_t dst_mask; if (format == PIPE_FORMAT_Z24_UNORM_S8_UINT) - dst_mask = 0xffffff00; + dst_mask = 0x00ffffff; else { assert(format == PIPE_FORMAT_S8_UINT_Z24_UNORM); - dst_mask = 0xffffff; + dst_mask = 0xffffff00; } if (clear_flags & PIPE_CLEAR_DEPTH) dst_mask = ~dst_mask; diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp index 7d826e3a6..df1714850 100644 --- a/mesalib/src/glsl/glsl_parser_extras.cpp +++ b/mesalib/src/glsl/glsl_parser_extras.cpp @@ -47,6 +47,11 @@ glsl_compute_version_string(void *mem_ctx, bool is_es, unsigned version) version / 100, version % 100); } + +static unsigned known_desktop_glsl_versions[] = + { 110, 120, 130, 140, 150, 330, 400, 410, 420, 430 }; + + _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx, GLenum target, void *mem_ctx) : ctx(_ctx) @@ -97,22 +102,51 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx, this->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers; - const unsigned lowest_version = - (ctx->API == API_OPENGLES2) || ctx->Extensions.ARB_ES2_compatibility - ? 100 : 110; - const unsigned highest_version = - _mesa_is_desktop_gl(ctx) ? ctx->Const.GLSLVersion : 100; - char *supported = ralloc_strdup(this, ""); + /* Populate the list of supported GLSL versions */ + /* FINISHME: Once the OpenGL 3.0 'forward compatible' context or + * the OpenGL 3.2 Core context is supported, this logic will need + * change. Older versions of GLSL are no longer supported + * outside the compatibility contexts of 3.x. + */ + this->num_supported_versions = 0; + if (_mesa_is_desktop_gl(ctx)) { + for (unsigned i = 0; i < ARRAY_SIZE(known_desktop_glsl_versions); i++) { + if (known_desktop_glsl_versions[i] <= ctx->Const.GLSLVersion) { + this->supported_versions[this->num_supported_versions].ver + = known_desktop_glsl_versions[i]; + this->supported_versions[this->num_supported_versions].es = false; + this->num_supported_versions++; + } + } + } + if (ctx->API == API_OPENGLES2 || ctx->Extensions.ARB_ES2_compatibility) { + this->supported_versions[this->num_supported_versions].ver = 100; + this->supported_versions[this->num_supported_versions].es = true; + this->num_supported_versions++; + } + if (_mesa_is_gles3(ctx) || ctx->Extensions.ARB_ES3_compatibility) { + this->supported_versions[this->num_supported_versions].ver = 300; + this->supported_versions[this->num_supported_versions].es = true; + this->num_supported_versions++; + } + assert(this->num_supported_versions + <= ARRAY_SIZE(this->supported_versions)); - for (unsigned ver = lowest_version; ver <= highest_version; ver += 10) { - const char *const prefix = (ver == lowest_version) + /* Create a string for use in error messages to tell the user which GLSL + * versions are supported. + */ + char *supported = ralloc_strdup(this, ""); + for (unsigned i = 0; i < this->num_supported_versions; i++) { + unsigned ver = this->supported_versions[i].ver; + const char *const prefix = (i == 0) ? "" - : ((ver == highest_version) ? ", and " : ", "); + : ((i == this->num_supported_versions - 1) ? ", and " : ", "); + const char *const suffix = (this->supported_versions[i].es) ? " ES" : ""; - ralloc_asprintf_append(& supported, "%s%d.%02d%s", + ralloc_asprintf_append(& supported, "%s%u.%02u%s", prefix, ver / 100, ver % 100, - (ver == 100) ? " ES" : ""); + suffix); } this->supported_version_string = supported; @@ -198,58 +232,28 @@ _mesa_glsl_parse_state::process_version_directive(YYLTYPE *locp, int version, } } - bool supported = false; - - if (es_token_present) { - this->es_shader = true; - switch (version) { - case 100: + this->es_shader = es_token_present; + if (version == 100) { + if (es_token_present) { _mesa_glsl_error(locp, this, "GLSL 1.00 ES should be selected using " "`#version 100'\n"); - supported = this->ctx->API == API_OPENGLES2 || - this->ctx->Extensions.ARB_ES2_compatibility; - break; - case 300: - supported = _mesa_is_gles3(this->ctx) || - this->ctx->Extensions.ARB_ES3_compatibility; - break; - default: - supported = false; - break; - } - } else { - switch (version) { - case 100: + } else { this->es_shader = true; - supported = this->ctx->API == API_OPENGLES2 || - this->ctx->Extensions.ARB_ES2_compatibility; - break; - case 110: - case 120: - /* FINISHME: Once the OpenGL 3.0 'forward compatible' context or - * the OpenGL 3.2 Core context is supported, this logic will need - * change. Older versions of GLSL are no longer supported - * outside the compatibility contexts of 3.x. - */ - case 130: - case 140: - case 150: - case 330: - case 400: - case 410: - case 420: - supported = _mesa_is_desktop_gl(this->ctx) && - ((unsigned) version) <= this->ctx->Const.GLSLVersion; - break; - default: - supported = false; - break; } } this->language_version = version; + bool supported = false; + for (unsigned i = 0; i < this->num_supported_versions; i++) { + if (this->supported_versions[i].ver == (unsigned) version + && this->supported_versions[i].es == this->es_shader) { + supported = true; + break; + } + } + if (!supported) { _mesa_glsl_error(locp, this, "%s is not supported. " "Supported versions are: %s\n", diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h index 06969d2c3..1815bb9b9 100644 --- a/mesalib/src/glsl/glsl_parser_extras.h +++ b/mesalib/src/glsl/glsl_parser_extras.h @@ -152,6 +152,12 @@ struct _mesa_glsl_parse_state { unsigned uniform_block_array_size; struct gl_uniform_block *uniform_blocks; + unsigned num_supported_versions; + struct { + unsigned ver; + bool es; + } supported_versions[12]; + bool es_shader; unsigned language_version; enum _mesa_glsl_parser_targets target; diff --git a/mesalib/src/mesa/main/formats.c b/mesalib/src/mesa/main/formats.c index 176067d53..68ce98430 100644 --- a/mesalib/src/mesa/main/formats.c +++ b/mesalib/src/mesa/main/formats.c @@ -2870,6 +2870,7 @@ _mesa_format_matches_format_and_type(gl_format gl_format, return GL_FALSE; case MESA_FORMAT_RGBA8888: + case MESA_FORMAT_SRGBA8: if (format == GL_RGBA && type == GL_UNSIGNED_INT_8_8_8_8 && !swapBytes) return GL_TRUE; @@ -2917,6 +2918,7 @@ _mesa_format_matches_format_and_type(gl_format gl_format, return GL_FALSE; case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_SARGB8: if (format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8_REV && !swapBytes) return GL_TRUE; @@ -2951,6 +2953,7 @@ _mesa_format_matches_format_and_type(gl_format gl_format, return GL_FALSE; case MESA_FORMAT_RGB888: + case MESA_FORMAT_SRGB8: return format == GL_BGR && type == GL_UNSIGNED_BYTE && littleEndian; case MESA_FORMAT_BGR888: @@ -2987,6 +2990,7 @@ _mesa_format_matches_format_and_type(gl_format gl_format, case MESA_FORMAT_AL44: return GL_FALSE; case MESA_FORMAT_AL88: + case MESA_FORMAT_SLA8: return format == GL_LUMINANCE_ALPHA && type == GL_UNSIGNED_BYTE && littleEndian; case MESA_FORMAT_AL88_REV: return GL_FALSE; @@ -3002,22 +3006,25 @@ _mesa_format_matches_format_and_type(gl_format gl_format, case MESA_FORMAT_A8: return format == GL_ALPHA && type == GL_UNSIGNED_BYTE; case MESA_FORMAT_A16: - return format == GL_ALPHA && type == GL_UNSIGNED_SHORT && - littleEndian && !swapBytes; + return format == GL_ALPHA && type == GL_UNSIGNED_SHORT && !swapBytes; case MESA_FORMAT_L8: + case MESA_FORMAT_SL8: return format == GL_LUMINANCE && type == GL_UNSIGNED_BYTE; case MESA_FORMAT_L16: - return format == GL_LUMINANCE && type == GL_UNSIGNED_SHORT && - littleEndian && !swapBytes; + return format == GL_LUMINANCE && type == GL_UNSIGNED_SHORT && !swapBytes; case MESA_FORMAT_I8: return format == GL_INTENSITY && type == GL_UNSIGNED_BYTE; case MESA_FORMAT_I16: - return format == GL_INTENSITY && type == GL_UNSIGNED_SHORT && - littleEndian && !swapBytes; + return format == GL_INTENSITY && type == GL_UNSIGNED_SHORT && !swapBytes; case MESA_FORMAT_YCBCR: + return format == GL_YCBCR_MESA && + ((type == GL_UNSIGNED_SHORT_8_8_MESA && littleEndian != swapBytes) || + (type == GL_UNSIGNED_SHORT_8_8_REV_MESA && littleEndian == swapBytes)); case MESA_FORMAT_YCBCR_REV: - return GL_FALSE; + return format == GL_YCBCR_MESA && + ((type == GL_UNSIGNED_SHORT_8_8_MESA && littleEndian == swapBytes) || + (type == GL_UNSIGNED_SHORT_8_8_REV_MESA && littleEndian != swapBytes)); case MESA_FORMAT_R8: return format == GL_RED && type == GL_UNSIGNED_BYTE; @@ -3027,7 +3034,7 @@ _mesa_format_matches_format_and_type(gl_format gl_format, return GL_FALSE; case MESA_FORMAT_R16: - return format == GL_RED && type == GL_UNSIGNED_SHORT && littleEndian && + return format == GL_RED && type == GL_UNSIGNED_SHORT && !swapBytes; case MESA_FORMAT_GR1616: return format == GL_RG && type == GL_UNSIGNED_SHORT && littleEndian && @@ -3060,11 +3067,6 @@ _mesa_format_matches_format_and_type(gl_format gl_format, case MESA_FORMAT_S8: return format == GL_STENCIL_INDEX && type == GL_UNSIGNED_BYTE; - case MESA_FORMAT_SRGB8: - case MESA_FORMAT_SRGBA8: - case MESA_FORMAT_SARGB8: - case MESA_FORMAT_SL8: - case MESA_FORMAT_SLA8: case MESA_FORMAT_SRGB_DXT1: case MESA_FORMAT_SRGBA_DXT1: case MESA_FORMAT_SRGBA_DXT3: @@ -3119,14 +3121,20 @@ _mesa_format_matches_format_and_type(gl_format gl_format, case MESA_FORMAT_RG_FLOAT16: return format == GL_RG && type == GL_HALF_FLOAT && !swapBytes; - /* FINISHME: What do we want to do for GL_EXT_texture_integer? */ case MESA_FORMAT_ALPHA_UINT8: + return format == GL_ALPHA_INTEGER && type == GL_UNSIGNED_BYTE; case MESA_FORMAT_ALPHA_UINT16: + return format == GL_ALPHA_INTEGER && type == GL_UNSIGNED_SHORT && + !swapBytes; case MESA_FORMAT_ALPHA_UINT32: + return format == GL_ALPHA_INTEGER && type == GL_UNSIGNED_INT && + !swapBytes; case MESA_FORMAT_ALPHA_INT8: + return format == GL_ALPHA_INTEGER && type == GL_BYTE; case MESA_FORMAT_ALPHA_INT16: + return format == GL_ALPHA_INTEGER && type == GL_SHORT && !swapBytes; case MESA_FORMAT_ALPHA_INT32: - return GL_FALSE; + return format == GL_ALPHA_INTEGER && type == GL_INT && !swapBytes; case MESA_FORMAT_INTENSITY_UINT8: case MESA_FORMAT_INTENSITY_UINT16: @@ -3134,55 +3142,107 @@ _mesa_format_matches_format_and_type(gl_format gl_format, case MESA_FORMAT_INTENSITY_INT8: case MESA_FORMAT_INTENSITY_INT16: case MESA_FORMAT_INTENSITY_INT32: + /* GL_INTENSITY_INTEGER_EXT doesn't exist. */ return GL_FALSE; case MESA_FORMAT_LUMINANCE_UINT8: + return format == GL_LUMINANCE_INTEGER_EXT && type == GL_UNSIGNED_BYTE; case MESA_FORMAT_LUMINANCE_UINT16: + return format == GL_LUMINANCE_INTEGER_EXT && type == GL_UNSIGNED_SHORT && + !swapBytes; case MESA_FORMAT_LUMINANCE_UINT32: + return format == GL_LUMINANCE_INTEGER_EXT && type == GL_UNSIGNED_INT && + !swapBytes; case MESA_FORMAT_LUMINANCE_INT8: + return format == GL_LUMINANCE_INTEGER_EXT && type == GL_BYTE; case MESA_FORMAT_LUMINANCE_INT16: + return format == GL_LUMINANCE_INTEGER_EXT && type == GL_SHORT && + !swapBytes; case MESA_FORMAT_LUMINANCE_INT32: - return GL_FALSE; + return format == GL_LUMINANCE_INTEGER_EXT && type == GL_INT && !swapBytes; case MESA_FORMAT_LUMINANCE_ALPHA_UINT8: + return format == GL_LUMINANCE_ALPHA_INTEGER_EXT && + type == GL_UNSIGNED_BYTE && !swapBytes; case MESA_FORMAT_LUMINANCE_ALPHA_UINT16: + return format == GL_LUMINANCE_ALPHA_INTEGER_EXT && + type == GL_UNSIGNED_SHORT && !swapBytes; case MESA_FORMAT_LUMINANCE_ALPHA_UINT32: + return format == GL_LUMINANCE_ALPHA_INTEGER_EXT && + type == GL_UNSIGNED_INT && !swapBytes; case MESA_FORMAT_LUMINANCE_ALPHA_INT8: + return format == GL_LUMINANCE_ALPHA_INTEGER_EXT && type == GL_BYTE && + !swapBytes; case MESA_FORMAT_LUMINANCE_ALPHA_INT16: + return format == GL_LUMINANCE_ALPHA_INTEGER_EXT && type == GL_SHORT && + !swapBytes; case MESA_FORMAT_LUMINANCE_ALPHA_INT32: - return GL_FALSE; + return format == GL_LUMINANCE_ALPHA_INTEGER_EXT && type == GL_INT && + !swapBytes; case MESA_FORMAT_R_INT8: + return format == GL_RED_INTEGER && type == GL_BYTE; case MESA_FORMAT_RG_INT8: + return format == GL_RG_INTEGER && type == GL_BYTE && !swapBytes; case MESA_FORMAT_RGB_INT8: + return format == GL_RGB_INTEGER && type == GL_BYTE && !swapBytes; case MESA_FORMAT_RGBA_INT8: + return format == GL_RGBA_INTEGER && type == GL_BYTE && !swapBytes; case MESA_FORMAT_R_INT16: + return format == GL_RED_INTEGER && type == GL_SHORT && !swapBytes; case MESA_FORMAT_RG_INT16: + return format == GL_RG_INTEGER && type == GL_SHORT && !swapBytes; case MESA_FORMAT_RGB_INT16: + return format == GL_RGB_INTEGER && type == GL_SHORT && !swapBytes; case MESA_FORMAT_RGBA_INT16: + return format == GL_RGBA_INTEGER && type == GL_SHORT && !swapBytes; case MESA_FORMAT_R_INT32: + return format == GL_RED_INTEGER && type == GL_INT && !swapBytes; case MESA_FORMAT_RG_INT32: + return format == GL_RG_INTEGER && type == GL_INT && !swapBytes; case MESA_FORMAT_RGB_INT32: + return format == GL_RGB_INTEGER && type == GL_INT && !swapBytes; case MESA_FORMAT_RGBA_INT32: - return GL_FALSE; + return format == GL_RGBA_INTEGER && type == GL_INT && !swapBytes; case MESA_FORMAT_R_UINT8: + return format == GL_RED_INTEGER && type == GL_UNSIGNED_BYTE; case MESA_FORMAT_RG_UINT8: + return format == GL_RG_INTEGER && type == GL_UNSIGNED_BYTE && !swapBytes; case MESA_FORMAT_RGB_UINT8: + return format == GL_RGB_INTEGER && type == GL_UNSIGNED_BYTE && !swapBytes; case MESA_FORMAT_RGBA_UINT8: + return format == GL_RGBA_INTEGER && type == GL_UNSIGNED_BYTE && + !swapBytes; case MESA_FORMAT_R_UINT16: + return format == GL_RED_INTEGER && type == GL_UNSIGNED_SHORT && + !swapBytes; case MESA_FORMAT_RG_UINT16: + return format == GL_RG_INTEGER && type == GL_UNSIGNED_SHORT && !swapBytes; case MESA_FORMAT_RGB_UINT16: + return format == GL_RGB_INTEGER && type == GL_UNSIGNED_SHORT && + !swapBytes; case MESA_FORMAT_RGBA_UINT16: + return format == GL_RGBA_INTEGER && type == GL_UNSIGNED_SHORT && + !swapBytes; case MESA_FORMAT_R_UINT32: + return format == GL_RED_INTEGER && type == GL_UNSIGNED_INT && !swapBytes; case MESA_FORMAT_RG_UINT32: + return format == GL_RG_INTEGER && type == GL_UNSIGNED_INT && !swapBytes; case MESA_FORMAT_RGB_UINT32: + return format == GL_RGB_INTEGER && type == GL_UNSIGNED_INT && !swapBytes; case MESA_FORMAT_RGBA_UINT32: - return GL_FALSE; + return format == GL_RGBA_INTEGER && type == GL_UNSIGNED_INT && !swapBytes; case MESA_FORMAT_DUDV8: + return (format == GL_DU8DV8_ATI || format == GL_DUDV_ATI) && + type == GL_BYTE && littleEndian && !swapBytes; + case MESA_FORMAT_SIGNED_R8: + return format == GL_RED && type == GL_BYTE; case MESA_FORMAT_SIGNED_RG88_REV: + return format == GL_RG && type == GL_BYTE && littleEndian && + !swapBytes; case MESA_FORMAT_SIGNED_RGBX8888: return GL_FALSE; @@ -3205,12 +3265,17 @@ _mesa_format_matches_format_and_type(gl_format gl_format, return GL_FALSE; case MESA_FORMAT_SIGNED_R16: + return format == GL_RED && type == GL_SHORT && + !swapBytes; case MESA_FORMAT_SIGNED_GR1616: + return format == GL_RG && type == GL_SHORT && littleEndian && !swapBytes; case MESA_FORMAT_SIGNED_RGB_16: + return format == GL_RGB && type == GL_SHORT && !swapBytes; case MESA_FORMAT_SIGNED_RGBA_16: + return format == GL_RGBA && type == GL_SHORT && !swapBytes; case MESA_FORMAT_RGBA_16: - /* FINISHME: SNORM */ - return GL_FALSE; + return format == GL_RGBA && type == GL_UNSIGNED_SHORT && + !swapBytes; case MESA_FORMAT_RED_RGTC1: case MESA_FORMAT_SIGNED_RED_RGTC1: @@ -3238,15 +3303,24 @@ _mesa_format_matches_format_and_type(gl_format gl_format, return GL_FALSE; case MESA_FORMAT_SIGNED_A8: + return format == GL_ALPHA && type == GL_BYTE; case MESA_FORMAT_SIGNED_L8: + return format == GL_LUMINANCE && type == GL_BYTE; case MESA_FORMAT_SIGNED_AL88: + return format == GL_LUMINANCE_ALPHA && type == GL_BYTE && + littleEndian && !swapBytes; case MESA_FORMAT_SIGNED_I8: + return format == GL_INTENSITY && type == GL_BYTE; case MESA_FORMAT_SIGNED_A16: + return format == GL_ALPHA && type == GL_SHORT && !swapBytes; case MESA_FORMAT_SIGNED_L16: + return format == GL_LUMINANCE && type == GL_SHORT && !swapBytes; case MESA_FORMAT_SIGNED_AL1616: + return format == GL_LUMINANCE_ALPHA && type == GL_SHORT && + littleEndian && !swapBytes; case MESA_FORMAT_SIGNED_I16: - /* FINISHME: SNORM */ - return GL_FALSE; + return format == GL_INTENSITY && type == GL_SHORT && littleEndian && + !swapBytes; case MESA_FORMAT_ARGB2101010_UINT: return (format == GL_BGRA_INTEGER_EXT && @@ -3270,7 +3344,8 @@ _mesa_format_matches_format_and_type(gl_format gl_format, return format == GL_DEPTH_COMPONENT && type == GL_FLOAT && !swapBytes; case MESA_FORMAT_Z32_FLOAT_X24S8: - return GL_FALSE; + return format == GL_DEPTH_STENCIL && + type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV && !swapBytes; case MESA_FORMAT_XRGB4444_UNORM: case MESA_FORMAT_XRGB1555_UNORM: diff --git a/mesalib/src/mesa/main/pack.c b/mesalib/src/mesa/main/pack.c index e00ae63fc..d976e5aae 100644 --- a/mesalib/src/mesa/main/pack.c +++ b/mesalib/src/mesa/main/pack.c @@ -6027,6 +6027,20 @@ _mesa_rebase_rgba_float(GLuint n, GLfloat rgba[][4], GLenum baseFormat) rgba[i][ACOMP] = 1.0F; } break; + case GL_RG: + for (i = 0; i < n; i++) { + rgba[i][BCOMP] = 0.0F; + rgba[i][ACOMP] = 1.0F; + } + break; + case GL_RED: + for (i = 0; i < n; i++) { + rgba[i][GCOMP] = 0.0F; + rgba[i][BCOMP] = 0.0F; + rgba[i][ACOMP] = 1.0F; + } + break; + default: /* no-op */ ; @@ -6070,6 +6084,18 @@ _mesa_rebase_rgba_uint(GLuint n, GLuint rgba[][4], GLenum baseFormat) rgba[i][ACOMP] = 1; } break; + case GL_RG: + for (i = 0; i < n; i++) { + rgba[i][BCOMP] = 0; + rgba[i][ACOMP] = 1; + } + break; + case GL_RED: + for (i = 0; i < n; i++) { + rgba[i][GCOMP] = 0; + rgba[i][BCOMP] = 0; + rgba[i][ACOMP] = 1; + } default: /* no-op */ ; diff --git a/mesalib/src/mesa/main/texgetimage.c b/mesalib/src/mesa/main/texgetimage.c index 3a550d941..7299a4b23 100644 --- a/mesalib/src/mesa/main/texgetimage.c +++ b/mesalib/src/mesa/main/texgetimage.c @@ -311,6 +311,41 @@ get_tex_rgba_compressed(struct gl_context *ctx, GLuint dimensions, /** + * Return a base GL format given the user-requested format + * for glGetTexImage(). + */ +static GLenum +_mesa_base_pack_format(GLenum format) +{ + switch (format) { + case GL_ABGR_EXT: + case GL_BGRA: + case GL_BGRA_INTEGER: + case GL_RGBA_INTEGER: + return GL_RGBA; + case GL_BGR: + case GL_BGR_INTEGER: + case GL_RGB_INTEGER: + return GL_RGB; + case GL_RED_INTEGER: + return GL_RED; + case GL_GREEN_INTEGER: + return GL_GREEN; + case GL_BLUE_INTEGER: + return GL_BLUE; + case GL_ALPHA_INTEGER: + return GL_ALPHA; + case GL_LUMINANCE_INTEGER_EXT: + return GL_LUMINANCE; + case GL_LUMINANCE_ALPHA_INTEGER_EXT: + return GL_LUMINANCE_ALPHA; + default: + return format; + } +} + + +/** * Get an uncompressed color texture image. */ static void @@ -323,7 +358,7 @@ get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions, const gl_format texFormat = _mesa_get_srgb_format_linear(texImage->TexFormat); const GLuint width = texImage->Width; - const GLenum destBaseFormat = _mesa_base_tex_format(ctx, format); + GLenum destBaseFormat = _mesa_base_pack_format(format); GLenum rebaseFormat = GL_NONE; GLuint height = texImage->Height; GLuint depth = texImage->Depth; @@ -332,6 +367,7 @@ get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions, GLuint (*rgba_uint)[4]; GLboolean tex_is_integer = _mesa_is_format_integer_color(texImage->TexFormat); GLboolean tex_is_uint = _mesa_is_format_unsigned(texImage->TexFormat); + GLenum texBaseFormat = _mesa_get_format_base_format(texImage->TexFormat); /* Allocate buffer for one row of texels */ rgba = malloc(4 * width * sizeof(GLfloat)); @@ -368,6 +404,50 @@ get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions, */ rebaseFormat = GL_LUMINANCE_ALPHA; /* this covers GL_LUMINANCE too */ } + else if (texImage->_BaseFormat != texBaseFormat) { + /* The internal format and the real format differ, so we can't rely + * on the unpack functions setting the correct constant values. + * (e.g. reading back GL_RGB8 which is actually RGBA won't set alpha=1) + */ + switch (texImage->_BaseFormat) { + case GL_RED: + if ((texBaseFormat == GL_RGBA || + texBaseFormat == GL_RGB || + texBaseFormat == GL_RG) && + (destBaseFormat == GL_RGBA || + destBaseFormat == GL_RGB || + destBaseFormat == GL_RG || + destBaseFormat == GL_GREEN)) { + rebaseFormat = texImage->_BaseFormat; + break; + } + /* fall through */ + case GL_RG: + if ((texBaseFormat == GL_RGBA || + texBaseFormat == GL_RGB) && + (destBaseFormat == GL_RGBA || + destBaseFormat == GL_RGB || + destBaseFormat == GL_BLUE)) { + rebaseFormat = texImage->_BaseFormat; + break; + } + /* fall through */ + case GL_RGB: + if (texBaseFormat == GL_RGBA && + (destBaseFormat == GL_RGBA || + destBaseFormat == GL_ALPHA || + destBaseFormat == GL_LUMINANCE_ALPHA)) { + rebaseFormat = texImage->_BaseFormat; + } + break; + + case GL_ALPHA: + if (destBaseFormat != GL_ALPHA) { + rebaseFormat = texImage->_BaseFormat; + } + break; + } + } for (img = 0; img < depth; img++) { GLubyte *srcMap; @@ -467,16 +547,18 @@ get_tex_memcpy(struct gl_context *ctx, GLenum format, GLenum type, { const GLenum target = texImage->TexObject->Target; GLboolean memCopy = GL_FALSE; + GLenum texBaseFormat = _mesa_get_format_base_format(texImage->TexFormat); /* * Check if we can use memcpy to copy from the hardware texture * format to the user's format/type. * Note that GL's pixel transfer ops don't apply to glGetTexImage() */ - if (target == GL_TEXTURE_1D || - target == GL_TEXTURE_2D || - target == GL_TEXTURE_RECTANGLE || - _mesa_is_cube_face(target)) { + if ((target == GL_TEXTURE_1D || + target == GL_TEXTURE_2D || + target == GL_TEXTURE_RECTANGLE || + _mesa_is_cube_face(target)) && + texBaseFormat == texImage->_BaseFormat) { memCopy = _mesa_format_matches_format_and_type(texImage->TexFormat, format, type, ctx->Pack.SwapBytes); diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c index 9283ece8a..f8f517a42 100644 --- a/mesalib/src/mesa/main/teximage.c +++ b/mesalib/src/mesa/main/teximage.c @@ -2454,9 +2454,7 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions, } } - if ((_mesa_is_desktop_gl(ctx) && - ctx->Extensions.ARB_framebuffer_object) || - _mesa_is_gles3(ctx)) { + if (_mesa_is_gles3(ctx)) { bool rb_is_srgb = false; bool dst_is_srgb = false; @@ -2470,22 +2468,16 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions, } if (rb_is_srgb != dst_is_srgb) { - /* Page 190 (page 211 of the PDF) in section 8.6 of the OpenGL 4.3 - * Core Profile spec says: - * - * "An INVALID_OPERATION error is generated under any of the - * following conditions: - * - * ... + /* Page 137 (page 149 of the PDF) in section 3.8.5 of the + * OpenGLES 3.0.0 spec says: * - * - if the value of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING - * for the framebuffer attachment corresponding to the read - * buffer is LINEAR (see section 9.2.3) and internalformat - * is one of the sRGB formats in table 8.23 - * - if the value of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING - * for the framebuffer attachment corresponding to the read - * buffer is SRGB and internalformat is not one of the sRGB - * formats. in table 8.23." + * "The error INVALID_OPERATION is also generated if the + * value of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING for the + * framebuffer attachment corresponding to the read buffer + * is LINEAR (see section 6.1.13) and internalformat is + * one of the sRGB formats described in section 3.8.16, or + * if the value of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING is + * SRGB and internalformat is not one of the sRGB formats." */ _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexImage%dD(srgb usage mismatch)", dimensions); diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c index 6e7ce237f..9281aa9ea 100644 --- a/mesalib/src/mesa/main/texstore.c +++ b/mesalib/src/mesa/main/texstore.c @@ -1022,20 +1022,7 @@ _mesa_texstore_z32(TEXSTORE_PARAMS) else dstType = GL_FLOAT; - if (ctx->Pixel.DepthScale == 1.0f && - ctx->Pixel.DepthBias == 0.0f && - !srcPacking->SwapBytes && - baseInternalFormat == GL_DEPTH_COMPONENT && - srcFormat == GL_DEPTH_COMPONENT && - srcType == dstType) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ GLint img, row; for (img = 0; img < srcDepth; img++) { @@ -1129,20 +1116,7 @@ _mesa_texstore_z16(TEXSTORE_PARAMS) ASSERT(dstFormat == MESA_FORMAT_Z16); ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLushort)); - if (ctx->Pixel.DepthScale == 1.0f && - ctx->Pixel.DepthBias == 0.0f && - !srcPacking->SwapBytes && - baseInternalFormat == GL_DEPTH_COMPONENT && - srcFormat == GL_DEPTH_COMPONENT && - srcType == GL_UNSIGNED_SHORT) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ GLint img, row; for (img = 0; img < srcDepth; img++) { @@ -1173,22 +1147,11 @@ _mesa_texstore_rgb565(TEXSTORE_PARAMS) ASSERT(_mesa_get_format_bytes(dstFormat) == 2); if (!ctx->_ImageTransferState && + !srcPacking->SwapBytes && baseInternalFormat == GL_RGB && - _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, - srcPacking->SwapBytes)) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == GL_RGB && - srcFormat == GL_RGB && - srcType == GL_UNSIGNED_BYTE && - dims == 2) { + srcFormat == GL_RGB && + srcType == GL_UNSIGNED_BYTE && + dims == 2) { /* do optimized tex store */ const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); @@ -1242,22 +1205,11 @@ _mesa_texstore_rgba8888(TEXSTORE_PARAMS) ASSERT(_mesa_get_format_bytes(dstFormat) == 4); if (!ctx->_ImageTransferState && - baseInternalFormat == GL_RGBA && - _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, - srcPacking->SwapBytes)) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else if (!ctx->_ImageTransferState && - (srcType == GL_UNSIGNED_BYTE || - srcType == GL_UNSIGNED_INT_8_8_8_8 || - srcType == GL_UNSIGNED_INT_8_8_8_8_REV) && - can_swizzle(baseInternalFormat) && - can_swizzle(srcFormat)) { + (srcType == GL_UNSIGNED_BYTE || + srcType == GL_UNSIGNED_INT_8_8_8_8 || + srcType == GL_UNSIGNED_INT_8_8_8_8_REV) && + can_swizzle(baseInternalFormat) && + can_swizzle(srcFormat)) { GLubyte dstmap[4]; @@ -1310,24 +1262,13 @@ _mesa_texstore_argb8888(TEXSTORE_PARAMS) ASSERT(_mesa_get_format_bytes(dstFormat) == 4); if (!ctx->_ImageTransferState && - baseInternalFormat == GL_RGBA && - _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, - srcPacking->SwapBytes)) { - /* simple memcpy path (big endian) */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - (dstFormat == MESA_FORMAT_ARGB8888 || - dstFormat == MESA_FORMAT_XRGB8888) && - srcFormat == GL_RGB && - (baseInternalFormat == GL_RGBA || - baseInternalFormat == GL_RGB) && - srcType == GL_UNSIGNED_BYTE) { + !srcPacking->SwapBytes && + (dstFormat == MESA_FORMAT_ARGB8888 || + dstFormat == MESA_FORMAT_XRGB8888) && + srcFormat == GL_RGB && + (baseInternalFormat == GL_RGBA || + baseInternalFormat == GL_RGB) && + srcType == GL_UNSIGNED_BYTE) { int img, row, col; for (img = 0; img < srcDepth; img++) { const GLint srcRowStride = @@ -1465,20 +1406,9 @@ _mesa_texstore_rgb888(TEXSTORE_PARAMS) ASSERT(_mesa_get_format_bytes(dstFormat) == 3); if (!ctx->_ImageTransferState && - baseInternalFormat == GL_RGB && - _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, - srcPacking->SwapBytes)) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - srcFormat == GL_RGBA && - srcType == GL_UNSIGNED_BYTE) { + !srcPacking->SwapBytes && + srcFormat == GL_RGBA && + srcType == GL_UNSIGNED_BYTE) { /* extract RGB from RGBA */ GLint img, row, col; for (img = 0; img < srcDepth; img++) { @@ -1538,20 +1468,9 @@ _mesa_texstore_bgr888(TEXSTORE_PARAMS) ASSERT(_mesa_get_format_bytes(dstFormat) == 3); if (!ctx->_ImageTransferState && - baseInternalFormat == GL_RGB && - _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, - srcPacking->SwapBytes)) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - srcFormat == GL_RGBA && - srcType == GL_UNSIGNED_BYTE) { + !srcPacking->SwapBytes && + srcFormat == GL_RGBA && + srcType == GL_UNSIGNED_BYTE) { /* extract BGR from RGBA */ int img, row, col; for (img = 0; img < srcDepth; img++) { @@ -1605,105 +1524,13 @@ _mesa_texstore_bgr888(TEXSTORE_PARAMS) static GLboolean -_mesa_texstore_argb4444(TEXSTORE_PARAMS) -{ - ASSERT(dstFormat == MESA_FORMAT_ARGB4444 || - dstFormat == MESA_FORMAT_ARGB4444_REV); - ASSERT(_mesa_get_format_bytes(dstFormat) == 2); - - if (!ctx->_ImageTransferState && - baseInternalFormat == GL_RGBA && - _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, - srcPacking->SwapBytes)) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { - return store_ubyte_texture(ctx, dims, baseInternalFormat, - dstFormat, dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, srcPacking); - } - return GL_TRUE; -} - -static GLboolean -_mesa_texstore_rgba5551(TEXSTORE_PARAMS) -{ - ASSERT(dstFormat == MESA_FORMAT_RGBA5551); - ASSERT(_mesa_get_format_bytes(dstFormat) == 2); - - if (!ctx->_ImageTransferState && - baseInternalFormat == GL_RGBA && - _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, - srcPacking->SwapBytes)) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { - return store_ubyte_texture(ctx, dims, baseInternalFormat, - dstFormat, dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, srcPacking); - } - return GL_TRUE; -} - -static GLboolean -_mesa_texstore_argb1555(TEXSTORE_PARAMS) -{ - ASSERT(dstFormat == MESA_FORMAT_ARGB1555 || - dstFormat == MESA_FORMAT_ARGB1555_REV); - ASSERT(_mesa_get_format_bytes(dstFormat) == 2); - - if (!ctx->_ImageTransferState && - baseInternalFormat == GL_RGBA && - _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, - srcPacking->SwapBytes)) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { - return store_ubyte_texture(ctx, dims, baseInternalFormat, - dstFormat, dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, srcPacking); - } - return GL_TRUE; -} - - -static GLboolean _mesa_texstore_argb2101010(TEXSTORE_PARAMS) { ASSERT(dstFormat == MESA_FORMAT_ARGB2101010 || dstFormat == MESA_FORMAT_XRGB2101010_UNORM); ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - if (!ctx->_ImageTransferState && - baseInternalFormat == GL_RGBA && - _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, - srcPacking->SwapBytes)) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ /* Hardcode GL_RGBA as the base format, which forces alpha to 1.0 * if the internal format is RGB. */ @@ -1803,26 +1630,10 @@ _mesa_texstore_unorm88(TEXSTORE_PARAMS) ASSERT(_mesa_get_format_bytes(dstFormat) == 2); if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - ((dstFormat == MESA_FORMAT_AL88 && - baseInternalFormat == GL_LUMINANCE_ALPHA && - srcFormat == GL_LUMINANCE_ALPHA) || - (dstFormat == MESA_FORMAT_GR88 && - baseInternalFormat == srcFormat)) && + littleEndian && srcType == GL_UNSIGNED_BYTE && - littleEndian) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else if (!ctx->_ImageTransferState && - littleEndian && - srcType == GL_UNSIGNED_BYTE && - can_swizzle(baseInternalFormat) && - can_swizzle(srcFormat)) { + can_swizzle(baseInternalFormat) && + can_swizzle(srcFormat)) { GLubyte dstmap[4]; /* dstmap - how to swizzle from RGBA to dst format: @@ -1909,7 +1720,6 @@ _mesa_texstore_unorm88(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_unorm1616(TEXSTORE_PARAMS) { - const GLboolean littleEndian = _mesa_little_endian(); const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); ASSERT(dstFormat == MESA_FORMAT_AL1616 || @@ -1918,23 +1728,7 @@ _mesa_texstore_unorm1616(TEXSTORE_PARAMS) dstFormat == MESA_FORMAT_RG1616); ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - ((dstFormat == MESA_FORMAT_AL1616 && - baseInternalFormat == GL_LUMINANCE_ALPHA && - srcFormat == GL_LUMINANCE_ALPHA) || - (dstFormat == MESA_FORMAT_GR1616 && - baseInternalFormat == srcFormat)) && - srcType == GL_UNSIGNED_SHORT && - littleEndian) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, baseInternalFormat, @@ -1985,7 +1779,6 @@ _mesa_texstore_unorm1616(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_unorm16(TEXSTORE_PARAMS) { - const GLboolean littleEndian = _mesa_little_endian(); const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); ASSERT(dstFormat == MESA_FORMAT_R16 || @@ -1994,19 +1787,7 @@ _mesa_texstore_unorm16(TEXSTORE_PARAMS) dstFormat == MESA_FORMAT_I16); ASSERT(_mesa_get_format_bytes(dstFormat) == 2); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - srcType == GL_UNSIGNED_SHORT && - littleEndian) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, baseInternalFormat, @@ -2046,19 +1827,7 @@ _mesa_texstore_rgba_16(TEXSTORE_PARAMS) dstFormat == MESA_FORMAT_XBGR16161616_UNORM); ASSERT(_mesa_get_format_bytes(dstFormat) == 8); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == GL_RGBA && - srcFormat == GL_RGBA && - srcType == GL_UNSIGNED_SHORT) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ /* Hardcode GL_RGBA as the base format, which forces alpha to 1.0 * if the internal format is RGB. */ @@ -2110,20 +1879,7 @@ _mesa_texstore_signed_rgba_16(TEXSTORE_PARAMS) dstFormat == MESA_FORMAT_SIGNED_RGBA_16 || dstFormat == MESA_FORMAT_XBGR16161616_SNORM); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == GL_RGBA && - dstFormat == MESA_FORMAT_SIGNED_RGBA_16 && - srcFormat == GL_RGBA && - srcType == GL_SHORT) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, baseInternalFormat, @@ -2192,33 +1948,6 @@ _mesa_texstore_signed_rgba_16(TEXSTORE_PARAMS) } -static GLboolean -_mesa_texstore_rgb332(TEXSTORE_PARAMS) -{ - ASSERT(dstFormat == MESA_FORMAT_RGB332); - ASSERT(_mesa_get_format_bytes(dstFormat) == 1); - - if (!ctx->_ImageTransferState && - baseInternalFormat == GL_RGB && - _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, - srcPacking->SwapBytes)) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { - return store_ubyte_texture(ctx, dims, baseInternalFormat, - dstFormat, dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, - srcFormat, srcType, srcAddr, srcPacking); - } - return GL_TRUE; -} - - /** * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8. */ @@ -2234,20 +1963,9 @@ _mesa_texstore_unorm8(TEXSTORE_PARAMS) ASSERT(_mesa_get_format_bytes(dstFormat) == 1); if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - srcType == GL_UNSIGNED_BYTE) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else if (!ctx->_ImageTransferState && - srcType == GL_UNSIGNED_BYTE && - can_swizzle(baseInternalFormat) && - can_swizzle(srcFormat)) { + srcType == GL_UNSIGNED_BYTE && + can_swizzle(baseInternalFormat) && + can_swizzle(srcFormat)) { GLubyte dstmap[4]; /* dstmap - how to swizzle from RGBA to dst format: @@ -2357,16 +2075,7 @@ _mesa_texstore_dudv8(TEXSTORE_PARAMS) (srcFormat == GL_DUDV_ATI)); ASSERT(baseInternalFormat == GL_DUDV_ATI); - if (!srcPacking->SwapBytes && srcType == GL_BYTE && - littleEndian) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else if (srcType == GL_BYTE) { + if (srcType == GL_BYTE) { GLubyte dstmap[4]; /* dstmap - how to swizzle from RGBA to dst format: @@ -2445,18 +2154,7 @@ _mesa_texstore_snorm8(TEXSTORE_PARAMS) dstFormat == MESA_FORMAT_SIGNED_R8); ASSERT(_mesa_get_format_bytes(dstFormat) == 1); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - srcType == GL_BYTE) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, baseInternalFormat, @@ -2491,26 +2189,13 @@ _mesa_texstore_snorm8(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_snorm88(TEXSTORE_PARAMS) { - const GLboolean littleEndian = _mesa_little_endian(); const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); ASSERT(dstFormat == MESA_FORMAT_SIGNED_AL88 || dstFormat == MESA_FORMAT_SIGNED_RG88_REV); ASSERT(_mesa_get_format_bytes(dstFormat) == 2); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - srcType == GL_BYTE && - littleEndian) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, baseInternalFormat, @@ -2545,7 +2230,6 @@ _mesa_texstore_snorm88(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_snorm16(TEXSTORE_PARAMS) { - const GLboolean littleEndian = _mesa_little_endian(); const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); ASSERT(dstFormat == MESA_FORMAT_SIGNED_R16 || @@ -2554,19 +2238,7 @@ _mesa_texstore_snorm16(TEXSTORE_PARAMS) dstFormat == MESA_FORMAT_SIGNED_I16); ASSERT(_mesa_get_format_bytes(dstFormat) == 2); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - srcType == GL_SHORT && - littleEndian) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, baseInternalFormat, @@ -2604,26 +2276,13 @@ _mesa_texstore_snorm16(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_snorm1616(TEXSTORE_PARAMS) { - const GLboolean littleEndian = _mesa_little_endian(); const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); ASSERT(dstFormat == MESA_FORMAT_SIGNED_AL1616 || dstFormat == MESA_FORMAT_SIGNED_GR1616); ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - srcType == GL_SHORT && - littleEndian) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, baseInternalFormat, @@ -2731,18 +2390,7 @@ _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS) dstFormat == MESA_FORMAT_SIGNED_RGBA8888_REV); ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - if (!ctx->_ImageTransferState && - baseInternalFormat == GL_RGBA && - _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, - srcPacking->SwapBytes)) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, baseInternalFormat, @@ -2805,18 +2453,8 @@ _mesa_texstore_z24_s8(TEXSTORE_PARAMS) srcFormat == GL_STENCIL_INDEX); ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || srcType == GL_UNSIGNED_INT_24_8_EXT); - if (srcFormat == GL_DEPTH_STENCIL && ctx->Pixel.DepthScale == 1.0f && - ctx->Pixel.DepthBias == 0.0f && - !srcPacking->SwapBytes) { - /* simple path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else if (srcFormat == GL_DEPTH_COMPONENT || - srcFormat == GL_STENCIL_INDEX) { + if (srcFormat == GL_DEPTH_COMPONENT || + srcFormat == GL_STENCIL_INDEX) { GLuint *depth = malloc(srcWidth * sizeof(GLuint)); GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte)); @@ -2972,18 +2610,7 @@ _mesa_texstore_s8(TEXSTORE_PARAMS) ASSERT(dstFormat == MESA_FORMAT_S8); ASSERT(srcFormat == GL_STENCIL_INDEX); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - srcType == GL_UNSIGNED_BYTE) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); GLint img, row; @@ -3064,19 +2691,7 @@ _mesa_texstore_rgba_float32(TEXSTORE_PARAMS) baseInternalFormat == GL_RG); ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLfloat)); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - baseInternalFormat == baseFormat && - srcType == GL_FLOAT) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, baseInternalFormat, @@ -3141,19 +2756,7 @@ _mesa_texstore_rgba_float16(TEXSTORE_PARAMS) baseInternalFormat == GL_RG); ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLhalfARB)); - if (!ctx->_ImageTransferState && - !srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - baseInternalFormat == baseFormat && - srcType == GL_HALF_FLOAT_ARB) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, baseInternalFormat, @@ -3217,20 +2820,7 @@ _mesa_texstore_rgba_int8(TEXSTORE_PARAMS) baseInternalFormat == GL_INTENSITY); ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLbyte)); - /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply - * to integer formats. - */ - if (!srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - srcType == GL_BYTE) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLuint *tempImage = make_temp_uint_image(ctx, dims, baseInternalFormat, @@ -3301,20 +2891,7 @@ _mesa_texstore_rgba_int16(TEXSTORE_PARAMS) baseInternalFormat == GL_INTENSITY); ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLshort)); - /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply - * to integer formats. - */ - if (!srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - srcType == GL_SHORT) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLuint *tempImage = make_temp_uint_image(ctx, dims, baseInternalFormat, @@ -3385,20 +2962,7 @@ _mesa_texstore_rgba_int32(TEXSTORE_PARAMS) baseInternalFormat == GL_INTENSITY); ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLint)); - /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply - * to integer formats. - */ - if (!srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - srcType == GL_INT) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLuint *tempImage = make_temp_uint_image(ctx, dims, baseInternalFormat, @@ -3469,20 +3033,7 @@ _mesa_texstore_rgba_uint8(TEXSTORE_PARAMS) baseInternalFormat == GL_INTENSITY); ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLubyte)); - /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply - * to integer formats. - */ - if (!srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - srcType == GL_UNSIGNED_BYTE) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLuint *tempImage = make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat, @@ -3550,20 +3101,7 @@ _mesa_texstore_rgba_uint16(TEXSTORE_PARAMS) baseInternalFormat == GL_INTENSITY); ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLushort)); - /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply - * to integer formats. - */ - if (!srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - srcType == GL_UNSIGNED_SHORT) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLuint *tempImage = make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat, @@ -3631,20 +3169,7 @@ _mesa_texstore_rgba_uint32(TEXSTORE_PARAMS) baseInternalFormat == GL_INTENSITY); ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLuint)); - /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply - * to integer formats. - */ - if (!srcPacking->SwapBytes && - baseInternalFormat == srcFormat && - srcType == GL_UNSIGNED_INT) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLuint *tempImage = make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat, @@ -3802,17 +3327,7 @@ _mesa_texstore_rgb9_e5(TEXSTORE_PARAMS) ASSERT(dstFormat == MESA_FORMAT_RGB9_E5_FLOAT); ASSERT(baseInternalFormat == GL_RGB); - if (!ctx->_ImageTransferState && - _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, - srcPacking->SwapBytes)) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, baseInternalFormat, @@ -3850,17 +3365,7 @@ _mesa_texstore_r11_g11_b10f(TEXSTORE_PARAMS) ASSERT(dstFormat == MESA_FORMAT_R11_G11_B10_FLOAT); ASSERT(baseInternalFormat == GL_RGB); - if (!ctx->_ImageTransferState && - _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, - srcPacking->SwapBytes)) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, baseInternalFormat, @@ -3901,19 +3406,8 @@ _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS) ASSERT(srcFormat != GL_DEPTH_STENCIL || srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); - if (srcFormat == GL_DEPTH_STENCIL && - ctx->Pixel.DepthScale == 1.0f && - ctx->Pixel.DepthBias == 0.0f && - !srcPacking->SwapBytes) { - /* simple path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else if (srcFormat == GL_DEPTH_COMPONENT || - srcFormat == GL_STENCIL_INDEX) { + if (srcFormat == GL_DEPTH_COMPONENT || + srcFormat == GL_STENCIL_INDEX) { GLint img, row; const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType) @@ -3961,17 +3455,7 @@ _mesa_texstore_argb2101010_uint(TEXSTORE_PARAMS) ASSERT(dstFormat == MESA_FORMAT_ARGB2101010_UINT); ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - if (baseInternalFormat == GL_RGBA && - _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, - srcPacking->SwapBytes)) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLuint *tempImage = make_temp_uint_image(ctx, dims, baseInternalFormat, @@ -4027,17 +3511,7 @@ _mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS) ASSERT(dstFormat == MESA_FORMAT_ABGR2101010_UINT); ASSERT(_mesa_get_format_bytes(dstFormat) == 4); - if (baseInternalFormat == GL_RGBA && - _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, - srcPacking->SwapBytes)) { - /* simple memcpy path */ - memcpy_texture(ctx, dims, - dstFormat, - dstRowStride, dstSlices, - srcWidth, srcHeight, srcDepth, srcFormat, srcType, - srcAddr, srcPacking); - } - else { + { /* general path */ const GLuint *tempImage = make_temp_uint_image(ctx, dims, baseInternalFormat, @@ -4127,17 +3601,17 @@ _mesa_get_texstore_func(gl_format format) table[MESA_FORMAT_BGR888] = _mesa_texstore_bgr888; table[MESA_FORMAT_RGB565] = _mesa_texstore_rgb565; table[MESA_FORMAT_RGB565_REV] = _mesa_texstore_rgb565; - table[MESA_FORMAT_ARGB4444] = _mesa_texstore_argb4444; - table[MESA_FORMAT_ARGB4444_REV] = _mesa_texstore_argb4444; - table[MESA_FORMAT_RGBA5551] = _mesa_texstore_rgba5551; - table[MESA_FORMAT_ARGB1555] = _mesa_texstore_argb1555; - table[MESA_FORMAT_ARGB1555_REV] = _mesa_texstore_argb1555; + table[MESA_FORMAT_ARGB4444] = store_ubyte_texture; + table[MESA_FORMAT_ARGB4444_REV] = store_ubyte_texture; + table[MESA_FORMAT_RGBA5551] = store_ubyte_texture; + table[MESA_FORMAT_ARGB1555] = store_ubyte_texture; + table[MESA_FORMAT_ARGB1555_REV] = store_ubyte_texture; table[MESA_FORMAT_AL44] = _mesa_texstore_unorm44; table[MESA_FORMAT_AL88] = _mesa_texstore_unorm88; table[MESA_FORMAT_AL88_REV] = _mesa_texstore_unorm88; table[MESA_FORMAT_AL1616] = _mesa_texstore_unorm1616; table[MESA_FORMAT_AL1616_REV] = _mesa_texstore_unorm1616; - table[MESA_FORMAT_RGB332] = _mesa_texstore_rgb332; + table[MESA_FORMAT_RGB332] = store_ubyte_texture; table[MESA_FORMAT_A8] = _mesa_texstore_unorm8; table[MESA_FORMAT_A16] = _mesa_texstore_unorm16; table[MESA_FORMAT_L8] = _mesa_texstore_unorm8; @@ -4317,6 +3791,58 @@ _mesa_get_texstore_func(gl_format format) } +static GLboolean +_mesa_texstore_memcpy(TEXSTORE_PARAMS) +{ + GLenum dstType; + + /* There are different restrictions depending on the base format... */ + switch (baseInternalFormat) { + case GL_DEPTH_COMPONENT: + case GL_DEPTH_STENCIL: + /* Depth scale and bias are not allowed. */ + if (ctx->Pixel.DepthScale != 1.0f || + ctx->Pixel.DepthBias != 0.0f) { + return GL_FALSE; + } + break; + + case GL_STENCIL_INDEX: + break; + + default: + /* Color formats. + * Pixel transfer ops (scale, bias, table lookup) do not apply + * to integer formats. + */ + dstType = _mesa_get_format_datatype(dstFormat); + + if (dstType != GL_INT && dstType != GL_UNSIGNED_INT && + ctx->_ImageTransferState) { + return GL_FALSE; + } + } + + /* The base internal format and the base Mesa format must match. */ + if (baseInternalFormat != _mesa_get_format_base_format(dstFormat)) { + return GL_FALSE; + } + + /* The Mesa format must match the input format and type. */ + if (!_mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, + srcPacking->SwapBytes)) { + return GL_FALSE; + } + + memcpy_texture(ctx, dims, + dstFormat, + dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, srcFormat, srcType, + srcAddr, srcPacking); + return GL_TRUE; +} + + /** * Store user data into texture memory. * Called via glTex[Sub]Image1/2/3D() @@ -4327,6 +3853,14 @@ _mesa_texstore(TEXSTORE_PARAMS) StoreTexImageFunc storeImage; GLboolean success; + if (_mesa_texstore_memcpy(ctx, dims, baseInternalFormat, + dstFormat, + dstRowStride, dstSlices, + srcWidth, srcHeight, srcDepth, + srcFormat, srcType, srcAddr, srcPacking)) { + return GL_TRUE; + } + storeImage = _mesa_get_texstore_func(dstFormat); success = storeImage(ctx, dims, baseInternalFormat, diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.c b/mesalib/src/mesa/state_tracker/st_cb_texture.c index ab5ff27b3..ac70e9292 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_texture.c +++ b/mesalib/src/mesa/state_tracker/st_cb_texture.c @@ -560,15 +560,52 @@ st_CompressedTexImage(struct gl_context *ctx, GLuint dims, } +static enum pipe_format +choose_matching_format(struct pipe_screen *screen, unsigned bind, + GLenum format, GLenum type, GLboolean swapBytes) +{ + gl_format mesa_format; + + for (mesa_format = 1; mesa_format < MESA_FORMAT_COUNT; mesa_format++) { + if (_mesa_get_format_color_encoding(mesa_format) == GL_SRGB) { + continue; + } + + if (_mesa_format_matches_format_and_type(mesa_format, format, type, + swapBytes)) { + enum pipe_format format = st_mesa_format_to_pipe_format(mesa_format); + + if (format && + screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, + bind)) { + return format; + } + /* It's unlikely to find 2 matching Mesa formats. */ + break; + } + } + return PIPE_FORMAT_NONE; +} + /** - * glGetTexImage() helper: decompress a compressed texture by rendering - * a textured quad. Store the results in the user's buffer. + * Called via ctx->Driver.GetTexImage() + * + * This uses a blit to copy the texture to a texture format which matches + * the format and type combo and then a fast read-back is done using memcpy. + * We can do arbitrary X/Y/Z/W/0/1 swizzling here as long as there is + * a format which matches the swizzling. + * + * If such a format isn't available, it falls back to _mesa_get_teximage. + * + * NOTE: Drivers usually do a blit to convert between tiled and linear + * texture layouts during texture uploads/downloads, so the blit + * we do here should be free in such cases. */ static void -decompress_with_blit(struct gl_context * ctx, - GLenum format, GLenum type, GLvoid *pixels, - struct gl_texture_image *texImage) +st_GetTexImage(struct gl_context * ctx, + GLenum format, GLenum type, GLvoid * pixels, + struct gl_texture_image *texImage) { struct st_context *st = st_context(ctx); struct pipe_context *pipe = st->pipe; @@ -576,38 +613,125 @@ decompress_with_blit(struct gl_context * ctx, const GLuint width = texImage->Width; const GLuint height = texImage->Height; const GLuint depth = texImage->Depth; + struct st_texture_image *stImage = st_texture_image(texImage); struct pipe_resource *src = st_texture_object(texImage->TexObject)->pt; - struct pipe_resource *dst; + struct pipe_resource *dst = NULL; struct pipe_resource dst_templ; - enum pipe_format pipe_format; + enum pipe_format dst_format, src_format; gl_format mesa_format; GLenum gl_target = texImage->TexObject->Target; enum pipe_texture_target pipe_target; struct pipe_blit_info blit; - unsigned bind = (PIPE_BIND_RENDER_TARGET | PIPE_BIND_TRANSFER_READ); + unsigned bind = PIPE_BIND_TRANSFER_READ; struct pipe_transfer *tex_xfer; - ubyte *map; + ubyte *map = NULL; + boolean done = FALSE; + + if (!stImage->pt) { + goto fallback; + } + + /* XXX Fallback to _mesa_get_teximage for depth-stencil formats + * due to an incomplete stencil blit implementation in some drivers. */ + if (format == GL_DEPTH_STENCIL) { + goto fallback; + } + + /* If the base internal format and the texture format don't match, we have + * to fall back to _mesa_get_teximage. */ + if (texImage->_BaseFormat != + _mesa_get_format_base_format(texImage->TexFormat)) { + goto fallback; + } + + /* See if the texture format already matches the format and type, + * in which case the memcpy-based fast path will be used. */ + if (_mesa_format_matches_format_and_type(texImage->TexFormat, format, + type, ctx->Pack.SwapBytes)) { + goto fallback; + } + + /* Convert the source format to what is expected by GetTexImage + * and see if it's supported. + * + * This only applies to glGetTexImage: + * - Luminance must be returned as (L,0,0,1). + * - Luminance alpha must be returned as (L,0,0,A). + * - Intensity must be returned as (I,0,0,1) + */ + src_format = util_format_linear(src->format); + src_format = util_format_luminance_to_red(src_format); + src_format = util_format_intensity_to_red(src_format); + + if (!src_format || + !screen->is_format_supported(screen, src_format, src->target, + src->nr_samples, + PIPE_BIND_SAMPLER_VIEW)) { + goto fallback; + } + + if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL) + bind |= PIPE_BIND_DEPTH_STENCIL; + else + bind |= PIPE_BIND_RENDER_TARGET; /* GetTexImage only returns a single face for cubemaps. */ if (gl_target == GL_TEXTURE_CUBE_MAP) { gl_target = GL_TEXTURE_2D; } - pipe_target = gl_target_to_pipe(gl_target); - /* Find the best match for the format+type combo. */ - pipe_format = st_choose_format(st, GL_RGBA8, format, type, - pipe_target, 0, bind, FALSE); - if (pipe_format == PIPE_FORMAT_NONE) { - /* unable to get an rgba format!?! */ - _mesa_problem(ctx, "%s: cannot find a supported format", __func__); - return; + /* Choose the destination format by finding the best match + * for the format+type combo. */ + dst_format = choose_matching_format(screen, bind, format, type, + ctx->Pack.SwapBytes); + + if (dst_format == PIPE_FORMAT_NONE) { + GLenum dst_glformat; + + /* Fall back to _mesa_get_teximage except for compressed formats, + * where decompression with a blit is always preferred. */ + if (!util_format_is_compressed(src->format)) { + goto fallback; + } + + /* Set the appropriate format for the decompressed texture. + * Luminance and sRGB formats shouldn't appear here.*/ + switch (src_format) { + case PIPE_FORMAT_DXT1_RGB: + case PIPE_FORMAT_DXT1_RGBA: + case PIPE_FORMAT_DXT3_RGBA: + case PIPE_FORMAT_DXT5_RGBA: + case PIPE_FORMAT_RGTC1_UNORM: + case PIPE_FORMAT_RGTC2_UNORM: + case PIPE_FORMAT_ETC1_RGB8: + dst_glformat = GL_RGBA8; + break; + case PIPE_FORMAT_RGTC1_SNORM: + case PIPE_FORMAT_RGTC2_SNORM: + if (!ctx->Extensions.EXT_texture_snorm) + goto fallback; + dst_glformat = GL_RGBA8_SNORM; + break; + /* TODO: for BPTC_*FLOAT, set RGBA32F and check for ARB_texture_float */ + default: + assert(0); + goto fallback; + } + + dst_format = st_choose_format(st, dst_glformat, format, type, + pipe_target, 0, bind, FALSE); + + if (dst_format == PIPE_FORMAT_NONE) { + /* unable to get an rgba format!?! */ + goto fallback; + } } /* create the destination texture */ memset(&dst_templ, 0, sizeof(dst_templ)); dst_templ.target = pipe_target; - dst_templ.format = pipe_format; + dst_templ.format = dst_format; dst_templ.bind = bind; dst_templ.usage = PIPE_USAGE_STAGING; @@ -617,13 +741,12 @@ decompress_with_blit(struct gl_context * ctx, dst = screen->resource_create(screen, &dst_templ); if (!dst) { - _mesa_problem(ctx, "%s: cannot create a temporary texture", __func__); - return; + goto fallback; } blit.src.resource = src; blit.src.level = texImage->Level; - blit.src.format = util_format_linear(src->format); + blit.src.format = src_format; blit.dst.resource = dst; blit.dst.level = 0; blit.dst.format = dst->format; @@ -649,13 +772,13 @@ decompress_with_blit(struct gl_context * ctx, goto end; } - mesa_format = st_pipe_format_to_mesa_format(pipe_format); + mesa_format = st_pipe_format_to_mesa_format(dst_format); /* copy/pack data into user buffer */ if (_mesa_format_matches_format_and_type(mesa_format, format, type, ctx->Pack.SwapBytes)) { /* memcpy */ - const uint bytesPerRow = width * util_format_get_blocksize(pipe_format); + const uint bytesPerRow = width * util_format_get_blocksize(dst_format); GLuint row, slice; for (slice = 0; slice < depth; slice++) { @@ -674,12 +797,12 @@ decompress_with_blit(struct gl_context * ctx, else { /* format translation via floats */ GLuint row, slice; - enum pipe_format pformat = util_format_linear(dst->format); GLfloat *rgba; + assert(util_format_is_compressed(src->format)); + rgba = malloc(width * 4 * sizeof(GLfloat)); if (!rgba) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()"); goto end; } @@ -695,7 +818,7 @@ decompress_with_blit(struct gl_context * ctx, /* get float[4] rgba row from surface */ pipe_get_tile_rgba_format(tex_xfer, map, 0, row, width, 1, - pformat, rgba); + dst_format, rgba); _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format, type, dest, &ctx->Pack, transferOps); @@ -705,6 +828,7 @@ decompress_with_blit(struct gl_context * ctx, free(rgba); } + done = TRUE; end: if (map) @@ -712,29 +836,9 @@ end: _mesa_unmap_pbo_dest(ctx, &ctx->Pack); pipe_resource_reference(&dst, NULL); -} - - - -/** - * Called via ctx->Driver.GetTexImage() - */ -static void -st_GetTexImage(struct gl_context * ctx, - GLenum format, GLenum type, GLvoid * pixels, - struct gl_texture_image *texImage) -{ - struct st_texture_image *stImage = st_texture_image(texImage); - if (stImage->pt && util_format_is_s3tc(stImage->pt->format)) { - /* Need to decompress the texture. - * We'll do this by rendering a textured quad (which is hopefully - * faster than using the fallback code in texcompress.c). - * Note that we only expect RGBA formats (no Z/depth formats). - */ - decompress_with_blit(ctx, format, type, pixels, texImage); - } - else { +fallback: + if (!done) { _mesa_get_teximage(ctx, format, type, pixels, texImage); } } diff --git a/mesalib/src/mesa/state_tracker/st_format.c b/mesalib/src/mesa/state_tracker/st_format.c index 5b6e74d50..02969b995 100644 --- a/mesalib/src/mesa/state_tracker/st_format.c +++ b/mesalib/src/mesa/state_tracker/st_format.c @@ -390,7 +390,6 @@ st_mesa_format_to_pipe_format(gl_format mesaFormat) return PIPE_FORMAT_R32G32B32X32_SINT; default: - assert(0); return PIPE_FORMAT_NONE; } } diff --git a/mesalib/src/mesa/vbo/vbo_save_api.c b/mesalib/src/mesa/vbo/vbo_save_api.c index b4c90a05c..749071753 100644 --- a/mesalib/src/mesa/vbo/vbo_save_api.c +++ b/mesalib/src/mesa/vbo/vbo_save_api.c @@ -301,6 +301,47 @@ _save_reset_counters(struct gl_context *ctx) save->dangling_attr_ref = 0; } +/** + * For a list of prims, try merging prims that can just be extensions of the + * previous prim. + */ +static void +vbo_merge_prims(struct gl_context *ctx, + struct _mesa_prim *prim_list, + GLuint *prim_count) +{ + GLuint i; + struct _mesa_prim *prev_prim = prim_list; + + for (i = 1; i < *prim_count; i++) { + struct _mesa_prim *this_prim = prim_list + i; + + if (this_prim->mode == prev_prim->mode && + this_prim->mode == GL_QUADS && + this_prim->count % 4 == 0 && + prev_prim->count % 4 == 0 && + this_prim->start == prev_prim->start + prev_prim->count && + this_prim->basevertex == prev_prim->basevertex && + this_prim->num_instances == prev_prim->num_instances && + this_prim->base_instance == prev_prim->base_instance) { + /* We've found a prim that just extend the previous one. Tack it + * onto the previous one, and let this primitive struct get dropped. + */ + prev_prim->count += this_prim->count; + prev_prim->end = this_prim->end; + continue; + } + + /* If any previous primitives have been dropped, then we need to copy + * this later one into the next available slot. + */ + prev_prim++; + if (prev_prim != this_prim) + *prev_prim = *this_prim; + } + + *prim_count = prev_prim - prim_list + 1; +} /** * Insert the active immediate struct onto the display list currently @@ -380,6 +421,8 @@ _save_compile_vertex_list(struct gl_context *ctx) */ save->copied.nr = _save_copy_vertices(ctx, node, save->buffer); + vbo_merge_prims(ctx, node->prim, &node->prim_count); + /* Deal with GL_COMPILE_AND_EXECUTE: */ if (ctx->ExecuteFlag) { @@ -1595,14 +1638,14 @@ vbo_print_vertex_list(struct gl_context *ctx, void *data) for (i = 0; i < node->prim_count; i++) { struct _mesa_prim *prim = &node->prim[i]; - _mesa_debug(NULL, " prim %d: %s%s %d..%d %s %s\n", - i, - _mesa_lookup_prim_by_nr(prim->mode), - prim->weak ? " (weak)" : "", - prim->start, - prim->start + prim->count, - (prim->begin) ? "BEGIN" : "(wrap)", - (prim->end) ? "END" : "(wrap)"); + printf(" prim %d: %s%s %d..%d %s %s\n", + i, + _mesa_lookup_prim_by_nr(prim->mode), + prim->weak ? " (weak)" : "", + prim->start, + prim->start + prim->count, + (prim->begin) ? "BEGIN" : "(wrap)", + (prim->end) ? "END" : "(wrap)"); } } diff --git a/pixman/pixman/pixman-compiler.h b/pixman/pixman/pixman-compiler.h index d38dfbe34..949182d4f 100644 --- a/pixman/pixman/pixman-compiler.h +++ b/pixman/pixman/pixman-compiler.h @@ -19,6 +19,12 @@ #endif #if defined (__GNUC__) +# define unlikely(expr) __builtin_expect ((expr), 0) +#else +# define unlikely(expr) (expr) +#endif + +#if defined (__GNUC__) # define MAYBE_UNUSED __attribute__((unused)) #else # define MAYBE_UNUSED diff --git a/pixman/pixman/pixman-implementation.c b/pixman/pixman/pixman-implementation.c index c0a643633..cfb82bb1f 100644 --- a/pixman/pixman/pixman-implementation.c +++ b/pixman/pixman/pixman-implementation.c @@ -150,9 +150,16 @@ _pixman_implementation_lookup_composite (pixman_implementation_t *toplevel, } /* We should never reach this point */ - _pixman_log_error (FUNC, "No known composite function\n"); + _pixman_log_error ( + FUNC, + "No composite function found\n" + "\n" + "The most likely cause of this is that this system has issues with\n" + "thread local storage\n"); + *out_imp = NULL; *out_func = dummy_composite_rect; + return; update_cache: if (i) diff --git a/pixman/pixman/pixman-private.h b/pixman/pixman/pixman-private.h index cb78a2ed8..181ab5c35 100644 --- a/pixman/pixman/pixman-private.h +++ b/pixman/pixman/pixman-private.h @@ -1014,15 +1014,13 @@ float pixman_unorm_to_float (uint16_t u, int n_bits); #endif -#ifdef DEBUG - void _pixman_log_error (const char *function, const char *message); #define return_if_fail(expr) \ do \ { \ - if (!(expr)) \ + if (unlikely (!(expr))) \ { \ _pixman_log_error (FUNC, "The expression " # expr " was false"); \ return; \ @@ -1033,7 +1031,7 @@ _pixman_log_error (const char *function, const char *message); #define return_val_if_fail(expr, retval) \ do \ { \ - if (!(expr)) \ + if (unlikely (!(expr))) \ { \ _pixman_log_error (FUNC, "The expression " # expr " was false"); \ return (retval); \ @@ -1044,39 +1042,11 @@ _pixman_log_error (const char *function, const char *message); #define critical_if_fail(expr) \ do \ { \ - if (!(expr)) \ + if (unlikely (!(expr))) \ _pixman_log_error (FUNC, "The expression " # expr " was false"); \ } \ while (0) - -#else - -#define _pixman_log_error(f,m) do { } while (0) - -#define return_if_fail(expr) \ - do \ - { \ - if (!(expr)) \ - return; \ - } \ - while (0) - -#define return_val_if_fail(expr, retval) \ - do \ - { \ - if (!(expr)) \ - return (retval); \ - } \ - while (0) - -#define critical_if_fail(expr) \ - do \ - { \ - } \ - while (0) -#endif - /* * Matrix */ diff --git a/pixman/pixman/pixman-sse2.c b/pixman/pixman/pixman-sse2.c index f04ea92d9..1d525794e 100755 --- a/pixman/pixman/pixman-sse2.c +++ b/pixman/pixman/pixman-sse2.c @@ -4558,7 +4558,7 @@ sse2_composite_add_n_8888 (pixman_implementation_t *imp, dst = dst_line; dst_line += dst_stride; - while (w && (unsigned long)dst & 15) + while (w && (uintptr_t)dst & 15) { d = *dst; *dst++ = @@ -4617,7 +4617,7 @@ sse2_composite_add_n_8_8888 (pixman_implementation_t *imp, mask_line += mask_stride; w = width; - while (w && ((unsigned long)dst & 15)) + while (w && ((uintptr_t)dst & 15)) { uint8_t m = *mask++; if (m) diff --git a/pixman/pixman/pixman-utils.c b/pixman/pixman/pixman-utils.c index b1e9fb62d..f31171f6d 100644 --- a/pixman/pixman/pixman-utils.c +++ b/pixman/pixman/pixman-utils.c @@ -292,8 +292,6 @@ _pixman_internal_only_get_implementation (void) return get_implementation (); } -#ifdef DEBUG - void _pixman_log_error (const char *function, const char *message) { @@ -310,5 +308,3 @@ _pixman_log_error (const char *function, const char *message) n_messages++; } } - -#endif diff --git a/pixman/test/Makefile.am b/pixman/test/Makefile.am index ca87f4ef4..5d901d572 100644 --- a/pixman/test/Makefile.am +++ b/pixman/test/Makefile.am @@ -8,6 +8,6 @@ AM_CPPFLAGS = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman $(PNG_CFLAGS) libutils_la_SOURCES = $(libutils_sources) $(libutils_headers) noinst_LTLIBRARIES = libutils.la -noinst_PROGRAMS = $(TESTPROGRAMS) $(BENCHMARKS) +noinst_PROGRAMS = $(TESTPROGRAMS) $(OTHERPROGRAMS) TESTS = $(TESTPROGRAMS) diff --git a/pixman/test/Makefile.sources b/pixman/test/Makefile.sources index e323a8e8c..5b30970b9 100644 --- a/pixman/test/Makefile.sources +++ b/pixman/test/Makefile.sources @@ -6,6 +6,7 @@ TESTPROGRAMS = \ region-test \ region-translate-test \ combiner-test \ + pixel-test \ fetch-test \ rotate-test \ oob-test \ @@ -28,8 +29,9 @@ TESTPROGRAMS = \ $(NULL) # Benchmarks -BENCHMARKS = \ +OTHERPROGRAMS = \ lowlevel-blt-bench \ + check-formats \ $(NULL) # Utility functions diff --git a/pixman/test/a1-trap-test.c b/pixman/test/a1-trap-test.c index 93c6caa14..c2b488316 100644 --- a/pixman/test/a1-trap-test.c +++ b/pixman/test/a1-trap-test.c @@ -45,6 +45,14 @@ main (int argc, char **argv) assert (bits[1] == 0xffffffff); assert (bits[1 * WIDTH + 0] == 0xffffffff); assert (bits[1 * WIDTH + 1] == 0xffffffff); + + /* The check-formats test depends on operator_name() and format_name() returning + * these precise formats, so if those change, check-formats.c must be updated too. + */ + assert ( + strcmp (operator_name (PIXMAN_OP_DISJOINT_OVER), "PIXMAN_OP_DISJOINT_OVER") == 0); + assert ( + strcmp (format_name (PIXMAN_r5g6b5), "r5g6b5") == 0); return 0; } diff --git a/pixman/test/check-formats.c b/pixman/test/check-formats.c new file mode 100644 index 000000000..7edc198c1 --- /dev/null +++ b/pixman/test/check-formats.c @@ -0,0 +1,352 @@ +#include <ctype.h> +#include "utils.h" + +static int +check_op (pixman_op_t op, + pixman_format_code_t src_format, + pixman_format_code_t dest_format) +{ + uint32_t src_alpha_mask, src_green_mask; + uint32_t dest_alpha_mask, dest_green_mask; + pixel_checker_t src_checker, dest_checker; + pixman_image_t *si, *di; + uint32_t sa, sg, da, dg; + uint32_t s, d; + int retval = 0; + + pixel_checker_init (&src_checker, src_format); + pixel_checker_init (&dest_checker, dest_format); + + pixel_checker_get_masks ( + &src_checker, &src_alpha_mask, NULL, &src_green_mask, NULL); + pixel_checker_get_masks ( + &dest_checker, &dest_alpha_mask, NULL, &dest_green_mask, NULL); + + /* printf ("masks: %x %x %x %x\n", */ + /* src_alpha_mask, src_green_mask, */ + /* dest_alpha_mask, dest_green_mask); */ + + si = pixman_image_create_bits (src_format, 1, 1, &s, 4); + di = pixman_image_create_bits (dest_format, 1, 1, &d, 4); + + sa = 0; + do + { + sg = 0; + do + { + da = 0; + do + { + dg = 0; + do + { + color_t src_color, dest_color, result_color; + uint32_t orig_d; + + s = sa | sg; + d = da | dg; + + orig_d = d; + + pixel_checker_convert_pixel_to_color (&src_checker, s, &src_color); + pixel_checker_convert_pixel_to_color (&dest_checker, d, &dest_color); + + do_composite (op, &src_color, NULL, &dest_color, &result_color, FALSE); + + + if (!is_little_endian()) + { + s <<= 32 - PIXMAN_FORMAT_BPP (src_format); + d <<= 32 - PIXMAN_FORMAT_BPP (dest_format); + } + + pixman_image_composite32 (op, si, NULL, di, + 0, 0, 0, 0, 0, 0, 1, 1); + + if (!is_little_endian()) + d >>= (32 - PIXMAN_FORMAT_BPP (dest_format)); + + if (!pixel_checker_check (&dest_checker, d, &result_color)) + { + printf ("---- test failed ----\n"); + printf ("operator: %-32s\n", operator_name (op)); + printf ("source: %-12s pixel: %08x\n", format_name (src_format), s); + printf ("dest: %-12s pixel: %08x\n", format_name (dest_format), orig_d); + printf ("got: %-12s pixel: %08x\n", format_name (dest_format), d); + + retval = 1; + } + + dg -= dest_green_mask; + dg &= dest_green_mask; + } + while (dg != 0); + + da -= dest_alpha_mask; + da &= dest_alpha_mask; + } + while (da != 0); + + sg -= src_green_mask; + sg &= src_green_mask; + } + while (sg != 0); + + sa -= src_alpha_mask; + sa &= src_alpha_mask; + } + while (sa != 0); + + pixman_image_unref (si); + pixman_image_unref (di); + + return retval; +} + +static const pixman_op_t op_list[] = +{ + PIXMAN_OP_CLEAR, + PIXMAN_OP_SRC, + PIXMAN_OP_DST, + PIXMAN_OP_OVER, + PIXMAN_OP_OVER_REVERSE, + PIXMAN_OP_IN, + PIXMAN_OP_IN_REVERSE, + PIXMAN_OP_OUT, + PIXMAN_OP_OUT_REVERSE, + PIXMAN_OP_ATOP, + PIXMAN_OP_ATOP_REVERSE, + PIXMAN_OP_XOR, + PIXMAN_OP_ADD, + PIXMAN_OP_SATURATE, + + PIXMAN_OP_DISJOINT_CLEAR, + PIXMAN_OP_DISJOINT_SRC, + PIXMAN_OP_DISJOINT_DST, + PIXMAN_OP_DISJOINT_OVER, + PIXMAN_OP_DISJOINT_OVER_REVERSE, + PIXMAN_OP_DISJOINT_IN, + PIXMAN_OP_DISJOINT_IN_REVERSE, + PIXMAN_OP_DISJOINT_OUT, + PIXMAN_OP_DISJOINT_OUT_REVERSE, + PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_OP_DISJOINT_XOR, + + PIXMAN_OP_CONJOINT_CLEAR, + PIXMAN_OP_CONJOINT_SRC, + PIXMAN_OP_CONJOINT_DST, + PIXMAN_OP_CONJOINT_OVER, + PIXMAN_OP_CONJOINT_OVER_REVERSE, + PIXMAN_OP_CONJOINT_IN, + PIXMAN_OP_CONJOINT_IN_REVERSE, + PIXMAN_OP_CONJOINT_OUT, + PIXMAN_OP_CONJOINT_OUT_REVERSE, + PIXMAN_OP_CONJOINT_ATOP, + PIXMAN_OP_CONJOINT_ATOP_REVERSE, + PIXMAN_OP_CONJOINT_XOR, +}; + +static const pixman_format_code_t format_list[] = +{ + PIXMAN_a8r8g8b8, + PIXMAN_x8r8g8b8, + PIXMAN_a8b8g8r8, + PIXMAN_x8b8g8r8, + PIXMAN_b8g8r8a8, + PIXMAN_b8g8r8x8, + PIXMAN_r8g8b8a8, + PIXMAN_r8g8b8x8, + PIXMAN_x14r6g6b6, + PIXMAN_x2r10g10b10, + PIXMAN_a2r10g10b10, + PIXMAN_x2b10g10r10, + PIXMAN_a2b10g10r10, + PIXMAN_a8r8g8b8_sRGB, + PIXMAN_r8g8b8, + PIXMAN_b8g8r8, + PIXMAN_r5g6b5, + PIXMAN_b5g6r5, + PIXMAN_a1r5g5b5, + PIXMAN_x1r5g5b5, + PIXMAN_a1b5g5r5, + PIXMAN_x1b5g5r5, + PIXMAN_a4r4g4b4, + PIXMAN_x4r4g4b4, + PIXMAN_a4b4g4r4, + PIXMAN_x4b4g4r4, + PIXMAN_a8, + PIXMAN_r3g3b2, + PIXMAN_b2g3r3, + PIXMAN_a2r2g2b2, + PIXMAN_a2b2g2r2, + PIXMAN_x4a4, + PIXMAN_a4, + PIXMAN_r1g2b1, + PIXMAN_b1g2r1, + PIXMAN_a1r1g1b1, + PIXMAN_a1b1g1r1, + PIXMAN_a1, +}; + +static pixman_format_code_t +format_from_string (const char *s) +{ + int i; + + for (i = 0; i < ARRAY_LENGTH (format_list); ++i) + { + if (strcasecmp (format_name (format_list[i]), s) == 0) + return format_list[i]; + } + + return PIXMAN_null; +} + +static void +emit (const char *s, int *n_chars) +{ + *n_chars += printf ("%s,", s); + if (*n_chars > 60) + { + printf ("\n "); + *n_chars = 0; + } + else + { + printf (" "); + (*n_chars)++; + } +} + +static void +list_formats (void) +{ + int n_chars; + int i; + + printf ("Formats:\n "); + + n_chars = 0; + for (i = 0; i < ARRAY_LENGTH (format_list); ++i) + emit (format_name (format_list[i]), &n_chars); + + printf ("\n\n"); +} + +static void +list_operators (void) +{ + char short_name [128] = { 0 }; + int i, n_chars; + + printf ("Operators:\n "); + + n_chars = 0; + for (i = 0; i < ARRAY_LENGTH (op_list); ++i) + { + pixman_op_t op = op_list[i]; + int j; + + snprintf (short_name, sizeof (short_name) - 1, "%s", + operator_name (op) + strlen ("PIXMAN_OP_")); + + for (j = 0; short_name[j] != '\0'; ++j) + short_name[j] = tolower (short_name[j]); + + emit (short_name, &n_chars); + } + + printf ("\n\n"); +} + +static pixman_op_t +operator_from_string (const char *s) +{ + char full_name[128] = { 0 }; + int i; + + snprintf (full_name, (sizeof full_name) - 1, "PIXMAN_OP_%s", s); + + for (i = 0; i < ARRAY_LENGTH (op_list); ++i) + { + pixman_op_t op = op_list[i]; + + if (strcasecmp (operator_name (op), full_name) == 0) + return op; + } + + return PIXMAN_OP_NONE; +} + +int +main (int argc, char **argv) +{ + enum { OPTION_OP, OPTION_SRC, OPTION_DEST, LAST_OPTION } option; + pixman_format_code_t src_fmt, dest_fmt; + pixman_op_t op; + + op = PIXMAN_OP_NONE; + src_fmt = PIXMAN_null; + dest_fmt = PIXMAN_null; + + argc--; + argv++; + + for (option = OPTION_OP; option < LAST_OPTION; ++option) + { + char *arg = NULL; + + if (argc) + { + argc--; + arg = *argv++; + } + + switch (option) + { + case OPTION_OP: + if (!arg) + printf (" - missing operator\n"); + else if ((op = operator_from_string (arg)) == PIXMAN_OP_NONE) + printf (" - unknown operator %s\n", arg); + break; + + case OPTION_SRC: + if (!arg) + printf (" - missing source format\n"); + else if ((src_fmt = format_from_string (arg)) == PIXMAN_null) + printf (" - unknown source format %s\n", arg); + break; + + case OPTION_DEST: + if (!arg) + printf (" - missing destination format\n"); + else if ((dest_fmt = format_from_string (arg)) == PIXMAN_null) + printf (" - unknown destination format %s\n", arg); + break; + + default: + assert (0); + break; + } + } + + while (argc--) + { + op = PIXMAN_OP_NONE; + printf (" - unexpected argument: %s\n", *argv++); + } + + if (op == PIXMAN_OP_NONE || src_fmt == PIXMAN_null || dest_fmt == PIXMAN_null) + { + printf ("\nUsage:\n check-formats <operator> <src-format> <dest-format>\n\n"); + list_operators(); + list_formats(); + + return -1; + } + + return check_op (op, src_fmt, dest_fmt); +} diff --git a/pixman/test/composite.c b/pixman/test/composite.c index b107b1106..9e51a8f65 100644 --- a/pixman/test/composite.c +++ b/pixman/test/composite.c @@ -181,283 +181,6 @@ static const pixman_op_t operators[] = PIXMAN_OP_CONJOINT_XOR, }; -static double -calc_op (pixman_op_t op, double src, double dst, double srca, double dsta) -{ -#define mult_chan(src, dst, Fa, Fb) MIN ((src) * (Fa) + (dst) * (Fb), 1.0) - - double Fa, Fb; - - switch (op) - { - case PIXMAN_OP_CLEAR: - case PIXMAN_OP_DISJOINT_CLEAR: - case PIXMAN_OP_CONJOINT_CLEAR: - return mult_chan (src, dst, 0.0, 0.0); - - case PIXMAN_OP_SRC: - case PIXMAN_OP_DISJOINT_SRC: - case PIXMAN_OP_CONJOINT_SRC: - return mult_chan (src, dst, 1.0, 0.0); - - case PIXMAN_OP_DST: - case PIXMAN_OP_DISJOINT_DST: - case PIXMAN_OP_CONJOINT_DST: - return mult_chan (src, dst, 0.0, 1.0); - - case PIXMAN_OP_OVER: - return mult_chan (src, dst, 1.0, 1.0 - srca); - - case PIXMAN_OP_OVER_REVERSE: - return mult_chan (src, dst, 1.0 - dsta, 1.0); - - case PIXMAN_OP_IN: - return mult_chan (src, dst, dsta, 0.0); - - case PIXMAN_OP_IN_REVERSE: - return mult_chan (src, dst, 0.0, srca); - - case PIXMAN_OP_OUT: - return mult_chan (src, dst, 1.0 - dsta, 0.0); - - case PIXMAN_OP_OUT_REVERSE: - return mult_chan (src, dst, 0.0, 1.0 - srca); - - case PIXMAN_OP_ATOP: - return mult_chan (src, dst, dsta, 1.0 - srca); - - case PIXMAN_OP_ATOP_REVERSE: - return mult_chan (src, dst, 1.0 - dsta, srca); - - case PIXMAN_OP_XOR: - return mult_chan (src, dst, 1.0 - dsta, 1.0 - srca); - - case PIXMAN_OP_ADD: - return mult_chan (src, dst, 1.0, 1.0); - - case PIXMAN_OP_SATURATE: - case PIXMAN_OP_DISJOINT_OVER_REVERSE: - if (srca == 0.0) - Fa = 1.0; - else - Fa = MIN (1.0, (1.0 - dsta) / srca); - return mult_chan (src, dst, Fa, 1.0); - - case PIXMAN_OP_DISJOINT_OVER: - if (dsta == 0.0) - Fb = 1.0; - else - Fb = MIN (1.0, (1.0 - srca) / dsta); - return mult_chan (src, dst, 1.0, Fb); - - case PIXMAN_OP_DISJOINT_IN: - if (srca == 0.0) - Fa = 0.0; - else - Fa = MAX (0.0, 1.0 - (1.0 - dsta) / srca); - return mult_chan (src, dst, Fa, 0.0); - - case PIXMAN_OP_DISJOINT_IN_REVERSE: - if (dsta == 0.0) - Fb = 0.0; - else - Fb = MAX (0.0, 1.0 - (1.0 - srca) / dsta); - return mult_chan (src, dst, 0.0, Fb); - - case PIXMAN_OP_DISJOINT_OUT: - if (srca == 0.0) - Fa = 1.0; - else - Fa = MIN (1.0, (1.0 - dsta) / srca); - return mult_chan (src, dst, Fa, 0.0); - - case PIXMAN_OP_DISJOINT_OUT_REVERSE: - if (dsta == 0.0) - Fb = 1.0; - else - Fb = MIN (1.0, (1.0 - srca) / dsta); - return mult_chan (src, dst, 0.0, Fb); - - case PIXMAN_OP_DISJOINT_ATOP: - if (srca == 0.0) - Fa = 0.0; - else - Fa = MAX (0.0, 1.0 - (1.0 - dsta) / srca); - if (dsta == 0.0) - Fb = 1.0; - else - Fb = MIN (1.0, (1.0 - srca) / dsta); - return mult_chan (src, dst, Fa, Fb); - - case PIXMAN_OP_DISJOINT_ATOP_REVERSE: - if (srca == 0.0) - Fa = 1.0; - else - Fa = MIN (1.0, (1.0 - dsta) / srca); - if (dsta == 0.0) - Fb = 0.0; - else - Fb = MAX (0.0, 1.0 - (1.0 - srca) / dsta); - return mult_chan (src, dst, Fa, Fb); - - case PIXMAN_OP_DISJOINT_XOR: - if (srca == 0.0) - Fa = 1.0; - else - Fa = MIN (1.0, (1.0 - dsta) / srca); - if (dsta == 0.0) - Fb = 1.0; - else - Fb = MIN (1.0, (1.0 - srca) / dsta); - return mult_chan (src, dst, Fa, Fb); - - case PIXMAN_OP_CONJOINT_OVER: - if (dsta == 0.0) - Fb = 0.0; - else - Fb = MAX (0.0, 1.0 - srca / dsta); - return mult_chan (src, dst, 1.0, Fb); - - case PIXMAN_OP_CONJOINT_OVER_REVERSE: - if (srca == 0.0) - Fa = 0.0; - else - Fa = MAX (0.0, 1.0 - dsta / srca); - return mult_chan (src, dst, Fa, 1.0); - - case PIXMAN_OP_CONJOINT_IN: - if (srca == 0.0) - Fa = 1.0; - else - Fa = MIN (1.0, dsta / srca); - return mult_chan (src, dst, Fa, 0.0); - - case PIXMAN_OP_CONJOINT_IN_REVERSE: - if (dsta == 0.0) - Fb = 1.0; - else - Fb = MIN (1.0, srca / dsta); - return mult_chan (src, dst, 0.0, Fb); - - case PIXMAN_OP_CONJOINT_OUT: - if (srca == 0.0) - Fa = 0.0; - else - Fa = MAX (0.0, 1.0 - dsta / srca); - return mult_chan (src, dst, Fa, 0.0); - - case PIXMAN_OP_CONJOINT_OUT_REVERSE: - if (dsta == 0.0) - Fb = 0.0; - else - Fb = MAX (0.0, 1.0 - srca / dsta); - return mult_chan (src, dst, 0.0, Fb); - - case PIXMAN_OP_CONJOINT_ATOP: - if (srca == 0.0) - Fa = 1.0; - else - Fa = MIN (1.0, dsta / srca); - if (dsta == 0.0) - Fb = 0.0; - else - Fb = MAX (0.0, 1.0 - srca / dsta); - return mult_chan (src, dst, Fa, Fb); - - case PIXMAN_OP_CONJOINT_ATOP_REVERSE: - if (srca == 0.0) - Fa = 0.0; - else - Fa = MAX (0.0, 1.0 - dsta / srca); - if (dsta == 0.0) - Fb = 1.0; - else - Fb = MIN (1.0, srca / dsta); - return mult_chan (src, dst, Fa, Fb); - - case PIXMAN_OP_CONJOINT_XOR: - if (srca == 0.0) - Fa = 0.0; - else - Fa = MAX (0.0, 1.0 - dsta / srca); - if (dsta == 0.0) - Fb = 0.0; - else - Fb = MAX (0.0, 1.0 - srca / dsta); - return mult_chan (src, dst, Fa, Fb); - - case PIXMAN_OP_MULTIPLY: - case PIXMAN_OP_SCREEN: - case PIXMAN_OP_OVERLAY: - case PIXMAN_OP_DARKEN: - case PIXMAN_OP_LIGHTEN: - case PIXMAN_OP_COLOR_DODGE: - case PIXMAN_OP_COLOR_BURN: - case PIXMAN_OP_HARD_LIGHT: - case PIXMAN_OP_SOFT_LIGHT: - case PIXMAN_OP_DIFFERENCE: - case PIXMAN_OP_EXCLUSION: - case PIXMAN_OP_HSL_HUE: - case PIXMAN_OP_HSL_SATURATION: - case PIXMAN_OP_HSL_COLOR: - case PIXMAN_OP_HSL_LUMINOSITY: - default: - abort(); - return 0; /* silence MSVC */ - } -#undef mult_chan -} - -static void -do_composite (pixman_op_t op, - const color_t *src, - const color_t *mask, - const color_t *dst, - color_t *result, - pixman_bool_t component_alpha) -{ - color_t srcval, srcalpha; - - if (mask == NULL) - { - srcval = *src; - - srcalpha.r = src->a; - srcalpha.g = src->a; - srcalpha.b = src->a; - srcalpha.a = src->a; - } - else if (component_alpha) - { - srcval.r = src->r * mask->r; - srcval.g = src->g * mask->g; - srcval.b = src->b * mask->b; - srcval.a = src->a * mask->a; - - srcalpha.r = src->a * mask->r; - srcalpha.g = src->a * mask->g; - srcalpha.b = src->a * mask->b; - srcalpha.a = src->a * mask->a; - } - else - { - srcval.r = src->r * mask->a; - srcval.g = src->g * mask->a; - srcval.b = src->b * mask->a; - srcval.a = src->a * mask->a; - - srcalpha.r = src->a * mask->a; - srcalpha.g = src->a * mask->a; - srcalpha.b = src->a * mask->a; - srcalpha.a = src->a * mask->a; - } - - result->r = calc_op (op, srcval.r, dst->r, srcalpha.r, dst->a); - result->g = calc_op (op, srcval.g, dst->g, srcalpha.g, dst->a); - result->b = calc_op (op, srcval.b, dst->b, srcalpha.b, dst->a); - result->a = calc_op (op, srcval.a, dst->a, srcalpha.a, dst->a); -} - static uint32_t get_value (pixman_image_t *image) { diff --git a/pixman/test/lowlevel-blt-bench.c b/pixman/test/lowlevel-blt-bench.c index 8e80b4280..4e16f7ba1 100644 --- a/pixman/test/lowlevel-blt-bench.c +++ b/pixman/test/lowlevel-blt-bench.c @@ -460,8 +460,8 @@ bench_composite (char * testname, printf ("%24s %c", testname, func != pixman_image_composite_wrapper ? '-' : '='); - memcpy (src, dst, BUFSIZE); memcpy (dst, src, BUFSIZE); + memcpy (src, dst, BUFSIZE); l1test_width = L1CACHE_SIZE / 8 - 64; if (l1test_width < 1) @@ -480,8 +480,8 @@ bench_composite (char * testname, ((t3 - t2) - (t2 - t1)) / 1000000.); fflush (stdout); - memcpy (src, dst, BUFSIZE); memcpy (dst, src, BUFSIZE); + memcpy (src, dst, BUFSIZE); nlines = (L2CACHE_SIZE / l1test_width) / ((PIXMAN_FORMAT_BPP(src_fmt) + PIXMAN_FORMAT_BPP(dst_fmt)) / 8); @@ -499,8 +499,8 @@ bench_composite (char * testname, ((t3 - t2) - (t2 - t1)) / 1000000.); fflush (stdout); - memcpy (src, dst, BUFSIZE); memcpy (dst, src, BUFSIZE); + memcpy (src, dst, BUFSIZE); n = 1 + npix / (WIDTH * HEIGHT); t1 = gettime (); @@ -515,8 +515,8 @@ bench_composite (char * testname, ((double)n * (WIDTH - 64) * HEIGHT / ((t3 - t2) - (t2 - t1)) * bytes_per_pix) * (100.0 / bandwidth) ); fflush (stdout); - memcpy (src, dst, BUFSIZE); memcpy (dst, src, BUFSIZE); + memcpy (src, dst, BUFSIZE); n = 1 + npix / (8 * TILEWIDTH * TILEWIDTH); t1 = gettime (); @@ -529,8 +529,8 @@ bench_composite (char * testname, printf (" HT:%6.2f", (double)pix_cnt / ((t3 - t2) - (t2 - t1)) / 1000000.); fflush (stdout); - memcpy (src, dst, BUFSIZE); memcpy (dst, src, BUFSIZE); + memcpy (src, dst, BUFSIZE); n = 1 + npix / (8 * TILEWIDTH * TILEWIDTH); t1 = gettime (); @@ -543,8 +543,8 @@ bench_composite (char * testname, printf (" VT:%6.2f", (double)pix_cnt / ((t3 - t2) - (t2 - t1)) / 1000000.); fflush (stdout); - memcpy (src, dst, BUFSIZE); memcpy (dst, src, BUFSIZE); + memcpy (src, dst, BUFSIZE); n = 1 + npix / (8 * TILEWIDTH * TILEWIDTH); t1 = gettime (); @@ -557,8 +557,8 @@ bench_composite (char * testname, printf (" R:%6.2f", (double)pix_cnt / ((t3 - t2) - (t2 - t1)) / 1000000.); fflush (stdout); - memcpy (src, dst, BUFSIZE); memcpy (dst, src, BUFSIZE); + memcpy (src, dst, BUFSIZE); n = 1 + npix / (16 * TINYWIDTH * TINYWIDTH); t1 = gettime (); diff --git a/pixman/test/pixel-test.c b/pixman/test/pixel-test.c new file mode 100644 index 000000000..8c525d202 --- /dev/null +++ b/pixman/test/pixel-test.c @@ -0,0 +1,267 @@ +/* + * Copyright © 2013 Soeren Sandmann + * Copyright © 2013 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#include <stdio.h> +#include <stdlib.h> /* abort() */ +#include <math.h> +#include <time.h> +#include "utils.h" + +typedef struct pixel_combination_t pixel_combination_t; +struct pixel_combination_t +{ + pixman_op_t op; + pixman_format_code_t src_format; + uint32_t src_pixel; + pixman_format_code_t dest_format; + uint32_t dest_pixel; +}; + +static const pixel_combination_t regressions[] = +{ + { PIXMAN_OP_OVER, + PIXMAN_a8r8g8b8, 0x0f00c300, + PIXMAN_x14r6g6b6, 0x003c0, + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a4r4g4b4, 0xd0c0, + PIXMAN_a8r8g8b8, 0x5300ea00, + }, + { PIXMAN_OP_OVER, + PIXMAN_a8r8g8b8, 0x20c6bf00, + PIXMAN_r5g6b5, 0xb9ff + }, + { PIXMAN_OP_OVER, + PIXMAN_a8r8g8b8, 0x204ac7ff, + PIXMAN_r5g6b5, 0xc1ff + }, + { PIXMAN_OP_OVER_REVERSE, + PIXMAN_r5g6b5, 0xffc3, + PIXMAN_a8r8g8b8, 0x102d00dd + }, + { PIXMAN_OP_OVER_REVERSE, + PIXMAN_r5g6b5, 0x1f00, + PIXMAN_a8r8g8b8, 0x1bdf0c89 + }, + { PIXMAN_OP_OVER_REVERSE, + PIXMAN_r5g6b5, 0xf9d2, + PIXMAN_a8r8g8b8, 0x1076bcf7 + }, + { PIXMAN_OP_OVER_REVERSE, + PIXMAN_r5g6b5, 0x00c3, + PIXMAN_a8r8g8b8, 0x1bfe9ae5 + }, + { PIXMAN_OP_OVER_REVERSE, + PIXMAN_r5g6b5, 0x09ff, + PIXMAN_a8r8g8b8, 0x0b00c16c + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a2r2g2b2, 0xbc, + PIXMAN_a8r8g8b8, 0x9efff1ff + }, + { PIXMAN_OP_DISJOINT_ATOP, + PIXMAN_a4r4g4b4, 0xae5f, + PIXMAN_a8r8g8b8, 0xf215b675 + }, + { PIXMAN_OP_DISJOINT_ATOP_REVERSE, + PIXMAN_a8r8g8b8, 0xce007980, + PIXMAN_a8r8g8b8, 0x80ffe4ad + }, + { PIXMAN_OP_DISJOINT_XOR, + PIXMAN_a8r8g8b8, 0xb8b07bea, + PIXMAN_a4r4g4b4, 0x939c + }, + { PIXMAN_OP_CONJOINT_ATOP_REVERSE, + PIXMAN_r5g6b5, 0x0063, + PIXMAN_a8r8g8b8, 0x10bb1ed7, + }, +}; + +static void +fill (pixman_image_t *image, uint32_t pixel) +{ + uint8_t *data = (uint8_t *)pixman_image_get_data (image); + int bytes_per_pixel = PIXMAN_FORMAT_BPP (pixman_image_get_format (image)) / 8; + int n_bytes = pixman_image_get_stride (image) * pixman_image_get_height (image); + int i; + + switch (bytes_per_pixel) + { + case 4: + for (i = 0; i < n_bytes / 4; ++i) + ((uint32_t *)data)[i] = pixel; + break; + + case 2: + pixel &= 0xffff; + for (i = 0; i < n_bytes / 2; ++i) + ((uint16_t *)data)[i] = pixel; + break; + + case 1: + pixel &= 0xff; + for (i = 0; i < n_bytes; ++i) + ((uint8_t *)data)[i] = pixel; + break; + + default: + assert (0); + break; + } +} + +static uint32_t +access (pixman_image_t *image, int x, int y) +{ + int bytes_per_pixel; + int stride; + uint32_t result; + uint8_t *location; + + if (x < 0 || x >= image->bits.width || y < 0 || y >= image->bits.height) + return 0; + + bytes_per_pixel = PIXMAN_FORMAT_BPP (image->bits.format) / 8; + stride = image->bits.rowstride * 4; + + location = (uint8_t *)image->bits.bits + y * stride + x * bytes_per_pixel; + + if (bytes_per_pixel == 4) + result = *(uint32_t *)location; + else if (bytes_per_pixel == 2) + result = *(uint16_t *)location; + else if (bytes_per_pixel == 1) + result = *(uint8_t *)location; + else + assert (0); + + return result; +} + +static pixman_bool_t +verify (int test_no, const pixel_combination_t *combination, int size) +{ + pixman_image_t *src, *dest; + pixel_checker_t src_checker, dest_checker; + color_t source_color, dest_color, reference_color; + pixman_bool_t result = TRUE; + int i, j; + + /* Compute reference color */ + pixel_checker_init (&src_checker, combination->src_format); + pixel_checker_init (&dest_checker, combination->dest_format); + pixel_checker_convert_pixel_to_color ( + &src_checker, combination->src_pixel, &source_color); + pixel_checker_convert_pixel_to_color ( + &dest_checker, combination->dest_pixel, &dest_color); + do_composite (combination->op, + &source_color, NULL, &dest_color, + &reference_color, FALSE); + + src = pixman_image_create_bits ( + combination->src_format, size, size, NULL, -1); + dest = pixman_image_create_bits ( + combination->dest_format, size, size, NULL, -1); + + fill (src, combination->src_pixel); + fill (dest, combination->dest_pixel); + + pixman_image_composite32 ( + combination->op, src, NULL, dest, 0, 0, 0, 0, 0, 0, size, size); + + for (j = 0; j < size; ++j) + { + for (i = 0; i < size; ++i) + { + uint32_t computed = access (dest, i, j); + int32_t a, r, g, b; + + if (!pixel_checker_check (&dest_checker, computed, &reference_color)) + { + printf ("----------- Test %d failed ----------\n", test_no); + + printf (" operator: %s\n", operator_name (combination->op)); + printf (" src format: %s\n", format_name (combination->src_format)); + printf (" dest format: %s\n", format_name (combination->dest_format)); + printf (" - source ARGB: %f %f %f %f (pixel: %8x)\n", + source_color.a, source_color.r, source_color.g, source_color.b, + combination->src_pixel); + pixel_checker_split_pixel (&src_checker, combination->src_pixel, + &a, &r, &g, &b); + printf (" %8d %8d %8d %8d\n", a, r, g, b); + + printf (" - dest ARGB: %f %f %f %f (pixel: %8x)\n", + dest_color.a, dest_color.r, dest_color.g, dest_color.b, + combination->dest_pixel); + pixel_checker_split_pixel (&dest_checker, combination->dest_pixel, + &a, &r, &g, &b); + printf (" %8d %8d %8d %8d\n", a, r, g, b); + + pixel_checker_split_pixel (&dest_checker, computed, &a, &r, &g, &b); + printf (" - expected ARGB: %f %f %f %f\n", + reference_color.a, reference_color.r, reference_color.g, reference_color.b); + + pixel_checker_get_min (&dest_checker, &reference_color, &a, &r, &g, &b); + printf (" min acceptable: %8d %8d %8d %8d\n", a, r, g, b); + + pixel_checker_split_pixel (&dest_checker, computed, &a, &r, &g, &b); + printf (" got: %8d %8d %8d %8d (pixel: %8x)\n", a, r, g, b, computed); + + pixel_checker_get_max (&dest_checker, &reference_color, &a, &r, &g, &b); + printf (" max acceptable: %8d %8d %8d %8d\n", a, r, g, b); + + result = FALSE; + goto done; + } + } + } + +done: + pixman_image_unref (src); + pixman_image_unref (dest); + + return result; +} + +int +main (int argc, char **argv) +{ + int result = 0; + int i, j; + + for (i = 0; i < ARRAY_LENGTH (regressions); ++i) + { + const pixel_combination_t *combination = &(regressions[i]); + + for (j = 1; j < 34; ++j) + { + if (!verify (i, combination, j)) + { + result = 1; + break; + } + } + } + + return result; +} diff --git a/pixman/test/utils.c b/pixman/test/utils.c index ba7e35335..3d1ba22ae 100644 --- a/pixman/test/utils.c +++ b/pixman/test/utils.c @@ -1033,6 +1033,283 @@ format_name (pixman_format_code_t format) }; static double +calc_op (pixman_op_t op, double src, double dst, double srca, double dsta) +{ +#define mult_chan(src, dst, Fa, Fb) MIN ((src) * (Fa) + (dst) * (Fb), 1.0) + + double Fa, Fb; + + switch (op) + { + case PIXMAN_OP_CLEAR: + case PIXMAN_OP_DISJOINT_CLEAR: + case PIXMAN_OP_CONJOINT_CLEAR: + return mult_chan (src, dst, 0.0, 0.0); + + case PIXMAN_OP_SRC: + case PIXMAN_OP_DISJOINT_SRC: + case PIXMAN_OP_CONJOINT_SRC: + return mult_chan (src, dst, 1.0, 0.0); + + case PIXMAN_OP_DST: + case PIXMAN_OP_DISJOINT_DST: + case PIXMAN_OP_CONJOINT_DST: + return mult_chan (src, dst, 0.0, 1.0); + + case PIXMAN_OP_OVER: + return mult_chan (src, dst, 1.0, 1.0 - srca); + + case PIXMAN_OP_OVER_REVERSE: + return mult_chan (src, dst, 1.0 - dsta, 1.0); + + case PIXMAN_OP_IN: + return mult_chan (src, dst, dsta, 0.0); + + case PIXMAN_OP_IN_REVERSE: + return mult_chan (src, dst, 0.0, srca); + + case PIXMAN_OP_OUT: + return mult_chan (src, dst, 1.0 - dsta, 0.0); + + case PIXMAN_OP_OUT_REVERSE: + return mult_chan (src, dst, 0.0, 1.0 - srca); + + case PIXMAN_OP_ATOP: + return mult_chan (src, dst, dsta, 1.0 - srca); + + case PIXMAN_OP_ATOP_REVERSE: + return mult_chan (src, dst, 1.0 - dsta, srca); + + case PIXMAN_OP_XOR: + return mult_chan (src, dst, 1.0 - dsta, 1.0 - srca); + + case PIXMAN_OP_ADD: + return mult_chan (src, dst, 1.0, 1.0); + + case PIXMAN_OP_SATURATE: + case PIXMAN_OP_DISJOINT_OVER_REVERSE: + if (srca == 0.0) + Fa = 1.0; + else + Fa = MIN (1.0, (1.0 - dsta) / srca); + return mult_chan (src, dst, Fa, 1.0); + + case PIXMAN_OP_DISJOINT_OVER: + if (dsta == 0.0) + Fb = 1.0; + else + Fb = MIN (1.0, (1.0 - srca) / dsta); + return mult_chan (src, dst, 1.0, Fb); + + case PIXMAN_OP_DISJOINT_IN: + if (srca == 0.0) + Fa = 0.0; + else + Fa = MAX (0.0, 1.0 - (1.0 - dsta) / srca); + return mult_chan (src, dst, Fa, 0.0); + + case PIXMAN_OP_DISJOINT_IN_REVERSE: + if (dsta == 0.0) + Fb = 0.0; + else + Fb = MAX (0.0, 1.0 - (1.0 - srca) / dsta); + return mult_chan (src, dst, 0.0, Fb); + + case PIXMAN_OP_DISJOINT_OUT: + if (srca == 0.0) + Fa = 1.0; + else + Fa = MIN (1.0, (1.0 - dsta) / srca); + return mult_chan (src, dst, Fa, 0.0); + + case PIXMAN_OP_DISJOINT_OUT_REVERSE: + if (dsta == 0.0) + Fb = 1.0; + else + Fb = MIN (1.0, (1.0 - srca) / dsta); + return mult_chan (src, dst, 0.0, Fb); + + case PIXMAN_OP_DISJOINT_ATOP: + if (srca == 0.0) + Fa = 0.0; + else + Fa = MAX (0.0, 1.0 - (1.0 - dsta) / srca); + if (dsta == 0.0) + Fb = 1.0; + else + Fb = MIN (1.0, (1.0 - srca) / dsta); + return mult_chan (src, dst, Fa, Fb); + + case PIXMAN_OP_DISJOINT_ATOP_REVERSE: + if (srca == 0.0) + Fa = 1.0; + else + Fa = MIN (1.0, (1.0 - dsta) / srca); + if (dsta == 0.0) + Fb = 0.0; + else + Fb = MAX (0.0, 1.0 - (1.0 - srca) / dsta); + return mult_chan (src, dst, Fa, Fb); + + case PIXMAN_OP_DISJOINT_XOR: + if (srca == 0.0) + Fa = 1.0; + else + Fa = MIN (1.0, (1.0 - dsta) / srca); + if (dsta == 0.0) + Fb = 1.0; + else + Fb = MIN (1.0, (1.0 - srca) / dsta); + return mult_chan (src, dst, Fa, Fb); + + case PIXMAN_OP_CONJOINT_OVER: + if (dsta == 0.0) + Fb = 0.0; + else + Fb = MAX (0.0, 1.0 - srca / dsta); + return mult_chan (src, dst, 1.0, Fb); + + case PIXMAN_OP_CONJOINT_OVER_REVERSE: + if (srca == 0.0) + Fa = 0.0; + else + Fa = MAX (0.0, 1.0 - dsta / srca); + return mult_chan (src, dst, Fa, 1.0); + + case PIXMAN_OP_CONJOINT_IN: + if (srca == 0.0) + Fa = 1.0; + else + Fa = MIN (1.0, dsta / srca); + return mult_chan (src, dst, Fa, 0.0); + + case PIXMAN_OP_CONJOINT_IN_REVERSE: + if (dsta == 0.0) + Fb = 1.0; + else + Fb = MIN (1.0, srca / dsta); + return mult_chan (src, dst, 0.0, Fb); + + case PIXMAN_OP_CONJOINT_OUT: + if (srca == 0.0) + Fa = 0.0; + else + Fa = MAX (0.0, 1.0 - dsta / srca); + return mult_chan (src, dst, Fa, 0.0); + + case PIXMAN_OP_CONJOINT_OUT_REVERSE: + if (dsta == 0.0) + Fb = 0.0; + else + Fb = MAX (0.0, 1.0 - srca / dsta); + return mult_chan (src, dst, 0.0, Fb); + + case PIXMAN_OP_CONJOINT_ATOP: + if (srca == 0.0) + Fa = 1.0; + else + Fa = MIN (1.0, dsta / srca); + if (dsta == 0.0) + Fb = 0.0; + else + Fb = MAX (0.0, 1.0 - srca / dsta); + return mult_chan (src, dst, Fa, Fb); + + case PIXMAN_OP_CONJOINT_ATOP_REVERSE: + if (srca == 0.0) + Fa = 0.0; + else + Fa = MAX (0.0, 1.0 - dsta / srca); + if (dsta == 0.0) + Fb = 1.0; + else + Fb = MIN (1.0, srca / dsta); + return mult_chan (src, dst, Fa, Fb); + + case PIXMAN_OP_CONJOINT_XOR: + if (srca == 0.0) + Fa = 0.0; + else + Fa = MAX (0.0, 1.0 - dsta / srca); + if (dsta == 0.0) + Fb = 0.0; + else + Fb = MAX (0.0, 1.0 - srca / dsta); + return mult_chan (src, dst, Fa, Fb); + + case PIXMAN_OP_MULTIPLY: + case PIXMAN_OP_SCREEN: + case PIXMAN_OP_OVERLAY: + case PIXMAN_OP_DARKEN: + case PIXMAN_OP_LIGHTEN: + case PIXMAN_OP_COLOR_DODGE: + case PIXMAN_OP_COLOR_BURN: + case PIXMAN_OP_HARD_LIGHT: + case PIXMAN_OP_SOFT_LIGHT: + case PIXMAN_OP_DIFFERENCE: + case PIXMAN_OP_EXCLUSION: + case PIXMAN_OP_HSL_HUE: + case PIXMAN_OP_HSL_SATURATION: + case PIXMAN_OP_HSL_COLOR: + case PIXMAN_OP_HSL_LUMINOSITY: + default: + abort(); + return 0; /* silence MSVC */ + } +#undef mult_chan +} + +void +do_composite (pixman_op_t op, + const color_t *src, + const color_t *mask, + const color_t *dst, + color_t *result, + pixman_bool_t component_alpha) +{ + color_t srcval, srcalpha; + + if (mask == NULL) + { + srcval = *src; + + srcalpha.r = src->a; + srcalpha.g = src->a; + srcalpha.b = src->a; + srcalpha.a = src->a; + } + else if (component_alpha) + { + srcval.r = src->r * mask->r; + srcval.g = src->g * mask->g; + srcval.b = src->b * mask->b; + srcval.a = src->a * mask->a; + + srcalpha.r = src->a * mask->r; + srcalpha.g = src->a * mask->g; + srcalpha.b = src->a * mask->b; + srcalpha.a = src->a * mask->a; + } + else + { + srcval.r = src->r * mask->a; + srcval.g = src->g * mask->a; + srcval.b = src->b * mask->a; + srcval.a = src->a * mask->a; + + srcalpha.r = src->a * mask->a; + srcalpha.g = src->a * mask->a; + srcalpha.b = src->a * mask->a; + srcalpha.a = src->a * mask->a; + } + + result->r = calc_op (op, srcval.r, dst->r, srcalpha.r, dst->a); + result->g = calc_op (op, srcval.g, dst->g, srcalpha.g, dst->a); + result->b = calc_op (op, srcval.b, dst->b, srcalpha.b, dst->a); + result->a = calc_op (op, srcval.a, dst->a, srcalpha.a, dst->a); +} + +static double round_channel (double p, int m) { int t; @@ -1144,6 +1421,59 @@ pixel_checker_split_pixel (const pixel_checker_t *checker, uint32_t pixel, *b = (pixel & checker->bm) >> checker->bs; } +void +pixel_checker_get_masks (const pixel_checker_t *checker, + uint32_t *am, + uint32_t *rm, + uint32_t *gm, + uint32_t *bm) +{ + if (am) + *am = checker->am; + if (rm) + *rm = checker->rm; + if (gm) + *gm = checker->gm; + if (bm) + *bm = checker->bm; +} + +void +pixel_checker_convert_pixel_to_color (const pixel_checker_t *checker, + uint32_t pixel, color_t *color) +{ + int a, r, g, b; + + pixel_checker_split_pixel (checker, pixel, &a, &r, &g, &b); + + if (checker->am == 0) + color->a = 1.0; + else + color->a = a / (double)(checker->am >> checker->as); + + if (checker->rm == 0) + color->r = 0.0; + else + color->r = r / (double)(checker->rm >> checker->rs); + + if (checker->gm == 0) + color->g = 0.0; + else + color->g = g / (double)(checker->gm >> checker->gs); + + if (checker->bm == 0) + color->b = 0.0; + else + color->b = b / (double)(checker->bm >> checker->bs); + + if (PIXMAN_FORMAT_TYPE (checker->format) == PIXMAN_TYPE_ARGB_SRGB) + { + color->r = convert_srgb_to_linear (color->r); + color->g = convert_srgb_to_linear (color->g); + color->b = convert_srgb_to_linear (color->b); + } +} + static int32_t convert (double v, uint32_t width, uint32_t mask, uint32_t shift, double def) { @@ -1183,7 +1513,7 @@ get_limits (const pixel_checker_t *checker, double limit, /* The acceptable deviation in units of [0.0, 1.0] */ -#define DEVIATION (0.004) +#define DEVIATION (0.0064) void pixel_checker_get_max (const pixel_checker_t *checker, color_t *color, diff --git a/pixman/test/utils.h b/pixman/test/utils.h index 498831433..c2781516f 100644 --- a/pixman/test/utils.h +++ b/pixman/test/utils.h @@ -189,6 +189,14 @@ typedef struct } color_t; void +do_composite (pixman_op_t op, + const color_t *src, + const color_t *mask, + const color_t *dst, + color_t *result, + pixman_bool_t component_alpha); + +void round_color (pixman_format_code_t format, color_t *color); typedef struct @@ -217,3 +225,14 @@ pixel_checker_get_min (const pixel_checker_t *checker, color_t *color, pixman_bool_t pixel_checker_check (const pixel_checker_t *checker, uint32_t pixel, color_t *color); + +void +pixel_checker_convert_pixel_to_color (const pixel_checker_t *checker, + uint32_t pixel, color_t *color); + +void +pixel_checker_get_masks (const pixel_checker_t *checker, + uint32_t *am, + uint32_t *rm, + uint32_t *gm, + uint32_t *bm); diff --git a/xorg-server/hw/xfree86/common/xf86Events.c b/xorg-server/hw/xfree86/common/xf86Events.c index 377e936f7..d92174edf 100644 --- a/xorg-server/hw/xfree86/common/xf86Events.c +++ b/xorg-server/hw/xfree86/common/xf86Events.c @@ -272,9 +272,9 @@ xf86Wakeup(pointer blockData, int err, pointer pReadmask) } if (err >= 0) { /* we don't want the handlers called if select() */ - IHPtr ih; /* returned with an error condition, do we? */ + IHPtr ih, ih_tmp; /* returned with an error condition, do we? */ - for (ih = InputHandlers; ih; ih = ih->next) { + nt_list_for_each_entry_safe(ih, ih_tmp, InputHandlers, next) { if (ih->enabled && ih->fd >= 0 && ih->ihproc && (FD_ISSET(ih->fd, ((fd_set *) pReadmask)) != 0)) { ih->ihproc(ih->fd, ih->data); diff --git a/xorg-server/hw/xfree86/common/xf86pciBus.c b/xorg-server/hw/xfree86/common/xf86pciBus.c index a2c18ebf2..258988a84 100644 --- a/xorg-server/hw/xfree86/common/xf86pciBus.c +++ b/xorg-server/hw/xfree86/common/xf86pciBus.c @@ -1147,14 +1147,62 @@ xf86VideoPtrToDriverList(struct pci_device *dev, driverList[0] = "i128"; break; case 0x8086: - if ((dev->device_id == 0x00d1) || (dev->device_id == 0x7800)) { - driverList[0] = "i740"; - } - else if (dev->device_id == 0x8108) { - break; /* "hooray" for poulsbo */ - } - else { - driverList[0] = "intel"; + switch (dev->device_id) + { + /* Intel i740 */ + case 0x00d1: + case 0x7800: + driverList[0] = "i740"; + break; + /* GMA500/Poulsbo */ + case 0x8108: + case 0x8109: + /* Try psb driver on Poulsbo - if available */ + driverList[0] = "psb"; + driverList[1] = "psb_drv"; + break; + /* GMA600/Oaktrail */ + case 0x4100: + case 0x4101: + case 0x4102: + case 0x4103: + case 0x4104: + case 0x4105: + case 0x4106: + case 0x4107: + /* Atom E620/Oaktrail */ + case 0x4108: + /* Medfield */ + case 0x0130: + case 0x0131: + case 0x0132: + case 0x0133: + case 0x0134: + case 0x0135: + case 0x0136: + case 0x0137: + /* GMA 3600/CDV */ + case 0x0be0: + case 0x0be1: + case 0x0be2: + case 0x0be3: + case 0x0be4: + case 0x0be5: + case 0x0be6: + case 0x0be7: + case 0x0be8: + case 0x0be9: + case 0x0bea: + case 0x0beb: + case 0x0bec: + case 0x0bed: + case 0x0bee: + case 0x0bef: + /* Use fbdev/vesa driver on Oaktrail, Medfield, CDV */ + break; + default: + driverList[0] = "intel"; + break; } break; case 0x102b: diff --git a/xorg-server/hw/xfree86/man/xorg.conf.man b/xorg-server/hw/xfree86/man/xorg.conf.man index 5d92bbe8b..9361ce978 100644 --- a/xorg-server/hw/xfree86/man/xorg.conf.man +++ b/xorg-server/hw/xfree86/man/xorg.conf.man @@ -1821,9 +1821,7 @@ sections have the following format: .PP The .B Identifier -and -.B Device -entries are mandatory. +entry is mandatory. All others are optional. .PP The @@ -1841,11 +1839,10 @@ The entries available for this section are: .TP 7 .BI "Device \*q" device\-id \*q -This mandatory entry specifies the +This entry specifies the .B Device -section to be used for this screen. -This is what ties a specific graphics card to a screen. -The +section to be used for this screen. When multiple graphics cards are +present, this is what ties a specific card to a screen. The .I device\-id must match the .B Identifier diff --git a/xorg-server/randr/rrcrtc.c b/xorg-server/randr/rrcrtc.c index 859d19efe..063be0477 100644 --- a/xorg-server/randr/rrcrtc.c +++ b/xorg-server/randr/rrcrtc.c @@ -373,6 +373,11 @@ RRCrtcDetachScanoutPixmap(RRCrtcPtr crtc) ret = pScrPriv->rrCrtcSetScanoutPixmap(crtc, NULL); if (crtc->scanout_pixmap) { master->StopPixmapTracking(mscreenpix, crtc->scanout_pixmap); + /* + * Unref the pixmap twice: once for the original reference, and once + * for the reference implicitly added by PixmapShareToSlave. + */ + master->DestroyPixmap(crtc->scanout_pixmap->master_pixmap); master->DestroyPixmap(crtc->scanout_pixmap->master_pixmap); crtc->pScreen->DestroyPixmap(crtc->scanout_pixmap); } |