Render Pipeline Descriptorization -- Part I

This patch remove render pipeline builder and use descriptor to create render pipeline.
Sub-objects in descriptor will be removed in future.

Bug: dawn:4
Change-Id: I58dd569c7be42c2648311847b939c681189c2854
Reviewed-on: https://dawn-review.googlesource.com/c/2180
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
Yan, Shaobo 2018-12-10 19:47:22 +00:00 committed by Commit Bot service account
parent 07df605a2b
commit a49242766a
51 changed files with 916 additions and 763 deletions

View File

@ -731,6 +731,8 @@ static_library("dawn_utils") {
sources = [ sources = [
"src/utils/BackendBinding.cpp", "src/utils/BackendBinding.cpp",
"src/utils/BackendBinding.h", "src/utils/BackendBinding.h",
"src/utils/ComboRenderPipelineDescriptor.cpp",
"src/utils/ComboRenderPipelineDescriptor.h",
"src/utils/DawnHelpers.cpp", "src/utils/DawnHelpers.cpp",
"src/utils/DawnHelpers.h", "src/utils/DawnHelpers.h",
"src/utils/SystemUtils.cpp", "src/utils/SystemUtils.cpp",

114
dawn.json
View File

@ -22,6 +22,13 @@
{"value": 2, "name":"clamp to edge"} {"value": 2, "name":"clamp to edge"}
] ]
}, },
"attachment descriptor": {
"category": "structure",
"extensible": true,
"members": [
{"name": "format", "type": "texture format"}
]
},
"bind group": { "bind group": {
"category": "object" "category": "object"
}, },
@ -463,8 +470,11 @@
] ]
}, },
{ {
"name": "create render pipeline builder", "name": "create render pipeline",
"returns": "render pipeline builder" "returns": "render pipeline",
"args": [
{"name": "descriptor", "type": "render pipeline descriptor", "annotation": "const*"}
]
}, },
{ {
"name": "create pipeline layout", "name": "create pipeline layout",
@ -679,6 +689,16 @@
{"name": "z", "type": "uint32_t"} {"name": "z", "type": "uint32_t"}
] ]
}, },
"attachments state descriptor": {
"category": "structure",
"extensible": true,
"members": [
{"name": "num color attachments", "type": "uint32_t"},
{"name": "color attachments", "type": "attachment descriptor", "annotation": "const*", "length": "num color attachments"},
{"name": "has depth stencil attachment", "type": "bool"},
{"name": "depth stencil attachment", "type": "attachment descriptor", "annotation":"const*"}
]
},
"pipeline layout": { "pipeline layout": {
"category": "object" "category": "object"
}, },
@ -690,6 +710,14 @@
{"name": "bind group layouts", "type": "bind group layout", "annotation": "const*", "length": "num bind group layouts"} {"name": "bind group layouts", "type": "bind group layout", "annotation": "const*", "length": "num bind group layouts"}
] ]
}, },
"pipeline stage descriptor": {
"category": "structure",
"extensible": true,
"members": [
{"name": "module", "type": "shader module"},
{"name": "entry point", "type": "char", "annotation": "const*", "length": "strlen"}
]
},
"primitive topology": { "primitive topology": {
"category": "enum", "category": "enum",
"values": [ "values": [
@ -863,73 +891,21 @@
"render pipeline": { "render pipeline": {
"category": "object" "category": "object"
}, },
"render pipeline builder": { "render pipeline descriptor": {
"category": "object", "category": "structure",
"methods": [ "extensible": true,
{ "members": [
"name": "get result", {"name": "layout", "type": "pipeline layout"},
"returns": "render pipeline" {"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": "set color attachment format", {"name": "index format", "type": "index format"},
"TODO": "Also need sample count", {"name": "primitive topology", "type": "primitive topology"},
"args": [ {"name": "attachments state", "type": "attachments state descriptor", "annotation": "const*"},
{"name": "attachment slot", "type": "uint32_t"}, {"name": "sample count", "type": "uint32_t"},
{"name": "format", "type": "texture format"} {"name": "depth stencil state", "type": "depth stencil state"},
] {"name": "num blend states", "type": "uint32_t"},
}, {"name": "blend states", "type": "blend state", "annotation": "const*", "length": "num blend states"}
{
"name": "set depth stencil attachment format",
"TODO": "Also need sample count",
"args": [
{"name": "format", "type": "texture format"}
]
},
{
"name": "set color attachment blend state",
"args": [
{"name": "attachment slot", "type": "uint32_t"},
{"name": "blend state", "type": "blend state"}
]
},
{
"name": "set depth stencil state",
"args": [
{"name": "depth stencil state", "type": "depth stencil state"}
]
},
{
"name": "set index format",
"args": [
{"name": "format", "type": "index format"}
]
},
{
"name": "set input state",
"args": [
{"name": "input", "type": "input state"}
]
},
{
"name": "set layout",
"args": [
{"name": "layout", "type": "pipeline layout"}
]
},
{
"name": "set primitive topology",
"args": [
{"name": "primitive topology", "type": "primitive topology"}
]
},
{
"name": "set stage",
"args": [
{"name": "stage", "type": "shader stage"},
{"name": "module", "type": "shader module"},
{"name": "entry point", "type": "char", "annotation": "const*", "length": "strlen"}
]
}
] ]
}, },
"sampler": { "sampler": {

View File

@ -14,6 +14,7 @@
#include "SampleUtils.h" #include "SampleUtils.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h" #include "utils/DawnHelpers.h"
#include "utils/SystemUtils.h" #include "utils/SystemUtils.h"
@ -109,12 +110,15 @@ void init() {
depthStencilView = CreateDefaultDepthStencilView(device); depthStencilView = CreateDefaultDepthStencilView(device);
pipeline = device.CreateRenderPipelineBuilder() utils::ComboRenderPipelineDescriptor descriptor(device);
.SetColorAttachmentFormat(0, GetPreferredSwapChainTextureFormat()) descriptor.cVertexStage.module = vsModule;
.SetDepthStencilAttachmentFormat(dawn::TextureFormat::D32FloatS8Uint) descriptor.cFragmentStage.module = fsModule;
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main") descriptor.cAttachmentsState.hasDepthStencilAttachment = true;
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main") descriptor.cDepthStencilAttachment.format = dawn::TextureFormat::D32FloatS8Uint;
.GetResult(); descriptor.cColorAttachments[0].format =
GetPreferredSwapChainTextureFormat();
pipeline = device.CreateRenderPipeline(&descriptor);
shaderData.resize(10000); shaderData.resize(10000);
for (auto& data : shaderData) { for (auto& data : shaderData) {

View File

@ -56,12 +56,62 @@ void init() {
dawnShaderModule fsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, fs).Release(); dawnShaderModule fsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, fs).Release();
{ {
dawnRenderPipelineBuilder builder = dawnDeviceCreateRenderPipelineBuilder(device); dawnRenderPipelineDescriptor descriptor;
dawnRenderPipelineBuilderSetColorAttachmentFormat(builder, 0, swapChainFormat); descriptor.nextInChain = nullptr;
dawnRenderPipelineBuilderSetStage(builder, DAWN_SHADER_STAGE_VERTEX, vsModule, "main");
dawnRenderPipelineBuilderSetStage(builder, DAWN_SHADER_STAGE_FRAGMENT, fsModule, "main"); dawnPipelineStageDescriptor vertexStage;
pipeline = dawnRenderPipelineBuilderGetResult(builder); vertexStage.nextInChain = nullptr;
dawnRenderPipelineBuilderRelease(builder); vertexStage.module = vsModule;
vertexStage.entryPoint = "main";
descriptor.vertexStage = &vertexStage;
dawnPipelineStageDescriptor fragmentStage;
fragmentStage.nextInChain = nullptr;
fragmentStage.module = fsModule;
fragmentStage.entryPoint = "main";
descriptor.fragmentStage = &fragmentStage;
dawnAttachmentsStateDescriptor attachmentsState;
attachmentsState.nextInChain = nullptr;
attachmentsState.numColorAttachments = 1;
dawnAttachmentDescriptor colorAttachment = {nullptr, swapChainFormat};
attachmentsState.colorAttachments = &colorAttachment;
attachmentsState.hasDepthStencilAttachment = false;
// Even with hasDepthStencilAttachment = false, depthStencilAttachment must point to valid
// data because we don't have optional substructures yet.
attachmentsState.depthStencilAttachment = &colorAttachment;
descriptor.attachmentsState = &attachmentsState;
descriptor.sampleCount = 1;
descriptor.numBlendStates = 1;
dawnBlendStateBuilder blendStateBuilder = dawnDeviceCreateBlendStateBuilder(device);
dawnBlendState blendState = dawnBlendStateBuilderGetResult(blendStateBuilder);
descriptor.blendStates = &blendState;
dawnBlendStateBuilderRelease(blendStateBuilder);
dawnPipelineLayoutDescriptor pl;
pl.nextInChain = nullptr;
pl.numBindGroupLayouts = 0;
pl.bindGroupLayouts = nullptr;
descriptor.layout = dawnDeviceCreatePipelineLayout(device, &pl);
dawnInputStateBuilder inputStateBuilder = dawnDeviceCreateInputStateBuilder(device);
descriptor.inputState = dawnInputStateBuilderGetResult(inputStateBuilder);
dawnInputStateBuilderRelease(inputStateBuilder);
descriptor.indexFormat = DAWN_INDEX_FORMAT_UINT32;
descriptor.primitiveTopology = DAWN_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
dawnDepthStencilStateBuilder depthStencilBuilder = dawnDeviceCreateDepthStencilStateBuilder(device);
descriptor.depthStencilState = dawnDepthStencilStateBuilderGetResult(depthStencilBuilder);
dawnDepthStencilStateBuilderRelease(depthStencilBuilder);
pipeline = dawnDeviceCreateRenderPipeline(device, &descriptor);
dawnBlendStateRelease(descriptor.blendStates[0]);
dawnDepthStencilStateRelease(descriptor.depthStencilState);
dawnInputStateRelease(descriptor.inputState);
} }
dawnShaderModuleRelease(vsModule); dawnShaderModuleRelease(vsModule);

View File

@ -14,6 +14,7 @@
#include "SampleUtils.h" #include "SampleUtils.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h" #include "utils/DawnHelpers.h"
#include "utils/SystemUtils.h" #include "utils/SystemUtils.h"
@ -123,13 +124,16 @@ void initRender() {
depthStencilView = CreateDefaultDepthStencilView(device); depthStencilView = CreateDefaultDepthStencilView(device);
renderPipeline = device.CreateRenderPipelineBuilder() utils::ComboRenderPipelineDescriptor descriptor(device);
.SetColorAttachmentFormat(0, GetPreferredSwapChainTextureFormat()) descriptor.cVertexStage.module = vsModule;
.SetDepthStencilAttachmentFormat(dawn::TextureFormat::D32FloatS8Uint) descriptor.cFragmentStage.module = fsModule;
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main") descriptor.inputState = inputState;
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main") descriptor.cAttachmentsState.hasDepthStencilAttachment = true;
.SetInputState(inputState) descriptor.cDepthStencilAttachment.format = dawn::TextureFormat::D32FloatS8Uint;
.GetResult(); descriptor.cColorAttachments[0].format =
GetPreferredSwapChainTextureFormat();
renderPipeline = device.CreateRenderPipeline(&descriptor);
} }
void initSim() { void initSim() {

View File

@ -14,6 +14,7 @@
#include "SampleUtils.h" #include "SampleUtils.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h" #include "utils/DawnHelpers.h"
#include "utils/SystemUtils.h" #include "utils/SystemUtils.h"
@ -125,15 +126,17 @@ void init() {
depthStencilView = CreateDefaultDepthStencilView(device); depthStencilView = CreateDefaultDepthStencilView(device);
pipeline = device.CreateRenderPipelineBuilder() utils::ComboRenderPipelineDescriptor descriptor(device);
.SetColorAttachmentFormat(0, GetPreferredSwapChainTextureFormat()) descriptor.layout = utils::MakeBasicPipelineLayout(device, &bgl);
.SetDepthStencilAttachmentFormat(dawn::TextureFormat::D32FloatS8Uint) descriptor.cVertexStage.module = vsModule;
.SetLayout(pl) descriptor.cFragmentStage.module = fsModule;
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main") descriptor.inputState = inputState;
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main") descriptor.cAttachmentsState.hasDepthStencilAttachment = true;
.SetIndexFormat(dawn::IndexFormat::Uint32) descriptor.cDepthStencilAttachment.format = dawn::TextureFormat::D32FloatS8Uint;
.SetInputState(inputState) descriptor.cColorAttachments[0].format =
.GetResult(); GetPreferredSwapChainTextureFormat();
pipeline = device.CreateRenderPipeline(&descriptor);
dawn::TextureView view = texture.CreateDefaultTextureView(); dawn::TextureView view = texture.CreateDefaultTextureView();

View File

@ -14,6 +14,7 @@
#include "SampleUtils.h" #include "SampleUtils.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h" #include "utils/DawnHelpers.h"
#include "utils/SystemUtils.h" #include "utils/SystemUtils.h"
@ -197,16 +198,18 @@ void init() {
.SetDepthWriteEnabled(true) .SetDepthWriteEnabled(true)
.GetResult(); .GetResult();
pipeline = device.CreateRenderPipelineBuilder() utils::ComboRenderPipelineDescriptor descriptor(device);
.SetColorAttachmentFormat(0, GetPreferredSwapChainTextureFormat()) descriptor.layout = pl;
.SetDepthStencilAttachmentFormat(dawn::TextureFormat::D32FloatS8Uint) descriptor.cVertexStage.module = vsModule;
.SetLayout(pl) descriptor.cFragmentStage.module = fsModule;
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main") descriptor.inputState = inputState;
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main") descriptor.cAttachmentsState.hasDepthStencilAttachment = true;
.SetIndexFormat(dawn::IndexFormat::Uint32) descriptor.cDepthStencilAttachment.format = dawn::TextureFormat::D32FloatS8Uint;
.SetInputState(inputState) descriptor.cColorAttachments[0].format =
.SetDepthStencilState(depthStencilState) GetPreferredSwapChainTextureFormat();
.GetResult(); descriptor.depthStencilState = depthStencilState;
pipeline = device.CreateRenderPipeline(&descriptor);
auto planeStencilState = device.CreateDepthStencilStateBuilder() auto planeStencilState = device.CreateDepthStencilStateBuilder()
.SetDepthCompareFunction(dawn::CompareFunction::Less) .SetDepthCompareFunction(dawn::CompareFunction::Less)
@ -214,15 +217,18 @@ void init() {
.SetStencilFunction(dawn::Face::Both, dawn::CompareFunction::Always, dawn::StencilOperation::Keep, dawn::StencilOperation::Keep, dawn::StencilOperation::Replace) .SetStencilFunction(dawn::Face::Both, dawn::CompareFunction::Always, dawn::StencilOperation::Keep, dawn::StencilOperation::Keep, dawn::StencilOperation::Replace)
.GetResult(); .GetResult();
planePipeline = device.CreateRenderPipelineBuilder() utils::ComboRenderPipelineDescriptor pDescriptor(device);
.SetColorAttachmentFormat(0, GetPreferredSwapChainTextureFormat()) pDescriptor.layout = pl;
.SetDepthStencilAttachmentFormat(dawn::TextureFormat::D32FloatS8Uint) pDescriptor.cVertexStage.module = vsModule;
.SetLayout(pl) pDescriptor.cFragmentStage.module = fsModule;
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main") pDescriptor.inputState = inputState;
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main") pDescriptor.cAttachmentsState.hasDepthStencilAttachment = true;
.SetInputState(inputState) pDescriptor.cDepthStencilAttachment.format = dawn::TextureFormat::D32FloatS8Uint;
.SetDepthStencilState(planeStencilState) pDescriptor.cColorAttachments[0].format =
.GetResult(); GetPreferredSwapChainTextureFormat();
pDescriptor.depthStencilState = planeStencilState;
planePipeline = device.CreateRenderPipeline(&pDescriptor);
auto reflectionStencilState = device.CreateDepthStencilStateBuilder() auto reflectionStencilState = device.CreateDepthStencilStateBuilder()
.SetDepthCompareFunction(dawn::CompareFunction::Less) .SetDepthCompareFunction(dawn::CompareFunction::Less)
@ -230,15 +236,18 @@ void init() {
.SetStencilFunction(dawn::Face::Both, dawn::CompareFunction::Equal, dawn::StencilOperation::Keep, dawn::StencilOperation::Keep, dawn::StencilOperation::Replace) .SetStencilFunction(dawn::Face::Both, dawn::CompareFunction::Equal, dawn::StencilOperation::Keep, dawn::StencilOperation::Keep, dawn::StencilOperation::Replace)
.GetResult(); .GetResult();
reflectionPipeline = device.CreateRenderPipelineBuilder() utils::ComboRenderPipelineDescriptor rfDescriptor(device);
.SetColorAttachmentFormat(0, GetPreferredSwapChainTextureFormat()) rfDescriptor.layout = pl;
.SetDepthStencilAttachmentFormat(dawn::TextureFormat::D32FloatS8Uint) rfDescriptor.cVertexStage.module = vsModule;
.SetLayout(pl) rfDescriptor.cFragmentStage.module = fsReflectionModule;
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main") rfDescriptor.inputState = inputState;
.SetStage(dawn::ShaderStage::Fragment, fsReflectionModule, "main") rfDescriptor.cAttachmentsState.hasDepthStencilAttachment = true;
.SetInputState(inputState) rfDescriptor.cDepthStencilAttachment.format = dawn::TextureFormat::D32FloatS8Uint;
.SetDepthStencilState(reflectionStencilState) rfDescriptor.cColorAttachments[0].format =
.GetResult(); GetPreferredSwapChainTextureFormat();
rfDescriptor.depthStencilState = reflectionStencilState;
reflectionPipeline = device.CreateRenderPipeline(&rfDescriptor);
cameraData.proj = glm::perspective(glm::radians(45.0f), 1.f, 1.0f, 100.0f); cameraData.proj = glm::perspective(glm::radians(45.0f), 1.f, 1.0f, 100.0f);
} }

View File

@ -23,6 +23,7 @@
#include "common/Assert.h" #include "common/Assert.h"
#include "common/Math.h" #include "common/Math.h"
#include "common/Constants.h" #include "common/Constants.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h" #include "utils/DawnHelpers.h"
#include "utils/SystemUtils.h" #include "utils/SystemUtils.h"
@ -287,16 +288,20 @@ namespace {
.GetResult(); .GetResult();
auto pipelineLayout = utils::MakeBasicPipelineLayout(device, &bindGroupLayout); auto pipelineLayout = utils::MakeBasicPipelineLayout(device, &bindGroupLayout);
auto pipeline = device.CreateRenderPipelineBuilder()
.SetColorAttachmentFormat(0, GetPreferredSwapChainTextureFormat()) utils::ComboRenderPipelineDescriptor descriptor(device);
.SetDepthStencilAttachmentFormat(dawn::TextureFormat::D32FloatS8Uint) descriptor.layout = pipelineLayout;
.SetLayout(pipelineLayout) descriptor.cVertexStage.module = oVSModule;
.SetStage(dawn::ShaderStage::Vertex, oVSModule, "main") descriptor.cFragmentStage.module = oFSModule;
.SetStage(dawn::ShaderStage::Fragment, oFSModule, "main") descriptor.inputState = inputState;
.SetIndexFormat(dawn::IndexFormat::Uint16) descriptor.indexFormat = dawn::IndexFormat::Uint16;
.SetInputState(inputState) descriptor.cAttachmentsState.hasDepthStencilAttachment = true;
.SetDepthStencilState(depthStencilState) descriptor.cDepthStencilAttachment.format = dawn::TextureFormat::D32FloatS8Uint;
.GetResult(); descriptor.cColorAttachments[0].format =
GetPreferredSwapChainTextureFormat();
descriptor.depthStencilState = depthStencilState;
dawn::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
dawn::BindGroup bindGroup; dawn::BindGroup bindGroup;

View File

@ -182,9 +182,6 @@ namespace dawn_native {
RenderPassDescriptorBuilder* DeviceBase::CreateRenderPassDescriptorBuilder() { RenderPassDescriptorBuilder* DeviceBase::CreateRenderPassDescriptorBuilder() {
return new RenderPassDescriptorBuilder(this); return new RenderPassDescriptorBuilder(this);
} }
RenderPipelineBuilder* DeviceBase::CreateRenderPipelineBuilder() {
return new RenderPipelineBuilder(this);
}
SamplerBase* DeviceBase::CreateSampler(const SamplerDescriptor* descriptor) { SamplerBase* DeviceBase::CreateSampler(const SamplerDescriptor* descriptor) {
SamplerBase* result = nullptr; SamplerBase* result = nullptr;
@ -194,6 +191,16 @@ namespace dawn_native {
return result; return result;
} }
RenderPipelineBase* DeviceBase::CreateRenderPipeline(
const RenderPipelineDescriptor* descriptor) {
RenderPipelineBase* result = nullptr;
if (ConsumedError(CreateRenderPipelineInternal(&result, descriptor))) {
return nullptr;
}
return result;
}
ShaderModuleBase* DeviceBase::CreateShaderModule(const ShaderModuleDescriptor* descriptor) { ShaderModuleBase* DeviceBase::CreateShaderModule(const ShaderModuleDescriptor* descriptor) {
ShaderModuleBase* result = nullptr; ShaderModuleBase* result = nullptr;
@ -296,6 +303,14 @@ namespace dawn_native {
return {}; return {};
} }
MaybeError DeviceBase::CreateRenderPipelineInternal(
RenderPipelineBase** result,
const RenderPipelineDescriptor* descriptor) {
DAWN_TRY(ValidateRenderPipelineDescriptor(this, descriptor));
DAWN_TRY_ASSIGN(*result, CreateRenderPipelineImpl(descriptor));
return {};
}
MaybeError DeviceBase::CreateSamplerInternal(SamplerBase** result, MaybeError DeviceBase::CreateSamplerInternal(SamplerBase** result,
const SamplerDescriptor* descriptor) { const SamplerDescriptor* descriptor) {
DAWN_TRY(ValidateSamplerDescriptor(this, descriptor)); DAWN_TRY(ValidateSamplerDescriptor(this, descriptor));

View File

@ -58,7 +58,6 @@ namespace dawn_native {
virtual InputStateBase* CreateInputState(InputStateBuilder* builder) = 0; virtual InputStateBase* CreateInputState(InputStateBuilder* builder) = 0;
virtual RenderPassDescriptorBase* CreateRenderPassDescriptor( virtual RenderPassDescriptorBase* CreateRenderPassDescriptor(
RenderPassDescriptorBuilder* builder) = 0; RenderPassDescriptorBuilder* builder) = 0;
virtual RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) = 0;
virtual SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) = 0; virtual SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) = 0;
virtual Serial GetCompletedCommandSerial() const = 0; virtual Serial GetCompletedCommandSerial() const = 0;
@ -96,7 +95,7 @@ namespace dawn_native {
PipelineLayoutBase* CreatePipelineLayout(const PipelineLayoutDescriptor* descriptor); PipelineLayoutBase* CreatePipelineLayout(const PipelineLayoutDescriptor* descriptor);
QueueBase* CreateQueue(); QueueBase* CreateQueue();
RenderPassDescriptorBuilder* CreateRenderPassDescriptorBuilder(); RenderPassDescriptorBuilder* CreateRenderPassDescriptorBuilder();
RenderPipelineBuilder* CreateRenderPipelineBuilder(); RenderPipelineBase* CreateRenderPipeline(const RenderPipelineDescriptor* descriptor);
SamplerBase* CreateSampler(const SamplerDescriptor* descriptor); SamplerBase* CreateSampler(const SamplerDescriptor* descriptor);
ShaderModuleBase* CreateShaderModule(const ShaderModuleDescriptor* descriptor); ShaderModuleBase* CreateShaderModule(const ShaderModuleDescriptor* descriptor);
SwapChainBuilder* CreateSwapChainBuilder(); SwapChainBuilder* CreateSwapChainBuilder();
@ -127,6 +126,8 @@ namespace dawn_native {
virtual ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl( virtual ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl(
const PipelineLayoutDescriptor* descriptor) = 0; const PipelineLayoutDescriptor* descriptor) = 0;
virtual ResultOrError<QueueBase*> CreateQueueImpl() = 0; virtual ResultOrError<QueueBase*> CreateQueueImpl() = 0;
virtual ResultOrError<RenderPipelineBase*> CreateRenderPipelineImpl(
const RenderPipelineDescriptor* descriptor) = 0;
virtual ResultOrError<SamplerBase*> CreateSamplerImpl( virtual ResultOrError<SamplerBase*> CreateSamplerImpl(
const SamplerDescriptor* descriptor) = 0; const SamplerDescriptor* descriptor) = 0;
virtual ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl( virtual ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
@ -148,6 +149,8 @@ namespace dawn_native {
MaybeError CreatePipelineLayoutInternal(PipelineLayoutBase** result, MaybeError CreatePipelineLayoutInternal(PipelineLayoutBase** result,
const PipelineLayoutDescriptor* descriptor); const PipelineLayoutDescriptor* descriptor);
MaybeError CreateQueueInternal(QueueBase** result); MaybeError CreateQueueInternal(QueueBase** result);
MaybeError CreateRenderPipelineInternal(RenderPipelineBase** result,
const RenderPipelineDescriptor* descriptor);
MaybeError CreateSamplerInternal(SamplerBase** result, const SamplerDescriptor* descriptor); MaybeError CreateSamplerInternal(SamplerBase** result, const SamplerDescriptor* descriptor);
MaybeError CreateShaderModuleInternal(ShaderModuleBase** result, MaybeError CreateShaderModuleInternal(ShaderModuleBase** result,
const ShaderModuleDescriptor* descriptor); const ShaderModuleDescriptor* descriptor);

View File

@ -21,48 +21,141 @@
#include "dawn_native/InputState.h" #include "dawn_native/InputState.h"
#include "dawn_native/RenderPassDescriptor.h" #include "dawn_native/RenderPassDescriptor.h"
#include "dawn_native/Texture.h" #include "dawn_native/Texture.h"
#include "dawn_native/ValidationUtils_autogen.h"
namespace dawn_native { namespace dawn_native {
// Helper functions
namespace {
MaybeError ValidatePipelineStageDescriptor(const PipelineStageDescriptor* descriptor,
const PipelineLayoutBase* layout,
dawn::ShaderStage stage) {
if (descriptor->entryPoint != std::string("main")) {
return DAWN_VALIDATION_ERROR("Entry point must be \"main\"");
}
if (descriptor->module->GetExecutionModel() != stage) {
return DAWN_VALIDATION_ERROR("Setting module with wrong stages");
}
if (!descriptor->module->IsCompatibleWithPipelineLayout(layout)) {
return DAWN_VALIDATION_ERROR("Stage not compatible with layout");
}
return {};
}
MaybeError ValidateAttachmentsStateDescriptor(
const AttachmentsStateDescriptor* descriptor) {
if (descriptor->numColorAttachments > kMaxColorAttachments) {
return DAWN_VALIDATION_ERROR("Color attachments number exceeds maximum");
}
if (descriptor->numColorAttachments == 0 && !descriptor->hasDepthStencilAttachment) {
return DAWN_VALIDATION_ERROR("Should have at least one attachment");
}
if (descriptor->hasDepthStencilAttachment) {
dawn::TextureFormat format = descriptor->depthStencilAttachment->format;
DAWN_TRY(ValidateTextureFormat(format));
if (!IsDepthStencilRenderableTextureFormat(format)) {
return DAWN_VALIDATION_ERROR(
"Depth stencil format must be depth-stencil renderable");
}
}
for (uint32_t i = 0; i < descriptor->numColorAttachments; ++i) {
dawn::TextureFormat format = descriptor->colorAttachments[i].format;
DAWN_TRY(ValidateTextureFormat(format));
if (!IsColorRenderableTextureFormat(format)) {
return DAWN_VALIDATION_ERROR("Color format must be color renderable");
}
}
return {};
}
} // namespace
MaybeError ValidateRenderPipelineDescriptor(DeviceBase* device,
const RenderPipelineDescriptor* descriptor) {
if (descriptor->nextInChain != nullptr) {
return DAWN_VALIDATION_ERROR("nextInChain must be nullptr");
}
if (descriptor->layout == nullptr) {
return DAWN_VALIDATION_ERROR("Layout must not be null");
}
if (descriptor->inputState == nullptr) {
return DAWN_VALIDATION_ERROR("Input state must not be null");
}
if (descriptor->depthStencilState == nullptr) {
return DAWN_VALIDATION_ERROR("Depth stencil state must not be null");
}
for (uint32_t i = 0; i < descriptor->numBlendStates; ++i) {
if (descriptor->blendStates[i] == nullptr) {
return DAWN_VALIDATION_ERROR("Blend state must not be null");
}
}
DAWN_TRY(ValidateIndexFormat(descriptor->indexFormat));
DAWN_TRY(ValidatePrimitiveTopology(descriptor->primitiveTopology));
DAWN_TRY(ValidatePipelineStageDescriptor(descriptor->vertexStage, descriptor->layout,
dawn::ShaderStage::Vertex));
DAWN_TRY(ValidatePipelineStageDescriptor(descriptor->fragmentStage, descriptor->layout,
dawn::ShaderStage::Fragment));
DAWN_TRY(ValidateAttachmentsStateDescriptor(descriptor->attachmentsState));
if ((descriptor->vertexStage->module->GetUsedVertexAttributes() &
~descriptor->inputState->GetAttributesSetMask())
.any()) {
return DAWN_VALIDATION_ERROR(
"Pipeline vertex stage uses inputs not in the input state");
}
if (descriptor->sampleCount != 1) {
return DAWN_VALIDATION_ERROR("Sample count must be one");
}
if (descriptor->numBlendStates > kMaxColorAttachments) {
return DAWN_VALIDATION_ERROR("Blend states number exceeds maximum");
}
if (descriptor->attachmentsState->numColorAttachments != descriptor->numBlendStates) {
return DAWN_VALIDATION_ERROR("Each color attachment should have blend state");
}
// TODO: validate depth stencil state
return {};
}
// RenderPipelineBase // RenderPipelineBase
RenderPipelineBase::RenderPipelineBase(RenderPipelineBuilder* builder) RenderPipelineBase::RenderPipelineBase(DeviceBase* device,
: PipelineBase(builder->GetDevice(), builder), const RenderPipelineDescriptor* descriptor)
mDepthStencilState(std::move(builder->mDepthStencilState)), : PipelineBase(device,
mIndexFormat(builder->mIndexFormat), descriptor->layout,
mInputState(std::move(builder->mInputState)), dawn::ShaderStageBit::Vertex | dawn::ShaderStageBit::Fragment),
mPrimitiveTopology(builder->mPrimitiveTopology), mDepthStencilState(descriptor->depthStencilState),
mBlendStates(builder->mBlendStates), mIndexFormat(descriptor->indexFormat),
mColorAttachmentsSet(builder->mColorAttachmentsSet), mInputState(descriptor->inputState),
mColorAttachmentFormats(builder->mColorAttachmentFormats), mPrimitiveTopology(descriptor->primitiveTopology),
mDepthStencilFormatSet(builder->mDepthStencilFormatSet), mHasDepthStencilAttachment(descriptor->attachmentsState->hasDepthStencilAttachment) {
mDepthStencilFormat(builder->mDepthStencilFormat) { if (mHasDepthStencilAttachment) {
if (GetStageMask() != (dawn::ShaderStageBit::Vertex | dawn::ShaderStageBit::Fragment)) { mDepthStencilFormat = descriptor->attachmentsState->depthStencilAttachment->format;
builder->HandleError("Render pipeline should have exactly a vertex and fragment stage");
return;
} }
ExtractModuleData(dawn::ShaderStage::Vertex, descriptor->vertexStage->module);
ExtractModuleData(dawn::ShaderStage::Fragment, descriptor->fragmentStage->module);
// TODO(kainino@chromium.org): Need to verify the pipeline against its render subpass. for (uint32_t i = 0; i < descriptor->attachmentsState->numColorAttachments; ++i) {
mColorAttachmentsSet.set(i);
if ((builder->GetStageInfo(dawn::ShaderStage::Vertex).module->GetUsedVertexAttributes() & mBlendStates[i] = descriptor->blendStates[i];
~mInputState->GetAttributesSetMask()) mColorAttachmentFormats[i] = descriptor->attachmentsState->colorAttachments[i].format;
.any()) {
builder->HandleError("Pipeline vertex stage uses inputs not in the input state");
return;
} }
// TODO(cwallez@chromium.org): Check against the shader module that the correct color // TODO(cwallez@chromium.org): Check against the shader module that the correct color
// attachment are set? // attachment are set?
size_t attachmentCount = mColorAttachmentsSet.count();
if (mDepthStencilFormatSet) {
attachmentCount++;
}
if (attachmentCount == 0) {
builder->HandleError("Should have at least one attachment");
return;
}
} }
BlendStateBase* RenderPipelineBase::GetBlendState(uint32_t attachmentSlot) { BlendStateBase* RenderPipelineBase::GetBlendState(uint32_t attachmentSlot) {
@ -91,7 +184,7 @@ namespace dawn_native {
} }
bool RenderPipelineBase::HasDepthStencilAttachment() const { bool RenderPipelineBase::HasDepthStencilAttachment() const {
return mDepthStencilFormatSet; return mHasDepthStencilAttachment;
} }
dawn::TextureFormat RenderPipelineBase::GetColorAttachmentFormat(uint32_t attachment) const { dawn::TextureFormat RenderPipelineBase::GetColorAttachmentFormat(uint32_t attachment) const {
@ -99,6 +192,7 @@ namespace dawn_native {
} }
dawn::TextureFormat RenderPipelineBase::GetDepthStencilFormat() const { dawn::TextureFormat RenderPipelineBase::GetDepthStencilFormat() const {
ASSERT(mHasDepthStencilAttachment);
return mDepthStencilFormat; return mDepthStencilFormat;
} }
@ -118,11 +212,11 @@ namespace dawn_native {
} }
} }
if (renderPass->HasDepthStencilAttachment() != mDepthStencilFormatSet) { if (renderPass->HasDepthStencilAttachment() != mHasDepthStencilAttachment) {
return false; return false;
} }
if (mDepthStencilFormatSet && if (mHasDepthStencilAttachment &&
(renderPass->GetDepthStencilAttachment().view->GetTexture()->GetFormat() != (renderPass->GetDepthStencilAttachment().view->GetTexture()->GetFormat() !=
mDepthStencilFormat)) { mDepthStencilFormat)) {
return false; return false;
@ -131,106 +225,4 @@ namespace dawn_native {
return true; return true;
} }
// RenderPipelineBuilder
RenderPipelineBuilder::RenderPipelineBuilder(DeviceBase* device)
: Builder(device), PipelineBuilder(this) {
}
RenderPipelineBase* RenderPipelineBuilder::GetResultImpl() {
DeviceBase* device = GetDevice();
// TODO(cwallez@chromium.org): the layout should be required, and put the default objects in
// the device
if (!mInputState) {
auto builder = device->CreateInputStateBuilder();
mInputState = builder->GetResult();
// Remove the external ref objects are created with
mInputState->Release();
builder->Release();
}
if (!mDepthStencilState) {
auto builder = device->CreateDepthStencilStateBuilder();
mDepthStencilState = builder->GetResult();
// Remove the external ref objects are created with
mDepthStencilState->Release();
builder->Release();
}
if ((mBlendStatesSet | mColorAttachmentsSet) != mColorAttachmentsSet) {
HandleError("Blend state set on unset color attachment");
return nullptr;
}
// Assign all color attachments without a blend state the default state
// TODO(enga@google.com): Put the default objects in the device
for (uint32_t attachmentSlot : IterateBitSet(mColorAttachmentsSet & ~mBlendStatesSet)) {
mBlendStates[attachmentSlot] = device->CreateBlendStateBuilder()->GetResult();
// Remove the external ref objects are created with
mBlendStates[attachmentSlot]->Release();
}
return device->CreateRenderPipeline(this);
}
void RenderPipelineBuilder::SetColorAttachmentFormat(uint32_t attachmentSlot,
dawn::TextureFormat format) {
if (attachmentSlot >= kMaxColorAttachments) {
HandleError("Attachment index out of bounds");
return;
}
mColorAttachmentsSet.set(attachmentSlot);
mColorAttachmentFormats[attachmentSlot] = format;
}
void RenderPipelineBuilder::SetColorAttachmentBlendState(uint32_t attachmentSlot,
BlendStateBase* blendState) {
if (attachmentSlot >= kMaxColorAttachments) {
HandleError("Attachment index out of bounds");
return;
}
if (blendState == nullptr) {
HandleError("Blend state must not be null");
return;
}
if (mBlendStatesSet[attachmentSlot]) {
HandleError("Attachment blend state already set");
return;
}
mBlendStatesSet.set(attachmentSlot);
mBlendStates[attachmentSlot] = blendState;
}
void RenderPipelineBuilder::SetDepthStencilState(DepthStencilStateBase* depthStencilState) {
if (depthStencilState == nullptr) {
HandleError("Depth stencil state must not be null");
return;
}
mDepthStencilState = depthStencilState;
}
void RenderPipelineBuilder::SetDepthStencilAttachmentFormat(dawn::TextureFormat format) {
mDepthStencilFormatSet = true;
mDepthStencilFormat = format;
}
void RenderPipelineBuilder::SetIndexFormat(dawn::IndexFormat format) {
mIndexFormat = format;
}
void RenderPipelineBuilder::SetInputState(InputStateBase* inputState) {
if (inputState == nullptr) {
HandleError("Input state must not be null");
return;
}
mInputState = inputState;
}
void RenderPipelineBuilder::SetPrimitiveTopology(dawn::PrimitiveTopology primitiveTopology) {
mPrimitiveTopology = primitiveTopology;
}
} // namespace dawn_native } // namespace dawn_native

View File

@ -27,9 +27,14 @@
namespace dawn_native { namespace dawn_native {
class DeviceBase;
MaybeError ValidateRenderPipelineDescriptor(DeviceBase* device,
const RenderPipelineDescriptor* descriptor);
class RenderPipelineBase : public PipelineBase { class RenderPipelineBase : public PipelineBase {
public: public:
RenderPipelineBase(RenderPipelineBuilder* builder); RenderPipelineBase(DeviceBase* device, const RenderPipelineDescriptor* descriptor);
BlendStateBase* GetBlendState(uint32_t attachmentSlot); BlendStateBase* GetBlendState(uint32_t attachmentSlot);
DepthStencilStateBase* GetDepthStencilState(); DepthStencilStateBase* GetDepthStencilState();
@ -55,39 +60,7 @@ namespace dawn_native {
std::bitset<kMaxColorAttachments> mColorAttachmentsSet; std::bitset<kMaxColorAttachments> mColorAttachmentsSet;
std::array<dawn::TextureFormat, kMaxColorAttachments> mColorAttachmentFormats; std::array<dawn::TextureFormat, kMaxColorAttachments> mColorAttachmentFormats;
bool mDepthStencilFormatSet = false; bool mHasDepthStencilAttachment = false;
dawn::TextureFormat mDepthStencilFormat;
};
class RenderPipelineBuilder : public Builder<RenderPipelineBase>, public PipelineBuilder {
public:
RenderPipelineBuilder(DeviceBase* device);
// Dawn API
void SetColorAttachmentFormat(uint32_t attachmentSlot, dawn::TextureFormat format);
void SetColorAttachmentBlendState(uint32_t attachmentSlot, BlendStateBase* blendState);
void SetDepthStencilAttachmentFormat(dawn::TextureFormat format);
void SetDepthStencilState(DepthStencilStateBase* depthStencilState);
void SetPrimitiveTopology(dawn::PrimitiveTopology primitiveTopology);
void SetIndexFormat(dawn::IndexFormat format);
void SetInputState(InputStateBase* inputState);
private:
friend class RenderPipelineBase;
RenderPipelineBase* GetResultImpl() override;
Ref<DepthStencilStateBase> mDepthStencilState;
Ref<InputStateBase> mInputState;
// TODO(enga@google.com): Remove default when we validate that all required properties are
// set
dawn::PrimitiveTopology mPrimitiveTopology = dawn::PrimitiveTopology::TriangleList;
dawn::IndexFormat mIndexFormat = dawn::IndexFormat::Uint32;
std::bitset<kMaxColorAttachments> mBlendStatesSet;
std::array<Ref<BlendStateBase>, kMaxColorAttachments> mBlendStates;
std::bitset<kMaxColorAttachments> mColorAttachmentsSet;
std::array<dawn::TextureFormat, kMaxColorAttachments> mColorAttachmentFormats;
bool mDepthStencilFormatSet = false;
dawn::TextureFormat mDepthStencilFormat; dawn::TextureFormat mDepthStencilFormat;
}; };

View File

@ -250,6 +250,26 @@ namespace dawn_native {
} }
} }
bool IsDepthStencilRenderableTextureFormat(dawn::TextureFormat format) {
switch (format) {
case dawn::TextureFormat::D32FloatS8Uint:
return true;
case dawn::TextureFormat::B8G8R8A8Unorm:
case dawn::TextureFormat::R8G8B8A8Uint:
case dawn::TextureFormat::R8G8B8A8Unorm:
case dawn::TextureFormat::R8G8Uint:
case dawn::TextureFormat::R8G8Unorm:
case dawn::TextureFormat::R8Uint:
case dawn::TextureFormat::R8Unorm:
return false;
default:
UNREACHABLE();
return false;
}
}
// TextureBase // TextureBase
TextureBase::TextureBase(DeviceBase* device, const TextureDescriptor* descriptor) TextureBase::TextureBase(DeviceBase* device, const TextureDescriptor* descriptor)

View File

@ -33,6 +33,7 @@ namespace dawn_native {
bool TextureFormatHasStencil(dawn::TextureFormat format); bool TextureFormatHasStencil(dawn::TextureFormat format);
bool TextureFormatHasDepthOrStencil(dawn::TextureFormat format); bool TextureFormatHasDepthOrStencil(dawn::TextureFormat format);
bool IsColorRenderableTextureFormat(dawn::TextureFormat format); bool IsColorRenderableTextureFormat(dawn::TextureFormat format);
bool IsDepthStencilRenderableTextureFormat(dawn::TextureFormat format);
static constexpr dawn::TextureUsageBit kReadOnlyTextureUsages = static constexpr dawn::TextureUsageBit kReadOnlyTextureUsages =
dawn::TextureUsageBit::TransferSrc | dawn::TextureUsageBit::Sampled | dawn::TextureUsageBit::TransferSrc | dawn::TextureUsageBit::Sampled |

View File

@ -324,8 +324,9 @@ namespace dawn_native { namespace d3d12 {
RenderPassDescriptorBuilder* builder) { RenderPassDescriptorBuilder* builder) {
return new RenderPassDescriptor(builder); return new RenderPassDescriptor(builder);
} }
RenderPipelineBase* Device::CreateRenderPipeline(RenderPipelineBuilder* builder) { ResultOrError<RenderPipelineBase*> Device::CreateRenderPipelineImpl(
return new RenderPipeline(builder); const RenderPipelineDescriptor* descriptor) {
return new RenderPipeline(this, descriptor);
} }
ResultOrError<SamplerBase*> Device::CreateSamplerImpl(const SamplerDescriptor* descriptor) { ResultOrError<SamplerBase*> Device::CreateSamplerImpl(const SamplerDescriptor* descriptor) {
return new Sampler(this, descriptor); return new Sampler(this, descriptor);

View File

@ -47,7 +47,6 @@ namespace dawn_native { namespace d3d12 {
InputStateBase* CreateInputState(InputStateBuilder* builder) override; InputStateBase* CreateInputState(InputStateBuilder* builder) override;
RenderPassDescriptorBase* CreateRenderPassDescriptor( RenderPassDescriptorBase* CreateRenderPassDescriptor(
RenderPassDescriptorBuilder* builder) override; RenderPassDescriptorBuilder* builder) override;
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override; SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
Serial GetCompletedCommandSerial() const final override; Serial GetCompletedCommandSerial() const final override;
@ -88,6 +87,8 @@ namespace dawn_native { namespace d3d12 {
ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl( ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl(
const PipelineLayoutDescriptor* descriptor) override; const PipelineLayoutDescriptor* descriptor) override;
ResultOrError<QueueBase*> CreateQueueImpl() override; ResultOrError<QueueBase*> CreateQueueImpl() override;
ResultOrError<RenderPipelineBase*> CreateRenderPipelineImpl(
const RenderPipelineDescriptor* descriptor) override;
ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override; ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override;
ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl( ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
const ShaderModuleDescriptor* descriptor) override; const ShaderModuleDescriptor* descriptor) override;

View File

@ -63,10 +63,9 @@ namespace dawn_native { namespace d3d12 {
} }
} // namespace } // namespace
RenderPipeline::RenderPipeline(RenderPipelineBuilder* builder) RenderPipeline::RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor)
: RenderPipelineBase(builder), : RenderPipelineBase(device, descriptor),
mD3d12PrimitiveTopology(D3D12PrimitiveTopology(GetPrimitiveTopology())), mD3d12PrimitiveTopology(D3D12PrimitiveTopology(GetPrimitiveTopology())) {
mDevice(ToBackend(builder->GetDevice())) {
uint32_t compileFlags = 0; uint32_t compileFlags = 0;
#if defined(_DEBUG) #if defined(_DEBUG)
// Enable better shader debugging with the graphics debugging tools. // Enable better shader debugging with the graphics debugging tools.
@ -75,36 +74,41 @@ namespace dawn_native { namespace d3d12 {
// SPRIV-cross does matrix multiplication expecting row major matrices // SPRIV-cross does matrix multiplication expecting row major matrices
compileFlags |= D3DCOMPILE_PACK_MATRIX_ROW_MAJOR; compileFlags |= D3DCOMPILE_PACK_MATRIX_ROW_MAJOR;
D3D12_GRAPHICS_PIPELINE_STATE_DESC descriptor = {}; D3D12_GRAPHICS_PIPELINE_STATE_DESC descriptorD3D12 = {};
PerStage<ComPtr<ID3DBlob>> compiledShader; PerStage<ComPtr<ID3DBlob>> compiledShader;
ComPtr<ID3DBlob> errors; ComPtr<ID3DBlob> errors;
for (auto stage : IterateStages(GetStageMask())) { dawn::ShaderStageBit renderStages =
const auto& module = ToBackend(builder->GetStageInfo(stage).module); dawn::ShaderStageBit::Vertex | dawn::ShaderStageBit::Fragment;
const auto& entryPoint = builder->GetStageInfo(stage).entryPoint; for (auto stage : IterateStages(renderStages)) {
const auto& hlslSource = module->GetHLSLSource(ToBackend(GetLayout())); const ShaderModule* module = nullptr;
const char* entryPoint = nullptr;
const char* compileTarget = nullptr; const char* compileTarget = nullptr;
D3D12_SHADER_BYTECODE* shader = nullptr; D3D12_SHADER_BYTECODE* shader = nullptr;
switch (stage) { switch (stage) {
case dawn::ShaderStage::Vertex: case dawn::ShaderStage::Vertex:
shader = &descriptor.VS; module = ToBackend(descriptor->vertexStage->module);
entryPoint = descriptor->vertexStage->entryPoint;
shader = &descriptorD3D12.VS;
compileTarget = "vs_5_1"; compileTarget = "vs_5_1";
break; break;
case dawn::ShaderStage::Fragment: case dawn::ShaderStage::Fragment:
shader = &descriptor.PS; module = ToBackend(descriptor->fragmentStage->module);
entryPoint = descriptor->fragmentStage->entryPoint;
shader = &descriptorD3D12.PS;
compileTarget = "ps_5_1"; compileTarget = "ps_5_1";
break; break;
case dawn::ShaderStage::Compute: default:
UNREACHABLE(); UNREACHABLE();
break; break;
} }
const PlatformFunctions* functions = ToBackend(builder->GetDevice())->GetFunctions(); const std::string hlslSource = module->GetHLSLSource(ToBackend(GetLayout()));
const PlatformFunctions* functions = device->GetFunctions();
if (FAILED(functions->d3dCompile(hlslSource.c_str(), hlslSource.length(), nullptr, if (FAILED(functions->d3dCompile(hlslSource.c_str(), hlslSource.length(), nullptr,
nullptr, nullptr, entryPoint.c_str(), compileTarget, nullptr, nullptr, entryPoint, compileTarget,
compileFlags, 0, &compiledShader[stage], &errors))) { compileFlags, 0, &compiledShader[stage], &errors))) {
printf("%s\n", reinterpret_cast<char*>(errors->GetBufferPointer())); printf("%s\n", reinterpret_cast<char*>(errors->GetBufferPointer()));
ASSERT(false); ASSERT(false);
@ -118,54 +122,55 @@ namespace dawn_native { namespace d3d12 {
PipelineLayout* layout = ToBackend(GetLayout()); PipelineLayout* layout = ToBackend(GetLayout());
descriptor.pRootSignature = layout->GetRootSignature().Get(); descriptorD3D12.pRootSignature = layout->GetRootSignature().Get();
// D3D12 logs warnings if any empty input state is used // D3D12 logs warnings if any empty input state is used
InputState* inputState = ToBackend(GetInputState()); InputState* inputState = ToBackend(GetInputState());
if (inputState->GetAttributesSetMask().any()) { if (inputState->GetAttributesSetMask().any()) {
descriptor.InputLayout = inputState->GetD3D12InputLayoutDescriptor(); descriptorD3D12.InputLayout = inputState->GetD3D12InputLayoutDescriptor();
} }
descriptor.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; descriptorD3D12.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
descriptor.RasterizerState.CullMode = D3D12_CULL_MODE_NONE; descriptorD3D12.RasterizerState.CullMode = D3D12_CULL_MODE_NONE;
descriptor.RasterizerState.FrontCounterClockwise = FALSE; descriptorD3D12.RasterizerState.FrontCounterClockwise = FALSE;
descriptor.RasterizerState.DepthBias = D3D12_DEFAULT_DEPTH_BIAS; descriptorD3D12.RasterizerState.DepthBias = D3D12_DEFAULT_DEPTH_BIAS;
descriptor.RasterizerState.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP; descriptorD3D12.RasterizerState.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP;
descriptor.RasterizerState.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; descriptorD3D12.RasterizerState.SlopeScaledDepthBias =
descriptor.RasterizerState.DepthClipEnable = TRUE; D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
descriptor.RasterizerState.MultisampleEnable = FALSE; descriptorD3D12.RasterizerState.DepthClipEnable = TRUE;
descriptor.RasterizerState.AntialiasedLineEnable = FALSE; descriptorD3D12.RasterizerState.MultisampleEnable = FALSE;
descriptor.RasterizerState.ForcedSampleCount = 0; descriptorD3D12.RasterizerState.AntialiasedLineEnable = FALSE;
descriptor.RasterizerState.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; descriptorD3D12.RasterizerState.ForcedSampleCount = 0;
descriptorD3D12.RasterizerState.ConservativeRaster =
D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
if (HasDepthStencilAttachment()) { if (HasDepthStencilAttachment()) {
descriptor.DSVFormat = D3D12TextureFormat(GetDepthStencilFormat()); descriptorD3D12.DSVFormat = D3D12TextureFormat(GetDepthStencilFormat());
} }
for (uint32_t i : IterateBitSet(GetColorAttachmentsMask())) { for (uint32_t i : IterateBitSet(GetColorAttachmentsMask())) {
descriptor.RTVFormats[i] = D3D12TextureFormat(GetColorAttachmentFormat(i)); descriptorD3D12.RTVFormats[i] = D3D12TextureFormat(GetColorAttachmentFormat(i));
descriptor.BlendState.RenderTarget[i] = descriptorD3D12.BlendState.RenderTarget[i] =
ToBackend(GetBlendState(i))->GetD3D12BlendDesc(); ToBackend(GetBlendState(i))->GetD3D12BlendDesc();
} }
descriptor.NumRenderTargets = static_cast<uint32_t>(GetColorAttachmentsMask().count()); descriptorD3D12.NumRenderTargets = static_cast<uint32_t>(GetColorAttachmentsMask().count());
descriptor.BlendState.AlphaToCoverageEnable = FALSE; descriptorD3D12.BlendState.AlphaToCoverageEnable = FALSE;
descriptor.BlendState.IndependentBlendEnable = TRUE; descriptorD3D12.BlendState.IndependentBlendEnable = TRUE;
DepthStencilState* depthStencilState = ToBackend(GetDepthStencilState()); DepthStencilState* depthStencilState = ToBackend(GetDepthStencilState());
descriptor.DepthStencilState = depthStencilState->GetD3D12DepthStencilDescriptor(); descriptorD3D12.DepthStencilState = depthStencilState->GetD3D12DepthStencilDescriptor();
descriptor.SampleMask = UINT_MAX; descriptorD3D12.SampleMask = UINT_MAX;
descriptor.PrimitiveTopologyType = D3D12PrimitiveTopologyType(GetPrimitiveTopology()); descriptorD3D12.PrimitiveTopologyType = D3D12PrimitiveTopologyType(GetPrimitiveTopology());
descriptor.SampleDesc.Count = 1; descriptorD3D12.SampleDesc.Count = 1;
Device* device = ToBackend(builder->GetDevice());
ASSERT_SUCCESS(device->GetD3D12Device()->CreateGraphicsPipelineState( ASSERT_SUCCESS(device->GetD3D12Device()->CreateGraphicsPipelineState(
&descriptor, IID_PPV_ARGS(&mPipelineState))); &descriptorD3D12, IID_PPV_ARGS(&mPipelineState)));
} }
RenderPipeline::~RenderPipeline() { RenderPipeline::~RenderPipeline() {
mDevice->ReferenceUntilUnused(mPipelineState); ToBackend(GetDevice())->ReferenceUntilUnused(mPipelineState);
} }
D3D12_PRIMITIVE_TOPOLOGY RenderPipeline::GetD3D12PrimitiveTopology() const { D3D12_PRIMITIVE_TOPOLOGY RenderPipeline::GetD3D12PrimitiveTopology() const {

View File

@ -25,7 +25,7 @@ namespace dawn_native { namespace d3d12 {
class RenderPipeline : public RenderPipelineBase { class RenderPipeline : public RenderPipelineBase {
public: public:
RenderPipeline(RenderPipelineBuilder* builder); RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor);
~RenderPipeline(); ~RenderPipeline();
D3D12_PRIMITIVE_TOPOLOGY GetD3D12PrimitiveTopology() const; D3D12_PRIMITIVE_TOPOLOGY GetD3D12PrimitiveTopology() const;
@ -34,8 +34,6 @@ namespace dawn_native { namespace d3d12 {
private: private:
D3D12_PRIMITIVE_TOPOLOGY mD3d12PrimitiveTopology; D3D12_PRIMITIVE_TOPOLOGY mD3d12PrimitiveTopology;
ComPtr<ID3D12PipelineState> mPipelineState; ComPtr<ID3D12PipelineState> mPipelineState;
Device* mDevice = nullptr;
}; };
}} // namespace dawn_native::d3d12 }} // namespace dawn_native::d3d12

View File

@ -43,7 +43,6 @@ namespace dawn_native { namespace metal {
InputStateBase* CreateInputState(InputStateBuilder* builder) override; InputStateBase* CreateInputState(InputStateBuilder* builder) override;
RenderPassDescriptorBase* CreateRenderPassDescriptor( RenderPassDescriptorBase* CreateRenderPassDescriptor(
RenderPassDescriptorBuilder* builder) override; RenderPassDescriptorBuilder* builder) override;
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override; SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
Serial GetCompletedCommandSerial() const final override; Serial GetCompletedCommandSerial() const final override;
@ -72,6 +71,8 @@ namespace dawn_native { namespace metal {
ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl( ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl(
const PipelineLayoutDescriptor* descriptor) override; const PipelineLayoutDescriptor* descriptor) override;
ResultOrError<QueueBase*> CreateQueueImpl() override; ResultOrError<QueueBase*> CreateQueueImpl() override;
ResultOrError<RenderPipelineBase*> CreateRenderPipelineImpl(
const RenderPipelineDescriptor* descriptor) override;
ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override; ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override;
ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl( ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
const ShaderModuleDescriptor* descriptor) override; const ShaderModuleDescriptor* descriptor) override;

View File

@ -197,12 +197,13 @@ namespace dawn_native { namespace metal {
RenderPassDescriptorBuilder* builder) { RenderPassDescriptorBuilder* builder) {
return new RenderPassDescriptor(builder); return new RenderPassDescriptor(builder);
} }
RenderPipelineBase* Device::CreateRenderPipeline(RenderPipelineBuilder* builder) {
return new RenderPipeline(builder);
}
ResultOrError<QueueBase*> Device::CreateQueueImpl() { ResultOrError<QueueBase*> Device::CreateQueueImpl() {
return new Queue(this); return new Queue(this);
} }
ResultOrError<RenderPipelineBase*> Device::CreateRenderPipelineImpl(
const RenderPipelineDescriptor* descriptor) {
return new RenderPipeline(this, descriptor);
}
ResultOrError<SamplerBase*> Device::CreateSamplerImpl(const SamplerDescriptor* descriptor) { ResultOrError<SamplerBase*> Device::CreateSamplerImpl(const SamplerDescriptor* descriptor) {
return new Sampler(this, descriptor); return new Sampler(this, descriptor);
} }

View File

@ -21,9 +21,11 @@
namespace dawn_native { namespace metal { namespace dawn_native { namespace metal {
class Device;
class RenderPipeline : public RenderPipelineBase { class RenderPipeline : public RenderPipelineBase {
public: public:
RenderPipeline(RenderPipelineBuilder* builder); RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor);
~RenderPipeline(); ~RenderPipeline();
MTLIndexType GetMTLIndexType() const; MTLIndexType GetMTLIndexType() const;

View File

@ -64,65 +64,57 @@ namespace dawn_native { namespace metal {
} }
} }
RenderPipeline::RenderPipeline(RenderPipelineBuilder* builder) RenderPipeline::RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor)
: RenderPipelineBase(builder), : RenderPipelineBase(device, descriptor),
mMtlIndexType(MTLIndexFormat(GetIndexFormat())), mMtlIndexType(MTLIndexFormat(GetIndexFormat())),
mMtlPrimitiveTopology(MTLPrimitiveTopology(GetPrimitiveTopology())) { mMtlPrimitiveTopology(MTLPrimitiveTopology(GetPrimitiveTopology())) {
auto mtlDevice = ToBackend(builder->GetDevice())->GetMTLDevice(); auto mtlDevice = device->GetMTLDevice();
MTLRenderPipelineDescriptor* descriptor = [MTLRenderPipelineDescriptor new]; MTLRenderPipelineDescriptor* descriptorMTL = [MTLRenderPipelineDescriptor new];
for (auto stage : IterateStages(GetStageMask())) { const ShaderModule* vertexModule = ToBackend(descriptor->vertexStage->module);
const auto& module = ToBackend(builder->GetStageInfo(stage).module); const char* vertexEntryPoint = descriptor->vertexStage->entryPoint;
ShaderModule::MetalFunctionData vertexData = vertexModule->GetFunction(
vertexEntryPoint, dawn::ShaderStage::Vertex, ToBackend(GetLayout()));
descriptorMTL.vertexFunction = vertexData.function;
const auto& entryPoint = builder->GetStageInfo(stage).entryPoint; const ShaderModule* fragmentModule = ToBackend(descriptor->fragmentStage->module);
ShaderModule::MetalFunctionData data = const char* fragmentEntryPoint = descriptor->fragmentStage->entryPoint;
module->GetFunction(entryPoint.c_str(), stage, ToBackend(GetLayout())); ShaderModule::MetalFunctionData fragmentData = fragmentModule->GetFunction(
id<MTLFunction> function = data.function; fragmentEntryPoint, dawn::ShaderStage::Fragment, ToBackend(GetLayout()));
descriptorMTL.fragmentFunction = fragmentData.function;
switch (stage) {
case dawn::ShaderStage::Vertex:
descriptor.vertexFunction = function;
break;
case dawn::ShaderStage::Fragment:
descriptor.fragmentFunction = function;
break;
case dawn::ShaderStage::Compute:
UNREACHABLE();
}
}
if (HasDepthStencilAttachment()) { if (HasDepthStencilAttachment()) {
// TODO(kainino@chromium.org): Handle depth-only and stencil-only formats. // TODO(kainino@chromium.org): Handle depth-only and stencil-only formats.
dawn::TextureFormat depthStencilFormat = GetDepthStencilFormat(); dawn::TextureFormat depthStencilFormat = GetDepthStencilFormat();
descriptor.depthAttachmentPixelFormat = MetalPixelFormat(depthStencilFormat); descriptorMTL.depthAttachmentPixelFormat = MetalPixelFormat(depthStencilFormat);
descriptor.stencilAttachmentPixelFormat = MetalPixelFormat(depthStencilFormat); descriptorMTL.stencilAttachmentPixelFormat = MetalPixelFormat(depthStencilFormat);
} }
for (uint32_t i : IterateBitSet(GetColorAttachmentsMask())) { for (uint32_t i : IterateBitSet(GetColorAttachmentsMask())) {
descriptor.colorAttachments[i].pixelFormat = descriptorMTL.colorAttachments[i].pixelFormat =
MetalPixelFormat(GetColorAttachmentFormat(i)); MetalPixelFormat(GetColorAttachmentFormat(i));
ToBackend(GetBlendState(i))->ApplyBlendState(descriptor.colorAttachments[i]); ToBackend(GetBlendState(i))->ApplyBlendState(descriptorMTL.colorAttachments[i]);
} }
descriptor.inputPrimitiveTopology = MTLInputPrimitiveTopology(GetPrimitiveTopology()); descriptorMTL.inputPrimitiveTopology = MTLInputPrimitiveTopology(GetPrimitiveTopology());
InputState* inputState = ToBackend(GetInputState()); InputState* inputState = ToBackend(GetInputState());
descriptor.vertexDescriptor = inputState->GetMTLVertexDescriptor(); descriptorMTL.vertexDescriptor = inputState->GetMTLVertexDescriptor();
// TODO(kainino@chromium.org): push constants, textures, samplers // TODO(kainino@chromium.org): push constants, textures, samplers
NSError* error = nil; NSError* error = nil;
mMtlRenderPipelineState = [mtlDevice newRenderPipelineStateWithDescriptor:descriptor mMtlRenderPipelineState = [mtlDevice newRenderPipelineStateWithDescriptor:descriptorMTL
error:&error]; error:&error];
if (error != nil) { if (error != nil) {
NSLog(@" error => %@", error); NSLog(@" error => %@", error);
builder->HandleError("Error creating pipeline state"); device->HandleError("Error creating rendering pipeline state");
[descriptor release]; [descriptorMTL release];
return; return;
} }
[descriptor release]; [descriptorMTL release];
} }
RenderPipeline::~RenderPipeline() { RenderPipeline::~RenderPipeline() {

View File

@ -72,8 +72,9 @@ namespace dawn_native { namespace null {
RenderPassDescriptorBuilder* builder) { RenderPassDescriptorBuilder* builder) {
return new RenderPassDescriptor(builder); return new RenderPassDescriptor(builder);
} }
RenderPipelineBase* Device::CreateRenderPipeline(RenderPipelineBuilder* builder) { ResultOrError<RenderPipelineBase*> Device::CreateRenderPipelineImpl(
return new RenderPipeline(builder); const RenderPipelineDescriptor* descriptor) {
return new RenderPipeline(this, descriptor);
} }
ResultOrError<SamplerBase*> Device::CreateSamplerImpl(const SamplerDescriptor* descriptor) { ResultOrError<SamplerBase*> Device::CreateSamplerImpl(const SamplerDescriptor* descriptor) {
return new Sampler(this, descriptor); return new Sampler(this, descriptor);

View File

@ -99,7 +99,6 @@ namespace dawn_native { namespace null {
InputStateBase* CreateInputState(InputStateBuilder* builder) override; InputStateBase* CreateInputState(InputStateBuilder* builder) override;
RenderPassDescriptorBase* CreateRenderPassDescriptor( RenderPassDescriptorBase* CreateRenderPassDescriptor(
RenderPassDescriptorBuilder* builder) override; RenderPassDescriptorBuilder* builder) override;
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override; SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
Serial GetCompletedCommandSerial() const final override; Serial GetCompletedCommandSerial() const final override;
@ -122,6 +121,8 @@ namespace dawn_native { namespace null {
ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl( ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl(
const PipelineLayoutDescriptor* descriptor) override; const PipelineLayoutDescriptor* descriptor) override;
ResultOrError<QueueBase*> CreateQueueImpl() override; ResultOrError<QueueBase*> CreateQueueImpl() override;
ResultOrError<RenderPipelineBase*> CreateRenderPipelineImpl(
const RenderPipelineDescriptor* descriptor) override;
ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override; ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override;
ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl( ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
const ShaderModuleDescriptor* descriptor) override; const ShaderModuleDescriptor* descriptor) override;

View File

@ -99,8 +99,9 @@ namespace dawn_native { namespace opengl {
RenderPassDescriptorBuilder* builder) { RenderPassDescriptorBuilder* builder) {
return new RenderPassDescriptor(builder); return new RenderPassDescriptor(builder);
} }
RenderPipelineBase* Device::CreateRenderPipeline(RenderPipelineBuilder* builder) { ResultOrError<RenderPipelineBase*> Device::CreateRenderPipelineImpl(
return new RenderPipeline(builder); const RenderPipelineDescriptor* descriptor) {
return new RenderPipeline(this, descriptor);
} }
ResultOrError<SamplerBase*> Device::CreateSamplerImpl(const SamplerDescriptor* descriptor) { ResultOrError<SamplerBase*> Device::CreateSamplerImpl(const SamplerDescriptor* descriptor) {
return new Sampler(this, descriptor); return new Sampler(this, descriptor);

View File

@ -46,7 +46,6 @@ namespace dawn_native { namespace opengl {
InputStateBase* CreateInputState(InputStateBuilder* builder) override; InputStateBase* CreateInputState(InputStateBuilder* builder) override;
RenderPassDescriptorBase* CreateRenderPassDescriptor( RenderPassDescriptorBase* CreateRenderPassDescriptor(
RenderPassDescriptorBuilder* builder) override; RenderPassDescriptorBuilder* builder) override;
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override; SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
Serial GetCompletedCommandSerial() const final override; Serial GetCompletedCommandSerial() const final override;
@ -66,6 +65,8 @@ namespace dawn_native { namespace opengl {
ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl( ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl(
const PipelineLayoutDescriptor* descriptor) override; const PipelineLayoutDescriptor* descriptor) override;
ResultOrError<QueueBase*> CreateQueueImpl() override; ResultOrError<QueueBase*> CreateQueueImpl() override;
ResultOrError<RenderPipelineBase*> CreateRenderPipelineImpl(
const RenderPipelineDescriptor* descriptor) override;
ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override; ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override;
ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl( ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
const ShaderModuleDescriptor* descriptor) override; const ShaderModuleDescriptor* descriptor) override;

View File

@ -16,6 +16,7 @@
#include "dawn_native/opengl/BlendStateGL.h" #include "dawn_native/opengl/BlendStateGL.h"
#include "dawn_native/opengl/DepthStencilStateGL.h" #include "dawn_native/opengl/DepthStencilStateGL.h"
#include "dawn_native/opengl/DeviceGL.h"
#include "dawn_native/opengl/Forward.h" #include "dawn_native/opengl/Forward.h"
#include "dawn_native/opengl/InputStateGL.h" #include "dawn_native/opengl/InputStateGL.h"
#include "dawn_native/opengl/PersistentPipelineStateGL.h" #include "dawn_native/opengl/PersistentPipelineStateGL.h"
@ -41,13 +42,12 @@ namespace dawn_native { namespace opengl {
} }
} // namespace } // namespace
RenderPipeline::RenderPipeline(RenderPipelineBuilder* builder) RenderPipeline::RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor)
: RenderPipelineBase(builder), : RenderPipelineBase(device, descriptor),
mGlPrimitiveTopology(GLPrimitiveTopology(GetPrimitiveTopology())) { mGlPrimitiveTopology(GLPrimitiveTopology(GetPrimitiveTopology())) {
PerStage<const ShaderModule*> modules(nullptr); PerStage<const ShaderModule*> modules(nullptr);
for (dawn::ShaderStage stage : IterateStages(GetStageMask())) { modules[dawn::ShaderStage::Vertex] = ToBackend(descriptor->vertexStage->module);
modules[stage] = ToBackend(builder->GetStageInfo(stage).module.Get()); modules[dawn::ShaderStage::Fragment] = ToBackend(descriptor->fragmentStage->module);
}
PipelineGL::Initialize(ToBackend(GetLayout()), modules); PipelineGL::Initialize(ToBackend(GetLayout()), modules);
} }

View File

@ -25,11 +25,12 @@
namespace dawn_native { namespace opengl { namespace dawn_native { namespace opengl {
class Device;
class PersistentPipelineState; class PersistentPipelineState;
class RenderPipeline : public RenderPipelineBase, public PipelineGL { class RenderPipeline : public RenderPipelineBase, public PipelineGL {
public: public:
RenderPipeline(RenderPipelineBuilder* builder); RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor);
GLenum GetGLPrimitiveTopology() const; GLenum GetGLPrimitiveTopology() const;

View File

@ -250,8 +250,9 @@ namespace dawn_native { namespace vulkan {
RenderPassDescriptorBuilder* builder) { RenderPassDescriptorBuilder* builder) {
return new RenderPassDescriptor(builder); return new RenderPassDescriptor(builder);
} }
RenderPipelineBase* Device::CreateRenderPipeline(RenderPipelineBuilder* builder) { ResultOrError<RenderPipelineBase*> Device::CreateRenderPipelineImpl(
return new RenderPipeline(builder); const RenderPipelineDescriptor* descriptor) {
return new RenderPipeline(this, descriptor);
} }
ResultOrError<SamplerBase*> Device::CreateSamplerImpl(const SamplerDescriptor* descriptor) { ResultOrError<SamplerBase*> Device::CreateSamplerImpl(const SamplerDescriptor* descriptor) {
return new Sampler(this, descriptor); return new Sampler(this, descriptor);

View File

@ -69,7 +69,6 @@ namespace dawn_native { namespace vulkan {
InputStateBase* CreateInputState(InputStateBuilder* builder) override; InputStateBase* CreateInputState(InputStateBuilder* builder) override;
RenderPassDescriptorBase* CreateRenderPassDescriptor( RenderPassDescriptorBase* CreateRenderPassDescriptor(
RenderPassDescriptorBuilder* builder) override; RenderPassDescriptorBuilder* builder) override;
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override; SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
Serial GetCompletedCommandSerial() const final override; Serial GetCompletedCommandSerial() const final override;
@ -89,6 +88,8 @@ namespace dawn_native { namespace vulkan {
ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl( ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl(
const PipelineLayoutDescriptor* descriptor) override; const PipelineLayoutDescriptor* descriptor) override;
ResultOrError<QueueBase*> CreateQueueImpl() override; ResultOrError<QueueBase*> CreateQueueImpl() override;
ResultOrError<RenderPipelineBase*> CreateRenderPipelineImpl(
const RenderPipelineDescriptor* descriptor) override;
ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override; ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override;
ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl( ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
const ShaderModuleDescriptor* descriptor) override; const ShaderModuleDescriptor* descriptor) override;

View File

@ -47,32 +47,29 @@ namespace dawn_native { namespace vulkan {
} // anonymous namespace } // anonymous namespace
RenderPipeline::RenderPipeline(RenderPipelineBuilder* builder) RenderPipeline::RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor)
: RenderPipelineBase(builder), mDevice(ToBackend(builder->GetDevice())) { : RenderPipelineBase(device, descriptor) {
// Eventually a bunch of the structures that need to be chained in the create info will be // Eventually a bunch of the structures that need to be chained in the create info will be
// held by objects such as the BlendState. They aren't implemented yet so we initialize // held by objects such as the BlendState. They aren't implemented yet so we initialize
// everything here. // everything here.
VkPipelineShaderStageCreateInfo shaderStages[2]; VkPipelineShaderStageCreateInfo shaderStages[2];
{ {
const auto& vertexStageInfo = builder->GetStageInfo(dawn::ShaderStage::Vertex);
const auto& fragmentStageInfo = builder->GetStageInfo(dawn::ShaderStage::Fragment);
shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
shaderStages[0].pNext = nullptr; shaderStages[0].pNext = nullptr;
shaderStages[0].flags = 0; shaderStages[0].flags = 0;
shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT; shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
shaderStages[0].module = ToBackend(vertexStageInfo.module)->GetHandle();
shaderStages[0].pName = vertexStageInfo.entryPoint.c_str();
shaderStages[0].pSpecializationInfo = nullptr; shaderStages[0].pSpecializationInfo = nullptr;
shaderStages[0].module = ToBackend(descriptor->vertexStage->module)->GetHandle();
shaderStages[0].pName = descriptor->vertexStage->entryPoint;
shaderStages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; shaderStages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
shaderStages[1].pNext = nullptr; shaderStages[1].pNext = nullptr;
shaderStages[1].flags = 0; shaderStages[1].flags = 0;
shaderStages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; shaderStages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
shaderStages[1].module = ToBackend(fragmentStageInfo.module)->GetHandle();
shaderStages[1].pName = fragmentStageInfo.entryPoint.c_str();
shaderStages[1].pSpecializationInfo = nullptr; shaderStages[1].pSpecializationInfo = nullptr;
shaderStages[1].module = ToBackend(descriptor->fragmentStage->module)->GetHandle();
shaderStages[1].pName = descriptor->fragmentStage->entryPoint;
} }
VkPipelineInputAssemblyStateCreateInfo inputAssembly; VkPipelineInputAssemblyStateCreateInfo inputAssembly;
@ -183,7 +180,7 @@ namespace dawn_native { namespace vulkan {
dawn::LoadOp::Load); dawn::LoadOp::Load);
} }
renderPass = mDevice->GetRenderPassCache()->GetRenderPass(query); renderPass = device->GetRenderPassCache()->GetRenderPass(query);
} }
// The create info chains in a bunch of things created on the stack here or inside state // The create info chains in a bunch of things created on the stack here or inside state
@ -209,15 +206,15 @@ namespace dawn_native { namespace vulkan {
createInfo.basePipelineHandle = VK_NULL_HANDLE; createInfo.basePipelineHandle = VK_NULL_HANDLE;
createInfo.basePipelineIndex = -1; createInfo.basePipelineIndex = -1;
if (mDevice->fn.CreateGraphicsPipelines(mDevice->GetVkDevice(), VK_NULL_HANDLE, 1, if (device->fn.CreateGraphicsPipelines(device->GetVkDevice(), VK_NULL_HANDLE, 1,
&createInfo, nullptr, &mHandle) != VK_SUCCESS) { &createInfo, nullptr, &mHandle) != VK_SUCCESS) {
ASSERT(false); ASSERT(false);
} }
} }
RenderPipeline::~RenderPipeline() { RenderPipeline::~RenderPipeline() {
if (mHandle != VK_NULL_HANDLE) { if (mHandle != VK_NULL_HANDLE) {
mDevice->GetFencedDeleter()->DeleteWhenUnused(mHandle); ToBackend(GetDevice())->GetFencedDeleter()->DeleteWhenUnused(mHandle);
mHandle = VK_NULL_HANDLE; mHandle = VK_NULL_HANDLE;
} }
} }

View File

@ -25,14 +25,13 @@ namespace dawn_native { namespace vulkan {
class RenderPipeline : public RenderPipelineBase { class RenderPipeline : public RenderPipelineBase {
public: public:
RenderPipeline(RenderPipelineBuilder* builder); RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor);
~RenderPipeline(); ~RenderPipeline();
VkPipeline GetHandle() const; VkPipeline GetHandle() const;
private: private:
VkPipeline mHandle = VK_NULL_HANDLE; VkPipeline mHandle = VK_NULL_HANDLE;
Device* mDevice = nullptr;
}; };
}} // namespace dawn_native::vulkan }} // namespace dawn_native::vulkan

View File

@ -15,6 +15,7 @@
#include "common/Assert.h" #include "common/Assert.h"
#include "common/Constants.h" #include "common/Constants.h"
#include "tests/DawnTest.h" #include "tests/DawnTest.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h" #include "utils/DawnHelpers.h"
constexpr static unsigned int kRTSize = 8; constexpr static unsigned int kRTSize = 8;
@ -114,13 +115,15 @@ TEST_P(BindGroupTests, ReusedUBO) {
); );
dawn::PipelineLayout pipelineLayout = utils::MakeBasicPipelineLayout(device, &bgl); dawn::PipelineLayout pipelineLayout = utils::MakeBasicPipelineLayout(device, &bgl);
dawn::RenderPipeline pipeline = device.CreateRenderPipelineBuilder() utils::ComboRenderPipelineDescriptor textureDescriptor(device);
.SetColorAttachmentFormat(0, renderPass.colorFormat) textureDescriptor.layout = pipelineLayout;
.SetLayout(pipelineLayout) textureDescriptor.cVertexStage.module = vsModule;
.SetPrimitiveTopology(dawn::PrimitiveTopology::TriangleList) textureDescriptor.cFragmentStage.module = fsModule;
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main") textureDescriptor.cColorAttachments[0].format =
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main") renderPass.colorFormat;
.GetResult();
dawn::RenderPipeline pipeline = device.CreateRenderPipeline(&textureDescriptor);
struct Data { struct Data {
float transform[8]; float transform[8];
char padding[256 - 8 * sizeof(float)]; char padding[256 - 8 * sizeof(float)];
@ -198,13 +201,15 @@ TEST_P(BindGroupTests, UBOSamplerAndTexture) {
); );
dawn::PipelineLayout pipelineLayout = utils::MakeBasicPipelineLayout(device, &bgl); dawn::PipelineLayout pipelineLayout = utils::MakeBasicPipelineLayout(device, &bgl);
dawn::RenderPipeline pipeline = device.CreateRenderPipelineBuilder() utils::ComboRenderPipelineDescriptor pipelineDescriptor(device);
.SetColorAttachmentFormat(0, renderPass.colorFormat) pipelineDescriptor.layout = pipelineLayout;
.SetLayout(pipelineLayout) pipelineDescriptor.cVertexStage.module = vsModule;
.SetPrimitiveTopology(dawn::PrimitiveTopology::TriangleList) pipelineDescriptor.cFragmentStage.module = fsModule;
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main") pipelineDescriptor.cColorAttachments[0].format =
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main") renderPass.colorFormat;
.GetResult();
dawn::RenderPipeline pipeline = device.CreateRenderPipeline(&pipelineDescriptor);
constexpr float dummy = 0.0f; constexpr float dummy = 0.0f;
constexpr float transform[] = { 1.f, 0.f, dummy, dummy, 0.f, 1.f, dummy, dummy }; constexpr float transform[] = { 1.f, 0.f, dummy, dummy, 0.f, 1.f, dummy, dummy };
dawn::Buffer buffer = utils::CreateBufferFromData(device, &transform, sizeof(transform), dawn::BufferUsageBit::Uniform); dawn::Buffer buffer = utils::CreateBufferFromData(device, &transform, sizeof(transform), dawn::BufferUsageBit::Uniform);

View File

@ -19,6 +19,7 @@
#include "common/Assert.h" #include "common/Assert.h"
#include "common/Constants.h" #include "common/Constants.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h" #include "utils/DawnHelpers.h"
constexpr static unsigned int kRTSize = 64; constexpr static unsigned int kRTSize = 64;
@ -66,20 +67,24 @@ class BlendStateTest : public DawnTest {
} }
)"); )");
basePipeline = device.CreateRenderPipelineBuilder() utils::ComboRenderPipelineDescriptor baseDescriptor(device);
.SetColorAttachmentFormat(0, renderPass.colorFormat) baseDescriptor.layout = pipelineLayout;
.SetLayout(pipelineLayout) baseDescriptor.cVertexStage.module = vsModule;
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main") baseDescriptor.cFragmentStage.module = fsModule;
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main") baseDescriptor.cColorAttachments[0].format =
.GetResult(); renderPass.colorFormat;
testPipeline = device.CreateRenderPipelineBuilder() basePipeline = device.CreateRenderPipeline(&baseDescriptor);
.SetColorAttachmentFormat(0, renderPass.colorFormat)
.SetLayout(pipelineLayout) utils::ComboRenderPipelineDescriptor testDescriptor(device);
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main") testDescriptor.layout = pipelineLayout;
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main") testDescriptor.cVertexStage.module = vsModule;
.SetColorAttachmentBlendState(0, blendState) testDescriptor.cFragmentStage.module = fsModule;
.GetResult(); testDescriptor.cColorAttachments[0].format =
renderPass.colorFormat;
testDescriptor.cBlendStates[0] = blendState;
testPipeline = device.CreateRenderPipeline(&testDescriptor);
} }
// Create a bind group to set the colors as a uniform buffer // Create a bind group to set the colors as a uniform buffer
@ -766,7 +771,7 @@ TEST_P(BlendStateTest, IndependentBlendState) {
blend3.srcFactor = dawn::BlendFactor::One; blend3.srcFactor = dawn::BlendFactor::One;
blend3.dstFactor = dawn::BlendFactor::One; blend3.dstFactor = dawn::BlendFactor::One;
std::array<dawn::BlendState, 3> blendStates = { { std::array<dawn::BlendState, 4> blendStates = { {
device.CreateBlendStateBuilder() device.CreateBlendStateBuilder()
.SetBlendEnabled(true) .SetBlendEnabled(true)
.SetColorBlend(&blend1) .SetColorBlend(&blend1)
@ -777,6 +782,7 @@ TEST_P(BlendStateTest, IndependentBlendState) {
.SetColorBlend(&blend2) .SetColorBlend(&blend2)
.SetAlphaBlend(&blend2) .SetAlphaBlend(&blend2)
.GetResult(), .GetResult(),
device.CreateBlendStateBuilder().GetResult(),
device.CreateBlendStateBuilder() device.CreateBlendStateBuilder()
.SetBlendEnabled(true) .SetBlendEnabled(true)
.SetColorBlend(&blend3) .SetColorBlend(&blend3)
@ -784,30 +790,24 @@ TEST_P(BlendStateTest, IndependentBlendState) {
.GetResult(), .GetResult(),
} }; } };
basePipeline = device.CreateRenderPipelineBuilder() utils::ComboRenderPipelineDescriptor baseDescriptor(device);
.SetColorAttachmentFormat(0, dawn::TextureFormat::R8G8B8A8Unorm) baseDescriptor.layout = pipelineLayout;
.SetColorAttachmentFormat(1, dawn::TextureFormat::R8G8B8A8Unorm) baseDescriptor.cVertexStage.module = vsModule;
.SetColorAttachmentFormat(2, dawn::TextureFormat::R8G8B8A8Unorm) baseDescriptor.cFragmentStage.module = fsModule;
.SetColorAttachmentFormat(3, dawn::TextureFormat::R8G8B8A8Unorm) baseDescriptor.cAttachmentsState.numColorAttachments = 4;
.SetLayout(pipelineLayout) baseDescriptor.numBlendStates = 4;
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
.GetResult();
testPipeline = device.CreateRenderPipelineBuilder() basePipeline = device.CreateRenderPipeline(&baseDescriptor);
.SetColorAttachmentFormat(0, dawn::TextureFormat::R8G8B8A8Unorm)
.SetColorAttachmentFormat(1, dawn::TextureFormat::R8G8B8A8Unorm)
.SetColorAttachmentFormat(2, dawn::TextureFormat::R8G8B8A8Unorm)
.SetColorAttachmentFormat(3, dawn::TextureFormat::R8G8B8A8Unorm)
.SetLayout(pipelineLayout)
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
.SetColorAttachmentBlendState(0, blendStates[0])
.SetColorAttachmentBlendState(1, blendStates[1])
// Blend state not set on third color attachment. It should be default
.SetColorAttachmentBlendState(3, blendStates[2])
.GetResult();
utils::ComboRenderPipelineDescriptor testDescriptor(device);
testDescriptor.layout = pipelineLayout;
testDescriptor.cVertexStage.module = vsModule;
testDescriptor.cFragmentStage.module = fsModule;
testDescriptor.cAttachmentsState.numColorAttachments = 4;
testDescriptor.numBlendStates = 4;
testDescriptor.blendStates = blendStates.data();
testPipeline = device.CreateRenderPipeline(&testDescriptor);
for (unsigned int c = 0; c < kColors.size(); ++c) { for (unsigned int c = 0; c < kColors.size(); ++c) {
RGBA8 base = kColors[((c + 31) * 29) % kColors.size()]; RGBA8 base = kColors[((c + 31) * 29) % kColors.size()];
@ -870,20 +870,24 @@ TEST_P(BlendStateTest, DefaultBlendColor) {
} }
)"); )");
basePipeline = device.CreateRenderPipelineBuilder() utils::ComboRenderPipelineDescriptor baseDescriptor(device);
.SetColorAttachmentFormat(0, renderPass.colorFormat) baseDescriptor.layout = pipelineLayout;
.SetLayout(pipelineLayout) baseDescriptor.cVertexStage.module = vsModule;
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main") baseDescriptor.cFragmentStage.module = fsModule;
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main") baseDescriptor.cColorAttachments[0].format =
.GetResult(); renderPass.colorFormat;
testPipeline = device.CreateRenderPipelineBuilder() basePipeline = device.CreateRenderPipeline(&baseDescriptor);
.SetColorAttachmentFormat(0, renderPass.colorFormat)
.SetLayout(pipelineLayout) utils::ComboRenderPipelineDescriptor testDescriptor(device);
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main") testDescriptor.layout = pipelineLayout;
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main") testDescriptor.cVertexStage.module = vsModule;
.SetColorAttachmentBlendState(0, blendState) testDescriptor.cFragmentStage.module = fsModule;
.GetResult(); testDescriptor.cColorAttachments[0].format =
renderPass.colorFormat;
testDescriptor.cBlendStates[0] = blendState;
testPipeline = device.CreateRenderPipeline(&testDescriptor);
// Check that the initial blend color is (0,0,0,0) // Check that the initial blend color is (0,0,0,0)
{ {

View File

@ -15,6 +15,7 @@
#include "tests/DawnTest.h" #include "tests/DawnTest.h"
#include "common/Assert.h" #include "common/Assert.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h" #include "utils/DawnHelpers.h"
constexpr static unsigned int kRTSize = 64; constexpr static unsigned int kRTSize = 64;
@ -213,14 +214,16 @@ class DepthStencilStateTest : public DawnTest {
dawn::BindGroup bindGroup = utils::MakeBindGroup(device, bindGroupLayout, {{0, buffer, 0, sizeof(TriangleData)}}); dawn::BindGroup bindGroup = utils::MakeBindGroup(device, bindGroupLayout, {{0, buffer, 0, sizeof(TriangleData)}});
// Create a pipeline for the triangles with the test spec's depth stencil state // Create a pipeline for the triangles with the test spec's depth stencil state
dawn::RenderPipeline pipeline = device.CreateRenderPipelineBuilder()
.SetColorAttachmentFormat(0, dawn::TextureFormat::R8G8B8A8Unorm) utils::ComboRenderPipelineDescriptor descriptor(device);
.SetDepthStencilAttachmentFormat(dawn::TextureFormat::D32FloatS8Uint) descriptor.layout = pipelineLayout;
.SetLayout(pipelineLayout) descriptor.cVertexStage.module = vsModule;
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main") descriptor.cFragmentStage.module = fsModule;
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main") descriptor.cAttachmentsState.hasDepthStencilAttachment = true;
.SetDepthStencilState(test.depthStencilState) descriptor.cDepthStencilAttachment.format = dawn::TextureFormat::D32FloatS8Uint;
.GetResult(); descriptor.depthStencilState = test.depthStencilState;
dawn::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
pass.SetRenderPipeline(pipeline); pass.SetRenderPipeline(pipeline);
pass.SetStencilReference(test.stencil); // Set the stencil reference pass.SetStencilReference(test.stencil); // Set the stencil reference

View File

@ -14,6 +14,7 @@
#include "tests/DawnTest.h" #include "tests/DawnTest.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h" #include "utils/DawnHelpers.h"
constexpr uint32_t kRTSize = 4; constexpr uint32_t kRTSize = 4;
@ -46,14 +47,16 @@ class DrawElementsTest : public DawnTest {
})" })"
); );
pipeline = device.CreateRenderPipelineBuilder() utils::ComboRenderPipelineDescriptor descriptor(device);
.SetColorAttachmentFormat(0, renderPass.colorFormat) descriptor.cVertexStage.module = vsModule;
.SetPrimitiveTopology(dawn::PrimitiveTopology::TriangleStrip) descriptor.cFragmentStage.module = fsModule;
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main") descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleStrip;
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main") descriptor.indexFormat = dawn::IndexFormat::Uint32;
.SetIndexFormat(dawn::IndexFormat::Uint32) descriptor.inputState = inputState;
.SetInputState(inputState) descriptor.cColorAttachments[0].format =
.GetResult(); renderPass.colorFormat;
pipeline = device.CreateRenderPipeline(&descriptor);
vertexBuffer = utils::CreateBufferFromData<float>(device, dawn::BufferUsageBit::Vertex, { vertexBuffer = utils::CreateBufferFromData<float>(device, dawn::BufferUsageBit::Vertex, {
-1.0f, -1.0f, 0.0f, 1.0f, -1.0f, -1.0f, 0.0f, 1.0f,

View File

@ -15,6 +15,7 @@
#include "tests/DawnTest.h" #include "tests/DawnTest.h"
#include "common/Assert.h" #include "common/Assert.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h" #include "utils/DawnHelpers.h"
constexpr uint32_t kRTSize = 400; constexpr uint32_t kRTSize = 400;
@ -51,14 +52,16 @@ class IndexFormatTest : public DawnTest {
})" })"
); );
return device.CreateRenderPipelineBuilder() utils::ComboRenderPipelineDescriptor descriptor(device);
.SetColorAttachmentFormat(0, renderPass.colorFormat) descriptor.cVertexStage.module = vsModule;
.SetPrimitiveTopology(dawn::PrimitiveTopology::TriangleStrip) descriptor.cFragmentStage.module = fsModule;
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main") descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleStrip;
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main") descriptor.indexFormat = format;
.SetIndexFormat(format) descriptor.inputState = inputState;
.SetInputState(inputState) descriptor.cColorAttachments[0].format =
.GetResult(); renderPass.colorFormat;
return device.CreateRenderPipeline(&descriptor);
} }
}; };

View File

@ -15,6 +15,7 @@
#include "tests/DawnTest.h" #include "tests/DawnTest.h"
#include "common/Assert.h" #include "common/Assert.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h" #include "utils/DawnHelpers.h"
using dawn::InputStepMode; using dawn::InputStepMode;
@ -120,12 +121,14 @@ class InputStateTest : public DawnTest {
})" })"
); );
return device.CreateRenderPipelineBuilder() utils::ComboRenderPipelineDescriptor descriptor(device);
.SetColorAttachmentFormat(0, renderPass.colorFormat) descriptor.cVertexStage.module = vsModule;
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main") descriptor.cFragmentStage.module = fsModule;
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main") descriptor.inputState = inputState;
.SetInputState(inputState) descriptor.cColorAttachments[0].format =
.GetResult(); renderPass.colorFormat;
return device.CreateRenderPipeline(&descriptor);
} }
struct InputSpec { struct InputSpec {

View File

@ -15,6 +15,7 @@
#include "tests/DawnTest.h" #include "tests/DawnTest.h"
#include "common/Assert.h" #include "common/Assert.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h" #include "utils/DawnHelpers.h"
// Primitive topology tests work by drawing the following vertices with all the different primitive topology states: // Primitive topology tests work by drawing the following vertices with all the different primitive topology states:
@ -185,13 +186,16 @@ class PrimitiveTopologyTest : public DawnTest {
// Draw the vertices with the given primitive topology and check the pixel values of the test locations // 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) { void DoTest(dawn::PrimitiveTopology primitiveTopology, const std::vector<LocationSpec> &locationSpecs) {
dawn::RenderPipeline pipeline = device.CreateRenderPipelineBuilder()
.SetColorAttachmentFormat(0, renderPass.colorFormat) utils::ComboRenderPipelineDescriptor descriptor(device);
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main") descriptor.cVertexStage.module = vsModule;
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main") descriptor.cFragmentStage.module = fsModule;
.SetInputState(inputState) descriptor.primitiveTopology = primitiveTopology;
.SetPrimitiveTopology(primitiveTopology) descriptor.inputState = inputState;
.GetResult(); descriptor.cColorAttachments[0].format =
renderPass.colorFormat;
dawn::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
static const uint32_t zeroOffset = 0; static const uint32_t zeroOffset = 0;
dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder();

View File

@ -16,6 +16,7 @@
#include "common/Assert.h" #include "common/Assert.h"
#include "common/Constants.h" #include "common/Constants.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h" #include "utils/DawnHelpers.h"
#include <array> #include <array>
@ -189,20 +190,18 @@ class PushConstantTest: public DawnTest {
blend.srcFactor = dawn::BlendFactor::One; blend.srcFactor = dawn::BlendFactor::One;
blend.dstFactor = dawn::BlendFactor::One; blend.dstFactor = dawn::BlendFactor::One;
dawn::BlendState blendState = device.CreateBlendStateBuilder() utils::ComboRenderPipelineDescriptor descriptor(device);
.SetBlendEnabled(true) descriptor.layout = layout;
.SetColorBlend(&blend) descriptor.cVertexStage.module = vsModule;
.SetAlphaBlend(&blend) descriptor.cFragmentStage.module = fsModule;
.GetResult(); descriptor.primitiveTopology = dawn::PrimitiveTopology::PointList;
descriptor.cBlendStates[0] = device.CreateBlendStateBuilder()
.SetBlendEnabled(true)
.SetColorBlend(&blend)
.SetAlphaBlend(&blend)
.GetResult();
return device.CreateRenderPipelineBuilder() return device.CreateRenderPipeline(&descriptor);
.SetColorAttachmentFormat(0, dawn::TextureFormat::R8G8B8A8Unorm)
.SetLayout(layout)
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
.SetPrimitiveTopology(dawn::PrimitiveTopology::PointList)
.SetColorAttachmentBlendState(0, blendState)
.GetResult();
} }
}; };

View File

@ -14,6 +14,7 @@
#include "tests/DawnTest.h" #include "tests/DawnTest.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h" #include "utils/DawnHelpers.h"
#include <array> #include <array>
@ -23,28 +24,29 @@ constexpr static unsigned int kRTSize = 16;
class DrawQuad { class DrawQuad {
public: public:
DrawQuad() {} DrawQuad() {}
DrawQuad(dawn::Device* device, const char* vsSource, const char* fsSource) DrawQuad(dawn::Device device, const char* vsSource, const char* fsSource)
: device(device) { : device(device) {
vsModule = utils::CreateShaderModule(*device, dawn::ShaderStage::Vertex, vsSource); vsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, vsSource);
fsModule = utils::CreateShaderModule(*device, dawn::ShaderStage::Fragment, fsSource); fsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, fsSource);
pipelineLayout = utils::MakeBasicPipelineLayout(*device, nullptr); pipelineLayout = utils::MakeBasicPipelineLayout(device, nullptr);
} }
void Draw(dawn::RenderPassEncoder* pass) { void Draw(dawn::RenderPassEncoder* pass) {
auto renderPipeline = device->CreateRenderPipelineBuilder()
.SetColorAttachmentFormat(0, dawn::TextureFormat::R8G8B8A8Unorm) utils::ComboRenderPipelineDescriptor descriptor(device);
.SetLayout(pipelineLayout) descriptor.layout = pipelineLayout;
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main") descriptor.cVertexStage.module = vsModule;
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main") descriptor.cFragmentStage.module = fsModule;
.GetResult();
auto renderPipeline = device.CreateRenderPipeline(&descriptor);
pass->SetRenderPipeline(renderPipeline); pass->SetRenderPipeline(renderPipeline);
pass->Draw(6, 1, 0, 0); pass->Draw(6, 1, 0, 0);
} }
private: private:
dawn::Device* device = nullptr; dawn::Device device;
dawn::ShaderModule vsModule = {}; dawn::ShaderModule vsModule = {};
dawn::ShaderModule fsModule = {}; dawn::ShaderModule fsModule = {};
dawn::PipelineLayout pipelineLayout = {}; dawn::PipelineLayout pipelineLayout = {};
@ -94,7 +96,7 @@ class RenderPassLoadOpTests : public DawnTest {
color = vec4(0.f, 0.f, 1.f, 1.f); color = vec4(0.f, 0.f, 1.f, 1.f);
} }
)"; )";
blueQuad = DrawQuad(&device, vsSource, fsSource); blueQuad = DrawQuad(device, vsSource, fsSource);
} }
dawn::Texture renderTarget; dawn::Texture renderTarget;

View File

@ -12,13 +12,13 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include <array>
#include <cmath> #include <cmath>
#include "tests/DawnTest.h" #include "tests/DawnTest.h"
#include "common/Assert.h" #include "common/Assert.h"
#include "common/Constants.h" #include "common/Constants.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h" #include "utils/DawnHelpers.h"
constexpr static unsigned int kRTSize = 64; constexpr static unsigned int kRTSize = 64;
@ -73,12 +73,14 @@ protected:
} }
)"); )");
mPipeline = device.CreateRenderPipelineBuilder() utils::ComboRenderPipelineDescriptor pipelineDescriptor(device);
.SetColorAttachmentFormat(0, mRenderPass.colorFormat) pipelineDescriptor.layout = pipelineLayout;
.SetLayout(pipelineLayout) pipelineDescriptor.cVertexStage.module = vsModule;
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main") pipelineDescriptor.cFragmentStage.module = fsModule;
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main") pipelineDescriptor.cColorAttachments[0].format =
.GetResult(); mRenderPass.colorFormat;
mPipeline = device.CreateRenderPipeline(&pipelineDescriptor);
dawn::TextureDescriptor descriptor; dawn::TextureDescriptor descriptor;
descriptor.dimension = dawn::TextureDimension::e2D; descriptor.dimension = dawn::TextureDimension::e2D;

View File

@ -14,6 +14,7 @@
#include "tests/DawnTest.h" #include "tests/DawnTest.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h" #include "utils/DawnHelpers.h"
class ScissorTest: public DawnTest { class ScissorTest: public DawnTest {
@ -36,13 +37,13 @@ class ScissorTest: public DawnTest {
fragColor = vec4(0.0f, 1.0f, 0.0f, 1.0f); fragColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);
})"); })");
dawn::RenderPipeline pipeline = device.CreateRenderPipelineBuilder() utils::ComboRenderPipelineDescriptor descriptor(device);
.SetColorAttachmentFormat(0, format) descriptor.cVertexStage.module = vsModule;
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main") descriptor.cFragmentStage.module = fsModule;
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main") descriptor.cColorAttachments[0].format =
.GetResult(); format;
return pipeline; return device.CreateRenderPipeline(&descriptor);
} }
}; };

View File

@ -17,6 +17,7 @@
#include "common/Assert.h" #include "common/Assert.h"
#include "common/Constants.h" #include "common/Constants.h"
#include "common/Math.h" #include "common/Math.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h" #include "utils/DawnHelpers.h"
#include <array> #include <array>
@ -163,12 +164,14 @@ protected:
dawn::ShaderModule fsModule = dawn::ShaderModule fsModule =
utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, fragmentShader); utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, fragmentShader);
dawn::RenderPipeline pipeline = device.CreateRenderPipelineBuilder() utils::ComboRenderPipelineDescriptor textureDescriptor(device);
.SetColorAttachmentFormat(0, mRenderPass.colorFormat) textureDescriptor.cVertexStage.module = mVSModule;
.SetLayout(mPipelineLayout) textureDescriptor.cFragmentStage.module = fsModule;
.SetStage(dawn::ShaderStage::Vertex, mVSModule, "main") textureDescriptor.layout = mPipelineLayout;
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main") textureDescriptor.cColorAttachments[0].format =
.GetResult(); mRenderPass.colorFormat;
dawn::RenderPipeline pipeline = device.CreateRenderPipeline(&textureDescriptor);
dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder();
{ {
@ -502,11 +505,13 @@ class TextureViewRenderingTest : public DawnTest {
dawn::ShaderModule oneColorFsModule = dawn::ShaderModule oneColorFsModule =
utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, oneColorFragmentShader); utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, oneColorFragmentShader);
dawn::RenderPipeline oneColorPipeline = device.CreateRenderPipelineBuilder() utils::ComboRenderPipelineDescriptor pipelineDescriptor(device);
.SetColorAttachmentFormat(0, kDefaultFormat) pipelineDescriptor.cVertexStage.module = vsModule;
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main") pipelineDescriptor.cFragmentStage.module = oneColorFsModule;
.SetStage(dawn::ShaderStage::Fragment, oneColorFsModule, "main") pipelineDescriptor.cColorAttachments[0].format = kDefaultFormat;
.GetResult();
dawn::RenderPipeline oneColorPipeline = device.CreateRenderPipeline(&pipelineDescriptor);
dawn::CommandBufferBuilder commandBufferBuilder = device.CreateCommandBufferBuilder(); dawn::CommandBufferBuilder commandBufferBuilder = device.CreateCommandBufferBuilder();
{ {
dawn::RenderPassEncoder pass = dawn::RenderPassEncoder pass =

View File

@ -14,6 +14,7 @@
#include "tests/DawnTest.h" #include "tests/DawnTest.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h" #include "utils/DawnHelpers.h"
class ViewportOrientationTests : public DawnTest {}; class ViewportOrientationTests : public DawnTest {};
@ -35,12 +36,14 @@ TEST_P(ViewportOrientationTests, OriginAt0x0) {
fragColor = vec4(0.0f, 1.0f, 0.0f, 1.0f); fragColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);
})"); })");
dawn::RenderPipeline pipeline = device.CreateRenderPipelineBuilder() utils::ComboRenderPipelineDescriptor descriptor(device);
.SetColorAttachmentFormat(0, renderPass.colorFormat) descriptor.cVertexStage.module = vsModule;
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main") descriptor.cFragmentStage.module = fsModule;
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main") descriptor.primitiveTopology = dawn::PrimitiveTopology::PointList;
.SetPrimitiveTopology(dawn::PrimitiveTopology::PointList) descriptor.cColorAttachments[0].format =
.GetResult(); renderPass.colorFormat;
dawn::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder();
{ {

View File

@ -318,24 +318,99 @@ TEST_F(WireTests, ValueArrayArgument) {
// Test that the wire is able to send C strings // Test that the wire is able to send C strings
TEST_F(WireTests, CStringArgument) { TEST_F(WireTests, CStringArgument) {
// Create shader module // Create shader module
dawnShaderModuleDescriptor descriptor; dawnShaderModuleDescriptor vertexDescriptor;
descriptor.nextInChain = nullptr; vertexDescriptor.nextInChain = nullptr;
descriptor.codeSize = 0; vertexDescriptor.codeSize = 0;
dawnShaderModule shaderModule = dawnDeviceCreateShaderModule(device, &descriptor); dawnShaderModule vsModule = dawnDeviceCreateShaderModule(device, &vertexDescriptor);
dawnShaderModule apiVsModule = api.GetNewShaderModule();
dawnShaderModule apiShaderModule = api.GetNewShaderModule();
EXPECT_CALL(api, DeviceCreateShaderModule(apiDevice, _)) EXPECT_CALL(api, DeviceCreateShaderModule(apiDevice, _))
.WillOnce(Return(apiShaderModule)); .WillOnce(Return(apiVsModule));
// Create the blend state
dawnBlendStateBuilder blendStateBuilder = dawnDeviceCreateBlendStateBuilder(device);
dawnBlendStateBuilder apiBlendStateBuilder = api.GetNewBlendStateBuilder();
EXPECT_CALL(api, DeviceCreateBlendStateBuilder(apiDevice))
.WillOnce(Return(apiBlendStateBuilder));
dawnBlendState blendState = dawnBlendStateBuilderGetResult(blendStateBuilder);
dawnBlendState apiBlendState = api.GetNewBlendState();
EXPECT_CALL(api, BlendStateBuilderGetResult(apiBlendStateBuilder))
.WillOnce(Return(apiBlendState));
// 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));
// Create the depth-stencil state
dawnDepthStencilStateBuilder depthStencilStateBuilder = dawnDeviceCreateDepthStencilStateBuilder(device);
dawnDepthStencilStateBuilder apiDepthStencilStateBuilder = api.GetNewDepthStencilStateBuilder();
EXPECT_CALL(api, DeviceCreateDepthStencilStateBuilder(apiDevice))
.WillOnce(Return(apiDepthStencilStateBuilder));
dawnDepthStencilState depthStencilState = dawnDepthStencilStateBuilderGetResult(depthStencilStateBuilder);
dawnDepthStencilState apiDepthStencilState = api.GetNewDepthStencilState();
EXPECT_CALL(api, DepthStencilStateBuilderGetResult(apiDepthStencilStateBuilder))
.WillOnce(Return(apiDepthStencilState));
// Create the pipeline layout
dawnPipelineLayoutDescriptor layoutDescriptor;
layoutDescriptor.nextInChain = nullptr;
layoutDescriptor.numBindGroupLayouts = 0;
layoutDescriptor.bindGroupLayouts = nullptr;
dawnPipelineLayout layout = dawnDeviceCreatePipelineLayout(device, &layoutDescriptor);
dawnPipelineLayout apiLayout = api.GetNewPipelineLayout();
EXPECT_CALL(api, DeviceCreatePipelineLayout(apiDevice, _))
.WillOnce(Return(apiLayout));
// Create pipeline // Create pipeline
dawnRenderPipelineBuilder pipelineBuilder = dawnDeviceCreateRenderPipelineBuilder(device); dawnRenderPipelineDescriptor pipelineDescriptor;
dawnRenderPipelineBuilderSetStage(pipelineBuilder, DAWN_SHADER_STAGE_FRAGMENT, shaderModule, "my entry point"); pipelineDescriptor.nextInChain = nullptr;
dawnRenderPipelineBuilder apiPipelineBuilder = api.GetNewRenderPipelineBuilder(); dawnPipelineStageDescriptor vertexStage;
EXPECT_CALL(api, DeviceCreateRenderPipelineBuilder(apiDevice)) vertexStage.nextInChain = nullptr;
.WillOnce(Return(apiPipelineBuilder)); vertexStage.module = vsModule;
vertexStage.entryPoint = "main";
pipelineDescriptor.vertexStage = &vertexStage;
EXPECT_CALL(api, RenderPipelineBuilderSetStage(apiPipelineBuilder, DAWN_SHADER_STAGE_FRAGMENT, apiShaderModule, StrEq("my entry point"))); dawnPipelineStageDescriptor fragmentStage;
fragmentStage.nextInChain = nullptr;
fragmentStage.module = vsModule;
fragmentStage.entryPoint = "main";
pipelineDescriptor.fragmentStage = &fragmentStage;
dawnAttachmentsStateDescriptor attachmentsState;
attachmentsState.nextInChain = nullptr;
attachmentsState.numColorAttachments = 1;
dawnAttachmentDescriptor colorAttachment = {nullptr, DAWN_TEXTURE_FORMAT_R8_G8_B8_A8_UNORM};
attachmentsState.colorAttachments = &colorAttachment;
attachmentsState.hasDepthStencilAttachment = false;
// Even with hasDepthStencilAttachment = false, depthStencilAttachment must point to valid
// data because we don't have optional substructures yet.
attachmentsState.depthStencilAttachment = &colorAttachment;
pipelineDescriptor.attachmentsState = &attachmentsState;
pipelineDescriptor.numBlendStates = 1;
pipelineDescriptor.blendStates = &blendState;
pipelineDescriptor.sampleCount = 1;
pipelineDescriptor.layout = layout;
pipelineDescriptor.inputState = inputState;
pipelineDescriptor.indexFormat = DAWN_INDEX_FORMAT_UINT32;
pipelineDescriptor.primitiveTopology = DAWN_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
pipelineDescriptor.depthStencilState = depthStencilState;
dawnDeviceCreateRenderPipeline(device, &pipelineDescriptor);
EXPECT_CALL(api, DeviceCreateRenderPipeline(apiDevice, MatchesLambda([](const dawnRenderPipelineDescriptor* desc) -> bool {
return desc->vertexStage->entryPoint == std::string("main");
})))
.WillOnce(Return(nullptr));
FlushClient(); FlushClient();
} }

View File

@ -14,15 +14,12 @@
#include "tests/unittests/validation/ValidationTest.h" #include "tests/unittests/validation/ValidationTest.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h" #include "utils/DawnHelpers.h"
// Maximums for Dawn, tests will start failing when this changes
static constexpr uint32_t kMaxVertexAttributes = 16u;
static constexpr uint32_t kMaxVertexInputs = 16u;
class InputStateTest : public ValidationTest { class InputStateTest : public ValidationTest {
protected: protected:
dawn::RenderPipeline CreatePipeline(bool success, const dawn::InputState& inputState, std::string vertexSource) { void CreatePipeline(bool success, const dawn::InputState& inputState, std::string vertexSource) {
DummyRenderPass renderpassData = CreateDummyRenderPass(); DummyRenderPass renderpassData = CreateDummyRenderPass();
dawn::ShaderModule vsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, vertexSource.c_str()); dawn::ShaderModule vsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, vertexSource.c_str());
@ -34,18 +31,18 @@ class InputStateTest : public ValidationTest {
} }
)"); )");
dawn::RenderPipelineBuilder builder; utils::ComboRenderPipelineDescriptor descriptor(device);
if (success) { descriptor.cVertexStage.module = vsModule;
builder = AssertWillBeSuccess(device.CreateRenderPipelineBuilder()); descriptor.cFragmentStage.module = fsModule;
} else { descriptor.inputState = inputState;
builder = AssertWillBeError(device.CreateRenderPipelineBuilder()); descriptor.cColorAttachments[0].format =
} renderpassData.attachmentFormat;
return builder.SetColorAttachmentFormat(0, renderpassData.attachmentFormat) if (!success) {
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main") ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor));
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main") } else {
.SetInputState(inputState) device.CreateRenderPipeline(&descriptor);
.GetResult(); }
} }
}; };

View File

@ -15,6 +15,7 @@
#include "tests/unittests/validation/ValidationTest.h" #include "tests/unittests/validation/ValidationTest.h"
#include "common/Constants.h" #include "common/Constants.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h" #include "utils/DawnHelpers.h"
class RenderPipelineValidationTest : public ValidationTest { class RenderPipelineValidationTest : public ValidationTest {
@ -24,12 +25,6 @@ class RenderPipelineValidationTest : public ValidationTest {
renderpass = CreateSimpleRenderPass(); renderpass = CreateSimpleRenderPass();
pipelineLayout = utils::MakeBasicPipelineLayout(device, nullptr);
inputState = device.CreateInputStateBuilder().GetResult();
blendState = device.CreateBlendStateBuilder().GetResult();
vsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, R"( vsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, R"(
#version 450 #version 450
void main() { void main() {
@ -45,167 +40,49 @@ class RenderPipelineValidationTest : public ValidationTest {
})"); })");
} }
dawn::RenderPipelineBuilder& AddDefaultStates(dawn::RenderPipelineBuilder&& builder) {
builder.SetColorAttachmentFormat(0, dawn::TextureFormat::R8G8B8A8Unorm)
.SetLayout(pipelineLayout)
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
.SetPrimitiveTopology(dawn::PrimitiveTopology::TriangleList);
return builder;
}
dawn::RenderPassDescriptor renderpass; dawn::RenderPassDescriptor renderpass;
dawn::ShaderModule vsModule; dawn::ShaderModule vsModule;
dawn::ShaderModule fsModule; dawn::ShaderModule fsModule;
dawn::InputState inputState;
dawn::BlendState blendState;
dawn::PipelineLayout pipelineLayout;
}; };
// Test cases where creation should succeed // Test cases where creation should succeed
TEST_F(RenderPipelineValidationTest, CreationSuccess) { TEST_F(RenderPipelineValidationTest, CreationSuccess) {
AddDefaultStates(AssertWillBeSuccess(device.CreateRenderPipelineBuilder())) utils::ComboRenderPipelineDescriptor descriptor(device);
.GetResult(); descriptor.cVertexStage.module = vsModule;
descriptor.cFragmentStage.module = fsModule;
AddDefaultStates(AssertWillBeSuccess(device.CreateRenderPipelineBuilder())) device.CreateRenderPipeline(&descriptor);
.SetInputState(inputState)
.GetResult();
AddDefaultStates(AssertWillBeSuccess(device.CreateRenderPipelineBuilder()))
.SetColorAttachmentBlendState(0, blendState)
.GetResult();
}
// Test creation failure when properties are missing
TEST_F(RenderPipelineValidationTest, CreationMissingProperty) {
// Vertex stage not set
{
AssertWillBeError(device.CreateRenderPipelineBuilder())
.SetColorAttachmentFormat(0, dawn::TextureFormat::R8G8B8A8Unorm)
.SetLayout(pipelineLayout)
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
.SetPrimitiveTopology(dawn::PrimitiveTopology::TriangleList)
.GetResult();
}
// Fragment stage not set
{
AssertWillBeError(device.CreateRenderPipelineBuilder())
.SetColorAttachmentFormat(0, dawn::TextureFormat::R8G8B8A8Unorm)
.SetLayout(pipelineLayout)
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
.SetPrimitiveTopology(dawn::PrimitiveTopology::TriangleList)
.GetResult();
}
// No attachment set
{
AssertWillBeError(device.CreateRenderPipelineBuilder())
.SetLayout(pipelineLayout)
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
.SetPrimitiveTopology(dawn::PrimitiveTopology::TriangleList)
.GetResult();
}
} }
TEST_F(RenderPipelineValidationTest, BlendState) { TEST_F(RenderPipelineValidationTest, BlendState) {
// Fails because blend state is set on a nonexistent color attachment
{ {
// This one succeeds because attachment 0 is the color attachment // This one succeeds because attachment 0 is the color attachment
AssertWillBeSuccess(device.CreateRenderPipelineBuilder()) utils::ComboRenderPipelineDescriptor descriptor(device);
.SetColorAttachmentFormat(0, dawn::TextureFormat::R8G8B8A8Unorm) descriptor.cVertexStage.module = vsModule;
.SetLayout(pipelineLayout) descriptor.cFragmentStage.module = fsModule;
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main") descriptor.numBlendStates = 1;
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
.SetPrimitiveTopology(dawn::PrimitiveTopology::TriangleList)
.SetColorAttachmentBlendState(0, blendState)
.GetResult();
// This fails because attachment 1 is not one of the color attachments device.CreateRenderPipeline(&descriptor);
AssertWillBeError(device.CreateRenderPipelineBuilder())
.SetColorAttachmentFormat(0, dawn::TextureFormat::R8G8B8A8Unorm)
.SetLayout(pipelineLayout)
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
.SetPrimitiveTopology(dawn::PrimitiveTopology::TriangleList)
.SetColorAttachmentBlendState(1, blendState)
.GetResult();
} }
// Fails because color attachment is out of bounds { // Fail because lack of blend states for color attachments
{ utils::ComboRenderPipelineDescriptor descriptor(device);
AddDefaultStates(AssertWillBeError(device.CreateRenderPipelineBuilder())) descriptor.cVertexStage.module = vsModule;
.SetColorAttachmentBlendState(kMaxColorAttachments, blendState) descriptor.cFragmentStage.module = fsModule;
.GetResult(); descriptor.numBlendStates = 0;
ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor));
} }
// Fails because color attachment blend state is set twice
{ {
AddDefaultStates(AssertWillBeError(device.CreateRenderPipelineBuilder())) // Fail because set blend states for empty color attachments
.SetColorAttachmentBlendState(0, blendState) utils::ComboRenderPipelineDescriptor descriptor(device);
.SetColorAttachmentBlendState(0, blendState) descriptor.cVertexStage.module = vsModule;
.GetResult(); descriptor.cFragmentStage.module = fsModule;
descriptor.numBlendStates = 2;
ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor));
} }
} }
// TODO(enga@google.com): These should be added to the test above when validation is implemented
TEST_F(RenderPipelineValidationTest, DISABLED_TodoCreationMissingProperty) {
// Fails because pipeline layout is not set
{
AssertWillBeError(device.CreateRenderPipelineBuilder())
.SetColorAttachmentFormat(0, dawn::TextureFormat::R8G8B8A8Unorm)
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
.SetPrimitiveTopology(dawn::PrimitiveTopology::TriangleList)
.GetResult();
}
// Fails because primitive topology is not set
{
AssertWillBeError(device.CreateRenderPipelineBuilder())
.SetColorAttachmentFormat(0, dawn::TextureFormat::R8G8B8A8Unorm)
.SetLayout(pipelineLayout)
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
.GetResult();
}
}
// Test creation failure when specifying properties multiple times
TEST_F(RenderPipelineValidationTest, DISABLED_CreationDuplicates) {
// Fails because input state is set twice
{
AddDefaultStates(AssertWillBeError(device.CreateRenderPipelineBuilder()))
.SetInputState(inputState)
.GetResult();
}
// Fails because primitive topology is set twice
{
AddDefaultStates(AssertWillBeError(device.CreateRenderPipelineBuilder()))
.SetPrimitiveTopology(dawn::PrimitiveTopology::TriangleList)
.GetResult();
}
// Fails because vertex stage is set twice
{
AddDefaultStates(AssertWillBeError(device.CreateRenderPipelineBuilder()))
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
.GetResult();
}
// Fails because fragment stage is set twice
{
AddDefaultStates(AssertWillBeError(device.CreateRenderPipelineBuilder()))
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
.GetResult();
}
// Fails because the layout is set twice
{
AddDefaultStates(AssertWillBeError(device.CreateRenderPipelineBuilder()))
.SetLayout(pipelineLayout)
.GetResult();
}
}

View File

@ -16,6 +16,7 @@
#include "tests/unittests/validation/ValidationTest.h" #include "tests/unittests/validation/ValidationTest.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h" #include "utils/DawnHelpers.h"
class VertexBufferValidationTest : public ValidationTest { class VertexBufferValidationTest : public ValidationTest {
@ -78,12 +79,13 @@ class VertexBufferValidationTest : public ValidationTest {
} }
dawn::RenderPipeline MakeRenderPipeline(const dawn::ShaderModule& vsModule, const dawn::InputState& inputState) { dawn::RenderPipeline MakeRenderPipeline(const dawn::ShaderModule& vsModule, const dawn::InputState& inputState) {
return device.CreateRenderPipelineBuilder()
.SetColorAttachmentFormat(0, dawn::TextureFormat::R8G8B8A8Unorm) utils::ComboRenderPipelineDescriptor descriptor(device);
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main") descriptor.cVertexStage.module = vsModule;
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main") descriptor.cFragmentStage.module = fsModule;
.SetInputState(inputState) descriptor.inputState = inputState;
.GetResult();
return device.CreateRenderPipeline(&descriptor);
} }
dawn::RenderPassDescriptor renderpass; dawn::RenderPassDescriptor renderpass;

View File

@ -0,0 +1,65 @@
// 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 "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h"
namespace utils {
ComboRenderPipelineDescriptor::ComboRenderPipelineDescriptor(const dawn::Device& device) {
dawn::RenderPipelineDescriptor* descriptor = this;
descriptor->indexFormat = dawn::IndexFormat::Uint32;
descriptor->primitiveTopology = dawn::PrimitiveTopology::TriangleList;
descriptor->sampleCount = 1;
// Set defaults for the vertex stage descriptor.
{
descriptor->vertexStage = &cVertexStage;
cVertexStage.entryPoint = "main";
}
// Set defaults for the fragment stage desriptor.
{
descriptor->fragmentStage = &cFragmentStage;
cFragmentStage.entryPoint = "main";
}
// Set defaults for the attachment states.
{
descriptor->attachmentsState = &cAttachmentsState;
cAttachmentsState.numColorAttachments = 1;
cAttachmentsState.colorAttachments = cColorAttachments;
cAttachmentsState.depthStencilAttachment = &cDepthStencilAttachment;
cAttachmentsState.hasDepthStencilAttachment = false;
for (uint32_t i = 0; i < kMaxColorAttachments; ++i) {
cColorAttachments[i].format = dawn::TextureFormat::R8G8B8A8Unorm;
}
}
descriptor->inputState = device.CreateInputStateBuilder().GetResult();
descriptor->depthStencilState = device.CreateDepthStencilStateBuilder().GetResult();
descriptor->layout = utils::MakeBasicPipelineLayout(device, nullptr);
descriptor->numBlendStates = 1;
descriptor->blendStates = cBlendStates;
for (uint32_t i = 0; i < kMaxColorAttachments; ++i) {
cBlendStates[i] = device.CreateBlendStateBuilder().GetResult();
}
}
} // namespace utils

View File

@ -0,0 +1,39 @@
// 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 UTILS_COMBORENDERPIPELINEDESCRIPTOR_H_
#define UTILS_COMBORENDERPIPELINEDESCRIPTOR_H_
#include <dawn/dawncpp.h>
#include "common/Constants.h"
namespace utils {
class ComboRenderPipelineDescriptor : public dawn::RenderPipelineDescriptor {
public:
ComboRenderPipelineDescriptor(const dawn::Device& device);
dawn::PipelineStageDescriptor cVertexStage;
dawn::PipelineStageDescriptor cFragmentStage;
dawn::AttachmentsStateDescriptor cAttachmentsState;
dawn::AttachmentDescriptor cColorAttachments[kMaxColorAttachments];
dawn::AttachmentDescriptor cDepthStencilAttachment;
dawn::BlendState cBlendStates[kMaxColorAttachments];
};
} // namespace utils
#endif // UTILS_COMBORENDERPIPELINEDESCRIPTOR_H_