From 92e488a3b7ff3f56a3e45aac1d088f0311fd7f7b Mon Sep 17 00:00:00 2001 From: Larry Gritz Date: Sun, 4 Dec 2022 09:55:23 -0800 Subject: [PATCH] Testing; better tests of environment mapping, minor fixes (#3694) Would you believe we never had a testsuite test for environment mapping? Well, it wasn't totally untested, in the sense that OSL testsuite had one, and obviously it's used in production all the time. But OIIO's testsuite didn't have any tests of TextureSystem::environmemt(). We now remedy that. * Add testsuite/texture-env, contains several environment tests, including handles vs filenames, subimage selection, different interp and mip modes, ask for >4 channels. * New CMake build option OIIO_TEX_IMPLEMENT_VARYINGREF can be used for testing to disable implementation of the old 1.x style of batch texture calls. We don't use them, they are deprecated. This option give us a way to exclude them from code analysis, because we really don't care. * Fix bug with >4 channels for environment batch shading! * Avoid unnecessary spec lookup in TileID constructor. * Avoid building testtex test_hash during code coverage -- it is an extremely specialized test, not run in the testsuite, it shouldn't really count againt good code coverage. --- .github/workflows/analysis.yml | 1 + CMakeLists.txt | 4 + src/cmake/testing.cmake | 1 + src/libtexture/environment.cpp | 12 +- src/libtexture/imagecache_pvt.h | 7 +- src/libtexture/texture3d.cpp | 8 + src/libtexture/texturesys.cpp | 8 + src/testtex/testtex.cpp | 322 +++++++++++++++++- testsuite/maketx/ref/out.txt | 1 + testsuite/maketx/run.py | 12 +- testsuite/runtest.py | 3 +- testsuite/texture-env/ref/5chan.exr | Bin 0 -> 8153 bytes .../texture-env/ref/bicubic-trilinear.exr | Bin 0 -> 6110 bytes .../texture-env/ref/bilinear-onelevel.exr | Bin 0 -> 2172 bytes testsuite/texture-env/ref/closest-nomip.exr | Bin 0 -> 1073 bytes testsuite/texture-env/ref/env-handle.exr | Bin 0 -> 5973 bytes .../texture-env/ref/env-handle.exr-ds.exr | Bin 0 -> 7931 bytes .../texture-env/ref/env-handle.exr-dt.exr | Bin 0 -> 6232 bytes testsuite/texture-env/ref/env.exr | Bin 0 -> 5973 bytes testsuite/texture-env/ref/out-batch.txt | 54 +++ testsuite/texture-env/ref/out.txt | 54 +++ testsuite/texture-env/ref/subimage0.exr | Bin 0 -> 5973 bytes testsuite/texture-env/ref/subimagefred.exr | Bin 0 -> 5973 bytes testsuite/texture-env/ref/subimagemissing.exr | Bin 0 -> 399 bytes testsuite/texture-env/run.py | 41 +++ 25 files changed, 513 insertions(+), 15 deletions(-) create mode 100644 testsuite/texture-env/ref/5chan.exr create mode 100644 testsuite/texture-env/ref/bicubic-trilinear.exr create mode 100644 testsuite/texture-env/ref/bilinear-onelevel.exr create mode 100644 testsuite/texture-env/ref/closest-nomip.exr create mode 100644 testsuite/texture-env/ref/env-handle.exr create mode 100644 testsuite/texture-env/ref/env-handle.exr-ds.exr create mode 100644 testsuite/texture-env/ref/env-handle.exr-dt.exr create mode 100644 testsuite/texture-env/ref/env.exr create mode 100644 testsuite/texture-env/ref/out-batch.txt create mode 100644 testsuite/texture-env/ref/out.txt create mode 100644 testsuite/texture-env/ref/subimage0.exr create mode 100644 testsuite/texture-env/ref/subimagefred.exr create mode 100644 testsuite/texture-env/ref/subimagemissing.exr create mode 100755 testsuite/texture-env/run.py diff --git a/.github/workflows/analysis.yml b/.github/workflows/analysis.yml index e1c0953247..d5a4454aef 100644 --- a/.github/workflows/analysis.yml +++ b/.github/workflows/analysis.yml @@ -61,6 +61,7 @@ jobs: CMAKE_UNITY_BUILD=OFF CODECOV=1 CTEST_TEST_TIMEOUT=1200 + OIIO_CMAKE_FLAGS="-DOIIO_TEX_IMPLEMENT_VARYINGREF=OFF" runs-on: ${{ matrix.os }} container: diff --git a/CMakeLists.txt b/CMakeLists.txt index bd54df8301..eef27d3f75 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -122,6 +122,10 @@ set (TEX_BATCH_SIZE "" CACHE STRING "Force TextureSystem SIMD batch size (e.g. 1 if (TEX_BATCH_SIZE) add_definitions ("-DOIIO_TEXTURE_SIMD_BATCH_WIDTH=${TEX_BATCH_SIZE}") endif () +option (OIIO_TEX_IMPLEMENT_VARYINGREF "Implement the deprecated batch texture functions taking VaryingRef params" ON) +if (NOT OIIO_TEX_IMPLEMENT_VARYINGREF) + add_definitions (-DOIIO_TEX_NO_IMPLEMENT_VARYINGREF=1) +endif () # Set the default namespace set (${PROJ_NAME}_NAMESPACE ${PROJECT_NAME} CACHE STRING diff --git a/src/cmake/testing.cmake b/src/cmake/testing.cmake index 4b307e24a9..ac2520692a 100644 --- a/src/cmake/testing.cmake +++ b/src/cmake/testing.cmake @@ -182,6 +182,7 @@ macro (oiio_add_all_tests) texture-wrapfill texture-fat texture-skinny texture-stats + texture-env ) oiio_add_tests (${all_texture_tests}) # Duplicate texture tests with batch mode diff --git a/src/libtexture/environment.cpp b/src/libtexture/environment.cpp index 576b9e0296..1637913857 100644 --- a/src/libtexture/environment.cpp +++ b/src/libtexture/environment.cpp @@ -216,11 +216,15 @@ TextureSystemImpl::environment(ustring filename, TextureOptions& options, float* result, float* dresultds, float* dresultdt) { +#ifdef OIIO_TEX_NO_IMPLEMENT_VARYINGREF + return false; +#else Perthread* thread_info = get_perthread_info(); TextureHandle* texture_handle = get_texture_handle(filename, thread_info); return environment(texture_handle, thread_info, options, runflags, beginactive, endactive, R, dRdx, dRdy, nchannels, result, dresultds, dresultdt); +#endif } @@ -235,6 +239,9 @@ TextureSystemImpl::environment(TextureHandle* texture_handle, float* result, float* dresultds, float* dresultdt) { +#ifdef OIIO_TEX_NO_IMPLEMENT_VARYINGREF + return false; +#else if (!texture_handle) return false; bool ok = true; @@ -256,6 +263,7 @@ TextureSystemImpl::environment(TextureHandle* texture_handle, } } return ok; +#endif } @@ -597,8 +605,10 @@ TextureSystemImpl::environment(TextureHandle* texture_handle, bool ok = true; Tex::RunMask bit = 1; + float* r = OIIO_ALLOCA(float, 3 * nchannels * Tex::BatchWidth); + float* drds = r + nchannels * Tex::BatchWidth; + float* drdt = r + 2 * nchannels * Tex::BatchWidth; for (int i = 0; i < Tex::BatchWidth; ++i, bit <<= 1) { - float r[4], drds[4], drdt[4]; // temp result if (mask & bit) { opt.sblur = options.sblur[i]; opt.tblur = options.tblur[i]; diff --git a/src/libtexture/imagecache_pvt.h b/src/libtexture/imagecache_pvt.h index 2828ca9bc3..2d1b40a598 100644 --- a/src/libtexture/imagecache_pvt.h +++ b/src/libtexture/imagecache_pvt.h @@ -489,7 +489,7 @@ struct TileID { /// Initialize a TileID based on full elaboration of image file, /// subimage, and tile x,y,z indices. TileID(ImageCacheFile& file, int subimage, int miplevel, int x, int y, - int z = 0, int chbegin = 0, int chend = -1) + int z, int chbegin, int chend) : m_x(x) , m_y(y) , m_z(z) @@ -499,9 +499,10 @@ struct TileID { , m_chend(chend) , m_file(&file) { - int nc = file.spec(subimage, miplevel).nchannels; - if (chend < chbegin || chend > nc) + if (chend < chbegin) { + int nc = file.spec(subimage, miplevel).nchannels; m_chend = nc; + } } /// Destructor is trivial, because we don't hold any resources diff --git a/src/libtexture/texture3d.cpp b/src/libtexture/texture3d.cpp index 2e606a622c..7a39b9869f 100644 --- a/src/libtexture/texture3d.cpp +++ b/src/libtexture/texture3d.cpp @@ -197,11 +197,15 @@ TextureSystemImpl::texture3d(ustring filename, TextureOptions& options, float* result, float* dresultds, float* dresultdt, float* dresultdr) { +#ifdef OIIO_TEX_NO_IMPLEMENT_VARYINGREF + return false; +#else Perthread* thread_info = get_perthread_info(); TextureHandle* texture_handle = get_texture_handle(filename, thread_info); return texture3d(texture_handle, thread_info, options, runflags, beginactive, endactive, P, dPdx, dPdy, dPdz, nchannels, result, dresultds, dresultdt, dresultdr); +#endif } @@ -214,6 +218,9 @@ TextureSystemImpl::texture3d( VaryingRef dPdy, VaryingRef dPdz, int nchannels, float* result, float* dresultds, float* dresultdt, float* dresultdr) { +#ifdef OIIO_TEX_NO_IMPLEMENT_VARYINGREF + return false; +#else bool ok = true; result += beginactive * nchannels; if (dresultds) { @@ -235,6 +242,7 @@ TextureSystemImpl::texture3d( } } return ok; +#endif } diff --git a/src/libtexture/texturesys.cpp b/src/libtexture/texturesys.cpp index d2d64dbdba..b0ed6f179d 100644 --- a/src/libtexture/texturesys.cpp +++ b/src/libtexture/texturesys.cpp @@ -1024,11 +1024,15 @@ TextureSystemImpl::texture(ustring filename, TextureOptions& options, int nchannels, float* result, float* dresultds, float* dresultdt) { +#ifdef OIIO_TEX_NO_IMPLEMENT_VARYINGREF + return false; +#else Perthread* thread_info = get_perthread_info(); TextureHandle* texture_handle = get_texture_handle(filename, thread_info); return texture(texture_handle, thread_info, options, runflags, beginactive, endactive, s, t, dsdx, dtdx, dsdy, dtdy, nchannels, result, dresultds, dresultdt); +#endif } @@ -1043,6 +1047,9 @@ TextureSystemImpl::texture(TextureHandle* texture_handle, int nchannels, float* result, float* dresultds, float* dresultdt) { +#ifdef OIIO_TEX_NO_IMPLEMENT_VARYINGREF + return false; +#else if (!texture_handle) return false; bool ok = true; @@ -1065,6 +1072,7 @@ TextureSystemImpl::texture(TextureHandle* texture_handle, } } return ok; +#endif } diff --git a/src/testtex/testtex.cpp b/src/testtex/testtex.cpp index f2d5fa7e0d..ce1c09288f 100644 --- a/src/testtex/testtex.cpp +++ b/src/testtex/testtex.cpp @@ -88,6 +88,9 @@ static bool invalidate_before_iter = true; static bool close_before_iter = false; static bool runstats = false; static bool udim_tests = false; +static bool do_gettextureinfo = true; +static int subimage = -1; +static std::string subimagename; static Imath::M33f xform; static std::string texoptions; static std::string gtiname; @@ -106,6 +109,9 @@ typedef void (*Mapping2D)(const int&, const int&, float&, float&, float&, typedef void (*Mapping3D)(const int&, const int&, Imath::V3f&, Imath::V3f&, Imath::V3f&, Imath::V3f&); +typedef void (*MappingEnv)(const int&, const int&, Imath::V3f&, Imath::V3f&, + Imath::V3f&); + typedef void (*Mapping2DWide)(const Tex::IntWide&, const Tex::IntWide&, Tex::FloatWide&, Tex::FloatWide&, Tex::FloatWide&, Tex::FloatWide&, Tex::FloatWide&, @@ -116,6 +122,11 @@ typedef void (*Mapping3DWide)(const Tex::IntWide&, const Tex::IntWide&, Imath::Vec3&, Imath::Vec3&); +typedef void (*MappingEnvWide)(const Tex::IntWide&, const Tex::IntWide&, + Imath::Vec3&, + Imath::Vec3&, + Imath::Vec3&); + static void @@ -251,6 +262,12 @@ getargs(int argc, const char* argv[]) .help("Do udim-oriented tests"); ap.arg("--bluenoise", &use_bluenoise) .help("Use blue noise for stochastic choices"); + ap.arg("--no-gettextureinfo %!", &do_gettextureinfo) + .help("Do not test gettextureinfo"); + ap.arg("--subimage %d:INDEX", &subimage) + .help("Use the specified subimage (by index)"); + ap.arg("--subimagename %s:NAME", &subimagename) + .help("Use the specified subimage (by name)"); // clang-format on ap.parse(argc, argv); @@ -282,6 +299,10 @@ initialize_opt(TextureOpt& opt) opt.anisotropic = anisomax; opt.mipmode = (TextureOpt::MipMode)mipmode; opt.interpmode = (TextureOpt::InterpMode)interpmode; + if (subimage >= 0) + opt.subimage = subimage; + else if (!subimagename.empty()) + opt.subimagename = ustring(subimagename); } @@ -307,6 +328,10 @@ initialize_opt(TextureOptBatch& opt) opt.anisotropic = anisomax; opt.mipmode = MipMode(mipmode); opt.interpmode = InterpMode(interpmode); + if (subimage >= 0) + opt.subimage = subimage; + else if (!subimagename.empty()) + opt.subimagename = ustring(subimagename); } @@ -628,6 +653,64 @@ map_warp_3D(const Int& x, const Int& y, Imath::Vec3& P, +// Just map pixels to environment direction +void +map_env_latlong(const int& x, const int& y, Imath::Vec3& R, + Imath::Vec3& dRdx, Imath::Vec3& dRdy) +{ + float u = (x + 0.5f) / output_xres; + float v = (y + 0.5f) / output_yres; + float du_dx = float(1.0f / output_xres); // du_dy = 0 + float dv_dy = float(1.0f / output_yres); // dv_dx = 0 + float theta = float(2.0 * M_PI) * u; + float dtheta_dx = float(2.0 * M_PI) * du_dx; // dtheta_dy = 0 + float phi = float(M_PI) * v; + float dphi_dy = float(M_PI) * dv_dy; // dphi_dx = 0 + + R = Imath::Vec3(fast_sin(phi) * fast_sin(theta), fast_cos(phi), + -fast_sin(phi) * fast_cos(theta)); + dRdx = Imath::Vec3(fast_sin(phi) * fast_cos(theta) * dtheta_dx, + float(0.0f), + fast_sin(phi) * fast_sin(theta) * dtheta_dx); + dRdy = Imath::Vec3(-fast_cos(phi) * fast_sin(theta) * dphi_dy, + -fast_sin(phi) * dphi_dy, + -fast_cos(phi) * fast_cos(theta) * dphi_dy); +} + + + +// Turn v3f[lanes] into simd[3] +inline Imath::Vec3 +soa(const Imath::V3f v[]) +{ + Imath::Vec3 result; + for (int i = 0; i < Tex::BatchWidth; ++i) { + result[0][i] = v[i].x; + result[1][i] = v[i].y; + result[2][i] = v[i].z; + } + return result; +} + + + +// FIXME -- templatize map_env_latlong. For now, just loop over scalar version. +void +map_env_latlong(const Tex::IntWide& x, const Tex::IntWide& y, + Imath::Vec3& R, + Imath::Vec3& dRdx, + Imath::Vec3& dRdy) +{ + Imath::V3f r[Tex::BatchWidth], drdx[Tex::BatchWidth], drdy[Tex::BatchWidth]; + for (int i = 0; i < Tex::BatchWidth; ++i) + map_env_latlong(x[i], y[i], r[i], drdx[i], drdy[i]); + R = soa(r); + dRdx = soa(drdx); + dRdy = soa(drdy); +} + + + void plain_tex_region(ImageBuf& image, ustring filename, Mapping2D mapping, ImageBuf* image_ds, ImageBuf* image_dt, ROI roi) @@ -1071,7 +1154,224 @@ static void test_shadow(ustring /*filename*/) {} -static void test_environment(ustring /*filename*/) {} +void +env_region(ImageBuf& image, ustring filename, MappingEnv mapping, + ImageBuf* image_ds, ImageBuf* image_dt, ROI roi) +{ + TextureSystem::Perthread* perthread_info = texsys->get_perthread_info(); + TextureSystem::TextureHandle* texture_handle = texsys->get_texture_handle( + filename); + int nchannels = nchannels_override ? nchannels_override : image.nchannels(); + + TextureOpt opt; + initialize_opt(opt); + + float* result = OIIO_ALLOCA(float, nchannels); + float* dresultds = test_derivs ? OIIO_ALLOCA(float, nchannels) : NULL; + float* dresultdt = test_derivs ? OIIO_ALLOCA(float, nchannels) : NULL; + for (ImageBuf::Iterator p(image, roi); !p.done(); ++p) { + Imath::V3f R, dRdx, dRdy; + mapping(p.x(), p.y(), R, dRdx, dRdy); + // if (p.x() == 0 && p.y() == 0) + // Strutil::print("R = {}\n", R); + // Call the texture system to do the filtering. + bool ok = use_handle + ? texsys->environment(texture_handle, perthread_info, opt, + R, dRdx, dRdy, nchannels, result, + dresultds, dresultdt) + : texsys->environment(filename, opt, R, dRdx, dRdy, + nchannels, result, dresultds, + dresultdt); + if (!ok) { + std::string e = texsys->geterror(); + if (!e.empty()) + Strutil::print(std::cerr, "ERROR: {}\n", e); + } + + // Save filtered pixels back to the image. + for (int i = 0; i < nchannels; ++i) + result[i] *= scalefactor; + image.setpixel(p.x(), p.y(), result); + if (image_ds) + image_ds->setpixel(p.x(), p.y(), dresultds); + if (image_dt) + image_dt->setpixel(p.x(), p.y(), dresultdt); + } +} + + + +void +env_region_batch(ImageBuf& image, ustring filename, MappingEnvWide mapping, + ImageBuf* image_ds, ImageBuf* image_dt, ROI roi) +{ + using namespace Tex; + TextureSystem::Perthread* perthread_info = texsys->get_perthread_info(); + TextureSystem::TextureHandle* texture_handle = texsys->get_texture_handle( + filename); + int nchannels_img = image.nchannels(); + int nchannels = nchannels_override ? nchannels_override : image.nchannels(); + + TextureOptBatch opt; + initialize_opt(opt); + + FloatWide* result = OIIO_ALLOCA(FloatWide, nchannels); + FloatWide* dresultds = test_derivs ? OIIO_ALLOCA(FloatWide, nchannels) + : nullptr; + FloatWide* dresultdt = test_derivs ? OIIO_ALLOCA(FloatWide, nchannels) + : nullptr; + for (int y = roi.ybegin; y < roi.yend; ++y) { + for (int x = roi.xbegin; x < roi.xend; x += BatchWidth) { + Imath::Vec3 R, dRdx, dRdy; + mapping(IntWide::Iota(x), y, R, dRdx, dRdy); + int npoints = std::min(BatchWidth, roi.xend - x); + RunMask mask = RunMaskOn >> (BatchWidth - npoints); + + // Call the texture system to do the filtering. + // if (y == 0 && x == 0) + // Strutil::print("R = {}\n", R); + bool ok + = use_handle + ? texsys->environment(texture_handle, perthread_info, opt, + mask, (const float*)&R, + (const float*)&dRdx, + (const float*)&dRdy, nchannels, + (float*)result, (float*)dresultds, + (float*)dresultdt) + : texsys->environment(filename, opt, mask, + (const float*)&R, + (const float*)&dRdx, + (const float*)&dRdy, nchannels, + (float*)result, (float*)dresultds, + (float*)dresultdt); + + if (!ok) { + std::string e = texsys->geterror(); + if (!e.empty()) + Strutil::print(std::cerr, "ERROR: {}\n", e); + } + + // Save filtered pixels back to the image. + for (int i = 0; i < nchannels; ++i) + result[i] *= scalefactor; + float* resultptr = (float*)image.pixeladdr(x, y); + // FIXME: simplify by using SIMD scatter + for (int i = 0; i < npoints; ++i) + for (int c = 0; c < nchannels; ++c) + resultptr[c + i * nchannels_img] = result[c][i]; + if (test_derivs) { + float* resultdsptr = (float*)image_ds->pixeladdr(x, y); + float* resultdtptr = (float*)image_dt->pixeladdr(x, y); + for (int c = 0; c < nchannels; ++c) { + for (int i = 0; i < npoints; ++i) { + resultdsptr[c + i * nchannels_img] = dresultds[c][i]; + resultdtptr[c + i * nchannels_img] = dresultdt[c][i]; + } + } + } + } + } +} + + + +static void +test_environment(ustring filename, MappingEnv mapping) +{ + Strutil::print("Testing environment {}, output = {}\n", filename, + output_filename); + int nchannels = nchannels_override ? nchannels_override : 4; + ImageSpec outspec(output_xres, output_yres, nchannels, TypeDesc::FLOAT); + ImageBuf image(outspec); + TypeDesc fmt(dataformatname); + image.set_write_format(fmt); + OIIO::ImageBufAlgo::zero(image); + ImageBuf image_ds, image_dt; + if (test_derivs) { + image_ds.reset(outspec); + image_ds.set_write_format(fmt); + OIIO::ImageBufAlgo::zero(image_ds); + image_dt.reset(outspec); + image_dt.set_write_format(fmt); + OIIO::ImageBufAlgo::zero(image_dt); + } + + for (int iter = 0; iter < iters; ++iter) { + // Trick: switch to second texture, if given, for second iteration + if (iter && filenames.size() > 1) + filename = filenames[1]; + if (close_before_iter) + texsys->close_all(); + ImageBufAlgo::parallel_image( + get_roi(image.spec()), nthreads, [&](ROI roi) { + env_region(image, filename, mapping, + test_derivs ? &image_ds : nullptr, + test_derivs ? &image_dt : nullptr, roi); + }); + } + + if (!image.write(output_filename)) + Strutil::print(std::cerr, "Error writing {} : {}\n", output_filename, + image.geterror()); + if (test_derivs) { + if (!image_ds.write(output_filename + "-ds.exr")) + Strutil::print(std::cerr, "Error writing {} : {}\n", + (output_filename + "-ds.exr"), image_ds.geterror()); + if (!image_dt.write(output_filename + "-dt.exr")) + Strutil::print(std::cerr, "Error writing {} : {}\n", + (output_filename + "-dt.exr"), image_dt.geterror()); + } +} + + + +static void +test_environment_batch(ustring filename, MappingEnvWide mapping) +{ + Strutil::print("Testing BATCHED environment {}, output = {}\n", filename, + output_filename); + int nchannels = nchannels_override ? nchannels_override : 4; + ImageSpec outspec(output_xres, output_yres, nchannels, TypeDesc::FLOAT); + ImageBuf image(outspec); + TypeDesc fmt(dataformatname); + image.set_write_format(fmt); + OIIO::ImageBufAlgo::zero(image); + ImageBuf image_ds, image_dt; + if (test_derivs) { + image_ds.reset(outspec); + image_ds.set_write_format(fmt); + OIIO::ImageBufAlgo::zero(image_ds); + image_dt.reset(outspec); + image_dt.set_write_format(fmt); + OIIO::ImageBufAlgo::zero(image_dt); + } + + for (int iter = 0; iter < iters; ++iter) { + // Trick: switch to second texture, if given, for second iteration + if (iter && filenames.size() > 1) + filename = filenames[1]; + if (close_before_iter) + texsys->close_all(); + ImageBufAlgo::parallel_image( + get_roi(image.spec()), nthreads, [&](ROI roi) { + env_region_batch(image, filename, mapping, + test_derivs ? &image_ds : nullptr, + test_derivs ? &image_dt : nullptr, roi); + }); + } + + if (!image.write(output_filename)) + Strutil::print(std::cerr, "Error writing {} : {}\n", output_filename, + image.geterror()); + if (test_derivs) { + if (!image_ds.write(output_filename + "-ds.exr")) + Strutil::print(std::cerr, "Error writing {} : {}\n", + (output_filename + "-ds.exr"), image_ds.geterror()); + if (!image_dt.write(output_filename + "-dt.exr")) + Strutil::print(std::cerr, "Error writing {} : {}\n", + (output_filename + "-dt.exr"), image_dt.geterror()); + } +} @@ -1121,6 +1421,7 @@ test_getimagespec_gettexels(ustring filename) +#ifndef CODECOV static void test_hash() { @@ -1155,7 +1456,7 @@ test_hash() for (int f = 0; f < nfiles; ++f) { for (int y = 0; y < res; y += tilesize) { for (int x = 0; x < res; x += tilesize, ++i) { - OIIO::pvt::TileID id(*icf[f], 0, 0, x, y, 0); + OIIO::pvt::TileID id(*icf[f], 0, 0, x, y, 0, 0, 1); size_t h = id.hash(); hh += h; } @@ -1173,7 +1474,7 @@ test_hash() for (int f = 0; f < nfiles; ++f) { for (int y = 0; y < res; y += tilesize) { for (int x = 0; x < res; x += tilesize, ++i) { - OIIO::pvt::TileID id(*icf[f], 0, 0, x, y, 0); + OIIO::pvt::TileID id(*icf[f], 0, 0, x, y, 0, 0, 1); size_t h = id.hash(); ++fourbits[h & 0xf]; ++eightbits[h & 0xff]; @@ -1229,6 +1530,7 @@ test_hash() ImageCache::destroy(imagecache); } +#endif @@ -1710,9 +2012,11 @@ main(int argc, const char* argv[]) iters = 0; } +#ifndef CODECOV if (testhash) { test_hash(); } +#endif Imath::M33f scale; scale.scale(Imath::V2f(0.3, 0.3)); @@ -1769,7 +2073,8 @@ main(int argc, const char* argv[]) Strutil::print("\n"); } else if (iters > 0 && filenames.size()) { ustring filename(filenames[0]); - test_gettextureinfo(filenames[0]); + if (do_gettextureinfo) + test_gettextureinfo(filenames[0]); const char* texturetype = "Plain Texture"; texsys->get_texture_info(filename, 0, ustring("texturetype"), TypeDesc::STRING, &texturetype); @@ -1813,10 +2118,13 @@ main(int argc, const char* argv[]) test_shadow(filename); } if (!strcmp(texturetype, "Environment")) { - test_environment(filename); + if (batch) { + test_environment_batch(filename, map_env_latlong); + } else { + test_environment(filename, map_env_latlong); + } } - if (!udim_tests) - test_getimagespec_gettexels(filename); + test_getimagespec_gettexels(filename); if (runstats || verbose) Strutil::print("Time: {}\n", Strutil::timeintervalformat(timer())); } diff --git a/testsuite/maketx/ref/out.txt b/testsuite/maketx/ref/out.txt index e706f43635..2c644b3d9d 100644 --- a/testsuite/maketx/ref/out.txt +++ b/testsuite/maketx/ref/out.txt @@ -263,6 +263,7 @@ checker-prman.tx : 128 x 128, 4 channel, int16 tiff tiff:Compression: 8 tiff:PhotometricInterpretation: 2 tiff:PlanarConfiguration: 2 +make_texture ERROR: maketx ERROR: Nan/Inf at 2 pixels Reading nan.exr nan.exr : 64 x 64, 3 channel, half openexr SHA-1: 47A8E8F3E8B2C3B6B032FCC8C39D3C5FC1AAA390 diff --git a/testsuite/maketx/run.py b/testsuite/maketx/run.py index 3ed6e9dbb9..ae5d122918 100755 --- a/testsuite/maketx/run.py +++ b/testsuite/maketx/run.py @@ -1,5 +1,8 @@ #!/usr/bin/env python +failureok = 1 + + # Just for simplicity, make a checkerboard with a solid alpha command += oiiotool (" --pattern checker 128x128 4 --ch R,G,B,=1.0" + " -d uint8 -o " + make_relpath("checker.tif") ) @@ -66,10 +69,13 @@ command += maketx_command ("checker.tif", "checker-prman.tx", "-d uint16 --prman", showinfo=True) +# Test --checknan : take advantage of the bad.exr images in +# testsuite/oiiotool-fixnan. (Use --nomipmap to cut down on stats output) +command += maketx_command (OIIO_TESTSUITE_ROOT+"/oiiotool-fixnan/src/bad.exr", + "nan.exr", "--checknan --nomipmap") + # Test --fixnan : take advantage of the bad.exr images in # testsuite/oiiotool-fixnan. (Use --nomipmap to cut down on stats output) -# FIXME: would also like to test --checknan, but the problem with that is -# that is actually FAILS if there's a nan. command += maketx_command (OIIO_TESTSUITE_ROOT+"/oiiotool-fixnan/src/bad.exr", "nan.exr", "--fixnan box3 --nomipmap", showinfo=True, showinfo_extra="--stats") @@ -121,7 +127,7 @@ -# To do: --filter --checknan --fullpixels +# To do: --filter --fullpixels # --prman-metadata --ignore-unassoc # --mipimage # --envlatl TIFF, --envlatl EXR diff --git a/testsuite/runtest.py b/testsuite/runtest.py index cc2e4fce97..b889723715 100755 --- a/testsuite/runtest.py +++ b/testsuite/runtest.py @@ -382,10 +382,11 @@ def checkref (name, refdirlist) : pattern = "*.*" else : pattern = prefix+"-*"+extension+"*" + print("comparisons are", ([defaulttest] + glob.glob (os.path.join (ref, pattern)))) for testfile in ([defaulttest] + glob.glob (os.path.join (ref, pattern))) : if not os.path.exists(testfile) : continue - # print ("comparing " + name + " to " + testfile) + print ("comparing " + name + " to " + testfile) if extension in image_extensions : # images -- use idiff cmpcommand = diff_command (name, testfile, concat=False, silent=True) diff --git a/testsuite/texture-env/ref/5chan.exr b/testsuite/texture-env/ref/5chan.exr new file mode 100644 index 0000000000000000000000000000000000000000..594f84c12bee5271599f25e0fdd628f76a89cbdd GIT binary patch literal 8153 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 ak$r!c)w>Qk-idh6nDZVi?s+v^$$tS=5~o-I literal 0 HcmV?d00001 diff --git a/testsuite/texture-env/ref/bilinear-onelevel.exr b/testsuite/texture-env/ref/bilinear-onelevel.exr new file mode 100644 index 0000000000000000000000000000000000000000..2132363da66ebd1c3713663316e73de861a2529b GIT binary patch literal 2172 zcmah}dpOj27yk)MT1B~TS&|KraeIl0K}se=7gsKqL{c!DwL5CS`1BY;0*{WNB=!VRXdO(Ad)00*OHc2cvLA0Exk2i6p>rv&|L| z+kCfTt8S&;H;ltK%$aW(0ErI@A)tsvEI#-+f{jGsY>6Q#B#o_f3|pH14x+vkpOOdH3ERD@BW$6l>~suOB465 z;1oO*UZao6rD$RNHUC&m)|A(EOGr9#cw+EOa-l9o#deQ>DkXN;7>iohV1f<|FY7hf zf8xu5_8!;E`tT=-m-p7>H7$zEYTdhc$XDZ_w2Yl>b6gEKA6h-Ly1Fx{dV51R?7l@c zSdE6#ekb}WYBZI4h{XY_6F@u`s1Dp#D3p2oV5Zob8XFpQ8uCgP@~X!Rz{Uesql538 z8r+*W{#fkCTX(v8yX~g%FSSIwWz6rOp<`q-=W6;}Zv2bNquhYwb0d#jBb#$WFe|rR zBQHU?dJ7|aU$hIdS+~TL)=aEd^0BoQ%WSHYp~0yi-!TUD8V>R7@fs}NWdzPi?u1ow z&*|#;eO5)fsp%t_kMz0dV--Jzs#|;yeb(szk$dw}Z8m?xyBzP1S-LS==4_f9(N=Y< zuPB5Qf`DLDu6={s$uTKgqc{gyF zj1@#5L}Ib|QeDQ9jFh!W>Jecc#CJWOU9qr0nGc^nw!`{1jGRL&2|sJSaHcm##jsxj zlKGo%X;ET4fBJ#{sUfLfp9{V8ES<(g?czS7&r{=lGj9qmjIq`whiis_g*+3N3fZz< zxc$NfEd$yp>Vj}&%|b|b-Nq`;9DHwpcJ}7})@;G4aUGG1gm&^@wlni}{G7dQE!Xqn zui{#UDK3Hy@Al%QnEpi2zT2&Zah5ib2o`(NQlR9DD&|o<$>GZlO=eF958=jg`{j7l zL?XFrHTy1|woyGaL5c3msS9s4WA>co(1V)kTFm8h$F58a`|Tf@%Drj{zShkd$Arr3=7$|aW;+UmfJm5(Uu><)w1dEoi& zf1;JD4Te}g-H@my!;DJzc`I3wS-<)FFcH3fnEZ?b=I|=W=dx@rie*-rrG;>kb! znwdwCB!qg@0-A`68e3pYTZ;td@;s@NdovEZj;YeMCsP(y!_H~j`1vULp`cu0(aAL! znsl>ZksPgBR11y{nTLX$;gz-#aQ4FTb7oBJGYeo&3dq-9ztD$#K)+u8)?qbD-AeW? ze7L2=0r)w$sEOggBWDyw-MyMXGq{@~B9=d{=Eh>1G8-7zc6PW#!VFZ5QucDfCe|Jz z6fz?0EF3pVn?uQgg08?+>}QjQQPCb^R4u|6`_9qzfkyode!dU1pKa@*csz5C-Ld=& zh0C*wMw>1~RmE95>ZA!CdQkZ174$%5o8>)ty`1bx<<)CKeRvHlrCSQ6=UZ9=xB1y4 ziz?M|BTRltN3>mDJyMfpP7Q2cPZ9X`C8$t&)=Eq7+^GRx!$qAGH-(u#vb3*5TDS5F zK8NARL*4F%Os$`O+}p_-5JYm+wU(_{o$G=eGqoEzPVSECI_`rSs`~ zPK0HhoN2mx&1;D=COc!(#@xG=B~e#mudfehuh6c_a0N~@c4g_6dDy;I9wpIx{54p355%{?o^V~NI2q;olYKQz zK>yWqFE_>19^|ws|G;$vTVCk*ZS$`>f+7}MM<&xcraVKmHBN*&(BnGL7nDot`JgzN z;8M1A_**uQXym0YS+?+28-<%Qx_74S2F0a+v{BBtmG{y0KTgtq>X>uiw10>6ckbzj zl0MK=buOBQEl)m@_E(O}Z~o9&Soz5meo(xtRmfsTh*a%p35~^6+E8egOF}@e?m$)@ zLL~$KPzP?v`p6LU+F!i(%o92Hq=DGRSjpyUb^6-9f#KM}P7H%{Fg p{MRS+?iJMRM#TpgX4hvhkLKh&uq_7uRB>hC9%Kioy<<0~>@PQ+2~_|9 literal 0 HcmV?d00001 diff --git a/testsuite/texture-env/ref/closest-nomip.exr b/testsuite/texture-env/ref/closest-nomip.exr new file mode 100644 index 0000000000000000000000000000000000000000..a0871a80df5fc2de610107e2ee82aa399afa16c7 GIT binary patch literal 1073 zcmXTZH)LdDU|>j2EO1FINo6Q5Day=CXAlMo85tNESs5By8JQ~>T38tvSs7U*XC&t3 zrREefBxmGg7MC!10+l&3Fak*s0MQ`qgdyUNArgck!jPPwTTql*T%4Johr$LK$()i{ zk{F(umy%!3kd$9xl*u3f6omnMAVVIAQ!Es>{jDOZ6{GNiAYPu)v-u$gD`s zaV#!KO)d#aEXmAgNXyAjEMZ^)Thw4*oLrQeng=o7IW?~YXh4}!8UqK+9Y7jcNqA;T zNd}q`42@um7#QAzLLCayfMOMKZ?D8^vjobpeJIsDx%{G^8-E=G4uO_~Kx6NI7;(uB+f5NMm zZol$+Bww$tiSs||8(1;?C0Z+U+5@4LU>cRE$~-MK$$6X(m+Pw(Tm|JFb9 zp6l(>dGl}8tECEG+Wh4H{=Dz=yYGwMGPbRs@}F77DqsyL)mTA7dy1piVF!uU*M=@f zriy&z(z9*th~QFM>TX~m?0a3$)vGhW<&Jmv>K)&i79E}1QNdoAWd1c(tCBB7?o4={ zTusY?>#kDI>Mh+JFZuRg_RoHME$H#@?=g48kDlTEY_tE&@*m%L;&&v-1y0E6`mVoN z;itg+`;Lx9%J=FUo0cfw``^-(;=HGxmG$KAivN0Cld?blv*ViN{P7ecZ@hm$v^;r#+5ZzEvuEUX*8fl1zkl_+WB)e% J({BcbAON2SxC8(I literal 0 HcmV?d00001 diff --git a/testsuite/texture-env/ref/env-handle.exr b/testsuite/texture-env/ref/env-handle.exr new file mode 100644 index 0000000000000000000000000000000000000000..a05a75df2043dc92178e48f508500dd67844640d GIT binary patch literal 5973 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 y_|kfs4DLWo-HoOKtH)30cPgn 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 literal 0 HcmV?d00001 diff --git a/testsuite/texture-env/ref/out-batch.txt b/testsuite/texture-env/ref/out-batch.txt new file mode 100644 index 0000000000..a8e4f47c3a --- /dev/null +++ b/testsuite/texture-env/ref/out-batch.txt @@ -0,0 +1,54 @@ +Created texture system +Result of get_texture_info resolution (as int[2]) = true 256x128 +Result of get_texture_info resolution (as int[3]) = true 256x128x1 +Result of get_texture_info channels = true 4 +Result of get_texture_info channels = true 4 +Result of get_texture_info data format = true half +Result of get_texture_info datawindow (as int[4]) = true [0 0 255 127] +Result of get_texture_info datawindow (as int[6]) = true [0 0 0 255 127 0] +Result of get_texture_info displaywindow (as int[4]) = true [0 0 255 127] +Result of get_texture_info displaywindow (as int[6]) = true [0 0 0 255 127 0] +Result of get_texture_info datetime = true 2022-11-11 11:11:11 +Result of get_texture_info averagecolor = yes 0.375 0.375 0 1 +Result of get_texture_info averagealpha = yes 1 +Result of get_texture_info constantcolor = no +Result of get_texture_info constantalpha = no +Texture type is true LatLong Environment + +Testing BATCHED environment rampenv.exr, output = env.exr +Created texture system +Testing BATCHED environment rampenv.exr, output = env-handle.exr +Created texture system +Testing BATCHED environment env5chan.exr, output = 5chan.exr +Created texture system +Testing BATCHED environment rampenv.exr, output = subimage0.exr +Created texture system +Testing BATCHED environment rampenv.exr, output = subimagefred.exr +Created texture system +Testing BATCHED environment rampenv.exr, output = subimagemissing.exr +ERROR: Unknown subimage "missing" in texture "rampenv.exr" +Unknown subimage "missing" in texture "rampenv.exr" +Created texture system +Testing BATCHED environment rampenv.exr, output = closest-nomip.exr +Created texture system +Testing BATCHED environment rampenv.exr, output = bilinear-onelevel.exr +Created texture system +Testing BATCHED environment rampenv.exr, output = bicubic-trilinear.exr +Comparing "env.exr" and "ref/env.exr" +PASS +Comparing "env-handle.exr" and "ref/env-handle.exr" +PASS +Comparing "5chan.exr" and "ref/5chan.exr" +PASS +Comparing "subimage0.exr" and "ref/subimage0.exr" +PASS +Comparing "subimagefred.exr" and "ref/subimagefred.exr" +PASS +Comparing "subimagemissing.exr" and "ref/subimagemissing.exr" +PASS +Comparing "closest-nomip.exr" and "ref/closest-nomip.exr" +PASS +Comparing "bilinear-onelevel.exr" and "ref/bilinear-onelevel.exr" +PASS +Comparing "bicubic-trilinear.exr" and "ref/bicubic-trilinear.exr" +PASS diff --git a/testsuite/texture-env/ref/out.txt b/testsuite/texture-env/ref/out.txt new file mode 100644 index 0000000000..b0357da282 --- /dev/null +++ b/testsuite/texture-env/ref/out.txt @@ -0,0 +1,54 @@ +Created texture system +Result of get_texture_info resolution (as int[2]) = true 256x128 +Result of get_texture_info resolution (as int[3]) = true 256x128x1 +Result of get_texture_info channels = true 4 +Result of get_texture_info channels = true 4 +Result of get_texture_info data format = true half +Result of get_texture_info datawindow (as int[4]) = true [0 0 255 127] +Result of get_texture_info datawindow (as int[6]) = true [0 0 0 255 127 0] +Result of get_texture_info displaywindow (as int[4]) = true [0 0 255 127] +Result of get_texture_info displaywindow (as int[6]) = true [0 0 0 255 127 0] +Result of get_texture_info datetime = true 2022-11-11 11:11:11 +Result of get_texture_info averagecolor = yes 0.375 0.375 0 1 +Result of get_texture_info averagealpha = yes 1 +Result of get_texture_info constantcolor = no +Result of get_texture_info constantalpha = no +Texture type is true LatLong Environment + +Testing environment rampenv.exr, output = env.exr +Created texture system +Testing environment rampenv.exr, output = env-handle.exr +Created texture system +Testing environment env5chan.exr, output = 5chan.exr +Created texture system +Testing environment rampenv.exr, output = subimage0.exr +Created texture system +Testing environment rampenv.exr, output = subimagefred.exr +Created texture system +Testing environment rampenv.exr, output = subimagemissing.exr +ERROR: Unknown subimage "missing" in texture "rampenv.exr" +ERROR: Unknown subimage "missing" in texture "rampenv.exr" +Created texture system +Testing environment rampenv.exr, output = closest-nomip.exr +Created texture system +Testing environment rampenv.exr, output = bilinear-onelevel.exr +Created texture system +Testing environment rampenv.exr, output = bicubic-trilinear.exr +Comparing "env.exr" and "ref/env.exr" +PASS +Comparing "env-handle.exr" and "ref/env-handle.exr" +PASS +Comparing "5chan.exr" and "ref/5chan.exr" +PASS +Comparing "subimage0.exr" and "ref/subimage0.exr" +PASS +Comparing "subimagefred.exr" and "ref/subimagefred.exr" +PASS +Comparing "subimagemissing.exr" and "ref/subimagemissing.exr" +PASS +Comparing "closest-nomip.exr" and "ref/closest-nomip.exr" +PASS +Comparing "bilinear-onelevel.exr" and "ref/bilinear-onelevel.exr" +PASS +Comparing "bicubic-trilinear.exr" and "ref/bicubic-trilinear.exr" +PASS diff --git a/testsuite/texture-env/ref/subimage0.exr b/testsuite/texture-env/ref/subimage0.exr new file mode 100644 index 0000000000000000000000000000000000000000..e28ed7de198a0d8ce77f027f0e072ae07deb9b6b GIT binary patch literal 5973 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 literal 0 HcmV?d00001 diff --git a/testsuite/texture-env/ref/subimagefred.exr b/testsuite/texture-env/ref/subimagefred.exr new file mode 100644 index 0000000000000000000000000000000000000000..e28ed7de198a0d8ce77f027f0e072ae07deb9b6b GIT binary patch literal 5973 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 literal 0 HcmV?d00001 diff --git a/testsuite/texture-env/ref/subimagemissing.exr b/testsuite/texture-env/ref/subimagemissing.exr new file mode 100644 index 0000000000000000000000000000000000000000..6248cdc97c2c991f8993e165aaa91d653a77c2f7 GIT binary patch literal 399 zcmaiu&uRiO5XQ$^Xip+|^VBzJH;Cebh;2c7YVqQ&5R=gzh)GBWyWaN2e5XD_vzEoS zd+5OY;p5{s-{C&%TmgWR{#i0Y#mVqEm^L~YWD#fR|