| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #include <Atom/RPI.Public/Image/AttachmentImagePool.h>
- #include <Atom/RPI.Public/Image/ImageSystemInterface.h>
- #include <Checkerboard/CheckerboardPass.h>
- namespace AZ
- {
- namespace Render
- {
- RPI::Ptr<Render::CheckerboardPass> CheckerboardPass::Create(const RPI::PassDescriptor& descriptor)
- {
- return aznew CheckerboardPass(descriptor);
- }
- CheckerboardPass::CheckerboardPass(const RPI::PassDescriptor& descriptor)
- : Base(descriptor)
- {
- // CheckerboardPass defines its own viewport and scissor
- m_overrideViewportState = true;
- m_overrideScissorSate = true;
- }
- void CheckerboardPass::FrameBeginInternal(FramePrepareParams params)
- {
- float width = (params.m_viewportState.m_maxX - params.m_viewportState.m_minX) * 0.5f;
- float height = (params.m_viewportState.m_maxY - params.m_viewportState.m_minY) * 0.5f;
-
- m_viewportState = params.m_viewportState;
- m_viewportState.m_minX += 0.5f * m_frameOffset;
- m_viewportState.m_maxX = m_viewportState.m_minX + width;
- m_viewportState.m_maxY = m_viewportState.m_minY + height;
- m_scissorState = params.m_scissorState;
- m_scissorState.m_maxX = m_scissorState.m_minX + (m_scissorState.m_maxX - m_scissorState.m_minX) / 2;
- m_scissorState.m_maxY = m_scissorState.m_minY + (m_scissorState.m_maxY - m_scissorState.m_minY) / 2;
-
- Base::FrameBeginInternal(params);
- }
- void CheckerboardPass::BuildInternal()
- {
- Data::Instance<RPI::AttachmentImagePool> pool = RPI::ImageSystemInterface::Get()->GetSystemAttachmentPool();
- // Create persistent attachment images to replace transient pass attachments
- // It's better to check if it connects to output slots too
- for (RPI::Ptr<RPI::PassAttachment>& attachment : m_ownedAttachments)
- {
- if (attachment->m_lifetime == RHI::AttachmentLifetimeType::Transient)
- {
- if (attachment->m_descriptor.m_type == RHI::AttachmentType::Image)
- {
- // Force update image attachment descriptor to sync up size and format
- attachment->Update();
- attachment->m_lifetime = RHI::AttachmentLifetimeType::Imported;
- // update image descriptor to new size and samples
- RHI::ImageDescriptor &imageDesc = attachment->m_descriptor.m_image;
- imageDesc.m_multisampleState.m_samples = 2;
- imageDesc.m_size.m_width /= 2;
- imageDesc.m_size.m_height /= 2;
- // using hard coded clear value here until we can get the information from pass templated data
- // [GFX TODO][ATOM-5406] We need a clear value for PassAttachmentDesc and PassAttachment
- RHI::ClearValue clearValue = RHI::ClearValue::CreateVector4Float(0, 0, 0, 0);
-
- if (imageDesc.m_format == RHI::Format::D32_FLOAT_S8X24_UINT) //hacky condition check
- {
- imageDesc.m_bindFlags |= RHI::ImageBindFlags::DepthStencil;
- }
- else
- {
- imageDesc.m_bindFlags |= RHI::ImageBindFlags::Color;
- }
-
- m_imageAttachments[attachment->m_name][0] = RPI::AttachmentImage::Create(*pool.get(), imageDesc,
- Name(AZStd::string::format("%s_0", attachment->m_path.GetCStr())), &clearValue, nullptr);
- m_imageAttachments[attachment->m_name][1] = RPI::AttachmentImage::Create(*pool.get(), imageDesc,
- Name(AZStd::string::format("%s_1", attachment->m_path.GetCStr())), &clearValue, nullptr);
- attachment->m_path = m_imageAttachments[attachment->m_name][0]->GetAttachmentId();
- attachment->m_importedResource = m_imageAttachments[attachment->m_name][0];
- }
- }
- }
- // reset frame offset to 0 since attachments are rebuilt
- m_frameOffset = 0;
- Base::BuildInternal();
- }
- Data::Instance<RPI::AttachmentImage> CheckerboardPass::GetAttachmentImage(Name attachmentName, uint8_t frameOffset)
- {
- if (m_imageAttachments.find(attachmentName) != m_imageAttachments.end())
- {
- return m_imageAttachments[attachmentName][frameOffset];
- }
- return nullptr;
- }
- void CheckerboardPass::FrameEndInternal()
- {
- m_frameOffset = 1 - m_frameOffset;
- // For next frame, we switch the internal attachment image for each owned pass attachments
- // So we can preserve the render target from current frame
- for (RPI::Ptr<RPI::PassAttachment>& attachment : m_ownedAttachments)
- {
- if (attachment->m_descriptor.m_type == RHI::AttachmentType::Image)
- {
- Data::Instance<RPI::AttachmentImage> nextAttachment = GetAttachmentImage(attachment->m_name, m_frameOffset);
- if (nextAttachment)
- {
- // update the attachment id and resource
- attachment->m_path = nextAttachment->GetAttachmentId();
- attachment->m_importedResource = nextAttachment;
- // the attachment id saved in bindings need to be updated too. so the frame attachment will be attached properly.
- for (auto& binding : m_attachmentBindings)
- {
- if (binding.GetAttachment() == attachment)
- {
- binding.m_unifiedScopeDesc.m_attachmentId = nextAttachment->GetAttachmentId();
- break;
- }
- }
- }
- }
- }
- Base::FrameEndInternal();
- }
- } // namespace Render
- } // namespace AZ
|