dawn-cmake/src/backend/common/Framebuffer.cpp

129 lines
4.4 KiB
C++
Raw Normal View History

// Copyright 2017 The NXT Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "Framebuffer.h"
#include "Buffer.h"
#include "Device.h"
#include "RenderPass.h"
#include "Texture.h"
namespace backend {
// Framebuffer
FramebufferBase::FramebufferBase(FramebufferBuilder* builder)
: renderPass(std::move(builder->renderPass)), width(builder->width), height(builder->height), textureViews(std::move(builder->textureViews)) {
}
RenderPassBase* FramebufferBase::GetRenderPass() {
return renderPass.Get();
}
TextureViewBase* FramebufferBase::GetTextureView(uint32_t index) {
ASSERT(index < textureViews.size());
return textureViews[index].Get();
}
2017-06-05 21:22:48 +00:00
uint32_t FramebufferBase::GetWidth() const {
return width;
}
uint32_t FramebufferBase::GetHeight() const {
return height;
}
// FramebufferBuilder
enum FramebufferSetProperties {
FRAMEBUFFER_PROPERTY_RENDER_PASS = 0x1,
FRAMEBUFFER_PROPERTY_DIMENSIONS = 0x2,
};
FramebufferBuilder::FramebufferBuilder(DeviceBase* device)
: Builder(device) {
}
FramebufferBase* FramebufferBuilder::GetResultImpl() {
constexpr int requiredProperties = FRAMEBUFFER_PROPERTY_RENDER_PASS | FRAMEBUFFER_PROPERTY_DIMENSIONS;
if ((propertiesSet & requiredProperties) != requiredProperties) {
HandleError("Framebuffer missing properties");
return nullptr;
}
// TODO(kainino@chromium.org): Remove this flag when the
// null=backbuffer hack is removed. Then, using null texture views can
// be completely disallowed.
bool usingBackbufferHack = false;
for (auto& textureView : textureViews) {
if (!textureView) {
if (usingBackbufferHack) {
// TODO(kainino@chromium.org) update this too
HandleError("Framebuffer has more than one null attachment");
return nullptr;
}
usingBackbufferHack = true;
}
}
return device->CreateFramebuffer(this);
}
void FramebufferBuilder::SetRenderPass(RenderPassBase* renderPass) {
if ((propertiesSet & FRAMEBUFFER_PROPERTY_RENDER_PASS) != 0) {
HandleError("Framebuffer render pass property set multiple times");
return;
}
this->renderPass = renderPass;
this->textureViews.resize(renderPass->GetAttachmentCount());
propertiesSet |= FRAMEBUFFER_PROPERTY_RENDER_PASS;
}
void FramebufferBuilder::SetDimensions(uint32_t width, uint32_t height) {
if ((propertiesSet & FRAMEBUFFER_PROPERTY_DIMENSIONS) != 0) {
HandleError("Framebuffer dimensions property set multiple times");
return;
}
this->width = width;
this->height = height;
propertiesSet |= FRAMEBUFFER_PROPERTY_DIMENSIONS;
}
void FramebufferBuilder::SetAttachment(uint32_t attachmentSlot, TextureViewBase* textureView) {
if ((propertiesSet & FRAMEBUFFER_PROPERTY_RENDER_PASS) == 0) {
HandleError("Render pass must be set before framebuffer attachments");
return;
}
if (attachmentSlot >= textureViews.size()) {
HandleError("Attachment slot out of bounds");
return;
}
if (textureViews[attachmentSlot]) {
HandleError("Framebuffer attachment[i] set multiple times");
return;
}
const auto& attachmentInfo = renderPass->GetAttachmentInfo(attachmentSlot);
const auto* texture = textureView->GetTexture();
if (attachmentInfo.format != texture->GetFormat()) {
HandleError("Texture format does not match attachment format");
return;
}
// TODO(kainino@chromium.org): also check attachment samples, etc.
textureViews[attachmentSlot] = textureView;
}
}