From ab725fddd4c3bda70359ab981f4b28b41b328df6 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 12 May 2023 11:58:39 +0200 Subject: [PATCH 01/63] Vulkan: IndexBuffer as Subrange Add support for index buffers as subrange. When an index buffer is a subrange it should bind the source buffer and use the index start as an offset in the buffer. --- source/blender/gpu/vulkan/vk_buffer.hh | 2 ++ .../blender/gpu/vulkan/vk_command_buffer.cc | 6 ++--- .../blender/gpu/vulkan/vk_command_buffer.hh | 3 ++- source/blender/gpu/vulkan/vk_common.hh | 2 ++ source/blender/gpu/vulkan/vk_index_buffer.cc | 24 ++++++++++++++++--- source/blender/gpu/vulkan/vk_index_buffer.hh | 1 + 6 files changed, 31 insertions(+), 7 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_buffer.hh b/source/blender/gpu/vulkan/vk_buffer.hh index 175bc363b7f..d4e20b0a584 100644 --- a/source/blender/gpu/vulkan/vk_buffer.hh +++ b/source/blender/gpu/vulkan/vk_buffer.hh @@ -66,6 +66,8 @@ class VKBuffer { * * VKImmediate mode uses a single VKBuffer with multiple vertex layouts. Those layouts are send to * the command buffer containing an offset. + * + * VKIndexBuffer uses this when it is a subrange of another buffer. */ struct VKBufferWithOffset { VKBuffer &buffer; diff --git a/source/blender/gpu/vulkan/vk_command_buffer.cc b/source/blender/gpu/vulkan/vk_command_buffer.cc index 70f88709362..4ae1f5b2d11 100644 --- a/source/blender/gpu/vulkan/vk_command_buffer.cc +++ b/source/blender/gpu/vulkan/vk_command_buffer.cc @@ -116,12 +116,12 @@ void VKCommandBuffer::bind(const uint32_t binding, vkCmdBindVertexBuffers(vk_command_buffer_, binding, 1, &vk_vertex_buffer, &offset); } -void VKCommandBuffer::bind(const VKIndexBuffer &index_buffer, VkIndexType index_type) +void VKCommandBuffer::bind(const VKBufferWithOffset &index_buffer, VkIndexType index_type) { validate_framebuffer_exists(); ensure_active_framebuffer(); - VkBuffer vk_buffer = index_buffer.vk_handle(); - vkCmdBindIndexBuffer(vk_command_buffer_, vk_buffer, 0, index_type); + vkCmdBindIndexBuffer( + vk_command_buffer_, index_buffer.buffer.vk_handle(), index_buffer.offset, index_type); } void VKCommandBuffer::begin_render_pass(const VKFrameBuffer &framebuffer) diff --git a/source/blender/gpu/vulkan/vk_command_buffer.hh b/source/blender/gpu/vulkan/vk_command_buffer.hh index 84783fa2f5d..04d82190841 100644 --- a/source/blender/gpu/vulkan/vk_command_buffer.hh +++ b/source/blender/gpu/vulkan/vk_command_buffer.hh @@ -144,7 +144,8 @@ class VKCommandBuffer : NonCopyable, NonMovable { /* Bind the given buffer as a vertex buffer. */ void bind(const uint32_t binding, const VKBufferWithOffset &vertex_buffer); void bind(const uint32_t binding, const VkBuffer &vk_vertex_buffer, const VkDeviceSize offset); - void bind(const VKIndexBuffer &index_buffer, VkIndexType index_type); + /* Bind the given buffer as an index buffer. */ + void bind(const VKBufferWithOffset &index_buffer, VkIndexType index_type); void begin_render_pass(const VKFrameBuffer &framebuffer); void end_render_pass(const VKFrameBuffer &framebuffer); diff --git a/source/blender/gpu/vulkan/vk_common.hh b/source/blender/gpu/vulkan/vk_common.hh index 48aaa634cc4..e86b00ee2e2 100644 --- a/source/blender/gpu/vulkan/vk_common.hh +++ b/source/blender/gpu/vulkan/vk_common.hh @@ -97,4 +97,6 @@ template VkObjectType to_vk_object_type(T /*vk_obj*/) return VK_OBJECT_TYPE_UNKNOWN; } +#define NOT_YET_IMPLEMENTED printf("%s not implemented yet\n", __func__); + } // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_index_buffer.cc b/source/blender/gpu/vulkan/vk_index_buffer.cc index 4242b9a7a57..aab3789e208 100644 --- a/source/blender/gpu/vulkan/vk_index_buffer.cc +++ b/source/blender/gpu/vulkan/vk_index_buffer.cc @@ -35,7 +35,7 @@ void VKIndexBuffer::upload_data() void VKIndexBuffer::bind(VKContext &context) { - context.command_buffer_get().bind(*this, to_vk_index_type(index_type_)); + context.command_buffer_get().bind(buffer_with_offset(), to_vk_index_type(index_type_)); } void VKIndexBuffer::bind_as_ssbo(uint binding) @@ -61,9 +61,15 @@ void VKIndexBuffer::read(uint32_t *data) const buffer_.read(data); } -void VKIndexBuffer::update_sub(uint /*start*/, uint /*len*/, const void * /*data*/) {} +void VKIndexBuffer::update_sub(uint /*start*/, uint /*len*/, const void * /*data*/) +{ + NOT_YET_IMPLEMENTED +} -void VKIndexBuffer::strip_restart_indices() {} +void VKIndexBuffer::strip_restart_indices() +{ + NOT_YET_IMPLEMENTED +} void VKIndexBuffer::allocate() { @@ -75,4 +81,16 @@ void VKIndexBuffer::allocate() debug::object_label(buffer_.vk_handle(), "IndexBuffer"); } +VKBufferWithOffset VKIndexBuffer::buffer_with_offset() +{ + VKIndexBuffer *src = unwrap(src_); + VKBufferWithOffset result{is_subrange_ ? src->buffer_ : buffer_, index_start_}; + + BLI_assert_msg(is_subrange_ || result.offset == 0, + "According to design index_start should always be zero when index buffer isn't " + "a subrange"); + + return result; +} + } // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_index_buffer.hh b/source/blender/gpu/vulkan/vk_index_buffer.hh index 00a78337683..36a286ed595 100644 --- a/source/blender/gpu/vulkan/vk_index_buffer.hh +++ b/source/blender/gpu/vulkan/vk_index_buffer.hh @@ -35,6 +35,7 @@ class VKIndexBuffer : public IndexBuf { void strip_restart_indices() override; void allocate(); void ensure_updated(); + VKBufferWithOffset buffer_with_offset(); }; static inline VKIndexBuffer *unwrap(IndexBuf *index_buffer) -- 2.30.2 From 3a4605a52abecc283ae90c1507cbddaecfa4bb88 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 12 May 2023 13:24:30 +0200 Subject: [PATCH 02/63] Vulkan: Disable Depth Bounds Test Depth bounds test was always enabled, but should have be disabled. With this change the outline of the default cube would become visible. --- source/blender/gpu/vulkan/vk_pipeline_state.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_pipeline_state.cc b/source/blender/gpu/vulkan/vk_pipeline_state.cc index e4d78eee17c..89745efda6c 100644 --- a/source/blender/gpu/vulkan/vk_pipeline_state.cc +++ b/source/blender/gpu/vulkan/vk_pipeline_state.cc @@ -234,8 +234,6 @@ void VKPipelineStateManager::set_depth_test(const eGPUDepthTest value) depth_stencil_state.depthTestEnable = VK_FALSE; depth_stencil_state.depthCompareOp = VK_COMPARE_OP_NEVER; } - - depth_stencil_state.depthBoundsTestEnable = VK_TRUE; } void VKPipelineStateManager::set_stencil_test(const eGPUStencilTest test, -- 2.30.2 From 2afb3f11697954ca5bed88e84ae263abd7ea4068 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 12 May 2023 14:42:27 +0200 Subject: [PATCH 03/63] Vulkan: Construct Blending State Per Attachment --- source/blender/gpu/vulkan/vk_framebuffer.cc | 4 +- source/blender/gpu/vulkan/vk_pipeline.cc | 3 +- .../blender/gpu/vulkan/vk_pipeline_state.cc | 51 ++++++++++++++----- .../blender/gpu/vulkan/vk_pipeline_state.hh | 9 ++++ 4 files changed, 51 insertions(+), 16 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_framebuffer.cc b/source/blender/gpu/vulkan/vk_framebuffer.cc index ca0a5ff5da4..5bee9fbaf0f 100644 --- a/source/blender/gpu/vulkan/vk_framebuffer.cc +++ b/source/blender/gpu/vulkan/vk_framebuffer.cc @@ -423,8 +423,8 @@ void VKFrameBuffer::render_pass_create() attachment_description.storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachment_description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachment_description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - attachment_description.initialLayout = VK_IMAGE_LAYOUT_GENERAL; - attachment_description.finalLayout = VK_IMAGE_LAYOUT_GENERAL; + attachment_description.initialLayout = texture.current_layout_get(); + attachment_description.finalLayout = texture.current_layout_get(); /* Create the attachment reference. */ const bool is_depth_attachment = ELEM( diff --git a/source/blender/gpu/vulkan/vk_pipeline.cc b/source/blender/gpu/vulkan/vk_pipeline.cc index 0fcb543ab95..85e0aa40b73 100644 --- a/source/blender/gpu/vulkan/vk_pipeline.cc +++ b/source/blender/gpu/vulkan/vk_pipeline.cc @@ -177,7 +177,8 @@ void VKPipeline::finalize(VKContext &context, pipeline_create_info.pMultisampleState = &multisample_state; /* States from the state manager. */ - const VKPipelineStateManager &state_manager = state_manager_get(); + VKPipelineStateManager &state_manager = state_manager_get(); + state_manager.finalize_color_blend_state(framebuffer); pipeline_create_info.pColorBlendState = &state_manager.pipeline_color_blend_state; pipeline_create_info.pRasterizationState = &state_manager.rasterization_state; pipeline_create_info.pDepthStencilState = &state_manager.depth_stencil_state; diff --git a/source/blender/gpu/vulkan/vk_pipeline_state.cc b/source/blender/gpu/vulkan/vk_pipeline_state.cc index 89745efda6c..fbc79c222ea 100644 --- a/source/blender/gpu/vulkan/vk_pipeline_state.cc +++ b/source/blender/gpu/vulkan/vk_pipeline_state.cc @@ -6,6 +6,8 @@ */ #include "vk_pipeline_state.hh" +#include "vk_framebuffer.hh" +#include "vk_texture.hh" namespace blender::gpu { VKPipelineStateManager::VKPipelineStateManager() @@ -22,12 +24,12 @@ VKPipelineStateManager::VKPipelineStateManager() /* TODO should be extracted from current framebuffer and should not be done here and now. */ /* When the attachments differ the state should be forced. */ - VkPipelineColorBlendAttachmentState color_blend_attachment = {}; - color_blend_attachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | - VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - color_blend_attachments.append(color_blend_attachment); - pipeline_color_blend_state.attachmentCount = color_blend_attachments.size(); - pipeline_color_blend_state.pAttachments = color_blend_attachments.data(); + color_blend_attachment_template = {}; + color_blend_attachment_template.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | + VK_COLOR_COMPONENT_G_BIT | + VK_COLOR_COMPONENT_B_BIT | + VK_COLOR_COMPONENT_A_BIT; + color_blend_attachment_int_template = color_blend_attachment_template; } void VKPipelineStateManager::set_state(const GPUState &state, const GPUStateMutable &mutable_state) @@ -74,10 +76,34 @@ void VKPipelineStateManager::force_state(const GPUState &state, set_state(state, mutable_state); } +void VKPipelineStateManager::finalize_color_blend_state(const VKFrameBuffer &framebuffer) +{ + color_blend_attachments.clear(); + + for (int color_slot = 0; color_slot < GPU_FB_MAX_COLOR_ATTACHMENT; color_slot++) { + VKTexture *texture = unwrap(unwrap(framebuffer.color_tex(color_slot))); + if (texture) { + eGPUTextureFormatFlag format_flag = texture->format_flag_get(); + if (format_flag & GPU_FORMAT_INTEGER) { + color_blend_attachments.append(color_blend_attachment_int_template); + } + else { + color_blend_attachments.append(color_blend_attachment_template); + } + } + else { + color_blend_attachments.append(color_blend_attachment_template); + } + } + + pipeline_color_blend_state.attachmentCount = color_blend_attachments.size(); + pipeline_color_blend_state.pAttachments = color_blend_attachments.data(); +} + void VKPipelineStateManager::set_blend(const eGPUBlend blend) { VkPipelineColorBlendStateCreateInfo &cb = pipeline_color_blend_state; - VkPipelineColorBlendAttachmentState &att_state = color_blend_attachments.last(); + VkPipelineColorBlendAttachmentState &att_state = color_blend_attachment_template; att_state.blendEnable = VK_TRUE; att_state.alphaBlendOp = VK_BLEND_OP_ADD; @@ -186,20 +212,19 @@ void VKPipelineStateManager::set_write_mask(const eGPUWriteMask write_mask) { depth_stencil_state.depthWriteEnable = (write_mask & GPU_WRITE_DEPTH) ? VK_TRUE : VK_FALSE; - VkPipelineColorBlendAttachmentState &att_state = color_blend_attachments.last(); - att_state.colorWriteMask = 0; + color_blend_attachment_template.colorWriteMask = 0; if ((write_mask & GPU_WRITE_RED) != 0) { - att_state.colorWriteMask |= VK_COLOR_COMPONENT_R_BIT; + color_blend_attachment_template.colorWriteMask |= VK_COLOR_COMPONENT_R_BIT; } if ((write_mask & GPU_WRITE_GREEN) != 0) { - att_state.colorWriteMask |= VK_COLOR_COMPONENT_G_BIT; + color_blend_attachment_template.colorWriteMask |= VK_COLOR_COMPONENT_G_BIT; } if ((write_mask & GPU_WRITE_BLUE) != 0) { - att_state.colorWriteMask |= VK_COLOR_COMPONENT_B_BIT; + color_blend_attachment_template.colorWriteMask |= VK_COLOR_COMPONENT_B_BIT; } if ((write_mask & GPU_WRITE_ALPHA) != 0) { - att_state.colorWriteMask |= VK_COLOR_COMPONENT_A_BIT; + color_blend_attachment_template.colorWriteMask |= VK_COLOR_COMPONENT_A_BIT; } } diff --git a/source/blender/gpu/vulkan/vk_pipeline_state.hh b/source/blender/gpu/vulkan/vk_pipeline_state.hh index 06bc5069978..55f8be8a3b4 100644 --- a/source/blender/gpu/vulkan/vk_pipeline_state.hh +++ b/source/blender/gpu/vulkan/vk_pipeline_state.hh @@ -12,14 +12,21 @@ #include "BLI_vector.hh" namespace blender::gpu { +class VKFrameBuffer; class VKPipelineStateManager { + private: GPUState current_; GPUStateMutable current_mutable_; public: VkPipelineColorBlendStateCreateInfo pipeline_color_blend_state; + /* Template of the color blending for color attachments. + * Blending is not supported on Integer based textures. + */ + VkPipelineColorBlendAttachmentState color_blend_attachment_template; + VkPipelineColorBlendAttachmentState color_blend_attachment_int_template; Vector color_blend_attachments; VkPipelineRasterizationStateCreateInfo rasterization_state; VkPipelineDepthStencilStateCreateInfo depth_stencil_state; @@ -29,6 +36,8 @@ class VKPipelineStateManager { void set_state(const GPUState &state, const GPUStateMutable &mutable_state); void force_state(const GPUState &state, const GPUStateMutable &mutable_state); + void finalize_color_blend_state(const VKFrameBuffer &framebuffer); + private: void set_blend(eGPUBlend blend); void set_write_mask(eGPUWriteMask write_mask); -- 2.30.2 From 93f6767c8ff9edc1d4b6087ef13396c3178dea83 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 12 May 2023 15:40:09 +0200 Subject: [PATCH 04/63] Add FLOAT R11 G11 B10 conversion. --- source/blender/gpu/tests/texture_test.cc | 3 +- .../blender/gpu/vulkan/vk_data_conversion.cc | 32 ++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/source/blender/gpu/tests/texture_test.cc b/source/blender/gpu/tests/texture_test.cc index 785f37fbcac..fd3aeb92010 100644 --- a/source/blender/gpu/tests/texture_test.cc +++ b/source/blender/gpu/tests/texture_test.cc @@ -255,12 +255,13 @@ static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB10_A2UI() } GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB10_A2UI); +#endif + static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_R11F_G11F_B10F() { texture_create_upload_read_with_bias(0.0f); } GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_R11F_G11F_B10F); -#endif static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8_A8() { diff --git a/source/blender/gpu/vulkan/vk_data_conversion.cc b/source/blender/gpu/vulkan/vk_data_conversion.cc index e31fd3845ff..627d1c83ec3 100644 --- a/source/blender/gpu/vulkan/vk_data_conversion.cc +++ b/source/blender/gpu/vulkan/vk_data_conversion.cc @@ -55,6 +55,9 @@ enum class ConversionType { FLOAT_TO_DEPTH_COMPONENT24, DEPTH_COMPONENT24_TO_FLOAT, + FLOAT_TO_R11F_G11F_B10F, + R11F_G11F_B10F_TO_FLOAT, + /** * The requested conversion isn't supported. */ @@ -104,6 +107,9 @@ static ConversionType type_of_conversion_float(eGPUTextureFormat device_format) case GPU_DEPTH_COMPONENT24: return ConversionType::FLOAT_TO_DEPTH_COMPONENT24; + case GPU_R11F_G11F_B10F: + return ConversionType::FLOAT_TO_R11F_G11F_B10F; + case GPU_RGB32F: /* GPU_RGB32F Not supported by vendors. */ case GPU_RGBA8UI: case GPU_RGBA8I: @@ -125,7 +131,6 @@ static ConversionType type_of_conversion_float(eGPUTextureFormat device_format) case GPU_R32I: case GPU_RGB10_A2: case GPU_RGB10_A2UI: - case GPU_R11F_G11F_B10F: case GPU_DEPTH32F_STENCIL8: case GPU_DEPTH24_STENCIL8: case GPU_RGB8UI: @@ -526,6 +531,7 @@ static ConversionType reversed(ConversionType type) CASE_PAIR(FLOAT, HALF) CASE_PAIR(FLOAT, SRGBA8) CASE_PAIR(FLOAT, DEPTH_COMPONENT24) + CASE_PAIR(FLOAT, R11F_G11F_B10F) case ConversionType::UNSUPPORTED: return ConversionType::UNSUPPORTED; @@ -560,6 +566,7 @@ using F32 = ComponentValue; using F16 = ComponentValue; using SRGBA8 = PixelValue>; using FLOAT4 = PixelValue>; +class R11F_G11F_B10F : public PixelValue {}; class DepthComponent24 : public ComponentValue { public: @@ -690,6 +697,21 @@ static void convert(FLOAT4 &dst, const SRGBA8 &src) dst.value = src.value.decode(); } +static void convert(FLOAT4 &dst, const R11F_G11F_B10F &src) +{ + dst.value.r = float((src.value >> 21) & 0b11111111111) / (0b11111111111); + dst.value.g = float((src.value >> 10) & 0b11111111111) / float(0b11111111111); + dst.value.b = float((src.value) & 0b1111111111) / float(0b1111111111); + dst.value.a = 1.0f; +} +static void convert(R11F_G11F_B10F &dst, const FLOAT4 &src) +{ + int32_t r = clamp_f(src.value.r, 0.0f, 1.0f) * 0b11111111111; + int32_t g = clamp_f(src.value.g, 0.0f, 1.0f) * 0b11111111111; + int32_t b = clamp_f(src.value.b, 0.0f, 1.0f) * 0b1111111111; + dst.value = r << 21 | g << 10 | b; +} + /* \} */ template @@ -829,6 +851,14 @@ static void convert_buffer(void *dst_memory, convert_per_component>( dst_memory, src_memory, buffer_size, device_format); break; + + case ConversionType::FLOAT_TO_R11F_G11F_B10F: + convert_per_pixel(dst_memory, src_memory, buffer_size); + break; + + case ConversionType::R11F_G11F_B10F_TO_FLOAT: + convert_per_pixel(dst_memory, src_memory, buffer_size); + break; } } -- 2.30.2 From 44548d3edf5af266f926233a4c20584d0ad0c018 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 12 May 2023 15:45:21 +0200 Subject: [PATCH 05/63] Added comment where I left for the weekend --- source/blender/gpu/vulkan/vk_data_conversion.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/gpu/vulkan/vk_data_conversion.cc b/source/blender/gpu/vulkan/vk_data_conversion.cc index 627d1c83ec3..c9218f85ffa 100644 --- a/source/blender/gpu/vulkan/vk_data_conversion.cc +++ b/source/blender/gpu/vulkan/vk_data_conversion.cc @@ -697,6 +697,7 @@ static void convert(FLOAT4 &dst, const SRGBA8 &src) dst.value = src.value.decode(); } +// TODO: These still have to be validated. static void convert(FLOAT4 &dst, const R11F_G11F_B10F &src) { dst.value.r = float((src.value >> 21) & 0b11111111111) / (0b11111111111); @@ -704,6 +705,7 @@ static void convert(FLOAT4 &dst, const R11F_G11F_B10F &src) dst.value.b = float((src.value) & 0b1111111111) / float(0b1111111111); dst.value.a = 1.0f; } + static void convert(R11F_G11F_B10F &dst, const FLOAT4 &src) { int32_t r = clamp_f(src.value.r, 0.0f, 1.0f) * 0b11111111111; -- 2.30.2 From 6511908936b3d3fcceddfde1f8115e4e3b71fe8b Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 15 May 2023 16:19:09 +0200 Subject: [PATCH 06/63] Data conversion custom float formats --- source/blender/gpu/CMakeLists.txt | 1 + source/blender/gpu/tests/texture_test.cc | 2 +- .../blender/gpu/vulkan/vk_data_conversion.cc | 69 ++++++--- .../blender/gpu/vulkan/vk_data_conversion.hh | 137 ++++++++++++++++++ .../gpu/vulkan/vk_data_conversion_test.cc | 13 ++ 5 files changed, 201 insertions(+), 21 deletions(-) create mode 100644 source/blender/gpu/vulkan/vk_data_conversion_test.cc diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 30f7c3b0cfe..85086433ffb 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -863,6 +863,7 @@ if(WITH_GTESTS) if(WITH_VULKAN_BACKEND) list(APPEND TEST_SRC tests/memory_layout_test.cc + vulkan/vk_data_conversion_test.cc ) endif() diff --git a/source/blender/gpu/tests/texture_test.cc b/source/blender/gpu/tests/texture_test.cc index fd3aeb92010..227c69d4c2c 100644 --- a/source/blender/gpu/tests/texture_test.cc +++ b/source/blender/gpu/tests/texture_test.cc @@ -259,7 +259,7 @@ GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB10_A2UI); static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_R11F_G11F_B10F() { - texture_create_upload_read_with_bias(0.0f); + texture_create_upload_read_with_bias(0.0009); } GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_R11F_G11F_B10F); diff --git a/source/blender/gpu/vulkan/vk_data_conversion.cc b/source/blender/gpu/vulkan/vk_data_conversion.cc index c9218f85ffa..c43724a9562 100644 --- a/source/blender/gpu/vulkan/vk_data_conversion.cc +++ b/source/blender/gpu/vulkan/vk_data_conversion.cc @@ -55,8 +55,8 @@ enum class ConversionType { FLOAT_TO_DEPTH_COMPONENT24, DEPTH_COMPONENT24_TO_FLOAT, - FLOAT_TO_R11F_G11F_B10F, - R11F_G11F_B10F_TO_FLOAT, + FLOAT_TO_B10F_G11F_R11F, + B10F_G11F_R11F_TO_FLOAT, /** * The requested conversion isn't supported. @@ -108,7 +108,7 @@ static ConversionType type_of_conversion_float(eGPUTextureFormat device_format) return ConversionType::FLOAT_TO_DEPTH_COMPONENT24; case GPU_R11F_G11F_B10F: - return ConversionType::FLOAT_TO_R11F_G11F_B10F; + return ConversionType::FLOAT_TO_B10F_G11F_R11F; case GPU_RGB32F: /* GPU_RGB32F Not supported by vendors. */ case GPU_RGBA8UI: @@ -531,7 +531,7 @@ static ConversionType reversed(ConversionType type) CASE_PAIR(FLOAT, HALF) CASE_PAIR(FLOAT, SRGBA8) CASE_PAIR(FLOAT, DEPTH_COMPONENT24) - CASE_PAIR(FLOAT, R11F_G11F_B10F) + CASE_PAIR(FLOAT, B10F_G11F_R11F) case ConversionType::UNSUPPORTED: return ConversionType::UNSUPPORTED; @@ -565,8 +565,10 @@ using I32 = ComponentValue; using F32 = ComponentValue; using F16 = ComponentValue; using SRGBA8 = PixelValue>; +using FLOAT3 = PixelValue; using FLOAT4 = PixelValue>; -class R11F_G11F_B10F : public PixelValue {}; +/* NOTE: Vulkan stores R11_G11_B10 in reverse component order. */ +class B10F_G11G_R11F : public PixelValue {}; class DepthComponent24 : public ComponentValue { public: @@ -697,21 +699,48 @@ static void convert(FLOAT4 &dst, const SRGBA8 &src) dst.value = src.value.decode(); } -// TODO: These still have to be validated. -static void convert(FLOAT4 &dst, const R11F_G11F_B10F &src) +constexpr uint32_t MASK_10_BITS = 0b1111111111; +constexpr uint32_t MASK_11_BITS = 0b11111111111; +constexpr uint8_t SHIFT_B = 22; +constexpr uint8_t SHIFT_G = 11; +constexpr uint8_t SHIFT_R = 0; + +static uint32_t float_to_uint32_t(float value) { - dst.value.r = float((src.value >> 21) & 0b11111111111) / (0b11111111111); - dst.value.g = float((src.value >> 10) & 0b11111111111) / float(0b11111111111); - dst.value.b = float((src.value) & 0b1111111111) / float(0b1111111111); - dst.value.a = 1.0f; + union { + float fl; + uint32_t u; + } float_to_bits; + float_to_bits.fl = value; + return float_to_bits.u; } -static void convert(R11F_G11F_B10F &dst, const FLOAT4 &src) +static float uint32_t_to_float(uint32_t value) { - int32_t r = clamp_f(src.value.r, 0.0f, 1.0f) * 0b11111111111; - int32_t g = clamp_f(src.value.g, 0.0f, 1.0f) * 0b11111111111; - int32_t b = clamp_f(src.value.b, 0.0f, 1.0f) * 0b1111111111; - dst.value = r << 21 | g << 10 | b; + union { + float fl; + uint32_t u; + } float_to_bits; + float_to_bits.u = value; + return float_to_bits.fl; +} + +static void convert(FLOAT3 &dst, const B10F_G11G_R11F &src) +{ + dst.value.x = uint32_t_to_float( + convert_float_formats((src.value >> SHIFT_R) && MASK_11_BITS)); + dst.value.y = uint32_t_to_float( + convert_float_formats((src.value >> SHIFT_G) && MASK_11_BITS)); + dst.value.z = uint32_t_to_float( + convert_float_formats((src.value >> SHIFT_B) && MASK_10_BITS)); +} + +static void convert(B10F_G11G_R11F &dst, const FLOAT3 &src) +{ + uint32_t r = convert_float_formats(float_to_uint32_t(src.value.x)); + uint32_t g = convert_float_formats(float_to_uint32_t(src.value.y)); + uint32_t b = convert_float_formats(float_to_uint32_t(src.value.z)); + dst.value = r << SHIFT_R | g << SHIFT_G | b << SHIFT_B; } /* \} */ @@ -854,12 +883,12 @@ static void convert_buffer(void *dst_memory, dst_memory, src_memory, buffer_size, device_format); break; - case ConversionType::FLOAT_TO_R11F_G11F_B10F: - convert_per_pixel(dst_memory, src_memory, buffer_size); + case ConversionType::FLOAT_TO_B10F_G11F_R11F: + convert_per_pixel(dst_memory, src_memory, buffer_size); break; - case ConversionType::R11F_G11F_B10F_TO_FLOAT: - convert_per_pixel(dst_memory, src_memory, buffer_size); + case ConversionType::B10F_G11F_R11F_TO_FLOAT: + convert_per_pixel(dst_memory, src_memory, buffer_size); break; } } diff --git a/source/blender/gpu/vulkan/vk_data_conversion.hh b/source/blender/gpu/vulkan/vk_data_conversion.hh index 1b5405f04c1..cf4db62273b 100644 --- a/source/blender/gpu/vulkan/vk_data_conversion.hh +++ b/source/blender/gpu/vulkan/vk_data_conversion.hh @@ -96,4 +96,141 @@ bool conversion_needed(const GPUVertFormat &vertex_format); */ void convert_in_place(void *data, const GPUVertFormat &vertex_format, const uint vertex_len); +/* -------------------------------------------------------------------- */ +/** \name Floating point conversions + * \{ */ + +template +class FloatingPointFormat { + public: + static constexpr bool HasSign = HasSignBit; + static constexpr uint8_t MantissaLen = MantissaBitLen; + static constexpr uint8_t MantissaShift = 0; + static constexpr uint32_t MantissaMask = (1 << MantissaBitLen) - 1; + static constexpr uint8_t ExponentShift = MantissaBitLen; + static constexpr uint8_t ExponentLen = ExponentBitLen; + static constexpr uint32_t ExponentMask = (1 << ExponentBitLen) - 1; + static constexpr uint8_t SignShift = MantissaBitLen + ExponentBitLen; + static constexpr uint32_t SignMask = HasSignBit ? 1 : 0; + static constexpr uint32_t ExponentBias = (1 << (ExponentBitLen - 1)) - 1; + + uint32_t get_mantissa(uint32_t floating_point_number) + { + return (floating_point_number >> MantissaShift) & MantissaMask; + } + uint32_t clear_mantissa(uint32_t floating_point_number) + { + return floating_point_number & ~(MantissaMask << MantissaShift); + } + uint32_t set_mantissa(uint32_t mantissa, uint32_t floating_point_number) + { + uint32_t result = clear_mantissa(floating_point_number); + result |= mantissa << MantissaShift; + return result; + } + + uint32_t get_exponent(uint32_t floating_point_number) + { + return ((floating_point_number >> ExponentShift) & ExponentMask); + } + uint32_t clear_exponent(uint32_t floating_point_number) + { + return floating_point_number & ~(ExponentMask << ExponentShift); + } + uint32_t set_exponent(uint32_t exponent, uint32_t floating_point_number) + { + uint32_t result = clear_exponent(floating_point_number); + result |= (exponent) << ExponentShift; + return result; + } + + bool is_signed(uint32_t floating_point_number) + { + if constexpr (HasSignBit) { + return (floating_point_number >> SignShift) & SignMask; + } + return false; + } + uint32_t clear_sign(uint32_t floating_point_number) + { + return floating_point_number & ~(1 << SignShift); + } + + uint32_t set_sign(bool sign, uint32_t floating_point_number) + { + if constexpr (HasSignBit) { + return floating_point_number; + } + uint32_t result = clear_sign(floating_point_number); + result |= uint32_t(sign) << SignShift; + return result; + } +}; + +using Format32F = FloatingPointFormat; +using Format16F = FloatingPointFormat; +using Format11F = FloatingPointFormat; +using Format10F = FloatingPointFormat; + +template +uint32_t convert_float_formats(uint32_t value) +{ + SourceFormat src_format; + DestinationFormat dst_format; + /* + printf("Source MS:%d MM:%x ES:%d EM:%x EB:%x\n", + SourceFormat::MantissaShift, + SourceFormat::MantissaMask, + SourceFormat::ExponentShift, + SourceFormat::ExponentMask, + SourceFormat::ExponentBias); + printf("Destination MS:%d MM:%x ES:%d EM:%x EB:%x\n", + DestinationFormat::MantissaShift, + DestinationFormat::MantissaMask, + DestinationFormat::ExponentShift, + DestinationFormat::ExponentMask, + DestinationFormat::ExponentBias); + */ + + bool is_signed = src_format.is_signed(value); + uint32_t mantissa = src_format.get_mantissa(value); + int32_t exponent = src_format.get_exponent(value); + printf("src:%x S:%d, M:%x E:%x\n", value, is_signed, mantissa, exponent); + /* Sign conversion */ + if (is_signed && !DestinationFormat::HasSign) { + // NOTE: we clamp to zero. + return 0; + } + + /* Mantissa conversion */ + if constexpr (SourceFormat::MantissaLen > DestinationFormat::MantissaLen) { + mantissa = mantissa >> (SourceFormat::MantissaLen - DestinationFormat::MantissaLen); + } + else if constexpr (SourceFormat::MantissaLen < DestinationFormat::MantissaLen) { + mantissa = mantissa << (DestinationFormat::MantissaLen - SourceFormat::MantissaLen); + } + + /* Exponent conversion */ + const bool is_denormalized = exponent == 0; + if (!is_denormalized) { + exponent -= SourceFormat::ExponentBias; + if constexpr (SourceFormat::ExponentLen > DestinationFormat::ExponentLen) { + exponent = exponent >> (SourceFormat::ExponentLen - DestinationFormat::ExponentLen); + } + else if constexpr (SourceFormat::ExponentLen < DestinationFormat::ExponentLen) { + exponent = exponent << (DestinationFormat::ExponentLen - SourceFormat::ExponentLen); + } + exponent += DestinationFormat::ExponentBias; + } + + uint32_t result = 0; + result = dst_format.set_sign(is_signed, result); + result = dst_format.set_exponent(exponent, result); + result = dst_format.set_mantissa(mantissa, result); + printf("dst:%x S:%d, M:%x E:%x\n", result, is_signed, mantissa, exponent); + return result; +} + +/* \} */ + }; // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_data_conversion_test.cc b/source/blender/gpu/vulkan/vk_data_conversion_test.cc new file mode 100644 index 00000000000..e619f630644 --- /dev/null +++ b/source/blender/gpu/vulkan/vk_data_conversion_test.cc @@ -0,0 +1,13 @@ +#include "testing/testing.h" + +#include "vk_data_conversion.hh" + +namespace blender::gpu::tests { +TEST(VulkanDataConversion, ConvertF32F16) +{ + uint32_t f32_2 = 0b01000000000000000000000000000000; + uint32_t f16_2_expected = 0b0100000000000000; + uint32_t f16_2 = convert_float_formats(f32_2); + EXPECT_EQ(f16_2, f16_2_expected); +} +} // namespace blender::gpu::tests \ No newline at end of file -- 2.30.2 From fbd53f81d44b833fb5cfe5150c8b3383efd0f184 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 15 May 2023 21:10:44 +0200 Subject: [PATCH 07/63] Added other known numbers. --- source/blender/gpu/vulkan/vk_data_conversion.hh | 2 ++ source/blender/gpu/vulkan/vk_data_conversion_test.cc | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/source/blender/gpu/vulkan/vk_data_conversion.hh b/source/blender/gpu/vulkan/vk_data_conversion.hh index cf4db62273b..bf51f5c09c8 100644 --- a/source/blender/gpu/vulkan/vk_data_conversion.hh +++ b/source/blender/gpu/vulkan/vk_data_conversion.hh @@ -214,12 +214,14 @@ uint32_t convert_float_formats(uint32_t value) const bool is_denormalized = exponent == 0; if (!is_denormalized) { exponent -= SourceFormat::ExponentBias; + /* if constexpr (SourceFormat::ExponentLen > DestinationFormat::ExponentLen) { exponent = exponent >> (SourceFormat::ExponentLen - DestinationFormat::ExponentLen); } else if constexpr (SourceFormat::ExponentLen < DestinationFormat::ExponentLen) { exponent = exponent << (DestinationFormat::ExponentLen - SourceFormat::ExponentLen); } + */ exponent += DestinationFormat::ExponentBias; } diff --git a/source/blender/gpu/vulkan/vk_data_conversion_test.cc b/source/blender/gpu/vulkan/vk_data_conversion_test.cc index e619f630644..73f6abe9af0 100644 --- a/source/blender/gpu/vulkan/vk_data_conversion_test.cc +++ b/source/blender/gpu/vulkan/vk_data_conversion_test.cc @@ -9,5 +9,15 @@ TEST(VulkanDataConversion, ConvertF32F16) uint32_t f16_2_expected = 0b0100000000000000; uint32_t f16_2 = convert_float_formats(f32_2); EXPECT_EQ(f16_2, f16_2_expected); + + uint32_t f32_3 = 0b01000000010000000000000000000000; + uint32_t f16_3_expected = 0b0100001000000000; + uint32_t f16_3 = convert_float_formats(f32_2); + EXPECT_EQ(f16_3, f16_3_expected); + + uint32_t f32_4 = 0b01000000100000000000000000000000; + uint32_t f16_4_expected = 0b0100010000000000; + uint32_t f16_4 = convert_float_formats(f32_2); + EXPECT_EQ(f16_4, f16_4_expected); } } // namespace blender::gpu::tests \ No newline at end of file -- 2.30.2 From 01135a85164099dd31ac22206f03bd4384b3f915 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 15 May 2023 21:13:21 +0200 Subject: [PATCH 08/63] Use correct parameters --- source/blender/gpu/vulkan/vk_data_conversion_test.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_data_conversion_test.cc b/source/blender/gpu/vulkan/vk_data_conversion_test.cc index 73f6abe9af0..569bf276325 100644 --- a/source/blender/gpu/vulkan/vk_data_conversion_test.cc +++ b/source/blender/gpu/vulkan/vk_data_conversion_test.cc @@ -12,12 +12,12 @@ TEST(VulkanDataConversion, ConvertF32F16) uint32_t f32_3 = 0b01000000010000000000000000000000; uint32_t f16_3_expected = 0b0100001000000000; - uint32_t f16_3 = convert_float_formats(f32_2); + uint32_t f16_3 = convert_float_formats(f32_3); EXPECT_EQ(f16_3, f16_3_expected); uint32_t f32_4 = 0b01000000100000000000000000000000; uint32_t f16_4_expected = 0b0100010000000000; - uint32_t f16_4 = convert_float_formats(f32_2); + uint32_t f16_4 = convert_float_formats(f32_4); EXPECT_EQ(f16_4, f16_4_expected); } } // namespace blender::gpu::tests \ No newline at end of file -- 2.30.2 From 0013103790a72063d9445ea920ecce38753d9220 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 16 May 2023 09:38:26 +0200 Subject: [PATCH 09/63] Float conversions. --- .../blender/gpu/vulkan/vk_data_conversion.cc | 58 +++++---- .../blender/gpu/vulkan/vk_data_conversion.hh | 114 +++++++++--------- .../gpu/vulkan/vk_data_conversion_test.cc | 9 +- 3 files changed, 93 insertions(+), 88 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_data_conversion.cc b/source/blender/gpu/vulkan/vk_data_conversion.cc index c43724a9562..c24ce2ff42d 100644 --- a/source/blender/gpu/vulkan/vk_data_conversion.cc +++ b/source/blender/gpu/vulkan/vk_data_conversion.cc @@ -9,8 +9,6 @@ #include "BLI_color.hh" -#include "Imath/half.h" - namespace blender::gpu { /* -------------------------------------------------------------------- */ @@ -549,6 +547,26 @@ static ConversionType reversed(ConversionType type) /** \name Data Conversion * \{ */ +static uint32_t float_to_uint32_t(float value) +{ + union { + float fl; + uint32_t u; + } float_to_bits; + float_to_bits.fl = value; + return float_to_bits.u; +} + +static float uint32_t_to_float(uint32_t value) +{ + union { + float fl; + uint32_t u; + } float_to_bits; + float_to_bits.u = value; + return float_to_bits.fl; +} + template struct ComponentValue { InnerType value; }; @@ -681,12 +699,12 @@ void convert(DestinationType &dst, const SourceType &src) static void convert(F16 &dst, const F32 &src) { - dst.value = imath_float_to_half(src.value); + dst.value = convert_float_formats(float_to_uint32_t(src.value)); } static void convert(F32 &dst, const F16 &src) { - dst.value = imath_half_to_float(src.value); + dst.value = uint32_t_to_float(convert_float_formats(src.value)); } static void convert(SRGBA8 &dst, const FLOAT4 &src) @@ -705,41 +723,21 @@ constexpr uint8_t SHIFT_B = 22; constexpr uint8_t SHIFT_G = 11; constexpr uint8_t SHIFT_R = 0; -static uint32_t float_to_uint32_t(float value) -{ - union { - float fl; - uint32_t u; - } float_to_bits; - float_to_bits.fl = value; - return float_to_bits.u; -} - -static float uint32_t_to_float(uint32_t value) -{ - union { - float fl; - uint32_t u; - } float_to_bits; - float_to_bits.u = value; - return float_to_bits.fl; -} - static void convert(FLOAT3 &dst, const B10F_G11G_R11F &src) { dst.value.x = uint32_t_to_float( - convert_float_formats((src.value >> SHIFT_R) && MASK_11_BITS)); + convert_float_formats((src.value >> SHIFT_R) && MASK_11_BITS)); dst.value.y = uint32_t_to_float( - convert_float_formats((src.value >> SHIFT_G) && MASK_11_BITS)); + convert_float_formats((src.value >> SHIFT_G) && MASK_11_BITS)); dst.value.z = uint32_t_to_float( - convert_float_formats((src.value >> SHIFT_B) && MASK_10_BITS)); + convert_float_formats((src.value >> SHIFT_B) && MASK_10_BITS)); } static void convert(B10F_G11G_R11F &dst, const FLOAT3 &src) { - uint32_t r = convert_float_formats(float_to_uint32_t(src.value.x)); - uint32_t g = convert_float_formats(float_to_uint32_t(src.value.y)); - uint32_t b = convert_float_formats(float_to_uint32_t(src.value.z)); + uint32_t r = convert_float_formats(float_to_uint32_t(src.value.x)); + uint32_t g = convert_float_formats(float_to_uint32_t(src.value.y)); + uint32_t b = convert_float_formats(float_to_uint32_t(src.value.z)); dst.value = r << SHIFT_R | g << SHIFT_G | b << SHIFT_B; } diff --git a/source/blender/gpu/vulkan/vk_data_conversion.hh b/source/blender/gpu/vulkan/vk_data_conversion.hh index bf51f5c09c8..f1f9ac6b7e2 100644 --- a/source/blender/gpu/vulkan/vk_data_conversion.hh +++ b/source/blender/gpu/vulkan/vk_data_conversion.hh @@ -100,6 +100,9 @@ void convert_in_place(void *data, const GPUVertFormat &vertex_format, const uint /** \name Floating point conversions * \{ */ +/** + * Description of a IEEE 754-1985 standard floating point data type. + */ template class FloatingPointFormat { public: @@ -114,49 +117,49 @@ class FloatingPointFormat { static constexpr uint32_t SignMask = HasSignBit ? 1 : 0; static constexpr uint32_t ExponentBias = (1 << (ExponentBitLen - 1)) - 1; - uint32_t get_mantissa(uint32_t floating_point_number) + static uint32_t get_mantissa(uint32_t floating_point_number) { return (floating_point_number >> MantissaShift) & MantissaMask; } - uint32_t clear_mantissa(uint32_t floating_point_number) + static uint32_t clear_mantissa(uint32_t floating_point_number) { return floating_point_number & ~(MantissaMask << MantissaShift); } - uint32_t set_mantissa(uint32_t mantissa, uint32_t floating_point_number) + static uint32_t set_mantissa(uint32_t mantissa, uint32_t floating_point_number) { uint32_t result = clear_mantissa(floating_point_number); result |= mantissa << MantissaShift; return result; } - uint32_t get_exponent(uint32_t floating_point_number) + static uint32_t get_exponent(uint32_t floating_point_number) { return ((floating_point_number >> ExponentShift) & ExponentMask); } - uint32_t clear_exponent(uint32_t floating_point_number) + static uint32_t clear_exponent(uint32_t floating_point_number) { return floating_point_number & ~(ExponentMask << ExponentShift); } - uint32_t set_exponent(uint32_t exponent, uint32_t floating_point_number) + static uint32_t set_exponent(uint32_t exponent, uint32_t floating_point_number) { uint32_t result = clear_exponent(floating_point_number); result |= (exponent) << ExponentShift; return result; } - bool is_signed(uint32_t floating_point_number) + static bool is_signed(uint32_t floating_point_number) { if constexpr (HasSignBit) { return (floating_point_number >> SignShift) & SignMask; } return false; } - uint32_t clear_sign(uint32_t floating_point_number) + static uint32_t clear_sign(uint32_t floating_point_number) { return floating_point_number & ~(1 << SignShift); } - uint32_t set_sign(bool sign, uint32_t floating_point_number) + static uint32_t set_sign(bool sign, uint32_t floating_point_number) { if constexpr (HasSignBit) { return floating_point_number; @@ -167,39 +170,52 @@ class FloatingPointFormat { } }; -using Format32F = FloatingPointFormat; -using Format16F = FloatingPointFormat; -using Format11F = FloatingPointFormat; -using Format10F = FloatingPointFormat; +using FormatF32 = FloatingPointFormat; +using FormatF16 = FloatingPointFormat; +using FormatF11 = FloatingPointFormat; +using FormatF10 = FloatingPointFormat; -template +/** + * Convert between low precision floating (including 32 bit floats). + * + * The input and output values are bits (uint32_t) as this function does a bit-wise operations to + * convert between the formats. Additional conversion rules can be applied to the conversion + * function. Due to the implementation the compiler would make an optimized version depending on + * the actual possibilities. + * + * NOTE: Implementation should be extended to support Nan, Inf, -Inf and clamping to min/max when + * values don't fit in the destination. + */ +template< + /** + * FloatingPointFormat of the the value that is converted to. + */ + typename DestinationFormat, + + /** + * FloatingPointFormat of the the value that is converted from. + */ + typename SourceFormat, + + /** + * Should negative values be clamped to zero when DestinationFormat doesn't contain a sign + * bit. + * + * When set to `false` and DestinationFormat doesn't contain a sign bit the value will be + * made absolute. + */ + bool ClampNegativeToZero = true> uint32_t convert_float_formats(uint32_t value) { - SourceFormat src_format; - DestinationFormat dst_format; - /* - printf("Source MS:%d MM:%x ES:%d EM:%x EB:%x\n", - SourceFormat::MantissaShift, - SourceFormat::MantissaMask, - SourceFormat::ExponentShift, - SourceFormat::ExponentMask, - SourceFormat::ExponentBias); - printf("Destination MS:%d MM:%x ES:%d EM:%x EB:%x\n", - DestinationFormat::MantissaShift, - DestinationFormat::MantissaMask, - DestinationFormat::ExponentShift, - DestinationFormat::ExponentMask, - DestinationFormat::ExponentBias); - */ + bool is_signed = SourceFormat::is_signed(value); + uint32_t mantissa = SourceFormat::get_mantissa(value); + int32_t exponent = SourceFormat::get_exponent(value); - bool is_signed = src_format.is_signed(value); - uint32_t mantissa = src_format.get_mantissa(value); - int32_t exponent = src_format.get_exponent(value); - printf("src:%x S:%d, M:%x E:%x\n", value, is_signed, mantissa, exponent); /* Sign conversion */ - if (is_signed && !DestinationFormat::HasSign) { - // NOTE: we clamp to zero. - return 0; + if constexpr (!DestinationFormat::HasSign && ClampNegativeToZero) { + if (is_signed) { + return 0; + } } /* Mantissa conversion */ @@ -211,28 +227,16 @@ uint32_t convert_float_formats(uint32_t value) } /* Exponent conversion */ - const bool is_denormalized = exponent == 0; - if (!is_denormalized) { - exponent -= SourceFormat::ExponentBias; - /* - if constexpr (SourceFormat::ExponentLen > DestinationFormat::ExponentLen) { - exponent = exponent >> (SourceFormat::ExponentLen - DestinationFormat::ExponentLen); - } - else if constexpr (SourceFormat::ExponentLen < DestinationFormat::ExponentLen) { - exponent = exponent << (DestinationFormat::ExponentLen - SourceFormat::ExponentLen); - } - */ - exponent += DestinationFormat::ExponentBias; - } + exponent += DestinationFormat::ExponentBias - SourceFormat::ExponentBias; + // TODO: Clamp to min/max value? only when Destination::ExponentBias < + // SourceFormat::ExponentBias. uint32_t result = 0; - result = dst_format.set_sign(is_signed, result); - result = dst_format.set_exponent(exponent, result); - result = dst_format.set_mantissa(mantissa, result); - printf("dst:%x S:%d, M:%x E:%x\n", result, is_signed, mantissa, exponent); + result = DestinationFormat::set_sign(is_signed, result); + result = DestinationFormat::set_exponent(exponent, result); + result = DestinationFormat::set_mantissa(mantissa, result); return result; } /* \} */ - }; // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_data_conversion_test.cc b/source/blender/gpu/vulkan/vk_data_conversion_test.cc index 569bf276325..fe34124dcc4 100644 --- a/source/blender/gpu/vulkan/vk_data_conversion_test.cc +++ b/source/blender/gpu/vulkan/vk_data_conversion_test.cc @@ -7,17 +7,20 @@ TEST(VulkanDataConversion, ConvertF32F16) { uint32_t f32_2 = 0b01000000000000000000000000000000; uint32_t f16_2_expected = 0b0100000000000000; - uint32_t f16_2 = convert_float_formats(f32_2); + uint32_t f16_2 = convert_float_formats(f32_2); EXPECT_EQ(f16_2, f16_2_expected); uint32_t f32_3 = 0b01000000010000000000000000000000; uint32_t f16_3_expected = 0b0100001000000000; - uint32_t f16_3 = convert_float_formats(f32_3); + uint32_t f16_3 = convert_float_formats(f32_3); EXPECT_EQ(f16_3, f16_3_expected); uint32_t f32_4 = 0b01000000100000000000000000000000; uint32_t f16_4_expected = 0b0100010000000000; - uint32_t f16_4 = convert_float_formats(f32_4); + uint32_t f16_4 = convert_float_formats(f32_4); EXPECT_EQ(f16_4, f16_4_expected); } + +// TODO: add test case for Nan, Inf, -Inf, Clamping + } // namespace blender::gpu::tests \ No newline at end of file -- 2.30.2 From 4b39e6b25821e850a599014ce52340520e55ea9c Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 16 May 2023 09:38:43 +0200 Subject: [PATCH 10/63] GHOST: Select compatible surface --- intern/ghost/intern/GHOST_ContextVK.cc | 70 +++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 8 deletions(-) diff --git a/intern/ghost/intern/GHOST_ContextVK.cc b/intern/ghost/intern/GHOST_ContextVK.cc index 77ab7f93bec..b0009b0b322 100644 --- a/intern/ghost/intern/GHOST_ContextVK.cc +++ b/intern/ghost/intern/GHOST_ContextVK.cc @@ -30,7 +30,17 @@ /* Set to 0 to allow devices that do not have the required features. * This allows development on OSX until we really needs these features. */ -#define STRICT_REQUIREMENTS 1 +#define STRICT_REQUIREMENTS true + +/* + * Should we only select surfaces that are known to be compatible. Or should we in case no + * compatible surfaces have been found select the first one. + * + * Currently we also select incompatible surfaces as Vulkan is still experimental. Assuming we get + * reports of color differences between OpenGL and Vulkan to narrow down if there are other + * configurations we need to support. + */ +#define SELECT_COMPATIBLE_SURFACES false using namespace std; @@ -796,6 +806,49 @@ GHOST_TSuccess GHOST_ContextVK::createGraphicsCommandBuffers() return GHOST_kSuccess; } +static bool surfaceFormatSupported(const VkSurfaceFormatKHR &surface_format) +{ + if (surface_format.colorSpace != VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) { + return false; + } + + if (surface_format.format == VK_FORMAT_R8G8B8A8_UNORM || + surface_format.format == VK_FORMAT_B8G8R8A8_UNORM) + { + return true; + } + + return false; +} + +/** + * Select the surface format that we will use. + * + * We will select any 8bit unorm surface. + */ +static bool selectSurfaceFormat(const VkPhysicalDevice physical_device, + const VkSurfaceKHR surface, + VkSurfaceFormatKHR &r_surfaceFormat) +{ + uint32_t format_count; + vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &format_count, NULL); + vector formats(format_count); + vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &format_count, formats.data()); + + for (VkSurfaceFormatKHR &format : formats) { + if (surfaceFormatSupported(format)) { + r_surfaceFormat = format; + return true; + } + } + +#if !SELECT_COMPATIBLE_SURFACES + r_surfaceFormat = formats[0]; +#endif + + return false; +} + GHOST_TSuccess GHOST_ContextVK::createSwapchain() { assert(vulkan_device.has_value() && vulkan_device->device != VK_NULL_HANDLE); @@ -803,13 +856,14 @@ GHOST_TSuccess GHOST_ContextVK::createSwapchain() VkPhysicalDevice physical_device = vulkan_device->physical_device; - uint32_t format_count; - vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, m_surface, &format_count, NULL); - vector formats(format_count); - vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, m_surface, &format_count, formats.data()); - - /* TODO choose appropriate format. */ - VkSurfaceFormatKHR format = formats[0]; + VkSurfaceFormatKHR format = {}; +#if SELECT_COMPATIBLE_SURFACES + if (!selectSurfaceFormat(physical_device, m_surface, format)) { + return GHOST_kFailure; + } +#else + selectSurfaceFormat(physical_device, m_surface, format); +#endif VkPresentModeKHR present_mode; if (!selectPresentMode(physical_device, m_surface, &present_mode)) { -- 2.30.2 From bae7f296c9b827c0eb484ed0e2e2cafcf7eb247c Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 16 May 2023 09:49:50 +0200 Subject: [PATCH 11/63] Remove dependency to IMath --- CMakeLists.txt | 3 +-- source/blender/gpu/CMakeLists.txt | 7 ------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 312a073288f..5545c3381b9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -900,10 +900,9 @@ set_and_warn_dependency(WITH_TBB WITH_MOD_FLUID OFF) # NanoVDB requires OpenVDB to convert the data structure set_and_warn_dependency(WITH_OPENVDB WITH_NANOVDB OFF) -# OpenVDB, Alembic and Vulkan, OSL uses 'half' or 'imath' from OpenEXR +# OpenVDB, Alembic, OSL uses 'half' or 'imath' from OpenEXR set_and_warn_dependency(WITH_IMAGE_OPENEXR WITH_OPENVDB OFF) set_and_warn_dependency(WITH_IMAGE_OPENEXR WITH_ALEMBIC OFF) -set_and_warn_dependency(WITH_IMAGE_OPENEXR WITH_VULKAN_BACKEND OFF) set_and_warn_dependency(WITH_IMAGE_OPENEXR WITH_CYCLES_OSL OFF) # auto enable openimageio for cycles diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 85086433ffb..54f3a8bf6a4 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -52,7 +52,6 @@ endif() set(INC_SYS ${Epoxy_INCLUDE_DIRS} - ${IMATH_INCLUDE_DIR} ) set(SRC @@ -354,11 +353,6 @@ if(WITH_VULKAN_BACKEND) ) add_definitions(-DWITH_VULKAN_BACKEND) - if(WIN32) - if(EXISTS ${LIBDIR}/imath/bin/imath.dll) - add_definitions(-DIMATH_DLL) - endif() - endif() endif() if(WITH_VULKAN_GUARDEDALLOC) @@ -817,7 +811,6 @@ if(WITH_GPU_BUILDTIME_SHADER_BUILDER) bf_blenlib bf_intern_ghost ${PLATFORM_LINKLIBS} - ${IMATH_LIBRARIES} ) target_include_directories(shader_builder PRIVATE ${INC} ${CMAKE_CURRENT_BINARY_DIR}) -- 2.30.2 From 4631fd788b897ba6bbd8a04e560005c82d349a74 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 16 May 2023 10:29:18 +0200 Subject: [PATCH 12/63] Use correct length for color blend attachments. --- source/blender/gpu/vulkan/vk_framebuffer.hh | 9 +++++ .../blender/gpu/vulkan/vk_pipeline_state.cc | 36 ++++++++++++------- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_framebuffer.hh b/source/blender/gpu/vulkan/vk_framebuffer.hh index e8fcbce657c..eb989a45d5d 100644 --- a/source/blender/gpu/vulkan/vk_framebuffer.hh +++ b/source/blender/gpu/vulkan/vk_framebuffer.hh @@ -111,6 +111,15 @@ class VKFrameBuffer : public FrameBuffer { return vk_image_; } + /** + * Framebuffers that are owned by GHOST are immutable and don't have any attachments assigned. It + * should be assumed that there is a single color texture in slot 0. + */ + bool is_immutable() const + { + return immutable_; + } + private: void update_attachments(); void render_pass_free(); diff --git a/source/blender/gpu/vulkan/vk_pipeline_state.cc b/source/blender/gpu/vulkan/vk_pipeline_state.cc index fbc79c222ea..01902cf905e 100644 --- a/source/blender/gpu/vulkan/vk_pipeline_state.cc +++ b/source/blender/gpu/vulkan/vk_pipeline_state.cc @@ -22,8 +22,6 @@ VKPipelineStateManager::VKPipelineStateManager() depth_stencil_state = {}; depth_stencil_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; - /* TODO should be extracted from current framebuffer and should not be done here and now. */ - /* When the attachments differ the state should be forced. */ color_blend_attachment_template = {}; color_blend_attachment_template.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | @@ -79,21 +77,35 @@ void VKPipelineStateManager::force_state(const GPUState &state, void VKPipelineStateManager::finalize_color_blend_state(const VKFrameBuffer &framebuffer) { color_blend_attachments.clear(); + if (framebuffer.is_immutable()) { + /* Immutable framebuffers are owned by GHOST and don't have any attachments assigned. In this + * case we assume that there is a single color texture assigned. + */ + color_blend_attachments.append(color_blend_attachment_template); + } + else { - for (int color_slot = 0; color_slot < GPU_FB_MAX_COLOR_ATTACHMENT; color_slot++) { - VKTexture *texture = unwrap(unwrap(framebuffer.color_tex(color_slot))); - if (texture) { - eGPUTextureFormatFlag format_flag = texture->format_flag_get(); - if (format_flag & GPU_FORMAT_INTEGER) { - color_blend_attachments.append(color_blend_attachment_int_template); + bool is_sequential = true; + for (int color_slot = 0; color_slot < GPU_FB_MAX_COLOR_ATTACHMENT; color_slot++) { + VKTexture *texture = unwrap(unwrap(framebuffer.color_tex(color_slot))); + if (texture) { + BLI_assert(is_sequential); + eGPUTextureFormatFlag format_flag = texture->format_flag_get(); + if (format_flag & GPU_FORMAT_INTEGER) { + color_blend_attachments.append(color_blend_attachment_int_template); + } + else { + color_blend_attachments.append(color_blend_attachment_template); + } } else { - color_blend_attachments.append(color_blend_attachment_template); + /* Test to detect if all color textures are sequential attached from the first slot. We + * assume at this moment that this is the case. Otherwise we need to rewire how attachments + * and bindings work.*/ + is_sequential = false; } } - else { - color_blend_attachments.append(color_blend_attachment_template); - } + UNUSED_VARS_NDEBUG(is_sequential); } pipeline_color_blend_state.attachmentCount = color_blend_attachments.size(); -- 2.30.2 From 2b1cf45a8a0bbd5421881782b467e7b1984baaa7 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 16 May 2023 11:41:55 +0200 Subject: [PATCH 13/63] Readback subarea of texture --- source/blender/gpu/tests/texture_test.cc | 12 ++-- source/blender/gpu/vulkan/vk_buffer.cc | 2 + source/blender/gpu/vulkan/vk_common.hh | 3 +- .../blender/gpu/vulkan/vk_data_conversion.cc | 5 +- source/blender/gpu/vulkan/vk_framebuffer.cc | 29 +++------- source/blender/gpu/vulkan/vk_texture.cc | 55 ++++++++++++++----- source/blender/gpu/vulkan/vk_texture.hh | 1 + 7 files changed, 63 insertions(+), 44 deletions(-) diff --git a/source/blender/gpu/tests/texture_test.cc b/source/blender/gpu/tests/texture_test.cc index 227c69d4c2c..91f41b97ee3 100644 --- a/source/blender/gpu/tests/texture_test.cc +++ b/source/blender/gpu/tests/texture_test.cc @@ -624,6 +624,12 @@ static void test_texture_roundtrip__GPU_DATA_UINT__GPU_RGB32UI() GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RGB32UI); #endif +static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT24() +{ + texture_create_upload_read(); +} +GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT24); + #if RUN_COMPONENT_UNIMPLEMENTED static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT32F() { @@ -631,12 +637,6 @@ static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT32F() } GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT32F); -static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT24() -{ - texture_create_upload_read(); -} -GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT24); - static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT16() { texture_create_upload_read(); diff --git a/source/blender/gpu/vulkan/vk_buffer.cc b/source/blender/gpu/vulkan/vk_buffer.cc index 2bc2fb017b8..b7e1fe6563c 100644 --- a/source/blender/gpu/vulkan/vk_buffer.cc +++ b/source/blender/gpu/vulkan/vk_buffer.cc @@ -46,6 +46,8 @@ bool VKBuffer::create(int64_t size_in_bytes, VkBufferUsageFlagBits buffer_usage) { BLI_assert(!is_allocated()); + BLI_assert(vk_buffer_ == VK_NULL_HANDLE); + BLI_assert(mapped_memory_ == nullptr); size_in_bytes_ = size_in_bytes; const VKDevice &device = VKBackend::get().device_get(); diff --git a/source/blender/gpu/vulkan/vk_common.hh b/source/blender/gpu/vulkan/vk_common.hh index e86b00ee2e2..fa01f406ef3 100644 --- a/source/blender/gpu/vulkan/vk_common.hh +++ b/source/blender/gpu/vulkan/vk_common.hh @@ -97,6 +97,7 @@ template VkObjectType to_vk_object_type(T /*vk_obj*/) return VK_OBJECT_TYPE_UNKNOWN; } -#define NOT_YET_IMPLEMENTED printf("%s not implemented yet\n", __func__); +#define NOT_YET_IMPLEMENTED \ + printf("%s:%d `%s` not implemented yet\n", __FILE__, __LINE__, __func__); } // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_data_conversion.cc b/source/blender/gpu/vulkan/vk_data_conversion.cc index c24ce2ff42d..953f648fd79 100644 --- a/source/blender/gpu/vulkan/vk_data_conversion.cc +++ b/source/blender/gpu/vulkan/vk_data_conversion.cc @@ -238,6 +238,7 @@ static ConversionType type_of_conversion_uint(eGPUTextureFormat device_format) case GPU_RGBA32UI: case GPU_RG32UI: case GPU_R32UI: + case GPU_DEPTH_COMPONENT24: return ConversionType::PASS_THROUGH; case GPU_RGBA16UI: @@ -304,7 +305,6 @@ static ConversionType type_of_conversion_uint(eGPUTextureFormat device_format) case GPU_SRGB8: case GPU_RGB9_E5: case GPU_DEPTH_COMPONENT32F: - case GPU_DEPTH_COMPONENT24: case GPU_DEPTH_COMPONENT16: return ConversionType::UNSUPPORTED; } @@ -935,7 +935,8 @@ void convert_device_to_host(void *dst_buffer, eGPUTextureFormat device_format) { ConversionType conversion_type = reversed(host_to_device(host_format, device_format)); - BLI_assert(conversion_type != ConversionType::UNSUPPORTED); + BLI_assert_msg(conversion_type != ConversionType::UNSUPPORTED, + "Data conversion between host_format and device_format isn't supported (yet)."); convert_buffer(dst_buffer, src_buffer, buffer_size, device_format, conversion_type); } diff --git a/source/blender/gpu/vulkan/vk_framebuffer.cc b/source/blender/gpu/vulkan/vk_framebuffer.cc index 5bee9fbaf0f..41f23d998d8 100644 --- a/source/blender/gpu/vulkan/vk_framebuffer.cc +++ b/source/blender/gpu/vulkan/vk_framebuffer.cc @@ -232,8 +232,8 @@ void VKFrameBuffer::attachment_set_loadstore_op(GPUAttachmentType /*type*/, void VKFrameBuffer::read(eGPUFrameBufferBits plane, eGPUDataFormat format, - const int /*area*/[4], - int channel_len, + const int area[4], + int /*channel_len*/, int slot, void *r_data) { @@ -243,30 +243,19 @@ void VKFrameBuffer::read(eGPUFrameBufferBits plane, texture = unwrap(unwrap(attachments_[GPU_FB_COLOR_ATTACHMENT0 + slot].tex)); break; + case GPU_DEPTH_BIT: + texture = unwrap(unwrap(attachments_[GPU_FB_DEPTH_ATTACHMENT].tex)); + break; + default: BLI_assert_unreachable(); return; } BLI_assert_msg(texture, - "Trying to read back color texture from framebuffer, but no color texture is " - "available in requested slot."); - void *data = texture->read(0, format); - - /* - * TODO: - * - Add support for area. - * - Add support for channel_len. - * Best option would be to add this to VKTexture so we don't over-allocate and reduce number of - * times copies are made. - */ - BLI_assert(format == GPU_DATA_FLOAT); - BLI_assert(channel_len == 4); - int mip_size[3] = {1, 1, 1}; - texture->mip_size_get(0, mip_size); - const size_t mem_size = mip_size[0] * mip_size[1] * mip_size[2] * sizeof(float) * channel_len; - memcpy(r_data, data, mem_size); - MEM_freeN(data); + "Trying to read back texture from framebuffer, but no texture is available in " + "requested slot."); + texture->read_sub(0, format, area, r_data); } /** \} */ diff --git a/source/blender/gpu/vulkan/vk_texture.cc b/source/blender/gpu/vulkan/vk_texture.cc index e636fe7172d..ae6f9499896 100644 --- a/source/blender/gpu/vulkan/vk_texture.cc +++ b/source/blender/gpu/vulkan/vk_texture.cc @@ -37,9 +37,15 @@ void VKTexture::init(VkImage vk_image, VkImageLayout layout) current_layout_ = layout; } -void VKTexture::generate_mipmap() {} +void VKTexture::generate_mipmap() +{ + NOT_YET_IMPLEMENTED +} -void VKTexture::copy_to(Texture * /*tex*/) {} +void VKTexture::copy_to(Texture * /*tex*/) +{ + NOT_YET_IMPLEMENTED; +} void VKTexture::clear(eGPUDataFormat format, const void *data) { @@ -60,13 +66,22 @@ void VKTexture::clear(eGPUDataFormat format, const void *data) vk_image_, current_layout_get(), clear_color, Span(&range, 1)); } -void VKTexture::swizzle_set(const char /*swizzle_mask*/[4]) {} +void VKTexture::swizzle_set(const char /*swizzle_mask*/[4]) +{ + NOT_YET_IMPLEMENTED; +} -void VKTexture::stencil_texture_mode_set(bool /*use_stencil*/) {} +void VKTexture::stencil_texture_mode_set(bool /*use_stencil*/) +{ + NOT_YET_IMPLEMENTED; +} -void VKTexture::mip_range_set(int /*min*/, int /*max*/) {} +void VKTexture::mip_range_set(int /*min*/, int /*max*/) +{ + NOT_YET_IMPLEMENTED; +} -void *VKTexture::read(int mip, eGPUDataFormat format) +void VKTexture::read_sub(int mip, eGPUDataFormat format, const int area[4], void *r_data) { VKContext &context = *VKContext::get(); layout_ensure(context, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); @@ -74,20 +89,18 @@ void *VKTexture::read(int mip, eGPUDataFormat format) /* Vulkan images cannot be directly mapped to host memory and requires a staging buffer. */ VKBuffer staging_buffer; - /* NOTE: mip_size_get() won't override any dimension that is equal to 0. */ - int extent[3] = {1, 1, 1}; - mip_size_get(mip, extent); - size_t sample_len = extent[0] * extent[1] * extent[2]; + size_t sample_len = area[2] * area[3]; size_t device_memory_size = sample_len * to_bytesize(format_); - size_t host_memory_size = sample_len * to_bytesize(format_, format); staging_buffer.create( device_memory_size, GPU_USAGE_DEVICE_ONLY, VK_BUFFER_USAGE_TRANSFER_DST_BIT); VkBufferImageCopy region = {}; - region.imageExtent.width = extent[0]; - region.imageExtent.height = extent[1]; - region.imageExtent.depth = extent[2]; + region.imageOffset.x = area[0]; + region.imageOffset.y = area[1]; + region.imageExtent.width = area[2]; + region.imageExtent.height = area[3]; + region.imageExtent.depth = 1; region.imageSubresource.aspectMask = to_vk_image_aspect_flag_bits(format_); region.imageSubresource.mipLevel = mip; region.imageSubresource.layerCount = 1; @@ -96,8 +109,19 @@ void *VKTexture::read(int mip, eGPUDataFormat format) command_buffer.copy(staging_buffer, *this, Span(®ion, 1)); command_buffer.submit(); + convert_device_to_host(r_data, staging_buffer.mapped_memory_get(), sample_len, format, format_); +} + +void *VKTexture::read(int mip, eGPUDataFormat format) +{ + int mip_size[3] = {1, 1, 1}; + mip_size_get(mip, mip_size); + size_t sample_len = mip_size[0] * mip_size[1]; + size_t host_memory_size = sample_len * to_bytesize(format_, format); + void *data = MEM_mallocN(host_memory_size, __func__); - convert_device_to_host(data, staging_buffer.mapped_memory_get(), sample_len, format, format_); + int area[4] = {0, 0, mip_size[0], mip_size[1]}; + read_sub(mip, format, area, data); return data; } @@ -158,6 +182,7 @@ void VKTexture::update_sub(int /*offset*/[3], eGPUDataFormat /*format*/, GPUPixelBuffer * /*pixbuf*/) { + NOT_YET_IMPLEMENTED; } /* TODO(fclem): Legacy. Should be removed at some point. */ diff --git a/source/blender/gpu/vulkan/vk_texture.hh b/source/blender/gpu/vulkan/vk_texture.hh index 7e9e803e596..10848315743 100644 --- a/source/blender/gpu/vulkan/vk_texture.hh +++ b/source/blender/gpu/vulkan/vk_texture.hh @@ -39,6 +39,7 @@ class VKTexture : public Texture { void stencil_texture_mode_set(bool use_stencil) override; void mip_range_set(int min, int max) override; void *read(int mip, eGPUDataFormat format) override; + void read_sub(int mip, eGPUDataFormat format, const int area[4], void *r_data); void update_sub( int mip, int offset[3], int extent[3], eGPUDataFormat format, const void *data) override; void update_sub(int offset[3], -- 2.30.2 From 3c70ae669c7b81397e0a5121aa10b396df9a39f3 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 16 May 2023 14:02:21 +0200 Subject: [PATCH 14/63] Fix Clang compilations errors. --- intern/ghost/intern/GHOST_ContextVK.cc | 4 +--- source/blender/gpu/vulkan/vk_common.cc | 2 +- source/blender/gpu/vulkan/vk_data_conversion.cc | 6 +++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/intern/ghost/intern/GHOST_ContextVK.cc b/intern/ghost/intern/GHOST_ContextVK.cc index b0009b0b322..307711e0e8d 100644 --- a/intern/ghost/intern/GHOST_ContextVK.cc +++ b/intern/ghost/intern/GHOST_ContextVK.cc @@ -1120,9 +1120,7 @@ GHOST_TSuccess GHOST_ContextVK::initializeDrawingContext() /* According to the Vulkan specs, when `VK_KHR_portability_subset` is available it should be * enabled. See * https://vulkan.lunarg.com/doc/view/1.2.198.1/mac/1.2-extensions/vkspec.html#VUID-VkDeviceCreateInfo-pProperties-04451*/ - if (device_extensions_support(vulkan_device->physical_device, - {VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME})) - { + if (vulkan_device->extensions_support({VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME})) { extensions_device.push_back(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME); } #endif diff --git a/source/blender/gpu/vulkan/vk_common.cc b/source/blender/gpu/vulkan/vk_common.cc index 8e059d40402..0db3091a46d 100644 --- a/source/blender/gpu/vulkan/vk_common.cc +++ b/source/blender/gpu/vulkan/vk_common.cc @@ -654,7 +654,7 @@ template void copy_color(T dst[4], const T *src) VkClearColorValue to_vk_clear_color_value(const eGPUDataFormat format, const void *data) { - VkClearColorValue result = {0.0f}; + VkClearColorValue result = {{0.0f}}; switch (format) { case GPU_DATA_FLOAT: { const float *float_data = static_cast(data); diff --git a/source/blender/gpu/vulkan/vk_data_conversion.cc b/source/blender/gpu/vulkan/vk_data_conversion.cc index 953f648fd79..68054dfae60 100644 --- a/source/blender/gpu/vulkan/vk_data_conversion.cc +++ b/source/blender/gpu/vulkan/vk_data_conversion.cc @@ -726,11 +726,11 @@ constexpr uint8_t SHIFT_R = 0; static void convert(FLOAT3 &dst, const B10F_G11G_R11F &src) { dst.value.x = uint32_t_to_float( - convert_float_formats((src.value >> SHIFT_R) && MASK_11_BITS)); + convert_float_formats((src.value >> SHIFT_R) & MASK_11_BITS)); dst.value.y = uint32_t_to_float( - convert_float_formats((src.value >> SHIFT_G) && MASK_11_BITS)); + convert_float_formats((src.value >> SHIFT_G) & MASK_11_BITS)); dst.value.z = uint32_t_to_float( - convert_float_formats((src.value >> SHIFT_B) && MASK_10_BITS)); + convert_float_formats((src.value >> SHIFT_B) & MASK_10_BITS)); } static void convert(B10F_G11G_R11F &dst, const FLOAT3 &src) -- 2.30.2 From 44a405ef55f69ca329d050af81eabcf622cce539 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 16 May 2023 15:57:22 +0200 Subject: [PATCH 15/63] Many small changes. Nothing worth mentioning as much is still WIP. --- source/blender/gpu/vulkan/vk_batch.cc | 5 +- .../blender/gpu/vulkan/vk_command_buffer.cc | 16 ++++++ .../blender/gpu/vulkan/vk_command_buffer.hh | 1 + .../blender/gpu/vulkan/vk_descriptor_set.hh | 5 +- .../blender/gpu/vulkan/vk_pipeline_state.cc | 9 +-- .../blender/gpu/vulkan/vk_pipeline_state.hh | 4 -- source/blender/gpu/vulkan/vk_texture.cc | 55 +++++++++++++++++-- source/blender/gpu/vulkan/vk_vertex_buffer.cc | 3 +- source/blender/gpu/vulkan/vk_vertex_buffer.hh | 4 ++ 9 files changed, 83 insertions(+), 19 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_batch.cc b/source/blender/gpu/vulkan/vk_batch.cc index d1d2997d3d3..44335b3f568 100644 --- a/source/blender/gpu/vulkan/vk_batch.cc +++ b/source/blender/gpu/vulkan/vk_batch.cc @@ -47,7 +47,10 @@ void VKBatch::draw(int vertex_first, int vertex_count, int instance_first, int i context.command_buffer_get().submit(); } -void VKBatch::draw_indirect(GPUStorageBuf * /*indirect_buf*/, intptr_t /*offset*/) {} +void VKBatch::draw_indirect(GPUStorageBuf * /*indirect_buf*/, intptr_t /*offset*/) +{ + NOT_YET_IMPLEMENTED; +} void VKBatch::multi_draw_indirect(GPUStorageBuf * /*indirect_buf*/, int /*count*/, diff --git a/source/blender/gpu/vulkan/vk_command_buffer.cc b/source/blender/gpu/vulkan/vk_command_buffer.cc index 4ae1f5b2d11..8e4c2e34e63 100644 --- a/source/blender/gpu/vulkan/vk_command_buffer.cc +++ b/source/blender/gpu/vulkan/vk_command_buffer.cc @@ -171,6 +171,7 @@ void VKCommandBuffer::copy(VKBuffer &dst_buffer, regions.size(), regions.data()); } + void VKCommandBuffer::copy(VKTexture &dst_texture, VKBuffer &src_buffer, Span regions) @@ -183,6 +184,21 @@ void VKCommandBuffer::copy(VKTexture &dst_texture, regions.size(), regions.data()); } + +void VKCommandBuffer::copy(VKTexture &dst_texture, + VKTexture &src_texture, + Span regions) +{ + ensure_no_active_framebuffer(); + vkCmdCopyImage(vk_command_buffer_, + src_texture.vk_image_handle(), + src_texture.current_layout_get(), + dst_texture.vk_image_handle(), + dst_texture.current_layout_get(), + regions.size(), + regions.data()); +} + void VKCommandBuffer::blit(VKTexture &dst_texture, VKTexture &src_buffer, Span regions) diff --git a/source/blender/gpu/vulkan/vk_command_buffer.hh b/source/blender/gpu/vulkan/vk_command_buffer.hh index 04d82190841..795cb651c12 100644 --- a/source/blender/gpu/vulkan/vk_command_buffer.hh +++ b/source/blender/gpu/vulkan/vk_command_buffer.hh @@ -162,6 +162,7 @@ class VKCommandBuffer : NonCopyable, NonMovable { /** Copy the contents of a texture MIP level to the dst buffer. */ void copy(VKBuffer &dst_buffer, VKTexture &src_texture, Span regions); void copy(VKTexture &dst_texture, VKBuffer &src_buffer, Span regions); + void copy(VKTexture &dst_texture, VKTexture &src_texture, Span regions); void blit(VKTexture &dst_texture, VKTexture &src_texture, Span regions); void pipeline_barrier(VkPipelineStageFlags source_stages, VkPipelineStageFlags destination_stages); diff --git a/source/blender/gpu/vulkan/vk_descriptor_set.hh b/source/blender/gpu/vulkan/vk_descriptor_set.hh index 8f7c984fcd1..3a714d49f23 100644 --- a/source/blender/gpu/vulkan/vk_descriptor_set.hh +++ b/source/blender/gpu/vulkan/vk_descriptor_set.hh @@ -128,7 +128,10 @@ class VKDescriptorSetTracker : protected VKResourceTracker { bool is_buffer() const { - return ELEM(type, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER); + return ELEM(type, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER); } bool is_image() const diff --git a/source/blender/gpu/vulkan/vk_pipeline_state.cc b/source/blender/gpu/vulkan/vk_pipeline_state.cc index 01902cf905e..9d9e2d89327 100644 --- a/source/blender/gpu/vulkan/vk_pipeline_state.cc +++ b/source/blender/gpu/vulkan/vk_pipeline_state.cc @@ -27,7 +27,6 @@ VKPipelineStateManager::VKPipelineStateManager() VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; - color_blend_attachment_int_template = color_blend_attachment_template; } void VKPipelineStateManager::set_state(const GPUState &state, const GPUStateMutable &mutable_state) @@ -90,13 +89,7 @@ void VKPipelineStateManager::finalize_color_blend_state(const VKFrameBuffer &fra VKTexture *texture = unwrap(unwrap(framebuffer.color_tex(color_slot))); if (texture) { BLI_assert(is_sequential); - eGPUTextureFormatFlag format_flag = texture->format_flag_get(); - if (format_flag & GPU_FORMAT_INTEGER) { - color_blend_attachments.append(color_blend_attachment_int_template); - } - else { - color_blend_attachments.append(color_blend_attachment_template); - } + color_blend_attachments.append(color_blend_attachment_template); } else { /* Test to detect if all color textures are sequential attached from the first slot. We diff --git a/source/blender/gpu/vulkan/vk_pipeline_state.hh b/source/blender/gpu/vulkan/vk_pipeline_state.hh index 55f8be8a3b4..f4afb262745 100644 --- a/source/blender/gpu/vulkan/vk_pipeline_state.hh +++ b/source/blender/gpu/vulkan/vk_pipeline_state.hh @@ -22,11 +22,7 @@ class VKPipelineStateManager { public: VkPipelineColorBlendStateCreateInfo pipeline_color_blend_state; - /* Template of the color blending for color attachments. - * Blending is not supported on Integer based textures. - */ VkPipelineColorBlendAttachmentState color_blend_attachment_template; - VkPipelineColorBlendAttachmentState color_blend_attachment_int_template; Vector color_blend_attachments; VkPipelineRasterizationStateCreateInfo rasterization_state; VkPipelineDepthStencilStateCreateInfo depth_stencil_state; diff --git a/source/blender/gpu/vulkan/vk_texture.cc b/source/blender/gpu/vulkan/vk_texture.cc index ae6f9499896..932de5b3c3b 100644 --- a/source/blender/gpu/vulkan/vk_texture.cc +++ b/source/blender/gpu/vulkan/vk_texture.cc @@ -14,6 +14,7 @@ #include "vk_shader.hh" #include "vk_shader_interface.hh" #include "vk_state_manager.hh" +#include "vk_vertex_buffer.hh" #include "BLI_math_vector.hh" @@ -42,9 +43,34 @@ void VKTexture::generate_mipmap() NOT_YET_IMPLEMENTED } -void VKTexture::copy_to(Texture * /*tex*/) +void VKTexture::copy_to(Texture *tex) { - NOT_YET_IMPLEMENTED; + VKTexture *dst = unwrap(tex); + VKTexture *src = this; + BLI_assert(dst); + BLI_assert(src->w_ == dst->w_ && src->h_ == dst->h_ && src->d_ == dst->d_); + BLI_assert(src->format_ == dst->format_); + UNUSED_VARS_NDEBUG(src); + + VKContext &context = *VKContext::get(); + layout_ensure(context, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + dst->ensure_allocated(); + dst->layout_ensure(context, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + + VkImageCopy region = {}; + region.srcSubresource.aspectMask = to_vk_image_aspect_flag_bits(format_); + region.srcSubresource.mipLevel = 0; + region.srcSubresource.layerCount = 1; + region.dstSubresource.aspectMask = to_vk_image_aspect_flag_bits(format_); + region.dstSubresource.mipLevel = 0; + region.dstSubresource.layerCount = 1; + region.extent.width = w_; + region.extent.height = h_; + region.extent.depth = d_; + + VKCommandBuffer &command_buffer = context.command_buffer_get(); + command_buffer.copy(*dst, *this, Span(®ion, 1)); + command_buffer.submit(); } void VKTexture::clear(eGPUDataFormat format, const void *data) @@ -201,13 +227,34 @@ bool VKTexture::init_internal() return true; } -bool VKTexture::init_internal(GPUVertBuf * /*vbo*/) +bool VKTexture::init_internal(GPUVertBuf *vbo) { - return false; + if (!allocate()) { + return false; + } + + VKVertexBuffer *vertex_buffer = unwrap(unwrap(vbo)); + + VkBufferImageCopy region = {}; + region.imageExtent.width = w_; + region.imageExtent.height = 1; + region.imageExtent.depth = 1; + region.imageSubresource.aspectMask = to_vk_image_aspect_flag_bits(format_); + region.imageSubresource.mipLevel = 0; + region.imageSubresource.layerCount = 1; + + VKContext &context = *VKContext::get(); + layout_ensure(context, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + VKCommandBuffer &command_buffer = context.command_buffer_get(); + command_buffer.copy(*this, vertex_buffer->buffer_, Span(®ion, 1)); + command_buffer.submit(); + + return true; } bool VKTexture::init_internal(GPUTexture * /*src*/, int /*mip_offset*/, int /*layer_offset*/) { + NOT_YET_IMPLEMENTED; return false; } diff --git a/source/blender/gpu/vulkan/vk_vertex_buffer.cc b/source/blender/gpu/vulkan/vk_vertex_buffer.cc index 0286b0088c1..644bdda34de 100644 --- a/source/blender/gpu/vulkan/vk_vertex_buffer.cc +++ b/source/blender/gpu/vulkan/vk_vertex_buffer.cc @@ -133,7 +133,8 @@ void VKVertexBuffer::allocate() { buffer_.create(size_alloc_get(), usage_, - static_cast(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | + static_cast(VK_BUFFER_USAGE_TRANSFER_SRC_BIT | + VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)); debug::object_label(buffer_.vk_handle(), "VertexBuffer"); } diff --git a/source/blender/gpu/vulkan/vk_vertex_buffer.hh b/source/blender/gpu/vulkan/vk_vertex_buffer.hh index 9e653a28b96..c4aea92e369 100644 --- a/source/blender/gpu/vulkan/vk_vertex_buffer.hh +++ b/source/blender/gpu/vulkan/vk_vertex_buffer.hh @@ -12,6 +12,7 @@ #include "vk_buffer.hh" namespace blender::gpu { +class VKTexture; class VKVertexBuffer : public VertBuf { VKBuffer buffer_; @@ -42,6 +43,9 @@ class VKVertexBuffer : public VertBuf { private: void allocate(); void *convert() const; + + /* VKTexture requires access to `buffer_` to convert a vertex buffer to a texture.*/ + friend class VKTexture; }; static inline VKVertexBuffer *unwrap(VertBuf *vertex_buffer) -- 2.30.2 From 26d1c4d59ad7a8bae17e7eb7f90468db10f333d8 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 16 May 2023 16:14:57 +0200 Subject: [PATCH 16/63] Fix extent height and depth. --- source/blender/gpu/vulkan/vk_texture.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_texture.cc b/source/blender/gpu/vulkan/vk_texture.cc index 932de5b3c3b..36cc994f9ca 100644 --- a/source/blender/gpu/vulkan/vk_texture.cc +++ b/source/blender/gpu/vulkan/vk_texture.cc @@ -65,8 +65,8 @@ void VKTexture::copy_to(Texture *tex) region.dstSubresource.mipLevel = 0; region.dstSubresource.layerCount = 1; region.extent.width = w_; - region.extent.height = h_; - region.extent.depth = d_; + region.extent.height = max_ii(h_, 1); + region.extent.depth = max_ii(d_, 1); VKCommandBuffer &command_buffer = context.command_buffer_get(); command_buffer.copy(*dst, *this, Span(®ion, 1)); -- 2.30.2 From 0b186b526653dbb7346dbbbe4a6ee4d54d2029fa Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Wed, 17 May 2023 12:30:08 +0200 Subject: [PATCH 17/63] Add support for Inf, Nan and clamping --- .../blender/gpu/vulkan/vk_data_conversion.hh | 52 ++++++++---- .../gpu/vulkan/vk_data_conversion_test.cc | 79 ++++++++++++++++--- 2 files changed, 106 insertions(+), 25 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_data_conversion.hh b/source/blender/gpu/vulkan/vk_data_conversion.hh index f1f9ac6b7e2..b505512d138 100644 --- a/source/blender/gpu/vulkan/vk_data_conversion.hh +++ b/source/blender/gpu/vulkan/vk_data_conversion.hh @@ -110,12 +110,14 @@ class FloatingPointFormat { static constexpr uint8_t MantissaLen = MantissaBitLen; static constexpr uint8_t MantissaShift = 0; static constexpr uint32_t MantissaMask = (1 << MantissaBitLen) - 1; + static constexpr uint32_t MantissaNanMask = MantissaMask; static constexpr uint8_t ExponentShift = MantissaBitLen; static constexpr uint8_t ExponentLen = ExponentBitLen; static constexpr uint32_t ExponentMask = (1 << ExponentBitLen) - 1; + static constexpr uint32_t ExponentBias = (1 << (ExponentBitLen - 1)) - 1; + static constexpr int32_t ExponentSpecialMask = ExponentMask; static constexpr uint8_t SignShift = MantissaBitLen + ExponentBitLen; static constexpr uint32_t SignMask = HasSignBit ? 1 : 0; - static constexpr uint32_t ExponentBias = (1 << (ExponentBitLen - 1)) - 1; static uint32_t get_mantissa(uint32_t floating_point_number) { @@ -161,7 +163,7 @@ class FloatingPointFormat { static uint32_t set_sign(bool sign, uint32_t floating_point_number) { - if constexpr (HasSignBit) { + if constexpr (!HasSignBit) { return floating_point_number; } uint32_t result = clear_sign(floating_point_number); @@ -182,9 +184,6 @@ using FormatF10 = FloatingPointFormat; * convert between the formats. Additional conversion rules can be applied to the conversion * function. Due to the implementation the compiler would make an optimized version depending on * the actual possibilities. - * - * NOTE: Implementation should be extended to support Nan, Inf, -Inf and clamping to min/max when - * values don't fit in the destination. */ template< /** @@ -199,7 +198,7 @@ template< /** * Should negative values be clamped to zero when DestinationFormat doesn't contain a sign - * bit. + * bit. Also -Inf will be clamped to zero. * * When set to `false` and DestinationFormat doesn't contain a sign bit the value will be * made absolute. @@ -211,25 +210,46 @@ uint32_t convert_float_formats(uint32_t value) uint32_t mantissa = SourceFormat::get_mantissa(value); int32_t exponent = SourceFormat::get_exponent(value); + const bool is_nan = (exponent == SourceFormat::ExponentSpecialMask) && mantissa; + const bool is_inf = (exponent == SourceFormat::ExponentSpecialMask) && (mantissa == 0); + /* Sign conversion */ if constexpr (!DestinationFormat::HasSign && ClampNegativeToZero) { - if (is_signed) { + if (is_signed && !is_nan) { return 0; } } - /* Mantissa conversion */ - if constexpr (SourceFormat::MantissaLen > DestinationFormat::MantissaLen) { - mantissa = mantissa >> (SourceFormat::MantissaLen - DestinationFormat::MantissaLen); + if (is_inf) { + exponent = DestinationFormat::ExponentSpecialMask; } - else if constexpr (SourceFormat::MantissaLen < DestinationFormat::MantissaLen) { - mantissa = mantissa << (DestinationFormat::MantissaLen - SourceFormat::MantissaLen); + else if (is_nan) { + exponent = DestinationFormat::ExponentSpecialMask; + mantissa = DestinationFormat::MantissaNanMask; } + else { + /* Exponent conversion */ + exponent -= SourceFormat::ExponentBias; + /* Clamping when destination has lower precision. */ + if constexpr (SourceFormat::ExponentLen > DestinationFormat::ExponentLen) { + if (exponent > DestinationFormat::ExponentBias) { + exponent = 0; + mantissa = SourceFormat::MantissaMask; + } + else if (exponent < -int32_t(DestinationFormat::ExponentBias)) { + return 0; + } + } + exponent += DestinationFormat::ExponentBias; - /* Exponent conversion */ - exponent += DestinationFormat::ExponentBias - SourceFormat::ExponentBias; - // TODO: Clamp to min/max value? only when Destination::ExponentBias < - // SourceFormat::ExponentBias. + /* Mantissa conversion */ + if constexpr (SourceFormat::MantissaLen > DestinationFormat::MantissaLen) { + mantissa = mantissa >> (SourceFormat::MantissaLen - DestinationFormat::MantissaLen); + } + else if constexpr (SourceFormat::MantissaLen < DestinationFormat::MantissaLen) { + mantissa = mantissa << (DestinationFormat::MantissaLen - SourceFormat::MantissaLen); + } + } uint32_t result = 0; result = DestinationFormat::set_sign(is_signed, result); diff --git a/source/blender/gpu/vulkan/vk_data_conversion_test.cc b/source/blender/gpu/vulkan/vk_data_conversion_test.cc index fe34124dcc4..f2a2add34c1 100644 --- a/source/blender/gpu/vulkan/vk_data_conversion_test.cc +++ b/source/blender/gpu/vulkan/vk_data_conversion_test.cc @@ -5,22 +5,83 @@ namespace blender::gpu::tests { TEST(VulkanDataConversion, ConvertF32F16) { - uint32_t f32_2 = 0b01000000000000000000000000000000; - uint32_t f16_2_expected = 0b0100000000000000; - uint32_t f16_2 = convert_float_formats(f32_2); + const uint32_t f32_2 = 0b01000000000000000000000000000000; + const uint32_t f16_2_expected = 0b0100000000000000; + const uint32_t f16_2 = convert_float_formats(f32_2); EXPECT_EQ(f16_2, f16_2_expected); - uint32_t f32_3 = 0b01000000010000000000000000000000; - uint32_t f16_3_expected = 0b0100001000000000; - uint32_t f16_3 = convert_float_formats(f32_3); + const uint32_t f32_3 = 0b01000000010000000000000000000000; + const uint32_t f16_3_expected = 0b0100001000000000; + const uint32_t f16_3 = convert_float_formats(f32_3); EXPECT_EQ(f16_3, f16_3_expected); - uint32_t f32_4 = 0b01000000100000000000000000000000; - uint32_t f16_4_expected = 0b0100010000000000; - uint32_t f16_4 = convert_float_formats(f32_4); + const uint32_t f32_4 = 0b01000000100000000000000000000000; + const uint32_t f16_4_expected = 0b0100010000000000; + const uint32_t f16_4 = convert_float_formats(f32_4); EXPECT_EQ(f16_4, f16_4_expected); } +TEST(VulkanDataConversion, clamp_negative_to_zero) +{ + const uint32_t f32_2 = 0b11000000000000000000000000000000; + const uint32_t f32_inf_min = 0b11111111100000000000000000000000; + const uint32_t f32_inf_max = 0b01111111100000000000000000000000; + const uint32_t f32_nan = 0b11111111111111111111111111111111; + + /* F32(-2) fits in F16. */ + const uint32_t f16_2_expected = 0b1100000000000000; + const uint32_t f16_2a = convert_float_formats(f32_2); + EXPECT_EQ(f16_2a, f16_2_expected); + + const uint32_t f16_2b = convert_float_formats(f32_2); + EXPECT_EQ(f16_2b, f16_2_expected); + + /* F32(-2) doesn't fit in F11 as F11 only supports unsigned values. Clamp to zero. */ + const uint32_t f11_0_expected = 0b00000000000; + const uint32_t f11_2_expected = 0b10000000000; + const uint32_t f11_inf_expected = 0b11111000000; + const uint32_t f11_nan_expected = 0b11111111111; + { + const uint32_t f11_0 = convert_float_formats(f32_2); + EXPECT_EQ(f11_0, f11_0_expected); + const uint32_t f11_0b = convert_float_formats(f32_inf_min); + EXPECT_EQ(f11_0b, f11_0_expected); + const uint32_t f11_inf = convert_float_formats(f32_inf_max); + EXPECT_EQ(f11_inf, f11_inf_expected); + const uint32_t f11_nan = convert_float_formats(f32_nan); + EXPECT_EQ(f11_nan, f11_nan_expected); + } + + /* F32(-2) doesn't fit in F11 as F11 only supports unsigned values. Make absolute. */ + { + const uint32_t f11_2 = convert_float_formats(f32_2); + EXPECT_EQ(f11_2, f11_2_expected); + const uint32_t f11_inf = convert_float_formats(f32_inf_min); + EXPECT_EQ(f11_inf, f11_inf_expected); + const uint32_t f11_infb = convert_float_formats(f32_inf_max); + EXPECT_EQ(f11_infb, f11_inf_expected); + const uint32_t f11_nan = convert_float_formats(f32_nan); + EXPECT_EQ(f11_nan, f11_nan_expected); + } +} + +TEST(VulkanDataConversion, infinity_upper) +{ + const uint32_t f32_inf = 0b01111111100000000000000000000000; + + const uint32_t f16_inf_expected = 0b0111110000000000; + const uint32_t f16_inf = convert_float_formats(f32_inf); + EXPECT_EQ(f16_inf, f16_inf_expected); + + const uint32_t f11_inf_expected = 0b11111000000; + const uint32_t f11_inf = convert_float_formats(f32_inf); + EXPECT_EQ(f11_inf, f11_inf_expected); + + const uint32_t f10_inf_expected = 0b1111100000; + const uint32_t f10_inf = convert_float_formats(f32_inf); + EXPECT_EQ(f10_inf, f10_inf_expected); +} + // TODO: add test case for Nan, Inf, -Inf, Clamping } // namespace blender::gpu::tests \ No newline at end of file -- 2.30.2 From 6371521557b1f5464d9366163a877e99b3224c58 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 19 May 2023 08:14:06 +0200 Subject: [PATCH 18/63] Fix float conversions. --- .../blender/gpu/vulkan/vk_data_conversion.hh | 12 ++++--- .../gpu/vulkan/vk_data_conversion_test.cc | 32 +++++++++++-------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_data_conversion.hh b/source/blender/gpu/vulkan/vk_data_conversion.hh index b505512d138..971148d216f 100644 --- a/source/blender/gpu/vulkan/vk_data_conversion.hh +++ b/source/blender/gpu/vulkan/vk_data_conversion.hh @@ -107,6 +107,8 @@ template class FloatingPointFormat { public: static constexpr bool HasSign = HasSignBit; + static constexpr uint8_t SignShift = MantissaBitLen + ExponentBitLen; + static constexpr uint32_t SignMask = HasSignBit ? 1 : 0; static constexpr uint8_t MantissaLen = MantissaBitLen; static constexpr uint8_t MantissaShift = 0; static constexpr uint32_t MantissaMask = (1 << MantissaBitLen) - 1; @@ -114,10 +116,8 @@ class FloatingPointFormat { static constexpr uint8_t ExponentShift = MantissaBitLen; static constexpr uint8_t ExponentLen = ExponentBitLen; static constexpr uint32_t ExponentMask = (1 << ExponentBitLen) - 1; - static constexpr uint32_t ExponentBias = (1 << (ExponentBitLen - 1)) - 1; + static constexpr int32_t ExponentBias = (1 << (ExponentBitLen - 1)) - 1; static constexpr int32_t ExponentSpecialMask = ExponentMask; - static constexpr uint8_t SignShift = MantissaBitLen + ExponentBitLen; - static constexpr uint32_t SignMask = HasSignBit ? 1 : 0; static uint32_t get_mantissa(uint32_t floating_point_number) { @@ -212,6 +212,7 @@ uint32_t convert_float_formats(uint32_t value) const bool is_nan = (exponent == SourceFormat::ExponentSpecialMask) && mantissa; const bool is_inf = (exponent == SourceFormat::ExponentSpecialMask) && (mantissa == 0); + const bool is_zero = (exponent == 0 && mantissa == 0); /* Sign conversion */ if constexpr (!DestinationFormat::HasSign && ClampNegativeToZero) { @@ -219,6 +220,9 @@ uint32_t convert_float_formats(uint32_t value) return 0; } } + if (is_zero) { + return 0; + } if (is_inf) { exponent = DestinationFormat::ExponentSpecialMask; @@ -236,7 +240,7 @@ uint32_t convert_float_formats(uint32_t value) exponent = 0; mantissa = SourceFormat::MantissaMask; } - else if (exponent < -int32_t(DestinationFormat::ExponentBias)) { + else if (exponent < -DestinationFormat::ExponentBias) { return 0; } } diff --git a/source/blender/gpu/vulkan/vk_data_conversion_test.cc b/source/blender/gpu/vulkan/vk_data_conversion_test.cc index f2a2add34c1..bcc910016a5 100644 --- a/source/blender/gpu/vulkan/vk_data_conversion_test.cc +++ b/source/blender/gpu/vulkan/vk_data_conversion_test.cc @@ -3,22 +3,26 @@ #include "vk_data_conversion.hh" namespace blender::gpu::tests { +static void test_f32_f16(uint32_t f32_in, uint32_t f16_expected) +{ + const uint32_t f16 = convert_float_formats(f32_in); + EXPECT_EQ(f16, f16_expected); + const uint32_t f32_reverse = convert_float_formats(f16); + EXPECT_EQ(f32_reverse, f32_in); +} + TEST(VulkanDataConversion, ConvertF32F16) { - const uint32_t f32_2 = 0b01000000000000000000000000000000; - const uint32_t f16_2_expected = 0b0100000000000000; - const uint32_t f16_2 = convert_float_formats(f32_2); - EXPECT_EQ(f16_2, f16_2_expected); - - const uint32_t f32_3 = 0b01000000010000000000000000000000; - const uint32_t f16_3_expected = 0b0100001000000000; - const uint32_t f16_3 = convert_float_formats(f32_3); - EXPECT_EQ(f16_3, f16_3_expected); - - const uint32_t f32_4 = 0b01000000100000000000000000000000; - const uint32_t f16_4_expected = 0b0100010000000000; - const uint32_t f16_4 = convert_float_formats(f32_4); - EXPECT_EQ(f16_4, f16_4_expected); + /* 0.0 */ + test_f32_f16(0b00000000000000000000000000000000, 0b0000000000000000); + /* 0.125 */ + test_f32_f16(0b00111110000000000000000000000000, 0b0011000000000000); + /* 2.0 */ + test_f32_f16(0b01000000000000000000000000000000, 0b0100000000000000); + /* 3.0 */ + test_f32_f16(0b01000000010000000000000000000000, 0b0100001000000000); + /* 4.0 */ + test_f32_f16(0b01000000100000000000000000000000, 0b0100010000000000); } TEST(VulkanDataConversion, clamp_negative_to_zero) -- 2.30.2 From f37f6c8c931d8944a56d15a9675700a5b2f70688 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 19 May 2023 09:07:58 +0200 Subject: [PATCH 19/63] Also reallocate fragmented pools --- source/blender/gpu/vulkan/vk_descriptor_pools.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/gpu/vulkan/vk_descriptor_pools.cc b/source/blender/gpu/vulkan/vk_descriptor_pools.cc index 80775deefd9..611e442fd7e 100644 --- a/source/blender/gpu/vulkan/vk_descriptor_pools.cc +++ b/source/blender/gpu/vulkan/vk_descriptor_pools.cc @@ -91,7 +91,7 @@ std::unique_ptr VKDescriptorPools::allocate( VkDescriptorSet vk_descriptor_set = VK_NULL_HANDLE; VkResult result = vkAllocateDescriptorSets(vk_device_, &allocate_info, &vk_descriptor_set); - if (result == VK_ERROR_OUT_OF_POOL_MEMORY) { + if (ELEM(result, VK_ERROR_OUT_OF_POOL_MEMORY, VK_ERROR_FRAGMENTED_POOL)) { if (is_last_pool_active()) { add_new_pool(); activate_last_pool(); -- 2.30.2 From a0beda7a5bbcce8e9e6596f0a60c3f4b7b8e7539 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 19 May 2023 09:08:18 +0200 Subject: [PATCH 20/63] Make ShaderInterface::debug_print const --- source/blender/gpu/intern/gpu_shader_interface.cc | 2 +- source/blender/gpu/intern/gpu_shader_interface.hh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/gpu/intern/gpu_shader_interface.cc b/source/blender/gpu/intern/gpu_shader_interface.cc index d9e5e066fea..37f416e7316 100644 --- a/source/blender/gpu/intern/gpu_shader_interface.cc +++ b/source/blender/gpu/intern/gpu_shader_interface.cc @@ -62,7 +62,7 @@ void ShaderInterface::sort_inputs() MutableSpan(inputs_ + attr_len_ + ubo_len_ + uniform_len_, ssbo_len_)); } -void ShaderInterface::debug_print() +void ShaderInterface::debug_print() const { Span attrs = Span(inputs_, attr_len_); Span ubos = Span(inputs_ + attr_len_, ubo_len_); diff --git a/source/blender/gpu/intern/gpu_shader_interface.hh b/source/blender/gpu/intern/gpu_shader_interface.hh index 24c4bde0971..4964d089172 100644 --- a/source/blender/gpu/intern/gpu_shader_interface.hh +++ b/source/blender/gpu/intern/gpu_shader_interface.hh @@ -77,7 +77,7 @@ class ShaderInterface { ShaderInterface(); virtual ~ShaderInterface(); - void debug_print(); + void debug_print() const; inline const ShaderInput *attr_get(const char *name) const { -- 2.30.2 From a826dbaa499f6fe466d9f53aeb32752361c0ae52 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 19 May 2023 09:09:23 +0200 Subject: [PATCH 21/63] Texel buffers --- source/blender/gpu/vulkan/vk_descriptor_set.cc | 10 ++++++++++ source/blender/gpu/vulkan/vk_descriptor_set.hh | 3 +++ source/blender/gpu/vulkan/vk_vertex_buffer.cc | 15 +++++++++++++-- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_descriptor_set.cc b/source/blender/gpu/vulkan/vk_descriptor_set.cc index b9847a74d05..d548bdf9f1c 100644 --- a/source/blender/gpu/vulkan/vk_descriptor_set.cc +++ b/source/blender/gpu/vulkan/vk_descriptor_set.cc @@ -58,6 +58,15 @@ void VKDescriptorSetTracker::bind_as_ssbo(VKVertexBuffer &buffer, binding.buffer_size = buffer.size_used_get(); } +void VKDescriptorSetTracker::bind_as_texture(VKVertexBuffer &buffer, + const VKDescriptorSet::Location location) +{ + Binding &binding = ensure_location(location); + binding.type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; + binding.vk_buffer = buffer.vk_handle(); + binding.buffer_size = buffer.size_used_get(); +} + void VKDescriptorSetTracker::bind(VKUniformBuffer &buffer, const VKDescriptorSet::Location location) { @@ -115,6 +124,7 @@ void VKDescriptorSetTracker::update(VKContext &context) tracked_resource_for(context, !bindings_.is_empty()); std::unique_ptr &descriptor_set = active_descriptor_set(); VkDescriptorSet vk_descriptor_set = descriptor_set->vk_handle(); + BLI_assert(vk_descriptor_set != VK_NULL_HANDLE); Vector buffer_infos; Vector descriptor_writes; diff --git a/source/blender/gpu/vulkan/vk_descriptor_set.hh b/source/blender/gpu/vulkan/vk_descriptor_set.hh index 3a714d49f23..a311af91c3e 100644 --- a/source/blender/gpu/vulkan/vk_descriptor_set.hh +++ b/source/blender/gpu/vulkan/vk_descriptor_set.hh @@ -83,12 +83,14 @@ class VKDescriptorSet : NonCopyable { VKDescriptorSet(VkDescriptorPool vk_descriptor_pool, VkDescriptorSet vk_descriptor_set) : vk_descriptor_pool_(vk_descriptor_pool), vk_descriptor_set_(vk_descriptor_set) { + BLI_assert(vk_descriptor_set_ != VK_NULL_HANDLE); } VKDescriptorSet(VKDescriptorSet &&other); virtual ~VKDescriptorSet(); VKDescriptorSet &operator=(VKDescriptorSet &&other) { + BLI_assert(other.vk_descriptor_set_ != VK_NULL_HANDLE); vk_descriptor_set_ = other.vk_descriptor_set_; vk_descriptor_pool_ = other.vk_descriptor_pool_; other.mark_freed(); @@ -154,6 +156,7 @@ class VKDescriptorSetTracker : protected VKResourceTracker { VKDescriptorSetTracker(VkDescriptorSetLayout layout) : layout_(layout) {} void bind_as_ssbo(VKVertexBuffer &buffer, VKDescriptorSet::Location location); + void bind_as_texture(VKVertexBuffer &buffer, VKDescriptorSet::Location location); void bind_as_ssbo(VKIndexBuffer &buffer, VKDescriptorSet::Location location); void bind(VKStorageBuffer &buffer, VKDescriptorSet::Location location); void bind(VKUniformBuffer &buffer, VKDescriptorSet::Location location); diff --git a/source/blender/gpu/vulkan/vk_vertex_buffer.cc b/source/blender/gpu/vulkan/vk_vertex_buffer.cc index 644bdda34de..29ca3998b58 100644 --- a/source/blender/gpu/vulkan/vk_vertex_buffer.cc +++ b/source/blender/gpu/vulkan/vk_vertex_buffer.cc @@ -35,9 +35,20 @@ void VKVertexBuffer::bind_as_ssbo(uint binding) shader->pipeline_get().descriptor_set_get().bind_as_ssbo(*this, *location); } -void VKVertexBuffer::bind_as_texture(uint /*binding*/) +void VKVertexBuffer::bind_as_texture(uint binding) { - NOT_YET_IMPLEMENTED + if (!buffer_.is_allocated()) { + allocate(); + } + + VKContext &context = *VKContext::get(); + VKShader *shader = static_cast(context.shader); + const VKShaderInterface &shader_interface = shader->interface_get(); + const std::optional location = + shader_interface.descriptor_set_location( + shader::ShaderCreateInfo::Resource::BindType::SAMPLER, binding); + BLI_assert_msg(location, "Locations to texel buffers should always exist."); + shader->pipeline_get().descriptor_set_get().bind_as_texture(*this, *location); } void VKVertexBuffer::wrap_handle(uint64_t /*handle*/) -- 2.30.2 From 0111c319a7bf5e6888cbda3acf3680b3d2bc51a5 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 19 May 2023 11:58:55 +0200 Subject: [PATCH 22/63] Add test case for binding vertex buffer as texture. --- source/blender/gpu/CMakeLists.txt | 2 + .../gpu/shaders/infos/gpu_shader_test_info.hh | 7 ++ .../blender/gpu/tests/buffer_texture_test.cc | 66 +++++++++++++++++++ .../shaders/gpu_buffer_texture_test.glsl | 6 ++ 4 files changed, 81 insertions(+) create mode 100644 source/blender/gpu/tests/buffer_texture_test.cc create mode 100644 source/blender/gpu/tests/shaders/gpu_buffer_texture_test.glsl diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 54f3a8bf6a4..5e582a01091 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -561,6 +561,7 @@ set(GLSL_SRC set(GLSL_SRC_TEST tests/shaders/gpu_math_test.glsl + tests/shaders/gpu_buffer_texture_test.glsl tests/shaders/gpu_compute_1d_test.glsl tests/shaders/gpu_compute_2d_test.glsl tests/shaders/gpu_compute_ibo_test.glsl @@ -841,6 +842,7 @@ if(WITH_GTESTS) set(TEST_SRC tests/gpu_testing.cc + tests/buffer_texture_test.cc tests/framebuffer_test.cc tests/immediate_test.cc tests/index_buffer_test.cc diff --git a/source/blender/gpu/shaders/infos/gpu_shader_test_info.hh b/source/blender/gpu/shaders/infos/gpu_shader_test_info.hh index ec7327df214..5798bfbd16f 100644 --- a/source/blender/gpu/shaders/infos/gpu_shader_test_info.hh +++ b/source/blender/gpu/shaders/infos/gpu_shader_test_info.hh @@ -85,6 +85,13 @@ GPU_SHADER_CREATE_INFO(gpu_push_constants_512bytes_test) .push_constant(Type::FLOAT, "filler3", 64) .do_static_compilation(true); +GPU_SHADER_CREATE_INFO(gpu_buffer_texture_test) + .local_group_size(1) + .sampler(0, ImageType::FLOAT_BUFFER, "bufferTexture") + .storage_buf(0, Qualifier::WRITE, "float", "data_out[]") + .compute_source("gpu_buffer_texture_test.glsl") + .do_static_compilation(true); + GPU_SHADER_CREATE_INFO(eevee_shadow_test) .fragment_source("eevee_shadow_test.glsl") .additional_info("gpu_shader_test") diff --git a/source/blender/gpu/tests/buffer_texture_test.cc b/source/blender/gpu/tests/buffer_texture_test.cc new file mode 100644 index 00000000000..e0f526e967c --- /dev/null +++ b/source/blender/gpu/tests/buffer_texture_test.cc @@ -0,0 +1,66 @@ +#include "testing/testing.h" + +#include "GPU_capabilities.h" +#include "GPU_compute.h" +#include "GPU_vertex_buffer.h" +#include "GPU_vertex_format.h" + +#include "BLI_index_range.hh" +#include "BLI_math_vector_types.hh" + +#include "gpu_testing.hh" + +namespace blender::gpu::tests { + +static constexpr int Size = 256; + +static void test_buffer_texture() +{ + if (!GPU_compute_shader_support() && !GPU_shader_storage_buffer_objects_support()) { + /* We can't test as a the platform does not support compute shaders. */ + std::cout << "Skipping compute shader test: platform not supported"; + GTEST_SKIP(); + } + + /* Build compute shader. */ + GPUShader *shader = GPU_shader_create_from_info_name("gpu_buffer_texture_test"); + EXPECT_NE(shader, nullptr); + GPU_shader_bind(shader); + + /* Vertex buffer. */ + GPUVertFormat format = {}; + uint value_pos = GPU_vertformat_attr_add(&format, "value", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + GPUVertBuf *vertex_buffer = GPU_vertbuf_create_with_format_ex( + &format, GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY); + float4 value = float4(42.42, 23.23, 1.0, -1.0); + GPU_vertbuf_data_alloc(vertex_buffer, 4); + GPU_vertbuf_attr_fill(vertex_buffer, value_pos, &value); + GPU_vertbuf_bind_as_texture(vertex_buffer, + GPU_shader_get_sampler_binding(shader, "bufferTexture")); + + /* Construct SSBO. */ + GPUStorageBuf *ssbo = GPU_storagebuf_create_ex( + 4 * sizeof(float), nullptr, GPU_USAGE_DEVICE_ONLY, __func__); + GPU_storagebuf_bind(ssbo, GPU_shader_get_ssbo_binding(shader, "data_out")); + + /* Dispatch compute task. */ + GPU_compute_dispatch(shader, 4, 1, 1); + + /* Check if compute has been done. */ + GPU_memory_barrier(GPU_BARRIER_BUFFER_UPDATE); + + /* Download the index buffer. */ + float4 read_data; + GPU_storagebuf_read(ssbo, read_data); + EXPECT_EQ(read_data, value); + + /* Cleanup. */ + GPU_shader_unbind(); + GPU_storagebuf_free(ssbo); + GPU_vertbuf_discard(vertex_buffer); + GPU_shader_free(shader); +} + +GPU_TEST(buffer_texture) + +} // namespace blender::gpu::tests diff --git a/source/blender/gpu/tests/shaders/gpu_buffer_texture_test.glsl b/source/blender/gpu/tests/shaders/gpu_buffer_texture_test.glsl new file mode 100644 index 00000000000..3007f049846 --- /dev/null +++ b/source/blender/gpu/tests/shaders/gpu_buffer_texture_test.glsl @@ -0,0 +1,6 @@ +void main() +{ + int index = int(gl_GlobalInvocationID.x); + float value = texelFetch(bufferTexture, index).r; + data_out[index] = value; +} \ No newline at end of file -- 2.30.2 From adc1cb6eee7e42fa423910e103ab81140bbf09d1 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 19 May 2023 13:04:03 +0200 Subject: [PATCH 23/63] Initial texel buffer --- source/blender/gpu/vulkan/vk_backend.cc | 2 ++ source/blender/gpu/vulkan/vk_batch.cc | 5 ++- .../blender/gpu/vulkan/vk_descriptor_set.cc | 18 +++++------ .../blender/gpu/vulkan/vk_descriptor_set.hh | 3 +- source/blender/gpu/vulkan/vk_immediate.cc | 5 ++- source/blender/gpu/vulkan/vk_state_manager.cc | 32 ++++++++++++++++++- source/blender/gpu/vulkan/vk_state_manager.hh | 11 +++++++ source/blender/gpu/vulkan/vk_vertex_buffer.cc | 22 ++++++++++--- source/blender/gpu/vulkan/vk_vertex_buffer.hh | 2 ++ 9 files changed, 82 insertions(+), 18 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_backend.cc b/source/blender/gpu/vulkan/vk_backend.cc index a9bd54d310f..499d807b37a 100644 --- a/source/blender/gpu/vulkan/vk_backend.cc +++ b/source/blender/gpu/vulkan/vk_backend.cc @@ -17,6 +17,7 @@ #include "vk_pixel_buffer.hh" #include "vk_query.hh" #include "vk_shader.hh" +#include "vk_state_manager.hh" #include "vk_storage_buffer.hh" #include "vk_texture.hh" #include "vk_uniform_buffer.hh" @@ -64,6 +65,7 @@ void VKBackend::samplers_update() {} void VKBackend::compute_dispatch(int groups_x_len, int groups_y_len, int groups_z_len) { VKContext &context = *VKContext::get(); + context.state_manager_get().apply_bindings(); context.bind_compute_pipeline(); VKCommandBuffer &command_buffer = context.command_buffer_get(); command_buffer.dispatch(groups_x_len, groups_y_len, groups_z_len); diff --git a/source/blender/gpu/vulkan/vk_batch.cc b/source/blender/gpu/vulkan/vk_batch.cc index 44335b3f568..ad725c3ebff 100644 --- a/source/blender/gpu/vulkan/vk_batch.cc +++ b/source/blender/gpu/vulkan/vk_batch.cc @@ -9,6 +9,7 @@ #include "vk_context.hh" #include "vk_index_buffer.hh" +#include "vk_state_manager.hh" #include "vk_vertex_attribute_object.hh" #include "vk_vertex_buffer.hh" @@ -22,7 +23,9 @@ void VKBatch::draw(int vertex_first, int vertex_count, int instance_first, int i /* Finalize graphics pipeline */ VKContext &context = *VKContext::get(); - context.state_manager->apply_state(); + VKStateManager &state_manager = context.state_manager_get(); + state_manager.apply_state(); + state_manager.apply_bindings(); VKVertexAttributeObject vao; vao.update_bindings(context, *this); context.bind_graphics_pipeline(prim_type, vao); diff --git a/source/blender/gpu/vulkan/vk_descriptor_set.cc b/source/blender/gpu/vulkan/vk_descriptor_set.cc index d548bdf9f1c..910d2c6f3ff 100644 --- a/source/blender/gpu/vulkan/vk_descriptor_set.cc +++ b/source/blender/gpu/vulkan/vk_descriptor_set.cc @@ -58,15 +58,6 @@ void VKDescriptorSetTracker::bind_as_ssbo(VKVertexBuffer &buffer, binding.buffer_size = buffer.size_used_get(); } -void VKDescriptorSetTracker::bind_as_texture(VKVertexBuffer &buffer, - const VKDescriptorSet::Location location) -{ - Binding &binding = ensure_location(location); - binding.type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; - binding.vk_buffer = buffer.vk_handle(); - binding.buffer_size = buffer.size_used_get(); -} - void VKDescriptorSetTracker::bind(VKUniformBuffer &buffer, const VKDescriptorSet::Location location) { @@ -103,6 +94,15 @@ void VKDescriptorSetTracker::bind(VKTexture &texture, binding.vk_sampler = sampler.vk_handle(); } +void VKDescriptorSetTracker::bind(VKVertexBuffer &vertex_buffer, + const VKDescriptorSet::Location location) +{ + Binding &binding = ensure_location(location); + binding.type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; + binding.vk_buffer = vertex_buffer.vk_handle(); + binding.buffer_size = vertex_buffer.size_alloc_get(); +} + VKDescriptorSetTracker::Binding &VKDescriptorSetTracker::ensure_location( const VKDescriptorSet::Location location) { diff --git a/source/blender/gpu/vulkan/vk_descriptor_set.hh b/source/blender/gpu/vulkan/vk_descriptor_set.hh index a311af91c3e..a093c5c21f6 100644 --- a/source/blender/gpu/vulkan/vk_descriptor_set.hh +++ b/source/blender/gpu/vulkan/vk_descriptor_set.hh @@ -156,13 +156,14 @@ class VKDescriptorSetTracker : protected VKResourceTracker { VKDescriptorSetTracker(VkDescriptorSetLayout layout) : layout_(layout) {} void bind_as_ssbo(VKVertexBuffer &buffer, VKDescriptorSet::Location location); - void bind_as_texture(VKVertexBuffer &buffer, VKDescriptorSet::Location location); void bind_as_ssbo(VKIndexBuffer &buffer, VKDescriptorSet::Location location); void bind(VKStorageBuffer &buffer, VKDescriptorSet::Location location); void bind(VKUniformBuffer &buffer, VKDescriptorSet::Location location); /* TODO: bind as image */ void image_bind(VKTexture &texture, VKDescriptorSet::Location location); void bind(VKTexture &texture, VKDescriptorSet::Location location, VKSampler &sampler); + /* Bind as uniform texel buffer. */ + void bind(VKVertexBuffer &vertex_buffer, VKDescriptorSet::Location location); /** * Some shaders don't need any descriptor sets so we don't need to bind them. diff --git a/source/blender/gpu/vulkan/vk_immediate.cc b/source/blender/gpu/vulkan/vk_immediate.cc index d5f7d2c1618..8ef30520729 100644 --- a/source/blender/gpu/vulkan/vk_immediate.cc +++ b/source/blender/gpu/vulkan/vk_immediate.cc @@ -9,6 +9,7 @@ #include "vk_immediate.hh" #include "vk_data_conversion.hh" +#include "vk_state_manager.hh" namespace blender::gpu { @@ -47,7 +48,9 @@ void VKImmediate::end() VKContext &context = *VKContext::get(); BLI_assert(context.shader == unwrap(shader)); - context.state_manager->apply_state(); + VKStateManager &state_manager = context.state_manager_get(); + state_manager.apply_state(); + state_manager.apply_bindings(); vertex_attributes_.update_bindings(*this); context.bind_graphics_pipeline(prim_type, vertex_attributes_); vertex_attributes_.bind(context); diff --git a/source/blender/gpu/vulkan/vk_state_manager.cc b/source/blender/gpu/vulkan/vk_state_manager.cc index 5c5b82899d9..2b320abe810 100644 --- a/source/blender/gpu/vulkan/vk_state_manager.cc +++ b/source/blender/gpu/vulkan/vk_state_manager.cc @@ -10,6 +10,7 @@ #include "vk_pipeline.hh" #include "vk_shader.hh" #include "vk_texture.hh" +#include "vk_vertex_buffer.hh" #include "GPU_capabilities.h" @@ -25,6 +26,8 @@ VKStateManager::VKStateManager() texture_bindings_.fill(ImageBinding()); uniform_buffer_bindings_ = Array(max_bindings); uniform_buffer_bindings_.fill(UniformBufferBinding()); + uniform_texel_buffer_bindings_ = Array(max_bindings); + uniform_texel_buffer_bindings_.fill(UniformTexelBufferBinding()); } void VKStateManager::apply_state() @@ -34,7 +37,13 @@ void VKStateManager::apply_state() VKShader &shader = unwrap(*context.shader); VKPipeline &pipeline = shader.pipeline_get(); pipeline.state_manager_get().set_state(state, mutable_state); + } +} +void VKStateManager::apply_bindings() +{ + VKContext &context = *VKContext::get(); + if (context.shader) { for (int binding : IndexRange(image_bindings_.size())) { if (image_bindings_[binding].texture == nullptr) { continue; @@ -42,13 +51,20 @@ void VKStateManager::apply_state() image_bindings_[binding].texture->image_bind(binding); } - for (int binding : IndexRange(image_bindings_.size())) { + for (int binding : IndexRange(texture_bindings_.size())) { if (texture_bindings_[binding].texture == nullptr) { continue; } texture_bindings_[binding].texture->bind(binding, sampler_); } + for (int binding : IndexRange(uniform_texel_buffer_bindings_.size())) { + if (uniform_texel_buffer_bindings_[binding].vertex_buffer == nullptr) { + continue; + } + uniform_texel_buffer_bindings_[binding].vertex_buffer->bind(binding); + } + for (int binding : IndexRange(uniform_buffer_bindings_.size())) { if (uniform_buffer_bindings_[binding].buffer == nullptr) { continue; @@ -141,6 +157,20 @@ void VKStateManager::uniform_buffer_unbind(VKUniformBuffer *uniform_buffer) } } +void VKStateManager::texel_buffer_bind(VKVertexBuffer *vertex_buffer, int slot) +{ + uniform_texel_buffer_bindings_[slot].vertex_buffer = vertex_buffer; +} + +void VKStateManager::texel_buffer_unbind(VKVertexBuffer *vertex_buffer) +{ + for (UniformTexelBufferBinding &binding : uniform_texel_buffer_bindings_) { + if (binding.vertex_buffer == vertex_buffer) { + binding.vertex_buffer = nullptr; + } + } +} + void VKStateManager::texture_unpack_row_length_set(uint len) { texture_unpack_row_length_ = len; diff --git a/source/blender/gpu/vulkan/vk_state_manager.hh b/source/blender/gpu/vulkan/vk_state_manager.hh index a454d74a7ef..7167cf68367 100644 --- a/source/blender/gpu/vulkan/vk_state_manager.hh +++ b/source/blender/gpu/vulkan/vk_state_manager.hh @@ -16,6 +16,7 @@ namespace blender::gpu { class VKTexture; class VKUniformBuffer; +class VKVertexBuffer; class VKStateManager : public StateManager { /* Dummy sampler for now.*/ @@ -29,9 +30,13 @@ class VKStateManager : public StateManager { struct UniformBufferBinding { VKUniformBuffer *buffer = nullptr; }; + struct UniformTexelBufferBinding { + VKVertexBuffer *vertex_buffer = nullptr; + }; Array image_bindings_; Array texture_bindings_; Array uniform_buffer_bindings_; + Array uniform_texel_buffer_bindings_; public: VKStateManager(); @@ -41,6 +46,9 @@ class VKStateManager : public StateManager { void issue_barrier(eGPUBarrier barrier_bits) override; + /** Apply resources to the bindings of the active shader.*/ + void apply_bindings(); + void texture_bind(Texture *tex, GPUSamplerState sampler, int unit) override; void texture_unbind(Texture *tex) override; void texture_unbind_all() override; @@ -52,6 +60,9 @@ class VKStateManager : public StateManager { void uniform_buffer_bind(VKUniformBuffer *uniform_buffer, int slot); void uniform_buffer_unbind(VKUniformBuffer *uniform_buffer); + void texel_buffer_bind(VKVertexBuffer *vertex_buffer, int slot); + void texel_buffer_unbind(VKVertexBuffer *vertex_buffer); + void texture_unpack_row_length_set(uint len) override; /** diff --git a/source/blender/gpu/vulkan/vk_vertex_buffer.cc b/source/blender/gpu/vulkan/vk_vertex_buffer.cc index 29ca3998b58..6109c001b8d 100644 --- a/source/blender/gpu/vulkan/vk_vertex_buffer.cc +++ b/source/blender/gpu/vulkan/vk_vertex_buffer.cc @@ -10,6 +10,7 @@ #include "vk_data_conversion.hh" #include "vk_shader.hh" #include "vk_shader_interface.hh" +#include "vk_state_manager.hh" #include "vk_vertex_buffer.hh" namespace blender::gpu { @@ -37,9 +38,15 @@ void VKVertexBuffer::bind_as_ssbo(uint binding) void VKVertexBuffer::bind_as_texture(uint binding) { - if (!buffer_.is_allocated()) { - allocate(); - } + VKContext &context = *VKContext::get(); + VKStateManager &state_manager = context.state_manager_get(); + state_manager.texel_buffer_bind(this, binding); + should_unbind_ = true; +} + +void VKVertexBuffer::bind(uint binding) +{ + upload_data(); VKContext &context = *VKContext::get(); VKShader *shader = static_cast(context.shader); @@ -47,8 +54,8 @@ void VKVertexBuffer::bind_as_texture(uint binding) const std::optional location = shader_interface.descriptor_set_location( shader::ShaderCreateInfo::Resource::BindType::SAMPLER, binding); - BLI_assert_msg(location, "Locations to texel buffers should always exist."); - shader->pipeline_get().descriptor_set_get().bind_as_texture(*this, *location); + BLI_assert_msg(location, "Locations to Texel buffers should always exist."); + shader->pipeline_get().descriptor_set_get().bind(*this, *location); } void VKVertexBuffer::wrap_handle(uint64_t /*handle*/) @@ -92,6 +99,11 @@ void VKVertexBuffer::resize_data() void VKVertexBuffer::release_data() { + if (should_unbind_) { + VKContext &context = *VKContext::get(); + context.state_manager_get().texel_buffer_unbind(this); + } + MEM_SAFE_FREE(data); } diff --git a/source/blender/gpu/vulkan/vk_vertex_buffer.hh b/source/blender/gpu/vulkan/vk_vertex_buffer.hh index c4aea92e369..ece5564ee55 100644 --- a/source/blender/gpu/vulkan/vk_vertex_buffer.hh +++ b/source/blender/gpu/vulkan/vk_vertex_buffer.hh @@ -16,12 +16,14 @@ class VKTexture; class VKVertexBuffer : public VertBuf { VKBuffer buffer_; + bool should_unbind_ = false; public: ~VKVertexBuffer(); void bind_as_ssbo(uint binding) override; void bind_as_texture(uint binding) override; + void bind(uint binding); void wrap_handle(uint64_t handle) override; void update_sub(uint start, uint len, const void *data) override; -- 2.30.2 From 747a714a928f055b68b72b3b1e0df89753eccdac Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 19 May 2023 14:46:07 +0200 Subject: [PATCH 24/63] Added support for texel buffers --- source/blender/gpu/vulkan/vk_buffer.cc | 2 +- .../blender/gpu/vulkan/vk_descriptor_set.cc | 23 +++++++++++++- .../blender/gpu/vulkan/vk_descriptor_set.hh | 12 +++++--- .../blender/gpu/vulkan/vk_uniform_buffer.cc | 11 +++++-- .../blender/gpu/vulkan/vk_uniform_buffer.hh | 1 + source/blender/gpu/vulkan/vk_vertex_buffer.cc | 30 +++++++++++++++++-- source/blender/gpu/vulkan/vk_vertex_buffer.hh | 8 +++++ 7 files changed, 77 insertions(+), 10 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_buffer.cc b/source/blender/gpu/vulkan/vk_buffer.cc index b7e1fe6563c..5f144c8a9db 100644 --- a/source/blender/gpu/vulkan/vk_buffer.cc +++ b/source/blender/gpu/vulkan/vk_buffer.cc @@ -90,7 +90,7 @@ void VKBuffer::update(const void *data) const const VKDevice &device = VKBackend::get().device_get(); VmaAllocator allocator = device.mem_allocator_get(); - vmaFlushAllocation(allocator, allocation_, 0, VK_WHOLE_SIZE); + vmaFlushAllocation(allocator, allocation_, 0, size_in_bytes()); } void VKBuffer::clear(VKContext &context, uint32_t clear_value) diff --git a/source/blender/gpu/vulkan/vk_descriptor_set.cc b/source/blender/gpu/vulkan/vk_descriptor_set.cc index 910d2c6f3ff..392e1db5da8 100644 --- a/source/blender/gpu/vulkan/vk_descriptor_set.cc +++ b/source/blender/gpu/vulkan/vk_descriptor_set.cc @@ -99,7 +99,7 @@ void VKDescriptorSetTracker::bind(VKVertexBuffer &vertex_buffer, { Binding &binding = ensure_location(location); binding.type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; - binding.vk_buffer = vertex_buffer.vk_handle(); + binding.vk_buffer_view = vertex_buffer.vk_buffer_view_get(); binding.buffer_size = vertex_buffer.size_alloc_get(); } @@ -127,6 +127,7 @@ void VKDescriptorSetTracker::update(VKContext &context) BLI_assert(vk_descriptor_set != VK_NULL_HANDLE); Vector buffer_infos; + buffer_infos.reserve(16); Vector descriptor_writes; for (const Binding &binding : bindings_) { @@ -148,7 +149,27 @@ void VKDescriptorSetTracker::update(VKContext &context) descriptor_writes.append(write_descriptor); } + for (const Binding &binding : bindings_) { + if (!binding.is_texel_buffer()) { + continue; + } + VkDescriptorBufferInfo buffer_info = {}; + buffer_info.buffer = binding.vk_buffer; + buffer_info.range = binding.buffer_size; + buffer_infos.append(buffer_info); + + VkWriteDescriptorSet write_descriptor = {}; + write_descriptor.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write_descriptor.dstSet = vk_descriptor_set; + write_descriptor.dstBinding = binding.location; + write_descriptor.descriptorCount = 1; + write_descriptor.descriptorType = binding.type; + write_descriptor.pTexelBufferView = &binding.vk_buffer_view; + descriptor_writes.append(write_descriptor); + } + Vector image_infos; + image_infos.reserve(16); for (const Binding &binding : bindings_) { if (!binding.is_image()) { continue; diff --git a/source/blender/gpu/vulkan/vk_descriptor_set.hh b/source/blender/gpu/vulkan/vk_descriptor_set.hh index a093c5c21f6..f632a5f643e 100644 --- a/source/blender/gpu/vulkan/vk_descriptor_set.hh +++ b/source/blender/gpu/vulkan/vk_descriptor_set.hh @@ -120,6 +120,8 @@ class VKDescriptorSetTracker : protected VKResourceTracker { VkBuffer vk_buffer = VK_NULL_HANDLE; VkDeviceSize buffer_size = 0; + VkBufferView vk_buffer_view = VK_NULL_HANDLE; + VKTexture *texture = nullptr; VkSampler vk_sampler = VK_NULL_HANDLE; @@ -130,10 +132,12 @@ class VKDescriptorSetTracker : protected VKResourceTracker { bool is_buffer() const { - return ELEM(type, - VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER); + return ELEM(type, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER); + } + + bool is_texel_buffer() const + { + return ELEM(type, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER); } bool is_image() const diff --git a/source/blender/gpu/vulkan/vk_uniform_buffer.cc b/source/blender/gpu/vulkan/vk_uniform_buffer.cc index 840892986a0..654af2f31a4 100644 --- a/source/blender/gpu/vulkan/vk_uniform_buffer.cc +++ b/source/blender/gpu/vulkan/vk_uniform_buffer.cc @@ -13,6 +13,11 @@ namespace blender::gpu { +VKUniformBuffer::~VKUniformBuffer() +{ + unbind(); +} + void VKUniformBuffer::update(const void *data) { if (!buffer_.is_allocated()) { @@ -67,8 +72,10 @@ void VKUniformBuffer::bind_as_ssbo(int slot) void VKUniformBuffer::unbind() { - VKContext &context = *VKContext::get(); - context.state_manager_get().uniform_buffer_unbind(this); + VKContext *context = VKContext::get(); + if (context) { + context->state_manager_get().uniform_buffer_unbind(this); + } } } // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_uniform_buffer.hh b/source/blender/gpu/vulkan/vk_uniform_buffer.hh index 0b8b51bcd26..031f56230e0 100644 --- a/source/blender/gpu/vulkan/vk_uniform_buffer.hh +++ b/source/blender/gpu/vulkan/vk_uniform_buffer.hh @@ -20,6 +20,7 @@ class VKUniformBuffer : public UniformBuf, NonCopyable { public: VKUniformBuffer(int size, const char *name) : UniformBuf(size, name) {} + ~VKUniformBuffer(); void update(const void *data) override; void clear_to_zero() override; diff --git a/source/blender/gpu/vulkan/vk_vertex_buffer.cc b/source/blender/gpu/vulkan/vk_vertex_buffer.cc index 6109c001b8d..5c1ca119b0f 100644 --- a/source/blender/gpu/vulkan/vk_vertex_buffer.cc +++ b/source/blender/gpu/vulkan/vk_vertex_buffer.cc @@ -8,6 +8,7 @@ #include "MEM_guardedalloc.h" #include "vk_data_conversion.hh" +#include "vk_memory.hh" #include "vk_shader.hh" #include "vk_shader_interface.hh" #include "vk_state_manager.hh" @@ -48,6 +49,21 @@ void VKVertexBuffer::bind(uint binding) { upload_data(); + if (vk_buffer_view_ == VK_NULL_HANDLE) { + VkBufferViewCreateInfo buffer_view_info = {}; + eGPUTextureFormat texture_format = to_texture_format(&format); + + buffer_view_info.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO; + buffer_view_info.buffer = buffer_.vk_handle(); + buffer_view_info.format = to_vk_format(texture_format); + buffer_view_info.range = buffer_.size_in_bytes(); + + VK_ALLOCATION_CALLBACKS; + const VKDevice &device = VKBackend::get().device_get(); + vkCreateBufferView( + device.device_get(), &buffer_view_info, vk_allocation_callbacks, &vk_buffer_view_); + } + VKContext &context = *VKContext::get(); VKShader *shader = static_cast(context.shader); const VKShaderInterface &shader_interface = shader->interface_get(); @@ -104,6 +120,13 @@ void VKVertexBuffer::release_data() context.state_manager_get().texel_buffer_unbind(this); } + if (vk_buffer_view_ != VK_NULL_HANDLE) { + VK_ALLOCATION_CALLBACKS; + const VKDevice &device = VKBackend::get().device_get(); + vkDestroyBufferView(device.device_get(), vk_buffer_view_, vk_allocation_callbacks); + vk_buffer_view_ = VK_NULL_HANDLE; + } + MEM_SAFE_FREE(data); } @@ -128,7 +151,9 @@ void VKVertexBuffer::upload_data() if (!buffer_.is_allocated()) { allocate(); } - + if (!ELEM(usage_, GPU_USAGE_STATIC, GPU_USAGE_STREAM, GPU_USAGE_DYNAMIC)) { + return; + } if (flag & GPU_VERTBUF_DATA_DIRTY) { void *data_to_upload = data; if (conversion_needed(format)) { @@ -158,7 +183,8 @@ void VKVertexBuffer::allocate() usage_, static_cast(VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | - VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)); + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | + VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)); debug::object_label(buffer_.vk_handle(), "VertexBuffer"); } diff --git a/source/blender/gpu/vulkan/vk_vertex_buffer.hh b/source/blender/gpu/vulkan/vk_vertex_buffer.hh index ece5564ee55..839d93cd081 100644 --- a/source/blender/gpu/vulkan/vk_vertex_buffer.hh +++ b/source/blender/gpu/vulkan/vk_vertex_buffer.hh @@ -17,6 +17,8 @@ class VKTexture; class VKVertexBuffer : public VertBuf { VKBuffer buffer_; bool should_unbind_ = false; + /** When a vertex buffer is used as a UNIFORM_TEXEL_BUFFER the buffer requires a buffer view. */ + VkBufferView vk_buffer_view_ = VK_NULL_HANDLE; public: ~VKVertexBuffer(); @@ -35,6 +37,12 @@ class VKVertexBuffer : public VertBuf { return buffer_.vk_handle(); } + VkBufferView vk_buffer_view_get() const + { + BLI_assert(vk_buffer_view_ != VK_NULL_HANDLE); + return vk_buffer_view_; + } + protected: void acquire_data() override; void resize_data() override; -- 2.30.2 From 8edef9da7c1a1f14366632e981332ceda8107b10 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 19 May 2023 15:02:53 +0200 Subject: [PATCH 25/63] Make vertex texture binding optional. --- source/blender/gpu/vulkan/vk_vertex_buffer.cc | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_vertex_buffer.cc b/source/blender/gpu/vulkan/vk_vertex_buffer.cc index 5c1ca119b0f..05d42de14e5 100644 --- a/source/blender/gpu/vulkan/vk_vertex_buffer.cc +++ b/source/blender/gpu/vulkan/vk_vertex_buffer.cc @@ -47,6 +47,16 @@ void VKVertexBuffer::bind_as_texture(uint binding) void VKVertexBuffer::bind(uint binding) { + VKContext &context = *VKContext::get(); + VKShader *shader = static_cast(context.shader); + const VKShaderInterface &shader_interface = shader->interface_get(); + const std::optional location = + shader_interface.descriptor_set_location( + shader::ShaderCreateInfo::Resource::BindType::SAMPLER, binding); + if (!location) { + return; + } + upload_data(); if (vk_buffer_view_ == VK_NULL_HANDLE) { @@ -64,13 +74,6 @@ void VKVertexBuffer::bind(uint binding) device.device_get(), &buffer_view_info, vk_allocation_callbacks, &vk_buffer_view_); } - VKContext &context = *VKContext::get(); - VKShader *shader = static_cast(context.shader); - const VKShaderInterface &shader_interface = shader->interface_get(); - const std::optional location = - shader_interface.descriptor_set_location( - shader::ShaderCreateInfo::Resource::BindType::SAMPLER, binding); - BLI_assert_msg(location, "Locations to Texel buffers should always exist."); shader->pipeline_get().descriptor_set_get().bind(*this, *location); } -- 2.30.2 From 84298f1f4562a11e58189c6e3af8d088962d94ec Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 19 May 2023 15:32:08 +0200 Subject: [PATCH 26/63] Combine textures and texel buffers. --- .../blender/gpu/vulkan/vk_descriptor_set.cc | 8 --- source/blender/gpu/vulkan/vk_shader.cc | 1 + source/blender/gpu/vulkan/vk_state_manager.cc | 52 ++++++++----------- source/blender/gpu/vulkan/vk_state_manager.hh | 11 ++-- 4 files changed, 28 insertions(+), 44 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_descriptor_set.cc b/source/blender/gpu/vulkan/vk_descriptor_set.cc index 392e1db5da8..52369302ecd 100644 --- a/source/blender/gpu/vulkan/vk_descriptor_set.cc +++ b/source/blender/gpu/vulkan/vk_descriptor_set.cc @@ -153,11 +153,6 @@ void VKDescriptorSetTracker::update(VKContext &context) if (!binding.is_texel_buffer()) { continue; } - VkDescriptorBufferInfo buffer_info = {}; - buffer_info.buffer = binding.vk_buffer; - buffer_info.range = binding.buffer_size; - buffer_infos.append(buffer_info); - VkWriteDescriptorSet write_descriptor = {}; write_descriptor.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; write_descriptor.dstSet = vk_descriptor_set; @@ -192,9 +187,6 @@ void VKDescriptorSetTracker::update(VKContext &context) descriptor_writes.append(write_descriptor); } - BLI_assert_msg(image_infos.size() + buffer_infos.size() == descriptor_writes.size(), - "Not all changes have been converted to a write descriptor. Check " - "`Binding::is_buffer` and `Binding::is_image`."); const VKDevice &device = VKBackend::get().device_get(); vkUpdateDescriptorSets( device.device_get(), descriptor_writes.size(), descriptor_writes.data(), 0, nullptr); diff --git a/source/blender/gpu/vulkan/vk_shader.cc b/source/blender/gpu/vulkan/vk_shader.cc index 805367e6de5..c12c32230e6 100644 --- a/source/blender/gpu/vulkan/vk_shader.cc +++ b/source/blender/gpu/vulkan/vk_shader.cc @@ -913,6 +913,7 @@ bool VKShader::finalize_descriptor_set_layouts(VkDevice vk_device, { return false; }; + debug::object_label(layout_, name_get()); return true; } diff --git a/source/blender/gpu/vulkan/vk_state_manager.cc b/source/blender/gpu/vulkan/vk_state_manager.cc index 2b320abe810..b828a513956 100644 --- a/source/blender/gpu/vulkan/vk_state_manager.cc +++ b/source/blender/gpu/vulkan/vk_state_manager.cc @@ -22,12 +22,10 @@ VKStateManager::VKStateManager() constexpr int max_bindings = 16; image_bindings_ = Array(max_bindings); image_bindings_.fill(ImageBinding()); - texture_bindings_ = Array(max_bindings); - texture_bindings_.fill(ImageBinding()); + texture_bindings_ = Array(max_bindings); + texture_bindings_.fill(TextureBinding()); uniform_buffer_bindings_ = Array(max_bindings); uniform_buffer_bindings_.fill(UniformBufferBinding()); - uniform_texel_buffer_bindings_ = Array(max_bindings); - uniform_texel_buffer_bindings_.fill(UniformTexelBufferBinding()); } void VKStateManager::apply_state() @@ -45,32 +43,25 @@ void VKStateManager::apply_bindings() VKContext &context = *VKContext::get(); if (context.shader) { for (int binding : IndexRange(image_bindings_.size())) { - if (image_bindings_[binding].texture == nullptr) { - continue; + if (image_bindings_[binding].texture) { + image_bindings_[binding].texture->image_bind(binding); } - image_bindings_[binding].texture->image_bind(binding); } for (int binding : IndexRange(texture_bindings_.size())) { - if (texture_bindings_[binding].texture == nullptr) { - continue; + if (texture_bindings_[binding].texture) { + texture_bindings_[binding].texture->bind(binding, sampler_); } - texture_bindings_[binding].texture->bind(binding, sampler_); - } - - for (int binding : IndexRange(uniform_texel_buffer_bindings_.size())) { - if (uniform_texel_buffer_bindings_[binding].vertex_buffer == nullptr) { - continue; + else if (texture_bindings_[binding].vertex_buffer) { + texture_bindings_[binding].vertex_buffer->bind(binding); } - uniform_texel_buffer_bindings_[binding].vertex_buffer->bind(binding); } for (int binding : IndexRange(uniform_buffer_bindings_.size())) { - if (uniform_buffer_bindings_[binding].buffer == nullptr) { - continue; + if (uniform_buffer_bindings_[binding].buffer) { + uniform_buffer_bindings_[binding].buffer->bind( + binding, shader::ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER); } - uniform_buffer_bindings_[binding].buffer->bind( - binding, shader::ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER); } } } @@ -97,12 +88,13 @@ void VKStateManager::texture_bind(Texture *tex, GPUSamplerState /*sampler*/, int { VKTexture *texture = unwrap(tex); texture_bindings_[unit].texture = texture; + texture_bindings_[unit].vertex_buffer = nullptr; } void VKStateManager::texture_unbind(Texture *tex) { VKTexture *texture = unwrap(tex); - for (ImageBinding &binding : texture_bindings_) { + for (TextureBinding &binding : texture_bindings_) { if (binding.texture == texture) { binding.texture = nullptr; } @@ -111,10 +103,8 @@ void VKStateManager::texture_unbind(Texture *tex) void VKStateManager::texture_unbind_all() { - for (ImageBinding &binding : texture_bindings_) { - if (binding.texture != nullptr) { - binding.texture = nullptr; - } + for (TextureBinding &binding : texture_bindings_) { + binding.texture = nullptr; } } @@ -136,10 +126,8 @@ void VKStateManager::image_unbind(Texture *tex) void VKStateManager::image_unbind_all() { - for (ImageBinding &binding : texture_bindings_) { - if (binding.texture != nullptr) { - binding.texture = nullptr; - } + for (ImageBinding &binding : image_bindings_) { + binding.texture = nullptr; } } @@ -159,14 +147,16 @@ void VKStateManager::uniform_buffer_unbind(VKUniformBuffer *uniform_buffer) void VKStateManager::texel_buffer_bind(VKVertexBuffer *vertex_buffer, int slot) { - uniform_texel_buffer_bindings_[slot].vertex_buffer = vertex_buffer; + texture_bindings_[slot].vertex_buffer = vertex_buffer; + texture_bindings_[slot].texture = nullptr; } void VKStateManager::texel_buffer_unbind(VKVertexBuffer *vertex_buffer) { - for (UniformTexelBufferBinding &binding : uniform_texel_buffer_bindings_) { + for (TextureBinding &binding : texture_bindings_) { if (binding.vertex_buffer == vertex_buffer) { binding.vertex_buffer = nullptr; + binding.texture = nullptr; } } } diff --git a/source/blender/gpu/vulkan/vk_state_manager.hh b/source/blender/gpu/vulkan/vk_state_manager.hh index 7167cf68367..47609f5c03e 100644 --- a/source/blender/gpu/vulkan/vk_state_manager.hh +++ b/source/blender/gpu/vulkan/vk_state_manager.hh @@ -24,19 +24,20 @@ class VKStateManager : public StateManager { uint texture_unpack_row_length_ = 0; + struct TextureBinding { + VKTexture *texture = nullptr; + /* bufferTextures and samplers share the same namespace. */ + VKVertexBuffer *vertex_buffer = nullptr; + }; struct ImageBinding { VKTexture *texture = nullptr; }; struct UniformBufferBinding { VKUniformBuffer *buffer = nullptr; }; - struct UniformTexelBufferBinding { - VKVertexBuffer *vertex_buffer = nullptr; - }; Array image_bindings_; - Array texture_bindings_; + Array texture_bindings_; Array uniform_buffer_bindings_; - Array uniform_texel_buffer_bindings_; public: VKStateManager(); -- 2.30.2 From e17eed22aac672fc29b8103f7bb15f4f0d8aec0e Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 22 May 2023 10:57:17 +0200 Subject: [PATCH 27/63] Fix compute pass hair/curve drawing --- source/blender/draw/intern/draw_curves.cc | 6 ++++++ source/blender/gpu/vulkan/vk_backend.cc | 3 +++ 2 files changed, 9 insertions(+) diff --git a/source/blender/draw/intern/draw_curves.cc b/source/blender/draw/intern/draw_curves.cc index 46802f8f4f7..3992cd0f0c7 100644 --- a/source/blender/draw/intern/draw_curves.cc +++ b/source/blender/draw/intern/draw_curves.cc @@ -320,10 +320,16 @@ DRWShadingGroup *DRW_shgroup_curves_create_sub(Object *object, /* Fix issue with certain driver not drawing anything if there is no texture bound to * "ac", "au", "u" or "c". */ + DRW_shgroup_buffer_texture(shgrp, "u", g_dummy_vbo); + DRW_shgroup_buffer_texture(shgrp, "au", g_dummy_vbo); + DRW_shgroup_buffer_texture(shgrp, "c", g_dummy_vbo); + DRW_shgroup_buffer_texture(shgrp, "ac", g_dummy_vbo); + /* DRW_shgroup_uniform_texture(shgrp, "u", g_dummy_texture); DRW_shgroup_uniform_texture(shgrp, "au", g_dummy_texture); DRW_shgroup_uniform_texture(shgrp, "c", g_dummy_texture); DRW_shgroup_uniform_texture(shgrp, "ac", g_dummy_texture); + */ /* TODO: Generalize radius implementation for curves data type. */ float hair_rad_shape = 0.0f; diff --git a/source/blender/gpu/vulkan/vk_backend.cc b/source/blender/gpu/vulkan/vk_backend.cc index 499d807b37a..2d21df57f95 100644 --- a/source/blender/gpu/vulkan/vk_backend.cc +++ b/source/blender/gpu/vulkan/vk_backend.cc @@ -159,6 +159,9 @@ void VKBackend::capabilities_init() GCaps.compute_shader_support = true; GCaps.shader_storage_buffer_objects_support = true; GCaps.shader_image_load_store_support = true; + /* Although not used or implemented, it is required to make sure that curve/hair drawing uses the + * right branch. This should be fixed in the draw manager. */ + GCaps.transform_feedback_support = true; GCaps.max_texture_size = max_ii(limits.maxImageDimension1D, limits.maxImageDimension2D); GCaps.max_texture_3d_size = limits.maxImageDimension3D; -- 2.30.2 From 26c1d55e6bc56ab530892962e989fd2b051d3275 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 23 May 2023 15:36:51 +0200 Subject: [PATCH 28/63] Revert enabling transform feedback. --- source/blender/gpu/vulkan/vk_backend.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_backend.cc b/source/blender/gpu/vulkan/vk_backend.cc index 2d21df57f95..499d807b37a 100644 --- a/source/blender/gpu/vulkan/vk_backend.cc +++ b/source/blender/gpu/vulkan/vk_backend.cc @@ -159,9 +159,6 @@ void VKBackend::capabilities_init() GCaps.compute_shader_support = true; GCaps.shader_storage_buffer_objects_support = true; GCaps.shader_image_load_store_support = true; - /* Although not used or implemented, it is required to make sure that curve/hair drawing uses the - * right branch. This should be fixed in the draw manager. */ - GCaps.transform_feedback_support = true; GCaps.max_texture_size = max_ii(limits.maxImageDimension1D, limits.maxImageDimension2D); GCaps.max_texture_3d_size = limits.maxImageDimension3D; -- 2.30.2 From 5b9fc072eb9221db329fd9796e8b393db7328820 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 23 May 2023 15:37:05 +0200 Subject: [PATCH 29/63] Enable primitive restart --- source/blender/gpu/vulkan/vk_pipeline.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/gpu/vulkan/vk_pipeline.cc b/source/blender/gpu/vulkan/vk_pipeline.cc index 89c71fef2ba..7f1d193d07a 100644 --- a/source/blender/gpu/vulkan/vk_pipeline.cc +++ b/source/blender/gpu/vulkan/vk_pipeline.cc @@ -156,6 +156,8 @@ void VKPipeline::finalize(VKContext &context, VkPipelineInputAssemblyStateCreateInfo pipeline_input_assembly = {}; pipeline_input_assembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; pipeline_input_assembly.topology = to_vk_primitive_topology(prim_type); + pipeline_input_assembly.primitiveRestartEnable = + ELEM(prim_type, GPU_PRIM_TRIS, GPU_PRIM_LINES, GPU_PRIM_POINTS) ? VK_FALSE : VK_TRUE; pipeline_create_info.pInputAssemblyState = &pipeline_input_assembly; /* Viewport state. */ -- 2.30.2 From 6e0de2095bb0752c226ebce34c20ad55601e5b88 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 25 May 2023 11:59:30 +0200 Subject: [PATCH 30/63] Show gpu backend selector in user pref. --- scripts/startup/bl_ui/space_userpref.py | 6 ------ source/blender/makesrna/intern/CMakeLists.txt | 8 ++++++++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/scripts/startup/bl_ui/space_userpref.py b/scripts/startup/bl_ui/space_userpref.py index 0bd6a099cb7..4f7a511c09d 100644 --- a/scripts/startup/bl_ui/space_userpref.py +++ b/scripts/startup/bl_ui/space_userpref.py @@ -610,12 +610,6 @@ class USERPREF_PT_system_cycles_devices(SystemPanel, CenterAlignMixIn, Panel): class USERPREF_PT_system_gpu_backend(SystemPanel, CenterAlignMixIn, Panel): bl_label = "GPU Backend" - @classmethod - def poll(cls, _context): - # Only for Apple so far - import sys - return sys.platform == "darwin" - def draw_centered(self, context, layout): import gpu prefs = context.preferences diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt index 04b3b1389ed..cdc41c5dc13 100644 --- a/source/blender/makesrna/intern/CMakeLists.txt +++ b/source/blender/makesrna/intern/CMakeLists.txt @@ -377,6 +377,14 @@ if(WITH_XR_OPENXR) add_definitions(-DWITH_XR_OPENXR) endif() +if(WITH_VULKAN_METAL) + add_definitions(-DWITH_VULKAN_METAL) +endif() + +if(WITH_VULKAN_BACKEND) + add_definitions(-DWITH_VULKAN_BACKEND) +endif() + if(WITH_GMP) add_definitions(-DWITH_GMP) endif() -- 2.30.2 From a5c92991a73a553016960ca96309170af684db31 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 25 May 2023 16:46:44 +0200 Subject: [PATCH 31/63] Add workaround for devices that don't support 24bit depth formats. --- source/blender/gpu/vulkan/vk_backend.cc | 14 +++++++++++++- source/blender/gpu/vulkan/vk_backend.hh | 3 ++- source/blender/gpu/vulkan/vk_context.cc | 1 + source/blender/gpu/vulkan/vk_context.hh | 5 +++++ source/blender/gpu/vulkan/vk_device.cc | 4 +++- source/blender/gpu/vulkan/vk_device.hh | 20 ++++++++++++++++++++ source/blender/gpu/vulkan/vk_texture.cc | 8 ++++++++ 7 files changed, 52 insertions(+), 3 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_backend.cc b/source/blender/gpu/vulkan/vk_backend.cc index f2da30467b3..10f05326499 100644 --- a/source/blender/gpu/vulkan/vk_backend.cc +++ b/source/blender/gpu/vulkan/vk_backend.cc @@ -72,6 +72,16 @@ void VKBackend::platform_init(const VKDevice &device) driver_version.c_str()); } +void VKBackend::detect_workarounds(VKDevice &device) +{ + device.workarounds_.depth_component_24 = false; + + /* */ + if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY)) { + device.workarounds_.depth_component_24 = true; + } +} + void VKBackend::platform_exit() { GPG.clear(); @@ -173,7 +183,7 @@ shaderc::Compiler &VKBackend::get_shaderc_compiler() return shaderc_compiler_; } -void VKBackend::capabilities_init(const VKDevice &device) +void VKBackend::capabilities_init(VKDevice &device) { const VkPhysicalDeviceProperties &properties = device.physical_device_properties_get(); const VkPhysicalDeviceLimits &limits = properties.limits; @@ -204,6 +214,8 @@ void VKBackend::capabilities_init(const VKDevice &device) GCaps.max_varying_floats = limits.maxVertexOutputComponents; GCaps.max_shader_storage_buffer_bindings = limits.maxPerStageDescriptorStorageBuffers; GCaps.max_compute_shader_storage_blocks = limits.maxPerStageDescriptorStorageBuffers; + + detect_workarounds(device); } } // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_backend.hh b/source/blender/gpu/vulkan/vk_backend.hh index 39feeb952a0..a259746585b 100644 --- a/source/blender/gpu/vulkan/vk_backend.hh +++ b/source/blender/gpu/vulkan/vk_backend.hh @@ -87,9 +87,10 @@ class VKBackend : public GPUBackend { } static void platform_init(const VKDevice &device); - static void capabilities_init(const VKDevice &device); + static void capabilities_init(VKDevice &device); private: + static void detect_workarounds(VKDevice &device); static void platform_init(); static void platform_exit(); diff --git a/source/blender/gpu/vulkan/vk_context.cc b/source/blender/gpu/vulkan/vk_context.cc index a167fa2402c..061827ea223 100644 --- a/source/blender/gpu/vulkan/vk_context.cc +++ b/source/blender/gpu/vulkan/vk_context.cc @@ -211,4 +211,5 @@ void VKContext::bind_graphics_pipeline(const GPUPrimType prim_type, /** \} */ + } // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_context.hh b/source/blender/gpu/vulkan/vk_context.hh index 817b5285bd7..8041fbcc5fe 100644 --- a/source/blender/gpu/vulkan/vk_context.hh +++ b/source/blender/gpu/vulkan/vk_context.hh @@ -25,6 +25,9 @@ class VKContext : public Context, NonCopyable { void *ghost_context_; + /** Workarounds. */ + static bool component_24_workaround; + public: VKContext(void *ghost_window, void *ghost_context); virtual ~VKContext(); @@ -69,6 +72,8 @@ class VKContext : public Context, NonCopyable { const VKStateManager &state_manager_get() const; VKStateManager &state_manager_get(); + + static bool get_component_24_workaround(); }; } // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_device.cc b/source/blender/gpu/vulkan/vk_device.cc index bd97850debd..c8379681066 100644 --- a/source/blender/gpu/vulkan/vk_device.cc +++ b/source/blender/gpu/vulkan/vk_device.cc @@ -87,7 +87,8 @@ void VKDevice::init_descriptor_pools() constexpr int32_t PCI_ID_NVIDIA = 0x10de; constexpr int32_t PCI_ID_INTEL = 0x8086; -constexpr int32_t PCI_ID_AMD = 0x1022; +constexpr int32_t PCI_ID_AMD = 0x1002; +constexpr int32_t PCI_ID_ATI = 0x1022; eGPUDeviceType VKDevice::device_type() const { @@ -103,6 +104,7 @@ eGPUDeviceType VKDevice::device_type() const case PCI_ID_INTEL: return GPU_DEVICE_INTEL; case PCI_ID_AMD: + case PCI_ID_ATI: return GPU_DEVICE_ATI; default: break; diff --git a/source/blender/gpu/vulkan/vk_device.hh b/source/blender/gpu/vulkan/vk_device.hh index d386da44767..3e9eaea94ac 100644 --- a/source/blender/gpu/vulkan/vk_device.hh +++ b/source/blender/gpu/vulkan/vk_device.hh @@ -14,6 +14,7 @@ #include "vk_descriptor_pools.hh" namespace blender::gpu { +class VKBackend; class VKDevice : public NonCopyable { private: @@ -34,6 +35,12 @@ class VKDevice : public NonCopyable { /** Functions of vk_ext_debugutils for this device/instance. */ debug::VKDebuggingTools debugging_tools_; + /* Workarounds */ + struct { + bool depth_component_24 = false; + + } workarounds_; + public: VkPhysicalDevice physical_device_get() const { @@ -94,11 +101,24 @@ class VKDevice : public NonCopyable { std::string vendor_name() const; std::string driver_version() const; + /** + * Some devices don't support `GPU_DEPTH_COMPONENT_24` texture formats. + * + * Check with this function if the workaround should be used to work around this issue. + */ + bool get_component_24_workaround() const + { + return workarounds_.depth_component_24; + } + private: void init_physical_device_properties(); void init_debug_callbacks(); void init_memory_allocator(); void init_descriptor_pools(); + + /* During initialization the backend requires access to update the workarounds. */ + friend VKBackend; }; } // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_texture.cc b/source/blender/gpu/vulkan/vk_texture.cc index 5999ee2f520..04e4384e882 100644 --- a/source/blender/gpu/vulkan/vk_texture.cc +++ b/source/blender/gpu/vulkan/vk_texture.cc @@ -218,6 +218,14 @@ bool VKTexture::init_internal() * at this moment, so we cannot initialize here. The initialization is postponed until the * allocation of the texture on the device. */ + const VKDevice &device = VKBackend::get().device_get(); + if (format_ == GPU_DEPTH_COMPONENT24 && device.get_component_24_workaround()) { + format_ = GPU_DEPTH_COMPONENT32F; + } + if (format_ == GPU_DEPTH24_STENCIL8 && device.get_component_24_workaround()) { + format_ = GPU_DEPTH32F_STENCIL8; + } + /* TODO: return false when texture format isn't supported. */ return true; } -- 2.30.2 From 4ecf13457f294487db7d3587c66d77b2cb3af177 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 25 May 2023 17:33:59 +0200 Subject: [PATCH 32/63] Enable test cases that pass. --- source/blender/gpu/tests/texture_test.cc | 6 +-- .../blender/gpu/vulkan/vk_data_conversion.cc | 49 ++++++++++++++----- source/blender/gpu/vulkan/vk_vertex_buffer.cc | 6 +-- 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/source/blender/gpu/tests/texture_test.cc b/source/blender/gpu/tests/texture_test.cc index 91f41b97ee3..1682a4a40da 100644 --- a/source/blender/gpu/tests/texture_test.cc +++ b/source/blender/gpu/tests/texture_test.cc @@ -396,13 +396,11 @@ static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB9_E5() GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB9_E5); #endif -#if RUN_UNSUPPORTED static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_DEPTH_COMPONENT32F() { texture_create_upload_read_with_bias(0.0f); } GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_DEPTH_COMPONENT32F); -#endif static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_DEPTH_COMPONENT24() { @@ -590,7 +588,6 @@ static void test_texture_roundtrip__GPU_DATA_UINT__GPU_R32UI() } GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_R32UI); -#if RUN_UNSUPPORTED static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH32F_STENCIL8() { texture_create_upload_read(); @@ -602,7 +599,6 @@ static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH24_STENCIL8() texture_create_upload_read(); } GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH24_STENCIL8); -#endif #if RUN_UNSUPPORTED static void test_texture_roundtrip__GPU_DATA_UINT__GPU_RGB8UI() @@ -630,13 +626,13 @@ static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT24() } GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT24); -#if RUN_COMPONENT_UNIMPLEMENTED static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT32F() { texture_create_upload_read(); } GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT32F); +#if RUN_COMPONENT_UNIMPLEMENTED static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT16() { texture_create_upload_read(); diff --git a/source/blender/gpu/vulkan/vk_data_conversion.cc b/source/blender/gpu/vulkan/vk_data_conversion.cc index 68054dfae60..ec9da42a8ca 100644 --- a/source/blender/gpu/vulkan/vk_data_conversion.cc +++ b/source/blender/gpu/vulkan/vk_data_conversion.cc @@ -31,6 +31,9 @@ enum class ConversionType { FLOAT_TO_SNORM16, SNORM16_TO_FLOAT, + FLOAT_TO_UNORM32, + UNORM32_TO_FLOAT, + UI32_TO_UI16, UI16_TO_UI32, @@ -252,6 +255,10 @@ static ConversionType type_of_conversion_uint(eGPUTextureFormat device_format) case GPU_R8UI: return ConversionType::UI32_TO_UI8; + case GPU_DEPTH_COMPONENT32F: + case GPU_DEPTH32F_STENCIL8: + return ConversionType::UNORM32_TO_FLOAT; + case GPU_RGBA8I: case GPU_RGBA8: case GPU_RGBA16I: @@ -276,7 +283,6 @@ static ConversionType type_of_conversion_uint(eGPUTextureFormat device_format) case GPU_RGB10_A2: case GPU_RGB10_A2UI: case GPU_R11F_G11F_B10F: - case GPU_DEPTH32F_STENCIL8: case GPU_DEPTH24_STENCIL8: case GPU_SRGB8_A8: case GPU_RGBA8_SNORM: @@ -304,7 +310,6 @@ static ConversionType type_of_conversion_uint(eGPUTextureFormat device_format) case GPU_RGBA8_DXT5: case GPU_SRGB8: case GPU_RGB9_E5: - case GPU_DEPTH_COMPONENT32F: case GPU_DEPTH_COMPONENT16: return ConversionType::UNSUPPORTED; } @@ -522,6 +527,7 @@ static ConversionType reversed(ConversionType type) CASE_PAIR(FLOAT, SNORM8) CASE_PAIR(FLOAT, UNORM16) CASE_PAIR(FLOAT, SNORM16) + CASE_PAIR(FLOAT, UNORM32) CASE_PAIR(UI32, UI16) CASE_PAIR(I32, I16) CASE_PAIR(UI32, UI8) @@ -630,6 +636,7 @@ template struct SignedNormalized { template struct UnsignedNormalized { static_assert(std::is_same() || std::is_same() || + std::is_same() || std::is_same()); InnerType value; @@ -643,15 +650,24 @@ template struct UnsignedNormalized { } } - static constexpr int32_t scalar() + static constexpr uint32_t scalar() { - - return (1 << (used_byte_size() * 8)) - 1; + if constexpr (std::is_same()) { + return (1 << (used_byte_size() * 8)) - 1; + } + else { + return std::numeric_limits::max(); + } } - static constexpr int32_t max() + static constexpr uint32_t max() { - return ((1 << (used_byte_size() * 8)) - 1); + if constexpr (std::is_same()) { + return (1 << (used_byte_size() * 8)) - 1; + } + else { + return std::numeric_limits::max(); + } } }; @@ -672,15 +688,15 @@ template void convert(F32 &dst, const SignedNormalized void convert(UnsignedNormalized &dst, const F32 &src) { - static constexpr int32_t scalar = UnsignedNormalized::scalar(); - static constexpr int32_t max = scalar; - dst.value = (clamp_i((src.value * scalar), 0, max)); + static constexpr uint32_t scalar = UnsignedNormalized::scalar(); + static constexpr uint32_t max = scalar; + dst.value = (clamp_f((src.value * scalar), 0, max)); } template void convert(F32 &dst, const UnsignedNormalized &src) { - static constexpr int32_t scalar = UnsignedNormalized::scalar(); - dst.value = float(int32_t(src.value)) / scalar; + static constexpr uint32_t scalar = UnsignedNormalized::scalar(); + dst.value = float(uint32_t(src.value)) / scalar; } /* Copy the contents of src to dst with out performing any actual conversion. */ @@ -858,6 +874,15 @@ static void convert_buffer(void *dst_memory, dst_memory, src_memory, buffer_size, device_format); break; + case ConversionType::FLOAT_TO_UNORM32: + convert_per_component, F32>( + dst_memory, src_memory, buffer_size, device_format); + break; + case ConversionType::UNORM32_TO_FLOAT: + convert_per_component>( + dst_memory, src_memory, buffer_size, device_format); + break; + case ConversionType::FLOAT_TO_HALF: convert_per_component(dst_memory, src_memory, buffer_size, device_format); break; diff --git a/source/blender/gpu/vulkan/vk_vertex_buffer.cc b/source/blender/gpu/vulkan/vk_vertex_buffer.cc index 05d42de14e5..310bd39a0ee 100644 --- a/source/blender/gpu/vulkan/vk_vertex_buffer.cc +++ b/source/blender/gpu/vulkan/vk_vertex_buffer.cc @@ -118,9 +118,9 @@ void VKVertexBuffer::resize_data() void VKVertexBuffer::release_data() { - if (should_unbind_) { - VKContext &context = *VKContext::get(); - context.state_manager_get().texel_buffer_unbind(this); + VKContext *context = VKContext::get(); + if (should_unbind_ && context) { + context->state_manager_get().texel_buffer_unbind(this); } if (vk_buffer_view_ != VK_NULL_HANDLE) { -- 2.30.2 From 4a10381faad6ca79f74d5812176d7065e5de6670 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 30 May 2023 11:38:01 +0200 Subject: [PATCH 33/63] Indirect drawing (not working) --- .../vk_mem_alloc_impl.cc | 3 + source/blender/gpu/vulkan/vk_batch.cc | 56 +++++++++++++------ source/blender/gpu/vulkan/vk_batch.hh | 3 + .../blender/gpu/vulkan/vk_command_buffer.cc | 25 ++++++++- .../blender/gpu/vulkan/vk_command_buffer.hh | 11 +++- source/blender/gpu/vulkan/vk_device.hh | 1 + .../blender/gpu/vulkan/vk_storage_buffer.cc | 6 +- .../blender/gpu/vulkan/vk_storage_buffer.hh | 5 ++ source/blender/gpu/vulkan/vk_texture.cc | 2 + 9 files changed, 92 insertions(+), 20 deletions(-) diff --git a/extern/vulkan_memory_allocator/vk_mem_alloc_impl.cc b/extern/vulkan_memory_allocator/vk_mem_alloc_impl.cc index 4542d19b132..265a4b6e25d 100644 --- a/extern/vulkan_memory_allocator/vk_mem_alloc_impl.cc +++ b/extern/vulkan_memory_allocator/vk_mem_alloc_impl.cc @@ -8,5 +8,8 @@ #endif #define VMA_IMPLEMENTATION +#ifdef DEBUG +#define VMA_ASSERT(test) +#endif #include "vk_mem_alloc.h" diff --git a/source/blender/gpu/vulkan/vk_batch.cc b/source/blender/gpu/vulkan/vk_batch.cc index ad725c3ebff..4d97fed0a28 100644 --- a/source/blender/gpu/vulkan/vk_batch.cc +++ b/source/blender/gpu/vulkan/vk_batch.cc @@ -10,12 +10,12 @@ #include "vk_context.hh" #include "vk_index_buffer.hh" #include "vk_state_manager.hh" +#include "vk_storage_buffer.hh" #include "vk_vertex_attribute_object.hh" #include "vk_vertex_buffer.hh" namespace blender::gpu { - -void VKBatch::draw(int vertex_first, int vertex_count, int instance_first, int instance_count) +void VKBatch::draw_setup() { /* Currently the pipeline is rebuild on each draw command. Clearing the dirty flag for * consistency with the internals of GPU module. */ @@ -37,29 +37,53 @@ void VKBatch::draw(int vertex_first, int vertex_count, int instance_first, int i if (draw_indexed) { index_buffer->upload_data(); index_buffer->bind(context); - context.command_buffer_get().draw(index_buffer->index_len_get(), - instance_count, - index_buffer->index_start_get(), - vertex_first, - instance_first); + } +} + +void VKBatch::draw(int vertex_first, int vertex_count, int instance_first, int instance_count) +{ + draw_setup(); + + VKContext &context = *VKContext::get(); + VKCommandBuffer &command_buffer = context.command_buffer_get(); + VKIndexBuffer *index_buffer = index_buffer_get(); + const bool draw_indexed = index_buffer != nullptr; + if (draw_indexed) { + command_buffer.draw_indexed(index_buffer->index_len_get(), + instance_count, + index_buffer->index_start_get(), + vertex_first, + instance_first); } else { - context.command_buffer_get().draw(vertex_first, vertex_count, instance_first, instance_count); + command_buffer.draw(vertex_first, vertex_count, instance_first, instance_count); } - - context.command_buffer_get().submit(); + command_buffer.submit(); } -void VKBatch::draw_indirect(GPUStorageBuf * /*indirect_buf*/, intptr_t /*offset*/) +void VKBatch::draw_indirect(GPUStorageBuf *indirect_buf, intptr_t offset) { - NOT_YET_IMPLEMENTED; + multi_draw_indirect(indirect_buf, 1, offset, 0); } -void VKBatch::multi_draw_indirect(GPUStorageBuf * /*indirect_buf*/, - int /*count*/, - intptr_t /*offset*/, - intptr_t /*stride*/) +void VKBatch::multi_draw_indirect(GPUStorageBuf *indirect_buf, + int count, + intptr_t offset, + intptr_t stride) { + draw_setup(); + + VKStorageBuffer &indirect_buffer = *unwrap(unwrap(indirect_buf)); + VKContext &context = *VKContext::get(); + const bool draw_indexed = index_buffer_get() != nullptr; + VKCommandBuffer &command_buffer = context.command_buffer_get(); + if (draw_indexed) { + command_buffer.draw_indexed_indirect(indirect_buffer, offset, count, stride); + } + else { + command_buffer.draw_indirect(indirect_buffer, offset, count, stride); + } + command_buffer.submit(); } VKVertexBuffer *VKBatch::vertex_buffer_get(int index) diff --git a/source/blender/gpu/vulkan/vk_batch.hh b/source/blender/gpu/vulkan/vk_batch.hh index 59fcae6d81d..5ae6faa3eea 100644 --- a/source/blender/gpu/vulkan/vk_batch.hh +++ b/source/blender/gpu/vulkan/vk_batch.hh @@ -25,6 +25,9 @@ class VKBatch : public Batch { VKVertexBuffer *vertex_buffer_get(int index); VKVertexBuffer *instance_buffer_get(int index); VKIndexBuffer *index_buffer_get(); + + private: + void draw_setup(); }; } // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_command_buffer.cc b/source/blender/gpu/vulkan/vk_command_buffer.cc index 8e4c2e34e63..b4cf9a422e7 100644 --- a/source/blender/gpu/vulkan/vk_command_buffer.cc +++ b/source/blender/gpu/vulkan/vk_command_buffer.cc @@ -12,6 +12,7 @@ #include "vk_index_buffer.hh" #include "vk_memory.hh" #include "vk_pipeline.hh" +#include "vk_storage_buffer.hh" #include "vk_texture.hh" #include "vk_vertex_buffer.hh" @@ -244,7 +245,7 @@ void VKCommandBuffer::draw(int v_first, int v_count, int i_first, int i_count) state.draw_counts++; } -void VKCommandBuffer::draw( +void VKCommandBuffer::draw_indexed( int index_count, int instance_count, int first_index, int vertex_offset, int first_instance) { validate_framebuffer_exists(); @@ -254,6 +255,28 @@ void VKCommandBuffer::draw( state.draw_counts++; } +void VKCommandBuffer::draw_indirect(const VKStorageBuffer &buffer, + VkDeviceSize offset, + uint32_t draw_count, + uint32_t stride) +{ + validate_framebuffer_exists(); + ensure_active_framebuffer(); + vkCmdDrawIndirect(vk_command_buffer_, buffer.vk_handle(), offset, draw_count, stride); + state.draw_counts++; +} + +void VKCommandBuffer::draw_indexed_indirect(const VKStorageBuffer &buffer, + VkDeviceSize offset, + uint32_t draw_count, + uint32_t stride) +{ + validate_framebuffer_exists(); + ensure_active_framebuffer(); + vkCmdDrawIndexedIndirect(vk_command_buffer_, buffer.vk_handle(), offset, draw_count, stride); + state.draw_counts++; +} + void VKCommandBuffer::pipeline_barrier(VkPipelineStageFlags source_stages, VkPipelineStageFlags destination_stages) { diff --git a/source/blender/gpu/vulkan/vk_command_buffer.hh b/source/blender/gpu/vulkan/vk_command_buffer.hh index 795cb651c12..90ac3479853 100644 --- a/source/blender/gpu/vulkan/vk_command_buffer.hh +++ b/source/blender/gpu/vulkan/vk_command_buffer.hh @@ -22,6 +22,7 @@ class VKPipeline; class VKPushConstants; class VKTexture; class VKVertexBuffer; +class VKStorageBuffer; /** Command buffer to keep track of the life-time of a command buffer. */ class VKCommandBuffer : NonCopyable, NonMovable { @@ -182,8 +183,16 @@ class VKCommandBuffer : NonCopyable, NonMovable { void fill(VKBuffer &buffer, uint32_t data); void draw(int v_first, int v_count, int i_first, int i_count); - void draw( + void draw_indexed( int index_count, int instance_count, int first_index, int vertex_offset, int first_instance); + void draw_indirect(const VKStorageBuffer &buffer, + VkDeviceSize offset, + uint32_t draw_count, + uint32_t stride); + void draw_indexed_indirect(const VKStorageBuffer &buffer, + VkDeviceSize offset, + uint32_t draw_count, + uint32_t stride); /** * Stop recording commands, encode + send the recordings to Vulkan, wait for the until the diff --git a/source/blender/gpu/vulkan/vk_device.hh b/source/blender/gpu/vulkan/vk_device.hh index 3e9eaea94ac..158e2ed6625 100644 --- a/source/blender/gpu/vulkan/vk_device.hh +++ b/source/blender/gpu/vulkan/vk_device.hh @@ -38,6 +38,7 @@ class VKDevice : public NonCopyable { /* Workarounds */ struct { bool depth_component_24 = false; + bool texture_format_rgb16f = false; } workarounds_; diff --git a/source/blender/gpu/vulkan/vk_storage_buffer.cc b/source/blender/gpu/vulkan/vk_storage_buffer.cc index 5b141507e84..8f6516c59d1 100644 --- a/source/blender/gpu/vulkan/vk_storage_buffer.cc +++ b/source/blender/gpu/vulkan/vk_storage_buffer.cc @@ -31,6 +31,7 @@ void VKStorageBuffer::allocate() void VKStorageBuffer::bind(int slot) { + /* TODO: move Storage buffer bindings to state manager to reuse bindings.*/ VKContext &context = *VKContext::get(); if (!buffer_.is_allocated()) { allocate(); @@ -40,8 +41,9 @@ void VKStorageBuffer::bind(int slot) const std::optional location = shader_interface.descriptor_set_location( shader::ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER, slot); - BLI_assert_msg(location, "Locations to SSBOs should always exist."); - shader->pipeline_get().descriptor_set_get().bind(*this, *location); + if (location) { + shader->pipeline_get().descriptor_set_get().bind(*this, *location); + } } void VKStorageBuffer::unbind() {} diff --git a/source/blender/gpu/vulkan/vk_storage_buffer.hh b/source/blender/gpu/vulkan/vk_storage_buffer.hh index 02a4c5e49f7..7239d2767f5 100644 --- a/source/blender/gpu/vulkan/vk_storage_buffer.hh +++ b/source/blender/gpu/vulkan/vk_storage_buffer.hh @@ -48,4 +48,9 @@ class VKStorageBuffer : public StorageBuf { void allocate(); }; +static inline VKStorageBuffer *unwrap(StorageBuf *storage_buffer) +{ + return static_cast(storage_buffer); +} + } // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_texture.cc b/source/blender/gpu/vulkan/vk_texture.cc index 04e4384e882..e5eed0cf7d9 100644 --- a/source/blender/gpu/vulkan/vk_texture.cc +++ b/source/blender/gpu/vulkan/vk_texture.cc @@ -53,6 +53,7 @@ void VKTexture::copy_to(Texture *tex) UNUSED_VARS_NDEBUG(src); VKContext &context = *VKContext::get(); + ensure_allocated(); layout_ensure(context, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); dst->ensure_allocated(); dst->layout_ensure(context, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); @@ -450,6 +451,7 @@ void VKTexture::current_layout_set(const VkImageLayout new_layout) void VKTexture::layout_ensure(VKContext &context, const VkImageLayout requested_layout) { + BLI_assert(is_allocated()); const VkImageLayout current_layout = current_layout_get(); if (current_layout == requested_layout) { return; -- 2.30.2 From 8be011308baa18a7dcc7fa6bcf155706d154ca9f Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 30 May 2023 15:56:50 +0200 Subject: [PATCH 34/63] Some tweaks to get image engine working. --- source/blender/gpu/vulkan/vk_common.cc | 5 ++++- source/blender/gpu/vulkan/vk_framebuffer.cc | 2 +- source/blender/gpu/vulkan/vk_pipeline_state.cc | 3 +++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_common.cc b/source/blender/gpu/vulkan/vk_common.cc index 0db3091a46d..1bd46067c40 100644 --- a/source/blender/gpu/vulkan/vk_common.cc +++ b/source/blender/gpu/vulkan/vk_common.cc @@ -55,9 +55,12 @@ VkImageAspectFlagBits to_vk_image_aspect_flag_bits(const eGPUTextureFormat forma case GPU_DEPTH_COMPONENT32F: case GPU_DEPTH_COMPONENT24: case GPU_DEPTH_COMPONENT16: + return VK_IMAGE_ASPECT_DEPTH_BIT; + case GPU_DEPTH32F_STENCIL8: case GPU_DEPTH24_STENCIL8: - return VK_IMAGE_ASPECT_DEPTH_BIT; + return static_cast(VK_IMAGE_ASPECT_DEPTH_BIT | + VK_IMAGE_ASPECT_STENCIL_BIT); /* Texture only formats. */ case GPU_RGB32UI: diff --git a/source/blender/gpu/vulkan/vk_framebuffer.cc b/source/blender/gpu/vulkan/vk_framebuffer.cc index 41f23d998d8..4384f520470 100644 --- a/source/blender/gpu/vulkan/vk_framebuffer.cc +++ b/source/blender/gpu/vulkan/vk_framebuffer.cc @@ -80,7 +80,7 @@ VkViewport VKFrameBuffer::vk_viewport_get() const viewport.y = viewport_rect[1]; viewport.width = viewport_rect[2]; viewport.height = viewport_rect[3]; - viewport.minDepth = 0.0f; + viewport.minDepth = -1.0f; viewport.maxDepth = 1.0f; /* diff --git a/source/blender/gpu/vulkan/vk_pipeline_state.cc b/source/blender/gpu/vulkan/vk_pipeline_state.cc index e546333043f..62a632af394 100644 --- a/source/blender/gpu/vulkan/vk_pipeline_state.cc +++ b/source/blender/gpu/vulkan/vk_pipeline_state.cc @@ -15,6 +15,9 @@ VKPipelineStateManager::VKPipelineStateManager() rasterization_state = {}; rasterization_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; rasterization_state.lineWidth = 1.0f; + /* By enabling depth clamping we disable depth clipping. */ + /* Note that this is only possible when device feature is available, which isn't on AMD/Mesa.*/ + rasterization_state.depthClampEnable = VK_TRUE; pipeline_color_blend_state = {}; pipeline_color_blend_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; -- 2.30.2 From 3c658d2c2e69e9cf97dfaa7a3c164262aefb9e76 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 30 May 2023 16:10:43 +0200 Subject: [PATCH 35/63] Skip conversion to half when GPU backend can do it. --- .../blender/draw/engines/image/image_drawing_mode.hh | 10 ++++++++-- source/blender/gpu/GPU_capabilities.h | 3 +++ source/blender/gpu/intern/gpu_capabilities.cc | 5 +++++ source/blender/gpu/intern/gpu_capabilities_private.hh | 1 + source/blender/gpu/vulkan/vk_backend.cc | 1 + 5 files changed, 18 insertions(+), 2 deletions(-) diff --git a/source/blender/draw/engines/image/image_drawing_mode.hh b/source/blender/draw/engines/image/image_drawing_mode.hh index 9a7d037763c..387bc655d5f 100644 --- a/source/blender/draw/engines/image/image_drawing_mode.hh +++ b/source/blender/draw/engines/image/image_drawing_mode.hh @@ -11,6 +11,8 @@ #include "IMB_imbuf_types.h" +#include "GPU_capabilities.h" + #include "BLI_math_matrix_types.hh" #include "BLI_math_vector_types.hh" @@ -509,7 +511,9 @@ template class ScreenSpaceDrawingMode : public AbstractD offset++; } } - IMB_gpu_clamp_half_float(&extracted_buffer); + if (!GPU_texture_clamp_to_half()) { + IMB_gpu_clamp_half_float(tile_buffer); + } GPU_texture_update_sub(texture, GPU_DATA_FLOAT, @@ -562,7 +566,9 @@ template class ScreenSpaceDrawingMode : public AbstractD } BKE_image_release_ibuf(image, tile_buffer, lock); } - IMB_gpu_clamp_half_float(&texture_buffer); + if (!GPU_texture_clamp_to_half()) { + IMB_gpu_clamp_half_float(&texture_buffer); + } GPU_texture_update(info.texture, GPU_DATA_FLOAT, texture_buffer.float_buffer.data); imb_freerectImbuf_all(&texture_buffer); } diff --git a/source/blender/gpu/GPU_capabilities.h b/source/blender/gpu/GPU_capabilities.h index 09eb917d9be..a80fbee4e14 100644 --- a/source/blender/gpu/GPU_capabilities.h +++ b/source/blender/gpu/GPU_capabilities.h @@ -55,6 +55,9 @@ bool GPU_shader_draw_parameters_support(void); bool GPU_mem_stats_supported(void); void GPU_mem_stats_get(int *totalmem, int *freemem); +/* Check if the active GPU backend automatically clamp values to fit in 16F. */ +bool GPU_texture_clamp_to_half(void); + /** * Return support for the active context + window. */ diff --git a/source/blender/gpu/intern/gpu_capabilities.cc b/source/blender/gpu/intern/gpu_capabilities.cc index fbc17d9e20a..55957b0cf8c 100644 --- a/source/blender/gpu/intern/gpu_capabilities.cc +++ b/source/blender/gpu/intern/gpu_capabilities.cc @@ -201,6 +201,11 @@ bool GPU_transform_feedback_support(void) return GCaps.transform_feedback_support; } +bool GPU_texture_clamp_to_half(void) +{ + return GCaps.texture_clamp_to_half; +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/gpu/intern/gpu_capabilities_private.hh b/source/blender/gpu/intern/gpu_capabilities_private.hh index 0bbdc45bc74..ccf1b1db76a 100644 --- a/source/blender/gpu/intern/gpu_capabilities_private.hh +++ b/source/blender/gpu/intern/gpu_capabilities_private.hh @@ -56,6 +56,7 @@ struct GPUCapabilities { bool use_hq_normals_workaround = false; bool clear_viewport_workaround = false; /* Vulkan related workarounds. */ + bool texture_clamp_to_half = false; /* Metal related workarounds. */ /* Minimum per-vertex stride in bytes (For a vertex buffer). */ diff --git a/source/blender/gpu/vulkan/vk_backend.cc b/source/blender/gpu/vulkan/vk_backend.cc index 10f05326499..e18a671c5ec 100644 --- a/source/blender/gpu/vulkan/vk_backend.cc +++ b/source/blender/gpu/vulkan/vk_backend.cc @@ -193,6 +193,7 @@ void VKBackend::capabilities_init(VKDevice &device) GCaps.compute_shader_support = true; GCaps.shader_storage_buffer_objects_support = true; GCaps.shader_image_load_store_support = true; + GCaps.texture_clamp_to_half = true; GCaps.max_texture_size = max_ii(limits.maxImageDimension1D, limits.maxImageDimension2D); GCaps.max_texture_3d_size = limits.maxImageDimension3D; -- 2.30.2 From 542bc7b8c843fc92692d7bd74ff787977fc35855 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 1 Jun 2023 13:33:44 +0200 Subject: [PATCH 36/63] Fix code formatting. --- source/blender/gpu/vulkan/vk_context.cc | 1 - source/blender/gpu/vulkan/vk_data_conversion.cc | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_context.cc b/source/blender/gpu/vulkan/vk_context.cc index 061827ea223..a167fa2402c 100644 --- a/source/blender/gpu/vulkan/vk_context.cc +++ b/source/blender/gpu/vulkan/vk_context.cc @@ -211,5 +211,4 @@ void VKContext::bind_graphics_pipeline(const GPUPrimType prim_type, /** \} */ - } // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_data_conversion.cc b/source/blender/gpu/vulkan/vk_data_conversion.cc index ec9da42a8ca..2f9668466da 100644 --- a/source/blender/gpu/vulkan/vk_data_conversion.cc +++ b/source/blender/gpu/vulkan/vk_data_conversion.cc @@ -592,7 +592,8 @@ using SRGBA8 = PixelValue>; using FLOAT3 = PixelValue; using FLOAT4 = PixelValue>; /* NOTE: Vulkan stores R11_G11_B10 in reverse component order. */ -class B10F_G11G_R11F : public PixelValue {}; +class B10F_G11G_R11F : public PixelValue { +}; class DepthComponent24 : public ComponentValue { public: -- 2.30.2 From f7fd0f2a9cca93f0d75850819470becbca2194a2 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 1 Jun 2023 14:08:05 +0200 Subject: [PATCH 37/63] Disable depth clamping. --- source/blender/gpu/vulkan/vk_framebuffer.cc | 2 +- source/blender/gpu/vulkan/vk_pipeline_state.cc | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_framebuffer.cc b/source/blender/gpu/vulkan/vk_framebuffer.cc index 7bc549b8f34..65b42b3a442 100644 --- a/source/blender/gpu/vulkan/vk_framebuffer.cc +++ b/source/blender/gpu/vulkan/vk_framebuffer.cc @@ -81,7 +81,7 @@ VkViewport VKFrameBuffer::vk_viewport_get() const viewport.y = viewport_rect[1]; viewport.width = viewport_rect[2]; viewport.height = viewport_rect[3]; - viewport.minDepth = -1.0f; + viewport.minDepth = 0.0f; viewport.maxDepth = 1.0f; /* diff --git a/source/blender/gpu/vulkan/vk_pipeline_state.cc b/source/blender/gpu/vulkan/vk_pipeline_state.cc index 8ddaa88e459..421947552ba 100644 --- a/source/blender/gpu/vulkan/vk_pipeline_state.cc +++ b/source/blender/gpu/vulkan/vk_pipeline_state.cc @@ -16,9 +16,7 @@ VKPipelineStateManager::VKPipelineStateManager() rasterization_state = {}; rasterization_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; rasterization_state.lineWidth = 1.0f; - /* By enabling depth clamping we disable depth clipping. */ - /* Note that this is only possible when device feature is available, which isn't on AMD/Mesa.*/ - rasterization_state.depthClampEnable = VK_TRUE; + rasterization_state.depthClampEnable = VK_FALSE; pipeline_color_blend_state = {}; pipeline_color_blend_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; -- 2.30.2 From bf592b9e9ca8f3b2ad66df1495275f3a73161bf1 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 1 Jun 2023 15:33:36 +0200 Subject: [PATCH 38/63] Add support for UBYTE to SRGB texture. --- source/blender/gpu/tests/texture_test.cc | 2 -- source/blender/gpu/vulkan/vk_data_conversion.cc | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/source/blender/gpu/tests/texture_test.cc b/source/blender/gpu/tests/texture_test.cc index 57654ce4769..91bea564ef3 100644 --- a/source/blender/gpu/tests/texture_test.cc +++ b/source/blender/gpu/tests/texture_test.cc @@ -715,13 +715,11 @@ static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_R8() } GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_R8); -#if RUN_SRGB_UNIMPLEMENTED static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_SRGB8_A8() { texture_create_upload_read(); } GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_SRGB8_A8); -#endif #if RUN_UNSUPPORTED static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_RGB8I() diff --git a/source/blender/gpu/vulkan/vk_data_conversion.cc b/source/blender/gpu/vulkan/vk_data_conversion.cc index 6df790612c4..661b71420b3 100644 --- a/source/blender/gpu/vulkan/vk_data_conversion.cc +++ b/source/blender/gpu/vulkan/vk_data_conversion.cc @@ -401,6 +401,7 @@ static ConversionType type_of_conversion_ubyte(eGPUTextureFormat device_format) case GPU_RG8: case GPU_R8UI: case GPU_R8: + case GPU_SRGB8_A8: return ConversionType::PASS_THROUGH; case GPU_RGBA8I: @@ -432,7 +433,6 @@ static ConversionType type_of_conversion_ubyte(eGPUTextureFormat device_format) case GPU_R11F_G11F_B10F: case GPU_DEPTH32F_STENCIL8: case GPU_DEPTH24_STENCIL8: - case GPU_SRGB8_A8: case GPU_RGBA8_SNORM: case GPU_RGBA16_SNORM: case GPU_RGB8UI: -- 2.30.2 From f07dbceb8d6e3ab63104758d3bddbbe498ec9c4e Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 2 Jun 2023 09:31:33 +0200 Subject: [PATCH 39/63] Update mipmaps sourced from level 0 --- .../blender/gpu/vulkan/vk_command_buffer.cc | 21 ++++-- .../blender/gpu/vulkan/vk_command_buffer.hh | 5 ++ source/blender/gpu/vulkan/vk_texture.cc | 68 +++++++++++++++++-- source/blender/gpu/vulkan/vk_texture.hh | 11 +++ 4 files changed, 97 insertions(+), 8 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_command_buffer.cc b/source/blender/gpu/vulkan/vk_command_buffer.cc index a3c0cec1b90..0f16fa75b99 100644 --- a/source/blender/gpu/vulkan/vk_command_buffer.cc +++ b/source/blender/gpu/vulkan/vk_command_buffer.cc @@ -202,15 +202,28 @@ void VKCommandBuffer::copy(VKTexture &dst_texture, } void VKCommandBuffer::blit(VKTexture &dst_texture, - VKTexture &src_buffer, + VKTexture &src_texture, + Span regions) +{ + blit(dst_texture, + dst_texture.current_layout_get(), + src_texture, + src_texture.current_layout_get(), + regions); +} + +void VKCommandBuffer::blit(VKTexture &dst_texture, + VkImageLayout dst_layout, + VKTexture &src_texture, + VkImageLayout src_layout, Span regions) { ensure_no_active_framebuffer(); vkCmdBlitImage(vk_command_buffer_, - src_buffer.vk_image_handle(), - src_buffer.current_layout_get(), + src_texture.vk_image_handle(), + src_layout, dst_texture.vk_image_handle(), - dst_texture.current_layout_get(), + dst_layout, regions.size(), regions.data(), VK_FILTER_NEAREST); diff --git a/source/blender/gpu/vulkan/vk_command_buffer.hh b/source/blender/gpu/vulkan/vk_command_buffer.hh index 8921aa96f5c..f63425a2ad2 100644 --- a/source/blender/gpu/vulkan/vk_command_buffer.hh +++ b/source/blender/gpu/vulkan/vk_command_buffer.hh @@ -166,6 +166,11 @@ class VKCommandBuffer : NonCopyable, NonMovable { void copy(VKTexture &dst_texture, VKBuffer &src_buffer, Span regions); void copy(VKTexture &dst_texture, VKTexture &src_texture, Span regions); void blit(VKTexture &dst_texture, VKTexture &src_texture, Span regions); + void blit(VKTexture &dst_texture, + VkImageLayout dst_layout, + VKTexture &src_texture, + VkImageLayout src_layout, + Span regions); void pipeline_barrier(VkPipelineStageFlags source_stages, VkPipelineStageFlags destination_stages); void pipeline_barrier(Span image_memory_barriers); diff --git a/source/blender/gpu/vulkan/vk_texture.cc b/source/blender/gpu/vulkan/vk_texture.cc index f407ea0ff4b..37df2ff1a57 100644 --- a/source/blender/gpu/vulkan/vk_texture.cc +++ b/source/blender/gpu/vulkan/vk_texture.cc @@ -41,7 +41,56 @@ void VKTexture::init(VkImage vk_image, VkImageLayout layout) void VKTexture::generate_mipmap() { - NOT_YET_IMPLEMENTED + if (mipmaps_ <= 1) { + return; + } + + ensure_allocated(); + + VKContext &context = *VKContext::get(); + VKCommandBuffer &command_buffer = context.command_buffer_get(); + layout_ensure(context, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + + for (int src_mipmap : IndexRange(mipmaps_ - 1)) { + int dst_mipmap = src_mipmap + 1; + int3 src_size(1); + int3 dst_size(1); + mip_size_get(src_mipmap, src_size); + mip_size_get(dst_mipmap, dst_size); + + layout_ensure(context, + IndexRange(src_mipmap, 1), + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + + VkImageBlit image_blit = {}; + image_blit.srcOffsets[0] = {0, 0, 0}; + image_blit.srcOffsets[1] = {src_size.x, src_size.y, src_size.z}; + image_blit.srcSubresource.aspectMask = to_vk_image_aspect_flag_bits(format_); + image_blit.srcSubresource.mipLevel = src_mipmap; + image_blit.srcSubresource.baseArrayLayer = 0; + image_blit.srcSubresource.layerCount = layer_count(); + + image_blit.dstOffsets[0] = {0, 0, 0}; + image_blit.dstOffsets[1] = {dst_size.x, dst_size.y, dst_size.z}; + image_blit.dstSubresource.aspectMask = to_vk_image_aspect_flag_bits(format_); + image_blit.dstSubresource.mipLevel = dst_mipmap; + image_blit.dstSubresource.baseArrayLayer = 0; + image_blit.dstSubresource.layerCount = layer_count(); + + command_buffer.blit(*this, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + *this, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + Span(&image_blit, 1)); + } + /* Ensure that all mipmap levels are in `VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL`. All miplevels are + * except the last one. */ + layout_ensure(context, + IndexRange(mipmaps_ - 1, 1), + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); + current_layout_set(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); } void VKTexture::copy_to(Texture *tex) @@ -338,7 +387,7 @@ bool VKTexture::allocate() image_info.extent.width = extent[0]; image_info.extent.height = extent[1]; image_info.extent.depth = extent[2]; - image_info.mipLevels = 1; + image_info.mipLevels = max_ii(mipmaps_, 1); image_info.arrayLayers = 1; image_info.format = to_vk_format(format_); /* Some platforms (NVIDIA) requires that attached textures are always tiled optimal. @@ -457,16 +506,27 @@ void VKTexture::layout_ensure(VKContext &context, const VkImageLayout requested_ if (current_layout == requested_layout) { return; } + layout_ensure(context, IndexRange(0, VK_REMAINING_MIP_LEVELS), current_layout, requested_layout); + current_layout_set(requested_layout); +} + +void VKTexture::layout_ensure(VKContext &context, + const IndexRange mipmap_range, + const VkImageLayout current_layout, + const VkImageLayout requested_layout) +{ + BLI_assert(is_allocated()); VkImageMemoryBarrier barrier{}; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; barrier.oldLayout = current_layout; barrier.newLayout = requested_layout; barrier.image = vk_image_; barrier.subresourceRange.aspectMask = to_vk_image_aspect_flag_bits(format_); - barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS; + barrier.subresourceRange.baseMipLevel = uint32_t(mipmap_range.start()); + barrier.subresourceRange.levelCount = uint32_t(mipmap_range.size()); + barrier.subresourceRange.baseArrayLayer = 0; barrier.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; context.command_buffer_get().pipeline_barrier(Span(&barrier, 1)); - current_layout_set(requested_layout); } /** \} */ diff --git a/source/blender/gpu/vulkan/vk_texture.hh b/source/blender/gpu/vulkan/vk_texture.hh index 64a26827209..c2bc41485d1 100644 --- a/source/blender/gpu/vulkan/vk_texture.hh +++ b/source/blender/gpu/vulkan/vk_texture.hh @@ -111,6 +111,17 @@ class VKTexture : public Texture { */ void layout_ensure(VKContext &context, VkImageLayout requested_layout); + private: + /** + * Internal function to ensure the layout of a single mipmap level. Note that the caller is + * responsible to update the current_layout of the image at the end of the operation and make + * sure that all mipmap levels are in that given layout. + */ + void layout_ensure(VKContext &context, + IndexRange mipmap_range, + VkImageLayout current_layout, + VkImageLayout requested_layout); + /** \} */ }; -- 2.30.2 From f8deeec9a4cd4434b48ba47d27f597904e64f96a Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 2 Jun 2023 16:01:05 +0200 Subject: [PATCH 40/63] Small changes to prepare for mipmaps framebuffers --- source/blender/gpu/vulkan/vk_framebuffer.cc | 1 + source/blender/gpu/vulkan/vk_texture.cc | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_framebuffer.cc b/source/blender/gpu/vulkan/vk_framebuffer.cc index e93f06b1108..d3107eb0250 100644 --- a/source/blender/gpu/vulkan/vk_framebuffer.cc +++ b/source/blender/gpu/vulkan/vk_framebuffer.cc @@ -402,6 +402,7 @@ void VKFrameBuffer::render_pass_create() /* Ensure texture is allocated to ensure the image view. */ VKTexture &texture = *static_cast(unwrap(attachment.tex)); texture.ensure_allocated(); + /* TODO: use image_view for attachment.mip */ image_views[attachment_location] = texture.vk_image_view_handle(); VkAttachmentDescription &attachment_description = diff --git a/source/blender/gpu/vulkan/vk_texture.cc b/source/blender/gpu/vulkan/vk_texture.cc index 37df2ff1a57..7d3902a0115 100644 --- a/source/blender/gpu/vulkan/vk_texture.cc +++ b/source/blender/gpu/vulkan/vk_texture.cc @@ -200,10 +200,6 @@ void *VKTexture::read(int mip, eGPUDataFormat format) void VKTexture::update_sub( int mip, int offset[3], int extent_[3], eGPUDataFormat format, const void *data) { - if (mip != 0) { - NOT_YET_IMPLEMENTED; - return; - } if (!is_allocated()) { allocate(); } -- 2.30.2 From d0360f840d26b9c37c24ffd0a07ad35fbbf5f27c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 4 Jun 2023 18:35:12 +1000 Subject: [PATCH 41/63] Cleanup: remove NULL literals in C++ (including comments & strings) --- .../blender/blenkernel/intern/action_test.cc | 4 +-- .../blender/blenkernel/intern/customdata.cc | 2 +- .../blenkernel/intern/grease_pencil.cc | 2 +- .../blender/blenkernel/intern/lib_override.cc | 2 +- .../blender/blenkernel/intern/main_namemap.cc | 2 +- source/blender/blenkernel/intern/paint.cc | 3 ++- source/blender/blenkernel/intern/volume.cc | 2 +- source/blender/blenlib/intern/delaunay_2d.cc | 26 +++++++++---------- .../blenlib/tests/BLI_listbase_test.cc | 2 +- .../blender/blenlib/tests/BLI_string_test.cc | 20 +++++++------- .../blenlib/tests/BLI_string_utf8_test.cc | 2 +- source/blender/blenloader/intern/readfile.cc | 2 +- source/blender/bmesh/intern/bmesh_query_uv.cc | 2 +- .../eval/deg_eval_runtime_backup_gpencil.cc | 2 +- .../draw/intern/draw_cache_impl_curve.cc | 4 +-- .../editors/sculpt_paint/sculpt_undo.cc | 8 +++--- .../blender/editors/space_image/image_undo.cc | 2 +- .../space_outliner/outliner_dragdrop.cc | 2 +- .../editors/space_outliner/outliner_edit.cc | 3 ++- .../tree/tree_display_libraries.cc | 2 +- .../blender/editors/uvedit/uvedit_select.cc | 6 ++--- .../editors/uvedit/uvedit_smart_stitch.cc | 2 +- .../geometry/intern/uv_parametrizer.cc | 2 +- .../blender/gpu/tests/vertex_buffer_test.cc | 2 +- .../gpu/vulkan/vk_vertex_attribute_object.cc | 2 +- .../io/alembic/exporter/abc_custom_props.cc | 2 +- .../io/alembic/exporter/abc_export_capi.cc | 2 +- .../io/alembic/exporter/abc_writer_hair.cc | 2 +- .../blender/io/alembic/intern/alembic_capi.cc | 2 +- .../blender/io/usd/intern/usd_capi_export.cc | 4 +-- .../blender/io/usd/intern/usd_capi_import.cc | 2 +- source/blender/makesrna/intern/rna_path.cc | 12 ++++----- .../windowmanager/intern/wm_init_exit.cc | 2 +- 33 files changed, 69 insertions(+), 67 deletions(-) diff --git a/source/blender/blenkernel/intern/action_test.cc b/source/blender/blenkernel/intern/action_test.cc index f7c260327c2..58c14405792 100644 --- a/source/blender/blenkernel/intern/action_test.cc +++ b/source/blender/blenkernel/intern/action_test.cc @@ -161,8 +161,8 @@ void add_keyframe(FCurve *fcu, float x, float y) TEST(action_assets, BKE_action_has_single_frame) { - /* NULL action. */ - EXPECT_FALSE(BKE_action_has_single_frame(nullptr)) << "NULL Action cannot have a single frame."; + /* Null action. */ + EXPECT_FALSE(BKE_action_has_single_frame(nullptr)) << "Null Action cannot have a single frame."; /* No FCurves. */ { diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc index dc2397b9b02..91102a511fa 100644 --- a/source/blender/blenkernel/intern/customdata.cc +++ b/source/blender/blenkernel/intern/customdata.cc @@ -4507,7 +4507,7 @@ static bool CustomData_layer_ensure_data_exists(CustomDataLayer *layer, size_t c default: /* Log an error so we can collect instances of bad files. */ - CLOG_WARN(&LOG, "CustomDataLayer->data is NULL for type %d.", layer->type); + CLOG_WARN(&LOG, "CustomDataLayer->data is null for type %d.", layer->type); break; } return false; diff --git a/source/blender/blenkernel/intern/grease_pencil.cc b/source/blender/blenkernel/intern/grease_pencil.cc index 9d813e34f76..17b4cc592cd 100644 --- a/source/blender/blenkernel/intern/grease_pencil.cc +++ b/source/blender/blenkernel/intern/grease_pencil.cc @@ -750,7 +750,7 @@ void BKE_grease_pencil_data_update(struct Depsgraph * /*depsgraph*/, int BKE_grease_pencil_object_material_index_get_by_name(Object *ob, const char *name) { short *totcol = BKE_object_material_len_p(ob); - Material *read_ma = NULL; + Material *read_ma = nullptr; for (short i = 0; i < *totcol; i++) { read_ma = BKE_object_material_get(ob, i + 1); if (STREQ(name, read_ma->id.name + 2)) { diff --git a/source/blender/blenkernel/intern/lib_override.cc b/source/blender/blenkernel/intern/lib_override.cc index f72d735b09d..a24775e79eb 100644 --- a/source/blender/blenkernel/intern/lib_override.cc +++ b/source/blender/blenkernel/intern/lib_override.cc @@ -1289,7 +1289,7 @@ static void lib_override_library_create_post_process(Main *bmain, /* No instantiation in case the root override is linked data, unless it is part of the given * owner library. * - * NOTE: that last case should never happen actually in current code? Since non-NULL owner + * NOTE: that last case should never happen actually in current code? Since non-null owner * library should only happen in case of recursive resync, which is already excluded by the * previous condition. */ } diff --git a/source/blender/blenkernel/intern/main_namemap.cc b/source/blender/blenkernel/intern/main_namemap.cc index d7339fccbed..527c619845f 100644 --- a/source/blender/blenkernel/intern/main_namemap.cc +++ b/source/blender/blenkernel/intern/main_namemap.cc @@ -48,7 +48,7 @@ using namespace blender; */ static bool id_name_final_build(char *name, char *base_name, size_t base_name_len, int number) { - char number_str[11]; /* Dot + nine digits + NULL terminator. */ + char number_str[11]; /* Dot + nine digits + null terminator. */ size_t number_str_len = SNPRINTF_RLEN(number_str, ".%.3d", number); /* If the number would lead to an overflow of the maximum ID name length, we need to truncate diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc index a2acc962fbf..5de1a81588c 100644 --- a/source/blender/blenkernel/intern/paint.cc +++ b/source/blender/blenkernel/intern/paint.cc @@ -1667,7 +1667,8 @@ static void sculpt_update_object( BLI_assert(me_eval != nullptr); - /* This is for handling a newly opened file with no object visible, causing me_eval==NULL. */ + /* This is for handling a newly opened file with no object visible, + * causing `me_eval == nullptr`. */ if (me_eval == nullptr) { return; } diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc index b8de549893d..f70b7f065e9 100644 --- a/source/blender/blenkernel/intern/volume.cc +++ b/source/blender/blenkernel/intern/volume.cc @@ -900,7 +900,7 @@ bool BKE_volume_load(const Volume *volume, const Main *bmain) CLOG_INFO(&LOG, 1, "Volume %s: %s", volume_name, grids.error_msg.c_str()); } - /* Add grids read from file to own vector, filtering out any NULL pointers. */ + /* Add grids read from file to own vector, filtering out any null pointers. */ for (const openvdb::GridBase::Ptr &vdb_grid : vdb_grids) { if (vdb_grid) { VolumeFileCache::Entry template_entry(filepath, vdb_grid); diff --git a/source/blender/blenlib/intern/delaunay_2d.cc b/source/blender/blenlib/intern/delaunay_2d.cc index cd882520c27..a39c04efeac 100644 --- a/source/blender/blenlib/intern/delaunay_2d.cc +++ b/source/blender/blenlib/intern/delaunay_2d.cc @@ -392,7 +392,7 @@ template std::ostream &operator<<(std::ostream &os, const SymEdge << vertname(se.next->vert); } else { - os << vertname(se.vert) << "(" << se.vert->co << "->NULL)"; + os << vertname(se.vert) << "(" << se.vert->co << "->null)"; } return os; } @@ -406,10 +406,10 @@ template std::ostream &operator<<(std::ostream &os, const SymEdge template std::string short_se_dump(const SymEdge *se) { if (se == nullptr) { - return std::string("NULL"); + return std::string("null"); } return vertname(se->vert) + - (se->next == nullptr ? std::string("[NULL]") : vertname(se->next->vert)); + (se->next == nullptr ? std::string("[null]") : vertname(se->next->vert)); } template std::ostream &operator<<(std::ostream &os, const CDT_state &cdt_state) @@ -431,11 +431,11 @@ template std::ostream &operator<<(std::ostream &os, const CDT_state< os << " edges out:\n"; do { if (se->next == nullptr) { - os << " [NULL] next/rot symedge, se=" << trunc_ptr(se) << "\n"; + os << " [null] next/rot symedge, se=" << trunc_ptr(se) << "\n"; break; } if (se->next->next == nullptr) { - os << " [NULL] next-next/rot symedge, se=" << trunc_ptr(se) << "\n"; + os << " [null] next-next/rot symedge, se=" << trunc_ptr(se) << "\n"; break; } const CDTVert *vother = sym(se)->vert; @@ -1155,7 +1155,7 @@ template void CDTArrangement::delete_edge(SymEdge *se) v2->symedge = f; } - /* Mark SymEdge as deleted by setting all its pointers to NULL. */ + /* Mark #SymEdge as deleted by setting all its pointers to null. */ se->next = se->rot = nullptr; sesym->next = sesym->rot = nullptr; if (!v1_isolated && !v2_isolated && aface != bface) { @@ -1565,16 +1565,16 @@ template inline int tri_orient(const SymEdge *t) * In general, lambda=0 indicates case a and lambda != 0 indicates case be. * The 'in' edge gives the destination attachment point of a diagonal from the previous crossing, * and the 'out' edge gives the origin attachment point of a diagonal to the next crossing. - * But in some cases, 'in' and 'out' are undefined or not needed, and will be NULL. + * But in some cases, 'in' and 'out' are undefined or not needed, and will be null. * * For case (a), 'vert' will be the vertex, and lambda will be 0, and 'in' will be the #SymEdge * from 'vert' that has as face the one that you go through to get to this vertex. If you go - * exactly along an edge then we set 'in' to NULL, since it won't be needed. The first crossing - * will have 'in' = NULL. We set 'out' to the #SymEdge that has the face we go through to get to + * exactly along an edge then we set 'in' to null, since it won't be needed. The first crossing + * will have 'in' = null. We set 'out' to the #SymEdge that has the face we go through to get to * the next crossing, or, if the next crossing is a case (a), then it is the edge that goes to that - * next vertex. 'out' will be NULL for the last one. + * next vertex. 'out' will be null for the last one. * - * For case (b), vert will be NULL at first, and later filled in with the created split vertex, + * For case (b), vert will be null at first, and later filled in with the created split vertex, * and 'in' will be the #SymEdge that we go through, and lambda will be between 0 and 1, * the fraction from in's vert to in->next's vert to put the split vertex. * 'out' is not needed in this case, since the attachment point will be the sym of the first @@ -1632,7 +1632,7 @@ bool get_next_crossing_from_vert(CDT_state *cdt_state, /** * As part of finding crossings, we found a case where the next crossing goes through vert v. * If it came from a previous vert in cd, then cd_out is the edge that leads from that to v. - * Else cd_out can be NULL, because it won't be used. + * Else cd_out can be null, because it won't be used. * Set *cd_next to indicate this. We can set 'in' but not 'out'. We can set the 'out' of the * current cd. */ @@ -1880,7 +1880,7 @@ void dump_crossings(const Vector, inline_crossings_size> &crossings * and partial overlaps with existing cdt vertices and edges. * Each created #CDTEdge will have input_id added to its input_ids list. * - * If \a r_edges is not NULL, the #CDTEdges generated or found that go from + * If \a r_edges is not null, the #CDTEdges generated or found that go from * v1 to v2 are put into that linked list, in order. * * Assumes that #blender_constrained_delaunay_get_output has not been called yet. diff --git a/source/blender/blenlib/tests/BLI_listbase_test.cc b/source/blender/blenlib/tests/BLI_listbase_test.cc index c47d0d67154..c349a9784a2 100644 --- a/source/blender/blenlib/tests/BLI_listbase_test.cc +++ b/source/blender/blenlib/tests/BLI_listbase_test.cc @@ -171,7 +171,7 @@ TEST(listbase, FromLink) Link *link2 = static_cast(MEM_callocN(sizeof(Link), "link2")); Link *link3 = static_cast(MEM_callocN(sizeof(Link), "link3")); - /* NULL safety. */ + /* Null safety. */ EXPECT_EQ(lb, BLI_listbase_from_link(nullptr)); /* One link. */ diff --git a/source/blender/blenlib/tests/BLI_string_test.cc b/source/blender/blenlib/tests/BLI_string_test.cc index f077c33c2ea..faf979b26c8 100644 --- a/source/blender/blenlib/tests/BLI_string_test.cc +++ b/source/blender/blenlib/tests/BLI_string_test.cc @@ -237,7 +237,7 @@ TEST(string, StrPartition) { const char *str = ""; - /* "" -> "", NULL, NULL, 0 */ + /* "" -> "", nullptr, nullptr, 0 */ pre_len = BLI_str_partition(str, delim, &sep, &suf); EXPECT_EQ(pre_len, 0); EXPECT_EQ(sep, (void *)nullptr); @@ -247,7 +247,7 @@ TEST(string, StrPartition) { const char *str = "material"; - /* "material" -> "material", NULL, NULL, 8 */ + /* "material" -> "material", nullptr, nullptr, 8 */ pre_len = BLI_str_partition(str, delim, &sep, &suf); EXPECT_EQ(pre_len, 8); EXPECT_EQ(sep, (void *)nullptr); @@ -296,7 +296,7 @@ TEST(string, StrRPartition) { const char *str = ""; - /* "" -> "", NULL, NULL, 0 */ + /* "" -> "", nullptr, nullptr, 0 */ pre_len = BLI_str_rpartition(str, delim, &sep, &suf); EXPECT_EQ(pre_len, 0); EXPECT_EQ(sep, (void *)nullptr); @@ -306,7 +306,7 @@ TEST(string, StrRPartition) { const char *str = "material"; - /* "material" -> "material", NULL, NULL, 8 */ + /* "material" -> "material", nullptr, nullptr, 8 */ pre_len = BLI_str_rpartition(str, delim, &sep, &suf); EXPECT_EQ(pre_len, 8); EXPECT_EQ(sep, (void *)nullptr); @@ -337,7 +337,7 @@ TEST(string, StrPartitionEx) { const char *str = "mate.rial"; - /* "mate.rial" over "mate" -> "mate.rial", NULL, NULL, 4 */ + /* "mate.rial" over "mate" -> "mate.rial", nullptr, nullptr, 4 */ pre_len = BLI_str_partition_ex(str, str + 4, delim, &sep, &suf, true); EXPECT_EQ(pre_len, 4); EXPECT_EQ(sep, (void *)nullptr); @@ -386,7 +386,7 @@ TEST(string, StrPartitionUtf8) { const char *str = ""; - /* "" -> "", NULL, NULL, 0 */ + /* "" -> "", nullptr, nullptr, 0 */ pre_len = BLI_str_partition_utf8(str, delim, &sep, &suf); EXPECT_EQ(pre_len, 0); EXPECT_EQ(sep, (void *)nullptr); @@ -396,7 +396,7 @@ TEST(string, StrPartitionUtf8) { const char *str = "material"; - /* "material" -> "material", NULL, NULL, 8 */ + /* "material" -> "material", nullptr, nullptr, 8 */ pre_len = BLI_str_partition_utf8(str, delim, &sep, &suf); EXPECT_EQ(pre_len, 8); EXPECT_EQ(sep, (void *)nullptr); @@ -445,7 +445,7 @@ TEST(string, StrRPartitionUtf8) { const char *str = ""; - /* "" -> "", NULL, NULL, 0 */ + /* "" -> "", nullptr, nullptr, 0 */ pre_len = BLI_str_rpartition_utf8(str, delim, &sep, &suf); EXPECT_EQ(pre_len, 0); EXPECT_EQ(sep, (void *)nullptr); @@ -455,7 +455,7 @@ TEST(string, StrRPartitionUtf8) { const char *str = "material"; - /* "material" -> "material", NULL, NULL, 8 */ + /* "material" -> "material", nullptr, nullptr, 8 */ pre_len = BLI_str_rpartition_utf8(str, delim, &sep, &suf); EXPECT_EQ(pre_len, 8); EXPECT_EQ(sep, (void *)nullptr); @@ -487,7 +487,7 @@ TEST(string, StrPartitionExUtf8) { const char *str = "mate\xe2\x98\xafrial"; - /* "mate\xe2\x98\xafrial" over "mate" -> "mate\xe2\x98\xafrial", NULL, NULL, 4 */ + /* "mate\xe2\x98\xafrial" over "mate" -> "mate\xe2\x98\xafrial", nullptr, nullptr, 4 */ pre_len = BLI_str_partition_ex_utf8(str, str + 4, delim, &sep, &suf, true); EXPECT_EQ(pre_len, 4); EXPECT_EQ(sep, (void *)nullptr); diff --git a/source/blender/blenlib/tests/BLI_string_utf8_test.cc b/source/blender/blenlib/tests/BLI_string_utf8_test.cc index 5cc9eb9d53f..94773fb85e8 100644 --- a/source/blender/blenlib/tests/BLI_string_utf8_test.cc +++ b/source/blender/blenlib/tests/BLI_string_utf8_test.cc @@ -21,7 +21,7 @@ /* Breaking strings is confusing here, prefer over-long lines. */ /* clang-format off */ -/* Each test is made of a 79 bytes (80 with NULL char) string to test, expected string result after +/* Each test is made of a 79 bytes (80 with null char) string to test, expected string result after * stripping invalid utf8 bytes, and a single-byte string encoded with expected number of errors. * * Based on utf-8 decoder stress-test (https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt) diff --git a/source/blender/blenloader/intern/readfile.cc b/source/blender/blenloader/intern/readfile.cc index 06836f1de3f..8750eca2b68 100644 --- a/source/blender/blenloader/intern/readfile.cc +++ b/source/blender/blenloader/intern/readfile.cc @@ -3140,7 +3140,7 @@ static void read_libblock_undo_restore_at_old_address(FileData *fd, Main *main, /* We do need remapping of internal pointers to the ID itself here. * - * Passing a NULL BMain means that not all potential runtime data (like collections' parent + * Passing a null #Main means that not all potential runtime data (like collections' parent * pointers etc.) will be up-to-date. However, this should not be a problem here, since these * data are re-generated later in file-read process anyway. */ BKE_lib_id_swap_full(nullptr, diff --git a/source/blender/bmesh/intern/bmesh_query_uv.cc b/source/blender/bmesh/intern/bmesh_query_uv.cc index befb1f87ccf..976df371327 100644 --- a/source/blender/bmesh/intern/bmesh_query_uv.cc +++ b/source/blender/bmesh/intern/bmesh_query_uv.cc @@ -176,7 +176,7 @@ bool BM_edge_uv_share_vert_check(BMEdge *e, BMLoop *l_a, BMLoop *l_b, const int return false; } - /* No need for NULL checks, these will always succeed. */ + /* No need for null checks, these will always succeed. */ const BMLoop *l_other_a = BM_loop_other_vert_loop_by_edge(l_a, e); const BMLoop *l_other_b = BM_loop_other_vert_loop_by_edge(l_b, e); diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_gpencil.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_gpencil.cc index 60311849097..9349a30fd4e 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_gpencil.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_gpencil.cc @@ -31,7 +31,7 @@ void GPencilBackup::restore_to_gpencil(bGPdata *gpd) BKE_gpencil_free_update_cache(gpd_orig); } /* Doing a copy-on-write copies the update cache pointer. Make sure to reset it - * to NULL as we should never use the update cache from eval data. */ + * to null as we should never use the update cache from eval data. */ gpd->runtime.update_cache = nullptr; /* Make sure to update the original runtime pointers in the eval data. */ BKE_gpencil_data_update_orig_pointers(gpd_orig, gpd); diff --git a/source/blender/draw/intern/draw_cache_impl_curve.cc b/source/blender/draw/intern/draw_cache_impl_curve.cc index d3e7b452a10..be443099d6b 100644 --- a/source/blender/draw/intern/draw_cache_impl_curve.cc +++ b/source/blender/draw/intern/draw_cache_impl_curve.cc @@ -195,8 +195,8 @@ enum { CU_DATATYPE_TEXT_SELECT = 1 << 4, }; -/* - * ob_curve_cache can be NULL +/** + * \param ob_curve_cache: can be null. */ static CurveRenderData *curve_render_data_create(Curve *cu, CurveCache *ob_curve_cache, diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.cc b/source/blender/editors/sculpt_paint/sculpt_undo.cc index bb14c615ae2..c649fa77561 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.cc +++ b/source/blender/editors/sculpt_paint/sculpt_undo.cc @@ -243,7 +243,7 @@ void sculpt_undo_print_nodes(Object *ob, void *active) UndoStack *ustack = ED_undo_stack_get(); UndoStep *us = ustack->steps.first; - if (active == NULL) { + if (active == nullptr) { active = ustack->step_active; } @@ -1822,7 +1822,7 @@ void SCULPT_undo_push_end_ex(Object *ob, const bool use_nested_undo) ustack, BKE_UNDOSYS_TYPE_SCULPT); sculpt_save_active_attribute(ob, &us->active_color_end); - sculpt_undo_print_nodes(ob, NULL); + sculpt_undo_print_nodes(ob, nullptr); } /* -------------------------------------------------------------------- */ @@ -1922,7 +1922,7 @@ static void sculpt_undosys_step_decode_undo_impl(bContext *C, sculpt_undo_restore_list(C, depsgraph, &us->data.nodes); us->step.is_applied = false; - sculpt_undo_print_nodes(CTX_data_active_object(C), NULL); + sculpt_undo_print_nodes(CTX_data_active_object(C), nullptr); } static void sculpt_undosys_step_decode_redo_impl(bContext *C, @@ -1934,7 +1934,7 @@ static void sculpt_undosys_step_decode_redo_impl(bContext *C, sculpt_undo_restore_list(C, depsgraph, &us->data.nodes); us->step.is_applied = true; - sculpt_undo_print_nodes(CTX_data_active_object(C), NULL); + sculpt_undo_print_nodes(CTX_data_active_object(C), nullptr); } static void sculpt_undosys_step_decode_undo(bContext *C, diff --git a/source/blender/editors/space_image/image_undo.cc b/source/blender/editors/space_image/image_undo.cc index 63c314b855f..13b19f6a3b5 100644 --- a/source/blender/editors/space_image/image_undo.cc +++ b/source/blender/editors/space_image/image_undo.cc @@ -1062,7 +1062,7 @@ void ED_image_undosys_type(UndoType *ut) /* NOTE: this is actually a confusing case, since it expects a valid context, but only in a * specific case, see `image_undosys_step_encode` code. We cannot specify - * `UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE` though, as it can be called with a NULL context by + * `UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE` though, as it can be called with a null context by * current code. */ ut->flags = UNDOTYPE_FLAG_DECODE_ACTIVE_STEP; diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.cc b/source/blender/editors/space_outliner/outliner_dragdrop.cc index 651e28205e6..ca645a79a68 100644 --- a/source/blender/editors/space_outliner/outliner_dragdrop.cc +++ b/source/blender/editors/space_outliner/outliner_dragdrop.cc @@ -243,7 +243,7 @@ static int outliner_get_insert_index(TreeElement *drag_te, TreeElementInsertType insert_type, ListBase *listbase) { - /* Find the element to insert after. NULL is the start of the list. */ + /* Find the element to insert after. Null is the start of the list. */ if (drag_te->index < drop_te->index) { if (insert_type == TE_INSERT_BEFORE) { drop_te = drop_te->prev; diff --git a/source/blender/editors/space_outliner/outliner_edit.cc b/source/blender/editors/space_outliner/outliner_edit.cc index 4b3a61d31b9..aeb3bb604cd 100644 --- a/source/blender/editors/space_outliner/outliner_edit.cc +++ b/source/blender/editors/space_outliner/outliner_edit.cc @@ -1279,7 +1279,8 @@ static int outliner_open_back(TreeElement *te) return retval; } -/* Return element representing the active base or bone in the outliner, or NULL if none exists +/** + * \return element representing the active base or bone in the outliner, or null if none exists */ static TreeElement *outliner_show_active_get_element(bContext *C, SpaceOutliner *space_outliner, diff --git a/source/blender/editors/space_outliner/tree/tree_display_libraries.cc b/source/blender/editors/space_outliner/tree/tree_display_libraries.cc index bbda66a9d92..b8f40f82b02 100644 --- a/source/blender/editors/space_outliner/tree/tree_display_libraries.cc +++ b/source/blender/editors/space_outliner/tree/tree_display_libraries.cc @@ -51,7 +51,7 @@ ListBase TreeDisplayLibraries::buildTree(const TreeSourceData &source_data) for (ID *id : List(source_data.bmain->libraries)) { Library *lib = reinterpret_cast(id); TreeElement *ten = add_library_contents(*source_data.bmain, tree, lib); - /* NULL-check matters, due to filtering there may not be a new element. */ + /* Null-check matters, due to filtering there may not be a new element. */ if (ten) { lib->id.newid = (ID *)ten; } diff --git a/source/blender/editors/uvedit/uvedit_select.cc b/source/blender/editors/uvedit/uvedit_select.cc index d91123681a6..e4ea95873e8 100644 --- a/source/blender/editors/uvedit/uvedit_select.cc +++ b/source/blender/editors/uvedit/uvedit_select.cc @@ -117,7 +117,7 @@ BMLoop *ED_uvedit_active_vert_loop_get(BMesh *bm) if (ese && ese->prev) { BMEditSelection *ese_prev = ese->prev; if ((ese->htype == BM_VERT) && (ese_prev->htype == BM_FACE)) { - /* May be NULL. */ + /* May be null. */ return BM_face_vert_share_loop((BMFace *)ese_prev->ele, (BMVert *)ese->ele); } } @@ -139,7 +139,7 @@ BMLoop *ED_uvedit_active_edge_loop_get(BMesh *bm) if (ese && ese->prev) { BMEditSelection *ese_prev = ese->prev; if ((ese->htype == BM_EDGE) && (ese_prev->htype == BM_FACE)) { - /* May be NULL. */ + /* May be null. */ return BM_face_edge_share_loop((BMFace *)ese_prev->ele, (BMEdge *)ese->ele); } } @@ -2541,7 +2541,7 @@ static bool uv_mouse_select_multi(bContext *C, } else { /* Vertex or island. For island (if we were using #uv_find_nearest_face_multi_ex, see above), - * `hit.l` is NULL, use `hit.efa` instead. */ + * `hit.l` is null, use `hit.efa` instead. */ if (hit.l != nullptr) { is_selected = uvedit_uv_select_test(scene, hit.l, offsets); } diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.cc b/source/blender/editors/uvedit/uvedit_smart_stitch.cc index 221d8871673..965c2ed04a0 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.cc +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.cc @@ -1166,7 +1166,7 @@ static int stitch_process_data(StitchStateContainer *ssc, /* copy data from UVs to the preview display buffers */ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { /* just to test if face was added for processing. - * uvs of unselected vertices will return NULL */ + * uvs of unselected vertices will return null */ UvElement *element = BM_uv_element_get(state->element_map, BM_FACE_FIRST_LOOP(efa)); if (element) { diff --git a/source/blender/geometry/intern/uv_parametrizer.cc b/source/blender/geometry/intern/uv_parametrizer.cc index 36527a1eb10..a16af0a6dc1 100644 --- a/source/blender/geometry/intern/uv_parametrizer.cc +++ b/source/blender/geometry/intern/uv_parametrizer.cc @@ -3026,7 +3026,7 @@ static void p_chart_lscm_begin(PChart *chart, bool live, bool abf) p_chart_boundaries(chart, &outer); - /* Outer can be NULL with non-finite coords. */ + /* Outer can be null with non-finite coordinates. */ if (!(outer && p_chart_symmetry_pins(chart, outer, &pin1, &pin2))) { p_chart_extrema_verts(chart, &pin1, &pin2); } diff --git a/source/blender/gpu/tests/vertex_buffer_test.cc b/source/blender/gpu/tests/vertex_buffer_test.cc index 904b27b10d3..839672d8df4 100644 --- a/source/blender/gpu/tests/vertex_buffer_test.cc +++ b/source/blender/gpu/tests/vertex_buffer_test.cc @@ -55,7 +55,7 @@ static void vertex_buffer_fetch_mode(ColorType color) GPU_vertbuf_vert_set(vbo, i, &data[i]); } - GPUBatch *batch = GPU_batch_create(GPU_PRIM_TRI_FAN, vbo, NULL); + GPUBatch *batch = GPU_batch_create(GPU_PRIM_TRI_FAN, vbo, nullptr); GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR); GPU_batch_draw(batch); diff --git a/source/blender/gpu/vulkan/vk_vertex_attribute_object.cc b/source/blender/gpu/vulkan/vk_vertex_attribute_object.cc index 4934d2a716a..0b49dfd7d60 100644 --- a/source/blender/gpu/vulkan/vk_vertex_attribute_object.cc +++ b/source/blender/gpu/vulkan/vk_vertex_attribute_object.cc @@ -22,7 +22,7 @@ VKVertexAttributeObject::VKVertexAttributeObject() void VKVertexAttributeObject::clear() { is_valid = false; - info.pNext = NULL; + info.pNext = nullptr; bindings.clear(); attributes.clear(); vbos.clear(); diff --git a/source/blender/io/alembic/exporter/abc_custom_props.cc b/source/blender/io/alembic/exporter/abc_custom_props.cc index 36c4bf8f081..b1c22a9d220 100644 --- a/source/blender/io/alembic/exporter/abc_custom_props.cc +++ b/source/blender/io/alembic/exporter/abc_custom_props.cc @@ -53,7 +53,7 @@ void CustomPropertiesExporter::write(const IDProperty *id_property) switch (id_property->type) { case IDP_STRING: { - /* The Alembic library doesn't accept NULL-terminated character arrays. */ + /* The Alembic library doesn't accept null-terminated character arrays. */ const std::string prop_value(IDP_String(id_property), id_property->len - 1); set_scalar_property(id_property->name, prop_value); break; diff --git a/source/blender/io/alembic/exporter/abc_export_capi.cc b/source/blender/io/alembic/exporter/abc_export_capi.cc index 9a80074025e..1b31d4642b4 100644 --- a/source/blender/io/alembic/exporter/abc_export_capi.cc +++ b/source/blender/io/alembic/exporter/abc_export_capi.cc @@ -230,7 +230,7 @@ bool ABC_export(Scene *scene, WM_jobs_start(CTX_wm_manager(C), wm_job); } else { - /* Fake a job context, so that we don't need NULL pointer checks while exporting. */ + /* Fake a job context, so that we don't need null pointer checks while exporting. */ bool stop = false, do_update = false; float progress = 0.0f; diff --git a/source/blender/io/alembic/exporter/abc_writer_hair.cc b/source/blender/io/alembic/exporter/abc_writer_hair.cc index 863a3f8ba33..c13474b742a 100644 --- a/source/blender/io/alembic/exporter/abc_writer_hair.cc +++ b/source/blender/io/alembic/exporter/abc_writer_hair.cc @@ -159,7 +159,7 @@ void ABCHairWriter::write_hair_sample(const HierarchyContext &context, const int num = pa->num_dmcache >= 0 ? pa->num_dmcache : pa->num; if (num < mesh->totface) { - /* TODO(Sybren): check whether the NULL check here and if(mface) are actually required + /* TODO(Sybren): check whether the null check here and if(mface) are actually required */ const MFace *face = mface == nullptr ? nullptr : &mface[num]; MTFace *tface = mtface + num; diff --git a/source/blender/io/alembic/intern/alembic_capi.cc b/source/blender/io/alembic/intern/alembic_capi.cc index e5726c81533..6147d1cc855 100644 --- a/source/blender/io/alembic/intern/alembic_capi.cc +++ b/source/blender/io/alembic/intern/alembic_capi.cc @@ -719,7 +719,7 @@ bool ABC_import(bContext *C, WM_jobs_start(CTX_wm_manager(C), wm_job); } else { - /* Fake a job context, so that we don't need NULL pointer checks while importing. */ + /* Fake a job context, so that we don't need null pointer checks while importing. */ bool stop = false, do_update = false; float progress = 0.0f; diff --git a/source/blender/io/usd/intern/usd_capi_export.cc b/source/blender/io/usd/intern/usd_capi_export.cc index 4decfe3bc77..200a6514857 100644 --- a/source/blender/io/usd/intern/usd_capi_export.cc +++ b/source/blender/io/usd/intern/usd_capi_export.cc @@ -383,7 +383,7 @@ static void create_temp_path_for_usdz_export(const char *filepath, static void set_job_filepath(blender::io::usd::ExportJobData *job, const char *filepath) { - if (BLI_path_extension_check_n(filepath, ".usdz", NULL)) { + if (BLI_path_extension_check_n(filepath, ".usdz", nullptr)) { create_temp_path_for_usdz_export(filepath, job); return; } @@ -432,7 +432,7 @@ bool USD_export(bContext *C, WM_jobs_start(CTX_wm_manager(C), wm_job); } else { - /* Fake a job context, so that we don't need NULL pointer checks while exporting. */ + /* Fake a job context, so that we don't need null pointer checks while exporting. */ bool stop = false, do_update = false; float progress = 0.0f; diff --git a/source/blender/io/usd/intern/usd_capi_import.cc b/source/blender/io/usd/intern/usd_capi_import.cc index ff96daf1b05..e49b8388f74 100644 --- a/source/blender/io/usd/intern/usd_capi_import.cc +++ b/source/blender/io/usd/intern/usd_capi_import.cc @@ -459,7 +459,7 @@ bool USD_import(struct bContext *C, WM_jobs_start(CTX_wm_manager(C), wm_job); } else { - /* Fake a job context, so that we don't need NULL pointer checks while importing. */ + /* Fake a job context, so that we don't need null pointer checks while importing. */ bool stop = false, do_update = false; float progress = 0.0f; diff --git a/source/blender/makesrna/intern/rna_path.cc b/source/blender/makesrna/intern/rna_path.cc index df6ad03efd9..b3a9a46b9cc 100644 --- a/source/blender/makesrna/intern/rna_path.cc +++ b/source/blender/makesrna/intern/rna_path.cc @@ -343,7 +343,7 @@ static bool rna_path_parse_array_index(const char **path, * that represent the whole given \a path). * \param eval_pointer: If \a true, and \a path leads to a Pointer property, or an item in a * Collection property, \a r_ptr will be set to the value of that property, - * and \a r_prop will be NULL. + * and \a r_prop will be null. * Mutually exclusive with \a r_item_ptr. * * \return \a true on success, \a false if the path is somehow invalid. @@ -846,7 +846,7 @@ static char *rna_idp_path(PointerRNA *ptr, if (prop->type == PROP_POINTER) { PointerRNA child_ptr = RNA_property_pointer_get(ptr, prop); if (RNA_pointer_is_null(&child_ptr)) { - /* Pointer ID prop might be a 'leaf' in the IDProp group hierarchy, in which case a NULL + /* Pointer ID prop might be a 'leaf' in the IDProp group hierarchy, in which case a null * value is perfectly valid. Just means it won't match the searched needle. */ continue; } @@ -874,7 +874,7 @@ static char *rna_idp_path(PointerRNA *ptr, if (RNA_property_collection_lookup_int(ptr, prop, j, &child_ptr)) { if (RNA_pointer_is_null(&child_ptr)) { /* Array item ID prop might be a 'leaf' in the IDProp group hierarchy, in which case - * a NULL value is perfectly valid. Just means it won't match the searched needle. */ + * a null value is perfectly valid. Just means it won't match the searched needle. */ continue; } link.index = j; @@ -1024,7 +1024,7 @@ char *RNA_path_from_real_ID_to_struct(Main *bmain, const PointerRNA *ptr, ID **r { char *path = RNA_path_from_ID_to_struct(ptr); - /* NULL path is valid in that case, when given struct is an ID one... */ + /* Null path is valid in that case, when given struct is an ID one. */ return rna_prepend_real_ID_path(bmain, ptr->owner_id, path, r_real); } @@ -1138,7 +1138,7 @@ char *RNA_path_from_real_ID_to_property_index(Main *bmain, { char *path = RNA_path_from_ID_to_property_index(ptr, prop, index_dim, index); - /* NULL path is always an error here, in that case do not return the 'fake ID from real ID' part + /* Null path is always an error here, in that case do not return the 'fake ID from real ID' part * of the path either. */ return path != nullptr ? rna_prepend_real_ID_path(bmain, ptr->owner_id, path, r_real_id) : nullptr; @@ -1231,7 +1231,7 @@ char *RNA_path_full_struct_py(const PointerRNA *ptr) data_path = RNA_path_from_ID_to_struct(ptr); - /* XXX data_path may be NULL (see #36788), + /* XXX data_path may be null (see #36788), * do we want to get the 'bpy.data.foo["bar"].(null)' stuff? */ ret = BLI_sprintfN("%s.%s", id_path, data_path); diff --git a/source/blender/windowmanager/intern/wm_init_exit.cc b/source/blender/windowmanager/intern/wm_init_exit.cc index d429ba24659..f269241ad7b 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.cc +++ b/source/blender/windowmanager/intern/wm_init_exit.cc @@ -546,7 +546,7 @@ void WM_exit_ex(bContext *C, const bool do_python, const bool do_user_exit_actio * Don't run this code when `C` is null because #pyrna_unregister_class * passes in `CTX_data_main(C)` to un-registration functions. * Further: `addon_utils.disable_all()` may call into functions that expect a valid context, - * supporting all these code-paths with a NULL context is quite involved for such a corner-case. + * supporting all these code-paths with a null context is quite involved for such a corner-case. */ if (C) { const char *imports[2] = {"addon_utils", nullptr}; -- 2.30.2 From 7d8c94cb628d33ddfbc1812a1e9b4627f3b3ee7e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 4 Jun 2023 18:46:04 +1000 Subject: [PATCH 42/63] Cleanup: remove redundant struct qualifier --- intern/ghost/intern/GHOST_SystemWayland.cc | 506 +++++++++--------- intern/ghost/intern/GHOST_WindowWayland.cc | 69 ++- .../ghost/intern/GHOST_XrGraphicsBinding.cc | 2 +- .../intern/mallocn_guarded_impl.c | 12 +- source/blender/compositor/intern/COM_Debug.cc | 2 +- .../operations/COM_PreviewOperation.cc | 4 +- .../transform/transform_mode_edge_slide.c | 2 +- .../editors/transform/transform_mode_resize.c | 2 +- .../transform/transform_mode_snapsource.c | 11 +- .../transform/transform_mode_vert_slide.c | 2 +- .../intern/application/Controller.cpp | 2 +- .../blender_interface/BlenderFileLoader.cpp | 4 +- .../blender_interface/FRS_freestyle.cpp | 12 +- .../intern/scene_graph/SceneHash.cpp | 4 +- 14 files changed, 303 insertions(+), 331 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemWayland.cc b/intern/ghost/intern/GHOST_SystemWayland.cc index 3a51fbedb12..a9d1e4113c9 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cc +++ b/intern/ghost/intern/GHOST_SystemWayland.cc @@ -103,9 +103,9 @@ static bool has_libdecor = true; /** \name Forward Declarations * \{ */ -static void keyboard_handle_key_repeat_cancel(struct GWL_Seat *seat); +static void keyboard_handle_key_repeat_cancel(GWL_Seat *seat); -static void output_handle_done(void *data, struct wl_output *wl_output); +static void output_handle_done(void *data, wl_output *wl_output); static void gwl_seat_capability_pointer_disable(GWL_Seat *seat); static void gwl_seat_capability_keyboard_disable(GWL_Seat *seat); @@ -119,14 +119,12 @@ static void gwl_registry_entry_remove_all(GWL_Display *display); struct GWL_RegistryHandler; static int gwl_registry_handler_interface_slot_max(); static int gwl_registry_handler_interface_slot_from_string(const char *interface); -static const struct GWL_RegistryHandler *gwl_registry_handler_from_interface_slot( - int interface_slot); +static const GWL_RegistryHandler *gwl_registry_handler_from_interface_slot(int interface_slot); #ifdef USE_EVENT_BACKGROUND_THREAD static void gwl_display_event_thread_destroy(GWL_Display *display); -static void ghost_wl_display_lock_without_input(struct wl_display *wl_display, - std::mutex *server_mutex); +static void ghost_wl_display_lock_without_input(wl_display *wl_display, std::mutex *server_mutex); /** Default size for pending event vector. */ constexpr size_t events_pending_default_size = 4096 / sizeof(void *); @@ -376,10 +374,10 @@ struct GWL_Cursor { bool is_hardware = true; /** When true, a custom image is used to display the cursor (stored in `wl_image`). */ bool is_custom = false; - struct wl_surface *wl_surface_cursor = nullptr; + wl_surface *wl_surface_cursor = nullptr; struct wl_buffer *wl_buffer = nullptr; - struct wl_cursor_image wl_image = {0}; - struct wl_cursor_theme *wl_theme = nullptr; + wl_cursor_image wl_image = {0}; + wl_cursor_theme *wl_theme = nullptr; void *custom_data = nullptr; /** The size of `custom_data` in bytes. */ size_t custom_data_size = 0; @@ -403,9 +401,9 @@ struct GWL_Cursor { * Since are no API's to access properties of the tool, store the values here. */ struct GWL_TabletTool { - struct GWL_Seat *seat = nullptr; + GWL_Seat *seat = nullptr; /** Tablets have a separate cursor to the 'pointer', this surface is used for cursor drawing. */ - struct wl_surface *wl_surface_cursor = nullptr; + wl_surface *wl_surface_cursor = nullptr; /** Used to delay clearing tablet focused wl_surface until the frame is handled. */ bool proximity = false; @@ -422,7 +420,7 @@ struct GWL_TabletTool { * Data storage used for clipboard paste & drag-and-drop. */ struct GWL_DataOffer { - struct wl_data_offer *id = nullptr; + wl_data_offer *id = nullptr; std::unordered_set types; struct { @@ -451,7 +449,7 @@ struct GWL_DataOffer { * \{ */ struct GWL_DataSource { - struct wl_data_source *wl_source = nullptr; + wl_data_source *wl_source = nullptr; GWL_SimpleBuffer buffer_out; }; @@ -470,7 +468,7 @@ struct GWL_DataSource { * Therefor keyboard events must always check the window has not been cleared. */ struct GWL_KeyRepeatPlayload { - struct GWL_Seat *seat = nullptr; + GWL_Seat *seat = nullptr; xkb_keycode_t key_code; @@ -520,7 +518,7 @@ struct GWL_SeatStatePointer { * The wl_surface last used with this pointing device * (events with this pointing device will be sent here). */ - struct wl_surface *wl_surface_window = nullptr; + wl_surface *wl_surface_window = nullptr; GHOST_Buttons buttons = GHOST_Buttons(); }; @@ -584,7 +582,7 @@ struct GWL_SeatStateKeyboard { * The wl_surface last used with this pointing device * (events with this pointing device will be sent here). */ - struct wl_surface *wl_surface_window = nullptr; + wl_surface *wl_surface_window = nullptr; }; /** @@ -598,7 +596,7 @@ struct GWL_KeyboardDepressedState { #ifdef WITH_GHOST_WAYLAND_LIBDECOR struct GWL_LibDecor_System { - struct libdecor *context = nullptr; + libdecor *context = nullptr; }; static void gwl_libdecor_system_destroy(GWL_LibDecor_System *decor) @@ -612,14 +610,14 @@ static void gwl_libdecor_system_destroy(GWL_LibDecor_System *decor) #endif struct GWL_XDG_Decor_System { - struct xdg_wm_base *shell = nullptr; + xdg_wm_base *shell = nullptr; uint32_t shell_name = WL_NAME_UNSET; - struct zxdg_decoration_manager_v1 *manager = nullptr; + zxdg_decoration_manager_v1 *manager = nullptr; uint32_t manager_name = WL_NAME_UNSET; }; -static void gwl_xdg_decor_system_destroy(struct GWL_Display *display, GWL_XDG_Decor_System *decor) +static void gwl_xdg_decor_system_destroy(GWL_Display *display, GWL_XDG_Decor_System *decor) { if (decor->manager) { gwl_registry_entry_remove_by_name(display, decor->manager_name, nullptr); @@ -633,13 +631,13 @@ static void gwl_xdg_decor_system_destroy(struct GWL_Display *display, GWL_XDG_De } struct GWL_PrimarySelection_DataOffer { - struct zwp_primary_selection_offer_v1 *id = nullptr; + zwp_primary_selection_offer_v1 *id = nullptr; std::unordered_set types; }; struct GWL_PrimarySelection_DataSource { - struct zwp_primary_selection_source_v1 *wp_source = nullptr; + zwp_primary_selection_source_v1 *wp_source = nullptr; GWL_SimpleBuffer buffer_out; }; @@ -685,16 +683,16 @@ struct GWL_Seat { struct wl_pointer *wl_pointer = nullptr; struct wl_touch *wl_touch = nullptr; struct wl_keyboard *wl_keyboard = nullptr; - struct zwp_tablet_seat_v2 *wp_tablet_seat = nullptr; + zwp_tablet_seat_v2 *wp_tablet_seat = nullptr; #ifdef ZWP_POINTER_GESTURE_HOLD_V1_INTERFACE - struct zwp_pointer_gesture_hold_v1 *wp_pointer_gesture_hold = nullptr; + zwp_pointer_gesture_hold_v1 *wp_pointer_gesture_hold = nullptr; #endif #ifdef ZWP_POINTER_GESTURE_PINCH_V1_INTERFACE - struct zwp_pointer_gesture_pinch_v1 *wp_pointer_gesture_pinch = nullptr; + zwp_pointer_gesture_pinch_v1 *wp_pointer_gesture_pinch = nullptr; #endif #ifdef ZWP_POINTER_GESTURE_SWIPE_V1_INTERFACE - struct zwp_pointer_gesture_swipe_v1 *wp_pointer_gesture_swipe = nullptr; + zwp_pointer_gesture_swipe_v1 *wp_pointer_gesture_swipe = nullptr; #endif /** All currently active tablet tools (needed for changing the cursor). */ @@ -718,11 +716,11 @@ struct GWL_Seat { /** The cursor location (in pixel-space) when hidden grab started (#GHOST_kGrabHide). */ wl_fixed_t grab_lock_xy[2] = {0, 0}; - struct GWL_Cursor cursor; + GWL_Cursor cursor; - struct zwp_relative_pointer_v1 *wp_relative_pointer = nullptr; - struct zwp_locked_pointer_v1 *wp_locked_pointer = nullptr; - struct zwp_confined_pointer_v1 *wp_confined_pointer = nullptr; + zwp_relative_pointer_v1 *wp_relative_pointer = nullptr; + zwp_locked_pointer_v1 *wp_locked_pointer = nullptr; + zwp_confined_pointer_v1 *wp_confined_pointer = nullptr; struct xkb_context *xkb_context = nullptr; @@ -748,7 +746,7 @@ struct GWL_Seat { #endif /** Keys held matching `xkb_state`. */ - struct GWL_KeyboardDepressedState key_depressed; + GWL_KeyboardDepressedState key_depressed; /** * Cache result of `xkb_keymap_mod_get_index` @@ -771,22 +769,22 @@ struct GWL_Seat { GHOST_ITimerTask *timer = nullptr; } key_repeat; - struct wl_surface *wl_surface_window_focus_dnd = nullptr; + wl_surface *wl_surface_window_focus_dnd = nullptr; struct wl_data_device *wl_data_device = nullptr; /** Drag & Drop. */ - struct GWL_DataOffer *data_offer_dnd = nullptr; + GWL_DataOffer *data_offer_dnd = nullptr; std::mutex data_offer_dnd_mutex; /** Copy & Paste. */ - struct GWL_DataOffer *data_offer_copy_paste = nullptr; + GWL_DataOffer *data_offer_copy_paste = nullptr; std::mutex data_offer_copy_paste_mutex; - struct GWL_DataSource *data_source = nullptr; + GWL_DataSource *data_source = nullptr; std::mutex data_source_mutex; - struct zwp_primary_selection_device_v1 *wp_primary_selection_device = nullptr; - struct GWL_PrimarySelection primary_selection; + zwp_primary_selection_device_v1 *wp_primary_selection_device = nullptr; + GWL_PrimarySelection primary_selection; /** * Last input device that was active (pointer/tablet/keyboard). @@ -875,7 +873,7 @@ struct GWL_Display { bool registry_skip_update_all = false; /** Registry entries, kept to allow updating & removal at run-time. */ - struct GWL_RegistryEntry *registry_entry = nullptr; + GWL_RegistryEntry *registry_entry = nullptr; struct wl_registry *wl_registry = nullptr; struct wl_display *wl_display = nullptr; @@ -887,7 +885,7 @@ struct GWL_Display { #endif GWL_XDG_Decor_System *xdg_decor = nullptr; - struct zxdg_output_manager_v1 *xdg_output_manager = nullptr; + zxdg_output_manager_v1 *xdg_output_manager = nullptr; struct wl_shm *wl_shm = nullptr; std::vector outputs; std::vector seats; @@ -906,14 +904,14 @@ struct GWL_Display { /* Managers. */ struct wl_data_device_manager *wl_data_device_manager = nullptr; - struct zwp_tablet_manager_v2 *wp_tablet_manager = nullptr; - struct zwp_relative_pointer_manager_v1 *wp_relative_pointer_manager = nullptr; - struct zwp_primary_selection_device_manager_v1 *wp_primary_selection_device_manager = nullptr; - struct xdg_activation_v1 *xdg_activation_manager = nullptr; - struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager = nullptr; + zwp_tablet_manager_v2 *wp_tablet_manager = nullptr; + zwp_relative_pointer_manager_v1 *wp_relative_pointer_manager = nullptr; + zwp_primary_selection_device_manager_v1 *wp_primary_selection_device_manager = nullptr; + xdg_activation_v1 *xdg_activation_manager = nullptr; + wp_fractional_scale_manager_v1 *wp_fractional_scale_manager = nullptr; struct wp_viewporter *wp_viewporter = nullptr; - struct zwp_pointer_constraints_v1 *wp_pointer_constraints = nullptr; - struct zwp_pointer_gestures_v1 *wp_pointer_gestures = nullptr; + zwp_pointer_constraints_v1 *wp_pointer_constraints = nullptr; + zwp_pointer_gestures_v1 *wp_pointer_gestures = nullptr; /* Threaded event handling. */ #ifdef USE_EVENT_BACKGROUND_THREAD @@ -1295,7 +1293,7 @@ static void gwl_registry_entry_update_all(GWL_Display *display, const int interf /** \name Private Utility Functions * \{ */ -static void ghost_wl_display_report_error(struct wl_display *display) +static void ghost_wl_display_report_error(wl_display *display) { int ecode = wl_display_get_error(display); GHOST_ASSERT(ecode, "Error not set!"); @@ -1638,7 +1636,7 @@ static int file_descriptor_is_io_ready(int fd, const int flags, const int timeou /* Note: We don't bother to account for elapsed time if we get EINTR */ do { #ifdef HAVE_POLL - struct pollfd info; + pollfd info; info.fd = fd; info.events = 0; @@ -1681,7 +1679,7 @@ static int file_descriptor_is_io_ready(int fd, const int flags, const int timeou return result; } -static int ghost_wl_display_event_pump(struct wl_display *wl_display) +static int ghost_wl_display_event_pump(wl_display *wl_display) { /* Based on SDL's `Wayland_PumpEvents`. */ int err; @@ -1709,8 +1707,7 @@ static int ghost_wl_display_event_pump(struct wl_display *wl_display) #ifdef USE_EVENT_BACKGROUND_THREAD -static void ghost_wl_display_lock_without_input(struct wl_display *wl_display, - std::mutex *server_mutex) +static void ghost_wl_display_lock_without_input(wl_display *wl_display, std::mutex *server_mutex) { const int fd = wl_display_get_fd(wl_display); int state; @@ -1727,7 +1724,7 @@ static void ghost_wl_display_lock_without_input(struct wl_display *wl_display, } while (state == 0); } -static int ghost_wl_display_event_pump_from_thread(struct wl_display *wl_display, +static int ghost_wl_display_event_pump_from_thread(wl_display *wl_display, const int fd, std::mutex *server_mutex) { @@ -1794,7 +1791,7 @@ static size_t ghost_wl_shm_format_as_size(enum wl_shm_format format) * \param r_buffer_data: The buffer to be filled. * \param r_buffer_data_size: The size of `r_buffer_data` in bytes. */ -static wl_buffer *ghost_wl_buffer_create_for_image(struct wl_shm *shm, +static wl_buffer *ghost_wl_buffer_create_for_image(wl_shm *shm, const int32_t size_xy[2], enum wl_shm_format format, void **r_buffer_data, @@ -1808,7 +1805,7 @@ static wl_buffer *ghost_wl_buffer_create_for_image(struct wl_shm *shm, if (posix_fallocate(fd, 0, buffer_size) == 0) { void *buffer_data = mmap(nullptr, buffer_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (buffer_data != MAP_FAILED) { - struct wl_shm_pool *pool = wl_shm_create_pool(shm, fd, buffer_size); + wl_shm_pool *pool = wl_shm_create_pool(shm, fd, buffer_size); buffer = wl_shm_pool_create_buffer(pool, 0, UNPACK2(size_xy), buffer_stride, format); wl_shm_pool_destroy(pool); if (buffer) { @@ -1944,7 +1941,7 @@ static void relative_pointer_handle_relative_motion_impl(GWL_Seat *seat, static void relative_pointer_handle_relative_motion( void *data, - struct zwp_relative_pointer_v1 * /*zwp_relative_pointer_v1*/, + zwp_relative_pointer_v1 * /*zwp_relative_pointer_v1*/, const uint32_t /*utime_hi*/, const uint32_t /*utime_lo*/, const wl_fixed_t dx, @@ -2142,14 +2139,14 @@ static char *read_buffer_from_primary_selection_offer(GWL_PrimarySelection_DataO * a target does not accept any of the offered types, type is nullptr. */ static void data_source_handle_target(void * /*data*/, - struct wl_data_source * /*wl_data_source*/, + wl_data_source * /*wl_data_source*/, const char * /*mime_type*/) { CLOG_INFO(LOG, 2, "target"); } static void data_source_handle_send(void *data, - struct wl_data_source * /*wl_data_source*/, + wl_data_source * /*wl_data_source*/, const char * /*mime_type*/, const int32_t fd) { @@ -2173,7 +2170,7 @@ static void data_source_handle_send(void *data, write_thread.detach(); } -static void data_source_handle_cancelled(void *data, struct wl_data_source *wl_data_source) +static void data_source_handle_cancelled(void *data, wl_data_source *wl_data_source) { CLOG_INFO(LOG, 2, "cancelled"); GWL_Seat *seat = static_cast(data); @@ -2193,7 +2190,7 @@ static void data_source_handle_cancelled(void *data, struct wl_data_source *wl_d * emitted afterwards if the drop destination does not accept any mime type. */ static void data_source_handle_dnd_drop_performed(void * /*data*/, - struct wl_data_source * /*wl_data_source*/) + wl_data_source * /*wl_data_source*/) { CLOG_INFO(LOG, 2, "dnd_drop_performed"); } @@ -2205,8 +2202,7 @@ static void data_source_handle_dnd_drop_performed(void * /*data*/, * source, so the client is now free to destroy this data source * and free all associated data. */ -static void data_source_handle_dnd_finished(void * /*data*/, - struct wl_data_source * /*wl_data_source*/) +static void data_source_handle_dnd_finished(void * /*data*/, wl_data_source * /*wl_data_source*/) { CLOG_INFO(LOG, 2, "dnd_finished"); } @@ -2219,7 +2215,7 @@ static void data_source_handle_dnd_finished(void * /*data*/, * action (or none) will be offered here. */ static void data_source_handle_action(void * /*data*/, - struct wl_data_source * /*wl_data_source*/, + wl_data_source * /*wl_data_source*/, const uint32_t dnd_action) { CLOG_INFO(LOG, 2, "handle_action (dnd_action=%u)", dnd_action); @@ -2246,7 +2242,7 @@ static CLG_LogRef LOG_WL_DATA_OFFER = {"ghost.wl.handle.data_offer"}; #define LOG (&LOG_WL_DATA_OFFER) static void data_offer_handle_offer(void *data, - struct wl_data_offer * /*wl_data_offer*/, + wl_data_offer * /*wl_data_offer*/, const char *mime_type) { CLOG_INFO(LOG, 2, "offer (mime_type=%s)", mime_type); @@ -2255,7 +2251,7 @@ static void data_offer_handle_offer(void *data, } static void data_offer_handle_source_actions(void *data, - struct wl_data_offer * /*wl_data_offer*/, + wl_data_offer * /*wl_data_offer*/, const uint32_t source_actions) { CLOG_INFO(LOG, 2, "source_actions (%u)", source_actions); @@ -2264,7 +2260,7 @@ static void data_offer_handle_source_actions(void *data, } static void data_offer_handle_action(void *data, - struct wl_data_offer * /*wl_data_offer*/, + wl_data_offer * /*wl_data_offer*/, const uint32_t dnd_action) { CLOG_INFO(LOG, 2, "actions (%u)", dnd_action); @@ -2290,8 +2286,8 @@ static CLG_LogRef LOG_WL_DATA_DEVICE = {"ghost.wl.handle.data_device"}; #define LOG (&LOG_WL_DATA_DEVICE) static void data_device_handle_data_offer(void * /*data*/, - struct wl_data_device * /*wl_data_device*/, - struct wl_data_offer *id) + wl_data_device * /*wl_data_device*/, + wl_data_offer *id) { CLOG_INFO(LOG, 2, "data_offer"); @@ -2301,12 +2297,12 @@ static void data_device_handle_data_offer(void * /*data*/, } static void data_device_handle_enter(void *data, - struct wl_data_device * /*wl_data_device*/, + wl_data_device * /*wl_data_device*/, const uint32_t serial, - struct wl_surface *wl_surface, + wl_surface *wl_surface, const wl_fixed_t x, const wl_fixed_t y, - struct wl_data_offer *id) + wl_data_offer *id) { if (!ghost_wl_surface_own_with_null_check(wl_surface)) { CLOG_INFO(LOG, 2, "enter (skipped)"); @@ -2342,7 +2338,7 @@ static void data_device_handle_enter(void *data, dnd_events(seat, GHOST_kEventDraggingEntered); } -static void data_device_handle_leave(void *data, struct wl_data_device * /*wl_data_device*/) +static void data_device_handle_leave(void *data, wl_data_device * /*wl_data_device*/) { GWL_Seat *seat = static_cast(data); std::lock_guard lock{seat->data_offer_dnd_mutex}; @@ -2360,7 +2356,7 @@ static void data_device_handle_leave(void *data, struct wl_data_device * /*wl_da } static void data_device_handle_motion(void *data, - struct wl_data_device * /*wl_data_device*/, + wl_data_device * /*wl_data_device*/, const uint32_t /*time*/, const wl_fixed_t x, const wl_fixed_t y) @@ -2376,7 +2372,7 @@ static void data_device_handle_motion(void *data, dnd_events(seat, GHOST_kEventDraggingUpdated); } -static void data_device_handle_drop(void *data, struct wl_data_device * /*wl_data_device*/) +static void data_device_handle_drop(void *data, wl_data_device * /*wl_data_device*/) { GWL_Seat *seat = static_cast(data); std::lock_guard lock{seat->data_offer_dnd_mutex}; @@ -2484,8 +2480,8 @@ static void data_device_handle_drop(void *data, struct wl_data_device * /*wl_dat } static void data_device_handle_selection(void *data, - struct wl_data_device * /*wl_data_device*/, - struct wl_data_offer *id) + wl_data_device * /*wl_data_device*/, + wl_data_offer *id) { GWL_Seat *seat = static_cast(data); @@ -2531,7 +2527,7 @@ static const wl_data_device_listener data_device_listener = { static CLG_LogRef LOG_WL_CURSOR_BUFFER = {"ghost.wl.handle.cursor_buffer"}; #define LOG (&LOG_WL_CURSOR_BUFFER) -static void cursor_buffer_handle_release(void *data, struct wl_buffer *wl_buffer) +static void cursor_buffer_handle_release(void *data, wl_buffer *wl_buffer) { CLOG_INFO(LOG, 2, "release"); @@ -2584,9 +2580,7 @@ static bool update_cursor_scale(GWL_Cursor &cursor, return false; } -static void cursor_surface_handle_enter(void *data, - struct wl_surface *wl_surface, - struct wl_output *wl_output) +static void cursor_surface_handle_enter(void *data, wl_surface *wl_surface, wl_output *wl_output) { if (!ghost_wl_output_own(wl_output)) { CLOG_INFO(LOG, 2, "handle_enter (skipped)"); @@ -2602,9 +2596,7 @@ static void cursor_surface_handle_enter(void *data, update_cursor_scale(seat->cursor, seat->system->wl_shm(), seat_state_pointer, wl_surface); } -static void cursor_surface_handle_leave(void *data, - struct wl_surface *wl_surface, - struct wl_output *wl_output) +static void cursor_surface_handle_leave(void *data, wl_surface *wl_surface, wl_output *wl_output) { if (!(wl_output && ghost_wl_output_own(wl_output))) { CLOG_INFO(LOG, 2, "handle_leave (skipped)"); @@ -2637,9 +2629,9 @@ static CLG_LogRef LOG_WL_POINTER = {"ghost.wl.handle.pointer"}; #define LOG (&LOG_WL_POINTER) static void pointer_handle_enter(void *data, - struct wl_pointer * /*wl_pointer*/, + wl_pointer * /*wl_pointer*/, const uint32_t serial, - struct wl_surface *wl_surface, + wl_surface *wl_surface, const wl_fixed_t surface_x, const wl_fixed_t surface_y) { @@ -2677,9 +2669,9 @@ static void pointer_handle_enter(void *data, } static void pointer_handle_leave(void *data, - struct wl_pointer * /*wl_pointer*/, + wl_pointer * /*wl_pointer*/, const uint32_t /*serial*/, - struct wl_surface *wl_surface) + wl_surface *wl_surface) { /* First clear the `pointer.wl_surface`, since the window won't exist when closing the window. */ static_cast(data)->pointer.wl_surface_window = nullptr; @@ -2691,7 +2683,7 @@ static void pointer_handle_leave(void *data, } static void pointer_handle_motion(void *data, - struct wl_pointer * /*wl_pointer*/, + wl_pointer * /*wl_pointer*/, const uint32_t /*time*/, const wl_fixed_t surface_x, const wl_fixed_t surface_y) @@ -2716,7 +2708,7 @@ static void pointer_handle_motion(void *data, } static void pointer_handle_button(void *data, - struct wl_pointer * /*wl_pointer*/, + wl_pointer * /*wl_pointer*/, const uint32_t serial, const uint32_t /*time*/, const uint32_t button, @@ -2771,7 +2763,7 @@ static void pointer_handle_button(void *data, } static void pointer_handle_axis(void *data, - struct wl_pointer * /*wl_pointer*/, + wl_pointer * /*wl_pointer*/, const uint32_t /*time*/, const uint32_t axis, const wl_fixed_t value) @@ -2787,7 +2779,7 @@ static void pointer_handle_axis(void *data, seat->pointer_scroll.smooth_xy[index] = value; } -static void pointer_handle_frame(void *data, struct wl_pointer * /*wl_pointer*/) +static void pointer_handle_frame(void *data, wl_pointer * /*wl_pointer*/) { CLOG_INFO(LOG, 2, "frame"); GWL_Seat *seat = static_cast(data); @@ -2853,7 +2845,7 @@ static void pointer_handle_frame(void *data, struct wl_pointer * /*wl_pointer*/) seat->pointer_scroll.inverted_xy[1] = false; } static void pointer_handle_axis_source(void *data, - struct wl_pointer * /*wl_pointer*/, + wl_pointer * /*wl_pointer*/, uint32_t axis_source) { CLOG_INFO(LOG, 2, "axis_source (axis_source=%u)", axis_source); @@ -2861,14 +2853,14 @@ static void pointer_handle_axis_source(void *data, seat->pointer_scroll.axis_source = (enum wl_pointer_axis_source)axis_source; } static void pointer_handle_axis_stop(void * /*data*/, - struct wl_pointer * /*wl_pointer*/, + wl_pointer * /*wl_pointer*/, uint32_t /*time*/, uint32_t axis) { CLOG_INFO(LOG, 2, "axis_stop (axis=%u)", axis); } static void pointer_handle_axis_discrete(void *data, - struct wl_pointer * /*wl_pointer*/, + wl_pointer * /*wl_pointer*/, uint32_t axis, int32_t discrete) { @@ -2883,7 +2875,7 @@ static void pointer_handle_axis_discrete(void *data, seat->pointer_scroll.discrete_xy[index] = discrete; } static void pointer_handle_axis_value120(void * /*data*/, - struct wl_pointer * /*wl_pointer*/, + wl_pointer * /*wl_pointer*/, uint32_t axis, int32_t value120) { @@ -2893,7 +2885,7 @@ static void pointer_handle_axis_value120(void * /*data*/, } #ifdef WL_POINTER_AXIS_RELATIVE_DIRECTION_ENUM /* Requires WAYLAND 1.22 or newer. */ static void pointer_handle_axis_relative_direction(void *data, - struct wl_pointer * /*wl_pointer*/, + wl_pointer * /*wl_pointer*/, uint32_t axis, uint32_t direction) { @@ -2938,21 +2930,20 @@ static CLG_LogRef LOG_WL_POINTER_GESTURE_HOLD = {"ghost.wl.handle.pointer_gestur static void gesture_hold_handle_begin( void * /*data*/, - struct zwp_pointer_gesture_hold_v1 * /*zwp_pointer_gesture_hold_v1*/, + zwp_pointer_gesture_hold_v1 * /*zwp_pointer_gesture_hold_v1*/, uint32_t /*serial*/, uint32_t /*time*/, - struct wl_surface * /*surface*/, + wl_surface * /*surface*/, uint32_t fingers) { CLOG_INFO(LOG, 2, "begin (fingers=%u)", fingers); } -static void gesture_hold_handle_end( - void * /*data*/, - struct zwp_pointer_gesture_hold_v1 * /*zwp_pointer_gesture_hold_v1*/, - uint32_t /*serial*/, - uint32_t /*time*/, - int32_t cancelled) +static void gesture_hold_handle_end(void * /*data*/, + zwp_pointer_gesture_hold_v1 * /*zwp_pointer_gesture_hold_v1*/, + uint32_t /*serial*/, + uint32_t /*time*/, + int32_t cancelled) { CLOG_INFO(LOG, 2, "end (cancelled=%i)", cancelled); } @@ -2976,10 +2967,10 @@ static CLG_LogRef LOG_WL_POINTER_GESTURE_PINCH = {"ghost.wl.handle.pointer_gestu # define LOG (&LOG_WL_POINTER_GESTURE_PINCH) static void gesture_pinch_handle_begin(void *data, - struct zwp_pointer_gesture_pinch_v1 * /*pinch*/, + zwp_pointer_gesture_pinch_v1 * /*pinch*/, uint32_t /*serial*/, uint32_t /*time*/, - struct wl_surface * /*surface*/, + wl_surface * /*surface*/, uint32_t fingers) { CLOG_INFO(LOG, 2, "begin (fingers=%u)", fingers); @@ -3021,7 +3012,7 @@ static void gesture_pinch_handle_begin(void *data, * however as the operators are not even using coordinates compatible with each other, * it would be better to resolve this by passing rotation & zoom levels directly, * instead of attempting to handle them as cursor coordinates. */ - const struct GWL_WindowScaleParams &scale_params = win->scale_params(); + const GWL_WindowScaleParams &scale_params = win->scale_params(); seat->pointer_gesture_pinch.scale.factor = gwl_window_scale_int_to( scale_params, seat->pointer_gesture_pinch.scale.factor); seat->pointer_gesture_pinch.rotation.factor = gwl_window_scale_int_to( @@ -3030,7 +3021,7 @@ static void gesture_pinch_handle_begin(void *data, } static void gesture_pinch_handle_update(void *data, - struct zwp_pointer_gesture_pinch_v1 * /*pinch*/, + zwp_pointer_gesture_pinch_v1 * /*pinch*/, uint32_t /*time*/, wl_fixed_t dx, wl_fixed_t dy, @@ -3092,7 +3083,7 @@ static void gesture_pinch_handle_update(void *data, } static void gesture_pinch_handle_end(void * /*data*/, - struct zwp_pointer_gesture_pinch_v1 * /*pinch*/, + zwp_pointer_gesture_pinch_v1 * /*pinch*/, uint32_t /*serial*/, uint32_t /*time*/, int32_t cancelled) @@ -3126,10 +3117,10 @@ static CLG_LogRef LOG_WL_POINTER_GESTURE_SWIPE = {"ghost.wl.handle.pointer_gestu static void gesture_swipe_handle_begin( void * /*data*/, - struct zwp_pointer_gesture_swipe_v1 * /*zwp_pointer_gesture_swipe_v1*/, + zwp_pointer_gesture_swipe_v1 * /*zwp_pointer_gesture_swipe_v1*/, uint32_t /*serial*/, uint32_t /*time*/, - struct wl_surface * /*surface*/, + wl_surface * /*surface*/, uint32_t fingers) { CLOG_INFO(LOG, 2, "begin (fingers=%u)", fingers); @@ -3137,7 +3128,7 @@ static void gesture_swipe_handle_begin( static void gesture_swipe_handle_update( void * /*data*/, - struct zwp_pointer_gesture_swipe_v1 * /*zwp_pointer_gesture_swipe_v1*/, + zwp_pointer_gesture_swipe_v1 * /*zwp_pointer_gesture_swipe_v1*/, uint32_t /*time*/, wl_fixed_t dx, wl_fixed_t dy) @@ -3147,7 +3138,7 @@ static void gesture_swipe_handle_update( static void gesture_swipe_handle_end( void * /*data*/, - struct zwp_pointer_gesture_swipe_v1 * /*zwp_pointer_gesture_swipe_v1*/, + zwp_pointer_gesture_swipe_v1 * /*zwp_pointer_gesture_swipe_v1*/, uint32_t /*serial*/, uint32_t /*time*/, int32_t cancelled) @@ -3178,10 +3169,10 @@ static CLG_LogRef LOG_WL_TOUCH = {"ghost.wl.handle.touch"}; #define LOG (&LOG_WL_TOUCH) static void touch_seat_handle_down(void * /*data*/, - struct wl_touch * /*wl_touch*/, + wl_touch * /*wl_touch*/, uint32_t /*serial*/, uint32_t /*time*/, - struct wl_surface * /*wl_surface*/, + wl_surface * /*wl_surface*/, int32_t /*id*/, wl_fixed_t /*x*/, wl_fixed_t /*y*/) @@ -3190,7 +3181,7 @@ static void touch_seat_handle_down(void * /*data*/, } static void touch_seat_handle_up(void * /*data*/, - struct wl_touch * /*wl_touch*/, + wl_touch * /*wl_touch*/, uint32_t /*serial*/, uint32_t /*time*/, int32_t /*id*/) @@ -3199,7 +3190,7 @@ static void touch_seat_handle_up(void * /*data*/, } static void touch_seat_handle_motion(void * /*data*/, - struct wl_touch * /*wl_touch*/, + wl_touch * /*wl_touch*/, uint32_t /*time*/, int32_t /*id*/, wl_fixed_t /*x*/, @@ -3208,19 +3199,19 @@ static void touch_seat_handle_motion(void * /*data*/, CLOG_INFO(LOG, 2, "motion"); } -static void touch_seat_handle_frame(void * /*data*/, struct wl_touch * /*wl_touch*/) +static void touch_seat_handle_frame(void * /*data*/, wl_touch * /*wl_touch*/) { CLOG_INFO(LOG, 2, "frame"); } -static void touch_seat_handle_cancel(void * /*data*/, struct wl_touch * /*wl_touch*/) +static void touch_seat_handle_cancel(void * /*data*/, wl_touch * /*wl_touch*/) { CLOG_INFO(LOG, 2, "cancel"); } static void touch_seat_handle_shape(void * /*data*/, - struct wl_touch * /*touch*/, + wl_touch * /*touch*/, int32_t /*id*/, wl_fixed_t /*major*/, wl_fixed_t /*minor*/) @@ -3229,7 +3220,7 @@ static void touch_seat_handle_shape(void * /*data*/, } static void touch_seat_handle_orientation(void * /*data*/, - struct wl_touch * /*touch*/, + wl_touch * /*touch*/, int32_t /*id*/, wl_fixed_t /*orientation*/) { @@ -3258,7 +3249,7 @@ static CLG_LogRef LOG_WL_TABLET_TOOL = {"ghost.wl.handle.tablet_tool"}; #define LOG (&LOG_WL_TABLET_TOOL) static void tablet_tool_handle_type(void *data, - struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, + zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, const uint32_t tool_type) { CLOG_INFO(LOG, 2, "type (type=%u)", tool_type); @@ -3269,24 +3260,23 @@ static void tablet_tool_handle_type(void *data, } static void tablet_tool_handle_hardware_serial(void * /*data*/, - struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, + zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, const uint32_t /*hardware_serial_hi*/, const uint32_t /*hardware_serial_lo*/) { CLOG_INFO(LOG, 2, "hardware_serial"); } -static void tablet_tool_handle_hardware_id_wacom( - void * /*data*/, - struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, - const uint32_t /*hardware_id_hi*/, - const uint32_t /*hardware_id_lo*/) +static void tablet_tool_handle_hardware_id_wacom(void * /*data*/, + zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, + const uint32_t /*hardware_id_hi*/, + const uint32_t /*hardware_id_lo*/) { CLOG_INFO(LOG, 2, "hardware_id_wacom"); } static void tablet_tool_handle_capability(void * /*data*/, - struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, + zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, const uint32_t capability) { CLOG_INFO(LOG, @@ -3299,12 +3289,11 @@ static void tablet_tool_handle_capability(void * /*data*/, (capability & ZWP_TABLET_TOOL_V2_CAPABILITY_WHEEL) != 0); } -static void tablet_tool_handle_done(void * /*data*/, - struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/) +static void tablet_tool_handle_done(void * /*data*/, zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/) { CLOG_INFO(LOG, 2, "done"); } -static void tablet_tool_handle_removed(void *data, struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2) +static void tablet_tool_handle_removed(void *data, zwp_tablet_tool_v2 *zwp_tablet_tool_v2) { CLOG_INFO(LOG, 2, "removed"); @@ -3319,10 +3308,10 @@ static void tablet_tool_handle_removed(void *data, struct zwp_tablet_tool_v2 *zw delete tablet_tool; } static void tablet_tool_handle_proximity_in(void *data, - struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, + zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, const uint32_t serial, - struct zwp_tablet_v2 * /*tablet*/, - struct wl_surface *wl_surface) + zwp_tablet_v2 * /*tablet*/, + wl_surface *wl_surface) { if (!ghost_wl_surface_own_with_null_check(wl_surface)) { CLOG_INFO(LOG, 2, "proximity_in (skipped)"); @@ -3357,7 +3346,7 @@ static void tablet_tool_handle_proximity_in(void *data, seat->system->cursor_shape_set(win->getCursorShape()); } static void tablet_tool_handle_proximity_out(void *data, - struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/) + zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/) { CLOG_INFO(LOG, 2, "proximity_out"); GWL_TabletTool *tablet_tool = static_cast(data); @@ -3367,7 +3356,7 @@ static void tablet_tool_handle_proximity_out(void *data, } static void tablet_tool_handle_down(void *data, - struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, + zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, const uint32_t serial) { CLOG_INFO(LOG, 2, "down"); @@ -3387,7 +3376,7 @@ static void tablet_tool_handle_down(void *data, } } -static void tablet_tool_handle_up(void *data, struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/) +static void tablet_tool_handle_up(void *data, zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/) { CLOG_INFO(LOG, 2, "up"); @@ -3406,7 +3395,7 @@ static void tablet_tool_handle_up(void *data, struct zwp_tablet_tool_v2 * /*zwp_ } static void tablet_tool_handle_motion(void *data, - struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, + zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, const wl_fixed_t x, const wl_fixed_t y) { @@ -3422,7 +3411,7 @@ static void tablet_tool_handle_motion(void *data, } static void tablet_tool_handle_pressure(void *data, - struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, + zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, const uint32_t pressure) { const float pressure_unit = float(pressure) / 65535; @@ -3433,14 +3422,14 @@ static void tablet_tool_handle_pressure(void *data, td.Pressure = pressure_unit; } static void tablet_tool_handle_distance(void * /*data*/, - struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, + zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, const uint32_t distance) { CLOG_INFO(LOG, 2, "distance (distance=%u)", distance); } static void tablet_tool_handle_tilt(void *data, - struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, + zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, const wl_fixed_t tilt_x, const wl_fixed_t tilt_y) { @@ -3459,20 +3448,20 @@ static void tablet_tool_handle_tilt(void *data, } static void tablet_tool_handle_rotation(void * /*data*/, - struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, + zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, const wl_fixed_t degrees) { CLOG_INFO(LOG, 2, "rotation (degrees=%.4f)", wl_fixed_to_double(degrees)); } static void tablet_tool_handle_slider(void * /*data*/, - struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, + zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, const int32_t position) { CLOG_INFO(LOG, 2, "slider (position=%d)", position); } static void tablet_tool_handle_wheel(void *data, - struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, + zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, const wl_fixed_t /*degrees*/, const int32_t clicks) { @@ -3490,7 +3479,7 @@ static void tablet_tool_handle_wheel(void *data, } } static void tablet_tool_handle_button(void *data, - struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, + zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, const uint32_t serial, const uint32_t button, const uint32_t state) @@ -3533,7 +3522,7 @@ static void tablet_tool_handle_button(void *data, } } static void tablet_tool_handle_frame(void *data, - struct zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, + zwp_tablet_tool_v2 * /*zwp_tablet_tool_v2*/, const uint32_t /*time*/) { CLOG_INFO(LOG, 2, "frame"); @@ -3594,15 +3583,15 @@ static CLG_LogRef LOG_WL_TABLET_SEAT = {"ghost.wl.handle.tablet_seat"}; #define LOG (&LOG_WL_TABLET_SEAT) static void tablet_seat_handle_tablet_added(void * /*data*/, - struct zwp_tablet_seat_v2 * /*zwp_tablet_seat_v2*/, - struct zwp_tablet_v2 *id) + zwp_tablet_seat_v2 * /*zwp_tablet_seat_v2*/, + zwp_tablet_v2 *id) { CLOG_INFO(LOG, 2, "tablet_added (id=%p)", id); } static void tablet_seat_handle_tool_added(void *data, - struct zwp_tablet_seat_v2 * /*zwp_tablet_seat_v2*/, - struct zwp_tablet_tool_v2 *id) + zwp_tablet_seat_v2 * /*zwp_tablet_seat_v2*/, + zwp_tablet_tool_v2 *id) { CLOG_INFO(LOG, 2, "tool_added (id=%p)", id); @@ -3622,8 +3611,8 @@ static void tablet_seat_handle_tool_added(void *data, } static void tablet_seat_handle_pad_added(void * /*data*/, - struct zwp_tablet_seat_v2 * /*zwp_tablet_seat_v2*/, - struct zwp_tablet_pad_v2 *id) + zwp_tablet_seat_v2 * /*zwp_tablet_seat_v2*/, + zwp_tablet_pad_v2 *id) { CLOG_INFO(LOG, 2, "pad_added (id=%p)", id); } @@ -3646,7 +3635,7 @@ static CLG_LogRef LOG_WL_KEYBOARD = {"ghost.wl.handle.keyboard"}; #define LOG (&LOG_WL_KEYBOARD) static void keyboard_handle_keymap(void *data, - struct wl_keyboard * /*wl_keyboard*/, + wl_keyboard * /*wl_keyboard*/, const uint32_t format, const int32_t fd, const uint32_t size) @@ -3665,7 +3654,7 @@ static void keyboard_handle_keymap(void *data, throw std::runtime_error("keymap mmap failed: " + std::string(std::strerror(errno))); } - struct xkb_keymap *keymap = xkb_keymap_new_from_string( + xkb_keymap *keymap = xkb_keymap_new_from_string( seat->xkb_context, map_str, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS); munmap(map_str, size); close(fd); @@ -3738,10 +3727,10 @@ static void keyboard_handle_keymap(void *data, * Notification that this seat's keyboard focus is on a certain wl_surface. */ static void keyboard_handle_enter(void *data, - struct wl_keyboard * /*wl_keyboard*/, + wl_keyboard * /*wl_keyboard*/, const uint32_t serial, - struct wl_surface *wl_surface, - struct wl_array *keys) + wl_surface *wl_surface, + wl_array *keys) { /* Null when just destroyed. */ if (!ghost_wl_surface_own_with_null_check(wl_surface)) { @@ -3782,9 +3771,9 @@ static void keyboard_handle_enter(void *data, * Notification that this seat's keyboard focus is no longer on a certain wl_surface. */ static void keyboard_handle_leave(void *data, - struct wl_keyboard * /*wl_keyboard*/, + wl_keyboard * /*wl_keyboard*/, const uint32_t /*serial*/, - struct wl_surface *wl_surface) + wl_surface *wl_surface) { if (!ghost_wl_surface_own_with_null_check(wl_surface)) { CLOG_INFO(LOG, 2, "leave (skipped)"); @@ -3811,9 +3800,9 @@ static void keyboard_handle_leave(void *data, * Needed because #GHOST_TKey uses these values as key-codes. */ static xkb_keysym_t xkb_state_key_get_one_sym_without_modifiers( - struct xkb_state *xkb_state_empty, - struct xkb_state *xkb_state_empty_with_numlock, - struct xkb_state *xkb_state_empty_with_shift, + xkb_state *xkb_state_empty, + xkb_state *xkb_state_empty_with_numlock, + xkb_state *xkb_state_empty_with_shift, const bool xkb_use_non_latin_workaround, const xkb_keycode_t key) { @@ -3886,7 +3875,7 @@ static void keyboard_handle_key_repeat_reset(GWL_Seat *seat, const bool use_dela } static void keyboard_handle_key(void *data, - struct wl_keyboard * /*wl_keyboard*/, + wl_keyboard * /*wl_keyboard*/, const uint32_t serial, const uint32_t /*time*/, const uint32_t key, @@ -3926,7 +3915,7 @@ static void keyboard_handle_key(void *data, std::lock_guard lock_timer_guard{*seat->system->timer_mutex}; #endif - struct GWL_KeyRepeatPlayload *key_repeat_payload = nullptr; + GWL_KeyRepeatPlayload *key_repeat_payload = nullptr; /* Delete previous timer. */ if (seat->key_repeat.timer) { @@ -4008,8 +3997,7 @@ static void keyboard_handle_key(void *data, if (key_repeat_payload) { auto key_repeat_fn = [](GHOST_ITimerTask *task, uint64_t /*time*/) { - struct GWL_KeyRepeatPlayload *payload = static_cast( - task->getUserData()); + GWL_KeyRepeatPlayload *payload = static_cast(task->getUserData()); GWL_Seat *seat = payload->seat; if (wl_surface *wl_surface_focus = seat->keyboard.wl_surface_window) { @@ -4032,7 +4020,7 @@ static void keyboard_handle_key(void *data, } static void keyboard_handle_modifiers(void *data, - struct wl_keyboard * /*wl_keyboard*/, + wl_keyboard * /*wl_keyboard*/, const uint32_t serial, const uint32_t mods_depressed, const uint32_t mods_latched, @@ -4065,7 +4053,7 @@ static void keyboard_handle_modifiers(void *data, } static void keyboard_handle_repeat_info(void *data, - struct wl_keyboard * /*wl_keyboard*/, + wl_keyboard * /*wl_keyboard*/, const int32_t rate, const int32_t delay) { @@ -4107,7 +4095,7 @@ static CLG_LogRef LOG_WL_PRIMARY_SELECTION_OFFER = {"ghost.wl.handle.primary_sel #define LOG (&LOG_WL_PRIMARY_SELECTION_OFFER) static void primary_selection_offer_offer(void *data, - struct zwp_primary_selection_offer_v1 *id, + zwp_primary_selection_offer_v1 *id, const char *type) { GWL_PrimarySelection_DataOffer *data_offer = static_cast(data); @@ -4136,8 +4124,8 @@ static CLG_LogRef LOG_WL_PRIMARY_SELECTION_DEVICE = {"ghost.wl.handle.primary_se static void primary_selection_device_handle_data_offer( void * /*data*/, - struct zwp_primary_selection_device_v1 * /*zwp_primary_selection_device_v1*/, - struct zwp_primary_selection_offer_v1 *id) + zwp_primary_selection_device_v1 * /*zwp_primary_selection_device_v1*/, + zwp_primary_selection_offer_v1 *id) { CLOG_INFO(LOG, 2, "data_offer"); @@ -4148,8 +4136,8 @@ static void primary_selection_device_handle_data_offer( static void primary_selection_device_handle_selection( void *data, - struct zwp_primary_selection_device_v1 * /*zwp_primary_selection_device_v1*/, - struct zwp_primary_selection_offer_v1 *id) + zwp_primary_selection_device_v1 * /*zwp_primary_selection_device_v1*/, + zwp_primary_selection_offer_v1 *id) { GWL_PrimarySelection *primary = static_cast(data); @@ -4188,7 +4176,7 @@ static CLG_LogRef LOG_WL_PRIMARY_SELECTION_SOURCE = {"ghost.wl.handle.primary_se #define LOG (&LOG_WL_PRIMARY_SELECTION_SOURCE) static void primary_selection_source_send(void *data, - struct zwp_primary_selection_source_v1 * /*source*/, + zwp_primary_selection_source_v1 * /*source*/, const char * /*mime_type*/, int32_t fd) { @@ -4212,8 +4200,7 @@ static void primary_selection_source_send(void *data, write_thread.detach(); } -static void primary_selection_source_cancelled(void *data, - struct zwp_primary_selection_source_v1 *source) +static void primary_selection_source_cancelled(void *data, zwp_primary_selection_source_v1 *source) { CLOG_INFO(LOG, 2, "cancelled"); @@ -4280,7 +4267,7 @@ static void gwl_seat_capability_pointer_enable(GWL_Seat *seat) if (pointer_gestures) { #ifdef ZWP_POINTER_GESTURE_HOLD_V1_INTERFACE { /* Hold gesture. */ - struct zwp_pointer_gesture_hold_v1 *gesture = zwp_pointer_gestures_v1_get_hold_gesture( + zwp_pointer_gesture_hold_v1 *gesture = zwp_pointer_gestures_v1_get_hold_gesture( pointer_gestures, seat->wl_pointer); zwp_pointer_gesture_hold_v1_set_user_data(gesture, seat); zwp_pointer_gesture_hold_v1_add_listener(gesture, &gesture_hold_listener, seat); @@ -4289,7 +4276,7 @@ static void gwl_seat_capability_pointer_enable(GWL_Seat *seat) #endif #ifdef ZWP_POINTER_GESTURE_PINCH_V1_INTERFACE { /* Pinch gesture. */ - struct zwp_pointer_gesture_pinch_v1 *gesture = zwp_pointer_gestures_v1_get_pinch_gesture( + zwp_pointer_gesture_pinch_v1 *gesture = zwp_pointer_gestures_v1_get_pinch_gesture( pointer_gestures, seat->wl_pointer); zwp_pointer_gesture_pinch_v1_set_user_data(gesture, seat); zwp_pointer_gesture_pinch_v1_add_listener(gesture, &gesture_pinch_listener, seat); @@ -4298,7 +4285,7 @@ static void gwl_seat_capability_pointer_enable(GWL_Seat *seat) #endif #ifdef ZWP_POINTER_GESTURE_SWIPE_V1_INTERFACE { /* Swipe gesture. */ - struct zwp_pointer_gesture_swipe_v1 *gesture = zwp_pointer_gestures_v1_get_swipe_gesture( + zwp_pointer_gesture_swipe_v1 *gesture = zwp_pointer_gestures_v1_get_swipe_gesture( pointer_gestures, seat->wl_pointer); zwp_pointer_gesture_swipe_v1_set_user_data(gesture, seat); zwp_pointer_gesture_swipe_v1_add_listener(gesture, &gesture_swipe_listener, seat); @@ -4318,7 +4305,7 @@ static void gwl_seat_capability_pointer_disable(GWL_Seat *seat) if (pointer_gestures) { #ifdef ZWP_POINTER_GESTURE_HOLD_V1_INTERFACE { /* Hold gesture. */ - struct zwp_pointer_gesture_hold_v1 **gesture_p = &seat->wp_pointer_gesture_hold; + zwp_pointer_gesture_hold_v1 **gesture_p = &seat->wp_pointer_gesture_hold; if (*gesture_p) { zwp_pointer_gesture_hold_v1_destroy(*gesture_p); *gesture_p = nullptr; @@ -4327,7 +4314,7 @@ static void gwl_seat_capability_pointer_disable(GWL_Seat *seat) #endif #ifdef ZWP_POINTER_GESTURE_PINCH_V1_INTERFACE { /* Pinch gesture. */ - struct zwp_pointer_gesture_pinch_v1 **gesture_p = &seat->wp_pointer_gesture_pinch; + zwp_pointer_gesture_pinch_v1 **gesture_p = &seat->wp_pointer_gesture_pinch; if (*gesture_p) { zwp_pointer_gesture_pinch_v1_destroy(*gesture_p); *gesture_p = nullptr; @@ -4336,7 +4323,7 @@ static void gwl_seat_capability_pointer_disable(GWL_Seat *seat) #endif #ifdef ZWP_POINTER_GESTURE_SWIPE_V1_INTERFACE { /* Swipe gesture. */ - struct zwp_pointer_gesture_swipe_v1 **gesture_p = &seat->wp_pointer_gesture_swipe; + zwp_pointer_gesture_swipe_v1 **gesture_p = &seat->wp_pointer_gesture_swipe; if (*gesture_p) { zwp_pointer_gesture_swipe_v1_destroy(*gesture_p); *gesture_p = nullptr; @@ -4406,7 +4393,7 @@ static void gwl_seat_capability_touch_disable(GWL_Seat *seat) static void seat_handle_capabilities(void *data, /* Only used in an assert. */ - [[maybe_unused]] struct wl_seat *wl_seat, + [[maybe_unused]] wl_seat *wl_seat, const uint32_t capabilities) { CLOG_INFO(LOG, @@ -4441,7 +4428,7 @@ static void seat_handle_capabilities(void *data, } } -static void seat_handle_name(void *data, struct wl_seat * /*wl_seat*/, const char *name) +static void seat_handle_name(void *data, wl_seat * /*wl_seat*/, const char *name) { CLOG_INFO(LOG, 2, "name (name=\"%s\")", name); static_cast(data)->name = std::string(name); @@ -4464,7 +4451,7 @@ static CLG_LogRef LOG_WL_XDG_OUTPUT = {"ghost.wl.handle.xdg_output"}; #define LOG (&LOG_WL_XDG_OUTPUT) static void xdg_output_handle_logical_position(void *data, - struct zxdg_output_v1 * /*xdg_output*/, + zxdg_output_v1 * /*xdg_output*/, const int32_t x, const int32_t y) { @@ -4477,7 +4464,7 @@ static void xdg_output_handle_logical_position(void *data, } static void xdg_output_handle_logical_size(void *data, - struct zxdg_output_v1 * /*xdg_output*/, + zxdg_output_v1 * /*xdg_output*/, const int32_t width, const int32_t height) { @@ -4512,7 +4499,7 @@ static void xdg_output_handle_logical_size(void *data, output->has_size_logical = true; } -static void xdg_output_handle_done(void *data, struct zxdg_output_v1 * /*xdg_output*/) +static void xdg_output_handle_done(void *data, zxdg_output_v1 * /*xdg_output*/) { CLOG_INFO(LOG, 2, "done"); /* NOTE: `xdg-output.done` events are deprecated and only apply below version 3 of the protocol. @@ -4524,14 +4511,14 @@ static void xdg_output_handle_done(void *data, struct zxdg_output_v1 * /*xdg_out } static void xdg_output_handle_name(void * /*data*/, - struct zxdg_output_v1 * /*xdg_output*/, + zxdg_output_v1 * /*xdg_output*/, const char *name) { CLOG_INFO(LOG, 2, "name (name=\"%s\")", name); } static void xdg_output_handle_description(void * /*data*/, - struct zxdg_output_v1 * /*xdg_output*/, + zxdg_output_v1 * /*xdg_output*/, const char *description) { CLOG_INFO(LOG, 2, "description (description=\"%s\")", description); @@ -4557,7 +4544,7 @@ static CLG_LogRef LOG_WL_OUTPUT = {"ghost.wl.handle.output"}; #define LOG (&LOG_WL_OUTPUT) static void output_handle_geometry(void *data, - struct wl_output * /*wl_output*/, + wl_output * /*wl_output*/, const int32_t /*x*/, const int32_t /*y*/, const int32_t physical_width, @@ -4585,7 +4572,7 @@ static void output_handle_geometry(void *data, } static void output_handle_mode(void *data, - struct wl_output * /*wl_output*/, + wl_output * /*wl_output*/, const uint32_t flags, const int32_t width, const int32_t height, @@ -4617,7 +4604,7 @@ static void output_handle_mode(void *data, * changes done after that. This allows changes to the output * properties to be seen as atomic, even if they happen via multiple events. */ -static void output_handle_done(void *data, struct wl_output * /*wl_output*/) +static void output_handle_done(void *data, wl_output * /*wl_output*/) { CLOG_INFO(LOG, 2, "done"); @@ -4646,7 +4633,7 @@ static void output_handle_done(void *data, struct wl_output * /*wl_output*/) } } -static void output_handle_scale(void *data, struct wl_output * /*wl_output*/, const int32_t factor) +static void output_handle_scale(void *data, wl_output * /*wl_output*/, const int32_t factor) { CLOG_INFO(LOG, 2, "scale"); GWL_Output *output = static_cast(data); @@ -4672,9 +4659,7 @@ static const wl_output_listener output_listener = { static CLG_LogRef LOG_WL_XDG_WM_BASE = {"ghost.wl.handle.xdg_wm_base"}; #define LOG (&LOG_WL_XDG_WM_BASE) -static void shell_handle_ping(void * /*data*/, - struct xdg_wm_base *xdg_wm_base, - const uint32_t serial) +static void shell_handle_ping(void * /*data*/, xdg_wm_base *xdg_wm_base, const uint32_t serial) { CLOG_INFO(LOG, 2, "ping"); xdg_wm_base_pong(xdg_wm_base, serial); @@ -4697,7 +4682,7 @@ static const xdg_wm_base_listener shell_listener = { static CLG_LogRef LOG_WL_LIBDECOR = {"ghost.wl.handle.libdecor"}; # define LOG (&LOG_WL_LIBDECOR) -static void decor_handle_error(struct libdecor * /*context*/, +static void decor_handle_error(libdecor * /*context*/, enum libdecor_error error, const char *message) { @@ -4709,7 +4694,7 @@ static void decor_handle_error(struct libdecor * /*context*/, exit(EXIT_FAILURE); } -static struct libdecor_interface libdecor_interface = { +static libdecor_interface libdecor_interface = { decor_handle_error, }; @@ -4739,7 +4724,7 @@ static void gwl_registry_compositor_remove(GWL_Display *display, void * /*user_data*/, const bool /*on_exit*/) { - struct wl_compositor **value_p = &display->wl_compositor; + wl_compositor **value_p = &display->wl_compositor; wl_compositor_destroy(*value_p); *value_p = nullptr; } @@ -4761,7 +4746,7 @@ static void gwl_registry_xdg_wm_base_remove(GWL_Display *display, const bool /*on_exit*/) { GWL_XDG_Decor_System &decor = *display->xdg_decor; - struct xdg_wm_base **value_p = &decor.shell; + xdg_wm_base **value_p = &decor.shell; uint32_t *name_p = &decor.shell_name; xdg_wm_base_destroy(*value_p); *value_p = nullptr; @@ -4784,7 +4769,7 @@ static void gwl_registry_xdg_decoration_manager_remove(GWL_Display *display, const bool /*on_exit*/) { GWL_XDG_Decor_System &decor = *display->xdg_decor; - struct zxdg_decoration_manager_v1 **value_p = &decor.manager; + zxdg_decoration_manager_v1 **value_p = &decor.manager; uint32_t *name_p = &decor.manager_name; zxdg_decoration_manager_v1_destroy(*value_p); *value_p = nullptr; @@ -4804,7 +4789,7 @@ static void gwl_registry_xdg_output_manager_remove(GWL_Display *display, void * /*user_data*/, const bool /*on_exit*/) { - struct zxdg_output_manager_v1 **value_p = &display->xdg_output_manager; + zxdg_output_manager_v1 **value_p = &display->xdg_output_manager; zxdg_output_manager_v1_destroy(*value_p); *value_p = nullptr; } @@ -5035,7 +5020,7 @@ static void gwl_registry_wl_shm_remove(GWL_Display *display, void * /*user_data*/, const bool /*on_exit*/) { - struct wl_shm **value_p = &display->wl_shm; + wl_shm **value_p = &display->wl_shm; wl_shm_destroy(*value_p); *value_p = nullptr; } @@ -5053,7 +5038,7 @@ static void gwl_registry_wl_data_device_manager_remove(GWL_Display *display, void * /*user_data*/, const bool /*on_exit*/) { - struct wl_data_device_manager **value_p = &display->wl_data_device_manager; + wl_data_device_manager **value_p = &display->wl_data_device_manager; wl_data_device_manager_destroy(*value_p); *value_p = nullptr; } @@ -5071,7 +5056,7 @@ static void gwl_registry_wp_tablet_manager_remove(GWL_Display *display, void * /*user_data*/, const bool /*on_exit*/) { - struct zwp_tablet_manager_v2 **value_p = &display->wp_tablet_manager; + zwp_tablet_manager_v2 **value_p = &display->wp_tablet_manager; zwp_tablet_manager_v2_destroy(*value_p); *value_p = nullptr; } @@ -5090,7 +5075,7 @@ static void gwl_registry_wp_relative_pointer_manager_remove(GWL_Display *display void * /*user_data*/, const bool /*on_exit*/) { - struct zwp_relative_pointer_manager_v1 **value_p = &display->wp_relative_pointer_manager; + zwp_relative_pointer_manager_v1 **value_p = &display->wp_relative_pointer_manager; zwp_relative_pointer_manager_v1_destroy(*value_p); *value_p = nullptr; } @@ -5108,7 +5093,7 @@ static void gwl_registry_wp_pointer_constraints_remove(GWL_Display *display, void * /*user_data*/, const bool /*on_exit*/) { - struct zwp_pointer_constraints_v1 **value_p = &display->wp_pointer_constraints; + zwp_pointer_constraints_v1 **value_p = &display->wp_pointer_constraints; zwp_pointer_constraints_v1_destroy(*value_p); *value_p = nullptr; } @@ -5126,7 +5111,7 @@ static void gwl_registry_wp_pointer_gestures_remove(GWL_Display *display, void * /*user_data*/, const bool /*on_exit*/) { - struct zwp_pointer_gestures_v1 **value_p = &display->wp_pointer_gestures; + zwp_pointer_gestures_v1 **value_p = &display->wp_pointer_gestures; zwp_pointer_gestures_v1_destroy(*value_p); *value_p = nullptr; } @@ -5144,7 +5129,7 @@ static void gwl_registry_xdg_activation_remove(GWL_Display *display, void * /*user_data*/, const bool /*on_exit*/) { - struct xdg_activation_v1 **value_p = &display->xdg_activation_manager; + xdg_activation_v1 **value_p = &display->xdg_activation_manager; xdg_activation_v1_destroy(*value_p); *value_p = nullptr; } @@ -5163,7 +5148,7 @@ static void gwl_registry_wp_fractional_scale_manager_remove(GWL_Display *display void * /*user_data*/, const bool /*on_exit*/) { - struct wp_fractional_scale_manager_v1 **value_p = &display->wp_fractional_scale_manager; + wp_fractional_scale_manager_v1 **value_p = &display->wp_fractional_scale_manager; wp_fractional_scale_manager_v1_destroy(*value_p); *value_p = nullptr; } @@ -5181,7 +5166,7 @@ static void gwl_registry_wp_viewporter_remove(GWL_Display *display, void * /*user_data*/, const bool /*on_exit*/) { - struct wp_viewporter **value_p = &display->wp_viewporter; + wp_viewporter **value_p = &display->wp_viewporter; wp_viewporter_destroy(*value_p); *value_p = nullptr; } @@ -5189,7 +5174,7 @@ static void gwl_registry_wp_viewporter_remove(GWL_Display *display, /* #GWL_Display.wp_primary_selection_device_manager */ static void gwl_registry_wp_primary_selection_device_manager_add( - struct GWL_Display *display, const GWL_RegisteryAdd_Params *params) + GWL_Display *display, const GWL_RegisteryAdd_Params *params) { display->wp_primary_selection_device_manager = static_cast( @@ -5203,7 +5188,7 @@ static void gwl_registry_wp_primary_selection_device_manager_remove(GWL_Display void * /*user_data*/, const bool /*on_exit*/) { - struct zwp_primary_selection_device_manager_v1 **value_p = + zwp_primary_selection_device_manager_v1 **value_p = &display->wp_primary_selection_device_manager; zwp_primary_selection_device_manager_v1_destroy(*value_p); *value_p = nullptr; @@ -5356,7 +5341,7 @@ static const GWL_RegistryHandler *gwl_registry_handler_from_interface_slot(int i } static void global_handle_add(void *data, - [[maybe_unused]] struct wl_registry *wl_registry, + [[maybe_unused]] wl_registry *wl_registry, const uint32_t name, const char *interface, const uint32_t version) @@ -5420,7 +5405,7 @@ static void global_handle_add(void *data, * using the bind request, the client should now destroy that object. */ static void global_handle_remove(void *data, - [[maybe_unused]] struct wl_registry *wl_registry, + [[maybe_unused]] wl_registry *wl_registry, const uint32_t name) { GWL_Display *display = static_cast(data); @@ -5530,7 +5515,7 @@ GHOST_SystemWayland::GHOST_SystemWayland(bool background) /* Register interfaces. */ { display_->registry_skip_update_all = true; - struct wl_registry *registry = wl_display_get_registry(display_->wl_display); + wl_registry *registry = wl_display_get_registry(display_->wl_display); display_->wl_registry = registry; wl_registry_add_listener(registry, ®istry_listener, display_); /* First round-trip to receive all registry objects. */ @@ -5894,7 +5879,7 @@ static char *system_clipboard_get_primary_selection(GWL_Display *display) auto read_clipboard_fn = [](GWL_PrimarySelection_DataOffer *data_offer, const char *mime_receive, std::mutex *mutex, - struct ThreadResult *thread_result) { + ThreadResult *thread_result) { size_t data_len = 0; thread_result->data = read_buffer_from_primary_selection_offer( data_offer, mime_receive, mutex, true, &data_len); @@ -5943,7 +5928,7 @@ static char *system_clipboard_get(GWL_Display *display) auto read_clipboard_fn = [](GWL_DataOffer *data_offer, const char *mime_receive, std::mutex *mutex, - struct ThreadResult *thread_result) { + ThreadResult *thread_result) { size_t data_len = 0; thread_result->data = read_buffer_from_data_offer( data_offer, mime_receive, mutex, true, &data_len); @@ -6252,7 +6237,7 @@ void GHOST_SystemWayland::getAllDisplayDimensions(uint32_t &width, uint32_t &hei } static GHOST_Context *createOffscreenContext_impl(GHOST_SystemWayland *system, - struct wl_display *wl_display, + wl_display *wl_display, wl_egl_window *egl_window) { /* Caller must lock `system->server_mutex`. */ @@ -6354,7 +6339,7 @@ GHOST_TSuccess GHOST_SystemWayland::disposeContext(GHOST_IContext *context) #ifdef USE_EVENT_BACKGROUND_THREAD std::lock_guard lock_server_guard{*server_mutex}; #endif - struct wl_surface *wl_surface = (struct wl_surface *)((GHOST_Context *)context)->getUserData(); + wl_surface *wl_surface = (struct wl_surface *)((GHOST_Context *)context)->getUserData(); /* Delete the context before the window so the context is able to release * native resources (such as the #EGLSurface) before WAYLAND frees them. */ delete context; @@ -6433,7 +6418,7 @@ static void cursor_buffer_show(const GWL_Seat *seat) const int scale = cursor->is_custom ? cursor->custom_scale : seat->tablet.theme_scale; const int32_t hotspot_x = int32_t(cursor->wl_image.hotspot_x) / scale; const int32_t hotspot_y = int32_t(cursor->wl_image.hotspot_y) / scale; - for (struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2 : seat->tablet_tools) { + for (zwp_tablet_tool_v2 *zwp_tablet_tool_v2 : seat->tablet_tools) { GWL_TabletTool *tablet_tool = static_cast( zwp_tablet_tool_v2_get_user_data(zwp_tablet_tool_v2)); zwp_tablet_tool_v2_set_cursor(zwp_tablet_tool_v2, @@ -6457,7 +6442,7 @@ static void cursor_buffer_show(const GWL_Seat *seat) static void cursor_buffer_hide(const GWL_Seat *seat) { wl_pointer_set_cursor(seat->wl_pointer, seat->pointer.serial, nullptr, 0, 0); - for (struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2 : seat->tablet_tools) { + for (zwp_tablet_tool_v2 *zwp_tablet_tool_v2 : seat->tablet_tools) { zwp_tablet_tool_v2_set_cursor(zwp_tablet_tool_v2, seat->tablet.serial, nullptr, 0, 0); } } @@ -6465,8 +6450,7 @@ static void cursor_buffer_hide(const GWL_Seat *seat) /** * Needed to ensure the cursor size is always a multiple of scale. */ -static int cursor_buffer_compatible_scale_from_image(const struct wl_cursor_image *wl_image, - int scale) +static int cursor_buffer_compatible_scale_from_image(const wl_cursor_image *wl_image, int scale) { const int32_t image_size_x = int32_t(wl_image->width); const int32_t image_size_y = int32_t(wl_image->height); @@ -6481,7 +6465,7 @@ static int cursor_buffer_compatible_scale_from_image(const struct wl_cursor_imag static void cursor_buffer_set_surface_impl(const GWL_Seat *seat, wl_buffer *buffer, - struct wl_surface *wl_surface, + wl_surface *wl_surface, const int scale) { const wl_cursor_image *wl_image = &seat->cursor.wl_image; @@ -6523,7 +6507,7 @@ static void cursor_buffer_set(const GWL_Seat *seat, wl_buffer *buffer) wl_image, cursor->is_custom ? cursor->custom_scale : seat->tablet.theme_scale); const int32_t hotspot_x = int32_t(wl_image->hotspot_x) / scale; const int32_t hotspot_y = int32_t(wl_image->hotspot_y) / scale; - for (struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2 : seat->tablet_tools) { + for (zwp_tablet_tool_v2 *zwp_tablet_tool_v2 : seat->tablet_tools) { GWL_TabletTool *tablet_tool = static_cast( zwp_tablet_tool_v2_get_user_data(zwp_tablet_tool_v2)); cursor_buffer_set_surface_impl(seat, buffer, tablet_tool->wl_surface_cursor, scale); @@ -6624,8 +6608,8 @@ GHOST_TSuccess GHOST_SystemWayland::cursor_shape_set(const GHOST_TStandardCursor return GHOST_kFailure; } - struct wl_cursor_image *image = wl_cursor->images[0]; - struct wl_buffer *buffer = wl_cursor_image_get_buffer(image); + wl_cursor_image *image = wl_cursor->images[0]; + wl_buffer *buffer = wl_cursor_image_get_buffer(image); if (!buffer) { return GHOST_kFailure; } @@ -6860,50 +6844,49 @@ static const char *ghost_wl_surface_tag_id = "GHOST-window"; static const char *ghost_wl_surface_cursor_pointer_tag_id = "GHOST-cursor-pointer"; static const char *ghost_wl_surface_cursor_tablet_tag_id = "GHOST-cursor-tablet"; -bool ghost_wl_output_own(const struct wl_output *wl_output) +bool ghost_wl_output_own(const wl_output *wl_output) { - return wl_proxy_get_tag((struct wl_proxy *)wl_output) == &ghost_wl_output_tag_id; + return wl_proxy_get_tag((wl_proxy *)wl_output) == &ghost_wl_output_tag_id; } -bool ghost_wl_surface_own(const struct wl_surface *wl_surface) +bool ghost_wl_surface_own(const wl_surface *wl_surface) { - return wl_proxy_get_tag((struct wl_proxy *)wl_surface) == &ghost_wl_surface_tag_id; + return wl_proxy_get_tag((wl_proxy *)wl_surface) == &ghost_wl_surface_tag_id; } -bool ghost_wl_surface_own_with_null_check(const struct wl_surface *wl_surface) +bool ghost_wl_surface_own_with_null_check(const wl_surface *wl_surface) { return wl_surface && ghost_wl_surface_own(wl_surface); } -bool ghost_wl_surface_own_cursor_pointer(const struct wl_surface *wl_surface) +bool ghost_wl_surface_own_cursor_pointer(const wl_surface *wl_surface) { - return wl_proxy_get_tag((struct wl_proxy *)wl_surface) == - &ghost_wl_surface_cursor_pointer_tag_id; + return wl_proxy_get_tag((wl_proxy *)wl_surface) == &ghost_wl_surface_cursor_pointer_tag_id; } -bool ghost_wl_surface_own_cursor_tablet(const struct wl_surface *wl_surface) +bool ghost_wl_surface_own_cursor_tablet(const wl_surface *wl_surface) { - return wl_proxy_get_tag((struct wl_proxy *)wl_surface) == &ghost_wl_surface_cursor_tablet_tag_id; + return wl_proxy_get_tag((wl_proxy *)wl_surface) == &ghost_wl_surface_cursor_tablet_tag_id; } -void ghost_wl_output_tag(struct wl_output *wl_output) +void ghost_wl_output_tag(wl_output *wl_output) { - wl_proxy_set_tag((struct wl_proxy *)wl_output, &ghost_wl_output_tag_id); + wl_proxy_set_tag((wl_proxy *)wl_output, &ghost_wl_output_tag_id); } -void ghost_wl_surface_tag(struct wl_surface *wl_surface) +void ghost_wl_surface_tag(wl_surface *wl_surface) { - wl_proxy_set_tag((struct wl_proxy *)wl_surface, &ghost_wl_surface_tag_id); + wl_proxy_set_tag((wl_proxy *)wl_surface, &ghost_wl_surface_tag_id); } -void ghost_wl_surface_tag_cursor_pointer(struct wl_surface *wl_surface) +void ghost_wl_surface_tag_cursor_pointer(wl_surface *wl_surface) { - wl_proxy_set_tag((struct wl_proxy *)wl_surface, &ghost_wl_surface_cursor_pointer_tag_id); + wl_proxy_set_tag((wl_proxy *)wl_surface, &ghost_wl_surface_cursor_pointer_tag_id); } -void ghost_wl_surface_tag_cursor_tablet(struct wl_surface *wl_surface) +void ghost_wl_surface_tag_cursor_tablet(wl_surface *wl_surface) { - wl_proxy_set_tag((struct wl_proxy *)wl_surface, &ghost_wl_surface_cursor_tablet_tag_id); + wl_proxy_set_tag((wl_proxy *)wl_surface, &ghost_wl_surface_cursor_tablet_tag_id); } /** \} */ @@ -6924,26 +6907,26 @@ wl_compositor *GHOST_SystemWayland::wl_compositor() return display_->wl_compositor; } -struct zwp_primary_selection_device_manager_v1 *GHOST_SystemWayland::wp_primary_selection_manager() +zwp_primary_selection_device_manager_v1 *GHOST_SystemWayland::wp_primary_selection_manager() { return display_->wp_primary_selection_device_manager; } -struct xdg_activation_v1 *GHOST_SystemWayland::xdg_activation_manager() +xdg_activation_v1 *GHOST_SystemWayland::xdg_activation_manager() { return display_->xdg_activation_manager; } -struct wp_fractional_scale_manager_v1 *GHOST_SystemWayland::wp_fractional_scale_manager() +wp_fractional_scale_manager_v1 *GHOST_SystemWayland::wp_fractional_scale_manager() { return display_->wp_fractional_scale_manager; } -struct wp_viewporter *GHOST_SystemWayland::wp_viewporter() +wp_viewporter *GHOST_SystemWayland::wp_viewporter() { return display_->wp_viewporter; } -struct zwp_pointer_gestures_v1 *GHOST_SystemWayland::wp_pointer_gestures() +zwp_pointer_gestures_v1 *GHOST_SystemWayland::wp_pointer_gestures() { return display_->wp_pointer_gestures; } @@ -6994,7 +6977,7 @@ const std::vector &GHOST_SystemWayland::outputs() const return display_->outputs; } -struct wl_shm *GHOST_SystemWayland::wl_shm() const +wl_shm *GHOST_SystemWayland::wl_shm() const { return display_->wl_shm; } @@ -7012,7 +6995,7 @@ GHOST_TimerManager *GHOST_SystemWayland::ghost_timer_manager() /** \name Public WAYLAND Query Access * \{ */ -struct GWL_Output *ghost_wl_output_user_data(struct wl_output *wl_output) +GWL_Output *ghost_wl_output_user_data(wl_output *wl_output) { GHOST_ASSERT(wl_output, "output must not be NULL"); GHOST_ASSERT(ghost_wl_output_own(wl_output), "output is not owned by GHOST"); @@ -7020,7 +7003,7 @@ struct GWL_Output *ghost_wl_output_user_data(struct wl_output *wl_output) return output; } -GHOST_WindowWayland *ghost_wl_surface_user_data(struct wl_surface *wl_surface) +GHOST_WindowWayland *ghost_wl_surface_user_data(wl_surface *wl_surface) { GHOST_ASSERT(wl_surface, "wl_surface must not be NULL"); GHOST_ASSERT(ghost_wl_surface_own(wl_surface), "wl_surface is not owned by GHOST"); @@ -7049,12 +7032,12 @@ GHOST_TSuccess GHOST_SystemWayland::pushEvent_maybe_pending(GHOST_IEvent *event) return pushEvent(event); } -void GHOST_SystemWayland::seat_active_set(const struct GWL_Seat *seat) +void GHOST_SystemWayland::seat_active_set(const GWL_Seat *seat) { gwl_display_seat_active_set(display_, seat); } -struct wl_seat *GHOST_SystemWayland::wl_seat_active_get_with_input_serial(uint32_t &serial) +wl_seat *GHOST_SystemWayland::wl_seat_active_get_with_input_serial(uint32_t &serial) { GWL_Seat *seat = gwl_display_seat_active_get(display_); if (seat) { @@ -7139,7 +7122,7 @@ void GHOST_SystemWayland::output_scale_update(GWL_Output *output) } if (seat->tablet.outputs.count(output)) { - for (struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2 : seat->tablet_tools) { + for (zwp_tablet_tool_v2 *zwp_tablet_tool_v2 : seat->tablet_tools) { GWL_TabletTool *tablet_tool = static_cast( zwp_tablet_tool_v2_get_user_data(zwp_tablet_tool_v2)); if (tablet_tool->wl_surface_cursor != nullptr) { @@ -7159,7 +7142,7 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod const GHOST_Rect *wrap_bounds, const GHOST_TAxisFlag wrap_axis, wl_surface *wl_surface, - const struct GWL_WindowScaleParams &scale_params) + const GWL_WindowScaleParams &scale_params) { /* Caller must lock `server_mutex`. */ @@ -7185,10 +7168,9 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod const bool use_software_confine = false; #endif - const struct GWL_SeatStateGrab grab_state_prev = seat_grab_state_from_mode(mode_current, - was_software_confine); - const struct GWL_SeatStateGrab grab_state_next = seat_grab_state_from_mode(mode, - use_software_confine); + const GWL_SeatStateGrab grab_state_prev = seat_grab_state_from_mode(mode_current, + was_software_confine); + const GWL_SeatStateGrab grab_state_next = seat_grab_state_from_mode(mode, use_software_confine); /* Check for wrap as #GHOST_kCapabilityCursorWarp isn't supported. */ const bool use_visible = !(ELEM(mode, GHOST_kGrabHide, GHOST_kGrabWrap) || use_software_confine); diff --git a/intern/ghost/intern/GHOST_WindowWayland.cc b/intern/ghost/intern/GHOST_WindowWayland.cc index 673814b9e4a..23e9ee338a4 100644 --- a/intern/ghost/intern/GHOST_WindowWayland.cc +++ b/intern/ghost/intern/GHOST_WindowWayland.cc @@ -46,7 +46,7 @@ /* Logging, use `ghost.wl.*` prefix. */ #include "CLG_log.h" -static const struct xdg_activation_token_v1_listener *xdg_activation_listener_get(); +static const xdg_activation_token_v1_listener *xdg_activation_listener_get(); static constexpr size_t base_dpi = 96; @@ -57,7 +57,7 @@ static constexpr size_t base_dpi = 96; #ifdef WITH_GHOST_WAYLAND_LIBDECOR struct WGL_LibDecor_Window { - struct libdecor_frame *frame = nullptr; + libdecor_frame *frame = nullptr; bool configured = false; }; @@ -69,9 +69,9 @@ static void gwl_libdecor_window_destroy(WGL_LibDecor_Window *decor) #endif /* WITH_GHOST_WAYLAND_LIBDECOR */ struct WGL_XDG_Decor_Window { - struct xdg_surface *surface = nullptr; - struct zxdg_toplevel_decoration_v1 *toplevel_decor = nullptr; - struct xdg_toplevel *toplevel = nullptr; + xdg_surface *surface = nullptr; + zxdg_toplevel_decoration_v1 *toplevel_decor = nullptr; + xdg_toplevel *toplevel = nullptr; enum zxdg_toplevel_decoration_v1_mode mode = (enum zxdg_toplevel_decoration_v1_mode)0; /** @@ -220,14 +220,14 @@ struct GWL_Window { std::vector outputs; /** A temporary token used for the window to be notified of it's activation. */ - struct xdg_activation_token_v1 *xdg_activation_token = nullptr; + xdg_activation_token_v1 *xdg_activation_token = nullptr; - struct wp_viewport *viewport = nullptr; + wp_viewport *viewport = nullptr; /** * When set, only respond to the #wp_fractional_scale_v1_listener::preferred_scale callback * and ignore updated scale based on #wl_surface_listener::enter & exit events. */ - struct wp_fractional_scale_v1 *fractional_scale_handle = nullptr; + wp_fractional_scale_v1 *fractional_scale_handle = nullptr; #ifdef WITH_GHOST_WAYLAND_LIBDECOR WGL_LibDecor_Window *libdecor = nullptr; @@ -299,7 +299,7 @@ static GHOST_TWindowState gwl_window_state_get(const GWL_Window *win) /** * \note Keep in sync with #gwl_window_state_set_for_xdg. */ -static bool gwl_window_state_set_for_libdecor(struct libdecor_frame *frame, +static bool gwl_window_state_set_for_libdecor(libdecor_frame *frame, const GHOST_TWindowState state, const GHOST_TWindowState state_current) { @@ -344,7 +344,7 @@ static bool gwl_window_state_set_for_libdecor(struct libdecor_frame *frame, /** * \note Keep in sync with #gwl_window_state_set_for_libdecor. */ -static bool gwl_window_state_set_for_xdg(struct xdg_toplevel *toplevel, +static bool gwl_window_state_set_for_xdg(xdg_toplevel *toplevel, const GHOST_TWindowState state, const GHOST_TWindowState state_current) { @@ -452,7 +452,7 @@ static bool gwl_window_viewport_set(GWL_Window *win, if (win->viewport != nullptr) { return false; } - struct wp_viewporter *viewporter = win->ghost_system->wp_viewporter(); + wp_viewporter *viewporter = win->ghost_system->wp_viewporter(); if (viewporter == nullptr) { return false; } @@ -547,7 +547,7 @@ static bool gwl_window_viewport_size_update(GWL_Window *win) static void gwl_window_activate(GWL_Window *win) { GHOST_SystemWayland *system = win->ghost_system; - struct xdg_activation_v1 *activation_manager = system->xdg_activation_manager(); + xdg_activation_v1 *activation_manager = system->xdg_activation_manager(); if (UNLIKELY(activation_manager == nullptr)) { return; } @@ -566,7 +566,7 @@ static void gwl_window_activate(GWL_Window *win) /* The serial of the input device requesting activation. */ { uint32_t serial = 0; - struct wl_seat *seat = system->wl_seat_active_get_with_input_serial(serial); + wl_seat *seat = system->wl_seat_active_get_with_input_serial(serial); if (seat) { xdg_activation_token_v1_set_serial(win->xdg_activation_token, serial, seat); } @@ -577,7 +577,7 @@ static void gwl_window_activate(GWL_Window *win) GHOST_WindowWayland *ghost_window_active = static_cast( system->getWindowManager()->getActiveWindow()); if (ghost_window_active) { - struct wl_surface *surface = ghost_window_active->wl_surface(); + wl_surface *surface = ghost_window_active->wl_surface(); if (surface) { xdg_activation_token_v1_set_surface(win->xdg_activation_token, surface); } @@ -977,7 +977,7 @@ static const xdg_toplevel_listener xdg_toplevel_listener = { * \{ */ static void xdg_activation_handle_done(void *data, - struct xdg_activation_token_v1 *xdg_activation_token_v1, + xdg_activation_token_v1 *xdg_activation_token_v1, const char *token) { GWL_Window *win = static_cast(data); @@ -986,17 +986,17 @@ static void xdg_activation_handle_done(void *data, } GHOST_SystemWayland *system = win->ghost_system; - struct xdg_activation_v1 *activation_manager = system->xdg_activation_manager(); + xdg_activation_v1 *activation_manager = system->xdg_activation_manager(); xdg_activation_v1_activate(activation_manager, token, win->wl_surface); xdg_activation_token_v1_destroy(win->xdg_activation_token); win->xdg_activation_token = nullptr; } -static const struct xdg_activation_token_v1_listener xdg_activation_listener = { +static const xdg_activation_token_v1_listener xdg_activation_listener = { /*done*/ xdg_activation_handle_done, }; -static const struct xdg_activation_token_v1_listener *xdg_activation_listener_get() +static const xdg_activation_token_v1_listener *xdg_activation_listener_get() { return &xdg_activation_listener; } @@ -1013,7 +1013,7 @@ static CLG_LogRef LOG_WL_FRACTIONAL_SCALE = {"ghost.wl.handle.fractional_scale"} #define LOG (&LOG_WL_FRACTIONAL_SCALE) static void wp_fractional_scale_handle_preferred_scale( - void *data, struct wp_fractional_scale_v1 * /*wp_fractional_scale_v1*/, uint preferred_scale) + void *data, wp_fractional_scale_v1 * /*wp_fractional_scale_v1*/, uint preferred_scale) { #ifdef USE_EVENT_BACKGROUND_THREAD std::lock_guard lock_frame_guard{static_cast(data)->frame_pending_mutex}; @@ -1031,7 +1031,7 @@ static void wp_fractional_scale_handle_preferred_scale( } } -static const struct wp_fractional_scale_v1_listener wp_fractional_scale_listener = { +static const wp_fractional_scale_v1_listener wp_fractional_scale_listener = { /*preferred_scale*/ wp_fractional_scale_handle_preferred_scale, }; @@ -1048,8 +1048,8 @@ static const struct wp_fractional_scale_v1_listener wp_fractional_scale_listener static CLG_LogRef LOG_WL_LIBDECOR_FRAME = {"ghost.wl.handle.libdecor_frame"}; # define LOG (&LOG_WL_LIBDECOR_FRAME) -static void frame_handle_configure(struct libdecor_frame *frame, - struct libdecor_configuration *configuration, +static void frame_handle_configure(libdecor_frame *frame, + libdecor_configuration *configuration, void *data) { CLOG_INFO(LOG, 2, "configure"); @@ -1098,7 +1098,7 @@ static void frame_handle_configure(struct libdecor_frame *frame, /* Commit the changes. */ { GWL_Window *win = static_cast(data); - struct libdecor_state *state = libdecor_state_new(UNPACK2(size_next)); + libdecor_state *state = libdecor_state_new(UNPACK2(size_next)); libdecor_frame_commit(frame, state, configuration); libdecor_state_free(state); @@ -1122,7 +1122,7 @@ static void frame_handle_configure(struct libdecor_frame *frame, } } -static void frame_handle_close(struct libdecor_frame * /*frame*/, void *data) +static void frame_handle_close(libdecor_frame * /*frame*/, void *data) { CLOG_INFO(LOG, 2, "close"); @@ -1131,7 +1131,7 @@ static void frame_handle_close(struct libdecor_frame * /*frame*/, void *data) win->ghost_window->close(); } -static void frame_handle_commit(struct libdecor_frame * /*frame*/, void *data) +static void frame_handle_commit(libdecor_frame * /*frame*/, void *data) { CLOG_INFO(LOG, 2, "commit"); @@ -1164,9 +1164,7 @@ static CLG_LogRef LOG_WL_XDG_TOPLEVEL_DECORATION = {"ghost.wl.handle.xdg_topleve #define LOG (&LOG_WL_XDG_TOPLEVEL_DECORATION) static void xdg_toplevel_decoration_handle_configure( - void *data, - struct zxdg_toplevel_decoration_v1 * /*zxdg_toplevel_decoration_v1*/, - const uint32_t mode) + void *data, zxdg_toplevel_decoration_v1 * /*zxdg_toplevel_decoration_v1*/, const uint32_t mode) { CLOG_INFO(LOG, 2, "configure (mode=%u)", mode); @@ -1238,9 +1236,7 @@ static const xdg_surface_listener xdg_surface_listener = { static CLG_LogRef LOG_WL_SURFACE = {"ghost.wl.handle.surface"}; #define LOG (&LOG_WL_SURFACE) -static void surface_handle_enter(void *data, - struct wl_surface * /*wl_surface*/, - struct wl_output *wl_output) +static void surface_handle_enter(void *data, wl_surface * /*wl_surface*/, wl_output *wl_output) { if (!ghost_wl_output_own(wl_output)) { CLOG_INFO(LOG, 2, "enter (skipped)"); @@ -1255,9 +1251,7 @@ static void surface_handle_enter(void *data, } } -static void surface_handle_leave(void *data, - struct wl_surface * /*wl_surface*/, - struct wl_output *wl_output) +static void surface_handle_leave(void *data, wl_surface * /*wl_surface*/, wl_output *wl_output) { if (!ghost_wl_output_own(wl_output)) { CLOG_INFO(LOG, 2, "leave (skipped)"); @@ -1356,8 +1350,7 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system, window_->egl_window = wl_egl_window_create( window_->wl_surface, int(window_->frame.size[0]), int(window_->frame.size[1])); - struct wp_fractional_scale_manager_v1 *fractional_scale_manager = - system->wp_fractional_scale_manager(); + wp_fractional_scale_manager_v1 *fractional_scale_manager = system->wp_fractional_scale_manager(); if (fractional_scale_manager) { window_->fractional_scale_handle = wp_fractional_scale_manager_v1_get_fractional_scale( fractional_scale_manager, window_->wl_surface); @@ -1443,7 +1436,7 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system, /* NOTE: LIBDECOR requires the window to be created & configured before the state can be set. * Workaround this by using the underlying `xdg_toplevel` */ WGL_LibDecor_Window &decor = *window_->libdecor; - struct xdg_toplevel *toplevel = libdecor_frame_get_xdg_toplevel(decor.frame); + xdg_toplevel *toplevel = libdecor_frame_get_xdg_toplevel(decor.frame); gwl_window_state_set_for_xdg(toplevel, state, GHOST_kWindowStateNormal); } else @@ -1831,7 +1824,7 @@ int GHOST_WindowWayland::scale() const return window_->frame.buffer_scale; } -const struct GWL_WindowScaleParams &GHOST_WindowWayland::scale_params() const +const GWL_WindowScaleParams &GHOST_WindowWayland::scale_params() const { /* NOTE(@ideasman42): This could be kept initialized, * since it's such a small struct it's not so important. */ diff --git a/intern/ghost/intern/GHOST_XrGraphicsBinding.cc b/intern/ghost/intern/GHOST_XrGraphicsBinding.cc index 0cbd70756ee..cd6104bab6b 100644 --- a/intern/ghost/intern/GHOST_XrGraphicsBinding.cc +++ b/intern/ghost/intern/GHOST_XrGraphicsBinding.cc @@ -142,7 +142,7 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding { # if defined(WITH_GHOST_WAYLAND) /* #GHOST_SystemWayland */ oxr_binding.wl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_WAYLAND_KHR; - oxr_binding.wl.display = (struct wl_display *)ctx_egl.m_nativeDisplay; + oxr_binding.wl.display = (wl_display *)ctx_egl.m_nativeDisplay; # else GHOST_ASSERT(false, "Unexpected State: logical error, unreachable!"); # endif /* !WITH_GHOST_WAYLAND */ diff --git a/intern/guardedalloc/intern/mallocn_guarded_impl.c b/intern/guardedalloc/intern/mallocn_guarded_impl.c index 0773c6b0051..a4d9225dc03 100644 --- a/intern/guardedalloc/intern/mallocn_guarded_impl.c +++ b/intern/guardedalloc/intern/mallocn_guarded_impl.c @@ -147,8 +147,8 @@ static const char *check_memlist(MemHead *memh); static uint totblock = 0; static size_t mem_in_use = 0, peak_mem = 0; -static volatile struct localListBase _membase; -static volatile struct localListBase *membase = &_membase; +static volatile localListBase _membase; +static volatile localListBase *membase = &_membase; static void (*error_callback)(const char *) = NULL; static bool malloc_debug_memset = false; @@ -923,7 +923,7 @@ void MEM_guarded_freeN(void *vmemh) static void addtail(volatile localListBase *listbase, void *vlink) { - struct localLink *link = vlink; + localLink *link = vlink; /* for a generic API error checks here is fine but * the limited use here they will never be NULL */ @@ -938,7 +938,7 @@ static void addtail(volatile localListBase *listbase, void *vlink) link->prev = listbase->last; if (listbase->last) { - ((struct localLink *)listbase->last)->next = link; + ((localLink *)listbase->last)->next = link; } if (listbase->first == NULL) { listbase->first = link; @@ -948,7 +948,7 @@ static void addtail(volatile localListBase *listbase, void *vlink) static void remlink(volatile localListBase *listbase, void *vlink) { - struct localLink *link = vlink; + localLink *link = vlink; /* for a generic API error checks here is fine but * the limited use here they will never be NULL */ @@ -1127,7 +1127,7 @@ static const char *check_memlist(MemHead *memh) } else { forwok->next = NULL; - membase->last = (struct localLink *)&forwok->next; + membase->last = (localLink *)&forwok->next; } } else { diff --git a/source/blender/compositor/intern/COM_Debug.cc b/source/blender/compositor/intern/COM_Debug.cc index 0d874b27568..72098bc9164 100644 --- a/source/blender/compositor/intern/COM_Debug.cc +++ b/source/blender/compositor/intern/COM_Debug.cc @@ -468,7 +468,7 @@ void DebugInfo::delete_operation_exports() { const std::string dir = get_operations_export_dir(); if (BLI_exists(dir.c_str())) { - struct direntry *file_list; + direntry *file_list; int file_list_num = BLI_filelist_dir_contents(dir.c_str(), &file_list); for (int i = 0; i < file_list_num; i++) { direntry *file = &file_list[i]; diff --git a/source/blender/compositor/operations/COM_PreviewOperation.cc b/source/blender/compositor/operations/COM_PreviewOperation.cc index f95128c41aa..4bbc9dbeb7f 100644 --- a/source/blender/compositor/operations/COM_PreviewOperation.cc +++ b/source/blender/compositor/operations/COM_PreviewOperation.cc @@ -66,7 +66,7 @@ void PreviewOperation::execute_region(rcti *rect, uint /*tile_number*/) { int offset; float color[4]; - struct ColormanageProcessor *cm_processor; + ColormanageProcessor *cm_processor; cm_processor = IMB_colormanagement_display_processor_new(view_settings_, display_settings_); @@ -160,7 +160,7 @@ void PreviewOperation::update_memory_buffer_partial(MemoryBuffer * /*output*/, Span inputs) { MemoryBuffer *input = inputs[0]; - struct ColormanageProcessor *cm_processor = IMB_colormanagement_display_processor_new( + ColormanageProcessor *cm_processor = IMB_colormanagement_display_processor_new( view_settings_, display_settings_); rcti buffer_area; diff --git a/source/blender/editors/transform/transform_mode_edge_slide.c b/source/blender/editors/transform/transform_mode_edge_slide.c index 163b498e634..45055def43b 100644 --- a/source/blender/editors/transform/transform_mode_edge_slide.c +++ b/source/blender/editors/transform/transform_mode_edge_slide.c @@ -1480,7 +1480,7 @@ static void applyEdgeSlide(TransInfo *t, const int UNUSED(mval[2])) ED_area_status_text(t->area, str); } -static void edge_slide_transform_matrix_fn(struct TransInfo *t, float mat_xform[4][4]) +static void edge_slide_transform_matrix_fn(TransInfo *t, float mat_xform[4][4]) { float delta[3], orig_co[3], final_co[3]; diff --git a/source/blender/editors/transform/transform_mode_resize.c b/source/blender/editors/transform/transform_mode_resize.c index 6387b8160bf..05a73aa0972 100644 --- a/source/blender/editors/transform/transform_mode_resize.c +++ b/source/blender/editors/transform/transform_mode_resize.c @@ -286,7 +286,7 @@ static void applyResize(TransInfo *t, const int UNUSED(mval[2])) ED_area_status_text(t->area, str); } -static void resize_transform_matrix_fn(struct TransInfo *t, float mat_xform[4][4]) +static void resize_transform_matrix_fn(TransInfo *t, float mat_xform[4][4]) { float mat4[4][4]; copy_m4_m3(mat4, t->mat); diff --git a/source/blender/editors/transform/transform_mode_snapsource.c b/source/blender/editors/transform/transform_mode_snapsource.c index eb3acd6938c..43307022100 100644 --- a/source/blender/editors/transform/transform_mode_snapsource.c +++ b/source/blender/editors/transform/transform_mode_snapsource.c @@ -40,11 +40,8 @@ struct SnapSouceCustomData { eSnapTargetOP target_operation_prev; struct { - void (*apply)(struct TransInfo *t, - struct MouseInput *mi, - const double mval[2], - float output[3]); - void (*post)(struct TransInfo *t, float values[3]); + void (*apply)(TransInfo *t, MouseInput *mi, const double mval[2], float output[3]); + void (*post)(TransInfo *t, float values[3]); bool use_virtual_mval; } mouse_prev; }; @@ -111,7 +108,7 @@ static void snapsource_confirm(TransInfo *t) t->tsnap.flag &= ~SCE_SNAP_PROJECT; } -static eRedrawFlag snapsource_handle_event_fn(struct TransInfo *t, const struct wmEvent *event) +static eRedrawFlag snapsource_handle_event_fn(TransInfo *t, const wmEvent *event) { if (event->type == EVT_MODAL_MAP) { switch (event->val) { @@ -224,7 +221,7 @@ void transform_mode_snap_source_init(TransInfo *t, wmOperator *UNUSED(op)) #ifdef REMOVE_GIZMO struct wmGizmo *gz = WM_gizmomap_get_modal(t->region->gizmo_map); if (gz) { - const struct wmEvent *event = CTX_wm_window(t->context)->eventstate; + const wmEvent *event = CTX_wm_window(t->context)->eventstate; # ifdef RESET_TRANSFORMATION wmGizmoFnModal modal_fn = gz->custom_modal ? gz->custom_modal : gz->type->modal; modal_fn(t->context, gz, event, 0); diff --git a/source/blender/editors/transform/transform_mode_vert_slide.c b/source/blender/editors/transform/transform_mode_vert_slide.c index 8d740e813d9..969213e5318 100644 --- a/source/blender/editors/transform/transform_mode_vert_slide.c +++ b/source/blender/editors/transform/transform_mode_vert_slide.c @@ -610,7 +610,7 @@ static void applyVertSlide(TransInfo *t, const int UNUSED(mval[2])) ED_area_status_text(t->area, str); } -static void vert_slide_transform_matrix_fn(struct TransInfo *t, float mat_xform[4][4]) +static void vert_slide_transform_matrix_fn(TransInfo *t, float mat_xform[4][4]) { float delta[3], orig_co[3], final_co[3]; diff --git a/source/blender/freestyle/intern/application/Controller.cpp b/source/blender/freestyle/intern/application/Controller.cpp index 997c4096c5e..a780946c708 100644 --- a/source/blender/freestyle/intern/application/Controller.cpp +++ b/source/blender/freestyle/intern/application/Controller.cpp @@ -936,7 +936,7 @@ void Controller::InsertStyleModule(uint index, const char *iName, const char *iB _Canvas->InsertStyleModule(index, sm); } -void Controller::InsertStyleModule(uint index, const char *iName, struct Text *iText) +void Controller::InsertStyleModule(uint index, const char *iName, Text *iText) { StyleModule *sm = new BlenderStyleModule(iText, iName, _inter); _Canvas->InsertStyleModule(index, sm); diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp index 78fcb5fd595..8dc6c131322 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp @@ -260,7 +260,7 @@ void BlenderFileLoader::clipTriangle(int numTris, (void)numTris; /* Ignored in release builds. */ } -void BlenderFileLoader::addTriangle(struct LoaderState *ls, +void BlenderFileLoader::addTriangle(LoaderState *ls, float v1[3], float v2[3], float v3[3], @@ -502,7 +502,7 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id) uint *NIndices = new uint[niSize]; uint *MIndices = new uint[viSize]; // Material Indices - struct LoaderState ls; + LoaderState ls; ls.pv = vertices; ls.pn = normals; ls.pm = faceEdgeMarks; diff --git a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp index f42a05b37fb..0da83e44889 100644 --- a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp +++ b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp @@ -51,7 +51,7 @@ using namespace Freestyle; extern "C" { -struct FreestyleGlobals g_freestyle; +FreestyleGlobals g_freestyle; // Freestyle configuration static bool freestyle_is_initialized = false; @@ -63,8 +63,8 @@ static AppView *view = nullptr; static FreestyleLineSet lineset_buffer; static bool lineset_copied = false; -static void load_post_callback(struct Main * /*main*/, - struct PointerRNA ** /*pointers*/, +static void load_post_callback(Main * /*main*/, + PointerRNA ** /*pointers*/, const int /*num_pointers*/, void * /*arg*/) { @@ -190,7 +190,7 @@ struct edge_type_condition { }; // examines the conditions and returns true if the target edge type needs to be computed -static bool test_edge_type_conditions(struct edge_type_condition *conditions, +static bool test_edge_type_conditions(edge_type_condition *conditions, int num_edge_types, bool logical_and, int target, @@ -330,7 +330,7 @@ static void prepare(Render *re, ViewLayer *view_layer, Depsgraph *depsgraph) int use_ridges_and_valleys = 0; int use_suggestive_contours = 0; int use_material_boundaries = 0; - struct edge_type_condition conditions[] = { + edge_type_condition conditions[] = { {FREESTYLE_FE_SILHOUETTE, 0}, {FREESTYLE_FE_BORDER, 0}, {FREESTYLE_FE_CREASE, 0}, @@ -765,7 +765,7 @@ bool FRS_move_active_lineset(FreestyleConfig *config, int direction) // Testing -Material *FRS_create_stroke_material(Main *bmain, struct FreestyleLineStyle *linestyle) +Material *FRS_create_stroke_material(Main *bmain, FreestyleLineStyle *linestyle) { bNodeTree *nt = (linestyle->use_nodes) ? linestyle->nodetree : nullptr; Material *ma = BlenderStrokeRenderer::GetStrokeShader(bmain, nt, true); diff --git a/source/blender/freestyle/intern/scene_graph/SceneHash.cpp b/source/blender/freestyle/intern/scene_graph/SceneHash.cpp index 0ab83003514..1892387cc8e 100644 --- a/source/blender/freestyle/intern/scene_graph/SceneHash.cpp +++ b/source/blender/freestyle/intern/scene_graph/SceneHash.cpp @@ -21,12 +21,12 @@ string SceneHash::toString() void SceneHash::visitNodeViewLayer(NodeViewLayer &node) { - struct RenderData *r = &node.scene().r; + RenderData *r = &node.scene().r; adler32((uchar *)&r->xsch, sizeof(r->xsch)); // resolution_x adler32((uchar *)&r->ysch, sizeof(r->ysch)); // resolution_y adler32((uchar *)&r->size, sizeof(r->size)); // resolution_percentage - struct FreestyleConfig *config = &node.sceneLayer().freestyle_config; + FreestyleConfig *config = &node.sceneLayer().freestyle_config; adler32((uchar *)&config->flags, sizeof(config->flags)); adler32((uchar *)&config->crease_angle, sizeof(config->crease_angle)); adler32((uchar *)&config->sphere_radius, sizeof(config->sphere_radius)); -- 2.30.2 From fed9b2f266b1a8f4682de33331796d110d710dcc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 4 Jun 2023 19:07:26 +1000 Subject: [PATCH 43/63] Cleanup: function style casts, use nullptr, printf & size macros --- .../intern/grease_pencil_convert_legacy.cc | 8 ++++---- source/blender/blenkernel/intern/light_linking.cc | 2 +- source/blender/blenloader/intern/versioning_280.cc | 4 ++-- source/blender/blenloader/intern/versioning_300.cc | 2 +- .../blender/draw/engines/select/select_instance.cc | 14 +++++++------- source/blender/draw/intern/draw_cache.c | 8 ++++---- .../editors/space_view3d/view3d_navigate.cc | 4 ++-- source/blender/editors/transform/transform_snap.cc | 2 +- 8 files changed, 22 insertions(+), 22 deletions(-) diff --git a/source/blender/blenkernel/intern/grease_pencil_convert_legacy.cc b/source/blender/blenkernel/intern/grease_pencil_convert_legacy.cc index 27000cc4c31..d54f89b77d8 100644 --- a/source/blender/blenkernel/intern/grease_pencil_convert_legacy.cc +++ b/source/blender/blenkernel/intern/grease_pencil_convert_legacy.cc @@ -98,9 +98,9 @@ void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf, /* Write curve attributes. */ stroke_cyclic.span[stroke_i] = (gps->flag & GP_STROKE_CYCLIC) != 0; /* TODO: This should be a `double` attribute. */ - stroke_init_times.span[stroke_i] = static_cast(gps->inittime); - stroke_start_caps.span[stroke_i] = static_cast(gps->caps[0]); - stroke_end_caps.span[stroke_i] = static_cast(gps->caps[1]); + stroke_init_times.span[stroke_i] = float(gps->inittime); + stroke_start_caps.span[stroke_i] = int8_t(gps->caps[0]); + stroke_end_caps.span[stroke_i] = int8_t(gps->caps[1]); stroke_hardnesses.span[stroke_i] = gps->hardeness; stroke_point_aspect_ratios.span[stroke_i] = gps->aspect_ratio[0] / max_ff(gps->aspect_ratio[1], 1e-8); @@ -207,7 +207,7 @@ void legacy_gpencil_to_grease_pencil(Main &bmain, GreasePencil &grease_pencil, b (gpl->onion_flag & GP_LAYER_ONIONSKIN), GP_LAYER_TREE_NODE_USE_ONION_SKINNING); - new_layer.blend_mode = static_cast(gpl->blend_mode); + new_layer.blend_mode = int8_t(gpl->blend_mode); /* Convert the layer masks. */ LISTBASE_FOREACH (bGPDlayer_Mask *, mask, &gpl->mask_layers) { diff --git a/source/blender/blenkernel/intern/light_linking.cc b/source/blender/blenkernel/intern/light_linking.cc index 4603f9d7de7..03290370bd9 100644 --- a/source/blender/blenkernel/intern/light_linking.cc +++ b/source/blender/blenkernel/intern/light_linking.cc @@ -67,7 +67,7 @@ static std::string get_default_collection_name(const Object *object, } char name[MAX_ID_NAME]; - BLI_snprintf(name, sizeof(name), format, object->id.name + 2); + SNPRINTF(name, format, object->id.name + 2); return name; } diff --git a/source/blender/blenloader/intern/versioning_280.cc b/source/blender/blenloader/intern/versioning_280.cc index 285d117c7fa..51f4482d51e 100644 --- a/source/blender/blenloader/intern/versioning_280.cc +++ b/source/blender/blenloader/intern/versioning_280.cc @@ -4098,8 +4098,8 @@ void blo_do_versions_280(FileData *fd, Library * /*lib*/, Main *bmain) UnitSettings *unit = &scene->unit; if (unit->system == USER_UNIT_NONE) { - unit->length_unit = (char)USER_UNIT_ADAPTIVE; - unit->mass_unit = (char)USER_UNIT_ADAPTIVE; + unit->length_unit = char(USER_UNIT_ADAPTIVE); + unit->mass_unit = char(USER_UNIT_ADAPTIVE); } RenderData *render_data = &scene->r; diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 7aacc494e3d..4a27a6ddd75 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -4480,7 +4480,7 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) } FOREACH_NODETREE_END; - BKE_animdata_main_cb(bmain, version_liboverride_nla_frame_start_end, NULL); + BKE_animdata_main_cb(bmain, version_liboverride_nla_frame_start_end, nullptr); /* Store simulation bake directory in geometry nodes modifier. */ LISTBASE_FOREACH (Object *, ob, &bmain->objects) { diff --git a/source/blender/draw/engines/select/select_instance.cc b/source/blender/draw/engines/select/select_instance.cc index 94a74560e2e..e9e31d5ffe2 100644 --- a/source/blender/draw/engines/select/select_instance.cc +++ b/source/blender/draw/engines/select/select_instance.cc @@ -99,21 +99,21 @@ static void SELECT_next_instance_free(void *instance_) static const DrawEngineDataSize SELECT_next_data_size = DRW_VIEWPORT_DATA_SIZE(SELECT_NextData); DrawEngineType draw_engine_select_next_type = { - NULL, - NULL, + nullptr, + nullptr, N_("Select-Next"), &SELECT_next_data_size, &SELECT_next_engine_init, - NULL, + nullptr, &SELECT_next_instance_free, &SELECT_next_cache_init, &SELECT_next_cache_populate, &SELECT_next_cache_finish, &SELECT_next_draw_scene, - NULL, - NULL, - NULL, - NULL, + nullptr, + nullptr, + nullptr, + nullptr, }; /** \} */ diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 98707cc98e4..5080e8ce53b 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -2466,7 +2466,7 @@ static float x_axis_name[4][2] = { {-0.9f * S_X, 1.0f * S_Y}, {1.0f * S_X, -1.0f * S_Y}, }; -#define X_LEN (sizeof(x_axis_name) / sizeof(float[2])) +#define X_LEN (ARRAY_SIZE(x_axis_name)) #undef S_X #undef S_Y @@ -2480,7 +2480,7 @@ static float y_axis_name[6][2] = { {0.0f * S_X, -0.1f * S_Y}, {0.0f * S_X, -1.0f * S_Y}, }; -#define Y_LEN (sizeof(y_axis_name) / sizeof(float[2])) +#define Y_LEN (ARRAY_SIZE(y_axis_name)) #undef S_X #undef S_Y @@ -2498,7 +2498,7 @@ static float z_axis_name[10][2] = { {-1.00f * S_X, -1.00f * S_Y}, {1.00f * S_X, -1.00f * S_Y}, }; -#define Z_LEN (sizeof(z_axis_name) / sizeof(float[2])) +#define Z_LEN (ARRAY_SIZE(z_axis_name)) #undef S_X #undef S_Y @@ -2525,7 +2525,7 @@ static float axis_marker[8][2] = { {-S_X, 0.0f} #endif }; -#define MARKER_LEN (sizeof(axis_marker) / sizeof(float[2])) +#define MARKER_LEN (ARRAY_SIZE(axis_marker)) #define MARKER_FILL_LAYER 6 #undef S_X #undef S_Y diff --git a/source/blender/editors/space_view3d/view3d_navigate.cc b/source/blender/editors/space_view3d/view3d_navigate.cc index 11c0d1c7162..61e1d1f460f 100644 --- a/source/blender/editors/space_view3d/view3d_navigate.cc +++ b/source/blender/editors/space_view3d/view3d_navigate.cc @@ -1969,7 +1969,7 @@ static eV3D_OpMode view3d_navigation_type_from_idname(const char *idname) ViewOpsData *ED_view3d_navigation_init(bContext *C) { if (!CTX_wm_region_view3d(C)) { - return NULL; + return nullptr; } ViewOpsData *vod = MEM_cnew(__func__); @@ -2069,7 +2069,7 @@ bool ED_view3d_navigation_do(bContext *C, ViewOpsData *vod, const wmEvent *event /* Although #ED_view3d_update_viewmat is already called when redrawing the 3D View, do it here * as well, so the updated matrix values can be accessed by the operator. */ ED_view3d_update_viewmat( - vod->depsgraph, vod->scene, vod->v3d, vod->region, NULL, NULL, NULL, false); + vod->depsgraph, vod->scene, vod->v3d, vod->region, nullptr, nullptr, nullptr, false); return true; } diff --git a/source/blender/editors/transform/transform_snap.cc b/source/blender/editors/transform/transform_snap.cc index 1037f7f8936..d6727182f55 100644 --- a/source/blender/editors/transform/transform_snap.cc +++ b/source/blender/editors/transform/transform_snap.cc @@ -1160,7 +1160,7 @@ static void snap_multipoints_free(TransInfo *t) if (t->tsnap.status & SNAP_MULTI_POINTS) { BLI_freelistN(&t->tsnap.points); t->tsnap.status &= ~SNAP_MULTI_POINTS; - t->tsnap.selectedPoint = NULL; + t->tsnap.selectedPoint = nullptr; } } -- 2.30.2 From ff155d6f3d365614dc6405dca78e5368a1e7e64e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 4 Jun 2023 19:48:14 +1000 Subject: [PATCH 44/63] Cleanup: use 'num' suffix for sizes in DNA instead of 'size' Avoid ambiguity with the term size. --- .../blenkernel/intern/grease_pencil.cc | 96 +++++++++---------- .../intern/grease_pencil_convert_legacy.cc | 2 +- source/blender/blenkernel/intern/material.cc | 4 +- .../makesdna/DNA_grease_pencil_types.h | 8 +- .../blender/makesdna/intern/dna_rename_defs.h | 3 + 5 files changed, 58 insertions(+), 55 deletions(-) diff --git a/source/blender/blenkernel/intern/grease_pencil.cc b/source/blender/blenkernel/intern/grease_pencil.cc index 17b4cc592cd..d7b1c636fd7 100644 --- a/source/blender/blenkernel/intern/grease_pencil.cc +++ b/source/blender/blenkernel/intern/grease_pencil.cc @@ -68,10 +68,10 @@ static void grease_pencil_copy_data(Main * /*bmain*/, MEM_dupallocN(grease_pencil_src->material_array)); /* Duplicate drawing array. */ - grease_pencil_dst->drawing_array_size = grease_pencil_src->drawing_array_size; + grease_pencil_dst->drawing_array_num = grease_pencil_src->drawing_array_num; grease_pencil_dst->drawing_array = MEM_cnew_array( - grease_pencil_src->drawing_array_size, __func__); - for (int i = 0; i < grease_pencil_src->drawing_array_size; i++) { + grease_pencil_src->drawing_array_num, __func__); + for (int i = 0; i < grease_pencil_src->drawing_array_num; i++) { const GreasePencilDrawingBase *src_drawing_base = grease_pencil_src->drawing_array[i]; switch (src_drawing_base->type) { case GP_DRAWING: { @@ -134,10 +134,10 @@ static void grease_pencil_free_data(ID *id) static void grease_pencil_foreach_id(ID *id, LibraryForeachIDData *data) { GreasePencil *grease_pencil = reinterpret_cast(id); - for (int i = 0; i < grease_pencil->material_array_size; i++) { + for (int i = 0; i < grease_pencil->material_array_num; i++) { BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, grease_pencil->material_array[i], IDWALK_CB_USER); } - for (int i = 0; i < grease_pencil->drawing_array_size; i++) { + for (int i = 0; i < grease_pencil->drawing_array_num; i++) { GreasePencilDrawingBase *drawing_base = grease_pencil->drawing_array[i]; if (drawing_base->type == GP_DRAWING_REFERENCE) { GreasePencilDrawingReference *drawing_reference = @@ -167,7 +167,7 @@ static void grease_pencil_blend_write(BlendWriter *writer, ID *id, const void *i /* Write materials. */ BLO_write_pointer_array( - writer, grease_pencil->material_array_size, grease_pencil->material_array); + writer, grease_pencil->material_array_num, grease_pencil->material_array); } static void grease_pencil_blend_read_data(BlendDataReader *reader, ID *id) @@ -195,10 +195,10 @@ static void grease_pencil_blend_read_data(BlendDataReader *reader, ID *id) static void grease_pencil_blend_read_lib(BlendLibReader *reader, ID *id) { GreasePencil *grease_pencil = reinterpret_cast(id); - for (int i = 0; i < grease_pencil->material_array_size; i++) { + for (int i = 0; i < grease_pencil->material_array_num; i++) { BLO_read_id_address(reader, id, &grease_pencil->material_array[i]); } - for (int i = 0; i < grease_pencil->drawing_array_size; i++) { + for (int i = 0; i < grease_pencil->drawing_array_num; i++) { GreasePencilDrawingBase *drawing_base = grease_pencil->drawing_array[i]; if (drawing_base->type == GP_DRAWING_REFERENCE) { GreasePencilDrawingReference *drawing_reference = @@ -211,10 +211,10 @@ static void grease_pencil_blend_read_lib(BlendLibReader *reader, ID *id) static void grease_pencil_blend_read_expand(BlendExpander *expander, ID *id) { GreasePencil *grease_pencil = reinterpret_cast(id); - for (int i = 0; i < grease_pencil->material_array_size; i++) { + for (int i = 0; i < grease_pencil->material_array_num; i++) { BLO_expand(expander, grease_pencil->material_array[i]); } - for (int i = 0; i < grease_pencil->drawing_array_size; i++) { + for (int i = 0; i < grease_pencil->drawing_array_num; i++) { GreasePencilDrawingBase *drawing_base = grease_pencil->drawing_array[i]; if (drawing_base->type == GP_DRAWING_REFERENCE) { GreasePencilDrawingReference *drawing_reference = @@ -337,7 +337,7 @@ Layer::Layer() { this->base = TreeNode(GP_LAYER_TREE_LEAF); - this->frames_storage.size = 0; + this->frames_storage.num = 0; this->frames_storage.keys = nullptr; this->frames_storage.values = nullptr; this->frames_storage.flag = 0; @@ -931,49 +931,49 @@ blender::Span GreasePencilDrawing::stro /** \name Grease Pencil data-block API * \{ */ -template static void grow_array(T **array, int *size, const int add_size) +template static void grow_array(T **array, int *num, const int add_num) { - BLI_assert(add_size > 0); - const int new_array_size = *size + add_size; - T *new_array = reinterpret_cast(MEM_cnew_array(new_array_size, __func__)); + BLI_assert(add_num > 0); + const int new_array_num = *num + add_num; + T *new_array = reinterpret_cast(MEM_cnew_array(new_array_num, __func__)); - blender::uninitialized_relocate_n(*array, *size, new_array); + blender::uninitialized_relocate_n(*array, *num, new_array); *array = new_array; - *size = new_array_size; + *num = new_array_num; } -template static void shrink_array(T **array, int *size, const int shrink_size) +template static void shrink_array(T **array, int *num, const int shrink_num) { - BLI_assert(shrink_size > 0); - const int new_array_size = *size - shrink_size; - T *new_array = reinterpret_cast(MEM_cnew_array(new_array_size, __func__)); + BLI_assert(shrink_num > 0); + const int new_array_num = *num - shrink_num; + T *new_array = reinterpret_cast(MEM_cnew_array(new_array_num, __func__)); - blender::uninitialized_move_n(*array, new_array_size, new_array); + blender::uninitialized_move_n(*array, new_array_num, new_array); MEM_freeN(*array); *array = new_array; - *size = new_array_size; + *num = new_array_num; } blender::Span GreasePencil::drawings() const { - return blender::Span{this->drawing_array, this->drawing_array_size}; + return blender::Span{this->drawing_array, this->drawing_array_num}; } blender::MutableSpan GreasePencil::drawings_for_write() { return blender::MutableSpan{this->drawing_array, - this->drawing_array_size}; + this->drawing_array_num}; } -void GreasePencil::add_empty_drawings(const int add_size) +void GreasePencil::add_empty_drawings(const int add_num) { using namespace blender; - BLI_assert(add_size > 0); - const int prev_size = this->drawings().size(); - grow_array(&this->drawing_array, &this->drawing_array_size, add_size); + BLI_assert(add_num > 0); + const int prev_num = this->drawings().size(); + grow_array(&this->drawing_array, &this->drawing_array_num, add_num); MutableSpan new_drawings = this->drawings_for_write().drop_front( - prev_size); + prev_num); for (const int i : new_drawings.index_range()) { new_drawings[i] = reinterpret_cast( MEM_new(__func__)); @@ -997,11 +997,11 @@ void GreasePencil::remove_drawing(const int index_to_remove) * 2) Destroy A and shrink the array by one. * 3) Remove any frames in the layers that reference the A's index. */ - BLI_assert(this->drawing_array_size > 0); - BLI_assert(index_to_remove >= 0 && index_to_remove < this->drawing_array_size); + BLI_assert(this->drawing_array_num > 0); + BLI_assert(index_to_remove >= 0 && index_to_remove < this->drawing_array_num); /* Move the drawing that should be removed to the last index. */ - const int last_drawing_index = this->drawing_array_size - 1; + const int last_drawing_index = this->drawing_array_num - 1; if (index_to_remove != last_drawing_index) { for (Layer *layer : this->layers_for_write()) { blender::Map &frames = layer->frames_for_write(); @@ -1050,7 +1050,7 @@ void GreasePencil::remove_drawing(const int index_to_remove) } /* Shrink drawing array. */ - shrink_array(&this->drawing_array, &this->drawing_array_size, 1); + shrink_array(&this->drawing_array, &this->drawing_array_num, 1); } void GreasePencil::foreach_visible_drawing( @@ -1083,7 +1083,7 @@ bool GreasePencil::bounds_min_max(float3 &min, float3 &max) const bool found = false; /* FIXME: this should somehow go through the visible drawings. We don't have access to the * scene time here, so we probably need to cache the visible drawing for each layer somehow. */ - for (int i = 0; i < this->drawing_array_size; i++) { + for (int i = 0; i < this->drawing_array_num; i++) { GreasePencilDrawingBase *drawing_base = this->drawing_array[i]; switch (drawing_base->type) { case GP_DRAWING: { @@ -1153,7 +1153,7 @@ void GreasePencil::print_layer_tree() void GreasePencil::read_drawing_array(BlendDataReader *reader) { BLO_read_pointer_array(reader, reinterpret_cast(&this->drawing_array)); - for (int i = 0; i < this->drawing_array_size; i++) { + for (int i = 0; i < this->drawing_array_num; i++) { BLO_read_data_address(reader, &this->drawing_array[i]); GreasePencilDrawingBase *drawing_base = this->drawing_array[i]; switch (drawing_base->type) { @@ -1176,8 +1176,8 @@ void GreasePencil::read_drawing_array(BlendDataReader *reader) void GreasePencil::write_drawing_array(BlendWriter *writer) { - BLO_write_pointer_array(writer, this->drawing_array_size, this->drawing_array); - for (int i = 0; i < this->drawing_array_size; i++) { + BLO_write_pointer_array(writer, this->drawing_array_num, this->drawing_array); + for (int i = 0; i < this->drawing_array_num; i++) { GreasePencilDrawingBase *drawing_base = this->drawing_array[i]; switch (drawing_base->type) { case GP_DRAWING: { @@ -1198,10 +1198,10 @@ void GreasePencil::write_drawing_array(BlendWriter *writer) void GreasePencil::free_drawing_array() { - if (this->drawing_array == nullptr || this->drawing_array_size == 0) { + if (this->drawing_array == nullptr || this->drawing_array_num == 0) { return; } - for (int i = 0; i < this->drawing_array_size; i++) { + for (int i = 0; i < this->drawing_array_num; i++) { GreasePencilDrawingBase *drawing_base = this->drawing_array[i]; switch (drawing_base->type) { case GP_DRAWING: { @@ -1222,7 +1222,7 @@ void GreasePencil::free_drawing_array() } MEM_freeN(this->drawing_array); this->drawing_array = nullptr; - this->drawing_array_size = 0; + this->drawing_array_num = 0; } /** \} */ @@ -1239,12 +1239,12 @@ static void read_layer(BlendDataReader *reader, node->base.parent = parent; /* Read frames storage. */ - BLO_read_int32_array(reader, node->frames_storage.size, &node->frames_storage.keys); + BLO_read_int32_array(reader, node->frames_storage.num, &node->frames_storage.keys); BLO_read_data_address(reader, &node->frames_storage.values); /* Re-create frames data in runtime map. */ node->wrap().runtime = MEM_new(__func__); - for (int i = 0; i < node->frames_storage.size; i++) { + for (int i = 0; i < node->frames_storage.num; i++) { node->wrap().frames_for_write().add(node->frames_storage.keys[i], node->frames_storage.values[i]); } @@ -1300,9 +1300,9 @@ static void write_layer(BlendWriter *writer, GreasePencilLayer *node) MEM_SAFE_FREE(node->frames_storage.values); const Layer &layer = node->wrap(); - node->frames_storage.size = layer.frames().size(); - node->frames_storage.keys = MEM_cnew_array(node->frames_storage.size, __func__); - node->frames_storage.values = MEM_cnew_array(node->frames_storage.size, + node->frames_storage.num = layer.frames().size(); + node->frames_storage.keys = MEM_cnew_array(node->frames_storage.num, __func__); + node->frames_storage.values = MEM_cnew_array(node->frames_storage.num, __func__); const Span sorted_keys = layer.sorted_keys(); for (const int i : sorted_keys.index_range()) { @@ -1314,9 +1314,9 @@ static void write_layer(BlendWriter *writer, GreasePencilLayer *node) node->frames_storage.flag &= ~GP_LAYER_FRAMES_STORAGE_DIRTY; } - BLO_write_int32_array(writer, node->frames_storage.size, node->frames_storage.keys); + BLO_write_int32_array(writer, node->frames_storage.num, node->frames_storage.keys); BLO_write_struct_array( - writer, GreasePencilFrame, node->frames_storage.size, node->frames_storage.values); + writer, GreasePencilFrame, node->frames_storage.num, node->frames_storage.values); BLO_write_struct_list(writer, GreasePencilLayerMask, &node->masks); LISTBASE_FOREACH (GreasePencilLayerMask *, mask, &node->masks) { diff --git a/source/blender/blenkernel/intern/grease_pencil_convert_legacy.cc b/source/blender/blenkernel/intern/grease_pencil_convert_legacy.cc index d54f89b77d8..85311128e77 100644 --- a/source/blender/blenkernel/intern/grease_pencil_convert_legacy.cc +++ b/source/blender/blenkernel/intern/grease_pencil_convert_legacy.cc @@ -182,7 +182,7 @@ void legacy_gpencil_to_grease_pencil(Main &bmain, GreasePencil &grease_pencil, b num_drawings += BLI_listbase_count(&gpl->frames); } - grease_pencil.drawing_array_size = num_drawings; + grease_pencil.drawing_array_num = num_drawings; grease_pencil.drawing_array = reinterpret_cast( MEM_cnew_array(num_drawings, __func__)); diff --git a/source/blender/blenkernel/intern/material.cc b/source/blender/blenkernel/intern/material.cc index a5e8fdaece2..0b2ce067315 100644 --- a/source/blender/blenkernel/intern/material.cc +++ b/source/blender/blenkernel/intern/material.cc @@ -395,7 +395,7 @@ short *BKE_object_material_len_p(Object *ob) } if (ob->type == OB_GREASE_PENCIL) { GreasePencil *grease_pencil = static_cast(ob->data); - return &(grease_pencil->material_array_size); + return &(grease_pencil->material_array_num); } return nullptr; } @@ -449,7 +449,7 @@ short *BKE_id_material_len_p(ID *id) case ID_VO: return &(((Volume *)id)->totcol); case ID_GP: - return &(((GreasePencil *)id)->material_array_size); + return &(((GreasePencil *)id)->material_array_num); default: break; } diff --git a/source/blender/makesdna/DNA_grease_pencil_types.h b/source/blender/makesdna/DNA_grease_pencil_types.h index 494a63d9e29..7349e5de8f5 100644 --- a/source/blender/makesdna/DNA_grease_pencil_types.h +++ b/source/blender/makesdna/DNA_grease_pencil_types.h @@ -170,7 +170,7 @@ typedef struct GreasePencilLayerFramesMapStorage { /* Array of `frames` values (order matches the keys array). */ GreasePencilFrame *values; /* Size of the map (number of key-value pairs). */ - int size; + int num; /* Flag for the status of the storage. */ int flag; } GreasePencilLayerFramesMapStorage; @@ -394,7 +394,7 @@ typedef struct GreasePencil { * is done by the layers. See the `Layer` class in `BKE_grease_pencil.hh`. */ GreasePencilDrawingBase **drawing_array; - int drawing_array_size; + int drawing_array_num; char _pad[4]; /* Root group of the layer tree. */ @@ -410,7 +410,7 @@ typedef struct GreasePencil { * An array of materials. */ struct Material **material_array; - short material_array_size; + short material_array_num; char _pad2[2]; /** * Global flag on the data-block. @@ -449,7 +449,7 @@ typedef struct GreasePencil { const blender::bke::greasepencil::Layer *find_layer_by_name(blender::StringRefNull name) const; blender::bke::greasepencil::Layer *find_layer_by_name(blender::StringRefNull name); - void add_empty_drawings(int add_size); + void add_empty_drawings(int add_num); void remove_drawing(int index); void foreach_visible_drawing(int frame, diff --git a/source/blender/makesdna/intern/dna_rename_defs.h b/source/blender/makesdna/intern/dna_rename_defs.h index 742f3483e46..363f5b12889 100644 --- a/source/blender/makesdna/intern/dna_rename_defs.h +++ b/source/blender/makesdna/intern/dna_rename_defs.h @@ -80,6 +80,9 @@ DNA_STRUCT_RENAME_ELEM(FluidDomainSettings, guiding_parent, guide_parent) DNA_STRUCT_RENAME_ELEM(FluidDomainSettings, guiding_source, guide_source) DNA_STRUCT_RENAME_ELEM(FluidDomainSettings, guiding_vel_factor, guide_vel_factor) DNA_STRUCT_RENAME_ELEM(FluidEffectorSettings, guiding_mode, guide_mode) +DNA_STRUCT_RENAME_ELEM(GreasePencil, drawing_array_size, drawing_array_num) +DNA_STRUCT_RENAME_ELEM(GreasePencil, material_array_size, material_array_num) +DNA_STRUCT_RENAME_ELEM(GreasePencilLayerFramesMapStorage, size, num) DNA_STRUCT_RENAME_ELEM(HookModifierData, totindex, indexar_num) DNA_STRUCT_RENAME_ELEM(Image, name, filepath) DNA_STRUCT_RENAME_ELEM(LaplacianDeformModifierData, total_verts, verts_num) -- 2.30.2 From 8771f9290307043cfb1a92f0a2885c7489c91adc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 4 Jun 2023 19:51:29 +1000 Subject: [PATCH 45/63] Cleanup: rename ParticleSettings.child_nbr to child_percent The old name was only kept to avoid breaking compatibility. --- scripts/startup/bl_ui/properties_particle.py | 2 +- source/blender/makesrna/intern/rna_particle.c | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/scripts/startup/bl_ui/properties_particle.py b/scripts/startup/bl_ui/properties_particle.py index e1bcfc660b2..98763a5dd0b 100644 --- a/scripts/startup/bl_ui/properties_particle.py +++ b/scripts/startup/bl_ui/properties_particle.py @@ -1720,7 +1720,7 @@ class PARTICLE_PT_children(ParticleButtonsPanel, Panel): col = layout.column() sub = col.column(align=True) - sub.prop(part, "child_nbr", text="Display Amount") + sub.prop(part, "child_percent", text="Display Amount") sub.prop(part, "rendered_child_count", text="Render Amount") col.separator() diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 0393f54bf6f..b88cbc16826 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -3144,9 +3144,7 @@ static void rna_def_particle_settings(BlenderRNA *brna) /* children */ - /* NOTE(@ideasman42): name is not following conventions: `nbr`. - * Could be changed next major version. */ - prop = RNA_def_property(srna, "child_nbr", PROP_INT, PROP_NONE); + prop = RNA_def_property(srna, "child_percent", PROP_INT, PROP_NONE); RNA_def_property_int_sdna( prop, NULL, "child_percent"); /* Optional if prop names are the same. */ RNA_def_property_range(prop, 0, 100000); -- 2.30.2 From 83b17201e89743ac4da56d1630c5e2b0b45a3ebc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 4 Jun 2023 19:56:19 +1000 Subject: [PATCH 46/63] Cleanup: replace 'sz' abbreviation with 'size' --- source/blender/blenlib/tests/BLI_math_matrix_test.cc | 4 ++-- source/blender/gpu/tests/shaders/gpu_math_test.glsl | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/blenlib/tests/BLI_math_matrix_test.cc b/source/blender/blenlib/tests/BLI_math_matrix_test.cc index 3c69b4bb60b..cc7e7c00766 100644 --- a/source/blender/blenlib/tests/BLI_math_matrix_test.cc +++ b/source/blender/blenlib/tests/BLI_math_matrix_test.cc @@ -351,11 +351,11 @@ TEST(math_matrix, MatrixMethods) EXPECT_EQ(to_scale(m), expect_scale); - float4 expect_sz = {3, 2, 2, M_SQRT2}; + float4 expect_size = {3, 2, 2, M_SQRT2}; float4 size; float4x4 m1 = normalize_and_get_size(m, size); EXPECT_TRUE(is_unit_scale(m1)); - EXPECT_V4_NEAR(size, expect_sz, 0.0002f); + EXPECT_V4_NEAR(size, expect_size, 0.0002f); float4x4 m2 = normalize(m); EXPECT_TRUE(is_unit_scale(m2)); diff --git a/source/blender/gpu/tests/shaders/gpu_math_test.glsl b/source/blender/gpu/tests/shaders/gpu_math_test.glsl index a1c22e822a8..c21e3e9f5bf 100644 --- a/source/blender/gpu/tests/shaders/gpu_math_test.glsl +++ b/source/blender/gpu/tests/shaders/gpu_math_test.glsl @@ -166,11 +166,11 @@ void main() EXPECT_NEAR(as_vec4(to_quaternion(m)), as_vec4(expect_qt), 0.0002); EXPECT_NEAR(to_scale(m), expect_scale, 0.00001); - vec4 expect_sz = vec4(3, 2, 2, M_SQRT2); + vec4 expect_size = vec4(3, 2, 2, M_SQRT2); vec4 size; mat4x4 m1 = normalize_and_get_size(m, size); EXPECT_TRUE(is_unit_scale(m1)); - EXPECT_NEAR(size, expect_sz, 0.0002); + EXPECT_NEAR(size, expect_size, 0.0002); mat4x4 m2 = normalize(m); EXPECT_TRUE(is_unit_scale(m2)); -- 2.30.2 From db1b14a3a46bc79539eafcad11e81c4e86f5f0ca Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Mon, 5 Jun 2023 01:00:19 +0200 Subject: [PATCH 47/63] Fix refraction BSDF color when using OSL --- intern/cycles/kernel/osl/shaders/node_refraction_bsdf.osl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/cycles/kernel/osl/shaders/node_refraction_bsdf.osl b/intern/cycles/kernel/osl/shaders/node_refraction_bsdf.osl index a356356f5a0..bf795b75b37 100644 --- a/intern/cycles/kernel/osl/shaders/node_refraction_bsdf.osl +++ b/intern/cycles/kernel/osl/shaders/node_refraction_bsdf.osl @@ -14,5 +14,5 @@ shader node_refraction_bsdf(color Color = 0.8, float eta = backfacing() ? 1.0 / f : f; float roughness = Roughness * Roughness; - BSDF = microfacet(distribution, Normal, roughness, eta, 1); + BSDF = Color * microfacet(distribution, Normal, roughness, eta, 1); } -- 2.30.2 From eec118aa4de9e7f0bfed4a2cf969204e1e203d7b Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Mon, 5 Jun 2023 01:35:19 +0200 Subject: [PATCH 48/63] Fix Principled Hair Absorption Coefficient when using OSL The additional SocktType::VECTOR argument was being interpreted as flags, which caused the OSL compiler to skip the input (since the Vector type enum happens to align with the INTERNAL flag), which caused the OSL shader to always use the hardcoded default absorption regardless of what was entered. --- intern/cycles/scene/shader_nodes.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/intern/cycles/scene/shader_nodes.cpp b/intern/cycles/scene/shader_nodes.cpp index 4019a169b76..bdc4abae3ee 100644 --- a/intern/cycles/scene/shader_nodes.cpp +++ b/intern/cycles/scene/shader_nodes.cpp @@ -3529,8 +3529,7 @@ NODE_DEFINE(PrincipledHairBsdfNode) SOCKET_IN_COLOR(tint, "Tint", make_float3(1.f, 1.f, 1.f)); SOCKET_IN_VECTOR(absorption_coefficient, "Absorption Coefficient", - make_float3(0.245531f, 0.52f, 1.365f), - SocketType::VECTOR); + make_float3(0.245531f, 0.52f, 1.365f)); SOCKET_IN_FLOAT(offset, "Offset", 2.f * M_PI_F / 180.f); SOCKET_IN_FLOAT(roughness, "Roughness", 0.3f); -- 2.30.2 From d12684cb5475b4924dff418eacbe536d541fe596 Mon Sep 17 00:00:00 2001 From: Chris Blackbourn Date: Mon, 5 Jun 2023 12:14:20 +1200 Subject: [PATCH 49/63] Cleanup: format --- intern/cycles/scene/shader_nodes.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/intern/cycles/scene/shader_nodes.cpp b/intern/cycles/scene/shader_nodes.cpp index bdc4abae3ee..4064bb29207 100644 --- a/intern/cycles/scene/shader_nodes.cpp +++ b/intern/cycles/scene/shader_nodes.cpp @@ -3527,9 +3527,8 @@ NODE_DEFINE(PrincipledHairBsdfNode) SOCKET_IN_FLOAT(melanin, "Melanin", 0.8f); SOCKET_IN_FLOAT(melanin_redness, "Melanin Redness", 1.0f); SOCKET_IN_COLOR(tint, "Tint", make_float3(1.f, 1.f, 1.f)); - SOCKET_IN_VECTOR(absorption_coefficient, - "Absorption Coefficient", - make_float3(0.245531f, 0.52f, 1.365f)); + SOCKET_IN_VECTOR( + absorption_coefficient, "Absorption Coefficient", make_float3(0.245531f, 0.52f, 1.365f)); SOCKET_IN_FLOAT(offset, "Offset", 2.f * M_PI_F / 180.f); SOCKET_IN_FLOAT(roughness, "Roughness", 0.3f); -- 2.30.2 From d578ce1b6dbd04a5f6595319451e9eb707bbe7ee Mon Sep 17 00:00:00 2001 From: Chris Blackbourn Date: Wed, 31 May 2023 09:33:48 +1200 Subject: [PATCH 50/63] UV: Add optimal uv packings using precomputed layouts Produce optimal layouts for `n` squares, where n == 11, 18, 19 and 26. With thanks: * Walter Trump * Pertti Hamalainen * Robert Wainwright * Erich Friedman --- source/blender/geometry/intern/uv_pack.cc | 312 ++++++++++++++++++++++ 1 file changed, 312 insertions(+) diff --git a/source/blender/geometry/intern/uv_pack.cc b/source/blender/geometry/intern/uv_pack.cc index 8ca13dd1a0a..f754adb2c0c 100644 --- a/source/blender/geometry/intern/uv_pack.cc +++ b/source/blender/geometry/intern/uv_pack.cc @@ -642,6 +642,36 @@ static void pack_gobel(const Span> aabbs, } } } + +static bool pack_islands_optimal_pack_table(const int table_count, + const float max_extent, + const float *optimal, + const char * /* unused_comment */, + int64_t island_count, + const float large_uv, + const Span aabbs, + const UVPackIsland_Params ¶ms, + MutableSpan r_phis, + rctf *r_extent) +{ + if (table_count < island_count) { + return false; + } + rctf extent = {0.0f, large_uv * max_extent, 0.0f, large_uv * max_extent}; + if (is_larger(extent, *r_extent, params)) { + return false; + } + *r_extent = extent; + + for (int i = 0; i < island_count; i++) { + uv_phi &phi = r_phis[aabbs[i]->index]; + phi.translation.x = optimal[i * 3 + 0] * large_uv; + phi.translation.y = optimal[i * 3 + 1] * large_uv; + phi.rotation = optimal[i * 3 + 2]; + } + return true; +} + /* Attempt to find an "Optimal" packing of the islands, e.g. assuming squares or circles. */ static void pack_islands_optimal_pack(const Span> aabbs, const UVPackIsland_Params ¶ms, @@ -654,6 +684,9 @@ static void pack_islands_optimal_pack(const Span> if (params.target_aspect_y != 1.0f) { return; } + if (params.rotate_method != ED_UVPACK_ROTATION_ANY) { + return; + } float large_uv = 0.0f; for (const int64_t i : aabbs.index_range()) { @@ -662,6 +695,285 @@ static void pack_islands_optimal_pack(const Span> } int64_t island_count_patch = aabbs.size(); + + const float opt_11[] = { + /* Walter Trump, 1979. */ + 2.6238700165660708840676f, + 2.4365065643739085565755f, + 0.70130710554829878145f, + 1.9596047386700836678841f, + 1.6885655318806973568257f, + 0.70130710554829878145f, + 1.9364970731945949644626f, + 3.1724566890997589752033f, + 0.70130710554829878145f, + 1.2722458068219282267819f, + 2.4245322476118422727609f, + 0.70130710554829878145f, + 3.1724918301381124230431f, + 1.536261617698265524723f, + 0.70130710554829878145f, + 3.3770999999999999907629f, + 3.3770999999999999907629f, + 0.0f, + 0.5f, + 1.5f, + 0.0f, + 2.5325444557069398676674f, + 0.5f, + 0.0f, + 0.5f, + 3.3770999999999999907629f, + 0.0f, + 1.5f, + 0.5f, + 0.0f, + 0.5f, + 0.5f, + 0.0f, + }; + pack_islands_optimal_pack_table(11, + 3.8770999999999999907629f, + opt_11, + "Walter Trump, 1979", + island_count_patch, + large_uv, + aabbs, + params, + r_phis, + r_extent); + + const float opt_18[] = { + /* Pertti Hamalainen, 1979. */ + 2.4700161985907582717914f, + 2.4335783708246112588824f, + 0.42403103949074028022892f, + 1.3528594569415370862941f, + 2.3892972847076845432923f, + 0.42403103949074028022892f, + 2.0585783708246108147932f, + 1.5221405430584633577951f, + 0.42403103949074028022892f, + 1.7642972847076845432923f, + 3.3007351124738324443797f, + 0.42403103949074028022892f, + 3.3228756555322949139963f, + 1.5f, + 0.0f, + 3.3228756555322949139963f, + 3.3228756555322949139963f, + 0.0f, + 0.5f, + 1.5f, + 0.0f, + 2.3228756555322949139963f, + 4.3228756555322949139963f, + 0.0f, + 0.5f, + 3.3228756555322949139963f, + 0.0f, + 1.5f, + 0.5f, + 0.0f, + 3.3228756555322949139963f, + 0.5f, + 0.0f, + 3.3228756555322949139963f, + 4.3228756555322949139963f, + 0.0f, + 4.3228756555322949139963f, + 1.5f, + 0.0f, + 4.3228756555322949139963f, + 3.3228756555322949139963f, + 0.0f, + 0.5f, + 0.5f, + 0.0f, + 0.5f, + 4.3228756555322949139963f, + 0.0f, + 4.3228756555322949139963f, + 0.5f, + 0.0f, + 4.3228756555322949139963f, + 4.3228756555322949139963f, + 0.0f, + }; + pack_islands_optimal_pack_table(18, + 4.8228756555322949139963f, + opt_18, + "Pertti Hamalainen, 1979", + island_count_patch, + large_uv, + aabbs, + params, + r_phis, + r_extent); + + const float opt_19[] = { + /* Robert Wainwright, 1979. */ + 2.1785113019775792508881f, + 1.9428090415820631342569f, + 0.78539816339744827899949f, + 1.4714045207910317891731f, + 2.6499158227686105959719f, + 0.78539816339744827899949f, + 2.9428090415820640224354f, + 2.7071067811865479058042f, + 0.78539816339744827899949f, + 2.2357022603955165607204f, + 3.4142135623730953675192f, + 0.78539816339744827899949f, + 1.4428090415820635783462f, + 1.2642977396044836613243f, + 0.78539816339744827899949f, + 3.3856180831641271566923f, + 1.5f, + 0.0f, + 0.73570226039551600560884f, + 1.9714045207910311230393f, + 0.78539816339744827899949f, + 3.6213203435596432733234f, + 3.4428090415820635783462f, + 0.78539816339744827899949f, + 2.9142135623730958116084f, + 4.1499158227686105959719f, + 0.78539816339744827899949f, + 2.3856180831641271566923f, + 0.5f, + 0.0f, + 0.5f, + 3.3856180831641271566923f, + 0.0f, + 1.5f, + 4.3856180831641271566923f, + 0.0f, + 4.3856180831641271566923f, + 2.5f, + 0.0f, + 3.3856180831641271566923f, + 0.5f, + 0.0f, + 4.3856180831641271566923f, + 1.5f, + 0.0f, + 0.5f, + 0.5f, + 0.0f, + 0.5f, + 4.3856180831641271566923f, + 0.0f, + 4.3856180831641271566923f, + 0.5f, + 0.0f, + 4.3856180831641271566923f, + 4.3856180831641271566923f, + 0.0f, + }; + pack_islands_optimal_pack_table(19, + 4.8856180831641271566923f, + opt_19, + "Robert Wainwright, 1979", + island_count_patch, + large_uv, + aabbs, + params, + r_phis, + r_extent); + + const float opt_26[] = { + /* Erich Friedman, 1997. */ + 2.3106601717798209705279f, + 2.8106601717798214146171f, + 0.78539816339744827899949f, + 1.6035533905932735088129f, + 2.1035533905932739529021f, + 0.78539816339744827899949f, + 3.0177669529663684322429f, + 2.1035533905932739529021f, + 0.78539816339744827899949f, + 2.3106601717798209705279f, + 1.3964466094067264911871f, + 0.78539816339744827899949f, + 1.6035533905932735088129f, + 3.5177669529663688763321f, + 0.78539816339744827899949f, + 0.89644660940672593607559f, + 2.8106601717798214146171f, + 0.78539816339744827899949f, + 3.0177669529663684322429f, + 3.5177669529663688763321f, + 0.78539816339744827899949f, + 3.7248737341529158939579f, + 2.8106601717798214146171f, + 0.78539816339744827899949f, + 2.3106601717798209705279f, + 4.2248737341529167821363f, + 0.78539816339744827899949f, + 0.5f, + 1.5f, + 0.0f, + 1.5f, + 0.5f, + 0.0f, + 3.1213203435596419410558f, + 0.5f, + 0.0f, + 4.1213203435596419410558f, + 1.5f, + 0.0f, + 0.5f, + 4.1213203435596419410558f, + 0.0f, + 0.5f, + 0.5f, + 0.0f, + 4.1213203435596419410558f, + 4.1213203435596419410558f, + 0.0f, + 4.1213203435596419410558f, + 0.5f, + 0.0f, + 1.5f, + 5.1213203435596419410558f, + 0.0f, + 3.1213203435596419410558f, + 5.1213203435596419410558f, + 0.0f, + 5.1213203435596419410558f, + 2.5f, + 0.0f, + 5.1213203435596419410558f, + 1.5f, + 0.0f, + 0.5f, + 5.1213203435596419410558f, + 0.0f, + 4.1213203435596419410558f, + 5.1213203435596419410558f, + 0.0f, + 5.1213203435596419410558f, + 4.1213203435596419410558f, + 0.0f, + 5.1213203435596419410558f, + 0.5f, + 0.0f, + 5.1213203435596419410558f, + 5.1213203435596419410558f, + 0.0f, + }; + pack_islands_optimal_pack_table(26, + 5.6213203435596419410558f, + opt_26, + "Erich Friedman, 1997", + island_count_patch, + large_uv, + aabbs, + params, + r_phis, + r_extent); + if (island_count_patch == 37) { island_count_patch = 38; /* TODO, Cantrell 2002. */ } -- 2.30.2 From a44d153c6ad3436db0b2238639cbc8db507b3f19 Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Mon, 5 Jun 2023 02:20:57 +0200 Subject: [PATCH 51/63] Cycles: Remove MultiGGX code, replace with albedo scaling While the multiscattering GGX code is cool and solves the darkening problem at higher roughnesses, it's also currently buggy, hard to maintain and often impractical to use due to the higher noise and render time. In practice, though, having the exact correct directional distribution is not that important as long as the overall albedo is correct and we a) don't get the darkening effect and b) do get the saturation effect at higher roughnesses. This can simply be achieved by adding a second lobe (https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf) or scaling the single-scattering GGX lobe (https://blog.selfshadow.com/publications/turquin/ms_comp_final.pdf). Both approaches require the same precomputation and produce outputs of comparable quality, so I went for the simple albedo scaling since it's easier to implement and more efficient. Overall, the results are pretty good: All scenarios that I tested (Glossy BSDF, Glass BSDF, Principled BSDF with metallic or transmissive = 1) pass the white furnace test (a material with pure-white color in front of a pure-white background should be indistinguishable from the background if it preserves energy), and the overall albedo for non-white materials matches that produced by the real multi-scattering code (with the expected saturation increase as the roughness increases). In order to produce the precomputed tables, the PR also includes a utility that computes them. This is not built by default, since there's no reason for a user to run it (it only makes sense for documentation/reproducibility purposes and when making changes to the microfacet models). Pull Request: https://projects.blender.org/blender/blender/pulls/107958 --- CMakeLists.txt | 2 + intern/cycles/app/CMakeLists.txt | 19 + intern/cycles/app/cycles_precompute.cpp | 192 +++++ intern/cycles/kernel/CMakeLists.txt | 2 - intern/cycles/kernel/closure/bsdf.h | 51 +- .../cycles/kernel/closure/bsdf_microfacet.h | 237 ++++-- .../kernel/closure/bsdf_microfacet_multi.h | 759 ------------------ .../closure/bsdf_microfacet_multi_impl.h | 250 ------ intern/cycles/kernel/closure/bsdf_util.h | 9 +- intern/cycles/kernel/osl/closures_setup.h | 526 ++---------- intern/cycles/kernel/osl/closures_template.h | 116 +-- .../cycles/kernel/osl/shaders/node_fresnel.h | 6 + .../kernel/osl/shaders/node_glossy_bsdf.osl | 2 +- .../osl/shaders/node_principled_bsdf.osl | 65 +- intern/cycles/kernel/osl/shaders/stdcycles.h | 28 +- intern/cycles/kernel/svm/closure.h | 135 ++-- intern/cycles/kernel/svm/types.h | 4 +- intern/cycles/kernel/types.h | 8 +- intern/cycles/kernel/util/lookup_table.h | 17 + intern/cycles/scene/shader.cpp | 31 +- intern/cycles/scene/shader.h | 9 + intern/cycles/scene/shader.tables | 635 +++++++++++++++ intern/cycles/scene/shader_nodes.cpp | 9 +- source/blender/makesrna/intern/rna_nodetree.c | 8 +- 24 files changed, 1294 insertions(+), 1826 deletions(-) create mode 100644 intern/cycles/app/cycles_precompute.cpp delete mode 100644 intern/cycles/kernel/closure/bsdf_microfacet_multi.h delete mode 100644 intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h create mode 100644 intern/cycles/scene/shader.tables diff --git a/CMakeLists.txt b/CMakeLists.txt index 2121ac7c335..8d5aa6a44bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -496,6 +496,7 @@ option(WITH_CYCLES_DEBUG "Build Cycles with options useful for debug option(WITH_CYCLES_STANDALONE "Build Cycles standalone application" OFF) option(WITH_CYCLES_STANDALONE_GUI "Build Cycles standalone with GUI" OFF) +option(WITH_CYCLES_PRECOMPUTE "Build Cycles data precomputation tool" OFF) option(WITH_CYCLES_HYDRA_RENDER_DELEGATE "Build Cycles Hydra render delegate" OFF) @@ -507,6 +508,7 @@ mark_as_advanced(WITH_CYCLES_KERNEL_ASAN) mark_as_advanced(WITH_CYCLES_LOGGING) mark_as_advanced(WITH_CYCLES_DEBUG_NAN) mark_as_advanced(WITH_CYCLES_NATIVE_ONLY) +mark_as_advanced(WITH_CYCLES_PRECOMPUTE) # NVIDIA CUDA & OptiX if(NOT APPLE) diff --git a/intern/cycles/app/CMakeLists.txt b/intern/cycles/app/CMakeLists.txt index 89181b0eb7e..7a96e193496 100644 --- a/intern/cycles/app/CMakeLists.txt +++ b/intern/cycles/app/CMakeLists.txt @@ -119,3 +119,22 @@ if(WITH_CYCLES_STANDALONE) $ DESTINATION ${CMAKE_INSTALL_PREFIX}) endif() + +if(WITH_CYCLES_PRECOMPUTE) + set(SRC + cycles_precompute.cpp + ) + + add_executable(cycles_precompute ${SRC} ${INC} ${INC_SYS}) + unset(SRC) + + target_link_libraries(cycles_precompute PRIVATE ${LIB}) + + if(UNIX AND NOT APPLE) + set_target_properties(cycles_precompute PROPERTIES INSTALL_RPATH $ORIGIN/lib) + endif() + + install(PROGRAMS + $ + DESTINATION ${CMAKE_INSTALL_PREFIX}) +endif() diff --git a/intern/cycles/app/cycles_precompute.cpp b/intern/cycles/app/cycles_precompute.cpp new file mode 100644 index 00000000000..9bb41c71d09 --- /dev/null +++ b/intern/cycles/app/cycles_precompute.cpp @@ -0,0 +1,192 @@ +#include "util/math.h" +#include "util/string.h" +#include "util/system.h" + +#include "util/array.h" +#include "util/hash.h" +#include "util/task.h" + +#include "kernel/device/cpu/compat.h" +#include "kernel/device/cpu/globals.h" + +#include "kernel/sample/lcg.h" +#include "kernel/sample/mapping.h" + +#include "kernel/closure/bsdf_microfacet.h" + +#include + +CCL_NAMESPACE_BEGIN + +static float precompute_ggx_E(float rough, float mu, float3 rand) +{ + MicrofacetBsdf bsdf; + bsdf.weight = one_float3(); + bsdf.sample_weight = 1.0f; + bsdf.N = make_float3(0.0f, 0.0f, 1.0f); + bsdf.alpha_x = bsdf.alpha_y = sqr(rough); + bsdf.ior = 1.0f; + bsdf.T = make_float3(1.0f, 0.0f, 0.0f); + + bsdf_microfacet_ggx_setup(&bsdf); + + float3 omega_in; + Spectrum eval; + float pdf = 0.0f, sampled_eta; + float2 sampled_roughness; + bsdf_microfacet_ggx_sample((ShaderClosure *)&bsdf, + 0, + make_float3(0.0f, 0.0f, 1.0f), + make_float3(sqrtf(1.0f - sqr(mu)), 0.0f, mu), + rand, + &eval, + &omega_in, + &pdf, + &sampled_roughness, + &sampled_eta); + if (pdf != 0.0f) { + return average(eval) / pdf; + } + return 0.0f; +} + +static float precompute_ggx_glass_E(float rough, float mu, float eta, float3 rand) +{ + MicrofacetBsdf bsdf; + bsdf.weight = one_float3(); + bsdf.sample_weight = 1.0f; + bsdf.N = make_float3(0.0f, 0.0f, 1.0f); + bsdf.alpha_x = bsdf.alpha_y = sqr(rough); + bsdf.ior = eta; + bsdf.T = make_float3(1.0f, 0.0f, 0.0f); + + bsdf_microfacet_ggx_glass_setup(&bsdf); + + float3 omega_in; + Spectrum eval; + float pdf = 0.0f, sampled_eta; + float2 sampled_roughness; + bsdf_microfacet_ggx_sample((ShaderClosure *)&bsdf, + 0, + make_float3(0.0f, 0.0f, 1.0f), + make_float3(sqrtf(1.0f - sqr(mu)), 0.0f, mu), + rand, + &eval, + &omega_in, + &pdf, + &sampled_roughness, + &sampled_eta); + if (pdf != 0.0f) { + return average(eval) / pdf; + } + return 0.0f; +} + +struct PrecomputeTerm { + int samples; + int nx, ny, nz; + std::function evaluation; +}; + +static bool cycles_precompute(std::string name) +{ + std::map precompute_terms; + precompute_terms["ggx_E"] = { + 1 << 23, 32, 32, 1, [](float rough, float mu, float ior, float3 rand) { + return precompute_ggx_E(rough, mu, rand); + }}; + precompute_terms["ggx_Eavg"] = { + 1 << 26, 32, 1, 1, [](float rough, float mu, float ior, float3 rand) { + return 2.0f * mu * precompute_ggx_E(rough, mu, rand); + }}; + precompute_terms["ggx_glass_E"] = { + 1 << 23, 16, 16, 16, [](float rough, float mu, float ior, float3 rand) { + return precompute_ggx_glass_E(rough, mu, ior, rand); + }}; + precompute_terms["ggx_glass_Eavg"] = { + 1 << 26, 16, 1, 16, [](float rough, float mu, float ior, float3 rand) { + return 2.0f * mu * precompute_ggx_glass_E(rough, mu, ior, rand); + }}; + precompute_terms["ggx_glass_inv_E"] = { + 1 << 23, 16, 16, 16, [](float rough, float mu, float ior, float3 rand) { + return precompute_ggx_glass_E(rough, mu, 1.0f / ior, rand); + }}; + precompute_terms["ggx_glass_inv_Eavg"] = { + 1 << 26, 16, 1, 16, [](float rough, float mu, float ior, float3 rand) { + return 2.0f * mu * precompute_ggx_glass_E(rough, mu, 1.0f / ior, rand); + }}; + + if (precompute_terms.count(name) == 0) { + return false; + } + + const PrecomputeTerm &term = precompute_terms[name]; + + const int samples = term.samples; + const int nz = term.nz, ny = term.ny, nx = term.nx; + + std::cout << "static const float table_" << name << "[" << nz * ny * nx << "] = {" << std::endl; + for (int z = 0; z < nz; z++) { + array data(nx * ny); + parallel_for(0, nx * ny, [&](int64_t i) { + int y = i / nx, x = i % nx; + uint seed = hash_uint2(x, y); + double sum = 0.0; + for (int sample = 0; sample < samples; sample++) { + float4 rand = sobol_burley_sample_4D(sample, 0, seed, 0xffffffff); + + float rough = (nx == 1) ? 0.0f : clamp(float(x) / float(nx - 1), 1e-4f, 1.0f); + float mu = (ny == 1) ? rand.w : clamp(float(y) / float(ny - 1), 1e-4f, 1.0f); + float ior = (nz == 1) ? 0.0f : clamp(float(z) / float(nz - 1), 1e-4f, 0.99f); + /* This parametrization ensures that the entire [1..inf] range of IORs is covered + * and that most precision is allocated to the common areas (1-2). */ + ior = ior_from_F0(sqr(sqr(ior))); + + float value = term.evaluation(rough, mu, ior, float4_to_float3(rand)); + if (isnan(value)) { + value = 0.0f; + } + sum += (double)value; + } + data[y * nx + x] = saturatef(float(sum / double(samples))); + }); + + /* Print data formatted as C++ array */ + for (int y = 0; y < ny; y++) { + std::cout << " "; + for (int x = 0; x < nx; x++) { + std::cout << std::to_string(data[y * nx + x]); + if (x + 1 < nx) { + /* Next number will follow in same line */ + std::cout << "f, "; + } + else if (y + 1 < ny || z + 1 < nz) { + /* Next number will follow in next line */ + std::cout << "f,"; + } + else { + /* No next number */ + std::cout << "f"; + } + } + std::cout << std::endl; + } + /* If the array is three-dimensional, put an empty line between each slice. */ + if (ny > 1 && z + 1 < nz) { + std::cout << std::endl; + } + } + std::cout << "};" << std::endl; + + return true; +} + +CCL_NAMESPACE_END + +int main(int argc, const char **argv) +{ + if (argc < 2) { + return 1; + } + return ccl::cycles_precompute(argv[1]) ? 0 : 1; +} diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index d1c62598612..314d4c7cfab 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -123,8 +123,6 @@ set(SRC_KERNEL_CLOSURE_HEADERS closure/bsdf_diffuse.h closure/bsdf_diffuse_ramp.h closure/bsdf_microfacet.h - closure/bsdf_microfacet_multi.h - closure/bsdf_microfacet_multi_impl.h closure/bsdf_oren_nayar.h closure/bsdf_phong_ramp.h closure/bsdf_toon.h diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h index 5c4f44f38c3..9ffb149a0b8 100644 --- a/intern/cycles/kernel/closure/bsdf.h +++ b/intern/cycles/kernel/closure/bsdf.h @@ -10,7 +10,6 @@ #include "kernel/closure/bsdf_phong_ramp.h" #include "kernel/closure/bsdf_diffuse_ramp.h" #include "kernel/closure/bsdf_microfacet.h" -#include "kernel/closure/bsdf_microfacet_multi.h" #include "kernel/closure/bsdf_transparent.h" #include "kernel/closure/bsdf_ashikhmin_shirley.h" #include "kernel/closure/bsdf_toon.h" @@ -170,34 +169,6 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg, label = bsdf_microfacet_ggx_sample( sc, path_flag, Ng, sd->wi, rand, eval, wo, pdf, sampled_roughness, eta); break; - case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID: - label = bsdf_microfacet_multi_ggx_sample(kg, - sc, - Ng, - sd->wi, - rand.x, - rand.y, - eval, - wo, - pdf, - &sd->lcg_state, - sampled_roughness, - eta); - break; - case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: - label = bsdf_microfacet_multi_ggx_glass_sample(kg, - sc, - Ng, - sd->wi, - rand.x, - rand.y, - eval, - wo, - pdf, - &sd->lcg_state, - sampled_roughness, - eta); - break; case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: @@ -339,13 +310,6 @@ ccl_device_inline void bsdf_roughness_eta(const KernelGlobals kg, *eta = CLOSURE_IS_REFRACTIVE(bsdf->type) ? 1.0f / bsdf->ior : bsdf->ior; break; } - case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID: - case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: { - ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; - *roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y); - *eta = bsdf->ior; - break; - } case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; *roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y); @@ -433,13 +397,11 @@ ccl_device_inline int bsdf_label(const KernelGlobals kg, case CLOSURE_BSDF_SHARP_GLASS_ID: case CLOSURE_BSDF_MICROFACET_GGX_ID: case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID: - case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID: - case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: - case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: { + case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; label = ((bsdf_is_transmission(sc, wo)) ? LABEL_TRANSMIT : LABEL_REFLECT) | ((bsdf->alpha_x * bsdf->alpha_y <= 1e-7f) ? LABEL_SINGULAR : LABEL_GLOSSY); @@ -542,12 +504,6 @@ ccl_device_inline case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID: eval = bsdf_microfacet_ggx_eval(sc, sd->N, sd->wi, wo, pdf); break; - case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID: - eval = bsdf_microfacet_multi_ggx_eval(sc, sd->N, sd->wi, wo, pdf, &sd->lcg_state); - break; - case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: - eval = bsdf_microfacet_multi_ggx_glass_eval(sc, sd->wi, wo, pdf, &sd->lcg_state); - break; case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: @@ -613,14 +569,11 @@ ccl_device void bsdf_blur(KernelGlobals kg, ccl_private ShaderClosure *sc, float /* TODO: do we want to blur volume closures? */ #if defined(__SVM__) || defined(__OSL__) switch (sc->type) { - case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID: - case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: - bsdf_microfacet_multi_ggx_blur(sc, roughness); - break; case CLOSURE_BSDF_MICROFACET_GGX_ID: case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID: case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID: + /* TODO: Recompute energy preservation after blur? */ bsdf_microfacet_ggx_blur(sc, roughness); break; case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index bbf1d1c602e..e2b63d95bcb 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -28,19 +28,8 @@ enum MicrofacetFresnel { DIELECTRIC_TINT, /* used by the OSL MaterialX closures */ CONDUCTOR, GENERALIZED_SCHLICK, - CONSTANT, /* only needed by MultiGGX */ - PRINCIPLED_V1, }; -typedef struct FresnelPrincipledV1 { - Spectrum color; /* only needed by MultiGGX */ - Spectrum cspec0; -} FresnelPrincipledV1; - -typedef struct FresnelConstant { - Spectrum color; -} FresnelConstant; - typedef struct FresnelDielectricTint { Spectrum reflection_tint; Spectrum transmission_tint; @@ -53,7 +42,9 @@ typedef struct FresnelConductor { typedef struct FresnelGeneralizedSchlick { Spectrum reflection_tint; Spectrum transmission_tint; + /* Reflectivity at perpendicular (F0) and glancing (F90) angles. */ Spectrum f0, f90; + /* Negative exponent signals a special case where the real Fresnel is remapped to F0...F90. */ float exponent; } FresnelGeneralizedSchlick; @@ -61,8 +52,18 @@ typedef struct MicrofacetBsdf { SHADER_CLOSURE_BASE; float alpha_x, alpha_y, ior; + + /* Used to account for missing energy due to the single-scattering microfacet model. + * This could be included in bsdf->weight as well, but there it would mess up the color + * channels. + * Note that this is currently only used by GGX. */ + float energy_scale; + + /* Fresnel model to apply, as well as the extra data for it. + * For NONE and DIELECTRIC, no extra storage is needed, so the pointer is NULL for them. */ int fresnel_type; ccl_private void *fresnel; + float3 T; } MicrofacetBsdf; @@ -218,12 +219,7 @@ ccl_device_forceinline Spectrum microfacet_fresnel(ccl_private const MicrofacetB const float3 H, const bool refraction) { - if (bsdf->fresnel_type == MicrofacetFresnel::PRINCIPLED_V1) { - kernel_assert(!refraction); - ccl_private FresnelPrincipledV1 *fresnel = (ccl_private FresnelPrincipledV1 *)bsdf->fresnel; - return interpolate_fresnel_color(wi, H, bsdf->ior, fresnel->cspec0); - } - else if (bsdf->fresnel_type == MicrofacetFresnel::DIELECTRIC) { + if (bsdf->fresnel_type == MicrofacetFresnel::DIELECTRIC) { const float F = fresnel_dielectric_cos(dot(wi, H), bsdf->ior); return make_spectrum(refraction ? 1.0f - F : F); } @@ -241,18 +237,29 @@ ccl_device_forceinline Spectrum microfacet_fresnel(ccl_private const MicrofacetB else if (bsdf->fresnel_type == MicrofacetFresnel::GENERALIZED_SCHLICK) { ccl_private FresnelGeneralizedSchlick *fresnel = (ccl_private FresnelGeneralizedSchlick *) bsdf->fresnel; - float cosI = dot(wi, H); - if (bsdf->ior < 1.0f) { - /* When going from a higher to a lower IOR, we must use the transmitted angle. */ - float sinT2 = (1.0f - sqr(cosI)) / sqr(bsdf->ior); - if (sinT2 >= 1.0f) { - /* Total internal reflection */ - return refraction ? zero_spectrum() : fresnel->reflection_tint; - } - cosI = safe_sqrtf(1.0f - sinT2); + float s; + if (fresnel->exponent < 0.0f) { + /* Special case: Use real Fresnel curve to determine the interpolation between F0 and F90. + * Used by Principled v1. */ + const float F_real = fresnel_dielectric_cos(dot(wi, H), bsdf->ior); + const float F0_real = F0_from_ior(bsdf->ior); + s = inverse_lerp(F0_real, 1.0f, F_real); + } + else { + /* Regular case: Generalized Schlick term. */ + float cosI = dot(wi, H); + if (bsdf->ior < 1.0f) { + /* When going from a higher to a lower IOR, we must use the transmitted angle. */ + const float sinT2 = (1.0f - sqr(cosI)) / sqr(bsdf->ior); + if (sinT2 >= 1.0f) { + /* Total internal reflection */ + return refraction ? zero_spectrum() : fresnel->reflection_tint; + } + cosI = safe_sqrtf(1.0f - sinT2); + } + /* TODO(lukas): Is a special case for exponent==5 worth it? */ + s = powf(1.0f - cosI, fresnel->exponent); } - /* TODO(lukas): Is a special case for exponent==5 worth it? */ - const float s = powf(1.0f - cosI, fresnel->exponent); const Spectrum F = mix(fresnel->f0, fresnel->f90, s); if (refraction) { return (one_spectrum() - F) * fresnel->transmission_tint; @@ -261,23 +268,75 @@ ccl_device_forceinline Spectrum microfacet_fresnel(ccl_private const MicrofacetB return F * fresnel->reflection_tint; } } - else if (bsdf->fresnel_type == MicrofacetFresnel::CONSTANT) { - /* CONSTANT is only used my MultiGGX, which doesn't call this function. - * Therefore, this case only happens when determining the albedo of a MultiGGX closure. - * In that case, return 1.0 since the constant color is already baked into the weight. */ - return one_spectrum(); - } else { return one_spectrum(); } } +ccl_device_inline void microfacet_ggx_preserve_energy(KernelGlobals kg, + ccl_private MicrofacetBsdf *bsdf, + ccl_private const ShaderData *sd, + const Spectrum Fss) +{ + const float mu = dot(sd->wi, bsdf->N); + const float rough = sqrtf(sqrtf(bsdf->alpha_x * bsdf->alpha_y)); + + float E, E_avg; + if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_ID) { + E = lookup_table_read_2D(kg, rough, mu, kernel_data.tables.ggx_E, 32, 32); + E_avg = lookup_table_read(kg, rough, kernel_data.tables.ggx_Eavg, 32); + } + else if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID) { + int ofs = kernel_data.tables.ggx_glass_E; + int avg_ofs = kernel_data.tables.ggx_glass_Eavg; + float ior = bsdf->ior; + if (ior < 1.0f) { + ior = 1.0f / ior; + ofs = kernel_data.tables.ggx_glass_inv_E; + avg_ofs = kernel_data.tables.ggx_glass_inv_Eavg; + } + /* TODO: Bias mu towards more precision for low values. */ + float z = sqrtf(fabsf((ior - 1.0f) / (ior + 1.0f))); + E = lookup_table_read_3D(kg, rough, mu, z, ofs, 16, 16, 16); + E_avg = lookup_table_read_2D(kg, rough, z, avg_ofs, 16, 16); + } + else { + kernel_assert(false); + E = 1.0f; + E_avg = 1.0f; + } + + const float missing_factor = ((1.0f - E) / E); + bsdf->energy_scale = 1.0f + missing_factor; + + /* Check if we need to account for extra darkening/saturation due to multi-bounce Fresnel. */ + if (Fss != one_spectrum()) { + /* Fms here is based on the appendix of "Revisiting Physically Based Shading at Imageworks" + * by Christopher Kulla and Alejandro Conty, + * with one Fss cancelled out since this is just a multiplier on top of + * the single-scattering BSDF, which already contains one bounce of Fresnel. */ + const Spectrum Fms = Fss * E_avg / (one_spectrum() - Fss * (1.0f - E_avg)); + /* Since we already include the energy compensation in bsdf->energy_scale, + * this term is what's needed to make the full BSDF * weight * energy_scale + * computation work out to the correct value. */ + const Spectrum darkening = (one_spectrum() + Fms * missing_factor) / bsdf->energy_scale; + bsdf->weight *= darkening; + bsdf->sample_weight *= average(darkening); + } +} + /* This function estimates the albedo of the BSDF (NOT including the bsdf->weight) as caused by * the applied Fresnel model for the given view direction. - * The base microfacet model is assumed to have an albedo of 1, but e.g. a reflection-only - * closure with Fresnel applied can end up having a very low overall albedo. + * The base microfacet model is assumed to have an albedo of 1 (we have the energy preservation + * code for that), but e.g. a reflection-only closure with Fresnel applied can end up having + * a very low overall albedo. * This is used to adjust the sample weight, as well as for the Diff/Gloss/Trans Color pass - * and the Denoising Albedo pass. */ + * and the Denoising Albedo pass. + * + * NOTE: This code assumes the microfacet surface is fairly smooth. For very high roughness, + * the results are much more uniform across the surface. + * For better results, we'd be blending between this and Fss based on roughness, but that + * would involve storing or recomputing Fss, which is probably not worth it. */ ccl_device Spectrum bsdf_microfacet_estimate_fresnel(ccl_private const ShaderData *sd, ccl_private const MicrofacetBsdf *bsdf) { @@ -658,45 +717,105 @@ ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc, /* Fresnel term setup functions. These get called after the distribution-specific setup functions * like bsdf_microfacet_ggx_setup. */ -ccl_device void bsdf_microfacet_setup_fresnel_principledv1( - ccl_private MicrofacetBsdf *bsdf, - ccl_private const ShaderData *sd, - ccl_private FresnelPrincipledV1 *fresnel) -{ - fresnel->cspec0 = saturate(fresnel->cspec0); - - bsdf->fresnel_type = MicrofacetFresnel::PRINCIPLED_V1; - bsdf->fresnel = fresnel; - bsdf->sample_weight *= average(bsdf_microfacet_estimate_fresnel(sd, bsdf)); -} - -ccl_device void bsdf_microfacet_setup_fresnel_conductor(ccl_private MicrofacetBsdf *bsdf, +ccl_device void bsdf_microfacet_setup_fresnel_conductor(KernelGlobals kg, + ccl_private MicrofacetBsdf *bsdf, ccl_private const ShaderData *sd, - ccl_private FresnelConductor *fresnel) + ccl_private FresnelConductor *fresnel, + const bool preserve_energy) { bsdf->fresnel_type = MicrofacetFresnel::CONDUCTOR; bsdf->fresnel = fresnel; bsdf->sample_weight *= average(bsdf_microfacet_estimate_fresnel(sd, bsdf)); + + if (preserve_energy) { + /* In order to estimate Fss of the conductor, we fit the F82-tint model to it based on the + * value at 0° and ~82° and then use the analytic expression for its Fss. */ + Spectrum F0 = fresnel_conductor(1.0f, fresnel->n, fresnel->k); + Spectrum F82 = fresnel_conductor(1.0f / 7.0f, fresnel->n, fresnel->k); + /* 0.46266436f is (1 - 1/7)^5, 17.651384f is 1/(1/7 * (1 - 1/7)^6) */ + Spectrum B = (mix(F0, one_spectrum(), 0.46266436f) - F82) * 17.651384f; + Spectrum Fss = saturate(mix(F0, one_spectrum(), 1.0f / 21.0f) - B * (1.0f / 126.0f)); + microfacet_ggx_preserve_energy(kg, bsdf, sd, Fss); + } } ccl_device void bsdf_microfacet_setup_fresnel_dielectric_tint( + KernelGlobals kg, ccl_private MicrofacetBsdf *bsdf, ccl_private const ShaderData *sd, - ccl_private FresnelDielectricTint *fresnel) + ccl_private FresnelDielectricTint *fresnel, + const bool preserve_energy) { bsdf->fresnel_type = MicrofacetFresnel::DIELECTRIC_TINT; bsdf->fresnel = fresnel; bsdf->sample_weight *= average(bsdf_microfacet_estimate_fresnel(sd, bsdf)); + + if (preserve_energy) { + /* Assume that the transmissive tint makes up most of the overall color. */ + microfacet_ggx_preserve_energy(kg, bsdf, sd, fresnel->transmission_tint); + } } ccl_device void bsdf_microfacet_setup_fresnel_generalized_schlick( + KernelGlobals kg, ccl_private MicrofacetBsdf *bsdf, ccl_private const ShaderData *sd, - ccl_private FresnelGeneralizedSchlick *fresnel) + ccl_private FresnelGeneralizedSchlick *fresnel, + const bool preserve_energy) { bsdf->fresnel_type = MicrofacetFresnel::GENERALIZED_SCHLICK; bsdf->fresnel = fresnel; bsdf->sample_weight *= average(bsdf_microfacet_estimate_fresnel(sd, bsdf)); + + if (preserve_energy) { + Spectrum Fss = one_spectrum(); + /* Multi-bounce Fresnel is only supported for reflective lobes here. */ + if (is_zero(fresnel->transmission_tint)) { + float s; + if (fresnel->exponent < 0.0f) { + const float eta = bsdf->ior; + const float real_F0 = F0_from_ior(bsdf->ior); + + /* Numerical fit for the integral of 2*cosI * F(cosI, eta) over 0...1 with F being + * the real dielectric Fresnel. From "Revisiting Physically Based Shading at Imageworks" + * by Christopher Kulla and Alejandro Conty. */ + float real_Fss; + if (eta < 1.0f) { + real_Fss = 0.997118f + eta * (0.1014f - eta * (0.965241f + eta * 0.130607f)); + } + else { + real_Fss = (eta - 1.0f) / (4.08567f + 1.00071f * eta); + } + s = saturatef(inverse_lerp(real_F0, 1.0f, real_Fss)); + } + else { + /* Integral of 2*cosI * (1 - cosI)^exponent over 0...1*/ + s = 2.0f / ((fresnel->exponent + 3.0f) * fresnel->exponent + 2.0f); + } + /* Due to the linearity of the generalized model, this ends up working. */ + Fss = fresnel->reflection_tint * mix(fresnel->f0, fresnel->f90, s); + } + else { + /* For transmissive BSDFs, assume that the transmissive tint makes up most of the overall + * color. */ + Fss = fresnel->transmission_tint; + } + + microfacet_ggx_preserve_energy(kg, bsdf, sd, Fss); + } +} + +ccl_device void bsdf_microfacet_setup_fresnel_constant(KernelGlobals kg, + ccl_private MicrofacetBsdf *bsdf, + ccl_private const ShaderData *sd, + const Spectrum color) +{ + /* Constant Fresnel is a special case - the color is already baked into the closure's + * weight, so we just need to perform the energy preservation. */ + kernel_assert(bsdf->fresnel_type == MicrofacetFresnel::NONE || + bsdf->fresnel_type == MicrofacetFresnel::DIELECTRIC); + + microfacet_ggx_preserve_energy(kg, bsdf, sd, color); } /* GGX microfacet with Smith shadow-masking from: @@ -718,6 +837,7 @@ ccl_device int bsdf_microfacet_ggx_setup(ccl_private MicrofacetBsdf *bsdf) bsdf->alpha_y = saturatef(bsdf->alpha_y); bsdf->fresnel_type = MicrofacetFresnel::NONE; + bsdf->energy_scale = 1.0f; bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_ID; return SD_BSDF | SD_BSDF_HAS_EVAL; @@ -730,6 +850,7 @@ ccl_device int bsdf_microfacet_ggx_clearcoat_setup(ccl_private MicrofacetBsdf *b bsdf->alpha_y = bsdf->alpha_x; bsdf->fresnel_type = MicrofacetFresnel::DIELECTRIC; + bsdf->energy_scale = 1.0f; bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID; bsdf->sample_weight *= average(bsdf_microfacet_estimate_fresnel(sd, bsdf)); @@ -742,6 +863,7 @@ ccl_device int bsdf_microfacet_ggx_refraction_setup(ccl_private MicrofacetBsdf * bsdf->alpha_y = bsdf->alpha_x; bsdf->fresnel_type = MicrofacetFresnel::NONE; + bsdf->energy_scale = 1.0f; bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_HAS_TRANSMISSION; @@ -753,6 +875,7 @@ ccl_device int bsdf_microfacet_ggx_glass_setup(ccl_private MicrofacetBsdf *bsdf) bsdf->alpha_y = bsdf->alpha_x; bsdf->fresnel_type = MicrofacetFresnel::DIELECTRIC; + bsdf->energy_scale = 1.0f; bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID; return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_HAS_TRANSMISSION; @@ -772,7 +895,8 @@ ccl_device Spectrum bsdf_microfacet_ggx_eval(ccl_private const ShaderClosure *sc const float3 wo, ccl_private float *pdf) { - return bsdf_microfacet_eval(sc, Ng, wi, wo, pdf); + ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; + return bsdf->energy_scale * bsdf_microfacet_eval(sc, Ng, wi, wo, pdf); } ccl_device int bsdf_microfacet_ggx_sample(ccl_private const ShaderClosure *sc, @@ -786,8 +910,11 @@ ccl_device int bsdf_microfacet_ggx_sample(ccl_private const ShaderClosure *sc, ccl_private float2 *sampled_roughness, ccl_private float *eta) { - return bsdf_microfacet_sample( + + int label = bsdf_microfacet_sample( sc, path_flag, Ng, wi, rand, eval, wo, pdf, sampled_roughness, eta); + *eval *= ((ccl_private const MicrofacetBsdf *)sc)->energy_scale; + return label; } /* Beckmann microfacet with Smith shadow-masking from: diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h deleted file mode 100644 index 6da5acbfbf3..00000000000 --- a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h +++ /dev/null @@ -1,759 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 - * Copyright 2011-2022 Blender Foundation */ - -#pragma once - -#include "kernel/sample/lcg.h" -#include "kernel/sample/mapping.h" - -CCL_NAMESPACE_BEGIN - -/* Most of the code is based on the supplemental implementations from - * https://eheitzresearch.wordpress.com/240-2/. */ - -/* === GGX Microfacet distribution functions === */ - -/* Isotropic GGX microfacet distribution */ -ccl_device_forceinline float D_ggx(float3 wm, float alpha) -{ - wm.z *= wm.z; - alpha *= alpha; - float tmp = (1.0f - wm.z) + alpha * wm.z; - return alpha / max(M_PI_F * tmp * tmp, 1e-7f); -} - -/* Anisotropic GGX microfacet distribution */ -ccl_device_forceinline float D_ggx_aniso(const float3 wm, const float2 alpha) -{ - float slope_x = -wm.x / alpha.x; - float slope_y = -wm.y / alpha.y; - float tmp = wm.z * wm.z + slope_x * slope_x + slope_y * slope_y; - - return 1.0f / max(M_PI_F * tmp * tmp * alpha.x * alpha.y, 1e-7f); -} - -/* Sample slope distribution (based on page 14 of the supplemental implementation). */ -ccl_device_forceinline float2 mf_sampleP22_11(const float cosI, - const float randx, - const float randy) -{ - if (cosI > 0.9999f || fabsf(cosI) < 1e-6f) { - const float r = sqrtf(randx / max(1.0f - randx, 1e-7f)); - const float phi = M_2PI_F * randy; - return make_float2(r * cosf(phi), r * sinf(phi)); - } - - const float sinI = sin_from_cos(cosI); - const float tanI = sinI / cosI; - const float projA = 0.5f * (cosI + 1.0f); - if (projA < 0.0001f) - return make_float2(0.0f, 0.0f); - const float A = 2.0f * randx * projA / cosI - 1.0f; - float tmp = A * A - 1.0f; - if (fabsf(tmp) < 1e-7f) - return make_float2(0.0f, 0.0f); - tmp = 1.0f / tmp; - const float D = safe_sqrtf(tanI * tanI * tmp * tmp - (A * A - tanI * tanI) * tmp); - - const float slopeX2 = tanI * tmp + D; - const float slopeX = (A < 0.0f || slopeX2 > 1.0f / tanI) ? (tanI * tmp - D) : slopeX2; - - float U2; - if (randy >= 0.5f) - U2 = 2.0f * (randy - 0.5f); - else - U2 = 2.0f * (0.5f - randy); - const float z = (U2 * (U2 * (U2 * 0.27385f - 0.73369f) + 0.46341f)) / - (U2 * (U2 * (U2 * 0.093073f + 0.309420f) - 1.0f) + 0.597999f); - const float slopeY = z * sqrtf(1.0f + slopeX * slopeX); - - if (randy >= 0.5f) - return make_float2(slopeX, slopeY); - else - return make_float2(slopeX, -slopeY); -} - -/* Visible normal sampling for the GGX distribution - * (based on page 7 of the supplemental implementation). */ -ccl_device_forceinline float3 mf_sample_vndf(const float3 wi, - const float2 alpha, - const float randx, - const float randy) -{ - const float3 wi_11 = normalize(make_float3(alpha.x * wi.x, alpha.y * wi.y, wi.z)); - const float2 slope_11 = mf_sampleP22_11(wi_11.z, randx, randy); - - const float3 cossin_phi = safe_normalize(make_float3(wi_11.x, wi_11.y, 0.0f)); - const float slope_x = alpha.x * (cossin_phi.x * slope_11.x - cossin_phi.y * slope_11.y); - const float slope_y = alpha.y * (cossin_phi.y * slope_11.x + cossin_phi.x * slope_11.y); - - kernel_assert(isfinite(slope_x)); - return normalize(make_float3(-slope_x, -slope_y, 1.0f)); -} - -/* === Phase functions: Glossy and Glass === */ - -/* Phase function for reflective materials. */ -ccl_device_forceinline float3 mf_sample_phase_glossy(const float3 wi, - ccl_private Spectrum *weight, - const float3 wm) -{ - return -wi + 2.0f * wm * dot(wi, wm); -} - -ccl_device_forceinline Spectrum mf_eval_phase_glossy(const float3 w, - const float lambda, - const float3 wo, - const float2 alpha) -{ - if (w.z > 0.9999f) - return zero_spectrum(); - - const float3 wh = normalize(wo - w); - if (wh.z < 0.0f) - return zero_spectrum(); - - float pArea = (w.z < -0.9999f) ? 1.0f : lambda * w.z; - - const float dotW_WH = dot(-w, wh); - if (dotW_WH < 0.0f) - return zero_spectrum(); - - float phase = max(0.0f, dotW_WH) * 0.25f / max(pArea * dotW_WH, 1e-7f); - if (alpha.x == alpha.y) - phase *= D_ggx(wh, alpha.x); - else - phase *= D_ggx_aniso(wh, alpha); - - return make_spectrum(phase); -} - -/* Phase function for dielectric transmissive materials, including both reflection and refraction - * according to the dielectric fresnel term. */ -ccl_device_forceinline float3 mf_sample_phase_glass(const float3 wi, - const float eta, - const float3 wm, - const float randV, - ccl_private bool *outside) -{ - float cosI = dot(wi, wm); - float f = fresnel_dielectric_cos(cosI, eta); - if (randV < f) { - *outside = true; - return -wi + 2.0f * wm * cosI; - } - *outside = false; - float inv_eta = 1.0f / eta; - float cosT = -safe_sqrtf(1.0f - (1.0f - cosI * cosI) * inv_eta * inv_eta); - return normalize(wm * (cosI * inv_eta + cosT) - wi * inv_eta); -} - -ccl_device_forceinline Spectrum mf_eval_phase_glass(const float3 w, - const float lambda, - const float3 wo, - const bool wo_outside, - const float2 alpha, - const float eta) -{ - if (w.z > 0.9999f) - return zero_spectrum(); - - float pArea = (w.z < -0.9999f) ? 1.0f : lambda * w.z; - float v; - if (wo_outside) { - const float3 wh = normalize(wo - w); - if (wh.z < 0.0f) - return zero_spectrum(); - - const float dotW_WH = dot(-w, wh); - v = fresnel_dielectric_cos(dotW_WH, eta) * max(0.0f, dotW_WH) * D_ggx(wh, alpha.x) * 0.25f / - (pArea * dotW_WH); - } - else { - float3 wh = normalize(wo * eta - w); - if (wh.z < 0.0f) - wh = -wh; - const float dotW_WH = dot(-w, wh), dotWO_WH = dot(wo, wh); - if (dotW_WH < 0.0f) - return zero_spectrum(); - - float temp = dotW_WH + eta * dotWO_WH; - v = (1.0f - fresnel_dielectric_cos(dotW_WH, eta)) * max(0.0f, dotW_WH) * max(0.0f, -dotWO_WH) * - D_ggx(wh, alpha.x) / (pArea * temp * temp); - } - - return make_spectrum(v); -} - -/* === Utility functions for the random walks === */ - -/* Smith Lambda function for GGX (based on page 12 of the supplemental implementation). */ -ccl_device_forceinline float mf_lambda(const float3 w, const float2 alpha) -{ - if (w.z > 0.9999f) - return 0.0f; - else if (w.z < -0.9999f) - return -0.9999f; - - const float inv_wz2 = 1.0f / max(w.z * w.z, 1e-7f); - const float2 wa = make_float2(w.x, w.y) * alpha; - float v = sqrtf(1.0f + dot(wa, wa) * inv_wz2); - if (w.z <= 0.0f) - v = -v; - - return 0.5f * (v - 1.0f); -} - -/* Height distribution CDF (based on page 4 of the supplemental implementation). */ -ccl_device_forceinline float mf_invC1(const float h) -{ - return 2.0f * saturatef(h) - 1.0f; -} - -ccl_device_forceinline float mf_C1(const float h) -{ - return saturatef(0.5f * (h + 1.0f)); -} - -/* Masking function (based on page 16 of the supplemental implementation). */ -ccl_device_forceinline float mf_G1(const float3 w, const float C1, const float lambda) -{ - if (w.z > 0.9999f) - return 1.0f; - if (w.z < 1e-5f) - return 0.0f; - return powf(C1, lambda); -} - -/* Sampling from the visible height distribution (based on page 17 of the supplemental - * implementation). */ -ccl_device_forceinline bool mf_sample_height(const float3 w, - ccl_private float *h, - ccl_private float *C1, - ccl_private float *G1, - ccl_private float *lambda, - const float U) -{ - if (w.z > 0.9999f) - return false; - if (w.z < -0.9999f) { - *C1 *= U; - *h = mf_invC1(*C1); - *G1 = mf_G1(w, *C1, *lambda); - } - else if (fabsf(w.z) >= 0.0001f) { - if (U > 1.0f - *G1) - return false; - if (*lambda >= 0.0f) { - *C1 = 1.0f; - } - else { - *C1 *= powf(1.0f - U, -1.0f / *lambda); - } - *h = mf_invC1(*C1); - *G1 = mf_G1(w, *C1, *lambda); - } - return true; -} - -/* === PDF approximations for the different phase functions. === - * As explained in bsdf_microfacet_multi_impl.h, using approximations with MIS still produces an - * unbiased result. */ - -/* Approximation for the albedo of the single-scattering GGX distribution, - * the missing energy is then approximated as a diffuse reflection for the PDF. */ -ccl_device_forceinline float mf_ggx_albedo(float r) -{ - float albedo = 0.806495f * expf(-1.98712f * r * r) + 0.199531f; - albedo -= ((((((1.76741f * r - 8.43891f) * r + 15.784f) * r - 14.398f) * r + 6.45221f) * r - - 1.19722f) * - r + - 0.027803f) * - r + - 0.00568739f; - return saturatef(albedo); -} - -ccl_device_inline float mf_ggx_transmission_albedo(float a, float ior) -{ - if (ior < 1.0f) { - ior = 1.0f / ior; - } - a = saturatef(a); - ior = clamp(ior, 1.0f, 3.0f); - float I_1 = 0.0476898f * expf(-0.978352f * (ior - 0.65657f) * (ior - 0.65657f)) - - 0.033756f * ior + 0.993261f; - float R_1 = (((0.116991f * a - 0.270369f) * a + 0.0501366f) * a - 0.00411511f) * a + 1.00008f; - float I_2 = (((-2.08704f * ior + 26.3298f) * ior - 127.906f) * ior + 292.958f) * ior - 287.946f + - 199.803f / (ior * ior) - 101.668f / (ior * ior * ior); - float R_2 = ((((5.3725f * a - 24.9307f) * a + 22.7437f) * a - 3.40751f) * a + 0.0986325f) * a + - 0.00493504f; - - return saturatef(1.0f + I_2 * R_2 * 0.0019127f - (1.0f - I_1) * (1.0f - R_1) * 9.3205f); -} - -ccl_device_forceinline float mf_ggx_pdf(const float3 wi, const float3 wo, const float alpha) -{ - float D = D_ggx(normalize(wi + wo), alpha); - float lambda = mf_lambda(wi, make_float2(alpha, alpha)); - float singlescatter = 0.25f * D / max((1.0f + lambda) * wi.z, 1e-7f); - - float multiscatter = wo.z * M_1_PI_F; - - float albedo = mf_ggx_albedo(alpha); - return albedo * singlescatter + (1.0f - albedo) * multiscatter; -} - -ccl_device_forceinline float mf_ggx_aniso_pdf(const float3 wi, const float3 wo, const float2 alpha) -{ - float D = D_ggx_aniso(normalize(wi + wo), alpha); - float lambda = mf_lambda(wi, alpha); - float singlescatter = 0.25f * D / max((1.0f + lambda) * wi.z, 1e-7f); - - float multiscatter = wo.z * M_1_PI_F; - - float albedo = mf_ggx_albedo(sqrtf(alpha.x * alpha.y)); - return albedo * singlescatter + (1.0f - albedo) * multiscatter; -} - -ccl_device_forceinline float mf_glass_pdf(const float3 wi, - const float3 wo, - const float alpha, - const float eta) -{ - bool reflective = (wi.z * wo.z > 0.0f); - - float wh_len; - float3 wh = normalize_len(wi + (reflective ? wo : (wo * eta)), &wh_len); - if (wh.z < 0.0f) - wh = -wh; - float3 r_wi = (wi.z < 0.0f) ? -wi : wi; - float lambda = mf_lambda(r_wi, make_float2(alpha, alpha)); - float D = D_ggx(wh, alpha); - float fresnel = fresnel_dielectric_cos(dot(r_wi, wh), eta); - - float multiscatter = fabsf(wo.z * M_1_PI_F); - if (reflective) { - float singlescatter = 0.25f * D / max((1.0f + lambda) * r_wi.z, 1e-7f); - float albedo = mf_ggx_albedo(alpha); - return fresnel * (albedo * singlescatter + (1.0f - albedo) * multiscatter); - } - else { - float singlescatter = fabsf(dot(r_wi, wh) * dot(wo, wh) * D * eta * eta / - max((1.0f + lambda) * r_wi.z * wh_len * wh_len, 1e-7f)); - float albedo = mf_ggx_transmission_albedo(alpha, eta); - return (1.0f - fresnel) * (albedo * singlescatter + (1.0f - albedo) * multiscatter); - } -} - -/* === Actual random walk implementations === */ -/* One version of mf_eval and mf_sample per phase function. */ - -#define MF_NAME_JOIN(x, y) x##_##y -#define MF_NAME_EVAL(x, y) MF_NAME_JOIN(x, y) -#define MF_FUNCTION_FULL_NAME(prefix) MF_NAME_EVAL(prefix, MF_PHASE_FUNCTION) - -#define MF_PHASE_FUNCTION glass -#define MF_MULTI_GLASS -#include "kernel/closure/bsdf_microfacet_multi_impl.h" - -#define MF_PHASE_FUNCTION glossy -#define MF_MULTI_GLOSSY -#include "kernel/closure/bsdf_microfacet_multi_impl.h" - -ccl_device void bsdf_microfacet_multi_ggx_blur(ccl_private ShaderClosure *sc, float roughness) -{ - ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)sc; - - bsdf->alpha_x = fmaxf(roughness, bsdf->alpha_x); - bsdf->alpha_y = fmaxf(roughness, bsdf->alpha_y); -} - -/* === Closure implementations === */ - -/* Multi-scattering GGX Glossy closure */ - -ccl_device int bsdf_microfacet_multi_ggx_common_setup(ccl_private MicrofacetBsdf *bsdf) -{ - bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f); - bsdf->alpha_y = clamp(bsdf->alpha_y, 1e-4f, 1.0f); - - return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG; -} - -ccl_device int bsdf_microfacet_multi_ggx_setup(ccl_private MicrofacetBsdf *bsdf) -{ - if (is_zero(bsdf->T)) - bsdf->T = make_float3(1.0f, 0.0f, 0.0f); - - ccl_private FresnelConstant *fresnel = (ccl_private FresnelConstant *)bsdf->fresnel; - fresnel->color = saturate(fresnel->color); - - bsdf->fresnel_type = MicrofacetFresnel::CONSTANT; - bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID; - - return bsdf_microfacet_multi_ggx_common_setup(bsdf); -} - -ccl_device int bsdf_microfacet_multi_ggx_fresnel_setup(ccl_private MicrofacetBsdf *bsdf, - ccl_private const ShaderData *sd) -{ - if (is_zero(bsdf->T)) - bsdf->T = make_float3(1.0f, 0.0f, 0.0f); - - ccl_private FresnelPrincipledV1 *fresnel = (ccl_private FresnelPrincipledV1 *)bsdf->fresnel; - fresnel->color = saturate(fresnel->color); - fresnel->cspec0 = saturate(fresnel->cspec0); - - bsdf->fresnel_type = MicrofacetFresnel::PRINCIPLED_V1; - bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID; - bsdf->sample_weight *= average(bsdf_microfacet_estimate_fresnel(sd, bsdf)); - - return bsdf_microfacet_multi_ggx_common_setup(bsdf); -} - -ccl_device int bsdf_microfacet_multi_ggx_refraction_setup(ccl_private MicrofacetBsdf *bsdf) -{ - bsdf->alpha_y = bsdf->alpha_x; - - ccl_private FresnelConstant *fresnel = (ccl_private FresnelConstant *)bsdf->fresnel; - fresnel->color = saturate(fresnel->color); - - bsdf->fresnel_type = MicrofacetFresnel::CONSTANT; - bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID; - - return bsdf_microfacet_multi_ggx_common_setup(bsdf); -} - -ccl_device Spectrum bsdf_microfacet_multi_ggx_eval(ccl_private const ShaderClosure *sc, - const float3 Ng, - const float3 wi, - const float3 wo, - ccl_private float *pdf, - ccl_private uint *lcg_state) -{ - ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; - const float cosNgO = dot(Ng, wo); - - if ((cosNgO < 0.0f) || bsdf->alpha_x * bsdf->alpha_y < 1e-7f) { - *pdf = 0.0f; - return zero_spectrum(); - } - - float3 X, Y, Z; - Z = bsdf->N; - - /* Ensure that the both directions are on the outside w.r.t. the shading normal. */ - if (dot(Z, wi) <= 0.0f || dot(Z, wo) <= 0.0f) { - *pdf = 0.0f; - return zero_spectrum(); - } - - Spectrum color, cspec0; - bool use_fresnel; - if (bsdf->fresnel_type == MicrofacetFresnel::PRINCIPLED_V1) { - ccl_private FresnelPrincipledV1 *fresnel = (ccl_private FresnelPrincipledV1 *)bsdf->fresnel; - use_fresnel = true; - color = fresnel->color; - cspec0 = fresnel->cspec0; - } - else { - kernel_assert(bsdf->fresnel_type == MicrofacetFresnel::CONSTANT); - ccl_private FresnelConstant *fresnel = (ccl_private FresnelConstant *)bsdf->fresnel; - use_fresnel = false; - color = fresnel->color; - cspec0 = zero_spectrum(); - } - - bool is_aniso = (bsdf->alpha_x != bsdf->alpha_y); - if (is_aniso) - make_orthonormals_tangent(Z, bsdf->T, &X, &Y); - else - make_orthonormals(Z, &X, &Y); - - float3 local_I = make_float3(dot(wi, X), dot(wi, Y), dot(wi, Z)); - float3 local_O = make_float3(dot(wo, X), dot(wo, Y), dot(wo, Z)); - - if (is_aniso) - *pdf = mf_ggx_aniso_pdf(local_I, local_O, make_float2(bsdf->alpha_x, bsdf->alpha_y)); - else - *pdf = mf_ggx_pdf(local_I, local_O, bsdf->alpha_x); - - if (*pdf <= 0.f) { - *pdf = 0.f; - return make_float3(0.f, 0.f, 0.f); - } - - return mf_eval_glossy(local_I, - local_O, - true, - color, - bsdf->alpha_x, - bsdf->alpha_y, - lcg_state, - bsdf->ior, - use_fresnel, - cspec0); -} - -ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg, - ccl_private const ShaderClosure *sc, - float3 Ng, - float3 wi, - float randu, - float randv, - ccl_private Spectrum *eval, - ccl_private float3 *wo, - ccl_private float *pdf, - ccl_private uint *lcg_state, - ccl_private float2 *sampled_roughness, - ccl_private float *eta) -{ - ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; - - float3 X, Y, Z; - Z = bsdf->N; - - /* Ensure that the view direction is on the outside w.r.t. the shading normal. */ - if (dot(Z, wi) <= 0.0f) { - *pdf = 0.0f; - return LABEL_NONE; - } - - /* Special case: Extremely low roughness. - * Don't bother with microfacets, just do specular reflection. */ - if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) { - *wo = 2 * dot(Z, wi) * Z - wi; - if (dot(Ng, *wo) <= 0.0f) { - *pdf = 0.0f; - return LABEL_NONE; - } - *pdf = 1e6f; - *eval = make_spectrum(1e6f); - return LABEL_REFLECT | LABEL_SINGULAR; - } - - Spectrum color, cspec0; - bool use_fresnel; - if (bsdf->fresnel_type == MicrofacetFresnel::PRINCIPLED_V1) { - ccl_private FresnelPrincipledV1 *fresnel = (ccl_private FresnelPrincipledV1 *)bsdf->fresnel; - use_fresnel = true; - color = fresnel->color; - cspec0 = fresnel->cspec0; - } - else { - kernel_assert(bsdf->fresnel_type == MicrofacetFresnel::CONSTANT); - ccl_private FresnelConstant *fresnel = (ccl_private FresnelConstant *)bsdf->fresnel; - use_fresnel = false; - color = fresnel->color; - cspec0 = zero_spectrum(); - } - - *eta = bsdf->ior; - *sampled_roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y); - - bool is_aniso = (bsdf->alpha_x != bsdf->alpha_y); - if (is_aniso) - make_orthonormals_tangent(Z, bsdf->T, &X, &Y); - else - make_orthonormals(Z, &X, &Y); - - float3 local_I = make_float3(dot(wi, X), dot(wi, Y), dot(wi, Z)); - float3 local_O; - - *eval = mf_sample_glossy(local_I, - &local_O, - color, - bsdf->alpha_x, - bsdf->alpha_y, - lcg_state, - bsdf->ior, - use_fresnel, - cspec0); - *wo = X * local_O.x + Y * local_O.y + Z * local_O.z; - - /* Ensure that the light direction is on the outside w.r.t. the geometry normal. */ - if (dot(Ng, *wo) <= 0.0f) { - *pdf = 0.0f; - return LABEL_NONE; - } - - if (is_aniso) - *pdf = mf_ggx_aniso_pdf(local_I, local_O, make_float2(bsdf->alpha_x, bsdf->alpha_y)); - else - *pdf = mf_ggx_pdf(local_I, local_O, bsdf->alpha_x); - *pdf = fmaxf(0.f, *pdf); - *eval *= *pdf; - - return LABEL_REFLECT | LABEL_GLOSSY; -} - -/* Multi-scattering GGX Glass closure */ - -ccl_device int bsdf_microfacet_multi_ggx_glass_setup(ccl_private MicrofacetBsdf *bsdf) -{ - bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f); - bsdf->alpha_y = bsdf->alpha_x; - bsdf->ior = max(0.0f, bsdf->ior); - - ccl_private FresnelConstant *fresnel = (ccl_private FresnelConstant *)bsdf->fresnel; - fresnel->color = saturate(fresnel->color); - - bsdf->fresnel_type = MicrofacetFresnel::CONSTANT; - bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID; - - return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG | SD_BSDF_HAS_TRANSMISSION; -} - -ccl_device int bsdf_microfacet_multi_ggx_glass_fresnel_setup(ccl_private MicrofacetBsdf *bsdf, - ccl_private const ShaderData *sd) -{ - bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f); - bsdf->alpha_y = bsdf->alpha_x; - bsdf->ior = max(0.0f, bsdf->ior); - - ccl_private FresnelPrincipledV1 *fresnel = (ccl_private FresnelPrincipledV1 *)bsdf->fresnel; - fresnel->color = saturate(fresnel->color); - fresnel->cspec0 = saturate(fresnel->cspec0); - - bsdf->fresnel_type = MicrofacetFresnel::PRINCIPLED_V1; - bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID; - bsdf->sample_weight *= average(bsdf_microfacet_estimate_fresnel(sd, bsdf)); - - return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG; -} - -ccl_device Spectrum bsdf_microfacet_multi_ggx_glass_eval(ccl_private const ShaderClosure *sc, - const float3 wi, - const float3 wo, - ccl_private float *pdf, - ccl_private uint *lcg_state) -{ - ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; - - if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) { - *pdf = 0.0f; - return zero_spectrum(); - } - - float3 X, Y, Z; - Z = bsdf->N; - make_orthonormals(Z, &X, &Y); - - float3 local_I = make_float3(dot(wi, X), dot(wi, Y), dot(wi, Z)); - float3 local_O = make_float3(dot(wo, X), dot(wo, Y), dot(wo, Z)); - - const bool is_transmission = local_O.z < 0.0f; - - Spectrum color, cspec0; - bool use_fresnel; - if (bsdf->fresnel_type == MicrofacetFresnel::PRINCIPLED_V1) { - ccl_private FresnelPrincipledV1 *fresnel = (ccl_private FresnelPrincipledV1 *)bsdf->fresnel; - use_fresnel = true; - color = fresnel->color; - cspec0 = is_transmission ? fresnel->color : fresnel->cspec0; - } - else { - kernel_assert(bsdf->fresnel_type == MicrofacetFresnel::CONSTANT); - ccl_private FresnelConstant *fresnel = (ccl_private FresnelConstant *)bsdf->fresnel; - use_fresnel = false; - color = fresnel->color; - cspec0 = zero_spectrum(); - } - - *pdf = mf_glass_pdf(local_I, local_O, bsdf->alpha_x, bsdf->ior); - kernel_assert(*pdf >= 0.f); - return mf_eval_glass(local_I, - local_O, - !is_transmission, - color, - bsdf->alpha_x, - bsdf->alpha_y, - lcg_state, - bsdf->ior, - !is_transmission && use_fresnel, - cspec0); -} - -ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals kg, - ccl_private const ShaderClosure *sc, - float3 Ng, - float3 wi, - float randu, - float randv, - ccl_private Spectrum *eval, - ccl_private float3 *wo, - ccl_private float *pdf, - ccl_private uint *lcg_state, - ccl_private float2 *sampled_roughness, - ccl_private float *eta) -{ - ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; - - float3 X, Y, Z; - Z = bsdf->N; - - *eta = bsdf->ior; - *sampled_roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y); - - if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) { - float3 T; - bool inside; - float fresnel = fresnel_dielectric(bsdf->ior, Z, wi, &T, &inside); - - *pdf = 1e6f; - *eval = make_spectrum(1e6f); - if (randu < fresnel) { - *wo = 2 * dot(Z, wi) * Z - wi; - return LABEL_REFLECT | LABEL_SINGULAR; - } - else { - *wo = T; - return LABEL_TRANSMIT | LABEL_SINGULAR; - } - } - - Spectrum color, cspec0; - bool use_fresnel; - if (bsdf->fresnel_type == MicrofacetFresnel::PRINCIPLED_V1) { - ccl_private FresnelPrincipledV1 *fresnel = (ccl_private FresnelPrincipledV1 *)bsdf->fresnel; - use_fresnel = true; - color = fresnel->color; - cspec0 = fresnel->cspec0; - } - else { - kernel_assert(bsdf->fresnel_type == MicrofacetFresnel::CONSTANT); - ccl_private FresnelConstant *fresnel = (ccl_private FresnelConstant *)bsdf->fresnel; - use_fresnel = false; - color = fresnel->color; - cspec0 = zero_spectrum(); - } - - make_orthonormals(Z, &X, &Y); - - float3 local_I = make_float3(dot(wi, X), dot(wi, Y), dot(wi, Z)); - float3 local_O; - - *eval = mf_sample_glass(local_I, - &local_O, - color, - bsdf->alpha_x, - bsdf->alpha_y, - lcg_state, - bsdf->ior, - use_fresnel, - cspec0); - *pdf = mf_glass_pdf(local_I, local_O, bsdf->alpha_x, bsdf->ior); - kernel_assert(*pdf >= 0.f); - *eval *= *pdf; - - *wo = X * local_O.x + Y * local_O.y + Z * local_O.z; - if (local_O.z * local_I.z > 0.0f) { - return LABEL_REFLECT | LABEL_GLOSSY; - } - else { - return LABEL_TRANSMIT | LABEL_GLOSSY; - } -} - -CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h b/intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h deleted file mode 100644 index af1a821b361..00000000000 --- a/intern/cycles/kernel/closure/bsdf_microfacet_multi_impl.h +++ /dev/null @@ -1,250 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 - * Copyright 2011-2022 Blender Foundation */ - -/* Evaluate the BSDF from wi to wo. - * Evaluation is split into the analytical single-scattering BSDF and the multi-scattering BSDF, - * which is evaluated stochastically through a random walk. At each bounce (except for the first - * one), the amount of reflection from here towards wo is evaluated before bouncing again. - * - * Because of the random walk, the evaluation is not deterministic, but its expected value is equal - * to the correct BSDF, which is enough for Monte-Carlo rendering. The PDF also can't be determined - * analytically, so the single-scattering PDF plus a diffuse term to account for the - * multi-scattered energy is used. In combination with MIS, that is enough to produce an unbiased - * result, although the balance heuristic isn't necessarily optimal anymore. - */ -ccl_device_forceinline Spectrum MF_FUNCTION_FULL_NAME(mf_eval)(float3 wi, - float3 wo, - const bool wo_outside, - const Spectrum color, - const float alpha_x, - const float alpha_y, - ccl_private uint *lcg_state, - const float eta, - bool use_fresnel, - const Spectrum cspec0) -{ - /* Evaluating for a shallower incoming direction produces less noise, and the properties of the - * BSDF guarantee reciprocity. */ - bool swapped = false; -#ifdef MF_MULTI_GLASS - if (wi.z * wo.z < 0.0f) { - /* Glass transmission is a special case and requires the directions to change hemisphere. */ - if (-wo.z < wi.z) { - swapped = true; - float3 tmp = -wo; - wo = -wi; - wi = tmp; - } - } - else -#endif - if (wo.z < wi.z) - { - swapped = true; - float3 tmp = wo; - wo = wi; - wi = tmp; - } - - if (wi.z < 1e-5f || (wo.z < 1e-5f && wo_outside) || (wo.z > -1e-5f && !wo_outside)) - return zero_spectrum(); - - const float2 alpha = make_float2(alpha_x, alpha_y); - - float lambda_r = mf_lambda(-wi, alpha); - float shadowing_lambda = mf_lambda(wo_outside ? wo : -wo, alpha); - - /* Analytically compute single scattering for lower noise. */ - Spectrum eval; - Spectrum throughput = one_spectrum(); - const float3 wh = normalize(wi + wo); -#ifdef MF_MULTI_GLASS - eval = mf_eval_phase_glass(-wi, lambda_r, wo, wo_outside, alpha, eta); - if (wo_outside) - eval *= -lambda_r / (shadowing_lambda - lambda_r); - else - eval *= -lambda_r * beta(-lambda_r, shadowing_lambda + 1.0f); -#else /* MF_MULTI_GLOSSY */ - const float G2 = 1.0f / (1.0f - (lambda_r + 1.0f) + shadowing_lambda); - float val = G2 * 0.25f / wi.z; - if (alpha.x == alpha.y) - val *= D_ggx(wh, alpha.x); - else - val *= D_ggx_aniso(wh, alpha); - eval = make_spectrum(val); -#endif - - if (use_fresnel) { - throughput = interpolate_fresnel_color(wi, wh, eta, cspec0); - - eval *= throughput; - } - - float3 wr = -wi; - float hr = 1.0f; - float C1_r = 1.0f; - float G1_r = 0.0f; - bool outside = true; - - for (int order = 0; order < 10; order++) { - /* Sample microfacet height. */ - float height_rand = lcg_step_float(lcg_state); - if (!mf_sample_height(wr, &hr, &C1_r, &G1_r, &lambda_r, height_rand)) - break; - /* Sample microfacet normal. */ - float vndf_rand_y = lcg_step_float(lcg_state); - float vndf_rand_x = lcg_step_float(lcg_state); - float3 wm = mf_sample_vndf(-wr, alpha, vndf_rand_x, vndf_rand_y); - -#ifdef MF_MULTI_GLASS - if (order == 0 && use_fresnel) { - /* Evaluate amount of scattering towards wo on this microfacet. */ - Spectrum phase; - if (outside) - phase = mf_eval_phase_glass(wr, lambda_r, wo, wo_outside, alpha, eta); - else - phase = mf_eval_phase_glass(wr, lambda_r, -wo, !wo_outside, alpha, 1.0f / eta); - - eval = throughput * phase * - mf_G1(wo_outside ? wo : -wo, - mf_C1((outside == wo_outside) ? hr : -hr), - shadowing_lambda); - } -#endif - if (order > 0) { - /* Evaluate amount of scattering towards wo on this microfacet. */ - Spectrum phase; -#ifdef MF_MULTI_GLASS - if (outside) - phase = mf_eval_phase_glass(wr, lambda_r, wo, wo_outside, alpha, eta); - else - phase = mf_eval_phase_glass(wr, lambda_r, -wo, !wo_outside, alpha, 1.0f / eta); -#else /* MF_MULTI_GLOSSY */ - phase = mf_eval_phase_glossy(wr, lambda_r, wo, alpha) * throughput; -#endif - eval += throughput * phase * - mf_G1(wo_outside ? wo : -wo, - mf_C1((outside == wo_outside) ? hr : -hr), - shadowing_lambda); - } - if (order + 1 < 10) { - /* Bounce from the microfacet. */ -#ifdef MF_MULTI_GLASS - bool next_outside; - float3 wi_prev = -wr; - float phase_rand = lcg_step_float(lcg_state); - wr = mf_sample_phase_glass(-wr, outside ? eta : 1.0f / eta, wm, phase_rand, &next_outside); - if (!next_outside) { - outside = !outside; - wr = -wr; - hr = -hr; - } - - if (use_fresnel && !next_outside) { - throughput *= color; - } - else if (use_fresnel && order > 0) { - throughput *= interpolate_fresnel_color(wi_prev, wm, eta, cspec0); - } -#else /* MF_MULTI_GLOSSY */ - if (use_fresnel && order > 0) { - throughput *= interpolate_fresnel_color(-wr, wm, eta, cspec0); - } - wr = mf_sample_phase_glossy(-wr, &throughput, wm); -#endif - - lambda_r = mf_lambda(wr, alpha); - - if (!use_fresnel) - throughput *= color; - - C1_r = mf_C1(hr); - G1_r = mf_G1(wr, C1_r, lambda_r); - } - } - - if (swapped) - eval *= fabsf(wi.z / wo.z); - return eval; -} - -/* Perform a random walk on the microsurface starting from wi, returning the direction in which the - * walk escaped the surface in wo. The function returns the throughput between wi and wo. Without - * reflection losses due to coloring or fresnel absorption in conductors, the sampling is optimal. - */ -ccl_device_forceinline Spectrum MF_FUNCTION_FULL_NAME(mf_sample)(float3 wi, - ccl_private float3 *wo, - const Spectrum color, - const float alpha_x, - const float alpha_y, - ccl_private uint *lcg_state, - const float eta, - bool use_fresnel, - const Spectrum cspec0) -{ - const float2 alpha = make_float2(alpha_x, alpha_y); - - Spectrum throughput = one_spectrum(); - float3 wr = -wi; - float lambda_r = mf_lambda(wr, alpha); - float hr = 1.0f; - float C1_r = 1.0f; - float G1_r = 0.0f; - bool outside = true; - - int order; - for (order = 0; order < 10; order++) { - /* Sample microfacet height. */ - float height_rand = lcg_step_float(lcg_state); - if (!mf_sample_height(wr, &hr, &C1_r, &G1_r, &lambda_r, height_rand)) { - /* The random walk has left the surface. */ - *wo = outside ? wr : -wr; - return throughput; - } - /* Sample microfacet normal. */ - float vndf_rand_y = lcg_step_float(lcg_state); - float vndf_rand_x = lcg_step_float(lcg_state); - float3 wm = mf_sample_vndf(-wr, alpha, vndf_rand_x, vndf_rand_y); - - /* First-bounce color is already accounted for in mix weight. */ - if (!use_fresnel && order > 0) - throughput *= color; - - /* Bounce from the microfacet. */ -#ifdef MF_MULTI_GLASS - bool next_outside; - float3 wi_prev = -wr; - float phase_rand = lcg_step_float(lcg_state); - wr = mf_sample_phase_glass(-wr, outside ? eta : 1.0f / eta, wm, phase_rand, &next_outside); - if (!next_outside) { - hr = -hr; - wr = -wr; - outside = !outside; - } - - if (use_fresnel) { - if (!next_outside) { - throughput *= color; - } - else { - throughput *= interpolate_fresnel_color(wi_prev, wm, eta, cspec0); - } - } -#else /* MF_MULTI_GLOSSY */ - if (use_fresnel) { - throughput *= interpolate_fresnel_color(-wr, wm, eta, cspec0); - } - wr = mf_sample_phase_glossy(-wr, &throughput, wm); -#endif - - /* Update random walk parameters. */ - lambda_r = mf_lambda(wr, alpha); - G1_r = mf_G1(wr, C1_r, lambda_r); - } - *wo = make_float3(0.0f, 0.0f, 1.0f); - return zero_spectrum(); -} - -#undef MF_MULTI_GLASS -#undef MF_MULTI_GLOSSY -#undef MF_PHASE_FUNCTION diff --git a/intern/cycles/kernel/closure/bsdf_util.h b/intern/cycles/kernel/closure/bsdf_util.h index de59556bb08..4e62820619e 100644 --- a/intern/cycles/kernel/closure/bsdf_util.h +++ b/intern/cycles/kernel/closure/bsdf_util.h @@ -75,12 +75,17 @@ ccl_device Spectrum fresnel_conductor(float cosi, const Spectrum eta, const Spec return (Rparl2 + Rperp2) * 0.5f; } -ccl_device float ior_from_F0(Spectrum f0) +ccl_device float ior_from_F0(float f0) { - const float sqrt_f0 = sqrtf(clamp(average(f0), 0.0f, 0.99f)); + const float sqrt_f0 = sqrtf(clamp(f0, 0.0f, 0.99f)); return (1.0f + sqrt_f0) / (1.0f - sqrt_f0); } +ccl_device float F0_from_ior(float ior) +{ + return sqr((ior - 1.0f) / (ior + 1.0f)); +} + ccl_device float schlick_fresnel(float u) { float m = clamp(1.0f - u, 0.0f, 1.0f); diff --git a/intern/cycles/kernel/osl/closures_setup.h b/intern/cycles/kernel/osl/closures_setup.h index 549ab3b6b21..041d02e8f85 100644 --- a/intern/cycles/kernel/osl/closures_setup.h +++ b/intern/cycles/kernel/osl/closures_setup.h @@ -14,7 +14,6 @@ #include "kernel/closure/bsdf_ashikhmin_velvet.h" #include "kernel/closure/bsdf_diffuse.h" #include "kernel/closure/bsdf_microfacet.h" -#include "kernel/closure/bsdf_microfacet_multi.h" #include "kernel/closure/bsdf_oren_nayar.h" #include "kernel/closure/bsdf_transparent.h" #include "kernel/closure/bsdf_ashikhmin_shirley.h" @@ -209,27 +208,12 @@ ccl_device void osl_closure_dielectric_bsdf_setup(KernelGlobals kg, bsdf->alpha_x = closure->alpha_x; bsdf->alpha_y = closure->alpha_y; bsdf->ior = closure->ior; - if (sd->flag & SD_BACKFACING) { - bsdf->ior = 1.0f / bsdf->ior; - } bsdf->T = closure->T; - /* GGX */ - if (closure->distribution == make_string("ggx", 11253504724482777663ull) || - closure->distribution == make_string("default", 4430693559278735917ull)) - { - if (has_reflection && has_transmission) { - sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf); - } - else if (has_transmission) { - sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf); - } - else { - sd->flag |= bsdf_microfacet_ggx_setup(bsdf); - } - } + bool preserve_energy = false; + /* Beckmann */ - else { + if (closure->distribution == make_string("beckmann", 14712237670914973463ull)) { if (has_reflection && has_transmission) { sd->flag |= bsdf_microfacet_beckmann_glass_setup(bsdf); } @@ -240,10 +224,24 @@ ccl_device void osl_closure_dielectric_bsdf_setup(KernelGlobals kg, sd->flag |= bsdf_microfacet_beckmann_setup(bsdf); } } + /* GGX (either single- or multiscattering) */ + else { + if (has_reflection && has_transmission) { + sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf); + } + else if (has_transmission) { + sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf); + } + else { + sd->flag |= bsdf_microfacet_ggx_setup(bsdf); + } + + preserve_energy = (closure->distribution == make_string("multi_ggx", 16842698693386468366ull)); + } fresnel->reflection_tint = rgb_to_spectrum(closure->reflection_tint); fresnel->transmission_tint = rgb_to_spectrum(closure->transmission_tint); - bsdf_microfacet_setup_fresnel_dielectric_tint(bsdf, sd, fresnel); + bsdf_microfacet_setup_fresnel_dielectric_tint(kg, bsdf, sd, fresnel, preserve_energy); } ccl_device void osl_closure_conductor_bsdf_setup(KernelGlobals kg, @@ -274,20 +272,21 @@ ccl_device void osl_closure_conductor_bsdf_setup(KernelGlobals kg, bsdf->ior = 0.0f; bsdf->T = closure->T; - /* GGX */ - if (closure->distribution == make_string("ggx", 11253504724482777663ull) || - closure->distribution == make_string("default", 4430693559278735917ull)) - { - sd->flag |= bsdf_microfacet_ggx_setup(bsdf); - } + bool preserve_energy = false; + /* Beckmann */ - else { + if (closure->distribution == make_string("beckmann", 14712237670914973463ull)) { sd->flag |= bsdf_microfacet_beckmann_setup(bsdf); } + /* GGX (either single- or multiscattering) */ + else { + sd->flag |= bsdf_microfacet_ggx_setup(bsdf); + preserve_energy = (closure->distribution == make_string("multi_ggx", 16842698693386468366ull)); + } fresnel->n = rgb_to_spectrum(closure->ior); fresnel->k = rgb_to_spectrum(closure->extinction); - bsdf_microfacet_setup_fresnel_conductor(bsdf, sd, fresnel); + bsdf_microfacet_setup_fresnel_conductor(kg, bsdf, sd, fresnel, preserve_energy); } ccl_device void osl_closure_generalized_schlick_bsdf_setup( @@ -319,28 +318,16 @@ ccl_device void osl_closure_generalized_schlick_bsdf_setup( bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N); bsdf->alpha_x = closure->alpha_x; bsdf->alpha_y = closure->alpha_y; - bsdf->ior = ior_from_F0(closure->f0); + bsdf->ior = ior_from_F0(average(closure->f0)); if (sd->flag & SD_BACKFACING) { bsdf->ior = 1.0f / bsdf->ior; } bsdf->T = closure->T; - /* GGX */ - if (closure->distribution == make_string("ggx", 11253504724482777663ull) || - closure->distribution == make_string("default", 4430693559278735917ull)) - { - if (has_reflection && has_transmission) { - sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf); - } - else if (has_transmission) { - sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf); - } - else { - sd->flag |= bsdf_microfacet_ggx_setup(bsdf); - } - } + bool preserve_energy = false; + /* Beckmann */ - else { + if (closure->distribution == make_string("beckmann", 14712237670914973463ull)) { if (has_reflection && has_transmission) { sd->flag |= bsdf_microfacet_beckmann_glass_setup(bsdf); } @@ -351,13 +338,27 @@ ccl_device void osl_closure_generalized_schlick_bsdf_setup( sd->flag |= bsdf_microfacet_beckmann_setup(bsdf); } } + /* GGX (either single- or multiscattering) */ + else { + if (has_reflection && has_transmission) { + sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf); + } + else if (has_transmission) { + sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf); + } + else { + sd->flag |= bsdf_microfacet_ggx_setup(bsdf); + } + + preserve_energy = (closure->distribution == make_string("multi_ggx", 16842698693386468366ull)); + } fresnel->reflection_tint = rgb_to_spectrum(closure->reflection_tint); fresnel->transmission_tint = rgb_to_spectrum(closure->transmission_tint); fresnel->f0 = rgb_to_spectrum(closure->f0); fresnel->f90 = rgb_to_spectrum(closure->f90); fresnel->exponent = closure->exponent; - bsdf_microfacet_setup_fresnel_generalized_schlick(bsdf, sd, fresnel); + bsdf_microfacet_setup_fresnel_generalized_schlick(kg, bsdf, sd, fresnel, preserve_energy); } /* Standard microfacet closures */ @@ -413,7 +414,7 @@ ccl_device void osl_closure_microfacet_setup(KernelGlobals kg, else if (closure->distribution == make_string("ashikhmin_shirley", 11318482998918370922ull)) { sd->flag |= bsdf_ashikhmin_shirley_setup(bsdf); } - /* GGX */ + /* GGX (either single- or multiscattering) */ else { if (closure->refract == 1) { sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf); @@ -424,195 +425,15 @@ ccl_device void osl_closure_microfacet_setup(KernelGlobals kg, else { sd->flag |= bsdf_microfacet_ggx_setup(bsdf); } + + if (closure->distribution == make_string("multi_ggx", 16842698693386468366ull)) { + /* Since there's no dedicated color input, the weight is the best we got. */ + bsdf_microfacet_setup_fresnel_constant(kg, bsdf, sd, rgb_to_spectrum(weight)); + } } } -ccl_device void osl_closure_microfacet_ggx_setup( - KernelGlobals kg, - ccl_private ShaderData *sd, - uint32_t path_flag, - float3 weight, - ccl_private const MicrofacetGGXIsotropicClosure *closure) -{ - if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { - return; - } - - ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( - sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); - if (!bsdf) { - return; - } - - bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N); - bsdf->alpha_x = bsdf->alpha_y = closure->alpha_x; - - sd->flag |= bsdf_microfacet_ggx_setup(bsdf); -} - -ccl_device void osl_closure_microfacet_ggx_aniso_setup( - KernelGlobals kg, - ccl_private ShaderData *sd, - uint32_t path_flag, - float3 weight, - ccl_private const MicrofacetGGXClosure *closure) -{ - if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { - return; - } - - ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( - sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); - if (!bsdf) { - return; - } - - bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N); - bsdf->alpha_x = closure->alpha_x; - bsdf->alpha_y = closure->alpha_y; - bsdf->T = closure->T; - - sd->flag |= bsdf_microfacet_ggx_setup(bsdf); -} - -ccl_device void osl_closure_microfacet_ggx_refraction_setup( - KernelGlobals kg, - ccl_private ShaderData *sd, - uint32_t path_flag, - float3 weight, - ccl_private const MicrofacetGGXRefractionClosure *closure) -{ - if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_TRANSMIT)) { - return; - } - - ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( - sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); - if (!bsdf) { - return; - } - - bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N); - bsdf->alpha_x = closure->alpha_x; - bsdf->ior = closure->ior; - - sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf); -} - -/* GGX closures with Fresnel */ - -ccl_device void osl_closure_microfacet_ggx_fresnel_setup( - KernelGlobals kg, - ccl_private ShaderData *sd, - uint32_t path_flag, - float3 weight, - ccl_private const MicrofacetGGXFresnelClosure *closure) -{ - if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { - return; - } - - ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( - sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); - if (!bsdf) { - return; - } - - ccl_private FresnelPrincipledV1 *fresnel = (ccl_private FresnelPrincipledV1 *) - closure_alloc_extra(sd, sizeof(FresnelPrincipledV1)); - if (!fresnel) { - return; - } - - bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N); - bsdf->alpha_x = closure->alpha_x; - bsdf->alpha_y = bsdf->alpha_x; - bsdf->ior = closure->ior; - bsdf->T = zero_float3(); - - sd->flag |= bsdf_microfacet_ggx_setup(bsdf); - - fresnel->color = rgb_to_spectrum(closure->color); - fresnel->cspec0 = rgb_to_spectrum(closure->cspec0); - bsdf_microfacet_setup_fresnel_principledv1(bsdf, sd, fresnel); -} - -ccl_device void osl_closure_microfacet_ggx_aniso_fresnel_setup( - KernelGlobals kg, - ccl_private ShaderData *sd, - uint32_t path_flag, - float3 weight, - ccl_private const MicrofacetGGXAnisoFresnelClosure *closure) -{ - if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { - return; - } - - ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( - sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); - if (!bsdf) { - return; - } - - ccl_private FresnelPrincipledV1 *fresnel = (ccl_private FresnelPrincipledV1 *) - closure_alloc_extra(sd, sizeof(FresnelPrincipledV1)); - if (!fresnel) { - return; - } - - bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N); - bsdf->alpha_x = closure->alpha_x; - bsdf->alpha_y = closure->alpha_y; - bsdf->ior = closure->ior; - bsdf->T = closure->T; - - sd->flag |= bsdf_microfacet_ggx_setup(bsdf); - - fresnel->color = rgb_to_spectrum(closure->color); - fresnel->cspec0 = rgb_to_spectrum(closure->cspec0); - bsdf_microfacet_setup_fresnel_principledv1(bsdf, sd, fresnel); -} - -/* Multi-scattering GGX closures */ - -ccl_device void osl_closure_microfacet_multi_ggx_setup( - KernelGlobals kg, - ccl_private ShaderData *sd, - uint32_t path_flag, - float3 weight, - ccl_private const MicrofacetMultiGGXClosure *closure) -{ - /* Technically, the MultiGGX closure may also transmit. However, - * since this is set statically and only used for caustic flags, this - * is probably as good as it gets. */ - if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { - return; - } - - ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( - sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); - if (!bsdf) { - return; - } - - ccl_private FresnelConstant *fresnel = (ccl_private FresnelConstant *)closure_alloc_extra( - sd, sizeof(FresnelConstant)); - if (!fresnel) { - return; - } - - bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N); - bsdf->alpha_x = closure->alpha_x; - bsdf->alpha_y = bsdf->alpha_x; - bsdf->ior = 1.0f; - - bsdf->fresnel = fresnel; - fresnel->color = rgb_to_spectrum(closure->color); - - bsdf->T = zero_float3(); - - sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf); -} +/* Special-purpose Microfacet closures */ ccl_device void osl_closure_microfacet_multi_ggx_glass_setup( KernelGlobals kg, @@ -634,23 +455,15 @@ ccl_device void osl_closure_microfacet_multi_ggx_glass_setup( return; } - ccl_private FresnelConstant *fresnel = (ccl_private FresnelConstant *)closure_alloc_extra( - sd, sizeof(FresnelConstant)); - if (!fresnel) { - return; - } - bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N); bsdf->alpha_x = closure->alpha_x; bsdf->alpha_y = bsdf->alpha_x; bsdf->ior = closure->ior; - bsdf->fresnel = fresnel; - fresnel->color = rgb_to_spectrum(closure->color); - bsdf->T = zero_float3(); - sd->flag |= bsdf_microfacet_multi_ggx_glass_setup(bsdf); + sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf); + bsdf_microfacet_setup_fresnel_constant(kg, bsdf, sd, rgb_to_spectrum(closure->color)); } ccl_device void osl_closure_microfacet_multi_ggx_aniso_setup( @@ -658,11 +471,8 @@ ccl_device void osl_closure_microfacet_multi_ggx_aniso_setup( ccl_private ShaderData *sd, uint32_t path_flag, float3 weight, - ccl_private const MicrofacetMultiGGXAnisoClosure *closure) + ccl_private const MicrofacetMultiGGXClosure *closure) { - /* Technically, the MultiGGX closure may also transmit. However, - * since this is set statically and only used for caustic flags, this - * is probably as good as it gets. */ if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { return; } @@ -673,37 +483,24 @@ ccl_device void osl_closure_microfacet_multi_ggx_aniso_setup( return; } - ccl_private FresnelConstant *fresnel = (ccl_private FresnelConstant *)closure_alloc_extra( - sd, sizeof(FresnelConstant)); - if (!fresnel) { - return; - } - bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N); bsdf->alpha_x = closure->alpha_x; bsdf->alpha_y = closure->alpha_y; bsdf->ior = 1.0f; - bsdf->fresnel = fresnel; - fresnel->color = rgb_to_spectrum(closure->color); - bsdf->T = closure->T; - sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf); + sd->flag |= bsdf_microfacet_ggx_setup(bsdf); + bsdf_microfacet_setup_fresnel_constant(kg, bsdf, sd, rgb_to_spectrum(closure->color)); } -/* Multi-scattering GGX closures with Fresnel */ - -ccl_device void osl_closure_microfacet_multi_ggx_fresnel_setup( +ccl_device void osl_closure_microfacet_aniso_fresnel_setup( KernelGlobals kg, ccl_private ShaderData *sd, uint32_t path_flag, float3 weight, - ccl_private const MicrofacetMultiGGXFresnelClosure *closure) + ccl_private const MicrofacetAnisoFresnelClosure *closure) { - /* Technically, the MultiGGX closure may also transmit. However, - * since this is set statically and only used for caustic flags, this - * is probably as good as it gets. */ if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { return; } @@ -714,88 +511,8 @@ ccl_device void osl_closure_microfacet_multi_ggx_fresnel_setup( return; } - ccl_private FresnelPrincipledV1 *fresnel = (ccl_private FresnelPrincipledV1 *) - closure_alloc_extra(sd, sizeof(FresnelPrincipledV1)); - if (!fresnel) { - return; - } - - bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N); - bsdf->alpha_x = closure->alpha_x; - bsdf->alpha_y = bsdf->alpha_x; - bsdf->ior = closure->ior; - - bsdf->fresnel = fresnel; - fresnel->color = rgb_to_spectrum(closure->color); - fresnel->cspec0 = rgb_to_spectrum(closure->cspec0); - - bsdf->T = zero_float3(); - - sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd); -} - -ccl_device void osl_closure_microfacet_multi_ggx_glass_fresnel_setup( - KernelGlobals kg, - ccl_private ShaderData *sd, - uint32_t path_flag, - float3 weight, - ccl_private const MicrofacetMultiGGXGlassFresnelClosure *closure) -{ - /* Technically, the MultiGGX closure may also transmit. However, - * since this is set statically and only used for caustic flags, this - * is probably as good as it gets. */ - if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { - return; - } - - ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( - sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); - if (!bsdf) { - return; - } - - ccl_private FresnelPrincipledV1 *fresnel = (ccl_private FresnelPrincipledV1 *) - closure_alloc_extra(sd, sizeof(FresnelPrincipledV1)); - if (!fresnel) { - return; - } - - bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N); - bsdf->alpha_x = closure->alpha_x; - bsdf->alpha_y = bsdf->alpha_x; - bsdf->ior = closure->ior; - - bsdf->fresnel = fresnel; - fresnel->color = rgb_to_spectrum(closure->color); - fresnel->cspec0 = rgb_to_spectrum(closure->cspec0); - - bsdf->T = zero_float3(); - - sd->flag |= bsdf_microfacet_multi_ggx_glass_fresnel_setup(bsdf, sd); -} - -ccl_device void osl_closure_microfacet_multi_ggx_aniso_fresnel_setup( - KernelGlobals kg, - ccl_private ShaderData *sd, - uint32_t path_flag, - float3 weight, - ccl_private const MicrofacetMultiGGXAnisoFresnelClosure *closure) -{ - /* Technically, the MultiGGX closure may also transmit. However, - * since this is set statically and only used for caustic flags, this - * is probably as good as it gets. */ - if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { - return; - } - - ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( - sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); - if (!bsdf) { - return; - } - - ccl_private FresnelPrincipledV1 *fresnel = (ccl_private FresnelPrincipledV1 *) - closure_alloc_extra(sd, sizeof(FresnelPrincipledV1)); + ccl_private FresnelGeneralizedSchlick *fresnel = (ccl_private FresnelGeneralizedSchlick *) + closure_alloc_extra(sd, sizeof(FresnelGeneralizedSchlick)); if (!fresnel) { return; } @@ -804,91 +521,23 @@ ccl_device void osl_closure_microfacet_multi_ggx_aniso_fresnel_setup( bsdf->alpha_x = closure->alpha_x; bsdf->alpha_y = closure->alpha_y; bsdf->ior = closure->ior; - - bsdf->fresnel = fresnel; - fresnel->color = rgb_to_spectrum(closure->color); - fresnel->cspec0 = rgb_to_spectrum(closure->cspec0); - bsdf->T = closure->T; - sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd); + /* Only GGX (either single- or multiscattering) supported here */ + sd->flag |= bsdf_microfacet_ggx_setup(bsdf); + + const bool preserve_energy = (closure->distribution == + make_string("multi_ggx", 16842698693386468366ull)); + + fresnel->reflection_tint = one_spectrum(); + fresnel->transmission_tint = zero_spectrum(); + fresnel->f0 = rgb_to_spectrum(closure->f0); + fresnel->f90 = rgb_to_spectrum(closure->f90); + fresnel->exponent = -1.0f; + bsdf_microfacet_setup_fresnel_generalized_schlick(kg, bsdf, sd, fresnel, preserve_energy); } -/* Beckmann closures */ - -ccl_device void osl_closure_microfacet_beckmann_setup( - KernelGlobals kg, - ccl_private ShaderData *sd, - uint32_t path_flag, - float3 weight, - ccl_private const MicrofacetBeckmannIsotropicClosure *closure) -{ - if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { - return; - } - - ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( - sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); - if (!bsdf) { - return; - } - - bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N); - bsdf->alpha_x = bsdf->alpha_y = closure->alpha_x; - - sd->flag |= bsdf_microfacet_beckmann_setup(bsdf); -} - -ccl_device void osl_closure_microfacet_beckmann_aniso_setup( - KernelGlobals kg, - ccl_private ShaderData *sd, - uint32_t path_flag, - float3 weight, - ccl_private const MicrofacetBeckmannClosure *closure) -{ - if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { - return; - } - - ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( - sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); - if (!bsdf) { - return; - } - - bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N); - bsdf->alpha_x = closure->alpha_x; - bsdf->alpha_y = closure->alpha_y; - bsdf->T = closure->T; - - sd->flag |= bsdf_microfacet_beckmann_setup(bsdf); -} - -ccl_device void osl_closure_microfacet_beckmann_refraction_setup( - KernelGlobals kg, - ccl_private ShaderData *sd, - uint32_t path_flag, - float3 weight, - ccl_private const MicrofacetBeckmannRefractionClosure *closure) -{ - if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_TRANSMIT)) { - return; - } - - ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( - sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); - if (!bsdf) { - return; - } - - bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N); - bsdf->alpha_x = closure->alpha_x; - bsdf->ior = closure->ior; - - sd->flag |= bsdf_microfacet_beckmann_refraction_setup(bsdf); -} - -/* Ashikhmin closures */ +/* Ashikhmin Velvet */ ccl_device void osl_closure_ashikhmin_velvet_setup( KernelGlobals kg, @@ -913,31 +562,6 @@ ccl_device void osl_closure_ashikhmin_velvet_setup( sd->flag |= bsdf_ashikhmin_velvet_setup(bsdf); } -ccl_device void osl_closure_ashikhmin_shirley_setup( - KernelGlobals kg, - ccl_private ShaderData *sd, - uint32_t path_flag, - float3 weight, - ccl_private const AshikhminShirleyClosure *closure) -{ - if (osl_closure_skip(kg, sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) { - return; - } - - ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( - sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(weight)); - if (!bsdf) { - return; - } - - bsdf->N = ensure_valid_specular_reflection(sd->Ng, sd->wi, closure->N); - bsdf->alpha_x = closure->alpha_x; - bsdf->alpha_y = closure->alpha_y; - bsdf->T = closure->T; - - sd->flag |= bsdf_ashikhmin_shirley_setup(bsdf); -} - ccl_device void osl_closure_diffuse_toon_setup(KernelGlobals kg, ccl_private ShaderData *sd, uint32_t path_flag, diff --git a/intern/cycles/kernel/osl/closures_template.h b/intern/cycles/kernel/osl/closures_template.h index e1ecd7f9d06..e7b93e48769 100644 --- a/intern/cycles/kernel/osl/closures_template.h +++ b/intern/cycles/kernel/osl/closures_template.h @@ -83,30 +83,6 @@ OSL_CLOSURE_STRUCT_BEGIN(Microfacet, microfacet) OSL_CLOSURE_STRUCT_MEMBER(Microfacet, INT, int, refract, NULL) OSL_CLOSURE_STRUCT_END(Microfacet, microfacet) -OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGXIsotropic, microfacet_ggx) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXIsotropic, VECTOR, packed_float3, N, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXIsotropic, FLOAT, float, alpha_x, NULL) -OSL_CLOSURE_STRUCT_END(MicrofacetGGXIsotropic, microfacet_ggx) - -OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGX, microfacet_ggx_aniso) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGX, VECTOR, packed_float3, N, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGX, VECTOR, packed_float3, T, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGX, FLOAT, float, alpha_x, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGX, FLOAT, float, alpha_y, NULL) -OSL_CLOSURE_STRUCT_END(MicrofacetGGX, microfacet_ggx_aniso) - -OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGXRefraction, microfacet_ggx_refraction) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXRefraction, VECTOR, packed_float3, N, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXRefraction, FLOAT, float, alpha_x, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXRefraction, FLOAT, float, ior, NULL) -OSL_CLOSURE_STRUCT_END(MicrofacetGGXRefraction, microfacet_ggx_refraction) - -OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGX, microfacet_multi_ggx) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, VECTOR, packed_float3, N, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, FLOAT, float, alpha_x, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, VECTOR, packed_float3, color, NULL) -OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGX, microfacet_multi_ggx) - OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXGlass, microfacet_multi_ggx_glass) OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlass, VECTOR, packed_float3, N, NULL) OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlass, FLOAT, float, alpha_x, NULL) @@ -114,82 +90,24 @@ OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXGlass, microfacet_multi_ggx_glass) OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlass, VECTOR, packed_float3, color, NULL) OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXGlass, microfacet_multi_ggx_glass) -OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXAniso, microfacet_multi_ggx_aniso) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, VECTOR, packed_float3, N, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, VECTOR, packed_float3, T, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, FLOAT, float, alpha_x, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, FLOAT, float, alpha_y, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, VECTOR, packed_float3, color, NULL) -OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXAniso, microfacet_multi_ggx_aniso) +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGX, microfacet_multi_ggx_aniso) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, VECTOR, packed_float3, T, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, FLOAT, float, alpha_y, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, VECTOR, packed_float3, color, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGX, microfacet_multi_ggx_aniso) -OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGXFresnel, microfacet_ggx_fresnel) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, VECTOR, packed_float3, N, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, FLOAT, float, alpha_x, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, FLOAT, float, ior, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, VECTOR, packed_float3, color, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, VECTOR, packed_float3, cspec0, NULL) -OSL_CLOSURE_STRUCT_END(MicrofacetGGXFresnel, microfacet_ggx_fresnel) - -OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGXAnisoFresnel, microfacet_ggx_aniso_fresnel) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, VECTOR, packed_float3, N, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, VECTOR, packed_float3, T, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, FLOAT, float, alpha_x, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, FLOAT, float, alpha_y, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, FLOAT, float, ior, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, VECTOR, packed_float3, color, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, VECTOR, packed_float3, cspec0, NULL) -OSL_CLOSURE_STRUCT_END(MicrofacetGGXAnisoFresnel, microfacet_ggx_aniso_fresnel) - -OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXFresnel, microfacet_multi_ggx_fresnel) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, VECTOR, packed_float3, N, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, FLOAT, float, alpha_x, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, FLOAT, float, ior, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, VECTOR, packed_float3, color, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, VECTOR, packed_float3, cspec0, NULL) -OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXFresnel, microfacet_multi_ggx_fresnel) - -OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXGlassFresnel, microfacet_multi_ggx_glass_fresnel) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, VECTOR, packed_float3, N, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, FLOAT, float, alpha_x, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, FLOAT, float, ior, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, VECTOR, packed_float3, color, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, VECTOR, packed_float3, cspec0, NULL) -OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXGlassFresnel, microfacet_multi_ggx_glass_fresnel) - -OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXAnisoFresnel, microfacet_multi_ggx_aniso_fresnel) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, VECTOR, packed_float3, N, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, VECTOR, packed_float3, T, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, FLOAT, float, alpha_x, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, FLOAT, float, alpha_y, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, FLOAT, float, ior, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, VECTOR, packed_float3, color, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, VECTOR, packed_float3, cspec0, NULL) -OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXAnisoFresnel, microfacet_multi_ggx_aniso_fresnel) - -OSL_CLOSURE_STRUCT_BEGIN(MicrofacetBeckmannIsotropic, microfacet_beckmann) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannIsotropic, VECTOR, packed_float3, N, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannIsotropic, FLOAT, float, alpha_x, NULL) -OSL_CLOSURE_STRUCT_END(MicrofacetBeckmannIsotropic, microfacet_beckmann) - -OSL_CLOSURE_STRUCT_BEGIN(MicrofacetBeckmann, microfacet_beckmann_aniso) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmann, VECTOR, packed_float3, N, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmann, VECTOR, packed_float3, T, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmann, FLOAT, float, alpha_x, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmann, FLOAT, float, alpha_y, NULL) -OSL_CLOSURE_STRUCT_END(MicrofacetBeckmann, microfacet_beckmann_aniso) - -OSL_CLOSURE_STRUCT_BEGIN(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannRefraction, VECTOR, packed_float3, N, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannRefraction, FLOAT, float, alpha_x, NULL) - OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannRefraction, FLOAT, float, ior, NULL) -OSL_CLOSURE_STRUCT_END(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction) - -OSL_CLOSURE_STRUCT_BEGIN(AshikhminShirley, ashikhmin_shirley) - OSL_CLOSURE_STRUCT_MEMBER(AshikhminShirley, VECTOR, packed_float3, N, NULL) - OSL_CLOSURE_STRUCT_MEMBER(AshikhminShirley, VECTOR, packed_float3, T, NULL) - OSL_CLOSURE_STRUCT_MEMBER(AshikhminShirley, FLOAT, float, alpha_x, NULL) - OSL_CLOSURE_STRUCT_MEMBER(AshikhminShirley, FLOAT, float, alpha_y, NULL) -OSL_CLOSURE_STRUCT_END(AshikhminShirley, ashikhmin_shirley) +OSL_CLOSURE_STRUCT_BEGIN(MicrofacetAnisoFresnel, microfacet_aniso_fresnel) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetAnisoFresnel, VECTOR, packed_float3, N, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetAnisoFresnel, VECTOR, packed_float3, T, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetAnisoFresnel, FLOAT, float, alpha_x, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetAnisoFresnel, FLOAT, float, alpha_y, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetAnisoFresnel, VECTOR, packed_float3, f0, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetAnisoFresnel, VECTOR, packed_float3, f90, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetAnisoFresnel, FLOAT, float, ior, NULL) + OSL_CLOSURE_STRUCT_MEMBER(MicrofacetAnisoFresnel, STRING, DeviceString, distribution, NULL) +OSL_CLOSURE_STRUCT_END(MicrofacetAnisoFresnel, microfacet_aniso_fresnel) OSL_CLOSURE_STRUCT_BEGIN(AshikhminVelvet, ashikhmin_velvet) OSL_CLOSURE_STRUCT_MEMBER(AshikhminVelvet, VECTOR, packed_float3, N, NULL) diff --git a/intern/cycles/kernel/osl/shaders/node_fresnel.h b/intern/cycles/kernel/osl/shaders/node_fresnel.h index 42b6ad42b05..cb047fbef92 100644 --- a/intern/cycles/kernel/osl/shaders/node_fresnel.h +++ b/intern/cycles/kernel/osl/shaders/node_fresnel.h @@ -36,3 +36,9 @@ color fresnel_conductor(float cosi, color eta, color k) color Rperp2 = (tmp_f - (2.0 * eta * cosi) + cosi2) / (tmp_f + (2.0 * eta * cosi) + cosi2); return (Rparl2 + Rperp2) * 0.5; } + +float F0_from_ior(float eta) +{ + float f0 = (eta - 1.0) / (eta + 1.0); + return f0 * f0; +} diff --git a/intern/cycles/kernel/osl/shaders/node_glossy_bsdf.osl b/intern/cycles/kernel/osl/shaders/node_glossy_bsdf.osl index 6bf5962e69d..074143e1d18 100644 --- a/intern/cycles/kernel/osl/shaders/node_glossy_bsdf.osl +++ b/intern/cycles/kernel/osl/shaders/node_glossy_bsdf.osl @@ -40,7 +40,7 @@ shader node_glossy_bsdf(color Color = 0.8, } if (distribution == "Multiscatter GGX") - BSDF = Color * microfacet_multi_ggx(Normal, roughness, Color); + BSDF = Color * microfacet_multi_ggx_aniso(Normal, T, roughness_u, roughness_v, Color); else BSDF = Color * microfacet(distribution, Normal, T, roughness_u, roughness_v, 0.0, 0); } diff --git a/intern/cycles/kernel/osl/shaders/node_principled_bsdf.osl b/intern/cycles/kernel/osl/shaders/node_principled_bsdf.osl index 2499f90bc03..03ffc1ef6a4 100644 --- a/intern/cycles/kernel/osl/shaders/node_principled_bsdf.osl +++ b/intern/cycles/kernel/osl/shaders/node_principled_bsdf.osl @@ -4,7 +4,7 @@ #include "node_fresnel.h" #include "stdcycles.h" -shader node_principled_bsdf(string distribution = "Multiscatter GGX", +shader node_principled_bsdf(string distribution = "multi_ggx", string subsurface_method = "random_walk", color BaseColor = color(0.8, 0.8, 0.8), float Subsurface = 0.0, @@ -34,6 +34,7 @@ shader node_principled_bsdf(string distribution = "Multiscatter GGX", float diffuse_weight = (1.0 - clamp(Metallic, 0.0, 1.0)) * (1.0 - clamp(Transmission, 0.0, 1.0)); float final_transmission = clamp(Transmission, 0.0, 1.0) * (1.0 - clamp(Metallic, 0.0, 1.0)); float specular_weight = (1.0 - final_transmission); + float r2 = Roughness * Roughness; vector T = Tangent; @@ -65,52 +66,35 @@ shader node_principled_bsdf(string distribution = "Multiscatter GGX", } if (Sheen > 1e-5) { - color sheen_color = color(1.0, 1.0, 1.0) * (1.0 - SheenTint) + m_ctint * SheenTint; + color sheen_color = mix(color(1.0), m_ctint, SheenTint); - BSDF = BSDF + sheen_color * Sheen * principled_sheen(Normal); + BSDF += sheen_color * Sheen * principled_sheen(Normal); } - BSDF = BSDF * diffuse_weight; + BSDF *= diffuse_weight; } if (specular_weight > 1e-5) { float aspect = sqrt(1.0 - Anisotropic * 0.9); - float r2 = Roughness * Roughness; - float alpha_x = r2 / aspect; float alpha_y = r2 * aspect; - color tmp_col = color(1.0, 1.0, 1.0) * (1.0 - SpecularTint) + m_ctint * SpecularTint; + color tmp_col = mix(color(1.0), m_ctint, SpecularTint); color Cspec0 = (Specular * 0.08 * tmp_col) * (1.0 - Metallic) + BaseColor * Metallic; - if (distribution == "GGX" || Roughness <= 0.075) { - BSDF = BSDF + specular_weight * - microfacet_ggx_aniso_fresnel(Normal, - T, - alpha_x, - alpha_y, - (2.0 / (1.0 - sqrt(0.08 * Specular))) - 1.0, - BaseColor, - Cspec0); - } - else { - BSDF = BSDF + specular_weight * microfacet_multi_ggx_aniso_fresnel( - Normal, - T, - alpha_x, - alpha_y, - (2.0 / (1.0 - sqrt(0.08 * Specular))) - 1.0, - BaseColor, - Cspec0); - } + float eta = (2.0 / (1.0 - sqrt(0.08 * Specular))) - 1.0; + + string spec_dist = (Roughness <= 0.075) ? "ggx" : distribution; + BSDF += specular_weight * microfacet_aniso_fresnel( + Normal, T, alpha_x, alpha_y, Cspec0, color(1.0), eta, spec_dist); } if (final_transmission > 1e-5) { - color Cspec0 = BaseColor * SpecularTint + color(1.0, 1.0, 1.0) * (1.0 - SpecularTint); + color Cspec0 = mix(color(1.0), BaseColor, SpecularTint); float eta = backfacing() ? 1.0 / f : f; - if (distribution == "GGX" || Roughness <= 5e-2) { + if (distribution == "ggx" || Roughness <= 5e-2) { float cosNI = dot(Normal, I); float Fr = fresnel_dielectric_cos(cosNI, eta); @@ -119,26 +103,23 @@ shader node_principled_bsdf(string distribution = "Multiscatter GGX", refl_roughness = 0.0; float transmission_roughness = refl_roughness; - if (distribution == "GGX") + if (distribution == "ggx") transmission_roughness = 1.0 - (1.0 - refl_roughness) * (1.0 - TransmissionRoughness); - BSDF = BSDF + - final_transmission * - (Fr * microfacet_ggx_fresnel( - Normal, refl_roughness * refl_roughness, eta, BaseColor, Cspec0) + - (1.0 - Fr) * BaseColor * - microfacet_ggx_refraction( - Normal, transmission_roughness * transmission_roughness, eta)); + closure color refraction = microfacet( + "ggx", Normal, transmission_roughness * transmission_roughness, eta, 1); + closure color reflection = microfacet_aniso_fresnel( + Normal, T, r2, r2, Cspec0, color(1.0), eta, "ggx"); + BSDF += final_transmission * mix(BaseColor * refraction, reflection, Fr); } else { - BSDF = BSDF + - final_transmission * microfacet_multi_ggx_glass_fresnel( - Normal, Roughness * Roughness, eta, BaseColor, Cspec0); + BSDF += final_transmission * + dielectric_bsdf(Normal, vector(0.0), Cspec0, BaseColor, r2, r2, eta, "multi_ggx"); } } if (Clearcoat > 1e-5) { - BSDF = BSDF + principled_clearcoat( - ClearcoatNormal, Clearcoat, ClearcoatRoughness * ClearcoatRoughness); + BSDF += principled_clearcoat( + ClearcoatNormal, Clearcoat, ClearcoatRoughness * ClearcoatRoughness); } } diff --git a/intern/cycles/kernel/osl/shaders/stdcycles.h b/intern/cycles/kernel/osl/shaders/stdcycles.h index 6fe0e5987fa..4ecee50548e 100644 --- a/intern/cycles/kernel/osl/shaders/stdcycles.h +++ b/intern/cycles/kernel/osl/shaders/stdcycles.h @@ -20,31 +20,21 @@ closure color diffuse_ramp(normal N, color colors[8]) BUILTIN; closure color phong_ramp(normal N, float exponent, color colors[8]) BUILTIN; closure color diffuse_toon(normal N, float size, float smooth) BUILTIN; closure color glossy_toon(normal N, float size, float smooth) BUILTIN; -closure color microfacet_ggx(normal N, float ag) BUILTIN; -closure color microfacet_ggx_aniso(normal N, vector T, float ax, float ay) BUILTIN; -closure color microfacet_ggx_refraction(normal N, float ag, float eta) BUILTIN; -closure color microfacet_multi_ggx(normal N, float ag, color C) BUILTIN; -closure color microfacet_multi_ggx_aniso(normal N, vector T, float ax, float ay, color C) BUILTIN; -closure color microfacet_multi_ggx_glass(normal N, float ag, float eta, color C) BUILTIN; -closure color microfacet_ggx_fresnel(normal N, float ag, float eta, color C, color Cspec0) BUILTIN; -closure color microfacet_ggx_aniso_fresnel( - normal N, vector T, float ax, float ay, float eta, color C, color Cspec0) BUILTIN; -closure color -microfacet_multi_ggx_fresnel(normal N, float ag, float eta, color C, color Cspec0) BUILTIN; -closure color microfacet_multi_ggx_aniso_fresnel( - normal N, vector T, float ax, float ay, float eta, color C, color Cspec0) BUILTIN; -closure color -microfacet_multi_ggx_glass_fresnel(normal N, float ag, float eta, color C, color Cspec0) BUILTIN; -closure color microfacet_beckmann(normal N, float ab) BUILTIN; -closure color microfacet_beckmann_aniso(normal N, vector T, float ax, float ay) BUILTIN; -closure color microfacet_beckmann_refraction(normal N, float ab, float eta) BUILTIN; -closure color ashikhmin_shirley(normal N, vector T, float ax, float ay) BUILTIN; closure color ashikhmin_velvet(normal N, float sigma) BUILTIN; closure color ambient_occlusion() BUILTIN; closure color principled_diffuse(normal N, float roughness) BUILTIN; closure color principled_sheen(normal N) BUILTIN; closure color principled_clearcoat(normal N, float clearcoat, float clearcoat_roughness) BUILTIN; +/* Needed to pass along the color for multiscattering saturation adjustment, + * otherwise could be replaced by microfacet() */ +closure color microfacet_multi_ggx_glass(normal N, float ag, float eta, color C) BUILTIN; +closure color microfacet_multi_ggx_aniso(normal N, vector T, float ax, float ay, color C) BUILTIN; +/* Needed to pass along the IOR for the Principled V1 Fresnel calculation, + * otherwise could be replaced by generalized_schlick_bsdf() */ +closure color microfacet_aniso_fresnel( + normal N, vector T, float ax, float ay, color f0, color f90, float eta, string dist) BUILTIN; + // BSSRDF closure color bssrdf(string method, normal N, vector radius, color albedo) BUILTIN; diff --git a/intern/cycles/kernel/svm/closure.h b/intern/cycles/kernel/svm/closure.h index 10e88f126a1..9b9c22acced 100644 --- a/intern/cycles/kernel/svm/closure.h +++ b/intern/cycles/kernel/svm/closure.h @@ -261,9 +261,9 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( sd, sizeof(MicrofacetBsdf), spec_weight); - ccl_private FresnelPrincipledV1 *fresnel = - (bsdf != NULL) ? (ccl_private FresnelPrincipledV1 *)closure_alloc_extra( - sd, sizeof(FresnelPrincipledV1)) : + ccl_private FresnelGeneralizedSchlick *fresnel = + (bsdf != NULL) ? (ccl_private FresnelGeneralizedSchlick *)closure_alloc_extra( + sd, sizeof(FresnelGeneralizedSchlick)) : NULL; if (bsdf && fresnel) { @@ -283,22 +283,17 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, one_float3(); // normalize lum. to isolate hue+sat float3 tmp_col = make_float3(1.0f - specular_tint) + m_ctint * specular_tint; - fresnel->cspec0 = rgb_to_spectrum((specular * 0.08f * tmp_col) * (1.0f - metallic) + - base_color * metallic); - fresnel->color = rgb_to_spectrum(base_color); + fresnel->f0 = rgb_to_spectrum((specular * 0.08f * tmp_col) * (1.0f - metallic) + + base_color * metallic); + fresnel->f90 = one_spectrum(); + fresnel->exponent = -1.0f; + fresnel->reflection_tint = one_spectrum(); + fresnel->transmission_tint = zero_spectrum(); /* setup bsdf */ - - /* Use single-scatter GGX. */ - if (distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID || roughness <= 0.075f) { - sd->flag |= bsdf_microfacet_ggx_setup(bsdf); - bsdf_microfacet_setup_fresnel_principledv1(bsdf, sd, fresnel); - } /* Use multi-scatter GGX. */ - else { - - bsdf->fresnel = fresnel; - sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd); - } + sd->flag |= bsdf_microfacet_ggx_setup(bsdf); + const bool is_multiggx = (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID); + bsdf_microfacet_setup_fresnel_generalized_schlick(kg, bsdf, sd, fresnel, is_multiggx); } } #ifdef __CAUSTICS_TRICKS__ @@ -313,7 +308,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, #endif if (final_transmission > CLOSURE_WEIGHT_CUTOFF) { Spectrum glass_weight = weight * final_transmission; - float3 cspec0 = base_color * specular_tint + make_float3(1.0f - specular_tint); + Spectrum cspec0 = base_color * specular_tint + make_float3(1.0f - specular_tint); /* Use single-scatter GGX. */ if (roughness <= 5e-2f || distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID) { @@ -327,15 +322,14 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, { ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( sd, sizeof(MicrofacetBsdf), glass_weight * fresnel); - ccl_private FresnelPrincipledV1 *fresnel = - (bsdf != NULL) ? (ccl_private FresnelPrincipledV1 *)closure_alloc_extra( - sd, sizeof(FresnelPrincipledV1)) : + ccl_private FresnelGeneralizedSchlick *fresnel = + (bsdf != NULL) ? (ccl_private FresnelGeneralizedSchlick *)closure_alloc_extra( + sd, sizeof(FresnelGeneralizedSchlick)) : NULL; if (bsdf && fresnel) { bsdf->N = valid_reflection_N; bsdf->T = zero_float3(); - bsdf->fresnel = fresnel; bsdf->alpha_x = refl_roughness * refl_roughness; bsdf->alpha_y = refl_roughness * refl_roughness; @@ -344,9 +338,13 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, /* setup bsdf */ sd->flag |= bsdf_microfacet_ggx_setup(bsdf); - fresnel->color = rgb_to_spectrum(base_color); - fresnel->cspec0 = rgb_to_spectrum(cspec0); - bsdf_microfacet_setup_fresnel_principledv1(bsdf, sd, fresnel); + fresnel->f0 = cspec0; + fresnel->f90 = one_spectrum(); + fresnel->exponent = -1.0f; + fresnel->reflection_tint = one_spectrum(); + fresnel->transmission_tint = zero_spectrum(); + + bsdf_microfacet_setup_fresnel_generalized_schlick(kg, bsdf, sd, fresnel, false); } } @@ -364,7 +362,6 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, if (bsdf) { bsdf->N = valid_reflection_N; bsdf->T = zero_float3(); - bsdf->fresnel = NULL; if (distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID) transmission_roughness = 1.0f - (1.0f - refl_roughness) * @@ -384,25 +381,28 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, else { ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( sd, sizeof(MicrofacetBsdf), glass_weight); - ccl_private FresnelPrincipledV1 *fresnel = - (bsdf != NULL) ? (ccl_private FresnelPrincipledV1 *)closure_alloc_extra( - sd, sizeof(FresnelPrincipledV1)) : + ccl_private FresnelGeneralizedSchlick *fresnel = + (bsdf != NULL) ? (ccl_private FresnelGeneralizedSchlick *)closure_alloc_extra( + sd, sizeof(FresnelGeneralizedSchlick)) : NULL; if (bsdf && fresnel) { bsdf->N = valid_reflection_N; - bsdf->fresnel = fresnel; bsdf->T = zero_float3(); bsdf->alpha_x = roughness * roughness; bsdf->alpha_y = roughness * roughness; bsdf->ior = ior; - fresnel->color = rgb_to_spectrum(base_color); - fresnel->cspec0 = rgb_to_spectrum(cspec0); + fresnel->f0 = make_spectrum(F0_from_ior(ior)); + fresnel->f90 = one_spectrum(); + fresnel->exponent = -1.0f; + fresnel->reflection_tint = cspec0; + fresnel->transmission_tint = base_color; /* setup bsdf */ - sd->flag |= bsdf_microfacet_multi_ggx_glass_fresnel_setup(bsdf, sd); + sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf); + bsdf_microfacet_setup_fresnel_generalized_schlick(kg, bsdf, sd, fresnel, true); } } } @@ -492,7 +492,6 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, bsdf->N = maybe_ensure_valid_specular_reflection(sd, N); bsdf->ior = 1.0f; - bsdf->fresnel = NULL; /* compute roughness */ float anisotropy = clamp(param2, -0.99f, 0.99f); @@ -525,20 +524,16 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, sd->flag |= bsdf_reflection_setup(bsdf); else if (type == CLOSURE_BSDF_MICROFACET_BECKMANN_ID) sd->flag |= bsdf_microfacet_beckmann_setup(bsdf); - else if (type == CLOSURE_BSDF_MICROFACET_GGX_ID) - sd->flag |= bsdf_microfacet_ggx_setup(bsdf); - else if (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID) { - kernel_assert(stack_valid(data_node.w)); - ccl_private FresnelConstant *fresnel = (ccl_private FresnelConstant *)closure_alloc_extra( - sd, sizeof(FresnelConstant)); - if (fresnel) { - bsdf->fresnel = fresnel; - fresnel->color = rgb_to_spectrum(stack_load_float3(stack, data_node.w)); - sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf); - } + else if (type == CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID) { + sd->flag |= bsdf_ashikhmin_shirley_setup(bsdf); } else { - sd->flag |= bsdf_ashikhmin_shirley_setup(bsdf); + sd->flag |= bsdf_microfacet_ggx_setup(bsdf); + if (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID) { + kernel_assert(stack_valid(data_node.w)); + const Spectrum color = rgb_to_spectrum(stack_load_float3(stack, data_node.w)); + bsdf_microfacet_setup_fresnel_constant(kg, bsdf, sd, color); + } } break; @@ -557,7 +552,6 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, if (bsdf) { bsdf->N = maybe_ensure_valid_specular_reflection(sd, N); bsdf->T = zero_float3(); - bsdf->fresnel = NULL; float eta = fmaxf(param2, 1e-5f); eta = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta; @@ -587,7 +581,8 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, } case CLOSURE_BSDF_SHARP_GLASS_ID: case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID: - case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: { + case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: + case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: { #ifdef __CAUSTICS_TRICKS__ if (!kernel_data.integrator.caustics_reflective && !kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) @@ -621,49 +616,19 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, if (type == CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID) sd->flag |= bsdf_microfacet_beckmann_glass_setup(bsdf); - else + else { sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf); + if (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID) { + kernel_assert(stack_valid(data_node.z)); + const Spectrum color = rgb_to_spectrum(stack_load_float3(stack, data_node.z)); + bsdf_microfacet_setup_fresnel_constant(kg, bsdf, sd, color); + } + } } } break; } - case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: { -#ifdef __CAUSTICS_TRICKS__ - if (!kernel_data.integrator.caustics_reflective && - !kernel_data.integrator.caustics_refractive && (path_flag & PATH_RAY_DIFFUSE)) - break; -#endif - Spectrum weight = sd->svm_closure_weight * mix_weight; - ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc( - sd, sizeof(MicrofacetBsdf), weight); - if (!bsdf) { - break; - } - - ccl_private FresnelConstant *fresnel = (ccl_private FresnelConstant *)closure_alloc_extra( - sd, sizeof(FresnelConstant)); - if (!fresnel) { - break; - } - - bsdf->N = maybe_ensure_valid_specular_reflection(sd, N); - bsdf->fresnel = fresnel; - bsdf->T = zero_float3(); - - float roughness = sqr(param1); - bsdf->alpha_x = roughness; - bsdf->alpha_y = roughness; - float eta = fmaxf(param2, 1e-5f); - bsdf->ior = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta; - - kernel_assert(stack_valid(data_node.z)); - fresnel->color = rgb_to_spectrum(stack_load_float3(stack, data_node.z)); - - /* setup bsdf */ - sd->flag |= bsdf_microfacet_multi_ggx_glass_setup(bsdf); - break; - } case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: { Spectrum weight = sd->svm_closure_weight * mix_weight; ccl_private VelvetBsdf *bsdf = (ccl_private VelvetBsdf *)bsdf_alloc( diff --git a/intern/cycles/kernel/svm/types.h b/intern/cycles/kernel/svm/types.h index b106cfed891..5cfd237ae23 100644 --- a/intern/cycles/kernel/svm/types.h +++ b/intern/cycles/kernel/svm/types.h @@ -423,7 +423,7 @@ typedef enum ClosureType { CLOSURE_BSDF_MICROFACET_GGX_ID, CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID, CLOSURE_BSDF_MICROFACET_BECKMANN_ID, - CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID, + CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID, /* virtual closure */ CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID, CLOSURE_BSDF_ASHIKHMIN_VELVET_ID, CLOSURE_BSDF_PHONG_RAMP_ID, @@ -437,7 +437,7 @@ typedef enum ClosureType { CLOSURE_BSDF_SHARP_GLASS_ID, CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID, CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID, - CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID, + CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID, /* virtual closure */ CLOSURE_BSDF_HAIR_PRINCIPLED_ID, CLOSURE_BSDF_HAIR_TRANSMISSION_ID, diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h index 14951e933fb..96185284198 100644 --- a/intern/cycles/kernel/types.h +++ b/intern/cycles/kernel/types.h @@ -1224,7 +1224,13 @@ typedef enum KernelBVHLayout { typedef struct KernelTables { int filter_table_offset; - int pad1, pad2, pad3; + int ggx_E; + int ggx_Eavg; + int ggx_glass_E; + int ggx_glass_Eavg; + int ggx_glass_inv_E; + int ggx_glass_inv_Eavg; + int pad1; } KernelTables; static_assert_align(KernelTables, 16); diff --git a/intern/cycles/kernel/util/lookup_table.h b/intern/cycles/kernel/util/lookup_table.h index 4db4dadab0e..aee0729c841 100644 --- a/intern/cycles/kernel/util/lookup_table.h +++ b/intern/cycles/kernel/util/lookup_table.h @@ -40,4 +40,21 @@ ccl_device float lookup_table_read_2D( return (1.0f - t) * data0 + t * data1; } +ccl_device float lookup_table_read_3D( + KernelGlobals kg, float x, float y, float z, int offset, int xsize, int ysize, int zsize) +{ + z = saturatef(z) * (zsize - 1); + + int index = min(float_to_int(z), zsize - 1); + int nindex = min(index + 1, zsize - 1); + float t = z - index; + + float data0 = lookup_table_read_2D(kg, x, y, offset + xsize * ysize * index, xsize, ysize); + if (t == 0.0f) + return data0; + + float data1 = lookup_table_read_2D(kg, x, y, offset + xsize * ysize * nindex, xsize, ysize); + return (1.0f - t) * data0 + t * data1; +} + CCL_NAMESPACE_END diff --git a/intern/cycles/scene/shader.cpp b/intern/cycles/scene/shader.cpp index 1a37d87513c..f9b7a6dff7c 100644 --- a/intern/cycles/scene/shader.cpp +++ b/intern/cycles/scene/shader.cpp @@ -29,6 +29,8 @@ namespace OCIO = OCIO_NAMESPACE; #endif +#include "scene/shader.tables" + CCL_NAMESPACE_BEGIN thread_mutex ShaderManager::lookup_table_mutex; @@ -564,6 +566,15 @@ void ShaderManager::device_update_common(Device * /*device*/, dscene->shaders.copy_to_device(); + /* lookup tables */ + KernelTables *ktables = &dscene->data.tables; + ktables->ggx_E = ensure_bsdf_table(dscene, scene, table_ggx_E); + ktables->ggx_Eavg = ensure_bsdf_table(dscene, scene, table_ggx_Eavg); + ktables->ggx_glass_E = ensure_bsdf_table(dscene, scene, table_ggx_glass_E); + ktables->ggx_glass_Eavg = ensure_bsdf_table(dscene, scene, table_ggx_glass_Eavg); + ktables->ggx_glass_inv_E = ensure_bsdf_table(dscene, scene, table_ggx_glass_inv_E); + ktables->ggx_glass_inv_Eavg = ensure_bsdf_table(dscene, scene, table_ggx_glass_inv_Eavg); + /* integrator */ KernelIntegrator *kintegrator = &dscene->data.integrator; kintegrator->use_volumes = has_volumes; @@ -583,8 +594,13 @@ void ShaderManager::device_update_common(Device * /*device*/, kfilm->is_rec709 = is_rec709; } -void ShaderManager::device_free_common(Device * /*device*/, DeviceScene *dscene, Scene * /*scene*/) +void ShaderManager::device_free_common(Device * /*device*/, DeviceScene *dscene, Scene *scene) { + for (auto &entry : bsdf_tables) { + scene->lookup_tables->remove_table(&entry.second); + } + bsdf_tables.clear(); + dscene->shaders.free(); } @@ -889,4 +905,17 @@ void ShaderManager::init_xyz_transforms() #endif } +size_t ShaderManager::ensure_bsdf_table_impl(DeviceScene *dscene, + Scene *scene, + const float *table, + size_t n) +{ + /* Since the BSDF tables are static arrays, we can use their address to identify them. */ + if (!(bsdf_tables.count(table))) { + vector entries(table, table + n); + bsdf_tables[table] = scene->lookup_tables->add_table(dscene, entries); + } + return bsdf_tables[table]; +} + CCL_NAMESPACE_END diff --git a/intern/cycles/scene/shader.h b/intern/cycles/scene/shader.h index fab09fcd9d3..d3dd53e736f 100644 --- a/intern/cycles/scene/shader.h +++ b/intern/cycles/scene/shader.h @@ -233,6 +233,15 @@ class ShaderManager { static thread_mutex lookup_table_mutex; + unordered_map bsdf_tables; + + template + size_t ensure_bsdf_table(DeviceScene *dscene, Scene *scene, const float (&table)[n]) + { + return ensure_bsdf_table_impl(dscene, scene, table, n); + } + size_t ensure_bsdf_table_impl(DeviceScene *dscene, Scene *scene, const float *table, size_t n); + uint get_graph_kernel_features(ShaderGraph *graph); thread_spin_lock attribute_lock_; diff --git a/intern/cycles/scene/shader.tables b/intern/cycles/scene/shader.tables new file mode 100644 index 00000000000..bbd4c5cae42 --- /dev/null +++ b/intern/cycles/scene/shader.tables @@ -0,0 +1,635 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + +/* Note: this file has a non-standard extension so it is skipped by clang-format. */ + +CCL_NAMESPACE_BEGIN + +/* Precomputed BSDF albedo tables for various microfacet distributions. */ + +static const float table_ggx_E[1024] = { + 1.000000f, 0.980405f, 0.994967f, 0.997749f, 0.998725f, 0.999173f, 0.999411f, 0.999550f, 0.999634f, 0.999686f, 0.999716f, 0.999732f, 0.999738f, 0.999735f, 0.999726f, 0.999712f, 0.999693f, 0.999671f, 0.999645f, 0.999615f, 0.999583f, 0.999548f, 0.999511f, 0.999471f, 0.999429f, 0.999385f, 0.999338f, 0.999290f, 0.999240f, 0.999188f, 0.999134f, 0.999079f, + 1.000000f, 0.999451f, 0.990086f, 0.954714f, 0.911203f, 0.891678f, 0.893893f, 0.905010f, 0.917411f, 0.928221f, 0.936755f, 0.943104f, 0.947567f, 0.950455f, 0.952036f, 0.952526f, 0.952096f, 0.950879f, 0.948983f, 0.946495f, 0.943484f, 0.940010f, 0.936122f, 0.931864f, 0.927272f, 0.922380f, 0.917217f, 0.911810f, 0.906184f, 0.900361f, 0.894361f, 0.888202f, + 1.000000f, 0.999866f, 0.997676f, 0.987331f, 0.962386f, 0.929174f, 0.902886f, 0.890270f, 0.888687f, 0.893114f, 0.899716f, 0.906297f, 0.911810f, 0.915853f, 0.918345f, 0.919348f, 0.918982f, 0.917380f, 0.914671f, 0.910973f, 0.906393f, 0.901026f, 0.894957f, 0.888261f, 0.881006f, 0.873254f, 0.865061f, 0.856478f, 0.847553f, 0.838329f, 0.828845f, 0.819138f, + 1.000000f, 0.999941f, 0.998997f, 0.994519f, 0.982075f, 0.959460f, 0.931758f, 0.907714f, 0.892271f, 0.885248f, 0.884058f, 0.885962f, 0.888923f, 0.891666f, 0.893488f, 0.894054f, 0.893246f, 0.891062f, 0.887565f, 0.882845f, 0.877003f, 0.870143f, 0.862365f, 0.853766f, 0.844436f, 0.834459f, 0.823915f, 0.812876f, 0.801410f, 0.789581f, 0.777445f, 0.765057f, + 1.000000f, 0.999967f, 0.999442f, 0.996987f, 0.989925f, 0.975437f, 0.953654f, 0.929078f, 0.907414f, 0.891877f, 0.882635f, 0.878166f, 0.876572f, 0.876236f, 0.876004f, 0.875144f, 0.873238f, 0.870080f, 0.865601f, 0.859812f, 0.852774f, 0.844571f, 0.835302f, 0.825069f, 0.813976f, 0.802123f, 0.789609f, 0.776523f, 0.762954f, 0.748982f, 0.734682f, 0.720122f, + 1.000000f, 0.999979f, 0.999644f, 0.998096f, 0.993618f, 0.983950f, 0.967765f, 0.946488f, 0.923989f, 0.904160f, 0.889039f, 0.878704f, 0.872099f, 0.867839f, 0.864665f, 0.861611f, 0.858015f, 0.853468f, 0.847745f, 0.840752f, 0.832480f, 0.822973f, 0.812312f, 0.800592f, 0.787922f, 0.774411f, 0.760171f, 0.745308f, 0.729926f, 0.714121f, 0.697985f, 0.681600f, + 1.000000f, 0.999985f, 0.999752f, 0.998684f, 0.995603f, 0.988803f, 0.976727f, 0.959272f, 0.938451f, 0.917446f, 0.898932f, 0.884154f, 0.873043f, 0.864773f, 0.858278f, 0.852565f, 0.846845f, 0.840555f, 0.833331f, 0.824969f, 0.815378f, 0.804550f, 0.792533f, 0.779405f, 0.765271f, 0.750246f, 0.734447f, 0.717996f, 0.701008f, 0.683595f, 0.665862f, 0.647905f, + 1.000000f, 0.999989f, 0.999816f, 0.999032f, 0.996781f, 0.991766f, 0.982561f, 0.968421f, 0.950089f, 0.929705f, 0.909775f, 0.892112f, 0.877428f, 0.865535f, 0.855737f, 0.847185f, 0.839084f, 0.830796f, 0.821858f, 0.811969f, 0.800961f, 0.788766f, 0.775391f, 0.760894f, 0.745367f, 0.728923f, 0.711685f, 0.693783f, 0.675344f, 0.656491f, 0.637343f, 0.618009f, + 1.000000f, 0.999991f, 0.999858f, 0.999255f, 0.997533f, 0.993686f, 0.986490f, 0.974988f, 0.959173f, 0.940264f, 0.920251f, 0.901030f, 0.883794f, 0.868900f, 0.856078f, 0.844728f, 0.834154f, 0.823720f, 0.812914f, 0.801368f, 0.788846f, 0.775227f, 0.760476f, 0.744623f, 0.727744f, 0.709946f, 0.691355f, 0.672105f, 0.652332f, 0.632172f, 0.611753f, 0.591195f, + 1.000000f, 0.999993f, 0.999886f, 0.999406f, 0.998040f, 0.994992f, 0.989227f, 0.979769f, 0.966203f, 0.949069f, 0.929766f, 0.909990f, 0.891126f, 0.873921f, 0.858498f, 0.844545f, 0.831539f, 0.818909f, 0.806146f, 0.792847f, 0.778733f, 0.763633f, 0.747476f, 0.730264f, 0.712056f, 0.692949f, 0.673066f, 0.652547f, 0.631533f, 0.610170f, 0.588596f, 0.566939f, + 1.000000f, 0.999995f, 0.999906f, 0.999513f, 0.998399f, 0.995917f, 0.991195f, 0.983312f, 0.971656f, 0.956303f, 0.938125f, 0.918488f, 0.898757f, 0.879901f, 0.862353f, 0.846089f, 0.830787f, 0.815992f, 0.801242f, 0.786135f, 0.770368f, 0.753741f, 0.736147f, 0.717566f, 0.698037f, 0.677649f, 0.656520f, 0.634791f, 0.612611f, 0.590130f, 0.567495f, 0.544843f, + 1.000000f, 0.999996f, 0.999921f, 0.999591f, 0.998661f, 0.996594f, 0.992650f, 0.985988f, 0.975917f, 0.962217f, 0.945336f, 0.926280f, 0.906266f, 0.886338f, 0.867144f, 0.848905f, 0.831508f, 0.814643f, 0.797929f, 0.780995f, 0.763540f, 0.745347f, 0.726289f, 0.706324f, 0.685477f, 0.663824f, 0.641483f, 0.618591f, 0.595303f, 0.571774f, 0.548156f, 0.524596f, + 1.000000f, 0.999996f, 0.999933f, 0.999651f, 0.998859f, 0.997104f, 0.993752f, 0.988046f, 0.979280f, 0.967055f, 0.951498f, 0.933282f, 0.913407f, 0.892888f, 0.872490f, 0.852624f, 0.833371f, 0.814578f, 0.795964f, 0.777219f, 0.758062f, 0.738279f, 0.717734f, 0.696371f, 0.674202f, 0.651296f, 0.627765f, 0.603747f, 0.579398f, 0.554878f, 0.530346f, 0.505951f, + 1.000000f, 0.999997f, 0.999941f, 0.999696f, 0.999012f, 0.997497f, 0.994604f, 0.989656f, 0.981964f, 0.971026f, 0.956742f, 0.939495f, 0.920052f, 0.899322f, 0.878109f, 0.856955f, 0.836102f, 0.815549f, 0.795133f, 0.774620f, 0.753771f, 0.732389f, 0.710341f, 0.687567f, 0.664071f, 0.639918f, 0.615213f, 0.590097f, 0.564725f, 0.539263f, 0.513871f, 0.488706f, + 1.000000f, 0.999997f, 0.999949f, 0.999733f, 0.999132f, 0.997806f, 0.995276f, 0.990935f, 0.984129f, 0.974304f, 0.961200f, 0.944967f, 0.926144f, 0.905496f, 0.883799f, 0.861667f, 0.839472f, 0.817348f, 0.795251f, 0.773035f, 0.750522f, 0.727545f, 0.703988f, 0.679793f, 0.654965f, 0.629565f, 0.603699f, 0.577506f, 0.551143f, 0.524778f, 0.498576f, 0.472695f, + 1.000000f, 0.999997f, 0.999954f, 0.999762f, 0.999228f, 0.998053f, 0.995814f, 0.991966f, 0.985893f, 0.977026f, 0.964995f, 0.949768f, 0.931677f, 0.911324f, 0.889415f, 0.866586f, 0.843295f, 0.819794f, 0.796153f, 0.772321f, 0.748187f, 0.723632f, 0.698566f, 0.672945f, 0.646780f, 0.620134f, 0.593114f, 0.565860f, 0.538532f, 0.511298f, 0.484328f, 0.457779f, + 1.000000f, 0.999998f, 0.999959f, 0.999786f, 0.999307f, 0.998254f, 0.996252f, 0.992808f, 0.987348f, 0.979302f, 0.968235f, 0.953973f, 0.936669f, 0.916763f, 0.894859f, 0.871576f, 0.847421f, 0.822737f, 0.797698f, 0.772347f, 0.746651f, 0.720547f, 0.693982f, 0.666934f, 0.639428f, 0.611535f, 0.583366f, 0.555065f, 0.526792f, 0.498719f, 0.471015f, 0.443841f, + 1.000000f, 0.999998f, 0.999962f, 0.999805f, 0.999371f, 0.998420f, 0.996612f, 0.993502f, 0.988557f, 0.981218f, 0.971011f, 0.957656f, 0.941156f, 0.921798f, 0.900070f, 0.876539f, 0.851730f, 0.826051f, 0.799763f, 0.773002f, 0.745814f, 0.718199f, 0.690150f, 0.661679f, 0.632832f, 0.603691f, 0.574377f, 0.545037f, 0.515837f, 0.486949f, 0.458544f, 0.430781f, + 1.000000f, 0.999998f, 0.999966f, 0.999822f, 0.999425f, 0.998558f, 0.996912f, 0.994082f, 0.989572f, 0.982843f, 0.973398f, 0.960884f, 0.945180f, 0.926433f, 0.905008f, 0.881402f, 0.856128f, 0.829631f, 0.802244f, 0.774186f, 0.745583f, 0.716504f, 0.686997f, 0.657112f, 0.626924f, 0.596535f, 0.566077f, 0.535706f, 0.505592f, 0.475910f, 0.446831f, 0.418514f, + 1.000000f, 0.999998f, 0.999968f, 0.999836f, 0.999471f, 0.998674f, 0.997165f, 0.994570f, 0.990430f, 0.984229f, 0.975460f, 0.963718f, 0.948785f, 0.930682f, 0.909656f, 0.886116f, 0.860541f, 0.833390f, 0.805050f, 0.775811f, 0.745878f, 0.715390f, 0.684454f, 0.653169f, 0.621644f, 0.590007f, 0.558407f, 0.527011f, 0.495995f, 0.465536f, 0.435808f, 0.406965f, + 1.000000f, 0.999999f, 0.999970f, 0.999848f, 0.999509f, 0.998773f, 0.997379f, 0.994985f, 0.991163f, 0.985419f, 0.977249f, 0.966213f, 0.952014f, 0.934568f, 0.914006f, 0.890646f, 0.864912f, 0.837258f, 0.808105f, 0.777803f, 0.746627f, 0.714789f, 0.682460f, 0.649794f, 0.616939f, 0.584055f, 0.551314f, 0.518896f, 0.486987f, 0.455768f, 0.425410f, 0.396069f, + 1.000000f, 0.999999f, 0.999973f, 0.999858f, 0.999542f, 0.998857f, 0.997562f, 0.995341f, 0.991792f, 0.986447f, 0.978809f, 0.968414f, 0.954908f, 0.938115f, 0.918063f, 0.894970f, 0.869199f, 0.841178f, 0.811344f, 0.780093f, 0.747765f, 0.714642f, 0.680962f, 0.646935f, 0.612760f, 0.578633f, 0.544751f, 0.511315f, 0.478520f, 0.446553f, 0.415586f, 0.385770f, + 1.000000f, 0.999999f, 0.999974f, 0.999867f, 0.999571f, 0.998930f, 0.997720f, 0.995648f, 0.992336f, 0.987340f, 0.980174f, 0.970361f, 0.957504f, 0.941351f, 0.921833f, 0.899078f, 0.873371f, 0.845104f, 0.814712f, 0.782625f, 0.749237f, 0.714896f, 0.679909f, 0.644547f, 0.609064f, 0.573697f, 0.538677f, 0.504225f, 0.470550f, 0.437846f, 0.406286f, 0.376017f, + 1.000000f, 0.999999f, 0.999976f, 0.999874f, 0.999596f, 0.998993f, 0.997858f, 0.995914f, 0.992810f, 0.988121f, 0.981374f, 0.972090f, 0.959837f, 0.944301f, 0.925331f, 0.902963f, 0.877406f, 0.848999f, 0.818163f, 0.785347f, 0.750991f, 0.715502f, 0.679256f, 0.642589f, 0.605812f, 0.569211f, 0.533054f, 0.497587f, 0.463038f, 0.429607f, 0.397469f, 0.366766f, + 1.000000f, 0.999999f, 0.999977f, 0.999881f, 0.999618f, 0.999049f, 0.997978f, 0.996147f, 0.993224f, 0.988806f, 0.982434f, 0.973628f, 0.961935f, 0.946991f, 0.928572f, 0.906628f, 0.881288f, 0.852834f, 0.821659f, 0.788217f, 0.752981f, 0.716417f, 0.678962f, 0.641022f, 0.602968f, 0.565141f, 0.527849f, 0.491370f, 0.455949f, 0.421800f, 0.389096f, 0.357977f, + 1.000000f, 0.999999f, 0.999978f, 0.999887f, 0.999637f, 0.999097f, 0.998083f, 0.996352f, 0.993588f, 0.989410f, 0.983373f, 0.975002f, 0.963827f, 0.949446f, 0.931571f, 0.910076f, 0.885009f, 0.856589f, 0.825169f, 0.791196f, 0.755170f, 0.717601f, 0.678991f, 0.639812f, 0.600501f, 0.561455f, 0.523031f, 0.485541f, 0.449253f, 0.414392f, 0.381135f, 0.349616f, + 1.000000f, 0.999999f, 0.999979f, 0.999892f, 0.999655f, 0.999141f, 0.998177f, 0.996533f, 0.993910f, 0.989945f, 0.984209f, 0.976232f, 0.965536f, 0.951688f, 0.934346f, 0.913314f, 0.888564f, 0.860245f, 0.828665f, 0.794253f, 0.757521f, 0.719020f, 0.679309f, 0.638927f, 0.598380f, 0.558126f, 0.518574f, 0.480074f, 0.442922f, 0.407354f, 0.373554f, 0.341651f, + 1.000000f, 0.999999f, 0.999980f, 0.999897f, 0.999669f, 0.999179f, 0.998260f, 0.996693f, 0.994197f, 0.990422f, 0.984956f, 0.977337f, 0.967083f, 0.953737f, 0.936913f, 0.916351f, 0.891951f, 0.863792f, 0.832128f, 0.797360f, 0.760004f, 0.720642f, 0.679885f, 0.638338f, 0.596578f, 0.555128f, 0.514452f, 0.474944f, 0.436929f, 0.400661f, 0.366328f, 0.334053f, + 1.000000f, 0.999999f, 0.999981f, 0.999901f, 0.999683f, 0.999213f, 0.998334f, 0.996836f, 0.994452f, 0.990848f, 0.985625f, 0.978332f, 0.968486f, 0.955612f, 0.939288f, 0.919197f, 0.895172f, 0.867221f, 0.835539f, 0.800494f, 0.762592f, 0.722438f, 0.680691f, 0.638020f, 0.595071f, 0.552438f, 0.510643f, 0.470129f, 0.431253f, 0.394289f, 0.359430f, 0.326796f, + 1.000000f, 0.999999f, 0.999982f, 0.999905f, 0.999695f, 0.999244f, 0.998400f, 0.996965f, 0.994681f, 0.991230f, 0.986227f, 0.979231f, 0.969761f, 0.957330f, 0.941486f, 0.921863f, 0.898229f, 0.870526f, 0.838887f, 0.803634f, 0.765260f, 0.724383f, 0.681702f, 0.637948f, 0.593837f, 0.550034f, 0.507126f, 0.465607f, 0.425873f, 0.388216f, 0.352839f, 0.319858f, + 1.000000f, 0.999999f, 0.999982f, 0.999908f, 0.999706f, 0.999271f, 0.998459f, 0.997080f, 0.994886f, 0.991574f, 0.986770f, 0.980045f, 0.970922f, 0.958906f, 0.943521f, 0.924358f, 0.901128f, 0.873705f, 0.842159f, 0.806765f, 0.767988f, 0.726453f, 0.682895f, 0.638100f, 0.592854f, 0.547896f, 0.503881f, 0.461361f, 0.420769f, 0.382424f, 0.346535f, 0.313216f, + 1.000000f, 0.999999f, 0.999983f, 0.999911f, 0.999716f, 0.999296f, 0.998513f, 0.997184f, 0.995072f, 0.991884f, 0.987261f, 0.980785f, 0.971982f, 0.960355f, 0.945407f, 0.926694f, 0.903873f, 0.876756f, 0.845349f, 0.809871f, 0.770757f, 0.728630f, 0.684249f, 0.638454f, 0.592102f, 0.546006f, 0.500893f, 0.457373f, 0.415925f, 0.376893f, 0.340499f, 0.306853f +}; + +static const float table_ggx_Eavg[32] = { + 1.000000f, 0.999992f, 0.999897f, 0.999548f, 0.998729f, 0.997199f, 0.994703f, 0.990986f, 0.985805f, 0.978930f, 0.970160f, 0.959321f, 0.946279f, 0.930937f, 0.913247f, 0.893209f, 0.870874f, 0.846345f, 0.819774f, 0.791360f, 0.761345f, 0.730001f, 0.697631f, 0.664547f, 0.631068f, 0.597509f, 0.564165f, 0.531311f, 0.499191f, 0.468013f, 0.437950f, 0.409137f +}; + +static const float table_ggx_glass_E[4096] = { + 0.999985f, 1.000000f, 0.999989f, 0.999990f, 1.000000f, 0.999999f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + + 1.000000f, 0.995405f, 0.998159f, 0.997352f, 0.995556f, 0.993264f, 0.990673f, 0.987859f, 0.984857f, 0.981686f, 0.978366f, 0.974910f, 0.971336f, 0.967655f, 0.963881f, 0.960025f, + 1.000000f, 0.999037f, 0.984373f, 0.951223f, 0.908812f, 0.850714f, 0.787824f, 0.732387f, 0.688038f, 0.653736f, 0.627288f, 0.606724f, 0.590534f, 0.577604f, 0.567136f, 0.558556f, + 1.000000f, 0.999790f, 0.996491f, 0.983048f, 0.954803f, 0.911598f, 0.857483f, 0.801146f, 0.750002f, 0.707130f, 0.672506f, 0.644881f, 0.622845f, 0.605146f, 0.590797f, 0.579049f, + 1.000000f, 0.999901f, 0.998395f, 0.991953f, 0.976043f, 0.947847f, 0.907820f, 0.860180f, 0.811070f, 0.765424f, 0.725673f, 0.692262f, 0.664642f, 0.641911f, 0.623184f, 0.607670f, + 1.000000f, 0.999943f, 0.999081f, 0.995375f, 0.985803f, 0.967476f, 0.939094f, 0.901894f, 0.859442f, 0.816061f, 0.775183f, 0.738672f, 0.707095f, 0.680251f, 0.657599f, 0.638515f, + 1.000000f, 0.999964f, 0.999418f, 0.997064f, 0.990881f, 0.978596f, 0.958507f, 0.930339f, 0.895632f, 0.857261f, 0.818368f, 0.781421f, 0.747848f, 0.718200f, 0.692449f, 0.670282f, + 1.000000f, 0.999976f, 0.999609f, 0.998028f, 0.993836f, 0.985334f, 0.970961f, 0.949851f, 0.922317f, 0.889899f, 0.854891f, 0.819635f, 0.785941f, 0.754930f, 0.727098f, 0.702515f, + 1.000000f, 0.999983f, 0.999729f, 0.998628f, 0.995695f, 0.989681f, 0.979281f, 0.963516f, 0.942069f, 0.915536f, 0.885302f, 0.853191f, 0.820962f, 0.790000f, 0.761205f, 0.735019f, + 1.000000f, 0.999988f, 0.999807f, 0.999027f, 0.996943f, 0.992630f, 0.985061f, 0.973329f, 0.956860f, 0.935671f, 0.910431f, 0.882327f, 0.852785f, 0.823168f, 0.794564f, 0.767691f, + 1.000000f, 0.999992f, 0.999862f, 0.999306f, 0.997815f, 0.994714f, 0.989218f, 0.980549f, 0.968095f, 0.951578f, 0.931158f, 0.907462f, 0.881472f, 0.854302f, 0.827016f, 0.800477f, + 1.000000f, 0.999994f, 0.999903f, 0.999508f, 0.998451f, 0.996240f, 0.992293f, 0.985990f, 0.976770f, 0.964243f, 0.948276f, 0.929081f, 0.907187f, 0.883360f, 0.858467f, 0.833340f, + 1.000000f, 0.999996f, 0.999933f, 0.999659f, 0.998925f, 0.997388f, 0.994627f, 0.990177f, 0.983575f, 0.974422f, 0.962463f, 0.947642f, 0.930135f, 0.910340f, 0.888830f, 0.866259f, + 1.000000f, 0.999997f, 0.999956f, 0.999775f, 0.999292f, 0.998273f, 0.996437f, 0.993456f, 0.988984f, 0.982691f, 0.974287f, 0.963598f, 0.950566f, 0.935300f, 0.918059f, 0.899216f, + 1.000000f, 0.999998f, 0.999974f, 0.999866f, 0.999577f, 0.998969f, 0.997868f, 0.996070f, 0.993349f, 0.989468f, 0.984197f, 0.977335f, 0.968739f, 0.958323f, 0.946109f, 0.932199f, + 1.000000f, 0.999999f, 0.999988f, 0.999938f, 0.999806f, 0.999525f, 0.999015f, 0.998179f, 0.996906f, 0.995072f, 0.992543f, 0.989188f, 0.984877f, 0.979492f, 0.972944f, 0.965165f, + 1.000000f, 1.000000f, 0.999999f, 0.999995f, 0.999985f, 0.999964f, 0.999925f, 0.999860f, 0.999762f, 0.999618f, 0.999419f, 0.999153f, 0.998802f, 0.998352f, 0.997801f, 0.997112f, + + 1.000000f, 0.995388f, 0.998717f, 0.998982f, 0.998625f, 0.997974f, 0.997140f, 0.996182f, 0.995130f, 0.993999f, 0.992798f, 0.991533f, 0.990206f, 0.988822f, 0.987383f, 0.985894f, + 1.000000f, 0.998651f, 0.978192f, 0.943710f, 0.926163f, 0.904416f, 0.868343f, 0.824688f, 0.781400f, 0.742589f, 0.709377f, 0.681460f, 0.658110f, 0.638518f, 0.622000f, 0.607981f, + 1.000000f, 0.999773f, 0.995969f, 0.981116f, 0.957538f, 0.930096f, 0.894925f, 0.851684f, 0.805599f, 0.761916f, 0.723411f, 0.690729f, 0.663465f, 0.640826f, 0.622007f, 0.606292f, + 1.000000f, 0.999911f, 0.998475f, 0.992107f, 0.977460f, 0.954862f, 0.924548f, 0.886566f, 0.843561f, 0.799865f, 0.759023f, 0.722868f, 0.691844f, 0.665632f, 0.643614f, 0.625119f, + 1.000000f, 0.999950f, 0.999175f, 0.995723f, 0.986844f, 0.970734f, 0.946942f, 0.915586f, 0.878129f, 0.837559f, 0.797224f, 0.759605f, 0.726013f, 0.696786f, 0.671701f, 0.650322f, + 1.000000f, 0.999968f, 0.999475f, 0.997315f, 0.991570f, 0.980337f, 0.962445f, 0.937545f, 0.906282f, 0.870486f, 0.832776f, 0.795698f, 0.761069f, 0.729848f, 0.702311f, 0.678351f, + 1.000000f, 0.999979f, 0.999643f, 0.998177f, 0.994255f, 0.986313f, 0.973041f, 0.953715f, 0.928347f, 0.897880f, 0.864109f, 0.829178f, 0.795033f, 0.763020f, 0.733880f, 0.707879f, + 1.000000f, 0.999985f, 0.999746f, 0.998712f, 0.995937f, 0.990229f, 0.980411f, 0.965602f, 0.945430f, 0.920208f, 0.890979f, 0.859337f, 0.826964f, 0.795377f, 0.765624f, 0.738299f, + 1.000000f, 0.999989f, 0.999817f, 0.999073f, 0.997075f, 0.992926f, 0.985659f, 0.974419f, 0.958652f, 0.938260f, 0.913723f, 0.886014f, 0.856456f, 0.826428f, 0.797093f, 0.769282f, + 1.000000f, 0.999991f, 0.999868f, 0.999329f, 0.997882f, 0.994860f, 0.989503f, 0.981072f, 0.968962f, 0.952856f, 0.932834f, 0.909386f, 0.883374f, 0.855884f, 0.828001f, 0.800646f, + 1.000000f, 0.999994f, 0.999905f, 0.999517f, 0.998476f, 0.996291f, 0.992395f, 0.986168f, 0.977075f, 0.964700f, 0.948872f, 0.929742f, 0.907742f, 0.883594f, 0.858150f, 0.832280f, + 1.000000f, 0.999996f, 0.999933f, 0.999660f, 0.998926f, 0.997385f, 0.994618f, 0.990151f, 0.983532f, 0.974353f, 0.962345f, 0.947409f, 0.929670f, 0.909496f, 0.887408f, 0.864093f, + 1.000000f, 0.999997f, 0.999955f, 0.999771f, 0.999277f, 0.998237f, 0.996357f, 0.993308f, 0.988723f, 0.982284f, 0.973688f, 0.962731f, 0.949336f, 0.933578f, 0.915681f, 0.896025f, + 1.000000f, 0.999998f, 0.999973f, 0.999859f, 0.999554f, 0.998910f, 0.997742f, 0.995841f, 0.992953f, 0.988845f, 0.983268f, 0.976012f, 0.966908f, 0.955859f, 0.942858f, 0.927996f, + 1.000000f, 0.999999f, 0.999986f, 0.999929f, 0.999774f, 0.999452f, 0.998859f, 0.997892f, 0.996414f, 0.994288f, 0.991361f, 0.987491f, 0.982523f, 0.976329f, 0.968792f, 0.959831f, + 1.000000f, 1.000000f, 0.999997f, 0.999982f, 0.999942f, 0.999857f, 0.999704f, 0.999448f, 0.999060f, 0.998493f, 0.997714f, 0.996670f, 0.995320f, 0.993613f, 0.991499f, 0.988921f, + + 1.000000f, 0.995365f, 0.998801f, 0.999276f, 0.999227f, 0.998963f, 0.998568f, 0.998082f, 0.997529f, 0.996923f, 0.996273f, 0.995583f, 0.994856f, 0.994093f, 0.993298f, 0.992470f, + 1.000000f, 0.998400f, 0.974244f, 0.935839f, 0.925457f, 0.920630f, 0.903983f, 0.875865f, 0.841964f, 0.807196f, 0.774375f, 0.744706f, 0.718426f, 0.695348f, 0.675129f, 0.657387f, + 1.000000f, 0.999729f, 0.995093f, 0.977435f, 0.953654f, 0.934130f, 0.912830f, 0.883507f, 0.847141f, 0.808095f, 0.770242f, 0.735737f, 0.705344f, 0.679048f, 0.656456f, 0.637080f, + 1.000000f, 0.999904f, 0.998303f, 0.991076f, 0.975623f, 0.955620f, 0.932714f, 0.904383f, 0.869703f, 0.831042f, 0.791868f, 0.754930f, 0.721663f, 0.692511f, 0.667329f, 0.645711f, + 1.000000f, 0.999950f, 0.999166f, 0.995545f, 0.986347f, 0.971067f, 0.950765f, 0.925206f, 0.893847f, 0.857809f, 0.819700f, 0.782222f, 0.747305f, 0.715920f, 0.688322f, 0.664353f, + 1.000000f, 0.999970f, 0.999497f, 0.997349f, 0.991580f, 0.980677f, 0.964385f, 0.942677f, 0.915420f, 0.883167f, 0.847684f, 0.811270f, 0.776018f, 0.743303f, 0.713816f, 0.687720f, + 1.000000f, 0.999979f, 0.999662f, 0.998244f, 0.994377f, 0.986622f, 0.974078f, 0.956417f, 0.933464f, 0.905495f, 0.873578f, 0.839486f, 0.805137f, 0.772120f, 0.741468f, 0.713698f, + 1.000000f, 0.999985f, 0.999760f, 0.998765f, 0.996051f, 0.990449f, 0.980961f, 0.966960f, 0.948125f, 0.924486f, 0.896610f, 0.865696f, 0.833324f, 0.801053f, 0.770094f, 0.741288f, + 1.000000f, 0.999989f, 0.999825f, 0.999106f, 0.997145f, 0.993050f, 0.985914f, 0.975021f, 0.959903f, 0.940392f, 0.916674f, 0.889467f, 0.859911f, 0.829349f, 0.799017f, 0.769914f, + 1.000000f, 0.999992f, 0.999871f, 0.999343f, 0.997913f, 0.994898f, 0.989563f, 0.981215f, 0.969336f, 0.953599f, 0.933946f, 0.910703f, 0.884586f, 0.856581f, 0.827793f, 0.799252f, + 1.000000f, 0.999994f, 0.999905f, 0.999520f, 0.998473f, 0.996269f, 0.992322f, 0.986046f, 0.976919f, 0.964556f, 0.948744f, 0.929525f, 0.907225f, 0.882483f, 0.856137f, 0.829089f, + 1.000000f, 0.999996f, 0.999932f, 0.999655f, 0.998905f, 0.997315f, 0.994456f, 0.989845f, 0.983045f, 0.973644f, 0.961379f, 0.946083f, 0.927839f, 0.906910f, 0.883827f, 0.859263f, + 1.000000f, 0.999997f, 0.999953f, 0.999760f, 0.999238f, 0.998136f, 0.996141f, 0.992892f, 0.988035f, 0.981227f, 0.972155f, 0.960609f, 0.946489f, 0.929771f, 0.910717f, 0.889658f, + 1.000000f, 0.999998f, 0.999970f, 0.999844f, 0.999505f, 0.998789f, 0.997485f, 0.995350f, 0.992123f, 0.987537f, 0.981342f, 0.973304f, 0.963244f, 0.951027f, 0.936610f, 0.920084f, + 1.000000f, 0.999999f, 0.999983f, 0.999911f, 0.999717f, 0.999310f, 0.998567f, 0.997335f, 0.995468f, 0.992786f, 0.989111f, 0.984278f, 0.978116f, 0.970461f, 0.961172f, 0.950156f, + 1.000000f, 1.000000f, 0.999992f, 0.999961f, 0.999873f, 0.999687f, 0.999348f, 0.998783f, 0.997916f, 0.996657f, 0.994936f, 0.992649f, 0.989728f, 0.986067f, 0.981571f, 0.976141f, + + 1.000000f, 0.995351f, 0.998825f, 0.999374f, 0.999438f, 0.999320f, 0.999098f, 0.998806f, 0.998460f, 0.998073f, 0.997651f, 0.997201f, 0.996723f, 0.996222f, 0.995696f, 0.995148f, + 1.000000f, 0.998247f, 0.971853f, 0.930499f, 0.922466f, 0.925445f, 0.919781f, 0.902821f, 0.877948f, 0.849240f, 0.819764f, 0.791363f, 0.764922f, 0.740764f, 0.718887f, 0.699161f, + 1.000000f, 0.999691f, 0.994374f, 0.974344f, 0.949194f, 0.933147f, 0.920047f, 0.900903f, 0.873664f, 0.840927f, 0.806286f, 0.772525f, 0.741186f, 0.712937f, 0.687847f, 0.665746f, + 1.000000f, 0.999891f, 0.998077f, 0.989841f, 0.972944f, 0.953646f, 0.935232f, 0.914098f, 0.886967f, 0.854149f, 0.818325f, 0.782378f, 0.748372f, 0.717379f, 0.689780f, 0.665505f, + 1.000000f, 0.999948f, 0.999095f, 0.995105f, 0.985120f, 0.969684f, 0.951429f, 0.930275f, 0.904363f, 0.873183f, 0.838235f, 0.801991f, 0.766711f, 0.733862f, 0.704162f, 0.677798f, + 1.000000f, 0.999969f, 0.999481f, 0.997211f, 0.991093f, 0.979948f, 0.964446f, 0.945167f, 0.921457f, 0.892837f, 0.860035f, 0.824915f, 0.789586f, 0.755768f, 0.724509f, 0.696306f, + 1.000000f, 0.999980f, 0.999662f, 0.998216f, 0.994213f, 0.986278f, 0.973997f, 0.957520f, 0.936668f, 0.911128f, 0.881257f, 0.848288f, 0.814019f, 0.780159f, 0.748034f, 0.718404f, + 1.000000f, 0.999986f, 0.999763f, 0.998768f, 0.996003f, 0.990290f, 0.980821f, 0.967303f, 0.949566f, 0.927380f, 0.900854f, 0.870765f, 0.838439f, 0.805471f, 0.773240f, 0.742756f, + 1.000000f, 0.999990f, 0.999828f, 0.999112f, 0.997132f, 0.992951f, 0.985733f, 0.974930f, 0.960250f, 0.941434f, 0.918449f, 0.891675f, 0.862029f, 0.830797f, 0.799266f, 0.768611f, + 1.000000f, 0.999992f, 0.999874f, 0.999345f, 0.997890f, 0.994798f, 0.989332f, 0.980869f, 0.969008f, 0.953434f, 0.933980f, 0.910769f, 0.884320f, 0.855554f, 0.825575f, 0.795502f, + 1.000000f, 0.999994f, 0.999906f, 0.999513f, 0.998440f, 0.996149f, 0.992040f, 0.985528f, 0.976163f, 0.963589f, 0.947551f, 0.927984f, 0.905085f, 0.879413f, 0.851774f, 0.823130f, + 1.000000f, 0.999996f, 0.999930f, 0.999641f, 0.998853f, 0.997173f, 0.994130f, 0.989225f, 0.982030f, 0.972164f, 0.959346f, 0.943372f, 0.924226f, 0.902133f, 0.877591f, 0.851276f, + 1.000000f, 0.999997f, 0.999949f, 0.999742f, 0.999176f, 0.997970f, 0.995769f, 0.992189f, 0.986844f, 0.979388f, 0.969535f, 0.957031f, 0.941711f, 0.923565f, 0.902781f, 0.879717f, + 1.000000f, 0.999998f, 0.999966f, 0.999823f, 0.999435f, 0.998604f, 0.997084f, 0.994588f, 0.990810f, 0.985469f, 0.978302f, 0.969050f, 0.957516f, 0.943553f, 0.927085f, 0.908201f, + 1.000000f, 0.999999f, 0.999977f, 0.999887f, 0.999639f, 0.999111f, 0.998133f, 0.996516f, 0.994047f, 0.990516f, 0.985714f, 0.979460f, 0.971538f, 0.961773f, 0.950012f, 0.936120f, + 1.000000f, 0.999999f, 0.999987f, 0.999932f, 0.999781f, 0.999458f, 0.998865f, 0.997872f, 0.996341f, 0.994130f, 0.991100f, 0.987136f, 0.982102f, 0.975874f, 0.968306f, 0.959261f, + + 1.000000f, 0.995343f, 0.998834f, 0.999417f, 0.999534f, 0.999486f, 0.999351f, 0.999156f, 0.998917f, 0.998643f, 0.998341f, 0.998014f, 0.997667f, 0.997300f, 0.996916f, 0.996514f, + 1.000000f, 0.998152f, 0.970350f, 0.926992f, 0.919810f, 0.926744f, 0.927339f, 0.917618f, 0.899592f, 0.876390f, 0.850767f, 0.824690f, 0.799364f, 0.775412f, 0.753093f, 0.732480f, + 1.000000f, 0.999662f, 0.993854f, 0.972077f, 0.945526f, 0.931029f, 0.922665f, 0.910276f, 0.890044f, 0.863129f, 0.832392f, 0.800590f, 0.769662f, 0.740698f, 0.714184f, 0.690214f, + 1.000000f, 0.999881f, 0.997877f, 0.988770f, 0.970473f, 0.951066f, 0.935189f, 0.918918f, 0.897606f, 0.870055f, 0.837934f, 0.803874f, 0.770140f, 0.738260f, 0.709006f, 0.682637f, + 1.000000f, 0.999944f, 0.999017f, 0.994627f, 0.983760f, 0.967743f, 0.950500f, 0.932327f, 0.910645f, 0.883712f, 0.852009f, 0.817534f, 0.782559f, 0.748862f, 0.717541f, 0.689106f, + 1.000000f, 0.999967f, 0.999451f, 0.997009f, 0.990405f, 0.978715f, 0.963443f, 0.945744f, 0.924775f, 0.899237f, 0.869030f, 0.835420f, 0.800394f, 0.765814f, 0.733053f, 0.702884f, + 1.000000f, 0.999979f, 0.999652f, 0.998128f, 0.993877f, 0.985555f, 0.973154f, 0.957354f, 0.938058f, 0.914542f, 0.886497f, 0.854660f, 0.820578f, 0.786015f, 0.752477f, 0.720993f, + 1.000000f, 0.999985f, 0.999760f, 0.998732f, 0.995835f, 0.989850f, 0.980146f, 0.966771f, 0.949739f, 0.928657f, 0.903252f, 0.873820f, 0.841491f, 0.807763f, 0.774164f, 0.741895f, + 1.000000f, 0.999990f, 0.999826f, 0.999093f, 0.997027f, 0.992657f, 0.985168f, 0.974212f, 0.959656f, 0.941256f, 0.918706f, 0.892130f, 0.862190f, 0.830060f, 0.797147f, 0.764696f, + 1.000000f, 0.999992f, 0.999870f, 0.999328f, 0.997815f, 0.994567f, 0.988825f, 0.980053f, 0.967938f, 0.952246f, 0.932681f, 0.909189f, 0.882118f, 0.852259f, 0.820769f, 0.788851f, + 1.000000f, 0.999994f, 0.999903f, 0.999496f, 0.998369f, 0.995932f, 0.991547f, 0.984629f, 0.974796f, 0.961723f, 0.945138f, 0.924851f, 0.900967f, 0.873946f, 0.844593f, 0.813961f, + 1.000000f, 0.999995f, 0.999928f, 0.999621f, 0.998775f, 0.996954f, 0.993626f, 0.988273f, 0.980454f, 0.969838f, 0.956104f, 0.939056f, 0.918565f, 0.894820f, 0.868295f, 0.839747f, + 1.000000f, 0.999997f, 0.999945f, 0.999718f, 0.999092f, 0.997740f, 0.995253f, 0.991184f, 0.985131f, 0.976743f, 0.965717f, 0.951804f, 0.934809f, 0.914653f, 0.891571f, 0.865936f, + 1.000000f, 0.999997f, 0.999960f, 0.999794f, 0.999339f, 0.998357f, 0.996540f, 0.993539f, 0.988990f, 0.982587f, 0.974059f, 0.963136f, 0.949594f, 0.933262f, 0.914088f, 0.892194f, + 1.000000f, 0.999998f, 0.999971f, 0.999855f, 0.999537f, 0.998843f, 0.997560f, 0.995425f, 0.992140f, 0.987444f, 0.981109f, 0.972937f, 0.962686f, 0.950191f, 0.935263f, 0.917776f, + 1.000000f, 0.999999f, 0.999980f, 0.999897f, 0.999669f, 0.999176f, 0.998257f, 0.996711f, 0.994312f, 0.990857f, 0.986147f, 0.980028f, 0.972349f, 0.962984f, 0.951747f, 0.938446f, + + 1.000000f, 0.995338f, 0.998838f, 0.999440f, 0.999586f, 0.999577f, 0.999490f, 0.999351f, 0.999175f, 0.998968f, 0.998736f, 0.998484f, 0.998214f, 0.997928f, 0.997626f, 0.997311f, + 1.000000f, 0.998092f, 0.969422f, 0.924749f, 0.917886f, 0.926986f, 0.931290f, 0.926250f, 0.913085f, 0.894264f, 0.872124f, 0.848514f, 0.824720f, 0.801539f, 0.779408f, 0.758534f, + 1.000000f, 0.999643f, 0.993497f, 0.970499f, 0.942854f, 0.929021f, 0.923442f, 0.915421f, 0.900249f, 0.878008f, 0.850911f, 0.821420f, 0.791524f, 0.762584f, 0.735343f, 0.710141f, + 1.000000f, 0.999872f, 0.997720f, 0.987944f, 0.968504f, 0.948723f, 0.934249f, 0.921133f, 0.903975f, 0.880621f, 0.851861f, 0.819891f, 0.786954f, 0.754774f, 0.724418f, 0.696424f, + 1.000000f, 0.999941f, 0.998942f, 0.994201f, 0.982545f, 0.965851f, 0.949003f, 0.932731f, 0.914054f, 0.890431f, 0.861560f, 0.828880f, 0.794502f, 0.760357f, 0.727794f, 0.697582f, + 1.000000f, 0.999966f, 0.999415f, 0.996792f, 0.989702f, 0.977385f, 0.961984f, 0.945192f, 0.926129f, 0.902953f, 0.874868f, 0.842631f, 0.807991f, 0.772842f, 0.738772f, 0.706761f, + 1.000000f, 0.999978f, 0.999635f, 0.998018f, 0.993472f, 0.984659f, 0.971907f, 0.956353f, 0.938049f, 0.915975f, 0.889331f, 0.858374f, 0.824386f, 0.789120f, 0.754188f, 0.720854f, + 1.000000f, 0.999985f, 0.999751f, 0.998669f, 0.995592f, 0.989245f, 0.979123f, 0.965596f, 0.948856f, 0.928433f, 0.903711f, 0.874633f, 0.842050f, 0.807429f, 0.772336f, 0.738157f, + 1.000000f, 0.999990f, 0.999820f, 0.999051f, 0.996866f, 0.992215f, 0.984304f, 0.972966f, 0.958226f, 0.939838f, 0.917349f, 0.890568f, 0.859995f, 0.826715f, 0.792153f, 0.757701f, + 1.000000f, 0.999992f, 0.999867f, 0.999298f, 0.997691f, 0.994215f, 0.988063f, 0.978772f, 0.966154f, 0.949994f, 0.929930f, 0.905745f, 0.877620f, 0.846305f, 0.812937f, 0.778847f, + 1.000000f, 0.999994f, 0.999899f, 0.999469f, 0.998258f, 0.995624f, 0.990838f, 0.983336f, 0.972760f, 0.958874f, 0.941336f, 0.919894f, 0.894559f, 0.865712f, 0.834213f, 0.801176f, + 1.000000f, 0.999995f, 0.999922f, 0.999592f, 0.998670f, 0.996654f, 0.992943f, 0.986954f, 0.978268f, 0.966560f, 0.951539f, 0.932919f, 0.910556f, 0.884624f, 0.855596f, 0.824331f, + 1.000000f, 0.999997f, 0.999939f, 0.999685f, 0.998980f, 0.997439f, 0.994566f, 0.989850f, 0.982832f, 0.973172f, 0.960564f, 0.944737f, 0.925481f, 0.902756f, 0.876764f, 0.848011f, + 1.000000f, 0.999997f, 0.999953f, 0.999760f, 0.999222f, 0.998042f, 0.995847f, 0.992171f, 0.986606f, 0.978789f, 0.968444f, 0.955311f, 0.939175f, 0.919856f, 0.897362f, 0.871839f, + 1.000000f, 0.999998f, 0.999965f, 0.999817f, 0.999412f, 0.998518f, 0.996844f, 0.994017f, 0.989671f, 0.983465f, 0.975149f, 0.964496f, 0.951323f, 0.935445f, 0.916701f, 0.895043f, + 1.000000f, 0.999998f, 0.999973f, 0.999857f, 0.999535f, 0.998835f, 0.997511f, 0.995268f, 0.991772f, 0.986725f, 0.979890f, 0.971099f, 0.960227f, 0.947129f, 0.931637f, 0.913594f, + + 1.000000f, 0.995335f, 0.998841f, 0.999454f, 0.999617f, 0.999633f, 0.999575f, 0.999472f, 0.999335f, 0.999171f, 0.998985f, 0.998781f, 0.998561f, 0.998327f, 0.998080f, 0.997821f, + 1.000000f, 0.998057f, 0.968893f, 0.923459f, 0.916722f, 0.927045f, 0.933608f, 0.931619f, 0.921879f, 0.906373f, 0.887096f, 0.865718f, 0.843494f, 0.821270f, 0.799603f, 0.778777f, + 1.000000f, 0.999630f, 0.993270f, 0.969511f, 0.941118f, 0.927569f, 0.923625f, 0.918415f, 0.906730f, 0.888060f, 0.863984f, 0.836655f, 0.807988f, 0.779413f, 0.751852f, 0.725815f, + 1.000000f, 0.999866f, 0.997609f, 0.987360f, 0.967111f, 0.946922f, 0.933184f, 0.922045f, 0.907742f, 0.887488f, 0.861456f, 0.831398f, 0.799368f, 0.767173f, 0.736051f, 0.706747f, + 1.000000f, 0.999936f, 0.998884f, 0.993871f, 0.981590f, 0.964266f, 0.947497f, 0.932325f, 0.915646f, 0.894410f, 0.867724f, 0.836543f, 0.802774f, 0.768338f, 0.734726f, 0.702937f, + 1.000000f, 0.999964f, 0.999381f, 0.996594f, 0.989068f, 0.976145f, 0.960438f, 0.944059f, 0.926151f, 0.904562f, 0.877990f, 0.846777f, 0.812393f, 0.776702f, 0.741371f, 0.707616f, + 1.000000f, 0.999977f, 0.999616f, 0.997896f, 0.993058f, 0.983726f, 0.970492f, 0.954856f, 0.937005f, 0.915755f, 0.889934f, 0.859457f, 0.825319f, 0.789215f, 0.752845f, 0.717588f, + 1.000000f, 0.999984f, 0.999738f, 0.998590f, 0.995306f, 0.988536f, 0.977873f, 0.963933f, 0.947112f, 0.926849f, 0.902275f, 0.873099f, 0.839926f, 0.804143f, 0.767380f, 0.731136f, + 1.000000f, 0.999989f, 0.999812f, 0.998996f, 0.996656f, 0.991651f, 0.983203f, 0.971253f, 0.956000f, 0.937219f, 0.914295f, 0.886837f, 0.855208f, 0.820400f, 0.783895f, 0.747196f, + 1.000000f, 0.999992f, 0.999859f, 0.999254f, 0.997520f, 0.993744f, 0.987064f, 0.977043f, 0.963617f, 0.946599f, 0.925582f, 0.900200f, 0.870532f, 0.837295f, 0.801669f, 0.765094f, + 1.000000f, 0.999994f, 0.999891f, 0.999426f, 0.998108f, 0.995200f, 0.989896f, 0.981609f, 0.970024f, 0.954912f, 0.935970f, 0.912863f, 0.885512f, 0.854314f, 0.820197f, 0.784360f, + 1.000000f, 0.999995f, 0.999914f, 0.999553f, 0.998523f, 0.996252f, 0.992040f, 0.985224f, 0.975379f, 0.962194f, 0.945386f, 0.924662f, 0.899836f, 0.871115f, 0.839063f, 0.804620f, + 1.000000f, 0.999997f, 0.999931f, 0.999645f, 0.998833f, 0.997041f, 0.993672f, 0.988105f, 0.979841f, 0.968489f, 0.953793f, 0.935483f, 0.913352f, 0.887395f, 0.857937f, 0.825571f, + 1.000000f, 0.999996f, 0.999946f, 0.999716f, 0.999075f, 0.997647f, 0.994947f, 0.990417f, 0.983533f, 0.973887f, 0.961201f, 0.945264f, 0.925853f, 0.902884f, 0.876431f, 0.846788f, + 1.000000f, 0.999997f, 0.999957f, 0.999772f, 0.999256f, 0.998115f, 0.995939f, 0.992236f, 0.986522f, 0.978386f, 0.967529f, 0.953795f, 0.937007f, 0.917074f, 0.893916f, 0.867565f, + 1.000000f, 0.999998f, 0.999963f, 0.999808f, 0.999376f, 0.998420f, 0.996599f, 0.993479f, 0.988597f, 0.981542f, 0.972038f, 0.959955f, 0.945226f, 0.927773f, 0.907511f, 0.884305f, + + 1.000000f, 0.995335f, 0.998844f, 0.999465f, 0.999639f, 0.999669f, 0.999632f, 0.999552f, 0.999442f, 0.999308f, 0.999153f, 0.998983f, 0.998797f, 0.998600f, 0.998390f, 0.998171f, + 1.000000f, 0.998044f, 0.968696f, 0.922973f, 0.916296f, 0.927294f, 0.935224f, 0.935229f, 0.927867f, 0.914821f, 0.897813f, 0.878318f, 0.857513f, 0.836257f, 0.815119f, 0.794485f, + 1.000000f, 0.999624f, 0.993156f, 0.969020f, 0.940235f, 0.926824f, 0.923789f, 0.920324f, 0.911013f, 0.894903f, 0.873185f, 0.847683f, 0.820176f, 0.792074f, 0.764380f, 0.737725f, + 1.000000f, 0.999862f, 0.997543f, 0.987009f, 0.966250f, 0.945776f, 0.932390f, 0.922391f, 0.909912f, 0.891815f, 0.867819f, 0.839273f, 0.808062f, 0.775915f, 0.744179f, 0.713729f, + 1.000000f, 0.999934f, 0.998840f, 0.993630f, 0.980895f, 0.963078f, 0.946202f, 0.931596f, 0.916075f, 0.896373f, 0.871175f, 0.841070f, 0.807718f, 0.772954f, 0.738364f, 0.705076f, + 1.000000f, 0.999963f, 0.999351f, 0.996429f, 0.988543f, 0.975067f, 0.958965f, 0.942618f, 0.925261f, 0.904521f, 0.878830f, 0.848156f, 0.813742f, 0.777356f, 0.740733f, 0.705209f, + 1.000000f, 0.999976f, 0.999593f, 0.997779f, 0.992648f, 0.982804f, 0.969002f, 0.953011f, 0.935135f, 0.914113f, 0.888522f, 0.857980f, 0.823355f, 0.786161f, 0.748188f, 0.710935f, + 1.000000f, 0.999983f, 0.999725f, 0.998500f, 0.994983f, 0.987753f, 0.976443f, 0.961866f, 0.944536f, 0.923912f, 0.898955f, 0.869139f, 0.834944f, 0.797666f, 0.758979f, 0.720489f, + 1.000000f, 0.999988f, 0.999800f, 0.998925f, 0.996398f, 0.990976f, 0.981847f, 0.969068f, 0.952950f, 0.933279f, 0.909384f, 0.880743f, 0.847536f, 0.810789f, 0.772008f, 0.732801f, + 1.000000f, 0.999991f, 0.999848f, 0.999191f, 0.997295f, 0.993140f, 0.985784f, 0.974812f, 0.960228f, 0.941901f, 0.919390f, 0.892251f, 0.860487f, 0.824834f, 0.786546f, 0.747163f, + 1.000000f, 0.999993f, 0.999881f, 0.999369f, 0.997902f, 0.994643f, 0.988678f, 0.979359f, 0.966399f, 0.949633f, 0.928731f, 0.903335f, 0.873372f, 0.839281f, 0.802053f, 0.763068f, + 1.000000f, 0.999994f, 0.999905f, 0.999496f, 0.998329f, 0.995725f, 0.990852f, 0.982969f, 0.971599f, 0.956461f, 0.937293f, 0.913808f, 0.885894f, 0.853766f, 0.818146f, 0.780156f, + 1.000000f, 0.999996f, 0.999921f, 0.999590f, 0.998646f, 0.996528f, 0.992521f, 0.985848f, 0.975946f, 0.962425f, 0.945039f, 0.923544f, 0.897845f, 0.868008f, 0.834488f, 0.798085f, + 1.000000f, 0.999996f, 0.999934f, 0.999659f, 0.998882f, 0.997141f, 0.993801f, 0.988155f, 0.979569f, 0.967566f, 0.951911f, 0.932421f, 0.909015f, 0.881690f, 0.850699f, 0.816519f, + 1.000000f, 0.999996f, 0.999945f, 0.999714f, 0.999066f, 0.997605f, 0.994799f, 0.989987f, 0.982516f, 0.971896f, 0.957849f, 0.940259f, 0.919094f, 0.894392f, 0.866221f, 0.834798f, + 1.000000f, 0.999997f, 0.999952f, 0.999750f, 0.999181f, 0.997914f, 0.995465f, 0.991237f, 0.984588f, 0.974987f, 0.962151f, 0.946012f, 0.926653f, 0.904147f, 0.878556f, 0.849884f, + + 1.000000f, 0.995337f, 0.998849f, 0.999474f, 0.999655f, 0.999697f, 0.999673f, 0.999609f, 0.999518f, 0.999405f, 0.999274f, 0.999128f, 0.998968f, 0.998797f, 0.998615f, 0.998423f, + 1.000000f, 0.998052f, 0.968822f, 0.923265f, 0.916662f, 0.927944f, 0.936637f, 0.937891f, 0.932151f, 0.920891f, 0.905625f, 0.887660f, 0.868061f, 0.847666f, 0.827052f, 0.806635f, + 1.000000f, 0.999623f, 0.993153f, 0.969006f, 0.940211f, 0.926863f, 0.924254f, 0.921762f, 0.913922f, 0.899581f, 0.879602f, 0.855532f, 0.828968f, 0.801287f, 0.773504f, 0.746324f, + 1.000000f, 0.999860f, 0.997516f, 0.986877f, 0.965924f, 0.945296f, 0.932018f, 0.922554f, 0.911097f, 0.894339f, 0.871706f, 0.844219f, 0.813562f, 0.781384f, 0.749046f, 0.717517f, + 1.000000f, 0.999932f, 0.998811f, 0.993481f, 0.980459f, 0.962295f, 0.945210f, 0.930718f, 0.915703f, 0.896784f, 0.872406f, 0.842881f, 0.809626f, 0.774388f, 0.738759f, 0.703967f, + 1.000000f, 0.999962f, 0.999327f, 0.996291f, 0.988107f, 0.974159f, 0.957580f, 0.940962f, 0.923592f, 0.903062f, 0.877585f, 0.846930f, 0.812107f, 0.774804f, 0.736746f, 0.699373f, + 1.000000f, 0.999975f, 0.999571f, 0.997657f, 0.992255f, 0.981883f, 0.967421f, 0.950799f, 0.932444f, 0.911052f, 0.885074f, 0.853957f, 0.818370f, 0.779796f, 0.740007f, 0.700593f, + 1.000000f, 0.999982f, 0.999706f, 0.998397f, 0.994632f, 0.986872f, 0.974779f, 0.959300f, 0.941070f, 0.919535f, 0.893583f, 0.862567f, 0.826849f, 0.787697f, 0.746802f, 0.705863f, + 1.000000f, 0.999987f, 0.999782f, 0.998834f, 0.996072f, 0.990154f, 0.980185f, 0.966294f, 0.948893f, 0.927835f, 0.902369f, 0.871911f, 0.836607f, 0.797476f, 0.756062f, 0.714084f, + 1.000000f, 0.999990f, 0.999833f, 0.999109f, 0.997003f, 0.992369f, 0.984152f, 0.971915f, 0.955755f, 0.935592f, 0.910961f, 0.881426f, 0.846974f, 0.808391f, 0.767037f, 0.724539f, + 1.000000f, 0.999992f, 0.999867f, 0.999292f, 0.997631f, 0.993915f, 0.987083f, 0.976413f, 0.961637f, 0.942644f, 0.919132f, 0.890789f, 0.857552f, 0.819982f, 0.779213f, 0.736731f, + 1.000000f, 0.999994f, 0.999891f, 0.999423f, 0.998071f, 0.995029f, 0.989302f, 0.980012f, 0.966642f, 0.948946f, 0.926737f, 0.899769f, 0.868025f, 0.831862f, 0.792195f, 0.750277f, + 1.000000f, 0.999995f, 0.999908f, 0.999518f, 0.998395f, 0.995854f, 0.990995f, 0.982894f, 0.970873f, 0.954534f, 0.933692f, 0.908243f, 0.878166f, 0.843771f, 0.805670f, 0.764892f, + 1.000000f, 0.999996f, 0.999922f, 0.999589f, 0.998635f, 0.996480f, 0.992312f, 0.985223f, 0.974419f, 0.959410f, 0.939975f, 0.916084f, 0.887813f, 0.855398f, 0.819314f, 0.780252f, + 1.000000f, 0.999996f, 0.999932f, 0.999642f, 0.998819f, 0.996953f, 0.993329f, 0.987079f, 0.977358f, 0.963575f, 0.945473f, 0.923115f, 0.896667f, 0.866416f, 0.832654f, 0.795872f, + 1.000000f, 0.999996f, 0.999938f, 0.999679f, 0.998940f, 0.997276f, 0.994034f, 0.988387f, 0.979485f, 0.966655f, 0.949608f, 0.928453f, 0.903518f, 0.875176f, 0.843709f, 0.809330f, + + 1.000000f, 0.995343f, 0.998855f, 0.999483f, 0.999669f, 0.999718f, 0.999704f, 0.999652f, 0.999575f, 0.999478f, 0.999364f, 0.999236f, 0.999096f, 0.998945f, 0.998784f, 0.998615f, + 1.000000f, 0.998083f, 0.969303f, 0.924430f, 0.917931f, 0.929179f, 0.938138f, 0.940083f, 0.935376f, 0.925368f, 0.911393f, 0.894614f, 0.875999f, 0.856324f, 0.836157f, 0.815926f, + 1.000000f, 0.999629f, 0.993257f, 0.969480f, 0.941061f, 0.927776f, 0.925202f, 0.923072f, 0.915997f, 0.902730f, 0.883901f, 0.860843f, 0.834978f, 0.807577f, 0.779658f, 0.751951f, + 1.000000f, 0.999861f, 0.997527f, 0.986952f, 0.966093f, 0.945483f, 0.932121f, 0.922708f, 0.911589f, 0.895462f, 0.873549f, 0.846656f, 0.816239f, 0.783848f, 0.750829f, 0.718183f, + 1.000000f, 0.999931f, 0.998797f, 0.993409f, 0.980244f, 0.961841f, 0.944467f, 0.929718f, 0.914624f, 0.895827f, 0.871621f, 0.842148f, 0.808628f, 0.772679f, 0.735883f, 0.699500f, + 1.000000f, 0.999960f, 0.999304f, 0.996172f, 0.987729f, 0.973327f, 0.956177f, 0.938978f, 0.921091f, 0.900152f, 0.874277f, 0.843070f, 0.807425f, 0.768903f, 0.729218f, 0.689856f, + 1.000000f, 0.999973f, 0.999548f, 0.997531f, 0.991825f, 0.980882f, 0.965598f, 0.948047f, 0.928751f, 0.906409f, 0.879409f, 0.847132f, 0.810118f, 0.769800f, 0.727940f, 0.686197f, + 1.000000f, 0.999981f, 0.999682f, 0.998272f, 0.994204f, 0.985815f, 0.972740f, 0.956015f, 0.936399f, 0.913386f, 0.885808f, 0.852995f, 0.815241f, 0.773789f, 0.730378f, 0.686765f, + 1.000000f, 0.999986f, 0.999761f, 0.998716f, 0.995668f, 0.989101f, 0.978044f, 0.962666f, 0.943491f, 0.920413f, 0.892719f, 0.859812f, 0.821845f, 0.779846f, 0.735462f, 0.690470f, + 1.000000f, 0.999989f, 0.999813f, 0.998997f, 0.996616f, 0.991347f, 0.981992f, 0.968097f, 0.949806f, 0.927145f, 0.899708f, 0.867065f, 0.829307f, 0.787277f, 0.742452f, 0.696583f, + 1.000000f, 0.999991f, 0.999849f, 0.999187f, 0.997264f, 0.992935f, 0.984960f, 0.972503f, 0.955315f, 0.933385f, 0.906506f, 0.874432f, 0.837230f, 0.795607f, 0.750846f, 0.704615f, + 1.000000f, 0.999993f, 0.999872f, 0.999321f, 0.997721f, 0.994091f, 0.987221f, 0.976077f, 0.960090f, 0.939078f, 0.912949f, 0.881662f, 0.845301f, 0.804470f, 0.760276f, 0.714188f, + 1.000000f, 0.999994f, 0.999890f, 0.999419f, 0.998059f, 0.994951f, 0.988977f, 0.978987f, 0.964177f, 0.944209f, 0.918995f, 0.888621f, 0.853316f, 0.813628f, 0.770455f, 0.725040f, + 1.000000f, 0.999994f, 0.999903f, 0.999492f, 0.998310f, 0.995607f, 0.990346f, 0.981362f, 0.967689f, 0.948783f, 0.924566f, 0.895218f, 0.861122f, 0.822828f, 0.781114f, 0.736951f, + 1.000000f, 0.999995f, 0.999914f, 0.999549f, 0.998501f, 0.996109f, 0.991426f, 0.983297f, 0.970650f, 0.952799f, 0.929588f, 0.901313f, 0.868512f, 0.831837f, 0.791942f, 0.749584f, + 1.000000f, 0.999995f, 0.999921f, 0.999587f, 0.998635f, 0.996461f, 0.992195f, 0.984724f, 0.972915f, 0.955941f, 0.933578f, 0.906196f, 0.874554f, 0.839421f, 0.801478f, 0.761256f, + + 1.000000f, 0.995353f, 0.998865f, 0.999494f, 0.999683f, 0.999736f, 0.999729f, 0.999686f, 0.999620f, 0.999535f, 0.999435f, 0.999322f, 0.999197f, 0.999062f, 0.998918f, 0.998766f, + 1.000000f, 0.998142f, 0.970240f, 0.926708f, 0.920346f, 0.931220f, 0.939975f, 0.942092f, 0.937929f, 0.928707f, 0.915627f, 0.899725f, 0.881865f, 0.862749f, 0.842926f, 0.822811f, + 1.000000f, 0.999640f, 0.993481f, 0.970495f, 0.942871f, 0.929672f, 0.926767f, 0.924403f, 0.917472f, 0.904673f, 0.886466f, 0.863995f, 0.838527f, 0.811225f, 0.783058f, 0.754755f, + 1.000000f, 0.999864f, 0.997569f, 0.987205f, 0.966716f, 0.946238f, 0.932608f, 0.922795f, 0.911423f, 0.895275f, 0.873498f, 0.846701f, 0.816172f, 0.783347f, 0.749489f, 0.715648f, + 1.000000f, 0.999930f, 0.998788f, 0.993377f, 0.980152f, 0.961536f, 0.943727f, 0.928369f, 0.912666f, 0.893344f, 0.868722f, 0.838781f, 0.804584f, 0.767636f, 0.729484f, 0.691397f, + 1.000000f, 0.999959f, 0.999279f, 0.996040f, 0.987304f, 0.972370f, 0.954439f, 0.936304f, 0.917405f, 0.895435f, 0.868538f, 0.836248f, 0.799330f, 0.759260f, 0.717727f, 0.676233f, + 1.000000f, 0.999971f, 0.999519f, 0.997370f, 0.991285f, 0.979590f, 0.963201f, 0.944311f, 0.923528f, 0.899607f, 0.870990f, 0.836968f, 0.798051f, 0.755634f, 0.711449f, 0.667187f, + 1.000000f, 0.999979f, 0.999652f, 0.998105f, 0.993635f, 0.984397f, 0.969980f, 0.951526f, 0.929938f, 0.904772f, 0.874915f, 0.839670f, 0.799368f, 0.755217f, 0.709017f, 0.662536f, + 1.000000f, 0.999984f, 0.999732f, 0.998553f, 0.995112f, 0.987668f, 0.975125f, 0.957697f, 0.936069f, 0.910260f, 0.879610f, 0.843577f, 0.802361f, 0.757048f, 0.709369f, 0.661181f, + 1.000000f, 0.999987f, 0.999785f, 0.998842f, 0.996080f, 0.989949f, 0.979048f, 0.962879f, 0.941712f, 0.915732f, 0.884654f, 0.848162f, 0.806442f, 0.760467f, 0.711831f, 0.662405f, + 1.000000f, 0.999989f, 0.999821f, 0.999038f, 0.996754f, 0.991590f, 0.982053f, 0.967179f, 0.946783f, 0.920992f, 0.889804f, 0.853131f, 0.811229f, 0.764994f, 0.715888f, 0.665713f, + 1.000000f, 0.999991f, 0.999847f, 0.999181f, 0.997236f, 0.992805f, 0.984396f, 0.970756f, 0.951286f, 0.925956f, 0.894889f, 0.858256f, 0.816447f, 0.770312f, 0.721200f, 0.670770f, + 1.000000f, 0.999992f, 0.999864f, 0.999283f, 0.997594f, 0.993722f, 0.986241f, 0.973735f, 0.955274f, 0.930582f, 0.899822f, 0.863404f, 0.821902f, 0.776188f, 0.727504f, 0.677325f, + 1.000000f, 0.999993f, 0.999880f, 0.999363f, 0.997868f, 0.994431f, 0.987713f, 0.976227f, 0.958784f, 0.934853f, 0.904567f, 0.868500f, 0.827467f, 0.782451f, 0.734612f, 0.685220f, + 1.000000f, 0.999994f, 0.999891f, 0.999425f, 0.998078f, 0.994987f, 0.988897f, 0.978306f, 0.961859f, 0.938761f, 0.909049f, 0.873455f, 0.833026f, 0.788954f, 0.742359f, 0.694317f, + 1.000000f, 0.999994f, 0.999899f, 0.999469f, 0.998230f, 0.995395f, 0.989794f, 0.979946f, 0.964372f, 0.942073f, 0.912956f, 0.877817f, 0.838022f, 0.794995f, 0.749934f, 0.703736f, + + 1.000000f, 0.995372f, 0.998882f, 0.999509f, 0.999698f, 0.999754f, 0.999751f, 0.999715f, 0.999657f, 0.999581f, 0.999491f, 0.999390f, 0.999278f, 0.999156f, 0.999026f, 0.998888f, + 1.000000f, 0.998242f, 0.971833f, 0.930547f, 0.924331f, 0.934324f, 0.942304f, 0.944064f, 0.939950f, 0.931093f, 0.918552f, 0.903232f, 0.885894f, 0.867167f, 0.847559f, 0.827465f, + 1.000000f, 0.999659f, 0.993827f, 0.972071f, 0.945685f, 0.932510f, 0.928824f, 0.925669f, 0.918261f, 0.905332f, 0.887252f, 0.864969f, 0.839592f, 0.812164f, 0.783606f, 0.754618f, + 1.000000f, 0.999867f, 0.997633f, 0.987557f, 0.967567f, 0.947227f, 0.933086f, 0.922399f, 0.910177f, 0.893396f, 0.871192f, 0.844036f, 0.813046f, 0.779516f, 0.744671f, 0.709514f, + 1.000000f, 0.999930f, 0.998771f, 0.993300f, 0.979919f, 0.960922f, 0.942369f, 0.925957f, 0.909076f, 0.888654f, 0.863025f, 0.832120f, 0.796861f, 0.758657f, 0.718960f, 0.679045f, + 1.000000f, 0.999956f, 0.999239f, 0.995830f, 0.986625f, 0.970820f, 0.951661f, 0.932046f, 0.911534f, 0.887936f, 0.859439f, 0.825540f, 0.786932f, 0.745027f, 0.701449f, 0.657704f, + 1.000000f, 0.999969f, 0.999473f, 0.997118f, 0.990453f, 0.977609f, 0.959545f, 0.938648f, 0.915693f, 0.889524f, 0.858630f, 0.822317f, 0.781060f, 0.736208f, 0.689492f, 0.642615f, + 1.000000f, 0.999976f, 0.999606f, 0.997854f, 0.992781f, 0.982286f, 0.965882f, 0.944911f, 0.920520f, 0.892413f, 0.859550f, 0.821273f, 0.777916f, 0.730738f, 0.681511f, 0.632081f, + 1.000000f, 0.999981f, 0.999687f, 0.998312f, 0.994284f, 0.985568f, 0.970883f, 0.950549f, 0.925506f, 0.896024f, 0.861574f, 0.821689f, 0.776670f, 0.727675f, 0.676486f, 0.625008f, + 1.000000f, 0.999985f, 0.999743f, 0.998616f, 0.995303f, 0.987934f, 0.974828f, 0.955478f, 0.930373f, 0.899997f, 0.864294f, 0.823096f, 0.776766f, 0.726395f, 0.673719f, 0.620682f, + 1.000000f, 0.999987f, 0.999781f, 0.998827f, 0.996025f, 0.989682f, 0.977961f, 0.959749f, 0.934996f, 0.904136f, 0.867474f, 0.825208f, 0.777828f, 0.726456f, 0.672745f, 0.618613f, + 1.000000f, 0.999988f, 0.999810f, 0.998982f, 0.996552f, 0.991001f, 0.980464f, 0.963424f, 0.939294f, 0.908297f, 0.870947f, 0.827811f, 0.779621f, 0.727558f, 0.673225f, 0.618454f, + 1.000000f, 0.999990f, 0.999830f, 0.999096f, 0.996952f, 0.992022f, 0.982488f, 0.966579f, 0.943252f, 0.912412f, 0.874629f, 0.830792f, 0.781979f, 0.729501f, 0.674937f, 0.619990f, + 1.000000f, 0.999991f, 0.999846f, 0.999185f, 0.997261f, 0.992825f, 0.984141f, 0.969298f, 0.946884f, 0.916421f, 0.878440f, 0.834092f, 0.784810f, 0.732168f, 0.677746f, 0.623118f, + 1.000000f, 0.999992f, 0.999858f, 0.999254f, 0.997503f, 0.993468f, 0.985501f, 0.971650f, 0.950197f, 0.920309f, 0.882351f, 0.837660f, 0.788084f, 0.735510f, 0.681629f, 0.627864f, + 1.000000f, 0.999992f, 0.999868f, 0.999309f, 0.997692f, 0.993974f, 0.986604f, 0.973631f, 0.953141f, 0.923966f, 0.886221f, 0.841379f, 0.791669f, 0.739403f, 0.686462f, 0.634174f, + + 1.000000f, 0.995413f, 0.998913f, 0.999532f, 0.999717f, 0.999772f, 0.999771f, 0.999739f, 0.999687f, 0.999618f, 0.999537f, 0.999445f, 0.999344f, 0.999233f, 0.999114f, 0.998988f, + 1.000000f, 0.998400f, 0.974429f, 0.936758f, 0.930501f, 0.938746f, 0.945098f, 0.945820f, 0.941234f, 0.932309f, 0.919951f, 0.904932f, 0.887890f, 0.869377f, 0.849842f, 0.829658f, + 1.000000f, 0.999681f, 0.994258f, 0.974035f, 0.949106f, 0.935700f, 0.930671f, 0.926035f, 0.917515f, 0.903922f, 0.885496f, 0.863037f, 0.837465f, 0.809716f, 0.780605f, 0.750826f, + 1.000000f, 0.999867f, 0.997657f, 0.987721f, 0.967895f, 0.947244f, 0.932082f, 0.919954f, 0.906332f, 0.888399f, 0.865291f, 0.837388f, 0.805642f, 0.771219f, 0.735246f, 0.698702f, + 1.000000f, 0.999925f, 0.998707f, 0.992961f, 0.978875f, 0.958705f, 0.938638f, 0.920490f, 0.901846f, 0.879769f, 0.852684f, 0.820426f, 0.783826f, 0.744171f, 0.702835f, 0.661064f, + 1.000000f, 0.999951f, 0.999157f, 0.995375f, 0.985160f, 0.967563f, 0.946128f, 0.924097f, 0.901206f, 0.875334f, 0.844707f, 0.808799f, 0.768233f, 0.724320f, 0.678633f, 0.632651f, + 1.000000f, 0.999965f, 0.999391f, 0.996667f, 0.988943f, 0.974050f, 0.953115f, 0.929017f, 0.902852f, 0.873624f, 0.839810f, 0.800723f, 0.756819f, 0.709381f, 0.660104f, 0.610670f, + 1.000000f, 0.999972f, 0.999530f, 0.997437f, 0.991362f, 0.978783f, 0.959185f, 0.934340f, 0.905871f, 0.873756f, 0.837055f, 0.795148f, 0.748369f, 0.697964f, 0.645713f, 0.593434f, + 1.000000f, 0.999977f, 0.999618f, 0.997931f, 0.992983f, 0.982271f, 0.964282f, 0.939592f, 0.909677f, 0.875207f, 0.835895f, 0.791409f, 0.742095f, 0.689182f, 0.634462f, 0.579861f, + 1.000000f, 0.999981f, 0.999679f, 0.998269f, 0.994120f, 0.984880f, 0.968507f, 0.944532f, 0.913892f, 0.877580f, 0.835951f, 0.789083f, 0.737498f, 0.682417f, 0.625664f, 0.569212f, + 1.000000f, 0.999983f, 0.999722f, 0.998511f, 0.994947f, 0.986867f, 0.971985f, 0.949030f, 0.918252f, 0.880613f, 0.836955f, 0.787880f, 0.734206f, 0.677265f, 0.618859f, 0.560978f, + 1.000000f, 0.999985f, 0.999755f, 0.998689f, 0.995564f, 0.988405f, 0.974849f, 0.953070f, 0.922585f, 0.884086f, 0.838719f, 0.787615f, 0.732013f, 0.673422f, 0.613712f, 0.554814f, + 1.000000f, 0.999987f, 0.999780f, 0.998827f, 0.996034f, 0.989616f, 0.977223f, 0.956653f, 0.926786f, 0.887858f, 0.841111f, 0.788160f, 0.730739f, 0.670705f, 0.610002f, 0.550491f, + 1.000000f, 0.999988f, 0.999799f, 0.998932f, 0.996407f, 0.990586f, 0.979197f, 0.959827f, 0.930789f, 0.891800f, 0.844011f, 0.789411f, 0.730324f, 0.669025f, 0.607615f, 0.547908f, + 1.000000f, 0.999989f, 0.999814f, 0.999017f, 0.996706f, 0.991378f, 0.980863f, 0.962638f, 0.934581f, 0.895866f, 0.847385f, 0.791390f, 0.730794f, 0.668422f, 0.606630f, 0.547188f, + 1.000000f, 0.999989f, 0.999827f, 0.999089f, 0.996952f, 0.992038f, 0.982292f, 0.965160f, 0.938212f, 0.900086f, 0.851302f, 0.794258f, 0.732412f, 0.669246f, 0.607505f, 0.548948f, + + 1.000000f, 0.995527f, 0.998988f, 0.999578f, 0.999746f, 0.999792f, 0.999788f, 0.999757f, 0.999709f, 0.999646f, 0.999572f, 0.999487f, 0.999393f, 0.999292f, 0.999182f, 0.999065f, + 1.000000f, 0.998630f, 0.978259f, 0.945594f, 0.938363f, 0.943208f, 0.946704f, 0.945624f, 0.940084f, 0.930762f, 0.918345f, 0.903424f, 0.886518f, 0.868076f, 0.848494f, 0.828108f, + 1.000000f, 0.999686f, 0.994379f, 0.974597f, 0.949667f, 0.934937f, 0.927853f, 0.921320f, 0.911428f, 0.896989f, 0.878093f, 0.855342f, 0.829503f, 0.801381f, 0.771709f, 0.741121f, + 1.000000f, 0.999854f, 0.997413f, 0.986433f, 0.964455f, 0.941275f, 0.923775f, 0.909649f, 0.894422f, 0.875277f, 0.851284f, 0.822663f, 0.790233f, 0.755013f, 0.718042f, 0.680244f, + 1.000000f, 0.999911f, 0.998460f, 0.991601f, 0.974763f, 0.950692f, 0.926863f, 0.905686f, 0.884687f, 0.860771f, 0.832199f, 0.798686f, 0.760917f, 0.720034f, 0.677317f, 0.633973f, + 1.000000f, 0.999939f, 0.998951f, 0.994222f, 0.981435f, 0.959489f, 0.933079f, 0.906577f, 0.880075f, 0.851316f, 0.818348f, 0.780447f, 0.738092f, 0.692475f, 0.645047f, 0.597247f, + 1.000000f, 0.999955f, 0.999220f, 0.995720f, 0.985790f, 0.966702f, 0.940181f, 0.910358f, 0.879136f, 0.845680f, 0.808362f, 0.766337f, 0.719885f, 0.670150f, 0.618757f, 0.567295f, + 1.000000f, 0.999964f, 0.999386f, 0.996651f, 0.988710f, 0.972315f, 0.947035f, 0.915627f, 0.880780f, 0.842993f, 0.801433f, 0.755396f, 0.705118f, 0.651733f, 0.596910f, 0.542404f, + 1.000000f, 0.999970f, 0.999497f, 0.997273f, 0.990734f, 0.976637f, 0.953160f, 0.921481f, 0.884126f, 0.842575f, 0.796931f, 0.746983f, 0.693063f, 0.636338f, 0.578514f, 0.521455f, + 1.000000f, 0.999975f, 0.999573f, 0.997701f, 0.992188f, 0.979945f, 0.958416f, 0.927337f, 0.888509f, 0.843869f, 0.794433f, 0.740656f, 0.683196f, 0.623342f, 0.562868f, 0.503667f, + 1.000000f, 0.999978f, 0.999630f, 0.998013f, 0.993256f, 0.982510f, 0.962846f, 0.932888f, 0.893436f, 0.846421f, 0.793557f, 0.736072f, 0.675142f, 0.612325f, 0.549463f, 0.488487f, + 1.000000f, 0.999980f, 0.999672f, 0.998245f, 0.994061f, 0.984514f, 0.966548f, 0.937969f, 0.898572f, 0.849868f, 0.794002f, 0.732975f, 0.668639f, 0.602965f, 0.537948f, 0.475509f, + 1.000000f, 0.999982f, 0.999704f, 0.998422f, 0.994681f, 0.986106f, 0.969639f, 0.942542f, 0.903685f, 0.853930f, 0.795521f, 0.731167f, 0.663513f, 0.595046f, 0.528062f, 0.464468f, + 1.000000f, 0.999983f, 0.999729f, 0.998565f, 0.995174f, 0.987383f, 0.972219f, 0.946621f, 0.908635f, 0.858379f, 0.797926f, 0.730503f, 0.659617f, 0.588452f, 0.519655f, 0.455184f, + 1.000000f, 0.999985f, 0.999750f, 0.998678f, 0.995570f, 0.988433f, 0.974409f, 0.950253f, 0.913383f, 0.863096f, 0.801085f, 0.730928f, 0.656937f, 0.583162f, 0.512731f, 0.447692f, + 1.000000f, 0.999986f, 0.999768f, 0.998774f, 0.995908f, 0.989329f, 0.976331f, 0.953588f, 0.918034f, 0.868186f, 0.805172f, 0.732710f, 0.655891f, 0.579707f, 0.507923f, 0.442761f, + + 1.000000f, 0.996312f, 0.999240f, 0.999651f, 0.999760f, 0.999787f, 0.999779f, 0.999749f, 0.999703f, 0.999645f, 0.999575f, 0.999495f, 0.999407f, 0.999309f, 0.999204f, 0.999092f, + 1.000000f, 0.998301f, 0.972928f, 0.931704f, 0.920748f, 0.925333f, 0.930051f, 0.930602f, 0.926625f, 0.918661f, 0.907363f, 0.893324f, 0.877064f, 0.859040f, 0.839650f, 0.819231f, + 1.000000f, 0.999525f, 0.991428f, 0.961144f, 0.923725f, 0.903320f, 0.896105f, 0.891629f, 0.884225f, 0.872051f, 0.855024f, 0.833730f, 0.808951f, 0.781485f, 0.752085f, 0.721414f, + 1.000000f, 0.999774f, 0.995997f, 0.978904f, 0.944981f, 0.910598f, 0.887366f, 0.871985f, 0.857707f, 0.840241f, 0.817970f, 0.790838f, 0.759542f, 0.725052f, 0.688400f, 0.650532f, + 1.000000f, 0.999866f, 0.997668f, 0.987231f, 0.961720f, 0.926013f, 0.892610f, 0.866048f, 0.842981f, 0.818867f, 0.790927f, 0.758281f, 0.721314f, 0.681005f, 0.638561f, 0.595155f, + 1.000000f, 0.999910f, 0.998450f, 0.991465f, 0.972609f, 0.940671f, 0.903484f, 0.868578f, 0.836857f, 0.805400f, 0.771279f, 0.733075f, 0.690796f, 0.645329f, 0.597985f, 0.550096f, + 1.000000f, 0.999934f, 0.998877f, 0.993833f, 0.979565f, 0.952395f, 0.915451f, 0.875635f, 0.836658f, 0.797939f, 0.757376f, 0.713464f, 0.665999f, 0.615761f, 0.564091f, 0.512452f, + 1.000000f, 0.999949f, 0.999134f, 0.995276f, 0.984114f, 0.961248f, 0.926533f, 0.884641f, 0.840287f, 0.794994f, 0.747999f, 0.698280f, 0.645647f, 0.590843f, 0.535249f, 0.480393f, + 1.000000f, 0.999958f, 0.999301f, 0.996212f, 0.987189f, 0.967857f, 0.936066f, 0.894071f, 0.846193f, 0.795328f, 0.742217f, 0.686680f, 0.628856f, 0.569615f, 0.510364f, 0.452686f, + 1.000000f, 0.999965f, 0.999416f, 0.996852f, 0.989347f, 0.972802f, 0.944007f, 0.903118f, 0.853287f, 0.797992f, 0.739251f, 0.678005f, 0.614995f, 0.551366f, 0.488656f, 0.428473f, + 1.000000f, 0.999970f, 0.999498f, 0.997309f, 0.990906f, 0.976548f, 0.950521f, 0.911388f, 0.860855f, 0.802240f, 0.738510f, 0.671750f, 0.603568f, 0.535592f, 0.469551f, 0.407102f, + 1.000000f, 0.999973f, 0.999559f, 0.997645f, 0.992065f, 0.979424f, 0.955846f, 0.918761f, 0.868427f, 0.807506f, 0.739482f, 0.667504f, 0.594210f, 0.521887f, 0.452611f, 0.388102f, + 1.000000f, 0.999976f, 0.999605f, 0.997901f, 0.992948f, 0.981668f, 0.960198f, 0.925230f, 0.875721f, 0.813375f, 0.741762f, 0.664925f, 0.586603f, 0.509959f, 0.437510f, 0.371096f, + 1.000000f, 0.999978f, 0.999641f, 0.998100f, 0.993634f, 0.983446f, 0.963777f, 0.930872f, 0.882581f, 0.819548f, 0.745028f, 0.663733f, 0.580515f, 0.499559f, 0.423985f, 0.355802f, + 1.000000f, 0.999980f, 0.999669f, 0.998256f, 0.994180f, 0.984875f, 0.966740f, 0.935768f, 0.888948f, 0.825804f, 0.749026f, 0.663698f, 0.575750f, 0.490506f, 0.411849f, 0.342017f, + 1.000000f, 0.999981f, 0.999693f, 0.998386f, 0.994628f, 0.986052f, 0.969236f, 0.940057f, 0.894841f, 0.832060f, 0.753620f, 0.664714f, 0.572245f, 0.482769f, 0.401059f, 0.329698f +}; + +static const float table_ggx_glass_Eavg[256] = { + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 0.999948f, 0.999526f, 0.998250f, 0.995368f, 0.990153f, 0.982226f, 0.971590f, 0.958500f, 0.943359f, 0.926629f, 0.908785f, 0.890266f, 0.871452f, 0.852674f, 0.834183f, + 1.000000f, 0.999940f, 0.999462f, 0.998212f, 0.995774f, 0.991512f, 0.984795f, 0.975285f, 0.963001f, 0.948259f, 0.931521f, 0.913309f, 0.894118f, 0.874394f, 0.854521f, 0.834797f, + 1.000000f, 0.999936f, 0.999404f, 0.998052f, 0.995642f, 0.991777f, 0.985879f, 0.977416f, 0.966120f, 0.952052f, 0.935530f, 0.917035f, 0.897098f, 0.876222f, 0.854858f, 0.833395f, + 1.000000f, 0.999933f, 0.999357f, 0.997885f, 0.995352f, 0.991530f, 0.985983f, 0.978146f, 0.967570f, 0.954055f, 0.937708f, 0.918892f, 0.898089f, 0.875842f, 0.852684f, 0.829081f, + 1.000000f, 0.999930f, 0.999320f, 0.997734f, 0.995026f, 0.991065f, 0.985531f, 0.977907f, 0.967633f, 0.954330f, 0.937894f, 0.918515f, 0.896607f, 0.872718f, 0.847450f, 0.821371f, + 1.000000f, 0.999928f, 0.999290f, 0.997605f, 0.994707f, 0.990512f, 0.984770f, 0.977000f, 0.966604f, 0.953075f, 0.936122f, 0.915787f, 0.892406f, 0.866527f, 0.838798f, 0.809912f, + 1.000000f, 0.999926f, 0.999266f, 0.997495f, 0.994409f, 0.989914f, 0.983790f, 0.975569f, 0.964631f, 0.950373f, 0.932381f, 0.910592f, 0.885253f, 0.856934f, 0.826371f, 0.794380f, + 1.000000f, 0.999925f, 0.999248f, 0.997401f, 0.994124f, 0.989277f, 0.982606f, 0.973644f, 0.961719f, 0.946182f, 0.926552f, 0.902670f, 0.874805f, 0.843553f, 0.809751f, 0.774356f, + 1.000000f, 0.999925f, 0.999234f, 0.997319f, 0.993845f, 0.988576f, 0.981182f, 0.971131f, 0.957731f, 0.940281f, 0.918293f, 0.891626f, 0.860559f, 0.825811f, 0.788362f, 0.749315f, + 1.000000f, 0.999924f, 0.999223f, 0.997242f, 0.993540f, 0.987743f, 0.979384f, 0.967830f, 0.952347f, 0.932247f, 0.907072f, 0.876767f, 0.841769f, 0.802929f, 0.761410f, 0.718503f, + 1.000000f, 0.999924f, 0.999213f, 0.997156f, 0.993169f, 0.986668f, 0.976990f, 0.963370f, 0.945041f, 0.921363f, 0.892008f, 0.857117f, 0.817340f, 0.773777f, 0.727800f, 0.680887f, + 1.000000f, 0.999924f, 0.999202f, 0.997042f, 0.992642f, 0.985137f, 0.973602f, 0.957122f, 0.934914f, 0.906478f, 0.871730f, 0.831125f, 0.785646f, 0.736704f, 0.685926f, 0.634955f, + 1.000000f, 0.999924f, 0.999184f, 0.996841f, 0.991769f, 0.982715f, 0.968441f, 0.947900f, 0.920380f, 0.885624f, 0.843955f, 0.796294f, 0.744081f, 0.689112f, 0.633285f, 0.578354f, + 1.000000f, 0.999923f, 0.999128f, 0.996370f, 0.990004f, 0.978288f, 0.959700f, 0.933154f, 0.898161f, 0.854912f, 0.804326f, 0.747966f, 0.687872f, 0.626278f, 0.565335f, 0.506855f, + 1.000000f, 0.999914f, 0.998848f, 0.994908f, 0.985894f, 0.969773f, 0.944970f, 0.910567f, 0.866457f, 0.813420f, 0.753069f, 0.687695f, 0.619929f, 0.552409f, 0.487430f, 0.426737f +}; + +static const float table_ggx_glass_inv_E[4096] = { + 0.999985f, 1.000000f, 0.999989f, 0.999990f, 1.000000f, 0.999999f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + + 1.000000f, 0.995082f, 0.997750f, 0.996814f, 0.994756f, 0.991983f, 0.988694f, 0.985008f, 0.980991f, 0.976680f, 0.972098f, 0.967263f, 0.962191f, 0.956897f, 0.951393f, 0.945694f, + 1.000000f, 0.997327f, 0.950645f, 0.832222f, 0.702110f, 0.601791f, 0.544343f, 0.516691f, 0.504458f, 0.499346f, 0.497379f, 0.496755f, 0.496683f, 0.496802f, 0.496978f, 0.497139f, + 1.000000f, 0.996432f, 0.971516f, 0.904908f, 0.818245f, 0.748255f, 0.698217f, 0.661132f, 0.632581f, 0.610204f, 0.592497f, 0.578360f, 0.566979f, 0.557720f, 0.550120f, 0.543824f, + 1.000000f, 0.999653f, 0.994103f, 0.970001f, 0.920214f, 0.860776f, 0.807060f, 0.761582f, 0.722953f, 0.690200f, 0.662685f, 0.639760f, 0.620730f, 0.604930f, 0.591761f, 0.580730f, + 1.000000f, 0.999842f, 0.997455f, 0.987479f, 0.964275f, 0.927927f, 0.884581f, 0.840264f, 0.798180f, 0.759801f, 0.725804f, 0.696324f, 0.671106f, 0.649700f, 0.631572f, 0.616216f, + 1.000000f, 0.999929f, 0.998864f, 0.994331f, 0.982910f, 0.962055f, 0.932008f, 0.895627f, 0.856527f, 0.817676f, 0.781038f, 0.747745f, 0.718231f, 0.692480f, 0.670225f, 0.651075f, + 1.000000f, 0.999961f, 0.999376f, 0.996863f, 0.990329f, 0.977586f, 0.957377f, 0.930096f, 0.897609f, 0.862462f, 0.826970f, 0.792904f, 0.761375f, 0.732918f, 0.707657f, 0.685460f, + 1.000000f, 0.999976f, 0.999613f, 0.998053f, 0.993938f, 0.985660f, 0.971838f, 0.951879f, 0.926313f, 0.896583f, 0.864557f, 0.832070f, 0.800565f, 0.771014f, 0.743952f, 0.719567f, + 1.000000f, 0.999984f, 0.999745f, 0.998715f, 0.995974f, 0.990366f, 0.980729f, 0.966212f, 0.946629f, 0.922522f, 0.895070f, 0.865716f, 0.835888f, 0.806747f, 0.779117f, 0.753489f, + 1.000000f, 0.999989f, 0.999826f, 0.999123f, 0.997243f, 0.993362f, 0.986560f, 0.976040f, 0.961305f, 0.942373f, 0.919782f, 0.894446f, 0.867512f, 0.840089f, 0.813118f, 0.787284f, + 1.000000f, 0.999993f, 0.999881f, 0.999395f, 0.998094f, 0.995389f, 0.990595f, 0.983039f, 0.972175f, 0.957736f, 0.939825f, 0.918897f, 0.895690f, 0.871077f, 0.845921f, 0.820980f, + 1.000000f, 0.999995f, 0.999918f, 0.999585f, 0.998693f, 0.996832f, 0.993503f, 0.988186f, 0.980393f, 0.969766f, 0.956157f, 0.939679f, 0.920694f, 0.899742f, 0.877484f, 0.854586f, + 1.000000f, 0.999997f, 0.999946f, 0.999726f, 0.999136f, 0.997899f, 0.995672f, 0.992082f, 0.986739f, 0.979309f, 0.969547f, 0.957358f, 0.942813f, 0.926153f, 0.907762f, 0.888097f, + 1.000000f, 0.999998f, 0.999967f, 0.999832f, 0.999469f, 0.998707f, 0.997331f, 0.995094f, 0.991728f, 0.986971f, 0.980592f, 0.972409f, 0.962344f, 0.950403f, 0.936705f, 0.921469f, + 1.000000f, 0.999999f, 0.999983f, 0.999915f, 0.999727f, 0.999335f, 0.998625f, 0.997464f, 0.995701f, 0.993179f, 0.989726f, 0.985207f, 0.979490f, 0.972486f, 0.964145f, 0.954484f, + 1.000000f, 1.000000f, 0.999994f, 0.999967f, 0.999894f, 0.999741f, 0.999464f, 0.999009f, 0.998309f, 0.997296f, 0.995883f, 0.993986f, 0.991504f, 0.988339f, 0.984390f, 0.979542f, + + 1.000000f, 0.995236f, 0.998550f, 0.998801f, 0.998428f, 0.997742f, 0.996831f, 0.995743f, 0.994509f, 0.993153f, 0.991690f, 0.990130f, 0.988479f, 0.986742f, 0.984923f, 0.983024f, + 1.000000f, 0.997491f, 0.958825f, 0.887405f, 0.836169f, 0.777014f, 0.700137f, 0.619723f, 0.550159f, 0.497933f, 0.462916f, 0.441865f, 0.430862f, 0.426506f, 0.426279f, 0.428417f, + 1.000000f, 0.999387f, 0.987949f, 0.938920f, 0.854742f, 0.761659f, 0.675893f, 0.609056f, 0.563787f, 0.535678f, 0.518945f, 0.509098f, 0.503253f, 0.499699f, 0.497454f, 0.495959f, + 1.000000f, 0.999697f, 0.992974f, 0.956997f, 0.880103f, 0.793559f, 0.724151f, 0.674443f, 0.639020f, 0.613009f, 0.593289f, 0.577939f, 0.565706f, 0.555794f, 0.547620f, 0.540809f, + 1.000000f, 0.998971f, 0.990531f, 0.966765f, 0.920386f, 0.858725f, 0.798945f, 0.749892f, 0.711318f, 0.680491f, 0.655226f, 0.634142f, 0.616388f, 0.601357f, 0.588586f, 0.577688f, + 1.000000f, 0.999848f, 0.997453f, 0.986597f, 0.958949f, 0.913663f, 0.861319f, 0.812788f, 0.771829f, 0.737675f, 0.708689f, 0.683692f, 0.661970f, 0.643061f, 0.626615f, 0.612317f, + 1.000000f, 0.999918f, 0.998627f, 0.992720f, 0.976730f, 0.947034f, 0.906966f, 0.864277f, 0.824492f, 0.789204f, 0.758048f, 0.730349f, 0.705627f, 0.683579f, 0.663985f, 0.646642f, + 1.000000f, 0.999947f, 0.999111f, 0.995378f, 0.985462f, 0.966521f, 0.938604f, 0.905036f, 0.869938f, 0.836001f, 0.804272f, 0.774971f, 0.748071f, 0.723512f, 0.701250f, 0.681195f, + 1.000000f, 0.999965f, 0.999442f, 0.997183f, 0.991249f, 0.979598f, 0.961119f, 0.936455f, 0.907646f, 0.877051f, 0.846437f, 0.816822f, 0.788744f, 0.762490f, 0.738197f, 0.715942f, + 1.000000f, 0.999979f, 0.999660f, 0.998288f, 0.994651f, 0.987309f, 0.975057f, 0.957452f, 0.935116f, 0.909384f, 0.881821f, 0.853716f, 0.826017f, 0.799342f, 0.774067f, 0.750429f, + 1.000000f, 0.999987f, 0.999784f, 0.998907f, 0.996567f, 0.991766f, 0.983508f, 0.971084f, 0.954354f, 0.933827f, 0.910448f, 0.885334f, 0.859505f, 0.833742f, 0.808627f, 0.784554f, + 1.000000f, 0.999992f, 0.999858f, 0.999280f, 0.997733f, 0.994535f, 0.988921f, 0.980212f, 0.967995f, 0.952272f, 0.933425f, 0.912153f, 0.889282f, 0.865590f, 0.841742f, 0.818257f, + 1.000000f, 0.999995f, 0.999906f, 0.999523f, 0.998498f, 0.996361f, 0.992567f, 0.986552f, 0.977881f, 0.966282f, 0.951793f, 0.934713f, 0.915529f, 0.894853f, 0.873307f, 0.851407f, + 1.000000f, 0.999996f, 0.999940f, 0.999690f, 0.999024f, 0.997628f, 0.995121f, 0.991104f, 0.985173f, 0.977015f, 0.966461f, 0.953524f, 0.938375f, 0.921364f, 0.902945f, 0.883553f, + 1.000000f, 0.999998f, 0.999962f, 0.999809f, 0.999389f, 0.998514f, 0.996933f, 0.994364f, 0.990509f, 0.985082f, 0.977837f, 0.968625f, 0.957380f, 0.944176f, 0.929178f, 0.912684f, + 1.000000f, 0.999999f, 0.999973f, 0.999862f, 0.999565f, 0.998939f, 0.997802f, 0.995933f, 0.993080f, 0.988962f, 0.983276f, 0.975719f, 0.965982f, 0.953785f, 0.938866f, 0.921038f, + + 1.000000f, 0.995264f, 0.998700f, 0.999181f, 0.999146f, 0.998899f, 0.998518f, 0.998034f, 0.997464f, 0.996820f, 0.996113f, 0.995349f, 0.994536f, 0.993675f, 0.992770f, 0.991822f, + 1.000000f, 0.997506f, 0.959780f, 0.895886f, 0.867758f, 0.847192f, 0.811951f, 0.761560f, 0.702769f, 0.642860f, 0.587308f, 0.539284f, 0.500040f, 0.469478f, 0.446760f, 0.430697f, + 1.000000f, 0.999403f, 0.988921f, 0.947698f, 0.887836f, 0.831693f, 0.772965f, 0.707226f, 0.641001f, 0.582776f, 0.537128f, 0.504336f, 0.482382f, 0.468571f, 0.460416f, 0.456006f, + 1.000000f, 0.999734f, 0.994985f, 0.971627f, 0.918352f, 0.846555f, 0.770872f, 0.699786f, 0.639815f, 0.593898f, 0.561036f, 0.538362f, 0.522894f, 0.512265f, 0.504808f, 0.499436f, + 1.000000f, 0.999845f, 0.996884f, 0.980556f, 0.935434f, 0.863605f, 0.786812f, 0.721647f, 0.671750f, 0.634636f, 0.606898f, 0.585793f, 0.569400f, 0.556404f, 0.545880f, 0.537246f, + 1.000000f, 0.999883f, 0.997078f, 0.981152f, 0.942190f, 0.884389f, 0.821505f, 0.765319f, 0.719739f, 0.683723f, 0.655004f, 0.631650f, 0.612346f, 0.596152f, 0.582440f, 0.570744f, + 1.000000f, 0.999708f, 0.995826f, 0.983677f, 0.958470f, 0.917402f, 0.865810f, 0.813738f, 0.767950f, 0.730061f, 0.698996f, 0.673189f, 0.651349f, 0.632596f, 0.616345f, 0.602177f, + 1.000000f, 0.999917f, 0.998624f, 0.992763f, 0.976951f, 0.946967f, 0.904504f, 0.857014f, 0.811931f, 0.772830f, 0.739955f, 0.712217f, 0.688432f, 0.667676f, 0.649364f, 0.633098f, + 1.000000f, 0.999950f, 0.999175f, 0.995639f, 0.985685f, 0.965189f, 0.932959f, 0.892918f, 0.851405f, 0.812999f, 0.779369f, 0.750289f, 0.724925f, 0.702481f, 0.682374f, 0.664235f, + 1.000000f, 0.999965f, 0.999425f, 0.996976f, 0.990134f, 0.975876f, 0.952425f, 0.921070f, 0.885697f, 0.850344f, 0.817472f, 0.787847f, 0.761314f, 0.737404f, 0.715685f, 0.695837f, + 1.000000f, 0.999974f, 0.999576f, 0.997806f, 0.992983f, 0.983078f, 0.966551f, 0.943335f, 0.915131f, 0.884541f, 0.853930f, 0.824734f, 0.797553f, 0.772445f, 0.749281f, 0.727863f, + 1.000000f, 0.999983f, 0.999708f, 0.998519f, 0.995334f, 0.988826f, 0.977711f, 0.961295f, 0.939903f, 0.914764f, 0.887583f, 0.859907f, 0.832855f, 0.807035f, 0.782699f, 0.759885f, + 1.000000f, 0.999988f, 0.999811f, 0.999042f, 0.996990f, 0.992740f, 0.985312f, 0.973911f, 0.958186f, 0.938466f, 0.915581f, 0.890711f, 0.864992f, 0.839356f, 0.814445f, 0.790603f, + 1.000000f, 0.999993f, 0.999876f, 0.999372f, 0.998020f, 0.995197f, 0.990179f, 0.982272f, 0.970926f, 0.955919f, 0.937441f, 0.916057f, 0.892562f, 0.867872f, 0.842769f, 0.817881f, + 1.000000f, 0.999995f, 0.999915f, 0.999566f, 0.998632f, 0.996669f, 0.993140f, 0.987456f, 0.979025f, 0.967403f, 0.952286f, 0.933661f, 0.911774f, 0.887060f, 0.860168f, 0.831767f, + 1.000000f, 0.999996f, 0.999937f, 0.999677f, 0.998980f, 0.997510f, 0.994842f, 0.990476f, 0.983850f, 0.974367f, 0.961453f, 0.944585f, 0.923348f, 0.897484f, 0.866932f, 0.831849f, + + 1.000000f, 0.995274f, 0.998753f, 0.999314f, 0.999400f, 0.999312f, 0.999128f, 0.998872f, 0.998561f, 0.998199f, 0.997795f, 0.997353f, 0.996877f, 0.996371f, 0.995835f, 0.995272f, + 1.000000f, 0.997511f, 0.960071f, 0.898620f, 0.878659f, 0.873821f, 0.860219f, 0.833543f, 0.796233f, 0.752198f, 0.705231f, 0.658472f, 0.614230f, 0.573972f, 0.538477f, 0.508025f, + 1.000000f, 0.999405f, 0.989130f, 0.949830f, 0.897468f, 0.858122f, 0.823932f, 0.782744f, 0.732512f, 0.677594f, 0.623754f, 0.575427f, 0.534943f, 0.502899f, 0.478646f, 0.461005f, + 1.000000f, 0.999738f, 0.995228f, 0.974062f, 0.929086f, 0.874707f, 0.820986f, 0.765529f, 0.707500f, 0.650969f, 0.600887f, 0.560050f, 0.528786f, 0.505868f, 0.489538f, 0.478098f, + 1.000000f, 0.999852f, 0.997285f, 0.984298f, 0.949907f, 0.894687f, 0.830051f, 0.764655f, 0.703610f, 0.650720f, 0.607837f, 0.574686f, 0.549707f, 0.531052f, 0.517044f, 0.506390f, + 1.000000f, 0.999903f, 0.998164f, 0.988845f, 0.961108f, 0.909217f, 0.842075f, 0.774576f, 0.716020f, 0.668788f, 0.631760f, 0.602815f, 0.580035f, 0.561884f, 0.547230f, 0.535234f, + 1.000000f, 0.999929f, 0.998507f, 0.990285f, 0.965135f, 0.917992f, 0.857129f, 0.795963f, 0.742667f, 0.699055f, 0.663951f, 0.635517f, 0.612188f, 0.592805f, 0.576520f, 0.562709f, + 1.000000f, 0.999930f, 0.997985f, 0.987991f, 0.965712f, 0.929365f, 0.880981f, 0.827897f, 0.777686f, 0.734212f, 0.698025f, 0.668119f, 0.643237f, 0.622258f, 0.604347f, 0.588895f, + 1.000000f, 0.999892f, 0.998245f, 0.991593f, 0.976269f, 0.949053f, 0.909388f, 0.861824f, 0.813348f, 0.769138f, 0.731260f, 0.699559f, 0.673029f, 0.650560f, 0.631217f, 0.614335f, + 1.000000f, 0.999951f, 0.999193f, 0.995758f, 0.986165f, 0.966390f, 0.934469f, 0.892812f, 0.847190f, 0.803233f, 0.764153f, 0.730780f, 0.702574f, 0.678537f, 0.657746f, 0.639441f, + 1.000000f, 0.999967f, 0.999464f, 0.997169f, 0.990665f, 0.976632f, 0.952374f, 0.918124f, 0.877615f, 0.835913f, 0.796893f, 0.762354f, 0.732463f, 0.706676f, 0.684154f, 0.664217f, + 1.000000f, 0.999976f, 0.999599f, 0.997898f, 0.993113f, 0.982787f, 0.964563f, 0.937646f, 0.903767f, 0.866396f, 0.829112f, 0.794260f, 0.762877f, 0.735004f, 0.710259f, 0.688126f, + 1.000000f, 0.999981f, 0.999687f, 0.998378f, 0.994751f, 0.987065f, 0.973532f, 0.953125f, 0.926150f, 0.894376f, 0.860258f, 0.826066f, 0.793349f, 0.762938f, 0.735056f, 0.709572f, + 1.000000f, 0.999985f, 0.999762f, 0.998782f, 0.996155f, 0.990674f, 0.981030f, 0.966111f, 0.945407f, 0.919258f, 0.888814f, 0.855632f, 0.821323f, 0.787139f, 0.753957f, 0.722283f, + 1.000000f, 0.999990f, 0.999832f, 0.999154f, 0.997326f, 0.993492f, 0.986639f, 0.975713f, 0.959807f, 0.938406f, 0.911476f, 0.879541f, 0.843530f, 0.804526f, 0.763704f, 0.722042f, + 1.000000f, 0.999993f, 0.999880f, 0.999393f, 0.998081f, 0.995315f, 0.990310f, 0.982153f, 0.969868f, 0.952528f, 0.929350f, 0.899824f, 0.863810f, 0.821621f, 0.773983f, 0.722012f, + + 1.000000f, 0.995279f, 0.998777f, 0.999375f, 0.999516f, 0.999502f, 0.999409f, 0.999263f, 0.999075f, 0.998852f, 0.998598f, 0.998317f, 0.998011f, 0.997682f, 0.997333f, 0.996965f, + 1.000000f, 0.997512f, 0.960193f, 0.899810f, 0.883560f, 0.886229f, 0.883754f, 0.870744f, 0.848142f, 0.818228f, 0.783377f, 0.745763f, 0.707244f, 0.669288f, 0.632992f, 0.599103f, + 1.000000f, 0.999406f, 0.989202f, 0.950635f, 0.901346f, 0.869619f, 0.848470f, 0.824120f, 0.791055f, 0.749978f, 0.704165f, 0.657309f, 0.612523f, 0.571935f, 0.536685f, 0.507097f, + 1.000000f, 0.999738f, 0.995293f, 0.974815f, 0.932797f, 0.886032f, 0.845632f, 0.806855f, 0.763730f, 0.715650f, 0.665786f, 0.618169f, 0.575818f, 0.540180f, 0.511466f, 0.489052f, + 1.000000f, 0.999852f, 0.997364f, 0.985187f, 0.954180f, 0.907250f, 0.855836f, 0.804425f, 0.752168f, 0.699650f, 0.649724f, 0.605354f, 0.568138f, 0.538243f, 0.514846f, 0.496802f, + 1.000000f, 0.999904f, 0.998287f, 0.990135f, 0.966897f, 0.924434f, 0.868932f, 0.809150f, 0.750508f, 0.696302f, 0.648748f, 0.608872f, 0.576454f, 0.550541f, 0.529942f, 0.513537f, + 1.000000f, 0.999932f, 0.998757f, 0.992664f, 0.974035f, 0.935966f, 0.880421f, 0.817418f, 0.756776f, 0.703644f, 0.659295f, 0.622981f, 0.593394f, 0.569220f, 0.549366f, 0.532937f, + 1.000000f, 0.999948f, 0.998998f, 0.993796f, 0.977216f, 0.942154f, 0.889613f, 0.829330f, 0.771355f, 0.720748f, 0.678401f, 0.643376f, 0.614334f, 0.590114f, 0.569735f, 0.552482f, + 1.000000f, 0.999956f, 0.999008f, 0.993380f, 0.976671f, 0.945269f, 0.900482f, 0.847803f, 0.794303f, 0.745187f, 0.702581f, 0.666575f, 0.636395f, 0.611019f, 0.589522f, 0.571144f, + 1.000000f, 0.999642f, 0.997254f, 0.990779f, 0.977436f, 0.953828f, 0.918026f, 0.872140f, 0.821771f, 0.772688f, 0.728481f, 0.690385f, 0.658196f, 0.631079f, 0.608078f, 0.588383f, + 1.000000f, 0.999950f, 0.999173f, 0.995700f, 0.986407f, 0.967945f, 0.938044f, 0.897296f, 0.849725f, 0.800827f, 0.754988f, 0.714460f, 0.679710f, 0.650226f, 0.625133f, 0.603566f, + 1.000000f, 0.999969f, 0.999491f, 0.997328f, 0.991190f, 0.977844f, 0.954242f, 0.919490f, 0.876027f, 0.828587f, 0.781834f, 0.738874f, 0.700951f, 0.668123f, 0.639755f, 0.615082f, + 1.000000f, 0.999977f, 0.999617f, 0.997990f, 0.993387f, 0.983289f, 0.964865f, 0.936338f, 0.898372f, 0.854074f, 0.807560f, 0.762265f, 0.720225f, 0.682178f, 0.648063f, 0.617433f, + 1.000000f, 0.999981f, 0.999683f, 0.998357f, 0.994648f, 0.986594f, 0.971921f, 0.948760f, 0.916623f, 0.876794f, 0.831897f, 0.784881f, 0.738053f, 0.692914f, 0.650113f, 0.609792f, + 1.000000f, 0.999984f, 0.999734f, 0.998629f, 0.995610f, 0.989205f, 0.977699f, 0.959459f, 0.933369f, 0.899232f, 0.857885f, 0.811010f, 0.760542f, 0.708378f, 0.655964f, 0.604417f, + 1.000000f, 0.999988f, 0.999800f, 0.998989f, 0.996796f, 0.992182f, 0.983853f, 0.970359f, 0.950269f, 0.922385f, 0.886016f, 0.841174f, 0.788665f, 0.730019f, 0.667293f, 0.602764f, + + 1.000000f, 0.995281f, 0.998789f, 0.999407f, 0.999577f, 0.999602f, 0.999558f, 0.999470f, 0.999349f, 0.999201f, 0.999030f, 0.998838f, 0.998627f, 0.998399f, 0.998155f, 0.997896f, + 1.000000f, 0.997513f, 0.960249f, 0.900406f, 0.886089f, 0.892774f, 0.896456f, 0.891395f, 0.877963f, 0.857758f, 0.832434f, 0.803495f, 0.772286f, 0.739949f, 0.707458f, 0.675561f, + 1.000000f, 0.999407f, 0.989231f, 0.951000f, 0.903200f, 0.875363f, 0.861319f, 0.847061f, 0.825875f, 0.796742f, 0.761239f, 0.721786f, 0.680816f, 0.640463f, 0.602298f, 0.567378f, + 1.000000f, 0.999738f, 0.995315f, 0.975112f, 0.934395f, 0.891271f, 0.858018f, 0.829830f, 0.799044f, 0.762384f, 0.720541f, 0.676210f, 0.632355f, 0.591401f, 0.554867f, 0.523436f, + 1.000000f, 0.999852f, 0.997386f, 0.985489f, 0.955810f, 0.912598f, 0.868448f, 0.827505f, 0.786526f, 0.742772f, 0.696651f, 0.650629f, 0.607470f, 0.569086f, 0.536346f, 0.509224f, + 1.000000f, 0.999904f, 0.998316f, 0.990504f, 0.968816f, 0.930527f, 0.882628f, 0.832611f, 0.782598f, 0.732654f, 0.683857f, 0.638184f, 0.597439f, 0.562499f, 0.533360f, 0.509454f, + 1.000000f, 0.999932f, 0.998803f, 0.993191f, 0.976633f, 0.943607f, 0.895857f, 0.840574f, 0.783946f, 0.729575f, 0.679617f, 0.635398f, 0.597373f, 0.565310f, 0.538606f, 0.516438f, + 1.000000f, 0.999948f, 0.999083f, 0.994709f, 0.981260f, 0.952269f, 0.906208f, 0.848944f, 0.789028f, 0.732726f, 0.682916f, 0.640159f, 0.603957f, 0.573434f, 0.547734f, 0.526040f, + 1.000000f, 0.999958f, 0.999244f, 0.995504f, 0.983610f, 0.957032f, 0.913261f, 0.857335f, 0.798097f, 0.742316f, 0.693015f, 0.650643f, 0.614578f, 0.583949f, 0.557917f, 0.535717f, + 1.000000f, 0.999965f, 0.999300f, 0.995552f, 0.983604f, 0.958348f, 0.918639f, 0.868000f, 0.812623f, 0.758282f, 0.708524f, 0.664736f, 0.626955f, 0.594631f, 0.567030f, 0.543396f, + 1.000000f, 0.999961f, 0.998876f, 0.993452f, 0.981396f, 0.960356f, 0.927836f, 0.883938f, 0.832391f, 0.778550f, 0.726910f, 0.680091f, 0.638976f, 0.603454f, 0.572900f, 0.546588f, + 1.000000f, 0.999948f, 0.999141f, 0.995636f, 0.986808f, 0.969928f, 0.942322f, 0.902955f, 0.853928f, 0.799818f, 0.745449f, 0.694280f, 0.648026f, 0.607120f, 0.571170f, 0.539507f, + 1.000000f, 0.999971f, 0.999515f, 0.997458f, 0.991643f, 0.978974f, 0.956207f, 0.921417f, 0.875407f, 0.821675f, 0.764848f, 0.708938f, 0.656438f, 0.608371f, 0.564828f, 0.525338f, + 1.000000f, 0.999977f, 0.999625f, 0.998046f, 0.993587f, 0.983730f, 0.965409f, 0.935992f, 0.894749f, 0.843544f, 0.786131f, 0.726560f, 0.667972f, 0.612238f, 0.560125f, 0.511730f, + 1.000000f, 0.999981f, 0.999680f, 0.998335f, 0.994583f, 0.986395f, 0.971213f, 0.946522f, 0.910722f, 0.863973f, 0.808275f, 0.746767f, 0.682739f, 0.618900f, 0.557115f, 0.498536f, + 1.000000f, 0.999981f, 0.999699f, 0.998465f, 0.995126f, 0.988082f, 0.975371f, 0.954899f, 0.924785f, 0.883853f, 0.832029f, 0.770609f, 0.702046f, 0.629568f, 0.556527f, 0.485918f, + + 1.000000f, 0.995282f, 0.998796f, 0.999425f, 0.999611f, 0.999659f, 0.999642f, 0.999587f, 0.999504f, 0.999400f, 0.999277f, 0.999137f, 0.998983f, 0.998814f, 0.998633f, 0.998441f, + 1.000000f, 0.997513f, 0.960278f, 0.900724f, 0.887483f, 0.896459f, 0.903728f, 0.903412f, 0.895650f, 0.881748f, 0.863017f, 0.840610f, 0.815525f, 0.788635f, 0.760702f, 0.732374f, + 1.000000f, 0.999406f, 0.989241f, 0.951173f, 0.904157f, 0.878444f, 0.868446f, 0.860220f, 0.846617f, 0.825875f, 0.798692f, 0.766633f, 0.731460f, 0.694854f, 0.658274f, 0.622879f, + 1.000000f, 0.999737f, 0.995320f, 0.975238f, 0.935149f, 0.893906f, 0.864579f, 0.842702f, 0.820146f, 0.792448f, 0.758869f, 0.720774f, 0.680337f, 0.639759f, 0.600864f, 0.564924f, + 1.000000f, 0.999851f, 0.997390f, 0.985602f, 0.956507f, 0.915093f, 0.874811f, 0.840192f, 0.807403f, 0.772125f, 0.732870f, 0.690663f, 0.647724f, 0.606303f, 0.568131f, 0.534194f, + 1.000000f, 0.999903f, 0.998318f, 0.990625f, 0.969560f, 0.933162f, 0.889260f, 0.845564f, 0.803221f, 0.760306f, 0.715854f, 0.670786f, 0.627061f, 0.586488f, 0.550288f, 0.518905f, + 1.000000f, 0.999931f, 0.998809f, 0.993343f, 0.977536f, 0.946684f, 0.903274f, 0.854232f, 0.804128f, 0.754285f, 0.705289f, 0.658308f, 0.614732f, 0.575639f, 0.541492f, 0.512202f, + 1.000000f, 0.999948f, 0.999096f, 0.994935f, 0.982501f, 0.956236f, 0.914970f, 0.863407f, 0.807776f, 0.752439f, 0.699918f, 0.651662f, 0.608475f, 0.570547f, 0.537739f, 0.509589f, + 1.000000f, 0.999958f, 0.999275f, 0.995902f, 0.985571f, 0.962583f, 0.923689f, 0.871527f, 0.812829f, 0.754063f, 0.699203f, 0.649900f, 0.606478f, 0.568627f, 0.535870f, 0.507601f, + 1.000000f, 0.999965f, 0.999383f, 0.996447f, 0.987229f, 0.966133f, 0.929214f, 0.878067f, 0.819103f, 0.759216f, 0.702844f, 0.651887f, 0.606737f, 0.567112f, 0.532548f, 0.502454f, + 1.000000f, 0.999969f, 0.999429f, 0.996540f, 0.987322f, 0.966773f, 0.932016f, 0.884166f, 0.827678f, 0.768075f, 0.709745f, 0.655332f, 0.605919f, 0.561753f, 0.522522f, 0.487763f, + 1.000000f, 0.999968f, 0.999268f, 0.995284f, 0.984967f, 0.966145f, 0.936275f, 0.894014f, 0.841088f, 0.781733f, 0.720705f, 0.661589f, 0.606471f, 0.556170f, 0.510737f, 0.469825f, + 1.000000f, 0.999951f, 0.999187f, 0.995914f, 0.987863f, 0.972540f, 0.946931f, 0.908810f, 0.858448f, 0.799008f, 0.735076f, 0.670924f, 0.609496f, 0.552335f, 0.499952f, 0.452233f, + 1.000000f, 0.999973f, 0.999555f, 0.997668f, 0.992328f, 0.980601f, 0.959061f, 0.924916f, 0.877395f, 0.818463f, 0.752161f, 0.683031f, 0.614861f, 0.550061f, 0.489851f, 0.434654f, + 1.000000f, 0.999978f, 0.999641f, 0.998129f, 0.993860f, 0.984408f, 0.966592f, 0.937159f, 0.894046f, 0.837539f, 0.770472f, 0.697165f, 0.622089f, 0.548834f, 0.479806f, 0.416360f, + 1.000000f, 0.999980f, 0.999677f, 0.998316f, 0.994494f, 0.986091f, 0.970357f, 0.944295f, 0.905394f, 0.852501f, 0.786514f, 0.710447f, 0.628796f, 0.546440f, 0.467649f, 0.395427f, + + 1.000000f, 0.995283f, 0.998800f, 0.999435f, 0.999631f, 0.999691f, 0.999691f, 0.999655f, 0.999595f, 0.999516f, 0.999421f, 0.999313f, 0.999192f, 0.999059f, 0.998917f, 0.998764f, + 1.000000f, 0.997512f, 0.960289f, 0.900893f, 0.888264f, 0.898575f, 0.907972f, 0.910513f, 0.906231f, 0.896299f, 0.881871f, 0.863923f, 0.843273f, 0.820621f, 0.796574f, 0.771649f, + 1.000000f, 0.999405f, 0.989242f, 0.951252f, 0.904648f, 0.880121f, 0.872458f, 0.867827f, 0.858917f, 0.843645f, 0.822263f, 0.795882f, 0.765817f, 0.733393f, 0.699798f, 0.666063f, + 1.000000f, 0.999737f, 0.995318f, 0.975282f, 0.935499f, 0.895244f, 0.868096f, 0.849903f, 0.832452f, 0.810814f, 0.783502f, 0.751086f, 0.715043f, 0.677112f, 0.638938f, 0.601879f, + 1.000000f, 0.999851f, 0.997386f, 0.985632f, 0.956797f, 0.916269f, 0.878042f, 0.847041f, 0.819403f, 0.790195f, 0.756908f, 0.719491f, 0.679341f, 0.638364f, 0.598372f, 0.560777f, + 1.000000f, 0.999902f, 0.998314f, 0.990652f, 0.969838f, 0.934317f, 0.892448f, 0.852349f, 0.815038f, 0.777756f, 0.738291f, 0.696378f, 0.653243f, 0.610715f, 0.570450f, 0.533612f, + 1.000000f, 0.999931f, 0.998805f, 0.993377f, 0.977845f, 0.947940f, 0.906676f, 0.861280f, 0.815943f, 0.770863f, 0.725219f, 0.679104f, 0.633630f, 0.590317f, 0.550417f, 0.514624f, + 1.000000f, 0.999947f, 0.999093f, 0.994984f, 0.982895f, 0.957752f, 0.918880f, 0.871041f, 0.819643f, 0.767602f, 0.716077f, 0.665972f, 0.618404f, 0.574405f, 0.534630f, 0.499381f, + 1.000000f, 0.999957f, 0.999273f, 0.995983f, 0.986141f, 0.964597f, 0.928467f, 0.879916f, 0.824267f, 0.766440f, 0.709605f, 0.655628f, 0.605583f, 0.560068f, 0.519284f, 0.483185f, + 1.000000f, 0.999964f, 0.999388f, 0.996606f, 0.988176f, 0.969082f, 0.935243f, 0.886835f, 0.828531f, 0.766332f, 0.704864f, 0.646706f, 0.592981f, 0.544086f, 0.499969f, 0.460436f, + 1.000000f, 0.999969f, 0.999462f, 0.996977f, 0.989321f, 0.971637f, 0.939471f, 0.892050f, 0.833246f, 0.769016f, 0.704403f, 0.642408f, 0.584516f, 0.531265f, 0.482743f, 0.438826f, + 1.000000f, 0.999972f, 0.999497f, 0.997057f, 0.989393f, 0.971996f, 0.941268f, 0.896395f, 0.839702f, 0.775622f, 0.708797f, 0.642841f, 0.580000f, 0.521463f, 0.467672f, 0.418720f, + 1.000000f, 0.999972f, 0.999371f, 0.996026f, 0.987157f, 0.970597f, 0.943509f, 0.903421f, 0.850272f, 0.786874f, 0.717688f, 0.647101f, 0.578407f, 0.513634f, 0.453828f, 0.399366f, + 1.000000f, 0.999962f, 0.999368f, 0.996733f, 0.989833f, 0.976117f, 0.952471f, 0.915908f, 0.865184f, 0.801869f, 0.729929f, 0.654168f, 0.578853f, 0.507031f, 0.440545f, 0.380228f, + 1.000000f, 0.999976f, 0.999611f, 0.997961f, 0.993266f, 0.982780f, 0.962941f, 0.930172f, 0.882238f, 0.819483f, 0.745055f, 0.663908f, 0.581283f, 0.501532f, 0.427616f, 0.361193f, + 1.000000f, 0.999980f, 0.999676f, 0.998309f, 0.994432f, 0.985758f, 0.969118f, 0.940802f, 0.897514f, 0.837756f, 0.762936f, 0.677418f, 0.587328f, 0.498831f, 0.416740f, 0.343944f, + + 1.000000f, 0.995284f, 0.998803f, 0.999441f, 0.999642f, 0.999710f, 0.999718f, 0.999694f, 0.999647f, 0.999582f, 0.999504f, 0.999414f, 0.999312f, 0.999201f, 0.999080f, 0.998951f, + 1.000000f, 0.997512f, 0.960292f, 0.900975f, 0.888686f, 0.899761f, 0.910395f, 0.914614f, 0.912405f, 0.904872f, 0.893093f, 0.877966f, 0.860221f, 0.840462f, 0.819208f, 0.796894f, + 1.000000f, 0.999405f, 0.989238f, 0.951276f, 0.904877f, 0.880987f, 0.874630f, 0.872074f, 0.865948f, 0.854019f, 0.836327f, 0.813747f, 0.787361f, 0.758246f, 0.727412f, 0.695734f, + 1.000000f, 0.999737f, 0.995312f, 0.975285f, 0.935633f, 0.895869f, 0.869876f, 0.853742f, 0.839276f, 0.821353f, 0.798151f, 0.769798f, 0.737350f, 0.702173f, 0.665661f, 0.629043f, + 1.000000f, 0.999850f, 0.997379f, 0.985625f, 0.956883f, 0.916759f, 0.879558f, 0.850506f, 0.825820f, 0.800359f, 0.771144f, 0.737499f, 0.700220f, 0.660799f, 0.620820f, 0.581736f, + 1.000000f, 0.999902f, 0.998306f, 0.990638f, 0.969902f, 0.934739f, 0.893834f, 0.855594f, 0.821126f, 0.787404f, 0.751594f, 0.712639f, 0.671124f, 0.628474f, 0.586340f, 0.546124f, + 1.000000f, 0.999930f, 0.998796f, 0.993357f, 0.977898f, 0.948353f, 0.908039f, 0.864468f, 0.821839f, 0.779918f, 0.737104f, 0.692614f, 0.646983f, 0.601522f, 0.557744f, 0.516844f, + 1.000000f, 0.999946f, 0.999083f, 0.994962f, 0.982947f, 0.958178f, 0.920299f, 0.874253f, 0.825298f, 0.775678f, 0.725608f, 0.675136f, 0.624987f, 0.576365f, 0.530474f, 0.488210f, + 1.000000f, 0.999956f, 0.999261f, 0.995963f, 0.986220f, 0.965139f, 0.930136f, 0.883416f, 0.829854f, 0.773384f, 0.716136f, 0.659351f, 0.604123f, 0.551503f, 0.502397f, 0.457343f, + 1.000000f, 0.999963f, 0.999381f, 0.996624f, 0.988423f, 0.970106f, 0.937845f, 0.891629f, 0.835197f, 0.773425f, 0.710114f, 0.647711f, 0.587740f, 0.531184f, 0.478705f, 0.430616f, + 1.000000f, 0.999968f, 0.999464f, 0.997068f, 0.989893f, 0.973513f, 0.943505f, 0.898286f, 0.840457f, 0.775113f, 0.707123f, 0.639883f, 0.575385f, 0.514719f, 0.458478f, 0.406970f, + 1.000000f, 0.999971f, 0.999518f, 0.997342f, 0.990741f, 0.975475f, 0.947004f, 0.903070f, 0.845362f, 0.778426f, 0.707289f, 0.635853f, 0.566724f, 0.501440f, 0.440912f, 0.385604f, + 1.000000f, 0.999974f, 0.999544f, 0.997381f, 0.990696f, 0.975518f, 0.948161f, 0.906540f, 0.851004f, 0.784431f, 0.711198f, 0.635679f, 0.561400f, 0.490787f, 0.425353f, 0.365921f, + 1.000000f, 0.999971f, 0.999304f, 0.995978f, 0.988280f, 0.974075f, 0.950003f, 0.912685f, 0.860537f, 0.794859f, 0.719504f, 0.639410f, 0.559229f, 0.482529f, 0.411669f, 0.347942f, + 1.000000f, 0.999974f, 0.999565f, 0.997708f, 0.992443f, 0.980948f, 0.959813f, 0.925528f, 0.875653f, 0.810248f, 0.732357f, 0.647157f, 0.560340f, 0.476823f, 0.400035f, 0.331897f, + 1.000000f, 0.999980f, 0.999676f, 0.998305f, 0.994391f, 0.985550f, 0.968368f, 0.938734f, 0.892932f, 0.829321f, 0.749688f, 0.659212f, 0.564921f, 0.473581f, 0.390180f, 0.317446f, + + 1.000000f, 0.995284f, 0.998804f, 0.999444f, 0.999649f, 0.999720f, 0.999733f, 0.999714f, 0.999674f, 0.999618f, 0.999548f, 0.999468f, 0.999377f, 0.999277f, 0.999169f, 0.999053f, + 1.000000f, 0.997511f, 0.960289f, 0.901005f, 0.888885f, 0.900363f, 0.911663f, 0.916803f, 0.915736f, 0.909530f, 0.899242f, 0.885721f, 0.869663f, 0.851634f, 0.832099f, 0.811466f, + 1.000000f, 0.999404f, 0.989232f, 0.951270f, 0.904948f, 0.881357f, 0.875662f, 0.874199f, 0.869582f, 0.859498f, 0.843900f, 0.823539f, 0.799383f, 0.772396f, 0.743448f, 0.713338f, + 1.000000f, 0.999736f, 0.995304f, 0.975264f, 0.935642f, 0.896072f, 0.870612f, 0.855492f, 0.842579f, 0.826666f, 0.805776f, 0.779833f, 0.749653f, 0.716403f, 0.681265f, 0.645355f, + 1.000000f, 0.999849f, 0.997370f, 0.985595f, 0.956856f, 0.916856f, 0.880077f, 0.851914f, 0.828681f, 0.805175f, 0.778204f, 0.746802f, 0.711421f, 0.673228f, 0.633628f, 0.593933f, + 1.000000f, 0.999901f, 0.998296f, 0.990603f, 0.969847f, 0.934766f, 0.894195f, 0.856719f, 0.823539f, 0.791566f, 0.757680f, 0.720436f, 0.679984f, 0.637406f, 0.594174f, 0.551717f, + 1.000000f, 0.999929f, 0.998784f, 0.993309f, 0.977807f, 0.948280f, 0.908200f, 0.865216f, 0.823601f, 0.782972f, 0.741355f, 0.697452f, 0.651329f, 0.604006f, 0.556943f, 0.511515f, + 1.000000f, 0.999945f, 0.999070f, 0.994912f, 0.982853f, 0.958118f, 0.920485f, 0.875042f, 0.827032f, 0.778447f, 0.728966f, 0.678055f, 0.625944f, 0.573684f, 0.522641f, 0.474050f, + 1.000000f, 0.999956f, 0.999251f, 0.995932f, 0.986200f, 0.965274f, 0.930739f, 0.884939f, 0.832635f, 0.777366f, 0.720585f, 0.662901f, 0.605062f, 0.548168f, 0.493456f, 0.441994f, + 1.000000f, 0.999962f, 0.999373f, 0.996618f, 0.988491f, 0.970487f, 0.938987f, 0.894031f, 0.839138f, 0.778529f, 0.715265f, 0.651254f, 0.587957f, 0.526632f, 0.468422f, 0.414199f, + 1.000000f, 0.999968f, 0.999462f, 0.997093f, 0.990092f, 0.974273f, 0.945421f, 0.901867f, 0.845664f, 0.781073f, 0.712340f, 0.642651f, 0.574201f, 0.508557f, 0.446828f, 0.389860f, + 1.000000f, 0.999971f, 0.999524f, 0.997429f, 0.991210f, 0.976951f, 0.950194f, 0.908174f, 0.851673f, 0.784555f, 0.711642f, 0.637052f, 0.563754f, 0.493742f, 0.428379f, 0.368565f, + 1.000000f, 0.999975f, 0.999569f, 0.997647f, 0.991870f, 0.978507f, 0.953171f, 0.912734f, 0.857072f, 0.789157f, 0.713541f, 0.634828f, 0.556787f, 0.482180f, 0.412907f, 0.350140f, + 1.000000f, 0.999977f, 0.999582f, 0.997604f, 0.991564f, 0.978111f, 0.953898f, 0.916014f, 0.863007f, 0.796031f, 0.718779f, 0.636196f, 0.553097f, 0.473399f, 0.399812f, 0.333928f, + 1.000000f, 0.999955f, 0.999237f, 0.996489f, 0.990324f, 0.978430f, 0.957354f, 0.923234f, 0.873265f, 0.807238f, 0.728095f, 0.641110f, 0.552257f, 0.466791f, 0.388451f, 0.319337f, + 1.000000f, 0.999980f, 0.999676f, 0.998299f, 0.994349f, 0.985351f, 0.967719f, 0.937130f, 0.889763f, 0.824107f, 0.742285f, 0.649870f, 0.554162f, 0.462036f, 0.378442f, 0.305989f, + + 1.000000f, 0.995284f, 0.998804f, 0.999446f, 0.999652f, 0.999725f, 0.999740f, 0.999724f, 0.999687f, 0.999634f, 0.999568f, 0.999492f, 0.999406f, 0.999311f, 0.999208f, 0.999098f, + 1.000000f, 0.997511f, 0.960284f, 0.901003f, 0.888942f, 0.900590f, 0.912189f, 0.917748f, 0.917206f, 0.911615f, 0.902013f, 0.889241f, 0.873977f, 0.856768f, 0.838075f, 0.818279f, + 1.000000f, 0.999403f, 0.989226f, 0.951247f, 0.904929f, 0.881422f, 0.875975f, 0.874958f, 0.870990f, 0.861727f, 0.847075f, 0.827739f, 0.804628f, 0.778648f, 0.750639f, 0.721328f, + 1.000000f, 0.999735f, 0.995295f, 0.975231f, 0.935580f, 0.896025f, 0.870709f, 0.855938f, 0.843609f, 0.828504f, 0.808588f, 0.783681f, 0.754503f, 0.722104f, 0.687576f, 0.651942f, + 1.000000f, 0.999848f, 0.997360f, 0.985556f, 0.956763f, 0.916724f, 0.879989f, 0.852036f, 0.829234f, 0.806371f, 0.780182f, 0.749567f, 0.714816f, 0.676938f, 0.637197f, 0.596804f, + 1.000000f, 0.999900f, 0.998284f, 0.990550f, 0.969710f, 0.934519f, 0.893858f, 0.856387f, 0.823348f, 0.791625f, 0.757994f, 0.720839f, 0.680069f, 0.636588f, 0.591729f, 0.546835f, + 1.000000f, 0.999928f, 0.998773f, 0.993263f, 0.977688f, 0.948075f, 0.907943f, 0.865013f, 0.823579f, 0.783224f, 0.741798f, 0.697762f, 0.650887f, 0.601974f, 0.552381f, 0.503517f, + 1.000000f, 0.999945f, 0.999062f, 0.994881f, 0.982790f, 0.958040f, 0.920489f, 0.875301f, 0.827751f, 0.779733f, 0.730697f, 0.679770f, 0.626870f, 0.572826f, 0.518979f, 0.466743f, + 1.000000f, 0.999955f, 0.999246f, 0.995916f, 0.986184f, 0.965323f, 0.931015f, 0.885691f, 0.834125f, 0.779686f, 0.723524f, 0.665834f, 0.607019f, 0.548073f, 0.490339f, 0.435150f, + 1.000000f, 0.999962f, 0.999373f, 0.996619f, 0.988535f, 0.970697f, 0.939609f, 0.895401f, 0.841545f, 0.782010f, 0.719433f, 0.655283f, 0.590734f, 0.527088f, 0.465722f, 0.407904f, + 1.000000f, 0.999968f, 0.999463f, 0.997115f, 0.990219f, 0.974709f, 0.946527f, 0.904071f, 0.849246f, 0.785904f, 0.717781f, 0.647661f, 0.577649f, 0.509486f, 0.444684f, 0.384456f, + 1.000000f, 0.999971f, 0.999528f, 0.997475f, 0.991437f, 0.977692f, 0.951962f, 0.911448f, 0.856566f, 0.790615f, 0.717942f, 0.642489f, 0.567318f, 0.494773f, 0.426595f, 0.364046f, + 1.000000f, 0.999975f, 0.999578f, 0.997733f, 0.992296f, 0.979810f, 0.955974f, 0.917293f, 0.863025f, 0.795639f, 0.719578f, 0.639531f, 0.559508f, 0.482585f, 0.410973f, 0.346112f, + 1.000000f, 0.999977f, 0.999610f, 0.997884f, 0.992738f, 0.980875f, 0.958232f, 0.921269f, 0.868446f, 0.801055f, 0.722874f, 0.638931f, 0.554163f, 0.472686f, 0.397447f, 0.330196f, + 1.000000f, 0.999978f, 0.999565f, 0.997403f, 0.991432f, 0.979516f, 0.958528f, 0.924585f, 0.874704f, 0.808512f, 0.728875f, 0.641091f, 0.551264f, 0.464814f, 0.385631f, 0.315904f, + 1.000000f, 0.999980f, 0.999676f, 0.998292f, 0.994295f, 0.985125f, 0.967084f, 0.935829f, 0.887676f, 0.821316f, 0.739011f, 0.646348f, 0.550586f, 0.458535f, 0.375096f, 0.302843f, + + 1.000000f, 0.995284f, 0.998805f, 0.999446f, 0.999652f, 0.999726f, 0.999742f, 0.999726f, 0.999690f, 0.999638f, 0.999573f, 0.999497f, 0.999412f, 0.999319f, 0.999217f, 0.999109f, + 1.000000f, 0.997511f, 0.960278f, 0.900983f, 0.888916f, 0.900587f, 0.912250f, 0.917908f, 0.917495f, 0.912056f, 0.902622f, 0.890032f, 0.874957f, 0.857948f, 0.839453f, 0.819858f, + 1.000000f, 0.999403f, 0.989217f, 0.951216f, 0.904855f, 0.881312f, 0.875855f, 0.874881f, 0.871011f, 0.861890f, 0.847414f, 0.828269f, 0.805342f, 0.779535f, 0.751654f, 0.722409f, + 1.000000f, 0.999735f, 0.995287f, 0.975194f, 0.935480f, 0.895835f, 0.870421f, 0.855571f, 0.843205f, 0.828107f, 0.808210f, 0.783319f, 0.754116f, 0.721610f, 0.686849f, 0.650834f, + 1.000000f, 0.999848f, 0.997350f, 0.985508f, 0.956627f, 0.916439f, 0.879490f, 0.851287f, 0.828198f, 0.805024f, 0.778469f, 0.747390f, 0.712022f, 0.673310f, 0.632463f, 0.590663f, + 1.000000f, 0.999900f, 0.998276f, 0.990513f, 0.969612f, 0.934314f, 0.893516f, 0.855889f, 0.822696f, 0.790800f, 0.756946f, 0.719429f, 0.678072f, 0.633700f, 0.587564f, 0.540993f, + 1.000000f, 0.999928f, 0.998768f, 0.993241f, 0.977633f, 0.947976f, 0.907810f, 0.864886f, 0.823513f, 0.783251f, 0.741884f, 0.697761f, 0.650515f, 0.600848f, 0.550036f, 0.499480f, + 1.000000f, 0.999945f, 0.999060f, 0.994873f, 0.982777f, 0.958041f, 0.920561f, 0.875536f, 0.828257f, 0.780592f, 0.731891f, 0.681116f, 0.628018f, 0.573302f, 0.518254f, 0.464324f, + 1.000000f, 0.999955f, 0.999247f, 0.995921f, 0.986211f, 0.965426f, 0.931295f, 0.886306f, 0.835243f, 0.781429f, 0.725868f, 0.668540f, 0.609650f, 0.550059f, 0.491114f, 0.434261f, + 1.000000f, 0.999962f, 0.999374f, 0.996629f, 0.988590f, 0.970879f, 0.940076f, 0.896375f, 0.843261f, 0.784609f, 0.722845f, 0.659190f, 0.594586f, 0.530250f, 0.467640f, 0.408199f, + 1.000000f, 0.999968f, 0.999465f, 0.997128f, 0.990290f, 0.974955f, 0.947163f, 0.905388f, 0.851522f, 0.789266f, 0.722065f, 0.652422f, 0.582245f, 0.513266f, 0.447157f, 0.385363f, + 1.000000f, 0.999972f, 0.999530f, 0.997493f, 0.991538f, 0.978036f, 0.952836f, 0.913211f, 0.859501f, 0.794737f, 0.722931f, 0.647753f, 0.572188f, 0.498666f, 0.429163f, 0.365186f, + 1.000000f, 0.999975f, 0.999580f, 0.997764f, 0.992463f, 0.980361f, 0.957300f, 0.919782f, 0.866810f, 0.800499f, 0.724974f, 0.644830f, 0.564130f, 0.486139f, 0.413298f, 0.347228f, + 1.000000f, 0.999977f, 0.999617f, 0.997960f, 0.993118f, 0.982006f, 0.960566f, 0.924916f, 0.873094f, 0.806184f, 0.727943f, 0.643492f, 0.557922f, 0.475485f, 0.399271f, 0.331161f, + 1.000000f, 0.999979f, 0.999637f, 0.998017f, 0.993219f, 0.982367f, 0.961927f, 0.928184f, 0.878334f, 0.812034f, 0.732125f, 0.643915f, 0.553566f, 0.466563f, 0.386869f, 0.316698f, + 1.000000f, 0.999980f, 0.999675f, 0.998280f, 0.994216f, 0.984850f, 0.966503f, 0.935014f, 0.886874f, 0.820774f, 0.738841f, 0.646535f, 0.551042f, 0.459158f, 0.375796f, 0.303554f, + + 1.000000f, 0.995284f, 0.998804f, 0.999446f, 0.999652f, 0.999725f, 0.999741f, 0.999725f, 0.999687f, 0.999635f, 0.999569f, 0.999493f, 0.999407f, 0.999312f, 0.999210f, 0.999100f, + 1.000000f, 0.997510f, 0.960272f, 0.900957f, 0.888850f, 0.900465f, 0.912056f, 0.917636f, 0.917129f, 0.911583f, 0.902026f, 0.889301f, 0.874076f, 0.856904f, 0.838235f, 0.818452f, + 1.000000f, 0.999403f, 0.989210f, 0.951184f, 0.904763f, 0.881115f, 0.875512f, 0.874354f, 0.870268f, 0.860899f, 0.846149f, 0.826693f, 0.803430f, 0.777250f, 0.748961f, 0.719274f, + 1.000000f, 0.999734f, 0.995279f, 0.975155f, 0.935366f, 0.895578f, 0.869943f, 0.854786f, 0.842031f, 0.826459f, 0.806013f, 0.780495f, 0.750587f, 0.717288f, 0.681647f, 0.644646f, + 1.000000f, 0.999848f, 0.997346f, 0.985485f, 0.956561f, 0.916289f, 0.879212f, 0.850822f, 0.827497f, 0.804019f, 0.777098f, 0.745565f, 0.709663f, 0.670316f, 0.628717f, 0.586038f, + 1.000000f, 0.999900f, 0.998275f, 0.990505f, 0.969587f, 0.934262f, 0.893425f, 0.855747f, 0.822486f, 0.790499f, 0.756509f, 0.718790f, 0.677140f, 0.632349f, 0.585661f, 0.538386f, + 1.000000f, 0.999928f, 0.998768f, 0.993243f, 0.977639f, 0.947997f, 0.907867f, 0.865006f, 0.823723f, 0.783570f, 0.742296f, 0.698204f, 0.650885f, 0.600994f, 0.549785f, 0.498656f, + 1.000000f, 0.999945f, 0.999060f, 0.994877f, 0.982795f, 0.958102f, 0.920709f, 0.875837f, 0.828783f, 0.781397f, 0.732985f, 0.682444f, 0.629450f, 0.574646f, 0.519295f, 0.464849f, + 1.000000f, 0.999955f, 0.999247f, 0.995925f, 0.986233f, 0.965502f, 0.931491f, 0.886717f, 0.835982f, 0.782584f, 0.727470f, 0.670523f, 0.611850f, 0.552237f, 0.493010f, 0.435639f, + 1.000000f, 0.999962f, 0.999374f, 0.996634f, 0.988615f, 0.970969f, 0.940313f, 0.896884f, 0.844187f, 0.786070f, 0.724876f, 0.661700f, 0.597367f, 0.533012f, 0.470085f, 0.410101f, + 1.000000f, 0.999968f, 0.999465f, 0.997134f, 0.990322f, 0.975066f, 0.947455f, 0.906016f, 0.852661f, 0.791049f, 0.724510f, 0.655390f, 0.585463f, 0.516409f, 0.449926f, 0.387555f, + 1.000000f, 0.999971f, 0.999531f, 0.997501f, 0.991579f, 0.978183f, 0.953219f, 0.914022f, 0.860936f, 0.796914f, 0.725810f, 0.651119f, 0.575713f, 0.502010f, 0.432062f, 0.367489f, + 1.000000f, 0.999975f, 0.999581f, 0.997776f, 0.992527f, 0.980582f, 0.957862f, 0.920918f, 0.868711f, 0.803199f, 0.728318f, 0.648503f, 0.567789f, 0.489490f, 0.416147f, 0.349507f, + 1.000000f, 0.999977f, 0.999620f, 0.997986f, 0.993247f, 0.982427f, 0.961553f, 0.926709f, 0.875746f, 0.809518f, 0.731656f, 0.647247f, 0.561449f, 0.478611f, 0.401907f, 0.333308f, + 1.000000f, 0.999979f, 0.999648f, 0.998134f, 0.993732f, 0.983669f, 0.964160f, 0.931158f, 0.881732f, 0.815571f, 0.735600f, 0.647188f, 0.556541f, 0.469195f, 0.389144f, 0.318641f, + 1.000000f, 0.999980f, 0.999673f, 0.998257f, 0.994093f, 0.984576f, 0.966265f, 0.935152f, 0.887595f, 0.822055f, 0.740532f, 0.648457f, 0.553048f, 0.461141f, 0.377688f, 0.305312f, + + 1.000000f, 0.995284f, 0.998804f, 0.999445f, 0.999651f, 0.999724f, 0.999739f, 0.999722f, 0.999684f, 0.999630f, 0.999563f, 0.999485f, 0.999398f, 0.999302f, 0.999198f, 0.999086f, + 1.000000f, 0.997510f, 0.960267f, 0.900933f, 0.888781f, 0.900318f, 0.911801f, 0.917239f, 0.916567f, 0.910833f, 0.901062f, 0.888105f, 0.872627f, 0.855182f, 0.836220f, 0.816125f, + 1.000000f, 0.999402f, 0.989206f, 0.951160f, 0.904689f, 0.880944f, 0.875182f, 0.873804f, 0.869439f, 0.859739f, 0.844607f, 0.824729f, 0.801003f, 0.774321f, 0.745496f, 0.715236f, + 1.000000f, 0.999734f, 0.995278f, 0.975147f, 0.935339f, 0.895510f, 0.869798f, 0.854523f, 0.841602f, 0.825821f, 0.805121f, 0.779311f, 0.749073f, 0.715413f, 0.679387f, 0.641971f, + 1.000000f, 0.999848f, 0.997346f, 0.985485f, 0.956559f, 0.916282f, 0.879189f, 0.850766f, 0.827382f, 0.803814f, 0.776771f, 0.745088f, 0.708998f, 0.669438f, 0.627598f, 0.584655f, + 1.000000f, 0.999900f, 0.998275f, 0.990506f, 0.969593f, 0.934278f, 0.893458f, 0.855801f, 0.822559f, 0.790580f, 0.756578f, 0.718819f, 0.677102f, 0.632212f, 0.585386f, 0.537943f, + 1.000000f, 0.999928f, 0.998768f, 0.993244f, 0.977646f, 0.948020f, 0.907922f, 0.865112f, 0.823896f, 0.783820f, 0.742617f, 0.698579f, 0.651280f, 0.601369f, 0.550088f, 0.498847f, + 1.000000f, 0.999945f, 0.999060f, 0.994879f, 0.982802f, 0.958127f, 0.920774f, 0.875972f, 0.829021f, 0.781764f, 0.733493f, 0.683077f, 0.630174f, 0.575404f, 0.520024f, 0.465484f, + 1.000000f, 0.999955f, 0.999247f, 0.995927f, 0.986241f, 0.965530f, 0.931565f, 0.886875f, 0.836271f, 0.783048f, 0.728128f, 0.671370f, 0.612838f, 0.553298f, 0.494056f, 0.436595f, + 1.000000f, 0.999962f, 0.999375f, 0.996635f, 0.988624f, 0.971000f, 0.940397f, 0.897068f, 0.844529f, 0.786627f, 0.725678f, 0.662737f, 0.598585f, 0.534315f, 0.471376f, 0.411283f, + 1.000000f, 0.999968f, 0.999465f, 0.997136f, 0.990333f, 0.975103f, 0.947555f, 0.906236f, 0.853072f, 0.791717f, 0.725468f, 0.656617f, 0.586883f, 0.517912f, 0.451388f, 0.388886f, + 1.000000f, 0.999972f, 0.999531f, 0.997504f, 0.991593f, 0.978230f, 0.953348f, 0.914303f, 0.861452f, 0.797735f, 0.726957f, 0.652547f, 0.577323f, 0.503668f, 0.433644f, 0.368907f, + 1.000000f, 0.999975f, 0.999582f, 0.997780f, 0.992547f, 0.980652f, 0.958047f, 0.921309f, 0.869402f, 0.804249f, 0.729712f, 0.650157f, 0.569569f, 0.491256f, 0.417789f, 0.350958f, + 1.000000f, 0.999977f, 0.999620f, 0.997993f, 0.993284f, 0.982553f, 0.961871f, 0.927340f, 0.876772f, 0.810939f, 0.733379f, 0.649135f, 0.563353f, 0.480418f, 0.403550f, 0.334740f, + 1.000000f, 0.999979f, 0.999651f, 0.998159f, 0.993858f, 0.984047f, 0.964963f, 0.932452f, 0.883441f, 0.817541f, 0.737667f, 0.649219f, 0.558458f, 0.470943f, 0.390703f, 0.320005f, + 1.000000f, 0.999980f, 0.999668f, 0.998199f, 0.993985f, 0.984715f, 0.966955f, 0.936405f, 0.889231f, 0.823875f, 0.742384f, 0.650248f, 0.554726f, 0.462681f, 0.379081f, 0.306563f, + + 1.000000f, 0.995284f, 0.998804f, 0.999445f, 0.999650f, 0.999723f, 0.999738f, 0.999720f, 0.999682f, 0.999627f, 0.999560f, 0.999482f, 0.999394f, 0.999297f, 0.999192f, 0.999079f, + 1.000000f, 0.997510f, 0.960266f, 0.900925f, 0.888755f, 0.900262f, 0.911700f, 0.917082f, 0.916341f, 0.910526f, 0.900670f, 0.887614f, 0.872031f, 0.854471f, 0.835387f, 0.815164f, + 1.000000f, 0.999402f, 0.989206f, 0.951159f, 0.904685f, 0.880930f, 0.875151f, 0.873744f, 0.869339f, 0.859591f, 0.844401f, 0.824460f, 0.800665f, 0.773907f, 0.745002f, 0.714660f, + 1.000000f, 0.999734f, 0.995278f, 0.975148f, 0.935340f, 0.895509f, 0.869794f, 0.854510f, 0.841571f, 0.825764f, 0.805031f, 0.779183f, 0.748902f, 0.715194f, 0.679117f, 0.641650f, + 1.000000f, 0.999848f, 0.997346f, 0.985485f, 0.956560f, 0.916285f, 0.879193f, 0.850771f, 0.827383f, 0.803807f, 0.776749f, 0.745046f, 0.708931f, 0.669342f, 0.627471f, 0.584496f, + 1.000000f, 0.999900f, 0.998275f, 0.990507f, 0.969594f, 0.934282f, 0.893466f, 0.855814f, 0.822578f, 0.790603f, 0.756600f, 0.718837f, 0.677111f, 0.632207f, 0.585365f, 0.537902f, + 1.000000f, 0.999928f, 0.998768f, 0.993244f, 0.977647f, 0.948023f, 0.907931f, 0.865129f, 0.823926f, 0.783862f, 0.742672f, 0.698642f, 0.651347f, 0.601434f, 0.550148f, 0.498895f, + 1.000000f, 0.999945f, 0.999060f, 0.994879f, 0.982803f, 0.958131f, 0.920784f, 0.875992f, 0.829057f, 0.781821f, 0.733571f, 0.683176f, 0.630288f, 0.575529f, 0.520149f, 0.465605f, + 1.000000f, 0.999955f, 0.999247f, 0.995927f, 0.986242f, 0.965534f, 0.931575f, 0.886898f, 0.836313f, 0.783116f, 0.728228f, 0.671499f, 0.612995f, 0.553471f, 0.494235f, 0.436771f, + 1.000000f, 0.999962f, 0.999375f, 0.996636f, 0.988625f, 0.971005f, 0.940409f, 0.897095f, 0.844579f, 0.786709f, 0.725799f, 0.662898f, 0.598779f, 0.534532f, 0.471600f, 0.411502f, + 1.000000f, 0.999968f, 0.999465f, 0.997137f, 0.990334f, 0.975108f, 0.947569f, 0.906268f, 0.853132f, 0.791816f, 0.725613f, 0.656809f, 0.587115f, 0.518167f, 0.451652f, 0.389139f, + 1.000000f, 0.999972f, 0.999531f, 0.997504f, 0.991595f, 0.978237f, 0.953366f, 0.914343f, 0.861527f, 0.797858f, 0.727135f, 0.652779f, 0.577593f, 0.503960f, 0.433938f, 0.369185f, + 1.000000f, 0.999975f, 0.999582f, 0.997781f, 0.992550f, 0.980661f, 0.958072f, 0.921364f, 0.869504f, 0.804411f, 0.729938f, 0.650437f, 0.569884f, 0.491585f, 0.418109f, 0.351255f, + 1.000000f, 0.999977f, 0.999620f, 0.997994f, 0.993289f, 0.982570f, 0.961917f, 0.927431f, 0.876930f, 0.811170f, 0.733679f, 0.649480f, 0.563719f, 0.480779f, 0.403887f, 0.335045f, + 1.000000f, 0.999979f, 0.999651f, 0.998163f, 0.993872f, 0.984095f, 0.965078f, 0.932660f, 0.883746f, 0.817923f, 0.738091f, 0.649655f, 0.558875f, 0.471330f, 0.391049f, 0.320309f, + 1.000000f, 0.999980f, 0.999658f, 0.998277f, 0.994324f, 0.985318f, 0.967688f, 0.937159f, 0.889944f, 0.824522f, 0.742959f, 0.650753f, 0.555166f, 0.463063f, 0.379413f, 0.306851f +}; + +static const float table_ggx_glass_inv_Eavg[256] = { + 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, + 1.000000f, 0.999883f, 0.998571f, 0.994611f, 0.987932f, 0.979340f, 0.969124f, 0.957150f, 0.943358f, 0.927910f, 0.911111f, 0.893347f, 0.875001f, 0.856410f, 0.837886f, 0.819667f, + 1.000000f, 0.999879f, 0.998460f, 0.993636f, 0.983961f, 0.969802f, 0.952851f, 0.934658f, 0.915966f, 0.896938f, 0.877591f, 0.857980f, 0.838240f, 0.818537f, 0.799061f, 0.779987f, + 1.000000f, 0.999877f, 0.998430f, 0.993345f, 0.982442f, 0.964923f, 0.941902f, 0.915671f, 0.888444f, 0.861595f, 0.835705f, 0.810866f, 0.787027f, 0.764116f, 0.742069f, 0.720883f, + 1.000000f, 0.999876f, 0.998425f, 0.993276f, 0.981921f, 0.962787f, 0.936011f, 0.903450f, 0.867828f, 0.831654f, 0.796632f, 0.763575f, 0.732728f, 0.704029f, 0.677271f, 0.652272f, + 1.000000f, 0.999877f, 0.998435f, 0.993313f, 0.981879f, 0.962128f, 0.933439f, 0.896895f, 0.854943f, 0.810510f, 0.766198f, 0.723791f, 0.684211f, 0.647805f, 0.614506f, 0.584089f, + 1.000000f, 0.999877f, 0.998450f, 0.993399f, 0.982078f, 0.962279f, 0.932879f, 0.894276f, 0.848326f, 0.797836f, 0.745795f, 0.694724f, 0.646345f, 0.601608f, 0.560861f, 0.524053f, + 1.000000f, 0.999878f, 0.998470f, 0.993509f, 0.982397f, 0.962854f, 0.933472f, 0.894132f, 0.846118f, 0.791843f, 0.734286f, 0.676340f, 0.620361f, 0.567934f, 0.519922f, 0.476637f, + 1.000000f, 0.999879f, 0.998491f, 0.993625f, 0.982756f, 0.963613f, 0.934645f, 0.895397f, 0.846683f, 0.790470f, 0.729520f, 0.666816f, 0.605085f, 0.546425f, 0.492207f, 0.443121f, + 1.000000f, 0.999880f, 0.998512f, 0.993737f, 0.983113f, 0.964411f, 0.936030f, 0.897312f, 0.848722f, 0.791863f, 0.729200f, 0.663653f, 0.598087f, 0.534951f, 0.475998f, 0.422303f, + 1.000000f, 0.999881f, 0.998529f, 0.993838f, 0.983432f, 0.965152f, 0.937379f, 0.899354f, 0.851322f, 0.794586f, 0.731348f, 0.664390f, 0.596615f, 0.530632f, 0.468483f, 0.411497f, + 1.000000f, 0.999882f, 0.998544f, 0.993921f, 0.983702f, 0.965776f, 0.938551f, 0.901202f, 0.853839f, 0.797572f, 0.734403f, 0.666974f, 0.598137f, 0.530590f, 0.466524f, 0.407467f, + 1.000000f, 0.999883f, 0.998556f, 0.993986f, 0.983909f, 0.966256f, 0.939459f, 0.902655f, 0.855886f, 0.800135f, 0.737288f, 0.669858f, 0.600660f, 0.532400f, 0.467352f, 0.407150f, + 1.000000f, 0.999883f, 0.998565f, 0.994033f, 0.984050f, 0.966579f, 0.940057f, 0.903620f, 0.857258f, 0.801907f, 0.739358f, 0.672075f, 0.602828f, 0.534326f, 0.468867f, 0.408146f, + 1.000000f, 0.999883f, 0.998570f, 0.994058f, 0.984128f, 0.966748f, 0.940358f, 0.904091f, 0.857927f, 0.802767f, 0.740383f, 0.673205f, 0.603988f, 0.535434f, 0.469853f, 0.408957f, + 1.000000f, 0.999883f, 0.998572f, 0.994065f, 0.984146f, 0.966784f, 0.940421f, 0.904186f, 0.858056f, 0.802932f, 0.740578f, 0.673420f, 0.604211f, 0.535654f, 0.470057f, 0.409136f +}; + +CCL_NAMESPACE_END diff --git a/intern/cycles/scene/shader_nodes.cpp b/intern/cycles/scene/shader_nodes.cpp index 4064bb29207..9b84222a8b7 100644 --- a/intern/cycles/scene/shader_nodes.cpp +++ b/intern/cycles/scene/shader_nodes.cpp @@ -2350,7 +2350,7 @@ NODE_DEFINE(GlossyBsdfNode) distribution_enum.insert("beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_ID); distribution_enum.insert("ggx", CLOSURE_BSDF_MICROFACET_GGX_ID); distribution_enum.insert("ashikhmin_shirley", CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID); - distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID); + distribution_enum.insert("multi_ggx", CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID); SOCKET_ENUM(distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_ID); SOCKET_IN_VECTOR(tangent, "Tangent", zero_float3(), SocketType::LINK_TANGENT); @@ -2444,6 +2444,7 @@ void GlossyBsdfNode::compile(SVMCompiler &compiler) if (closure == CLOSURE_BSDF_REFLECTION_ID) BsdfNode::compile(compiler, NULL, NULL); + /* TODO: Just use weight for legacy MultiGGX? Would also simplify OSL. */ else if (closure == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID) BsdfNode::compile( compiler, input("Roughness"), input("Anisotropy"), input("Rotation"), input("Color")); @@ -2471,7 +2472,7 @@ NODE_DEFINE(GlassBsdfNode) distribution_enum.insert("sharp", CLOSURE_BSDF_SHARP_GLASS_ID); distribution_enum.insert("beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID); distribution_enum.insert("ggx", CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID); - distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID); + distribution_enum.insert("multi_ggx", CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID); SOCKET_ENUM( distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID); SOCKET_IN_FLOAT(roughness, "Roughness", 0.0f); @@ -2749,8 +2750,8 @@ NODE_DEFINE(PrincipledBsdfNode) NodeType *type = NodeType::add("principled_bsdf", create, NodeType::SHADER); static NodeEnum distribution_enum; - distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID); - distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID); + distribution_enum.insert("ggx", CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID); + distribution_enum.insert("multi_ggx", CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID); SOCKET_ENUM( distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID); diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 4646f949413..34f79a80103 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -4752,8 +4752,8 @@ static const EnumPropertyItem node_glossy_items[] = { "MULTI_GGX", 0, "Multiscatter GGX", - "Slower than GGX but gives a more energy conserving results, which would otherwise be " - "visible as excessive darkening"}, + "GGX with additional correction to account for multiple scattering, preserve energy and " + "prevent unexpected darkening at high roughness"}, {0, NULL, 0, NULL, NULL}, }; @@ -4764,8 +4764,8 @@ static const EnumPropertyItem node_glass_items[] = { "MULTI_GGX", 0, "Multiscatter GGX", - "Slower than GGX but gives a more energy conserving results, which would otherwise be " - "visible as excessive darkening"}, + "GGX with additional correction to account for multiple scattering, preserve energy and " + "prevent unexpected darkening at high roughness"}, {0, NULL, 0, NULL, NULL}, }; -- 2.30.2 From bd2ee6b1c17aa5342a5083432b16a95811428fb6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 5 Jun 2023 10:47:37 +1000 Subject: [PATCH 52/63] Cleanup: disambiguate the term 'path' Use filepath or dirpath, unless the contents might be either, in that case note that the contents could be both. Use `rna_path*` in some cases too. --- .../blender/asset_system/AS_asset_library.h | 2 +- .../asset_system/intern/asset_identifier.cc | 7 +- .../asset_system/intern/asset_library.cc | 10 +-- .../intern/asset_library_service.cc | 24 +++---- .../asset_system/tests/asset_library_test.cc | 10 +-- source/blender/blenkernel/BKE_preferences.h | 2 +- source/blender/blenkernel/intern/appdir.c | 4 +- .../blender/blenkernel/intern/preferences.c | 17 ++--- .../intern/asset_library_reference_enum.cc | 6 +- .../editors/asset/intern/asset_list.cc | 6 +- .../blender/editors/asset/intern/asset_ops.cc | 4 +- .../blender/editors/object/object_modifier.cc | 14 ++-- .../blender/editors/physics/rigidbody_world.c | 6 +- source/blender/editors/screen/screendump.c | 8 +-- source/blender/editors/sound/sound_ops.c | 6 +- .../editors/space_buttons/buttons_ops.c | 50 ++++++------- source/blender/editors/space_clip/clip_ops.cc | 16 ++--- source/blender/editors/space_file/file_ops.c | 28 ++++---- source/blender/editors/space_file/filelist.cc | 6 +- source/blender/editors/space_file/filelist.h | 2 +- source/blender/editors/space_file/filesel.cc | 10 +-- .../blender/editors/space_graph/graph_edit.c | 10 +-- .../editors/space_script/script_edit.c | 6 +- .../editors/space_sequencer/sequencer_add.c | 8 +-- .../space_sequencer/sequencer_drag_drop.c | 4 ++ source/blender/io/alembic/ABC_alembic.h | 2 +- .../blender/io/alembic/intern/alembic_capi.cc | 26 +++---- .../io/usd/intern/usd_writer_material.cc | 18 ++--- .../wavefront_obj/exporter/obj_export_mtl.cc | 10 +-- source/blender/makesdna/DNA_userdef_types.h | 4 +- .../blender/makesdna/intern/dna_rename_defs.h | 1 + .../intern/rna_gpencil_legacy_modifier.c | 12 ++-- .../blender/makesrna/intern/rna_sequencer.c | 35 +++++----- source/blender/makesrna/intern/rna_tracking.c | 8 ++- source/blender/makesrna/intern/rna_userdef.c | 1 + source/blender/sequencer/SEQ_add.h | 3 +- source/blender/sequencer/intern/disk_cache.c | 56 ++++++++------- source/blender/sequencer/intern/effects.c | 8 +-- source/blender/sequencer/intern/proxy.c | 13 ++-- source/blender/sequencer/intern/strip_add.c | 17 ++--- .../windowmanager/intern/wm_files_link.c | 70 +++++++++---------- .../windowmanager/intern/wm_operators.c | 8 +-- 42 files changed, 287 insertions(+), 271 deletions(-) diff --git a/source/blender/asset_system/AS_asset_library.h b/source/blender/asset_system/AS_asset_library.h index 64bacec6f38..0127b4c6b99 100644 --- a/source/blender/asset_system/AS_asset_library.h +++ b/source/blender/asset_system/AS_asset_library.h @@ -33,7 +33,7 @@ void AS_asset_libraries_exit(void); * * To get the in-memory-only "current file" asset library, pass an empty path. */ -struct AssetLibrary *AS_asset_library_load(const char *name, const char *library_path); +struct AssetLibrary *AS_asset_library_load(const char *name, const char *library_dirpath); /** Look up the asset's catalog and copy its simple name into #asset_data. */ void AS_asset_library_refresh_catalog_simplename(struct AssetLibrary *asset_library, diff --git a/source/blender/asset_system/intern/asset_identifier.cc b/source/blender/asset_system/intern/asset_identifier.cc index 927c2639829..8e3e292a484 100644 --- a/source/blender/asset_system/intern/asset_identifier.cc +++ b/source/blender/asset_system/intern/asset_identifier.cc @@ -31,9 +31,10 @@ StringRefNull AssetIdentifier::library_relative_identifier() const std::string AssetIdentifier::full_path() const { - char path[FILE_MAX]; - BLI_path_join(path, sizeof(path), library_root_path_->c_str(), relative_asset_path_.c_str()); - return path; + char filepath[FILE_MAX]; + BLI_path_join( + filepath, sizeof(filepath), library_root_path_->c_str(), relative_asset_path_.c_str()); + return filepath; } std::string AssetIdentifier::full_library_path() const diff --git a/source/blender/asset_system/intern/asset_library.cc b/source/blender/asset_system/intern/asset_library.cc index d0c64e3ba76..401c8166e90 100644 --- a/source/blender/asset_system/intern/asset_library.cc +++ b/source/blender/asset_system/intern/asset_library.cc @@ -45,18 +45,18 @@ asset_system::AssetLibrary *AS_asset_library_load(const Main *bmain, return service->get_asset_library(bmain, library_reference); } -::AssetLibrary *AS_asset_library_load(const char *name, const char *library_path) +::AssetLibrary *AS_asset_library_load(const char *name, const char *library_dirpath) { /* NOTE: Loading an asset library at this point only means loading the catalogs. * Later on this should invoke reading of asset representations too. */ AssetLibraryService *service = AssetLibraryService::get(); asset_system::AssetLibrary *lib; - if (library_path == nullptr || library_path[0] == '\0') { + if (library_dirpath == nullptr || library_dirpath[0] == '\0') { lib = service->get_asset_library_current_file(); } else { - lib = service->get_asset_library_on_disk_custom(name, library_path); + lib = service->get_asset_library_on_disk_custom(name, library_dirpath); } return reinterpret_cast<::AssetLibrary *>(lib); } @@ -79,7 +79,7 @@ std::string AS_asset_library_find_suitable_root_path_from_path( if (bUserAssetLibrary *preferences_lib = BKE_preferences_asset_library_containing_path( &U, input_path.c_str())) { - return preferences_lib->path; + return preferences_lib->dirpath; } char buffer[FILE_MAXDIR]; @@ -342,7 +342,7 @@ Vector all_valid_asset_library_refs() } int i; LISTBASE_FOREACH_INDEX (const bUserAssetLibrary *, asset_library, &U.asset_libraries, i) { - if (!BLI_is_dir(asset_library->path)) { + if (!BLI_is_dir(asset_library->dirpath)) { continue; } AssetLibraryReference library_ref{}; diff --git a/source/blender/asset_system/intern/asset_library_service.cc b/source/blender/asset_system/intern/asset_library_service.cc index 5c255a6a5f9..ef7faba7243 100644 --- a/source/blender/asset_system/intern/asset_library_service.cc +++ b/source/blender/asset_system/intern/asset_library_service.cc @@ -95,7 +95,7 @@ AssetLibrary *AssetLibraryService::get_asset_library( return nullptr; } - std::string root_path = custom_library->path; + std::string root_path = custom_library->dirpath; if (root_path.empty()) { return nullptr; } @@ -252,14 +252,14 @@ AssetLibrary *AssetLibraryService::find_loaded_on_disk_asset_library_from_name( std::string AssetLibraryService::resolve_asset_weak_reference_to_library_path( const AssetWeakReference &asset_reference) { - StringRefNull library_path; + StringRefNull library_dirpath; switch (eAssetLibraryType(asset_reference.asset_library_type)) { case ASSET_LIBRARY_CUSTOM: { bUserAssetLibrary *custom_lib = find_custom_preferences_asset_library_from_asset_weak_ref( asset_reference); if (custom_lib) { - library_path = custom_lib->path; + library_dirpath = custom_lib->dirpath; break; } @@ -271,19 +271,19 @@ std::string AssetLibraryService::resolve_asset_weak_reference_to_library_path( return ""; } - library_path = *loaded_custom_lib->root_path_; + library_dirpath = *loaded_custom_lib->root_path_; break; } case ASSET_LIBRARY_ESSENTIALS: - library_path = essentials_directory_path(); + library_dirpath = essentials_directory_path(); break; case ASSET_LIBRARY_LOCAL: case ASSET_LIBRARY_ALL: return ""; } - std::string normalized_library_path = utils::normalize_path(library_path); - return normalized_library_path; + std::string normalized_library_dirpath = utils::normalize_path(library_dirpath); + return normalized_library_dirpath; } int64_t AssetLibraryService::rfind_blendfile_extension(StringRef path) @@ -353,12 +353,12 @@ std::string AssetLibraryService::resolve_asset_weak_reference_to_full_path( return ""; } - std::string library_path = resolve_asset_weak_reference_to_library_path(asset_reference); - if (library_path.empty()) { + std::string library_dirpath = resolve_asset_weak_reference_to_library_path(asset_reference); + if (library_dirpath.empty()) { return ""; } - std::string normalized_full_path = utils::normalize_path(library_path + SEP_STR) + + std::string normalized_full_path = utils::normalize_path(library_dirpath + SEP_STR) + normalize_asset_weak_reference_relative_asset_identifier( asset_reference); @@ -443,11 +443,11 @@ std::string AssetLibraryService::root_path_from_library_ref( bUserAssetLibrary *custom_library = find_custom_asset_library_from_library_ref( library_reference); - if (!custom_library || !custom_library->path[0]) { + if (!custom_library || !custom_library->dirpath[0]) { return ""; } - return custom_library->path; + return custom_library->dirpath; } void AssetLibraryService::allocate_service_instance() diff --git a/source/blender/asset_system/tests/asset_library_test.cc b/source/blender/asset_system/tests/asset_library_test.cc index 8d35f70bd44..a14853b2aaa 100644 --- a/source/blender/asset_system/tests/asset_library_test.cc +++ b/source/blender/asset_system/tests/asset_library_test.cc @@ -43,8 +43,8 @@ TEST_F(AssetLibraryTest, AS_asset_library_load) } /* Load the asset library. */ - const std::string library_path = test_files_dir + "/" + "asset_library"; - ::AssetLibrary *library_c_ptr = AS_asset_library_load(__func__, library_path.data()); + const std::string library_dirpath = test_files_dir + "/" + "asset_library"; + ::AssetLibrary *library_c_ptr = AS_asset_library_load(__func__, library_dirpath.data()); ASSERT_NE(nullptr, library_c_ptr); /* Check that it can be cast to the C++ type and has a Catalog Service. */ @@ -70,9 +70,9 @@ TEST_F(AssetLibraryTest, load_nonexistent_directory) } /* Load the asset library. */ - const std::string library_path = test_files_dir + "/" + - "asset_library/this/subdir/does/not/exist"; - ::AssetLibrary *library_c_ptr = AS_asset_library_load(__func__, library_path.data()); + const std::string library_dirpath = test_files_dir + "/" + + "asset_library/this/subdir/does/not/exist"; + ::AssetLibrary *library_c_ptr = AS_asset_library_load(__func__, library_dirpath.data()); ASSERT_NE(nullptr, library_c_ptr); /* Check that it can be cast to the C++ type and has a Catalog Service. */ diff --git a/source/blender/blenkernel/BKE_preferences.h b/source/blender/blenkernel/BKE_preferences.h index 7b1da3a7407..5aafcf2dab8 100644 --- a/source/blender/blenkernel/BKE_preferences.h +++ b/source/blender/blenkernel/BKE_preferences.h @@ -22,7 +22,7 @@ struct bUserAssetLibrary; struct bUserAssetLibrary *BKE_preferences_asset_library_add(struct UserDef *userdef, const char *name, - const char *path) ATTR_NONNULL(1); + const char *dirpath) ATTR_NONNULL(1); /** * Unlink and free a library preference member. * \note Free's \a library itself. diff --git a/source/blender/blenkernel/intern/appdir.c b/source/blender/blenkernel/intern/appdir.c index 63d6dfd5575..7aa23efa346 100644 --- a/source/blender/blenkernel/intern/appdir.c +++ b/source/blender/blenkernel/intern/appdir.c @@ -412,8 +412,8 @@ static bool get_path_local(char *targetpath, bool BKE_appdir_app_is_portable_install(void) { /* Detect portable install by the existence of `config` folder. */ - char path[FILE_MAX]; - return get_path_local(path, sizeof(path), "config", NULL); + char dirpath[FILE_MAX]; + return get_path_local(dirpath, sizeof(dirpath), "config", NULL); } /** diff --git a/source/blender/blenkernel/intern/preferences.c b/source/blender/blenkernel/intern/preferences.c index ad867c4cb17..9a2f49d65e2 100644 --- a/source/blender/blenkernel/intern/preferences.c +++ b/source/blender/blenkernel/intern/preferences.c @@ -37,7 +37,7 @@ bUserAssetLibrary *BKE_preferences_asset_library_add(UserDef *userdef, const char *name, - const char *path) + const char *dirpath) { bUserAssetLibrary *library = MEM_callocN(sizeof(*library), "bUserAssetLibrary"); memcpy(library, DNA_struct_default_get(bUserAssetLibrary), sizeof(*library)); @@ -47,8 +47,8 @@ bUserAssetLibrary *BKE_preferences_asset_library_add(UserDef *userdef, if (name) { BKE_preferences_asset_library_name_set(userdef, library, name); } - if (path) { - STRNCPY(library->path, path); + if (dirpath) { + STRNCPY(library->dirpath, dirpath); } return library; @@ -74,9 +74,9 @@ void BKE_preferences_asset_library_name_set(UserDef *userdef, void BKE_preferences_asset_library_path_set(bUserAssetLibrary *library, const char *path) { - STRNCPY(library->path, path); - if (BLI_is_file(library->path)) { - BLI_path_parent_dir(library->path); + STRNCPY(library->dirpath, path); + if (BLI_is_file(library->dirpath)) { + BLI_path_parent_dir(library->dirpath); } } @@ -95,7 +95,7 @@ bUserAssetLibrary *BKE_preferences_asset_library_containing_path(const UserDef * const char *path) { LISTBASE_FOREACH (bUserAssetLibrary *, asset_lib_pref, &userdef->asset_libraries) { - if (BLI_path_contains(asset_lib_pref->path, path)) { + if (BLI_path_contains(asset_lib_pref->dirpath, path)) { return asset_lib_pref; } } @@ -121,7 +121,8 @@ void BKE_preferences_asset_library_default_add(UserDef *userdef) userdef, DATA_(BKE_PREFS_ASSET_LIBRARY_DEFAULT_NAME), NULL); /* Add new "Default" library under '[doc_path]/Blender/Assets'. */ - BLI_path_join(library->path, sizeof(library->path), documents_path, N_("Blender"), N_("Assets")); + BLI_path_join( + library->dirpath, sizeof(library->dirpath), documents_path, N_("Blender"), N_("Assets")); } /** \} */ diff --git a/source/blender/editors/asset/intern/asset_library_reference_enum.cc b/source/blender/editors/asset/intern/asset_library_reference_enum.cc index 0bac71f8179..f71cd7dcbe3 100644 --- a/source/blender/editors/asset/intern/asset_library_reference_enum.cc +++ b/source/blender/editors/asset/intern/asset_library_reference_enum.cc @@ -63,7 +63,7 @@ AssetLibraryReference ED_asset_library_reference_from_enum_value(int value) library.custom_library_index = -1; } else { - const bool is_valid = (user_library->name[0] && user_library->path[0]); + const bool is_valid = (user_library->name[0] && user_library->dirpath[0]); if (is_valid) { library.custom_library_index = value - ASSET_LIBRARY_CUSTOM; library.type = ASSET_LIBRARY_CUSTOM; @@ -108,7 +108,7 @@ const EnumPropertyItem *ED_asset_library_reference_to_rna_enum_itemf(const bool LISTBASE_FOREACH_INDEX (bUserAssetLibrary *, user_library, &U.asset_libraries, i) { /* Note that the path itself isn't checked for validity here. If an invalid library path is * used, the Asset Browser can give a nice hint on what's wrong. */ - const bool is_valid = (user_library->name[0] && user_library->path[0]); + const bool is_valid = (user_library->name[0] && user_library->dirpath[0]); if (!is_valid) { continue; } @@ -120,7 +120,7 @@ const EnumPropertyItem *ED_asset_library_reference_to_rna_enum_itemf(const bool const int enum_value = ED_asset_library_reference_to_enum_value(&library_reference); /* Use library path as description, it's a nice hint for users. */ EnumPropertyItem tmp = { - enum_value, user_library->name, ICON_NONE, user_library->name, user_library->path}; + enum_value, user_library->name, ICON_NONE, user_library->name, user_library->dirpath}; RNA_enum_item_add(&item, &totitem, &tmp); } diff --git a/source/blender/editors/asset/intern/asset_list.cc b/source/blender/editors/asset/intern/asset_list.cc index 3dd2a510373..376822e0875 100644 --- a/source/blender/editors/asset/intern/asset_list.cc +++ b/source/blender/editors/asset/intern/asset_list.cc @@ -155,11 +155,11 @@ void AssetList::setup() const bool use_asset_indexer = !USER_EXPERIMENTAL_TEST(&U, no_asset_indexing); filelist_setindexer(files, use_asset_indexer ? &file_indexer_asset : &file_indexer_noop); - char path[FILE_MAX_LIBEXTRA] = ""; + char dirpath[FILE_MAX_LIBEXTRA] = ""; if (!asset_lib_path.empty()) { - STRNCPY(path, asset_lib_path.c_str()); + STRNCPY(dirpath, asset_lib_path.c_str()); } - filelist_setdir(files, path); + filelist_setdir(files, dirpath); } void AssetList::fetch(const bContext &C) diff --git a/source/blender/editors/asset/intern/asset_ops.cc b/source/blender/editors/asset/intern/asset_ops.cc index 74530538e3c..2a1d17c6741 100644 --- a/source/blender/editors/asset/intern/asset_ops.cc +++ b/source/blender/editors/asset/intern/asset_ops.cc @@ -854,7 +854,7 @@ static bool is_contained_in_selected_asset_library(wmOperator *op, const char *f if (!lib) { return false; } - return BLI_path_contains(lib->path, filepath); + return BLI_path_contains(lib->dirpath, filepath); } /** @@ -876,7 +876,7 @@ static bool set_filepath_for_asset_lib(const Main *bmain, wmOperator *op) } char file_path[PATH_MAX]; - BLI_path_join(file_path, sizeof(file_path), lib->path, blend_filename); + BLI_path_join(file_path, sizeof(file_path), lib->dirpath, blend_filename); RNA_string_set(op->ptr, "filepath", file_path); return true; diff --git a/source/blender/editors/object/object_modifier.cc b/source/blender/editors/object/object_modifier.cc index 75186d85c19..9953185e6ed 100644 --- a/source/blender/editors/object/object_modifier.cc +++ b/source/blender/editors/object/object_modifier.cc @@ -2420,7 +2420,7 @@ static int multires_external_save_exec(bContext *C, wmOperator *op) Main *bmain = CTX_data_main(C); Object *ob = ED_object_active_context(C); Mesh *me = (ob) ? static_cast(ob->data) : static_cast(op->customdata); - char path[FILE_MAX]; + char filepath[FILE_MAX]; const bool relative = RNA_boolean_get(op->ptr, "relative_path"); if (!me) { @@ -2431,13 +2431,13 @@ static int multires_external_save_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - RNA_string_get(op->ptr, "filepath", path); + RNA_string_get(op->ptr, "filepath", filepath); if (relative) { - BLI_path_rel(path, BKE_main_blendfile_path(bmain)); + BLI_path_rel(filepath, BKE_main_blendfile_path(bmain)); } - CustomData_external_add(&me->ldata, &me->id, CD_MDISPS, me->totloop, path); + CustomData_external_add(&me->ldata, &me->id, CD_MDISPS, me->totloop, filepath); CustomData_external_write(&me->ldata, &me->id, CD_MASK_MESH.lmask, me->totloop, 0); return OPERATOR_FINISHED; @@ -2447,7 +2447,7 @@ static int multires_external_save_invoke(bContext *C, wmOperator *op, const wmEv { Object *ob = ED_object_active_context(C); Mesh *me = static_cast(ob->data); - char path[FILE_MAX]; + char filepath[FILE_MAX]; if (!edit_modifier_invoke_properties(C, op)) { return OPERATOR_CANCELLED; @@ -2470,8 +2470,8 @@ static int multires_external_save_invoke(bContext *C, wmOperator *op, const wmEv op->customdata = me; - SNPRINTF(path, "//%s.btx", me->id.name + 2); - RNA_string_set(op->ptr, "filepath", path); + SNPRINTF(filepath, "//%s.btx", me->id.name + 2); + RNA_string_set(op->ptr, "filepath", filepath); WM_event_add_fileselect(C, op); diff --git a/source/blender/editors/physics/rigidbody_world.c b/source/blender/editors/physics/rigidbody_world.c index 0e15167ed7b..ef5071c087e 100644 --- a/source/blender/editors/physics/rigidbody_world.c +++ b/source/blender/editors/physics/rigidbody_world.c @@ -135,7 +135,7 @@ static int rigidbody_world_export_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); RigidBodyWorld *rbw = scene->rigidbody_world; - char path[FILE_MAX]; + char filepath[FILE_MAX]; /* sanity checks */ if (ELEM(NULL, scene, rbw)) { @@ -148,9 +148,9 @@ static int rigidbody_world_export_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - RNA_string_get(op->ptr, "filepath", path); + RNA_string_get(op->ptr, "filepath", filepath); #ifdef WITH_BULLET - RB_dworld_export(rbw->shared->physics_world, path); + RB_dworld_export(rbw->shared->physics_world, filepath); #endif return OPERATOR_FINISHED; } diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c index b66ee31eda8..eb5844259fa 100644 --- a/source/blender/editors/screen/screendump.c +++ b/source/blender/editors/screen/screendump.c @@ -112,10 +112,10 @@ static int screenshot_exec(bContext *C, wmOperator *op) if (scd) { if (scd->dumprect) { ImBuf *ibuf; - char path[FILE_MAX]; + char filepath[FILE_MAX]; - RNA_string_get(op->ptr, "filepath", path); - BLI_path_abs(path, BKE_main_blendfile_path_from_global()); + RNA_string_get(op->ptr, "filepath", filepath); + BLI_path_abs(filepath, BKE_main_blendfile_path_from_global()); /* operator ensures the extension */ ibuf = IMB_allocImBuf(scd->dumpsx, scd->dumpsy, 24, 0); @@ -133,7 +133,7 @@ static int screenshot_exec(bContext *C, wmOperator *op) /* bw screenshot? - users will notice if it fails! */ IMB_color_to_bw(ibuf); } - if (BKE_imbuf_write(ibuf, path, &scd->im_format)) { + if (BKE_imbuf_write(ibuf, filepath, &scd->im_format)) { ok = true; } else { diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index f4648252cec..67226fb0b90 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -73,14 +73,14 @@ static void sound_open_init(bContext *C, wmOperator *op) #ifdef WITH_AUDASPACE static int sound_open_exec(bContext *C, wmOperator *op) { - char path[FILE_MAX]; + char filepath[FILE_MAX]; bSound *sound; PropertyPointerRNA *pprop; PointerRNA idptr; Main *bmain = CTX_data_main(C); - RNA_string_get(op->ptr, "filepath", path); - sound = BKE_sound_new_file(bmain, path); + RNA_string_get(op->ptr, "filepath", filepath); + sound = BKE_sound_new_file(bmain, filepath); if (!op->customdata) { sound_open_init(C, op); diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index 4711bc3ce7c..b2da842b882 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -184,8 +184,8 @@ static int file_browse_exec(bContext *C, wmOperator *op) Main *bmain = CTX_data_main(C); FileBrowseOp *fbo = op->customdata; ID *id; - char *str; - int str_len; + char *path; + int path_len; const char *path_prop = RNA_struct_find_property(op->ptr, "directory") ? "directory" : "filepath"; @@ -193,41 +193,41 @@ static int file_browse_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - str = RNA_string_get_alloc(op->ptr, path_prop, NULL, 0, &str_len); + path = RNA_string_get_alloc(op->ptr, path_prop, NULL, 0, &path_len); /* Add slash for directories, important for some properties. */ if (RNA_property_subtype(fbo->prop) == PROP_DIRPATH) { - char path[FILE_MAX]; + char path_buf[FILE_MAX]; const bool is_relative = RNA_boolean_get(op->ptr, "relative_path"); id = fbo->ptr.owner_id; - STRNCPY(path, str); - BLI_path_abs(path, id ? ID_BLEND_PATH(bmain, id) : BKE_main_blendfile_path(bmain)); + STRNCPY(path_buf, path); + BLI_path_abs(path_buf, id ? ID_BLEND_PATH(bmain, id) : BKE_main_blendfile_path(bmain)); - if (BLI_is_dir(path)) { + if (BLI_is_dir(path_buf)) { /* Do this first so '//' isn't converted to '//\' on windows. */ - BLI_path_slash_ensure(path, sizeof(path)); + BLI_path_slash_ensure(path_buf, sizeof(path_buf)); if (is_relative) { - BLI_path_rel(path, BKE_main_blendfile_path(bmain)); - str_len = strlen(path); - str = MEM_reallocN(str, str_len + 1); - memcpy(str, path, str_len + 1); + BLI_path_rel(path_buf, BKE_main_blendfile_path(bmain)); + path_len = strlen(path_buf); + path = MEM_reallocN(path, path_len + 1); + memcpy(path, path_buf, path_len + 1); } else { - str = MEM_reallocN(str, str_len + 1); + path = MEM_reallocN(path, path_len + 1); } } else { - char *const lslash = (char *)BLI_path_slash_rfind(str); + char *const lslash = (char *)BLI_path_slash_rfind(path); if (lslash) { lslash[1] = '\0'; } } } - RNA_property_string_set(&fbo->ptr, fbo->prop, str); + RNA_property_string_set(&fbo->ptr, fbo->prop, path); RNA_property_update(C, &fbo->ptr, fbo->prop); - MEM_freeN(str); + MEM_freeN(path); if (fbo->is_undo) { const char *undostr = RNA_property_identifier(fbo->prop); @@ -267,7 +267,7 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event) bool is_undo; bool is_userdef; FileBrowseOp *fbo; - char *str; + char *path; const SpaceFile *sfile = CTX_wm_space_file(C); if (sfile && sfile->op) { @@ -281,7 +281,7 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_CANCELLED; } - str = RNA_property_string_get_alloc(&ptr, prop, NULL, 0, NULL); + path = RNA_property_string_get_alloc(&ptr, prop, NULL, 0, NULL); /* Useful yet irritating feature, Shift+Click to open the file * Alt+Click to browse a folder in the OS's browser. */ @@ -290,18 +290,18 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event) PointerRNA props_ptr; if (event->modifier & KM_ALT) { - char *lslash = (char *)BLI_path_slash_rfind(str); + char *lslash = (char *)BLI_path_slash_rfind(path); if (lslash) { *lslash = '\0'; } } WM_operator_properties_create_ptr(&props_ptr, ot); - RNA_string_set(&props_ptr, "filepath", str); + RNA_string_set(&props_ptr, "filepath", path); WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, &props_ptr, NULL); WM_operator_properties_free(&props_ptr); - MEM_freeN(str); + MEM_freeN(path); return OPERATOR_CANCELLED; } @@ -323,8 +323,8 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event) /* While we want to follow the defaults, * we better not switch existing paths relative/absolute state. */ - if (str[0]) { - is_relative = BLI_path_is_rel(str); + if (path[0]) { + is_relative = BLI_path_is_rel(path); } if (UNLIKELY(ptr.data == &U || is_userdef)) { @@ -336,8 +336,8 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event) } } - RNA_string_set(op->ptr, path_prop, str); - MEM_freeN(str); + RNA_string_set(op->ptr, path_prop, path); + MEM_freeN(path); PropertyRNA *prop_check_existing = RNA_struct_find_property(op->ptr, "check_existing"); if (!RNA_property_is_set(op->ptr, prop_check_existing)) { diff --git a/source/blender/editors/space_clip/clip_ops.cc b/source/blender/editors/space_clip/clip_ops.cc index dea5f5c01b3..8b5d558a13a 100644 --- a/source/blender/editors/space_clip/clip_ops.cc +++ b/source/blender/editors/space_clip/clip_ops.cc @@ -156,9 +156,9 @@ static void sclip_zoom_set_factor_exec(bContext *C, const wmEvent *event, float /** \name Open Clip Operator * \{ */ -static void clip_filesel(bContext *C, wmOperator *op, const char *path) +static void clip_filesel(bContext *C, wmOperator *op, const char *dirpath) { - RNA_string_set(op->ptr, "directory", path); + RNA_string_set(op->ptr, "directory", dirpath); WM_event_add_fileselect(C, op); } @@ -261,7 +261,7 @@ static int open_exec(bContext *C, wmOperator *op) static int open_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/) { SpaceClip *sc = CTX_wm_space_clip(C); - char path[FILE_MAX]; + char dirpath[FILE_MAX]; MovieClip *clip = nullptr; if (sc) { @@ -269,13 +269,13 @@ static int open_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/) } if (clip) { - STRNCPY(path, clip->filepath); + STRNCPY(dirpath, clip->filepath); - BLI_path_abs(path, CTX_data_main(C)->filepath); - BLI_path_parent_dir(path); + BLI_path_abs(dirpath, CTX_data_main(C)->filepath); + BLI_path_parent_dir(dirpath); } else { - STRNCPY(path, U.textudir); + STRNCPY(dirpath, U.textudir); } if (RNA_struct_property_is_set(op->ptr, "files")) { @@ -288,7 +288,7 @@ static int open_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/) open_init(C, op); - clip_filesel(C, op, path); + clip_filesel(C, op, dirpath); return OPERATOR_RUNNING_MODAL; } diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index fc90c6357c9..53e566bb202 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -2613,7 +2613,7 @@ static bool new_folder_path(const char *parent, static int file_directory_new_exec(bContext *C, wmOperator *op) { char dirname[FILE_MAXFILE]; - char path[FILE_MAX]; + char dirpath[FILE_MAX]; bool generate_name = true; wmWindowManager *wm = CTX_wm_manager(C); @@ -2626,19 +2626,19 @@ static int file_directory_new_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - path[0] = '\0'; + dirpath[0] = '\0'; { PropertyRNA *prop = RNA_struct_find_property(op->ptr, "directory"); - RNA_property_string_get(op->ptr, prop, path); - if (path[0] != '\0') { + RNA_property_string_get(op->ptr, prop, dirpath); + if (dirpath[0] != '\0') { generate_name = false; } } if (generate_name) { /* create a new, non-existing folder name */ - if (!new_folder_path(params->dir, path, dirname)) { + if (!new_folder_path(params->dir, dirpath, dirname)) { BKE_report(op->reports, RPT_ERROR, "Could not create new folder name"); return OPERATOR_CANCELLED; } @@ -2646,22 +2646,22 @@ static int file_directory_new_exec(bContext *C, wmOperator *op) else { /* We assume we are able to generate a valid name! */ char org_path[FILE_MAX]; - STRNCPY(org_path, path); - if (BLI_path_make_safe(path)) { + STRNCPY(org_path, dirpath); + if (BLI_path_make_safe(dirpath)) { BKE_reportf(op->reports, RPT_WARNING, "'%s' given path is OS-invalid, creating '%s' path instead", org_path, - path); + dirpath); } } /* create the file */ errno = 0; - if (!BLI_dir_create_recursive(path) || + if (!BLI_dir_create_recursive(dirpath) || /* Should no more be needed, * now that BLI_dir_create_recursive returns a success state - but kept just in case. */ - !BLI_exists(path)) + !BLI_exists(dirpath)) { BKE_reportf(op->reports, RPT_ERROR, @@ -2688,7 +2688,7 @@ static int file_directory_new_exec(bContext *C, wmOperator *op) ED_fileselect_clear(wm, sfile); if (do_diropen) { - STRNCPY(params->dir, path); + STRNCPY(params->dir, dirpath); ED_file_change_dir(C); } @@ -2809,10 +2809,10 @@ void file_directory_enter_handle(bContext *C, void *UNUSED(arg_unused), void *UN char *group, *name; if (BLI_is_file(params->dir)) { - char path[sizeof(params->dir)]; - STRNCPY(path, params->dir); + char dirpath[sizeof(params->dir)]; + STRNCPY(dirpath, params->dir); BLI_path_split_dir_file( - path, params->dir, sizeof(params->dir), params->file, sizeof(params->file)); + dirpath, params->dir, sizeof(params->dir), params->file, sizeof(params->file)); } else if (BKE_blendfile_library_path_explode(params->dir, tdir, &group, &name)) { if (group) { diff --git a/source/blender/editors/space_file/filelist.cc b/source/blender/editors/space_file/filelist.cc index 9d5e77d6c36..8b5cc2a6f6f 100644 --- a/source/blender/editors/space_file/filelist.cc +++ b/source/blender/editors/space_file/filelist.cc @@ -1146,16 +1146,16 @@ void filelist_free_icons(void) void filelist_file_get_full_path(const FileList *filelist, const FileDirEntry *file, - char r_path[/*FILE_MAX_LIBEXTRA*/]) + char r_filepath[/*FILE_MAX_LIBEXTRA*/]) { if (file->asset) { const std::string asset_path = AS_asset_representation_full_path_get(file->asset); - BLI_strncpy(r_path, asset_path.c_str(), FILE_MAX_LIBEXTRA); + BLI_strncpy(r_filepath, asset_path.c_str(), FILE_MAX_LIBEXTRA); return; } const char *root = filelist_dir(filelist); - BLI_path_join(r_path, FILE_MAX_LIBEXTRA, root, file->relpath); + BLI_path_join(r_filepath, FILE_MAX_LIBEXTRA, root, file->relpath); } static FileDirEntry *filelist_geticon_get_file(FileList *filelist, const int index) diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h index 2b77aafca79..c8e5a4de980 100644 --- a/source/blender/editors/space_file/filelist.h +++ b/source/blender/editors/space_file/filelist.h @@ -74,7 +74,7 @@ void filelist_init_icons(void); void filelist_free_icons(void); void filelist_file_get_full_path(const struct FileList *filelist, const FileDirEntry *file, - char r_path[/*FILE_MAX_LIBEXTRA*/]); + char r_filepath[/*FILE_MAX_LIBEXTRA*/]); struct ImBuf *filelist_getimage(struct FileList *filelist, int index); struct ImBuf *filelist_file_getimage(const FileDirEntry *file); struct ImBuf *filelist_geticon_image_ex(const FileDirEntry *file); diff --git a/source/blender/editors/space_file/filesel.cc b/source/blender/editors/space_file/filesel.cc index 04c7dee381c..df7ac9ba370 100644 --- a/source/blender/editors/space_file/filesel.cc +++ b/source/blender/editors/space_file/filesel.cc @@ -446,7 +446,7 @@ static void fileselect_refresh_asset_params(FileAssetSelectParams *asset_params) break; case ASSET_LIBRARY_CUSTOM: BLI_assert(user_library); - STRNCPY(base_params->dir, user_library->path); + STRNCPY(base_params->dir, user_library->dirpath); base_params->type = FILE_ASSET_LIBRARY; break; } @@ -1232,14 +1232,14 @@ int autocomplete_directory(bContext *C, char *str, void * /*arg_v*/) /* pass */ } else { - char path[FILE_MAX]; + char dirpath[FILE_MAX]; BLI_stat_t status; - BLI_path_join(path, sizeof(path), dirname, de->d_name); + BLI_path_join(dirpath, sizeof(dirpath), dirname, de->d_name); - if (BLI_stat(path, &status) == 0) { + if (BLI_stat(dirpath, &status) == 0) { if (S_ISDIR(status.st_mode)) { /* is subdir */ - UI_autocomplete_update_name(autocpl, path); + UI_autocomplete_update_name(autocpl, dirpath); } } } diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index 90f71c18813..f94db218646 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -1087,24 +1087,24 @@ static int graphkeys_sound_bake_exec(bContext *C, wmOperator *op) Scene *scene = NULL; int start, end; - char path[FILE_MAX]; + char filepath[FILE_MAX]; /* Get editor data. */ if (ANIM_animdata_get_context(C, &ac) == 0) { return OPERATOR_CANCELLED; } - RNA_string_get(op->ptr, "filepath", path); + RNA_string_get(op->ptr, "filepath", filepath); - if (!BLI_is_file(path)) { - BKE_reportf(op->reports, RPT_ERROR, "File not found '%s'", path); + if (!BLI_is_file(filepath)) { + BKE_reportf(op->reports, RPT_ERROR, "File not found '%s'", filepath); return OPERATOR_CANCELLED; } scene = ac.scene; /* Current scene. */ /* Store necessary data for the baking steps. */ - sbi.samples = AUD_readSoundBuffer(path, + sbi.samples = AUD_readSoundBuffer(filepath, RNA_float_get(op->ptr, "low"), RNA_float_get(op->ptr, "high"), RNA_float_get(op->ptr, "attack"), diff --git a/source/blender/editors/space_script/script_edit.c b/source/blender/editors/space_script/script_edit.c index 878d207512e..5423e87937c 100644 --- a/source/blender/editors/space_script/script_edit.c +++ b/source/blender/editors/space_script/script_edit.c @@ -32,10 +32,10 @@ static int run_pyfile_exec(bContext *C, wmOperator *op) { - char path[FILE_MAX]; - RNA_string_get(op->ptr, "filepath", path); + char filepath[FILE_MAX]; + RNA_string_get(op->ptr, "filepath", filepath); #ifdef WITH_PYTHON - if (BPY_run_filepath(C, path, op->reports)) { + if (BPY_run_filepath(C, filepath, op->reports)) { ARegion *region = CTX_wm_region(C); if (region != NULL) { ED_region_tag_redraw(region); diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index 68f7ed5f2da..310089336f8 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -179,10 +179,10 @@ static void sequencer_generic_invoke_path__internal(bContext *C, Sequence *last_seq = SEQ_select_active_get(scene); if (last_seq && last_seq->strip && SEQ_HAS_PATH(last_seq)) { Main *bmain = CTX_data_main(C); - char path[FILE_MAX]; - STRNCPY(path, last_seq->strip->dirpath); - BLI_path_abs(path, BKE_main_blendfile_path(bmain)); - RNA_string_set(op->ptr, identifier, path); + char dirpath[FILE_MAX]; + STRNCPY(dirpath, last_seq->strip->dirpath); + BLI_path_abs(dirpath, BKE_main_blendfile_path(bmain)); + RNA_string_set(op->ptr, identifier, dirpath); } } } diff --git a/source/blender/editors/space_sequencer/sequencer_drag_drop.c b/source/blender/editors/space_sequencer/sequencer_drag_drop.c index 69172dee685..6155d01dcc2 100644 --- a/source/blender/editors/space_sequencer/sequencer_drag_drop.c +++ b/source/blender/editors/space_sequencer/sequencer_drag_drop.c @@ -507,6 +507,10 @@ static bool generic_drop_draw_handling(wmDropBox *drop) } typedef struct DropJobData { + /** + * This is practically always a `filepath`, however that isn't a requirement + * for drag-and-drop, so keep the name generic. + */ char path[FILE_MAX]; bool only_audio; float scene_fps; diff --git a/source/blender/io/alembic/ABC_alembic.h b/source/blender/io/alembic/ABC_alembic.h index dec1f455926..dbd034d657f 100644 --- a/source/blender/io/alembic/ABC_alembic.h +++ b/source/blender/io/alembic/ABC_alembic.h @@ -106,7 +106,7 @@ bool ABC_import(struct bContext *C, bool as_background_job); struct CacheArchiveHandle *ABC_create_handle(struct Main *bmain, - const char *filename, + const char *filepath, const struct CacheFileLayer *layers, struct ListBase *object_paths); diff --git a/source/blender/io/alembic/intern/alembic_capi.cc b/source/blender/io/alembic/intern/alembic_capi.cc index 6147d1cc855..5d5353727b6 100644 --- a/source/blender/io/alembic/intern/alembic_capi.cc +++ b/source/blender/io/alembic/intern/alembic_capi.cc @@ -153,24 +153,24 @@ static bool gather_objects_paths(const IObject &object, ListBase *object_paths) } CacheArchiveHandle *ABC_create_handle(Main *bmain, - const char *filename, + const char *filepath, const CacheFileLayer *layers, ListBase *object_paths) { - std::vector filenames; - filenames.push_back(filename); + std::vector filepaths; + filepaths.push_back(filepath); while (layers) { if ((layers->flag & CACHEFILE_LAYER_HIDDEN) == 0) { - filenames.push_back(layers->filepath); + filepaths.push_back(layers->filepath); } layers = layers->next; } /* We need to reverse the order as overriding archives should come first. */ - std::reverse(filenames.begin(), filenames.end()); + std::reverse(filepaths.begin(), filepaths.end()); - ArchiveReader *archive = ArchiveReader::get(bmain, filenames); + ArchiveReader *archive = ArchiveReader::get(bmain, filepaths); if (!archive || !archive->valid()) { delete archive; @@ -426,7 +426,7 @@ struct ImportJobData { ViewLayer *view_layer; wmWindowManager *wm; - char filename[1024]; + char filepath[1024]; ImportSettings settings; ArchiveReader *archive; @@ -446,7 +446,7 @@ struct ImportJobData { static void report_job_duration(const ImportJobData *data) { blender::timeit::Nanoseconds duration = blender::timeit::Clock::now() - data->start_time; - std::cout << "Alembic import of '" << data->filename << "' took "; + std::cout << "Alembic import of '" << data->filepath << "' took "; blender::timeit::print_duration(duration); std::cout << '\n'; } @@ -464,7 +464,7 @@ static void import_startjob(void *user_data, bool *stop, bool *do_update, float WM_set_locked_interface(data->wm, true); - ArchiveReader *archive = ArchiveReader::get(data->bmain, {data->filename}); + ArchiveReader *archive = ArchiveReader::get(data->bmain, {data->filepath}); if (!archive || !archive->valid()) { data->error_code = ABC_ARCHIVE_FAIL; @@ -473,7 +473,7 @@ static void import_startjob(void *user_data, bool *stop, bool *do_update, float } CacheFile *cache_file = static_cast( - BKE_cachefile_add(data->bmain, BLI_path_basename(data->filename))); + BKE_cachefile_add(data->bmain, BLI_path_basename(data->filepath))); /* Decrement the ID ref-count because it is going to be incremented for each * modifier and constraint that it will be attached to, so since currently @@ -482,7 +482,7 @@ static void import_startjob(void *user_data, bool *stop, bool *do_update, float cache_file->is_sequence = data->settings.is_sequence; cache_file->scale = data->settings.scale; - STRNCPY(cache_file->filepath, data->filename); + STRNCPY(cache_file->filepath, data->filepath); data->archive = archive; data->settings.cache_file = cache_file; @@ -525,7 +525,7 @@ static void import_startjob(void *user_data, bool *stop, bool *do_update, float max_time = std::max(max_time, reader->maxTime()); } else { - std::cerr << "Object " << reader->name() << " in Alembic file " << data->filename + std::cerr << "Object " << reader->name() << " in Alembic file " << data->filepath << " is invalid.\n"; } @@ -686,7 +686,7 @@ bool ABC_import(bContext *C, job->view_layer = CTX_data_view_layer(C); job->wm = CTX_wm_manager(C); job->import_ok = false; - STRNCPY(job->filename, filepath); + STRNCPY(job->filepath, filepath); job->settings.scale = params->global_scale; job->settings.is_sequence = params->is_sequence; diff --git a/source/blender/io/usd/intern/usd_writer_material.cc b/source/blender/io/usd/intern/usd_writer_material.cc index 99dbf3ea550..8874abb288a 100644 --- a/source/blender/io/usd/intern/usd_writer_material.cc +++ b/source/blender/io/usd/intern/usd_writer_material.cc @@ -112,9 +112,9 @@ static void export_texture(bNode *node, const bool allow_overwrite = false); static bNode *find_bsdf_node(Material *material); static void get_absolute_path(Image *ima, char *r_path); -static std::string get_tex_image_asset_path(bNode *node, - const pxr::UsdStageRefPtr stage, - const USDExportParams &export_params); +static std::string get_tex_image_asset_filepath(bNode *node, + const pxr::UsdStageRefPtr stage, + const USDExportParams &export_params); static InputSpecMap &preview_surface_input_map(); static bNodeLink *traverse_channel(bNodeSocket *input, short target_type); @@ -582,7 +582,7 @@ static pxr::UsdShadeShader create_usd_preview_shader(const USDExporterContext &u } /* For texture image nodes we set the image path and color space. */ - std::string imagePath = get_tex_image_asset_path( + std::string imagePath = get_tex_image_asset_filepath( node, usd_export_context.stage, usd_export_context.export_params); if (!imagePath.empty()) { shader.CreateInput(usdtokens::file, pxr::SdfValueTypeNames->Asset) @@ -597,7 +597,7 @@ static pxr::UsdShadeShader create_usd_preview_shader(const USDExporterContext &u return shader; } -static std::string get_tex_image_asset_path(Image *ima) +static std::string get_tex_image_asset_filepath(Image *ima) { char filepath[FILE_MAX]; get_absolute_path(ima, filepath); @@ -612,9 +612,9 @@ static std::string get_tex_image_asset_path(Image *ima) * generated based on the image name for in-memory textures when exporting textures. * This function may return an empty string if the image does not have a filepath * assigned and no asset path could be determined. */ -static std::string get_tex_image_asset_path(bNode *node, - const pxr::UsdStageRefPtr stage, - const USDExportParams &export_params) +static std::string get_tex_image_asset_filepath(bNode *node, + const pxr::UsdStageRefPtr stage, + const USDExportParams &export_params) { Image *ima = reinterpret_cast(node->id); if (!ima) { @@ -625,7 +625,7 @@ static std::string get_tex_image_asset_path(bNode *node, if (strlen(ima->filepath) > 0) { /* Get absolute path. */ - path = get_tex_image_asset_path(ima); + path = get_tex_image_asset_filepath(ima); } else if (export_params.export_textures) { /* Image has no filepath, but since we are exporting textures, diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc b/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc index 2a84e857fb4..30470492363 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc @@ -150,18 +150,18 @@ static std::string get_image_filepath(const bNode *tex_node) return filename; } - char path[FILE_MAX]; - STRNCPY(path, tex_image->filepath); + char filepath[FILE_MAX]; + STRNCPY(filepath, tex_image->filepath); if (tex_image->source == IMA_SRC_SEQUENCE) { char head[FILE_MAX], tail[FILE_MAX]; ushort numlen; int framenr = static_cast(tex_node->storage)->iuser.framenr; - BLI_path_sequence_decode(path, head, sizeof(head), tail, sizeof(tail), &numlen); - BLI_path_sequence_encode(path, sizeof(path), head, tail, numlen, framenr); + BLI_path_sequence_decode(filepath, head, sizeof(head), tail, sizeof(tail), &numlen); + BLI_path_sequence_encode(filepath, sizeof(filepath), head, tail, numlen, framenr); } - return path; + return filepath; } /** diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index a55b6cda9c0..98a11b2b461 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -594,8 +594,8 @@ enum { typedef struct bUserAssetLibrary { struct bUserAssetLibrary *next, *prev; - char name[64]; /* MAX_NAME */ - char path[1024]; /* FILE_MAX */ + char name[64]; /* MAX_NAME */ + char dirpath[1024]; /* FILE_MAX */ short import_method; /* eAssetImportMethod */ short flag; /* eAssetLibrary_Flag */ diff --git a/source/blender/makesdna/intern/dna_rename_defs.h b/source/blender/makesdna/intern/dna_rename_defs.h index 363f5b12889..db2ad49e0ac 100644 --- a/source/blender/makesdna/intern/dna_rename_defs.h +++ b/source/blender/makesdna/intern/dna_rename_defs.h @@ -192,6 +192,7 @@ DNA_STRUCT_RENAME_ELEM(bTheme, tstatusbar, space_statusbar) DNA_STRUCT_RENAME_ELEM(bTheme, ttopbar, space_topbar) DNA_STRUCT_RENAME_ELEM(bTheme, tuserpref, space_preferences) DNA_STRUCT_RENAME_ELEM(bTheme, tv3d, space_view3d) +DNA_STRUCT_RENAME_ELEM(bUserAssetLibrary, path, dirpath) /* Write with a different name, old Blender versions crash loading files with non-NULL * global_areas. See D9442. */ DNA_STRUCT_RENAME_ELEM(wmWindow, global_area_map, global_areas) diff --git a/source/blender/makesrna/intern/rna_gpencil_legacy_modifier.c b/source/blender/makesrna/intern/rna_gpencil_legacy_modifier.c index 11031aca9bc..8904a76a761 100644 --- a/source/blender/makesrna/intern/rna_gpencil_legacy_modifier.c +++ b/source/blender/makesrna/intern/rna_gpencil_legacy_modifier.c @@ -894,11 +894,11 @@ static void rna_DashGpencilModifierSegment_name_set(PointerRNA *ptr, const char char name_esc[sizeof(ds->dmd->modifier.name) * 2]; BLI_str_escape(name_esc, ds->dmd->modifier.name, sizeof(name_esc)); - char prefix[36 + sizeof(name_esc) + 1]; - SNPRINTF(prefix, "grease_pencil_modifiers[\"%s\"].segments", name_esc); + char rna_path_prefix[36 + sizeof(name_esc) + 1]; + SNPRINTF(rna_path_prefix, "grease_pencil_modifiers[\"%s\"].segments", name_esc); /* Fix all the animation data which may link to this. */ - BKE_animdata_fix_paths_rename_all(NULL, prefix, oldname, ds->name); + BKE_animdata_fix_paths_rename_all(NULL, rna_path_prefix, oldname, ds->name); } static void rna_TimeGpencilModifierSegment_name_set(PointerRNA *ptr, const char *value) @@ -917,11 +917,11 @@ static void rna_TimeGpencilModifierSegment_name_set(PointerRNA *ptr, const char char name_esc[sizeof(ds->gpmd->modifier.name) * 2]; BLI_str_escape(name_esc, ds->gpmd->modifier.name, sizeof(name_esc)); - char prefix[36 + sizeof(name_esc) + 1]; - SNPRINTF(prefix, "grease_pencil_modifiers[\"%s\"].segments", name_esc); + char rna_path_prefix[36 + sizeof(name_esc) + 1]; + SNPRINTF(rna_path_prefix, "grease_pencil_modifiers[\"%s\"].segments", name_esc); /* Fix all the animation data which may link to this. */ - BKE_animdata_fix_paths_rename_all(NULL, prefix, oldname, ds->name); + BKE_animdata_fix_paths_rename_all(NULL, rna_path_prefix, oldname, ds->name); } static int rna_ShrinkwrapGpencilModifier_face_cull_get(PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index 7557807b8be..f6d41eb865e 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -857,19 +857,19 @@ static void rna_Sequence_filepath_set(PointerRNA *ptr, const char *value) static void rna_Sequence_filepath_get(PointerRNA *ptr, char *value) { Sequence *seq = (Sequence *)(ptr->data); - char path[FILE_MAX]; + char filepath[FILE_MAX]; - BLI_path_join(path, sizeof(path), seq->strip->dirpath, seq->strip->stripdata->filename); - strcpy(value, path); + BLI_path_join(filepath, sizeof(filepath), seq->strip->dirpath, seq->strip->stripdata->filename); + strcpy(value, filepath); } static int rna_Sequence_filepath_length(PointerRNA *ptr) { Sequence *seq = (Sequence *)(ptr->data); - char path[FILE_MAX]; + char filepath[FILE_MAX]; - BLI_path_join(path, sizeof(path), seq->strip->dirpath, seq->strip->stripdata->filename); - return strlen(path); + BLI_path_join(filepath, sizeof(filepath), seq->strip->dirpath, seq->strip->stripdata->filename); + return strlen(filepath); } static void rna_Sequence_proxy_filepath_set(PointerRNA *ptr, const char *value) @@ -886,19 +886,19 @@ static void rna_Sequence_proxy_filepath_set(PointerRNA *ptr, const char *value) static void rna_Sequence_proxy_filepath_get(PointerRNA *ptr, char *value) { StripProxy *proxy = (StripProxy *)(ptr->data); - char path[FILE_MAX]; + char filepath[FILE_MAX]; - BLI_path_join(path, sizeof(path), proxy->dirpath, proxy->filename); - strcpy(value, path); + BLI_path_join(filepath, sizeof(filepath), proxy->dirpath, proxy->filename); + strcpy(value, filepath); } static int rna_Sequence_proxy_filepath_length(PointerRNA *ptr) { StripProxy *proxy = (StripProxy *)(ptr->data); - char path[FILE_MAX]; + char filepath[FILE_MAX]; - BLI_path_join(path, sizeof(path), proxy->dirpath, proxy->filename); - return strlen(path); + BLI_path_join(filepath, sizeof(filepath), proxy->dirpath, proxy->filename); + return strlen(filepath); } static void rna_Sequence_audio_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) @@ -1135,11 +1135,11 @@ static char *rna_SequenceColorBalance_path(const PointerRNA *ptr) BLI_str_escape(name_esc, seq->name + 2, sizeof(name_esc)); if (!smd) { - /* path to old filter color balance */ + /* Path to old filter color balance. */ return BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].color_balance", name_esc); } else { - /* path to modifier */ + /* Path to modifier. */ char name_esc_smd[sizeof(smd->name) * 2]; BLI_str_escape(name_esc_smd, smd->name, sizeof(name_esc_smd)); @@ -1328,13 +1328,14 @@ static void rna_SequenceModifier_name_set(PointerRNA *ptr, const char *value) /* fix all the animation data which may link to this */ adt = BKE_animdata_from_id(&scene->id); if (adt) { - char path[1024]; + char rna_path_prefix[1024]; char seq_name_esc[(sizeof(seq->name) - 2) * 2]; BLI_str_escape(seq_name_esc, seq->name + 2, sizeof(seq_name_esc)); - SNPRINTF(path, "sequence_editor.sequences_all[\"%s\"].modifiers", seq_name_esc); - BKE_animdata_fix_paths_rename(&scene->id, adt, NULL, path, oldname, smd->name, 0, 0, 1); + SNPRINTF(rna_path_prefix, "sequence_editor.sequences_all[\"%s\"].modifiers", seq_name_esc); + BKE_animdata_fix_paths_rename( + &scene->id, adt, NULL, rna_path_prefix, oldname, smd->name, 0, 0, 1); } } diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index fa068cd6d4c..f35f46f0ade 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -273,9 +273,11 @@ static void rna_trackingTrack_name_set(PointerRNA *ptr, const char *value) /* Fix animation paths. */ AnimData *adt = BKE_animdata_from_id(&clip->id); if (adt != NULL) { - char rna_path[MAX_NAME * 2 + 64]; - BKE_tracking_get_rna_path_prefix_for_track(&clip->tracking, track, rna_path, sizeof(rna_path)); - BKE_animdata_fix_paths_rename(&clip->id, adt, NULL, rna_path, old_name, track->name, 0, 0, 1); + char rna_path_prefix[MAX_NAME * 2 + 64]; + BKE_tracking_get_rna_path_prefix_for_track( + &clip->tracking, track, rna_path_prefix, sizeof(rna_path_prefix)); + BKE_animdata_fix_paths_rename( + &clip->id, adt, NULL, rna_path_prefix, old_name, track->name, 0, 0, 1); } } diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index ca7dc8cfd1b..ab218c1d83f 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -6272,6 +6272,7 @@ static void rna_def_userdef_filepaths_asset_library(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_userdef_update"); prop = RNA_def_property(srna, "path", PROP_STRING, PROP_DIRPATH); + RNA_def_property_string_sdna(prop, NULL, "dirpath"); RNA_def_property_ui_text( prop, "Path", "Path to a directory with .blend files to use as an asset library"); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_userdef_asset_library_path_set"); diff --git a/source/blender/sequencer/SEQ_add.h b/source/blender/sequencer/SEQ_add.h index 5f8abe8de62..579d34b6607 100644 --- a/source/blender/sequencer/SEQ_add.h +++ b/source/blender/sequencer/SEQ_add.h @@ -28,7 +28,8 @@ typedef enum eSeqLoadFlags { typedef struct SeqLoadData { int start_frame; int channel; - char name[64]; /* Strip name. */ + char name[64]; /* Strip name. */ + /** Typically a `filepath` but may reference any kind of path. */ char path[1024]; /* 1024 = FILE_MAX */ struct { int len; diff --git a/source/blender/sequencer/intern/disk_cache.c b/source/blender/sequencer/intern/disk_cache.c index 35cd920a00c..b289d5ce419 100644 --- a/source/blender/sequencer/intern/disk_cache.c +++ b/source/blender/sequencer/intern/disk_cache.c @@ -92,7 +92,7 @@ typedef struct SeqDiskCache { typedef struct DiskCacheFile { struct DiskCacheFile *next, *prev; - char path[FILE_MAX]; + char filepath[FILE_MAX]; char dir[FILE_MAXDIR]; char file[FILE_MAX]; BLI_stat_t fstat; @@ -137,13 +137,14 @@ bool seq_disk_cache_is_enabled(Main *bmain) bmain->filepath[0] != '\0'); } -static DiskCacheFile *seq_disk_cache_add_file_to_list(SeqDiskCache *disk_cache, const char *path) +static DiskCacheFile *seq_disk_cache_add_file_to_list(SeqDiskCache *disk_cache, + const char *filepath) { DiskCacheFile *cache_file = MEM_callocN(sizeof(DiskCacheFile), "SeqDiskCacheFile"); char dir[FILE_MAXDIR], file[FILE_MAX]; - BLI_path_split_dir_file(path, dir, sizeof(dir), file, sizeof(file)); - STRNCPY(cache_file->path, path); + BLI_path_split_dir_file(filepath, dir, sizeof(dir), file, sizeof(file)); + STRNCPY(cache_file->filepath, filepath); STRNCPY(cache_file->dir, dir); STRNCPY(cache_file->file, file); sscanf(file, @@ -159,13 +160,13 @@ static DiskCacheFile *seq_disk_cache_add_file_to_list(SeqDiskCache *disk_cache, return cache_file; } -static void seq_disk_cache_get_files(SeqDiskCache *disk_cache, char *path) +static void seq_disk_cache_get_files(SeqDiskCache *disk_cache, char *dirpath) { struct direntry *filelist, *fl; uint i; disk_cache->size_total = 0; - const int filelist_num = BLI_filelist_dir_contents(path, &filelist); + const int filelist_num = BLI_filelist_dir_contents(dirpath, &filelist); i = filelist_num; fl = filelist; while (i--) { @@ -218,7 +219,7 @@ static DiskCacheFile *seq_disk_cache_get_oldest_file(SeqDiskCache *disk_cache) static void seq_disk_cache_delete_file(SeqDiskCache *disk_cache, DiskCacheFile *file) { disk_cache->size_total -= file->fstat.st_size; - BLI_delete(file->path, false, false); + BLI_delete(file->filepath, false, false); BLI_remlink(&disk_cache->files, file); MEM_freeN(file); } @@ -235,7 +236,7 @@ bool seq_disk_cache_enforce_limits(SeqDiskCache *disk_cache) continue; } - if (BLI_exists(oldest_file->path) == 0) { + if (BLI_exists(oldest_file->filepath) == 0) { /* File may have been manually deleted during runtime, do re-scan. */ BLI_freelistN(&disk_cache->files); seq_disk_cache_get_files(disk_cache, seq_disk_cache_base_dir()); @@ -249,12 +250,13 @@ bool seq_disk_cache_enforce_limits(SeqDiskCache *disk_cache) return true; } -static DiskCacheFile *seq_disk_cache_get_file_entry_by_path(SeqDiskCache *disk_cache, char *path) +static DiskCacheFile *seq_disk_cache_get_file_entry_by_path(SeqDiskCache *disk_cache, + char *filepath) { DiskCacheFile *cache_file = disk_cache->files.first; for (; cache_file; cache_file = cache_file->next) { - if (BLI_strcasecmp(cache_file->path, path) == 0) { + if (BLI_strcasecmp(cache_file->filepath, filepath) == 0) { return cache_file; } } @@ -263,16 +265,16 @@ static DiskCacheFile *seq_disk_cache_get_file_entry_by_path(SeqDiskCache *disk_c } /* Update file size and timestamp. */ -static void seq_disk_cache_update_file(SeqDiskCache *disk_cache, char *path) +static void seq_disk_cache_update_file(SeqDiskCache *disk_cache, char *filepath) { DiskCacheFile *cache_file; int64_t size_before; int64_t size_after; - cache_file = seq_disk_cache_get_file_entry_by_path(disk_cache, path); + cache_file = seq_disk_cache_get_file_entry_by_path(disk_cache, filepath); size_before = cache_file->fstat.st_size; - if (BLI_stat(path, &cache_file->fstat) == -1) { + if (BLI_stat(filepath, &cache_file->fstat) == -1) { BLI_assert(false); memset(&cache_file->fstat, 0, sizeof(BLI_stat_t)); } @@ -285,7 +287,9 @@ static void seq_disk_cache_update_file(SeqDiskCache *disk_cache, char *path) * /_seq_cache/-//DCACHE_FNAME_FORMAT */ -static void seq_disk_cache_get_project_dir(SeqDiskCache *disk_cache, char *path, size_t path_len) +static void seq_disk_cache_get_project_dir(SeqDiskCache *disk_cache, + char *dirpath, + size_t dirpath_maxncpy) { char cache_dir[FILE_MAX]; BLI_path_split_file_part( @@ -294,11 +298,11 @@ static void seq_disk_cache_get_project_dir(SeqDiskCache *disk_cache, char *path, const char *suffix = "_seq_cache"; strncat(cache_dir, suffix, sizeof(cache_dir) - strlen(cache_dir) - 1); - BLI_path_join(path, path_len, seq_disk_cache_base_dir(), cache_dir); + BLI_path_join(dirpath, dirpath_maxncpy, seq_disk_cache_base_dir(), cache_dir); } static void seq_disk_cache_get_dir( - SeqDiskCache *disk_cache, Scene *scene, Sequence *seq, char *path, size_t path_len) + SeqDiskCache *disk_cache, Scene *scene, Sequence *seq, char *dirpath, size_t dirpath_maxncpy) { char scene_name[MAX_ID_NAME + 22]; /* + -%PRId64 */ char seq_name[SEQ_NAME_MAXSTR]; @@ -310,15 +314,15 @@ static void seq_disk_cache_get_dir( BLI_path_make_safe_filename(scene_name); BLI_path_make_safe_filename(seq_name); - BLI_path_join(path, path_len, project_dir, scene_name, seq_name); + BLI_path_join(dirpath, dirpath_maxncpy, project_dir, scene_name, seq_name); } static void seq_disk_cache_get_file_path(SeqDiskCache *disk_cache, SeqCacheKey *key, - char *path, - size_t path_len) + char *filepath, + size_t filepath_maxncpy) { - seq_disk_cache_get_dir(disk_cache, key->context.scene, key->seq, path, path_len); + seq_disk_cache_get_dir(disk_cache, key->context.scene, key->seq, filepath, filepath_maxncpy); int frameno = (int)key->frame_index / DCACHE_IMAGES_PER_FILE; char cache_filename[FILE_MAXFILE]; SNPRINTF(cache_filename, @@ -330,7 +334,7 @@ static void seq_disk_cache_get_file_path(SeqDiskCache *disk_cache, key->context.view_id, frameno); - BLI_path_append(path, path_len, cache_filename); + BLI_path_append(filepath, filepath_maxncpy, cache_filename); } static void seq_disk_cache_create_version_file(char *filepath) @@ -346,14 +350,14 @@ static void seq_disk_cache_create_version_file(char *filepath) static void seq_disk_cache_handle_versioning(SeqDiskCache *disk_cache) { - char filepath[FILE_MAX]; + char dirpath[FILE_MAX]; char path_version_file[FILE_MAX]; int version = 0; - seq_disk_cache_get_project_dir(disk_cache, filepath, sizeof(filepath)); - BLI_path_join(path_version_file, sizeof(path_version_file), filepath, "cache_version"); + seq_disk_cache_get_project_dir(disk_cache, dirpath, sizeof(dirpath)); + BLI_path_join(path_version_file, sizeof(path_version_file), dirpath, "cache_version"); - if (BLI_exists(filepath) && BLI_is_dir(filepath)) { + if (BLI_exists(dirpath) && BLI_is_dir(dirpath)) { FILE *file = BLI_fopen(path_version_file, "r"); if (file) { @@ -365,7 +369,7 @@ static void seq_disk_cache_handle_versioning(SeqDiskCache *disk_cache) } if (version != DCACHE_CURRENT_VERSION) { - BLI_delete(filepath, false, true); + BLI_delete(dirpath, false, true); seq_disk_cache_create_version_file(path_version_file); } } diff --git a/source/blender/sequencer/intern/effects.c b/source/blender/sequencer/intern/effects.c index be3b0a954bc..c8fced4abdb 100644 --- a/source/blender/sequencer/intern/effects.c +++ b/source/blender/sequencer/intern/effects.c @@ -3243,12 +3243,12 @@ void SEQ_effect_text_font_load(TextVars *data, const bool do_id_user) data->text_blf_id = BLF_load_mem(name, pf->data, pf->size); } else { - char path[FILE_MAX]; - STRNCPY(path, vfont->filepath); + char filepath[FILE_MAX]; + STRNCPY(filepath, vfont->filepath); BLI_assert(BLI_thread_is_main()); - BLI_path_abs(path, ID_BLEND_PATH_FROM_GLOBAL(&vfont->id)); + BLI_path_abs(filepath, ID_BLEND_PATH_FROM_GLOBAL(&vfont->id)); - data->text_blf_id = BLF_load(path); + data->text_blf_id = BLF_load(filepath); } } diff --git a/source/blender/sequencer/intern/proxy.c b/source/blender/sequencer/intern/proxy.c index a82801cd0f2..e88edbcd71f 100644 --- a/source/blender/sequencer/intern/proxy.c +++ b/source/blender/sequencer/intern/proxy.c @@ -342,25 +342,24 @@ static bool seq_proxy_multiview_context_invalid(Sequence *seq, } if ((seq->type == SEQ_TYPE_IMAGE) && (seq->views_format == R_IMF_VIEWS_INDIVIDUAL)) { - char filepath[FILE_MAX]; - if (view_id == 0) { /* Clear on first use. */ prefix_vars->prefix[0] = '\0'; prefix_vars->ext = NULL; - char path[FILE_MAX]; - BLI_path_join(path, sizeof(path), seq->strip->dirpath, seq->strip->stripdata->filename); - BLI_path_abs(path, BKE_main_blendfile_path_from_global()); - BKE_scene_multiview_view_prefix_get(scene, path, prefix_vars->prefix, &prefix_vars->ext); + char filepath[FILE_MAX]; + BLI_path_join( + filepath, sizeof(filepath), seq->strip->dirpath, seq->strip->stripdata->filename); + BLI_path_abs(filepath, BKE_main_blendfile_path_from_global()); + BKE_scene_multiview_view_prefix_get(scene, filepath, prefix_vars->prefix, &prefix_vars->ext); } if (prefix_vars->prefix[0] == '\0') { return view_id != 0; } + char filepath[FILE_MAX]; seq_multiview_name(scene, view_id, prefix_vars->prefix, prefix_vars->ext, filepath, FILE_MAX); - if (BLI_access(filepath, R_OK) == 0) { return false; } diff --git a/source/blender/sequencer/intern/strip_add.c b/source/blender/sequencer/intern/strip_add.c index 0a7b7c50159..b2207c7d4d2 100644 --- a/source/blender/sequencer/intern/strip_add.c +++ b/source/blender/sequencer/intern/strip_add.c @@ -515,7 +515,6 @@ Sequence *SEQ_add_movie_strip(Main *bmain, Scene *scene, ListBase *seqbase, SeqL void SEQ_add_reload_new_file(Main *bmain, Scene *scene, Sequence *seq, const bool lock_range) { - char path[FILE_MAX]; int prev_startdisp = 0, prev_enddisp = 0; /* NOTE: don't rename the strip, will break animation curves. */ @@ -551,13 +550,15 @@ void SEQ_add_reload_new_file(Main *bmain, Scene *scene, Sequence *seq, const boo break; } case SEQ_TYPE_MOVIE: { + char filepath[FILE_MAX]; StripAnim *sanim; bool is_multiview_loaded = false; const bool is_multiview = (seq->flag & SEQ_USE_VIEWS) != 0 && (scene->r.scemode & R_MULTIVIEW) != 0; - BLI_path_join(path, sizeof(path), seq->strip->dirpath, seq->strip->stripdata->filename); - BLI_path_abs(path, BKE_main_blendfile_path_from_global()); + BLI_path_join( + filepath, sizeof(filepath), seq->strip->dirpath, seq->strip->stripdata->filename); + BLI_path_abs(filepath, BKE_main_blendfile_path_from_global()); SEQ_relations_sequence_free_anim(seq); @@ -567,15 +568,15 @@ void SEQ_add_reload_new_file(Main *bmain, Scene *scene, Sequence *seq, const boo const int totfiles = seq_num_files(scene, seq->views_format, true); int i = 0; - BKE_scene_multiview_view_prefix_get(scene, path, prefix, &ext); + BKE_scene_multiview_view_prefix_get(scene, filepath, prefix, &ext); if (prefix[0] != '\0') { for (i = 0; i < totfiles; i++) { struct anim *anim; - char filepath[FILE_MAX]; + char filepath_view[FILE_MAX]; - seq_multiview_name(scene, i, prefix, ext, filepath, sizeof(filepath)); - anim = openanim(filepath, + seq_multiview_name(scene, i, prefix, ext, filepath_view, sizeof(filepath_view)); + anim = openanim(filepath_view, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0), seq->streamindex, seq->strip->colorspace_settings.name); @@ -593,7 +594,7 @@ void SEQ_add_reload_new_file(Main *bmain, Scene *scene, Sequence *seq, const boo if (is_multiview_loaded == false) { struct anim *anim; - anim = openanim(path, + anim = openanim(filepath, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0), seq->streamindex, seq->strip->colorspace_settings.name); diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c index 4e4ca7af6dd..282c37dfe99 100644 --- a/source/blender/windowmanager/intern/wm_files_link.c +++ b/source/blender/windowmanager/intern/wm_files_link.c @@ -104,10 +104,9 @@ static int wm_link_append_invoke(bContext *C, wmOperator *op, const wmEvent *UNU RNA_string_set(op->ptr, "filepath", G.lib); } else if (blendfile_path[0] != '\0') { - char path[FILE_MAX]; - STRNCPY(path, blendfile_path); - BLI_path_parent_dir(path); - RNA_string_set(op->ptr, "filepath", path); + char dirpath[FILE_MAX]; + BLI_path_split_dir_part(blendfile_path, dirpath, sizeof(dirpath)); + RNA_string_set(op->ptr, "filepath", dirpath); } } @@ -164,7 +163,7 @@ static int wm_link_append_flag(wmOperator *op) * \param reports: Optionally report an error when an item can't be appended/linked. */ static bool wm_link_append_item_poll(ReportList *reports, - const char *path, + const char *filepath, const char *group, const char *name, const bool do_append) @@ -172,7 +171,7 @@ static bool wm_link_append_item_poll(ReportList *reports, short idcode; if (!group || !name) { - CLOG_WARN(&LOG, "Skipping %s", path); + CLOG_WARN(&LOG, "Skipping %s", filepath); return false; } @@ -210,26 +209,27 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) ViewLayer *view_layer = CTX_data_view_layer(C); PropertyRNA *prop; BlendfileLinkAppendContext *lapp_context; - char path[FILE_MAX_LIBEXTRA], root[FILE_MAXDIR], libname[FILE_MAX_LIBEXTRA], relname[FILE_MAX]; + char filepath[FILE_MAX_LIBEXTRA], root[FILE_MAXDIR], libname[FILE_MAX_LIBEXTRA], + relname[FILE_MAX]; char *group, *name; int totfiles = 0; RNA_string_get(op->ptr, "filename", relname); RNA_string_get(op->ptr, "directory", root); - BLI_path_join(path, sizeof(path), root, relname); + BLI_path_join(filepath, sizeof(filepath), root, relname); /* test if we have a valid data */ - if (!BKE_blendfile_library_path_explode(path, libname, &group, &name)) { - BKE_reportf(op->reports, RPT_ERROR, "'%s': not a library", path); + if (!BKE_blendfile_library_path_explode(filepath, libname, &group, &name)) { + BKE_reportf(op->reports, RPT_ERROR, "'%s': not a library", filepath); return OPERATOR_CANCELLED; } if (!group) { - BKE_reportf(op->reports, RPT_ERROR, "'%s': nothing indicated", path); + BKE_reportf(op->reports, RPT_ERROR, "'%s': nothing indicated", filepath); return OPERATOR_CANCELLED; } if (BLI_path_cmp(BKE_main_blendfile_path(bmain), libname) == 0) { - BKE_reportf(op->reports, RPT_ERROR, "'%s': cannot use current file as library", path); + BKE_reportf(op->reports, RPT_ERROR, "'%s': cannot use current file as library", filepath); return OPERATOR_CANCELLED; } @@ -239,13 +239,13 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) totfiles = RNA_property_collection_length(op->ptr, prop); if (totfiles == 0) { if (!name) { - BKE_reportf(op->reports, RPT_ERROR, "'%s': nothing indicated", path); + BKE_reportf(op->reports, RPT_ERROR, "'%s': nothing indicated", filepath); return OPERATOR_CANCELLED; } } } else if (!name) { - BKE_reportf(op->reports, RPT_ERROR, "'%s': nothing indicated", path); + BKE_reportf(op->reports, RPT_ERROR, "'%s': nothing indicated", filepath); return OPERATOR_CANCELLED; } @@ -291,10 +291,10 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) RNA_BEGIN (op->ptr, itemptr, "files") { RNA_string_get(&itemptr, "name", relname); - BLI_path_join(path, sizeof(path), root, relname); + BLI_path_join(filepath, sizeof(filepath), root, relname); - if (BKE_blendfile_library_path_explode(path, libname, &group, &name)) { - if (!wm_link_append_item_poll(NULL, path, group, name, do_append)) { + if (BKE_blendfile_library_path_explode(filepath, libname, &group, &name)) { + if (!wm_link_append_item_poll(NULL, filepath, group, name, do_append)) { continue; } @@ -310,12 +310,12 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) RNA_BEGIN (op->ptr, itemptr, "files") { RNA_string_get(&itemptr, "name", relname); - BLI_path_join(path, sizeof(path), root, relname); + BLI_path_join(filepath, sizeof(filepath), root, relname); - if (BKE_blendfile_library_path_explode(path, libname, &group, &name)) { + if (BKE_blendfile_library_path_explode(filepath, libname, &group, &name)) { BlendfileLinkAppendContextItem *item; - if (!wm_link_append_item_poll(op->reports, path, group, name, do_append)) { + if (!wm_link_append_item_poll(op->reports, filepath, group, name, do_append)) { continue; } @@ -674,7 +674,7 @@ static int wm_lib_relocate_exec_do(bContext *C, wmOperator *op, bool do_reload) PropertyRNA *prop; BlendfileLinkAppendContext *lapp_context; - char path[FILE_MAX], root[FILE_MAXDIR], libname[FILE_MAX], relname[FILE_MAX]; + char filepath[FILE_MAX], root[FILE_MAXDIR], libname[FILE_MAX], relname[FILE_MAX]; short flag = 0; if (RNA_boolean_get(op->ptr, "relative_path")) { @@ -697,23 +697,23 @@ static int wm_lib_relocate_exec_do(bContext *C, wmOperator *op, bool do_reload) return OPERATOR_CANCELLED; } - BLI_path_join(path, sizeof(path), root, libname); + BLI_path_join(filepath, sizeof(filepath), root, libname); - if (!BLI_exists(path)) { + if (!BLI_exists(filepath)) { BKE_reportf(op->reports, RPT_ERROR_INVALID_INPUT, "Trying to reload or relocate library '%s' to invalid path '%s'", lib->id.name, - path); + filepath); return OPERATOR_CANCELLED; } - if (BLI_path_cmp(BKE_main_blendfile_path(bmain), path) == 0) { + if (BLI_path_cmp(BKE_main_blendfile_path(bmain), filepath) == 0) { BKE_reportf(op->reports, RPT_ERROR_INVALID_INPUT, "Cannot relocate library '%s' to current blend file '%s'", lib->id.name, - path); + filepath); return OPERATOR_CANCELLED; } @@ -721,13 +721,13 @@ static int wm_lib_relocate_exec_do(bContext *C, wmOperator *op, bool do_reload) BLO_library_link_params_init_with_context( &lapp_params, bmain, flag, 0, CTX_data_scene(C), CTX_data_view_layer(C), NULL); - if (BLI_path_cmp(lib->filepath_abs, path) == 0) { + if (BLI_path_cmp(lib->filepath_abs, filepath) == 0) { CLOG_INFO(&LOG, 4, "We are supposed to reload '%s' lib (%d)", lib->filepath, lib->id.us); do_reload = true; lapp_context = BKE_blendfile_link_append_context_new(&lapp_params); - BKE_blendfile_link_append_context_library_add(lapp_context, path, NULL); + BKE_blendfile_link_append_context_library_add(lapp_context, filepath, NULL); } else { int totfiles = 0; @@ -753,21 +753,21 @@ static int wm_lib_relocate_exec_do(bContext *C, wmOperator *op, bool do_reload) RNA_BEGIN (op->ptr, itemptr, "files") { RNA_string_get(&itemptr, "name", relname); - BLI_path_join(path, sizeof(path), root, relname); + BLI_path_join(filepath, sizeof(filepath), root, relname); - if (BLI_path_cmp(path, lib->filepath_abs) == 0 || !BKE_blendfile_extension_check(relname)) - { + if (BLI_path_cmp(filepath, lib->filepath_abs) == 0 || + !BKE_blendfile_extension_check(relname)) { continue; } - CLOG_INFO(&LOG, 4, "\tCandidate new lib to reload datablocks from: %s", path); - BKE_blendfile_link_append_context_library_add(lapp_context, path, NULL); + CLOG_INFO(&LOG, 4, "\tCandidate new lib to reload datablocks from: %s", filepath); + BKE_blendfile_link_append_context_library_add(lapp_context, filepath, NULL); } RNA_END; } else { - CLOG_INFO(&LOG, 4, "\tCandidate new lib to reload datablocks from: %s", path); - BKE_blendfile_link_append_context_library_add(lapp_context, path, NULL); + CLOG_INFO(&LOG, 4, "\tCandidate new lib to reload datablocks from: %s", filepath); + BKE_blendfile_link_append_context_library_add(lapp_context, filepath, NULL); } } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 97e81790093..8fdeac3faa4 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1291,15 +1291,15 @@ ID *WM_operator_drop_load_path(bContext *C, wmOperator *op, const short idcode) /* check input variables */ if (RNA_struct_property_is_set(op->ptr, "filepath")) { const bool is_relative_path = RNA_boolean_get(op->ptr, "relative_path"); - char path[FILE_MAX]; + char filepath[FILE_MAX]; bool exists = false; - RNA_string_get(op->ptr, "filepath", path); + RNA_string_get(op->ptr, "filepath", filepath); errno = 0; if (idcode == ID_IM) { - id = (ID *)BKE_image_load_exists_ex(bmain, path, &exists); + id = (ID *)BKE_image_load_exists_ex(bmain, filepath, &exists); } else { BLI_assert_unreachable(); @@ -1310,7 +1310,7 @@ ID *WM_operator_drop_load_path(bContext *C, wmOperator *op, const short idcode) RPT_ERROR, "Cannot read %s '%s': %s", BKE_idtype_idcode_to_name(idcode), - path, + filepath, errno ? strerror(errno) : TIP_("unsupported format")); return NULL; } -- 2.30.2 From 7eeca95502a77baa452b2144fb8c01605888777a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 5 Jun 2023 11:04:53 +1000 Subject: [PATCH 53/63] PyAPI: rename filename to filepath for RNA API functions - Depsgraph.debug_relations_graphviz - Depsgraph.debug_stats_gnuplot - RenderLayer.load_from_file - RenderResult.load_from_file - bpy.app.icons.new_triangles_from_file --- source/blender/makesrna/intern/rna_depsgraph.c | 18 +++++++++--------- source/blender/makesrna/intern/rna_render.c | 8 ++++---- source/blender/python/intern/bpy_app_icons.c | 16 ++++++++-------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/source/blender/makesrna/intern/rna_depsgraph.c b/source/blender/makesrna/intern/rna_depsgraph.c index a6fdc8c201d..b42422be640 100644 --- a/source/blender/makesrna/intern/rna_depsgraph.c +++ b/source/blender/makesrna/intern/rna_depsgraph.c @@ -246,9 +246,9 @@ static bool rna_DepsgraphUpdate_is_updated_geometry_get(PointerRNA *ptr) /* **************** Depsgraph **************** */ -static void rna_Depsgraph_debug_relations_graphviz(Depsgraph *depsgraph, const char *filename) +static void rna_Depsgraph_debug_relations_graphviz(Depsgraph *depsgraph, const char *filepath) { - FILE *f = fopen(filename, "w"); + FILE *f = fopen(filepath, "w"); if (f == NULL) { return; } @@ -257,14 +257,14 @@ static void rna_Depsgraph_debug_relations_graphviz(Depsgraph *depsgraph, const c } static void rna_Depsgraph_debug_stats_gnuplot(Depsgraph *depsgraph, - const char *filename, - const char *output_filename) + const char *filepath, + const char *output_filepath) { - FILE *f = fopen(filename, "w"); + FILE *f = fopen(filepath, "w"); if (f == NULL) { return; } - DEG_debug_stats_gnuplot(depsgraph, f, "Timing Statistics", output_filename); + DEG_debug_stats_gnuplot(depsgraph, f, "Timing Statistics", output_filepath); fclose(f); } @@ -695,15 +695,15 @@ static void rna_def_depsgraph(BlenderRNA *brna) func = RNA_def_function( srna, "debug_relations_graphviz", "rna_Depsgraph_debug_relations_graphviz"); parm = RNA_def_string_file_path( - func, "filename", NULL, FILE_MAX, "File Name", "Output path for the graphviz debug file"); + func, "filepath", NULL, FILE_MAX, "File Name", "Output path for the graphviz debug file"); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); func = RNA_def_function(srna, "debug_stats_gnuplot", "rna_Depsgraph_debug_stats_gnuplot"); parm = RNA_def_string_file_path( - func, "filename", NULL, FILE_MAX, "File Name", "Output path for the gnuplot debug file"); + func, "filepath", NULL, FILE_MAX, "File Name", "Output path for the gnuplot debug file"); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); parm = RNA_def_string_file_path(func, - "output_filename", + "output_filepath", NULL, FILE_MAX, "Output File Name", diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index e2634e2392f..a0a58875ddc 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -1001,7 +1001,7 @@ static void rna_def_render_result(BlenderRNA *brna) RNA_def_function_flag(func, FUNC_USE_REPORTS); parm = RNA_def_string_file_name( func, - "filename", + "filepath", NULL, FILE_MAX, "File Name", @@ -1122,11 +1122,11 @@ static void rna_def_render_layer(BlenderRNA *brna) RNA_def_function_flag(func, FUNC_USE_REPORTS); parm = RNA_def_string( func, - "filename", + "filepath", NULL, 0, - "Filename", - "Filename to load into this render tile, must be no smaller than the renderlayer"); + "File Path", + "File path to load into this render tile, must be no smaller than the renderlayer"); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); RNA_def_int(func, "x", diff --git a/source/blender/python/intern/bpy_app_icons.c b/source/blender/python/intern/bpy_app_icons.c index cd79d188dc0..bcd66904c45 100644 --- a/source/blender/python/intern/bpy_app_icons.c +++ b/source/blender/python/intern/bpy_app_icons.c @@ -87,12 +87,12 @@ static PyObject *bpy_app_icons_new_triangles(PyObject *UNUSED(self), PyObject *a } PyDoc_STRVAR(bpy_app_icons_new_triangles_from_file_doc, - ".. function:: new_triangles_from_file(filename)\n" + ".. function:: new_triangles_from_file(filepath)\n" "\n" " Create a new icon from triangle geometry.\n" "\n" - " :arg filename: File path.\n" - " :type filename: string.\n" + " :arg filepath: File path.\n" + " :type filepath: string.\n" " :return: Unique icon value (pass to interface ``icon_value`` argument).\n" " :rtype: int\n"); static PyObject *bpy_app_icons_new_triangles_from_file(PyObject *UNUSED(self), @@ -100,20 +100,20 @@ static PyObject *bpy_app_icons_new_triangles_from_file(PyObject *UNUSED(self), PyObject *kw) { /* bytes */ - char *filename; + char *filepath; - static const char *_keywords[] = {"filename", NULL}; + static const char *_keywords[] = {"filepath", NULL}; static _PyArg_Parser _parser = { - "s" /* `filename` */ + "s" /* `filepath` */ ":new_triangles_from_file", _keywords, 0, }; - if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, &filename)) { + if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, &filepath)) { return NULL; } - struct Icon_Geom *geom = BKE_icon_geom_from_file(filename); + struct Icon_Geom *geom = BKE_icon_geom_from_file(filepath); if (geom == NULL) { PyErr_SetString(PyExc_ValueError, "Unable to load from file"); return NULL; -- 2.30.2 From 75a93813e58fecb978383844153d91a24f04a78e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 5 Jun 2023 12:17:13 +1000 Subject: [PATCH 54/63] BLI_string: add BLI_strchr_or_end Returning the pointer to the null byte when the character isn't found is useful when handling null terminated strings that contain newlines. This means the return value is never null and the line span always ends at the resulting value. --- source/blender/blenlib/BLI_string.h | 10 ++++++++++ source/blender/blenlib/intern/string.c | 15 +++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h index 5f237418171..5afeabb0867 100644 --- a/source/blender/blenlib/BLI_string.h +++ b/source/blender/blenlib/BLI_string.h @@ -114,6 +114,16 @@ size_t BLI_strcpy_rlen(char *__restrict dst, const char *__restrict src) ATTR_WA char *BLI_strncat(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1, 2); +/** + * A version of `strchr` that returns the end of the string (point to `\0`) + * if the character is not found. + * + * Useful for stepping over newlines up until the last line. + */ +const char *BLI_strchr_or_end(const char *str, + char ch) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL + ATTR_NONNULL(1); + /** * Return the range of the quoted string (excluding quotes) `str` after `prefix`. * diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c index b9af76c4ac0..0e25312279a 100644 --- a/source/blender/blenlib/intern/string.c +++ b/source/blender/blenlib/intern/string.c @@ -988,6 +988,21 @@ size_t BLI_strnlen(const char *s, const size_t maxlen) /** \} */ +/* -------------------------------------------------------------------- */ +/** \name String Scanning + * \{ */ + +const char *BLI_strchr_or_end(const char *str, const char ch) +{ + const char *p = str; + while (!ELEM(*p, ch, '\0')) { + p++; + } + return p; +} + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name String Case Conversion * \{ */ -- 2.30.2 From 60e0589f68ca686fa25cdcf1edf30929470b60cb Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 5 Jun 2023 12:24:57 +1000 Subject: [PATCH 55/63] Cleanup: use BLI_strchr_or_end to simplify new-line stepping - DRW_draw_region_engine_info: - Remove duplicate line drawing for the last line. - Remove string copying, pass the length to BLF_draw_default instead. - Resolve a potential buffer overflow as the source string length was used to define the destinations maximum size. - CONSOLE_OT_paste: - Remove the need to null-terminate each line. - Buffer stepping uses const values - console_line_insert no longer strips the string it inserts. - CONSOLE_OT_insert: - New lines in the middle of text now reports an error, new lines at the end of text is stripped (as before). --- source/blender/draw/intern/draw_manager.c | 30 +++----- .../editors/interface/interface_query.cc | 8 +-- .../editors/space_console/console_ops.c | 70 +++++++++++-------- 3 files changed, 50 insertions(+), 58 deletions(-) diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 1e989b1baf0..8c41c1e161f 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1137,10 +1137,6 @@ void DRW_draw_region_engine_info(int xoffset, int *yoffset, int line_height) { DRW_ENABLED_ENGINE_ITER (DST.view_data_active, engine, data) { if (data->info[0] != '\0') { - char *chr_current = data->info; - char *chr_start = chr_current; - int line_len = 0; - const int font_id = BLF_default(); UI_FontThemeColor(font_id, TH_TEXT_HI); @@ -1148,24 +1144,14 @@ void DRW_draw_region_engine_info(int xoffset, int *yoffset, int line_height) BLF_shadow(font_id, 5, (const float[4]){0.0f, 0.0f, 0.0f, 1.0f}); BLF_shadow_offset(font_id, 1, -1); - while (*chr_current++ != '\0') { - line_len++; - if (*chr_current == '\n') { - char info[GPU_INFO_SIZE]; - BLI_strncpy(info, chr_start, line_len + 1); - *yoffset -= line_height; - BLF_draw_default(xoffset, *yoffset, 0.0f, info, sizeof(info)); - - /* Re-start counting. */ - chr_start = chr_current + 1; - line_len = -1; - } - } - - char info[GPU_INFO_SIZE]; - BLI_strncpy(info, chr_start, line_len + 1); - *yoffset -= line_height; - BLF_draw_default(xoffset, *yoffset, 0.0f, info, sizeof(info)); + const char *buf_step = data->info; + do { + const char *buf = buf_step; + buf_step = BLI_strchr_or_end(buf, '\n'); + const int buf_len = buf_step - buf; + *yoffset -= line_height; + BLF_draw_default(xoffset, *yoffset, 0.0f, buf, buf_len); + } while (*buf_step ? ((void)buf_step++, true) : false); BLF_disable(font_id, BLF_SHADOW); } diff --git a/source/blender/editors/interface/interface_query.cc b/source/blender/editors/interface/interface_query.cc index dd20fc07cf5..72ecf9ece39 100644 --- a/source/blender/editors/interface/interface_query.cc +++ b/source/blender/editors/interface/interface_query.cc @@ -596,12 +596,8 @@ size_t ui_but_tip_len_only_first_line(const uiBut *but) if (but->tip == nullptr) { return 0; } - - const char *str_sep = strchr(but->tip, '\n'); - if (str_sep != nullptr) { - return (str_sep - but->tip); - } - return strlen(but->tip); + const char *str_sep = BLI_strchr_or_end(but->tip, '\n'); + return (str_sep - but->tip); } /** \} */ diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c index ac089ab52c7..cbed73d286d 100644 --- a/source/blender/editors/space_console/console_ops.c +++ b/source/blender/editors/space_console/console_ops.c @@ -24,6 +24,7 @@ #include "BLI_utildefines.h" #include "BKE_context.h" +#include "BKE_report.h" #include "WM_api.h" #include "WM_types.h" @@ -304,19 +305,16 @@ static void console_line_verify_length(ConsoleLine *ci, int len) } } -static int console_line_insert(ConsoleLine *ci, char *str) +static void console_line_insert(ConsoleLine *ci, const char *str, int len) { - int len = strlen(str); - - if (len > 0 && str[len - 1] == '\n') { /* stop new lines being pasted at the end of lines */ - str[len - 1] = '\0'; - len--; - } - if (len == 0) { - return 0; + return; } + BLI_assert(len <= strlen(str)); + /* The caller must delimit new-lines. */ + BLI_assert(str[len - 1] != '\n'); + console_line_verify_length(ci, len + ci->len); memmove(ci->line + ci->cursor + len, ci->line + ci->cursor, (ci->len - ci->cursor) + 1); @@ -324,8 +322,6 @@ static int console_line_insert(ConsoleLine *ci, char *str) ci->len += len; ci->cursor += len; - - return len; } /** @@ -460,8 +456,25 @@ static int console_insert_exec(bContext *C, wmOperator *op) memset(str, ' ', len); str[len] = '\0'; } + else { + len = strlen(str); + } - len = console_line_insert(ci, str); + /* Allow trailing newlines (but strip them). */ + while (len > 0 && str[len - 1] == '\n') { + len--; + str[len] = '\0'; + } + + if (strchr(str, '\n')) { + BKE_report(op->reports, RPT_ERROR, "New lines unsupported, call this operator multiple times"); + /* Force cancel. */ + len = 0; + } + + if (len != 0) { + console_line_insert(ci, str, len); + } MEM_freeN(str); @@ -1076,31 +1089,28 @@ static int console_paste_exec(bContext *C, wmOperator *op) SpaceConsole *sc = CTX_wm_space_console(C); ARegion *region = CTX_wm_region(C); ConsoleLine *ci = console_history_verify(C); - int buf_len; - - char *buf_str = WM_clipboard_text_get(selection, true, &buf_len); - char *buf_step, *buf_next; + int buf_str_len; + char *buf_str = WM_clipboard_text_get(selection, true, &buf_str_len); if (buf_str == NULL) { return OPERATOR_CANCELLED; } - - buf_step = buf_str; - - while ((buf_next = buf_step) && buf_next[0] != '\0') { - buf_step = strchr(buf_next, '\n'); - if (buf_step) { - *buf_step = '\0'; - buf_step++; - } - - if (buf_next != buf_str) { + if (*buf_str == '\0') { + MEM_freeN(buf_str); + return OPERATOR_CANCELLED; + } + const char *buf_step = buf_str; + do { + const char *buf = buf_step; + buf_step = (char *)BLI_strchr_or_end(buf, '\n'); + const int buf_len = buf_step - buf; + if (buf != buf_str) { WM_operator_name_call(C, "CONSOLE_OT_execute", WM_OP_EXEC_DEFAULT, NULL, NULL); ci = console_history_verify(C); } - - console_select_offset(sc, console_line_insert(ci, buf_next)); - } + console_line_insert(ci, buf, buf_len); + console_select_offset(sc, buf_len); + } while (*buf_step ? ((void)buf_step++, true) : false); MEM_freeN(buf_str); -- 2.30.2 From ddf835bd33e41cb6e944ec7cd36a196afd3d3933 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 5 Jun 2023 12:42:46 +1000 Subject: [PATCH 56/63] Cleanup: replace list-base count_at_most with is_single for clarity --- source/blender/blenkernel/intern/layer.cc | 2 +- source/blender/blenloader/intern/versioning_280.cc | 2 +- source/blender/editors/armature/pose_transform.c | 2 +- source/blender/windowmanager/intern/wm_dragdrop.cc | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/layer.cc b/source/blender/blenkernel/intern/layer.cc index f42b703a660..2f5930b513b 100644 --- a/source/blender/blenkernel/intern/layer.cc +++ b/source/blender/blenkernel/intern/layer.cc @@ -1317,7 +1317,7 @@ void BKE_layer_collection_sync(const Scene *scene, ViewLayer *view_layer) #ifndef NDEBUG { - BLI_assert_msg(BLI_listbase_count_at_most(&view_layer->layer_collections, 2) == 1, + BLI_assert_msg(BLI_listbase_is_single(&view_layer->layer_collections), "ViewLayer's first level of children layer collections should always have " "exactly one item"); diff --git a/source/blender/blenloader/intern/versioning_280.cc b/source/blender/blenloader/intern/versioning_280.cc index 51f4482d51e..caae70b5854 100644 --- a/source/blender/blenloader/intern/versioning_280.cc +++ b/source/blender/blenloader/intern/versioning_280.cc @@ -1257,7 +1257,7 @@ void do_versions_after_linking_280(FileData *fd, Main *bmain) space_outliner->outlinevis = SO_VIEW_LAYER; - if (BLI_listbase_count_at_most(&layer->layer_collections, 2) == 1) { + if (BLI_listbase_is_single(&layer->layer_collections)) { if (space_outliner->treestore == nullptr) { space_outliner->treestore = BLI_mempool_create( sizeof(TreeStoreElem), 1, 512, BLI_MEMPOOL_ALLOW_ITER); diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c index 78ff70f819e..42617580963 100644 --- a/source/blender/editors/armature/pose_transform.c +++ b/source/blender/editors/armature/pose_transform.c @@ -864,7 +864,7 @@ static int pose_paste_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } /* Make sure data from this file is usable for pose paste. */ - if (BLI_listbase_count_at_most(&temp_bmain->objects, 2) != 1) { + if (!BLI_listbase_is_single(&temp_bmain->objects)) { BKE_report(op->reports, RPT_ERROR, "Internal clipboard is not from pose mode"); BKE_main_free(temp_bmain); return OPERATOR_CANCELLED; diff --git a/source/blender/windowmanager/intern/wm_dragdrop.cc b/source/blender/windowmanager/intern/wm_dragdrop.cc index 29d540623e7..44ee394ed49 100644 --- a/source/blender/windowmanager/intern/wm_dragdrop.cc +++ b/source/blender/windowmanager/intern/wm_dragdrop.cc @@ -832,7 +832,7 @@ const char *WM_drag_get_item_name(wmDrag *drag) switch (drag->type) { case WM_DRAG_ID: { ID *id = WM_drag_get_local_ID(drag, 0); - bool single = (BLI_listbase_count_at_most(&drag->ids, 2) == 1); + bool single = BLI_listbase_is_single(&drag->ids); if (single) { return id->name + 2; -- 2.30.2 From 36eebb48b5109080be21c6bf69bdf249a36e414e Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 5 Jun 2023 09:28:19 +0200 Subject: [PATCH 57/63] Metal: Silence Console Output This PR silences console output during statup phase of blender. During startup logging isn't yet initialized and print statements where used. Logging is initialized during the first construction of a Metal Context. The console prints are now hidden by behind the '--debug-gpu' command line option. Pull Request: https://projects.blender.org/blender/blender/pulls/108593 --- source/blender/gpu/metal/mtl_backend.mm | 32 ++++++++++++++----------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/source/blender/gpu/metal/mtl_backend.mm b/source/blender/gpu/metal/mtl_backend.mm index 6d2289fcc71..a50dfe2c8ce 100644 --- a/source/blender/gpu/metal/mtl_backend.mm +++ b/source/blender/gpu/metal/mtl_backend.mm @@ -189,7 +189,9 @@ void MTLBackend::platform_init(MTLContext *ctx) const char *vendor = [gpu_name UTF8String]; const char *renderer = "Metal API"; const char *version = "1.2"; - printf("METAL API - DETECTED GPU: %s\n", vendor); + if (G.debug & G_DEBUG_GPU) { + printf("METAL API - DETECTED GPU: %s\n", vendor); + } /* macOS is the only supported platform, but check to ensure we are not building with Metal * enablement on another platform. */ @@ -229,7 +231,7 @@ void MTLBackend::platform_init(MTLContext *ctx) device = GPU_DEVICE_SOFTWARE; driver = GPU_DRIVER_SOFTWARE; } - else { + else if (G.debug & G_DEBUG_GPU) { printf("Warning: Could not find a matching GPU name. Things may not behave as expected.\n"); printf("Detected configuration:\n"); printf("Vendor: %s\n", vendor); @@ -325,19 +327,21 @@ bool MTLBackend::metal_is_supported() bool result = supports_argument_buffers_tier2 && supports_barycentrics && supported_os_version && supported_metal_version; - if (!supports_argument_buffers_tier2) { - printf("[Metal] Device does not support argument buffers tier 2\n"); - } - if (!supports_barycentrics) { - printf("[Metal] Device does not support barycentrics coordinates\n"); - } - if (!supported_metal_version) { - printf("[Metal] Device does not support metal 2.2 or higher\n"); - } + if (G.debug & G_DEBUG_GPU) { + if (!supports_argument_buffers_tier2) { + printf("[Metal] Device does not support argument buffers tier 2\n"); + } + if (!supports_barycentrics) { + printf("[Metal] Device does not support barycentrics coordinates\n"); + } + if (!supported_metal_version) { + printf("[Metal] Device does not support metal 2.2 or higher\n"); + } - if (result) { - printf("Device with name %s supports metal minimum requirements\n", - [[device name] UTF8String]); + if (result) { + printf("Device with name %s supports metal minimum requirements\n", + [[device name] UTF8String]); + } } return result; -- 2.30.2 From 16701aac28f60090fb97657a58b903cdf06836df Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 8 Jun 2023 09:18:37 +0200 Subject: [PATCH 58/63] Remove double define. --- extern/vulkan_memory_allocator/vk_mem_alloc_impl.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/extern/vulkan_memory_allocator/vk_mem_alloc_impl.cc b/extern/vulkan_memory_allocator/vk_mem_alloc_impl.cc index 66725c64758..67bfafbd05d 100644 --- a/extern/vulkan_memory_allocator/vk_mem_alloc_impl.cc +++ b/extern/vulkan_memory_allocator/vk_mem_alloc_impl.cc @@ -8,9 +8,6 @@ #endif #define VMA_IMPLEMENTATION -#ifdef DEBUG -#define VMA_ASSERT(test) -#endif /* * Disabling internal asserts of VMA. -- 2.30.2 From 8abf5be8001b696c66c500f2754e3ffdba409432 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 8 Jun 2023 09:22:15 +0200 Subject: [PATCH 59/63] Remove obsolete code --- source/blender/gpu/vulkan/vk_context.hh | 5 ----- 1 file changed, 5 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_context.hh b/source/blender/gpu/vulkan/vk_context.hh index 39dad8d0227..0679f227a03 100644 --- a/source/blender/gpu/vulkan/vk_context.hh +++ b/source/blender/gpu/vulkan/vk_context.hh @@ -26,9 +26,6 @@ class VKContext : public Context, NonCopyable { void *ghost_context_; - /** Workarounds. */ - static bool component_24_workaround; - public: VKContext(void *ghost_window, void *ghost_context); virtual ~VKContext(); @@ -73,8 +70,6 @@ class VKContext : public Context, NonCopyable { const VKStateManager &state_manager_get() const; VKStateManager &state_manager_get(); - - static bool get_component_24_workaround(); }; } // namespace blender::gpu -- 2.30.2 From ef4525b1ff53b0ff9bfa088989b7be194dafdc63 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 8 Jun 2023 12:46:09 +0200 Subject: [PATCH 60/63] Experiment with custom vk image views. --- .../blender/gpu/vulkan/vk_data_conversion.cc | 2 +- source/blender/gpu/vulkan/vk_framebuffer.cc | 15 +++- source/blender/gpu/vulkan/vk_texture.cc | 77 +++++++++++++++---- source/blender/gpu/vulkan/vk_texture.hh | 27 +++++-- 4 files changed, 95 insertions(+), 26 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_data_conversion.cc b/source/blender/gpu/vulkan/vk_data_conversion.cc index 661b71420b3..3a78eeb955a 100644 --- a/source/blender/gpu/vulkan/vk_data_conversion.cc +++ b/source/blender/gpu/vulkan/vk_data_conversion.cc @@ -243,6 +243,7 @@ static ConversionType type_of_conversion_uint(eGPUTextureFormat device_format) case GPU_RG32UI: case GPU_R32UI: case GPU_DEPTH_COMPONENT24: + case GPU_DEPTH24_STENCIL8: return ConversionType::PASS_THROUGH; case GPU_RGBA16UI: @@ -284,7 +285,6 @@ static ConversionType type_of_conversion_uint(eGPUTextureFormat device_format) case GPU_RGB10_A2: case GPU_RGB10_A2UI: case GPU_R11F_G11F_B10F: - case GPU_DEPTH24_STENCIL8: case GPU_SRGB8_A8: case GPU_RGBA8_SNORM: case GPU_RGBA16_SNORM: diff --git a/source/blender/gpu/vulkan/vk_framebuffer.cc b/source/blender/gpu/vulkan/vk_framebuffer.cc index d3107eb0250..0b0ae1c41c4 100644 --- a/source/blender/gpu/vulkan/vk_framebuffer.cc +++ b/source/blender/gpu/vulkan/vk_framebuffer.cc @@ -403,6 +403,7 @@ void VKFrameBuffer::render_pass_create() VKTexture &texture = *static_cast(unwrap(attachment.tex)); texture.ensure_allocated(); /* TODO: use image_view for attachment.mip */ + // texture.mip_range_set(attachment.mip, attachment.mip); image_views[attachment_location] = texture.vk_image_view_handle(); VkAttachmentDescription &attachment_description = @@ -412,8 +413,8 @@ void VKFrameBuffer::render_pass_create() attachment_description.samples = VK_SAMPLE_COUNT_1_BIT; attachment_description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; attachment_description.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - attachment_description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - attachment_description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; + attachment_description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + attachment_description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; attachment_description.initialLayout = texture.current_layout_get(); attachment_description.finalLayout = texture.current_layout_get(); @@ -468,8 +469,11 @@ void VKFrameBuffer::render_pass_create() render_pass_info.pSubpasses = &subpass; const VKDevice &device = VKBackend::get().device_get(); - vkCreateRenderPass( + VkResult result = vkCreateRenderPass( device.device_get(), &render_pass_info, vk_allocation_callbacks, &vk_render_pass_); + if (result != VK_SUCCESS) { + BLI_assert_unreachable(); + } /* We might want to split frame-buffer and render pass. */ VkFramebufferCreateInfo framebuffer_create_info = {}; @@ -481,8 +485,11 @@ void VKFrameBuffer::render_pass_create() framebuffer_create_info.height = height_; framebuffer_create_info.layers = 1; - vkCreateFramebuffer( + result = vkCreateFramebuffer( device.device_get(), &framebuffer_create_info, vk_allocation_callbacks, &vk_framebuffer_); + if (result != VK_SUCCESS) { + BLI_assert_unreachable(); + } } void VKFrameBuffer::render_pass_free() diff --git a/source/blender/gpu/vulkan/vk_texture.cc b/source/blender/gpu/vulkan/vk_texture.cc index 81ed84c80c0..e5ee5c9eb3b 100644 --- a/source/blender/gpu/vulkan/vk_texture.cc +++ b/source/blender/gpu/vulkan/vk_texture.cc @@ -83,6 +83,9 @@ void VKTexture::generate_mipmap() *this, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, Span(&image_blit, 1)); + /* TODO: Until we do actual command encoding we need to submit each transfer operation + * individually. */ + command_buffer.submit(); } /* Ensure that all mipmap levels are in `VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL`. All miplevels are * except the last one. */ @@ -148,9 +151,12 @@ void VKTexture::swizzle_set(const char /*swizzle_mask*/[4]) NOT_YET_IMPLEMENTED; } -void VKTexture::mip_range_set(int /*min*/, int /*max*/) +void VKTexture::mip_range_set(int min, int max) { - NOT_YET_IMPLEMENTED; + mip_min_ = min; + mip_max_ = max; + + flags_ |= IMAGE_VIEW_DIRTY; } void VKTexture::read_sub(int mip, eGPUDataFormat format, const int area[4], void *r_data) @@ -430,20 +436,6 @@ bool VKTexture::allocate() /* Promote image to the correct layout. */ layout_ensure(context, VK_IMAGE_LAYOUT_GENERAL); - VK_ALLOCATION_CALLBACKS - VkImageViewCreateInfo image_view_info = {}; - image_view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - image_view_info.image = vk_image_; - image_view_info.viewType = to_vk_image_view_type(type_); - image_view_info.format = to_vk_format(format_); - image_view_info.components = to_vk_component_mapping(format_); - image_view_info.subresourceRange.aspectMask = to_vk_image_aspect_flag_bits(format_); - image_view_info.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS; - image_view_info.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; - - result = vkCreateImageView( - device.device_get(), &image_view_info, vk_allocation_callbacks, &vk_image_view_); - debug::object_label(vk_image_view_, name_); return result == VK_SUCCESS; } @@ -527,4 +519,57 @@ void VKTexture::layout_ensure(VKContext &context, } /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Mipmapping + * \{ */ + +void VKTexture::vk_image_view_ensure() +{ + if (flags_ & IMAGE_VIEW_DIRTY) { + vk_image_view_free(); + vk_image_view_create(); + flags_ &= ~IMAGE_VIEW_DIRTY; + } + BLI_assert(vk_image_view_ != VK_NULL_HANDLE); +} + +void VKTexture::vk_image_view_free() +{ + if (vk_image_view_ != VK_NULL_HANDLE) { + VK_ALLOCATION_CALLBACKS + const VKDevice &device = VKBackend::get().device_get(); + vkDestroyImageView(device.device_get(), vk_image_view_, vk_allocation_callbacks); + vk_image_view_ = VK_NULL_HANDLE; + } +} + +void VKTexture::vk_image_view_create() +{ + BLI_assert(vk_image_view_ == VK_NULL_HANDLE); + VK_ALLOCATION_CALLBACKS + VkImageViewCreateInfo image_view_info = {}; + image_view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + image_view_info.image = vk_image_; + image_view_info.viewType = to_vk_image_view_type(type_); + image_view_info.format = to_vk_format(format_); + image_view_info.components = to_vk_component_mapping(format_); + image_view_info.subresourceRange.aspectMask = to_vk_image_aspect_flag_bits(format_); + IndexRange mip_range = mip_map_range(); + image_view_info.subresourceRange.baseMipLevel = mip_range.first(); + image_view_info.subresourceRange.levelCount = mip_range.size(); + image_view_info.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; + + const VKDevice &device = VKBackend::get().device_get(); + vkCreateImageView( + device.device_get(), &image_view_info, vk_allocation_callbacks, &vk_image_view_); + debug::object_label(vk_image_view_, name_); +} + +IndexRange VKTexture::mip_map_range() const +{ + return IndexRange(mip_min_, mip_max_ - mip_min_ + 1); +} + +/** \} */ + } // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_texture.hh b/source/blender/gpu/vulkan/vk_texture.hh index c2bc41485d1..5a5ff3327a4 100644 --- a/source/blender/gpu/vulkan/vk_texture.hh +++ b/source/blender/gpu/vulkan/vk_texture.hh @@ -26,6 +26,10 @@ class VKTexture : public Texture { * can be done. */ VkImageLayout current_layout_ = VK_IMAGE_LAYOUT_UNDEFINED; + const int IMAGE_VIEW_DIRTY = (1 << 0); + + int flags_ = IMAGE_VIEW_DIRTY; + public: VKTexture(const char *name) : Texture(name) {} @@ -58,11 +62,6 @@ class VKTexture : public Texture { BLI_assert(vk_image_ != VK_NULL_HANDLE); return vk_image_; } - VkImageView vk_image_view_handle() const - { - BLI_assert(is_allocated()); - return vk_image_view_; - } void ensure_allocated(); @@ -123,6 +122,24 @@ class VKTexture : public Texture { VkImageLayout requested_layout); /** \} */ + + /* -------------------------------------------------------------------- */ + /** \name Mipmapping + * \{ */ + public: + VkImageView vk_image_view_handle() + { + vk_image_view_ensure(); + return vk_image_view_; + } + + private: + IndexRange mip_map_range() const; + void vk_image_view_ensure(); + void vk_image_view_free(); + void vk_image_view_create(); + + /** \} */ }; static inline VKTexture *unwrap(Texture *tex) -- 2.30.2 From 8c15503c70194fa98b2ac746e05b38c821dee4c5 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 8 Jun 2023 12:58:28 +0200 Subject: [PATCH 61/63] silence a vulkan error when starting blender. --- intern/ghost/intern/GHOST_ContextVK.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/ghost/intern/GHOST_ContextVK.cc b/intern/ghost/intern/GHOST_ContextVK.cc index 79489379707..840ff8f0040 100644 --- a/intern/ghost/intern/GHOST_ContextVK.cc +++ b/intern/ghost/intern/GHOST_ContextVK.cc @@ -709,7 +709,7 @@ static GHOST_TSuccess create_render_pass(VkDevice device, colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + colorAttachment.initialLayout = VK_IMAGE_LAYOUT_GENERAL; colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; VkAttachmentReference colorAttachmentRef = {}; -- 2.30.2 From e1e5f0bf54b779b180277de0b261522b09490e8f Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 8 Jun 2023 15:19:20 +0200 Subject: [PATCH 62/63] Workbench depth of field. --- source/blender/gpu/CMakeLists.txt | 2 + source/blender/gpu/vulkan/vk_buffer.cc | 8 ++- .../blender/gpu/vulkan/vk_descriptor_set.cc | 2 +- source/blender/gpu/vulkan/vk_framebuffer.cc | 8 ++- source/blender/gpu/vulkan/vk_framebuffer.hh | 3 + source/blender/gpu/vulkan/vk_image_view.cc | 68 +++++++++++++++++++ source/blender/gpu/vulkan/vk_image_view.hh | 44 ++++++++++++ source/blender/gpu/vulkan/vk_texture.cc | 26 ++----- source/blender/gpu/vulkan/vk_texture.hh | 13 ++-- 9 files changed, 143 insertions(+), 31 deletions(-) create mode 100644 source/blender/gpu/vulkan/vk_image_view.cc create mode 100644 source/blender/gpu/vulkan/vk_image_view.hh diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 30addfaa0b7..9d7e453210e 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -215,6 +215,7 @@ set(VULKAN_SRC vulkan/vk_drawlist.cc vulkan/vk_fence.cc vulkan/vk_framebuffer.cc + vulkan/vk_image_view.cc vulkan/vk_immediate.cc vulkan/vk_index_buffer.cc vulkan/vk_memory.cc @@ -250,6 +251,7 @@ set(VULKAN_SRC vulkan/vk_drawlist.hh vulkan/vk_fence.hh vulkan/vk_framebuffer.hh + vulkan/vk_image_view.hh vulkan/vk_immediate.hh vulkan/vk_index_buffer.hh vulkan/vk_memory.hh diff --git a/source/blender/gpu/vulkan/vk_buffer.cc b/source/blender/gpu/vulkan/vk_buffer.cc index dad8797b712..3f32c69e701 100644 --- a/source/blender/gpu/vulkan/vk_buffer.cc +++ b/source/blender/gpu/vulkan/vk_buffer.cc @@ -131,7 +131,9 @@ void VKBuffer::unmap() BLI_assert(is_mapped()); const VKDevice &device = VKBackend::get().device_get(); VmaAllocator allocator = device.mem_allocator_get(); - vmaUnmapMemory(allocator, allocation_); + if (allocator != VK_NULL_HANDLE) { + vmaUnmapMemory(allocator, allocation_); + } mapped_memory_ = nullptr; } @@ -143,7 +145,9 @@ bool VKBuffer::free() const VKDevice &device = VKBackend::get().device_get(); VmaAllocator allocator = device.mem_allocator_get(); - vmaDestroyBuffer(allocator, vk_buffer_, allocation_); + if (allocator != VK_NULL_HANDLE) { + vmaDestroyBuffer(allocator, vk_buffer_, allocation_); + } return true; } diff --git a/source/blender/gpu/vulkan/vk_descriptor_set.cc b/source/blender/gpu/vulkan/vk_descriptor_set.cc index 5751162bba1..3698aecd6fa 100644 --- a/source/blender/gpu/vulkan/vk_descriptor_set.cc +++ b/source/blender/gpu/vulkan/vk_descriptor_set.cc @@ -174,7 +174,7 @@ void VKDescriptorSetTracker::update(VKContext &context) binding.texture->layout_ensure(context, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); VkDescriptorImageInfo image_info = {}; image_info.sampler = binding.vk_sampler; - image_info.imageView = binding.texture->vk_image_view_handle(); + image_info.imageView = binding.texture->image_view_get().vk_handle(); image_info.imageLayout = binding.texture->current_layout_get(); image_infos.append(image_info); diff --git a/source/blender/gpu/vulkan/vk_framebuffer.cc b/source/blender/gpu/vulkan/vk_framebuffer.cc index 0b0ae1c41c4..9be30ba8bd1 100644 --- a/source/blender/gpu/vulkan/vk_framebuffer.cc +++ b/source/blender/gpu/vulkan/vk_framebuffer.cc @@ -372,6 +372,8 @@ void VKFrameBuffer::render_pass_create() std::array attachment_descriptions; std::array image_views; std::array attachment_references; + image_views_.clear(); + bool has_depth_attachment = false; bool found_attachment = false; int depth_location = -1; @@ -402,9 +404,8 @@ void VKFrameBuffer::render_pass_create() /* Ensure texture is allocated to ensure the image view. */ VKTexture &texture = *static_cast(unwrap(attachment.tex)); texture.ensure_allocated(); - /* TODO: use image_view for attachment.mip */ - // texture.mip_range_set(attachment.mip, attachment.mip); - image_views[attachment_location] = texture.vk_image_view_handle(); + image_views_.append(VKImageView(texture, attachment.mip, name_)); + image_views[attachment_location] = image_views_.last().vk_handle(); VkAttachmentDescription &attachment_description = attachment_descriptions[attachment_location]; @@ -505,6 +506,7 @@ void VKFrameBuffer::render_pass_free() vkDestroyRenderPass(device.device_get(), vk_render_pass_, vk_allocation_callbacks); vkDestroyFramebuffer(device.device_get(), vk_framebuffer_, vk_allocation_callbacks); } + image_views_.clear(); vk_render_pass_ = VK_NULL_HANDLE; vk_framebuffer_ = VK_NULL_HANDLE; } diff --git a/source/blender/gpu/vulkan/vk_framebuffer.hh b/source/blender/gpu/vulkan/vk_framebuffer.hh index d0addb9c8af..7f6d1c44314 100644 --- a/source/blender/gpu/vulkan/vk_framebuffer.hh +++ b/source/blender/gpu/vulkan/vk_framebuffer.hh @@ -15,6 +15,7 @@ #include "gpu_framebuffer_private.hh" #include "vk_common.hh" +#include "vk_image_view.hh" namespace blender::gpu { @@ -41,6 +42,8 @@ class VKFrameBuffer : public FrameBuffer { */ bool flip_viewport_ = false; + Vector image_views_; + public: /** * Create a conventional framebuffer to attach texture to. diff --git a/source/blender/gpu/vulkan/vk_image_view.cc b/source/blender/gpu/vulkan/vk_image_view.cc new file mode 100644 index 00000000000..b1ad74bc1da --- /dev/null +++ b/source/blender/gpu/vulkan/vk_image_view.cc @@ -0,0 +1,68 @@ +/* SPDX-FileCopyrightText: 2022 Blender Foundation + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup gpu + */ + +#include "vk_image_view.hh" +#include "vk_backend.hh" +#include "vk_debug.hh" +#include "vk_device.hh" +#include "vk_memory.hh" +#include "vk_texture.hh" + +namespace blender::gpu { + +VKImageView::VKImageView(VKTexture &texture, int mip_level, StringRefNull name) + : vk_image_view_(create_vk_image_view(texture, mip_level, name)) +{ + BLI_assert(vk_image_view_ != VK_NULL_HANDLE); +} + +VKImageView::VKImageView(VkImageView vk_image_view) : vk_image_view_(vk_image_view) +{ + BLI_assert(vk_image_view_ != VK_NULL_HANDLE); +} + +VKImageView::VKImageView(VKImageView &&other) +{ + vk_image_view_ = other.vk_image_view_; + other.vk_image_view_ = VK_NULL_HANDLE; +} + +VKImageView::~VKImageView() +{ + if (vk_image_view_ != VK_NULL_HANDLE) { + VK_ALLOCATION_CALLBACKS + const VKDevice &device = VKBackend::get().device_get(); + vkDestroyImageView(device.device_get(), vk_image_view_, vk_allocation_callbacks); + } +} +VkImageView VKImageView::create_vk_image_view(VKTexture &texture, + int mip_level, + StringRefNull name) +{ + + VK_ALLOCATION_CALLBACKS + VkImageViewCreateInfo image_view_info = {}; + image_view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + image_view_info.image = texture.vk_image_handle(); + image_view_info.viewType = to_vk_image_view_type(texture.type_get()); + image_view_info.format = to_vk_format(texture.format_get()); + image_view_info.components = to_vk_component_mapping(texture.format_get()); + image_view_info.subresourceRange.aspectMask = to_vk_image_aspect_flag_bits(texture.format_get()); + image_view_info.subresourceRange.baseMipLevel = mip_level; + image_view_info.subresourceRange.levelCount = 1; + image_view_info.subresourceRange.baseArrayLayer = 0; + image_view_info.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; + + const VKDevice &device = VKBackend::get().device_get(); + VkImageView image_view = VK_NULL_HANDLE; + vkCreateImageView(device.device_get(), &image_view_info, vk_allocation_callbacks, &image_view); + debug::object_label(image_view, name.c_str()); + return image_view; +} + +} // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_image_view.hh b/source/blender/gpu/vulkan/vk_image_view.hh new file mode 100644 index 00000000000..ce67e0f5dff --- /dev/null +++ b/source/blender/gpu/vulkan/vk_image_view.hh @@ -0,0 +1,44 @@ +/* SPDX-FileCopyrightText: 2022 Blender Foundation + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup gpu + */ + +#pragma once + +#include "vk_common.hh" + +#include "BLI_string_ref.hh" +#include "BLI_utility_mixins.hh" + +namespace blender::gpu { +class VKTexture; + +class VKImageView : NonCopyable { + VkImageView vk_image_view_ = VK_NULL_HANDLE; + + public: + VKImageView(VKTexture &texture, int mip_level, StringRefNull name); + + /** + * Wrap the given vk_image_view handle. Note that the vk_image_view handle ownership is + * transferred to VKImageView. + */ + VKImageView(VkImageView vk_image_view); + + VKImageView(VKImageView &&other); + ~VKImageView(); + + VkImageView vk_handle() const + { + BLI_assert(vk_image_view_ != VK_NULL_HANDLE); + return vk_image_view_; + } + + private: + static VkImageView create_vk_image_view(VKTexture &texture, int mip_level, StringRefNull name); +}; + +} // namespace blender::gpu \ No newline at end of file diff --git a/source/blender/gpu/vulkan/vk_texture.cc b/source/blender/gpu/vulkan/vk_texture.cc index e5ee5c9eb3b..6f27a9e975c 100644 --- a/source/blender/gpu/vulkan/vk_texture.cc +++ b/source/blender/gpu/vulkan/vk_texture.cc @@ -25,11 +25,9 @@ namespace blender::gpu { VKTexture::~VKTexture() { - VK_ALLOCATION_CALLBACKS if (is_allocated()) { const VKDevice &device = VKBackend::get().device_get(); vmaDestroyImage(device.mem_allocator_get(), vk_image_, allocation_); - vkDestroyImageView(device.device_get(), vk_image_view_, vk_allocation_callbacks); } } @@ -526,26 +524,13 @@ void VKTexture::layout_ensure(VKContext &context, void VKTexture::vk_image_view_ensure() { if (flags_ & IMAGE_VIEW_DIRTY) { - vk_image_view_free(); - vk_image_view_create(); + image_view_update(); flags_ &= ~IMAGE_VIEW_DIRTY; } - BLI_assert(vk_image_view_ != VK_NULL_HANDLE); } -void VKTexture::vk_image_view_free() +void VKTexture::image_view_update() { - if (vk_image_view_ != VK_NULL_HANDLE) { - VK_ALLOCATION_CALLBACKS - const VKDevice &device = VKBackend::get().device_get(); - vkDestroyImageView(device.device_get(), vk_image_view_, vk_allocation_callbacks); - vk_image_view_ = VK_NULL_HANDLE; - } -} - -void VKTexture::vk_image_view_create() -{ - BLI_assert(vk_image_view_ == VK_NULL_HANDLE); VK_ALLOCATION_CALLBACKS VkImageViewCreateInfo image_view_info = {}; image_view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; @@ -560,9 +545,10 @@ void VKTexture::vk_image_view_create() image_view_info.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; const VKDevice &device = VKBackend::get().device_get(); - vkCreateImageView( - device.device_get(), &image_view_info, vk_allocation_callbacks, &vk_image_view_); - debug::object_label(vk_image_view_, name_); + VkImageView image_view = VK_NULL_HANDLE; + vkCreateImageView(device.device_get(), &image_view_info, vk_allocation_callbacks, &image_view); + debug::object_label(image_view, name_); + image_view_.emplace(image_view); } IndexRange VKTexture::mip_map_range() const diff --git a/source/blender/gpu/vulkan/vk_texture.hh b/source/blender/gpu/vulkan/vk_texture.hh index 5a5ff3327a4..ae675255399 100644 --- a/source/blender/gpu/vulkan/vk_texture.hh +++ b/source/blender/gpu/vulkan/vk_texture.hh @@ -9,7 +9,9 @@ #pragma once #include "gpu_texture_private.hh" + #include "vk_context.hh" +#include "vk_image_view.hh" namespace blender::gpu { @@ -17,9 +19,11 @@ class VKSampler; class VKTexture : public Texture { VkImage vk_image_ = VK_NULL_HANDLE; - VkImageView vk_image_view_ = VK_NULL_HANDLE; VmaAllocation allocation_ = VK_NULL_HANDLE; + /* Image view when used in a shader. */ + std::optional image_view_; + /* Last image layout of the texture. Frame-buffer and barriers can alter/require the actual * layout to be changed. During this it requires to set the current layout in order to know which * conversion should happen. #current_layout_ keep track of the layout so the correct conversion @@ -127,17 +131,16 @@ class VKTexture : public Texture { /** \name Mipmapping * \{ */ public: - VkImageView vk_image_view_handle() + VKImageView &image_view_get() { vk_image_view_ensure(); - return vk_image_view_; + return *image_view_; } private: IndexRange mip_map_range() const; void vk_image_view_ensure(); - void vk_image_view_free(); - void vk_image_view_create(); + void image_view_update(); /** \} */ }; -- 2.30.2 From a34dd7e56b143f9fe399a6274a81bdcaeb6a792c Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 8 Jun 2023 15:38:29 +0200 Subject: [PATCH 63/63] Use meaningfull code block headers. --- source/blender/gpu/vulkan/vk_pipeline_state.cc | 1 - source/blender/gpu/vulkan/vk_texture.cc | 4 ++-- source/blender/gpu/vulkan/vk_texture.hh | 6 +++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_pipeline_state.cc b/source/blender/gpu/vulkan/vk_pipeline_state.cc index 78ac0425f5b..8c142d2923d 100644 --- a/source/blender/gpu/vulkan/vk_pipeline_state.cc +++ b/source/blender/gpu/vulkan/vk_pipeline_state.cc @@ -16,7 +16,6 @@ VKPipelineStateManager::VKPipelineStateManager() rasterization_state = {}; rasterization_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; rasterization_state.lineWidth = 1.0f; - rasterization_state.depthClampEnable = VK_FALSE; pipeline_color_blend_state = {}; pipeline_color_blend_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; diff --git a/source/blender/gpu/vulkan/vk_texture.cc b/source/blender/gpu/vulkan/vk_texture.cc index 6f27a9e975c..a282eb41735 100644 --- a/source/blender/gpu/vulkan/vk_texture.cc +++ b/source/blender/gpu/vulkan/vk_texture.cc @@ -518,10 +518,10 @@ void VKTexture::layout_ensure(VKContext &context, /** \} */ /* -------------------------------------------------------------------- */ -/** \name Mipmapping +/** \name Image Views * \{ */ -void VKTexture::vk_image_view_ensure() +void VKTexture::image_view_ensure() { if (flags_ & IMAGE_VIEW_DIRTY) { image_view_update(); diff --git a/source/blender/gpu/vulkan/vk_texture.hh b/source/blender/gpu/vulkan/vk_texture.hh index ae675255399..8e5fb837122 100644 --- a/source/blender/gpu/vulkan/vk_texture.hh +++ b/source/blender/gpu/vulkan/vk_texture.hh @@ -128,18 +128,18 @@ class VKTexture : public Texture { /** \} */ /* -------------------------------------------------------------------- */ - /** \name Mipmapping + /** \name Image Views * \{ */ public: VKImageView &image_view_get() { - vk_image_view_ensure(); + image_view_ensure(); return *image_view_; } private: IndexRange mip_map_range() const; - void vk_image_view_ensure(); + void image_view_ensure(); void image_view_update(); /** \} */ -- 2.30.2