Wine-Devel
By message
wine-devel@list.winehq.org
By month
Threads by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
August 2018
- 62 participants
- 701 discussions
Adapted from video-x-generic in the Tango Icon Library.
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
dlls/shell32/Makefile.in | 1 +
dlls/shell32/resources/video.ico | Bin 0 -> 64287 bytes
dlls/shell32/resources/video.svg | 783 +++++++++++++++++++++++++++++++
dlls/shell32/shell32.rc | 3 +
dlls/shell32/shresdef.h | 1 +
5 files changed, 788 insertions(+)
create mode 100644 dlls/shell32/resources/video.ico
create mode 100644 dlls/shell32/resources/video.svg
diff --git a/dlls/shell32/Makefile.in b/dlls/shell32/Makefile.in
index 74a3c13f2b..aad12636ce 100644
--- a/dlls/shell32/Makefile.in
+++ b/dlls/shell32/Makefile.in
@@ -98,4 +98,5 @@ SVG_SRCS = \
resources/trash_file.svg \
resources/trash_full.svg \
resources/update.svg \
+ resources/video.svg \
resources/window.svg
diff --git a/dlls/shell32/resources/video.ico b/dlls/shell32/resources/video.ico
new file mode 100644
index 0000000000000000000000000000000000000000..2edeeeef3ab09ace3468a4e60891cb7c51c8e348
GIT binary patch
literal 64287
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
literal 0
HcmV?d00001
diff --git a/dlls/shell32/resources/video.svg b/dlls/shell32/resources/video.svg
new file mode 100644
index 0000000000..c7a0b9ed45
--- /dev/null
+++ b/dlls/shell32/resources/video.svg
@@ -0,0 +1,783 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="1.1"
+ id="svg11300"
+ height="272"
+ width="632">
+ <defs
+ id="defs3">
+ <linearGradient
+ id="linearGradient7087">
+ <stop
+ id="stop7089"
+ offset="0"
+ style="stop-color:#888a85;stop-opacity:1;" />
+ <stop
+ id="stop7091"
+ offset="1"
+ style="stop-color:#b8b9b6;stop-opacity:1;" />
+ </linearGradient>
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.99999998,0,0,0.66393398,1.2374365,9.8240947)"
+ r="21.566757"
+ fy="26.963573"
+ fx="23.157747"
+ cy="26.963573"
+ cx="23.157747"
+ id="radialGradient7085"
+ xlink:href="#linearGradient7079" />
+ <linearGradient
+ id="linearGradient7079">
+ <stop
+ id="stop7081"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop7083"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ gradientTransform="translate(1.9716765,9.2201447)"
+ xlink:href="#aigrd4-3"
+ id="radialGradient6540"
+ gradientUnits="userSpaceOnUse"
+ cx="20.655508"
+ cy="24.735121"
+ fx="20.655508"
+ fy="24.735121"
+ r="14.1515" />
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ fy="22.6138"
+ fx="9.3417997"
+ r="14.1515"
+ cy="22.6138"
+ cx="9.3417997"
+ id="aigrd4-3">
+ <stop
+ id="stop6452-6"
+ style="stop-color:#767676"
+ offset="0" />
+ <stop
+ id="stop6454-7"
+ style="stop-color:#484848"
+ offset="1" />
+ </radialGradient>
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ y2="25.772396"
+ x2="29.049412"
+ y1="12.75"
+ x1="23.816254"
+ id="linearGradient7093"
+ xlink:href="#linearGradient7087"
+ gradientTransform="matrix(0.76096898,0,0,0.98666301,2.9050465,0.58427473)" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ y2="-4.5986342"
+ x2="21.107563"
+ y1="31.867859"
+ x1="21.03167"
+ id="linearGradient7060"
+ xlink:href="#linearGradient7054"
+ gradientTransform="matrix(0.950533,0,0,0.9375,1.4509965,3.3206247)" />
+ <linearGradient
+ id="linearGradient7054">
+ <stop
+ id="stop7056"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop7058"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="matrix(0.88487799,0,0,0.88487801,5.3181165,5.9431647)"
+ gradientUnits="userSpaceOnUse"
+ y2="34.140205"
+ x2="40.820396"
+ y1="35.24506"
+ x1="46.54464"
+ id="linearGradient7075"
+ xlink:href="#linearGradient7069" />
+ <linearGradient
+ id="linearGradient7069">
+ <stop
+ id="stop7071"
+ offset="0"
+ style="stop-color:#888a85;stop-opacity:1;" />
+ <stop
+ id="stop7073"
+ offset="1"
+ style="stop-color:#888a85;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="translate(6.5136719e-6,2.0000047)"
+ gradientUnits="userSpaceOnUse"
+ y2="32.133045"
+ x2="26.625"
+ y1="32.133045"
+ x1="43.6875"
+ id="linearGradient7144"
+ xlink:href="#linearGradient7054" />
+ <linearGradient
+ gradientTransform="translate(1.6748048e-6,1.9999997)"
+ gradientUnits="userSpaceOnUse"
+ y2="32.133045"
+ x2="26.625"
+ y1="32.133045"
+ x1="43.6875"
+ id="linearGradient7144-5"
+ xlink:href="#linearGradient7054" />
+ <linearGradient
+ gradientTransform="matrix(0.884878,0,0,0.884878,5.3181217,5.9431597)"
+ gradientUnits="userSpaceOnUse"
+ y2="34.140205"
+ x2="40.820396"
+ y1="35.24506"
+ x1="46.54464"
+ id="linearGradient7075-9"
+ xlink:href="#linearGradient7069" />
+ <radialGradient
+ gradientTransform="translate(1.9716817,9.2201397)"
+ xlink:href="#aigrd4-3-3"
+ id="radialGradient6540-9"
+ gradientUnits="userSpaceOnUse"
+ cx="20.655508"
+ cy="24.735121"
+ fx="20.655508"
+ fy="24.735121"
+ r="14.1515" />
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ fy="22.6138"
+ fx="9.3417997"
+ r="14.1515"
+ cy="22.6138"
+ cx="9.3417997"
+ id="aigrd4-3-3">
+ <stop
+ id="stop6452-6-6"
+ style="stop-color:#767676"
+ offset="0" />
+ <stop
+ id="stop6454-7-0"
+ style="stop-color:#484848"
+ offset="1" />
+ </radialGradient>
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.663934,1.2374417,9.8240897)"
+ r="21.566757"
+ fy="26.963573"
+ fx="23.157747"
+ cy="26.963573"
+ cx="23.157747"
+ id="radialGradient7085-6"
+ xlink:href="#linearGradient7079" />
+ <linearGradient
+ y2="25.772396"
+ x2="29.049412"
+ y1="12.75"
+ x1="23.816254"
+ gradientTransform="matrix(0.760969,0,0,0.986663,2.9050517,0.58426974)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1048"
+ xlink:href="#linearGradient7087" />
+ <linearGradient
+ y2="-4.5986342"
+ x2="21.107563"
+ y1="31.867859"
+ x1="21.03167"
+ gradientTransform="matrix(0.950533,0,0,0.9375,1.4510017,3.3206197)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1050"
+ xlink:href="#linearGradient7054" />
+ <linearGradient
+ gradientTransform="translate(5.4928296e-7,2.0000038)"
+ gradientUnits="userSpaceOnUse"
+ y2="32.133045"
+ x2="26.625"
+ y1="32.133045"
+ x1="43.6875"
+ id="linearGradient7144-5-5"
+ xlink:href="#linearGradient7054" />
+ <linearGradient
+ gradientTransform="matrix(0.88487802,0,0,0.88487802,5.3181239,5.9431621)"
+ gradientUnits="userSpaceOnUse"
+ y2="34.140205"
+ x2="40.820396"
+ y1="35.24506"
+ x1="46.54464"
+ id="linearGradient7075-9-2"
+ xlink:href="#linearGradient7069" />
+ <linearGradient
+ y2="-4.5986342"
+ x2="21.107563"
+ y1="31.867859"
+ x1="21.03167"
+ gradientTransform="matrix(0.95053306,0,0,0.93750001,1.4509995,3.3206198)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1050-7"
+ xlink:href="#linearGradient7054" />
+ <linearGradient
+ y2="25.772396"
+ x2="29.049412"
+ y1="12.75"
+ x1="23.816254"
+ gradientTransform="matrix(0.760969,0,0,0.98666303,2.9050524,0.584272)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1048-3"
+ xlink:href="#linearGradient7087" />
+ <radialGradient
+ gradientTransform="translate(1.9716838,9.2201388)"
+ xlink:href="#aigrd4-3-3-9"
+ id="radialGradient6540-9-2"
+ gradientUnits="userSpaceOnUse"
+ cx="20.655508"
+ cy="24.735121"
+ fx="20.655508"
+ fy="24.735121"
+ r="14.1515" />
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ fy="22.6138"
+ fx="9.3417997"
+ r="14.1515"
+ cy="22.6138"
+ cx="9.3417997"
+ id="aigrd4-3-3-9">
+ <stop
+ id="stop6452-6-6-3"
+ style="stop-color:#767676"
+ offset="0" />
+ <stop
+ id="stop6454-7-0-1"
+ style="stop-color:#484848"
+ offset="1" />
+ </radialGradient>
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.66393399,1.2374433,9.8240901)"
+ r="21.566757"
+ fy="26.963573"
+ fx="23.157747"
+ cy="26.963573"
+ cx="23.157747"
+ id="radialGradient7085-6-9"
+ xlink:href="#linearGradient7079" />
+ </defs>
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://jimmac.musichall.cz</dc:source>
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:title></dc:title>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>video</rdf:li>
+ <rdf:li>audio</rdf:li>
+ <rdf:li>multimedia</rdf:li>
+ <rdf:li>movie</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <ellipse
+ id="path7077"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.70329674;fill:url(#radialGradient7085);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+ cx="139.2869"
+ cy="154.96852"
+ rx="116.2039"
+ ry="77.271484" />
+ <ellipse
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#a1a39f;fill-opacity:1;fill-rule:evenodd;stroke:#6d6f6a;stroke-width:0.99999958;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+ id="path7028"
+ cx="129.07542"
+ cy="146.19809"
+ rx="99.679878"
+ ry="68.647804" />
+ <ellipse
+ id="path7042"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#555753;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.97567552;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+ cx="126.29389"
+ cy="132.6004"
+ rx="60.719406"
+ ry="44.601574" />
+ <path
+ id="path6456"
+ d="m 255.83491,227.82128 c 0,0 -44.85,-20.16662 -73.57993,-17.62872 -30.62065,2.70491 -81.77403,4.51919 -101.824885,-27.19461 85.121765,25.71126 124.395075,-16.97591 182.006765,7.06674 0,0 -6.60195,37.75659 -6.60195,37.75659 z"
+ style="fill:url(#radialGradient6540);fill-rule:nonzero;stroke:#3b3d39;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1" />
+ <ellipse
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#linearGradient7093);fill-opacity:1;fill-rule:evenodd;stroke:#757972;stroke-width:1.06933594;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+ id="path7026"
+ cx="129.07545"
+ cy="120.31272"
+ rx="60.477642"
+ ry="43.927044" />
+ <path
+ id="path7012"
+ d="m 121.49844,46.999405 c -51.496905,2.83678 -92.102881,34.61625 -92.102882,73.020875 0,40.26326 44.656612,73.02089 99.679902,73.02089 55.02329,0 99.6799,-32.75764 99.6799,-73.02089 0,-40.263245 -44.65661,-73.020875 -99.6799,-73.020875 -0.21493,0 -0.45891,-0.001 -0.67351,0 -1.28267,0.006 -2.60195,-0.0412 -3.8727,0 -0.62049,0.0201 -1.23469,-0.0284 -1.85216,0 -0.4068,0.0187 -0.77316,-0.0223 -1.17865,0 z m -7.40864,11.80476 c 0.3408,-0.0276 0.66592,0.0187 1.01027,0 0.72256,-0.0393 1.45233,0 2.18891,0 15.71382,0 28.45592,9.18587 28.45592,20.40537 0,11.2195 -12.7421,20.23674 -28.45592,20.23674 -15.71381,0 -28.455913,-9.01724 -28.455913,-20.23674 0,-10.44295 11.056139,-19.25707 25.256733,-20.40537 z m 61.96318,24.79 c 0.35912,-0.0324 0.64757,0.0232 1.01027,0 0.62907,-0.0399 1.21306,0.0113 1.85216,0 0.25971,-0.005 0.41224,0 0.67351,0 16.72173,0 30.30808,9.79028 30.30808,21.754485 0,11.96421 -13.58635,21.58585 -30.30808,21.58585 -16.72173,1e-5 -30.30807,-9.62164 -30.30807,-21.58585 -10e-6,-11.051965 11.80955,-20.413775 26.77213,-21.754485 z M 72.500381,100.62674 c 1.173668,-0.0962 2.49488,0 3.70432,0 17.20092,0 31.149969,9.94217 31.149969,22.26041 0,12.31825 -13.949049,22.26041 -31.149969,22.26041 -17.200916,0 -31.149969,-9.94216 -31.149969,-22.26041 0,-11.45211 11.927126,-20.98865 27.445649,-22.26041 z m 62.131559,27.65688 c 0.12921,-0.0151 0.20712,0.014 0.33676,0 0.0145,-6.4e-4 0.15464,-1.8e-4 0.16838,0 0.014,2.4e-4 0.1535,5.3e-4 0.16837,0 0.0334,5.7e-4 0.15119,6.2e-4 0.16838,0 0.1409,9.6e-4 0.36375,-0.002 0.50514,0 0.0172,-4.2e-4 0.13481,-4.5e-4 0.16837,0 1.29841,-0.10675 2.53473,0 3.8727,0 19.02898,0 34.51754,10.95245 34.51754,24.62136 0,13.66891 -15.48856,24.79 -34.51754,24.79 -19.02898,0 -34.51753,-11.12109 -34.51753,-24.79 0,-12.31456 12.7237,-22.71216 29.12943,-24.62136 z"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#d3d7cf;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" />
+ <ellipse
+ id="path7044"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient7060);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+ cx="129.28571"
+ cy="119.43317"
+ rx="94.611595"
+ ry="67.970284" />
+ <path
+ id="path7067"
+ d="m 260.41047,191.49053 -5.82757,32.64854 c -14.05766,-4.72426 -22.53331,-8.46249 -38.10017,-12.17906 l 1.78793,-26.51092 c 10.22948,-1.08634 26.20385,0.76487 42.13981,6.04144 z"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#linearGradient7075);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" />
+ <path
+ id="path7136"
+ d="m 260.41047,190.51158 -1.01027,4.7219 c -43.67003,-16.34527 -83.87156,-1.22348 -125.94691,0 57.17345,-4.7628 75.91968,-20.0514 126.95718,-4.7219 z"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.70329674;fill:url(#linearGradient7144);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" />
+ <rect
+ id="icon:256-32"
+ height="256"
+ width="256"
+ y="8"
+ x="8"
+ style="fill:none" />
+ <ellipse
+ id="path7077-1"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.70329674;fill:url(#radialGradient7085-6);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+ cx="296.39474"
+ cy="247.72609"
+ rx="21.566757"
+ ry="14.318913" />
+ <ellipse
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#a1a39f;fill-opacity:1;fill-rule:evenodd;stroke:#6d6f6a;stroke-width:0.99999958;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+ id="path7028-8"
+ cx="294.49957"
+ cy="246.10088"
+ rx="18.499996"
+ ry="12.720889" />
+ <ellipse
+ id="path7042-7"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#555753;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.97567552;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+ cx="293.98334"
+ cy="243.58113"
+ rx="11.269162"
+ ry="8.2649651" />
+ <path
+ id="path6456-9"
+ d="m 318.02537,261.22618 c 0,0 -8.32389,-3.73701 -13.65599,-3.26672 -5.68302,0.50124 -15.17678,0.83743 -18.8981,-5.03934 15.7981,4.76446 23.08699,-3.14575 33.77938,1.30951 0,0 -1.22529,6.99655 -1.22529,6.99655 z"
+ style="fill:url(#radialGradient6540-9);fill-rule:nonzero;stroke:#3b3d39;stroke-miterlimit:4;stroke-opacity:1" />
+ <ellipse
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#linearGradient1048);fill-opacity:1;fill-rule:evenodd;stroke:#757972;stroke-width:1.06933594;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+ id="path7026-2"
+ cx="294.49957"
+ cy="241.30414"
+ rx="11.224293"
+ ry="8.1399698" />
+ <path
+ id="path7012-0"
+ d="m 293.09332,227.71869 c -9.55752,0.52568 -17.09375,6.41462 -17.09375,13.53125 0,7.46105 8.288,13.53125 18.5,13.53125 10.212,0 18.5,-6.0702 18.5,-13.53125 0,-7.46104 -8.288,-13.53125 -18.5,-13.53125 -0.0399,0 -0.0852,-1.8e-4 -0.125,0 -0.23806,0.001 -0.48291,-0.008 -0.71875,0 -0.11516,0.004 -0.22915,-0.005 -0.34375,0 -0.0755,0.004 -0.14349,-0.004 -0.21875,0 z m -1.375,2.1875 c 0.0632,-0.005 0.12359,0.004 0.1875,0 0.1341,-0.007 0.26954,0 0.40625,0 2.91639,0 5.28125,1.70221 5.28125,3.78125 0,2.07905 -2.36486,3.75 -5.28125,3.75 -2.91639,0 -5.28125,-1.67095 -5.28125,-3.75 0,-1.93515 2.05195,-3.56846 4.6875,-3.78125 z m 11.5,4.59375 c 0.0667,-0.006 0.12019,0.004 0.1875,0 0.11675,-0.007 0.22514,0.002 0.34375,0 0.0482,-8.7e-4 0.0765,0 0.125,0 3.10345,0 5.625,1.81421 5.625,4.03125 0,2.21705 -2.52155,4 -5.625,4 -3.10345,0 -5.625,-1.78295 -5.625,-4 0,-2.048 2.19178,-3.7828 4.96875,-4.03125 z m -19.21875,3.15625 c 0.21783,-0.0178 0.46304,0 0.6875,0 3.19239,0 5.78125,1.84235 5.78125,4.125 0,2.28265 -2.58886,4.125 -5.78125,4.125 -3.19239,0 -5.78125,-1.84235 -5.78125,-4.125 0,-2.12215 2.2136,-3.88933 5.09375,-4.125 z m 11.53125,5.125 c 0.024,-0.003 0.0384,0.003 0.0625,0 0.003,-1.1e-4 0.0287,-3e-5 0.0312,0 0.003,5e-5 0.0285,1e-4 0.0312,0 0.006,1.1e-4 0.0281,1.2e-4 0.0312,0 0.0262,1.8e-4 0.0675,-3.8e-4 0.0937,0 0.003,-7e-5 0.025,-8e-5 0.0312,0 0.24098,-0.0198 0.47043,0 0.71875,0 3.53167,0 6.40625,2.02956 6.40625,4.5625 0,2.53294 -2.87458,4.59375 -6.40625,4.59375 -3.53167,0 -6.40625,-2.06081 -6.40625,-4.59375 0,-2.28197 2.36144,-4.20871 5.40625,-4.5625 z"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#d3d7cf;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" />
+ <ellipse
+ id="path7044-2"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient1050);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+ cx="294.53857"
+ cy="241.14116"
+ rx="17.559353"
+ ry="12.59534" />
+ <path
+ id="path7067-3"
+ d="m 318.87457,254.49385 -1.08156,6.04999 c -2.60902,-0.87544 -4.18205,-1.56816 -7.07117,-2.25686 l 0.33183,-4.91265 c 1.89853,-0.2013 4.86328,0.14174 7.8209,1.11952 z"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#linearGradient7075-9);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" />
+ <path
+ id="path7136-7"
+ d="m 318.87457,254.31244 -0.1875,0.875 c -8.1049,-3.02888 -15.56606,-0.22672 -23.375,0 10.61105,-0.88258 14.09024,-3.71565 23.5625,-0.875 z"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.70329674;fill:url(#linearGradient7144-5);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" />
+ <rect
+ id="icon:48-32"
+ height="48"
+ width="48"
+ y="220"
+ x="272"
+ style="fill:none" />
+ <image
+ width="48"
+ height="48"
+ preserveAspectRatio="none"
+ xlink:href="data:image/png;base64,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
+VrtF222TxAme51Gt1mg1uyFp6AZCSKIowvM8oigijuM7JgEhBAMDA2zbvo3dD+1iZHSUxaVFfvKv
+//Lp50KHDx9mbO8uZRg6Q9uHKRSLCCFwXY+33noL13Xp6+3HXq8TDF1HNwykFCSJIo4igjAkCqP1
+0bnzc9Pwm5/fBACwHRvHsclmHRzHIU4iJibeu/+jxZf+5q8pForKsgx6ewcol8tomsb58xc4c+Y0
+ppmikCuQy+cxDXP9WEWhlCJJkk2NvxvIHYkqBE7WWTe+C7FyY4WPz0+Kz3Q2Ojrax9PPHCaXdZSU
+GrbtkMvlyKTTVGs1Ji9OsrK0gmmaWFYaXdfR9W4NrBKFApIkJgojojjaKPyTJOHWjl9snHLclKZp
+ZHNdz9+EuHjpEnPXFj4bwCf13HNPs314GCudVoZuws1DLakR+B28jo/rufgdnzDsVlRJoroAUbzx
+jFBdDyNZrykEEgFCoGsaumaQyWTWRyCL49g4WZuTp04hlS703xbg7bffBd7tugzYv38/W7b0ksnY
+aGb3xXEco+KEjusyP7/M5OTkfff/1FNPEYuYKIpVJ/AIogDd0MnlsggBbtvj3V/+6vP/wfH70Fee
++wqmr4EUyjRMevt6mZ9f4FfvnPjtQ+iL0sFnDqIlUimFOPHuiS/anAd6oAf6f6//BS95WkgntXrp
+AAAAFHRFWHRBdXRob3IASmFrdWIgU3RlaW5lcub79y8AAABYdEVYdENvcHlyaWdodABDQzAgUHVi
+bGljIERvbWFpbiBEZWRpY2F0aW9uIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL3B1YmxpY2Rv
+bWFpbi96ZXJvLzEuMC/G4735AAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE4LTA4LTI5VDIxOjQ1OjA1
+LTA2OjAwCN7M2wAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOC0wOC0yOVQyMTo0NTowNS0wNjowMHmD
+dGcAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAIXRFWHRTb3VyY2UAaHR0
+cDovL2ppbW1hYy5tdXNpY2hhbGwuY3ppZuNeAAAAE3RFWHRUaXRsZQBHZW5lcmljIFZpZGVvLHad
+gQAAAABJRU5ErkJggg==
+"
+ id="icon:48-8"
+ x="328"
+ y="220" />
+ <image
+ width="48"
+ height="48"
+ preserveAspectRatio="none"
+ xlink:href="data:image/png;base64,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
+VrtF222TxAme51Gt1mg1uyFp6AZCSKIowvM8oigijuM7JgEhBAMDA2zbvo3dD+1iZHSUxaVFfvKv
+//Lp50KHDx9mbO8uZRg6Q9uHKRSLCCFwXY+33noL13Xp6+3HXq8TDF1HNwykFCSJIo4igjAkCqP1
+0bnzc9Pwm5/fBACwHRvHsclmHRzHIU4iJibeu/+jxZf+5q8pForKsgx6ewcol8tomsb58xc4c+Y0
+ppmikCuQy+cxDXP9WEWhlCJJkk2NvxvIHYkqBE7WWTe+C7FyY4WPz0+Kz3Q2Ojrax9PPHCaXdZSU
+GrbtkMvlyKTTVGs1Ji9OsrK0gmmaWFYaXdfR9W4NrBKFApIkJgojojjaKPyTJOHWjl9snHLclKZp
+ZHNdz9+EuHjpEnPXFj4bwCf13HNPs314GCudVoZuws1DLakR+B28jo/rufgdnzDsVlRJoroAUbzx
+jFBdDyNZrykEEgFCoGsaumaQyWTWRyCL49g4WZuTp04hlS703xbg7bffBd7tugzYv38/W7b0ksnY
+aGb3xXEco+KEjusyP7/M5OTkfff/1FNPEYuYKIpVJ/AIogDd0MnlsggBbtvj3V/+6vP/wfH70Fee
++wqmr4EUyjRMevt6mZ9f4FfvnPjtQ+iL0sFnDqIlUimFOPHuiS/anAd6oAf6f6//BS95WkgntXrp
+AAAAFHRFWHRBdXRob3IASmFrdWIgU3RlaW5lcub79y8AAABYdEVYdENvcHlyaWdodABDQzAgUHVi
+bGljIERvbWFpbiBEZWRpY2F0aW9uIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL3B1YmxpY2Rv
+bWFpbi96ZXJvLzEuMC/G4735AAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE4LTA4LTI5VDIxOjQ1OjA1
+LTA2OjAwCN7M2wAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOC0wOC0yOVQyMTo0NTowNS0wNjowMHmD
+dGcAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAIXRFWHRTb3VyY2UAaHR0
+cDovL2ppbW1hYy5tdXNpY2hhbGwuY3ppZuNeAAAAE3RFWHRUaXRsZQBHZW5lcmljIFZpZGVvLHad
+gQAAAABJRU5ErkJggg==
+"
+ id="icon:48-4"
+ x="384"
+ y="220" />
+ <ellipse
+ id="path7077-1-8"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.70329674;fill:url(#radialGradient7085-6-9);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+ cx="456.17224"
+ cy="254.37633"
+ rx="14.28721"
+ ry="9.4764519" />
+ <ellipse
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#a1a39f;fill-opacity:1;fill-rule:evenodd;stroke:#6d6f6a;stroke-width:0.99999964;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+ id="path7028-8-4"
+ cx="454.91672"
+ cy="253.30074"
+ rx="12.255589"
+ ry="8.4188576" />
+ <ellipse
+ id="path7042-7-5"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#555753;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.97567552;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+ cx="454.57474"
+ cy="251.63313"
+ rx="7.4654193"
+ ry="5.4698663" />
+ <path
+ id="path6456-9-0"
+ d="m 470.50174,263.31088 c 0,0 -5.51429,-2.4732 -9.04662,-2.16196 -3.76479,0.33173 -10.05407,0.55423 -12.51931,-3.3351 10.46568,3.15319 15.2943,-2.0819 22.37764,0.86665 0,0 -0.81171,4.63041 -0.81171,4.63041 z"
+ style="fill:url(#radialGradient6540-9-2);fill-rule:nonzero;stroke:#3b3d39;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1" />
+ <ellipse
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#linearGradient1048-3);fill-opacity:1;fill-rule:evenodd;stroke:#757972;stroke-width:1.06933594;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+ id="path7026-2-3"
+ cx="454.91672"
+ cy="250.12619"
+ rx="7.4356947"
+ ry="5.3871427" />
+ <path
+ id="path7012-0-6"
+ d="m 453.98514,241.13517 c -6.33152,0.3479 -11.32401,4.24528 -11.32401,8.95517 0,4.93782 5.49051,8.95516 12.2556,8.95516 6.76509,0 12.25559,-4.01734 12.25559,-8.95516 0,-4.93782 -5.4905,-8.95517 -12.25559,-8.95517 -0.0264,0 -0.0564,-1.2e-4 -0.0828,0 -0.15771,6.6e-4 -0.31991,-0.005 -0.47615,0 -0.0763,0.003 -0.1518,-0.003 -0.22772,0 -0.05,0.003 -0.095,-0.003 -0.14491,0 z m -0.91089,1.44772 c 0.0419,-0.003 0.0819,0.003 0.12421,0 0.0888,-0.005 0.17856,0 0.26913,0 1.932,0 3.49864,1.12654 3.49864,2.50248 0,1.37594 -1.56664,2.4818 -3.49864,2.4818 -1.93201,0 -3.49864,-1.10586 -3.49864,-2.4818 0,-1.28071 1.35935,-2.36165 3.1053,-2.50248 z m 7.61834,3.0402 c 0.0442,-0.004 0.0796,0.003 0.12422,0 0.0773,-0.005 0.14914,0.001 0.22772,0 0.0319,-5.7e-4 0.0507,0 0.0828,0 2.05592,0 3.72636,1.20067 3.72636,2.66794 0,1.46727 -1.67044,2.64726 -3.72636,2.64726 -2.05592,0 -3.72636,-1.17999 -3.72636,-2.64726 0,-1.35539 1.45197,-2.50351 3.29162,-2.66794 z m -12.73174,2.08885 c 0.14431,-0.0118 0.30675,0 0.45544,0 2.11485,0 3.82988,1.2193 3.82988,2.72999 0,1.51068 -1.71503,2.72998 -3.82988,2.72998 -2.11484,0 -3.82986,-1.2193 -3.82986,-2.72998 0,-1.40447 1.46642,-2.57402 3.37442,-2.72999 z m 7.63904,3.3918 c 0.0159,-0.002 0.0254,0.002 0.0414,0 0.002,-7e-5 0.019,-2e-5 0.0207,0 0.002,3e-5 0.0189,6e-5 0.0207,0 0.004,7e-5 0.0186,8e-5 0.0207,0 0.0174,1.2e-4 0.0447,-2.5e-4 0.0621,0 0.002,-5e-5 0.0166,-5e-5 0.0207,0 0.15964,-0.0131 0.31164,0 0.47614,0 2.33961,0 4.24391,1.34319 4.24391,3.01952 0,1.67634 -1.9043,3.04021 -4.24391,3.04021 -2.3396,0 -4.24391,-1.36387 -4.24391,-3.04021 0,-1.51024 1.56437,-2.78538 3.58144,-3.01952 z"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#d3d7cf;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" />
+ <ellipse
+ id="path7044-2-1"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient1050-7);stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
+ cx="454.94257"
+ cy="250.01833"
+ rx="11.632446"
+ ry="8.3357677" />
+ <path
+ id="path7067-3-0"
+ d="m 471.06429,258.85534 -0.71648,4.00396 c -1.72839,-0.57938 -2.77047,-1.03783 -4.68441,-1.49362 l 0.21983,-3.25126 c 1.25771,-0.13322 3.22175,0.0938 5.18106,0.74092 z"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#linearGradient7075-9-2);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" />
+ <path
+ id="path7136-7-6"
+ d="m 471.06429,258.73528 -0.12421,0.57908 c -5.3692,-2.00455 -10.31196,-0.15004 -15.4851,0 7.02944,-0.5841 9.33428,-2.45906 15.60931,-0.57908 z"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.70329674;fill:url(#linearGradient7144-5-5);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" />
+ <rect
+ id="icon:32-32"
+ height="32"
+ width="32"
+ y="236"
+ x="440"
+ style="fill:none" />
+ <image
+ width="32"
+ height="32"
+ preserveAspectRatio="none"
+ xlink:href="data:image/png;base64,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
+SUVORK5CYII=
+"
+ id="icon:32-8"
+ x="480"
+ y="236" />
+ <image
+ width="32"
+ height="32"
+ preserveAspectRatio="none"
+ xlink:href="data:image/png;base64,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
+SUVORK5CYII=
+"
+ id="icon:32-4"
+ x="520"
+ y="236" />
+ <image
+ width="16"
+ height="16"
+ preserveAspectRatio="none"
+ xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
+WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1gEEDDonMwh5AwAAADV0RVh0Q29tbWVudAAoYykgMjAw
+NCBKYWt1YiBTdGVpbmVyCgpDcmVhdGVkIHdpdGggVGhlIEdJTVCQ2YtvAAACg0lEQVQ4y52T30tT
+YRjHP+ec6ZxnxjbEmw3NYrpjWmpqGSpECf2gCNb02qsu6loEqTtB/AdCCIzubAai+CvNQL0QkpLQ
+nbOoC/XCaTGlneN25qZduEnaTfXcvO8Lz/Pheb/f5xE4Fb19PR1AAKgDXEAUWAKCXZ3dA6fzhd8K
+LwL9NdW1VxVFQc6Xj5OMPQNVVfm0/HEReNTV2f35BCBTPB3wtxXZC+zoRgwzmSB9kEYSJay5edjl
+AvSYTvDN622gNQsRM6D+gL+tSJAgpK2wvrGGmTQBMJMm6xtrhLQVBAkC/rYioD/bgdTb19NRU137
+uLikmK/fvrC/v08opBLWwnjLvExOTBGN7uByOYnpMdxuDwKCp7KqYn1menZZBAKKoqAbMQA0Lcz8
+3AKGbhz9XzeYn1tA08IA6EYMRVHICI0FqJPzZbZ+/MThdBCPx1EUH/cf3AM4PuPxOA6nAzOZwHHG
+ScYlLBmrSB+ksVgs3Ll7+4RNVquVQPvD43f6IJ29urIiRgEkUSKVSjE+NkFwcAjTzIhomgQHhxgf
+myCVSiGJUhYQzQKWjD0Da24euzu72Gw2VFVjZHgUgJHhUVRVw2azsbuzizU3D2PPIDNciEBQVVXs
+cgEAPl85zS1NyPajQZLtMs0tTfh85QDY5QJUVQUIAkgz07PLlVUVt7znvR6H00FMjyEIAg1X6hFF
+kdJzpUQ2I6yvbdDYeI1kIsm79zOLXZ3dTwAkgJutNz6E1FV/he+C7HZ7KCwsBODw8JAcSw5l3nLq
+6xpIJpK8fDUQjUS2np0tLbGGVtXNf9qFqbeTX7e3v0+ZpnkdmANeCP+zjYF2/2XgOTD6B+BvI9Du
+fwpc+gUuhglRSTLyIQAAAABJRU5ErkJggg==
+"
+ id="icon:16-32"
+ x="560"
+ y="252" />
+ <image
+ width="16"
+ height="16"
+ preserveAspectRatio="none"
+ xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAACBjSFJN
+AAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAV1BMVEUAAACIioVqbGhVV1OI
+ioW5urfi4+Dt7evd3dvp6ufd39rW2dLT18/e4Nu/wrvP08u6vbaSlY+JjIZVV1N+gHvM0MiprKaY
+m5WLjYh9f3pydG9cXloAAABrterCAAAABHRSTlMAAAAAs5NmmgAAAAFiS0dEAIgFHUgAAAAJcEhZ
+cwAACxMAAAsTAQCanBgAAAAHdElNRQfWAhQUDiATysDQAAAAgElEQVQY022P2Q7DIAwEoRjM4ZiA
+Sc///8+SBClN23lcjexdpToaVrQaaLAOEZ0dkQYfYqIUg98T8BNzpsw8eVgFG3gulWqZOdiugItc
+pFGTwtF1BTDl2hZaWs0Jt4AO8K/xfePny9bj2nvc7nuPz6aPizlteb5EjDqtNSM4MPIGY+0ISe9t
+J8gAAAA1dEVYdENvbW1lbnQAKGMpIDIwMDQgSmFrdWIgU3RlaW5lcgoKQ3JlYXRlZCB3aXRoIFRo
+ZSBHSU1QkNmLbwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxOC0wOC0yM1QyMjoxNDo1Ny0wNjowMABN
+wggAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMDYtMDItMjFUMDM6MTQ6MzItMDc6MDDLd46aAAAAAElF
+TkSuQmCC
+"
+ id="icon:16-8"
+ x="584"
+ y="252" />
+ <image
+ width="16"
+ height="16"
+ preserveAspectRatio="none"
+ xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAACBjSFJN
+AAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAV1BMVEUAAACIioVqbGhVV1OI
+ioW5urfi4+Dt7evd3dvp6ufd39rW2dLT18/e4Nu/wrvP08u6vbaSlY+JjIZVV1N+gHvM0MiprKaY
+m5WLjYh9f3pydG9cXloAAABrterCAAAABHRSTlMAAAAAs5NmmgAAAAFiS0dEAIgFHUgAAAAJcEhZ
+cwAACxMAAAsTAQCanBgAAAAHdElNRQfWAhQUDiATysDQAAAAgElEQVQY022P2Q7DIAwEoRjM4ZiA
+Sc///8+SBClN23lcjexdpToaVrQaaLAOEZ0dkQYfYqIUg98T8BNzpsw8eVgFG3gulWqZOdiugItc
+pFGTwtF1BTDl2hZaWs0Jt4AO8K/xfePny9bj2nvc7nuPz6aPizlteb5EjDqtNSM4MPIGY+0ISe9t
+J8gAAAA1dEVYdENvbW1lbnQAKGMpIDIwMDQgSmFrdWIgU3RlaW5lcgoKQ3JlYXRlZCB3aXRoIFRo
+ZSBHSU1QkNmLbwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxOC0wOC0yM1QyMjoxNDo1Ny0wNjowMABN
+wggAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMDYtMDItMjFUMDM6MTQ6MzItMDc6MDDLd46aAAAAAElF
+TkSuQmCC
+"
+ id="icon:16-4"
+ x="608"
+ y="252" />
+</svg>
diff --git a/dlls/shell32/shell32.rc b/dlls/shell32/shell32.rc
index 6dad8bc574..806e8ef64f 100644
--- a/dlls/shell32/shell32.rc
+++ b/dlls/shell32/shell32.rc
@@ -804,6 +804,9 @@ IDI_SHELL_DVD ICON resources/optical_disc.ico
/* @makedep: resources/document.ico */
IDI_SHELL_DOCUMENTS ICON resources/document.ico
+/* @makedep: resources/video.ico */
+IDI_SHELL_VIDEO_FILE ICON resources/video.ico
+
/* FIXME: Following resource is not yet added */
/* @makedep: resources/optical_disc.ico */
IDI_SHELL_MUSIC_CD_95 ICON resources/optical_disc.ico
diff --git a/dlls/shell32/shresdef.h b/dlls/shell32/shresdef.h
index 1c28a06dc8..38e444c361 100644
--- a/dlls/shell32/shresdef.h
+++ b/dlls/shell32/shresdef.h
@@ -293,6 +293,7 @@
#define IDI_SHELL_POWER_OFF 221
#define IDI_SHELL_DVD 222
#define IDI_SHELL_DOCUMENTS 223
+#define IDI_SHELL_VIDEO_FILE 224
#define IDI_SHELL_MUSIC_CD_95 228
#define IDI_SHELL_MY_DOCUMENTS 235
#define IDI_SHELL_MY_PICTURES 236
--
2.18.0
2
16
[PATCH] kernel32: Fallback to default comspec when %COMSPEC% is not set.
by Alistair Leslie-Hughes Aug. 31, 2018
by Alistair Leslie-Hughes Aug. 31, 2018
Aug. 31, 2018
From: Qian Hong <qhong(a)codeweavers.com>
Wine-bug: https://bugs.winehq.org/show_bug.cgi?id=19801
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com>
---
dlls/kernel32/process.c | 6 +++++-
programs/cmd/wcmdmain.c | 10 ++++++++++
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index 7ac7477..85e0042 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -2206,6 +2206,7 @@ static BOOL create_cmd_process( LPCWSTR filename, LPWSTR cmd_line, LPVOID env, L
{
static const WCHAR comspecW[] = {'C','O','M','S','P','E','C',0};
+ static const WCHAR cmdW[] = {'\\','c','m','d','.','e','x','e',0};
static const WCHAR slashscW[] = {' ','/','s','/','c',' ',0};
static const WCHAR quotW[] = {'"',0};
WCHAR comspec[MAX_PATH];
@@ -2213,7 +2214,10 @@ static BOOL create_cmd_process( LPCWSTR filename, LPWSTR cmd_line, LPVOID env, L
BOOL ret;
if (!GetEnvironmentVariableW( comspecW, comspec, ARRAY_SIZE( comspec )))
- return FALSE;
+ {
+ GetSystemDirectoryW( comspec, (sizeof(comspec) - sizeof(cmdW))/sizeof(WCHAR) );
+ strcatW( comspec, cmdW );
+ }
if (!(newcmdline = HeapAlloc( GetProcessHeap(), 0,
(strlenW(comspec) + 7 + strlenW(cmd_line) + 2) * sizeof(WCHAR))))
return FALSE;
diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c
index 7a7ee16..66a5ac0 100644
--- a/programs/cmd/wcmdmain.c
+++ b/programs/cmd/wcmdmain.c
@@ -2400,10 +2400,20 @@ int wmain (int argc, WCHAR *argvW[])
static const WCHAR offW[] = {'O','F','F','\0'};
static const WCHAR promptW[] = {'P','R','O','M','P','T','\0'};
static const WCHAR defaultpromptW[] = {'$','P','$','G','\0'};
+ static const WCHAR comspecW[] = {'C','O','M','S','P','E','C',0};
+ static const WCHAR cmdW[] = {'\\','c','m','d','.','e','x','e',0};
+ WCHAR comspec[MAX_PATH];
CMD_LIST *toExecute = NULL; /* Commands left to be executed */
OSVERSIONINFOW osv;
char osver[50];
+ if (!GetEnvironmentVariableW(comspecW, comspec, sizeof(comspec)/sizeof(WCHAR)))
+ {
+ GetSystemDirectoryW(comspec, (sizeof(comspec) - sizeof(cmdW))/sizeof(WCHAR));
+ strcatW(comspec, cmdW);
+ SetEnvironmentVariableW(comspecW, comspec);
+ }
+
srand(time(NULL));
/* Get the windows version being emulated */
--
1.9.1
1
0
Aug. 31, 2018
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com>
---
include/ddk/ntddk.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/ddk/ntddk.h b/include/ddk/ntddk.h
index 5c124ca..e76ccc9 100644
--- a/include/ddk/ntddk.h
+++ b/include/ddk/ntddk.h
@@ -214,6 +214,7 @@ NTSTATUS WINAPI IoQueryDeviceDescription(PINTERFACE_TYPE,PULONG,PCONFIGURATION_
PCONFIGURATION_TYPE,PULONG,PIO_QUERY_DEVICE_ROUTINE,PVOID);
void WINAPI IoRegisterDriverReinitialization(PDRIVER_OBJECT,PDRIVER_REINITIALIZE,PVOID);
NTSTATUS WINAPI IoRegisterShutdownNotification(PDEVICE_OBJECT);
+BOOLEAN WINAPI MmIsAddressValid(void *);
NTSTATUS WINAPI PsSetLoadImageNotifyRoutine(PLOAD_IMAGE_NOTIFY_ROUTINE);
void WINAPI RtlInitializeGenericTableAvl(PRTL_AVL_TABLE,PRTL_AVL_COMPARE_ROUTINE,PRTL_AVL_ALLOCATE_ROUTINE, PRTL_AVL_FREE_ROUTINE,void *);
void WINAPI RtlInsertElementGenericTableAvl(PRTL_AVL_TABLE,void *,ULONG,BOOL*);
--
1.9.1
1
0
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
include/opcbase.idl | 15 ++++
include/opcobjectmodel.idl | 174 +++++++++++++++++++++++++++++++++++++
2 files changed, 189 insertions(+)
diff --git a/include/opcbase.idl b/include/opcbase.idl
index fc92675420..33f56ac077 100644
--- a/include/opcbase.idl
+++ b/include/opcbase.idl
@@ -25,3 +25,18 @@ typedef [v1_enum] enum
OPC_STREAM_IO_READ = 1,
OPC_STREAM_IO_WRITE = 2,
} OPC_STREAM_IO_MODE;
+
+typedef [v1_enum] enum
+{
+ OPC_COMPRESSION_NONE = -1,
+ OPC_COMPRESSION_NORMAL = 0,
+ OPC_COMPRESSION_MAXIMUM = 1,
+ OPC_COMPRESSION_FAST = 2,
+ OPC_COMPRESSION_SUPERFAST = 3,
+} OPC_COMPRESSION_OPTIONS;
+
+typedef [v1_enum] enum
+{
+ OPC_URI_TARGET_MODE_INTERNAL = 0,
+ OPC_URI_TARGET_MODE_EXTERNAL = 1,
+} OPC_URI_TARGET_MODE;
diff --git a/include/opcobjectmodel.idl b/include/opcobjectmodel.idl
index e5370d2e54..45bc8aa4a5 100644
--- a/include/opcobjectmodel.idl
+++ b/include/opcobjectmodel.idl
@@ -20,6 +20,11 @@
#pragma makedep install
#endif
+interface IOpcPart;
+interface IOpcPartUri;
+interface IOpcUri;
+interface IOpcRelationship;
+
typedef [v1_enum] enum
{
OPC_READ_DEFAULT = 0,
@@ -32,3 +37,172 @@ typedef [v1_enum] enum
OPC_WRITE_DEFAULT = 0,
OPC_WRITE_FORCE_ZIP32 = 1,
} OPC_WRITE_FLAGS;
+
+[
+ object,
+ uuid(42195949-3b79-4fc8-89c6-fc7fb979ee75),
+ pointer_default(ref)
+]
+interface IOpcPartEnumerator : IUnknown
+{
+ HRESULT MoveNext(
+ [out, retval] BOOL *has_next
+ );
+
+ HRESULT MovePrevious(
+ [out, retval] BOOL *has_previous
+ );
+
+ HRESULT GetCurrent(
+ [out, retval] IOpcPart **part
+ );
+
+ HRESULT Clone(
+ [out, retval] IOpcPartEnumerator **enumerator
+ );
+}
+
+[
+ object,
+ uuid(42195949-3b79-4fc8-89c6-fc7fb979ee76),
+ pointer_default(ref)
+]
+interface IOpcRelationshipEnumerator : IUnknown
+{
+ HRESULT MoveNext(
+ [out, retval] BOOL *has_next
+ );
+
+ HRESULT MovePrevious(
+ [out, retval] BOOL *has_previous
+ );
+
+ HRESULT GetCurrent(
+ [out, retval] IOpcRelationship **relationship
+ );
+
+ HRESULT Clone(
+ [out, retval] IOpcRelationshipEnumerator **enumerator
+ );
+}
+
+[
+ object,
+ uuid(42195949-3b79-4fc8-89c6-fc7fb979ee73),
+ pointer_default(ref)
+]
+interface IOpcPartSet : IUnknown
+{
+ HRESULT GetPart(
+ [in] IOpcPartUri *name,
+ [out, retval] IOpcPart **part
+ );
+
+ HRESULT CreatePart(
+ [in] IOpcPartUri *name,
+ [in, string] LPCWSTR content_type,
+ [in] OPC_COMPRESSION_OPTIONS compression_options,
+ [out, retval] IOpcPart **part
+ );
+
+ HRESULT DeletePart(
+ [in] IOpcPartUri *name
+ );
+
+ HRESULT PartExists(
+ [in] IOpcPartUri *name,
+ [out, retval] BOOL *exists
+ );
+
+ HRESULT GetEnumerator(
+ [out, retval] IOpcPartEnumerator **enumerator
+ );
+}
+
+[
+ object,
+ uuid(42195949-3b79-4fc8-89c6-fc7fb979ee72),
+ pointer_default(ref)
+]
+interface IOpcRelationship : IUnknown
+{
+ HRESULT GetId(
+ [out, string, retval] LPWSTR *id
+ );
+
+ HRESULT GetRelationshipType(
+ [out, string, retval] LPWSTR *type
+ );
+
+ HRESULT GetSourceUri(
+ [out, retval] IOpcUri **uri
+ );
+
+ HRESULT GetTargetUri(
+ [out, retval] IUri **target
+ );
+
+ HRESULT GetTargetMode(
+ [out, retval] OPC_URI_TARGET_MODE *target_mode
+ );
+}
+
+
+[
+ object,
+ uuid(42195949-3b79-4fc8-89c6-fc7fb979ee74),
+ pointer_default(ref)
+]
+interface IOpcRelationshipSet : IUnknown
+{
+ HRESULT GetRelationship(
+ [in, string] LPCWSTR id,
+ [out, retval] IOpcRelationship **relationship
+ );
+
+ HRESULT CreateRelationship(
+ [in, string, unique] LPCWSTR id,
+ [in, string] LPCWSTR type,
+ [in] IUri *target_uri,
+ [in] OPC_URI_TARGET_MODE target_mode,
+ [out, retval] IOpcRelationship **relationship
+ );
+
+ HRESULT DeleteRelationship(
+ [in, string] LPCWSTR id
+ );
+
+ HRESULT RelationshipExists(
+ [in, string] LPCWSTR id,
+ [out, retval] BOOL *exists
+ );
+
+ HRESULT GetEnumerator(
+ [out, retval] IOpcRelationshipEnumerator **enumerator
+ );
+
+ HRESULT GetEnumeratorForType(
+ [in, string] LPCWSTR type,
+ [out, retval] IOpcRelationshipEnumerator **enumerator
+ );
+
+ HRESULT GetRelationshipsContentStream(
+ [out, retval] IStream **stream
+ );
+}
+
+[
+ object,
+ uuid(42195949-3b79-4fc8-89c6-fc7fb979ee70),
+ pointer_default(ref)
+]
+interface IOpcPackage : IUnknown
+{
+ HRESULT GetPartSet(
+ [out, retval] IOpcPartSet **part_set
+ );
+
+ HRESULT GetRelationshipSet(
+ [out, retval] IOpcRelationshipSet **relationship_set
+ );
+}
--
2.18.0
1
2
Aug. 30, 2018
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/shlwapi/tests/istream.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/dlls/shlwapi/tests/istream.c b/dlls/shlwapi/tests/istream.c
index 300e9b9c00..f1854a283f 100644
--- a/dlls/shlwapi/tests/istream.c
+++ b/dlls/shlwapi/tests/istream.c
@@ -247,6 +247,27 @@ static void test_stream_read_write(IStream *stream, DWORD mode)
ok(buf[0] == 0x5e && buf[1] == 0xa7, "expected 5ea7, got %02x%02x\n", buf[0], buf[1]);
}
+static void test_stream_qi(IStream *stream)
+{
+ IUnknown *unk;
+ HRESULT hr;
+
+ hr = IStream_QueryInterface(stream, &IID_IStream, (void **)&unk);
+ ok(SUCCEEDED(hr), "Failed to get IStream interface, hr %#x.\n", hr);
+ IUnknown_Release(unk);
+
+ unk = NULL;
+ hr = IStream_QueryInterface(stream, &IID_ISequentialStream, (void **)&unk);
+todo_wine
+ ok(SUCCEEDED(hr) || broken(hr == E_NOINTERFACE) /* XP */, "Failed to get ISequentialStream interface, hr %#x.\n", hr);
+ if (unk)
+ IUnknown_Release(unk);
+
+ hr = IStream_QueryInterface(stream, &IID_IUnknown, (void **)&unk);
+ ok(SUCCEEDED(hr), "Failed to get IUnknown interface, hr %#x.\n", hr);
+ IUnknown_Release(unk);
+}
+
static void test_SHCreateStreamOnFileA(DWORD mode, DWORD stgm)
{
IStream * stream;
@@ -310,6 +331,7 @@ if (0) /* This test crashes on WinXP SP2 */
ok(stream != NULL, "SHCreateStreamOnFileA: expected a valid IStream object, got NULL\n");
if (stream) {
+ test_stream_qi(stream);
test_IStream_invalid_operations(stream, mode);
refcount = IStream_Release(stream);
@@ -422,6 +444,7 @@ static void test_SHCreateStreamOnFileW(DWORD mode, DWORD stgm)
ok(stream != NULL, "SHCreateStreamOnFileW: expected a valid IStream object, got NULL\n");
if (stream) {
+ test_stream_qi(stream);
test_IStream_invalid_operations(stream, mode);
refcount = IStream_Release(stream);
@@ -551,6 +574,7 @@ static void test_SHCreateStreamOnFileEx(DWORD mode, DWORD stgm)
ok(stream != NULL, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n");
if (stream) {
+ test_stream_qi(stream);
test_IStream_invalid_operations(stream, mode);
refcount = IStream_Release(stream);
--
2.18.0
1
3
Aug. 30, 2018
Replicate the scenario of an exe calling
ReplaceFileW on itself.
An exe calling ReplaceFileW on itself will fail
in Wine currently but succeed in Windows 7.
This seems to be the problem seen in bug 33845.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=33845
Signed-off-by: Brock York <twunknown(a)gmail.com>
---
dlls/kernel32/tests/file.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c
index 1c4157279b..d496e9273b 100644
--- a/dlls/kernel32/tests/file.c
+++ b/dlls/kernel32/tests/file.c
@@ -3677,6 +3677,30 @@ static void test_ReplaceFileA(void)
ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
"SetFileAttributesA: error setting to normal %d\n", GetLastError());
+ /* re-create replacement file for pass w/ replaced opened with
+ * the same permissions as an exe (Replicating an exe trying to
+ * replace itself)
+ */
+ ret = GetTempFileNameA(temp_path, prefix, 0, replacement);
+ ok(ret != 0, "GetTempFileNameA error (replacement) %d\n", GetLastError());
+
+ SetLastError(0xdeadbeef);
+ /* make sure that the replacement file still exists */
+ hReplacementFile = CreateFileA(replacement, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
+ ok(hReplacementFile != INVALID_HANDLE_VALUE ||
+ broken(GetLastError() == ERROR_FILE_NOT_FOUND), /* win2k */
+ "unexpected error, replacement file should still exist %d\n", GetLastError());
+ CloseHandle(hReplacementFile);
+
+ /* make sure that the replaced file is opened like an exe*/
+ hReplacedFile = CreateFileA(replaced, GENERIC_READ | SYNCHRONIZE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, 0);
+ ok(hReplacedFile != INVALID_HANDLE_VALUE,
+ "unexpected error, replaced file should be able to be opened %d\n", GetLastError());
+ /*Calling ReplaceFileA on an exe should succeed*/
+ ret = pReplaceFileA(replaced, replacement, NULL, 0, 0, 0);
+ ok(ret, "ReplaceFileA: unexpected error %d\n", GetLastError());
+ CloseHandle(hReplacedFile);
+
/* replacement file still exists, make pass w/o "replaced" */
ret = DeleteFileA(replaced);
ok(ret || GetLastError() == ERROR_ACCESS_DENIED,
--
2.18.0
2
8
[PATCH vkd3d 1/3] vkd3d: Use vkd3d_create_vk_buffer_view() to create counter resource views.
by Józef Kucia Aug. 30, 2018
by Józef Kucia Aug. 30, 2018
Aug. 30, 2018
From: Józef Kucia <jkucia(a)codeweavers.com>
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
libs/vkd3d/resource.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c
index d97c3dbeb88b..7dc7b384b57e 100644
--- a/libs/vkd3d/resource.c
+++ b/libs/vkd3d/resource.c
@@ -1590,11 +1590,16 @@ static void vkd3d_create_buffer_uav(struct d3d12_desc *descriptor, struct d3d12_
if (counter_resource)
{
+ const struct vkd3d_format *format;
+
assert(d3d12_resource_is_buffer(counter_resource));
assert(desc->u.Buffer.StructureByteStride);
- if (!vkd3d_create_buffer_view(device, counter_resource, DXGI_FORMAT_R32_UINT,
- desc->u.Buffer.CounterOffsetInBytes / sizeof(uint32_t), 1, 0, 0, &view->vk_counter_view))
+
+ format = vkd3d_get_format(DXGI_FORMAT_R32_UINT, false);
+ if (!vkd3d_create_vk_buffer_view(device, counter_resource, format,
+ desc->u.Buffer.CounterOffsetInBytes, sizeof(uint32_t), &view->vk_counter_view))
{
+ WARN("Failed to create counter buffer view.\n");
view->vk_counter_view = VK_NULL_HANDLE;
d3d12_desc_destroy(descriptor, device);
}
--
2.16.4
2
1
Aug. 30, 2018
From: Józef Kucia <jkucia(a)codeweavers.com>
For consistency with vkd3d_create_buffer_view().
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
libs/vkd3d/resource.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c
index 4772b3f10dbf..219b95c37194 100644
--- a/libs/vkd3d/resource.c
+++ b/libs/vkd3d/resource.c
@@ -1341,7 +1341,7 @@ static bool init_default_texture_view_desc(struct vkd3d_texture_view_desc *desc,
return true;
}
-static HRESULT vkd3d_create_texture_view(struct d3d12_device *device,
+static bool vkd3d_create_texture_view(struct d3d12_device *device,
struct d3d12_resource *resource, const struct vkd3d_texture_view_desc *desc,
struct vkd3d_view **view)
{
@@ -1369,18 +1369,18 @@ static HRESULT vkd3d_create_texture_view(struct d3d12_device *device,
if ((vr = VK_CALL(vkCreateImageView(device->vk_device, &view_desc, NULL, &vk_view))) < 0)
{
WARN("Failed to create Vulkan image view, vr %d.\n", vr);
- return hresult_from_vk_result(vr);
+ return false;
}
if (!(object = vkd3d_view_create()))
{
VK_CALL(vkDestroyImageView(device->vk_device, vk_view, NULL));
- return E_OUTOFMEMORY;
+ return false;
}
object->u.vk_image_view = vk_view;
*view = object;
- return S_OK;
+ return true;
}
void d3d12_desc_create_cbv(struct d3d12_desc *descriptor,
@@ -1541,7 +1541,7 @@ void d3d12_desc_create_srv(struct d3d12_desc *descriptor,
}
}
- if (FAILED(vkd3d_create_texture_view(device, resource, &vkd3d_desc, &view)))
+ if (!vkd3d_create_texture_view(device, resource, &vkd3d_desc, &view))
return;
descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_SRV;
@@ -1663,7 +1663,7 @@ static void vkd3d_create_texture_uav(struct d3d12_desc *descriptor,
}
}
- if (FAILED(vkd3d_create_texture_view(device, resource, &vkd3d_desc, &view)))
+ if (!vkd3d_create_texture_view(device, resource, &vkd3d_desc, &view))
return;
descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_UAV;
@@ -1913,7 +1913,7 @@ void d3d12_rtv_desc_create_rtv(struct d3d12_rtv_desc *rtv_desc, struct d3d12_dev
vkd3d_desc.layer_count = resource->desc.DepthOrArraySize;
}
- if (FAILED(vkd3d_create_texture_view(device, resource, &vkd3d_desc, &view)))
+ if (!vkd3d_create_texture_view(device, resource, &vkd3d_desc, &view))
return;
rtv_desc->magic = VKD3D_DESCRIPTOR_MAGIC_RTV;
@@ -1985,7 +1985,7 @@ void d3d12_dsv_desc_create_dsv(struct d3d12_dsv_desc *dsv_desc, struct d3d12_dev
}
}
- if (FAILED(vkd3d_create_texture_view(device, resource, &vkd3d_desc, &view)))
+ if (!vkd3d_create_texture_view(device, resource, &vkd3d_desc, &view))
return;
dsv_desc->magic = VKD3D_DESCRIPTOR_MAGIC_DSV;
--
2.16.4
2
1
[PATCH vkd3d 2/3] vkd3d: Create vkd3d_views in vkd3d_create_buffer_view().
by Józef Kucia Aug. 30, 2018
by Józef Kucia Aug. 30, 2018
Aug. 30, 2018
From: Józef Kucia <jkucia(a)codeweavers.com>
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
libs/vkd3d/resource.c | 44 +++++++++++++++++++++++---------------------
1 file changed, 23 insertions(+), 21 deletions(-)
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c
index 7dc7b384b57e..4772b3f10dbf 100644
--- a/libs/vkd3d/resource.c
+++ b/libs/vkd3d/resource.c
@@ -1206,10 +1206,13 @@ static bool vkd3d_create_vk_buffer_view(struct d3d12_device *device,
static bool vkd3d_create_buffer_view(struct d3d12_device *device,
struct d3d12_resource *resource, DXGI_FORMAT view_format,
unsigned int offset, unsigned int size, unsigned int structure_stride,
- unsigned int flags, VkBufferView *vk_view)
+ unsigned int flags, struct vkd3d_view **view)
{
+ const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
const struct vkd3d_format *format;
+ struct vkd3d_view *object;
unsigned int element_size;
+ VkBufferView vk_view;
if (view_format == DXGI_FORMAT_R32_TYPELESS && (flags & VKD3D_VIEW_RAW_BUFFER))
{
@@ -1231,8 +1234,19 @@ static bool vkd3d_create_buffer_view(struct d3d12_device *device,
return false;
}
- return vkd3d_create_vk_buffer_view(device, resource, format,
- offset * element_size, size * element_size, vk_view);
+ if (!vkd3d_create_vk_buffer_view(device, resource, format,
+ offset * element_size, size * element_size, &vk_view))
+ return false;
+
+ if (!(object = vkd3d_view_create()))
+ {
+ VK_CALL(vkDestroyBufferView(device->vk_device, vk_view, NULL));
+ return false;
+ }
+
+ object->u.vk_buffer_view = vk_view;
+ *view = object;
+ return true;
}
static void vkd3d_set_view_swizzle_for_format(VkComponentMapping *components,
@@ -1419,6 +1433,7 @@ static void vkd3d_create_buffer_srv(struct d3d12_desc *descriptor,
const D3D12_SHADER_RESOURCE_VIEW_DESC *desc)
{
struct vkd3d_view *view;
+ unsigned int flags;
if (!desc)
{
@@ -1432,18 +1447,11 @@ static void vkd3d_create_buffer_srv(struct d3d12_desc *descriptor,
return;
}
- if (!(view = vkd3d_view_create()))
- return;
-
+ flags = vkd3d_view_flags_from_d3d12_buffer_srv_flags(desc->u.Buffer.Flags);
if (!vkd3d_create_buffer_view(device, resource, desc->Format,
desc->u.Buffer.FirstElement, desc->u.Buffer.NumElements,
- desc->u.Buffer.StructureByteStride,
- vkd3d_view_flags_from_d3d12_buffer_srv_flags(desc->u.Buffer.Flags),
- &view->u.vk_buffer_view))
- {
- vkd3d_free(view);
+ desc->u.Buffer.StructureByteStride, flags, &view))
return;
- }
descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_SRV;
descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
@@ -1555,6 +1563,7 @@ static void vkd3d_create_buffer_uav(struct d3d12_desc *descriptor, struct d3d12_
const D3D12_UNORDERED_ACCESS_VIEW_DESC *desc)
{
struct vkd3d_view *view;
+ unsigned int flags;
if (!desc)
{
@@ -1571,18 +1580,11 @@ static void vkd3d_create_buffer_uav(struct d3d12_desc *descriptor, struct d3d12_
if (desc->u.Buffer.CounterOffsetInBytes)
FIXME("Ignoring counter offset %"PRIu64".\n", desc->u.Buffer.CounterOffsetInBytes);
- if (!(view = vkd3d_view_create()))
- return;
-
+ flags = vkd3d_view_flags_from_d3d12_buffer_uav_flags(desc->u.Buffer.Flags);
if (!vkd3d_create_buffer_view(device, resource, desc->Format,
desc->u.Buffer.FirstElement, desc->u.Buffer.NumElements,
- desc->u.Buffer.StructureByteStride,
- vkd3d_view_flags_from_d3d12_buffer_uav_flags(desc->u.Buffer.Flags),
- &view->u.vk_buffer_view))
- {
- vkd3d_free(view);
+ desc->u.Buffer.StructureByteStride, flags, &view))
return;
- }
descriptor->magic = VKD3D_DESCRIPTOR_MAGIC_UAV;
descriptor->vk_descriptor_type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
--
2.16.4
2
1
[PATCH 3/3] wined3d: Use get_format_internal() in init_format_filter_info().
by Józef Kucia Aug. 30, 2018
by Józef Kucia Aug. 30, 2018
Aug. 30, 2018
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/wined3d/utils.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 5720cabba99e..d75cbc1a1645 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -3330,7 +3330,7 @@ static void init_format_filter_info(struct wined3d_adapter *adapter,
{
enum wined3d_pci_vendor vendor = adapter->driver_info.vendor;
struct wined3d_format *format;
- unsigned int fmt_idx, i;
+ unsigned int i;
static const enum wined3d_format_id fmts16[] =
{
WINED3DFMT_R16_FLOAT,
@@ -3339,8 +3339,8 @@ static void init_format_filter_info(struct wined3d_adapter *adapter,
};
BOOL filtered;
+ /* This was already handled by init_format_texture_info(). */
if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2])
- /* This was already handled by init_format_texture_info(). */
return;
if (wined3d_settings.offscreen_rendering_mode != ORM_FBO
@@ -3367,8 +3367,8 @@ static void init_format_filter_info(struct wined3d_adapter *adapter,
{
for (i = 0; i < ARRAY_SIZE(fmts16); ++i)
{
- fmt_idx = get_format_idx(fmts16[i]);
- format_set_flag(&adapter->formats[fmt_idx], WINED3DFMT_FLAG_FILTERING);
+ format = get_format_internal(adapter, fmts16[i]);
+ format_set_flag(format, WINED3DFMT_FLAG_FILTERING);
}
}
return;
@@ -3376,19 +3376,19 @@ static void init_format_filter_info(struct wined3d_adapter *adapter,
for (i = 0; i < ARRAY_SIZE(fmts16); ++i)
{
- fmt_idx = get_format_idx(fmts16[i]);
- format = &adapter->formats[fmt_idx];
- if (!format->glInternal) continue; /* Not supported by GL */
+ format = get_format_internal(adapter, fmts16[i]);
+ if (!format->glInternal)
+ continue; /* Not supported by GL */
- filtered = check_filter(gl_info, adapter->formats[fmt_idx].glInternal);
+ filtered = check_filter(gl_info, format->glInternal);
if (filtered)
{
- TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
+ TRACE("Format %s supports filtering.\n", debug_d3dformat(format->id));
format_set_flag(format, WINED3DFMT_FLAG_FILTERING);
}
else
{
- TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
+ TRACE("Format %s does not support filtering.\n", debug_d3dformat(format->id));
}
}
}
--
2.16.4
2
1
[PATCH 2/3] wined3d: Use get_format_internal() in apply_format_fixups().
by Józef Kucia Aug. 30, 2018
by Józef Kucia Aug. 30, 2018
Aug. 30, 2018
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/wined3d/utils.c | 198 +++++++++++++++++++++++++--------------------------
1 file changed, 99 insertions(+), 99 deletions(-)
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index bc225878e5e8..5720cabba99e 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -3395,27 +3395,27 @@ static void init_format_filter_info(struct wined3d_adapter *adapter,
static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_gl_info *gl_info)
{
+ struct wined3d_format *format;
unsigned int i;
- int idx;
- idx = get_format_idx(WINED3DFMT_R16_FLOAT);
- adapter->formats[idx].color_fixup = create_color_fixup_desc(
+ format = get_format_internal(adapter, WINED3DFMT_R16_FLOAT);
+ format->color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
- idx = get_format_idx(WINED3DFMT_R32_FLOAT);
- adapter->formats[idx].color_fixup = create_color_fixup_desc(
+ format = get_format_internal(adapter, WINED3DFMT_R32_FLOAT);
+ format->color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
- idx = get_format_idx(WINED3DFMT_R16G16_UNORM);
- adapter->formats[idx].color_fixup = create_color_fixup_desc(
+ format = get_format_internal(adapter, WINED3DFMT_R16G16_UNORM);
+ format->color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
- idx = get_format_idx(WINED3DFMT_R16G16_FLOAT);
- adapter->formats[idx].color_fixup = create_color_fixup_desc(
+ format = get_format_internal(adapter, WINED3DFMT_R16G16_FLOAT);
+ format->color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
- idx = get_format_idx(WINED3DFMT_R32G32_FLOAT);
- adapter->formats[idx].color_fixup = create_color_fixup_desc(
+ format = get_format_internal(adapter, WINED3DFMT_R32G32_FLOAT);
+ format->color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
/* GL_ATI_envmap_bumpmap in theory supports R8G8_SNORM but is no longer supported by
@@ -3425,163 +3425,163 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_
/* R8G8_SNORM and R16G16_SNORM need a fixup of the undefined blue channel. OpenGL
* returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
* conversion for this format. */
- idx = get_format_idx(WINED3DFMT_R8G8_SNORM);
- adapter->formats[idx].color_fixup = create_color_fixup_desc(
+ format = get_format_internal(adapter, WINED3DFMT_R8G8_SNORM);
+ format->color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
- idx = get_format_idx(WINED3DFMT_R16G16_SNORM);
- adapter->formats[idx].color_fixup = create_color_fixup_desc(
+ format = get_format_internal(adapter, WINED3DFMT_R16G16_SNORM);
+ format->color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
}
else
{
/* Emulate using unsigned formats. This requires load-time conversion in addition to the
* fixups here. */
- idx = get_format_idx(WINED3DFMT_R8G8_SNORM);
- adapter->formats[idx].color_fixup = create_color_fixup_desc(
+ format = get_format_internal(adapter, WINED3DFMT_R8G8_SNORM);
+ format->color_fixup = create_color_fixup_desc(
1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
- idx = get_format_idx(WINED3DFMT_R16G16_SNORM);
- adapter->formats[idx].color_fixup = create_color_fixup_desc(
+ format = get_format_internal(adapter, WINED3DFMT_R16G16_SNORM);
+ format->color_fixup = create_color_fixup_desc(
1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
- idx = get_format_idx(WINED3DFMT_R8G8B8A8_SNORM);
- adapter->formats[idx].color_fixup = create_color_fixup_desc(
+ format = get_format_internal(adapter, WINED3DFMT_R8G8B8A8_SNORM);
+ format->color_fixup = create_color_fixup_desc(
1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
- idx = get_format_idx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
- adapter->formats[idx].color_fixup = create_color_fixup_desc(
+ format = get_format_internal(adapter, WINED3DFMT_R5G5_SNORM_L6_UNORM);
+ format->color_fixup = create_color_fixup_desc(
1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
}
if (!gl_info->supported[NV_TEXTURE_SHADER])
{
- idx = get_format_idx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
- adapter->formats[idx].color_fixup = create_color_fixup_desc(
+ format = get_format_internal(adapter, WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
+ format->color_fixup = create_color_fixup_desc(
1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
}
if (gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC] || gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
{
- idx = get_format_idx(WINED3DFMT_ATI1N);
- adapter->formats[idx].color_fixup = create_color_fixup_desc(
+ format = get_format_internal(adapter, WINED3DFMT_ATI1N);
+ format->color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X);
- idx = get_format_idx(WINED3DFMT_ATI2N);
- adapter->formats[idx].color_fixup = create_color_fixup_desc(
+ format = get_format_internal(adapter, WINED3DFMT_ATI2N);
+ format->color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
}
else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
{
- idx = get_format_idx(WINED3DFMT_ATI2N);
- adapter->formats[idx].color_fixup = create_color_fixup_desc(
+ format = get_format_internal(adapter, WINED3DFMT_ATI2N);
+ format->color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
}
if (!gl_info->supported[APPLE_YCBCR_422] && (gl_info->supported[ARB_FRAGMENT_PROGRAM]
|| (gl_info->supported[ARB_FRAGMENT_SHADER] && gl_info->supported[ARB_VERTEX_SHADER])))
{
- idx = get_format_idx(WINED3DFMT_YUY2);
- adapter->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
+ format = get_format_internal(adapter, WINED3DFMT_YUY2);
+ format->color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
- idx = get_format_idx(WINED3DFMT_UYVY);
- adapter->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
+ format = get_format_internal(adapter, WINED3DFMT_UYVY);
+ format->color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
}
else if (!gl_info->supported[APPLE_YCBCR_422] && (!gl_info->supported[ARB_FRAGMENT_PROGRAM]
&& (!gl_info->supported[ARB_FRAGMENT_SHADER] || !gl_info->supported[ARB_VERTEX_SHADER])))
{
- idx = get_format_idx(WINED3DFMT_YUY2);
- adapter->formats[idx].glInternal = 0;
+ format = get_format_internal(adapter, WINED3DFMT_YUY2);
+ format->glInternal = 0;
- idx = get_format_idx(WINED3DFMT_UYVY);
- adapter->formats[idx].glInternal = 0;
+ format = get_format_internal(adapter, WINED3DFMT_UYVY);
+ format->glInternal = 0;
}
if (gl_info->supported[ARB_FRAGMENT_PROGRAM]
|| (gl_info->supported[ARB_FRAGMENT_SHADER] && gl_info->supported[ARB_VERTEX_SHADER]))
{
- idx = get_format_idx(WINED3DFMT_YV12);
- format_set_flag(&adapter->formats[idx], WINED3DFMT_FLAG_HEIGHT_SCALE);
- adapter->formats[idx].height_scale.numerator = 3;
- adapter->formats[idx].height_scale.denominator = 2;
- adapter->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
+ format = get_format_internal(adapter, WINED3DFMT_YV12);
+ format_set_flag(format, WINED3DFMT_FLAG_HEIGHT_SCALE);
+ format->height_scale.numerator = 3;
+ format->height_scale.denominator = 2;
+ format->color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
- idx = get_format_idx(WINED3DFMT_NV12);
- format_set_flag(&adapter->formats[idx], WINED3DFMT_FLAG_HEIGHT_SCALE);
- adapter->formats[idx].height_scale.numerator = 3;
- adapter->formats[idx].height_scale.denominator = 2;
- adapter->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_NV12);
+ format = get_format_internal(adapter, WINED3DFMT_NV12);
+ format_set_flag(format, WINED3DFMT_FLAG_HEIGHT_SCALE);
+ format->height_scale.numerator = 3;
+ format->height_scale.denominator = 2;
+ format->color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_NV12);
}
else
{
- idx = get_format_idx(WINED3DFMT_YV12);
- adapter->formats[idx].glInternal = 0;
+ format = get_format_internal(adapter, WINED3DFMT_YV12);
+ format->glInternal = 0;
- idx = get_format_idx(WINED3DFMT_NV12);
- adapter->formats[idx].glInternal = 0;
+ format = get_format_internal(adapter, WINED3DFMT_NV12);
+ format->glInternal = 0;
}
if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
{
- idx = get_format_idx(WINED3DFMT_A8_UNORM);
- adapter->formats[idx].color_fixup = create_color_fixup_desc(
+ format = get_format_internal(adapter, WINED3DFMT_A8_UNORM);
+ format->color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_ZERO, 0, CHANNEL_SOURCE_ZERO, 0, CHANNEL_SOURCE_ZERO, 0, CHANNEL_SOURCE_X);
- idx = get_format_idx(WINED3DFMT_L8A8_UNORM);
- adapter->formats[idx].color_fixup = create_color_fixup_desc(
+ format = get_format_internal(adapter, WINED3DFMT_L8A8_UNORM);
+ format->color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y);
- idx = get_format_idx(WINED3DFMT_L4A4_UNORM);
- adapter->formats[idx].color_fixup = create_color_fixup_desc(
+ format = get_format_internal(adapter, WINED3DFMT_L4A4_UNORM);
+ format->color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y);
- idx = get_format_idx(WINED3DFMT_L16_UNORM);
- adapter->formats[idx].color_fixup = create_color_fixup_desc(
+ format = get_format_internal(adapter, WINED3DFMT_L16_UNORM);
+ format->color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE);
- idx = get_format_idx(WINED3DFMT_INTZ);
- adapter->formats[idx].color_fixup = create_color_fixup_desc(
+ format = get_format_internal(adapter, WINED3DFMT_INTZ);
+ format->color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X);
}
if (gl_info->supported[ARB_TEXTURE_RG])
{
- idx = get_format_idx(WINED3DFMT_L8_UNORM);
- adapter->formats[idx].color_fixup = create_color_fixup_desc(
+ format = get_format_internal(adapter, WINED3DFMT_L8_UNORM);
+ format->color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE);
}
if (gl_info->supported[ARB_FRAGMENT_PROGRAM] || gl_info->supported[ARB_FRAGMENT_SHADER])
{
- idx = get_format_idx(WINED3DFMT_P8_UINT);
- adapter->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
+ format = get_format_internal(adapter, WINED3DFMT_P8_UINT);
+ format->color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
}
if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
{
- idx = get_format_idx(WINED3DFMT_B8G8R8A8_UNORM);
- adapter->formats[idx].gl_vtx_format = GL_BGRA;
+ format = get_format_internal(adapter, WINED3DFMT_B8G8R8A8_UNORM);
+ format->gl_vtx_format = GL_BGRA;
}
if (!gl_info->supported[ARB_HALF_FLOAT_VERTEX])
{
/* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
* It is the job of the vertex buffer code to make sure that the vbos have the right format */
- idx = get_format_idx(WINED3DFMT_R16G16_FLOAT);
- adapter->formats[idx].gl_vtx_type = GL_FLOAT;
+ format = get_format_internal(adapter, WINED3DFMT_R16G16_FLOAT);
+ format->gl_vtx_type = GL_FLOAT;
- idx = get_format_idx(WINED3DFMT_R16G16B16A16_FLOAT);
- adapter->formats[idx].gl_vtx_type = GL_FLOAT;
+ format = get_format_internal(adapter, WINED3DFMT_R16G16B16A16_FLOAT);
+ format->gl_vtx_type = GL_FLOAT;
}
if (!gl_info->supported[ARB_HALF_FLOAT_PIXEL])
{
- idx = get_format_idx(WINED3DFMT_R16_FLOAT);
- format_clear_flag(&adapter->formats[idx], WINED3DFMT_FLAG_TEXTURE);
+ format = get_format_internal(adapter, WINED3DFMT_R16_FLOAT);
+ format_clear_flag(format, WINED3DFMT_FLAG_TEXTURE);
- idx = get_format_idx(WINED3DFMT_R16G16_FLOAT);
- format_clear_flag(&adapter->formats[idx], WINED3DFMT_FLAG_TEXTURE);
+ format = get_format_internal(adapter, WINED3DFMT_R16G16_FLOAT);
+ format_clear_flag(format, WINED3DFMT_FLAG_TEXTURE);
- idx = get_format_idx(WINED3DFMT_R16G16B16A16_FLOAT);
- format_clear_flag(&adapter->formats[idx], WINED3DFMT_FLAG_TEXTURE);
+ format = get_format_internal(adapter, WINED3DFMT_R16G16B16A16_FLOAT);
+ format_clear_flag(format, WINED3DFMT_FLAG_TEXTURE);
}
if (gl_info->quirks & WINED3D_QUIRK_BROKEN_RGBA16)
{
- idx = get_format_idx(WINED3DFMT_R16G16B16A16_UNORM);
- format_clear_flag(&adapter->formats[idx], WINED3DFMT_FLAG_TEXTURE);
+ format = get_format_internal(adapter, WINED3DFMT_R16G16B16A16_UNORM);
+ format_clear_flag(format, WINED3DFMT_FLAG_TEXTURE);
}
/* ATI instancing hack: Although ATI cards do not support Shader Model
@@ -3599,8 +3599,8 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_
/* FIXME: This should just check the shader backend caps. */
if (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_VERTEX_SHADER])
{
- idx = get_format_idx(WINED3DFMT_INST);
- format_set_flag(&adapter->formats[idx], WINED3DFMT_FLAG_TEXTURE);
+ format = get_format_internal(adapter, WINED3DFMT_INST);
+ format_set_flag(format, WINED3DFMT_FLAG_TEXTURE);
}
/* Depth bound test. To query if the card supports it CheckDeviceFormat()
@@ -3611,8 +3611,8 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_
* value. */
if (gl_info->supported[EXT_DEPTH_BOUNDS_TEST])
{
- idx = get_format_idx(WINED3DFMT_NVDB);
- format_set_flag(&adapter->formats[idx], WINED3DFMT_FLAG_TEXTURE);
+ format = get_format_internal(adapter, WINED3DFMT_NVDB);
+ format_set_flag(format, WINED3DFMT_FLAG_TEXTURE);
}
/* RESZ aka AMD DX9-level hack for multisampled depth buffer resolve. You query for RESZ
@@ -3620,8 +3620,8 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_
* RENDERTARGET usage. */
if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
{
- idx = get_format_idx(WINED3DFMT_RESZ);
- format_set_flag(&adapter->formats[idx], WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET);
+ format = get_format_internal(adapter, WINED3DFMT_RESZ);
+ format_set_flag(format, WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET);
}
for (i = 0; i < adapter->format_count; ++i)
@@ -3650,18 +3650,18 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_
/* These formats are not supported for 3D textures. See also
* WINED3DFMT_FLAG_DECOMPRESS. */
- idx = get_format_idx(WINED3DFMT_ATI1N);
- adapter->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
- idx = get_format_idx(WINED3DFMT_ATI2N);
- adapter->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
- idx = get_format_idx(WINED3DFMT_BC4_UNORM);
- adapter->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
- idx = get_format_idx(WINED3DFMT_BC4_SNORM);
- adapter->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
- idx = get_format_idx(WINED3DFMT_BC5_UNORM);
- adapter->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
- idx = get_format_idx(WINED3DFMT_BC5_SNORM);
- adapter->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
+ format = get_format_internal(adapter, WINED3DFMT_ATI1N);
+ format->flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
+ format = get_format_internal(adapter, WINED3DFMT_ATI2N);
+ format->flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
+ format = get_format_internal(adapter, WINED3DFMT_BC4_UNORM);
+ format->flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
+ format = get_format_internal(adapter, WINED3DFMT_BC4_SNORM);
+ format->flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
+ format = get_format_internal(adapter, WINED3DFMT_BC5_UNORM);
+ format->flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
+ format = get_format_internal(adapter, WINED3DFMT_BC5_SNORM);
+ format->flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
}
static unsigned int calculate_vertex_attribute_size(GLenum type, unsigned int component_count)
--
2.16.4
2
1
Aug. 30, 2018
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/wined3d/directx.c | 5 +-
dlls/wined3d/texture.c | 1 -
dlls/wined3d/utils.c | 236 +++++++++++++++++++++--------------------
dlls/wined3d/wined3d_private.h | 6 +-
4 files changed, 127 insertions(+), 121 deletions(-)
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 8fa3a2492dfe..ab6a452a2e8c 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -73,7 +73,7 @@ UINT64 adapter_adjust_memory(struct wined3d_adapter *adapter, INT64 amount)
static void wined3d_adapter_cleanup(struct wined3d_adapter *adapter)
{
- heap_free(adapter->gl_info.formats);
+ heap_free(adapter->formats);
heap_free(adapter->cfgs);
}
@@ -2512,6 +2512,9 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, unsigned int o
TRACE("Allocated LUID %08x:%08x for adapter %p.\n",
adapter->luid.HighPart, adapter->luid.LowPart, adapter);
+ adapter->formats = NULL;
+ adapter->format_count = 0;
+
if (wined3d_creation_flags & WINED3D_NO3D)
return wined3d_adapter_no3d_init(adapter);
return wined3d_adapter_opengl_init(adapter, wined3d_creation_flags);
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index f72442d1ddfe..8f499d4ada60 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -2656,7 +2656,6 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
if (desc->resource_type != WINED3D_RTYPE_TEXTURE_3D && !gl_info->supported[ARB_TEXTURE_RECTANGLE]
&& !gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT])
{
-
/* TODO: Add support for non-power-of-two compressed textures. */
if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D]
& (WINED3DFMT_FLAG_COMPRESSED | WINED3DFMT_FLAG_HEIGHT_SCALE))
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 0c80756e2a87..bc225878e5e8 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -1936,7 +1936,7 @@ static inline int get_format_idx(enum wined3d_format_id format_id)
return -1;
}
-static struct wined3d_format *get_format_internal(struct wined3d_gl_info *gl_info,
+static struct wined3d_format *get_format_internal(const struct wined3d_adapter *adapter,
enum wined3d_format_id format_id)
{
int fmt_idx;
@@ -1947,7 +1947,7 @@ static struct wined3d_format *get_format_internal(struct wined3d_gl_info *gl_inf
return NULL;
}
- return &gl_info->formats[fmt_idx];
+ return &adapter->formats[fmt_idx];
}
static void copy_format(struct wined3d_format *dst_format, const struct wined3d_format *src_format)
@@ -1999,14 +1999,14 @@ static enum wined3d_channel_type map_channel_type(char t)
}
}
-static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
+static BOOL init_format_base_info(struct wined3d_adapter *adapter)
{
struct wined3d_format *format;
unsigned int i, j;
- gl_info->format_count = WINED3D_FORMAT_COUNT;
- if (!(gl_info->formats = heap_calloc(gl_info->format_count
- + ARRAY_SIZE(typeless_depth_stencil_formats), sizeof(*gl_info->formats))))
+ adapter->format_count = WINED3D_FORMAT_COUNT;
+ if (!(adapter->formats = heap_calloc(adapter->format_count
+ + ARRAY_SIZE(typeless_depth_stencil_formats), sizeof(*adapter->formats))))
{
ERR("Failed to allocate memory.\n");
return FALSE;
@@ -2014,7 +2014,7 @@ static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
for (i = 0; i < ARRAY_SIZE(formats); ++i)
{
- if (!(format = get_format_internal(gl_info, formats[i].id)))
+ if (!(format = get_format_internal(adapter, formats[i].id)))
goto fail;
format->id = formats[i].id;
@@ -2039,10 +2039,10 @@ static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
const struct wined3d_format *typeless_format;
DWORD flags = 0;
- if (!(format = get_format_internal(gl_info, typed_formats[i].id)))
+ if (!(format = get_format_internal(adapter, typed_formats[i].id)))
goto fail;
- if (!(typeless_format = get_format_internal(gl_info, typed_formats[i].typeless_id)))
+ if (!(typeless_format = get_format_internal(adapter, typed_formats[i].typeless_id)))
goto fail;
format->id = typed_formats[i].id;
@@ -2082,7 +2082,7 @@ static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
for (i = 0; i < ARRAY_SIZE(ddi_formats); ++i)
{
- if (!(format = get_format_internal(gl_info, ddi_formats[i].id)))
+ if (!(format = get_format_internal(adapter, ddi_formats[i].id)))
goto fail;
format->ddi_format = ddi_formats[i].ddi_format;
@@ -2090,7 +2090,7 @@ static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
for (i = 0; i < ARRAY_SIZE(format_base_flags); ++i)
{
- if (!(format = get_format_internal(gl_info, format_base_flags[i].id)))
+ if (!(format = get_format_internal(adapter, format_base_flags[i].id)))
goto fail;
format_set_flag(format, format_base_flags[i].flags);
@@ -2099,18 +2099,18 @@ static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
return TRUE;
fail:
- heap_free(gl_info->formats);
+ heap_free(adapter->formats);
return FALSE;
}
-static BOOL init_format_block_info(struct wined3d_gl_info *gl_info)
+static BOOL init_format_block_info(struct wined3d_adapter *adapter)
{
struct wined3d_format *format;
unsigned int i;
for (i = 0; i < ARRAY_SIZE(format_block_info); ++i)
{
- if (!(format = get_format_internal(gl_info, format_block_info[i].id)))
+ if (!(format = get_format_internal(adapter, format_block_info[i].id)))
return FALSE;
format->block_width = format_block_info[i].block_width;
@@ -2135,14 +2135,14 @@ static BOOL init_format_block_info(struct wined3d_gl_info *gl_info)
*
* Affected applications include "Heroes VI", "From Dust", "Halo Online" and
* "Eldorado". */
-static BOOL init_format_decompress_info(struct wined3d_gl_info *gl_info)
+static BOOL init_format_decompress_info(struct wined3d_adapter *adapter)
{
struct wined3d_format *format;
unsigned int i;
for (i = 0; i < ARRAY_SIZE(format_decompress_info); ++i)
{
- if (!(format = get_format_internal(gl_info, format_decompress_info[i].id)))
+ if (!(format = get_format_internal(adapter, format_decompress_info[i].id)))
return FALSE;
format->flags[WINED3D_GL_RES_TYPE_TEX_3D] |= WINED3DFMT_FLAG_DECOMPRESS;
@@ -2723,7 +2723,8 @@ static void query_format_flag(struct wined3d_gl_info *gl_info, struct wined3d_fo
}
/* Context activation is done by the caller. */
-static void init_format_fbo_compat_info(struct wined3d_caps_gl_ctx *ctx)
+static void init_format_fbo_compat_info(const struct wined3d_adapter *adapter,
+ struct wined3d_caps_gl_ctx *ctx)
{
const struct wined3d_gl_info *gl_info = ctx->gl_info;
unsigned int i, type;
@@ -2731,12 +2732,12 @@ static void init_format_fbo_compat_info(struct wined3d_caps_gl_ctx *ctx)
if (gl_info->supported[ARB_INTERNALFORMAT_QUERY2])
{
- for (i = 0; i < gl_info->format_count; ++i)
+ for (i = 0; i < adapter->format_count; ++i)
{
- GLint value;
- struct wined3d_format *format = &gl_info->formats[i];
BOOL fallback_fmt_used = FALSE, regular_fmt_used = FALSE;
+ struct wined3d_format *format = &adapter->formats[i];
GLenum rt_internal = format->rtInternal;
+ GLint value;
if (!format->glInternal)
continue;
@@ -2845,9 +2846,9 @@ static void init_format_fbo_compat_info(struct wined3d_caps_gl_ctx *ctx)
gl_info->gl_ops.gl.p_glReadBuffer(GL_COLOR_ATTACHMENT0);
}
- for (i = 0; i < gl_info->format_count; ++i)
+ for (i = 0; i < adapter->format_count; ++i)
{
- struct wined3d_format *format = &gl_info->formats[i];
+ struct wined3d_format *format = &adapter->formats[i];
if (!format->glInternal) continue;
@@ -3125,7 +3126,7 @@ static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct win
for (i = 0; i < ARRAY_SIZE(format_texture_info); ++i)
{
- if (!(format = get_format_internal(gl_info, format_texture_info[i].id)))
+ if (!(format = get_format_internal(adapter, format_texture_info[i].id)))
return FALSE;
if (!gl_info->supported[format_texture_info[i].extension])
@@ -3189,7 +3190,7 @@ static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct win
{
if (format_srgb_info[j].base_format_id == format->id)
{
- if (!(srgb_format = get_format_internal(gl_info, format_srgb_info[j].srgb_format_id)))
+ if (!(srgb_format = get_format_internal(adapter, format_srgb_info[j].srgb_format_id)))
return FALSE;
break;
}
@@ -3324,8 +3325,10 @@ static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
return ret;
}
-static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
+static void init_format_filter_info(struct wined3d_adapter *adapter,
+ struct wined3d_gl_info *gl_info)
{
+ enum wined3d_pci_vendor vendor = adapter->driver_info.vendor;
struct wined3d_format *format;
unsigned int fmt_idx, i;
static const enum wined3d_format_id fmts16[] =
@@ -3365,7 +3368,7 @@ static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3
for (i = 0; i < ARRAY_SIZE(fmts16); ++i)
{
fmt_idx = get_format_idx(fmts16[i]);
- format_set_flag(&gl_info->formats[fmt_idx], WINED3DFMT_FLAG_FILTERING);
+ format_set_flag(&adapter->formats[fmt_idx], WINED3DFMT_FLAG_FILTERING);
}
}
return;
@@ -3374,10 +3377,10 @@ static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3
for (i = 0; i < ARRAY_SIZE(fmts16); ++i)
{
fmt_idx = get_format_idx(fmts16[i]);
- format = &gl_info->formats[fmt_idx];
+ format = &adapter->formats[fmt_idx];
if (!format->glInternal) continue; /* Not supported by GL */
- filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal);
+ filtered = check_filter(gl_info, adapter->formats[fmt_idx].glInternal);
if (filtered)
{
TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
@@ -3396,23 +3399,23 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_
int idx;
idx = get_format_idx(WINED3DFMT_R16_FLOAT);
- gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ adapter->formats[idx].color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
idx = get_format_idx(WINED3DFMT_R32_FLOAT);
- gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ adapter->formats[idx].color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
idx = get_format_idx(WINED3DFMT_R16G16_UNORM);
- gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ adapter->formats[idx].color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
idx = get_format_idx(WINED3DFMT_R16G16_FLOAT);
- gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ adapter->formats[idx].color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
idx = get_format_idx(WINED3DFMT_R32G32_FLOAT);
- gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ adapter->formats[idx].color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
/* GL_ATI_envmap_bumpmap in theory supports R8G8_SNORM but is no longer supported by
@@ -3423,10 +3426,10 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_
* returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
* conversion for this format. */
idx = get_format_idx(WINED3DFMT_R8G8_SNORM);
- gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ adapter->formats[idx].color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
idx = get_format_idx(WINED3DFMT_R16G16_SNORM);
- gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ adapter->formats[idx].color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
}
else
@@ -3434,40 +3437,40 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_
/* Emulate using unsigned formats. This requires load-time conversion in addition to the
* fixups here. */
idx = get_format_idx(WINED3DFMT_R8G8_SNORM);
- gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ adapter->formats[idx].color_fixup = create_color_fixup_desc(
1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
idx = get_format_idx(WINED3DFMT_R16G16_SNORM);
- gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ adapter->formats[idx].color_fixup = create_color_fixup_desc(
1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
idx = get_format_idx(WINED3DFMT_R8G8B8A8_SNORM);
- gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ adapter->formats[idx].color_fixup = create_color_fixup_desc(
1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
idx = get_format_idx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
- gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ adapter->formats[idx].color_fixup = create_color_fixup_desc(
1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
}
if (!gl_info->supported[NV_TEXTURE_SHADER])
{
idx = get_format_idx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
- gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ adapter->formats[idx].color_fixup = create_color_fixup_desc(
1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
}
if (gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC] || gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
{
idx = get_format_idx(WINED3DFMT_ATI1N);
- gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ adapter->formats[idx].color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X);
idx = get_format_idx(WINED3DFMT_ATI2N);
- gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ adapter->formats[idx].color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
}
else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
{
idx = get_format_idx(WINED3DFMT_ATI2N);
- gl_info->formats[idx].color_fixup= create_color_fixup_desc(
+ adapter->formats[idx].color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
}
@@ -3475,81 +3478,81 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_
|| (gl_info->supported[ARB_FRAGMENT_SHADER] && gl_info->supported[ARB_VERTEX_SHADER])))
{
idx = get_format_idx(WINED3DFMT_YUY2);
- gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
+ adapter->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
idx = get_format_idx(WINED3DFMT_UYVY);
- gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
+ adapter->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
}
else if (!gl_info->supported[APPLE_YCBCR_422] && (!gl_info->supported[ARB_FRAGMENT_PROGRAM]
&& (!gl_info->supported[ARB_FRAGMENT_SHADER] || !gl_info->supported[ARB_VERTEX_SHADER])))
{
idx = get_format_idx(WINED3DFMT_YUY2);
- gl_info->formats[idx].glInternal = 0;
+ adapter->formats[idx].glInternal = 0;
idx = get_format_idx(WINED3DFMT_UYVY);
- gl_info->formats[idx].glInternal = 0;
+ adapter->formats[idx].glInternal = 0;
}
if (gl_info->supported[ARB_FRAGMENT_PROGRAM]
|| (gl_info->supported[ARB_FRAGMENT_SHADER] && gl_info->supported[ARB_VERTEX_SHADER]))
{
idx = get_format_idx(WINED3DFMT_YV12);
- format_set_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_HEIGHT_SCALE);
- gl_info->formats[idx].height_scale.numerator = 3;
- gl_info->formats[idx].height_scale.denominator = 2;
- gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
+ format_set_flag(&adapter->formats[idx], WINED3DFMT_FLAG_HEIGHT_SCALE);
+ adapter->formats[idx].height_scale.numerator = 3;
+ adapter->formats[idx].height_scale.denominator = 2;
+ adapter->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
idx = get_format_idx(WINED3DFMT_NV12);
- format_set_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_HEIGHT_SCALE);
- gl_info->formats[idx].height_scale.numerator = 3;
- gl_info->formats[idx].height_scale.denominator = 2;
- gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_NV12);
+ format_set_flag(&adapter->formats[idx], WINED3DFMT_FLAG_HEIGHT_SCALE);
+ adapter->formats[idx].height_scale.numerator = 3;
+ adapter->formats[idx].height_scale.denominator = 2;
+ adapter->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_NV12);
}
else
{
idx = get_format_idx(WINED3DFMT_YV12);
- gl_info->formats[idx].glInternal = 0;
+ adapter->formats[idx].glInternal = 0;
idx = get_format_idx(WINED3DFMT_NV12);
- gl_info->formats[idx].glInternal = 0;
+ adapter->formats[idx].glInternal = 0;
}
if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
{
idx = get_format_idx(WINED3DFMT_A8_UNORM);
- gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ adapter->formats[idx].color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_ZERO, 0, CHANNEL_SOURCE_ZERO, 0, CHANNEL_SOURCE_ZERO, 0, CHANNEL_SOURCE_X);
idx = get_format_idx(WINED3DFMT_L8A8_UNORM);
- gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ adapter->formats[idx].color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y);
idx = get_format_idx(WINED3DFMT_L4A4_UNORM);
- gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ adapter->formats[idx].color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y);
idx = get_format_idx(WINED3DFMT_L16_UNORM);
- gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ adapter->formats[idx].color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE);
idx = get_format_idx(WINED3DFMT_INTZ);
- gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ adapter->formats[idx].color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X);
}
if (gl_info->supported[ARB_TEXTURE_RG])
{
idx = get_format_idx(WINED3DFMT_L8_UNORM);
- gl_info->formats[idx].color_fixup = create_color_fixup_desc(
+ adapter->formats[idx].color_fixup = create_color_fixup_desc(
0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE);
}
if (gl_info->supported[ARB_FRAGMENT_PROGRAM] || gl_info->supported[ARB_FRAGMENT_SHADER])
{
idx = get_format_idx(WINED3DFMT_P8_UINT);
- gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
+ adapter->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
}
if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
{
idx = get_format_idx(WINED3DFMT_B8G8R8A8_UNORM);
- gl_info->formats[idx].gl_vtx_format = GL_BGRA;
+ adapter->formats[idx].gl_vtx_format = GL_BGRA;
}
if (!gl_info->supported[ARB_HALF_FLOAT_VERTEX])
@@ -3557,28 +3560,28 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_
/* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
* It is the job of the vertex buffer code to make sure that the vbos have the right format */
idx = get_format_idx(WINED3DFMT_R16G16_FLOAT);
- gl_info->formats[idx].gl_vtx_type = GL_FLOAT;
+ adapter->formats[idx].gl_vtx_type = GL_FLOAT;
idx = get_format_idx(WINED3DFMT_R16G16B16A16_FLOAT);
- gl_info->formats[idx].gl_vtx_type = GL_FLOAT;
+ adapter->formats[idx].gl_vtx_type = GL_FLOAT;
}
if (!gl_info->supported[ARB_HALF_FLOAT_PIXEL])
{
idx = get_format_idx(WINED3DFMT_R16_FLOAT);
- format_clear_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE);
+ format_clear_flag(&adapter->formats[idx], WINED3DFMT_FLAG_TEXTURE);
idx = get_format_idx(WINED3DFMT_R16G16_FLOAT);
- format_clear_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE);
+ format_clear_flag(&adapter->formats[idx], WINED3DFMT_FLAG_TEXTURE);
idx = get_format_idx(WINED3DFMT_R16G16B16A16_FLOAT);
- format_clear_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE);
+ format_clear_flag(&adapter->formats[idx], WINED3DFMT_FLAG_TEXTURE);
}
if (gl_info->quirks & WINED3D_QUIRK_BROKEN_RGBA16)
{
idx = get_format_idx(WINED3DFMT_R16G16B16A16_UNORM);
- format_clear_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE);
+ format_clear_flag(&adapter->formats[idx], WINED3DFMT_FLAG_TEXTURE);
}
/* ATI instancing hack: Although ATI cards do not support Shader Model
@@ -3597,7 +3600,7 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_
if (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_VERTEX_SHADER])
{
idx = get_format_idx(WINED3DFMT_INST);
- format_set_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE);
+ format_set_flag(&adapter->formats[idx], WINED3DFMT_FLAG_TEXTURE);
}
/* Depth bound test. To query if the card supports it CheckDeviceFormat()
@@ -3609,7 +3612,7 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_
if (gl_info->supported[EXT_DEPTH_BOUNDS_TEST])
{
idx = get_format_idx(WINED3DFMT_NVDB);
- format_set_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE);
+ format_set_flag(&adapter->formats[idx], WINED3DFMT_FLAG_TEXTURE);
}
/* RESZ aka AMD DX9-level hack for multisampled depth buffer resolve. You query for RESZ
@@ -3618,12 +3621,12 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_
if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
{
idx = get_format_idx(WINED3DFMT_RESZ);
- format_set_flag(&gl_info->formats[idx], WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET);
+ format_set_flag(&adapter->formats[idx], WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_RENDERTARGET);
}
- for (i = 0; i < gl_info->format_count; ++i)
+ for (i = 0; i < adapter->format_count; ++i)
{
- struct wined3d_format *format = &gl_info->formats[i];
+ struct wined3d_format *format = &adapter->formats[i];
if (!(format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_TEXTURE))
continue;
@@ -3648,17 +3651,17 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_
/* These formats are not supported for 3D textures. See also
* WINED3DFMT_FLAG_DECOMPRESS. */
idx = get_format_idx(WINED3DFMT_ATI1N);
- gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
+ adapter->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
idx = get_format_idx(WINED3DFMT_ATI2N);
- gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
+ adapter->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
idx = get_format_idx(WINED3DFMT_BC4_UNORM);
- gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
+ adapter->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
idx = get_format_idx(WINED3DFMT_BC4_SNORM);
- gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
+ adapter->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
idx = get_format_idx(WINED3DFMT_BC5_UNORM);
- gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
+ adapter->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
idx = get_format_idx(WINED3DFMT_BC5_SNORM);
- gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
+ adapter->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
}
static unsigned int calculate_vertex_attribute_size(GLenum type, unsigned int component_count)
@@ -3689,14 +3692,15 @@ static unsigned int calculate_vertex_attribute_size(GLenum type, unsigned int co
}
}
-static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
+static BOOL init_format_vertex_info(const struct wined3d_adapter *adapter,
+ struct wined3d_gl_info *gl_info)
{
struct wined3d_format *format;
unsigned int i;
for (i = 0; i < ARRAY_SIZE(format_vertex_info); ++i)
{
- if (!(format = get_format_internal(gl_info, format_vertex_info[i].id)))
+ if (!(format = get_format_internal(adapter, format_vertex_info[i].id)))
return FALSE;
if (!gl_info->supported[format_vertex_info[i].extension])
@@ -3719,7 +3723,7 @@ static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
return TRUE;
}
-static BOOL init_typeless_formats(struct wined3d_gl_info *gl_info)
+static BOOL init_typeless_formats(const struct wined3d_adapter *adapter)
{
unsigned int flags[WINED3D_GL_RES_TYPE_COUNT];
unsigned int i, j;
@@ -3728,9 +3732,9 @@ static BOOL init_typeless_formats(struct wined3d_gl_info *gl_info)
{
struct wined3d_format *format, *typeless_format;
- if (!(format = get_format_internal(gl_info, typed_formats[i].id)))
+ if (!(format = get_format_internal(adapter, typed_formats[i].id)))
return FALSE;
- if (!(typeless_format = get_format_internal(gl_info, typed_formats[i].typeless_id)))
+ if (!(typeless_format = get_format_internal(adapter, typed_formats[i].typeless_id)))
return FALSE;
memcpy(flags, typeless_format->flags, sizeof(flags));
@@ -3745,12 +3749,12 @@ static BOOL init_typeless_formats(struct wined3d_gl_info *gl_info)
struct wined3d_format *depth_view_format, *stencil_view_format;
enum wined3d_format_id format_id;
- if (!(typeless_format = get_format_internal(gl_info, typeless_depth_stencil_formats[i].typeless_id)))
+ if (!(typeless_format = get_format_internal(adapter, typeless_depth_stencil_formats[i].typeless_id)))
return FALSE;
- if (!(ds_format = get_format_internal(gl_info, typeless_depth_stencil_formats[i].depth_stencil_id)))
+ if (!(ds_format = get_format_internal(adapter, typeless_depth_stencil_formats[i].depth_stencil_id)))
return FALSE;
- typeless_ds_format = &gl_info->formats[WINED3D_FORMAT_COUNT + i];
+ typeless_ds_format = &adapter->formats[WINED3D_FORMAT_COUNT + i];
typeless_ds_format->id = typeless_depth_stencil_formats[i].typeless_id;
copy_format(typeless_ds_format, ds_format);
for (j = 0; j < ARRAY_SIZE(typeless_ds_format->flags); ++j)
@@ -3762,13 +3766,13 @@ static BOOL init_typeless_formats(struct wined3d_gl_info *gl_info)
if ((format_id = typeless_depth_stencil_formats[i].depth_view_id)
&& typeless_depth_stencil_formats[i].separate_depth_view_format)
{
- if (!(depth_view_format = get_format_internal(gl_info, format_id)))
+ if (!(depth_view_format = get_format_internal(adapter, format_id)))
return FALSE;
copy_format(depth_view_format, ds_format);
}
if ((format_id = typeless_depth_stencil_formats[i].stencil_view_id))
{
- if (!(stencil_view_format = get_format_internal(gl_info, format_id)))
+ if (!(stencil_view_format = get_format_internal(adapter, format_id)))
return FALSE;
copy_format(stencil_view_format, ds_format);
}
@@ -3777,16 +3781,17 @@ static BOOL init_typeless_formats(struct wined3d_gl_info *gl_info)
return TRUE;
}
-static void init_format_gen_mipmap_info(struct wined3d_gl_info *gl_info)
+static void init_format_gen_mipmap_info(const struct wined3d_adapter *adapter,
+ struct wined3d_gl_info *gl_info)
{
unsigned int i, j;
if (!gl_info->fbo_ops.glGenerateMipmap)
return;
- for (i = 0; i < gl_info->format_count; ++i)
+ for (i = 0; i < adapter->format_count; ++i)
{
- struct wined3d_format *format = &gl_info->formats[i];
+ struct wined3d_format *format = &adapter->formats[i];
for (j = 0; j < ARRAY_SIZE(format->flags); ++j)
if (!(~format->flags[j] & (WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FILTERING)))
@@ -3935,15 +3940,15 @@ static float wined3d_adapter_find_polyoffset_scale(struct wined3d_caps_gl_ctx *c
return (float)(1u << cur);
}
-static void init_format_depth_bias_scale(struct wined3d_caps_gl_ctx *ctx,
- const struct wined3d_d3d_info *d3d_info)
+static void init_format_depth_bias_scale(struct wined3d_adapter *adapter,
+ struct wined3d_caps_gl_ctx *ctx)
{
- const struct wined3d_gl_info *gl_info = ctx->gl_info;
+ const struct wined3d_d3d_info *d3d_info = &adapter->d3d_info;
unsigned int i;
- for (i = 0; i < gl_info->format_count; ++i)
+ for (i = 0; i < adapter->format_count; ++i)
{
- struct wined3d_format *format = &gl_info->formats[i];
+ struct wined3d_format *format = &adapter->formats[i];
if (format->flags[WINED3D_GL_RES_TYPE_RB] & WINED3DFMT_FLAG_DEPTH)
{
@@ -3969,35 +3974,34 @@ BOOL wined3d_adapter_init_format_info(struct wined3d_adapter *adapter, struct wi
{
struct wined3d_gl_info *gl_info = &adapter->gl_info;
- if (!init_format_base_info(gl_info)) return FALSE;
- if (!init_format_block_info(gl_info)) goto fail;
- if (!init_format_decompress_info(gl_info)) goto fail;
+ if (!init_format_base_info(adapter)) return FALSE;
+ if (!init_format_block_info(adapter)) goto fail;
+ if (!init_format_decompress_info(adapter)) goto fail;
if (!ctx) /* WINED3D_NO3D */
return TRUE;
if (!init_format_texture_info(adapter, gl_info)) goto fail;
- if (!init_format_vertex_info(gl_info)) goto fail;
+ if (!init_format_vertex_info(adapter, gl_info)) goto fail;
apply_format_fixups(adapter, gl_info);
- init_format_fbo_compat_info(ctx);
- init_format_filter_info(gl_info, adapter->driver_info.vendor);
- if (!init_typeless_formats(gl_info)) goto fail;
- init_format_gen_mipmap_info(gl_info);
- init_format_depth_bias_scale(ctx, &adapter->d3d_info);
+ init_format_fbo_compat_info(adapter, ctx);
+ init_format_filter_info(adapter, gl_info);
+ if (!init_typeless_formats(adapter)) goto fail;
+ init_format_gen_mipmap_info(adapter, gl_info);
+ init_format_depth_bias_scale(adapter, ctx);
return TRUE;
fail:
- heap_free(gl_info->formats);
- gl_info->formats = NULL;
+ heap_free(adapter->formats);
+ adapter->formats = NULL;
return FALSE;
}
const struct wined3d_format *wined3d_get_format(const struct wined3d_adapter *adapter,
enum wined3d_format_id format_id, unsigned int resource_usage)
{
- const struct wined3d_gl_info *gl_info = &adapter->gl_info;
const struct wined3d_format *format;
int idx = get_format_idx(format_id);
unsigned int i;
@@ -4006,22 +4010,22 @@ const struct wined3d_format *wined3d_get_format(const struct wined3d_adapter *ad
{
FIXME("Can't find format %s (%#x) in the format lookup table.\n",
debug_d3dformat(format_id), format_id);
- return &gl_info->formats[get_format_idx(WINED3DFMT_UNKNOWN)];
+ return &adapter->formats[get_format_idx(WINED3DFMT_UNKNOWN)];
}
- format = &gl_info->formats[idx];
+ format = &adapter->formats[idx];
if (resource_usage & WINED3DUSAGE_DEPTHSTENCIL && wined3d_format_is_typeless(format))
{
for (i = 0; i < ARRAY_SIZE(typeless_depth_stencil_formats); ++i)
{
if (typeless_depth_stencil_formats[i].typeless_id == format_id)
- return &gl_info->formats[WINED3D_FORMAT_COUNT + i];
+ return &adapter->formats[WINED3D_FORMAT_COUNT + i];
}
FIXME("Cannot find depth/stencil typeless format %s (%#x).\n",
debug_d3dformat(format_id), format_id);
- return &gl_info->formats[get_format_idx(WINED3DFMT_UNKNOWN)];
+ return &adapter->formats[get_format_idx(WINED3DFMT_UNKNOWN)];
}
return format;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index da3cd4615686..70841683e5ba 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2599,9 +2599,6 @@ struct wined3d_gl_info
HGLRC (WINAPI *p_wglCreateContextAttribsARB)(HDC dc, HGLRC share, const GLint *attribs);
struct opengl_funcs gl_ops;
struct wined3d_fbo_ops fbo_ops;
-
- struct wined3d_format *formats;
- unsigned int format_count;
};
/* The driver names reflect the lowest GPU supported
@@ -2682,6 +2679,9 @@ struct wined3d_adapter
UINT64 vram_bytes_used;
LUID luid;
+ struct wined3d_format *formats;
+ unsigned int format_count;
+
const struct wined3d_vertex_pipe_ops *vertex_pipe;
const struct fragment_pipeline *fragment_pipe;
const struct wined3d_shader_backend_ops *shader_backend;
--
2.16.4
2
1
[PATCH 1/3] dxgi: Add support for DXGI_FORMAT_R10G10B10A2_UNORM D3D12 swapchains.
by Józef Kucia Aug. 30, 2018
by Józef Kucia Aug. 30, 2018
Aug. 30, 2018
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/dxgi/swapchain.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c
index b285f3d33e0a..6eda2353152e 100644
--- a/dlls/dxgi/swapchain.c
+++ b/dlls/dxgi/swapchain.c
@@ -917,6 +917,7 @@ static DXGI_FORMAT dxgi_format_from_vk_format(VkFormat vk_format)
case VK_FORMAT_B8G8R8A8_UNORM: return DXGI_FORMAT_B8G8R8A8_UNORM;
case VK_FORMAT_R8G8B8A8_SRGB: return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
case VK_FORMAT_R8G8B8A8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM;
+ case VK_FORMAT_A2B10G10R10_UNORM_PACK32: return DXGI_FORMAT_R10G10B10A2_UNORM;
default:
WARN("Unhandled format %#x.\n", vk_format);
return DXGI_FORMAT_UNKNOWN;
@@ -929,6 +930,7 @@ static VkFormat get_swapchain_fallback_format(VkFormat vk_format)
{
case VK_FORMAT_R8G8B8A8_SRGB: return VK_FORMAT_B8G8R8A8_SRGB;
case VK_FORMAT_R8G8B8A8_UNORM: return VK_FORMAT_B8G8R8A8_UNORM;
+ case VK_FORMAT_A2B10G10R10_UNORM_PACK32: return VK_FORMAT_B8G8R8A8_UNORM;
default:
WARN("Unhandled format %#x.\n", vk_format);
return VK_FORMAT_UNDEFINED;
--
2.16.4
2
1
Aug. 30, 2018
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/dxgi/swapchain.c | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c
index 6eda2353152e..f8e4f8078e74 100644
--- a/dlls/dxgi/swapchain.c
+++ b/dlls/dxgi/swapchain.c
@@ -37,6 +37,24 @@
WINE_DEFAULT_DEBUG_CHANNEL(dxgi);
WINE_DECLARE_DEBUG_CHANNEL(winediag);
+static DXGI_SWAP_EFFECT dxgi_swap_effect_from_wined3d(enum wined3d_swap_effect swap_effect)
+{
+ switch (swap_effect)
+ {
+ case WINED3D_SWAP_EFFECT_DISCARD:
+ return DXGI_SWAP_EFFECT_DISCARD;
+ case WINED3D_SWAP_EFFECT_SEQUENTIAL:
+ return DXGI_SWAP_EFFECT_SEQUENTIAL;
+ case WINED3D_SWAP_EFFECT_FLIP_DISCARD:
+ return DXGI_SWAP_EFFECT_FLIP_DISCARD;
+ case WINED3D_SWAP_EFFECT_FLIP_SEQUENTIAL:
+ return DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
+ default:
+ FIXME("Invalid swap effect %#x.\n", swap_effect);
+ return DXGI_SWAP_EFFECT_DISCARD;
+ }
+}
+
static inline struct d3d11_swapchain *d3d11_swapchain_from_IDXGISwapChain1(IDXGISwapChain1 *iface)
{
return CONTAINING_RECORD(iface, struct d3d11_swapchain, IDXGISwapChain1_iface);
@@ -297,7 +315,7 @@ static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetDesc(IDXGISwapChain1 *iface,
wined3d_swapchain_get_desc(swapchain->wined3d_swapchain, &wined3d_desc);
wined3d_mutex_unlock();
- FIXME("Ignoring ScanlineOrdering, Scaling and SwapEffect.\n");
+ FIXME("Ignoring ScanlineOrdering and Scaling.\n");
desc->BufferDesc.Width = wined3d_desc.backbuffer_width;
desc->BufferDesc.Height = wined3d_desc.backbuffer_height;
@@ -312,7 +330,7 @@ static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetDesc(IDXGISwapChain1 *iface,
desc->BufferCount = wined3d_desc.backbuffer_count;
desc->OutputWindow = wined3d_desc.device_window;
desc->Windowed = wined3d_desc.windowed;
- desc->SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
+ desc->SwapEffect = dxgi_swap_effect_from_wined3d(wined3d_desc.swap_effect);
desc->Flags = dxgi_swapchain_flags_from_wined3d(wined3d_desc.flags);
return S_OK;
@@ -457,7 +475,7 @@ static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetDesc1(IDXGISwapChain1 *iface
wined3d_swapchain_get_desc(swapchain->wined3d_swapchain, &wined3d_desc);
wined3d_mutex_unlock();
- FIXME("Ignoring Stereo, Scaling, SwapEffect and AlphaMode.\n");
+ FIXME("Ignoring Stereo, Scaling and AlphaMode.\n");
desc->Width = wined3d_desc.backbuffer_width;
desc->Height = wined3d_desc.backbuffer_height;
@@ -468,7 +486,7 @@ static HRESULT STDMETHODCALLTYPE d3d11_swapchain_GetDesc1(IDXGISwapChain1 *iface
desc->BufferUsage = dxgi_usage_from_wined3d_usage(wined3d_desc.backbuffer_usage);
desc->BufferCount = wined3d_desc.backbuffer_count;
desc->Scaling = DXGI_SCALING_STRETCH;
- desc->SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
+ desc->SwapEffect = dxgi_swap_effect_from_wined3d(wined3d_desc.swap_effect);
desc->AlphaMode = DXGI_ALPHA_MODE_IGNORE;
desc->Flags = dxgi_swapchain_flags_from_wined3d(wined3d_desc.flags);
--
2.16.4
2
1
[PATCH 2/3] d3d12/tests: Add test for DXGI_FORMAT_R10G10B10A2_UNORM swapchain.
by Józef Kucia Aug. 30, 2018
by Józef Kucia Aug. 30, 2018
Aug. 30, 2018
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/d3d12/tests/d3d12.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/dlls/d3d12/tests/d3d12.c b/dlls/d3d12/tests/d3d12.c
index 2e2e69be0adc..7b610c0c85a9 100644
--- a/dlls/d3d12/tests/d3d12.c
+++ b/dlls/d3d12/tests/d3d12.c
@@ -47,6 +47,7 @@ static unsigned int format_size(DXGI_FORMAT format)
case DXGI_FORMAT_R8G8B8A8_UNORM:
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
case DXGI_FORMAT_B8G8R8A8_UNORM:
+ case DXGI_FORMAT_R10G10B10A2_UNORM:
return 4;
default:
trace("Unhandled format %#x.\n", format);
@@ -832,10 +833,12 @@ static void test_swapchain_draw(void)
}
tests[] =
{
- {DXGI_FORMAT_B8G8R8A8_UNORM, {1.0f, 0.0f, 0.0f, 1.0f}, 0xffff0000},
- {DXGI_FORMAT_B8G8R8A8_UNORM, {0.0f, 1.0f, 0.0f, 1.0f}, 0xff00ff00},
- {DXGI_FORMAT_R8G8B8A8_UNORM, {1.0f, 0.0f, 0.0f, 1.0f}, 0xff0000ff},
- {DXGI_FORMAT_R8G8B8A8_UNORM, {0.0f, 1.0f, 0.0f, 1.0f}, 0xff00ff00},
+ {DXGI_FORMAT_B8G8R8A8_UNORM, {1.0f, 0.0f, 0.0f, 1.0f}, 0xffff0000},
+ {DXGI_FORMAT_B8G8R8A8_UNORM, {0.0f, 1.0f, 0.0f, 1.0f}, 0xff00ff00},
+ {DXGI_FORMAT_R8G8B8A8_UNORM, {1.0f, 0.0f, 0.0f, 1.0f}, 0xff0000ff},
+ {DXGI_FORMAT_R8G8B8A8_UNORM, {0.0f, 1.0f, 0.0f, 1.0f}, 0xff00ff00},
+ {DXGI_FORMAT_R10G10B10A2_UNORM, {1.0f, 0.0f, 0.0f, 1.0f}, 0xc00003ff},
+ {DXGI_FORMAT_R10G10B10A2_UNORM, {0.0f, 1.0f, 0.0f, 1.0f}, 0xc00ffc00},
};
desc.no_pipeline = TRUE;
--
2.16.4
2
1
[PATCH v2] shell32/autocomplete: Revamp pwzsRegKeyPath handling so it can deal with arbitrary sizes and make it more robust
by Gabriel Ivăncescu Aug. 30, 2018
by Gabriel Ivăncescu Aug. 30, 2018
Aug. 30, 2018
Handle heap_alloc failure, reg strings without a \ character at all, try
harder to find the reg path (if only value fails the lookup), and read the
registry value with any size.
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
v2: Retrieve the registry value without failing in rare race conditions.
dlls/shell32/autocomplete.c | 93 +++++++++++++++++++++++++++++----------------
1 file changed, 61 insertions(+), 32 deletions(-)
diff --git a/dlls/shell32/autocomplete.c b/dlls/shell32/autocomplete.c
index 5fe48e9..99d5ae7 100644
--- a/dlls/shell32/autocomplete.c
+++ b/dlls/shell32/autocomplete.c
@@ -486,40 +486,69 @@ static HRESULT WINAPI IAutoComplete2_fnInit(
if (This->options & ACO_AUTOSUGGEST)
create_listbox(This);
- if (pwzsRegKeyPath) {
- WCHAR *key;
- WCHAR result[MAX_PATH];
- WCHAR *value;
- HKEY hKey = 0;
- LONG res;
- LONG len;
-
- /* pwszRegKeyPath contains the key as well as the value, so we split */
- key = heap_alloc((lstrlenW(pwzsRegKeyPath)+1)*sizeof(WCHAR));
- strcpyW(key, pwzsRegKeyPath);
- value = strrchrW(key, '\\');
- *value = 0;
- value++;
- /* Now value contains the value and buffer the key */
- res = RegOpenKeyExW(HKEY_CURRENT_USER, key, 0, KEY_READ, &hKey);
- if (res != ERROR_SUCCESS) {
- /* if the key is not found, MSDN states we must seek in HKEY_LOCAL_MACHINE */
- res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hKey);
- }
- if (res == ERROR_SUCCESS) {
- res = RegQueryValueW(hKey, value, result, &len);
- if (res == ERROR_SUCCESS) {
- This->quickComplete = heap_alloc(len*sizeof(WCHAR));
- strcpyW(This->quickComplete, result);
- }
- RegCloseKey(hKey);
- }
- heap_free(key);
+ if (pwzsRegKeyPath)
+ {
+ WCHAR *key, *value;
+ DWORD type, sz = MAX_PATH * sizeof(WCHAR);
+ BYTE *qc;
+ HKEY hKey;
+ LSTATUS res;
+ size_t len;
+
+ /* pwszRegKeyPath contains the key as well as the value, so split it */
+ value = strrchrW(pwzsRegKeyPath, '\\');
+ len = value - pwzsRegKeyPath;
+
+ if (value && (key = heap_alloc((len+1) * sizeof(*key))) != NULL) {
+ memcpy(key, pwzsRegKeyPath, len * sizeof(*key));
+ key[len] = '\0';
+ value++;
+
+ res = RegOpenKeyExW(HKEY_CURRENT_USER, key, 0, KEY_READ, &hKey);
+
+ /* if not found, MSDN states we must seek in HKEY_LOCAL_MACHINE */
+ if (res != ERROR_SUCCESS)
+ res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hKey);
+
+ if (res == ERROR_SUCCESS && (qc = heap_alloc(sz)) != NULL) {
+ res = RegQueryValueExW(hKey, value, NULL, &type, qc, &sz);
+
+ if ((res != ERROR_SUCCESS && res != ERROR_MORE_DATA) || type != REG_SZ)
+ {
+ RegCloseKey(hKey);
+ res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hKey);
+ if (res != ERROR_SUCCESS) {
+ heap_free(qc);
+ goto free_key_str;
+ }
+ sz = MAX_PATH * sizeof(WCHAR);
+ res = RegQueryValueExW(hKey, value, NULL, &type, qc, &sz);
+ }
+
+ for (;;) {
+ if (res == ERROR_SUCCESS && type == REG_SZ) {
+ This->quickComplete = heap_realloc(qc, sz);
+ break;
+ }
+ heap_free(qc);
+ if (res != ERROR_MORE_DATA || type != REG_SZ)
+ break;
+ if ((qc = heap_alloc(sz)) == NULL)
+ break;
+ res = RegQueryValueExW(hKey, value, NULL, &type, qc, &sz);
+ }
+ RegCloseKey(hKey);
+ }
+ free_key_str:
+ heap_free(key);
+ }
}
- if ((pwszQuickComplete) && (!This->quickComplete)) {
- This->quickComplete = heap_alloc((lstrlenW(pwszQuickComplete)+1)*sizeof(WCHAR));
- lstrcpyW(This->quickComplete, pwszQuickComplete);
+ if (!This->quickComplete && pwszQuickComplete)
+ {
+ size_t len = strlenW(pwszQuickComplete)+1;
+ if ((This->quickComplete = heap_alloc(len * sizeof(WCHAR))) != NULL)
+ memcpy(This->quickComplete, pwszQuickComplete, len * sizeof(WCHAR));
}
return S_OK;
--
1.9.1
1
0
[PATCH 1/3] shell32/autocomplete: Don't crash when there's another AutoComplete object on the same edit control
by Gabriel Ivăncescu Aug. 30, 2018
by Gabriel Ivăncescu Aug. 30, 2018
Aug. 30, 2018
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=22333
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
dlls/shell32/autocomplete.c | 33 +++++++++++++++++++++++++--------
1 file changed, 25 insertions(+), 8 deletions(-)
diff --git a/dlls/shell32/autocomplete.c b/dlls/shell32/autocomplete.c
index 99ce23d..5fe48e9 100644
--- a/dlls/shell32/autocomplete.c
+++ b/dlls/shell32/autocomplete.c
@@ -93,6 +93,14 @@ static inline IAutoCompleteImpl *impl_from_IAutoCompleteDropDown(IAutoCompleteDr
return CONTAINING_RECORD(iface, IAutoCompleteImpl, IAutoCompleteDropDown_iface);
}
+static void destroy_autocomplete_object(IAutoCompleteImpl *ac)
+{
+ ac->hwndEdit = NULL;
+ if (ac->hwndListBox)
+ DestroyWindow(ac->hwndListBox);
+ IAutoComplete2_Release(&ac->IAutoComplete2_iface);
+}
+
/*
Window procedure for autocompletion
*/
@@ -276,10 +284,7 @@ static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam,
RemovePropW(hwnd, autocomplete_propertyW);
SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR)proc);
- This->hwndEdit = NULL;
- if (This->hwndListBox)
- DestroyWindow(This->hwndListBox);
- IAutoComplete2_Release(&This->IAutoComplete2_iface);
+ destroy_autocomplete_object(This);
return CallWindowProcW(proc, hwnd, uMsg, wParam, lParam);
}
default:
@@ -434,7 +439,7 @@ static HRESULT WINAPI IAutoComplete2_fnInit(
LPCOLESTR pwzsRegKeyPath,
LPCOLESTR pwszQuickComplete)
{
- IAutoCompleteImpl *This = impl_from_IAutoComplete2(iface);
+ IAutoCompleteImpl *Other, *This = impl_from_IAutoComplete2(iface);
TRACE("(%p)->(%p, %p, %s, %s)\n",
This, hwndEdit, punkACL, debugstr_w(pwzsRegKeyPath), debugstr_w(pwszQuickComplete));
@@ -461,10 +466,22 @@ static HRESULT WINAPI IAutoComplete2_fnInit(
This->initialized = TRUE;
This->hwndEdit = hwndEdit;
- This->wpOrigEditProc = (WNDPROC) SetWindowLongPtrW( hwndEdit, GWLP_WNDPROC, (LONG_PTR) ACEditSubclassProc);
- /* Keep at least one reference to the object until the edit window is destroyed. */
+
+ /* If another AutoComplete object was previously assigned to this edit control,
+ release it but keep the same callback on the control, to avoid an infinite
+ recursive loop in ACEditSubclassProc while the property is set to this object */
+ Other = GetPropW(hwndEdit, autocomplete_propertyW);
+ SetPropW(hwndEdit, autocomplete_propertyW, This);
+
+ if (Other && Other->initialized) {
+ This->wpOrigEditProc = Other->wpOrigEditProc;
+ destroy_autocomplete_object(Other);
+ }
+ else
+ This->wpOrigEditProc = (WNDPROC) SetWindowLongPtrW(hwndEdit, GWLP_WNDPROC, (LONG_PTR) ACEditSubclassProc);
+
+ /* Keep at least one reference to the object until the edit window is destroyed */
IAutoComplete2_AddRef(&This->IAutoComplete2_iface);
- SetPropW( hwndEdit, autocomplete_propertyW, This );
if (This->options & ACO_AUTOSUGGEST)
create_listbox(This);
--
1.9.1
2
7
Aug. 30, 2018
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
v2: fixed up includes in main idl.
include/Makefile.in | 4 ++
include/msopc.idl | 89 ++++++++++++++++++++++++++++++++++++++
include/opcbase.idl | 28 ++++++++++++
include/opcobjectmodel.idl | 34 +++++++++++++++
include/opcparturi.idl | 71 ++++++++++++++++++++++++++++++
5 files changed, 226 insertions(+)
create mode 100644 include/msopc.idl
create mode 100644 include/opcbase.idl
create mode 100644 include/opcobjectmodel.idl
create mode 100644 include/opcparturi.idl
diff --git a/include/Makefile.in b/include/Makefile.in
index a89fef6eac..ffecb98d9e 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -399,6 +399,7 @@ SOURCES = \
msident.idl \
msinkaut.idl \
msiquery.h \
+ msopc.idl \
mssip.h \
msstkppg.h \
mstask.idl \
@@ -493,6 +494,9 @@ SOURCES = \
oledberr.h \
oledlg.h \
oleidl.idl \
+ opcbase.idl \
+ opcobjectmodel.idl \
+ opcparturi.idl \
opnrst.idl \
optary.idl \
patchapi.h \
diff --git a/include/msopc.idl b/include/msopc.idl
new file mode 100644
index 0000000000..12404e5a12
--- /dev/null
+++ b/include/msopc.idl
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2018 Nikolay Sivov for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+import "unknwn.idl";
+import "ocidl.idl";
+
+#include "opcbase.idl"
+#include "opcobjectmodel.idl"
+#include "opcparturi.idl"
+
+#ifndef __WIDL__
+#define threading(model)
+#endif
+
+interface IOpcUri;
+interface IOpcPartUri;
+interface IOpcPackage;
+interface IOpcDigitalSignatureManager;
+
+[
+ object,
+ uuid(6d0b4446-cd73-4ab3-94f4-8ccdf6116154),
+ pointer_default(ref)
+]
+interface IOpcFactory : IUnknown
+{
+ HRESULT CreatePackageRootUri(
+ [out, retval] IOpcUri **uri
+ );
+
+ HRESULT CreatePartUri(
+ [in, string] LPCWSTR uri,
+ [out, retval] IOpcPartUri **part_uri
+ );
+
+ [local]
+ HRESULT CreateStreamOnFile(
+ [in, string] LPCWSTR filename,
+ [in] OPC_STREAM_IO_MODE io_mode,
+ [in, unique] SECURITY_ATTRIBUTES *sa,
+ [in] DWORD flags,
+ [out, retval] IStream **stream
+ );
+
+ HRESULT CreatePackage(
+ [out, retval] IOpcPackage **package
+ );
+
+ HRESULT ReadPackageFromStream(
+ [in] IStream *stream,
+ [in] OPC_READ_FLAGS flags,
+ [out, retval] IOpcPackage **package
+ );
+
+ HRESULT WritePackageToStream(
+ [in] IOpcPackage *package,
+ [in] OPC_WRITE_FLAGS flags,
+ [in] IStream *stream
+ );
+
+ HRESULT CreateDigitalSignatureManager(
+ [in] IOpcPackage *package,
+ [out, retval] IOpcDigitalSignatureManager **signature_manager
+ );
+}
+
+[
+ threading(both),
+ uuid(6b2d6Ba0-9f3e-4f27-920b-313cc426a39e)
+]
+coclass OpcFactory
+{
+ interface IOpcFactory;
+};
diff --git a/include/opcbase.idl b/include/opcbase.idl
new file mode 100644
index 0000000000..2cfb885c12
--- /dev/null
+++ b/include/opcbase.idl
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2018 Nikolay Sivov for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#if 0
+#pragma makedep install
+#endif
+
+typedef [v1_enum] enum
+{
+ OPC_STREAM_IO_READ = 1,
+ OPC_STREAM_IO_WRITE = 2,
+} OPC_STREAM_IO_MODE;
+
diff --git a/include/opcobjectmodel.idl b/include/opcobjectmodel.idl
new file mode 100644
index 0000000000..e5370d2e54
--- /dev/null
+++ b/include/opcobjectmodel.idl
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2018 Nikolay Sivov for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#if 0
+#pragma makedep install
+#endif
+
+typedef [v1_enum] enum
+{
+ OPC_READ_DEFAULT = 0,
+ OPC_VALIDATE_ON_LOAD = 1,
+ OPC_CACHE_ON_ACCESS = 2,
+} OPC_READ_FLAGS;
+
+typedef [v1_enum] enum
+{
+ OPC_WRITE_DEFAULT = 0,
+ OPC_WRITE_FORCE_ZIP32 = 1,
+} OPC_WRITE_FLAGS;
diff --git a/include/opcparturi.idl b/include/opcparturi.idl
new file mode 100644
index 0000000000..00b21b9598
--- /dev/null
+++ b/include/opcparturi.idl
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2018 Nikolay Sivov for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+import "unknwn.idl";
+import "ocidl.idl";
+
+#if 0
+#pragma makedep install
+#endif
+
+interface IOpcPartUri;
+
+[
+ object,
+ uuid(bc9c1b9b-d62c-49eb-aef0-3b4e0b28ebed),
+ nonextensible,
+ pointer_default(ref)
+]
+interface IOpcUri : IUri
+{
+ HRESULT GetRelationshipsPartUri(
+ [out, retval] IOpcPartUri **part_uri
+ );
+
+ HRESULT GetRelativeUri(
+ [in] IOpcPartUri *part_uri,
+ [out, retval] IUri **relative_uri
+ );
+
+ HRESULT CombinePartUri(
+ [in] IUri *relative_uri,
+ [out, retval] IOpcPartUri **combined
+ );
+}
+
+[
+ object,
+ uuid(7d3babe7-88b2-46ba-85cb-4203cb016c87),
+ nonextensible,
+ pointer_default(ref)
+]
+interface IOpcPartUri : IOpcUri
+{
+ HRESULT ComparePartUri(
+ [in] IOpcPartUri *part_uri,
+ [out, retval] INT32 *result
+ );
+
+ HRESULT GetSourceUri(
+ [out, retval] IOpcUri **source_uri
+ );
+
+ HRESULT IsRelationshipsPartUri(
+ [out, retval] BOOL *result
+ );
+}
--
2.18.0
1
1
[PATCH 4/4] winevulkan: Free all command buffers when vkAllocateCommandBuffers() fails.
by Józef Kucia Aug. 30, 2018
by Józef Kucia Aug. 30, 2018
Aug. 30, 2018
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/winevulkan/vulkan.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c
index f500602e96d5..4e0d999ddb41 100644
--- a/dlls/winevulkan/vulkan.c
+++ b/dlls/winevulkan/vulkan.c
@@ -540,25 +540,24 @@ VkResult WINAPI wine_vkAllocateCommandBuffers(VkDevice device,
buffers[i]->base.loader_magic = VULKAN_ICD_MAGIC_VALUE;
buffers[i]->device = device;
+ list_add_tail(&pool->command_buffers, &buffers[i]->pool_link);
res = device->funcs.p_vkAllocateCommandBuffers(device->device,
&allocate_info_host, &buffers[i]->command_buffer);
if (res != VK_SUCCESS)
{
ERR("Failed to allocate command buffer, res=%d.\n", res);
+ buffers[i]->command_buffer = VK_NULL_HANDLE;
break;
}
-
- list_add_tail(&pool->command_buffers, &buffers[i]->pool_link);
}
if (res != VK_SUCCESS)
{
- wine_vk_free_command_buffers(device, pool, i, buffers);
+ wine_vk_free_command_buffers(device, pool, i + 1, buffers);
memset(buffers, 0, allocate_info->commandBufferCount * sizeof(*buffers));
- return res;
}
- return VK_SUCCESS;
+ return res;
}
void WINAPI wine_vkCmdExecuteCommands(VkCommandBuffer buffer, uint32_t count,
--
2.16.4
1
0
Aug. 30, 2018
The Vulkan spec says:
"When a pool is destroyed, all command buffers allocated from the pool
are implicitly freed and become invalid. Command buffers allocated
from a given pool do not need to be freed before destroying that
command pool."
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/vulkan-1/tests/vulkan.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/dlls/vulkan-1/tests/vulkan.c b/dlls/vulkan-1/tests/vulkan.c
index 1d2f66f5f901..20a245238b02 100644
--- a/dlls/vulkan-1/tests/vulkan.c
+++ b/dlls/vulkan-1/tests/vulkan.c
@@ -232,6 +232,45 @@ static void test_physical_device_groups(void)
vkDestroyInstance(vk_instance, NULL);
}
+static void test_destroy_command_pool(VkPhysicalDevice vk_physical_device)
+{
+ VkCommandBufferAllocateInfo allocate_info;
+ VkCommandPoolCreateInfo pool_info;
+ VkCommandBuffer vk_cmd_buffers[4];
+ uint32_t queue_family_index;
+ VkCommandPool vk_cmd_pool;
+ VkDevice vk_device;
+ VkResult vr;
+
+ if ((vr = create_device(vk_physical_device, 0, NULL, NULL, &vk_device)) < 0)
+ {
+ skip("Failed to create device, vr %d.\n", vr);
+ return;
+ }
+
+ find_queue_family(vk_physical_device, VK_QUEUE_GRAPHICS_BIT, &queue_family_index);
+
+ pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+ pool_info.pNext = NULL;
+ pool_info.flags = 0;
+ pool_info.queueFamilyIndex = queue_family_index;
+ vr = vkCreateCommandPool(vk_device, &pool_info, NULL, &vk_cmd_pool);
+ ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
+
+ allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+ allocate_info.pNext = NULL;
+ allocate_info.commandPool = vk_cmd_pool;
+ allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+ allocate_info.commandBufferCount = ARRAY_SIZE(vk_cmd_buffers);
+ vr = vkAllocateCommandBuffers(vk_device, &allocate_info, vk_cmd_buffers);
+ ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
+
+ vkDestroyCommandPool(vk_device, vk_cmd_pool, NULL);
+ vkDestroyCommandPool(vk_device, VK_NULL_HANDLE, NULL);
+
+ vkDestroyDevice(vk_device, NULL);
+}
+
static void for_each_device(void (*test_func)(VkPhysicalDevice))
{
VkPhysicalDevice *vk_physical_devices;
@@ -272,4 +311,5 @@ START_TEST(vulkan)
for_each_device(enumerate_physical_device);
for_each_device(enumerate_device_queues);
test_physical_device_groups();
+ for_each_device(test_destroy_command_pool);
}
--
2.16.4
1
0
[PATCH 2/4] winevulkan: Fix potential memory leaks when a command pool is destroyed.
by Józef Kucia Aug. 30, 2018
by Józef Kucia Aug. 30, 2018
Aug. 30, 2018
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/winevulkan/vulkan.c | 22 ++++++++++++++++++----
dlls/winevulkan/vulkan_private.h | 5 +++++
2 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c
index 886ef0b47344..f500602e96d5 100644
--- a/dlls/winevulkan/vulkan.c
+++ b/dlls/winevulkan/vulkan.c
@@ -165,6 +165,7 @@ static void wine_vk_free_command_buffers(struct VkDevice_T *device,
continue;
device->funcs.p_vkFreeCommandBuffers(device->device, pool->command_pool, 1, &buffers[i]->command_buffer);
+ list_remove(&buffers[i]->pool_link);
heap_free(buffers[i]);
}
}
@@ -528,9 +529,8 @@ VkResult WINAPI wine_vkAllocateCommandBuffers(VkDevice device,
allocate_info_host.level = allocate_info->level;
allocate_info_host.commandBufferCount = 1;
- TRACE("Creating command buffer %u, pool 0x%s, level %#x\n", i,
- wine_dbgstr_longlong(allocate_info_host.commandPool),
- allocate_info_host.level);
+ TRACE("Allocating command buffer %u from pool 0x%s.\n",
+ i, wine_dbgstr_longlong(allocate_info_host.commandPool));
if (!(buffers[i] = heap_alloc_zero(sizeof(**buffers))))
{
@@ -544,9 +544,11 @@ VkResult WINAPI wine_vkAllocateCommandBuffers(VkDevice device,
&allocate_info_host, &buffers[i]->command_buffer);
if (res != VK_SUCCESS)
{
- ERR("Failed to allocate command buffer, res=%d\n", res);
+ ERR("Failed to allocate command buffer, res=%d.\n", res);
break;
}
+
+ list_add_tail(&pool->command_buffers, &buffers[i]->pool_link);
}
if (res != VK_SUCCESS)
@@ -1132,6 +1134,8 @@ VkResult WINAPI wine_vkCreateCommandPool(VkDevice device, const VkCommandPoolCre
if (!(object = heap_alloc_zero(sizeof(*object))))
return VK_ERROR_OUT_OF_HOST_MEMORY;
+ list_init(&object->command_buffers);
+
res = device->funcs.p_vkCreateCommandPool(device->device, info, NULL, &object->command_pool);
if (res == VK_SUCCESS)
@@ -1146,6 +1150,7 @@ void WINAPI wine_vkDestroyCommandPool(VkDevice device, VkCommandPool handle,
const VkAllocationCallbacks *allocator)
{
struct wine_cmd_pool *pool = wine_cmd_pool_from_handle(handle);
+ struct VkCommandBuffer_T *buffer, *cursor;
TRACE("%p, 0x%s, %p\n", device, wine_dbgstr_longlong(handle), allocator);
@@ -1155,6 +1160,15 @@ void WINAPI wine_vkDestroyCommandPool(VkDevice device, VkCommandPool handle,
if (allocator)
FIXME("Support for allocation callbacks not implemented yet\n");
+ /* The Vulkan spec says:
+ *
+ * "When a pool is destroyed, all command buffers allocated from the pool are freed."
+ */
+ LIST_FOR_EACH_ENTRY_SAFE(buffer, cursor, &pool->command_buffers, struct VkCommandBuffer_T, pool_link)
+ {
+ heap_free(buffer);
+ }
+
device->funcs.p_vkDestroyCommandPool(device->device, pool->command_pool, NULL);
heap_free(pool);
}
diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h
index f31d4d5d8f52..17072d234193 100644
--- a/dlls/winevulkan/vulkan_private.h
+++ b/dlls/winevulkan/vulkan_private.h
@@ -27,6 +27,7 @@
#include "wine/debug.h"
#include "wine/heap.h"
+#include "wine/list.h"
#define VK_NO_PROTOTYPES
#include "wine/vulkan.h"
#include "wine/vulkan_driver.h"
@@ -62,6 +63,8 @@ struct VkCommandBuffer_T
struct wine_vk_base base;
struct VkDevice_T *device; /* parent */
VkCommandBuffer command_buffer; /* native command buffer */
+
+ struct list pool_link;
};
struct VkDevice_T
@@ -113,6 +116,8 @@ struct VkQueue_T
struct wine_cmd_pool
{
VkCommandPool command_pool;
+
+ struct list command_buffers;
};
static inline struct wine_cmd_pool *wine_cmd_pool_from_handle(VkCommandPool handle)
--
2.16.4
1
0
We need to wrap VkCommandPools to track allocated VkCommandBuffers.
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/winevulkan/make_vulkan | 50 +++++++++++++++--------------
dlls/winevulkan/vulkan.c | 68 +++++++++++++++++++++++++++++++++-------
dlls/winevulkan/vulkan_private.h | 15 +++++++++
dlls/winevulkan/vulkan_thunks.c | 18 ++---------
dlls/winevulkan/vulkan_thunks.h | 2 ++
5 files changed, 103 insertions(+), 50 deletions(-)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan
index 5b0f82ce355a..8e7d88ad7dec 100755
--- a/dlls/winevulkan/make_vulkan
+++ b/dlls/winevulkan/make_vulkan
@@ -157,6 +157,8 @@ FUNCTION_OVERRIDES = {
# Device functions
"vkAllocateCommandBuffers" : {"dispatch" : True, "driver" : False, "thunk" : False},
"vkCmdExecuteCommands" : {"dispatch" : True, "driver" : False, "thunk" : False},
+ "vkCreateCommandPool" : {"dispatch": True, "driver" : False, "thunk" : False},
+ "vkDestroyCommandPool" : {"dispatch": True, "driver" : False, "thunk" : False},
"vkDestroyDevice" : {"dispatch" : True, "driver" : False, "thunk" : False},
"vkFreeCommandBuffers" : {"dispatch" : True, "driver" : False, "thunk" : False},
"vkGetDeviceProcAddr" : {"dispatch" : False, "driver" : True, "thunk" : False},
@@ -838,27 +840,31 @@ class VkHandle(object):
def is_required(self):
return self.required
- def native_handle(self):
- """ Provide access to the native handle of a dispatchable object.
+ def native_handle(self, name):
+ """ Provide access to the native handle of a wrapped object. """
- Dispatchable objects wrap an underlying 'native' object.
- This method provides access to the native object.
- """
- if not self.is_dispatchable():
- return None
+ if self.name == "VkCommandPool":
+ return "wine_cmd_pool_from_handle({0})->command_pool".format(name)
+
+ native_handle_name = None
if self.name == "VkCommandBuffer":
- return "command_buffer"
- elif self.name == "VkDevice":
- return "device"
- elif self.name == "VkInstance":
- return "instance"
- elif self.name == "VkPhysicalDevice":
- return "phys_dev"
- elif self.name == "VkQueue":
- return "queue"
- else:
+ native_handle_name = "command_buffer"
+ if self.name == "VkDevice":
+ native_handle_name = "device"
+ if self.name == "VkInstance":
+ native_handle_name = "instance"
+ if self.name == "VkPhysicalDevice":
+ native_handle_name = "phys_dev"
+ if self.name == "VkQueue":
+ native_handle_name = "queue"
+
+ if native_handle_name:
+ return "{0}->{1}".format(name, native_handle_name)
+
+ if self.is_dispatchable():
LOGGER.error("Unhandled native handle for: {0}".format(self.name))
+ return None
class VkMember(object):
@@ -1471,17 +1477,15 @@ class VkParam(object):
LOGGER.debug("TODO: setting NULL VkAllocationCallbacks for {0}".format(self.name))
return "NULL"
- # Dispatchable objects wrap the native handle. For thunk generation we
- # need to pass the native handle to the native Vulkan calls.
- if self.is_dispatchable():
- return "{0}->{1}".format(self.name, self.handle.native_handle())
- elif conv and self.needs_conversion():
+ if conv and self.needs_conversion():
if self.is_dynamic_array():
return "{0}_host".format(self.name)
else:
return "&{0}_host".format(self.name)
else:
- return self.name
+ # We need to pass the native handle to the native Vulkan calls.
+ native_handle = self.handle.native_handle(self.name) if self.is_handle() else None
+ return native_handle if native_handle else self.name
class VkStruct(Sequence):
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c
index 89df838f0499..886ef0b47344 100644
--- a/dlls/winevulkan/vulkan.c
+++ b/dlls/winevulkan/vulkan.c
@@ -154,9 +154,8 @@ err:
return NULL;
}
-/* Helper function to release command buffers. */
-static void wine_vk_command_buffers_free(struct VkDevice_T *device, VkCommandPool pool,
- uint32_t count, const VkCommandBuffer *buffers)
+static void wine_vk_free_command_buffers(struct VkDevice_T *device,
+ struct wine_cmd_pool *pool, uint32_t count, const VkCommandBuffer *buffers)
{
unsigned int i;
@@ -165,12 +164,11 @@ static void wine_vk_command_buffers_free(struct VkDevice_T *device, VkCommandPoo
if (!buffers[i])
continue;
- device->funcs.p_vkFreeCommandBuffers(device->device, pool, 1, &buffers[i]->command_buffer);
+ device->funcs.p_vkFreeCommandBuffers(device->device, pool->command_pool, 1, &buffers[i]->command_buffer);
heap_free(buffers[i]);
}
}
-/* Helper function to create queues for a given family index. */
static struct VkQueue_T *wine_vk_device_alloc_queues(struct VkDevice_T *device,
uint32_t family_index, uint32_t queue_count, VkDeviceQueueCreateFlags flags)
{
@@ -506,10 +504,13 @@ static void wine_vk_instance_free(struct VkInstance_T *instance)
VkResult WINAPI wine_vkAllocateCommandBuffers(VkDevice device,
const VkCommandBufferAllocateInfo *allocate_info, VkCommandBuffer *buffers)
{
+ struct wine_cmd_pool *pool;
VkResult res = VK_SUCCESS;
unsigned int i;
- TRACE("%p %p %p\n", device, allocate_info, buffers);
+ TRACE("%p, %p, %p\n", device, allocate_info, buffers);
+
+ pool = wine_cmd_pool_from_handle(allocate_info->commandPool);
memset(buffers, 0, allocate_info->commandBufferCount * sizeof(*buffers));
@@ -523,7 +524,7 @@ VkResult WINAPI wine_vkAllocateCommandBuffers(VkDevice device,
/* TODO: future extensions (none yet) may require pNext conversion. */
allocate_info_host.pNext = allocate_info->pNext;
allocate_info_host.sType = allocate_info->sType;
- allocate_info_host.commandPool = allocate_info->commandPool;
+ allocate_info_host.commandPool = pool->command_pool;
allocate_info_host.level = allocate_info->level;
allocate_info_host.commandBufferCount = 1;
@@ -550,7 +551,7 @@ VkResult WINAPI wine_vkAllocateCommandBuffers(VkDevice device,
if (res != VK_SUCCESS)
{
- wine_vk_command_buffers_free(device, allocate_info->commandPool, i, buffers);
+ wine_vk_free_command_buffers(device, pool, i, buffers);
memset(buffers, 0, allocate_info->commandBufferCount * sizeof(*buffers));
return res;
}
@@ -920,12 +921,14 @@ VkResult WINAPI wine_vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *c
return *count < instance->phys_dev_count ? VK_INCOMPLETE : VK_SUCCESS;
}
-void WINAPI wine_vkFreeCommandBuffers(VkDevice device, VkCommandPool pool, uint32_t count,
- const VkCommandBuffer *buffers)
+void WINAPI wine_vkFreeCommandBuffers(VkDevice device, VkCommandPool pool_handle,
+ uint32_t count, const VkCommandBuffer *buffers)
{
- TRACE("%p 0x%s %u %p\n", device, wine_dbgstr_longlong(pool), count, buffers);
+ struct wine_cmd_pool *pool = wine_cmd_pool_from_handle(pool_handle);
- wine_vk_command_buffers_free(device, pool, count, buffers);
+ TRACE("%p, 0x%s, %u, %p\n", device, wine_dbgstr_longlong(pool_handle), count, buffers);
+
+ wine_vk_free_command_buffers(device, pool, count, buffers);
}
PFN_vkVoidFunction WINAPI wine_vkGetDeviceProcAddr(VkDevice device, const char *name)
@@ -1115,6 +1118,47 @@ err:
return res;
}
+VkResult WINAPI wine_vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *info,
+ const VkAllocationCallbacks *allocator, VkCommandPool *command_pool)
+{
+ struct wine_cmd_pool *object;
+ VkResult res;
+
+ TRACE("%p, %p, %p, %p\n", device, info, allocator, command_pool);
+
+ if (allocator)
+ FIXME("Support for allocation callbacks not implemented yet\n");
+
+ if (!(object = heap_alloc_zero(sizeof(*object))))
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+
+ res = device->funcs.p_vkCreateCommandPool(device->device, info, NULL, &object->command_pool);
+
+ if (res == VK_SUCCESS)
+ *command_pool = wine_cmd_pool_to_handle(object);
+ else
+ heap_free(object);
+
+ return res;
+}
+
+void WINAPI wine_vkDestroyCommandPool(VkDevice device, VkCommandPool handle,
+ const VkAllocationCallbacks *allocator)
+{
+ struct wine_cmd_pool *pool = wine_cmd_pool_from_handle(handle);
+
+ TRACE("%p, 0x%s, %p\n", device, wine_dbgstr_longlong(handle), allocator);
+
+ if (!handle)
+ return;
+
+ if (allocator)
+ FIXME("Support for allocation callbacks not implemented yet\n");
+
+ device->funcs.p_vkDestroyCommandPool(device->device, pool->command_pool, NULL);
+ heap_free(pool);
+}
+
static VkResult wine_vk_enumerate_physical_device_groups(struct VkInstance_T *instance,
VkResult (*p_vkEnumeratePhysicalDeviceGroups)(VkInstance, uint32_t *, VkPhysicalDeviceGroupProperties *),
uint32_t *count, VkPhysicalDeviceGroupProperties *properties)
diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h
index 2e071a524b1c..f31d4d5d8f52 100644
--- a/dlls/winevulkan/vulkan_private.h
+++ b/dlls/winevulkan/vulkan_private.h
@@ -110,6 +110,21 @@ struct VkQueue_T
VkDeviceQueueCreateFlags flags;
};
+struct wine_cmd_pool
+{
+ VkCommandPool command_pool;
+};
+
+static inline struct wine_cmd_pool *wine_cmd_pool_from_handle(VkCommandPool handle)
+{
+ return (struct wine_cmd_pool *)(uintptr_t)handle;
+}
+
+static inline VkCommandPool wine_cmd_pool_to_handle(struct wine_cmd_pool *cmd_pool)
+{
+ return (VkCommandPool)(uintptr_t)cmd_pool;
+}
+
void *wine_vk_get_device_proc_addr(const char *name) DECLSPEC_HIDDEN;
void *wine_vk_get_instance_proc_addr(const char *name) DECLSPEC_HIDDEN;
diff --git a/dlls/winevulkan/vulkan_thunks.c b/dlls/winevulkan/vulkan_thunks.c
index 9d637bf9eb92..f5cadd8c72b6 100644
--- a/dlls/winevulkan/vulkan_thunks.c
+++ b/dlls/winevulkan/vulkan_thunks.c
@@ -1744,12 +1744,6 @@ VkResult WINAPI wine_vkCreateBufferView(VkDevice device, const VkBufferViewCreat
#endif
}
-VkResult WINAPI wine_vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool)
-{
- TRACE("%p, %p, %p, %p\n", device, pCreateInfo, pAllocator, pCommandPool);
- return device->funcs.p_vkCreateCommandPool(device->device, pCreateInfo, NULL, pCommandPool);
-}
-
VkResult WINAPI wine_vkCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines)
{
#if defined(USE_STRUCT_CONVERSION)
@@ -1979,12 +1973,6 @@ void WINAPI wine_vkDestroyBufferView(VkDevice device, VkBufferView bufferView, c
device->funcs.p_vkDestroyBufferView(device->device, bufferView, NULL);
}
-void WINAPI wine_vkDestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator)
-{
- TRACE("%p, 0x%s, %p\n", device, wine_dbgstr_longlong(commandPool), pAllocator);
- device->funcs.p_vkDestroyCommandPool(device->device, commandPool, NULL);
-}
-
void WINAPI wine_vkDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks *pAllocator)
{
TRACE("%p, 0x%s, %p\n", device, wine_dbgstr_longlong(descriptorPool), pAllocator);
@@ -2744,7 +2732,7 @@ VkResult WINAPI wine_vkResetCommandBuffer(VkCommandBuffer commandBuffer, VkComma
VkResult WINAPI wine_vkResetCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags)
{
TRACE("%p, 0x%s, %#x\n", device, wine_dbgstr_longlong(commandPool), flags);
- return device->funcs.p_vkResetCommandPool(device->device, commandPool, flags);
+ return device->funcs.p_vkResetCommandPool(device->device, wine_cmd_pool_from_handle(commandPool)->command_pool, flags);
}
VkResult WINAPI wine_vkResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags)
@@ -2774,13 +2762,13 @@ VkResult WINAPI wine_vkSetEvent(VkDevice device, VkEvent event)
void WINAPI wine_vkTrimCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags)
{
TRACE("%p, 0x%s, %#x\n", device, wine_dbgstr_longlong(commandPool), flags);
- device->funcs.p_vkTrimCommandPool(device->device, commandPool, flags);
+ device->funcs.p_vkTrimCommandPool(device->device, wine_cmd_pool_from_handle(commandPool)->command_pool, flags);
}
static void WINAPI wine_vkTrimCommandPoolKHR(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags)
{
TRACE("%p, 0x%s, %#x\n", device, wine_dbgstr_longlong(commandPool), flags);
- device->funcs.p_vkTrimCommandPoolKHR(device->device, commandPool, flags);
+ device->funcs.p_vkTrimCommandPoolKHR(device->device, wine_cmd_pool_from_handle(commandPool)->command_pool, flags);
}
void WINAPI wine_vkUnmapMemory(VkDevice device, VkDeviceMemory memory)
diff --git a/dlls/winevulkan/vulkan_thunks.h b/dlls/winevulkan/vulkan_thunks.h
index 94e56bb97300..21f9b4817800 100644
--- a/dlls/winevulkan/vulkan_thunks.h
+++ b/dlls/winevulkan/vulkan_thunks.h
@@ -43,7 +43,9 @@
/* Functions for which we have custom implementations outside of the thunks. */
VkResult WINAPI wine_vkAllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pAllocateInfo, VkCommandBuffer *pCommandBuffers);
void WINAPI wine_vkCmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer *pCommandBuffers);
+VkResult WINAPI wine_vkCreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkCommandPool *pCommandPool);
VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDevice *pDevice);
+void WINAPI wine_vkDestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator);
void WINAPI wine_vkDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator);
void WINAPI wine_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator);
VkResult WINAPI wine_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName, uint32_t *pPropertyCount, VkExtensionProperties *pProperties);
--
2.16.4
1
0
[PATCH 1/2] testbot/web: Make it possible to link to the top and bottom of the page.
by Francois Gouget Aug. 30, 2018
by Francois Gouget Aug. 30, 2018
Aug. 30, 2018
The PageTitle anchor identifies the page's title while the PageEnd one
points to the bottom of the page.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/lib/ObjectModel/CGI/CollectionPage.pm | 2 +-
testbot/lib/ObjectModel/CGI/FormPage.pm | 2 +-
testbot/lib/WineTestBot/CGI/PageBase.pm | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/testbot/lib/ObjectModel/CGI/CollectionPage.pm b/testbot/lib/ObjectModel/CGI/CollectionPage.pm
index 6593afcd2..194379f40 100644
--- a/testbot/lib/ObjectModel/CGI/CollectionPage.pm
+++ b/testbot/lib/ObjectModel/CGI/CollectionPage.pm
@@ -63,7 +63,7 @@ sub GenerateTitle($)
my $Title = $self->GetTitle();
if ($Title)
{
- print "<h1>", $self->escapeHTML($Title), "</h1>\n";
+ print "<h1 id='PageTitle'>", $self->escapeHTML($Title), "</h1>\n";
}
}
diff --git a/testbot/lib/ObjectModel/CGI/FormPage.pm b/testbot/lib/ObjectModel/CGI/FormPage.pm
index 3a41fe0e6..01f789489 100644
--- a/testbot/lib/ObjectModel/CGI/FormPage.pm
+++ b/testbot/lib/ObjectModel/CGI/FormPage.pm
@@ -86,7 +86,7 @@ sub GenerateTitle($)
my $Title = $self->GetTitle();
if ($Title)
{
- print "<h1>", $self->CGI->escapeHTML($Title), "</h1>\n";
+ print "<h1 id='PageTitle'>", $self->CGI->escapeHTML($Title), "</h1>\n";
}
}
diff --git a/testbot/lib/WineTestBot/CGI/PageBase.pm b/testbot/lib/WineTestBot/CGI/PageBase.pm
index e5b2f2d3b..0eac6b17b 100644
--- a/testbot/lib/WineTestBot/CGI/PageBase.pm
+++ b/testbot/lib/WineTestBot/CGI/PageBase.pm
@@ -328,7 +328,7 @@ sub GenerateFooter($)
print <<EOF;
</div><!--ContentContainer-->
- <b class="rbottom"><b class="r4"> </b><b class="r3"> </b><b class="r2"> </b><b class="r1"> </b></b>
+ <b id="PageEnd" class="rbottom"><b class="r4"> </b><b class="r3"> </b><b class="r2"> </b><b class="r1"> </b></b>
</div>
</div><!--main_content-->
--
2.18.0
1
1
[PATCH 1/2] testbot/web: Highlight new errors on the JobDetails page.
by Francois Gouget Aug. 30, 2018
by Francois Gouget Aug. 30, 2018
Aug. 30, 2018
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineRunBuild.pl | 31 +++++++++++++++++++++++++++
testbot/bin/WineSendLog.pl | 2 +-
testbot/lib/WineTestBot/LogUtils.pm | 21 +++++++++++-------
testbot/lib/WineTestBot/Steps.pm | 16 +++++++++-----
testbot/lib/WineTestBot/StepsTasks.pm | 16 +++++++++-----
testbot/web/JobDetails.pl | 24 ++++++++++++++++++++-
testbot/web/WineTestBot.css | 1 +
7 files changed, 91 insertions(+), 20 deletions(-)
diff --git a/testbot/bin/WineRunBuild.pl b/testbot/bin/WineRunBuild.pl
index 117b06551..11b41c67a 100755
--- a/testbot/bin/WineRunBuild.pl
+++ b/testbot/bin/WineRunBuild.pl
@@ -471,6 +471,37 @@ foreach my $TestInfo (values %{$Impacts->{Tests}})
$TA->Disconnect();
+#
+# Grab a copy of the reference logs
+#
+
+# Note that this may be a bit inaccurate right after a Wine commit.
+# See WineSendLog.pl for more details.
+my $LatestDir = "$DataDir/latest";
+foreach my $TestStep (@{$Job->Steps->GetItems()})
+{
+ if (($TestStep->PreviousNo || 0) == $Step->No and
+ $TestStep->FileType =~ /^exe/)
+ {
+ foreach my $TestTask (@{$TestStep->Tasks->GetItems()})
+ {
+ my $RefReport = $TestTask->VM->Name ."_". $TestStep->FileType .".report";
+ for my $Suffix ("", ".err")
+ {
+ if (-f "$LatestDir/$RefReport$Suffix")
+ {
+ unlink "$StepDir/$RefReport$Suffix";
+ if (!link "$LatestDir/$RefReport$Suffix", "$StepDir/$RefReport$Suffix")
+ {
+ Error "Could not link '$RefReport$Suffix': $!\n";
+ }
+ }
+ }
+ }
+ }
+}
+
+
#
# Wrap up
#
diff --git a/testbot/bin/WineSendLog.pl b/testbot/bin/WineSendLog.pl
index a4b1c823d..36d47c3a6 100755
--- a/testbot/bin/WineSendLog.pl
+++ b/testbot/bin/WineSendLog.pl
@@ -288,7 +288,7 @@ EOF
{
my $LogErrors = $JobErrors->{$Key}->{$LogName};
my $RefFileName = "$DataDir/latest". $StepTask->VM->Name ."_$LogName";
- my ($NewGroups, $NewErrors) = GetNewLogErrors($RefFileName, $LogErrors->{Groups}, $LogErrors->{Errors});
+ my ($NewGroups, $NewErrors, $_NewIndices) = GetNewLogErrors($RefFileName, $LogErrors->{Groups}, $LogErrors->{Errors});
if (!$NewGroups)
{
# There was no reference log (typical of build logs)
diff --git a/testbot/lib/WineTestBot/LogUtils.pm b/testbot/lib/WineTestBot/LogUtils.pm
index 17b9093aa..5120217c0 100644
--- a/testbot/lib/WineTestBot/LogUtils.pm
+++ b/testbot/lib/WineTestBot/LogUtils.pm
@@ -781,8 +781,9 @@ sub _GetLineKey($)
Compares the specified errors to the reference log and returns only the ones
that are new.
-Returns a list of error groups containing new errors and a hashtable containing
-the list of new errors for each group.
+Returns a list of error groups containing new errors, a hashtable containing
+the list of new errors for each group, and a hashtable containing the indices
+of the new errors in the input errors list for each group.
=back
=cut
@@ -791,10 +792,10 @@ sub GetNewLogErrors($$$)
{
my ($RefFileName, $Groups, $Errors) = @_;
- my ($_Dummy, $RefErrors, $NoLog) = GetLogErrors($RefFileName);
- return (undef, undef) if ($NoLog);
+ my ($RefGroups, $RefErrors) = GetLogErrors($RefFileName);
+ return (undef, undef) if (!$RefGroups);
- my (@NewGroups, %NewErrors);
+ my (@NewGroups, %NewErrors, %NewIndices);
foreach my $GroupName (@$Groups)
{
if ($RefErrors->{$GroupName})
@@ -802,7 +803,7 @@ sub GetNewLogErrors($$$)
my $Diff = Algorithm::Diff->new($RefErrors->{$GroupName},
$Errors->{$GroupName},
{ keyGen => \&_GetLineKey });
- my $CurrentGroup;
+ my ($CurrentGroup, $CurrentIndices);
while ($Diff->Next())
{
# Skip if there are no new lines
@@ -812,20 +813,24 @@ sub GetNewLogErrors($$$)
{
push @NewGroups, $GroupName;
$CurrentGroup = $NewErrors{$GroupName} = [];
+ $CurrentIndices = $NewIndices{$GroupName} = {};
}
push @$CurrentGroup, $Diff->Items(2);
+ $CurrentIndices->{$_} = 1 for ($Diff->Range(2));
}
}
else
{
- # This module did not have errors before, so every error is new
+ # This group did not have errors before, so every error is new
push @NewGroups, $GroupName;
$NewErrors{$GroupName} = $Errors->{$GroupName};
+ $NewIndices{$GroupName} = {};
my $Last = @{$Errors->{$GroupName}} - 1;
+ $NewIndices{$GroupName}->{$_} = 1 for (0..$Last);
}
}
- return (\@NewGroups, \%NewErrors);
+ return (\@NewGroups, \%NewErrors, \%NewIndices);
}
1;
diff --git a/testbot/lib/WineTestBot/Steps.pm b/testbot/lib/WineTestBot/Steps.pm
index 2f5bdb070..ae1180c66 100644
--- a/testbot/lib/WineTestBot/Steps.pm
+++ b/testbot/lib/WineTestBot/Steps.pm
@@ -146,16 +146,22 @@ sub RmTree($)
rmtree($Dir);
}
-sub GetFullFileName($)
+sub GetFullFileName($;$)
{
- my ($self) = @_;
+ my ($self, $FileName) = @_;
- return undef if (!defined $self->FileName);
+ $FileName = $self->FileName if (!defined $FileName);
+ return undef if (!defined $FileName);
my ($JobId, $StepNo) = @{$self->GetMasterKey()};
my $Path = "$DataDir/jobs/$JobId/";
- $Path .= $self->PreviousNo ."/" if ($self->PreviousNo);
- return $Path . $self->FileName;
+ foreach my $StepNo ($StepNo, $self->PreviousNo)
+ {
+ next if (!$StepNo);
+ my $Full = "$Path$StepNo/$FileName";
+ return $Full if (-f $Full);
+ }
+ return $Path . $FileName;
}
sub UpdateStatus($$)
diff --git a/testbot/lib/WineTestBot/StepsTasks.pm b/testbot/lib/WineTestBot/StepsTasks.pm
index 4675194e6..a50f61ada 100644
--- a/testbot/lib/WineTestBot/StepsTasks.pm
+++ b/testbot/lib/WineTestBot/StepsTasks.pm
@@ -40,16 +40,22 @@ sub GetStepDir($)
}
# See WineTestBot::Step::GetFullFileName()
-sub GetFullFileName($)
+sub GetFullFileName($;$)
{
- my ($self) = @_;
+ my ($self, $FileName) = @_;
- return undef if (!defined $self->FileName);
+ $FileName = $self->FileName if (!defined $FileName);
+ return undef if (!defined $FileName);
my ($JobId, $_StepTaskId) = @{$self->GetMasterKey()};
my $Path = "$DataDir/jobs/$JobId/";
- $Path .= $self->PreviousNo ."/" if ($self->PreviousNo);
- return $Path . $self->FileName;
+ foreach my $StepNo ($self->StepNo, $self->PreviousNo)
+ {
+ next if (!$StepNo);
+ my $Full = "$Path$StepNo/$FileName";
+ return $Full if (-f $Full);
+ }
+ return $Path . $FileName;
}
sub GetTaskDir($)
diff --git a/testbot/web/JobDetails.pl b/testbot/web/JobDetails.pl
index 7dd6aa5e9..d8e55296d 100644
--- a/testbot/web/JobDetails.pl
+++ b/testbot/web/JobDetails.pl
@@ -25,6 +25,7 @@ package JobDetailsPage;
use ObjectModel::CGI::CollectionPage;
our @ISA = qw(ObjectModel::CGI::CollectionPage);
+use File::Basename;
use URI::Escape;
use WineTestBot::Config;
@@ -490,11 +491,32 @@ EOF
}
my $Summary = $LogSummaries->{$LogName};
+ my $New;
+ if ($LogName =~ /\.report$/)
+ {
+ # Identify new errors in test reports
+ my $RefFileName = $StepTask->GetFullFileName($VM->Name ."_$LogName");
+ (my $_NewGroups, my $_NewErrors, $New) = GetNewLogErrors($RefFileName, $Summary->{Groups}, $Summary->{Errors});
+ }
+
foreach my $GroupName (@{$Summary->{Groups}})
{
print "<div class='LogDllName'>$GroupName:</div>\n" if ($GroupName);
+
print "<pre><code>";
- print $self->escapeHTML($_), "\n" for (@{$Summary->{Errors}->{$GroupName}});
+ my $ErrIndex = 0;
+ foreach my $Line (@{$Summary->{Errors}->{$GroupName}})
+ {
+ if ($New and $New->{$GroupName}->{$ErrIndex})
+ {
+ print "<span class='log-new'>", $self->escapeHTML($Line), "</span>\n";
+ }
+ else
+ {
+ print $self->escapeHTML($Line), "\n";
+ }
+ $ErrIndex++;
+ }
print "</code></pre>\n";
}
}
diff --git a/testbot/web/WineTestBot.css b/testbot/web/WineTestBot.css
index 55c61a300..df683f863 100644
--- a/testbot/web/WineTestBot.css
+++ b/testbot/web/WineTestBot.css
@@ -381,6 +381,7 @@ pre
.log-error { color: red; }
.log-boterror { color: #cc0052; }
.log-diag { color: #e56300; }
+.log-new { color: #e56e00; font-weight: bold; }
a.title { color:inherit; text-decoration: none; }
--
2.18.0
1
1
[PATCH] testbot/WineSendLog: Report TestBot errors to the mailing list too.
by Francois Gouget Aug. 29, 2018
by Francois Gouget Aug. 29, 2018
Aug. 29, 2018
TestBot errors may or may not be caused by the patch but either way
they make it impossible to know if there are new errors. Thus the patch
requires extra scrutiny anyway.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineSendLog.pl | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/testbot/bin/WineSendLog.pl b/testbot/bin/WineSendLog.pl
index b0efa8c33..a4b1c823d 100755
--- a/testbot/bin/WineSendLog.pl
+++ b/testbot/bin/WineSendLog.pl
@@ -279,13 +279,10 @@ EOF
my $StepTask = $StepsTasks->GetItem($Key);
my $TaskDir = $StepTask->GetTaskDir();
- if ($StepTask->Status eq "boterror")
- {
- # TestBot errors are not the developer's fault and prevent us from
- # identifying new errors. So skip.
- Error "A Task error was found in '$TaskDir/log.err'\n";
- next;
- }
+ # Note: We could check $StepTask->Status for TestBot errors. However,
+ # whether they are caused by the patch or not, they prevent the TestBot
+ # from checking for new errors which justifies sending an email to the
+ # mailing list so that the patch receives greater scrutiny.
foreach my $LogName (@{$JobErrors->{$Key}->{LogNames}})
{
--
2.18.0
1
0