resizes and everything... Big Big Moves

This commit is contained in:
Alex Janka 2023-10-03 11:47:29 +11:00
parent 520d2e148b
commit 29a5c272b4
4 changed files with 1096 additions and 755 deletions

View file

@ -0,0 +1,649 @@
use ash::{
extensions::khr::{Surface, Swapchain},
vk, Device,
};
use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
use winit::window::Window;
use crate::window::ResolutionData;
use super::{
utils::{find_memorytype_index, record_submit_commandbuffer},
WindowDataManager,
};
#[derive(Clone, Debug, Copy)]
pub(super) struct Vertex(pub(super) f32, pub(super) f32);
pub(super) struct VulkanData {
pub(super) pdevice: vk::PhysicalDevice,
pub(super) device: Device,
pub(super) device_memory_properties: vk::PhysicalDeviceMemoryProperties,
pub(super) desc_set_layouts: [vk::DescriptorSetLayout; 1],
pub(super) present_queue: vk::Queue,
pub(super) pool: vk::CommandPool,
pub(super) draw_command_buffer: vk::CommandBuffer,
pub(super) setup_command_buffer: vk::CommandBuffer,
pub(super) present_complete_semaphore: vk::Semaphore,
pub(super) rendering_complete_semaphore: vk::Semaphore,
pub(super) draw_commands_reuse_fence: vk::Fence,
pub(super) setup_commands_reuse_fence: vk::Fence,
pub(super) descriptor_sets: Vec<vk::DescriptorSet>,
pub(super) descriptor_pool: vk::DescriptorPool,
}
impl VulkanData {
pub(super) unsafe fn new(manager: &WindowDataManager, surface: &SurfaceData) -> Self {
let pdevices = manager
.instance
.enumerate_physical_devices()
.expect("Physical device error");
let (pdevice, queue_family_index) = pdevices
.iter()
.find_map(|pdevice| {
manager
.instance
.get_physical_device_queue_family_properties(*pdevice)
.iter()
.enumerate()
.find_map(|(index, info)| {
let supports_graphic_and_surface =
info.queue_flags.contains(vk::QueueFlags::GRAPHICS)
&& surface
.surface_loader
.get_physical_device_surface_support(
*pdevice,
index as u32,
surface.surface,
)
.unwrap();
if supports_graphic_and_surface {
Some((*pdevice, index))
} else {
None
}
})
})
.expect("Couldn't find suitable device.");
let queue_family_index = queue_family_index as u32;
let device_extension_names_raw = [
Swapchain::name().as_ptr(),
#[cfg(any(target_os = "macos", target_os = "ios"))]
vk::KhrPortabilitySubsetFn::name().as_ptr(),
];
let features = vk::PhysicalDeviceFeatures {
shader_clip_distance: 1,
..Default::default()
};
let priorities = [1.0];
let queue_info = vk::DeviceQueueCreateInfo::builder()
.queue_family_index(queue_family_index)
.queue_priorities(&priorities)
.build();
let device_create_info = vk::DeviceCreateInfo::builder()
.queue_create_infos(std::slice::from_ref(&queue_info))
.enabled_extension_names(&device_extension_names_raw)
.enabled_features(&features)
.build();
let device = manager
.instance
.create_device(pdevice, &device_create_info, None)
.unwrap();
let present_queue = device.get_device_queue(queue_family_index, 0);
let pool_create_info = vk::CommandPoolCreateInfo::builder()
.flags(vk::CommandPoolCreateFlags::RESET_COMMAND_BUFFER)
.queue_family_index(queue_family_index)
.build();
let pool = device.create_command_pool(&pool_create_info, None).unwrap();
let command_buffer_allocate_info = vk::CommandBufferAllocateInfo::builder()
.command_buffer_count(2)
.command_pool(pool)
.level(vk::CommandBufferLevel::PRIMARY)
.build();
let command_buffers = device
.allocate_command_buffers(&command_buffer_allocate_info)
.unwrap();
let setup_command_buffer = command_buffers[0];
let draw_command_buffer = command_buffers[1];
let device_memory_properties = manager
.instance
.get_physical_device_memory_properties(pdevice);
let fence_create_info = vk::FenceCreateInfo::builder()
.flags(vk::FenceCreateFlags::SIGNALED)
.build();
let draw_commands_reuse_fence = device
.create_fence(&fence_create_info, None)
.expect("Create fence failed.");
let setup_commands_reuse_fence = device
.create_fence(&fence_create_info, None)
.expect("Create fence failed.");
let semaphore_create_info = vk::SemaphoreCreateInfo::default();
let present_complete_semaphore = device
.create_semaphore(&semaphore_create_info, None)
.unwrap();
let rendering_complete_semaphore = device
.create_semaphore(&semaphore_create_info, None)
.unwrap();
let descriptor_sizes = [
vk::DescriptorPoolSize {
ty: vk::DescriptorType::UNIFORM_BUFFER,
descriptor_count: 1,
},
vk::DescriptorPoolSize {
ty: vk::DescriptorType::COMBINED_IMAGE_SAMPLER,
descriptor_count: 1,
},
];
let descriptor_pool_info = vk::DescriptorPoolCreateInfo::builder()
.pool_sizes(&descriptor_sizes)
.max_sets(1)
.build();
let descriptor_pool = device
.create_descriptor_pool(&descriptor_pool_info, None)
.unwrap();
let desc_layout_bindings = [
vk::DescriptorSetLayoutBinding {
descriptor_type: vk::DescriptorType::UNIFORM_BUFFER,
descriptor_count: 1,
stage_flags: vk::ShaderStageFlags::FRAGMENT,
..Default::default()
},
vk::DescriptorSetLayoutBinding {
binding: 1,
descriptor_type: vk::DescriptorType::COMBINED_IMAGE_SAMPLER,
descriptor_count: 1,
stage_flags: vk::ShaderStageFlags::FRAGMENT,
..Default::default()
},
];
let descriptor_info = vk::DescriptorSetLayoutCreateInfo::builder()
.bindings(&desc_layout_bindings)
.build();
let desc_set_layouts = [device
.create_descriptor_set_layout(&descriptor_info, None)
.unwrap()];
let desc_alloc_info = vk::DescriptorSetAllocateInfo::builder()
.descriptor_pool(descriptor_pool)
.set_layouts(&desc_set_layouts)
.build();
let descriptor_sets = device.allocate_descriptor_sets(&desc_alloc_info).unwrap();
Self {
pdevice,
device,
device_memory_properties,
present_queue,
pool,
draw_command_buffer,
setup_command_buffer,
present_complete_semaphore,
rendering_complete_semaphore,
draw_commands_reuse_fence,
setup_commands_reuse_fence,
descriptor_sets,
desc_set_layouts,
descriptor_pool,
}
}
}
pub(super) struct SurfaceData {
pub(super) surface: vk::SurfaceKHR,
pub(super) surface_loader: Surface,
}
impl SurfaceData {
pub(super) unsafe fn new(window: &Window, manager: &WindowDataManager) -> Self {
let surface = ash_window::create_surface(
&manager.entry,
&manager.instance,
window.raw_display_handle(),
window.raw_window_handle(),
None,
)
.unwrap();
let surface_loader = Surface::new(&manager.entry, &manager.instance);
Self {
surface,
surface_loader,
}
}
pub(super) unsafe fn manual_drop(&mut self) {
self.surface_loader.destroy_surface(self.surface, None);
}
}
pub(super) struct SwapchainData {
pub(super) swapchain_loader: Swapchain,
pub(super) swapchain: vk::SwapchainKHR,
pub(super) format: vk::SurfaceFormatKHR,
pub(super) surface_resolution: vk::Extent2D,
pub(super) present_image_views: Vec<vk::ImageView>,
pub(super) viewports: [vk::Viewport; 1],
pub(super) scissors: [vk::Rect2D; 1],
pub(super) sampler: vk::Sampler,
pub(super) texture_memory: vk::DeviceMemory,
pub(super) tex_image_view: vk::ImageView,
pub(super) image_buffer: vk::Buffer,
pub(super) image_buffer_memory: vk::DeviceMemory,
pub(super) image_buffer_memory_req: vk::MemoryRequirements,
pub(super) image_extent: vk::Extent2D,
pub(super) texture_image: vk::Image,
}
impl SwapchainData {
pub(super) unsafe fn new(
resolutions: ResolutionData,
manager: &WindowDataManager,
surface: &SurfaceData,
vulkan: &VulkanData,
) -> (Self, vk::PipelineViewportStateCreateInfo) {
let format = surface
.surface_loader
.get_physical_device_surface_formats(vulkan.pdevice, surface.surface)
.unwrap()[0];
let surface_capabilities = surface
.surface_loader
.get_physical_device_surface_capabilities(vulkan.pdevice, surface.surface)
.unwrap();
let mut desired_image_count = surface_capabilities.min_image_count + 1;
if surface_capabilities.max_image_count > 0
&& desired_image_count > surface_capabilities.max_image_count
{
desired_image_count = surface_capabilities.max_image_count;
}
let surface_resolution = match surface_capabilities.current_extent.width {
std::u32::MAX => vk::Extent2D {
width: resolutions.real_width,
height: resolutions.real_height,
},
_ => surface_capabilities.current_extent,
};
let pre_transform = if surface_capabilities
.supported_transforms
.contains(vk::SurfaceTransformFlagsKHR::IDENTITY)
{
vk::SurfaceTransformFlagsKHR::IDENTITY
} else {
surface_capabilities.current_transform
};
let present_modes = surface
.surface_loader
.get_physical_device_surface_present_modes(vulkan.pdevice, surface.surface)
.unwrap();
let present_mode = present_modes
.iter()
.cloned()
.find(|&mode| mode == vk::PresentModeKHR::MAILBOX)
.unwrap_or(vk::PresentModeKHR::FIFO);
let swapchain_loader = Swapchain::new(&manager.instance, &vulkan.device);
let swapchain_create_info = vk::SwapchainCreateInfoKHR::builder()
.surface(surface.surface)
.min_image_count(desired_image_count)
.image_color_space(format.color_space)
.image_format(format.format)
.image_extent(surface_resolution)
.image_usage(vk::ImageUsageFlags::COLOR_ATTACHMENT)
.image_sharing_mode(vk::SharingMode::EXCLUSIVE)
.pre_transform(pre_transform)
.composite_alpha(vk::CompositeAlphaFlagsKHR::OPAQUE)
.present_mode(present_mode)
.clipped(true)
.image_array_layers(1)
.build();
let swapchain = swapchain_loader
.create_swapchain(&swapchain_create_info, None)
.unwrap();
let present_images = swapchain_loader.get_swapchain_images(swapchain).unwrap();
let present_image_views: Vec<vk::ImageView> = present_images
.iter()
.map(|&image| {
let create_view_info = vk::ImageViewCreateInfo::builder()
.view_type(vk::ImageViewType::TYPE_2D)
.format(format.format)
.components(vk::ComponentMapping {
r: vk::ComponentSwizzle::R,
g: vk::ComponentSwizzle::G,
b: vk::ComponentSwizzle::B,
a: vk::ComponentSwizzle::A,
})
.subresource_range(vk::ImageSubresourceRange {
aspect_mask: vk::ImageAspectFlags::COLOR,
base_mip_level: 0,
level_count: 1,
base_array_layer: 0,
layer_count: 1,
})
.image(image)
.build();
vulkan
.device
.create_image_view(&create_view_info, None)
.unwrap()
})
.collect();
let viewports = [vk::Viewport {
x: 0.0,
y: 0.0,
width: surface_resolution.width as f32,
height: surface_resolution.height as f32,
min_depth: 0.0,
max_depth: 1.0,
}];
let scissors = [surface_resolution.into()];
let viewport_state_info = vk::PipelineViewportStateCreateInfo::builder()
.scissors(&scissors)
.viewports(&viewports)
.build();
let image_extent = vk::Extent2D {
width: resolutions.scaled_width,
height: resolutions.scaled_height,
};
let image_buffer_info = vk::BufferCreateInfo {
size: (std::mem::size_of::<u8>()
* (resolutions.scaled_width * resolutions.scaled_height * 4) as usize)
as u64,
usage: vk::BufferUsageFlags::TRANSFER_SRC,
sharing_mode: vk::SharingMode::EXCLUSIVE,
..Default::default()
};
let image_buffer = vulkan
.device
.create_buffer(&image_buffer_info, None)
.unwrap();
let image_buffer_memory_req = vulkan.device.get_buffer_memory_requirements(image_buffer);
let image_buffer_memory_index = find_memorytype_index(
&image_buffer_memory_req,
&vulkan.device_memory_properties,
vk::MemoryPropertyFlags::HOST_VISIBLE | vk::MemoryPropertyFlags::HOST_COHERENT,
)
.expect("Unable to find suitable memorytype for the image buffer.");
let image_buffer_allocate_info = vk::MemoryAllocateInfo {
allocation_size: image_buffer_memory_req.size,
memory_type_index: image_buffer_memory_index,
..Default::default()
};
let image_buffer_memory = vulkan
.device
.allocate_memory(&image_buffer_allocate_info, None)
.unwrap();
vulkan
.device
.bind_buffer_memory(image_buffer, image_buffer_memory, 0)
.unwrap();
let texture_create_info = vk::ImageCreateInfo {
image_type: vk::ImageType::TYPE_2D,
format: vk::Format::R8G8B8A8_UNORM,
extent: image_extent.into(),
mip_levels: 1,
array_layers: 1,
samples: vk::SampleCountFlags::TYPE_1,
tiling: vk::ImageTiling::OPTIMAL,
usage: vk::ImageUsageFlags::TRANSFER_DST | vk::ImageUsageFlags::SAMPLED,
sharing_mode: vk::SharingMode::EXCLUSIVE,
..Default::default()
};
let texture_image = vulkan
.device
.create_image(&texture_create_info, None)
.unwrap();
let texture_memory_req = vulkan.device.get_image_memory_requirements(texture_image);
let texture_memory_index = find_memorytype_index(
&texture_memory_req,
&vulkan.device_memory_properties,
vk::MemoryPropertyFlags::DEVICE_LOCAL,
)
.expect("Unable to find suitable memory index for depth image.");
let texture_allocate_info = vk::MemoryAllocateInfo {
allocation_size: texture_memory_req.size,
memory_type_index: texture_memory_index,
..Default::default()
};
let texture_memory = vulkan
.device
.allocate_memory(&texture_allocate_info, None)
.unwrap();
vulkan
.device
.bind_image_memory(texture_image, texture_memory, 0)
.expect("Unable to bind depth image memory");
record_submit_commandbuffer(
&vulkan.device,
vulkan.setup_command_buffer,
vulkan.setup_commands_reuse_fence,
vulkan.present_queue,
&[],
&[],
&[],
|device, texture_command_buffer| {
let texture_barrier = vk::ImageMemoryBarrier {
dst_access_mask: vk::AccessFlags::TRANSFER_WRITE,
new_layout: vk::ImageLayout::TRANSFER_DST_OPTIMAL,
image: texture_image,
subresource_range: vk::ImageSubresourceRange {
aspect_mask: vk::ImageAspectFlags::COLOR,
level_count: 1,
layer_count: 1,
..Default::default()
},
..Default::default()
};
device.cmd_pipeline_barrier(
texture_command_buffer,
vk::PipelineStageFlags::BOTTOM_OF_PIPE,
vk::PipelineStageFlags::TRANSFER,
vk::DependencyFlags::empty(),
&[],
&[],
&[texture_barrier],
);
let buffer_copy_regions = vk::BufferImageCopy::builder()
.image_subresource(
vk::ImageSubresourceLayers::builder()
.aspect_mask(vk::ImageAspectFlags::COLOR)
.layer_count(1)
.build(),
)
.image_extent(image_extent.into())
.build();
device.cmd_copy_buffer_to_image(
texture_command_buffer,
image_buffer,
texture_image,
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
&[buffer_copy_regions],
);
let texture_barrier_end = vk::ImageMemoryBarrier {
src_access_mask: vk::AccessFlags::TRANSFER_WRITE,
dst_access_mask: vk::AccessFlags::SHADER_READ,
old_layout: vk::ImageLayout::TRANSFER_DST_OPTIMAL,
new_layout: vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL,
image: texture_image,
subresource_range: vk::ImageSubresourceRange {
aspect_mask: vk::ImageAspectFlags::COLOR,
level_count: 1,
layer_count: 1,
..Default::default()
},
..Default::default()
};
device.cmd_pipeline_barrier(
texture_command_buffer,
vk::PipelineStageFlags::TRANSFER,
vk::PipelineStageFlags::FRAGMENT_SHADER,
vk::DependencyFlags::empty(),
&[],
&[],
&[texture_barrier_end],
);
},
);
let tex_image_view_info = vk::ImageViewCreateInfo {
view_type: vk::ImageViewType::TYPE_2D,
format: texture_create_info.format,
components: vk::ComponentMapping {
r: vk::ComponentSwizzle::R,
g: vk::ComponentSwizzle::G,
b: vk::ComponentSwizzle::B,
a: vk::ComponentSwizzle::A,
},
subresource_range: vk::ImageSubresourceRange {
aspect_mask: vk::ImageAspectFlags::COLOR,
level_count: 1,
layer_count: 1,
..Default::default()
},
image: texture_image,
..Default::default()
};
let sampler_info = vk::SamplerCreateInfo {
mag_filter: vk::Filter::NEAREST,
min_filter: vk::Filter::NEAREST,
mipmap_mode: vk::SamplerMipmapMode::NEAREST,
address_mode_u: vk::SamplerAddressMode::MIRRORED_REPEAT,
address_mode_v: vk::SamplerAddressMode::MIRRORED_REPEAT,
address_mode_w: vk::SamplerAddressMode::MIRRORED_REPEAT,
max_anisotropy: 1.0,
border_color: vk::BorderColor::FLOAT_OPAQUE_WHITE,
compare_op: vk::CompareOp::NEVER,
..Default::default()
};
let sampler = vulkan.device.create_sampler(&sampler_info, None).unwrap();
let tex_image_view = vulkan
.device
.create_image_view(&tex_image_view_info, None)
.unwrap();
let tex_descriptor = vk::DescriptorImageInfo {
image_layout: vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL,
image_view: tex_image_view,
sampler,
};
let write_desc_sets = [vk::WriteDescriptorSet {
dst_set: vulkan.descriptor_sets[0],
dst_binding: 1,
descriptor_count: 1,
descriptor_type: vk::DescriptorType::COMBINED_IMAGE_SAMPLER,
p_image_info: &tex_descriptor,
..Default::default()
}];
vulkan.device.update_descriptor_sets(&write_desc_sets, &[]);
(
Self {
swapchain_loader,
swapchain,
format,
surface_resolution,
present_image_views,
viewports,
scissors,
sampler,
texture_memory,
tex_image_view,
image_buffer,
image_buffer_memory,
image_buffer_memory_req,
image_extent,
texture_image,
},
viewport_state_info,
)
}
pub(super) unsafe fn manual_drop(&mut self, vulkan: &VulkanData) {
vulkan.device.free_memory(self.image_buffer_memory, None);
vulkan.device.destroy_buffer(self.image_buffer, None);
vulkan.device.free_memory(self.texture_memory, None);
vulkan.device.destroy_image_view(self.tex_image_view, None);
vulkan.device.destroy_image(self.texture_image, None);
vulkan.device.destroy_sampler(self.sampler, None);
for &image_view in self.present_image_views.iter() {
vulkan.device.destroy_image_view(image_view, None);
}
self.swapchain_loader
.destroy_swapchain(self.swapchain, None);
}
}
pub(super) struct FramebufferData {
pub(super) framebuffers: Vec<vk::Framebuffer>,
}
impl FramebufferData {
pub(super) unsafe fn new(
swapchain: &SwapchainData,
vulkan: &VulkanData,
renderpass: vk::RenderPass,
) -> Self {
let framebuffers: Vec<vk::Framebuffer> = swapchain
.present_image_views
.iter()
.map(|&present_image_view| {
let framebuffer_attachments = [present_image_view];
let frame_buffer_create_info = vk::FramebufferCreateInfo::builder()
.render_pass(renderpass)
.attachments(&framebuffer_attachments)
.width(swapchain.surface_resolution.width)
.height(swapchain.surface_resolution.height)
.layers(1)
.build();
vulkan
.device
.create_framebuffer(&frame_buffer_create_info, None)
.unwrap()
})
.collect();
Self { framebuffers }
}
}

View file

@ -0,0 +1,98 @@
use ash::{vk, Device};
#[allow(clippy::too_many_arguments)]
pub(super) unsafe fn record_submit_commandbuffer<F: FnOnce(&Device, vk::CommandBuffer)>(
device: &Device,
command_buffer: vk::CommandBuffer,
command_buffer_reuse_fence: vk::Fence,
submit_queue: vk::Queue,
wait_mask: &[vk::PipelineStageFlags],
wait_semaphores: &[vk::Semaphore],
signal_semaphores: &[vk::Semaphore],
f: F,
) {
record_commandbuffer(device, command_buffer, command_buffer_reuse_fence, f);
submit_commandbuffer(
device,
command_buffer,
command_buffer_reuse_fence,
submit_queue,
wait_mask,
wait_semaphores,
signal_semaphores,
);
}
#[allow(clippy::too_many_arguments)]
pub(super) unsafe fn record_commandbuffer<F: FnOnce(&Device, vk::CommandBuffer)>(
device: &Device,
command_buffer: vk::CommandBuffer,
command_buffer_reuse_fence: vk::Fence,
f: F,
) {
device
.wait_for_fences(&[command_buffer_reuse_fence], true, std::u64::MAX)
.expect("Wait for fence failed.");
device
.reset_fences(&[command_buffer_reuse_fence])
.expect("Reset fences failed.");
device
.reset_command_buffer(
command_buffer,
vk::CommandBufferResetFlags::RELEASE_RESOURCES,
)
.expect("Reset command buffer failed.");
let command_buffer_begin_info = vk::CommandBufferBeginInfo::builder()
.flags(vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT)
.build();
device
.begin_command_buffer(command_buffer, &command_buffer_begin_info)
.expect("Begin commandbuffer");
f(device, command_buffer);
}
pub(super) unsafe fn submit_commandbuffer(
device: &Device,
command_buffer: vk::CommandBuffer,
command_buffer_reuse_fence: vk::Fence,
submit_queue: vk::Queue,
wait_mask: &[vk::PipelineStageFlags],
wait_semaphores: &[vk::Semaphore],
signal_semaphores: &[vk::Semaphore],
) {
device
.end_command_buffer(command_buffer)
.expect("End commandbuffer");
let command_buffers = vec![command_buffer];
let submit_info = vk::SubmitInfo::builder()
.wait_semaphores(wait_semaphores)
.wait_dst_stage_mask(wait_mask)
.command_buffers(&command_buffers)
.signal_semaphores(signal_semaphores)
.build();
device
.queue_submit(submit_queue, &[submit_info], command_buffer_reuse_fence)
.expect("queue submit failed.");
}
pub(super) fn find_memorytype_index(
memory_req: &vk::MemoryRequirements,
memory_prop: &vk::PhysicalDeviceMemoryProperties,
flags: vk::MemoryPropertyFlags,
) -> Option<u32> {
memory_prop.memory_types[..memory_prop.memory_type_count as _]
.iter()
.enumerate()
.find(|(index, memory_type)| {
(1 << index) & memory_req.memory_type_bits != 0
&& memory_type.property_flags & flags == flags
})
.map(|(index, _memory_type)| index as _)
}

File diff suppressed because it is too large Load diff

View file

@ -8,6 +8,7 @@ use gilrs::{
ff::{BaseEffect, BaseEffectType, EffectBuilder, Replay, Ticks},
Button, Gilrs,
};
use raw_window_handle::HasRawDisplayHandle;
use winit::{
dpi::PhysicalSize,
event::{Event, VirtualKeyCode, WindowEvent},
@ -23,7 +24,15 @@ mod renderer;
use renderer::WindowData;
use self::renderer::WindowOptions;
use self::renderer::{WindowDataManager, WindowOptions};
#[derive(Clone, Copy, Debug)]
pub struct ResolutionData {
real_width: u32,
real_height: u32,
scaled_width: u32,
scaled_height: u32,
}
pub struct WindowInfo {
id: WindowId,
@ -33,15 +42,22 @@ pub struct WindowInfo {
pub struct WindowManager {
event_loop: EventLoop<()>,
windows: HashMap<WindowId, Arc<Mutex<WindowData>>>,
window_data_manager: Arc<WindowDataManager>,
input: Arc<Mutex<WinitInputHelper>>,
sender: Sender<EmulatorMessage>,
}
impl WindowManager {
pub(crate) fn new(sender: Sender<EmulatorMessage>) -> Self {
let event_loop = EventLoop::new();
#[cfg(feature = "vulkan")]
let window_data_manager = Arc::new(WindowDataManager::new(event_loop.raw_display_handle()));
#[cfg(feature = "pixels")]
let window_data_manager = Arc::new(WindowDataManager::new());
Self {
event_loop: EventLoop::new(),
event_loop,
windows: HashMap::new(),
window_data_manager,
input: Arc::new(Mutex::new(WinitInputHelper::new())),
sender,
}
@ -53,6 +69,7 @@ impl WindowManager {
gamepad_handler,
self.input.clone(),
&self.event_loop,
self.window_data_manager.clone(),
);
self.windows.insert(info.id, info.data);
r
@ -95,7 +112,7 @@ pub struct WindowRenderer {
width: usize,
height: usize,
factor: usize,
real_factor: usize,
real_factor: u32,
gamepad_handler: Option<Gilrs>,
joypad_state: JoypadState,
current_rumble: bool,
@ -107,6 +124,7 @@ impl WindowRenderer {
gamepad_handler: Option<Gilrs>,
input: Arc<Mutex<WinitInputHelper>>,
event_loop: &EventLoop<()>,
manager: Arc<WindowDataManager>,
) -> (Self, WindowInfo) {
let window = WindowBuilder::new()
.with_title("Gameboy")
@ -114,7 +132,14 @@ impl WindowRenderer {
.build(event_loop)
.unwrap();
let real_factor = (window.scale_factor() * factor as f64) as usize;
let real_factor = (window.scale_factor() * factor as f64) as u32;
let inner_size = window.inner_size();
let resolutions = ResolutionData {
real_width: inner_size.width,
real_height: inner_size.height,
scaled_width: inner_size.width / real_factor,
scaled_height: inner_size.height / real_factor,
};
let options = WindowOptions {
shader_path: std::path::PathBuf::from(
@ -123,9 +148,10 @@ impl WindowRenderer {
};
let data = Arc::new(Mutex::new(WindowData::new(
real_factor as u32,
resolutions,
&window,
options,
manager,
)));
let info = WindowInfo {
id: window.id(),
@ -154,20 +180,23 @@ impl Renderer<[u8; 4]> for WindowRenderer {
fn prepare(&mut self, width: usize, height: usize) {
self.width = width;
self.height = height;
self.real_factor = (self.window.scale_factor() * self.factor as f64) as usize;
self.real_factor = (self.window.scale_factor() * self.factor as f64) as u32;
let w = (width * self.real_factor) as u32;
let h = (height * self.real_factor) as u32;
let real_width = (width as u32) * self.real_factor;
let real_height = (height as u32) * self.real_factor;
self.window.set_inner_size(PhysicalSize::new(w, h));
self.window
.set_inner_size(PhysicalSize::new(real_width, real_height));
let resolutions = ResolutionData {
real_width,
real_height,
scaled_width: width as u32,
scaled_height: height as u32,
};
if let Ok(mut data) = self.data.lock() {
data.resize(
width as u32,
height as u32,
self.real_factor as u32,
&self.window,
);
data.resize(resolutions, &self.window);
}
self.window.request_redraw();
}