/// <summary>Initializes a new instance of the <see cref="GraphicsHeap" /> class.</summary> /// <param name="graphicsDevice">The graphics device for which the heap was created.</param> /// <param name="size">The size, in bytes, of the heap.</param> /// <param name="cpuAccess">The CPU access capabilities of the heap.</param> /// <exception cref="ArgumentNullException"><paramref name="graphicsDevice" /> is <c>null</c>.</exception> protected GraphicsHeap(GraphicsDevice graphicsDevice, ulong size, GraphicsHeapCpuAccess cpuAccess) { ThrowIfNull(graphicsDevice, nameof(graphicsDevice)); _graphicsDevice = graphicsDevice; _size = size; _cpuAccess = cpuAccess; }
static uint GetVulkanBufferUsageKind(GraphicsHeapCpuAccess cpuAccess, GraphicsBufferKind kind) { var vulkanBufferUsageKind = cpuAccess switch { GraphicsHeapCpuAccess.Read => VK_BUFFER_USAGE_TRANSFER_DST_BIT, GraphicsHeapCpuAccess.Write => VK_BUFFER_USAGE_TRANSFER_SRC_BIT, _ => VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, }; if (cpuAccess != GraphicsHeapCpuAccess.Read) { vulkanBufferUsageKind |= kind switch { GraphicsBufferKind.Vertex => VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, GraphicsBufferKind.Index => VK_BUFFER_USAGE_INDEX_BUFFER_BIT, GraphicsBufferKind.Constant => VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, _ => default,
/// <summary>Creates a new graphics heap for the device.</summary> /// <param name="size">The size, in bytes, of the graphics heap.</param> /// <param name="cpuAccess">The CPU access capabilities of the graphics heap.</param> /// <returns>A new graphics heap created for the device.</returns> public abstract GraphicsHeap CreateGraphicsHeap(ulong size, GraphicsHeapCpuAccess cpuAccess = GraphicsHeapCpuAccess.None);
internal D3D12GraphicsHeap(D3D12GraphicsDevice graphicsDevice, ulong size, GraphicsHeapCpuAccess cpuAccess) : base(graphicsDevice, size, cpuAccess) { _d3d12Heap = new ValueLazy <Pointer <ID3D12Heap> >(CreateD3D12Heap); }
internal VulkanGraphicsHeap(VulkanGraphicsDevice graphicsDevice, ulong size, GraphicsHeapCpuAccess cpuAccess) : base(graphicsDevice, size, cpuAccess) { _vulkanDeviceMemory = new ValueLazy <VkDeviceMemory>(CreateVulkanDeviceMemory); _ = _state.Transition(to: Initialized); }
static uint GetMemoryTypeIndex(VkPhysicalDevice vulkanPhysicalDevice, GraphicsHeapCpuAccess cpuAccess) { var memoryTypeIndex = uint.MaxValue; var memoryTypeHasDesiredFlag = false; var memoryTypeHasUndesiredFlag = false; VkPhysicalDeviceMemoryProperties physicalDeviceMemoryProperties; vkGetPhysicalDeviceMemoryProperties(vulkanPhysicalDevice, &physicalDeviceMemoryProperties); var memoryTypesCount = physicalDeviceMemoryProperties.memoryTypeCount; var memoryTypes = physicalDeviceMemoryProperties.memoryTypes; var(requiredFlag, desiredFlag, undesiredFlag) = cpuAccess switch { GraphicsHeapCpuAccess.Read => (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_CACHED_BIT, default(VkMemoryPropertyFlagBits)), GraphicsHeapCpuAccess.Write => (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, default(VkMemoryPropertyFlagBits), VK_MEMORY_PROPERTY_HOST_COHERENT_BIT), _ => (default(VkMemoryPropertyFlagBits), VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT), }; for (uint index = 0; index < memoryTypesCount; index++) { var propertyFlags = (VkMemoryPropertyFlagBits)memoryTypes[unchecked ((int)index)].propertyFlags; var hasRequiredFlag = (propertyFlags & requiredFlag) == requiredFlag; var hasDesiredFlag = (propertyFlags & desiredFlag) == desiredFlag; var hasUndesiredFlag = (propertyFlags & undesiredFlag) == undesiredFlag; if (hasRequiredFlag) { if (hasDesiredFlag) { if (!hasUndesiredFlag) { // We have the required flag, the desired flag, and do not // have the undesired flag; so we've found the best match. memoryTypeIndex = index; break; } if (!memoryTypeHasDesiredFlag) { // We have the required flag and the desired flag, but also the // undesired flag. But, the last match did not have the desired // flag, so we'll treat this as a better match. memoryTypeIndex = index; memoryTypeHasDesiredFlag = true; memoryTypeHasUndesiredFlag = true; } } else if (!memoryTypeHasDesiredFlag && ((!hasUndesiredFlag && memoryTypeHasUndesiredFlag) || (memoryTypeIndex == uint.MaxValue))) { // We have the required flag and do not have the desired flag, but // the last match didn't have the desired flag either. So, if the last // match had the undesired flag but we don't, then we'll treat this // as a better match. We'll likewise treat this as a better match if // we haven't found a match yet. memoryTypeIndex = index; memoryTypeHasUndesiredFlag = hasUndesiredFlag; } } } if (memoryTypeIndex == uint.MaxValue) { ThrowInvalidOperationException(nameof(memoryTypeIndex), memoryTypeIndex); } return(memoryTypeIndex); }