Diff
Modified: trunk/LayoutTests/ChangeLog (244092 => 244093)
--- trunk/LayoutTests/ChangeLog 2019-04-09 19:53:35 UTC (rev 244092)
+++ trunk/LayoutTests/ChangeLog 2019-04-09 20:03:18 UTC (rev 244093)
@@ -1,3 +1,19 @@
+2019-04-09 Justin Fan <justin_...@apple.com>
+
+ [Web GPU] GPURenderPassEncoder updates: setBlendColor, setViewport, setScissorRect
+ https://bugs.webkit.org/show_bug.cgi?id=196719
+
+ Reviewed by Myles C. Maxfield.
+
+ Add blend-color-triangle-strip to set and blend with a custom blend color on the renderpass encoder.
+ Add viewport-scissor-rect-triangle-strip to draw a checkerboard by restricting the drawing viewport or scissor rectangle.
+
+ * webgpu/blend-color-triangle-strip.html: Added.
+ * webgpu/js/webgpu-functions.js:
+ (beginBasicRenderPass):
+ * webgpu/viewport-scissor-rect-triangle-strip-expected.html: Added.
+ * webgpu/viewport-scissor-rect-triangle-strip.html: Added.
+
2019-04-09 Devin Rousso <drou...@apple.com>
Unreviewed, fix test failures after r239698.
Added: trunk/LayoutTests/webgpu/blend-color-triangle-strip-expected.html (0 => 244093)
--- trunk/LayoutTests/webgpu/blend-color-triangle-strip-expected.html (rev 0)
+++ trunk/LayoutTests/webgpu/blend-color-triangle-strip-expected.html 2019-04-09 20:03:18 UTC (rev 244093)
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Reference File</title>
+<p>Pass if square canvas below is completely green.</p>
+<canvas width="400" height="400"></canvas>
+<script>
+const canvas = document.querySelector("canvas");
+const context = canvas.getContext('2d');
+
+context.fillStyle = 'rgb(0, 255, 0)';
+context.fillRect(0, 0, canvas.width, canvas.height);
+</script>
\ No newline at end of file
Added: trunk/LayoutTests/webgpu/blend-color-triangle-strip.html (0 => 244093)
--- trunk/LayoutTests/webgpu/blend-color-triangle-strip.html (rev 0)
+++ trunk/LayoutTests/webgpu/blend-color-triangle-strip.html 2019-04-09 20:03:18 UTC (rev 244093)
@@ -0,0 +1,86 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>WebGPU Hello Triangles</title>
+<meta name="assert" content="WebGPU correctly renders a green canvas.">
+<link rel="match" href=""
+<p>Pass if square canvas below is completely green.</p>
+<canvas width="400" height="400"></canvas>
+<script src=""
+<script>
+if (window.testRunner)
+ testRunner.waitUntilDone();
+
+const shaderCode = `
+#include <metal_stdlib>
+
+using namespace metal;
+
+struct Vertex
+{
+ float4 position [[position]];
+};
+
+vertex Vertex vertex_main(uint vid [[vertex_id]])
+{
+ Vertex v;
+ switch (vid) {
+ case 0:
+ v.position = float4(-1, 1, 0, 1);
+ break;
+ case 1:
+ v.position = float4(-1, -1, 0, 1);
+ break;
+ case 2:
+ v.position = float4(1, 1, 0, 1);
+ break;
+ default:
+ v.position = float4(1, -1, 0, 1);
+ }
+ return v;
+}
+
+fragment float4 fragment_main()
+{
+ return float4(0, 1, 1, 1);
+}
+`;
+
+async function test() {
+ const device = await getBasicDevice();
+ const canvas = document.querySelector("canvas");
+ const swapChain = createBasicSwapChain(canvas, device);
+ // FIXME: Replace with non-MSL shaders.
+ const shaderModule = device.createShaderModule({ code: shaderCode });
+
+ const colorStates = [{
+ format: "bgra8unorm",
+ alphaBlend: {
+ srcFactor: "blend-color",
+ dstFactor: "blend-color",
+ operation: "add"
+ },
+ colorBlend: {
+ srcFactor: "blend-color",
+ dstFactor: "blend-color",
+ operation: "add"
+ },
+ writeMask: GPUColorWriteBits.ALL
+ }];
+
+ const pipeline = createBasicPipeline(shaderModule, device, colorStates);
+ const commandEncoder = device.createCommandEncoder();
+ const passEncoder = beginBasicRenderPass(swapChain, commandEncoder);
+ passEncoder.setBlendColor({ r: 0, g: 1, b: 0, a: 1 });
+ encodeBasicCommands(passEncoder, pipeline);
+ const queue = device.getQueue();
+
+ queue.submit([commandEncoder.finish()]);
+
+ requestAnimationFrame(() => {
+ if (window.testRunner)
+ testRunner.notifyDone();
+ });
+}
+
+test();
+</script>
\ No newline at end of file
Modified: trunk/LayoutTests/webgpu/js/webgpu-functions.js (244092 => 244093)
--- trunk/LayoutTests/webgpu/js/webgpu-functions.js 2019-04-09 19:53:35 UTC (rev 244092)
+++ trunk/LayoutTests/webgpu/js/webgpu-functions.js 2019-04-09 20:03:18 UTC (rev 244093)
@@ -87,7 +87,7 @@
loadOp: "clear",
storeOp: "store",
clearColor: { r: 1.0, g: 0, b: 0, a: 1.0 }
- }
+ };
// FIXME: Flesh out the rest of WebGPURenderPassDescriptor.
return commandEncoder.beginRenderPass({ colorAttachments : [basicAttachment] });
Added: trunk/LayoutTests/webgpu/viewport-scissor-rect-triangle-strip-expected.html (0 => 244093)
--- trunk/LayoutTests/webgpu/viewport-scissor-rect-triangle-strip-expected.html (rev 0)
+++ trunk/LayoutTests/webgpu/viewport-scissor-rect-triangle-strip-expected.html 2019-04-09 20:03:18 UTC (rev 244093)
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Reference File</title>
+<p>Pass if square canvas below is a 4 by 4 blue/green checkerboard.</p>
+<canvas width="400" height="400"></canvas>
+<script>
+const canvas = document.querySelector("canvas");
+const context = canvas.getContext('2d');
+
+context.fillStyle = 'rgb(0, 255, 0)';
+context.fillRect(0, 0, canvas.width, canvas.height);
+
+const numColumns = 4;
+const numRows = 4;
+context.beginPath();
+context.fillStyle = 'rgb(0, 0, 255)';
+for (let x = 0; x < numColumns; ++x) {
+ for (let y = 0; y < numRows; ++y) {
+ if (x % 2 == 0 && y % 2 == 0 || x % 2 == 1 && y % 2 == 1)
+ context.rect(
+ x * canvas.width / numColumns,
+ y * canvas.height / numRows,
+ canvas.width / numColumns,
+ canvas.height / numRows
+ );
+ }
+}
+context.fill();
+</script>
\ No newline at end of file
Added: trunk/LayoutTests/webgpu/viewport-scissor-rect-triangle-strip.html (0 => 244093)
--- trunk/LayoutTests/webgpu/viewport-scissor-rect-triangle-strip.html (rev 0)
+++ trunk/LayoutTests/webgpu/viewport-scissor-rect-triangle-strip.html 2019-04-09 20:03:18 UTC (rev 244093)
@@ -0,0 +1,105 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>WebGPU Hello Triangles</title>
+<meta name="assert" content="WebGPU correctly renders a green canvas.">
+<link rel="match" href=""
+<p>Pass if square canvas below is a 4 by 4 blue/green checkerboard.</p>
+<canvas width="400" height="400"></canvas>
+<script src=""
+<script>
+if (window.testRunner)
+ testRunner.waitUntilDone();
+
+const shaderCode = `
+#include <metal_stdlib>
+
+using namespace metal;
+
+struct Vertex
+{
+ float4 position [[position]];
+};
+
+vertex Vertex vertex_main(uint vid [[vertex_id]])
+{
+ Vertex v;
+ switch (vid) {
+ case 0:
+ v.position = float4(-1, 1, 0, 1);
+ break;
+ case 1:
+ v.position = float4(-1, -1, 0, 1);
+ break;
+ case 2:
+ v.position = float4(1, 1, 0, 1);
+ break;
+ default:
+ v.position = float4(1, -1, 0, 1);
+ }
+ return v;
+}
+
+fragment float4 fragment_main(Vertex vertexIn [[stage_in]])
+{
+ return float4(0.0, 1.0, 0.0, 1.0);
+}
+`;
+
+async function test() {
+ const device = await getBasicDevice();
+ const canvas = document.querySelector("canvas");
+ const swapChain = createBasicSwapChain(canvas, device);
+ // FIXME: Replace with non-MSL shaders.
+ const shaderModule = device.createShaderModule({ code: shaderCode });
+ const pipeline = createBasicPipeline(shaderModule, device);
+ const commandEncoder = device.createCommandEncoder();
+ const blueAttachment = {
+ attachment: swapChain.getCurrentTexture().createDefaultView(),
+ loadOp: "clear",
+ storeOp: "store",
+ clearColor: { r: 0, g: 0, b: 1, a: 1 }
+ };
+ const passEncoder = commandEncoder.beginRenderPass({ colorAttachments: [blueAttachment] });
+ passEncoder.setPipeline(pipeline);
+
+ function drawViewport(x, y) {
+ passEncoder.setViewport(x, y, 100, 100, 0, 1);
+ passEncoder.draw(4, 1, 0, 0);
+ }
+
+ function drawScissorRect(x, y) {
+ passEncoder.setScissorRect(x, y, 100, 100);
+ passEncoder.draw(4, 1, 0, 0);
+ }
+
+ passEncoder.setScissorRect(0, 0, 200, 400);
+ drawViewport(100, 0);
+ drawViewport(0, 100);
+ drawViewport(100, 200);
+ drawViewport(0, 300);
+
+ // Draw outside of scissor rect should not appear.
+ drawViewport(200, 100);
+
+ passEncoder.setViewport(200, 0, 200, 400, 0, 1);
+ drawScissorRect(300, 0);
+ drawScissorRect(200, 100);
+ drawScissorRect(300, 200);
+ drawScissorRect(200, 300);
+
+ // Draw outside of viewport should not appear.
+ drawScissorRect(0, 0);
+
+ passEncoder.endPass();
+ const queue = device.getQueue();
+
+ queue.submit([commandEncoder.finish()]);
+
+ requestAnimationFrame(() => {
+ if (window.testRunner)
+ testRunner.notifyDone();
+ });
+}
+
+test();
+</script>
\ No newline at end of file
Modified: trunk/Source/WebCore/ChangeLog (244092 => 244093)
--- trunk/Source/WebCore/ChangeLog 2019-04-09 19:53:35 UTC (rev 244092)
+++ trunk/Source/WebCore/ChangeLog 2019-04-09 20:03:18 UTC (rev 244093)
@@ -1,3 +1,26 @@
+2019-04-09 Justin Fan <justin_...@apple.com>
+
+ [Web GPU] GPURenderPassEncoder updates: setBlendColor, setViewport, setScissorRect
+ https://bugs.webkit.org/show_bug.cgi?id=196719
+
+ Reviewed by Myles C. Maxfield.
+
+ Implement setBlendColor, setViewport, and setScissorRect for GPURenderPassEncoder.
+
+ Tests: webgpu/viewport-scissor-rect-triangle-strip.html, webgpu/blend-color-triangle-strip.html
+
+ * Modules/webgpu/WebGPURenderPassEncoder.cpp:
+ (WebCore::WebGPURenderPassEncoder::setBlendColor):
+ (WebCore::WebGPURenderPassEncoder::setViewport):
+ (WebCore::WebGPURenderPassEncoder::setScissorRect):
+ * Modules/webgpu/WebGPURenderPassEncoder.h:
+ * Modules/webgpu/WebGPURenderPassEncoder.idl:
+ * platform/graphics/gpu/GPURenderPassEncoder.h:
+ * platform/graphics/gpu/cocoa/GPURenderPassEncoderMetal.mm:
+ (WebCore::GPURenderPassEncoder::setBlendColor):
+ (WebCore::GPURenderPassEncoder::setViewport):
+ (WebCore::GPURenderPassEncoder::setScissorRect):
+
2019-04-09 Andy Estes <aes...@apple.com>
[Apple Pay] Add release logging to PaymentCoordinator
Modified: trunk/Source/WebCore/Modules/webgpu/WebGPURenderPassEncoder.cpp (244092 => 244093)
--- trunk/Source/WebCore/Modules/webgpu/WebGPURenderPassEncoder.cpp 2019-04-09 19:53:35 UTC (rev 244092)
+++ trunk/Source/WebCore/Modules/webgpu/WebGPURenderPassEncoder.cpp 2019-04-09 20:03:18 UTC (rev 244093)
@@ -28,6 +28,7 @@
#if ENABLE(WEBGPU)
+#include "GPUColor.h"
#include "GPULimits.h"
#include "GPUProgrammablePassEncoder.h"
#include "GPURenderPassEncoder.h"
@@ -60,6 +61,37 @@
m_passEncoder->setPipeline(makeRef(*pipeline.renderPipeline()));
}
+void WebGPURenderPassEncoder::setBlendColor(const GPUColor& color)
+{
+ if (!m_passEncoder) {
+ LOG(WebGPU, "GPURenderPassEncoder::setBlendColor(): Invalid operation!");
+ return;
+ }
+ m_passEncoder->setBlendColor(color);
+}
+
+void WebGPURenderPassEncoder::setViewport(float x, float y, float width, float height, float minDepth, float maxDepth)
+{
+ if (!m_passEncoder) {
+ LOG(WebGPU, "GPURenderPassEncoder::setViewport(): Invalid operation!");
+ return;
+ }
+ m_passEncoder->setViewport(x, y, width, height, minDepth, maxDepth);
+}
+
+void WebGPURenderPassEncoder::setScissorRect(unsigned x, unsigned y, unsigned width, unsigned height)
+{
+ if (!m_passEncoder) {
+ LOG(WebGPU, "GPURenderPassEncoder::setScissorRect(): Invalid operation!");
+ return;
+ }
+ if (!width || !height) {
+ LOG(WebGPU, "GPURenderPassEncoder::setScissorRect(): Width or height must be greater than 0!");
+ return;
+ }
+ m_passEncoder->setScissorRect(x, y, width, height);
+}
+
void WebGPURenderPassEncoder::setVertexBuffers(unsigned startSlot, Vector<RefPtr<WebGPUBuffer>>&& buffers, Vector<uint64_t>&& offsets)
{
#if !LOG_DISABLED
Modified: trunk/Source/WebCore/Modules/webgpu/WebGPURenderPassEncoder.h (244092 => 244093)
--- trunk/Source/WebCore/Modules/webgpu/WebGPURenderPassEncoder.h 2019-04-09 19:53:35 UTC (rev 244092)
+++ trunk/Source/WebCore/Modules/webgpu/WebGPURenderPassEncoder.h 2019-04-09 20:03:18 UTC (rev 244093)
@@ -38,11 +38,16 @@
class WebGPUBuffer;
class WebGPURenderPipeline;
+struct GPUColor;
+
class WebGPURenderPassEncoder final : public WebGPUProgrammablePassEncoder {
public:
static Ref<WebGPURenderPassEncoder> create(RefPtr<GPURenderPassEncoder>&&);
void setPipeline(const WebGPURenderPipeline&);
+ void setBlendColor(const GPUColor&);
+ void setViewport(float x, float y, float width, float height, float minDepth, float maxDepth);
+ void setScissorRect(unsigned x, unsigned y, unsigned width, unsigned height);
void setVertexBuffers(unsigned, Vector<RefPtr<WebGPUBuffer>>&&, Vector<uint64_t>&&);
void draw(unsigned vertexCount, unsigned instanceCount, unsigned firstVertex, unsigned firstInstance);
Modified: trunk/Source/WebCore/Modules/webgpu/WebGPURenderPassEncoder.idl (244092 => 244093)
--- trunk/Source/WebCore/Modules/webgpu/WebGPURenderPassEncoder.idl 2019-04-09 19:53:35 UTC (rev 244092)
+++ trunk/Source/WebCore/Modules/webgpu/WebGPURenderPassEncoder.idl 2019-04-09 20:03:18 UTC (rev 244093)
@@ -33,13 +33,20 @@
JSGenerateToJSObject
] interface WebGPURenderPassEncoder : WebGPUProgrammablePassEncoder {
void setPipeline(WebGPURenderPipeline pipeline);
+ void setBlendColor(GPUColor color);
+ // The default viewport is (0.0, 0.0, w, h, 0.0, 1.0), where w and h are the dimensions of back buffer
+ void setViewport(float x, float y, float width, float height, float minDepth, float maxDepth);
+
+ // The default scissor rectangle is (0, 0, w, h), where w and h are the dimensions of back buffer.
+ // Width and height must be greater than 0. Otherwise, an error will be generated.
+ void setScissorRect(u32 x, u32 y, u32 width, u32 height);
+
void setVertexBuffers(u32 startSlot, sequence<WebGPUBuffer> buffers, sequence<u64> offsets);
void draw(u32 vertexCount, u32 instanceCount, u32 firstVertex, u32 firstInstance);
/* Not Yet Implemented
- void setBlendColor(float r, float g, float b, float a);
void setIndexBuffer(WebGPUBuffer buffer, u64 offset);
void drawIndexed(u32 indexCount, u32 instanceCount, u32 firstIndex, i32 baseVertex, u32 firstInstance);
Modified: trunk/Source/WebCore/platform/graphics/gpu/GPURenderPassEncoder.h (244092 => 244093)
--- trunk/Source/WebCore/platform/graphics/gpu/GPURenderPassEncoder.h 2019-04-09 19:53:35 UTC (rev 244092)
+++ trunk/Source/WebCore/platform/graphics/gpu/GPURenderPassEncoder.h 2019-04-09 20:03:18 UTC (rev 244093)
@@ -42,6 +42,7 @@
class GPUBuffer;
class GPUCommandBuffer;
+struct GPUColor;
struct GPURenderPassDescriptor;
using PlatformRenderPassEncoder = MTLRenderCommandEncoder;
@@ -52,6 +53,9 @@
static RefPtr<GPURenderPassEncoder> tryCreate(Ref<GPUCommandBuffer>&&, GPURenderPassDescriptor&&);
void setPipeline(Ref<const GPURenderPipeline>&&);
+ void setBlendColor(const GPUColor&);
+ void setViewport(float x, float y, float width, float height, float minDepth, float maxDepth);
+ void setScissorRect(unsigned x, unsigned y, unsigned width, unsigned height);
void setVertexBuffers(unsigned, Vector<Ref<GPUBuffer>>&&, Vector<uint64_t>&&);
void draw(unsigned vertexCount, unsigned instanceCount, unsigned firstVertex, unsigned firstInstance);
Modified: trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPURenderPassEncoderMetal.mm (244092 => 244093)
--- trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPURenderPassEncoderMetal.mm 2019-04-09 19:53:35 UTC (rev 244092)
+++ trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPURenderPassEncoderMetal.mm 2019-04-09 20:03:18 UTC (rev 244093)
@@ -29,6 +29,7 @@
#if ENABLE(WEBGPU)
#import "GPUBuffer.h"
+#import "GPUColor.h"
#import "GPUCommandBuffer.h"
#import "GPURenderPassDescriptor.h"
#import "GPURenderPipeline.h"
@@ -204,6 +205,42 @@
m_pipeline = WTFMove(pipeline);
}
+void GPURenderPassEncoder::setBlendColor(const GPUColor& color)
+{
+ if (!m_platformRenderPassEncoder) {
+ LOG(WebGPU, "GPURenderPassEncoder::setBlendColor(): Invalid operation: Encoding is ended!");
+ return;
+ }
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS;
+ [m_platformRenderPassEncoder setBlendColorRed:color.r green:color.g blue:color.b alpha:color.a];
+ END_BLOCK_OBJC_EXCEPTIONS;
+}
+
+void GPURenderPassEncoder::setViewport(float x, float y, float width, float height, float minDepth, float maxDepth)
+{
+ if (!m_platformRenderPassEncoder) {
+ LOG(WebGPU, "GPURenderPassEncoder::setViewport(): Invalid operation: Encoding is ended!");
+ return;
+ }
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS;
+ [m_platformRenderPassEncoder setViewport: { x, y, width, height, minDepth, maxDepth }];
+ END_BLOCK_OBJC_EXCEPTIONS;
+}
+
+void GPURenderPassEncoder::setScissorRect(unsigned x, unsigned y, unsigned width, unsigned height)
+{
+ if (!m_platformRenderPassEncoder) {
+ LOG(WebGPU, "GPURenderPassEncoder::setScissorRect(): Invalid operation: Encoding is ended!");
+ return;
+ }
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS;
+ [m_platformRenderPassEncoder setScissorRect: { x, y, width, height }];
+ END_BLOCK_OBJC_EXCEPTIONS;
+}
+
void GPURenderPassEncoder::setVertexBuffers(unsigned index, Vector<Ref<GPUBuffer>>&& buffers, Vector<uint64_t>&& offsets)
{
if (!m_platformRenderPassEncoder) {