OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/command_buffer/service/gles2_cmd_apply_framebuffer_attachment_cmaa
_intel.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_apply_framebuffer_attachment_cmaa
_intel.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "gpu/command_buffer/service/framebuffer_manager.h" | 8 #include "gpu/command_buffer/service/framebuffer_manager.h" |
9 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 9 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
10 #include "ui/gl/gl_context.h" | 10 #include "ui/gl/gl_context.h" |
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
705 float y = -1.0 + float((gl_VertexID & 2) << 1); | 705 float y = -1.0 + float((gl_VertexID & 2) << 1); |
706 gl_Position = vec4(x, y, g_Depth, 1.0); | 706 gl_Position = vec4(x, y, g_Depth, 1.0); |
707 } | 707 } |
708 ); | 708 ); |
709 | 709 |
710 const char ApplyFramebufferAttachmentCMAAINTELResourceManager::cmaa_frag_s1_[] = | 710 const char ApplyFramebufferAttachmentCMAAINTELResourceManager::cmaa_frag_s1_[] = |
711 SHADER( | 711 SHADER( |
712 precision highp float; | 712 precision highp float; |
713 precision highp int; | 713 precision highp int; |
714 | 714 |
715 \n#define SETTINGS_ALLOW_SHORT_Zs 1\n | |
716 \n#define EDGE_DETECT_THRESHOLD 13.0f\n | 715 \n#define EDGE_DETECT_THRESHOLD 13.0f\n |
717 \n#define saturate(x) clamp((x), 0.0, 1.0)\n | 716 \n#define saturate(x) clamp((x), 0.0, 1.0)\n |
718 | 717 |
719 // bind to location 0 | 718 // bind to location 0 |
720 layout(location = 0) uniform float g_Depth; | 719 layout(location = 0) uniform float g_Depth; |
721 // bind to a uniform buffer bind point 0 | 720 // bind to a uniform buffer bind point 0 |
722 layout(location = 1) uniform vec2 g_OneOverScreenSize; | 721 layout(location = 1) uniform vec2 g_OneOverScreenSize; |
723 \n#ifndef EDGE_DETECT_THRESHOLD\n | 722 \n#ifndef EDGE_DETECT_THRESHOLD\n |
724 layout(location = 2) uniform float g_ColorThreshold; | 723 layout(location = 2) uniform float g_ColorThreshold; |
725 \n#endif\n | 724 \n#endif\n |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
953 maskStopRight = 0x08u; // stop on bottom edge | 952 maskStopRight = 0x08u; // stop on bottom edge |
954 } | 953 } |
955 | 954 |
956 maskLeft = maskTraceLeft | maskStopLeft; | 955 maskLeft = maskTraceLeft | maskStopLeft; |
957 bitsContinueLeft = maskTraceLeft; | 956 bitsContinueLeft = maskTraceLeft; |
958 maskRight = maskTraceRight | maskStopRight; | 957 maskRight = maskTraceRight | maskStopRight; |
959 bitsContinueRight = maskTraceRight; | 958 bitsContinueRight = maskTraceRight; |
960 } | 959 } |
961 /////////////////////////////////////////////////////////////////////// | 960 /////////////////////////////////////////////////////////////////////// |
962 | 961 |
963 \n#ifdef SETTINGS_ALLOW_SHORT_Zs\n | 962 int i = 2; |
964 int i = 1; | |
965 \n#else\n | |
966 int i = 2; // starting from 2 because we already know it's at least 2 | |
967 \n#endif\n | |
968 for (; i < c_maxLineLength; i++) { | 963 for (; i < c_maxLineLength; i++) { |
969 uint edgeLeft = uint( | 964 uint edgeLeft = uint( |
970 texelFetch(g_src0TextureFlt, | 965 texelFetch(g_src0TextureFlt, |
971 ivec2(screenPos.xy - stepRight * i), 0).r * 255.5); | 966 ivec2(screenPos.xy - stepRight * i), 0).r * 255.5); |
972 uint edgeRight = uint( | 967 uint edgeRight = uint( |
973 texelFetch(g_src0TextureFlt, | 968 texelFetch(g_src0TextureFlt, |
974 ivec2(screenPos.xy + stepRight * (i + 1)), | 969 ivec2(screenPos.xy + stepRight * (i + 1)), |
975 0).r * 255.5); | 970 0).r * 255.5); |
976 | 971 |
977 // stop on encountering 'stopping' edge (as defined by masks) | 972 // stop on encountering 'stopping' edge (as defined by masks) |
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1526 vec4 xFroms = vec4(fromBelow, fromAbove, fromRight, fromLeft); | 1521 vec4 xFroms = vec4(fromBelow, fromAbove, fromRight, fromLeft); |
1527 | 1522 |
1528 float blurCoeff = 0.0; | 1523 float blurCoeff = 0.0; |
1529 | 1524 |
1530 // These are additional blurs that complement the main line-based | 1525 // These are additional blurs that complement the main line-based |
1531 // blurring; Unlike line-based, these do not necessarily preserve | 1526 // blurring; Unlike line-based, these do not necessarily preserve |
1532 // the total amount of screen colour as they will take | 1527 // the total amount of screen colour as they will take |
1533 // neighbouring pixel colours and apply them to the one currently | 1528 // neighbouring pixel colours and apply them to the one currently |
1534 // processed. | 1529 // processed. |
1535 | 1530 |
1536 // 1.) L-like shape. | 1531 // 1.) U-like shape (surrounded with edges from 3 sides) |
1537 // For this shape, the total amount of screen colour will be | |
1538 // preserved when this is a part of a (zigzag) diagonal line as the | |
1539 // corners from the other side will do the same and take some of | |
1540 // the current pixel's colour in return. | |
1541 // However, in the case when this is an actual corner, the pixel's | |
1542 // colour will be partially overwritten by it's 2 neighbours. | |
1543 if( numberOfEdges == 2.0 ) | |
1544 { | |
1545 // with value of 0.15, the pixel will retain approx 77% of its | |
1546 // colour and the remaining 23% will come from its 2 neighbours | |
1547 // (which are likely to be blurred too in the opposite direction) | |
1548 blurCoeff = 0.15; | |
1549 | |
1550 // Only do blending if it's L shape - if we're between two | |
1551 // parallel edges, don't do anything | |
1552 blurCoeff *= (1.0 - fromBelow * fromAbove) * | |
1553 (1.0 - fromRight * fromLeft); | |
1554 | |
1555 if (blurCoeff == 0.0) | |
1556 continue; | |
1557 | |
1558 uint packedEdgesL = packedEdgesArray[(0 + _x) * 4 + (1 + _y)]; | |
1559 uint packedEdgesB = packedEdgesArray[(1 + _x) * 4 + (0 + _y)]; | |
1560 uint packedEdgesR = packedEdgesArray[(2 + _x) * 4 + (1 + _y)]; | |
1561 uint packedEdgesT = packedEdgesArray[(1 + _x) * 4 + (2 + _y)]; | |
1562 | |
1563 // Don't blend large L shape because it would be the intended shape | |
1564 // with high probability. e.g. rectangle | |
1565 // large_l1 large_l2 large_l3 large_l4 | |
1566 // _ _ | | _ _ | |
1567 // X| X| |X |X | |
1568 // | ¯¯¯¯ ¯¯¯¯ | | |
1569 bool large_l1 = (packedEdgesC == (0x01u | 0x02u)) && | |
1570 bool(packedEdgesL & 0x02u) && | |
1571 bool(packedEdgesB & 0x01u); | |
1572 bool large_l2 = (packedEdgesC == (0x01u | 0x08u)) && | |
1573 bool(packedEdgesL & 0x08u) && | |
1574 bool(packedEdgesT & 0x01u); | |
1575 bool large_l3 = (packedEdgesC == (0x04u | 0x08u)) && | |
1576 bool(packedEdgesR & 0x08u) && | |
1577 bool(packedEdgesT & 0x04u); | |
1578 bool large_l4 = (packedEdgesC == (0x02u | 0x04u)) && | |
1579 bool(packedEdgesR & 0x02u) && | |
1580 bool(packedEdgesB & 0x04u); | |
1581 if (large_l1 || large_l2 || large_l3 || large_l4) | |
1582 continue; | |
1583 } | |
1584 | |
1585 // 2.) U-like shape (surrounded with edges from 3 sides) | |
1586 if (numberOfEdges == 3.0) { | 1532 if (numberOfEdges == 3.0) { |
1587 // with value of 0.13, the pixel will retain approx 72% of its | 1533 // with value of 0.13, the pixel will retain approx 72% of its |
1588 // colour and the remaining 28% will be picked from its 3 | 1534 // colour and the remaining 28% will be picked from its 3 |
1589 // neighbours (which are unlikely to be blurred too but could be) | 1535 // neighbours (which are unlikely to be blurred too but could be) |
1590 blurCoeff = 0.13; | 1536 blurCoeff = 0.13; |
1591 } | 1537 } |
1592 | 1538 |
1593 // 3.) Completely surrounded with edges from all 4 sides | 1539 // 2.) Completely surrounded with edges from all 4 sides |
1594 if (numberOfEdges == 4.0) { | 1540 if (numberOfEdges == 4.0) { |
1595 // with value of 0.07, the pixel will retain 78% of its colour | 1541 // with value of 0.07, the pixel will retain 78% of its colour |
1596 // and the remaining 22% will come from its 4 neighbours (which | 1542 // and the remaining 22% will come from its 4 neighbours (which |
1597 // are unlikely to be blurred) | 1543 // are unlikely to be blurred) |
1598 blurCoeff = 0.07; | 1544 blurCoeff = 0.07; |
1599 } | 1545 } |
1600 | 1546 |
| 1547 // 3.) L-like shape. |
| 1548 // Two edge case is a bit complicated. We want to handle only staircase |
| 1549 // case. The staircase case consists of small staircase and Z shape. |
| 1550 // Define small staircase as at least 2 texels form Z shape. |
| 1551 // Standard form Variants |
| 1552 // __ |__ __ __ |__ |
| 1553 // X| X| | X | X| |
| 1554 // ¯¯ ¯¯ ¯¯ ¯¯| ¯¯| |
| 1555 // |
| 1556 // Define Z shape as at least 4 texels form Z shape. |
| 1557 // __ __ |
| 1558 // X| |
| 1559 // ¯¯ ¯¯ |
| 1560 // Anything else will be skipped. e.g. |
| 1561 // Parallel |X| |
| 1562 // |
| 1563 // Isolated L shape |
| 1564 // _ _ |
| 1565 // X| X| |X |X |
| 1566 // ¯¯ ¯¯ |
| 1567 // Large L shape |
| 1568 // _ _ | | _ _ |
| 1569 // X| X| |X |X |
| 1570 // | ¯¯¯¯ ¯¯¯¯ | |
| 1571 // |
| 1572 // etc.. |
| 1573 if (numberOfEdges == 2.0) { |
| 1574 // with value of 0.15, the pixel will retain approx 77% of its |
| 1575 // colour and the remaining 23% will come from its 2 neighbours |
| 1576 // (which are likely to be blurred too in the opposite direction) |
| 1577 blurCoeff = 0.15; |
| 1578 |
| 1579 uint packedEdgesL = packedEdgesArray[(0 + _x) * 4 + (1 + _y)]; |
| 1580 uint packedEdgesB = packedEdgesArray[(1 + _x) * 4 + (0 + _y)]; |
| 1581 uint packedEdgesR = packedEdgesArray[(2 + _x) * 4 + (1 + _y)]; |
| 1582 uint packedEdgesT = packedEdgesArray[(1 + _x) * 4 + (2 + _y)]; |
| 1583 |
| 1584 // HorizontalA HorizontalB HorizontalC HorizontalD |
| 1585 // _ _ _ _ |
| 1586 // X| X| |X |X |
| 1587 // ¯¯ ¯¯ ¯¯ ¯¯ |
| 1588 bool isHorizontalA = ((packedEdgesC) == (0x01u | 0x02u)) && |
| 1589 ((packedEdgesR & 0x08u) == 0x08u); |
| 1590 bool isHorizontalB = ((packedEdgesC) == (0x01u | 0x08u)) && |
| 1591 ((packedEdgesR & 0x02u) == 0x02u); |
| 1592 bool isHorizontalC = ((packedEdgesC) == (0x04u | 0x08u)) && |
| 1593 ((packedEdgesL & 0x02u) == 0x02u); |
| 1594 bool isHorizontalD = ((packedEdgesC) == (0x02u | 0x04u)) && |
| 1595 ((packedEdgesL & 0x08u) == 0x08u); |
| 1596 |
| 1597 // VerticalA VerticalB VerticalC VerticalD |
| 1598 // _| |_ X| |X |
| 1599 // |X X| |¯¯ ¯¯| |
| 1600 bool isVerticalA = ((packedEdgesC) == (0x02u | 0x04u)) && |
| 1601 ((packedEdgesT & 0x01u) == 0x01u); |
| 1602 bool isVerticalB = ((packedEdgesC) == (0x01u | 0x02u)) && |
| 1603 ((packedEdgesT & 0x04u) == 0x04u); |
| 1604 bool isVerticalC = ((packedEdgesC) == (0x01u | 0x08u)) && |
| 1605 ((packedEdgesB & 0x04u) == 0x04u); |
| 1606 bool isVerticalD = ((packedEdgesC) == (0x04u | 0x08u)) && |
| 1607 ((packedEdgesT & 0x01u) == 0x01u); |
| 1608 |
| 1609 bool isStaircase = isHorizontalA || isHorizontalB || isHorizontalC || |
| 1610 isHorizontalD || isVerticalA || isVerticalB || |
| 1611 isVerticalC || isVerticalD; |
| 1612 |
| 1613 // Skip anything else as mentioned above. |
| 1614 if (!isStaircase) |
| 1615 continue; |
| 1616 |
| 1617 bool isHCandidate = isHorizontalA || isHorizontalB; |
| 1618 bool isVCandidate = isVerticalA || isVerticalB; |
| 1619 bool isZCandidate = isHCandidate || isVCandidate; |
| 1620 |
| 1621 // isHorizontalA/B are the same to isHorizontalC/D in another fragment |
| 1622 if (isZCandidate) { |
| 1623 bool horizontal = isHCandidate; |
| 1624 |
| 1625 // what if both are candidates? do additional pruning (still not |
| 1626 // 100% but gets rid of worst case errors) |
| 1627 if (isHCandidate && isVCandidate) |
| 1628 horizontal = |
| 1629 (isHorizontalA && ((packedEdgesL & 0x02u) == 0x02u)) || |
| 1630 (isHorizontalB && ((packedEdgesL & 0x08u) == 0x08u)); |
| 1631 |
| 1632 ivec2 offsetC; |
| 1633 uint packedEdgesM1P0; |
| 1634 uint packedEdgesP1P0; |
| 1635 if (horizontal) { |
| 1636 packedEdgesM1P0 = packedEdgesL; |
| 1637 packedEdgesP1P0 = packedEdgesR; |
| 1638 offsetC = ivec2(2, 0); |
| 1639 } else { |
| 1640 packedEdgesM1P0 = packedEdgesB; |
| 1641 packedEdgesP1P0 = packedEdgesT; |
| 1642 offsetC = ivec2(0, 2); |
| 1643 } |
| 1644 |
| 1645 uvec4 edgesM1P0 = UnpackEdge(packedEdgesM1P0); |
| 1646 uvec4 edgesP1P0 = UnpackEdge(packedEdgesP1P0); |
| 1647 uvec4 edgesP2P0 = UnpackEdge(uint( |
| 1648 texelFetch(g_src0TextureFlt, screenPosI.xy + offsetC, 0).r * |
| 1649 255.5)); |
| 1650 |
| 1651 uvec4 arg0; |
| 1652 uvec4 arg1; |
| 1653 uvec4 arg2; |
| 1654 uvec4 arg3; |
| 1655 bool arg4; |
| 1656 |
| 1657 if (horizontal) { |
| 1658 arg0 = uvec4(edges); |
| 1659 arg1 = edgesM1P0; |
| 1660 arg2 = edgesP1P0; |
| 1661 arg3 = edgesP2P0; |
| 1662 arg4 = true; |
| 1663 } else { |
| 1664 // Reuse the same code for vertical (used for horizontal above) |
| 1665 // but rotate input data 90º counter-clockwise. |
| 1666 // See FindLineLength() |
| 1667 // e.g. arg0.r (new top) must be mapped to edges.g (old top) |
| 1668 arg0 = uvec4(edges.gbar); |
| 1669 arg1 = edgesM1P0.gbar; |
| 1670 arg2 = edgesP1P0.gbar; |
| 1671 arg3 = edgesP2P0.gbar; |
| 1672 arg4 = false; |
| 1673 } |
| 1674 |
| 1675 { |
| 1676 ivec2 screenPos = screenPosI.xy; |
| 1677 bvec4 _edges = bvec4(arg0); |
| 1678 bvec4 _edgesM1P0 = bvec4(arg1); |
| 1679 bvec4 _edgesP1P0 = bvec4(arg2); |
| 1680 bvec4 _edgesP2P0 = bvec4(arg3); |
| 1681 bool horizontal = arg4; |
| 1682 |
| 1683 // Normal Z case: |
| 1684 // __ __ |
| 1685 // X| |
| 1686 // ¯¯ ¯¯ |
| 1687 bool isNormalZ = _edges.r && _edges.g && !_edgesP1P0.r && |
| 1688 !_edgesP1P0.g && _edgesP1P0.b && _edgesP1P0.a && |
| 1689 !_edgesM1P0.r && _edgesM1P0.g && !_edgesP2P0.b && |
| 1690 _edgesP2P0.a; |
| 1691 |
| 1692 // Inverted Z case: |
| 1693 // __ __ |
| 1694 // X| |
| 1695 // ¯¯ ¯¯ |
| 1696 bool isInvertedZ = _edges.r && _edges.a && !_edgesP1P0.r && |
| 1697 _edgesP1P0.g && _edgesP1P0.b && |
| 1698 !_edgesP1P0.a && !_edgesM1P0.r && |
| 1699 _edgesM1P0.a && _edgesP2P0.g && !_edgesP2P0.b; |
| 1700 |
| 1701 bool isZ = isInvertedZ || isNormalZ; |
| 1702 if (isZ) { |
| 1703 forFollowUpCoords[forFollowUpCount++] = |
| 1704 ivec4(screenPosI.xy, horizontal, isInvertedZ); |
| 1705 } |
| 1706 } |
| 1707 } |
| 1708 } |
| 1709 |
1601 // |blurCoeff| must be not zero at this point. | 1710 // |blurCoeff| must be not zero at this point. |
1602 vec4 blurMap = xFroms * blurCoeff; | 1711 vec4 blurMap = xFroms * blurCoeff; |
1603 | |
1604 vec4 pixelC = texelFetch(g_screenTexture, screenPosI.xy, 0); | 1712 vec4 pixelC = texelFetch(g_screenTexture, screenPosI.xy, 0); |
1605 | 1713 |
1606 const float centerWeight = 1.0; | 1714 const float centerWeight = 1.0; |
1607 float fromBelowWeight = blurMap.x; | 1715 float fromBelowWeight = blurMap.x; |
1608 float fromAboveWeight = blurMap.y; | 1716 float fromAboveWeight = blurMap.y; |
1609 float fromRightWeight = blurMap.z; | 1717 float fromRightWeight = blurMap.z; |
1610 float fromLeftWeight = blurMap.w; | 1718 float fromLeftWeight = blurMap.w; |
1611 | 1719 |
1612 // this would be the proper math for blending if we were handling | 1720 // this would be the proper math for blending if we were handling |
1613 // lines (Zs) and mini kernel smoothing here, but since we're doing | 1721 // lines (Zs) and mini kernel smoothing here, but since we're doing |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1647 color = mix(color, pixelC, centerWeight / allWeightSum); | 1755 color = mix(color, pixelC, centerWeight / allWeightSum); |
1648 \n#ifdef IN_GAMMA_CORRECT_MODE\n | 1756 \n#ifdef IN_GAMMA_CORRECT_MODE\n |
1649 color.rgb = D3DX_FLOAT3_to_SRGB(color.rgb); | 1757 color.rgb = D3DX_FLOAT3_to_SRGB(color.rgb); |
1650 \n#endif\n | 1758 \n#endif\n |
1651 | 1759 |
1652 \n#ifdef DEBUG_OUTPUT_AAINFO\n | 1760 \n#ifdef DEBUG_OUTPUT_AAINFO\n |
1653 imageStore(g_resultTextureSlot2, screenPosI.xy, | 1761 imageStore(g_resultTextureSlot2, screenPosI.xy, |
1654 PackBlurAAInfo(screenPosI.xy, uint(numberOfEdges))); | 1762 PackBlurAAInfo(screenPosI.xy, uint(numberOfEdges))); |
1655 \n#endif\n | 1763 \n#endif\n |
1656 imageStore(g_resultTextureFlt4Slot1, screenPosI.xy, color); | 1764 imageStore(g_resultTextureFlt4Slot1, screenPosI.xy, color); |
1657 | |
1658 if (numberOfEdges == 2.0) { | |
1659 uint packedEdgesL = packedEdgesArray[(0 + _x) * 4 + (1 + _y)]; | |
1660 uint packedEdgesB = packedEdgesArray[(1 + _x) * 4 + (0 + _y)]; | |
1661 uint packedEdgesR = packedEdgesArray[(2 + _x) * 4 + (1 + _y)]; | |
1662 uint packedEdgesT = packedEdgesArray[(1 + _x) * 4 + (2 + _y)]; | |
1663 | |
1664 bool isHorizontalA = ((packedEdgesC) == (0x01u | 0x02u)) && | |
1665 ((packedEdgesR & 0x08u) == 0x08u); | |
1666 bool isHorizontalB = ((packedEdgesC) == (0x01u | 0x08u)) && | |
1667 ((packedEdgesR & 0x02u) == 0x02u); | |
1668 | |
1669 bool isHCandidate = isHorizontalA || isHorizontalB; | |
1670 | |
1671 bool isVerticalA = ((packedEdgesC) == (0x02u | 0x04u)) && | |
1672 ((packedEdgesT & 0x01u) == 0x01u); | |
1673 bool isVerticalB = ((packedEdgesC) == (0x01u | 0x02u)) && | |
1674 ((packedEdgesT & 0x04u) == 0x04u); | |
1675 bool isVCandidate = isVerticalA || isVerticalB; | |
1676 | |
1677 bool isCandidate = isHCandidate || isVCandidate; | |
1678 | |
1679 if (!isCandidate) | |
1680 continue; | |
1681 | |
1682 bool horizontal = isHCandidate; | |
1683 | |
1684 // what if both are candidates? do additional pruning (still not | |
1685 // 100% but gets rid of worst case errors) | |
1686 if (isHCandidate && isVCandidate) | |
1687 horizontal = | |
1688 (isHorizontalA && ((packedEdgesL & 0x02u) == 0x02u)) || | |
1689 (isHorizontalB && ((packedEdgesL & 0x08u) == 0x08u)); | |
1690 | |
1691 ivec2 offsetC; | |
1692 uint packedEdgesM1P0; | |
1693 uint packedEdgesP1P0; | |
1694 if (horizontal) { | |
1695 packedEdgesM1P0 = packedEdgesL; | |
1696 packedEdgesP1P0 = packedEdgesR; | |
1697 offsetC = ivec2(2, 0); | |
1698 } else { | |
1699 packedEdgesM1P0 = packedEdgesB; | |
1700 packedEdgesP1P0 = packedEdgesT; | |
1701 offsetC = ivec2(0, 2); | |
1702 } | |
1703 | |
1704 uvec4 edgesM1P0 = UnpackEdge(packedEdgesM1P0); | |
1705 uvec4 edgesP1P0 = UnpackEdge(packedEdgesP1P0); | |
1706 uvec4 edgesP2P0 = UnpackEdge(uint(texelFetch( | |
1707 g_src0TextureFlt, screenPosI.xy + offsetC, 0).r * 255.5)); | |
1708 | |
1709 uvec4 arg0; | |
1710 uvec4 arg1; | |
1711 uvec4 arg2; | |
1712 uvec4 arg3; | |
1713 bool arg4; | |
1714 | |
1715 if (horizontal) { | |
1716 arg0 = uvec4(edges); | |
1717 arg1 = edgesM1P0; | |
1718 arg2 = edgesP1P0; | |
1719 arg3 = edgesP2P0; | |
1720 arg4 = true; | |
1721 } else { | |
1722 // Reuse the same code for vertical (used for horizontal above) | |
1723 // but rotate input data 90º counter-clockwise. See FindLineLength() | |
1724 // e.g. arg0.r (new top) must be mapped to edges.g (old top) | |
1725 arg0 = uvec4(edges.gbar); | |
1726 arg1 = edgesM1P0.gbar; | |
1727 arg2 = edgesP1P0.gbar; | |
1728 arg3 = edgesP2P0.gbar; | |
1729 arg4 = false; | |
1730 } | |
1731 | |
1732 { | |
1733 ivec2 screenPos = screenPosI.xy; | |
1734 uvec4 _edges = arg0; | |
1735 uvec4 _edgesM1P0 = arg1; | |
1736 uvec4 _edgesP1P0 = arg2; | |
1737 uvec4 _edgesP2P0 = arg3; | |
1738 bool horizontal = arg4; | |
1739 | |
1740 // Normal Z case: | |
1741 // __ | |
1742 // X| | |
1743 // ¯¯ | |
1744 bool isInvertedZ = false; | |
1745 bool isNormalZ = false; | |
1746 { | |
1747 \n#ifndef SETTINGS_ALLOW_SHORT_Zs\n | |
1748 // (1u-_edges.a) constraint can be removed; it was added for | |
1749 // some rare cases | |
1750 uint isZShape = _edges.r * _edges.g * _edgesM1P0.g * | |
1751 _edgesP1P0.a *_edgesP2P0.a * (1u - _edges.b) * | |
1752 (1u - _edgesP1P0.r) * (1u - _edges.a) * | |
1753 (1u - _edgesP1P0.g); | |
1754 \n#else\n | |
1755 uint isZShape = _edges.r * _edges.g * _edgesP1P0.a * | |
1756 (1u - _edges.b) * (1u - _edgesP1P0.r) * (1u - _edges.a) * | |
1757 (1u - _edgesP1P0.g); | |
1758 isZShape *= (_edgesM1P0.g + _edgesP2P0.a); | |
1759 // and at least one of these need to be there | |
1760 \n#endif\n | |
1761 if (isZShape > 0u) { | |
1762 isNormalZ = true; | |
1763 } | |
1764 } | |
1765 | |
1766 // Inverted Z case: | |
1767 // __ | |
1768 // X| | |
1769 // ¯¯ | |
1770 { | |
1771 \n#ifndef SETTINGS_ALLOW_SHORT_Zs\n | |
1772 uint isZShape = _edges.r * _edges.a * _edgesM1P0.a * | |
1773 _edgesP1P0.g * _edgesP2P0.g * (1u - _edges.b) * | |
1774 (1u - _edgesP1P0.r) * (1u - _edges.g) * | |
1775 (1u - _edgesP1P0.a); | |
1776 \n#else\n | |
1777 uint isZShape = _edges.r * _edges.a * _edgesP1P0.g * | |
1778 (1u - _edges.b) * (1u - _edgesP1P0.r) * (1u - _edges.g) * | |
1779 (1u - _edgesP1P0.a); | |
1780 isZShape *= | |
1781 (_edgesM1P0.a + _edgesP2P0.g); | |
1782 // and at least one of these need to be there | |
1783 \n#endif\n | |
1784 | |
1785 if (isZShape > 0u) { | |
1786 isInvertedZ = true; | |
1787 } | |
1788 } | |
1789 | |
1790 bool isZ = isInvertedZ || isNormalZ; | |
1791 if (isZ) { | |
1792 forFollowUpCoords[forFollowUpCount++] = | |
1793 ivec4(screenPosI.xy, horizontal, isInvertedZ); | |
1794 } | |
1795 } | |
1796 } | |
1797 } | 1765 } |
1798 | 1766 |
1799 // This code below is the only potential bug with this algorithm : | 1767 // This code below is the only potential bug with this algorithm : |
1800 // it HAS to be executed after the simple shapes above. It used to be | 1768 // it HAS to be executed after the simple shapes above. It used to be |
1801 // executed as separate compute shader (by storing the packed | 1769 // executed as separate compute shader (by storing the packed |
1802 // 'forFollowUpCoords' in an append buffer and consuming it later) | 1770 // 'forFollowUpCoords' in an append buffer and consuming it later) |
1803 // but the whole thing (append/consume buffers, using CS) appears to | 1771 // but the whole thing (append/consume buffers, using CS) appears to |
1804 // be too inefficient on most hardware. | 1772 // be too inefficient on most hardware. |
1805 // However, it seems to execute fairly efficiently here and without | 1773 // However, it seems to execute fairly efficiently here and without |
1806 // any issues, although there is no 100% guarantee that this code | 1774 // any issues, although there is no 100% guarantee that this code |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1883 \n#ifdef OUT_FBO\n | 1851 \n#ifdef OUT_FBO\n |
1884 outColor = pixel; | 1852 outColor = pixel; |
1885 \n#else\n | 1853 \n#else\n |
1886 imageStore(outTexture, screenPosI, pixel); | 1854 imageStore(outTexture, screenPosI, pixel); |
1887 \n#endif\n | 1855 \n#endif\n |
1888 } | 1856 } |
1889 ); | 1857 ); |
1890 /* clang-format on */ | 1858 /* clang-format on */ |
1891 | 1859 |
1892 } // namespace gpu | 1860 } // namespace gpu |
OLD | NEW |