Texture filtering tests in Vulkan
authorCollin Baker <collinbaker@google.com>
Mon, 25 Jul 2016 21:32:02 +0000 (14:32 -0700)
committerCollin Baker <collinbaker@google.com>
Wed, 27 Jul 2016 21:29:10 +0000 (14:29 -0700)
This is a framework for testing image sampling with explicit LOD in vulkan.

Change-Id: I36ea968d9e4624a76b9a918f5ab7e3d5a9039a55

16 files changed:
Android.mk
android/cts/master/com.drawelements.deqp.vk.xml
android/cts/master/vk-master.txt
external/vulkancts/framework/vulkan/vkImageUtil.cpp
external/vulkancts/framework/vulkan/vkImageUtil.hpp
external/vulkancts/modules/vulkan/CMakeLists.txt
external/vulkancts/modules/vulkan/shaderexecutor/vktShaderExecutor.cpp
external/vulkancts/modules/vulkan/shaderexecutor/vktShaderExecutor.hpp
external/vulkancts/modules/vulkan/texture_filtering/CMakeLists.txt [new file with mode: 0644]
external/vulkancts/modules/vulkan/texture_filtering/vktSampleVerifier.cpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/texture_filtering/vktSampleVerifier.hpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/texture_filtering/vktTextureFilteringExplicitLodTests.cpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/texture_filtering/vktTextureFilteringExplicitLodTests.hpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/texture_filtering/vktTextureFilteringTests.cpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/texture_filtering/vktTextureFilteringTests.hpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/vktTestPackage.cpp

index 0ae3320..a00fe25 100644 (file)
@@ -787,8 +787,8 @@ LOCAL_SRC_FILES := \
        external/vulkancts/modules/vulkan/shaderexecutor/vktShaderExecutor.cpp \
        external/vulkancts/modules/vulkan/shaderexecutor/vktShaderIntegerFunctionTests.cpp \
        external/vulkancts/modules/vulkan/shaderexecutor/vktShaderPackingFunctionTests.cpp \
-       external/vulkancts/modules/vulkan/shaderrender/vktShaderRenderBuiltinVarTests.cpp \
        external/vulkancts/modules/vulkan/shaderrender/vktShaderRender.cpp \
+       external/vulkancts/modules/vulkan/shaderrender/vktShaderRenderBuiltinVarTests.cpp \
        external/vulkancts/modules/vulkan/shaderrender/vktShaderRenderDerivateTests.cpp \
        external/vulkancts/modules/vulkan/shaderrender/vktShaderRenderDiscardTests.cpp \
        external/vulkancts/modules/vulkan/shaderrender/vktShaderRenderIndexingTests.cpp \
@@ -845,6 +845,9 @@ LOCAL_SRC_FILES := \
        external/vulkancts/modules/vulkan/tessellation/vktTessellationUserDefinedIO.cpp \
        external/vulkancts/modules/vulkan/tessellation/vktTessellationUtil.cpp \
        external/vulkancts/modules/vulkan/tessellation/vktTessellationWindingTests.cpp \
+       external/vulkancts/modules/vulkan/texture_filtering/vktSampleVerifier.cpp \
+       external/vulkancts/modules/vulkan/texture_filtering/vktTextureFilteringTests.cpp \
+       external/vulkancts/modules/vulkan/texture_filtering/vktTextureFilteringExplicitLodTests.cpp \
        external/vulkancts/modules/vulkan/ubo/vktRandomUniformBlockCase.cpp \
        external/vulkancts/modules/vulkan/ubo/vktUniformBlockCase.cpp \
        external/vulkancts/modules/vulkan/ubo/vktUniformBlockTests.cpp \
@@ -918,6 +921,7 @@ LOCAL_C_INCLUDES := \
        $(deqp_dir)/external/vulkancts/modules/vulkan/ssbo \
        $(deqp_dir)/external/vulkancts/modules/vulkan/synchronization \
        $(deqp_dir)/external/vulkancts/modules/vulkan/tessellation \
+       $(deqp_dir)/external/vulkancts/modules/vulkan/texture_filtering \
        $(deqp_dir)/external/vulkancts/modules/vulkan/ubo \
        $(deqp_dir)/external/vulkancts/modules/vulkan/wsi
 
index 96aeaea..b0ce753 100644 (file)
                                </TestSuite>
                        </TestSuite>
                </TestSuite>
+               <TestSuite name="texture_filtering">
+                       <TestSuite name="explicit_lod">
+                               <TestSuite name="2d">
+                                       <TestCase name="sizes">
+                                               <Test name="2x2_nearest_nearest_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x2_nearest_nearest_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x2_nearest_nearest_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x2_nearest_nearest_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x2_nearest_linear_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x2_nearest_linear_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x2_nearest_linear_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x2_nearest_linear_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x2_linear_nearest_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x2_linear_nearest_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x2_linear_nearest_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x2_linear_nearest_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x2_linear_linear_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x2_linear_linear_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x2_linear_linear_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x2_linear_linear_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x3_nearest_nearest_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x3_nearest_nearest_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x3_nearest_nearest_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x3_nearest_nearest_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x3_nearest_linear_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x3_nearest_linear_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x3_nearest_linear_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x3_nearest_linear_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x3_linear_nearest_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x3_linear_nearest_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x3_linear_nearest_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x3_linear_nearest_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x3_linear_linear_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x3_linear_linear_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x3_linear_linear_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="2x3_linear_linear_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="3x7_nearest_nearest_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="3x7_nearest_nearest_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="3x7_nearest_nearest_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="3x7_nearest_nearest_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="3x7_nearest_linear_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="3x7_nearest_linear_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="3x7_nearest_linear_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="3x7_nearest_linear_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="3x7_linear_nearest_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="3x7_linear_nearest_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="3x7_linear_nearest_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="3x7_linear_nearest_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="3x7_linear_linear_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="3x7_linear_linear_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="3x7_linear_linear_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="3x7_linear_linear_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="4x8_nearest_nearest_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="4x8_nearest_nearest_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="4x8_nearest_nearest_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="4x8_nearest_nearest_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="4x8_nearest_linear_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="4x8_nearest_linear_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="4x8_nearest_linear_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="4x8_nearest_linear_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="4x8_linear_nearest_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="4x8_linear_nearest_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="4x8_linear_nearest_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="4x8_linear_nearest_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="4x8_linear_linear_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="4x8_linear_linear_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="4x8_linear_linear_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="4x8_linear_linear_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="31x55_nearest_nearest_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="31x55_nearest_nearest_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="31x55_nearest_nearest_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="31x55_nearest_nearest_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="31x55_nearest_linear_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="31x55_nearest_linear_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="31x55_nearest_linear_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="31x55_nearest_linear_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="31x55_linear_nearest_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="31x55_linear_nearest_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="31x55_linear_nearest_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="31x55_linear_nearest_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="31x55_linear_linear_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="31x55_linear_linear_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="31x55_linear_linear_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="31x55_linear_linear_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x32_nearest_nearest_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x32_nearest_nearest_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x32_nearest_nearest_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x32_nearest_nearest_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x32_nearest_linear_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x32_nearest_linear_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x32_nearest_linear_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x32_nearest_linear_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x32_linear_nearest_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x32_linear_nearest_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x32_linear_nearest_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x32_linear_nearest_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x32_linear_linear_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x32_linear_linear_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x32_linear_linear_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x32_linear_linear_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x64_nearest_nearest_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x64_nearest_nearest_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x64_nearest_nearest_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x64_nearest_nearest_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x64_nearest_linear_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x64_nearest_linear_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x64_nearest_linear_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x64_nearest_linear_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x64_linear_nearest_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x64_linear_nearest_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x64_linear_nearest_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x64_linear_nearest_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x64_linear_linear_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x64_linear_linear_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x64_linear_linear_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="32x64_linear_linear_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="57x35_nearest_nearest_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="57x35_nearest_nearest_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="57x35_nearest_nearest_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="57x35_nearest_nearest_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="57x35_nearest_linear_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="57x35_nearest_linear_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="57x35_nearest_linear_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="57x35_nearest_linear_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="57x35_linear_nearest_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="57x35_linear_nearest_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="57x35_linear_nearest_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="57x35_linear_nearest_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="57x35_linear_linear_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="57x35_linear_linear_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="57x35_linear_linear_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="57x35_linear_linear_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="128x128_nearest_nearest_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="128x128_nearest_nearest_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="128x128_nearest_nearest_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="128x128_nearest_nearest_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="128x128_nearest_linear_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="128x128_nearest_linear_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="128x128_nearest_linear_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="128x128_nearest_linear_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="128x128_linear_nearest_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="128x128_linear_nearest_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="128x128_linear_nearest_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="128x128_linear_nearest_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="128x128_linear_linear_mipmap_nearest_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="128x128_linear_linear_mipmap_nearest_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="128x128_linear_linear_mipmap_linear_repeat">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="128x128_linear_linear_mipmap_linear_clamp">
+                                                       <TestInstance/>
+                                               </Test>
+                                       </TestCase>
+                                       <TestCase name="formats">
+                                               <Test name="VK_FORMAT_B4G4R4A4_UNORM_PACK16_nearest">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_B4G4R4A4_UNORM_PACK16_linear">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_R5G6B5_UNORM_PACK16_nearest">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_R5G6B5_UNORM_PACK16_linear">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_A1R5G5B5_UNORM_PACK16_nearest">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_A1R5G5B5_UNORM_PACK16_linear">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_R8_UNORM_nearest">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_R8_UNORM_linear">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_R8_SNORM_nearest">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_R8_SNORM_linear">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_R8G8_UNORM_nearest">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_R8G8_UNORM_linear">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_R8G8_SNORM_nearest">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_R8G8_SNORM_linear">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_R8G8B8A8_UNORM_nearest">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_R8G8B8A8_UNORM_linear">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_R8G8B8A8_SNORM_nearest">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_R8G8B8A8_SNORM_linear">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_R8G8B8A8_SRGB_nearest">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_R8G8B8A8_SRGB_linear">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_B8G8R8A8_UNORM_nearest">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_B8G8R8A8_UNORM_linear">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_B8G8R8A8_SRGB_nearest">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_B8G8R8A8_SRGB_linear">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_A8B8G8R8_UNORM_PACK32_nearest">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_A8B8G8R8_UNORM_PACK32_linear">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_A8B8G8R8_SNORM_PACK32_nearest">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_A8B8G8R8_SNORM_PACK32_linear">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_A8B8G8R8_SRGB_PACK32_nearest">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_A8B8G8R8_SRGB_PACK32_linear">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_A2B10G10R10_UNORM_PACK32_nearest">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_A2B10G10R10_UNORM_PACK32_linear">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_R16_SFLOAT_nearest">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_R16_SFLOAT_linear">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_R16G16_SFLOAT_nearest">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_R16G16_SFLOAT_linear">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_R16G16B16A16_SFLOAT_nearest">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_R16G16B16A16_SFLOAT_linear">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_B10G11R11_UFLOAT_PACK32_nearest">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_B10G11R11_UFLOAT_PACK32_linear">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_E5B9G9R9_UFLOAT_PACK32_nearest">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="VK_FORMAT_E5B9G9R9_UFLOAT_PACK32_linear">
+                                                       <TestInstance/>
+                                               </Test>
+                                       </TestCase>
+                               </TestSuite>
+                       </TestSuite>
+               </TestSuite>
        </TestSuite>
 </TestPackage>
index f7a21a0..efb35a4 100644 (file)
@@ -114335,3 +114335,189 @@ dEQP-VK.clipping.user_defined.clip_cull_distance_dynamic_index.vert_tess_geom.5_
 dEQP-VK.clipping.user_defined.clip_cull_distance_dynamic_index.vert_tess_geom.6_2
 dEQP-VK.clipping.user_defined.clip_cull_distance_dynamic_index.vert_tess_geom.7_1
 dEQP-VK.clipping.user_defined.clip_cull_distance_dynamic_index.vert_tess_geom.8
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x2_nearest_nearest_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x2_nearest_nearest_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x2_nearest_nearest_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x2_nearest_nearest_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x2_nearest_linear_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x2_nearest_linear_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x2_nearest_linear_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x2_nearest_linear_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x2_linear_nearest_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x2_linear_nearest_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x2_linear_nearest_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x2_linear_nearest_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x2_linear_linear_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x2_linear_linear_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x2_linear_linear_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x2_linear_linear_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x3_nearest_nearest_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x3_nearest_nearest_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x3_nearest_nearest_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x3_nearest_nearest_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x3_nearest_linear_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x3_nearest_linear_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x3_nearest_linear_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x3_nearest_linear_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x3_linear_nearest_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x3_linear_nearest_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x3_linear_nearest_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x3_linear_nearest_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x3_linear_linear_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x3_linear_linear_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x3_linear_linear_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.2x3_linear_linear_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.3x7_nearest_nearest_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.3x7_nearest_nearest_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.3x7_nearest_nearest_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.3x7_nearest_nearest_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.3x7_nearest_linear_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.3x7_nearest_linear_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.3x7_nearest_linear_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.3x7_nearest_linear_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.3x7_linear_nearest_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.3x7_linear_nearest_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.3x7_linear_nearest_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.3x7_linear_nearest_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.3x7_linear_linear_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.3x7_linear_linear_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.3x7_linear_linear_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.3x7_linear_linear_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.4x8_nearest_nearest_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.4x8_nearest_nearest_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.4x8_nearest_nearest_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.4x8_nearest_nearest_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.4x8_nearest_linear_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.4x8_nearest_linear_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.4x8_nearest_linear_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.4x8_nearest_linear_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.4x8_linear_nearest_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.4x8_linear_nearest_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.4x8_linear_nearest_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.4x8_linear_nearest_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.4x8_linear_linear_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.4x8_linear_linear_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.4x8_linear_linear_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.4x8_linear_linear_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.31x55_nearest_nearest_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.31x55_nearest_nearest_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.31x55_nearest_nearest_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.31x55_nearest_nearest_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.31x55_nearest_linear_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.31x55_nearest_linear_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.31x55_nearest_linear_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.31x55_nearest_linear_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.31x55_linear_nearest_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.31x55_linear_nearest_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.31x55_linear_nearest_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.31x55_linear_nearest_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.31x55_linear_linear_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.31x55_linear_linear_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.31x55_linear_linear_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.31x55_linear_linear_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x32_nearest_nearest_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x32_nearest_nearest_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x32_nearest_nearest_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x32_nearest_nearest_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x32_nearest_linear_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x32_nearest_linear_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x32_nearest_linear_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x32_nearest_linear_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x32_linear_nearest_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x32_linear_nearest_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x32_linear_nearest_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x32_linear_nearest_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x32_linear_linear_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x32_linear_linear_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x32_linear_linear_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x32_linear_linear_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x64_nearest_nearest_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x64_nearest_nearest_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x64_nearest_nearest_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x64_nearest_nearest_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x64_nearest_linear_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x64_nearest_linear_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x64_nearest_linear_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x64_nearest_linear_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x64_linear_nearest_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x64_linear_nearest_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x64_linear_nearest_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x64_linear_nearest_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x64_linear_linear_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x64_linear_linear_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x64_linear_linear_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.32x64_linear_linear_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.57x35_nearest_nearest_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.57x35_nearest_nearest_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.57x35_nearest_nearest_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.57x35_nearest_nearest_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.57x35_nearest_linear_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.57x35_nearest_linear_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.57x35_nearest_linear_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.57x35_nearest_linear_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.57x35_linear_nearest_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.57x35_linear_nearest_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.57x35_linear_nearest_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.57x35_linear_nearest_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.57x35_linear_linear_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.57x35_linear_linear_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.57x35_linear_linear_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.57x35_linear_linear_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.128x128_nearest_nearest_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.128x128_nearest_nearest_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.128x128_nearest_nearest_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.128x128_nearest_nearest_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.128x128_nearest_linear_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.128x128_nearest_linear_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.128x128_nearest_linear_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.128x128_nearest_linear_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.128x128_linear_nearest_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.128x128_linear_nearest_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.128x128_linear_nearest_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.128x128_linear_nearest_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.128x128_linear_linear_mipmap_nearest_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.128x128_linear_linear_mipmap_nearest_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.128x128_linear_linear_mipmap_linear_repeat
+dEQP-VK.texture_filtering.explicit_lod.2d.sizes.128x128_linear_linear_mipmap_linear_clamp
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_B4G4R4A4_UNORM_PACK16_nearest
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_B4G4R4A4_UNORM_PACK16_linear
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_R5G6B5_UNORM_PACK16_nearest
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_R5G6B5_UNORM_PACK16_linear
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_A1R5G5B5_UNORM_PACK16_nearest
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_A1R5G5B5_UNORM_PACK16_linear
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_R8_UNORM_nearest
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_R8_UNORM_linear
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_R8_SNORM_nearest
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_R8_SNORM_linear
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_R8G8_UNORM_nearest
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_R8G8_UNORM_linear
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_R8G8_SNORM_nearest
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_R8G8_SNORM_linear
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_R8G8B8A8_UNORM_nearest
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_R8G8B8A8_UNORM_linear
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_R8G8B8A8_SNORM_nearest
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_R8G8B8A8_SNORM_linear
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_R8G8B8A8_SRGB_nearest
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_R8G8B8A8_SRGB_linear
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_B8G8R8A8_UNORM_nearest
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_B8G8R8A8_UNORM_linear
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_B8G8R8A8_SRGB_nearest
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_B8G8R8A8_SRGB_linear
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_A8B8G8R8_UNORM_PACK32_nearest
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_A8B8G8R8_UNORM_PACK32_linear
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_A8B8G8R8_SNORM_PACK32_nearest
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_A8B8G8R8_SNORM_PACK32_linear
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_A8B8G8R8_SRGB_PACK32_nearest
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_A8B8G8R8_SRGB_PACK32_linear
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_A2B10G10R10_UNORM_PACK32_nearest
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_A2B10G10R10_UNORM_PACK32_linear
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_R16_SFLOAT_nearest
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_R16_SFLOAT_linear
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_R16G16_SFLOAT_nearest
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_R16G16_SFLOAT_linear
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_R16G16B16A16_SFLOAT_nearest
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_R16G16B16A16_SFLOAT_linear
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_B10G11R11_UFLOAT_PACK32_nearest
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_B10G11R11_UFLOAT_PACK32_linear
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_E5B9G9R9_UFLOAT_PACK32_nearest
+dEQP-VK.texture_filtering.explicit_lod.2d.formats.VK_FORMAT_E5B9G9R9_UFLOAT_PACK32_linear
index f529ee7..c115775 100644 (file)
@@ -63,6 +63,23 @@ bool isDepthStencilFormat (VkFormat format)
        return tcuFormat.order == tcu::TextureFormat::D || tcuFormat.order == tcu::TextureFormat::S || tcuFormat.order == tcu::TextureFormat::DS;
 }
 
+bool isSrgbFormat (VkFormat format)
+{
+       switch (mapVkFormat(format).order)
+       {
+               case tcu::TextureFormat::sR:
+               case tcu::TextureFormat::sRG:
+               case tcu::TextureFormat::sRGB:
+               case tcu::TextureFormat::sRGBA:
+               case tcu::TextureFormat::sBGR:
+               case tcu::TextureFormat::sBGRA:
+                       return true;
+
+               default:
+                       return false;
+       }
+}
+
 bool isCompressedFormat (VkFormat format)
 {
        // update this mapping if VkFormat changes
index 0c16a05..b2f02ec 100644 (file)
@@ -39,6 +39,7 @@ bool                                          isIntFormat                                     (VkFormat format);
 bool                                           isUintFormat                            (VkFormat format);
 bool                                           isDepthStencilFormat            (VkFormat format);
 bool                                           isCompressedFormat                      (VkFormat format);
+bool                                           isSrgbFormat                            (VkFormat format);
 
 tcu::TextureFormat                     mapVkFormat                                     (VkFormat format);
 tcu::CompressedTexFormat       mapVkCompressedFormat           (VkFormat format);
index 9c27e91..fbc11d0 100644 (file)
@@ -6,6 +6,7 @@ add_subdirectory(binding_model)
 add_subdirectory(spirv_assembly)
 add_subdirectory(shaderrender)
 add_subdirectory(shaderexecutor)
+add_subdirectory(texture_filtering)
 add_subdirectory(memory)
 add_subdirectory(ubo)
 add_subdirectory(dynamic_state)
@@ -28,6 +29,7 @@ include_directories(
        spirv_assembly
        shaderrender
        shaderexecutor
+       texture_filtering
        memory
        ubo
        dynamic_state
@@ -71,6 +73,7 @@ set(DEQP_VK_COMMON_LIBS
        deqp-vk-spirv-assembly
        deqp-vk-shaderrender
        deqp-vk-shaderexecutor
+       deqp-vk-texture-filtering
        deqp-vk-memory
        deqp-vk-ubo
        deqp-vk-dynamic-state
index 4302e28..4a7fc94 100644 (file)
@@ -960,7 +960,7 @@ void FragmentOutExecutor::execute (const Context& ctx, int numValues, const void
                descriptorSetLayout = m_descriptorSetLayoutBuilder.build(vk, vkDevice);
                if (!m_uniformInfos.empty())
                        descriptorPool = m_descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
-               else 
+               else
                {
                        const VkDescriptorPoolSize                      poolSizeCount   = { vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1 };
                        const VkDescriptorPoolCreateInfo        createInfo              =
@@ -3065,6 +3065,29 @@ void ShaderExecutor::setupSamplerData (const VkDevice&                           vkDevice,
        m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(samplers)));
 }
 
+void ShaderExecutor::addSamplerUniform (deUint32                               bindingLocation,
+                                                                               VkImageView                             imageView,
+                                                                               VkSampler                               sampler)
+{
+       de::MovePtr<UnmanagedSamplerUniform> samplerUniform(new UnmanagedSamplerUniform());
+
+       const VkDescriptorImageInfo descriptor =
+       {
+               sampler,
+               imageView,
+               VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
+       };
+
+       samplerUniform->type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+       samplerUniform->location = bindingLocation;
+       samplerUniform->descriptor = descriptor;
+
+       m_uniformInfos.push_back(UniformInfoSp(new de::UniquePtr<UniformInfo>(samplerUniform)));
+
+       m_descriptorSetLayoutBuilder.addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_ALL, DE_NULL);
+       m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1);
+}
+
 const void*    ShaderExecutor::getBufferPtr (const deUint32 bindingLocation) const
 {
        std::vector<UniformInfoSp>::const_iterator it = m_uniformInfos.begin();
@@ -3134,6 +3157,11 @@ void ShaderExecutor::uploadUniforms (DescriptorSetUpdateBuilder& descriptorSetUp
                        const SamplerUniform*                                   samplerUniform  = static_cast<const SamplerUniform*>(uniformInfo);
                        descriptorSetUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(samplerUniform->location), samplerUniform->type, &samplerUniform->descriptor);
                }
+               else if (uniformType == UniformInfo::UNIFORM_TYPE_UNMANAGED_SAMPLER)
+               {
+                       const UnmanagedSamplerUniform* samplerUniform = static_cast<const UnmanagedSamplerUniform*>(uniformInfo);
+                       descriptorSetUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(samplerUniform->location), samplerUniform->type, &samplerUniform->descriptor);
+               }
        }
 }
 
index c90d815..80b190f 100644 (file)
@@ -148,6 +148,10 @@ public:
                                                                                                 VkImageViewType                        imageViewType,
                                                                                                 const void*                            data);
 
+       void                                    addSamplerUniform       (deUint32                                       bindingLocation,
+                                                                                                VkImageView                            imageView,
+                                                                                                VkSampler                                      sampler);
+
        const void*                             getBufferPtr            (const deUint32 bindingLocation) const;
 
 protected:
@@ -177,6 +181,7 @@ protected:
                {
                        UNIFORM_TYPE_BUFFER = 0,
                        UNIFORM_TYPE_SAMPLER,
+                       UNIFORM_TYPE_UNMANAGED_SAMPLER,
                        UNIFORM_TYPE_BUFFER_ARRAY,
                        UNIFORM_TYPE_SAMPLER_ARRAY,
 
@@ -217,6 +222,18 @@ protected:
                VkDescriptorImageInfo           descriptor;
        };
 
+       class UnmanagedSamplerUniform : public UniformInfo
+       {
+       public:
+                                                               UnmanagedSamplerUniform  (void) {}
+               virtual                                 ~UnmanagedSamplerUniform (void) {}
+               virtual UniformType             getType                  (void) const { return UNIFORM_TYPE_UNMANAGED_SAMPLER; }
+
+               VkImageView                             imageView;
+               VkSampler                               sampler;
+               VkDescriptorImageInfo   descriptor;
+       };
+
        class BufferArrayUniform : public UniformInfo
        {
        public:
diff --git a/external/vulkancts/modules/vulkan/texture_filtering/CMakeLists.txt b/external/vulkancts/modules/vulkan/texture_filtering/CMakeLists.txt
new file mode 100644 (file)
index 0000000..41a40be
--- /dev/null
@@ -0,0 +1,20 @@
+include_directories(.. ../shaderexecutor)
+
+set(DEQP_VK_TEXTURE_FILTERING_SRCS
+  vktTextureFilteringTests.cpp
+  vktTextureFilteringTests.hpp
+  vktSampleVerifier.cpp
+  vktSampleVerifier.hpp
+  vktTextureFilteringExplicitLodTests.cpp
+  vktTextureFilteringExplicitLodTests.hpp
+)
+
+set(DEQP_VK_TEXTURE_FILTERING_LIBS
+  deqp-vk-common
+  deqp-vk-shaderexecutor
+  tcutil
+  vkutil
+)
+
+add_library(deqp-vk-texture-filtering STATIC ${DEQP_VK_TEXTURE_FILTERING_SRCS})
+target_link_libraries(deqp-vk-texture-filtering ${DEQP_VK_TEXTURE_FITLERING_LIBS})
diff --git a/external/vulkancts/modules/vulkan/texture_filtering/vktSampleVerifier.cpp b/external/vulkancts/modules/vulkan/texture_filtering/vktSampleVerifier.cpp
new file mode 100644 (file)
index 0000000..f5a9886
--- /dev/null
@@ -0,0 +1,1349 @@
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief GPU image sample verification
+ *//*--------------------------------------------------------------------*/
+
+#include "vktSampleVerifier.hpp"
+
+#include "deMath.h"
+#include "tcuFloat.hpp"
+#include "tcuTextureUtil.hpp"
+#include "vkImageUtil.hpp"
+
+#include <fstream>
+#include <sstream>
+
+namespace vkt
+{
+namespace texture_filtering
+{
+
+using namespace vk;
+using namespace tcu;
+
+namespace
+{
+
+bool isEqualRelEpsilon (const float a, const float b, const float epsilon)
+{
+       const float diff = de::abs(a - b);
+
+       const float largest = de::max(de::abs(a), de::abs(b));
+
+       return diff <= largest * epsilon;
+}
+
+template <int Size>
+bool isEqualRelEpsilon (const Vector<float, Size>& a, const Vector<float, Size>& b, const float epsilon)
+{
+       for (deUint8 compNdx = 0; compNdx < Size; ++compNdx)
+       {
+               if (!isEqualRelEpsilon(a[compNdx], b[compNdx], epsilon))
+               {
+                       return false;
+               }
+       }
+
+       return true;
+}
+
+float calcRelEpsilon (VkFormat format, VkFilter filter, VkSamplerMipmapMode mipmapFilter)
+{
+       // fp16 format approximates the minimum precision for internal calculations mandated by spec
+       const float fp16MachineEpsilon = 0.0009765625f;
+
+       // \todo [2016-07-06 collinbaker] Pick the epsilon more
+       // scientifically
+       float relEpsilon = fp16MachineEpsilon;
+
+       if (filter == VK_FILTER_LINEAR)
+       {
+               relEpsilon *= 3.0f;
+       }
+
+       if (mipmapFilter == VK_SAMPLER_MIPMAP_MODE_LINEAR)
+       {
+               relEpsilon *= 2.0f;
+       }
+
+       return relEpsilon;
+}
+
+deInt32 mod (const deInt32 a, const deInt32 n)
+{
+       const deInt32 result = a % n;
+
+       return (result < 0) ? result + n : result;
+}
+
+deInt32 mirror (const deInt32 n)
+{
+       if (n >= 0)
+       {
+               return n;
+       }
+       else
+       {
+               return -(1 + n);
+       }
+}
+
+template <int Size>
+Vector<float, Size> floor (const Vector<float, Size>& v)
+{
+       Vector<float, Size> result;
+
+       for (int compNdx = 0; compNdx < Size; ++compNdx)
+       {
+               result[compNdx] = deFloor(v[compNdx]);
+       }
+
+       return result;
+}
+
+template <int Size>
+Vector<float, Size> ceil (const Vector<float, Size>& v)
+{
+       Vector<float, Size> result;
+
+       for (int compNdx = 0; compNdx < Size; ++compNdx)
+       {
+               result[compNdx] = deCeil(v[compNdx]);
+       }
+
+       return result;
+}
+
+template <int Size>
+Vector<float, Size> abs (const Vector<float, Size>& v)
+{
+       Vector<float, Size> result;
+
+       for (int compNdx = 0; compNdx < Size; ++compNdx)
+       {
+               result[compNdx] = de::abs(v[compNdx]);
+       }
+
+       return result;
+}
+
+Vec2 computeLevelLodBounds (const Vec2& lodBounds, deUint8 level)
+{
+       Vec2 levelLodBounds;
+
+       if (lodBounds[0] <= 0.0f)
+       {
+               levelLodBounds[0] = lodBounds[0];
+       }
+       else
+       {
+               levelLodBounds[0] = de::max(lodBounds[0], (float) level);
+       }
+
+       levelLodBounds[1] = de::min(lodBounds[1], (float) level + 1.0f);
+
+       return levelLodBounds;
+}
+
+float addUlp (float num, deInt32 ulp)
+{
+       // Note: adding positive ulp always moves float away from zero
+
+       tcu::Float32 f(num);
+
+       DE_ASSERT(!f.isNaN() && !f.isInf());
+       DE_ASSERT(num > FLT_MIN * (float) ulp || num < FLT_MIN * (float) ulp);
+
+       deUint32 bits = f.bits();
+       bits += ulp;
+
+       return tcu::Float32(bits).asFloat();
+}
+
+deInt32 wrapTexelCoord (const deInt32 coord,
+                                               const deUint32 size,
+                                               const VkSamplerAddressMode wrap)
+{
+       deInt32 wrappedCoord = 0;
+
+       switch (wrap)
+       {
+               case VK_SAMPLER_ADDRESS_MODE_REPEAT:
+                       wrappedCoord = mod(coord, size);
+                       break;
+               case VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT:
+                       wrappedCoord = (size - 1) - mirror(mod(coord, 2 * size) - size);
+                       break;
+               case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:
+                       wrappedCoord = de::clamp(coord, 0, (deInt32) size - 1);
+                       break;
+               case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER:
+                       wrappedCoord = de::clamp(coord, -1, (deInt32) size);
+                       break;
+               case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE:
+                       wrappedCoord = de::clamp(mirror(coord), 0, (deInt32) size - 1);
+                       break;
+               default:
+                       DE_FATAL("Invalid VkSamplerAddressMode");
+                       break;
+       }
+
+       return wrappedCoord;
+}
+
+} // anonymous
+
+SampleVerifier::SampleVerifier (const ImageViewParameters&                                             imParams,
+                                                               const SamplerParameters&                                                samplerParams,
+                                                               const SampleLookupSettings&                                             sampleLookupSettings,
+                                                               int                                                                                             coordBits,
+                                                               int                                                                                             mipmapBits,
+                                                               const std::vector<tcu::ConstPixelBufferAccess>& pba)
+
+       : m_imParams                            (imParams)
+       , m_samplerParams                       (samplerParams)
+       , m_sampleLookupSettings        (sampleLookupSettings)
+       , m_coordBits                           (coordBits)
+       , m_mipmapBits                          (mipmapBits)
+       , m_pba                                         (pba)
+{
+       if (m_imParams.dim == IMG_DIM_1D)
+       {
+               m_unnormalizedDim = 1;
+       }
+       else if (m_imParams.dim == IMG_DIM_2D || m_imParams.dim == IMG_DIM_CUBE)
+       {
+               m_unnormalizedDim = 2;
+       }
+       else
+       {
+               m_unnormalizedDim = 3;
+       }
+}
+
+bool SampleVerifier::coordOutOfRange (const IVec3& coord, int compNdx, int level) const
+{
+       DE_ASSERT(compNdx >= 0 && compNdx < 3);
+
+       return coord[compNdx] < 0 || coord[compNdx] >= m_pba[level].getSize()[compNdx];
+}
+
+Vec4 SampleVerifier::fetchTexel (const IVec3& coordIn, deUint32 layer, deUint8 level, VkFilter filter) const
+{
+       IVec3 coord = coordIn;
+
+       VkSamplerAddressMode wrappingModes[] =
+       {
+               m_samplerParams.wrappingModeU,
+               m_samplerParams.wrappingModeV,
+               m_samplerParams.wrappingModeW
+       };
+
+       const bool isSrgb = isSrgbFormat(m_imParams.format);
+
+       // Wrapping operations
+
+       if (m_imParams.dim == IMG_DIM_CUBE && filter == VK_FILTER_LINEAR)
+       {
+               const deUint32  arrayLayer = layer / 6;
+               deUint8                 arrayFace  = (deUint8) (layer % 6);
+
+               // Cube map adjacent faces ordered clockwise from top
+
+               // \todo [2016-07-07 collinbaker] Verify these are correct
+               static const deUint8 adjacentFaces[6][4] =
+               {
+                   {3, 5, 2, 4},
+                       {3, 4, 2, 5},
+                       {4, 0, 5, 1},
+                       {5, 0, 4, 1},
+                       {3, 0, 2, 1},
+                       {3, 1, 2, 0}
+               };
+
+               static const deUint8 adjacentEdges[6][4] =
+               {
+                       {1, 3, 1, 1},
+                       {3, 3, 3, 1},
+                       {2, 2, 2, 2},
+                       {0, 0, 0, 0},
+                       {2, 3, 0, 1},
+                       {0, 3, 2, 1}
+               };
+
+               static const deInt8 adjacentEdgeDirs[6][4] =
+               {
+                       {-1, +1, +1, +1},
+                       {+1, +1, -1, +1},
+                       {+1, +1, -1, -1},
+                       {-1, -1, +1, +1},
+                       {+1, +1, +1, +1},
+                       {-1, +1, -1, +1}
+               };
+
+               static const deUint8 edgeComponent[4] = {0, 1, 0, 1};
+
+               static const deUint8 edgeFactors[4][2] =
+               {
+                       {0, 0},
+                       {1, 0},
+                       {0, 1},
+                       {0, 0}
+               };
+
+               if (coordOutOfRange(coord, 0, level) != coordOutOfRange(coord, 1, level))
+               {
+                       // Handle edge
+
+                       deUint8 edgeNdx;
+
+                       if (coord[1] < 0)
+                       {
+                               edgeNdx = 0;
+                       }
+                       else if (coord[0] > 0)
+                       {
+                               edgeNdx = 1;
+                       }
+                       else if (coord[1] > 0)
+                       {
+                               edgeNdx = 2;
+                       }
+                       else
+                       {
+                               edgeNdx = 3;
+                       }
+
+                       const deUint8   adjacentEdgeNdx = adjacentEdges[arrayFace][edgeNdx];
+                       const IVec2             edgeFactor              = IVec2(edgeFactors[adjacentEdgeNdx][0],
+                                                                                                       edgeFactors[adjacentEdgeNdx][1]);
+                       const IVec2             edgeOffset              = edgeFactor * (m_pba[level].getSize().swizzle(0, 1) - IVec2(1));
+
+                       IVec2 newCoord;
+
+                       if (adjacentEdgeDirs[arrayFace][edgeNdx] > 0)
+                       {
+                               newCoord[edgeComponent[adjacentEdgeNdx]] = coord[edgeComponent[edgeNdx]];
+                       }
+                       else
+                       {
+                               newCoord[edgeComponent[adjacentEdgeNdx]] =
+                                       m_pba[level].getSize()[edgeComponent[edgeNdx]] - coord[edgeComponent[edgeNdx]] - 1;
+                       }
+
+                       newCoord[1 - edgeComponent[adjacentEdgeNdx]] = 0;
+                       coord.xy() = newCoord + edgeOffset;
+
+                       arrayFace = adjacentFaces[arrayFace][edgeNdx];
+                       layer = arrayLayer * 6 + arrayFace;
+               }
+               else if (coordOutOfRange(coord, 0, level) && coordOutOfRange(coord, 1, level))
+               {
+                       // Handle corner; corners are numbered clockwise starting
+                       // from top left
+
+                       deUint8 cornerNdx;
+
+                       if (coord[0] < 0 && coord[1] < 0)
+                       {
+                               cornerNdx = 0;
+                       }
+                       else if (coord[0] > 0 && coord[1] < 0)
+                       {
+                               cornerNdx = 1;
+                       }
+                       else if (coord[0] > 0 && coord[1] > 0)
+                       {
+                               cornerNdx = 2;
+                       }
+                       else
+                       {
+                               cornerNdx = 3;
+                       }
+
+                       // Calculate faces and corners thereof adjacent to sampled corner
+
+                       const deUint8 cornerEdges[2] = {cornerNdx, (deUint8) ((cornerNdx + 3) % 4)};
+
+                   const deUint8 faces[3]               = {arrayFace,
+                                                                                       adjacentFaces[arrayFace][cornerEdges[0]],
+                                                                                       adjacentFaces[arrayFace][cornerEdges[1]]};
+
+                       deUint8           faceCorners[3] = {cornerNdx, 0, 0};
+
+                   for (deUint8 edgeNdx = 0; edgeNdx < 2; ++edgeNdx)
+                       {
+                               const deUint8 faceEdge = adjacentEdges[arrayFace][cornerEdges[edgeNdx]];
+
+                               bool isFlipped = (adjacentEdgeDirs[arrayFace][cornerEdges[edgeNdx]]);
+
+                               if ((cornerEdges[edgeNdx] > 1) != (faceEdge > 1))
+                               {
+                                       isFlipped = !isFlipped;
+                               }
+
+                               if (isFlipped)
+                               {
+                                       faceCorners[edgeNdx + 1] = (deUint8) ((faceEdge + 1) % 4);
+                               }
+                               else
+                               {
+                                       faceCorners[edgeNdx + 1] = faceEdge;
+                               }
+                       }
+
+                       // Compute average of corners and return
+
+                       Vec4 result(0.0f);
+
+                       for (deUint8 faceNdx = 0; faceNdx < 3; ++faceNdx)
+                       {
+                               IVec2 cornerFactor;
+
+                               switch (faceCorners[faceNdx])
+                               {
+                                       case 0:
+                                               cornerFactor = IVec2(0, 0);
+                                               break;
+                                       case 1:
+                                               cornerFactor = IVec2(1, 0);
+                                               break;
+                                       case 2:
+                                               cornerFactor = IVec2(1, 1);
+                                               break;
+                                       case 3:
+                                               cornerFactor = IVec2(0, 1);
+                               }
+
+                               const IVec2 cornerCoord = cornerFactor * (m_pba[level].getSize().swizzle(0, 1) - IVec2(1));
+                               const deUint32 cornerLayer = arrayLayer * 6 + faces[faceNdx];
+
+                               if (isSrgb)
+                               {
+                                       result += sRGBToLinear(m_pba[level].getPixel(cornerCoord[0], cornerCoord[1], cornerLayer));
+                               }
+                               else
+                               {
+                                       result += m_pba[level].getPixel(cornerCoord[0], cornerCoord[1], cornerLayer);
+                               }
+                       }
+
+                       result = result / 3.0f;
+
+                       return result;
+               }
+       }
+       else
+       {
+               if (m_imParams.dim == IMG_DIM_CUBE)
+               {
+                       wrappingModes[0] = wrappingModes[1] = wrappingModes[2] = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+               }
+
+               for (deUint8 compNdx = 0; compNdx < 3; ++compNdx)
+               {
+                       const deUint32 size = m_pba[level].getSize()[compNdx];
+
+                       coord[compNdx] = wrapTexelCoord(coord[compNdx], size, wrappingModes[compNdx]);
+               }
+       }
+
+       if (coordOutOfRange(coord, 0, level) ||
+               coordOutOfRange(coord, 1, level) ||
+               coordOutOfRange(coord, 2, level))
+       {
+               switch (m_samplerParams.borderColor)
+               {
+                       case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
+                               return Vec4(0.0f, 0.0f, 0.0f, 0.0f);
+                       case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK:
+                               return Vec4(0.0f, 0.0f, 0.0f, 1.0f);
+                       case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE:
+                               return Vec4(1.0f, 1.0f, 1.0f, 1.0f);
+                       default:
+                               // \\ [2016-07-07 collinbaker] Handle
+                               // VK_BORDER_COLOR_INT_* borders
+                               DE_FATAL("Not implemented");
+                               break;
+               }
+       }
+       else
+       {
+               Vec4 result;
+
+           if (m_imParams.dim == IMG_DIM_1D)
+               {
+                       result = m_pba[level].getPixel(coord[0], layer, 0);
+               }
+               else if (m_imParams.dim == IMG_DIM_2D)
+               {
+                       result = m_pba[level].getPixel(coord[0], coord[1], layer);
+               }
+               else
+               {
+                       result = m_pba[level].getPixel(coord[0], coord[1], coord[2]);
+               }
+
+               // Do sRGB conversion if necessary
+
+               if (isSrgb)
+               {
+                       return sRGBToLinear(result);
+               }
+               else
+               {
+                       return result;
+               }
+       }
+
+       return Vec4(0.0f);
+}
+
+Vec4 SampleVerifier::getFilteredSample1D (const IVec3& texelBase,
+                                                                                 float                 weight,
+                                                                                 deUint32              layer,
+                                                                                 deUint8               level) const
+{
+       Vec4 texels[2];
+
+       for (deUint8 i = 0; i < 2; ++i)
+       {
+               texels[i] = fetchTexel(texelBase + IVec3(i, 0, 0), layer, level, VK_FILTER_LINEAR);
+       }
+
+       return (1.0f - weight) * texels[0] + weight * texels[1];
+}
+
+
+Vec4 SampleVerifier::getFilteredSample2D (const IVec3& texelBase,
+                                                                                 const Vec2&   weights,
+                                                                                 deUint32              layer,
+                                                                                 deUint8               level) const
+{
+       Vec4 texels[4];
+
+       for (deUint8 i = 0; i < 2; ++i)
+       {
+               for (deUint8 j = 0; j < 2; ++j)
+               {
+                       texels[2 * j + i] = fetchTexel(texelBase + IVec3(i, j, 0), layer, level, VK_FILTER_LINEAR);
+               }
+       }
+
+       return (1.0f - weights[0]) * (1.0f - weights[1]) * texels[0]
+               + weights[0] * (1.0f - weights[1]) * texels[1]
+               + (1.0f - weights[0]) * weights[1] * texels[2]
+               + weights[0] * weights[1] * texels[3];
+}
+
+Vec4 SampleVerifier::getFilteredSample3D (const IVec3& texelBase,
+                                                                                 const Vec3&   weights,
+                                                                                 deUint32              layer,
+                                                                                 deUint8               level) const
+{
+       Vec4 texels[8];
+
+       for (deUint8 i = 0; i < 2; ++i)
+       {
+               for (deUint8 j = 0; j < 2; ++j)
+               {
+                       for (deUint8 k = 0; k < 2; ++k)
+                       {
+                               texels[4 * k + 2 * j + i] = fetchTexel(texelBase + IVec3(i, j, k), layer, level, VK_FILTER_LINEAR);
+                       }
+               }
+       }
+
+       return (1.0f - weights[0]) * (1.0f - weights[1]) * (1.0f - weights[2]) * texels[0]
+               + weights[0] * (1.0f - weights[1]) * (1.0f - weights[2]) * texels[1]
+               + (1.0f - weights[0]) * weights[1] * (1.0f - weights[2]) * texels[2]
+               + weights[0] * weights[1] * (1.0f - weights[2]) * texels[3]
+               + (1.0f - weights[0]) * (1.0f - weights[1]) * weights[2] * texels[4]
+               + weights[0] * (1.0f - weights[1]) * weights[2] * texels[5]
+               + (1.0f - weights[0]) * weights[1] * weights[2] * texels[6]
+               + weights[0] * weights[1] * weights[3] * texels[7];
+}
+
+Vec4 SampleVerifier::getFilteredSample (const IVec3&   texelBase,
+                                                                               const Vec3&             weights,
+                                                                               deUint32                layer,
+                                                                               deUint8                 level) const
+{
+       DE_ASSERT(layer < m_imParams.arrayLayers);
+       DE_ASSERT(level < m_imParams.levels);
+
+       if (m_imParams.dim == IMG_DIM_1D)
+       {
+               return getFilteredSample1D(texelBase, weights.x(), layer, level);
+       }
+       else if (m_imParams.dim == IMG_DIM_2D || m_imParams.dim == IMG_DIM_CUBE)
+       {
+               return getFilteredSample2D(texelBase, weights.swizzle(0, 1), layer, level);
+       }
+       else
+       {
+               return getFilteredSample3D(texelBase, weights, layer, level);
+       }
+}
+
+void SampleVerifier::getWeightStepBounds (const Vec3&  unnormalizedCoord,
+                                                                                 IVec3&                weightStepMin,
+                                                                                 IVec3&                weightStepMax,
+                                                                                 IVec3&                texelBase) const
+{
+       DE_ASSERT(m_coordBits < 32);
+       const deUint32 coordSteps = ((deUint32) 1) << m_coordBits;
+
+    for (deUint8 compNdx = 0; compNdx < m_unnormalizedDim; ++compNdx)
+       {
+               const float component = unnormalizedCoord[compNdx];
+               double intPart;
+
+               float weight = (float) modf((double) component - 0.5, &intPart);
+
+               if (weight < 0.0f)
+               {
+                       weight = 1.0f + weight;
+                       intPart -= 1.0;
+               }
+
+               texelBase[compNdx] = (deInt32) intPart;
+
+               weightStepMin[compNdx] = deCeilFloatToInt32 (weight * (float) coordSteps - 1.5f);
+               weightStepMax[compNdx] = deFloorFloatToInt32(weight * (float) coordSteps + 1.5f);
+
+               weightStepMin[compNdx] = de::max(weightStepMin[compNdx], (deInt32) 0);
+               weightStepMax[compNdx] = de::min(weightStepMax[compNdx], (deInt32) coordSteps);
+       }
+}
+
+void SampleVerifier::getMipmapStepBounds (const Vec2&  lodFracBounds,
+                                                                                 deInt32&              stepMin,
+                                                                                 deInt32&              stepMax) const
+{
+       DE_ASSERT(m_mipmapBits < 32);
+       const deUint32 mipmapSteps = ((deUint32) 1) << m_mipmapBits;
+
+       stepMin = deFloorFloatToInt32(lodFracBounds[0] * (float) mipmapSteps);
+       stepMax = deCeilFloatToInt32 (lodFracBounds[1] * (float) mipmapSteps);
+
+       stepMin = de::max(stepMin, (deInt32) 0);
+       stepMax = de::min(stepMax, (deInt32) mipmapSteps);
+}
+
+bool SampleVerifier::verifySampleFiltered (const Vec4&                 result,
+                                                                                  const Vec3&                  unnormalizedCoordHi,
+                                                                                  const Vec3&                  unnormalizedCoordLo,
+                                                                                  deUint32                             layer,
+                                                                                  deUint8                              levelHi,
+                                                                                  const Vec2&                  lodFracBounds,
+                                                                                  VkFilter                             filter,
+                                                                                  VkSamplerMipmapMode  mipmapFilter,
+                                                                                  std::ostream&                report) const
+{
+       DE_ASSERT(layer < m_imParams.arrayLayers);
+       DE_ASSERT(levelHi < m_imParams.levels);
+
+       const float             epsilon    = calcRelEpsilon(m_imParams.format, filter, mipmapFilter);
+
+       const deUint32  coordSteps = ((deUint32) 1) << m_coordBits;
+       const deUint32  lodSteps   = ((deUint32) 1) << m_mipmapBits;
+
+       IVec3                   texelBase[2];
+       IVec3                   weightStepsMin[2];
+       IVec3                   weightStepsMax[2];
+       deInt32                 lodStepsMin;
+       deInt32                 lodStepsMax;
+
+       deUint8                 levels;
+       deUint8                 levelLo;
+
+       if (levelHi == m_imParams.levels - 1 || mipmapFilter == VK_SAMPLER_MIPMAP_MODE_NEAREST)
+       {
+               levels = 1;
+               levelLo = levelHi;
+               mipmapFilter = VK_SAMPLER_MIPMAP_MODE_NEAREST;
+       }
+       else
+       {
+               levels = 2;
+               levelLo = (deUint8) 1 + levelHi;
+       }
+
+       getWeightStepBounds(unnormalizedCoordHi, weightStepsMin[0], weightStepsMax[0], texelBase[0]);
+
+       if (mipmapFilter == VK_SAMPLER_MIPMAP_MODE_LINEAR)
+       {
+               getWeightStepBounds(unnormalizedCoordLo, weightStepsMin[1], weightStepsMax[1], texelBase[1]);
+               getMipmapStepBounds(lodFracBounds, lodStepsMin, lodStepsMax);
+       }
+       else
+       {
+               texelBase[1] = IVec3(0);
+               weightStepsMin[1] = IVec3(0);
+               weightStepsMax[1] = IVec3(0);
+       }
+
+       IVec3 weightSteps[2] = {weightStepsMin[0], weightStepsMin[1]};
+
+       bool done = false;
+
+       while (!done)
+       {
+               report << "Testing at base texel " << texelBase[0] << ", " << texelBase[1] << " with weight steps " << weightSteps[0] << ", " << weightSteps[1] << "\n";
+
+               Vec4 idealSampleHi, idealSampleLo;
+
+               // Get ideal samples at steps at each mipmap level
+
+               if (filter == VK_FILTER_LINEAR)
+               {
+                       Vec3 roundedWeightsHi, roundedWeightsLo;
+
+                       roundedWeightsHi = weightSteps[0].asFloat() / (float) coordSteps;
+                       roundedWeightsLo = weightSteps[1].asFloat() / (float) coordSteps;
+
+                       report << "Computed weights: " << roundedWeightsHi << ", " << roundedWeightsLo << "\n";
+
+                       idealSampleHi = getFilteredSample(texelBase[0], roundedWeightsHi, layer, levelHi);
+
+                       report << "Ideal hi sample: " << idealSampleHi << "\n";
+
+                       if (mipmapFilter == VK_SAMPLER_MIPMAP_MODE_LINEAR)
+                       {
+                               idealSampleLo = getFilteredSample(texelBase[1], roundedWeightsLo, layer, levelLo);
+
+                               report << "Ideal lo sample: " << idealSampleLo << "\n";
+                       }
+               }
+               else
+               {
+                       // \todo [2016-07-14 collinbaker] fix this because this is definitely wrong
+                       idealSampleHi = fetchTexel(floor(unnormalizedCoordHi).cast<deInt32>(), layer, levelHi, VK_FILTER_NEAREST);
+
+                       report << "Ideal hi sample: " << idealSampleHi << "\n";
+
+                       if (mipmapFilter == VK_SAMPLER_MIPMAP_MODE_LINEAR)
+                       {
+                               idealSampleLo = fetchTexel(floor(unnormalizedCoordLo).cast<deInt32>(), layer, levelLo, VK_FILTER_NEAREST);
+
+                               report << "Ideal lo sample: " << idealSampleLo << "\n";
+                       }
+               }
+
+               // Test ideal samples based on mipmap filtering mode
+
+               if (mipmapFilter == VK_SAMPLER_MIPMAP_MODE_LINEAR)
+               {
+                       for (deInt32 lodStep = lodStepsMin; lodStep <= lodStepsMax; ++lodStep)
+                       {
+                               float weight = (float) lodStep / (float) lodSteps;
+
+                               report << "Testing at mipmap weight " << weight << "\n";
+
+                               Vec4 idealSample = weight * idealSampleLo + (1.0f - weight) * idealSampleHi;
+
+                               report << "Ideal sample: " << idealSample << "\n";
+
+                               if (isEqualRelEpsilon(idealSample, result, epsilon))
+                               {
+                                       return true;
+                               }
+                               else
+                               {
+                                       report << "Failed comparison\n";
+                               }
+                       }
+               }
+               else if (filter == VK_FILTER_LINEAR)
+               {
+                       if (isEqualRelEpsilon(idealSampleHi, result, epsilon))
+                       {
+                               return true;
+                       }
+                       else
+                       {
+                               report << "Failed comparison\n";
+                       }
+               }
+               else
+               {
+                       if (idealSampleHi == result)
+                       {
+                               return true;
+                       }
+               }
+
+               // Increment step
+
+               // Represents whether the increment at a position wraps and should "carry" to the next place
+               bool carry = true;
+
+               for (deUint8 levelNdx = 0; levelNdx < levels; ++levelNdx)
+               {
+                       for (deUint8 compNdx = 0; compNdx < 3; ++compNdx)
+                       {
+                               if (carry)
+                               {
+                                       carry = false;
+                                       deInt32& n = weightSteps[levelNdx][compNdx];
+
+                                       if (n++ == weightStepsMax[levelNdx][compNdx])
+                                       {
+                                               n = weightStepsMin[levelNdx][compNdx];
+                                               carry = true;
+                                       }
+                               }
+                               else
+                               {
+                                       break;
+                               }
+                       }
+
+                       if (!carry)
+                       {
+                               break;
+                       }
+               }
+
+               if (carry)
+               {
+                       done = true;
+               }
+       }
+
+       report << "Failed comparison against all possible weights\n\n";
+
+       return false;
+}
+
+bool SampleVerifier::verifySampleUnnormalizedCoords (const SampleArguments&    args,
+                                                                                                        const Vec4&                    result,
+                                                                                                        const Vec3&                    unnormalizedCoord,
+                                                                                                        const Vec3&                    unnormalizedCoordLo,
+                                                                                                        const Vec2&                    lodBounds,
+                                                                                                        deUint8                                level,
+                                                                                                        VkSamplerMipmapMode    mipmapFilter,
+                                                                                                        std::ostream&                  report) const
+{
+       const deUint8 layer = m_imParams.isArrayed ? (deUint8) deRoundEven(args.layer) : 0U;
+
+       const bool canBeMinified = lodBounds[1] > 0.0f;
+       const bool canBeMagnified = lodBounds[0] <= 0.0f;
+
+       if (canBeMagnified)
+       {
+               report << "Trying magnification...\n";
+
+               if (m_samplerParams.magFilter == VK_FILTER_NEAREST)
+               {
+                       report << "Testing against nearest texel at " << floor(unnormalizedCoord).cast<deInt32>() << "\n";
+
+                       const Vec4 ideal = fetchTexel(floor(unnormalizedCoord).cast<deInt32>(), layer, level, VK_FILTER_NEAREST);
+
+                       if (result == ideal)
+                   {
+                               return true;
+                       }
+                       else
+                       {
+                               report << "Failed against " << ideal << "\n";
+                       }
+               }
+               else
+               {
+                       if  (verifySampleFiltered(result, unnormalizedCoord, Vec3(0.0f), layer, level, Vec2(0.0f, 0.0f), VK_FILTER_LINEAR, VK_SAMPLER_MIPMAP_MODE_NEAREST, report))
+                               return true;
+               }
+       }
+
+       if (canBeMinified)
+       {
+               report << "Trying minification...\n";
+
+               if (mipmapFilter == VK_SAMPLER_MIPMAP_MODE_LINEAR)
+               {
+                       const Vec2 lodFracBounds = lodBounds - Vec2(level);
+
+                       if (verifySampleFiltered(result, unnormalizedCoord, unnormalizedCoordLo, layer, level, lodFracBounds, m_samplerParams.minFilter, VK_SAMPLER_MIPMAP_MODE_LINEAR, report))
+                               return true;
+               }
+               else if (m_samplerParams.minFilter == VK_FILTER_LINEAR)
+               {
+                   if (verifySampleFiltered(result, unnormalizedCoord, Vec3(0.0f), layer, level, Vec2(0.0f, 0.0f), VK_FILTER_LINEAR, VK_SAMPLER_MIPMAP_MODE_NEAREST, report))
+                               return true;
+               }
+               else
+               {
+                       report << "Testing against nearest texel at " << floor(unnormalizedCoord).cast<deInt32>() << "\n";
+
+                       Vec4 ideal = fetchTexel(floor(unnormalizedCoord).cast<deInt32>(), layer, level, VK_FILTER_NEAREST);
+
+                       if (result == ideal)
+                   {
+                               return true;
+                       }
+                       else
+                       {
+                               report << "Failed against " << ideal << "\n";
+                       }
+               }
+       }
+
+       return false;
+}
+
+bool SampleVerifier::verifySampleMipmapLevel (const SampleArguments&   args,
+                                                                                         const Vec4&                           result,
+                                                                                         const Vec4&                           coord,
+                                                                                         const Vec2&                           lodBounds,
+                                                                                         deUint8                                       level,
+                                                                                         std::ostream&                         report) const
+{
+       DE_ASSERT(level < m_imParams.levels);
+
+       VkSamplerMipmapMode mipmapFilter = m_samplerParams.mipmapFilter;
+
+       if (level == m_imParams.levels - 1)
+       {
+               mipmapFilter = VK_SAMPLER_MIPMAP_MODE_NEAREST;
+       }
+
+       Vector<double, 3> unnormalizedCoordHiDbl, unnormalizedCoordLoDbl;
+
+       unnormalizedCoordHiDbl = coord.cast<double>().swizzle(0, 1, 2) * m_pba[level].getSize().cast<double>();
+
+       if (mipmapFilter == VK_SAMPLER_MIPMAP_MODE_LINEAR)
+       {
+               unnormalizedCoordLoDbl = coord.cast<double>().swizzle(0, 1, 2) * m_pba[level + 1].getSize().cast<double>();
+       }
+
+       // Check if result(s) will be rounded
+
+       bool hiIsRounded[3] = {false};
+       bool loIsRounded[3] = {false};
+
+       for (deUint8 compNdx = 0; compNdx < 3; ++compNdx)
+       {
+               hiIsRounded[compNdx] = ((double) (float) unnormalizedCoordHiDbl[compNdx]) != unnormalizedCoordHiDbl[compNdx];
+
+               if (mipmapFilter == VK_SAMPLER_MIPMAP_MODE_LINEAR)
+               {
+                       loIsRounded[compNdx] = ((double) (float) unnormalizedCoordLoDbl[compNdx]) != unnormalizedCoordLoDbl[compNdx];
+               }
+       }
+
+       const deInt32 ulpEpsilon        = (deInt32) (2.0e-5f / FLT_EPSILON);
+       const deInt32 ulpOffsets[3] = {0, -ulpEpsilon, ulpEpsilon};
+
+       deUint8 roundTypesHi[3] = {0, 0, 0};
+       deUint8 roundTypesLo[3] = {0, 0, 0};
+
+       bool done = false;
+
+       // Take into account different possible rounding modes by offsetting rounded result by ULPs
+       // \todo [2016-07-15 collinbaker] This is not 100% correct; should simulate floating point arithmetic with possible rounding modes
+    while (!done)
+       {
+               Vec3 unnormalizedCoordHi;
+               Vec3 unnormalizedCoordLo;
+
+               for (deUint8 compNdx = 0; compNdx < 3; ++compNdx)
+               {
+                       float comp = coord[compNdx];
+                       float compHi;
+                       float compLo;
+
+                       if (roundTypesHi[compNdx] != 0 && comp > FLT_MIN * (float) ulpEpsilon)
+                       {
+                               compHi = addUlp(comp, ulpOffsets[roundTypesHi[compNdx]]);
+                       }
+                       else
+                       {
+                               compHi = comp;
+                       }
+
+                       if (roundTypesLo[compNdx] != 0 && comp > FLT_MIN * (float) ulpEpsilon)
+                       {
+                               compLo = addUlp(comp, ulpOffsets[roundTypesLo[compNdx]]);
+                       }
+                       else
+                       {
+                               compLo = comp;
+                       }
+
+                       unnormalizedCoordHi[compNdx] = compHi * (float) m_pba[level].getSize()[compNdx];
+
+                       if (mipmapFilter == VK_SAMPLER_MIPMAP_MODE_LINEAR)
+                       {
+                           unnormalizedCoordLo[compNdx] = compLo * (float) m_pba[level + 1].getSize()[compNdx];
+                       }
+               }
+
+               report << "Testing at " << unnormalizedCoordHi << ", " << unnormalizedCoordLo << "\n";
+
+               if (verifySampleUnnormalizedCoords(args, result, unnormalizedCoordHi, unnormalizedCoordLo, lodBounds, level, mipmapFilter, report))
+                       return true;
+
+               // Increment rounding types
+
+               bool carry = true;
+
+               for (deUint8 compNdx = 0; compNdx < 3; ++compNdx)
+               {
+                       if (hiIsRounded[compNdx])
+                       {
+                               if (carry)
+                               {
+                                       if (roundTypesHi[compNdx] == 2)
+                                       {
+                                               roundTypesHi[compNdx] = 0;
+                                       }
+                                       else
+                                       {
+                                               roundTypesHi[compNdx]++;
+                                               carry = false;
+                                       }
+                               }
+                               else
+                               {
+                                       break;
+                               }
+                       }
+               }
+
+               for (deUint8 compNdx = 0; compNdx < 3; ++compNdx)
+               {
+                       if (loIsRounded[compNdx])
+                       {
+                               if (carry)
+                               {
+                                       if (roundTypesLo[compNdx] == 2)
+                                       {
+                                               roundTypesLo[compNdx] = 0;
+                                       }
+                                       else
+                                       {
+                                               roundTypesLo[compNdx]++;
+                                               carry = false;
+                                       }
+                               }
+                               else
+                               {
+                                       break;
+                               }
+                       }
+               }
+
+               if (carry)
+               {
+                       done = true;
+               }
+       }
+
+       return false;
+}
+
+bool SampleVerifier::verifySampleCubemapFace (const SampleArguments&   args,
+                                                                                         const Vec4&                           result,
+                                                                                         const Vec4&                           coord,
+                                                                                         const Vec4&                           dPdx,
+                                                                                         const Vec4&                           dPdy,
+                                                                                         deUint8                                       face,
+                                                                                         std::ostream&                         report) const
+{
+       Vec2 lodBounds;
+
+       if (m_sampleLookupSettings.lookupLodMode == LOOKUP_LOD_MODE_DERIVATIVES)
+       {
+               const Vec3 mx = abs(dPdx.swizzle(0, 1, 2)) * m_imParams.size.asFloat();
+               const Vec3 my = abs(dPdy.swizzle(0, 1, 2)) * m_imParams.size.asFloat();
+
+               Vec2 scaleXBounds;
+               Vec2 scaleYBounds;
+
+               scaleXBounds[0] = de::max(de::abs(mx[0]), de::max(de::abs(mx[1]), de::abs(mx[2])));
+               scaleYBounds[0] = de::max(de::abs(my[0]), de::max(de::abs(my[1]), de::abs(my[2])));
+
+               scaleXBounds[1] = de::abs(mx[0]) + de::abs(mx[1]) + de::abs(mx[2]);
+               scaleYBounds[1] = de::abs(my[0]) + de::abs(my[1]) + de::abs(my[2]);
+
+               Vec2 scaleMaxBounds;
+
+               for (deUint8 compNdx = 0; compNdx < 2; ++compNdx)
+               {
+                       scaleMaxBounds[compNdx] = de::max(scaleXBounds[compNdx], scaleYBounds[compNdx]);
+               }
+
+               float lodBias = m_samplerParams.lodBias;
+
+               if (m_sampleLookupSettings.hasLodBias)
+                       lodBias += args.lodBias;
+
+               for (deUint8 compNdx = 0; compNdx < 2; ++compNdx)
+               {
+                       lodBounds[compNdx] = deFloatLog2(scaleMaxBounds[compNdx]);
+                       lodBounds[compNdx] += lodBias;
+                       lodBounds[compNdx] = de::clamp(lodBounds[compNdx], m_samplerParams.minLod, m_samplerParams.maxLod);
+               }
+       }
+       else
+       {
+               lodBounds[0] = lodBounds[1] = args.lod;
+       }
+
+       DE_ASSERT(lodBounds[0] <= lodBounds[1]);
+
+    const float q = (float) (m_imParams.levels - 1);
+
+       if (m_samplerParams.mipmapFilter == VK_SAMPLER_MIPMAP_MODE_NEAREST)
+       {
+               UVec2 levelBounds;
+
+           if (lodBounds[0] <= 0.5f)
+               {
+                       levelBounds[0] = 0;
+               }
+               else if (lodBounds[0] < q + 0.5f)
+               {
+                       levelBounds[0] = deCeilFloatToInt32(lodBounds[0] + 0.5f) - 1;
+               }
+               else
+               {
+                       levelBounds[0] = deRoundFloatToInt32(q);
+               }
+
+               if (lodBounds[1] < 0.5f)
+               {
+                       levelBounds[1] = 0;
+               }
+               else if (lodBounds[1] < q + 0.5f)
+               {
+                       levelBounds[1] = deFloorFloatToInt32(lodBounds[1] + 0.5f);
+               }
+               else
+               {
+                       levelBounds[1] = deRoundFloatToInt32(q);
+               }
+
+               for (deUint8 level = (deUint8) levelBounds[0]; level <= (deUint8) levelBounds[1]; ++level)
+               {
+                       const Vec2 levelLodBounds = computeLevelLodBounds(lodBounds, level);
+
+                       if (verifySampleMipmapLevel(args, result, coord, levelLodBounds, level, report))
+                       {
+                               return true;
+                       }
+               }
+       }
+       else
+       {
+               UVec2 levelBounds;
+
+               for (deUint8 compNdx = 0; compNdx < 2; ++compNdx)
+               {
+                       if (lodBounds[compNdx] >= q)
+                       {
+                               levelBounds[compNdx] = deRoundFloatToInt32(q);
+                       }
+                       else
+                       {
+                               levelBounds[compNdx] = lodBounds[compNdx] < 0.0f ? 0 : deFloorFloatToInt32(lodBounds[compNdx]);
+                       }
+               }
+
+               for (deUint8 level = (deUint8) levelBounds[0]; level <= (deUint8) levelBounds[1]; ++level)
+               {
+                       const Vec2 levelLodBounds = computeLevelLodBounds(lodBounds, level);
+
+                       if (verifySampleMipmapLevel(args, result, coord, levelLodBounds, level, report))
+                       {
+                               return true;
+                       }
+               }
+       }
+
+       return false;
+}
+
+bool SampleVerifier::verifySampleImpl (const SampleArguments&  args,
+                                                                          const Vec4&                          result,
+                                                                          std::ostream&                        report) const
+{
+       // \todo [2016-07-11 collinbaker] Handle depth and stencil formats
+       // \todo [2016-07-06 collinbaker] Handle dRef
+       DE_ASSERT(m_samplerParams.isCompare == false);
+
+       Vec4 coord = args.coord;
+       deUint8 coordSize = 0;
+
+       if (m_imParams.dim == IMG_DIM_1D)
+       {
+               coordSize = 1;
+       }
+       else if (m_imParams.dim == IMG_DIM_2D)
+       {
+               coordSize = 2;
+       }
+       else if (m_imParams.dim == IMG_DIM_3D || m_imParams.dim == IMG_DIM_CUBE)
+       {
+               coordSize = 3;
+       }
+
+       // 15.6.1 Project operation
+
+       if (m_sampleLookupSettings.isProjective)
+       {
+               DE_ASSERT(args.coord[coordSize] != 0.0f);
+               const float proj = coord[coordSize];
+
+               coord = coord / proj;
+       }
+
+       const Vec4 dPdx = (m_sampleLookupSettings.lookupLodMode == LOOKUP_LOD_MODE_DERIVATIVES) ? args.dPdx : Vec4(0);
+       const Vec4 dPdy = (m_sampleLookupSettings.lookupLodMode == LOOKUP_LOD_MODE_DERIVATIVES) ? args.dPdy : Vec4(0);
+
+       // 15.6.3 Cube Map Face Selection and Transformations
+
+       if (m_imParams.dim == IMG_DIM_CUBE)
+       {
+               const Vec3 r = coord.swizzle(0, 1, 2);
+               const Vec3 drdx = dPdx.swizzle(0, 1, 2);
+               const Vec3 drdy = dPdy.swizzle(0, 1, 2);
+
+               BVec3 isMajor(false);
+               float rMax = de::abs(r[0]);
+
+               for (deUint8 compNdx = 1; compNdx < 3; ++compNdx)
+               {
+                       rMax = de::max(rMax, de::abs(r[compNdx]));
+               }
+
+               for (deUint8 compNdx = 0; compNdx < 3; ++compNdx)
+               {
+                       if (de::abs(r[compNdx]) == rMax)
+                       {
+                               isMajor[compNdx] = true;
+                       }
+               }
+
+               DE_ASSERT(isMajor[0] || isMajor[1] || isMajor[2]);
+
+               // We must test every possible disambiguation order
+
+               for (deUint8 i = 0; i < 3; ++i)
+               {
+                   if (!isMajor[i])
+                       {
+                               continue;
+                       }
+
+                       const deUint8 faceNdx = (deUint8) (2U * i + (r[i] < 0.0f ? 1U : 0U));
+
+                       const deUint8 compMap[6][3] =
+                       {
+                               {2, 1, 0},
+                               {2, 1, 0},
+                               {0, 2, 1},
+                               {0, 2, 1},
+                               {0, 1, 2},
+                               {0, 1, 2}
+                       };
+
+                       const deInt8 signMap[6][3] =
+                       {
+                               {-1, -1, +1},
+                               {+1, -1, -1},
+                               {+1, +1, +1},
+                               {+1, -1, -1},
+                               {+1, -1, +1},
+                               {-1, -1, -1}
+                       };
+
+                       Vec3 coordC;
+                       Vec3 dPcdx;
+                       Vec3 dPcdy;
+
+                       for (deUint8 compNdx = 0; compNdx < 3; ++compNdx)
+                       {
+                               const deUint8   mappedComp = compMap[faceNdx][compNdx];
+                               const deInt8    mappedSign = signMap[faceNdx][compNdx];
+
+                               coordC[compNdx] = r[mappedComp]         * mappedSign;
+                               dPcdx[compNdx]  = drdx[mappedComp]      * mappedSign;
+                               dPcdy[compNdx]  = drdy[mappedComp]      * mappedSign;
+                       }
+
+                       coordC[2] = de::abs(coordC[2]);
+
+                       Vec4 coordFace;
+                       Vec4 dPdxFace;
+                       Vec4 dPdyFace;
+
+                       for (deUint8 compNdx = 0; compNdx < 2; ++compNdx)
+                       {
+                               coordFace[compNdx] = 0.5f * coordC[compNdx] / de::abs(coordC[2]) + 0.5f;
+
+                               dPdxFace[compNdx]  = 0.5f * (de::abs(coordC[2]) * dPcdx[compNdx] - coordC[compNdx] * dPcdx[2]) / (coordC[2] * coordC[2]);
+                               dPdyFace[compNdx]  = 0.5f * (de::abs(coordC[2]) * dPcdy[compNdx] - coordC[compNdx] * dPcdy[2]) / (coordC[2] * coordC[2]);
+                       }
+
+                       for (deUint8 compNdx = 2; compNdx < 4; ++compNdx)
+                       {
+                               coordFace[compNdx] = dPdxFace[compNdx] = dPdyFace[compNdx] = 0.0f;
+                       }
+
+                       if (verifySampleCubemapFace(args, result, coordFace, dPdxFace, dPdyFace, faceNdx, report))
+                               return true;
+               }
+
+               return false;
+       }
+       else
+       {
+               return verifySampleCubemapFace(args, result, coord, dPdx, dPdy, 0, report);
+       }
+}
+
+bool SampleVerifier::verifySampleReport (const SampleArguments&        args,
+                                                                                const Vec4&                    result,
+                                                                                std::string&                   report) const
+{
+       std::ostringstream reportStream;
+
+       const bool isValid = verifySampleImpl(args, result, reportStream);
+
+       report = reportStream.str();
+
+    return isValid;
+}
+
+bool SampleVerifier::verifySample (const SampleArguments&      args,
+                                                                  const Vec4&                          result) const
+{
+       // Create unopened ofstream to simulate "null" ostream
+       std::ofstream nullStream;
+
+       return verifySampleImpl(args, result, nullStream);
+}
+
+} // texture_filtering
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/texture_filtering/vktSampleVerifier.hpp b/external/vulkancts/modules/vulkan/texture_filtering/vktSampleVerifier.hpp
new file mode 100644 (file)
index 0000000..28981d6
--- /dev/null
@@ -0,0 +1,238 @@
+#ifndef _VKTSAMPLEVERIFIER_HPP
+#define _VKTSAMPLEVERIFIER_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief GPU image sample verification
+ *//*--------------------------------------------------------------------*/
+
+#include "vkDefs.hpp"
+
+#include "deUniquePtr.hpp"
+
+#include "tcuTexture.hpp"
+#include "tcuVector.hpp"
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+namespace vkt
+{
+namespace texture_filtering
+{
+
+struct SampleArguments
+{
+       tcu::Vec4       coord;
+       tcu::Vec4       dPdx;
+       tcu::Vec4       dPdy;
+       float           layer;
+       float           lod;
+       float           lodBias;
+       float           dRef;
+};
+
+enum LookupLodMode
+{
+       LOOKUP_LOD_MODE_DERIVATIVES = 0,
+       LOOKUP_LOD_MODE_LOD,
+
+       LOOKUP_LOD_MODE_LAST
+};
+
+struct SampleLookupSettings
+{
+       LookupLodMode   lookupLodMode;
+       bool                    hasLodBias;
+       bool                    isProjective;
+};
+
+enum WrappingMode
+{
+       WRAPPING_MODE_REPEAT = 0,
+       WRAPPING_MODE_MIRRORED_REPEAT,
+       WRAPPING_MODE_CLAMP_TO_EDGE,
+       WRAPPING_MODE_CLAMP_TO_BORDER,
+       WRAPPING_MODE_MIRROR_CLAMP_TO_EDGE,
+
+       WRAPPING_MODE_LAST
+};
+
+struct SamplerParameters
+{
+       vk::VkFilter                            magFilter;
+       vk::VkFilter                            minFilter;
+       vk::VkSamplerMipmapMode         mipmapFilter;
+
+       vk::VkSamplerAddressMode        wrappingModeU;
+       vk::VkSamplerAddressMode        wrappingModeV;
+       vk::VkSamplerAddressMode        wrappingModeW;
+
+       vk::VkBorderColor                       borderColor;
+
+       float                                           lodBias;
+       float                                           minLod;
+       float                                           maxLod;
+
+       bool                                            isUnnormalized;
+       bool                                            isCompare;
+};
+
+enum ImgDim
+{
+       IMG_DIM_INVALID = 0,
+       IMG_DIM_1D,
+       IMG_DIM_2D,
+       IMG_DIM_3D,
+       IMG_DIM_CUBE,
+
+       IMG_DIM_LAST
+};
+
+struct ImageViewParameters
+{
+       ImgDim                  dim;
+       vk::VkFormat    format;
+       tcu::IVec3              size;
+       deUint8                 levels;
+
+       bool                    isArrayed;
+       deUint32                arrayLayers;
+};
+
+class SampleVerifier
+{
+public:
+       SampleVerifier                                          (const ImageViewParameters&                                                     imParams,
+                                                                                const SamplerParameters&                                                       samplerParams,
+                                                                                const SampleLookupSettings&                                            sampleLookupSettings,
+                                                                                int                                                                                            coordBits,
+                                                                                int                                                                                            mipmapBits,
+                                                                                const std::vector<tcu::ConstPixelBufferAccess>&        pba);
+
+       bool verifySample                                       (const SampleArguments&                                                         args,
+                                                                                const tcu::Vec4&                                                                       result) const;
+
+       bool verifySampleReport                         (const SampleArguments&                                                         args,
+                                                                                const tcu::Vec4&                                                                       result,
+                                                                                std::string&                                                                           report) const;
+
+private:
+       bool verifySampleMipmapLinear           (tcu::Vec4                                                                                      result,
+                                                                                tcu::Vec4                                                                                      sampleHi,
+                                                                                tcu::Vec4                                                                                      sampleLo,
+                                                                                deInt32                                                                                        lodStepMin,
+                                                                                deInt32                                                                                        lodStepMax,
+                                                                                deUint32                                                                                       layer,
+                                                                                deUint8                                                                                        levelHi) const;
+
+       bool verifySampleFiltered                       (const tcu::Vec4&                                                                       result,
+                                                                                const tcu::Vec3&                                                                       unnormalizedCoordHi,
+                                                                                const tcu::Vec3&                                                                       unnormalizedCoordLo,
+                                                                                deUint32                                                                                       layer,
+                                                                                deUint8                                                                                        levelHi,
+                                                                                const tcu::Vec2&                                                                       lodFracBounds,
+                                                                                vk::VkFilter                                                                           filter,
+                                                                                vk::VkSamplerMipmapMode                                                        mipmapFilter,
+                                                                                std::ostream&                                                                          report) const;
+
+       bool verifySampleUnnormalizedCoords (const SampleArguments&                                                             args,
+                                                                                const tcu::Vec4&                                                                       result,
+                                                                                const tcu::Vec3&                                                                       unnormalizedCoord,
+                                                                                const tcu::Vec3&                                                                       unnormalizedCoordLo,
+                                                                                const tcu::Vec2&                                                                       lodBounds,
+                                                                                deUint8                                                                                        level,
+                                                                                vk::VkSamplerMipmapMode                                                        mipmapFilter,
+                                                                                std::ostream&                                                                          report) const;
+
+       bool verifySampleMipmapLevel            (const SampleArguments&                                                         args,
+                                                                                const tcu::Vec4&                                                                       result,
+                                                                                const tcu::Vec4&                                                                       coord,
+                                                                                const tcu::Vec2&                                                                       lodFracBounds,
+                                                                                deUint8                                                                                        level,
+                                                                                std::ostream&                                                                          report) const;
+
+       bool verifySampleCubemapFace            (const SampleArguments&                                                         args,
+                                                                                const tcu::Vec4&                                                                       result,
+                                                                                const tcu::Vec4&                                                                       coord,
+                                                                                const tcu::Vec4&                                                                       dPdx,
+                                                                                const tcu::Vec4&                                                                       dPdy,
+                                                                                deUint8                                                                                        face,
+                                                                                std::ostream&                                                                          report) const;
+
+       bool verifySampleImpl                           (const SampleArguments&                                                         args,
+                                                                                const tcu::Vec4&                                                                       result,
+                                                                                std::ostream&                                                                          report) const;
+
+       bool coordOutOfRange                            (const tcu::IVec3&                                                                      coord,
+                                                                                int                                                                                            compNdx,
+                                                                                int                                                                                            level) const;
+
+       tcu::Vec4 fetchTexel                            (const tcu::IVec3&                                                                      coordIn,
+                                                                                deUint32                                                                                       layer,
+                                                                                deUint8                                                                                        level,
+                                                                                vk::VkFilter                                                                           filter) const;
+
+       tcu::Vec4 getFilteredSample1D           (const tcu::IVec3&                                                                      texelBase,
+                                                                                float                                                                                          weight,
+                                                                                deUint32                                                                                       layer,
+                                                                                deUint8                                                                                        level) const;
+
+       tcu::Vec4 getFilteredSample2D           (const tcu::IVec3&                                                                      texelBase,
+                                                                                const tcu::Vec2&                                                                       weights,
+                                                                                deUint32                                                                                       layer,
+                                                                                deUint8                                                                                        level) const;
+
+       tcu::Vec4 getFilteredSample3D           (const tcu::IVec3&                                                                      texelBase,
+                                                                                const tcu::Vec3&                                                                       weights,
+                                                                                deUint32                                                                                       layer,
+                                                                                deUint8                                                                                        level) const;
+
+       tcu::Vec4 getFilteredSample                     (const tcu::IVec3&                                                                      texelBase,
+                                                                                const tcu::Vec3&                                                                       weights,
+                                                                                deUint32                                                                                       layer,
+                                                                                deUint8                                                                                        level) const;
+
+       void getWeightStepBounds                        (const tcu::Vec3&                                                                       unnormalizedCoord,
+                                                                                tcu::IVec3&                                                                            weightStepMin,
+                                                                                tcu::IVec3&                                                                            weightStepMax,
+                                                                                tcu::IVec3&                                                                            texelBase) const;
+
+       void getMipmapStepBounds                        (const tcu::Vec2&                                                                       lodFracBounds,
+                                                                                deInt32&                                                                                       stepMin,
+                                                                                deInt32&                                                                                       stepMax) const;
+
+       const ImageViewParameters&                                              m_imParams;
+       const SamplerParameters&                                                m_samplerParams;
+       const SampleLookupSettings&                                             m_sampleLookupSettings;
+
+    int                                                                                                m_coordBits;
+       int                                                                                             m_mipmapBits;
+
+       int                                                                                             m_unnormalizedDim;
+
+       const std::vector<tcu::ConstPixelBufferAccess>& m_pba;
+};
+
+} // texture_filtering
+} // vkt
+
+#endif // _VKTSAMPLEVERIFIER_HPP
diff --git a/external/vulkancts/modules/vulkan/texture_filtering/vktTextureFilteringExplicitLodTests.cpp b/external/vulkancts/modules/vulkan/texture_filtering/vktTextureFilteringExplicitLodTests.cpp
new file mode 100644 (file)
index 0000000..e663f10
--- /dev/null
@@ -0,0 +1,1360 @@
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Texture filtering tests with explicit LOD instructions
+ *//*--------------------------------------------------------------------*/
+
+#include "vktTextureFilteringExplicitLodTests.hpp"
+
+#include "vkDefs.hpp"
+
+#include "vktSampleVerifier.hpp"
+#include "vktShaderExecutor.hpp"
+#include "vktTestCaseUtil.hpp"
+
+#include "vkDeviceUtil.hpp"
+#include "vkImageUtil.hpp"
+#include "vkPlatform.hpp"
+#include "vkRef.hpp"
+#include "vkRefUtil.hpp"
+#include "vkStrUtil.hpp"
+
+#include "tcuTexLookupVerifier.hpp"
+#include "tcuTestLog.hpp"
+#include "tcuTexture.hpp"
+#include "tcuTextureUtil.hpp"
+#include "tcuVector.hpp"
+
+#include "deClock.h"
+#include "deMath.h"
+#include "deUniquePtr.hpp"
+
+#include <sstream>
+#include <string>
+#include <vector>
+
+namespace vkt
+{
+namespace texture_filtering
+{
+
+using namespace tcu;
+using namespace vk;
+using std::string;
+
+namespace
+{
+
+using namespace shaderexecutor;
+
+string genSamplerDeclaration(const ImageViewParameters& imParams,
+                                                        const SamplerParameters&       samplerParams)
+{
+       string result = "sampler";
+
+       switch (imParams.dim)
+       {
+               case IMG_DIM_1D:
+                       result += "1D";
+                       break;
+               case IMG_DIM_2D:
+                       result += "2D";
+                       break;
+               case IMG_DIM_3D:
+                       result += "3D";
+                       break;
+               case IMG_DIM_CUBE:
+                       result += "Cube";
+                       break;
+               default:
+                       break;
+       }
+
+       if (imParams.isArrayed)
+       {
+               result += "Array";
+       }
+
+       if (samplerParams.isCompare)
+       {
+               result += "Shadow";
+       }
+
+       return result;
+}
+
+string genLookupCode(const ImageViewParameters&                imParams,
+                                        const SamplerParameters&               samplerParams,
+                                        const SampleLookupSettings&    lookupSettings)
+{
+       int dim;
+
+       switch (imParams.dim)
+       {
+               case IMG_DIM_1D:
+                       dim = 1;
+                       break;
+               case IMG_DIM_2D:
+                       dim = 2;
+                       break;
+               case IMG_DIM_3D:
+                       dim = 3;
+                       break;
+               case IMG_DIM_CUBE:
+                       dim = 3;
+                       break;
+               default:
+                       dim = 0;
+                       break;
+       }
+
+       DE_ASSERT(dim >= 1 && dim <= 3);
+
+       int numCoordComp = dim;
+
+       if (lookupSettings.isProjective)
+       {
+               ++numCoordComp;
+       }
+
+       int numArgComp = numCoordComp;
+       bool hasSeparateCompare = false;
+
+       if (imParams.isArrayed)
+       {
+               DE_ASSERT(!lookupSettings.isProjective && "Can't do a projective lookup on an arrayed image!");
+
+               ++numArgComp;
+       }
+
+       if (samplerParams.isCompare && numCoordComp == 4)
+       {
+               hasSeparateCompare = true;
+       }
+       else if (samplerParams.isCompare)
+       {
+               ++numArgComp;
+       }
+
+       // Build coordinate input to texture*() function
+
+       string arg      = "vec";
+       arg += (char) (numArgComp + '0');
+       arg += "(vec";
+       arg += (char) (numCoordComp + '0');
+       arg += "(coord)";
+
+    int numZero = numArgComp - numCoordComp;
+
+       if (imParams.isArrayed)
+       {
+               arg += ", layer";
+               --numZero;
+       }
+
+       if (samplerParams.isCompare && !hasSeparateCompare)
+       {
+               arg += ", dRef";
+               --numZero;
+       }
+
+       for (int ndx = 0; ndx < numZero; ++ndx)
+       {
+               arg += ", 0.0";
+       }
+
+       arg += ")";
+
+       // Build call to texture*() function
+
+       string code;
+
+       code += "result = texture";
+
+       if (lookupSettings.isProjective)
+       {
+               code += "Proj";
+       }
+
+       if (lookupSettings.lookupLodMode == LOOKUP_LOD_MODE_DERIVATIVES)
+       {
+               code += "Grad";
+       }
+       else if (lookupSettings.lookupLodMode == LOOKUP_LOD_MODE_LOD)
+       {
+               code += "Lod";
+       }
+
+       code += "(testSampler, ";
+       code += arg;
+
+       if (samplerParams.isCompare && hasSeparateCompare)
+       {
+               code += ", dRef";
+       }
+
+       if (lookupSettings.lookupLodMode == LOOKUP_LOD_MODE_DERIVATIVES)
+       {
+               code += ", dPdx, dPdy";
+       }
+       else if (lookupSettings.lookupLodMode == LOOKUP_LOD_MODE_LOD)
+       {
+               code += ", lod";
+       }
+
+       code += ");";
+
+       return code;
+}
+
+void initializeImage(Context& ctx, VkImage im, const ConstPixelBufferAccess* pba, ImageViewParameters imParams)
+{
+       const DeviceInterface& vkd = ctx.getDeviceInterface();
+       const VkDevice dev = ctx.getDevice();
+       const deUint32 uqfi = ctx.getUniversalQueueFamilyIndex();
+
+       const VkDeviceSize bufSize =
+               getPixelSize(mapVkFormat(imParams.format))
+               * imParams.arrayLayers
+               * imParams.size[0]
+               * imParams.size[1]
+               * imParams.size[2]
+               * 2;
+
+    const VkBufferCreateInfo bufCreateInfo =
+       {
+               VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,   // sType
+               DE_NULL,                                                                // pNext
+               0,                                                                              // flags
+               bufSize,                                                                // size
+               VK_BUFFER_USAGE_TRANSFER_SRC_BIT,               // usage
+               VK_SHARING_MODE_EXCLUSIVE,                              // sharingMode
+               1,                                                                              // queueFamilyIndexCount
+               &uqfi                                                                   // pQueueFamilyIndices
+       };
+
+       Unique<VkBuffer> buf(createBuffer(vkd, dev, &bufCreateInfo));
+
+       VkMemoryRequirements bufMemReq;
+       vkd.getBufferMemoryRequirements(dev, buf.get(), &bufMemReq);
+
+       de::UniquePtr<Allocation> bufMem(ctx.getDefaultAllocator().allocate(bufMemReq, MemoryRequirement::HostVisible));
+       VK_CHECK(vkd.bindBufferMemory(dev, buf.get(), bufMem->getMemory(), bufMem->getOffset()));
+
+       const VkCommandPoolCreateInfo copyPoolCreateInfo =
+       {
+               VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
+               DE_NULL,
+               VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,
+               uqfi
+       };
+
+       Unique<VkCommandPool> copyPool(createCommandPool(vkd, dev, &copyPoolCreateInfo));
+
+       const VkCommandBufferAllocateInfo copyBufferCreateInfo =
+       {
+               VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
+               DE_NULL,
+               copyPool.get(),
+               VK_COMMAND_BUFFER_LEVEL_PRIMARY,
+               1
+       };
+
+       Unique<VkCommandBuffer> copyBuffer(allocateCommandBuffer(vkd, dev, &copyBufferCreateInfo));
+
+       std::vector<VkBufferImageCopy> copyRegions;
+
+       deUint8* const bufMapPtr = reinterpret_cast<deUint8*>(bufMem->getHostPtr());
+       deUint8* bufCurPtr = bufMapPtr;
+
+       for (int level = 0; level < imParams.levels; ++level)
+       {
+               const IVec3 curLevelSize = pba[level].getSize();
+
+               const std::size_t copySize =
+                       getPixelSize(mapVkFormat(imParams.format))
+                       * curLevelSize[0] * curLevelSize[1] * curLevelSize[2]
+                       * imParams.arrayLayers;
+
+               deMemcpy(bufCurPtr, pba[level].getDataPtr(), copySize);
+
+           flushMappedMemoryRange(vkd, dev, bufMem->getMemory(), bufMem->getOffset() + (bufCurPtr - bufMapPtr), copySize);
+
+               const VkImageSubresourceLayers curSubresource =
+               {
+                       VK_IMAGE_ASPECT_COLOR_BIT,
+                       (deUint32) level,
+                       0,
+                       (deUint32) imParams.arrayLayers
+               };
+
+               const VkBufferImageCopy curRegion =
+               {
+                       (VkDeviceSize) (bufCurPtr - bufMapPtr),
+                       0,
+                       0,
+                       curSubresource,
+                       {0U, 0U, 0U},
+                       {(deUint32) curLevelSize[0], (deUint32) curLevelSize[1], (deUint32) curLevelSize[2]}
+               };
+
+               copyRegions.push_back(curRegion);
+
+               bufCurPtr += copySize;
+       }
+
+       const VkCommandBufferBeginInfo beginInfo =
+       {
+               VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
+               DE_NULL,
+               VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
+               DE_NULL
+       };
+
+       VK_CHECK(vkd.beginCommandBuffer(copyBuffer.get(), &beginInfo));
+
+       const VkImageSubresourceRange imMemBarSubRange =
+       {
+               VK_IMAGE_ASPECT_COLOR_BIT,
+               0,
+               imParams.levels,
+               0,
+               imParams.arrayLayers
+       };
+
+       VkImageMemoryBarrier imMemBar =
+       {
+               VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
+               DE_NULL,
+               0,
+               VK_ACCESS_TRANSFER_WRITE_BIT,
+               VK_IMAGE_LAYOUT_UNDEFINED,
+               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+               VK_QUEUE_FAMILY_IGNORED,
+               VK_QUEUE_FAMILY_IGNORED,
+               im,
+               imMemBarSubRange
+       };
+
+       VkBufferMemoryBarrier bufMemBar =
+       {
+               VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
+               DE_NULL,
+               VK_ACCESS_HOST_WRITE_BIT,
+               VK_ACCESS_TRANSFER_READ_BIT,
+               VK_QUEUE_FAMILY_IGNORED,
+               VK_QUEUE_FAMILY_IGNORED,
+               buf.get(),
+               0,
+               bufSize
+       };
+
+       vkd.cmdPipelineBarrier(copyBuffer.get(),
+                                                  VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+                                                  VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+                                                  0,
+                                                  0,
+                                                  DE_NULL,
+                                                  1,
+                                                  &bufMemBar,
+                                                  1,
+                                                  &imMemBar);
+
+       vkd.cmdCopyBufferToImage(copyBuffer.get(),
+                                                        buf.get(),
+                                                        im,
+                                                        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+                                                        (deUint32) copyRegions.size(),
+                                                        &copyRegions[0]);
+
+       imMemBar.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+       imMemBar.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
+       imMemBar.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+       imMemBar.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+
+       vkd.cmdPipelineBarrier(copyBuffer.get(),
+                                                  VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+                                                  VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+                                                  0,
+                                                  0,
+                                                  DE_NULL,
+                                                  0,
+                                                  DE_NULL,
+                                                  1,
+                                                  &imMemBar);
+
+       VK_CHECK(vkd.endCommandBuffer(copyBuffer.get()));
+
+       const VkSubmitInfo copySubmitInfo =
+       {
+               VK_STRUCTURE_TYPE_SUBMIT_INFO,
+               DE_NULL,
+               0,
+               DE_NULL,
+               DE_NULL,
+               1,
+               &(copyBuffer.get()),
+               0,
+               DE_NULL
+       };
+
+       VK_CHECK(vkd.queueSubmit(ctx.getUniversalQueue(), 1, &copySubmitInfo, 0));
+       VK_CHECK(vkd.queueWaitIdle(ctx.getUniversalQueue()));
+}
+
+struct TestCaseData
+{
+       std::vector<ConstPixelBufferAccess>     pba;
+       ImageViewParameters                                     imParams;
+       SamplerParameters                                       samplerParams;
+       SampleLookupSettings                            sampleLookupSettings;
+       const SampleArguments*                          sampleArguments;
+       deUint32                                                        numSamples;
+       glu::ShaderType                                         shaderType;
+};
+
+VkSamplerCreateInfo mapSamplerCreateInfo (const SamplerParameters& samplerParams)
+{
+       VkSamplerCreateInfo samplerCreateInfo =
+       {
+               VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,                          // sType
+               DE_NULL,                                                                                        // pNext
+               0U,                                                                                                     // flags
+           samplerParams.magFilter,                                                    // magFilter
+               samplerParams.minFilter,                                                        // minFilter
+               samplerParams.mipmapFilter,                                                     // mipmapMode
+           samplerParams.wrappingModeU,                                                // addressModeU
+           samplerParams.wrappingModeV,                                                // addressModeV
+           samplerParams.wrappingModeW,                                                // addressMoveW
+               samplerParams.lodBias,                                                          // mipLodBias
+               VK_FALSE,                                                                                       // anisotropyEnable
+               1.0f,                                                                                           // maxAnisotropy
+               VK_FALSE,                                                                                       // compareEnable
+               VK_COMPARE_OP_NEVER,                                                            // compareOp
+               samplerParams.minLod,                                                           // minLod
+               samplerParams.maxLod,                                                           // maxLod
+           samplerParams.borderColor,                                                  // borderColor
+               samplerParams.isUnnormalized ? VK_TRUE : VK_FALSE,      // unnormalizedCoordinates
+       };
+
+       if (samplerParams.isCompare)
+       {
+               samplerCreateInfo.compareEnable = VK_TRUE;
+
+           DE_FATAL("Not implemented");
+       }
+
+       return samplerCreateInfo;
+}
+
+VkImageType mapImageType (ImgDim dim)
+{
+       VkImageType imType;
+
+       switch (dim)
+       {
+               case IMG_DIM_1D:
+                       imType = VK_IMAGE_TYPE_1D;
+                       break;
+               case IMG_DIM_2D:
+               case IMG_DIM_CUBE:
+                       imType = VK_IMAGE_TYPE_2D;
+                       break;
+               case IMG_DIM_3D:
+                       imType = VK_IMAGE_TYPE_3D;
+                       break;
+               default:
+                       imType = VK_IMAGE_TYPE_LAST;
+                       break;
+       }
+
+       return imType;
+}
+
+VkImageViewType mapImageViewType (const ImageViewParameters& imParams)
+{
+       VkImageViewType imViewType;
+
+       if (imParams.isArrayed)
+       {
+               switch (imParams.dim)
+               {
+                       case IMG_DIM_1D:
+                               imViewType = VK_IMAGE_VIEW_TYPE_1D_ARRAY;
+                               break;
+                       case IMG_DIM_2D:
+                               imViewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
+                               break;
+                       case IMG_DIM_CUBE:
+                               imViewType = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
+                               break;
+                       default:
+                               imViewType = VK_IMAGE_VIEW_TYPE_LAST;
+                               break;
+               }
+       }
+       else
+       {
+               switch (imParams.dim)
+               {
+                       case IMG_DIM_1D:
+                               imViewType = VK_IMAGE_VIEW_TYPE_1D;
+                               break;
+                       case IMG_DIM_2D:
+                               imViewType = VK_IMAGE_VIEW_TYPE_2D;
+                               break;
+                       case IMG_DIM_3D:
+                               imViewType = VK_IMAGE_VIEW_TYPE_3D;
+                               break;
+                       case IMG_DIM_CUBE:
+                               imViewType = VK_IMAGE_VIEW_TYPE_CUBE;
+                               break;
+                       default:
+                               imViewType = VK_IMAGE_VIEW_TYPE_LAST;
+                               break;
+               }
+       }
+
+       return imViewType;
+}
+
+class DataGenerator
+{
+public:
+       virtual                                                                         ~DataGenerator  (void) {}
+
+       virtual bool                                                            generate                (void) = 0;
+
+       virtual std::vector<ConstPixelBufferAccess> getPba                      (void) const = 0;
+       virtual std::vector<SampleArguments>            getSampleArgs   (void) const = 0;
+
+protected:
+       DataGenerator (void) {}
+};
+
+class TextureFilteringTestInstance : public TestInstance
+{
+public:
+       TextureFilteringTestInstance (Context&                                          ctx,
+                                                                 const TestCaseData&                   testCaseData,
+                                                                 ShaderExecutor&                               shaderExecutor,
+                                                                 de::MovePtr<DataGenerator>    gen)
+
+               : TestInstance                          (ctx)
+               , m_imParams                            (testCaseData.imParams)
+               , m_samplerParams                       (testCaseData.samplerParams)
+               , m_sampleLookupSettings        (testCaseData.sampleLookupSettings)
+               , m_shaderExecutor                      (shaderExecutor)
+               , m_ctx                                         (ctx)
+               , m_vki                                         (m_ctx.getInstanceInterface())
+               , m_vkd                                         (m_ctx.getDeviceInterface())
+               , m_instance                            (m_ctx.getInstance())
+               , m_physicalDevice                      (m_ctx.getPhysicalDevice())
+               , m_device                                      (m_ctx.getDevice())
+               , m_uqfi                                        (m_ctx.getUniversalQueueFamilyIndex())
+               , m_pba                                         (testCaseData.pba)
+               , m_gen                                         (gen.release())
+       {
+               for (deUint8 compNdx = 0; compNdx < 3; ++compNdx)
+               {
+                       DE_ASSERT(m_imParams.size[compNdx] > 0);
+               }
+
+               m_imExtent.width  = m_imParams.size[0];
+               m_imExtent.height = m_imParams.size[1];
+               m_imExtent.depth  = m_imParams.size[2];
+       }
+
+       virtual TestStatus iterate (void)
+       {
+               return runTest();
+       }
+
+protected:
+       TestStatus      runTest                 (void);
+       bool            isSupported             (void);
+       void            createResources (void);
+       void            execute                 (void);
+       bool            verify                  (void);
+
+       tcu::Sampler mapTcuSampler      (void);
+
+       const ImageViewParameters&                      m_imParams;
+       const SamplerParameters&                        m_samplerParams;
+       const SampleLookupSettings&                     m_sampleLookupSettings;
+
+       std::vector<SampleArguments>            m_sampleArguments;
+       deUint32                                                        m_numSamples;
+
+       ShaderExecutor&                                         m_shaderExecutor;
+       Context&                                                        m_ctx;
+       const InstanceInterface&                        m_vki;
+       const DeviceInterface&                          m_vkd;
+       VkInstance                                                      m_instance;
+       VkPhysicalDevice                                        m_physicalDevice;
+       VkDevice                                                        m_device;
+       deUint32                                                        m_uqfi;
+
+       VkExtent3D                                                      m_imExtent;
+
+    int                                                                        m_coordBits;
+       int                                                                     m_mipmapBits;
+
+       de::MovePtr<Allocation>                         m_imAllocation;
+       Move<VkImage>                                           m_im;
+       Move<VkImageView>                                       m_imView;
+       Move<VkSampler>                                         m_sampler;
+
+       std::vector<ConstPixelBufferAccess> m_pba;
+       de::MovePtr<DataGenerator>                      m_gen;
+
+       std::vector<Vec4>                                       m_resultSamples;
+       std::vector<Vec4>                                       m_resultCoords;
+};
+
+TestStatus TextureFilteringTestInstance::runTest (void)
+{
+       if (!isSupported())
+       {
+           TCU_THROW(NotSupportedError, "Unsupported combination of filtering and image format");
+       }
+
+       TCU_CHECK(m_gen->generate());
+       m_pba =   m_gen->getPba();
+
+       m_sampleArguments = m_gen->getSampleArgs();
+       m_numSamples = (deUint32) m_sampleArguments.size();
+
+       createResources();
+       initializeImage(m_ctx, m_im.get(), &m_pba[0], m_imParams);
+
+       m_shaderExecutor.addSamplerUniform(0, m_imView.get(), m_sampler.get());
+
+       deUint64 startTime, endTime;
+
+       startTime = deGetMicroseconds();
+       execute();
+       endTime = deGetMicroseconds();
+
+       m_ctx.getTestContext().getLog() << TestLog::Message
+                                                                       << "Execution time: "
+                                                                       << endTime - startTime
+                                                                       << "us"
+                                                                       << TestLog::EndMessage;
+
+    startTime = deGetMicroseconds();
+       bool result = verify();
+    endTime = deGetMicroseconds();
+
+       m_ctx.getTestContext().getLog() << TestLog::Message
+                                                                       << "Verification time: "
+                                                                       << endTime - startTime
+                                                                       << "us"
+                                                                       << TestLog::EndMessage;
+
+       if (result)
+       {
+               return TestStatus::pass("Success");
+       }
+       else
+       {
+               // \todo [2016-06-24 collinbaker] Print report if verification fails
+               return TestStatus::fail("Verification failed");
+       }
+}
+
+bool TextureFilteringTestInstance::verify (void)
+{
+       // \todo [2016-06-24 collinbaker] Handle cubemaps
+
+       m_coordBits  = (deUint8) m_ctx.getDeviceProperties().limits.subTexelPrecisionBits;
+       m_mipmapBits = (deUint8) m_ctx.getDeviceProperties().limits.mipmapPrecisionBits;
+
+       SampleVerifier verifier(m_imParams,
+                                                       m_samplerParams,
+                                                       m_sampleLookupSettings,
+                                                       m_coordBits,
+                                                       m_mipmapBits,
+                                                       m_pba);
+
+       for (deUint32 sampleNdx = 0; sampleNdx < m_numSamples; ++sampleNdx)
+       {
+               if (!verifier.verifySample(m_sampleArguments[sampleNdx], m_resultSamples[sampleNdx]))
+               {
+                       // Re-run with report logging
+                       std::string report;
+                       verifier.verifySampleReport(m_sampleArguments[sampleNdx], m_resultSamples[sampleNdx], report);
+
+                       m_ctx.getTestContext().getLog()
+                               << TestLog::Message
+                               << "Failed verification at sample " << sampleNdx << ".\n"
+                               << "\tCoordinate: " << m_sampleArguments[sampleNdx].coord << "\n"
+                               << "\tLOD: " << m_sampleArguments[sampleNdx].lod << "\n"
+                               << "\tGPU Result: " << m_resultSamples[sampleNdx] << "\n"
+                               << TestLog::EndMessage;
+
+                       for (int levelNdx = 0; levelNdx < m_imParams.levels; ++levelNdx)
+                       {
+                               LogImage("", "", m_pba[levelNdx]).write(m_ctx.getTestContext().getLog());
+                       }
+
+                   m_ctx.getTestContext().getLog()
+                               << TestLog::Message
+                               << "Failure report:\n" << report << "\n"
+                               << TestLog::EndMessage;
+
+                       return false;
+               }
+       }
+
+       return true;
+}
+
+void TextureFilteringTestInstance::execute (void)
+{
+       std::vector<float> coords, layers, dRefs, dPdxs, dPdys, lods;
+
+       for (deUint32 ndx = 0; ndx < m_numSamples; ++ndx)
+       {
+               const SampleArguments& sampleArgs = m_sampleArguments[ndx];
+
+               for (deUint8 compNdx = 0; compNdx < 4; ++compNdx)
+               {
+                       coords.push_back(sampleArgs.coord[compNdx]);
+                       dPdxs .push_back(sampleArgs.dPdx[compNdx]);
+                       dPdys .push_back(sampleArgs.dPdy[compNdx]);
+               }
+
+               layers.push_back(sampleArgs.layer);
+               dRefs .push_back(sampleArgs.dRef);
+               lods  .push_back(sampleArgs.lod);
+       }
+
+       const void* inputs[6] =
+       {
+               reinterpret_cast<const void*>(&coords[0]),
+               reinterpret_cast<const void*>(&layers[0]),
+               reinterpret_cast<const void*>(&dRefs[0]),
+               reinterpret_cast<const void*>(&dPdxs[0]),
+               reinterpret_cast<const void*>(&dPdys[0]),
+               reinterpret_cast<const void*>(&lods[0])
+       };
+
+       // Staging buffers; data will be copied into vectors of Vec4
+       // \todo [2016-06-24 collinbaker] Figure out if I actually need to
+       // use staging buffers
+       std::vector<float> resultSamplesTemp(m_numSamples * 4);
+       std::vector<float> resultCoordsTemp (m_numSamples * 4);
+
+       void* outputs[2] =
+       {
+               reinterpret_cast<void*>(&resultSamplesTemp[0]),
+               reinterpret_cast<void*>(&resultCoordsTemp[0])
+       };
+
+       m_shaderExecutor.execute(m_ctx, m_numSamples, inputs, outputs);
+
+       m_resultSamples.resize(m_numSamples);
+       m_resultCoords .resize(m_numSamples);
+
+       for (deUint32 ndx = 0; ndx < m_numSamples; ++ndx)
+       {
+               m_resultSamples[ndx] = Vec4(resultSamplesTemp[4 * ndx + 0],
+                                                                       resultSamplesTemp[4 * ndx + 1],
+                                                                       resultSamplesTemp[4 * ndx + 2],
+                                                                       resultSamplesTemp[4 * ndx + 3]);
+
+               m_resultCoords [ndx] = Vec4(resultCoordsTemp [4 * ndx + 0],
+                                                                       resultCoordsTemp [4 * ndx + 1],
+                                                                       resultCoordsTemp [4 * ndx + 2],
+                                                                       resultCoordsTemp [4 * ndx + 3]);
+       }
+}
+
+void TextureFilteringTestInstance::createResources (void)
+{
+       // Create VkImage
+
+       const VkImageCreateFlags imCreateFlags =
+               (m_imParams.dim == IMG_DIM_CUBE) ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0;
+
+       const VkImageCreateInfo imCreateInfo =
+       {
+               VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                    // sType
+               DE_NULL,                                                                                                                // pNext
+               imCreateFlags,                                                                                                  // flags
+           mapImageType(m_imParams.dim),                                                                       // imageType
+           m_imParams.format,                                                                                          // format
+               m_imExtent,                                                                                                             // extent
+           m_imParams.levels,                                                                                          // mipLevels
+           m_imParams.arrayLayers,                                                                                     // arrayLayers
+               VK_SAMPLE_COUNT_1_BIT,                                                                                  // samples
+               VK_IMAGE_TILING_OPTIMAL,                                                                                // tiling
+               VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,   // usage
+               VK_SHARING_MODE_EXCLUSIVE,                                                                              // sharingMode
+               1,                                                                                                                              // queueFamilyIndexCount
+               &m_uqfi,                                                                                                                // pQueueFamilyIndices
+               VK_IMAGE_LAYOUT_UNDEFINED                                                                               // initialLayout
+       };
+
+    m_im = createImage(m_vkd, m_device, &imCreateInfo);
+
+       // Allocate memory for image
+
+       VkMemoryRequirements imMemReq;
+       m_vkd.getImageMemoryRequirements(m_device, m_im.get(), &imMemReq);
+
+       m_imAllocation = m_ctx.getDefaultAllocator().allocate(imMemReq, MemoryRequirement::Any);
+       VK_CHECK(m_vkd.bindImageMemory(m_device, m_im.get(), m_imAllocation->getMemory(), m_imAllocation->getOffset()));
+
+       // Create VkImageView
+
+       // \todo [2016-06-23 collinbaker] Pick aspectMask based on image type (i.e. support depth and/or stencil images)
+       VkImageSubresourceRange imViewSubresourceRange =
+       {
+               VK_IMAGE_ASPECT_COLOR_BIT,      // aspectMask
+               0,                                                      // baseMipLevel
+               m_imParams.levels,                      // levelCount
+               0,                                                      // baseArrayLayer
+               m_imParams.arrayLayers          // layerCount
+       };
+
+       if (m_imParams.dim == IMG_DIM_CUBE)
+       {
+               imViewSubresourceRange.layerCount *= 6;
+       }
+
+       const VkComponentMapping imViewCompMap =
+       {
+               VK_COMPONENT_SWIZZLE_R,
+               VK_COMPONENT_SWIZZLE_G,
+               VK_COMPONENT_SWIZZLE_B,
+               VK_COMPONENT_SWIZZLE_A
+       };
+
+       const VkImageViewCreateInfo imViewCreateInfo =
+       {
+               VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // sType
+               DE_NULL,                                                                        // pNext
+               0,                                                                                      // flags
+               m_im.get(),                                                                     // image
+               mapImageViewType(m_imParams),                           // viewType
+           m_imParams.format,                                                  // format
+           imViewCompMap,                                                              // components
+               imViewSubresourceRange                                          // subresourceRange
+       };
+
+       m_imView = createImageView(m_vkd, m_device, &imViewCreateInfo);
+
+       // Create VkSampler
+
+       const VkSamplerCreateInfo samplerCreateInfo = mapSamplerCreateInfo(m_samplerParams);
+       m_sampler = createSampler(m_vkd, m_device, &samplerCreateInfo);
+}
+
+bool TextureFilteringTestInstance::isSupported (void)
+{
+       const VkImageCreateFlags imCreateFlags =
+               (m_imParams.dim == IMG_DIM_CUBE) ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0;
+
+       VkImageFormatProperties imFormatProperties;
+       VkFormatProperties              formatProperties;
+
+       m_vki.getPhysicalDeviceImageFormatProperties(m_physicalDevice,
+                                                                                                m_imParams.format,
+                                                                                                mapImageType(m_imParams.dim),
+                                                                                                VK_IMAGE_TILING_OPTIMAL,
+                                                                                                VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
+                                                                                                imCreateFlags,
+                                                                                                &imFormatProperties);
+
+       m_vki.getPhysicalDeviceFormatProperties(         m_physicalDevice,
+                                                                                                m_imParams.format,
+                                                                                                &formatProperties);
+
+       // \todo [2016-06-23 collinbaker] Check image parameters against imFormatProperties
+
+       VkFormatFeatureFlags reqImFeatures = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
+
+       if (m_samplerParams.minFilter    == VK_FILTER_LINEAR ||
+               m_samplerParams.magFilter        == VK_FILTER_LINEAR ||
+               m_samplerParams.mipmapFilter == VK_SAMPLER_MIPMAP_MODE_LINEAR)
+       {
+               reqImFeatures |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
+       }
+
+       return (formatProperties.optimalTilingFeatures & reqImFeatures) == reqImFeatures;
+}
+
+class TextureFilteringTestCase : public TestCase
+{
+public:
+       TextureFilteringTestCase (tcu::TestContext& testCtx,
+                                                         const char* name,
+                                                         const char* description)
+               : TestCase(testCtx, name, description)
+       {
+       }
+
+       void init (void);
+
+       virtual void initPrograms (vk::SourceCollections& programCollection) const
+       {
+               DE_ASSERT(m_executor);
+               m_executor->setShaderSources(programCollection);
+       }
+
+       virtual de::MovePtr<DataGenerator> createGenerator (void) const = 0;
+
+       virtual TestInstance* createInstance (Context& ctx) const
+       {
+               return new TextureFilteringTestInstance(ctx, m_testCaseData, *m_executor, createGenerator());
+       }
+
+protected:
+       de::MovePtr<ShaderExecutor> m_executor;
+       TestCaseData                            m_testCaseData;
+};
+
+void TextureFilteringTestCase::init (void)
+{
+       ShaderSpec shaderSpec;
+       shaderSpec.source = genLookupCode(m_testCaseData.imParams,
+                                                                         m_testCaseData.samplerParams,
+                                                                         m_testCaseData.sampleLookupSettings);
+       shaderSpec.source += "\nsampledCoord = coord;";
+
+       shaderSpec.outputs.push_back(Symbol("result", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
+       shaderSpec.outputs.push_back(Symbol("sampledCoord", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
+       shaderSpec.inputs .push_back(Symbol("coord", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
+       shaderSpec.inputs .push_back(Symbol("layer", glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP)));
+       shaderSpec.inputs .push_back(Symbol("dRef", glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP)));
+       shaderSpec.inputs .push_back(Symbol("dPdx", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
+       shaderSpec.inputs .push_back(Symbol("dPdy", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
+       shaderSpec.inputs .push_back(Symbol("lod", glu::VarType(glu::TYPE_FLOAT, glu::PRECISION_HIGHP)));
+
+       shaderSpec.globalDeclarations = "layout(set=0, binding=0) uniform highp ";
+       shaderSpec.globalDeclarations += genSamplerDeclaration(m_testCaseData.imParams,
+                                                                                                                  m_testCaseData.samplerParams);
+       shaderSpec.globalDeclarations += " testSampler;";
+
+       m_executor = de::MovePtr<ShaderExecutor>(createExecutor(m_testCaseData.shaderType, shaderSpec));
+       DE_ASSERT(m_executor);
+
+       m_testCtx.getLog() << *m_executor;
+}
+
+class Texture2DGradientTestCase : public TextureFilteringTestCase
+{
+public:
+       Texture2DGradientTestCase (TestContext& testCtx,
+                                                          const char* name,
+                                                          const char* desc,
+                                                          TextureFormat format,
+                                                          IVec3 dimensions,
+                                                          VkFilter magFilter,
+                                                          VkFilter minFilter,
+                                                          VkSamplerMipmapMode mipmapFilter,
+                                                          VkSamplerAddressMode wrappingMode)
+
+               : TextureFilteringTestCase      (testCtx, name, desc)
+               , m_testCtx                                     (testCtx)
+               , m_format                                      (format)
+               , m_dimensions                          (dimensions)
+               , m_magFilter                           (magFilter)
+               , m_minFilter                           (minFilter)
+               , m_mipmapFilter                        (mipmapFilter)
+               , m_wrappingMode                        (wrappingMode)
+       {
+               m_testCaseData = genTestCaseData();
+               init();
+       }
+
+protected:
+       class Generator;
+
+       virtual de::MovePtr<DataGenerator> createGenerator (void) const;
+
+       TestCaseData genTestCaseData()
+       {
+               // Generate grid
+
+               SampleLookupSettings sampleLookupSettings =
+               {
+                       LOOKUP_LOD_MODE_LOD, // lookupLodMode
+                       false, // hasLodBias
+                       false, // isProjective
+               };
+
+               SamplerParameters samplerParameters =
+               {
+                       m_magFilter, // magFilter
+                       m_minFilter, // minFilter
+                       m_mipmapFilter, // mipmapFilter
+                   m_wrappingMode, // wrappingModeU
+                       m_wrappingMode, // wrappingModeV
+                       m_wrappingMode, // wrappingModeW
+                       VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE, // borderColor
+                       0.0f, // lodBias
+                       -1.0f, // minLod
+                       50.0f, // maxLod
+                       false, // isUnnormalized
+                       false // isCompare
+               };
+
+           deUint8 numLevels = (deUint8) (1 + deLog2Floor32(de::max(m_dimensions[0],
+                                                                                                                                m_dimensions[1])));
+
+               ImageViewParameters imParameters =
+               {
+                       IMG_DIM_2D, // dim
+                       mapTextureFormat(m_format), // format
+                       m_dimensions, // size
+                       numLevels, // levels
+                       false, // isArrayed
+                       1, // arrayLayers
+               };
+
+               TestCaseData data =
+               {
+                       std::vector<ConstPixelBufferAccess>(),
+                       imParameters,
+                       samplerParameters,
+                       sampleLookupSettings,
+                       &m_args[0],
+                       (deUint32) m_args.size(),
+                       glu::SHADERTYPE_FRAGMENT
+               };
+
+               return data;
+       }
+
+private:
+       TestContext&                                    m_testCtx;
+       TextureFormat                                   m_format;
+       IVec3                                                   m_dimensions;
+       VkFilter                                                m_magFilter;
+       VkFilter                                                m_minFilter;
+       VkSamplerMipmapMode                             m_mipmapFilter;
+       VkSamplerAddressMode                    m_wrappingMode;
+
+       std::vector<SampleArguments>    m_args;
+};
+
+class Texture2DGradientTestCase::Generator : public DataGenerator
+{
+public:
+       Generator (const Texture2DGradientTestCase* testCase) : m_testCase(testCase) {}
+
+       virtual ~Generator (void)
+       {
+               delete m_tex.release();
+       }
+
+       virtual bool generate (void)
+       {
+               m_tex = de::MovePtr<Texture2D>(new Texture2D(m_testCase->m_format,
+                                                                                                        m_testCase->m_dimensions[0],
+                                                                                                        m_testCase->m_dimensions[1]));
+
+               deUint8 numLevels = (deUint8) (1 + deLog2Floor32(de::max(m_testCase->m_dimensions[0],
+                                                                                                                                m_testCase->m_dimensions[1])));
+
+               TextureFormatInfo fmtInfo = getTextureFormatInfo(m_testCase->m_format);
+
+               Vec4 cBias  = fmtInfo.valueMin;
+               Vec4 cScale = fmtInfo.valueMax - fmtInfo.valueMin;
+
+               for (deUint8 levelNdx = 0; levelNdx < numLevels; ++levelNdx)
+               {
+                       Vec4 gMin = Vec4(0.0f, 0.0f, 0.0f, 1.0f) * cScale + cBias;
+                       Vec4 gMax = Vec4(1.0f, 1.0f, 1.0f, 0.0f) * cScale + cBias;
+
+                       m_tex->allocLevel(levelNdx);
+                       fillWithComponentGradients(m_tex->getLevel(levelNdx), gMin, gMax);
+               }
+
+               return true;
+       }
+
+       virtual std::vector<ConstPixelBufferAccess> getPba (void) const
+       {
+               std::vector<ConstPixelBufferAccess> pba;
+
+               const deUint8 numLevels = (deUint8) m_tex->getNumLevels();
+
+               for (deUint8 levelNdx = 0; levelNdx < numLevels; ++levelNdx)
+               {
+                       pba.push_back(m_tex->getLevel(levelNdx));
+               }
+
+               return pba;
+       }
+
+       virtual std::vector<SampleArguments> getSampleArgs (void) const
+       {
+               std::vector<SampleArguments> args;
+
+               const float lodList[] = {-1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0};
+
+               for (deInt32 i = 0; i < 2 * m_testCase->m_dimensions[0] + 1; ++i)
+               {
+                       for (deInt32 j = 0; j < 2 * m_testCase->m_dimensions[1] + 1; ++j)
+                       {
+                               for (deUint32 lodNdx = 0; lodNdx < DE_LENGTH_OF_ARRAY(lodList); ++lodNdx)
+                               {
+                                       SampleArguments cur;
+                                       cur.coord = Vec4((float) i / (float) (2 * m_testCase->m_dimensions[0]),
+                                                                        (float) j / (float) (2 * m_testCase->m_dimensions[1]),
+                                                                        0.0f, 0.0f);
+                                       cur.lod = lodList[lodNdx];
+
+                                       args.push_back(cur);
+                               }
+                       }
+               }
+
+               return args;
+       }
+
+private:
+       const Texture2DGradientTestCase*        m_testCase;
+       de::MovePtr<Texture2D>                          m_tex;
+};
+
+de::MovePtr<DataGenerator> Texture2DGradientTestCase::createGenerator (void) const
+{
+       return de::MovePtr<DataGenerator>(new Generator(this));
+}
+
+TestCaseGroup* create2DFormatTests (TestContext& testCtx)
+{
+       de::MovePtr<TestCaseGroup> tests(
+               new TestCaseGroup(testCtx, "formats", "Various image formats"));
+
+    VkFormat formats[] =
+       {
+           VK_FORMAT_B4G4R4A4_UNORM_PACK16,
+               VK_FORMAT_R5G6B5_UNORM_PACK16,
+               VK_FORMAT_A1R5G5B5_UNORM_PACK16,
+               VK_FORMAT_R8_UNORM,
+               VK_FORMAT_R8_SNORM,
+               VK_FORMAT_R8G8_UNORM,
+               VK_FORMAT_R8G8_SNORM,
+               VK_FORMAT_R8G8B8A8_UNORM,
+               VK_FORMAT_R8G8B8A8_SNORM,
+               VK_FORMAT_R8G8B8A8_SRGB,
+               VK_FORMAT_B8G8R8A8_UNORM,
+               VK_FORMAT_B8G8R8A8_SRGB,
+               VK_FORMAT_A8B8G8R8_UNORM_PACK32,
+               VK_FORMAT_A8B8G8R8_SNORM_PACK32,
+               VK_FORMAT_A8B8G8R8_SRGB_PACK32,
+               VK_FORMAT_A2B10G10R10_UNORM_PACK32,
+               VK_FORMAT_R16_SFLOAT,
+               VK_FORMAT_R16G16_SFLOAT,
+               VK_FORMAT_R16G16B16A16_SFLOAT,
+               VK_FORMAT_B10G11R11_UFLOAT_PACK32,
+               VK_FORMAT_E5B9G9R9_UFLOAT_PACK32
+       };
+
+       const IVec3 size(32, 32, 1);
+
+       for (deUint32 formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
+       {
+               std::string prefix = getFormatName(formats[formatNdx]);
+
+               Texture2DGradientTestCase* testCaseNearest =
+                       new Texture2DGradientTestCase(
+                               testCtx,
+                           (prefix + "_nearest").c_str(),
+                               "...",
+                               mapVkFormat(formats[formatNdx]),
+                               size,
+                               VK_FILTER_NEAREST,
+                               VK_FILTER_NEAREST,
+                               VK_SAMPLER_MIPMAP_MODE_NEAREST,
+                               VK_SAMPLER_ADDRESS_MODE_REPEAT);
+
+               tests->addChild(testCaseNearest);
+
+           Texture2DGradientTestCase* testCaseLinear =
+                       new Texture2DGradientTestCase(
+                               testCtx,
+                           (prefix + "_linear").c_str(),
+                               "...",
+                               mapVkFormat(formats[formatNdx]),
+                               size,
+                               VK_FILTER_LINEAR,
+                               VK_FILTER_LINEAR,
+                               VK_SAMPLER_MIPMAP_MODE_LINEAR,
+                               VK_SAMPLER_ADDRESS_MODE_REPEAT);
+
+               tests->addChild(testCaseLinear);
+       }
+
+       return tests.release();
+}
+
+TestCaseGroup* create2DSizeTests (TestContext& testCtx)
+{
+       de::MovePtr<TestCaseGroup> tests(
+               new TestCaseGroup(testCtx, "sizes", "Various size and filtering combinations"));
+
+       const VkFilter filters[2] =
+       {
+               VK_FILTER_NEAREST,
+               VK_FILTER_LINEAR
+       };
+
+       const VkSamplerMipmapMode mipmapFilters[2] =
+       {
+               VK_SAMPLER_MIPMAP_MODE_NEAREST,
+               VK_SAMPLER_MIPMAP_MODE_LINEAR
+       };
+
+       const VkSamplerAddressMode wrappingModes[2] =
+       {
+               VK_SAMPLER_ADDRESS_MODE_REPEAT,
+               VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE
+       };
+
+       IVec3 sizes[] =
+       {
+               IVec3(2, 2, 1),
+               IVec3(2, 3, 1),
+               IVec3(3, 7, 1),
+               IVec3(4, 8, 1),
+               IVec3(31, 55, 1),
+               IVec3(32, 32, 1),
+               IVec3(32, 64, 1),
+               IVec3(57, 35, 1),
+               IVec3(128, 128, 1)
+       };
+
+
+       for (deUint32 sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes); ++sizeNdx)
+       {
+               for (deUint32 magFilterNdx = 0; magFilterNdx < 2; ++magFilterNdx)
+               {
+                       for (deUint32 minFilterNdx = 0; minFilterNdx < 2; ++minFilterNdx)
+                       {
+                               for (deUint32 mipmapFilterNdx = 0; mipmapFilterNdx < 2; ++mipmapFilterNdx)
+                               {
+                                       for (deUint32 wrappingModeNdx = 0; wrappingModeNdx < 2; ++wrappingModeNdx)
+                                       {
+                                               std::ostringstream caseName;
+
+                                               caseName << sizes[sizeNdx][0] << "x" << sizes[sizeNdx][1];
+
+                                               switch (filters[magFilterNdx])
+                                               {
+                                                       case VK_FILTER_NEAREST:
+                                                               caseName << "_nearest";
+                                                               break;
+                                                       case VK_FILTER_LINEAR:
+                                                               caseName << "_linear";
+                                                               break;
+                                                       default:
+                                                               break;
+                                               }
+
+                                               switch (filters[minFilterNdx])
+                                               {
+                                                       case VK_FILTER_NEAREST:
+                                                               caseName << "_nearest";
+                                                               break;
+                                                       case VK_FILTER_LINEAR:
+                                                               caseName << "_linear";
+                                                               break;
+                                                       default:
+                                                               break;
+                                               }
+
+                                               switch (mipmapFilters[mipmapFilterNdx])
+                                               {
+                                                       case VK_SAMPLER_MIPMAP_MODE_NEAREST:
+                                                               caseName << "_mipmap_nearest";
+                                                               break;
+                                                       case VK_SAMPLER_MIPMAP_MODE_LINEAR:
+                                                               caseName << "_mipmap_linear";
+                                                               break;
+                                                       default:
+                                                               break;
+                                               }
+
+                                               switch (wrappingModes[wrappingModeNdx])
+                                               {
+                                                       case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:
+                                                               caseName << "_clamp";
+                                                               break;
+                                                       case VK_SAMPLER_ADDRESS_MODE_REPEAT:
+                                                               caseName << "_repeat";
+                                                               break;
+                                                       default:
+                                                               break;
+                                               }
+
+                                               Texture2DGradientTestCase* testCase =
+                                                       new Texture2DGradientTestCase(
+                                                               testCtx,
+                                                               caseName.str().c_str(),
+                                                               "...",
+                                                               mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM),
+                                                               sizes[sizeNdx],
+                                                               filters[magFilterNdx],
+                                                               filters[minFilterNdx],
+                                                               mipmapFilters[mipmapFilterNdx],
+                                                               wrappingModes[wrappingModeNdx]);
+
+                                               tests->addChild(testCase);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       return tests.release();
+}
+
+TestCaseGroup* create2DTests (TestContext& testCtx)
+{
+       de::MovePtr<TestCaseGroup> tests(
+               new TestCaseGroup(testCtx, "2d", "2D Image filtering tests"));
+
+       tests->addChild(create2DSizeTests(testCtx));
+       tests->addChild(create2DFormatTests(testCtx));
+
+       return tests.release();
+}
+
+} // anonymous
+
+TestCaseGroup* createExplicitLodTests (TestContext& testCtx)
+{
+       de::MovePtr<TestCaseGroup> tests(
+               new TestCaseGroup(testCtx, "explicit_lod", "Texture filtering with explicit LOD"));
+
+       tests->addChild(create2DTests(testCtx));
+
+       return tests.release();
+}
+
+} // texture_filtering
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/texture_filtering/vktTextureFilteringExplicitLodTests.hpp b/external/vulkancts/modules/vulkan/texture_filtering/vktTextureFilteringExplicitLodTests.hpp
new file mode 100644 (file)
index 0000000..28fd636
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef _VKTTEXTUREFILTERINGEXPLICITLODTESTS_HPP
+#define _VKTTEXTUREFILTERINGEXPLICITLODTESTS_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Texture filtering tests with explicit LOD instructions
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuTestCase.hpp"
+
+namespace vkt
+{
+namespace texture_filtering
+{
+
+tcu::TestCaseGroup* createExplicitLodTests (tcu::TestContext& testCtx);
+
+} // texture_filtering
+} // vkt
+
+#endif // _VKTTEXTUREFILTERINGEXPLICITLODTESTS_HPP
diff --git a/external/vulkancts/modules/vulkan/texture_filtering/vktTextureFilteringTests.cpp b/external/vulkancts/modules/vulkan/texture_filtering/vktTextureFilteringTests.cpp
new file mode 100644 (file)
index 0000000..38d9add
--- /dev/null
@@ -0,0 +1,44 @@
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Texture filtering tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktTextureFilteringTests.hpp"
+
+#include "vktTextureFilteringExplicitLodTests.hpp"
+#include "deUniquePtr.hpp"
+
+namespace vkt
+{
+namespace texture_filtering
+{
+
+tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx)
+{
+       de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "texture_filtering", "Texture filtering verification tests"));
+
+       group->addChild(createExplicitLodTests(testCtx));
+
+       return group.release();
+}
+
+} // texture_filtering
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/texture_filtering/vktTextureFilteringTests.hpp b/external/vulkancts/modules/vulkan/texture_filtering/vktTextureFilteringTests.hpp
new file mode 100644 (file)
index 0000000..cddc743
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef _VKTTEXTUREFILTERINGTESTS_HPP
+#define _VKTTEXTUREFILTERINGTESTS_HPP
+
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Texture filtering tests
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tcuTestCase.hpp"
+
+namespace vkt
+{
+namespace texture_filtering
+{
+
+tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx);
+
+} // texture_filtering
+} // vkt
+
+#endif // _VKTTEXTUREFILTERINGTESTS_HPP
index 785b8a5..928e017 100644 (file)
@@ -59,6 +59,7 @@
 #include "vktShaderRenderTextureGatherTests.hpp"
 #include "vktShaderBuiltinTests.hpp"
 #include "vktOpaqueTypeIndexingTests.hpp"
+#include "vktTextureFilteringTests.hpp"
 #include "vktUniformBlockTests.hpp"
 #include "vktDynamicStateTests.hpp"
 #include "vktSSBOLayoutTests.hpp"
@@ -392,6 +393,7 @@ void TestPackage::init (void)
        addChild(tessellation::createTests              (m_testCtx));
        addChild(rasterization::createTests             (m_testCtx));
        addChild(clipping::createTests                  (m_testCtx));
+       addChild(texture_filtering::createTests (m_testCtx));
 }
 
 } // vkt