From 5a4ebf6bc12b01fdecdb04c1e4a1df573d75ce8a Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Wed, 8 Jul 2015 17:29:49 -0700 Subject: [PATCH] vk: Move to the new pipeline creation API's --- include/vulkan/vulkan.h | 130 ++++++++++++------- src/vulkan/compiler.cpp | 12 +- src/vulkan/device.c | 4 +- src/vulkan/glsl_scraper.py | 24 ++-- src/vulkan/meta.c | 213 +++++++++++++++---------------- src/vulkan/pipeline.c | 254 ++++++++++++++++++++++--------------- src/vulkan/private.h | 9 +- 7 files changed, 368 insertions(+), 278 deletions(-) diff --git a/include/vulkan/vulkan.h b/include/vulkan/vulkan.h index fd226c5570a..98146b1276a 100644 --- a/include/vulkan/vulkan.h +++ b/include/vulkan/vulkan.h @@ -215,6 +215,8 @@ typedef enum { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO = 52, VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET, + VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, + VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, VK_ENUM_RANGE(STRUCTURE_TYPE, APPLICATION_INFO, PIPELINE_LAYOUT_CREATE_INFO) } VkStructureType; @@ -437,7 +439,7 @@ typedef enum { VK_OBJECT_TYPE_IMAGE_VIEW = 9, VK_OBJECT_TYPE_COLOR_ATTACHMENT_VIEW = 10, VK_OBJECT_TYPE_DEPTH_STENCIL_VIEW = 11, - + VK_OBJECT_TYPE_SHADER_MODULE = 12, VK_OBJECT_TYPE_SHADER = 13, VK_OBJECT_TYPE_PIPELINE = 14, VK_OBJECT_TYPE_PIPELINE_LAYOUT = 15, @@ -455,9 +457,10 @@ typedef enum { VK_OBJECT_TYPE_QUERY_POOL = 27, VK_OBJECT_TYPE_FRAMEBUFFER = 28, VK_OBJECT_TYPE_RENDER_PASS = 29, + VK_OBJECT_TYPE_PIPELINE_CACHE = 30, VK_OBJECT_TYPE_BEGIN_RANGE = VK_OBJECT_TYPE_INSTANCE, - VK_OBJECT_TYPE_END_RANGE = VK_OBJECT_TYPE_RENDER_PASS, - VK_NUM_OBJECT_TYPE = (VK_OBJECT_TYPE_END_RANGE - VK_OBJECT_TYPE_BEGIN_RANGE + 1), + VK_OBJECT_TYPE_END_RANGE = VK_OBJECT_TYPE_PIPELINE_CACHE, + VK_OBJECT_TYPE_NUM = (VK_OBJECT_TYPE_PIPELINE_CACHE - VK_OBJECT_TYPE_INSTANCE + 1), VK_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF } VkObjectType; @@ -1006,6 +1009,7 @@ typedef enum { VK_DEPTH_STENCIL_VIEW_CREATE_READ_ONLY_STENCIL_BIT = 0x00000002, } VkDepthStencilViewCreateFlagBits; typedef VkFlags VkDepthStencilViewCreateFlags; +typedef VkFlags VkShaderModuleCreateFlags; typedef VkFlags VkShaderCreateFlags; typedef enum { @@ -1019,6 +1023,7 @@ typedef VkFlags VkChannelFlags; typedef enum { VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT = 0x00000001, VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT = 0x00000002, + VK_PIPELINE_CREATE_DERIVATIVE_BIT = 0x00000004, } VkPipelineCreateFlagBits; typedef VkFlags VkPipelineCreateFlags; @@ -1377,20 +1382,30 @@ typedef struct { const void* pNext; size_t codeSize; const void* pCode; + VkShaderModuleCreateFlags flags; +} VkShaderModuleCreateInfo; + +typedef struct { + VkStructureType sType; + const void* pNext; + VkShaderModule module; + const char* pName; VkShaderCreateFlags flags; } VkShaderCreateInfo; +typedef struct { + VkStructureType sType; + const void* pNext; + size_t initialSize; + const void* initialData; + size_t maxSize; +} VkPipelineCacheCreateInfo; + typedef struct { uint32_t constantId; uint32_t offset; } VkSpecializationMapEntry; -typedef struct { - uint32_t bufferId; - size_t bufferSize; - const void* pBufferData; -} VkLinkConstBuffer; - typedef struct { uint32_t mapEntryCount; const VkSpecializationMapEntry* pMap; @@ -1398,17 +1413,11 @@ typedef struct { } VkSpecializationInfo; typedef struct { + VkStructureType sType; + const void* pNext; VkShaderStage stage; VkShader shader; - uint32_t linkConstBufferCount; - const VkLinkConstBuffer* pLinkConstBufferInfo; const VkSpecializationInfo* pSpecializationInfo; -} VkPipelineShader; - -typedef struct { - VkStructureType sType; - const void* pNext; - VkPipelineShader shader; } VkPipelineShaderStageCreateInfo; typedef struct { @@ -1517,23 +1526,45 @@ typedef struct { typedef struct { VkStructureType sType; const void* pNext; + uint32_t stageCount; + const VkPipelineShaderStageCreateInfo* pStages; + const VkPipelineVertexInputStateCreateInfo* pVertexInputState; + const VkPipelineIaStateCreateInfo* pIaState; + const VkPipelineTessStateCreateInfo* pTessState; + const VkPipelineVpStateCreateInfo* pVpState; + const VkPipelineRsStateCreateInfo* pRsState; + const VkPipelineMsStateCreateInfo* pMsState; + const VkPipelineDsStateCreateInfo* pDsState; + const VkPipelineCbStateCreateInfo* pCbState; VkPipelineCreateFlags flags; VkPipelineLayout layout; + VkPipeline basePipelineHandle; + int32_t basePipelineIndex; } VkGraphicsPipelineCreateInfo; typedef struct { VkStructureType sType; const void* pNext; - VkPipelineShader cs; + VkPipelineShaderStageCreateInfo cs; VkPipelineCreateFlags flags; VkPipelineLayout layout; + VkPipeline basePipelineHandle; + int32_t basePipelineIndex; } VkComputePipelineCreateInfo; +typedef struct { + VkShaderStageFlags stageFlags; + uint32_t start; + uint32_t length; +} VkPushConstantRange; + typedef struct { VkStructureType sType; const void* pNext; uint32_t descriptorSetCount; const VkDescriptorSetLayout* pSetLayouts; + uint32_t pushConstantRangeCount; + const VkPushConstantRange* pPushConstantRanges; } VkPipelineLayoutCreateInfo; typedef struct { @@ -1892,13 +1923,14 @@ typedef VkResult (VKAPI *PFN_vkGetImageSubresourceLayout)(VkDevice device, VkIma typedef VkResult (VKAPI *PFN_vkCreateImageView)(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, VkImageView* pView); typedef VkResult (VKAPI *PFN_vkCreateColorAttachmentView)(VkDevice device, const VkColorAttachmentViewCreateInfo* pCreateInfo, VkColorAttachmentView* pView); typedef VkResult (VKAPI *PFN_vkCreateDepthStencilView)(VkDevice device, const VkDepthStencilViewCreateInfo* pCreateInfo, VkDepthStencilView* pView); +typedef VkResult (VKAPI *PFN_vkCreateShaderModule)(VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, VkShaderModule* pShaderModule); typedef VkResult (VKAPI *PFN_vkCreateShader)(VkDevice device, const VkShaderCreateInfo* pCreateInfo, VkShader* pShader); -typedef VkResult (VKAPI *PFN_vkCreateGraphicsPipeline)(VkDevice device, const VkGraphicsPipelineCreateInfo* pCreateInfo, VkPipeline* pPipeline); -typedef VkResult (VKAPI *PFN_vkCreateGraphicsPipelineDerivative)(VkDevice device, const VkGraphicsPipelineCreateInfo* pCreateInfo, VkPipeline basePipeline, VkPipeline* pPipeline); -typedef VkResult (VKAPI *PFN_vkCreateComputePipeline)(VkDevice device, const VkComputePipelineCreateInfo* pCreateInfo, VkPipeline* pPipeline); -typedef VkResult (VKAPI *PFN_vkStorePipeline)(VkDevice device, VkPipeline pipeline, size_t* pDataSize, void* pData); -typedef VkResult (VKAPI *PFN_vkLoadPipeline)(VkDevice device, size_t dataSize, const void* pData, VkPipeline* pPipeline); -typedef VkResult (VKAPI *PFN_vkLoadPipelineDerivative)(VkDevice device, size_t dataSize, const void* pData, VkPipeline basePipeline, VkPipeline* pPipeline); +typedef VkResult (VKAPI *PFN_vkCreatePipelineCache)(VkDevice device, const VkPipelineCacheCreateInfo* pCreateInfo, VkPipelineCache* pPipelineCache); +typedef size_t (VKAPI *PFN_vkGetPipelineCacheSize)(VkDevice device, VkPipelineCache pipelineCache); +typedef VkResult (VKAPI *PFN_vkGetPipelineCacheData)(VkDevice device, VkPipelineCache pipelineCache, void* pData); +typedef VkResult (VKAPI *PFN_vkMergePipelineCaches)(VkDevice device, VkPipelineCache destCache, uint32_t srcCacheCount, const VkPipelineCache* pSrcCaches); +typedef VkResult (VKAPI *PFN_vkCreateGraphicsPipelines)(VkDevice device, VkPipelineCache pipelineCache, uint32_t count, const VkGraphicsPipelineCreateInfo* pCreateInfos, VkPipeline* pPipelines); +typedef VkResult (VKAPI *PFN_vkCreateComputePipelines)(VkDevice device, VkPipelineCache pipelineCache, uint32_t count, const VkComputePipelineCreateInfo* pCreateInfos, VkPipeline* pPipelines); typedef VkResult (VKAPI *PFN_vkCreatePipelineLayout)(VkDevice device, const VkPipelineLayoutCreateInfo* pCreateInfo, VkPipelineLayout* pPipelineLayout); typedef VkResult (VKAPI *PFN_vkCreateSampler)(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, VkSampler* pSampler); typedef VkResult (VKAPI *PFN_vkCreateDescriptorSetLayout)(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayout* pSetLayout); @@ -2200,45 +2232,49 @@ VkResult VKAPI vkCreateDepthStencilView( const VkDepthStencilViewCreateInfo* pCreateInfo, VkDepthStencilView* pView); +VkResult VKAPI vkCreateShaderModule( + VkDevice device, + const VkShaderModuleCreateInfo* pCreateInfo, + VkShaderModule* pShaderModule); + VkResult VKAPI vkCreateShader( VkDevice device, const VkShaderCreateInfo* pCreateInfo, VkShader* pShader); -VkResult VKAPI vkCreateGraphicsPipeline( +VkResult VKAPI vkCreatePipelineCache( VkDevice device, - const VkGraphicsPipelineCreateInfo* pCreateInfo, - VkPipeline* pPipeline); + const VkPipelineCacheCreateInfo* pCreateInfo, + VkPipelineCache* pPipelineCache); -VkResult VKAPI vkCreateGraphicsPipelineDerivative( +size_t VKAPI vkGetPipelineCacheSize( VkDevice device, - const VkGraphicsPipelineCreateInfo* pCreateInfo, - VkPipeline basePipeline, - VkPipeline* pPipeline); + VkPipelineCache pipelineCache); -VkResult VKAPI vkCreateComputePipeline( +VkResult VKAPI vkGetPipelineCacheData( VkDevice device, - const VkComputePipelineCreateInfo* pCreateInfo, - VkPipeline* pPipeline); + VkPipelineCache pipelineCache, + void* pData); -VkResult VKAPI vkStorePipeline( +VkResult VKAPI vkMergePipelineCaches( VkDevice device, - VkPipeline pipeline, - size_t* pDataSize, - void* pData); + VkPipelineCache destCache, + uint32_t srcCacheCount, + const VkPipelineCache* pSrcCaches); -VkResult VKAPI vkLoadPipeline( +VkResult VKAPI vkCreateGraphicsPipelines( VkDevice device, - size_t dataSize, - const void* pData, - VkPipeline* pPipeline); + VkPipelineCache pipelineCache, + uint32_t count, + const VkGraphicsPipelineCreateInfo* pCreateInfos, + VkPipeline* pPipelines); -VkResult VKAPI vkLoadPipelineDerivative( +VkResult VKAPI vkCreateComputePipelines( VkDevice device, - size_t dataSize, - const void* pData, - VkPipeline basePipeline, - VkPipeline* pPipeline); + VkPipelineCache pipelineCache, + uint32_t count, + const VkComputePipelineCreateInfo* pCreateInfos, + VkPipeline* pPipelines); VkResult VKAPI vkCreatePipelineLayout( VkDevice device, diff --git a/src/vulkan/compiler.cpp b/src/vulkan/compiler.cpp index 558a31001e2..fb9615306e6 100644 --- a/src/vulkan/compiler.cpp +++ b/src/vulkan/compiler.cpp @@ -942,7 +942,7 @@ anv_compile_shader_glsl(struct anv_compiler *compiler, shader = brw_new_shader(&brw->ctx, name, stage_info[stage].token); fail_if(shader == NULL, "failed to create %s shader\n", stage_info[stage].name); - shader->Source = strdup(src_as_glsl(pipeline->shaders[stage]->data)); + shader->Source = strdup(src_as_glsl(pipeline->shaders[stage]->module->data)); _mesa_glsl_compile_shader(&brw->ctx, shader, false, false); fail_on_compile_error(shader->CompileStatus, shader->InfoLog); @@ -968,13 +968,13 @@ anv_compile_shader_spirv(struct anv_compiler *compiler, mesa_shader->Type = stage_info[stage].token; mesa_shader->Stage = stage_info[stage].stage; - assert(shader->size % 4 == 0); + assert(shader->module->size % 4 == 0); struct gl_shader_compiler_options *glsl_options = &compiler->screen->compiler->glsl_compiler_options[stage_info[stage].stage]; mesa_shader->Program->nir = - spirv_to_nir((uint32_t *)shader->data, shader->size / 4, + spirv_to_nir((uint32_t *)shader->module->data, shader->module->size / 4, glsl_options->NirOptions); nir_validate_shader(mesa_shader->Program->nir); @@ -1041,14 +1041,14 @@ anv_compiler_run(struct anv_compiler *compiler, struct anv_pipeline *pipeline) continue; /* You need at least this much for "void main() { }" anyway */ - assert(pipeline->shaders[i]->size >= 12); + assert(pipeline->shaders[i]->module->size >= 12); - if (src_as_glsl(pipeline->shaders[i]->data)) { + if (src_as_glsl(pipeline->shaders[i]->module->data)) { all_spirv = false; break; } - assert(pipeline->shaders[i]->size % 4 == 0); + assert(pipeline->shaders[i]->module->size % 4 == 0); } if (all_spirv) { diff --git a/src/vulkan/device.c b/src/vulkan/device.c index 379095c24da..61e29a78015 100644 --- a/src/vulkan/device.c +++ b/src/vulkan/device.c @@ -1015,6 +1015,7 @@ VkResult anv_DestroyObject( return anv_FreeMemory(_device, (VkDeviceMemory) _object); case VK_OBJECT_TYPE_DESCRIPTOR_POOL: + case VK_OBJECT_TYPE_PIPELINE_CACHE: /* These are just dummys anyway, so we don't need to destroy them */ return VK_SUCCESS; @@ -1022,6 +1023,7 @@ VkResult anv_DestroyObject( case VK_OBJECT_TYPE_IMAGE: case VK_OBJECT_TYPE_DEPTH_STENCIL_VIEW: case VK_OBJECT_TYPE_SHADER: + case VK_OBJECT_TYPE_SHADER_MODULE: case VK_OBJECT_TYPE_PIPELINE_LAYOUT: case VK_OBJECT_TYPE_SAMPLER: case VK_OBJECT_TYPE_DESCRIPTOR_SET: @@ -2877,7 +2879,7 @@ flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer) uint32_t s, dirty = cmd_buffer->descriptors_dirty & cmd_buffer->pipeline->active_stages; - VkResult result; + VkResult result = VK_SUCCESS; for_each_bit(s, dirty) { result = flush_descriptor_set(cmd_buffer, s); if (result != VK_SUCCESS) diff --git a/src/vulkan/glsl_scraper.py b/src/vulkan/glsl_scraper.py index f72aaf8299c..918c156027a 100644 --- a/src/vulkan/glsl_scraper.py +++ b/src/vulkan/glsl_scraper.py @@ -101,7 +101,7 @@ class Shader: line_start += 6 f.write('\n};\n') -token_exp = re.compile(r'(GLSL_VK_SHADER|\(|\)|,)') +token_exp = re.compile(r'(GLSL_VK_SHADER_MODULE|\(|\)|,)') class Parser: def __init__(self, f): @@ -172,7 +172,7 @@ class Parser: def run(self): for t in self.token_iter: - if t == 'GLSL_VK_SHADER': + if t == 'GLSL_VK_SHADER_MODULE': self.handle_macro() def open_file(name, mode): @@ -188,9 +188,10 @@ def open_file(name, mode): def parse_args(): description = dedent("""\ - This program scrapes a C file for any instance of the GLSL_VK_SHADER - macro, grabs the GLSL source code, compiles it to SPIR-V. The resulting - SPIR-V code is written to another C file as an array of 32-bit words. + This program scrapes a C file for any instance of the + GLSL_VK_SHADER_MODULE macro, grabs the GLSL source code, compiles it + to SPIR-V. The resulting SPIR-V code is written to another C file as + an array of 32-bit words. If '-' is passed as the input file or output file, stdin or stdout will be used instead of a file on disc.""") @@ -256,15 +257,16 @@ with open_file(outfname, 'w') as outfile: #define _ANV_GLSL_SRC_VAR2(_line) _glsl_helpers_shader ## _line ## _glsl_src #define _ANV_GLSL_SRC_VAR(_line) _ANV_GLSL_SRC_VAR2(_line) - #define GLSL_VK_SHADER(device, stage, ...) ({ \\ - VkShader __shader; \\ - VkShaderCreateInfo __shader_create_info = { \\ - .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO, \\ + #define GLSL_VK_SHADER_MODULE(device, stage, ...) ({ \\ + VkShaderModule __module; \\ + VkShaderModuleCreateInfo __shader_create_info = { \\ + .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, \\ .codeSize = sizeof(_ANV_GLSL_SRC_VAR(__LINE__)), \\ .pCode = _ANV_GLSL_SRC_VAR(__LINE__), \\ }; \\ - vkCreateShader((VkDevice) device, &__shader_create_info, &__shader); \\ - __shader; \\ + vkCreateShaderModule((VkDevice) device, \\ + &__shader_create_info, &__module); \\ + __module; \\ }) """)) diff --git a/src/vulkan/meta.c b/src/vulkan/meta.c index c89373f3316..7f17adee733 100644 --- a/src/vulkan/meta.c +++ b/src/vulkan/meta.c @@ -33,16 +33,10 @@ static void anv_device_init_meta_clear_state(struct anv_device *device) { - VkPipelineIaStateCreateInfo ia_create_info = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO, - .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, - .primitiveRestartEnable = false, - }; - /* We don't use a vertex shader for clearing, but instead build and pass * the VUEs directly to the rasterization backend. */ - VkShader fs = GLSL_VK_SHADER(device, FRAGMENT, + VkShader fsm = GLSL_VK_SHADER_MODULE(device, FRAGMENT, out vec4 f_color; flat in vec4 v_color; void main() @@ -51,17 +45,13 @@ anv_device_init_meta_clear_state(struct anv_device *device) } ); - VkPipelineShaderStageCreateInfo fs_create_info = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - .pNext = &ia_create_info, - .shader = { - .stage = VK_SHADER_STAGE_FRAGMENT, - .shader = fs, - .linkConstBufferCount = 0, - .pLinkConstBufferInfo = NULL, - .pSpecializationInfo = NULL - } - }; + VkShader fs; + anv_CreateShader((VkDevice) device, + &(VkShaderCreateInfo) { + .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO, + .module = fsm, + .pName = "main", + }, &fs); /* We use instanced rendering to clear multiple render targets. We have two * vertex buffers: the first vertex buffer holds per-vertex data and @@ -71,7 +61,6 @@ anv_device_init_meta_clear_state(struct anv_device *device) */ VkPipelineVertexInputStateCreateInfo vi_create_info = { .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, - .pNext = &fs_create_info, .bindingCount = 2, .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) { { @@ -111,32 +100,39 @@ anv_device_init_meta_clear_state(struct anv_device *device) } }; - VkPipelineRsStateCreateInfo rs_create_info = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO, - .pNext = &vi_create_info, - .depthClipEnable = true, - .rasterizerDiscardEnable = false, - .fillMode = VK_FILL_MODE_SOLID, - .cullMode = VK_CULL_MODE_NONE, - .frontFace = VK_FRONT_FACE_CCW - }; - - VkPipelineCbStateCreateInfo cb_create_info = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO, - .pNext = &rs_create_info, - .attachmentCount = 1, - .pAttachments = (VkPipelineCbAttachmentState []) { - { .channelWriteMask = VK_CHANNEL_A_BIT | - VK_CHANNEL_R_BIT | VK_CHANNEL_G_BIT | VK_CHANNEL_B_BIT }, - } - }; - anv_pipeline_create((VkDevice) device, &(VkGraphicsPipelineCreateInfo) { .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, - .pNext = &cb_create_info, + .stageCount = 1, + .pStages = &(VkPipelineShaderStageCreateInfo) { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_FRAGMENT, + .shader = fs, + .pSpecializationInfo = NULL, + }, + .pVertexInputState = &vi_create_info, + .pIaState = &(VkPipelineIaStateCreateInfo) { + .sType = VK_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO, + .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, + .primitiveRestartEnable = false, + }, + .pRsState = &(VkPipelineRsStateCreateInfo) { + .sType = VK_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO, + .depthClipEnable = true, + .rasterizerDiscardEnable = false, + .fillMode = VK_FILL_MODE_SOLID, + .cullMode = VK_CULL_MODE_NONE, + .frontFace = VK_FRONT_FACE_CCW + }, + .pCbState = &(VkPipelineCbStateCreateInfo) { + .sType = VK_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO, + .attachmentCount = 1, + .pAttachments = (VkPipelineCbAttachmentState []) { + { .channelWriteMask = VK_CHANNEL_A_BIT | + VK_CHANNEL_R_BIT | VK_CHANNEL_G_BIT | VK_CHANNEL_B_BIT }, + } + }, .flags = 0, - .layout = 0 }, &(struct anv_pipeline_create_info) { .use_repclear = true, @@ -302,18 +298,12 @@ anv_cmd_buffer_clear(struct anv_cmd_buffer *cmd_buffer, static void anv_device_init_meta_blit_state(struct anv_device *device) { - VkPipelineIaStateCreateInfo ia_create_info = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO, - .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, - .primitiveRestartEnable = false, - }; - /* We don't use a vertex shader for clearing, but instead build and pass * the VUEs directly to the rasterization backend. However, we do need * to provide GLSL source for the vertex shader so that the compiler * does not dead-code our inputs. */ - VkShader vs = GLSL_VK_SHADER(device, VERTEX, + VkShaderModule vsm = GLSL_VK_SHADER_MODULE(device, VERTEX, in vec2 a_pos; in vec2 a_tex_coord; out vec4 v_tex_coord; @@ -324,7 +314,7 @@ anv_device_init_meta_blit_state(struct anv_device *device) } ); - VkShader fs = GLSL_VK_SHADER(device, FRAGMENT, + VkShaderModule fsm = GLSL_VK_SHADER_MODULE(device, FRAGMENT, out vec4 f_color; in vec4 v_tex_coord; layout(set = 0, binding = 0) uniform sampler2D u_tex; @@ -334,33 +324,24 @@ anv_device_init_meta_blit_state(struct anv_device *device) } ); - VkPipelineShaderStageCreateInfo vs_create_info = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - .pNext = &ia_create_info, - .shader = { - .stage = VK_SHADER_STAGE_VERTEX, - .shader = vs, - .linkConstBufferCount = 0, - .pLinkConstBufferInfo = NULL, - .pSpecializationInfo = NULL - } - }; - - VkPipelineShaderStageCreateInfo fs_create_info = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - .pNext = &vs_create_info, - .shader = { - .stage = VK_SHADER_STAGE_FRAGMENT, - .shader = fs, - .linkConstBufferCount = 0, - .pLinkConstBufferInfo = NULL, - .pSpecializationInfo = NULL - } - }; + VkShader vs; + anv_CreateShader((VkDevice) device, + &(VkShaderCreateInfo) { + .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO, + .module = vsm, + .pName = "main", + }, &vs); + + VkShader fs; + anv_CreateShader((VkDevice) device, + &(VkShaderCreateInfo) { + .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO, + .module = fsm, + .pName = "main", + }, &fs); VkPipelineVertexInputStateCreateInfo vi_create_info = { .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, - .pNext = &fs_create_info, .bindingCount = 2, .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) { { @@ -423,42 +404,56 @@ anv_device_init_meta_blit_state(struct anv_device *device) }, &device->meta_state.blit.pipeline_layout); - VkPipelineRsStateCreateInfo rs_create_info = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO, - .pNext = &vi_create_info, - .depthClipEnable = true, - .rasterizerDiscardEnable = false, - .fillMode = VK_FILL_MODE_SOLID, - .cullMode = VK_CULL_MODE_NONE, - .frontFace = VK_FRONT_FACE_CCW - }; - - VkPipelineCbStateCreateInfo cb_create_info = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO, - .pNext = &rs_create_info, - .attachmentCount = 1, - .pAttachments = (VkPipelineCbAttachmentState []) { - { .channelWriteMask = VK_CHANNEL_A_BIT | - VK_CHANNEL_R_BIT | VK_CHANNEL_G_BIT | VK_CHANNEL_B_BIT }, - } - }; - - VkGraphicsPipelineCreateInfo pipeline_info = { - .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, - .pNext = &cb_create_info, - .flags = 0, - .layout = device->meta_state.blit.pipeline_layout, - }; - - anv_pipeline_create((VkDevice) device, &pipeline_info, - &(struct anv_pipeline_create_info) { - .use_repclear = false, - .disable_viewport = true, - .disable_scissor = true, - .disable_vs = true, - .use_rectlist = true - }, - &device->meta_state.blit.pipeline); + anv_pipeline_create((VkDevice) device, + &(VkGraphicsPipelineCreateInfo) { + .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, + .stageCount = 2, + .pStages = (VkPipelineShaderStageCreateInfo[]) { + { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_VERTEX, + .shader = vs, + .pSpecializationInfo = NULL + }, { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_FRAGMENT, + .shader = fs, + .pSpecializationInfo = NULL + }, + }, + .pVertexInputState = &vi_create_info, + .pIaState = &(VkPipelineIaStateCreateInfo) { + .sType = VK_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO, + .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, + .primitiveRestartEnable = false, + }, + .pRsState = &(VkPipelineRsStateCreateInfo) { + .sType = VK_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO, + .depthClipEnable = true, + .rasterizerDiscardEnable = false, + .fillMode = VK_FILL_MODE_SOLID, + .cullMode = VK_CULL_MODE_NONE, + .frontFace = VK_FRONT_FACE_CCW + }, + .pCbState = &(VkPipelineCbStateCreateInfo) { + .sType = VK_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO, + .attachmentCount = 1, + .pAttachments = (VkPipelineCbAttachmentState []) { + { .channelWriteMask = VK_CHANNEL_A_BIT | + VK_CHANNEL_R_BIT | VK_CHANNEL_G_BIT | VK_CHANNEL_B_BIT }, + } + }, + .flags = 0, + .layout = device->meta_state.blit.pipeline_layout, + }, + &(struct anv_pipeline_create_info) { + .use_repclear = false, + .disable_viewport = true, + .disable_scissor = true, + .disable_vs = true, + .use_rectlist = true + }, + &device->meta_state.blit.pipeline); anv_DestroyObject((VkDevice) device, VK_OBJECT_TYPE_SHADER, vs); anv_DestroyObject((VkDevice) device, VK_OBJECT_TYPE_SHADER, fs); diff --git a/src/vulkan/pipeline.c b/src/vulkan/pipeline.c index 7df34d16a0a..9307a452bc9 100644 --- a/src/vulkan/pipeline.c +++ b/src/vulkan/pipeline.c @@ -31,33 +31,100 @@ // Shader functions +VkResult anv_CreateShaderModule( + VkDevice _device, + const VkShaderModuleCreateInfo* pCreateInfo, + VkShader* pShaderModule) +{ + ANV_FROM_HANDLE(anv_device, device, _device); + struct anv_shader_module *module; + + assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO); + assert(pCreateInfo->flags == 0); + + module = anv_device_alloc(device, sizeof(*module) + pCreateInfo->codeSize, 8, + VK_SYSTEM_ALLOC_TYPE_API_OBJECT); + if (module == NULL) + return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); + + module->size = pCreateInfo->codeSize; + memcpy(module->data, pCreateInfo->pCode, module->size); + + *pShaderModule = (VkShaderModule) module; + + return VK_SUCCESS; +} + VkResult anv_CreateShader( VkDevice _device, const VkShaderCreateInfo* pCreateInfo, VkShader* pShader) { - struct anv_device *device = (struct anv_device *) _device; + ANV_FROM_HANDLE(anv_device, device, _device); + ANV_FROM_HANDLE(anv_shader_module, module, pCreateInfo->module); struct anv_shader *shader; assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SHADER_CREATE_INFO); + assert(pCreateInfo->flags == 0); - shader = anv_device_alloc(device, sizeof(*shader) + pCreateInfo->codeSize, 8, - VK_SYSTEM_ALLOC_TYPE_API_OBJECT); + size_t name_len = strlen(pCreateInfo->pName); + + if (strcmp(pCreateInfo->pName, "main") != 0) { + anv_finishme("Multiple shaders per module not really supported"); + } + + shader = anv_device_alloc(device, sizeof(*shader) + name_len + 1, 8, + VK_SYSTEM_ALLOC_TYPE_API_OBJECT); if (shader == NULL) return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); - shader->size = pCreateInfo->codeSize; - memcpy(shader->data, pCreateInfo->pCode, shader->size); + shader->module = module; + memcpy(shader->entrypoint, pCreateInfo->pName, name_len + 1); *pShader = (VkShader) shader; return VK_SUCCESS; } +VkResult anv_CreatePipelineCache( + VkDevice device, + const VkPipelineCacheCreateInfo* pCreateInfo, + VkPipelineCache* pPipelineCache) +{ + *pPipelineCache = 1; + + stub_return(VK_SUCCESS); +} + +size_t anv_GetPipelineCacheSize( + VkDevice device, + VkPipelineCache pipelineCache) +{ + stub_return(0); +} + +VkResult anv_GetPipelineCacheData( + VkDevice device, + VkPipelineCache pipelineCache, + void* pData) +{ + stub_return(VK_UNSUPPORTED); +} + +VkResult anv_MergePipelineCaches( + VkDevice device, + VkPipelineCache destCache, + uint32_t srcCacheCount, + const VkPipelineCache* pSrcCaches) +{ + stub_return(VK_UNSUPPORTED); +} + // Pipeline functions static void -emit_vertex_input(struct anv_pipeline *pipeline, VkPipelineVertexInputStateCreateInfo *info) +emit_vertex_input(struct anv_pipeline *pipeline, + const VkPipelineVertexInputStateCreateInfo *info) { const uint32_t num_dwords = 1 + info->attributeCount * 2; uint32_t *p; @@ -125,7 +192,7 @@ emit_vertex_input(struct anv_pipeline *pipeline, VkPipelineVertexInputStateCreat static void emit_ia_state(struct anv_pipeline *pipeline, - VkPipelineIaStateCreateInfo *info, + const VkPipelineIaStateCreateInfo *info, const struct anv_pipeline_create_info *extra) { static const uint32_t vk_to_gen_primitive_type[] = { @@ -157,7 +224,8 @@ emit_ia_state(struct anv_pipeline *pipeline, } static void -emit_rs_state(struct anv_pipeline *pipeline, VkPipelineRsStateCreateInfo *info, +emit_rs_state(struct anv_pipeline *pipeline, + const VkPipelineRsStateCreateInfo *info, const struct anv_pipeline_create_info *extra) { static const uint32_t vk_to_gen_cullmode[] = { @@ -214,7 +282,8 @@ emit_rs_state(struct anv_pipeline *pipeline, VkPipelineRsStateCreateInfo *info, } static void -emit_cb_state(struct anv_pipeline *pipeline, VkPipelineCbStateCreateInfo *info) +emit_cb_state(struct anv_pipeline *pipeline, + const VkPipelineCbStateCreateInfo *info) { struct anv_device *device = pipeline->device; @@ -331,7 +400,8 @@ static const uint32_t vk_to_gen_stencil_op[] = { }; static void -emit_ds_state(struct anv_pipeline *pipeline, VkPipelineDsStateCreateInfo *info) +emit_ds_state(struct anv_pipeline *pipeline, + const VkPipelineDsStateCreateInfo *info) { if (info == NULL) { /* We're going to OR this together with the dynamic state. We need @@ -364,14 +434,6 @@ emit_ds_state(struct anv_pipeline *pipeline, VkPipelineDsStateCreateInfo *info) GEN8_3DSTATE_WM_DEPTH_STENCIL_pack(NULL, pipeline->state_wm_depth_stencil, &wm_depth_stencil); } -VkResult anv_CreateGraphicsPipeline( - VkDevice device, - const VkGraphicsPipelineCreateInfo* pCreateInfo, - VkPipeline* pPipeline) -{ - return anv_pipeline_create(device, pCreateInfo, NULL, pPipeline); -} - static void anv_pipeline_destroy(struct anv_device *device, struct anv_object *object, @@ -397,13 +459,6 @@ anv_pipeline_create( { struct anv_device *device = (struct anv_device *) _device; struct anv_pipeline *pipeline; - const struct anv_common *common; - VkPipelineShaderStageCreateInfo *shader_create_info; - VkPipelineIaStateCreateInfo *ia_info = NULL; - VkPipelineRsStateCreateInfo *rs_info = NULL; - VkPipelineDsStateCreateInfo *ds_info = NULL; - VkPipelineCbStateCreateInfo *cb_info = NULL; - VkPipelineVertexInputStateCreateInfo *vi_info = NULL; VkResult result; uint32_t offset, length; @@ -430,42 +485,18 @@ anv_pipeline_create( anv_state_stream_init(&pipeline->program_stream, &device->instruction_block_pool); - for (common = pCreateInfo->pNext; common; common = common->pNext) { - switch (common->sType) { - case VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO: - vi_info = (VkPipelineVertexInputStateCreateInfo *) common; - break; - case VK_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO: - ia_info = (VkPipelineIaStateCreateInfo *) common; - break; - case VK_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO: - anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO"); - break; - case VK_STRUCTURE_TYPE_PIPELINE_VP_STATE_CREATE_INFO: - anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_VP_STATE_CREATE_INFO"); - break; - case VK_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO: - rs_info = (VkPipelineRsStateCreateInfo *) common; - break; - case VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO: - anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO"); - break; - case VK_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO: - cb_info = (VkPipelineCbStateCreateInfo *) common; - break; - case VK_STRUCTURE_TYPE_PIPELINE_DS_STATE_CREATE_INFO: - ds_info = (VkPipelineDsStateCreateInfo *) common; - break; - case VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO: - shader_create_info = (VkPipelineShaderStageCreateInfo *) common; - pipeline->shaders[shader_create_info->shader.stage] = - (struct anv_shader *) shader_create_info->shader.shader; - break; - default: - break; - } + for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) { + pipeline->shaders[pCreateInfo->pStages[i].stage] = + (struct anv_shader *) pCreateInfo->pStages[i].shader; } + if (pCreateInfo->pTessState) + anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO"); + if (pCreateInfo->pVpState) + anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_VP_STATE_CREATE_INFO"); + if (pCreateInfo->pMsState) + anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO"); + pipeline->use_repclear = extra && extra->use_repclear; anv_compiler_run(device->compiler, pipeline); @@ -474,17 +505,19 @@ anv_pipeline_create( * hard code this to num_attributes - 2. This is because the attributes * include VUE header and position, which aren't counted as varying * inputs. */ - if (pipeline->vs_simd8 == NO_KERNEL) - pipeline->wm_prog_data.num_varying_inputs = vi_info->attributeCount - 2; - - assert(vi_info); - emit_vertex_input(pipeline, vi_info); - assert(ia_info); - emit_ia_state(pipeline, ia_info, extra); - assert(rs_info); - emit_rs_state(pipeline, rs_info, extra); - emit_ds_state(pipeline, ds_info); - emit_cb_state(pipeline, cb_info); + if (pipeline->vs_simd8 == NO_KERNEL) { + pipeline->wm_prog_data.num_varying_inputs = + pCreateInfo->pVertexInputState->attributeCount - 2; + } + + assert(pCreateInfo->pVertexInputState); + emit_vertex_input(pipeline, pCreateInfo->pVertexInputState); + assert(pCreateInfo->pIaState); + emit_ia_state(pipeline, pCreateInfo->pIaState, extra); + assert(pCreateInfo->pRsState); + emit_rs_state(pipeline, pCreateInfo->pRsState, extra); + emit_ds_state(pipeline, pCreateInfo->pDsState); + emit_cb_state(pipeline, pCreateInfo->pCbState); anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_VF_STATISTICS, .StatisticsEnable = true); @@ -611,7 +644,7 @@ anv_pipeline_create( * vertex data to read from this field. We use attribute * count - 1, as we don't count the VUE header here. */ .VertexURBEntryOutputLength = - DIV_ROUND_UP(vi_info->attributeCount - 1, 2)); + DIV_ROUND_UP(pCreateInfo->pVertexInputState->attributeCount - 1, 2)); else anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_VS, .KernelStartPointer = pipeline->vs_simd8, @@ -703,16 +736,34 @@ anv_pipeline_create( return VK_SUCCESS; } -VkResult anv_CreateGraphicsPipelineDerivative( - VkDevice device, - const VkGraphicsPipelineCreateInfo* pCreateInfo, - VkPipeline basePipeline, - VkPipeline* pPipeline) +VkResult anv_CreateGraphicsPipelines( + VkDevice _device, + VkPipelineCache pipelineCache, + uint32_t count, + const VkGraphicsPipelineCreateInfo* pCreateInfos, + VkPipeline* pPipelines) { - stub_return(VK_UNSUPPORTED); + ANV_FROM_HANDLE(anv_device, device, _device); + VkResult result = VK_SUCCESS; + + unsigned i = 0; + for (; i < count; i++) { + result = anv_pipeline_create(_device, &pCreateInfos[i], + NULL, &pPipelines[i]); + if (result != VK_SUCCESS) { + for (unsigned j = 0; j < i; j++) { + anv_pipeline_destroy(device, (struct anv_object *)pPipelines[j], + VK_OBJECT_TYPE_PIPELINE); + } + + return result; + } + } + + return VK_SUCCESS; } -VkResult anv_CreateComputePipeline( +static VkResult anv_compute_pipeline_create( VkDevice _device, const VkComputePipelineCreateInfo* pCreateInfo, VkPipeline* pPipeline) @@ -784,32 +835,31 @@ VkResult anv_CreateComputePipeline( return VK_SUCCESS; } -VkResult anv_StorePipeline( - VkDevice device, - VkPipeline pipeline, - size_t* pDataSize, - void* pData) -{ - stub_return(VK_UNSUPPORTED); -} - -VkResult anv_LoadPipeline( - VkDevice device, - size_t dataSize, - const void* pData, - VkPipeline* pPipeline) +VkResult anv_CreateComputePipelines( + VkDevice _device, + VkPipelineCache pipelineCache, + uint32_t count, + const VkComputePipelineCreateInfo* pCreateInfos, + VkPipeline* pPipelines) { - stub_return(VK_UNSUPPORTED); -} + ANV_FROM_HANDLE(anv_device, device, _device); + VkResult result = VK_SUCCESS; + + unsigned i = 0; + for (; i < count; i++) { + result = anv_compute_pipeline_create(_device, &pCreateInfos[i], + &pPipelines[i]); + if (result != VK_SUCCESS) { + for (unsigned j = 0; j < i; j++) { + anv_pipeline_destroy(device, (struct anv_object *)pPipelines[j], + VK_OBJECT_TYPE_PIPELINE); + } + + return result; + } + } -VkResult anv_LoadPipelineDerivative( - VkDevice device, - size_t dataSize, - const void* pData, - VkPipeline basePipeline, - VkPipeline* pPipeline) -{ - stub_return(VK_UNSUPPORTED); + return VK_SUCCESS; } // Pipeline layout functions diff --git a/src/vulkan/private.h b/src/vulkan/private.h index 6f1f350a5b6..0965b999a65 100644 --- a/src/vulkan/private.h +++ b/src/vulkan/private.h @@ -714,9 +714,14 @@ struct anv_fence { bool ready; }; +struct anv_shader_module { + uint32_t size; + char data[0]; +}; + struct anv_shader { - uint32_t size; - char data[0]; + struct anv_shader_module * module; + char entrypoint[0]; }; struct anv_pipeline { -- 2.30.2