diff --git a/BUILD.gn b/BUILD.gn index ba97de5da9..c346ea7004 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -348,6 +348,8 @@ source_set("libdawn_native_sources") { "src/dawn_native/CommandBufferStateTracker.h", "src/dawn_native/Commands.cpp", "src/dawn_native/Commands.h", + "src/dawn_native/ComputePassEncoder.cpp", + "src/dawn_native/ComputePassEncoder.h", "src/dawn_native/ComputePipeline.cpp", "src/dawn_native/ComputePipeline.h", "src/dawn_native/DawnNative.cpp", @@ -369,12 +371,16 @@ source_set("libdawn_native_sources") { "src/dawn_native/Pipeline.h", "src/dawn_native/PipelineLayout.cpp", "src/dawn_native/PipelineLayout.h", + "src/dawn_native/ProgrammablePassEncoder.cpp", + "src/dawn_native/ProgrammablePassEncoder.h", "src/dawn_native/Queue.cpp", "src/dawn_native/Queue.h", "src/dawn_native/RefCounted.cpp", "src/dawn_native/RefCounted.h", "src/dawn_native/RenderPassDescriptor.cpp", "src/dawn_native/RenderPassDescriptor.h", + "src/dawn_native/RenderPassEncoder.cpp", + "src/dawn_native/RenderPassEncoder.h", "src/dawn_native/RenderPipeline.cpp", "src/dawn_native/RenderPipeline.h", "src/dawn_native/Sampler.cpp", diff --git a/dawn.json b/dawn.json index 94a77cd061..ee23549051 100644 --- a/dawn.json +++ b/dawn.json @@ -319,13 +319,15 @@ "returns": "command buffer" }, { - "name": "begin compute pass" + "name": "begin compute pass", + "returns": "compute pass encoder" }, { "name": "begin render pass", "args": [ {"name": "info", "type": "render pass descriptor"} - ] + ], + "returns": "render pass encoder" }, { "name": "copy buffer to buffer", @@ -385,66 +387,30 @@ "Add these arguments too", {"name": "image height", "type": "uint32_t"} ] - }, + } + ] + }, + "compare function": { + "category": "enum", + "values": [ + {"value": 0, "name": "never"}, + {"value": 1, "name": "less"}, + {"value": 2, "name": "less equal"}, + {"value": 3, "name": "greater"}, + {"value": 4, "name": "greater equal"}, + {"value": 5, "name": "equal"}, + {"value": 6, "name": "not equal"}, + {"value": 7, "name": "always"} + ] + }, + "compute pass encoder": { + "category": "object", + "methods": [ { - "name": "dispatch", + "name": "set compute pipeline", + "TODO": "This is called setPipeline in the WebGPU IDL", "args": [ - {"name": "x", "type": "uint32_t"}, - {"name": "y", "type": "uint32_t"}, - {"name": "z", "type": "uint32_t"} - ] - }, - { - "name": "draw arrays", - "args": [ - {"name": "vertex count", "type": "uint32_t"}, - {"name": "instance count", "type": "uint32_t"}, - {"name": "first vertex", "type": "uint32_t"}, - {"name": "first instance", "type": "uint32_t"} - ] - }, - { - "name": "draw elements", - "args": [ - {"name": "index count", "type": "uint32_t"}, - {"name": "instance count", "type": "uint32_t"}, - {"name": "first index", "type": "uint32_t"}, - {"name": "first instance", "type": "uint32_t"} - ] - }, - { - "name": "end compute pass" - }, - { - "name": "end render pass" - }, - { - "name": "set stencil reference", - "args": [ - {"name": "reference", "type": "uint32_t"} - ] - }, - { - "name": "set blend color", - "args": [ - {"name": "r", "type": "float"}, - {"name": "g", "type": "float"}, - {"name": "b", "type": "float"}, - {"name": "a", "type": "float"} - ] - }, - { - "name": "set bind group", - "args": [ - {"name": "group index", "type": "uint32_t"}, - {"name": "group", "type": "bind group"} - ] - }, - { - "name": "set index buffer", - "args": [ - {"name": "buffer", "type": "buffer"}, - {"name": "offset", "type": "uint32_t"} + {"name": "pipeline", "type": "compute pipeline"} ] }, { @@ -461,50 +427,26 @@ ] }, { - "name": "set compute pipeline", + "name": "set bind group", "args": [ - {"name": "pipeline", "type": "compute pipeline"} + {"name": "group index", "type": "uint32_t"}, + {"name": "group", "type": "bind group"} ] }, { - "name": "set render pipeline", - "args": [ - {"name": "pipeline", "type": "render pipeline"} - ] - }, - { - "name": "set scissor rect", + "name": "dispatch", "args": [ {"name": "x", "type": "uint32_t"}, {"name": "y", "type": "uint32_t"}, - {"name": "width", "type": "uint32_t"}, - {"name": "height", "type": "uint32_t"} + {"name": "z", "type": "uint32_t"} ] }, { - "name": "set vertex buffers", - "args": [ - {"name": "start slot", "type": "uint32_t"}, - {"name": "count", "type": "uint32_t"}, - {"name": "buffers", "type": "buffer", "annotation": "const*", "length": "count"}, - {"name": "offsets", "type": "uint32_t", "annotation": "const*", "length": "count"} - ] + "name": "end pass", + "TODO": "This returns the top-level encoder in the WebGPU IDL" } ] }, - "compare function": { - "category": "enum", - "values": [ - {"value": 0, "name": "never"}, - {"value": 1, "name": "less"}, - {"value": 2, "name": "less equal"}, - {"value": 3, "name": "greater"}, - {"value": 4, "name": "greater equal"}, - {"value": 5, "name": "equal"}, - {"value": 6, "name": "not equal"}, - {"value": 7, "name": "always"} - ] - }, "compute pipeline": { "category": "object" }, @@ -822,6 +764,100 @@ "render pass descriptor": { "category": "object" }, + "render pass encoder": { + "category": "object", + "methods": [ + { + "name": "set render pipeline", + "TODO": "This is called setPipeline in the WebGPU IDL", + "args": [ + {"name": "pipeline", "type": "render pipeline"} + ] + }, + { + "name": "set push constants", + "TODO": [ + "data should be void*", + "TODO Vulkan has an additional stage mask" + ], + "args": [ + {"name": "stages", "type": "shader stage bit"}, + {"name": "offset", "type": "uint32_t"}, + {"name": "count", "type": "uint32_t"}, + {"name": "data", "type": "uint32_t", "annotation": "const*", "length": "count"} + ] + }, + { + "name": "set bind group", + "args": [ + {"name": "group index", "type": "uint32_t"}, + {"name": "group", "type": "bind group"} + ] + }, + { + "name": "draw arrays", + "args": [ + {"name": "vertex count", "type": "uint32_t"}, + {"name": "instance count", "type": "uint32_t"}, + {"name": "first vertex", "type": "uint32_t"}, + {"name": "first instance", "type": "uint32_t"} + ] + }, + { + "name": "draw elements", + "args": [ + {"name": "index count", "type": "uint32_t"}, + {"name": "instance count", "type": "uint32_t"}, + {"name": "first index", "type": "uint32_t"}, + {"name": "first instance", "type": "uint32_t"} + ] + }, + { + "name": "set stencil reference", + "args": [ + {"name": "reference", "type": "uint32_t"} + ] + }, + { + "name": "set blend color", + "args": [ + {"name": "r", "type": "float"}, + {"name": "g", "type": "float"}, + {"name": "b", "type": "float"}, + {"name": "a", "type": "float"} + ] + }, + { + "name": "set scissor rect", + "args": [ + {"name": "x", "type": "uint32_t"}, + {"name": "y", "type": "uint32_t"}, + {"name": "width", "type": "uint32_t"}, + {"name": "height", "type": "uint32_t"} + ] + }, + { + "name": "set vertex buffers", + "args": [ + {"name": "start slot", "type": "uint32_t"}, + {"name": "count", "type": "uint32_t"}, + {"name": "buffers", "type": "buffer", "annotation": "const*", "length": "count"}, + {"name": "offsets", "type": "uint32_t", "annotation": "const*", "length": "count"} + ] + }, + { + "name": "set index buffer", + "args": [ + {"name": "buffer", "type": "buffer"}, + {"name": "offset", "type": "uint32_t"} + ] + }, + { + "name": "end pass", + "TODO": "This returns the top-level encoder in the WebGPU IDL" + } + ] + }, "render pipeline": { "category": "object" }, diff --git a/examples/Animometer.cpp b/examples/Animometer.cpp index ccbcb942e2..9e0eff9073 100644 --- a/examples/Animometer.cpp +++ b/examples/Animometer.cpp @@ -137,24 +137,22 @@ void frame() { size_t i = 0; - dawn::CommandBuffer commands; + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); { - dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPass) - .SetRenderPipeline(pipeline) - .Clone(); + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass); + pass.SetRenderPipeline(pipeline); for (int k = 0; k < 10000; k++) { shaderData[i].time = f / 60.0f; - builder.SetPushConstants(dawn::ShaderStageBit::Vertex, 0, 6, reinterpret_cast(&shaderData[i])) - .DrawArrays(3, 1, 0, 0); + pass.SetPushConstants(dawn::ShaderStageBit::Vertex, 0, 6, reinterpret_cast(&shaderData[i])); + pass.DrawArrays(3, 1, 0, 0); i++; } - builder.EndRenderPass(); - commands = builder.GetResult(); + pass.EndPass(); } + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); swapchain.Present(backbuffer); DoFlush(); diff --git a/examples/CHelloTriangle.cpp b/examples/CHelloTriangle.cpp index 075b442083..1d87073d16 100644 --- a/examples/CHelloTriangle.cpp +++ b/examples/CHelloTriangle.cpp @@ -84,10 +84,13 @@ void frame() { dawnCommandBuffer commands; { dawnCommandBufferBuilder builder = dawnDeviceCreateCommandBufferBuilder(device); - dawnCommandBufferBuilderBeginRenderPass(builder, renderpassInfo); - dawnCommandBufferBuilderSetRenderPipeline(builder, pipeline); - dawnCommandBufferBuilderDrawArrays(builder, 3, 1, 0, 0); - dawnCommandBufferBuilderEndRenderPass(builder); + + dawnRenderPassEncoder pass = dawnCommandBufferBuilderBeginRenderPass(builder, renderpassInfo); + dawnRenderPassEncoderSetRenderPipeline(pass, pipeline); + dawnRenderPassEncoderDrawArrays(pass, 3, 1, 0, 0); + dawnRenderPassEncoderEndPass(pass); + dawnRenderPassEncoderRelease(pass); + commands = dawnCommandBufferBuilderGetResult(builder); dawnCommandBufferBuilderRelease(builder); } diff --git a/examples/ComputeBoids.cpp b/examples/ComputeBoids.cpp index 4a69710ba2..77b2ad8247 100644 --- a/examples/ComputeBoids.cpp +++ b/examples/ComputeBoids.cpp @@ -261,21 +261,26 @@ void initSim() { dawn::CommandBuffer createCommandBuffer(const dawn::RenderPassDescriptor& renderPass, size_t i) { static const uint32_t zeroOffsets[1] = {0}; auto& bufferDst = particleBuffers[(i + 1) % 2]; - return device.CreateCommandBufferBuilder() - .BeginComputePass() - .SetComputePipeline(updatePipeline) - .SetBindGroup(0, updateBGs[i]) - .Dispatch(kNumParticles, 1, 1) - .EndComputePass() + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); - .BeginRenderPass(renderPass) - .SetRenderPipeline(renderPipeline) - .SetVertexBuffers(0, 1, &bufferDst, zeroOffsets) - .SetVertexBuffers(1, 1, &modelBuffer, zeroOffsets) - .DrawArrays(3, kNumParticles, 0, 0) - .EndRenderPass() + { + dawn::ComputePassEncoder pass = builder.BeginComputePass(); + pass.SetComputePipeline(updatePipeline); + pass.SetBindGroup(0, updateBGs[i]); + pass.Dispatch(kNumParticles, 1, 1); + pass.EndPass(); + } - .GetResult(); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass); + pass.SetRenderPipeline(renderPipeline); + pass.SetVertexBuffers(0, 1, &bufferDst, zeroOffsets); + pass.SetVertexBuffers(1, 1, &modelBuffer, zeroOffsets); + pass.DrawArrays(3, kNumParticles, 0, 0); + pass.EndPass(); + } + + return builder.GetResult(); } void init() { diff --git a/examples/CppHelloTriangle.cpp b/examples/CppHelloTriangle.cpp index 3be8973968..c9aa88c9e4 100644 --- a/examples/CppHelloTriangle.cpp +++ b/examples/CppHelloTriangle.cpp @@ -151,16 +151,18 @@ void frame() { GetNextRenderPassDescriptor(device, swapchain, depthStencilView, &backbuffer, &renderPass); static const uint32_t vertexBufferOffsets[1] = {0}; - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPass) - .SetRenderPipeline(pipeline) - .SetBindGroup(0, bindGroup) - .SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets) - .SetIndexBuffer(indexBuffer, 0) - .DrawElements(3, 1, 0, 0) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass); + pass.SetRenderPipeline(pipeline); + pass.SetBindGroup(0, bindGroup); + pass.SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets); + pass.SetIndexBuffer(indexBuffer, 0); + pass.DrawElements(3, 1, 0, 0); + pass.EndPass(); + } + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); swapchain.Present(backbuffer); DoFlush(); diff --git a/examples/CubeReflection.cpp b/examples/CubeReflection.cpp index 75ed5d715b..5a5f658822 100644 --- a/examples/CubeReflection.cpp +++ b/examples/CubeReflection.cpp @@ -277,27 +277,30 @@ void frame() { dawn::RenderPassDescriptor renderPass; GetNextRenderPassDescriptor(device, swapchain, depthStencilView, &backbuffer, &renderPass); - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPass) - .SetRenderPipeline(pipeline) - .SetBindGroup(0, bindGroup[0]) - .SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets) - .SetIndexBuffer(indexBuffer, 0) - .DrawElements(36, 1, 0, 0) + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass); + pass.SetRenderPipeline(pipeline); + pass.SetBindGroup(0, bindGroup[0]); + pass.SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets); + pass.SetIndexBuffer(indexBuffer, 0); + pass.DrawElements(36, 1, 0, 0); - .SetStencilReference(0x1) - .SetRenderPipeline(planePipeline) - .SetBindGroup(0, bindGroup[0]) - .SetVertexBuffers(0, 1, &planeBuffer, vertexBufferOffsets) - .DrawElements(6, 1, 0, 0) + pass.SetStencilReference(0x1); + pass.SetRenderPipeline(planePipeline); + pass.SetBindGroup(0, bindGroup[0]); + pass.SetVertexBuffers(0, 1, &planeBuffer, vertexBufferOffsets); + pass.DrawElements(6, 1, 0, 0); - .SetRenderPipeline(reflectionPipeline) - .SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets) - .SetBindGroup(0, bindGroup[1]) - .DrawElements(36, 1, 0, 0) - .EndRenderPass() - .GetResult(); + pass.SetRenderPipeline(reflectionPipeline); + pass.SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets); + pass.SetBindGroup(0, bindGroup[1]); + pass.DrawElements(36, 1, 0, 0); + pass.EndPass(); + } + + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); swapchain.Present(backbuffer); DoFlush(); diff --git a/examples/glTFViewer/glTFViewer.cpp b/examples/glTFViewer/glTFViewer.cpp index ecded7f7dd..2418dba967 100644 --- a/examples/glTFViewer/glTFViewer.cpp +++ b/examples/glTFViewer/glTFViewer.cpp @@ -460,7 +460,7 @@ namespace { // Drawing namespace { - void drawMesh(dawn::CommandBufferBuilder& cmd, const tinygltf::Mesh& iMesh, const glm::mat4& model) { + void drawMesh(dawn::RenderPassEncoder& pass, const tinygltf::Mesh& iMesh, const glm::mat4& model) { for (const auto& iPrim : iMesh.primitives) { if (iPrim.mode != gl::Triangles) { fprintf(stderr, "unsupported primitive mode %d\n", iPrim.mode); @@ -484,9 +484,9 @@ namespace { } } const MaterialInfo& material = getMaterial(iPrim.material, strides[0], strides[1], strides[2]); - cmd.SetRenderPipeline(material.pipeline); - cmd.SetBindGroup(0, material.bindGroup0); - cmd.SetPushConstants(dawn::ShaderStageBit::Vertex, + pass.SetRenderPipeline(material.pipeline); + pass.SetBindGroup(0, material.bindGroup0); + pass.SetPushConstants(dawn::ShaderStageBit::Vertex, 0, sizeof(u_transform_block) / sizeof(uint32_t), reinterpret_cast(&transforms)); @@ -496,7 +496,7 @@ namespace { auto it = iPrim.attributes.find(s.second); if (it == iPrim.attributes.end()) { uint32_t zero = 0; - cmd.SetVertexBuffers(slot, 1, &defaultBuffer, &zero); + pass.SetVertexBuffers(slot, 1, &defaultBuffer, &zero); continue; } const auto& iAccessor = scene.accessors.at(it->second); @@ -511,7 +511,7 @@ namespace { } const auto& oBuffer = buffers.at(iAccessor.bufferView); uint32_t iBufferOffset = static_cast(iAccessor.byteOffset); - cmd.SetVertexBuffers(slot, 1, &oBuffer, &iBufferOffset); + pass.SetVertexBuffers(slot, 1, &oBuffer, &iBufferOffset); } if (!iPrim.indices.empty()) { @@ -522,16 +522,16 @@ namespace { continue; } const auto& oIndicesBuffer = buffers.at(iIndices.bufferView); - cmd.SetIndexBuffer(oIndicesBuffer, static_cast(iIndices.byteOffset)); - cmd.DrawElements(static_cast(iIndices.count), 1, 0, 0); + pass.SetIndexBuffer(oIndicesBuffer, static_cast(iIndices.byteOffset)); + pass.DrawElements(static_cast(iIndices.count), 1, 0, 0); } else { // DrawArrays - cmd.DrawArrays(vertexCount, 1, 0, 0); + pass.DrawArrays(vertexCount, 1, 0, 0); } } } - void drawNode(dawn::CommandBufferBuilder& cmd, const tinygltf::Node& node, const glm::mat4& parent = glm::mat4()) { + void drawNode(dawn::RenderPassEncoder& pass, const tinygltf::Node& node, const glm::mat4& parent = glm::mat4()) { glm::mat4 model; if (node.matrix.size() == 16) { model = glm::make_mat4(node.matrix.data()); @@ -552,10 +552,10 @@ namespace { model = parent * model; for (const auto& meshID : node.meshes) { - drawMesh(cmd, scene.meshes[meshID], model); + drawMesh(pass, scene.meshes[meshID], model); } for (const auto& child : node.children) { - drawNode(cmd, scene.nodes.at(child), model); + drawNode(pass, scene.nodes.at(child), model); } } @@ -565,15 +565,17 @@ namespace { GetNextRenderPassDescriptor(device, swapchain, depthStencilView, &backbuffer, &renderPass); const auto& defaultSceneNodes = scene.scenes.at(scene.defaultScene); - dawn::CommandBufferBuilder cmd = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPass) - .Clone(); - for (const auto& n : defaultSceneNodes) { - const auto& node = scene.nodes.at(n); - drawNode(cmd, node); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass); + for (const auto& n : defaultSceneNodes) { + const auto& node = scene.nodes.at(n); + drawNode(pass, node); + } + pass.EndPass(); } - auto commands = cmd.EndRenderPass() - .GetResult(); + + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); swapchain.Present(backbuffer); diff --git a/src/dawn_native/CMakeLists.txt b/src/dawn_native/CMakeLists.txt index 031728a94d..90e9f37d4e 100644 --- a/src/dawn_native/CMakeLists.txt +++ b/src/dawn_native/CMakeLists.txt @@ -333,6 +333,8 @@ list(APPEND DAWN_NATIVE_SOURCES ${DAWN_NATIVE_DIR}/CommandAllocator.h ${DAWN_NATIVE_DIR}/CommandBuffer.cpp ${DAWN_NATIVE_DIR}/CommandBuffer.h + ${DAWN_NATIVE_DIR}/ComputePassEncoder.cpp + ${DAWN_NATIVE_DIR}/ComputePassEncoder.h ${DAWN_NATIVE_DIR}/ComputePipeline.cpp ${DAWN_NATIVE_DIR}/ComputePipeline.h ${DAWN_NATIVE_DIR}/CommandBufferStateTracker.cpp @@ -358,10 +360,14 @@ list(APPEND DAWN_NATIVE_SOURCES ${DAWN_NATIVE_DIR}/Pipeline.h ${DAWN_NATIVE_DIR}/PipelineLayout.cpp ${DAWN_NATIVE_DIR}/PipelineLayout.h + ${DAWN_NATIVE_DIR}/ProgrammablePassEncoder.cpp + ${DAWN_NATIVE_DIR}/ProgrammablePassEncoder.h ${DAWN_NATIVE_DIR}/Queue.cpp ${DAWN_NATIVE_DIR}/Queue.h ${DAWN_NATIVE_DIR}/RenderPassDescriptor.cpp ${DAWN_NATIVE_DIR}/RenderPassDescriptor.h + ${DAWN_NATIVE_DIR}/RenderPassEncoder.cpp + ${DAWN_NATIVE_DIR}/RenderPassEncoder.h ${DAWN_NATIVE_DIR}/RefCounted.cpp ${DAWN_NATIVE_DIR}/RefCounted.h ${DAWN_NATIVE_DIR}/Sampler.cpp diff --git a/src/dawn_native/CommandBuffer.cpp b/src/dawn_native/CommandBuffer.cpp index 3db3c5a977..32c5caa7a3 100644 --- a/src/dawn_native/CommandBuffer.cpp +++ b/src/dawn_native/CommandBuffer.cpp @@ -18,10 +18,13 @@ #include "dawn_native/Buffer.h" #include "dawn_native/CommandBufferStateTracker.h" #include "dawn_native/Commands.h" +#include "dawn_native/ComputePassEncoder.h" #include "dawn_native/ComputePipeline.h" #include "dawn_native/Device.h" +#include "dawn_native/ErrorData.h" #include "dawn_native/InputState.h" #include "dawn_native/PipelineLayout.h" +#include "dawn_native/RenderPassEncoder.h" #include "dawn_native/RenderPipeline.h" #include "dawn_native/Texture.h" @@ -273,6 +276,13 @@ namespace dawn_native { } // namespace + enum class CommandBufferBuilder::EncodingState : uint8_t { + TopLevel, + ComputePass, + RenderPass, + Finished + }; + // CommandBuffer CommandBufferBase::CommandBufferBase(CommandBufferBuilder* builder) @@ -285,7 +295,8 @@ namespace dawn_native { // CommandBufferBuilder - CommandBufferBuilder::CommandBufferBuilder(DeviceBase* device) : Builder(device) { + CommandBufferBuilder::CommandBufferBuilder(DeviceBase* device) + : Builder(device), mEncodingState(EncodingState::TopLevel) { } CommandBufferBuilder::~CommandBufferBuilder() { @@ -308,6 +319,8 @@ namespace dawn_native { } CommandBufferBase* CommandBufferBuilder::GetResultImpl() { + mEncodingState = EncodingState::Finished; + MoveToIterator(); return mDevice->CreateCommandBuffer(this); } @@ -319,6 +332,21 @@ namespace dawn_native { } } + void CommandBufferBuilder::PassEnded() { + if (mEncodingState == EncodingState::ComputePass) { + mAllocator.Allocate(Command::EndComputePass); + } else { + ASSERT(mEncodingState == EncodingState::RenderPass); + mAllocator.Allocate(Command::EndRenderPass); + } + mEncodingState = EncodingState::TopLevel; + } + + void CommandBufferBuilder::ConsumeError(ErrorData* error) { + HandleError(error->GetMessage().c_str()); + delete error; + } + // Implementation of the command buffer validation that can be precomputed before submit MaybeError CommandBufferBuilder::ValidateGetResult() { @@ -558,14 +586,20 @@ namespace dawn_native { // Implementation of the API's command recording methods - void CommandBufferBuilder::BeginComputePass() { + ComputePassEncoderBase* CommandBufferBuilder::BeginComputePass() { mAllocator.Allocate(Command::BeginComputePass); + + mEncodingState = EncodingState::ComputePass; + return new ComputePassEncoderBase(mDevice, this, &mAllocator); } - void CommandBufferBuilder::BeginRenderPass(RenderPassDescriptorBase* info) { + RenderPassEncoderBase* CommandBufferBuilder::BeginRenderPass(RenderPassDescriptorBase* info) { BeginRenderPassCmd* cmd = mAllocator.Allocate(Command::BeginRenderPass); new (cmd) BeginRenderPassCmd; cmd->info = info; + + mEncodingState = EncodingState::RenderPass; + return new RenderPassEncoderBase(mDevice, this, &mAllocator); } void CommandBufferBuilder::CopyBufferToBuffer(BufferBase* source, @@ -647,149 +681,4 @@ namespace dawn_native { copy->rowPitch = rowPitch; } - void CommandBufferBuilder::Dispatch(uint32_t x, uint32_t y, uint32_t z) { - DispatchCmd* dispatch = mAllocator.Allocate(Command::Dispatch); - new (dispatch) DispatchCmd; - dispatch->x = x; - dispatch->y = y; - dispatch->z = z; - } - - void CommandBufferBuilder::DrawArrays(uint32_t vertexCount, - uint32_t instanceCount, - uint32_t firstVertex, - uint32_t firstInstance) { - DrawArraysCmd* draw = mAllocator.Allocate(Command::DrawArrays); - new (draw) DrawArraysCmd; - draw->vertexCount = vertexCount; - draw->instanceCount = instanceCount; - draw->firstVertex = firstVertex; - draw->firstInstance = firstInstance; - } - - void CommandBufferBuilder::DrawElements(uint32_t indexCount, - uint32_t instanceCount, - uint32_t firstIndex, - uint32_t firstInstance) { - DrawElementsCmd* draw = mAllocator.Allocate(Command::DrawElements); - new (draw) DrawElementsCmd; - draw->indexCount = indexCount; - draw->instanceCount = instanceCount; - draw->firstIndex = firstIndex; - draw->firstInstance = firstInstance; - } - - void CommandBufferBuilder::EndComputePass() { - mAllocator.Allocate(Command::EndComputePass); - } - - void CommandBufferBuilder::EndRenderPass() { - mAllocator.Allocate(Command::EndRenderPass); - } - - void CommandBufferBuilder::SetComputePipeline(ComputePipelineBase* pipeline) { - SetComputePipelineCmd* cmd = - mAllocator.Allocate(Command::SetComputePipeline); - new (cmd) SetComputePipelineCmd; - cmd->pipeline = pipeline; - } - - void CommandBufferBuilder::SetRenderPipeline(RenderPipelineBase* pipeline) { - SetRenderPipelineCmd* cmd = - mAllocator.Allocate(Command::SetRenderPipeline); - new (cmd) SetRenderPipelineCmd; - cmd->pipeline = pipeline; - } - - void CommandBufferBuilder::SetPushConstants(dawn::ShaderStageBit stages, - uint32_t offset, - uint32_t count, - const void* data) { - // TODO(cwallez@chromium.org): check for overflows - if (offset + count > kMaxPushConstants) { - HandleError("Setting too many push constants"); - return; - } - - SetPushConstantsCmd* cmd = - mAllocator.Allocate(Command::SetPushConstants); - new (cmd) SetPushConstantsCmd; - cmd->stages = stages; - cmd->offset = offset; - cmd->count = count; - - uint32_t* values = mAllocator.AllocateData(count); - memcpy(values, data, count * sizeof(uint32_t)); - } - - void CommandBufferBuilder::SetStencilReference(uint32_t reference) { - SetStencilReferenceCmd* cmd = - mAllocator.Allocate(Command::SetStencilReference); - new (cmd) SetStencilReferenceCmd; - cmd->reference = reference; - } - - void CommandBufferBuilder::SetBlendColor(float r, float g, float b, float a) { - SetBlendColorCmd* cmd = mAllocator.Allocate(Command::SetBlendColor); - new (cmd) SetBlendColorCmd; - cmd->r = r; - cmd->g = g; - cmd->b = b; - cmd->a = a; - } - - void CommandBufferBuilder::SetScissorRect(uint32_t x, - uint32_t y, - uint32_t width, - uint32_t height) { - SetScissorRectCmd* cmd = mAllocator.Allocate(Command::SetScissorRect); - new (cmd) SetScissorRectCmd; - cmd->x = x; - cmd->y = y; - cmd->width = width; - cmd->height = height; - } - - void CommandBufferBuilder::SetBindGroup(uint32_t groupIndex, BindGroupBase* group) { - if (groupIndex >= kMaxBindGroups) { - HandleError("Setting bind group over the max"); - return; - } - - SetBindGroupCmd* cmd = mAllocator.Allocate(Command::SetBindGroup); - new (cmd) SetBindGroupCmd; - cmd->index = groupIndex; - cmd->group = group; - } - - void CommandBufferBuilder::SetIndexBuffer(BufferBase* buffer, uint32_t offset) { - // TODO(kainino@chromium.org): validation - - SetIndexBufferCmd* cmd = mAllocator.Allocate(Command::SetIndexBuffer); - new (cmd) SetIndexBufferCmd; - cmd->buffer = buffer; - cmd->offset = offset; - } - - void CommandBufferBuilder::SetVertexBuffers(uint32_t startSlot, - uint32_t count, - BufferBase* const* buffers, - uint32_t const* offsets) { - // TODO(kainino@chromium.org): validation - - SetVertexBuffersCmd* cmd = - mAllocator.Allocate(Command::SetVertexBuffers); - new (cmd) SetVertexBuffersCmd; - cmd->startSlot = startSlot; - cmd->count = count; - - Ref* cmdBuffers = mAllocator.AllocateData>(count); - for (size_t i = 0; i < count; ++i) { - new (&cmdBuffers[i]) Ref(buffers[i]); - } - - uint32_t* cmdOffsets = mAllocator.AllocateData(count); - memcpy(cmdOffsets, offsets, count * sizeof(uint32_t)); - } - } // namespace dawn_native diff --git a/src/dawn_native/CommandBuffer.h b/src/dawn_native/CommandBuffer.h index 5ec9e6e42f..56d6251f82 100644 --- a/src/dawn_native/CommandBuffer.h +++ b/src/dawn_native/CommandBuffer.h @@ -60,8 +60,8 @@ namespace dawn_native { std::vector AcquirePassResourceUsage(); // Dawn API - void BeginComputePass(); - void BeginRenderPass(RenderPassDescriptorBase* info); + ComputePassEncoderBase* BeginComputePass(); + RenderPassEncoderBase* BeginRenderPass(RenderPassDescriptorBase* info); void CopyBufferToBuffer(BufferBase* source, uint32_t sourceOffset, BufferBase* destination, @@ -91,54 +91,32 @@ namespace dawn_native { BufferBase* buffer, uint32_t bufferOffset, uint32_t rowPitch); - void Dispatch(uint32_t x, uint32_t y, uint32_t z); - void DrawArrays(uint32_t vertexCount, - uint32_t instanceCount, - uint32_t firstVertex, - uint32_t firstInstance); - void DrawElements(uint32_t vertexCount, - uint32_t instanceCount, - uint32_t firstIndex, - uint32_t firstInstance); - void EndComputePass(); - void EndRenderPass(); - void SetPushConstants(dawn::ShaderStageBit stages, - uint32_t offset, - uint32_t count, - const void* data); - void SetComputePipeline(ComputePipelineBase* pipeline); - void SetRenderPipeline(RenderPipelineBase* pipeline); - void SetStencilReference(uint32_t reference); - void SetBlendColor(float r, float g, float b, float a); - void SetScissorRect(uint32_t x, uint32_t y, uint32_t width, uint32_t height); - void SetBindGroup(uint32_t groupIndex, BindGroupBase* group); - void SetIndexBuffer(BufferBase* buffer, uint32_t offset); - template - void SetVertexBuffers(uint32_t startSlot, - uint32_t count, - T* const* buffers, - uint32_t const* offsets) { - static_assert(std::is_base_of::value, ""); - SetVertexBuffers(startSlot, count, reinterpret_cast(buffers), - offsets); + // Functions to interact with the encoders + bool ConsumedError(MaybeError maybeError) { + if (DAWN_UNLIKELY(maybeError.IsError())) { + ConsumeError(maybeError.AcquireError()); + return true; + } + return false; } - void SetVertexBuffers(uint32_t startSlot, - uint32_t count, - BufferBase* const* buffers, - uint32_t const* offsets); - void TransitionBufferUsage(BufferBase* buffer, dawn::BufferUsageBit usage); + void PassEnded(); private: friend class CommandBufferBase; + enum class EncodingState : uint8_t; + EncodingState mEncodingState; + CommandBufferBase* GetResultImpl() override; void MoveToIterator(); MaybeError ValidateComputePass(); MaybeError ValidateRenderPass(RenderPassDescriptorBase* renderPass); + void ConsumeError(ErrorData* error); + CommandAllocator mAllocator; CommandIterator mIterator; bool mWasMovedToIterator = false; diff --git a/src/dawn_native/ComputePassEncoder.cpp b/src/dawn_native/ComputePassEncoder.cpp new file mode 100644 index 0000000000..77774db3d5 --- /dev/null +++ b/src/dawn_native/ComputePassEncoder.cpp @@ -0,0 +1,52 @@ +// Copyright 2018 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "dawn_native/ComputePassEncoder.h" + +#include "dawn_native/CommandBuffer.h" +#include "dawn_native/Commands.h" +#include "dawn_native/ComputePipeline.h" + +namespace dawn_native { + + ComputePassEncoderBase::ComputePassEncoderBase(DeviceBase* device, + CommandBufferBuilder* topLevelBuilder, + CommandAllocator* allocator) + : ProgrammablePassEncoder(device, topLevelBuilder, allocator) { + } + + void ComputePassEncoderBase::Dispatch(uint32_t x, uint32_t y, uint32_t z) { + if (mTopLevelBuilder->ConsumedError(ValidateCanRecordCommands())) { + return; + } + + DispatchCmd* dispatch = mAllocator->Allocate(Command::Dispatch); + new (dispatch) DispatchCmd; + dispatch->x = x; + dispatch->y = y; + dispatch->z = z; + } + + void ComputePassEncoderBase::SetComputePipeline(ComputePipelineBase* pipeline) { + if (mTopLevelBuilder->ConsumedError(ValidateCanRecordCommands())) { + return; + } + + SetComputePipelineCmd* cmd = + mAllocator->Allocate(Command::SetComputePipeline); + new (cmd) SetComputePipelineCmd; + cmd->pipeline = pipeline; + } + +} // namespace dawn_native diff --git a/src/dawn_native/ComputePassEncoder.h b/src/dawn_native/ComputePassEncoder.h new file mode 100644 index 0000000000..79c8f63c04 --- /dev/null +++ b/src/dawn_native/ComputePassEncoder.h @@ -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 DAWNNATIVE_COMPUTEPASSENCODER_H_ +#define DAWNNATIVE_COMPUTEPASSENCODER_H_ + +#include "dawn_native/Error.h" +#include "dawn_native/ProgrammablePassEncoder.h" + +namespace dawn_native { + + // This is called ComputePassEncoderBase to match the code generator expectations. Note that it + // is a pure frontend type to record in its parent CommandBufferBuilder and never has a backend + // implementation. + // TODO(cwallez@chromium.org): Remove that generator limitation and rename to ComputePassEncoder + class ComputePassEncoderBase : public ProgrammablePassEncoder { + public: + ComputePassEncoderBase(DeviceBase* device, + CommandBufferBuilder* topLevelBuilder, + CommandAllocator* allocator); + + void Dispatch(uint32_t x, uint32_t y, uint32_t z); + void SetComputePipeline(ComputePipelineBase* pipeline); + }; + +} // namespace dawn_native + +#endif // DAWNNATIVE_COMPUTEPASSENCODER_H_ diff --git a/src/dawn_native/Forward.h b/src/dawn_native/Forward.h index a67b89aaee..a5ac6e4a3f 100644 --- a/src/dawn_native/Forward.h +++ b/src/dawn_native/Forward.h @@ -33,6 +33,7 @@ namespace dawn_native { class ComputePipelineBuilder; class CommandBufferBase; class CommandBufferBuilder; + class ComputePassEncoderBase; class DepthStencilStateBase; class DepthStencilStateBuilder; class InputStateBase; @@ -42,6 +43,7 @@ namespace dawn_native { class QueueBase; class RenderPassDescriptorBase; class RenderPassDescriptorBuilder; + class RenderPassEncoderBase; class RenderPipelineBase; class RenderPipelineBuilder; class SamplerBase; diff --git a/src/dawn_native/ProgrammablePassEncoder.cpp b/src/dawn_native/ProgrammablePassEncoder.cpp new file mode 100644 index 0000000000..7b06146d82 --- /dev/null +++ b/src/dawn_native/ProgrammablePassEncoder.cpp @@ -0,0 +1,87 @@ +// Copyright 2018 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "dawn_native/ProgrammablePassEncoder.h" + +#include "dawn_native/BindGroup.h" +#include "dawn_native/CommandBuffer.h" +#include "dawn_native/Commands.h" + +namespace dawn_native { + + ProgrammablePassEncoder::ProgrammablePassEncoder(DeviceBase* device, + CommandBufferBuilder* topLevelBuilder, + CommandAllocator* allocator) + : mDevice(device), mTopLevelBuilder(topLevelBuilder), mAllocator(allocator) { + } + + void ProgrammablePassEncoder::EndPass() { + mTopLevelBuilder->PassEnded(); + mAllocator = nullptr; + } + + void ProgrammablePassEncoder::SetBindGroup(uint32_t groupIndex, BindGroupBase* group) { + if (mTopLevelBuilder->ConsumedError(ValidateCanRecordCommands())) { + return; + } + + if (groupIndex >= kMaxBindGroups) { + mTopLevelBuilder->HandleError("Setting bind group over the max"); + return; + } + + SetBindGroupCmd* cmd = mAllocator->Allocate(Command::SetBindGroup); + new (cmd) SetBindGroupCmd; + cmd->index = groupIndex; + cmd->group = group; + } + + void ProgrammablePassEncoder::SetPushConstants(dawn::ShaderStageBit stages, + uint32_t offset, + uint32_t count, + const void* data) { + if (mTopLevelBuilder->ConsumedError(ValidateCanRecordCommands())) { + return; + } + + // TODO(cwallez@chromium.org): check for overflows + if (offset + count > kMaxPushConstants) { + mTopLevelBuilder->HandleError("Setting too many push constants"); + return; + } + + SetPushConstantsCmd* cmd = + mAllocator->Allocate(Command::SetPushConstants); + new (cmd) SetPushConstantsCmd; + cmd->stages = stages; + cmd->offset = offset; + cmd->count = count; + + uint32_t* values = mAllocator->AllocateData(count); + memcpy(values, data, count * sizeof(uint32_t)); + } + + DeviceBase* ProgrammablePassEncoder::GetDevice() const { + return mDevice; + } + + MaybeError ProgrammablePassEncoder::ValidateCanRecordCommands() const { + if (mAllocator == nullptr) { + return DAWN_VALIDATION_ERROR("Recording in an already ended computePassEncoder"); + } + + return nullptr; + } + +} // namespace dawn_native diff --git a/src/dawn_native/ProgrammablePassEncoder.h b/src/dawn_native/ProgrammablePassEncoder.h new file mode 100644 index 0000000000..8f59f7d03b --- /dev/null +++ b/src/dawn_native/ProgrammablePassEncoder.h @@ -0,0 +1,59 @@ +// Copyright 2018 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef DAWNNATIVE_PROGRAMMABLEPASSENCODER_H_ +#define DAWNNATIVE_PROGRAMMABLEPASSENCODER_H_ + +#include "dawn_native/Error.h" +#include "dawn_native/RefCounted.h" + +#include "dawn_native/dawn_platform.h" + +namespace dawn_native { + + class CommandAllocator; + class DeviceBase; + + // Base class for shared functionality between ComputePassEncoder and RenderPassEncoder. + class ProgrammablePassEncoder : public RefCounted { + public: + ProgrammablePassEncoder(DeviceBase* device, + CommandBufferBuilder* topLevelBuilder, + CommandAllocator* allocator); + + void EndPass(); + + void SetBindGroup(uint32_t groupIndex, BindGroupBase* group); + void SetPushConstants(dawn::ShaderStageBit stages, + uint32_t offset, + uint32_t count, + const void* data); + + DeviceBase* GetDevice() const; + + protected: + MaybeError ValidateCanRecordCommands() const; + + DeviceBase* mDevice; + + // The allocator is borrowed from the top level builder. Keep a reference to the builder + // to make sure the allocator isn't freed. + Ref mTopLevelBuilder = nullptr; + // mAllocator is cleared at the end of the pass so it acts as a tag that EndPass was called + CommandAllocator* mAllocator = nullptr; + }; + +} // namespace dawn_native + +#endif // DAWNNATIVE_PROGRAMMABLEPASSENCODER_H_ diff --git a/src/dawn_native/RenderPassEncoder.cpp b/src/dawn_native/RenderPassEncoder.cpp new file mode 100644 index 0000000000..fb0a6dfe21 --- /dev/null +++ b/src/dawn_native/RenderPassEncoder.cpp @@ -0,0 +1,123 @@ +// Copyright 2018 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "dawn_native/RenderPassEncoder.h" + +#include "dawn_native/Buffer.h" +#include "dawn_native/CommandBuffer.h" +#include "dawn_native/Commands.h" +#include "dawn_native/RenderPipeline.h" + +namespace dawn_native { + + RenderPassEncoderBase::RenderPassEncoderBase(DeviceBase* device, + CommandBufferBuilder* topLevelBuilder, + CommandAllocator* allocator) + : ProgrammablePassEncoder(device, topLevelBuilder, allocator) { + } + + void RenderPassEncoderBase::DrawArrays(uint32_t vertexCount, + uint32_t instanceCount, + uint32_t firstVertex, + uint32_t firstInstance) { + DrawArraysCmd* draw = mAllocator->Allocate(Command::DrawArrays); + new (draw) DrawArraysCmd; + draw->vertexCount = vertexCount; + draw->instanceCount = instanceCount; + draw->firstVertex = firstVertex; + draw->firstInstance = firstInstance; + } + + void RenderPassEncoderBase::DrawElements(uint32_t indexCount, + uint32_t instanceCount, + uint32_t firstIndex, + uint32_t firstInstance) { + DrawElementsCmd* draw = mAllocator->Allocate(Command::DrawElements); + new (draw) DrawElementsCmd; + draw->indexCount = indexCount; + draw->instanceCount = instanceCount; + draw->firstIndex = firstIndex; + draw->firstInstance = firstInstance; + } + + void RenderPassEncoderBase::SetRenderPipeline(RenderPipelineBase* pipeline) { + if (mTopLevelBuilder->ConsumedError(ValidateCanRecordCommands())) { + return; + } + + SetRenderPipelineCmd* cmd = + mAllocator->Allocate(Command::SetRenderPipeline); + new (cmd) SetRenderPipelineCmd; + cmd->pipeline = pipeline; + } + + void RenderPassEncoderBase::SetStencilReference(uint32_t reference) { + SetStencilReferenceCmd* cmd = + mAllocator->Allocate(Command::SetStencilReference); + new (cmd) SetStencilReferenceCmd; + cmd->reference = reference; + } + + void RenderPassEncoderBase::SetBlendColor(float r, float g, float b, float a) { + SetBlendColorCmd* cmd = mAllocator->Allocate(Command::SetBlendColor); + new (cmd) SetBlendColorCmd; + cmd->r = r; + cmd->g = g; + cmd->b = b; + cmd->a = a; + } + + void RenderPassEncoderBase::SetScissorRect(uint32_t x, + uint32_t y, + uint32_t width, + uint32_t height) { + SetScissorRectCmd* cmd = mAllocator->Allocate(Command::SetScissorRect); + new (cmd) SetScissorRectCmd; + cmd->x = x; + cmd->y = y; + cmd->width = width; + cmd->height = height; + } + + void RenderPassEncoderBase::SetIndexBuffer(BufferBase* buffer, uint32_t offset) { + // TODO(kainino@chromium.org): validation + + SetIndexBufferCmd* cmd = mAllocator->Allocate(Command::SetIndexBuffer); + new (cmd) SetIndexBufferCmd; + cmd->buffer = buffer; + cmd->offset = offset; + } + + void RenderPassEncoderBase::SetVertexBuffers(uint32_t startSlot, + uint32_t count, + BufferBase* const* buffers, + uint32_t const* offsets) { + // TODO(kainino@chromium.org): validation + + SetVertexBuffersCmd* cmd = + mAllocator->Allocate(Command::SetVertexBuffers); + new (cmd) SetVertexBuffersCmd; + cmd->startSlot = startSlot; + cmd->count = count; + + Ref* cmdBuffers = mAllocator->AllocateData>(count); + for (size_t i = 0; i < count; ++i) { + new (&cmdBuffers[i]) Ref(buffers[i]); + } + + uint32_t* cmdOffsets = mAllocator->AllocateData(count); + memcpy(cmdOffsets, offsets, count * sizeof(uint32_t)); + } + +} // namespace dawn_native diff --git a/src/dawn_native/RenderPassEncoder.h b/src/dawn_native/RenderPassEncoder.h new file mode 100644 index 0000000000..c2bdad8a9a --- /dev/null +++ b/src/dawn_native/RenderPassEncoder.h @@ -0,0 +1,66 @@ +// Copyright 2018 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef DAWNNATIVE_RENDERPASSENCODER_H_ +#define DAWNNATIVE_RENDERPASSENCODER_H_ + +#include "dawn_native/Error.h" +#include "dawn_native/ProgrammablePassEncoder.h" + +namespace dawn_native { + + // This is called RenderPassEncoderBase to match the code generator expectations. Note that it + // is a pure frontend type to record in its parent CommandBufferBuilder and never has a backend + // implementation. + // TODO(cwallez@chromium.org): Remove that generator limitation and rename to ComputePassEncoder + class RenderPassEncoderBase : public ProgrammablePassEncoder { + public: + RenderPassEncoderBase(DeviceBase* device, + CommandBufferBuilder* topLevelBuilder, + CommandAllocator* allocator); + + void DrawArrays(uint32_t vertexCount, + uint32_t instanceCount, + uint32_t firstVertex, + uint32_t firstInstance); + void DrawElements(uint32_t vertexCount, + uint32_t instanceCount, + uint32_t firstIndex, + uint32_t firstInstance); + + void SetRenderPipeline(RenderPipelineBase* pipeline); + + void SetStencilReference(uint32_t reference); + void SetBlendColor(float r, float g, float b, float a); + void SetScissorRect(uint32_t x, uint32_t y, uint32_t width, uint32_t height); + + template + void SetVertexBuffers(uint32_t startSlot, + uint32_t count, + T* const* buffers, + uint32_t const* offsets) { + static_assert(std::is_base_of::value, ""); + SetVertexBuffers(startSlot, count, reinterpret_cast(buffers), + offsets); + } + void SetVertexBuffers(uint32_t startSlot, + uint32_t count, + BufferBase* const* buffers, + uint32_t const* offsets); + void SetIndexBuffer(BufferBase* buffer, uint32_t offset); + }; + +} // namespace dawn_native + +#endif // DAWNNATIVE_RENDERPASSENCODER_H_ diff --git a/src/tests/end2end/BlendStateTests.cpp b/src/tests/end2end/BlendStateTests.cpp index a9231fa25c..416d1f17ce 100644 --- a/src/tests/end2end/BlendStateTests.cpp +++ b/src/tests/end2end/BlendStateTests.cpp @@ -109,22 +109,23 @@ class BlendStateTest : public DawnTest { // Test that after drawing a triangle with the base color, and then the given triangle spec, the color is as expected void DoSingleSourceTest(RGBA8 base, const TriangleSpec& triangle, const RGBA8& expected) { - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPass.renderPassInfo) - // First use the base pipeline to draw a triangle with no blending - .SetRenderPipeline(basePipeline) - .SetBindGroup(0, MakeBindGroupForColors(std::array({ { base } }))) - .DrawArrays(3, 1, 0, 0) - - // Then use the test pipeline to draw the test triangle with blending - .SetRenderPipeline(testPipeline) - .SetBindGroup(0, MakeBindGroupForColors(std::array({ { triangle.color } }))) - .SetBlendColor(triangle.blendFactor[0], triangle.blendFactor[1], triangle.blendFactor[2], triangle.blendFactor[3]) - .DrawArrays(3, 1, 0, 0) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo); + // First use the base pipeline to draw a triangle with no blending + pass.SetRenderPipeline(basePipeline); + pass.SetBindGroup(0, MakeBindGroupForColors(std::array({ { base } }))); + pass.DrawArrays(3, 1, 0, 0); + // Then use the test pipeline to draw the test triangle with blending + pass.SetRenderPipeline(testPipeline); + pass.SetBindGroup(0, MakeBindGroupForColors(std::array({ { triangle.color } }))); + pass.SetBlendColor(triangle.blendFactor[0], triangle.blendFactor[1], triangle.blendFactor[2], triangle.blendFactor[3]); + pass.DrawArrays(3, 1, 0, 0); + pass.EndPass(); + } + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); EXPECT_PIXEL_RGBA8_EQ(expected, renderPass.color, kRTSize / 2, kRTSize / 2); @@ -671,14 +672,17 @@ TEST_P(BlendStateTest, ColorWriteMaskBlendingDisabled) { RGBA8 base(32, 64, 128, 192); RGBA8 expected(32, 0, 0, 0); - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPass.renderPassInfo) - .SetRenderPipeline(testPipeline) - .SetBindGroup(0, MakeBindGroupForColors(std::array({ { base } }))) - .DrawArrays(3, 1, 0, 0) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo); + pass.SetRenderPipeline(testPipeline); + pass.SetBindGroup(0, MakeBindGroupForColors(std::array({ { base } }))); + pass.DrawArrays(3, 1, 0, 0); + pass.EndPass(); + } + + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); EXPECT_PIXEL_RGBA8_EQ(expected, renderPass.color, kRTSize / 2, kRTSize / 2); } @@ -790,18 +794,20 @@ TEST_P(BlendStateTest, IndependentBlendState) { RGBA8 expected2 = color2; RGBA8 expected3 = min(color3, base); - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderpass) - .SetRenderPipeline(basePipeline) - .SetBindGroup(0, MakeBindGroupForColors(std::array({ { base, base, base, base } }))) - .DrawArrays(3, 1, 0, 0) + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderpass); + pass.SetRenderPipeline(basePipeline); + pass.SetBindGroup(0, MakeBindGroupForColors(std::array({ { base, base, base, base } }))); + pass.DrawArrays(3, 1, 0, 0); - .SetRenderPipeline(testPipeline) - .SetBindGroup(0, MakeBindGroupForColors(std::array({ { color0, color1, color2, color3 } }))) - .DrawArrays(3, 1, 0, 0) - .EndRenderPass() - .GetResult(); + pass.SetRenderPipeline(testPipeline); + pass.SetBindGroup(0, MakeBindGroupForColors(std::array({ { color0, color1, color2, color3 } }))); + pass.DrawArrays(3, 1, 0, 0); + pass.EndPass(); + } + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); EXPECT_PIXEL_RGBA8_EQ(expected0, renderTargets[0], kRTSize / 2, kRTSize / 2) << "Attachment slot 0 should have been " << color0 << " + " << base << " = " << expected0; @@ -849,17 +855,19 @@ TEST_P(BlendStateTest, DefaultBlendColor) { // Check that the initial blend color is (0,0,0,0) { - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPass.renderPassInfo) - .SetRenderPipeline(basePipeline) - .SetBindGroup(0, MakeBindGroupForColors(std::array({ { RGBA8(0, 0, 0, 0) } }))) - .DrawArrays(3, 1, 0, 0) - .SetRenderPipeline(testPipeline) - .SetBindGroup(0, MakeBindGroupForColors(std::array({ { RGBA8(255, 255, 255, 255) } }))) - .DrawArrays(3, 1, 0, 0) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo); + pass.SetRenderPipeline(basePipeline); + pass.SetBindGroup(0, MakeBindGroupForColors(std::array({ { RGBA8(0, 0, 0, 0) } }))); + pass.DrawArrays(3, 1, 0, 0); + pass.SetRenderPipeline(testPipeline); + pass.SetBindGroup(0, MakeBindGroupForColors(std::array({ { RGBA8(255, 255, 255, 255) } }))); + pass.DrawArrays(3, 1, 0, 0); + pass.EndPass(); + } + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 0, 0, 0), renderPass.color, kRTSize / 2, kRTSize / 2); @@ -867,18 +875,20 @@ TEST_P(BlendStateTest, DefaultBlendColor) { // Check that setting the blend color works { - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPass.renderPassInfo) - .SetRenderPipeline(basePipeline) - .SetBindGroup(0, MakeBindGroupForColors(std::array({ { RGBA8(0, 0, 0, 0) } }))) - .DrawArrays(3, 1, 0, 0) - .SetRenderPipeline(testPipeline) - .SetBlendColor(1, 1, 1, 1) - .SetBindGroup(0, MakeBindGroupForColors(std::array({ { RGBA8(255, 255, 255, 255) } }))) - .DrawArrays(3, 1, 0, 0) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo); + pass.SetRenderPipeline(basePipeline); + pass.SetBindGroup(0, MakeBindGroupForColors(std::array({ { RGBA8(0, 0, 0, 0) } }))); + pass.DrawArrays(3, 1, 0, 0); + pass.SetRenderPipeline(testPipeline); + pass.SetBlendColor(1, 1, 1, 1); + pass.SetBindGroup(0, MakeBindGroupForColors(std::array({ { RGBA8(255, 255, 255, 255) } }))); + pass.DrawArrays(3, 1, 0, 0); + pass.EndPass(); + } + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); EXPECT_PIXEL_RGBA8_EQ(RGBA8(255, 255, 255, 255), renderPass.color, kRTSize / 2, kRTSize / 2); @@ -886,26 +896,30 @@ TEST_P(BlendStateTest, DefaultBlendColor) { // Check that the blend color is not inherited between render passes { - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPass.renderPassInfo) - .SetRenderPipeline(basePipeline) - .SetBindGroup(0, MakeBindGroupForColors(std::array({ { RGBA8(0, 0, 0, 0) } }))) - .DrawArrays(3, 1, 0, 0) - .SetRenderPipeline(testPipeline) - .SetBlendColor(1, 1, 1, 1) - .SetBindGroup(0, MakeBindGroupForColors(std::array({ { RGBA8(255, 255, 255, 255) } }))) - .DrawArrays(3, 1, 0, 0) - .EndRenderPass() - .BeginRenderPass(renderPass.renderPassInfo) - .SetRenderPipeline(basePipeline) - .SetBindGroup(0, MakeBindGroupForColors(std::array({ { RGBA8(0, 0, 0, 0) } }))) - .DrawArrays(3, 1, 0, 0) - .SetRenderPipeline(testPipeline) - .SetBindGroup(0, MakeBindGroupForColors(std::array({ { RGBA8(255, 255, 255, 255) } }))) - .DrawArrays(3, 1, 0, 0) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo); + pass.SetRenderPipeline(basePipeline); + pass.SetBindGroup(0, MakeBindGroupForColors(std::array({ { RGBA8(0, 0, 0, 0) } }))); + pass.DrawArrays(3, 1, 0, 0); + pass.SetRenderPipeline(testPipeline); + pass.SetBlendColor(1, 1, 1, 1); + pass.SetBindGroup(0, MakeBindGroupForColors(std::array({ { RGBA8(255, 255, 255, 255) } }))); + pass.DrawArrays(3, 1, 0, 0); + pass.EndPass(); + } + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo); + pass.SetRenderPipeline(basePipeline); + pass.SetBindGroup(0, MakeBindGroupForColors(std::array({ { RGBA8(0, 0, 0, 0) } }))); + pass.DrawArrays(3, 1, 0, 0); + pass.SetRenderPipeline(testPipeline); + pass.SetBindGroup(0, MakeBindGroupForColors(std::array({ { RGBA8(255, 255, 255, 255) } }))); + pass.DrawArrays(3, 1, 0, 0); + pass.EndPass(); + } + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 0, 0, 0), renderPass.color, kRTSize / 2, kRTSize / 2); diff --git a/src/tests/end2end/ComputeCopyStorageBufferTests.cpp b/src/tests/end2end/ComputeCopyStorageBufferTests.cpp index 834185e876..9ee30213f2 100644 --- a/src/tests/end2end/ComputeCopyStorageBufferTests.cpp +++ b/src/tests/end2end/ComputeCopyStorageBufferTests.cpp @@ -78,13 +78,18 @@ void ComputeCopyStorageBufferTests::BasicTest(const char* shader) { .SetBufferViews(0, 1, &srcView) .SetBufferViews(1, 1, &dstView) .GetResult(); - auto commands = device.CreateCommandBufferBuilder() - .BeginComputePass() - .SetComputePipeline(pipeline) - .SetBindGroup(0, bindGroup) - .Dispatch(kInstances, 1, 1) - .EndComputePass() - .GetResult(); + + dawn::CommandBuffer commands; + { + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + dawn::ComputePassEncoder pass = builder.BeginComputePass(); + pass.SetComputePipeline(pipeline); + pass.SetBindGroup(0, bindGroup); + pass.Dispatch(kInstances, 1, 1); + pass.EndPass(); + + commands = builder.GetResult(); + } queue.Submit(1, &commands); diff --git a/src/tests/end2end/DepthStencilStateTests.cpp b/src/tests/end2end/DepthStencilStateTests.cpp index 3f52d0264e..475c77e680 100644 --- a/src/tests/end2end/DepthStencilStateTests.cpp +++ b/src/tests/end2end/DepthStencilStateTests.cpp @@ -197,7 +197,7 @@ class DepthStencilStateTest : public DawnTest { float depth; }; - builder.BeginRenderPass(renderpass); + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderpass); for (size_t i = 0; i < testParams.size(); ++i) { const TestSpec& test = testParams[i]; @@ -229,16 +229,14 @@ class DepthStencilStateTest : public DawnTest { .SetDepthStencilState(test.depthStencilState) .GetResult(); - builder.SetRenderPipeline(pipeline) - .SetStencilReference(test.stencil) // Set the stencil reference - .SetBindGroup(0, bindGroup) // Set the bind group which contains color and depth data - .DrawArrays(6, 1, 0, 0); + pass.SetRenderPipeline(pipeline); + pass.SetStencilReference(test.stencil); // Set the stencil reference + pass.SetBindGroup(0, bindGroup); // Set the bind group which contains color and depth data + pass.DrawArrays(6, 1, 0, 0); } + pass.EndPass(); - dawn::CommandBuffer commands = builder - .EndRenderPass() - .GetResult(); - + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); EXPECT_PIXEL_RGBA8_EQ(expectedFront, renderTarget, kRTSize / 4, kRTSize / 2) << "Front face check failed"; diff --git a/src/tests/end2end/DrawElementsTests.cpp b/src/tests/end2end/DrawElementsTests.cpp index 2ec3d4a0b7..c26b44c772 100644 --- a/src/tests/end2end/DrawElementsTests.cpp +++ b/src/tests/end2end/DrawElementsTests.cpp @@ -74,15 +74,17 @@ class DrawElementsTest : public DawnTest { void Test(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, uint32_t firstInstance, RGBA8 bottomLeftExpected, RGBA8 topRightExpected) { uint32_t zeroOffset = 0; - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPass.renderPassInfo) - .SetRenderPipeline(pipeline) - .SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset) - .SetIndexBuffer(indexBuffer, 0) - .DrawElements(indexCount, instanceCount, firstIndex, firstInstance) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo); + pass.SetRenderPipeline(pipeline); + pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset); + pass.SetIndexBuffer(indexBuffer, 0); + pass.DrawElements(indexCount, instanceCount, firstIndex, firstInstance); + pass.EndPass(); + } + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); EXPECT_PIXEL_RGBA8_EQ(bottomLeftExpected, renderPass.color, 1, 3); diff --git a/src/tests/end2end/IndexFormatTests.cpp b/src/tests/end2end/IndexFormatTests.cpp index d9582bbcb2..ae6066397a 100644 --- a/src/tests/end2end/IndexFormatTests.cpp +++ b/src/tests/end2end/IndexFormatTests.cpp @@ -78,15 +78,17 @@ TEST_P(IndexFormatTest, Uint32) { }); uint32_t zeroOffset = 0; - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPass.renderPassInfo) - .SetRenderPipeline(pipeline) - .SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset) - .SetIndexBuffer(indexBuffer, 0) - .DrawElements(3, 1, 0, 0) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo); + pass.SetRenderPipeline(pipeline); + pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset); + pass.SetIndexBuffer(indexBuffer, 0); + pass.DrawElements(3, 1, 0, 0); + pass.EndPass(); + } + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 255, 0, 255), renderPass.color, 100, 300); @@ -107,15 +109,17 @@ TEST_P(IndexFormatTest, Uint16) { }); uint32_t zeroOffset = 0; - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPass.renderPassInfo) - .SetRenderPipeline(pipeline) - .SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset) - .SetIndexBuffer(indexBuffer, 0) - .DrawElements(3, 1, 0, 0) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo); + pass.SetRenderPipeline(pipeline); + pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset); + pass.SetIndexBuffer(indexBuffer, 0); + pass.DrawElements(3, 1, 0, 0); + pass.EndPass(); + } + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 255, 0, 255), renderPass.color, 100, 300); @@ -149,15 +153,17 @@ TEST_P(IndexFormatTest, Uint32PrimitiveRestart) { }); uint32_t zeroOffset = 0; - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPass.renderPassInfo) - .SetRenderPipeline(pipeline) - .SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset) - .SetIndexBuffer(indexBuffer, 0) - .DrawElements(7, 1, 0, 0) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo); + pass.SetRenderPipeline(pipeline); + pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset); + pass.SetIndexBuffer(indexBuffer, 0); + pass.DrawElements(7, 1, 0, 0); + pass.EndPass(); + } + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 255, 0, 255), renderPass.color, 190, 190); // A @@ -181,15 +187,17 @@ TEST_P(IndexFormatTest, Uint16PrimitiveRestart) { }); uint32_t zeroOffset = 0; - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPass.renderPassInfo) - .SetRenderPipeline(pipeline) - .SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset) - .SetIndexBuffer(indexBuffer, 0) - .DrawElements(7, 1, 0, 0) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo); + pass.SetRenderPipeline(pipeline); + pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset); + pass.SetIndexBuffer(indexBuffer, 0); + pass.DrawElements(7, 1, 0, 0); + pass.EndPass(); + } + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 255, 0, 255), renderPass.color, 190, 190); // A @@ -218,16 +226,18 @@ TEST_P(IndexFormatTest, ChangePipelineAfterSetIndexBuffer) { }); uint32_t zeroOffset = 0; - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPass.renderPassInfo) - .SetRenderPipeline(pipeline16) - .SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset) - .SetIndexBuffer(indexBuffer, 0) - .SetRenderPipeline(pipeline32) - .DrawElements(3, 1, 0, 0) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo); + pass.SetRenderPipeline(pipeline16); + pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset); + pass.SetIndexBuffer(indexBuffer, 0); + pass.SetRenderPipeline(pipeline32); + pass.DrawElements(3, 1, 0, 0); + pass.EndPass(); + } + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 255, 0, 255), renderPass.color, 100, 300); @@ -251,15 +261,17 @@ TEST_P(IndexFormatTest, DISABLED_SetIndexBufferBeforeSetPipeline) { }); uint32_t zeroOffset = 0; - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPass.renderPassInfo) - .SetIndexBuffer(indexBuffer, 0) - .SetRenderPipeline(pipeline) - .SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset) - .DrawElements(3, 1, 0, 0) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo); + pass.SetIndexBuffer(indexBuffer, 0); + pass.SetRenderPipeline(pipeline); + pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset); + pass.DrawElements(3, 1, 0, 0); + pass.EndPass(); + } + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 255, 0, 255), renderPass.color, 100, 300); diff --git a/src/tests/end2end/InputStateTests.cpp b/src/tests/end2end/InputStateTests.cpp index 5771ce62a9..5abe632c49 100644 --- a/src/tests/end2end/InputStateTests.cpp +++ b/src/tests/end2end/InputStateTests.cpp @@ -168,19 +168,18 @@ class InputStateTest : public DawnTest { dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); - builder.BeginRenderPass(renderPass.renderPassInfo) - .SetRenderPipeline(pipeline); + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo); + pass.SetRenderPipeline(pipeline); uint32_t zeroOffset = 0; for (const auto& buffer : vertexBuffers) { - builder.SetVertexBuffers(buffer.location, 1, buffer.buffer, &zeroOffset); + pass.SetVertexBuffers(buffer.location, 1, buffer.buffer, &zeroOffset); } - dawn::CommandBuffer commands = builder - .DrawArrays(triangles * 3, instances, 0, 0) - .EndRenderPass() - .GetResult(); + pass.DrawArrays(triangles * 3, instances, 0, 0); + pass.EndPass(); + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); // Check that the center of each triangle is pure green, so that if a single vertex shader diff --git a/src/tests/end2end/PrimitiveTopologyTests.cpp b/src/tests/end2end/PrimitiveTopologyTests.cpp index bc5624906d..696077b6dc 100644 --- a/src/tests/end2end/PrimitiveTopologyTests.cpp +++ b/src/tests/end2end/PrimitiveTopologyTests.cpp @@ -194,14 +194,16 @@ class PrimitiveTopologyTest : public DawnTest { .GetResult(); static const uint32_t zeroOffset = 0; - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPass.renderPassInfo) - .SetRenderPipeline(pipeline) - .SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset) - .DrawArrays(6, 1, 0, 0) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo); + pass.SetRenderPipeline(pipeline); + pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset); + pass.DrawArrays(6, 1, 0, 0); + pass.EndPass(); + } + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); for (auto& locationSpec : locationSpecs) { diff --git a/src/tests/end2end/PushConstantTests.cpp b/src/tests/end2end/PushConstantTests.cpp index 0417ddf401..070abeccab 100644 --- a/src/tests/end2end/PushConstantTests.cpp +++ b/src/tests/end2end/PushConstantTests.cpp @@ -207,23 +207,31 @@ TEST_P(PushConstantTest, ComputePassDefaultsToZero) { dawn::ComputePipeline pipeline = MakeTestComputePipeline(binding.layout, MakeAllZeroSpec()); uint32_t notZero = 42; - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginComputePass() - // Test compute push constants are set to zero by default. - .SetComputePipeline(pipeline) - .SetBindGroup(0, binding.bindGroup) - .Dispatch(1, 1, 1) - // Set push constants to non-zero value to check they will be reset to zero - // on the next BeginComputePass - .SetPushConstants(dawn::ShaderStageBit::Compute, 0, 1, ¬Zero) - .EndComputePass() - .BeginComputePass() - .SetComputePipeline(pipeline) - .SetBindGroup(0, binding.bindGroup) - .Dispatch(1, 1, 1) - .EndComputePass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::ComputePassEncoder pass = builder.BeginComputePass(); + // Test compute push constants are set to zero by default. + pass.SetComputePipeline(pipeline); + pass.SetBindGroup(0, binding.bindGroup); + pass.Dispatch(1, 1, 1); + // Set push constants to non-zero value to check they will be reset to zero + // on the next BeginComputePass + pass.SetPushConstants(dawn::ShaderStageBit::Compute, 0, 1, ¬Zero); + + pass.EndPass(); + } + { + dawn::ComputePassEncoder pass = builder.BeginComputePass(); + + pass.SetComputePipeline(pipeline); + pass.SetBindGroup(0, binding.bindGroup); + pass.Dispatch(1, 1, 1); + + pass.EndPass(); + } + + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); EXPECT_BUFFER_U32_EQ(1, binding.resultBuffer, 0); @@ -238,14 +246,16 @@ TEST_P(PushConstantTest, RenderPassDefaultsToZero) { dawn::PipelineLayout layout = MakeEmptyLayout(); dawn::RenderPipeline pipeline = MakeTestRenderPipeline(layout, MakeAllZeroSpec(), MakeAllZeroSpec()); - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPass.renderPassInfo) - // Test render push constants are set to zero by default. - .SetRenderPipeline(pipeline) - .DrawArrays(1, 1, 0, 0) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo); + // Test render push constants are set to zero by default. + pass.SetRenderPipeline(pipeline); + pass.DrawArrays(1, 1, 0, 0); + pass.EndPass(); + } + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 1, 0, 0), renderPass.color, 0, 0); @@ -266,15 +276,19 @@ TEST_P(PushConstantTest, VariousConstantTypes) { dawn::ComputePipeline pipeline = MakeTestComputePipeline(binding.layout, spec); - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginComputePass() - .SetPushConstants(dawn::ShaderStageBit::Compute, 0, 3, reinterpret_cast(&values)) - .SetComputePipeline(pipeline) - .SetBindGroup(0, binding.bindGroup) - .Dispatch(1, 1, 1) - .EndComputePass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::ComputePassEncoder pass = builder.BeginComputePass(); + pass.SetPushConstants(dawn::ShaderStageBit::Compute, 0, 3, reinterpret_cast(&values)); + pass.SetComputePipeline(pipeline); + pass.SetBindGroup(0, binding.bindGroup); + pass.Dispatch(1, 1, 1); + + pass.EndPass(); + } + + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); EXPECT_BUFFER_U32_EQ(1, binding.resultBuffer, 0); @@ -292,21 +306,25 @@ TEST_P(PushConstantTest, InheritThroughPipelineLayoutChange) { uint32_t one = 1; uint32_t two = 2; - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginComputePass() - // Set Push constant before there is a pipeline set - .SetPushConstants(dawn::ShaderStageBit::Compute, 0, 1, &one) - .SetComputePipeline(pipeline1) - .SetBindGroup(0, binding1.bindGroup) - .Dispatch(1, 1, 1) - // Change the push constant before changing pipeline layout - .SetPushConstants(dawn::ShaderStageBit::Compute, 0, 1, &two) - .SetComputePipeline(pipeline2) - .SetBindGroup(0, binding2.bindGroup) - .Dispatch(1, 1, 1) - .EndComputePass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::ComputePassEncoder pass = builder.BeginComputePass(); + // Set Push constant before there is a pipeline set + pass.SetPushConstants(dawn::ShaderStageBit::Compute, 0, 1, &one); + pass.SetComputePipeline(pipeline1); + pass.SetBindGroup(0, binding1.bindGroup); + pass.Dispatch(1, 1, 1); + // Change the push constant before changing pipeline layout + pass.SetPushConstants(dawn::ShaderStageBit::Compute, 0, 1, &two); + pass.SetComputePipeline(pipeline2); + pass.SetBindGroup(0, binding2.bindGroup); + pass.Dispatch(1, 1, 1); + + pass.EndPass(); + } + + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); EXPECT_BUFFER_U32_EQ(1, binding1.resultBuffer, 0); @@ -325,15 +343,19 @@ TEST_P(PushConstantTest, SetAllConstantsToNonZero) { auto binding = MakeTestBindings(false); dawn::ComputePipeline pipeline = MakeTestComputePipeline(binding.layout, spec); - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginComputePass() - .SetPushConstants(dawn::ShaderStageBit::Compute, 0, kMaxPushConstants, &values[0]) - .SetComputePipeline(pipeline) - .SetBindGroup(0, binding.bindGroup) - .Dispatch(1, 1, 1) - .EndComputePass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::ComputePassEncoder pass = builder.BeginComputePass(); + pass.SetPushConstants(dawn::ShaderStageBit::Compute, 0, kMaxPushConstants, &values[0]); + pass.SetComputePipeline(pipeline); + pass.SetBindGroup(0, binding.bindGroup); + pass.Dispatch(1, 1, 1); + + pass.EndPass(); + } + + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); EXPECT_BUFFER_U32_EQ(1, binding.resultBuffer, 0); @@ -351,15 +373,17 @@ TEST_P(PushConstantTest, SeparateVertexAndFragmentConstants) { uint32_t one = 1; uint32_t two = 2; - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPass.renderPassInfo) - .SetPushConstants(dawn::ShaderStageBit::Vertex, 0, 1, &one) - .SetPushConstants(dawn::ShaderStageBit::Fragment, 0, 1, &two) - .SetRenderPipeline(pipeline) - .DrawArrays(1, 1, 0, 0) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo); + pass.SetPushConstants(dawn::ShaderStageBit::Vertex, 0, 1, &one); + pass.SetPushConstants(dawn::ShaderStageBit::Fragment, 0, 1, &two); + pass.SetRenderPipeline(pipeline); + pass.DrawArrays(1, 1, 0, 0); + pass.EndPass(); + } + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 1, 0, 0), renderPass.color, 0, 0); @@ -375,14 +399,16 @@ TEST_P(PushConstantTest, SimultaneousVertexAndFragmentConstants) { dawn::RenderPipeline pipeline = MakeTestRenderPipeline(layout, spec, spec); uint32_t two = 2; - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPass.renderPassInfo) - .SetPushConstants(dawn::ShaderStageBit::Vertex | dawn::ShaderStageBit::Fragment, 0, 1, &two) - .SetRenderPipeline(pipeline) - .DrawArrays(1, 1, 0, 0) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo); + pass.SetPushConstants(dawn::ShaderStageBit::Vertex | dawn::ShaderStageBit::Fragment, 0, 1, &two); + pass.SetRenderPipeline(pipeline); + pass.DrawArrays(1, 1, 0, 0); + pass.EndPass(); + } + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); EXPECT_PIXEL_RGBA8_EQ(RGBA8(1, 1, 0, 0), renderPass.color, 0, 0); diff --git a/src/tests/end2end/RenderPassLoadOpTests.cpp b/src/tests/end2end/RenderPassLoadOpTests.cpp index 4c80487dea..ceea243e32 100644 --- a/src/tests/end2end/RenderPassLoadOpTests.cpp +++ b/src/tests/end2end/RenderPassLoadOpTests.cpp @@ -31,7 +31,7 @@ class DrawQuad { pipelineLayout = utils::MakeBasicPipelineLayout(*device, nullptr); } - void Draw(dawn::CommandBufferBuilder* builder) { + void Draw(dawn::RenderPassEncoder* pass) { auto renderPipeline = device->CreateRenderPipelineBuilder() .SetColorAttachmentFormat(0, dawn::TextureFormat::R8G8B8A8Unorm) .SetLayout(pipelineLayout) @@ -39,8 +39,8 @@ class DrawQuad { .SetStage(dawn::ShaderStage::Fragment, fsModule, "main") .GetResult(); - builder->SetRenderPipeline(renderPipeline); - builder->DrawArrays(6, 1, 0, 0); + pass->SetRenderPipeline(renderPipeline); + pass->DrawArrays(6, 1, 0, 0); } private: @@ -117,24 +117,20 @@ TEST_P(RenderPassLoadOpTests, ColorClearThenLoadAndDraw) { .SetColorAttachmentClearColor(0, 0.0f, 0.0f, 0.0f, 0.0f) .GetResult(); - auto commandsClearZero = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPassClearZero) - // Clear should occur implicitly - // Store should occur implicitly - .EndRenderPass() - .GetResult(); + auto commandsClearZeroBuilder = device.CreateCommandBufferBuilder(); + auto clearZeroPass = commandsClearZeroBuilder.BeginRenderPass(renderPassClearZero); + clearZeroPass.EndPass(); + auto commandsClearZero = commandsClearZeroBuilder.GetResult(); auto renderPassClearGreen = device.CreateRenderPassDescriptorBuilder() .SetColorAttachment(0, renderTargetView, dawn::LoadOp::Clear) .SetColorAttachmentClearColor(0, 0.0f, 1.0f, 0.0f, 1.0f) .GetResult(); - auto commandsClearGreen = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPassClearGreen) - // Clear should occur implicitly - // Store should occur implicitly - .EndRenderPass() - .GetResult(); + auto commandsClearGreenBuilder = device.CreateCommandBufferBuilder(); + auto clearGreenPass = commandsClearGreenBuilder.BeginRenderPass(renderPassClearGreen); + clearGreenPass.EndPass(); + auto commandsClearGreen = commandsClearGreenBuilder.GetResult(); queue.Submit(1, &commandsClearZero); EXPECT_TEXTURE_RGBA8_EQ(expectZero.data(), renderTarget, 0, 0, kRTSize, kRTSize, 0); @@ -150,15 +146,11 @@ TEST_P(RenderPassLoadOpTests, ColorClearThenLoadAndDraw) { dawn::CommandBuffer commandsLoad; { - auto builder = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPassLoad) - // Load should occur implicitly - .Clone(); - blueQuad.Draw(&builder); - commandsLoad = builder - // Store should occur implicitly - .EndRenderPass() - .GetResult(); + auto builder = device.CreateCommandBufferBuilder(); + auto pass = builder.BeginRenderPass(renderPassLoad); + blueQuad.Draw(&pass); + pass.EndPass(); + commandsLoad = builder.GetResult(); } queue.Submit(1, &commandsLoad); diff --git a/src/tests/end2end/SamplerTests.cpp b/src/tests/end2end/SamplerTests.cpp index f6c0d10dac..3f4a4be5d2 100644 --- a/src/tests/end2end/SamplerTests.cpp +++ b/src/tests/end2end/SamplerTests.cpp @@ -127,14 +127,16 @@ protected: .SetTextureViews(1, 1, &mTextureView) .GetResult(); - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginRenderPass(mRenderPass.renderPassInfo) - .SetRenderPipeline(mPipeline) - .SetBindGroup(0, bindGroup) - .DrawArrays(6, 1, 0, 0) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(mRenderPass.renderPassInfo); + pass.SetRenderPipeline(mPipeline); + pass.SetBindGroup(0, bindGroup); + pass.DrawArrays(6, 1, 0, 0); + pass.EndPass(); + } + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); RGBA8 expectedU2(u.mExpected2, u.mExpected2, u.mExpected2, 255); diff --git a/src/tests/end2end/ScissorTests.cpp b/src/tests/end2end/ScissorTests.cpp index 3a4fc32cac..5052c4c465 100644 --- a/src/tests/end2end/ScissorTests.cpp +++ b/src/tests/end2end/ScissorTests.cpp @@ -51,13 +51,15 @@ TEST_P(ScissorTest, DefaultsToWholeRenderTarget) { utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, 100, 100); dawn::RenderPipeline pipeline = CreateQuadPipeline(renderPass.colorFormat); - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPass.renderPassInfo) - .SetRenderPipeline(pipeline) - .DrawArrays(6, 1, 0, 0) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo); + pass.SetRenderPipeline(pipeline); + pass.DrawArrays(6, 1, 0, 0); + pass.EndPass(); + } + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 255, 0, 255), renderPass.color, 0, 0); @@ -71,14 +73,16 @@ TEST_P(ScissorTest, LargerThanAttachment) { utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, 100, 100); dawn::RenderPipeline pipeline = CreateQuadPipeline(renderPass.colorFormat); - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPass.renderPassInfo) - .SetRenderPipeline(pipeline) - .SetScissorRect(0, 0, 200, 200) - .DrawArrays(6, 1, 0, 0) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo); + pass.SetRenderPipeline(pipeline); + pass.SetScissorRect(0, 0, 200, 200); + pass.DrawArrays(6, 1, 0, 0); + pass.EndPass(); + } + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 255, 0, 255), renderPass.color, 0, 0); @@ -95,14 +99,16 @@ TEST_P(ScissorTest, EmptyRect) { utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, 2, 2); dawn::RenderPipeline pipeline = CreateQuadPipeline(renderPass.colorFormat); - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPass.renderPassInfo) - .SetRenderPipeline(pipeline) - .SetScissorRect(0, 0, 0, 0) - .DrawArrays(6, 1, 0, 0) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo); + pass.SetRenderPipeline(pipeline); + pass.SetScissorRect(0, 0, 0, 0); + pass.DrawArrays(6, 1, 0, 0); + pass.EndPass(); + } + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 0, 0, 0), renderPass.color, 0, 0); @@ -121,14 +127,16 @@ TEST_P(ScissorTest, PartialRect) { constexpr uint32_t kW = 5; constexpr uint32_t kH = 13; - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPass.renderPassInfo) - .SetRenderPipeline(pipeline) - .SetScissorRect(kX, kY, kW, kH) - .DrawArrays(6, 1, 0, 0) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo); + pass.SetRenderPipeline(pipeline); + pass.SetScissorRect(kX, kY, kW, kH); + pass.DrawArrays(6, 1, 0, 0); + pass.EndPass(); + } + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); // Test the two opposite corners of the scissor box. With one pixel inside and on outside @@ -144,18 +152,22 @@ TEST_P(ScissorTest, NoInheritanceBetweenRenderPass) { utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, 100, 100); dawn::RenderPipeline pipeline = CreateQuadPipeline(renderPass.colorFormat); - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - // RenderPass 1 set the scissor - .BeginRenderPass(renderPass.renderPassInfo) - .SetScissorRect(0, 0, 0, 0) - .EndRenderPass() - // RenderPass 2 draw a full quad, it shouldn't be scissored - .BeginRenderPass(renderPass.renderPassInfo) - .SetRenderPipeline(pipeline) - .DrawArrays(6, 1, 0, 0) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + // RenderPass 1 set the scissor + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo); + pass.SetScissorRect(0, 0, 0, 0); + pass.EndPass(); + } + // RenderPass 2 draw a full quad, it shouldn't be scissored + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo); + pass.SetRenderPipeline(pipeline); + pass.DrawArrays(6, 1, 0, 0); + pass.EndPass(); + } + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 255, 0, 255), renderPass.color, 0, 0); diff --git a/src/tests/end2end/ViewportOrientationTests.cpp b/src/tests/end2end/ViewportOrientationTests.cpp index 084c1de11f..e85f5ac6d6 100644 --- a/src/tests/end2end/ViewportOrientationTests.cpp +++ b/src/tests/end2end/ViewportOrientationTests.cpp @@ -42,13 +42,15 @@ TEST_P(ViewportOrientationTests, OriginAt0x0) { .SetPrimitiveTopology(dawn::PrimitiveTopology::PointList) .GetResult(); - dawn::CommandBuffer commands = device.CreateCommandBufferBuilder() - .BeginRenderPass(renderPass.renderPassInfo) - .SetRenderPipeline(pipeline) - .DrawArrays(1, 1, 0, 0) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder(); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo); + pass.SetRenderPipeline(pipeline); + pass.DrawArrays(1, 1, 0, 0); + pass.EndPass(); + } + dawn::CommandBuffer commands = builder.GetResult(); queue.Submit(1, &commands); EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 255, 0, 255), renderPass.color, 0, 0); diff --git a/src/tests/unittests/WireTests.cpp b/src/tests/unittests/WireTests.cpp index c1be1e6107..ba29834e1b 100644 --- a/src/tests/unittests/WireTests.cpp +++ b/src/tests/unittests/WireTests.cpp @@ -250,13 +250,18 @@ TEST_F(WireTests, ReleaseCalledOnRefCount0) { // Test that the wire is able to send numerical values TEST_F(WireTests, ValueArgument) { dawnCommandBufferBuilder builder = dawnDeviceCreateCommandBufferBuilder(device); - dawnCommandBufferBuilderDispatch(builder, 1, 2, 3); + dawnComputePassEncoder pass = dawnCommandBufferBuilderBeginComputePass(builder); + dawnComputePassEncoderDispatch(pass, 1, 2, 3); dawnCommandBufferBuilder apiBuilder = api.GetNewCommandBufferBuilder(); EXPECT_CALL(api, DeviceCreateCommandBufferBuilder(apiDevice)) .WillOnce(Return(apiBuilder)); - EXPECT_CALL(api, CommandBufferBuilderDispatch(apiBuilder, 1, 2, 3)) + dawnComputePassEncoder apiPass = api.GetNewComputePassEncoder(); + EXPECT_CALL(api, CommandBufferBuilderBeginComputePass(apiBuilder)) + .WillOnce(Return(apiPass)); + + EXPECT_CALL(api, ComputePassEncoderDispatch(apiPass, 1, 2, 3)) .Times(1); FlushClient(); @@ -281,13 +286,18 @@ bool CheckPushConstantValues(const uint32_t* values) { TEST_F(WireTests, ValueArrayArgument) { dawnCommandBufferBuilder builder = dawnDeviceCreateCommandBufferBuilder(device); - dawnCommandBufferBuilderSetPushConstants(builder, DAWN_SHADER_STAGE_BIT_VERTEX, 0, 4, testPushConstantValues); + dawnComputePassEncoder pass = dawnCommandBufferBuilderBeginComputePass(builder); + dawnComputePassEncoderSetPushConstants(pass, DAWN_SHADER_STAGE_BIT_VERTEX, 0, 4, testPushConstantValues); dawnCommandBufferBuilder apiBuilder = api.GetNewCommandBufferBuilder(); EXPECT_CALL(api, DeviceCreateCommandBufferBuilder(apiDevice)) .WillOnce(Return(apiBuilder)); - EXPECT_CALL(api, CommandBufferBuilderSetPushConstants(apiBuilder, DAWN_SHADER_STAGE_BIT_VERTEX, 0, 4, ResultOf(CheckPushConstantValues, Eq(true)))); + dawnComputePassEncoder apiPass = api.GetNewComputePassEncoder(); + EXPECT_CALL(api, CommandBufferBuilderBeginComputePass(apiBuilder)) + .WillOnce(Return(apiPass)); + + EXPECT_CALL(api, ComputePassEncoderSetPushConstants(apiPass, DAWN_SHADER_STAGE_BIT_VERTEX, 0, 4, ResultOf(CheckPushConstantValues, Eq(true)))); FlushClient(); } @@ -318,28 +328,33 @@ TEST_F(WireTests, CStringArgument) { } // Test that the wire is able to send objects as value arguments -TEST_F(WireTests, ObjectAsValueArgument) { +TEST_F(WireTests, DISABLED_ObjectAsValueArgument) { // Create pipeline - dawnRenderPipelineBuilder pipelineBuilder = dawnDeviceCreateRenderPipelineBuilder(device); - dawnRenderPipeline pipeline = dawnRenderPipelineBuilderGetResult(pipelineBuilder); + dawnComputePipelineDescriptor pipelineDesc; + pipelineDesc.nextInChain = nullptr; + pipelineDesc.layout = nullptr; + pipelineDesc.entryPoint = "main"; + pipelineDesc.module = nullptr; + dawnComputePipeline pipeline = dawnDeviceCreateComputePipeline(device, &pipelineDesc); - dawnRenderPipelineBuilder apiPipelineBuilder = api.GetNewRenderPipelineBuilder(); - EXPECT_CALL(api, DeviceCreateRenderPipelineBuilder(apiDevice)) - .WillOnce(Return(apiPipelineBuilder)); - - dawnRenderPipeline apiPipeline = api.GetNewRenderPipeline(); - EXPECT_CALL(api, RenderPipelineBuilderGetResult(apiPipelineBuilder)) + dawnComputePipeline apiPipeline = api.GetNewComputePipeline(); + EXPECT_CALL(api, DeviceCreateComputePipeline(apiDevice, _)) .WillOnce(Return(apiPipeline)); // Create command buffer builder, setting pipeline dawnCommandBufferBuilder cmdBufBuilder = dawnDeviceCreateCommandBufferBuilder(device); - dawnCommandBufferBuilderSetRenderPipeline(cmdBufBuilder, pipeline); + dawnComputePassEncoder pass = dawnCommandBufferBuilderBeginComputePass(cmdBufBuilder); + dawnComputePassEncoderSetComputePipeline(pass, pipeline); dawnCommandBufferBuilder apiCmdBufBuilder = api.GetNewCommandBufferBuilder(); EXPECT_CALL(api, DeviceCreateCommandBufferBuilder(apiDevice)) .WillOnce(Return(apiCmdBufBuilder)); - EXPECT_CALL(api, CommandBufferBuilderSetRenderPipeline(apiCmdBufBuilder, apiPipeline)); + dawnComputePassEncoder apiPass = api.GetNewComputePassEncoder(); + EXPECT_CALL(api, CommandBufferBuilderBeginComputePass(apiCmdBufBuilder)) + .WillOnce(Return(apiPass)); + + EXPECT_CALL(api, ComputePassEncoderSetComputePipeline(apiPass, apiPipeline)); FlushClient(); } @@ -472,23 +487,33 @@ TEST_F(WireTests, StructureOfStructureArrayArgument) { // Test that the server doesn't forward calls to error objects or with error objects // Also test that when GetResult is called on an error builder, the error callback is fired -TEST_F(WireTests, CallsSkippedAfterBuilderError) { +// TODO(cwallez@chromium.org): This test is disabled because the introduction of encoders breaks +// the assumptions of the "builder error" handling that a builder is self-contained. We need to +// revisit this once the new error handling is in place. +TEST_F(WireTests, DISABLED_CallsSkippedAfterBuilderError) { dawnCommandBufferBuilder cmdBufBuilder = dawnDeviceCreateCommandBufferBuilder(device); dawnCommandBufferBuilderSetErrorCallback(cmdBufBuilder, ToMockBuilderErrorCallback, 1, 2); + dawnRenderPassEncoder pass = dawnCommandBufferBuilderBeginRenderPass(cmdBufBuilder, nullptr); + dawnBufferBuilder bufferBuilder = dawnDeviceCreateBufferBuilderForTesting(device); dawnBufferBuilderSetErrorCallback(bufferBuilder, ToMockBuilderErrorCallback, 3, 4); dawnBuffer buffer = dawnBufferBuilderGetResult(bufferBuilder); // Hey look an error! // These calls will be skipped because of the error dawnBufferSetSubData(buffer, 0, 0, nullptr); - dawnCommandBufferBuilderSetIndexBuffer(cmdBufBuilder, buffer, 0); + dawnRenderPassEncoderSetIndexBuffer(pass, buffer, 0); + dawnRenderPassEncoderEndPass(pass); dawnCommandBufferBuilderGetResult(cmdBufBuilder); dawnCommandBufferBuilder apiCmdBufBuilder = api.GetNewCommandBufferBuilder(); EXPECT_CALL(api, DeviceCreateCommandBufferBuilder(apiDevice)) .WillOnce(Return(apiCmdBufBuilder)); + dawnRenderPassEncoder apiPass = api.GetNewRenderPassEncoder(); + EXPECT_CALL(api, CommandBufferBuilderBeginRenderPass(apiCmdBufBuilder, _)) + .WillOnce(Return(apiPass)); + dawnBufferBuilder apiBufferBuilder = api.GetNewBufferBuilder(); EXPECT_CALL(api, DeviceCreateBufferBuilderForTesting(apiDevice)) .WillOnce(Return(apiBufferBuilder)); @@ -501,7 +526,7 @@ TEST_F(WireTests, CallsSkippedAfterBuilderError) { })); EXPECT_CALL(api, BufferSetSubData(_, _, _, _)).Times(0); - EXPECT_CALL(api, CommandBufferBuilderSetIndexBuffer(_, _, _)).Times(0); + EXPECT_CALL(api, RenderPassEncoderSetIndexBuffer(_, _, _)).Times(0); EXPECT_CALL(api, CommandBufferBuilderGetResult(_)).Times(0); FlushClient(); diff --git a/src/tests/unittests/validation/CommandBufferValidationTests.cpp b/src/tests/unittests/validation/CommandBufferValidationTests.cpp index 3f4ca902b4..e3e319e351 100644 --- a/src/tests/unittests/validation/CommandBufferValidationTests.cpp +++ b/src/tests/unittests/validation/CommandBufferValidationTests.cpp @@ -27,11 +27,16 @@ TEST_F(CommandBufferValidationTest, Empty) { TEST_F(CommandBufferValidationTest, RenderPass) { auto renderpass = CreateSimpleRenderPass(); - AssertWillBeSuccess(device.CreateCommandBufferBuilder()) - .BeginRenderPass(renderpass) - .EndRenderPass() - .GetResult(); - AssertWillBeError(device.CreateCommandBufferBuilder()) - .BeginRenderPass(renderpass) - .GetResult(); + { + dawn::CommandBufferBuilder builder = AssertWillBeSuccess(device.CreateCommandBufferBuilder()); + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderpass); + pass.EndPass(); + builder.GetResult(); + } + + { + dawn::CommandBufferBuilder builder = AssertWillBeError(device.CreateCommandBufferBuilder()); + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderpass); + builder.GetResult(); + } } diff --git a/src/tests/unittests/validation/DynamicStateCommandValidationTests.cpp b/src/tests/unittests/validation/DynamicStateCommandValidationTests.cpp index fd2b28c73b..4d1c1ef429 100644 --- a/src/tests/unittests/validation/DynamicStateCommandValidationTests.cpp +++ b/src/tests/unittests/validation/DynamicStateCommandValidationTests.cpp @@ -17,36 +17,30 @@ class SetScissorRectTest : public ValidationTest { }; -// Test to check that SetScissor can only be used inside render passes -TEST_F(SetScissorRectTest, AllowedOnlyInRenderPass) { +// Test to check basic use of SetScissor +TEST_F(SetScissorRectTest, Success) { DummyRenderPass renderPass = CreateDummyRenderPass(); - AssertWillBeSuccess(device.CreateCommandBufferBuilder()) - .BeginRenderPass(renderPass.renderPass) - .SetScissorRect(0, 0, 1, 1) - .EndRenderPass() - .GetResult(); - - AssertWillBeError(device.CreateCommandBufferBuilder()) - .SetScissorRect(0, 0, 1, 1) - .GetResult(); - - AssertWillBeError(device.CreateCommandBufferBuilder()) - .BeginComputePass() - .SetScissorRect(0, 0, 1, 1) - .EndComputePass() - .GetResult(); + dawn::CommandBufferBuilder builder = AssertWillBeSuccess(device.CreateCommandBufferBuilder()); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPass); + pass.SetScissorRect(0, 0, 1, 1); + pass.EndPass(); + } + builder.GetResult(); } // Test to check that an empty scissor is allowed TEST_F(SetScissorRectTest, EmptyScissor) { DummyRenderPass renderPass = CreateDummyRenderPass(); - AssertWillBeSuccess(device.CreateCommandBufferBuilder()) - .BeginRenderPass(renderPass.renderPass) - .SetScissorRect(0, 0, 0, 0) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = AssertWillBeSuccess(device.CreateCommandBufferBuilder()); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPass); + pass.SetScissorRect(0, 0, 0, 0); + pass.EndPass(); + } + builder.GetResult(); } // Test to check that a scissor larger than the framebuffer is allowed @@ -55,79 +49,69 @@ TEST_F(SetScissorRectTest, EmptyScissor) { TEST_F(SetScissorRectTest, ScissorLargerThanFramebuffer) { DummyRenderPass renderPass = CreateDummyRenderPass(); - AssertWillBeSuccess(device.CreateCommandBufferBuilder()) - .BeginRenderPass(renderPass.renderPass) - .SetScissorRect(0, 0, renderPass.width + 1, renderPass.height + 1) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = AssertWillBeSuccess(device.CreateCommandBufferBuilder()); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPass); + pass.SetScissorRect(0, 0, renderPass.width + 1, renderPass.height + 1); + pass.EndPass(); + } + builder.GetResult(); } class SetBlendColorTest : public ValidationTest { }; -// Test to check that SetBlendColor can only be used inside render passes -TEST_F(SetBlendColorTest, AllowedOnlyInRenderPass) { +// Test to check basic use of SetBlendColor +TEST_F(SetBlendColorTest, Success) { DummyRenderPass renderPass = CreateDummyRenderPass(); - AssertWillBeSuccess(device.CreateCommandBufferBuilder()) - .BeginRenderPass(renderPass.renderPass) - .SetBlendColor(0.0f, 0.0f, 0.0f, 0.0f) - .EndRenderPass() - .GetResult(); - - AssertWillBeError(device.CreateCommandBufferBuilder()) - .SetBlendColor(0.0f, 0.0f, 0.0f, 0.0f) - .GetResult(); - - AssertWillBeError(device.CreateCommandBufferBuilder()) - .BeginComputePass() - .SetBlendColor(0.0f, 0.0f, 0.0f, 0.0f) - .EndComputePass() - .GetResult(); + dawn::CommandBufferBuilder builder = AssertWillBeSuccess(device.CreateCommandBufferBuilder()); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPass); + pass.SetBlendColor(0.0f, 0.0f, 0.0f, 0.0f); + pass.EndPass(); + } + builder.GetResult(); } // Test that SetBlendColor allows any value, large, small or negative TEST_F(SetBlendColorTest, AnyValueAllowed) { DummyRenderPass renderPass = CreateDummyRenderPass(); - AssertWillBeSuccess(device.CreateCommandBufferBuilder()) - .BeginRenderPass(renderPass.renderPass) - .SetBlendColor(-1.0f, 42.0f, -0.0f, 0.0f) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = AssertWillBeSuccess(device.CreateCommandBufferBuilder()); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPass); + pass.SetBlendColor(-1.0f, 42.0f, -0.0f, 0.0f); + pass.EndPass(); + } + builder.GetResult(); } class SetStencilReferenceTest : public ValidationTest { }; -// Test to check that SetStencilReference can only be used inside render passes -TEST_F(SetStencilReferenceTest, AllowedOnlyInRenderPass) { +// Test to check basic use of SetBlendColor +TEST_F(SetStencilReferenceTest, Success) { DummyRenderPass renderPass = CreateDummyRenderPass(); - AssertWillBeSuccess(device.CreateCommandBufferBuilder()) - .BeginRenderPass(renderPass.renderPass) - .SetStencilReference(0) - .EndRenderPass() - .GetResult(); - - AssertWillBeError(device.CreateCommandBufferBuilder()) - .SetStencilReference(0) - .GetResult(); - - AssertWillBeError(device.CreateCommandBufferBuilder()) - .BeginComputePass() - .SetStencilReference(0) - .EndComputePass() - .GetResult(); + dawn::CommandBufferBuilder builder = AssertWillBeSuccess(device.CreateCommandBufferBuilder()); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPass); + pass.SetStencilReference(0); + pass.EndPass(); + } + builder.GetResult(); } // Test that SetStencilReference allows any bit to be set TEST_F(SetStencilReferenceTest, AllBitsAllowed) { DummyRenderPass renderPass = CreateDummyRenderPass(); - AssertWillBeSuccess(device.CreateCommandBufferBuilder()) - .BeginRenderPass(renderPass.renderPass) - .SetStencilReference(0xFFFFFFFF) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = AssertWillBeSuccess(device.CreateCommandBufferBuilder()); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPass); + pass.SetStencilReference(0xFFFFFFFF); + pass.EndPass(); + } + builder.GetResult(); } diff --git a/src/tests/unittests/validation/PushConstantsValidationTests.cpp b/src/tests/unittests/validation/PushConstantsValidationTests.cpp index ec9e63b6c8..fac6de2bcc 100644 --- a/src/tests/unittests/validation/PushConstantsValidationTests.cpp +++ b/src/tests/unittests/validation/PushConstantsValidationTests.cpp @@ -46,28 +46,36 @@ class PushConstantTest : public ValidationTest { TEST_F(PushConstantTest, Success) { DummyRenderPass renderpassData = CreateDummyRenderPass(); - AssertWillBeSuccess(device.CreateCommandBufferBuilder()) - // PushConstants in a compute pass - .BeginComputePass() - .SetPushConstants(dawn::ShaderStageBit::Compute, 0, 1, constants) - .EndComputePass() + dawn::CommandBufferBuilder builder = AssertWillBeSuccess(device.CreateCommandBufferBuilder()); + // PushConstants in a compute pass + { + dawn::ComputePassEncoder pass = builder.BeginComputePass(); + pass.SetPushConstants(dawn::ShaderStageBit::Compute, 0, 1, constants); + pass.EndPass(); + } - // PushConstants in a render pass - .BeginRenderPass(renderpassData.renderPass) - .SetPushConstants(dawn::ShaderStageBit::Vertex | dawn::ShaderStageBit::Fragment, 0, 1, constants) - .EndRenderPass() + // PushConstants in a render pass + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderpassData.renderPass); + pass.SetPushConstants(dawn::ShaderStageBit::Vertex | dawn::ShaderStageBit::Fragment, 0, 1, constants); + pass.EndPass(); + } - // Setting all constants - .BeginComputePass() - .SetPushConstants(dawn::ShaderStageBit::Compute, 0, kMaxPushConstants, constants) - .EndComputePass() + // Setting all constants + { + dawn::ComputePassEncoder pass = builder.BeginComputePass(); + pass.SetPushConstants(dawn::ShaderStageBit::Compute, 0, kMaxPushConstants, constants); + pass.EndPass(); + } - // Setting constants at an offset - .BeginComputePass() - .SetPushConstants(dawn::ShaderStageBit::Compute, kMaxPushConstants - 1, 1, constants) - .EndComputePass() + // Setting constants at an offset + { + dawn::ComputePassEncoder pass = builder.BeginComputePass(); + pass.SetPushConstants(dawn::ShaderStageBit::Compute, kMaxPushConstants - 1, 1, constants); + pass.EndPass(); + } - .GetResult(); + builder.GetResult(); } // Test check for constants being set out of bounds @@ -76,45 +84,29 @@ TEST_F(PushConstantTest, SetPushConstantsOOB) { // Control case: setting all constants { - AssertWillBeSuccess(device.CreateCommandBufferBuilder()) - .BeginComputePass() - .SetPushConstants(dawn::ShaderStageBit::Compute, 0, kMaxPushConstants, constants) - .EndComputePass() - .GetResult(); + dawn::CommandBufferBuilder builder = AssertWillBeSuccess(device.CreateCommandBufferBuilder()); + dawn::ComputePassEncoder pass = builder.BeginComputePass(); + pass.SetPushConstants(dawn::ShaderStageBit::Compute, 0, kMaxPushConstants, constants); + pass.EndPass(); + builder.GetResult(); } // OOB because count is too big. { - AssertWillBeError(device.CreateCommandBufferBuilder()) - .BeginComputePass() - .SetPushConstants(dawn::ShaderStageBit::Compute, 0, kMaxPushConstants + 1, constants) - .EndComputePass() - .GetResult(); + dawn::CommandBufferBuilder builder = AssertWillBeError(device.CreateCommandBufferBuilder()); + dawn::ComputePassEncoder pass = builder.BeginComputePass(); + pass.SetPushConstants(dawn::ShaderStageBit::Compute, 0, kMaxPushConstants + 1, constants); + pass.EndPass(); + builder.GetResult(); } // OOB because of the offset. { - AssertWillBeError(device.CreateCommandBufferBuilder()) - .BeginComputePass() - .SetPushConstants(dawn::ShaderStageBit::Compute, 1, kMaxPushConstants, constants) - .EndComputePass() - .GetResult(); - } -} - -// Test which places push constants can be set -TEST_F(PushConstantTest, NotInPass) { - DummyRenderPass renderpassData = CreateDummyRenderPass(); - - // Setting outside of any pass is invalid. - { - AssertWillBeError(device.CreateCommandBufferBuilder()) - .SetPushConstants(dawn::ShaderStageBit::Compute, 0, 1, constants) - .GetResult(); - - AssertWillBeError(device.CreateCommandBufferBuilder()) - .SetPushConstants(dawn::ShaderStageBit::Vertex, 0, 1, constants) - .GetResult(); + dawn::CommandBufferBuilder builder = AssertWillBeError(device.CreateCommandBufferBuilder()); + dawn::ComputePassEncoder pass = builder.BeginComputePass(); + pass.SetPushConstants(dawn::ShaderStageBit::Compute, 1, kMaxPushConstants, constants); + pass.EndPass(); + builder.GetResult(); } } @@ -122,29 +114,29 @@ TEST_F(PushConstantTest, NotInPass) { TEST_F(PushConstantTest, StageForComputePass) { // Control case: setting to the compute stage in compute passes { - AssertWillBeSuccess(device.CreateCommandBufferBuilder()) - .BeginComputePass() - .SetPushConstants(dawn::ShaderStageBit::Compute, 0, 1, constants) - .EndComputePass() - .GetResult(); + dawn::CommandBufferBuilder builder = AssertWillBeSuccess(device.CreateCommandBufferBuilder()); + dawn::ComputePassEncoder pass = builder.BeginComputePass(); + pass.SetPushConstants(dawn::ShaderStageBit::Compute, 0, 1, constants); + pass.EndPass(); + builder.GetResult(); } // Graphics stages are disallowed { - AssertWillBeError(device.CreateCommandBufferBuilder()) - .BeginComputePass() - .SetPushConstants(dawn::ShaderStageBit::Vertex, 0, 1, constants) - .EndComputePass() - .GetResult(); + dawn::CommandBufferBuilder builder = AssertWillBeError(device.CreateCommandBufferBuilder()); + dawn::ComputePassEncoder pass = builder.BeginComputePass(); + pass.SetPushConstants(dawn::ShaderStageBit::Vertex, 0, 1, constants); + pass.EndPass(); + builder.GetResult(); } // A None shader stage mask is valid. { - AssertWillBeSuccess(device.CreateCommandBufferBuilder()) - .BeginComputePass() - .SetPushConstants(dawn::ShaderStageBit::None, 0, 1, constants) - .EndComputePass() - .GetResult(); + dawn::CommandBufferBuilder builder = AssertWillBeSuccess(device.CreateCommandBufferBuilder()); + dawn::ComputePassEncoder pass = builder.BeginComputePass(); + pass.SetPushConstants(dawn::ShaderStageBit::None, 0, 1, constants); + pass.EndPass(); + builder.GetResult(); } } @@ -154,29 +146,29 @@ TEST_F(PushConstantTest, StageForRenderPass) { // Control case: setting to vertex and fragment in render pass { - AssertWillBeSuccess(device.CreateCommandBufferBuilder()) - .BeginRenderPass(renderpassData.renderPass) - .SetPushConstants(dawn::ShaderStageBit::Vertex | dawn::ShaderStageBit::Fragment, 0, 1, constants) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = AssertWillBeSuccess(device.CreateCommandBufferBuilder()); + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderpassData.renderPass); + pass.SetPushConstants(dawn::ShaderStageBit::Vertex | dawn::ShaderStageBit::Fragment, 0, 1, constants); + pass.EndPass(); + builder.GetResult(); } // Compute stage is disallowed { - AssertWillBeError(device.CreateCommandBufferBuilder()) - .BeginRenderPass(renderpassData.renderPass) - .SetPushConstants(dawn::ShaderStageBit::Compute, 0, 1, constants) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = AssertWillBeError(device.CreateCommandBufferBuilder()); + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderpassData.renderPass); + pass.SetPushConstants(dawn::ShaderStageBit::Compute, 0, 1, constants); + pass.EndPass(); + builder.GetResult(); } // A None shader stage mask is valid. { - AssertWillBeSuccess(device.CreateCommandBufferBuilder()) - .BeginRenderPass(renderpassData.renderPass) - .SetPushConstants(dawn::ShaderStageBit::None, 0, 1, constants) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = AssertWillBeSuccess(device.CreateCommandBufferBuilder()); + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderpassData.renderPass); + pass.SetPushConstants(dawn::ShaderStageBit::None, 0, 1, constants); + pass.EndPass(); + builder.GetResult(); } } diff --git a/src/tests/unittests/validation/VertexBufferValidationTests.cpp b/src/tests/unittests/validation/VertexBufferValidationTests.cpp index b3d97c6e70..014e7b0cbc 100644 --- a/src/tests/unittests/validation/VertexBufferValidationTests.cpp +++ b/src/tests/unittests/validation/VertexBufferValidationTests.cpp @@ -104,23 +104,27 @@ TEST_F(VertexBufferValidationTest, VertexInputsInheritedBetweenPipelines) { uint32_t offsets[] = { 0, 0 }; // Check failure when vertex buffer is not set - AssertWillBeError(device.CreateCommandBufferBuilder()) - .BeginRenderPass(renderpass) - .SetRenderPipeline(pipeline1) - .DrawArrays(3, 1, 0, 0) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = AssertWillBeError(device.CreateCommandBufferBuilder()); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderpass); + pass.SetRenderPipeline(pipeline1); + pass.DrawArrays(3, 1, 0, 0); + pass.EndPass(); + } + builder.GetResult(); // Check success when vertex buffer is inherited from previous pipeline - AssertWillBeSuccess(device.CreateCommandBufferBuilder()) - .BeginRenderPass(renderpass) - .SetRenderPipeline(pipeline2) - .SetVertexBuffers(0, 2, vertexBuffers.data(), offsets) - .DrawArrays(3, 1, 0, 0) - .SetRenderPipeline(pipeline1) - .DrawArrays(3, 1, 0, 0) - .EndRenderPass() - .GetResult(); + builder = AssertWillBeSuccess(device.CreateCommandBufferBuilder()); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderpass); + pass.SetRenderPipeline(pipeline2); + pass.SetVertexBuffers(0, 2, vertexBuffers.data(), offsets); + pass.DrawArrays(3, 1, 0, 0); + pass.SetRenderPipeline(pipeline1); + pass.DrawArrays(3, 1, 0, 0); + pass.EndPass(); + } + builder.GetResult(); } TEST_F(VertexBufferValidationTest, VertexInputsNotInheritedBetweenRendePasses) { @@ -137,29 +141,37 @@ TEST_F(VertexBufferValidationTest, VertexInputsNotInheritedBetweenRendePasses) { uint32_t offsets[] = { 0, 0 }; // Check success when vertex buffer is set for each render pass - AssertWillBeSuccess(device.CreateCommandBufferBuilder()) - .BeginRenderPass(renderpass) - .SetRenderPipeline(pipeline2) - .SetVertexBuffers(0, 2, vertexBuffers.data(), offsets) - .DrawArrays(3, 1, 0, 0) - .EndRenderPass() - .BeginRenderPass(renderpass) - .SetRenderPipeline(pipeline1) - .SetVertexBuffers(0, 1, vertexBuffers.data(), offsets) - .DrawArrays(3, 1, 0, 0) - .EndRenderPass() - .GetResult(); + dawn::CommandBufferBuilder builder = AssertWillBeSuccess(device.CreateCommandBufferBuilder()); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderpass); + pass.SetRenderPipeline(pipeline2); + pass.SetVertexBuffers(0, 2, vertexBuffers.data(), offsets); + pass.DrawArrays(3, 1, 0, 0); + pass.EndPass(); + } + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderpass); + pass.SetRenderPipeline(pipeline1); + pass.SetVertexBuffers(0, 1, vertexBuffers.data(), offsets); + pass.DrawArrays(3, 1, 0, 0); + pass.EndPass(); + } + builder.GetResult(); // Check failure because vertex buffer is not inherited in second subpass - AssertWillBeError(device.CreateCommandBufferBuilder()) - .BeginRenderPass(renderpass) - .SetRenderPipeline(pipeline2) - .SetVertexBuffers(0, 2, vertexBuffers.data(), offsets) - .DrawArrays(3, 1, 0, 0) - .EndRenderPass() - .BeginRenderPass(renderpass) - .SetRenderPipeline(pipeline1) - .DrawArrays(3, 1, 0, 0) - .EndRenderPass() - .GetResult(); + builder = AssertWillBeError(device.CreateCommandBufferBuilder()); + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderpass); + pass.SetRenderPipeline(pipeline2); + pass.SetVertexBuffers(0, 2, vertexBuffers.data(), offsets); + pass.DrawArrays(3, 1, 0, 0); + pass.EndPass(); + } + { + dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderpass); + pass.SetRenderPipeline(pipeline1); + pass.DrawArrays(3, 1, 0, 0); + pass.EndPass(); + } + builder.GetResult(); }