luboslenco il y a 1 mois
Parent
commit
c3cf9353d3

+ 7 - 7
base/sources/backends/direct3d12_gpu.c

@@ -152,10 +152,10 @@ void gpu_barrier(gpu_texture_t *render_target, gpu_texture_state_t state_after)
 void gpu_destroy() {
 	gpu_wait();
 	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) {
-		gpu_texture_destroy(&framebuffer_depth);
+		gpu_texture_destroy_internal(&framebuffer_depth);
 	}
 	if (readback_buffer != NULL) {
 		readback_buffer->lpVtbl->Release(readback_buffer);
@@ -448,10 +448,10 @@ void gpu_present_internal() {
 		framebuffer_index = 0;
 
 		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) {
-			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);
@@ -707,7 +707,7 @@ void gpu_use_linear_sampling(bool b) {
 	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) {
 		pipe->impl.pso->lpVtbl->Release(pipe->impl.pso);
 		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(); ////
 }
 
-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) {
 		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;
 }
 
-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 = NULL;
 }

+ 4 - 4
base/sources/backends/metal_gpu.m

@@ -280,7 +280,7 @@ void gpu_present_internal() {
 		CAMetalLayer *layer = get_metal_layer();
 		layer.drawableSize = CGSizeMake(iron_window_width(), iron_window_height());
 		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);
 		}
 		resized = false;
@@ -418,7 +418,7 @@ void gpu_use_linear_sampling(bool 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;
 	pipe = nil;
 	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];
 }
 
-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;
 	tex = nil;
 	target->impl._tex = NULL;
@@ -632,7 +632,7 @@ void gpu_index_buffer_init(gpu_buffer_t *buffer, int indexCount) {
 					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;
 	buf = nil;
 	buffer->impl.metal_buffer = NULL;

+ 25 - 9
base/sources/backends/vulkan_gpu.c

@@ -159,10 +159,10 @@ static VkBool32 vk_debug_utils_messenger_callback_ext(
 	const VkDebugUtilsMessengerCallbackDataEXT *pcallback_data,
 	void *puser_data) {
 	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) {
-		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;
 }
@@ -386,7 +386,7 @@ static void create_descriptors(void) {
 
 VkSwapchainKHR cleanup_swapchain() {
 	// for (int i = 0; i < GPU_FRAMEBUFFER_COUNT; ++i) {
-	// 	gpu_texture_destroy(&framebuffers[i]);
+	// 	gpu_texture_destroy_internal(&framebuffers[i]);
 	// }
 	VkSwapchainKHR chain = window_swapchain;
 	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->state = (framebuffer_index >= 0) ? GPU_TEXTURE_STATE_PRESENT : GPU_TEXTURE_STATE_SHADER_RESOURCE;
 	target->buffer = NULL;
+	target->impl.has_storage_bit = false;
 
 	if (framebuffer_index >= 0) {
 		return;
@@ -627,7 +628,7 @@ static void acquire_next_image() {
 		acquire_next_image();
 
 		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);
 			framebuffers[i].width = iron_window_width();
 			framebuffers[i].height = iron_window_height();
@@ -1298,6 +1299,9 @@ void gpu_disable_scissor() {
 void gpu_set_pipeline(gpu_pipeline_t *pipeline) {
 	current_pipeline = 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) {
@@ -1457,7 +1461,7 @@ void gpu_use_linear_sampling(bool 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);
 	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(); ////
 }
 
-void gpu_texture_destroy(gpu_texture_t *target) {
+void gpu_texture_destroy_internal(gpu_texture_t *target) {
 	if (target->impl.image != NULL) {
 		vkDestroyImage(device, target->impl.image, NULL);
 		vkFreeMemory(device, target->impl.mem, NULL);
@@ -1934,7 +1938,7 @@ void gpu_constant_buffer_unlock(gpu_buffer_t *buffer) {
 	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);
 	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) {
-	if (_output != output) {
-		vkDestroyImage(device, _output->impl.image, NULL);
+	if (!_output->impl.has_storage_bit) {
+		_output->impl.has_storage_bit = true;
+		gpu_texture_destroy(_output);
 
 		VkImageCreateInfo image_info = {
 			.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
@@ -3049,6 +3054,17 @@ void gpu_raytrace_set_target(gpu_texture_t *_output) {
 			.flags = 0,
 		};
 		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);
 
 		VkImageViewCreateInfo image_view_info = {

+ 1 - 0
base/sources/backends/vulkan_gpu.h

@@ -20,6 +20,7 @@ typedef struct {
 	VkImage image;
 	VkDeviceMemory mem;
 	VkImageView view;
+	bool has_storage_bit;
 } gpu_texture_impl_t;
 
 typedef struct {

+ 6 - 28
base/sources/iron.h

@@ -392,12 +392,6 @@ static gpu_raytrace_acceleration_structure_t rt_accel;
 static bool rt_created = false;
 static bool rt_accel_created = false;
 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) {
 	#ifdef IRON_WINDOWS
@@ -435,22 +429,6 @@ void _update(void *data) {
 	iron_a2_update();
 	#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();
 	gpu_present();
 }
@@ -943,8 +921,8 @@ void iron_set_gamepad_button_callback(void (*callback)(int, int, float)) {
 #endif
 
 void gpu_delete_buffer(gpu_buffer_t *buffer) {
-	buffers_to_destroy[buffers_to_destroy_count] = buffer;
-	buffers_to_destroy_count++;
+	gpu_buffer_destroy(buffer);
+	free(buffer);
 }
 
 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) {
-	pipelines_to_destroy[pipelines_to_destroy_count] = pipeline;
-	pipelines_to_destroy_count++;
+	gpu_pipeline_destroy(pipeline);
+	free(pipeline);
 }
 
 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) {
-	textures_to_destroy[textures_to_destroy_count] = texture;
-	textures_to_destroy_count++;
+	gpu_texture_destroy(texture);
+	free(texture);
 }
 
 #ifdef WITH_AUDIO

+ 34 - 0
base/sources/iron_gpu.c

@@ -3,6 +3,12 @@
 
 static gpu_buffer_t constant_buffer;
 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 draw_calls = 0;
@@ -91,6 +97,19 @@ void gpu_present() {
 	gpu_present_internal();
 	draw_calls_last = draw_calls;
 	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) {
@@ -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) {
 	switch (data) {
 	case GPU_VERTEX_DATA_F32_1X:

+ 3 - 0
base/sources/iron_gpu.h

@@ -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_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_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_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);
@@ -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_index_buffer_init(gpu_buffer_t *buffer, int count);
 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_unlock(gpu_buffer_t *buffer);
 
 void gpu_pipeline_init(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_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);

+ 1 - 2
base/sources/ts/iron/render_path.ts

@@ -245,8 +245,7 @@ function render_path_resize() {
 	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]);
 		if (rt != null && rt.width == 0) {
-			let _image: gpu_texture_t = rt._image;
-			iron_delete_texture(_image);
+			iron_delete_texture(rt._image);
 			rt._image = render_path_create_image(rt);
 		}
 	}