12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786 |
- From f8574ff8a8c64fe6ab7a4399eb0d693e926f45d1 Mon Sep 17 00:00:00 2001
- From: Nick Sarnie <commendsarnex@gmail.com>
- Date: Sun, 5 Nov 2017 22:31:07 -0500
- Subject: [PATCH 2/2] Wine D3D9
- Signed-off-by: Nick Sarnie <commendsarnex@gmail.com>
- ---
- configure.ac | 188 ++++
- dlls/d3d9-nine/Makefile.in | 15 +
- dlls/d3d9-nine/d3d9-nine.spec | 14 +
- dlls/d3d9-nine/d3d9_main.c | 173 ++++
- dlls/d3d9-nine/d3dadapter9.c | 898 +++++++++++++++++++
- dlls/d3d9-nine/d3dadapter9.h | 32 +
- dlls/d3d9-nine/device_wrap.c | 500 +++++++++++
- dlls/d3d9-nine/device_wrap.h | 26 +
- dlls/d3d9-nine/dri3.c | 1426 ++++++++++++++++++++++++++++++
- dlls/d3d9-nine/dri3.h | 91 ++
- dlls/d3d9-nine/present.c | 1748 +++++++++++++++++++++++++++++++++++++
- dlls/d3d9-nine/present.h | 40 +
- dlls/d3d9-nine/shader_validator.c | 88 ++
- dlls/d3d9-nine/shader_validator.h | 29 +
- dlls/d3d9-nine/version.rc | 26 +
- dlls/d3d9-nine/wndproc.c | 277 ++++++
- dlls/d3d9-nine/wndproc.h | 41 +
- 17 files changed, 5612 insertions(+)
- create mode 100644 dlls/d3d9-nine/Makefile.in
- create mode 100644 dlls/d3d9-nine/d3d9-nine.spec
- create mode 100644 dlls/d3d9-nine/d3d9_main.c
- create mode 100644 dlls/d3d9-nine/d3dadapter9.c
- create mode 100644 dlls/d3d9-nine/d3dadapter9.h
- create mode 100644 dlls/d3d9-nine/device_wrap.c
- create mode 100644 dlls/d3d9-nine/device_wrap.h
- create mode 100644 dlls/d3d9-nine/dri3.c
- create mode 100644 dlls/d3d9-nine/dri3.h
- create mode 100644 dlls/d3d9-nine/present.c
- create mode 100644 dlls/d3d9-nine/present.h
- create mode 100644 dlls/d3d9-nine/shader_validator.c
- create mode 100644 dlls/d3d9-nine/shader_validator.h
- create mode 100644 dlls/d3d9-nine/version.rc
- create mode 100644 dlls/d3d9-nine/wndproc.c
- create mode 100644 dlls/d3d9-nine/wndproc.h
- diff --git a/configure.ac b/configure.ac
- index 7a8fcc4987..0f2a45f336 100644
- --- a/configure.ac
- +++ b/configure.ac
- @@ -67,6 +67,14 @@ AC_ARG_WITH(openal, AS_HELP_STRING([--without-openal],[do not use OpenAL]),
- AC_ARG_WITH(opencl, AS_HELP_STRING([--without-opencl],[do not use OpenCL]),
- [if test "x$withval" = "xno"; then ac_cv_header_CL_cl_h=no; ac_cv_header_OpenCL_opencl_h=no; fi])
- AC_ARG_WITH(opengl, AS_HELP_STRING([--without-opengl],[do not use OpenGL]))
- +AC_ARG_WITH(d3d9-nine, AS_HELP_STRING([--without-d3d9-nine],[do not build d3d9-nine.dll (Gallium Nine support)]),
- + [], [with_d3d9_nine=auto])
- +AC_ARG_WITH(d3d9-nine-module, AS_HELP_STRING([--with-d3d9-nine-module],
- + [Gallium Nine module location. Can be 'manual' (path to be filled in a register), 'auto' (default. use pkgconfig to detect the location) or a path]),
- + [], [with_d3d9_nine_module=auto])
- +AC_ARG_WITH(d3d9-nine-headers-path, AS_HELP_STRING([--with-d3d9-nine-headers-path],
- + [Gallium Nine headers location. Can be 'auto' (default. use pkgconfig to detect the location) or a path]),
- + [], [with_d3d9_nine_headers_path=auto])
- AC_ARG_WITH(osmesa, AS_HELP_STRING([--without-osmesa],[do not use the OSMesa library]))
- AC_ARG_WITH(oss, AS_HELP_STRING([--without-oss],[do not use the OSS sound support]))
- AC_ARG_WITH(pcap, AS_HELP_STRING([--without-pcap],[do not use the Packet Capture library]),
- @@ -391,6 +399,8 @@ AC_CHECK_LIB(ossaudio,_oss_ioctl)
-
- AC_SUBST(OPENGL_LIBS,"")
-
- +AC_SUBST(D3D9NINE_LIBS,"")
- +
- dnl **** Check for header files ****
-
- AC_SYS_LARGEFILE()
- @@ -1248,6 +1258,183 @@ OpenGL and Direct3D won't be supported.])
- WINE_NOTICE_WITH(va,[test "x$ac_cv_lib_soname_va" = "x" -o "x$ac_cv_lib_soname_va_x11" = "x" -o "x$ac_cv_lib_soname_va_drm" = "x"],
- [libva ${notice_platform}development files not found, GPU video acceleration won't be supported.])
-
- + dnl Check for d3d9-nine support
- + if test "x$with_d3d9_nine" = "xauto" && (test "x$with_d3d9_nine_module" = "xauto" || test "x$with_d3d9_nine_headers_path" = "xauto")
- + then
- + AC_MSG_CHECKING([whether d3dadapter9 package (Gallium Nine) is present])
- + D3DADAPTER9_MODULEDIR=`$PKG_CONFIG --variable=moduledir d3dadapter9 2>/dev/null`
- + D3DADAPTER9_LEGACY_MODULEDIR=`$PKG_CONFIG --variable=moduledir d3d 2>/dev/null`
- + if test "x$D3DADAPTER9_MODULEDIR" = "x" -a "x$D3DADAPTER9_LEGACY_MODULEDIR" = "x"
- + then
- + AC_MSG_RESULT([no, disabling support])
- + with_d3d9_nine=no
- + else
- + AC_MSG_RESULT([yes])
- + fi
- + fi
- +
- + if test "x$with_d3d9_nine" != "xno"
- + then
- + AC_MSG_NOTICE([Checking for d3dadapter9 library dependencies])
- + D3D9NINE_LIBS=""
- + D3D9NINE_MISSING_LIBS=""
- + AC_CHECK_LIB(xcb,xcb_request_check,[AC_SUBST(D3D9NINE_LIBS,["$D3D9NINE_LIBS -lxcb"])])
- + test "x$ac_cv_lib_xcb_xcb_request_check" != xyes && D3D9NINE_MISSING_LIBS="libxcb "
- + AC_CHECK_LIB(xcb-dri3,xcb_dri3_open,[AC_SUBST(D3D9NINE_LIBS,["$D3D9NINE_LIBS -lxcb-dri3"])])
- + test "x$ac_cv_lib_xcb_dri3_xcb_dri3_open" != xyes && D3D9NINE_MISSING_LIBS="${D3D9NINE_MISSING_LIBS}libxcb-dri3 "
- + AC_CHECK_LIB(xcb-present,xcb_present_notify_msc,[AC_SUBST(D3D9NINE_LIBS,["$D3D9NINE_LIBS -lxcb-present"])])
- + test "x$ac_cv_lib_xcb_present_xcb_present_notify_msc" != xyes && D3D9NINE_MISSING_LIBS="${D3D9NINE_MISSING_LIBS}libxcb-present "
- + AC_CHECK_LIB(xcb-xfixes,xcb_xfixes_create_region,[AC_SUBST(D3D9NINE_LIBS,["$D3D9NINE_LIBS -lxcb-xfixes"])])
- + test "x$ac_cv_lib_xcb_xfixes_xcb_xfixes_create_region" != xyes && D3D9NINE_MISSING_LIBS="${D3D9NINE_MISSING_LIBS}libxcb-xfixes "
- + AC_CHECK_LIB(X11-xcb,XGetXCBConnection,[AC_SUBST(D3D9NINE_LIBS,["$D3D9NINE_LIBS -lX11-xcb"])])
- + test "x$ac_cv_lib_X11_xcb_XGetXCBConnection" != xyes && D3D9NINE_MISSING_LIBS="${D3D9NINE_MISSING_LIBS}libX11-xcb "
- + AC_CHECK_LIB(X11,XOpenDisplay,[AC_SUBST(D3D9NINE_LIBS,["$D3D9NINE_LIBS -lX11"])])
- + test "x$ac_cv_lib_X11_XOpenDisplay" != xyes && D3D9NINE_MISSING_LIBS="${D3D9NINE_MISSING_LIBS}libX11 "
- + AC_CHECK_LIB(Xext,XextRemoveDisplay,[AC_SUBST(D3D9NINE_LIBS,["$D3D9NINE_LIBS -lXext"])])
- + test "x$ac_cv_lib_Xext_XextRemoveDisplay" != xyes && D3D9NINE_MISSING_LIBS="${D3D9NINE_MISSING_LIBS}libXext "
- + # libs for the dri2 fallback
- + AC_CHECK_LIB(GL,glGenFramebuffers,[AC_SUBST(D3D9NINE_LIBS,["$D3D9NINE_LIBS -lGL"])])
- + test "x$ac_cv_lib_GL_glGenFramebuffers" != xyes && D3D9NINE_MISSING_LIBS="libGL "
- + AC_CHECK_LIB(EGL,eglCreateContext,[AC_SUBST(D3D9NINE_LIBS,["$D3D9NINE_LIBS -lEGL"])])
- + test "x$ac_cv_lib_EGL_eglCreateContext" != xyes && D3D9NINE_MISSING_LIBS="${D3D9NINE_MISSING_LIBS}libEGL"
- +
- + if test "x$D3D9NINE_MISSING_LIBS" != x
- + then
- + if test "x$with_d3d9_nine" = "xyes"
- + then
- + AC_MSG_ERROR([Missing libraries to build d3d9-nine.dll: $D3D9NINE_MISSING_LIBS])
- + else
- + AC_MSG_NOTICE([Missing libraries to build d3d9-nine.dll: $D3D9NINE_MISSING_LIBS . disabling support])
- + with_d3d9_nine=no
- + fi
- + fi
- + fi
- +
- + if test "x$with_d3d9_nine" != "xno"
- + then
- + AC_MSG_NOTICE([Checking d3dadapter9 header dependencies])
- + D3D9NINE_MISSING_HEADERS=""
- + AC_CHECK_HEADERS([X11/Xlib-xcb.h xcb/dri3.h xcb/present.h X11/Xutil.h X11/Xlib.h pthread.h])
- + test "x$ac_cv_header_X11_Xlib_xcb_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}X11/Xlib-xcb.h "
- + test "x$ac_cv_header_xcb_dri3_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}xcb/dri3.h "
- + test "x$ac_cv_header_xcb_present_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}xcb/present.h "
- + test "x$ac_cv_header_X11_Xutil_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}X11/Xutil.h "
- + test "x$ac_cv_header_X11_Xlib_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}X11/Xlib.h "
- + test "x$ac_cv_header_pthread_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}pthread.h "
- + # headers for the dri2 fallback
- + AC_CHECK_HEADERS([X11/Xmd.h X11/Xlibint.h X11/extensions/dri2tokens.h X11/extensions/dri2proto.h X11/extensions/extutil.h GL/gl.h GL/glext.h EGL/egl.h EGL/eglext.h libdrm/drm_fourcc.h libdrm/drm.h],
- + [],[],[[
- +#include <X11/Xlibint.h>
- +#include <X11/extensions/dri2tokens.h>
- +#include <GL/gl.h>
- +#include <EGL/egl.h>
- +]])
- + test "x$ac_cv_header_X11_Xmd_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}X11/Xmd.h "
- + test "x$ac_cv_header_X11_Xlibint_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}X11/Xlibint.h "
- + test "x$ac_cv_header_X11_extensions_dri2tokens_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}X11/extensions/dri2tokens.h "
- + test "x$ac_cv_header_X11_extensions_dri2proto_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}X11/extensions/dri2proto.h "
- + test "x$ac_cv_header_X11_extensions_extutil_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}X11/extensions/extutil.h "
- + test "x$ac_cv_header_GL_gl_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}GL/gl.h "
- + test "x$ac_cv_header_GL_glext_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}GL/glext.h "
- + test "x$ac_cv_header_EGL_egl_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}EGL/egl.h "
- + test "x$ac_cv_header_EGL_eglext_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}EGL/eglext.h "
- + test "x$ac_cv_header_libdrm_drm_fourcc_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}libdrm/drm_fourcc.h "
- + test "x$ac_cv_header_libdrm_drm_h" != xyes && D3D9NINE_MISSING_HEADERS="${D3D9NINE_MISSING_HEADERS}libdrm/drm.h "
- + if test "x$D3D9NINE_MISSING_HEADERS" != x
- + then
- + if test "x$with_d3d9_nine" = "xyes"
- + then
- + AC_MSG_ERROR([Missing headers to build d3d9-nine.dll: $D3D9NINE_MISSING_HEADERS])
- + else
- + AC_MSG_NOTICE([Missing headers to build d3d9-nine.dll: $D3D9NINE_MISSING_HEADERS . disabling support])
- + with_d3d9_nine=no
- + fi
- + fi
- + fi
- +
- + if test "x$with_d3d9_nine" != "xno"
- + then
- + # d3d9-nine.dll will be built and an option to use it
- + # added. The module path can always be overriden by
- + # a wine registry setting. If the module isn't found
- + # at execution time, the dll will refuse to load and
- + # print an error message to the user.
- + AC_DEFINE(HAVE_D3D9NINE, 1, [Whether d3d9-nine.dll is built])
- + # default: use pkgconfig to find the gallium nine module.
- + # Check the module is there.
- + if test "x$with_d3d9_nine_module" = "xauto"
- + then
- + D3DADAPTER9_MODULEDIR=`$PKG_CONFIG --variable=moduledir d3dadapter9 2>/dev/null`
- + if test "x$D3DADAPTER9_MODULEDIR" = x
- + then
- + # legacy path
- + D3DADAPTER9_MODULEDIR=`$PKG_CONFIG --variable=moduledir d3d 2>/dev/null`
- + if test "x$D3DADAPTER9_MODULEDIR" = x
- + then
- + AC_MSG_ERROR([pkg-config couldn't find Gallium Nine module])
- + fi
- + fi
- + AC_DEFINE_UNQUOTED(D3D9NINE_MODULEPATH, ["`echo ${D3DADAPTER9_MODULEDIR}/d3dadapter9.so.1`"], [Gallium Nine module path])
- + # Check module
- + CPPFLAGSBAK=$CPPFLAGS
- + # link against libdl
- + CPPFLAGS="$CPPFLAGS -Wl,--no-as-needed -ldl"
- +
- + AC_RUN_IFELSE([AC_LANG_PROGRAM([[#include <dlfcn.h>
- +#include <stdlib.h>]],[[void *handle = dlopen("${D3DADAPTER9_MODULEDIR}/d3dadapter9.so.1", RTLD_GLOBAL | RTLD_NOW);
- +exit((handle && dlsym(handle, "D3DAdapter9GetProc")) ? 0 : 1)]])],
- + [echo "d3dadapter9.so.1 found at '${D3DADAPTER9_MODULEDIR}/d3dadapter9.so.1'"],
- + [AC_MSG_ERROR([Couldn't load Gallium nine module at '${D3DADAPTER9_MODULEDIR}/d3dadapter9.so.1' (found by pkg-config)])])
- + CPPFLAGS=$CPPFLAGSBAK
- + else
- + # Manual : do not feed any path, the wine registry will have
- + # to be used to pass a path. Useful for wine builds
- + # that are distributed and will run on different
- + # distros.
- + # Else feed a path directly. Useful for distro maintainers who
- + # know where the package would be installed, but don't have
- + # it installed on their build.
- + # Don't check if the module is there.
- + if test "x$with_d3d9_nine_module" != "xmanual"
- + then
- + AC_DEFINE_UNQUOTED(D3D9NINE_MODULEPATH, ["`echo ${with_d3d9_nine_module}`"], [Gallium Nine module path])
- + fi
- + fi
- +
- + # by default the headers are found with pkgconfig,
- + # but it is possible to pass a path to a specific directory.
- + # that directory must contain a d3dadapter directory
- + # with d3dadapter9.h, drm.h and present.h
- + if test "x$with_d3d9_nine_headers_path" = "xauto"
- + then
- + AC_PROG_SED
- + D3DADAPTER9_INCLUDEDIR=`$PKG_CONFIG --variable=includedir d3dadapter9 2>/dev/null`
- + D3DADAPTER9_MAJOR=`$PKG_CONFIG --modversion d3dadapter9 2>/dev/null | $SED -n 's/\([[^\.]]*\)\..*$/\1/p'`
- + if test "x$D3DADAPTER9_INCLUDEDIR" = x
- + then
- + # legacy path
- + D3DADAPTER9_INCLUDEDIR=`$PKG_CONFIG --variable=includedir d3d 2>/dev/null`
- + D3DADAPTER9_MAJOR=`$PKG_CONFIG --modversion d3d 2>/dev/null | $SED -n 's/\([[^\.]]*\)\..*$/\1/p'`
- + if test "x$D3DADAPTER9_INCLUDEDIR" = x
- + then
- + AC_MSG_ERROR([pkg-config couldn't find Gallium Nine headers])
- + fi
- + fi
- + # check major version of package. The major version number guarantees header compatibility.
- + if test "x$D3DADAPTER9_MAJOR" != x1
- + then
- + AC_MSG_ERROR([pkg-config found Gallium Nine Module and Headers, but version is incompatible])
- + fi
- + else
- + D3DADAPTER9_INCLUDEDIR=`echo ${with_d3d9_nine_headers_path}`
- + fi
- + AC_DEFINE_UNQUOTED(D3D9NINE_HEADERS_CFLAGS, ["`echo -I${D3DADAPTER9_INCLUDEDIR}`"], [Gallium Nine headers cflags])
- +
- + AC_DEFINE(D3D9NINE_DRI2, 1, [Whether d3d9-nine DRI2 fallback is compiled])
- + else
- + enable_d3d9_nine=${enable_d3d9_nine:-no}
- + fi
- +
- CPPFLAGS="$ac_save_CPPFLAGS"
- else
- X_CFLAGS=""
- @@ -3127,6 +3314,7 @@ WINE_CONFIG_DLL(d3d8,,[implib])
- WINE_CONFIG_TEST(dlls/d3d8/tests)
- WINE_CONFIG_DLL(d3d9,,[implib])
- WINE_CONFIG_TEST(dlls/d3d9/tests)
- +WINE_CONFIG_DLL(d3d9-nine,,[implib])
- WINE_CONFIG_DLL(d3dcompiler_33)
- WINE_CONFIG_DLL(d3dcompiler_34)
- WINE_CONFIG_DLL(d3dcompiler_35)
- diff --git a/dlls/d3d9-nine/Makefile.in b/dlls/d3d9-nine/Makefile.in
- new file mode 100644
- index 0000000000..c6df8d7dbe
- --- /dev/null
- +++ b/dlls/d3d9-nine/Makefile.in
- @@ -0,0 +1,15 @@
- +MODULE = d3d9-nine.dll
- +IMPORTS = dxguid uuid advapi32 gdi32 user32
- +EXTRAINCL = $(X_CFLAGS) $(D3D9NINE_HEADERS_CFLAGS)
- +EXTRALIBS = $(D3D9NINE_LIBS)
- +
- +C_SRCS = \
- + d3d9_main.c \
- + d3dadapter9.c \
- + device_wrap.c \
- + present.c \
- + dri3.c \
- + wndproc.c \
- + shader_validator.c
- +
- +RC_SRCS = version.rc
- diff --git a/dlls/d3d9-nine/d3d9-nine.spec b/dlls/d3d9-nine/d3d9-nine.spec
- new file mode 100644
- index 0000000000..a33cba51e7
- --- /dev/null
- +++ b/dlls/d3d9-nine/d3d9-nine.spec
- @@ -0,0 +1,14 @@
- +@ stdcall Direct3DShaderValidatorCreate9()
- +@ stub PSGPError
- +@ stub PSGPSampleTexture
- +@ stdcall D3DPERF_BeginEvent(long wstr)
- +@ stdcall D3DPERF_EndEvent()
- +@ stdcall D3DPERF_GetStatus()
- +@ stdcall D3DPERF_QueryRepeatFrame()
- +@ stdcall D3DPERF_SetMarker(long wstr)
- +@ stdcall D3DPERF_SetOptions(long)
- +@ stdcall D3DPERF_SetRegion(long wstr)
- +@ stub DebugSetLevel
- +@ stdcall DebugSetMute()
- +@ stdcall Direct3DCreate9(long)
- +@ stdcall Direct3DCreate9Ex(long ptr)
- diff --git a/dlls/d3d9-nine/d3d9_main.c b/dlls/d3d9-nine/d3d9_main.c
- new file mode 100644
- index 0000000000..d1efdf4a71
- --- /dev/null
- +++ b/dlls/d3d9-nine/d3d9_main.c
- @@ -0,0 +1,173 @@
- +/*
- + * Direct3D 9
- + *
- + * Copyright 2002-2003 Jason Edmeades
- + * Copyright 2002-2003 Raphael Junqueira
- + * Copyright 2005 Oliver Stieber
- + * Copyright 2015 Patrick Rudolph
- + *
- + * 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
- + *
- + */
- +
- +#include "config.h"
- +#include "wine/debug.h"
- +
- +#include <fcntl.h>
- +#include <d3d9.h>
- +
- +#include "d3dadapter9.h"
- +#include "wndproc.h"
- +#include "shader_validator.h"
- +
- +WINE_DEFAULT_DEBUG_CHANNEL(d3d9nine);
- +
- +static int D3DPERF_event_level = 0;
- +static Display *gdi_display;
- +
- +void WINAPI DebugSetMute(void)
- +{
- + /* nothing to do */
- +}
- +
- +IDirect3D9 * WINAPI DECLSPEC_HOTPATCH Direct3DCreate9(UINT sdk_version)
- +{
- + IDirect3D9 *native;
- + TRACE("sdk_version %#x.\n", sdk_version);
- +
- + if (SUCCEEDED(d3dadapter9_new(gdi_display, FALSE, (IDirect3D9Ex **)&native)))
- + return native;
- +
- + return NULL;
- +}
- +
- +HRESULT WINAPI DECLSPEC_HOTPATCH Direct3DCreate9Ex(UINT sdk_version, IDirect3D9Ex **d3d9ex)
- +{
- + TRACE("sdk_version %#x, d3d9ex %p.\n", sdk_version, d3d9ex);
- +
- + return d3dadapter9_new(gdi_display, TRUE, d3d9ex);
- +}
- +
- +/*******************************************************************
- + * Direct3DShaderValidatorCreate9 (D3D9.@)
- + *
- + * No documentation available for this function.
- + * SDK only says it is internal and shouldn't be used.
- + */
- +
- +void* WINAPI Direct3DShaderValidatorCreate9(void)
- +{
- + IDirect3DShaderValidator9Impl* object =
- + HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- + sizeof(IDirect3DShaderValidator9Impl));
- +
- + object->lpVtbl = &IDirect3DShaderValidator9Vtbl;
- + object->ref = 1;
- +
- + FIXME("Returning interface %p\n", object);
- + return (void*) object;
- +}
- +
- +/*******************************************************************
- + * DllMain
- + */
- +BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved)
- +{
- + switch (reason)
- + {
- + case DLL_PROCESS_ATTACH:
- + if (!(gdi_display = XOpenDisplay( NULL )))
- + {
- + ERR("Failed to open display\n");
- + return FALSE;
- + }
- +
- + fcntl( ConnectionNumber(gdi_display), F_SETFD, 1 ); /* set close on exec flag */
- +
- + nine_dll_init(inst);
- + break;
- + case DLL_PROCESS_DETACH:
- + if (!reserved)
- + return nine_dll_destroy(inst);
- + break;
- + }
- +
- + return TRUE;
- +}
- +
- +/***********************************************************************
- + * D3DPERF_BeginEvent (D3D9.@)
- + */
- +int WINAPI D3DPERF_BeginEvent(D3DCOLOR color, const WCHAR *name)
- +{
- + TRACE("color 0x%08x, name %s.\n", color, debugstr_w(name));
- +
- + return D3DPERF_event_level++;
- +}
- +
- +/***********************************************************************
- + * D3DPERF_EndEvent (D3D9.@)
- + */
- +int WINAPI D3DPERF_EndEvent(void)
- +{
- + TRACE("(void) : stub\n");
- +
- + return --D3DPERF_event_level;
- +}
- +
- +/***********************************************************************
- + * D3DPERF_GetStatus (D3D9.@)
- + */
- +DWORD WINAPI D3DPERF_GetStatus(void)
- +{
- + FIXME("(void) : stub\n");
- +
- + return 0;
- +}
- +
- +/***********************************************************************
- + * D3DPERF_SetOptions (D3D9.@)
- + *
- + */
- +void WINAPI D3DPERF_SetOptions(DWORD options)
- +{
- + FIXME("(%#x) : stub\n", options);
- +}
- +
- +/***********************************************************************
- + * D3DPERF_QueryRepeatFrame (D3D9.@)
- + */
- +BOOL WINAPI D3DPERF_QueryRepeatFrame(void)
- +{
- + FIXME("(void) : stub\n");
- +
- + return FALSE;
- +}
- +
- +/***********************************************************************
- + * D3DPERF_SetMarker (D3D9.@)
- + */
- +void WINAPI D3DPERF_SetMarker(D3DCOLOR color, const WCHAR *name)
- +{
- + FIXME("color 0x%08x, name %s stub!\n", color, debugstr_w(name));
- +}
- +
- +/***********************************************************************
- + * D3DPERF_SetRegion (D3D9.@)
- + */
- +void WINAPI D3DPERF_SetRegion(D3DCOLOR color, const WCHAR *name)
- +{
- + FIXME("color 0x%08x, name %s stub!\n", color, debugstr_w(name));
- +}
- diff --git a/dlls/d3d9-nine/d3dadapter9.c b/dlls/d3d9-nine/d3dadapter9.c
- new file mode 100644
- index 0000000000..188eebf763
- --- /dev/null
- +++ b/dlls/d3d9-nine/d3dadapter9.c
- @@ -0,0 +1,898 @@
- +/*
- + * Wine IDirect3D9 interface using ID3DAdapter9
- + *
- + * Copyright 2013 Joakim Sindholt
- + * Christoph Bumiller
- + * Copyright 2014 David Heidelberger
- + * Copyright 2014-2015 Axel Davy
- + * Copyright 2015 Nick Sarnie
- + * Patrick Rudolph
- + *
- + * 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
- + */
- +
- +#include "config.h"
- +#include "wine/debug.h"
- +
- +WINE_DEFAULT_DEBUG_CHANNEL(d3d9nine);
- +
- +#include <d3dadapter/d3dadapter9.h>
- +#include "present.h"
- +#include "device_wrap.h"
- +
- +/* this represents a snapshot taken at the moment of creation */
- +struct output
- +{
- + D3DDISPLAYROTATION rotation; /* current rotation */
- + D3DDISPLAYMODEEX *modes;
- + unsigned nmodes;
- + unsigned nmodesalloc;
- + unsigned current; /* current mode num */
- +
- + HMONITOR monitor;
- +};
- +
- +struct adapter_group
- +{
- + struct output *outputs;
- + unsigned noutputs;
- + unsigned noutputsalloc;
- +
- + /* override driver provided DeviceName with this to homogenize device names
- + * with wine */
- + WCHAR devname[32];
- +
- + /* driver stuff */
- + ID3DAdapter9 *adapter;
- +};
- +
- +struct adapter_map
- +{
- + unsigned group;
- + unsigned master;
- +};
- +
- +struct d3dadapter9
- +{
- + /* COM vtable */
- + void *vtable;
- + /* IUnknown reference count */
- + LONG refs;
- +
- + /* adapter groups and mappings */
- + struct adapter_group *groups;
- + struct adapter_map *map;
- + unsigned nadapters;
- + unsigned ngroups;
- + unsigned ngroupsalloc;
- +
- + /* true if it implements IDirect3D9Ex */
- + boolean ex;
- + Display *gdi_display;
- +};
- +
- +/* convenience wrapper for calls into ID3D9Adapter */
- +#define ADAPTER_GROUP \
- + This->groups[This->map[Adapter].group]
- +
- +#define ADAPTER_PROC(name, ...) \
- + ID3DAdapter9_##name(ADAPTER_GROUP.adapter, ## __VA_ARGS__)
- +
- +#define ADAPTER_OUTPUT \
- + ADAPTER_GROUP.outputs[Adapter-This->map[Adapter].master]
- +
- +static HRESULT WINAPI d3dadapter9_CheckDeviceFormat(struct d3dadapter9 *This,
- + UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat,
- + DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat);
- +
- +static ULONG WINAPI d3dadapter9_AddRef(struct d3dadapter9 *This)
- +{
- + ULONG refs = InterlockedIncrement(&This->refs);
- + TRACE("%p increasing refcount to %u.\n", This, refs);
- + return refs;
- +}
- +
- +static ULONG WINAPI d3dadapter9_Release(struct d3dadapter9 *This)
- +{
- + ULONG refs = InterlockedDecrement(&This->refs);
- + TRACE("%p decreasing refcount to %u.\n", This, refs);
- + if (refs == 0)
- + {
- + /* dtor */
- + if (This->map)
- + {
- + HeapFree(GetProcessHeap(), 0, This->map);
- + }
- +
- + if (This->groups)
- + {
- + int i, j;
- + for (i = 0; i < This->ngroups; ++i)
- + {
- + if (This->groups[i].outputs)
- + {
- + for (j = 0; j < This->groups[i].noutputs; ++j)
- + {
- + if (This->groups[i].outputs[j].modes)
- + {
- + HeapFree(GetProcessHeap(), 0,
- + This->groups[i].outputs[j].modes);
- + }
- + }
- + HeapFree(GetProcessHeap(), 0, This->groups[i].outputs);
- + }
- +
- + if (This->groups[i].adapter)
- + ID3DAdapter9_Release(This->groups[i].adapter);
- + }
- + HeapFree(GetProcessHeap(), 0, This->groups);
- + }
- +
- + HeapFree(GetProcessHeap(), 0, This);
- + }
- + return refs;
- +}
- +
- +static HRESULT WINAPI d3dadapter9_QueryInterface(struct d3dadapter9 *This,
- + REFIID riid, void **ppvObject)
- +{
- + if (!ppvObject)
- + return E_POINTER;
- +
- + if ((IsEqualGUID(&IID_IDirect3D9Ex, riid) && This->ex) ||
- + IsEqualGUID(&IID_IDirect3D9, riid) ||
- + IsEqualGUID(&IID_IUnknown, riid))
- + {
- + *ppvObject = This;
- + d3dadapter9_AddRef(This);
- + return S_OK;
- + }
- +
- + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
- + *ppvObject = NULL;
- +
- + return E_NOINTERFACE;
- +}
- +
- +static HRESULT WINAPI d3dadapter9_RegisterSoftwareDevice(struct d3dadapter9 *This,
- + void *pInitializeFunction)
- +{
- + FIXME("(%p, %p), stub!\n", This, pInitializeFunction);
- + return D3DERR_INVALIDCALL;
- +}
- +
- +static UINT WINAPI d3dadapter9_GetAdapterCount(struct d3dadapter9 *This)
- +{
- + return This->nadapters;
- +}
- +
- +static HRESULT WINAPI d3dadapter9_GetAdapterIdentifier(struct d3dadapter9 *This,
- + UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER9 *pIdentifier)
- +{
- + HRESULT hr;
- + HKEY regkey;
- +
- + if (Adapter >= d3dadapter9_GetAdapterCount(This))
- + return D3DERR_INVALIDCALL;
- +
- + hr = ADAPTER_PROC(GetAdapterIdentifier, Flags, pIdentifier);
- + if (SUCCEEDED(hr))
- + {
- + /* Override the driver provided DeviceName with what Wine provided */
- + ZeroMemory(pIdentifier->DeviceName, sizeof(pIdentifier->DeviceName));
- + if (!WideCharToMultiByte(CP_ACP, 0, ADAPTER_GROUP.devname, -1,
- + pIdentifier->DeviceName, sizeof(pIdentifier->DeviceName), NULL, NULL))
- + return D3DERR_INVALIDCALL;
- +
- + TRACE("DeviceName overriden: %s\n", pIdentifier->DeviceName);
- +
- + /* Override PCI IDs when wined3d registry keys are set */
- + if (!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Direct3DNine", ®key))
- + {
- + DWORD type, data;
- + DWORD size = sizeof(DWORD);
- +
- + if (!RegQueryValueExA(regkey, "VideoPciDeviceID", 0, &type, (BYTE *)&data, &size) &&
- + (type == REG_DWORD) && (size == sizeof(DWORD)))
- + pIdentifier->DeviceId = data;
- + if (size != sizeof(DWORD))
- + {
- + ERR("VideoPciDeviceID is not a DWORD\n");
- + size = sizeof(DWORD);
- + }
- + if (!RegQueryValueExA(regkey, "VideoPciVendorID", 0, &type, (BYTE *)&data, &size) &&
- + (type == REG_DWORD) && (size == sizeof(DWORD)))
- + pIdentifier->VendorId = data;
- + if (size != sizeof(DWORD))
- + ERR("VideoPciVendorID is not a DWORD\n");
- + RegCloseKey(regkey);
- +
- + TRACE("DeviceId:VendorId overridden: %04X:%04X\n", pIdentifier->DeviceId, pIdentifier->VendorId);
- + }
- + }
- + return hr;
- +}
- +
- +static UINT WINAPI d3dadapter9_GetAdapterModeCount(struct d3dadapter9 *This,
- + UINT Adapter, D3DFORMAT Format)
- +{
- + if (Adapter >= d3dadapter9_GetAdapterCount(This))
- + return D3DERR_INVALIDCALL;
- +
- + if (FAILED(d3dadapter9_CheckDeviceFormat(This, Adapter, D3DDEVTYPE_HAL,
- + Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, Format)))
- + {
- + WARN("DeviceFormat not available.\n");
- + return 0;
- + }
- +
- + TRACE("%u modes.\n", ADAPTER_OUTPUT.nmodes);
- + return ADAPTER_OUTPUT.nmodes;
- +}
- +
- +static HRESULT WINAPI d3dadapter9_EnumAdapterModes(struct d3dadapter9 *This,
- + UINT Adapter, D3DFORMAT Format, UINT Mode, D3DDISPLAYMODE *pMode)
- +{
- + HRESULT hr;
- +
- + if (Adapter >= d3dadapter9_GetAdapterCount(This))
- + return D3DERR_INVALIDCALL;
- +
- + hr = d3dadapter9_CheckDeviceFormat(This, Adapter, D3DDEVTYPE_HAL,
- + Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, Format);
- +
- + if (FAILED(hr))
- + {
- + TRACE("DeviceFormat not available.\n");
- + return hr;
- + }
- +
- + if (Mode >= ADAPTER_OUTPUT.nmodes)
- + {
- + WARN("Mode %u does not exist.\n", Mode);
- + return D3DERR_INVALIDCALL;
- + }
- +
- + pMode->Width = ADAPTER_OUTPUT.modes[Mode].Width;
- + pMode->Height = ADAPTER_OUTPUT.modes[Mode].Height;
- + pMode->RefreshRate = ADAPTER_OUTPUT.modes[Mode].RefreshRate;
- + pMode->Format = Format;
- +
- + return D3D_OK;
- +}
- +
- +static HRESULT WINAPI d3dadapter9_GetAdapterDisplayMode(struct d3dadapter9 *This,
- + UINT Adapter, D3DDISPLAYMODE *pMode)
- +{
- + UINT Mode;
- +
- + if (Adapter >= d3dadapter9_GetAdapterCount(This))
- + return D3DERR_INVALIDCALL;
- +
- + Mode = ADAPTER_OUTPUT.current;
- + pMode->Width = ADAPTER_OUTPUT.modes[Mode].Width;
- + pMode->Height = ADAPTER_OUTPUT.modes[Mode].Height;
- + pMode->RefreshRate = ADAPTER_OUTPUT.modes[Mode].RefreshRate;
- + pMode->Format = ADAPTER_OUTPUT.modes[Mode].Format;
- +
- + return D3D_OK;
- +}
- +
- +static HRESULT WINAPI d3dadapter9_CheckDeviceType(struct d3dadapter9 *This,
- + UINT Adapter, D3DDEVTYPE DevType, D3DFORMAT AdapterFormat,
- + D3DFORMAT BackBufferFormat, BOOL bWindowed)
- +{
- + if (Adapter >= d3dadapter9_GetAdapterCount(This))
- + return D3DERR_INVALIDCALL;
- +
- + return ADAPTER_PROC(CheckDeviceType,
- + DevType, AdapterFormat, BackBufferFormat, bWindowed);
- +}
- +
- +static HRESULT WINAPI d3dadapter9_CheckDeviceFormat(struct d3dadapter9 *This,
- + UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat,
- + DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat)
- +{
- + if (Adapter >= d3dadapter9_GetAdapterCount(This))
- + return D3DERR_INVALIDCALL;
- +
- + return ADAPTER_PROC(CheckDeviceFormat,
- + DeviceType, AdapterFormat, Usage, RType, CheckFormat);
- +}
- +
- +static HRESULT WINAPI d3dadapter9_CheckDeviceMultiSampleType(struct d3dadapter9 *This,
- + UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat,
- + BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType, DWORD *pQualityLevels)
- +{
- + if (Adapter >= d3dadapter9_GetAdapterCount(This))
- + return D3DERR_INVALIDCALL;
- +
- + return ADAPTER_PROC(CheckDeviceMultiSampleType, DeviceType, SurfaceFormat,
- + Windowed, MultiSampleType, pQualityLevels);
- +}
- +
- +static HRESULT WINAPI d3dadapter9_CheckDepthStencilMatch(struct d3dadapter9 *This,
- + UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat,
- + D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat)
- +{
- + if (Adapter >= d3dadapter9_GetAdapterCount(This))
- + return D3DERR_INVALIDCALL;
- +
- + return ADAPTER_PROC(CheckDepthStencilMatch, DeviceType, AdapterFormat,
- + RenderTargetFormat, DepthStencilFormat);
- +}
- +
- +static HRESULT WINAPI d3dadapter9_CheckDeviceFormatConversion(struct d3dadapter9 *This,
- + UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SourceFormat, D3DFORMAT TargetFormat)
- +{
- + if (Adapter >= d3dadapter9_GetAdapterCount(This))
- + return D3DERR_INVALIDCALL;
- +
- + return ADAPTER_PROC(CheckDeviceFormatConversion,
- + DeviceType, SourceFormat, TargetFormat);
- +}
- +
- +static HRESULT WINAPI d3dadapter9_GetDeviceCaps(struct d3dadapter9 *This,
- + UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9 *pCaps)
- +{
- + HRESULT hr;
- +
- + if (Adapter >= d3dadapter9_GetAdapterCount(This))
- + return D3DERR_INVALIDCALL;
- +
- + hr = ADAPTER_PROC(GetDeviceCaps, DeviceType, pCaps);
- + if (FAILED(hr))
- + return hr;
- +
- + pCaps->MasterAdapterOrdinal = This->map[Adapter].master;
- + pCaps->AdapterOrdinalInGroup = Adapter-This->map[Adapter].master;
- + pCaps->NumberOfAdaptersInGroup = ADAPTER_GROUP.noutputs;
- +
- + return hr;
- +}
- +
- +static HMONITOR WINAPI d3dadapter9_GetAdapterMonitor(struct d3dadapter9 *This,
- + UINT Adapter)
- +{
- + if (Adapter >= d3dadapter9_GetAdapterCount(This))
- + return (HMONITOR)0;
- +
- + return (HMONITOR)ADAPTER_OUTPUT.monitor;
- +}
- +
- +static HRESULT WINAPI DECLSPEC_HOTPATCH d3dadapter9_CreateDeviceEx(struct d3dadapter9 *This,
- + UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags,
- + D3DPRESENT_PARAMETERS *pPresentationParameters,
- + D3DDISPLAYMODEEX *pFullscreenDisplayMode,
- + IDirect3DDevice9Ex **ppReturnedDeviceInterface);
- +
- +static HRESULT WINAPI DECLSPEC_HOTPATCH d3dadapter9_CreateDevice(struct d3dadapter9 *This,
- + UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags,
- + D3DPRESENT_PARAMETERS *pPresentationParameters,
- + IDirect3DDevice9 **ppReturnedDeviceInterface)
- +{
- + HRESULT hr;
- + hr = d3dadapter9_CreateDeviceEx(This, Adapter, DeviceType, hFocusWindow,
- + BehaviorFlags, pPresentationParameters, NULL,
- + (IDirect3DDevice9Ex **)ppReturnedDeviceInterface);
- + if (FAILED(hr))
- + return hr;
- +
- + return D3D_OK;
- +}
- +
- +static UINT WINAPI d3dadapter9_GetAdapterModeCountEx(struct d3dadapter9 *This,
- + UINT Adapter, const D3DDISPLAYMODEFILTER *pFilter)
- +{
- + FIXME("(%p, %u, %p), half stub!\n", This, Adapter, pFilter);
- + return d3dadapter9_GetAdapterModeCount(This, Adapter, pFilter->Format);
- +}
- +
- +static HRESULT WINAPI d3dadapter9_EnumAdapterModesEx(struct d3dadapter9 *This,
- + UINT Adapter, const D3DDISPLAYMODEFILTER *pFilter, UINT Mode,
- + D3DDISPLAYMODEEX *pMode)
- +{
- + HRESULT hr;
- +
- + FIXME("(%p, %u, %p, %u, %p), half stub!\n", This, Adapter, pFilter, Mode, pMode);
- +
- + if (Adapter >= d3dadapter9_GetAdapterCount(This))
- + return D3DERR_INVALIDCALL;
- +
- + hr = d3dadapter9_CheckDeviceFormat(This, Adapter, D3DDEVTYPE_HAL,
- + pFilter->Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, pFilter->Format);
- +
- + if (FAILED(hr))
- + {
- + TRACE("DeviceFormat not available.\n");
- + return hr;
- + }
- +
- + if (Mode >= ADAPTER_OUTPUT.nmodes)
- + {
- + WARN("Mode %u does not exist.\n", Mode);
- + return D3DERR_INVALIDCALL;
- + }
- +
- + pMode->Size = ADAPTER_OUTPUT.modes[Mode].Size;
- + pMode->Width = ADAPTER_OUTPUT.modes[Mode].Width;
- + pMode->Height = ADAPTER_OUTPUT.modes[Mode].Height;
- + pMode->RefreshRate = ADAPTER_OUTPUT.modes[Mode].RefreshRate;
- + pMode->Format = ADAPTER_OUTPUT.modes[Mode].Format;
- + pMode->ScanLineOrdering = ADAPTER_OUTPUT.modes[Mode].ScanLineOrdering;
- +
- + return D3D_OK;
- +}
- +
- +static HRESULT WINAPI d3dadapter9_GetAdapterDisplayModeEx(struct d3dadapter9 *This,
- + UINT Adapter, D3DDISPLAYMODEEX *pMode, D3DDISPLAYROTATION *pRotation)
- +{
- + UINT Mode;
- +
- + if (Adapter >= d3dadapter9_GetAdapterCount(This))
- + return D3DERR_INVALIDCALL;
- +
- + if (pMode)
- + {
- + Mode = ADAPTER_OUTPUT.current;
- + pMode->Size = sizeof(D3DDISPLAYMODEEX);
- + pMode->Width = ADAPTER_OUTPUT.modes[Mode].Width;
- + pMode->Height = ADAPTER_OUTPUT.modes[Mode].Height;
- + pMode->RefreshRate = ADAPTER_OUTPUT.modes[Mode].RefreshRate;
- + pMode->Format = ADAPTER_OUTPUT.modes[Mode].Format;
- + pMode->ScanLineOrdering = ADAPTER_OUTPUT.modes[Mode].ScanLineOrdering;
- + }
- + if (pRotation)
- + *pRotation = ADAPTER_OUTPUT.rotation;
- +
- + return D3D_OK;
- +}
- +
- +static HRESULT WINAPI DECLSPEC_HOTPATCH d3dadapter9_CreateDeviceEx(struct d3dadapter9 *This,
- + UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags,
- + D3DPRESENT_PARAMETERS *pPresentationParameters,
- + D3DDISPLAYMODEEX *pFullscreenDisplayMode,
- + IDirect3DDevice9Ex **ppReturnedDeviceInterface)
- +{
- + ID3DPresentGroup *present;
- + HRESULT hr;
- +
- + if (Adapter >= d3dadapter9_GetAdapterCount(This))
- + return D3DERR_INVALIDCALL;
- +
- + {
- + struct adapter_group *group = &ADAPTER_GROUP;
- + unsigned nparams, ordinal;
- +
- + if (BehaviorFlags & D3DCREATE_ADAPTERGROUP_DEVICE)
- + {
- + nparams = group->noutputs;
- + ordinal = 0;
- + }
- + else
- + {
- + nparams = 1;
- + ordinal = Adapter - This->map[Adapter].master;
- + }
- + hr = present_create_present_group(This->gdi_display, group->devname, ordinal,
- + hFocusWindow, pPresentationParameters, nparams, &present, This->ex,
- + BehaviorFlags);
- + }
- +
- + if (FAILED(hr))
- + {
- + WARN("Failed to create PresentGroup.\n");
- + return hr;
- + }
- +
- + if (This->ex)
- + {
- + hr = ADAPTER_PROC(CreateDeviceEx, Adapter, DeviceType, hFocusWindow,
- + BehaviorFlags, pPresentationParameters, pFullscreenDisplayMode,
- + (IDirect3D9Ex *)This, present, ppReturnedDeviceInterface);
- + }
- + else
- + {
- + /* CreateDevice on non-ex */
- + hr = ADAPTER_PROC(CreateDevice, Adapter, DeviceType, hFocusWindow,
- + BehaviorFlags, pPresentationParameters, (IDirect3D9 *)This, present,
- + (IDirect3DDevice9 **)ppReturnedDeviceInterface);
- + }
- + if (FAILED(hr))
- + {
- + WARN("ADAPTER_PROC failed.\n");
- + ID3DPresentGroup_Release(present);
- + return hr;
- + }
- +
- + /* Nine returns different vtables for Ex, non Ex and
- + * if you use the multithread flag or not. This prevents
- + * things like Steam overlay to work, in addition to the problem
- + * that functions nine side are not recognized by wine as
- + * hotpatch-able. If possible, we use our vtable wrapper,
- + * which solves the problem described above. */
- + if (enable_device_vtable_wrapper())
- + (*ppReturnedDeviceInterface)->lpVtbl = get_device_vtable();
- + return hr;
- +}
- +
- +static HRESULT WINAPI d3dadapter9_GetAdapterLUID(struct d3dadapter9 *This,
- + UINT Adapter, LUID *pLUID)
- +{
- + FIXME("(%p, %u, %p), stub!\n", This, Adapter, pLUID);
- + return D3DERR_INVALIDCALL;
- +}
- +
- +static struct adapter_group *add_group(struct d3dadapter9 *This)
- +{
- + if (This->ngroups >= This->ngroupsalloc)
- + {
- + void *r;
- +
- + if (This->ngroupsalloc == 0)
- + {
- + This->ngroupsalloc = 2;
- + r = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- + This->ngroupsalloc*sizeof(struct adapter_group));
- + }
- + else
- + {
- + This->ngroupsalloc <<= 1;
- + r = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->groups,
- + This->ngroupsalloc*sizeof(struct adapter_group));
- + }
- +
- + if (!r)
- + return NULL;
- + This->groups = r;
- + }
- +
- + return &This->groups[This->ngroups++];
- +}
- +
- +static void remove_group(struct d3dadapter9 *This)
- +{
- + struct adapter_group *group = &This->groups[This->ngroups-1];
- + int i;
- +
- + for (i = 0; i < group->noutputs; ++i)
- + {
- + HeapFree(GetProcessHeap(), 0, group->outputs[i].modes);
- + }
- + HeapFree(GetProcessHeap(), 0, group->outputs);
- +
- + ZeroMemory(group, sizeof(struct adapter_group));
- + This->ngroups--;
- +}
- +
- +static struct output *add_output(struct d3dadapter9 *This)
- +{
- + struct adapter_group *group = &This->groups[This->ngroups-1];
- +
- + if (group->noutputs >= group->noutputsalloc)
- + {
- + void *r;
- +
- + if (group->noutputsalloc == 0)
- + {
- + group->noutputsalloc = 2;
- + r = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- + group->noutputsalloc*sizeof(struct output));
- + }
- + else
- + {
- + group->noutputsalloc <<= 1;
- + r = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, group->outputs,
- + group->noutputsalloc*sizeof(struct output));
- + }
- +
- + if (!r)
- + return NULL;
- + group->outputs = r;
- + }
- +
- + return &group->outputs[group->noutputs++];
- +}
- +
- +static void remove_output(struct d3dadapter9 *This)
- +{
- + struct adapter_group *group = &This->groups[This->ngroups-1];
- + struct output *out = &group->outputs[group->noutputs-1];
- +
- + HeapFree(GetProcessHeap(), 0, out->modes);
- +
- + ZeroMemory(out, sizeof(struct output));
- + group->noutputs--;
- +}
- +
- +static D3DDISPLAYMODEEX *add_mode(struct d3dadapter9 *This)
- +{
- + struct adapter_group *group = &This->groups[This->ngroups-1];
- + struct output *out = &group->outputs[group->noutputs-1];
- +
- + if (out->nmodes >= out->nmodesalloc)
- + {
- + void *r;
- +
- + if (out->nmodesalloc == 0)
- + {
- + out->nmodesalloc = 8;
- + r = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- + out->nmodesalloc*sizeof(struct D3DDISPLAYMODEEX));
- + }
- + else
- + {
- + out->nmodesalloc <<= 1;
- + r = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, out->modes,
- + out->nmodesalloc*sizeof(struct D3DDISPLAYMODEEX));
- + }
- +
- + if (!r)
- + return NULL;
- + out->modes = r;
- + }
- +
- + return &out->modes[out->nmodes++];
- +}
- +
- +static void remove_mode(struct d3dadapter9 *This)
- +{
- + struct adapter_group *group = &This->groups[This->ngroups-1];
- + struct output *out = &group->outputs[group->noutputs-1];
- + out->nmodes--;
- +}
- +
- +static HRESULT fill_groups(struct d3dadapter9 *This)
- +{
- + DISPLAY_DEVICEW dd;
- + DEVMODEW dm;
- + POINT pt;
- + HDC hdc;
- + HRESULT hr;
- + int i, j, k;
- +
- + WCHAR wdisp[] = {'D','I','S','P','L','A','Y',0};
- +
- + ZeroMemory(&dd, sizeof(dd));
- + ZeroMemory(&dm, sizeof(dm));
- + dd.cb = sizeof(dd);
- + dm.dmSize = sizeof(dm);
- +
- + for (i = 0; EnumDisplayDevicesW(NULL, i, &dd, 0); ++i)
- + {
- + struct adapter_group *group = add_group(This);
- + if (!group)
- + {
- + ERR("Out of memory.\n");
- + return E_OUTOFMEMORY;
- + }
- +
- + hdc = CreateDCW(wdisp, dd.DeviceName, NULL, NULL);
- + if (!hdc)
- + {
- + remove_group(This);
- + WARN("Unable to create DC for display %d.\n", i);
- + goto end_group;
- + }
- +
- + hr = present_create_adapter9(This->gdi_display, hdc, &group->adapter);
- + DeleteDC(hdc);
- + if (FAILED(hr))
- + {
- + remove_group(This);
- + goto end_group;
- + }
- +
- + CopyMemory(group->devname, dd.DeviceName, sizeof(group->devname));
- + for (j = 0; EnumDisplayDevicesW(group->devname, j, &dd, 0); ++j)
- + {
- + struct output *out = add_output(This);
- + boolean orient = FALSE, monit = FALSE;
- + if (!out)
- + {
- + ERR("Out of memory.\n");
- + return E_OUTOFMEMORY;
- + }
- +
- + for (k = 0; EnumDisplaySettingsExW(dd.DeviceName, k, &dm, 0); ++k)
- + {
- + D3DDISPLAYMODEEX *mode = add_mode(This);
- + if (!out)
- + {
- + ERR("Out of memory.\n");
- + return E_OUTOFMEMORY;
- + }
- +
- + mode->Size = sizeof(D3DDISPLAYMODEEX);
- + mode->Width = dm.dmPelsWidth;
- + mode->Height = dm.dmPelsHeight;
- + mode->RefreshRate = dm.dmDisplayFrequency;
- + mode->ScanLineOrdering =
- + (dm.dmDisplayFlags & DM_INTERLACED) ?
- + D3DSCANLINEORDERING_INTERLACED :
- + D3DSCANLINEORDERING_PROGRESSIVE;
- +
- + switch (dm.dmBitsPerPel)
- + {
- + case 32: mode->Format = D3DFMT_X8R8G8B8; break;
- + case 24: mode->Format = D3DFMT_R8G8B8; break;
- + case 16: mode->Format = D3DFMT_R5G6B5; break;
- + case 8:
- + remove_mode(This);
- + goto end_mode;
- +
- + default:
- + remove_mode(This);
- + WARN("Unknown format (%u bpp) in display %d, monitor "
- + "%d, mode %d.\n", dm.dmBitsPerPel, i, j, k);
- + goto end_mode;
- + }
- +
- + if (!orient)
- + {
- + switch (dm.dmDisplayOrientation)
- + {
- + case DMDO_DEFAULT:
- + out->rotation = D3DDISPLAYROTATION_IDENTITY;
- + break;
- +
- + case DMDO_90:
- + out->rotation = D3DDISPLAYROTATION_90;
- + break;
- +
- + case DMDO_180:
- + out->rotation = D3DDISPLAYROTATION_180;
- + break;
- +
- + case DMDO_270:
- + out->rotation = D3DDISPLAYROTATION_270;
- + break;
- +
- + default:
- + remove_output(This);
- + WARN("Unknown display rotation in display %d, "
- + "monitor %d\n", i, j);
- + goto end_output;
- + }
- + orient = TRUE;
- + }
- +
- + if (!monit)
- + {
- + pt.x = dm.dmPosition.x;
- + pt.y = dm.dmPosition.y;
- + out->monitor = MonitorFromPoint(pt, 0);
- + if (!out->monitor)
- + {
- + remove_output(This);
- + WARN("Unable to get monitor handle for display %d, "
- + "monitor %d.\n", i, j);
- + goto end_output;
- + }
- + monit = TRUE;
- + }
- +
- +end_mode:
- + ZeroMemory(&dm, sizeof(dm));
- + dm.dmSize = sizeof(dm);
- + }
- +
- +end_output:
- + ZeroMemory(&dd, sizeof(dd));
- + dd.cb = sizeof(dd);
- + }
- +
- +end_group:
- + ZeroMemory(&dd, sizeof(dd));
- + dd.cb = sizeof(dd);
- + }
- +
- + return D3D_OK;
- +}
- +
- +static IDirect3D9ExVtbl d3dadapter9_vtable = {
- + (void *)d3dadapter9_QueryInterface,
- + (void *)d3dadapter9_AddRef,
- + (void *)d3dadapter9_Release,
- + (void *)d3dadapter9_RegisterSoftwareDevice,
- + (void *)d3dadapter9_GetAdapterCount,
- + (void *)d3dadapter9_GetAdapterIdentifier,
- + (void *)d3dadapter9_GetAdapterModeCount,
- + (void *)d3dadapter9_EnumAdapterModes,
- + (void *)d3dadapter9_GetAdapterDisplayMode,
- + (void *)d3dadapter9_CheckDeviceType,
- + (void *)d3dadapter9_CheckDeviceFormat,
- + (void *)d3dadapter9_CheckDeviceMultiSampleType,
- + (void *)d3dadapter9_CheckDepthStencilMatch,
- + (void *)d3dadapter9_CheckDeviceFormatConversion,
- + (void *)d3dadapter9_GetDeviceCaps,
- + (void *)d3dadapter9_GetAdapterMonitor,
- + (void *)d3dadapter9_CreateDevice,
- + (void *)d3dadapter9_GetAdapterModeCountEx,
- + (void *)d3dadapter9_EnumAdapterModesEx,
- + (void *)d3dadapter9_GetAdapterDisplayModeEx,
- + (void *)d3dadapter9_CreateDeviceEx,
- + (void *)d3dadapter9_GetAdapterLUID
- +};
- +
- +HRESULT d3dadapter9_new(Display *gdi_display, boolean ex, IDirect3D9Ex **ppOut)
- +{
- + struct d3dadapter9 *This;
- + HRESULT hr;
- + unsigned i, j, k;
- +
- + This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct d3dadapter9));
- + if (!This)
- + {
- + ERR("Out of memory.\n");
- + return E_OUTOFMEMORY;
- + }
- +
- + This->vtable = &d3dadapter9_vtable;
- + This->refs = 1;
- + This->ex = ex;
- + This->gdi_display = gdi_display;
- +
- + if (!present_has_d3dadapter(gdi_display))
- + {
- + ERR("Your display driver doesn't support native D3D9 adapters.\n");
- + d3dadapter9_Release(This);
- + return D3DERR_NOTAVAILABLE;
- + }
- +
- + if (FAILED(hr = fill_groups(This)))
- + {
- + d3dadapter9_Release(This);
- + return hr;
- + }
- +
- + /* map absolute adapter IDs with internal adapters */
- + for (i = 0; i < This->ngroups; ++i)
- + {
- + for (j = 0; j < This->groups[i].noutputs; ++j)
- + {
- + This->nadapters++;
- + }
- + }
- + if (This->nadapters == 0)
- + {
- + ERR("No available native adapters in system.\n");
- + d3dadapter9_Release(This);
- + return D3DERR_NOTAVAILABLE;
- + }
- +
- + This->map = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- + This->nadapters * sizeof(struct adapter_map));
- +
- + if (!This->map)
- + {
- + d3dadapter9_Release(This);
- + ERR("Out of memory.\n");
- + return E_OUTOFMEMORY;
- + }
- + for (i = k = 0; i < This->ngroups; ++i)
- + {
- + for (j = 0; j < This->groups[i].noutputs; ++j, ++k)
- + {
- + This->map[k].master = k-j;
- + This->map[k].group = i;
- + }
- + }
- +
- + *ppOut = (IDirect3D9Ex *)This;
- + FIXME("\033[1;32m\nNative Direct3D 9 is active."
- + "\nFor more information visit https://wiki.ixit.cz/d3d9\033[0m\n");
- + return D3D_OK;
- +}
- diff --git a/dlls/d3d9-nine/d3dadapter9.h b/dlls/d3d9-nine/d3dadapter9.h
- new file mode 100644
- index 0000000000..ad54f67285
- --- /dev/null
- +++ b/dlls/d3d9-nine/d3dadapter9.h
- @@ -0,0 +1,32 @@
- +/*
- + * D3DAdapter9 interface
- + *
- + * Copyright 2015 Patrick Rudolph
- + *
- + * 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
- + */
- +
- +#ifndef __WINE_D3D9ADAPTER_H
- +#define __WINE_D3D9ADAPTER_H
- +
- +#include <X11/Xlib.h>
- +
- +void d3dadapter9_init(HINSTANCE hinst);
- +
- +void d3dadapter9_destroy(HINSTANCE hinst);
- +
- +HRESULT d3dadapter9_new(Display *gdi_display, boolean ex, IDirect3D9Ex **ppOut);
- +
- +#endif /* __WINE_D3D9ADAPTER_H */
- diff --git a/dlls/d3d9-nine/device_wrap.c b/dlls/d3d9-nine/device_wrap.c
- new file mode 100644
- index 0000000000..e662c6f89a
- --- /dev/null
- +++ b/dlls/d3d9-nine/device_wrap.c
- @@ -0,0 +1,500 @@
- +/*
- + * Copyright 2016 Axel Davy
- + *
- + * 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
- + */
- +
- +#include "config.h"
- +#include "wine/port.h"
- +#include "wine/debug.h"
- +
- +#include <d3d9.h>
- +
- +#include "device_wrap.h"
- +
- +struct IDirect3DDevice9Ex_Minor1
- +{
- + IDirect3DDevice9ExVtbl *lpVtbl;
- + IDirect3DDevice9ExVtbl *lpVtbl_internal;
- +};
- +
- +struct IDirect3DSwapChain9Ex_Minor1
- +{
- + IDirect3DSwapChain9ExVtbl *lpVtbl;
- + IDirect3DSwapChain9ExVtbl *lpVtbl_internal;
- +};
- +
- +typedef struct IDirect3DDevice9Ex_Minor1 IDirect3DDevice9Ex_Minor1;
- +typedef struct IDirect3DSwapChain9Ex_Minor1 IDirect3DSwapChain9Ex_Minor1;
- +
- +#define SWAPCHAIN_WRAP0(ret, func) \
- + ret WINAPI WineNineSwapChain9_ ## func(IDirect3DSwapChain9Ex *This) \
- + { \
- + return ((IDirect3DSwapChain9Ex_Minor1 *)This)->lpVtbl_internal->func(This); \
- + }
- +
- +#define SWAPCHAIN_WRAP1(ret, func, type1) \
- + ret WINAPI WineNineSwapChain9_ ## func(IDirect3DSwapChain9Ex *This, type1 arg1) \
- + { \
- + return ((IDirect3DSwapChain9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1); \
- + }
- +
- +#define SWAPCHAIN_WRAP2(ret, func, type1, type2) \
- + ret WINAPI WineNineSwapChain9_ ## func(IDirect3DSwapChain9Ex *This, type1 arg1, type2 arg2) \
- + { \
- + return ((IDirect3DSwapChain9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2); \
- + }
- +
- +#define SWAPCHAIN_WRAP3(ret, func, type1, type2, type3) \
- + ret WINAPI WineNineSwapChain9_ ## func(IDirect3DSwapChain9Ex *This, type1 arg1, type2 arg2, type3 arg3) \
- + { \
- + return ((IDirect3DSwapChain9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2, arg3); \
- + }
- +
- +#define SWAPCHAIN_H_WRAP5(ret, func, type1, type2, type3, type4, type5) \
- + ret WINAPI DECLSPEC_HOTPATCH WineNineSwapChain9_ ## func(IDirect3DSwapChain9Ex *This, type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
- + { \
- + return ((IDirect3DSwapChain9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2, arg3, arg4, arg5); \
- + }
- +
- +#define DEVICE_WRAP0(ret, func) \
- + ret WINAPI WineNineDevice9_ ## func(IDirect3DDevice9Ex *This) \
- + { \
- + return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This); \
- + }
- +
- +#define DEVICE_WRAP1(ret, func, type1) \
- + ret WINAPI WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1) \
- + { \
- + return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1); \
- + }
- +
- +#define DEVICE_WRAP2(ret, func, type1, type2) \
- + ret WINAPI WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1, type2 arg2) \
- + { \
- + return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2); \
- + }
- +
- +#define DEVICE_WRAP3(ret, func, type1, type2, type3) \
- + ret WINAPI WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1, type2 arg2, type3 arg3) \
- + { \
- + return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2, arg3); \
- + }
- +
- +#define DEVICE_WRAP4(ret, func, type1, type2, type3, type4) \
- + ret WINAPI WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
- + { \
- + return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2, arg3, arg4); \
- + }
- +
- +#define DEVICE_WRAP5(ret, func, type1, type2, type3, type4, type5) \
- + ret WINAPI WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
- + { \
- + return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2, arg3, arg4, arg5); \
- + }
- +
- +#define DEVICE_WRAP6(ret, func, type1, type2, type3, type4, type5, type6) \
- + ret WINAPI WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \
- + { \
- + return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2, arg3, arg4, arg5, arg6); \
- + }
- +
- +#define DEVICE_WRAP7(ret, func, type1, type2, type3, type4, type5, type6, type7) \
- + ret WINAPI WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6, type7 arg7) \
- + { \
- + return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \
- + }
- +
- +#define DEVICE_WRAP8(ret, func, type1, type2, type3, type4, type5, type6, type7, type8) \
- + ret WINAPI WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6, type7 arg7, type8 arg8) \
- + { \
- + return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \
- + }
- +
- +#define DEVICE_WRAP9(ret, func, type1, type2, type3, type4, type5, type6, type7, type8, type9) \
- + ret WINAPI WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6, type7 arg7, type8 arg8, type9 arg9) \
- + { \
- + return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \
- + }
- +
- +#define DEVICE_H_WRAP0(ret, func) \
- + ret WINAPI DECLSPEC_HOTPATCH WineNineDevice9_ ## func(IDirect3DDevice9Ex *This) \
- + { \
- + return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This); \
- + }
- +
- +#define DEVICE_H_WRAP1(ret, func, type1) \
- + ret WINAPI DECLSPEC_HOTPATCH WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1) \
- + { \
- + return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1); \
- + }
- +
- +#define DEVICE_H_WRAP2(ret, func, type1, type2) \
- + ret WINAPI DECLSPEC_HOTPATCH WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1, type2 arg2) \
- + { \
- + return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2); \
- + }
- +
- +#define DEVICE_H_WRAP3(ret, func, type1, type2, type3) \
- + ret WINAPI DECLSPEC_HOTPATCH WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1, type2 arg2, type3 arg3) \
- + { \
- + return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2, arg3); \
- + }
- +
- +#define DEVICE_H_WRAP4(ret, func, type1, type2, type3, type4) \
- + ret WINAPI DECLSPEC_HOTPATCH WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
- + { \
- + return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2, arg3, arg4); \
- + }
- +
- +#define DEVICE_H_WRAP5(ret, func, type1, type2, type3, type4, type5) \
- + ret WINAPI DECLSPEC_HOTPATCH WineNineDevice9_ ## func(IDirect3DDevice9Ex *This, type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
- + { \
- + return ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->func(This, arg1, arg2, arg3, arg4, arg5); \
- + }
- +
- +SWAPCHAIN_WRAP2(HRESULT, QueryInterface, REFIID, void **)
- +SWAPCHAIN_WRAP0(ULONG, AddRef)
- +SWAPCHAIN_WRAP0(ULONG, Release)
- +SWAPCHAIN_H_WRAP5(HRESULT, Present, const RECT *, const RECT *, HWND, const RGNDATA *, DWORD)
- +SWAPCHAIN_WRAP1(HRESULT, GetFrontBufferData, IDirect3DSurface9 *)
- +SWAPCHAIN_WRAP3(HRESULT, GetBackBuffer, UINT, D3DBACKBUFFER_TYPE, IDirect3DSurface9 **)
- +SWAPCHAIN_WRAP1(HRESULT, GetRasterStatus, D3DRASTER_STATUS *)
- +SWAPCHAIN_WRAP1(HRESULT, GetDisplayMode, D3DDISPLAYMODE *)
- +SWAPCHAIN_WRAP1(HRESULT, GetDevice, IDirect3DDevice9 **)
- +SWAPCHAIN_WRAP1(HRESULT, GetPresentParameters, D3DPRESENT_PARAMETERS *)
- +SWAPCHAIN_WRAP1(HRESULT, GetLastPresentCount, UINT *)
- +SWAPCHAIN_WRAP1(HRESULT, GetPresentStats, D3DPRESENTSTATS *)
- +SWAPCHAIN_WRAP2(HRESULT, GetDisplayModeEx, D3DDISPLAYMODEEX *, D3DDISPLAYROTATION *)
- +
- +DEVICE_WRAP2(HRESULT, QueryInterface, REFIID, void **)
- +DEVICE_WRAP0(ULONG, AddRef)
- +DEVICE_H_WRAP0(ULONG, Release)
- +DEVICE_WRAP0(HRESULT, TestCooperativeLevel)
- +DEVICE_WRAP0(UINT, GetAvailableTextureMem)
- +DEVICE_WRAP0(HRESULT, EvictManagedResources)
- +DEVICE_WRAP1(HRESULT, GetDirect3D, IDirect3D9 **)
- +DEVICE_WRAP1(HRESULT, GetDeviceCaps, D3DCAPS9 *)
- +DEVICE_WRAP2(HRESULT, GetDisplayMode, UINT, D3DDISPLAYMODE*)
- +DEVICE_WRAP1(HRESULT, GetCreationParameters, D3DDEVICE_CREATION_PARAMETERS *)
- +DEVICE_WRAP3(HRESULT, SetCursorProperties, UINT, UINT, IDirect3DSurface9 *)
- +DEVICE_WRAP3(void, SetCursorPosition, int, int, DWORD)
- +DEVICE_WRAP1(BOOL, ShowCursor, BOOL)
- +/*DEVICE_H_WRAP2(HRESULT, CreateAdditionalSwapChain, D3DPRESENT_PARAMETERS *, IDirect3DSwapChain9 **)*/
- +/*DEVICE_H_WRAP2(HRESULT, GetSwapChain, UINT, IDirect3DSwapChain9 **)*/
- +DEVICE_WRAP0(UINT, GetNumberOfSwapChains)
- +DEVICE_H_WRAP1(HRESULT, Reset, D3DPRESENT_PARAMETERS *)
- +DEVICE_H_WRAP4(HRESULT, Present, const RECT *, const RECT *, HWND, const RGNDATA *)
- +DEVICE_WRAP4(HRESULT, GetBackBuffer, UINT, UINT, D3DBACKBUFFER_TYPE, IDirect3DSurface9 **)
- +DEVICE_WRAP2(HRESULT, GetRasterStatus, UINT, D3DRASTER_STATUS *)
- +DEVICE_WRAP1(HRESULT, SetDialogBoxMode, BOOL)
- +DEVICE_H_WRAP3(void, SetGammaRamp, UINT, DWORD, const D3DGAMMARAMP *)
- +DEVICE_WRAP2(void, GetGammaRamp, UINT, D3DGAMMARAMP *)
- +DEVICE_WRAP8(HRESULT, CreateTexture, UINT, UINT, UINT, DWORD, D3DFORMAT, D3DPOOL, IDirect3DTexture9 **, HANDLE *)
- +DEVICE_WRAP9(HRESULT, CreateVolumeTexture, UINT, UINT, UINT, UINT, DWORD, D3DFORMAT, D3DPOOL, IDirect3DVolumeTexture9 **, HANDLE *)
- +DEVICE_WRAP7(HRESULT, CreateCubeTexture, UINT, UINT, DWORD, D3DFORMAT, D3DPOOL, IDirect3DCubeTexture9 **, HANDLE *)
- +DEVICE_WRAP6(HRESULT, CreateVertexBuffer, UINT, DWORD, DWORD, D3DPOOL, IDirect3DVertexBuffer9 **, HANDLE *)
- +DEVICE_WRAP6(HRESULT, CreateIndexBuffer, UINT, DWORD, D3DFORMAT, D3DPOOL, IDirect3DIndexBuffer9 **, HANDLE *)
- +DEVICE_WRAP8(HRESULT, CreateRenderTarget, UINT, UINT, D3DFORMAT, D3DMULTISAMPLE_TYPE, DWORD, BOOL, IDirect3DSurface9 **, HANDLE *)
- +DEVICE_WRAP8(HRESULT, CreateDepthStencilSurface, UINT, UINT, D3DFORMAT, D3DMULTISAMPLE_TYPE, DWORD, BOOL, IDirect3DSurface9 **, HANDLE *)
- +DEVICE_WRAP4(HRESULT, UpdateSurface, IDirect3DSurface9 *, const RECT *, IDirect3DSurface9 *, const POINT *)
- +DEVICE_WRAP2(HRESULT, UpdateTexture, IDirect3DBaseTexture9 *, IDirect3DBaseTexture9 *)
- +DEVICE_WRAP2(HRESULT, GetRenderTargetData, IDirect3DSurface9 *, IDirect3DSurface9 *)
- +DEVICE_WRAP2(HRESULT, GetFrontBufferData, UINT, IDirect3DSurface9 *)
- +DEVICE_WRAP5(HRESULT, StretchRect, IDirect3DSurface9 *, const RECT *, IDirect3DSurface9 *, const RECT *, D3DTEXTUREFILTERTYPE)
- +DEVICE_WRAP3(HRESULT, ColorFill, IDirect3DSurface9 *, const RECT *, D3DCOLOR)
- +DEVICE_WRAP6(HRESULT, CreateOffscreenPlainSurface, UINT, UINT, D3DFORMAT, D3DPOOL, IDirect3DSurface9 **, HANDLE *)
- +DEVICE_WRAP2(HRESULT, SetRenderTarget, DWORD, IDirect3DSurface9 *)
- +DEVICE_WRAP2(HRESULT, GetRenderTarget, DWORD, IDirect3DSurface9 **)
- +DEVICE_WRAP1(HRESULT, SetDepthStencilSurface, IDirect3DSurface9 *)
- +DEVICE_WRAP1(HRESULT, GetDepthStencilSurface, IDirect3DSurface9 **)
- +DEVICE_WRAP0(HRESULT, BeginScene)
- +DEVICE_H_WRAP0(HRESULT, EndScene)
- +DEVICE_WRAP6(HRESULT, Clear, DWORD, const D3DRECT *, DWORD, D3DCOLOR, float, DWORD)
- +DEVICE_WRAP2(HRESULT, SetTransform, D3DTRANSFORMSTATETYPE, const D3DMATRIX *)
- +DEVICE_WRAP2(HRESULT, GetTransform, D3DTRANSFORMSTATETYPE, D3DMATRIX *)
- +DEVICE_WRAP2(HRESULT, MultiplyTransform, D3DTRANSFORMSTATETYPE, const D3DMATRIX *)
- +DEVICE_WRAP1(HRESULT, SetViewport, const D3DVIEWPORT9 *)
- +DEVICE_WRAP1(HRESULT, GetViewport, D3DVIEWPORT9 *)
- +DEVICE_WRAP1(HRESULT, SetMaterial, const D3DMATERIAL9 *)
- +DEVICE_WRAP1(HRESULT, GetMaterial, D3DMATERIAL9 *)
- +DEVICE_WRAP2(HRESULT, SetLight, DWORD, const D3DLIGHT9 *)
- +DEVICE_WRAP2(HRESULT, GetLight, DWORD, D3DLIGHT9 *)
- +DEVICE_WRAP2(HRESULT, LightEnable, DWORD, BOOL)
- +DEVICE_WRAP2(HRESULT, GetLightEnable, DWORD, BOOL *)
- +DEVICE_WRAP2(HRESULT, SetClipPlane, DWORD, const float *)
- +DEVICE_WRAP2(HRESULT, GetClipPlane, DWORD, float *)
- +DEVICE_H_WRAP2(HRESULT, SetRenderState, D3DRENDERSTATETYPE, DWORD)
- +DEVICE_WRAP2(HRESULT, GetRenderState, D3DRENDERSTATETYPE, DWORD *)
- +DEVICE_WRAP2(HRESULT, CreateStateBlock, D3DSTATEBLOCKTYPE, IDirect3DStateBlock9 **)
- +DEVICE_WRAP0(HRESULT, BeginStateBlock)
- +DEVICE_WRAP1(HRESULT, EndStateBlock, IDirect3DStateBlock9 **)
- +DEVICE_WRAP1(HRESULT, SetClipStatus, const D3DCLIPSTATUS9 *)
- +DEVICE_WRAP1(HRESULT, GetClipStatus, D3DCLIPSTATUS9 *)
- +DEVICE_WRAP2(HRESULT, GetTexture, DWORD, IDirect3DBaseTexture9 **)
- +DEVICE_WRAP2(HRESULT, SetTexture, DWORD, IDirect3DBaseTexture9 *)
- +DEVICE_WRAP3(HRESULT, GetTextureStageState, DWORD, D3DTEXTURESTAGESTATETYPE, DWORD *)
- +DEVICE_WRAP3(HRESULT, SetTextureStageState, DWORD, D3DTEXTURESTAGESTATETYPE, DWORD)
- +DEVICE_WRAP3(HRESULT, GetSamplerState, DWORD, D3DSAMPLERSTATETYPE, DWORD *)
- +DEVICE_H_WRAP3(HRESULT, SetSamplerState, DWORD, D3DSAMPLERSTATETYPE, DWORD)
- +DEVICE_WRAP1(HRESULT, ValidateDevice, DWORD *)
- +DEVICE_WRAP2(HRESULT, SetPaletteEntries, UINT, const PALETTEENTRY *)
- +DEVICE_WRAP2(HRESULT, GetPaletteEntries, UINT, PALETTEENTRY *)
- +DEVICE_WRAP1(HRESULT, SetCurrentTexturePalette, UINT)
- +DEVICE_WRAP1(HRESULT, GetCurrentTexturePalette, UINT *)
- +DEVICE_WRAP1(HRESULT, SetScissorRect, const RECT *)
- +DEVICE_WRAP1(HRESULT, GetScissorRect, RECT *)
- +DEVICE_WRAP1(HRESULT, SetSoftwareVertexProcessing, BOOL)
- +DEVICE_WRAP0(BOOL, GetSoftwareVertexProcessing)
- +DEVICE_WRAP1(HRESULT, SetNPatchMode, float)
- +DEVICE_WRAP0(float, GetNPatchMode)
- +DEVICE_WRAP3(HRESULT, DrawPrimitive, D3DPRIMITIVETYPE, UINT, UINT)
- +DEVICE_WRAP6(HRESULT, DrawIndexedPrimitive, D3DPRIMITIVETYPE, INT, UINT, UINT, UINT, UINT)
- +DEVICE_WRAP4(HRESULT, DrawPrimitiveUP, D3DPRIMITIVETYPE, UINT, const void *, UINT)
- +DEVICE_WRAP8(HRESULT, DrawIndexedPrimitiveUP, D3DPRIMITIVETYPE, UINT, UINT, UINT, const void *, D3DFORMAT, const void *, UINT)
- +DEVICE_WRAP6(HRESULT, ProcessVertices, UINT, UINT, UINT, IDirect3DVertexBuffer9 *, IDirect3DVertexDeclaration9 *, DWORD)
- +DEVICE_WRAP2(HRESULT, CreateVertexDeclaration, const D3DVERTEXELEMENT9 *, IDirect3DVertexDeclaration9 **)
- +DEVICE_WRAP1(HRESULT, SetVertexDeclaration, IDirect3DVertexDeclaration9 *)
- +DEVICE_WRAP1(HRESULT, GetVertexDeclaration, IDirect3DVertexDeclaration9 **)
- +DEVICE_WRAP1(HRESULT, SetFVF, DWORD)
- +DEVICE_WRAP1(HRESULT, GetFVF, DWORD *)
- +DEVICE_WRAP2(HRESULT, CreateVertexShader, const DWORD *, IDirect3DVertexShader9 **)
- +DEVICE_WRAP1(HRESULT, SetVertexShader, IDirect3DVertexShader9 *)
- +DEVICE_WRAP1(HRESULT, GetVertexShader, IDirect3DVertexShader9 **)
- +DEVICE_WRAP3(HRESULT, SetVertexShaderConstantF, UINT, const float *, UINT)
- +DEVICE_WRAP3(HRESULT, GetVertexShaderConstantF, UINT, float *, UINT)
- +DEVICE_WRAP3(HRESULT, SetVertexShaderConstantI, UINT, const int *, UINT)
- +DEVICE_WRAP3(HRESULT, GetVertexShaderConstantI, UINT, int *, UINT)
- +DEVICE_WRAP3(HRESULT, SetVertexShaderConstantB, UINT, const BOOL *, UINT)
- +DEVICE_WRAP3(HRESULT, GetVertexShaderConstantB, UINT, BOOL *, UINT)
- +DEVICE_WRAP4(HRESULT, SetStreamSource, UINT, IDirect3DVertexBuffer9 *, UINT, UINT)
- +DEVICE_WRAP4(HRESULT, GetStreamSource, UINT, IDirect3DVertexBuffer9 **, UINT *, UINT *)
- +DEVICE_WRAP2(HRESULT, SetStreamSourceFreq, UINT, UINT)
- +DEVICE_WRAP2(HRESULT, GetStreamSourceFreq, UINT, UINT *)
- +DEVICE_WRAP1(HRESULT, SetIndices, IDirect3DIndexBuffer9 *)
- +DEVICE_WRAP1(HRESULT, GetIndices, IDirect3DIndexBuffer9 **)
- +DEVICE_WRAP2(HRESULT, CreatePixelShader, const DWORD *, IDirect3DPixelShader9 **)
- +DEVICE_WRAP1(HRESULT, SetPixelShader, IDirect3DPixelShader9 *)
- +DEVICE_WRAP1(HRESULT, GetPixelShader, IDirect3DPixelShader9 **)
- +DEVICE_WRAP3(HRESULT, SetPixelShaderConstantF, UINT, const float *, UINT)
- +DEVICE_WRAP3(HRESULT, GetPixelShaderConstantF, UINT, float *, UINT)
- +DEVICE_WRAP3(HRESULT, SetPixelShaderConstantI, UINT, const int *, UINT)
- +DEVICE_WRAP3(HRESULT, GetPixelShaderConstantI, UINT, int *, UINT)
- +DEVICE_WRAP3(HRESULT, SetPixelShaderConstantB, UINT, const BOOL *, UINT)
- +DEVICE_WRAP3(HRESULT, GetPixelShaderConstantB, UINT, BOOL *, UINT)
- +DEVICE_WRAP3(HRESULT, DrawRectPatch, UINT, const float *, const D3DRECTPATCH_INFO *)
- +DEVICE_WRAP3(HRESULT, DrawTriPatch, UINT, const float *, const D3DTRIPATCH_INFO *)
- +DEVICE_WRAP1(HRESULT, DeletePatch, UINT)
- +DEVICE_WRAP2(HRESULT, CreateQuery, D3DQUERYTYPE, IDirect3DQuery9 **)
- +DEVICE_WRAP4(HRESULT, SetConvolutionMonoKernel, UINT, UINT, float *, float *)
- +DEVICE_WRAP8(HRESULT, ComposeRects, IDirect3DSurface9 *, IDirect3DSurface9 *, IDirect3DVertexBuffer9 *, UINT, IDirect3DVertexBuffer9 *, D3DCOMPOSERECTSOP, int, int)
- +DEVICE_H_WRAP5(HRESULT, PresentEx, const RECT *, const RECT *, HWND, const RGNDATA *, DWORD)
- +DEVICE_WRAP1(HRESULT, GetGPUThreadPriority, INT *)
- +DEVICE_WRAP1(HRESULT, SetGPUThreadPriority, INT)
- +DEVICE_WRAP1(HRESULT, WaitForVBlank, UINT)
- +DEVICE_WRAP2(HRESULT, CheckResourceResidency, IDirect3DResource9 **, UINT32)
- +DEVICE_WRAP1(HRESULT, SetMaximumFrameLatency, UINT)
- +DEVICE_WRAP1(HRESULT, GetMaximumFrameLatency, UINT *)
- +DEVICE_WRAP1(HRESULT, CheckDeviceState, HWND)
- +DEVICE_WRAP9(HRESULT, CreateRenderTargetEx, UINT, UINT, D3DFORMAT, D3DMULTISAMPLE_TYPE, DWORD, BOOL, IDirect3DSurface9 **, HANDLE *, DWORD)
- +DEVICE_WRAP7(HRESULT, CreateOffscreenPlainSurfaceEx, UINT, UINT, D3DFORMAT, D3DPOOL, IDirect3DSurface9 **, HANDLE *, DWORD)
- +DEVICE_WRAP9(HRESULT, CreateDepthStencilSurfaceEx, UINT, UINT, D3DFORMAT, D3DMULTISAMPLE_TYPE, DWORD, BOOL, IDirect3DSurface9 **, HANDLE *, DWORD)
- +DEVICE_H_WRAP2(HRESULT, ResetEx, D3DPRESENT_PARAMETERS *, D3DDISPLAYMODEEX *)
- +DEVICE_WRAP3(HRESULT, GetDisplayModeEx, UINT, D3DDISPLAYMODEEX *, D3DDISPLAYROTATION *)
- +
- +IDirect3DSwapChain9ExVtbl WineNineSwapChain9Ex_vtable = {
- + WineNineSwapChain9_QueryInterface,
- + WineNineSwapChain9_AddRef,
- + WineNineSwapChain9_Release,
- + WineNineSwapChain9_Present,
- + WineNineSwapChain9_GetFrontBufferData,
- + WineNineSwapChain9_GetBackBuffer,
- + WineNineSwapChain9_GetRasterStatus,
- + WineNineSwapChain9_GetDisplayMode,
- + WineNineSwapChain9_GetDevice,
- + WineNineSwapChain9_GetPresentParameters,
- + WineNineSwapChain9_GetLastPresentCount,
- + WineNineSwapChain9_GetPresentStats,
- + WineNineSwapChain9_GetDisplayModeEx
- +};
- +
- +HRESULT WINAPI DECLSPEC_HOTPATCH WineNineDevice9_CreateAdditionalSwapChain(IDirect3DDevice9Ex *This, D3DPRESENT_PARAMETERS *pPresentationParameters, IDirect3DSwapChain9 **pSwapChain)
- +{
- + HRESULT hr;
- +
- + hr = ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->CreateAdditionalSwapChain(This, pPresentationParameters, pSwapChain);
- + if (FAILED(hr))
- + return hr;
- +
- + (*pSwapChain)->lpVtbl = (IDirect3DSwapChain9Vtbl *)&WineNineSwapChain9Ex_vtable;
- +
- + return hr;
- +}
- +
- +HRESULT WINAPI DECLSPEC_HOTPATCH WineNineDevice9_GetSwapChain(IDirect3DDevice9Ex *This, UINT iSwapChain, IDirect3DSwapChain9 **pSwapChain)
- +{
- + HRESULT hr;
- +
- + hr = ((IDirect3DDevice9Ex_Minor1 *)This)->lpVtbl_internal->GetSwapChain(This, iSwapChain, pSwapChain);
- + if (FAILED(hr))
- + return hr;
- +
- + (*pSwapChain)->lpVtbl = (IDirect3DSwapChain9Vtbl *)&WineNineSwapChain9Ex_vtable;
- +
- + return hr;
- +}
- +
- +
- +IDirect3DDevice9ExVtbl WineNineDevice9_vtable = {
- + WineNineDevice9_QueryInterface,
- + WineNineDevice9_AddRef,
- + WineNineDevice9_Release,
- + WineNineDevice9_TestCooperativeLevel,
- + WineNineDevice9_GetAvailableTextureMem,
- + WineNineDevice9_EvictManagedResources,
- + WineNineDevice9_GetDirect3D,
- + WineNineDevice9_GetDeviceCaps,
- + WineNineDevice9_GetDisplayMode,
- + WineNineDevice9_GetCreationParameters,
- + WineNineDevice9_SetCursorProperties,
- + WineNineDevice9_SetCursorPosition,
- + WineNineDevice9_ShowCursor,
- + WineNineDevice9_CreateAdditionalSwapChain,
- + WineNineDevice9_GetSwapChain,
- + WineNineDevice9_GetNumberOfSwapChains,
- + WineNineDevice9_Reset,
- + WineNineDevice9_Present,
- + WineNineDevice9_GetBackBuffer,
- + WineNineDevice9_GetRasterStatus,
- + WineNineDevice9_SetDialogBoxMode,
- + WineNineDevice9_SetGammaRamp,
- + WineNineDevice9_GetGammaRamp,
- + WineNineDevice9_CreateTexture,
- + WineNineDevice9_CreateVolumeTexture,
- + WineNineDevice9_CreateCubeTexture,
- + WineNineDevice9_CreateVertexBuffer,
- + WineNineDevice9_CreateIndexBuffer,
- + WineNineDevice9_CreateRenderTarget,
- + WineNineDevice9_CreateDepthStencilSurface,
- + WineNineDevice9_UpdateSurface,
- + WineNineDevice9_UpdateTexture,
- + WineNineDevice9_GetRenderTargetData,
- + WineNineDevice9_GetFrontBufferData,
- + WineNineDevice9_StretchRect,
- + WineNineDevice9_ColorFill,
- + WineNineDevice9_CreateOffscreenPlainSurface,
- + WineNineDevice9_SetRenderTarget,
- + WineNineDevice9_GetRenderTarget,
- + WineNineDevice9_SetDepthStencilSurface,
- + WineNineDevice9_GetDepthStencilSurface,
- + WineNineDevice9_BeginScene,
- + WineNineDevice9_EndScene,
- + WineNineDevice9_Clear,
- + WineNineDevice9_SetTransform,
- + WineNineDevice9_GetTransform,
- + WineNineDevice9_MultiplyTransform,
- + WineNineDevice9_SetViewport,
- + WineNineDevice9_GetViewport,
- + WineNineDevice9_SetMaterial,
- + WineNineDevice9_GetMaterial,
- + WineNineDevice9_SetLight,
- + WineNineDevice9_GetLight,
- + WineNineDevice9_LightEnable,
- + WineNineDevice9_GetLightEnable,
- + WineNineDevice9_SetClipPlane,
- + WineNineDevice9_GetClipPlane,
- + WineNineDevice9_SetRenderState,
- + WineNineDevice9_GetRenderState,
- + WineNineDevice9_CreateStateBlock,
- + WineNineDevice9_BeginStateBlock,
- + WineNineDevice9_EndStateBlock,
- + WineNineDevice9_SetClipStatus,
- + WineNineDevice9_GetClipStatus,
- + WineNineDevice9_GetTexture,
- + WineNineDevice9_SetTexture,
- + WineNineDevice9_GetTextureStageState,
- + WineNineDevice9_SetTextureStageState,
- + WineNineDevice9_GetSamplerState,
- + WineNineDevice9_SetSamplerState,
- + WineNineDevice9_ValidateDevice,
- + WineNineDevice9_SetPaletteEntries,
- + WineNineDevice9_GetPaletteEntries,
- + WineNineDevice9_SetCurrentTexturePalette,
- + WineNineDevice9_GetCurrentTexturePalette,
- + WineNineDevice9_SetScissorRect,
- + WineNineDevice9_GetScissorRect,
- + WineNineDevice9_SetSoftwareVertexProcessing,
- + WineNineDevice9_GetSoftwareVertexProcessing,
- + WineNineDevice9_SetNPatchMode,
- + WineNineDevice9_GetNPatchMode,
- + WineNineDevice9_DrawPrimitive,
- + WineNineDevice9_DrawIndexedPrimitive,
- + WineNineDevice9_DrawPrimitiveUP,
- + WineNineDevice9_DrawIndexedPrimitiveUP,
- + WineNineDevice9_ProcessVertices,
- + WineNineDevice9_CreateVertexDeclaration,
- + WineNineDevice9_SetVertexDeclaration,
- + WineNineDevice9_GetVertexDeclaration,
- + WineNineDevice9_SetFVF,
- + WineNineDevice9_GetFVF,
- + WineNineDevice9_CreateVertexShader,
- + WineNineDevice9_SetVertexShader,
- + WineNineDevice9_GetVertexShader,
- + WineNineDevice9_SetVertexShaderConstantF,
- + WineNineDevice9_GetVertexShaderConstantF,
- + WineNineDevice9_SetVertexShaderConstantI,
- + WineNineDevice9_GetVertexShaderConstantI,
- + WineNineDevice9_SetVertexShaderConstantB,
- + WineNineDevice9_GetVertexShaderConstantB,
- + WineNineDevice9_SetStreamSource,
- + WineNineDevice9_GetStreamSource,
- + WineNineDevice9_SetStreamSourceFreq,
- + WineNineDevice9_GetStreamSourceFreq,
- + WineNineDevice9_SetIndices,
- + WineNineDevice9_GetIndices,
- + WineNineDevice9_CreatePixelShader,
- + WineNineDevice9_SetPixelShader,
- + WineNineDevice9_GetPixelShader,
- + WineNineDevice9_SetPixelShaderConstantF,
- + WineNineDevice9_GetPixelShaderConstantF,
- + WineNineDevice9_SetPixelShaderConstantI,
- + WineNineDevice9_GetPixelShaderConstantI,
- + WineNineDevice9_SetPixelShaderConstantB,
- + WineNineDevice9_GetPixelShaderConstantB,
- + WineNineDevice9_DrawRectPatch,
- + WineNineDevice9_DrawTriPatch,
- + WineNineDevice9_DeletePatch,
- + WineNineDevice9_CreateQuery,
- + WineNineDevice9_SetConvolutionMonoKernel,
- + WineNineDevice9_ComposeRects,
- + WineNineDevice9_PresentEx,
- + WineNineDevice9_GetGPUThreadPriority,
- + WineNineDevice9_SetGPUThreadPriority,
- + WineNineDevice9_WaitForVBlank,
- + WineNineDevice9_CheckResourceResidency,
- + WineNineDevice9_SetMaximumFrameLatency,
- + WineNineDevice9_GetMaximumFrameLatency,
- + WineNineDevice9_CheckDeviceState,
- + WineNineDevice9_CreateRenderTargetEx,
- + WineNineDevice9_CreateOffscreenPlainSurfaceEx,
- + WineNineDevice9_CreateDepthStencilSurfaceEx,
- + WineNineDevice9_ResetEx,
- + WineNineDevice9_GetDisplayModeEx
- +};
- +
- +IDirect3DDevice9ExVtbl *get_device_vtable()
- +{
- + return &WineNineDevice9_vtable;
- +}
- diff --git a/dlls/d3d9-nine/device_wrap.h b/dlls/d3d9-nine/device_wrap.h
- new file mode 100644
- index 0000000000..8f5e7206a0
- --- /dev/null
- +++ b/dlls/d3d9-nine/device_wrap.h
- @@ -0,0 +1,26 @@
- +/*
- + * Copyright 2016 Axel Davy
- + *
- + * 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
- + */
- +
- +#ifndef __NINE_DEVICE_WRAP_H
- +#define __NINE_DEVICE_WRAP_H
- +
- +#include <d3dadapter/d3dadapter9.h>
- +
- +IDirect3DDevice9ExVtbl *get_device_vtable(void);
- +
- +#endif /* __NINE_DEVICE_WRAP_H */
- diff --git a/dlls/d3d9-nine/dri3.c b/dlls/d3d9-nine/dri3.c
- new file mode 100644
- index 0000000000..3946e7f8bf
- --- /dev/null
- +++ b/dlls/d3d9-nine/dri3.c
- @@ -0,0 +1,1426 @@
- +/*
- + * Wine DRI3 interface
- + *
- + * Copyright 2014-2015 Axel Davy
- + * Copyright 2015 Patrick Rudolph
- + *
- + * 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
- + */
- +
- +
- +#include "config.h"
- +#include "wine/debug.h"
- +
- +WINE_DEFAULT_DEBUG_CHANNEL(d3d9nine);
- +
- +#include "dri3.h"
- +
- +#include <fcntl.h>
- +#include <unistd.h>
- +#include <pthread.h>
- +
- +#include <X11/Xlib-xcb.h>
- +#include <xcb/dri3.h>
- +#include <xcb/present.h>
- +
- +#include "winbase.h"
- +
- +#ifdef D3D9NINE_DRI2
- +#include <sys/ioctl.h>
- +
- +#define BOOL X_BOOL
- +#define BYTE X_BYTE
- +#define INT8 X_INT8
- +#define INT16 X_INT16
- +#define INT32 X_INT32
- +#define INT64 X_INT64
- +#include <X11/Xmd.h>
- +#undef BOOL
- +#undef BYTE
- +#undef INT8
- +#undef INT16
- +#undef INT32
- +#undef INT64
- +#undef LONG64
- +
- +#include <X11/Xlibint.h>
- +#include <X11/extensions/dri2tokens.h>
- +#include <X11/extensions/dri2proto.h>
- +#include <X11/extensions/extutil.h>
- +#define GL_GLEXT_PROTOTYPES 1
- +#define EGL_EGLEXT_PROTOTYPES 1
- +#define GL_GLEXT_LEGACY 1
- +
- +/* workaround for broken ABI on x86_64 due to windef.h */
- +#undef APIENTRY
- +#undef APIENTRYP
- +#include <GL/gl.h>
- +
- +/* workaround gl header bug */
- +#define glBlendColor glBlendColorLEV
- +#define glBlendEquation glBlendEquationLEV
- +#include <GL/glext.h>
- +#include <EGL/egl.h>
- +#include <EGL/eglext.h>
- +#include <libdrm/drm_fourcc.h>
- +#include <libdrm/drm.h>
- +
- +static EGLDisplay display = NULL;
- +static int display_ref = 0;
- +
- +struct DRI2priv {
- + Display *dpy;
- + EGLDisplay display;
- + EGLContext context;
- + PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES_func;
- + PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR_func;
- + PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR_func;
- +};
- +#endif
- +
- +struct PRESENTPriv {
- + xcb_connection_t *xcb_connection;
- + xcb_connection_t *xcb_connection_bis; /* to avoid libxcb thread bugs, use a different connection to present pixmaps */
- + XID window;
- + uint64_t last_msc;
- + uint64_t last_target;
- + uint32_t last_serial_given;
- + xcb_special_event_t *special_event;
- + PRESENTPixmapPriv *first_present_priv;
- + int pixmap_present_pending;
- + BOOL idle_notify_since_last_check;
- + BOOL notify_with_serial_pending;
- + CRITICAL_SECTION mutex_present; /* protect readind/writing present_priv things */
- + CRITICAL_SECTION mutex_xcb_wait;
- + BOOL xcb_wait;
- +};
- +
- +struct PRESENTPixmapPriv {
- + PRESENTpriv *present_priv;
- + Pixmap pixmap;
- + BOOL released;
- + unsigned int width;
- + unsigned int height;
- + unsigned int depth;
- + unsigned int present_complete_pending;
- + uint32_t serial;
- +#ifdef D3D9NINE_DRI2
- + struct {
- + BOOL is_dri2;
- + struct DRI2priv *dri2_priv;
- + GLuint fbo_read;
- + GLuint fbo_write;
- + GLuint texture_read;
- + GLuint texture_write;
- + } dri2_info;
- +#endif
- + BOOL last_present_was_flip;
- + PRESENTPixmapPriv *next;
- +};
- +
- +BOOL DRI3CheckExtension(Display *dpy, int major, int minor)
- +{
- + xcb_connection_t *xcb_connection = XGetXCBConnection(dpy);
- + xcb_dri3_query_version_cookie_t dri3_cookie;
- + xcb_dri3_query_version_reply_t *dri3_reply;
- + xcb_generic_error_t *error;
- + const xcb_query_extension_reply_t *extension;
- + int fd;
- +
- + xcb_prefetch_extension_data(xcb_connection, &xcb_dri3_id);
- +
- + extension = xcb_get_extension_data(xcb_connection, &xcb_dri3_id);
- + if (!(extension && extension->present))
- + {
- + ERR("DRI3 extension is not present\n");
- + return FALSE;
- + }
- +
- + dri3_cookie = xcb_dri3_query_version(xcb_connection, major, minor);
- +
- + dri3_reply = xcb_dri3_query_version_reply(xcb_connection, dri3_cookie, &error);
- + if (!dri3_reply)
- + {
- + free(error);
- + ERR("Issue getting requested version of DRI3: %d,%d\n", major, minor);
- + return FALSE;
- + }
- +
- + if (!DRI3Open(dpy, DefaultScreen(dpy), &fd))
- + {
- + ERR("DRI3 advertised, but not working\n");
- + return FALSE;
- + }
- + close(fd);
- +
- + TRACE("DRI3 version %d,%d found. %d %d requested\n", major, minor,
- + (int)dri3_reply->major_version, (int)dri3_reply->minor_version);
- + free(dri3_reply);
- +
- + return TRUE;
- +}
- +
- +#ifdef D3D9NINE_DRI2
- +
- +BOOL DRI2FallbackInit(Display *dpy, struct DRI2priv **priv)
- +{
- + PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES_func;
- + PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR_func;
- + PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT_func;
- + PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR_func;
- + EGLint major, minor;
- + EGLConfig config;
- + EGLContext context;
- + EGLint i;
- + EGLBoolean b;
- + EGLenum current_api = 0;
- + const char *extensions;
- + EGLint config_attribs[] = {
- + EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
- + EGL_NONE
- + };
- + EGLint context_compatibility_attribs[] = {
- + EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR,
- + EGL_NONE
- + };
- +
- + current_api = eglQueryAPI();
- + eglGetPlatformDisplayEXT_func = (PFNEGLGETPLATFORMDISPLAYEXTPROC)
- + eglGetProcAddress("eglGetPlatformDisplayEXT");
- +
- + if (!eglGetPlatformDisplayEXT_func)
- + return FALSE;
- + if (!display)
- + display = eglGetPlatformDisplayEXT_func(EGL_PLATFORM_X11_EXT, dpy, NULL);
- + if (!display)
- + return FALSE;
- + /* count references on display for multi device setups */
- + display_ref++;
- +
- + if (eglInitialize(display, &major, &minor) != EGL_TRUE)
- + goto clean_egl_display;
- +
- + extensions = eglQueryString(display, EGL_CLIENT_APIS);
- + if (!extensions || !strstr(extensions, "OpenGL"))
- + goto clean_egl_display;
- +
- + extensions = eglQueryString(display, EGL_EXTENSIONS);
- + if (!extensions || !strstr(extensions, "EGL_EXT_image_dma_buf_import") ||
- + !strstr(extensions, "EGL_KHR_create_context") ||
- + !strstr(extensions, "EGL_KHR_surfaceless_context") ||
- + !strstr(extensions, "EGL_KHR_image_base"))
- + goto clean_egl_display;
- +
- + if (!eglChooseConfig(display, config_attribs, &config, 1, &i))
- + goto clean_egl_display;
- +
- + b = eglBindAPI(EGL_OPENGL_API);
- + if (b == EGL_FALSE)
- + goto clean_egl_display;
- + context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_compatibility_attribs);
- + if (context == EGL_NO_CONTEXT)
- + goto clean_egl_display;
- +
- + glEGLImageTargetTexture2DOES_func = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)
- + eglGetProcAddress("glEGLImageTargetTexture2DOES");
- +
- + eglCreateImageKHR_func = (PFNEGLCREATEIMAGEKHRPROC)
- + eglGetProcAddress("eglCreateImageKHR");
- +
- + eglDestroyImageKHR_func = (PFNEGLDESTROYIMAGEKHRPROC)
- + eglGetProcAddress("eglDestroyImageKHR");
- +
- + if (!eglCreateImageKHR_func ||
- + !glEGLImageTargetTexture2DOES_func ||
- + !eglDestroyImageKHR_func)
- + {
- + ERR("eglGetProcAddress failed !");
- + goto clean_egl;
- + }
- +
- + eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- +
- + *priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- + sizeof(struct DRI2priv));
- + if (!*priv)
- + goto clean_egl;
- + (*priv)->dpy = dpy;
- + (*priv)->display = display;
- + (*priv)->context = context;
- + (*priv)->glEGLImageTargetTexture2DOES_func = glEGLImageTargetTexture2DOES_func;
- + (*priv)->eglCreateImageKHR_func = eglCreateImageKHR_func;
- + (*priv)->eglDestroyImageKHR_func = eglDestroyImageKHR_func;
- + eglBindAPI(current_api);
- + return TRUE;
- +
- +clean_egl:
- + eglDestroyContext(display, context);
- +
- +clean_egl_display:
- + eglTerminate(display);
- + eglBindAPI(current_api);
- + return FALSE;
- +}
- +
- +/* hypothesis: at this step all textures, etc are destroyed */
- +void DRI2FallbackDestroy(struct DRI2priv *priv)
- +{
- + EGLenum current_api;
- + current_api = eglQueryAPI();
- + eglBindAPI(EGL_OPENGL_API);
- + eglMakeCurrent(priv->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- + eglDestroyContext(priv->display, priv->context);
- + if (display)
- + {
- + /* destroy display connection with last device */
- + display_ref--;
- + if (!display_ref)
- + {
- + eglTerminate(display);
- + display = NULL;
- + }
- + }
- + eglBindAPI(current_api);
- + HeapFree(GetProcessHeap(), 0, priv);
- +}
- +
- +BOOL DRI2FallbackCheckSupport(Display *dpy)
- +{
- + struct DRI2priv *priv;
- + int fd;
- + if (!DRI2FallbackInit(dpy, &priv))
- + return FALSE;
- + DRI2FallbackDestroy(priv);
- + if (!DRI2FallbackOpen(dpy, DefaultScreen(dpy), &fd))
- + return FALSE;
- + close(fd);
- + return TRUE;
- +}
- +
- +#endif
- +
- +BOOL PRESENTCheckExtension(Display *dpy, int major, int minor)
- +{
- + xcb_connection_t *xcb_connection = XGetXCBConnection(dpy);
- + xcb_present_query_version_cookie_t present_cookie;
- + xcb_present_query_version_reply_t *present_reply;
- + xcb_generic_error_t *error;
- + const xcb_query_extension_reply_t *extension;
- +
- + xcb_prefetch_extension_data(xcb_connection, &xcb_present_id);
- +
- + extension = xcb_get_extension_data(xcb_connection, &xcb_present_id);
- + if (!(extension && extension->present))
- + {
- + ERR("PRESENT extension is not present\n");
- + return FALSE;
- + }
- +
- + present_cookie = xcb_present_query_version(xcb_connection, major, minor);
- +
- + present_reply = xcb_present_query_version_reply(xcb_connection, present_cookie, &error);
- + if (!present_reply)
- + {
- + free(error);
- + ERR("Issue getting requested version of PRESENT: %d,%d\n", major, minor);
- + return FALSE;
- + }
- +
- + TRACE("PRESENT version %d,%d found. %u %u requested\n", major, minor,
- + present_reply->major_version, present_reply->minor_version);
- +
- + free(present_reply);
- +
- + return TRUE;
- +}
- +
- +BOOL DRI3Open(Display *dpy, int screen, int *device_fd)
- +{
- + xcb_dri3_open_cookie_t cookie;
- + xcb_dri3_open_reply_t *reply;
- + xcb_connection_t *xcb_connection = XGetXCBConnection(dpy);
- + int fd;
- + Window root = RootWindow(dpy, screen);
- +
- + cookie = xcb_dri3_open(xcb_connection, root, 0);
- +
- + reply = xcb_dri3_open_reply(xcb_connection, cookie, NULL);
- + if (!reply)
- + return FALSE;
- +
- + if (reply->nfd != 1)
- + {
- + free(reply);
- + return FALSE;
- + }
- +
- + fd = xcb_dri3_open_reply_fds(xcb_connection, reply)[0];
- + fcntl(fd, F_SETFD, FD_CLOEXEC);
- +
- + *device_fd = fd;
- + free(reply);
- +
- + return TRUE;
- +}
- +
- +#ifdef D3D9NINE_DRI2
- +
- +static XExtensionInfo _dri2_info_data;
- +static XExtensionInfo *dri2_info = &_dri2_info_data;
- +static char dri2_name[] = DRI2_NAME;
- +
- +#define DRI2CheckExtension(dpy, i, val) \
- + XextCheckExtension(dpy, i, dri2_name, val)
- +
- +static int close_display(Display *dpy, XExtCodes *codes);
- +static Bool wire_to_event(Display *dpy, XEvent *re, xEvent *event);
- +static Status event_to_wire(Display *dpy, XEvent *re, xEvent *event);
- +static int error( Display *dpy, xError *err, XExtCodes *codes, int *ret_code );
- +
- +static XExtensionHooks dri2_hooks = {
- + NULL, /* create_gc */
- + NULL, /* copy_gc */
- + NULL, /* flush_gc */
- + NULL, /* free_gc */
- + NULL, /* create_font */
- + NULL, /* free_font */
- + close_display, /* close_display */
- + wire_to_event, /* wire_to_event */
- + event_to_wire, /* event_to_wire */
- + error, /* error */
- + NULL, /* error_string */
- +};
- +static XEXT_GENERATE_CLOSE_DISPLAY(close_display, dri2_info);
- +static XEXT_GENERATE_FIND_DISPLAY(find_display, dri2_info,
- + dri2_name, &dri2_hooks, 0, NULL);
- +static Bool wire_to_event(Display *dpy, XEvent *re, xEvent *event)
- +{
- + XExtDisplayInfo *info = find_display(dpy);
- + DRI2CheckExtension(dpy, info, False);
- + TRACE("dri2 wire_to_event\n");
- + return False;
- +}
- +
- +static Status event_to_wire(Display *dpy, XEvent *re, xEvent *event)
- +{
- + XExtDisplayInfo *info = find_display(dpy);
- + DRI2CheckExtension(dpy, info, False);
- + TRACE("dri2 event_to_wire\n");
- + return False;
- +}
- +
- +static int error(Display *dpy, xError *err, XExtCodes *codes, int *ret_code)
- +{
- + TRACE("dri2 error\n");
- + return False;
- +}
- +
- +#define XALIGN(x) (((x) + 3) & (~3))
- +
- +static BOOL DRI2Connect(Display *dpy, XID window, unsigned driver_type, char **device)
- +{
- + XExtDisplayInfo *info = find_display(dpy);
- + xDRI2ConnectReply rep;
- + xDRI2ConnectReq *req;
- + int dev_len, driv_len;
- + char *driver;
- +
- + DRI2CheckExtension(dpy, info, False);
- +
- + *device = NULL;
- +
- + LockDisplay(dpy);
- + GetReq(DRI2Connect, req);
- + req->reqType = info->codes->major_opcode;
- + req->dri2ReqType = X_DRI2Connect;
- + req->window = window;
- + req->driverType = driver_type;
- + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse))
- + {
- + UnlockDisplay(dpy);
- + SyncHandle();
- + return False;
- + }
- +
- + /* check string lengths */
- + dev_len = rep.deviceNameLength;
- + driv_len = rep.driverNameLength;
- + if (dev_len == 0 || driv_len == 0)
- + {
- + _XEatData(dpy, XALIGN(dev_len) + XALIGN(driv_len));
- + UnlockDisplay(dpy);
- + SyncHandle();
- + return False;
- + }
- +
- + /* read out driver */
- + driver = HeapAlloc(GetProcessHeap(), 0, driv_len + 1);
- + if (!driver)
- + {
- + _XEatData(dpy, XALIGN(dev_len) + XALIGN(driv_len));
- + UnlockDisplay(dpy);
- + SyncHandle();
- + return False;
- + }
- + _XReadPad(dpy, driver, driv_len);
- + HeapFree(GetProcessHeap(), 0, driver); /* we don't need the driver */
- +
- + /* read out device */
- + *device = HeapAlloc(GetProcessHeap(), 0, dev_len + 1);
- + if (!*device)
- + {
- + _XEatData(dpy, XALIGN(dev_len));
- + UnlockDisplay(dpy);
- + SyncHandle();
- + return False;
- + }
- + _XReadPad(dpy, *device, dev_len);
- + (*device)[dev_len] = '\0';
- +
- + UnlockDisplay(dpy);
- + SyncHandle();
- +
- + return True;
- +}
- +
- +static Bool DRI2Authenticate(Display *dpy, XID window, uint32_t token)
- +{
- + XExtDisplayInfo *info = find_display(dpy);
- + xDRI2AuthenticateReply rep;
- + xDRI2AuthenticateReq *req;
- +
- + DRI2CheckExtension(dpy, info, False);
- +
- + LockDisplay(dpy);
- + GetReq(DRI2Authenticate, req);
- + req->reqType = info->codes->major_opcode;
- + req->dri2ReqType = X_DRI2Authenticate;
- + req->window = window;
- + req->magic = token;
- + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse))
- + {
- + UnlockDisplay(dpy);
- + SyncHandle();
- + return False;
- + }
- + UnlockDisplay(dpy);
- + SyncHandle();
- +
- + return rep.authenticated ? True : False;
- +}
- +
- +BOOL DRI2FallbackOpen(Display *dpy, int screen, int *device_fd)
- +{
- + char *device;
- + int fd;
- + Window root = RootWindow(dpy, screen);
- + drm_auth_t auth;
- +
- + if (!DRI2Connect(dpy, root, DRI2DriverDRI, &device))
- + return FALSE;
- +
- + fd = open(device, O_RDWR);
- + HeapFree(GetProcessHeap(), 0, device);
- + if (fd < 0)
- + return FALSE;
- +
- + if (ioctl(fd, DRM_IOCTL_GET_MAGIC, &auth) != 0)
- + {
- + close(fd);
- + return FALSE;
- + }
- +
- + if (!DRI2Authenticate(dpy, root, auth.magic))
- + {
- + close(fd);
- + return FALSE;
- + }
- +
- + *device_fd = fd;
- +
- + return TRUE;
- +}
- +
- +#endif
- +
- +
- +BOOL DRI3PixmapFromDmaBuf(Display *dpy, int screen, int fd, int width, int height,
- + int stride, int depth, int bpp, Pixmap *pixmap)
- +{
- + xcb_connection_t *xcb_connection = XGetXCBConnection(dpy);
- + Window root = RootWindow(dpy, screen);
- + xcb_void_cookie_t cookie;
- + xcb_generic_error_t *error;
- +
- + cookie = xcb_dri3_pixmap_from_buffer_checked(xcb_connection,
- + (*pixmap = xcb_generate_id(xcb_connection)), root, 0,
- + width, height, stride, depth, bpp, fd);
- +
- + error = xcb_request_check(xcb_connection, cookie); /* performs a flush */
- + if (error)
- + {
- + ERR("Error using DRI3 to convert a DmaBufFd to pixmap\n");
- + return FALSE;
- + }
- + return TRUE;
- +}
- +
- +BOOL DRI3DmaBufFromPixmap(Display *dpy, Pixmap pixmap, int *fd, int *width, int *height,
- + int *stride, int *depth, int *bpp)
- +{
- + xcb_connection_t *xcb_connection = XGetXCBConnection(dpy);
- + xcb_dri3_buffer_from_pixmap_cookie_t bp_cookie;
- + xcb_dri3_buffer_from_pixmap_reply_t *bp_reply;
- +
- + bp_cookie = xcb_dri3_buffer_from_pixmap(xcb_connection, pixmap);
- + bp_reply = xcb_dri3_buffer_from_pixmap_reply(xcb_connection, bp_cookie, NULL);
- + if (!bp_reply)
- + return FALSE;
- + *fd = xcb_dri3_buffer_from_pixmap_reply_fds(xcb_connection, bp_reply)[0];
- + *width = bp_reply->width;
- + *height = bp_reply->height;
- + *stride = bp_reply->stride;
- + *depth = bp_reply->depth;
- + *bpp = bp_reply->depth;
- + return TRUE;
- +}
- +
- +static PRESENTPixmapPriv *PRESENTFindPixmapPriv(PRESENTpriv *present_priv, uint32_t serial)
- +{
- + PRESENTPixmapPriv *current = present_priv->first_present_priv;
- +
- + while (current)
- + {
- + if (current->serial == serial)
- + return current;
- + current = current->next;
- + }
- + return NULL;
- +}
- +
- +static void PRESENThandle_events(PRESENTpriv *present_priv, xcb_present_generic_event_t *ge)
- +{
- + PRESENTPixmapPriv *present_pixmap_priv = NULL;
- +
- + switch (ge->evtype)
- + {
- + case XCB_PRESENT_COMPLETE_NOTIFY:
- + {
- + xcb_present_complete_notify_event_t *ce = (void *) ge;
- + if (ce->kind == XCB_PRESENT_COMPLETE_KIND_NOTIFY_MSC)
- + {
- + if (ce->serial)
- + present_priv->notify_with_serial_pending = FALSE;
- + free(ce);
- + return;
- + }
- + present_pixmap_priv = PRESENTFindPixmapPriv(present_priv, ce->serial);
- + if (!present_pixmap_priv || ce->kind != XCB_PRESENT_COMPLETE_KIND_PIXMAP)
- + {
- + ERR("FATAL ERROR: PRESENT handling failed\n");
- + free(ce);
- + return;
- + }
- + present_pixmap_priv->present_complete_pending--;
- + switch (ce->mode)
- + {
- + case XCB_PRESENT_COMPLETE_MODE_FLIP:
- + present_pixmap_priv->last_present_was_flip = TRUE;
- + break;
- + case XCB_PRESENT_COMPLETE_MODE_COPY:
- + present_pixmap_priv->last_present_was_flip = FALSE;
- + break;
- + }
- + present_priv->pixmap_present_pending--;
- + present_priv->last_msc = ce->msc;
- + break;
- + }
- + case XCB_PRESENT_EVENT_IDLE_NOTIFY:
- + {
- + xcb_present_idle_notify_event_t *ie = (void *) ge;
- + present_pixmap_priv = PRESENTFindPixmapPriv(present_priv, ie->serial);
- + if (!present_pixmap_priv || present_pixmap_priv->pixmap != ie->pixmap)
- + {
- + ERR("FATAL ERROR: PRESENT handling failed\n");
- + free(ie);
- + return;
- + }
- + present_pixmap_priv->released = TRUE;
- + present_priv->idle_notify_since_last_check = TRUE;
- + break;
- + }
- + }
- + free(ge);
- +}
- +
- +static void PRESENTflush_events(PRESENTpriv *present_priv, BOOL assert_no_other_thread_waiting)
- +{
- + xcb_generic_event_t *ev;
- +
- + if ((present_priv->xcb_wait && !assert_no_other_thread_waiting) || /* don't steal events to someone waiting */
- + !present_priv->special_event)
- + return;
- +
- + while ((ev = xcb_poll_for_special_event(present_priv->xcb_connection,
- + present_priv->special_event)) != NULL)
- + {
- + PRESENThandle_events(present_priv, (void *) ev);
- + }
- +}
- +
- +static BOOL PRESENTwait_events(PRESENTpriv *present_priv, BOOL allow_other_threads)
- +{
- + xcb_generic_event_t *ev;
- +
- + if (allow_other_threads)
- + {
- + present_priv->xcb_wait = TRUE;
- + EnterCriticalSection(&present_priv->mutex_xcb_wait);
- + LeaveCriticalSection(&present_priv->mutex_present);
- + }
- + ev = xcb_wait_for_special_event(present_priv->xcb_connection, present_priv->special_event);
- + if (allow_other_threads)
- + {
- + LeaveCriticalSection(&present_priv->mutex_xcb_wait);
- + EnterCriticalSection(&present_priv->mutex_present);
- + present_priv->xcb_wait = FALSE;
- + }
- + if (!ev)
- + {
- + ERR("FATAL error: xcb had an error\n");
- + return FALSE;
- + }
- +
- + PRESENThandle_events(present_priv, (void *) ev);
- + return TRUE;
- +}
- +
- +static struct xcb_connection_t *create_xcb_connection(Display *dpy)
- +{
- + int screen_num = DefaultScreen(dpy);
- + xcb_connection_t *ret;
- + xcb_xfixes_query_version_cookie_t cookie;
- + xcb_xfixes_query_version_reply_t *rep;
- +
- + ret = xcb_connect(DisplayString(dpy), &screen_num);
- + cookie = xcb_xfixes_query_version_unchecked(ret, XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MINOR_VERSION);
- + rep = xcb_xfixes_query_version_reply(ret, cookie, NULL);
- + if (rep)
- + free(rep);
- + return ret;
- +}
- +
- +BOOL PRESENTInit(Display *dpy, PRESENTpriv **present_priv)
- +{
- + *present_priv = (PRESENTpriv *) HeapAlloc(GetProcessHeap(),
- + HEAP_ZERO_MEMORY, sizeof(PRESENTpriv));
- +
- + if (!*present_priv)
- + return FALSE;
- +
- + (*present_priv)->xcb_connection = create_xcb_connection(dpy);
- + (*present_priv)->xcb_connection_bis = create_xcb_connection(dpy);
- +
- + InitializeCriticalSection(&(*present_priv)->mutex_present);
- + InitializeCriticalSection(&(*present_priv)->mutex_xcb_wait);
- + return TRUE;
- +}
- +
- +static void PRESENTForceReleases(PRESENTpriv *present_priv)
- +{
- + PRESENTPixmapPriv *current = NULL;
- +
- + if (!present_priv->window)
- + return;
- +
- + /* There should be no other thread listening for events here.
- + * This can happen when hDestWindowOverride changes without reset.
- + * This case should never happen, but can happen in theory.*/
- + if (present_priv->xcb_wait)
- + {
- + xcb_present_notify_msc(present_priv->xcb_connection, present_priv->window, 0, 0, 0, 0);
- + xcb_flush(present_priv->xcb_connection);
- + EnterCriticalSection(&present_priv->mutex_xcb_wait);
- + LeaveCriticalSection(&present_priv->mutex_xcb_wait);
- + /* the problem here is that we don't have access to the event the other thread got.
- + * It is either presented event, idle event or notify event.
- + */
- + while (present_priv->pixmap_present_pending >= 2)
- + PRESENTwait_events(present_priv, FALSE);
- + PRESENTflush_events(present_priv, TRUE);
- + /* Remaining events to come can be a pair of present/idle,
- + * or an idle, or nothing. To be sure we are after all pixmaps
- + * have been presented, add an event to the queue that can only
- + * be after the present event, then if we receive an event more,
- + * we are sure all pixmaps were presented */
- + present_priv->notify_with_serial_pending = TRUE;
- + xcb_present_notify_msc(present_priv->xcb_connection, present_priv->window,
- + 1, present_priv->last_target + 5, 0, 0);
- +
- + xcb_flush(present_priv->xcb_connection);
- + while (present_priv->notify_with_serial_pending)
- + PRESENTwait_events(present_priv, FALSE);
- + /* Now we are sure we are not expecting any new event */
- + }
- + else
- + {
- + while (present_priv->pixmap_present_pending) /* wait all sent pixmaps are presented */
- + PRESENTwait_events(present_priv, FALSE);
- + PRESENTflush_events(present_priv, TRUE); /* may be remaining idle event */
- + /* Since idle events are send with the complete events when it is not flips,
- + * we are not expecting any new event here */
- + }
- +
- + current = present_priv->first_present_priv;
- + while (current)
- + {
- + if (!current->released)
- + {
- + if (!current->last_present_was_flip && !present_priv->xcb_wait)
- + {
- + ERR("ERROR: a pixmap seems not released by PRESENT for no reason. Code bug.\n");
- + }
- + else
- + {
- + /* Present the same pixmap with a non-valid part to force the copy mode and the releases */
- + xcb_xfixes_region_t valid, update;
- + xcb_rectangle_t rect_update;
- + rect_update.x = 0;
- + rect_update.y = 0;
- + rect_update.width = 8;
- + rect_update.height = 1;
- + valid = xcb_generate_id(present_priv->xcb_connection);
- + update = xcb_generate_id(present_priv->xcb_connection);
- + xcb_xfixes_create_region(present_priv->xcb_connection, valid, 1, &rect_update);
- + xcb_xfixes_create_region(present_priv->xcb_connection, update, 1, &rect_update);
- + /* here we know the pixmap has been presented. Thus if it is on screen,
- + * the following request can only make it released by the server if it is not */
- + xcb_present_pixmap(present_priv->xcb_connection, present_priv->window,
- + current->pixmap, 0, valid, update, 0, 0, None, None,
- + None, XCB_PRESENT_OPTION_COPY | XCB_PRESENT_OPTION_ASYNC, 0, 0, 0, 0, NULL);
- + xcb_flush(present_priv->xcb_connection);
- + PRESENTwait_events(present_priv, FALSE); /* by assumption this can only be idle event */
- + PRESENTflush_events(present_priv, TRUE); /* Shoudln't be needed */
- + }
- + }
- + current = current->next;
- + }
- + /* Now all pixmaps are released (possibility if xcb_wait is true that one is not aware yet),
- + * and we don't expect any new Present event to come from Xserver */
- +}
- +
- +static void PRESENTFreeXcbQueue(PRESENTpriv *present_priv)
- +{
- + if (present_priv->window)
- + {
- + xcb_unregister_for_special_event(present_priv->xcb_connection, present_priv->special_event);
- + present_priv->last_msc = 0;
- + present_priv->last_target = 0;
- + present_priv->special_event = NULL;
- + }
- +}
- +
- +static BOOL PRESENTPrivChangeWindow(PRESENTpriv *present_priv, XID window)
- +{
- + xcb_void_cookie_t cookie;
- + xcb_generic_error_t *error;
- + xcb_present_event_t eid;
- +
- + PRESENTForceReleases(present_priv);
- + PRESENTFreeXcbQueue(present_priv);
- + present_priv->window = window;
- +
- + if (window)
- + {
- + cookie = xcb_present_select_input_checked(present_priv->xcb_connection,
- + (eid = xcb_generate_id(present_priv->xcb_connection)), window,
- + XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY | XCB_PRESENT_EVENT_MASK_IDLE_NOTIFY);
- +
- + present_priv->special_event = xcb_register_for_special_xge(present_priv->xcb_connection,
- + &xcb_present_id, eid, NULL);
- +
- + error = xcb_request_check(present_priv->xcb_connection, cookie); /* performs a flush */
- + if (error || !present_priv->special_event)
- + {
- + ERR("FAILED to use the X PRESENT extension. Was the destination a window ?\n");
- + if (present_priv->special_event)
- + xcb_unregister_for_special_event(present_priv->xcb_connection, present_priv->special_event);
- + present_priv->special_event = NULL;
- + present_priv->window = 0;
- + }
- + }
- + return (present_priv->window != 0);
- +}
- +
- +/* Destroy the content, except the link and the struct mem */
- +static void PRESENTDestroyPixmapContent(Display *dpy, PRESENTPixmapPriv *present_pixmap)
- +{
- + XFreePixmap(dpy, present_pixmap->pixmap);
- +#ifdef D3D9NINE_DRI2
- + if (present_pixmap->dri2_info.is_dri2)
- + {
- + struct DRI2priv *dri2_priv = present_pixmap->dri2_info.dri2_priv;
- + EGLenum current_api;
- + current_api = eglQueryAPI();
- + eglBindAPI(EGL_OPENGL_API);
- + if (eglMakeCurrent(dri2_priv->display, EGL_NO_SURFACE, EGL_NO_SURFACE, dri2_priv->context))
- + {
- + glDeleteFramebuffers(1, &present_pixmap->dri2_info.fbo_read);
- + glDeleteFramebuffers(1, &present_pixmap->dri2_info.fbo_write);
- + glDeleteTextures(1, &present_pixmap->dri2_info.texture_read);
- + glDeleteTextures(1, &present_pixmap->dri2_info.texture_write);
- + }
- + else
- + ERR("eglMakeCurrent failed with 0x%0X\n", eglGetError());
- +
- + eglMakeCurrent(dri2_priv->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- + eglBindAPI(current_api);
- + }
- +#endif
- +}
- +
- +void PRESENTDestroy(Display *dpy, PRESENTpriv *present_priv)
- +{
- + PRESENTPixmapPriv *current = NULL;
- +
- + EnterCriticalSection(&present_priv->mutex_present);
- +
- + PRESENTForceReleases(present_priv);
- +
- + current = present_priv->first_present_priv;
- + while (current)
- + {
- + PRESENTPixmapPriv *next = current->next;
- + PRESENTDestroyPixmapContent(dpy, current);
- + HeapFree(GetProcessHeap(), 0, current);
- + current = next;
- + }
- +
- + PRESENTFreeXcbQueue(present_priv);
- +
- + xcb_disconnect(present_priv->xcb_connection);
- + xcb_disconnect(present_priv->xcb_connection_bis);
- + LeaveCriticalSection(&present_priv->mutex_present);
- + DeleteCriticalSection(&present_priv->mutex_present);
- + DeleteCriticalSection(&present_priv->mutex_xcb_wait);
- +
- + HeapFree(GetProcessHeap(), 0, present_priv);
- +}
- +
- +BOOL PRESENTPixmapInit(PRESENTpriv *present_priv, Pixmap pixmap, PRESENTPixmapPriv **present_pixmap_priv)
- +{
- + xcb_get_geometry_cookie_t cookie;
- + xcb_get_geometry_reply_t *reply;
- +
- + cookie = xcb_get_geometry(present_priv->xcb_connection, pixmap);
- + reply = xcb_get_geometry_reply(present_priv->xcb_connection, cookie, NULL);
- +
- + if (!reply)
- + return FALSE;
- +
- + *present_pixmap_priv = (PRESENTPixmapPriv *) HeapAlloc(GetProcessHeap(),
- + HEAP_ZERO_MEMORY, sizeof(PRESENTPixmapPriv));
- +
- + if (!*present_pixmap_priv)
- + {
- + free(reply);
- + return FALSE;
- + }
- + EnterCriticalSection(&present_priv->mutex_present);
- +
- + (*present_pixmap_priv)->released = TRUE;
- + (*present_pixmap_priv)->pixmap = pixmap;
- + (*present_pixmap_priv)->present_priv = present_priv;
- + (*present_pixmap_priv)->next = present_priv->first_present_priv;
- + (*present_pixmap_priv)->width = reply->width;
- + (*present_pixmap_priv)->height = reply->height;
- + (*present_pixmap_priv)->depth = reply->depth;
- +#ifdef D3D9NINE_DRI2
- + (*present_pixmap_priv)->dri2_info.is_dri2 = FALSE;
- +#endif
- + free(reply);
- +
- + present_priv->last_serial_given++;
- + (*present_pixmap_priv)->serial = present_priv->last_serial_given;
- + present_priv->first_present_priv = *present_pixmap_priv;
- +
- + LeaveCriticalSection(&present_priv->mutex_present);
- + return TRUE;
- +}
- +
- +#ifdef D3D9NINE_DRI2
- +
- +BOOL DRI2FallbackPRESENTPixmap(PRESENTpriv *present_priv, struct DRI2priv *dri2_priv,
- + int fd, int width, int height, int stride, int depth,
- + int bpp, PRESENTPixmapPriv **present_pixmap_priv)
- +{
- + Window root = RootWindow(dri2_priv->dpy, DefaultScreen(dri2_priv->dpy));
- + Pixmap pixmap;
- + EGLImageKHR image;
- + GLuint texture_read, texture_write, fbo_read, fbo_write;
- + EGLint attribs[] = {
- + EGL_WIDTH, 0,
- + EGL_HEIGHT, 0,
- + EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888,
- + EGL_DMA_BUF_PLANE0_FD_EXT, 0,
- + EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,
- + EGL_DMA_BUF_PLANE0_PITCH_EXT, 0,
- + EGL_NONE
- + };
- + EGLenum current_api = 0;
- + int status;
- +
- + EnterCriticalSection(&present_priv->mutex_present);
- +
- + pixmap = XCreatePixmap(dri2_priv->dpy, root, width, height, 24);
- + if (!pixmap)
- + goto fail;
- +
- + attribs[1] = width;
- + attribs[3] = height;
- + attribs[7] = fd;
- + attribs[11] = stride;
- +
- + current_api = eglQueryAPI();
- + eglBindAPI(EGL_OPENGL_API);
- +
- + /* We bind the dma-buf to a EGLImage, then to a texture, and then to a fbo.
- + * Note that we can delete the EGLImage, but we shouldn't delete the texture,
- + * else the fbo is invalid */
- +
- + image = dri2_priv->eglCreateImageKHR_func(dri2_priv->display,
- + EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
- +
- + if (image == EGL_NO_IMAGE_KHR)
- + goto fail;
- + close(fd);
- +
- + if (eglMakeCurrent(dri2_priv->display, EGL_NO_SURFACE, EGL_NO_SURFACE, dri2_priv->context))
- + {
- + glGenTextures(1, &texture_read);
- + glBindTexture(GL_TEXTURE_2D, texture_read);
- + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- + dri2_priv->glEGLImageTargetTexture2DOES_func(GL_TEXTURE_2D, image);
- + glGenFramebuffers(1, &fbo_read);
- + glBindFramebuffer(GL_FRAMEBUFFER, fbo_read);
- + glFramebufferTexture2D(GL_FRAMEBUFFER,
- + GL_COLOR_ATTACHMENT0,
- + GL_TEXTURE_2D, texture_read,
- + 0);
- + status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
- + if (status != GL_FRAMEBUFFER_COMPLETE)
- + goto fail;
- + glBindTexture(GL_TEXTURE_2D, 0);
- + dri2_priv->eglDestroyImageKHR_func(dri2_priv->display, image);
- +
- + /* We bind a newly created pixmap (to which we want to copy the content)
- + * to an EGLImage, then to a texture, then to a fbo. */
- + image = dri2_priv->eglCreateImageKHR_func(dri2_priv->display,
- + dri2_priv->context,
- + EGL_NATIVE_PIXMAP_KHR,
- + (void *)pixmap, NULL);
- + if (image == EGL_NO_IMAGE_KHR)
- + goto fail;
- +
- + glGenTextures(1, &texture_write);
- + glBindTexture(GL_TEXTURE_2D, texture_write);
- + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- + dri2_priv->glEGLImageTargetTexture2DOES_func(GL_TEXTURE_2D, image);
- + glGenFramebuffers(1, &fbo_write);
- + glBindFramebuffer(GL_FRAMEBUFFER, fbo_write);
- + glFramebufferTexture2D(GL_FRAMEBUFFER,
- + GL_COLOR_ATTACHMENT0,
- + GL_TEXTURE_2D, texture_write,
- + 0);
- + status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
- + if (status != GL_FRAMEBUFFER_COMPLETE)
- + goto fail;
- + glBindTexture(GL_TEXTURE_2D, 0);
- + dri2_priv->eglDestroyImageKHR_func(dri2_priv->display, image);
- + }
- + else
- + ERR("eglMakeCurrent failed with 0x%0X\n", eglGetError());
- +
- + eglMakeCurrent(dri2_priv->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- +
- + *present_pixmap_priv = (PRESENTPixmapPriv *) HeapAlloc(GetProcessHeap(),
- + HEAP_ZERO_MEMORY, sizeof(PRESENTPixmapPriv));
- +
- + if (!*present_pixmap_priv)
- + goto fail;
- +
- + (*present_pixmap_priv)->released = TRUE;
- + (*present_pixmap_priv)->pixmap = pixmap;
- + (*present_pixmap_priv)->present_priv = present_priv;
- + (*present_pixmap_priv)->next = present_priv->first_present_priv;
- + (*present_pixmap_priv)->width = width;
- + (*present_pixmap_priv)->height = height;
- + (*present_pixmap_priv)->depth = depth;
- + (*present_pixmap_priv)->dri2_info.is_dri2 = TRUE;
- + (*present_pixmap_priv)->dri2_info.dri2_priv = dri2_priv;
- + (*present_pixmap_priv)->dri2_info.fbo_read = fbo_read;
- + (*present_pixmap_priv)->dri2_info.fbo_write = fbo_write;
- + (*present_pixmap_priv)->dri2_info.texture_read = texture_read;
- + (*present_pixmap_priv)->dri2_info.texture_write = texture_write;
- +
- + present_priv->last_serial_given++;
- + (*present_pixmap_priv)->serial = present_priv->last_serial_given;
- + present_priv->first_present_priv = *present_pixmap_priv;
- +
- + eglBindAPI(current_api);
- +
- + LeaveCriticalSection(&present_priv->mutex_present);
- + return TRUE;
- +fail:
- + eglMakeCurrent(dri2_priv->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- + eglBindAPI(current_api);
- + LeaveCriticalSection(&present_priv->mutex_present);
- + return FALSE;
- +}
- +
- +#endif
- +
- +BOOL PRESENTTryFreePixmap(Display *dpy, PRESENTPixmapPriv *present_pixmap_priv)
- +{
- + PRESENTpriv *present_priv = present_pixmap_priv->present_priv;
- + PRESENTPixmapPriv *current;
- +
- + EnterCriticalSection(&present_priv->mutex_present);
- +
- + if (!present_pixmap_priv->released || present_pixmap_priv->present_complete_pending)
- + {
- + LeaveCriticalSection(&present_priv->mutex_present);
- + return FALSE;
- + }
- +
- + if (present_priv->first_present_priv == present_pixmap_priv)
- + {
- + present_priv->first_present_priv = present_pixmap_priv->next;
- + goto free_priv;
- + }
- +
- + current = present_priv->first_present_priv;
- + while (current->next != present_pixmap_priv)
- + current = current->next;
- + current->next = present_pixmap_priv->next;
- +free_priv:
- + PRESENTDestroyPixmapContent(dpy, present_pixmap_priv);
- + HeapFree(GetProcessHeap(), 0, present_pixmap_priv);
- + LeaveCriticalSection(&present_priv->mutex_present);
- + return TRUE;
- +}
- +
- +BOOL PRESENTHelperCopyFront(Display *dpy, PRESENTPixmapPriv *present_pixmap_priv)
- +{
- + PRESENTpriv *present_priv = present_pixmap_priv->present_priv;
- + xcb_void_cookie_t cookie;
- + xcb_generic_error_t *error;
- + uint32_t v = 0;
- + xcb_gcontext_t gc;
- +
- + EnterCriticalSection(&present_priv->mutex_present);
- +
- + if (!present_priv->window)
- + {
- + LeaveCriticalSection(&present_priv->mutex_present);
- + return FALSE;
- + }
- +
- + gc = xcb_generate_id(present_priv->xcb_connection);
- + xcb_create_gc(present_priv->xcb_connection, gc, present_priv->window,
- + XCB_GC_GRAPHICS_EXPOSURES, &v);
- +
- + cookie = xcb_copy_area_checked(present_priv->xcb_connection,
- + present_priv->window, present_pixmap_priv->pixmap, gc,
- + 0, 0, 0, 0, present_pixmap_priv->width, present_pixmap_priv->height);
- +
- + error = xcb_request_check(present_priv->xcb_connection, cookie);
- + xcb_free_gc(present_priv->xcb_connection, gc);
- + LeaveCriticalSection(&present_priv->mutex_present);
- + return (error != NULL);
- +}
- +
- +BOOL PRESENTPixmap(Display *dpy, XID window, PRESENTPixmapPriv *present_pixmap_priv,
- + const UINT PresentationInterval, const BOOL PresentAsync, const BOOL SwapEffectCopy,
- + const RECT *pSourceRect, const RECT *pDestRect, const RGNDATA *pDirtyRegion)
- +{
- + PRESENTpriv *present_priv = present_pixmap_priv->present_priv;
- +#ifdef D3D9NINE_DRI2
- + struct DRI2priv *dri2_priv = present_pixmap_priv->dri2_info.dri2_priv;
- + EGLenum current_api = 0;
- +#endif
- + xcb_void_cookie_t cookie;
- + xcb_generic_error_t *error;
- + int64_t target_msc, presentationInterval;
- + xcb_xfixes_region_t valid, update;
- + int16_t x_off, y_off;
- + uint32_t options = XCB_PRESENT_OPTION_NONE;
- +
- + EnterCriticalSection(&present_priv->mutex_present);
- +
- + if (window != present_priv->window)
- + PRESENTPrivChangeWindow(present_priv, window);
- +
- + if (!window)
- + {
- + ERR("ERROR: Try to Present a pixmap on a NULL window\n");
- + LeaveCriticalSection(&present_priv->mutex_present);
- + return FALSE;
- + }
- +
- + PRESENTflush_events(present_priv, FALSE);
- + /* Note: present_pixmap_priv->present_complete_pending may be non-0, because
- + * on some paths the Xserver sends the complete event just after the idle
- + * event. */
- + if (!present_pixmap_priv->released)
- + {
- + ERR("FATAL ERROR: Trying to Present a pixmap not released\n");
- + LeaveCriticalSection(&present_priv->mutex_present);
- + return FALSE;
- + }
- +#ifdef D3D9NINE_DRI2
- + if (present_pixmap_priv->dri2_info.is_dri2)
- + {
- + current_api = eglQueryAPI();
- + eglBindAPI(EGL_OPENGL_API);
- + if (eglMakeCurrent(dri2_priv->display, EGL_NO_SURFACE, EGL_NO_SURFACE, dri2_priv->context))
- + {
- + glBindFramebuffer(GL_READ_FRAMEBUFFER, present_pixmap_priv->dri2_info.fbo_read);
- + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, present_pixmap_priv->dri2_info.fbo_write);
- +
- + glBlitFramebuffer(0, 0, present_pixmap_priv->width, present_pixmap_priv->height,
- + 0, 0, present_pixmap_priv->width, present_pixmap_priv->height,
- + GL_COLOR_BUFFER_BIT, GL_NEAREST);
- + glFlush(); /* Perhaps useless */
- + }
- + else
- + ERR("eglMakeCurrent failed with 0x%0X\n", eglGetError());
- +
- + eglMakeCurrent(dri2_priv->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- + eglBindAPI(current_api);
- + }
- +#endif
- + target_msc = present_priv->last_msc;
- +
- + presentationInterval = PresentationInterval;
- + if (PresentAsync)
- + options |= XCB_PRESENT_OPTION_ASYNC;
- + if (SwapEffectCopy)
- + options |= XCB_PRESENT_OPTION_COPY;
- +
- + target_msc += presentationInterval * (present_priv->pixmap_present_pending + 1);
- +
- + /* Note: PRESENT defines some way to do partial copy:
- + * presentproto:
- + * 'x-off' and 'y-off' define the location in the window where
- + * the 0,0 location of the pixmap will be presented. valid-area
- + * and update-area are relative to the pixmap.
- + */
- + if (!pSourceRect && !pDestRect && !pDirtyRegion)
- + {
- + valid = 0;
- + update = 0;
- + x_off = 0;
- + y_off = 0;
- + }
- + else
- + {
- + xcb_rectangle_t rect_update;
- + xcb_rectangle_t *rect_updates;
- + int i;
- +
- + rect_update.x = 0;
- + rect_update.y = 0;
- + rect_update.width = present_pixmap_priv->width;
- + rect_update.height = present_pixmap_priv->height;
- + x_off = 0;
- + y_off = 0;
- + if (pSourceRect)
- + {
- + x_off = -pSourceRect->left;
- + y_off = -pSourceRect->top;
- + rect_update.x = pSourceRect->left;
- + rect_update.y = pSourceRect->top;
- + rect_update.width = pSourceRect->right - pSourceRect->left;
- + rect_update.height = pSourceRect->bottom - pSourceRect->top;
- + }
- + if (pDestRect)
- + {
- + x_off += pDestRect->left;
- + y_off += pDestRect->top;
- + rect_update.width = pDestRect->right - pDestRect->left;
- + rect_update.height = pDestRect->bottom - pDestRect->top;
- + /* Note: the size of pDestRect and pSourceRect are supposed to be the same size
- + * because the driver would have done things to assure that. */
- + }
- + valid = xcb_generate_id(present_priv->xcb_connection_bis);
- + update = xcb_generate_id(present_priv->xcb_connection_bis);
- + xcb_xfixes_create_region(present_priv->xcb_connection_bis, valid, 1, &rect_update);
- + if (pDirtyRegion && pDirtyRegion->rdh.nCount)
- + {
- + rect_updates = (void *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- + sizeof(xcb_rectangle_t) * pDirtyRegion->rdh.nCount);
- +
- + for (i = 0; i < pDirtyRegion->rdh.nCount; i++)
- + {
- + RECT rc;
- + memcpy(&rc, pDirtyRegion->Buffer + i * sizeof(RECT), sizeof(RECT));
- + rect_update.x = rc.left;
- + rect_update.y = rc.top;
- + rect_update.width = rc.right - rc.left;
- + rect_update.height = rc.bottom - rc.top;
- + memcpy(rect_updates + i * sizeof(xcb_rectangle_t), &rect_update, sizeof(xcb_rectangle_t));
- + }
- + xcb_xfixes_create_region(present_priv->xcb_connection_bis, update, pDirtyRegion->rdh.nCount, rect_updates);
- + HeapFree(GetProcessHeap(), 0, rect_updates);
- + } else
- + xcb_xfixes_create_region(present_priv->xcb_connection_bis, update, 1, &rect_update);
- + }
- +
- + cookie = xcb_present_pixmap_checked(present_priv->xcb_connection_bis,
- + window, present_pixmap_priv->pixmap, present_pixmap_priv->serial,
- + valid, update, x_off, y_off, None, None, None, options,
- + target_msc, 0, 0, 0, NULL);
- + error = xcb_request_check(present_priv->xcb_connection_bis, cookie); /* performs a flush */
- +
- + if (update)
- + xcb_xfixes_destroy_region(present_priv->xcb_connection_bis, update);
- + if (valid)
- + xcb_xfixes_destroy_region(present_priv->xcb_connection_bis, valid);
- +
- + if (error)
- + {
- + xcb_get_geometry_cookie_t cookie_geom;
- + xcb_get_geometry_reply_t *reply;
- +
- + cookie_geom = xcb_get_geometry(present_priv->xcb_connection_bis, window);
- + reply = xcb_get_geometry_reply(present_priv->xcb_connection_bis, cookie_geom, NULL);
- +
- + ERR("Error using PRESENT. Here some debug info\n");
- + if (!reply)
- + {
- + ERR("Error querying window info. Perhaps it doesn't exist anymore\n");
- + LeaveCriticalSection(&present_priv->mutex_present);
- + return FALSE;
- + }
- + ERR("Pixmap: width=%d, height=%d, depth=%d\n",
- + present_pixmap_priv->width, present_pixmap_priv->height,
- + present_pixmap_priv->depth);
- +
- + ERR("Window: width=%d, height=%d, depth=%d, x=%d, y=%d\n",
- + (int) reply->width, (int) reply->height,
- + (int) reply->depth, (int) reply->x, (int) reply->y);
- +
- + ERR("Present parameter: PresentationInterval=%d, Pending presentations=%d\n",
- + PresentationInterval, present_priv->pixmap_present_pending);
- +
- + if (present_pixmap_priv->depth != reply->depth)
- + ERR("Depths are different. PRESENT needs the pixmap and the window have same depth\n");
- + free(reply);
- + LeaveCriticalSection(&present_priv->mutex_present);
- + return FALSE;
- + }
- + present_priv->last_target = target_msc;
- + present_priv->pixmap_present_pending++;
- + present_pixmap_priv->present_complete_pending++;
- + present_pixmap_priv->released = FALSE;
- + LeaveCriticalSection(&present_priv->mutex_present);
- + return TRUE;
- +}
- +
- +BOOL PRESENTWaitPixmapReleased(PRESENTPixmapPriv *present_pixmap_priv)
- +{
- + PRESENTpriv *present_priv = present_pixmap_priv->present_priv;
- +
- + EnterCriticalSection(&present_priv->mutex_present);
- +
- + PRESENTflush_events(present_priv, FALSE);
- +
- + /* The part with present_pixmap_priv->present_complete_pending is legacy behaviour.
- + * It matters for SwapEffectCopy with swapinterval > 0. */
- + while (!present_pixmap_priv->released || present_pixmap_priv->present_complete_pending)
- + {
- + /* Note: following if should not happen because we'll never
- + * use two PRESENTWaitPixmapReleased in parallels on same window.
- + * However it would make it work in that case */
- + if (present_priv->xcb_wait)
- + {
- + /* we allow only one thread to dispatch events */
- + EnterCriticalSection(&present_priv->mutex_xcb_wait);
- + /* here the other thread got an event but hasn't treated it yet */
- + LeaveCriticalSection(&present_priv->mutex_xcb_wait);
- + LeaveCriticalSection(&present_priv->mutex_present);
- + Sleep(10); /* Let it treat the event */
- + EnterCriticalSection(&present_priv->mutex_present);
- + }
- + else if (!PRESENTwait_events(present_priv, TRUE))
- + {
- + LeaveCriticalSection(&present_priv->mutex_present);
- + return FALSE;
- + }
- + }
- + LeaveCriticalSection(&present_priv->mutex_present);
- + return TRUE;
- +}
- +
- +BOOL PRESENTIsPixmapReleased(PRESENTPixmapPriv *present_pixmap_priv)
- +{
- + PRESENTpriv *present_priv = present_pixmap_priv->present_priv;
- + BOOL ret;
- +
- + EnterCriticalSection(&present_priv->mutex_present);
- +
- + PRESENTflush_events(present_priv, FALSE);
- +
- + ret = present_pixmap_priv->released;
- +
- + LeaveCriticalSection(&present_priv->mutex_present);
- + return ret;
- +}
- +
- +BOOL PRESENTWaitReleaseEvent(PRESENTpriv *present_priv)
- +{
- +
- + EnterCriticalSection(&present_priv->mutex_present);
- +
- + while (!present_priv->idle_notify_since_last_check)
- + {
- + /* Note: following if should not happen because we'll never
- + * use two PRESENTWaitPixmapReleased in parallels on same window.
- + * However it would make it work in that case */
- + if (present_priv->xcb_wait)
- + {
- + /* we allow only one thread to dispatch events */
- + EnterCriticalSection(&present_priv->mutex_xcb_wait);
- + /* here the other thread got an event but hasn't treated it yet */
- + LeaveCriticalSection(&present_priv->mutex_xcb_wait);
- + LeaveCriticalSection(&present_priv->mutex_present);
- + Sleep(10); /* Let it treat the event */
- + EnterCriticalSection(&present_priv->mutex_present);
- + }
- + else if (!PRESENTwait_events(present_priv, TRUE))
- + {
- + ERR("Issue in PRESENTWaitReleaseEvent\n");
- + LeaveCriticalSection(&present_priv->mutex_present);
- + return FALSE;
- + }
- + }
- + present_priv->idle_notify_since_last_check = FALSE;
- +
- + LeaveCriticalSection(&present_priv->mutex_present);
- + return TRUE;
- +}
- diff --git a/dlls/d3d9-nine/dri3.h b/dlls/d3d9-nine/dri3.h
- new file mode 100644
- index 0000000000..3c9309dedb
- --- /dev/null
- +++ b/dlls/d3d9-nine/dri3.h
- @@ -0,0 +1,91 @@
- +/*
- + * Wine X11DRV DRI3 interface
- + *
- + * Copyright 2014 Axel Davy
- + *
- + * 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
- + */
- +
- +#ifndef __WINE_DRI3_H
- +#define __WINE_DRI3_H
- +
- +#ifndef __WINE_CONFIG_H
- +# error You must include config.h to use this header
- +#endif
- +
- +#include <X11/Xlib.h>
- +#include <wingdi.h>
- +
- +BOOL DRI3CheckExtension(Display *dpy, int major, int minor);
- +
- +#ifdef D3D9NINE_DRI2
- +struct DRI2priv;
- +
- +BOOL DRI2FallbackInit(Display *dpy, struct DRI2priv **priv);
- +
- +void DRI2FallbackDestroy(struct DRI2priv *priv);
- +
- +BOOL DRI2FallbackCheckSupport(Display *dpy);
- +#endif
- +
- +BOOL PRESENTCheckExtension(Display *dpy, int major, int minor);
- +
- +BOOL DRI3Open(Display *dpy, int screen, int *device_fd);
- +
- +#ifdef D3D9NINE_DRI2
- +BOOL DRI2FallbackOpen(Display *dpy, int screen, int *device_fd);
- +#endif
- +
- +BOOL DRI3PixmapFromDmaBuf(Display *dpy, int screen, int fd, int width, int height,
- + int stride, int depth, int bpp, Pixmap *pixmap);
- +
- +BOOL DRI3DmaBufFromPixmap(Display *dpy, Pixmap pixmap, int *fd, int *width, int *height,
- + int *stride, int *depth, int *bpp);
- +
- +typedef struct PRESENTPriv PRESENTpriv;
- +typedef struct PRESENTPixmapPriv PRESENTPixmapPriv;
- +
- +BOOL PRESENTInit(Display *dpy, PRESENTpriv **present_priv);
- +
- +/* will clean properly and free all PRESENTPixmapPriv associated to PRESENTpriv.
- + * PRESENTPixmapPriv should not be freed by something else.
- + * If never a PRESENTPixmapPriv has to be destroyed,
- + * please destroy the current PRESENTpriv and create a new one.
- + * This will take care than all pixmaps are released */
- +void PRESENTDestroy(Display *dpy, PRESENTpriv *present_priv);
- +
- +BOOL PRESENTPixmapInit(PRESENTpriv *present_priv, Pixmap pixmap, PRESENTPixmapPriv **present_pixmap_priv);
- +
- +#ifdef D3D9NINE_DRI2
- +BOOL DRI2FallbackPRESENTPixmap(PRESENTpriv *present_priv, struct DRI2priv *priv,
- + int fd, int width, int height, int stride, int depth,
- + int bpp, PRESENTPixmapPriv **present_pixmap_priv);
- +#endif
- +
- +BOOL PRESENTTryFreePixmap(Display *dpy, PRESENTPixmapPriv *present_pixmap_priv);
- +
- +BOOL PRESENTHelperCopyFront(Display *dpy, PRESENTPixmapPriv *present_pixmap_priv);
- +
- +BOOL PRESENTPixmap(Display *dpy, XID window, PRESENTPixmapPriv *present_pixmap_priv,
- + const UINT PresentationInterval, const BOOL PresentAsync, const BOOL SwapEffectCopy,
- + const RECT *pSourceRect, const RECT *pDestRect, const RGNDATA *pDirtyRegion);
- +
- +BOOL PRESENTWaitPixmapReleased(PRESENTPixmapPriv *present_pixmap_priv);
- +
- +BOOL PRESENTIsPixmapReleased(PRESENTPixmapPriv *present_pixmap_priv);
- +
- +BOOL PRESENTWaitReleaseEvent(PRESENTpriv *present_priv);
- +
- +#endif /* __WINE_DRI3_H */
- diff --git a/dlls/d3d9-nine/present.c b/dlls/d3d9-nine/present.c
- new file mode 100644
- index 0000000000..2d9390a358
- --- /dev/null
- +++ b/dlls/d3d9-nine/present.c
- @@ -0,0 +1,1748 @@
- +/*
- + * Wine ID3DAdapter9 support functions
- + *
- + * Copyright 2013 Joakim Sindholt
- + * Christoph Bumiller
- + * Copyright 2014 Tiziano Bacocco
- + * David Heidelberger
- + * Copyright 2014-2015 Axel Davy
- + * Copyright 2015 Patrick Rudolph
- + *
- + * 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
- + */
- +
- +#include "config.h"
- +#include "wine/port.h"
- +#include "wine/debug.h"
- +
- +WINE_DEFAULT_DEBUG_CHANNEL(d3d9nine);
- +
- +#include <d3dadapter/drm.h>
- +#include <X11/Xutil.h>
- +
- +#include "dri3.h"
- +#include "wndproc.h"
- +
- +#include "wine/library.h" // for wine_dl*
- +#include "wine/unicode.h" // for strcpyW
- +
- +#ifndef D3DPRESENT_DONOTWAIT
- +#define D3DPRESENT_DONOTWAIT 0x00000001
- +#endif
- +
- +#define WINE_D3DADAPTER_DRIVER_PRESENT_VERSION_MAJOR 1
- +#if defined (ID3DPresent_SetPresentParameters2)
- +#define WINE_D3DADAPTER_DRIVER_PRESENT_VERSION_MINOR 3
- +#elif defined (ID3DPresent_ResolutionMismatch)
- +#define WINE_D3DADAPTER_DRIVER_PRESENT_VERSION_MINOR 2
- +#elif defined (ID3DPresent_GetWindowOccluded)
- +#define WINE_D3DADAPTER_DRIVER_PRESENT_VERSION_MINOR 1
- +#else
- +#define WINE_D3DADAPTER_DRIVER_PRESENT_VERSION_MINOR 0
- +#endif
- +
- +static const struct D3DAdapter9DRM *d3d9_drm = NULL;
- +#ifdef D3D9NINE_DRI2
- +static int is_dri2_fallback = 0;
- +#endif
- +
- +/* Start section of x11drv.h */
- +#define X11DRV_ESCAPE 6789
- +enum x11drv_escape_codes
- +{
- + X11DRV_SET_DRAWABLE, /* set current drawable for a DC */
- + X11DRV_GET_DRAWABLE, /* get current drawable for a DC */
- + X11DRV_START_EXPOSURES, /* start graphics exposures */
- + X11DRV_END_EXPOSURES, /* end graphics exposures */
- + X11DRV_FLUSH_GL_DRAWABLE /* flush changes made to the gl drawable */
- +};
- +
- +struct x11drv_escape_get_drawable
- +{
- + enum x11drv_escape_codes code; /* escape code (X11DRV_GET_DRAWABLE) */
- + Drawable drawable; /* X drawable */
- + Drawable gl_drawable; /* GL drawable */
- + int pixel_format; /* internal GL pixel format */
- +};
- +/* End section x11drv.h */
- +
- +static XContext d3d_hwnd_context;
- +static CRITICAL_SECTION context_section;
- +static CRITICAL_SECTION_DEBUG critsect_debug =
- +{
- + 0, 0, &context_section,
- + { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
- + 0, 0, { (DWORD_PTR)(__FILE__ ": context_section") }
- +};
- +static CRITICAL_SECTION context_section = { &critsect_debug, -1, 0, 0, 0, 0 };
- +
- +const GUID IID_ID3DPresent = { 0x77D60E80, 0xF1E6, 0x11DF, { 0x9E, 0x39, 0x95, 0x0C, 0xDF, 0xD7, 0x20, 0x85 } };
- +const GUID IID_ID3DPresentGroup = { 0xB9C3016E, 0xF32A, 0x11DF, { 0x9C, 0x18, 0x92, 0xEA, 0xDE, 0xD7, 0x20, 0x85 } };
- +
- +struct d3d_drawable
- +{
- + Drawable drawable; /* X11 drawable */
- + HDC hdc;
- + HWND wnd; /* HWND (for convenience) */
- +};
- +
- +struct DRI3Present
- +{
- + /* COM vtable */
- + void *vtable;
- + /* IUnknown reference count */
- + LONG refs;
- +
- + D3DPRESENT_PARAMETERS params;
- + HWND focus_wnd;
- + PRESENTpriv *present_priv;
- +#ifdef D3D9NINE_DRI2
- + struct DRI2priv *dri2_priv;
- +#endif
- +
- + WCHAR devname[32];
- + HCURSOR hCursor;
- +
- + DEVMODEW initial_mode;
- +
- + DWORD style;
- + DWORD style_ex;
- +
- + BOOL reapply_mode;
- + BOOL ex;
- + BOOL resolution_mismatch;
- + BOOL occluded;
- + BOOL drop_wnd_messages;
- + BOOL no_window_changes;
- + Display *gdi_display;
- +
- + UINT present_interval;
- + BOOL present_async;
- + BOOL present_swapeffectcopy;
- + BOOL allow_discard_delayed_release;
- + BOOL tear_free_discard;
- + struct d3d_drawable *d3d;
- +};
- +
- +struct D3DWindowBuffer
- +{
- + PRESENTPixmapPriv *present_pixmap_priv;
- +};
- +
- +static void free_d3dadapter_drawable(struct d3d_drawable *d3d)
- +{
- + ReleaseDC(d3d->wnd, d3d->hdc);
- + HeapFree(GetProcessHeap(), 0, d3d);
- +}
- +
- +static void destroy_d3dadapter_drawable(Display *gdi_display, HWND hwnd)
- +{
- + struct d3d_drawable *d3d;
- +
- + EnterCriticalSection(&context_section);
- + if (!XFindContext(gdi_display, (XID)hwnd,
- + d3d_hwnd_context, (char **)&d3d))
- + {
- + XDeleteContext(gdi_display, (XID)hwnd, d3d_hwnd_context);
- + free_d3dadapter_drawable(d3d);
- + }
- + LeaveCriticalSection(&context_section);
- +}
- +
- +static RECT DRI3Present_GetClientRecWindowRelative(HWND hwnd)
- +{
- + RECT rect;
- + RECT wnd;
- +
- + /* Get client space dimensions */
- + GetClientRect(hwnd, &rect);
- +
- + /* Get window in screen space */
- + GetWindowRect(hwnd, &wnd);
- +
- + /* Transform to offset */
- + MapWindowPoints(HWND_DESKTOP, hwnd, (LPPOINT) &wnd, 2);
- + wnd.top *= -1;
- + wnd.left *= -1;
- + wnd.bottom = wnd.top + rect.bottom;
- + wnd.right = wnd.left + rect.right;
- +
- + return wnd;
- +}
- +
- +static struct d3d_drawable *create_d3dadapter_drawable(HWND hwnd)
- +{
- + struct x11drv_escape_get_drawable extesc = { X11DRV_GET_DRAWABLE };
- + struct d3d_drawable *d3d;
- +
- + d3d = HeapAlloc(GetProcessHeap(), 0, sizeof(*d3d));
- + if (!d3d)
- + {
- + ERR("Couldn't allocate d3d_drawable.\n");
- + return NULL;
- + }
- +
- + d3d->hdc = GetDCEx(hwnd, 0, DCX_CACHE | DCX_CLIPSIBLINGS);
- + if (ExtEscape(d3d->hdc, X11DRV_ESCAPE, sizeof(extesc), (LPCSTR)&extesc,
- + sizeof(extesc), (LPSTR)&extesc) <= 0)
- + {
- + ERR("Unexpected error in X Drawable lookup (hwnd=%p, hdc=%p)\n", hwnd, d3d->hdc);
- + ReleaseDC(hwnd, d3d->hdc);
- + HeapFree(GetProcessHeap(), 0, d3d);
- + return NULL;
- + }
- +
- + d3d->drawable = extesc.drawable;
- + d3d->wnd = hwnd;
- +
- + return d3d;
- +}
- +
- +static struct d3d_drawable *get_d3d_drawable(Display *gdi_display, HWND hwnd)
- +{
- + struct d3d_drawable *d3d, *race;
- +
- + EnterCriticalSection(&context_section);
- + if (!XFindContext(gdi_display, (XID)hwnd, d3d_hwnd_context, (char **)&d3d))
- + {
- + return d3d;
- + }
- + LeaveCriticalSection(&context_section);
- +
- + TRACE("No d3d_drawable attached to hwnd %p, creating one.\n", hwnd);
- +
- + d3d = create_d3dadapter_drawable(hwnd);
- + if (!d3d)
- + return NULL;
- +
- + EnterCriticalSection(&context_section);
- + if (!XFindContext(gdi_display, (XID)hwnd,
- + d3d_hwnd_context, (char **)&race))
- + {
- + /* apparently someone beat us to creating this d3d drawable. Let's not
- + waste more time with X11 calls and just use theirs instead. */
- + free_d3dadapter_drawable(d3d);
- + return race;
- + }
- + XSaveContext(gdi_display, (XID)hwnd, d3d_hwnd_context, (char *)d3d);
- + return d3d;
- +}
- +
- +static void release_d3d_drawable(struct d3d_drawable *d3d)
- +{
- + if (!d3d)
- + ERR("Driver internal error: d3d_drawable is NULL\n");
- + LeaveCriticalSection(&context_section);
- +}
- +
- +static ULONG WINAPI DRI3Present_AddRef(struct DRI3Present *This)
- +{
- + ULONG refs = InterlockedIncrement(&This->refs);
- + TRACE("%p increasing refcount to %u.\n", This, refs);
- + return refs;
- +}
- +
- +static ULONG WINAPI DRI3Present_Release(struct DRI3Present *This)
- +{
- + ULONG refs = InterlockedDecrement(&This->refs);
- + TRACE("%p decreasing refcount to %u.\n", This, refs);
- + if (refs == 0)
- + {
- + /* dtor */
- + (void) nine_unregister_window(This->focus_wnd);
- + if (This->d3d)
- + destroy_d3dadapter_drawable(This->gdi_display, This->d3d->wnd);
- + ChangeDisplaySettingsExW(This->devname, &(This->initial_mode), 0, CDS_FULLSCREEN, NULL);
- + PRESENTDestroy(This->gdi_display, This->present_priv);
- +#ifdef D3D9NINE_DRI2
- + if (is_dri2_fallback)
- + DRI2FallbackDestroy(This->dri2_priv);
- +#endif
- + HeapFree(GetProcessHeap(), 0, This);
- + }
- + return refs;
- +}
- +
- +static HRESULT WINAPI DRI3Present_QueryInterface(struct DRI3Present *This,
- + REFIID riid, void **ppvObject)
- +{
- + if (!ppvObject)
- + return E_POINTER;
- +
- + if (IsEqualGUID(&IID_ID3DPresent, riid) ||
- + IsEqualGUID(&IID_IUnknown, riid))
- + {
- + *ppvObject = This;
- + DRI3Present_AddRef(This);
- + return S_OK;
- + }
- +
- + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
- + *ppvObject = NULL;
- +
- + return E_NOINTERFACE;
- +}
- +
- +static HRESULT DRI3Present_ChangePresentParameters(struct DRI3Present *This,
- + D3DPRESENT_PARAMETERS *params);
- +
- +static HRESULT WINAPI DRI3Present_SetPresentParameters(struct DRI3Present *This,
- + D3DPRESENT_PARAMETERS *pPresentationParameters,
- + D3DDISPLAYMODEEX *pFullscreenDisplayMode)
- +{
- + if (pFullscreenDisplayMode)
- + FIXME("Ignoring pFullscreenDisplayMode\n");
- + return DRI3Present_ChangePresentParameters(This, pPresentationParameters);
- +}
- +
- +static HRESULT WINAPI DRI3Present_D3DWindowBufferFromDmaBuf(struct DRI3Present *This,
- + int dmaBufFd, int width, int height, int stride, int depth,
- + int bpp, struct D3DWindowBuffer **out)
- +{
- + Pixmap pixmap;
- +
- +#ifdef D3D9NINE_DRI2
- + if (is_dri2_fallback)
- + {
- + *out = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- + sizeof(struct D3DWindowBuffer));
- + if (!DRI2FallbackPRESENTPixmap(This->present_priv, This->dri2_priv,
- + dmaBufFd, width, height, stride, depth,
- + bpp, &((*out)->present_pixmap_priv)))
- + {
- + ERR("DRI2FallbackPRESENTPixmap failed\n");
- + HeapFree(GetProcessHeap(), 0, *out);
- + return D3DERR_DRIVERINTERNALERROR;
- + }
- + return D3D_OK;
- + }
- +#endif
- + if (!DRI3PixmapFromDmaBuf(This->gdi_display, DefaultScreen(This->gdi_display),
- + dmaBufFd, width, height, stride, depth, bpp, &pixmap))
- + {
- + ERR("DRI3PixmapFromDmaBuf failed\n");
- + return D3DERR_DRIVERINTERNALERROR;
- + }
- +
- + *out = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- + sizeof(struct D3DWindowBuffer));
- + if (!PRESENTPixmapInit(This->present_priv, pixmap, &((*out)->present_pixmap_priv)))
- + {
- + ERR("PRESENTPixmapInit failed\n");
- + HeapFree(GetProcessHeap(), 0, *out);
- + return D3DERR_DRIVERINTERNALERROR;
- + }
- + return D3D_OK;
- +}
- +
- +static HRESULT WINAPI DRI3Present_DestroyD3DWindowBuffer(struct DRI3Present *This,
- + struct D3DWindowBuffer *buffer)
- +{
- + /* the pixmap is managed by the PRESENT backend.
- + * But if it can delete it right away, we may have
- + * better performance */
- + PRESENTTryFreePixmap(This->gdi_display, buffer->present_pixmap_priv);
- + HeapFree(GetProcessHeap(), 0, buffer);
- + return D3D_OK;
- +}
- +
- +static HRESULT WINAPI DRI3Present_WaitBufferReleased(struct DRI3Present *This,
- + struct D3DWindowBuffer *buffer)
- +{
- + if(!PRESENTWaitPixmapReleased(buffer->present_pixmap_priv))
- + {
- + ERR("PRESENTWaitPixmapReleased failed\n");
- + return D3DERR_DRIVERINTERNALERROR;
- + }
- + return D3D_OK;
- +}
- +
- +static HRESULT WINAPI DRI3Present_FrontBufferCopy(struct DRI3Present *This,
- + struct D3DWindowBuffer *buffer)
- +{
- +#ifdef D3D9NINE_DRI2
- + if (is_dri2_fallback)
- + return D3DERR_DRIVERINTERNALERROR;
- +#endif
- + if (PRESENTHelperCopyFront(This->gdi_display, buffer->present_pixmap_priv))
- + return D3D_OK;
- + else
- + return D3DERR_DRIVERINTERNALERROR;
- +}
- +
- +/* Try to detect client side window decorations by walking the X Drawable up.
- + * In case there's an intermediate Drawable, server side window decorations are used.
- + * TODO: Find a X11 function to query for window decorations.
- + */
- +static BOOL DRI3Present_HasClientSideWindowDecorations(struct DRI3Present *This,
- + HWND hwnd)
- +{
- + struct x11drv_escape_get_drawable extesc = { X11DRV_GET_DRAWABLE };
- + Window Wroot;
- + Window Wparent;
- + Window *Wchildren;
- + unsigned int numchildren;
- + HWND parent;
- + HDC hdc;
- + BOOL ret = TRUE;
- +
- + parent = GetParent(hwnd);
- + if (!parent)
- + parent = GetDesktopWindow();
- + if (!parent)
- + {
- + ERR("Unexpected error getting the parent hwnd (hwnd=%p)\n", hwnd);
- + return FALSE;
- + }
- +
- + hdc = GetDCEx(hwnd, 0, DCX_CACHE | DCX_CLIPSIBLINGS);
- + if (!hdc)
- + return FALSE;
- + if (ExtEscape(hdc, X11DRV_ESCAPE, sizeof(extesc), (LPCSTR)&extesc,
- + sizeof(extesc), (LPSTR)&extesc) <= 0)
- + {
- + ERR("Unexpected error in X Drawable lookup (hwnd=%p, hdc=%p)\n", hwnd, hdc);
- + ReleaseDC(hwnd, hdc);
- + return FALSE;
- + }
- + ReleaseDC(hwnd, hdc);
- +
- + if (XQueryTree(This->gdi_display, extesc.drawable, &Wroot, &Wparent, &Wchildren, &numchildren))
- + {
- + hdc = GetDCEx(parent, 0, DCX_CACHE | DCX_CLIPSIBLINGS);
- + if (!hdc)
- + return FALSE;
- +
- + if (ExtEscape(hdc, X11DRV_ESCAPE, sizeof(extesc), (LPCSTR)&extesc,
- + sizeof(extesc), (LPSTR)&extesc) <= 0)
- + {
- + ERR("Unexpected error in X Drawable lookup (hwnd=%p, hdc=%p)\n", parent, hdc);
- + ReleaseDC(parent, hdc);
- + return FALSE;
- + }
- + ReleaseDC(parent, hdc);
- +
- + if (Wparent != extesc.drawable)
- + {
- + /* Found at least one intermediate window */
- + ret = FALSE;
- + }
- + if (Wchildren)
- + free(Wchildren);
- + }
- +
- + return ret;
- +}
- +
- +static HRESULT WINAPI DRI3Present_PresentBuffer( struct DRI3Present *This,
- + struct D3DWindowBuffer *buffer, HWND hWndOverride, const RECT *pSourceRect,
- + const RECT *pDestRect, const RGNDATA *pDirtyRegion, DWORD Flags )
- +{
- + struct d3d_drawable *d3d;
- + RECT dest_translate;
- + RECT offset;
- + HWND hwnd;
- +
- + if (hWndOverride)
- + hwnd = hWndOverride;
- + else if (This->params.hDeviceWindow)
- + hwnd = This->params.hDeviceWindow;
- + else
- + hwnd = This->focus_wnd;
- +
- + d3d = get_d3d_drawable(This->gdi_display, hwnd);
- +
- + if (!d3d)
- + return D3DERR_DRIVERINTERNALERROR;
- +
- + /* TODO: should we use a list here instead ? */
- + if (This->d3d && (This->d3d->wnd != d3d->wnd))
- + destroy_d3dadapter_drawable(This->gdi_display, This->d3d->wnd);
- +
- + This->d3d = d3d;
- +
- + /* In case of client side window decorations we need to add an offset within
- + * the X drawable.
- + * FIXME: Call once on window style / size change */
- + if (DRI3Present_HasClientSideWindowDecorations(This, hwnd))
- + {
- + offset = DRI3Present_GetClientRecWindowRelative(hwnd);
- +
- + if ((offset.top != 0) || (offset.left != 0))
- + {
- + if (!pDestRect)
- + pDestRect = (const RECT *) &offset;
- + else
- + {
- + dest_translate.top = pDestRect->top + offset.top;
- + dest_translate.left = pDestRect->left + offset.left;
- + dest_translate.bottom = pDestRect->bottom + offset.bottom;
- + dest_translate.right = pDestRect->right + offset.right;
- + pDestRect = (const RECT *) &dest_translate;
- + }
- + }
- + }
- +
- + if (!PRESENTPixmap(This->gdi_display, d3d->drawable, buffer->present_pixmap_priv,
- + This->present_interval, This->present_async, This->present_swapeffectcopy,
- + pSourceRect, pDestRect, pDirtyRegion))
- + {
- + release_d3d_drawable(d3d);
- + return D3DERR_DRIVERINTERNALERROR;
- + }
- + release_d3d_drawable(d3d);
- +
- + return D3D_OK;
- +}
- +
- +/* Based on wine's wined3d_get_adapter_raster_status. */
- +static HRESULT WINAPI DRI3Present_GetRasterStatus( struct DRI3Present *This,
- + D3DRASTER_STATUS *pRasterStatus )
- +{
- + LONGLONG freq_per_frame, freq_per_line;
- + LARGE_INTEGER counter, freq_per_sec;
- + unsigned refresh_rate, height;
- +
- + TRACE("This=%p, pRasterStatus=%p\n", This, pRasterStatus);
- +
- + if (!QueryPerformanceCounter(&counter) || !QueryPerformanceFrequency(&freq_per_sec))
- + return D3DERR_INVALIDCALL;
- +
- + if (This->params.Windowed)
- + {
- + refresh_rate = This->initial_mode.dmDisplayFrequency;
- + height = This->initial_mode.dmPelsHeight;
- + }
- + else
- + {
- + refresh_rate = This->params.FullScreen_RefreshRateInHz;
- + height = This->params.BackBufferHeight;
- + }
- +
- + if (refresh_rate == 0)
- + refresh_rate = 60;
- +
- + TRACE("refresh_rate=%u, height=%u\n", refresh_rate, height);
- +
- + freq_per_frame = freq_per_sec.QuadPart / refresh_rate;
- + /* Assume 20 scan lines in the vertical blank. */
- + freq_per_line = freq_per_frame / (height + 20);
- + pRasterStatus->ScanLine = (counter.QuadPart % freq_per_frame) / freq_per_line;
- + if (pRasterStatus->ScanLine < height)
- + pRasterStatus->InVBlank = FALSE;
- + else
- + {
- + pRasterStatus->ScanLine = 0;
- + pRasterStatus->InVBlank = TRUE;
- + }
- +
- + TRACE("Returning fake value, InVBlank %u, ScanLine %u.\n",
- + pRasterStatus->InVBlank, pRasterStatus->ScanLine);
- +
- + return D3D_OK;
- +}
- +
- +static HRESULT WINAPI DRI3Present_GetDisplayMode( struct DRI3Present *This,
- + D3DDISPLAYMODEEX *pMode, D3DDISPLAYROTATION *pRotation )
- +{
- + DEVMODEW dm;
- +
- + ZeroMemory(&dm, sizeof(dm));
- + dm.dmSize = sizeof(dm);
- +
- + EnumDisplaySettingsExW(This->devname, ENUM_CURRENT_SETTINGS, &dm, 0);
- + pMode->Width = dm.dmPelsWidth;
- + pMode->Height = dm.dmPelsHeight;
- + pMode->RefreshRate = dm.dmDisplayFrequency;
- + pMode->ScanLineOrdering = (dm.dmDisplayFlags & DM_INTERLACED) ?
- + D3DSCANLINEORDERING_INTERLACED : D3DSCANLINEORDERING_PROGRESSIVE;
- +
- + /* XXX This is called "guessing" */
- + switch (dm.dmBitsPerPel)
- + {
- + case 32: pMode->Format = D3DFMT_X8R8G8B8; break;
- + case 24: pMode->Format = D3DFMT_R8G8B8; break;
- + case 16: pMode->Format = D3DFMT_R5G6B5; break;
- + default:
- + WARN("Unknown display format with %u bpp.\n", dm.dmBitsPerPel);
- + pMode->Format = D3DFMT_UNKNOWN;
- + }
- +
- + switch (dm.dmDisplayOrientation)
- + {
- + case DMDO_DEFAULT: *pRotation = D3DDISPLAYROTATION_IDENTITY; break;
- + case DMDO_90: *pRotation = D3DDISPLAYROTATION_90; break;
- + case DMDO_180: *pRotation = D3DDISPLAYROTATION_180; break;
- + case DMDO_270: *pRotation = D3DDISPLAYROTATION_270; break;
- + default:
- + WARN("Unknown display rotation %u.\n", dm.dmDisplayOrientation);
- + *pRotation = D3DDISPLAYROTATION_IDENTITY;
- + }
- +
- + return D3D_OK;
- +}
- +
- +static HRESULT WINAPI DRI3Present_GetPresentStats( struct DRI3Present *This, D3DPRESENTSTATS *pStats )
- +{
- + FIXME("(%p, %p), stub!\n", This, pStats);
- + return D3DERR_INVALIDCALL;
- +}
- +
- +static HRESULT WINAPI DRI3Present_GetCursorPos( struct DRI3Present *This, POINT *pPoint )
- +{
- + BOOL ok;
- + HWND draw_window;
- +
- + if (!pPoint)
- + return D3DERR_INVALIDCALL;
- +
- + draw_window = This->params.hDeviceWindow ?
- + This->params.hDeviceWindow : This->focus_wnd;
- +
- + ok = GetCursorPos(pPoint);
- + ok = ok && ScreenToClient(draw_window, pPoint);
- + return ok ? S_OK : D3DERR_DRIVERINTERNALERROR;
- +}
- +
- +static HRESULT WINAPI DRI3Present_SetCursorPos( struct DRI3Present *This, POINT *pPoint )
- +{
- + BOOL ok;
- + POINT real_pos;
- +
- + if (!pPoint)
- + return D3DERR_INVALIDCALL;
- +
- + ok = SetCursorPos(pPoint->x, pPoint->y);
- + if (!ok)
- + goto error;
- +
- + ok = GetCursorPos(&real_pos);
- + if (!ok || real_pos.x != pPoint->x || real_pos.y != pPoint->y)
- + goto error;
- +
- + return D3D_OK;
- +
- +error:
- + SetCursor(NULL); /* Hide cursor rather than put wrong pos */
- + return D3DERR_DRIVERINTERNALERROR;
- +}
- +
- +/* Note: assuming 32x32 cursor */
- +static HRESULT WINAPI DRI3Present_SetCursor( struct DRI3Present *This, void *pBitmap,
- + POINT *pHotspot, BOOL bShow )
- +{
- + if (pBitmap)
- + {
- + ICONINFO info;
- + HCURSOR cursor;
- +
- + DWORD mask[32];
- + memset(mask, ~0, sizeof(mask));
- +
- + if (!pHotspot)
- + return D3DERR_INVALIDCALL;
- + info.fIcon = FALSE;
- + info.xHotspot = pHotspot->x;
- + info.yHotspot = pHotspot->y;
- + info.hbmMask = CreateBitmap(32, 32, 1, 1, mask);
- + info.hbmColor = CreateBitmap(32, 32, 1, 32, pBitmap);
- +
- + cursor = CreateIconIndirect(&info);
- + if (info.hbmMask) DeleteObject(info.hbmMask);
- + if (info.hbmColor) DeleteObject(info.hbmColor);
- + if (cursor)
- + DestroyCursor(This->hCursor);
- + This->hCursor = cursor;
- + }
- + SetCursor(bShow ? This->hCursor : NULL);
- +
- + return D3D_OK;
- +}
- +
- +static HRESULT WINAPI DRI3Present_SetGammaRamp( struct DRI3Present *This,
- + const D3DGAMMARAMP *pRamp, HWND hWndOverride )
- +{
- + HWND hWnd = hWndOverride ? hWndOverride : This->focus_wnd;
- + HDC hdc;
- + BOOL ok;
- + if (!pRamp)
- + return D3DERR_INVALIDCALL;
- +
- + hdc = GetDC(hWnd);
- + ok = SetDeviceGammaRamp(hdc, (void *)pRamp);
- + ReleaseDC(hWnd, hdc);
- + return ok ? D3D_OK : D3DERR_DRIVERINTERNALERROR;
- +}
- +
- +static HRESULT WINAPI DRI3Present_GetWindowInfo( struct DRI3Present *This,
- + HWND hWnd, int *width, int *height, int *depth )
- +{
- + HRESULT hr;
- + RECT pRect;
- +
- + if (!hWnd)
- + hWnd = This->focus_wnd;
- + hr = GetClientRect(hWnd, &pRect);
- + if (!hr)
- + return D3DERR_INVALIDCALL;
- + *width = pRect.right - pRect.left;
- + *height = pRect.bottom - pRect.top;
- + *depth = 24; //TODO
- + return D3D_OK;
- +}
- +
- +#if WINE_D3DADAPTER_DRIVER_PRESENT_VERSION_MINOR >= 1
- +static BOOL WINAPI DRI3Present_GetWindowOccluded(struct DRI3Present *This)
- +{
- + return This->occluded;
- +}
- +#endif
- +
- +#if WINE_D3DADAPTER_DRIVER_PRESENT_VERSION_MINOR >= 2
- +static BOOL WINAPI DRI3Present_ResolutionMismatch(struct DRI3Present *This)
- +{
- + /* The resolution might change due to a third party app.
- + * Poll this function to get the device's resolution match.
- + * A device reset is required to restore the requested resolution.
- + */
- + return This->resolution_mismatch;
- +}
- +
- +static HANDLE WINAPI DRI3Present_CreateThread( struct DRI3Present *This,
- + void *pThreadfunc, void *pParam )
- +{
- + LPTHREAD_START_ROUTINE lpStartAddress =
- + (LPTHREAD_START_ROUTINE) pThreadfunc;
- +
- + return CreateThread(NULL, 0, lpStartAddress, pParam, 0, NULL);
- +}
- +
- +static BOOL WINAPI DRI3Present_WaitForThread( struct DRI3Present *This, HANDLE thread )
- +{
- + DWORD ExitCode = 0;
- + while (GetExitCodeThread(thread, &ExitCode) && ExitCode == STILL_ACTIVE)
- + Sleep(10);
- +
- + return TRUE;
- +}
- +#endif
- +
- +#if WINE_D3DADAPTER_DRIVER_PRESENT_VERSION_MINOR >= 3
- +static HRESULT WINAPI DRI3Present_SetPresentParameters2( struct DRI3Present *This, D3DPRESENT_PARAMETERS2 *pParams )
- +{
- + This->allow_discard_delayed_release = pParams->AllowDISCARDDelayedRelease;
- + This->tear_free_discard = pParams->AllowDISCARDDelayedRelease && pParams->TearFreeDISCARD;
- + return D3D_OK;
- +}
- +
- +static BOOL WINAPI DRI3Present_IsBufferReleased( struct DRI3Present *This, struct D3DWindowBuffer *buffer )
- +{
- + return PRESENTIsPixmapReleased(buffer->present_pixmap_priv);
- +}
- +
- +static HRESULT WINAPI DRI3Present_WaitBufferReleaseEvent( struct DRI3Present *This )
- +{
- + PRESENTWaitReleaseEvent(This->present_priv);
- + return D3D_OK;
- +}
- +#endif
- +
- +/*----------*/
- +
- +static ID3DPresentVtbl DRI3Present_vtable = {
- + (void *)DRI3Present_QueryInterface,
- + (void *)DRI3Present_AddRef,
- + (void *)DRI3Present_Release,
- + (void *)DRI3Present_SetPresentParameters,
- + (void *)DRI3Present_D3DWindowBufferFromDmaBuf,
- + (void *)DRI3Present_DestroyD3DWindowBuffer,
- + (void *)DRI3Present_WaitBufferReleased,
- + (void *)DRI3Present_FrontBufferCopy,
- + (void *)DRI3Present_PresentBuffer,
- + (void *)DRI3Present_GetRasterStatus,
- + (void *)DRI3Present_GetDisplayMode,
- + (void *)DRI3Present_GetPresentStats,
- + (void *)DRI3Present_GetCursorPos,
- + (void *)DRI3Present_SetCursorPos,
- + (void *)DRI3Present_SetCursor,
- + (void *)DRI3Present_SetGammaRamp,
- + (void *)DRI3Present_GetWindowInfo,
- +#if WINE_D3DADAPTER_DRIVER_PRESENT_VERSION_MINOR >= 1
- + (void *)DRI3Present_GetWindowOccluded,
- +#endif
- +#if WINE_D3DADAPTER_DRIVER_PRESENT_VERSION_MINOR >= 2
- + (void *)DRI3Present_ResolutionMismatch,
- + (void *)DRI3Present_CreateThread,
- + (void *)DRI3Present_WaitForThread,
- +#endif
- +#if WINE_D3DADAPTER_DRIVER_PRESENT_VERSION_MINOR >= 3
- + (void *)DRI3Present_SetPresentParameters2,
- + (void *)DRI3Present_IsBufferReleased,
- + (void *)DRI3Present_WaitBufferReleaseEvent,
- +#endif
- +};
- +
- +/* The following code is based on WINE's wined3d/device.c and
- + * wined3d/swapchain.c and WINE's d3d9 files. */
- +
- +static LONG fullscreen_style(LONG style)
- +{
- + /* Make sure the window is managed, otherwise we won't get keyboard input. */
- + style |= WS_POPUP | WS_SYSMENU;
- + style &= ~(WS_CAPTION | WS_THICKFRAME);
- +
- + return style;
- +}
- +
- +static LONG fullscreen_exstyle(LONG exstyle)
- +{
- + /* Filter out window decorations. */
- + exstyle &= ~(WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE);
- +
- + return exstyle;
- +}
- +
- +static HRESULT DRI3Present_ChangeDisplaySettingsIfNeccessary(struct DRI3Present *This, DEVMODEW *new_mode)
- +{
- + DEVMODEW current_mode;
- + LONG hr;
- +
- + /* Filter invalid resolution */
- + if (!new_mode->dmPelsWidth || !new_mode->dmPelsHeight)
- + return D3DERR_INVALIDCALL;
- +
- + /* Ignore invalid frequency requested */
- + if (new_mode->dmDisplayFrequency > 1000)
- + new_mode->dmDisplayFrequency = 0;
- +
- + ZeroMemory(¤t_mode, sizeof(DEVMODEW));
- + current_mode.dmSize = sizeof(DEVMODEW);
- + /* Only change the mode if necessary. */
- + if (!EnumDisplaySettingsW(This->devname, ENUM_CURRENT_SETTINGS, ¤t_mode))
- + ERR("Failed to get current display mode.\n");
- + else if (current_mode.dmPelsWidth != new_mode->dmPelsWidth
- + || current_mode.dmPelsHeight != new_mode->dmPelsHeight
- + || (current_mode.dmDisplayFrequency != new_mode->dmDisplayFrequency
- + && (new_mode->dmFields & DM_DISPLAYFREQUENCY)))
- + {
- + hr = ChangeDisplaySettingsExW(This->devname, new_mode, 0, CDS_FULLSCREEN, NULL);
- + if (hr != DISP_CHANGE_SUCCESSFUL)
- + {
- + /* try again without display RefreshRate */
- + if (new_mode->dmFields & DM_DISPLAYFREQUENCY)
- + {
- + new_mode->dmFields &= ~DM_DISPLAYFREQUENCY;
- + new_mode->dmDisplayFrequency = 0;
- + hr = ChangeDisplaySettingsExW(This->devname, new_mode, 0, CDS_FULLSCREEN, NULL);
- + if (hr != DISP_CHANGE_SUCCESSFUL)
- + {
- + ERR("ChangeDisplaySettingsExW failed with 0x%08X\n", hr);
- + return D3DERR_INVALIDCALL;
- + }
- + }
- + else
- + {
- + ERR("ChangeDisplaySettingsExW failed with 0x%08X\n", hr);
- + return D3DERR_INVALIDCALL;
- + }
- + }
- + }
- + return D3D_OK;
- +}
- +
- +LRESULT device_process_message(struct DRI3Present *present, HWND window, BOOL unicode,
- + UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc)
- +{
- + boolean drop_wnd_messages;
- + DEVMODEW current_mode;
- + DEVMODEW new_mode;
- +
- + TRACE("Got message: window %p, message %#x, wparam %#lx, lparam %#lx.\n",
- + window, message, wparam, lparam);
- +
- + if (present->drop_wnd_messages && message != WM_DISPLAYCHANGE)
- + {
- + TRACE("Filtering message: window %p, message %#x, wparam %#lx, lparam %#lx.\n",
- + window, message, wparam, lparam);
- + if (unicode)
- + return DefWindowProcW(window, message, wparam, lparam);
- + else
- + return DefWindowProcA(window, message, wparam, lparam);
- + }
- +
- + if (message == WM_DESTROY)
- + {
- + TRACE("unregister window %p.\n", window);
- + (void) nine_unregister_window(window);
- + }
- + else if (message == WM_DISPLAYCHANGE)
- + {
- + /* Ex restores display mode, while non Ex requires the
- + * user to call Device::Reset() */
- + ZeroMemory(¤t_mode, sizeof(DEVMODEW));
- + current_mode.dmSize = sizeof(current_mode);
- + if (!present->ex &&
- + !present->params.Windowed &&
- + present->params.hDeviceWindow &&
- + EnumDisplaySettingsW(present->devname, ENUM_CURRENT_SETTINGS, ¤t_mode) &&
- + (current_mode.dmPelsWidth != present->params.BackBufferWidth ||
- + current_mode.dmPelsHeight != present->params.BackBufferHeight))
- + {
- + present->resolution_mismatch = TRUE;
- + }
- + else
- + {
- + present->resolution_mismatch = FALSE;
- + }
- + }
- + else if (message == WM_ACTIVATEAPP)
- + {
- + drop_wnd_messages = present->drop_wnd_messages;
- + present->drop_wnd_messages = TRUE;
- +
- + if (wparam == WA_INACTIVE)
- + {
- + present->occluded = TRUE;
- + present->reapply_mode = TRUE;
- +
- + ZeroMemory(&new_mode, sizeof(DEVMODEW));
- + new_mode.dmSize = sizeof(new_mode);
- + if (EnumDisplaySettingsW(present->devname, ENUM_REGISTRY_SETTINGS, &new_mode))
- + DRI3Present_ChangeDisplaySettingsIfNeccessary(present, &new_mode);
- +
- + if (!present->no_window_changes &&
- + IsWindowVisible(present->params.hDeviceWindow))
- + ShowWindow(present->params.hDeviceWindow, SW_MINIMIZE);
- + }
- + else
- + {
- + present->occluded = FALSE;
- +
- + if (!present->no_window_changes)
- + {
- + /* restore window */
- + SetWindowPos(present->params.hDeviceWindow, NULL, 0, 0,
- + present->params.BackBufferWidth, present->params.BackBufferHeight,
- + SWP_NOACTIVATE | SWP_NOZORDER);
- + }
- +
- + if (present->ex)
- + {
- + ZeroMemory(&new_mode, sizeof(DEVMODEW));
- + new_mode.dmSize = sizeof(new_mode);
- + new_mode.dmPelsWidth = present->params.BackBufferWidth;
- + new_mode.dmPelsHeight = present->params.BackBufferHeight;
- + new_mode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
- + if (present->params.FullScreen_RefreshRateInHz)
- + {
- + new_mode.dmFields |= DM_DISPLAYFREQUENCY;
- + new_mode.dmDisplayFrequency = present->params.FullScreen_RefreshRateInHz;
- + }
- + DRI3Present_ChangeDisplaySettingsIfNeccessary(present, &new_mode);
- + }
- + }
- + present->drop_wnd_messages = drop_wnd_messages;
- + }
- + else if (message == WM_SYSCOMMAND)
- + {
- + if (wparam == SC_RESTORE)
- + {
- + if (unicode)
- + DefWindowProcW(window, message, wparam, lparam);
- + else
- + DefWindowProcA(window, message, wparam, lparam);
- + }
- + }
- +
- + if (unicode)
- + return CallWindowProcW(proc, window, message, wparam, lparam);
- + else
- + return CallWindowProcA(proc, window, message, wparam, lparam);
- +}
- +
- +static void setup_fullscreen_window(struct DRI3Present *This,
- + HWND hwnd, int w, int h)
- +{
- + boolean drop_wnd_messages;
- + LONG style, style_ex;
- +
- + This->style = GetWindowLongW(hwnd, GWL_STYLE);
- + This->style_ex = GetWindowLongW(hwnd, GWL_EXSTYLE);
- +
- + style = fullscreen_style(This->style);
- + style_ex = fullscreen_exstyle(This->style_ex);
- +
- + drop_wnd_messages = This->drop_wnd_messages;
- + This->drop_wnd_messages = TRUE;
- +
- + SetWindowLongW(hwnd, GWL_STYLE, style);
- + SetWindowLongW(hwnd, GWL_EXSTYLE, style_ex);
- +
- + SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, w, h,
- + SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE);
- +
- + This->drop_wnd_messages = drop_wnd_messages;
- +}
- +
- +static void move_fullscreen_window(struct DRI3Present *This,
- + HWND hwnd, int w, int h)
- +{
- + boolean drop_wnd_messages;
- + LONG style, style_ex;
- +
- + /* move draw window back to place */
- +
- + style = GetWindowLongW(hwnd, GWL_STYLE);
- + style_ex = GetWindowLongW(hwnd, GWL_EXSTYLE);
- +
- + style = fullscreen_style(style);
- + style_ex = fullscreen_exstyle(style_ex);
- +
- + drop_wnd_messages = This->drop_wnd_messages;
- + This->drop_wnd_messages = TRUE;
- + SetWindowLongW(hwnd, GWL_STYLE, style);
- + SetWindowLongW(hwnd, GWL_EXSTYLE, style_ex);
- + SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, w, h,
- + SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE);
- + This->drop_wnd_messages = drop_wnd_messages;
- +}
- +
- +static void restore_fullscreen_window(struct DRI3Present *This,
- + HWND hwnd)
- +{
- + boolean drop_wnd_messages;
- + LONG style, style_ex;
- +
- + /* switch from fullscreen to window */
- + style = GetWindowLongW(hwnd, GWL_STYLE);
- + style_ex = GetWindowLongW(hwnd, GWL_EXSTYLE);
- + /* These flags are set by us, not the
- + * application, and we want to ignore them in the test below, since it's
- + * not the application's fault that they changed. Additionally, we want to
- + * preserve the current status of these flags (i.e. don't restore them) to
- + * more closely emulate the behavior of Direct3D, which leaves these flags
- + * alone when returning to windowed mode. */
- + This->style ^= (This->style ^ style) & WS_VISIBLE;
- + This->style_ex ^= (This->style_ex ^ style_ex) & WS_EX_TOPMOST;
- +
- + /* Only restore the style if the application didn't modify it during the
- + * fullscreen phase. Some applications change it before calling Reset()
- + * when switching between windowed and fullscreen modes (HL2), some
- + * depend on the original style (Eve Online). */
- + drop_wnd_messages = This->drop_wnd_messages;
- + This->drop_wnd_messages = TRUE;
- + if (style == fullscreen_style(This->style) &&
- + style_ex == fullscreen_exstyle(This->style_ex))
- + {
- + SetWindowLongW(hwnd, GWL_STYLE, This->style);
- + SetWindowLongW(hwnd, GWL_EXSTYLE, This->style_ex);
- + }
- + SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED |
- + SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
- + SWP_NOACTIVATE);
- + This->drop_wnd_messages = drop_wnd_messages;
- +
- + This->style = 0;
- + This->style_ex = 0;
- +}
- +
- +static void DRI3Present_UpdatePresentationInterval(struct DRI3Present *This)
- +{
- + switch(This->params.PresentationInterval)
- + {
- + case D3DPRESENT_INTERVAL_DEFAULT:
- + case D3DPRESENT_INTERVAL_ONE:
- + This->present_interval = 1;
- + This->present_async = FALSE;
- + break;
- + case D3DPRESENT_INTERVAL_TWO:
- + This->present_interval = 2;
- + This->present_async = FALSE;
- + break;
- + case D3DPRESENT_INTERVAL_THREE:
- + This->present_interval = 3;
- + This->present_async = FALSE;
- + break;
- + case D3DPRESENT_INTERVAL_FOUR:
- + This->present_interval = 4;
- + This->present_async = FALSE;
- + break;
- + case D3DPRESENT_INTERVAL_IMMEDIATE:
- + default:
- + This->present_interval = 0;
- + This->present_async =
- + !(This->params.SwapEffect == D3DSWAPEFFECT_DISCARD &&
- + This->tear_free_discard);
- + break;
- + }
- +
- + /* D3DSWAPEFFECT_COPY: Force Copy.
- + * This->present_interval == 0: Force Copy to have buffers
- + * release as soon as possible (the display server/compositor
- + * won't hold any buffer), unless DISCARD and
- + * allow_discard_delayed_release */
- + This->present_swapeffectcopy =
- + This->params.SwapEffect == D3DSWAPEFFECT_COPY ||
- + (This->present_interval == 0 &&
- + !(This->params.SwapEffect == D3DSWAPEFFECT_DISCARD &&
- + This->allow_discard_delayed_release));
- +}
- +
- +static HRESULT DRI3Present_ChangePresentParameters(struct DRI3Present *This,
- + D3DPRESENT_PARAMETERS *params)
- +{
- + HWND focus_window = This->focus_wnd ? This->focus_wnd : params->hDeviceWindow;
- + RECT rect;
- + DEVMODEW new_mode;
- + HRESULT hr;
- + boolean drop_wnd_messages;
- +
- + TRACE("This=%p, params=%p, focus_window=%p, params->hDeviceWindow=%p\n",
- + This, params, focus_window, params->hDeviceWindow);
- +
- + This->params.SwapEffect = params->SwapEffect;
- + This->params.AutoDepthStencilFormat = params->AutoDepthStencilFormat;
- + This->params.Flags = params->Flags;
- + This->params.FullScreen_RefreshRateInHz = params->FullScreen_RefreshRateInHz;
- + This->params.PresentationInterval = params->PresentationInterval;
- + This->params.EnableAutoDepthStencil = params->EnableAutoDepthStencil;
- + if (!params->hDeviceWindow)
- + params->hDeviceWindow = This->params.hDeviceWindow;
- + else
- + This->params.hDeviceWindow = params->hDeviceWindow;
- +
- + if ((This->params.BackBufferWidth != params->BackBufferWidth) ||
- + (This->params.BackBufferHeight != params->BackBufferHeight) ||
- + (This->params.Windowed != params->Windowed) ||
- + This->reapply_mode)
- + {
- + This->reapply_mode = FALSE;
- +
- + if (!params->Windowed)
- + {
- + TRACE("Setting fullscreen mode: %dx%d@%d\n", params->BackBufferWidth,
- + params->BackBufferHeight, params->FullScreen_RefreshRateInHz);
- +
- + /* switch display mode */
- + ZeroMemory(&new_mode, sizeof(DEVMODEW));
- + new_mode.dmPelsWidth = params->BackBufferWidth;
- + new_mode.dmPelsHeight = params->BackBufferHeight;
- + new_mode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
- + if (params->FullScreen_RefreshRateInHz)
- + {
- + new_mode.dmFields |= DM_DISPLAYFREQUENCY;
- + new_mode.dmDisplayFrequency = params->FullScreen_RefreshRateInHz;
- + }
- + new_mode.dmSize = sizeof(DEVMODEW);
- + hr = DRI3Present_ChangeDisplaySettingsIfNeccessary(This, &new_mode);
- + if (FAILED(hr))
- + return hr;
- +
- + /* Dirty as BackBufferWidth and BackBufferHeight hasn't been set yet */
- + This->resolution_mismatch = FALSE;
- + }
- + else if(!This->params.Windowed && params->Windowed)
- + {
- + TRACE("Setting fullscreen mode: %dx%d@%d\n", This->initial_mode.dmPelsWidth,
- + This->initial_mode.dmPelsHeight, This->initial_mode.dmDisplayFrequency);
- +
- + hr = DRI3Present_ChangeDisplaySettingsIfNeccessary(This, &This->initial_mode);
- + if (FAILED(hr))
- + return hr;
- +
- + /* Dirty as BackBufferWidth and BackBufferHeight hasn't been set yet */
- + This->resolution_mismatch = FALSE;
- + }
- +
- + if (This->params.Windowed)
- + {
- + if (!params->Windowed)
- + {
- + /* switch from window to fullscreen */
- + if (!nine_register_window(focus_window, This))
- + return D3DERR_INVALIDCALL;
- +
- + SetWindowPos(focus_window, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
- +
- + setup_fullscreen_window(This, params->hDeviceWindow,
- + params->BackBufferWidth, params->BackBufferHeight);
- + }
- + }
- + else
- + {
- + if (!params->Windowed)
- + {
- + /* switch from fullscreen to fullscreen */
- + drop_wnd_messages = This->drop_wnd_messages;
- + This->drop_wnd_messages = TRUE;
- + MoveWindow(params->hDeviceWindow, 0, 0,
- + params->BackBufferWidth,
- + params->BackBufferHeight,
- + TRUE);
- + This->drop_wnd_messages = drop_wnd_messages;
- + }
- + else if (This->style || This->style_ex)
- + {
- + restore_fullscreen_window(This, params->hDeviceWindow);
- + }
- +
- + if (params->Windowed && !nine_unregister_window(focus_window))
- + ERR("Window %p is not registered with nine.\n", focus_window);
- + }
- + This->params.Windowed = params->Windowed;
- + }
- + else if (!params->Windowed)
- + {
- + move_fullscreen_window(This, params->hDeviceWindow, params->BackBufferWidth, params->BackBufferHeight);
- + }
- + else
- + {
- + TRACE("Nothing changed.\n");
- + }
- + if (!params->BackBufferWidth || !params->BackBufferHeight) {
- + if (!params->Windowed)
- + return D3DERR_INVALIDCALL;
- +
- + if (!GetClientRect(params->hDeviceWindow, &rect))
- + return D3DERR_INVALIDCALL;
- +
- + if (params->BackBufferWidth == 0)
- + params->BackBufferWidth = rect.right - rect.left;
- +
- + if (params->BackBufferHeight == 0)
- + params->BackBufferHeight = rect.bottom - rect.top;
- + }
- +
- + /* Set as last in case of failed reset those aren't updated */
- + This->params.BackBufferWidth = params->BackBufferWidth;
- + This->params.BackBufferHeight = params->BackBufferHeight;
- + This->params.BackBufferFormat = params->BackBufferFormat;
- + This->params.BackBufferCount = params->BackBufferCount;
- + This->params.MultiSampleType = params->MultiSampleType;
- + This->params.MultiSampleQuality = params->MultiSampleQuality;
- +
- + DRI3Present_UpdatePresentationInterval(This);
- +
- + return D3D_OK;
- +}
- +
- +/* The following code isn't based on WINE's wined3d or d3d9. */
- +
- +static HRESULT DRI3Present_new(Display *gdi_display, const WCHAR *devname,
- + D3DPRESENT_PARAMETERS *params, HWND focus_wnd, struct DRI3Present **out,
- + boolean ex, boolean no_window_changes)
- +{
- + struct DRI3Present *This;
- + HWND focus_window;
- + DEVMODEW new_mode;
- + HRESULT hr;
- + RECT rect;
- +
- + if (!focus_wnd && !params->hDeviceWindow)
- + {
- + ERR("No focus HWND specified for presentation backend.\n");
- + return D3DERR_INVALIDCALL;
- + }
- +
- + This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- + sizeof(struct DRI3Present));
- + if (!This)
- + {
- + ERR("Out of memory.\n");
- + return E_OUTOFMEMORY;
- + }
- +
- + This->gdi_display = gdi_display;
- + This->vtable = &DRI3Present_vtable;
- + This->refs = 1;
- + This->focus_wnd = focus_wnd;
- + This->ex = ex;
- + This->no_window_changes = no_window_changes;
- +
- + /* store current resolution */
- + ZeroMemory(&(This->initial_mode), sizeof(This->initial_mode));
- + This->initial_mode.dmSize = sizeof(This->initial_mode);
- + EnumDisplaySettingsExW(This->devname, ENUM_CURRENT_SETTINGS, &(This->initial_mode), 0);
- +
- + if (!params->hDeviceWindow)
- + params->hDeviceWindow = This->focus_wnd;
- +
- + if (!params->Windowed) {
- + focus_window = This->focus_wnd ? This->focus_wnd : params->hDeviceWindow;
- +
- + if (!nine_register_window(focus_window, This))
- + return D3DERR_INVALIDCALL;
- +
- + SetWindowPos(focus_window, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
- +
- + /* switch display mode */
- + ZeroMemory(&new_mode, sizeof(DEVMODEW));
- + new_mode.dmSize = sizeof(DEVMODEW);
- + new_mode.dmPelsWidth = params->BackBufferWidth;
- + new_mode.dmPelsHeight = params->BackBufferHeight;
- + new_mode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
- +
- + if (params->FullScreen_RefreshRateInHz)
- + {
- + new_mode.dmFields |= DM_DISPLAYFREQUENCY;
- + new_mode.dmDisplayFrequency = params->FullScreen_RefreshRateInHz;
- + }
- +
- + hr = DRI3Present_ChangeDisplaySettingsIfNeccessary(This, &new_mode);
- + if (FAILED(hr))
- + {
- + nine_unregister_window(focus_window);
- + HeapFree(GetProcessHeap(), 0, This);
- + return hr;
- + }
- +
- + /* Dirty as BackBufferWidth and BackBufferHeight hasn't been set yet */
- + This->resolution_mismatch = FALSE;
- +
- + setup_fullscreen_window(This, params->hDeviceWindow,
- + params->BackBufferWidth, params->BackBufferHeight);
- + } else {
- + GetClientRect(params->hDeviceWindow, &rect);
- + if (!params->BackBufferWidth || !params->BackBufferHeight) {
- +
- + if (params->BackBufferWidth == 0)
- + params->BackBufferWidth = rect.right - rect.left;
- +
- + if (params->BackBufferHeight == 0)
- + params->BackBufferHeight = rect.bottom - rect.top;
- + }
- + }
- +
- + This->params = *params;
- +
- + DRI3Present_UpdatePresentationInterval(This);
- +
- + strcpyW(This->devname, devname);
- +
- + PRESENTInit(gdi_display, &(This->present_priv));
- +#ifdef D3D9NINE_DRI2
- + if (is_dri2_fallback && !DRI2FallbackInit(gdi_display, &(This->dri2_priv)))
- + return D3DERR_INVALIDCALL;
- +#endif
- + *out = This;
- +
- + return D3D_OK;
- +}
- +
- +struct DRI3PresentGroup
- +{
- + /* COM vtable */
- + void *vtable;
- + /* IUnknown reference count */
- + LONG refs;
- +
- + boolean ex;
- + struct DRI3Present **present_backends;
- + unsigned npresent_backends;
- + Display *gdi_display;
- + boolean no_window_changes;
- +};
- +
- +static ULONG WINAPI DRI3PresentGroup_AddRef(struct DRI3PresentGroup *This)
- +{
- + ULONG refs = InterlockedIncrement(&This->refs);
- + TRACE("%p increasing refcount to %u.\n", This, refs);
- + return refs;
- +}
- +
- +static ULONG WINAPI DRI3PresentGroup_Release(struct DRI3PresentGroup *This)
- +{
- + ULONG refs = InterlockedDecrement(&This->refs);
- + TRACE("%p decreasing refcount to %u.\n", This, refs);
- + if (refs == 0)
- + {
- + unsigned i;
- + if (This->present_backends)
- + {
- + for (i = 0; i < This->npresent_backends; ++i)
- + {
- + if (This->present_backends[i])
- + DRI3Present_Release(This->present_backends[i]);
- + }
- + HeapFree(GetProcessHeap(), 0, This->present_backends);
- + }
- + HeapFree(GetProcessHeap(), 0, This);
- + }
- + return refs;
- +}
- +
- +static HRESULT WINAPI DRI3PresentGroup_QueryInterface(struct DRI3PresentGroup *This,
- + REFIID riid, void **ppvObject )
- +{
- + if (!ppvObject)
- + return E_POINTER;
- + if (IsEqualGUID(&IID_ID3DPresentGroup, riid) ||
- + IsEqualGUID(&IID_IUnknown, riid))
- + {
- + *ppvObject = This;
- + DRI3PresentGroup_AddRef(This);
- + return S_OK;
- + }
- +
- + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
- + *ppvObject = NULL;
- +
- + return E_NOINTERFACE;
- +}
- +
- +static UINT WINAPI DRI3PresentGroup_GetMultiheadCount(struct DRI3PresentGroup *This)
- +{
- + FIXME("(%p), stub!\n", This);
- + return 1;
- +}
- +
- +static HRESULT WINAPI DRI3PresentGroup_GetPresent(struct DRI3PresentGroup *This,
- + UINT Index, ID3DPresent **ppPresent)
- +{
- + if (Index >= DRI3PresentGroup_GetMultiheadCount(This))
- + {
- + ERR("Index >= MultiHeadCount\n");
- + return D3DERR_INVALIDCALL;
- + }
- + DRI3Present_AddRef(This->present_backends[Index]);
- + *ppPresent = (ID3DPresent *)This->present_backends[Index];
- +
- + return D3D_OK;
- +}
- +
- +static HRESULT WINAPI DRI3PresentGroup_CreateAdditionalPresent(struct DRI3PresentGroup *This,
- + D3DPRESENT_PARAMETERS *pPresentationParameters, ID3DPresent **ppPresent)
- +{
- + HRESULT hr;
- + hr = DRI3Present_new(This->gdi_display, This->present_backends[0]->devname,
- + pPresentationParameters, 0, (struct DRI3Present **)ppPresent,
- + This->ex, This->no_window_changes);
- +
- + return hr;
- +}
- +
- +static void WINAPI DRI3PresentGroup_GetVersion(struct DRI3PresentGroup *This,
- + int *major, int *minor)
- +{
- + *major = WINE_D3DADAPTER_DRIVER_PRESENT_VERSION_MAJOR;
- + *minor = WINE_D3DADAPTER_DRIVER_PRESENT_VERSION_MINOR;
- +}
- +
- +static ID3DPresentGroupVtbl DRI3PresentGroup_vtable = {
- + (void *)DRI3PresentGroup_QueryInterface,
- + (void *)DRI3PresentGroup_AddRef,
- + (void *)DRI3PresentGroup_Release,
- + (void *)DRI3PresentGroup_GetMultiheadCount,
- + (void *)DRI3PresentGroup_GetPresent,
- + (void *)DRI3PresentGroup_CreateAdditionalPresent,
- + (void *)DRI3PresentGroup_GetVersion
- +};
- +
- +HRESULT present_create_present_group(Display *gdi_display, const WCHAR *device_name,
- + UINT adapter, HWND focus_wnd, D3DPRESENT_PARAMETERS *params,
- + unsigned nparams, ID3DPresentGroup **group, boolean ex, DWORD BehaviorFlags)
- +{
- + struct DRI3PresentGroup *This;
- + DISPLAY_DEVICEW dd;
- + HRESULT hr;
- + unsigned i;
- +
- + This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- + sizeof(struct DRI3PresentGroup));
- + if (!This)
- + {
- + ERR("Out of memory.\n");
- + return E_OUTOFMEMORY;
- + }
- +
- + This->gdi_display = gdi_display;
- + This->vtable = &DRI3PresentGroup_vtable;
- + This->refs = 1;
- + This->ex = ex;
- + This->npresent_backends = nparams;
- + This->no_window_changes = !!(BehaviorFlags & D3DCREATE_NOWINDOWCHANGES);
- + This->present_backends = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- + This->npresent_backends * sizeof(struct DRI3Present *));
- + if (!This->present_backends)
- + {
- + DRI3PresentGroup_Release(This);
- + ERR("Out of memory.\n");
- + return E_OUTOFMEMORY;
- + }
- +
- + if (nparams != 1)
- + adapter = 0;
- +
- + for (i = 0; i < This->npresent_backends; ++i)
- + {
- + ZeroMemory(&dd, sizeof(dd));
- + dd.cb = sizeof(dd);
- + /* find final device name */
- + if (!EnumDisplayDevicesW(device_name, adapter + i, &dd, 0))
- + {
- + WARN("Couldn't find subdevice %d from `%s'\n",
- + i, debugstr_w(device_name));
- + }
- +
- + /* create an ID3DPresent for it */
- + hr = DRI3Present_new(gdi_display, dd.DeviceName, ¶ms[i],
- + focus_wnd, &This->present_backends[i], ex, This->no_window_changes);
- + if (FAILED(hr))
- + {
- + DRI3PresentGroup_Release(This);
- + return hr;
- + }
- + }
- +
- + *group = (ID3DPresentGroup *)This;
- + TRACE("Returning %p\n", *group);
- +
- + return D3D_OK;
- +}
- +
- +HRESULT present_create_adapter9(Display *gdi_display, HDC hdc, ID3DAdapter9 **out)
- +{
- + struct x11drv_escape_get_drawable extesc = { X11DRV_GET_DRAWABLE };
- + HRESULT hr;
- + int fd;
- +
- + if (!d3d9_drm)
- + {
- + ERR("DRM drivers are not supported on your system.\n");
- + return D3DERR_DRIVERINTERNALERROR;
- + }
- +
- + if (ExtEscape(hdc, X11DRV_ESCAPE, sizeof(extesc), (LPCSTR)&extesc,
- + sizeof(extesc), (LPSTR)&extesc) <= 0)
- + ERR("X11 drawable lookup failed (hdc=%p)\n", hdc);
- +
- +#ifdef D3D9NINE_DRI2
- + if (!is_dri2_fallback && !DRI3Open(gdi_display, DefaultScreen(gdi_display), &fd))
- +#else
- + if (!DRI3Open(gdi_display, DefaultScreen(gdi_display), &fd))
- +#endif
- + {
- + ERR("DRI3Open failed (fd=%d)\n", fd);
- + return D3DERR_DRIVERINTERNALERROR;
- + }
- +#ifdef D3D9NINE_DRI2
- + if (is_dri2_fallback && !DRI2FallbackOpen(gdi_display, DefaultScreen(gdi_display), &fd))
- + {
- + ERR("DRI2Open failed (fd=%d)\n", fd);
- + return D3DERR_DRIVERINTERNALERROR;
- + }
- +#endif
- + hr = d3d9_drm->create_adapter(fd, out);
- + if (FAILED(hr))
- + {
- + ERR("Unable to create ID3DAdapter9 (fd=%d)\n", fd);
- + return hr;
- + }
- +
- + TRACE("Created ID3DAdapter9 with fd %d\n", fd);
- +
- + return D3D_OK;
- +}
- +
- +BOOL present_has_d3dadapter(Display *gdi_display)
- +{
- + static const void * WINAPI (*pD3DAdapter9GetProc)(const char *);
- + static void *handle = NULL;
- + static int done = 0;
- + HKEY regkey;
- + LSTATUS rc;
- + char *path = NULL;
- +
- + char errbuf[256];
- + char pathbuf[MAX_PATH];
- +
- + /* like in opengl.c (single threaded assumption OK?) */
- + if (done)
- + return handle != NULL;
- + done = 1;
- +
- + if (!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Direct3DNine", ®key))
- + {
- + DWORD type;
- + DWORD size = 0;
- +
- + rc = RegQueryValueExA(regkey, "ModulePath", 0, &type, NULL, &size);
- + if (rc == ERROR_FILE_NOT_FOUND)
- + goto use_default_path;
- +
- + TRACE("Reading registry key for module path\n");
- + if (rc != ERROR_SUCCESS || type != REG_SZ)
- + {
- + ERR("Failed to read Direct3DNine ModulePath registry key: Invalid content\n");
- + goto cleanup;
- + }
- +
- + path = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + 1);
- + if (!path)
- + {
- + ERR("Out of memory\n");
- + return FALSE;
- + }
- + rc = RegQueryValueExA(regkey, "ModulePath", 0, &type, (LPBYTE)path, &size);
- + if (rc != ERROR_SUCCESS)
- + {
- + ERR("Failed to read Direct3DNine registry\n");
- + goto cleanup;
- + }
- + /* Split colon separated path for multi-arch support */
- + if (strstr(path, ":"))
- + {
- + char *tmp_path = strstr(path, ":");
- +
- + /* Replace colon by string terminate */
- + *tmp_path = 0;
- + tmp_path ++;
- + handle = wine_dlopen(path,
- + RTLD_GLOBAL | RTLD_NOW, errbuf, sizeof(errbuf));
- + if (!handle)
- + {
- + TRACE("Failed to load '%s': %s\n", path, errbuf);
- +
- + handle = wine_dlopen(tmp_path,
- + RTLD_GLOBAL | RTLD_NOW, errbuf, sizeof(errbuf));
- + if (!handle)
- + {
- + TRACE("Failed to load '%s': %s\n", tmp_path, errbuf);
- + ERR("Failed to load '%s' and '%s' set by ModulePath.\n",
- + path, tmp_path);
- + goto cleanup;
- + }
- + }
- + }
- + else
- + {
- + handle = wine_dlopen(path,
- + RTLD_GLOBAL | RTLD_NOW, errbuf, sizeof(errbuf));
- + if (!handle)
- + {
- + TRACE("Failed to load %s: %s\n", path, errbuf);
- + ERR("Failed to load '%s' set by ModulePath.\n", path);
- + goto cleanup;
- + }
- + }
- + memcpy(pathbuf, path, size >= sizeof(pathbuf) ? (sizeof(pathbuf)-1) : size);
- + pathbuf[sizeof(pathbuf)-1] = 0;
- +
- + HeapFree(GetProcessHeap(), 0, path);
- + }
- +
- +use_default_path:
- +#if !defined(D3D9NINE_MODULEPATH)
- + if (!handle)
- + {
- + ERR("d3d9-nine.dll was built without default module path.\n"
- + "Setting Software\\Wine\\Direct3DNine ModulePath is required\n");
- + goto cleanup;
- + }
- +#else
- + if (!handle)
- + {
- + handle = wine_dlopen(D3D9NINE_MODULEPATH,
- + RTLD_GLOBAL | RTLD_NOW, errbuf, sizeof(errbuf));
- + if (!handle)
- + {
- + ERR("Failed to load '%s': %s\n", D3D9NINE_MODULEPATH, errbuf);
- + goto cleanup;
- + }
- + memcpy(pathbuf, D3D9NINE_MODULEPATH,
- + sizeof(D3D9NINE_MODULEPATH) >= sizeof(pathbuf) ?
- + (sizeof(pathbuf)-1) : sizeof(D3D9NINE_MODULEPATH));
- + pathbuf[sizeof(pathbuf)-1] = 0;
- + }
- +#endif
- + /* find our entry point in d3dadapter9 */
- + pD3DAdapter9GetProc = wine_dlsym(handle, "D3DAdapter9GetProc",
- + errbuf, sizeof(errbuf));
- + if (!pD3DAdapter9GetProc)
- + {
- + ERR("Failed to get the entry point from %s: %s", pathbuf, errbuf);
- + goto cleanup;
- + }
- +
- + /* get a handle to the drm backend struct */
- + d3d9_drm = pD3DAdapter9GetProc("drm");
- + if (!d3d9_drm)
- + {
- + ERR("%s doesn't support the drm backend.\n", pathbuf);
- + goto cleanup;
- + }
- +
- + /* verify that we're binary compatible */
- + if (d3d9_drm->major_version != 0)
- + {
- + ERR("Version mismatch. %s has %d.%d, was expecting 0.x\n",
- + pathbuf, d3d9_drm->major_version, d3d9_drm->minor_version);
- + goto cleanup;
- + }
- +
- + /* this will be used to store d3d_drawables */
- + d3d_hwnd_context = XUniqueContext();
- +
- + if (!PRESENTCheckExtension(gdi_display, 1, 0))
- + {
- + ERR("Unable to query PRESENT.\n");
- + goto cleanup;
- + }
- +
- + if (!DRI3CheckExtension(gdi_display, 1, 0))
- + {
- +#ifndef D3D9NINE_DRI2
- + ERR("Unable to query DRI3.\n");
- + goto cleanup;
- +#else
- + ERR("Unable to query DRI3. Trying DRI2 fallback (slower performance).\n");
- + is_dri2_fallback = 1;
- + if (!DRI2FallbackCheckSupport(gdi_display))
- + {
- + ERR("DRI2 fallback unsupported\n");
- + goto cleanup;
- + }
- +#endif
- + }
- +
- + return TRUE;
- +
- +cleanup:
- + ERR("\033[1;31m\nNative Direct3D 9 will be unavailable."
- + "\nFor more information visit https://wiki.ixit.cz/d3d9\033[0m\n");
- + if (handle)
- + {
- + wine_dlclose(handle, NULL, 0);
- + handle = NULL;
- + }
- +
- + if (path)
- + HeapFree(GetProcessHeap(), 0, path);
- +
- + return FALSE;
- +}
- +
- +BOOL enable_device_vtable_wrapper(void)
- +{
- + if (!d3d9_drm)
- + {
- + ERR("enable_device_vtable_wrapper call before init.\n");
- + return FALSE;
- + }
- + /* Since minor version 1, we can assume a copy of the internal vtable is stored in second pos.
- + * For now always enable if possible the wrapper (enables Steam overlay for example),
- + * we might in the future let user choose. */
- + return d3d9_drm->minor_version >= 1;
- +}
- diff --git a/dlls/d3d9-nine/present.h b/dlls/d3d9-nine/present.h
- new file mode 100644
- index 0000000000..a5516877f1
- --- /dev/null
- +++ b/dlls/d3d9-nine/present.h
- @@ -0,0 +1,40 @@
- +/*
- + * Wine present interface
- + *
- + * Copyright 2015 Patrick Rudolph
- + *
- + * 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
- + */
- +
- +#ifndef __WINE_PRESENT_H
- +#define __WINE_PRESENT_H
- +
- +#ifndef __WINE_CONFIG_H
- +# error You must include config.h to use this header
- +#endif
- +
- +#include <X11/Xlib.h>
- +
- +HRESULT present_create_present_group(Display *gdi_display, const WCHAR *device_name, UINT adapter,
- + HWND focus, D3DPRESENT_PARAMETERS *params, unsigned nparams, ID3DPresentGroup **group,
- + boolean ex, DWORD BehaviorFlags);
- +
- +HRESULT present_create_adapter9(Display *gdi_display, HDC hdc, ID3DAdapter9 **adapter);
- +
- +BOOL present_has_d3dadapter(Display *gdi_display);
- +
- +BOOL enable_device_vtable_wrapper(void);
- +
- +#endif /* __WINE_PRESENT_H */
- diff --git a/dlls/d3d9-nine/shader_validator.c b/dlls/d3d9-nine/shader_validator.c
- new file mode 100644
- index 0000000000..03848b2aa2
- --- /dev/null
- +++ b/dlls/d3d9-nine/shader_validator.c
- @@ -0,0 +1,88 @@
- +/*
- + * Direct3D 9 ShaderValidator
- + *
- + * Copyright 2016 Patrick Rudolph
- + *
- + * 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
- + *
- + */
- +#include "wine/debug.h"
- +WINE_DEFAULT_DEBUG_CHANNEL(d3d9nine);
- +
- +#include "winbase.h"
- +
- +#include "shader_validator.h"
- +
- +static HRESULT WINAPI IDirect3DShaderValidator9Impl_QueryInterface(IDirect3DShaderValidator9Impl *This,
- + REFIID riid, LPVOID* ppobj)
- +{
- + /* TODO: AddRef(iface). */
- + *ppobj = This;
- + TRACE("This=%p, riid=%s, object=%p.\n", This, debugstr_guid(riid), ppobj);
- +
- + return S_OK;
- +}
- +
- +static ULONG WINAPI IDirect3DShaderValidator9Impl_AddRef(IDirect3DShaderValidator9Impl *This)
- +{
- + ULONG ref = InterlockedIncrement(&This->ref);
- + TRACE("This=%p increasing refcount to %u.\n", This, ref);
- +
- + return ref;
- +}
- +
- +static ULONG WINAPI IDirect3DShaderValidator9Impl_Release(IDirect3DShaderValidator9Impl *This)
- +{
- + ULONG ref = InterlockedDecrement(&This->ref);
- + TRACE("This=%p decreasing refcount to %u.\n", This, ref);
- +
- + if (ref == 0)
- + HeapFree(GetProcessHeap(), 0, This);
- +
- + return ref;
- +}
- +
- +static LONG WINAPI IDirect3DShaderValidator9Impl_Begin(IDirect3DShaderValidator9Impl *This,
- + void* callback, void* unknown1, ULONG unknown2)
- +{
- + TRACE("This=%p, callback=%p, unknown1=%p, unknown2=%u\n", This, callback, unknown1, unknown2);
- + return 1;
- +}
- +
- +static LONG WINAPI IDirect3DShaderValidator9Impl_Instruction(IDirect3DShaderValidator9Impl *This,
- + const char* unknown1, unsigned int unknown2, const unsigned long* unknown3, unsigned int unknown4)
- +{
- + TRACE("This=%p, unknown1=%p, unknown2=%u, unknown3=%p, unknown4=%u\n", This, unknown1, unknown2, unknown3, unknown4);
- + return 1;
- +}
- +
- +static LONG WINAPI IDirect3DShaderValidator9Impl_End(IDirect3DShaderValidator9Impl *This)
- +{
- + TRACE("This=%p\n", This);
- + return 1;
- +}
- +
- +const void *IDirect3DShaderValidator9Vtbl[] =
- +{
- + /* IUnknown */
- + IDirect3DShaderValidator9Impl_QueryInterface,
- + IDirect3DShaderValidator9Impl_AddRef,
- + IDirect3DShaderValidator9Impl_Release,
- + /* IDirect3DShaderValidator9 */
- + IDirect3DShaderValidator9Impl_Begin,
- + IDirect3DShaderValidator9Impl_Instruction,
- + IDirect3DShaderValidator9Impl_End
- +};
- +
- diff --git a/dlls/d3d9-nine/shader_validator.h b/dlls/d3d9-nine/shader_validator.h
- new file mode 100644
- index 0000000000..07a5e2d2b4
- --- /dev/null
- +++ b/dlls/d3d9-nine/shader_validator.h
- @@ -0,0 +1,29 @@
- +/*
- + * Direct3D 9 ShaderValidator
- + *
- + * Copyright 2016 Patrick Rudolph
- + *
- + * 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
- + *
- + */
- +
- +typedef struct IDirect3DShaderValidator9Impl
- +{
- + /* IUnknown fields */
- + void *lpVtbl;
- + LONG ref;
- +} IDirect3DShaderValidator9Impl;
- +
- +const void *IDirect3DShaderValidator9Vtbl[6];
- diff --git a/dlls/d3d9-nine/version.rc b/dlls/d3d9-nine/version.rc
- new file mode 100644
- index 0000000000..bfafc2f24a
- --- /dev/null
- +++ b/dlls/d3d9-nine/version.rc
- @@ -0,0 +1,26 @@
- +/*
- + * Copyright 2015 Patrick Rudolph
- + *
- + * 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
- + */
- +
- +#define WINE_FILEDESCRIPTION_STR "Wine Gallium Nine Direct3D"
- +#define WINE_FILENAME_STR "d3d9-nine.dll"
- +#define WINE_FILEVERSION 5,3,1,904
- +#define WINE_FILEVERSION_STR "5.3.1.904"
- +#define WINE_PRODUCTVERSION 5,3,1,904
- +#define WINE_PRODUCTVERSION_STR "5.3.1.904"
- +
- +#include "wine/wine_common_ver.rc"
- diff --git a/dlls/d3d9-nine/wndproc.c b/dlls/d3d9-nine/wndproc.c
- new file mode 100644
- index 0000000000..0ed80de7d7
- --- /dev/null
- +++ b/dlls/d3d9-nine/wndproc.c
- @@ -0,0 +1,277 @@
- +/*
- + * Copyright 2016 Patrick Rudolph
- + *
- + * Based on the file wined3d_main.c taken from wined3d:
- + * All credits go to the original developers:
- + *
- + * Copyright 2002-2003 The wine-d3d team
- + * Copyright 2002-2003 Raphael Junqueira
- + * Copyright 2004 Jason Edmeades
- + * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
- + * Copyright 2009 Henri Verbeet 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
- + */
- +
- +#include "config.h"
- +#include "wine/port.h"
- +
- +#include <stdarg.h>
- +#include <math.h>
- +#include <limits.h>
- +#define NONAMELESSUNION
- +#define NONAMELESSSTRUCT
- +#define COBJMACROS
- +#include "windef.h"
- +#include "winbase.h"
- +#include "winreg.h"
- +#include "wingdi.h"
- +#include "winuser.h"
- +#include "wine/debug.h"
- +#include "wine/unicode.h"
- +
- +#include "wndproc.h"
- +
- +WINE_DEFAULT_DEBUG_CHANNEL(d3dadapter);
- +
- +struct nine_wndproc
- +{
- + HWND window;
- + BOOL unicode;
- + WNDPROC proc;
- + struct DRI3Present *present;
- +};
- +
- +struct nine_wndproc_table
- +{
- + struct nine_wndproc *entries;
- + unsigned int count;
- + unsigned int size;
- +};
- +
- +static struct nine_wndproc_table wndproc_table;
- +
- +static CRITICAL_SECTION nine_wndproc_cs;
- +static CRITICAL_SECTION_DEBUG nine_wndproc_cs_debug =
- +{
- + 0, 0, &nine_wndproc_cs,
- + {&nine_wndproc_cs_debug.ProcessLocksList,
- + &nine_wndproc_cs_debug.ProcessLocksList},
- + 0, 0, {(DWORD_PTR)(__FILE__ ": nine_wndproc_cs")}
- +};
- +static CRITICAL_SECTION nine_wndproc_cs = {&nine_wndproc_cs_debug, -1, 0, 0, 0, 0};
- +
- +BOOL nine_dll_init(HINSTANCE hInstDLL)
- +{
- + WNDCLASSA wc;
- +
- + /* We need our own window class for a fake window which we use to retrieve GL capabilities */
- + /* We might need CS_OWNDC in the future if we notice strange things on Windows.
- + * Various articles/posts about OpenGL problems on Windows recommend this. */
- + wc.style = CS_HREDRAW | CS_VREDRAW;
- + wc.lpfnWndProc = DefWindowProcA;
- + wc.cbClsExtra = 0;
- + wc.cbWndExtra = 0;
- + wc.hInstance = hInstDLL;
- + wc.hIcon = LoadIconA(NULL, (const char *)IDI_WINLOGO);
- + wc.hCursor = LoadCursorA(NULL, (const char *)IDC_ARROW);
- + wc.hbrBackground = NULL;
- + wc.lpszMenuName = NULL;
- + wc.lpszClassName = NINE_WINDOW_CLASS_NAME;
- +
- + if (!RegisterClassA(&wc))
- + {
- + ERR("Failed to register window class '%s'!\n", NINE_WINDOW_CLASS_NAME);
- + return FALSE;
- + }
- +
- + DisableThreadLibraryCalls(hInstDLL);
- +
- + return TRUE;
- +}
- +
- +BOOL nine_dll_destroy(HINSTANCE hInstDLL)
- +{
- + unsigned int i;
- +
- + for (i = 0; i < wndproc_table.count; ++i)
- + {
- + /* Trying to unregister these would be futile. These entries can only
- + * exist if either we skipped them in nine_unregister_window() due
- + * to the application replacing the wndproc after the entry was
- + * registered, or if the application still has an active nine
- + * device. In the latter case the application has bigger problems than
- + * these entries. */
- + WARN("Leftover wndproc table entry %p.\n", &wndproc_table.entries[i]);
- + }
- + HeapFree(GetProcessHeap(), 0, wndproc_table.entries);
- +
- + UnregisterClassA(NINE_WINDOW_CLASS_NAME, hInstDLL);
- +
- + DeleteCriticalSection(&nine_wndproc_cs);
- + return TRUE;
- +}
- +
- +static void nine_wndproc_mutex_lock(void)
- +{
- + EnterCriticalSection(&nine_wndproc_cs);
- +}
- +
- +static void nine_wndproc_mutex_unlock(void)
- +{
- + LeaveCriticalSection(&nine_wndproc_cs);
- +}
- +
- +static struct nine_wndproc *nine_find_wndproc(HWND window)
- +{
- + unsigned int i;
- +
- + for (i = 0; i < wndproc_table.count; ++i)
- + {
- + if (wndproc_table.entries[i].window == window)
- + {
- + return &wndproc_table.entries[i];
- + }
- + }
- +
- + return NULL;
- +}
- +
- +static LRESULT CALLBACK nine_wndproc(HWND window, UINT message, WPARAM wparam, LPARAM lparam)
- +{
- + struct nine_wndproc *entry;
- + struct DRI3Present *present;
- + BOOL unicode;
- + WNDPROC proc;
- +
- + nine_wndproc_mutex_lock();
- + entry = nine_find_wndproc(window);
- +
- + if (!entry)
- + {
- + nine_wndproc_mutex_unlock();
- + ERR("Window %p is not registered with nine.\n", window);
- + return DefWindowProcW(window, message, wparam, lparam);
- + }
- +
- + present = entry->present;
- + unicode = entry->unicode;
- + proc = entry->proc;
- + nine_wndproc_mutex_unlock();
- +
- + if (present)
- + return device_process_message(present, window, unicode, message, wparam, lparam, proc);
- + if (unicode)
- + return CallWindowProcW(proc, window, message, wparam, lparam);
- + return CallWindowProcA(proc, window, message, wparam, lparam);
- +}
- +
- +BOOL nine_register_window(HWND window, struct DRI3Present *present)
- +{
- + struct nine_wndproc *entry;
- +
- + nine_wndproc_mutex_lock();
- +
- + if (nine_find_wndproc(window))
- + {
- + nine_wndproc_mutex_unlock();
- + WARN("Window %p is already registered with nine.\n", window);
- + return TRUE;
- + }
- +
- + if (wndproc_table.size == wndproc_table.count)
- + {
- + unsigned int new_size = max(1, wndproc_table.size * 2);
- + struct nine_wndproc *new_entries;
- +
- + if (!wndproc_table.entries) new_entries = HeapAlloc(GetProcessHeap(), 0, new_size * sizeof(*new_entries));
- + else new_entries = HeapReAlloc(GetProcessHeap(), 0, wndproc_table.entries, new_size * sizeof(*new_entries));
- +
- + if (!new_entries)
- + {
- + nine_wndproc_mutex_unlock();
- + ERR("Failed to grow table.\n");
- + return FALSE;
- + }
- +
- + wndproc_table.entries = new_entries;
- + wndproc_table.size = new_size;
- + }
- +
- + entry = &wndproc_table.entries[wndproc_table.count++];
- + entry->window = window;
- + entry->unicode = IsWindowUnicode(window);
- + /* Set a window proc that matches the window. Some applications (e.g. NoX)
- + * replace the window proc after we've set ours, and expect to be able to
- + * call the previous one (ours) directly, without using CallWindowProc(). */
- + if (entry->unicode)
- + entry->proc = (WNDPROC)SetWindowLongPtrW(window, GWLP_WNDPROC, (LONG_PTR)nine_wndproc);
- + else
- + entry->proc = (WNDPROC)SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)nine_wndproc);
- + entry->present = present;
- +
- + nine_wndproc_mutex_unlock();
- +
- + return TRUE;
- +}
- +
- +BOOL nine_unregister_window(HWND window)
- +{
- + struct nine_wndproc *entry, *last;
- + LONG_PTR proc;
- +
- + nine_wndproc_mutex_lock();
- +
- + if (!(entry = nine_find_wndproc(window)))
- + {
- + nine_wndproc_mutex_unlock();
- + return FALSE;
- + }
- +
- + if (entry->unicode)
- + {
- + proc = GetWindowLongPtrW(window, GWLP_WNDPROC);
- + if (proc != (LONG_PTR)nine_wndproc)
- + {
- + entry->present = NULL;
- + nine_wndproc_mutex_unlock();
- + WARN("Not unregistering window %p, window proc %#lx doesn't match nine window proc %p.\n",
- + window, proc, nine_wndproc);
- + return FALSE;
- + }
- +
- + SetWindowLongPtrW(window, GWLP_WNDPROC, (LONG_PTR)entry->proc);
- + }
- + else
- + {
- + proc = GetWindowLongPtrA(window, GWLP_WNDPROC);
- + if (proc != (LONG_PTR)nine_wndproc)
- + {
- + entry->present = NULL;
- + nine_wndproc_mutex_unlock();
- + WARN("Not unregistering window %p, window proc %#lx doesn't match nine window proc %p.\n",
- + window, proc, nine_wndproc);
- + return FALSE;
- + }
- +
- + SetWindowLongPtrA(window, GWLP_WNDPROC, (LONG_PTR)entry->proc);
- + }
- +
- + last = &wndproc_table.entries[--wndproc_table.count];
- + if (entry != last) *entry = *last;
- +
- + nine_wndproc_mutex_unlock();
- + return TRUE;
- +}
- diff --git a/dlls/d3d9-nine/wndproc.h b/dlls/d3d9-nine/wndproc.h
- new file mode 100644
- index 0000000000..15f26d491a
- --- /dev/null
- +++ b/dlls/d3d9-nine/wndproc.h
- @@ -0,0 +1,41 @@
- +/*
- + * Direct3D wine internal interface main
- + *
- + * Copyright 2002-2003 The wine-d3d team
- + * Copyright 2002-2003 Raphael Junqueira
- + * Copyright 2004 Jason Edmeades
- + * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
- + * Copyright 2009 Henri Verbeet 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
- + */
- +
- +#ifndef __WINE_NINE_WNDPROC_H
- +#define __WINE_NINE_WNDPROC_H
- +
- +struct DRI3Present;
- +
- +BOOL nine_register_window(HWND window, struct DRI3Present *present);
- +BOOL nine_unregister_window(HWND window);
- +
- +BOOL nine_dll_init(HINSTANCE hInstDLL);
- +BOOL nine_dll_destroy(HINSTANCE hInstDLL);
- +
- +LRESULT device_process_message(struct DRI3Present *present, HWND window, BOOL unicode,
- + UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc);
- +
- +#define NINE_WINDOW_CLASS_NAME "Gallium_Nine_Window"
- +
- +#endif
- --
- 2.15.0
|