[Piglit] [PATCH] amd_compressed_atc_texture: add miptree test

Ilia Mirkin imirkin at alum.mit.edu
Sun Mar 1 19:15:49 PST 2015


And naturally I forgot to add the new test to all.py, I've added this
hunk locally:

--- a/tests/all.py
+++ b/tests/all.py
@@ -3901,6 +3901,9 @@ oes_compressed_paletted_texture['basic API'] =
PiglitGLTest(['oes_compressed_pal
 oes_compressed_paletted_texture['invalid formats'] =
PiglitGLTest(['arb_texture_compression-invalid-formats', 'paletted'],
run_concurrent=True)
 oes_compressed_paletted_texture['basic API'] =
PiglitGLTest(['oes_compressed_paletted_texture-api'],
run_concurrent=True)

+amd_compressed_atc_texture = spec['AMD_compressed_ATC_texture']
+amd_compressed_atc_texture['miptree'] =
PiglitGLTest(['amd_compressed_atc_texture-miptree'],
run_concurrent=True)
+
 egl14 = spec['EGL 1.4']
 egl14['eglCreateSurface'] = PiglitGLTest(['egl-create-surface'],
exclude_platforms=['glx'])
 egl14['eglQuerySurface EGL_BAD_ATTRIBUTE'] =
PiglitGLTest(['egl-query-surface', '--bad-attr'],
exclude_platforms=['glx'])



On Sun, Mar 1, 2015 at 10:01 PM, Ilia Mirkin <imirkin at alum.mit.edu> wrote:
> This echoes the ETC1 miptree test, and even uses the same image.
>
> Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
> ---
>
> I used The Compressonator tool from AMD, which generates DDS files,
> so I also added *very* basic support for DDS files in piglit. It could
> be extended by an interested party to actually support more formats/etc.
>
>  tests/spec/CMakeLists.txt                          |   1 +
>  .../CMakeLists.gles2.txt                           |   6 +
>  .../spec/amd_compressed_atc_texture/CMakeLists.txt |   1 +
>  tests/spec/amd_compressed_atc_texture/miptree.c    | 261 +++++++++++++++++++++
>  .../waffles-compressed-atc-64x32-miptree.dds       | Bin 0 -> 1512 bytes
>  .../waffles-decompressed-rgb-64x32-miptree.dds     | Bin 0 -> 8321 bytes
>  tests/util/CMakeLists.txt                          |   1 +
>  tests/util/piglit-dds.c                            | 220 +++++++++++++++++
>  tests/util/piglit-dds.h                            |  72 ++++++
>  9 files changed, 562 insertions(+)
>  create mode 100644 tests/spec/amd_compressed_atc_texture/CMakeLists.gles2.txt
>  create mode 100644 tests/spec/amd_compressed_atc_texture/CMakeLists.txt
>  create mode 100644 tests/spec/amd_compressed_atc_texture/miptree.c
>  create mode 100644 tests/spec/amd_compressed_atc_texture/waffles-compressed-atc-64x32-miptree.dds
>  create mode 100644 tests/spec/amd_compressed_atc_texture/waffles-decompressed-rgb-64x32-miptree.dds
>  create mode 100644 tests/util/piglit-dds.c
>  create mode 100644 tests/util/piglit-dds.h
>
> diff --git a/tests/spec/CMakeLists.txt b/tests/spec/CMakeLists.txt
> index 7423589..dee56d6 100644
> --- a/tests/spec/CMakeLists.txt
> +++ b/tests/spec/CMakeLists.txt
> @@ -1,3 +1,4 @@
> +add_subdirectory (amd_compressed_atc_texture)
>  add_subdirectory (amd_performance_monitor)
>  add_subdirectory (amd_pinned_memory)
>  add_subdirectory (arb_base_instance)
> diff --git a/tests/spec/amd_compressed_atc_texture/CMakeLists.gles2.txt b/tests/spec/amd_compressed_atc_texture/CMakeLists.gles2.txt
> new file mode 100644
> index 0000000..0509e44
> --- /dev/null
> +++ b/tests/spec/amd_compressed_atc_texture/CMakeLists.gles2.txt
> @@ -0,0 +1,6 @@
> +include_directories(
> +       ${GLEXT_INCLUDE_DIR}
> +       ${OPENGL_INCLUDE_PATH}
> +)
> +link_libraries(piglitutil_${piglit_target_api})
> +piglit_add_executable(amd_compressed_atc_texture-miptree miptree.c)
> diff --git a/tests/spec/amd_compressed_atc_texture/CMakeLists.txt b/tests/spec/amd_compressed_atc_texture/CMakeLists.txt
> new file mode 100644
> index 0000000..144a306
> --- /dev/null
> +++ b/tests/spec/amd_compressed_atc_texture/CMakeLists.txt
> @@ -0,0 +1 @@
> +piglit_include_target_api()
> diff --git a/tests/spec/amd_compressed_atc_texture/miptree.c b/tests/spec/amd_compressed_atc_texture/miptree.c
> new file mode 100644
> index 0000000..c533dac
> --- /dev/null
> +++ b/tests/spec/amd_compressed_atc_texture/miptree.c
> @@ -0,0 +1,261 @@
> +/*
> + * Copyright 2012 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + */
> +
> +/**
> + * \file
> + * \brief Test texturing from an ATC miptree of a real image.
> + *
> + * Copied from identical ETC1 test.
> + *
> + * This test uses two data files. The file waffles-compressed-atc-64x32.dds
> + * contains a full miptree in GL_ATC_RGB_AMD format of a 2D texture of
> + * waffles and fruit [1].  The base level size is 64x32 pixels. The file
> + * waffles-decompressed-rgb-64x32.ktx contains a parallel miptree in GL_RGB
> + * format. Each of its RGB images was obtained by decompressing the corresponding
> + * ATC image with AMD-supplied Compressonator [2].
> + *
> + * This test draws each miplevel i of the ATC texture such that the image's
> + * lower left corner is at (x=0, y=sum(height of miplevel j for j=0 to i-1)),
> + * and it draws each miplevel of the RGB texture to the right of its
> + * corresponding ETC1 image. Then it compares that the images are identical.
> + *
> + * [1] The reference image is located at http://people.freedesktop.org/~chadversary/permalink/2012-07-09/1574cff2-d091-4421-a3cf-b56c7943d060.jpg.
> + * [2] http://developer.amd.com/tools-and-sdks/archive/legacy-cpu-gpu-tools/the-compressonator/
> + */
> +
> +#include "piglit-util-gl.h"
> +#include "piglit-dds.h"
> +
> +#define num_levels 7
> +#define level0_width 64
> +#define level0_height 32
> +
> +#define num_vertices 4
> +
> +static const int window_width = 2 * level0_width;
> +static const int window_height = 2 * level0_height;
> +
> +PIGLIT_GL_TEST_CONFIG_BEGIN
> +
> +       config.supports_gl_es_version = 20;
> +
> +       config.window_width = window_width;
> +       config.window_height = window_height;
> +       config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
> +
> +PIGLIT_GL_TEST_CONFIG_END
> +
> +
> +static GLuint prog;
> +
> +/* Texture objects. */
> +static GLuint compressed_tex;
> +static GLuint decompressed_tex;
> +
> +/**
> + * The \a filename is relative to the current test's source directory.
> + *
> + * A new texture is created and returned in \a tex_name.
> + */
> +static void
> +load_texture(const char *filename, GLuint *tex_name)
> +{
> +       struct piglit_dds *dds;
> +       const struct piglit_dds_info *info;
> +       char filepath[4096];
> +       int i;
> +
> +       piglit_join_paths(filepath, sizeof(filepath), 5,
> +                         piglit_source_dir(),
> +                         "tests",
> +                         "spec",
> +                         "amd_compressed_atc_texture",
> +                         filename);
> +
> +       dds = piglit_dds_read_file(filepath);
> +       if (dds == NULL)
> +               piglit_report_result(PIGLIT_FAIL);
> +
> +       info = piglit_dds_get_info(dds);
> +       assert(info->num_miplevels == num_levels);
> +       assert(info->pixel_width == level0_width);
> +       assert(info->pixel_height== level0_height);
> +
> +       glGenTextures(1, tex_name);
> +       glBindTexture(GL_TEXTURE_2D, *tex_name);
> +        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
> +       for (i = 0; i < info->num_miplevels; i++) {
> +               const struct piglit_dds_image *img = piglit_dds_get_image(dds, i);
> +               if (info->gl_internal_format == GL_RGB)
> +                       glTexImage2D(GL_TEXTURE_2D, i,
> +                                    info->gl_internal_format,
> +                                    img->pixel_width,
> +                                    img->pixel_height,
> +                                    0,
> +                                    GL_RGB, GL_UNSIGNED_BYTE,
> +                                    img->data);
> +               else
> +                       glCompressedTexImage2D(GL_TEXTURE_2D, i,
> +                                              info->gl_internal_format,
> +                                              img->pixel_width,
> +                                              img->pixel_height,
> +                                              0,
> +                                              img->size,
> +                                              img->data);
> +               if (glGetError())
> +                       piglit_report_result(PIGLIT_FAIL);
> +       }
> +
> +       piglit_dds_destroy(dds);
> +}
> +
> +void
> +piglit_init(int argc, char **argv)
> +{
> +       static const char compressed_filename[] = "waffles-compressed-atc-64x32-miptree.dds";
> +       static const char decompressed_filename[] = "waffles-decompressed-rgb-64x32-miptree.dds";
> +
> +       const char vs_source[] =
> +               "#version 100\n"
> +               "\n"
> +               "uniform vec2 window_pixel_size;\n"
> +               "uniform vec2 level_pixel_size;\n"
> +               "uniform vec2 pixel_offset;\n"
> +               "\n"
> +               "// vertex is some corner of the unit square [0,1]^2 \n"
> +               "attribute vec2 vertex;\n"
> +               "varying vec2 tex_coord;\n"
> +               "\n"
> +               "void main()\n"
> +               "{\n"
> +               "    vec2 pos = vertex;\n"
> +               "    pos *= level_pixel_size;\n"
> +               "    pos += pixel_offset;\n"
> +               "    pos /= 0.5 * window_pixel_size;\n"
> +               "    pos -= vec2(1, 1);\n"
> +               "    gl_Position = vec4(pos.xy, 0.0, 1.0);\n"
> +               "\n"
> +               "    tex_coord = vertex;\n"
> +               "}\n";
> +
> +       const char fs_source[] =
> +               "#version 100\n"
> +               "precision highp float;\n"
> +               "\n"
> +               "uniform sampler2D tex;\n"
> +               "varying vec2 tex_coord;\n"
> +               "\n"
> +               "void main()\n"
> +               "{\n"
> +               "    vec4 t = texture2D(tex, tex_coord);\n"
> +               "    gl_FragColor = vec4(t.rgb, 1.0);\n"
> +               "}\n";
> +
> +       /* Draw a square triangle strip. */
> +       const GLfloat vertices[2 * num_vertices] = {
> +               0, 0,
> +               1, 0,
> +               1, 1,
> +               0, 1,
> +       };
> +
> +       GLint vertex_loc;
> +       GLuint vertex_buf;
> +
> +       piglit_require_extension("GL_AMD_compressed_ATC_texture");
> +
> +       load_texture(compressed_filename, &compressed_tex);
> +       load_texture(decompressed_filename, &decompressed_tex);
> +
> +       glClearColor(1.0, 0.0, 0.0, 1.0);
> +       glViewport(0, 0, window_width, window_height);
> +
> +       prog = piglit_build_simple_program(vs_source, fs_source);
> +       glUseProgram(prog);
> +
> +       vertex_loc = glGetAttribLocation(prog, "vertex");
> +       glGenBuffers(1, &vertex_buf);
> +       glBindBuffer(GL_ARRAY_BUFFER, vertex_buf);
> +       glEnableVertexAttribArray(vertex_loc);
> +       glVertexAttribPointer(vertex_loc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
> +       glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices,
> +                    GL_STATIC_DRAW);
> +
> +       glUniform1i(glGetUniformLocation(prog, "tex"), 0);
> +       glActiveTexture(GL_TEXTURE0);
> +       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
> +       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
> +
> +       glUniform2f(glGetUniformLocation(prog, "window_pixel_size"),
> +                   window_width, window_height);
> +}
> +
> +static void
> +minify(int *x)
> +{
> +       assert(*x > 0);
> +
> +       if (*x > 1)
> +               *x >>= 1;
> +}
> +
> +enum piglit_result
> +piglit_display(void)
> +{
> +       GLint pixel_offset_loc = glGetUniformLocation(prog, "pixel_offset");
> +       GLint level_pixel_size_loc = glGetUniformLocation(prog, "level_pixel_size");
> +
> +       int level = 0;
> +       int level_width = level0_width;
> +       int level_height = level0_height;
> +       int y_offset = 0;
> +
> +       bool pass = true;
> +
> +       glClear(GL_COLOR_BUFFER_BIT);
> +
> +       for (level = 0; level < num_levels; ++level) {
> +               glUniform2f(level_pixel_size_loc,
> +                           (float) level_width,
> +                           (float) level_height);
> +
> +               /* Draw miplevel of compressed texture. */
> +               glBindTexture(GL_TEXTURE_2D, compressed_tex);
> +               glUniform2f(pixel_offset_loc, 0, y_offset);
> +               glDrawArrays(GL_TRIANGLE_FAN, 0, num_vertices);
> +
> +               /* Draw miplevel of decompressed texture. */
> +               glBindTexture(GL_TEXTURE_2D, decompressed_tex);
> +               glUniform2f(pixel_offset_loc, level0_width, y_offset);
> +               glDrawArrays(GL_TRIANGLE_FAN, 0, num_vertices);
> +
> +               y_offset += level_height;
> +               minify(&level_width);
> +               minify(&level_height);
> +       }
> +
> +       pass = piglit_probe_rect_halves_equal_rgba(0, 0, window_width, window_height);
> +       piglit_present_results();
> +
> +       return pass ? PIGLIT_PASS : PIGLIT_FAIL;
> +}
> diff --git a/tests/spec/amd_compressed_atc_texture/waffles-compressed-atc-64x32-miptree.dds b/tests/spec/amd_compressed_atc_texture/waffles-compressed-atc-64x32-miptree.dds
> new file mode 100644
> index 0000000000000000000000000000000000000000..de29f5c69ea8984176239460020d68123f4f7e6b
> GIT binary patch
> literal 1512
> zcma)6Z%k8H6h9AbVXd*<2Bcddv_dz)Zt#Uf7qzb~;BdwiM^R+zr1%FausLTInHEfS
> z8k41(;j*b11^*zLW*M4&P>Pd=%ox`XRF};3wWFoL<j?fAudu#%b|1!NiC=b-dw=ho
> zd+#~#p7T4mwDd#GmjIBel!1mIO$IC!Ct`aJ|9jSuof0yPRc7(?B}r4#FWHz at 2ER!1
> zJkyGp!9RK=A|T>_v5M#cV!t{ktnzLnibtJdOaEv(hoT^=SB?%SU at o;ahH4c+UH*`e
> zB3Gk1|K|O+y#O{1gUBaXbdYn%vmiPrBKkMXBZEmch5!uFh&aUQ**sQSH&{g-ii?Zw
> zI|7^|N0C}yz58KG<xKaHmG>rtv8&ZTZ=Mn+My;T29ug48yS at 7x(4f at 0Y+3J*0yJW2
> z+1K%8vPV|1Cx9sMi5Kx-pu3q70~W0o*HKL$ZR{tp0e04%;V?<V68$X>dns_PP)^m>
> zS_b}D=Iz5CDs!7=q!$lS5^Y6~0C1b7txjIxgP}wFqdec=k`dkKLa0w%H`f%#sDAvr
> zV&82p!G^;Exi<>QfB)lJJiysArBbu<x?g~L+Nl~H#N<q<z1TTuC~8q_Rb5vsAVE|9
> zmDs>Q at Ed2tdQ35{ZXPMU!oKmU;=OkLr5|UYwji|P?vwD?>`x)u8S^-#R+Dux9 at ypT
> zsMvRl1B);CiQ_Cc(AH)W^PUj+<nugZ(zfWA`*OKly(I10rWt??TYABb0RYyRSALD~
> zFIB6L+`DlRd>1T|I9OQBHBL<OGv#W^I?hI0B;AsdH={tsBIU*a2T+A$o7K^D3x#Pr
> zzT?_}M*E(}9GjR!mxI9*k>@-bo0#}>zOG<Ubmhsssg;m&C`)Ij{XyTwlHE7ho{p-z
> zbnl at 2_lJ@5#q}|kr0mZ2Zr+n4g<RuTu_7TxbvL}mDM8-g{q#4^7Ys!btpRQvAe3lj
> zI1DH8tevD;aM;pUZH}IMw(Q>LYdSfcWtNPq0vxF`jH~)NPYS?DalxR0_`i^MEDRLl
> z-TYmTt*{ll^4=akQC5iCG<U-&guflxZjPZtF73*yA6B~&!}<b$U(n+|PWTgMlLC^w
> zihc5dmiYI`rA at li4?;~&qb$2~+9PD9ypsL;UIhgpBS at NXV6Beuns$Yb89O<el4E1Z
> zlVKEs@}ou>$r8FM8W+daqaAQ(nJgkF2AfqDAyM3yty$3%6crq+VX)1|<CuyetC%yC
> z&Y)xKdN{mjoxO4^g_o4;Y|TGZS!LNzKO^zjrP`a$k1ZP`u6Gy?=&<l~Im0E%L6Hwt
> zF~9#s|JmzAe-6W8RX-L<J8E_scg6o=al)4OR@@|4c+#o`LSHs0*3Uq8{`!>M*IjM&
> zR<?4O0btgvrdw#5ZqFZQH%aV{cKyQ1_|&l9Y#oasMqSaS4V-T{%!~QLq>wZ(x_sKa
> zp!Sq0Yv-AC)xoJcx;|DK6x=qeee#y+`#zm<BL|bSd_^PS*C|B*mdD%^oUn{%F~mU&
> z)s<i5m(9((b4z3q=*79*ifCBqi{fa_foV{-v1 at dU$OCzy_Tcon^#E&i*$k-zy;R#d
> z4K7wVQYQN8g at r2_EUJ|#CCgXGvscY_H}08lQ?^TUe2_Zdiwi0<A6ib;OcZL*a2JJ^
> u)TRRRKD<l$E>#B5AOZSn8DeO-$23}#`Cw>fXlCt}livG802E#l0RI6`11H)5
>
> literal 0
> HcmV?d00001
>
> diff --git a/tests/spec/amd_compressed_atc_texture/waffles-decompressed-rgb-64x32-miptree.dds b/tests/spec/amd_compressed_atc_texture/waffles-decompressed-rgb-64x32-miptree.dds
> new file mode 100644
> index 0000000000000000000000000000000000000000..b0444b132b703b7ca3e01220a81c8c3afec7aa11
> GIT binary patch
> literal 8321
> zcmb`Me{hra8Nj*yv;5();CbW4Z3o#gxhS5-9rIof{E at jG20@HtY80JD<wv)1ECND+
> z354Gjjv9+#WwY8kkhG(aLZz)jH8MLZ6&H0qI%dam!d#Fl?}U2UCw-D9Z$pD~TkgZR
> zPv3s?yr1X!e)Hx{xcTNgMlBvPWXLz1UmG%tpEvUFRsLlkUzZ>M at i>Z^H|Ay={Xa89
> zh6w$?Ih^^w<|gqYV_BKc`!eS;nSY(loXx|*3y`1IXM1F9kJQODJUk<07;e)H2$8l_
> zER$LGQQt#dXU&A=-qh+e{DR^13yXrk$(ks(oP&oVsq+#0Di6^wdPd!wABj2gfHvf+
> zNLcD`c4f2#<o({q<CPtZzx>6Tui($QX}kLKtMs<Wsl>1N+y8?3!WX;Tp at iLE`=1RG
> zR)K#1kq=a`1ls>>V0eF5voEJ)&t5A2fB0LLg*@hhbY8|88yg_E3IqLF0-?yiumq)?
> z?Z??d+JAdspHm{X&RIhAm7`PlB|Onsj$qgm4F70LoB!qX<i@`Xp}*v8#o3q62=2IL
> z7^dR#mxqp6f^{yVlu*cIU#IpZ&=N{Mq3{Ql4^(yha7Q!pj4)wEEg&!c<DU5wB^3Fi
> z4ddQCdjbE(&NE-`kNp4Uk32}{gKsB+&MU|(mu^3CS<7i)2{4BVAN1jW&FUIq%sq>4
> zSia{c)g8jR_^B`V*M=7bg*KOr=s!D0{pmcr2#}X0V04CB6i0ctmZ1Ho1aEsv5p#AC
> z_{vkd1SKVG+FEQju)PDMdaVMMmC6%oOW(Ju?Z?w=!M!!E7)xS`!xvR9*>KF&kP$}K
> zoi$rCIa<<Yo-60RW%%QQFPh%f`Dxm+;J@}?*>>ElO4$7?pKTWG{v)QZA33i|xcJV9
> z!|*~ju=!s!zg_*^d-_B^8?>aSb$&LZ`*X(etGfNQ77*aSy6Lp|_hklLs|)1}?0@~c
> zXC8m~lo?HVYmy57!lLH)fA&Ds=?DleR~V%K_&d#zFm%Ff at n;;hwAuGw20YctA^sT1
> zDyV#RAzISNM|v|L at -m9QECJi0;B1fj{oguzIvndpTc8A$Cs2O^l_wB?Mizq3Q-V~1
> zf1w0lR7;@$>W{YItg&c2=9B=^`9b{$T>@T%!B`qDo6|69K}A_(Qt)g`D6Wcx;BW;U
> z4i5~y=zefI{erjAnz=9S3MPdy_w2bQ)WK+&<qlT>JoDn<FvCNq*IqoY&DffDHCV#%
> zNc*@o?V+9w5YTfa(wz~~z5TDofp7P+2x5*r_i~2QrMO(4BLCqteyjdch28(w%HtwW
> zAm(;|sRDoGi~NT at Qt$M~Cht53>K|!3oh9#|IC(ZRm^>wjzub=^f9;fqSOrG>wFGHC
> z{=+7%k<Q!wuUgPV|Dz`}QUas5(gK<fwB0qWV)%`VL7PwiX*=c)GXnSn@{}OWN1m(P
> z0RIyAmPP*3fBeVXHWU9V=4 at aU@E3XdZ(I^n=>K=8Yy?VR|4;%W{%jtQ641sUvP;n4
> zf8<#L<Q2>X_21d~DgLxwO4xb4FMB~B?BUzmaqX<NM*qX<a6)ie0Q4TrR~z at Niw&PJ
> z$KmwBC1X~CdwR#WCsaG#HOiIqcKTb>f^VBO>Y+oPa2J8wTc&vY5ycyBSzP@`An-;y
> zge`wa1*%dTUimn6&Vq)2W+JH!<KbTPtwC?s&-a%q)Sp1i?f%HC|A+_M!0<&t{V~U%
> zDrPO+Qp&$jLf)S$@NanU6ZIE)?lASEQqdxORey&gpwN8G-E9_(uSl>2l)#8KIJ_~y
> zACf&Op!wlV^+K-mG~d?$`LUzOtH1rm_`?2|PrR2Mbk*o91eSodUp{#{o2O|1h`eke
> zF_)3fYYAw}{$UBk|Eb!2_{;sOjNLscrK8tUr1LV`{b~E4`^R6Mxbmlu8EzjqU8XSN
> zx=HS`vg;$Of^~6lZ%vGxwccsC!Ql=L3v6}OSy>u0!tknpm<<+;UEj_UxXO}n>(d`H
> zx<e at l)_$BgXTAT0^|!t(l#sFU`I)rtiuB18yt?E0Bd at huy;gzzXN_$6`A1{@PLXE>
> zv<3IWS^3G)ErR%um>49;ncMt_l^=72Ixv?K7{y;k at n3)F6Z{jI0d##~ebkpNq{zP}
> z5|%0sH8*v=)0r#5=8v||^a#><d;dpHx=Z{iL8_qn$e-^|+eIG#(R1rTN{IGYGaFBc
> zKb at z9LH!F$knjFyr;Z~}=kX^HbE?P&=d8wto$Ho`)m(z{k8aiy3Y+KQGTA>;g2+=v
> zQUB3ake5pkBRdCwAiy8QpZ&uUoWFn2Pp6Ws0{+N at ECJ1rRYhei(k}eED&gzLFoRBB
> z0(r*Vu}T>|X(=@_jtxF%Y)uu|VHtT`8<O9d`OLSbg!szGWd^Q(V2!UfdEJs112x^7
> zUq5l+&!@95#_T;LU(sZdSFwzhtHWghUqek*_mK{(H!U>%en-{v5cs?%_-zFJK1JkZ
> z{NB`v`Wqg<g1MG(@vQBG_?I8WUrL|~`~i7N5dYkjB)?CxmE`wx^ZwoVV~#%o+FHWQ
> zz!Z@$<^OEO6Lx=JMN08*=muE=+AgpP+|m!7`0HF1H2>+85$*u-ml172`d_#V4)n)7
> z;P(Q}*CoJzV`K@?aFrj_ANki>_g~mwsxVh26`GHKt_0-EkCyUB9&$TJJ|)@wk&kX#
> zDgGiaRp75%Wl(>16z1$7<jLm?Muc at +>Vw;oioZIggxaj&t`m3HeCUfNIrxJG`yHMT
> z7=f71S at iTlvn<9~)7a?^$Ax|EJ%#2=3H{@W#S3p9f34ePFhbyVUuag4 at s^tg?DK%n
> z3l$5?7C#b*1PesNA-#5?ttH$Wi4E#6@{AOs!UW at 2cj~X=PYEFMYhF5BN*@2vtTGUP
> zv^{Q at l%UNg5P#(D{tZ=8l_%iR+St-ACHMnnAXTUs0i72p!G7Ex+x<(K at 2Rgt6nX7G
> zO904If>7iy%@=>n4<Br{%Zq>R4X)Rs`N&HZ-e3eKF4}(Ux&v$*#qKOIs{qn at HczT2
> zb$;8|EL-X|J;*E4e;HMt0RP!{O^GfEfpne{;+2u}&2xqDxgh_2{`u#XBl2C)_S#);
> zmuLLSdNUC5zHPynm5qks1J~W_b{{^*#a*zyOu5qc|DS>!vb_ZC=OXj`xl2h7B<B>8
> z-}6S{6y8YeLiy#>*<krMztTl=ffGq)&Ce;M1oE$JXfNqsI)9)lL2 at a9;QHs=1x`V7
> zfku%Zq)Ybx==%skce+5LCk>G&_uhT~CeNHE7<Jo57(RFJu-iAes?*?YwG=bl4YO-f
> zEhj0W at R0oBcnW_0T$|ty)fmozKz_;WaQT7!WR_8r6G-xW{=z9pd;NkP0%;X{{_KaT
> zd<lGv#a~Jw?U+S}u6e3U^RGYfale1zyD~D%mjeWvyvU#Y0)<F&$#3{$Ag2&>lK1B?
> z_?z>p3_h$ljnU(7aXQVBH{1sVP9yTosr52)oe$Kd;ie5qw=bgTi<%%7Z{b5n=dr&s
> z+V{5R=M<!M-#1_Lll;<o?c9))mQ%ph3ttbes!yD>*4MQ&Hokje-OC>WL8;F*<R5$6
> zY~+FD=7uWZ6p~r)_Q?+<XC%KQC%=8~VJ at iu{)RnIEL)+;2_(Oal9{uBm`i`epX5dP
> z=?@%y`yC*y&oqT;3tj-j?a$&XQ^qcR!`zk<JmI*~x_`g6*Gi{h<Lc#2yXw+C-5|Gx
> z^1dUZ<PX;-f$Qz~W%~rf7acuoH~Be{B!8^-O#*v<()xW~^26pe%k-X8GDp`gZ{A%u
> z;m#GDLi6k8oy_EyDpdZ(whvUkV$%~OS2Q^R`AIIfk&;=e5OX<&Hiv-x$fx at s<fjC`
> z-<M^u{1k$=-lM9I1~0|ma(Tm7&3nOYw;0{tQ0oV03Kx`t*H|V$x_T#kfAj0i2j=^$
> zQug_~4jvI?CdnngK85*u3Qw?Hk(oS;fV9Z)6kvYEfm3pdtEcjb!<)lfV|Z))zuF6H
> z*RF*6-MgXi<$tdw^KY6Rg+&!@GMT_WZC_IpPhl(z_yZLQnas#!eTwAdS)66dlN*^S
> zFkfM^5N}H|pP8~EGLvU<Q2)=xQ&v+^z1Lq>-ulK7N((=i01g5N`4ezlj>yOnCJTC;
> gXK{q5$g|>Y9S>HvvO@@D9}++?+7fL at gsT((23cn6xc~qF
>
> literal 0
> HcmV?d00001
>
> diff --git a/tests/util/CMakeLists.txt b/tests/util/CMakeLists.txt
> index 45fd25f..0b2147f 100644
> --- a/tests/util/CMakeLists.txt
> +++ b/tests/util/CMakeLists.txt
> @@ -35,6 +35,7 @@ set(UTIL_GL_INCLUDES
>  set(UTIL_GL_SOURCES
>         fdo-bitmap.c
>         minmax-test.c
> +       piglit-dds.c
>         piglit-dispatch.c
>         piglit-dispatch-init.c
>         piglit-fbo.cpp
> diff --git a/tests/util/piglit-dds.c b/tests/util/piglit-dds.c
> new file mode 100644
> index 0000000..c5c7960
> --- /dev/null
> +++ b/tests/util/piglit-dds.c
> @@ -0,0 +1,220 @@
> +#include <assert.h>
> +#include <stdarg.h>
> +#include <stdlib.h>
> +#include <string.h>
> +
> +#include "piglit-dds.h"
> +#include "piglit-util-gl.h"
> +
> +
> +// DDS values taken from http://www.mindcontrol.org/~hplus/graphics/dds-info/
> +
> +//  little-endian, of course
> +
> +//  DDS_header.dwFlags
> +#define DDSD_CAPS                   0x00000001
> +#define DDSD_HEIGHT                 0x00000002
> +#define DDSD_WIDTH                  0x00000004
> +#define DDSD_PITCH                  0x00000008
> +#define DDSD_PIXELFORMAT            0x00001000
> +#define DDSD_MIPMAPCOUNT            0x00020000
> +#define DDSD_LINEARSIZE             0x00080000
> +#define DDSD_DEPTH                  0x00800000
> +
> +//  DDS_header.sPixelFormat.dwFlags
> +#define DDPF_ALPHAPIXELS            0x00000001
> +#define DDPF_FOURCC                 0x00000004
> +#define DDPF_INDEXED                0x00000020
> +#define DDPF_RGB                    0x00000040
> +
> +//  DDS_header.sCaps.dwCaps1
> +#define DDSCAPS_COMPLEX             0x00000008
> +#define DDSCAPS_TEXTURE             0x00001000
> +#define DDSCAPS_MIPMAP              0x00400000
> +
> +//  DDS_header.sCaps.dwCaps2
> +#define DDSCAPS2_CUBEMAP            0x00000200
> +#define DDSCAPS2_CUBEMAP_POSITIVEX  0x00000400
> +#define DDSCAPS2_CUBEMAP_NEGATIVEX  0x00000800
> +#define DDSCAPS2_CUBEMAP_POSITIVEY  0x00001000
> +#define DDSCAPS2_CUBEMAP_NEGATIVEY  0x00002000
> +#define DDSCAPS2_CUBEMAP_POSITIVEZ  0x00004000
> +#define DDSCAPS2_CUBEMAP_NEGATIVEZ  0x00008000
> +#define DDSCAPS2_VOLUME             0x00200000
> +
> +union DDS_header {
> +       struct {
> +               unsigned int    dwMagic;
> +               unsigned int    dwSize;
> +               unsigned int    dwFlags;
> +               unsigned int    dwHeight;
> +               unsigned int    dwWidth;
> +               unsigned int    dwPitchOrLinearSize;
> +               unsigned int    dwDepth;
> +               unsigned int    dwMipMapCount;
> +               unsigned int    dwReserved1[ 11 ];
> +
> +               //  DDPIXELFORMAT
> +               struct {
> +                       unsigned int    dwSize;
> +                       unsigned int    dwFlags;
> +                       unsigned int    dwFourCC;
> +                       unsigned int    dwRGBBitCount;
> +                       unsigned int    dwRBitMask;
> +                       unsigned int    dwGBitMask;
> +                       unsigned int    dwBBitMask;
> +                       unsigned int    dwAlphaBitMask;
> +               }               sPixelFormat;
> +
> +               //  DDCAPS2
> +               struct {
> +                       unsigned int    dwCaps1;
> +                       unsigned int    dwCaps2;
> +                       unsigned int    dwDDSX;
> +                       unsigned int    dwReserved;
> +               }               sCaps;
> +               unsigned int    dwReserved2;
> +       };
> +       char data[ 128 ];
> +};
> +
> +#define FOURCC(a, b, c, d)  ((a) << 0 | (b) << 8 | (c) << 16 | (d) << 24)
> +
> +#define DDS_MAGIC   FOURCC('D', 'D', 'S', ' ')
> +#define ATC_RGB     FOURCC('A', 'T', 'C', ' ')
> +#define ATC_RGBA_E  FOURCC('A', 'T', 'C', 'A')
> +#define ATC_RGBA_I  FOURCC('A', 'T', 'C', 'I')
> +
> +struct piglit_dds {
> +       struct piglit_dds_info info;
> +       void *data;
> +       size_t size;
> +
> +       struct piglit_dds_image *images;
> +};
> +
> +void
> +piglit_dds_destroy(struct piglit_dds *self)
> +{
> +       free(self->images);
> +       free(self->data);
> +       free(self);
> +}
> +
> +struct piglit_dds *
> +piglit_dds_read_file(const char *filename)
> +{
> +       struct piglit_dds *ret = calloc(1, sizeof(struct piglit_dds));
> +       FILE *f;
> +       bool success = false;
> +       int read, i, shift = 0, factor = 0;
> +       union DDS_header *header;
> +
> +       if (!ret)
> +               goto err_ret;
> +
> +       f = fopen(filename, "rb");
> +
> +       if (!f)
> +               goto err_file;
> +
> +       if (fseek(f, 0, SEEK_END))
> +               goto err_read;
> +       ret->size = ftell(f);
> +       if (fseek(f, 0, SEEK_SET))
> +               goto err_read;
> +
> +       ret->data = malloc(ret->size);
> +       if (!ret->data)
> +               goto err_read;
> +
> +       read = fread(ret->data, 1, ret->size, f);
> +       if (read < ret->size)
> +               goto err_read;
> +
> +       header = ret->data;
> +
> +       if (header->dwMagic != DDS_MAGIC)
> +               goto err_read;
> +
> +       ret->info.num_miplevels = header->dwMipMapCount;
> +       ret->info.pixel_width = header->dwWidth;
> +       ret->info.pixel_height = header->dwHeight;
> +       switch (header->sPixelFormat.dwFourCC) {
> +       case 0:
> +               ret->info.gl_internal_format = GL_RGB;
> +               factor = 3;
> +               /* And the actual data is GL_BGR, which doesn't exist
> +                * in gles2, so we have to do it by hand.
> +                */
> +               for (i = 128; i < ret->size; i += 3) {
> +                       uint8_t *texel = ret->data + i;
> +                       uint8_t tmp = texel[0];
> +                       texel[0] = texel[2];
> +                       texel[2] = tmp;
> +               }
> +               break;
> +       case ATC_RGB:
> +               ret->info.gl_internal_format = GL_ATC_RGB_AMD;
> +               shift = 1;
> +               break;
> +       case ATC_RGBA_I:
> +               ret->info.gl_internal_format = GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD;
> +               break;
> +       case ATC_RGBA_E:
> +               ret->info.gl_internal_format = GL_ATC_RGBA_EXPLICIT_ALPHA_AMD;
> +               break;
> +       default:
> +               goto err_read;
> +       }
> +
> +       ret->images = calloc(ret->info.num_miplevels, sizeof(struct piglit_dds_image));
> +       for (i = 0; i < ret->info.num_miplevels; i++) {
> +               struct piglit_dds_image *img = &ret->images[i];
> +               if (i == 0) {
> +                       img->data = ret->data + 128;
> +                       img->pixel_width = ret->info.pixel_width;
> +                       img->pixel_height = ret->info.pixel_height;
> +               } else {
> +                       struct piglit_dds_image *prev = &ret->images[i - 1];
> +                       img->data = prev->data + prev->size;
> +                       img->pixel_width = MAX2(1, prev->pixel_width >> 1);
> +                       img->pixel_height = MAX2(1, prev->pixel_height >> 1);
> +               }
> +               if (header->sPixelFormat.dwFourCC)
> +                       img->size = ALIGN(img->pixel_width, 4) * ALIGN(img->pixel_height, 4);
> +               else
> +                       img->size = img->pixel_width * img->pixel_height;
> +               if (shift > 0)
> +                       img->size >>= shift;
> +               if (factor > 0)
> +                       img->size *= factor;
> +       }
> +
> +       success = true;
> +
> +err_read:
> +       fclose(f);
> +       if (success)
> +               return ret;
> +       if (ret->data)
> +               free(ret->data);
> +err_file:
> +       free(ret);
> +err_ret:
> +       return NULL;
> +}
> +
> +const struct piglit_dds_info *
> +piglit_dds_get_info(struct piglit_dds *self)
> +{
> +       return &self->info;
> +}
> +
> +const struct piglit_dds_image *
> +piglit_dds_get_image(struct piglit_dds *self,
> +                     int miplevel)
> +{
> +       assert(miplevel < self->info.num_miplevels);
> +       return &self->images[miplevel];
> +}
> diff --git a/tests/util/piglit-dds.h b/tests/util/piglit-dds.h
> new file mode 100644
> index 0000000..8f4c9ae
> --- /dev/null
> +++ b/tests/util/piglit-dds.h
> @@ -0,0 +1,72 @@
> +/*
> + * Copyright 2015 Ilia Mirkin
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> + * IN THE SOFTWARE.
> + */
> +
> +/**
> + * \file
> + *
> + * \brief Utilities for the DDS file format
> + *
> + * The DDS file format specifies a simple format for storing texture
> + * miptrees.
> + */
> +
> +#include <stdint.h>
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +struct piglit_dds;
> +
> +struct piglit_dds_info {
> +  uint32_t gl_internal_format;
> +  uint32_t num_miplevels;
> +
> +  uint32_t pixel_width;
> +  uint32_t pixel_height;
> +};
> +
> +struct piglit_dds_image {
> +  const void *data;
> +  size_t size;
> +
> +  uint32_t pixel_width;
> +  uint32_t pixel_height;
> +};
> +
> +void
> +piglit_dds_destroy(struct piglit_dds *self);
> +
> +struct piglit_dds *
> +piglit_dds_read_file(const char *filename);
> +
> +const struct piglit_dds_info *
> +piglit_dds_get_info(struct piglit_dds *self);
> +
> +const struct piglit_dds_image *
> +piglit_dds_get_image(struct piglit_dds *self,
> +                     int miplevel);
> +
> +#ifdef __cplusplus
> +}
> +#endif
> --
> 2.0.5
>


More information about the Piglit mailing list