diff --git a/examples/VulkanTriangle/executable-linux.zip b/examples/VulkanTriangle/executable-linux.zip deleted file mode 100644 index 7e55202..0000000 Binary files a/examples/VulkanTriangle/executable-linux.zip and /dev/null differ diff --git a/examples/VulkanTriangle/executable-windows.zip b/examples/VulkanTriangle/executable-windows.zip deleted file mode 100644 index d55aadf..0000000 Binary files a/examples/VulkanTriangle/executable-windows.zip and /dev/null differ diff --git a/examples/VulkanTriangle/project.json b/examples/VulkanTriangle/project.json index 292a1cd..dd9d5a1 100644 --- a/examples/VulkanTriangle/project.json +++ b/examples/VulkanTriangle/project.json @@ -7,13 +7,9 @@ "dependencies": [ { "path":"../../project.json", - "configuration":"lib-win32-vulkan-debug" + "configuration":"lib-wayland-vulkan-debug" } ], - "march": "x86-64-v3", - "mtune": "generic", - "target": "x86_64-w64-mingw32", - "debug": false, "shaders": [ { "path":"raygen.glsl", diff --git a/examples/VulkanUI/main.cpp b/examples/VulkanUI/main.cpp new file mode 100644 index 0000000..1695cab --- /dev/null +++ b/examples/VulkanUI/main.cpp @@ -0,0 +1,230 @@ +#include "vulkan/vulkan.h" +#include + +import Crafter.Graphics; +using namespace Crafter; +import std; +import Crafter.Event; +import Crafter.Math; + + +int main() { + Device::Initialize(); + Window window(1280, 720, "HelloVulkan"); + VkCommandBuffer cmd = window.StartInit(); + DescriptorHeapVulkan descriptorHeap; + descriptorHeap.Initialize(1,1,0); + + VkSpecializationMapEntry entry = { + .constantID = 0, + .offset = 0, + .size = sizeof(uint16_t) + }; + + VkSpecializationInfo specilizationInfo = { + .mapEntryCount = 1, + .pMapEntries = &entry, + .dataSize = sizeof(uint16_t), + .pData = &descriptorHeap.bufferStartElement + }; + + std::array shaders{{ + {"raygen.spv", "main", VK_SHADER_STAGE_RAYGEN_BIT_KHR, &specilizationInfo} + }}; + + ShaderBindingTableVulkan shaderTable; + shaderTable.Init(shaders); + + std::array raygenGroups {{ + { + .sType = VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR, + .type = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR, + .generalShader = 0, + .closestHitShader = VK_SHADER_UNUSED_KHR, + .anyHitShader = VK_SHADER_UNUSED_KHR, + .intersectionShader = VK_SHADER_UNUSED_KHR, + }, + }}; + std::array missGroups; + std::array hitGroups; + + + PipelineRTVulkan pipeline; + pipeline.Init(cmd, raygenGroups, missGroups, hitGroups, shaderTable); + + window.FinishInit(); + + RendertargetBase<3> rendertargetBase(1280, 720); + RenderingElement2DVulkan element( + { + 0.5, //anchorX: relative position where this elements x anchor (top-left) is placed to its parent x anchor + 0.5, //anchorY: relative position where this elements y anchor (top-left) is placed to its parent y anchor + 0.5, //relativeSizeX: the relative x size this element should be scaled to compared to its parent + 0.5, //relativeSizeY: the relative y size this element should be scaled to compared to its parent + 0.5, //anchorOffsetX: the amount this element's anchor should be offset from the top left corner (0.5 to in the middle) + 0.5, //anchorOffsetY: the amount this element's anchor should be offset from the top left corner (0.5 to place it in the middle) + 0 //z: this elements Z position + }, + 2, + 1 + ); + for(std::uint8_t i = 0; i < Window::numFrames; i++) { + element.buffers[i]->value[0] = {1, 0, 0, 1}; + element.buffers[i]->value[1] = {0, 1, 0, 1}; + element.buffers[i]->FlushDevice(); + } + + InitializeRenderingElement2DVulkanBuffer(); + element.UpdatePosition(rendertargetBase, rendertargetBase.transform); + + renderingElement2DVulkanTransformBuffer[0].FlushDevice(); + renderingElement2DVulkanTransformBuffer[1].FlushDevice(); + renderingElement2DVulkanTransformBuffer[2].FlushDevice(); + + VkImageDescriptorInfoEXT imageInfo0 = { + .sType = VK_STRUCTURE_TYPE_IMAGE_DESCRIPTOR_INFO_EXT, + .pView = &window.imageViews[0], + .layout = VK_IMAGE_LAYOUT_GENERAL + }; + + VkImageDescriptorInfoEXT imageInfo1 = { + .sType = VK_STRUCTURE_TYPE_IMAGE_DESCRIPTOR_INFO_EXT, + .pView = &window.imageViews[1], + .layout = VK_IMAGE_LAYOUT_GENERAL + }; + + VkImageDescriptorInfoEXT imageInfo2 = { + .sType = VK_STRUCTURE_TYPE_IMAGE_DESCRIPTOR_INFO_EXT, + .pView = &window.imageViews[2], + .layout = VK_IMAGE_LAYOUT_GENERAL + }; + + VkDeviceAddressRangeKHR transformRange0 = { + .address = renderingElement2DVulkanTransformBuffer[0].address, + .size = renderingElement2DVulkanTransformBuffer[0].descriptor.range + }; + + VkDeviceAddressRangeKHR transformRange1 = { + .address = renderingElement2DVulkanTransformBuffer[1].address, + .size = renderingElement2DVulkanTransformBuffer[1].descriptor.range + }; + + VkDeviceAddressRangeKHR transformRange2 = { + .address = renderingElement2DVulkanTransformBuffer[2].address, + .size = renderingElement2DVulkanTransformBuffer[2].descriptor.range + }; + + VkDeviceAddressRangeKHR elRange0 = { + .address = element.buffers[0]->address, + .size = element.buffers[0]->descriptor.range + }; + + VkDeviceAddressRangeKHR elRange1 = { + .address = element.buffers[1]->address, + .size = element.buffers[1]->descriptor.range + }; + + VkDeviceAddressRangeKHR elRange2 = { + .address = element.buffers[2]->address, + .size = element.buffers[2]->descriptor.range + }; + + VkResourceDescriptorInfoEXT resources[9] = { + { + .sType = VK_STRUCTURE_TYPE_RESOURCE_DESCRIPTOR_INFO_EXT, + .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + .data = { .pImage = &imageInfo0 } + }, + { + .sType = VK_STRUCTURE_TYPE_RESOURCE_DESCRIPTOR_INFO_EXT, + .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + .data = { .pImage = &imageInfo1 } + }, + { + .sType = VK_STRUCTURE_TYPE_RESOURCE_DESCRIPTOR_INFO_EXT, + .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + .data = { .pImage = &imageInfo2 } + }, + { + .sType = VK_STRUCTURE_TYPE_RESOURCE_DESCRIPTOR_INFO_EXT, + .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + .data = { .pAddressRange = &transformRange0} + }, + { + .sType = VK_STRUCTURE_TYPE_RESOURCE_DESCRIPTOR_INFO_EXT, + .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + .data = { .pAddressRange = &transformRange1} + }, + { + .sType = VK_STRUCTURE_TYPE_RESOURCE_DESCRIPTOR_INFO_EXT, + .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + .data = { .pAddressRange = &transformRange2} + }, + { + .sType = VK_STRUCTURE_TYPE_RESOURCE_DESCRIPTOR_INFO_EXT, + .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + .data = { .pAddressRange = &elRange0} + }, + { + .sType = VK_STRUCTURE_TYPE_RESOURCE_DESCRIPTOR_INFO_EXT, + .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + .data = { .pAddressRange = &elRange1} + }, + { + .sType = VK_STRUCTURE_TYPE_RESOURCE_DESCRIPTOR_INFO_EXT, + .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + .data = { .pAddressRange = &elRange2} + }, + }; + + VkHostAddressRangeEXT destinations[9] = { + { + .address = descriptorHeap.resourceHeap[0].value, + .size = Device::descriptorHeapProperties.imageDescriptorSize + }, + { + .address = descriptorHeap.resourceHeap[1].value, + .size = Device::descriptorHeapProperties.imageDescriptorSize + }, + { + .address = descriptorHeap.resourceHeap[2].value, + .size = Device::descriptorHeapProperties.imageDescriptorSize + }, + { + .address = descriptorHeap.resourceHeap[0].value + descriptorHeap.bufferStartOffset, + .size = Device::descriptorHeapProperties.bufferDescriptorSize + }, + { + .address = descriptorHeap.resourceHeap[1].value + descriptorHeap.bufferStartOffset, + .size = Device::descriptorHeapProperties.bufferDescriptorSize + }, + { + .address = descriptorHeap.resourceHeap[2].value + descriptorHeap.bufferStartOffset, + .size = Device::descriptorHeapProperties.bufferDescriptorSize + }, + { + .address = descriptorHeap.resourceHeap[0].value + descriptorHeap.bufferStartOffset + Device::descriptorHeapProperties.bufferDescriptorSize * (renderingElement2DVulkans.size()), + .size = Device::descriptorHeapProperties.bufferDescriptorSize + }, + { + .address = descriptorHeap.resourceHeap[1].value + descriptorHeap.bufferStartOffset + Device::descriptorHeapProperties.bufferDescriptorSize * (renderingElement2DVulkans.size()), + .size = Device::descriptorHeapProperties.bufferDescriptorSize + }, + { + .address = descriptorHeap.resourceHeap[2].value + descriptorHeap.bufferStartOffset + Device::descriptorHeapProperties.bufferDescriptorSize * (renderingElement2DVulkans.size()), + .size = Device::descriptorHeapProperties.bufferDescriptorSize + }, + }; + + Device::vkWriteResourceDescriptorsEXT(Device::device, 9, resources, destinations); + + descriptorHeap.resourceHeap[0].FlushDevice(); + descriptorHeap.resourceHeap[1].FlushDevice(); + descriptorHeap.resourceHeap[2].FlushDevice(); + + window.pipeline = &pipeline; + window.descriptorHeap = &descriptorHeap; + + window.Render(); + window.StartSync(); +} diff --git a/examples/VulkanUI/project.json b/examples/VulkanUI/project.json new file mode 100644 index 0000000..31cecf9 --- /dev/null +++ b/examples/VulkanUI/project.json @@ -0,0 +1,23 @@ +{ + "name": "crafter-graphics", + "configurations": [ + { + "name": "executable", + "implementations": ["main"], + "dependencies": [ + { + "path":"../../project.json", + "configuration":"lib-wayland-vulkan-debug" + } + ], + "debug": true, + "shaders": [ + { + "path":"raygen.glsl", + "type": 6, + "entrypoint":"main" + } + ] + } + ] +} diff --git a/examples/VulkanUI/raygen.glsl b/examples/VulkanUI/raygen.glsl new file mode 100644 index 0000000..364122e --- /dev/null +++ b/examples/VulkanUI/raygen.glsl @@ -0,0 +1,48 @@ +#version 460 +#extension GL_EXT_ray_tracing : enable +#extension GL_EXT_shader_image_load_formatted : enable +#extension GL_EXT_shader_explicit_arithmetic_types_int16 : enable +#extension GL_EXT_descriptor_heap : enable +#extension GL_EXT_nonuniform_qualifier : enable +#extension GL_EXT_shader_explicit_arithmetic_types_float16 : enable + + +struct UIScaledData{ + int16_t x; + int16_t y; + int16_t sizeX; + int16_t sizeY; + uint16_t bufferX; + uint16_t bufferY; +}; + +layout(std430, descriptor_heap) buffer UIScaledDataBuffer { + uint16_t count; + uint16_t pad[5]; + UIScaledData data[]; +} UITransformBuffer[]; + +layout(std430, descriptor_heap) buffer UIPixelBufferr { + f16vec4 pixels[]; +} UIPixelBuffer[]; + +layout(constant_id = 0) const uint16_t bufferStart = 0us; +layout(descriptor_heap) uniform writeonly image2D image[]; + +void main() +{ + uvec2 pixel = gl_LaunchIDEXT.xy; + uvec2 resolution = gl_LaunchSizeEXT.xy; + + vec4 hitValue = vec4(0); + + for (uint16_t i = 1us; i < UITransformBuffer[bufferStart].count+1; i++) { + if(pixel.x > UITransformBuffer[bufferStart].data[i].x && pixel.x < UITransformBuffer[bufferStart].data[i].x + UITransformBuffer[bufferStart].data[i].sizeX && pixel.y > UITransformBuffer[bufferStart].data[i].y && pixel.y < UITransformBuffer[bufferStart].data[i].y + UITransformBuffer[bufferStart].data[i].sizeY) { + int16_t srcX = int16_t((pixel.x - UITransformBuffer[bufferStart].data[i].x) * UITransformBuffer[bufferStart].data[i].bufferX / UITransformBuffer[bufferStart].data[i].sizeX); + int16_t srcY = int16_t((pixel.y - UITransformBuffer[bufferStart].data[i].y) * UITransformBuffer[bufferStart].data[i].bufferY / UITransformBuffer[bufferStart].data[i].sizeY); + hitValue = vec4(UIPixelBuffer[bufferStart + UITransformBuffer[bufferStart].count].pixels[srcY * UITransformBuffer[bufferStart].data[i].bufferX + srcX]); + } + } + + imageStore(image[0], ivec2(pixel), hitValue); +} diff --git a/implementations/Crafter.Graphics-Device.cpp b/implementations/Crafter.Graphics-Device.cpp index 50a06a2..b027a26 100644 --- a/implementations/Crafter.Graphics-Device.cpp +++ b/implementations/Crafter.Graphics-Device.cpp @@ -70,7 +70,8 @@ const char* const deviceExtensionNames[] = { "VK_EXT_descriptor_heap", "VK_KHR_deferred_host_operations", "VK_KHR_maintenance5", - "VK_KHR_shader_untyped_pointers" + "VK_KHR_shader_untyped_pointers", + "VK_EXT_device_fault" }; const char* const layerNames[] = { "VK_LAYER_KHRONOS_validation" @@ -80,6 +81,58 @@ const char* const layerNames[] = { void Device::CheckVkResult(VkResult result) { if (result != VK_SUCCESS) { + if(result == VK_ERROR_DEVICE_LOST) { + VkDeviceFaultCountsEXT faultCounts = { + .sType = VK_STRUCTURE_TYPE_DEVICE_FAULT_COUNTS_EXT, + .pNext = NULL, + }; + Device::vkGetDeviceFaultInfoEXT(device, &faultCounts, NULL); + + std::vector addressInfos(faultCounts.addressInfoCount); + std::vector vendorInfos(faultCounts.vendorInfoCount); + std::vector vendorBinaryData(faultCounts.vendorBinarySize); + + VkDeviceFaultInfoEXT faultInfo = { + .sType = VK_STRUCTURE_TYPE_DEVICE_FAULT_INFO_EXT, + .pNext = NULL, + .pAddressInfos = addressInfos.data(), + .pVendorInfos = vendorInfos.data(), + .pVendorBinaryData = vendorBinaryData.data(), + }; + Device::vkGetDeviceFaultInfoEXT(device, &faultCounts, &faultInfo); + + std::println("{}", faultInfo.description); + + std::println("{} AddressInfos:", addressInfos.size()); + for(const VkDeviceFaultAddressInfoEXT& info : addressInfos) { + std::println("\t{} {}", static_cast(info.addressType), info.reportedAddress); + } + + std::println("{} vendorInfos:", vendorInfos.size()); + for(const VkDeviceFaultVendorInfoEXT& info : vendorInfos) { + std::println("\t{} {} {}", info.description, info.vendorFaultCode, info.vendorFaultData); + } + + if(!vendorBinaryData.empty()) { + std::string ext = ".bin"; + if(vendorBinaryData.size() >= sizeof(VkDeviceFaultVendorBinaryHeaderVersionOneEXT)) { + VkDeviceFaultVendorBinaryHeaderVersionOneEXT header; + std::memcpy(&header, vendorBinaryData.data(), sizeof(header)); + if(header.vendorID == 0x10DE) { // NVIDIA + ext = ".nv-gpudmp"; + } + } + const auto now = std::chrono::system_clock::now(); + const std::string dumpPath = std::format("gpu_crash_dump-{:%Y%m%d-%H%M%S}{}", now, ext); + std::ofstream file(dumpPath, std::ios::binary); + if(file.write(vendorBinaryData.data(), vendorBinaryData.size())) { + std::println("Vendor binary saved to: {}", std::filesystem::canonical(dumpPath).string()); + } else { + std::println(stderr, "Failed to write vendor binary to: {}", dumpPath); + } + } + } + throw std::runtime_error(string_VkResult(result)); } } @@ -603,8 +656,24 @@ void Device::Initialize() { queueCreateInfo.queueCount = 1; queueCreateInfo.pQueuePriorities = &priority; + VkPhysicalDeviceFaultFeaturesEXT faultFeatures2 = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT, + }; + VkPhysicalDeviceFeatures2 features22 = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, + .pNext = &faultFeatures2, + }; + vkGetPhysicalDeviceFeatures2(physDevice, &features22); + + VkPhysicalDeviceFaultFeaturesEXT faultFeatures = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT, + .deviceFault = VK_TRUE, + .deviceFaultVendorBinary = faultFeatures2.deviceFaultVendorBinary, + }; + VkPhysicalDeviceShaderUntypedPointersFeaturesKHR untypedPointersFeatures { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_UNTYPED_POINTERS_FEATURES_KHR, + .pNext = &faultFeatures, .shaderUntypedPointers = VK_TRUE, }; @@ -623,6 +692,7 @@ void Device::Initialize() { VkPhysicalDeviceVulkan12Features features12 { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, .pNext = &bit16, + .shaderFloat16 = VK_TRUE, .runtimeDescriptorArray = VK_TRUE, .bufferDeviceAddress = VK_TRUE }; @@ -703,6 +773,7 @@ void Device::Initialize() { vkCmdBindSamplerHeapEXT = reinterpret_cast(vkGetInstanceProcAddr(instance, "vkCmdBindSamplerHeapEXT")); vkWriteResourceDescriptorsEXT = reinterpret_cast(vkGetInstanceProcAddr(instance, "vkWriteResourceDescriptorsEXT")); vkGetPhysicalDeviceDescriptorSizeEXT = reinterpret_cast(vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceDescriptorSizeEXT")); + vkGetDeviceFaultInfoEXT = reinterpret_cast(vkGetInstanceProcAddr(instance, "vkGetDeviceFaultInfoEXT")); #endif } diff --git a/interfaces/Crafter.Graphics-Device.cppm b/interfaces/Crafter.Graphics-Device.cppm index 819a43e..214e970 100644 --- a/interfaces/Crafter.Graphics-Device.cppm +++ b/interfaces/Crafter.Graphics-Device.cppm @@ -118,6 +118,7 @@ export namespace Crafter { inline static PFN_vkCmdBindSamplerHeapEXT vkCmdBindSamplerHeapEXT; inline static PFN_vkWriteResourceDescriptorsEXT vkWriteResourceDescriptorsEXT; inline static PFN_vkGetPhysicalDeviceDescriptorSizeEXT vkGetPhysicalDeviceDescriptorSizeEXT; + inline static PFN_vkGetDeviceFaultInfoEXT vkGetDeviceFaultInfoEXT; inline static VkPhysicalDeviceMemoryProperties memoryProperties; diff --git a/interfaces/Crafter.Graphics-RenderingElement2DVulkan.cppm b/interfaces/Crafter.Graphics-RenderingElement2DVulkan.cppm index c88c982..e9aaac1 100644 --- a/interfaces/Crafter.Graphics-RenderingElement2DVulkan.cppm +++ b/interfaces/Crafter.Graphics-RenderingElement2DVulkan.cppm @@ -19,10 +19,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA module; #include "../lib/stb_truetype.h" +#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN +#include +#endif export module Crafter.Graphics:RenderingElement2DVulkan; +#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN import Crafter.Asset; import std; import :Transform2D; +import :VulkanBuffer; import :Types; import :Window; @@ -32,44 +37,85 @@ export namespace Crafter { std::uint16_t bufferX; // 8 - 2 bytes std::uint16_t bufferY; // 10 - 2 bytes //12 bytes total; - } + }; + struct RenderingElement2DVulkanBase : Transform2D { + std::uint16_t index; + std::uint16_t bufferX; + std::uint16_t bufferY; + RenderingElement2DVulkanBase(Anchor2D anchor, std::uint16_t bufferX, std::uint16_t bufferY) : bufferX(bufferX), bufferY(bufferY), Transform2D(anchor) { + + } + }; + + std::vector renderingElement2DVulkans; + VulkanBuffer renderingElement2DVulkanTransformBuffer[Window::numFrames]; template - struct RenderingElement2DVulkan { - std::uint16_t index; - std:array*, Window::NumFrames> buffers; - RenderingElement2DVulkan(Anchor2D anchor, std::uint16_t bufferWidth, std::uint16_t bufferHeight) requires(Owning) : index(renderingElement2DVulkans.size()-1) { + struct RenderingElement2DVulkan : RenderingElement2DVulkanBase { + std::array, Mapped, true>*, Window::numFrames> buffers; + RenderingElement2DVulkan(Anchor2D anchor, std::uint16_t bufferX, std::uint16_t bufferY) requires(Owning) : RenderingElement2DVulkanBase(anchor, bufferX, bufferY) { renderingElement2DVulkans.push_back(this); + for(std::uint8_t i = 0; i < Window::numFrames; i++) { + buffers[i] = new VulkanBuffer, Mapped, true>(); + buffers[i]->Create(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, bufferX * bufferY); + } } - RenderingElement2DVulkan(Anchor2D anchor, std::uint16_t bufferWidth, std::uint16_t bufferHeight, std:array*, Window::NumFrames> buffers) requires(!Owning) : buffers(buffers) { + RenderingElement2DVulkan(Anchor2D anchor, std::uint16_t bufferX, std::uint16_t bufferY, std::array*, Window::numFrames> buffers) requires(!Owning) : buffers(buffers), RenderingElement2DVulkanBase(anchor, bufferX, bufferY) { renderingElement2DVulkans.push_back(this); } ~RenderingElement2DVulkan() { if constexpr(Owning) { - for(VulkanBuffer<_Float16, Mapped, false>* buffer : buffers) { + for(VulkanBuffer, Mapped, true>* buffer : buffers) { delete buffer; } } + auto it = std::find(renderingElement2DVulkans.begin(), renderingElement2DVulkans.end(), this); + if (it != renderingElement2DVulkans.end()) { + renderingElement2DVulkans.erase(it); + } } RenderingElement2DVulkan(RenderingElement2DVulkan&) = delete; RenderingElement2DVulkan& operator=(RenderingElement2DVulkan&) = delete; - void UpdatePosition(RendertargetBase& window, Transform2D& parent) override { - ScaleData2D oldScale = this->scaled; + void UpdatePosition(RendertargetBase& window, Transform2D& parent) override { this->ScaleElement(parent); - if(oldScale.size.x != this->scaled.size.x || oldScale.size.y != this->scaled.size.y) { - this->buffer.resize(this->scaled.size.x * this->scaled.size.y); - } + RenderingElement2DVulkanTransformInfo* val = reinterpret_cast(reinterpret_cast(renderingElement2DVulkanTransformBuffer[window.frame].value) + sizeof(RenderingElement2DVulkanTransformInfo)); + val[index].scaled = this->scaled; for(Transform2D* child : this->children) { child->UpdatePosition(window, *this); } } }; - inline static std::vector renderingElement2DVulkans; - inline static std::vector renderingElement2DVulkanDescriptors[Window::NumFrames]; - inline static VulkanBuffer* renderingElement2DVulkanTransformBuffer[Window::NumFrames]; -} \ No newline at end of file + void InitializeRenderingElement2DVulkanBuffer() { + for(std::uint8_t frame = 0; frame < Window::numFrames; frame++) { + renderingElement2DVulkanTransformBuffer[frame].Create(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, renderingElement2DVulkans.size()+1); + RenderingElement2DVulkanTransformInfo* val = reinterpret_cast(reinterpret_cast(renderingElement2DVulkanTransformBuffer[frame].value) + sizeof(RenderingElement2DVulkanTransformInfo)); + std::uint16_t* sizePtr = reinterpret_cast(renderingElement2DVulkanTransformBuffer[frame].value); + *sizePtr = renderingElement2DVulkans.size(); + for(std::uint16_t i = 0; i < renderingElement2DVulkans.size(); i++) { + val[i].scaled = renderingElement2DVulkans[i]->scaled; + val[i].bufferX = renderingElement2DVulkans[i]->bufferX; + val[i].bufferY = renderingElement2DVulkans[i]->bufferY; + renderingElement2DVulkans[i]->index = i; + } + } + } + + void UpdateRenderingElement2DVulkanBuffer(std::uint8_t frame) { + renderingElement2DVulkanTransformBuffer[frame].Resize(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, renderingElement2DVulkans.size()+1); + RenderingElement2DVulkanTransformInfo* val = reinterpret_cast(reinterpret_cast(renderingElement2DVulkanTransformBuffer[frame].value) + sizeof(RenderingElement2DVulkanTransformInfo)); + std::uint16_t* sizePtr = reinterpret_cast(renderingElement2DVulkanTransformBuffer[frame].value); + *sizePtr = renderingElement2DVulkans.size(); + for(std::uint16_t i = 0; i < renderingElement2DVulkans.size(); i++) { + val[i].scaled = renderingElement2DVulkans[i]->scaled; + val[i].bufferX = renderingElement2DVulkans[i]->bufferX; + val[i].bufferY = renderingElement2DVulkans[i]->bufferY; + renderingElement2DVulkans[i]->index = i + 1; + } + } +} +#endif \ No newline at end of file diff --git a/interfaces/Crafter.Graphics-Rendertarget.cppm b/interfaces/Crafter.Graphics-Rendertarget.cppm index 53d3c8f..da850ef 100644 --- a/interfaces/Crafter.Graphics-Rendertarget.cppm +++ b/interfaces/Crafter.Graphics-Rendertarget.cppm @@ -33,6 +33,7 @@ export namespace Crafter { Transform2D transform; std::uint16_t sizeX; std::uint16_t sizeY; + std::uint8_t frame; RendertargetBase() = default; RendertargetBase(std::uint16_t sizeX, std::uint16_t sizeY) : sizeX(sizeX), sizeY(sizeY), transform({0, 0, 1, 1, 0, 0, 0}){ transform.scaled.size.x = sizeX; @@ -61,8 +62,8 @@ export namespace Crafter { } for(ClipRect dirty : dirtyRects) { - dirty.left = std::max(element->scaled.position.x, dirty.left); - dirty.top = std::max(element->scaled.position.y, dirty.top); + dirty.left = std::uint16_t(std::max(element->scaled.position.x, std::int16_t(dirty.left))); + dirty.top = std::uint16_t(std::max(element->scaled.position.y,std::int16_t(dirty.top))); dirty.right = std::min(std::uint16_t(element->scaled.position.x+element->scaled.size.x), dirty.right); dirty.bottom = std::min(std::uint16_t(element->scaled.position.y+element->scaled.size.y), dirty.bottom); @@ -147,16 +148,16 @@ export namespace Crafter { void AddOldRects(Transform2D* elementTransform, std::uint8_t frame, std::vector& clipRects) { RenderingElement2DBase* element = dynamic_cast*>(elementTransform); if(element) { - if(element->scaled.position.x != element->oldScale[frame].position.x || element->scaled.position.y != element->oldScale[frame].position.y || element->scaled.size.x != element->oldScale[frame].size.x || element->scaled.size.y != element->oldScale[frame].size.y || element->redraw[frame]) { - clipRects.emplace_back(std::max(element->scaled.position.x, std::uint16_t(0)), std::min(std::uint16_t(element->scaled.position.x + element->scaled.size.x), this->sizeX), std::max(element->scaled.position.y, std::uint16_t(0)), std::min(std::uint16_t(element->scaled.position.y + element->scaled.size.y), this->sizeY)); - clipRects.emplace_back(std::max(element->oldScale[frame].position.x, std::uint16_t(0)), std::min(std::uint16_t(element->oldScale[frame].position.x + element->oldScale[frame].size.x), this->sizeX), std::max(element->oldScale[frame].position.y, std::uint16_t(0)), std::min(std::uint16_t(element->oldScale[frame].position.y + element->oldScale[frame].size.y), this->sizeY)); - element->oldScale[frame] = element->scaled; - element->redraw[frame] = false; - } else if(element->redraw[frame]) { - clipRects.emplace_back(std::max(element->scaled.position.x, std::uint16_t(0)), std::min(std::uint16_t(element->scaled.position.x + element->scaled.size.x), this->sizeX), std::max(element->scaled.position.y, std::uint16_t(0)), std::min(std::uint16_t(element->scaled.position.y + element->scaled.size.y), this->sizeY)); - element->oldScale[frame] = element->scaled; - element->redraw[frame] = false; - } + // if(element->scaled.position.x != element->oldScale[frame].position.x || element->scaled.position.y != element->oldScale[frame].position.y || element->scaled.size.x != element->oldScale[frame].size.x || element->scaled.size.y != element->oldScale[frame].size.y || element->redraw[frame]) { + // clipRects.emplace_back(std::max(element->scaled.position.x, std::uint16_t(0)), std::min(std::uint16_t(element->scaled.position.x + element->scaled.size.x), this->sizeX), std::max(element->scaled.position.y, std::uint16_t(0)), std::min(std::uint16_t(element->scaled.position.y + element->scaled.size.y), this->sizeY)); + // clipRects.emplace_back(std::max(element->oldScale[frame].position.x, std::uint16_t(0)), std::min(std::uint16_t(element->oldScale[frame].position.x + element->oldScale[frame].size.x), this->sizeX), std::max(element->oldScale[frame].position.y, std::uint16_t(0)), std::min(std::uint16_t(element->oldScale[frame].position.y + element->oldScale[frame].size.y), this->sizeY)); + // element->oldScale[frame] = element->scaled; + // element->redraw[frame] = false; + // } else if(element->redraw[frame]) { + // clipRects.emplace_back(std::max(element->scaled.position.x, std::uint16_t(0)), std::min(std::uint16_t(element->scaled.position.x + element->scaled.size.x), this->sizeX), std::max(element->scaled.position.y, std::uint16_t(0)), std::min(std::uint16_t(element->scaled.position.y + element->scaled.size.y), this->sizeY)); + // element->oldScale[frame] = element->scaled; + // element->redraw[frame] = false; + // } } for(Transform2D* child : elementTransform->children) { AddOldRects(child, frame, clipRects); diff --git a/interfaces/Crafter.Graphics-Types.cppm b/interfaces/Crafter.Graphics-Types.cppm index 4f8afe3..8a55f2e 100644 --- a/interfaces/Crafter.Graphics-Types.cppm +++ b/interfaces/Crafter.Graphics-Types.cppm @@ -33,8 +33,8 @@ export namespace Crafter { }; struct ScaleData2D { - Vector position; - Vector size; + Vector position; + Vector size; }; struct ClipRect { diff --git a/interfaces/Crafter.Graphics.cppm b/interfaces/Crafter.Graphics.cppm index d06c440..025f548 100644 --- a/interfaces/Crafter.Graphics.cppm +++ b/interfaces/Crafter.Graphics.cppm @@ -45,6 +45,7 @@ export import :RenderingElement3D; export import :ImageVulkan; export import :SamplerVulkan; export import :DescriptorHeapVulkan; +export import :RenderingElement2DVulkan; #endif // export import :WindowWaylandVulkan; diff --git a/project.json b/project.json index 89385d7..c19bdf0 100644 --- a/project.json +++ b/project.json @@ -35,7 +35,8 @@ "interfaces/Crafter.Graphics-SamplerVulkan", "interfaces/Crafter.Graphics-DescriptorHeapVulkan", "interfaces/Crafter.Graphics-Rendertarget", - "interfaces/Crafter.Graphics-ForwardDeclarations" + "interfaces/Crafter.Graphics-ForwardDeclarations", + "interfaces/Crafter.Graphics-RenderingElement2DVulkan" ], "type": "library" },