From 5dc7915d38e207c7cdbbb0cce1b8c6f721b571c1 Mon Sep 17 00:00:00 2001 From: Corentin Wallez Date: Mon, 8 May 2017 10:52:11 +0200 Subject: [PATCH] Introduce a base class for Builder objects. All builder objects will depend from this "Builder" base class. This will allow having the builder callback logic in only one place. --- src/backend/CMakeLists.txt | 2 ++ src/backend/common/BindGroup.cpp | 34 +++++++++---------- src/backend/common/BindGroup.h | 7 ++-- src/backend/common/BindGroupLayout.cpp | 12 +++---- src/backend/common/BindGroupLayout.h | 6 ++-- src/backend/common/Buffer.cpp | 31 +++++++---------- src/backend/common/Buffer.h | 13 ++------ src/backend/common/Builder.cpp | 37 +++++++++++++++++++++ src/backend/common/Builder.h | 41 +++++++++++++++++++++++ src/backend/common/CommandBuffer.cpp | 46 ++++++++++++-------------- src/backend/common/CommandBuffer.h | 6 ++-- src/backend/common/InputState.cpp | 21 +++++------- src/backend/common/InputState.h | 7 ++-- src/backend/common/Pipeline.cpp | 20 +++++------ src/backend/common/Pipeline.h | 7 ++-- src/backend/common/PipelineLayout.cpp | 12 +++---- src/backend/common/PipelineLayout.h | 7 ++-- src/backend/common/Queue.cpp | 8 ++--- src/backend/common/Queue.h | 9 ++--- src/backend/common/Sampler.cpp | 11 ++---- src/backend/common/Sampler.h | 7 ++-- src/backend/common/ShaderModule.cpp | 10 +++--- src/backend/common/ShaderModule.h | 7 ++-- src/backend/common/Texture.cpp | 34 ++++++++----------- src/backend/common/Texture.h | 13 ++------ src/backend/metal/MetalBackend.mm | 6 ++-- 26 files changed, 202 insertions(+), 212 deletions(-) create mode 100644 src/backend/common/Builder.cpp create mode 100644 src/backend/common/Builder.h diff --git a/src/backend/CMakeLists.txt b/src/backend/CMakeLists.txt index cfb2a552b3..78c8c7978b 100644 --- a/src/backend/CMakeLists.txt +++ b/src/backend/CMakeLists.txt @@ -23,6 +23,8 @@ list(APPEND BACKEND_SOURCES ${COMMON_DIR}/BindGroupLayout.cpp ${COMMON_DIR}/BindGroupLayout.h ${COMMON_DIR}/BitSetIterator.h + ${COMMON_DIR}/Builder.cpp + ${COMMON_DIR}/Builder.h ${COMMON_DIR}/Buffer.cpp ${COMMON_DIR}/Buffer.h ${COMMON_DIR}/CommandAllocator.cpp diff --git a/src/backend/common/BindGroup.cpp b/src/backend/common/BindGroup.cpp index 744325aabc..a4435e2b07 100644 --- a/src/backend/common/BindGroup.cpp +++ b/src/backend/common/BindGroup.cpp @@ -65,32 +65,28 @@ namespace backend { }; BindGroupBuilder::BindGroupBuilder(DeviceBase* device) - : device(device) { - } - - bool BindGroupBuilder::WasConsumed() const { - return consumed; + : Builder(device) { } BindGroupBase* BindGroupBuilder::GetResult() { constexpr int allProperties = BINDGROUP_PROPERTY_USAGE | BINDGROUP_PROPERTY_LAYOUT; if ((propertiesSet & allProperties) != allProperties) { - device->HandleError("Bindgroup missing properties"); + HandleError("Bindgroup missing properties"); return nullptr; } if (setMask != layout->GetBindingInfo().mask) { - device->HandleError("Bindgroup missing bindings"); + HandleError("Bindgroup missing bindings"); return nullptr; } - consumed = true; + MarkConsumed(); return device->CreateBindGroup(this); } void BindGroupBuilder::SetLayout(BindGroupLayoutBase* layout) { if ((propertiesSet & BINDGROUP_PROPERTY_LAYOUT) != 0) { - device->HandleError("Bindgroup layout property set multiple times"); + HandleError("Bindgroup layout property set multiple times"); return; } @@ -100,7 +96,7 @@ namespace backend { void BindGroupBuilder::SetUsage(nxt::BindGroupUsage usage) { if ((propertiesSet & BINDGROUP_PROPERTY_USAGE) != 0) { - device->HandleError("Bindgroup usage property set multiple times"); + HandleError("Bindgroup usage property set multiple times"); return; } @@ -127,12 +123,12 @@ namespace backend { case nxt::BindingType::Sampler: case nxt::BindingType::SampledTexture: - device->HandleError("Setting buffer for a wrong binding type"); + HandleError("Setting buffer for a wrong binding type"); return; } if (!(bufferViews[j]->GetBuffer()->GetAllowedUsage() & requiredBit)) { - device->HandleError("Buffer needs to allow the correct usage bit"); + HandleError("Buffer needs to allow the correct usage bit"); return; } } @@ -148,7 +144,7 @@ namespace backend { const auto& layoutInfo = layout->GetBindingInfo(); for (size_t i = start, j = 0; i < start + count; ++i, ++j) { if (layoutInfo.types[i] != nxt::BindingType::Sampler) { - device->HandleError("Setting binding for a wrong layout binding type"); + HandleError("Setting binding for a wrong layout binding type"); return; } } @@ -164,12 +160,12 @@ namespace backend { const auto& layoutInfo = layout->GetBindingInfo(); for (size_t i = start, j = 0; i < start + count; ++i, ++j) { if (layoutInfo.types[i] != nxt::BindingType::SampledTexture) { - device->HandleError("Setting binding for a wrong layout binding type"); + HandleError("Setting binding for a wrong layout binding type"); return; } if (!(textureViews[j]->GetTexture()->GetAllowedUsage() & nxt::TextureUsageBit::Sampled)) { - device->HandleError("Texture needs to allow the sampled usage bit"); + HandleError("Texture needs to allow the sampled usage bit"); return; } } @@ -186,24 +182,24 @@ namespace backend { bool BindGroupBuilder::SetBindingsValidationBase(uint32_t start, uint32_t count) { if (start + count > kMaxBindingsPerGroup) { - device->HandleError("Setting bindings type over maximum number of bindings"); + HandleError("Setting bindings type over maximum number of bindings"); return false; } if ((propertiesSet & BINDGROUP_PROPERTY_LAYOUT) == 0) { - device->HandleError("Bindgroup layout must be set before views"); + HandleError("Bindgroup layout must be set before views"); return false; } const auto& layoutInfo = layout->GetBindingInfo(); for (size_t i = start, j = 0; i < start + count; ++i, ++j) { if (setMask[i]) { - device->HandleError("Setting already set binding"); + HandleError("Setting already set binding"); return false; } if (!layoutInfo.mask[i]) { - device->HandleError("Setting binding that isn't present in the layout"); + HandleError("Setting binding that isn't present in the layout"); return false; } } diff --git a/src/backend/common/BindGroup.h b/src/backend/common/BindGroup.h index 4e6f9000b1..472e822b98 100644 --- a/src/backend/common/BindGroup.h +++ b/src/backend/common/BindGroup.h @@ -16,6 +16,7 @@ #define BACKEND_COMMON_BINDGROUP_H_ #include "Forward.h" +#include "Builder.h" #include "RefCounted.h" #include "nxt/nxtcpp.h" @@ -42,12 +43,10 @@ namespace backend { std::array, kMaxBindingsPerGroup> bindings; }; - class BindGroupBuilder : public RefCounted { + class BindGroupBuilder : public Builder { public: BindGroupBuilder(DeviceBase* device); - bool WasConsumed() const; - // NXT API BindGroupBase* GetResult(); void SetLayout(BindGroupLayoutBase* layout); @@ -80,10 +79,8 @@ namespace backend { void SetBindingsBase(uint32_t start, uint32_t count, RefCounted* const * objects); bool SetBindingsValidationBase(uint32_t start, uint32_t count); - DeviceBase* device; std::bitset setMask; int propertiesSet = 0; - bool consumed = false; Ref layout; nxt::BindGroupUsage usage; diff --git a/src/backend/common/BindGroupLayout.cpp b/src/backend/common/BindGroupLayout.cpp index 27c6d92824..588d32a63a 100644 --- a/src/backend/common/BindGroupLayout.cpp +++ b/src/backend/common/BindGroupLayout.cpp @@ -94,11 +94,7 @@ namespace backend { // BindGroupLayoutBuilder - BindGroupLayoutBuilder::BindGroupLayoutBuilder(DeviceBase* device) : device(device) { - } - - bool BindGroupLayoutBuilder::WasConsumed() const { - return consumed; + BindGroupLayoutBuilder::BindGroupLayoutBuilder(DeviceBase* device) : Builder(device) { } const BindGroupLayoutBase::LayoutBindingInfo& BindGroupLayoutBuilder::GetBindingInfo() const { @@ -106,7 +102,7 @@ namespace backend { } BindGroupLayoutBase* BindGroupLayoutBuilder::GetResult() { - consumed = true; + MarkConsumed(); BindGroupLayoutBase blueprint(this, true); auto* result = device->GetOrCreateBindGroupLayout(&blueprint, this); @@ -116,13 +112,13 @@ namespace backend { void BindGroupLayoutBuilder::SetBindingsType(nxt::ShaderStageBit visibility, nxt::BindingType bindingType, uint32_t start, uint32_t count) { if (start + count > kMaxBindingsPerGroup) { - device->HandleError("Setting bindings type over maximum number of bindings"); + HandleError("Setting bindings type over maximum number of bindings"); return; } for (size_t i = start; i < start + count; i++) { if (bindingInfo.mask[i]) { - device->HandleError("Setting already set binding type"); + HandleError("Setting already set binding type"); return; } bindingInfo.mask.set(i); diff --git a/src/backend/common/BindGroupLayout.h b/src/backend/common/BindGroupLayout.h index 91f6115057..ef5c2a689a 100644 --- a/src/backend/common/BindGroupLayout.h +++ b/src/backend/common/BindGroupLayout.h @@ -16,6 +16,7 @@ #define BACKEND_COMMON_BINDGROUPLAYOUT_H_ #include "Forward.h" +#include "Builder.h" #include "RefCounted.h" #include "nxt/nxtcpp.h" @@ -43,11 +44,10 @@ namespace backend { bool blueprint = false; }; - class BindGroupLayoutBuilder : public RefCounted { + class BindGroupLayoutBuilder : public Builder { public: BindGroupLayoutBuilder(DeviceBase* device); - bool WasConsumed() const; const BindGroupLayoutBase::LayoutBindingInfo& GetBindingInfo() const; // NXT API @@ -57,9 +57,7 @@ namespace backend { private: friend class BindGroupLayoutBase; - DeviceBase* device; BindGroupLayoutBase::LayoutBindingInfo bindingInfo; - bool consumed = false; }; // Implements the functors necessary for the unordered_set-based cache. diff --git a/src/backend/common/Buffer.cpp b/src/backend/common/Buffer.cpp index 7592b041fe..6191763b1e 100644 --- a/src/backend/common/Buffer.cpp +++ b/src/backend/common/Buffer.cpp @@ -118,32 +118,28 @@ namespace backend { BUFFER_PROPERTY_SIZE = 0x4, }; - BufferBuilder::BufferBuilder(DeviceBase* device) : device(device) { - } - - bool BufferBuilder::WasConsumed() const { - return consumed; + BufferBuilder::BufferBuilder(DeviceBase* device) : Builder(device) { } BufferBase* BufferBuilder::GetResult() { constexpr int allProperties = BUFFER_PROPERTY_ALLOWED_USAGE | BUFFER_PROPERTY_SIZE; if ((propertiesSet & allProperties) != allProperties) { - device->HandleError("Buffer missing properties"); + HandleError("Buffer missing properties"); return nullptr; } if (!BufferBase::IsUsagePossible(allowedUsage, currentUsage)) { - device->HandleError("Initial buffer usage is not allowed"); + HandleError("Initial buffer usage is not allowed"); return nullptr; } - consumed = true; + MarkConsumed(); return device->CreateBuffer(this); } void BufferBuilder::SetAllowedUsage(nxt::BufferUsageBit usage) { if ((propertiesSet & BUFFER_PROPERTY_ALLOWED_USAGE) != 0) { - device->HandleError("Buffer allowedUsage property set multiple times"); + HandleError("Buffer allowedUsage property set multiple times"); return; } @@ -153,7 +149,7 @@ namespace backend { void BufferBuilder::SetInitialUsage(nxt::BufferUsageBit usage) { if ((propertiesSet & BUFFER_PROPERTY_INITIAL_USAGE) != 0) { - device->HandleError("Buffer initialUsage property set multiple times"); + HandleError("Buffer initialUsage property set multiple times"); return; } @@ -163,7 +159,7 @@ namespace backend { void BufferBuilder::SetSize(uint32_t size) { if ((propertiesSet & BUFFER_PROPERTY_SIZE) != 0) { - device->HandleError("Buffer size property set multiple times"); + HandleError("Buffer size property set multiple times"); return; } @@ -196,32 +192,29 @@ namespace backend { }; BufferViewBuilder::BufferViewBuilder(DeviceBase* device, BufferBase* buffer) - : device(device), buffer(buffer) { - } - - bool BufferViewBuilder::WasConsumed() const { - return consumed; + : Builder(device), buffer(buffer) { } BufferViewBase* BufferViewBuilder::GetResult() { constexpr int allProperties = BUFFER_VIEW_PROPERTY_EXTENT; if ((propertiesSet & allProperties) != allProperties) { - device->HandleError("Buffer view missing properties"); + HandleError("Buffer view missing properties"); return nullptr; } + MarkConsumed(); return device->CreateBufferView(this); } void BufferViewBuilder::SetExtent(uint32_t offset, uint32_t size) { if ((propertiesSet & BUFFER_VIEW_PROPERTY_EXTENT) != 0) { - device->HandleError("Buffer view extent property set multiple times"); + HandleError("Buffer view extent property set multiple times"); return; } uint64_t viewEnd = static_cast(offset) + static_cast(size); if (viewEnd > static_cast(buffer->GetSize())) { - device->HandleError("Buffer view end is OOB"); + HandleError("Buffer view end is OOB"); return; } diff --git a/src/backend/common/Buffer.h b/src/backend/common/Buffer.h index d8216bcb95..71ec79af4e 100644 --- a/src/backend/common/Buffer.h +++ b/src/backend/common/Buffer.h @@ -16,6 +16,7 @@ #define BACKEND_COMMON_BUFFER_H_ #include "Forward.h" +#include "Builder.h" #include "RefCounted.h" #include "nxt/nxtcpp.h" @@ -51,12 +52,10 @@ namespace backend { bool frozen = false; }; - class BufferBuilder : public RefCounted { + class BufferBuilder : public Builder { public: BufferBuilder(DeviceBase* device); - bool WasConsumed() const; - // NXT API BufferBase* GetResult(); void SetAllowedUsage(nxt::BufferUsageBit usage); @@ -66,12 +65,10 @@ namespace backend { private: friend class BufferBase; - DeviceBase* device; uint32_t size; nxt::BufferUsageBit allowedUsage = nxt::BufferUsageBit::None; nxt::BufferUsageBit currentUsage = nxt::BufferUsageBit::None; int propertiesSet = 0; - bool consumed = false; }; class BufferViewBase : public RefCounted { @@ -88,12 +85,10 @@ namespace backend { uint32_t offset; }; - class BufferViewBuilder : public RefCounted { + class BufferViewBuilder : public Builder { public: BufferViewBuilder(DeviceBase* device, BufferBase* buffer); - bool WasConsumed() const; - // NXT API BufferViewBase* GetResult(); void SetExtent(uint32_t offset, uint32_t size); @@ -101,12 +96,10 @@ namespace backend { private: friend class BufferViewBase; - DeviceBase* device; Ref buffer; uint32_t offset = 0; uint32_t size = 0; int propertiesSet = 0; - bool consumed = false; }; } diff --git a/src/backend/common/Builder.cpp b/src/backend/common/Builder.cpp new file mode 100644 index 0000000000..cf3b63c5fa --- /dev/null +++ b/src/backend/common/Builder.cpp @@ -0,0 +1,37 @@ +// 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 "Builder.h" + +#include "Device.h" + +namespace backend { + + bool Builder::WasConsumed() const { + return consumed; + } + + Builder::Builder(DeviceBase* device) : device(device) { + } + + void Builder::MarkConsumed() { + ASSERT(!consumed); + consumed = true; + } + + void Builder::HandleError(const char* message) { + device->HandleError(message); + } + +} diff --git a/src/backend/common/Builder.h b/src/backend/common/Builder.h new file mode 100644 index 0000000000..e3431c5b3b --- /dev/null +++ b/src/backend/common/Builder.h @@ -0,0 +1,41 @@ +// 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. + +#ifndef BACKEND_COMMON_BUILDER_H_ +#define BACKEND_COMMON_BUILDER_H_ + +#include "Forward.h" +#include "RefCounted.h" + +namespace backend { + + class Builder : public RefCounted { + public: + bool WasConsumed() const; + void HandleError(const char* message); + + protected: + Builder(DeviceBase* device); + + void MarkConsumed(); + + DeviceBase* const device; + + private: + bool consumed = false; + }; + +} + +#endif // BACKEND_COMMON_BUILDER_H_ diff --git a/src/backend/common/CommandBuffer.cpp b/src/backend/common/CommandBuffer.cpp index b6814805d0..b95cbee59a 100644 --- a/src/backend/common/CommandBuffer.cpp +++ b/src/backend/common/CommandBuffer.cpp @@ -132,20 +132,16 @@ namespace backend { commands->DataWasDestroyed(); } - CommandBufferBuilder::CommandBufferBuilder(DeviceBase* device) : device(device) { + CommandBufferBuilder::CommandBufferBuilder(DeviceBase* device) : Builder(device) { } CommandBufferBuilder::~CommandBufferBuilder() { - if (!consumed) { + if (!WasConsumed()) { MoveToIterator(); FreeCommands(&iterator); } } - bool CommandBufferBuilder::WasConsumed() const { - return consumed; - } - enum ValidationAspect { VALIDATION_ASPECT_RENDER_PIPELINE, VALIDATION_ASPECT_COMPUTE_PIPELINE, @@ -215,7 +211,7 @@ namespace backend { auto buffer = group->GetBindingAsBufferView(i)->GetBuffer(); if (!bufferHasGuaranteedUsageBit(buffer, requiredUsage)) { - device->HandleError("Can't guarantee buffer usage needed by bind group"); + HandleError("Can't guarantee buffer usage needed by bind group"); return false; } } @@ -226,7 +222,7 @@ namespace backend { auto texture = group->GetBindingAsTextureView(i)->GetTexture(); if (!textureHasGuaranteedUsageBit(texture, requiredUsage)) { - device->HandleError("Can't guarantee texture usage needed by bind group"); + HandleError("Can't guarantee texture usage needed by bind group"); return false; } } @@ -256,17 +252,17 @@ namespace backend { uint32_t level = copy->level; if (!bufferHasGuaranteedUsageBit(buffer, nxt::BufferUsageBit::TransferSrc)) { - device->HandleError("Buffer needs the transfer source usage bit"); + HandleError("Buffer needs the transfer source usage bit"); return false; } if (!textureHasGuaranteedUsageBit(texture, nxt::TextureUsageBit::TransferDst)) { - device->HandleError("Texture needs the transfer destination usage bit"); + HandleError("Texture needs the transfer destination usage bit"); return false; } if (width == 0 || height == 0 || depth == 0) { - device->HandleError("Empty copy"); + HandleError("Empty copy"); return false; } @@ -275,7 +271,7 @@ namespace backend { uint64_t dataSize = width * height * depth * pixelSize; if (dataSize + static_cast(bufferOffset) > static_cast(buffer->GetSize())) { - device->HandleError("Copy would read after end of the buffer"); + HandleError("Copy would read after end of the buffer"); return false; } @@ -283,7 +279,7 @@ namespace backend { y + height > static_cast(texture->GetHeight()) || z + depth > static_cast(texture->GetDepth()) || level > texture->GetNumMipLevels()) { - device->HandleError("Copy would write outside of the texture"); + HandleError("Copy would write outside of the texture"); return false; } } @@ -311,7 +307,7 @@ namespace backend { // Check again if anything is missing if ((requiredDispatchAspects & ~aspects).any()) { - device->HandleError("Some dispatch state is missing"); + HandleError("Some dispatch state is missing"); return false; } } @@ -339,7 +335,7 @@ namespace backend { // Check again if anything is missing if ((requiredDrawAspects & ~aspects).any()) { - device->HandleError("Some draw state is missing"); + HandleError("Some draw state is missing"); return false; } } @@ -351,7 +347,7 @@ namespace backend { DrawElementsCmd* draw = iterator.NextCommand(); if (!aspects[VALIDATION_ASPECT_INDEX_BUFFER]) { - device->HandleError("Draw elements requires an index buffer"); + HandleError("Draw elements requires an index buffer"); return false; } } @@ -394,7 +390,7 @@ namespace backend { SetPushConstantsCmd* cmd = iterator.NextCommand(); iterator.NextData(cmd->count); if (cmd->count + cmd->offset > kMaxPushConstants) { - device->HandleError("Setting pushconstants past the limit"); + HandleError("Setting pushconstants past the limit"); return false; } } @@ -406,7 +402,7 @@ namespace backend { uint32_t index = cmd->index; if (cmd->group->GetLayout() != lastPipeline->GetLayout()->GetBindGroupLayout(index)) { - device->HandleError("Bind group layout mismatch"); + HandleError("Bind group layout mismatch"); return false; } if (!validateBindGroupUsages(cmd->group.Get())) { @@ -422,7 +418,7 @@ namespace backend { auto buffer = cmd->buffer; auto usage = nxt::BufferUsageBit::Index; if (!bufferHasGuaranteedUsageBit(buffer.Get(), usage)) { - device->HandleError("Buffer needs the index usage bit to be guaranteed"); + HandleError("Buffer needs the index usage bit to be guaranteed"); return false; } @@ -440,7 +436,7 @@ namespace backend { auto buffer = buffers[i]; auto usage = nxt::BufferUsageBit::Vertex; if (!bufferHasGuaranteedUsageBit(buffer.Get(), usage)) { - device->HandleError("Buffer needs vertex usage bit to be guaranteed"); + HandleError("Buffer needs vertex usage bit to be guaranteed"); return false; } inputsSet.set(cmd->startSlot + i); @@ -455,7 +451,7 @@ namespace backend { auto usage = cmd->usage; if (!cmd->buffer->IsTransitionPossible(cmd->usage)) { - device->HandleError("Buffer frozen or usage not allowed"); + HandleError("Buffer frozen or usage not allowed"); return false; } @@ -472,7 +468,7 @@ namespace backend { auto usage = cmd->usage; if (!cmd->texture->IsTransitionPossible(cmd->usage)) { - device->HandleError("Texture frozen or usage not allowed"); + HandleError("Texture frozen or usage not allowed"); return false; } @@ -493,7 +489,7 @@ namespace backend { CommandBufferBase* CommandBufferBuilder::GetResult() { MoveToIterator(); - consumed = true; + MarkConsumed(); return device->CreateCommandBuffer(this); } @@ -548,7 +544,7 @@ namespace backend { void CommandBufferBuilder::SetPushConstants(nxt::ShaderStageBit stage, uint32_t offset, uint32_t count, const void* data) { if (offset + count > kMaxPushConstants) { - device->HandleError("Setting too many push constants"); + HandleError("Setting too many push constants"); return; } @@ -564,7 +560,7 @@ namespace backend { void CommandBufferBuilder::SetBindGroup(uint32_t groupIndex, BindGroupBase* group) { if (groupIndex >= kMaxBindGroups) { - device->HandleError("Setting bind group over the max"); + HandleError("Setting bind group over the max"); return; } diff --git a/src/backend/common/CommandBuffer.h b/src/backend/common/CommandBuffer.h index 2fb0e0a838..02b85c7de1 100644 --- a/src/backend/common/CommandBuffer.h +++ b/src/backend/common/CommandBuffer.h @@ -18,6 +18,7 @@ #include "nxt/nxtcpp.h" #include "CommandAllocator.h" +#include "Builder.h" #include "RefCounted.h" #include @@ -44,12 +45,11 @@ namespace backend { std::set texturesTransitioned; }; - class CommandBufferBuilder : public RefCounted { + class CommandBufferBuilder : public Builder { public: CommandBufferBuilder(DeviceBase* device); ~CommandBufferBuilder(); - bool WasConsumed() const; bool ValidateGetResult(); CommandIterator AcquireCommands(); @@ -83,10 +83,8 @@ namespace backend { void MoveToIterator(); - DeviceBase* device; CommandAllocator allocator; CommandIterator iterator; - bool consumed = false; bool movedToIterator = false; // These pointers will remain valid since they are referenced by // the bind groups which are referenced by this command buffer. diff --git a/src/backend/common/InputState.cpp b/src/backend/common/InputState.cpp index 2b2da0c117..a0ea2be4b5 100644 --- a/src/backend/common/InputState.cpp +++ b/src/backend/common/InputState.cpp @@ -78,37 +78,34 @@ namespace backend { // InputStateBuilder - InputStateBuilder::InputStateBuilder(DeviceBase* device) : device(device) { - } - - bool InputStateBuilder::WasConsumed() const { - return consumed; + InputStateBuilder::InputStateBuilder(DeviceBase* device) : Builder(device) { } InputStateBase* InputStateBuilder::GetResult() { for (uint32_t location = 0; location < kMaxVertexAttributes; ++location) { if (attributesSetMask[location] && !inputsSetMask[attributeInfos[location].bindingSlot]) { - device->HandleError("Attribute uses unset input"); + HandleError("Attribute uses unset input"); return nullptr; } } - consumed = true; + + MarkConsumed(); return device->CreateInputState(this); } void InputStateBuilder::SetAttribute(uint32_t shaderLocation, uint32_t bindingSlot, nxt::VertexFormat format, uint32_t offset) { if (shaderLocation >= kMaxVertexAttributes) { - device->HandleError("Setting attribute out of bounds"); + HandleError("Setting attribute out of bounds"); return; } if (bindingSlot >= kMaxVertexInputs) { - device->HandleError("Binding slot out of bounds"); + HandleError("Binding slot out of bounds"); return; } if (attributesSetMask[shaderLocation]) { - device->HandleError("Setting already set attribute"); + HandleError("Setting already set attribute"); return; } @@ -122,11 +119,11 @@ namespace backend { void InputStateBuilder::SetInput(uint32_t bindingSlot, uint32_t stride, nxt::InputStepMode stepMode) { if (bindingSlot >= kMaxVertexInputs) { - device->HandleError("Setting input out of bounds"); + HandleError("Setting input out of bounds"); return; } if (inputsSetMask[bindingSlot]) { - device->HandleError("Setting already set input"); + HandleError("Setting already set input"); return; } diff --git a/src/backend/common/InputState.h b/src/backend/common/InputState.h index 3cf29c2814..2fa48dbf6a 100644 --- a/src/backend/common/InputState.h +++ b/src/backend/common/InputState.h @@ -16,6 +16,7 @@ #define BACKEND_COMMON_INPUTSTATE_H_ #include "Forward.h" +#include "Builder.h" #include "RefCounted.h" #include "nxt/nxtcpp.h" @@ -56,12 +57,10 @@ namespace backend { std::array inputInfos; }; - class InputStateBuilder : public RefCounted { + class InputStateBuilder : public Builder { public: InputStateBuilder(DeviceBase* device); - bool WasConsumed() const; - // NXT API InputStateBase* GetResult(); void SetAttribute(uint32_t shaderLocation, uint32_t bindingSlot, @@ -72,12 +71,10 @@ namespace backend { private: friend class InputStateBase; - DeviceBase* device; std::bitset attributesSetMask; std::array attributeInfos; std::bitset inputsSetMask; std::array inputInfos; - bool consumed = false; }; } diff --git a/src/backend/common/Pipeline.cpp b/src/backend/common/Pipeline.cpp index f9901af60a..ded1a0bb4c 100644 --- a/src/backend/common/Pipeline.cpp +++ b/src/backend/common/Pipeline.cpp @@ -29,7 +29,7 @@ namespace backend { if (stageMask != (nxt::ShaderStageBit::Vertex | nxt::ShaderStageBit::Fragment) && stageMask != nxt::ShaderStageBit::Compute) { - device->HandleError("Wrong combination of stage for pipeline"); + builder->HandleError("Wrong combination of stage for pipeline"); return; } @@ -52,7 +52,7 @@ namespace backend { for (auto stageBit : IterateStages(builder->stageMask)) { if (!builder->stages[stageBit].module->IsCompatibleWithPipelineLayout(layout.Get())) { - device->HandleError("Stage not compatible with layout"); + builder->HandleError("Stage not compatible with layout"); return; } @@ -61,7 +61,7 @@ namespace backend { if (!IsCompute()) { if ((builder->stages[nxt::ShaderStage::Vertex].module->GetUsedVertexAttributes() & ~inputState->GetAttributesSetMask()).any()) { - device->HandleError("Pipeline vertex stage uses inputs not in the input state"); + builder->HandleError("Pipeline vertex stage uses inputs not in the input state"); return; } } @@ -90,11 +90,7 @@ namespace backend { // PipelineBuilder PipelineBuilder::PipelineBuilder(DeviceBase* device) - : device(device), stageMask(static_cast(0)) { - } - - bool PipelineBuilder::WasConsumed() const { - return consumed; + : Builder(device), stageMask(static_cast(0)) { } const PipelineBuilder::StageInfo& PipelineBuilder::GetStageInfo(nxt::ShaderStage stage) const { @@ -111,7 +107,7 @@ namespace backend { inputState = device->CreateInputStateBuilder()->GetResult(); } - consumed = true; + MarkConsumed(); return device->CreatePipeline(this); } @@ -121,18 +117,18 @@ namespace backend { void PipelineBuilder::SetStage(nxt::ShaderStage stage, ShaderModuleBase* module, const char* entryPoint) { if (entryPoint != std::string("main")) { - device->HandleError("Currently the entry point has to be main()"); + HandleError("Currently the entry point has to be main()"); return; } if (stage != module->GetExecutionModel()) { - device->HandleError("Setting module with wrong execution model"); + HandleError("Setting module with wrong execution model"); return; } nxt::ShaderStageBit bit = StageBit(stage); if (stageMask & bit) { - device->HandleError("Setting already set stage"); + HandleError("Setting already set stage"); return; } stageMask |= bit; diff --git a/src/backend/common/Pipeline.h b/src/backend/common/Pipeline.h index 761ec5aa15..e2fb2490a4 100644 --- a/src/backend/common/Pipeline.h +++ b/src/backend/common/Pipeline.h @@ -16,6 +16,7 @@ #define BACKEND_COMMON_PIPELINE_H_ #include "Forward.h" +#include "Builder.h" #include "PerStage.h" #include "RefCounted.h" @@ -58,12 +59,10 @@ namespace backend { Ref inputState; }; - class PipelineBuilder : public RefCounted { + class PipelineBuilder : public Builder { public: PipelineBuilder(DeviceBase* device); - bool WasConsumed() const; - struct StageInfo { std::string entryPoint; Ref module; @@ -79,12 +78,10 @@ namespace backend { private: friend class PipelineBase; - DeviceBase* device; Ref layout; nxt::ShaderStageBit stageMask; PerStage stages; Ref inputState; - bool consumed = false; }; } diff --git a/src/backend/common/PipelineLayout.cpp b/src/backend/common/PipelineLayout.cpp index 3a01640053..0400c4d105 100644 --- a/src/backend/common/PipelineLayout.cpp +++ b/src/backend/common/PipelineLayout.cpp @@ -36,11 +36,7 @@ namespace backend { // PipelineLayoutBuilder - PipelineLayoutBuilder::PipelineLayoutBuilder(DeviceBase* device) : device(device) { - } - - bool PipelineLayoutBuilder::WasConsumed() const { - return consumed; + PipelineLayoutBuilder::PipelineLayoutBuilder(DeviceBase* device) : Builder(device) { } PipelineLayoutBase* PipelineLayoutBuilder::GetResult() { @@ -52,17 +48,17 @@ namespace backend { } } - consumed = true; + MarkConsumed(); return device->CreatePipelineLayout(this); } void PipelineLayoutBuilder::SetBindGroupLayout(uint32_t groupIndex, BindGroupLayoutBase* layout) { if (groupIndex >= kMaxBindGroups) { - device->HandleError("groupIndex is over the maximum allowed"); + HandleError("groupIndex is over the maximum allowed"); return; } if (mask[groupIndex]) { - device->HandleError("Bind group layout already specified"); + HandleError("Bind group layout already specified"); return; } diff --git a/src/backend/common/PipelineLayout.h b/src/backend/common/PipelineLayout.h index 79e362617f..fcb74b910a 100644 --- a/src/backend/common/PipelineLayout.h +++ b/src/backend/common/PipelineLayout.h @@ -16,6 +16,7 @@ #define BACKEND_COMMON_PIPELINELAYOUT_H_ #include "Forward.h" +#include "Builder.h" #include "RefCounted.h" #include "nxt/nxtcpp.h" @@ -39,12 +40,10 @@ namespace backend { std::bitset mask; }; - class PipelineLayoutBuilder : public RefCounted { + class PipelineLayoutBuilder : public Builder { public: PipelineLayoutBuilder(DeviceBase* device); - bool WasConsumed() const; - // NXT API PipelineLayoutBase* GetResult(); void SetBindGroupLayout(uint32_t groupIndex, BindGroupLayoutBase* layout); @@ -52,10 +51,8 @@ namespace backend { private: friend class PipelineLayoutBase; - DeviceBase* device; BindGroupLayoutArray bindGroupLayouts; std::bitset mask; - bool consumed = false; }; } diff --git a/src/backend/common/Queue.cpp b/src/backend/common/Queue.cpp index f5483fbffc..f6c89ca4a0 100644 --- a/src/backend/common/Queue.cpp +++ b/src/backend/common/Queue.cpp @@ -27,15 +27,11 @@ namespace backend { // QueueBuilder - QueueBuilder::QueueBuilder(DeviceBase* device) : device(device) { - } - - bool QueueBuilder::WasConsumed() const { - return consumed; + QueueBuilder::QueueBuilder(DeviceBase* device) : Builder(device) { } QueueBase* QueueBuilder::GetResult() { - consumed = true; + MarkConsumed(); return device->CreateQueue(this); } diff --git a/src/backend/common/Queue.h b/src/backend/common/Queue.h index 0c0ce6c35c..4cac9f5f68 100644 --- a/src/backend/common/Queue.h +++ b/src/backend/common/Queue.h @@ -16,6 +16,7 @@ #define BACKEND_COMMON_QUEUE_H_ #include "Forward.h" +#include "Builder.h" #include "RefCounted.h" #include "nxt/nxtcpp.h" @@ -40,18 +41,12 @@ namespace backend { } }; - class QueueBuilder : public RefCounted { + class QueueBuilder : public Builder { public: QueueBuilder(DeviceBase* device); - bool WasConsumed() const; - // NXT API QueueBase* GetResult(); - - private: - DeviceBase* device; - bool consumed = false; }; } diff --git a/src/backend/common/Sampler.cpp b/src/backend/common/Sampler.cpp index 8a4f2fa4fc..8e6ece2194 100644 --- a/src/backend/common/Sampler.cpp +++ b/src/backend/common/Sampler.cpp @@ -28,8 +28,7 @@ namespace backend { enum SamplerSetProperties { SAMPLER_PROPERTY_FILTER = 0x1, }; - SamplerBuilder::SamplerBuilder(DeviceBase* device) - :device(device) { + SamplerBuilder::SamplerBuilder(DeviceBase* device) : Builder(device) { } nxt::FilterMode SamplerBuilder::GetMagFilter() const { @@ -44,18 +43,14 @@ namespace backend { return mipMapFilter; } - bool SamplerBuilder::WasConsumed() const { - return consumed; - } - SamplerBase* SamplerBuilder::GetResult() { - consumed = true; + MarkConsumed(); return device->CreateSampler(this); } void SamplerBuilder::SetFilterMode(nxt::FilterMode magFilter, nxt::FilterMode minFilter, nxt::FilterMode mipMapFilter) { if ((propertiesSet & SAMPLER_PROPERTY_FILTER) != 0) { - device->HandleError("Sampler filter property set multiple times"); + HandleError("Sampler filter property set multiple times"); return; } diff --git a/src/backend/common/Sampler.h b/src/backend/common/Sampler.h index bbd5c58e6c..437b2918ee 100644 --- a/src/backend/common/Sampler.h +++ b/src/backend/common/Sampler.h @@ -16,6 +16,7 @@ #define BACKEND_COMMON_SAMPLER_H_ #include "Forward.h" +#include "Buffer.h" #include "RefCounted.h" #include "nxt/nxtcpp.h" @@ -27,7 +28,7 @@ namespace backend { SamplerBase(SamplerBuilder* builder); }; - class SamplerBuilder : public RefCounted { + class SamplerBuilder : public Builder { public: SamplerBuilder(DeviceBase* device); @@ -35,8 +36,6 @@ namespace backend { nxt::FilterMode GetMinFilter() const; nxt::FilterMode GetMipMapFilter() const; - bool WasConsumed() const; - // NXT API SamplerBase* GetResult(); void SetFilterMode(nxt::FilterMode magFilter, nxt::FilterMode minFilter, nxt::FilterMode mipMapFilter); @@ -44,9 +43,7 @@ namespace backend { private: friend class SamplerBase; - DeviceBase* device; int propertiesSet = 0; - bool consumed = false; nxt::FilterMode magFilter = nxt::FilterMode::Nearest; nxt::FilterMode minFilter = nxt::FilterMode::Nearest; diff --git a/src/backend/common/ShaderModule.cpp b/src/backend/common/ShaderModule.cpp index 831dcb8f5b..2878b94946 100644 --- a/src/backend/common/ShaderModule.cpp +++ b/src/backend/common/ShaderModule.cpp @@ -28,6 +28,7 @@ namespace backend { } void ShaderModuleBase::ExtractSpirvInfo(const spirv_cross::Compiler& compiler) { + // TODO(cwallez@chromium.org): make errors here builder-level const auto& resources = compiler.get_shader_resources(); switch (compiler.get_execution_model()) { @@ -190,10 +191,7 @@ namespace backend { return true; } - ShaderModuleBuilder::ShaderModuleBuilder(DeviceBase* device) : device(device) {} - - bool ShaderModuleBuilder::WasConsumed() const { - return consumed; + ShaderModuleBuilder::ShaderModuleBuilder(DeviceBase* device) : Builder(device) { } std::vector ShaderModuleBuilder::AcquireSpirv() { @@ -202,11 +200,11 @@ namespace backend { ShaderModuleBase* ShaderModuleBuilder::GetResult() { if (spirv.size() == 0) { - device->HandleError("Shader module needs to have the source set"); + HandleError("Shader module needs to have the source set"); return nullptr; } - consumed = true; + MarkConsumed(); return device->CreateShaderModule(this); } diff --git a/src/backend/common/ShaderModule.h b/src/backend/common/ShaderModule.h index 1407fd9f44..1a1591d107 100644 --- a/src/backend/common/ShaderModule.h +++ b/src/backend/common/ShaderModule.h @@ -16,6 +16,7 @@ #define BACKEND_COMMON_SHADERMODULE_H_ #include "Forward.h" +#include "Builder.h" #include "RefCounted.h" #include "nxt/nxtcpp.h" @@ -70,12 +71,10 @@ namespace backend { nxt::ShaderStage executionModel; }; - class ShaderModuleBuilder : public RefCounted { + class ShaderModuleBuilder : public Builder { public: ShaderModuleBuilder(DeviceBase* device); - bool WasConsumed() const; - std::vector AcquireSpirv(); // NXT API @@ -85,9 +84,7 @@ namespace backend { private: friend class ShaderModuleBase; - DeviceBase* device; std::vector spirv; - bool consumed = false; }; } diff --git a/src/backend/common/Texture.cpp b/src/backend/common/Texture.cpp index 4551dbfca6..f92a0edcd8 100644 --- a/src/backend/common/Texture.cpp +++ b/src/backend/common/Texture.cpp @@ -118,35 +118,31 @@ namespace backend { }; TextureBuilder::TextureBuilder(DeviceBase* device) - : device(device) { - } - - bool TextureBuilder::WasConsumed() const { - return consumed; + : Builder(device) { } TextureBase* TextureBuilder::GetResult() { constexpr int allProperties = TEXTURE_PROPERTY_DIMENSION | TEXTURE_PROPERTY_EXTENT | TEXTURE_PROPERTY_FORMAT | TEXTURE_PROPERTY_MIP_LEVELS | TEXTURE_PROPERTY_ALLOWED_USAGE; if ((propertiesSet & allProperties) != allProperties) { - device->HandleError("Texture missing properties"); + HandleError("Texture missing properties"); return nullptr; } if (!TextureBase::IsUsagePossible(allowedUsage, currentUsage)) { - device->HandleError("Initial texture usage is not allowed"); + HandleError("Initial texture usage is not allowed"); return nullptr; } // TODO(cwallez@chromium.org): check stuff based on the dimension - consumed = true; + MarkConsumed(); return device->CreateTexture(this); } void TextureBuilder::SetDimension(nxt::TextureDimension dimension) { if ((propertiesSet & TEXTURE_PROPERTY_DIMENSION) != 0) { - device->HandleError("Texture dimension property set multiple times"); + HandleError("Texture dimension property set multiple times"); return; } @@ -156,12 +152,12 @@ namespace backend { void TextureBuilder::SetExtent(uint32_t width, uint32_t height, uint32_t depth) { if ((propertiesSet & TEXTURE_PROPERTY_EXTENT) != 0) { - device->HandleError("Texture extent property set multiple times"); + HandleError("Texture extent property set multiple times"); return; } if (width == 0 || height == 0 || depth == 0) { - device->HandleError("Cannot create an empty texture"); + HandleError("Cannot create an empty texture"); return; } @@ -173,7 +169,7 @@ namespace backend { void TextureBuilder::SetFormat(nxt::TextureFormat format) { if ((propertiesSet & TEXTURE_PROPERTY_FORMAT) != 0) { - device->HandleError("Texture format property set multiple times"); + HandleError("Texture format property set multiple times"); return; } @@ -183,7 +179,7 @@ namespace backend { void TextureBuilder::SetMipLevels(uint32_t numMipLevels) { if ((propertiesSet & TEXTURE_PROPERTY_MIP_LEVELS) != 0) { - device->HandleError("Texture mip levels property set multiple times"); + HandleError("Texture mip levels property set multiple times"); return; } @@ -193,7 +189,7 @@ namespace backend { void TextureBuilder::SetAllowedUsage(nxt::TextureUsageBit usage) { if ((propertiesSet & TEXTURE_PROPERTY_ALLOWED_USAGE) != 0) { - device->HandleError("Texture allowed usage property set multiple times"); + HandleError("Texture allowed usage property set multiple times"); return; } @@ -203,7 +199,7 @@ namespace backend { void TextureBuilder::SetInitialUsage(nxt::TextureUsageBit usage) { if ((propertiesSet & TEXTURE_PROPERTY_INITIAL_USAGE) != 0) { - device->HandleError("Texture initial usage property set multiple times"); + HandleError("Texture initial usage property set multiple times"); return; } @@ -224,15 +220,11 @@ namespace backend { // TextureViewBuilder TextureViewBuilder::TextureViewBuilder(DeviceBase* device, TextureBase* texture) - : device(device), texture(texture) { - } - - bool TextureViewBuilder::WasConsumed() const { - return false; + : Builder(device), texture(texture) { } TextureViewBase* TextureViewBuilder::GetResult() { - consumed = true; + MarkConsumed(); return device->CreateTextureView(this); } diff --git a/src/backend/common/Texture.h b/src/backend/common/Texture.h index d76fe802f3..8090f26b8c 100644 --- a/src/backend/common/Texture.h +++ b/src/backend/common/Texture.h @@ -16,6 +16,7 @@ #define BACKEND_COMMON_TEXTURE_H_ #include "Forward.h" +#include "Builder.h" #include "RefCounted.h" #include "nxt/nxtcpp.h" @@ -59,12 +60,10 @@ namespace backend { bool frozen = false; }; - class TextureBuilder : public RefCounted { + class TextureBuilder : public Builder { public: TextureBuilder(DeviceBase* device); - bool WasConsumed() const; - // NXT API TextureBase* GetResult(); void SetDimension(nxt::TextureDimension dimension); @@ -77,9 +76,7 @@ namespace backend { private: friend class TextureBase; - DeviceBase* device; int propertiesSet = 0; - bool consumed = false; nxt::TextureDimension dimension; uint32_t width, height, depth; @@ -99,20 +96,16 @@ namespace backend { Ref texture; }; - class TextureViewBuilder : public RefCounted { + class TextureViewBuilder : public Builder { public: TextureViewBuilder(DeviceBase* device, TextureBase* texture); - bool WasConsumed() const; - // NXT API TextureViewBase* GetResult(); private: friend class TextureViewBase; - DeviceBase* device; - bool consumed = false; Ref texture; }; diff --git a/src/backend/metal/MetalBackend.mm b/src/backend/metal/MetalBackend.mm index c14008e474..b16ab292d5 100644 --- a/src/backend/metal/MetalBackend.mm +++ b/src/backend/metal/MetalBackend.mm @@ -678,7 +678,7 @@ namespace metal { newComputePipelineStateWithFunction:function error:&error]; if (error != nil) { NSLog(@" error => %@", error); - device->HandleError("Error creating pipeline state"); + builder->HandleError("Error creating pipeline state"); return; } @@ -720,7 +720,7 @@ namespace metal { newRenderPipelineStateWithDescriptor:descriptor error:&error]; if (error != nil) { NSLog(@" error => %@", error); - device->HandleError("Error creating pipeline state"); + builder->HandleError("Error creating pipeline state"); return; } @@ -898,7 +898,7 @@ namespace metal { mtlLibrary = [device->GetMTLDevice() newLibraryWithSource:mslSource options:nil error:&error]; if (error != nil) { NSLog(@"MTLDevice newLibraryWithSource => %@", error); - device->HandleError("Error creating MTLLibrary from MSL source"); + builder->HandleError("Error creating MTLLibrary from MSL source"); } }