void LLDrawPoolAlpha::endPostDeferredPass(S32 pass) { if (pass == 1 && !LLPipeline::sImpostorRender) { gPipeline.mDeferredDepth.flush(); gPipeline.mScreen.bindTarget(); gObjectFullbrightAlphaMaskProgram.unbind(); } deferred_render = FALSE; endRenderPass(pass); }
void LLDrawPoolAlpha::endPostDeferredPass(S32 pass) { if (pass == 1) { gPipeline.mDeferredDepth.flush(); gPipeline.mScreen.bindTarget(); } deferred_render = FALSE; endRenderPass(pass); }
void VkPPRenderState::RenderScreenQuad(VkPPRenderPassSetup *passSetup, VulkanDescriptorSet *descriptorSet, VulkanFramebuffer *framebuffer, int framebufferWidth, int framebufferHeight, int x, int y, int width, int height, const void *pushConstants, uint32_t pushConstantsSize, bool stencilTest) { auto fb = GetVulkanFrameBuffer(); auto cmdbuffer = fb->GetDrawCommands(); VkViewport viewport = { }; viewport.x = x; viewport.y = y; viewport.width = width; viewport.height = height; viewport.minDepth = 0.0f; viewport.maxDepth = 1.0f; VkRect2D scissor = { }; scissor.offset.x = 0; scissor.offset.y = 0; scissor.extent.width = framebufferWidth; scissor.extent.height = framebufferHeight; RenderPassBegin beginInfo; beginInfo.setRenderPass(passSetup->RenderPass.get()); beginInfo.setRenderArea(0, 0, framebufferWidth, framebufferHeight); beginInfo.setFramebuffer(framebuffer); beginInfo.addClearColor(0.0f, 0.0f, 0.0f, 1.0f); VkBuffer vertexBuffers[] = { static_cast<VKVertexBuffer*>(screen->mVertexData->GetBufferObjects().first)->mBuffer->buffer }; VkDeviceSize offsets[] = { 0 }; cmdbuffer->beginRenderPass(beginInfo); cmdbuffer->bindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, passSetup->Pipeline.get()); cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, passSetup->PipelineLayout.get(), 0, descriptorSet); cmdbuffer->bindVertexBuffers(0, 1, vertexBuffers, offsets); cmdbuffer->setViewport(0, 1, &viewport); cmdbuffer->setScissor(0, 1, &scissor); if (stencilTest) cmdbuffer->setStencilReference(VK_STENCIL_FRONT_AND_BACK, screen->stencilValue); if (pushConstantsSize > 0) cmdbuffer->pushConstants(passSetup->PipelineLayout.get(), VK_SHADER_STAGE_FRAGMENT_BIT, 0, pushConstantsSize, pushConstants); cmdbuffer->draw(4, 1, FFlatVertexBuffer::PRESENT_INDEX, 0); cmdbuffer->endRenderPass(); }
void LLDrawPoolAlpha::endPostDeferredPass(S32 pass) { deferred_render = FALSE; endRenderPass(pass); }
void LLDrawPoolWater::endPostDeferredPass(S32 pass) { endRenderPass(pass); deferred_render = FALSE; }
void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) { if (pass == -1) { for (S32 i = 1; i < getNumPasses(); i++) { //skip foot shadows prerender(); beginRenderPass(i); renderAvatars(single_avatar, i); endRenderPass(i); } return; } if (mDrawFace.empty() && !single_avatar) { return; } LLVOAvatar *avatarp; if (single_avatar) { avatarp = single_avatar; } else { const LLFace *facep = mDrawFace[0]; if (!facep->getDrawable()) { return; } avatarp = (LLVOAvatar *)facep->getDrawable()->getVObj().get(); } if (avatarp->isDead() || avatarp->mDrawable.isNull()) { return; } if (!single_avatar && !avatarp->isFullyLoaded()) { if (pass == 0 && (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES) || LLViewerPartSim::getMaxPartCount() <= 0)) { // debug code to draw a sphere in place of avatar gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); gGL.setColorMask(true, true); LLVector3 pos = avatarp->getPositionAgent(); gGL.color4f(1.0f, 1.0f, 1.0f, 0.7f); gGL.pushMatrix(); gGL.translatef((F32)(pos.mV[VX]), (F32)(pos.mV[VY]), (F32)(pos.mV[VZ])); gGL.scalef(0.15f, 0.15f, 0.3f); gSphere.renderGGL(); gGL.popMatrix(); gGL.setColorMask(true, false); } // don't render please return; } BOOL impostor = avatarp->isImpostor() && !single_avatar; if (impostor && pass != 0) { //don't draw anything but the impostor for impostored avatars return; } if (pass == 0 && !impostor && LLPipeline::sUnderWaterRender) { //don't draw foot shadows under water return; } if (pass == 0) { if (!LLPipeline::sReflectionRender) { LLVOAvatar::sNumVisibleAvatars++; } if (impostor) { if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && avatarp->mImpostor.isComplete()) { if (normal_channel > -1) { avatarp->mImpostor.bindTexture(2, normal_channel); } if (specular_channel > -1) { avatarp->mImpostor.bindTexture(1, specular_channel); } } avatarp->renderImpostor(LLColor4U(255,255,255,255), sDiffuseChannel); } return; } if (single_avatar && avatarp->mSpecialRenderMode >= 1) // 1=anim preview, 2=image preview, 3=morph view { gPipeline.enableLightsAvatarEdit(LLColor4(.5f, .5f, .5f, 1.f)); } if (pass == 1) { // render rigid meshes (eyeballs) first avatarp->renderRigid(); return; } if (pass == 3) { if (is_deferred_render) { renderDeferredRiggedSimple(avatarp); } else { renderRiggedSimple(avatarp); } return; } if (pass == 4) { if (is_deferred_render) { renderDeferredRiggedBump(avatarp); } else { renderRiggedFullbright(avatarp); } return; } if (pass == 5) { renderRiggedShinySimple(avatarp); return; } if (pass == 6) { renderRiggedFullbrightShiny(avatarp); return; } if (pass >= 7 && pass < 9) { LLGLEnable blend(GL_BLEND); gGL.setColorMask(true, true); gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA, LLRender::BF_ZERO, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); if (pass == 7) { renderRiggedAlpha(avatarp); return; } if (pass == 8) { renderRiggedFullbrightAlpha(avatarp); return; } } if (pass == 9) { LLGLEnable blend(GL_BLEND); LLGLDisable test(GL_ALPHA_TEST); gGL.flush(); LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); glPolygonOffset(-1.0f, -1.0f); gGL.setSceneBlendType(LLRender::BT_ADD); LLGLDepthTest depth(GL_TRUE, GL_FALSE); gGL.setColorMask(false, true); renderRiggedGlow(avatarp); gGL.setColorMask(true, false); gGL.setSceneBlendType(LLRender::BT_ALPHA); return; } if (sShaderLevel > 0) { gAvatarMatrixParam = sVertexProgram->mUniform[LLViewerShaderMgr::AVATAR_MATRIX]; } if (sShaderLevel >= SHADER_LEVEL_CLOTH) { LLMatrix4 rot_mat; LLViewerCamera::getInstance()->getMatrixToLocal(rot_mat); LLMatrix4 cfr(OGL_TO_CFR_ROTATION); rot_mat *= cfr; LLVector4 wind; wind.setVec(avatarp->mWindVec); wind.mV[VW] = 0; wind = wind * rot_mat; wind.mV[VW] = avatarp->mWindVec.mV[VW]; sVertexProgram->vertexAttrib4fv(LLViewerShaderMgr::AVATAR_WIND, wind.mV); F32 phase = -1.f * (avatarp->mRipplePhase); F32 freq = 7.f + (noise1(avatarp->mRipplePhase) * 2.f); LLVector4 sin_params(freq, freq, freq, phase); sVertexProgram->vertexAttrib4fv(LLViewerShaderMgr::AVATAR_SINWAVE, sin_params.mV); LLVector4 gravity(0.f, 0.f, -CLOTHING_GRAVITY_EFFECT, 0.f); gravity = gravity * rot_mat; sVertexProgram->vertexAttrib4fv(LLViewerShaderMgr::AVATAR_GRAVITY, gravity.mV); } if (!single_avatar || avatarp == single_avatar) { avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE); } }
void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) { LLFastTimer t(FTM_RENDER_AVATARS); if (pass == -1) { for (S32 i = 1; i < getNumPasses(); i++) { //skip foot shadows prerender(); beginRenderPass(i); renderAvatars(single_avatar, i); endRenderPass(i); } return; } if (mDrawFace.empty() && !single_avatar) { return; } LLVOAvatar *avatarp; if (single_avatar) { avatarp = single_avatar; } else { const LLFace *facep = mDrawFace[0]; if (!facep->getDrawable()) { return; } avatarp = (LLVOAvatar *)facep->getDrawable()->getVObj().get(); } if (avatarp->isDead() || avatarp->mDrawable.isNull()) { return; } if (!single_avatar && !avatarp->isFullyLoaded() ) { if (pass==0 && (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES) || LLViewerPartSim::getMaxPartCount() <= 0)) { // debug code to draw a sphere in place of avatar gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); gGL.setColorMask(true, true); LLVector3 pos = avatarp->getPositionAgent(); gGL.color4f(1.0f, 1.0f, 1.0f, 0.7f); gGL.pushMatrix(); gGL.translatef((F32)(pos.mV[VX]), (F32)(pos.mV[VY]), (F32)(pos.mV[VZ])); gGL.scalef(0.15f, 0.15f, 0.3f); gSphere.renderGGL(); gGL.popMatrix(); gGL.setColorMask(true, false); } // don't render please return; } BOOL impostor = avatarp->isImpostor() && !single_avatar; if (impostor && pass != 0) { //don't draw anything but the impostor for impostored avatars return; } if (pass == 0 && !impostor && LLPipeline::sUnderWaterRender) { //don't draw foot shadows under water return; } if (pass == 0) { if (!LLPipeline::sReflectionRender) { LLVOAvatar::sNumVisibleAvatars++; } if (impostor) { if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && avatarp->mImpostor.isComplete()) { if (normal_channel > -1) { avatarp->mImpostor.bindTexture(2, normal_channel); } if (specular_channel > -1) { avatarp->mImpostor.bindTexture(1, specular_channel); } } avatarp->renderImpostor(LLColor4U(255,255,255,255), sDiffuseChannel); } //else if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOOT_SHADOWS) && !LLPipeline::sRenderDeferred) //{ // avatarp->renderFootShadows(); //} return; } llassert(LLPipeline::sImpostorRender || !avatarp->isVisuallyMuted()); /*if (single_avatar && avatarp->mSpecialRenderMode >= 1) // 1=anim preview, 2=image preview, 3=morph view { gPipeline.enableLightsAvatarEdit(LLColor4(.5f, .5f, .5f, 1.f)); }*/ if (pass == 1) { // render rigid meshes (eyeballs) first avatarp->renderRigid(); return; } if (pass == 3) { if (is_deferred_render) { renderDeferredRiggedSimple(avatarp); } else { renderRiggedSimple(avatarp); if (LLPipeline::sRenderDeferred) { //render "simple" materials renderRigged(avatarp, RIGGED_MATERIAL); renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_MASK); renderRigged(avatarp, RIGGED_MATERIAL_ALPHA_EMISSIVE); renderRigged(avatarp, RIGGED_NORMMAP); renderRigged(avatarp, RIGGED_NORMMAP_MASK); renderRigged(avatarp, RIGGED_NORMMAP_EMISSIVE); renderRigged(avatarp, RIGGED_SPECMAP); renderRigged(avatarp, RIGGED_SPECMAP_MASK); renderRigged(avatarp, RIGGED_SPECMAP_EMISSIVE); renderRigged(avatarp, RIGGED_NORMSPEC); renderRigged(avatarp, RIGGED_NORMSPEC_MASK); renderRigged(avatarp, RIGGED_NORMSPEC_EMISSIVE); } } return; } if (pass == 4) { if (is_deferred_render) { renderDeferredRiggedBump(avatarp); } else { renderRiggedFullbright(avatarp); } return; } if (is_deferred_render && pass >= 5 && pass <= 21) { S32 p = pass-5; if (p != 1 && p != 5 && p != 9 && p != 13) { renderDeferredRiggedMaterial(avatarp, p); } return; } if (pass == 5) { renderRiggedShinySimple(avatarp); return; } if (pass == 6) { renderRiggedFullbrightShiny(avatarp); return; } if (pass >= 7 && pass < 13) { if (pass == 7) { renderRiggedAlpha(avatarp); if (LLPipeline::sRenderDeferred && !is_post_deferred_render) { //render transparent materials under water LLGLEnable blend(GL_BLEND); gGL.setColorMask(true, true); gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA, LLRender::BF_ZERO, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); renderRigged(avatarp, RIGGED_MATERIAL_ALPHA); renderRigged(avatarp, RIGGED_SPECMAP_BLEND); renderRigged(avatarp, RIGGED_NORMMAP_BLEND); renderRigged(avatarp, RIGGED_NORMSPEC_BLEND); gGL.setSceneBlendType(LLRender::BT_ALPHA); gGL.setColorMask(true, false); } return; } if (pass == 8) { renderRiggedFullbrightAlpha(avatarp); return; } if (LLPipeline::sRenderDeferred && is_post_deferred_render) { S32 p = 0; switch (pass) { case 9: p = 1; break; case 10: p = 5; break; case 11: p = 9; break; case 12: p = 13; break; } { LLGLEnable blend(GL_BLEND); renderDeferredRiggedMaterial(avatarp, p); } return; } else if (pass == 9) { renderRiggedGlow(avatarp); return; } } if (pass == 13) { renderRiggedGlow(avatarp); return; } if ((sShaderLevel >= SHADER_LEVEL_CLOTH)) { LLMatrix4 rot_mat; LLViewerCamera::getInstance()->getMatrixToLocal(rot_mat); LLMatrix4 cfr(OGL_TO_CFR_ROTATION.getF32ptr()); rot_mat *= cfr; LLVector4 wind; wind.setVec(avatarp->mWindVec); wind.mV[VW] = 0; wind = wind * rot_mat; wind.mV[VW] = avatarp->mWindVec.mV[VW]; sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_WIND, 1, wind.mV); F32 phase = -1.f * (avatarp->mRipplePhase); F32 freq = 7.f + (noise1(avatarp->mRipplePhase) * 2.f); LLVector4 sin_params(freq, freq, freq, phase); sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_SINWAVE, 1, sin_params.mV); LLVector4 gravity(0.f, 0.f, -CLOTHING_GRAVITY_EFFECT, 0.f); gravity = gravity * rot_mat; sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_GRAVITY, 1, gravity.mV); } if( !single_avatar || (avatarp == single_avatar) ) { avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE); } }
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); } }