From fff1669b6f2f1bea51d47614fbd41571b4cb68a0 Mon Sep 17 00:00:00 2001 From: Toni Merilehti Date: Tue, 19 Mar 2019 16:38:16 +0200 Subject: [PATCH] Reduce memory usage in point size clamping tests Win32 builds running dEQP-VK.rasterization.primitive_size.points.* caused resource errors when using 16384 x 16384 render targes due to large memory allocations. This optimization changes the rendering format from R8G8B8A8 to a single-channel format R8_UNORM, reduces the sizes of the render targets on the last two test cases to 10240 x 10240 and 9216 x 9216, and removes one unnecessary result buffer copy to reduce memory allocation. Affects: dEQP-VK.rasterization.primitive_size.points.* Components: Vulkan VK-GL-CTS issue: 1649 Change-Id: I5d9f435961f0cd56f8b520ac7e98cece1d4f73d7 --- .../vulkan/rasterization/vktRasterizationTests.cpp | 216 ++++++++++++++++++--- 1 file changed, 186 insertions(+), 30 deletions(-) diff --git a/external/vulkancts/modules/vulkan/rasterization/vktRasterizationTests.cpp b/external/vulkancts/modules/vulkan/rasterization/vktRasterizationTests.cpp index 4fbd8ab..0b3e690 100644 --- a/external/vulkancts/modules/vulkan/rasterization/vktRasterizationTests.cpp +++ b/external/vulkancts/modules/vulkan/rasterization/vktRasterizationTests.cpp @@ -142,7 +142,7 @@ public: DEFAULT_RENDER_SIZE = 256 }; - BaseRenderingTestInstance (Context& context, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT, deUint32 renderSize = DEFAULT_RENDER_SIZE); + BaseRenderingTestInstance (Context& context, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT, deUint32 renderSize = DEFAULT_RENDER_SIZE, VkFormat imageFormat = VK_FORMAT_R8G8B8A8_UNORM); ~BaseRenderingTestInstance (void); protected: @@ -198,13 +198,13 @@ protected: const VkDeviceSize m_resultBufferSize; }; -BaseRenderingTestInstance::BaseRenderingTestInstance (Context& context, VkSampleCountFlagBits sampleCount, deUint32 renderSize) +BaseRenderingTestInstance::BaseRenderingTestInstance (Context& context, VkSampleCountFlagBits sampleCount, deUint32 renderSize, VkFormat imageFormat) : TestInstance (context) , m_renderSize (renderSize) , m_sampleCount (sampleCount) , m_subpixelBits (context.getDeviceProperties().limits.subPixelPrecisionBits) , m_multisampling (m_sampleCount != VK_SAMPLE_COUNT_1_BIT) - , m_imageFormat (VK_FORMAT_R8G8B8A8_UNORM) + , m_imageFormat (imageFormat) , m_textureFormat (vk::mapVkFormat(m_imageFormat)) , m_uniformBufferSize (sizeof(float)) , m_resultBufferSize (renderSize * renderSize * m_textureFormat.getPixelSize()) @@ -1250,40 +1250,43 @@ public: virtual float getPointSize (void) const; private: - void generatePointData (std::vector& outData, std::vector& outPoints); - bool verifyPoint (tcu::TestLog& log, tcu::Surface image, float pointSize); + void generatePointData (PointSceneSpec::ScenePoint& outPoint); + void drawPoint (tcu::PixelBufferAccess& result, tcu::PointSceneSpec::ScenePoint& point); + bool verifyPoint (tcu::TestLog& log, tcu::PixelBufferAccess& access, float pointSize); bool isPointSizeClamped (float pointSize, float maxPointSizeLimit); const float m_pointSize; const float m_maxPointSize; const deUint32 m_renderSize; + const VkFormat m_format; }; PointSizeTestInstance::PointSizeTestInstance (Context& context, deUint32 renderSize, float pointSize) - : BaseRenderingTestInstance (context, vk::VK_SAMPLE_COUNT_1_BIT, renderSize) + : BaseRenderingTestInstance (context, vk::VK_SAMPLE_COUNT_1_BIT, renderSize, VK_FORMAT_R8_UNORM) , m_pointSize (pointSize) , m_maxPointSize (context.getDeviceProperties().limits.pointSizeRange[1]) , m_renderSize (renderSize) + , m_format (VK_FORMAT_R8_UNORM) // Use single-channel format to minimize memory allocation when using large render targets { } tcu::TestStatus PointSizeTestInstance::iterate (void) { - tcu::Surface resultImage (m_renderSize, m_renderSize); - std::vector drawBuffer; - std::vector points; + tcu::TextureLevel resultBuffer (mapVkFormat(m_format), m_renderSize, m_renderSize); + tcu::PixelBufferAccess access (resultBuffer.getAccess()); + PointSceneSpec::ScenePoint point; // Generate data - generatePointData(drawBuffer, points); + generatePointData(point); - // Draw image - drawPrimitives(resultImage, drawBuffer, VK_PRIMITIVE_TOPOLOGY_POINT_LIST); + // Draw + drawPoint(access, point); // Compare { // pointSize must either be specified pointSize or clamped to device limit pointSizeRange[1] const float pointSize (deFloatMin(m_pointSize, m_maxPointSize)); - const bool compareOk (verifyPoint(m_context.getTestContext().getLog(), resultImage, pointSize)); + const bool compareOk (verifyPoint(m_context.getTestContext().getLog(), access, pointSize)); // Result if (compareOk) @@ -1298,27 +1301,180 @@ float PointSizeTestInstance::getPointSize (void) const return m_pointSize; } -void PointSizeTestInstance::generatePointData (std::vector& outData, std::vector& outPoints) +void PointSizeTestInstance::generatePointData (PointSceneSpec::ScenePoint& outPoint) { const tcu::PointSceneSpec::ScenePoint point = { tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), // position - tcu::Vec4(1.0f), // color + tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f), // color m_pointSize // pointSize }; - outData.push_back(point.position); - outPoints.push_back(point); + outPoint = point; // log - m_context.getTestContext().getLog() << tcu::TestLog::Message << "Point position: " << de::toString(point.position) << tcu::TestLog::EndMessage; - m_context.getTestContext().getLog() << tcu::TestLog::Message << "Point color: " << de::toString(point.color) << tcu::TestLog::EndMessage; - m_context.getTestContext().getLog() << tcu::TestLog::Message << "Point size: " << de::toString(point.pointSize) << tcu::TestLog::EndMessage; - m_context.getTestContext().getLog() << tcu::TestLog::Message << "Render size: " << de::toString(m_renderSize) << tcu::TestLog::EndMessage; + { + tcu::TestLog& log = m_context.getTestContext().getLog(); + + log << tcu::TestLog::Message << "Point position: " << de::toString(point.position) << tcu::TestLog::EndMessage; + log << tcu::TestLog::Message << "Point color: " << de::toString(point.color) << tcu::TestLog::EndMessage; + log << tcu::TestLog::Message << "Point size: " << de::toString(point.pointSize) << tcu::TestLog::EndMessage; + log << tcu::TestLog::Message << "Render size: " << de::toString(m_renderSize) << tcu::TestLog::EndMessage; + log << tcu::TestLog::Message << "Format: " << de::toString(m_format) << tcu::TestLog::EndMessage; + } +} + +void PointSizeTestInstance::drawPoint (tcu::PixelBufferAccess& result, PointSceneSpec::ScenePoint& point) +{ + const tcu::Vec4 positionData (point.position); + const tcu::Vec4 colorData (point.color); + + const DeviceInterface& vkd (m_context.getDeviceInterface()); + const VkDevice vkDevice (m_context.getDevice()); + const VkQueue queue (m_context.getUniversalQueue()); + const deUint32 queueFamilyIndex (m_context.getUniversalQueueFamilyIndex()); + const size_t attributeBatchSize (sizeof(tcu::Vec4)); + Allocator& allocator (m_context.getDefaultAllocator()); + + Move commandBuffer; + Move graphicsPipeline; + Move vertexBuffer; + de::MovePtr vertexBufferMemory; + + // Create Graphics Pipeline + { + const std::vector viewports (1, makeViewport(tcu::UVec2(m_renderSize))); + const std::vector scissors (1, makeRect2D(tcu::UVec2(m_renderSize))); + + const VkVertexInputBindingDescription vertexInputBindingDescription = + { + 0u, // deUint32 binding; + sizeof(tcu::Vec4), // deUint32 strideInBytes; + VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate; + }; + + const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] = + { + { + 0u, // deUint32 location; + 0u, // deUint32 binding; + VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; + 0u // deUint32 offsetInBytes; + }, + { + 1u, // deUint32 location; + 0u, // deUint32 binding; + VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; + (deUint32)sizeof(tcu::Vec4) // deUint32 offsetInBytes; + } + }; + + const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = + { + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0, // VkPipelineVertexInputStateCreateFlags flags; + 1u, // deUint32 bindingCount; + &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; + 2u, // deUint32 attributeCount; + vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; + }; + + graphicsPipeline = makeGraphicsPipeline(vkd, // const DeviceInterface& vk + vkDevice, // const VkDevice device + *m_pipelineLayout, // const VkPipelineLayout pipelineLayout + *m_vertexShaderModule, // const VkShaderModule vertexShaderModule + DE_NULL, // const VkShaderModule tessellationControlShaderModule + DE_NULL, // const VkShaderModule tessellationEvalShaderModule + DE_NULL, // const VkShaderModule geometryShaderModule + *m_fragmentShaderModule, // const VkShaderModule fragmentShaderModule + *m_renderPass, // const VkRenderPass renderPass + viewports, // const std::vector& viewports + scissors, // const std::vector& scissors + VK_PRIMITIVE_TOPOLOGY_POINT_LIST, // const VkPrimitiveTopology topology + 0u, // const deUint32 subpass + 0u, // const deUint32 patchControlPoints + &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo + getRasterizationStateCreateInfo(), // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo + DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo + DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo, + getColorBlendStateCreateInfo()); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo + } + + // Create Vertex Buffer + { + const VkBufferCreateInfo vertexBufferParams = + { + VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkBufferCreateFlags flags; + attributeBatchSize * 2, // VkDeviceSize size; + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage; + VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; + 1u, // deUint32 queueFamilyCount; + &queueFamilyIndex // const deUint32* pQueueFamilyIndices; + }; + + vertexBuffer = createBuffer(vkd, vkDevice, &vertexBufferParams); + vertexBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible); + + VK_CHECK(vkd.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset())); + + // Load vertices into vertex buffer + deMemcpy(vertexBufferMemory->getHostPtr(), &positionData, attributeBatchSize); + deMemcpy(reinterpret_cast(vertexBufferMemory->getHostPtr()) + attributeBatchSize, &colorData, attributeBatchSize); + flushAlloc(vkd, vkDevice, *vertexBufferMemory); + } + + // Create Command Buffer + commandBuffer = allocateCommandBuffer(vkd, vkDevice, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); + + // Begin Command Buffer + beginCommandBuffer(vkd, *commandBuffer); + + addImageTransitionBarrier(*commandBuffer, *m_image, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask + 0, // VkAccessFlags srcAccessMask + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask + VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // VkImageLayout newLayout; + + // Begin Render Pass + beginRenderPass(vkd, *commandBuffer, *m_renderPass, *m_frameBuffer, vk::makeRect2D(0, 0, m_renderSize, m_renderSize), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); + + const VkDeviceSize vertexBufferOffset = 0; + + vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline); + vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &m_descriptorSet.get(), 0u, DE_NULL); + vkd.cmdBindVertexBuffers(*commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset); + vkd.cmdDraw(*commandBuffer, 1, 1, 0, 0); + endRenderPass(vkd, *commandBuffer); + + // Copy Image + copyImageToBuffer(vkd, *commandBuffer, *m_image, *m_resultBuffer, tcu::IVec2(m_renderSize, m_renderSize)); + + endCommandBuffer(vkd, *commandBuffer); + + // Set Point Size + { + float pointSize = getPointSize(); + + deMemcpy(m_uniformBufferMemory->getHostPtr(), &pointSize, (size_t)m_uniformBufferSize); + flushAlloc(vkd, vkDevice, *m_uniformBufferMemory); + } + + // Submit + submitCommandsAndWait(vkd, vkDevice, queue, commandBuffer.get()); + + invalidateAlloc(vkd, vkDevice, *m_resultBufferMemory); + tcu::copy(result, tcu::ConstPixelBufferAccess(m_textureFormat, tcu::IVec3(m_renderSize, m_renderSize, 1), m_resultBufferMemory->getHostPtr())); } -bool PointSizeTestInstance::verifyPoint (tcu::TestLog& log, tcu::Surface image, float pointSize) +bool PointSizeTestInstance::verifyPoint (tcu::TestLog& log, tcu::PixelBufferAccess& image, float pointSize) { + const float expectedPointColor (1.0f); + const float expectedBackgroundColor (0.0f); deUint32 pointWidth (0u); deUint32 pointHeight (0u); bool incorrectlyColoredPixelsFound (false); @@ -1327,24 +1483,24 @@ bool PointSizeTestInstance::verifyPoint (tcu::TestLog& log, tcu::Surface image, // Verify rasterized point width and color for (size_t x = 0; x < (deUint32)image.getWidth(); x++) { - tcu::Vec4 pixelColor = image.getAccess().getPixel((deUint32)x, image.getHeight() / 2); + float pixelColor = image.getPixel((deUint32)x, image.getHeight() / 2).x(); - if (pixelColor == tcu::Vec4(1.0f)) + if (pixelColor == expectedPointColor) pointWidth++; - if ((pixelColor != tcu::Vec4(1.0f)) && (pixelColor != tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f))) + if ((pixelColor != expectedPointColor) && (pixelColor != expectedBackgroundColor)) incorrectlyColoredPixelsFound = true; } // Verify rasterized point height and color for (size_t y = 0; y < (deUint32)image.getHeight(); y++) { - tcu::Vec4 pixelColor = image.getAccess().getPixel((deUint32)y, image.getWidth() / 2); + float pixelColor = image.getPixel((deUint32)y, image.getWidth() / 2).x(); - if (pixelColor == tcu::Vec4(1.0f)) + if (pixelColor == expectedPointColor) pointHeight++; - if ((pixelColor != tcu::Vec4(1.0f)) && (pixelColor != tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f))) + if ((pixelColor != expectedPointColor) && (pixelColor != expectedBackgroundColor)) incorrectlyColoredPixelsFound = true; } @@ -3332,8 +3488,8 @@ void createRasterizationTests (tcu::TestCaseGroup* rasterizationTests) { 2048, 1024.0f }, { 4096, 2048.0f }, { 8192, 4096.0f }, - { 16384, 8192.0f }, - { 16384, 10000.0f } + { 9216, 8192.0f }, + { 10240, 10000.0f } }; for (size_t testCombNdx = 0; testCombNdx < DE_LENGTH_OF_ARRAY(testCombinations); testCombNdx++) -- 2.7.4