2019-04-30 23:00:39 +02:00
# pragma once
2018-08-26 15:11:43 +02:00
# include <drm/drm.h>
# include <drm/drm_fourcc.h>
# include <drm/vc4_drm.h>
2019-09-30 02:13:55 +02:00
# define VK_NO_PROTOTYPES
2018-08-26 15:11:43 +02:00
# include <vulkan/vulkan.h>
2019-09-30 00:52:21 +02:00
# include <vulkan/vk_icd.h>
2018-08-26 15:11:43 +02:00
# include "vkExt.h"
# include "AlignedAllocator.h"
# include "PoolAllocator.h"
# include "ConsecutivePoolAllocator.h"
# include "LinearAllocator.h"
2019-05-02 23:00:23 +02:00
# include "map.h"
2018-08-26 15:11:43 +02:00
# include <stdio.h>
# include "CustomAssert.h"
# include <string.h>
# include <stdlib.h>
# include <unistd.h>
# include <stdint.h>
# include <pthread.h>
# include <semaphore.h>
# include "kernelInterface.h"
# include "ControlListUtil.h"
# ifndef min
# define min(a, b) (a < b ? a : b)
# endif
# ifndef max
# define max(a, b) (a > b ? a : b)
# endif
# include "vkCaps.h"
2018-11-17 16:53:13 +01:00
/**
//scope
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
VK_SYSTEM_ALLOCATION_SCOPE_CACHE
VK_SYSTEM_ALLOCATION_SCOPE_DEVICE
VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE
* */
2019-04-30 23:00:39 +02:00
# define ALLOCATE(size, alignment, scope) (pAllocator == 0) ? malloc(size) : pAllocator->pfnAllocation(pAllocator->pUserData, size, alignment, scope)
# define FREE(memory) (pAllocator == 0) ? free(memory) : pAllocator->pfnFree(pAllocator->pUserData, memory)
2018-11-17 16:53:13 +01:00
2020-04-17 13:06:41 +02:00
# define UNSUPPORTED(str) fprintf(stderr, "Unsupported: %s\n", #str); //exit(-1)
2020-02-08 20:38:29 +01:00
# define UNSUPPORTED_RETURN VK_SUCCESS
2019-09-07 18:41:46 +02:00
2018-11-16 20:39:33 +01:00
typedef struct VkDevice_T _device ;
2018-08-26 15:11:43 +02:00
typedef struct VkQueue_T
{
2019-09-30 00:52:21 +02:00
VK_LOADER_DATA loaderData ;
2018-08-26 15:11:43 +02:00
uint64_t lastEmitSeqno ;
2018-11-16 20:39:33 +01:00
_device * dev ;
2018-08-26 15:11:43 +02:00
} _queue ;
typedef struct VkCommandPool_T
{
PoolAllocator pa ;
ConsecutivePoolAllocator cpa ;
uint32_t queueFamilyIndex ;
2019-09-07 18:41:46 +02:00
uint32_t resetAble ;
2018-08-26 15:11:43 +02:00
} _commandPool ;
typedef enum commandBufferState
{
CMDBUF_STATE_INITIAL = 0 ,
CMDBUF_STATE_RECORDING ,
CMDBUF_STATE_EXECUTABLE ,
CMDBUF_STATE_PENDING ,
CMDBUF_STATE_INVALID ,
CMDBUF_STATE_LAST
} commandBufferState ;
2018-11-16 20:39:33 +01:00
typedef struct VkInstance_T _instance ;
typedef struct VkPhysicalDevice_T
{
2019-09-30 00:52:21 +02:00
VK_LOADER_DATA loaderData ;
2019-09-30 22:30:37 +02:00
//apparently unknown physical device extensions can't quite pass anything other than VkPhysicalDevice
//now that object has to have the loader magic
//so we just provide a custom data pointer so that our extensions can be used...
void * customData ;
2018-11-16 20:39:33 +01:00
//hardware id?
char * path ;
_instance * instance ;
} _physicalDevice ;
2018-08-26 15:11:43 +02:00
typedef struct VkInstance_T
{
2019-09-30 00:52:21 +02:00
VK_LOADER_DATA loaderData ;
2018-11-16 20:39:33 +01:00
_physicalDevice dev ;
2018-08-26 15:11:43 +02:00
//supposedly this should contain all the enabled layers?
int enabledExtensions [ numInstanceExtensions ] ;
int numEnabledExtensions ;
2020-02-21 00:51:59 +01:00
uint32_t technologyVersion ;
uint32_t IDstrUINT ;
uint32_t vpmMemorySize ;
uint32_t hdrSupported ;
uint32_t numSemaphores ;
uint32_t numTMUperSlice ;
uint32_t numQPUperSlice ;
uint32_t numSlices ;
uint32_t v3dRevision ;
uint32_t tileBufferDoubleBufferModeSupported ;
uint32_t tileBufferSize ;
uint32_t vriMemorySize ;
uint32_t hasTiling ;
uint32_t hasControlFlow ;
uint32_t hasEtc1 ;
uint32_t hasThreadedFs ;
uint32_t hasMadvise ;
uint32_t hasPerfmon ;
uint32_t hasFixedRCLorder ;
2018-08-26 15:11:43 +02:00
} _instance ;
typedef struct VkDevice_T
{
2019-09-30 00:52:21 +02:00
VK_LOADER_DATA loaderData ;
2018-08-26 15:11:43 +02:00
int enabledExtensions [ numDeviceExtensions ] ;
int numEnabledExtensions ;
VkPhysicalDeviceFeatures enabledFeatures ;
_physicalDevice * dev ;
_queue * queues [ numQueueFamilies ] ;
int numQueues [ numQueueFamilies ] ;
2019-12-14 20:43:52 +01:00
//emulation resources
VkBuffer emulFsqVertexBuffer ;
VkDeviceMemory emulFsqVertexBufferMemory ;
VkDescriptorPool emulDescriptorPool ;
2020-03-02 22:50:08 +01:00
VkDescriptorSetLayout emulBufferDsl ;
VkDescriptorSetLayout emulTextureDsl ;
VkSampler emulNearestTextureSampler ;
VkSampler emulLinearTextureSampler ;
VkShaderModule emulBufferToTextureShaderModule ;
VkShaderModule emulTextureToTextureShaderModule ;
VkShaderModule emulTextureToBufferShaderModule ; //TODO
VkShaderModule emulBufferToBufferShaderModule ; //TODO
2018-08-26 15:11:43 +02:00
} _device ;
2018-09-09 16:45:07 +02:00
typedef struct VkRenderPass_T
{
2018-09-18 22:22:43 +02:00
//collection of:
//attachments, subpasses, dependencies between subpasses
//describes how attachments are used in subpasses
//attachment describes:
//format, sample count, how contents are treated at start/end of a renderpass
//subpasses render to same dimensions and fragments
//framebuffer objects specify views for attachements
VkAttachmentDescription * attachments ;
uint32_t numAttachments ;
VkSubpassDescription * subpasses ;
uint32_t numSubpasses ;
VkSubpassDependency * subpassDependencies ;
uint32_t numSubpassDependencies ;
2018-09-09 16:45:07 +02:00
} _renderpass ;
typedef struct VkDeviceMemory_T
{
uint32_t size ;
uint32_t bo ;
uint32_t memTypeIndex ;
void * mappedPtr ;
uint32_t mappedOffset , mappedSize ;
} _deviceMemory ;
typedef struct VkBuffer_T
{
uint32_t size ;
VkBufferUsageFlags usage ;
_deviceMemory * boundMem ;
uint32_t boundOffset ;
uint32_t alignment ;
uint32_t alignedSize ;
} _buffer ;
2018-09-18 22:22:43 +02:00
typedef struct VkImage_T
{
2018-10-20 16:46:12 +02:00
VkImageType type ; //1d, 2d, 3d
2018-09-18 22:22:43 +02:00
uint32_t fb ; //needed for swapchain
uint32_t width , height , depth ;
uint32_t paddedWidth , paddedHeight ;
uint32_t miplevels , samples ;
2020-03-01 20:11:31 +01:00
uint32_t levelOffsets [ 11 ] ; //max 11 mip levels
2018-09-18 22:22:43 +02:00
uint32_t layers ; //number of views for multiview/stereo
2018-10-20 16:46:12 +02:00
uint32_t size ; //overall size including padding and alignment
2018-09-18 22:22:43 +02:00
uint32_t stride ; //the number of bytes from one row of pixels in memory to the next row of pixels in memory (aka pitch)
uint32_t usageBits ;
uint32_t format ;
uint32_t imageSpace ;
2020-03-02 00:28:27 +01:00
uint32_t tiling ; //Linear or T or LT
2018-09-18 22:22:43 +02:00
uint32_t layout ;
2018-10-20 16:46:12 +02:00
_deviceMemory * boundMem ;
uint32_t boundOffset ;
uint32_t alignment ;
2018-09-18 22:22:43 +02:00
uint32_t concurrentAccess ; //TODO
uint32_t numQueueFamiliesWithAccess ;
uint32_t * queueFamiliesWithAccess ;
uint32_t preTransformMode ;
uint32_t compositeAlpha ;
uint32_t presentMode ;
uint32_t clipped ;
2020-04-14 19:31:58 +02:00
uint32_t flags ;
2018-09-18 22:22:43 +02:00
} _image ;
typedef struct VkImageView_T
{
_image * image ;
VkImageViewType viewType ;
VkFormat interpretedFormat ;
VkComponentMapping swizzle ;
VkImageSubresourceRange subresourceRange ;
} _imageView ;
typedef struct VkSwapchain_T
{
_image * images ;
uint32_t numImages ;
uint32_t backbufferIdx ;
VkSurfaceKHR surface ;
} _swapchain ;
typedef struct VkFramebuffer_T
{
_renderpass * renderpass ;
_imageView * attachmentViews ;
uint32_t numAttachmentViews ;
uint32_t width , height , layers ;
} _framebuffer ;
typedef struct VkShaderModule_T
{
2020-04-21 16:22:19 +02:00
uint32_t bos [ VK_RPI_ASSEMBLY_TYPE_MAX ] ;
uint32_t sizes [ VK_RPI_ASSEMBLY_TYPE_MAX ] ;
2020-04-17 21:59:04 +02:00
//uint64_t* instructions[RPI_ASSEMBLY_TYPE_MAX];
2020-04-21 16:22:19 +02:00
VkRpiAssemblyMappingEXT * mappings [ VK_RPI_ASSEMBLY_TYPE_MAX ] ;
uint32_t numMappings [ VK_RPI_ASSEMBLY_TYPE_MAX ] ;
2019-08-25 22:59:18 +02:00
uint32_t hasThreadSwitch ;
2019-09-21 00:05:19 +02:00
uint32_t numVaryings ;
2018-09-18 22:22:43 +02:00
} _shaderModule ;
2019-07-27 22:57:13 +02:00
typedef struct VkDescriptorSetLayout_T
{
//an array of zero or more descriptor bindings
VkDescriptorSetLayoutBinding * bindings ;
uint32_t bindingsCount ;
VkDescriptorSetLayoutCreateFlags flags ;
} _descriptorSetLayout ;
2019-07-08 22:10:22 +02:00
typedef struct VkPipelineLayout_T
{
map descriptorSetBindingMap ;
uint32_t setLayoutCount ;
const _descriptorSetLayout * setLayouts ;
uint32_t pushConstantRangeCount ;
const VkPushConstantRange * pushConstantRanges ;
} _pipelineLayout ;
2018-09-23 21:55:30 +02:00
typedef struct VkPipeline_T
{
2019-07-08 22:10:22 +02:00
_shaderModule * modules [ 6 ] ;
2018-09-23 21:55:30 +02:00
char * names [ 6 ] ;
uint32_t vertexBindingDescriptionCount ;
VkVertexInputBindingDescription * vertexBindingDescriptions ;
uint32_t vertexAttributeDescriptionCount ;
VkVertexInputAttributeDescription * vertexAttributeDescriptions ;
VkPrimitiveTopology topology ;
VkBool32 primitiveRestartEnable ;
uint32_t viewportCount ;
VkViewport * viewports ;
uint32_t scissorCount ;
VkRect2D * scissors ;
VkBool32 depthClampEnable ;
VkBool32 rasterizerDiscardEnable ;
VkPolygonMode polygonMode ;
VkCullModeFlags cullMode ;
VkFrontFace frontFace ;
VkBool32 depthBiasEnable ;
float depthBiasConstantFactor ;
float depthBiasClamp ;
float depthBiasSlopeFactor ;
float lineWidth ;
VkSampleCountFlagBits rasterizationSamples ;
VkBool32 sampleShadingEnable ;
float minSampleShading ;
VkSampleMask sampleMask ;
VkBool32 alphaToCoverageEnable ;
VkBool32 alphaToOneEnable ;
VkBool32 depthTestEnable ;
VkBool32 depthWriteEnable ;
VkCompareOp depthCompareOp ;
VkBool32 depthBoundsTestEnable ;
VkBool32 stencilTestEnable ;
VkStencilOpState front ;
VkStencilOpState back ;
float minDepthBounds ;
float maxDepthBounds ;
VkBool32 logicOpEnable ;
VkLogicOp logicOp ;
uint32_t attachmentCount ;
VkPipelineColorBlendAttachmentState * attachmentBlendStates ;
float blendConstants [ 4 ] ;
uint32_t dynamicStateCount ;
VkDynamicState * dynamicStates ;
2019-07-08 22:10:22 +02:00
_pipelineLayout * layout ;
2018-09-23 21:55:30 +02:00
_renderpass * renderPass ;
uint32_t subpass ;
} _pipeline ;
2018-09-26 22:59:00 +02:00
typedef struct VkCommandBuffer_T
{
2019-09-30 00:52:21 +02:00
VK_LOADER_DATA loaderData ;
2019-08-19 23:12:51 +02:00
_device * dev ; //device from which it was created
2018-09-26 22:59:00 +02:00
//Recorded commands include commands to bind pipelines and descriptor sets to the command buffer, commands to modify dynamic state, commands to draw (for graphics rendering),
//commands to dispatch (for compute), commands to execute secondary command buffers (for primary command buffers only), commands to copy buffers and images, and other commands
2019-07-27 22:57:13 +02:00
//Rpi only supports vertex and pixel shaders
//(coordinate shaders will just use the vertex shader push constants)
//anything else will be ignored I guess
char pushConstantBufferVertex [ 256 ] ;
char pushConstantBufferPixel [ 256 ] ;
2018-09-26 22:59:00 +02:00
ControlList binCl ;
ControlList shaderRecCl ;
uint32_t shaderRecCount ;
ControlList uniformsCl ;
ControlList handlesCl ;
commandBufferState state ;
VkCommandBufferUsageFlags usageFlags ;
_commandPool * cp ;
2020-02-18 22:59:15 +01:00
//State data
2018-09-26 22:59:00 +02:00
_pipeline * graphicsPipeline ;
_pipeline * computePipeline ;
2019-09-01 20:14:47 +02:00
uint32_t numDrawCallsSubmitted ;
2018-10-21 14:33:02 +02:00
VkViewport viewport ;
VkRect2D scissor ;
float lineWidth ;
float depthBiasConstantFactor ;
float depthBiasClamp ;
float depthBiasSlopeFactor ;
float blendConstants [ 4 ] ;
float minDepthBounds ;
float maxDepthBounds ;
uint32_t stencilCompareMask [ 2 ] ;
uint32_t stencilWriteMask [ 2 ] ;
uint32_t stencilReference [ 2 ] ;
2018-09-26 22:59:00 +02:00
uint32_t vertexBufferOffsets [ 8 ] ;
_buffer * vertexBuffers [ 8 ] ;
2019-09-23 20:40:36 +02:00
uint32_t indexBufferOffset ;
_buffer * indexBuffer ;
2020-02-18 22:59:15 +01:00
2020-02-24 22:45:47 +01:00
//Renderpass scope query must begin outside renderpass
//so there won't be any current marker...
//therefore store perfmonID here, and copy on beginrenderpass
//into marker
void * perfmonID ;
2020-02-18 22:59:15 +01:00
//dirty flags used to reduce command stream clutter
uint32_t vertexBufferDirty ;
uint32_t indexBufferDirty ;
uint32_t viewportDirty ;
uint32_t lineWidthDirty ;
uint32_t depthBiasDirty ;
uint32_t graphicsPipelineDirty ;
uint32_t computePipelineDirty ;
uint32_t subpassDirty ;
uint32_t blendConstantsDirty ;
uint32_t scissorDirty ;
uint32_t depthBoundsDirty ;
uint32_t stencilCompareMaskDirty ;
uint32_t stencilWriteMaskDirty ;
uint32_t stencilReferenceDirty ;
uint32_t descriptorSetDirty ;
uint32_t pushConstantDirty ;
2018-09-26 22:59:00 +02:00
} _commandBuffer ;
2018-10-17 21:56:13 +02:00
typedef struct VkFence_T
{
uint64_t seqno ;
uint32_t signaled ;
} _fence ;
2018-10-18 22:17:02 +02:00
typedef struct VkBufferView_T
{
_buffer * buffer ;
VkFormat format ;
VkDeviceSize offset ;
VkDeviceSize range ;
} _bufferView ;
2019-04-30 23:00:39 +02:00
typedef struct VkSampler_T
{
2019-08-18 18:36:57 +02:00
VkFilter minFilter , magFilter ;
VkSamplerMipmapMode mipmapMode ;
2019-08-19 23:12:51 +02:00
VkSamplerAddressMode addressModeU , addressModeV , addressModeW ;
2019-08-18 18:36:57 +02:00
float mipLodBias ;
2020-03-10 21:20:35 +01:00
uint32_t disableAutoLod ;
2019-08-18 18:36:57 +02:00
VkBool32 anisotropyEnable ;
float maxAnisotropy ;
VkBool32 compareEnable ;
VkCompareOp compareOp ;
float minLod , maxLod ;
VkBorderColor borderColor ;
VkBool32 unnormalizedCoordinates ;
2019-04-30 23:00:39 +02:00
} _sampler ;
typedef struct VkDescriptorImage_T
{
uint32_t count ;
VkDescriptorType type ;
VkShaderStageFlags stageFlags ;
_sampler * sampler ;
_imageView * imageView ;
VkImageLayout imageLayout ;
} _descriptorImage ;
typedef struct VkDescriptorBuffer_T
{
uint32_t count ;
VkDescriptorType type ;
VkShaderStageFlags stageFlags ;
_buffer * buffer ;
VkDeviceSize offset ;
VkDeviceSize range ;
} _descriptorBuffer ;
typedef struct VkDescriptorTexelBuffer_T
{
uint32_t count ;
VkDescriptorType type ;
VkShaderStageFlags stageFlags ;
_bufferView * bufferView ;
} _descriptorTexelBuffer ;
typedef struct VkDescriptorSet_T
{
//VkDescriptorSetLayoutCreateFlags flags;
2019-05-02 23:00:23 +02:00
map imageBindingMap ;
map bufferBindingMap ;
map texelBufferBindingMap ;
//pointers into CPAs
2019-04-30 23:00:39 +02:00
//VK_DESCRIPTOR_TYPE_SAMPLER, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
//VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
//VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT
_descriptorImage * imageDescriptors ;
//VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
//VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
_descriptorBuffer * bufferDescriptors ;
//VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
_descriptorTexelBuffer * texelBufferDescriptors ;
uint32_t imageDescriptorsCount ;
uint32_t bufferDescriptorsCount ;
uint32_t texelBufferDescriptorsCount ;
} _descriptorSet ;
typedef struct VkDescriptorPool_T
{
PoolAllocator descriptorSetPA ;
2019-05-02 23:00:23 +02:00
ConsecutivePoolAllocator mapElementCPA ;
2019-04-30 23:00:39 +02:00
ConsecutivePoolAllocator * imageDescriptorCPA ;
ConsecutivePoolAllocator * bufferDescriptorCPA ;
ConsecutivePoolAllocator * texelBufferDescriptorCPA ;
2019-09-08 00:30:52 +02:00
uint32_t freeAble ;
2019-04-30 23:00:39 +02:00
} _descriptorPool ;
2020-02-22 22:50:53 +01:00
typedef struct VkQuery_T
{
uint32_t enabledCounters [ VC4_PERFCNT_NUM_EVENTS ] ;
2020-02-23 14:29:01 +01:00
uint64_t counterValues [ 2 ] [ DRM_VC4_MAX_PERF_COUNTERS ] ;
2020-02-22 22:50:53 +01:00
uint32_t numEnabledCounters ;
uint32_t perfmonIDs [ 2 ] ;
} _query ;
typedef struct VkQueryPool_T
{
VkQueryType type ;
uint32_t queryCount ;
_query * queryPool ;
} _queryPool ;
2020-04-16 01:04:41 +02:00
typedef struct VkDisplayModeKHR_T
{
uint32_t connectorID ;
uint32_t modeID ;
} _displayMode ;
2018-08-26 15:11:43 +02:00
uint32_t getFormatBpp ( VkFormat f ) ;
uint32_t packVec4IntoABGR8 ( const float rgba [ 4 ] ) ;
2018-10-15 23:37:09 +02:00
void createImageBO ( _image * i ) ;
2018-08-26 15:11:43 +02:00
int findInstanceExtension ( char * name ) ;
int findDeviceExtension ( char * name ) ;
2020-03-02 00:28:27 +01:00
void getUTileDimensions ( uint32_t bpp , uint32_t * tileW , uint32_t * tileH ) ;
uint32_t roundUp ( uint32_t numToRound , uint32_t multiple ) ;
2018-10-15 23:37:09 +02:00
int isDepthStencilFormat ( VkFormat format ) ;
2019-09-23 18:51:31 +02:00
uint32_t getCompareOp ( VkCompareOp op ) ;
uint32_t getStencilOp ( VkStencilOp op ) ;
2018-10-15 23:37:09 +02:00
uint32_t getTopology ( VkPrimitiveTopology topology ) ;
uint32_t getPrimitiveMode ( VkPrimitiveTopology topology ) ;
uint32_t getFormatByteSize ( VkFormat format ) ;
uint32_t ulog2 ( uint32_t v ) ;
2019-08-18 18:36:57 +02:00
void encodeTextureUniform ( uint32_t * params ,
uint8_t numMipLevels ,
uint8_t textureDataType ,
uint8_t isCubeMap ,
uint32_t cubemapStride ,
uint32_t textureBasePtr ,
uint16_t height ,
uint16_t width ,
uint8_t minFilter ,
uint8_t magFilter ,
uint8_t wrapT ,
uint8_t wrapS ,
uint8_t noAutoLod ) ;
2019-09-29 20:06:26 +02:00
void encodeStencilValue ( uint32_t * values , uint32_t * numValues , VkStencilOpState front , VkStencilOpState back , uint8_t stencilTestEnable ) ;
2019-12-08 16:31:42 +01:00
uint32_t encodeVPMSetup ( uint8_t stride ,
uint8_t direction ,
uint8_t isLaned ,
uint8_t size ,
uint8_t address ,
uint8_t vectorComponentsToRead ) ;
2019-08-18 18:36:57 +02:00
uint8_t getTextureDataType ( VkFormat format ) ;
2020-04-10 16:04:09 +02:00
uint8_t getMinFilterType ( VkFilter minFilter , VkSamplerMipmapMode mipFilter ) ; //, float maxLod);
2019-08-18 18:36:57 +02:00
uint8_t getWrapMode ( VkSamplerAddressMode mode ) ;
2019-09-01 20:14:47 +02:00
uint32_t getRenderTargetFormatVC4 ( VkFormat format ) ;
2018-10-16 20:34:17 +02:00
void clFit ( VkCommandBuffer cb , ControlList * cl , uint32_t commandSize ) ;
void clDump ( void * cl , uint32_t size ) ;
2019-12-14 20:43:52 +01:00
void setupEmulationResources ( VkDevice device ) ;
2020-03-01 20:11:31 +01:00
uint32_t getPow2Pad ( uint32_t n ) ;