Skip to content

Commit 57ac9c7

Browse files
fix: fix wgpu_texture to run on android emulator on mac with disable push constants
1 parent abd800d commit 57ac9c7

File tree

3 files changed

+80
-54
lines changed

3 files changed

+80
-54
lines changed

examples/wgpu_texture/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ name = "wgpu_texture_lib"
2323
slint = { path = "../../api/rs/slint", features = ["unstable-wgpu-27", "backend-android-activity-06"] }
2424
bytemuck = { workspace = true }
2525
wgpu-27 = { workspace = true, features = ["wgsl"] }
26+
spin_on = "0.1.1"
2627

2728
[build-dependencies]
2829
slint-build = { path = "../../api/rs/build" }
30+
31+
[package.metadata.android]
32+
hardware_accelerated = true

examples/wgpu_texture/lib.rs

Lines changed: 74 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,6 @@ struct DemoRenderer {
1313
start_time: std::time::Instant,
1414
}
1515

16-
#[repr(C)]
17-
#[derive(Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
18-
struct PushConstants {
19-
light_color_and_time: [f32; 4],
20-
}
21-
2216
impl DemoRenderer {
2317
fn new(device: &wgpu::Device, queue: &wgpu::Queue) -> Self {
2418
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
@@ -28,18 +22,9 @@ impl DemoRenderer {
2822
))),
2923
});
3024

31-
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
32-
label: None,
33-
bind_group_layouts: &[],
34-
push_constant_ranges: &[wgpu::PushConstantRange {
35-
stages: wgpu::ShaderStages::FRAGMENT,
36-
range: 0..16, // full size in bytes, aligned
37-
}],
38-
});
39-
4025
let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
4126
label: None,
42-
layout: Some(&pipeline_layout),
27+
layout: None, // Auto-layout
4328
vertex: wgpu::VertexState {
4429
module: &shader,
4530
entry_point: Some("vs_main"),
@@ -50,7 +35,7 @@ impl DemoRenderer {
5035
module: &shader,
5136
entry_point: Some("fs_main"),
5237
compilation_options: Default::default(),
53-
targets: &[Some(wgpu::TextureFormat::Rgba8UnormSrgb.into())],
38+
targets: &[Some(wgpu::TextureFormat::Rgba8Unorm.into())],
5439
}),
5540
primitive: wgpu::PrimitiveState::default(),
5641
depth_stencil: None,
@@ -77,38 +62,26 @@ impl DemoRenderer {
7762
mip_level_count: 1,
7863
sample_count: 1,
7964
dimension: wgpu::TextureDimension::D2,
80-
format: wgpu::TextureFormat::Rgba8UnormSrgb,
65+
format: wgpu::TextureFormat::Rgba8Unorm,
8166
usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::TEXTURE_BINDING,
8267
view_formats: &[],
8368
})
8469
}
8570

86-
fn render(
87-
&mut self,
88-
light_red: f32,
89-
light_green: f32,
90-
light_blue: f32,
91-
width: u32,
92-
height: u32,
93-
) -> wgpu::Texture {
94-
if self.texture.size().width != width || self.texture.size().height != height {
95-
self.texture = Self::create_texture(&self.device, width, height);
96-
}
97-
98-
let elapsed: f32 = self.start_time.elapsed().as_millis() as f32 / 500.;
99-
let push_constants =
100-
PushConstants { light_color_and_time: [light_red, light_green, light_blue, elapsed] };
71+
fn render(&self, _size: slint::PhysicalSize) -> wgpu::Texture {
72+
let _time = self.start_time.elapsed().as_secs_f32();
73+
let texture_view = self.texture.create_view(&wgpu::TextureViewDescriptor::default());
10174

10275
let mut encoder =
10376
self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
10477
{
10578
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
10679
label: None,
10780
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
108-
view: &self.texture.create_view(&wgpu::TextureViewDescriptor::default()),
81+
view: &texture_view,
10982
resolve_target: None,
11083
ops: wgpu::Operations {
111-
load: wgpu::LoadOp::Clear(wgpu::Color::GREEN),
84+
load: wgpu::LoadOp::Clear(wgpu::Color { r: 0.0, g: 0.0, b: 0.0, a: 1.0 }),
11285
store: wgpu::StoreOp::Store,
11386
},
11487
depth_slice: None,
@@ -118,11 +91,6 @@ impl DemoRenderer {
11891
occlusion_query_set: None,
11992
});
12093
rpass.set_pipeline(&self.pipeline);
121-
rpass.set_push_constants(
122-
wgpu::ShaderStages::FRAGMENT, // Stage (your constants are for fragment shader)
123-
0, // Offset in bytes (start at 0)
124-
bytemuck::bytes_of(&push_constants),
125-
);
12694
rpass.draw(0..3, 0..1);
12795
}
12896

@@ -132,7 +100,8 @@ impl DemoRenderer {
132100
}
133101
}
134102

135-
pub fn main() {
103+
#[cfg(not(target_os = "android"))]
104+
fn main() {
136105
let mut wgpu_settings = WGPUSettings::default();
137106
wgpu_settings.device_required_features = wgpu::Features::PUSH_CONSTANTS;
138107
wgpu_settings.device_required_limits.max_push_constant_size = 16;
@@ -163,13 +132,72 @@ pub fn main() {
163132
}
164133
slint::RenderingState::BeforeRendering => {
165134
if let (Some(renderer), Some(app)) = (renderer.as_mut(), app_weak.upgrade()) {
166-
let texture = renderer.render(
167-
app.get_selected_red(),
168-
app.get_selected_green(),
169-
app.get_selected_blue(),
135+
let texture = renderer.render(slint::PhysicalSize::new(
136+
app.get_requested_texture_width() as u32,
137+
app.get_requested_texture_height() as u32,
138+
));
139+
app.set_texture(slint::Image::try_from(texture).unwrap());
140+
app.window().request_redraw();
141+
}
142+
}
143+
slint::RenderingState::AfterRendering => {}
144+
slint::RenderingState::RenderingTeardown => {
145+
drop(renderer.take());
146+
}
147+
_ => {}
148+
}
149+
})
150+
.expect("Unable to set rendering notifier");
151+
152+
app.run().unwrap();
153+
}
154+
155+
#[cfg(target_os = "android")]
156+
fn main() {
157+
let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor {
158+
flags: wgpu::InstanceFlags::empty(),
159+
..Default::default()
160+
});
161+
162+
let adapter = spin_on::spin_on(async {
163+
instance
164+
.request_adapter(&Default::default())
165+
.await
166+
.expect("Failed to find an appropriate WGPU adapter")
167+
});
168+
169+
let (device, queue) = spin_on::spin_on(async {
170+
adapter.request_device(&Default::default()).await.expect("Failed to create WGPU device")
171+
});
172+
173+
slint::BackendSelector::new()
174+
.require_wgpu_27(WGPUConfiguration::Manual { instance, adapter, device, queue })
175+
.select()
176+
.expect("Unable to create Slint backend with WGPU based renderer");
177+
178+
let app = App::new().unwrap();
179+
180+
let mut renderer = None;
181+
182+
let app_weak = app.as_weak();
183+
184+
app.window()
185+
.set_rendering_notifier(move |state, graphics_api| {
186+
match state {
187+
slint::RenderingState::RenderingSetup => {
188+
match graphics_api {
189+
slint::GraphicsAPI::WGPU27 { device, queue, .. } => {
190+
renderer = Some(DemoRenderer::new(device, queue));
191+
}
192+
_ => return,
193+
};
194+
}
195+
slint::RenderingState::BeforeRendering => {
196+
if let (Some(renderer), Some(app)) = (renderer.as_mut(), app_weak.upgrade()) {
197+
let texture = renderer.render(slint::PhysicalSize::new(
170198
app.get_requested_texture_width() as u32,
171199
app.get_requested_texture_height() as u32,
172-
);
200+
));
173201
app.set_texture(slint::Image::try_from(texture).unwrap());
174202
app.window().request_redraw();
175203
}

examples/wgpu_texture/shader.wgsl

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,6 @@ fn vs_main(
2424
return output;
2525
}
2626

27-
struct PushConstants {
28-
light_color_and_time: vec4<f32>,
29-
};
30-
31-
var<push_constant> pc: PushConstants;
32-
3327
fn sdRoundBox(p: vec3<f32>, b: vec3<f32>, r: f32) -> f32 {
3428
let q = abs(p) - b;
3529
return length(max(q, vec3<f32>(0.0))) + min(max(q.x, max(q.y, q.z)), 0.0) - r;
@@ -59,7 +53,7 @@ fn rotateZ(r: vec3<f32>, angle: f32) -> vec3<f32> {
5953

6054
// Distance from the scene
6155
fn scene(r: vec3<f32>) -> f32 {
62-
let iTime = pc.light_color_and_time.w;
56+
let iTime = 1.0;
6357
let pos = rotateZ(rotateY(r + vec3<f32>(-1.0, -1.0, 4.0), iTime), iTime);
6458
let cube = vec3<f32>(0.5, 0.5, 0.5);
6559
let edge = 0.1;
@@ -104,7 +98,7 @@ fn render(fragCoord: vec2<f32>, light_color: vec3<f32>) -> vec4<f32> {
10498

10599
@fragment
106100
fn fs_main(@location(0) frag_position: vec2<f32>) -> @location(0) vec4<f32> {
107-
let selected_light_color = pc.light_color_and_time.xyz;
101+
let selected_light_color = vec3<f32>(0.0, 1.0, 0.0);
108102
let r = vec2<f32>(0.5 * frag_position.x + 1.0, 0.5 - 0.5 * frag_position.y);
109103
return render(r, selected_light_color);
110104
}

0 commit comments

Comments
 (0)