Forbid explicit transitions to/from attachment usages (#18)

This commit is contained in:
Kai Ninomiya 2017-05-24 13:07:30 -07:00 committed by GitHub
parent 79a62bf6e3
commit b2b495b5aa
1 changed files with 58 additions and 29 deletions

View File

@ -201,6 +201,22 @@ namespace backend {
auto it = mostRecentTextureUsages.find(texture);
return it != mostRecentTextureUsages.end() && (it->second & usage);
};
auto isTextureTransitionPossible = [&](TextureBase* texture, nxt::TextureUsageBit usage) -> bool {
const nxt::TextureUsageBit attachmentUsages =
nxt::TextureUsageBit::ColorAttachment |
nxt::TextureUsageBit::DepthStencilAttachment;
ASSERT(usage != nxt::TextureUsageBit::None && nxt::HasZeroOrOneBits(usage));
if (usage & attachmentUsages) {
return false;
}
auto it = mostRecentTextureUsages.find(texture);
if (it != mostRecentTextureUsages.end()) {
if (it->second & attachmentUsages) {
return false;
}
}
return texture->IsTransitionPossible(usage);
};
auto validateBindGroupUsages = [&](BindGroupBase* group) -> bool {
const auto& layoutInfo = group->GetLayout()->GetBindingInfo();
@ -260,7 +276,8 @@ namespace backend {
uint32_t currentSubpass = 0;
auto beginSubpass = [&]() -> bool {
auto& subpassInfo = currentRenderPass->GetSubpassInfo(currentSubpass);
for (auto attachmentSlot : subpassInfo.colorAttachments) {
for (auto location : IterateBitSet(subpassInfo.colorAttachmentsSet)) {
auto attachmentSlot = subpassInfo.colorAttachments[location];
auto* tv = currentFramebuffer->GetTextureView(attachmentSlot);
// TODO(kainino@chromium.org): the TextureView can only be null
// because of the null=backbuffer hack (null representing the
@ -278,11 +295,31 @@ namespace backend {
HandleError("Can't transition attachment to ColorAttachment usage");
return false;
}
mostRecentTextureUsages.erase(texture);
mostRecentTextureUsages[texture] = nxt::TextureUsageBit::ColorAttachment;
texturesTransitioned.insert(texture);
}
return true;
};
auto endSubpass = [&]() {
auto& subpassInfo = currentRenderPass->GetSubpassInfo(currentSubpass);
for (auto location : IterateBitSet(subpassInfo.colorAttachmentsSet)) {
auto attachmentSlot = subpassInfo.colorAttachments[location];
auto* tv = currentFramebuffer->GetTextureView(attachmentSlot);
// TODO(kainino@chromium.org): the TextureView can only be null
// because of the null=backbuffer hack (null representing the
// backbuffer). Once that hack is removed (once we have WSI)
// this check isn't needed.
if (tv == nullptr) {
continue;
}
auto* texture = tv->GetTexture();
if (texture->IsFrozen()) {
continue;
}
mostRecentTextureUsages[texture] = nxt::TextureUsageBit::None;
}
};
Command type;
while(iterator.NextCommandId(&type)) {
@ -298,6 +335,8 @@ namespace backend {
HandleError("Can't advance beyond the last subpass");
return false;
}
endSubpass();
currentSubpass += 1;
if (!beginSubpass()) {
return false;
@ -465,6 +504,7 @@ namespace backend {
HandleError("Can't end a render pass before the last subpass");
return false;
}
endSubpass();
currentRenderPass = nullptr;
currentFramebuffer = nullptr;
aspects.reset(VALIDATION_ASPECT_RENDER_PASS);
@ -578,8 +618,14 @@ namespace backend {
auto buffer = cmd->buffer.Get();
auto usage = cmd->usage;
if (!cmd->buffer->IsTransitionPossible(cmd->usage)) {
HandleError("Buffer frozen or usage not allowed");
if (!buffer->IsTransitionPossible(usage)) {
if (buffer->IsFrozen()) {
HandleError("Buffer transition not possible (usage is frozen)");
} else if (!BufferBase::IsUsagePossible(buffer->GetAllowedUsage(), usage)) {
HandleError("Buffer transition not possible (usage not allowed)");
} else {
HandleError("Buffer transition not possible");
}
return false;
}
@ -595,32 +641,15 @@ namespace backend {
auto texture = cmd->texture.Get();
auto usage = cmd->usage;
if (!cmd->texture->IsTransitionPossible(cmd->usage)) {
HandleError("Texture frozen or usage not allowed");
return false;
}
// TODO(kainino@chromium.org): We should be able to
// optimize this by tracking which textures are in use
// as attachments. Maybe it's possible that the
// XAttachment usages could mark this: disallow
// explicit transitions to XAttachment usages, and
// disallow explicit transitions of resources already
// in an XAttachment usage.
if (currentRenderPass) {
auto& info = currentRenderPass->GetSubpassInfo(currentSubpass);
for (uint32_t location = 0; location < info.colorAttachments.size(); ++location) {
if (!info.colorAttachmentsSet[location]) {
continue;
}
uint32_t attachmentSlot = info.colorAttachments[location];
auto* tv = currentFramebuffer->GetTextureView(attachmentSlot);
// TODO(kainino@chromium.org): remove check for tv being non-null once the null=backbuffer hack is removed.
if (tv && tv->GetTexture() == texture) {
HandleError("Can't transition a texture while it's used as a color attachment");
return false;
}
if (!isTextureTransitionPossible(texture, usage)) {
if (texture->IsFrozen()) {
HandleError("Texture transition not possible (usage is frozen)");
} else if (!TextureBase::IsUsagePossible(texture->GetAllowedUsage(), usage)) {
HandleError("Texture transition not possible (usage not allowed)");
} else {
HandleError("Texture transition not possible");
}
return false;
}
mostRecentTextureUsages[texture] = usage;