File include/jen/compute.h changed (mode: 100644) (index a2510c2..09081dc) |
... |
... |
namespace jen::compute { |
58 |
58 |
/// Can be used only as uniform or storage buffer. |
/// Can be used only as uniform or storage buffer. |
59 |
59 |
/// Data in this structure is required for computing, |
/// Data in this structure is required for computing, |
60 |
60 |
/// reading fields is optional for user. |
/// reading fields is optional for user. |
61 |
|
/// Changing member variables leans to undefined behaviour. |
|
62 |
|
/// Data valid only valid after filling with |
|
63 |
|
/// ModuleCompute::create_bindings and become invalid after |
|
|
61 |
|
/// Changing member variables leads to undefined behaviour. |
|
62 |
|
/// Data are valid only after filling with |
|
63 |
|
/// ModuleCompute::create_bindings and becomes invalid after |
64 |
64 |
/// ModuleCompute::destroy_bindings. |
/// ModuleCompute::destroy_bindings. |
65 |
65 |
struct BindingBuffer { |
struct BindingBuffer { |
66 |
66 |
/// Buffer part allocation |
/// Buffer part allocation |
|
... |
... |
namespace jen::compute { |
69 |
69 |
vkw::BindNo binding; |
vkw::BindNo binding; |
70 |
70 |
/// Is staging required for transferring data |
/// Is staging required for transferring data |
71 |
71 |
bool use_staging; |
bool use_staging; |
72 |
|
/// Staging buffer part allocation, if stating is required |
|
|
72 |
|
/// Staging buffer part allocation, if staging is required |
73 |
73 |
DeviceBufferPart staging; |
DeviceBufferPart staging; |
74 |
74 |
}; |
}; |
75 |
75 |
/// @brief Binding buffer with buffer view. |
/// @brief Binding buffer with buffer view. |
|
... |
... |
namespace jen::compute { |
90 |
90 |
}; } |
}; } |
91 |
91 |
/// @brief Type used to store bitmask of ImageUseFlag enumeration flags |
/// @brief Type used to store bitmask of ImageUseFlag enumeration flags |
92 |
92 |
using ImageUseMask = uint32_t; |
using ImageUseMask = uint32_t; |
93 |
|
/// @brief User-provided information about image |
|
|
93 |
|
/// @brief User-provided information about the image |
94 |
94 |
struct ImageCreateInfo { |
struct ImageCreateInfo { |
95 |
|
/// 3-dimensional size of image: x - width, y - height, z - depth |
|
|
95 |
|
/// 3-dimensional size of the image: x - width, y - height, z - depth |
96 |
96 |
/// Values must be in range: |
/// Values must be in range: |
97 |
|
/// [1;2048] for 3D image; |
|
98 |
|
/// [1;16384] for 2D image |
|
|
97 |
|
/// [1;2048] for a 3D image; |
|
98 |
|
/// [1;16384] for a 2D image |
99 |
99 |
jm::v3u32 extent; |
jm::v3u32 extent; |
100 |
100 |
/// Amount of layers in image array, must be in range [1;2048]. |
/// Amount of layers in image array, must be in range [1;2048]. |
101 |
|
/// Used as 4rd dimension - array of images. |
|
|
101 |
|
/// Used as 4th dimension - array of images. |
102 |
102 |
uint32_t layer_count; |
uint32_t layer_count; |
103 |
|
/// Number of mipmap levels in image |
|
|
103 |
|
/// Number of mipmap levels in the image |
104 |
104 |
uint32_t mip_level_count; |
uint32_t mip_level_count; |
105 |
|
/// Format of image pixel. @see VkFormat |
|
|
105 |
|
/// Texel format. @see VkFormat |
106 |
106 |
VkFormat format; |
VkFormat format; |
107 |
|
/// Type of image: 1D, 2D, 3D. @see VkImageType |
|
|
107 |
|
/// Image type: 1D, 2D, 3D. @see VkImageType |
108 |
108 |
vkw::ImType type; |
vkw::ImType type; |
109 |
109 |
/// Integer amount of samples per pixel. Must be power of 2. |
/// Integer amount of samples per pixel. Must be power of 2. |
110 |
|
/// Usage more than 1 sample is called "multisampling". |
|
|
110 |
|
/// Usage of more than 1 sample is called "multisampling". |
111 |
111 |
vkw::Samples samples; |
vkw::Samples samples; |
112 |
112 |
/// Usage of image. @see ImageUseMask |
/// Usage of image. @see ImageUseMask |
113 |
113 |
ImageUseMask usage; |
ImageUseMask usage; |
|
... |
... |
namespace jen::compute { |
117 |
117 |
/// @brief Image. |
/// @brief Image. |
118 |
118 |
/// Can be used only as storage image. |
/// Can be used only as storage image. |
119 |
119 |
/// Data in this structure is required for computing. |
/// Data in this structure is required for computing. |
120 |
|
/// Reading fields is optional for user. |
|
121 |
|
/// Changing member variables leans to undefined behaviour. |
|
122 |
|
/// Data valid only valid after filling with |
|
123 |
|
/// ModuleCompute::create_images and become invalid after |
|
|
120 |
|
/// Reading fields are optional for user. |
|
121 |
|
/// Changing member variables leads to undefined behaviour. |
|
122 |
|
/// Data are valid only after filling with |
|
123 |
|
/// ModuleCompute::create_images and becomes invalid after |
124 |
124 |
/// ModuleCompute::destroy_images. |
/// ModuleCompute::destroy_images. |
125 |
125 |
struct Image { |
struct Image { |
126 |
126 |
/// Memory part allocation and Vulkan image related handles |
/// Memory part allocation and Vulkan image related handles |
127 |
127 |
GpuImage<GpuImageMode::VIEW> image; |
GpuImage<GpuImageMode::VIEW> image; |
128 |
|
/// Format of image. @see VkFormat |
|
|
128 |
|
/// Texel format. @see VkFormat |
129 |
129 |
VkFormat format; |
VkFormat format; |
130 |
130 |
/// Current image layout. @see VkImageLayout |
/// Current image layout. @see VkImageLayout |
131 |
131 |
vkw::ImLayout layout; |
vkw::ImLayout layout; |
132 |
132 |
/// Staging buffer part allocation for reading from and writing to image |
/// Staging buffer part allocation for reading from and writing to image |
133 |
133 |
DeviceBufferPart staging; |
DeviceBufferPart staging; |
134 |
|
/// Count of mip levels in image |
|
|
134 |
|
/// Number of mip levels in image |
135 |
135 |
uint32_t mip_level_count; |
uint32_t mip_level_count; |
136 |
|
/// Count of layers in image |
|
|
136 |
|
/// Number of layers in image |
137 |
137 |
uint32_t layer_count; |
uint32_t layer_count; |
138 |
138 |
}; |
}; |
139 |
139 |
/// @brief User-provided information about image binding |
/// @brief User-provided information about image binding |
|
... |
... |
namespace jen::compute { |
157 |
157 |
/// @brief Constant jl::rarray list of storage image bindings |
/// @brief Constant jl::rarray list of storage image bindings |
158 |
158 |
jl::rarray<const BindingImage> storage_image; |
jl::rarray<const BindingImage> storage_image; |
159 |
159 |
}; |
}; |
160 |
|
/// @brief Bindings set. |
|
161 |
|
/// Binding lists that required to bind to compute pipeline. |
|
|
160 |
|
/// @brief Set of Bindings. |
|
161 |
|
/// Binding lists which are required to bind to compute pipeline. |
162 |
162 |
/// Data in this structure is required for computing. |
/// Data in this structure is required for computing. |
163 |
163 |
/// Reading fields is optional for user. |
/// Reading fields is optional for user. |
164 |
|
/// Changing member variables leans to undefined behaviour. |
|
165 |
|
/// Data valid only valid after filling with |
|
166 |
|
/// ModuleCompute::create_bindingSet and become invalid after |
|
|
164 |
|
/// Changing member variables leads to undefined behaviour. |
|
165 |
|
/// Data are valid only after filling with |
|
166 |
|
/// ModuleCompute::create_bindingSet and becomes invalid after |
167 |
167 |
/// ModuleCompute::destroy_bindingSet. |
/// ModuleCompute::destroy_bindingSet. |
168 |
168 |
struct BindingsSet { |
struct BindingsSet { |
169 |
169 |
/// Vulkan descriptor set handle. @see VkDescriptorSet |
/// Vulkan descriptor set handle. @see VkDescriptorSet |
|
... |
... |
namespace jen::compute { |
173 |
173 |
}; |
}; |
174 |
174 |
/// @brief Compute pipeline. |
/// @brief Compute pipeline. |
175 |
175 |
/// Compute pipeline is required to run shader programs |
/// Compute pipeline is required to run shader programs |
176 |
|
/// and bind binding set to them. |
|
|
176 |
|
/// and bind a binding set to them. |
177 |
177 |
/// Data in this structure is required for computing. |
/// Data in this structure is required for computing. |
178 |
178 |
/// Reading fields is optional for user. |
/// Reading fields is optional for user. |
179 |
179 |
/// Changing member variables leans to undefined behaviour. |
/// Changing member variables leans to undefined behaviour. |
|
... |
... |
namespace jen::compute { |
191 |
191 |
vkw::DescrLayout setLayout; |
vkw::DescrLayout setLayout; |
192 |
192 |
}; |
}; |
193 |
193 |
/// @brief User information about image region transferring operation. |
/// @brief User information about image region transferring operation. |
194 |
|
/// Image region is like array of 3D cubes, where layer is index of an array |
|
195 |
|
/// and position is 3-dimensional integer vector. |
|
|
194 |
|
/// Image region can be represented as an array of 3D cubes, where a layer is an index in the array |
|
195 |
|
/// and position is a 3-dimensional integer vector. |
196 |
196 |
struct ImageTransfer { |
struct ImageTransfer { |
197 |
|
/// mip level to transfer |
|
|
197 |
|
/// Mip level to transfer |
198 |
198 |
uint32_t mip_level; |
uint32_t mip_level; |
199 |
|
/// layer offset or "first layer number to copy" |
|
|
199 |
|
/// Layer offset or "first layer number to copy" |
200 |
200 |
uint32_t layer_offset; |
uint32_t layer_offset; |
201 |
|
/// count of layers to transfer |
|
|
201 |
|
/// Number of layers to transfer |
202 |
202 |
uint32_t layer_count; |
uint32_t layer_count; |
203 |
203 |
/// 3-dimensional offset position of region to transfer |
/// 3-dimensional offset position of region to transfer |
204 |
204 |
jm::v3u32 offset; |
jm::v3u32 offset; |
|
... |
... |
namespace jen::compute { |
207 |
207 |
/// Pointer to user memory for reading-to or writing-from |
/// Pointer to user memory for reading-to or writing-from |
208 |
208 |
void *p_data; |
void *p_data; |
209 |
209 |
}; |
}; |
210 |
|
/// @brief List of regions transferring operations per image. |
|
|
210 |
|
/// @brief List of region transferring operations per image. |
211 |
211 |
struct ImageTransfers { |
struct ImageTransfers { |
212 |
212 |
/// @brief Target image |
/// @brief Target image |
213 |
213 |
Image *p_image; |
Image *p_image; |
214 |
|
/// @brief List of regions transfers. @see ImageTransfer |
|
|
214 |
|
/// @brief List of region transfers. @see ImageTransfer |
215 |
215 |
jl::rarray<const ImageTransfer> transfers; |
jl::rarray<const ImageTransfer> transfers; |
216 |
216 |
}; |
}; |
217 |
217 |
/// @brief Constant jl::rarray, array of image transfer operations. |
/// @brief Constant jl::rarray, array of image transfer operations. |
|
... |
... |
namespace jen::compute { |
231 |
231 |
}; |
}; |
232 |
232 |
/// @brief Constant jl::rarray, array of BufferTransfers data types. |
/// @brief Constant jl::rarray, array of BufferTransfers data types. |
233 |
233 |
using BufferTransfers = jl::rarray<const BufferTransfer>; |
using BufferTransfers = jl::rarray<const BufferTransfer>; |
234 |
|
/// Minimum possible value of maximum allowed workgroups on specific device. |
|
|
234 |
|
/// The lowest possible value of a maximum number of workgroups on specific device. |
235 |
235 |
constexpr static const uint32_t MAX_WORKGROUP_COUNT = 65535; |
constexpr static const uint32_t MAX_WORKGROUP_COUNT = 65535; |
236 |
236 |
} |
} |
237 |
237 |
namespace jen |
namespace jen |
|
... |
... |
namespace jen |
250 |
250 |
struct ModuleCompute { |
struct ModuleCompute { |
251 |
251 |
/// @brief Initialize compute::Pipeline. |
/// @brief Initialize compute::Pipeline. |
252 |
252 |
/// After creation, Pipeline must be destroyed with destroy_pipeline |
/// After creation, Pipeline must be destroyed with destroy_pipeline |
253 |
|
/// when is not needed anymore. |
|
254 |
|
/// @param bi bindings that will be bind to this pipeline, |
|
255 |
|
/// must be same bindings that passed to create_bindingSet |
|
256 |
|
/// that will called with this pipeline. |
|
|
253 |
|
/// when it is not needed anymore. |
|
254 |
|
/// @param bi bindings, that will be bound to this pipeline, |
|
255 |
|
/// must be the same bindings that will be passed to |
|
256 |
|
/// create_bindingSet that will be called with this pipeline. |
257 |
257 |
/// @param p_shader_file_path path to SPIR-V shader file |
/// @param p_shader_file_path path to SPIR-V shader file |
258 |
258 |
/// @param ssp shader specialization constants, optional |
/// @param ssp shader specialization constants, optional |
259 |
|
/// @param p_dst pointer to store created pipeline |
|
|
259 |
|
/// @param p_dst pointer to store a created pipeline |
260 |
260 |
/// @return If not VK_SUCCESS then function has no effect |
/// @return If not VK_SUCCESS then function has no effect |
261 |
261 |
/// and pipeline is not created |
/// and pipeline is not created |
262 |
262 |
[[nodiscard]] Result |
[[nodiscard]] Result |
|
... |
... |
namespace jen |
266 |
266 |
compute::Pipeline *p_dst); |
compute::Pipeline *p_dst); |
267 |
267 |
/// @brief Initialize array of compute::BindingBuffer. |
/// @brief Initialize array of compute::BindingBuffer. |
268 |
268 |
/// After creation, binding buffers must be destroyed with destroy_bindings |
/// After creation, binding buffers must be destroyed with destroy_bindings |
269 |
|
/// when is not needed anymore. |
|
270 |
|
/// @param infos information about bindings to create |
|
|
269 |
|
/// when it is not needed anymore. |
|
270 |
|
/// @param infos information about bindings to create. |
271 |
271 |
/// @param p_dst pointer to store created bindings, must be pointed to |
/// @param p_dst pointer to store created bindings, must be pointed to |
272 |
|
/// valid row memory with at least size of |
|
|
272 |
|
/// valid memory with is at least the size of |
273 |
273 |
/// infos.count() * sizeof(compute::BindingBuffer) |
/// infos.count() * sizeof(compute::BindingBuffer) |
274 |
274 |
/// @return If not VK_SUCCESS then function has no effect |
/// @return If not VK_SUCCESS then function has no effect |
275 |
275 |
/// and bindings are not created |
/// and bindings are not created |
|
... |
... |
namespace jen |
278 |
278 |
compute::BindingBuffer *p_dst); |
compute::BindingBuffer *p_dst); |
279 |
279 |
/// @brief Initialize array of compute::BindingBufferView. |
/// @brief Initialize array of compute::BindingBufferView. |
280 |
280 |
/// After creation, binding buffers must be destroyed with destroy_bindings |
/// After creation, binding buffers must be destroyed with destroy_bindings |
281 |
|
/// when is not needed anymore. |
|
282 |
|
/// @param infos information about bindings to create |
|
|
281 |
|
/// when it is not needed anymore. |
|
282 |
|
/// @param infos information about bindings to create. |
283 |
283 |
/// @param p_formats pointer to array of formats of buffer views, must be |
/// @param p_formats pointer to array of formats of buffer views, must be |
284 |
|
/// pointed to valid row memory with at least size of |
|
|
284 |
|
/// pointed to valid memory with at least size of |
285 |
285 |
/// infos.count() * sizeof(VkFormat) |
/// infos.count() * sizeof(VkFormat) |
286 |
286 |
/// @param p_dst pointer to store created bindings, must be pointed to |
/// @param p_dst pointer to store created bindings, must be pointed to |
287 |
|
/// valid row memory with at least size of |
|
|
287 |
|
/// valid memory with is at least size of |
288 |
288 |
/// infos.count() * sizeof(compute::BindingBufferView) |
/// infos.count() * sizeof(compute::BindingBufferView) |
289 |
289 |
/// @return If not VK_SUCCESS then function has no effect |
/// @return If not VK_SUCCESS then function has no effect |
290 |
290 |
/// and bindings are not created |
/// and bindings are not created |
|
... |
... |
namespace jen |
295 |
295 |
/// @brief Initialize array of compute::Image. |
/// @brief Initialize array of compute::Image. |
296 |
296 |
/// After creation, images must be destroyed with destroy_images |
/// After creation, images must be destroyed with destroy_images |
297 |
297 |
/// when is not needed anymore. |
/// when is not needed anymore. |
298 |
|
/// @param infos information about bindings to create |
|
|
298 |
|
/// @param infos information about bindings to create. |
299 |
299 |
/// @param p_dst pointer to store created bindings, must be pointed to |
/// @param p_dst pointer to store created bindings, must be pointed to |
300 |
|
/// valid row memory with at least size of |
|
|
300 |
|
/// valid memory with is at least size of |
301 |
301 |
/// infos.count() * sizeof(compute::Image) |
/// infos.count() * sizeof(compute::Image) |
302 |
302 |
/// @return If not VK_SUCCESS then function has no effect |
/// @return If not VK_SUCCESS then function has no effect |
303 |
303 |
/// and images are not created |
/// and images are not created |
|
... |
... |
namespace jen |
307 |
307 |
/// @brief Initialize compute::BindingsSet. |
/// @brief Initialize compute::BindingsSet. |
308 |
308 |
/// After creation, binding set must be destroyed with destroy_bindingSet |
/// After creation, binding set must be destroyed with destroy_bindingSet |
309 |
309 |
/// when is not needed anymore. |
/// when is not needed anymore. |
310 |
|
/// @param pipeline specify pipeline this set to bind to |
|
|
310 |
|
/// @param pipeline pipeline to bind this set. |
311 |
311 |
/// @param bindings list of bindings to include in this set, |
/// @param bindings list of bindings to include in this set, |
312 |
|
/// must have at least single binding and must be same as |
|
313 |
|
/// bindings list passed to create_pipeline. |
|
|
312 |
|
/// must have at least one binding and must be the same |
|
313 |
|
/// as bindings list passed to create_pipeline. |
314 |
314 |
/// @param p_dst pointer to store created binding set |
/// @param p_dst pointer to store created binding set |
315 |
315 |
/// @return If not VK_SUCCESS then function has no effect |
/// @return If not VK_SUCCESS then function has no effect |
316 |
316 |
/// and binding set is not created |
/// and binding set is not created |
|
... |
... |
namespace jen |
319 |
319 |
const compute::Bindings &bindings, |
const compute::Bindings &bindings, |
320 |
320 |
compute::BindingsSet *p_dst); |
compute::BindingsSet *p_dst); |
321 |
321 |
/// @brief Destroy binding set. |
/// @brief Destroy binding set. |
322 |
|
/// Must be called only once for created set. |
|
|
322 |
|
/// Must be called only once for a created set. |
323 |
323 |
/// Set cannot be used after destroying. |
/// Set cannot be used after destroying. |
324 |
324 |
/// @param p_set pointer to created by create_bindingSet set |
/// @param p_set pointer to created by create_bindingSet set |
325 |
325 |
void destroy_bindingSet(compute::BindingsSet *p_set); |
void destroy_bindingSet(compute::BindingsSet *p_set); |
|
... |
... |
namespace jen |
327 |
327 |
/// Must be called only once for every created binding. |
/// Must be called only once for every created binding. |
328 |
328 |
/// Binding cannot be used after destroying. |
/// Binding cannot be used after destroying. |
329 |
329 |
/// @param p_bs pointer to array created by create_bindings bindings |
/// @param p_bs pointer to array created by create_bindings bindings |
330 |
|
/// @param count count of bindings to destroy |
|
|
330 |
|
/// @param count binding count to destroy |
331 |
331 |
void destroy_bindings(compute::BindingBuffer *p_bs, uint32_t count = 1); |
void destroy_bindings(compute::BindingBuffer *p_bs, uint32_t count = 1); |
332 |
332 |
/// @brief Destroy buffer view bindings. |
/// @brief Destroy buffer view bindings. |
333 |
333 |
/// Must be called only once for every created binding. |
/// Must be called only once for every created binding. |
334 |
334 |
/// Binding cannot be used after destroying. |
/// Binding cannot be used after destroying. |
335 |
335 |
/// @param p_bs pointer to array created by create_bindings bindings |
/// @param p_bs pointer to array created by create_bindings bindings |
336 |
|
/// @param count count of bindings to destroy |
|
|
336 |
|
/// @param count binding count to destroy |
337 |
337 |
void destroy_bindings(compute::BindingBufferView *p_bs, uint32_t count = 1); |
void destroy_bindings(compute::BindingBufferView *p_bs, uint32_t count = 1); |
338 |
338 |
/// @brief Destroy images. |
/// @brief Destroy images. |
339 |
339 |
/// Must be called only once for every created image. |
/// Must be called only once for every created image. |
|
... |
... |
namespace jen |
349 |
349 |
struct Data; |
struct Data; |
350 |
350 |
/// @brief Pointer to hidden data of ModuleCompute. |
/// @brief Pointer to hidden data of ModuleCompute. |
351 |
351 |
/// Can be acquired from Framework.compute.p |
/// Can be acquired from Framework.compute.p |
352 |
|
/// Changing leans to undefined behaviour. |
|
|
352 |
|
/// Changing leads to undefined behaviour. |
353 |
353 |
Data *p; |
Data *p; |
354 |
354 |
}; |
}; |
355 |
355 |
/// @brief User information for compute operation. |
/// @brief User information for compute operation. |
|
... |
... |
namespace jen |
360 |
360 |
/// Must be created with pipeline from *p_pipeline |
/// Must be created with pipeline from *p_pipeline |
361 |
361 |
compute::BindingsSet *p_bindingsSet; |
compute::BindingsSet *p_bindingsSet; |
362 |
362 |
/// Pointer to bindings lists. |
/// Pointer to bindings lists. |
363 |
|
/// Must be same as passed to this pipeline and this binding set |
|
|
363 |
|
/// Must be еру same as the one passed to this pipeline and this binding set |
364 |
364 |
compute::Bindings *p_bindings; |
compute::Bindings *p_bindings; |
365 |
|
/// Size of workgroups, amount of works to execute. |
|
|
365 |
|
/// Size of workgroups, amount of groups to execute. |
366 |
366 |
jm::v3u32 group_count; |
jm::v3u32 group_count; |
367 |
367 |
/// Write-to buffer operations to apply before computing. |
/// Write-to buffer operations to apply before computing. |
368 |
368 |
compute::BufferTransfers buffer_writes; |
compute::BufferTransfers buffer_writes; |
|
... |
... |
namespace jen |
373 |
373 |
/// Read-from image operations to apply after computing. |
/// Read-from image operations to apply after computing. |
374 |
374 |
compute::ImagesTransfers images_reads; |
compute::ImagesTransfers images_reads; |
375 |
375 |
}; |
}; |
376 |
|
/// @brief Compute unit to perform compute operations. |
|
|
376 |
|
/// @brief Compute unit used to perform compute operations. |
377 |
377 |
/// While ModuleCompute is used to create compute objects, |
/// While ModuleCompute is used to create compute objects, |
378 |
378 |
/// ComputeCmdUnit is used to run compute operations. |
/// ComputeCmdUnit is used to run compute operations. |
379 |
379 |
/// Compute process is period between start of ComputeCmdUnit::compute and |
/// Compute process is period between start of ComputeCmdUnit::compute and |
380 |
380 |
/// end of ComputeCmdUnit::read_result. |
/// end of ComputeCmdUnit::read_result. |
381 |
381 |
/// User can create several ComputeCmdUnits and run them simultaneously with |
/// User can create several ComputeCmdUnits and run them simultaneously with |
382 |
382 |
/// those restrictions: |
/// those restrictions: |
383 |
|
/// - same buffer and image instances cannot used for simultaneous |
|
384 |
|
/// compute process; |
|
385 |
|
/// - all ComputeCmdUnit instances must be destroyed before Framework |
|
386 |
|
/// is destroyed; |
|
|
383 |
|
/// - same buffer and image instances cannot be used for simultaneous |
|
384 |
|
/// compute process; |
|
385 |
|
/// - all ComputeCmdUnit instances must be destroyed before |
|
386 |
|
/// the Framework is destroyed; |
387 |
387 |
/// - all buffers and images used as bindings must not be destroyed while |
/// - all buffers and images used as bindings must not be destroyed while |
388 |
|
/// compute process is running; |
|
|
388 |
|
/// computing process is running; |
389 |
389 |
/// - all data pointed from ComputeInfo must not change while compute process |
/// - all data pointed from ComputeInfo must not change while compute process |
390 |
|
/// is running; |
|
|
390 |
|
/// is running; |
391 |
391 |
/// - ComputeCmdUnit must be valid (initialized and not destroyed). |
/// - ComputeCmdUnit must be valid (initialized and not destroyed). |
392 |
392 |
struct ComputeCmdUnit { |
struct ComputeCmdUnit { |
393 |
393 |
/// @brief Initialize ComputeCmdUnit. |
/// @brief Initialize ComputeCmdUnit. |
|
... |
... |
namespace jen |
413 |
413 |
/// device is corrupted (compute cannot continue). |
/// device is corrupted (compute cannot continue). |
414 |
414 |
[[nodiscard]] Result |
[[nodiscard]] Result |
415 |
415 |
compute_status(); |
compute_status(); |
416 |
|
/// @brief Wait for end of compute process and read results. |
|
|
416 |
|
/// @brief Wait for the end of compute process and read results. |
417 |
417 |
/// Must be called only after running ComputeCmdUnit::compute |
/// Must be called only after running ComputeCmdUnit::compute |
418 |
418 |
/// @param buffer_reads Read-from buffer operations to apply, |
/// @param buffer_reads Read-from buffer operations to apply, |
419 |
|
/// must not contain operations that is not specified in |
|
|
419 |
|
/// must not contain operations are not specified in |
420 |
420 |
/// ComputeInfo.buffer_reads. |
/// ComputeInfo.buffer_reads. |
421 |
|
/// @param image_reads Read-from image operations to apply, must be same |
|
422 |
|
/// as specified in ComputeInfo.images_reads. |
|
|
421 |
|
/// @param image_reads Read-from image operations to apply, must be |
|
422 |
|
/// the same as specified in ComputeInfo.images_reads. |
423 |
423 |
/// @return same as ComputeCmdUnit::compute_status |
/// @return same as ComputeCmdUnit::compute_status |
424 |
424 |
[[nodiscard]] Result |
[[nodiscard]] Result |
425 |
425 |
read_result(compute::BufferTransfers buffer_reads, |
read_result(compute::BufferTransfers buffer_reads, |
File include/jen/graphics.h changed (mode: 100644) (index b646365..cdd29e4) |
... |
... |
namespace jen { |
36 |
36 |
struct DrawFrameLoop; |
struct DrawFrameLoop; |
37 |
37 |
} |
} |
38 |
38 |
/// @brief 3D Graphics renderer |
/// @brief 3D Graphics renderer |
39 |
|
/// ModuleGraphics can only be created and destroyed by Framework. |
|
|
39 |
|
/// ModuleGraphics can only be created and destroyed by the Framework. |
40 |
40 |
/// To get compute module instance use Framework.graphics member field, |
/// To get compute module instance use Framework.graphics member field, |
41 |
|
/// framework must be created with ModuleFlag::GRAPHICS bit set |
|
|
41 |
|
/// Framework must be created with ModuleFlag::GRAPHICS bit set |
42 |
42 |
/// All handles created by ModuleGraphics::create must be destroyed by calling |
/// All handles created by ModuleGraphics::create must be destroyed by calling |
43 |
|
/// ModuleGraphics::destroy before Framework is destroyed. |
|
|
43 |
|
/// ModuleGraphics::destroy before the Framework is destroyed. |
44 |
44 |
struct jen::ModuleGraphics |
struct jen::ModuleGraphics |
45 |
45 |
{ |
{ |
46 |
|
/// @brief Change graphics settings. |
|
|
46 |
|
/// @brief Change graphic settings. |
47 |
47 |
/// Settings are updated anyway, but appliyng can fail, |
/// Settings are updated anyway, but appliyng can fail, |
48 |
48 |
/// ModuleGraphics will try to apply them again in ModuleGraphics::draw_frame. |
/// ModuleGraphics will try to apply them again in ModuleGraphics::draw_frame. |
49 |
49 |
/// @param settings GraphicsSettings with valid values |
/// @param settings GraphicsSettings with valid values |
50 |
50 |
/// @return User optionally can check for VK_ERROR_OUT_OF_HOST_MEMORY or |
/// @return User optionally can check for VK_ERROR_OUT_OF_HOST_MEMORY or |
51 |
|
/// VK_ERROR_OUT_OF_DEVICE_MEMORY to free some memory. |
|
|
51 |
|
/// VK_ERROR_OUT_OF_DEVICE_MEMORY to free up some memory. |
52 |
52 |
Result apply_settings(const GraphicsSettings &settings); |
Result apply_settings(const GraphicsSettings &settings); |
53 |
53 |
/// @brief Update camera and frustum parameters |
/// @brief Update camera and frustum parameters |
54 |
54 |
void apply_camera(const Camera&, const Frustum&); |
void apply_camera(const Camera&, const Frustum&); |
55 |
55 |
/// @brief Update shadow-casting light. |
/// @brief Update shadow-casting light. |
56 |
56 |
/// @param l light for shadow mapping |
/// @param l light for shadow mapping |
57 |
57 |
void apply_light_shadow(const Light &l); |
void apply_light_shadow(const Light &l); |
58 |
|
/// @brief Provide pointer to lights information. |
|
59 |
|
/// Lights data must not change simultaneously with function draw_frame |
|
|
58 |
|
/// @brief Provide pointer to light information. |
|
59 |
|
/// Light data must not change simultaneously with function draw_frame |
60 |
60 |
/// (data pointed to by array LightsDraw.lights). |
/// (data pointed to by array LightsDraw.lights). |
61 |
61 |
/// When data is changed outside of draw_frame, user must set |
/// When data is changed outside of draw_frame, user must set |
62 |
62 |
/// LightsDraw.is_updated flag to true to update lights. is_updated flag is |
/// LightsDraw.is_updated flag to true to update lights. is_updated flag is |
63 |
63 |
/// checked in draw_frame function and will be set to false. |
/// checked in draw_frame function and will be set to false. |
64 |
|
/// @param p_lights pointer to LightsDraw, must be valid pointer untill |
|
|
64 |
|
/// @param p_lights pointer to LightsDraw, must be valid pointer until |
65 |
65 |
/// new pointer is provided or ModuleGraphics is destroyed |
/// new pointer is provided or ModuleGraphics is destroyed |
66 |
66 |
void apply_lights(LightsDraw *p_lights); |
void apply_lights(LightsDraw *p_lights); |
67 |
67 |
/// @brief Run data to GPU writing process and acquire GpuData memory handle. |
/// @brief Run data to GPU writing process and acquire GpuData memory handle. |
68 |
|
/// User memory under WriteData.p pointer must be valid while writting process |
|
69 |
|
/// is occuring. To check writtings process status, use is_resource_ready. |
|
70 |
|
/// Depending on Device properties, writting process can end up after this |
|
71 |
|
/// function return, or can require some time to wait gpu commands executions. |
|
72 |
|
/// GpuData handle must be cleaned up by ModuleGraphics::destroy, |
|
73 |
|
/// before destroying Framework |
|
|
68 |
|
/// User memory under WriteData.p ptr must be valid when the writing process |
|
69 |
|
/// is occurs. To check writtings process status, use is_resource_ready. |
|
70 |
|
/// Depending on Device properties, writing process can after this function |
|
71 |
|
/// return, or may require some time to wait for gpu commands executions. |
|
72 |
|
/// GpuData handle must be cleared up by ModuleGraphics::destroy, |
|
73 |
|
/// before destroying the Framework |
74 |
74 |
/// @param w User data to write |
/// @param w User data to write |
75 |
75 |
/// @param pp_dst Pointer to write GpuData handle |
/// @param pp_dst Pointer to write GpuData handle |
76 |
|
/// @param free_src If this flag set to true, WriteData.p memory will be |
|
77 |
|
/// be deallocated in the end of writing proccess |
|
78 |
|
/// @return If not VK_SUCCESS than nothing is done |
|
|
76 |
|
/// @param free_src If this flag is set to true, WriteData.p memory will |
|
77 |
|
/// be deallocated in the end of the writing proccess |
|
78 |
|
/// @return If not VK_SUCCESS then nothing is done |
79 |
79 |
[[nodiscard]] Result |
[[nodiscard]] Result |
80 |
80 |
create(const WriteData &w, GpuData **pp_dst, bool free_src); |
create(const WriteData &w, GpuData **pp_dst, bool free_src); |
81 |
81 |
/// @brief Run data to GPU writing process and write GpuData to user memory. |
/// @brief Run data to GPU writing process and write GpuData to user memory. |
82 |
82 |
/// @param w User data to write |
/// @param w User data to write |
83 |
83 |
/// @param p_allocated externally allocated GpuData memory, |
/// @param p_allocated externally allocated GpuData memory, |
84 |
|
/// must have at least size of GPU_DATA_ALLOCATION_SIZE |
|
85 |
|
/// @param free_src If this flag set to true, WriteData.p memory will be |
|
86 |
|
/// be deallocated in the end of writing proccess |
|
|
84 |
|
/// must be at least size of GPU_DATA_ALLOCATION_SIZE |
|
85 |
|
/// @param free_src If this flag is set to true, WriteData.p memory will |
|
86 |
|
/// be deallocated in the end of the writing proccess |
87 |
87 |
/// @see create(const WriteData&, GpuData**, bool) |
/// @see create(const WriteData&, GpuData**, bool) |
88 |
88 |
[[nodiscard]] Result |
[[nodiscard]] Result |
89 |
89 |
create(const WriteData& w, GpuData *p_allocated, bool free_src); |
create(const WriteData& w, GpuData *p_allocated, bool free_src); |
90 |
90 |
/// @brief Run gpu texture creation process and acquire GpuTexture handle. |
/// @brief Run gpu texture creation process and acquire GpuTexture handle. |
91 |
|
/// User memory under jrf::Image.p_pixels pointer must be valid while |
|
92 |
|
/// texture creation process is occuring. To check process status, |
|
|
91 |
|
/// User memory under jrf::Image.p_pixels pointer must be valid when the |
|
92 |
|
/// texture creation process occurs. To check process status, |
93 |
93 |
/// use is_resource_ready. |
/// use is_resource_ready. |
94 |
|
/// Process require staging and complex image tranferring operations. |
|
95 |
|
/// Process is running on separate thread using GPU commands execution. |
|
96 |
|
/// GpuTexture handle must be cleaned up by ModuleGraphics::destroy, |
|
97 |
|
/// before destroying Framework |
|
|
94 |
|
/// Process requires staging and complex image tranferring operations. |
|
95 |
|
/// Process is running on a separate thread using GPU command execution. |
|
96 |
|
/// GpuTexture handle must be freed up by ModuleGraphics::destroy, |
|
97 |
|
/// before destroying the Framework |
98 |
98 |
/// @param texture valid jrf::Image information |
/// @param texture valid jrf::Image information |
99 |
99 |
/// @param pp_dst Pointer to write GpuTexture handle |
/// @param pp_dst Pointer to write GpuTexture handle |
100 |
|
/// @param free_src If this flag set to true, jrf::Image will be |
|
101 |
|
/// be destroyed in the end of writing proccess |
|
|
100 |
|
/// @param free_src If this flag is set to true, jrf::Image will |
|
101 |
|
/// be destroyed in the end if the writing proccess |
102 |
102 |
[[nodiscard]] Result |
[[nodiscard]] Result |
103 |
103 |
create(const jrf::Image &texture, GpuTexture **pp_dst, bool free_src); |
create(const jrf::Image &texture, GpuTexture **pp_dst, bool free_src); |
104 |
|
/// @brief Clean memory and GpuData handle. |
|
105 |
|
/// GpuData handle becomes invalid after cleaning |
|
|
104 |
|
/// @brief Free memory and GpuData handle. |
|
105 |
|
/// GpuData handle becomes invalid after freeing |
106 |
106 |
/// @param p Valid GpuData handle, acquired from ModuleGraphics::create |
/// @param p Valid GpuData handle, acquired from ModuleGraphics::create |
107 |
107 |
/// @param free_src If set to true, specified in ModuleGraphics::create |
/// @param free_src If set to true, specified in ModuleGraphics::create |
108 |
108 |
/// WriteData.p memory will be deallocated |
/// WriteData.p memory will be deallocated |
109 |
109 |
/// (no effect if it is already deallocated after create) |
/// (no effect if it is already deallocated after create) |
110 |
110 |
void destroy(GpuData *p, bool free_src); |
void destroy(GpuData *p, bool free_src); |
111 |
|
/// @brief Clean memory and GpuTexture handle. |
|
112 |
|
/// GpuTexture handle becomes invalid after cleaning |
|
|
111 |
|
/// @brief Free memory and GpuTexture handle. |
|
112 |
|
/// GpuTexture handle becomes invalid after freeing |
113 |
113 |
/// @param p Valid GpuTexture handle, acquired from ModuleGraphics::create |
/// @param p Valid GpuTexture handle, acquired from ModuleGraphics::create |
114 |
114 |
/// @param free_src If set to true, specified in ModuleGraphics::create |
/// @param free_src If set to true, specified in ModuleGraphics::create |
115 |
115 |
/// jrf::Image will be destroyed |
/// jrf::Image will be destroyed |
|
... |
... |
struct jen::ModuleGraphics |
124 |
124 |
[[nodiscard]] bool |
[[nodiscard]] bool |
125 |
125 |
create(const char* font_path, GlyphManager **pp_dst); |
create(const char* font_path, GlyphManager **pp_dst); |
126 |
126 |
|
|
127 |
|
/// @brief Create or update text on gpu. |
|
|
127 |
|
/// @brief Create or update text on the gpu. |
128 |
128 |
/// After this function call this text will be drawn every frame untill |
/// After this function call this text will be drawn every frame untill |
129 |
129 |
/// ModuleGraphics::destroy(GpuText*) is called with this GpuText handle. |
/// ModuleGraphics::destroy(GpuText*) is called with this GpuText handle. |
130 |
|
/// @param layout text characters positioning in box |
|
|
130 |
|
/// @param layout text characters positioning in the box |
131 |
131 |
/// @param pixel_size Size of glyphs in pixels |
/// @param pixel_size Size of glyphs in pixels |
132 |
132 |
/// @param chars UTF32 Characters |
/// @param chars UTF32 Characters |
133 |
|
/// @param colors Colors of characters. If count of colors less than |
|
134 |
|
/// characters count than colors will be repeated in cycle. |
|
|
133 |
|
/// @param colors Character colors. If the number of colors is less than |
|
134 |
|
/// the character count than the colors will be repeated in a cycle. |
135 |
135 |
/// @param p_font Valid GlyphManager handle created with create func |
/// @param p_font Valid GlyphManager handle created with create func |
136 |
136 |
/// @param pp_text Valid GpuText handle or nullptr. |
/// @param pp_text Valid GpuText handle or nullptr. |
137 |
137 |
/// If nullptr, new GpuText handle will be created. |
/// If nullptr, new GpuText handle will be created. |
|
... |
... |
struct jen::ModuleGraphics |
142 |
142 |
[[nodiscard]] Result |
[[nodiscard]] Result |
143 |
143 |
text_update(TextLayout layout, uint16_t pixel_size, Chars chars, |
text_update(TextLayout layout, uint16_t pixel_size, Chars chars, |
144 |
144 |
Colors_RGBA colors, GlyphManager *p_font, GpuText **pp_text); |
Colors_RGBA colors, GlyphManager *p_font, GpuText **pp_text); |
145 |
|
/// @brief Stop gpu text drawing and clean GpuText handle. |
|
|
145 |
|
/// @brief Stop gpu text drawing and free GpuText handle. |
146 |
146 |
/// After this call, GpuText handle cant be used again for text_update |
/// After this call, GpuText handle cant be used again for text_update |
147 |
|
/// @param p_text Text to clean |
|
|
147 |
|
/// @param p_text Text to free |
148 |
148 |
void destroy(GpuText *p_text); |
void destroy(GpuText *p_text); |
149 |
149 |
/// @brief Destroy GlyphManager handle and font data. |
/// @brief Destroy GlyphManager handle and font data. |
150 |
|
/// GlyphManager handle is invalid after destroying |
|
|
150 |
|
/// GlyphManager handle is freed and invalid after this function. |
151 |
151 |
/// @param p_font Valid GlyphManager handle, all GpuText handles created |
/// @param p_font Valid GlyphManager handle, all GpuText handles created |
152 |
152 |
/// with this GlyphManager handle must be destroyed before. |
/// with this GlyphManager handle must be destroyed before. |
153 |
153 |
void destroy(GlyphManager *p_font); |
void destroy(GlyphManager *p_font); |
154 |
|
/// @brief Acquire swapchain image, draw to it and preset to window surface. |
|
|
154 |
|
/// @brief Acquire swapchain image, draw on it and present to window's surface |
155 |
155 |
/// @param models Constant array of models to use in rendering operation |
/// @param models Constant array of models to use in rendering operation |
156 |
|
/// @return If not VK_SUCCESS than frame is not presented |
|
|
156 |
|
/// @return If not VK_SUCCESS then frame is not presented |
157 |
157 |
[[nodiscard]] Result |
[[nodiscard]] Result |
158 |
158 |
draw_frame(const jl::rarray<const Model> &models); |
draw_frame(const jl::rarray<const Model> &models); |
159 |
159 |
struct Data; |
struct Data; |
160 |
160 |
/// @brief Pointer to hidden data of ModuleGraphics. |
/// @brief Pointer to hidden data of ModuleGraphics. |
161 |
|
/// Because of this pointer, ModuleGraphics can be passed by value. |
|
162 |
|
/// Pointer value is valid untill Framework is destroyed. |
|
|
161 |
|
/// Because of this pointer, ModuleGraphics can be shared by value. |
|
162 |
|
/// Pointer value is valid untill the Framework is destroyed. |
163 |
163 |
Data *p; |
Data *p; |
164 |
164 |
}; |
}; |
165 |
165 |
/// @brief Routine to run produce frame drawing in infinite loop. |
/// @brief Routine to run produce frame drawing in infinite loop. |
166 |
166 |
struct jen::DrawFrameLoop { |
struct jen::DrawFrameLoop { |
167 |
167 |
/// @brief Run loop. |
/// @brief Run loop. |
168 |
|
/// To stop drawing loop, set break_loop frag to true. |
|
169 |
|
/// All FrameLoop member values will be initialized before loop in this |
|
170 |
|
/// function. |
|
|
168 |
|
/// To stop drawing the loop, set break_loop frag to true. |
|
169 |
|
/// All FrameLoop member values will be initialized before |
|
170 |
|
/// the loop in this function. |
171 |
171 |
/// @param mg Graphics module to call draw_frame |
/// @param mg Graphics module to call draw_frame |
172 |
172 |
/// @param p_update_arg User pointer to pass to pf_update function |
/// @param p_update_arg User pointer to pass to pf_update function |
173 |
173 |
/// @param pf_update Function pointer to user function that will be called |
/// @param pf_update Function pointer to user function that will be called |
174 |
174 |
/// every frame |
/// every frame |
175 |
175 |
void run(ModuleGraphics mg, void *p_update_arg, void(*pf_update)(void*)); |
void run(ModuleGraphics mg, void *p_update_arg, void(*pf_update)(void*)); |
176 |
|
/// User can check reason of draw_frame failure |
|
|
176 |
|
/// User can check the reason of draw_frame failure |
177 |
177 |
Result result; |
Result result; |
178 |
178 |
/// Last time draw_frame succeeded |
/// Last time draw_frame succeeded |
179 |
179 |
jl::time last_update_time; |
jl::time last_update_time; |
180 |
180 |
/// Time elapsed between loop update and successfull draw_frame |
/// Time elapsed between loop update and successfull draw_frame |
181 |
181 |
jl::time elapsed_after_update; |
jl::time elapsed_after_update; |
182 |
|
/// If true, loop will not draw and will wait user events by using |
|
|
182 |
|
/// If true, loop will not draw and will wait for user events by using |
183 |
183 |
/// Window.wait function. |
/// Window.wait function. |
184 |
|
/// State of this flag is also changing if Key::kPAUSE button is fired |
|
|
184 |
|
/// The state of this flag is also changing if Key::kPAUSE button is fired |
185 |
185 |
bool pause; |
bool pause; |
186 |
186 |
/// Is draw_frame succeeded last time |
/// Is draw_frame succeeded last time |
187 |
187 |
bool is_drawn; |
bool is_drawn; |
188 |
|
/// Set this flag to true every time when need to produce frame |
|
|
188 |
|
/// Set this flag to true every time a frame has to be reproduced |
189 |
189 |
bool draw; |
bool draw; |
190 |
190 |
/// If set to true, function DrawFrameLoop::run will return |
/// If set to true, function DrawFrameLoop::run will return |
191 |
191 |
bool break_loop; |
bool break_loop; |
192 |
|
/// If set to false, loop will make frames as fast as possible using |
|
193 |
|
/// Window.poll, else it will wait user interactions in Window.wait |
|
|
192 |
|
/// If set to false, the loop will make frames as fast as possible using |
|
193 |
|
/// Window.poll, else it will wait for user interactions in Window.wait |
194 |
194 |
bool wait_events; |
bool wait_events; |
195 |
195 |
/// Models to put in draw_frame function |
/// Models to put in draw_frame function |
196 |
196 |
jl::rarray<const Model> models; |
jl::rarray<const Model> models; |
File include/jen/resources.h changed (mode: 100644) (index 997e506..ec9b1c9) |
... |
... |
namespace jen { |
30 |
30 |
struct GpuData; |
struct GpuData; |
31 |
31 |
struct GpuText; |
struct GpuText; |
32 |
32 |
struct GlyphManager; |
struct GlyphManager; |
33 |
|
/// @brief In case user want to allocate manually. |
|
|
33 |
|
/// @brief In case user wants to allocate manually. |
34 |
34 |
constexpr static const uint64_t GPU_DATA_ALLOCATION_SIZE = 88; |
constexpr static const uint64_t GPU_DATA_ALLOCATION_SIZE = 88; |
35 |
35 |
/// @brief Just for fun |
/// @brief Just for fun |
36 |
36 |
constexpr static const uint64_t GPU_TEXTURE_ALLOCATION_SIZE = 120; |
constexpr static const uint64_t GPU_TEXTURE_ALLOCATION_SIZE = 120; |
37 |
37 |
/// @brief User provided data to write into resource memory. |
/// @brief User provided data to write into resource memory. |
38 |
38 |
struct WriteData { |
struct WriteData { |
39 |
|
void *p; ///< Pointer to data that user want to write |
|
|
39 |
|
void *p; ///< Pointer to data which user want to write |
40 |
40 |
uint64_t size; ///< Size of data |
uint64_t size; ///< Size of data |
41 |
41 |
}; |
}; |
42 |
|
/// @brief State of the resource creation. |
|
|
42 |
|
/// @brief State of resource creation. |
43 |
43 |
enum class [[nodiscard]] ResourceState : uint8_t { |
enum class [[nodiscard]] ResourceState : uint8_t { |
44 |
|
LOADING = 0b00, ///< Resource is still loading on the background |
|
|
44 |
|
LOADING = 0b00, ///< Resource is still loading in the background |
45 |
45 |
DONE = 0b01 ///< Resource is loaded and ready to use |
DONE = 0b01 ///< Resource is loaded and ready to use |
46 |
46 |
}; |
}; |
47 |
47 |
/// @brief Get resource state of the GpuData. |
/// @brief Get resource state of the GpuData. |
48 |
|
/// @param p pointer to created by ModuleGraphics::create GpuData |
|
49 |
|
/// @return state of the data preparing process |
|
|
48 |
|
/// @param p pointer to GpuData created by ModuleGraphics::create |
|
49 |
|
/// @return state of the data preparation process |
50 |
50 |
ResourceState resource_state(const GpuData * const p); |
ResourceState resource_state(const GpuData * const p); |
51 |
51 |
/// @brief Get resource state of the GpuTexture. |
/// @brief Get resource state of the GpuTexture. |
52 |
|
/// @param p pointer to created by ModuleGraphics::create GpuTexture |
|
53 |
|
/// @return state of the texture preparing process |
|
|
52 |
|
/// @param p pointer to GpuTexture created by ModuleGraphics::create |
|
53 |
|
/// @return state of the texture preparation process |
54 |
54 |
ResourceState resource_state(const GpuTexture* const p); |
ResourceState resource_state(const GpuTexture* const p); |
55 |
|
/// @brief Helper function to check if resource ready to use. |
|
56 |
|
/// @param p pointer to created by ModuleGraphics::create GpuData |
|
|
55 |
|
/// @brief Helper function to check if resource is ready to use. |
|
56 |
|
/// @param p pointer to GpuData created by ModuleGraphics::create |
57 |
57 |
/// @return true, if resource is ready |
/// @return true, if resource is ready |
58 |
58 |
[[nodiscard]] inline bool is_resource_ready(const GpuData*const p) { |
[[nodiscard]] inline bool is_resource_ready(const GpuData*const p) { |
59 |
59 |
return resource_state(p) == ResourceState::DONE; |
return resource_state(p) == ResourceState::DONE; |
60 |
60 |
} |
} |
61 |
|
/// @brief Helper function to check if resource ready to use. |
|
62 |
|
/// @param p pointer to created by ModuleGraphics::create GpuTexture |
|
|
61 |
|
/// @brief Helper function to check if resource is ready to use. |
|
62 |
|
/// @param p pointer to GpuTexture created by ModuleGraphics::create |
63 |
63 |
/// @return true, if resource is ready |
/// @return true, if resource is ready |
64 |
64 |
[[nodiscard]] inline bool is_resource_ready(const GpuTexture*const p) { |
[[nodiscard]] inline bool is_resource_ready(const GpuTexture*const p) { |
65 |
65 |
return resource_state(p) == ResourceState::DONE; |
return resource_state(p) == ResourceState::DONE; |
66 |
66 |
} |
} |
67 |
67 |
|
|
68 |
|
/// @brief Vertex attributes indices. |
|
|
68 |
|
/// @brief Vertex attribute indices. |
69 |
69 |
enum VAttr : uint8_t { |
enum VAttr : uint8_t { |
70 |
70 |
/// 3x32bit floating point, position |
/// 3x32bit floating point, position |
71 |
71 |
POSITION, |
POSITION, |
|
... |
... |
namespace jen { |
75 |
75 |
NORMAL, |
NORMAL, |
76 |
76 |
/// 32bit value, 4x8bit texture indices (for terrain pipeline) |
/// 32bit value, 4x8bit texture indices (for terrain pipeline) |
77 |
77 |
TEX_IND, |
TEX_IND, |
78 |
|
/// 32bit value, 4x8bit texture indices weights (for terrain pipeline) |
|
|
78 |
|
/// 32bit value, 4x8bit texture index weights (for terrain pipeline) |
79 |
79 |
TEX_SCALE |
TEX_SCALE |
80 |
80 |
}; |
}; |
81 |
|
/// @brief Count of vertex attributes. |
|
|
81 |
|
/// @brief Vertex attribute count. |
82 |
82 |
/// @see Vattr |
/// @see Vattr |
83 |
83 |
constexpr static const uint8_t VATTR_TYPE_COUNT = 5; |
constexpr static const uint8_t VATTR_TYPE_COUNT = 5; |
84 |
|
/// @brief Array of vertex attributes offsets in the memory. |
|
|
84 |
|
/// @brief Array of vertex attribute offsets in the memory. |
85 |
85 |
using VAttrsOffsets = jl::array<uint64_t, VATTR_TYPE_COUNT>; |
using VAttrsOffsets = jl::array<uint64_t, VATTR_TYPE_COUNT>; |
86 |
86 |
/// @brief Vertices stored on gpu. |
/// @brief Vertices stored on gpu. |
87 |
87 |
struct VertexData { |
struct VertexData { |
88 |
88 |
GpuData *p_data; ///< GpuData memory with vertixes |
GpuData *p_data; ///< GpuData memory with vertixes |
89 |
89 |
VAttrsOffsets offsets; ///< where to find attributes in memory |
VAttrsOffsets offsets; ///< where to find attributes in memory |
90 |
|
uint32_t count; ///< count of vertixes |
|
|
90 |
|
uint32_t count; ///< vertex count |
91 |
91 |
}; |
}; |
92 |
92 |
/// @brief Type of index. |
/// @brief Type of index. |
93 |
93 |
enum class IndexType { |
enum class IndexType { |
|
... |
... |
namespace jen { |
98 |
98 |
struct IndexData { |
struct IndexData { |
99 |
99 |
GpuData *p_data; ///< GpuData memory with indices |
GpuData *p_data; ///< GpuData memory with indices |
100 |
100 |
uint64_t offset; ///< where to find indices in memory |
uint64_t offset; ///< where to find indices in memory |
101 |
|
uint32_t count; ///< count of indices |
|
102 |
|
IndexType type; ///< indices encoding |
|
|
101 |
|
uint32_t count; ///< index count |
|
102 |
|
IndexType type; ///< index encoding |
103 |
103 |
}; |
}; |
104 |
104 |
/// @brief Texture stored on gpu. |
/// @brief Texture stored on gpu. |
105 |
105 |
struct TextureData { |
struct TextureData { |
106 |
106 |
GpuTexture *p_data; ///< GpuTexture handle |
GpuTexture *p_data; ///< GpuTexture handle |
107 |
107 |
uint32_t layer_index; ///< Array index in texture to use for model |
uint32_t layer_index; ///< Array index in texture to use for model |
108 |
108 |
}; |
}; |
109 |
|
/// @brief Model rotation, scaling and positioning. |
|
|
109 |
|
/// @brief Model rotation, scale and position. |
110 |
110 |
struct ModelWorld { |
struct ModelWorld { |
111 |
111 |
/// Model transformation matrix 4x4 |
/// Model transformation matrix 4x4 |
112 |
112 |
/// Final model matrix is calculated as: |
/// Final model matrix is calculated as: |
|
... |
... |
namespace jen { |
123 |
123 |
/// final_position = position + offset - camera.position; |
/// final_position = position + offset - camera.position; |
124 |
124 |
/// @endcode |
/// @endcode |
125 |
125 |
jm::v3f position; |
jm::v3f position; |
126 |
|
/// Offset applied to position after shifting on Camera.offset_shift. |
|
|
126 |
|
/// Offset applied to position after shifting to "Camera.offset_shift". |
127 |
127 |
/// @see Camera.pos_offset |
/// @see Camera.pos_offset |
128 |
128 |
/// @see Camera.offset_shift |
/// @see Camera.offset_shift |
129 |
129 |
jm::v3i32 position_offset; |
jm::v3i32 position_offset; |
|
... |
... |
namespace jen { |
134 |
134 |
/// be silently discarded. |
/// be silently discarded. |
135 |
135 |
struct Model { |
struct Model { |
136 |
136 |
/// @brief Is model ready to draw. |
/// @brief Is model ready to draw. |
137 |
|
/// This is helper function, calling it for real-time applications is |
|
|
137 |
|
/// This a helper function, calling it for real-time applications is |
138 |
138 |
/// unnecessary, because unfinished models will be discarded in current |
/// unnecessary, because unfinished models will be discarded in current |
139 |
139 |
/// frame. But for interactive applications it can be important to |
/// frame. But for interactive applications it can be important to |
140 |
140 |
/// explicitly wait until all models will be ready to produce expected |
/// explicitly wait until all models will be ready to produce expected |
141 |
141 |
/// drawing results. |
/// drawing results. |
142 |
|
/// @return false, if any of model resources is on state |
|
|
142 |
|
/// @return false, if any of model resources is in state |
143 |
143 |
/// ResourceState::LOADING |
/// ResourceState::LOADING |
144 |
144 |
[[nodiscard]] bool is_ready_to_draw() const { |
[[nodiscard]] bool is_ready_to_draw() const { |
145 |
145 |
if (not is_resource_ready(tex.p_data)) |
if (not is_resource_ready(tex.p_data)) |
|
... |
... |
namespace jen { |
155 |
155 |
} |
} |
156 |
156 |
/// Model vertices, neccessary |
/// Model vertices, neccessary |
157 |
157 |
VertexData ver; |
VertexData ver; |
158 |
|
/// Indices data, optional, if ind.p_data is null then vertices will |
|
159 |
|
/// be drawed this way: every 3 vertices is a triangle. |
|
160 |
|
/// If indices is presented: every 3 indices pointed to vertices |
|
161 |
|
/// making triangle. |
|
|
158 |
|
/// Index data, optional, if ind.p_data is null then vertices will |
|
159 |
|
/// be drawn this way: each 3 vertex is a triangle. |
|
160 |
|
/// If indices are presented: every 3 indices pointed to vertices |
|
161 |
|
/// making a triangle. |
162 |
162 |
/// So: |
/// So: |
163 |
|
/// - ver.count % 3 == 0, if indices is not presented |
|
164 |
|
/// - ind.count % 3 == 0, if indices is presented |
|
|
163 |
|
/// - ver.count % 3 == 0, if indices are not presented |
|
164 |
|
/// - ind.count % 3 == 0, if indices are presented |
165 |
165 |
IndexData ind; |
IndexData ind; |
166 |
166 |
/// Texture to use, neccessary |
/// Texture to use, neccessary |
167 |
167 |
TextureData tex; |
TextureData tex; |
|
... |
... |
namespace jen { |
173 |
173 |
using Chars = jl::rarray<const uint32_t>; |
using Chars = jl::rarray<const uint32_t>; |
174 |
174 |
/// @brief constant array of R8G8B8A8 colors. |
/// @brief constant array of R8G8B8A8 colors. |
175 |
175 |
using Colors_RGBA = jl::rarray<const uint32_t>; |
using Colors_RGBA = jl::rarray<const uint32_t>; |
176 |
|
/// @brief Ancors for onscreen positioning. |
|
|
176 |
|
/// @brief Anchors for onscreen positioning. |
177 |
177 |
struct TextOffsetMode { |
struct TextOffsetMode { |
178 |
178 |
/// Horizontal offset positioning |
/// Horizontal offset positioning |
179 |
179 |
enum class X : uint8_t { |
enum class X : uint8_t { |
|
... |
... |
namespace jen { |
192 |
192 |
}; |
}; |
193 |
193 |
/// @brief This option changes text characters positioning. |
/// @brief This option changes text characters positioning. |
194 |
194 |
enum class TextLayout : uint8_t { |
enum class TextLayout : uint8_t { |
195 |
|
LEFT, ///< All lines will start from left border |
|
196 |
|
CENTER, ///< All lines will be aligned in the center |
|
|
195 |
|
LEFT, ///< All lines will start from the left border |
|
196 |
|
CENTER, ///< All lines will be aligned to the center |
197 |
197 |
RIGHT ///< All lines will be aligned to the right border |
RIGHT ///< All lines will be aligned to the right border |
198 |
198 |
}; |
}; |
199 |
199 |
/// @brief User provided information about text positioning. |
/// @brief User provided information about text positioning. |
200 |
200 |
struct TextPosition { |
struct TextPosition { |
201 |
201 |
/// Offset position |
/// Offset position |
202 |
202 |
jm::v2f offset; |
jm::v2f offset; |
203 |
|
/// @brief How to place text box relative to offset. |
|
|
203 |
|
/// @brief Text box placement in relation to offset. |
204 |
204 |
TextOffsetMode text_offset_mode; |
TextOffsetMode text_offset_mode; |
205 |
|
/// @brief How to place text box relative to screen. |
|
206 |
|
/// In this valiable offset mode have slightly different meaning, |
|
|
205 |
|
/// @brief Text box placement in relation to screen. |
|
206 |
|
/// In this variable offset mode has slightly different meaning, |
207 |
207 |
/// top-left means text is on the top-left corner of the screen and etc |
/// top-left means text is on the top-left corner of the screen and etc |
208 |
208 |
TextOffsetMode screen_offset_mode; |
TextOffsetMode screen_offset_mode; |
209 |
209 |
}; |
}; |
File include/jen/settings.h changed (mode: 100644) (index 3a08f2b..c7ba267) |
... |
... |
struct jen::ThreadPoolSettings { |
63 |
63 |
/// Must be less than ThreadPoolSettings.queues_count |
/// Must be less than ThreadPoolSettings.queues_count |
64 |
64 |
uint32_t drawFrame; |
uint32_t drawFrame; |
65 |
65 |
}; |
}; |
66 |
|
/// Count of queues in thread pool |
|
|
66 |
|
/// Queue count in thread pool |
67 |
67 |
uint32_t queues_count; |
uint32_t queues_count; |
68 |
|
/// Count of threads in thread pool. |
|
69 |
|
/// If equal to 0, threads count will be selected based on system cpu number |
|
|
68 |
|
/// Thread count in thread pool. |
|
69 |
|
/// If equal to 0, thread count will be selected based on system cpu number |
70 |
70 |
/// @see jl::threads::cpu_number |
/// @see jl::threads::cpu_number |
71 |
71 |
uint32_t threads_count; |
uint32_t threads_count; |
72 |
72 |
/// Queue indices to use in some framework modules |
/// Queue indices to use in some framework modules |
|
... |
... |
struct jen::GraphicsSettings |
96 |
96 |
/// Render weird-looking colors instead of textures to detect |
/// Render weird-looking colors instead of textures to detect |
97 |
97 |
/// texture coordinates |
/// texture coordinates |
98 |
98 |
DEBUG_TEXTURE_COORDINATES, |
DEBUG_TEXTURE_COORDINATES, |
99 |
|
/// Render different colors for every clusters depth level |
|
|
99 |
|
/// Render different colors for every cluster depth level |
100 |
100 |
DEBUG_CLUSTERS_DEPTH, |
DEBUG_CLUSTERS_DEPTH, |
101 |
|
/// Render shapes of gray depending on lights count in cluster |
|
|
101 |
|
/// Render shapes of gray depending on light count in cluster |
102 |
102 |
DEBUG_CLUSTERS_NUM_LIGHTS, |
DEBUG_CLUSTERS_NUM_LIGHTS, |
103 |
|
/// Count of Shading options, invalid value |
|
|
103 |
|
/// Shading option count, invalid value |
104 |
104 |
COUNT |
COUNT |
105 |
105 |
}; |
}; |
106 |
106 |
/// @brief Filter options, specified in number of lookups per fragment. |
/// @brief Filter options, specified in number of lookups per fragment. |
|
... |
... |
struct jen::GraphicsSettings |
120 |
120 |
BACK = 2, /// Discard back faces |
BACK = 2, /// Discard back faces |
121 |
121 |
FRONT_AND_BACK = FRONT | BACK /// Discard all faces |
FRONT_AND_BACK = FRONT | BACK /// Discard all faces |
122 |
122 |
}; |
}; |
123 |
|
/// @brief Update settubgs from keyboard input. |
|
124 |
|
/// Function must be called every frame to be usefull |
|
|
123 |
|
/// @brief Update settings from keyboard input. |
|
124 |
|
/// Function must be called every frame to be useful |
125 |
125 |
/// - F2 to toggle window cursor mode |
/// - F2 to toggle window cursor mode |
126 |
126 |
/// - F3 to toggle is_debug_depth_cube_visible |
/// - F3 to toggle is_debug_depth_cube_visible |
127 |
127 |
/// - F4 to cycle draw_mode |
/// - F4 to cycle draw_mode |
|
... |
... |
struct jen::GraphicsSettings |
174 |
174 |
struct Shadow { |
struct Shadow { |
175 |
175 |
/// bias value |
/// bias value |
176 |
176 |
float bias; |
float bias; |
177 |
|
/// Amount of pcss blocker search lookups (percentage closer soft shadows) |
|
|
177 |
|
/// Amount of "percentage closer soft shadows"'s blocker search lookup count |
178 |
178 |
Filter pcss_search; |
Filter pcss_search; |
179 |
|
/// Percentage closer filtering lookups. |
|
|
179 |
|
/// Amount of "Percentage closer filtering"'s lookup count. |
180 |
180 |
Filter pcf; |
Filter pcf; |
181 |
181 |
/// Light-view depth texture side size. |
/// Light-view depth texture side size. |
182 |
|
/// There is 2D-cube texture, so 6 layers: extent*extent*6. |
|
|
182 |
|
/// A 2D-cube texture represented by 6 layers: extent*extent*6. |
183 |
183 |
uint32_t extent; |
uint32_t extent; |
184 |
184 |
}; |
}; |
185 |
185 |
/// @brief Options for DebugOverlay (display some information on screen). |
/// @brief Options for DebugOverlay (display some information on screen). |
186 |
186 |
struct DebugOverlay { |
struct DebugOverlay { |
187 |
187 |
/// If not enabled, it is impossible to enable later |
/// If not enabled, it is impossible to enable later |
188 |
188 |
bool is_enabled; |
bool is_enabled; |
189 |
|
/// Hide if is not visible |
|
|
189 |
|
/// Overlay will hide if it is not visible |
190 |
190 |
bool is_visible; |
bool is_visible; |
191 |
191 |
/// Keyboard code to toggle visibility |
/// Keyboard code to toggle visibility |
192 |
192 |
Key::Board toggle_key; |
Key::Board toggle_key; |
|
... |
... |
struct jen::GraphicsSettings |
202 |
202 |
/// @see GraphicsSettings::CullMode |
/// @see GraphicsSettings::CullMode |
203 |
203 |
CullMode cull_mode; |
CullMode cull_mode; |
204 |
204 |
/// multisampling mode, must be power of 2. |
/// multisampling mode, must be power of 2. |
205 |
|
/// Values grater than 4 is less likely supported by device. |
|
|
205 |
|
/// Values greater than 4 are less likely supported by device. |
206 |
206 |
uint8_t multisampling; |
uint8_t multisampling; |
207 |
|
/// SwapChain present mode is depends on this setting. |
|
|
207 |
|
/// SwapChain present mode depends on this setting. |
208 |
208 |
/// Usually there is no reason not to use it. |
/// Usually there is no reason not to use it. |
209 |
209 |
/// @see VkPresentModeKHR |
/// @see VkPresentModeKHR |
210 |
210 |
bool is_vSync_enabled; |
bool is_vSync_enabled; |
211 |
211 |
/// If set to false, draw_frame will not wait for device |
/// If set to false, draw_frame will not wait for device |
212 |
|
/// and will return VK_NOT_READY if frame is still not complete. |
|
|
212 |
|
/// and will return VK_NOT_READY if frame is still incomplete. |
213 |
213 |
bool wait_for_gpu_frame_draw; |
bool wait_for_gpu_frame_draw; |
214 |
|
/// If set to true, draw_frame will not allow to draw faster than monitor |
|
|
214 |
|
/// If set to true, draw_frame will not allow to draw faster than the monitor |
215 |
215 |
/// refresh rate. |
/// refresh rate. |
216 |
216 |
bool wait_for_monitor; |
bool wait_for_monitor; |
217 |
|
/// Draw normals for debug purpose. Significantly decreases performance. |
|
|
217 |
|
/// Draw normals for debug purposes. Significantly decreases performance. |
218 |
218 |
bool is_debug_normals_visible; |
bool is_debug_normals_visible; |
219 |
|
/// Draw shadow map depth cube faces onscreen for debug purpose. |
|
|
219 |
|
/// Draw shadow map depth cube faces onscreen for debug purposes. |
220 |
220 |
bool is_debug_depth_cube_visible; |
bool is_debug_depth_cube_visible; |
221 |
221 |
/// @see GraphicsSettings::DebugOverlay |
/// @see GraphicsSettings::DebugOverlay |
222 |
222 |
DebugOverlay debug_overlay; |
DebugOverlay debug_overlay; |
File include/jen/window.h changed (mode: 100644) (index fa0390c..886dfa0) |
... |
... |
struct jen::Window |
37 |
37 |
HIDDEN = GLFW_CURSOR_HIDDEN, |
HIDDEN = GLFW_CURSOR_HIDDEN, |
38 |
38 |
DISABLED = GLFW_CURSOR_DISABLED |
DISABLED = GLFW_CURSOR_DISABLED |
39 |
39 |
}; |
}; |
40 |
|
/// @brief Cursor is just 2D position vector. |
|
|
40 |
|
/// @brief Cursor is just a 2D position vector. |
41 |
41 |
using Cursor = jm::v2d; |
using Cursor = jm::v2d; |
42 |
42 |
/// @brief Extent is 2D size vector. |
/// @brief Extent is 2D size vector. |
43 |
43 |
using Extent = jm::vec2<int>; |
using Extent = jm::vec2<int>; |
|
... |
... |
struct jen::Window |
51 |
51 |
else |
else |
52 |
52 |
glfwHideWindow(p_window); |
glfwHideWindow(p_window); |
53 |
53 |
} |
} |
54 |
|
/// @brief Set minimum and maximum allowed window size. |
|
|
54 |
|
/// @brief Set minimum and maximum window size. |
55 |
55 |
void set_extent_limits(Extent min = ExtentAny, Extent max = ExtentAny) const { |
void set_extent_limits(Extent min = ExtentAny, Extent max = ExtentAny) const { |
56 |
56 |
glfwSetWindowSizeLimits(p_window, min.x, min.y, max.x, max.y); |
glfwSetWindowSizeLimits(p_window, min.x, min.y, max.x, max.y); |
57 |
57 |
} |
} |
58 |
|
/// @brief Get state of keyboard button. |
|
|
58 |
|
/// @brief The state of a keyboard button. |
59 |
59 |
[[nodiscard]] Key::State state(Key::Board key) const { |
[[nodiscard]] Key::State state(Key::Board key) const { |
60 |
60 |
return Key::State(glfwGetKey(p_window, key)); |
return Key::State(glfwGetKey(p_window, key)); |
61 |
61 |
} |
} |
62 |
|
/// @brief Get state of mouse button. |
|
|
62 |
|
/// @brief The state of a mouse button. |
63 |
63 |
[[nodiscard]] Key::State state(Key::Mouse key) const { |
[[nodiscard]] Key::State state(Key::Mouse key) const { |
64 |
64 |
return Key::State(glfwGetMouseButton(p_window, key)); |
return Key::State(glfwGetMouseButton(p_window, key)); |
65 |
65 |
} |
} |
|
... |
... |
struct jen::Window |
86 |
86 |
glfwPollEvents(); |
glfwPollEvents(); |
87 |
87 |
} |
} |
88 |
88 |
/// @brief Wait untill user input or window state will be changed. |
/// @brief Wait untill user input or window state will be changed. |
89 |
|
/// Same as glfwPollEvents, but it will wait untill something to update. |
|
|
89 |
|
/// Same as glfwPollEvents, but it will wait for something to update. |
90 |
90 |
/// Recommended for interactive window usage |
/// Recommended for interactive window usage |
91 |
91 |
/// @see glfwWaitEvents |
/// @see glfwWaitEvents |
92 |
92 |
static void wait() { |
static void wait() { |
93 |
93 |
glfwWaitEvents(); |
glfwWaitEvents(); |
94 |
94 |
} |
} |
95 |
|
/// @brief Check if user want to close the window. |
|
|
95 |
|
/// @brief Check if user wants to close the window. |
96 |
96 |
/// @see glfwWindowShouldClose |
/// @see glfwWindowShouldClose |
97 |
97 |
[[nodiscard]] bool is_window_close_fired() const { |
[[nodiscard]] bool is_window_close_fired() const { |
98 |
98 |
return glfwWindowShouldClose(p_window) == GLFW_TRUE; |
return glfwWindowShouldClose(p_window) == GLFW_TRUE; |
|
... |
... |
struct jen::Window |
119 |
119 |
is_fullscreen = false; |
is_fullscreen = false; |
120 |
120 |
} |
} |
121 |
121 |
} |
} |
122 |
|
/// @brief Set fullscreen mode from windowed or windowed from fullscreen. |
|
|
122 |
|
/// @brief Set fullscreen mode to windowed or windowed to fullscreen. |
123 |
123 |
void toggle_fullscreen() { |
void toggle_fullscreen() { |
124 |
124 |
if (is_fullscreen) |
if (is_fullscreen) |
125 |
125 |
set_windowed(); |
set_windowed(); |
|
... |
... |
struct jen::Window |
151 |
151 |
/// @brief Window data type will be converted to GLFWwindow* silently. |
/// @brief Window data type will be converted to GLFWwindow* silently. |
152 |
152 |
operator GLFWwindow* () { return p_window; } |
operator GLFWwindow* () { return p_window; } |
153 |
153 |
/// @brief This data is used to restore window position and size |
/// @brief This data is used to restore window position and size |
154 |
|
/// as before fullscreen. |
|
|
154 |
|
/// as it was before fullscreen. |
155 |
155 |
struct OldData { |
struct OldData { |
156 |
156 |
Extent extent; ///< @see Window.extent |
Extent extent; ///< @see Window.extent |
157 |
157 |
Extent framebuffer_extent; ///< @see Window.framebuffer_extent |
Extent framebuffer_extent; ///< @see Window.framebuffer_extent |
|
... |
... |
struct jen::Button { |
190 |
190 |
/// @brief Function to get user input without repeating. |
/// @brief Function to get user input without repeating. |
191 |
191 |
/// @param key key code to check state on |
/// @param key key code to check state on |
192 |
192 |
/// @param w window handle to get input from |
/// @param w window handle to get input from |
193 |
|
/// @return true if button is pressed if and only if it was not pressed |
|
194 |
|
/// previous time when function called. |
|
|
193 |
|
/// @return If button is pressed, it returns true. If button was not released |
|
194 |
|
/// and this function is called again than it will return false. |
195 |
195 |
[[nodiscard]] bool is_fired(Key::Board key, const Window &w) { |
[[nodiscard]] bool is_fired(Key::Board key, const Window &w) { |
196 |
196 |
Key::State new_state = w.state(key); |
Key::State new_state = w.state(key); |
197 |
197 |
if (new_state != state) { |
if (new_state != state) { |