Commit 767b41b1 by Alexis Hetu Committed by Alexis Hétu

Vulkan dispatchable objects

Vulkan has a few dispatchable objects: Instance, Device, Physical Device, Command Buffer and Queue. These objects, when loaded through an ICD, are constrained to have a bit of memory allocated at the beginning of these objects to contain loader data. In order to do this, a wrapper class, DispatchableObject, was created to handle pointing directly to the loader data when casting to the associated VK handle and similarly back to a pointer to the internal object. Note that Queue, being allocated within another object, and not directly through the API, simply have the loader data at the beginning of the class, without requiring a wrapper class. Also, since all these object are allocated through a custom placement new operator, they have to be deallocated through an associated destroy() function, so the DispatchableObject destructor is deleted, in order to prevent these objects from being released any other way. Bug b/116336664 Change-Id: Iac749f6adcba0eaf7557f0df876ac0474081d9cc Reviewed-on: https://swiftshader-review.googlesource.com/c/20948Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 71e256ca
// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "VkCommandBuffer.hpp"
namespace vk
{
CommandBuffer::CommandBuffer(VkCommandBufferLevel pLevel) : level(pLevel)
{
pipelines[VK_PIPELINE_BIND_POINT_GRAPHICS] = VK_NULL_HANDLE;
pipelines[VK_PIPELINE_BIND_POINT_COMPUTE] = VK_NULL_HANDLE;
}
} // namespace vk
\ No newline at end of file
// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef VK_COMMAND_BUFFER_HPP_
#define VK_COMMAND_BUFFER_HPP_
#include "VkConfig.h"
#include "VkObject.hpp"
namespace vk
{
class CommandBuffer
{
public:
static constexpr VkSystemAllocationScope GetAllocationScope() { return VK_SYSTEM_ALLOCATION_SCOPE_OBJECT; }
CommandBuffer(VkCommandBufferLevel pLevel);
private:
VkCommandBufferLevel level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
VkPipeline pipelines[VK_PIPELINE_BIND_POINT_RANGE_SIZE];
};
using DispatchableCommandBuffer = DispatchableObject<CommandBuffer, VkCommandBuffer>;
static inline CommandBuffer* Cast(VkCommandBuffer object)
{
return DispatchableCommandBuffer::Cast(object);
}
} // namespace vk
#endif // VK_COMMAND_BUFFER_HPP_
// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef VK_CONFIG_HPP_
#define VK_CONFIG_HPP_
namespace vk
{
// Note: Constant array initialization requires a string literal.
// constexpr char* or char[] does not work for that purpose.
#define SWIFTSHADER_DEVICE_NAME "SwiftShader Device" // Max length: VK_MAX_PHYSICAL_DEVICE_NAME_SIZE
#define SWIFTSHADER_UUID "SwiftShaderUUID" // Max length: VK_UUID_SIZE
enum
{
DRIVER_VERSION = 1,
VENDOR_ID = 0x1AE0, // Google
DEVICE_ID = 0xC0DE, // SwiftShader
};
enum
{
REQUIRED_MEMORY_ALIGNMENT = 8, // For 64 bit formats on ARM64
REQUIRED_MEMORY_TYPE_BITS = 1,
};
enum
{
MAX_IMAGE_LEVELS_1D = 14,
MAX_IMAGE_LEVELS_2D = 14,
MAX_IMAGE_LEVELS_3D = 11,
MAX_IMAGE_LEVELS_CUBE = 14,
MAX_IMAGE_ARRAY_LAYERS = 11,
};
enum {
MaxVertexInputBindings = 16,
};
}
#endif // VK_CONFIG_HPP_
// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "VkConfig.h"
#include "VkDebug.hpp"
#include "VkDevice.hpp"
#include <new> // Must #include this to use "placement new"
namespace vk
{
Device::Device(const Device::CreateInfo* info, void* mem)
: physicalDevice(info->pPhysicalDevice), queues(reinterpret_cast<Queue*>(mem))
{
const auto* pCreateInfo = info->pCreateInfo;
for(uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++)
{
const VkDeviceQueueCreateInfo& queueCreateInfo = pCreateInfo->pQueueCreateInfos[i];
queueCount += info->pCreateInfo->pQueueCreateInfos[i].queueCount;
}
uint32_t queueID = 0;
for(uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++)
{
const VkDeviceQueueCreateInfo& queueCreateInfo = pCreateInfo->pQueueCreateInfos[i];
for(uint32_t j = 0; j < queueCreateInfo.queueCount; j++, queueID++)
{
new (queues + queueID) Queue(queueCreateInfo.queueFamilyIndex, queueCreateInfo.pQueuePriorities[j]);
}
}
}
void Device::destroy(const VkAllocationCallbacks* pAllocator)
{
vk::deallocate(queues, pAllocator);
}
size_t Device::ComputeRequiredAllocationSize(const Device::CreateInfo* info)
{
uint32_t queueCount = 0;
for(uint32_t i = 0; i < info->pCreateInfo->queueCreateInfoCount; i++)
{
queueCount += info->pCreateInfo->pQueueCreateInfos[i].queueCount;
}
return sizeof(Queue) * queueCount;
}
VkQueue Device::getQueue(uint32_t queueFamilyIndex, uint32_t queueIndex) const
{
ASSERT(queueFamilyIndex == 0);
return queues[queueIndex];
}
} // namespace vk
// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef VK_DEVICE_HPP_
#define VK_DEVICE_HPP_
#include "VkObject.hpp"
#include "VkQueue.hpp"
namespace vk
{
class Device
{
public:
struct CreateInfo
{
const VkDeviceCreateInfo* pCreateInfo;
VkPhysicalDevice pPhysicalDevice;
};
static constexpr VkSystemAllocationScope GetAllocationScope() { return VK_SYSTEM_ALLOCATION_SCOPE_DEVICE; }
Device(const CreateInfo* info, void* mem);
void destroy(const VkAllocationCallbacks* pAllocator);
static size_t ComputeRequiredAllocationSize(const CreateInfo* info);
VkQueue getQueue(uint32_t queueFamilyIndex, uint32_t queueIndex) const;
private:
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
Queue* queues = nullptr;
uint32_t queueCount = 0;
};
using DispatchableDevice = DispatchableObject<Device, VkDevice>;
static inline Device* Cast(VkDevice object)
{
return DispatchableDevice::Cast(object);
}
} // namespace vk
#endif // VK_DEVICE_HPP_
// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "VkInstance.hpp"
namespace vk
{
Instance::Instance(const CreateInfo* pCreateInfo, void* mem)
{
if(pCreateInfo->pPhysicalDevice)
{
physicalDevice = pCreateInfo->pPhysicalDevice;
physicalDeviceCount = 1;
}
}
void Instance::destroy(const VkAllocationCallbacks* pAllocator)
{
vk::destroy(physicalDevice, pAllocator);
}
uint32_t Instance::getPhysicalDeviceCount() const
{
return physicalDeviceCount;
}
void Instance::getPhysicalDevices(uint32_t pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices) const
{
ASSERT(pPhysicalDeviceCount == 1);
*pPhysicalDevices = physicalDevice;
}
uint32_t Instance::getPhysicalDeviceGroupCount() const
{
return physicalDeviceGroupCount;
}
void Instance::getPhysicalDeviceGroups(uint32_t pPhysicalDeviceGroupCount,
VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) const
{
ASSERT(pPhysicalDeviceGroupCount == 1);
pPhysicalDeviceGroupProperties->physicalDeviceCount = physicalDeviceCount;
pPhysicalDeviceGroupProperties->physicalDevices[0] = physicalDevice;
pPhysicalDeviceGroupProperties->subsetAllocation = VK_FALSE;
}
} // namespace vk
// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef VK_INSTANCE_HPP_
#define VK_INSTANCE_HPP_
#include "VkPhysicalDevice.hpp"
namespace vk
{
class Instance
{
public:
struct CreateInfo
{
const VkInstanceCreateInfo* pCreateInfo;
VkPhysicalDevice pPhysicalDevice;
};
static constexpr VkSystemAllocationScope GetAllocationScope() { return VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE; }
Instance(const CreateInfo* pCreateInfo, void* mem);
void destroy(const VkAllocationCallbacks* pAllocator);
static size_t ComputeRequiredAllocationSize(const CreateInfo*) { return 0; }
uint32_t getPhysicalDeviceCount() const;
void getPhysicalDevices(uint32_t pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices) const;
uint32_t getPhysicalDeviceGroupCount() const;
void getPhysicalDeviceGroups(uint32_t pPhysicalDeviceGroupCount,
VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) const;
private:
uint32_t physicalDeviceCount = 0;
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
uint32_t physicalDeviceGroupCount = 1;
};
using DispatchableInstance = DispatchableObject<Instance, VkInstance>;
static inline Instance* Cast(VkInstance object)
{
return DispatchableInstance::Cast(object);
}
} // namespace vk
#endif // VK_INSTANCE_HPP_
// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef VK_OBJECT_HPP_
#define VK_OBJECT_HPP_
#include "VkConfig.h"
#include "VkMemory.h"
namespace vk
{
void* allocate(size_t count, size_t alignment, const VkAllocationCallbacks* pAllocator, VkSystemAllocationScope allocationScope)
{
return pAllocator ?
pAllocator->pfnAllocation(pAllocator->pUserData, count, alignment, allocationScope) :
sw::allocate(count, alignment);
}
void deallocate(void* ptr, const VkAllocationCallbacks* pAllocator)
{
pAllocator ? pAllocator->pfnFree(pAllocator->pUserData, ptr) : sw::deallocate(ptr);
}
} // namespace vk
#endif // VK_OBJECT_HPP_
// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef VK_MEMORY_HPP_
#define VK_MEMORY_HPP_
#include "System/Memory.hpp"
#include <vulkan/vulkan.h>
namespace vk
{
void* allocate(size_t count, size_t alignment, const VkAllocationCallbacks* pAllocator,
VkSystemAllocationScope allocationScope = VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
void deallocate(void* ptr, const VkAllocationCallbacks* pAllocator);
template <typename T>
T* allocate(size_t count, const VkAllocationCallbacks* pAllocator)
{
return reinterpret_cast<T*>(allocate(count, alignof(T), pAllocator, T::GetAllocationScope()));
}
// Because Vulkan uses optional allocation callbacks, we use them in a custom
// placement new operator in the VkObjectBase class for simplicity.
// Unfortunately, since we use a placement new to allocate VkObjectBase derived
// classes objects, the corresponding deletion operator is a placement delete,
// which does nothing. In order to properly dispose of these objects' memory,
// we use this function, which calls the proper T:destroy() function
// prior to releasing the object (by default, VkObjectBase::destroy does nothing).
template<typename VkT>
inline void destroy(VkT vkObject, const VkAllocationCallbacks* pAllocator)
{
auto object = Cast(vkObject);
if(object)
{
object->destroy(pAllocator);
// object may not point to the same pointer as vkObject, for dispatchable objects,
// for example, so make sure to deallocate based on the vkObject pointer, which
// should always point to the beginning of the allocated memory
vk::deallocate(vkObject, pAllocator);
}
}
} // namespace vk
#endif // VK_MEMORY_HPP_
\ No newline at end of file
// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef VK_OBJECT_HPP_
#define VK_OBJECT_HPP_
#include "VkDebug.hpp"
#include "VkMemory.h"
#include <vulkan/vulkan.h>
#include <vulkan/vk_icd.h>
namespace vk
{
// For use in the placement new to make it verbose that we're allocating an object using device memory
static constexpr VkAllocationCallbacks* DEVICE_MEMORY = nullptr;
template<typename T, typename VkT, typename CreateInfo>
static VkResult Create(const VkAllocationCallbacks* pAllocator, const CreateInfo* pCreateInfo, VkT* outObject)
{
*outObject = VK_NULL_HANDLE;
size_t size = T::ComputeRequiredAllocationSize(pCreateInfo);
void* memory = nullptr;
if(size)
{
memory = vk::allocate(size, REQUIRED_MEMORY_ALIGNMENT, pAllocator, T::GetAllocationScope());
if(!memory)
{
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
}
auto object = new (pAllocator) T(pCreateInfo, memory);
if(!object)
{
vk::deallocate(memory, pAllocator);
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
*outObject = *object;
return VK_SUCCESS;
}
template<typename T, typename VkT>
class ObjectBase
{
public:
using VkType = VkT;
void destroy(const VkAllocationCallbacks* pAllocator) {} // Method defined by objects to delete their content, if necessary
void* operator new(size_t count, const VkAllocationCallbacks* pAllocator)
{
return vk::allocate(count, alignof(T), pAllocator, T::GetAllocationScope());
}
void operator delete(void* ptr, const VkAllocationCallbacks* pAllocator)
{
// Should never happen
ASSERT(false);
}
template<typename CreateInfo>
static VkResult Create(const VkAllocationCallbacks* pAllocator, const CreateInfo* pCreateInfo, VkT* outObject)
{
return vk::Create<T, VkT, CreateInfo>(pAllocator, pCreateInfo, outObject);
}
static constexpr VkSystemAllocationScope GetAllocationScope() { return VK_SYSTEM_ALLOCATION_SCOPE_OBJECT; }
protected:
// All derived classes should have deleted destructors
~ObjectBase() {}
};
template<typename T, typename VkT>
class Object : public ObjectBase<T, VkT>
{
public:
operator VkT()
{
return reinterpret_cast<VkT>(this);
}
};
template<typename T, typename VkT>
class DispatchableObject
{
VK_LOADER_DATA loaderData = { ICD_LOADER_MAGIC };
T object;
public:
static constexpr VkSystemAllocationScope GetAllocationScope() { return T::GetAllocationScope(); }
template<typename ...Args>
DispatchableObject(Args... args) : object(args...)
{
}
~DispatchableObject() = delete;
void destroy(const VkAllocationCallbacks* pAllocator)
{
object.destroy(pAllocator);
}
void* operator new(size_t count, const VkAllocationCallbacks* pAllocator)
{
return vk::allocate(count, alignof(T), pAllocator, T::GetAllocationScope());
}
void operator delete(void* ptr, const VkAllocationCallbacks* pAllocator)
{
// Should never happen
ASSERT(false);
}
template<typename CreateInfo>
static VkResult Create(const VkAllocationCallbacks* pAllocator, const CreateInfo* pCreateInfo, VkT* outObject)
{
return vk::Create<DispatchableObject<T, VkT>, VkT, CreateInfo>(pAllocator, pCreateInfo, outObject);
}
template<typename CreateInfo>
static size_t ComputeRequiredAllocationSize(const CreateInfo* pCreateInfo)
{
return T::ComputeRequiredAllocationSize(pCreateInfo);
}
static inline T* Cast(VkT vkObject)
{
return &(reinterpret_cast<DispatchableObject<T, VkT>*>(vkObject)->object);
}
operator VkT()
{
return reinterpret_cast<VkT>(this);
}
};
} // namespace vk
#endif // VK_OBJECT_HPP_
// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "VkPhysicalDevice.hpp"
#include "VkConfig.h"
#include <memory.h>
namespace vk
{
PhysicalDevice::PhysicalDevice(const void*, void* mem)
{
}
const VkPhysicalDeviceFeatures& PhysicalDevice::getFeatures() const
{
static const VkPhysicalDeviceFeatures features
{
true, // robustBufferAccess
false, // fullDrawIndexUint32
false, // imageCubeArray
false, // independentBlend
false, // geometryShader
false, // tessellationShader
false, // sampleRateShading
false, // dualSrcBlend
false, // logicOp
false, // multiDrawIndirect
false, // drawIndirectFirstInstance
false, // depthClamp
false, // depthBiasClamp
false, // fillModeNonSolid
false, // depthBounds
false, // wideLines
false, // largePoints
false, // alphaToOne
false, // multiViewport
false, // samplerAnisotropy
false, // textureCompressionETC2
false, // textureCompressionASTC_LDR
false, // textureCompressionBC
false, // occlusionQueryPrecise
false, // pipelineStatisticsQuery
false, // vertexPipelineStoresAndAtomics
false, // fragmentStoresAndAtomics
false, // shaderTessellationAndGeometryPointSize
false, // shaderImageGatherExtended
false, // shaderStorageImageExtendedFormats
false, // shaderStorageImageMultisample
false, // shaderStorageImageReadWithoutFormat
false, // shaderStorageImageWriteWithoutFormat
false, // shaderUniformBufferArrayDynamicIndexing
false, // shaderSampledImageArrayDynamicIndexing
false, // shaderStorageBufferArrayDynamicIndexing
false, // shaderStorageImageArrayDynamicIndexing
false, // shaderClipDistance
false, // shaderCullDistance
false, // shaderFloat64
false, // shaderInt64
false, // shaderInt16
false, // shaderResourceResidency
false, // shaderResourceMinLod
false, // sparseBinding
false, // sparseResidencyBuffer
false, // sparseResidencyImage2D
false, // sparseResidencyImage3D
false, // sparseResidency2Samples
false, // sparseResidency4Samples
false, // sparseResidency8Samples
false, // sparseResidency16Samples
false, // sparseResidencyAliased
false, // variableMultisampleRate
false, // inheritedQueries
};
return features;
}
VkSampleCountFlags PhysicalDevice::getSampleCounts() const
{
return VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT;
}
const VkPhysicalDeviceLimits& PhysicalDevice::getLimits() const
{
VkSampleCountFlags sampleCounts = getSampleCounts();
static const VkPhysicalDeviceLimits limits =
{
(1 << vk::MAX_IMAGE_LEVELS_1D), // maxImageDimension1D
(1 << vk::MAX_IMAGE_LEVELS_2D), // maxImageDimension2D
(1 << vk::MAX_IMAGE_LEVELS_3D), // maxImageDimension3D
(1 << vk::MAX_IMAGE_LEVELS_CUBE), // maxImageDimensionCube
(1 << vk::MAX_IMAGE_ARRAY_LAYERS), // maxImageArrayLayers
65536, // maxTexelBufferElements
16384, // maxUniformBufferRange
(1ul << 27), // maxStorageBufferRange
128, // maxPushConstantsSize
4096, // maxMemoryAllocationCount
4000, // maxSamplerAllocationCount
131072, // bufferImageGranularity
0, // sparseAddressSpaceSize (unsupported)
4, // maxBoundDescriptorSets
16, // maxPerStageDescriptorSamplers
12, // maxPerStageDescriptorUniformBuffers
4, // maxPerStageDescriptorStorageBuffers
16, // maxPerStageDescriptorSampledImages
4, // maxPerStageDescriptorStorageImages
4, // maxPerStageDescriptorInputAttachments
128, // maxPerStageResources
96, // maxDescriptorSetSamplers
72, // maxDescriptorSetUniformBuffers
8, // maxDescriptorSetUniformBuffersDynamic
24, // maxDescriptorSetStorageBuffers
4, // maxDescriptorSetStorageBuffersDynamic
96, // maxDescriptorSetSampledImages
24, // maxDescriptorSetStorageImages
4, // maxDescriptorSetInputAttachments
16, // maxVertexInputAttributes
vk::MaxVertexInputBindings, // maxVertexInputBindings
2047, // maxVertexInputAttributeOffset
2048, // maxVertexInputBindingStride
64, // maxVertexOutputComponents
0, // maxTessellationGenerationLevel (unsupported)
0, // maxTessellationPatchSize (unsupported)
0, // maxTessellationControlPerVertexInputComponents (unsupported)
0, // maxTessellationControlPerVertexOutputComponents (unsupported)
0, // maxTessellationControlPerPatchOutputComponents (unsupported)
0, // maxTessellationControlTotalOutputComponents (unsupported)
0, // maxTessellationEvaluationInputComponents (unsupported)
0, // maxTessellationEvaluationOutputComponents (unsupported)
0, // maxGeometryShaderInvocations (unsupported)
0, // maxGeometryInputComponents (unsupported)
0, // maxGeometryOutputComponents (unsupported)
0, // maxGeometryOutputVertices (unsupported)
0, // maxGeometryTotalOutputComponents (unsupported)
64, // maxFragmentInputComponents
4, // maxFragmentOutputAttachments
1, // maxFragmentDualSrcAttachments
4, // maxFragmentCombinedOutputResources
16384, // maxComputeSharedMemorySize
{ 65535, 65535, 65535 }, // maxComputeWorkGroupCount[3]
128, // maxComputeWorkGroupInvocations
{ 128, 128, 64, }, // maxComputeWorkGroupSize[3]
4, // subPixelPrecisionBits
4, // subTexelPrecisionBits
4, // mipmapPrecisionBits
UINT32_MAX, // maxDrawIndexedIndexValue
UINT32_MAX, // maxDrawIndirectCount
2, // maxSamplerLodBias
16, // maxSamplerAnisotropy
16, // maxViewports
{ 4096, 4096 }, // maxViewportDimensions[2]
{ -8192, 8191 }, // viewportBoundsRange[2]
0, // viewportSubPixelBits
64, // minMemoryMapAlignment
256, // minTexelBufferOffsetAlignment
256, // minUniformBufferOffsetAlignment
256, // minStorageBufferOffsetAlignment
-8, // minTexelOffset
7, // maxTexelOffset
-8, // minTexelGatherOffset
7, // maxTexelGatherOffset
-0.5, // minInterpolationOffset
0.5, // maxInterpolationOffset
4, // subPixelInterpolationOffsetBits
4096, // maxFramebufferWidth
4096, // maxFramebufferHeight
256, // maxFramebufferLayers
sampleCounts, // framebufferColorSampleCounts
sampleCounts, // framebufferDepthSampleCounts
sampleCounts, // framebufferStencilSampleCounts
sampleCounts, // framebufferNoAttachmentsSampleCounts
4, // maxColorAttachments
sampleCounts, // sampledImageColorSampleCounts
VK_SAMPLE_COUNT_1_BIT, // sampledImageIntegerSampleCounts
sampleCounts, // sampledImageDepthSampleCounts
sampleCounts, // sampledImageStencilSampleCounts
VK_SAMPLE_COUNT_1_BIT, // storageImageSampleCounts (unsupported)
1, // maxSampleMaskWords
false, // timestampComputeAndGraphics
60, // timestampPeriod
8, // maxClipDistances
8, // maxCullDistances
8, // maxCombinedClipAndCullDistances
2, // discreteQueuePriorities
{ 1.0, 64.0 }, // pointSizeRange[2]
{ 0.0, 8.0 }, // lineWidthRange[2]
1.0, // pointSizeGranularity
1.0, // lineWidthGranularity
false, // strictLines
true, // standardSampleLocations
64, // optimalBufferCopyOffsetAlignment
64, // optimalBufferCopyRowPitchAlignment
256, // nonCoherentAtomSize
};
return limits;
}
const VkPhysicalDeviceProperties& PhysicalDevice::getProperties() const
{
uint32_t apiVersion;
VkResult result = vkEnumerateInstanceVersion(&apiVersion);
ASSERT(result == VK_SUCCESS);
static const VkPhysicalDeviceProperties properties
{
apiVersion,
DRIVER_VERSION,
VENDOR_ID,
DEVICE_ID,
VK_PHYSICAL_DEVICE_TYPE_CPU, // deviceType
SWIFTSHADER_DEVICE_NAME, // deviceName
SWIFTSHADER_UUID, // pipelineCacheUUID
getLimits(), // limits
{ 0 } // sparseProperties
};
return properties;
}
bool PhysicalDevice::hasFeatures(const VkPhysicalDeviceFeatures& requestedFeatures) const
{
const VkPhysicalDeviceFeatures& availableFeatures = getFeatures();
return (!requestedFeatures.robustBufferAccess || availableFeatures.robustBufferAccess) &&
(!requestedFeatures.fullDrawIndexUint32 || availableFeatures.fullDrawIndexUint32) &&
(!requestedFeatures.imageCubeArray || availableFeatures.imageCubeArray) &&
(!requestedFeatures.independentBlend || availableFeatures.independentBlend) &&
(!requestedFeatures.geometryShader || availableFeatures.geometryShader) &&
(!requestedFeatures.tessellationShader || availableFeatures.tessellationShader) &&
(!requestedFeatures.sampleRateShading || availableFeatures.sampleRateShading) &&
(!requestedFeatures.dualSrcBlend || availableFeatures.dualSrcBlend) &&
(!requestedFeatures.logicOp || availableFeatures.logicOp) &&
(!requestedFeatures.multiDrawIndirect || availableFeatures.multiDrawIndirect) &&
(!requestedFeatures.drawIndirectFirstInstance || availableFeatures.drawIndirectFirstInstance) &&
(!requestedFeatures.depthClamp || availableFeatures.depthClamp) &&
(!requestedFeatures.depthBiasClamp || availableFeatures.depthBiasClamp) &&
(!requestedFeatures.fillModeNonSolid || availableFeatures.fillModeNonSolid) &&
(!requestedFeatures.depthBounds || availableFeatures.depthBounds) &&
(!requestedFeatures.wideLines || availableFeatures.wideLines) &&
(!requestedFeatures.largePoints || availableFeatures.largePoints) &&
(!requestedFeatures.alphaToOne || availableFeatures.alphaToOne) &&
(!requestedFeatures.multiViewport || availableFeatures.multiViewport) &&
(!requestedFeatures.samplerAnisotropy || availableFeatures.samplerAnisotropy) &&
(!requestedFeatures.textureCompressionETC2 || availableFeatures.textureCompressionETC2) &&
(!requestedFeatures.textureCompressionASTC_LDR || availableFeatures.textureCompressionASTC_LDR) &&
(!requestedFeatures.textureCompressionBC || availableFeatures.textureCompressionBC) &&
(!requestedFeatures.occlusionQueryPrecise || availableFeatures.occlusionQueryPrecise) &&
(!requestedFeatures.pipelineStatisticsQuery || availableFeatures.pipelineStatisticsQuery) &&
(!requestedFeatures.vertexPipelineStoresAndAtomics || availableFeatures.vertexPipelineStoresAndAtomics) &&
(!requestedFeatures.fragmentStoresAndAtomics || availableFeatures.fragmentStoresAndAtomics) &&
(!requestedFeatures.shaderTessellationAndGeometryPointSize || availableFeatures.shaderTessellationAndGeometryPointSize) &&
(!requestedFeatures.shaderImageGatherExtended || availableFeatures.shaderImageGatherExtended) &&
(!requestedFeatures.shaderStorageImageExtendedFormats || availableFeatures.shaderStorageImageExtendedFormats) &&
(!requestedFeatures.shaderStorageImageMultisample || availableFeatures.shaderStorageImageMultisample) &&
(!requestedFeatures.shaderStorageImageReadWithoutFormat || availableFeatures.shaderStorageImageReadWithoutFormat) &&
(!requestedFeatures.shaderStorageImageWriteWithoutFormat || availableFeatures.shaderStorageImageWriteWithoutFormat) &&
(!requestedFeatures.shaderUniformBufferArrayDynamicIndexing || availableFeatures.shaderUniformBufferArrayDynamicIndexing) &&
(!requestedFeatures.shaderSampledImageArrayDynamicIndexing || availableFeatures.shaderSampledImageArrayDynamicIndexing) &&
(!requestedFeatures.shaderStorageBufferArrayDynamicIndexing || availableFeatures.shaderStorageBufferArrayDynamicIndexing) &&
(!requestedFeatures.shaderStorageImageArrayDynamicIndexing || availableFeatures.shaderStorageImageArrayDynamicIndexing) &&
(!requestedFeatures.shaderClipDistance || availableFeatures.shaderClipDistance) &&
(!requestedFeatures.shaderCullDistance || availableFeatures.shaderCullDistance) &&
(!requestedFeatures.shaderFloat64 || availableFeatures.shaderFloat64) &&
(!requestedFeatures.shaderInt64 || availableFeatures.shaderInt64) &&
(!requestedFeatures.shaderInt16 || availableFeatures.shaderInt16) &&
(!requestedFeatures.shaderResourceResidency || availableFeatures.shaderResourceResidency) &&
(!requestedFeatures.shaderResourceMinLod || availableFeatures.shaderResourceMinLod) &&
(!requestedFeatures.sparseBinding || availableFeatures.sparseBinding) &&
(!requestedFeatures.sparseResidencyBuffer || availableFeatures.sparseResidencyBuffer) &&
(!requestedFeatures.sparseResidencyImage2D || availableFeatures.sparseResidencyImage2D) &&
(!requestedFeatures.sparseResidencyImage3D || availableFeatures.sparseResidencyImage3D) &&
(!requestedFeatures.sparseResidency2Samples || availableFeatures.sparseResidency2Samples) &&
(!requestedFeatures.sparseResidency4Samples || availableFeatures.sparseResidency4Samples) &&
(!requestedFeatures.sparseResidency8Samples || availableFeatures.sparseResidency8Samples) &&
(!requestedFeatures.sparseResidency16Samples || availableFeatures.sparseResidency16Samples) &&
(!requestedFeatures.sparseResidencyAliased || availableFeatures.sparseResidencyAliased) &&
(!requestedFeatures.variableMultisampleRate || availableFeatures.variableMultisampleRate) &&
(!requestedFeatures.inheritedQueries || availableFeatures.inheritedQueries);
}
void PhysicalDevice::getFormatProperties(VkFormat format, VkFormatProperties* pFormatProperties) const
{
pFormatProperties->linearTilingFeatures = 0; // Unsupported format
pFormatProperties->optimalTilingFeatures = 0; // Unsupported format
pFormatProperties->bufferFeatures = 0; // Unsupported format
}
void PhysicalDevice::getImageFormatProperties(VkFormat format, VkImageType type, VkImageTiling tiling,
VkImageUsageFlags usage, VkImageCreateFlags flags,
VkImageFormatProperties* pImageFormatProperties) const
{
pImageFormatProperties->maxArrayLayers = 1 << vk::MAX_IMAGE_ARRAY_LAYERS;
switch(type)
{
case VK_IMAGE_TYPE_1D:
pImageFormatProperties->maxMipLevels = vk::MAX_IMAGE_LEVELS_1D;
pImageFormatProperties->maxExtent.width = 1 << vk::MAX_IMAGE_LEVELS_1D;
pImageFormatProperties->maxExtent.height = 1;
pImageFormatProperties->maxExtent.depth = 1;
break;
case VK_IMAGE_TYPE_2D:
if(flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
{
pImageFormatProperties->maxMipLevels = vk::MAX_IMAGE_LEVELS_CUBE;
pImageFormatProperties->maxExtent.width = 1 << vk::MAX_IMAGE_LEVELS_CUBE;
pImageFormatProperties->maxExtent.height = 1 << vk::MAX_IMAGE_LEVELS_CUBE;
pImageFormatProperties->maxExtent.depth = 1;
}
else
{
pImageFormatProperties->maxMipLevels = vk::MAX_IMAGE_LEVELS_2D;
pImageFormatProperties->maxExtent.width = 1 << vk::MAX_IMAGE_LEVELS_2D;
pImageFormatProperties->maxExtent.height = 1 << vk::MAX_IMAGE_LEVELS_2D;
pImageFormatProperties->maxExtent.depth = 1;
}
break;
case VK_IMAGE_TYPE_3D:
pImageFormatProperties->maxMipLevels = vk::MAX_IMAGE_LEVELS_3D;
pImageFormatProperties->maxExtent.width = 1 << vk::MAX_IMAGE_LEVELS_3D;
pImageFormatProperties->maxExtent.height = 1 << vk::MAX_IMAGE_LEVELS_3D;
pImageFormatProperties->maxExtent.depth = 1 << vk::MAX_IMAGE_LEVELS_3D;
break;
default:
UNREACHABLE(type);
break;
}
pImageFormatProperties->maxResourceSize = 1 << 31; // Minimum value for maxResourceSize
pImageFormatProperties->sampleCounts = getSampleCounts();
}
uint32_t PhysicalDevice::getQueueFamilyPropertyCount() const
{
return 1;
}
void PhysicalDevice::getQueueFamilyProperties(uint32_t pQueueFamilyPropertyCount,
VkQueueFamilyProperties* pQueueFamilyProperties) const
{
for(uint32_t i = 0; i < pQueueFamilyPropertyCount; i++)
{
pQueueFamilyProperties[i].minImageTransferGranularity.width = 1;
pQueueFamilyProperties[i].minImageTransferGranularity.height = 1;
pQueueFamilyProperties[i].minImageTransferGranularity.depth = 1;
pQueueFamilyProperties[i].queueCount = 1;
pQueueFamilyProperties[i].queueFlags = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT;
pQueueFamilyProperties[i].timestampValidBits = 0; // No support for time stamps
}
}
const VkPhysicalDeviceMemoryProperties& PhysicalDevice::getMemoryProperties() const
{
static const VkPhysicalDeviceMemoryProperties properties
{
1, // memoryTypeCount
{{VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
0}}, // heapIndex
1, // memoryHeapCount
{{1ull << 31, // size, FIXME(sugoi): This could be configurable based on available RAM
VK_MEMORY_HEAP_DEVICE_LOCAL_BIT}},
};
return properties;
}
} // namespace vk
\ No newline at end of file
// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef VK_PHYSICAL_DEVICE_HPP_
#define VK_PHYSICAL_DEVICE_HPP_
#include "VkObject.hpp"
namespace vk
{
class PhysicalDevice
{
public:
static constexpr VkSystemAllocationScope GetAllocationScope() { return VK_SYSTEM_ALLOCATION_SCOPE_DEVICE; }
PhysicalDevice(const void*, void* mem);
void destroy(const VkAllocationCallbacks* pAllocator) {}
static size_t ComputeRequiredAllocationSize(const void*) { return 0; }
const VkPhysicalDeviceFeatures& getFeatures() const;
bool hasFeatures(const VkPhysicalDeviceFeatures& requestedFeatures) const;
const VkPhysicalDeviceProperties& getProperties() const;
void getFormatProperties(VkFormat format, VkFormatProperties* pFormatProperties) const;
void getImageFormatProperties(VkFormat format, VkImageType type, VkImageTiling tiling,
VkImageUsageFlags usage, VkImageCreateFlags flags,
VkImageFormatProperties* pImageFormatProperties) const;
uint32_t getQueueFamilyPropertyCount() const;
void getQueueFamilyProperties(uint32_t pQueueFamilyPropertyCount,
VkQueueFamilyProperties* pQueueFamilyProperties) const;
const VkPhysicalDeviceMemoryProperties& getMemoryProperties() const;
private:
const VkPhysicalDeviceLimits& getLimits() const;
VkSampleCountFlags getSampleCounts() const;
};
using DispatchablePhysicalDevice = DispatchableObject<PhysicalDevice, VkPhysicalDevice>;
static inline PhysicalDevice* Cast(VkPhysicalDevice object)
{
return DispatchablePhysicalDevice::Cast(object);
}
} // namespace vk
#endif // VK_PHYSICAL_DEVICE_HPP_
// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "VkQueue.hpp"
namespace vk
{
Queue::Queue(uint32_t pFamilyIndex, float pPriority) : familyIndex(pFamilyIndex), priority(pPriority)
{
}
} // namespace vk
\ No newline at end of file
// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef VK_QUEUE_HPP_
#define VK_QUEUE_HPP_
#include "VkObject.hpp"
namespace vk
{
class Queue
{
VK_LOADER_DATA loaderData = { ICD_LOADER_MAGIC };
public:
Queue(uint32_t pFamilyIndex, float pPriority);
~Queue() = delete;
operator VkQueue()
{
return reinterpret_cast<VkQueue>(this);
}
private:
uint32_t familyIndex = 0;
float priority = 0.0f;
};
static inline Queue* Cast(VkQueue object)
{
return reinterpret_cast<Queue*>(object);
}
} // namespace vk
#endif // VK_QUEUE_HPP_
......@@ -12,10 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "VkConfig.h"
#include "VkCommandBuffer.hpp"
#include "VkDebug.hpp"
#include "VkDevice.hpp"
#include "VkGetProcAddress.h"
#include <vulkan/vulkan.h>
#include "VkInstance.hpp"
#include "VkPhysicalDevice.hpp"
#include "VkQueue.hpp"
#include <cstring>
#include <string>
extern "C"
{
......@@ -29,16 +35,62 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance(const VkInstanceCreateInfo* pCre
TRACE("(const VkInstanceCreateInfo* pCreateInfo = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X, VkInstance* pInstance = 0x%X)",
pCreateInfo, pAllocator, pInstance);
UNIMPLEMENTED();
if(pCreateInfo->enabledLayerCount)
{
UNIMPLEMENTED();
}
return VK_SUCCESS;
if(pCreateInfo->enabledExtensionCount)
{
UNIMPLEMENTED();
}
if(pCreateInfo->pNext)
{
switch(*reinterpret_cast<const VkStructureType*>(pCreateInfo->pNext))
{
case VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO:
// According to the Vulkan spec, section 2.7.2. Implicit Valid Usage:
// "The values VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO and
// VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO are reserved for
// internal use by the loader, and do not have corresponding
// Vulkan structures in this Specification."
break;
default:
UNIMPLEMENTED();
}
}
*pInstance = VK_NULL_HANDLE;
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
VkResult result = vk::DispatchablePhysicalDevice::Create(pAllocator, pCreateInfo, &physicalDevice);
if(result != VK_SUCCESS)
{
return result;
}
vk::Instance::CreateInfo info =
{
pCreateInfo,
physicalDevice
};
result = vk::DispatchableInstance::Create(pAllocator, &info, pInstance);
if(result != VK_SUCCESS)
{
vk::destroy(physicalDevice, pAllocator);
return result;
}
return result;
}
VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks* pAllocator)
{
TRACE("(VkInstance instance = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)", instance, pAllocator);
UNIMPLEMENTED();
vk::destroy(instance, pAllocator);
}
VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices)
......@@ -46,7 +98,14 @@ VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(VkInstance instance, u
TRACE("(VkInstance instance = 0x%X, uint32_t* pPhysicalDeviceCount = 0x%X, VkPhysicalDevice* pPhysicalDevices = 0x%X)",
instance, pPhysicalDeviceCount, pPhysicalDevices);
UNIMPLEMENTED();
if(!pPhysicalDevices)
{
*pPhysicalDeviceCount = vk::Cast(instance)->getPhysicalDeviceCount();
}
else
{
vk::Cast(instance)->getPhysicalDevices(*pPhysicalDeviceCount, pPhysicalDevices);
}
return VK_SUCCESS;
}
......@@ -56,7 +115,7 @@ VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures(VkPhysicalDevice physical
TRACE("(VkPhysicalDevice physicalDevice = 0x%X, VkPhysicalDeviceFeatures* pFeatures = 0x%X)",
physicalDevice, pFeatures);
UNIMPLEMENTED();
*pFeatures = vk::Cast(physicalDevice)->getFeatures();
}
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties* pFormatProperties)
......@@ -64,7 +123,7 @@ VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties(VkPhysicalDevice
TRACE("GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice = 0x%X, VkFormat format = %d, VkFormatProperties* pFormatProperties = 0x%X)",
physicalDevice, (int)format, pFormatProperties);
UNIMPLEMENTED();
vk::Cast(physicalDevice)->getFormatProperties(format, pFormatProperties);
}
VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties* pImageFormatProperties)
......@@ -72,7 +131,7 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties(VkPhysic
TRACE("(VkPhysicalDevice physicalDevice = 0x%X, VkFormat format = %d, VkImageType type = %d, VkImageTiling tiling = %d, VkImageUsageFlags usage = %d, VkImageCreateFlags flags = %d, VkImageFormatProperties* pImageFormatProperties = 0x%X)",
physicalDevice, (int)format, (int)type, (int)tiling, usage, flags, pImageFormatProperties);
UNIMPLEMENTED();
vk::Cast(physicalDevice)->getImageFormatProperties(format, type, tiling, usage, flags, pImageFormatProperties);
return VK_SUCCESS;
}
......@@ -82,38 +141,39 @@ VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties(VkPhysicalDevice physic
TRACE("(VkPhysicalDevice physicalDevice = 0x%X, VkPhysicalDeviceProperties* pProperties = 0x%X)",
physicalDevice, pProperties);
UNIMPLEMENTED();
*pProperties = vk::Cast(physicalDevice)->getProperties();
}
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties* pQueueFamilyProperties)
{
TRACE("(VkPhysicalDevice physicalDevice = 0x%X, uint32_t* pQueueFamilyPropertyCount = 0x%X, VkQueueFamilyProperties* pQueueFamilyProperties = 0x%X))", physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties);
UNIMPLEMENTED();
if(!pQueueFamilyProperties)
{
*pQueueFamilyPropertyCount = vk::Cast(physicalDevice)->getQueueFamilyPropertyCount();
}
else
{
vk::Cast(physicalDevice)->getQueueFamilyProperties(*pQueueFamilyPropertyCount, pQueueFamilyProperties);
}
}
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties* pMemoryProperties)
{
TRACE("(VkPhysicalDevice physicalDevice = 0x%X, VkPhysicalDeviceMemoryProperties* pMemoryProperties = 0x%X)", physicalDevice, pMemoryProperties);
UNIMPLEMENTED();
*pMemoryProperties = vk::Cast(physicalDevice)->getMemoryProperties();
}
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char* pName)
{
TRACE("(VkInstance instance = 0x%X, const char* pName = 0x%X)", instance, pName);
UNIMPLEMENTED();
return vk::GetProcAddr(pName);
}
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device, const char* pName)
{
TRACE("(VkDevice device = 0x%X, const char* pName = 0x%X)", device, pName);
UNIMPLEMENTED();
return vk::GetProcAddr(pName);
}
......@@ -122,16 +182,62 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice, c
TRACE("(VkPhysicalDevice physicalDevice = 0x%X, const VkDeviceCreateInfo* pCreateInfo = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X, VkDevice* pDevice = 0x%X)",
physicalDevice, pCreateInfo, pAllocator, pDevice);
UNIMPLEMENTED();
if(pCreateInfo->enabledLayerCount || pCreateInfo->enabledExtensionCount)
{
UNIMPLEMENTED();
}
return VK_SUCCESS;
if(pCreateInfo->pNext)
{
switch(*reinterpret_cast<const VkStructureType*>(pCreateInfo->pNext))
{
case VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO:
// According to the Vulkan spec, section 2.7.2. Implicit Valid Usage:
// "The values VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO and
// VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO are reserved for
// internal use by the loader, and do not have corresponding
// Vulkan structures in this Specification."
break;
default:
UNIMPLEMENTED();
}
}
ASSERT(pCreateInfo->queueCreateInfoCount > 0);
if(pCreateInfo->pEnabledFeatures &&
!vk::Cast(physicalDevice)->hasFeatures(*(pCreateInfo->pEnabledFeatures)))
{
return VK_ERROR_FEATURE_NOT_PRESENT;
}
uint32_t queueFamilyPropertyCount = vk::Cast(physicalDevice)->getQueueFamilyPropertyCount();
for(uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++)
{
const VkDeviceQueueCreateInfo& queueCreateInfo = pCreateInfo->pQueueCreateInfos[i];
if(queueCreateInfo.pNext || queueCreateInfo.flags)
{
UNIMPLEMENTED();
}
ASSERT(queueCreateInfo.queueFamilyIndex < queueFamilyPropertyCount);
}
vk::Device::CreateInfo deviceCreateInfo =
{
pCreateInfo,
physicalDevice
};
return vk::DispatchableDevice::Create(pAllocator, &deviceCreateInfo, pDevice);
}
VKAPI_ATTR void VKAPI_CALL vkDestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator)
{
TRACE("(VkDevice device = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)", device, pAllocator);
UNIMPLEMENTED();
vk::destroy(device, pAllocator);
}
VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties)
......@@ -194,7 +300,11 @@ VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDe
{
TRACE("(VkPhysicalDevice physicalDevice = 0x%X, const char* pLayerName, uint32_t* pPropertyCount = 0x%X, VkExtensionProperties* pProperties = 0x%X)", physicalDevice, pPropertyCount, pProperties);
UNIMPLEMENTED();
if(!pProperties)
{
*pPropertyCount = 0;
return VK_SUCCESS;
}
return VK_SUCCESS;
}
......@@ -203,7 +313,11 @@ VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t* pPro
{
TRACE("(uint32_t* pPropertyCount = 0x%X, VkLayerProperties* pProperties = 0x%X)", pPropertyCount, pProperties);
UNIMPLEMENTED();
if(!pProperties)
{
*pPropertyCount = 0;
return VK_SUCCESS;
}
return VK_SUCCESS;
}
......@@ -212,7 +326,11 @@ VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice
{
TRACE("(VkPhysicalDevice physicalDevice = 0x%X, uint32_t* pPropertyCount = 0x%X, VkLayerProperties* pProperties = 0x%X)", physicalDevice, pPropertyCount, pProperties);
UNIMPLEMENTED();
if(!pProperties)
{
*pPropertyCount = 0;
return VK_SUCCESS;
}
return VK_SUCCESS;
}
......@@ -222,7 +340,7 @@ VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue(VkDevice device, uint32_t queueFamil
TRACE("(VkDevice device = 0x%X, uint32_t queueFamilyIndex = %d, uint32_t queueIndex = %d, VkQueue* pQueue = 0x%X)",
device, queueFamilyIndex, queueIndex, pQueue);
UNIMPLEMENTED();
*pQueue = vk::Cast(device)->getQueue(queueFamilyIndex, queueIndex);
}
VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo* pSubmits, VkFence fence)
......@@ -376,7 +494,7 @@ VKAPI_ATTR void VKAPI_CALL vkDestroyFence(VkDevice device, VkFence fence, const
{
TRACE("(VkDevice device = 0x%X, VkFence fence = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)",
device, fence, pAllocator);
UNIMPLEMENTED();
}
......@@ -1163,14 +1281,24 @@ VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures2(VkPhysicalDevice physica
{
TRACE("(VkPhysicalDevice physicalDevice = 0x%X, VkPhysicalDeviceFeatures2* pFeatures = 0x%X)", physicalDevice, pFeatures);
UNIMPLEMENTED();
if(pFeatures->pNext)
{
UNIMPLEMENTED();
}
vkGetPhysicalDeviceFeatures(physicalDevice, &(pFeatures->features));
}
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2* pProperties)
{
TRACE("(VkPhysicalDevice physicalDevice = 0x%X, VkPhysicalDeviceProperties2* pProperties = 0x%X)", physicalDevice, pProperties);
UNIMPLEMENTED();
if(pProperties->pNext)
{
UNIMPLEMENTED();
}
vkGetPhysicalDeviceProperties(physicalDevice, &(pProperties->properties));
}
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties2* pFormatProperties)
......@@ -1178,7 +1306,12 @@ VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties2(VkPhysicalDevice
TRACE("(VkPhysicalDevice physicalDevice = 0x%X, VkFormat format = %d, VkFormatProperties2* pFormatProperties = 0x%X)",
physicalDevice, format, pFormatProperties);
UNIMPLEMENTED();
if(pFormatProperties->pNext)
{
UNIMPLEMENTED();
}
vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &(pFormatProperties->formatProperties));
}
VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo, VkImageFormatProperties2* pImageFormatProperties)
......@@ -1186,9 +1319,18 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties2(VkPhysi
TRACE("(VkPhysicalDevice physicalDevice = 0x%X, const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo = 0x%X, VkImageFormatProperties2* pImageFormatProperties = 0x%X)",
physicalDevice, pImageFormatInfo, pImageFormatProperties);
UNIMPLEMENTED();
if(pImageFormatProperties->pNext)
{
UNIMPLEMENTED();
}
return VK_SUCCESS;
return vkGetPhysicalDeviceImageFormatProperties(physicalDevice,
pImageFormatInfo->format,
pImageFormatInfo->type,
pImageFormatInfo->tiling,
pImageFormatInfo->usage,
pImageFormatInfo->flags,
&(pImageFormatProperties->imageFormatProperties));
}
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties2(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties2* pQueueFamilyProperties)
......@@ -1196,20 +1338,53 @@ VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties2(VkPhysicalD
TRACE("(VkPhysicalDevice physicalDevice = 0x%X, uint32_t* pQueueFamilyPropertyCount = 0x%X, VkQueueFamilyProperties2* pQueueFamilyProperties = 0x%X)",
physicalDevice, pQueueFamilyPropertyCount, pQueueFamilyProperties);
UNIMPLEMENTED();
if(!pQueueFamilyProperties)
{
*pQueueFamilyPropertyCount = 1;
}
else
{
if(pQueueFamilyProperties->pNext)
{
UNIMPLEMENTED();
}
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, pQueueFamilyPropertyCount, &(pQueueFamilyProperties->queueFamilyProperties));
}
}
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2* pMemoryProperties)
{
TRACE("(VkPhysicalDevice physicalDevice = 0x%X, VkPhysicalDeviceMemoryProperties2* pMemoryProperties = 0x%X)", physicalDevice, pMemoryProperties);
UNIMPLEMENTED();
if(pMemoryProperties->pNext)
{
UNIMPLEMENTED();
}
vkGetPhysicalDeviceMemoryProperties(physicalDevice, &(pMemoryProperties->memoryProperties));
}
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties2(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, uint32_t* pPropertyCount, VkSparseImageFormatProperties2* pProperties)
{
TRACE("()");
UNIMPLEMENTED();
TRACE("(VkPhysicalDevice physicalDevice = 0x%X, const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo = 0x%X, uint32_t* pPropertyCount = 0x%X, VkSparseImageFormatProperties2* pProperties = 0x%X)",
physicalDevice, pFormatInfo, pPropertyCount, pProperties);
if(!pProperties)
{
*pPropertyCount = 1;
}
else
{
if(pProperties->pNext)
{
UNIMPLEMENTED();
}
vkGetPhysicalDeviceSparseImageFormatProperties(physicalDevice, pFormatInfo->format, pFormatInfo->type,
pFormatInfo->samples, pFormatInfo->usage, pFormatInfo->tiling,
pPropertyCount, &(pProperties->properties));
}
}
VKAPI_ATTR void VKAPI_CALL vkTrimCommandPool(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags)
......
......@@ -171,6 +171,17 @@ copy "$(OutDir)vk_swiftshader.dll" "$(SolutionDir)out\$(Configuration)_$(Platfor
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="libVulkan.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="VkCommandBuffer.cpp" />
<ClCompile Include="VkDebug.cpp" />
<ClCompile Include="VkDevice.cpp" />
<ClCompile Include="VkGetProcAddress.cpp" />
<ClCompile Include="VkInstance.cpp" />
<ClCompile Include="VkMemory.cpp" />
<ClCompile Include="VkPhysicalDevice.cpp" />
<ClCompile Include="VkPromotedExtensions.cpp" />
<ClCompile Include="VkQueue.cpp" />
<ClCompile Include="..\Device\Blitter.cpp" />
<ClCompile Include="..\Device\Clipper.cpp" />
<ClCompile Include="..\Device\Color.cpp" />
......@@ -253,13 +264,19 @@ copy "$(OutDir)vk_swiftshader.dll" "$(SolutionDir)out\$(Configuration)_$(Platfor
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="libVulkan.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="VkDebug.cpp" />
<ClCompile Include="VkGetProcAddress.cpp" />
<ClCompile Include="VkPromotedExtensions.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h" />
<ClInclude Include="VkCommandBuffer.hpp" />
<ClInclude Include="VkConfig.h" />
<ClInclude Include="VkDebug.hpp" />
<ClInclude Include="VkDevice.hpp" />
<ClInclude Include="VkGetProcAddress.h" />
<ClInclude Include="VkInstance.hpp" />
<ClInclude Include="VkMemory.h" />
<ClInclude Include="VkObject.hpp" />
<ClInclude Include="VkPhysicalDevice.hpp" />
<ClInclude Include="VkQueue.hpp" />
<ClInclude Include="..\Device\Blitter.hpp" />
<ClInclude Include="..\Device\Clipper.hpp" />
<ClInclude Include="..\Device\Color.hpp" />
......@@ -359,9 +376,6 @@ copy "$(OutDir)vk_swiftshader.dll" "$(SolutionDir)out\$(Configuration)_$(Platfor
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="VkDebug.hpp" />
<ClInclude Include="resource.h" />
<ClInclude Include="VkGetProcAddress.h" />
</ItemGroup>
<ItemGroup>
<None Include="..\WSI\FrameBufferOSX.mm">
......
......@@ -22,6 +22,12 @@
<Filter Include="Header Files\Pipeline">
<UniqueIdentifier>{ab31f9cb-85bf-4ad3-8ee0-1810977a5944}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Vulkan">
<UniqueIdentifier>{eae937f9-88b4-4bd4-ba7b-bb4a4dcdaf52}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Device">
<UniqueIdentifier>{31e80f94-e9d4-42cf-97b1-58bda4d1ab31}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\System">
<UniqueIdentifier>{c9884906-cd72-4adb-9641-d72660051aa3}</UniqueIdentifier>
</Filter>
......@@ -37,29 +43,8 @@
<Filter Include="Source Files\Device">
<UniqueIdentifier>{3fd774af-dfbe-40e2-9944-a85206cf00ee}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Vulkan">
<UniqueIdentifier>{eae937f9-88b4-4bd4-ba7b-bb4a4dcdaf52}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Device">
<UniqueIdentifier>{31e80f94-e9d4-42cf-97b1-58bda4d1ab31}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="libVulkan.cpp">
<Filter>Source Files\Vulkan</Filter>
</ClCompile>
<ClCompile Include="main.cpp">
<Filter>Source Files\Vulkan</Filter>
</ClCompile>
<ClCompile Include="VkDebug.cpp">
<Filter>Source Files\Vulkan</Filter>
</ClCompile>
<ClCompile Include="VkGetProcAddress.cpp">
<Filter>Source Files\Vulkan</Filter>
</ClCompile>
<ClCompile Include="VkPromotedExtensions.cpp">
<Filter>Source Files\Vulkan</Filter>
</ClCompile>
<ClCompile Include="..\Device\VertexProcessor.cpp">
<Filter>Source Files\Device</Filter>
</ClCompile>
......@@ -216,17 +201,71 @@
<ClCompile Include="..\System\Timer.cpp">
<Filter>Source Files\System</Filter>
</ClCompile>
<ClCompile Include="libVulkan.cpp">
<Filter>Source Files\Vulkan</Filter>
</ClCompile>
<ClCompile Include="main.cpp">
<Filter>Source Files\Vulkan</Filter>
</ClCompile>
<ClCompile Include="VkCommandBuffer.cpp">
<Filter>Source Files\Vulkan</Filter>
</ClCompile>
<ClCompile Include="VkDebug.cpp">
<Filter>Source Files\Vulkan</Filter>
</ClCompile>
<ClCompile Include="VkDevice.cpp">
<Filter>Source Files\Vulkan</Filter>
</ClCompile>
<ClCompile Include="VkGetProcAddress.cpp">
<Filter>Source Files\Vulkan</Filter>
</ClCompile>
<ClCompile Include="VkInstance.cpp">
<Filter>Source Files\Vulkan</Filter>
</ClCompile>
<ClCompile Include="VkMemory.cpp">
<Filter>Source Files\Vulkan</Filter>
</ClCompile>
<ClCompile Include="VkPhysicalDevice.cpp">
<Filter>Source Files\Vulkan</Filter>
</ClCompile>
<ClCompile Include="VkPromotedExtensions.cpp">
<Filter>Source Files\Vulkan</Filter>
</ClCompile>
<ClCompile Include="VkQueue.cpp">
<Filter>Source Files\Vulkan</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h">
<Filter>Header Files\Vulkan</Filter>
</ClInclude>
<ClInclude Include="VkDebug.hpp">
<ClInclude Include="VkCommandBuffer.hpp">
<Filter>Header Files\Vulkan</Filter>
</ClInclude>
<ClInclude Include="VkConfig.h">
<Filter>Header Files\Vulkan</Filter>
</ClInclude>
<ClInclude Include="VkDevice.hpp">
<Filter>Header Files\Vulkan</Filter>
</ClInclude>
<ClInclude Include="VkGetProcAddress.h">
<Filter>Header Files\Vulkan</Filter>
</ClInclude>
<ClInclude Include="VkInstance.hpp">
<Filter>Header Files\Vulkan</Filter>
</ClInclude>
<ClInclude Include="VkMemory.h">
<Filter>Header Files\Vulkan</Filter>
</ClInclude>
<ClInclude Include="VkObject.hpp">
<Filter>Header Files\Vulkan</Filter>
</ClInclude>
<ClInclude Include="VkPhysicalDevice.hpp">
<Filter>Header Files\Vulkan</Filter>
</ClInclude>
<ClInclude Include="VkQueue.hpp">
<Filter>Header Files\Vulkan</Filter>
</ClInclude>
<ClInclude Include="..\Device\VertexProcessor.hpp">
<Filter>Header Files\Device</Filter>
</ClInclude>
......@@ -419,6 +458,9 @@
<ClInclude Include="..\System\Types.hpp">
<Filter>Header Files\System</Filter>
</ClInclude>
<ClInclude Include="VkDebug.hpp">
<Filter>Header Files\Vulkan</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="swiftshader_icd.def" />
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment