MXVK Vulkan Framework 0.24.0
C++20 Vulkan rendering framework for practical 2D and 3D application development with SDL3.
Loading...
Searching...
No Matches
mxvk::VKAbstractModel Class Reference

Convenience wrapper that owns mesh, textures, descriptors, and pipeline state. More...

#include <mxvk/include/mxvk/mxvk_abstract_model.hpp>

Public Member Functions

void cleanup (VK_Window *window)
 Destroy all owned Vulkan resources.
void enableExtendedFragmentUniforms ()
 Use binding 1 for fragment uniforms and binding 2 for model transforms.
bool isLoaded () const
 True once the model has been uploaded to GPU buffers.
void load (VK_Window *window, const std::string &modelPath, const std::string &textureManifestPath, const std::string &textureBasePath, float scale=1.0f)
 Load mesh/texture resources and build Vulkan state.
void load (VK_Window *window, MXModel &&model, const std::string &textureManifestPath, const std::string &textureBasePath, float scale=1.0f)
 Consume pre-parsed mesh data and build Vulkan state.
const MXModelmodel () const
 Access the underlying mesh object.
glm::vec3 modelAxisExtent () const
 Per-axis extent (max - min) of the source mesh's bounding box.
glm::vec3 modelCenterOffset () const
 Access the computed center offset used for normalization.
float modelRenderScale () const
 Access the computed render scale used for normalization.
VKAbstractModeloperator= (const VKAbstractModel &)=delete
VKAbstractModeloperator= (VKAbstractModel &&)=delete
void render (VkCommandBuffer cmd, uint32_t imageIndex, bool wireframe=false) const
 Record draw commands for this model.
void renderWithPushConstants (VkCommandBuffer cmd, uint32_t imageIndex, size_t textureIndex, const UniformBufferObject &ubo, bool wireframe=false)
 Record one draw using push constants for per-draw transforms and an explicit texture slot.
void resize (VK_Window *window)
 Rebuild swapchain-dependent resources after resize.
void setAlphaBlending (bool enabled)
 Enable or disable alpha blending for this model pipeline.
void setBackfaceCulling (bool enabled)
 Enable or disable backface culling for this model pipeline.
void setFragmentPushConstants (const ModelFragmentPushConstants &constants)
 Set sprite-compatible push constants used by custom fragment shaders.
void setShaders (VK_Window *window, const std::string &vertSpv, const std::string &fragSpv)
 Configure custom shader paths and rebuild pipelines.
void updateFragmentUBO (uint32_t imageIndex, const ModelFragmentUniforms &uniforms)
 Update extended fragment uniforms for one swapchain image.
bool updatePrimaryTexture (const void *pixels, int width, int height, int pitch=0)
 Upload raw RGBA pixels into the primary model texture.
void updateUBO (uint32_t imageIndex, const UniformBufferObject &ubo)
 Update one per-frame UBO payload.
 VKAbstractModel ()=default
 VKAbstractModel (const VKAbstractModel &)=delete
 VKAbstractModel (VKAbstractModel &&)=delete
 ~VKAbstractModel ()=default

Detailed Description

Convenience wrapper that owns mesh, textures, descriptors, and pipeline state.

This class is intended to be recorded from inside VK_Window::onRecordCustomRendering() so it participates in the same dynamic-rendering pass as sprites/text.

Definition at line 67 of file mxvk_abstract_model.hpp.

Constructor & Destructor Documentation

◆ VKAbstractModel() [1/3]

mxvk::VKAbstractModel::VKAbstractModel ( )
default

◆ ~VKAbstractModel()

mxvk::VKAbstractModel::~VKAbstractModel ( )
default

◆ VKAbstractModel() [2/3]

mxvk::VKAbstractModel::VKAbstractModel ( const VKAbstractModel & )
delete

◆ VKAbstractModel() [3/3]

mxvk::VKAbstractModel::VKAbstractModel ( VKAbstractModel && )
delete

Member Function Documentation

◆ cleanup()

void mxvk::VKAbstractModel::cleanup ( VK_Window * window)

Destroy all owned Vulkan resources.

Parameters
windowActive MXVK window.

Definition at line 461 of file mxvk_abstract_model.cpp.

461 {
462 if (targetWindow == nullptr || targetWindow->getDevice() == VK_NULL_HANDLE) {
463 return;
464 }
465
466 logVKAbstractModelStep("teardown begin", true);
467 windowPtr = targetWindow;
468 destroyPipelines();
469 destroyDescriptors();
470 destroyTextures();
471 obj.cleanup(windowPtr->getDevice());
472 windowPtr = nullptr;
473 logVKAbstractModelStep("teardown complete", true);
474 }
void logVKAbstractModelStep(const std::string &message, bool important=false)

◆ enableExtendedFragmentUniforms()

void mxvk::VKAbstractModel::enableExtendedFragmentUniforms ( )

Use binding 1 for fragment uniforms and binding 2 for model transforms.

Call before load().

Definition at line 214 of file mxvk_abstract_model.cpp.

214 {
215 if (windowPtr != nullptr) {
216 throw mxvk::Exception("VKAbstractModel::enableExtendedFragmentUniforms must be called before load");
217 }
218 extendedFragmentUniformsEnabled = true;
219 }

◆ isLoaded()

bool mxvk::VKAbstractModel::isLoaded ( ) const
inlinenodiscard

True once the model has been uploaded to GPU buffers.

Definition at line 192 of file mxvk_abstract_model.hpp.

192{ return obj.indexCount() > 0 && vertexBufferReady(); }

◆ load() [1/2]

void mxvk::VKAbstractModel::load ( VK_Window * window,
const std::string & modelPath,
const std::string & textureManifestPath,
const std::string & textureBasePath,
float scale = 1.0f )

Load mesh/texture resources and build Vulkan state.

Parameters
windowActive MXVK window.
modelPathPath to .obj or .mxmod mesh file.
textureManifestPathOptional texture manifest path (.tex or .mtl-like text).
textureBasePathOptional base path for texture files in the manifest.
scaleUniform mesh scale.

Definition at line 81 of file mxvk_abstract_model.cpp.

85 {
86 if (targetWindow == nullptr) {
87 throw mxvk::Exception("VKAbstractModel::load requires a valid window");
88 }
89 if (modelPath.empty()) {
90 throw mxvk::Exception("VKAbstractModel::load modelPath is empty");
91 }
92
93 logVKAbstractModelStep("creation begin: " + modelPath, true);
94
95 windowPtr = targetWindow;
96 if (!windowPtr->ensureRenderResources()) {
97 throw mxvk::Exception("VKAbstractModel::load failed because render resources are not ready");
98 }
99
100 obj.load(modelPath, scale);
101 obj.upload(windowPtr->getDevice(), windowPtr->getPhysicalDevice(), windowPtr->getCommandPool(), windowPtr->getGraphicsQueue());
102 computeBoundsAndScale();
103 logVKAbstractModelStep("mesh upload complete", true);
104
105 textures.clear();
106 if (!textureManifestPath.empty()) {
107 loadTextures(textureManifestPath, textureBasePath);
108 } else {
109 loadTexturesFromMTL(textureBasePath.empty() ? std::filesystem::path(modelPath).parent_path().string() : textureBasePath);
110 }
111 if (textures.empty()) {
112 createFallbackTexture();
113 logVKAbstractModelStep("using fallback texture", true);
114 }
115 logVKAbstractModelStep("textures ready: " + std::to_string(textures.size()), true);
116
117 createTextureSampler();
118 createDescriptorSetLayout();
119 createUniformBuffers();
120 createDescriptorPool();
121 createDescriptorSets();
122 createPipelines();
123 logVKAbstractModelStep("creation complete", true);
124 }

◆ load() [2/2]

void mxvk::VKAbstractModel::load ( VK_Window * window,
MXModel && model,
const std::string & textureManifestPath,
const std::string & textureBasePath,
float scale = 1.0f )

Consume pre-parsed mesh data and build Vulkan state.

Parameters
windowActive MXVK window.
modelPre-parsed CPU-side model data.
textureManifestPathOptional texture manifest path (.tex or .mtl-like text).
textureBasePathOptional base path for texture files in the manifest.
scaleUniform mesh scale. Kept for API compatibility.

Definition at line 126 of file mxvk_abstract_model.cpp.

130 {
131 if (targetWindow == nullptr) {
132 throw mxvk::Exception("VKAbstractModel::load requires a valid window");
133 }
134
135 windowPtr = targetWindow;
136 if (!windowPtr->ensureRenderResources()) {
137 throw mxvk::Exception("VKAbstractModel::load failed because render resources are not ready");
138 }
139
140 obj = std::move(model);
141 obj.upload(windowPtr->getDevice(), windowPtr->getPhysicalDevice(), windowPtr->getCommandPool(), windowPtr->getGraphicsQueue());
142 computeBoundsAndScale();
143 logVKAbstractModelStep("mesh upload complete (prepared)", true);
144
145 textures.clear();
146 if (!textureManifestPath.empty()) {
147 loadTextures(textureManifestPath, textureBasePath);
148 } else if (!obj.mtlLibPath().empty()) {
149 loadTexturesFromMTL(textureBasePath.empty() ? std::filesystem::path(obj.mtlLibPath()).parent_path().string() : textureBasePath);
150 } else {
151 createFallbackTexture();
152 logVKAbstractModelStep("using fallback texture", true);
153 }
154 if (textures.empty()) {
155 createFallbackTexture();
156 logVKAbstractModelStep("using fallback texture", true);
157 }
158 logVKAbstractModelStep("textures ready: " + std::to_string(textures.size()), true);
159
160 createTextureSampler();
161 createDescriptorSetLayout();
162 createUniformBuffers();
163 createDescriptorPool();
164 createDescriptorSets();
165 createPipelines();
166 logVKAbstractModelStep("creation complete", true);
167 }
const MXModel & model() const
Access the underlying mesh object.

◆ model()

const MXModel & mxvk::VKAbstractModel::model ( ) const
inlinenodiscard

Access the underlying mesh object.

Definition at line 184 of file mxvk_abstract_model.hpp.

184{ return obj; }

◆ modelAxisExtent()

glm::vec3 mxvk::VKAbstractModel::modelAxisExtent ( ) const
inlinenodiscard

Per-axis extent (max - min) of the source mesh's bounding box.

Definition at line 190 of file mxvk_abstract_model.hpp.

190{ return modelAxisExtentValue; }

◆ modelCenterOffset()

glm::vec3 mxvk::VKAbstractModel::modelCenterOffset ( ) const
inlinenodiscard

Access the computed center offset used for normalization.

Definition at line 186 of file mxvk_abstract_model.hpp.

186{ return modelCenterOffsetValue; }

◆ modelRenderScale()

float mxvk::VKAbstractModel::modelRenderScale ( ) const
inlinenodiscard

Access the computed render scale used for normalization.

Definition at line 188 of file mxvk_abstract_model.hpp.

188{ return modelRenderScaleValue; }

◆ operator=() [1/2]

VKAbstractModel & mxvk::VKAbstractModel::operator= ( const VKAbstractModel & )
delete

◆ operator=() [2/2]

VKAbstractModel & mxvk::VKAbstractModel::operator= ( VKAbstractModel && )
delete

◆ render()

void mxvk::VKAbstractModel::render ( VkCommandBuffer cmd,
uint32_t imageIndex,
bool wireframe = false ) const

Record draw commands for this model.

Parameters
cmdActive command buffer, inside a dynamic rendering scope.
imageIndexCurrent swapchain image index.
wireframeRender using the optional wireframe pipeline when available.

Definition at line 345 of file mxvk_abstract_model.cpp.

345 {
346 if (cmd == VK_NULL_HANDLE || imageIndex >= uniformBuffers.size() || descriptorSets.empty()) {
347 return;
348 }
349
350 const VkPipeline pipeline = (wireframe && pipelineWireframe != VK_NULL_HANDLE) ? pipelineWireframe : pipelineFill;
351 if (pipeline == VK_NULL_HANDLE || pipelineLayout == VK_NULL_HANDLE) {
352 return;
353 }
354
355 vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
356 if (extendedFragmentUniformsEnabled) {
357 vkCmdPushConstants(cmd,
358 pipelineLayout,
359 VK_SHADER_STAGE_FRAGMENT_BIT,
360 0,
361 sizeof(ModelFragmentPushConstants),
362 &fragmentPushConstants);
363 }
364
365 const size_t textureCount = std::max<size_t>(1, textures.size());
366 for (size_t i = 0; i < obj.subMeshCount(); ++i) {
367 const SubMesh &submesh = obj.subMesh(i);
368 const size_t textureIndex = std::min<size_t>(submesh.textureIndex, textureCount - 1U);
369 const size_t setIndex = static_cast<size_t>(imageIndex) * textureCount + textureIndex;
370 if (setIndex >= descriptorSets.size()) {
371 continue;
372 }
373
374 vkCmdBindDescriptorSets(cmd,
375 VK_PIPELINE_BIND_POINT_GRAPHICS,
376 pipelineLayout,
377 0,
378 1,
379 &descriptorSets[setIndex],
380 0,
381 nullptr);
382
383 obj.drawSubMesh(cmd, i);
384 }
385 }

◆ renderWithPushConstants()

void mxvk::VKAbstractModel::renderWithPushConstants ( VkCommandBuffer cmd,
uint32_t imageIndex,
size_t textureIndex,
const UniformBufferObject & ubo,
bool wireframe = false )

Record one draw using push constants for per-draw transforms and an explicit texture slot.

Parameters
cmdActive command buffer, inside a dynamic rendering scope.
imageIndexCurrent swapchain image index.
textureIndexTexture slot to bind for all submeshes in this draw.
uboTransform/effect payload copied into vertex-stage push constants.
wireframeRender using the optional wireframe pipeline when available.

Definition at line 387 of file mxvk_abstract_model.cpp.

391 {
392 if (cmd == VK_NULL_HANDLE || imageIndex >= uniformBuffers.size() || descriptorSets.empty()) {
393 return;
394 }
395
396 const VkPipeline pipeline = (wireframe && pipelineWireframe != VK_NULL_HANDLE) ? pipelineWireframe : pipelineFill;
397 if (pipeline == VK_NULL_HANDLE || pipelineLayout == VK_NULL_HANDLE) {
398 return;
399 }
400
401 const size_t textureCount = std::max<size_t>(1, textures.size());
402 textureIndex = std::min(textureIndex, textureCount - 1U);
403 const size_t setIndex = static_cast<size_t>(imageIndex) * textureCount + textureIndex;
404 if (setIndex >= descriptorSets.size()) {
405 return;
406 }
407
408 vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
409 updateUBO(imageIndex, ubo);
410 const ModelPushConstants pushConstants{
411 .model = ubo.model,
412 .fx = ubo.fx,
413 };
414 vkCmdPushConstants(cmd,
415 pipelineLayout,
416 VK_SHADER_STAGE_VERTEX_BIT,
417 0,
418 sizeof(ModelPushConstants),
419 &pushConstants);
420 if (extendedFragmentUniformsEnabled) {
421 vkCmdPushConstants(cmd,
422 pipelineLayout,
423 VK_SHADER_STAGE_FRAGMENT_BIT,
424 0,
425 sizeof(ModelFragmentPushConstants),
426 &fragmentPushConstants);
427 }
428 vkCmdBindDescriptorSets(cmd,
429 VK_PIPELINE_BIND_POINT_GRAPHICS,
430 pipelineLayout,
431 0,
432 1,
433 &descriptorSets[setIndex],
434 0,
435 nullptr);
436
437 obj.draw(cmd);
438 }
void updateUBO(uint32_t imageIndex, const UniformBufferObject &ubo)
Update one per-frame UBO payload.

◆ resize()

void mxvk::VKAbstractModel::resize ( VK_Window * window)

Rebuild swapchain-dependent resources after resize.

Parameters
windowActive MXVK window.

Definition at line 440 of file mxvk_abstract_model.cpp.

440 {
441 if (targetWindow == nullptr || targetWindow->getDevice() == VK_NULL_HANDLE) {
442 return;
443 }
444 if (!isLoaded()) {
445 return;
446 }
447
448 logVKAbstractModelStep("resize begin", true);
449 windowPtr = targetWindow;
450 destroyPipelines();
451 destroyDescriptors();
452
453 createDescriptorSetLayout();
454 createUniformBuffers();
455 createDescriptorPool();
456 createDescriptorSets();
457 createPipelines();
458 logVKAbstractModelStep("resize complete", true);
459 }
bool isLoaded() const
True once the model has been uploaded to GPU buffers.

◆ setAlphaBlending()

void mxvk::VKAbstractModel::setAlphaBlending ( bool enabled)

Enable or disable alpha blending for this model pipeline.

Parameters
enabledTrue to blend fragment alpha and avoid depth writes.

Definition at line 192 of file mxvk_abstract_model.cpp.

192 {
193 if (alphaBlendingEnabled == enabled) {
194 return;
195 }
196
197 alphaBlendingEnabled = enabled;
198 if (windowPtr != nullptr) {
199 createPipelines();
200 }
201 }

◆ setBackfaceCulling()

void mxvk::VKAbstractModel::setBackfaceCulling ( bool enabled)

Enable or disable backface culling for this model pipeline.

Parameters
enabledTrue to cull backfaces, false to disable culling.

Definition at line 181 of file mxvk_abstract_model.cpp.

181 {
182 if (backfaceCullingEnabled == enabled) {
183 return;
184 }
185
186 backfaceCullingEnabled = enabled;
187 if (windowPtr != nullptr) {
188 createPipelines();
189 }
190 }

◆ setFragmentPushConstants()

void mxvk::VKAbstractModel::setFragmentPushConstants ( const ModelFragmentPushConstants & constants)

Set sprite-compatible push constants used by custom fragment shaders.

Definition at line 228 of file mxvk_abstract_model.cpp.

228 {
229 fragmentPushConstants = constants;
230 }

◆ setShaders()

void mxvk::VKAbstractModel::setShaders ( VK_Window * window,
const std::string & vertSpv,
const std::string & fragSpv )

Configure custom shader paths and rebuild pipelines.

Parameters
windowActive MXVK window.
vertSpvVertex shader SPIR-V path.
fragSpvFragment shader SPIR-V path.

Definition at line 169 of file mxvk_abstract_model.cpp.

169 {
170 if (targetWindow == nullptr) {
171 throw mxvk::Exception("VKAbstractModel::setShaders requires a valid window");
172 }
173
174 windowPtr = targetWindow;
175 vertexShaderPath = vertSpv;
176 fragmentShaderPath = fragSpv;
177 logVKAbstractModelStep("setShaders", true);
178 createPipelines();
179 }

◆ updateFragmentUBO()

void mxvk::VKAbstractModel::updateFragmentUBO ( uint32_t imageIndex,
const ModelFragmentUniforms & uniforms )

Update extended fragment uniforms for one swapchain image.

Definition at line 221 of file mxvk_abstract_model.cpp.

221 {
222 if (imageIndex >= fragmentUniformBuffersMapped.size() || fragmentUniformBuffersMapped[imageIndex] == nullptr) {
223 return;
224 }
225 std::memcpy(fragmentUniformBuffersMapped[imageIndex], &uniforms, sizeof(ModelFragmentUniforms));
226 }

◆ updatePrimaryTexture()

bool mxvk::VKAbstractModel::updatePrimaryTexture ( const void * pixels,
int width,
int height,
int pitch = 0 )
nodiscard

Upload raw RGBA pixels into the primary model texture.

Parameters
pixelsPointer to RGBA8 pixel data.
widthTexture width in pixels.
heightTexture height in pixels.
pitchBytes per input row. When 0, defaults to width * 4.
Returns
True when the upload succeeds, false for invalid inputs or unavailable resources.

Definition at line 232 of file mxvk_abstract_model.cpp.

232 {
233 if (windowPtr == nullptr || windowPtr->getDevice() == VK_NULL_HANDLE) {
234 return false;
235 }
236 if (pixels == nullptr || width <= 0 || height <= 0) {
237 return false;
238 }
239
240 const uint32_t uploadWidth = static_cast<uint32_t>(width);
241 const uint32_t uploadHeight = static_cast<uint32_t>(height);
242 const uint32_t srcRowBytes = static_cast<uint32_t>(pitch > 0 ? pitch : width * 4);
243 const uint32_t tightRowBytes = uploadWidth * 4U;
244 if (srcRowBytes < tightRowBytes) {
245 return false;
246 }
247
248 if (textures.empty()) {
249 createFallbackTexture();
250 createDescriptorSets();
251 }
252
253 TextureEntry &texture = textures[0];
254 if (texture.image == VK_NULL_HANDLE || texture.memory == VK_NULL_HANDLE || texture.view == VK_NULL_HANDLE) {
255 return false;
256 }
257
258 bool recreatedTexture = false;
259 if (texture.width != uploadWidth || texture.height != uploadHeight) {
260 vkDeviceWaitIdle(windowPtr->getDevice());
261
262#ifdef MXVK_CUDA
263 destroyTextureCudaInterop(texture);
264#endif
265 if (texture.view != VK_NULL_HANDLE) {
266 vkDestroyImageView(windowPtr->getDevice(), texture.view, nullptr);
267 }
268 if (texture.image != VK_NULL_HANDLE) {
269 vkDestroyImage(windowPtr->getDevice(), texture.image, nullptr);
270 }
271 if (texture.memory != VK_NULL_HANDLE) {
272 vkFreeMemory(windowPtr->getDevice(), texture.memory, nullptr);
273 }
274
275 texture.view = VK_NULL_HANDLE;
276 texture.image = VK_NULL_HANDLE;
277 texture.memory = VK_NULL_HANDLE;
278
279 createTextureImage(uploadWidth, uploadHeight, texture);
280
281 texture.view = createImageView(texture.image, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_ASPECT_COLOR_BIT);
282 texture.width = uploadWidth;
283 texture.height = uploadHeight;
284 recreatedTexture = true;
285
286 createDescriptorSets();
287 }
288
289#ifdef MXVK_CUDA
290 if (updatePrimaryTextureCudaHost(texture, pixels, uploadWidth, uploadHeight, srcRowBytes)) {
291 return true;
292 }
293#endif
294
295 const VkDeviceSize stagingSize = static_cast<VkDeviceSize>(tightRowBytes) * uploadHeight;
296 VkBuffer stagingBuffer = VK_NULL_HANDLE;
297 VkDeviceMemory stagingMemory = VK_NULL_HANDLE;
298 createBuffer(stagingSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
299 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
300 stagingBuffer, stagingMemory);
301
302 void *mapped = nullptr;
303 const VkResult mapResult = vkMapMemory(windowPtr->getDevice(), stagingMemory, 0, stagingSize, 0, &mapped);
304 if (mapResult != VK_SUCCESS || mapped == nullptr) {
305 vkDestroyBuffer(windowPtr->getDevice(), stagingBuffer, nullptr);
306 vkFreeMemory(windowPtr->getDevice(), stagingMemory, nullptr);
307 return false;
308 }
309
310 if (srcRowBytes == tightRowBytes) {
311 std::memcpy(mapped, pixels, static_cast<size_t>(stagingSize));
312 } else {
313 const auto *src = static_cast<const uint8_t *>(pixels);
314 auto *dst = static_cast<uint8_t *>(mapped);
315 for (uint32_t y = 0; y < uploadHeight; ++y) {
316 const size_t srcOffset = static_cast<size_t>(y) * srcRowBytes;
317 const size_t dstOffset = static_cast<size_t>(y) * tightRowBytes;
318 std::memcpy(dst + dstOffset, src + srcOffset, tightRowBytes);
319 }
320 }
321 vkUnmapMemory(windowPtr->getDevice(), stagingMemory);
322
323 if (recreatedTexture) {
324 transitionImageLayout(texture.image, VK_FORMAT_R8G8B8A8_UNORM,
325 VK_IMAGE_LAYOUT_UNDEFINED,
326 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
327 } else {
328 transitionImageLayout(texture.image, VK_FORMAT_R8G8B8A8_UNORM,
329 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
330 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
331 }
332 copyBufferToImage(stagingBuffer, texture.image, uploadWidth, uploadHeight);
333 transitionImageLayout(texture.image, VK_FORMAT_R8G8B8A8_UNORM,
334 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
335 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
336#ifdef MXVK_CUDA
337 texture.cudaImageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
338#endif
339
340 vkDestroyBuffer(windowPtr->getDevice(), stagingBuffer, nullptr);
341 vkFreeMemory(windowPtr->getDevice(), stagingMemory, nullptr);
342 return true;
343 }

◆ updateUBO()

void mxvk::VKAbstractModel::updateUBO ( uint32_t imageIndex,
const UniformBufferObject & ubo )

Update one per-frame UBO payload.

Parameters
imageIndexSwapchain image index.
uboNew transform values.

Definition at line 203 of file mxvk_abstract_model.cpp.

203 {
204 if (imageIndex >= uniformBuffersMapped.size()) {
205 return;
206 }
207 if (uniformBuffersMapped[imageIndex] == nullptr) {
208 return;
209 }
210
211 std::memcpy(uniformBuffersMapped[imageIndex], &ubo, sizeof(UniformBufferObject));
212 }

The documentation for this class was generated from the following files: