diff --git a/implementations/Crafter.Graphics-VulkanDevice.cpp b/implementations/Crafter.Graphics-VulkanDevice.cpp index 3b60cc4..86e4aa2 100644 --- a/implementations/Crafter.Graphics-VulkanDevice.cpp +++ b/implementations/Crafter.Graphics-VulkanDevice.cpp @@ -45,7 +45,8 @@ const char* const deviceExtensionNames[] = { "VK_KHR_dynamic_rendering", "VK_KHR_acceleration_structure", "VK_KHR_deferred_host_operations", - "VK_KHR_ray_tracing_pipeline" + "VK_KHR_ray_tracing_pipeline", + "VK_KHR_ray_tracing_position_fetch" }; const char* const layerNames[] = { "VK_LAYER_KHRONOS_validation" @@ -220,8 +221,14 @@ void VulkanDevice::CreateDevice() { queueCreateInfo.queueCount = 1; queueCreateInfo.pQueuePriorities = &priority; + VkPhysicalDeviceRayTracingPositionFetchFeaturesKHR vkPhysicalDeviceRayTracingPositionFetchFeatures { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_POSITION_FETCH_FEATURES_KHR, + .rayTracingPositionFetch = VK_TRUE, + }; + VkPhysicalDeviceRayTracingPipelineFeaturesKHR physicalDeviceRayTracingPipelineFeatures{ .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR, + .pNext = &vkPhysicalDeviceRayTracingPositionFetchFeatures, .rayTracingPipeline = VK_TRUE }; diff --git a/implementations/Crafter.Graphics-Window_vulkan.cpp b/implementations/Crafter.Graphics-Window_vulkan.cpp index 327a81e..e8dac5a 100644 --- a/implementations/Crafter.Graphics-Window_vulkan.cpp +++ b/implementations/Crafter.Graphics-Window_vulkan.cpp @@ -376,7 +376,7 @@ void WindowVulkan::Render() { .stageFlags = VK_SHADER_STAGE_ALL, .layout = rtPipelineLayout, .firstSet = 0, - .descriptorSetCount = 1, + .descriptorSetCount = static_cast(descriptorsRt.size()), .pDescriptorSets = descriptorsRt.data() }; @@ -472,10 +472,12 @@ void WindowVulkan::wl_surface_frame_done(void* data, struct wl_callback *cb, uin #endif if(window->updating) { + window->mouseDelta = {std::int64_t(window->currentMousePos.x)-window->lastMousePos.x, std::int64_t(window->currentMousePos.y)-window->lastMousePos.y}; cb = wl_surface_frame(window->surface); wl_callback_add_listener(cb, &WindowVulkan::wl_callback_listener, window); window->currentFrameTime = {start, start-window->lastFrameBegin}; window->onUpdate.Invoke({start, start-window->lastFrameBegin}); + window->lastMousePos = window->currentMousePos; #ifdef CRAFTER_TIMING window->totalUpdate = std::chrono::nanoseconds(0); window->updateTimings.clear(); @@ -565,9 +567,7 @@ void WindowVulkan::pointer_handle_button(void* data, wl_pointer* pointer, std::u void WindowVulkan::PointerListenerHandleMotion(void* data, wl_pointer* wl_pointer, uint time, wl_fixed_t surface_x, wl_fixed_t surface_y) { WindowVulkan* window = reinterpret_cast(data); MousePoint pos = {FractionalToMappedBoundless((wl_fixed_to_double(surface_x) * window->scale) / window->width), FractionalToMappedBoundless((wl_fixed_to_double(surface_y) * window->scale) / window->height)}; - window->lastMousePos = window->currentMousePos; window->currentMousePos = pos; - window->mouseDelta = {window->currentMousePos.x-window->lastMousePos.x, window->currentMousePos.y-window->lastMousePos.y}; window->onMouseMove.Invoke({window->lastMousePos, window->currentMousePos, window->mouseDelta}); for(MouseElement* element : window->mouseElements) { if(element) { diff --git a/interfaces/Crafter.Graphics-PipelineRTVulkan.cppm b/interfaces/Crafter.Graphics-PipelineRTVulkan.cppm index cdc8a70..4901901 100644 --- a/interfaces/Crafter.Graphics-PipelineRTVulkan.cppm +++ b/interfaces/Crafter.Graphics-PipelineRTVulkan.cppm @@ -29,7 +29,7 @@ import :VulkanBuffer; import :Types; export namespace Crafter { - template + template class PipelineRTVulkan { public: inline static VkPipeline pipeline; @@ -50,7 +50,7 @@ export namespace Crafter { VulkanDevice::CheckVkResult(vkCreatePipelineLayout(VulkanDevice::device, &pipelineLayoutInfo, nullptr, &pipelineLayout)); - std::array shaderStages; + std::array shaderStages; shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; shaderStages[0].stage = Raygen::_stage; @@ -76,8 +76,23 @@ export namespace Crafter { shaderStages[2].pSpecializationInfo = nullptr; shaderStages[2].pNext = nullptr; + shaderStages[3].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shaderStages[3].stage = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR; + shaderStages[3].module = ShadowClosestHit::shader; + shaderStages[3].pName = ShadowClosestHit::_entrypoint.value; + shaderStages[3].flags = 0; + shaderStages[3].pSpecializationInfo = nullptr; + shaderStages[3].pNext = nullptr; - std::array groups {{ + shaderStages[4].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + shaderStages[4].stage = ShadowMiss::_stage; + shaderStages[4].module = ShadowMiss::shader; + shaderStages[4].pName = ShadowMiss::_entrypoint.value; + shaderStages[4].flags = 0; + shaderStages[4].pSpecializationInfo = nullptr; + shaderStages[4].pNext = nullptr; + + std::array groups {{ { .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR, .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR, @@ -101,6 +116,22 @@ export namespace Crafter { .closestHitShader = 2, .anyHitShader = VK_SHADER_UNUSED_KHR, .intersectionShader = VK_SHADER_UNUSED_KHR + }, + { + .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR, + .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR, + .generalShader = VK_SHADER_UNUSED_KHR, + .closestHitShader = 3, + .anyHitShader = VK_SHADER_UNUSED_KHR, + .intersectionShader = VK_SHADER_UNUSED_KHR + }, + { + .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR, + .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR, + .generalShader = 4, + .closestHitShader = VK_SHADER_UNUSED_KHR, + .anyHitShader = VK_SHADER_UNUSED_KHR, + .intersectionShader = VK_SHADER_UNUSED_KHR } }}; @@ -110,7 +141,7 @@ export namespace Crafter { .pStages = shaderStages.data(), .groupCount = static_cast(groups.size()), .pGroups = groups.data(), - .maxPipelineRayRecursionDepth = 1, + .maxPipelineRayRecursionDepth = 2, .layout = pipelineLayout }; @@ -125,35 +156,33 @@ export namespace Crafter { shaderHandles.resize(dataSize); VulkanDevice::CheckVkResult(VulkanDevice::vkGetRayTracingShaderGroupHandlesKHR(VulkanDevice::device, pipeline, 0, groupCount, dataSize, shaderHandles.data())); - std::uint32_t raygenSize = AlignUp(handleSize, handleAlignment); - std::uint32_t missSize = AlignUp(handleSize, handleAlignment); - std::uint32_t hitSize = AlignUp(handleSize, handleAlignment); - std::uint32_t callableSize = 0; + std::uint32_t sbtStride = AlignUp(handleSize, handleAlignment); + std::uint32_t raygenOffset = 0; + std::uint32_t missOffset = AlignUp(raygenOffset + sbtStride, baseAlignment); + std::uint32_t hitOffset = AlignUp(missOffset + sbtStride * 2, baseAlignment); - std::uint32_t raygenOffset = 0; - std::uint32_t missOffset = AlignUp(raygenSize, baseAlignment); - std::uint32_t hitOffset = AlignUp(missOffset + missSize, baseAlignment); - std::uint32_t callableOffset = AlignUp(hitOffset + hitSize, baseAlignment); - - std::size_t bufferSize = callableOffset + callableSize; + std::uint32_t hitGroupCount = 2; + std::size_t bufferSize = hitOffset + sbtStride * hitGroupCount; sbtBuffer.Create(VK_BUFFER_USAGE_2_SHADER_BINDING_TABLE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, bufferSize); // Ray generation shader (group 0) std::memcpy(sbtBuffer.value + raygenOffset, shaderHandles.data() + 0 * handleSize, handleSize); raygenRegion.deviceAddress = sbtBuffer.address + raygenOffset; - raygenRegion.stride = raygenSize; - raygenRegion.size = raygenSize; + raygenRegion.stride = sbtStride; + raygenRegion.size = sbtStride; std::memcpy(sbtBuffer.value + missOffset, shaderHandles.data() + 1 * handleSize, handleSize); + std::memcpy(sbtBuffer.value + missOffset + 1 * sbtStride, shaderHandles.data() + 4 * handleSize, handleSize); missRegion.deviceAddress = sbtBuffer.address + missOffset; - missRegion.stride = missSize; - missRegion.size = missSize; + missRegion.stride = sbtStride; + missRegion.size = sbtStride * 2; - std::memcpy(sbtBuffer.value + hitOffset, shaderHandles.data() + 2 * handleSize, handleSize); + std::memcpy(sbtBuffer.value + hitOffset + 0 * sbtStride, shaderHandles.data() + 2 * handleSize, handleSize); + std::memcpy(sbtBuffer.value + hitOffset + 1 * sbtStride, shaderHandles.data() + 3 * handleSize, handleSize); hitRegion.deviceAddress = sbtBuffer.address + hitOffset; - hitRegion.stride = hitSize; - hitRegion.size = hitSize; + hitRegion.stride = sbtStride; + hitRegion.size = sbtStride * hitGroupCount; callableRegion.deviceAddress = 0; callableRegion.stride = 0;