ShaderRenderCase: Add texture/sampler support
authorPeter Gal <pgal.u-szeged@partner.samsung.com>
Thu, 3 Sep 2015 18:19:41 +0000 (20:19 +0200)
committerPeter Gal <pgal.u-szeged@partner.samsung.com>
Thu, 12 Nov 2015 18:52:42 +0000 (19:52 +0100)
external/vulkancts/modules/vulkan/shaderrendercase/CMakeLists.txt
external/vulkancts/modules/vulkan/shaderrendercase/vktShaderRenderCase.cpp
external/vulkancts/modules/vulkan/shaderrendercase/vktShaderRenderCase.hpp
external/vulkancts/modules/vulkan/shaderrendercase/vktShaderRenderCaseTests.cpp
external/vulkancts/modules/vulkan/shaderrendercase/vktTexture.cpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/shaderrendercase/vktTexture.hpp [new file with mode: 0644]

index c162976..48723b9 100644 (file)
@@ -5,6 +5,8 @@ include_directories(
 set(DEQP_VK_SHADERRENDERCASE_SRCS
        vktShaderRenderCase.cpp
        vktShaderRenderCaseTests.cpp
+
+       vktTexture.cpp
 )
 
 set(DEQP_VK_SHADERRENDERCASE_LIBS
index 85479f8..a86c135 100644 (file)
@@ -69,8 +69,7 @@ static const tcu::Vec4        DEFAULT_CLEAR_COLOR     = tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f
 class QuadGrid
 {
 public:
-                            QuadGrid                (int gridSize, int screenWidth, int screenHeight, const Vec4& constCoords, const vector<Mat4>& userAttribTransforms
-/*, const vector<TextureBinding>& textures*/);
+                            QuadGrid                (int gridSize, int screenWidth, int screenHeight, const Vec4& constCoords, const vector<Mat4>& userAttribTransforms, const vector<TextureBinding>& textures);
                             ~QuadGrid               (void);
 
     int                     getGridSize             (void) const { return m_gridSize; }
@@ -78,8 +77,7 @@ public:
     int                     getNumTriangles         (void) const { return m_numTriangles; }
     const Vec4&             getConstCoords          (void) const { return m_constCoords; }
     const vector<Mat4>      getUserAttribTransforms (void) const { return m_userAttribTransforms; }
-       // TODO:
-    //const vector<TextureBinding>&   getTextures     (void) const { return m_textures; }
+       const vector<TextureBinding>&   getTextures     (void) const { return m_textures; }
 
        const Vec4*                             getPositions                    (void) const { return &m_positions[0]; }
        const float*                    getAttribOne                    (void) const { return &m_attribOne[0]; }
@@ -101,8 +99,8 @@ private:
     int                     m_numTriangles;
     Vec4                    m_constCoords;
     vector<Mat4>            m_userAttribTransforms;
-       // TODO:
-    // vector<TextureBinding>  m_textures;
+
+    vector<TextureBinding>  m_textures;
 
     vector<Vec4>            m_screenPos;
        vector<Vec4>                    m_positions;
@@ -113,14 +111,13 @@ private:
     vector<deUint16>        m_indices;
 };
 
-QuadGrid::QuadGrid (int gridSize, int width, int height, const Vec4& constCoords, const vector<Mat4>& userAttribTransforms
-/*, const vector<TextureBinding>& textures*/)
+QuadGrid::QuadGrid (int gridSize, int width, int height, const Vec4& constCoords, const vector<Mat4>& userAttribTransforms, const vector<TextureBinding>& textures)
     : m_gridSize                (gridSize)
     , m_numVertices             ((gridSize + 1) * (gridSize + 1))
     , m_numTriangles            (gridSize * gridSize * 2)
     , m_constCoords             (constCoords)
     , m_userAttribTransforms    (userAttribTransforms)
-//    , m_textures                (textures)
+    , m_textures                (textures)
 {
     Vec4 viewportScale = Vec4((float)width, (float)height, 0.0f, 0.0f);
 
@@ -199,6 +196,16 @@ inline Vec4 QuadGrid::getUserAttrib (int attribNdx, float sx, float sy) const
     return m_userAttribTransforms[attribNdx] * Vec4(sx, sy, 0.0f, 1.0f);
 }
 
+// TextureBinding
+
+TextureBinding::TextureBinding (const Texture2D* tex2D, const tcu::Sampler& sampler)
+       : m_type        (TYPE_2D)
+       , m_sampler     (sampler)
+{
+       m_binding.tex2D = tex2D;
+}
+
+
 
 
 // ShaderEvalContext.
@@ -208,8 +215,6 @@ ShaderEvalContext::ShaderEvalContext (const QuadGrid& quadGrid_)
        , isDiscarded(false)
        , quadGrid(quadGrid_)
 {
-       // TODO...
-/*
     const vector<TextureBinding>& bindings = quadGrid.getTextures();
     DE_ASSERT((int)bindings.size() <= MAX_TEXTURES);
 
@@ -226,14 +231,14 @@ ShaderEvalContext::ShaderEvalContext (const QuadGrid& quadGrid_)
         switch (binding.getType())
         {
             case TextureBinding::TYPE_2D:       textures[ndx].tex2D         = &binding.get2D()->getRefTexture();        break;
-            case TextureBinding::TYPE_CUBE_MAP: textures[ndx].texCube       = &binding.getCube()->getRefTexture();      break;
+/*            case TextureBinding::TYPE_CUBE_MAP: textures[ndx].texCube       = &binding.getCube()->getRefTexture();      break;
             case TextureBinding::TYPE_2D_ARRAY: textures[ndx].tex2DArray    = &binding.get2DArray()->getRefTexture();   break;
-            case TextureBinding::TYPE_3D:       textures[ndx].tex3D         = &binding.get3D()->getRefTexture();        break;
+            case TextureBinding::TYPE_3D:       textures[ndx].tex3D         = &binding.get3D()->getRefTexture();        break;*/
             default:
                 DE_ASSERT(DE_FALSE);
         }
     }
-*/
+
 }
 
 ShaderEvalContext::~ShaderEvalContext (void)
@@ -257,13 +262,11 @@ void ShaderEvalContext::reset (float sx, float sy)
         in[attribNdx] = quadGrid.getUserAttrib(attribNdx, sx, sy);
 }
 
-tcu::Vec4 ShaderEvalContext::texture2D (int /* unitNdx */, const tcu::Vec2& /* texCoords */)
+tcu::Vec4 ShaderEvalContext::texture2D (int unitNdx, const tcu::Vec2& texCoords)
 {
-       // TODO: add texture binding
-/*    if (textures[unitNdx].tex2D)
+    if (textures[unitNdx].tex2D)
         return textures[unitNdx].tex2D->sample(textures[unitNdx].sampler, texCoords.x(), texCoords.y(), 0.0f);
     else
-*/
         return tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
 }
 
@@ -316,22 +319,35 @@ ShaderRenderCaseInstance::~ShaderRenderCaseInstance (void)
                VK_CHECK(vk.destroyBuffer(vkDevice, m_vertexBuffers[i]));
        }
 
+
        for (size_t i = 0; i < m_uniformInfos.size(); i++)
        {
-               VK_CHECK(vk.destroyBufferView(vkDevice, m_uniformInfos[i].view));
-               VK_CHECK(vk.freeMemory(vkDevice, m_uniformInfos[i].alloc->getMemory()));
-               VK_CHECK(vk.destroyBuffer(vkDevice, m_uniformInfos[i].buffer));
+               if (m_uniformInfos[i].type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
+               {
+                       VK_CHECK(vk.destroyBufferView(vkDevice, m_uniformInfos[i].descriptor.bufferView));
+                       VK_CHECK(vk.freeMemory(vkDevice, m_uniformInfos[i].alloc->getMemory()));
+                       VK_CHECK(vk.destroyBuffer(vkDevice, m_uniformInfos[i].buffer));
+               }
+               else if (m_uniformInfos[i].type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
+               {
+                       VK_CHECK(vk.destroyImageView(vkDevice, m_uniformInfos[i].descriptor.imageView));
+                       VK_CHECK(vk.destroySampler(vkDevice, m_uniformInfos[i].descriptor.sampler));
+               }
+               else
+                       DE_ASSERT(false);
        }
 }
 
 tcu::TestStatus ShaderRenderCaseInstance::iterate (void)
 {
+       setup();
+
        // Create quad grid.
        IVec2   viewportSize    = getViewportSize();
        int             width                   = viewportSize.x();
        int     height                  = viewportSize.y();
 
-       QuadGrid quadGrid(m_isVertexCase ? GRID_SIZE : 4, width, height, Vec4(0.125f, 0.25f, 0.5f, 1.0f), m_userAttribTransforms/*, m_textures*/);
+       QuadGrid quadGrid(m_isVertexCase ? GRID_SIZE : 4, width, height, Vec4(0.125f, 0.25f, 0.5f, 1.0f), m_userAttribTransforms, m_textures);
 
        // Render result.
        Surface resImage(width, height);
@@ -391,25 +407,23 @@ void ShaderRenderCaseInstance::setupUniformData (deUint32 bindingLocation, deUin
                size                                                                            // VkDeviceSize range;
        };
 
-       VkBufferView bufferView = createBufferView(vk, vkDevice, &viewInfo).disown();
+       Move<VkBufferView> bufferView = createBufferView(vk, vkDevice, &viewInfo);
 
        const VkDescriptorInfo descriptor =
        {
-               bufferView,                                                                     // VkBufferView         bufferView;
+               bufferView.disown(),                                            // VkBufferView         bufferView;
                0,                                                                                      // VkSampler            sampler;
                0,                                                                                      // VkImageView          imageView;
                0,                                                                                      // VkAttachmentView     attachmentView;
                (vk::VkImageLayout)0,                                           // VkImageLayout        imageLayout;
        };
 
-       const UniformInfo uniformInfo =
-       {
-               buffer.disown(),                                                        // VkBuffer                     buffer;
-               alloc.release(),                                                        // Allocation*          alloc;
-               bufferView,                                                                     // VkBufferView         view;
-               descriptor,                                                                     // VkDescriptorInfo     descriptor
-               bindingLocation                                                         // deUint32             location;
-       };
+       UniformInfo uniformInfo;
+       uniformInfo.buffer = buffer.disown();
+       uniformInfo.alloc = alloc.release();
+       uniformInfo.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+       uniformInfo.descriptor = descriptor;
+       uniformInfo.location = bindingLocation;
 
        m_uniformInfos.push_back(uniformInfo);
 }
@@ -607,6 +621,77 @@ tcu::IVec2 ShaderRenderCaseInstance::getViewportSize (void) const
                                          de::min(m_renderSize.y(), MAX_RENDER_HEIGHT));
 }
 
+void ShaderRenderCaseInstance::useSampler2D (deUint32 bindingLocation, deUint32 textureID)
+{
+       const VkDevice                          vkDevice                        = m_context.getDevice();
+       const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
+
+       DE_ASSERT(textureID < m_textures.size());
+
+       const TextureBinding& textureBinding = m_textures[textureID];
+       const Texture2D* texture = textureBinding.get2D();
+       const tcu::Sampler& refSampler = textureBinding.getSampler();
+
+       // Create sampler
+       const VkSamplerCreateInfo samplerParams =
+       {
+               VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
+               DE_NULL,
+               mapTexFilter(refSampler.magFilter),
+               mapTexFilter(refSampler.minFilter),
+               mapTexMipmapMode(refSampler.minFilter),
+               mapWrapMode(refSampler.wrapS),
+               mapWrapMode(refSampler.wrapT),
+               mapWrapMode(refSampler.wrapR),
+               refSampler.lodThreshold,
+               1,
+               (refSampler.compare != tcu::Sampler::COMPAREMODE_NONE),
+               mapCompareMode(refSampler.compare),
+               0.0f,
+               0.0f,
+               VK_BORDER_COLOR_INT_OPAQUE_WHITE
+       };
+
+       Move<VkSampler> sampler = createSampler(vk, vkDevice, &samplerParams);
+
+       const VkImageViewCreateInfo viewParams =
+       {
+               .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+               .pNext = NULL,
+               .image = *texture->getVkTexture(),
+               .viewType = VK_IMAGE_VIEW_TYPE_2D,
+               .format = texture->getVkFormat(),
+               .channels = { VK_CHANNEL_SWIZZLE_R,
+                                               VK_CHANNEL_SWIZZLE_G,
+                                               VK_CHANNEL_SWIZZLE_B,
+                                               VK_CHANNEL_SWIZZLE_A },
+               .subresourceRange = { VK_IMAGE_ASPECT_COLOR, 0, 1, 0, 1 },
+       };
+
+       Move<VkImageView> imageView = createImageView(vk, vkDevice, &viewParams);
+
+       const vk::VkDescriptorInfo descriptor =
+       {
+               0,                                                                                      // VkBufferView         bufferView;
+               sampler.disown(),                                                       // VkSampler            sampler;
+               imageView.disown(),                                                     // VkImageView          imageView;
+               0,                                                                                      // VkAttachmentView     attachmentView;
+               vk::VK_IMAGE_LAYOUT_GENERAL,                            // VkImageLayout        imageLayout;
+       };
+
+       UniformInfo newUniformInfo;
+       m_uniformInfos.push_back(newUniformInfo);
+
+       UniformInfo& uniformInfo = m_uniformInfos[m_uniformInfos.size() - 1];
+
+       uniformInfo.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+       uniformInfo.descriptor = descriptor;
+       uniformInfo.location = bindingLocation;
+
+       m_descriptorSetLayoutBuilder.addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, vk::VK_SHADER_STAGE_FRAGMENT_BIT, &uniformInfo.descriptor.sampler);
+       m_descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
+}
+
 void ShaderRenderCaseInstance::setupDefaultInputs (const QuadGrid& quadGrid)
 {
        /* Configuration of the vertex input attributes:
@@ -767,7 +852,7 @@ void ShaderRenderCaseInstance::render (Surface& result, const QuadGrid& quadGrid
                for(deUint32 i = 0; i < m_uniformInfos.size(); i++)
                {
                        deUint32 location = m_uniformInfos[i].location;
-                       m_descriptorSetUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &m_uniformInfos[i].descriptor);
+                       m_descriptorSetUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(location), m_uniformInfos[i].type, &m_uniformInfos[i].descriptor);
                }
 
                m_descriptorSetUpdateBuilder.update(vk, vkDevice);
@@ -1060,6 +1145,41 @@ void ShaderRenderCaseInstance::render (Surface& result, const QuadGrid& quadGrid
                m_cmdBuffer = createCommandBuffer(vk, vkDevice, &cmdBufferParams);
 
                VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
+
+               // Add texture barrier
+               std::vector<VkImageMemoryBarrier> barriers;
+               std::vector<void*> barrierPtrs;
+
+               for(size_t i = 0; i < m_textures.size(); i++)
+               {
+                       const TextureBinding& textureBinding = m_textures[i];
+                       const Texture2D* texture = textureBinding.get2D();
+                       VkImageMemoryBarrier textureBarrier =
+                       {
+                               VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
+                               DE_NULL,
+                               VK_MEMORY_OUTPUT_HOST_WRITE_BIT | VK_MEMORY_OUTPUT_TRANSFER_BIT,
+                               0,
+                               VK_IMAGE_LAYOUT_UNDEFINED,
+                               VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
+                               queueFamilyIndex,
+                               queueFamilyIndex,
+                               *texture->getVkTexture(),
+                               {
+                                       VK_IMAGE_ASPECT_COLOR,
+                                       0,
+                                       1,
+                                       0,
+                                       0
+                               }
+                       };
+
+                       barriers.push_back(textureBarrier);
+                       barrierPtrs.push_back((void*)&barriers[i]);
+               }
+
+               vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, false, (deUint32)barrierPtrs.size(), (const void * const*)&barrierPtrs[0]);
+
                vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_RENDER_PASS_CONTENTS_INLINE);
 
                vk.cmdBindDynamicViewportState(*m_cmdBuffer, *m_viewportState);
index 0a762a7..e4a508b 100644 (file)
 #include "deMemory.h"
 #include "deUniquePtr.hpp"
 
-#include "vktTestCaseUtil.hpp"
-
 #include "vkDefs.hpp"
 #include "vkPrograms.hpp"
 #include "vkRef.hpp"
 #include "vkMemUtil.hpp"
 #include "vkBuilderUtil.hpp"
 
+#include "vktTestCaseUtil.hpp"
+#include "vktTexture.hpp"
+
 namespace vkt
 {
 namespace shaderrendercase
@@ -55,6 +56,31 @@ class QuadGrid;
 
 class TextureBinding
 {
+public:
+       enum Type
+       {
+               TYPE_NONE = 0,
+               TYPE_2D,
+               TYPE_CUBE_MAP,
+               TYPE_2D_ARRAY,
+               TYPE_3D,
+
+               TYPE_LAST
+       };
+
+                                                       TextureBinding          (const Texture2D* tex2D, const tcu::Sampler& sampler);
+
+       Type                                    getType                         (void) const { return m_type;           }
+       const tcu::Sampler&             getSampler                      (void) const { return m_sampler;        }
+       const Texture2D*                get2D                           (void) const { DE_ASSERT(getType() == TYPE_2D);         return m_binding.tex2D; }
+
+private:
+       Type                                    m_type;
+       tcu::Sampler                    m_sampler;
+       union
+       {
+               const Texture2D*        tex2D;
+       } m_binding;
 };
 
 // ShaderEvalContext.
@@ -324,6 +350,8 @@ public:
                                                                                                                                                                        const T data);
        void                                                                                            useUniform                                      (deUint32 bindingLocation,
                                                                                                                                                                        BaseUniformType type);
+       void                                                                                            useSampler2D                            (deUint32 bindingLocation,
+                                                                                                                                                                       deUint32 textureId);
 
 protected:
        virtual void                                                                            setupShaderData                         (void);
@@ -334,11 +362,13 @@ protected:
 
        std::vector<tcu::Mat4>                                                          m_userAttribTransforms;
        tcu::Vec4                                                                                       m_clearColor;
+       std::vector<TextureBinding>                                                     m_textures;
 
        vk::SimpleAllocator                                                                     memAlloc;
 
 private:
 
+       void                                                                                            setupTextures                           (void);
        void                                                                                            setupUniformData                        (deUint32 bindingLocation, deUint32 size, const void* dataPtr);
        void                                                                                            setupDefaultInputs                      (const QuadGrid& quadGrid);
 
@@ -396,7 +426,7 @@ private:
        {
                vk::VkBuffer                            buffer;
                vk::Allocation*                         alloc;
-               vk::VkBufferView                        view;
+               vk::VkDescriptorType            type;
                vk::VkDescriptorInfo            descriptor;
                deUint32                                        location;
        };
index 5a2006f..c9a104a 100644 (file)
@@ -33,6 +33,7 @@
 #include "vktShaderRenderCaseTests.hpp"
 
 #include "vktShaderRenderCase.hpp"
+#include "vktTexture.hpp"
 
 #include "deUniquePtr.hpp"
 
@@ -42,6 +43,7 @@ namespace shaderrendercase
 {
 
 inline void eval_DEBUG      (ShaderEvalContext& c) { c.color = tcu::Vec4(1, 0, 1, 1); }
+inline void eval_DEBUG_TEX  (ShaderEvalContext& c) { c.color.xyz() = c.texture2D(0, c.coords.swizzle(0, 1)).swizzle(0,1,2); }
 
 void empty_uniform (ShaderRenderCaseInstance& /* instance */) {}
 
@@ -58,7 +60,6 @@ void dummy_uniforms (ShaderRenderCaseInstance& instance)
 {
        instance.useUniform(0u, UI_ZERO);
        instance.useUniform(1u, UI_ONE);
-       instance.useUniform(4u, UV4_WHITE);
        //instance.addUniform(1u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1.0f);
        //instance.addUniform(0u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0.5f);
        instance.addUniform(2u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, tcu::Vec4(1, 0.5f, 1.0f, 0.5f));
@@ -72,6 +73,7 @@ void dummy_uniforms (ShaderRenderCaseInstance& instance)
        };
 
        instance.addUniform<test_struct>(3u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, data);
+       instance.useSampler2D(4u, 0u);
 }
 
 void dummy_attributes (ShaderRenderCaseInstance& instance, deUint32 numVertices)
@@ -85,9 +87,41 @@ void dummy_attributes (ShaderRenderCaseInstance& instance, deUint32 numVertices)
 }
 
 
-class DummyShaderRenderCaseInstance;
+class DummyShaderRenderCaseInstance : public ShaderRenderCaseInstance
+{
+public:
+                                       DummyShaderRenderCaseInstance   (Context& context,
+                                                                                                       bool isVertexCase,
+                                                                                                       ShaderEvaluator& evaluator,
+                                                                                                       UniformSetupFunc uniformFunc,
+                                                                                                       AttributeSetupFunc attribFunc)
+                                               : ShaderRenderCaseInstance(context, isVertexCase, evaluator, uniformFunc, attribFunc)
+                                       {}
+
+       virtual                 ~DummyShaderRenderCaseInstance  (void)
+                                       {
+                                               delete m_brickTexture;
+                                               m_brickTexture = DE_NULL;
+                                       }
+
+protected:
+       virtual void    setup                                                   (void)
+                                       {
+                                               fprintf(stderr, "LOLOOLLLLL\n");
+                                               m_brickTexture = Texture2D::create(m_context, m_context.getTestContext().getArchive(), "data/brick.png");
+                                               m_textures.push_back(TextureBinding(m_brickTexture, tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE,
+                                                                                                                                                                               tcu::Sampler::CLAMP_TO_EDGE,
+                                                                                                                                                                               tcu::Sampler::CLAMP_TO_EDGE,
+                                                                                                                                                                               tcu::Sampler::LINEAR,
+                                                                                                                                                                               tcu::Sampler::LINEAR)));
+                                       }
+
+       Texture2D*              m_brickTexture;
+};
+
 
-class DummyTestRenderCase : public ShaderRenderCase<ShaderRenderCaseInstance>
+
+class DummyTestRenderCase : public ShaderRenderCase<DummyShaderRenderCaseInstance>
 {
 public:
        DummyTestRenderCase     (tcu::TestContext& testCtx,
@@ -137,8 +171,13 @@ tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx)
                "       highp vec2 f_3[2];\n"
                "};\n"
 
-               "out mediump vec4 v_color;\n"
-        "void main (void) { gl_Position = a_position; v_color = vec4(a_coords.xyz, f_1.a + f_2.a + f_3[0].x + f_3[1].x - (item ? item2 : 0)); }\n";
+               "layout(location=0) out mediump vec4 v_color;\n"
+               "layout(location=1) out mediump vec4 v_coords;\n"
+        "void main (void) { \n"
+               "       gl_Position = a_position;\n"
+               "       v_coords = a_coords;\n"
+               "       v_color = vec4(a_coords.xyz, f_1.a + f_2.a + f_3[0].x + f_3[1].x - (item ? item2 : 0));\n"
+               "}\n";
 
        std::string base_fragment = "#version 300 es\n"
         "layout(location = 0) out lowp vec4 o_color;\n"
@@ -149,18 +188,21 @@ tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx)
                "#extension GL_ARB_separate_shader_objects : enable\n"
                "#extension GL_ARB_shading_language_420pack : enable\n"
 
+               "layout(location=0) in vec4 v_color;\n"
+               "layout(location=1) in vec4 v_coords;\n"
         "layout(location = 0) out lowp vec4 o_color;\n"
 
-               "layout (set=0, binding=2) uniform buf {\n"
+               "layout (set=0, binding=3) uniform buf {\n"
                "       float item[4];\n"
                "};\n"
 
-        "in mediump vec4 v_color;\n"
-        "void main (void) { o_color = vec4(1,0,item[0],1); }\n";
+               "layout (set=0, binding=4) uniform sampler2D tex;\n"
+
+        "void main (void) { o_color = texture(tex, v_coords.xy); }\n";
 
 
        shaderRenderCaseTests->addChild(new DummyTestRenderCase(testCtx, "testVertex", "testVertex", true, evalCoordsPassthrough, base_vertex, base_fragment));
-       shaderRenderCaseTests->addChild(new DummyTestRenderCase(testCtx, "testFragment", "testFragment", false, eval_DEBUG, base_vertex, debug_fragment));
+       shaderRenderCaseTests->addChild(new DummyTestRenderCase(testCtx, "testFragment", "testFragment", false, eval_DEBUG_TEX, base_vertex, debug_fragment));
 
        return shaderRenderCaseTests.release();
 }
diff --git a/external/vulkancts/modules/vulkan/shaderrendercase/vktTexture.cpp b/external/vulkancts/modules/vulkan/shaderrendercase/vktTexture.cpp
new file mode 100644 (file)
index 0000000..534de0a
--- /dev/null
@@ -0,0 +1,329 @@
+/*------------------------------------------------------------------------
+ * Copyright (c) 2015 The Khronos Group Inc.
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included
+ * in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by Khronos,
+ * at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Vulkan Texture utilities
+ *//*--------------------------------------------------------------------*/
+
+#include "vktTexture.hpp"
+
+#include "deFilePath.hpp"
+#include "tcuImageIO.hpp"
+#include "tcuSurface.hpp"
+#include "tcuTextureUtil.hpp"
+
+#include "vkQueryUtil.hpp"
+#include "vkRefUtil.hpp"
+
+namespace vkt
+{
+
+static vk::VkFormat mapVkFormat(tcu::CompressedTexFormat format)
+{
+       switch (format)
+       {
+               // TODO!!
+               default:        return vk::VK_FORMAT_UNDEFINED;
+       }
+}
+
+static tcu::TextureFormat::ChannelType mapVkChannelType (deUint32 dataType, bool normalized)
+{
+       // TODO!!
+       switch (dataType)
+    {
+               default:        return normalized ? tcu::TextureFormat::UNORM_INT8      : tcu::TextureFormat::UNSIGNED_INT8;
+       }
+}
+
+static tcu::TextureFormat mapVkTransferFormat (deUint32 format, deUint32 dataType)
+{
+       // TODO!!
+       switch (format)
+       {
+               case vk::VK_FORMAT_R8G8B8_UNORM:        return tcu::TextureFormat(tcu::TextureFormat::RGB,              mapVkChannelType(dataType, true));
+               case vk::VK_FORMAT_R8G8B8A8_UNORM:
+               default:                                                        return tcu::TextureFormat(tcu::TextureFormat::RGBA,             mapVkChannelType(dataType, true));
+       }
+}
+
+static tcu::TextureFormat mapVkInternalFormat (vk::VkFormat format)
+{
+       switch (format)
+       {
+               // TODO!!
+               default:        return tcu::TextureFormat(tcu::TextureFormat::RGBA,             tcu::TextureFormat::FLOAT);
+       }
+}
+
+
+Texture2D::Texture2D (int numLevels, const tcu::CompressedTexture* levels, const tcu::TexDecompressionParams& decompressionParams)
+       : m_isCompressed        (true)
+       , m_format                      (mapVkFormat(levels[0].getFormat()))
+       , m_refTexture          (getUncompressedFormat(levels[0].getFormat()), levels[0].getWidth(), levels[0].getHeight())
+{
+       try
+       {
+               loadCompressed(numLevels, levels, decompressionParams);
+       }
+       catch (const std::exception&)
+       {
+               throw;
+       }
+}
+
+Texture2D::Texture2D (vk::VkFormat format, deUint32 dataType, int width, int height)
+       : m_isCompressed        (false)
+       , m_format                      (format)
+       , m_refTexture          (mapVkTransferFormat(format, dataType), width, height)
+{
+}
+
+
+Texture2D::Texture2D (vk::VkFormat format, int width, int height)
+       : m_isCompressed        (false)
+       , m_format                      (format)
+       , m_refTexture          (mapVkInternalFormat(format), width, height)
+{
+}
+
+Texture2D::~Texture2D (void)
+{
+}
+
+void Texture2D::upload (const Context& context)
+{
+       const vk::VkDevice vkDevice = context.getDevice();
+       const vk::DeviceInterface& vk = context.getDeviceInterface();
+       const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
+
+       vk::SimpleAllocator memAlloc(vk, vkDevice, vk::getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
+
+       const vk::VkImageCreateInfo imageCreateInfo =
+       {
+               vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                        // VkStructureType                      sType;
+               DE_NULL,                                                                                                        // const void*                          pnext;
+               vk::VK_IMAGE_TYPE_2D,                                                                           // VkImageType                          imageType;
+               m_format,                                                                                                       // VkFormat                                     format;
+               { m_refTexture.getWidth(), m_refTexture.getHeight(), 1 },       // VkExtend3D                           extent;
+               1u,                                                                                                                     // deUint32                                     mipLevels;
+               1u,                                                                                                                     // deUint32                                     arraySize;
+               1u,                                                                                                                     // deUint32                                     samples;
+               vk::VK_IMAGE_TILING_LINEAR,                                                                     // VkImageTiling                        tiling;
+               vk::VK_IMAGE_USAGE_SAMPLED_BIT,                                                         // VkImageUsageFlags            usage;
+               vk::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,                                        // VkImageCreateFlags           flags;
+               vk::VK_SHARING_MODE_EXCLUSIVE,                                                          // VkSharingMode                        sharingMode;
+               1,                                                                                                                      // deuint32                                     queueFamilyCount;
+               &queueFamilyIndex                                                                                       // const deUint32*                      pQueueFamilyIndices;
+       };
+
+       m_vkTexture = vk::createImage(vk, vkDevice, &imageCreateInfo);
+
+       // Allocate and bind color image memory
+       m_allocation = memAlloc.allocate(vk::getImageMemoryRequirements(vk, vkDevice, *m_vkTexture), vk::MemoryRequirement::HostVisible);
+       VK_CHECK(vk.bindImageMemory(vkDevice, *m_vkTexture, m_allocation->getMemory(), 0));
+
+       const vk::VkImageSubresource subres =
+       {
+               vk::VK_IMAGE_ASPECT_COLOR,
+               0u,
+               0u
+       };
+
+       vk::VkSubresourceLayout layout;
+       VK_CHECK(vk.getImageSubresourceLayout(vkDevice, *m_vkTexture, &subres, &layout));
+
+       void *imagePtr;
+       VK_CHECK(vk.mapMemory(vkDevice, m_allocation->getMemory(), m_allocation->getOffset(), layout.size, 0u, &imagePtr));
+
+       tcu::ConstPixelBufferAccess access = m_refTexture.getLevel(0);
+
+       deMemcpy(imagePtr, access.getDataPtr(), layout.size);
+
+       const vk::VkMappedMemoryRange range =
+       {
+               vk::VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,  //  VkStructureType sType;
+               DE_NULL,                                        //  const void*     pNext;
+               m_allocation->getMemory(),                              //  VkDeviceMemory  mem;
+               0,                                              //  VkDeviceSize    offset;
+               layout.size,                                                    //  VkDeviceSize    size;
+    };
+
+    VK_CHECK(vk.flushMappedMemoryRanges(vkDevice, 1u, &range));
+       VK_CHECK(vk.unmapMemory(vkDevice, m_allocation->getMemory()));
+}
+
+Texture2D* Texture2D::create (const Context& context, const tcu::Archive& archive, int numLevels, const char* const* levelFileNames)
+{
+       DE_ASSERT(numLevels > 0);
+
+       std::string ext = de::FilePath(levelFileNames[0]).getFileExtension();
+
+       if (ext == "png")
+       {
+               // Uncompressed texture.
+               tcu::TextureLevel level;
+
+               // Load level 0.
+               tcu::ImageIO::loadPNG(level, archive, levelFileNames[0]);
+
+               TCU_CHECK_INTERNAL(level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8) ||
+                                                       level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8));
+
+               bool isRGBA = (level.getFormat() == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8));
+               DE_UNREF(isRGBA);
+               // \todo [2015-09-07 elecro] use correct format based on the isRGBA value
+               Texture2D* texture = new Texture2D(/*isRGBA ? vk::VK_FORMAT_R8G8B8A8_UNORM :*/ vk::VK_FORMAT_R8G8B8A8_UNORM, /*GL_UNSIGNED_BYTE*/0, level.getWidth(), level.getHeight());
+
+               try
+               {
+                       // Fill level 0.
+                       texture->getRefTexture().allocLevel(0);
+
+                       tcu::copy(texture->getRefTexture().getLevel(0), level.getAccess());
+
+                       // Fill remaining levels.
+                       for (int levelNdx = 1; levelNdx < numLevels; levelNdx++)
+                       {
+                               tcu::ImageIO::loadPNG(level, archive, levelFileNames[levelNdx]);
+
+                               texture->getRefTexture().allocLevel(levelNdx);
+                               tcu::copy(texture->getRefTexture().getLevel(levelNdx), level.getAccess());
+                       }
+
+                       texture->upload(context);
+               }
+               catch (const std::exception&)
+               {
+                       delete texture;
+                       throw;
+               }
+
+               return texture;
+       }
+       else
+               TCU_FAIL("Unsupported file format"); // TODO: maybe support pkm?
+}
+
+
+void Texture2D::loadCompressed (int numLevels, const tcu::CompressedTexture* levels, const tcu::TexDecompressionParams& decompressionParams)
+{
+       DE_UNREF(numLevels);
+       DE_UNREF(levels);
+       DE_UNREF(decompressionParams);
+
+       for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
+       {
+               const tcu::CompressedTexture& level = levels[levelNdx];
+
+               // Decompress to reference texture.
+               m_refTexture.allocLevel(levelNdx);
+               tcu::PixelBufferAccess refLevelAccess = m_refTexture.getLevel(levelNdx);
+               TCU_CHECK(level.getWidth()  == refLevelAccess.getWidth() &&
+                                 level.getHeight() == refLevelAccess.getHeight());
+               level.decompress(refLevelAccess, decompressionParams);
+
+               // \todo [2015-09-07 elecro] add 'upload' logic for compressed image
+       }
+}
+
+
+vk::VkTexFilter mapTexFilter(const tcu::Sampler::FilterMode& filterMode)
+{
+       // \todo [2015-09-07 elecro] dobule check the mappings
+       switch(filterMode)
+       {
+               case tcu::Sampler::NEAREST:                                     return vk::VK_TEX_FILTER_NEAREST;
+               case tcu::Sampler::LINEAR:                                      return vk::VK_TEX_FILTER_LINEAR;
+               case tcu::Sampler::NEAREST_MIPMAP_NEAREST:      return vk::VK_TEX_FILTER_NEAREST;
+               case tcu::Sampler::LINEAR_MIPMAP_NEAREST:       return vk::VK_TEX_FILTER_NEAREST;
+               case tcu::Sampler::LINEAR_MIPMAP_LINEAR:        return vk::VK_TEX_FILTER_LINEAR;
+               default:
+                       DE_ASSERT(false);
+       }
+
+       return vk::VK_TEX_FILTER_NEAREST;
+}
+
+vk::VkTexMipmapMode mapTexMipmapMode(const tcu::Sampler::FilterMode& filterMode)
+{
+       // \todo [2015-09-07 elecro] dobule check the mappings
+       switch(filterMode)
+       {
+               case tcu::Sampler::NEAREST:                                     return vk::VK_TEX_MIPMAP_MODE_BASE;
+               case tcu::Sampler::LINEAR:                                      return vk::VK_TEX_MIPMAP_MODE_BASE;
+               case tcu::Sampler::NEAREST_MIPMAP_NEAREST:      return vk::VK_TEX_MIPMAP_MODE_NEAREST;
+               case tcu::Sampler::LINEAR_MIPMAP_NEAREST:       return vk::VK_TEX_MIPMAP_MODE_NEAREST;
+               case tcu::Sampler::LINEAR_MIPMAP_LINEAR:        return vk::VK_TEX_MIPMAP_MODE_LINEAR;
+               default:
+                       DE_ASSERT(false);
+       }
+
+       return vk::VK_TEX_MIPMAP_MODE_BASE;
+}
+
+vk::VkTexAddress mapWrapMode(const tcu::Sampler::WrapMode& wrapMode)
+{
+       // \todo [2015-09-07 elecro] dobule check the mappings
+       switch(wrapMode)
+       {
+               case tcu::Sampler::CLAMP_TO_EDGE:               return vk::VK_TEX_ADDRESS_CLAMP;
+               case tcu::Sampler::CLAMP_TO_BORDER:             return vk::VK_TEX_ADDRESS_CLAMP_BORDER;
+               case tcu::Sampler::REPEAT_GL:                   return vk::VK_TEX_ADDRESS_WRAP;
+               case tcu::Sampler::REPEAT_CL:                   return vk::VK_TEX_ADDRESS_WRAP;
+               case tcu::Sampler::MIRRORED_REPEAT_GL:  return vk::VK_TEX_ADDRESS_MIRROR;
+               case tcu::Sampler::MIRRORED_REPEAT_CL:  return vk::VK_TEX_ADDRESS_MIRROR;
+               default:
+                       DE_ASSERT(false);
+       }
+
+       return vk::VK_TEX_ADDRESS_WRAP;
+}
+
+vk::VkCompareOp mapCompareMode(const tcu::Sampler::CompareMode& mode)
+{
+       // \todo [2015-09-07 elecro] dobule check the mappings
+       switch(mode)
+       {
+               case tcu::Sampler::COMPAREMODE_NONE:                            return vk::VK_COMPARE_OP_NEVER;
+               case tcu::Sampler::COMPAREMODE_LESS:                            return vk::VK_COMPARE_OP_LESS;
+               case tcu::Sampler::COMPAREMODE_LESS_OR_EQUAL:           return vk::VK_COMPARE_OP_LESS_EQUAL;
+               case tcu::Sampler::COMPAREMODE_GREATER:                         return vk::VK_COMPARE_OP_GREATER;
+               case tcu::Sampler::COMPAREMODE_GREATER_OR_EQUAL:        return vk::VK_COMPARE_OP_GREATER_EQUAL;
+               case tcu::Sampler::COMPAREMODE_EQUAL:                           return vk::VK_COMPARE_OP_EQUAL;
+               case tcu::Sampler::COMPAREMODE_NOT_EQUAL:                       return vk::VK_COMPARE_OP_NOT_EQUAL;
+               case tcu::Sampler::COMPAREMODE_ALWAYS:                          return vk::VK_COMPARE_OP_ALWAYS;
+               case tcu::Sampler::COMPAREMODE_NEVER:                           return vk::VK_COMPARE_OP_NEVER;
+               default:
+                       DE_ASSERT(false);
+       }
+
+       return vk::VK_COMPARE_OP_NEVER;
+}
+
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/shaderrendercase/vktTexture.hpp b/external/vulkancts/modules/vulkan/shaderrendercase/vktTexture.hpp
new file mode 100644 (file)
index 0000000..6236935
--- /dev/null
@@ -0,0 +1,107 @@
+#ifndef _VKTTEXTURE_HPP
+#define _VKTTEXTURE_HPP
+/*------------------------------------------------------------------------
+ * Copyright (c) 2015 The Khronos Group Inc.
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included
+ * in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by Khronos,
+ * at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Vulkan Texture utilities
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuCompressedTexture.hpp"
+#include "tcuTexture.hpp"
+#include "tcuResource.hpp"
+
+#include "deUniquePtr.hpp"
+
+#include "vkDefs.hpp"
+#include "vkRef.hpp"
+#include "vkMemUtil.hpp"
+
+#include "vktTestCase.hpp"
+
+namespace vkt
+{
+
+class Texture2D
+{
+public:
+                                                                       Texture2D                               (int numLevels,
+                                                                                                                       const tcu::CompressedTexture* levels,
+                                                                                                                       const tcu::TexDecompressionParams& decompressionParams = tcu::TexDecompressionParams());
+                                                                       Texture2D                               (vk::VkFormat format,
+                                                                                                                       deUint32 dataType,
+                                                                                                                       int width,
+                                                                                                                       int height);
+                                                                       Texture2D                               (vk::VkFormat format,
+                                                                                                                       int width,
+                                                                                                                       int height);
+                                                                       ~Texture2D                              (void);
+
+       tcu::Texture2D&                                 getRefTexture                   (void)                  { return m_refTexture; }
+       const tcu::Texture2D&                   getRefTexture                   (void) const    { return m_refTexture; }
+       const vk::VkImage*                              getVkTexture                    (void) const    { return &m_vkTexture.get(); }
+       vk::VkFormat                                    getVkFormat                             (void) const    { return (vk::VkFormat)m_format; }
+
+
+       static Texture2D*                               create                                  (const Context& context,
+                                                                                                                       const tcu::Archive& archive,
+                                                                                                                       int numLevels,
+                                                                                                                       const char* const* levelFileNames);
+       static Texture2D*                               create                                  (const Context& context,
+                                                                                                                       const tcu::Archive& archive,
+                                                                                                                       const char* filename)
+                                                                                                                       { return Texture2D::create(context, archive, 1, &filename); }
+
+private:
+                                                                       Texture2D                               (const Texture2D& other);       // Not allowed!
+       Texture2D&                                              operator=                               (const Texture2D& other);       // Not allowed!
+
+
+       void                                                    upload                                  (const Context& context);
+
+       void                                                    loadCompressed                  (int numLevels,
+                                                                                                                       const tcu::CompressedTexture* levels,
+                                                                                                                       const tcu::TexDecompressionParams& decompressionParams);
+
+       bool                                                    m_isCompressed;
+       vk::VkFormat                                    m_format;
+       tcu::Texture2D                                  m_refTexture;
+       vk::Move<vk::VkImage>                   m_vkTexture;
+
+       de::MovePtr<vk::Allocation>             m_allocation;
+};
+
+
+vk::VkTexFilter mapTexFilter(const tcu::Sampler::FilterMode& filterMode);
+vk::VkTexMipmapMode mapTexMipmapMode(const tcu::Sampler::FilterMode& filterMode);
+vk::VkTexAddress mapWrapMode(const tcu::Sampler::WrapMode& wrapMode);
+vk::VkCompareOp mapCompareMode(const tcu::Sampler::CompareMode& mode);
+
+} // vkt
+
+#endif // _VKTSHADERRENDERCASE_HPP