From 4f25f5d86cf38c94eb27b98695e0bdf7523af779 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Kristian=20H=C3=B8gsberg?= Date: Mon, 11 May 2015 22:17:04 -0700 Subject: [PATCH] vk: Support not having a vertex shader This lets us bypass the vertex shader and pass data straight into the rasterizer part of the pipeline. --- src/vulkan/compiler.cpp | 39 ++++++++++---------- src/vulkan/pipeline.c | 79 +++++++++++++++++++++++++---------------- 2 files changed, 68 insertions(+), 50 deletions(-) diff --git a/src/vulkan/compiler.cpp b/src/vulkan/compiler.cpp index 39858426cf4..3f2435402ad 100644 --- a/src/vulkan/compiler.cpp +++ b/src/vulkan/compiler.cpp @@ -676,7 +676,8 @@ static void gen7_compute_urb_partition(struct anv_pipeline *pipeline) { const struct brw_device_info *devinfo = &pipeline->device->info; - unsigned vs_size = pipeline->vs_prog_data.base.urb_entry_size; + bool vs_present = pipeline->vs_simd8 != NO_KERNEL; + unsigned vs_size = vs_present ? pipeline->vs_prog_data.base.urb_entry_size : 1; unsigned vs_entry_size_bytes = vs_size * 64; bool gs_present = pipeline->gs_vec4 != NO_KERNEL; unsigned gs_size = gs_present ? pipeline->gs_prog_data.base.urb_entry_size : 1; @@ -841,11 +842,8 @@ anv_compiler_run(struct anv_compiler *compiler, struct anv_pipeline *pipeline) fail_if(program == NULL || program->Shaders == NULL, "failed to create program\n"); - /* FIXME: Only supports vs and fs combo at the moment */ - assert(pipeline->shaders[VK_SHADER_STAGE_VERTEX]); - assert(pipeline->shaders[VK_SHADER_STAGE_FRAGMENT]); - - anv_compile_shader(compiler, program, pipeline, VK_SHADER_STAGE_VERTEX); + if (pipeline->shaders[VK_SHADER_STAGE_VERTEX]) + anv_compile_shader(compiler, program, pipeline, VK_SHADER_STAGE_VERTEX); anv_compile_shader(compiler, program, pipeline, VK_SHADER_STAGE_FRAGMENT); if (pipeline->shaders[VK_SHADER_STAGE_GEOMETRY]) anv_compile_shader(compiler, program, pipeline, VK_SHADER_STAGE_GEOMETRY); @@ -870,18 +868,25 @@ anv_compiler_run(struct anv_compiler *compiler, struct anv_pipeline *pipeline) success = really_do_wm_prog(brw, program, bfp, &wm_key, pipeline); fail_if(!success, "do_wm_prog failed\n"); pipeline->prog_data[VK_SHADER_STAGE_FRAGMENT] = &pipeline->wm_prog_data.base; + pipeline->active_stages = VK_SHADER_STAGE_FRAGMENT_BIT; - struct brw_vs_prog_key vs_key; - struct gl_vertex_program *vp = (struct gl_vertex_program *) - program->_LinkedShaders[MESA_SHADER_VERTEX]->Program; - struct brw_vertex_program *bvp = brw_vertex_program(vp); + if (pipeline->shaders[VK_SHADER_STAGE_VERTEX]) { + struct brw_vs_prog_key vs_key; + struct gl_vertex_program *vp = (struct gl_vertex_program *) + program->_LinkedShaders[MESA_SHADER_VERTEX]->Program; + struct brw_vertex_program *bvp = brw_vertex_program(vp); - brw_vs_populate_key(brw, bvp, &vs_key); + brw_vs_populate_key(brw, bvp, &vs_key); + + success = really_do_vs_prog(brw, program, bvp, &vs_key, pipeline); + fail_if(!success, "do_wm_prog failed\n"); + pipeline->prog_data[VK_SHADER_STAGE_VERTEX] = &pipeline->vs_prog_data.base.base; + pipeline->active_stages |= VK_SHADER_STAGE_VERTEX_BIT;; + } else { + pipeline->vs_simd8 = NO_KERNEL; + } - success = really_do_vs_prog(brw, program, bvp, &vs_key, pipeline); - fail_if(!success, "do_wm_prog failed\n"); - pipeline->prog_data[VK_SHADER_STAGE_VERTEX] = &pipeline->vs_prog_data.base.base; if (pipeline->shaders[VK_SHADER_STAGE_GEOMETRY]) { struct brw_gs_prog_key gs_key; @@ -893,14 +898,10 @@ anv_compiler_run(struct anv_compiler *compiler, struct anv_pipeline *pipeline) success = really_do_gs_prog(brw, program, bgp, &gs_key, pipeline); fail_if(!success, "do_gs_prog failed\n"); - pipeline->active_stages = VK_SHADER_STAGE_VERTEX_BIT | - VK_SHADER_STAGE_GEOMETRY_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; + pipeline->active_stages |= VK_SHADER_STAGE_GEOMETRY_BIT; pipeline->prog_data[VK_SHADER_STAGE_GEOMETRY] = &pipeline->gs_prog_data.base.base; - } else { pipeline->gs_vec4 = NO_KERNEL; - pipeline->active_stages = - VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; } diff --git a/src/vulkan/pipeline.c b/src/vulkan/pipeline.c index 33b4f64f489..445ffde94ff 100644 --- a/src/vulkan/pipeline.c +++ b/src/vulkan/pipeline.c @@ -266,6 +266,13 @@ VkResult VKAPI vkCreateGraphicsPipeline( anv_compiler_run(device->compiler, pipeline); + /* FIXME: The compiler dead-codes FS inputs when we don't have a VS, so we + * 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; + emit_vertex_input(pipeline, vi_info); emit_ia_state(pipeline, ia_info); emit_rs_state(pipeline, rs_info); @@ -358,40 +365,50 @@ VkResult VKAPI vkCreateGraphicsPipeline( offset = 1; length = (vue_prog_data->vue_map.num_slots + 1) / 2 - offset; - anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_VS, - .KernelStartPointer = pipeline->vs_simd8, - .SingleVertexDispatch = Multiple, - .VectorMaskEnable = Dmask, - .SamplerCount = 0, - .BindingTableEntryCount = + if (pipeline->vs_simd8 == NO_KERNEL) + anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_VS, + .FunctionEnable = false, + .VertexURBEntryOutputReadOffset = 1, + /* Even if VS is disabled, SBE still gets the amount of + * 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)); + else + anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_VS, + .KernelStartPointer = pipeline->vs_simd8, + .SingleVertexDispatch = Multiple, + .VectorMaskEnable = Dmask, + .SamplerCount = 0, + .BindingTableEntryCount = vue_prog_data->base.binding_table.size_bytes / 4, - .ThreadDispatchPriority = Normal, - .FloatingPointMode = IEEE754, - .IllegalOpcodeExceptionEnable = false, - .AccessesUAV = false, - .SoftwareExceptionEnable = false, - - /* FIXME: pointer needs to be assigned outside as it aliases - * PerThreadScratchSpace. - */ - .ScratchSpaceBasePointer = 0, - .PerThreadScratchSpace = 0, + .ThreadDispatchPriority = Normal, + .FloatingPointMode = IEEE754, + .IllegalOpcodeExceptionEnable = false, + .AccessesUAV = false, + .SoftwareExceptionEnable = false, + + /* FIXME: pointer needs to be assigned outside as it aliases + * PerThreadScratchSpace. + */ + .ScratchSpaceBasePointer = 0, + .PerThreadScratchSpace = 0, - .DispatchGRFStartRegisterForURBData = + .DispatchGRFStartRegisterForURBData = vue_prog_data->base.dispatch_grf_start_reg, - .VertexURBEntryReadLength = vue_prog_data->urb_read_length, - .VertexURBEntryReadOffset = 0, - - .MaximumNumberofThreads = device->info.max_vs_threads - 1, - .StatisticsEnable = false, - .SIMD8DispatchEnable = true, - .VertexCacheDisable = ia_info->disableVertexReuse, - .FunctionEnable = true, - - .VertexURBEntryOutputReadOffset = offset, - .VertexURBEntryOutputLength = length, - .UserClipDistanceClipTestEnableBitmask = 0, - .UserClipDistanceCullTestEnableBitmask = 0); + .VertexURBEntryReadLength = vue_prog_data->urb_read_length, + .VertexURBEntryReadOffset = 0, + + .MaximumNumberofThreads = device->info.max_vs_threads - 1, + .StatisticsEnable = false, + .SIMD8DispatchEnable = true, + .VertexCacheDisable = ia_info->disableVertexReuse, + .FunctionEnable = true, + + .VertexURBEntryOutputReadOffset = offset, + .VertexURBEntryOutputLength = length, + .UserClipDistanceClipTestEnableBitmask = 0, + .UserClipDistanceCullTestEnableBitmask = 0); const struct brw_wm_prog_data *wm_prog_data = &pipeline->wm_prog_data; uint32_t ksp0, ksp2, grf_start0, grf_start2; -- 2.30.2