Format: src/backend/opengl
diff --git a/src/backend/opengl/BlendStateGL.cpp b/src/backend/opengl/BlendStateGL.cpp
index f4aa285..d1ead39 100644
--- a/src/backend/opengl/BlendStateGL.cpp
+++ b/src/backend/opengl/BlendStateGL.cpp
@@ -17,8 +17,7 @@
 #include "backend/opengl/OpenGLBackend.h"
 #include "common/Assert.h"
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
     namespace {
         GLenum GLBlendFactor(nxt::BlendFactor factor, bool alpha) {
@@ -70,7 +69,7 @@
                     UNREACHABLE();
             }
         }
-    }
+    }  // namespace
 
     BlendState::BlendState(BlendStateBuilder* builder) : BlendStateBase(builder) {
     }
@@ -80,17 +79,19 @@
 
         if (info.blendEnabled) {
             glEnablei(GL_BLEND, attachment);
-            glBlendEquationSeparatei(attachment, GLBlendMode(info.colorBlend.operation), GLBlendMode(info.alphaBlend.operation));
-            glBlendFuncSeparatei(attachment, GLBlendFactor(info.colorBlend.srcFactor, false), GLBlendFactor(info.colorBlend.dstFactor, false), GLBlendFactor(info.alphaBlend.srcFactor, true), GLBlendFactor(info.alphaBlend.dstFactor, true));
-            glColorMaski(attachment,
-                info.colorWriteMask & nxt::ColorWriteMask::Red,
-                info.colorWriteMask & nxt::ColorWriteMask::Green,
-                info.colorWriteMask & nxt::ColorWriteMask::Blue,
-                info.colorWriteMask & nxt::ColorWriteMask::Alpha);
+            glBlendEquationSeparatei(attachment, GLBlendMode(info.colorBlend.operation),
+                                     GLBlendMode(info.alphaBlend.operation));
+            glBlendFuncSeparatei(attachment, GLBlendFactor(info.colorBlend.srcFactor, false),
+                                 GLBlendFactor(info.colorBlend.dstFactor, false),
+                                 GLBlendFactor(info.alphaBlend.srcFactor, true),
+                                 GLBlendFactor(info.alphaBlend.dstFactor, true));
+            glColorMaski(attachment, info.colorWriteMask & nxt::ColorWriteMask::Red,
+                         info.colorWriteMask & nxt::ColorWriteMask::Green,
+                         info.colorWriteMask & nxt::ColorWriteMask::Blue,
+                         info.colorWriteMask & nxt::ColorWriteMask::Alpha);
         } else {
             glDisablei(GL_BLEND, attachment);
         }
     }
 
-}
-}
+}}  // namespace backend::opengl
diff --git a/src/backend/opengl/BlendStateGL.h b/src/backend/opengl/BlendStateGL.h
index e286cd5..499692d 100644
--- a/src/backend/opengl/BlendStateGL.h
+++ b/src/backend/opengl/BlendStateGL.h
@@ -19,17 +19,15 @@
 
 #include "glad/glad.h"
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
     class BlendState : public BlendStateBase {
-        public:
-            BlendState(BlendStateBuilder* builder);
+      public:
+        BlendState(BlendStateBuilder* builder);
 
-            void ApplyNow(uint32_t attachment);
+        void ApplyNow(uint32_t attachment);
     };
 
-}
-}
+}}  // namespace backend::opengl
 
-#endif // BACKEND_OPENGL_BLENDSTATED3D12_H_
+#endif  // BACKEND_OPENGL_BLENDSTATED3D12_H_
diff --git a/src/backend/opengl/BufferGL.cpp b/src/backend/opengl/BufferGL.cpp
index 0086dba..0e82fe3 100644
--- a/src/backend/opengl/BufferGL.cpp
+++ b/src/backend/opengl/BufferGL.cpp
@@ -16,13 +16,11 @@
 
 #include "backend/opengl/OpenGLBackend.h"
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
     // Buffer
 
-    Buffer::Buffer(BufferBuilder* builder)
-        : BufferBase(builder) {
+    Buffer::Buffer(BufferBuilder* builder) : BufferBase(builder) {
         glGenBuffers(1, &mBuffer);
         glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
         glBufferData(GL_ARRAY_BUFFER, GetSize(), nullptr, GL_STATIC_DRAW);
@@ -40,7 +38,8 @@
     void Buffer::MapReadAsyncImpl(uint32_t serial, uint32_t start, uint32_t count) {
         // TODO(cwallez@chromium.org): this does GPU->CPU synchronization, we could require a high
         // version of OpenGL that would let us map the buffer unsynchronized.
-        // TODO(cwallez@chromium.org): this crashes on Mac NVIDIA, use GetBufferSubData there instead?
+        // TODO(cwallez@chromium.org): this crashes on Mac NVIDIA, use GetBufferSubData there
+        // instead?
         glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
         void* data = glMapBufferRange(GL_ARRAY_BUFFER, start, count, GL_MAP_READ_BIT);
         CallMapReadCallback(serial, NXT_BUFFER_MAP_READ_STATUS_SUCCESS, data);
@@ -56,9 +55,7 @@
 
     // BufferView
 
-    BufferView::BufferView(BufferViewBuilder* builder)
-        : BufferViewBase(builder) {
+    BufferView::BufferView(BufferViewBuilder* builder) : BufferViewBase(builder) {
     }
 
-}
-}
+}}  // namespace backend::opengl
diff --git a/src/backend/opengl/BufferGL.h b/src/backend/opengl/BufferGL.h
index fb589c7..4dfa96a 100644
--- a/src/backend/opengl/BufferGL.h
+++ b/src/backend/opengl/BufferGL.h
@@ -19,32 +19,31 @@
 
 #include "glad/glad.h"
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
     class Device;
 
     class Buffer : public BufferBase {
-        public:
-            Buffer(BufferBuilder* builder);
+      public:
+        Buffer(BufferBuilder* builder);
 
-            GLuint GetHandle() const;
+        GLuint GetHandle() const;
 
-        private:
-            void SetSubDataImpl(uint32_t start, uint32_t count, const uint32_t* data) override;
-            void MapReadAsyncImpl(uint32_t serial, uint32_t start, uint32_t count) override;
-            void UnmapImpl() override;
-            void TransitionUsageImpl(nxt::BufferUsageBit currentUsage, nxt::BufferUsageBit targetUsage) override;
+      private:
+        void SetSubDataImpl(uint32_t start, uint32_t count, const uint32_t* data) override;
+        void MapReadAsyncImpl(uint32_t serial, uint32_t start, uint32_t count) override;
+        void UnmapImpl() override;
+        void TransitionUsageImpl(nxt::BufferUsageBit currentUsage,
+                                 nxt::BufferUsageBit targetUsage) override;
 
-            GLuint mBuffer = 0;
+        GLuint mBuffer = 0;
     };
 
     class BufferView : public BufferViewBase {
-        public:
-            BufferView(BufferViewBuilder* builder);
+      public:
+        BufferView(BufferViewBuilder* builder);
     };
 
-}
-}
+}}  // namespace backend::opengl
 
-#endif // BACKEND_OPENGL_BUFFERGL_H_
+#endif  // BACKEND_OPENGL_BUFFERGL_H_
diff --git a/src/backend/opengl/CommandBufferGL.cpp b/src/backend/opengl/CommandBufferGL.cpp
index 32eead8..c8be720 100644
--- a/src/backend/opengl/CommandBufferGL.cpp
+++ b/src/backend/opengl/CommandBufferGL.cpp
@@ -27,8 +27,7 @@
 
 #include <cstring>
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
     namespace {
 
@@ -55,148 +54,159 @@
             }
         }
 
-        // Push constants are implemented using OpenGL uniforms, however they aren't part of the global
-        // OpenGL state but are part of the program state instead. This means that we have to reapply
-        // push constants on pipeline change.
+        // Push constants are implemented using OpenGL uniforms, however they aren't part of the
+        // global OpenGL state but are part of the program state instead. This means that we have to
+        // reapply push constants on pipeline change.
         //
-        // This structure tracks the current values of push constants as well as dirty bits for push constants
-        // that should be applied before the next draw or dispatch.
+        // This structure tracks the current values of push constants as well as dirty bits for push
+        // constants that should be applied before the next draw or dispatch.
         class PushConstantTracker {
-            public:
-                void OnBeginPass() {
-                    for (auto stage : IterateStages(kAllStages)) {
-                        mValues[stage].fill(0);
-                        // No need to set dirty bits as a pipeline will be set before the next operation
-                        // using push constants.
-                    }
+          public:
+            void OnBeginPass() {
+                for (auto stage : IterateStages(kAllStages)) {
+                    mValues[stage].fill(0);
+                    // No need to set dirty bits as a pipeline will be set before the next operation
+                    // using push constants.
                 }
+            }
 
-                void OnSetPushConstants(nxt::ShaderStageBit stages, uint32_t count,
-                                        uint32_t offset, const uint32_t* data) {
-                    for (auto stage : IterateStages(stages)) {
-                        memcpy(&mValues[stage][offset], data, count * sizeof(uint32_t));
+            void OnSetPushConstants(nxt::ShaderStageBit stages,
+                                    uint32_t count,
+                                    uint32_t offset,
+                                    const uint32_t* data) {
+                for (auto stage : IterateStages(stages)) {
+                    memcpy(&mValues[stage][offset], data, count * sizeof(uint32_t));
 
-                        // Use 64 bit masks and make sure there are no shift UB
-                        static_assert(kMaxPushConstants <= 8 * sizeof(unsigned long long) - 1, "");
-                        mDirtyBits[stage] |= ((1ull << count) - 1ull) << offset;
-                    }
+                    // Use 64 bit masks and make sure there are no shift UB
+                    static_assert(kMaxPushConstants <= 8 * sizeof(unsigned long long) - 1, "");
+                    mDirtyBits[stage] |= ((1ull << count) - 1ull) << offset;
                 }
+            }
 
-                void OnSetPipeline(PipelineBase* pipeline) {
-                    for (auto stage : IterateStages(kAllStages)) {
-                        mDirtyBits[stage] = pipeline->GetPushConstants(stage).mask;
-                    }
+            void OnSetPipeline(PipelineBase* pipeline) {
+                for (auto stage : IterateStages(kAllStages)) {
+                    mDirtyBits[stage] = pipeline->GetPushConstants(stage).mask;
                 }
+            }
 
-                void Apply(PipelineBase* pipeline, PipelineGL* glPipeline) {
-                    for (auto stage : IterateStages(kAllStages)) {
-                        const auto& pushConstants = pipeline->GetPushConstants(stage);
-                        const auto& glPushConstants = glPipeline->GetGLPushConstants(stage);
+            void Apply(PipelineBase* pipeline, PipelineGL* glPipeline) {
+                for (auto stage : IterateStages(kAllStages)) {
+                    const auto& pushConstants = pipeline->GetPushConstants(stage);
+                    const auto& glPushConstants = glPipeline->GetGLPushConstants(stage);
 
-                        for (uint32_t constant : IterateBitSet(mDirtyBits[stage] & pushConstants.mask)) {
-                            GLint location = glPushConstants[constant];
-                            switch (pushConstants.types[constant]) {
-                                case PushConstantType::Int:
-                                    glUniform1i(location, *reinterpret_cast<GLint*>(&mValues[stage][constant]));
-                                    break;
-                                case PushConstantType::UInt:
-                                    glUniform1ui(location, *reinterpret_cast<GLuint*>(&mValues[stage][constant]));
-                                    break;
-                                case PushConstantType::Float:
-                                    glUniform1f(location, *reinterpret_cast<GLfloat*>(&mValues[stage][constant]));
-                                    break;
-                            }
+                    for (uint32_t constant :
+                         IterateBitSet(mDirtyBits[stage] & pushConstants.mask)) {
+                        GLint location = glPushConstants[constant];
+                        switch (pushConstants.types[constant]) {
+                            case PushConstantType::Int:
+                                glUniform1i(location,
+                                            *reinterpret_cast<GLint*>(&mValues[stage][constant]));
+                                break;
+                            case PushConstantType::UInt:
+                                glUniform1ui(location,
+                                             *reinterpret_cast<GLuint*>(&mValues[stage][constant]));
+                                break;
+                            case PushConstantType::Float:
+                                glUniform1f(location,
+                                            *reinterpret_cast<GLfloat*>(&mValues[stage][constant]));
+                                break;
                         }
-
-                        mDirtyBits[stage].reset();
                     }
-                }
 
-        private:
+                    mDirtyBits[stage].reset();
+                }
+            }
+
+          private:
             PerStage<std::array<uint32_t, kMaxPushConstants>> mValues;
             PerStage<std::bitset<kMaxPushConstants>> mDirtyBits;
         };
 
-        // Vertex buffers and index buffers are implemented as part of an OpenGL VAO that corresponds to an
-        // InputState. On the contrary in NXT they are part of the global state. This means that we have to
-        // re-apply these buffers on an InputState change.
+        // Vertex buffers and index buffers are implemented as part of an OpenGL VAO that
+        // corresponds to an InputState. On the contrary in NXT they are part of the global state.
+        // This means that we have to re-apply these buffers on an InputState change.
         class InputBufferTracker {
-            public:
-                void OnBeginPass() {
-                    // We don't know what happened between this pass and the last one, just reset the
-                    // input state so everything gets reapplied.
-                    mLastInputState = nullptr;
+          public:
+            void OnBeginPass() {
+                // We don't know what happened between this pass and the last one, just reset the
+                // input state so everything gets reapplied.
+                mLastInputState = nullptr;
+            }
+
+            void OnSetIndexBuffer(BufferBase* buffer) {
+                mIndexBufferDirty = true;
+                mIndexBuffer = ToBackend(buffer);
+            }
+
+            void OnSetVertexBuffers(uint32_t startSlot,
+                                    uint32_t count,
+                                    Ref<BufferBase>* buffers,
+                                    uint32_t* offsets) {
+                for (uint32_t i = 0; i < count; ++i) {
+                    uint32_t slot = startSlot + i;
+                    mVertexBuffers[slot] = ToBackend(buffers[i].Get());
+                    mVertexBufferOffsets[slot] = offsets[i];
                 }
 
-                void OnSetIndexBuffer(BufferBase* buffer) {
-                    mIndexBufferDirty = true;
-                    mIndexBuffer = ToBackend(buffer);
+                // Use 64 bit masks and make sure there are no shift UB
+                static_assert(kMaxVertexInputs <= 8 * sizeof(unsigned long long) - 1, "");
+                mDirtyVertexBuffers |= ((1ull << count) - 1ull) << startSlot;
+            }
+
+            void OnSetPipeline(RenderPipelineBase* pipeline) {
+                InputStateBase* inputState = pipeline->GetInputState();
+                if (mLastInputState == inputState) {
+                    return;
                 }
 
-                void OnSetVertexBuffers(uint32_t startSlot, uint32_t count, Ref<BufferBase>* buffers, uint32_t* offsets) {
-                    for (uint32_t i = 0; i < count; ++i) {
-                        uint32_t slot = startSlot + i;
-                        mVertexBuffers[slot] = ToBackend(buffers[i].Get());
-                        mVertexBufferOffsets[slot] = offsets[i];
+                mIndexBufferDirty = true;
+                mDirtyVertexBuffers |= inputState->GetInputsSetMask();
+
+                mLastInputState = ToBackend(inputState);
+            }
+
+            void Apply() {
+                if (mIndexBufferDirty && mIndexBuffer != nullptr) {
+                    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer->GetHandle());
+                    mIndexBufferDirty = false;
+                }
+
+                for (uint32_t slot :
+                     IterateBitSet(mDirtyVertexBuffers & mLastInputState->GetInputsSetMask())) {
+                    for (uint32_t location :
+                         IterateBitSet(mLastInputState->GetAttributesUsingInput(slot))) {
+                        auto attribute = mLastInputState->GetAttribute(location);
+
+                        GLuint buffer = mVertexBuffers[slot]->GetHandle();
+                        uint32_t offset = mVertexBufferOffsets[slot];
+
+                        auto input = mLastInputState->GetInput(slot);
+                        auto components = VertexFormatNumComponents(attribute.format);
+                        auto formatType = VertexFormatType(attribute.format);
+
+                        glBindBuffer(GL_ARRAY_BUFFER, buffer);
+                        glVertexAttribPointer(
+                            location, components, formatType, GL_FALSE, input.stride,
+                            reinterpret_cast<void*>(
+                                static_cast<intptr_t>(offset + attribute.offset)));
                     }
-
-                    // Use 64 bit masks and make sure there are no shift UB
-                    static_assert(kMaxVertexInputs <= 8 * sizeof(unsigned long long) - 1, "");
-                    mDirtyVertexBuffers |= ((1ull << count) - 1ull) << startSlot;
                 }
 
-                void OnSetPipeline(RenderPipelineBase* pipeline) {
-                    InputStateBase* inputState = pipeline->GetInputState();
-                    if (mLastInputState == inputState) {
-                        return;
-                    }
+                mDirtyVertexBuffers.reset();
+            }
 
-                    mIndexBufferDirty = true;
-                    mDirtyVertexBuffers |= inputState->GetInputsSetMask();
+          private:
+            bool mIndexBufferDirty = false;
+            Buffer* mIndexBuffer = nullptr;
 
-                    mLastInputState = ToBackend(inputState);
-                }
+            std::bitset<kMaxVertexInputs> mDirtyVertexBuffers;
+            std::array<Buffer*, kMaxVertexInputs> mVertexBuffers;
+            std::array<uint32_t, kMaxVertexInputs> mVertexBufferOffsets;
 
-                void Apply() {
-                    if (mIndexBufferDirty && mIndexBuffer != nullptr) {
-                        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer->GetHandle());
-                        mIndexBufferDirty = false;
-                    }
-
-                    for (uint32_t slot : IterateBitSet(mDirtyVertexBuffers & mLastInputState->GetInputsSetMask())) {
-                        for (uint32_t location : IterateBitSet(mLastInputState->GetAttributesUsingInput(slot))) {
-                            auto attribute = mLastInputState->GetAttribute(location);
-
-                            GLuint buffer = mVertexBuffers[slot]->GetHandle();
-                            uint32_t offset = mVertexBufferOffsets[slot];
-
-                            auto input = mLastInputState->GetInput(slot);
-                            auto components = VertexFormatNumComponents(attribute.format);
-                            auto formatType = VertexFormatType(attribute.format);
-
-                            glBindBuffer(GL_ARRAY_BUFFER, buffer);
-                            glVertexAttribPointer(
-                                    location, components, formatType, GL_FALSE,
-                                    input.stride,
-                                    reinterpret_cast<void*>(static_cast<intptr_t>(offset + attribute.offset)));
-                        }
-                    }
-
-                    mDirtyVertexBuffers.reset();
-                }
-
-            private:
-                bool mIndexBufferDirty = false;
-                Buffer* mIndexBuffer = nullptr;
-
-                std::bitset<kMaxVertexInputs> mDirtyVertexBuffers;
-                std::array<Buffer*, kMaxVertexInputs> mVertexBuffers;
-                std::array<uint32_t, kMaxVertexInputs> mVertexBufferOffsets;
-
-                InputState* mLastInputState = nullptr;
+            InputState* mLastInputState = nullptr;
         };
 
-    }
+    }  // namespace
 
     CommandBuffer::CommandBuffer(CommandBufferBuilder* builder)
         : CommandBufferBase(builder), mCommands(builder->AcquireCommands()) {
@@ -224,426 +234,402 @@
         uint32_t currentSubpass = 0;
         GLuint currentFBO = 0;
 
-        while(mCommands.NextCommandId(&type)) {
+        while (mCommands.NextCommandId(&type)) {
             switch (type) {
-                case Command::BeginComputePass:
-                    {
-                        mCommands.NextCommand<BeginComputePassCmd>();
-                        pushConstants.OnBeginPass();
+                case Command::BeginComputePass: {
+                    mCommands.NextCommand<BeginComputePassCmd>();
+                    pushConstants.OnBeginPass();
+                } break;
+
+                case Command::BeginRenderPass: {
+                    auto* cmd = mCommands.NextCommand<BeginRenderPassCmd>();
+                    currentRenderPass = ToBackend(cmd->renderPass.Get());
+                    currentFramebuffer = ToBackend(cmd->framebuffer.Get());
+                    currentSubpass = 0;
+                } break;
+
+                case Command::BeginRenderSubpass: {
+                    mCommands.NextCommand<BeginRenderSubpassCmd>();
+                    pushConstants.OnBeginPass();
+                    inputBuffers.OnBeginPass();
+
+                    // TODO(kainino@chromium.org): This is added to possibly
+                    // work around an issue seen on Windows/Intel. It should
+                    // break any feedback loop before the clears, even if
+                    // there shouldn't be any negative effects from this.
+                    // Investigate whether it's actually needed.
+                    glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
+                    // TODO(kainino@chromium.org): possible future
+                    // optimization: create these framebuffers at
+                    // Framebuffer build time (or maybe CommandBuffer build
+                    // time) so they don't have to be created and destroyed
+                    // at draw time.
+                    glGenFramebuffers(1, &currentFBO);
+                    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, currentFBO);
+
+                    const auto& subpass = currentRenderPass->GetSubpassInfo(currentSubpass);
+
+                    // Mapping from attachmentSlot to GL framebuffer
+                    // attachment points. Defaults to zero (GL_NONE).
+                    std::array<GLenum, kMaxColorAttachments> drawBuffers = {};
+
+                    // Construct GL framebuffer
+
+                    unsigned int attachmentCount = 0;
+                    for (unsigned int location : IterateBitSet(subpass.colorAttachmentsSet)) {
+                        uint32_t attachment = subpass.colorAttachments[location];
+
+                        auto textureView = currentFramebuffer->GetTextureView(attachment);
+                        GLuint texture = ToBackend(textureView->GetTexture())->GetHandle();
+
+                        // Attach color buffers.
+                        glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + location,
+                                               GL_TEXTURE_2D, texture, 0);
+                        drawBuffers[location] = GL_COLOR_ATTACHMENT0 + location;
+                        attachmentCount = location + 1;
+
+                        // TODO(kainino@chromium.org): the color clears (later in
+                        // this function) may be undefined for other texture formats.
+                        ASSERT(textureView->GetTexture()->GetFormat() ==
+                               nxt::TextureFormat::R8G8B8A8Unorm);
                     }
-                    break;
+                    glDrawBuffers(attachmentCount, drawBuffers.data());
 
-                case Command::BeginRenderPass:
-                    {
-                        auto* cmd = mCommands.NextCommand<BeginRenderPassCmd>();
-                        currentRenderPass = ToBackend(cmd->renderPass.Get());
-                        currentFramebuffer = ToBackend(cmd->framebuffer.Get());
-                        currentSubpass = 0;
-                    }
-                    break;
+                    if (subpass.depthStencilAttachmentSet) {
+                        uint32_t attachmentSlot = subpass.depthStencilAttachment;
 
-                case Command::BeginRenderSubpass:
-                    {
-                        mCommands.NextCommand<BeginRenderSubpassCmd>();
-                        pushConstants.OnBeginPass();
-                        inputBuffers.OnBeginPass();
+                        auto textureView = currentFramebuffer->GetTextureView(attachmentSlot);
+                        GLuint texture = ToBackend(textureView->GetTexture())->GetHandle();
+                        nxt::TextureFormat format = textureView->GetTexture()->GetFormat();
 
-                        // TODO(kainino@chromium.org): This is added to possibly
-                        // work around an issue seen on Windows/Intel. It should
-                        // break any feedback loop before the clears, even if
-                        // there shouldn't be any negative effects from this.
-                        // Investigate whether it's actually needed.
-                        glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
-                        // TODO(kainino@chromium.org): possible future
-                        // optimization: create these framebuffers at
-                        // Framebuffer build time (or maybe CommandBuffer build
-                        // time) so they don't have to be created and destroyed
-                        // at draw time.
-                        glGenFramebuffers(1, &currentFBO);
-                        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, currentFBO);
-
-                        const auto& subpass = currentRenderPass->GetSubpassInfo(currentSubpass);
-
-                        // Mapping from attachmentSlot to GL framebuffer
-                        // attachment points. Defaults to zero (GL_NONE).
-                        std::array<GLenum, kMaxColorAttachments> drawBuffers = {};
-
-                        // Construct GL framebuffer
-
-                        unsigned int attachmentCount = 0;
-                        for (unsigned int location : IterateBitSet(subpass.colorAttachmentsSet)) {
-                            uint32_t attachment = subpass.colorAttachments[location];
-
-                            auto textureView = currentFramebuffer->GetTextureView(attachment);
-                            GLuint texture = ToBackend(textureView->GetTexture())->GetHandle();
-
-                            // Attach color buffers.
-                            glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
-                                    GL_COLOR_ATTACHMENT0 + location,
-                                    GL_TEXTURE_2D, texture, 0);
-                            drawBuffers[location] = GL_COLOR_ATTACHMENT0 + location;
-                            attachmentCount = location + 1;
-
-                            // TODO(kainino@chromium.org): the color clears (later in
-                            // this function) may be undefined for other texture formats.
-                            ASSERT(textureView->GetTexture()->GetFormat() == nxt::TextureFormat::R8G8B8A8Unorm);
-                        }
-                        glDrawBuffers(attachmentCount, drawBuffers.data());
-
-                        if (subpass.depthStencilAttachmentSet) {
-                            uint32_t attachmentSlot = subpass.depthStencilAttachment;
-
-                            auto textureView = currentFramebuffer->GetTextureView(attachmentSlot);
-                            GLuint texture = ToBackend(textureView->GetTexture())->GetHandle();
-                            nxt::TextureFormat format = textureView->GetTexture()->GetFormat();
-
-                            // Attach depth/stencil buffer.
-                            GLenum glAttachment = 0;
-                            // TODO(kainino@chromium.org): it may be valid to just always use GL_DEPTH_STENCIL_ATTACHMENT here.
-                            if (TextureFormatHasDepth(format)) {
-                                if (TextureFormatHasStencil(format)) {
-                                    glAttachment = GL_DEPTH_STENCIL_ATTACHMENT;
-                                } else {
-                                    glAttachment = GL_DEPTH_ATTACHMENT;
-                                }
+                        // Attach depth/stencil buffer.
+                        GLenum glAttachment = 0;
+                        // TODO(kainino@chromium.org): it may be valid to just always use
+                        // GL_DEPTH_STENCIL_ATTACHMENT here.
+                        if (TextureFormatHasDepth(format)) {
+                            if (TextureFormatHasStencil(format)) {
+                                glAttachment = GL_DEPTH_STENCIL_ATTACHMENT;
                             } else {
-                                glAttachment = GL_STENCIL_ATTACHMENT;
+                                glAttachment = GL_DEPTH_ATTACHMENT;
                             }
-
-                            glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, glAttachment, GL_TEXTURE_2D, texture, 0);
-
-                            // TODO(kainino@chromium.org): the depth/stencil clears (later in
-                            // this function) may be undefined for other texture formats.
-                            ASSERT(format == nxt::TextureFormat::D32FloatS8Uint);
-                        }
-
-                        // Clear framebuffer attachments as needed
-
-                        for (unsigned int location : IterateBitSet(subpass.colorAttachmentsSet)) {
-                            uint32_t attachmentSlot = subpass.colorAttachments[location];
-                            const auto& attachmentInfo = currentRenderPass->GetAttachmentInfo(attachmentSlot);
-
-                            // Only perform load op on first use
-                            if (attachmentInfo.firstSubpass == currentSubpass) {
-                                // Load op - color
-                                if (attachmentInfo.colorLoadOp == nxt::LoadOp::Clear) {
-                                    const auto& clear = currentFramebuffer->GetClearColor(location);
-                                    glClearBufferfv(GL_COLOR, location, clear.color);
-                                }
-                            }
-                        }
-
-                        if (subpass.depthStencilAttachmentSet) {
-                            uint32_t attachmentSlot = subpass.depthStencilAttachment;
-                            const auto& attachmentInfo = currentRenderPass->GetAttachmentInfo(attachmentSlot);
-
-                            // Only perform load op on first use
-                            if (attachmentInfo.firstSubpass == currentSubpass) {
-                                // Load op - depth/stencil
-                                const auto& clear = currentFramebuffer->GetClearDepthStencil(subpass.depthStencilAttachment);
-                                bool doDepthClear = TextureFormatHasDepth(attachmentInfo.format) &&
-                                    (attachmentInfo.depthLoadOp == nxt::LoadOp::Clear);
-                                bool doStencilClear = TextureFormatHasStencil(attachmentInfo.format) &&
-                                    (attachmentInfo.stencilLoadOp == nxt::LoadOp::Clear);
-                                if (doDepthClear && doStencilClear) {
-                                    glClearBufferfi(GL_DEPTH_STENCIL, 0, clear.depth, clear.stencil);
-                                } else if (doDepthClear) {
-                                    glClearBufferfv(GL_DEPTH, 0, &clear.depth);
-                                } else if (doStencilClear) {
-                                    const GLint clearStencil = clear.stencil;
-                                    glClearBufferiv(GL_STENCIL, 0, &clearStencil);
-                                }
-                            }
-                        }
-
-                        glBlendColor(0, 0, 0, 0);
-                        glViewport(0, 0, currentFramebuffer->GetWidth(), currentFramebuffer->GetHeight());
-                    }
-                    break;
-
-                case Command::CopyBufferToBuffer:
-                    {
-                        CopyBufferToBufferCmd* copy = mCommands.NextCommand<CopyBufferToBufferCmd>();
-                        auto& src = copy->source;
-                        auto& dst = copy->destination;
-
-                        glBindBuffer(GL_PIXEL_PACK_BUFFER, ToBackend(src.buffer)->GetHandle());
-                        glBindBuffer(GL_PIXEL_UNPACK_BUFFER, ToBackend(dst.buffer)->GetHandle());
-                        glCopyBufferSubData(GL_PIXEL_PACK_BUFFER, GL_PIXEL_UNPACK_BUFFER, src.offset, dst.offset, copy->size);
-
-                        glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
-                        glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
-                    }
-                    break;
-
-                case Command::CopyBufferToTexture:
-                    {
-                        CopyBufferToTextureCmd* copy = mCommands.NextCommand<CopyBufferToTextureCmd>();
-                        auto& src = copy->source;
-                        auto& dst = copy->destination;
-                        Buffer* buffer = ToBackend(src.buffer.Get());
-                        Texture* texture = ToBackend(dst.texture.Get());
-                        GLenum target = texture->GetGLTarget();
-                        auto format = texture->GetGLFormat();
-
-                        glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer->GetHandle());
-                        glActiveTexture(GL_TEXTURE0);
-                        glBindTexture(target, texture->GetHandle());
-
-                        ASSERT(texture->GetDimension() == nxt::TextureDimension::e2D);
-                        glPixelStorei(GL_UNPACK_ROW_LENGTH, copy->rowPitch / TextureFormatPixelSize(texture->GetFormat()));
-                        glTexSubImage2D(target, dst.level, dst.x, dst.y, dst.width, dst.height,
-                                        format.format, format.type,
-                                        reinterpret_cast<void*>(static_cast<uintptr_t>(src.offset)));
-                        glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-                        glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
-                    }
-                    break;
-
-                case Command::CopyTextureToBuffer:
-                    {
-                        CopyTextureToBufferCmd* copy = mCommands.NextCommand<CopyTextureToBufferCmd>();
-                        auto& src = copy->source;
-                        auto& dst = copy->destination;
-                        Texture* texture = ToBackend(src.texture.Get());
-                        Buffer* buffer = ToBackend(dst.buffer.Get());
-                        auto format = texture->GetGLFormat();
-
-                        // The only way to move data from a texture to a buffer in GL is via
-                        // glReadPixels with a pack buffer. Create a temporary FBO for the copy.
-                        ASSERT(texture->GetDimension() == nxt::TextureDimension::e2D);
-                        glBindTexture(GL_TEXTURE_2D, texture->GetHandle());
-
-                        GLuint readFBO = 0;
-                        glGenFramebuffers(1, &readFBO);
-                        glBindFramebuffer(GL_READ_FRAMEBUFFER, readFBO);
-
-                        glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
-                                               texture->GetHandle(), src.level);
-
-                        glBindBuffer(GL_PIXEL_PACK_BUFFER, buffer->GetHandle());
-                        glPixelStorei(GL_PACK_ROW_LENGTH, copy->rowPitch / TextureFormatPixelSize(texture->GetFormat()));
-                        ASSERT(src.depth == 1 && src.z == 0);
-                        void* offset = reinterpret_cast<void*>(static_cast<uintptr_t>(dst.offset));
-                        glReadPixels(src.x, src.y, src.width, src.height, format.format, format.type, offset);
-                        glPixelStorei(GL_PACK_ROW_LENGTH, 0);
-
-                        glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
-                        glDeleteFramebuffers(1, &readFBO);
-                    }
-                    break;
-
-                case Command::Dispatch:
-                    {
-                        DispatchCmd* dispatch = mCommands.NextCommand<DispatchCmd>();
-                        pushConstants.Apply(lastPipeline, lastGLPipeline);
-                        glDispatchCompute(dispatch->x, dispatch->y, dispatch->z);
-                        // TODO(cwallez@chromium.org): add barriers to the API
-                        glMemoryBarrier(GL_ALL_BARRIER_BITS);
-                    }
-                    break;
-
-                case Command::DrawArrays:
-                    {
-                        DrawArraysCmd* draw = mCommands.NextCommand<DrawArraysCmd>();
-                        pushConstants.Apply(lastPipeline, lastGLPipeline);
-                        inputBuffers.Apply();
-
-                        if (draw->firstInstance > 0) {
-                            glDrawArraysInstancedBaseInstance(lastRenderPipeline->GetGLPrimitiveTopology(),
-                                draw->firstVertex, draw->vertexCount, draw->instanceCount, draw->firstInstance);
                         } else {
-                            // This branch is only needed on OpenGL < 4.2
-                            glDrawArraysInstanced(lastRenderPipeline->GetGLPrimitiveTopology(),
-                                draw->firstVertex, draw->vertexCount, draw->instanceCount);
+                            glAttachment = GL_STENCIL_ATTACHMENT;
                         }
+
+                        glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, glAttachment, GL_TEXTURE_2D,
+                                               texture, 0);
+
+                        // TODO(kainino@chromium.org): the depth/stencil clears (later in
+                        // this function) may be undefined for other texture formats.
+                        ASSERT(format == nxt::TextureFormat::D32FloatS8Uint);
                     }
-                    break;
 
-                case Command::DrawElements:
-                    {
-                        DrawElementsCmd* draw = mCommands.NextCommand<DrawElementsCmd>();
-                        pushConstants.Apply(lastPipeline, lastGLPipeline);
-                        inputBuffers.Apply();
+                    // Clear framebuffer attachments as needed
 
-                        nxt::IndexFormat indexFormat = lastRenderPipeline->GetIndexFormat();
-                        size_t formatSize = IndexFormatSize(indexFormat);
-                        GLenum formatType = IndexFormatType(indexFormat);
+                    for (unsigned int location : IterateBitSet(subpass.colorAttachmentsSet)) {
+                        uint32_t attachmentSlot = subpass.colorAttachments[location];
+                        const auto& attachmentInfo =
+                            currentRenderPass->GetAttachmentInfo(attachmentSlot);
 
-                        if (draw->firstInstance > 0) {
-                            glDrawElementsInstancedBaseInstance(lastRenderPipeline->GetGLPrimitiveTopology(),
-                                draw->indexCount, formatType,
-                                reinterpret_cast<void*>(draw->firstIndex * formatSize + indexBufferOffset),
-                                draw->instanceCount, draw->firstInstance);
-                        } else {
-                            // This branch is only needed on OpenGL < 4.2
-                            glDrawElementsInstanced(lastRenderPipeline->GetGLPrimitiveTopology(),
-                                draw->indexCount, formatType,
-                                reinterpret_cast<void*>(draw->firstIndex * formatSize + indexBufferOffset),
-                                draw->instanceCount);
-                        }
-                    }
-                    break;
-
-                case Command::EndComputePass:
-                    {
-                        mCommands.NextCommand<EndComputePassCmd>();
-                    }
-                    break;
-
-                case Command::EndRenderPass:
-                    {
-                        mCommands.NextCommand<EndRenderPassCmd>();
-                    }
-                    break;
-
-                case Command::EndRenderSubpass:
-                    {
-                        mCommands.NextCommand<EndRenderSubpassCmd>();
-                        glDeleteFramebuffers(1, &currentFBO);
-                        currentFBO = 0;
-                        currentSubpass += 1;
-                    }
-                    break;
-
-                case Command::SetComputePipeline:
-                    {
-                        SetComputePipelineCmd* cmd = mCommands.NextCommand<SetComputePipelineCmd>();
-                        ToBackend(cmd->pipeline)->ApplyNow();
-                        lastGLPipeline = ToBackend(cmd->pipeline).Get();
-                        lastPipeline = ToBackend(cmd->pipeline).Get();
-                        pushConstants.OnSetPipeline(lastPipeline);
-                    }
-                    break;
-
-                case Command::SetRenderPipeline:
-                    {
-                        SetRenderPipelineCmd* cmd = mCommands.NextCommand<SetRenderPipelineCmd>();
-                        ToBackend(cmd->pipeline)->ApplyNow(persistentPipelineState);
-                        lastRenderPipeline = ToBackend(cmd->pipeline).Get();
-                        lastGLPipeline = ToBackend(cmd->pipeline).Get();
-                        lastPipeline = ToBackend(cmd->pipeline).Get();
-
-                        pushConstants.OnSetPipeline(lastPipeline);
-                        inputBuffers.OnSetPipeline(lastRenderPipeline);
-                    }
-                    break;
-
-                case Command::SetPushConstants:
-                    {
-                        SetPushConstantsCmd* cmd = mCommands.NextCommand<SetPushConstantsCmd>();
-                        uint32_t* data = mCommands.NextData<uint32_t>(cmd->count);
-                        pushConstants.OnSetPushConstants(cmd->stages, cmd->count, cmd->offset, data);
-                    }
-                    break;
-
-                case Command::SetStencilReference:
-                    {
-                        SetStencilReferenceCmd* cmd = mCommands.NextCommand<SetStencilReferenceCmd>();
-                        persistentPipelineState.SetStencilReference(cmd->reference);
-                    }
-                    break;
-
-                case Command::SetBlendColor:
-                    {
-                        SetBlendColorCmd* cmd = mCommands.NextCommand<SetBlendColorCmd>();
-                        glBlendColor(cmd->r, cmd->g, cmd->b, cmd->a);
-                    }
-                    break;
-
-                case Command::SetBindGroup:
-                    {
-                        SetBindGroupCmd* cmd = mCommands.NextCommand<SetBindGroupCmd>();
-                        size_t groupIndex = cmd->index;
-                        BindGroup* group = ToBackend(cmd->group.Get());
-
-                        const auto& indices = ToBackend(lastPipeline->GetLayout())->GetBindingIndexInfo()[groupIndex];
-                        const auto& layout = group->GetLayout()->GetBindingInfo();
-
-                        for (uint32_t binding : IterateBitSet(layout.mask)) {
-                            switch (layout.types[binding]) {
-                                case nxt::BindingType::UniformBuffer:
-                                    {
-                                        BufferView* view = ToBackend(group->GetBindingAsBufferView(binding));
-                                        GLuint buffer = ToBackend(view->GetBuffer())->GetHandle();
-                                        GLuint uboIndex = indices[binding];
-
-                                        glBindBufferRange(GL_UNIFORM_BUFFER, uboIndex, buffer, view->GetOffset(), view->GetSize());
-                                    }
-                                    break;
-
-                                case nxt::BindingType::Sampler:
-                                    {
-                                        GLuint sampler = ToBackend(group->GetBindingAsSampler(binding))->GetHandle();
-                                        GLuint samplerIndex = indices[binding];
-
-                                        for (auto unit : lastGLPipeline->GetTextureUnitsForSampler(samplerIndex)) {
-                                            glBindSampler(unit, sampler);
-                                        }
-                                    }
-                                    break;
-
-                                case nxt::BindingType::SampledTexture:
-                                    {
-                                        TextureView* view = ToBackend(group->GetBindingAsTextureView(binding));
-                                        Texture* texture = ToBackend(view->GetTexture());
-                                        GLuint handle = texture->GetHandle();
-                                        GLenum target = texture->GetGLTarget();
-                                        GLuint textureIndex = indices[binding];
-
-                                        for (auto unit : lastGLPipeline->GetTextureUnitsForTexture(textureIndex)) {
-                                            glActiveTexture(GL_TEXTURE0 + unit);
-                                            glBindTexture(target, handle);
-                                        }
-                                    }
-                                    break;
-
-                                case nxt::BindingType::StorageBuffer:
-                                    {
-                                        BufferView* view = ToBackend(group->GetBindingAsBufferView(binding));
-                                        GLuint buffer = ToBackend(view->GetBuffer())->GetHandle();
-                                        GLuint ssboIndex = indices[binding];
-
-                                        glBindBufferRange(GL_SHADER_STORAGE_BUFFER, ssboIndex, buffer, view->GetOffset(), view->GetSize());
-                                    }
-                                    break;
+                        // Only perform load op on first use
+                        if (attachmentInfo.firstSubpass == currentSubpass) {
+                            // Load op - color
+                            if (attachmentInfo.colorLoadOp == nxt::LoadOp::Clear) {
+                                const auto& clear = currentFramebuffer->GetClearColor(location);
+                                glClearBufferfv(GL_COLOR, location, clear.color);
                             }
                         }
                     }
-                    break;
 
-                case Command::SetIndexBuffer:
-                    {
-                        SetIndexBufferCmd* cmd = mCommands.NextCommand<SetIndexBufferCmd>();
-                        indexBufferOffset = cmd->offset;
-                        inputBuffers.OnSetIndexBuffer(cmd->buffer.Get());
+                    if (subpass.depthStencilAttachmentSet) {
+                        uint32_t attachmentSlot = subpass.depthStencilAttachment;
+                        const auto& attachmentInfo =
+                            currentRenderPass->GetAttachmentInfo(attachmentSlot);
+
+                        // Only perform load op on first use
+                        if (attachmentInfo.firstSubpass == currentSubpass) {
+                            // Load op - depth/stencil
+                            const auto& clear = currentFramebuffer->GetClearDepthStencil(
+                                subpass.depthStencilAttachment);
+                            bool doDepthClear = TextureFormatHasDepth(attachmentInfo.format) &&
+                                                (attachmentInfo.depthLoadOp == nxt::LoadOp::Clear);
+                            bool doStencilClear =
+                                TextureFormatHasStencil(attachmentInfo.format) &&
+                                (attachmentInfo.stencilLoadOp == nxt::LoadOp::Clear);
+                            if (doDepthClear && doStencilClear) {
+                                glClearBufferfi(GL_DEPTH_STENCIL, 0, clear.depth, clear.stencil);
+                            } else if (doDepthClear) {
+                                glClearBufferfv(GL_DEPTH, 0, &clear.depth);
+                            } else if (doStencilClear) {
+                                const GLint clearStencil = clear.stencil;
+                                glClearBufferiv(GL_STENCIL, 0, &clearStencil);
+                            }
+                        }
                     }
-                    break;
 
-                case Command::SetVertexBuffers:
-                    {
-                        SetVertexBuffersCmd* cmd = mCommands.NextCommand<SetVertexBuffersCmd>();
-                        auto buffers = mCommands.NextData<Ref<BufferBase>>(cmd->count);
-                        auto offsets = mCommands.NextData<uint32_t>(cmd->count);
-                        inputBuffers.OnSetVertexBuffers(cmd->startSlot, cmd->count, buffers, offsets);
+                    glBlendColor(0, 0, 0, 0);
+                    glViewport(0, 0, currentFramebuffer->GetWidth(),
+                               currentFramebuffer->GetHeight());
+                } break;
+
+                case Command::CopyBufferToBuffer: {
+                    CopyBufferToBufferCmd* copy = mCommands.NextCommand<CopyBufferToBufferCmd>();
+                    auto& src = copy->source;
+                    auto& dst = copy->destination;
+
+                    glBindBuffer(GL_PIXEL_PACK_BUFFER, ToBackend(src.buffer)->GetHandle());
+                    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, ToBackend(dst.buffer)->GetHandle());
+                    glCopyBufferSubData(GL_PIXEL_PACK_BUFFER, GL_PIXEL_UNPACK_BUFFER, src.offset,
+                                        dst.offset, copy->size);
+
+                    glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+                    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+                } break;
+
+                case Command::CopyBufferToTexture: {
+                    CopyBufferToTextureCmd* copy = mCommands.NextCommand<CopyBufferToTextureCmd>();
+                    auto& src = copy->source;
+                    auto& dst = copy->destination;
+                    Buffer* buffer = ToBackend(src.buffer.Get());
+                    Texture* texture = ToBackend(dst.texture.Get());
+                    GLenum target = texture->GetGLTarget();
+                    auto format = texture->GetGLFormat();
+
+                    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer->GetHandle());
+                    glActiveTexture(GL_TEXTURE0);
+                    glBindTexture(target, texture->GetHandle());
+
+                    ASSERT(texture->GetDimension() == nxt::TextureDimension::e2D);
+                    glPixelStorei(GL_UNPACK_ROW_LENGTH,
+                                  copy->rowPitch / TextureFormatPixelSize(texture->GetFormat()));
+                    glTexSubImage2D(target, dst.level, dst.x, dst.y, dst.width, dst.height,
+                                    format.format, format.type,
+                                    reinterpret_cast<void*>(static_cast<uintptr_t>(src.offset)));
+                    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+                    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+                } break;
+
+                case Command::CopyTextureToBuffer: {
+                    CopyTextureToBufferCmd* copy = mCommands.NextCommand<CopyTextureToBufferCmd>();
+                    auto& src = copy->source;
+                    auto& dst = copy->destination;
+                    Texture* texture = ToBackend(src.texture.Get());
+                    Buffer* buffer = ToBackend(dst.buffer.Get());
+                    auto format = texture->GetGLFormat();
+
+                    // The only way to move data from a texture to a buffer in GL is via
+                    // glReadPixels with a pack buffer. Create a temporary FBO for the copy.
+                    ASSERT(texture->GetDimension() == nxt::TextureDimension::e2D);
+                    glBindTexture(GL_TEXTURE_2D, texture->GetHandle());
+
+                    GLuint readFBO = 0;
+                    glGenFramebuffers(1, &readFBO);
+                    glBindFramebuffer(GL_READ_FRAMEBUFFER, readFBO);
+
+                    glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+                                           texture->GetHandle(), src.level);
+
+                    glBindBuffer(GL_PIXEL_PACK_BUFFER, buffer->GetHandle());
+                    glPixelStorei(GL_PACK_ROW_LENGTH,
+                                  copy->rowPitch / TextureFormatPixelSize(texture->GetFormat()));
+                    ASSERT(src.depth == 1 && src.z == 0);
+                    void* offset = reinterpret_cast<void*>(static_cast<uintptr_t>(dst.offset));
+                    glReadPixels(src.x, src.y, src.width, src.height, format.format, format.type,
+                                 offset);
+                    glPixelStorei(GL_PACK_ROW_LENGTH, 0);
+
+                    glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+                    glDeleteFramebuffers(1, &readFBO);
+                } break;
+
+                case Command::Dispatch: {
+                    DispatchCmd* dispatch = mCommands.NextCommand<DispatchCmd>();
+                    pushConstants.Apply(lastPipeline, lastGLPipeline);
+                    glDispatchCompute(dispatch->x, dispatch->y, dispatch->z);
+                    // TODO(cwallez@chromium.org): add barriers to the API
+                    glMemoryBarrier(GL_ALL_BARRIER_BITS);
+                } break;
+
+                case Command::DrawArrays: {
+                    DrawArraysCmd* draw = mCommands.NextCommand<DrawArraysCmd>();
+                    pushConstants.Apply(lastPipeline, lastGLPipeline);
+                    inputBuffers.Apply();
+
+                    if (draw->firstInstance > 0) {
+                        glDrawArraysInstancedBaseInstance(
+                            lastRenderPipeline->GetGLPrimitiveTopology(), draw->firstVertex,
+                            draw->vertexCount, draw->instanceCount, draw->firstInstance);
+                    } else {
+                        // This branch is only needed on OpenGL < 4.2
+                        glDrawArraysInstanced(lastRenderPipeline->GetGLPrimitiveTopology(),
+                                              draw->firstVertex, draw->vertexCount,
+                                              draw->instanceCount);
                     }
-                    break;
+                } break;
 
-                case Command::TransitionBufferUsage:
-                    {
-                        TransitionBufferUsageCmd* cmd = mCommands.NextCommand<TransitionBufferUsageCmd>();
+                case Command::DrawElements: {
+                    DrawElementsCmd* draw = mCommands.NextCommand<DrawElementsCmd>();
+                    pushConstants.Apply(lastPipeline, lastGLPipeline);
+                    inputBuffers.Apply();
 
-                        cmd->buffer->UpdateUsageInternal(cmd->usage);
+                    nxt::IndexFormat indexFormat = lastRenderPipeline->GetIndexFormat();
+                    size_t formatSize = IndexFormatSize(indexFormat);
+                    GLenum formatType = IndexFormatType(indexFormat);
+
+                    if (draw->firstInstance > 0) {
+                        glDrawElementsInstancedBaseInstance(
+                            lastRenderPipeline->GetGLPrimitiveTopology(), draw->indexCount,
+                            formatType,
+                            reinterpret_cast<void*>(draw->firstIndex * formatSize +
+                                                    indexBufferOffset),
+                            draw->instanceCount, draw->firstInstance);
+                    } else {
+                        // This branch is only needed on OpenGL < 4.2
+                        glDrawElementsInstanced(
+                            lastRenderPipeline->GetGLPrimitiveTopology(), draw->indexCount,
+                            formatType,
+                            reinterpret_cast<void*>(draw->firstIndex * formatSize +
+                                                    indexBufferOffset),
+                            draw->instanceCount);
                     }
-                    break;
+                } break;
 
-                case Command::TransitionTextureUsage:
-                    {
-                        TransitionTextureUsageCmd* cmd = mCommands.NextCommand<TransitionTextureUsageCmd>();
+                case Command::EndComputePass: {
+                    mCommands.NextCommand<EndComputePassCmd>();
+                } break;
 
-                        cmd->texture->UpdateUsageInternal(cmd->usage);
+                case Command::EndRenderPass: {
+                    mCommands.NextCommand<EndRenderPassCmd>();
+                } break;
+
+                case Command::EndRenderSubpass: {
+                    mCommands.NextCommand<EndRenderSubpassCmd>();
+                    glDeleteFramebuffers(1, &currentFBO);
+                    currentFBO = 0;
+                    currentSubpass += 1;
+                } break;
+
+                case Command::SetComputePipeline: {
+                    SetComputePipelineCmd* cmd = mCommands.NextCommand<SetComputePipelineCmd>();
+                    ToBackend(cmd->pipeline)->ApplyNow();
+                    lastGLPipeline = ToBackend(cmd->pipeline).Get();
+                    lastPipeline = ToBackend(cmd->pipeline).Get();
+                    pushConstants.OnSetPipeline(lastPipeline);
+                } break;
+
+                case Command::SetRenderPipeline: {
+                    SetRenderPipelineCmd* cmd = mCommands.NextCommand<SetRenderPipelineCmd>();
+                    ToBackend(cmd->pipeline)->ApplyNow(persistentPipelineState);
+                    lastRenderPipeline = ToBackend(cmd->pipeline).Get();
+                    lastGLPipeline = ToBackend(cmd->pipeline).Get();
+                    lastPipeline = ToBackend(cmd->pipeline).Get();
+
+                    pushConstants.OnSetPipeline(lastPipeline);
+                    inputBuffers.OnSetPipeline(lastRenderPipeline);
+                } break;
+
+                case Command::SetPushConstants: {
+                    SetPushConstantsCmd* cmd = mCommands.NextCommand<SetPushConstantsCmd>();
+                    uint32_t* data = mCommands.NextData<uint32_t>(cmd->count);
+                    pushConstants.OnSetPushConstants(cmd->stages, cmd->count, cmd->offset, data);
+                } break;
+
+                case Command::SetStencilReference: {
+                    SetStencilReferenceCmd* cmd = mCommands.NextCommand<SetStencilReferenceCmd>();
+                    persistentPipelineState.SetStencilReference(cmd->reference);
+                } break;
+
+                case Command::SetBlendColor: {
+                    SetBlendColorCmd* cmd = mCommands.NextCommand<SetBlendColorCmd>();
+                    glBlendColor(cmd->r, cmd->g, cmd->b, cmd->a);
+                } break;
+
+                case Command::SetBindGroup: {
+                    SetBindGroupCmd* cmd = mCommands.NextCommand<SetBindGroupCmd>();
+                    size_t groupIndex = cmd->index;
+                    BindGroup* group = ToBackend(cmd->group.Get());
+
+                    const auto& indices =
+                        ToBackend(lastPipeline->GetLayout())->GetBindingIndexInfo()[groupIndex];
+                    const auto& layout = group->GetLayout()->GetBindingInfo();
+
+                    for (uint32_t binding : IterateBitSet(layout.mask)) {
+                        switch (layout.types[binding]) {
+                            case nxt::BindingType::UniformBuffer: {
+                                BufferView* view =
+                                    ToBackend(group->GetBindingAsBufferView(binding));
+                                GLuint buffer = ToBackend(view->GetBuffer())->GetHandle();
+                                GLuint uboIndex = indices[binding];
+
+                                glBindBufferRange(GL_UNIFORM_BUFFER, uboIndex, buffer,
+                                                  view->GetOffset(), view->GetSize());
+                            } break;
+
+                            case nxt::BindingType::Sampler: {
+                                GLuint sampler =
+                                    ToBackend(group->GetBindingAsSampler(binding))->GetHandle();
+                                GLuint samplerIndex = indices[binding];
+
+                                for (auto unit :
+                                     lastGLPipeline->GetTextureUnitsForSampler(samplerIndex)) {
+                                    glBindSampler(unit, sampler);
+                                }
+                            } break;
+
+                            case nxt::BindingType::SampledTexture: {
+                                TextureView* view =
+                                    ToBackend(group->GetBindingAsTextureView(binding));
+                                Texture* texture = ToBackend(view->GetTexture());
+                                GLuint handle = texture->GetHandle();
+                                GLenum target = texture->GetGLTarget();
+                                GLuint textureIndex = indices[binding];
+
+                                for (auto unit :
+                                     lastGLPipeline->GetTextureUnitsForTexture(textureIndex)) {
+                                    glActiveTexture(GL_TEXTURE0 + unit);
+                                    glBindTexture(target, handle);
+                                }
+                            } break;
+
+                            case nxt::BindingType::StorageBuffer: {
+                                BufferView* view =
+                                    ToBackend(group->GetBindingAsBufferView(binding));
+                                GLuint buffer = ToBackend(view->GetBuffer())->GetHandle();
+                                GLuint ssboIndex = indices[binding];
+
+                                glBindBufferRange(GL_SHADER_STORAGE_BUFFER, ssboIndex, buffer,
+                                                  view->GetOffset(), view->GetSize());
+                            } break;
+                        }
                     }
-                    break;
+                } break;
+
+                case Command::SetIndexBuffer: {
+                    SetIndexBufferCmd* cmd = mCommands.NextCommand<SetIndexBufferCmd>();
+                    indexBufferOffset = cmd->offset;
+                    inputBuffers.OnSetIndexBuffer(cmd->buffer.Get());
+                } break;
+
+                case Command::SetVertexBuffers: {
+                    SetVertexBuffersCmd* cmd = mCommands.NextCommand<SetVertexBuffersCmd>();
+                    auto buffers = mCommands.NextData<Ref<BufferBase>>(cmd->count);
+                    auto offsets = mCommands.NextData<uint32_t>(cmd->count);
+                    inputBuffers.OnSetVertexBuffers(cmd->startSlot, cmd->count, buffers, offsets);
+                } break;
+
+                case Command::TransitionBufferUsage: {
+                    TransitionBufferUsageCmd* cmd =
+                        mCommands.NextCommand<TransitionBufferUsageCmd>();
+
+                    cmd->buffer->UpdateUsageInternal(cmd->usage);
+                } break;
+
+                case Command::TransitionTextureUsage: {
+                    TransitionTextureUsageCmd* cmd =
+                        mCommands.NextCommand<TransitionTextureUsageCmd>();
+
+                    cmd->texture->UpdateUsageInternal(cmd->usage);
+                } break;
             }
         }
 
@@ -652,5 +638,4 @@
         glBindSampler(0, 0);
     }
 
-}
-}
+}}  // namespace backend::opengl
diff --git a/src/backend/opengl/CommandBufferGL.h b/src/backend/opengl/CommandBufferGL.h
index dcbe06f..b87ffb1 100644
--- a/src/backend/opengl/CommandBufferGL.h
+++ b/src/backend/opengl/CommandBufferGL.h
@@ -18,23 +18,21 @@
 #include "backend/CommandAllocator.h"
 #include "backend/CommandBuffer.h"
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
     class Device;
 
     class CommandBuffer : public CommandBufferBase {
-        public:
-            CommandBuffer(CommandBufferBuilder* builder);
-            ~CommandBuffer();
+      public:
+        CommandBuffer(CommandBufferBuilder* builder);
+        ~CommandBuffer();
 
-            void Execute();
+        void Execute();
 
-        private:
-            CommandIterator mCommands;
+      private:
+        CommandIterator mCommands;
     };
 
-}
-}
+}}  // namespace backend::opengl
 
-#endif // BACKEND_OPENGL_COMMANDBUFFERGL_H_
+#endif  // BACKEND_OPENGL_COMMANDBUFFERGL_H_
diff --git a/src/backend/opengl/ComputePipelineGL.cpp b/src/backend/opengl/ComputePipelineGL.cpp
index d2fd8ad..e4638b3 100644
--- a/src/backend/opengl/ComputePipelineGL.cpp
+++ b/src/backend/opengl/ComputePipelineGL.cpp
@@ -14,8 +14,7 @@
 
 #include "backend/opengl/ComputePipelineGL.h"
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
     ComputePipeline::ComputePipeline(ComputePipelineBuilder* builder)
         : ComputePipelineBase(builder), PipelineGL(this, builder) {
@@ -25,5 +24,4 @@
         PipelineGL::ApplyNow();
     }
 
-}
-}
+}}  // namespace backend::opengl
diff --git a/src/backend/opengl/ComputePipelineGL.h b/src/backend/opengl/ComputePipelineGL.h
index c0678c3..764e1ae 100644
--- a/src/backend/opengl/ComputePipelineGL.h
+++ b/src/backend/opengl/ComputePipelineGL.h
@@ -21,17 +21,15 @@
 
 #include "glad/glad.h"
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
     class ComputePipeline : public ComputePipelineBase, public PipelineGL {
-        public:
-            ComputePipeline(ComputePipelineBuilder* builder);
+      public:
+        ComputePipeline(ComputePipelineBuilder* builder);
 
-            void ApplyNow();
+        void ApplyNow();
     };
 
-}
-}
+}}  // namespace backend::opengl
 
-#endif // BACKEND_OPENGL_COMPUTEPIPELINEGL_H_
+#endif  // BACKEND_OPENGL_COMPUTEPIPELINEGL_H_
diff --git a/src/backend/opengl/DepthStencilStateGL.cpp b/src/backend/opengl/DepthStencilStateGL.cpp
index 1397670..0df1cf0 100644
--- a/src/backend/opengl/DepthStencilStateGL.cpp
+++ b/src/backend/opengl/DepthStencilStateGL.cpp
@@ -18,8 +18,7 @@
 #include "backend/opengl/PersistentPipelineStateGL.h"
 #include "common/Assert.h"
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
     namespace {
         GLuint OpenGLCompareFunction(nxt::CompareFunction compareFunction) {
@@ -67,17 +66,18 @@
                     UNREACHABLE();
             }
         }
-    }
+    }  // namespace
 
     DepthStencilState::DepthStencilState(DepthStencilStateBuilder* builder)
         : DepthStencilStateBase(builder) {
     }
 
-    void DepthStencilState::ApplyNow(PersistentPipelineState &persistentPipelineState) const {
+    void DepthStencilState::ApplyNow(PersistentPipelineState& persistentPipelineState) const {
         auto& depthInfo = GetDepth();
 
         // Depth writes only occur if depth is enabled
-        if (depthInfo.compareFunction == nxt::CompareFunction::Always && !depthInfo.depthWriteEnabled) {
+        if (depthInfo.compareFunction == nxt::CompareFunction::Always &&
+            !depthInfo.depthWriteEnabled) {
             glDisable(GL_DEPTH_TEST);
         } else {
             glEnable(GL_DEPTH_TEST);
@@ -101,22 +101,17 @@
 
         GLenum backCompareFunction = OpenGLCompareFunction(stencilInfo.back.compareFunction);
         GLenum frontCompareFunction = OpenGLCompareFunction(stencilInfo.front.compareFunction);
-        persistentPipelineState.SetStencilFuncsAndMask(backCompareFunction, frontCompareFunction, stencilInfo.readMask);
+        persistentPipelineState.SetStencilFuncsAndMask(backCompareFunction, frontCompareFunction,
+                                                       stencilInfo.readMask);
 
-        glStencilOpSeparate(GL_BACK,
-            OpenGLStencilOperation(stencilInfo.back.stencilFail),
-            OpenGLStencilOperation(stencilInfo.back.depthFail),
-            OpenGLStencilOperation(stencilInfo.back.depthStencilPass)
-        );
-        glStencilOpSeparate(GL_FRONT,
-            OpenGLStencilOperation(stencilInfo.front.stencilFail),
-            OpenGLStencilOperation(stencilInfo.front.depthFail),
-            OpenGLStencilOperation(stencilInfo.front.depthStencilPass)
-        );
+        glStencilOpSeparate(GL_BACK, OpenGLStencilOperation(stencilInfo.back.stencilFail),
+                            OpenGLStencilOperation(stencilInfo.back.depthFail),
+                            OpenGLStencilOperation(stencilInfo.back.depthStencilPass));
+        glStencilOpSeparate(GL_FRONT, OpenGLStencilOperation(stencilInfo.front.stencilFail),
+                            OpenGLStencilOperation(stencilInfo.front.depthFail),
+                            OpenGLStencilOperation(stencilInfo.front.depthStencilPass));
 
         glStencilMask(stencilInfo.writeMask);
-
     }
 
-}
-}
+}}  // namespace backend::opengl
diff --git a/src/backend/opengl/DepthStencilStateGL.h b/src/backend/opengl/DepthStencilStateGL.h
index 5c5d781..5f920aa 100644
--- a/src/backend/opengl/DepthStencilStateGL.h
+++ b/src/backend/opengl/DepthStencilStateGL.h
@@ -17,20 +17,18 @@
 
 #include "backend/DepthStencilState.h"
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
     class Device;
     class PersistentPipelineState;
 
     class DepthStencilState : public DepthStencilStateBase {
-        public:
-            DepthStencilState(DepthStencilStateBuilder* builder);
+      public:
+        DepthStencilState(DepthStencilStateBuilder* builder);
 
-            void ApplyNow(PersistentPipelineState &persistentPipelineState) const;
+        void ApplyNow(PersistentPipelineState& persistentPipelineState) const;
     };
 
-}
-}
+}}  // namespace backend::opengl
 
-#endif // BACKEND_OPENGL_DEPTHSTENCILSTATEGL_H_
+#endif  // BACKEND_OPENGL_DEPTHSTENCILSTATEGL_H_
diff --git a/src/backend/opengl/GeneratedCodeIncludes.h b/src/backend/opengl/GeneratedCodeIncludes.h
index a57f833..b47f055 100644
--- a/src/backend/opengl/GeneratedCodeIncludes.h
+++ b/src/backend/opengl/GeneratedCodeIncludes.h
@@ -12,13 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "backend/opengl/OpenGLBackend.h"
 #include "backend/opengl/BlendStateGL.h"
 #include "backend/opengl/BufferGL.h"
 #include "backend/opengl/CommandBufferGL.h"
 #include "backend/opengl/ComputePipelineGL.h"
 #include "backend/opengl/DepthStencilStateGL.h"
 #include "backend/opengl/InputStateGL.h"
+#include "backend/opengl/OpenGLBackend.h"
 #include "backend/opengl/PersistentPipelineStateGL.h"
 #include "backend/opengl/PipelineLayoutGL.h"
 #include "backend/opengl/RenderPipelineGL.h"
diff --git a/src/backend/opengl/InputStateGL.cpp b/src/backend/opengl/InputStateGL.cpp
index 957d1d0..8bb04e5 100644
--- a/src/backend/opengl/InputStateGL.cpp
+++ b/src/backend/opengl/InputStateGL.cpp
@@ -17,11 +17,9 @@
 #include "backend/opengl/OpenGLBackend.h"
 #include "common/Assert.h"
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
-    InputState::InputState(InputStateBuilder* builder)
-        : InputStateBase(builder) {
+    InputState::InputState(InputStateBuilder* builder) : InputStateBase(builder) {
         glGenVertexArrays(1, &mVertexArrayObject);
         glBindVertexArray(mVertexArrayObject);
         auto& attributesSetMask = GetAttributesSetMask();
@@ -61,5 +59,4 @@
         return mVertexArrayObject;
     }
 
-}
-}
+}}  // namespace backend::opengl
diff --git a/src/backend/opengl/InputStateGL.h b/src/backend/opengl/InputStateGL.h
index e3401ad..2c0446e 100644
--- a/src/backend/opengl/InputStateGL.h
+++ b/src/backend/opengl/InputStateGL.h
@@ -19,24 +19,22 @@
 
 #include "glad/glad.h"
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
     class Device;
 
     class InputState : public InputStateBase {
-        public:
-            InputState(InputStateBuilder* builder);
+      public:
+        InputState(InputStateBuilder* builder);
 
-            std::bitset<kMaxVertexAttributes> GetAttributesUsingInput(uint32_t slot) const;
-            GLuint GetVAO();
+        std::bitset<kMaxVertexAttributes> GetAttributesUsingInput(uint32_t slot) const;
+        GLuint GetVAO();
 
-        private:
-            GLuint mVertexArrayObject;
-            std::array<std::bitset<kMaxVertexAttributes>, kMaxVertexInputs> attributesUsingInput;
+      private:
+        GLuint mVertexArrayObject;
+        std::array<std::bitset<kMaxVertexAttributes>, kMaxVertexInputs> attributesUsingInput;
     };
 
-}
-}
+}}  // namespace backend::opengl
 
-#endif // BACKEND_OPENGL_INPUTSTATEGL_H_
+#endif  // BACKEND_OPENGL_INPUTSTATEGL_H_
diff --git a/src/backend/opengl/OpenGLBackend.cpp b/src/backend/opengl/OpenGLBackend.cpp
index 96e6866..79ec008 100644
--- a/src/backend/opengl/OpenGLBackend.cpp
+++ b/src/backend/opengl/OpenGLBackend.cpp
@@ -22,13 +22,12 @@
 #include "backend/opengl/InputStateGL.h"
 #include "backend/opengl/PipelineLayoutGL.h"
 #include "backend/opengl/RenderPipelineGL.h"
+#include "backend/opengl/SamplerGL.h"
 #include "backend/opengl/ShaderModuleGL.h"
 #include "backend/opengl/SwapChainGL.h"
-#include "backend/opengl/SamplerGL.h"
 #include "backend/opengl/TextureGL.h"
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
     nxtProcTable GetNonValidatingProcs();
     nxtProcTable GetValidatingProcs();
 
@@ -109,8 +108,7 @@
 
     // Bind Group
 
-    BindGroup::BindGroup(BindGroupBuilder* builder)
-        : BindGroupBase(builder) {
+    BindGroup::BindGroup(BindGroupBuilder* builder) : BindGroupBase(builder) {
     }
 
     // Bind Group Layout
@@ -121,17 +119,15 @@
 
     // Framebuffer
 
-    Framebuffer::Framebuffer(FramebufferBuilder* builder)
-        : FramebufferBase(builder) {
+    Framebuffer::Framebuffer(FramebufferBuilder* builder) : FramebufferBase(builder) {
     }
 
     // Queue
 
-    Queue::Queue(QueueBuilder* builder)
-        : QueueBase(builder) {
+    Queue::Queue(QueueBuilder* builder) : QueueBase(builder) {
     }
 
-    void Queue::Submit(uint32_t numCommands, CommandBuffer* const * commands) {
+    void Queue::Submit(uint32_t numCommands, CommandBuffer* const* commands) {
         for (uint32_t i = 0; i < numCommands; ++i) {
             commands[i]->Execute();
         }
@@ -139,9 +135,7 @@
 
     // RenderPass
 
-    RenderPass::RenderPass(RenderPassBuilder* builder)
-        : RenderPassBase(builder) {
+    RenderPass::RenderPass(RenderPassBuilder* builder) : RenderPassBase(builder) {
     }
 
-}
-}
+}}  // namespace backend::opengl
diff --git a/src/backend/opengl/OpenGLBackend.h b/src/backend/opengl/OpenGLBackend.h
index a4449e1..5a9be0e 100644
--- a/src/backend/opengl/OpenGLBackend.h
+++ b/src/backend/opengl/OpenGLBackend.h
@@ -17,12 +17,12 @@
 
 #include "nxt/nxtcpp.h"
 
-#include "backend/Buffer.h"
-#include "backend/BlendState.h"
 #include "backend/BindGroup.h"
 #include "backend/BindGroupLayout.h"
-#include "backend/Device.h"
+#include "backend/BlendState.h"
+#include "backend/Buffer.h"
 #include "backend/DepthStencilState.h"
+#include "backend/Device.h"
 #include "backend/Framebuffer.h"
 #include "backend/InputState.h"
 #include "backend/Queue.h"
@@ -31,8 +31,7 @@
 
 #include "glad/glad.h"
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
     class BindGroup;
     class BindGroupLayout;
@@ -79,66 +78,65 @@
         using TextureViewType = TextureView;
     };
 
-    template<typename T>
+    template <typename T>
     auto ToBackend(T&& common) -> decltype(ToBackendBase<OpenGLBackendTraits>(common)) {
         return ToBackendBase<OpenGLBackendTraits>(common);
     }
 
     // Definition of backend types
     class Device : public DeviceBase {
-        public:
-            BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) override;
-            BindGroupLayoutBase* CreateBindGroupLayout(BindGroupLayoutBuilder* builder) override;
-            BlendStateBase* CreateBlendState(BlendStateBuilder* builder) override;
-            BufferBase* CreateBuffer(BufferBuilder* builder) override;
-            BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
-            CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
-            ComputePipelineBase* CreateComputePipeline(ComputePipelineBuilder* builder) override;
-            DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
-            InputStateBase* CreateInputState(InputStateBuilder* builder) override;
-            FramebufferBase* CreateFramebuffer(FramebufferBuilder* builder) override;
-            PipelineLayoutBase* CreatePipelineLayout(PipelineLayoutBuilder* builder) override;
-            QueueBase* CreateQueue(QueueBuilder* builder) override;
-            RenderPassBase* CreateRenderPass(RenderPassBuilder* builder) override;
-            RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
-            SamplerBase* CreateSampler(SamplerBuilder* builder) override;
-            ShaderModuleBase* CreateShaderModule(ShaderModuleBuilder* builder) override;
-            SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
-            TextureBase* CreateTexture(TextureBuilder* builder) override;
-            TextureViewBase* CreateTextureView(TextureViewBuilder* builder) override;
+      public:
+        BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) override;
+        BindGroupLayoutBase* CreateBindGroupLayout(BindGroupLayoutBuilder* builder) override;
+        BlendStateBase* CreateBlendState(BlendStateBuilder* builder) override;
+        BufferBase* CreateBuffer(BufferBuilder* builder) override;
+        BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
+        CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
+        ComputePipelineBase* CreateComputePipeline(ComputePipelineBuilder* builder) override;
+        DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
+        InputStateBase* CreateInputState(InputStateBuilder* builder) override;
+        FramebufferBase* CreateFramebuffer(FramebufferBuilder* builder) override;
+        PipelineLayoutBase* CreatePipelineLayout(PipelineLayoutBuilder* builder) override;
+        QueueBase* CreateQueue(QueueBuilder* builder) override;
+        RenderPassBase* CreateRenderPass(RenderPassBuilder* builder) override;
+        RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
+        SamplerBase* CreateSampler(SamplerBuilder* builder) override;
+        ShaderModuleBase* CreateShaderModule(ShaderModuleBuilder* builder) override;
+        SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
+        TextureBase* CreateTexture(TextureBuilder* builder) override;
+        TextureViewBase* CreateTextureView(TextureViewBuilder* builder) override;
 
-            void TickImpl() override;
+        void TickImpl() override;
     };
 
     class BindGroup : public BindGroupBase {
-        public:
-            BindGroup(BindGroupBuilder* builder);
+      public:
+        BindGroup(BindGroupBuilder* builder);
     };
 
     class BindGroupLayout : public BindGroupLayoutBase {
-        public:
-            BindGroupLayout(BindGroupLayoutBuilder* builder);
+      public:
+        BindGroupLayout(BindGroupLayoutBuilder* builder);
     };
 
     class Framebuffer : public FramebufferBase {
-        public:
-            Framebuffer(FramebufferBuilder* builder);
+      public:
+        Framebuffer(FramebufferBuilder* builder);
     };
 
     class Queue : public QueueBase {
-        public:
-            Queue(QueueBuilder* builder);
+      public:
+        Queue(QueueBuilder* builder);
 
-            // NXT API
-            void Submit(uint32_t numCommands, CommandBuffer* const * commands);
+        // NXT API
+        void Submit(uint32_t numCommands, CommandBuffer* const* commands);
     };
 
     class RenderPass : public RenderPassBase {
-        public:
-            RenderPass(RenderPassBuilder* builder);
+      public:
+        RenderPass(RenderPassBuilder* builder);
     };
 
-}
-}
+}}  // namespace backend::opengl
 
-#endif // BACKEND_OPENGL_OPENGLBACKEND_H_
+#endif  // BACKEND_OPENGL_OPENGLBACKEND_H_
diff --git a/src/backend/opengl/PersistentPipelineStateGL.cpp b/src/backend/opengl/PersistentPipelineStateGL.cpp
index bec9bfa..7f0f54c 100644
--- a/src/backend/opengl/PersistentPipelineStateGL.cpp
+++ b/src/backend/opengl/PersistentPipelineStateGL.cpp
@@ -16,14 +16,15 @@
 
 #include "backend/opengl/OpenGLBackend.h"
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
     void PersistentPipelineState::SetDefaultState() {
         CallGLStencilFunc();
     }
 
-    void PersistentPipelineState::SetStencilFuncsAndMask(GLenum stencilBackCompareFunction, GLenum stencilFrontCompareFunction, uint32_t stencilReadMask) {
+    void PersistentPipelineState::SetStencilFuncsAndMask(GLenum stencilBackCompareFunction,
+                                                         GLenum stencilFrontCompareFunction,
+                                                         uint32_t stencilReadMask) {
         if (mStencilBackCompareFunction == stencilBackCompareFunction &&
             mStencilFrontCompareFunction == stencilFrontCompareFunction &&
             mStencilReadMask == stencilReadMask) {
@@ -46,15 +47,10 @@
     }
 
     void PersistentPipelineState::CallGLStencilFunc() {
-        glStencilFuncSeparate(GL_BACK,
-                mStencilBackCompareFunction,
-                mStencilReference,
-                mStencilReadMask);
-        glStencilFuncSeparate(GL_FRONT,
-                mStencilFrontCompareFunction,
-                mStencilReference,
-                mStencilReadMask);
+        glStencilFuncSeparate(GL_BACK, mStencilBackCompareFunction, mStencilReference,
+                              mStencilReadMask);
+        glStencilFuncSeparate(GL_FRONT, mStencilFrontCompareFunction, mStencilReference,
+                              mStencilReadMask);
     }
 
-}
-}
+}}  // namespace backend::opengl
diff --git a/src/backend/opengl/PersistentPipelineStateGL.h b/src/backend/opengl/PersistentPipelineStateGL.h
index ef6eddf..a084a42 100644
--- a/src/backend/opengl/PersistentPipelineStateGL.h
+++ b/src/backend/opengl/PersistentPipelineStateGL.h
@@ -19,25 +19,25 @@
 
 #include "glad/glad.h"
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
     class PersistentPipelineState {
-        public:
-            void SetDefaultState();
-            void SetStencilFuncsAndMask(GLenum stencilBackCompareFunction, GLenum stencilFrontCompareFunction, uint32_t stencilReadMask);
-            void SetStencilReference(uint32_t stencilReference);
+      public:
+        void SetDefaultState();
+        void SetStencilFuncsAndMask(GLenum stencilBackCompareFunction,
+                                    GLenum stencilFrontCompareFunction,
+                                    uint32_t stencilReadMask);
+        void SetStencilReference(uint32_t stencilReference);
 
-        private:
-            void CallGLStencilFunc();
+      private:
+        void CallGLStencilFunc();
 
-            GLenum mStencilBackCompareFunction = GL_ALWAYS;
-            GLenum mStencilFrontCompareFunction = GL_ALWAYS;
-            GLuint mStencilReadMask = 0xffffffff;
-            GLuint mStencilReference = 0;
+        GLenum mStencilBackCompareFunction = GL_ALWAYS;
+        GLenum mStencilFrontCompareFunction = GL_ALWAYS;
+        GLuint mStencilReadMask = 0xffffffff;
+        GLuint mStencilReference = 0;
     };
 
-}
-}
+}}  // namespace backend::opengl
 
-#endif // BACKEND_OPENGL_PERSISTENTPIPELINESTATE_H_
+#endif  // BACKEND_OPENGL_PERSISTENTPIPELINESTATE_H_
diff --git a/src/backend/opengl/PipelineGL.cpp b/src/backend/opengl/PipelineGL.cpp
index 26e06a6..b33875e 100644
--- a/src/backend/opengl/PipelineGL.cpp
+++ b/src/backend/opengl/PipelineGL.cpp
@@ -22,8 +22,7 @@
 #include <iostream>
 #include <set>
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
     namespace {
 
@@ -40,7 +39,7 @@
             }
         }
 
-    }
+    }  // namespace
 
     PipelineGL::PipelineGL(PipelineBase* parent, PipelineBuilder* builder) {
         auto CreateShader = [](GLenum type, const char* source) -> GLuint {
@@ -65,7 +64,8 @@
             return shader;
         };
 
-        auto FillPushConstants = [](const ShaderModule* module, GLPushConstantInfo* info, GLuint program) {
+        auto FillPushConstants = [](const ShaderModule* module, GLPushConstantInfo* info,
+                                    GLuint program) {
             const auto& moduleInfo = module->GetPushConstants();
             for (uint32_t i = 0; i < moduleInfo.names.size(); i++) {
                 (*info)[i] = -1;
@@ -119,7 +119,8 @@
 
         glUseProgram(mProgram);
 
-        // The uniforms are part of the program state so we can pre-bind buffer units, texture units etc.
+        // The uniforms are part of the program state so we can pre-bind buffer units, texture units
+        // etc.
         const auto& layout = ToBackend(parent->GetLayout());
         const auto& indices = layout->GetBindingIndexInfo();
 
@@ -133,25 +134,22 @@
 
                 std::string name = GetBindingName(group, binding);
                 switch (groupInfo.types[binding]) {
-                    case nxt::BindingType::UniformBuffer:
-                        {
-                            GLint location = glGetUniformBlockIndex(mProgram, name.c_str());
-                            glUniformBlockBinding(mProgram, location, indices[group][binding]);
-                        }
-                        break;
+                    case nxt::BindingType::UniformBuffer: {
+                        GLint location = glGetUniformBlockIndex(mProgram, name.c_str());
+                        glUniformBlockBinding(mProgram, location, indices[group][binding]);
+                    } break;
 
-                    case nxt::BindingType::StorageBuffer:
-                        {
-                            GLuint location = glGetProgramResourceIndex(mProgram, GL_SHADER_STORAGE_BLOCK, name.c_str());
-                            glShaderStorageBlockBinding(mProgram, location, indices[group][binding]);
-                        }
-                        break;
+                    case nxt::BindingType::StorageBuffer: {
+                        GLuint location = glGetProgramResourceIndex(
+                            mProgram, GL_SHADER_STORAGE_BLOCK, name.c_str());
+                        glShaderStorageBlockBinding(mProgram, location, indices[group][binding]);
+                    } break;
 
                     case nxt::BindingType::Sampler:
                     case nxt::BindingType::SampledTexture:
-                        // These binding types are handled in the separate sampler and texture emulation
+                        // These binding types are handled in the separate sampler and texture
+                        // emulation
                         break;
-
                 }
             }
         }
@@ -176,18 +174,21 @@
                 GLint location = glGetUniformLocation(mProgram, name.c_str());
                 glUniform1i(location, textureUnit);
 
-                GLuint samplerIndex = indices[combined.samplerLocation.group][combined.samplerLocation.binding];
+                GLuint samplerIndex =
+                    indices[combined.samplerLocation.group][combined.samplerLocation.binding];
                 mUnitsForSamplers[samplerIndex].push_back(textureUnit);
 
-                GLuint textureIndex = indices[combined.textureLocation.group][combined.textureLocation.binding];
+                GLuint textureIndex =
+                    indices[combined.textureLocation.group][combined.textureLocation.binding];
                 mUnitsForTextures[textureIndex].push_back(textureUnit);
 
-                textureUnit ++;
+                textureUnit++;
             }
         }
     }
 
-    const PipelineGL::GLPushConstantInfo& PipelineGL::GetGLPushConstants(nxt::ShaderStage stage) const {
+    const PipelineGL::GLPushConstantInfo& PipelineGL::GetGLPushConstants(
+        nxt::ShaderStage stage) const {
         return mGlPushConstants[stage];
     }
 
@@ -209,5 +210,4 @@
         glUseProgram(mProgram);
     }
 
-}
-}
+}}  // namespace backend::opengl
diff --git a/src/backend/opengl/PipelineGL.h b/src/backend/opengl/PipelineGL.h
index 1f1d09b..d9c3ac3 100644
--- a/src/backend/opengl/PipelineGL.h
+++ b/src/backend/opengl/PipelineGL.h
@@ -21,35 +21,34 @@
 
 #include <vector>
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
     class Device;
     class PersistentPipelineState;
     class ShaderModule;
 
     class PipelineGL {
-        public:
-            PipelineGL(PipelineBase* parent, PipelineBuilder* builder);
+      public:
+        PipelineGL(PipelineBase* parent, PipelineBuilder* builder);
 
-            using GLPushConstantInfo = std::array<GLint, kMaxPushConstants>;
-            using BindingLocations = std::array<std::array<GLint, kMaxBindingsPerGroup>, kMaxBindGroups>;
+        using GLPushConstantInfo = std::array<GLint, kMaxPushConstants>;
+        using BindingLocations =
+            std::array<std::array<GLint, kMaxBindingsPerGroup>, kMaxBindGroups>;
 
-            const GLPushConstantInfo& GetGLPushConstants(nxt::ShaderStage stage) const;
-            const std::vector<GLuint>& GetTextureUnitsForSampler(GLuint index) const;
-            const std::vector<GLuint>& GetTextureUnitsForTexture(GLuint index) const;
-            GLuint GetProgramHandle() const;
+        const GLPushConstantInfo& GetGLPushConstants(nxt::ShaderStage stage) const;
+        const std::vector<GLuint>& GetTextureUnitsForSampler(GLuint index) const;
+        const std::vector<GLuint>& GetTextureUnitsForTexture(GLuint index) const;
+        GLuint GetProgramHandle() const;
 
-            void ApplyNow();
+        void ApplyNow();
 
-        private:
-            GLuint mProgram;
-            PerStage<GLPushConstantInfo> mGlPushConstants;
-            std::vector<std::vector<GLuint>> mUnitsForSamplers;
-            std::vector<std::vector<GLuint>> mUnitsForTextures;
+      private:
+        GLuint mProgram;
+        PerStage<GLPushConstantInfo> mGlPushConstants;
+        std::vector<std::vector<GLuint>> mUnitsForSamplers;
+        std::vector<std::vector<GLuint>> mUnitsForTextures;
     };
 
-}
-}
+}}  // namespace backend::opengl
 
-#endif // BACKEND_OPENGL_PIPELINEGL_H_
+#endif  // BACKEND_OPENGL_PIPELINEGL_H_
diff --git a/src/backend/opengl/PipelineLayoutGL.cpp b/src/backend/opengl/PipelineLayoutGL.cpp
index 7a2acd1..c9c0b56 100644
--- a/src/backend/opengl/PipelineLayoutGL.cpp
+++ b/src/backend/opengl/PipelineLayoutGL.cpp
@@ -16,11 +16,9 @@
 
 #include "backend/opengl/OpenGLBackend.h"
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
-    PipelineLayout::PipelineLayout(PipelineLayoutBuilder* builder)
-        : PipelineLayoutBase(builder) {
+    PipelineLayout::PipelineLayout(PipelineLayoutBuilder* builder) : PipelineLayoutBase(builder) {
         GLuint uboIndex = 0;
         GLuint samplerIndex = 0;
         GLuint sampledTextureIndex = 0;
@@ -37,20 +35,20 @@
                 switch (groupInfo.types[binding]) {
                     case nxt::BindingType::UniformBuffer:
                         mIndexInfo[group][binding] = uboIndex;
-                        uboIndex ++;
+                        uboIndex++;
                         break;
                     case nxt::BindingType::Sampler:
                         mIndexInfo[group][binding] = samplerIndex;
-                        samplerIndex ++;
+                        samplerIndex++;
                         break;
                     case nxt::BindingType::SampledTexture:
                         mIndexInfo[group][binding] = sampledTextureIndex;
-                        sampledTextureIndex ++;
+                        sampledTextureIndex++;
                         break;
 
                     case nxt::BindingType::StorageBuffer:
                         mIndexInfo[group][binding] = ssboIndex;
-                        ssboIndex ++;
+                        ssboIndex++;
                         break;
                 }
             }
@@ -76,5 +74,4 @@
         return mNumSampledTextures;
     }
 
-}
-}
+}}  // namespace backend::opengl
diff --git a/src/backend/opengl/PipelineLayoutGL.h b/src/backend/opengl/PipelineLayoutGL.h
index 2fdea35..3c60787 100644
--- a/src/backend/opengl/PipelineLayoutGL.h
+++ b/src/backend/opengl/PipelineLayoutGL.h
@@ -19,29 +19,28 @@
 
 #include "glad/glad.h"
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
     class Device;
 
     class PipelineLayout : public PipelineLayoutBase {
-        public:
-            PipelineLayout(PipelineLayoutBuilder* builder);
+      public:
+        PipelineLayout(PipelineLayoutBuilder* builder);
 
-            using BindingIndexInfo = std::array<std::array<GLuint, kMaxBindingsPerGroup>, kMaxBindGroups>;
-            const BindingIndexInfo& GetBindingIndexInfo() const;
+        using BindingIndexInfo =
+            std::array<std::array<GLuint, kMaxBindingsPerGroup>, kMaxBindGroups>;
+        const BindingIndexInfo& GetBindingIndexInfo() const;
 
-            GLuint GetTextureUnitsUsed() const;
-            size_t GetNumSamplers() const;
-            size_t GetNumSampledTextures() const;
+        GLuint GetTextureUnitsUsed() const;
+        size_t GetNumSamplers() const;
+        size_t GetNumSampledTextures() const;
 
-        private:
-            BindingIndexInfo mIndexInfo;
-            size_t mNumSamplers;
-            size_t mNumSampledTextures;
+      private:
+        BindingIndexInfo mIndexInfo;
+        size_t mNumSamplers;
+        size_t mNumSampledTextures;
     };
 
-}
-}
+}}  // namespace backend::opengl
 
-#endif // BACKEND_OPENGL_PIPELINELAYOUTGL_H_
+#endif  // BACKEND_OPENGL_PIPELINELAYOUTGL_H_
diff --git a/src/backend/opengl/RenderPipelineGL.cpp b/src/backend/opengl/RenderPipelineGL.cpp
index 7684f76..5804d49 100644
--- a/src/backend/opengl/RenderPipelineGL.cpp
+++ b/src/backend/opengl/RenderPipelineGL.cpp
@@ -20,8 +20,7 @@
 #include "backend/opengl/OpenGLBackend.h"
 #include "backend/opengl/PersistentPipelineStateGL.h"
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
     namespace {
         GLenum GLPrimitiveTopology(nxt::PrimitiveTopology primitiveTopology) {
@@ -40,10 +39,11 @@
                     UNREACHABLE();
             }
         }
-    }
+    }  // namespace
 
     RenderPipeline::RenderPipeline(RenderPipelineBuilder* builder)
-        : RenderPipelineBase(builder), PipelineGL(this, builder),
+        : RenderPipelineBase(builder),
+          PipelineGL(this, builder),
           mGlPrimitiveTopology(GLPrimitiveTopology(GetPrimitiveTopology())) {
     }
 
@@ -51,7 +51,7 @@
         return mGlPrimitiveTopology;
     }
 
-    void RenderPipeline::ApplyNow(PersistentPipelineState &persistentPipelineState) {
+    void RenderPipeline::ApplyNow(PersistentPipelineState& persistentPipelineState) {
         PipelineGL::ApplyNow();
 
         auto inputState = ToBackend(GetInputState());
@@ -68,5 +68,4 @@
         }
     }
 
-}
-}
+}}  // namespace backend::opengl
diff --git a/src/backend/opengl/RenderPipelineGL.h b/src/backend/opengl/RenderPipelineGL.h
index a45f06d..542092c 100644
--- a/src/backend/opengl/RenderPipelineGL.h
+++ b/src/backend/opengl/RenderPipelineGL.h
@@ -23,24 +23,22 @@
 
 #include <vector>
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
     class PersistentPipelineState;
 
     class RenderPipeline : public RenderPipelineBase, public PipelineGL {
-        public:
-            RenderPipeline(RenderPipelineBuilder* builder);
+      public:
+        RenderPipeline(RenderPipelineBuilder* builder);
 
-            GLenum GetGLPrimitiveTopology() const;
+        GLenum GetGLPrimitiveTopology() const;
 
-            void ApplyNow(PersistentPipelineState &persistentPipelineState);
+        void ApplyNow(PersistentPipelineState& persistentPipelineState);
 
-        private:
-            GLenum mGlPrimitiveTopology;
+      private:
+        GLenum mGlPrimitiveTopology;
     };
 
-}
-}
+}}  // namespace backend::opengl
 
-#endif // BACKEND_OPENGL_RENDERPIPELINEGL_H_
+#endif  // BACKEND_OPENGL_RENDERPIPELINEGL_H_
diff --git a/src/backend/opengl/SamplerGL.cpp b/src/backend/opengl/SamplerGL.cpp
index b06c12f..2da9b9d 100644
--- a/src/backend/opengl/SamplerGL.cpp
+++ b/src/backend/opengl/SamplerGL.cpp
@@ -16,8 +16,7 @@
 
 #include "common/Assert.h"
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
     namespace {
         GLenum MagFilterMode(nxt::FilterMode filter) {
@@ -55,18 +54,17 @@
                     UNREACHABLE();
             }
         }
-    }
+    }  // namespace
 
-    Sampler::Sampler(SamplerBuilder* builder)
-        : SamplerBase(builder) {
+    Sampler::Sampler(SamplerBuilder* builder) : SamplerBase(builder) {
         glGenSamplers(1, &mHandle);
         glSamplerParameteri(mHandle, GL_TEXTURE_MAG_FILTER, MagFilterMode(builder->GetMagFilter()));
-        glSamplerParameteri(mHandle, GL_TEXTURE_MIN_FILTER, MinFilterMode(builder->GetMinFilter(), builder->GetMipMapFilter()));
+        glSamplerParameteri(mHandle, GL_TEXTURE_MIN_FILTER,
+                            MinFilterMode(builder->GetMinFilter(), builder->GetMipMapFilter()));
     }
 
     GLuint Sampler::GetHandle() const {
         return mHandle;
     }
 
-}
-}
+}}  // namespace backend::opengl
diff --git a/src/backend/opengl/SamplerGL.h b/src/backend/opengl/SamplerGL.h
index 1c56381..36f823d 100644
--- a/src/backend/opengl/SamplerGL.h
+++ b/src/backend/opengl/SamplerGL.h
@@ -19,22 +19,20 @@
 
 #include "glad/glad.h"
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
     class Device;
 
     class Sampler : public SamplerBase {
-        public:
-            Sampler(SamplerBuilder* builder);
+      public:
+        Sampler(SamplerBuilder* builder);
 
-            GLuint GetHandle() const;
+        GLuint GetHandle() const;
 
-        private:
-            GLuint mHandle;
+      private:
+        GLuint mHandle;
     };
 
-}
-}
+}}  // namespace backend::opengl
 
-#endif // BACKEND_OPENGL_SAMPLERGL_H_
+#endif  // BACKEND_OPENGL_SAMPLERGL_H_
diff --git a/src/backend/opengl/ShaderModuleGL.cpp b/src/backend/opengl/ShaderModuleGL.cpp
index 654ac0c..78ebad4 100644
--- a/src/backend/opengl/ShaderModuleGL.cpp
+++ b/src/backend/opengl/ShaderModuleGL.cpp
@@ -21,8 +21,7 @@
 
 #include <sstream>
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
     std::string GetBindingName(uint32_t group, uint32_t binding) {
         std::ostringstream o;
@@ -30,12 +29,13 @@
         return o.str();
     }
 
-    bool operator < (const BindingLocation& a, const BindingLocation& b) {
+    bool operator<(const BindingLocation& a, const BindingLocation& b) {
         return std::tie(a.group, a.binding) < std::tie(b.group, b.binding);
     }
 
-    bool operator < (const CombinedSampler& a, const CombinedSampler& b) {
-        return std::tie(a.samplerLocation, a.textureLocation) < std::tie(b.samplerLocation, b.textureLocation);
+    bool operator<(const CombinedSampler& a, const CombinedSampler& b) {
+        return std::tie(a.samplerLocation, a.textureLocation) <
+               std::tie(b.samplerLocation, b.textureLocation);
     }
 
     std::string CombinedSampler::GetName() const {
@@ -46,8 +46,7 @@
         return o.str();
     }
 
-    ShaderModule::ShaderModule(ShaderModuleBuilder* builder)
-        : ShaderModuleBase(builder) {
+    ShaderModule::ShaderModule(ShaderModuleBuilder* builder) : ShaderModuleBase(builder) {
         spirv_cross::CompilerGLSL compiler(builder->AcquireSpirv());
         spirv_cross::CompilerGLSL::Options options;
 
@@ -60,8 +59,8 @@
         options.vertex.flip_vert_y = true;
         compiler.set_options(options);
 
-        // Rename the push constant block to be prefixed with the shader stage type so that uniform names
-        // don't match between the FS and the VS.
+        // Rename the push constant block to be prefixed with the shader stage type so that uniform
+        // names don't match between the FS and the VS.
         const auto& resources = compiler.get_shader_resources();
         if (resources.push_constant_buffers.size() > 0) {
             const char* prefix = nullptr;
@@ -95,10 +94,14 @@
             mCombinedInfo.emplace_back();
 
             auto& info = mCombinedInfo.back();
-            info.samplerLocation.group = compiler.get_decoration(combined.sampler_id, spv::DecorationDescriptorSet);
-            info.samplerLocation.binding = compiler.get_decoration(combined.sampler_id, spv::DecorationBinding);
-            info.textureLocation.group = compiler.get_decoration(combined.image_id, spv::DecorationDescriptorSet);
-            info.textureLocation.binding = compiler.get_decoration(combined.image_id, spv::DecorationBinding);
+            info.samplerLocation.group =
+                compiler.get_decoration(combined.sampler_id, spv::DecorationDescriptorSet);
+            info.samplerLocation.binding =
+                compiler.get_decoration(combined.sampler_id, spv::DecorationBinding);
+            info.textureLocation.group =
+                compiler.get_decoration(combined.image_id, spv::DecorationDescriptorSet);
+            info.textureLocation.binding =
+                compiler.get_decoration(combined.image_id, spv::DecorationBinding);
             compiler.set_name(combined.combined_id, info.GetName());
         }
 
@@ -127,5 +130,4 @@
         return mCombinedInfo;
     }
 
-}
-}
+}}  // namespace backend::opengl
diff --git a/src/backend/opengl/ShaderModuleGL.h b/src/backend/opengl/ShaderModuleGL.h
index ccb2deb..5951ece 100644
--- a/src/backend/opengl/ShaderModuleGL.h
+++ b/src/backend/opengl/ShaderModuleGL.h
@@ -19,8 +19,7 @@
 
 #include "glad/glad.h"
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
     class Device;
 
@@ -30,30 +29,29 @@
         uint32_t group;
         uint32_t binding;
     };
-    bool operator < (const BindingLocation& a, const BindingLocation& b);
+    bool operator<(const BindingLocation& a, const BindingLocation& b);
 
     struct CombinedSampler {
         BindingLocation samplerLocation;
         BindingLocation textureLocation;
         std::string GetName() const;
     };
-    bool operator < (const CombinedSampler& a, const CombinedSampler& b);
+    bool operator<(const CombinedSampler& a, const CombinedSampler& b);
 
     class ShaderModule : public ShaderModuleBase {
-        public:
-            ShaderModule(ShaderModuleBuilder* builder);
+      public:
+        ShaderModule(ShaderModuleBuilder* builder);
 
-            using CombinedSamplerInfo = std::vector<CombinedSampler>;
+        using CombinedSamplerInfo = std::vector<CombinedSampler>;
 
-            const char* GetSource() const;
-            const CombinedSamplerInfo& GetCombinedSamplerInfo() const;
+        const char* GetSource() const;
+        const CombinedSamplerInfo& GetCombinedSamplerInfo() const;
 
-        private:
-            CombinedSamplerInfo mCombinedInfo;
-            std::string mGlslSource;
+      private:
+        CombinedSamplerInfo mCombinedInfo;
+        std::string mGlslSource;
     };
 
-}
-}
+}}  // namespace backend::opengl
 
-#endif // BACKEND_OPENGL_SHADERMODULEGL_H_
+#endif  // BACKEND_OPENGL_SHADERMODULEGL_H_
diff --git a/src/backend/opengl/SwapChainGL.cpp b/src/backend/opengl/SwapChainGL.cpp
index e37234b..6c5bf63 100644
--- a/src/backend/opengl/SwapChainGL.cpp
+++ b/src/backend/opengl/SwapChainGL.cpp
@@ -19,11 +19,9 @@
 
 #include <nxt/nxt_wsi.h>
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
-    SwapChain::SwapChain(SwapChainBuilder* builder)
-        : SwapChainBase(builder) {
+    SwapChain::SwapChain(SwapChainBuilder* builder) : SwapChainBase(builder) {
         const auto& im = GetImplementation();
         im.Init(im.userData, nullptr);
     }
@@ -43,5 +41,4 @@
         return new Texture(builder, nativeTexture);
     }
 
-}
-}
+}}  // namespace backend::opengl
diff --git a/src/backend/opengl/SwapChainGL.h b/src/backend/opengl/SwapChainGL.h
index 24741ff..03cf06e 100644
--- a/src/backend/opengl/SwapChainGL.h
+++ b/src/backend/opengl/SwapChainGL.h
@@ -19,21 +19,19 @@
 
 #include "glad/glad.h"
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
     class Device;
 
     class SwapChain : public SwapChainBase {
-        public:
-            SwapChain(SwapChainBuilder* builder);
-            ~SwapChain();
+      public:
+        SwapChain(SwapChainBuilder* builder);
+        ~SwapChain();
 
-        protected:
-            TextureBase* GetNextTextureImpl(TextureBuilder* builder) override;
+      protected:
+        TextureBase* GetNextTextureImpl(TextureBuilder* builder) override;
     };
 
-}
-}
+}}  // namespace backend::opengl
 
-#endif // BACKEND_OPENGL_SWAPCHAINGL_H_
+#endif  // BACKEND_OPENGL_SWAPCHAINGL_H_
diff --git a/src/backend/opengl/TextureGL.cpp b/src/backend/opengl/TextureGL.cpp
index d50efe2..6625faf 100644
--- a/src/backend/opengl/TextureGL.cpp
+++ b/src/backend/opengl/TextureGL.cpp
@@ -19,8 +19,7 @@
 #include <algorithm>
 #include <vector>
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
     namespace {
 
@@ -43,7 +42,8 @@
                     // This doesn't have an enum for the internal format in OpenGL.
                     return {GL_NONE, GL_BGRA, GL_UNSIGNED_BYTE};
                 case nxt::TextureFormat::D32FloatS8Uint:
-                    return {GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV};
+                    return {GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL,
+                            GL_FLOAT_32_UNSIGNED_INT_24_8_REV};
                 default:
                     UNREACHABLE();
             }
@@ -55,12 +55,11 @@
             return handle;
         }
 
-    }
+    }  // namespace
 
     // Texture
 
-    Texture::Texture(TextureBuilder* builder)
-        : Texture(builder, GenTexture()) {
+    Texture::Texture(TextureBuilder* builder) : Texture(builder, GenTexture()) {
     }
 
     Texture::Texture(TextureBuilder* builder, GLuint handle)
@@ -76,7 +75,8 @@
         glBindTexture(mTarget, handle);
 
         for (uint32_t i = 0; i < levels; ++i) {
-            glTexImage2D(mTarget, i, formatInfo.internalFormat, width, height, 0, formatInfo.format, formatInfo.type, nullptr);
+            glTexImage2D(mTarget, i, formatInfo.internalFormat, width, height, 0, formatInfo.format,
+                         formatInfo.type, nullptr);
             width = std::max(uint32_t(1), width / 2);
             height = std::max(uint32_t(1), height / 2);
         }
@@ -87,7 +87,8 @@
     }
 
     Texture::~Texture() {
-        // TODO(kainino@chromium.org): delete texture (but only when not using the native texture constructor?)
+        // TODO(kainino@chromium.org): delete texture (but only when not using the native texture
+        // constructor?)
     }
 
     GLuint Texture::GetHandle() const {
@@ -107,9 +108,7 @@
 
     // TextureView
 
-    TextureView::TextureView(TextureViewBuilder* builder)
-        : TextureViewBase(builder) {
+    TextureView::TextureView(TextureViewBuilder* builder) : TextureViewBase(builder) {
     }
 
-}
-}
+}}  // namespace backend::opengl
diff --git a/src/backend/opengl/TextureGL.h b/src/backend/opengl/TextureGL.h
index 648c5a1..a6583e8 100644
--- a/src/backend/opengl/TextureGL.h
+++ b/src/backend/opengl/TextureGL.h
@@ -19,8 +19,7 @@
 
 #include "glad/glad.h"
 
-namespace backend {
-namespace opengl {
+namespace backend { namespace opengl {
 
     class Device;
 
@@ -31,29 +30,28 @@
     };
 
     class Texture : public TextureBase {
-        public:
-            Texture(TextureBuilder* builder);
-            Texture(TextureBuilder* builder, GLuint handle);
-            ~Texture();
+      public:
+        Texture(TextureBuilder* builder);
+        Texture(TextureBuilder* builder, GLuint handle);
+        ~Texture();
 
-            GLuint GetHandle() const;
-            GLenum GetGLTarget() const;
-            TextureFormatInfo GetGLFormat() const;
+        GLuint GetHandle() const;
+        GLenum GetGLTarget() const;
+        TextureFormatInfo GetGLFormat() const;
 
-            void TransitionUsageImpl(nxt::TextureUsageBit currentUsage, nxt::TextureUsageBit targetUsage) override;
+        void TransitionUsageImpl(nxt::TextureUsageBit currentUsage,
+                                 nxt::TextureUsageBit targetUsage) override;
 
-        private:
-            GLuint mHandle;
-            GLenum mTarget;
+      private:
+        GLuint mHandle;
+        GLenum mTarget;
     };
 
     class TextureView : public TextureViewBase {
-        public:
-            TextureView(TextureViewBuilder* builder);
+      public:
+        TextureView(TextureViewBuilder* builder);
     };
 
+}}  // namespace backend::opengl
 
-}
-}
-
-#endif // BACKEND_OPENGL_TEXTUREGL_H_
+#endif  // BACKEND_OPENGL_TEXTUREGL_H_