diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..d31b156d20 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +* text=auto +*.sh eol=lf +*.gn eol=lf +*.gni eol=lf diff --git a/.gitignore b/.gitignore index 1dc05c780c..9c66304c45 100644 --- a/.gitignore +++ b/.gitignore @@ -45,8 +45,6 @@ tramp *.DS_Store .AppleDouble .LSOverride -# Icon must end with two \r -Icon ._* .DocumentRevisions-V100 .fseventsd diff --git a/docs/DebugMarkers.md b/docs/DebugMarkers.md index e33d5b8350..06b3dde681 100644 --- a/docs/DebugMarkers.md +++ b/docs/DebugMarkers.md @@ -1,50 +1,50 @@ -# Debug Markers - -Dawn provides debug tooling integration for each backend. - -Debugging markers are exposed through this API: -``` -partial GPUProgrammablePassEncoder { - void pushDebugGroup(const char * markerLabel); - void popDebugGroup(); - void insertDebugMarker(const char * markerLabel); -}; -``` - -These APIs will result in silent no-ops if they are used without setting up -the execution environment properly. Each backend has a specific process -for setting up this environment. - -## D3D12 - -Debug markers on D3D12 are implemented with the [PIX Event Runtime](https://blogs.msdn.microsoft.com/pix/winpixeventruntime/). - -To enable marker functionality, you must: -1. Click the download link on https://www.nuget.org/packages/WinPixEventRuntime -2. Rename the .nupkg file to a .zip extension, then extract its contents. -3. Copy `bin\WinPixEventRuntime.dll` into the same directory as `libdawn_native.dll`. -4. Launch your application. - -You may now call the debug marker APIs mentioned above and see them from your GPU debugging tool. When using your tool, it is supported to both launch your application with the debugger attached, or attach the debugger while your application is running. - -D3D12 debug markers have been tested with [Microsoft PIX](https://devblogs.microsoft.com/pix/) and [Intel Graphics Frame Analyzer](https://software.intel.com/en-us/gpa/graphics-frame-analyzer). - -Unfortunately, PIX's UI does does not lend itself to capturing single frame applications like tests. You must enable capture from within your application. To do this in Dawn tests, pass the --begin-capture-on-startup flag to dawn_end2end_tests.exe. - -## Vulkan - -Debug markers on Vulkan are implemented with [VK_EXT_debug_marker](https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VK_EXT_debug_marker). - -To enable marker functionality, you must launch your application from your debugging tool. Attaching to an already running application is not supported. - -Vulkan markers have been tested with [RenderDoc](https://renderdoc.org/). - -## Metal - -Debug markers on Metal are used with the XCode debugger. - -To enable marker functionality, you must launch your application from XCode and use [GPU Frame Capture](https://developer.apple.com/documentation/metal/tools_profiling_and_debugging/metal_gpu_capture). - -## OpenGL - +# Debug Markers + +Dawn provides debug tooling integration for each backend. + +Debugging markers are exposed through this API: +``` +partial GPUProgrammablePassEncoder { + void pushDebugGroup(const char * markerLabel); + void popDebugGroup(); + void insertDebugMarker(const char * markerLabel); +}; +``` + +These APIs will result in silent no-ops if they are used without setting up +the execution environment properly. Each backend has a specific process +for setting up this environment. + +## D3D12 + +Debug markers on D3D12 are implemented with the [PIX Event Runtime](https://blogs.msdn.microsoft.com/pix/winpixeventruntime/). + +To enable marker functionality, you must: +1. Click the download link on https://www.nuget.org/packages/WinPixEventRuntime +2. Rename the .nupkg file to a .zip extension, then extract its contents. +3. Copy `bin\WinPixEventRuntime.dll` into the same directory as `libdawn_native.dll`. +4. Launch your application. + +You may now call the debug marker APIs mentioned above and see them from your GPU debugging tool. When using your tool, it is supported to both launch your application with the debugger attached, or attach the debugger while your application is running. + +D3D12 debug markers have been tested with [Microsoft PIX](https://devblogs.microsoft.com/pix/) and [Intel Graphics Frame Analyzer](https://software.intel.com/en-us/gpa/graphics-frame-analyzer). + +Unfortunately, PIX's UI does does not lend itself to capturing single frame applications like tests. You must enable capture from within your application. To do this in Dawn tests, pass the --begin-capture-on-startup flag to dawn_end2end_tests.exe. + +## Vulkan + +Debug markers on Vulkan are implemented with [VK_EXT_debug_marker](https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VK_EXT_debug_marker). + +To enable marker functionality, you must launch your application from your debugging tool. Attaching to an already running application is not supported. + +Vulkan markers have been tested with [RenderDoc](https://renderdoc.org/). + +## Metal + +Debug markers on Metal are used with the XCode debugger. + +To enable marker functionality, you must launch your application from XCode and use [GPU Frame Capture](https://developer.apple.com/documentation/metal/tools_profiling_and_debugging/metal_gpu_capture). + +## OpenGL + Debug markers on OpenGL are not implemented and will result in a silent no-op. This is due to low adoption of the GL_EXT_debug_marker extension in Linux device drivers. \ No newline at end of file diff --git a/src/tests/end2end/DestroyTests.cpp b/src/tests/end2end/DestroyTests.cpp index 752aba46a1..fdd968fb01 100644 --- a/src/tests/end2end/DestroyTests.cpp +++ b/src/tests/end2end/DestroyTests.cpp @@ -1,160 +1,160 @@ -// Copyright 2019 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 "tests/DawnTest.h" - -#include "utils/ComboRenderPipelineDescriptor.h" -#include "utils/DawnHelpers.h" - -constexpr uint32_t kRTSize = 4; - -class DestroyTest : public DawnTest { - protected: - void SetUp() override { - DawnTest::SetUp(); - - renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize); - - dawn::ShaderModule vsModule = - utils::CreateShaderModule(device, utils::ShaderStage::Vertex, R"( - #version 450 - layout(location = 0) in vec4 pos; - void main() { - gl_Position = pos; - })"); - - dawn::ShaderModule fsModule = - utils::CreateShaderModule(device, utils::ShaderStage::Fragment, R"( - #version 450 - layout(location = 0) out vec4 fragColor; - void main() { - fragColor = vec4(0.0, 1.0, 0.0, 1.0); - })"); - - utils::ComboRenderPipelineDescriptor descriptor(device); - descriptor.cVertexStage.module = vsModule; - descriptor.cFragmentStage.module = fsModule; - descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleStrip; - descriptor.cVertexInput.bufferCount = 1; - descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float); - descriptor.cVertexInput.cBuffers[0].attributeCount = 1; - descriptor.cVertexInput.cAttributes[0].format = dawn::VertexFormat::Float4; - descriptor.cColorStates[0]->format = renderPass.colorFormat; - - pipeline = device.CreateRenderPipeline(&descriptor); - - vertexBuffer = utils::CreateBufferFromData( - device, dawn::BufferUsageBit::Vertex, - {// The bottom left triangle - -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f}); - - dawn::CommandEncoder encoder = device.CreateCommandEncoder(); - encoder.BeginRenderPass(&renderPass.renderPassInfo).EndPass(); - dawn::CommandBuffer commands = encoder.Finish(); - queue.Submit(1, &commands); - } - - utils::BasicRenderPass renderPass; - dawn::RenderPipeline pipeline; - dawn::Buffer vertexBuffer; - - dawn::CommandBuffer CreateTriangleCommandBuffer() { - uint64_t zeroOffset = 0; - dawn::CommandEncoder encoder = device.CreateCommandEncoder(); - { - dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo); - pass.SetPipeline(pipeline); - pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset); - pass.Draw(3, 1, 0, 0); - pass.EndPass(); - } - dawn::CommandBuffer commands = encoder.Finish(); - return commands; - } -}; - -// Destroy before submit will result in error, and nothing drawn -TEST_P(DestroyTest, BufferDestroyBeforeSubmit) { - RGBA8 notFilled(0, 0, 0, 0); - - dawn::CommandBuffer commands = CreateTriangleCommandBuffer(); - vertexBuffer.Destroy(); - ASSERT_DEVICE_ERROR(queue.Submit(1, &commands)); - - EXPECT_PIXEL_RGBA8_EQ(notFilled, renderPass.color, 1, 3); -} - -// Destroy after submit will draw successfully -TEST_P(DestroyTest, BufferDestroyAfterSubmit) { - RGBA8 filled(0, 255, 0, 255); - - dawn::CommandBuffer commands = CreateTriangleCommandBuffer(); - queue.Submit(1, &commands); - - EXPECT_PIXEL_RGBA8_EQ(filled, renderPass.color, 1, 3); - vertexBuffer.Destroy(); -} - -// First submit succeeds, draws triangle, second submit fails -// after destroy is called on the buffer, pixel does not change -TEST_P(DestroyTest, BufferSubmitDestroySubmit) { - RGBA8 filled(0, 255, 0, 255); - - dawn::CommandBuffer commands = CreateTriangleCommandBuffer(); - queue.Submit(1, &commands); - EXPECT_PIXEL_RGBA8_EQ(filled, renderPass.color, 1, 3); - - vertexBuffer.Destroy(); - - // Submit fails because vertex buffer was destroyed - ASSERT_DEVICE_ERROR(queue.Submit(1, &commands)); - - // Pixel stays the same - EXPECT_PIXEL_RGBA8_EQ(filled, renderPass.color, 1, 3); -} - -// Destroy texture before submit should fail submit -TEST_P(DestroyTest, TextureDestroyBeforeSubmit) { - dawn::CommandBuffer commands = CreateTriangleCommandBuffer(); - renderPass.color.Destroy(); - ASSERT_DEVICE_ERROR(queue.Submit(1, &commands)); -} - -// Destroy after submit will draw successfully -TEST_P(DestroyTest, TextureDestroyAfterSubmit) { - RGBA8 filled(0, 255, 0, 255); - - dawn::CommandBuffer commands = CreateTriangleCommandBuffer(); - queue.Submit(1, &commands); - - EXPECT_PIXEL_RGBA8_EQ(filled, renderPass.color, 1, 3); - renderPass.color.Destroy(); -} - -// First submit succeeds, draws triangle, second submit fails -// after destroy is called on the texture -TEST_P(DestroyTest, TextureSubmitDestroySubmit) { - RGBA8 filled(0, 255, 0, 255); - - dawn::CommandBuffer commands = CreateTriangleCommandBuffer(); - queue.Submit(1, &commands); - EXPECT_PIXEL_RGBA8_EQ(filled, renderPass.color, 1, 3); - - renderPass.color.Destroy(); - - // Submit fails because texture was destroyed - ASSERT_DEVICE_ERROR(queue.Submit(1, &commands)); -} - -DAWN_INSTANTIATE_TEST(DestroyTest, D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend); +// Copyright 2019 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 "tests/DawnTest.h" + +#include "utils/ComboRenderPipelineDescriptor.h" +#include "utils/DawnHelpers.h" + +constexpr uint32_t kRTSize = 4; + +class DestroyTest : public DawnTest { + protected: + void SetUp() override { + DawnTest::SetUp(); + + renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize); + + dawn::ShaderModule vsModule = + utils::CreateShaderModule(device, utils::ShaderStage::Vertex, R"( + #version 450 + layout(location = 0) in vec4 pos; + void main() { + gl_Position = pos; + })"); + + dawn::ShaderModule fsModule = + utils::CreateShaderModule(device, utils::ShaderStage::Fragment, R"( + #version 450 + layout(location = 0) out vec4 fragColor; + void main() { + fragColor = vec4(0.0, 1.0, 0.0, 1.0); + })"); + + utils::ComboRenderPipelineDescriptor descriptor(device); + descriptor.cVertexStage.module = vsModule; + descriptor.cFragmentStage.module = fsModule; + descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleStrip; + descriptor.cVertexInput.bufferCount = 1; + descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float); + descriptor.cVertexInput.cBuffers[0].attributeCount = 1; + descriptor.cVertexInput.cAttributes[0].format = dawn::VertexFormat::Float4; + descriptor.cColorStates[0]->format = renderPass.colorFormat; + + pipeline = device.CreateRenderPipeline(&descriptor); + + vertexBuffer = utils::CreateBufferFromData( + device, dawn::BufferUsageBit::Vertex, + {// The bottom left triangle + -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f}); + + dawn::CommandEncoder encoder = device.CreateCommandEncoder(); + encoder.BeginRenderPass(&renderPass.renderPassInfo).EndPass(); + dawn::CommandBuffer commands = encoder.Finish(); + queue.Submit(1, &commands); + } + + utils::BasicRenderPass renderPass; + dawn::RenderPipeline pipeline; + dawn::Buffer vertexBuffer; + + dawn::CommandBuffer CreateTriangleCommandBuffer() { + uint64_t zeroOffset = 0; + dawn::CommandEncoder encoder = device.CreateCommandEncoder(); + { + dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo); + pass.SetPipeline(pipeline); + pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset); + pass.Draw(3, 1, 0, 0); + pass.EndPass(); + } + dawn::CommandBuffer commands = encoder.Finish(); + return commands; + } +}; + +// Destroy before submit will result in error, and nothing drawn +TEST_P(DestroyTest, BufferDestroyBeforeSubmit) { + RGBA8 notFilled(0, 0, 0, 0); + + dawn::CommandBuffer commands = CreateTriangleCommandBuffer(); + vertexBuffer.Destroy(); + ASSERT_DEVICE_ERROR(queue.Submit(1, &commands)); + + EXPECT_PIXEL_RGBA8_EQ(notFilled, renderPass.color, 1, 3); +} + +// Destroy after submit will draw successfully +TEST_P(DestroyTest, BufferDestroyAfterSubmit) { + RGBA8 filled(0, 255, 0, 255); + + dawn::CommandBuffer commands = CreateTriangleCommandBuffer(); + queue.Submit(1, &commands); + + EXPECT_PIXEL_RGBA8_EQ(filled, renderPass.color, 1, 3); + vertexBuffer.Destroy(); +} + +// First submit succeeds, draws triangle, second submit fails +// after destroy is called on the buffer, pixel does not change +TEST_P(DestroyTest, BufferSubmitDestroySubmit) { + RGBA8 filled(0, 255, 0, 255); + + dawn::CommandBuffer commands = CreateTriangleCommandBuffer(); + queue.Submit(1, &commands); + EXPECT_PIXEL_RGBA8_EQ(filled, renderPass.color, 1, 3); + + vertexBuffer.Destroy(); + + // Submit fails because vertex buffer was destroyed + ASSERT_DEVICE_ERROR(queue.Submit(1, &commands)); + + // Pixel stays the same + EXPECT_PIXEL_RGBA8_EQ(filled, renderPass.color, 1, 3); +} + +// Destroy texture before submit should fail submit +TEST_P(DestroyTest, TextureDestroyBeforeSubmit) { + dawn::CommandBuffer commands = CreateTriangleCommandBuffer(); + renderPass.color.Destroy(); + ASSERT_DEVICE_ERROR(queue.Submit(1, &commands)); +} + +// Destroy after submit will draw successfully +TEST_P(DestroyTest, TextureDestroyAfterSubmit) { + RGBA8 filled(0, 255, 0, 255); + + dawn::CommandBuffer commands = CreateTriangleCommandBuffer(); + queue.Submit(1, &commands); + + EXPECT_PIXEL_RGBA8_EQ(filled, renderPass.color, 1, 3); + renderPass.color.Destroy(); +} + +// First submit succeeds, draws triangle, second submit fails +// after destroy is called on the texture +TEST_P(DestroyTest, TextureSubmitDestroySubmit) { + RGBA8 filled(0, 255, 0, 255); + + dawn::CommandBuffer commands = CreateTriangleCommandBuffer(); + queue.Submit(1, &commands); + EXPECT_PIXEL_RGBA8_EQ(filled, renderPass.color, 1, 3); + + renderPass.color.Destroy(); + + // Submit fails because texture was destroyed + ASSERT_DEVICE_ERROR(queue.Submit(1, &commands)); +} + +DAWN_INSTANTIATE_TEST(DestroyTest, D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend); diff --git a/src/utils/ComboRenderPipelineDescriptor.h b/src/utils/ComboRenderPipelineDescriptor.h index 8be63d23e0..9448705286 100644 --- a/src/utils/ComboRenderPipelineDescriptor.h +++ b/src/utils/ComboRenderPipelineDescriptor.h @@ -1,52 +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. - -#ifndef UTILS_COMBORENDERPIPELINEDESCRIPTOR_H_ -#define UTILS_COMBORENDERPIPELINEDESCRIPTOR_H_ - -#include - -#include "common/Constants.h" - -#include - -namespace utils { - - class ComboVertexInputDescriptor : public dawn::VertexInputDescriptor { - public: - ComboVertexInputDescriptor(); - - std::array cBuffers; - std::array cAttributes; - }; - - class ComboRenderPipelineDescriptor : public dawn::RenderPipelineDescriptor { - public: - ComboRenderPipelineDescriptor(const dawn::Device& device); - - dawn::PipelineStageDescriptor cVertexStage; - dawn::PipelineStageDescriptor cFragmentStage; - - ComboVertexInputDescriptor cVertexInput; - dawn::RasterizationStateDescriptor cRasterizationState; - std::array cColorStates; - dawn::DepthStencilStateDescriptor cDepthStencilState; - - private: - dawn::ColorStateDescriptor mColorStates[kMaxColorAttachments]; - }; - -} // namespace utils - -#endif // UTILS_COMBORENDERPIPELINEDESCRIPTOR_H_ +// Copyright 2018 The Dawn Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef UTILS_COMBORENDERPIPELINEDESCRIPTOR_H_ +#define UTILS_COMBORENDERPIPELINEDESCRIPTOR_H_ + +#include + +#include "common/Constants.h" + +#include + +namespace utils { + + class ComboVertexInputDescriptor : public dawn::VertexInputDescriptor { + public: + ComboVertexInputDescriptor(); + + std::array cBuffers; + std::array cAttributes; + }; + + class ComboRenderPipelineDescriptor : public dawn::RenderPipelineDescriptor { + public: + ComboRenderPipelineDescriptor(const dawn::Device& device); + + dawn::PipelineStageDescriptor cVertexStage; + dawn::PipelineStageDescriptor cFragmentStage; + + ComboVertexInputDescriptor cVertexInput; + dawn::RasterizationStateDescriptor cRasterizationState; + std::array cColorStates; + dawn::DepthStencilStateDescriptor cDepthStencilState; + + private: + dawn::ColorStateDescriptor mColorStates[kMaxColorAttachments]; + }; + +} // namespace utils + +#endif // UTILS_COMBORENDERPIPELINEDESCRIPTOR_H_