From 8285408d9d00928b9601f9ec412c3fa5e2b91f7e Mon Sep 17 00:00:00 2001 From: Unknown <0.tamas.marton@gmail.com> Date: Sun, 18 Aug 2019 17:36:57 +0100 Subject: [PATCH] started to add functionality to make texture mapping work --- driver/common.c | 173 +++++++++++++++++++++++++++++++++++ driver/common.h | 48 ++++++++-- driver/draw.c | 113 +++++++++++++++++++++-- driver/shader.c | 84 +++++------------ driver/vkCaps.h | 6 +- driver/vkExt.h | 60 ++++++++++--- test/triangle/triangle.cpp | 178 ++++++++++++++++++++++++++++--------- 7 files changed, 524 insertions(+), 138 deletions(-) diff --git a/driver/common.c b/driver/common.c index a88ed76..f696196 100644 --- a/driver/common.c +++ b/driver/common.c @@ -557,7 +557,180 @@ void clDump(void* cl, uint32_t size) clif_dump_destroy(clif); } +void encodeTextureUniform(uint32_t* params, //array of 4 uint32_t + //num mip levels - 1 + uint8_t numMipLevels, + ///0: rgba8 + ///1: rgbx8 (a=1) + ///2: rgba4 + ///3: rgb5a1 + ///4: r5g6b5 (a=1) + ///5: luminance (8 bit, a=1) + //6: alpha (8 bit, rga=0) + ///7: lumalpha + ///8: etc1 + ///9: s16f (blending supported) + ///10: s8 (blending supported) + ///11: s16 (point sampling only) + //12: bw1 (1 bit black and white) + //13: a4 + //14: a1 + ///15: rgba16f + //16: rgba8r (raster format = not in T format) + ///17: yuyv422r (raster format = not in T format, yuyv) + uint8_t textureDataType, + uint8_t isCubeMap, + uint32_t cubemapStride, //in multiples of 4k bytes + uint32_t textureBasePtr, //in multiples of 4k bytes + //0 = 2048 + uint16_t height, + uint16_t width, + //0: linear + //1: nearest + //2: near_mip_near + //3: near_mip_lin + //4: lin_mip_near + //5: lin_mip_lin + uint8_t minFilter, + //0: linear + //1: nearest + uint8_t magFilter, + //0: repeat + //1: clamp + //2: mirror + //3: border + uint8_t wrapT, + uint8_t wrapS, + uint8_t noAutoLod //disable automatic LOD, use bias only + ) +{ + assert(params); + params[0] = 0 + | numMipLevels & 0xf + | (uint32_t)(textureDataType & 0xf) << 4 + | (uint32_t)(isCubeMap ? 1 : 0) << 9 + | (uint32_t)(textureBasePtr & 0xfffff) << 12; + + params[1] = 0 + | wrapS & 0x3 + | (uint32_t)(wrapT & 0x3) << 2 + | (uint32_t)(minFilter & 0x7) << 4 + | (uint32_t)(magFilter & 0x1) << 7 + | (uint32_t)(width & 0x7ff) << 8 + | (uint32_t)(height & 0x7ff) < 20 + | (uint32_t)((textureDataType & 0x10) >> 4) << 31; + + params[2] = 0 + | noAutoLod & 0x1 + | (uint32_t)(cubemapStride & 0x3ffff) << 12 + | (uint32_t)(isCubeMap ? 1 : 0) << 30; + + //TODO + //child images + params[3] = 0; +} + +uint8_t getTextureDataType(VkFormat format) +{ + switch(format) + { + case VK_FORMAT_R16G16B16A16_SFLOAT: + return 15; //rgba16f + case VK_FORMAT_R8G8B8_UNORM: + return 1; //rgbx8 (a=1) + case VK_FORMAT_R8G8B8A8_UNORM: + return 0; //rgba8 + case VK_FORMAT_R5G5B5A1_UNORM_PACK16: + return 3; //rgb5a1 + case VK_FORMAT_R4G4B4A4_UNORM_PACK16: + return 2; //rgba4 + case VK_FORMAT_R5G6B5_UNORM_PACK16: + return 4; //r5g6b5 (a=1) + case VK_FORMAT_R8G8_UNORM: + return 7; //lumalpha + case VK_FORMAT_R16_SFLOAT: + return 9; //s16f (blending supported) + case VK_FORMAT_R16_SINT: + return 11; //s16 (point sampling only) + case VK_FORMAT_R8_UNORM: + return 5; //luminance (8 bit, a=1) + case VK_FORMAT_R8_SINT: + return 10; //s8 (blending supported) + case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: + return 8; //etc1 + case VK_FORMAT_G8B8G8R8_422_UNORM: + return 17; //yuyv422r (raster format = not in T format, yuyv) + case VK_FORMAT_UNDEFINED: //TODO + return -1; + default:// + printf("unsupported format %i\n", format); + assert(0); + return -1; + } +} + +uint8_t getMinFilterType(VkFilter minFilter, VkSamplerMipmapMode mipFilter, float maxLod) +{ + if(minFilter == VK_FILTER_NEAREST) + { + if(maxLod < 0.0001f) + { + return 1; //no mip filtering + } + + if(mipFilter == VK_SAMPLER_MIPMAP_MODE_NEAREST) + { + return 2; + } + else if(mipFilter == VK_SAMPLER_MIPMAP_MODE_LINEAR) + { + return 3; + } + } + else if(minFilter == VK_FILTER_LINEAR) + { + if(maxLod < 0.0001f) + { + return 0; //no mip filtering + } + + if(mipFilter == VK_SAMPLER_MIPMAP_MODE_NEAREST) + { + return 4; + } + else if(mipFilter == VK_SAMPLER_MIPMAP_MODE_LINEAR) + { + return 5; + } + } +} + +uint8_t getWrapMode(VkSamplerAddressMode mode) +{ + if(mode == VK_SAMPLER_ADDRESS_MODE_REPEAT) + { + return 0; + } + else if(mode == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE) + { + return 1; + } + else if(mode == VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT) + { + return 2; + } + else if(mode == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) + { + return 3; + } + else + { + printf("unsupported wrap mode: %i\n", mode); + assert(0); + return -1; + } +} //////////////////////////////////////////////////// //////////////////////////////////////////////////// diff --git a/driver/common.h b/driver/common.h index 9f0a694..2f7acaa 100644 --- a/driver/common.h +++ b/driver/common.h @@ -202,16 +202,20 @@ typedef struct VkFramebuffer_T uint32_t width, height, layers; } _framebuffer; +typedef enum RpiAssemblyType { + RPI_ASSEMBLY_TYPE_COORDINATE = 0, + RPI_ASSEMBLY_TYPE_VERTEX = 1, + RPI_ASSEMBLY_TYPE_FRAGMENT = 2, + RPI_ASSEMBLY_TYPE_COMPUTE = 3, + RPI_ASSEMBLY_TYPE_MAX, +} RpiAssemblyType; + typedef struct VkShaderModule_T { - uint32_t bos[VK_RPI_ASSEMBLY_TYPE_MAX]; - uint32_t sizes[VK_RPI_ASSEMBLY_TYPE_MAX]; - uint32_t* descriptorBindings[VK_RPI_ASSEMBLY_TYPE_MAX]; - uint32_t* descriptorSets[VK_RPI_ASSEMBLY_TYPE_MAX]; - VkDescriptorType* descriptorTypes[VK_RPI_ASSEMBLY_TYPE_MAX]; - uint32_t* descriptorCounts[VK_RPI_ASSEMBLY_TYPE_MAX]; - uint32_t* descriptorArrayElems[VK_RPI_ASSEMBLY_TYPE_MAX]; - uint32_t numDescriptorBindings[VK_RPI_ASSEMBLY_TYPE_MAX]; + uint32_t bos[RPI_ASSEMBLY_TYPE_MAX]; + uint32_t sizes[RPI_ASSEMBLY_TYPE_MAX]; + VkRpiAssemblyMappingEXT* mappings; + uint32_t numMappings; } _shaderModule; typedef struct VkDescriptorSetLayout_T @@ -363,7 +367,17 @@ typedef struct VkBufferView_T typedef struct VkSampler_T { - int dummy; + VkFilter minFilter, magFilter; + VkSamplerMipmapMode mipmapMode; + VkSamplerAddressMode addressModeU, addressModeV, assressModeW; + float mipLodBias; + VkBool32 anisotropyEnable; + float maxAnisotropy; + VkBool32 compareEnable; + VkCompareOp compareOp; + float minLod, maxLod; + VkBorderColor borderColor; + VkBool32 unnormalizedCoordinates; } _sampler; typedef struct VkDescriptorImage_T @@ -442,5 +456,21 @@ uint32_t getTopology(VkPrimitiveTopology topology); uint32_t getPrimitiveMode(VkPrimitiveTopology topology); uint32_t getFormatByteSize(VkFormat format); uint32_t ulog2(uint32_t v); +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); +uint8_t getTextureDataType(VkFormat format); +uint8_t getMinFilterType(VkFilter minFilter, VkSamplerMipmapMode mipFilter, float maxLod); +uint8_t getWrapMode(VkSamplerAddressMode mode); void clFit(VkCommandBuffer cb, ControlList* cl, uint32_t commandSize); void clDump(void* cl, uint32_t size); diff --git a/driver/draw.c b/driver/draw.c index 4fdd5e1..63a2c61 100644 --- a/driver/draw.c +++ b/driver/draw.c @@ -102,17 +102,17 @@ void vkCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t ins //emit shader record ControlListAddress fragCode = { - .handle = ((_shaderModule*)(cb->graphicsPipeline->modules[ulog2(VK_SHADER_STAGE_FRAGMENT_BIT)]))->bos[VK_RPI_ASSEMBLY_TYPE_FRAGMENT], + .handle = ((_shaderModule*)(cb->graphicsPipeline->modules[ulog2(VK_SHADER_STAGE_FRAGMENT_BIT)]))->bos[RPI_ASSEMBLY_TYPE_FRAGMENT], .offset = 0, }; ControlListAddress vertCode = { - .handle = ((_shaderModule*)(cb->graphicsPipeline->modules[ulog2(VK_SHADER_STAGE_VERTEX_BIT)]))->bos[VK_RPI_ASSEMBLY_TYPE_VERTEX], + .handle = ((_shaderModule*)(cb->graphicsPipeline->modules[ulog2(VK_SHADER_STAGE_VERTEX_BIT)]))->bos[RPI_ASSEMBLY_TYPE_VERTEX], .offset = 0, }; ControlListAddress coordCode = { - .handle = ((_shaderModule*)(cb->graphicsPipeline->modules[ulog2(VK_SHADER_STAGE_VERTEX_BIT)]))->bos[VK_RPI_ASSEMBLY_TYPE_COORDINATE], + .handle = ((_shaderModule*)(cb->graphicsPipeline->modules[ulog2(VK_SHADER_STAGE_VERTEX_BIT)]))->bos[RPI_ASSEMBLY_TYPE_COORDINATE], .offset = 0, }; @@ -266,7 +266,110 @@ void vkCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t ins _pipelineLayout* pl = cb->graphicsPipeline->layout; - for(uint32_t c = 0; c < pl->pushConstantRangeCount; ++c) + for(uint32_t c = 0; c < cb->graphicsPipeline->modules[ulog2(VK_SHADER_STAGE_FRAGMENT_BIT)]->numMappings; ++c) + { + VkRpiAssemblyMappingEXT mapping = cb->graphicsPipeline->modules[ulog2(VK_SHADER_STAGE_FRAGMENT_BIT)]->mappings[c]; + + if(mapping.shaderStage & VK_SHADER_STAGE_FRAGMENT_BIT) + { + if(mapping.mappingType == VK_RPI_ASSEMBLY_MAPPING_TYPE_PUSH_CONSTANT) + { + clFit(commandBuffer, &commandBuffer->uniformsCl, 4); + clInsertData(&commandBuffer->uniformsCl, 4, cb->pushConstantBufferPixel + mapping.resourceOffset); + } + else if(mapping.mappingType == VK_RPI_ASSEMBLY_MAPPING_TYPE_DESCRIPTOR) + { + if(mapping.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || + mapping.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || + mapping.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) + { + _descriptorSet* ds = getMapElement(pl->descriptorSetBindingMap, mapping.descriptorSet); + _descriptorImage* di = getMapElement(ds->imageBindingMap, mapping.descriptorBinding); + di += mapping.descriptorArrayElement; + + //TODO handle miplevels according to subresource rage? + uint32_t params[4]; + encodeTextureUniform(params, + di->imageView->image->miplevels - 1, + getTextureDataType(di->imageView->interpretedFormat), + di->imageView->viewType == VK_IMAGE_VIEW_TYPE_CUBE, + 0, //TODO cubemap stride + 0, //TODO texture base ptr + di->imageView->image->height % 2048, + di->imageView->image->width % 2048, + getMinFilterType(di->sampler->minFilter, di->sampler->mipmapMode, di->sampler->maxLod), + di->sampler->magFilter == VK_FILTER_NEAREST, + getWrapMode(di->sampler->addressModeU), + getWrapMode(di->sampler->addressModeV), + 0 //TODO no auto LOD + ); + + uint32_t size = 0; + if(di->imageView->viewType == VK_IMAGE_VIEW_TYPE_1D) + { + size = 4; + } + else if(di->imageView->viewType == VK_IMAGE_VIEW_TYPE_2D) + { + size = 8; + } + else if(di->imageView->viewType == VK_IMAGE_VIEW_TYPE_CUBE) + { + size = 12; + } + else + { + assert(0); //unsupported + } + + //emit reloc for texture BO + clFit(commandBuffer, &commandBuffer->handlesCl, 4); + //TODO anything to do with the index returned? + clGetHandleIndex(&commandBuffer->handlesCl, di->imageView->image->boundMem->bo); + + //emit tex parameters + clFit(commandBuffer, &commandBuffer->uniformsCl, size); + clInsertData(&commandBuffer->uniformsCl, size, params); + } + else + { //all buffers types handled here + //TODO + } + } + else + { + assert(0); //shouldn't happen + } + } + } + + //do it twice for vertex and then coordinate + for(uint32_t d = 0; d < 2; ++d) + { + for(uint32_t c = 0; c < cb->graphicsPipeline->modules[ulog2(VK_SHADER_STAGE_VERTEX_BIT)]->numMappings; ++c) + { + VkRpiAssemblyMappingEXT mapping = cb->graphicsPipeline->modules[ulog2(VK_SHADER_STAGE_VERTEX_BIT)]->mappings[c]; + + if(mapping.shaderStage & VK_SHADER_STAGE_VERTEX_BIT) + { + if(mapping.mappingType == VK_RPI_ASSEMBLY_MAPPING_TYPE_PUSH_CONSTANT) + { + clFit(commandBuffer, &commandBuffer->uniformsCl, 4); + clInsertData(&commandBuffer->uniformsCl, 4, cb->pushConstantBufferVertex + mapping.resourceOffset); + } + else if(mapping.mappingType == VK_RPI_ASSEMBLY_MAPPING_TYPE_DESCRIPTOR) + { + + } + else + { + assert(0); //shouldn't happen + } + } + } + } + + /*for(uint32_t c = 0; c < pl->pushConstantRangeCount; ++c) { //TODO //we should use the shader module's declaration of what order it wants this to be passed in @@ -297,7 +400,7 @@ void vkCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t ins clFit(commandBuffer, &commandBuffer->uniformsCl, pl->pushConstantRanges[c].size); clInsertData(&commandBuffer->uniformsCl, pl->pushConstantRanges[c].size, cb->pushConstantBufferVertex + pl->pushConstantRanges[c].offset); } - } + }*/ /*_shaderModule* csModule = cb->graphicsPipeline->modules[ulog2(VK_SHADER_STAGE_VERTEX_BIT)]; _pipelineLayout* pl = cb->graphicsPipeline->layout; diff --git a/driver/shader.c b/driver/shader.c index 209df6d..8afaf84 100644 --- a/driver/shader.c +++ b/driver/shader.c @@ -18,7 +18,7 @@ VkResult vkCreateShaderModuleFromRpiAssemblyEXT(VkDevice device, VkRpiShaderModu return VK_ERROR_OUT_OF_HOST_MEMORY; } - for(int c = 0; c < VK_RPI_ASSEMBLY_TYPE_MAX; ++c) + for(int c = 0; c < RPI_ASSEMBLY_TYPE_MAX; ++c) { if(pCreateInfo->asmStrings[c]) { @@ -46,66 +46,28 @@ VkResult vkCreateShaderModuleFromRpiAssemblyEXT(VkDevice device, VkRpiShaderModu FREE(instructions); shader->sizes[c] = size; - - shader->numDescriptorBindings[c] = pCreateInfo->numDescriptorBindings[c]; - - if(pCreateInfo->numDescriptorBindings[c] > 0) - { - uint32_t offset = 0; - for(uint32_t d = 0; d < c; ++d) - { - offset += pCreateInfo->numDescriptorBindings[d]; - } - - shader->descriptorBindings[c] = ALLOCATE(sizeof(uint32_t)*pCreateInfo->numDescriptorBindings[c], 1, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - if(!shader->descriptorBindings[c]) - { - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - memcpy(shader->descriptorBindings[c], pCreateInfo->descriptorBindings + offset, sizeof(uint32_t)*pCreateInfo->numDescriptorBindings[c]); - - shader->descriptorSets[c] = ALLOCATE(sizeof(uint32_t)*pCreateInfo->numDescriptorBindings[c], 1, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - if(!shader->descriptorSets[c]) - { - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - memcpy(shader->descriptorSets[c], pCreateInfo->descriptorSets + offset, sizeof(uint32_t)*pCreateInfo->numDescriptorBindings[c]); - - shader->descriptorTypes[c] = ALLOCATE(sizeof(VkDescriptorType)*pCreateInfo->numDescriptorBindings[c], 1, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - if(!shader->descriptorTypes[c]) - { - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - memcpy(shader->descriptorTypes[c], pCreateInfo->descriptorTypes + offset, sizeof(VkDescriptorType)*pCreateInfo->numDescriptorBindings[c]); - - shader->descriptorCounts[c] = ALLOCATE(sizeof(uint32_t)*pCreateInfo->numDescriptorBindings[c], 1, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - if(!shader->descriptorCounts[c]) - { - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - memcpy(shader->descriptorCounts[c], pCreateInfo->descriptorCounts + offset, sizeof(uint32_t)*pCreateInfo->numDescriptorBindings[c]); - - shader->descriptorArrayElems[c] = ALLOCATE(sizeof(uint32_t)*pCreateInfo->numDescriptorBindings[c], 1, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - if(!shader->descriptorArrayElems[c]) - { - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - memcpy(shader->descriptorArrayElems[c], pCreateInfo->descriptorArrayElems + offset, sizeof(uint32_t)*pCreateInfo->numDescriptorBindings[c]); - } } else { shader->bos[c] = 0; - shader->descriptorBindings[c] = 0; - shader->descriptorCounts[c] = 0; - shader->descriptorSets[c] = 0; - shader->descriptorTypes[c] = 0; - shader->descriptorArrayElems[c] = 0; - shader->numDescriptorBindings[c] = 0; shader->sizes[c] = 0; } } + shader->numMappings = pCreateInfo->numMappings; + + if(pCreateInfo->numMappings > 0) + { + shader->mappings = ALLOCATE(sizeof(VkRpiAssemblyMappingEXT)*pCreateInfo->numMappings, 1, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + + if(!shader->mappings) + { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + + memcpy(shader->mappings, pCreateInfo->mappings, sizeof(VkRpiAssemblyMappingEXT)*pCreateInfo->numMappings); + } + *pShaderModule = shader; return VK_SUCCESS; @@ -128,21 +90,19 @@ void vkDestroyShaderModule(VkDevice device, VkShaderModule shaderModule, const V if(shader) { - for(int c = 0; c < VK_RPI_ASSEMBLY_TYPE_MAX; ++c) + for(int c = 0; c < RPI_ASSEMBLY_TYPE_MAX; ++c) { if(shader->bos[c]) { vc4_bo_free(controlFd, shader->bos[c], 0, shader->sizes[c]); - if(shader->numDescriptorBindings[c]>0) - { - FREE(shader->descriptorBindings[c]); - FREE(shader->descriptorSets[c]); - FREE(shader->descriptorTypes[c]); - FREE(shader->descriptorCounts[c]); - FREE(shader->descriptorArrayElems[c]); - } } } + + if(shader->numMappings>0) + { + FREE(shader->mappings); + } + FREE(shader); } } diff --git a/driver/vkCaps.h b/driver/vkCaps.h index f8c5dfd..9a5b0e0 100644 --- a/driver/vkCaps.h +++ b/driver/vkCaps.h @@ -302,8 +302,7 @@ static VkFormat unsupportedFormats[] = VK_FORMAT_BC6H_SFLOAT_BLOCK, VK_FORMAT_BC7_UNORM_BLOCK, VK_FORMAT_BC7_SRGB_BLOCK, - VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, //etc2 formats - VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, + VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, //etc2 formats VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, @@ -340,8 +339,7 @@ static VkFormat unsupportedFormats[] = VK_FORMAT_ASTC_12x10_SRGB_BLOCK, VK_FORMAT_ASTC_12x12_UNORM_BLOCK, VK_FORMAT_ASTC_12x12_SRGB_BLOCK, - VK_FORMAT_G8B8G8R8_422_UNORM, //TODO yuv formats??? - VK_FORMAT_B8G8R8G8_422_UNORM, + VK_FORMAT_B8G8R8G8_422_UNORM, //TODO yuv formats??? VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM, diff --git a/driver/vkExt.h b/driver/vkExt.h index 919e6ca..695800e 100644 --- a/driver/vkExt.h +++ b/driver/vkExt.h @@ -13,14 +13,6 @@ typedef enum VkRpiSurfaceCreateFlagsEXT { VK_RPI_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkRpiSurfaceCreateFlagsEXT; -typedef enum VkRpiAssemblyTypeEXT { - VK_RPI_ASSEMBLY_TYPE_COORDINATE = 0, - VK_RPI_ASSEMBLY_TYPE_VERTEX = 1, - VK_RPI_ASSEMBLY_TYPE_FRAGMENT = 2, - VK_RPI_ASSEMBLY_TYPE_COMPUTE = 3, - VK_RPI_ASSEMBLY_TYPE_MAX, -} VkRpiAssemblyTypeKHR; - typedef struct VkRpiSurfaceCreateInfoEXT { VkStructureType sType; const void* pNext; @@ -28,16 +20,56 @@ typedef struct VkRpiSurfaceCreateInfoEXT { //maybe include some other stuff dunno } VkRpiSurfaceCreateInfoEXT; +typedef enum VkRpiAssemblyMappingTypeEXT { + VK_RPI_ASSEMBLY_MAPPING_TYPE_DESCRIPTOR = 0, + VK_RPI_ASSEMBLY_MAPPING_TYPE_PUSH_CONSTANT = 1, + VK_RPI_ASSEMBLY_MAPPING_TYPE_MAX +} VkRpiAssemblyMappingTypeEXT; + +/* + * assembly to vulkan resource mapping + * + * map vulkan resources such as + * -push constants + * -descriptor set entries + * -images + * -buffers + * + * to assembly uniform reads + * + * push constants should be one read + * + * buffers and images are handled through the TMU pipeline + * and therefore carry implicit uniform reads + * buffers should be one uniform (general memory read) + * number of uniforms for images are dependent on type (and TMU writes) + * + * therefore what we need is a mapping for each assembly uniform read + * to some vulkan resource + * and the driver should be able to figure out what to put in the uniform queue + * based on the mapping + * + * vertex and coordinate shader mappings are shared + * + */ + +//defines mapping for a single uniform FIFO read to a Vulkan resource +typedef struct VkRpiAssemblyMappingEXT { + VkRpiAssemblyMappingTypeEXT mappingType; + VkDescriptorType descriptorType; + uint32_t descriptorSet; + uint32_t descriptorBinding; + uint32_t descriptorArrayElement; + uint32_t resourceOffset; //in bytes + VkShaderStageFlagBits shaderStage; +} VkRpiAssemblyMappingEXT; + typedef struct VkRpiShaderModuleAssemblyCreateInfoEXT { VkStructureType sType; const void* pNext; char** asmStrings; - uint32_t* descriptorBindings; - uint32_t* descriptorSets; - VkDescriptorType* descriptorTypes; - uint32_t* descriptorCounts; - uint32_t* descriptorArrayElems; - uint32_t* numDescriptorBindings; + VkRpiAssemblyMappingEXT* mappings; + uint32_t numMappings; } VkRpiShaderModuleAssemblyCreateInfoEXT; //extension name something like: VK_KHR_rpi_surface diff --git a/test/triangle/triangle.cpp b/test/triangle/triangle.cpp index 2a95212..6eba1e0 100644 --- a/test/triangle/triangle.cpp +++ b/test/triangle/triangle.cpp @@ -78,6 +78,10 @@ VkDescriptorPool descriptorPool; VkDescriptorSet descriptorSet; VkDescriptorSetLayout dsl; VkPipelineLayout pipelineLayout; +VkImage textureImage; +VkDeviceMemory textureMemory; +VkSampler textureSampler; +VkImageView textureView; uint32_t graphicsQueueFamily; uint32_t presentQueueFamily; @@ -814,24 +818,6 @@ void CreateFramebuffer() printf("Frame buffers created\n"); } -VkShaderModule VulkanCreateShaderModule(VkDevice& device, char* byteStream, uint32_t byteStreamSize) -{ - VkShaderModule shaderModule; - - VkShaderModuleCreateInfo shaderCreateInfo = {}; - shaderCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - shaderCreateInfo.codeSize = byteStreamSize; - shaderCreateInfo.pCode = (const uint32_t*)byteStream; - - VkResult res = vkCreateShaderModule(device, &shaderCreateInfo, NULL, &shaderModule); - - //VkResult res = vkCreateShaderModuleFromRpiAssemblyKHR(device, byteStreamSize, byteStream, NULL, &shaderModule); - - printf("Created shader\n"); - - return shaderModule; -} - void CreateShaders() { /** @@ -1000,36 +986,60 @@ void CreateShaders() (char*)cs_asm_code, (char*)vs_asm_code, (char*)fs_asm_code, 0 }; - uint32_t numDescriptorBindings[VK_RPI_ASSEMBLY_TYPE_MAX] = {4, 4, 0, 0}; - uint32_t descriptorBindings[VK_RPI_ASSEMBLY_TYPE_MAX][4] = { - {0, 0, 0, 0}, - {0, 0, 0, 0} - }; - uint32_t descriptorSets[VK_RPI_ASSEMBLY_TYPE_MAX][4] = { - {0, 0, 0, 0}, - {0, 0, 0, 0} - }; - VkDescriptorType descriptorTypes[VK_RPI_ASSEMBLY_TYPE_MAX][4] = { - {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER}, - {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER} - }; - uint32_t descriptorCounts[VK_RPI_ASSEMBLY_TYPE_MAX][4] = { - {4, 4, 4, 4}, - {4, 4, 4, 4} - }; - uint32_t descriptorArrayElems[VK_RPI_ASSEMBLY_TYPE_MAX][4] = { - {2, 0, 1, 3}, //coord - {0, 1, 2, 3}, //vert + VkRpiAssemblyMappingEXT mappings[] = { + //vertex shader uniforms + { + VK_RPI_ASSEMBLY_MAPPING_TYPE_PUSH_CONSTANT, + VK_DESCRIPTOR_TYPE_MAX_ENUM, //descriptor type + 0, //descriptor set # + 0, //descriptor binding # + 0, //descriptor array element # + 0, //resource offset + VK_SHADER_STAGE_VERTEX_BIT + }, + { + VK_RPI_ASSEMBLY_MAPPING_TYPE_PUSH_CONSTANT, + VK_DESCRIPTOR_TYPE_MAX_ENUM, //descriptor type + 0, //descriptor set # + 0, //descriptor binding # + 0, //descriptor array element # + 4, //resource offset + VK_SHADER_STAGE_VERTEX_BIT + }, + { + VK_RPI_ASSEMBLY_MAPPING_TYPE_PUSH_CONSTANT, + VK_DESCRIPTOR_TYPE_MAX_ENUM, //descriptor type + 0, //descriptor set # + 0, //descriptor binding # + 0, //descriptor array element # + 8, //resource offset + VK_SHADER_STAGE_VERTEX_BIT + }, + { + VK_RPI_ASSEMBLY_MAPPING_TYPE_PUSH_CONSTANT, + VK_DESCRIPTOR_TYPE_MAX_ENUM, //descriptor type + 0, //descriptor set # + 0, //descriptor binding # + 0, //descriptor array element # + 12, //resource offset + VK_SHADER_STAGE_VERTEX_BIT + }, + //fragment shader uniforms + { + VK_RPI_ASSEMBLY_MAPPING_TYPE_PUSH_CONSTANT, + VK_DESCRIPTOR_TYPE_MAX_ENUM, //descriptor type + 0, //descriptor set # + 0, //descriptor binding # + 0, //descriptor array element # + 0, //resource offset + VK_SHADER_STAGE_FRAGMENT_BIT + } }; VkRpiShaderModuleAssemblyCreateInfoEXT shaderModuleCreateInfo; shaderModuleCreateInfo.asmStrings = asm_strings; - shaderModuleCreateInfo.numDescriptorBindings = numDescriptorBindings; - shaderModuleCreateInfo.descriptorBindings = (uint32_t*)descriptorBindings; - shaderModuleCreateInfo.descriptorSets = (uint32_t*)descriptorSets; - shaderModuleCreateInfo.descriptorTypes = (VkDescriptorType*)descriptorTypes; - shaderModuleCreateInfo.descriptorCounts = (uint32_t*)descriptorCounts; - shaderModuleCreateInfo.descriptorArrayElems = (uint32_t*)descriptorArrayElems; + shaderModuleCreateInfo.mappings = mappings; + shaderModuleCreateInfo.numMappings = sizeof(mappings) / sizeof(VkRpiAssemblyMappingEXT); VkResult res = vkCreateShaderModuleFromRpiAssemblyEXT(device, &shaderModuleCreateInfo, 0, &shaderModule); assert(shaderModule); @@ -1212,6 +1222,86 @@ void CreateUniformBuffer() printf("Uniform buffer created\n");*/ } +void CreateTexture() +{ + VkFormat format = VK_FORMAT_R8G8B8A8_UNORM; + + char texData[4 * 2 * 2] = + { + //r, g, b, a + 255, 0, 0, 255, 0, 0, 255, 255, + 0, 0, 255, 255, 255, 0, 0, 255 + + }; + + uint32_t width = 2, height = 2; + uint32_t mipLevels = 1; + + VkImageCreateInfo imageCreateInfo = {}; + imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + imageCreateInfo.pNext = 0; + imageCreateInfo.imageType = VK_IMAGE_TYPE_2D; + imageCreateInfo.format = format; + imageCreateInfo.mipLevels = mipLevels; + imageCreateInfo.arrayLayers = 1; + imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; + imageCreateInfo.tiling = VK_IMAGE_TILING_LINEAR; + imageCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT; + imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; + imageCreateInfo.extent = { width, height, 1 }; + vkCreateImage(device, &imageCreateInfo, 0, &textureImage); + + VkMemoryRequirements mr; + vkGetImageMemoryRequirements(device, textureImage, &mr); + + VkMemoryAllocateInfo mai = {}; + mai.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + mai.allocationSize = mr.size; + mai.memoryTypeIndex = getMemoryTypeIndex(pdmp, mr.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + + vkAllocateMemory(device, &mai, 0, &textureMemory); + + void* data; + vkMapMemory(device, textureMemory, 0, mr.size, 0, &data); + memcpy(data, texData, sizeof(texData)); + vkUnmapMemory(device, textureMemory); + + vkBindImageMemory(device, textureImage, textureMemory, 0); + + //TODO do barrier here to transition layout... + + VkSamplerCreateInfo sampler = {}; + sampler.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + sampler.pNext = 0; + sampler.magFilter = VK_FILTER_LINEAR; + sampler.minFilter = VK_FILTER_LINEAR; + sampler.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + sampler.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; + sampler.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; + sampler.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; + sampler.mipLodBias = 0.0f; + sampler.compareOp = VK_COMPARE_OP_NEVER; + sampler.minLod = 0.0f; + sampler.maxLod = 0.0f; + sampler.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; + vkCreateSampler(device, &sampler, 0, &textureSampler); + + VkImageViewCreateInfo view = {}; + view.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + view.pNext = 0; + view.viewType = VK_IMAGE_VIEW_TYPE_2D; + view.format = format; + view.components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; + view.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + view.subresourceRange.baseMipLevel = 0; + view.subresourceRange.baseArrayLayer = 0; + view.subresourceRange.layerCount = 1; + view.subresourceRange.levelCount = 1; + view.image = textureImage; + vkCreateImageView(device, &view, nullptr, &textureView); +} + void CreateDescriptorSet() { /*VkDescriptorSetLayoutBinding setLayoutBinding = {};