From 60ca4c06ae2bb5c0d16afb0790ae02c815d2f1ba Mon Sep 17 00:00:00 2001 From: Matthew Date: Wed, 21 May 2025 22:32:28 +1000 Subject: [PATCH] start work on pbr pipeline, some clean up/fixes for allocators --- assets/test_char.m3d | Bin 0 -> 2403 bytes assets/yoda.m3d | Bin 0 -> 15862 bytes external/m3d/m3d.h | 6 +- external/stb/stb_image.h | 6 +- external/xxhash/xxhash.h | 4 +- src/allocators.c | 18 ++++- src/assets.h | 2 + src/entry_linux.c | 5 ++ src/game.c | 2 +- src/packer.c | 103 +++++++++------------------ src/packer.h | 26 +++---- src/platform/platform.h | 19 ++++- src/platform/platform_linux.h | 5 ++ src/platform/platform_linux_public.c | 85 ++++++++++++++++++++-- src/renderer.h | 13 +++- src/renderer_vulkan.c | 72 ++++++++++++++++--- src/renderer_vulkan.h | 2 +- src/renderer_vulkan_public.c | 2 +- src/shaders/glsl/pbr.frag.glsl | 16 +++++ src/shaders/glsl/pbr.vert.glsl | 18 +++++ src/vulkan_config.c | 33 +++++++++ 21 files changed, 324 insertions(+), 113 deletions(-) create mode 100644 assets/test_char.m3d create mode 100644 assets/yoda.m3d create mode 100644 src/shaders/glsl/pbr.frag.glsl create mode 100644 src/shaders/glsl/pbr.vert.glsl diff --git a/assets/test_char.m3d b/assets/test_char.m3d new file mode 100644 index 0000000000000000000000000000000000000000..ecb623b34e0b56dbe3912411d11de9d795f2bc79 GIT binary patch literal 2403 zcmXxj4OCKh9|v$iK@d>VP*^sR5HrcHFR(Ml{bbv)JseD<^(kZAI7M3s5 zP)whew)s+C^|8lhCSY04w_K_CQmr(#iIuBNLuJ?JoadbTKlgwB=bq2`{=esUy*L5i zL}FmD#E5q>r@nU;3Iu#sKwqv*cGii}N@coS_5Q-+qW1cFW`Xt#uT71##wL!Fhf4#4 z>5(tfy83P+@}|fnm5!7NWUf*Q5s@UXrpa*^=Luk*URZ8-1VQe(a{*4p3Enz#N`2xd zQqlWrkW{-~ucr@f}` zPY>QVU3}*FZEKm(WLlavetc8w+Z(fOIr+zJ+f$NLmVV4Mn%>-h_AIrvv`pq(+8R;n zx7?b1dog9?h>;E$- zh{N-fyT8sc)TIz^6+2mxN~`TIxfnLq1;k9t>$IIJI;r*nO0U7R={#TfcTUas+)@5x~}0a9x$R5 z8!;Dx{9`1$>56_YPcHqodG1b4j3Cb&abEf!F(inMndd%*b*8oLvf+4cwfN=SBqg3- zn%;fdiZ$u;z+qrg5MP@91V)!pDI;ZTWL?QtR>y&kPYwna(1BPvE!ZjeNRow%%x^wH zOWyc^3zO^@HPB+)Onnt{MWOhw(o~)o0b8OL(5$H08p%3>k<4HG|5NgD+xo&Q<6@xs z8yKmz3WY=G5xZUwTiEoOHGJ?JA0fJBkWEiS@Vb+yW-NYx`UkQ>d+da)pUr(0TwUt9 zoL_kfUX@#!il&BZB=!X3qpdma>oEy!F5sH^OPfp&=1-E%)<1O`-wtA|we&6K>bC?* zT1$HR)-hj~RNn)50ZJTctSujV|7}a*^H#rgZK-=MlTDZDUW*@JL;uiWky!WvkNJBQ zqUyX@AQB0V3ZlS|r|@%V#LK0qF;c$&cVb)bdqzJ7Ns#l8MN6=Oy4%KaVw?S4BO(z=af8|f={kKkr(`KNM1H^yi8iv4>~ zNmPl;7LQ%!z6S($5cv1P1ZlFftD`_oq(>)0VdH zUQTe_x{-C#{pEkt#t!9%`ot|cS=zE06e4}|NE7$RK-olw`M+D(b~(E(hOtoo`cXzC z1W#JCgI2j|yDGu3fH$>Xi#nEBxEp*%-?u zH&OfcM;_ddltLn>HUTls3g7Ub(b?V*b~j-7kvp5P*Aq ztDTKIT%ihpK~ZmZ&>~YCvr?+!J-?hxgZfZM=XvbAS{s&X`NkY7SH`OpU*6y0d1Zg~ zvz0tAhi$WEqz4=F%aD*|Dfd~if-yZP$jW|rD3XGz-*9}T*s9@#yx3cYyOs++%&>T9 zB!aJdbTsi|LMoF}D-0`i@N6$j>{(PUWH}*Jr81}{7_S%7cEBHbK|LU3ugK5@Z4{hA z)k{}nfvpW-cfY9Yy7tTe6~n{jE6s2&sB^u-ToqJ|D}Btr{a?Q|P;o}4^c5M38g`~( z?d9!@%3Ea8*T+Z<8i}N259Rp{7S&zIt<1^|{ej-Odgnky`)Y&k5r{3*xG!RxL92CU zW^1k$#Bz1V(U*8Iteb4Df|iU{$9yqnZ_pj%QQZ1)uf$5W%?WwvP`4gw7Xmwov41TZ zO%I=6n;=Ara|%eA=0f`uTKC(;=C@dbE|9^${$A^T=xlhRS;F&Odif51UD&J4@TN54 zDm?dj%Q<4SVN~nhbw4w>5&D2C(X}Y|=)r5+XuaG=UsrWg=U$Q>p7?pfbF5xo^ra>w z3>e4)m|1D>DoD|_3JgbIT-Q@r*O>*Arm$8;S-J~jR(&|QQS`MXBbT^czs(1k#1VZ9KMDW(V;GR*^w7II-L8Du& zX+dBJ!XMf<3$M|gK#&k!`E+1zoSF>v^{EGEyPfNull8iccyfracA76I-Kc6q2yTq7C7*}!nSfsmz8C7dbnx5+r-8leIlqif%nb7gghOtDkc|Ii0gT$gfoJl zY~hvd1S^gEXhwJ3BpZ1igz3U8lHs(e0^`LlRDup=<(;QNMIt4$l1T`jq@t7p{#to!p> z;+2xjk`0WFW&MG6_oipp4TRM-Zm_v_ujE#^aCYalFoWRAhMDvO2b^1?$2N^o9u8b< zeQ_9h5K-R1Ivvrl!!11_DfFHqMVbDNN|2O5nub=07FU6#d`{8 zi^C%kPVCaG9>>fvZSyB}3Zb^i`C@a(_2bd+a^k7AacoL(p>`(80;vLG|+21Nafn3BA6mveVgX3T6j z1m2Zo=>2N86Ct1%#5;GNMPH#9xodlVfc+ewKZMWhX@(koV0rxQkZJBBZ*p}5B<+}} z<>z|E<5!RkiIYh;&kR5O!6anCT7LvhEF@TIMTpS3s|Z#fb~<-MnF0)( z0lb#_eRc|gq+}r{4`D0=u&$Y77~F1!x1v5jRa6=uu2GmQ=Y49~-!9%ayDTz=dm!rL zBF~wP69s36S9GfovXI;ygARfb+T#N|HOz;S7S_n}ux}}F-4x0yVFGmLsLX5O37r@t ze^XY;(inmogmzbD)lMiQfYNBtUJql8Q}iMQ`Bme(IK{{p>@^|V?yhgH^Fw3Q<&A-^ z6H#c(tgkR9_o{&y=kqC!sXa=;NO*v$p~AOh4_}=3Ijz2ff%T$=->jCOKQpXdS5Uc& zeRSG>3X-X~>&rEDEkdy-tq8`rBAOmA#`1~+7eVxxvwZcmyp={uO-CS*?6 z3AAS1Qif<>H+1ol`RHoca$}Vxq=UmO|C;p*yK}`~4vukAOg`ltUBNSj4o@?G7hhX> zNz^`j3f(%ct@$R9&cY8jW}J+#wGj+XAagz~Ai>CQkW_(%HjW(>6|{h)V}pZoJ|x?w zcKVit-xDEerrICU`|*0N@C?gG7a5d1XW_RFS3EC#e8sC)vKb1-**BAi9^;O_fc_l# zpz71yw-AX_T{9@kAG~ndzq!Iji??QC3f_3)K!T`?n)N=!`MeRFG+^ljvEH~F<+RR6 z6_=mBgOE4hQ=-B1(1NpF))5hTy6JABlE2LrFs?NV1k2MKS*DzGS1ejImjLbW98q_^ zJy=3wzy4TqIsBdth8QyR1Jd1>sO{Mm<=`z*#tlz=X7`%fmRt*`-9Zr<*+-$}n~vL) zIv&4L;J%DY6xqeT&9(+Lj${QNnq?J~y*B|W^3lj=ao%#LXH_(pG|SWOek^BYCAg@V z4@?KgJD-nv{wluqzC@(@@)T5(y8jx~`Thxmh@sa3lxE2o!f7=L%0nQYvHZo60%&r! zN*h@L3wg*8>hV|sxQoxpcP63kbv^5Xox6Vsc2a_y&c)X{zjA=4iB40xNWz?VF{<>p zR*NB=m46MD#8V6IzM*s}r+$T@QjR;eY*@9EU322N4avrQ3T}NT975}xn8$`jH_P#2 zhnjX>4ZjzTIj#!BnorQ&)T=~gAI`|77QuQo>!%XOxW}m!ZO=kzqk8>rK%oJc-~4pmg#{R%yJ;g^%@hwUi8R^Fip~k%zOH#PA5U*^ZAKsZ5|cSNDkr$}(SDGU zh6UdLm{ujpOMLcT3eS((Lq<6gSU8a@?Yt6r!624$kW1w8No#G?Y9Ju$fcBI|WFrOLWH!1?^ED{*7oySYZ&Equ1<9U#{K_b?y%E z?t6~3;GwYlCuJT|e!E8pvMSD`uU@P=_{*vwmt>i+*NVNLU-d6JCrHZuA<|~jMkY^R%F2X2{E?DhlZ>YD#Sl$B%-E6G?j9nmF;{9agu{!VKJ1uzk zL;y}$@bxOD@B3aY(bFFRCZv$cV#ITkp_lA4i5uaV!o5wDiRk2$2KfR%)o=$Au=poy z)uNwn>H>xQX9hTOewoNFxg3E*<>!ikuE@I}O3PmsEq2qYNY^EOzPt}=>U+(c1{ z(c<{pB``|b5){R1NDc07N@F;8 zbcr2dI}$}%zsgPhv#2EYkuuI??>F|RRSLe9E8l!73D0@yqU*`BTx{WOIv?4PzfN#+ zje_s9mF%)hIVwW^oDsAR!CsALe<3-T?c~8u^SX?{wXX{jEws3yz;nHDhZSwIL7sU1 z!X`R)z&wL`{)~Su z_63=_1$I;8;t(3E`D_9bcCix1gxlx~$oH7gSJ*B0{u<+MG0Pg`zWM^cFKoi$cE56f z-`HNxSl?XKk0K`f-e-lST-GL`HZa(x!mW5=*oBwFDD%xV2qV@(!DT(~`t4=_?Hv>5 z)a{_rviTODRho1P@39Cv`e=K2W(k=T@(!hCe#>o7$98h26FKwvQsC6sO^oL?jAxoD z$z=!UY3=s?pW*HM zSGX4bdY2Y`N6}|!-s-K{?B!QCkx1uSleZ7x+mhLTt-baKS(ck*5 zy^r3hL16MXODHOD?GSzuw=nGY35uG_ZgJW2Kl7FdD{l8dgX1{#^~YY2->NfVYI+nS zbo-fmVaj#{f=*qVFGP)SKGdzY5#~OUr$u_aa|3LkX!B=L;ZJLC-YU*z%BMFX6T)Xy ztDzpIM6JM`HMaG!iU1um4sUZl4ck5WEDETZxUP^ShX~)QgG(U-UY&? zUr#ITJ~TAsOPFYS9belt!74iy$1d3Q#Rb^foQu%O+>dA<;0?+V_00m2ex2Fd&%7Xi zZ-Van$z{6@YNJY64vdsm@{XtITEQK7%k6#((Z2N)kkWfBr`G$d8E&e_ zw?hY#!967a?pVmt;vLZux0Y9(GFa^AZV z$j!VRey}%t%hhqtj@wx51JCs7$~`|}wLWJINqr+bVC9?6yg3|SyK<@MY3$R@fc=tB zR>Cz7Ya!q3UaR$4jy{?iRu)o80}DgLGFDA zdA?$5KC8oY)?CPHNJ5re96bhk<~9=stT|JMTDZF_h_JWIP~b{uu#}SgytP>yko2rF zCS>#Nl5F;0M{cOneM+ChyyDbQfSDR}?289QZ;6`s*)=9w^r4JU2)QH`Pr8vY3B7Mq zrA&15ILG39m?-qQWmyV19-CO72n2l`w9@TO@;iY}*MuLSKB?4SGmUEVsdUSIxYK+2 z*j+?K&rWZv>4_DlZEN3#ceVD{6uCt0yk?C%CTT#@JV zNyWkG2nn(fu4E%nRtf^{3*M^`RTfUOJ1B6?ojS3Uw4L(X2Jn>yMJzd2Rp{AgFkb`n24_S~5 z-azaZ@08=vmpii4t=aWpvoU@P39Ht9PSDd5ZT*2VS1IGXL=Ps5s#5hd4F>U|h74y7 zx=|@7Ipwq-57(~9{&es@igz%S5@3h-p4d>U8*xwK3smLU!u{BGgQCP^n4-to@@T&V zWP_-c@l}~_jrB)k^N@KWUw@HOWY;ue44qU6Q~Y#RV0-W^LzMS?tv6yCQ8Tr+C90}f z9oR7~-;bX`)XX#&i-6fU)kSAUQ=oLar9t}wnkQ4B5wA47)n-f#=wFvYb9L8#V=2c! zt&-2V0mo`;EIRs}yk=6N1UI~=%!r0JfeG~HTzThup$*!AJ! zDxhZMlAgyxxcfx)fzFDCv`9hZ-wz%`6pxVmxTLI7_=ApPiS~X zI6-dw!+Jr=OND8Kci1^TWDztyU<@7+M7ObwqXE&Z8I!n_71jA(;85?dlgAb zd(p#k+Z&*KVU6;IBL)#udo~LqvusIiT709QQOMtX8|k>KW4Mo>xzhbI1uSDe>4#nAP_v6wr%FQdt;gntEfz zTG&CK(WCd~ctL*{^t>dFaeGd%EzYf1z}-3B%+eqH0MF|i#uL?))Po#?@W2f1{6QdiAo_F_s2Dk3h$KK;U`0zWvb`Ay#{Kcn>#x=KD0)Dd{}uevGPx zITm5NP`RG31tZ5cE8^Ov|LgkBL~~H*Dy&#gaR9tz;cd6J?4xjDe@is1_V7`w)F^oG z0X;{7*PeTB>W=K~(9>R`*G22$n67KH>^;pJy$vVrmD(3gokV?`*_cUw&xTNvoYE=&lJr&$IzvJK;qtpoRA=`XDW^!r_Mw7!l0tb*oT-_EG# zxqB&R1K%U4(^^{uZ>xwAB?^X*QBm?> z7P;lwG0K&vE5a4}@dkX@>bUE8`WcsW=uzYzb67Uxux8YvVt2jvyvJkcBXm234D^)gmj-Vy2c*=U~WcPW8bGO>KJY|_C zZ`ILzC~9+-mk3(u>E7ub{2>~MVaCakM3#8gjSU4bQox4Gkj5LaNWlKdRRx;pb0z!s z#Q-clY`HvabjGfU6;BOV3p}Ho&}t{NSR<+3VJ%-D%Rb&Y0jMLx{?ZQ?7C&GYaedfM zyX9!3zo`9=KZ@3Hq7j^dZet>RPQg+q6@6b6V&=WxmW`yct{|c+njADDu6;HECiQxu zHyu>gq8)-%8sUmp`c8|Uh$GelVm&-{jYh|k)gT=ee%XwG5nSJJH2fU;sWRlh6 zMI(?l zI#NVx+l<0|^b)XZWgi%5U^SFhdIG^Nm@suy^^)fqF2F;b56HLfs6<#s*zn=&f0)Js zI+d*|T(Ot4=uX#h2NKGr1DuGDJCiu|oR_8}g4ndB5jg=ft}O;5k119?NOsTtrRMdG zccEI1ciGjHBlF|dW;&38Xk%CTcK2*Y^wFjD94GCODawn+vk)B{1C*rLUR?xSo>Im< z*0BHxF0WNeqV<#0>keD7-sBw~r(|rpz~W!%v1lp6GCGB+r{O}A>mhKzs@QTi^4J>& zu<_*rNZ+VChEnRjpKbB6Wgd_@uK|uNIBW*{yy%;fdFehIVRRW!quut>0VGlW6p~$k zZc2}IcVPxJcVPxRdsn`(P)#FTd9Yx?E);6eD4>&gaAqlCqk-n*?{T7|DT$6Gmv4=r zKaY)E3cpte{q}9SH*X8Vv?4=;_4Zl_q!!Rq%#8T1OhlfnVB2T^v;npV*TTkQ2S-_c z`Vz?HB^7$SOyy)|p|U=#w{{XP0@B~f&9h-tO!zx@FVg__Ry&&1tx#BmHm?=EB-GYP zszp_z$D$UXSuB^GCAK&Z%kdFkUZHrAtLBG~6DXG8+I0rmg{36;=e z_2eKUZMjd{B|g863pKZSR)xqr9-@|12gx~c`muVmWkIu?A0kJ)4M2H~*-bhMVLdgL zjC(wenJ`%kk1qdSNM;w@!TIh?mP`}}4>O-HYLMQ)5gUr|inen)1FtVOC%ZCt4JVu1 zDTm*fZIsJX2vRDCbqoOyzw&H%q2Y8jZL-!s-i##z%PDagpGtsBN*MiYO7G^IAj}!kf*v6&$U{ zNzi1&VW^on!E=(sZ^pHmFboq&^1X^Ar^P}XX9_SgaS@sDROFLLG3xG%Y!p*ezhK+;e* z0MsRiQ(SrYM|C%{@l|N_eNBy5)>Nq?Xhu#2gCJGp2Wiz%=t9(}m=-0_<*XzbsLues z^YS`(_{ka2lBdcU3vbY6;^y_${v$6gr(=V6Rl-z;Z(IoG zn(}u`l*3x4v<{2;x%2QcEw>3*-6Aam3;nlJxlBUN2Fses+3KRHJiIg={!OnKt@3Tg zbD6#Ckhxm~DDJn^G-qZVBg(Y?NWxDaJ_P2=KP9>hdoI20bv{z2ZKT=V``pa0he>Yi z9g!HLxiX2UorQL~{R}v=c zPSa;##|M6%QENRwg;A))PxH~NUb}ysy?b3V9QfguLfIag(gb-zU&C` z!Lr}g`wG_Aa*8VQ@#8E^D%Iwh6ym)M3 zY_Ah`@fv2xN^0#^rWdp35r#-Cago$YXm*A);L;}S@HHYOj-hB4!@Ts0CWWmh{(eGV z()lDMWA814F4_8C-uhM`V7}d$B~PrWyRa4hbm&EW)Y0W3&c^htVH&mPArZKg#67A+ zqx`gFa)Y@Gym%mxhLc|og+RQn01DYK{!r8zcA7;QA6X)2ZeY}a$%_}8eAN$4jDU=y z%-$c9o$KO76}DQL=|%eqrlz0qw~#;021Bgu&eRl{HX-ujABIjNE(9()5^bE_v49Bz zuQ%0wznL%xTHL1TJ&8NbtOKt1gdnZ#ltZphR>Sh_g2sy={GE(Cpt}F(A?d+Gd9|>- zt-$+fg_366oBKREeP5xwCZ5B2aPZ*b^m;BMQQJ60g}JN?F3l4#5NqvLMUi9;c5RSS zU#Ok5EqErd<{+&QasK2IS)iuX%`O^9{sh<863xUc5LU8*nGH-gyq^>W{>Aj#vOX#W z_6A2(=xr?H6_J)r{)XDmGTWS3P+3A*Wz1JRFU^jBb$UgwcrDAlQ+DNVlEEVUtGVcU zx|$4{lWL8uYk=RA21Jze81XTlEZLhwo?j37FEFn{y|^TiCE_;TITOZzfVuvWQSd{I zH0hFzGuV*g|75CTDQ`AdhPfkXuzZze<-6|8|Gj$uK=J?g5k0Q5BclG^DT}rz z;BC95y4t*{PFz)Sv@|!@C-upqWUY$I!>6*2@TUyVuQSV0VaD4vz^8yqiPXGinra-0 z%wK7kt(G=aQx~5)Y?$4}poXNbQ`IP`!x53!ee>`}DomHKOy_#g<^X7Hvj(b`NevNR z0nV@IndI5xIs9Y13ny$1hsD(WBrp9ib{&TgEU#6)$Oabz99|6L!Za>(68LeJl)8bW z3yNTZ!@E?{F;lB<4KtafW436oaxejU;e`-_0TJn-10EV*hOiS7K(S;YYJ;5)r$g1`_`3aw_;I-|NBI^Qd(>$z+OM4%K*ngLA zI0Bf_vux=KkqbTaC6e&gKBh+(=ku*_?K(ok<{2L6=mh;y1fN@*hKQ)>ygno{L0uDLp0|vF?IVsP_5GlNaQ`$NhX=>X zo5@GEJT^Iw>EZBga7cCn=z<8)1)my;Ig-?BwC;i9j0%1mjtF8K=-C3%xcdh&EeV_G z0|Miqg6B+dsBf4Z>Xm}SrWBvO24FEPPJ03vfKzNoCjT8Xm$QmAPO`j zB8XbGvzU6g^gF$j0%lMm zcJ2Q%XqRm~qg0wf6SnbzOxu5K0sa0{n)Ye+Z;peVS(-snO+lEOT9LaERxdVDLrB?& zv-VmWgZ}x3pniEI0dJnGhPkw~9r-3S0v%+-?3#QSJeNMW>s-*PFLq2aY0T~okdqN? z&tw86K@T1k)jgs=61{wc$T{(ZiS**zrJ+gCo-i^mk?dt(D&>L8kCn0tc9c&Vgd-X< ztb^w&7q}SccK$_`-ft@By9M%t#3s&uA!mR8ZfX-K9 zOy2jZqGxcsvq_GP+pq_c%s{WZqpsWnalD6E>+06KP22Wt_`+vlApANoN#BBCUI&=h zFC#xWZjwx<*Nnq8r1L;93Qli0CGN&}R+`#uBXIUEmR-Jb21?9r5`9t_soal=(SsjT zBZD=#sLu+|Yh#q~KMYC3^)E+VpT#(rt0qOe2WHzKD&>EoT`sRJaSlOl1?}3({1bth z_U?<&bF49tn;gUclcP=@Uq0b9H_XOx&8EQu`$isB9&}jtFWK2Kyh<_ckWi!D`levh_*7of=BwJ_v_PD9Q)?dzG-nY(k`oB}v1>gRI#_|hh|9`3KIX&4- zbzv#`kI?-_hsDy(!2gK+FE-3kJRl3_isa}eR^17Ok<8lLk~9hT8U4r$vPA(IODc`9 zTOA&{xe4}uKH17Y7^GZIxU!5tO?t9F&$6tlAiaIHmF)Z1Tyf z53H=t%PY1g0jG{M+oET~pt=e-<*QUe{tv9z7#z#qfrMdGz13#u+9E! zLFMB?VID}r6SDYE5M8d|vHN*OOgpv`^i`zfk*57IC@2_28h3Fzp?{QTyq+OWu06qb ze}fnIf`hkIROQjMQq5q4c4i2knl;Z4)bJEx+LXI2oG(hQ-9W2a1{y&Cv5~I2Qa{p# zuIBO6$!z9|1aJ!p!BV#|qxL0lcgPECz1x6rKtz^D>lC{!)S#_UgICs%|2=i`}ZR3~h+@PO3ELSBq5M+x}~@%~yc$vPaVs54N``w4(fmc_$!1Q?ZS zzm|mi843ogIfzL+bU_<5H3Jvt&}Ndl*Rd94B0Z5iTz+ZWoX``^4seveDAQn_1;j!Rbs%!}ogS&86x=zvH znL5u6oiUsiMG(G#fpvq+=4^ErY0HnjF544IufLa{yPo);>u!p& z>+||lC%{}>i(4BUL<_moc&@#sBAI_9SHAAV_Mm`zq837J;h8F<+Ul(}nxROwg%6rL z=RaD=Uw-}sk{B_~atkvW-A+Bh08@|fj(zx2uHm}FYQ%_0ab0h9aFgh1&F&PRzd2w( zAghopO`*>;QW2vncB^iI3r4;l_jn@+IADu?7bL$MAW5CEnJDIh%~xGA6#gW?4xE2DOoO-7*6vIrnUD0X_*8N2e2i27b_OmT>TLv~N z8eG`?a>ij#c9nEz(J4qtF_6+1z3tNFM(Pi6$D9pBHeuTiqd3cF` zbyr2&6Z(;kw=BHmTez|n(;lV!St9Zm_lXIv$E1r_!*MpqsDll79S@16^1+vE>6((j z26doX+8ILHj+!e{K7mN+x1 z89?cI)R+n=3Y}-IGDm9%BV-HZ*D6d{#%TvL*_KXJ)?+1`Iezm1P?{|U*M#7?^e$eh z46EBUYHvy~4YYU~Z5EHUYjh3=*P5}*cp1DJ10im&F!gE>io6rHv5c&{w`{VX#Nx+F zF0aB+9*n?Hq;j@+c#%ft&dN-vgczdyLj+(PUM8~{N9yx^X6(Qbg}H1H4lYrvT}aQ4 zyDekOrlFbOUe*ty411$hq>Jt^Q1V@R>+@yv!Z29mXe0l0gEV0@y0%Dh`L!Z5opiW4 z1YGT{L1W!d5~Z0es#=kzCBr;nIr$nPS`_3L^mRBJ|md^ z;ia^&vrlj6RmirbTOQ_5k;xzdyH`cDX-=&U4+~x*uByLq;W3C&U{!(~Y@H&Gq0Rug zMDH@{!6BOGG=b{3@{lTZIr4vFe;&+f(>zNRCW_QxS+=Z|bDw$m>$}j3*}~+X=y7EG zrPz{l1H2<*i5{`5s>CxvxW0yNf)o5AfP=muqhN?l?z8b}DzTR6>RMJg7Zz z5u`4X&qU~JjP&Haw#WhUZ!GbWlb!;;%O9TlNCYjTbD?#27+$>!>@4}9aD}VtsHE zjjMoBr-jExg@Ijb%PZF0VF8divm8l>Ld$eG{FmIIWSLodjECzPgg-@}T5Ne*3k+HR z>fY2Xza_&GEpSu7v|TY$4pOq2m0`+1oBp9>T=5nw%B0Gmm2mdBXa@cRHrQ%|fxVf~8_5Z4Cnl~QI!4`5(&47v(!L~GiB*6$LqSH}wbbEIr>O+fRxAL-Iv${a^u za}eAoASEapeiqoHAA~&32>!*j|M7KijM>jv=?=rSnRmV8f4*+two|QVzBE{$(I;%A zY1q)Tb?~ul+qV;s(fT(JA=vDgxjZEEPk`X^zx|0U57F5c8qz#$wWl#rV1M}|RxN+avq)(?7|d<1e3{eqC) zdxNAo7_xkFC;na{`c^Af`~b3KkDlUw$81}kg{Z2&kqcIj{b9aU8uHI*W#Hm8=-~F} z;sW5qfXb6~OGJn!j4-Tt`EG1`pLey$s(dnn?tYji>2}5%O z4tz(1V0OIVfrzdJ<)3G3bWY(5@{tO|Ziebgg@M3gEa!&yxc^%lD zB?)GgnqWsRQ7Caim*^7}@|wfe)rZ+i2Zj9-oq8~m8-TG6U<~jPPMb1M90MK1bjWs} z4-z>)q+g}F?3uuNO&y7hKVIY;+kgwu4eYi@?1yMjoOYNRxTHpryLnU3a3GRe3gZ*K z>vTBF#UmGaH!cdnp@3-x4lWjkd<`l@YevyW%@Z7!R6xCZlb?l;YzbcRgU?t5i6}=!+Ps{aaEGp67yC zMZQ(~l_#{@2Vc>HQ{s=?nd>uOH;cZX#@C&=68t43&oT(5s53#%xF5=^QT@h466HSp zI1S`C32aZOf!~W$$%(*jHIOsGrj$oNhd9L z2}lGb&Y0u980i3YwqA8|Ud3_vhlRp6*~nx#4)WsOCDbu%k-C9L@|2t8@g~uIeZob~ zX_Ra_kisRn3S%Dq8U{PM%GQ$fI>?(Cbh}aXvKsTD5&V;x`Mp;5(ldqkgPx4wOW#+% z+loRnj~tYa(t$m8=Z(v~%t2yMw>OFz8+O_pmf}7Yt)jRO+GC7z`H^Oq<6A%`YTrEaBSJR=3w!N~&9GEFV`tLHZXXg40Q* z4=1~5TxXgQ4dYDPj9(Pb+IE{FX~GPWX8cgpzYaBFFi$a?af>d14M?&YyzJur;G}6@ zR*;Tj%k*DFP&7j0E(xAu@UYGt^>p^Ik7flnRqev8igC+~qN(oNt2ZlkucdEl%&@XTl7YO+p3333u7y@2Y055I=3|M>}f&pc+hG3w{O7KRE zLwS7k2sA|{=Ni)jybThe-+~5u_n-tSgy{tEU)ISP(iUdtv(1*g z%g&ee_*`Xeofw?Sn0_Q-3^)?Kz~LYASjj;&N+J&I4e~jMhuI?*gr9{anunV?1En1w))SNb=e+0!+(-X&LFvKJGpl!nw(euD4(__)!u1{pdUA76oh{)JR!BJ{V4J8$>Y#1alK z7R|4|A!Y}iVlbCxHgISol#yQ-4!tY;nsfd9K(T?6*RgHwipBGyBP(dcZI~vB5FpZNGwH%+9oLV=!aNC!i*Y_K~T^|*i&eM5?&al2~{{@>8 z-*aFm|JBmdpJG;?y8NKy%d7PDCCfghPp?@yRNhkdNwT|QbkTu^*^G4UYdc(+?{V{{ zjypc); diff --git a/src/packer.c b/src/packer.c index dbb4302..f304732 100644 --- a/src/packer.c +++ b/src/packer.c @@ -28,6 +28,8 @@ const FileMapping g_Shader_File_Map[] = { { .file_name = "quad.vert.spv", .ix = QUAD_VERT_SPIRV_SHADER }, { .file_name = "gui.frag.spv", .ix = GUI_FRAG_SPIRV_SHADER }, { .file_name = "gui.vert.spv", .ix = GUI_VERT_SPIRV_SHADER }, + { .file_name = "pbr.frag.spv", .ix = PBR_FRAG_SPIRV_SHADER }, + { .file_name = "pbr.vert.spv", .ix = PBR_VERT_SPIRV_SHADER }, }; const FileMapping g_Texture_File_Map[] = { @@ -47,45 +49,6 @@ c8 *g_Texture_File_Names[TEXTURE_ASSET_MAX] = {0}; -// ::Packer::Files::Functions::Start:: - -u64 FileLength(FILE *file) -{ - Assert(fseek(file, 0, SEEK_END) == 0, "fseek failure"); - return (u64)ftell(file); -} - -u64 WriteData(void *buf, u64 pos, u64 size, FILE *file) -{ - Assert(fseek(file, pos, SEEK_SET) == 0, "WriteData fseek failure"); - u64 written = (u64)FWrite(buf, size, 1, file); - fflush(file); - return written; -} - -u64 ReadData(void *buf, u64 pos, u64 size, FILE *file) -{ - Assert(fseek(file, pos, SEEK_SET) == 0, "ReadData fseek failure"); - return FRead(buf, size, 1, file); -} - -FILE *pOpenFile(c8 *name, c8 *mode) -{ - FILE *file = fopen(name, mode); - Assert(file != NULL, "pOpenFile: file is null"); - return file; -} - -void CloseFile(FILE *file) -{ - fflush(file); - Assert(fclose(file) != EOF, "Error closing file"); -} - -// ::Packer::Files::Functions::End:: - - - // ::Packer::Packing::Functions::Start:: void SetArrayLookups() @@ -113,7 +76,7 @@ void SetArrayLookups() } } -i32 WriteHeader(FILE *file, FileHeader *header) +i32 WriteHeader(pFile file, FileHeader *header) { i32 offset = 0; @@ -195,9 +158,9 @@ void InitHeader(FileHeader *header) void PackFiles(Arena *arena, FileHeader *header) { - FILE *file = pOpenFile("assets.sgp", "w+"); + pFile file = pFileOpen("assets.sgp", pFS_WRITE | pFS_TRUNC); - u64 file_pos = WriteData(header, 0, sizeof(FileHeader), file); + u64 file_pos = pFileWrite(file, 0, header, sizeof(FileHeader)); u64 data_offset = 0; for (u32 i = 0; i < ASSET_TYPE_MAX; i++) @@ -222,21 +185,21 @@ void PackFiles(Arena *arena, FileHeader *header) Printfln("Packing file: %s...", asset_name); - FILE *asset_file = pOpenFile(asset_name, "r"); - u64 file_size = FileLength(asset_file); + pFile asset_file = pFileOpen(asset_name, pFS_READ); + u64 file_size = pFileLength(asset_file); u8 *file_data = MakeArray(arena, u8, file_size); - ReadData(file_data, 0, file_size, asset_file); + pFileRead(asset_file, 0, file_data, file_size); u64 prev_offset = data_offset; - data_offset += WriteData(file_data, data_offset, file_size, file); + data_offset += pFileWrite(file, data_offset, file_data, file_size); Assert((data_offset - prev_offset) == file_size, "File write size invalid"); shader_assets[i].data_offset = prev_offset; shader_assets[i].len = file_size; - CloseFile(asset_file); + pFileClose(asset_file); } Assert(pDirNavigate(return_dir) == 0, "Unable to return to previous directory"); @@ -249,21 +212,25 @@ void PackFiles(Arena *arena, FileHeader *header) Printfln("Packing file: %s...", asset_name); - FILE *asset_file = pOpenFile(asset_name, "r"); - u64 file_size = FileLength(asset_file); + pFile asset_file = pFileOpen(asset_name, pFS_READ); + u64 file_size = pFileLength(asset_file); u8 *file_data = MakeArray(arena, u8, file_size); - ReadData(file_data, 0, file_size, asset_file); + pFileRead(asset_file, 0, file_data, file_size); int ch = 4; int w, h, has_ch; u8 *image_bytes = stbi_load_from_memory(file_data, file_size, &w, &h, &has_ch, ch); - Assert(w > 0 && h > 0 && has_ch > 0, "stbi_load_from_memory failure"); + if (w <= 0 || h <= 0 || has_ch <= 0) + { + Printfln("%s", stbi_failure_reason()); + Assert(0, "stbi_load_from_memory failure"); + } u64 loaded_length = u64(w * h * ch); u64 prev_offset = data_offset; - data_offset += WriteData(image_bytes, data_offset, loaded_length, file); + data_offset += pFileWrite(file, data_offset, image_bytes, loaded_length); Assert((data_offset - prev_offset) == loaded_length, "File write size invalid"); @@ -275,11 +242,11 @@ void PackFiles(Arena *arena, FileHeader *header) stbi_image_free(image_bytes); - CloseFile(asset_file); + pFileClose(asset_file); } - WriteData(shader_assets, header->asset_offsets[SHADER_ASSET], sizeof(AssetFile)*SHADER_ASSET_MAX, file); - WriteData(texture_assets, header->asset_offsets[TEXTURE_ASSET], sizeof(AssetFile)*TEXTURE_ASSET_MAX, file); + pFileWrite(file, header->asset_offsets[SHADER_ASSET], shader_assets, sizeof(AssetFile)*SHADER_ASSET_MAX); + pFileWrite(file, header->asset_offsets[TEXTURE_ASSET], texture_assets, sizeof(AssetFile)*TEXTURE_ASSET_MAX); pDirNavigate(return_dir); } @@ -290,18 +257,18 @@ void PackFiles(Arena *arena, FileHeader *header) // ::Packer::Tests::Functions::Start:: -static inline void TestAssetIsCorrect(Arena *arena, c8 *file_name, AssetFile *file_info, AssetType type, FILE *file) +static inline void TestAssetIsCorrect(Arena *arena, c8 *file_name, AssetFile *file_info, AssetType type, pFile file) { - FILE *asset_file = pOpenFile(file_name, "r"); - u64 size = FileLength(asset_file); + pFile asset_file = pFileOpen(file_name, pFS_READ); + u64 size = pFileLength(asset_file); u8 *file_data = MakeArray(arena, u8, size); - u64 write_count = ReadData(file_data, 0, size, asset_file); + u64 write_count = pFileRead(asset_file, 0, file_data, size); Assert(write_count == size, "Incorrect asset size retrieved"); u8 *packed_asset = MakeArray(arena, u8, file_info->len); - ReadData(packed_asset, file_info->data_offset, file_info->len, file); + pFileRead(file, file_info->data_offset, packed_asset, file_info->len); u8 *image_bytes; u64 image_length; @@ -331,15 +298,15 @@ static inline void TestAssetIsCorrect(Arena *arena, c8 *file_name, AssetFile *fi } } - CloseFile(asset_file); + pFileClose(asset_file); } void TestAssetPack(Arena *arena) { - FILE *file = pOpenFile("assets.sgp", "r"); + pFile file = pFileOpen("assets.sgp", pFS_READ); FileHeader header; - i64 offset = FRead(&header, sizeof(FileHeader), 1, file); + i64 offset = pFileRead(file, 0, &header, sizeof(FileHeader)); Assert(header.magic_num == CreateMagicValue('s', 't', 'e', 'g'), "Magic number is incorrect"); Assert(header.version == FILE_VERSION, "File version is incorrect"); @@ -364,13 +331,13 @@ void TestAssetPack(Arena *arena) if (header.tag_counts[i] > 0) { tags[i] = MakeArray(arena, AssetTag, header.tag_counts[i]); - ReadData(tags[i], header.tag_offsets[i], sizeof(AssetTag)*header.tag_counts[i], file); + pFileRead(file, header.tag_offsets[i], tags[i], sizeof(AssetTag)*header.tag_counts[i]); } if (header.asset_counts[i] > 0) { files[i] = MakeArray(arena, AssetFile, header.asset_counts[i]); - ReadData(files[i], header.asset_offsets[i], sizeof(AssetFile)*header.asset_counts[i], file); + pFileRead(file, header.asset_offsets[i], files[i], sizeof(AssetFile)*header.asset_counts[i]); } } @@ -410,15 +377,15 @@ int main(int argc, c8 **argv) void *mem = pMemAllocZeroed(GB(1)); Arena *arena = ArenaInitDebug(mem, GB(1), __LINE__); - FILE *file = fopen("assets.sgp", "w+"); - Assert(file != NULL, "File is null"); + pFile file = pFileOpen("assets.sgp", pFS_WRITE | pFS_TRUNC); + Assert(file > 0, "File is null"); FileHeader header = {0}; InitHeader(&header); PackFiles(arena, &header); - CloseFile(file); + pFileClose(file); TestAssetPack(arena); } diff --git a/src/packer.h b/src/packer.h index c5621fb..a33ac44 100644 --- a/src/packer.h +++ b/src/packer.h @@ -14,17 +14,19 @@ #define STB_IMAGE_IMPLEMENTATION +#include "shared_types.h" +#include "platform/platform.h" +#include "util.h" +#include "assets.h" +#include "ds.h" +#include "allocators.h" + +// ::ThirdParty::Include::Header:: #include "stb/stb_sprintf.h" #include "stb/stb_image.h" #include "xxhash/xxhash.h" #include "fastlz/fastlz.h" -#include "shared_types.h" -#include "assets.h" -#include "util.h" -#include "ds.h" -#include "platform/platform.h" -#include "allocators.h" #include "renderer.h" #include "game.h" @@ -43,19 +45,11 @@ typedef struct FileMapping u32 ix; } FileMapping; -// ::Packer::Files::Functions::Header:: - -FILE *pOpenFile(c8 *name, c8 *mode); -void CloseFile(FILE *file); -u64 FileLength(FILE *file); -u64 WriteData(void *buf, u64 pos, u64 size, FILE *file); -u64 ReadData(void *buf, u64 pos, u64 size, FILE *file); - // ::Packer::Packing::Functions::Header:: void SetArrayLookups(); void InitHeader(FileHeader *header); -i32 WriteHeader(FILE *file, FileHeader *header); +i32 WriteHeader(pFile file, FileHeader *header); void PackFiles(Arena *arena, FileHeader *header); void MoveToTextureDir(c8 **return_dir); void MoveToShaderDir(c8 **return_dir); @@ -63,7 +57,7 @@ void MoveToShaderDir(c8 **return_dir); // ::Packer::Tests::Functions::Header:: void TestAssetPack(Arena *arena); -static inline void TestAssetIsCorrect(Arena *arena, c8 *file_name, AssetFile *file_info, AssetType type, FILE *file); +static inline void TestAssetIsCorrect(Arena *arena, c8 *file_name, AssetFile *file_info, AssetType type, pFile file); // ::Packer::Main::Functions::Header:: diff --git a/src/platform/platform.h b/src/platform/platform.h index 072e47f..aeb4afe 100644 --- a/src/platform/platform.h +++ b/src/platform/platform.h @@ -117,9 +117,26 @@ pPlatformWindow *pWindowGet(); // ::Platform::FileSystem::Functions::Header:: +typedef enum e_pFSAccess +{ + pFS_READ = 0x01, + pFS_WRITE = 0x02, + pFS_TRUNC = 0x04, + pFS_APPEND = 0x08, +} pFSAccess; + b32 pDirNavigate(c8 *dir); c8 **pDirGetFileNames(Arena *arena, u32 *count); -static b8 pDirIsVisible(c8 *dir_name); +static pFile pFileOpen(c8 *file_name, pFSAccess access); +static void pFileClose(pFile file); +static u64 pFileRead(pFile file, u64 offset, rawptr buf, u64 len); +static u64 pFileWrite(pFile file, u64 offset, rawptr buf, u64 len); +static u64 pFileSeek(pFile file, u64 pos); +static u64 pFileLength(pFile file); +static b32 pFSIsVisible(c8 *name, b32 is_dir); +static b32 pDirIsVisible(c8 *dir_name); +static b32 pFileIsVisible(c8 *file_name); +static b32 pFileCanAccess(c8 *file_name, pFSAccess access); // ::Platform::Profiling::Functions::Header:: diff --git a/src/platform/platform_linux.h b/src/platform/platform_linux.h index 356025f..80af75a 100644 --- a/src/platform/platform_linux.h +++ b/src/platform/platform_linux.h @@ -25,6 +25,7 @@ #include #include #include +#include // ::Platform::Linux::Defines::Header:: @@ -52,6 +53,8 @@ // ::Platform::Linux::Types::Header +typedef int pFile; + typedef struct pThread { pthread_t handle; @@ -79,6 +82,8 @@ typedef struct pFunction void *fn; } pFunction; +typedef int pFile; + // ::Platform::Linux::Print::Functions::Header:: i32 pWrite(int fd, void const *str, isize count); diff --git a/src/platform/platform_linux_public.c b/src/platform/platform_linux_public.c index 1e7f18f..e5e8492 100644 --- a/src/platform/platform_linux_public.c +++ b/src/platform/platform_linux_public.c @@ -225,13 +225,66 @@ b32 pWindowShouldQuit() -// ::Platform::Functions::Directory::Start:: +// ::Platform::FileSystem::Functions::Start:: b32 pDirNavigate(c8 *dir) { return chdir(dir); } +static pFile pFileOpen(c8 *file_name, pFSAccess acc) +{ + int flags = 0; + if (BitEq(acc, pFS_READ) && BitEq(acc, pFS_WRITE)) + flags = O_RDWR; + else if (BitEq(acc, pFS_READ)) + flags = O_RDONLY; + else if (BitEq(acc, pFS_WRITE)) + flags = O_WRONLY; + + if (BitEq(acc, pFS_TRUNC)) + flags |= O_TRUNC; + else if (BitEq(acc, pFS_APPEND)) + flags |= O_APPEND; + + return open(file_name, flags); +} + +static void pFileClose(pFile file) +{ + close(file); +} + +// TODO: make these more resilient +static u64 pFileRead(pFile file, u64 offset, rawptr buf, u64 len) +{ + lseek(file, (isize)offset, SEEK_SET); + return read(file, buf, (usize)len); +} + +static u64 pFileWrite(pFile file, u64 offset, rawptr buf, u64 len) +{ + lseek(file, (isize)offset, SEEK_SET); + return write(file, buf, (usize)len); +} + +static u64 pFileSeek(pFile file, u64 pos) +{ + return (u64)lseek(file, (isize)pos, SEEK_SET); +} + +static u64 pFileLength(pFile file) +{ + isize offset = lseek(file, 0, SEEK_CUR); + isize size = lseek(file, 0, SEEK_END); + lseek(file, offset, SEEK_SET); + + if (size == -1) + size = UINT64_MAX; + + return (u64)size; +} + c8 **pDirGetFileNames(Arena *arena, u32 *count) { struct dirent *dir; @@ -269,18 +322,19 @@ c8 **pDirGetFileNames(Arena *arena, u32 *count) return (c8 **)file_names; } -static b8 pDirIsVisible(c8 *dir_name) +static b32 pFSIsVisible(c8 *name, b32 is_dir) { - b8 found = false; + b32 found = false; struct dirent *dir; DIR *d = opendir("."); + u8 type = is_dir ? DT_DIR : DT_REG; if (d) { while ((dir = readdir(d)) != NULL) { - if (StrEq(dir_name, dir->d_name) && dir->d_type == DT_DIR) + if (StrEq(name, dir->d_name) && dir->d_type == type) { found = true; break; @@ -291,7 +345,28 @@ static b8 pDirIsVisible(c8 *dir_name) return found; } -// ::Platform::Functions::Directory::End:: +static b32 pDirIsVisible(c8 *dir_name) +{ + return pFSIsVisible(dir_name, true); +} + +static b32 pFileIsVisible(c8 *file_name) +{ + return pFSIsVisible(file_name, false); +} + +static b32 pFileCanAccess(c8 *file_name, pFSAccess file_access) +{ + int a = 0; + if (BitEq(file_access, pFS_READ)) + a |= R_OK; + if (BitEq(file_access, pFS_WRITE)) + a |= W_OK; + + return access(file_name, a) == 0; +} + +// ::Platform::FileSystem::Functions::End:: diff --git a/src/renderer.h b/src/renderer.h index 5480c89..9f6bff4 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -22,10 +22,11 @@ typedef struct rShaderGlobals rShaderGlobals; typedef enum Pipeline_e { - R_PIPELINE_CUBE, - R_PIPELINE_GUI, + rPIPELINE_CUBE, + rPIPELINE_GUI, + rPIPELINE_PBR, - R_PIPELINE_MAX, + rPIPELINE_MAX, } rPipelineHandle; typedef enum PipelineType_e @@ -72,6 +73,12 @@ typedef struct rUIVertex u32 tex_idx; } rUIVertex; +typedef struct rPBRVertex +{ + Vec4 pos; + Vec4 col; +} rPBRVertex; + typedef struct rUploadQueue { union diff --git a/src/renderer_vulkan.c b/src/renderer_vulkan.c index 83e713b..51ee4da 100644 --- a/src/renderer_vulkan.c +++ b/src/renderer_vulkan.c @@ -1534,12 +1534,9 @@ static b32 vPipelinesInit() VkResult result; VkDevice device = v_Renderer.handles.device; - Asset quad_vert_shader = apLoadShader(QUAD_VERT_SPIRV_SHADER); - Asset quad_frag_shader = apLoadShader(QUAD_FRAG_SPIRV_SHADER); - - VkShaderModule cube_vert, cube_frag; - success &= vShaderModuleInit(quad_vert_shader.bytes, quad_vert_shader.len, &cube_vert); - success &= vShaderModuleInit(quad_frag_shader.bytes, quad_frag_shader.len, &cube_frag); + /* + * SHARED + */ VkPipelineRenderingCreateInfo pipeline_render_info = { .sType = STYPE(PIPELINE_RENDERING_CREATE_INFO), @@ -1548,6 +1545,17 @@ static b32 vPipelinesInit() .depthAttachmentFormat = v_Renderer.images.depth.image.format, }; + /* + * QUAD PIPELINE START + */ + + Asset quad_vert_shader = apLoadShader(QUAD_VERT_SPIRV_SHADER); + Asset quad_frag_shader = apLoadShader(QUAD_FRAG_SPIRV_SHADER); + + VkShaderModule cube_vert, cube_frag; + success &= vShaderModuleInit(quad_vert_shader.bytes, quad_vert_shader.len, &cube_vert); + success &= vShaderModuleInit(quad_frag_shader.bytes, quad_frag_shader.len, &cube_frag); + VkPipelineShaderStageCreateInfo cube_shader_stages[] = { { .sType = STYPE(PIPELINE_SHADER_STAGE_CREATE_INFO), @@ -1568,7 +1576,7 @@ static b32 vPipelinesInit() cube_create_info.layout = v_Renderer.handles.pipeline_layout; cube_create_info.pNext = &pipeline_render_info; - result = vkCreateGraphicsPipelines(device, 0, 1, &cube_create_info, NULL, &v_Renderer.handles.pipelines[R_PIPELINE_CUBE]); + result = vkCreateGraphicsPipelines(device, 0, 1, &cube_create_info, NULL, &v_Renderer.handles.pipelines[rPIPELINE_CUBE]); if (result != VK_SUCCESS) { Printf("vkCreateGraphicsPipelines failure: %s", vVkResultStr(result)); @@ -1581,6 +1589,10 @@ static b32 vPipelinesInit() apUnloadShader(QUAD_VERT_SPIRV_SHADER); apUnloadShader(QUAD_FRAG_SPIRV_SHADER); + /* + * GUI PIPELINE START + */ + Asset gui_vert_shader = apLoadShader(GUI_VERT_SPIRV_SHADER); Asset gui_frag_shader = apLoadShader(GUI_FRAG_SPIRV_SHADER); @@ -1608,7 +1620,7 @@ static b32 vPipelinesInit() gui_create_info.layout = v_Renderer.handles.pipeline_layout; gui_create_info.pNext = &pipeline_render_info; - result = vkCreateGraphicsPipelines(device, 0, 1, &gui_create_info, NULL, &v_Renderer.handles.pipelines[R_PIPELINE_GUI]); + result = vkCreateGraphicsPipelines(device, 0, 1, &gui_create_info, NULL, &v_Renderer.handles.pipelines[rPIPELINE_GUI]); if (result != VK_SUCCESS) { Printfln("vkCreateGraphicsPipelines failure: %s", vVkResultStr(result)); @@ -1621,6 +1633,50 @@ static b32 vPipelinesInit() apUnloadShader(GUI_VERT_SPIRV_SHADER); apUnloadShader(GUI_FRAG_SPIRV_SHADER); + /* + * PBR PIPELINE START + */ + + Asset pbr_vert_shader = apLoadShader(PBR_VERT_SPIRV_SHADER); + Asset pbr_frag_shader = apLoadShader(PBR_FRAG_SPIRV_SHADER); + + VkShaderModule pbr_vert, pbr_frag; + success &= vShaderModuleInit(pbr_vert_shader.bytes, pbr_vert_shader.len, &pbr_vert); + success &= vShaderModuleInit(pbr_frag_shader.bytes, pbr_frag_shader.len, &pbr_frag); + + VkPipelineShaderStageCreateInfo pbr_shader_stages[] = { + { + .sType = STYPE(PIPELINE_SHADER_STAGE_CREATE_INFO), + .stage = VK_SHADER_STAGE_VERTEX_BIT, + .module = pbr_vert, + .pName = "main", + }, + { + .sType = STYPE(PIPELINE_SHADER_STAGE_CREATE_INFO), + .stage = VK_SHADER_STAGE_FRAGMENT_BIT, + .module = pbr_frag, + .pName = "main", + }, + }; + + pbr_create_info.pStages = pbr_shader_stages; + pbr_create_info.stageCount = Len(pbr_shader_stages); + pbr_create_info.layout = v_Renderer.handles.pipeline_layout; + pbr_create_info.pNext = &pipeline_render_info; + + result = vkCreateGraphicsPipelines(device, 0, 1, &pbr_create_info, NULL, &v_Renderer.handles.pipelines[rPIPELINE_PBR]); + if (result != VK_SUCCESS) + { + Printfln("vkCreateGraphicsPipelineFailure: %s", vVkResultStr(result)); + success = false; + } + + vkDestroyShaderModule(device, pbr_vert, NULL); + vkDestroyShaderModule(device, pbr_frag, NULL); + + apUnloadShader(PBR_VERT_SPIRV_SHADER); + apUnloadShader(PBR_FRAG_SPIRV_SHADER); + return success; } diff --git a/src/renderer_vulkan.h b/src/renderer_vulkan.h index 8d8b93a..00a9747 100644 --- a/src/renderer_vulkan.h +++ b/src/renderer_vulkan.h @@ -312,7 +312,7 @@ typedef struct vRHandles VkSwapchainKHR swapchain; VmaAllocator vma_alloc; VkDescriptorPool desc_pool; - VkPipeline pipelines[R_PIPELINE_MAX]; + VkPipeline pipelines[rPIPELINE_MAX]; VkPipelineLayout pipeline_layout; VkDescriptorSetLayout desc_layouts[vDT_MAX]; VkDescriptorSet desc_sets[vDT_MAX]; diff --git a/src/renderer_vulkan_public.c b/src/renderer_vulkan_public.c index 45a29d8..0eff72a 100644 --- a/src/renderer_vulkan_public.c +++ b/src/renderer_vulkan_public.c @@ -53,7 +53,7 @@ void rDestroy() vkDestroySampler(device, nearest_sampler, NULL); - for (u32 i = R_PIPELINE_CUBE; i < R_PIPELINE_MAX; i++) + for (u32 i = rPIPELINE_CUBE; i < rPIPELINE_MAX; i++) vkDestroyPipeline(device, pipelines[i], NULL); vkDestroyPipelineLayout(device, pipeline_layout, NULL); diff --git a/src/shaders/glsl/pbr.frag.glsl b/src/shaders/glsl/pbr.frag.glsl new file mode 100644 index 0000000..8f686c6 --- /dev/null +++ b/src/shaders/glsl/pbr.frag.glsl @@ -0,0 +1,16 @@ +#version 460 + +#extension GL_EXT_buffer_reference : require +#extension GL_GOOGLE_include_directive : require +#extension GL_EXT_nonuniform_qualifier : require + +#include "structures.glsl" + +layout (location = 0) in vec4 in_col; + +layout (location = 0) out vec4 out_frag_col; + +void main() +{ + out_frag_col = in_col; +} diff --git a/src/shaders/glsl/pbr.vert.glsl b/src/shaders/glsl/pbr.vert.glsl new file mode 100644 index 0000000..0b3848d --- /dev/null +++ b/src/shaders/glsl/pbr.vert.glsl @@ -0,0 +1,18 @@ +#version 460 + +#extension GL_EXT_buffer_reference : require +#extension GL_GOOGLE_include_directive : require +#extension GL_EXT_nonuniform_qualifier : require + +#include "structures.glsl" + +layout (location = 0) in vec4 in_pos; +layout (location = 1) in vec4 in_col; + +layout (location = 0) out vec4 out_col; + +void main() +{ + out_col = in_col; + gl_Position = in_pos; +} diff --git a/src/vulkan_config.c b/src/vulkan_config.c index a307e4d..cb31429 100644 --- a/src/vulkan_config.c +++ b/src/vulkan_config.c @@ -451,8 +451,41 @@ VkPipelineInputAssemblyStateCreateInfo gui_assembly_info = { .primitiveRestartEnable = VK_FALSE, }; +// PBR Pipeline +INIT_PIPELINE_DEFAULTS(pbr); + +VkVertexInputBindingDescription pbr_input_bind_desc = { + .binding = 0, + .stride = sizeof(rPBRVertex), + .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, +}; + +VkVertexInputAttributeDescription pbr_input_descriptions[] = { + { .binding = 0, .location = 0, .format = VK_FORMAT_R32G32B32A32_SFLOAT, .offset = 0 }, + { .binding = 1, .location = 1, .format = VK_FORMAT_R32G32B32A32_SFLOAT, .offset = offsetof(rPBRVertex, col) }, +}; + +VkPipelineVertexInputStateCreationInfo pbr_vertex_input_info = { + .sType = STYPE(PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO), + .vertexBindingDescriptionCount = 1, + .pVertexBindingDescriptions = &pbr_vertex_bind_desc, + .vertexAttributeDescriptionCount = Len(pbr_input_descriptions), + .pVertexAttributeDescriptions = pbr_input_descriptions, +}; + +VkPipelineInputAssemblyStateCreateInfo pbr_assembly_info = { + .sType = STYPE(PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO), + .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, + .primitiveRestartEnable = VK_FALSE, +}; + static void vCustomizePipelines() { + // GUI gui_create_info.pVertexInputState = &gui_vertex_input_info; gui_create_info.pInputAssemblyState = &gui_assembly_info; + + // PBR + pbr_create_info.pVertexInputState = &pbr_vertex_input_info; + pbr_create_info.pInputAssemblyState = &pbr_assembly_info; }