Gpu fixes

This commit is contained in:
luboslenco
2025-08-14 00:25:01 +02:00
parent 328ff1c18b
commit c3cf9353d3
8 changed files with 81 additions and 50 deletions
+7 -7
View File
@@ -152,10 +152,10 @@ void gpu_barrier(gpu_texture_t *render_target, gpu_texture_state_t state_after)
void gpu_destroy() { void gpu_destroy() {
gpu_wait(); gpu_wait();
for (int i = 0; i < GPU_FRAMEBUFFER_COUNT; ++i) { for (int i = 0; i < GPU_FRAMEBUFFER_COUNT; ++i) {
gpu_texture_destroy(&framebuffers[i]); gpu_texture_destroy_internal(&framebuffers[i]);
} }
if (framebuffer_depth.width > 0) { if (framebuffer_depth.width > 0) {
gpu_texture_destroy(&framebuffer_depth); gpu_texture_destroy_internal(&framebuffer_depth);
} }
if (readback_buffer != NULL) { if (readback_buffer != NULL) {
readback_buffer->lpVtbl->Release(readback_buffer); readback_buffer->lpVtbl->Release(readback_buffer);
@@ -448,10 +448,10 @@ void gpu_present_internal() {
framebuffer_index = 0; framebuffer_index = 0;
for (int i = 0; i < GPU_FRAMEBUFFER_COUNT; ++i) { for (int i = 0; i < GPU_FRAMEBUFFER_COUNT; ++i) {
gpu_texture_destroy(&framebuffers[i]); gpu_texture_destroy_internal(&framebuffers[i]);
} }
if (framebuffer_depth.width > 0) { if (framebuffer_depth.width > 0) {
gpu_texture_destroy(&framebuffer_depth); gpu_texture_destroy_internal(&framebuffer_depth);
} }
window_swapchain->lpVtbl->ResizeBuffers(window_swapchain, GPU_FRAMEBUFFER_COUNT, iron_window_width(), iron_window_height(), DXGI_FORMAT_R8G8B8A8_UNORM, 0); window_swapchain->lpVtbl->ResizeBuffers(window_swapchain, GPU_FRAMEBUFFER_COUNT, iron_window_width(), iron_window_height(), DXGI_FORMAT_R8G8B8A8_UNORM, 0);
@@ -707,7 +707,7 @@ void gpu_use_linear_sampling(bool b) {
device->lpVtbl->CreateSampler(device, &sampler_desc, sampler_handle); device->lpVtbl->CreateSampler(device, &sampler_desc, sampler_handle);
} }
void gpu_pipeline_destroy(gpu_pipeline_t *pipe) { void gpu_pipeline_destroy_internal(gpu_pipeline_t *pipe) {
if (pipe->impl.pso != NULL) { if (pipe->impl.pso != NULL) {
pipe->impl.pso->lpVtbl->Release(pipe->impl.pso); pipe->impl.pso->lpVtbl->Release(pipe->impl.pso);
pipe->impl.pso = NULL; pipe->impl.pso = NULL;
@@ -965,7 +965,7 @@ void gpu_texture_init_from_bytes(gpu_texture_t *texture, void *data, int width,
gpu_execute_and_wait(); //// gpu_execute_and_wait(); ////
} }
void gpu_texture_destroy(gpu_texture_t *render_target) { void gpu_texture_destroy_internal(gpu_texture_t *render_target) {
if (render_target->impl.image != NULL) { if (render_target->impl.image != NULL) {
render_target->impl.image->lpVtbl->Release(render_target->impl.image); render_target->impl.image->lpVtbl->Release(render_target->impl.image);
} }
@@ -1113,7 +1113,7 @@ void gpu_constant_buffer_unlock(gpu_buffer_t *buffer) {
buffer->data = NULL; buffer->data = NULL;
} }
void gpu_buffer_destroy(gpu_buffer_t *buffer) { void gpu_buffer_destroy_internal(gpu_buffer_t *buffer) {
buffer->impl.buffer->lpVtbl->Release(buffer->impl.buffer); buffer->impl.buffer->lpVtbl->Release(buffer->impl.buffer);
buffer->impl.buffer = NULL; buffer->impl.buffer = NULL;
} }
+4 -4
View File
@@ -280,7 +280,7 @@ void gpu_present_internal() {
CAMetalLayer *layer = get_metal_layer(); CAMetalLayer *layer = get_metal_layer();
layer.drawableSize = CGSizeMake(iron_window_width(), iron_window_height()); layer.drawableSize = CGSizeMake(iron_window_width(), iron_window_height());
for (int i = 0; i < GPU_FRAMEBUFFER_COUNT; ++i) { for (int i = 0; i < GPU_FRAMEBUFFER_COUNT; ++i) {
// gpu_texture_destroy(&framebuffers[i]); // gpu_texture_destroy_internal(&framebuffers[i]);
gpu_render_target_init2(&framebuffers[i], iron_window_width(), iron_window_height(), GPU_TEXTURE_FORMAT_RGBA32, i); gpu_render_target_init2(&framebuffers[i], iron_window_width(), iron_window_height(), GPU_TEXTURE_FORMAT_RGBA32, i);
} }
resized = false; resized = false;
@@ -418,7 +418,7 @@ void gpu_use_linear_sampling(bool b) {
linear_sampling = b; linear_sampling = b;
} }
void gpu_pipeline_destroy(gpu_pipeline_t *pipeline) { void gpu_pipeline_destroy_internal(gpu_pipeline_t *pipeline) {
id<MTLRenderPipelineState> pipe = (__bridge_transfer id<MTLRenderPipelineState>)pipeline->impl._pipeline; id<MTLRenderPipelineState> pipe = (__bridge_transfer id<MTLRenderPipelineState>)pipeline->impl._pipeline;
pipe = nil; pipe = nil;
pipeline->impl._pipeline = NULL; pipeline->impl._pipeline = NULL;
@@ -572,7 +572,7 @@ void gpu_texture_init_from_bytes(gpu_texture_t *texture, void *data, int width,
bytesPerImage:width * gpu_texture_format_size(format) * height]; bytesPerImage:width * gpu_texture_format_size(format) * height];
} }
void gpu_texture_destroy(gpu_texture_t *target) { void gpu_texture_destroy_internal(gpu_texture_t *target) {
id<MTLTexture> tex = (__bridge_transfer id<MTLTexture>)target->impl._tex; id<MTLTexture> tex = (__bridge_transfer id<MTLTexture>)target->impl._tex;
tex = nil; tex = nil;
target->impl._tex = NULL; target->impl._tex = NULL;
@@ -632,7 +632,7 @@ void gpu_index_buffer_init(gpu_buffer_t *buffer, int indexCount) {
options:options]; options:options];
} }
void gpu_buffer_destroy(gpu_buffer_t *buffer) { void gpu_buffer_destroy_internal(gpu_buffer_t *buffer) {
id<MTLBuffer> buf = (__bridge_transfer id<MTLBuffer>)buffer->impl.metal_buffer; id<MTLBuffer> buf = (__bridge_transfer id<MTLBuffer>)buffer->impl.metal_buffer;
buf = nil; buf = nil;
buffer->impl.metal_buffer = NULL; buffer->impl.metal_buffer = NULL;
+25 -9
View File
@@ -159,10 +159,10 @@ static VkBool32 vk_debug_utils_messenger_callback_ext(
const VkDebugUtilsMessengerCallbackDataEXT *pcallback_data, const VkDebugUtilsMessengerCallbackDataEXT *pcallback_data,
void *puser_data) { void *puser_data) {
if (message_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) { if (message_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) {
iron_error("Vulkan ERROR: Code %d : %s", pcallback_data->messageIdNumber, pcallback_data->pMessage); iron_error("Vulkan ERROR: Code %d : %s\n", pcallback_data->messageIdNumber, pcallback_data->pMessage);
} }
else if (message_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) { else if (message_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) {
iron_log("Vulkan WARNING: Code %d : %s", pcallback_data->messageIdNumber, pcallback_data->pMessage); iron_log("Vulkan WARNING: Code %d : %s\n", pcallback_data->messageIdNumber, pcallback_data->pMessage);
} }
return VK_FALSE; return VK_FALSE;
} }
@@ -386,7 +386,7 @@ static void create_descriptors(void) {
VkSwapchainKHR cleanup_swapchain() { VkSwapchainKHR cleanup_swapchain() {
// for (int i = 0; i < GPU_FRAMEBUFFER_COUNT; ++i) { // for (int i = 0; i < GPU_FRAMEBUFFER_COUNT; ++i) {
// gpu_texture_destroy(&framebuffers[i]); // gpu_texture_destroy_internal(&framebuffers[i]);
// } // }
VkSwapchainKHR chain = window_swapchain; VkSwapchainKHR chain = window_swapchain;
window_swapchain = VK_NULL_HANDLE; window_swapchain = VK_NULL_HANDLE;
@@ -399,6 +399,7 @@ void gpu_render_target_init2(gpu_texture_t *target, int width, int height, gpu_t
target->format = format; target->format = format;
target->state = (framebuffer_index >= 0) ? GPU_TEXTURE_STATE_PRESENT : GPU_TEXTURE_STATE_SHADER_RESOURCE; target->state = (framebuffer_index >= 0) ? GPU_TEXTURE_STATE_PRESENT : GPU_TEXTURE_STATE_SHADER_RESOURCE;
target->buffer = NULL; target->buffer = NULL;
target->impl.has_storage_bit = false;
if (framebuffer_index >= 0) { if (framebuffer_index >= 0) {
return; return;
@@ -627,7 +628,7 @@ static void acquire_next_image() {
acquire_next_image(); acquire_next_image();
for (int i = 0; i < GPU_FRAMEBUFFER_COUNT; ++i) { for (int i = 0; i < GPU_FRAMEBUFFER_COUNT; ++i) {
// gpu_texture_destroy(&framebuffers[i]); // gpu_texture_destroy_internal(&framebuffers[i]);
// gpu_render_target_init2(&framebuffers[i], iron_window_width(), iron_window_height(), GPU_TEXTURE_FORMAT_RGBA32, i); // gpu_render_target_init2(&framebuffers[i], iron_window_width(), iron_window_height(), GPU_TEXTURE_FORMAT_RGBA32, i);
framebuffers[i].width = iron_window_width(); framebuffers[i].width = iron_window_width();
framebuffers[i].height = iron_window_height(); framebuffers[i].height = iron_window_height();
@@ -1298,6 +1299,9 @@ void gpu_disable_scissor() {
void gpu_set_pipeline(gpu_pipeline_t *pipeline) { void gpu_set_pipeline(gpu_pipeline_t *pipeline) {
current_pipeline = pipeline; current_pipeline = pipeline;
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, current_pipeline->impl.pipeline); vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, current_pipeline->impl.pipeline);
for (int i = 0; i < GPU_MAX_TEXTURES; ++i) {
current_textures[i] = NULL;
}
} }
void gpu_set_vertex_buffer(gpu_buffer_t *buffer) { void gpu_set_vertex_buffer(gpu_buffer_t *buffer) {
@@ -1457,7 +1461,7 @@ void gpu_use_linear_sampling(bool b) {
linear_sampling = b; linear_sampling = b;
} }
void gpu_pipeline_destroy(gpu_pipeline_t *pipeline) { void gpu_pipeline_destroy_internal(gpu_pipeline_t *pipeline) {
vkDestroyPipeline(device, pipeline->impl.pipeline, NULL); vkDestroyPipeline(device, pipeline->impl.pipeline, NULL);
vkDestroyPipelineLayout(device, pipeline->impl.pipeline_layout, NULL); vkDestroyPipelineLayout(device, pipeline->impl.pipeline_layout, NULL);
} }
@@ -1804,7 +1808,7 @@ void gpu_texture_init_from_bytes(gpu_texture_t *texture, void *data, int width,
gpu_execute_and_wait(); //// gpu_execute_and_wait(); ////
} }
void gpu_texture_destroy(gpu_texture_t *target) { void gpu_texture_destroy_internal(gpu_texture_t *target) {
if (target->impl.image != NULL) { if (target->impl.image != NULL) {
vkDestroyImage(device, target->impl.image, NULL); vkDestroyImage(device, target->impl.image, NULL);
vkFreeMemory(device, target->impl.mem, NULL); vkFreeMemory(device, target->impl.mem, NULL);
@@ -1934,7 +1938,7 @@ void gpu_constant_buffer_unlock(gpu_buffer_t *buffer) {
buffer->data = NULL; buffer->data = NULL;
} }
void gpu_buffer_destroy(gpu_buffer_t *buffer) { void gpu_buffer_destroy_internal(gpu_buffer_t *buffer) {
vkFreeMemory(device, buffer->impl.mem, NULL); vkFreeMemory(device, buffer->impl.mem, NULL);
vkDestroyBuffer(device, buffer->impl.buf, NULL); vkDestroyBuffer(device, buffer->impl.buf, NULL);
} }
@@ -3030,8 +3034,9 @@ void gpu_raytrace_set_pipeline(gpu_raytrace_pipeline_t *_pipeline) {
} }
void gpu_raytrace_set_target(gpu_texture_t *_output) { void gpu_raytrace_set_target(gpu_texture_t *_output) {
if (_output != output) { if (!_output->impl.has_storage_bit) {
vkDestroyImage(device, _output->impl.image, NULL); _output->impl.has_storage_bit = true;
gpu_texture_destroy(_output);
VkImageCreateInfo image_info = { VkImageCreateInfo image_info = {
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
@@ -3049,6 +3054,17 @@ void gpu_raytrace_set_target(gpu_texture_t *_output) {
.flags = 0, .flags = 0,
}; };
vkCreateImage(device, &image_info, NULL, &_output->impl.image); vkCreateImage(device, &image_info, NULL, &_output->impl.image);
VkMemoryRequirements memory_reqs;
vkGetImageMemoryRequirements(device, _output->impl.image, &memory_reqs);
VkMemoryAllocateInfo allocation_nfo = {
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.pNext = NULL,
.allocationSize = memory_reqs.size,
};
allocation_nfo.memoryTypeIndex = memory_type_from_properties(memory_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
vkAllocateMemory(device, &allocation_nfo, NULL, &_output->impl.mem);
vkBindImageMemory(device, _output->impl.image, _output->impl.mem, 0); vkBindImageMemory(device, _output->impl.image, _output->impl.mem, 0);
VkImageViewCreateInfo image_view_info = { VkImageViewCreateInfo image_view_info = {
+1
View File
@@ -20,6 +20,7 @@ typedef struct {
VkImage image; VkImage image;
VkDeviceMemory mem; VkDeviceMemory mem;
VkImageView view; VkImageView view;
bool has_storage_bit;
} gpu_texture_impl_t; } gpu_texture_impl_t;
typedef struct { typedef struct {
+6 -28
View File
@@ -392,12 +392,6 @@ static gpu_raytrace_acceleration_structure_t rt_accel;
static bool rt_created = false; static bool rt_created = false;
static bool rt_accel_created = false; static bool rt_accel_created = false;
const int rt_constant_buffer_size = 24; const int rt_constant_buffer_size = 24;
static gpu_texture_t *textures_to_destroy[128];
static gpu_buffer_t *buffers_to_destroy[128];
static gpu_pipeline_t *pipelines_to_destroy[32];
static int textures_to_destroy_count = 0;
static int buffers_to_destroy_count = 0;
static int pipelines_to_destroy_count = 0;
void _update(void *data) { void _update(void *data) {
#ifdef IRON_WINDOWS #ifdef IRON_WINDOWS
@@ -435,22 +429,6 @@ void _update(void *data) {
iron_a2_update(); iron_a2_update();
#endif #endif
while (textures_to_destroy_count > 0) {
textures_to_destroy_count--;
gpu_texture_destroy(textures_to_destroy[textures_to_destroy_count]);
free(textures_to_destroy[textures_to_destroy_count]);
}
while (buffers_to_destroy_count > 0) {
buffers_to_destroy_count--;
gpu_buffer_destroy(buffers_to_destroy[buffers_to_destroy_count]);
free(buffers_to_destroy[buffers_to_destroy_count]);
}
while (pipelines_to_destroy_count > 0) {
pipelines_to_destroy_count--;
gpu_pipeline_destroy(pipelines_to_destroy[pipelines_to_destroy_count]);
free(pipelines_to_destroy[pipelines_to_destroy_count]);
}
iron_update(); iron_update();
gpu_present(); gpu_present();
} }
@@ -943,8 +921,8 @@ void iron_set_gamepad_button_callback(void (*callback)(int, int, float)) {
#endif #endif
void gpu_delete_buffer(gpu_buffer_t *buffer) { void gpu_delete_buffer(gpu_buffer_t *buffer) {
buffers_to_destroy[buffers_to_destroy_count] = buffer; gpu_buffer_destroy(buffer);
buffers_to_destroy_count++; free(buffer);
} }
any gpu_create_index_buffer(i32 count) { any gpu_create_index_buffer(i32 count) {
@@ -1163,8 +1141,8 @@ gpu_pipeline_t *gpu_create_pipeline() {
} }
void gpu_delete_pipeline(gpu_pipeline_t *pipeline) { void gpu_delete_pipeline(gpu_pipeline_t *pipeline) {
pipelines_to_destroy[pipelines_to_destroy_count] = pipeline; gpu_pipeline_destroy(pipeline);
pipelines_to_destroy_count++; free(pipeline);
} }
gpu_texture_t *gpu_create_render_target(i32 width, i32 height, i32 format) { gpu_texture_t *gpu_create_render_target(i32 width, i32 height, i32 format) {
@@ -1253,8 +1231,8 @@ gpu_texture_t *iron_load_texture(string_t *file) {
} }
void iron_delete_texture(gpu_texture_t *texture) { void iron_delete_texture(gpu_texture_t *texture) {
textures_to_destroy[textures_to_destroy_count] = texture; gpu_texture_destroy(texture);
textures_to_destroy_count++; free(texture);
} }
#ifdef WITH_AUDIO #ifdef WITH_AUDIO
+34
View File
@@ -3,6 +3,12 @@
static gpu_buffer_t constant_buffer; static gpu_buffer_t constant_buffer;
static bool gpu_thrown = false; static bool gpu_thrown = false;
static gpu_texture_t textures_to_destroy[128];
static gpu_buffer_t buffers_to_destroy[128];
static gpu_pipeline_t pipelines_to_destroy[32];
static int textures_to_destroy_count = 0;
static int buffers_to_destroy_count = 0;
static int pipelines_to_destroy_count = 0;
int constant_buffer_index = 0; int constant_buffer_index = 0;
int draw_calls = 0; int draw_calls = 0;
@@ -91,6 +97,19 @@ void gpu_present() {
gpu_present_internal(); gpu_present_internal();
draw_calls_last = draw_calls; draw_calls_last = draw_calls;
draw_calls = 0; draw_calls = 0;
while (textures_to_destroy_count > 0) {
textures_to_destroy_count--;
gpu_texture_destroy_internal(&textures_to_destroy[textures_to_destroy_count]);
}
while (buffers_to_destroy_count > 0) {
buffers_to_destroy_count--;
gpu_buffer_destroy_internal(&buffers_to_destroy[buffers_to_destroy_count]);
}
while (pipelines_to_destroy_count > 0) {
pipelines_to_destroy_count--;
gpu_pipeline_destroy_internal(&pipelines_to_destroy[pipelines_to_destroy_count]);
}
} }
void gpu_resize(int width, int height) { void gpu_resize(int width, int height) {
@@ -254,6 +273,21 @@ void gpu_create_framebuffers(int depth_buffer_bits) {
} }
} }
void gpu_texture_destroy(gpu_texture_t *texture) {
textures_to_destroy[textures_to_destroy_count] = *texture;
textures_to_destroy_count++;
}
void gpu_pipeline_destroy(gpu_pipeline_t *pipeline) {
pipelines_to_destroy[pipelines_to_destroy_count] = *pipeline;
pipelines_to_destroy_count++;
}
void gpu_buffer_destroy(gpu_buffer_t *buffer) {
buffers_to_destroy[buffers_to_destroy_count] = *buffer;
buffers_to_destroy_count++;
}
int gpu_vertex_data_size(gpu_vertex_data_t data) { int gpu_vertex_data_size(gpu_vertex_data_t data) {
switch (data) { switch (data) {
case GPU_VERTEX_DATA_F32_1X: case GPU_VERTEX_DATA_F32_1X:
+3
View File
@@ -177,6 +177,7 @@ void gpu_set_matrix4(int location, iron_matrix4x4_t value);
void gpu_vertex_structure_add(gpu_vertex_structure_t *structure, const char *name, gpu_vertex_data_t data); void gpu_vertex_structure_add(gpu_vertex_structure_t *structure, const char *name, gpu_vertex_data_t data);
void gpu_texture_init_from_bytes(gpu_texture_t *texture, void *data, int width, int height, gpu_texture_format_t format); void gpu_texture_init_from_bytes(gpu_texture_t *texture, void *data, int width, int height, gpu_texture_format_t format);
void gpu_texture_destroy(gpu_texture_t *texture); void gpu_texture_destroy(gpu_texture_t *texture);
void gpu_texture_destroy_internal(gpu_texture_t *texture);
void gpu_render_target_init(gpu_texture_t *target, int width, int height, gpu_texture_format_t format); void gpu_render_target_init(gpu_texture_t *target, int width, int height, gpu_texture_format_t format);
void gpu_render_target_init2(gpu_texture_t *render_target, int width, int height, gpu_texture_format_t format, int framebuffer_index); void gpu_render_target_init2(gpu_texture_t *render_target, int width, int height, gpu_texture_format_t format, int framebuffer_index);
void gpu_vertex_buffer_init(gpu_buffer_t *buffer, int count, gpu_vertex_structure_t *structure); void gpu_vertex_buffer_init(gpu_buffer_t *buffer, int count, gpu_vertex_structure_t *structure);
@@ -187,11 +188,13 @@ void gpu_constant_buffer_lock(gpu_buffer_t *buffer, int start, int count);
void gpu_constant_buffer_unlock(gpu_buffer_t *buffer); void gpu_constant_buffer_unlock(gpu_buffer_t *buffer);
void gpu_index_buffer_init(gpu_buffer_t *buffer, int count); void gpu_index_buffer_init(gpu_buffer_t *buffer, int count);
void gpu_buffer_destroy(gpu_buffer_t *buffer); void gpu_buffer_destroy(gpu_buffer_t *buffer);
void gpu_buffer_destroy_internal(gpu_buffer_t *buffer);
void *gpu_index_buffer_lock(gpu_buffer_t *buffer); void *gpu_index_buffer_lock(gpu_buffer_t *buffer);
void gpu_index_buffer_unlock(gpu_buffer_t *buffer); void gpu_index_buffer_unlock(gpu_buffer_t *buffer);
void gpu_pipeline_init(gpu_pipeline_t *pipeline); void gpu_pipeline_init(gpu_pipeline_t *pipeline);
void gpu_pipeline_destroy(gpu_pipeline_t *pipeline); void gpu_pipeline_destroy(gpu_pipeline_t *pipeline);
void gpu_pipeline_destroy_internal(gpu_pipeline_t *pipeline);
void gpu_pipeline_compile(gpu_pipeline_t *pipeline); void gpu_pipeline_compile(gpu_pipeline_t *pipeline);
void gpu_shader_init(gpu_shader_t *shader, const void *source, size_t length, gpu_shader_type_t type); void gpu_shader_init(gpu_shader_t *shader, const void *source, size_t length, gpu_shader_type_t type);
void gpu_shader_destroy(gpu_shader_t *shader); void gpu_shader_destroy(gpu_shader_t *shader);
+1 -2
View File
@@ -245,8 +245,7 @@ function render_path_resize() {
for (let i: i32 = 0; i < render_targets_keys.length; ++i) { for (let i: i32 = 0; i < render_targets_keys.length; ++i) {
let rt: render_target_t = map_get(render_path_render_targets, render_targets_keys[i]); let rt: render_target_t = map_get(render_path_render_targets, render_targets_keys[i]);
if (rt != null && rt.width == 0) { if (rt != null && rt.width == 0) {
let _image: gpu_texture_t = rt._image; iron_delete_texture(rt._image);
iron_delete_texture(_image);
rt._image = render_path_create_image(rt); rt._image = render_path_create_image(rt);
} }
} }