diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /gfx/layers/d3d11/mlgshaders/common-vs.hlsl | |
parent | Initial commit. (diff) | |
download | firefox-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.hlsl | 167 |
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 |