#include "tcuRGBA.hpp"
#include <iostream>
+#include <functional>
+#include <set>
namespace vkt
{
TEST_TYPE_XFB_CLIPDISTANCE,
TEST_TYPE_XFB_CULLDISTANCE,
TEST_TYPE_XFB_CLIP_AND_CULL,
+ TEST_TYPE_LINE_LIST,
+ TEST_TYPE_LINE_STRIP,
+ TEST_TYPE_TRIANGLE_LIST,
+ TEST_TYPE_TRIANGLE_STRIP,
+ TEST_TYPE_TRIANGLE_FAN,
+ TEST_TYPE_LINE_LIST_ADJACENCY,
+ TEST_TYPE_LINE_STRIP_ADJACENCY,
TEST_TYPE_TRIANGLE_STRIP_ADJACENCY,
+ TEST_TYPE_TRIANGLE_LIST_ADJACENCY,
+ TEST_TYPE_PATCH_LIST,
TEST_TYPE_STREAMS_POINTSIZE,
TEST_TYPE_STREAMS_CLIPDISTANCE,
TEST_TYPE_STREAMS_CULLDISTANCE,
const VkPipelineLayout pipelineLayout,
const VkRenderPass renderPass,
const VkShaderModule vertexModule,
+ const VkShaderModule tessellationControlModule,
+ const VkShaderModule tessellationEvalModule,
const VkShaderModule geometryModule,
const VkShaderModule fragmendModule,
const VkExtent2D renderSize,
};
const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfoPtr = (rasterizationStreamPtr == DE_NULL) ? DE_NULL : &rasterizationStateCreateInfo;
- return makeGraphicsPipeline(vk, // const DeviceInterface& vk
- device, // const VkDevice device
- pipelineLayout, // const VkPipelineLayout pipelineLayout
- vertexModule, // const VkShaderModule vertexShaderModule
- DE_NULL, // const VkShaderModule tessellationControlModule
- DE_NULL, // const VkShaderModule tessellationEvalModule
- geometryModule, // const VkShaderModule geometryShaderModule
- fragmendModule, // const VkShaderModule fragmentShaderModule
- renderPass, // const VkRenderPass renderPass
- viewports, // const std::vector<VkViewport>& viewports
- scissors, // const std::vector<VkRect2D>& scissors
- topology, // const VkPrimitiveTopology topology
- subpass, // const deUint32 subpass
- 0u, // const deUint32 patchControlPoints
- vertexInputStateCreateInfoPtr, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
- rasterizationStateCreateInfoPtr); // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
+ return makeGraphicsPipeline(vk, // const DeviceInterface& vk
+ device, // const VkDevice device
+ pipelineLayout, // const VkPipelineLayout pipelineLayout
+ vertexModule, // const VkShaderModule vertexShaderModule
+ tessellationControlModule, // const VkShaderModule tessellationControlModule
+ tessellationEvalModule, // const VkShaderModule tessellationEvalModule
+ geometryModule, // const VkShaderModule geometryShaderModule
+ fragmendModule, // const VkShaderModule fragmentShaderModule
+ renderPass, // const VkRenderPass renderPass
+ viewports, // const std::vector<VkViewport>& viewports
+ scissors, // const std::vector<VkRect2D>& scissors
+ topology, // const VkPrimitiveTopology topology
+ subpass, // const deUint32 subpass
+ (tessellationEvalModule != DE_NULL) * 3u, // const deUint32 patchControlPoints
+ vertexInputStateCreateInfoPtr, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
+ rasterizationStateCreateInfoPtr); // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
}
VkImageCreateInfo makeImageCreateInfo (const VkImageCreateFlags flags, const VkImageType type, const VkFormat format, const VkExtent2D size, const deUint32 numLayers, const VkImageUsageFlags usage)
deUint32 getNextChunkSize (const deUint32 usedBytes, const deUint32 bufBytes);
std::vector<VkDeviceSize> generateSizesList (const size_t bufBytes, const size_t chunkCount);
std::vector<VkDeviceSize> generateOffsetsList (const std::vector<VkDeviceSize>& sizesList);
- void verifyTransformFeedbackBuffer (const MovePtr<Allocation>& bufAlloc, const deUint32 bufBytes);
+ void verifyTransformFeedbackBuffer (const MovePtr<Allocation>& bufAlloc,
+ const deUint32 bufBytes);
const bool m_extensions;
const VkExtent2D m_imageExtent2D;
return result;
}
-void TransformFeedbackTestInstance::verifyTransformFeedbackBuffer (const MovePtr<Allocation>& bufAlloc, const deUint32 bufBytes)
+void TransformFeedbackTestInstance::verifyTransformFeedbackBuffer (const MovePtr<Allocation>& bufAlloc,
+ const deUint32 bufBytes)
{
const DeviceInterface& vk = m_context.getDeviceInterface();
const VkDevice device = m_context.getDevice();
- invalidateMappedMemoryRange(vk, device, bufAlloc->getMemory(), bufAlloc->getOffset(), bufBytes);
+ invalidateMappedMemoryRange(vk, device, bufAlloc->getMemory(), bufAlloc->getOffset(), VK_WHOLE_SIZE);
const deUint32 numPoints = static_cast<deUint32>(bufBytes / sizeof(deUint32));
const deUint32* tfData = (deUint32*)bufAlloc->getHostPtr();
const Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, VK_FORMAT_UNDEFINED));
const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
const Unique<VkPipelineLayout> pipelineLayout (TransformFeedback::makePipelineLayout (vk, device));
- const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, m_imageExtent2D, 0u));
+ const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, DE_NULL, DE_NULL, m_imageExtent2D, 0u));
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 Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, VK_FORMAT_UNDEFINED));
const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
const Unique<VkPipelineLayout> pipelineLayout (TransformFeedback::makePipelineLayout (vk, device));
- const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, m_imageExtent2D, 0u));
+ const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, DE_NULL, DE_NULL, m_imageExtent2D, 0u));
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));
return tcu::TestStatus::pass("Pass");
}
-class TransformFeedbackTriangleStripWithAdjacencyTestInstance : public TransformFeedbackTestInstance
+class TransformFeedbackWindingOrderTestInstance : public TransformFeedbackTestInstance
{
public:
- TransformFeedbackTriangleStripWithAdjacencyTestInstance (Context& context, const TestParameters& parameters);
+ TransformFeedbackWindingOrderTestInstance(Context& context, const TestParameters& parameters);
+
+protected:
+ struct TopologyParameters
+ {
+ VkPrimitiveTopology topology;
+
+ // number of vertex in primitive; 2 for line, 3 for triangle
+ deUint32 vertexPerPrimitive;
+
+ // pointer to function calculating number of points that
+ // will be generated for given part count
+ std::function<deUint32(deUint32)> getNumGeneratedPoints;
+
+ // pointer to function generating expected values; parameter is
+ // primitive index, result array with expected data for primitive vertex
+ std::function<std::vector<deUint32>(deUint32)> getExpectedValuesForPrimitive;
+ };
+ typedef const std::map<TestType, TopologyParameters> TopologyParametersMap;
protected:
- tcu::TestStatus iterate (void);
- void verifyTransformFeedbackBuffer (const MovePtr<Allocation>& bufAlloc, const VkDeviceSize bufBytes);
+ const TopologyParametersMap& getTopologyParametersMap (void);
+ tcu::TestStatus iterate (void);
+ void verifyTransformFeedbackBuffer (const MovePtr<Allocation>& bufAlloc,
+ const deUint32 bufBytes);
+
+private:
+ TopologyParameters m_tParameters;
+ const bool m_requiresTesselationStage;
};
-TransformFeedbackTriangleStripWithAdjacencyTestInstance::TransformFeedbackTriangleStripWithAdjacencyTestInstance (Context& context, const TestParameters& parameters)
+TransformFeedbackWindingOrderTestInstance::TransformFeedbackWindingOrderTestInstance(Context& context, const TestParameters& parameters)
: TransformFeedbackTestInstance (context, parameters)
+ , m_requiresTesselationStage(parameters.testType == TEST_TYPE_PATCH_LIST)
{
+ if (m_requiresTesselationStage && !context.getDeviceFeatures().tessellationShader)
+ throw tcu::NotSupportedError("Tessellation shader not supported");
+
+ TopologyParametersMap topologyParametersMap = getTopologyParametersMap();
+ DE_ASSERT(topologyParametersMap.find(parameters.testType) != topologyParametersMap.end());
+ m_tParameters = topologyParametersMap.at(parameters.testType);
}
-tcu::TestStatus TransformFeedbackTriangleStripWithAdjacencyTestInstance::iterate (void)
+const TransformFeedbackWindingOrderTestInstance::TopologyParametersMap& TransformFeedbackWindingOrderTestInstance::getTopologyParametersMap(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& allocator = m_context.getDefaultAllocator();
+ static const TopologyParametersMap topologyParametersMap =
+ {
+ {
+ TEST_TYPE_LINE_LIST,
+ {
+ VK_PRIMITIVE_TOPOLOGY_LINE_LIST,
+ 2u,
+ [](deUint32 partCount) { return partCount; },
+ [](deUint32 i) { return std::vector<deUint32>{ 2 * i, 2 * i + 1u }; }
+ }
+ },
+ {
+ TEST_TYPE_LINE_STRIP,
+ {
+ VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,
+ 2u,
+ [](deUint32 partCount) { return 2u * (partCount - 1); },
+ [](deUint32 i) { return std::vector<deUint32>{ i, i + 1u }; }
+ }
+ },
+ {
+ TEST_TYPE_TRIANGLE_LIST,
+ {
+ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
+ 3u,
+ [](deUint32 partCount) { return partCount; },
+ [](deUint32 i) { return std::vector<deUint32>{ 3 * i, 3 * i + 1u, 3 * i + 2u }; }
+ }
+ },
+ {
+ TEST_TYPE_TRIANGLE_STRIP,
+ {
+ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
+ 3u,
+ [](deUint32 partCount) { return 3u * (partCount - 2); },
+ [](deUint32 i)
+ {
+ const deUint32 iMod2 = i % 2;
+ return std::vector<deUint32>{ i, i + 1 + iMod2, i + 2 - iMod2 };
+ }
+ }
+ },
+ {
+ TEST_TYPE_TRIANGLE_FAN,
+ {
+ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,
+ 3u,
+ [](deUint32 partCount) { return partCount; },
+ [](deUint32 i) { return std::vector<deUint32>{ i + 1, i + 2, 0 }; }
+ }
+ },
+ {
+ TEST_TYPE_LINE_LIST_ADJACENCY,
+ {
+ VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY,
+ 2u,
+ [](deUint32 partCount) { return partCount / 4u; }, // note: this cant be replaced with partCount / 2 as for partCount=6 we will get 3 instead of 2
+ [](deUint32 i) { return std::vector<deUint32>{ i + 1u, i + 2u }; }
+ }
+ },
+ {
+ TEST_TYPE_LINE_STRIP_ADJACENCY,
+ {
+ VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY,
+ 2u,
+ [](deUint32 partCount) { return 2u * (partCount - 3u); },
+ [](deUint32 i) { return std::vector<deUint32>{ i + 1u, i + 2u }; }
+ }
+ },
+ {
+ TEST_TYPE_TRIANGLE_LIST_ADJACENCY,
+ {
+ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY,
+ 3u,
+ [](deUint32 partCount) { return partCount / 2u; },
+ [](deUint32 i) { return std::vector<deUint32>{ 6 * i, 6 * i + 2u, 6 * i + 4u }; }
+ }
+ },
+ {
+ TEST_TYPE_TRIANGLE_STRIP_ADJACENCY,
+ {
+ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY,
+ 3u,
+ [](deUint32 partCount) { return 3u * (partCount / 2u - 2u); },
+ [](deUint32 i)
+ {
+ const bool even = (0 == i % 2);
+ if (even)
+ return std::vector<deUint32>{ 2 * i + 0, 2 * i + 2, 2 * i + 4 };
+ return std::vector<deUint32>{ 2 * i + 0, 2 * i + 4, 2 * i + 2 };
+ }
+ }
+ },
+ {
+ TEST_TYPE_PATCH_LIST,
+ {
+ VK_PRIMITIVE_TOPOLOGY_PATCH_LIST,
+ 9u,
+ [](deUint32 partCount) { return partCount * 3u; },
+ [](deUint32 i)
+ {
+ // we cant generate vertex numbers in tesselation evaluation shader;
+ // check if patch index is correct for every 9 generated vertex
+ return std::vector<deUint32>(9, i);
+ }
+ }
+ }
+ };
+ return topologyParametersMap;
+}
+
+tcu::TestStatus TransformFeedbackWindingOrderTestInstance::iterate (void)
+{
DE_ASSERT(m_parameters.partCount >= 6);
- const VkPrimitiveTopology topology (VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY);
- const Unique<VkShaderModule> vertexModule (createShaderModule (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
- const Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, VK_FORMAT_UNDEFINED));
- const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
- const Unique<VkPipelineLayout> pipelineLayout (TransformFeedback::makePipelineLayout (vk, device));
- const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, m_imageExtent2D, 0u, DE_NULL, topology));
- 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 DeviceInterface& vk = m_context.getDeviceInterface();
+ const VkDevice device = m_context.getDevice();
+ const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
+ const VkQueue queue = m_context.getUniversalQueue();
+ Allocator& allocator = m_context.getDefaultAllocator();
- const deUint32 numPrimitives = m_parameters.partCount / 2u - 2u;
- const deUint32 numPoints = 3u * numPrimitives;
- const VkDeviceSize bufferSize = numPoints * sizeof(deUint32);
- const VkBufferCreateInfo tfBufCreateInfo = makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
- const Move<VkBuffer> tfBuf = createBuffer(vk, device, &tfBufCreateInfo);
- const MovePtr<Allocation> tfBufAllocation = allocator.allocate(getBufferMemoryRequirements(vk, device, *tfBuf), MemoryRequirement::HostVisible);
- const VkMemoryBarrier tfMemoryBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, VK_ACCESS_HOST_READ_BIT);
- const VkDeviceSize tfBufBindingSize = bufferSize;
- const VkDeviceSize tfBufBindingOffset = 0u;
- const deUint32 startValue = 0u;
+ const Move<VkShaderModule> vertexModule(createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
+ Move<VkShaderModule> tescModule;
+ Move<VkShaderModule> teseModule;
+ if (m_requiresTesselationStage)
+ {
+ tescModule = createShaderModule(vk, device, m_context.getBinaryCollection().get("tesc"), 0u);
+ teseModule = createShaderModule(vk, device, m_context.getBinaryCollection().get("tese"), 0u);
+ }
+
+ const Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, VK_FORMAT_UNDEFINED));
+ const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
+ const Unique<VkPipelineLayout> pipelineLayout (TransformFeedback::makePipelineLayout (vk, device));
+ const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass,
+ *vertexModule,
+ m_requiresTesselationStage ? *tescModule : DE_NULL,
+ m_requiresTesselationStage ? *teseModule : DE_NULL,
+ DE_NULL,
+ DE_NULL,
+ m_imageExtent2D, 0u, DE_NULL, m_tParameters.topology));
+ 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 bufferSize = m_tParameters.getNumGeneratedPoints (m_parameters.partCount) * sizeof(deUint32);
+ const VkBufferCreateInfo tfBufCreateInfo = makeBufferCreateInfo (bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
+ const Move<VkBuffer> tfBuf = createBuffer (vk, device, &tfBufCreateInfo);
+ const MovePtr<Allocation> tfBufAllocation = allocator.allocate (getBufferMemoryRequirements(vk, device, *tfBuf), MemoryRequirement::HostVisible);
+ const VkMemoryBarrier tfMemoryBarrier = makeMemoryBarrier (VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, VK_ACCESS_HOST_READ_BIT);
+ const VkDeviceSize tfBufBindingSize = bufferSize;
+ const VkDeviceSize tfBufBindingOffset = 0u;
+ const deUint32 startValue = 0u;
VK_CHECK(vk.bindBufferMemory(device, *tfBuf, tfBufAllocation->getMemory(), tfBufAllocation->getOffset()));
endCommandBuffer(vk, *cmdBuffer);
submitCommandsAndWait(vk, device, queue, *cmdBuffer);
- verifyTransformFeedbackBuffer(tfBufAllocation, bufferSize);
+ verifyTransformFeedbackBuffer(tfBufAllocation, static_cast<deUint32>(bufferSize));
return tcu::TestStatus::pass("Pass");
}
-void TransformFeedbackTriangleStripWithAdjacencyTestInstance::verifyTransformFeedbackBuffer (const MovePtr<Allocation>& bufAlloc, const VkDeviceSize bufBytes)
+void TransformFeedbackWindingOrderTestInstance::verifyTransformFeedbackBuffer(const MovePtr<Allocation>& bufAlloc,
+ const deUint32 bufBytes)
{
- const DeviceInterface& vk = m_context.getDeviceInterface();
- const VkDevice device = m_context.getDevice();
+ const DeviceInterface& vk = m_context.getDeviceInterface();
+ const VkDevice device = m_context.getDevice();
invalidateMappedMemoryRange(vk, device, bufAlloc->getMemory(), bufAlloc->getOffset(), VK_WHOLE_SIZE);
- const deUint32 numPoints = static_cast<deUint32>(bufBytes / sizeof(deUint32));
- const deUint32* tfData = (deUint32*)bufAlloc->getHostPtr();
+ const deUint32 numPoints = static_cast<deUint32>(bufBytes / sizeof(deUint32));
+ const deUint32 vertexPerPrimitive = m_tParameters.vertexPerPrimitive;
+ const deUint32 numPrimitives = numPoints / vertexPerPrimitive;
+ const deUint32* tfData = (deUint32*)bufAlloc->getHostPtr();
- for (deUint32 dataNdx = 0; dataNdx + 2 < numPoints; dataNdx += 3)
+ for (deUint32 primitiveIndex = 0; primitiveIndex < numPrimitives; ++primitiveIndex)
{
- const deUint32 i = dataNdx / 3;
- const bool even = (0 == i % 2);
- deUint32 vertexNumbers[3];
- bool correctWinding = false;
-
- if (even)
- {
- vertexNumbers[0] = 2 * i + 0;
- vertexNumbers[1] = 2 * i + 2;
- vertexNumbers[2] = 2 * i + 4;
- }
- else
+ const deUint32* tfDataForPrimitive = &tfData[primitiveIndex * vertexPerPrimitive];
+ std::vector<deUint32> expectedDataForPrimitive = m_tParameters.getExpectedValuesForPrimitive(primitiveIndex);
+
+ // For multi - vertex primitives, all values for a given vertex are written before writing values for any other vertex.
+ // Implementations may write out any vertex within the primitive first, but all subsequent vertices for that primitive
+ // must be written out in a consistent winding order
+ bool correctWinding = true;
+ for (deUint32 combinationIndex = 0; combinationIndex < vertexPerPrimitive; combinationIndex++)
{
- vertexNumbers[0] = 2 * i + 0;
- vertexNumbers[1] = 2 * i + 4;
- vertexNumbers[2] = 2 * i + 2;
- }
+ correctWinding = true;
+ for (deUint32 vertexIndex = 0; vertexIndex < vertexPerPrimitive; vertexIndex++)
+ {
+ correctWinding &= (tfDataForPrimitive[vertexIndex] == expectedDataForPrimitive[(combinationIndex + vertexIndex) % vertexPerPrimitive]);
- for (deUint32 j = 0; j < 3 && !correctWinding; j++)
- {
- correctWinding = (tfData[dataNdx] == vertexNumbers[j] && tfData[dataNdx + 1] == vertexNumbers[(j+1) % 3] && tfData[dataNdx + 2] == vertexNumbers[(j+2) % 3]);
+ // if data for this vertex is not correct then there
+ // is no need to check other, go to next combination
+ if (!correctWinding)
+ break;
+ }
+
+ // no need to check other combinations, we found correct one
+ if (correctWinding)
+ break;
}
if (!correctWinding)
{
- TCU_FAIL(std::string("Failed at item ") + de::toString(dataNdx) +
- " received: " + de::toString(tfData[dataNdx]) + "," + de::toString(tfData[dataNdx + 1]) + "," + de::toString(tfData[dataNdx + 2]) +
- " expected: " + de::toString(vertexNumbers[0]) + "," + de::toString(vertexNumbers[1]) + "," + de::toString(vertexNumbers[2]) );
+ std::stringstream message;
+ message << "Failed at primitive " << primitiveIndex << " received: [";
+ for (deUint32 vertexIndex = 0; vertexIndex < vertexPerPrimitive; vertexIndex++)
+ message << de::toString(tfDataForPrimitive[vertexIndex]) << " ";
+ message << "] expected: [";
+ for (deUint32 vertexIndex = 0; vertexIndex < vertexPerPrimitive; vertexIndex++)
+ message << de::toString(expectedDataForPrimitive[vertexIndex]) << " ";
+ message << "]";
+ TCU_FAIL(message.str());
}
}
}
const Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, VK_FORMAT_UNDEFINED));
const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
const Unique<VkPipelineLayout> pipelineLayout (TransformFeedback::makePipelineLayout (vk, device));
- const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, m_imageExtent2D, 0u));
+ const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, DE_NULL, DE_NULL, m_imageExtent2D, 0u));
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 Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
const Unique<VkPipelineLayout> pipelineLayout (TransformFeedback::makePipelineLayout (vk, device));
- const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertexModule, *geomModule, DE_NULL, m_imageExtent2D, 0u));
+ const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, *geomModule, DE_NULL, m_imageExtent2D, 0u));
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 Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, *colorAttachment, m_imageExtent2D.width, m_imageExtent2D.height));
const Unique<VkPipelineLayout> pipelineLayout (TransformFeedback::makePipelineLayout (vk, device));
- const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertModule, *geomModule, *fragModule, m_imageExtent2D, 0u, &m_parameters.streamId));
+ const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertModule, DE_NULL, DE_NULL, *geomModule, *fragModule, m_imageExtent2D, 0u, &m_parameters.streamId));
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 Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, *colorAttachment, m_imageExtent2D.width, m_imageExtent2D.height));
const Unique<VkPipelineLayout> pipelineLayout (TransformFeedback::makePipelineLayout (vk, device));
- const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertModule, DE_NULL, *fragModule, m_imageExtent2D, 0u, DE_NULL, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, true));
+ const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertModule, DE_NULL, DE_NULL, DE_NULL, *fragModule, m_imageExtent2D, 0u, DE_NULL, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, true));
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 Unique<VkRenderPass> renderPass (TransformFeedback::makeRenderPass (vk, device));
const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
const Unique<VkPipelineLayout> pipelineLayout (TransformFeedback::makePipelineLayout (vk, device));
- const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, m_imageExtent2D, 0u));
+ const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, DE_NULL, DE_NULL, m_imageExtent2D, 0u));
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 Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
const Unique<VkPipelineLayout> pipelineLayout (TransformFeedback::makePipelineLayout (vk, device));
- const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertModule, *geomModule, DE_NULL, m_imageExtent2D, 0u));
+ const Unique<VkPipeline> pipeline (makeGraphicsPipeline (vk, device, *pipelineLayout, *renderPass, *vertModule, DE_NULL, DE_NULL, *geomModule, DE_NULL, m_imageExtent2D, 0u));
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));
if (m_parameters.testType == TEST_TYPE_XFB_CLIP_AND_CULL)
return new TransformFeedbackBuiltinTestInstance(context, m_parameters);
- if (m_parameters.testType == TEST_TYPE_TRIANGLE_STRIP_ADJACENCY)
- return new TransformFeedbackTriangleStripWithAdjacencyTestInstance(context, m_parameters);
+ static const std::set<TestType> windingTests =
+ {
+ TEST_TYPE_LINE_LIST,
+ TEST_TYPE_LINE_STRIP,
+ TEST_TYPE_TRIANGLE_LIST,
+ TEST_TYPE_TRIANGLE_STRIP,
+ TEST_TYPE_TRIANGLE_FAN,
+ TEST_TYPE_LINE_LIST_ADJACENCY,
+ TEST_TYPE_LINE_STRIP_ADJACENCY,
+ TEST_TYPE_TRIANGLE_STRIP_ADJACENCY,
+ TEST_TYPE_TRIANGLE_LIST_ADJACENCY,
+ TEST_TYPE_PATCH_LIST
+ };
+ if (windingTests.count(m_parameters.testType))
+ return new TransformFeedbackWindingOrderTestInstance(context, m_parameters);
if (m_parameters.testType == TEST_TYPE_STREAMS)
return new TransformFeedbackStreamsTestInstance(context, m_parameters);
const bool vertexShaderOnly = m_parameters.testType == TEST_TYPE_BASIC
|| m_parameters.testType == TEST_TYPE_RESUME
|| m_parameters.testType == TEST_TYPE_BACKWARD_DEPENDENCY
- || m_parameters.testType == TEST_TYPE_TRIANGLE_STRIP_ADJACENCY;
+ || m_parameters.testType == TEST_TYPE_LINE_LIST
+ || m_parameters.testType == TEST_TYPE_LINE_STRIP
+ || m_parameters.testType == TEST_TYPE_TRIANGLE_LIST
+ || m_parameters.testType == TEST_TYPE_TRIANGLE_STRIP
+ || m_parameters.testType == TEST_TYPE_TRIANGLE_FAN
+ || m_parameters.testType == TEST_TYPE_LINE_LIST_ADJACENCY
+ || m_parameters.testType == TEST_TYPE_LINE_STRIP_ADJACENCY
+ || m_parameters.testType == TEST_TYPE_TRIANGLE_STRIP_ADJACENCY
+ || m_parameters.testType == TEST_TYPE_TRIANGLE_LIST_ADJACENCY;
const bool requiresFullPipeline = m_parameters.testType == TEST_TYPE_STREAMS
|| m_parameters.testType == TEST_TYPE_STREAMS_POINTSIZE
|| m_parameters.testType == TEST_TYPE_STREAMS_CULLDISTANCE
- || m_parameters.testType == TEST_TYPE_STREAMS_CLIPDISTANCE;
+ || m_parameters.testType == TEST_TYPE_STREAMS_CLIPDISTANCE
+ || m_parameters.testType == TEST_TYPE_PATCH_LIST;
const bool xfbBuiltinPipeline = m_parameters.testType == TEST_TYPE_XFB_POINTSIZE
|| m_parameters.testType == TEST_TYPE_XFB_CLIPDISTANCE
|| m_parameters.testType == TEST_TYPE_XFB_CULLDISTANCE
return;
}
+ if (m_parameters.testType == TEST_TYPE_PATCH_LIST)
+ {
+ // Vertex shader
+ {
+ std::ostringstream src;
+ src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+ << "layout(push_constant) uniform pushConstants\n"
+ << "{\n"
+ << " uint start;\n"
+ << "} uInput;\n"
+ << "void main(void)\n"
+ << "{\n"
+ << " //idx_out = uInput.start + gl_VertexIndex;\n" // TODO
+ << "}\n";
+ programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
+ }
+
+ // Tesselation control shader
+ {
+ std::ostringstream src;
+ src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+ << "layout(vertices = 3) out;\n"
+ << "void main (void)\n"
+ << "{\n"
+ << " gl_TessLevelInner[0] = 2.0;\n" // generate three triangles out of each patch
+ << " gl_TessLevelOuter[0] = 1.0;\n"
+ << " gl_TessLevelOuter[1] = 1.0;\n"
+ << " gl_TessLevelOuter[2] = 1.0;\n"
+ << "}\n";
+ programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str());
+ }
+
+ // Tessellation evaluation shader
+ {
+ std::ostringstream src;
+ src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+ << "layout(triangles, ccw) in;\n"
+ << "layout(xfb_buffer = 0, xfb_offset = 0, xfb_stride = 4, location = 0) out uint idx_out;\n"
+ << "\n"
+ << "void main (void)\n"
+ << "{\n"
+ << " idx_out = gl_PrimitiveID;\n" // all vertex generated from patch will have its id
+ << "}\n";
+ programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str());
+ }
+
+ return;
+ }
+
if (xfbBuiltinPipeline)
{
const std::string outputBuiltIn = (m_parameters.testType == TEST_TYPE_XFB_POINTSIZE) ? "float gl_PointSize;\n"
{
const deUint32 bufferCounts[] = { 6, 8, 10, 12 };
- const TestType testTypes[] = { TEST_TYPE_TRIANGLE_STRIP_ADJACENCY };
- const std::string testTypeNames[] = { "triangle_strip_with_adjacency"};
+ const TestType testTypes[] =
+ {
+ // note: no need to test POINT_LIST as is tested in many tests
+ TEST_TYPE_LINE_LIST,
+ TEST_TYPE_LINE_STRIP,
+ TEST_TYPE_TRIANGLE_LIST,
+ TEST_TYPE_TRIANGLE_STRIP,
+ TEST_TYPE_TRIANGLE_FAN,
+ TEST_TYPE_LINE_LIST_ADJACENCY,
+ TEST_TYPE_LINE_STRIP_ADJACENCY,
+ TEST_TYPE_TRIANGLE_STRIP_ADJACENCY,
+ TEST_TYPE_TRIANGLE_LIST_ADJACENCY,
+ TEST_TYPE_PATCH_LIST
+ };
+ const std::string testTypeNames[] =
+ {
+ "winding_line_list",
+ "winding_line_strip",
+ "winding_triangle_list",
+ "winding_triangle_strip",
+ "winding_triangle_fan",
+ "winding_line_list_with_adjacency",
+ "winding_line_strip_with_adjacency",
+ "winding_triangle_strip_with_adjacency",
+ "winding_triangle_list_with_adjacency",
+ "winding_patch_list"
+ };
for (deUint32 testTypesNdx = 0; testTypesNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypesNdx)
{
for (deUint32 bufferCountsNdx = 0; bufferCountsNdx < DE_LENGTH_OF_ARRAY(bufferCounts); ++bufferCountsNdx)
{
- const deUint32 vertexCount = bufferCounts[bufferCountsNdx];
+ const deUint32 vertexCount = bufferCounts[bufferCountsNdx];
TestParameters parameters = { testType, 0u, vertexCount, 0u, 0u, 0u, STREAM_ID_0_NORMAL, false };
- group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_" + de::toString(vertexCount)).c_str(), "Triangle Strip With Adjacency Transform Feedback test", parameters));
- parameters.streamId0Mode = STREAM_ID_0_BEGIN_QUERY_INDEXED;
- group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_beginqueryindexed_streamid_0_" + de::toString(vertexCount)).c_str(), "Triangle Strip With Adjacency Transform Feedback test", parameters));
- parameters.streamId0Mode = STREAM_ID_0_END_QUERY_INDEXED;
- group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_endqueryindexed_streamid_0_" + de::toString(vertexCount)).c_str(), "Triangle Strip With Adjacency Transform Feedback test", parameters));
+ group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_" + de::toString(vertexCount)).c_str(), "Topology winding test", parameters));
}
}
}