null backend: fix resource usage after cmdbuf transition (#63)
and test it.
This commit is contained in:
parent
fa37f2239c
commit
794d4faece
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue