Create a command buffer builder state tracker object (#19)
diff --git a/src/backend/common/CommandBufferStateTracker.h b/src/backend/common/CommandBufferStateTracker.h
new file mode 100644
index 0000000..7fe4a23
--- /dev/null
+++ b/src/backend/common/CommandBufferStateTracker.h
@@ -0,0 +1,102 @@
+// 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_COMMANDBUFFERSTATETRACKER_H
+#define BACKEND_COMMON_COMMANDBUFFERSTATETRACKER_H
+
+#include "CommandBuffer.h"
+
+#include <bitset>
+#include <map>
+#include <set>
+
+namespace backend {
+ class CommandBufferStateTracker {
+ public:
+ explicit CommandBufferStateTracker(CommandBufferBuilder* builder);
+
+ // Non-state-modifying validation functions
+ bool HaveRenderPass() const;
+ bool ValidateCanCopy() const;
+ bool ValidateCanUseBufferAs(BufferBase* buffer, nxt::BufferUsageBit usage) const;
+ bool ValidateCanUseTextureAs(TextureBase* texture, nxt::TextureUsageBit usage) const;
+ bool ValidateCanDispatch();
+ bool ValidateCanDrawArrays();
+ bool ValidateCanDrawElements();
+
+ // State-modifying methods
+ bool BeginSubpass();
+ bool EndSubpass();
+ bool BeginRenderPass(RenderPassBase* renderPass, FramebufferBase* framebuffer);
+ bool AdvanceSubpass();
+ bool EndRenderPass();
+ bool SetPipeline(PipelineBase* pipeline);
+ bool SetBindGroup(uint32_t index, BindGroupBase* bindgroup);
+ bool SetIndexBuffer(BufferBase* buffer);
+ bool SetVertexBuffer(uint32_t index, BufferBase* buffer);
+ bool TransitionBufferUsage(BufferBase* buffer, nxt::BufferUsageBit usage);
+ bool TransitionTextureUsage(TextureBase* texture, nxt::TextureUsageBit usage);
+
+ // These collections are copied to the CommandBuffer at build time.
+ // These pointers will remain valid since they are referenced by
+ // the bind groups which are referenced by this command buffer.
+ std::set<BufferBase*> buffersTransitioned;
+ std::set<TextureBase*> texturesTransitioned;
+
+ private:
+ enum ValidationAspect {
+ VALIDATION_ASPECT_RENDER_PIPELINE,
+ VALIDATION_ASPECT_COMPUTE_PIPELINE,
+ VALIDATION_ASPECT_BIND_GROUPS,
+ VALIDATION_ASPECT_VERTEX_BUFFERS,
+ VALIDATION_ASPECT_INDEX_BUFFER,
+
+ VALIDATION_ASPECT_COUNT
+ };
+ using ValidationAspects = std::bitset<VALIDATION_ASPECT_COUNT>;
+
+ // Usage helper functions
+ bool BufferHasGuaranteedUsageBit(BufferBase* buffer, nxt::BufferUsageBit usage) const;
+ bool TextureHasGuaranteedUsageBit(TextureBase* texture, nxt::TextureUsageBit usage) const;
+ bool IsTextureTransitionPossible(TextureBase* texture, nxt::TextureUsageBit usage) const;
+
+ // Queries for lazily evaluated aspects
+ bool RecomputeHaveAspectBindGroups();
+ bool RecomputeHaveAspectVertexBuffers();
+
+ bool HavePipeline() const;
+ bool ValidateBindGroupUsages(BindGroupBase* group) const;
+ bool RevalidateCanDraw();
+
+ void UnsetPipeline();
+
+ CommandBufferBuilder* builder;
+
+ ValidationAspects aspects;
+
+ std::bitset<kMaxBindGroups> bindgroupsSet;
+ std::bitset<kMaxVertexInputs> inputsSet;
+ PipelineBase* lastPipeline = nullptr;
+
+ std::map<BufferBase*, nxt::BufferUsageBit> mostRecentBufferUsages;
+ std::map<TextureBase*, nxt::TextureUsageBit> mostRecentTextureUsages;
+
+ RenderPassBase* currentRenderPass = nullptr;
+ FramebufferBase* currentFramebuffer = nullptr;
+ bool subpassActive = false;
+ uint32_t currentSubpass = 0;
+ };
+}
+
+#endif // BACKEND_COMMON_COMMANDBUFFERSTATETRACKER_H