null backend: fix resource usage after cmdbuf transition (#63)

and test it.
This commit is contained in:
Kai Ninomiya 2017-07-07 11:47:40 -07:00 committed by GitHub
parent fa37f2239c
commit 794d4faece
4 changed files with 121 additions and 14 deletions

View File

@ -14,6 +14,8 @@
#include "backend/null/NullBackend.h"
#include "backend/Commands.h"
#include <spirv-cross/spirv_cross.hpp>
namespace backend {
@ -36,46 +38,46 @@ namespace null {
}
BindGroupBase* Device::CreateBindGroup(BindGroupBuilder* builder) {
return new BindGroupBase(builder);
return new BindGroup(builder);
}
BindGroupLayoutBase* Device::CreateBindGroupLayout(BindGroupLayoutBuilder* builder) {
return new BindGroupLayoutBase(builder);
return new BindGroupLayout(builder);
}
BufferBase* Device::CreateBuffer(BufferBuilder* builder) {
return new Buffer(builder);
}
BufferViewBase* Device::CreateBufferView(BufferViewBuilder* builder) {
return new BufferViewBase(builder);
return new BufferView(builder);
}
CommandBufferBase* Device::CreateCommandBuffer(CommandBufferBuilder* builder) {
return new CommandBufferBase(builder);
return new CommandBuffer(builder);
}
DepthStencilStateBase* Device::CreateDepthStencilState(DepthStencilStateBuilder* builder) {
return new DepthStencilStateBase(builder);
return new DepthStencilState(builder);
}
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
return new InputStateBase(builder);
return new InputState(builder);
}
FramebufferBase* Device::CreateFramebuffer(FramebufferBuilder* builder) {
return new FramebufferBase(builder);
return new Framebuffer(builder);
}
PipelineBase* Device::CreatePipeline(PipelineBuilder* builder) {
return new PipelineBase(builder);
return new Pipeline(builder);
}
PipelineLayoutBase* Device::CreatePipelineLayout(PipelineLayoutBuilder* builder) {
return new PipelineLayoutBase(builder);
return new PipelineLayout(builder);
}
QueueBase* Device::CreateQueue(QueueBuilder* builder) {
return new Queue(builder);
}
RenderPassBase* Device::CreateRenderPass(RenderPassBuilder* builder) {
return new RenderPassBase(builder);
return new RenderPass(builder);
}
SamplerBase* Device::CreateSampler(SamplerBuilder* builder) {
return new SamplerBase(builder);
return new Sampler(builder);
}
ShaderModuleBase* Device::CreateShaderModule(ShaderModuleBuilder* builder) {
auto module = new ShaderModuleBase(builder);
auto module = new ShaderModule(builder);
spirv_cross::Compiler compiler(builder->AcquireSpirv());
module->ExtractSpirvInfo(compiler);
@ -86,7 +88,7 @@ namespace null {
return new Texture(builder);
}
TextureViewBase* Device::CreateTextureView(TextureViewBuilder* builder) {
return new TextureViewBase(builder);
return new TextureView(builder);
}
void Device::TickImpl() {
@ -155,6 +157,39 @@ namespace null {
void Buffer::TransitionUsageImpl(nxt::BufferUsageBit currentUsage, nxt::BufferUsageBit targetUsage) {
}
// CommandBuffer
CommandBuffer::CommandBuffer(CommandBufferBuilder* builder)
: CommandBufferBase(builder), commands(builder->AcquireCommands()) {
}
CommandBuffer::~CommandBuffer() {
FreeCommands(&commands);
}
void CommandBuffer::Execute() {
Command type;
while (commands.NextCommandId(&type)) {
switch (type) {
case Command::TransitionBufferUsage:
{
TransitionBufferUsageCmd* cmd = commands.NextCommand<TransitionBufferUsageCmd>();
cmd->buffer->UpdateUsageInternal(cmd->usage);
}
break;
case Command::TransitionTextureUsage:
{
TransitionTextureUsageCmd* cmd = commands.NextCommand<TransitionTextureUsageCmd>();
cmd->texture->UpdateUsageInternal(cmd->usage);
}
break;
default:
SkipCommand(&commands, type);
break;
}
}
}
// Queue
Queue::Queue(QueueBuilder* builder)
@ -171,6 +206,10 @@ namespace null {
operation->Execute();
}
for (uint32_t i = 0; i < numCommands; ++i) {
commands[i]->Execute();
}
operations.clear();
}

View File

@ -41,7 +41,7 @@ namespace null {
using BindGroupLayout = BindGroupLayoutBase;
class Buffer;
using BufferView = BufferViewBase;
using CommandBuffer = CommandBufferBase;
class CommandBuffer;
using DepthStencilState = DepthStencilStateBase;
class Device;
using InputState = InputStateBase;
@ -136,6 +136,17 @@ namespace null {
std::unique_ptr<char[]> backingData;
};
class CommandBuffer : public CommandBufferBase {
public:
CommandBuffer(CommandBufferBuilder* builder);
~CommandBuffer();
void Execute();
private:
CommandIterator commands;
};
class Queue : public QueueBase {
public:
Queue(QueueBuilder* builder);

View File

@ -36,6 +36,7 @@ add_executable(nxt_unittests
${VALIDATION_TESTS_DIR}/FramebufferValidationTests.cpp
${VALIDATION_TESTS_DIR}/InputStateValidationTests.cpp
${VALIDATION_TESTS_DIR}/RenderPassValidationTests.cpp
${VALIDATION_TESTS_DIR}/UsageValidationTests.cpp
${VALIDATION_TESTS_DIR}/ValidationTest.cpp
${VALIDATION_TESTS_DIR}/ValidationTest.h
${TESTS_DIR}/UnittestsMain.cpp

View File

@ -0,0 +1,56 @@
// Copyright 2017 The NXT Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "tests/unittests/validation/ValidationTest.h"
#include <gmock/gmock.h>
using namespace testing;
class UsageValidationTest : public ValidationTest {
protected:
nxt::Queue queue;
private:
void SetUp() override {
ValidationTest::SetUp();
queue = device.CreateQueueBuilder().GetResult();
}
};
// Test that command buffer submit changes buffer usage
TEST_F(UsageValidationTest, UsageAfterCommandBuffer) {
// TODO(kainino@chromium.org): This needs to be tested on every backend.
// Should we make an end2end test that tests this as well?
nxt::Buffer buf = device.CreateBufferBuilder()
.SetSize(4)
.SetAllowedUsage(nxt::BufferUsageBit::TransferDst | nxt::BufferUsageBit::Vertex)
.SetInitialUsage(nxt::BufferUsageBit::TransferDst)
.GetResult();
uint32_t foo = 0;
buf.SetSubData(0, 1, &foo);
buf.TransitionUsage(nxt::BufferUsageBit::Vertex);
ASSERT_DEVICE_ERROR(buf.SetSubData(0, 1, &foo));
nxt::CommandBuffer cmdbuf = device.CreateCommandBufferBuilder()
.TransitionBufferUsage(buf, nxt::BufferUsageBit::TransferDst)
.GetResult();
queue.Submit(1, &cmdbuf);
// buf should be in TransferDst usage
buf.SetSubData(0, 1, &foo);
}