Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Benjamin Lee
ball-gfx-hal
Commits
5cdcc664
Commit
5cdcc664
authored
Jan 28, 2019
by
Benjamin Lee
💬
Browse files
Detect present modes and only allow selecting supported ones.
parent
7ed49ab0
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/debug.rs
View file @
5cdcc664
...
...
@@ -4,6 +4,7 @@ use crate::ui;
use
crossbeam
::
channel
::{
self
,
Receiver
,
Sender
};
use
gfx_hal
::{
Backend
,
PresentMode
};
use
imgui
::{
im_str
,
ImString
,
Ui
};
use
smallvec
::
SmallVec
;
use
std
::
time
::
Duration
;
const
NETWORK_HISTORY_LENGTH
:
usize
=
256
;
...
...
@@ -180,23 +181,25 @@ impl DebugState {
)))
.build
();
let
supported
=
graphics
.supported_present_modes
();
let
labels
=
supported
.iter
()
.map
(|
present_mode
|
{
match
present_mode
{
PresentMode
::
Immediate
=>
im_str!
(
"immediate"
),
PresentMode
::
Relaxed
=>
im_str!
(
"relaxed"
),
PresentMode
::
Fifo
=>
im_str!
(
"fifo"
),
PresentMode
::
Mailbox
=>
im_str!
(
"mailbox"
),
}
})
.collect
::
<
SmallVec
<
[
_
;
4
]
>>
();
let
mut
present_mode
=
graphics
.present_mode
();
if
ui
::
enum_combo
(
&
ui
,
im_str!
(
"Present mode"
),
&
mut
present_mode
,
&
[
im_str!
(
"immediate"
),
im_str!
(
"relaxed"
),
im_str!
(
"fifo"
),
im_str!
(
"mailbox"
),
],
&
[
PresentMode
::
Immediate
,
PresentMode
::
Relaxed
,
PresentMode
::
Fifo
,
PresentMode
::
Mailbox
,
],
&
labels
,
supported
,
4
,
)
{
graphics
.set_present_mode
(
present_mode
);
...
...
src/graphics/circles.rs
View file @
5cdcc664
...
...
@@ -24,7 +24,6 @@ use gfx_hal::{
ShaderStageFlags
,
Specialization
,
VertexBufferDesc
,
Viewport
,
},
Backend
,
DescriptorPool
,
...
...
@@ -74,76 +73,6 @@ pub struct CircleRenderer<B: Backend> {
pipeline
:
B
::
GraphicsPipeline
,
}
fn
create_pipeline
<
'a
,
B
:
Backend
>
(
device
:
&
B
::
Device
,
vs_module
:
&
'a
B
::
ShaderModule
,
fs_module
:
&
'a
B
::
ShaderModule
,
pipeline_layout
:
&
'a
B
::
PipelineLayout
,
render_pass
:
&
'a
B
::
RenderPass
,
viewport
:
&
Viewport
,
)
->
B
::
GraphicsPipeline
{
let
vs_entry
=
EntryPoint
{
entry
:
"main"
,
module
:
vs_module
,
specialization
:
Specialization
::
default
(),
};
let
fs_entry
=
EntryPoint
{
entry
:
"main"
,
module
:
fs_module
,
specialization
:
Specialization
::
default
(),
};
let
shader_entries
=
GraphicsShaderSet
{
vertex
:
vs_entry
,
hull
:
None
,
domain
:
None
,
geometry
:
None
,
fragment
:
Some
(
fs_entry
),
};
let
subpass
=
Subpass
{
index
:
0
,
main_pass
:
render_pass
,
};
let
mut
pipeline_desc
=
GraphicsPipelineDesc
::
new
(
shader_entries
,
Primitive
::
TriangleStrip
,
Rasterizer
{
cull_face
:
Face
::
NONE
,
..
Rasterizer
::
FILL
},
pipeline_layout
,
subpass
,
);
// Enable blending (for fake AA).
pipeline_desc
.blender
.targets
.push
(
ColorBlendDesc
(
ColorMask
::
ALL
,
BlendState
::
ALPHA
));
pipeline_desc
.vertex_buffers
.push
(
VertexBufferDesc
{
binding
:
0
,
stride
:
mem
::
size_of
::
<
Vertex
>
()
as
u32
,
rate
:
0
,
});
pipeline_desc
.attributes
.push
(
AttributeDesc
{
location
:
0
,
binding
:
0
,
element
:
Element
{
format
:
Format
::
Rg32Float
,
offset
:
0
,
},
});
pipeline_desc
.baked_states.viewport
=
Some
(
viewport
.clone
());
pipeline_desc
.baked_states.scissor
=
Some
(
viewport
.rect
);
unsafe
{
device
.create_graphics_pipeline
(
&
pipeline_desc
,
None
)
.unwrap
()
}
}
impl
<
B
:
Backend
>
CircleRenderer
<
B
>
{
pub
fn
new
(
graphics
:
&
mut
Graphics
<
B
>
)
->
CircleRenderer
<
B
>
{
// Create vertex buffer.
...
...
@@ -277,15 +206,70 @@ impl<B: Backend> CircleRenderer<B> {
)
.unwrap
()
};
let
pipeline
=
create_pipeline
::
<
B
>
(
&
graphics
.device
,
&
vs_module
,
&
fs_module
,
let
vs_entry
=
EntryPoint
{
entry
:
"main"
,
module
:
&
vs_module
,
specialization
:
Specialization
::
default
(),
};
let
fs_entry
=
EntryPoint
{
entry
:
"main"
,
module
:
&
fs_module
,
specialization
:
Specialization
::
default
(),
};
let
shader_entries
=
GraphicsShaderSet
{
vertex
:
vs_entry
,
hull
:
None
,
domain
:
None
,
geometry
:
None
,
fragment
:
Some
(
fs_entry
),
};
let
subpass
=
Subpass
{
index
:
0
,
main_pass
:
&
graphics
.render_pass
,
};
let
mut
pipeline_desc
=
GraphicsPipelineDesc
::
new
(
shader_entries
,
Primitive
::
TriangleStrip
,
Rasterizer
{
cull_face
:
Face
::
NONE
,
..
Rasterizer
::
FILL
},
&
pipeline_layout
,
&
graphics
.render_pass
,
&
graphics
.swapchain_state.viewport
,
subpass
,
);
// Enable blending (for fake AA).
pipeline_desc
.blender
.targets
.push
(
ColorBlendDesc
(
ColorMask
::
ALL
,
BlendState
::
ALPHA
));
pipeline_desc
.vertex_buffers
.push
(
VertexBufferDesc
{
binding
:
0
,
stride
:
mem
::
size_of
::
<
Vertex
>
()
as
u32
,
rate
:
0
,
});
pipeline_desc
.attributes
.push
(
AttributeDesc
{
location
:
0
,
binding
:
0
,
element
:
Element
{
format
:
Format
::
Rg32Float
,
offset
:
0
,
},
});
let
pipeline
=
unsafe
{
graphics
.device
.create_graphics_pipeline
(
&
pipeline_desc
,
None
)
.unwrap
()
};
// When transfer is finished, delete the staging buffers.
unsafe
{
graphics
...
...
@@ -313,25 +297,6 @@ impl<B: Backend> CircleRenderer<B> {
ctx
:
&
mut
DrawContext
<
B
>
,
circles
:
I
,
)
{
if
ctx
.update_viewport
{
let
cleanup
=
ctx
.cleanup
.as_mut
()
.unwrap
();
// Silly hack to prevent calling draw more than once in a
// frame from creating a pipeline each time.
if
let
None
=
cleanup
.pipeline
{
let
pipeline
=
create_pipeline
::
<
B
>
(
ctx
.device
,
&
self
.vs_module
,
&
self
.fs_module
,
&
self
.pipeline_layout
,
ctx
.render_pass
,
&
ctx
.viewport
,
);
let
old_pipeline
=
mem
::
replace
(
&
mut
self
.pipeline
,
pipeline
);
cleanup
.pipeline
=
Some
(
old_pipeline
);
}
}
// TODO: re-use command buffers
unsafe
{
ctx
.encoder
.bind_vertex_buffers
(
...
...
@@ -339,6 +304,8 @@ impl<B: Backend> CircleRenderer<B> {
[(
&
self
.vertex_buffer
,
0
)]
.iter
()
.cloned
(),
);
ctx
.encoder
.bind_graphics_pipeline
(
&
self
.pipeline
);
ctx
.encoder
.set_viewports
(
0
,
Some
(
ctx
.viewport
));
ctx
.encoder
.set_scissors
(
0
,
Some
(
&
ctx
.viewport.rect
));
ctx
.encoder
.bind_graphics_descriptor_sets
(
&
self
.pipeline_layout
,
0
,
...
...
src/graphics/mod.rs
View file @
5cdcc664
...
...
@@ -103,6 +103,7 @@ pub struct Graphics<B: Backend> {
imgui_renderer
:
imgui_gfx_hal
::
Renderer
<
B
>
,
color_format
:
Format
,
present_mode
:
PresentMode
,
supported_present_modes
:
Vec
<
PresentMode
>
,
cleanup
:
ArrayVec
<
[
SmallVec
<
[
Cleanup
<
B
>
;
3
]
>
;
MAX_FRAMES
]
>
,
current_frame
:
usize
,
swapchain_update
:
bool
,
...
...
@@ -117,16 +118,11 @@ pub struct Graphics<B: Backend> {
pub
struct
Cleanup
<
B
:
Backend
>
{
framebuffers
:
Vec
<
B
::
Framebuffer
>
,
frame_views
:
Vec
<
B
::
ImageView
>
,
pipeline
:
Option
<
B
::
GraphicsPipeline
>
,
}
pub
struct
DrawContext
<
'a
,
'b
,
'c
,
B
:
Backend
>
{
device
:
&
'c
B
::
Device
,
render_pass
:
&
'c
B
::
RenderPass
,
encoder
:
&
'a
mut
RenderPassInlineEncoder
<
'b
,
B
>
,
viewport
:
&
'c
Viewport
,
update_viewport
:
bool
,
cleanup
:
Option
<&
'a
mut
Cleanup
<
B
>>
,
}
#[cfg(feature
=
"renderdoc"
)]
...
...
@@ -214,7 +210,6 @@ impl<B: Backend> Graphics<B> {
instance
:
&
I
,
mut
surface
:
B
::
Surface
,
imgui
:
&
mut
ImGui
,
present_mode
:
PresentMode
,
)
->
Graphics
<
B
>
{
let
mut
adapters
=
instance
.enumerate_adapters
()
.into_iter
()
.sorted_by
(|
a
,
b
|
{
...
...
@@ -291,7 +286,19 @@ impl<B: Backend> Graphics<B> {
// Determine image capabilities and color format
// TODO figure out what available present modes are
let
(
_
,
formats
,
..
)
=
surface
.compatibility
(
physical_device
);
let
(
_
,
formats
,
supported_present_modes
,
_
)
=
surface
.compatibility
(
physical_device
);
// Select present mode.
let
present_mode
=
if
supported_present_modes
.contains
(
&
PresentMode
::
Mailbox
)
{
// Use mailbox if available.
PresentMode
::
Mailbox
}
else
{
// Otherwise default to immediate.
PresentMode
::
Immediate
};
let
color_format
=
formats
.map_or
(
Format
::
Rgba8Unorm
,
|
formats
|
{
formats
.iter
()
...
...
@@ -377,7 +384,8 @@ impl<B: Backend> Graphics<B> {
.collect
();
// Allocate a separate command pool for each frame, to allow
// resetting the corresponding command buffers individually.
let
mut
frame_command_pools
:
ArrayVec
<
[
_
;
2
]
>
=
(
0
..
MAX_FRAMES
)
let
mut
frame_command_pools
:
ArrayVec
<
[
_
;
MAX_FRAMES
]
>
=
(
0
..
MAX_FRAMES
)
.map
(|
_
|
{
unsafe
{
device
...
...
@@ -449,9 +457,14 @@ impl<B: Backend> Graphics<B> {
viewport_update
:
false
,
first_frame
:
true
,
present_mode
,
supported_present_modes
,
}
}
pub
fn
supported_present_modes
(
&
self
)
->
&
[
PresentMode
]
{
&
self
.supported_present_modes
}
pub
fn
present_mode
(
&
self
)
->
PresentMode
{
self
.present_mode
}
...
...
@@ -514,7 +527,6 @@ impl<B: Backend> Graphics<B> {
cleanup
=
Some
(
Cleanup
{
framebuffers
,
frame_views
,
pipeline
:
None
,
});
SwapchainState
::
new
(
device
,
...
...
@@ -648,12 +660,8 @@ impl<B: Backend> Graphics<B> {
{
let
ctx
=
DrawContext
{
device
:
&
self
.device
,
render_pass
:
&
self
.render_pass
,
encoder
:
&
mut
encoder
,
viewport
:
&
self
.swapchain_state.viewport
,
update_viewport
:
self
.viewport_update
,
cleanup
:
cleanup
.as_mut
(),
};
draw_fn
(
ctx
);
}
...
...
@@ -774,13 +782,9 @@ impl<B: Backend> Cleanup<B> {
let
Cleanup
{
framebuffers
,
frame_views
,
pipeline
,
..
}
=
self
;
unsafe
{
if
let
Some
(
pipeline
)
=
pipeline
{
device
.destroy_graphics_pipeline
(
pipeline
);
}
for
framebuffer
in
framebuffers
{
device
.destroy_framebuffer
(
framebuffer
);
}
...
...
src/main.rs
View file @
5cdcc664
#![feature(duration_float,
range_contains,
exact_size_is_empty,
copy_within)]
#![feature(duration_float,
range_contains,
copy_within)]
extern
crate
gfx_backend_vulkan
as
backend
;
use
ctrlc
;
use
gfx_hal
::
PresentMode
;
use
imgui
::
ImGui
;
use
imgui_winit
::
ImGuiWinit
;
use
nalgebra
::
Point2
;
...
...
@@ -102,12 +101,7 @@ fn run_gui() {
let
instance
=
backend
::
Instance
::
create
(
"Ball"
,
1
);
let
surface
=
instance
.create_surface
(
&
window
);
let
mut
graphics
=
graphics
::
Graphics
::
new
(
&
instance
,
surface
,
&
mut
imgui
,
PresentMode
::
Immediate
,
);
let
mut
graphics
=
graphics
::
Graphics
::
new
(
&
instance
,
surface
,
&
mut
imgui
);
let
mut
circle_rend
=
graphics
::
CircleRenderer
::
new
(
&
mut
graphics
);
let
mut
renderdoc
=
graphics
::
renderdoc
::
init
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment