|
|
|
|
@ -58,43 +58,68 @@ namespace AZ
|
|
|
|
|
// Overwrite descriptor dimensions with the native ones (the ones assigned by the platform) returned by InitInternal.
|
|
|
|
|
m_descriptor.m_dimensions = nativeDimensions;
|
|
|
|
|
|
|
|
|
|
m_images.reserve(m_descriptor.m_dimensions.m_imageCount);
|
|
|
|
|
resultCode = InitImages();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (uint32_t imageIdx = 0; imageIdx < m_descriptor.m_dimensions.m_imageCount; ++imageIdx)
|
|
|
|
|
{
|
|
|
|
|
m_images.emplace_back(RHI::Factory::Get().CreateImage());
|
|
|
|
|
}
|
|
|
|
|
return resultCode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
InitImageRequest request;
|
|
|
|
|
void SwapChain::ShutdownImages()
|
|
|
|
|
{
|
|
|
|
|
// Shutdown existing set of images.
|
|
|
|
|
uint32_t imageSize = aznumeric_cast<uint32_t>(m_images.size());
|
|
|
|
|
for (uint32_t imageIdx = 0; imageIdx < imageSize; ++imageIdx)
|
|
|
|
|
{
|
|
|
|
|
m_images[imageIdx]->Shutdown();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RHI::ImageDescriptor& imageDescriptor = request.m_descriptor;
|
|
|
|
|
imageDescriptor.m_dimension = RHI::ImageDimension::Image2D;
|
|
|
|
|
imageDescriptor.m_bindFlags = RHI::ImageBindFlags::Color;
|
|
|
|
|
imageDescriptor.m_size.m_width = m_descriptor.m_dimensions.m_imageWidth;
|
|
|
|
|
imageDescriptor.m_size.m_height = m_descriptor.m_dimensions.m_imageHeight;
|
|
|
|
|
imageDescriptor.m_format = m_descriptor.m_dimensions.m_imageFormat;
|
|
|
|
|
m_images.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (uint32_t imageIdx = 0; imageIdx < m_descriptor.m_dimensions.m_imageCount; ++imageIdx)
|
|
|
|
|
{
|
|
|
|
|
request.m_image = m_images[imageIdx].get();
|
|
|
|
|
request.m_imageIndex = imageIdx;
|
|
|
|
|
ResultCode SwapChain::InitImages()
|
|
|
|
|
{
|
|
|
|
|
ResultCode resultCode = ResultCode::Success;
|
|
|
|
|
|
|
|
|
|
m_images.reserve(m_descriptor.m_dimensions.m_imageCount);
|
|
|
|
|
|
|
|
|
|
// If the new display mode has more buffers, add them.
|
|
|
|
|
for (uint32_t i = 0; i < m_descriptor.m_dimensions.m_imageCount; ++i)
|
|
|
|
|
{
|
|
|
|
|
m_images.emplace_back(RHI::Factory::Get().CreateImage());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
InitImageRequest request;
|
|
|
|
|
|
|
|
|
|
RHI::ImageDescriptor& imageDescriptor = request.m_descriptor;
|
|
|
|
|
imageDescriptor.m_dimension = RHI::ImageDimension::Image2D;
|
|
|
|
|
imageDescriptor.m_bindFlags = RHI::ImageBindFlags::Color;
|
|
|
|
|
imageDescriptor.m_size.m_width = m_descriptor.m_dimensions.m_imageWidth;
|
|
|
|
|
imageDescriptor.m_size.m_height = m_descriptor.m_dimensions.m_imageHeight;
|
|
|
|
|
imageDescriptor.m_format = m_descriptor.m_dimensions.m_imageFormat;
|
|
|
|
|
|
|
|
|
|
resultCode = ImagePoolBase::InitImage(
|
|
|
|
|
request.m_image,
|
|
|
|
|
imageDescriptor,
|
|
|
|
|
[this, &request]()
|
|
|
|
|
for (uint32_t imageIdx = 0; imageIdx < m_descriptor.m_dimensions.m_imageCount; ++imageIdx)
|
|
|
|
|
{
|
|
|
|
|
request.m_image = m_images[imageIdx].get();
|
|
|
|
|
request.m_imageIndex = imageIdx;
|
|
|
|
|
|
|
|
|
|
resultCode = ImagePoolBase::InitImage(
|
|
|
|
|
request.m_image, imageDescriptor,
|
|
|
|
|
[this, &request]()
|
|
|
|
|
{
|
|
|
|
|
return InitImageInternal(request);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (resultCode != ResultCode::Success)
|
|
|
|
|
{
|
|
|
|
|
Shutdown();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (resultCode != ResultCode::Success)
|
|
|
|
|
{
|
|
|
|
|
AZ_Error("Swapchain", false, "Failed to initialize images.");
|
|
|
|
|
Shutdown();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Reset the current index back to 0 so we match the platform swap chain.
|
|
|
|
|
m_currentImageIndex = 0;
|
|
|
|
|
|
|
|
|
|
return resultCode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -105,63 +130,15 @@ namespace AZ
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ResultCode SwapChain::Resize(const RHI::SwapChainDimensions& dimensions)
|
|
|
|
|
{
|
|
|
|
|
// Shutdown existing set of images.
|
|
|
|
|
for (uint32_t imageIdx = 0; imageIdx < GetImageCount(); ++imageIdx)
|
|
|
|
|
{
|
|
|
|
|
m_images[imageIdx]->Shutdown();
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
ShutdownImages();
|
|
|
|
|
|
|
|
|
|
SwapChainDimensions nativeDimensions = dimensions;
|
|
|
|
|
ResultCode resultCode = ResizeInternal(dimensions, &nativeDimensions);
|
|
|
|
|
if (resultCode == ResultCode::Success)
|
|
|
|
|
{
|
|
|
|
|
m_descriptor.m_dimensions = nativeDimensions;
|
|
|
|
|
m_images.reserve(m_descriptor.m_dimensions.m_imageCount);
|
|
|
|
|
|
|
|
|
|
// If the new display mode has more buffers, add them.
|
|
|
|
|
while (m_images.size() < static_cast<size_t>(m_descriptor.m_dimensions.m_imageCount))
|
|
|
|
|
{
|
|
|
|
|
m_images.emplace_back(RHI::Factory::Get().CreateImage());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If it has fewer, trim down.
|
|
|
|
|
while (m_images.size() > static_cast<size_t>(m_descriptor.m_dimensions.m_imageCount))
|
|
|
|
|
{
|
|
|
|
|
m_images.pop_back();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
InitImageRequest request;
|
|
|
|
|
|
|
|
|
|
RHI::ImageDescriptor& imageDescriptor = request.m_descriptor;
|
|
|
|
|
imageDescriptor.m_dimension = RHI::ImageDimension::Image2D;
|
|
|
|
|
imageDescriptor.m_bindFlags = RHI::ImageBindFlags::Color;
|
|
|
|
|
imageDescriptor.m_size.m_width = m_descriptor.m_dimensions.m_imageWidth;
|
|
|
|
|
imageDescriptor.m_size.m_height = m_descriptor.m_dimensions.m_imageHeight;
|
|
|
|
|
imageDescriptor.m_format = m_descriptor.m_dimensions.m_imageFormat;
|
|
|
|
|
|
|
|
|
|
for (uint32_t imageIdx = 0; imageIdx < GetImageCount(); ++imageIdx)
|
|
|
|
|
{
|
|
|
|
|
request.m_image = m_images[imageIdx].get();
|
|
|
|
|
request.m_imageIndex = imageIdx;
|
|
|
|
|
|
|
|
|
|
resultCode = ImagePoolBase::InitImage(
|
|
|
|
|
request.m_image,
|
|
|
|
|
imageDescriptor,
|
|
|
|
|
[this, &request]()
|
|
|
|
|
{
|
|
|
|
|
return InitImageInternal(request);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (resultCode != ResultCode::Success)
|
|
|
|
|
{
|
|
|
|
|
Shutdown();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Reset the current index back to 0 so we match the platform swap chain.
|
|
|
|
|
m_currentImageIndex = 0;
|
|
|
|
|
resultCode = InitImages();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return resultCode;
|
|
|
|
|
@ -188,7 +165,7 @@ namespace AZ
|
|
|
|
|
|
|
|
|
|
uint32_t SwapChain::GetImageCount() const
|
|
|
|
|
{
|
|
|
|
|
return static_cast<uint32_t>(m_images.size());
|
|
|
|
|
return aznumeric_cast<uint32_t>(m_images.size());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t SwapChain::GetCurrentImageIndex() const
|
|
|
|
|
@ -209,8 +186,18 @@ namespace AZ
|
|
|
|
|
void SwapChain::Present()
|
|
|
|
|
{
|
|
|
|
|
AZ_TRACE_METHOD();
|
|
|
|
|
m_currentImageIndex = PresentInternal();
|
|
|
|
|
AZ_Assert(m_currentImageIndex < m_images.size(), "Invalid image index");
|
|
|
|
|
// Due to swapchain recreation, the images are refreshed.
|
|
|
|
|
// There is no need to present swapchain for this frame.
|
|
|
|
|
const uint32_t imageCount = aznumeric_cast<uint32_t>(m_images.size());
|
|
|
|
|
if (imageCount == 0)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_currentImageIndex = PresentInternal();
|
|
|
|
|
AZ_Assert(m_currentImageIndex < imageCount, "Invalid image index");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|