mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-18 17:35:30 +00:00
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:
committed by
Commit Bot service account
parent
07df605a2b
commit
a49242766a
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user