Skip to content

Commit 388f8fa

Browse files
Implemented the per-image-view usages to no longer get errors about extended usages of the source image, @achalpandeyy I'm ready for your compute blits!
P.S. Also fixed the setting of IGPUImageView's format to always match IGPUImages, now only if format got promoted.
1 parent 4a4058b commit 388f8fa

File tree

1 file changed

+44
-8
lines changed

1 file changed

+44
-8
lines changed

include/nbl/video/utilities/IGPUObjectFromAssetConverter.h

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,6 +1059,7 @@ auto IGPUObjectFromAssetConverter::create(const asset::ICPUImage** const _begin,
10591059
{
10601060
newFormat = physDev->promoteImageFormat(promotionRequest, video::IGPUImage::ET_LINEAR);
10611061
newFormatIsStorable = physDev->getImageFormatUsagesLinearTiling()[newFormat].storageImage;
1062+
params.tiling = video::IGPUImage::ET_LINEAR;
10621063
}
10631064

10641065
assert(newFormat != asset::EF_UNKNOWN); // No feasible supported format found for creating this image
@@ -1548,20 +1549,55 @@ inline created_gpu_object_array<asset::ICPUImageView> IGPUObjectFromAssetConvert
15481549
core::vector<size_t> redirs = eliminateDuplicatesAndGenRedirs(cpuDeps);
15491550

15501551
auto gpuDeps = getGPUObjectsFromAssets<asset::ICPUImage>(cpuDeps.data(), cpuDeps.data() + cpuDeps.size(), _params);
1551-
1552+
const auto physDev = _params.device->getPhysicalDevice();
1553+
const auto& optimalUsages = physDev->getImageFormatUsagesOptimalTiling();
1554+
const auto& linearUsages = physDev->getImageFormatUsagesLinearTiling();
15521555
for (ptrdiff_t i = 0; i < assetCount; ++i)
15531556
{
15541557
if (gpuDeps->begin()[redirs[i]])
15551558
{
1556-
const asset::ICPUImageView::SCreationParams& cpuparams = _begin[i]->getCreationParameters();
1559+
const auto& cpuParams = _begin[i]->getCreationParameters();
1560+
15571561
IGPUImageView::SCreationParams params = {};
1558-
params.flags = static_cast<IGPUImageView::E_CREATE_FLAGS>(cpuparams.flags);
1562+
params.flags = static_cast<IGPUImageView::E_CREATE_FLAGS>(cpuParams.flags);
1563+
params.viewType = static_cast<IGPUImageView::E_TYPE>(cpuParams.viewType);
15591564
params.image = (*gpuDeps)[redirs[i]];
1560-
params.viewType = static_cast<IGPUImageView::E_TYPE>(cpuparams.viewType);
1561-
params.format = params.image->getCreationParameters().format;
1562-
memcpy(&params.components, &cpuparams.components, sizeof(params.components));
1563-
params.subresourceRange = cpuparams.subresourceRange;
1564-
params.subresourceRange.levelCount = (*gpuDeps)[redirs[i]]->getCreationParameters().mipLevels - params.subresourceRange.baseMipLevel;
1565+
const auto& gpuImgParams = params.image->getCreationParameters();
1566+
// override the view's format if the source image got promoted, a bit crude, but don't want to scratch my head about how to promote the views and guess semantics
1567+
const bool formatGotPromoted = asset::getFormatClass(cpuParams.format)!=asset::getFormatClass(gpuImgParams.format);
1568+
params.format = formatGotPromoted ? gpuImgParams.format:cpuParams.format;
1569+
params.subUsages = cpuParams.subUsages;
1570+
// TODO: In Asset Converter 2.0 we'd pass through all descriptor sets etc and propagate the adding usages backwards to views, but here we need to trim the image's usages instead
1571+
{
1572+
IPhysicalDevice::SFormatImageUsages::SUsage validUsages(gpuImgParams.usage);
1573+
if (params.image->getTiling()!=IGPUImage::ET_LINEAR)
1574+
validUsages = validUsages & optimalUsages[params.format];
1575+
else
1576+
validUsages = validUsages & linearUsages[params.format];
1577+
// add them after trimming
1578+
if (validUsages.sampledImage)
1579+
params.subUsages |= IGPUImage::EUF_SAMPLED_BIT;
1580+
if (validUsages.storageImage)
1581+
params.subUsages |= IGPUImage::EUF_STORAGE_BIT;
1582+
if (validUsages.attachment)
1583+
{
1584+
if (asset::isDepthOrStencilFormat(params.format))
1585+
params.subUsages |= IGPUImage::EUF_DEPTH_STENCIL_ATTACHMENT_BIT;
1586+
else
1587+
params.subUsages |= IGPUImage::EUF_COLOR_ATTACHMENT_BIT;
1588+
}
1589+
if (validUsages.transferSrc)
1590+
params.subUsages |= IGPUImage::EUF_TRANSFER_SRC_BIT;
1591+
if (validUsages.transferDst)
1592+
params.subUsages |= IGPUImage::EUF_TRANSFER_DST_BIT;
1593+
// stuff thats not dependent on device caps
1594+
const auto uncappedUsages = IGPUImage::EUF_TRANSIENT_ATTACHMENT_BIT|IGPUImage::EUF_INPUT_ATTACHMENT_BIT|IGPUImage::EUF_SHADING_RATE_IMAGE_BIT_NV|IGPUImage::EUF_FRAGMENT_DENSITY_MAP_BIT_EXT;
1595+
params.subUsages |= gpuImgParams.usage&uncappedUsages;
1596+
}
1597+
memcpy(&params.components, &cpuParams.components, sizeof(params.components));
1598+
params.subresourceRange = cpuParams.subresourceRange;
1599+
// TODO: Undo this, make all loaders set the level and layer counts on image views to `ICPUImageView::remaining_...`
1600+
params.subresourceRange.levelCount = gpuImgParams.mipLevels-params.subresourceRange.baseMipLevel;
15651601
(*res)[i] = _params.device->createImageView(std::move(params));
15661602
}
15671603
}

0 commit comments

Comments
 (0)