void submitCommandsAndWait (const DeviceInterface& vk, const VkDevice device, const VkQueue queue, const VkCommandBuffer commandBuffer) { const VkFenceCreateInfo fenceParams = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; 0u, // VkFenceCreateFlags flags; }; const Unique<VkFence> fence(createFence(vk, device, &fenceParams)); const VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; 0u, // deUint32 waitSemaphoreCount; DE_NULL, // const VkSemaphore* pWaitSemaphores; (const VkPipelineStageFlags*)DE_NULL, 1u, // deUint32 commandBufferCount; &commandBuffer, // const VkCommandBuffer* pCommandBuffers; 0u, // deUint32 signalSemaphoreCount; DE_NULL, // const VkSemaphore* pSignalSemaphores; }; VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence)); VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull)); }
PlainMesh::PlainMesh(Unique id) { try { name = id.get_text(); read(Matrix::id()); } catch(gfx_fatal_error &e) { throw gfx_fatal_error(string(e.what()) + " reading object: " + id.get_text()); } }
Rc<Gosu::Song> genSong(const std::string& name) { Unique<Resource> r = Resources::instance().load(name); if (!r) { // Error logged. return Rc<Gosu::Song>(); } GosuCBuffer buffer(r->data(), r->size()); TimeMeasure m("Constructed " + name + " as music"); return Rc<Gosu::Song>(new Gosu::Song(buffer.front_reader())); }
ParametricMesh::ParametricMesh(Unique id) { try { mtx = Matrix::id(); param = -1; name = id.get_text(); read(mtx); } catch(gfx_fatal_error &e) { throw gfx_fatal_error(string(e.what()) + " reading object: " + name); } }
inline MeshMgrImpl::ObjectType MeshMgrImpl::get_obj_type(Unique id) { // FIXME: also ugly, but in a different way ;) /* fix when the generic resource tree is implemented, * i.e.: if (res["objects"][id.get_text()]["parametric"]) * ... * else * ... */ try { Lua lua; Table obj = load_table(lua, "objects/"+id.get_text()); if (obj.lookup("parametric").type() != type::Nil) return Parametric; if (obj.lookup("lod").type() != type::Nil) return Standard; } catch (res::resource_not_found) { dout << id.get_text() << " not found\n"; } return Unknown; }
double find_branch(exPtrs &p, Tree *t, Appear &app) { double minTot = 10.0, minThr; int minBra = -1; for (Appear::IT it = app.B; it != app.E; it++) { int i = *it; // i-th feature for branching Comp comp(i); sort(p.B, p.E, comp); Unique u; // u stores Vm's for (int j = 0; j < p.size(); j++) u.insert(p[j]->feat[i]); int yl = 0, nl = 0, yr = Y(p), nr = N(p); exPtrs::IT k = p.B; Unique::IT j = u.B, prev = j; j++; for ( ; j != u.E; j++) { // j-th threshold double mid = ( *prev + *j ) / 2; prev = j; for ( ; k != p.E && (*k)->feat[i] < mid; k++) { if ((*k)->ans > 0) yl++, yr--; else nl++, nr--; } double curTot = total(yl, nl, yr, nr); if (curTot < minTot) { minTot = curTot; minBra = i; minThr = mid; } } } t->branch = minBra; t->thresh = minThr; return minBra; }
int main (int argc, char * argv[]) { Unique * q = new Unique; boost::shared_ptr <Unique> x (new Unique); boost::shared_ptr <Unique> y (new Unique); boost::shared_ptr <Unique> z (x); boost::shared_ptr <Unique> w (q); if (x->GetId() == z->GetId()) { std::cout << "x == z\n"; } if (y->GetId() == z->GetId()) { std::cout << "z == y\n"; } else { std::cout << "z != y\n"; } if (w->GetId() == q->GetId()) { std::cout << "q == w\n"; } }
// BEGIN CUT HERE void main( int argc, char* argv[] ) { { Unique theObject; eq(0, theObject.removeDuplicates("banana"),"ban"); } { Unique theObject; eq(1, theObject.removeDuplicates("aardvark"),"ardvk"); } { Unique theObject; eq(2, theObject.removeDuplicates("xxxxx"),"x"); } { Unique theObject; eq(3, theObject.removeDuplicates("topcoder"),"topcder"); } }
void SparseShaderIntrinsicsInstanceSampledBase::recordCommands (const VkCommandBuffer commandBuffer, const VkImageCreateInfo& imageSparseInfo, const VkImage imageSparse, const VkImage imageTexels, const VkImage imageResidency) { const InstanceInterface& instance = m_context.getInstanceInterface(); const DeviceInterface& deviceInterface = getDeviceInterface(); const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice(); const VkPhysicalDeviceProperties deviceProperties = getPhysicalDeviceProperties(instance, physicalDevice); if (imageSparseInfo.extent.width > deviceProperties.limits.maxFramebufferWidth || imageSparseInfo.extent.height > deviceProperties.limits.maxFramebufferHeight || imageSparseInfo.arrayLayers > deviceProperties.limits.maxFramebufferLayers) { TCU_THROW(NotSupportedError, "Image size exceeds allowed framebuffer dimensions"); } // Check if device supports image format for sampled images if (!checkImageFormatFeatureSupport(instance, physicalDevice, imageSparseInfo.format, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) TCU_THROW(NotSupportedError, "Device does not support image format for sampled images"); // Check if device supports image format for color attachment if (!checkImageFormatFeatureSupport(instance, physicalDevice, imageSparseInfo.format, VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) TCU_THROW(NotSupportedError, "Device does not support image format for color attachment"); // Make sure device supports VK_FORMAT_R32_UINT format for color attachment if (!checkImageFormatFeatureSupport(instance, physicalDevice, mapTextureFormat(m_residencyFormat), VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) TCU_THROW(TestError, "Device does not support VK_FORMAT_R32_UINT format for color attachment"); // Create buffer storing vertex data std::vector<tcu::Vec2> vertexData; vertexData.push_back(tcu::Vec2(-1.0f,-1.0f)); vertexData.push_back(tcu::Vec2( 0.0f, 0.0f)); vertexData.push_back(tcu::Vec2(-1.0f, 1.0f)); vertexData.push_back(tcu::Vec2( 0.0f, 1.0f)); vertexData.push_back(tcu::Vec2( 1.0f,-1.0f)); vertexData.push_back(tcu::Vec2( 1.0f, 0.0f)); vertexData.push_back(tcu::Vec2( 1.0f, 1.0f)); vertexData.push_back(tcu::Vec2( 1.0f, 1.0f)); const VkDeviceSize vertexDataSizeInBytes = sizeInBytes(vertexData); const VkBufferCreateInfo vertexBufferCreateInfo = makeBufferCreateInfo(vertexDataSizeInBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); m_vertexBuffer = createBuffer(deviceInterface, getDevice(), &vertexBufferCreateInfo); m_vertexBufferAlloc = bindBuffer(deviceInterface, getDevice(), getAllocator(), *m_vertexBuffer, MemoryRequirement::HostVisible); deMemcpy(m_vertexBufferAlloc->getHostPtr(), &vertexData[0], static_cast<std::size_t>(vertexDataSizeInBytes)); flushMappedMemoryRange(deviceInterface, getDevice(), m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset(), vertexDataSizeInBytes); // Create render pass const VkAttachmentDescription texelsAttachmentDescription = { (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; imageSparseInfo.format, // VkFormat format; VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; }; const VkAttachmentDescription residencyAttachmentDescription = { (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; mapTextureFormat(m_residencyFormat), // VkFormat format; VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; }; const VkAttachmentDescription colorAttachmentsDescription[] = { texelsAttachmentDescription, residencyAttachmentDescription }; const VkAttachmentReference texelsAttachmentReference = { 0u, // deUint32 attachment; VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; }; const VkAttachmentReference residencyAttachmentReference = { 1u, // deUint32 attachment; VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; }; const VkAttachmentReference colorAttachmentsReference[] = { texelsAttachmentReference, residencyAttachmentReference }; const VkAttachmentReference depthAttachmentReference = { VK_ATTACHMENT_UNUSED, // deUint32 attachment; VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout; }; const VkSubpassDescription subpassDescription = { (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 0u, // deUint32 inputAttachmentCount; DE_NULL, // const VkAttachmentReference* pInputAttachments; 2u, // deUint32 colorAttachmentCount; colorAttachmentsReference, // const VkAttachmentReference* pColorAttachments; DE_NULL, // const VkAttachmentReference* pResolveAttachments; &depthAttachmentReference, // const VkAttachmentReference* pDepthStencilAttachment; 0u, // deUint32 preserveAttachmentCount; DE_NULL // const deUint32* pPreserveAttachments; }; const VkRenderPassCreateInfo renderPassInfo = { VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags; 2u, // deUint32 attachmentCount; colorAttachmentsDescription, // const VkAttachmentDescription* pAttachments; 1u, // deUint32 subpassCount; &subpassDescription, // const VkSubpassDescription* pSubpasses; 0u, // deUint32 dependencyCount; DE_NULL // const VkSubpassDependency* pDependencies; }; m_renderPass = createRenderPass(deviceInterface, getDevice(), &renderPassInfo); // Create descriptor set layout DescriptorSetLayoutBuilder descriptorLayerBuilder; descriptorLayerBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT); const Unique<VkDescriptorSetLayout> descriptorSetLayout(descriptorLayerBuilder.build(deviceInterface, getDevice())); // Create descriptor pool DescriptorPoolBuilder descriptorPoolBuilder; descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, imageSparseInfo.mipLevels); descriptorPool = descriptorPoolBuilder.build(deviceInterface, getDevice(), VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, imageSparseInfo.mipLevels); // Create sampler object const tcu::Sampler samplerObject(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::NEAREST_MIPMAP_NEAREST, tcu::Sampler::NEAREST); const VkSamplerCreateInfo samplerCreateInfo = mapSampler(samplerObject, m_format); m_sampler = createSampler(deviceInterface, getDevice(), &samplerCreateInfo); struct PushConstants { deUint32 lod; deUint32 padding; // padding needed to satisfy std430 rules float lodWidth; float lodHeight; }; // Create pipeline layout const VkPushConstantRange lodConstantRange = { VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags; 0u, // deUint32 offset; sizeof(PushConstants), // deUint32 size; }; const VkPipelineLayoutCreateInfo pipelineLayoutParams = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; 0u, // VkPipelineLayoutCreateFlags flags; 1u, // deUint32 setLayoutCount; &descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts; 1u, // deUint32 pushConstantRangeCount; &lodConstantRange, // const VkPushConstantRange* pPushConstantRanges; }; const Unique<VkPipelineLayout> pipelineLayout(createPipelineLayout(deviceInterface, getDevice(), &pipelineLayoutParams)); // Create graphics pipeline { Move<VkShaderModule> vertexModule = createShaderModule(deviceInterface, getDevice(), m_context.getBinaryCollection().get("vertex_shader"), (VkShaderModuleCreateFlags)0); Move<VkShaderModule> fragmentModule = createShaderModule(deviceInterface, getDevice(), m_context.getBinaryCollection().get("fragment_shader"), (VkShaderModuleCreateFlags)0); Move<VkShaderModule> geometryModule; if (imageSparseInfo.arrayLayers > 1u) { requireFeatures(instance, physicalDevice, FEATURE_GEOMETRY_SHADER); geometryModule = createShaderModule(deviceInterface, getDevice(), m_context.getBinaryCollection().get("geometry_shader"), (VkShaderModuleCreateFlags)0); } pipelines.push_back(makeVkSharedPtr(makeGraphicsPipeline( deviceInterface, getDevice(), *pipelineLayout, *m_renderPass, *vertexModule, *fragmentModule, *geometryModule))); } const VkPipeline graphicsPipeline = **pipelines[0]; { const VkImageSubresourceRange fullImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers); VkImageMemoryBarrier imageShaderAccessBarriers[3]; imageShaderAccessBarriers[0] = makeImageMemoryBarrier ( VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, imageSparse, fullImageSubresourceRange ); imageShaderAccessBarriers[1] = makeImageMemoryBarrier ( 0u, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, imageTexels, fullImageSubresourceRange ); imageShaderAccessBarriers[2] = makeImageMemoryBarrier ( 0u, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, imageResidency, fullImageSubresourceRange ); deviceInterface.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 3u, imageShaderAccessBarriers); } imageSparseViews.resize(imageSparseInfo.mipLevels); imageTexelsViews.resize(imageSparseInfo.mipLevels); imageResidencyViews.resize(imageSparseInfo.mipLevels); m_framebuffers.resize(imageSparseInfo.mipLevels); descriptorSets.resize(imageSparseInfo.mipLevels); std::vector<VkClearValue> clearValues; clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f))); clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f))); for (deUint32 mipLevelNdx = 0u; mipLevelNdx < imageSparseInfo.mipLevels; ++mipLevelNdx) { const vk::VkExtent3D mipLevelSize = mipLevelExtents(imageSparseInfo.extent, mipLevelNdx); const vk::VkRect2D renderArea = makeRect2D(mipLevelSize); const VkViewport viewport = makeViewport(mipLevelSize); const VkImageSubresourceRange mipLevelRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, mipLevelNdx, 1u, 0u, imageSparseInfo.arrayLayers); // Create color attachments image views imageTexelsViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), imageTexels, mapImageViewType(m_imageType), imageSparseInfo.format, mipLevelRange)); imageResidencyViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), imageResidency, mapImageViewType(m_imageType), mapTextureFormat(m_residencyFormat), mipLevelRange)); const VkImageView attachmentsViews[] = { **imageTexelsViews[mipLevelNdx], **imageResidencyViews[mipLevelNdx] }; // Create framebuffer const VkFramebufferCreateInfo framebufferInfo = { VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkFramebufferCreateFlags)0, // VkFramebufferCreateFlags flags; *m_renderPass, // VkRenderPass renderPass; 2u, // uint32_t attachmentCount; attachmentsViews, // const VkImageView* pAttachments; mipLevelSize.width, // uint32_t width; mipLevelSize.height, // uint32_t height; imageSparseInfo.arrayLayers, // uint32_t layers; }; m_framebuffers[mipLevelNdx] = makeVkSharedPtr(createFramebuffer(deviceInterface, getDevice(), &framebufferInfo)); // Create descriptor set descriptorSets[mipLevelNdx] = makeVkSharedPtr(makeDescriptorSet(deviceInterface, getDevice(), *descriptorPool, *descriptorSetLayout)); const VkDescriptorSet descriptorSet = **descriptorSets[mipLevelNdx]; // Update descriptor set const VkImageSubresourceRange sparseImageSubresourceRange = sampledImageRangeToBind(imageSparseInfo, mipLevelNdx); imageSparseViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), imageSparse, mapImageViewType(m_imageType), imageSparseInfo.format, sparseImageSubresourceRange)); const VkDescriptorImageInfo imageSparseDescInfo = makeDescriptorImageInfo(*m_sampler, **imageSparseViews[mipLevelNdx], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); DescriptorSetUpdateBuilder descriptorUpdateBuilder; descriptorUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(BINDING_IMAGE_SPARSE), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSparseDescInfo); descriptorUpdateBuilder.update(deviceInterface, getDevice()); // Begin render pass beginRenderPass(deviceInterface, commandBuffer, *m_renderPass, **m_framebuffers[mipLevelNdx], renderArea, (deUint32)clearValues.size(), &clearValues[0]); // Bind graphics pipeline deviceInterface.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline); // Bind descriptor set deviceInterface.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL); // Bind vertex buffer { const VkDeviceSize offset = 0ull; deviceInterface.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &m_vertexBuffer.get(), &offset); } // Bind Viewport deviceInterface.cmdSetViewport(commandBuffer, 0u, 1u, &viewport); // Bind Scissor Rectangle deviceInterface.cmdSetScissor(commandBuffer, 0u, 1u, &renderArea); const PushConstants pushConstants = { mipLevelNdx, 0u, // padding static_cast<float>(mipLevelSize.width), static_cast<float>(mipLevelSize.height) }; // Update push constants deviceInterface.cmdPushConstants(commandBuffer, *pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(PushConstants), &pushConstants); // Draw full screen quad deviceInterface.cmdDraw(commandBuffer, 4u, 1u, 0u, 0u); // End render pass endRenderPass(deviceInterface, commandBuffer); } { const VkImageSubresourceRange fullImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers); VkImageMemoryBarrier imageOutputTransferSrcBarriers[2]; imageOutputTransferSrcBarriers[0] = makeImageMemoryBarrier ( VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, imageTexels, fullImageSubresourceRange ); imageOutputTransferSrcBarriers[1] = makeImageMemoryBarrier ( VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, imageResidency, fullImageSubresourceRange ); deviceInterface.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 2u, imageOutputTransferSrcBarriers); } }
namespace sparse { namespace { Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface& vk, const VkDevice device, const VkPipelineLayout pipelineLayout, const VkRenderPass renderPass, const VkShaderModule vertexModule, const VkShaderModule fragmentModule, const VkShaderModule geometryModule) { const std::vector<VkViewport> noViewports; const std::vector<VkRect2D> noScissors; const VkFormat format = VK_FORMAT_R32G32_SFLOAT; const deUint32 size = tcu::getPixelSize(mapVkFormat(format)); const VkVertexInputBindingDescription vertexBinding = { 0u, // deUint32 binding; size * 2, // deUint32 stride; VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate; }; const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] = { // position { 0u, // deUint32 location; 0u, // deUint32 binding; format, // VkFormat format; 0u // deUint32 offset; }, // texture coordinates { 1u, // deUint32 location; 0u, // deUint32 binding; format, // VkFormat format; size // deUint32 offset; }, }; const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags; 1u, // deUint32 vertexBindingDescriptionCount; &vertexBinding, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 2u, // deUint32 vertexAttributeDescriptionCount; vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; }; const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; const VkPipelineColorBlendAttachmentState defaultColorBlendAttachmentState = { VK_FALSE, // VkBool32 blendEnable; VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor; VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor; VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor; VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor; VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; colorComponentsAll // VkColorComponentFlags colorWriteMask; }; const VkPipelineColorBlendAttachmentState colorBlendAttachmentStates[] = { defaultColorBlendAttachmentState, defaultColorBlendAttachmentState }; const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags; VK_FALSE, // VkBool32 logicOpEnable; VK_LOGIC_OP_COPY, // VkLogicOp logicOp; DE_LENGTH_OF_ARRAY(colorBlendAttachmentStates), // deUint32 attachmentCount; colorBlendAttachmentStates, // const VkPipelineColorBlendAttachmentState* pAttachments; { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4]; }; return vk::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 fragmentModule, // const VkShaderModule fragmentShaderModule renderPass, // const VkRenderPass renderPass noViewports, // const std::vector<VkViewport>& viewports noScissors, // const std::vector<VkRect2D>& scissors VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // const VkPrimitiveTopology topology 0u, // const deUint32 subpass 0u, // const deUint32 patchControlPoints &vertexInputStateCreateInfo, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo &pipelineColorBlendStateInfo); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo } } // anonymous void SparseShaderIntrinsicsCaseSampledBase::initPrograms (vk::SourceCollections& programCollection) const { const deUint32 numLayers = getNumLayers(m_imageType, m_imageSize); const std::string coordString = getShaderImageCoordinates(m_imageType, "%local_texCoord_x", "%local_texCoord_xy", "%local_texCoord_xyz"); // Create vertex shader std::ostringstream vs; vs << "#version 440\n" << "layout(location = 0) in highp vec2 vs_in_position;\n" << "layout(location = 1) in highp vec2 vs_in_texCoord;\n" << "\n" << "layout(location = 0) out highp vec3 vs_out_texCoord;\n" << "\n" << "out gl_PerVertex {\n" << " vec4 gl_Position;\n" << "};\n" << "void main (void)\n" << "{\n" << " gl_Position = vec4(vs_in_position, 0.0f, 1.0f);\n" << " vs_out_texCoord = vec3(vs_in_texCoord, 0.0f);\n" << "}\n"; programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str()); if (numLayers > 1u) { const deInt32 maxVertices = 3u * numLayers; // Create geometry shader std::ostringstream gs; gs << "#version 440\n" << "layout(triangles) in;\n" << "layout(triangle_strip, max_vertices = " << static_cast<deInt32>(maxVertices) << ") out;\n" << "\n" << "in gl_PerVertex {\n" << " vec4 gl_Position;\n" << "} gl_in[];\n" << "out gl_PerVertex {\n" << " vec4 gl_Position;\n" << "};\n" << "layout(location = 0) in highp vec3 gs_in_texCoord[];\n" << "\n" << "layout(location = 0) out highp vec3 gs_out_texCoord;\n" << "\n" << "void main (void)\n" << "{\n" << " for (int layerNdx = 0; layerNdx < " << static_cast<deInt32>(numLayers) << "; ++layerNdx)\n" << " {\n" << " for (int vertexNdx = 0; vertexNdx < gl_in.length(); ++vertexNdx)\n" << " {\n" << " gl_Layer = layerNdx;\n" << " gl_Position = gl_in[vertexNdx].gl_Position;\n" << " gs_out_texCoord = vec3(gs_in_texCoord[vertexNdx].xy, float(layerNdx));\n" << " EmitVertex();\n" << " }\n" << " EndPrimitive();\n" << " }\n" << "}\n"; programCollection.glslSources.add("geometry_shader") << glu::GeometrySource(gs.str()); } // Create fragment shader std::ostringstream fs; const std::string typeImgComp = getImageComponentTypeName(m_format); const std::string typeImgCompVec4 = getImageComponentVec4TypeName(m_format); fs << "OpCapability Shader\n" << "OpCapability SampledCubeArray\n" << "OpCapability ImageCubeArray\n" << "OpCapability SparseResidency\n" << "OpCapability StorageImageExtendedFormats\n" << "%ext_import = OpExtInstImport \"GLSL.std.450\"\n" << "OpMemoryModel Logical GLSL450\n" << "OpEntryPoint Fragment %func_main \"main\" %varying_texCoord %output_texel %output_residency\n" << "OpExecutionMode %func_main OriginUpperLeft\n" << "OpSource GLSL 440\n" << "OpName %func_main \"main\"\n" << "OpName %varying_texCoord \"varying_texCoord\"\n" << "OpName %output_texel \"out_texel\"\n" << "OpName %output_residency \"out_residency\"\n" << "OpName %type_uniformblock \"LodBlock\"\n" << "OpMemberName %type_uniformblock 0 \"lod\"\n" << "OpMemberName %type_uniformblock 1 \"size\"\n" << "OpName %uniformblock_instance \"lodInstance\"\n" << "OpName %uniformconst_image_sparse \"u_imageSparse\"\n" << "OpDecorate %varying_texCoord Location 0\n" << "OpDecorate %output_texel Location 0\n" << "OpDecorate %output_residency Location 1\n" << "OpDecorate %type_uniformblock Block\n" << "OpMemberDecorate %type_uniformblock 0 Offset 0\n" << "OpMemberDecorate %type_uniformblock 1 Offset 8\n" << "OpDecorate %uniformconst_image_sparse DescriptorSet 0\n" << "OpDecorate %uniformconst_image_sparse Binding " << BINDING_IMAGE_SPARSE << "\n" << "%type_void = OpTypeVoid\n" << "%type_void_func = OpTypeFunction %type_void\n" << "%type_bool = OpTypeBool\n" << "%type_int = OpTypeInt 32 1\n" << "%type_uint = OpTypeInt 32 0\n" << "%type_float = OpTypeFloat 32\n" << "%type_vec2 = OpTypeVector %type_float 2\n" << "%type_vec3 = OpTypeVector %type_float 3\n" << "%type_vec4 = OpTypeVector %type_float 4\n" << "%type_ivec4 = OpTypeVector %type_int 4\n" << "%type_uvec4 = OpTypeVector %type_uint 4\n" << "%type_uniformblock = OpTypeStruct %type_uint %type_vec2\n" << "%type_struct_int_img_comp_vec4 = OpTypeStruct %type_int " << typeImgCompVec4 << "\n" << "%type_input_vec3 = OpTypePointer Input %type_vec3\n" << "%type_input_float = OpTypePointer Input %type_float\n" << "%type_output_img_comp_vec4 = OpTypePointer Output " << typeImgCompVec4 << "\n" << "%type_output_uint = OpTypePointer Output %type_uint\n" << "%type_function_int = OpTypePointer Function %type_int\n" << "%type_function_img_comp_vec4 = OpTypePointer Function " << typeImgCompVec4 << "\n" << "%type_function_int_img_comp_vec4 = OpTypePointer Function %type_struct_int_img_comp_vec4\n" << "%type_pushconstant_uniformblock = OpTypePointer PushConstant %type_uniformblock\n" << "%type_pushconstant_uniformblock_member_lod = OpTypePointer PushConstant %type_uint\n" << "%type_pushconstant_uniformblock_member_size = OpTypePointer PushConstant %type_vec2\n" << "%type_image_sparse = " << getOpTypeImageSparse(m_imageType, m_format, typeImgComp, true) << "\n" << "%type_sampled_image_sparse = OpTypeSampledImage %type_image_sparse\n" << "%type_uniformconst_image_sparse = OpTypePointer UniformConstant %type_sampled_image_sparse\n" << "%varying_texCoord = OpVariable %type_input_vec3 Input\n" << "%output_texel = OpVariable %type_output_img_comp_vec4 Output\n" << "%output_residency = OpVariable %type_output_uint Output\n" << "%uniformconst_image_sparse = OpVariable %type_uniformconst_image_sparse UniformConstant\n" << "%uniformblock_instance = OpVariable %type_pushconstant_uniformblock PushConstant\n" // Declare constants << "%constant_uint_0 = OpConstant %type_uint 0\n" << "%constant_uint_1 = OpConstant %type_uint 1\n" << "%constant_uint_2 = OpConstant %type_uint 2\n" << "%constant_uint_3 = OpConstant %type_uint 3\n" << "%constant_int_0 = OpConstant %type_int 0\n" << "%constant_int_1 = OpConstant %type_int 1\n" << "%constant_int_2 = OpConstant %type_int 2\n" << "%constant_int_3 = OpConstant %type_int 3\n" << "%constant_float_0 = OpConstant %type_float 0.0\n" << "%constant_float_half = OpConstant %type_float 0.5\n" << "%constant_texel_resident = OpConstant %type_uint " << MEMORY_BLOCK_BOUND_VALUE << "\n" << "%constant_texel_not_resident = OpConstant %type_uint " << MEMORY_BLOCK_NOT_BOUND_VALUE << "\n" // Call main function << "%func_main = OpFunction %type_void None %type_void_func\n" << "%label_func_main = OpLabel\n" << "%local_image_sparse = OpLoad %type_sampled_image_sparse %uniformconst_image_sparse\n" << "%texCoord = OpLoad %type_vec3 %varying_texCoord\n" << "%local_texCoord_x = OpCompositeExtract %type_float %texCoord 0\n" << "%local_texCoord_y = OpCompositeExtract %type_float %texCoord 1\n" << "%local_texCoord_z = OpCompositeExtract %type_float %texCoord 2\n" << "%local_texCoord_xy = OpCompositeConstruct %type_vec2 %local_texCoord_x %local_texCoord_y\n" << "%local_texCoord_xyz = OpCompositeConstruct %type_vec3 %local_texCoord_x %local_texCoord_y %local_texCoord_z\n" << "%access_uniformblock_member_uint_lod = OpAccessChain %type_pushconstant_uniformblock_member_lod %uniformblock_instance %constant_int_0\n" << "%local_uniformblock_member_uint_lod = OpLoad %type_uint %access_uniformblock_member_uint_lod\n" << "%local_uniformblock_member_float_lod = OpConvertUToF %type_float %local_uniformblock_member_uint_lod\n" << "%access_uniformblock_member_size = OpAccessChain %type_pushconstant_uniformblock_member_size %uniformblock_instance %constant_int_1\n" << "%local_uniformblock_member_size = OpLoad %type_vec2 %access_uniformblock_member_size\n" << sparseImageOpString("%local_sparse_op_result", "%type_struct_int_img_comp_vec4", "%local_image_sparse", coordString, "%local_uniformblock_member_float_lod") << "\n" // Load texel value << "%local_img_comp_vec4 = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_op_result 1\n" << "OpStore %output_texel %local_img_comp_vec4\n" // Load residency code << "%local_residency_code = OpCompositeExtract %type_int %local_sparse_op_result 0\n" // Check if loaded texel is placed in resident memory << "%local_texel_resident = OpImageSparseTexelsResident %type_bool %local_residency_code\n" << "OpSelectionMerge %branch_texel_resident None\n" << "OpBranchConditional %local_texel_resident %label_texel_resident %label_texel_not_resident\n" << "%label_texel_resident = OpLabel\n" // Loaded texel is in resident memory << "OpStore %output_residency %constant_texel_resident\n" << "OpBranch %branch_texel_resident\n" << "%label_texel_not_resident = OpLabel\n" // Loaded texel is not in resident memory << "OpStore %output_residency %constant_texel_not_resident\n" << "OpBranch %branch_texel_resident\n" << "%branch_texel_resident = OpLabel\n" << "OpReturn\n" << "OpFunctionEnd\n"; programCollection.spirvAsmSources.add("fragment_shader") << fs.str(); } std::string SparseCaseOpImageSparseSampleExplicitLod::sparseImageOpString (const std::string& resultVariable, const std::string& resultType, const std::string& image, const std::string& coord, const std::string& miplevel) const { std::ostringstream src; src << resultVariable << " = OpImageSparseSampleExplicitLod " << resultType << " " << image << " " << coord << " Lod " << miplevel << "\n"; return src.str(); } std::string SparseCaseOpImageSparseSampleImplicitLod::sparseImageOpString (const std::string& resultVariable, const std::string& resultType, const std::string& image, const std::string& coord, const std::string& miplevel) const { DE_UNREF(miplevel); std::ostringstream src; src << resultVariable << " = OpImageSparseSampleImplicitLod " << resultType << " " << image << " " << coord << "\n"; return src.str(); } std::string SparseCaseOpImageSparseGather::sparseImageOpString (const std::string& resultVariable, const std::string& resultType, const std::string& image, const std::string& coord, const std::string& miplevel) const { DE_UNREF(miplevel); std::ostringstream src; const std::string typeImgComp = getImageComponentTypeName(m_format); const std::string typeImgCompVec4 = getImageComponentVec4TypeName(m_format); // Bias the coord value by half a texel, so we sample from center of 2x2 gather rectangle src << "%local_image_width = OpCompositeExtract %type_float %local_uniformblock_member_size 0\n"; src << "%local_image_height = OpCompositeExtract %type_float %local_uniformblock_member_size 1\n"; src << "%local_coord_x_bias = OpFDiv %type_float %constant_float_half %local_image_width\n"; src << "%local_coord_y_bias = OpFDiv %type_float %constant_float_half %local_image_height\n"; switch (m_imageType) { case IMAGE_TYPE_2D: { src << "%local_coord_bias = OpCompositeConstruct %type_vec2 %local_coord_x_bias %local_coord_y_bias\n"; src << "%local_coord_biased = OpFAdd %type_vec2 " << coord << " %local_coord_bias\n"; break; } case IMAGE_TYPE_2D_ARRAY: case IMAGE_TYPE_3D: { src << "%local_coord_bias = OpCompositeConstruct %type_vec3 %local_coord_x_bias %local_coord_y_bias %constant_float_0\n"; src << "%local_coord_biased = OpFAdd %type_vec3 " << coord << " %local_coord_bias\n"; break; } default: { /* This can't be happening. */ DE_ASSERT(DE_FALSE); } } src << "%local_sparse_gather_result_x = OpImageSparseGather " << resultType << " " << image << " %local_coord_biased %constant_int_0\n"; src << "%local_sparse_gather_result_y = OpImageSparseGather " << resultType << " " << image << " %local_coord_biased %constant_int_1\n"; src << "%local_sparse_gather_result_z = OpImageSparseGather " << resultType << " " << image << " %local_coord_biased %constant_int_2\n"; src << "%local_sparse_gather_result_w = OpImageSparseGather " << resultType << " " << image << " %local_coord_biased %constant_int_3\n"; src << "%local_gather_residency_code = OpCompositeExtract %type_int %local_sparse_gather_result_x 0\n"; src << "%local_gather_texels_x = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_gather_result_x 1\n"; src << "%local_gather_texels_y = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_gather_result_y 1\n"; src << "%local_gather_texels_z = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_gather_result_z 1\n"; src << "%local_gather_texels_w = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_gather_result_w 1\n"; src << "%local_gather_primary_texel_x = OpCompositeExtract " << typeImgComp << " %local_gather_texels_x 3\n"; src << "%local_gather_primary_texel_y = OpCompositeExtract " << typeImgComp << " %local_gather_texels_y 3\n"; src << "%local_gather_primary_texel_z = OpCompositeExtract " << typeImgComp << " %local_gather_texels_z 3\n"; src << "%local_gather_primary_texel_w = OpCompositeExtract " << typeImgComp << " %local_gather_texels_w 3\n"; src << "%local_gather_primary_texel = OpCompositeConstruct " << typeImgCompVec4 << " %local_gather_primary_texel_x %local_gather_primary_texel_y %local_gather_primary_texel_z %local_gather_primary_texel_w\n"; src << resultVariable << " = OpCompositeConstruct " << resultType << " %local_gather_residency_code %local_gather_primary_texel\n"; return src.str(); } class SparseShaderIntrinsicsInstanceSampledBase : public SparseShaderIntrinsicsInstanceBase { public: SparseShaderIntrinsicsInstanceSampledBase (Context& context, const SpirVFunction function, const ImageType imageType, const tcu::UVec3& imageSize, const tcu::TextureFormat& format) : SparseShaderIntrinsicsInstanceBase(context, function, imageType, imageSize, format) {} VkImageUsageFlags imageSparseUsageFlags (void) const; VkImageUsageFlags imageOutputUsageFlags (void) const; VkQueueFlags getQueueFlags (void) const; void recordCommands (const VkCommandBuffer commandBuffer, const VkImageCreateInfo& imageSparseInfo, const VkImage imageSparse, const VkImage imageTexels, const VkImage imageResidency); virtual VkImageSubresourceRange sampledImageRangeToBind(const VkImageCreateInfo& imageSparseInfo, const deUint32 mipLevel) const = 0; private: typedef de::SharedPtr< vk::Unique<vk::VkFramebuffer> > VkFramebufferSp; Move<VkBuffer> m_vertexBuffer; de::MovePtr<Allocation> m_vertexBufferAlloc; std::vector<VkFramebufferSp> m_framebuffers; Move<VkRenderPass> m_renderPass; Move<VkSampler> m_sampler; }; VkImageUsageFlags SparseShaderIntrinsicsInstanceSampledBase::imageSparseUsageFlags (void) const { return VK_IMAGE_USAGE_SAMPLED_BIT; } VkImageUsageFlags SparseShaderIntrinsicsInstanceSampledBase::imageOutputUsageFlags (void) const { return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; } VkQueueFlags SparseShaderIntrinsicsInstanceSampledBase::getQueueFlags (void) const { return VK_QUEUE_GRAPHICS_BIT; } void SparseShaderIntrinsicsInstanceSampledBase::recordCommands (const VkCommandBuffer commandBuffer, const VkImageCreateInfo& imageSparseInfo, const VkImage imageSparse, const VkImage imageTexels, const VkImage imageResidency) { const InstanceInterface& instance = m_context.getInstanceInterface(); const DeviceInterface& deviceInterface = getDeviceInterface(); const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice(); const VkPhysicalDeviceProperties deviceProperties = getPhysicalDeviceProperties(instance, physicalDevice); if (imageSparseInfo.extent.width > deviceProperties.limits.maxFramebufferWidth || imageSparseInfo.extent.height > deviceProperties.limits.maxFramebufferHeight || imageSparseInfo.arrayLayers > deviceProperties.limits.maxFramebufferLayers) { TCU_THROW(NotSupportedError, "Image size exceeds allowed framebuffer dimensions"); } // Check if device supports image format for sampled images if (!checkImageFormatFeatureSupport(instance, physicalDevice, imageSparseInfo.format, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) TCU_THROW(NotSupportedError, "Device does not support image format for sampled images"); // Check if device supports image format for color attachment if (!checkImageFormatFeatureSupport(instance, physicalDevice, imageSparseInfo.format, VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) TCU_THROW(NotSupportedError, "Device does not support image format for color attachment"); // Make sure device supports VK_FORMAT_R32_UINT format for color attachment if (!checkImageFormatFeatureSupport(instance, physicalDevice, mapTextureFormat(m_residencyFormat), VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) TCU_THROW(TestError, "Device does not support VK_FORMAT_R32_UINT format for color attachment"); // Create buffer storing vertex data std::vector<tcu::Vec2> vertexData; vertexData.push_back(tcu::Vec2(-1.0f,-1.0f)); vertexData.push_back(tcu::Vec2( 0.0f, 0.0f)); vertexData.push_back(tcu::Vec2(-1.0f, 1.0f)); vertexData.push_back(tcu::Vec2( 0.0f, 1.0f)); vertexData.push_back(tcu::Vec2( 1.0f,-1.0f)); vertexData.push_back(tcu::Vec2( 1.0f, 0.0f)); vertexData.push_back(tcu::Vec2( 1.0f, 1.0f)); vertexData.push_back(tcu::Vec2( 1.0f, 1.0f)); const VkDeviceSize vertexDataSizeInBytes = sizeInBytes(vertexData); const VkBufferCreateInfo vertexBufferCreateInfo = makeBufferCreateInfo(vertexDataSizeInBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); m_vertexBuffer = createBuffer(deviceInterface, getDevice(), &vertexBufferCreateInfo); m_vertexBufferAlloc = bindBuffer(deviceInterface, getDevice(), getAllocator(), *m_vertexBuffer, MemoryRequirement::HostVisible); deMemcpy(m_vertexBufferAlloc->getHostPtr(), &vertexData[0], static_cast<std::size_t>(vertexDataSizeInBytes)); flushMappedMemoryRange(deviceInterface, getDevice(), m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset(), vertexDataSizeInBytes); // Create render pass const VkAttachmentDescription texelsAttachmentDescription = { (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; imageSparseInfo.format, // VkFormat format; VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; }; const VkAttachmentDescription residencyAttachmentDescription = { (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; mapTextureFormat(m_residencyFormat), // VkFormat format; VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; }; const VkAttachmentDescription colorAttachmentsDescription[] = { texelsAttachmentDescription, residencyAttachmentDescription }; const VkAttachmentReference texelsAttachmentReference = { 0u, // deUint32 attachment; VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; }; const VkAttachmentReference residencyAttachmentReference = { 1u, // deUint32 attachment; VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; }; const VkAttachmentReference colorAttachmentsReference[] = { texelsAttachmentReference, residencyAttachmentReference }; const VkAttachmentReference depthAttachmentReference = { VK_ATTACHMENT_UNUSED, // deUint32 attachment; VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout; }; const VkSubpassDescription subpassDescription = { (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 0u, // deUint32 inputAttachmentCount; DE_NULL, // const VkAttachmentReference* pInputAttachments; 2u, // deUint32 colorAttachmentCount; colorAttachmentsReference, // const VkAttachmentReference* pColorAttachments; DE_NULL, // const VkAttachmentReference* pResolveAttachments; &depthAttachmentReference, // const VkAttachmentReference* pDepthStencilAttachment; 0u, // deUint32 preserveAttachmentCount; DE_NULL // const deUint32* pPreserveAttachments; }; const VkRenderPassCreateInfo renderPassInfo = { VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags; 2u, // deUint32 attachmentCount; colorAttachmentsDescription, // const VkAttachmentDescription* pAttachments; 1u, // deUint32 subpassCount; &subpassDescription, // const VkSubpassDescription* pSubpasses; 0u, // deUint32 dependencyCount; DE_NULL // const VkSubpassDependency* pDependencies; }; m_renderPass = createRenderPass(deviceInterface, getDevice(), &renderPassInfo); // Create descriptor set layout DescriptorSetLayoutBuilder descriptorLayerBuilder; descriptorLayerBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT); const Unique<VkDescriptorSetLayout> descriptorSetLayout(descriptorLayerBuilder.build(deviceInterface, getDevice())); // Create descriptor pool DescriptorPoolBuilder descriptorPoolBuilder; descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, imageSparseInfo.mipLevels); descriptorPool = descriptorPoolBuilder.build(deviceInterface, getDevice(), VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, imageSparseInfo.mipLevels); // Create sampler object const tcu::Sampler samplerObject(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::NEAREST_MIPMAP_NEAREST, tcu::Sampler::NEAREST); const VkSamplerCreateInfo samplerCreateInfo = mapSampler(samplerObject, m_format); m_sampler = createSampler(deviceInterface, getDevice(), &samplerCreateInfo); struct PushConstants { deUint32 lod; deUint32 padding; // padding needed to satisfy std430 rules float lodWidth; float lodHeight; }; // Create pipeline layout const VkPushConstantRange lodConstantRange = { VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags; 0u, // deUint32 offset; sizeof(PushConstants), // deUint32 size; }; const VkPipelineLayoutCreateInfo pipelineLayoutParams = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; 0u, // VkPipelineLayoutCreateFlags flags; 1u, // deUint32 setLayoutCount; &descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts; 1u, // deUint32 pushConstantRangeCount; &lodConstantRange, // const VkPushConstantRange* pPushConstantRanges; }; const Unique<VkPipelineLayout> pipelineLayout(createPipelineLayout(deviceInterface, getDevice(), &pipelineLayoutParams)); // Create graphics pipeline { Move<VkShaderModule> vertexModule = createShaderModule(deviceInterface, getDevice(), m_context.getBinaryCollection().get("vertex_shader"), (VkShaderModuleCreateFlags)0); Move<VkShaderModule> fragmentModule = createShaderModule(deviceInterface, getDevice(), m_context.getBinaryCollection().get("fragment_shader"), (VkShaderModuleCreateFlags)0); Move<VkShaderModule> geometryModule; if (imageSparseInfo.arrayLayers > 1u) { requireFeatures(instance, physicalDevice, FEATURE_GEOMETRY_SHADER); geometryModule = createShaderModule(deviceInterface, getDevice(), m_context.getBinaryCollection().get("geometry_shader"), (VkShaderModuleCreateFlags)0); } pipelines.push_back(makeVkSharedPtr(makeGraphicsPipeline( deviceInterface, getDevice(), *pipelineLayout, *m_renderPass, *vertexModule, *fragmentModule, *geometryModule))); } const VkPipeline graphicsPipeline = **pipelines[0]; { const VkImageSubresourceRange fullImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers); VkImageMemoryBarrier imageShaderAccessBarriers[3]; imageShaderAccessBarriers[0] = makeImageMemoryBarrier ( VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, imageSparse, fullImageSubresourceRange ); imageShaderAccessBarriers[1] = makeImageMemoryBarrier ( 0u, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, imageTexels, fullImageSubresourceRange ); imageShaderAccessBarriers[2] = makeImageMemoryBarrier ( 0u, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, imageResidency, fullImageSubresourceRange ); deviceInterface.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 3u, imageShaderAccessBarriers); } imageSparseViews.resize(imageSparseInfo.mipLevels); imageTexelsViews.resize(imageSparseInfo.mipLevels); imageResidencyViews.resize(imageSparseInfo.mipLevels); m_framebuffers.resize(imageSparseInfo.mipLevels); descriptorSets.resize(imageSparseInfo.mipLevels); std::vector<VkClearValue> clearValues; clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f))); clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f))); for (deUint32 mipLevelNdx = 0u; mipLevelNdx < imageSparseInfo.mipLevels; ++mipLevelNdx) { const vk::VkExtent3D mipLevelSize = mipLevelExtents(imageSparseInfo.extent, mipLevelNdx); const vk::VkRect2D renderArea = makeRect2D(mipLevelSize); const VkViewport viewport = makeViewport(mipLevelSize); const VkImageSubresourceRange mipLevelRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, mipLevelNdx, 1u, 0u, imageSparseInfo.arrayLayers); // Create color attachments image views imageTexelsViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), imageTexels, mapImageViewType(m_imageType), imageSparseInfo.format, mipLevelRange)); imageResidencyViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), imageResidency, mapImageViewType(m_imageType), mapTextureFormat(m_residencyFormat), mipLevelRange)); const VkImageView attachmentsViews[] = { **imageTexelsViews[mipLevelNdx], **imageResidencyViews[mipLevelNdx] }; // Create framebuffer const VkFramebufferCreateInfo framebufferInfo = { VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkFramebufferCreateFlags)0, // VkFramebufferCreateFlags flags; *m_renderPass, // VkRenderPass renderPass; 2u, // uint32_t attachmentCount; attachmentsViews, // const VkImageView* pAttachments; mipLevelSize.width, // uint32_t width; mipLevelSize.height, // uint32_t height; imageSparseInfo.arrayLayers, // uint32_t layers; }; m_framebuffers[mipLevelNdx] = makeVkSharedPtr(createFramebuffer(deviceInterface, getDevice(), &framebufferInfo)); // Create descriptor set descriptorSets[mipLevelNdx] = makeVkSharedPtr(makeDescriptorSet(deviceInterface, getDevice(), *descriptorPool, *descriptorSetLayout)); const VkDescriptorSet descriptorSet = **descriptorSets[mipLevelNdx]; // Update descriptor set const VkImageSubresourceRange sparseImageSubresourceRange = sampledImageRangeToBind(imageSparseInfo, mipLevelNdx); imageSparseViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), imageSparse, mapImageViewType(m_imageType), imageSparseInfo.format, sparseImageSubresourceRange)); const VkDescriptorImageInfo imageSparseDescInfo = makeDescriptorImageInfo(*m_sampler, **imageSparseViews[mipLevelNdx], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); DescriptorSetUpdateBuilder descriptorUpdateBuilder; descriptorUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(BINDING_IMAGE_SPARSE), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSparseDescInfo); descriptorUpdateBuilder.update(deviceInterface, getDevice()); // Begin render pass beginRenderPass(deviceInterface, commandBuffer, *m_renderPass, **m_framebuffers[mipLevelNdx], renderArea, (deUint32)clearValues.size(), &clearValues[0]); // Bind graphics pipeline deviceInterface.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline); // Bind descriptor set deviceInterface.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL); // Bind vertex buffer { const VkDeviceSize offset = 0ull; deviceInterface.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &m_vertexBuffer.get(), &offset); } // Bind Viewport deviceInterface.cmdSetViewport(commandBuffer, 0u, 1u, &viewport); // Bind Scissor Rectangle deviceInterface.cmdSetScissor(commandBuffer, 0u, 1u, &renderArea); const PushConstants pushConstants = { mipLevelNdx, 0u, // padding static_cast<float>(mipLevelSize.width), static_cast<float>(mipLevelSize.height) }; // Update push constants deviceInterface.cmdPushConstants(commandBuffer, *pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(PushConstants), &pushConstants); // Draw full screen quad deviceInterface.cmdDraw(commandBuffer, 4u, 1u, 0u, 0u); // End render pass endRenderPass(deviceInterface, commandBuffer); } { const VkImageSubresourceRange fullImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers); VkImageMemoryBarrier imageOutputTransferSrcBarriers[2]; imageOutputTransferSrcBarriers[0] = makeImageMemoryBarrier ( VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, imageTexels, fullImageSubresourceRange ); imageOutputTransferSrcBarriers[1] = makeImageMemoryBarrier ( VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, imageResidency, fullImageSubresourceRange ); deviceInterface.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 2u, imageOutputTransferSrcBarriers); } } class SparseShaderIntrinsicsInstanceSampledExplicit : public SparseShaderIntrinsicsInstanceSampledBase { public: SparseShaderIntrinsicsInstanceSampledExplicit (Context& context, const SpirVFunction function, const ImageType imageType, const tcu::UVec3& imageSize, const tcu::TextureFormat& format) : SparseShaderIntrinsicsInstanceSampledBase(context, function, imageType, imageSize, format) {} VkImageSubresourceRange sampledImageRangeToBind (const VkImageCreateInfo& imageSparseInfo, const deUint32 mipLevel) const { DE_UNREF(mipLevel); return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers); } }; TestInstance* SparseShaderIntrinsicsCaseSampledExplicit::createInstance (Context& context) const { return new SparseShaderIntrinsicsInstanceSampledExplicit(context, m_function, m_imageType, m_imageSize, m_format); } class SparseShaderIntrinsicsInstanceSampledImplicit : public SparseShaderIntrinsicsInstanceSampledBase { public: SparseShaderIntrinsicsInstanceSampledImplicit (Context& context, const SpirVFunction function, const ImageType imageType, const tcu::UVec3& imageSize, const tcu::TextureFormat& format) : SparseShaderIntrinsicsInstanceSampledBase(context, function, imageType, imageSize, format) {} VkImageSubresourceRange sampledImageRangeToBind (const VkImageCreateInfo& imageSparseInfo, const deUint32 mipLevel) const { return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, mipLevel, 1u, 0u, imageSparseInfo.arrayLayers); } }; TestInstance* SparseShaderIntrinsicsCaseSampledImplicit::createInstance (Context& context) const { return new SparseShaderIntrinsicsInstanceSampledImplicit(context, m_function, m_imageType, m_imageSize, m_format); } } // sparse