Input State Descriptorization
This change also removes InputState object. BUG=dawn:107 Change-Id: Ia3fd2d348658f5719de0279bfe7bb10a4f183523 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/5660 Commit-Queue: Yunchao He <yunchao.he@intel.com> Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
parent
5490e9aca1
commit
889d743baa
10
BUILD.gn
10
BUILD.gn
|
@ -121,8 +121,6 @@ source_set("libdawn_native_sources") {
|
|||
"src/dawn_native/FenceSignalTracker.cpp",
|
||||
"src/dawn_native/FenceSignalTracker.h",
|
||||
"src/dawn_native/Forward.h",
|
||||
"src/dawn_native/InputState.cpp",
|
||||
"src/dawn_native/InputState.h",
|
||||
"src/dawn_native/Instance.cpp",
|
||||
"src/dawn_native/Instance.h",
|
||||
"src/dawn_native/ObjectBase.cpp",
|
||||
|
@ -184,8 +182,6 @@ source_set("libdawn_native_sources") {
|
|||
"src/dawn_native/d3d12/DeviceD3D12.cpp",
|
||||
"src/dawn_native/d3d12/DeviceD3D12.h",
|
||||
"src/dawn_native/d3d12/Forward.h",
|
||||
"src/dawn_native/d3d12/InputStateD3D12.cpp",
|
||||
"src/dawn_native/d3d12/InputStateD3D12.h",
|
||||
"src/dawn_native/d3d12/NativeSwapChainImplD3D12.cpp",
|
||||
"src/dawn_native/d3d12/NativeSwapChainImplD3D12.h",
|
||||
"src/dawn_native/d3d12/PipelineLayoutD3D12.cpp",
|
||||
|
@ -235,8 +231,6 @@ source_set("libdawn_native_sources") {
|
|||
"src/dawn_native/metal/DeviceMTL.h",
|
||||
"src/dawn_native/metal/DeviceMTL.mm",
|
||||
"src/dawn_native/metal/Forward.h",
|
||||
"src/dawn_native/metal/InputStateMTL.h",
|
||||
"src/dawn_native/metal/InputStateMTL.mm",
|
||||
"src/dawn_native/metal/PipelineLayoutMTL.h",
|
||||
"src/dawn_native/metal/PipelineLayoutMTL.mm",
|
||||
"src/dawn_native/metal/QueueMTL.h",
|
||||
|
@ -279,8 +273,6 @@ source_set("libdawn_native_sources") {
|
|||
"src/dawn_native/opengl/DeviceGL.cpp",
|
||||
"src/dawn_native/opengl/DeviceGL.h",
|
||||
"src/dawn_native/opengl/Forward.h",
|
||||
"src/dawn_native/opengl/InputStateGL.cpp",
|
||||
"src/dawn_native/opengl/InputStateGL.h",
|
||||
"src/dawn_native/opengl/PersistentPipelineStateGL.cpp",
|
||||
"src/dawn_native/opengl/PersistentPipelineStateGL.h",
|
||||
"src/dawn_native/opengl/PipelineGL.cpp",
|
||||
|
@ -326,8 +318,6 @@ source_set("libdawn_native_sources") {
|
|||
"src/dawn_native/vulkan/FencedDeleter.cpp",
|
||||
"src/dawn_native/vulkan/FencedDeleter.h",
|
||||
"src/dawn_native/vulkan/Forward.h",
|
||||
"src/dawn_native/vulkan/InputStateVk.cpp",
|
||||
"src/dawn_native/vulkan/InputStateVk.h",
|
||||
"src/dawn_native/vulkan/MemoryAllocator.cpp",
|
||||
"src/dawn_native/vulkan/MemoryAllocator.h",
|
||||
"src/dawn_native/vulkan/NativeSwapChainImplVk.cpp",
|
||||
|
|
36
dawn.json
36
dawn.json
|
@ -448,10 +448,6 @@
|
|||
"name": "create command encoder",
|
||||
"returns": "command encoder"
|
||||
},
|
||||
{
|
||||
"name": "create input state builder",
|
||||
"returns": "input state builder"
|
||||
},
|
||||
{
|
||||
"name": "create compute pipeline",
|
||||
"returns": "compute pipeline",
|
||||
|
@ -622,28 +618,14 @@
|
|||
{"name": "step mode", "type": "input step mode"}
|
||||
]
|
||||
},
|
||||
"input state": {
|
||||
"category": "object"
|
||||
},
|
||||
"input state builder": {
|
||||
"category": "object",
|
||||
"methods": [
|
||||
{
|
||||
"name": "get result",
|
||||
"returns": "input state"
|
||||
},
|
||||
{
|
||||
"name": "set attribute",
|
||||
"args": [
|
||||
{"name": "attribute", "type": "vertex attribute descriptor", "annotation": "const*"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "set input",
|
||||
"args": [
|
||||
{"name": "input", "type": "vertex input descriptor", "annotation": "const*"}
|
||||
]
|
||||
}
|
||||
"input state descriptor": {
|
||||
"category": "structure",
|
||||
"extensible": true,
|
||||
"members": [
|
||||
{"name": "num attributes", "type": "uint32_t"},
|
||||
{"name": "attributes", "type": "vertex attribute descriptor", "annotation": "const*", "length": "num attributes"},
|
||||
{"name": "num inputs", "type": "uint32_t"},
|
||||
{"name": "inputs", "type": "vertex input descriptor", "annotation": "const*", "length": "num inputs"}
|
||||
]
|
||||
},
|
||||
"input step mode": {
|
||||
|
@ -881,7 +863,7 @@
|
|||
{"name": "layout", "type": "pipeline layout"},
|
||||
{"name": "vertex stage", "type": "pipeline stage descriptor", "annotation": "const*"},
|
||||
{"name": "fragment stage", "type": "pipeline stage descriptor", "annotation": "const*"},
|
||||
{"name": "input state", "type": "input state"},
|
||||
{"name": "input state", "type": "input state descriptor", "annotation": "const*"},
|
||||
{"name": "index format", "type": "index format"},
|
||||
{"name": "primitive topology", "type": "primitive topology"},
|
||||
{"name": "sample count", "type": "uint32_t"},
|
||||
|
|
|
@ -93,9 +93,13 @@ void init() {
|
|||
pl.bindGroupLayouts = nullptr;
|
||||
descriptor.layout = dawnDeviceCreatePipelineLayout(device, &pl);
|
||||
|
||||
DawnInputStateBuilder inputStateBuilder = dawnDeviceCreateInputStateBuilder(device);
|
||||
descriptor.inputState = dawnInputStateBuilderGetResult(inputStateBuilder);
|
||||
dawnInputStateBuilderRelease(inputStateBuilder);
|
||||
DawnInputStateDescriptor inputState;
|
||||
inputState.nextInChain = nullptr;
|
||||
inputState.numInputs = 0;
|
||||
inputState.inputs = nullptr;
|
||||
inputState.numAttributes = 0;
|
||||
inputState.attributes = nullptr;
|
||||
descriptor.inputState = &inputState;
|
||||
|
||||
descriptor.indexFormat = DAWN_INDEX_FORMAT_UINT32;
|
||||
descriptor.primitiveTopology = DAWN_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
|
@ -103,8 +107,6 @@ void init() {
|
|||
descriptor.depthStencilState = nullptr;
|
||||
|
||||
pipeline = dawnDeviceCreateRenderPipeline(device, &descriptor);
|
||||
|
||||
dawnInputStateRelease(descriptor.inputState);
|
||||
}
|
||||
|
||||
dawnShaderModuleRelease(vsModule);
|
||||
|
|
|
@ -114,48 +114,41 @@ void initRender() {
|
|||
}
|
||||
)");
|
||||
|
||||
dawn::VertexAttributeDescriptor attribute1;
|
||||
attribute1.shaderLocation = 0;
|
||||
attribute1.inputSlot = 0;
|
||||
attribute1.offset = offsetof(Particle, pos);
|
||||
attribute1.format = dawn::VertexFormat::Float2;
|
||||
dawn::VertexAttributeDescriptor attribute[3];
|
||||
attribute[0].shaderLocation = 0;
|
||||
attribute[0].inputSlot = 0;
|
||||
attribute[0].offset = offsetof(Particle, pos);
|
||||
attribute[0].format = dawn::VertexFormat::Float2;
|
||||
|
||||
dawn::VertexAttributeDescriptor attribute2;
|
||||
attribute2.shaderLocation = 1;
|
||||
attribute2.inputSlot = 0;
|
||||
attribute2.offset = offsetof(Particle, vel);
|
||||
attribute2.format = dawn::VertexFormat::Float2;
|
||||
attribute[1].shaderLocation = 1;
|
||||
attribute[1].inputSlot = 0;
|
||||
attribute[1].offset = offsetof(Particle, vel);
|
||||
attribute[1].format = dawn::VertexFormat::Float2;
|
||||
|
||||
dawn::VertexInputDescriptor input1;
|
||||
input1.inputSlot = 0;
|
||||
input1.stride = sizeof(Particle);
|
||||
input1.stepMode = dawn::InputStepMode::Instance;
|
||||
attribute[2].shaderLocation = 2;
|
||||
attribute[2].inputSlot = 1;
|
||||
attribute[2].offset = 0;
|
||||
attribute[2].format = dawn::VertexFormat::Float2;
|
||||
|
||||
dawn::VertexAttributeDescriptor attribute3;
|
||||
attribute3.shaderLocation = 2;
|
||||
attribute3.inputSlot = 1;
|
||||
attribute3.offset = 0;
|
||||
attribute3.format = dawn::VertexFormat::Float2;
|
||||
dawn::VertexInputDescriptor input[2];
|
||||
input[0].inputSlot = 0;
|
||||
input[0].stride = sizeof(Particle);
|
||||
input[0].stepMode = dawn::InputStepMode::Instance;
|
||||
|
||||
dawn::VertexInputDescriptor input2;
|
||||
input2.inputSlot = 1;
|
||||
input2.stride = sizeof(glm::vec2);
|
||||
input2.stepMode = dawn::InputStepMode::Vertex;
|
||||
|
||||
dawn::InputState inputState = device.CreateInputStateBuilder()
|
||||
.SetAttribute(&attribute1)
|
||||
.SetAttribute(&attribute2)
|
||||
.SetInput(&input1)
|
||||
.SetAttribute(&attribute3)
|
||||
.SetInput(&input2)
|
||||
.GetResult();
|
||||
input[1].inputSlot = 1;
|
||||
input[1].stride = sizeof(glm::vec2);
|
||||
input[1].stepMode = dawn::InputStepMode::Vertex;
|
||||
|
||||
depthStencilView = CreateDefaultDepthStencilView(device);
|
||||
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
descriptor.cFragmentStage.module = fsModule;
|
||||
descriptor.inputState = inputState;
|
||||
|
||||
descriptor.cInputState.numAttributes = 3;
|
||||
descriptor.cInputState.attributes = attribute;
|
||||
descriptor.cInputState.numInputs = 2;
|
||||
descriptor.cInputState.inputs = input;
|
||||
descriptor.depthStencilState = &descriptor.cDepthStencilState;
|
||||
descriptor.cDepthStencilState.format = dawn::TextureFormat::D32FloatS8Uint;
|
||||
descriptor.cColorStates[0]->format = GetPreferredSwapChainTextureFormat();
|
||||
|
|
|
@ -122,9 +122,6 @@ void init() {
|
|||
input.stride = 4 * sizeof(float);
|
||||
input.stepMode = dawn::InputStepMode::Vertex;
|
||||
|
||||
auto inputState =
|
||||
device.CreateInputStateBuilder().SetAttribute(&attribute).SetInput(&input).GetResult();
|
||||
|
||||
auto bgl = utils::MakeBindGroupLayout(
|
||||
device, {
|
||||
{0, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler},
|
||||
|
@ -139,7 +136,10 @@ void init() {
|
|||
descriptor.layout = utils::MakeBasicPipelineLayout(device, &bgl);
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
descriptor.cFragmentStage.module = fsModule;
|
||||
descriptor.inputState = inputState;
|
||||
descriptor.cInputState.numAttributes = 1;
|
||||
descriptor.cInputState.attributes = &attribute;
|
||||
descriptor.cInputState.numInputs = 1;
|
||||
descriptor.cInputState.inputs = &input;
|
||||
descriptor.depthStencilState = &descriptor.cDepthStencilState;
|
||||
descriptor.cDepthStencilState.format = dawn::TextureFormat::D32FloatS8Uint;
|
||||
descriptor.cColorStates[0]->format = GetPreferredSwapChainTextureFormat();
|
||||
|
|
|
@ -156,28 +156,27 @@ void init() {
|
|||
fragColor = vec4(mix(f_col, vec3(0.5, 0.5, 0.5), 0.5), 1.0);
|
||||
})");
|
||||
|
||||
dawn::VertexAttributeDescriptor attribute1;
|
||||
attribute1.shaderLocation = 0;
|
||||
attribute1.inputSlot = 0;
|
||||
attribute1.offset = 0;
|
||||
attribute1.format = dawn::VertexFormat::Float3;
|
||||
dawn::VertexAttributeDescriptor attribute[2];
|
||||
attribute[0].shaderLocation = 0;
|
||||
attribute[0].inputSlot = 0;
|
||||
attribute[0].offset = 0;
|
||||
attribute[0].format = dawn::VertexFormat::Float3;
|
||||
|
||||
dawn::VertexAttributeDescriptor attribute2;
|
||||
attribute2.shaderLocation = 1;
|
||||
attribute2.inputSlot = 0;
|
||||
attribute2.offset = 3 * sizeof(float);
|
||||
attribute2.format = dawn::VertexFormat::Float3;
|
||||
attribute[1].shaderLocation = 1;
|
||||
attribute[1].inputSlot = 0;
|
||||
attribute[1].offset = 3 * sizeof(float);
|
||||
attribute[1].format = dawn::VertexFormat::Float3;
|
||||
|
||||
dawn::VertexInputDescriptor input;
|
||||
input.inputSlot = 0;
|
||||
input.stride = 6 * sizeof(float);
|
||||
input.stepMode = dawn::InputStepMode::Vertex;
|
||||
|
||||
auto inputState = device.CreateInputStateBuilder()
|
||||
.SetAttribute(&attribute1)
|
||||
.SetAttribute(&attribute2)
|
||||
.SetInput(&input)
|
||||
.GetResult();
|
||||
dawn::InputStateDescriptor inputState;
|
||||
inputState.numAttributes = 2;
|
||||
inputState.attributes = attribute;
|
||||
inputState.numInputs = 1;
|
||||
inputState.inputs = &input;
|
||||
|
||||
auto bgl = utils::MakeBindGroupLayout(
|
||||
device, {
|
||||
|
@ -214,7 +213,7 @@ void init() {
|
|||
descriptor.layout = pl;
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
descriptor.cFragmentStage.module = fsModule;
|
||||
descriptor.inputState = inputState;
|
||||
descriptor.inputState = &inputState;
|
||||
descriptor.depthStencilState = &descriptor.cDepthStencilState;
|
||||
descriptor.cDepthStencilState.format = dawn::TextureFormat::D32FloatS8Uint;
|
||||
descriptor.cColorStates[0]->format = GetPreferredSwapChainTextureFormat();
|
||||
|
@ -227,7 +226,7 @@ void init() {
|
|||
pDescriptor.layout = pl;
|
||||
pDescriptor.cVertexStage.module = vsModule;
|
||||
pDescriptor.cFragmentStage.module = fsModule;
|
||||
pDescriptor.inputState = inputState;
|
||||
pDescriptor.inputState = &inputState;
|
||||
pDescriptor.depthStencilState = &pDescriptor.cDepthStencilState;
|
||||
pDescriptor.cDepthStencilState.format = dawn::TextureFormat::D32FloatS8Uint;
|
||||
pDescriptor.cColorStates[0]->format = GetPreferredSwapChainTextureFormat();
|
||||
|
@ -241,7 +240,7 @@ void init() {
|
|||
rfDescriptor.layout = pl;
|
||||
rfDescriptor.cVertexStage.module = vsModule;
|
||||
rfDescriptor.cFragmentStage.module = fsReflectionModule;
|
||||
rfDescriptor.inputState = inputState;
|
||||
rfDescriptor.inputState = &inputState;
|
||||
rfDescriptor.depthStencilState = &rfDescriptor.cDepthStencilState;
|
||||
rfDescriptor.cDepthStencilState.format = dawn::TextureFormat::D32FloatS8Uint;
|
||||
rfDescriptor.cColorStates[0]->format = GetPreferredSwapChainTextureFormat();
|
||||
|
|
|
@ -237,7 +237,11 @@ namespace {
|
|||
|
||||
auto oFSModule = utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, hasTexture ? oFSSourceTextured : oFSSourceUntextured);
|
||||
|
||||
dawn::InputStateBuilder builder = device.CreateInputStateBuilder();
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
dawn::VertexAttributeDescriptor attributes[kMaxVertexAttributes];
|
||||
dawn::VertexInputDescriptor inputs[kMaxVertexInputs];
|
||||
uint32_t numAttributes = 0;
|
||||
uint32_t numInputs = 0;
|
||||
std::bitset<3> slotsSet;
|
||||
for (const auto& a : iTechnique.attributes) {
|
||||
const auto iAttributeName = a.first;
|
||||
|
@ -247,60 +251,58 @@ namespace {
|
|||
fprintf(stderr, "unsupported technique parameter type %d\n", iParameter.type);
|
||||
continue;
|
||||
}
|
||||
dawn::VertexAttributeDescriptor attribute;
|
||||
attribute.offset = 0;
|
||||
attribute.format = format;
|
||||
dawn::VertexInputDescriptor input;
|
||||
input.stepMode = dawn::InputStepMode::Vertex;
|
||||
attributes[numAttributes].offset = 0;
|
||||
attributes[numAttributes].format = format;
|
||||
inputs[numInputs].stepMode = dawn::InputStepMode::Vertex;
|
||||
|
||||
if (iParameter.semantic == "POSITION") {
|
||||
attribute.shaderLocation = 0;
|
||||
attribute.inputSlot = 0;
|
||||
input.inputSlot = 0;
|
||||
input.stride = static_cast<uint32_t>(stridePos);
|
||||
builder.SetAttribute(&attribute);
|
||||
builder.SetInput(&input);
|
||||
attributes[numAttributes].shaderLocation = 0;
|
||||
attributes[numAttributes].inputSlot = 0;
|
||||
inputs[numInputs].inputSlot = 0;
|
||||
inputs[numInputs].stride = static_cast<uint32_t>(stridePos);
|
||||
numAttributes++;
|
||||
numInputs++;
|
||||
slotsSet.set(0);
|
||||
} else if (iParameter.semantic == "NORMAL") {
|
||||
attribute.shaderLocation = 1;
|
||||
attribute.inputSlot = 1;
|
||||
input.inputSlot = 1;
|
||||
input.stride = static_cast<uint32_t>(strideNor);
|
||||
builder.SetAttribute(&attribute);
|
||||
builder.SetInput(&input);
|
||||
attributes[numAttributes].shaderLocation = 1;
|
||||
attributes[numAttributes].inputSlot = 1;
|
||||
inputs[numInputs].inputSlot = 1;
|
||||
inputs[numInputs].stride = static_cast<uint32_t>(strideNor);
|
||||
numAttributes++;
|
||||
numInputs++;
|
||||
slotsSet.set(1);
|
||||
} else if (iParameter.semantic == "TEXCOORD_0") {
|
||||
attribute.shaderLocation = 2;
|
||||
attribute.inputSlot = 2;
|
||||
input.inputSlot = 2;
|
||||
input.stride = static_cast<uint32_t>(strideTxc);
|
||||
builder.SetAttribute(&attribute);
|
||||
builder.SetInput(&input);
|
||||
attributes[numAttributes].shaderLocation = 2;
|
||||
attributes[numAttributes].inputSlot = 2;
|
||||
inputs[numInputs].inputSlot = 2;
|
||||
inputs[numInputs].stride = static_cast<uint32_t>(strideTxc);
|
||||
numAttributes++;
|
||||
numInputs++;
|
||||
slotsSet.set(2);
|
||||
} else {
|
||||
fprintf(stderr, "unsupported technique attribute semantic %s\n", iParameter.semantic.c_str());
|
||||
}
|
||||
// TODO: use iAttributeParameter.node?
|
||||
}
|
||||
for (uint32_t i = 0; i < slotsSet.size(); i++) {
|
||||
if (slotsSet[i]) {
|
||||
continue;
|
||||
}
|
||||
dawn::VertexAttributeDescriptor attribute;
|
||||
attribute.offset = 0;
|
||||
attribute.shaderLocation = i;
|
||||
attribute.inputSlot = i;
|
||||
attribute.format = dawn::VertexFormat::Float4;
|
||||
attributes[numAttributes].offset = 0;
|
||||
attributes[numAttributes].shaderLocation = i;
|
||||
attributes[numAttributes].inputSlot = i;
|
||||
attributes[numAttributes].format = dawn::VertexFormat::Float4;
|
||||
|
||||
dawn::VertexInputDescriptor input;
|
||||
input.inputSlot = i;
|
||||
input.stride = 0;
|
||||
input.stepMode = dawn::InputStepMode::Vertex;
|
||||
inputs[numInputs].inputSlot = i;
|
||||
inputs[numInputs].stride = 0;
|
||||
inputs[numInputs].stepMode = dawn::InputStepMode::Vertex;
|
||||
|
||||
builder.SetAttribute(&attribute);
|
||||
builder.SetInput(&input);
|
||||
numAttributes++;
|
||||
numInputs++;
|
||||
}
|
||||
auto inputState = builder.GetResult();
|
||||
descriptor.cInputState.numAttributes = numAttributes;
|
||||
descriptor.cInputState.attributes = attributes;
|
||||
descriptor.cInputState.numInputs = numInputs;
|
||||
descriptor.cInputState.inputs = inputs;
|
||||
|
||||
constexpr dawn::ShaderStageBit kNoStages{};
|
||||
dawn::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
|
||||
|
@ -313,11 +315,9 @@ namespace {
|
|||
|
||||
auto pipelineLayout = utils::MakeBasicPipelineLayout(device, &bindGroupLayout);
|
||||
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.layout = pipelineLayout;
|
||||
descriptor.cVertexStage.module = oVSModule;
|
||||
descriptor.cFragmentStage.module = oFSModule;
|
||||
descriptor.inputState = inputState;
|
||||
descriptor.indexFormat = dawn::IndexFormat::Uint16;
|
||||
descriptor.depthStencilState = &descriptor.cDepthStencilState;
|
||||
descriptor.cDepthStencilState.format = dawn::TextureFormat::D32FloatS8Uint;
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include "dawn_native/BindGroup.h"
|
||||
#include "dawn_native/ComputePipeline.h"
|
||||
#include "dawn_native/Forward.h"
|
||||
#include "dawn_native/InputState.h"
|
||||
#include "dawn_native/PipelineLayout.h"
|
||||
#include "dawn_native/RenderPipeline.h"
|
||||
|
||||
|
@ -106,7 +105,7 @@ namespace dawn_native {
|
|||
if (aspects[VALIDATION_ASPECT_VERTEX_BUFFERS]) {
|
||||
ASSERT(mLastRenderPipeline != nullptr);
|
||||
|
||||
auto requiredInputs = mLastRenderPipeline->GetInputState()->GetInputsSetMask();
|
||||
auto requiredInputs = mLastRenderPipeline->GetInputsSetMask();
|
||||
if ((mInputsSet & requiredInputs) == requiredInputs) {
|
||||
mAspects.set(VALIDATION_ASPECT_VERTEX_BUFFERS);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "dawn_native/ErrorData.h"
|
||||
#include "dawn_native/Fence.h"
|
||||
#include "dawn_native/FenceSignalTracker.h"
|
||||
#include "dawn_native/InputState.h"
|
||||
#include "dawn_native/PipelineLayout.h"
|
||||
#include "dawn_native/Queue.h"
|
||||
#include "dawn_native/RenderPipeline.h"
|
||||
|
@ -159,9 +158,6 @@ namespace dawn_native {
|
|||
|
||||
return result;
|
||||
}
|
||||
InputStateBuilder* DeviceBase::CreateInputStateBuilder() {
|
||||
return new InputStateBuilder(this);
|
||||
}
|
||||
PipelineLayoutBase* DeviceBase::CreatePipelineLayout(
|
||||
const PipelineLayoutDescriptor* descriptor) {
|
||||
PipelineLayoutBase* result = nullptr;
|
||||
|
|
|
@ -60,7 +60,6 @@ namespace dawn_native {
|
|||
FenceSignalTracker* GetFenceSignalTracker() const;
|
||||
|
||||
virtual CommandBufferBase* CreateCommandBuffer(CommandEncoderBase* encoder) = 0;
|
||||
virtual InputStateBase* CreateInputState(InputStateBuilder* builder) = 0;
|
||||
|
||||
virtual Serial GetCompletedCommandSerial() const = 0;
|
||||
virtual Serial GetLastSubmittedCommandSerial() const = 0;
|
||||
|
@ -91,7 +90,6 @@ namespace dawn_native {
|
|||
BufferBase* CreateBuffer(const BufferDescriptor* descriptor);
|
||||
CommandEncoderBase* CreateCommandEncoder();
|
||||
ComputePipelineBase* CreateComputePipeline(const ComputePipelineDescriptor* descriptor);
|
||||
InputStateBuilder* CreateInputStateBuilder();
|
||||
PipelineLayoutBase* CreatePipelineLayout(const PipelineLayoutDescriptor* descriptor);
|
||||
QueueBase* CreateQueue();
|
||||
RenderPipelineBase* CreateRenderPipeline(const RenderPipelineDescriptor* descriptor);
|
||||
|
|
|
@ -28,8 +28,6 @@ namespace dawn_native {
|
|||
class CommandEncoderBase;
|
||||
class ComputePassEncoderBase;
|
||||
class FenceBase;
|
||||
class InputStateBase;
|
||||
class InputStateBuilder;
|
||||
class InstanceBase;
|
||||
class PipelineBase;
|
||||
class PipelineLayoutBase;
|
||||
|
|
|
@ -1,217 +0,0 @@
|
|||
// Copyright 2017 The Dawn 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 "dawn_native/InputState.h"
|
||||
|
||||
#include "common/Assert.h"
|
||||
#include "dawn_native/Device.h"
|
||||
#include "dawn_native/ValidationUtils_autogen.h"
|
||||
|
||||
namespace dawn_native {
|
||||
|
||||
// InputState helpers
|
||||
|
||||
size_t IndexFormatSize(dawn::IndexFormat format) {
|
||||
switch (format) {
|
||||
case dawn::IndexFormat::Uint16:
|
||||
return sizeof(uint16_t);
|
||||
case dawn::IndexFormat::Uint32:
|
||||
return sizeof(uint32_t);
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(shaobo.yan@intel.com): Add end2end test to cover all the formats.
|
||||
uint32_t VertexFormatNumComponents(dawn::VertexFormat format) {
|
||||
switch (format) {
|
||||
case dawn::VertexFormat::UChar4:
|
||||
case dawn::VertexFormat::Char4:
|
||||
case dawn::VertexFormat::UChar4Norm:
|
||||
case dawn::VertexFormat::Char4Norm:
|
||||
case dawn::VertexFormat::UShort4:
|
||||
case dawn::VertexFormat::Short4:
|
||||
case dawn::VertexFormat::UShort4Norm:
|
||||
case dawn::VertexFormat::Short4Norm:
|
||||
case dawn::VertexFormat::Half4:
|
||||
case dawn::VertexFormat::Float4:
|
||||
case dawn::VertexFormat::UInt4:
|
||||
case dawn::VertexFormat::Int4:
|
||||
return 4;
|
||||
case dawn::VertexFormat::Float3:
|
||||
case dawn::VertexFormat::UInt3:
|
||||
case dawn::VertexFormat::Int3:
|
||||
return 3;
|
||||
case dawn::VertexFormat::UChar2:
|
||||
case dawn::VertexFormat::Char2:
|
||||
case dawn::VertexFormat::UChar2Norm:
|
||||
case dawn::VertexFormat::Char2Norm:
|
||||
case dawn::VertexFormat::UShort2:
|
||||
case dawn::VertexFormat::Short2:
|
||||
case dawn::VertexFormat::UShort2Norm:
|
||||
case dawn::VertexFormat::Short2Norm:
|
||||
case dawn::VertexFormat::Half2:
|
||||
case dawn::VertexFormat::Float2:
|
||||
case dawn::VertexFormat::UInt2:
|
||||
case dawn::VertexFormat::Int2:
|
||||
return 2;
|
||||
case dawn::VertexFormat::Float:
|
||||
case dawn::VertexFormat::UInt:
|
||||
case dawn::VertexFormat::Int:
|
||||
return 1;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
size_t VertexFormatComponentSize(dawn::VertexFormat format) {
|
||||
switch (format) {
|
||||
case dawn::VertexFormat::UChar2:
|
||||
case dawn::VertexFormat::UChar4:
|
||||
case dawn::VertexFormat::Char2:
|
||||
case dawn::VertexFormat::Char4:
|
||||
case dawn::VertexFormat::UChar2Norm:
|
||||
case dawn::VertexFormat::UChar4Norm:
|
||||
case dawn::VertexFormat::Char2Norm:
|
||||
case dawn::VertexFormat::Char4Norm:
|
||||
return sizeof(char);
|
||||
case dawn::VertexFormat::UShort2:
|
||||
case dawn::VertexFormat::UShort4:
|
||||
case dawn::VertexFormat::UShort2Norm:
|
||||
case dawn::VertexFormat::UShort4Norm:
|
||||
case dawn::VertexFormat::Short2:
|
||||
case dawn::VertexFormat::Short4:
|
||||
case dawn::VertexFormat::Short2Norm:
|
||||
case dawn::VertexFormat::Short4Norm:
|
||||
case dawn::VertexFormat::Half2:
|
||||
case dawn::VertexFormat::Half4:
|
||||
return sizeof(uint16_t);
|
||||
case dawn::VertexFormat::Float:
|
||||
case dawn::VertexFormat::Float2:
|
||||
case dawn::VertexFormat::Float3:
|
||||
case dawn::VertexFormat::Float4:
|
||||
return sizeof(float);
|
||||
case dawn::VertexFormat::UInt:
|
||||
case dawn::VertexFormat::UInt2:
|
||||
case dawn::VertexFormat::UInt3:
|
||||
case dawn::VertexFormat::UInt4:
|
||||
case dawn::VertexFormat::Int:
|
||||
case dawn::VertexFormat::Int2:
|
||||
case dawn::VertexFormat::Int3:
|
||||
case dawn::VertexFormat::Int4:
|
||||
return sizeof(int32_t);
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
size_t VertexFormatSize(dawn::VertexFormat format) {
|
||||
return VertexFormatNumComponents(format) * VertexFormatComponentSize(format);
|
||||
}
|
||||
|
||||
// InputStateBase
|
||||
|
||||
InputStateBase::InputStateBase(InputStateBuilder* builder) : ObjectBase(builder->GetDevice()) {
|
||||
mAttributesSetMask = builder->mAttributesSetMask;
|
||||
mAttributeInfos = builder->mAttributeInfos;
|
||||
mInputsSetMask = builder->mInputsSetMask;
|
||||
mInputInfos = builder->mInputInfos;
|
||||
}
|
||||
|
||||
const std::bitset<kMaxVertexAttributes>& InputStateBase::GetAttributesSetMask() const {
|
||||
return mAttributesSetMask;
|
||||
}
|
||||
|
||||
const VertexAttributeDescriptor& InputStateBase::GetAttribute(uint32_t location) const {
|
||||
ASSERT(mAttributesSetMask[location]);
|
||||
return mAttributeInfos[location];
|
||||
}
|
||||
|
||||
const std::bitset<kMaxVertexInputs>& InputStateBase::GetInputsSetMask() const {
|
||||
return mInputsSetMask;
|
||||
}
|
||||
|
||||
const VertexInputDescriptor& InputStateBase::GetInput(uint32_t slot) const {
|
||||
ASSERT(mInputsSetMask[slot]);
|
||||
return mInputInfos[slot];
|
||||
}
|
||||
|
||||
// InputStateBuilder
|
||||
|
||||
InputStateBuilder::InputStateBuilder(DeviceBase* device) : Builder(device) {
|
||||
}
|
||||
|
||||
InputStateBase* InputStateBuilder::GetResultImpl() {
|
||||
for (uint32_t location = 0; location < kMaxVertexAttributes; ++location) {
|
||||
if (mAttributesSetMask[location] &&
|
||||
!mInputsSetMask[mAttributeInfos[location].inputSlot]) {
|
||||
HandleError("Attribute uses unset input");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return GetDevice()->CreateInputState(this);
|
||||
}
|
||||
|
||||
void InputStateBuilder::SetAttribute(const VertexAttributeDescriptor* attribute) {
|
||||
if (attribute->shaderLocation >= kMaxVertexAttributes) {
|
||||
HandleError("Setting attribute out of bounds");
|
||||
return;
|
||||
}
|
||||
if (attribute->inputSlot >= kMaxVertexInputs) {
|
||||
HandleError("Binding slot out of bounds");
|
||||
return;
|
||||
}
|
||||
if (GetDevice()->ConsumedError(ValidateVertexFormat(attribute->format))) {
|
||||
return;
|
||||
}
|
||||
// If attribute->offset is close to 0xFFFFFFFF, the validation below to add
|
||||
// attribute->offset and VertexFormatSize(attribute->format) might overflow on a
|
||||
// 32bit machine, then it can pass the validation incorrectly. We need to catch it.
|
||||
if (attribute->offset >= kMaxVertexAttributeEnd) {
|
||||
HandleError("Setting attribute offset out of bounds");
|
||||
return;
|
||||
}
|
||||
if (attribute->offset + VertexFormatSize(attribute->format) > kMaxVertexAttributeEnd) {
|
||||
HandleError("Setting attribute offset out of bounds");
|
||||
return;
|
||||
}
|
||||
if (mAttributesSetMask[attribute->shaderLocation]) {
|
||||
HandleError("Setting already set attribute");
|
||||
return;
|
||||
}
|
||||
|
||||
mAttributesSetMask.set(attribute->shaderLocation);
|
||||
mAttributeInfos[attribute->shaderLocation] = *attribute;
|
||||
}
|
||||
|
||||
void InputStateBuilder::SetInput(const VertexInputDescriptor* input) {
|
||||
if (input->inputSlot >= kMaxVertexInputs) {
|
||||
HandleError("Setting input out of bounds");
|
||||
return;
|
||||
}
|
||||
if (input->stride > kMaxVertexInputStride) {
|
||||
HandleError("Setting input stride out of bounds");
|
||||
return;
|
||||
}
|
||||
if (mInputsSetMask[input->inputSlot]) {
|
||||
HandleError("Setting already set input");
|
||||
return;
|
||||
}
|
||||
|
||||
mInputsSetMask.set(input->inputSlot);
|
||||
mInputInfos[input->inputSlot] = *input;
|
||||
}
|
||||
|
||||
} // namespace dawn_native
|
|
@ -1,72 +0,0 @@
|
|||
// Copyright 2017 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef DAWNNATIVE_INPUTSTATE_H_
|
||||
#define DAWNNATIVE_INPUTSTATE_H_
|
||||
|
||||
#include "common/Constants.h"
|
||||
#include "dawn_native/Builder.h"
|
||||
#include "dawn_native/Forward.h"
|
||||
#include "dawn_native/ObjectBase.h"
|
||||
|
||||
#include "dawn_native/dawn_platform.h"
|
||||
|
||||
#include <array>
|
||||
#include <bitset>
|
||||
|
||||
namespace dawn_native {
|
||||
|
||||
size_t IndexFormatSize(dawn::IndexFormat format);
|
||||
uint32_t VertexFormatNumComponents(dawn::VertexFormat format);
|
||||
size_t VertexFormatComponentSize(dawn::VertexFormat format);
|
||||
size_t VertexFormatSize(dawn::VertexFormat format);
|
||||
|
||||
class InputStateBase : public ObjectBase {
|
||||
public:
|
||||
InputStateBase(InputStateBuilder* builder);
|
||||
|
||||
const std::bitset<kMaxVertexAttributes>& GetAttributesSetMask() const;
|
||||
const VertexAttributeDescriptor& GetAttribute(uint32_t location) const;
|
||||
const std::bitset<kMaxVertexInputs>& GetInputsSetMask() const;
|
||||
const VertexInputDescriptor& GetInput(uint32_t slot) const;
|
||||
|
||||
private:
|
||||
std::bitset<kMaxVertexAttributes> mAttributesSetMask;
|
||||
std::array<VertexAttributeDescriptor, kMaxVertexAttributes> mAttributeInfos;
|
||||
std::bitset<kMaxVertexInputs> mInputsSetMask;
|
||||
std::array<VertexInputDescriptor, kMaxVertexInputs> mInputInfos;
|
||||
};
|
||||
|
||||
class InputStateBuilder : public Builder<InputStateBase> {
|
||||
public:
|
||||
InputStateBuilder(DeviceBase* device);
|
||||
|
||||
// Dawn API
|
||||
void SetAttribute(const VertexAttributeDescriptor* attribute);
|
||||
void SetInput(const VertexInputDescriptor* input);
|
||||
|
||||
private:
|
||||
friend class InputStateBase;
|
||||
|
||||
InputStateBase* GetResultImpl() override;
|
||||
|
||||
std::bitset<kMaxVertexAttributes> mAttributesSetMask;
|
||||
std::array<VertexAttributeDescriptor, kMaxVertexAttributes> mAttributeInfos;
|
||||
std::bitset<kMaxVertexInputs> mInputsSetMask;
|
||||
std::array<VertexInputDescriptor, kMaxVertexInputs> mInputInfos;
|
||||
};
|
||||
|
||||
} // namespace dawn_native
|
||||
|
||||
#endif // DAWNNATIVE_INPUTSTATE_H_
|
|
@ -15,7 +15,6 @@
|
|||
#include "dawn_native/Pipeline.h"
|
||||
|
||||
#include "dawn_native/Device.h"
|
||||
#include "dawn_native/InputState.h"
|
||||
#include "dawn_native/PipelineLayout.h"
|
||||
#include "dawn_native/ShaderModule.h"
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include "common/BitSetIterator.h"
|
||||
#include "dawn_native/Commands.h"
|
||||
#include "dawn_native/Device.h"
|
||||
#include "dawn_native/InputState.h"
|
||||
#include "dawn_native/Texture.h"
|
||||
#include "dawn_native/ValidationUtils_autogen.h"
|
||||
|
||||
|
@ -25,6 +24,77 @@ namespace dawn_native {
|
|||
// Helper functions
|
||||
namespace {
|
||||
|
||||
MaybeError ValidateVertexInputDescriptor(const VertexInputDescriptor* input,
|
||||
std::bitset<kMaxVertexInputs>* inputsSetMask) {
|
||||
DAWN_TRY(ValidateInputStepMode(input->stepMode));
|
||||
if (input->inputSlot >= kMaxVertexInputs) {
|
||||
return DAWN_VALIDATION_ERROR("Setting input out of bounds");
|
||||
}
|
||||
if (input->stride > kMaxVertexInputStride) {
|
||||
return DAWN_VALIDATION_ERROR("Setting input stride out of bounds");
|
||||
}
|
||||
if ((*inputsSetMask)[input->inputSlot]) {
|
||||
return DAWN_VALIDATION_ERROR("Setting already set input");
|
||||
}
|
||||
|
||||
inputsSetMask->set(input->inputSlot);
|
||||
return {};
|
||||
}
|
||||
|
||||
MaybeError ValidateVertexAttributeDescriptor(
|
||||
const VertexAttributeDescriptor* attribute,
|
||||
const std::bitset<kMaxVertexInputs>* inputsSetMask,
|
||||
std::bitset<kMaxVertexAttributes>* attributesSetMask) {
|
||||
DAWN_TRY(ValidateVertexFormat(attribute->format));
|
||||
|
||||
if (attribute->shaderLocation >= kMaxVertexAttributes) {
|
||||
return DAWN_VALIDATION_ERROR("Setting attribute out of bounds");
|
||||
}
|
||||
if (attribute->inputSlot >= kMaxVertexInputs) {
|
||||
return DAWN_VALIDATION_ERROR("Binding slot out of bounds");
|
||||
}
|
||||
ASSERT(kMaxVertexAttributeEnd >= VertexFormatSize(attribute->format));
|
||||
if (attribute->offset > kMaxVertexAttributeEnd - VertexFormatSize(attribute->format)) {
|
||||
return DAWN_VALIDATION_ERROR("Setting attribute offset out of bounds");
|
||||
}
|
||||
if ((*attributesSetMask)[attribute->shaderLocation]) {
|
||||
return DAWN_VALIDATION_ERROR("Setting already set attribute");
|
||||
}
|
||||
if (!(*inputsSetMask)[attribute->inputSlot]) {
|
||||
return DAWN_VALIDATION_ERROR(
|
||||
"Vertex attribute slot doesn't match any vertex input slot");
|
||||
}
|
||||
|
||||
attributesSetMask->set(attribute->shaderLocation);
|
||||
return {};
|
||||
}
|
||||
|
||||
MaybeError ValidateInputStateDescriptor(
|
||||
const InputStateDescriptor* descriptor,
|
||||
std::bitset<kMaxVertexInputs>* inputsSetMask,
|
||||
std::bitset<kMaxVertexAttributes>* attributesSetMask) {
|
||||
if (descriptor->nextInChain != nullptr) {
|
||||
return DAWN_VALIDATION_ERROR("nextInChain must be nullptr");
|
||||
}
|
||||
if (descriptor->numInputs > kMaxVertexInputs) {
|
||||
return DAWN_VALIDATION_ERROR("Vertex Inputs number exceeds maximum");
|
||||
}
|
||||
if (descriptor->numAttributes > kMaxVertexAttributes) {
|
||||
return DAWN_VALIDATION_ERROR("Vertex Attributes number exceeds maximum");
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < descriptor->numInputs; ++i) {
|
||||
DAWN_TRY(ValidateVertexInputDescriptor(&descriptor->inputs[i], inputsSetMask));
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < descriptor->numAttributes; ++i) {
|
||||
DAWN_TRY(ValidateVertexAttributeDescriptor(&descriptor->attributes[i],
|
||||
inputsSetMask, attributesSetMask));
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
MaybeError ValidatePipelineStageDescriptor(DeviceBase* device,
|
||||
const PipelineStageDescriptor* descriptor,
|
||||
const PipelineLayoutBase* layout,
|
||||
|
@ -91,6 +161,104 @@ namespace dawn_native {
|
|||
|
||||
} // anonymous namespace
|
||||
|
||||
// Helper functions
|
||||
size_t IndexFormatSize(dawn::IndexFormat format) {
|
||||
switch (format) {
|
||||
case dawn::IndexFormat::Uint16:
|
||||
return sizeof(uint16_t);
|
||||
case dawn::IndexFormat::Uint32:
|
||||
return sizeof(uint32_t);
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t VertexFormatNumComponents(dawn::VertexFormat format) {
|
||||
switch (format) {
|
||||
case dawn::VertexFormat::UChar4:
|
||||
case dawn::VertexFormat::Char4:
|
||||
case dawn::VertexFormat::UChar4Norm:
|
||||
case dawn::VertexFormat::Char4Norm:
|
||||
case dawn::VertexFormat::UShort4:
|
||||
case dawn::VertexFormat::Short4:
|
||||
case dawn::VertexFormat::UShort4Norm:
|
||||
case dawn::VertexFormat::Short4Norm:
|
||||
case dawn::VertexFormat::Half4:
|
||||
case dawn::VertexFormat::Float4:
|
||||
case dawn::VertexFormat::UInt4:
|
||||
case dawn::VertexFormat::Int4:
|
||||
return 4;
|
||||
case dawn::VertexFormat::Float3:
|
||||
case dawn::VertexFormat::UInt3:
|
||||
case dawn::VertexFormat::Int3:
|
||||
return 3;
|
||||
case dawn::VertexFormat::UChar2:
|
||||
case dawn::VertexFormat::Char2:
|
||||
case dawn::VertexFormat::UChar2Norm:
|
||||
case dawn::VertexFormat::Char2Norm:
|
||||
case dawn::VertexFormat::UShort2:
|
||||
case dawn::VertexFormat::Short2:
|
||||
case dawn::VertexFormat::UShort2Norm:
|
||||
case dawn::VertexFormat::Short2Norm:
|
||||
case dawn::VertexFormat::Half2:
|
||||
case dawn::VertexFormat::Float2:
|
||||
case dawn::VertexFormat::UInt2:
|
||||
case dawn::VertexFormat::Int2:
|
||||
return 2;
|
||||
case dawn::VertexFormat::Float:
|
||||
case dawn::VertexFormat::UInt:
|
||||
case dawn::VertexFormat::Int:
|
||||
return 1;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
size_t VertexFormatComponentSize(dawn::VertexFormat format) {
|
||||
switch (format) {
|
||||
case dawn::VertexFormat::UChar2:
|
||||
case dawn::VertexFormat::UChar4:
|
||||
case dawn::VertexFormat::Char2:
|
||||
case dawn::VertexFormat::Char4:
|
||||
case dawn::VertexFormat::UChar2Norm:
|
||||
case dawn::VertexFormat::UChar4Norm:
|
||||
case dawn::VertexFormat::Char2Norm:
|
||||
case dawn::VertexFormat::Char4Norm:
|
||||
return sizeof(char);
|
||||
case dawn::VertexFormat::UShort2:
|
||||
case dawn::VertexFormat::UShort4:
|
||||
case dawn::VertexFormat::UShort2Norm:
|
||||
case dawn::VertexFormat::UShort4Norm:
|
||||
case dawn::VertexFormat::Short2:
|
||||
case dawn::VertexFormat::Short4:
|
||||
case dawn::VertexFormat::Short2Norm:
|
||||
case dawn::VertexFormat::Short4Norm:
|
||||
case dawn::VertexFormat::Half2:
|
||||
case dawn::VertexFormat::Half4:
|
||||
return sizeof(uint16_t);
|
||||
case dawn::VertexFormat::Float:
|
||||
case dawn::VertexFormat::Float2:
|
||||
case dawn::VertexFormat::Float3:
|
||||
case dawn::VertexFormat::Float4:
|
||||
return sizeof(float);
|
||||
case dawn::VertexFormat::UInt:
|
||||
case dawn::VertexFormat::UInt2:
|
||||
case dawn::VertexFormat::UInt3:
|
||||
case dawn::VertexFormat::UInt4:
|
||||
case dawn::VertexFormat::Int:
|
||||
case dawn::VertexFormat::Int2:
|
||||
case dawn::VertexFormat::Int3:
|
||||
case dawn::VertexFormat::Int4:
|
||||
return sizeof(int32_t);
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
size_t VertexFormatSize(dawn::VertexFormat format) {
|
||||
return VertexFormatNumComponents(format) * VertexFormatComponentSize(format);
|
||||
}
|
||||
|
||||
MaybeError ValidateRenderPipelineDescriptor(DeviceBase* device,
|
||||
const RenderPipelineDescriptor* descriptor) {
|
||||
if (descriptor->nextInChain != nullptr) {
|
||||
|
@ -104,14 +272,17 @@ namespace dawn_native {
|
|||
}
|
||||
|
||||
DAWN_TRY(ValidateIndexFormat(descriptor->indexFormat));
|
||||
std::bitset<kMaxVertexInputs> inputsSetMask;
|
||||
std::bitset<kMaxVertexAttributes> attributesSetMask;
|
||||
DAWN_TRY(ValidateInputStateDescriptor(descriptor->inputState, &inputsSetMask,
|
||||
&attributesSetMask));
|
||||
DAWN_TRY(ValidatePrimitiveTopology(descriptor->primitiveTopology));
|
||||
DAWN_TRY(ValidatePipelineStageDescriptor(device, descriptor->vertexStage,
|
||||
descriptor->layout, dawn::ShaderStage::Vertex));
|
||||
DAWN_TRY(ValidatePipelineStageDescriptor(device, descriptor->fragmentStage,
|
||||
descriptor->layout, dawn::ShaderStage::Fragment));
|
||||
|
||||
if ((descriptor->vertexStage->module->GetUsedVertexAttributes() &
|
||||
~descriptor->inputState->GetAttributesSetMask())
|
||||
if ((descriptor->vertexStage->module->GetUsedVertexAttributes() & ~attributesSetMask)
|
||||
.any()) {
|
||||
return DAWN_VALIDATION_ERROR(
|
||||
"Pipeline vertex stage uses inputs not in the input state");
|
||||
|
@ -168,10 +339,23 @@ namespace dawn_native {
|
|||
descriptor->layout,
|
||||
dawn::ShaderStageBit::Vertex | dawn::ShaderStageBit::Fragment),
|
||||
mIndexFormat(descriptor->indexFormat),
|
||||
mInputState(descriptor->inputState),
|
||||
mInputState(*descriptor->inputState),
|
||||
mPrimitiveTopology(descriptor->primitiveTopology),
|
||||
mHasDepthStencilAttachment(descriptor->depthStencilState != nullptr),
|
||||
mSampleCount(descriptor->sampleCount) {
|
||||
uint32_t location = 0;
|
||||
for (uint32_t i = 0; i < mInputState.numAttributes; ++i) {
|
||||
location = mInputState.attributes[i].shaderLocation;
|
||||
mAttributesSetMask.set(location);
|
||||
mAttributeInfos[location] = mInputState.attributes[i];
|
||||
}
|
||||
uint32_t slot = 0;
|
||||
for (uint32_t i = 0; i < mInputState.numInputs; ++i) {
|
||||
slot = mInputState.inputs[i].inputSlot;
|
||||
mInputsSetMask.set(slot);
|
||||
mInputInfos[slot] = mInputState.inputs[i];
|
||||
}
|
||||
|
||||
if (mHasDepthStencilAttachment) {
|
||||
mDepthStencilState = *descriptor->depthStencilState;
|
||||
} else {
|
||||
|
@ -213,6 +397,33 @@ namespace dawn_native {
|
|||
return new RenderPipelineBase(device, ObjectBase::kError);
|
||||
}
|
||||
|
||||
const InputStateDescriptor* RenderPipelineBase::GetInputStateDescriptor() const {
|
||||
ASSERT(!IsError());
|
||||
return &mInputState;
|
||||
}
|
||||
|
||||
const std::bitset<kMaxVertexAttributes>& RenderPipelineBase::GetAttributesSetMask() const {
|
||||
ASSERT(!IsError());
|
||||
return mAttributesSetMask;
|
||||
}
|
||||
|
||||
const VertexAttributeDescriptor& RenderPipelineBase::GetAttribute(uint32_t location) const {
|
||||
ASSERT(!IsError());
|
||||
ASSERT(mAttributesSetMask[location]);
|
||||
return mAttributeInfos[location];
|
||||
}
|
||||
|
||||
const std::bitset<kMaxVertexInputs>& RenderPipelineBase::GetInputsSetMask() const {
|
||||
ASSERT(!IsError());
|
||||
return mInputsSetMask;
|
||||
}
|
||||
|
||||
const VertexInputDescriptor& RenderPipelineBase::GetInput(uint32_t slot) const {
|
||||
ASSERT(!IsError());
|
||||
ASSERT(mInputsSetMask[slot]);
|
||||
return mInputInfos[slot];
|
||||
}
|
||||
|
||||
const ColorStateDescriptor* RenderPipelineBase::GetColorStateDescriptor(
|
||||
uint32_t attachmentSlot) {
|
||||
ASSERT(!IsError());
|
||||
|
@ -230,11 +441,6 @@ namespace dawn_native {
|
|||
return mIndexFormat;
|
||||
}
|
||||
|
||||
InputStateBase* RenderPipelineBase::GetInputState() {
|
||||
ASSERT(!IsError());
|
||||
return mInputState.Get();
|
||||
}
|
||||
|
||||
dawn::PrimitiveTopology RenderPipelineBase::GetPrimitiveTopology() const {
|
||||
ASSERT(!IsError());
|
||||
return mPrimitiveTopology;
|
||||
|
@ -293,4 +499,10 @@ namespace dawn_native {
|
|||
return true;
|
||||
}
|
||||
|
||||
std::bitset<kMaxVertexAttributes> RenderPipelineBase::GetAttributesUsingInput(
|
||||
uint32_t slot) const {
|
||||
ASSERT(!IsError());
|
||||
return attributesUsingInput[slot];
|
||||
}
|
||||
|
||||
} // namespace dawn_native
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#ifndef DAWNNATIVE_RENDERPIPELINE_H_
|
||||
#define DAWNNATIVE_RENDERPIPELINE_H_
|
||||
|
||||
#include "dawn_native/InputState.h"
|
||||
#include "dawn_native/Pipeline.h"
|
||||
|
||||
#include "dawn_native/dawn_platform.h"
|
||||
|
@ -31,6 +30,11 @@ namespace dawn_native {
|
|||
|
||||
MaybeError ValidateRenderPipelineDescriptor(DeviceBase* device,
|
||||
const RenderPipelineDescriptor* descriptor);
|
||||
size_t IndexFormatSize(dawn::IndexFormat format);
|
||||
uint32_t VertexFormatNumComponents(dawn::VertexFormat format);
|
||||
size_t VertexFormatComponentSize(dawn::VertexFormat format);
|
||||
size_t VertexFormatSize(dawn::VertexFormat format);
|
||||
|
||||
bool StencilTestEnabled(const DepthStencilStateDescriptor* mDepthStencilState);
|
||||
bool BlendEnabled(const ColorStateDescriptor* mColorState);
|
||||
|
||||
|
@ -40,10 +44,15 @@ namespace dawn_native {
|
|||
|
||||
static RenderPipelineBase* MakeError(DeviceBase* device);
|
||||
|
||||
const InputStateDescriptor* GetInputStateDescriptor() const;
|
||||
const std::bitset<kMaxVertexAttributes>& GetAttributesSetMask() const;
|
||||
const VertexAttributeDescriptor& GetAttribute(uint32_t location) const;
|
||||
const std::bitset<kMaxVertexInputs>& GetInputsSetMask() const;
|
||||
const VertexInputDescriptor& GetInput(uint32_t slot) const;
|
||||
|
||||
const ColorStateDescriptor* GetColorStateDescriptor(uint32_t attachmentSlot);
|
||||
const DepthStencilStateDescriptor* GetDepthStencilStateDescriptor();
|
||||
dawn::IndexFormat GetIndexFormat() const;
|
||||
InputStateBase* GetInputState();
|
||||
dawn::PrimitiveTopology GetPrimitiveTopology() const;
|
||||
|
||||
std::bitset<kMaxColorAttachments> GetColorAttachmentsMask() const;
|
||||
|
@ -54,14 +63,20 @@ namespace dawn_native {
|
|||
// A pipeline can be used in a render pass if its attachment info matches the actual
|
||||
// attachments in the render pass. This returns whether it is the case.
|
||||
bool IsCompatibleWith(const BeginRenderPassCmd* renderPassCmd) const;
|
||||
std::bitset<kMaxVertexAttributes> GetAttributesUsingInput(uint32_t slot) const;
|
||||
std::array<std::bitset<kMaxVertexAttributes>, kMaxVertexInputs> attributesUsingInput;
|
||||
|
||||
private:
|
||||
RenderPipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag);
|
||||
|
||||
DepthStencilStateDescriptor mDepthStencilState;
|
||||
dawn::IndexFormat mIndexFormat;
|
||||
Ref<InputStateBase> mInputState;
|
||||
InputStateDescriptor mInputState;
|
||||
std::bitset<kMaxVertexAttributes> mAttributesSetMask;
|
||||
std::array<VertexAttributeDescriptor, kMaxVertexAttributes> mAttributeInfos;
|
||||
std::bitset<kMaxVertexInputs> mInputsSetMask;
|
||||
std::array<VertexInputDescriptor, kMaxVertexInputs> mInputInfos;
|
||||
dawn::PrimitiveTopology mPrimitiveTopology;
|
||||
DepthStencilStateDescriptor mDepthStencilState;
|
||||
std::array<ColorStateDescriptor, kMaxColorAttachments> mColorStates;
|
||||
|
||||
std::bitset<kMaxColorAttachments> mColorAttachmentsSet;
|
||||
|
|
|
@ -58,11 +58,6 @@ namespace dawn_native {
|
|||
using BackendType = typename BackendTraits::DeviceType;
|
||||
};
|
||||
|
||||
template <typename BackendTraits>
|
||||
struct ToBackendTraits<InputStateBase, BackendTraits> {
|
||||
using BackendType = typename BackendTraits::InputStateType;
|
||||
};
|
||||
|
||||
template <typename BackendTraits>
|
||||
struct ToBackendTraits<PipelineLayoutBase, BackendTraits> {
|
||||
using BackendType = typename BackendTraits::PipelineLayoutType;
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "dawn_native/d3d12/ComputePipelineD3D12.h"
|
||||
#include "dawn_native/d3d12/DescriptorHeapAllocator.h"
|
||||
#include "dawn_native/d3d12/DeviceD3D12.h"
|
||||
#include "dawn_native/d3d12/InputStateD3D12.h"
|
||||
#include "dawn_native/d3d12/PipelineLayoutD3D12.h"
|
||||
#include "dawn_native/d3d12/RenderPipelineD3D12.h"
|
||||
#include "dawn_native/d3d12/ResourceAllocator.h"
|
||||
|
@ -576,11 +575,11 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
void CommandBuffer::FlushSetVertexBuffers(ComPtr<ID3D12GraphicsCommandList> commandList,
|
||||
VertexBuffersInfo* vertexBuffersInfo,
|
||||
const InputState* inputState) {
|
||||
const RenderPipeline* renderPipeline) {
|
||||
DAWN_ASSERT(vertexBuffersInfo != nullptr);
|
||||
DAWN_ASSERT(inputState != nullptr);
|
||||
DAWN_ASSERT(renderPipeline != nullptr);
|
||||
|
||||
auto inputsMask = inputState->GetInputsSetMask();
|
||||
auto inputsMask = renderPipeline->GetInputsSetMask();
|
||||
|
||||
uint32_t startSlot = vertexBuffersInfo->startSlot;
|
||||
uint32_t endSlot = vertexBuffersInfo->endSlot;
|
||||
|
@ -588,14 +587,14 @@ namespace dawn_native { namespace d3d12 {
|
|||
// If the input state has changed, we need to update the StrideInBytes
|
||||
// for the D3D12 buffer views. We also need to extend the dirty range to
|
||||
// touch all these slots because the stride may have changed.
|
||||
if (vertexBuffersInfo->lastInputState != inputState) {
|
||||
vertexBuffersInfo->lastInputState = inputState;
|
||||
if (vertexBuffersInfo->lastRenderPipeline != renderPipeline) {
|
||||
vertexBuffersInfo->lastRenderPipeline = renderPipeline;
|
||||
|
||||
for (uint32_t slot : IterateBitSet(inputsMask)) {
|
||||
startSlot = std::min(startSlot, slot);
|
||||
endSlot = std::max(endSlot, slot + 1);
|
||||
vertexBuffersInfo->d3d12BufferViews[slot].StrideInBytes =
|
||||
inputState->GetInput(slot).stride;
|
||||
renderPipeline->GetInput(slot).stride;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -728,7 +727,6 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
RenderPipeline* lastPipeline = nullptr;
|
||||
PipelineLayout* lastLayout = nullptr;
|
||||
InputState* lastInputState = nullptr;
|
||||
VertexBuffersInfo vertexBuffersInfo = {};
|
||||
|
||||
Command type;
|
||||
|
@ -742,7 +740,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
case Command::Draw: {
|
||||
DrawCmd* draw = mCommands.NextCommand<DrawCmd>();
|
||||
|
||||
FlushSetVertexBuffers(commandList, &vertexBuffersInfo, lastInputState);
|
||||
FlushSetVertexBuffers(commandList, &vertexBuffersInfo, lastPipeline);
|
||||
commandList->DrawInstanced(draw->vertexCount, draw->instanceCount,
|
||||
draw->firstVertex, draw->firstInstance);
|
||||
} break;
|
||||
|
@ -750,7 +748,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
case Command::DrawIndexed: {
|
||||
DrawIndexedCmd* draw = mCommands.NextCommand<DrawIndexedCmd>();
|
||||
|
||||
FlushSetVertexBuffers(commandList, &vertexBuffersInfo, lastInputState);
|
||||
FlushSetVertexBuffers(commandList, &vertexBuffersInfo, lastPipeline);
|
||||
commandList->DrawIndexedInstanced(draw->indexCount, draw->instanceCount,
|
||||
draw->firstIndex, draw->baseVertex,
|
||||
draw->firstInstance);
|
||||
|
@ -768,7 +766,6 @@ namespace dawn_native { namespace d3d12 {
|
|||
SetRenderPipelineCmd* cmd = mCommands.NextCommand<SetRenderPipelineCmd>();
|
||||
RenderPipeline* pipeline = ToBackend(cmd->pipeline).Get();
|
||||
PipelineLayout* layout = ToBackend(pipeline->GetLayout());
|
||||
InputState* inputState = ToBackend(pipeline->GetInputState());
|
||||
|
||||
commandList->SetGraphicsRootSignature(layout->GetRootSignature().Get());
|
||||
commandList->SetPipelineState(pipeline->GetPipelineState().Get());
|
||||
|
@ -778,7 +775,6 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
lastPipeline = pipeline;
|
||||
lastLayout = layout;
|
||||
lastInputState = inputState;
|
||||
} break;
|
||||
|
||||
case Command::SetStencilReference: {
|
||||
|
|
|
@ -15,13 +15,15 @@
|
|||
#ifndef DAWNNATIVE_D3D12_COMMANDBUFFERD3D12_H_
|
||||
#define DAWNNATIVE_D3D12_COMMANDBUFFERD3D12_H_
|
||||
|
||||
#include "common/Constants.h"
|
||||
#include "dawn_native/CommandAllocator.h"
|
||||
#include "dawn_native/CommandBuffer.h"
|
||||
|
||||
#include "dawn_native/d3d12/Forward.h"
|
||||
#include "dawn_native/d3d12/InputStateD3D12.h"
|
||||
#include "dawn_native/d3d12/d3d12_platform.h"
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace dawn_native {
|
||||
struct BeginRenderPassCmd;
|
||||
} // namespace dawn_native
|
||||
|
@ -30,6 +32,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
class Device;
|
||||
class RenderPassDescriptorHeapTracker;
|
||||
class RenderPipeline;
|
||||
|
||||
struct BindGroupStateTracker;
|
||||
|
||||
|
@ -38,7 +41,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
// If there are multiple calls to SetVertexBuffers, the start and end
|
||||
// represent the union of the dirty ranges (the union may have non-dirty
|
||||
// data in the middle of the range).
|
||||
const InputState* lastInputState = nullptr;
|
||||
const RenderPipeline* lastRenderPipeline = nullptr;
|
||||
uint32_t startSlot = kMaxVertexInputs;
|
||||
uint32_t endSlot = 0;
|
||||
std::array<D3D12_VERTEX_BUFFER_VIEW, kMaxVertexInputs> d3d12BufferViews = {};
|
||||
|
@ -54,7 +57,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
private:
|
||||
void FlushSetVertexBuffers(ComPtr<ID3D12GraphicsCommandList> commandList,
|
||||
VertexBuffersInfo* vertexBuffersInfo,
|
||||
const InputState* inputState);
|
||||
const RenderPipeline* lastRenderPipeline);
|
||||
void RecordComputePass(ComPtr<ID3D12GraphicsCommandList> commandList,
|
||||
BindGroupStateTracker* bindingTracker);
|
||||
void RecordRenderPass(ComPtr<ID3D12GraphicsCommandList> commandList,
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include "dawn_native/d3d12/CommandBufferD3D12.h"
|
||||
#include "dawn_native/d3d12/ComputePipelineD3D12.h"
|
||||
#include "dawn_native/d3d12/DescriptorHeapAllocator.h"
|
||||
#include "dawn_native/d3d12/InputStateD3D12.h"
|
||||
#include "dawn_native/d3d12/PipelineLayoutD3D12.h"
|
||||
#include "dawn_native/d3d12/PlatformFunctions.h"
|
||||
#include "dawn_native/d3d12/QueueD3D12.h"
|
||||
|
@ -216,9 +215,6 @@ namespace dawn_native { namespace d3d12 {
|
|||
const ComputePipelineDescriptor* descriptor) {
|
||||
return new ComputePipeline(this, descriptor);
|
||||
}
|
||||
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
|
||||
return new InputState(builder);
|
||||
}
|
||||
ResultOrError<PipelineLayoutBase*> Device::CreatePipelineLayoutImpl(
|
||||
const PipelineLayoutDescriptor* descriptor) {
|
||||
return new PipelineLayout(this, descriptor);
|
||||
|
|
|
@ -41,7 +41,6 @@ namespace dawn_native { namespace d3d12 {
|
|||
~Device();
|
||||
|
||||
CommandBufferBase* CreateCommandBuffer(CommandEncoderBase* encoder) override;
|
||||
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
|
||||
|
||||
Serial GetCompletedCommandSerial() const final override;
|
||||
Serial GetLastSubmittedCommandSerial() const final override;
|
||||
|
|
|
@ -26,7 +26,6 @@ namespace dawn_native { namespace d3d12 {
|
|||
class CommandBuffer;
|
||||
class ComputePipeline;
|
||||
class Device;
|
||||
class InputState;
|
||||
class PipelineLayout;
|
||||
class Queue;
|
||||
class RenderPipeline;
|
||||
|
@ -45,7 +44,6 @@ namespace dawn_native { namespace d3d12 {
|
|||
using CommandBufferType = CommandBuffer;
|
||||
using ComputePipelineType = ComputePipeline;
|
||||
using DeviceType = Device;
|
||||
using InputStateType = InputState;
|
||||
using PipelineLayoutType = PipelineLayout;
|
||||
using QueueType = Queue;
|
||||
using RenderPipelineType = RenderPipeline;
|
||||
|
|
|
@ -1,139 +0,0 @@
|
|||
// Copyright 2017 The Dawn 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 "dawn_native/d3d12/InputStateD3D12.h"
|
||||
|
||||
#include "common/BitSetIterator.h"
|
||||
|
||||
namespace dawn_native { namespace d3d12 {
|
||||
|
||||
static DXGI_FORMAT VertexFormatType(dawn::VertexFormat format) {
|
||||
switch (format) {
|
||||
case dawn::VertexFormat::UChar2:
|
||||
return DXGI_FORMAT_R8G8_UINT;
|
||||
case dawn::VertexFormat::UChar4:
|
||||
return DXGI_FORMAT_R8G8B8A8_UINT;
|
||||
case dawn::VertexFormat::Char2:
|
||||
return DXGI_FORMAT_R8G8_SINT;
|
||||
case dawn::VertexFormat::Char4:
|
||||
return DXGI_FORMAT_R8G8B8A8_SINT;
|
||||
case dawn::VertexFormat::UChar2Norm:
|
||||
return DXGI_FORMAT_R8G8_UNORM;
|
||||
case dawn::VertexFormat::UChar4Norm:
|
||||
return DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
case dawn::VertexFormat::Char2Norm:
|
||||
return DXGI_FORMAT_R8G8_SNORM;
|
||||
case dawn::VertexFormat::Char4Norm:
|
||||
return DXGI_FORMAT_R8G8B8A8_SNORM;
|
||||
case dawn::VertexFormat::UShort2:
|
||||
return DXGI_FORMAT_R16G16_UINT;
|
||||
case dawn::VertexFormat::UShort4:
|
||||
return DXGI_FORMAT_R16G16B16A16_UINT;
|
||||
case dawn::VertexFormat::Short2:
|
||||
return DXGI_FORMAT_R16G16_SINT;
|
||||
case dawn::VertexFormat::Short4:
|
||||
return DXGI_FORMAT_R16G16B16A16_SINT;
|
||||
case dawn::VertexFormat::UShort2Norm:
|
||||
return DXGI_FORMAT_R16G16_UNORM;
|
||||
case dawn::VertexFormat::UShort4Norm:
|
||||
return DXGI_FORMAT_R16G16B16A16_UNORM;
|
||||
case dawn::VertexFormat::Short2Norm:
|
||||
return DXGI_FORMAT_R16G16_SNORM;
|
||||
case dawn::VertexFormat::Short4Norm:
|
||||
return DXGI_FORMAT_R16G16B16A16_SNORM;
|
||||
case dawn::VertexFormat::Half2:
|
||||
return DXGI_FORMAT_R16G16_FLOAT;
|
||||
case dawn::VertexFormat::Half4:
|
||||
return DXGI_FORMAT_R16G16B16A16_FLOAT;
|
||||
case dawn::VertexFormat::Float:
|
||||
return DXGI_FORMAT_R32_FLOAT;
|
||||
case dawn::VertexFormat::Float2:
|
||||
return DXGI_FORMAT_R32G32_FLOAT;
|
||||
case dawn::VertexFormat::Float3:
|
||||
return DXGI_FORMAT_R32G32B32_FLOAT;
|
||||
case dawn::VertexFormat::Float4:
|
||||
return DXGI_FORMAT_R32G32B32A32_FLOAT;
|
||||
case dawn::VertexFormat::UInt:
|
||||
return DXGI_FORMAT_R32_UINT;
|
||||
case dawn::VertexFormat::UInt2:
|
||||
return DXGI_FORMAT_R32G32_UINT;
|
||||
case dawn::VertexFormat::UInt3:
|
||||
return DXGI_FORMAT_R32G32B32_UINT;
|
||||
case dawn::VertexFormat::UInt4:
|
||||
return DXGI_FORMAT_R32G32B32A32_UINT;
|
||||
case dawn::VertexFormat::Int:
|
||||
return DXGI_FORMAT_R32_SINT;
|
||||
case dawn::VertexFormat::Int2:
|
||||
return DXGI_FORMAT_R32G32_SINT;
|
||||
case dawn::VertexFormat::Int3:
|
||||
return DXGI_FORMAT_R32G32B32_SINT;
|
||||
case dawn::VertexFormat::Int4:
|
||||
return DXGI_FORMAT_R32G32B32A32_SINT;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
static D3D12_INPUT_CLASSIFICATION InputStepModeFunction(dawn::InputStepMode mode) {
|
||||
switch (mode) {
|
||||
case dawn::InputStepMode::Vertex:
|
||||
return D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA;
|
||||
case dawn::InputStepMode::Instance:
|
||||
return D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
InputState::InputState(InputStateBuilder* builder) : InputStateBase(builder) {
|
||||
const auto& attributesSetMask = GetAttributesSetMask();
|
||||
|
||||
unsigned int count = 0;
|
||||
for (auto i : IterateBitSet(attributesSetMask)) {
|
||||
if (!attributesSetMask[i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
D3D12_INPUT_ELEMENT_DESC& inputElementDescriptor = mInputElementDescriptors[count++];
|
||||
|
||||
const VertexAttributeDescriptor& attribute = GetAttribute(i);
|
||||
|
||||
// If the HLSL semantic is TEXCOORDN the SemanticName should be "TEXCOORD" and the
|
||||
// SemanticIndex N
|
||||
inputElementDescriptor.SemanticName = "TEXCOORD";
|
||||
inputElementDescriptor.SemanticIndex = static_cast<uint32_t>(i);
|
||||
inputElementDescriptor.Format = VertexFormatType(attribute.format);
|
||||
inputElementDescriptor.InputSlot = attribute.inputSlot;
|
||||
|
||||
const VertexInputDescriptor& input = GetInput(attribute.inputSlot);
|
||||
|
||||
inputElementDescriptor.AlignedByteOffset = attribute.offset;
|
||||
inputElementDescriptor.InputSlotClass = InputStepModeFunction(input.stepMode);
|
||||
if (inputElementDescriptor.InputSlotClass ==
|
||||
D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA) {
|
||||
inputElementDescriptor.InstanceDataStepRate = 0;
|
||||
} else {
|
||||
inputElementDescriptor.InstanceDataStepRate = 1;
|
||||
}
|
||||
}
|
||||
|
||||
mInputLayoutDescriptor.pInputElementDescs = mInputElementDescriptors;
|
||||
mInputLayoutDescriptor.NumElements = count;
|
||||
}
|
||||
|
||||
const D3D12_INPUT_LAYOUT_DESC& InputState::GetD3D12InputLayoutDescriptor() const {
|
||||
return mInputLayoutDescriptor;
|
||||
}
|
||||
|
||||
}} // namespace dawn_native::d3d12
|
|
@ -1,39 +0,0 @@
|
|||
// Copyright 2017 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef DAWNNATIVE_D3D12_INPUTSTATED3D12_H_
|
||||
#define DAWNNATIVE_D3D12_INPUTSTATED3D12_H_
|
||||
|
||||
#include "dawn_native/InputState.h"
|
||||
|
||||
#include "dawn_native/d3d12/d3d12_platform.h"
|
||||
|
||||
namespace dawn_native { namespace d3d12 {
|
||||
|
||||
class Device;
|
||||
|
||||
class InputState : public InputStateBase {
|
||||
public:
|
||||
InputState(InputStateBuilder* builder);
|
||||
|
||||
const D3D12_INPUT_LAYOUT_DESC& GetD3D12InputLayoutDescriptor() const;
|
||||
|
||||
private:
|
||||
D3D12_INPUT_LAYOUT_DESC mInputLayoutDescriptor;
|
||||
D3D12_INPUT_ELEMENT_DESC mInputElementDescriptors[kMaxVertexAttributes];
|
||||
};
|
||||
|
||||
}} // namespace dawn_native::d3d12
|
||||
|
||||
#endif // DAWNNATIVE_D3D12_INPUTSTATED3D12_H_
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
#include "common/Assert.h"
|
||||
#include "dawn_native/d3d12/DeviceD3D12.h"
|
||||
#include "dawn_native/d3d12/InputStateD3D12.h"
|
||||
#include "dawn_native/d3d12/PipelineLayoutD3D12.h"
|
||||
#include "dawn_native/d3d12/PlatformFunctions.h"
|
||||
#include "dawn_native/d3d12/ShaderModuleD3D12.h"
|
||||
|
@ -28,6 +27,84 @@
|
|||
namespace dawn_native { namespace d3d12 {
|
||||
|
||||
namespace {
|
||||
DXGI_FORMAT VertexFormatType(dawn::VertexFormat format) {
|
||||
switch (format) {
|
||||
case dawn::VertexFormat::UChar2:
|
||||
return DXGI_FORMAT_R8G8_UINT;
|
||||
case dawn::VertexFormat::UChar4:
|
||||
return DXGI_FORMAT_R8G8B8A8_UINT;
|
||||
case dawn::VertexFormat::Char2:
|
||||
return DXGI_FORMAT_R8G8_SINT;
|
||||
case dawn::VertexFormat::Char4:
|
||||
return DXGI_FORMAT_R8G8B8A8_SINT;
|
||||
case dawn::VertexFormat::UChar2Norm:
|
||||
return DXGI_FORMAT_R8G8_UNORM;
|
||||
case dawn::VertexFormat::UChar4Norm:
|
||||
return DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
case dawn::VertexFormat::Char2Norm:
|
||||
return DXGI_FORMAT_R8G8_SNORM;
|
||||
case dawn::VertexFormat::Char4Norm:
|
||||
return DXGI_FORMAT_R8G8B8A8_SNORM;
|
||||
case dawn::VertexFormat::UShort2:
|
||||
return DXGI_FORMAT_R16G16_UINT;
|
||||
case dawn::VertexFormat::UShort4:
|
||||
return DXGI_FORMAT_R16G16B16A16_UINT;
|
||||
case dawn::VertexFormat::Short2:
|
||||
return DXGI_FORMAT_R16G16_SINT;
|
||||
case dawn::VertexFormat::Short4:
|
||||
return DXGI_FORMAT_R16G16B16A16_SINT;
|
||||
case dawn::VertexFormat::UShort2Norm:
|
||||
return DXGI_FORMAT_R16G16_UNORM;
|
||||
case dawn::VertexFormat::UShort4Norm:
|
||||
return DXGI_FORMAT_R16G16B16A16_UNORM;
|
||||
case dawn::VertexFormat::Short2Norm:
|
||||
return DXGI_FORMAT_R16G16_SNORM;
|
||||
case dawn::VertexFormat::Short4Norm:
|
||||
return DXGI_FORMAT_R16G16B16A16_SNORM;
|
||||
case dawn::VertexFormat::Half2:
|
||||
return DXGI_FORMAT_R16G16_FLOAT;
|
||||
case dawn::VertexFormat::Half4:
|
||||
return DXGI_FORMAT_R16G16B16A16_FLOAT;
|
||||
case dawn::VertexFormat::Float:
|
||||
return DXGI_FORMAT_R32_FLOAT;
|
||||
case dawn::VertexFormat::Float2:
|
||||
return DXGI_FORMAT_R32G32_FLOAT;
|
||||
case dawn::VertexFormat::Float3:
|
||||
return DXGI_FORMAT_R32G32B32_FLOAT;
|
||||
case dawn::VertexFormat::Float4:
|
||||
return DXGI_FORMAT_R32G32B32A32_FLOAT;
|
||||
case dawn::VertexFormat::UInt:
|
||||
return DXGI_FORMAT_R32_UINT;
|
||||
case dawn::VertexFormat::UInt2:
|
||||
return DXGI_FORMAT_R32G32_UINT;
|
||||
case dawn::VertexFormat::UInt3:
|
||||
return DXGI_FORMAT_R32G32B32_UINT;
|
||||
case dawn::VertexFormat::UInt4:
|
||||
return DXGI_FORMAT_R32G32B32A32_UINT;
|
||||
case dawn::VertexFormat::Int:
|
||||
return DXGI_FORMAT_R32_SINT;
|
||||
case dawn::VertexFormat::Int2:
|
||||
return DXGI_FORMAT_R32G32_SINT;
|
||||
case dawn::VertexFormat::Int3:
|
||||
return DXGI_FORMAT_R32G32B32_SINT;
|
||||
case dawn::VertexFormat::Int4:
|
||||
return DXGI_FORMAT_R32G32B32A32_SINT;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
D3D12_INPUT_CLASSIFICATION InputStepModeFunction(dawn::InputStepMode mode) {
|
||||
switch (mode) {
|
||||
case dawn::InputStepMode::Vertex:
|
||||
return D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA;
|
||||
case dawn::InputStepMode::Instance:
|
||||
return D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
D3D12_PRIMITIVE_TOPOLOGY D3D12PrimitiveTopology(dawn::PrimitiveTopology primitiveTopology) {
|
||||
switch (primitiveTopology) {
|
||||
case dawn::PrimitiveTopology::PointList:
|
||||
|
@ -261,9 +338,9 @@ namespace dawn_native { namespace d3d12 {
|
|||
descriptorD3D12.pRootSignature = layout->GetRootSignature().Get();
|
||||
|
||||
// D3D12 logs warnings if any empty input state is used
|
||||
InputState* inputState = ToBackend(GetInputState());
|
||||
if (inputState->GetAttributesSetMask().any()) {
|
||||
descriptorD3D12.InputLayout = inputState->GetD3D12InputLayoutDescriptor();
|
||||
std::array<D3D12_INPUT_ELEMENT_DESC, kMaxVertexAttributes> inputElementDescriptors;
|
||||
if (GetAttributesSetMask().any()) {
|
||||
descriptorD3D12.InputLayout = ComputeInputLayout(&inputElementDescriptors);
|
||||
}
|
||||
|
||||
descriptorD3D12.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
|
||||
|
@ -317,4 +394,42 @@ namespace dawn_native { namespace d3d12 {
|
|||
return mPipelineState;
|
||||
}
|
||||
|
||||
D3D12_INPUT_LAYOUT_DESC RenderPipeline::ComputeInputLayout(
|
||||
std::array<D3D12_INPUT_ELEMENT_DESC, kMaxVertexAttributes>* inputElementDescriptors) {
|
||||
const auto& attributesSetMask = GetAttributesSetMask();
|
||||
unsigned int count = 0;
|
||||
for (auto i : IterateBitSet(attributesSetMask)) {
|
||||
if (!attributesSetMask[i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
D3D12_INPUT_ELEMENT_DESC& inputElementDescriptor = (*inputElementDescriptors)[count++];
|
||||
|
||||
const VertexAttributeDescriptor& attribute = GetAttribute(i);
|
||||
|
||||
// If the HLSL semantic is TEXCOORDN the SemanticName should be "TEXCOORD" and the
|
||||
// SemanticIndex N
|
||||
inputElementDescriptor.SemanticName = "TEXCOORD";
|
||||
inputElementDescriptor.SemanticIndex = static_cast<uint32_t>(i);
|
||||
inputElementDescriptor.Format = VertexFormatType(attribute.format);
|
||||
inputElementDescriptor.InputSlot = attribute.inputSlot;
|
||||
|
||||
const VertexInputDescriptor& input = GetInput(attribute.inputSlot);
|
||||
|
||||
inputElementDescriptor.AlignedByteOffset = attribute.offset;
|
||||
inputElementDescriptor.InputSlotClass = InputStepModeFunction(input.stepMode);
|
||||
if (inputElementDescriptor.InputSlotClass ==
|
||||
D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA) {
|
||||
inputElementDescriptor.InstanceDataStepRate = 0;
|
||||
} else {
|
||||
inputElementDescriptor.InstanceDataStepRate = 1;
|
||||
}
|
||||
}
|
||||
|
||||
D3D12_INPUT_LAYOUT_DESC inputLayoutDescriptor;
|
||||
inputLayoutDescriptor.pInputElementDescs = &(*inputElementDescriptors)[0];
|
||||
inputLayoutDescriptor.NumElements = count;
|
||||
return inputLayoutDescriptor;
|
||||
}
|
||||
|
||||
}} // namespace dawn_native::d3d12
|
||||
|
|
|
@ -32,6 +32,9 @@ namespace dawn_native { namespace d3d12 {
|
|||
ComPtr<ID3D12PipelineState> GetPipelineState();
|
||||
|
||||
private:
|
||||
D3D12_INPUT_LAYOUT_DESC ComputeInputLayout(
|
||||
std::array<D3D12_INPUT_ELEMENT_DESC, kMaxVertexAttributes>* inputElementDescriptors);
|
||||
|
||||
D3D12_PRIMITIVE_TOPOLOGY mD3d12PrimitiveTopology;
|
||||
ComPtr<ID3D12PipelineState> mPipelineState;
|
||||
};
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include "dawn_native/metal/BufferMTL.h"
|
||||
#include "dawn_native/metal/ComputePipelineMTL.h"
|
||||
#include "dawn_native/metal/DeviceMTL.h"
|
||||
#include "dawn_native/metal/InputStateMTL.h"
|
||||
#include "dawn_native/metal/PipelineLayoutMTL.h"
|
||||
#include "dawn_native/metal/RenderPipelineMTL.h"
|
||||
#include "dawn_native/metal/SamplerMTL.h"
|
||||
|
|
|
@ -38,7 +38,6 @@ namespace dawn_native { namespace metal {
|
|||
~Device();
|
||||
|
||||
CommandBufferBase* CreateCommandBuffer(CommandEncoderBase* encoder) override;
|
||||
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
|
||||
|
||||
Serial GetCompletedCommandSerial() const final override;
|
||||
Serial GetLastSubmittedCommandSerial() const final override;
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "dawn_native/metal/BufferMTL.h"
|
||||
#include "dawn_native/metal/CommandBufferMTL.h"
|
||||
#include "dawn_native/metal/ComputePipelineMTL.h"
|
||||
#include "dawn_native/metal/InputStateMTL.h"
|
||||
#include "dawn_native/metal/PipelineLayoutMTL.h"
|
||||
#include "dawn_native/metal/QueueMTL.h"
|
||||
#include "dawn_native/metal/RenderPipelineMTL.h"
|
||||
|
@ -86,9 +85,6 @@ namespace dawn_native { namespace metal {
|
|||
const ComputePipelineDescriptor* descriptor) {
|
||||
return new ComputePipeline(this, descriptor);
|
||||
}
|
||||
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
|
||||
return new InputState(builder);
|
||||
}
|
||||
ResultOrError<PipelineLayoutBase*> Device::CreatePipelineLayoutImpl(
|
||||
const PipelineLayoutDescriptor* descriptor) {
|
||||
return new PipelineLayout(this, descriptor);
|
||||
|
|
|
@ -32,7 +32,6 @@ namespace dawn_native { namespace metal {
|
|||
class ComputePipeline;
|
||||
class Device;
|
||||
class Framebuffer;
|
||||
class InputState;
|
||||
class PipelineLayout;
|
||||
class Queue;
|
||||
class RenderPipeline;
|
||||
|
@ -51,7 +50,6 @@ namespace dawn_native { namespace metal {
|
|||
using CommandBufferType = CommandBuffer;
|
||||
using ComputePipelineType = ComputePipeline;
|
||||
using DeviceType = Device;
|
||||
using InputStateType = InputState;
|
||||
using PipelineLayoutType = PipelineLayout;
|
||||
using QueueType = Queue;
|
||||
using RenderPipelineType = RenderPipeline;
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
// Copyright 2017 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef DAWNNATIVE_METAL_INPUTSTATEMTL_H_
|
||||
#define DAWNNATIVE_METAL_INPUTSTATEMTL_H_
|
||||
|
||||
#include "dawn_native/InputState.h"
|
||||
|
||||
#import <Metal/Metal.h>
|
||||
|
||||
namespace dawn_native { namespace metal {
|
||||
|
||||
class InputState : public InputStateBase {
|
||||
public:
|
||||
InputState(InputStateBuilder* builder);
|
||||
~InputState();
|
||||
|
||||
MTLVertexDescriptor* GetMTLVertexDescriptor();
|
||||
|
||||
private:
|
||||
MTLVertexDescriptor* mMtlVertexDescriptor = nil;
|
||||
};
|
||||
|
||||
}} // namespace dawn_native::metal
|
||||
|
||||
#endif // DAWNNATIVE_METAL_COMMANDINPUTSTATEMTL_H_
|
|
@ -1,160 +0,0 @@
|
|||
// Copyright 2017 The Dawn 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 "dawn_native/metal/InputStateMTL.h"
|
||||
|
||||
#include "common/BitSetIterator.h"
|
||||
|
||||
namespace dawn_native { namespace metal {
|
||||
|
||||
namespace {
|
||||
MTLVertexFormat VertexFormatType(dawn::VertexFormat format) {
|
||||
switch (format) {
|
||||
case dawn::VertexFormat::UChar2:
|
||||
return MTLVertexFormatUChar2;
|
||||
case dawn::VertexFormat::UChar4:
|
||||
return MTLVertexFormatUChar4;
|
||||
case dawn::VertexFormat::Char2:
|
||||
return MTLVertexFormatChar2;
|
||||
case dawn::VertexFormat::Char4:
|
||||
return MTLVertexFormatChar4;
|
||||
case dawn::VertexFormat::UChar2Norm:
|
||||
return MTLVertexFormatUChar2Normalized;
|
||||
case dawn::VertexFormat::UChar4Norm:
|
||||
return MTLVertexFormatUChar4Normalized;
|
||||
case dawn::VertexFormat::Char2Norm:
|
||||
return MTLVertexFormatChar2Normalized;
|
||||
case dawn::VertexFormat::Char4Norm:
|
||||
return MTLVertexFormatChar4Normalized;
|
||||
case dawn::VertexFormat::UShort2:
|
||||
return MTLVertexFormatUShort2;
|
||||
case dawn::VertexFormat::UShort4:
|
||||
return MTLVertexFormatUShort4;
|
||||
case dawn::VertexFormat::Short2:
|
||||
return MTLVertexFormatShort2;
|
||||
case dawn::VertexFormat::Short4:
|
||||
return MTLVertexFormatShort4;
|
||||
case dawn::VertexFormat::UShort2Norm:
|
||||
return MTLVertexFormatUShort2Normalized;
|
||||
case dawn::VertexFormat::UShort4Norm:
|
||||
return MTLVertexFormatUShort4Normalized;
|
||||
case dawn::VertexFormat::Short2Norm:
|
||||
return MTLVertexFormatShort2Normalized;
|
||||
case dawn::VertexFormat::Short4Norm:
|
||||
return MTLVertexFormatShort4Normalized;
|
||||
case dawn::VertexFormat::Half2:
|
||||
return MTLVertexFormatHalf2;
|
||||
case dawn::VertexFormat::Half4:
|
||||
return MTLVertexFormatHalf4;
|
||||
case dawn::VertexFormat::Float:
|
||||
return MTLVertexFormatFloat;
|
||||
case dawn::VertexFormat::Float2:
|
||||
return MTLVertexFormatFloat2;
|
||||
case dawn::VertexFormat::Float3:
|
||||
return MTLVertexFormatFloat3;
|
||||
case dawn::VertexFormat::Float4:
|
||||
return MTLVertexFormatFloat4;
|
||||
case dawn::VertexFormat::UInt:
|
||||
return MTLVertexFormatUInt;
|
||||
case dawn::VertexFormat::UInt2:
|
||||
return MTLVertexFormatUInt2;
|
||||
case dawn::VertexFormat::UInt3:
|
||||
return MTLVertexFormatUInt3;
|
||||
case dawn::VertexFormat::UInt4:
|
||||
return MTLVertexFormatUInt4;
|
||||
case dawn::VertexFormat::Int:
|
||||
return MTLVertexFormatInt;
|
||||
case dawn::VertexFormat::Int2:
|
||||
return MTLVertexFormatInt2;
|
||||
case dawn::VertexFormat::Int3:
|
||||
return MTLVertexFormatInt3;
|
||||
case dawn::VertexFormat::Int4:
|
||||
return MTLVertexFormatInt4;
|
||||
}
|
||||
}
|
||||
|
||||
MTLVertexStepFunction InputStepModeFunction(dawn::InputStepMode mode) {
|
||||
switch (mode) {
|
||||
case dawn::InputStepMode::Vertex:
|
||||
return MTLVertexStepFunctionPerVertex;
|
||||
case dawn::InputStepMode::Instance:
|
||||
return MTLVertexStepFunctionPerInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InputState::InputState(InputStateBuilder* builder) : InputStateBase(builder) {
|
||||
mMtlVertexDescriptor = [MTLVertexDescriptor new];
|
||||
|
||||
const auto& attributesSetMask = GetAttributesSetMask();
|
||||
for (uint32_t i = 0; i < attributesSetMask.size(); ++i) {
|
||||
if (!attributesSetMask[i]) {
|
||||
continue;
|
||||
}
|
||||
const VertexAttributeDescriptor& info = GetAttribute(i);
|
||||
|
||||
auto attribDesc = [MTLVertexAttributeDescriptor new];
|
||||
attribDesc.format = VertexFormatType(info.format);
|
||||
attribDesc.offset = info.offset;
|
||||
attribDesc.bufferIndex = kMaxBindingsPerGroup + info.inputSlot;
|
||||
mMtlVertexDescriptor.attributes[i] = attribDesc;
|
||||
[attribDesc release];
|
||||
}
|
||||
|
||||
for (uint32_t i : IterateBitSet(GetInputsSetMask())) {
|
||||
const VertexInputDescriptor& info = GetInput(i);
|
||||
|
||||
auto layoutDesc = [MTLVertexBufferLayoutDescriptor new];
|
||||
if (info.stride == 0) {
|
||||
// For MTLVertexStepFunctionConstant, the stepRate must be 0,
|
||||
// but the stride must NOT be 0, so we made up it with
|
||||
// max(attrib.offset + sizeof(attrib) for each attrib)
|
||||
uint32_t max_stride = 0;
|
||||
for (uint32_t attribIndex : IterateBitSet(attributesSetMask)) {
|
||||
const VertexAttributeDescriptor& attrib = GetAttribute(attribIndex);
|
||||
// Only use the attributes that use the current input
|
||||
if (attrib.inputSlot != info.inputSlot) {
|
||||
continue;
|
||||
}
|
||||
max_stride = std::max(
|
||||
max_stride,
|
||||
static_cast<uint32_t>(VertexFormatSize(attrib.format)) + attrib.offset);
|
||||
}
|
||||
|
||||
layoutDesc.stepFunction = MTLVertexStepFunctionConstant;
|
||||
layoutDesc.stepRate = 0;
|
||||
// Metal requires the stride must be a multiple of 4 bytes, align it with next
|
||||
// multiple of 4 if it's not.
|
||||
layoutDesc.stride = Align(max_stride, 4);
|
||||
} else {
|
||||
layoutDesc.stepFunction = InputStepModeFunction(info.stepMode);
|
||||
layoutDesc.stepRate = 1;
|
||||
layoutDesc.stride = info.stride;
|
||||
}
|
||||
// TODO(cwallez@chromium.org): make the offset depend on the pipeline layout
|
||||
mMtlVertexDescriptor.layouts[kMaxBindingsPerGroup + i] = layoutDesc;
|
||||
[layoutDesc release];
|
||||
}
|
||||
}
|
||||
|
||||
InputState::~InputState() {
|
||||
[mMtlVertexDescriptor release];
|
||||
mMtlVertexDescriptor = nil;
|
||||
}
|
||||
|
||||
MTLVertexDescriptor* InputState::GetMTLVertexDescriptor() {
|
||||
return mMtlVertexDescriptor;
|
||||
}
|
||||
|
||||
}} // namespace dawn_native::metal
|
|
@ -36,6 +36,8 @@ namespace dawn_native { namespace metal {
|
|||
id<MTLDepthStencilState> GetMTLDepthStencilState();
|
||||
|
||||
private:
|
||||
MTLVertexDescriptor* MakeVertexDesc();
|
||||
|
||||
MTLIndexType mMtlIndexType;
|
||||
MTLPrimitiveType mMtlPrimitiveTopology;
|
||||
id<MTLRenderPipelineState> mMtlRenderPipelineState = nil;
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include "dawn_native/metal/RenderPipelineMTL.h"
|
||||
|
||||
#include "dawn_native/metal/DeviceMTL.h"
|
||||
#include "dawn_native/metal/InputStateMTL.h"
|
||||
#include "dawn_native/metal/PipelineLayoutMTL.h"
|
||||
#include "dawn_native/metal/ShaderModuleMTL.h"
|
||||
#include "dawn_native/metal/TextureMTL.h"
|
||||
|
@ -24,6 +23,80 @@
|
|||
namespace dawn_native { namespace metal {
|
||||
|
||||
namespace {
|
||||
MTLVertexFormat VertexFormatType(dawn::VertexFormat format) {
|
||||
switch (format) {
|
||||
case dawn::VertexFormat::UChar2:
|
||||
return MTLVertexFormatUChar2;
|
||||
case dawn::VertexFormat::UChar4:
|
||||
return MTLVertexFormatUChar4;
|
||||
case dawn::VertexFormat::Char2:
|
||||
return MTLVertexFormatChar2;
|
||||
case dawn::VertexFormat::Char4:
|
||||
return MTLVertexFormatChar4;
|
||||
case dawn::VertexFormat::UChar2Norm:
|
||||
return MTLVertexFormatUChar2Normalized;
|
||||
case dawn::VertexFormat::UChar4Norm:
|
||||
return MTLVertexFormatUChar4Normalized;
|
||||
case dawn::VertexFormat::Char2Norm:
|
||||
return MTLVertexFormatChar2Normalized;
|
||||
case dawn::VertexFormat::Char4Norm:
|
||||
return MTLVertexFormatChar4Normalized;
|
||||
case dawn::VertexFormat::UShort2:
|
||||
return MTLVertexFormatUShort2;
|
||||
case dawn::VertexFormat::UShort4:
|
||||
return MTLVertexFormatUShort4;
|
||||
case dawn::VertexFormat::Short2:
|
||||
return MTLVertexFormatShort2;
|
||||
case dawn::VertexFormat::Short4:
|
||||
return MTLVertexFormatShort4;
|
||||
case dawn::VertexFormat::UShort2Norm:
|
||||
return MTLVertexFormatUShort2Normalized;
|
||||
case dawn::VertexFormat::UShort4Norm:
|
||||
return MTLVertexFormatUShort4Normalized;
|
||||
case dawn::VertexFormat::Short2Norm:
|
||||
return MTLVertexFormatShort2Normalized;
|
||||
case dawn::VertexFormat::Short4Norm:
|
||||
return MTLVertexFormatShort4Normalized;
|
||||
case dawn::VertexFormat::Half2:
|
||||
return MTLVertexFormatHalf2;
|
||||
case dawn::VertexFormat::Half4:
|
||||
return MTLVertexFormatHalf4;
|
||||
case dawn::VertexFormat::Float:
|
||||
return MTLVertexFormatFloat;
|
||||
case dawn::VertexFormat::Float2:
|
||||
return MTLVertexFormatFloat2;
|
||||
case dawn::VertexFormat::Float3:
|
||||
return MTLVertexFormatFloat3;
|
||||
case dawn::VertexFormat::Float4:
|
||||
return MTLVertexFormatFloat4;
|
||||
case dawn::VertexFormat::UInt:
|
||||
return MTLVertexFormatUInt;
|
||||
case dawn::VertexFormat::UInt2:
|
||||
return MTLVertexFormatUInt2;
|
||||
case dawn::VertexFormat::UInt3:
|
||||
return MTLVertexFormatUInt3;
|
||||
case dawn::VertexFormat::UInt4:
|
||||
return MTLVertexFormatUInt4;
|
||||
case dawn::VertexFormat::Int:
|
||||
return MTLVertexFormatInt;
|
||||
case dawn::VertexFormat::Int2:
|
||||
return MTLVertexFormatInt2;
|
||||
case dawn::VertexFormat::Int3:
|
||||
return MTLVertexFormatInt3;
|
||||
case dawn::VertexFormat::Int4:
|
||||
return MTLVertexFormatInt4;
|
||||
}
|
||||
}
|
||||
|
||||
MTLVertexStepFunction InputStepModeFunction(dawn::InputStepMode mode) {
|
||||
switch (mode) {
|
||||
case dawn::InputStepMode::Vertex:
|
||||
return MTLVertexStepFunctionPerVertex;
|
||||
case dawn::InputStepMode::Instance:
|
||||
return MTLVertexStepFunctionPerInstance;
|
||||
}
|
||||
}
|
||||
|
||||
MTLPrimitiveType MTLPrimitiveTopology(dawn::PrimitiveTopology primitiveTopology) {
|
||||
switch (primitiveTopology) {
|
||||
case dawn::PrimitiveTopology::PointList:
|
||||
|
@ -243,8 +316,7 @@ namespace dawn_native { namespace metal {
|
|||
|
||||
descriptorMTL.inputPrimitiveTopology = MTLInputPrimitiveTopology(GetPrimitiveTopology());
|
||||
|
||||
InputState* inputState = ToBackend(GetInputState());
|
||||
descriptorMTL.vertexDescriptor = inputState->GetMTLVertexDescriptor();
|
||||
descriptorMTL.vertexDescriptor = MakeVertexDesc();
|
||||
|
||||
// TODO(kainino@chromium.org): push constants, textures, samplers
|
||||
|
||||
|
@ -252,6 +324,7 @@ namespace dawn_native { namespace metal {
|
|||
NSError* error = nil;
|
||||
mMtlRenderPipelineState = [mtlDevice newRenderPipelineStateWithDescriptor:descriptorMTL
|
||||
error:&error];
|
||||
[descriptorMTL.vertexDescriptor release];
|
||||
[descriptorMTL release];
|
||||
if (error != nil) {
|
||||
NSLog(@" error => %@", error);
|
||||
|
@ -289,4 +362,46 @@ namespace dawn_native { namespace metal {
|
|||
return mMtlDepthStencilState;
|
||||
}
|
||||
|
||||
MTLVertexDescriptor* RenderPipeline::MakeVertexDesc() {
|
||||
MTLVertexDescriptor* mtlVertexDescriptor = [MTLVertexDescriptor new];
|
||||
|
||||
const auto& attributesSetMask = GetAttributesSetMask();
|
||||
for (uint32_t i = 0; i < attributesSetMask.size(); ++i) {
|
||||
if (!attributesSetMask[i]) {
|
||||
continue;
|
||||
}
|
||||
const VertexAttributeDescriptor& info = GetAttribute(i);
|
||||
|
||||
auto attribDesc = [MTLVertexAttributeDescriptor new];
|
||||
attribDesc.format = VertexFormatType(info.format);
|
||||
attribDesc.offset = info.offset;
|
||||
attribDesc.bufferIndex = kMaxBindingsPerGroup + info.inputSlot;
|
||||
mtlVertexDescriptor.attributes[i] = attribDesc;
|
||||
[attribDesc release];
|
||||
}
|
||||
|
||||
for (uint32_t i : IterateBitSet(GetInputsSetMask())) {
|
||||
const VertexInputDescriptor& info = GetInput(i);
|
||||
|
||||
auto layoutDesc = [MTLVertexBufferLayoutDescriptor new];
|
||||
if (info.stride == 0) {
|
||||
// For MTLVertexStepFunctionConstant, the stepRate must be 0,
|
||||
// but the stride must NOT be 0, so I made up a value (256).
|
||||
// TODO(cwallez@chromium.org): the made up value will need to be at least
|
||||
// max(attrib.offset + sizeof(attrib) for each attrib)
|
||||
layoutDesc.stepFunction = MTLVertexStepFunctionConstant;
|
||||
layoutDesc.stepRate = 0;
|
||||
layoutDesc.stride = 256;
|
||||
} else {
|
||||
layoutDesc.stepFunction = InputStepModeFunction(info.stepMode);
|
||||
layoutDesc.stepRate = 1;
|
||||
layoutDesc.stride = info.stride;
|
||||
}
|
||||
// TODO(cwallez@chromium.org): make the offset depend on the pipeline layout
|
||||
mtlVertexDescriptor.layouts[kMaxBindingsPerGroup + i] = layoutDesc;
|
||||
[layoutDesc release];
|
||||
}
|
||||
return mtlVertexDescriptor;
|
||||
}
|
||||
|
||||
}} // namespace dawn_native::metal
|
||||
|
|
|
@ -82,9 +82,6 @@ namespace dawn_native { namespace null {
|
|||
const ComputePipelineDescriptor* descriptor) {
|
||||
return new ComputePipeline(this, descriptor);
|
||||
}
|
||||
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
|
||||
return new InputState(builder);
|
||||
}
|
||||
ResultOrError<PipelineLayoutBase*> Device::CreatePipelineLayoutImpl(
|
||||
const PipelineLayoutDescriptor* descriptor) {
|
||||
return new PipelineLayout(this, descriptor);
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include "dawn_native/CommandEncoder.h"
|
||||
#include "dawn_native/ComputePipeline.h"
|
||||
#include "dawn_native/Device.h"
|
||||
#include "dawn_native/InputState.h"
|
||||
#include "dawn_native/PipelineLayout.h"
|
||||
#include "dawn_native/Queue.h"
|
||||
#include "dawn_native/RenderPipeline.h"
|
||||
|
@ -44,7 +43,6 @@ namespace dawn_native { namespace null {
|
|||
class CommandBuffer;
|
||||
using ComputePipeline = ComputePipelineBase;
|
||||
class Device;
|
||||
using InputState = InputStateBase;
|
||||
using PipelineLayout = PipelineLayoutBase;
|
||||
class Queue;
|
||||
using RenderPipeline = RenderPipelineBase;
|
||||
|
@ -62,7 +60,6 @@ namespace dawn_native { namespace null {
|
|||
using CommandBufferType = CommandBuffer;
|
||||
using ComputePipelineType = ComputePipeline;
|
||||
using DeviceType = Device;
|
||||
using InputStateType = InputState;
|
||||
using PipelineLayoutType = PipelineLayout;
|
||||
using QueueType = Queue;
|
||||
using RenderPipelineType = RenderPipeline;
|
||||
|
@ -89,7 +86,6 @@ namespace dawn_native { namespace null {
|
|||
~Device();
|
||||
|
||||
CommandBufferBase* CreateCommandBuffer(CommandEncoderBase* encoder) override;
|
||||
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
|
||||
|
||||
Serial GetCompletedCommandSerial() const final override;
|
||||
Serial GetLastSubmittedCommandSerial() const final override;
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "dawn_native/opengl/ComputePipelineGL.h"
|
||||
#include "dawn_native/opengl/DeviceGL.h"
|
||||
#include "dawn_native/opengl/Forward.h"
|
||||
#include "dawn_native/opengl/InputStateGL.h"
|
||||
#include "dawn_native/opengl/PersistentPipelineStateGL.h"
|
||||
#include "dawn_native/opengl/PipelineLayoutGL.h"
|
||||
#include "dawn_native/opengl/RenderPipelineGL.h"
|
||||
|
@ -212,15 +211,14 @@ namespace dawn_native { namespace opengl {
|
|||
}
|
||||
|
||||
void OnSetPipeline(RenderPipelineBase* pipeline) {
|
||||
InputStateBase* inputState = pipeline->GetInputState();
|
||||
if (mLastInputState == inputState) {
|
||||
if (mLastPipeline == pipeline) {
|
||||
return;
|
||||
}
|
||||
|
||||
mIndexBufferDirty = true;
|
||||
mDirtyVertexBuffers |= inputState->GetInputsSetMask();
|
||||
mDirtyVertexBuffers |= pipeline->GetInputsSetMask();
|
||||
|
||||
mLastInputState = ToBackend(inputState);
|
||||
mLastPipeline = pipeline;
|
||||
}
|
||||
|
||||
void Apply() {
|
||||
|
@ -230,15 +228,15 @@ namespace dawn_native { namespace opengl {
|
|||
}
|
||||
|
||||
for (uint32_t slot :
|
||||
IterateBitSet(mDirtyVertexBuffers & mLastInputState->GetInputsSetMask())) {
|
||||
IterateBitSet(mDirtyVertexBuffers & mLastPipeline->GetInputsSetMask())) {
|
||||
for (uint32_t location :
|
||||
IterateBitSet(mLastInputState->GetAttributesUsingInput(slot))) {
|
||||
auto attribute = mLastInputState->GetAttribute(location);
|
||||
IterateBitSet(mLastPipeline->GetAttributesUsingInput(slot))) {
|
||||
auto attribute = mLastPipeline->GetAttribute(location);
|
||||
|
||||
GLuint buffer = mVertexBuffers[slot]->GetHandle();
|
||||
uint32_t offset = mVertexBufferOffsets[slot];
|
||||
|
||||
auto input = mLastInputState->GetInput(slot);
|
||||
auto input = mLastPipeline->GetInput(slot);
|
||||
auto components = VertexFormatNumComponents(attribute.format);
|
||||
auto formatType = VertexFormatType(attribute.format);
|
||||
|
||||
|
@ -262,7 +260,7 @@ namespace dawn_native { namespace opengl {
|
|||
std::array<Buffer*, kMaxVertexInputs> mVertexBuffers;
|
||||
std::array<uint32_t, kMaxVertexInputs> mVertexBufferOffsets;
|
||||
|
||||
InputState* mLastInputState = nullptr;
|
||||
RenderPipelineBase* mLastPipeline = nullptr;
|
||||
};
|
||||
|
||||
// Handles SetBindGroup commands with the specifics of translating to OpenGL texture and
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "dawn_native/opengl/BufferGL.h"
|
||||
#include "dawn_native/opengl/CommandBufferGL.h"
|
||||
#include "dawn_native/opengl/ComputePipelineGL.h"
|
||||
#include "dawn_native/opengl/InputStateGL.h"
|
||||
#include "dawn_native/opengl/PipelineLayoutGL.h"
|
||||
#include "dawn_native/opengl/QueueGL.h"
|
||||
#include "dawn_native/opengl/RenderPipelineGL.h"
|
||||
|
@ -67,9 +66,6 @@ namespace dawn_native { namespace opengl {
|
|||
const ComputePipelineDescriptor* descriptor) {
|
||||
return new ComputePipeline(this, descriptor);
|
||||
}
|
||||
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
|
||||
return new InputState(builder);
|
||||
}
|
||||
ResultOrError<PipelineLayoutBase*> Device::CreatePipelineLayoutImpl(
|
||||
const PipelineLayoutDescriptor* descriptor) {
|
||||
return new PipelineLayout(this, descriptor);
|
||||
|
|
|
@ -41,7 +41,6 @@ namespace dawn_native { namespace opengl {
|
|||
|
||||
// Dawn API
|
||||
CommandBufferBase* CreateCommandBuffer(CommandEncoderBase* encoder) override;
|
||||
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
|
||||
|
||||
Serial GetCompletedCommandSerial() const final override;
|
||||
Serial GetLastSubmittedCommandSerial() const final override;
|
||||
|
|
|
@ -32,7 +32,6 @@ namespace dawn_native { namespace opengl {
|
|||
class CommandBuffer;
|
||||
class ComputePipeline;
|
||||
class Device;
|
||||
class InputState;
|
||||
class PersistentPipelineState;
|
||||
class PipelineLayout;
|
||||
class Queue;
|
||||
|
@ -51,7 +50,6 @@ namespace dawn_native { namespace opengl {
|
|||
using CommandBufferType = CommandBuffer;
|
||||
using ComputePipelineType = ComputePipeline;
|
||||
using DeviceType = Device;
|
||||
using InputStateType = InputState;
|
||||
using PipelineLayoutType = PipelineLayout;
|
||||
using QueueType = Queue;
|
||||
using RenderPipelineType = RenderPipeline;
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
// Copyright 2017 The Dawn 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 "dawn_native/opengl/InputStateGL.h"
|
||||
|
||||
#include "common/Assert.h"
|
||||
|
||||
namespace dawn_native { namespace opengl {
|
||||
|
||||
InputState::InputState(InputStateBuilder* builder) : InputStateBase(builder) {
|
||||
glGenVertexArrays(1, &mVertexArrayObject);
|
||||
glBindVertexArray(mVertexArrayObject);
|
||||
auto& attributesSetMask = GetAttributesSetMask();
|
||||
for (uint32_t location = 0; location < attributesSetMask.size(); ++location) {
|
||||
if (!attributesSetMask[location]) {
|
||||
continue;
|
||||
}
|
||||
auto attribute = GetAttribute(location);
|
||||
glEnableVertexAttribArray(location);
|
||||
|
||||
attributesUsingInput[attribute.inputSlot][location] = true;
|
||||
auto input = GetInput(attribute.inputSlot);
|
||||
|
||||
if (input.stride == 0) {
|
||||
// Emulate a stride of zero (constant vertex attribute) by
|
||||
// setting the attribute instance divisor to a huge number.
|
||||
glVertexAttribDivisor(location, 0xffffffff);
|
||||
} else {
|
||||
switch (input.stepMode) {
|
||||
case dawn::InputStepMode::Vertex:
|
||||
break;
|
||||
case dawn::InputStepMode::Instance:
|
||||
glVertexAttribDivisor(location, 1);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::bitset<kMaxVertexAttributes> InputState::GetAttributesUsingInput(uint32_t slot) const {
|
||||
return attributesUsingInput[slot];
|
||||
}
|
||||
|
||||
GLuint InputState::GetVAO() {
|
||||
return mVertexArrayObject;
|
||||
}
|
||||
|
||||
}} // namespace dawn_native::opengl
|
|
@ -1,40 +0,0 @@
|
|||
// Copyright 2017 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef DAWNNATIVE_OPENGL_INPUTSTATEGL_H_
|
||||
#define DAWNNATIVE_OPENGL_INPUTSTATEGL_H_
|
||||
|
||||
#include "dawn_native/InputState.h"
|
||||
|
||||
#include "glad/glad.h"
|
||||
|
||||
namespace dawn_native { namespace opengl {
|
||||
|
||||
class Device;
|
||||
|
||||
class InputState : public InputStateBase {
|
||||
public:
|
||||
InputState(InputStateBuilder* builder);
|
||||
|
||||
std::bitset<kMaxVertexAttributes> GetAttributesUsingInput(uint32_t slot) const;
|
||||
GLuint GetVAO();
|
||||
|
||||
private:
|
||||
GLuint mVertexArrayObject;
|
||||
std::array<std::bitset<kMaxVertexAttributes>, kMaxVertexInputs> attributesUsingInput;
|
||||
};
|
||||
|
||||
}} // namespace dawn_native::opengl
|
||||
|
||||
#endif // DAWNNATIVE_OPENGL_INPUTSTATEGL_H_
|
|
@ -16,13 +16,13 @@
|
|||
|
||||
#include "dawn_native/opengl/DeviceGL.h"
|
||||
#include "dawn_native/opengl/Forward.h"
|
||||
#include "dawn_native/opengl/InputStateGL.h"
|
||||
#include "dawn_native/opengl/PersistentPipelineStateGL.h"
|
||||
#include "dawn_native/opengl/UtilsGL.h"
|
||||
|
||||
namespace dawn_native { namespace opengl {
|
||||
|
||||
namespace {
|
||||
|
||||
GLenum GLPrimitiveTopology(dawn::PrimitiveTopology primitiveTopology) {
|
||||
switch (primitiveTopology) {
|
||||
case dawn::PrimitiveTopology::PointList:
|
||||
|
@ -175,23 +175,62 @@ namespace dawn_native { namespace opengl {
|
|||
|
||||
RenderPipeline::RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor)
|
||||
: RenderPipelineBase(device, descriptor),
|
||||
mVertexArrayObject(0),
|
||||
mGlPrimitiveTopology(GLPrimitiveTopology(GetPrimitiveTopology())) {
|
||||
PerStage<const ShaderModule*> modules(nullptr);
|
||||
modules[dawn::ShaderStage::Vertex] = ToBackend(descriptor->vertexStage->module);
|
||||
modules[dawn::ShaderStage::Fragment] = ToBackend(descriptor->fragmentStage->module);
|
||||
|
||||
PipelineGL::Initialize(ToBackend(GetLayout()), modules);
|
||||
CreateVAOForInputState(descriptor->inputState);
|
||||
}
|
||||
|
||||
RenderPipeline::~RenderPipeline() {
|
||||
glDeleteVertexArrays(1, &mVertexArrayObject);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
GLenum RenderPipeline::GetGLPrimitiveTopology() const {
|
||||
return mGlPrimitiveTopology;
|
||||
}
|
||||
|
||||
void RenderPipeline::CreateVAOForInputState(const InputStateDescriptor* inputState) {
|
||||
glGenVertexArrays(1, &mVertexArrayObject);
|
||||
glBindVertexArray(mVertexArrayObject);
|
||||
auto& attributesSetMask = GetAttributesSetMask();
|
||||
for (uint32_t location = 0; location < attributesSetMask.size(); ++location) {
|
||||
if (!attributesSetMask[location]) {
|
||||
continue;
|
||||
}
|
||||
auto attribute = GetAttribute(location);
|
||||
glEnableVertexAttribArray(location);
|
||||
|
||||
attributesUsingInput[attribute.inputSlot][location] = true;
|
||||
auto input = GetInput(attribute.inputSlot);
|
||||
|
||||
if (input.stride == 0) {
|
||||
// Emulate a stride of zero (constant vertex attribute) by
|
||||
// setting the attribute instance divisor to a huge number.
|
||||
glVertexAttribDivisor(location, 0xffffffff);
|
||||
} else {
|
||||
switch (input.stepMode) {
|
||||
case dawn::InputStepMode::Vertex:
|
||||
break;
|
||||
case dawn::InputStepMode::Instance:
|
||||
glVertexAttribDivisor(location, 1);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPipeline::ApplyNow(PersistentPipelineState& persistentPipelineState) {
|
||||
PipelineGL::ApplyNow();
|
||||
|
||||
auto inputState = ToBackend(GetInputState());
|
||||
glBindVertexArray(inputState->GetVAO());
|
||||
ASSERT(mVertexArrayObject);
|
||||
glBindVertexArray(mVertexArrayObject);
|
||||
|
||||
ApplyDepthStencilState(GetDepthStencilStateDescriptor(), &persistentPipelineState);
|
||||
|
||||
|
|
|
@ -31,12 +31,17 @@ namespace dawn_native { namespace opengl {
|
|||
class RenderPipeline : public RenderPipelineBase, public PipelineGL {
|
||||
public:
|
||||
RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor);
|
||||
~RenderPipeline();
|
||||
|
||||
GLenum GetGLPrimitiveTopology() const;
|
||||
|
||||
void ApplyNow(PersistentPipelineState& persistentPipelineState);
|
||||
|
||||
private:
|
||||
void CreateVAOForInputState(const InputStateDescriptor* inputState);
|
||||
|
||||
// TODO(yunchao.he@intel.com): vao need to be deduplicated between pipelines.
|
||||
GLuint mVertexArrayObject;
|
||||
GLenum mGlPrimitiveTopology;
|
||||
};
|
||||
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include "dawn_native/vulkan/CommandBufferVk.h"
|
||||
#include "dawn_native/vulkan/ComputePipelineVk.h"
|
||||
#include "dawn_native/vulkan/FencedDeleter.h"
|
||||
#include "dawn_native/vulkan/InputStateVk.h"
|
||||
#include "dawn_native/vulkan/PipelineLayoutVk.h"
|
||||
#include "dawn_native/vulkan/QueueVk.h"
|
||||
#include "dawn_native/vulkan/RenderPassCache.h"
|
||||
|
@ -152,9 +151,6 @@ namespace dawn_native { namespace vulkan {
|
|||
const ComputePipelineDescriptor* descriptor) {
|
||||
return new ComputePipeline(this, descriptor);
|
||||
}
|
||||
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
|
||||
return new InputState(builder);
|
||||
}
|
||||
ResultOrError<PipelineLayoutBase*> Device::CreatePipelineLayoutImpl(
|
||||
const PipelineLayoutDescriptor* descriptor) {
|
||||
return new PipelineLayout(this, descriptor);
|
||||
|
|
|
@ -65,7 +65,6 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
// Dawn API
|
||||
CommandBufferBase* CreateCommandBuffer(CommandEncoderBase* encoder) override;
|
||||
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
|
||||
|
||||
Serial GetCompletedCommandSerial() const final override;
|
||||
Serial GetLastSubmittedCommandSerial() const final override;
|
||||
|
|
|
@ -26,7 +26,6 @@ namespace dawn_native { namespace vulkan {
|
|||
class CommandBuffer;
|
||||
class ComputePipeline;
|
||||
class Device;
|
||||
class InputState;
|
||||
class PipelineLayout;
|
||||
class Queue;
|
||||
class RenderPipeline;
|
||||
|
@ -45,7 +44,6 @@ namespace dawn_native { namespace vulkan {
|
|||
using CommandBufferType = CommandBuffer;
|
||||
using ComputePipelineType = ComputePipeline;
|
||||
using DeviceType = Device;
|
||||
using InputStateType = InputState;
|
||||
using PipelineLayoutType = PipelineLayout;
|
||||
using QueueType = Queue;
|
||||
using RenderPipelineType = RenderPipeline;
|
||||
|
|
|
@ -1,145 +0,0 @@
|
|||
// Copyright 2018 The Dawn 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 "dawn_native/vulkan/InputStateVk.h"
|
||||
|
||||
#include "common/BitSetIterator.h"
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
namespace {
|
||||
|
||||
VkVertexInputRate VulkanInputRate(dawn::InputStepMode stepMode) {
|
||||
switch (stepMode) {
|
||||
case dawn::InputStepMode::Vertex:
|
||||
return VK_VERTEX_INPUT_RATE_VERTEX;
|
||||
case dawn::InputStepMode::Instance:
|
||||
return VK_VERTEX_INPUT_RATE_INSTANCE;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
VkFormat VulkanVertexFormat(dawn::VertexFormat format) {
|
||||
switch (format) {
|
||||
case dawn::VertexFormat::UChar2:
|
||||
return VK_FORMAT_R8G8_UINT;
|
||||
case dawn::VertexFormat::UChar4:
|
||||
return VK_FORMAT_R8G8B8A8_UINT;
|
||||
case dawn::VertexFormat::Char2:
|
||||
return VK_FORMAT_R8G8_SINT;
|
||||
case dawn::VertexFormat::Char4:
|
||||
return VK_FORMAT_R8G8B8A8_SINT;
|
||||
case dawn::VertexFormat::UChar2Norm:
|
||||
return VK_FORMAT_R8G8_UNORM;
|
||||
case dawn::VertexFormat::UChar4Norm:
|
||||
return VK_FORMAT_R8G8B8A8_UNORM;
|
||||
case dawn::VertexFormat::Char2Norm:
|
||||
return VK_FORMAT_R8G8_SNORM;
|
||||
case dawn::VertexFormat::Char4Norm:
|
||||
return VK_FORMAT_R8G8B8A8_SNORM;
|
||||
case dawn::VertexFormat::UShort2:
|
||||
return VK_FORMAT_R16G16_UINT;
|
||||
case dawn::VertexFormat::UShort4:
|
||||
return VK_FORMAT_R16G16B16A16_UINT;
|
||||
case dawn::VertexFormat::Short2:
|
||||
return VK_FORMAT_R16G16_SINT;
|
||||
case dawn::VertexFormat::Short4:
|
||||
return VK_FORMAT_R16G16B16A16_SINT;
|
||||
case dawn::VertexFormat::UShort2Norm:
|
||||
return VK_FORMAT_R16G16_UNORM;
|
||||
case dawn::VertexFormat::UShort4Norm:
|
||||
return VK_FORMAT_R16G16B16A16_UNORM;
|
||||
case dawn::VertexFormat::Short2Norm:
|
||||
return VK_FORMAT_R16G16_SNORM;
|
||||
case dawn::VertexFormat::Short4Norm:
|
||||
return VK_FORMAT_R16G16B16A16_SNORM;
|
||||
case dawn::VertexFormat::Half2:
|
||||
return VK_FORMAT_R16G16_SFLOAT;
|
||||
case dawn::VertexFormat::Half4:
|
||||
return VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
case dawn::VertexFormat::Float:
|
||||
return VK_FORMAT_R32_SFLOAT;
|
||||
case dawn::VertexFormat::Float2:
|
||||
return VK_FORMAT_R32G32_SFLOAT;
|
||||
case dawn::VertexFormat::Float3:
|
||||
return VK_FORMAT_R32G32B32_SFLOAT;
|
||||
case dawn::VertexFormat::Float4:
|
||||
return VK_FORMAT_R32G32B32A32_SFLOAT;
|
||||
case dawn::VertexFormat::UInt:
|
||||
return VK_FORMAT_R32_UINT;
|
||||
case dawn::VertexFormat::UInt2:
|
||||
return VK_FORMAT_R32G32_UINT;
|
||||
case dawn::VertexFormat::UInt3:
|
||||
return VK_FORMAT_R32G32B32_UINT;
|
||||
case dawn::VertexFormat::UInt4:
|
||||
return VK_FORMAT_R32G32B32A32_UINT;
|
||||
case dawn::VertexFormat::Int:
|
||||
return VK_FORMAT_R32_SINT;
|
||||
case dawn::VertexFormat::Int2:
|
||||
return VK_FORMAT_R32G32_SINT;
|
||||
case dawn::VertexFormat::Int3:
|
||||
return VK_FORMAT_R32G32B32_SINT;
|
||||
case dawn::VertexFormat::Int4:
|
||||
return VK_FORMAT_R32G32B32A32_SINT;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
InputState::InputState(InputStateBuilder* builder) : InputStateBase(builder) {
|
||||
// Fill in the "binding info" that will be chained in the create info
|
||||
uint32_t bindingCount = 0;
|
||||
for (uint32_t i : IterateBitSet(GetInputsSetMask())) {
|
||||
const auto& bindingInfo = GetInput(i);
|
||||
|
||||
auto& bindingDesc = mBindings[bindingCount];
|
||||
bindingDesc.binding = i;
|
||||
bindingDesc.stride = bindingInfo.stride;
|
||||
bindingDesc.inputRate = VulkanInputRate(bindingInfo.stepMode);
|
||||
|
||||
bindingCount++;
|
||||
}
|
||||
|
||||
// Fill in the "attribute info" that will be chained in the create info
|
||||
uint32_t attributeCount = 0;
|
||||
for (uint32_t i : IterateBitSet(GetAttributesSetMask())) {
|
||||
const auto& attributeInfo = GetAttribute(i);
|
||||
|
||||
auto& attributeDesc = mAttributes[attributeCount];
|
||||
attributeDesc.location = i;
|
||||
attributeDesc.binding = attributeInfo.inputSlot;
|
||||
attributeDesc.format = VulkanVertexFormat(attributeInfo.format);
|
||||
attributeDesc.offset = attributeInfo.offset;
|
||||
|
||||
attributeCount++;
|
||||
}
|
||||
|
||||
// Build the create info
|
||||
mCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
||||
mCreateInfo.pNext = nullptr;
|
||||
mCreateInfo.flags = 0;
|
||||
mCreateInfo.vertexBindingDescriptionCount = bindingCount;
|
||||
mCreateInfo.pVertexBindingDescriptions = mBindings.data();
|
||||
mCreateInfo.vertexAttributeDescriptionCount = attributeCount;
|
||||
mCreateInfo.pVertexAttributeDescriptions = mAttributes.data();
|
||||
}
|
||||
|
||||
const VkPipelineVertexInputStateCreateInfo* InputState::GetCreateInfo() const {
|
||||
return &mCreateInfo;
|
||||
}
|
||||
|
||||
}} // namespace dawn_native::vulkan
|
|
@ -1,41 +0,0 @@
|
|||
// Copyright 2018 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef DAWNNATIVE_VULKAN_INPUTSTATEVK_H_
|
||||
#define DAWNNATIVE_VULKAN_INPUTSTATEVK_H_
|
||||
|
||||
#include "dawn_native/InputState.h"
|
||||
|
||||
#include "common/vulkan_platform.h"
|
||||
|
||||
namespace dawn_native { namespace vulkan {
|
||||
|
||||
class Device;
|
||||
|
||||
// Pre-computes the input state configuration to give to a graphics pipeline create info.
|
||||
class InputState : public InputStateBase {
|
||||
public:
|
||||
InputState(InputStateBuilder* builder);
|
||||
|
||||
const VkPipelineVertexInputStateCreateInfo* GetCreateInfo() const;
|
||||
|
||||
private:
|
||||
VkPipelineVertexInputStateCreateInfo mCreateInfo;
|
||||
std::array<VkVertexInputBindingDescription, kMaxVertexInputs> mBindings;
|
||||
std::array<VkVertexInputAttributeDescription, kMaxVertexAttributes> mAttributes;
|
||||
};
|
||||
|
||||
}} // namespace dawn_native::vulkan
|
||||
|
||||
#endif // DAWNNATIVE_VULKAN_INPUTSTATEVK_H_
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
#include "dawn_native/vulkan/DeviceVk.h"
|
||||
#include "dawn_native/vulkan/FencedDeleter.h"
|
||||
#include "dawn_native/vulkan/InputStateVk.h"
|
||||
#include "dawn_native/vulkan/PipelineLayoutVk.h"
|
||||
#include "dawn_native/vulkan/RenderPassCache.h"
|
||||
#include "dawn_native/vulkan/ShaderModuleVk.h"
|
||||
|
@ -26,6 +25,84 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
namespace {
|
||||
|
||||
VkVertexInputRate VulkanInputRate(dawn::InputStepMode stepMode) {
|
||||
switch (stepMode) {
|
||||
case dawn::InputStepMode::Vertex:
|
||||
return VK_VERTEX_INPUT_RATE_VERTEX;
|
||||
case dawn::InputStepMode::Instance:
|
||||
return VK_VERTEX_INPUT_RATE_INSTANCE;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
VkFormat VulkanVertexFormat(dawn::VertexFormat format) {
|
||||
switch (format) {
|
||||
case dawn::VertexFormat::UChar2:
|
||||
return VK_FORMAT_R8G8_UINT;
|
||||
case dawn::VertexFormat::UChar4:
|
||||
return VK_FORMAT_R8G8B8A8_UINT;
|
||||
case dawn::VertexFormat::Char2:
|
||||
return VK_FORMAT_R8G8_SINT;
|
||||
case dawn::VertexFormat::Char4:
|
||||
return VK_FORMAT_R8G8B8A8_SINT;
|
||||
case dawn::VertexFormat::UChar2Norm:
|
||||
return VK_FORMAT_R8G8_UNORM;
|
||||
case dawn::VertexFormat::UChar4Norm:
|
||||
return VK_FORMAT_R8G8B8A8_UNORM;
|
||||
case dawn::VertexFormat::Char2Norm:
|
||||
return VK_FORMAT_R8G8_SNORM;
|
||||
case dawn::VertexFormat::Char4Norm:
|
||||
return VK_FORMAT_R8G8B8A8_SNORM;
|
||||
case dawn::VertexFormat::UShort2:
|
||||
return VK_FORMAT_R16G16_UINT;
|
||||
case dawn::VertexFormat::UShort4:
|
||||
return VK_FORMAT_R16G16B16A16_UINT;
|
||||
case dawn::VertexFormat::Short2:
|
||||
return VK_FORMAT_R16G16_SINT;
|
||||
case dawn::VertexFormat::Short4:
|
||||
return VK_FORMAT_R16G16B16A16_SINT;
|
||||
case dawn::VertexFormat::UShort2Norm:
|
||||
return VK_FORMAT_R16G16_UNORM;
|
||||
case dawn::VertexFormat::UShort4Norm:
|
||||
return VK_FORMAT_R16G16B16A16_UNORM;
|
||||
case dawn::VertexFormat::Short2Norm:
|
||||
return VK_FORMAT_R16G16_SNORM;
|
||||
case dawn::VertexFormat::Short4Norm:
|
||||
return VK_FORMAT_R16G16B16A16_SNORM;
|
||||
case dawn::VertexFormat::Half2:
|
||||
return VK_FORMAT_R16G16_SFLOAT;
|
||||
case dawn::VertexFormat::Half4:
|
||||
return VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
case dawn::VertexFormat::Float:
|
||||
return VK_FORMAT_R32_SFLOAT;
|
||||
case dawn::VertexFormat::Float2:
|
||||
return VK_FORMAT_R32G32_SFLOAT;
|
||||
case dawn::VertexFormat::Float3:
|
||||
return VK_FORMAT_R32G32B32_SFLOAT;
|
||||
case dawn::VertexFormat::Float4:
|
||||
return VK_FORMAT_R32G32B32A32_SFLOAT;
|
||||
case dawn::VertexFormat::UInt:
|
||||
return VK_FORMAT_R32_UINT;
|
||||
case dawn::VertexFormat::UInt2:
|
||||
return VK_FORMAT_R32G32_UINT;
|
||||
case dawn::VertexFormat::UInt3:
|
||||
return VK_FORMAT_R32G32B32_UINT;
|
||||
case dawn::VertexFormat::UInt4:
|
||||
return VK_FORMAT_R32G32B32A32_UINT;
|
||||
case dawn::VertexFormat::Int:
|
||||
return VK_FORMAT_R32_SINT;
|
||||
case dawn::VertexFormat::Int2:
|
||||
return VK_FORMAT_R32G32_SINT;
|
||||
case dawn::VertexFormat::Int3:
|
||||
return VK_FORMAT_R32G32B32_SINT;
|
||||
case dawn::VertexFormat::Int4:
|
||||
return VK_FORMAT_R32G32B32A32_SINT;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
VkPrimitiveTopology VulkanPrimitiveTopology(dawn::PrimitiveTopology topology) {
|
||||
switch (topology) {
|
||||
case dawn::PrimitiveTopology::PointList:
|
||||
|
@ -218,6 +295,12 @@ namespace dawn_native { namespace vulkan {
|
|||
shaderStages[1].pName = descriptor->fragmentStage->entryPoint;
|
||||
}
|
||||
|
||||
std::array<VkVertexInputBindingDescription, kMaxVertexInputs> mBindings;
|
||||
std::array<VkVertexInputAttributeDescription, kMaxVertexAttributes> mAttributes;
|
||||
const InputStateDescriptor* inputState = GetInputStateDescriptor();
|
||||
VkPipelineVertexInputStateCreateInfo inputStateCreateInfo =
|
||||
ComputeInputStateDesc(inputState, &mBindings, &mAttributes);
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo inputAssembly;
|
||||
inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
||||
inputAssembly.pNext = nullptr;
|
||||
|
@ -341,7 +424,7 @@ namespace dawn_native { namespace vulkan {
|
|||
createInfo.flags = 0;
|
||||
createInfo.stageCount = 2;
|
||||
createInfo.pStages = shaderStages;
|
||||
createInfo.pVertexInputState = ToBackend(GetInputState())->GetCreateInfo();
|
||||
createInfo.pVertexInputState = &inputStateCreateInfo;
|
||||
createInfo.pInputAssemblyState = &inputAssembly;
|
||||
createInfo.pTessellationState = nullptr;
|
||||
createInfo.pViewportState = &viewport;
|
||||
|
@ -362,6 +445,49 @@ namespace dawn_native { namespace vulkan {
|
|||
}
|
||||
}
|
||||
|
||||
VkPipelineVertexInputStateCreateInfo RenderPipeline::ComputeInputStateDesc(
|
||||
const InputStateDescriptor* inputState,
|
||||
std::array<VkVertexInputBindingDescription, kMaxVertexInputs>* mBindings,
|
||||
std::array<VkVertexInputAttributeDescription, kMaxVertexAttributes>* mAttributes) {
|
||||
// Fill in the "binding info" that will be chained in the create info
|
||||
uint32_t bindingCount = 0;
|
||||
for (uint32_t i : IterateBitSet(GetInputsSetMask())) {
|
||||
const auto& bindingInfo = GetInput(i);
|
||||
|
||||
auto& bindingDesc = (*mBindings)[bindingCount];
|
||||
bindingDesc.binding = i;
|
||||
bindingDesc.stride = bindingInfo.stride;
|
||||
bindingDesc.inputRate = VulkanInputRate(bindingInfo.stepMode);
|
||||
|
||||
bindingCount++;
|
||||
}
|
||||
|
||||
// Fill in the "attribute info" that will be chained in the create info
|
||||
uint32_t attributeCount = 0;
|
||||
for (uint32_t i : IterateBitSet(GetAttributesSetMask())) {
|
||||
const auto& attributeInfo = GetAttribute(i);
|
||||
|
||||
auto& attributeDesc = (*mAttributes)[attributeCount];
|
||||
attributeDesc.location = i;
|
||||
attributeDesc.binding = attributeInfo.inputSlot;
|
||||
attributeDesc.format = VulkanVertexFormat(attributeInfo.format);
|
||||
attributeDesc.offset = attributeInfo.offset;
|
||||
|
||||
attributeCount++;
|
||||
}
|
||||
|
||||
// Build the create info
|
||||
VkPipelineVertexInputStateCreateInfo mCreateInfo;
|
||||
mCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
||||
mCreateInfo.pNext = nullptr;
|
||||
mCreateInfo.flags = 0;
|
||||
mCreateInfo.vertexBindingDescriptionCount = bindingCount;
|
||||
mCreateInfo.pVertexBindingDescriptions = &(*mBindings)[0];
|
||||
mCreateInfo.vertexAttributeDescriptionCount = attributeCount;
|
||||
mCreateInfo.pVertexAttributeDescriptions = &(*mAttributes)[0];
|
||||
return mCreateInfo;
|
||||
}
|
||||
|
||||
RenderPipeline::~RenderPipeline() {
|
||||
if (mHandle != VK_NULL_HANDLE) {
|
||||
ToBackend(GetDevice())->GetFencedDeleter()->DeleteWhenUnused(mHandle);
|
||||
|
|
|
@ -31,6 +31,11 @@ namespace dawn_native { namespace vulkan {
|
|||
VkPipeline GetHandle() const;
|
||||
|
||||
private:
|
||||
VkPipelineVertexInputStateCreateInfo ComputeInputStateDesc(
|
||||
const InputStateDescriptor* inputState,
|
||||
std::array<VkVertexInputBindingDescription, kMaxVertexInputs>* mBindings,
|
||||
std::array<VkVertexInputAttributeDescription, kMaxVertexAttributes>* mAttributes);
|
||||
|
||||
VkPipeline mHandle = VK_NULL_HANDLE;
|
||||
};
|
||||
|
||||
|
|
|
@ -36,9 +36,6 @@ class DestroyBufferTest : public DawnTest {
|
|||
attribute.offset = 0;
|
||||
attribute.format = dawn::VertexFormat::Float4;
|
||||
|
||||
dawn::InputState inputState =
|
||||
device.CreateInputStateBuilder().SetInput(&input).SetAttribute(&attribute).GetResult();
|
||||
|
||||
dawn::ShaderModule vsModule =
|
||||
utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, R"(
|
||||
#version 450
|
||||
|
@ -60,7 +57,10 @@ class DestroyBufferTest : public DawnTest {
|
|||
descriptor.cFragmentStage.module = fsModule;
|
||||
descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleStrip;
|
||||
descriptor.indexFormat = dawn::IndexFormat::Uint32;
|
||||
descriptor.inputState = inputState;
|
||||
descriptor.cInputState.numInputs = 1;
|
||||
descriptor.cInputState.inputs = &input;
|
||||
descriptor.cInputState.numAttributes = 1;
|
||||
descriptor.cInputState.attributes = &attribute;
|
||||
descriptor.cColorStates[0]->format = renderPass.colorFormat;
|
||||
|
||||
pipeline = device.CreateRenderPipeline(&descriptor);
|
||||
|
@ -135,4 +135,4 @@ TEST_P(DestroyBufferTest, SubmitDestroySubmit) {
|
|||
EXPECT_PIXEL_RGBA8_EQ(filled, renderPass.color, 1, 3);
|
||||
}
|
||||
|
||||
DAWN_INSTANTIATE_TEST(DestroyBufferTest, D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend);
|
||||
DAWN_INSTANTIATE_TEST(DestroyBufferTest, D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend);
|
||||
|
|
|
@ -37,18 +37,13 @@ class DrawIndexedTest : public DawnTest {
|
|||
attribute.offset = 0;
|
||||
attribute.format = dawn::VertexFormat::Float4;
|
||||
|
||||
dawn::InputState inputState = device.CreateInputStateBuilder()
|
||||
.SetInput(&input)
|
||||
.SetAttribute(&attribute)
|
||||
.GetResult();
|
||||
|
||||
dawn::ShaderModule vsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, R"(
|
||||
dawn::ShaderModule vsModule =
|
||||
utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, R"(
|
||||
#version 450
|
||||
layout(location = 0) in vec4 pos;
|
||||
void main() {
|
||||
gl_Position = pos;
|
||||
})"
|
||||
);
|
||||
})");
|
||||
|
||||
dawn::ShaderModule fsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, R"(
|
||||
#version 450
|
||||
|
@ -63,7 +58,10 @@ class DrawIndexedTest : public DawnTest {
|
|||
descriptor.cFragmentStage.module = fsModule;
|
||||
descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleStrip;
|
||||
descriptor.indexFormat = dawn::IndexFormat::Uint32;
|
||||
descriptor.inputState = inputState;
|
||||
descriptor.cInputState.numInputs = 1;
|
||||
descriptor.cInputState.inputs = &input;
|
||||
descriptor.cInputState.numAttributes = 1;
|
||||
descriptor.cInputState.attributes = &attribute;
|
||||
descriptor.cColorStates[0]->format = renderPass.colorFormat;
|
||||
|
||||
pipeline = device.CreateRenderPipeline(&descriptor);
|
||||
|
|
|
@ -37,9 +37,6 @@ class DrawTest : public DawnTest {
|
|||
attribute.offset = 0;
|
||||
attribute.format = dawn::VertexFormat::Float4;
|
||||
|
||||
dawn::InputState inputState =
|
||||
device.CreateInputStateBuilder().SetInput(&input).SetAttribute(&attribute).GetResult();
|
||||
|
||||
dawn::ShaderModule vsModule =
|
||||
utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, R"(
|
||||
#version 450
|
||||
|
@ -61,7 +58,10 @@ class DrawTest : public DawnTest {
|
|||
descriptor.cFragmentStage.module = fsModule;
|
||||
descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleStrip;
|
||||
descriptor.indexFormat = dawn::IndexFormat::Uint32;
|
||||
descriptor.inputState = inputState;
|
||||
descriptor.cInputState.numInputs = 1;
|
||||
descriptor.cInputState.inputs = &input;
|
||||
descriptor.cInputState.numAttributes = 1;
|
||||
descriptor.cInputState.attributes = &attribute;
|
||||
descriptor.cColorStates[0]->format = renderPass.colorFormat;
|
||||
|
||||
pipeline = device.CreateRenderPipeline(&descriptor);
|
||||
|
|
|
@ -42,11 +42,6 @@ class IndexFormatTest : public DawnTest {
|
|||
attribute.offset = 0;
|
||||
attribute.format = dawn::VertexFormat::Float4;
|
||||
|
||||
dawn::InputState inputState = device.CreateInputStateBuilder()
|
||||
.SetInput(&input)
|
||||
.SetAttribute(&attribute)
|
||||
.GetResult();
|
||||
|
||||
dawn::ShaderModule vsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, R"(
|
||||
#version 450
|
||||
layout(location = 0) in vec4 pos;
|
||||
|
@ -68,7 +63,10 @@ class IndexFormatTest : public DawnTest {
|
|||
descriptor.cFragmentStage.module = fsModule;
|
||||
descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleStrip;
|
||||
descriptor.indexFormat = format;
|
||||
descriptor.inputState = inputState;
|
||||
descriptor.cInputState.numInputs = 1;
|
||||
descriptor.cInputState.inputs = &input;
|
||||
descriptor.cInputState.numAttributes = 1;
|
||||
descriptor.cInputState.attributes = &attribute;
|
||||
descriptor.cColorStates[0]->format = renderPass.colorFormat;
|
||||
|
||||
return device.CreateRenderPipeline(&descriptor);
|
||||
|
|
|
@ -64,7 +64,9 @@ class InputStateTest : public DawnTest {
|
|||
VertexFormat format;
|
||||
InputStepMode step;
|
||||
};
|
||||
dawn::RenderPipeline MakeTestPipeline(const dawn::InputState& inputState, int multiplier, std::vector<ShaderTestSpec> testSpec) {
|
||||
dawn::RenderPipeline MakeTestPipeline(const dawn::InputStateDescriptor& inputState,
|
||||
int multiplier,
|
||||
std::vector<ShaderTestSpec> testSpec) {
|
||||
std::ostringstream vs;
|
||||
vs << "#version 450\n";
|
||||
|
||||
|
@ -124,7 +126,7 @@ class InputStateTest : public DawnTest {
|
|||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
descriptor.cFragmentStage.module = fsModule;
|
||||
descriptor.inputState = inputState;
|
||||
descriptor.inputState = &inputState;
|
||||
descriptor.cColorStates[0]->format = renderPass.colorFormat;
|
||||
|
||||
return device.CreateRenderPipeline(&descriptor);
|
||||
|
@ -141,28 +143,30 @@ class InputStateTest : public DawnTest {
|
|||
uint32_t offset;
|
||||
VertexFormat format;
|
||||
};
|
||||
dawn::InputState MakeInputState(std::vector<InputSpec> inputs, std::vector<AttributeSpec> attributes) {
|
||||
dawn::InputStateBuilder builder = device.CreateInputStateBuilder();
|
||||
|
||||
dawn::InputStateDescriptor MakeInputState(std::vector<InputSpec> inputs,
|
||||
std::vector<AttributeSpec> attributes) {
|
||||
dawn::InputStateDescriptor inputState;
|
||||
uint32_t numInputs = 0;
|
||||
for (const auto& input : inputs) {
|
||||
dawn::VertexInputDescriptor descriptor;
|
||||
descriptor.inputSlot = input.slot;
|
||||
descriptor.stride = input.stride;
|
||||
descriptor.stepMode = input.step;
|
||||
builder.SetInput(&descriptor);
|
||||
vertexInputs[numInputs].inputSlot = input.slot;
|
||||
vertexInputs[numInputs].stride = input.stride;
|
||||
vertexInputs[numInputs].stepMode = input.step;
|
||||
numInputs++;
|
||||
}
|
||||
|
||||
uint32_t numAttributes = 0;
|
||||
for (const auto& attribute : attributes) {
|
||||
dawn::VertexAttributeDescriptor descriptor;
|
||||
descriptor.shaderLocation = attribute.location;
|
||||
descriptor.inputSlot = attribute.slot;
|
||||
descriptor.offset = attribute.offset;
|
||||
descriptor.format = attribute.format;
|
||||
|
||||
builder.SetAttribute(&descriptor);
|
||||
vertexAttributes[numAttributes].shaderLocation = attribute.location;
|
||||
vertexAttributes[numAttributes].inputSlot = attribute.slot;
|
||||
vertexAttributes[numAttributes].offset = attribute.offset;
|
||||
vertexAttributes[numAttributes].format = attribute.format;
|
||||
numAttributes++;
|
||||
}
|
||||
|
||||
return builder.GetResult();
|
||||
inputState.numInputs = numInputs;
|
||||
inputState.inputs = vertexInputs;
|
||||
inputState.numAttributes = numAttributes;
|
||||
inputState.attributes = vertexAttributes;
|
||||
return inputState;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -214,16 +218,14 @@ class InputStateTest : public DawnTest {
|
|||
}
|
||||
|
||||
utils::BasicRenderPass renderPass;
|
||||
dawn::VertexAttributeDescriptor vertexAttributes[kMaxVertexAttributes];
|
||||
dawn::VertexInputDescriptor vertexInputs[kMaxVertexInputs];
|
||||
};
|
||||
|
||||
// Test compilation and usage of the fixture :)
|
||||
TEST_P(InputStateTest, Basic) {
|
||||
dawn::InputState inputState = MakeInputState({
|
||||
{0, 4 * sizeof(float), InputStepMode::Vertex}
|
||||
}, {
|
||||
{0, 0, 0, VertexFormat::Float4}
|
||||
}
|
||||
);
|
||||
dawn::InputStateDescriptor inputState = MakeInputState(
|
||||
{{0, 4 * sizeof(float), InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float4}});
|
||||
dawn::RenderPipeline pipeline = MakeTestPipeline(inputState, 1, {
|
||||
{0, VertexFormat::Float4, InputStepMode::Vertex}
|
||||
});
|
||||
|
@ -241,12 +243,8 @@ TEST_P(InputStateTest, ZeroStride) {
|
|||
// This test was failing only on AMD but the OpenGL backend doesn't gather PCI info yet.
|
||||
DAWN_SKIP_TEST_IF(IsLinux() && IsOpenGL());
|
||||
|
||||
dawn::InputState inputState = MakeInputState({
|
||||
{0, 0, InputStepMode::Vertex}
|
||||
}, {
|
||||
{0, 0, 0, VertexFormat::Float4}
|
||||
}
|
||||
);
|
||||
dawn::InputStateDescriptor inputState =
|
||||
MakeInputState({{0, 0, InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float4}});
|
||||
dawn::RenderPipeline pipeline = MakeTestPipeline(inputState, 0, {
|
||||
{0, VertexFormat::Float4, InputStepMode::Vertex}
|
||||
});
|
||||
|
@ -264,12 +262,8 @@ TEST_P(InputStateTest, AttributeExpanding) {
|
|||
|
||||
// R32F case
|
||||
{
|
||||
dawn::InputState inputState = MakeInputState({
|
||||
{0, 0, InputStepMode::Vertex}
|
||||
}, {
|
||||
{0, 0, 0, VertexFormat::Float}
|
||||
}
|
||||
);
|
||||
dawn::InputStateDescriptor inputState =
|
||||
MakeInputState({{0, 0, InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float}});
|
||||
dawn::RenderPipeline pipeline = MakeTestPipeline(inputState, 0, {
|
||||
{0, VertexFormat::Float, InputStepMode::Vertex}
|
||||
});
|
||||
|
@ -281,12 +275,8 @@ TEST_P(InputStateTest, AttributeExpanding) {
|
|||
}
|
||||
// RG32F case
|
||||
{
|
||||
dawn::InputState inputState = MakeInputState({
|
||||
{0, 0, InputStepMode::Vertex}
|
||||
}, {
|
||||
{0, 0, 0, VertexFormat::Float2}
|
||||
}
|
||||
);
|
||||
dawn::InputStateDescriptor inputState =
|
||||
MakeInputState({{0, 0, InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float2}});
|
||||
dawn::RenderPipeline pipeline = MakeTestPipeline(inputState, 0, {
|
||||
{0, VertexFormat::Float2, InputStepMode::Vertex}
|
||||
});
|
||||
|
@ -298,12 +288,8 @@ TEST_P(InputStateTest, AttributeExpanding) {
|
|||
}
|
||||
// RGB32F case
|
||||
{
|
||||
dawn::InputState inputState = MakeInputState({
|
||||
{0, 0, InputStepMode::Vertex}
|
||||
}, {
|
||||
{0, 0, 0, VertexFormat::Float3}
|
||||
}
|
||||
);
|
||||
dawn::InputStateDescriptor inputState =
|
||||
MakeInputState({{0, 0, InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float3}});
|
||||
dawn::RenderPipeline pipeline = MakeTestPipeline(inputState, 0, {
|
||||
{0, VertexFormat::Float3, InputStepMode::Vertex}
|
||||
});
|
||||
|
@ -320,12 +306,8 @@ TEST_P(InputStateTest, StrideLargerThanAttributes) {
|
|||
// This test was failing only on AMD but the OpenGL backend doesn't gather PCI info yet.
|
||||
DAWN_SKIP_TEST_IF(IsLinux() && IsOpenGL());
|
||||
|
||||
dawn::InputState inputState = MakeInputState({
|
||||
{0, 8 * sizeof(float), InputStepMode::Vertex}
|
||||
}, {
|
||||
{0, 0, 0, VertexFormat::Float4}
|
||||
}
|
||||
);
|
||||
dawn::InputStateDescriptor inputState = MakeInputState(
|
||||
{{0, 8 * sizeof(float), InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float4}});
|
||||
dawn::RenderPipeline pipeline = MakeTestPipeline(inputState, 1, {
|
||||
{0, VertexFormat::Float4, InputStepMode::Vertex}
|
||||
});
|
||||
|
@ -340,13 +322,9 @@ TEST_P(InputStateTest, StrideLargerThanAttributes) {
|
|||
|
||||
// Test two attributes at an offset, vertex version
|
||||
TEST_P(InputStateTest, TwoAttributesAtAnOffsetVertex) {
|
||||
dawn::InputState inputState = MakeInputState({
|
||||
{0, 8 * sizeof(float), InputStepMode::Vertex}
|
||||
}, {
|
||||
{0, 0, 0, VertexFormat::Float4},
|
||||
{1, 0, 4 * sizeof(float), VertexFormat::Float4}
|
||||
}
|
||||
);
|
||||
dawn::InputStateDescriptor inputState = MakeInputState(
|
||||
{{0, 8 * sizeof(float), InputStepMode::Vertex}},
|
||||
{{0, 0, 0, VertexFormat::Float4}, {1, 0, 4 * sizeof(float), VertexFormat::Float4}});
|
||||
dawn::RenderPipeline pipeline = MakeTestPipeline(inputState, 1, {
|
||||
{0, VertexFormat::Float4, InputStepMode::Vertex}
|
||||
});
|
||||
|
@ -361,13 +339,9 @@ TEST_P(InputStateTest, TwoAttributesAtAnOffsetVertex) {
|
|||
|
||||
// Test two attributes at an offset, instance version
|
||||
TEST_P(InputStateTest, TwoAttributesAtAnOffsetInstance) {
|
||||
dawn::InputState inputState = MakeInputState({
|
||||
{0, 8 * sizeof(float), InputStepMode::Instance}
|
||||
}, {
|
||||
{0, 0, 0, VertexFormat::Float4},
|
||||
{1, 0, 4 * sizeof(float), VertexFormat::Float4}
|
||||
}
|
||||
);
|
||||
dawn::InputStateDescriptor inputState = MakeInputState(
|
||||
{{0, 8 * sizeof(float), InputStepMode::Instance}},
|
||||
{{0, 0, 0, VertexFormat::Float4}, {1, 0, 4 * sizeof(float), VertexFormat::Float4}});
|
||||
dawn::RenderPipeline pipeline = MakeTestPipeline(inputState, 1, {
|
||||
{0, VertexFormat::Float4, InputStepMode::Instance}
|
||||
});
|
||||
|
@ -382,12 +356,8 @@ TEST_P(InputStateTest, TwoAttributesAtAnOffsetInstance) {
|
|||
|
||||
// Test a pure-instance input state
|
||||
TEST_P(InputStateTest, PureInstance) {
|
||||
dawn::InputState inputState = MakeInputState({
|
||||
{0, 4 * sizeof(float), InputStepMode::Instance}
|
||||
}, {
|
||||
{0, 0, 0, VertexFormat::Float4}
|
||||
}
|
||||
);
|
||||
dawn::InputStateDescriptor inputState = MakeInputState(
|
||||
{{0, 4 * sizeof(float), InputStepMode::Instance}}, {{0, 0, 0, VertexFormat::Float4}});
|
||||
dawn::RenderPipeline pipeline = MakeTestPipeline(inputState, 1, {
|
||||
{0, VertexFormat::Float4, InputStepMode::Instance}
|
||||
});
|
||||
|
@ -404,16 +374,15 @@ TEST_P(InputStateTest, PureInstance) {
|
|||
// Test with mixed everything, vertex vs. instance, different stride and offsets
|
||||
// different attribute types
|
||||
TEST_P(InputStateTest, MixedEverything) {
|
||||
dawn::InputState inputState = MakeInputState({
|
||||
dawn::InputStateDescriptor inputState = MakeInputState(
|
||||
{
|
||||
{0, 12 * sizeof(float), InputStepMode::Vertex},
|
||||
{1, 10 * sizeof(float), InputStepMode::Instance},
|
||||
}, {
|
||||
{0, 0, 0, VertexFormat::Float},
|
||||
{1, 0, 6 * sizeof(float), VertexFormat::Float2},
|
||||
{2, 1, 0, VertexFormat::Float3},
|
||||
{3, 1, 5 * sizeof(float), VertexFormat::Float4}
|
||||
}
|
||||
);
|
||||
},
|
||||
{{0, 0, 0, VertexFormat::Float},
|
||||
{1, 0, 6 * sizeof(float), VertexFormat::Float2},
|
||||
{2, 1, 0, VertexFormat::Float3},
|
||||
{3, 1, 5 * sizeof(float), VertexFormat::Float4}});
|
||||
dawn::RenderPipeline pipeline = MakeTestPipeline(inputState, 1, {
|
||||
{0, VertexFormat::Float, InputStepMode::Vertex},
|
||||
{1, VertexFormat::Float2, InputStepMode::Vertex},
|
||||
|
@ -439,9 +408,8 @@ TEST_P(InputStateTest, MixedEverything) {
|
|||
// Test input state is unaffected by unused vertex slot
|
||||
TEST_P(InputStateTest, UnusedVertexSlot) {
|
||||
// Instance input state, using slot 1
|
||||
dawn::InputState instanceInputState =
|
||||
MakeInputState({{1, 4 * sizeof(float), InputStepMode::Instance}},
|
||||
{{0, 1, 0, VertexFormat::Float4}});
|
||||
dawn::InputStateDescriptor instanceInputState = MakeInputState(
|
||||
{{1, 4 * sizeof(float), InputStepMode::Instance}}, {{0, 1, 0, VertexFormat::Float4}});
|
||||
dawn::RenderPipeline instancePipeline = MakeTestPipeline(
|
||||
instanceInputState, 1, {{0, VertexFormat::Float4, InputStepMode::Instance}});
|
||||
|
||||
|
@ -477,16 +445,14 @@ TEST_P(InputStateTest, UnusedVertexSlot) {
|
|||
// SetVertexBuffers should be reapplied when the input state changes.
|
||||
TEST_P(InputStateTest, MultiplePipelinesMixedInputState) {
|
||||
// Basic input state, using slot 0
|
||||
dawn::InputState vertexInputState =
|
||||
MakeInputState({{0, 4 * sizeof(float), InputStepMode::Vertex}},
|
||||
{{0, 0, 0, VertexFormat::Float4}});
|
||||
dawn::InputStateDescriptor vertexInputState = MakeInputState(
|
||||
{{0, 4 * sizeof(float), InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float4}});
|
||||
dawn::RenderPipeline vertexPipeline = MakeTestPipeline(
|
||||
vertexInputState, 1, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
|
||||
|
||||
// Instance input state, using slot 1
|
||||
dawn::InputState instanceInputState =
|
||||
MakeInputState({{1, 4 * sizeof(float), InputStepMode::Instance}},
|
||||
{{0, 1, 0, VertexFormat::Float4}});
|
||||
dawn::InputStateDescriptor instanceInputState = MakeInputState(
|
||||
{{1, 4 * sizeof(float), InputStepMode::Instance}}, {{0, 1, 0, VertexFormat::Float4}});
|
||||
dawn::RenderPipeline instancePipeline = MakeTestPipeline(
|
||||
instanceInputState, 1, {{0, VertexFormat::Float4, InputStepMode::Instance}});
|
||||
|
||||
|
|
|
@ -165,22 +165,6 @@ class PrimitiveTopologyTest : public DawnTest {
|
|||
fragColor = vec4(0.0, 1.0, 0.0, 1.0);
|
||||
})");
|
||||
|
||||
dawn::VertexAttributeDescriptor attribute;
|
||||
attribute.shaderLocation = 0;
|
||||
attribute.inputSlot = 0;
|
||||
attribute.offset = 0;
|
||||
attribute.format = dawn::VertexFormat::Float4;
|
||||
|
||||
dawn::VertexInputDescriptor input;
|
||||
input.inputSlot = 0;
|
||||
input.stride = 4 * sizeof(float);
|
||||
input.stepMode = dawn::InputStepMode::Vertex;
|
||||
|
||||
inputState = device.CreateInputStateBuilder()
|
||||
.SetAttribute(&attribute)
|
||||
.SetInput(&input)
|
||||
.GetResult();
|
||||
|
||||
vertexBuffer = utils::CreateBufferFromData(device, kVertices, sizeof(kVertices), dawn::BufferUsageBit::Vertex);
|
||||
}
|
||||
|
||||
|
@ -197,12 +181,25 @@ class PrimitiveTopologyTest : public DawnTest {
|
|||
|
||||
// Draw the vertices with the given primitive topology and check the pixel values of the test locations
|
||||
void DoTest(dawn::PrimitiveTopology primitiveTopology, const std::vector<LocationSpec> &locationSpecs) {
|
||||
dawn::VertexAttributeDescriptor attribute;
|
||||
attribute.shaderLocation = 0;
|
||||
attribute.inputSlot = 0;
|
||||
attribute.offset = 0;
|
||||
attribute.format = dawn::VertexFormat::Float4;
|
||||
|
||||
dawn::VertexInputDescriptor input;
|
||||
input.inputSlot = 0;
|
||||
input.stride = 4 * sizeof(float);
|
||||
input.stepMode = dawn::InputStepMode::Vertex;
|
||||
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
descriptor.cFragmentStage.module = fsModule;
|
||||
descriptor.primitiveTopology = primitiveTopology;
|
||||
descriptor.inputState = inputState;
|
||||
descriptor.cInputState.numInputs = 1;
|
||||
descriptor.cInputState.inputs = &input;
|
||||
descriptor.cInputState.numAttributes = 1;
|
||||
descriptor.cInputState.attributes = &attribute;
|
||||
descriptor.cColorStates[0]->format = renderPass.colorFormat;
|
||||
|
||||
dawn::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
|
||||
|
@ -234,7 +231,6 @@ class PrimitiveTopologyTest : public DawnTest {
|
|||
utils::BasicRenderPass renderPass;
|
||||
dawn::ShaderModule vsModule;
|
||||
dawn::ShaderModule fsModule;
|
||||
dawn::InputState inputState;
|
||||
dawn::Buffer vertexBuffer;
|
||||
};
|
||||
|
||||
|
|
|
@ -25,9 +25,13 @@ constexpr static dawn::VertexInputDescriptor kBaseInput = {
|
|||
|
||||
class InputStateTest : public ValidationTest {
|
||||
protected:
|
||||
void CreatePipeline(bool success, const dawn::InputState& inputState, std::string vertexSource) {
|
||||
dawn::ShaderModule vsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, vertexSource.c_str());
|
||||
dawn::ShaderModule fsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, R"(
|
||||
void CreatePipeline(bool success,
|
||||
const dawn::InputStateDescriptor* state,
|
||||
std::string vertexSource) {
|
||||
dawn::ShaderModule vsModule =
|
||||
utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, vertexSource.c_str());
|
||||
dawn::ShaderModule fsModule =
|
||||
utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, R"(
|
||||
#version 450
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
void main() {
|
||||
|
@ -35,26 +39,25 @@ class InputStateTest : public ValidationTest {
|
|||
}
|
||||
)");
|
||||
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
descriptor.cFragmentStage.module = fsModule;
|
||||
descriptor.inputState = inputState;
|
||||
descriptor.cColorStates[0]->format = dawn::TextureFormat::R8G8B8A8Unorm;
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
descriptor.cFragmentStage.module = fsModule;
|
||||
if (state) {
|
||||
descriptor.inputState = state;
|
||||
}
|
||||
descriptor.cColorStates[0]->format = dawn::TextureFormat::R8G8B8A8Unorm;
|
||||
|
||||
if (!success) {
|
||||
ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor));
|
||||
} else {
|
||||
device.CreateRenderPipeline(&descriptor);
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor));
|
||||
} else {
|
||||
device.CreateRenderPipeline(&descriptor);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Check an empty input state is valid
|
||||
TEST_F(InputStateTest, EmptyIsOk) {
|
||||
dawn::InputState state = AssertWillBeSuccess(device.CreateInputStateBuilder())
|
||||
.GetResult();
|
||||
|
||||
CreatePipeline(true, state, R"(
|
||||
CreatePipeline(true, nullptr, R"(
|
||||
#version 450
|
||||
void main() {
|
||||
gl_Position = vec4(0.0);
|
||||
|
@ -64,31 +67,30 @@ TEST_F(InputStateTest, EmptyIsOk) {
|
|||
|
||||
// Check validation that pipeline vertex inputs are backed by attributes in the input state
|
||||
TEST_F(InputStateTest, PipelineCompatibility) {
|
||||
dawn::VertexAttributeDescriptor attribute1;
|
||||
attribute1.shaderLocation = 0;
|
||||
attribute1.inputSlot = 0;
|
||||
attribute1.offset = 0;
|
||||
attribute1.format = dawn::VertexFormat::Float;
|
||||
dawn::VertexAttributeDescriptor attribute[2];
|
||||
attribute[0].shaderLocation = 0;
|
||||
attribute[0].inputSlot = 0;
|
||||
attribute[0].offset = 0;
|
||||
attribute[0].format = dawn::VertexFormat::Float;
|
||||
|
||||
dawn::VertexAttributeDescriptor attribute2;
|
||||
attribute2.shaderLocation = 1;
|
||||
attribute2.inputSlot = 0;
|
||||
attribute2.offset = sizeof(float);
|
||||
attribute2.format = dawn::VertexFormat::Float;
|
||||
attribute[1].shaderLocation = 1;
|
||||
attribute[1].inputSlot = 0;
|
||||
attribute[1].offset = sizeof(float);
|
||||
attribute[1].format = dawn::VertexFormat::Float;
|
||||
|
||||
dawn::VertexInputDescriptor input;
|
||||
input.inputSlot = 0;
|
||||
input.stride = 2 * sizeof(float);
|
||||
input.stepMode = dawn::InputStepMode::Vertex;
|
||||
|
||||
dawn::InputState state = AssertWillBeSuccess(device.CreateInputStateBuilder())
|
||||
.SetInput(&input)
|
||||
.SetAttribute(&attribute1)
|
||||
.SetAttribute(&attribute2)
|
||||
.GetResult();
|
||||
dawn::InputStateDescriptor state;
|
||||
state.numInputs = 1;
|
||||
state.inputs = &input;
|
||||
state.numAttributes = 2;
|
||||
state.attributes = attribute;
|
||||
|
||||
// Control case: pipeline with one input per attribute
|
||||
CreatePipeline(true, state, R"(
|
||||
CreatePipeline(true, &state, R"(
|
||||
#version 450
|
||||
layout(location = 0) in vec4 a;
|
||||
layout(location = 1) in vec4 b;
|
||||
|
@ -98,7 +100,7 @@ TEST_F(InputStateTest, PipelineCompatibility) {
|
|||
)");
|
||||
|
||||
// Check it is valid for the pipeline to use a subset of the InputState
|
||||
CreatePipeline(true, state, R"(
|
||||
CreatePipeline(true, &state, R"(
|
||||
#version 450
|
||||
layout(location = 0) in vec4 a;
|
||||
void main() {
|
||||
|
@ -107,7 +109,7 @@ TEST_F(InputStateTest, PipelineCompatibility) {
|
|||
)");
|
||||
|
||||
// Check for an error when the pipeline uses an attribute not in the input state
|
||||
CreatePipeline(false, state, R"(
|
||||
CreatePipeline(false, &state, R"(
|
||||
#version 450
|
||||
layout(location = 2) in vec4 a;
|
||||
void main() {
|
||||
|
@ -119,7 +121,17 @@ TEST_F(InputStateTest, PipelineCompatibility) {
|
|||
// Test that a stride of 0 is valid
|
||||
TEST_F(InputStateTest, StrideZero) {
|
||||
// Works ok without attributes
|
||||
AssertWillBeSuccess(device.CreateInputStateBuilder()).SetInput(&kBaseInput).GetResult();
|
||||
dawn::InputStateDescriptor state;
|
||||
state.numInputs = 1;
|
||||
state.inputs = &kBaseInput;
|
||||
state.numAttributes = 0;
|
||||
|
||||
CreatePipeline(true, &state, R"(
|
||||
#version 450
|
||||
void main() {
|
||||
gl_Position = vec4(0.0);
|
||||
}
|
||||
)");
|
||||
|
||||
// Works ok with attributes at a large-ish offset
|
||||
dawn::VertexAttributeDescriptor attribute;
|
||||
|
@ -128,22 +140,42 @@ TEST_F(InputStateTest, StrideZero) {
|
|||
attribute.offset = 128;
|
||||
attribute.format = dawn::VertexFormat::Float;
|
||||
|
||||
AssertWillBeSuccess(device.CreateInputStateBuilder())
|
||||
.SetInput(&kBaseInput)
|
||||
.SetAttribute(&attribute)
|
||||
.GetResult();
|
||||
state.numAttributes = 1;
|
||||
state.attributes = &attribute;
|
||||
CreatePipeline(true, &state, R"(
|
||||
#version 450
|
||||
void main() {
|
||||
gl_Position = vec4(0.0);
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
// Test that we cannot set an already set input
|
||||
TEST_F(InputStateTest, AlreadySetInput) {
|
||||
// Control case
|
||||
AssertWillBeSuccess(device.CreateInputStateBuilder()).SetInput(&kBaseInput).GetResult();
|
||||
dawn::InputStateDescriptor state;
|
||||
state.numInputs = 1;
|
||||
state.inputs = &kBaseInput;
|
||||
state.numAttributes = 0;
|
||||
|
||||
CreatePipeline(true, &state, R"(
|
||||
#version 450
|
||||
void main() {
|
||||
gl_Position = vec4(0.0);
|
||||
}
|
||||
)");
|
||||
|
||||
// Oh no, input 0 is set twice
|
||||
AssertWillBeError(device.CreateInputStateBuilder())
|
||||
.SetInput(&kBaseInput)
|
||||
.SetInput(&kBaseInput)
|
||||
.GetResult();
|
||||
dawn::VertexInputDescriptor vertexInput[2] = {kBaseInput, kBaseInput};
|
||||
state.numInputs = 2;
|
||||
state.inputs = vertexInput;
|
||||
|
||||
CreatePipeline(false, &state, R"(
|
||||
#version 450
|
||||
void main() {
|
||||
gl_Position = vec4(0.0);
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
// Check out of bounds condition on input slot
|
||||
|
@ -154,11 +186,26 @@ TEST_F(InputStateTest, SetInputSlotOutOfBounds) {
|
|||
input.stride = 0;
|
||||
input.stepMode = dawn::InputStepMode::Vertex;
|
||||
|
||||
AssertWillBeSuccess(device.CreateInputStateBuilder()).SetInput(&input).GetResult();
|
||||
dawn::InputStateDescriptor state;
|
||||
state.numInputs = 1;
|
||||
state.inputs = &input;
|
||||
state.numAttributes = 0;
|
||||
|
||||
CreatePipeline(true, &state, R"(
|
||||
#version 450
|
||||
void main() {
|
||||
gl_Position = vec4(0.0);
|
||||
}
|
||||
)");
|
||||
|
||||
// Test input slot OOB
|
||||
input.inputSlot = kMaxVertexInputs;
|
||||
AssertWillBeError(device.CreateInputStateBuilder()).SetInput(&input).GetResult();
|
||||
CreatePipeline(false, &state, R"(
|
||||
#version 450
|
||||
void main() {
|
||||
gl_Position = vec4(0.0);
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
// Check out of bounds condition on input stride
|
||||
|
@ -168,11 +215,27 @@ TEST_F(InputStateTest, SetInputStrideOutOfBounds) {
|
|||
input.inputSlot = 0;
|
||||
input.stride = kMaxVertexInputStride;
|
||||
input.stepMode = dawn::InputStepMode::Vertex;
|
||||
AssertWillBeSuccess(device.CreateInputStateBuilder()).SetInput(&input).GetResult();
|
||||
|
||||
dawn::InputStateDescriptor state;
|
||||
state.numInputs = 1;
|
||||
state.inputs = &input;
|
||||
state.numAttributes = 0;
|
||||
|
||||
CreatePipeline(true, &state, R"(
|
||||
#version 450
|
||||
void main() {
|
||||
gl_Position = vec4(0.0);
|
||||
}
|
||||
)");
|
||||
|
||||
// Test input stride OOB
|
||||
input.stride = kMaxVertexInputStride + 1;
|
||||
AssertWillBeError(device.CreateInputStateBuilder()).SetInput(&input).GetResult();
|
||||
CreatePipeline(false, &state, R"(
|
||||
#version 450
|
||||
void main() {
|
||||
gl_Position = vec4(0.0);
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
// Test that we cannot set an already set attribute
|
||||
|
@ -184,17 +247,30 @@ TEST_F(InputStateTest, AlreadySetAttribute) {
|
|||
attribute.offset = 0;
|
||||
attribute.format = dawn::VertexFormat::Float;
|
||||
|
||||
AssertWillBeSuccess(device.CreateInputStateBuilder())
|
||||
.SetInput(&kBaseInput)
|
||||
.SetAttribute(&attribute)
|
||||
.GetResult();
|
||||
dawn::InputStateDescriptor state;
|
||||
state.numInputs = 1;
|
||||
state.inputs = &kBaseInput;
|
||||
state.numAttributes = 1;
|
||||
state.attributes = &attribute;
|
||||
|
||||
CreatePipeline(true, &state, R"(
|
||||
#version 450
|
||||
void main() {
|
||||
gl_Position = vec4(0.0);
|
||||
}
|
||||
)");
|
||||
|
||||
// Oh no, attribute 0 is set twice
|
||||
AssertWillBeError(device.CreateInputStateBuilder())
|
||||
.SetInput(&kBaseInput)
|
||||
.SetAttribute(&attribute)
|
||||
.SetAttribute(&attribute)
|
||||
.GetResult();
|
||||
dawn::VertexAttributeDescriptor vertexAttribute[2] = {attribute, attribute};
|
||||
state.numAttributes = 2;
|
||||
state.attributes = vertexAttribute;
|
||||
|
||||
CreatePipeline(false, &state, R"(
|
||||
#version 450
|
||||
void main() {
|
||||
gl_Position = vec4(0.0);
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
// Check out of bounds condition on attribute shader location
|
||||
|
@ -206,17 +282,27 @@ TEST_F(InputStateTest, SetAttributeLocationOutOfBounds) {
|
|||
attribute.offset = 0;
|
||||
attribute.format = dawn::VertexFormat::Float;
|
||||
|
||||
AssertWillBeSuccess(device.CreateInputStateBuilder())
|
||||
.SetInput(&kBaseInput)
|
||||
.SetAttribute(&attribute)
|
||||
.GetResult();
|
||||
dawn::InputStateDescriptor state;
|
||||
state.numInputs = 1;
|
||||
state.inputs = &kBaseInput;
|
||||
state.numAttributes = 1;
|
||||
state.attributes = &attribute;
|
||||
|
||||
CreatePipeline(true, &state, R"(
|
||||
#version 450
|
||||
void main() {
|
||||
gl_Position = vec4(0.0);
|
||||
}
|
||||
)");
|
||||
|
||||
// Test attribute location OOB
|
||||
attribute.shaderLocation = kMaxVertexAttributes;
|
||||
AssertWillBeError(device.CreateInputStateBuilder())
|
||||
.SetInput(&kBaseInput)
|
||||
.SetAttribute(&attribute)
|
||||
.GetResult();
|
||||
CreatePipeline(false, &state, R"(
|
||||
#version 450
|
||||
void main() {
|
||||
gl_Position = vec4(0.0);
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
// Check attribute offset out of bounds
|
||||
|
@ -227,17 +313,28 @@ TEST_F(InputStateTest, SetAttributeOffsetOutOfBounds) {
|
|||
attribute.inputSlot = 0;
|
||||
attribute.offset = kMaxVertexAttributeEnd - sizeof(dawn::VertexFormat::Float);
|
||||
attribute.format = dawn::VertexFormat::Float;
|
||||
AssertWillBeSuccess(device.CreateInputStateBuilder())
|
||||
.SetInput(&kBaseInput)
|
||||
.SetAttribute(&attribute)
|
||||
.GetResult();
|
||||
|
||||
dawn::InputStateDescriptor state;
|
||||
state.numInputs = 1;
|
||||
state.inputs = &kBaseInput;
|
||||
state.numAttributes = 1;
|
||||
state.attributes = &attribute;
|
||||
|
||||
CreatePipeline(true, &state, R"(
|
||||
#version 450
|
||||
void main() {
|
||||
gl_Position = vec4(0.0);
|
||||
}
|
||||
)");
|
||||
|
||||
// Test attribute offset out of bounds
|
||||
attribute.offset = kMaxVertexAttributeEnd - 1;
|
||||
AssertWillBeError(device.CreateInputStateBuilder())
|
||||
.SetInput(&kBaseInput)
|
||||
.SetAttribute(&attribute)
|
||||
.GetResult();
|
||||
CreatePipeline(false, &state, R"(
|
||||
#version 450
|
||||
void main() {
|
||||
gl_Position = vec4(0.0);
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
// Check attribute offset overflow
|
||||
|
@ -247,10 +344,19 @@ TEST_F(InputStateTest, SetAttributeOffsetOverflow) {
|
|||
attribute.inputSlot = 0;
|
||||
attribute.offset = std::numeric_limits<uint32_t>::max();
|
||||
attribute.format = dawn::VertexFormat::Float;
|
||||
AssertWillBeError(device.CreateInputStateBuilder())
|
||||
.SetInput(&kBaseInput)
|
||||
.SetAttribute(&attribute)
|
||||
.GetResult();
|
||||
|
||||
dawn::InputStateDescriptor state;
|
||||
state.numInputs = 1;
|
||||
state.inputs = &kBaseInput;
|
||||
state.numAttributes = 1;
|
||||
state.attributes = &attribute;
|
||||
|
||||
CreatePipeline(false, &state, R"(
|
||||
#version 450
|
||||
void main() {
|
||||
gl_Position = vec4(0.0);
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
// Check that all attributes must be backed by an input
|
||||
|
@ -262,17 +368,27 @@ TEST_F(InputStateTest, RequireInputForAttribute) {
|
|||
attribute.offset = 0;
|
||||
attribute.format = dawn::VertexFormat::Float;
|
||||
|
||||
AssertWillBeSuccess(device.CreateInputStateBuilder())
|
||||
.SetInput(&kBaseInput)
|
||||
.SetAttribute(&attribute)
|
||||
.GetResult();
|
||||
dawn::InputStateDescriptor state;
|
||||
state.numInputs = 1;
|
||||
state.inputs = &kBaseInput;
|
||||
state.numAttributes = 1;
|
||||
state.attributes = &attribute;
|
||||
|
||||
CreatePipeline(true, &state, R"(
|
||||
#version 450
|
||||
void main() {
|
||||
gl_Position = vec4(0.0);
|
||||
}
|
||||
)");
|
||||
|
||||
// Attribute 0 uses input 1 which doesn't exist
|
||||
attribute.inputSlot = 1;
|
||||
AssertWillBeError(device.CreateInputStateBuilder())
|
||||
.SetInput(&kBaseInput)
|
||||
.SetAttribute(&attribute)
|
||||
.GetResult();
|
||||
CreatePipeline(false, &state, R"(
|
||||
#version 450
|
||||
void main() {
|
||||
gl_Position = vec4(0.0);
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
// Check OOB checks for an attribute's input
|
||||
|
@ -284,15 +400,25 @@ TEST_F(InputStateTest, SetAttributeOOBCheckForInputs) {
|
|||
attribute.offset = 0;
|
||||
attribute.format = dawn::VertexFormat::Float;
|
||||
|
||||
AssertWillBeSuccess(device.CreateInputStateBuilder())
|
||||
.SetInput(&kBaseInput)
|
||||
.SetAttribute(&attribute)
|
||||
.GetResult();
|
||||
dawn::InputStateDescriptor state;
|
||||
state.numInputs = 1;
|
||||
state.inputs = &kBaseInput;
|
||||
state.numAttributes = 1;
|
||||
state.attributes = &attribute;
|
||||
|
||||
CreatePipeline(true, &state, R"(
|
||||
#version 450
|
||||
void main() {
|
||||
gl_Position = vec4(0.0);
|
||||
}
|
||||
)");
|
||||
|
||||
// Could crash if we didn't check for OOB
|
||||
attribute.inputSlot = 1000000;
|
||||
AssertWillBeError(device.CreateInputStateBuilder())
|
||||
.SetInput(&kBaseInput)
|
||||
.SetAttribute(&attribute)
|
||||
.GetResult();
|
||||
CreatePipeline(false, &state, R"(
|
||||
#version 450
|
||||
void main() {
|
||||
gl_Position = vec4(0.0);
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
|
|
@ -67,8 +67,12 @@ class VertexBufferValidationTest : public ValidationTest {
|
|||
return utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, vs.str().c_str());
|
||||
}
|
||||
|
||||
dawn::InputState MakeInputState(unsigned int numInputs) {
|
||||
auto builder = device.CreateInputStateBuilder();
|
||||
dawn::RenderPipeline MakeRenderPipeline(const dawn::ShaderModule& vsModule,
|
||||
unsigned int numInputs) {
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
descriptor.cFragmentStage.module = fsModule;
|
||||
|
||||
dawn::VertexAttributeDescriptor attribute;
|
||||
attribute.offset = 0;
|
||||
attribute.format = dawn::VertexFormat::Float3;
|
||||
|
@ -77,22 +81,19 @@ class VertexBufferValidationTest : public ValidationTest {
|
|||
input.stride = 0;
|
||||
input.stepMode = dawn::InputStepMode::Vertex;
|
||||
|
||||
dawn::VertexInputDescriptor vertexInputs[kMaxVertexInputs];
|
||||
dawn::VertexAttributeDescriptor vertexAttributes[kMaxVertexAttributes];
|
||||
for (unsigned int i = 0; i < numInputs; ++i) {
|
||||
attribute.shaderLocation = i;
|
||||
attribute.inputSlot = i;
|
||||
input.inputSlot = i;
|
||||
builder.SetAttribute(&attribute);
|
||||
builder.SetInput(&input);
|
||||
vertexInputs[i] = input;
|
||||
vertexAttributes[i] = attribute;
|
||||
}
|
||||
return builder.GetResult();
|
||||
}
|
||||
|
||||
dawn::RenderPipeline MakeRenderPipeline(const dawn::ShaderModule& vsModule, const dawn::InputState& inputState) {
|
||||
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
descriptor.cFragmentStage.module = fsModule;
|
||||
descriptor.inputState = inputState;
|
||||
descriptor.cInputState.numInputs = numInputs;
|
||||
descriptor.cInputState.inputs = vertexInputs;
|
||||
descriptor.cInputState.numAttributes = numInputs;
|
||||
descriptor.cInputState.attributes = vertexAttributes;
|
||||
|
||||
return device.CreateRenderPipeline(&descriptor);
|
||||
}
|
||||
|
@ -105,11 +106,8 @@ TEST_F(VertexBufferValidationTest, VertexInputsInheritedBetweenPipelines) {
|
|||
auto vsModule2 = MakeVertexShader(2);
|
||||
auto vsModule1 = MakeVertexShader(1);
|
||||
|
||||
auto inputState2 = MakeInputState(2);
|
||||
auto inputState1 = MakeInputState(1);
|
||||
|
||||
auto pipeline2 = MakeRenderPipeline(vsModule2, inputState2);
|
||||
auto pipeline1 = MakeRenderPipeline(vsModule1, inputState1);
|
||||
auto pipeline2 = MakeRenderPipeline(vsModule2, 2);
|
||||
auto pipeline1 = MakeRenderPipeline(vsModule1, 1);
|
||||
|
||||
auto vertexBuffers = MakeVertexBuffers<2>();
|
||||
uint32_t offsets[] = { 0, 0 };
|
||||
|
@ -143,11 +141,8 @@ TEST_F(VertexBufferValidationTest, VertexInputsNotInheritedBetweenRendePasses) {
|
|||
auto vsModule2 = MakeVertexShader(2);
|
||||
auto vsModule1 = MakeVertexShader(1);
|
||||
|
||||
auto inputState2 = MakeInputState(2);
|
||||
auto inputState1 = MakeInputState(1);
|
||||
|
||||
auto pipeline2 = MakeRenderPipeline(vsModule2, inputState2);
|
||||
auto pipeline1 = MakeRenderPipeline(vsModule1, inputState1);
|
||||
auto pipeline2 = MakeRenderPipeline(vsModule2, 2);
|
||||
auto pipeline1 = MakeRenderPipeline(vsModule1, 1);
|
||||
|
||||
auto vertexBuffers = MakeVertexBuffers<2>();
|
||||
uint32_t offsets[] = { 0, 0 };
|
||||
|
|
|
@ -101,15 +101,12 @@ TEST_F(WireArgumentTests, CStringArgument) {
|
|||
colorStateDescriptor.colorWriteMask = DAWN_COLOR_WRITE_MASK_ALL;
|
||||
|
||||
// Create the input state
|
||||
DawnInputStateBuilder inputStateBuilder = dawnDeviceCreateInputStateBuilder(device);
|
||||
DawnInputStateBuilder apiInputStateBuilder = api.GetNewInputStateBuilder();
|
||||
EXPECT_CALL(api, DeviceCreateInputStateBuilder(apiDevice))
|
||||
.WillOnce(Return(apiInputStateBuilder));
|
||||
|
||||
DawnInputState inputState = dawnInputStateBuilderGetResult(inputStateBuilder);
|
||||
DawnInputState apiInputState = api.GetNewInputState();
|
||||
EXPECT_CALL(api, InputStateBuilderGetResult(apiInputStateBuilder))
|
||||
.WillOnce(Return(apiInputState));
|
||||
DawnInputStateDescriptor inputState;
|
||||
inputState.nextInChain = nullptr;
|
||||
inputState.numInputs = 0;
|
||||
inputState.inputs = nullptr;
|
||||
inputState.numAttributes = 0;
|
||||
inputState.attributes = nullptr;
|
||||
|
||||
// Create the depth-stencil state
|
||||
DawnStencilStateFaceDescriptor stencilFace;
|
||||
|
@ -159,7 +156,7 @@ TEST_F(WireArgumentTests, CStringArgument) {
|
|||
|
||||
pipelineDescriptor.sampleCount = 1;
|
||||
pipelineDescriptor.layout = layout;
|
||||
pipelineDescriptor.inputState = inputState;
|
||||
pipelineDescriptor.inputState = &inputState;
|
||||
pipelineDescriptor.indexFormat = DAWN_INDEX_FORMAT_UINT32;
|
||||
pipelineDescriptor.primitiveTopology = DAWN_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
pipelineDescriptor.depthStencilState = &depthStencilState;
|
||||
|
@ -172,8 +169,6 @@ TEST_F(WireArgumentTests, CStringArgument) {
|
|||
})))
|
||||
.WillOnce(Return(nullptr));
|
||||
EXPECT_CALL(api, ShaderModuleRelease(apiVsModule));
|
||||
EXPECT_CALL(api, InputStateBuilderRelease(apiInputStateBuilder));
|
||||
EXPECT_CALL(api, InputStateRelease(apiInputState));
|
||||
EXPECT_CALL(api, PipelineLayoutRelease(apiLayout));
|
||||
|
||||
FlushClient();
|
||||
|
|
|
@ -86,15 +86,12 @@ TEST_F(WireOptionalTests, OptionalStructPointer) {
|
|||
colorStateDescriptor.colorWriteMask = DAWN_COLOR_WRITE_MASK_ALL;
|
||||
|
||||
// Create the input state
|
||||
DawnInputStateBuilder inputStateBuilder = dawnDeviceCreateInputStateBuilder(device);
|
||||
DawnInputStateBuilder apiInputStateBuilder = api.GetNewInputStateBuilder();
|
||||
EXPECT_CALL(api, DeviceCreateInputStateBuilder(apiDevice))
|
||||
.WillOnce(Return(apiInputStateBuilder));
|
||||
|
||||
DawnInputState inputState = dawnInputStateBuilderGetResult(inputStateBuilder);
|
||||
DawnInputState apiInputState = api.GetNewInputState();
|
||||
EXPECT_CALL(api, InputStateBuilderGetResult(apiInputStateBuilder))
|
||||
.WillOnce(Return(apiInputState));
|
||||
DawnInputStateDescriptor inputState;
|
||||
inputState.nextInChain = nullptr;
|
||||
inputState.numInputs = 0;
|
||||
inputState.inputs = nullptr;
|
||||
inputState.numAttributes = 0;
|
||||
inputState.attributes = nullptr;
|
||||
|
||||
// Create the depth-stencil state
|
||||
DawnStencilStateFaceDescriptor stencilFace;
|
||||
|
@ -144,7 +141,7 @@ TEST_F(WireOptionalTests, OptionalStructPointer) {
|
|||
|
||||
pipelineDescriptor.sampleCount = 1;
|
||||
pipelineDescriptor.layout = layout;
|
||||
pipelineDescriptor.inputState = inputState;
|
||||
pipelineDescriptor.inputState = &inputState;
|
||||
pipelineDescriptor.indexFormat = DAWN_INDEX_FORMAT_UINT32;
|
||||
pipelineDescriptor.primitiveTopology = DAWN_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
|
||||
|
@ -191,8 +188,6 @@ TEST_F(WireOptionalTests, OptionalStructPointer) {
|
|||
.WillOnce(Return(nullptr));
|
||||
|
||||
EXPECT_CALL(api, ShaderModuleRelease(apiVsModule));
|
||||
EXPECT_CALL(api, InputStateBuilderRelease(apiInputStateBuilder));
|
||||
EXPECT_CALL(api, InputStateRelease(apiInputState));
|
||||
EXPECT_CALL(api, PipelineLayoutRelease(apiLayout));
|
||||
|
||||
FlushClient();
|
||||
|
|
|
@ -37,6 +37,15 @@ namespace utils {
|
|||
cFragmentStage.entryPoint = "main";
|
||||
}
|
||||
|
||||
// Set defaults for the input state descriptors.
|
||||
{
|
||||
descriptor->inputState = &cInputState;
|
||||
cInputState.numInputs = 0;
|
||||
cInputState.inputs = nullptr;
|
||||
cInputState.numAttributes = 0;
|
||||
cInputState.attributes = nullptr;
|
||||
}
|
||||
|
||||
// Set defaults for the color state descriptors.
|
||||
{
|
||||
descriptor->colorStateCount = 1;
|
||||
|
@ -75,7 +84,6 @@ namespace utils {
|
|||
descriptor->depthStencilState = nullptr;
|
||||
}
|
||||
|
||||
descriptor->inputState = device.CreateInputStateBuilder().GetResult();
|
||||
descriptor->layout = utils::MakeBasicPipelineLayout(device, nullptr);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace utils {
|
|||
dawn::PipelineStageDescriptor cVertexStage;
|
||||
dawn::PipelineStageDescriptor cFragmentStage;
|
||||
|
||||
dawn::InputStateDescriptor cInputState;
|
||||
std::array<dawn::ColorStateDescriptor*, kMaxColorAttachments> cColorStates;
|
||||
dawn::DepthStencilStateDescriptor cDepthStencilState;
|
||||
|
||||
|
|
Loading…
Reference in New Issue