struct CaseDef
{
- PipelineConstructionType pipelineConstructionType;
+ SharedGroupParams groupParams;
deInt32 seed;
VkExtent2D framebufferDim;
VkSampleCountFlagBits samples;
bool shaderWritesRate;
bool geometryShader;
bool useDynamicState;
- bool useDynamicRendering;
bool useApiSampleMask;
bool useSampleMaskIn;
bool conservativeEnable;
class FSRTestInstance : public TestInstance
{
public:
- FSRTestInstance (Context& context, const CaseDef& data);
- ~FSRTestInstance (void);
- tcu::TestStatus iterate (void);
+ FSRTestInstance (Context& context, const CaseDef& data);
+ ~FSRTestInstance (void);
+ tcu::TestStatus iterate (void);
private:
// Test parameters
vector<VkPhysicalDeviceFragmentShadingRateKHR> m_supportedFragmentShadingRates;
VkPhysicalDeviceFragmentShadingRatePropertiesKHR m_shadingRateProperties;
+protected:
+
+ void beginSecondaryCmdBuffer (VkCommandBuffer cmdBuffer,
+ VkFormat cbFormat,
+ VkFormat dsFormat,
+ VkRenderingFlagsKHR renderingFlags = 0u) const;
+ void preRenderCommands (VkCommandBuffer cmdBuffer,
+ ImageWithMemory* cbImage,
+ ImageWithMemory* dsImage,
+ ImageWithMemory* derivImage,
+ deUint32 derivNumLevels,
+ ImageWithMemory* srImage,
+ VkImageLayout srLayout,
+ BufferWithMemory* srFillBuffer,
+ deUint32 numSRLayers,
+ deUint32 srWidth,
+ deUint32 srHeight,
+ deUint32 srFillBpp,
+ const VkClearValue& clearColor,
+ const VkClearValue& clearDepthStencil);
+ void beginRender (VkCommandBuffer cmdBuffer,
+ VkRenderPass renderPass,
+ VkFramebuffer framebuffer,
+ VkImageView srImageView,
+ VkImageLayout srImageLayout,
+ const VkExtent2D& srTexelSize,
+ VkImageView cbImageView,
+ VkImageView dsImageView,
+ bool imagelessFB,
+ const VkClearValue& clearColor,
+ const VkClearValue& clearDepthStencil,
+ VkRenderingFlagsKHR renderingFlags = 0u) const;
+ void drawCommands (VkCommandBuffer cmdBuffer,
+ std::vector<GraphicsPipelineWrapper>& pipelines,
+ const std::vector<VkViewport>& viewports,
+ const std::vector<VkRect2D>& scissors,
+ const VkPipelineLayout pipelineLayout,
+ const VkRenderPass renderPass,
+ const VkPipelineVertexInputStateCreateInfo* vertexInputState,
+ const VkPipelineDynamicStateCreateInfo* dynamicState,
+ const VkPipelineRasterizationStateCreateInfo* rasterizationState,
+ const VkPipelineDepthStencilStateCreateInfo* depthStencilState,
+ const VkPipelineMultisampleStateCreateInfo* multisampleState,
+ VkPipelineFragmentShadingRateStateCreateInfoKHR* shadingRateState,
+ VkPipelineRenderingCreateInfoKHR* dynamicRendering,
+ const VkShaderModule vertShader,
+ const VkShaderModule geomShader,
+ const VkShaderModule fragShader,
+ VkDescriptorSet descriptorSet,
+ VkBuffer vertexBuffer);
+ void endRender (VkCommandBuffer cmdBuffer) const;
+
deInt32 PrimIDToPrimitiveShadingRate (deInt32 primID);
deInt32 PrimIDToPipelineShadingRate (deInt32 primID);
- VkExtent2D SanitizeExtent (VkExtent2D ext) const;
- deInt32 SanitizeRate (deInt32 rate) const;
+ VkExtent2D SanitizeExtent (VkExtent2D ext) const;
+ deInt32 SanitizeRate (deInt32 rate) const;
deInt32 ShadingRateExtentToClampedMask (VkExtent2D ext, bool allowSwap) const;
- deInt32 ShadingRateExtentToEnum (VkExtent2D ext) const;
- VkExtent2D ShadingRateEnumToExtent (deInt32 rate) const;
- deInt32 Simulate (deInt32 rate0, deInt32 rate1, deInt32 rate2);
- VkExtent2D Combine (VkExtent2D ext0, VkExtent2D ext1, VkFragmentShadingRateCombinerOpKHR comb) const;
- bool Force1x1 () const;
+ deInt32 ShadingRateExtentToEnum (VkExtent2D ext) const;
+ VkExtent2D ShadingRateEnumToExtent (deInt32 rate) const;
+ deInt32 Simulate (deInt32 rate0, deInt32 rate1, deInt32 rate2);
+ VkExtent2D Combine (VkExtent2D ext0, VkExtent2D ext1, VkFragmentShadingRateCombinerOpKHR comb) const;
+ bool Force1x1 () const;
};
FSRTestInstance::FSRTestInstance (Context& context, const CaseDef& data)
{
context.requireDeviceFunctionality("VK_KHR_fragment_shading_rate");
- checkPipelineLibraryRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_data.pipelineConstructionType);
+ checkPipelineLibraryRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_data.groupParams->pipelineConstructionType);
- if (m_data.useDynamicRendering)
+ if (m_data.groupParams->useDynamicRendering)
context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
if (!context.getFragmentShadingRateFeatures().pipelineFragmentShadingRate)
if (m_data.sampleMaskTest && !context.getFragmentShadingRateProperties().fragmentShadingRateWithSampleMask)
TCU_THROW(NotSupportedError, "fragmentShadingRateWithSampleMask not supported");
- checkPipelineLibraryRequirements(vki, physicalDevice, m_data.pipelineConstructionType);
+ checkPipelineLibraryRequirements(vki, physicalDevice, m_data.groupParams->pipelineConstructionType);
}
// Error codes writted by the fragment shader
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
- VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV;
+ VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR;
const VkFormat cbFormat = VK_FORMAT_R32G32B32A32_UINT;
- const VkFormat dsFormat = VK_FORMAT_D32_SFLOAT_S8_UINT;
+ const VkFormat dsFormat = m_data.useDepthStencil ? VK_FORMAT_D32_SFLOAT_S8_UINT : VK_FORMAT_UNDEFINED;
if (m_data.geometryShader)
{
srTexelHeight *= 2)
for (deUint32 formatIdx = 0; formatIdx < numFillFormats; ++formatIdx)
{
-
deUint32 aspectRatio = (srTexelHeight > srTexelWidth) ? (srTexelHeight / srTexelWidth) : (srTexelWidth / srTexelHeight);
if (aspectRatio > maxFragmentShadingRateAttachmentTexelSizeAspectRatio)
continue;
attachments.push_back(*dsImageView);
}
- if (!m_data.useDynamicRendering)
+ if (!m_data.groupParams->useDynamicRendering)
{
const vk::VkAttachmentReference2 colorAttachmentReference
{
const deUint32 fragSizeWH = m_data.sampleMaskTest ? 2 : 0;
+#ifndef CTS_USES_VULKANSC
VkPipelineRenderingCreateInfoKHR renderingCreateInfo
{
VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
m_data.multiView ? 0x3 : 0u,
1u,
&cbFormat,
- m_data.useDepthStencil ? dsFormat : VK_FORMAT_UNDEFINED,
- m_data.useDepthStencil ? dsFormat : VK_FORMAT_UNDEFINED
+ dsFormat,
+ dsFormat
};
+#endif // CTS_USES_VULKANSC
VkPipelineFragmentShadingRateStateCreateInfoKHR shadingRateStateCreateInfo
{
VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR, // VkStructureType sType;
- m_data.useDynamicRendering ? &renderingCreateInfo : DE_NULL, // const void* pNext;
+#ifndef CTS_USES_VULKANSC
+ m_data.groupParams->useDynamicRendering ? &renderingCreateInfo : DE_NULL, // const void* pNext;
+#else
+ DE_NULL, // const void* pNext;
+#endif // CTS_USES_VULKANSC
{ fragSizeWH, fragSizeWH }, // VkExtent2D fragmentSize;
{ m_data.combinerOp[0], m_data.combinerOp[1] }, // VkFragmentShadingRateCombinerOpKHR combinerOps[2];
};
VkDynamicState dynamicState = VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR;
- const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo =
+ const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo
{
VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
DE_NULL, // const void* pNext;
m_data.useDynamicState ? 1u : 0u, // uint32_t dynamicStateCount;
&dynamicState, // const VkDynamicState* pDynamicStates;
};
+ vk::VkPipelineRenderingCreateInfoKHR* pDynamicRendering = (m_data.groupParams->useDynamicRendering ? &renderingCreateInfo : DE_NULL);
// Enable depth/stencil writes, always passing
VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
0.0f, // float maxDepthBounds;
};
- VkPipelineCreateFlags pipelineCreateFlags = (VkPipelineCreateFlags)0;
- if (m_data.useDynamicRendering)
- pipelineCreateFlags |= VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR;
-
- VkImageMemoryBarrier imageBarrier =
- {
- VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
- DE_NULL, // const void* pNext
- 0u, // VkAccessFlags srcAccessMask
- VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
- VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
- VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout
- VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
- VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
- **cbImage, // VkImage image
- {
- VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
- 0u, // uint32_t baseMipLevel
- VK_REMAINING_MIP_LEVELS, // uint32_t mipLevels,
- 0u, // uint32_t baseArray
- VK_REMAINING_ARRAY_LAYERS, // uint32_t arraySize
- }
- };
-
- const VkQueue queue = m_context.getUniversalQueue();
- Move<VkCommandPool> cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_context.getUniversalQueueFamilyIndex());
- Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
- VkClearValue clearColor = makeClearValueColorU32(0, 0, 0, 0);
- VkClearValue clearDepthStencil = makeClearValueDepthStencil(0.0, 0);
-
- beginCommandBuffer(vk, *cmdBuffer, 0u);
-
- vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
- (VkDependencyFlags)0,
- 0, (const VkMemoryBarrier*)DE_NULL,
- 0, (const VkBufferMemoryBarrier*)DE_NULL,
- 1, &imageBarrier);
-
- imageBarrier.image = **derivImage;
- imageBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
-
- vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
- (VkDependencyFlags)0,
- 0, (const VkMemoryBarrier*)DE_NULL,
- 0, (const VkBufferMemoryBarrier*)DE_NULL,
- 1, &imageBarrier);
+ const VkQueue queue = m_context.getUniversalQueue();
+ Move<VkCommandPool> cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, m_context.getUniversalQueueFamilyIndex());
+ Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+ Move<VkCommandBuffer> secCmdBuffer;
+ VkClearValue clearColor = makeClearValueColorU32(0, 0, 0, 0);
+ VkClearValue clearDepthStencil = makeClearValueDepthStencil(0.0, 0);
+ const VkExtent2D srTexelSize { srTexelWidth, srTexelHeight };
- // Clear level to 1<<level
- for (deUint32 i = 0; i < derivNumLevels; ++i)
- {
- VkImageSubresourceRange range = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, i, 1u, 0u, 1u);
- VkClearValue clearLevelColor = makeClearValueColorU32(1<<i,0,0,0);
- vk.cmdClearColorImage(*cmdBuffer, **derivImage, VK_IMAGE_LAYOUT_GENERAL, &clearLevelColor.color, 1, &range);
- }
-
- // Clear color buffer to transparent black
- {
- VkImageSubresourceRange range = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, VK_REMAINING_ARRAY_LAYERS);
- vk.cmdClearColorImage(*cmdBuffer, **cbImage, VK_IMAGE_LAYOUT_GENERAL, &clearColor.color, 1, &range);
- }
-
- // Clear depth and stencil
- if (m_data.useDepthStencil)
- {
- VkImageSubresourceRange range = makeImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 1u, 0u, VK_REMAINING_ARRAY_LAYERS);
- VkImageMemoryBarrier dsBarrier = imageBarrier;
- dsBarrier.image = **dsImage;
- dsBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
- dsBarrier.subresourceRange = range;
- vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
- 0u, // dependencyFlags
- 0u, nullptr,
- 0u, nullptr,
- 1u, &dsBarrier);
- vk.cmdClearDepthStencilImage(*cmdBuffer, **dsImage, VK_IMAGE_LAYOUT_GENERAL, &clearDepthStencil.depthStencil, 1, &range);
- }
+ std::vector<GraphicsPipelineWrapper> pipelines;
+ pipelines.reserve(m_data.useDynamicState ? 1u : NUM_TRIANGLES);
- // Initialize shading rate image with varying values
- if (m_data.useAttachment())
+ if (m_data.groupParams->useSecondaryCmdBuffer)
{
- imageBarrier.image = **srImage;
- imageBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
-
- vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
- (VkDependencyFlags)0,
- 0, (const VkMemoryBarrier*)DE_NULL,
- 0, (const VkBufferMemoryBarrier*)DE_NULL,
- 1, &imageBarrier);
+ secCmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
- deMemset(fillPtr, 0, (size_t)srFillBufferSize);
- for (deUint32 layer = 0; layer < numSRLayers; ++layer)
+ // record secondary command buffer
+ if (m_data.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
{
- for (deUint32 x = 0; x < srWidth; ++x)
- {
- for (deUint32 y = 0; y < srHeight; ++y)
- {
- deUint32 idx = (layer*srHeight + y)*srWidth + x;
- deUint8 val = (deUint8)SanitizeRate(idx & 0xF);
- // actual shading rate is always in the LSBs of the first byte of a texel
- fillPtr[srFillBpp*idx] = val;
- }
- }
+ beginSecondaryCmdBuffer(*secCmdBuffer, cbFormat, dsFormat, VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT);
+ beginRender(*secCmdBuffer, *renderPass, *framebuffer, *srImageView, srLayout, srTexelSize,
+ *cbImageView, *dsImageView, imagelessFB, clearColor, clearDepthStencil);
}
- flushAlloc(vk, device, srFillBuffer->getAllocation());
-
- const VkBufferImageCopy copyRegion =
- {
- 0u, // VkDeviceSize bufferOffset;
- 0u, // deUint32 bufferRowLength;
- 0u, // deUint32 bufferImageHeight;
- {
- VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
- 0u, // deUint32 mipLevel;
- 0u, // deUint32 baseArrayLayer;
- numSRLayers, // deUint32 layerCount;
- }, // VkImageSubresourceLayers imageSubresource;
- { 0, 0, 0 }, // VkOffset3D imageOffset;
- { srWidth, srHeight, 1 }, // VkExtent3D imageExtent;
- };
+ else
+ beginSecondaryCmdBuffer(*secCmdBuffer, cbFormat, dsFormat);
- vk.cmdCopyBufferToImage(*cmdBuffer, **srFillBuffer, **srImage, VK_IMAGE_LAYOUT_GENERAL, 1, ©Region);
+ drawCommands(*secCmdBuffer, pipelines, viewports, scissors, *pipelineLayout, *renderPass,
+ &vertexInputStateCreateInfo, &dynamicStateCreateInfo, &rasterizationStateCreateInfo,
+ &depthStencilStateParams, &multisampleStateCreateInfo, &shadingRateStateCreateInfo,
+ pDynamicRendering, *vertShader, *geomShader, *fragShader, *descriptorSet, **vertexBuffer);
- imageBarrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
- imageBarrier.newLayout = srLayout;
+ if (m_data.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
+ endRender(*secCmdBuffer);
- vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
- (VkDependencyFlags)0,
- 0, (const VkMemoryBarrier*)DE_NULL,
- 0, (const VkBufferMemoryBarrier*)DE_NULL,
- 1, &imageBarrier);
- }
+ endCommandBuffer(vk, *secCmdBuffer);
- VkMemoryBarrier memBarrier =
- {
- VK_STRUCTURE_TYPE_MEMORY_BARRIER, // sType
- DE_NULL, // pNext
- 0u, // srcAccessMask
- 0u, // dstAccessMask
- };
+ // record primary command buffer
+ beginCommandBuffer(vk, *cmdBuffer, 0u);
- memBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
- memBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR;
- vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, allPipelineStages,
- 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
+ preRenderCommands(*cmdBuffer, cbImage.get(), dsImage.get(), derivImage.get(), derivNumLevels, srImage.get(), srLayout,
+ srFillBuffer.get(), numSRLayers, srWidth, srHeight, srFillBpp, clearColor, clearDepthStencil);
+ if (!m_data.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
+ beginRender(*cmdBuffer, *renderPass, *framebuffer, *srImageView, srLayout, srTexelSize,
+ *cbImageView, *dsImageView, imagelessFB, clearColor, clearDepthStencil, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
- vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0, 1, &descriptorSet.get(), 0, DE_NULL);
+ vk.cmdExecuteCommands(*cmdBuffer, 1u, &*secCmdBuffer);
- vector<GraphicsPipelineWrapper> pipelines;
- pipelines.reserve(m_data.useDynamicState ? 1u : NUM_TRIANGLES);
-
- // If using dynamic state, create a single graphics pipeline and bind it
- vk::VkPipelineRenderingCreateInfoKHR* pDynamicRendering = (m_data.useDynamicRendering ? &renderingCreateInfo : DE_NULL);
- if (m_data.useDynamicState)
- {
- pipelines.emplace_back(vk, device, m_data.pipelineConstructionType, pipelineCreateFlags);
- pipelines.back()
- .setDefaultColorBlendState()
- .setDynamicState(&dynamicStateCreateInfo)
- .setupVertexInputStete(&vertexInputStateCreateInfo)
- .setupPreRasterizationShaderState(viewports,
- scissors,
- *pipelineLayout,
- *renderPass,
- 0u,
- *vertShader,
- &rasterizationStateCreateInfo,
- DE_NULL,
- DE_NULL,
- *geomShader,
- DE_NULL,
- pDynamicRendering)
- .setupFragmentShaderState(
- *pipelineLayout,
- *renderPass,
- 0u,
- *fragShader,
- &depthStencilStateParams,
- &multisampleStateCreateInfo,
- &shadingRateStateCreateInfo)
- .setupFragmentOutputState(*renderPass, 0u, DE_NULL, &multisampleStateCreateInfo)
- .setMonolithicPipelineLayout(*pipelineLayout)
- .buildPipeline();
- vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.back().getPipeline());
- }
-
- VkRect2D renderArea = makeRect2D(m_data.framebufferDim.width, m_data.framebufferDim.height);
- if (m_data.useDynamicRendering)
- {
- VkRenderingFragmentShadingRateAttachmentInfoKHR shadingRateAttachmentInfo
- {
- VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR, // VkStructureType sType;
- DE_NULL, // const void* pNext;
- *srImageView, // VkImageView imageView;
- srLayout, // VkImageLayout imageLayout;
- { srTexelWidth, srTexelHeight } // VkExtent2D shadingRateAttachmentTexelSize;
- };
-
- VkRenderingAttachmentInfoKHR colorAttachment
- {
- vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
- DE_NULL, // const void* pNext;
- *cbImageView, // VkImageView imageView;
- VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
- VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
- DE_NULL, // VkImageView resolveImageView;
- VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
- VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
- VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
- clearColor // VkClearValue clearValue;
- };
-
- std::vector<VkRenderingAttachmentInfoKHR> depthStencilAttachments(2,
- {
- VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
- DE_NULL, // const void* pNext;
- *dsImageView, // VkImageView imageView;
- VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
- VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
- DE_NULL, // VkImageView resolveImageView;
- VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
- VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
- VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
- clearDepthStencil // VkClearValue clearValue;
- });
-
- vk::VkRenderingInfoKHR renderingInfo
- {
- vk::VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
- m_data.useAttachment() ? &shadingRateAttachmentInfo : DE_NULL,
- 0, // VkRenderingFlagsKHR flags;
- renderArea, // VkRect2D renderArea;
- m_data.multiView ? 1 : m_data.numColorLayers, // deUint32 layerCount;
- m_data.multiView ? 0x3 : 0u, // deUint32 viewMask;
- 1u, // deUint32 colorAttachmentCount;
- &colorAttachment, // const VkRenderingAttachmentInfoKHR* pColorAttachments;
- m_data.useDepthStencil ? &depthStencilAttachments[0] : DE_NULL, // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
- m_data.useDepthStencil ? &depthStencilAttachments[1] : DE_NULL, // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
- };
-
- vk.cmdBeginRendering(*cmdBuffer, &renderingInfo);
+ if (!m_data.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
+ endRender(*cmdBuffer);
}
else
{
- const VkRenderPassAttachmentBeginInfo renderPassAttachmentBeginInfo
- {
- VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO, // VkStructureType sType;
- DE_NULL, // const void* pNext;
- (deUint32)attachments.size(), // deUint32 attachmentCount;
- &attachments[0] // const VkImageView* pAttachments;
- };
-
- beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderArea,
- 0, DE_NULL, VK_SUBPASS_CONTENTS_INLINE, imagelessFB ? &renderPassAttachmentBeginInfo : DE_NULL);
+ beginCommandBuffer(vk, *cmdBuffer);
+ preRenderCommands(*cmdBuffer, cbImage.get(), dsImage.get(), derivImage.get(), derivNumLevels, srImage.get(), srLayout,
+ srFillBuffer.get(), numSRLayers, srWidth, srHeight, srFillBpp, clearColor, clearDepthStencil);
+ beginRender(*cmdBuffer, *renderPass, *framebuffer, *srImageView, srLayout, srTexelSize,
+ *cbImageView, *dsImageView, imagelessFB, clearColor, clearDepthStencil);
+ drawCommands(*cmdBuffer, pipelines, viewports, scissors, *pipelineLayout, *renderPass,
+ &vertexInputStateCreateInfo, &dynamicStateCreateInfo, &rasterizationStateCreateInfo,
+ &depthStencilStateParams, &multisampleStateCreateInfo, &shadingRateStateCreateInfo,
+ pDynamicRendering, *vertShader, *geomShader, *fragShader, *descriptorSet, **vertexBuffer);
+ endRender(*cmdBuffer);
}
- for (deInt32 i = 0; i < NUM_TRIANGLES; ++i)
+ VkMemoryBarrier memBarrier
{
- // Bind vertex attributes pointing to the next triangle
- VkDeviceSize vertexBufferOffset = i*3*2*sizeof(float);
- VkBuffer vb = **vertexBuffer;
- vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vb, &vertexBufferOffset);
-
- // Put primitive shading rate in a push constant
- deInt32 shadingRatePC = PrimIDToPrimitiveShadingRate(i);
- vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, allShaderStages, 0, sizeof(shadingRatePC), &shadingRatePC);
-
- if (m_data.useDynamicState)
- {
- VkExtent2D fragmentSize = ShadingRateEnumToExtent(PrimIDToPipelineShadingRate(i));
- vk.cmdSetFragmentShadingRateKHR(*cmdBuffer, &fragmentSize, m_data.combinerOp);
- }
- else
- {
- // Create a new pipeline with the desired pipeline shading rate
- shadingRateStateCreateInfo.fragmentSize = ShadingRateEnumToExtent(PrimIDToPipelineShadingRate(i));
- pipelines.emplace_back(vk, device, m_data.pipelineConstructionType, pipelineCreateFlags);
- pipelines.back()
- .setDefaultColorBlendState()
- .setDynamicState(&dynamicStateCreateInfo)
- .setupVertexInputStete(&vertexInputStateCreateInfo)
- .setupPreRasterizationShaderState(viewports,
- scissors,
- *pipelineLayout,
- *renderPass,
- 0u,
- *vertShader,
- &rasterizationStateCreateInfo,
- DE_NULL,
- DE_NULL,
- *geomShader,
- DE_NULL,
- pDynamicRendering)
- .setupFragmentShaderState(
- *pipelineLayout,
- *renderPass,
- 0u,
- *fragShader,
- &depthStencilStateParams,
- &multisampleStateCreateInfo,
- &shadingRateStateCreateInfo)
- .setupFragmentOutputState(*renderPass, 0u, DE_NULL, &multisampleStateCreateInfo)
- .setMonolithicPipelineLayout(*pipelineLayout)
- .buildPipeline();
- vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.back().getPipeline());
- }
-
- // Draw one triangle, with "primitive ID" in gl_InstanceIndex
- vk.cmdDraw(*cmdBuffer, 3u, 1, 0u, i);
- }
-
- if (m_data.useDynamicRendering)
- endRendering(vk, *cmdBuffer);
- else
- endRenderPass(vk, *cmdBuffer);
-
- memBarrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
- memBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
- vk.cmdPipelineBarrier(*cmdBuffer, allPipelineStages, allPipelineStages,
- 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
+ VK_STRUCTURE_TYPE_MEMORY_BARRIER,
+ DE_NULL,
+ VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
+ VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT
+ };
+ vk.cmdPipelineBarrier(*cmdBuffer, allPipelineStages, allPipelineStages, 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1, &*descriptorSet, 0u, DE_NULL);
vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
return tcu::TestStatus(res, qpGetTestResultName(res));
}
+void FSRTestInstance::beginSecondaryCmdBuffer(VkCommandBuffer cmdBuffer, VkFormat cbFormat, VkFormat dsFormat, VkRenderingFlagsKHR renderingFlags) const
+{
+ VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo
+ {
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ renderingFlags, // VkRenderingFlagsKHR flags;
+ m_data.multiView ? 0x3 : 0u, // uint32_t viewMask;
+ 1u, // uint32_t colorAttachmentCount;
+ &cbFormat, // const VkFormat* pColorAttachmentFormats;
+ dsFormat, // VkFormat depthAttachmentFormat;
+ dsFormat, // VkFormat stencilAttachmentFormat;
+ m_data.samples, // VkSampleCountFlagBits rasterizationSamples;
+ };
+ const VkCommandBufferInheritanceInfo bufferInheritanceInfo = initVulkanStructure(&inheritanceRenderingInfo);
+
+ VkCommandBufferUsageFlags usageFlags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+ if (!m_data.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
+ usageFlags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
+
+ const VkCommandBufferBeginInfo commandBufBeginParams
+ {
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ usageFlags, // VkCommandBufferUsageFlags flags;
+ &bufferInheritanceInfo
+ };
+
+ const DeviceInterface& vk = m_context.getDeviceInterface();
+ VK_CHECK(vk.beginCommandBuffer(cmdBuffer, &commandBufBeginParams));
+}
+
+void FSRTestInstance::preRenderCommands(VkCommandBuffer cmdBuffer, ImageWithMemory* cbImage, ImageWithMemory* dsImage,
+ ImageWithMemory* derivImage, deUint32 derivNumLevels,
+ ImageWithMemory* srImage, VkImageLayout srLayout, BufferWithMemory* srFillBuffer,
+ deUint32 numSRLayers, deUint32 srWidth, deUint32 srHeight, deUint32 srFillBpp,
+ const VkClearValue& clearColor, const VkClearValue& clearDepthStencil)
+{
+ const DeviceInterface& vk = m_context.getDeviceInterface();
+ const VkDevice device = m_context.getDevice();
+
+ VkFlags allPipelineStages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
+ VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
+ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
+ VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
+ VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
+ VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
+ VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV;
+
+ if (m_data.geometryShader)
+ allPipelineStages |= VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
+
+ VkImageMemoryBarrier imageBarrier
+ {
+ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
+ DE_NULL, // const void* pNext
+ 0u, // VkAccessFlags srcAccessMask
+ VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
+ VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
+ VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout
+ VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
+ VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
+ cbImage->get(), // VkImage image
+ {
+ VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
+ 0u, // uint32_t baseMipLevel
+ VK_REMAINING_MIP_LEVELS, // uint32_t mipLevels,
+ 0u, // uint32_t baseArray
+ VK_REMAINING_ARRAY_LAYERS, // uint32_t arraySize
+ }
+ };
+
+ vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
+ (VkDependencyFlags)0,
+ 0, (const VkMemoryBarrier*)DE_NULL,
+ 0, (const VkBufferMemoryBarrier*)DE_NULL,
+ 1, &imageBarrier);
+
+ imageBarrier.image = derivImage->get();
+ imageBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
+
+ vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
+ (VkDependencyFlags)0,
+ 0, (const VkMemoryBarrier*)DE_NULL,
+ 0, (const VkBufferMemoryBarrier*)DE_NULL,
+ 1, &imageBarrier);
+
+ // Clear level to 1<<level
+ for (deUint32 i = 0; i < derivNumLevels; ++i)
+ {
+ VkImageSubresourceRange range = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, i, 1u, 0u, 1u);
+ VkClearValue clearLevelColor = makeClearValueColorU32(1<<i,0,0,0);
+ vk.cmdClearColorImage(cmdBuffer, derivImage->get(), VK_IMAGE_LAYOUT_GENERAL, &clearLevelColor.color, 1, &range);
+ }
+
+ // Clear color buffer to transparent black
+ {
+ VkImageSubresourceRange range = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, VK_REMAINING_ARRAY_LAYERS);
+ vk.cmdClearColorImage(cmdBuffer, cbImage->get(), VK_IMAGE_LAYOUT_GENERAL, &clearColor.color, 1, &range);
+ }
+
+ // Clear depth and stencil
+ if (m_data.useDepthStencil)
+ {
+ VkImageSubresourceRange range = makeImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 1u, 0u, VK_REMAINING_ARRAY_LAYERS);
+ VkImageMemoryBarrier dsBarrier = imageBarrier;
+ dsBarrier.image = dsImage->get();
+ dsBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
+ dsBarrier.subresourceRange = range;
+ vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
+ 0u, // dependencyFlags
+ 0u, nullptr,
+ 0u, nullptr,
+ 1u, &dsBarrier);
+ vk.cmdClearDepthStencilImage(cmdBuffer, dsImage->get(), VK_IMAGE_LAYOUT_GENERAL, &clearDepthStencil.depthStencil, 1, &range);
+ }
+
+ // Initialize shading rate image with varying values
+ if (m_data.useAttachment())
+ {
+ imageBarrier.image = srImage->get();
+ imageBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
+
+ vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
+ (VkDependencyFlags)0,
+ 0, (const VkMemoryBarrier*)DE_NULL,
+ 0, (const VkBufferMemoryBarrier*)DE_NULL,
+ 1, &imageBarrier);
+
+ deUint8 *fillPtr = (deUint8 *)srFillBuffer->getAllocation().getHostPtr();
+ for (deUint32 layer = 0; layer < numSRLayers; ++layer)
+ {
+ for (deUint32 x = 0; x < srWidth; ++x)
+ {
+ for (deUint32 y = 0; y < srHeight; ++y)
+ {
+ deUint32 idx = (layer*srHeight + y)*srWidth + x;
+ deUint8 val = (deUint8)SanitizeRate(idx & 0xF);
+ // actual shading rate is always in the LSBs of the first byte of a texel
+ fillPtr[srFillBpp*idx] = val;
+ }
+ }
+ }
+ flushAlloc(vk, device, srFillBuffer->getAllocation());
+
+ const VkBufferImageCopy copyRegion
+ {
+ 0u, // VkDeviceSize bufferOffset;
+ 0u, // deUint32 bufferRowLength;
+ 0u, // deUint32 bufferImageHeight;
+ {
+ VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
+ 0u, // deUint32 mipLevel;
+ 0u, // deUint32 baseArrayLayer;
+ numSRLayers, // deUint32 layerCount;
+ }, // VkImageSubresourceLayers imageSubresource;
+ { 0, 0, 0 }, // VkOffset3D imageOffset;
+ { srWidth, srHeight, 1 }, // VkExtent3D imageExtent;
+ };
+
+ vk.cmdCopyBufferToImage(cmdBuffer, srFillBuffer->get(), srImage->get(), VK_IMAGE_LAYOUT_GENERAL, 1, ©Region);
+
+ imageBarrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
+ imageBarrier.newLayout = srLayout;
+
+ vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
+ (VkDependencyFlags)0,
+ 0, (const VkMemoryBarrier*)DE_NULL,
+ 0, (const VkBufferMemoryBarrier*)DE_NULL,
+ 1, &imageBarrier);
+ }
+
+ VkMemoryBarrier memBarrier
+ {
+ VK_STRUCTURE_TYPE_MEMORY_BARRIER, // sType
+ DE_NULL, // pNext
+ 0u, // srcAccessMask
+ 0u, // dstAccessMask
+ };
+
+ memBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+ memBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR;
+ vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, allPipelineStages,
+ 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
+}
+
+void FSRTestInstance::beginRender(VkCommandBuffer cmdBuffer, VkRenderPass renderPass, VkFramebuffer framebuffer,
+ VkImageView srImageView, VkImageLayout srImageLayout, const VkExtent2D& srTexelSize,
+ VkImageView cbImageView, VkImageView dsImageView, bool imagelessFB,
+ const VkClearValue& clearColor, const VkClearValue& clearDepthStencil,
+ VkRenderingFlagsKHR renderingFlags) const
+{
+ const DeviceInterface& vk = m_context.getDeviceInterface();
+ VkRect2D renderArea = makeRect2D(m_data.framebufferDim.width, m_data.framebufferDim.height);
+
+ if (m_data.groupParams->useDynamicRendering)
+ {
+ VkRenderingFragmentShadingRateAttachmentInfoKHR shadingRateAttachmentInfo
+ {
+ VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ srImageView, // VkImageView imageView;
+ srImageLayout, // VkImageLayout imageLayout;
+ srTexelSize // VkExtent2D shadingRateAttachmentTexelSize;
+ };
+
+ VkRenderingAttachmentInfoKHR colorAttachment
+ {
+ vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ cbImageView, // VkImageView imageView;
+ VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
+ VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
+ DE_NULL, // VkImageView resolveImageView;
+ VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
+ VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
+ VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
+ clearColor // VkClearValue clearValue;
+ };
+
+ std::vector<VkRenderingAttachmentInfoKHR> depthStencilAttachments(2,
+ {
+ VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ dsImageView, // VkImageView imageView;
+ VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
+ VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
+ DE_NULL, // VkImageView resolveImageView;
+ VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
+ VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
+ VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
+ clearDepthStencil // VkClearValue clearValue;
+ });
+
+ vk::VkRenderingInfoKHR renderingInfo
+ {
+ vk::VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
+ m_data.useAttachment() ? &shadingRateAttachmentInfo : DE_NULL,
+ renderingFlags, // VkRenderingFlagsKHR flags;
+ renderArea, // VkRect2D renderArea;
+ m_data.multiView ? 1 : m_data.numColorLayers, // deUint32 layerCount;
+ m_data.multiView ? 0x3 : 0u, // deUint32 viewMask;
+ 1u, // deUint32 colorAttachmentCount;
+ &colorAttachment, // const VkRenderingAttachmentInfoKHR* pColorAttachments;
+ m_data.useDepthStencil ? &depthStencilAttachments[0] : DE_NULL, // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
+ m_data.useDepthStencil ? &depthStencilAttachments[1] : DE_NULL, // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
+ };
+
+ vk.cmdBeginRendering(cmdBuffer, &renderingInfo);
+ }
+ else
+ {
+ std::vector<VkImageView> attachments = { cbImageView };
+ if (m_data.useAttachment())
+ attachments.push_back(srImageView);
+ if (m_data.useDepthStencil)
+ attachments.push_back(dsImageView);
+
+ const VkRenderPassAttachmentBeginInfo renderPassAttachmentBeginInfo
+ {
+ VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (deUint32)attachments.size(), // deUint32 attachmentCount;
+ &attachments[0] // const VkImageView* pAttachments;
+ };
+
+ beginRenderPass(vk, cmdBuffer, renderPass, framebuffer, renderArea,
+ 0, DE_NULL, VK_SUBPASS_CONTENTS_INLINE, imagelessFB ? &renderPassAttachmentBeginInfo : DE_NULL);
+ }
+}
+
+void FSRTestInstance::drawCommands(VkCommandBuffer cmdBuffer,
+ std::vector<GraphicsPipelineWrapper>& pipelines,
+ const std::vector<VkViewport>& viewports,
+ const std::vector<VkRect2D>& scissors,
+ const VkPipelineLayout pipelineLayout,
+ const VkRenderPass renderPass,
+ const VkPipelineVertexInputStateCreateInfo* vertexInputState,
+ const VkPipelineDynamicStateCreateInfo* dynamicState,
+ const VkPipelineRasterizationStateCreateInfo* rasterizationState,
+ const VkPipelineDepthStencilStateCreateInfo* depthStencilState,
+ const VkPipelineMultisampleStateCreateInfo* multisampleState,
+ VkPipelineFragmentShadingRateStateCreateInfoKHR* shadingRateState,
+ VkPipelineRenderingCreateInfoKHR* dynamicRendering,
+ const VkShaderModule vertShader,
+ const VkShaderModule geomShader,
+ const VkShaderModule fragShader,
+ VkDescriptorSet descriptorSet,
+ VkBuffer vertexBuffer)
+{
+ const DeviceInterface& vk = m_context.getDeviceInterface();
+ const VkDevice device = m_context.getDevice();
+
+ VkFlags allShaderStages = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT;
+ if (m_data.geometryShader)
+ allShaderStages |= VK_SHADER_STAGE_GEOMETRY_BIT;
+
+ VkPipelineCreateFlags pipelineCreateFlags = (VkPipelineCreateFlags)0;
+ if (m_data.groupParams->useDynamicRendering)
+ pipelineCreateFlags |= VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR;
+
+ vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, DE_NULL);
+
+ // If using dynamic state, create a single graphics pipeline and bind it
+ if (m_data.useDynamicState)
+ {
+ pipelines.emplace_back(vk, device, m_data.groupParams->pipelineConstructionType, pipelineCreateFlags);
+ pipelines.back()
+ .setDefaultColorBlendState()
+ .setDynamicState(dynamicState)
+ .setupVertexInputStete(vertexInputState)
+ .setupPreRasterizationShaderState(viewports,
+ scissors,
+ pipelineLayout,
+ renderPass,
+ 0u,
+ vertShader,
+ rasterizationState,
+ DE_NULL,
+ DE_NULL,
+ geomShader,
+ DE_NULL,
+ dynamicRendering)
+ .setupFragmentShaderState(pipelineLayout,
+ renderPass,
+ 0u,
+ fragShader,
+ depthStencilState,
+ multisampleState,
+ shadingRateState)
+ .setupFragmentOutputState(renderPass, 0u, DE_NULL, multisampleState)
+ .buildPipeline();
+
+ vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.back().getPipeline());
+ }
+
+ for (deInt32 i = 0; i < NUM_TRIANGLES; ++i)
+ {
+ // Bind vertex attributes pointing to the next triangle
+ VkDeviceSize vertexBufferOffset = i * 3 * 2 * sizeof(float);
+ vk.cmdBindVertexBuffers(cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
+
+ // Put primitive shading rate in a push constant
+ deInt32 shadingRatePC = PrimIDToPrimitiveShadingRate(i);
+ vk.cmdPushConstants(cmdBuffer, pipelineLayout, allShaderStages, 0, sizeof(shadingRatePC), &shadingRatePC);
+
+ if (m_data.useDynamicState)
+ {
+ VkExtent2D fragmentSize = ShadingRateEnumToExtent(PrimIDToPipelineShadingRate(i));
+ vk.cmdSetFragmentShadingRateKHR(cmdBuffer, &fragmentSize, m_data.combinerOp);
+ }
+ else
+ {
+ // Create a new pipeline with the desired pipeline shading rate
+ shadingRateState->fragmentSize = ShadingRateEnumToExtent(PrimIDToPipelineShadingRate(i));
+
+ pipelines.emplace_back(vk, device, m_data.groupParams->pipelineConstructionType, pipelineCreateFlags);
+ pipelines.back()
+ .setDefaultColorBlendState()
+ .setDynamicState(dynamicState)
+ .setupVertexInputStete(vertexInputState)
+ .setupPreRasterizationShaderState(viewports,
+ scissors,
+ pipelineLayout,
+ renderPass,
+ 0u,
+ vertShader,
+ rasterizationState,
+ DE_NULL,
+ DE_NULL,
+ geomShader,
+ DE_NULL,
+ dynamicRendering)
+ .setupFragmentShaderState(pipelineLayout,
+ renderPass,
+ 0u,
+ fragShader,
+ depthStencilState,
+ multisampleState,
+ shadingRateState)
+ .setupFragmentOutputState(renderPass, 0u, DE_NULL, multisampleState)
+ .buildPipeline();
+
+ vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.back().getPipeline());
+ }
+
+ // Draw one triangle, with "primitive ID" in gl_InstanceIndex
+ vk.cmdDraw(cmdBuffer, 3u, 1, 0u, i);
+ }
+}
+
+void FSRTestInstance::endRender(VkCommandBuffer cmdBuffer) const
+{
+ const DeviceInterface& vk = m_context.getDeviceInterface();
+ if (m_data.groupParams->useDynamicRendering)
+ endRendering(vk, cmdBuffer);
+ else
+ endRenderPass(vk, cmdBuffer);
+}
+
} // anonymous
-void createBasicTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* parentGroup, vk::PipelineConstructionType pipelineConstructionType, bool useDynamicRendering)
+void createBasicTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* parentGroup, SharedGroupParams groupParams)
{
typedef struct
{
for (int groupNdx = 0; groupNdx < DE_LENGTH_OF_ARRAY(groupCases); groupNdx++)
{
- if (useDynamicRendering && groupNdx == 12)
+ if (groupParams->useDynamicRendering && groupNdx == 12)
continue;
- if (pipelineConstructionType != PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
+ if (groupParams->pipelineConstructionType != PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
{
// for graphics pipeline library we need to repeat only selected groups
if (std::set<int> { 2, 3, 4, 10, 11, 12, 13, 14, 15 }.count(groupNdx) == 0)
de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, groupCases[groupNdx].name, groupCases[groupNdx].description));
for (int dynNdx = 0; dynNdx < DE_LENGTH_OF_ARRAY(dynCases); dynNdx++)
{
+ // reduce number of tests for dynamic rendering cases where secondary command buffer is used
+ if (groupParams->useSecondaryCmdBuffer && (dynNdx != 0))
+ continue;
+
de::MovePtr<tcu::TestCaseGroup> dynGroup(new tcu::TestCaseGroup(testCtx, dynCases[dynNdx].name, dynCases[dynNdx].description));
for (int attNdx = 0; attNdx < DE_LENGTH_OF_ARRAY(attCases); attNdx++)
{
- if (useDynamicRendering && attCases[attNdx].usage == AttachmentUsage::NO_ATTACHMENT_PTR)
+ if (groupParams->useDynamicRendering && attCases[attNdx].usage == AttachmentUsage::NO_ATTACHMENT_PTR)
continue;
de::MovePtr<tcu::TestCaseGroup> attGroup(new tcu::TestCaseGroup(testCtx, attCases[attNdx].name, attCases[attNdx].description));
de::MovePtr<tcu::TestCaseGroup> cmb1Group(new tcu::TestCaseGroup(testCtx, combCases[cmb1Ndx].name, combCases[cmb1Ndx].description));
for (int extNdx = 0; extNdx < DE_LENGTH_OF_ARRAY(extentCases); extNdx++)
{
- // to reduce number of cases repeat every other extent case for graphics pipeline library
- if ((pipelineConstructionType != PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC) && ((extNdx % 2) == 1))
+ // reduce number of cases repeat every other extent case for graphics pipeline library
+ if ((groupParams->pipelineConstructionType != PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC) && ((extNdx % 2) == 1))
+ continue;
+
+ // reduce number of tests for dynamic rendering cases where secondary command buffer is used
+ if (groupParams->useSecondaryCmdBuffer && (extNdx != 1))
continue;
de::MovePtr<tcu::TestCaseGroup> extGroup(new tcu::TestCaseGroup(testCtx, extentCases[extNdx].name, extentCases[extNdx].description));
for (int sampNdx = 0; sampNdx < DE_LENGTH_OF_ARRAY(sampCases); sampNdx++)
{
+ // reduce number of tests for dynamic rendering cases where secondary command buffer is used
+ if (groupParams->useSecondaryCmdBuffer && (sampNdx != 1))
+ continue;
+
de::MovePtr<tcu::TestCaseGroup> sampGroup(new tcu::TestCaseGroup(testCtx, sampCases[sampNdx].name, sampCases[sampNdx].description));
for (int geomNdx = 0; geomNdx < DE_LENGTH_OF_ARRAY(geomCases); geomNdx++)
{
+ // reduce number of tests for dynamic rendering cases where secondary command buffer is used
+ if (groupParams->useSecondaryCmdBuffer && (geomNdx != 0))
+ continue;
+
bool useApiSampleMask = groupNdx == 1;
bool useSampleMaskIn = groupNdx == 2;
bool consRast = groupNdx == 3 || groupNdx == 4;
if (srLayered && attCases[attNdx].usage != AttachmentUsage::WITH_ATTACHMENT)
continue;
- CaseDef c =
+ CaseDef c
{
- pipelineConstructionType, // PipelineConstructionType pipelineConstructionType;
+ groupParams, // SharedGroupParams groupParams;
seed++, // deInt32 seed;
extentCases[extNdx].count, // VkExtent2D framebufferDim;
(VkSampleCountFlagBits)sampCases[sampNdx].count, // VkSampleCountFlagBits samples;
(bool)shdCases[shdNdx].count, // bool shaderWritesRate;
(bool)geomCases[geomNdx].count, // bool geometryShader;
(bool)dynCases[dynNdx].count, // bool useDynamicState;
- useDynamicRendering, // bool useDynamicRendering;
useApiSampleMask, // bool useApiSampleMask;
useSampleMaskIn, // bool useSampleMaskIn;
consRast, // bool conservativeEnable;
parentGroup->addChild(group.release());
}
- de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "misc_tests", "Single tests that don't need to be part of above test matrix"));
- group->addChild(new FSRTestCase(testCtx, "sample_mask_test", "", {
- pipelineConstructionType, // PipelineConstructionType pipelineConstructionType;
- 123, // deInt32 seed;
- {32, 33}, // VkExtent2D framebufferDim;
- VK_SAMPLE_COUNT_4_BIT, // VkSampleCountFlagBits samples;
- {
- VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
- VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR
- }, // VkFragmentShadingRateCombinerOpKHR combinerOp[2];
- AttachmentUsage::NO_ATTACHMENT, // AttachmentUsage attachmentUsage;
- true, // bool shaderWritesRate;
- false, // bool geometryShader;
- false, // bool useDynamicState;
- false, // bool useDynamicRendering;
- true, // bool useApiSampleMask;
- false, // bool useSampleMaskIn;
- false, // bool conservativeEnable;
- VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT, // VkConservativeRasterizationModeEXT conservativeMode;
- false, // bool useDepthStencil;
- false, // bool fragDepth;
- false, // bool fragStencil;
- false, // bool multiViewport;
- false, // bool colorLayered;
- false, // bool srLayered;
- 1u, // deUint32 numColorLayers;
- false, // bool multiView;
- false, // bool correlationMask;
- false, // bool interlock;
- false, // bool sampleLocations;
- false, // bool sampleShadingEnable;
- false, // bool sampleShadingInput;
- true, // bool sampleMaskTest;
- }));
-
- parentGroup->addChild(group.release());
+ if (!groupParams->useSecondaryCmdBuffer)
+ {
+ de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "misc_tests", "Single tests that don't need to be part of above test matrix"));
+ group->addChild(new FSRTestCase(testCtx, "sample_mask_test", "", {
+ groupParams, // SharedGroupParams groupParams;
+ 123, // deInt32 seed;
+ {32, 33}, // VkExtent2D framebufferDim;
+ VK_SAMPLE_COUNT_4_BIT, // VkSampleCountFlagBits samples;
+ {
+ VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
+ VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR
+ }, // VkFragmentShadingRateCombinerOpKHR combinerOp[2];
+ AttachmentUsage::NO_ATTACHMENT, // AttachmentUsage attachmentUsage;
+ true, // bool shaderWritesRate;
+ false, // bool geometryShader;
+ false, // bool useDynamicState;
+ true, // bool useApiSampleMask;
+ false, // bool useSampleMaskIn;
+ false, // bool conservativeEnable;
+ VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT, // VkConservativeRasterizationModeEXT conservativeMode;
+ false, // bool useDepthStencil;
+ false, // bool fragDepth;
+ false, // bool fragStencil;
+ false, // bool multiViewport;
+ false, // bool colorLayered;
+ false, // bool srLayered;
+ 1u, // deUint32 numColorLayers;
+ false, // bool multiView;
+ false, // bool correlationMask;
+ false, // bool interlock;
+ false, // bool sampleLocations;
+ false, // bool sampleShadingEnable;
+ false, // bool sampleShadingInput;
+ true, // bool sampleMaskTest;
+ }));
+
+ parentGroup->addChild(group.release());
+ }
}
} // FragmentShadingRage