blob: b035604c1e565d79a2a4eb55e96c6dca3ac08af1 [file] [log] [blame]
/*------------------------------------------------------------------------
* Vulkan Conformance Tests
* ------------------------
*
* Copyright (c) 2016 The Khronos Group Inc.
* Copyright (c) 2016 The Android Open Source Project
*
* 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 Geometry Basic Class
*//*--------------------------------------------------------------------*/
#include "vktGeometryBasicClass.hpp"
#include "vkDefs.hpp"
#include "vktTestCase.hpp"
#include "vktTestCaseUtil.hpp"
#include "vkBarrierUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkPrograms.hpp"
#include "vkBuilderUtil.hpp"
#include "vkRefUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkMemUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"
#include <string>
namespace vkt
{
namespace geometry
{
using namespace vk;
using tcu::IVec2;
using tcu::Vec4;
using tcu::TestStatus;
using tcu::TestContext;
using tcu::TestCaseGroup;
using de::MovePtr;
using std::string;
using std::vector;
using std::size_t;
static const int TEST_CANVAS_SIZE = 256;
GeometryExpanderRenderTestInstance::GeometryExpanderRenderTestInstance (Context& context,
const VkPrimitiveTopology primitiveType,
const char* name)
: TestInstance (context)
, m_primitiveType (primitiveType)
, m_name (name)
, m_numDrawVertices (0)
{
}
tcu::TestStatus GeometryExpanderRenderTestInstance::iterate (void)
{
const DeviceInterface& vk = m_context.getDeviceInterface();
const VkDevice device = m_context.getDevice();
const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
const VkQueue queue = m_context.getUniversalQueue();
Allocator& memAlloc = m_context.getDefaultAllocator();
const IVec2 resolution = IVec2(TEST_CANVAS_SIZE, TEST_CANVAS_SIZE);
const VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
const Image colorAttachmentImage (
vk,
device,
memAlloc,
makeImageCreateInfo(resolution, colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT),
MemoryRequirement::Any
);
const Unique<VkRenderPass> renderPass (makeRenderPass(vk, device, colorFormat));
const Move<VkPipelineLayout> pipelineLayout (createPipelineLayout(vk, device));
const VkImageSubresourceRange colorSubRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
const Unique<VkImageView> colorAttachmentView (makeImageView(vk, device, *colorAttachmentImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubRange));
const Unique<VkFramebuffer> framebuffer (makeFramebuffer(vk, device, *renderPass, *colorAttachmentView, resolution.x(), resolution.y(), 1u));
const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
const VkDeviceSize vertexDataSizeBytes = sizeInBytes(m_vertexPosData) + sizeInBytes(m_vertexAttrData);
const deUint32 vertexPositionsOffset = 0u;
const deUint32 vertexAtrrOffset = static_cast<deUint32>(sizeof(Vec4));
const string geometryShaderName = (m_context.getBinaryCollection().contains("geometry_pointsize") && checkPointSize (m_context.getInstanceInterface(), m_context.getPhysicalDevice()))?
"geometry_pointsize" : "geometry";
const Unique<VkPipeline> pipeline (GraphicsPipelineBuilder()
.setRenderSize (resolution)
.setShader (vk, device, VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("vertex"), DE_NULL)
.setShader (vk, device, VK_SHADER_STAGE_GEOMETRY_BIT, m_context.getBinaryCollection().get(geometryShaderName), DE_NULL)
.setShader (vk, device, VK_SHADER_STAGE_FRAGMENT_BIT, m_context.getBinaryCollection().get("fragment"), DE_NULL)
.addVertexBinding (makeVertexInputBindingDescription(0u, 2u*vertexAtrrOffset, VK_VERTEX_INPUT_RATE_VERTEX))
.addVertexAttribute (makeVertexInputAttributeDescription(0u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, vertexPositionsOffset))
.addVertexAttribute (makeVertexInputAttributeDescription(1u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, vertexAtrrOffset))
.setPrimitiveTopology (m_primitiveType)
.build (vk, device, *pipelineLayout, *renderPass));
const VkDeviceSize colorBufferSizeBytes = resolution.x()*resolution.y() * tcu::getPixelSize(mapVkFormat(colorFormat));
const Buffer colorBuffer (vk, device, memAlloc, makeBufferCreateInfo(colorBufferSizeBytes,
VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible);
const Buffer vertexBuffer (vk, device, memAlloc, makeBufferCreateInfo(vertexDataSizeBytes,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT ), MemoryRequirement::HostVisible);
{
const Allocation& alloc = vertexBuffer.getAllocation();
struct DataVec4
{
Vec4 pos;
Vec4 color;
};
DataVec4* const pData = static_cast<DataVec4*>(alloc.getHostPtr());
for(int ndx = 0; ndx < m_numDrawVertices; ++ndx)
{
pData[ndx].pos = m_vertexPosData[ndx];
pData[ndx].color = m_vertexAttrData[ndx];
}
flushAlloc(vk, device, alloc);
// No barrier needed, flushed memory is automatically visible
}
// Draw commands
beginCommandBuffer(vk, *cmdBuffer);
// Change color attachment image layout
{
const VkImageMemoryBarrier colorAttachmentLayoutBarrier = makeImageMemoryBarrier(
(VkAccessFlags)0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
*colorAttachmentImage, colorSubRange);
vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u,
0u, DE_NULL, 0u, DE_NULL, 1u, &colorAttachmentLayoutBarrier);
}
// Begin render pass
{
const VkRect2D renderArea = {
makeOffset2D(0, 0),
makeExtent2D(resolution.x(), resolution.y()),
};
const tcu::Vec4 clearColor(0.0f, 0.0f, 0.0f, 1.0f);
beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderArea, clearColor);
}
vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
{
const VkBuffer buffers[] = { vertexBuffer.get()};
const VkDeviceSize offsets[] = { vertexPositionsOffset };
vk.cmdBindVertexBuffers(*cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(buffers), buffers, offsets);
}
bindDescriptorSets(vk, device, memAlloc, *cmdBuffer, *pipelineLayout);
drawCommand (*cmdBuffer);
endRenderPass(vk, *cmdBuffer);
// Copy render result to a host-visible buffer
copyImageToBuffer(vk, *cmdBuffer, *colorAttachmentImage, *colorBuffer, resolution);
endCommandBuffer(vk, *cmdBuffer);
submitCommandsAndWait(vk, device, queue, *cmdBuffer);
{
// Log the result image.
const Allocation& colorBufferAlloc = colorBuffer.getAllocation();
invalidateAlloc(vk, device, colorBufferAlloc);
const tcu::ConstPixelBufferAccess imagePixelAccess(mapVkFormat(colorFormat), resolution.x(), resolution.y(), 1, colorBufferAlloc.getHostPtr());
if (!compareWithFileImage(m_context, imagePixelAccess, m_name))
return TestStatus::fail("Fail");
}
return TestStatus::pass("Pass");
}
Move<VkPipelineLayout> GeometryExpanderRenderTestInstance::createPipelineLayout (const DeviceInterface& vk, const VkDevice device)
{
return makePipelineLayout(vk, device);
}
void GeometryExpanderRenderTestInstance::drawCommand (const VkCommandBuffer& cmdBuffer)
{
const DeviceInterface& vk = m_context.getDeviceInterface();
vk.cmdDraw(cmdBuffer, static_cast<deUint32>(m_numDrawVertices), 1u, 0u, 0u);
}
} // geometry
} // vkt