set(DEQP_VK_SHADERRENDERCASE_SRCS
vktShaderRenderCase.cpp
vktShaderRenderCaseTests.cpp
+
+ vktTexture.cpp
)
set(DEQP_VK_SHADERRENDERCASE_LIBS
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; }
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]; }
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;
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);
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.
, isDiscarded(false)
, quadGrid(quadGrid_)
{
- // TODO...
-/*
const vector<TextureBinding>& bindings = quadGrid.getTextures();
DE_ASSERT((int)bindings.size() <= MAX_TEXTURES);
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)
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);
}
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);
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);
}
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:
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);
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);
#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
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.
const T data);
void useUniform (deUint32 bindingLocation,
BaseUniformType type);
+ void useSampler2D (deUint32 bindingLocation,
+ deUint32 textureId);
protected:
virtual void setupShaderData (void);
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);
{
vk::VkBuffer buffer;
vk::Allocation* alloc;
- vk::VkBufferView view;
+ vk::VkDescriptorType type;
vk::VkDescriptorInfo descriptor;
deUint32 location;
};
#include "vktShaderRenderCaseTests.hpp"
#include "vktShaderRenderCase.hpp"
+#include "vktTexture.hpp"
#include "deUniquePtr.hpp"
{
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 */) {}
{
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));
};
instance.addUniform<test_struct>(3u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, data);
+ instance.useSampler2D(4u, 0u);
}
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,
" 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"
"#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();
}
--- /dev/null
+/*------------------------------------------------------------------------
+ * 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
--- /dev/null
+#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