From 5ff05b7f02b2ff1b0859a9a61ca7e1af6476424f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Tue, 5 Nov 2019 20:40:17 +0100 Subject: [PATCH] Apply HiDPI scaling to quads The anti-aliasing strategy is pretty naive, but we will manage for now. --- wgpu/src/quad.rs | 58 +++++++++++++++++++++++++--------- wgpu/src/renderer.rs | 7 ++-- wgpu/src/shader/quad.frag | 8 ++--- wgpu/src/shader/quad.frag.spv | Bin 3212 -> 3044 bytes wgpu/src/shader/quad.vert | 20 +++++++----- wgpu/src/shader/quad.vert.spv | Bin 2544 -> 3020 bytes 6 files changed, 61 insertions(+), 32 deletions(-) diff --git a/wgpu/src/quad.rs b/wgpu/src/quad.rs index bfbd7e2d..4356f8af 100644 --- a/wgpu/src/quad.rs +++ b/wgpu/src/quad.rs @@ -6,7 +6,7 @@ use std::mem; pub struct Pipeline { pipeline: wgpu::RenderPipeline, constants: wgpu::BindGroup, - transform: wgpu::Buffer, + constants_buffer: wgpu::Buffer, vertices: wgpu::Buffer, indices: wgpu::Buffer, instances: wgpu::Buffer, @@ -23,20 +23,20 @@ impl Pipeline { }], }); - let transform = device + let constants_buffer = device .create_buffer_mapped( - 16, + 1, wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, ) - .fill_from_slice(Transformation::identity().as_ref()); + .fill_from_slice(&[Uniforms::default()]); let constants = device.create_bind_group(&wgpu::BindGroupDescriptor { layout: &constant_layout, bindings: &[wgpu::Binding { binding: 0, resource: wgpu::BindingResource::Buffer { - buffer: &transform, - range: 0..64, + buffer: &constants_buffer, + range: 0..std::mem::size_of::() as u64, }, }], }); @@ -124,7 +124,7 @@ impl Pipeline { }, wgpu::VertexAttributeDescriptor { shader_location: 4, - format: wgpu::VertexFormat::Uint, + format: wgpu::VertexFormat::Float, offset: 4 * (2 + 2 + 4), }, ], @@ -151,7 +151,7 @@ impl Pipeline { Pipeline { pipeline, constants, - transform, + constants_buffer, vertices, indices, instances, @@ -164,19 +164,22 @@ impl Pipeline { encoder: &mut wgpu::CommandEncoder, instances: &[Quad], transformation: Transformation, + scale: f32, bounds: Rectangle, target: &wgpu::TextureView, ) { - let transform_buffer = device - .create_buffer_mapped(16, wgpu::BufferUsage::COPY_SRC) - .fill_from_slice(transformation.as_ref()); + let uniforms = Uniforms::new(transformation, scale); + + let constants_buffer = device + .create_buffer_mapped(1, wgpu::BufferUsage::COPY_SRC) + .fill_from_slice(&[uniforms]); encoder.copy_buffer_to_buffer( - &transform_buffer, + &constants_buffer, 0, - &self.transform, + &self.constants_buffer, 0, - 16 * 4, + std::mem::size_of::() as u64, ); let mut i = 0; @@ -271,9 +274,34 @@ pub struct Quad { pub position: [f32; 2], pub scale: [f32; 2], pub color: [f32; 4], - pub border_radius: u32, + pub border_radius: f32, } impl Quad { const MAX: usize = 100_000; } + +#[repr(C)] +#[derive(Debug, Clone, Copy)] +struct Uniforms { + transform: [f32; 16], + scale: f32, +} + +impl Uniforms { + fn new(transformation: Transformation, scale: f32) -> Uniforms { + Self { + transform: *transformation.as_ref(), + scale, + } + } +} + +impl Default for Uniforms { + fn default() -> Self { + Self { + transform: *Transformation::identity().as_ref(), + scale: 1.0, + } + } +} diff --git a/wgpu/src/renderer.rs b/wgpu/src/renderer.rs index 7ac74e93..f46acb8c 100644 --- a/wgpu/src/renderer.rs +++ b/wgpu/src/renderer.rs @@ -239,7 +239,7 @@ impl Renderer { color: match background { Background::Color(color) => color.into_linear(), }, - border_radius: *border_radius as u32, + border_radius: *border_radius as f32, }); } Primitive::Image { path, bounds } => { @@ -327,13 +327,14 @@ impl Renderer { encoder, &layer.quads, transformation, + dpi, bounds, target, ); } if layer.images.len() > 0 { - let translated = transformation + let translated_and_scaled = transformation * Transformation::scale(dpi, dpi) * Transformation::translate( -(layer.offset.x as f32), @@ -344,7 +345,7 @@ impl Renderer { &mut self.device, encoder, &layer.images, - translated, + translated_and_scaled, bounds, target, ); diff --git a/wgpu/src/shader/quad.frag b/wgpu/src/shader/quad.frag index 849f581e..2ee77e71 100644 --- a/wgpu/src/shader/quad.frag +++ b/wgpu/src/shader/quad.frag @@ -3,7 +3,7 @@ layout(location = 0) in vec4 v_Color; layout(location = 1) in vec2 v_Pos; layout(location = 2) in vec2 v_Scale; -layout(location = 3) in flat uint v_BorderRadius; +layout(location = 3) in float v_BorderRadius; layout(location = 0) out vec4 o_Color; @@ -27,11 +27,7 @@ float rounded(in vec2 frag_coord, in vec2 position, in vec2 size, float radius, } void main() { - float radius_alpha = 1.0; - - if(v_BorderRadius > 0.0) { - radius_alpha = rounded(gl_FragCoord.xy, v_Pos, v_Scale, v_BorderRadius, 0.5); - } + float radius_alpha = rounded(gl_FragCoord.xy, v_Pos, v_Scale, v_BorderRadius, 0.5); o_Color = vec4(v_Color.xyz, v_Color.w * radius_alpha); } diff --git a/wgpu/src/shader/quad.frag.spv b/wgpu/src/shader/quad.frag.spv index 71b91b44f7cc7dda15caea27aeb00d1d99874601..17bd8f465ada98f5308097b3ce01c65532cdf70a 100644 GIT binary patch delta 1057 zcmeB?d?L=v%%sfDz`)4B&cMM?J(1U4G>U9}SgfXJB9e$%FVHCxPT)e2|kse2{r@Q1u`? zK=L3y$cc;$3~>zF3@l*F6F`n*V6X>i$YEe$0J$CJ01zMK2ap)Z0FVPgegIhj@<2Y+ z10Z>jdAbY?3`HO_CU0ahuLngJ%&8m<3=E*?Lgs^_3&!VUU|;}67cw6dT_C&&%n+A5>IAeU;v4MFvt@iSJ^QzGl1+(W?-mi0BHm%OogULkR-?vAU;ek9hy!- zav%qR_#in@m}NrKFGvpLI1nGi2008AY?ch1;2_LqU|KPaqK#D*Tfl$G61_lO@WgtsnViiy^Q1HRTDxqQ^ wM+7jigHvi10|Ns{KS(`DzKnr^0pvMQ0s+bWWng5mU|?i0gW9z@gI$Fc03WbsNB{r; delta 1244 zcmaDN-XqD&%%sfDz`)4B&cMOYJdxL3G?IaVA&G&3A%%f~A(erFp@e~fp>$(rG-EwT zrYznmzbGZOC@3){v$U9jft7&`tU5g>-mNGx-8nzM2&9pLm4O9pLRox3elY_`9ShjB zviRWS#GF*Hd?o_}LqTFuVlGrZ2aTVH%CBcAKowvpMB{^;nji0+pOaq%wxE=OfuRh_ zcV}Q`0C|9qfq}uDfd$N#V_;xlhVnsP=4N1E;D_=-z5vNHLiwo-@(c_h0Vb#b$TAS0 z0m?6(e3j{Ty#fOZLj(gTKp7Zx85kI>p?r|lAfrSWm>6Oh7#PGESQru*7#P?X7#LU> z7#KkM5~2D);vjt>KFC=heIWT{s60E=To51ROprWCeKG?>Jvfj-0@@5LV8b&&?qguE z2N?j02#|ka7J&F5Z-B%=27oLCg&9ac$bn^02ZH25=7Bs^2@Nxlc~wvcfjnWxz{5GxuP{C*C<+-E7?Am(Xa(`@7?>Ht85kJ685kIB8CbyK z8O6W=j=BP<_o5jX7(imX7+AsK8Vd>oke~?z1H*R)W`=l({~3NUurS0jFfhb1Fo4B= zFff7HFoV<33{GcYU;v4M>eR==@ diff --git a/wgpu/src/shader/quad.vert b/wgpu/src/shader/quad.vert index b7c5cf3e..539755cb 100644 --- a/wgpu/src/shader/quad.vert +++ b/wgpu/src/shader/quad.vert @@ -4,29 +4,33 @@ layout(location = 0) in vec2 v_Pos; layout(location = 1) in vec2 i_Pos; layout(location = 2) in vec2 i_Scale; layout(location = 3) in vec4 i_Color; -layout(location = 4) in uint i_BorderRadius; +layout(location = 4) in float i_BorderRadius; layout (set = 0, binding = 0) uniform Globals { mat4 u_Transform; + float u_Scale; }; layout(location = 0) out vec4 o_Color; layout(location = 1) out vec2 o_Pos; layout(location = 2) out vec2 o_Scale; -layout(location = 3) out uint o_BorderRadius; +layout(location = 3) out float o_BorderRadius; void main() { + vec2 p_Pos = i_Pos * u_Scale; + vec2 p_Scale = i_Scale * u_Scale; + mat4 i_Transform = mat4( - vec4(i_Scale.x, 0.0, 0.0, 0.0), - vec4(0.0, i_Scale.y, 0.0, 0.0), + vec4(p_Scale.x + 1.0, 0.0, 0.0, 0.0), + vec4(0.0, p_Scale.y + 1.0, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), - vec4(i_Pos, 0.0, 1.0) + vec4(p_Pos - vec2(0.5, 0.5), 0.0, 1.0) ); o_Color = i_Color; - o_Pos = i_Pos; - o_Scale = i_Scale; - o_BorderRadius = i_BorderRadius; + o_Pos = p_Pos; + o_Scale = p_Scale; + o_BorderRadius = i_BorderRadius * u_Scale; gl_Position = u_Transform * i_Transform * vec4(v_Pos, 0.0, 1.0); } diff --git a/wgpu/src/shader/quad.vert.spv b/wgpu/src/shader/quad.vert.spv index f62a160c1e8742a61653671cdb0373cee6c31487..9050adfb01dbe35088d3150834ade4555071ca2b 100644 GIT binary patch literal 3020 zcmZQ(Qf6mhU}Rut;9$sOfB-=TCI&_Z1_o{hHZbk(6YQf`T#}+^Vrl?V!NekF({tjTb21BDGK)(R^O95H`arP@k}J*0fy;ry3>0r5GeG_a z#a|i7N(Kf7cLo*)P~6BdfKn0zg9if(ILskxL3~IYfcVNFf&o>Goq>Tt07(qwZjd?$ zu-VLDvq0_z*#n9$4%W`q0>qG4hn^FU%C8YTuZ6C?&Q3nm6)gTz4Q zxic_>%>$_exdjx)AiF^33NtW)^NJ!k*D!$DVhqd-Yzzzx3JeSk;tVVdpl}57LHZRK zSQt1M7{Fp6aS)#i8b2VuH3JI+h!3(GJ!MnFr#7;s+!q%D}=P1a%w8d~GOS80rR)eh~(UKS1Vz^n=_3ia(Hg zkUYrmAh&|-1epi&CkTVW17seE4U2n_dQiFmsRx+{k_XYMAjJ#~_AtIWn9slf;)C>S zLfxaozz+7S9s>gdNDT;s^nz%RT98@b!jFN$UWb7d9Il283=AMK5C+-r4KC9lVFvOK zh!0ACpg0D}`$Fvkg(*lL#0RBEn12JH`aymG$%FWy^a;`r$uO`m#6sg66b5n(Y~Zv9avMlJNDhQS_QXT&0hK8rdq8|p zSpc#J6gHrEPK1UlNPQACUP18&QV)t(P+A7rYsSC|PP?Eq1=0dC;|Bv111kdq14u0> z&4S8(SQvo#pz;~U2c-#6c?{y)Leo4CxUOPgaAaU*0HrBW1_p5X4oYhvH6Z_pF)%QI z#QUIeC(gjY0MZ8%w_{*t0NDu=1E~j@Ed{N^U}j2VF;j+tfdM2AGgFp zVVId(3=9k)GeL0(GgF&^fdM2AGgF5Fl-?N_kj>PErgM-S%uJAekl*zg7{KAt3=JzI z1_lO@7%065LfvW1z`y_!2gM;w%mgY1if5SHO&J&%Kx#p9AbUV=fT=fQU|<0G4cQEH zs2Io$m^urn7^qxA9xj@B`&2xo{fy{%2ts4Ua11JnZ zVFn5#P?*5v+!+`cK;Z%MKghoz|H0%u7#J8pegpXh;#z&G6SR*l+Ho<5hMpnKcMo%AKLB%$$`p05FaE5N?SqDv;~p_m2DtC zOfCePmO*l$at_1?$$|1oB(&`aO81~V9)%@8Ml&!lfW%v&X*7m`fdQlsBn~nYR5pUd zKxTl-sAQ-apt1{O56F)x3=9k)aTp)eXaf0f5(6u^K1^d^U;wEBiG$RD{FDJ|n}OT8 zkUX5pz`y_!LyqSxs2C`oLE#Asr)*HWl7WE%BnQhI6B$^+^-vB20|Uq|kQ$JCL3K$k XwCxOXFUUV2K1khP21W)821W(|z1G8} literal 2544 zcmZQ(Qf6mhU}Rut;9!VkfB-=TCI&_Z1_o{hHZbk(6YQf`T#}+^Vrl?V!Nfq|8Qg#pz`&566CaRT6qZ_4l3D@sKN|xZ14tai2Fc|YXO?8<=P|G`u!F@x zVG9<|%qt1btV#u`gUNxyBRwbHIVZEgC9}9BF)uk4t`8LIAi2_<9Jm}S12Z^0L1uu$ z&F%TOh1~Si`ff;NbNSy}*3j-`XSfS>^_{vCj z!Nk}Z7#IXV;mN=Z)(0{JKuU;>AuA~>}}!c>fbnSqUg zfkAvtQVTK@BoCs6L5dj|7(jfGeo?3$ zAU;T55-i_fufxC&cB>Qv0|Q782!rH6v^4|7Eui!RG9TntQ*geA_zxrx;)Bu?D9%9g z=1_Y;VFHo|@j>Yerr!#x9~1^4c@Q6z-az_cd{BA=@j>R|kOl3=9k)KOmc@3Kc^(PYo)DY@Rw)4B0#l1_lODoxeMeDki8%|P&zhYU|;~*2{IdG z21ui#k?GFUJ$G5`SD2%WqD