summaryrefslogtreecommitdiffstats
path: root/gfx/layers/d3d11/mlgshaders/common-vs.hlsl
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /gfx/layers/d3d11/mlgshaders/common-vs.hlsl
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'gfx/layers/d3d11/mlgshaders/common-vs.hlsl')
-rw-r--r--gfx/layers/d3d11/mlgshaders/common-vs.hlsl167
1 files changed, 167 insertions, 0 deletions
diff --git a/gfx/layers/d3d11/mlgshaders/common-vs.hlsl b/gfx/layers/d3d11/mlgshaders/common-vs.hlsl
new file mode 100644
index 0000000000..6231b525a9
--- /dev/null
+++ b/gfx/layers/d3d11/mlgshaders/common-vs.hlsl
@@ -0,0 +1,167 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_gfx_layers_d3d11_mlgshaders_common_vs_hlsl
+#define mozilla_gfx_layers_d3d11_mlgshaders_common_vs_hlsl
+
+#include "common.hlsl"
+
+cbuffer VSBufSimple : register(b0)
+{
+ float4x4 WorldTransform;
+ float2 RenderTargetOffset;
+ int SortIndexOffset;
+ uint DebugFrameNumber;
+};
+
+struct Layer {
+ float4x4 transform;
+ float4 clipRect;
+ uint4 info;
+};
+
+cbuffer Layers : register(b1)
+{
+ Layer sLayers[682];
+};
+
+cbuffer MaskRects : register(b3)
+{
+ float4 sMaskRects[4096];
+};
+
+struct VertexInfo {
+ float4 worldPos;
+ float2 screenPos;
+ float3 maskCoords;
+ float4 clipRect;
+};
+
+float3 ComputeMaskCoords(float4 aPosition, Layer aLayer)
+{
+ if (aLayer.info.x == 0) {
+ return float3(0.0, 0.0, 0.0);
+ }
+
+ float4 maskRect = sMaskRects[aLayer.info.x - 1];
+
+ // See the perspective comment in CompositorD3D11.hlsl.
+ float4x4 transform = float4x4(
+ 1.0/maskRect.z, 0.0, 0.0, -maskRect.x/maskRect.z,
+ 0.0, 1.0/maskRect.w, 0.0, -maskRect.y/maskRect.w,
+ 0.0, 0.0, 1.0, 0.0,
+ 0.0, 0.0, 0.0, 1.0);
+
+ return float3(mul(transform, aPosition / aPosition.w).xy, 1.0) * aPosition.w;
+}
+
+float2 UnitTriangleToPos(const float3 aVertex,
+ const float2 aPos1,
+ const float2 aPos2,
+ const float2 aPos3)
+{
+ return aVertex.x * aPos1 +
+ aVertex.y * aPos2 +
+ aVertex.z * aPos3;
+}
+
+float2 UnitQuadToRect(const float2 aVertex, const float4 aRect)
+{
+ return float2(aRect.x + aVertex.x * aRect.z, aRect.y + aVertex.y * aRect.w);
+}
+
+float ComputeDepth(float4 aPosition, float aSortIndex)
+{
+ // Note: this value should match ShaderDefinitionsMLGPU.h.
+ return ((aSortIndex + SortIndexOffset) / 1000000.0f) * aPosition.w;
+}
+
+// Compute the world-space, screen-space, layer-space clip, and mask
+// uv-coordinates given a layer-space vertex, id, and z-index.
+VertexInfo ComputePosition(float2 aVertex, uint aLayerId, float aSortIndex)
+{
+ Layer layer = sLayers[aLayerId];
+
+ // Translate from unit vertex to layer quad vertex.
+ float4 clipRect = layer.clipRect;
+
+ // Transform to screen coordinates.
+ float4x4 transform = layer.transform;
+ float4 layerPos = mul(transform, float4(aVertex, 0, 1));
+ float4 position = layerPos;
+ position.xyz /= position.w;
+ position.xy -= RenderTargetOffset.xy;
+ position.xyz *= position.w;
+
+ float4 worldPos = mul(WorldTransform, position);
+
+ // Depth must be computed after the world transform, since we don't want
+ // 3d transforms clobbering the z-value. We assume a viewport culling
+ // everything outside of [0, 1). Note that when depth-testing, we do not
+ // use sorting indices < 1.
+ //
+ // Note that we have to normalize this value to w=1, since the GPU will
+ // divide all values by w internally.
+ worldPos.z = ComputeDepth(worldPos, aSortIndex);
+
+ VertexInfo info;
+ info.screenPos = position.xy;
+ info.worldPos = worldPos;
+ info.maskCoords = ComputeMaskCoords(layerPos, layer);
+ info.clipRect = clipRect;
+ return info;
+}
+
+// This function takes a unit quad position and a layer rectangle, and computes
+// a clipped draw rect. It is only valid to use this function for layers with
+// rectilinear transforms that do not have masks.
+float4 ComputeClippedPosition(const float2 aVertex,
+ const float4 aRect,
+ uint aLayerId,
+ float aDepth)
+{
+ Layer layer = sLayers[aLayerId];
+
+ float4 position = float4(UnitQuadToRect(aVertex, aRect), 0, 1);
+
+ float4x4 transform = layer.transform;
+ float4 clipRect = layer.clipRect;
+
+ // Transform to screen coordinates.
+ //
+ // We clamp the draw rect to the clip. This lets us use faster shaders.
+ // For opaque shapes, it is necessary to do this anyway since we might
+ // otherwrite write transparent pixels in the pixel which would also be
+ // written to the depth buffer. We cannot use discard in the pixel shader
+ // as this would break early-z tests.
+ //
+ // Note that for some shaders, like textured shaders, it is not valid to
+ // change the draw rect like this without also clamping the texture
+ // coordinates. We take care to adjust for this in our batching code.
+ //
+ // We do not need to do this for 3D transforms since we always treat those
+ // as transparent (they are not written to the depth buffer). 3D items
+ // will always use the full clip+masking shader.
+ position = mul(transform, position);
+ position.xyz /= position.w;
+ position.xy -= RenderTargetOffset.xy;
+ position.xy = clamp(position.xy, clipRect.xy, clipRect.xy + clipRect.zw);
+ position.xyz *= position.w;
+
+ float4 worldPos = mul(WorldTransform, position);
+
+ // Depth must be computed after the world transform, since we don't want
+ // 3d transforms clobbering the z-value. We assume a viewport culling
+ // everything outside of [0, 1). Note that when depth-testing, we do not
+ // use sorting indices < 1.
+ //
+ // Note that we have to normalize this value to w=1, since the GPU will
+ // divide all values by w internally.
+ worldPos.z = ComputeDepth(worldPos, aDepth);
+
+ return worldPos;
+}
+
+#endif // mozilla_gfx_layers_d3d11_mlgshaders_common_vs_hlsl