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:
parent
07df605a2b
commit
a49242766a
2
BUILD.gn
2
BUILD.gn
|
@ -731,6 +731,8 @@ static_library("dawn_utils") {
|
|||
sources = [
|
||||
"src/utils/BackendBinding.cpp",
|
||||
"src/utils/BackendBinding.h",
|
||||
"src/utils/ComboRenderPipelineDescriptor.cpp",
|
||||
"src/utils/ComboRenderPipelineDescriptor.h",
|
||||
"src/utils/DawnHelpers.cpp",
|
||||
"src/utils/DawnHelpers.h",
|
||||
"src/utils/SystemUtils.cpp",
|
||||
|
|
114
dawn.json
114
dawn.json
|
@ -22,6 +22,13 @@
|
|||
{"value": 2, "name":"clamp to edge"}
|
||||
]
|
||||
},
|
||||
"attachment descriptor": {
|
||||
"category": "structure",
|
||||
"extensible": true,
|
||||
"members": [
|
||||
{"name": "format", "type": "texture format"}
|
||||
]
|
||||
},
|
||||
"bind group": {
|
||||
"category": "object"
|
||||
},
|
||||
|
@ -463,8 +470,11 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"name": "create render pipeline builder",
|
||||
"returns": "render pipeline builder"
|
||||
"name": "create render pipeline",
|
||||
"returns": "render pipeline",
|
||||
"args": [
|
||||
{"name": "descriptor", "type": "render pipeline descriptor", "annotation": "const*"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "create pipeline layout",
|
||||
|
@ -679,6 +689,16 @@
|
|||
{"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": {
|
||||
"category": "object"
|
||||
},
|
||||
|
@ -690,6 +710,14 @@
|
|||
{"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": {
|
||||
"category": "enum",
|
||||
"values": [
|
||||
|
@ -863,73 +891,21 @@
|
|||
"render pipeline": {
|
||||
"category": "object"
|
||||
},
|
||||
"render pipeline builder": {
|
||||
"category": "object",
|
||||
"methods": [
|
||||
{
|
||||
"name": "get result",
|
||||
"returns": "render pipeline"
|
||||
},
|
||||
{
|
||||
"name": "set color attachment format",
|
||||
"TODO": "Also need sample count",
|
||||
"args": [
|
||||
{"name": "attachment slot", "type": "uint32_t"},
|
||||
{"name": "format", "type": "texture format"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"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"}
|
||||
]
|
||||
}
|
||||
"render pipeline descriptor": {
|
||||
"category": "structure",
|
||||
"extensible": true,
|
||||
"members": [
|
||||
{"name": "layout", "type": "pipeline layout"},
|
||||
{"name": "vertex stage", "type": "pipeline stage descriptor", "annotation": "const*"},
|
||||
{"name": "fragment stage", "type": "pipeline stage descriptor", "annotation": "const*"},
|
||||
{"name": "input state", "type": "input state"},
|
||||
{"name": "index format", "type": "index format"},
|
||||
{"name": "primitive topology", "type": "primitive topology"},
|
||||
{"name": "attachments state", "type": "attachments state descriptor", "annotation": "const*"},
|
||||
{"name": "sample count", "type": "uint32_t"},
|
||||
{"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"}
|
||||
]
|
||||
},
|
||||
"sampler": {
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "SampleUtils.h"
|
||||
|
||||
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "utils/DawnHelpers.h"
|
||||
#include "utils/SystemUtils.h"
|
||||
|
||||
|
@ -109,12 +110,15 @@ void init() {
|
|||
|
||||
depthStencilView = CreateDefaultDepthStencilView(device);
|
||||
|
||||
pipeline = device.CreateRenderPipelineBuilder()
|
||||
.SetColorAttachmentFormat(0, GetPreferredSwapChainTextureFormat())
|
||||
.SetDepthStencilAttachmentFormat(dawn::TextureFormat::D32FloatS8Uint)
|
||||
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
|
||||
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
|
||||
.GetResult();
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
descriptor.cFragmentStage.module = fsModule;
|
||||
descriptor.cAttachmentsState.hasDepthStencilAttachment = true;
|
||||
descriptor.cDepthStencilAttachment.format = dawn::TextureFormat::D32FloatS8Uint;
|
||||
descriptor.cColorAttachments[0].format =
|
||||
GetPreferredSwapChainTextureFormat();
|
||||
|
||||
pipeline = device.CreateRenderPipeline(&descriptor);
|
||||
|
||||
shaderData.resize(10000);
|
||||
for (auto& data : shaderData) {
|
||||
|
|
|
@ -56,12 +56,62 @@ void init() {
|
|||
dawnShaderModule fsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, fs).Release();
|
||||
|
||||
{
|
||||
dawnRenderPipelineBuilder builder = dawnDeviceCreateRenderPipelineBuilder(device);
|
||||
dawnRenderPipelineBuilderSetColorAttachmentFormat(builder, 0, swapChainFormat);
|
||||
dawnRenderPipelineBuilderSetStage(builder, DAWN_SHADER_STAGE_VERTEX, vsModule, "main");
|
||||
dawnRenderPipelineBuilderSetStage(builder, DAWN_SHADER_STAGE_FRAGMENT, fsModule, "main");
|
||||
pipeline = dawnRenderPipelineBuilderGetResult(builder);
|
||||
dawnRenderPipelineBuilderRelease(builder);
|
||||
dawnRenderPipelineDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
|
||||
dawnPipelineStageDescriptor vertexStage;
|
||||
vertexStage.nextInChain = nullptr;
|
||||
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);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "SampleUtils.h"
|
||||
|
||||
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "utils/DawnHelpers.h"
|
||||
#include "utils/SystemUtils.h"
|
||||
|
||||
|
@ -123,13 +124,16 @@ void initRender() {
|
|||
|
||||
depthStencilView = CreateDefaultDepthStencilView(device);
|
||||
|
||||
renderPipeline = device.CreateRenderPipelineBuilder()
|
||||
.SetColorAttachmentFormat(0, GetPreferredSwapChainTextureFormat())
|
||||
.SetDepthStencilAttachmentFormat(dawn::TextureFormat::D32FloatS8Uint)
|
||||
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
|
||||
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
|
||||
.SetInputState(inputState)
|
||||
.GetResult();
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
descriptor.cFragmentStage.module = fsModule;
|
||||
descriptor.inputState = inputState;
|
||||
descriptor.cAttachmentsState.hasDepthStencilAttachment = true;
|
||||
descriptor.cDepthStencilAttachment.format = dawn::TextureFormat::D32FloatS8Uint;
|
||||
descriptor.cColorAttachments[0].format =
|
||||
GetPreferredSwapChainTextureFormat();
|
||||
|
||||
renderPipeline = device.CreateRenderPipeline(&descriptor);
|
||||
}
|
||||
|
||||
void initSim() {
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "SampleUtils.h"
|
||||
|
||||
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "utils/DawnHelpers.h"
|
||||
#include "utils/SystemUtils.h"
|
||||
|
||||
|
@ -125,15 +126,17 @@ void init() {
|
|||
|
||||
depthStencilView = CreateDefaultDepthStencilView(device);
|
||||
|
||||
pipeline = device.CreateRenderPipelineBuilder()
|
||||
.SetColorAttachmentFormat(0, GetPreferredSwapChainTextureFormat())
|
||||
.SetDepthStencilAttachmentFormat(dawn::TextureFormat::D32FloatS8Uint)
|
||||
.SetLayout(pl)
|
||||
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
|
||||
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
|
||||
.SetIndexFormat(dawn::IndexFormat::Uint32)
|
||||
.SetInputState(inputState)
|
||||
.GetResult();
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.layout = utils::MakeBasicPipelineLayout(device, &bgl);
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
descriptor.cFragmentStage.module = fsModule;
|
||||
descriptor.inputState = inputState;
|
||||
descriptor.cAttachmentsState.hasDepthStencilAttachment = true;
|
||||
descriptor.cDepthStencilAttachment.format = dawn::TextureFormat::D32FloatS8Uint;
|
||||
descriptor.cColorAttachments[0].format =
|
||||
GetPreferredSwapChainTextureFormat();
|
||||
|
||||
pipeline = device.CreateRenderPipeline(&descriptor);
|
||||
|
||||
dawn::TextureView view = texture.CreateDefaultTextureView();
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "SampleUtils.h"
|
||||
|
||||
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "utils/DawnHelpers.h"
|
||||
#include "utils/SystemUtils.h"
|
||||
|
||||
|
@ -197,16 +198,18 @@ void init() {
|
|||
.SetDepthWriteEnabled(true)
|
||||
.GetResult();
|
||||
|
||||
pipeline = device.CreateRenderPipelineBuilder()
|
||||
.SetColorAttachmentFormat(0, GetPreferredSwapChainTextureFormat())
|
||||
.SetDepthStencilAttachmentFormat(dawn::TextureFormat::D32FloatS8Uint)
|
||||
.SetLayout(pl)
|
||||
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
|
||||
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
|
||||
.SetIndexFormat(dawn::IndexFormat::Uint32)
|
||||
.SetInputState(inputState)
|
||||
.SetDepthStencilState(depthStencilState)
|
||||
.GetResult();
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.layout = pl;
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
descriptor.cFragmentStage.module = fsModule;
|
||||
descriptor.inputState = inputState;
|
||||
descriptor.cAttachmentsState.hasDepthStencilAttachment = true;
|
||||
descriptor.cDepthStencilAttachment.format = dawn::TextureFormat::D32FloatS8Uint;
|
||||
descriptor.cColorAttachments[0].format =
|
||||
GetPreferredSwapChainTextureFormat();
|
||||
descriptor.depthStencilState = depthStencilState;
|
||||
|
||||
pipeline = device.CreateRenderPipeline(&descriptor);
|
||||
|
||||
auto planeStencilState = device.CreateDepthStencilStateBuilder()
|
||||
.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)
|
||||
.GetResult();
|
||||
|
||||
planePipeline = device.CreateRenderPipelineBuilder()
|
||||
.SetColorAttachmentFormat(0, GetPreferredSwapChainTextureFormat())
|
||||
.SetDepthStencilAttachmentFormat(dawn::TextureFormat::D32FloatS8Uint)
|
||||
.SetLayout(pl)
|
||||
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
|
||||
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
|
||||
.SetInputState(inputState)
|
||||
.SetDepthStencilState(planeStencilState)
|
||||
.GetResult();
|
||||
utils::ComboRenderPipelineDescriptor pDescriptor(device);
|
||||
pDescriptor.layout = pl;
|
||||
pDescriptor.cVertexStage.module = vsModule;
|
||||
pDescriptor.cFragmentStage.module = fsModule;
|
||||
pDescriptor.inputState = inputState;
|
||||
pDescriptor.cAttachmentsState.hasDepthStencilAttachment = true;
|
||||
pDescriptor.cDepthStencilAttachment.format = dawn::TextureFormat::D32FloatS8Uint;
|
||||
pDescriptor.cColorAttachments[0].format =
|
||||
GetPreferredSwapChainTextureFormat();
|
||||
pDescriptor.depthStencilState = planeStencilState;
|
||||
|
||||
planePipeline = device.CreateRenderPipeline(&pDescriptor);
|
||||
|
||||
auto reflectionStencilState = device.CreateDepthStencilStateBuilder()
|
||||
.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)
|
||||
.GetResult();
|
||||
|
||||
reflectionPipeline = device.CreateRenderPipelineBuilder()
|
||||
.SetColorAttachmentFormat(0, GetPreferredSwapChainTextureFormat())
|
||||
.SetDepthStencilAttachmentFormat(dawn::TextureFormat::D32FloatS8Uint)
|
||||
.SetLayout(pl)
|
||||
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
|
||||
.SetStage(dawn::ShaderStage::Fragment, fsReflectionModule, "main")
|
||||
.SetInputState(inputState)
|
||||
.SetDepthStencilState(reflectionStencilState)
|
||||
.GetResult();
|
||||
utils::ComboRenderPipelineDescriptor rfDescriptor(device);
|
||||
rfDescriptor.layout = pl;
|
||||
rfDescriptor.cVertexStage.module = vsModule;
|
||||
rfDescriptor.cFragmentStage.module = fsReflectionModule;
|
||||
rfDescriptor.inputState = inputState;
|
||||
rfDescriptor.cAttachmentsState.hasDepthStencilAttachment = true;
|
||||
rfDescriptor.cDepthStencilAttachment.format = dawn::TextureFormat::D32FloatS8Uint;
|
||||
rfDescriptor.cColorAttachments[0].format =
|
||||
GetPreferredSwapChainTextureFormat();
|
||||
rfDescriptor.depthStencilState = reflectionStencilState;
|
||||
|
||||
reflectionPipeline = device.CreateRenderPipeline(&rfDescriptor);
|
||||
|
||||
cameraData.proj = glm::perspective(glm::radians(45.0f), 1.f, 1.0f, 100.0f);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "common/Assert.h"
|
||||
#include "common/Math.h"
|
||||
#include "common/Constants.h"
|
||||
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "utils/DawnHelpers.h"
|
||||
#include "utils/SystemUtils.h"
|
||||
|
||||
|
@ -287,16 +288,20 @@ namespace {
|
|||
.GetResult();
|
||||
|
||||
auto pipelineLayout = utils::MakeBasicPipelineLayout(device, &bindGroupLayout);
|
||||
auto pipeline = device.CreateRenderPipelineBuilder()
|
||||
.SetColorAttachmentFormat(0, GetPreferredSwapChainTextureFormat())
|
||||
.SetDepthStencilAttachmentFormat(dawn::TextureFormat::D32FloatS8Uint)
|
||||
.SetLayout(pipelineLayout)
|
||||
.SetStage(dawn::ShaderStage::Vertex, oVSModule, "main")
|
||||
.SetStage(dawn::ShaderStage::Fragment, oFSModule, "main")
|
||||
.SetIndexFormat(dawn::IndexFormat::Uint16)
|
||||
.SetInputState(inputState)
|
||||
.SetDepthStencilState(depthStencilState)
|
||||
.GetResult();
|
||||
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.layout = pipelineLayout;
|
||||
descriptor.cVertexStage.module = oVSModule;
|
||||
descriptor.cFragmentStage.module = oFSModule;
|
||||
descriptor.inputState = inputState;
|
||||
descriptor.indexFormat = dawn::IndexFormat::Uint16;
|
||||
descriptor.cAttachmentsState.hasDepthStencilAttachment = true;
|
||||
descriptor.cDepthStencilAttachment.format = dawn::TextureFormat::D32FloatS8Uint;
|
||||
descriptor.cColorAttachments[0].format =
|
||||
GetPreferredSwapChainTextureFormat();
|
||||
descriptor.depthStencilState = depthStencilState;
|
||||
|
||||
dawn::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
|
||||
|
||||
dawn::BindGroup bindGroup;
|
||||
|
||||
|
|
|
@ -182,9 +182,6 @@ namespace dawn_native {
|
|||
RenderPassDescriptorBuilder* DeviceBase::CreateRenderPassDescriptorBuilder() {
|
||||
return new RenderPassDescriptorBuilder(this);
|
||||
}
|
||||
RenderPipelineBuilder* DeviceBase::CreateRenderPipelineBuilder() {
|
||||
return new RenderPipelineBuilder(this);
|
||||
}
|
||||
SamplerBase* DeviceBase::CreateSampler(const SamplerDescriptor* descriptor) {
|
||||
SamplerBase* result = nullptr;
|
||||
|
||||
|
@ -194,6 +191,16 @@ namespace dawn_native {
|
|||
|
||||
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* result = nullptr;
|
||||
|
||||
|
@ -296,6 +303,14 @@ namespace dawn_native {
|
|||
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,
|
||||
const SamplerDescriptor* descriptor) {
|
||||
DAWN_TRY(ValidateSamplerDescriptor(this, descriptor));
|
||||
|
|
|
@ -58,7 +58,6 @@ namespace dawn_native {
|
|||
virtual InputStateBase* CreateInputState(InputStateBuilder* builder) = 0;
|
||||
virtual RenderPassDescriptorBase* CreateRenderPassDescriptor(
|
||||
RenderPassDescriptorBuilder* builder) = 0;
|
||||
virtual RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) = 0;
|
||||
virtual SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) = 0;
|
||||
|
||||
virtual Serial GetCompletedCommandSerial() const = 0;
|
||||
|
@ -96,7 +95,7 @@ namespace dawn_native {
|
|||
PipelineLayoutBase* CreatePipelineLayout(const PipelineLayoutDescriptor* descriptor);
|
||||
QueueBase* CreateQueue();
|
||||
RenderPassDescriptorBuilder* CreateRenderPassDescriptorBuilder();
|
||||
RenderPipelineBuilder* CreateRenderPipelineBuilder();
|
||||
RenderPipelineBase* CreateRenderPipeline(const RenderPipelineDescriptor* descriptor);
|
||||
SamplerBase* CreateSampler(const SamplerDescriptor* descriptor);
|
||||
ShaderModuleBase* CreateShaderModule(const ShaderModuleDescriptor* descriptor);
|
||||
SwapChainBuilder* CreateSwapChainBuilder();
|
||||
|
@ -127,6 +126,8 @@ namespace dawn_native {
|
|||
virtual ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl(
|
||||
const PipelineLayoutDescriptor* descriptor) = 0;
|
||||
virtual ResultOrError<QueueBase*> CreateQueueImpl() = 0;
|
||||
virtual ResultOrError<RenderPipelineBase*> CreateRenderPipelineImpl(
|
||||
const RenderPipelineDescriptor* descriptor) = 0;
|
||||
virtual ResultOrError<SamplerBase*> CreateSamplerImpl(
|
||||
const SamplerDescriptor* descriptor) = 0;
|
||||
virtual ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
|
||||
|
@ -148,6 +149,8 @@ namespace dawn_native {
|
|||
MaybeError CreatePipelineLayoutInternal(PipelineLayoutBase** result,
|
||||
const PipelineLayoutDescriptor* descriptor);
|
||||
MaybeError CreateQueueInternal(QueueBase** result);
|
||||
MaybeError CreateRenderPipelineInternal(RenderPipelineBase** result,
|
||||
const RenderPipelineDescriptor* descriptor);
|
||||
MaybeError CreateSamplerInternal(SamplerBase** result, const SamplerDescriptor* descriptor);
|
||||
MaybeError CreateShaderModuleInternal(ShaderModuleBase** result,
|
||||
const ShaderModuleDescriptor* descriptor);
|
||||
|
|
|
@ -21,48 +21,141 @@
|
|||
#include "dawn_native/InputState.h"
|
||||
#include "dawn_native/RenderPassDescriptor.h"
|
||||
#include "dawn_native/Texture.h"
|
||||
#include "dawn_native/ValidationUtils_autogen.h"
|
||||
|
||||
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(RenderPipelineBuilder* builder)
|
||||
: PipelineBase(builder->GetDevice(), builder),
|
||||
mDepthStencilState(std::move(builder->mDepthStencilState)),
|
||||
mIndexFormat(builder->mIndexFormat),
|
||||
mInputState(std::move(builder->mInputState)),
|
||||
mPrimitiveTopology(builder->mPrimitiveTopology),
|
||||
mBlendStates(builder->mBlendStates),
|
||||
mColorAttachmentsSet(builder->mColorAttachmentsSet),
|
||||
mColorAttachmentFormats(builder->mColorAttachmentFormats),
|
||||
mDepthStencilFormatSet(builder->mDepthStencilFormatSet),
|
||||
mDepthStencilFormat(builder->mDepthStencilFormat) {
|
||||
if (GetStageMask() != (dawn::ShaderStageBit::Vertex | dawn::ShaderStageBit::Fragment)) {
|
||||
builder->HandleError("Render pipeline should have exactly a vertex and fragment stage");
|
||||
return;
|
||||
RenderPipelineBase::RenderPipelineBase(DeviceBase* device,
|
||||
const RenderPipelineDescriptor* descriptor)
|
||||
: PipelineBase(device,
|
||||
descriptor->layout,
|
||||
dawn::ShaderStageBit::Vertex | dawn::ShaderStageBit::Fragment),
|
||||
mDepthStencilState(descriptor->depthStencilState),
|
||||
mIndexFormat(descriptor->indexFormat),
|
||||
mInputState(descriptor->inputState),
|
||||
mPrimitiveTopology(descriptor->primitiveTopology),
|
||||
mHasDepthStencilAttachment(descriptor->attachmentsState->hasDepthStencilAttachment) {
|
||||
if (mHasDepthStencilAttachment) {
|
||||
mDepthStencilFormat = descriptor->attachmentsState->depthStencilAttachment->format;
|
||||
}
|
||||
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.
|
||||
|
||||
if ((builder->GetStageInfo(dawn::ShaderStage::Vertex).module->GetUsedVertexAttributes() &
|
||||
~mInputState->GetAttributesSetMask())
|
||||
.any()) {
|
||||
builder->HandleError("Pipeline vertex stage uses inputs not in the input state");
|
||||
return;
|
||||
for (uint32_t i = 0; i < descriptor->attachmentsState->numColorAttachments; ++i) {
|
||||
mColorAttachmentsSet.set(i);
|
||||
mBlendStates[i] = descriptor->blendStates[i];
|
||||
mColorAttachmentFormats[i] = descriptor->attachmentsState->colorAttachments[i].format;
|
||||
}
|
||||
|
||||
// TODO(cwallez@chromium.org): Check against the shader module that the correct color
|
||||
// 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) {
|
||||
|
@ -91,7 +184,7 @@ namespace dawn_native {
|
|||
}
|
||||
|
||||
bool RenderPipelineBase::HasDepthStencilAttachment() const {
|
||||
return mDepthStencilFormatSet;
|
||||
return mHasDepthStencilAttachment;
|
||||
}
|
||||
|
||||
dawn::TextureFormat RenderPipelineBase::GetColorAttachmentFormat(uint32_t attachment) const {
|
||||
|
@ -99,6 +192,7 @@ namespace dawn_native {
|
|||
}
|
||||
|
||||
dawn::TextureFormat RenderPipelineBase::GetDepthStencilFormat() const {
|
||||
ASSERT(mHasDepthStencilAttachment);
|
||||
return mDepthStencilFormat;
|
||||
}
|
||||
|
||||
|
@ -118,11 +212,11 @@ namespace dawn_native {
|
|||
}
|
||||
}
|
||||
|
||||
if (renderPass->HasDepthStencilAttachment() != mDepthStencilFormatSet) {
|
||||
if (renderPass->HasDepthStencilAttachment() != mHasDepthStencilAttachment) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mDepthStencilFormatSet &&
|
||||
if (mHasDepthStencilAttachment &&
|
||||
(renderPass->GetDepthStencilAttachment().view->GetTexture()->GetFormat() !=
|
||||
mDepthStencilFormat)) {
|
||||
return false;
|
||||
|
@ -131,106 +225,4 @@ namespace dawn_native {
|
|||
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
|
||||
|
|
|
@ -27,9 +27,14 @@
|
|||
|
||||
namespace dawn_native {
|
||||
|
||||
class DeviceBase;
|
||||
|
||||
MaybeError ValidateRenderPipelineDescriptor(DeviceBase* device,
|
||||
const RenderPipelineDescriptor* descriptor);
|
||||
|
||||
class RenderPipelineBase : public PipelineBase {
|
||||
public:
|
||||
RenderPipelineBase(RenderPipelineBuilder* builder);
|
||||
RenderPipelineBase(DeviceBase* device, const RenderPipelineDescriptor* descriptor);
|
||||
|
||||
BlendStateBase* GetBlendState(uint32_t attachmentSlot);
|
||||
DepthStencilStateBase* GetDepthStencilState();
|
||||
|
@ -55,39 +60,7 @@ namespace dawn_native {
|
|||
|
||||
std::bitset<kMaxColorAttachments> mColorAttachmentsSet;
|
||||
std::array<dawn::TextureFormat, kMaxColorAttachments> mColorAttachmentFormats;
|
||||
bool mDepthStencilFormatSet = 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;
|
||||
bool mHasDepthStencilAttachment = false;
|
||||
dawn::TextureFormat mDepthStencilFormat;
|
||||
};
|
||||
|
||||
|
|
|
@ -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(DeviceBase* device, const TextureDescriptor* descriptor)
|
||||
|
|
|
@ -33,6 +33,7 @@ namespace dawn_native {
|
|||
bool TextureFormatHasStencil(dawn::TextureFormat format);
|
||||
bool TextureFormatHasDepthOrStencil(dawn::TextureFormat format);
|
||||
bool IsColorRenderableTextureFormat(dawn::TextureFormat format);
|
||||
bool IsDepthStencilRenderableTextureFormat(dawn::TextureFormat format);
|
||||
|
||||
static constexpr dawn::TextureUsageBit kReadOnlyTextureUsages =
|
||||
dawn::TextureUsageBit::TransferSrc | dawn::TextureUsageBit::Sampled |
|
||||
|
|
|
@ -324,8 +324,9 @@ namespace dawn_native { namespace d3d12 {
|
|||
RenderPassDescriptorBuilder* builder) {
|
||||
return new RenderPassDescriptor(builder);
|
||||
}
|
||||
RenderPipelineBase* Device::CreateRenderPipeline(RenderPipelineBuilder* builder) {
|
||||
return new RenderPipeline(builder);
|
||||
ResultOrError<RenderPipelineBase*> Device::CreateRenderPipelineImpl(
|
||||
const RenderPipelineDescriptor* descriptor) {
|
||||
return new RenderPipeline(this, descriptor);
|
||||
}
|
||||
ResultOrError<SamplerBase*> Device::CreateSamplerImpl(const SamplerDescriptor* descriptor) {
|
||||
return new Sampler(this, descriptor);
|
||||
|
|
|
@ -47,7 +47,6 @@ namespace dawn_native { namespace d3d12 {
|
|||
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
|
||||
RenderPassDescriptorBase* CreateRenderPassDescriptor(
|
||||
RenderPassDescriptorBuilder* builder) override;
|
||||
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
|
||||
SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
|
||||
|
||||
Serial GetCompletedCommandSerial() const final override;
|
||||
|
@ -88,6 +87,8 @@ namespace dawn_native { namespace d3d12 {
|
|||
ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl(
|
||||
const PipelineLayoutDescriptor* descriptor) override;
|
||||
ResultOrError<QueueBase*> CreateQueueImpl() override;
|
||||
ResultOrError<RenderPipelineBase*> CreateRenderPipelineImpl(
|
||||
const RenderPipelineDescriptor* descriptor) override;
|
||||
ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override;
|
||||
ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
|
||||
const ShaderModuleDescriptor* descriptor) override;
|
||||
|
|
|
@ -63,10 +63,9 @@ namespace dawn_native { namespace d3d12 {
|
|||
}
|
||||
} // namespace
|
||||
|
||||
RenderPipeline::RenderPipeline(RenderPipelineBuilder* builder)
|
||||
: RenderPipelineBase(builder),
|
||||
mD3d12PrimitiveTopology(D3D12PrimitiveTopology(GetPrimitiveTopology())),
|
||||
mDevice(ToBackend(builder->GetDevice())) {
|
||||
RenderPipeline::RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor)
|
||||
: RenderPipelineBase(device, descriptor),
|
||||
mD3d12PrimitiveTopology(D3D12PrimitiveTopology(GetPrimitiveTopology())) {
|
||||
uint32_t compileFlags = 0;
|
||||
#if defined(_DEBUG)
|
||||
// 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
|
||||
compileFlags |= D3DCOMPILE_PACK_MATRIX_ROW_MAJOR;
|
||||
|
||||
D3D12_GRAPHICS_PIPELINE_STATE_DESC descriptor = {};
|
||||
D3D12_GRAPHICS_PIPELINE_STATE_DESC descriptorD3D12 = {};
|
||||
|
||||
PerStage<ComPtr<ID3DBlob>> compiledShader;
|
||||
ComPtr<ID3DBlob> errors;
|
||||
|
||||
for (auto stage : IterateStages(GetStageMask())) {
|
||||
const auto& module = ToBackend(builder->GetStageInfo(stage).module);
|
||||
const auto& entryPoint = builder->GetStageInfo(stage).entryPoint;
|
||||
const auto& hlslSource = module->GetHLSLSource(ToBackend(GetLayout()));
|
||||
|
||||
dawn::ShaderStageBit renderStages =
|
||||
dawn::ShaderStageBit::Vertex | dawn::ShaderStageBit::Fragment;
|
||||
for (auto stage : IterateStages(renderStages)) {
|
||||
const ShaderModule* module = nullptr;
|
||||
const char* entryPoint = nullptr;
|
||||
const char* compileTarget = nullptr;
|
||||
|
||||
D3D12_SHADER_BYTECODE* shader = nullptr;
|
||||
switch (stage) {
|
||||
case dawn::ShaderStage::Vertex:
|
||||
shader = &descriptor.VS;
|
||||
module = ToBackend(descriptor->vertexStage->module);
|
||||
entryPoint = descriptor->vertexStage->entryPoint;
|
||||
shader = &descriptorD3D12.VS;
|
||||
compileTarget = "vs_5_1";
|
||||
break;
|
||||
case dawn::ShaderStage::Fragment:
|
||||
shader = &descriptor.PS;
|
||||
module = ToBackend(descriptor->fragmentStage->module);
|
||||
entryPoint = descriptor->fragmentStage->entryPoint;
|
||||
shader = &descriptorD3D12.PS;
|
||||
compileTarget = "ps_5_1";
|
||||
break;
|
||||
case dawn::ShaderStage::Compute:
|
||||
default:
|
||||
UNREACHABLE();
|
||||
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,
|
||||
nullptr, nullptr, entryPoint.c_str(), compileTarget,
|
||||
nullptr, nullptr, entryPoint, compileTarget,
|
||||
compileFlags, 0, &compiledShader[stage], &errors))) {
|
||||
printf("%s\n", reinterpret_cast<char*>(errors->GetBufferPointer()));
|
||||
ASSERT(false);
|
||||
|
@ -118,54 +122,55 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
PipelineLayout* layout = ToBackend(GetLayout());
|
||||
|
||||
descriptor.pRootSignature = layout->GetRootSignature().Get();
|
||||
descriptorD3D12.pRootSignature = layout->GetRootSignature().Get();
|
||||
|
||||
// D3D12 logs warnings if any empty input state is used
|
||||
InputState* inputState = ToBackend(GetInputState());
|
||||
if (inputState->GetAttributesSetMask().any()) {
|
||||
descriptor.InputLayout = inputState->GetD3D12InputLayoutDescriptor();
|
||||
descriptorD3D12.InputLayout = inputState->GetD3D12InputLayoutDescriptor();
|
||||
}
|
||||
|
||||
descriptor.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
|
||||
descriptor.RasterizerState.CullMode = D3D12_CULL_MODE_NONE;
|
||||
descriptor.RasterizerState.FrontCounterClockwise = FALSE;
|
||||
descriptor.RasterizerState.DepthBias = D3D12_DEFAULT_DEPTH_BIAS;
|
||||
descriptor.RasterizerState.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP;
|
||||
descriptor.RasterizerState.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
|
||||
descriptor.RasterizerState.DepthClipEnable = TRUE;
|
||||
descriptor.RasterizerState.MultisampleEnable = FALSE;
|
||||
descriptor.RasterizerState.AntialiasedLineEnable = FALSE;
|
||||
descriptor.RasterizerState.ForcedSampleCount = 0;
|
||||
descriptor.RasterizerState.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
|
||||
descriptorD3D12.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
|
||||
descriptorD3D12.RasterizerState.CullMode = D3D12_CULL_MODE_NONE;
|
||||
descriptorD3D12.RasterizerState.FrontCounterClockwise = FALSE;
|
||||
descriptorD3D12.RasterizerState.DepthBias = D3D12_DEFAULT_DEPTH_BIAS;
|
||||
descriptorD3D12.RasterizerState.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP;
|
||||
descriptorD3D12.RasterizerState.SlopeScaledDepthBias =
|
||||
D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
|
||||
descriptorD3D12.RasterizerState.DepthClipEnable = TRUE;
|
||||
descriptorD3D12.RasterizerState.MultisampleEnable = FALSE;
|
||||
descriptorD3D12.RasterizerState.AntialiasedLineEnable = FALSE;
|
||||
descriptorD3D12.RasterizerState.ForcedSampleCount = 0;
|
||||
descriptorD3D12.RasterizerState.ConservativeRaster =
|
||||
D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
|
||||
|
||||
if (HasDepthStencilAttachment()) {
|
||||
descriptor.DSVFormat = D3D12TextureFormat(GetDepthStencilFormat());
|
||||
descriptorD3D12.DSVFormat = D3D12TextureFormat(GetDepthStencilFormat());
|
||||
}
|
||||
|
||||
for (uint32_t i : IterateBitSet(GetColorAttachmentsMask())) {
|
||||
descriptor.RTVFormats[i] = D3D12TextureFormat(GetColorAttachmentFormat(i));
|
||||
descriptor.BlendState.RenderTarget[i] =
|
||||
descriptorD3D12.RTVFormats[i] = D3D12TextureFormat(GetColorAttachmentFormat(i));
|
||||
descriptorD3D12.BlendState.RenderTarget[i] =
|
||||
ToBackend(GetBlendState(i))->GetD3D12BlendDesc();
|
||||
}
|
||||
descriptor.NumRenderTargets = static_cast<uint32_t>(GetColorAttachmentsMask().count());
|
||||
descriptorD3D12.NumRenderTargets = static_cast<uint32_t>(GetColorAttachmentsMask().count());
|
||||
|
||||
descriptor.BlendState.AlphaToCoverageEnable = FALSE;
|
||||
descriptor.BlendState.IndependentBlendEnable = TRUE;
|
||||
descriptorD3D12.BlendState.AlphaToCoverageEnable = FALSE;
|
||||
descriptorD3D12.BlendState.IndependentBlendEnable = TRUE;
|
||||
|
||||
DepthStencilState* depthStencilState = ToBackend(GetDepthStencilState());
|
||||
descriptor.DepthStencilState = depthStencilState->GetD3D12DepthStencilDescriptor();
|
||||
descriptorD3D12.DepthStencilState = depthStencilState->GetD3D12DepthStencilDescriptor();
|
||||
|
||||
descriptor.SampleMask = UINT_MAX;
|
||||
descriptor.PrimitiveTopologyType = D3D12PrimitiveTopologyType(GetPrimitiveTopology());
|
||||
descriptor.SampleDesc.Count = 1;
|
||||
descriptorD3D12.SampleMask = UINT_MAX;
|
||||
descriptorD3D12.PrimitiveTopologyType = D3D12PrimitiveTopologyType(GetPrimitiveTopology());
|
||||
descriptorD3D12.SampleDesc.Count = 1;
|
||||
|
||||
Device* device = ToBackend(builder->GetDevice());
|
||||
ASSERT_SUCCESS(device->GetD3D12Device()->CreateGraphicsPipelineState(
|
||||
&descriptor, IID_PPV_ARGS(&mPipelineState)));
|
||||
&descriptorD3D12, IID_PPV_ARGS(&mPipelineState)));
|
||||
}
|
||||
|
||||
RenderPipeline::~RenderPipeline() {
|
||||
mDevice->ReferenceUntilUnused(mPipelineState);
|
||||
ToBackend(GetDevice())->ReferenceUntilUnused(mPipelineState);
|
||||
}
|
||||
|
||||
D3D12_PRIMITIVE_TOPOLOGY RenderPipeline::GetD3D12PrimitiveTopology() const {
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
class RenderPipeline : public RenderPipelineBase {
|
||||
public:
|
||||
RenderPipeline(RenderPipelineBuilder* builder);
|
||||
RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor);
|
||||
~RenderPipeline();
|
||||
|
||||
D3D12_PRIMITIVE_TOPOLOGY GetD3D12PrimitiveTopology() const;
|
||||
|
@ -34,8 +34,6 @@ namespace dawn_native { namespace d3d12 {
|
|||
private:
|
||||
D3D12_PRIMITIVE_TOPOLOGY mD3d12PrimitiveTopology;
|
||||
ComPtr<ID3D12PipelineState> mPipelineState;
|
||||
|
||||
Device* mDevice = nullptr;
|
||||
};
|
||||
|
||||
}} // namespace dawn_native::d3d12
|
||||
|
|
|
@ -43,7 +43,6 @@ namespace dawn_native { namespace metal {
|
|||
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
|
||||
RenderPassDescriptorBase* CreateRenderPassDescriptor(
|
||||
RenderPassDescriptorBuilder* builder) override;
|
||||
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
|
||||
SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
|
||||
|
||||
Serial GetCompletedCommandSerial() const final override;
|
||||
|
@ -72,6 +71,8 @@ namespace dawn_native { namespace metal {
|
|||
ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl(
|
||||
const PipelineLayoutDescriptor* descriptor) override;
|
||||
ResultOrError<QueueBase*> CreateQueueImpl() override;
|
||||
ResultOrError<RenderPipelineBase*> CreateRenderPipelineImpl(
|
||||
const RenderPipelineDescriptor* descriptor) override;
|
||||
ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override;
|
||||
ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
|
||||
const ShaderModuleDescriptor* descriptor) override;
|
||||
|
|
|
@ -197,12 +197,13 @@ namespace dawn_native { namespace metal {
|
|||
RenderPassDescriptorBuilder* builder) {
|
||||
return new RenderPassDescriptor(builder);
|
||||
}
|
||||
RenderPipelineBase* Device::CreateRenderPipeline(RenderPipelineBuilder* builder) {
|
||||
return new RenderPipeline(builder);
|
||||
}
|
||||
ResultOrError<QueueBase*> Device::CreateQueueImpl() {
|
||||
return new Queue(this);
|
||||
}
|
||||
ResultOrError<RenderPipelineBase*> Device::CreateRenderPipelineImpl(
|
||||
const RenderPipelineDescriptor* descriptor) {
|
||||
return new RenderPipeline(this, descriptor);
|
||||
}
|
||||
ResultOrError<SamplerBase*> Device::CreateSamplerImpl(const SamplerDescriptor* descriptor) {
|
||||
return new Sampler(this, descriptor);
|
||||
}
|
||||
|
|
|
@ -21,9 +21,11 @@
|
|||
|
||||
namespace dawn_native { namespace metal {
|
||||
|
||||
class Device;
|
||||
|
||||
class RenderPipeline : public RenderPipelineBase {
|
||||
public:
|
||||
RenderPipeline(RenderPipelineBuilder* builder);
|
||||
RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor);
|
||||
~RenderPipeline();
|
||||
|
||||
MTLIndexType GetMTLIndexType() const;
|
||||
|
|
|
@ -64,65 +64,57 @@ namespace dawn_native { namespace metal {
|
|||
}
|
||||
}
|
||||
|
||||
RenderPipeline::RenderPipeline(RenderPipelineBuilder* builder)
|
||||
: RenderPipelineBase(builder),
|
||||
RenderPipeline::RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor)
|
||||
: RenderPipelineBase(device, descriptor),
|
||||
mMtlIndexType(MTLIndexFormat(GetIndexFormat())),
|
||||
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 auto& module = ToBackend(builder->GetStageInfo(stage).module);
|
||||
const ShaderModule* vertexModule = ToBackend(descriptor->vertexStage->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;
|
||||
ShaderModule::MetalFunctionData data =
|
||||
module->GetFunction(entryPoint.c_str(), stage, ToBackend(GetLayout()));
|
||||
id<MTLFunction> function = data.function;
|
||||
|
||||
switch (stage) {
|
||||
case dawn::ShaderStage::Vertex:
|
||||
descriptor.vertexFunction = function;
|
||||
break;
|
||||
case dawn::ShaderStage::Fragment:
|
||||
descriptor.fragmentFunction = function;
|
||||
break;
|
||||
case dawn::ShaderStage::Compute:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
const ShaderModule* fragmentModule = ToBackend(descriptor->fragmentStage->module);
|
||||
const char* fragmentEntryPoint = descriptor->fragmentStage->entryPoint;
|
||||
ShaderModule::MetalFunctionData fragmentData = fragmentModule->GetFunction(
|
||||
fragmentEntryPoint, dawn::ShaderStage::Fragment, ToBackend(GetLayout()));
|
||||
descriptorMTL.fragmentFunction = fragmentData.function;
|
||||
|
||||
if (HasDepthStencilAttachment()) {
|
||||
// TODO(kainino@chromium.org): Handle depth-only and stencil-only formats.
|
||||
dawn::TextureFormat depthStencilFormat = GetDepthStencilFormat();
|
||||
descriptor.depthAttachmentPixelFormat = MetalPixelFormat(depthStencilFormat);
|
||||
descriptor.stencilAttachmentPixelFormat = MetalPixelFormat(depthStencilFormat);
|
||||
descriptorMTL.depthAttachmentPixelFormat = MetalPixelFormat(depthStencilFormat);
|
||||
descriptorMTL.stencilAttachmentPixelFormat = MetalPixelFormat(depthStencilFormat);
|
||||
}
|
||||
|
||||
for (uint32_t i : IterateBitSet(GetColorAttachmentsMask())) {
|
||||
descriptor.colorAttachments[i].pixelFormat =
|
||||
descriptorMTL.colorAttachments[i].pixelFormat =
|
||||
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());
|
||||
descriptor.vertexDescriptor = inputState->GetMTLVertexDescriptor();
|
||||
descriptorMTL.vertexDescriptor = inputState->GetMTLVertexDescriptor();
|
||||
|
||||
// TODO(kainino@chromium.org): push constants, textures, samplers
|
||||
|
||||
NSError* error = nil;
|
||||
mMtlRenderPipelineState = [mtlDevice newRenderPipelineStateWithDescriptor:descriptor
|
||||
mMtlRenderPipelineState = [mtlDevice newRenderPipelineStateWithDescriptor:descriptorMTL
|
||||
error:&error];
|
||||
if (error != nil) {
|
||||
NSLog(@" error => %@", error);
|
||||
builder->HandleError("Error creating pipeline state");
|
||||
[descriptor release];
|
||||
device->HandleError("Error creating rendering pipeline state");
|
||||
[descriptorMTL release];
|
||||
return;
|
||||
}
|
||||
|
||||
[descriptor release];
|
||||
[descriptorMTL release];
|
||||
}
|
||||
|
||||
RenderPipeline::~RenderPipeline() {
|
||||
|
|
|
@ -72,8 +72,9 @@ namespace dawn_native { namespace null {
|
|||
RenderPassDescriptorBuilder* builder) {
|
||||
return new RenderPassDescriptor(builder);
|
||||
}
|
||||
RenderPipelineBase* Device::CreateRenderPipeline(RenderPipelineBuilder* builder) {
|
||||
return new RenderPipeline(builder);
|
||||
ResultOrError<RenderPipelineBase*> Device::CreateRenderPipelineImpl(
|
||||
const RenderPipelineDescriptor* descriptor) {
|
||||
return new RenderPipeline(this, descriptor);
|
||||
}
|
||||
ResultOrError<SamplerBase*> Device::CreateSamplerImpl(const SamplerDescriptor* descriptor) {
|
||||
return new Sampler(this, descriptor);
|
||||
|
|
|
@ -99,7 +99,6 @@ namespace dawn_native { namespace null {
|
|||
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
|
||||
RenderPassDescriptorBase* CreateRenderPassDescriptor(
|
||||
RenderPassDescriptorBuilder* builder) override;
|
||||
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
|
||||
SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
|
||||
|
||||
Serial GetCompletedCommandSerial() const final override;
|
||||
|
@ -122,6 +121,8 @@ namespace dawn_native { namespace null {
|
|||
ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl(
|
||||
const PipelineLayoutDescriptor* descriptor) override;
|
||||
ResultOrError<QueueBase*> CreateQueueImpl() override;
|
||||
ResultOrError<RenderPipelineBase*> CreateRenderPipelineImpl(
|
||||
const RenderPipelineDescriptor* descriptor) override;
|
||||
ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override;
|
||||
ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
|
||||
const ShaderModuleDescriptor* descriptor) override;
|
||||
|
|
|
@ -99,8 +99,9 @@ namespace dawn_native { namespace opengl {
|
|||
RenderPassDescriptorBuilder* builder) {
|
||||
return new RenderPassDescriptor(builder);
|
||||
}
|
||||
RenderPipelineBase* Device::CreateRenderPipeline(RenderPipelineBuilder* builder) {
|
||||
return new RenderPipeline(builder);
|
||||
ResultOrError<RenderPipelineBase*> Device::CreateRenderPipelineImpl(
|
||||
const RenderPipelineDescriptor* descriptor) {
|
||||
return new RenderPipeline(this, descriptor);
|
||||
}
|
||||
ResultOrError<SamplerBase*> Device::CreateSamplerImpl(const SamplerDescriptor* descriptor) {
|
||||
return new Sampler(this, descriptor);
|
||||
|
|
|
@ -46,7 +46,6 @@ namespace dawn_native { namespace opengl {
|
|||
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
|
||||
RenderPassDescriptorBase* CreateRenderPassDescriptor(
|
||||
RenderPassDescriptorBuilder* builder) override;
|
||||
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
|
||||
SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
|
||||
|
||||
Serial GetCompletedCommandSerial() const final override;
|
||||
|
@ -66,6 +65,8 @@ namespace dawn_native { namespace opengl {
|
|||
ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl(
|
||||
const PipelineLayoutDescriptor* descriptor) override;
|
||||
ResultOrError<QueueBase*> CreateQueueImpl() override;
|
||||
ResultOrError<RenderPipelineBase*> CreateRenderPipelineImpl(
|
||||
const RenderPipelineDescriptor* descriptor) override;
|
||||
ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override;
|
||||
ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
|
||||
const ShaderModuleDescriptor* descriptor) override;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "dawn_native/opengl/BlendStateGL.h"
|
||||
#include "dawn_native/opengl/DepthStencilStateGL.h"
|
||||
#include "dawn_native/opengl/DeviceGL.h"
|
||||
#include "dawn_native/opengl/Forward.h"
|
||||
#include "dawn_native/opengl/InputStateGL.h"
|
||||
#include "dawn_native/opengl/PersistentPipelineStateGL.h"
|
||||
|
@ -41,13 +42,12 @@ namespace dawn_native { namespace opengl {
|
|||
}
|
||||
} // namespace
|
||||
|
||||
RenderPipeline::RenderPipeline(RenderPipelineBuilder* builder)
|
||||
: RenderPipelineBase(builder),
|
||||
RenderPipeline::RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor)
|
||||
: RenderPipelineBase(device, descriptor),
|
||||
mGlPrimitiveTopology(GLPrimitiveTopology(GetPrimitiveTopology())) {
|
||||
PerStage<const ShaderModule*> modules(nullptr);
|
||||
for (dawn::ShaderStage stage : IterateStages(GetStageMask())) {
|
||||
modules[stage] = ToBackend(builder->GetStageInfo(stage).module.Get());
|
||||
}
|
||||
modules[dawn::ShaderStage::Vertex] = ToBackend(descriptor->vertexStage->module);
|
||||
modules[dawn::ShaderStage::Fragment] = ToBackend(descriptor->fragmentStage->module);
|
||||
|
||||
PipelineGL::Initialize(ToBackend(GetLayout()), modules);
|
||||
}
|
||||
|
|
|
@ -25,11 +25,12 @@
|
|||
|
||||
namespace dawn_native { namespace opengl {
|
||||
|
||||
class Device;
|
||||
class PersistentPipelineState;
|
||||
|
||||
class RenderPipeline : public RenderPipelineBase, public PipelineGL {
|
||||
public:
|
||||
RenderPipeline(RenderPipelineBuilder* builder);
|
||||
RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor);
|
||||
|
||||
GLenum GetGLPrimitiveTopology() const;
|
||||
|
||||
|
|
|
@ -250,8 +250,9 @@ namespace dawn_native { namespace vulkan {
|
|||
RenderPassDescriptorBuilder* builder) {
|
||||
return new RenderPassDescriptor(builder);
|
||||
}
|
||||
RenderPipelineBase* Device::CreateRenderPipeline(RenderPipelineBuilder* builder) {
|
||||
return new RenderPipeline(builder);
|
||||
ResultOrError<RenderPipelineBase*> Device::CreateRenderPipelineImpl(
|
||||
const RenderPipelineDescriptor* descriptor) {
|
||||
return new RenderPipeline(this, descriptor);
|
||||
}
|
||||
ResultOrError<SamplerBase*> Device::CreateSamplerImpl(const SamplerDescriptor* descriptor) {
|
||||
return new Sampler(this, descriptor);
|
||||
|
|
|
@ -69,7 +69,6 @@ namespace dawn_native { namespace vulkan {
|
|||
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
|
||||
RenderPassDescriptorBase* CreateRenderPassDescriptor(
|
||||
RenderPassDescriptorBuilder* builder) override;
|
||||
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
|
||||
SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
|
||||
|
||||
Serial GetCompletedCommandSerial() const final override;
|
||||
|
@ -89,6 +88,8 @@ namespace dawn_native { namespace vulkan {
|
|||
ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl(
|
||||
const PipelineLayoutDescriptor* descriptor) override;
|
||||
ResultOrError<QueueBase*> CreateQueueImpl() override;
|
||||
ResultOrError<RenderPipelineBase*> CreateRenderPipelineImpl(
|
||||
const RenderPipelineDescriptor* descriptor) override;
|
||||
ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override;
|
||||
ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
|
||||
const ShaderModuleDescriptor* descriptor) override;
|
||||
|
|
|
@ -47,32 +47,29 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
} // anonymous namespace
|
||||
|
||||
RenderPipeline::RenderPipeline(RenderPipelineBuilder* builder)
|
||||
: RenderPipelineBase(builder), mDevice(ToBackend(builder->GetDevice())) {
|
||||
RenderPipeline::RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor)
|
||||
: RenderPipelineBase(device, descriptor) {
|
||||
// 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
|
||||
// everything here.
|
||||
|
||||
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].pNext = nullptr;
|
||||
shaderStages[0].flags = 0;
|
||||
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].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].pNext = nullptr;
|
||||
shaderStages[1].flags = 0;
|
||||
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].module = ToBackend(descriptor->fragmentStage->module)->GetHandle();
|
||||
shaderStages[1].pName = descriptor->fragmentStage->entryPoint;
|
||||
}
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo inputAssembly;
|
||||
|
@ -183,7 +180,7 @@ namespace dawn_native { namespace vulkan {
|
|||
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
|
||||
|
@ -209,15 +206,15 @@ namespace dawn_native { namespace vulkan {
|
|||
createInfo.basePipelineHandle = VK_NULL_HANDLE;
|
||||
createInfo.basePipelineIndex = -1;
|
||||
|
||||
if (mDevice->fn.CreateGraphicsPipelines(mDevice->GetVkDevice(), VK_NULL_HANDLE, 1,
|
||||
&createInfo, nullptr, &mHandle) != VK_SUCCESS) {
|
||||
if (device->fn.CreateGraphicsPipelines(device->GetVkDevice(), VK_NULL_HANDLE, 1,
|
||||
&createInfo, nullptr, &mHandle) != VK_SUCCESS) {
|
||||
ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
RenderPipeline::~RenderPipeline() {
|
||||
if (mHandle != VK_NULL_HANDLE) {
|
||||
mDevice->GetFencedDeleter()->DeleteWhenUnused(mHandle);
|
||||
ToBackend(GetDevice())->GetFencedDeleter()->DeleteWhenUnused(mHandle);
|
||||
mHandle = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,14 +25,13 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
class RenderPipeline : public RenderPipelineBase {
|
||||
public:
|
||||
RenderPipeline(RenderPipelineBuilder* builder);
|
||||
RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor);
|
||||
~RenderPipeline();
|
||||
|
||||
VkPipeline GetHandle() const;
|
||||
|
||||
private:
|
||||
VkPipeline mHandle = VK_NULL_HANDLE;
|
||||
Device* mDevice = nullptr;
|
||||
};
|
||||
|
||||
}} // namespace dawn_native::vulkan
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "common/Assert.h"
|
||||
#include "common/Constants.h"
|
||||
#include "tests/DawnTest.h"
|
||||
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "utils/DawnHelpers.h"
|
||||
|
||||
constexpr static unsigned int kRTSize = 8;
|
||||
|
@ -114,13 +115,15 @@ TEST_P(BindGroupTests, ReusedUBO) {
|
|||
);
|
||||
dawn::PipelineLayout pipelineLayout = utils::MakeBasicPipelineLayout(device, &bgl);
|
||||
|
||||
dawn::RenderPipeline pipeline = device.CreateRenderPipelineBuilder()
|
||||
.SetColorAttachmentFormat(0, renderPass.colorFormat)
|
||||
.SetLayout(pipelineLayout)
|
||||
.SetPrimitiveTopology(dawn::PrimitiveTopology::TriangleList)
|
||||
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
|
||||
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
|
||||
.GetResult();
|
||||
utils::ComboRenderPipelineDescriptor textureDescriptor(device);
|
||||
textureDescriptor.layout = pipelineLayout;
|
||||
textureDescriptor.cVertexStage.module = vsModule;
|
||||
textureDescriptor.cFragmentStage.module = fsModule;
|
||||
textureDescriptor.cColorAttachments[0].format =
|
||||
renderPass.colorFormat;
|
||||
|
||||
dawn::RenderPipeline pipeline = device.CreateRenderPipeline(&textureDescriptor);
|
||||
|
||||
struct Data {
|
||||
float transform[8];
|
||||
char padding[256 - 8 * sizeof(float)];
|
||||
|
@ -198,13 +201,15 @@ TEST_P(BindGroupTests, UBOSamplerAndTexture) {
|
|||
);
|
||||
dawn::PipelineLayout pipelineLayout = utils::MakeBasicPipelineLayout(device, &bgl);
|
||||
|
||||
dawn::RenderPipeline pipeline = device.CreateRenderPipelineBuilder()
|
||||
.SetColorAttachmentFormat(0, renderPass.colorFormat)
|
||||
.SetLayout(pipelineLayout)
|
||||
.SetPrimitiveTopology(dawn::PrimitiveTopology::TriangleList)
|
||||
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
|
||||
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
|
||||
.GetResult();
|
||||
utils::ComboRenderPipelineDescriptor pipelineDescriptor(device);
|
||||
pipelineDescriptor.layout = pipelineLayout;
|
||||
pipelineDescriptor.cVertexStage.module = vsModule;
|
||||
pipelineDescriptor.cFragmentStage.module = fsModule;
|
||||
pipelineDescriptor.cColorAttachments[0].format =
|
||||
renderPass.colorFormat;
|
||||
|
||||
dawn::RenderPipeline pipeline = device.CreateRenderPipeline(&pipelineDescriptor);
|
||||
|
||||
constexpr float dummy = 0.0f;
|
||||
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);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "common/Assert.h"
|
||||
#include "common/Constants.h"
|
||||
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "utils/DawnHelpers.h"
|
||||
|
||||
constexpr static unsigned int kRTSize = 64;
|
||||
|
@ -66,20 +67,24 @@ class BlendStateTest : public DawnTest {
|
|||
}
|
||||
)");
|
||||
|
||||
basePipeline = device.CreateRenderPipelineBuilder()
|
||||
.SetColorAttachmentFormat(0, renderPass.colorFormat)
|
||||
.SetLayout(pipelineLayout)
|
||||
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
|
||||
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
|
||||
.GetResult();
|
||||
utils::ComboRenderPipelineDescriptor baseDescriptor(device);
|
||||
baseDescriptor.layout = pipelineLayout;
|
||||
baseDescriptor.cVertexStage.module = vsModule;
|
||||
baseDescriptor.cFragmentStage.module = fsModule;
|
||||
baseDescriptor.cColorAttachments[0].format =
|
||||
renderPass.colorFormat;
|
||||
|
||||
testPipeline = device.CreateRenderPipelineBuilder()
|
||||
.SetColorAttachmentFormat(0, renderPass.colorFormat)
|
||||
.SetLayout(pipelineLayout)
|
||||
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
|
||||
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
|
||||
.SetColorAttachmentBlendState(0, blendState)
|
||||
.GetResult();
|
||||
basePipeline = device.CreateRenderPipeline(&baseDescriptor);
|
||||
|
||||
utils::ComboRenderPipelineDescriptor testDescriptor(device);
|
||||
testDescriptor.layout = pipelineLayout;
|
||||
testDescriptor.cVertexStage.module = vsModule;
|
||||
testDescriptor.cFragmentStage.module = fsModule;
|
||||
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
|
||||
|
@ -766,7 +771,7 @@ TEST_P(BlendStateTest, IndependentBlendState) {
|
|||
blend3.srcFactor = dawn::BlendFactor::One;
|
||||
blend3.dstFactor = dawn::BlendFactor::One;
|
||||
|
||||
std::array<dawn::BlendState, 3> blendStates = { {
|
||||
std::array<dawn::BlendState, 4> blendStates = { {
|
||||
device.CreateBlendStateBuilder()
|
||||
.SetBlendEnabled(true)
|
||||
.SetColorBlend(&blend1)
|
||||
|
@ -777,6 +782,7 @@ TEST_P(BlendStateTest, IndependentBlendState) {
|
|||
.SetColorBlend(&blend2)
|
||||
.SetAlphaBlend(&blend2)
|
||||
.GetResult(),
|
||||
device.CreateBlendStateBuilder().GetResult(),
|
||||
device.CreateBlendStateBuilder()
|
||||
.SetBlendEnabled(true)
|
||||
.SetColorBlend(&blend3)
|
||||
|
@ -784,30 +790,24 @@ TEST_P(BlendStateTest, IndependentBlendState) {
|
|||
.GetResult(),
|
||||
} };
|
||||
|
||||
basePipeline = device.CreateRenderPipelineBuilder()
|
||||
.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")
|
||||
.GetResult();
|
||||
utils::ComboRenderPipelineDescriptor baseDescriptor(device);
|
||||
baseDescriptor.layout = pipelineLayout;
|
||||
baseDescriptor.cVertexStage.module = vsModule;
|
||||
baseDescriptor.cFragmentStage.module = fsModule;
|
||||
baseDescriptor.cAttachmentsState.numColorAttachments = 4;
|
||||
baseDescriptor.numBlendStates = 4;
|
||||
|
||||
testPipeline = device.CreateRenderPipelineBuilder()
|
||||
.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();
|
||||
basePipeline = device.CreateRenderPipeline(&baseDescriptor);
|
||||
|
||||
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) {
|
||||
RGBA8 base = kColors[((c + 31) * 29) % kColors.size()];
|
||||
|
@ -870,20 +870,24 @@ TEST_P(BlendStateTest, DefaultBlendColor) {
|
|||
}
|
||||
)");
|
||||
|
||||
basePipeline = device.CreateRenderPipelineBuilder()
|
||||
.SetColorAttachmentFormat(0, renderPass.colorFormat)
|
||||
.SetLayout(pipelineLayout)
|
||||
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
|
||||
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
|
||||
.GetResult();
|
||||
utils::ComboRenderPipelineDescriptor baseDescriptor(device);
|
||||
baseDescriptor.layout = pipelineLayout;
|
||||
baseDescriptor.cVertexStage.module = vsModule;
|
||||
baseDescriptor.cFragmentStage.module = fsModule;
|
||||
baseDescriptor.cColorAttachments[0].format =
|
||||
renderPass.colorFormat;
|
||||
|
||||
testPipeline = device.CreateRenderPipelineBuilder()
|
||||
.SetColorAttachmentFormat(0, renderPass.colorFormat)
|
||||
.SetLayout(pipelineLayout)
|
||||
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
|
||||
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
|
||||
.SetColorAttachmentBlendState(0, blendState)
|
||||
.GetResult();
|
||||
basePipeline = device.CreateRenderPipeline(&baseDescriptor);
|
||||
|
||||
utils::ComboRenderPipelineDescriptor testDescriptor(device);
|
||||
testDescriptor.layout = pipelineLayout;
|
||||
testDescriptor.cVertexStage.module = vsModule;
|
||||
testDescriptor.cFragmentStage.module = fsModule;
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "tests/DawnTest.h"
|
||||
|
||||
#include "common/Assert.h"
|
||||
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "utils/DawnHelpers.h"
|
||||
|
||||
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)}});
|
||||
|
||||
// Create a pipeline for the triangles with the test spec's depth stencil state
|
||||
dawn::RenderPipeline pipeline = device.CreateRenderPipelineBuilder()
|
||||
.SetColorAttachmentFormat(0, dawn::TextureFormat::R8G8B8A8Unorm)
|
||||
.SetDepthStencilAttachmentFormat(dawn::TextureFormat::D32FloatS8Uint)
|
||||
.SetLayout(pipelineLayout)
|
||||
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
|
||||
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
|
||||
.SetDepthStencilState(test.depthStencilState)
|
||||
.GetResult();
|
||||
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.layout = pipelineLayout;
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
descriptor.cFragmentStage.module = fsModule;
|
||||
descriptor.cAttachmentsState.hasDepthStencilAttachment = true;
|
||||
descriptor.cDepthStencilAttachment.format = dawn::TextureFormat::D32FloatS8Uint;
|
||||
descriptor.depthStencilState = test.depthStencilState;
|
||||
|
||||
dawn::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
|
||||
|
||||
pass.SetRenderPipeline(pipeline);
|
||||
pass.SetStencilReference(test.stencil); // Set the stencil reference
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "tests/DawnTest.h"
|
||||
|
||||
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "utils/DawnHelpers.h"
|
||||
|
||||
constexpr uint32_t kRTSize = 4;
|
||||
|
@ -46,14 +47,16 @@ class DrawElementsTest : public DawnTest {
|
|||
})"
|
||||
);
|
||||
|
||||
pipeline = device.CreateRenderPipelineBuilder()
|
||||
.SetColorAttachmentFormat(0, renderPass.colorFormat)
|
||||
.SetPrimitiveTopology(dawn::PrimitiveTopology::TriangleStrip)
|
||||
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
|
||||
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
|
||||
.SetIndexFormat(dawn::IndexFormat::Uint32)
|
||||
.SetInputState(inputState)
|
||||
.GetResult();
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
descriptor.cFragmentStage.module = fsModule;
|
||||
descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleStrip;
|
||||
descriptor.indexFormat = dawn::IndexFormat::Uint32;
|
||||
descriptor.inputState = inputState;
|
||||
descriptor.cColorAttachments[0].format =
|
||||
renderPass.colorFormat;
|
||||
|
||||
pipeline = device.CreateRenderPipeline(&descriptor);
|
||||
|
||||
vertexBuffer = utils::CreateBufferFromData<float>(device, dawn::BufferUsageBit::Vertex, {
|
||||
-1.0f, -1.0f, 0.0f, 1.0f,
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "tests/DawnTest.h"
|
||||
|
||||
#include "common/Assert.h"
|
||||
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "utils/DawnHelpers.h"
|
||||
|
||||
constexpr uint32_t kRTSize = 400;
|
||||
|
@ -51,14 +52,16 @@ class IndexFormatTest : public DawnTest {
|
|||
})"
|
||||
);
|
||||
|
||||
return device.CreateRenderPipelineBuilder()
|
||||
.SetColorAttachmentFormat(0, renderPass.colorFormat)
|
||||
.SetPrimitiveTopology(dawn::PrimitiveTopology::TriangleStrip)
|
||||
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
|
||||
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
|
||||
.SetIndexFormat(format)
|
||||
.SetInputState(inputState)
|
||||
.GetResult();
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
descriptor.cFragmentStage.module = fsModule;
|
||||
descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleStrip;
|
||||
descriptor.indexFormat = format;
|
||||
descriptor.inputState = inputState;
|
||||
descriptor.cColorAttachments[0].format =
|
||||
renderPass.colorFormat;
|
||||
|
||||
return device.CreateRenderPipeline(&descriptor);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "tests/DawnTest.h"
|
||||
|
||||
#include "common/Assert.h"
|
||||
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "utils/DawnHelpers.h"
|
||||
|
||||
using dawn::InputStepMode;
|
||||
|
@ -120,12 +121,14 @@ class InputStateTest : public DawnTest {
|
|||
})"
|
||||
);
|
||||
|
||||
return device.CreateRenderPipelineBuilder()
|
||||
.SetColorAttachmentFormat(0, renderPass.colorFormat)
|
||||
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
|
||||
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
|
||||
.SetInputState(inputState)
|
||||
.GetResult();
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
descriptor.cFragmentStage.module = fsModule;
|
||||
descriptor.inputState = inputState;
|
||||
descriptor.cColorAttachments[0].format =
|
||||
renderPass.colorFormat;
|
||||
|
||||
return device.CreateRenderPipeline(&descriptor);
|
||||
}
|
||||
|
||||
struct InputSpec {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "tests/DawnTest.h"
|
||||
|
||||
#include "common/Assert.h"
|
||||
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "utils/DawnHelpers.h"
|
||||
|
||||
// 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
|
||||
void DoTest(dawn::PrimitiveTopology primitiveTopology, const std::vector<LocationSpec> &locationSpecs) {
|
||||
dawn::RenderPipeline pipeline = device.CreateRenderPipelineBuilder()
|
||||
.SetColorAttachmentFormat(0, renderPass.colorFormat)
|
||||
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
|
||||
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
|
||||
.SetInputState(inputState)
|
||||
.SetPrimitiveTopology(primitiveTopology)
|
||||
.GetResult();
|
||||
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
descriptor.cFragmentStage.module = fsModule;
|
||||
descriptor.primitiveTopology = primitiveTopology;
|
||||
descriptor.inputState = inputState;
|
||||
descriptor.cColorAttachments[0].format =
|
||||
renderPass.colorFormat;
|
||||
|
||||
dawn::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
|
||||
|
||||
static const uint32_t zeroOffset = 0;
|
||||
dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder();
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "common/Assert.h"
|
||||
#include "common/Constants.h"
|
||||
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "utils/DawnHelpers.h"
|
||||
|
||||
#include <array>
|
||||
|
@ -189,20 +190,18 @@ class PushConstantTest: public DawnTest {
|
|||
blend.srcFactor = dawn::BlendFactor::One;
|
||||
blend.dstFactor = dawn::BlendFactor::One;
|
||||
|
||||
dawn::BlendState blendState = device.CreateBlendStateBuilder()
|
||||
.SetBlendEnabled(true)
|
||||
.SetColorBlend(&blend)
|
||||
.SetAlphaBlend(&blend)
|
||||
.GetResult();
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.layout = layout;
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
descriptor.cFragmentStage.module = fsModule;
|
||||
descriptor.primitiveTopology = dawn::PrimitiveTopology::PointList;
|
||||
descriptor.cBlendStates[0] = device.CreateBlendStateBuilder()
|
||||
.SetBlendEnabled(true)
|
||||
.SetColorBlend(&blend)
|
||||
.SetAlphaBlend(&blend)
|
||||
.GetResult();
|
||||
|
||||
return device.CreateRenderPipelineBuilder()
|
||||
.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();
|
||||
return device.CreateRenderPipeline(&descriptor);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "tests/DawnTest.h"
|
||||
|
||||
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "utils/DawnHelpers.h"
|
||||
|
||||
#include <array>
|
||||
|
@ -23,28 +24,29 @@ constexpr static unsigned int kRTSize = 16;
|
|||
class DrawQuad {
|
||||
public:
|
||||
DrawQuad() {}
|
||||
DrawQuad(dawn::Device* device, const char* vsSource, const char* fsSource)
|
||||
DrawQuad(dawn::Device device, const char* vsSource, const char* fsSource)
|
||||
: device(device) {
|
||||
vsModule = utils::CreateShaderModule(*device, dawn::ShaderStage::Vertex, vsSource);
|
||||
fsModule = utils::CreateShaderModule(*device, dawn::ShaderStage::Fragment, fsSource);
|
||||
vsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, vsSource);
|
||||
fsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, fsSource);
|
||||
|
||||
pipelineLayout = utils::MakeBasicPipelineLayout(*device, nullptr);
|
||||
pipelineLayout = utils::MakeBasicPipelineLayout(device, nullptr);
|
||||
}
|
||||
|
||||
void Draw(dawn::RenderPassEncoder* pass) {
|
||||
auto renderPipeline = device->CreateRenderPipelineBuilder()
|
||||
.SetColorAttachmentFormat(0, dawn::TextureFormat::R8G8B8A8Unorm)
|
||||
.SetLayout(pipelineLayout)
|
||||
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
|
||||
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
|
||||
.GetResult();
|
||||
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.layout = pipelineLayout;
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
descriptor.cFragmentStage.module = fsModule;
|
||||
|
||||
auto renderPipeline = device.CreateRenderPipeline(&descriptor);
|
||||
|
||||
pass->SetRenderPipeline(renderPipeline);
|
||||
pass->Draw(6, 1, 0, 0);
|
||||
}
|
||||
|
||||
private:
|
||||
dawn::Device* device = nullptr;
|
||||
dawn::Device device;
|
||||
dawn::ShaderModule vsModule = {};
|
||||
dawn::ShaderModule fsModule = {};
|
||||
dawn::PipelineLayout pipelineLayout = {};
|
||||
|
@ -94,7 +96,7 @@ class RenderPassLoadOpTests : public DawnTest {
|
|||
color = vec4(0.f, 0.f, 1.f, 1.f);
|
||||
}
|
||||
)";
|
||||
blueQuad = DrawQuad(&device, vsSource, fsSource);
|
||||
blueQuad = DrawQuad(device, vsSource, fsSource);
|
||||
}
|
||||
|
||||
dawn::Texture renderTarget;
|
||||
|
|
|
@ -12,13 +12,13 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
|
||||
#include "tests/DawnTest.h"
|
||||
|
||||
#include "common/Assert.h"
|
||||
#include "common/Constants.h"
|
||||
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "utils/DawnHelpers.h"
|
||||
|
||||
constexpr static unsigned int kRTSize = 64;
|
||||
|
@ -73,12 +73,14 @@ protected:
|
|||
}
|
||||
)");
|
||||
|
||||
mPipeline = device.CreateRenderPipelineBuilder()
|
||||
.SetColorAttachmentFormat(0, mRenderPass.colorFormat)
|
||||
.SetLayout(pipelineLayout)
|
||||
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
|
||||
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
|
||||
.GetResult();
|
||||
utils::ComboRenderPipelineDescriptor pipelineDescriptor(device);
|
||||
pipelineDescriptor.layout = pipelineLayout;
|
||||
pipelineDescriptor.cVertexStage.module = vsModule;
|
||||
pipelineDescriptor.cFragmentStage.module = fsModule;
|
||||
pipelineDescriptor.cColorAttachments[0].format =
|
||||
mRenderPass.colorFormat;
|
||||
|
||||
mPipeline = device.CreateRenderPipeline(&pipelineDescriptor);
|
||||
|
||||
dawn::TextureDescriptor descriptor;
|
||||
descriptor.dimension = dawn::TextureDimension::e2D;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "tests/DawnTest.h"
|
||||
|
||||
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "utils/DawnHelpers.h"
|
||||
|
||||
class ScissorTest: public DawnTest {
|
||||
|
@ -36,13 +37,13 @@ class ScissorTest: public DawnTest {
|
|||
fragColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
})");
|
||||
|
||||
dawn::RenderPipeline pipeline = device.CreateRenderPipelineBuilder()
|
||||
.SetColorAttachmentFormat(0, format)
|
||||
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
|
||||
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
|
||||
.GetResult();
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
descriptor.cFragmentStage.module = fsModule;
|
||||
descriptor.cColorAttachments[0].format =
|
||||
format;
|
||||
|
||||
return pipeline;
|
||||
return device.CreateRenderPipeline(&descriptor);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "common/Assert.h"
|
||||
#include "common/Constants.h"
|
||||
#include "common/Math.h"
|
||||
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "utils/DawnHelpers.h"
|
||||
|
||||
#include <array>
|
||||
|
@ -163,12 +164,14 @@ protected:
|
|||
dawn::ShaderModule fsModule =
|
||||
utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, fragmentShader);
|
||||
|
||||
dawn::RenderPipeline pipeline = device.CreateRenderPipelineBuilder()
|
||||
.SetColorAttachmentFormat(0, mRenderPass.colorFormat)
|
||||
.SetLayout(mPipelineLayout)
|
||||
.SetStage(dawn::ShaderStage::Vertex, mVSModule, "main")
|
||||
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
|
||||
.GetResult();
|
||||
utils::ComboRenderPipelineDescriptor textureDescriptor(device);
|
||||
textureDescriptor.cVertexStage.module = mVSModule;
|
||||
textureDescriptor.cFragmentStage.module = fsModule;
|
||||
textureDescriptor.layout = mPipelineLayout;
|
||||
textureDescriptor.cColorAttachments[0].format =
|
||||
mRenderPass.colorFormat;
|
||||
|
||||
dawn::RenderPipeline pipeline = device.CreateRenderPipeline(&textureDescriptor);
|
||||
|
||||
dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder();
|
||||
{
|
||||
|
@ -502,11 +505,13 @@ class TextureViewRenderingTest : public DawnTest {
|
|||
dawn::ShaderModule oneColorFsModule =
|
||||
utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, oneColorFragmentShader);
|
||||
|
||||
dawn::RenderPipeline oneColorPipeline = device.CreateRenderPipelineBuilder()
|
||||
.SetColorAttachmentFormat(0, kDefaultFormat)
|
||||
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
|
||||
.SetStage(dawn::ShaderStage::Fragment, oneColorFsModule, "main")
|
||||
.GetResult();
|
||||
utils::ComboRenderPipelineDescriptor pipelineDescriptor(device);
|
||||
pipelineDescriptor.cVertexStage.module = vsModule;
|
||||
pipelineDescriptor.cFragmentStage.module = oneColorFsModule;
|
||||
pipelineDescriptor.cColorAttachments[0].format = kDefaultFormat;
|
||||
|
||||
dawn::RenderPipeline oneColorPipeline = device.CreateRenderPipeline(&pipelineDescriptor);
|
||||
|
||||
dawn::CommandBufferBuilder commandBufferBuilder = device.CreateCommandBufferBuilder();
|
||||
{
|
||||
dawn::RenderPassEncoder pass =
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "tests/DawnTest.h"
|
||||
|
||||
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "utils/DawnHelpers.h"
|
||||
|
||||
class ViewportOrientationTests : public DawnTest {};
|
||||
|
@ -35,12 +36,14 @@ TEST_P(ViewportOrientationTests, OriginAt0x0) {
|
|||
fragColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
})");
|
||||
|
||||
dawn::RenderPipeline pipeline = device.CreateRenderPipelineBuilder()
|
||||
.SetColorAttachmentFormat(0, renderPass.colorFormat)
|
||||
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
|
||||
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
|
||||
.SetPrimitiveTopology(dawn::PrimitiveTopology::PointList)
|
||||
.GetResult();
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
descriptor.cFragmentStage.module = fsModule;
|
||||
descriptor.primitiveTopology = dawn::PrimitiveTopology::PointList;
|
||||
descriptor.cColorAttachments[0].format =
|
||||
renderPass.colorFormat;
|
||||
|
||||
dawn::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
|
||||
|
||||
dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder();
|
||||
{
|
||||
|
|
|
@ -318,24 +318,99 @@ TEST_F(WireTests, ValueArrayArgument) {
|
|||
// Test that the wire is able to send C strings
|
||||
TEST_F(WireTests, CStringArgument) {
|
||||
// Create shader module
|
||||
dawnShaderModuleDescriptor descriptor;
|
||||
descriptor.nextInChain = nullptr;
|
||||
descriptor.codeSize = 0;
|
||||
dawnShaderModule shaderModule = dawnDeviceCreateShaderModule(device, &descriptor);
|
||||
|
||||
dawnShaderModule apiShaderModule = api.GetNewShaderModule();
|
||||
dawnShaderModuleDescriptor vertexDescriptor;
|
||||
vertexDescriptor.nextInChain = nullptr;
|
||||
vertexDescriptor.codeSize = 0;
|
||||
dawnShaderModule vsModule = dawnDeviceCreateShaderModule(device, &vertexDescriptor);
|
||||
dawnShaderModule apiVsModule = api.GetNewShaderModule();
|
||||
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
|
||||
dawnRenderPipelineBuilder pipelineBuilder = dawnDeviceCreateRenderPipelineBuilder(device);
|
||||
dawnRenderPipelineBuilderSetStage(pipelineBuilder, DAWN_SHADER_STAGE_FRAGMENT, shaderModule, "my entry point");
|
||||
dawnRenderPipelineDescriptor pipelineDescriptor;
|
||||
pipelineDescriptor.nextInChain = nullptr;
|
||||
|
||||
dawnRenderPipelineBuilder apiPipelineBuilder = api.GetNewRenderPipelineBuilder();
|
||||
EXPECT_CALL(api, DeviceCreateRenderPipelineBuilder(apiDevice))
|
||||
.WillOnce(Return(apiPipelineBuilder));
|
||||
dawnPipelineStageDescriptor vertexStage;
|
||||
vertexStage.nextInChain = nullptr;
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -14,15 +14,12 @@
|
|||
|
||||
#include "tests/unittests/validation/ValidationTest.h"
|
||||
|
||||
#include "utils/ComboRenderPipelineDescriptor.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 {
|
||||
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();
|
||||
|
||||
dawn::ShaderModule vsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, vertexSource.c_str());
|
||||
|
@ -34,18 +31,18 @@ class InputStateTest : public ValidationTest {
|
|||
}
|
||||
)");
|
||||
|
||||
dawn::RenderPipelineBuilder builder;
|
||||
if (success) {
|
||||
builder = AssertWillBeSuccess(device.CreateRenderPipelineBuilder());
|
||||
} else {
|
||||
builder = AssertWillBeError(device.CreateRenderPipelineBuilder());
|
||||
}
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
descriptor.cFragmentStage.module = fsModule;
|
||||
descriptor.inputState = inputState;
|
||||
descriptor.cColorAttachments[0].format =
|
||||
renderpassData.attachmentFormat;
|
||||
|
||||
return builder.SetColorAttachmentFormat(0, renderpassData.attachmentFormat)
|
||||
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
|
||||
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
|
||||
.SetInputState(inputState)
|
||||
.GetResult();
|
||||
if (!success) {
|
||||
ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor));
|
||||
} else {
|
||||
device.CreateRenderPipeline(&descriptor);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "tests/unittests/validation/ValidationTest.h"
|
||||
|
||||
#include "common/Constants.h"
|
||||
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "utils/DawnHelpers.h"
|
||||
|
||||
class RenderPipelineValidationTest : public ValidationTest {
|
||||
|
@ -24,12 +25,6 @@ class RenderPipelineValidationTest : public ValidationTest {
|
|||
|
||||
renderpass = CreateSimpleRenderPass();
|
||||
|
||||
pipelineLayout = utils::MakeBasicPipelineLayout(device, nullptr);
|
||||
|
||||
inputState = device.CreateInputStateBuilder().GetResult();
|
||||
|
||||
blendState = device.CreateBlendStateBuilder().GetResult();
|
||||
|
||||
vsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, R"(
|
||||
#version 450
|
||||
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::ShaderModule vsModule;
|
||||
dawn::ShaderModule fsModule;
|
||||
dawn::InputState inputState;
|
||||
dawn::BlendState blendState;
|
||||
dawn::PipelineLayout pipelineLayout;
|
||||
};
|
||||
|
||||
// Test cases where creation should succeed
|
||||
TEST_F(RenderPipelineValidationTest, CreationSuccess) {
|
||||
AddDefaultStates(AssertWillBeSuccess(device.CreateRenderPipelineBuilder()))
|
||||
.GetResult();
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
descriptor.cFragmentStage.module = fsModule;
|
||||
|
||||
AddDefaultStates(AssertWillBeSuccess(device.CreateRenderPipelineBuilder()))
|
||||
.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();
|
||||
}
|
||||
device.CreateRenderPipeline(&descriptor);
|
||||
}
|
||||
|
||||
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
|
||||
AssertWillBeSuccess(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(0, blendState)
|
||||
.GetResult();
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
descriptor.cFragmentStage.module = fsModule;
|
||||
descriptor.numBlendStates = 1;
|
||||
|
||||
// This fails because attachment 1 is not one of the color attachments
|
||||
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();
|
||||
device.CreateRenderPipeline(&descriptor);
|
||||
}
|
||||
|
||||
// Fails because color attachment is out of bounds
|
||||
{
|
||||
AddDefaultStates(AssertWillBeError(device.CreateRenderPipelineBuilder()))
|
||||
.SetColorAttachmentBlendState(kMaxColorAttachments, blendState)
|
||||
.GetResult();
|
||||
{ // Fail because lack of blend states for color attachments
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
descriptor.cFragmentStage.module = fsModule;
|
||||
descriptor.numBlendStates = 0;
|
||||
|
||||
ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor));
|
||||
}
|
||||
|
||||
// Fails because color attachment blend state is set twice
|
||||
{
|
||||
AddDefaultStates(AssertWillBeError(device.CreateRenderPipelineBuilder()))
|
||||
.SetColorAttachmentBlendState(0, blendState)
|
||||
.SetColorAttachmentBlendState(0, blendState)
|
||||
.GetResult();
|
||||
// Fail because set blend states for empty color attachments
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "tests/unittests/validation/ValidationTest.h"
|
||||
|
||||
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||
#include "utils/DawnHelpers.h"
|
||||
|
||||
class VertexBufferValidationTest : public ValidationTest {
|
||||
|
@ -78,12 +79,13 @@ class VertexBufferValidationTest : public ValidationTest {
|
|||
}
|
||||
|
||||
dawn::RenderPipeline MakeRenderPipeline(const dawn::ShaderModule& vsModule, const dawn::InputState& inputState) {
|
||||
return device.CreateRenderPipelineBuilder()
|
||||
.SetColorAttachmentFormat(0, dawn::TextureFormat::R8G8B8A8Unorm)
|
||||
.SetStage(dawn::ShaderStage::Vertex, vsModule, "main")
|
||||
.SetStage(dawn::ShaderStage::Fragment, fsModule, "main")
|
||||
.SetInputState(inputState)
|
||||
.GetResult();
|
||||
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.cVertexStage.module = vsModule;
|
||||
descriptor.cFragmentStage.module = fsModule;
|
||||
descriptor.inputState = inputState;
|
||||
|
||||
return device.CreateRenderPipeline(&descriptor);
|
||||
}
|
||||
|
||||
dawn::RenderPassDescriptor renderpass;
|
||||
|
|
|
@ -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
|
|
@ -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_
|
Loading…
Reference in New Issue